Merhaba sevgili e-bergi okuyucuları! Hep birlikte yeni yaşımıza girerken bu senemizin herkese güzellikler getirmesini dileyerek yazıma başlamak istiyorum. Önceki yazımda vaat ettiğim üzere, bu ayki konum veri sıkıştırma yöntemleri. Veri sıkıştırma nedir, nasıl işimize yarar, nasıl yapılır gibi sorulara elimden geldiğince cevap vermeye çalıştım; umarım beğeneceğiniz bir yazı olmuştur.

Öncelikle veri sıkıştırma diye seslendiğimizde bize bakanın kim olduğuna karar verelim sonra da yanlışlıkla bakanları ayırt edelim. :) Bilgisayar biliminde, veri sıkıştırma, bir verinin önceden belirlenmiş olan bir kodlama şeması ile daha az depolama alanı kullanılarak tamamen veya kısmen ifade edilmesidir. Bu tanıma göre verilebilecek birkaç adet çarpıcı, enteresan ve kafa karıştıracak kadar belirsiz olan örnekler şunlardır: Bir metin belgesi için son harfini silmek veya her dördüncü harfini silmek, bir resim dosyasının alt yarısını silmek, bir müzik dosyasında sadece 3. ile 14. saniyeler arasını tutup kalanlarını silmek, vb. Bunlar her ne kadar çok kötü, başarısız sayılabilecek algoritmalar olsa da sıkıştırma algoritması kapsamına girmektedir. Ancak bu örneklerde verinin tutulmayan kısmının kesinlikle silinmesi veya en azından bir sıkıştırma algoritmasına tabi tutulması gerekmektedir. Tabii burada akla hemen neden aynı algoritmayı kullanmayacağımıza ilişkin bir soru gelebilir. Yukarıda bahsettiğim algoritmayı kendini tekrar ederek (özyinelemeli) uyguladığımızda neler olduğunu açık bir şekilde ifade edersek bu şekildeki bir yöntemin sıkıştırma algoritması olamayacağı hemen anlaşılabilir. Algoritma genel yapısı itibariyle şöyle işlemektedir: veriyi al, bunun bir kısmını olduğu gibi sakla, kalan kısmına da bu “sıkıştırma” algoritmasını uygula. Sürekli biçimde veriyi daha küçük parçalara ayırmaya çalışıp kendini uygulamaya çalışırken öyle bir an gelecektir ki artık veri daha küçük parçalara bölünemez halde, taşınabilecek en küçük birime sığıyor olacaktır. Bu noktada algoritma bu verinin saklanmasını tercih ederse bu aslında verinin tamamını saklamak istediği anlamına gelmektedir; yani burada gerçekleşen sadece bir parçalama işlemidir. Bu durumda da herhangi bir alandan tasarruf söz konusu olmadığı için buna bir sıkıştırma algoritması diyemeyiz.

Yukarıda verdiğim örnekler gibi veriden bariz bir şekilde kayıp varsa bu tarz sıkıştırma algoritmalarının yaptıkları sıkıştırmaya kayıplı sıkıştırma deniyor. Kayıpsız sıkıştırma algoritmaları da mevcuttur; zaten bazı durumlarda kayıplı algoritmalar kullanıcının işine yaramayacağı için uygulanamaz. Kodlama şemasının aynı olması gerektiği detayını da açıkladığımda tanım kısmını geçebiliriz. Belirli bir şema olması gerekiyor; çünkü bunu veriyi sıkıştıracak kişi ve okuyacak (genişletecek) kişi aynı şeyleri aynı şekilde yorumlamalı. Aksi takdirde kullanılan veriler çok farklı yorumlanabilir ve anlamlı bir bilgi elde edilemez. Buradaki mantık benim şu an Türkçe yazıyor olmam ve sizin Türkçe okuyor olmanıza eş değerdir.

Artık nasıl işimize yaradıklarından bahsedebiliriz. Tabi ki, sıkıştırmanın en kolay farkedilen yararı yerden tasarruf. Aklımıza şöyle bir soru gelebilir: "Dosyayı sıkıştırdık, sonra kullanırken geri açtık; yani yerden tasarruf için zamandan kaybetmedik mi?" Bu her zaman doğru değildir; aksine sıkça zamandan da kazanç sağlar. Örneğin BMP uzantılı bir resim dosyası 20 MB'a denk geldirken onu JPEG uzantılı hale getirdiğimizde boyut 5 MB'a -hatta kaliteden ödün verdiğimiz ölçüde KB'lara- kadar bile düşebilir. Hal bu olunca da resim dosyamızın veri transferinde BMP yerine JPEG formatını kullanırsak bize en az 4 kat zaman kazandıracaktır. Hemen burada küçük bir not düşelim: JPEG hem kayıplı hem de kayıpsız sıkıştırmalara müsaade ediyor. Bu gibi durumlarda sıkıştırmanın sadece yerden değil aynı zamanda süreden de kazanç sağladığı ortaya çıkıyor. Peki veri sıkıştırmanın hiç mi kötü yanı yok; niye bütün verileri sıkıştırarak saklamıyoruz? Öncelikle yukarıda örneklerini de verdiğimiz üzere tabii ki kötü yanları var. Kayıplı bir algoritma kullanıldığında kaliteden geri dönüşü mümkün olmayan bir kayıp yaşanıyor; ancak genelde bu kayıplı sıkıştırmalar resim, müzik, video gibi multimedya dosyalarında kullanılıyor ve insanın görsel, işitsel yeteneklerinin ötesindeki veriler siliniyor. Dolayısıyla gözle kolay görülemeyen veya duyulamayan bir kalite kaybıyla da yerden kazanç sağlanabiliyor. Bunun en önemli örneklerinden biri şüphesiz ki MP3 formatıdır. Bir CD'ye yaklaşık 700 MB'lık (80 dakika) bir ses kaydı, yani ortalama 16 şarkı ancak sığarken MP3 formatıyla birlikte tek CD'ye 150'nin üzerinde şarkı yazılabilir oldu; takdire şayan bir yenilikti. Bu arada, az önce “geri dönüşü mümküm olmayan” diye bir tabir kullandım. Belirtmekte fayda var; kayıplıyla kayıpsız sıkıştırma algoritmalarının arasındaki en önemli fark sıkıştırmanın ardından genişletmede (ya da direk olarak kullanımda) başlangıçtaki veriye tamamen geri dönüp dönemediğimizdir. Neden bütün verileri sıkıştırarak saklamıyoruz sorusunun cevabı ise biraz hayal kırıklığı yaratan cinsten; çünkü sıkıştırmak her zaman mümkün olmuyor. Özellikle bilgiden kayıp yaşanmaması gerekiyorsa bir veriyi sıkıştırmak zorlaşıyor: ya sıkıştırma oranı az oluyor ya da hiç sıkıştırılamıyor. Bazı algoritmalar verinin büyüklüğünü artmasına bile sebep olabiliyor. Tabii bu durumda sıkıştırma kullanılmadığından böyle bir olumsuz etkiyle pratikte karşılaşmıyoruz. Sıkıştırmanın neden mümkün olmadığını merak ediyorsanız, bu genelde verinin aşırı düzensiz (bir anlamda homojen) dağılmasından kaynaklanır. Az sonra bahsedeceğim üzere algoritmalarda genelde istatistiksel verilerden faydalanır. Aynı bilgi veride kaç kez , nerelerde geçmiş; arka arkaya kaç kez tekrarlamış gibi bilgiler yoğrularak en sonunda veri olabildiğince az yer tutması sağlanacak şekilde saklanır. İşte, eğer veri homojense yani bilgi yapıları birbiri içine iyi dağılmışsa genelde arka arkaya tekrar 2-3 kez olur. Ayrıca her bir farklı bilgi parçacığı toplamda eşit sayıda kullanıldığı için bir önem sırasına koyulamaz ve bunun gibi sebeplerden ötürü sıkıştırma gerçekleştirilemez.

Şimdi veri sıkıştırmanın nasıl yapıldığıyla ilgilenme vakti geldi. Yukarıda verdiğim bazı örnekler ile kafanızda az çok kayıplı ve kayıpsız sıkıştırmanın nasıl yapıldığına dair düşünceler oluşmaya başlamıştır. İkisine birden verilebilecek en açık örnek muhtemelen bir sayı yuvarlama olacaktır. Diyelim ki elinizdeki veri 4.999999 gibi bir sayı, o zaman bu sayıyı örnek olarak siz şu şekilde tutabilirsiniz 4.[6]9 yani “4.”dan sonra 6 tane 9 var. Bu kayıpsız sıkıştırmaya bir örnek teşkil etmektedir. Kodlama kısmında bu yöntemi çok daha verimli halde yazmak mümkün olsa da burada gözle görülmesi rahat olduğu için, '8 karakter kullanarak yazdığınız bir sayıyı 6 karakter kullanarak sıkıştırmış olduk' gibi düşünebiliriz. Yine bu örnekte aynı sayıyı 4.9'a ya da direk 5'e yuvarlayarak sakladığımızda da işimizi görecekse bu yöntemi de seçebiliriz. Görüldüğü üzere bu yöntemle karakter sayısını 1'e kadar düşürmek yani 8'de 1'i kadar yer kullanmak mümkün; ancak bu kayıplı bir sıkıştırma örneği olduğu için her zaman tercih edebileceğimiz bir yöntem değildir. Sonuçta bilgisayarda her şeyi sayılarla ifade edebildiğimizi düşünürsek bu sayıların birbirine belirli bir düzen içinde yuvarlanmasını herhangi bir kayıplı sıkıştırma algoritmasının yapısı olarak düşünebiliriz. Kayıplı yöntemleri hayal etmek daha kolay olduğu için ve daha az teknik bilgi gerektirdiği için onların üzerinde çok fazla durmakta fayda olmadığını düşünüyorum ve kayıpsız algoritmaların üzerinde biraz daha durmak istiyorum. Örnek olarak bir metin belgesini düşünürsek bu belgede kullanılan karakterlerin sayısı eğer çok fazla özel karakter kullanmıyorsak alfabedeki harflerin sayısının 2 katını geçmeyecektir; yani 64'ten fazla karaktere çok fazla ihtiyaç duyulmayacaktır. Yani biz kullandığımız bütün karakterleri 0-63 arası sayıları kullanarak ifade edebilmekteyizdir; ancak bilgisayarda karakterler 1 byte'ta yani 8 bit'te tutulmaktadır. 0-63 arası sayılar ise sadece 6 bit kullanılarak ifade edilebilir. Dolayısıyla bizim burda karakter başında 2 bit kullanmamız fazlalık olarak düşünülebilir; bu da toplamda %25 alanı boşu boşuna kullandığımız anlamına gelmektedir. O halde çeşitli numaralar yaparak bir karakter için gerekli bit sayısını 6'ya çektiğimizde yerden kazancımız %25 oranında olacaktır. Mantığı buna benzeyen ama çok daha verimli ve önemli bir algoritma ise Huffman kodlaması olarak anılmaktadır. Bu kodlamada ise kullanılan harflerin sıklıkları da önemlidir. Öyle ki en sık kullanılan harfler örnek olarak yerine göre 3 bit en az kullanılanlar ise 7 bit'le ifade edilecek şekilde ayarlanır. Sonrası ise malum; 8 bit'lik karakterlerle doldurmaktansa belgede bulunma sıklığı açısından en fazla olan karakterleri 3 bit'le ifade ederek çok büyük oranda yerden tasarruf sağlamış oluyoruz.

Umarım veri sıkıştırmayla ilgili aklınıza takılan sorulara cevap bulmanızda bir nebze olsun yardımım dokunmuştur. Tekrar, yeni senemizin herkes için iyi geçmesini temenni ederim. Gelecek sayımızda görüşmek üzere kendinize iyi bakın.

Kaynaklar