2016-08-22 68 views
5

Stworzyłem kilka 4x4 pikselowych, 16-bitowych odcieni szarości, obrazów w Photoshopie i zapisałem je jako nieskompresowane, bez przeplotu, pliki PNG. Próbuję napisać program, aby wyodrębnić dane obrazu z tych plików, ale trochę się pomyliłem z porcją IDAT. Ma to na celu samokształcenie, więc nie używam biblioteki.Jak odkodować porcję IDAT pliku PNG bez kompresji

Oto kod szesnastkowy dla fragmentu IDAT jednego z obrazów, gdzie każdy piksel jest biały.

hex code

mam kolorami co wierzę rozumiem w tym momencie.

Czerwony = Zignoruj, ponieważ jest częścią porcji IEND i nie dotyczy IDAT.
Żółty = Informacja o porcji. Pierwsze 4 żółte bajty to długość danych. Drugie 4 żółte bajty to identyfikator kawałka. Ostatnie 4 żółte bajty na końcu obrazu to Cykliczna kontrola nadmiarowa.
Niebieski = Informacja o formacie kompresji zlib. Gdzie pierwszy niebieski bajt to metoda kompresji i informacja o kompresji. Drugi niebieski bajt to informacje o flagach. Ostatnie cztery niebieskie bajty w dolnej części obrazu to suma kontrolna ADLER-32. Zakładam, że w tym przypadku nie ma DICTID.
Szary = Informacja dla algorytmu kompresji Deflate. W pierwszym szarym bajcie, bit jeden jest ostatnim znacznikiem bloku, a bity dwa i trzy są metodą kodowania. Reszta pierwszego szarego bajtu jest ignorowana. Ponieważ ta metoda jest metodą nieskompresowaną, drugi i trzeci szary bajt to długość bajtów danych w bloku, a czwarty i piąty szary bajt stanowią komplement drugiego i trzeciego szarego bajtu.
Bez ramki = Dane obrazu skompresowane algorytmem LZ77 (bez kodu Huffmana z powodu metody bez kompresji) z algorytmem wykorzystującym 8 bitów dla potencjalnej długości duplikatów i 15 bitów dla odległości wyszukiwania wstecznego.

Albo rozumiem coś niepoprawnie, albo nie rozumiem, jak rozszyfrować bajty w obrazie bez ramki poprawnie używając algorytmu LZ77. Jeśli ktoś może mnie poprawić lub pokazać to, czego nie rozumiem, byłbym bardzo wdzięczny. Dziękuję Ci.

+0

Dodano kilka tagów ... Wygląda również na to, że żółta partia początkowa/końcowa IDAT została poprawnie zdekodowana "(rozmiar + 12 znaków BYTE)" przynajmniej jest taka sama na testowanych urządzeniach. – Spektre

Odpowiedz

5

Górny rząd: 01 ff fd 00 00 00 00 00 ("dodatkowe" filtr 00, pierwszy piksel FFFD kolejnych pikseli oznaczają to samo, co piksel w swoją lewą stronę (różnica = 0)

Pozostały 3 wiersze: 02 00 00 00 00 00 00 00 00 (filtr "górny", taki sam jak wiersz powyżej)

Ostatni blok: 01 00 00 ff ff (ostatni znacznik bajtu 01, len 0000, ~ len ffff)

Tak więc obraz ma rozmiar 4x4, wszystkie piksele to 16-bitowe fffd, które jest prawie białe.

Jeśli użyłeś filtru typu 0 dla wszystkich bajtów, może to być czystsze zrozumienie; wiersze miałyby być od 00 ff fd ff fd fd fd fd

Nawiasem mówiąc, porcja IEND powinna mieć 4 dodatkowe bajty (CRC); albo coś jest nie tak z twoim koderem, albo edytowałeś je poza obrazkiem heksowego zrzutu.

+0

Zrobiłem edytować resztę fragmentu IEND, a wszystkie kawałki przed IDAT. Moje rozumowanie było takie, że nacisk kładziono na IDAT. Załączam dowód, że IEND jest następny, aby ludzie nie pytali się, czy następna porcja IDAT następuje, czy to naprawdę koniec fragmentu IDAT. Dziękuję za odpowiedź. –