Ya, GIF tua yang bagus. Dicintai karena keserbagunaannya, dibenci karena patennya dan sebagian sudah usang karena keterbatasannya (dan patennya), GIF pada intinya terdiri dari palet warna dan gambar yang diindeks palet yang dikompres menggunakan algoritma LZW.
Tugas Anda adalah menulis program yang membaca gambar dalam format ASCII PPM ("nomor ajaib") dari input standar, dan menulis gambar yang sama (pixel-by-pixel identik) dalam format GIF ke output standar. Outputnya bisa dalam bentuk biner, atau teks ASCII dengan setiap byte diwakili oleh angka antara 0 dan 255 (inklusif), dipisahkan oleh spasi putih.
Gambar input dijamin tidak memiliki lebih dari 256 warna berbeda.
Mencetak:
Program Anda akan diuji pada 3 gambar sampel, dan skor Anda akan dihitung sebagai:
ukuran program + jumlah (ukuran output - ukuran referensi untuk setiap gambar sampel)
Skor terendah menang.
Persyaratan:
- Program Anda harus bekerja dengan jenis gambar yang serupa dari berbagai ukuran, dan tidak terbatas pada gambar sampel. Anda dapat, misalnya, membatasi dimensi menjadi kelipatan 2 atau menganggap bahwa warna ppm max adalah 255, tetapi masih harus bekerja dengan berbagai macam gambar input.
- Keluaran harus berupa file GIF yang valid yang dapat dimuat dengan program apa pun yang sesuai (setelah mengonversi kembali ke biner jika menggunakan opsi keluaran ASCII).
- Anda tidak dapat menggunakan fungsi pemrosesan gambar apa pun (bawaan atau pihak ketiga), program Anda harus berisi semua kode yang relevan.
- Program Anda harus dapat dijalankan di Linux menggunakan perangkat lunak yang tersedia secara bebas.
- Kode sumber harus hanya menggunakan karakter ASCII.
Contoh gambar:
Berikut adalah 3 contoh gambar yang akan digunakan untuk penilaian. Anda dapat mengunduh arsip zip dengan file ppm (gunakan tombol unduh di bagian atas halaman itu). Atau Anda dapat mengonversinya dari gambar png di bawah ini, menggunakan ImageMagick dengan perintah berikut:
convert file.png -compress none file.ppm
Saya juga menyediakan checksum MD5 dari file ppm untuk konfirmasi.
1. kuning
Ukuran referensi: 38055
MD5 checksum dari ppm: d1ad863cb556869332074717eb278080
2. mata biru
Ukuran referensi: 28638
MD5 checksum dari ppm: e9ad410057a5f6c25a22a534259dcf3a
3. paprika
Ukuran referensi: 53586
MD5 checksum dari ppm: 74112dbdbb8b7de5216f9e24c2e1a627
sumber
Jawaban:
Perl, 515 + -2922 + 0 + -2571 = -4978
Pendekatan lain. Kali ini saya mencoba untuk menyimpan gambar dalam ubin ukuran 64xH. Ini sesuai dengan spesifikasi, tetapi beberapa perangkat lunak hanya menampilkan ubin pertama atau animasi. Ubin mengkompres lebih baik karena lokalitas spasial yang lebih baik. Saya masih melakukan kompresi normal juga untuk gambar kedua dan memilih apa pun yang datang lebih pendek. Karena ini memampatkan gambar dua kali, itu dua kali lebih lambat dibandingkan dengan solusi saya sebelumnya.
Perl, 354 + 12 + 0 + -1 = 365
418 9521 51168 56639Entah ada beberapa bug dalam kode saya atau gambar kedua dioptimalkan untuk encoder tertentu karena perubahan yang tampaknya tidak signifikan mengurangi ukuran ke referensi dengan tepat. Memakan sekitar 30-an-60 per gambar.
Versi golf.
Satu-satunya keputusan yang dapat diambil oleh kompresor GIF adalah kapan harus mengatur ulang kamus LZW. Secara umum karena bagaimana gambar untuk tugas ini dipilih saat terbaik untuk melakukannya adalah setiap kode 4096 yang merupakan saat kamus akan meluap. Dengan batas seperti itu kamus tidak pernah meluap yang menyimpan beberapa byte dalam implementasi. Beginilah cara kerjanya secara detail:
Perl, 394 + -8 + 0 + -12 = 374
Menambahkan heuristik untuk menebak titik reset meningkatkan kompresi sedikit tetapi tidak cukup untuk membenarkan kode tambahan:
sumber
CJam, skor 155 + 35306 + 44723 + 21518 = 101702
Hanya implementasi referensi bodoh. Ini lambat, tidak melakukan kompresi yang sebenarnya dan tidak golf.
sumber