Tag Archives: Compression

ทดลองบีบย่อไฟล์แบบ Brotli

เคยทดลองวิธีบีบย่อไฟล์ด้วยโปรแกรม Zopfli มาก่อน ตอนนี้มีรูปแบบใหม่จาก Google มาอีก คือ Brotli ซึ่งใช้ไฟล์รูปแบบใหม่ไม่เหมือน deflat เลยจะเปิดด้วย deflate ไม่ได้ ไหนๆ เคยทดลอง Zopfli มาแล้ว ลองกับ Brotli บ้างจะเป็นไร สร้างโปรแกรมนี้จาก git โดยพลันครับ

git clone https://github.com/google/brotli.git
cd brotli/tools
make -j4

จะได้ไฟล์โปรแกรม bro มาใช้ ก็ทดสอบคร่าวๆ เหมือนคราวก่อน โดยสั่ง time ไว้ด้วย

time ./bro --quality 11 --input enwik8 --output enwik8.bro --verbose
Brotli compression speed: 0.159104 MB/s

real    10m2.654s
user    9m54.819s
sys    0m4.588s

ได้ไฟล์บีบแล้วชื่อ enwik8.bro ขนาด 27,721,194 ไบต์ บีบมาจากไฟล์ enwik8 ขนาด 100,000,000 ไบต์

ถ้าพิมพ์คำสั่ง bro เฉยๆ มันจะรอรับข้อมูลจาก stdin ซึ่งมักจะเป็น keyboard นะครับ
ผ่านทาง http://www.cnx-software.com/2015/09/24/brotli-compression-algorithm-combines-high-compression-ratio-and-fast-decompression/

Advertisements

บีบภาพ JPEG ให้เล็กลงไปอีก ด้วย mozjpeg เวอร์ชัน 2.0.1

Mozilla มีโครงการ mozjpeg เป็น library ช่วยบีบไฟล์ JPEG ให้เล็กลงไปอีก ตอนนี้มาถึงเวอร์ชัน 2.0.1 แล้ว เคยทดลองใช้ Zopfli บีบภาพ PNG มาแล้ว คราวนี้ลองตัวนี้บ้างครับ

sudo yum install nasm
wget https://github.com/mozilla/mozjpeg/archive/v2.0.1.tar.gz
tar -xzvf v2.0.1.tar.gz
cd mozjpeg-2.0.1
autoreconf -fiv
sh ./configure
make
sudo make install prefix=/usr/local libdir=/usr/local/lib64

 

นอกจาก library แล้ว ก็จะได้โปรแกรมอีกหลายตัว ขอทดลองใช้ /usr/local/bin/cjpeg บีบภาพ JPEG ให้เล็กลง ใช้ไฟล์รูป Nikola Tesla มาทดลองบีบย่อครับ รูปขนาด 55,321 ไบต์

บีบแล้วได้ขนาด 49,218 ไบต์ อ้อ โปรแกรม cjpeg นี้ ส่ง output ออกทาง stdout นะครับ ให้ redirect ไปยังไฟล์ที่ต้องการด้วย ถ้าปล่อยออกหน้าจอ terminal ข้อความหน้าจออาจเละได้

ehoeks-zopfli-png ใช้ Zopfli บีบไฟล์ภาพ png ให้เล็กลง

ไปเจอโปรแกรม ehoeks-zopfli-png ซึ่งจะช่วยบีบย่อไฟล์ png ให้มีขนาดลง ด้วยอัลกอริทึม Zopfli แล้วยังดูภาพแบบ png ได้อยู่ เพราะวิธีคลายการบีบย่อข้อมูลเหมือนเดิม มีแจกโค้ดด้วยครับ ก็มาลองกันเลย พิมพ์คำสั่ง

git clone https://code.google.com/r/ehoeks-zopfli-png/
cd ehoeks-zopfli-png/

ผมใช้ Fedora 18 มีต้องแก้โค้ดนิดหน่อยจึงจะ make ได้ เหมือนจะมีปัญหากับ zlib คือที่ไฟล์ png_optimizer.c ต้องเพิ่มบรรทัด #include “zlib.h” เข้าไปเพราะตอนแรกมันไปหาค่าคงที่ต่างๆ ที่ชื่อขึ้นต้นด้วย Z_ ไม่เจอ และ makefile ก็เพิ่ม -lz เข้าไปในการทำ make: จากนั้นจึง

make

ก็จะได้ไฟล์โปรแกรม zopfli ไว้ใช้งาน ซึ่งสิ่งที่เพิ่มเติมจาก zopfli แบบดั้งเดิม คือเพิ่ม option –png ให้ดึงภาพจากไฟล์ png แล้วบีบใหม่ด้วยอัลกอริทึม Zopfli แล้วบันทึกเป็นไฟล์ภาพ png จากนั้นทดลองบีบภาพเลยครับ ขอใช้รูปของท่านผู้นี้ครับ Nicola Tesla โดยได้ภาพแบบ public domain มาจาก Wikimedia

ภาพต้นฉบับ Tesla3.png ขนาด 162,248 ไบต์

เมื่อสั่ง ./zopfli –png Tesla3.png บีบได้ไฟล์เป็น png ขนาด 131,629 ไบต์ ไม่ได้จับเวลาว่านานขนาดไหนครับแต่รอไม่นาน จะได้ไฟล์ Tesla3.png.png ผมเปลี่ยนชื่อเป็น Tesla3.zopfli.png จะได้ไม่โดนทับในการทดลองต่อไป

เมื่อสั่ง ./zopfli –png –i1000 Tesla3.png เพื่อคำนวณมากขึ้นจะได้บีบไฟล์ให้เล็กลงมากขึ้นไปอีก ก็ได้ขนาดเป็น 131,584 ไบต์ครับ ประหยัดพื้นที่ได้อีกเล็กน้อย โดยใช้เวลาเกือบ 6 นาที

ภาพขณะกำลังทำการทดลองครับ
testing-ehoeks-zopfli-png

ปล. Zopfli มี zopflipng รองรับไฟล์ PNG แล้วครับ

แนวคิดคร่าวๆ ของหลักการบีบย่อข้อมูล ว่ามันทำได้อย่างไร

หลายคนอาจสงสัยว่า การบีบย่อข้อมูล ทำได้อย่างไร ไฟล์มันเล็กไปกว่านี้ได้ด้วยหรือ ก็มีหลายแนวคิดในการบีบลดข้อมุลครับ

แนวคิดหนึ่งคือ ถ้าข้อความซ้ำ แทนที่จะเขียนซ้ำๆ กันอีก ก็แค่บอกว่าให้ย้อนไปอ่านข้อความที่เขียนไปแล้วก่อนหน้านี้ที่ตำแหน่งไหนและให้อ่านกี่ตัวอักษร ทั้งนี้อาจต้องมีอักษรพิเศษเพื่อบอกว่าตัวไหนคือตัวอักษร และตัวไหนคือคำสั่งให้ไปอ่านข้อความที่เคยเขียนมาแล้ว

อีกแนวคิด คล้ายๆ การเคาะรหัสส่งโทรเลขที่ตัวอักษรที่ใช้บ่อยๆ รหัสที่ต้องเคาะก็ควรจะสั้น เช่น E และ T และตัวอักษรที่ใช้ไม่บ่อย เคาะรหัสยาวหน่อยก็ได้ แต่ในคอมพิวเตอร์ จะเก็บเป็นบิตหรือเลขฐานสองแทนการเคาะ

สมมติมีแค่ตัวอีกษร A, B, C, D มาประกอบเป็นข้อความ AAAABBCD ถ้ากำหนดให้ทุกตัวอักษรใช้จำนวนบิตที่จะแทนที่ตัวอักษรเท่ากันหมดคือ 2 บิต (หรือเลขฐานสองสองหลัก) โดยกำหนดให้ A=00, B=01, C=10 และ D=11 ข้อความดังกล่าวก็จะเปลี่ยนเป็นบิตได้เป็น AAAABBCD = 00,00,00,01,01,10,11 รวมทั้งหมด 16 บิต

แต่ถ้ากำหนดให้ ตัวอักษรแต่ละตัวเก็บด้วยจำนวนบิตที่ไม่เท่ากัน ให้ตัวอักษรที่ใช้บ่อยๆ ใช้จำนวนบิตน้อยหน่อย ตัวอักษรที่ใช้ไม่บ่อย ก็ยอมให้ใช้จำนวนบิตยาวกว่าได้ เช่น A=1, B=01, C=001 และ D=000 จะใช้แค่ AAAABBCD = 1,1,1,1,01,01,001,000 รวมทั้งหมด 14 บิต จะเห็นว่า จำนวนบิตที่ใช้ลดลง

 

อัลกอริทึมใหม่จากกูเกิล Zopfli บีบอัดไฟล์อัตราส่วนดีกว่า 7-zip จริงหรือ

มีข่าวว่า “กูเกิลเปิดตัว Zopfli อัลกอริทึมบีบอัดไฟล์แบบใหม่ที่ให้อัตราส่วนดีกว่า 7-zip” เลยขอพิสูจน์หน่อย อีกทั้งไปเห็นที่ CNX-Soft ได้ทดลองแล้ว ลองกับเขาบ้าง จะใช้ไฟล์ enwik8 ซึ่งมีขนาดร้อยล้านไบต์พอดีเปะจาก http://mattmahoney.net/dc/textdata.html ซึ่งใช้เพื่อ Large Text Compression Benchmark

เลียนแบบวิธีใน CNX-Soft แต่ใช้แค่ -i1000 ครับ บีบแล้วได้ขนาด 34,988,599 ไบต์ ทวีตข้อความผิดไปหน่อย แต่ในรูปที่ capture มานั้นถูกแล้ว

วันต่อมา จึงลองกับ 7-Zip พบว่าสำหรับไฟล์นี้ 7-Zip บีบย่อได้ดีกว่าครับ โดยใช้ option ให้บีบอัดเต็มที่โดยไม่ได้ระบุอัลกอริทึม ซึ่งมันจะใช้แบบ LZMA ก็พบว่าบีบได้เล็กกว่าครับ คือ 24,861,205 ไบต์

enwik8-compare-7z-zip-zopfli

อันที่จริงที่ link ข้างบน Large Text Compression Benchmark ก็มีพูดถึง 7-Zip เหมือนกันครับ ใช้วิธีคล้ายๆ กัน แต่ใส่ option ให้ทำเป็น self-extractor ขนาดก็พอๆ กับที่ผมทดลอง

links แปะอ่าน
https://code.google.com/p/zopfli/source/browse/deflate.c (จุดนี้กำลังไล่ดูอยู่ครับ อัลกอริทึมนี้จะบีบย่อไฟล์ให้ได้ฟอร์แมตที่อัลกอริทึมคลายไฟล์แบบเดิม คลายได้)
http://encode.ru/threads/1689-Google-Compress-Data-More-Densely-with-Zopfli?p=32537&viewfull=1#post32537
https://twitter.com/ohmohm/status/308073421814763522