66#include " bitarray.h"
77#include " tree.h"
88
9- static const unsigned short order [19 ] = {16 , 17 , 18 , 0 , 8 , 7 , 9 , 6 , 10 , 5 , 11 , 4 , 12 , 3 , 13 , 2 , 14 , 1 , 15 }; /* permutation of code lengths */
9+ static const unsigned short huffmanTreeOrder [19 ] = {16 , 17 , 18 , 0 , 8 , 7 , 9 , 6 , 10 , 5 , 11 , 4 , 12 , 3 , 13 , 2 , 14 , 1 , 15 };
1010static const unsigned short lengths[29 ] = {3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 13 , 15 , 17 , 19 , 23 , 27 , 31 , 35 , 43 , 51 , 59 , 67 , 83 , 99 , 115 , 131 , 163 , 195 , 227 , 258 };
1111static const unsigned short lengthsExtraBits[29 ] = {0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 2 , 2 , 2 , 2 , 3 , 3 , 3 , 3 , 4 , 4 , 4 , 4 , 5 , 5 , 5 , 5 , 0 };
1212static const unsigned int offsets[30 ] = {1 , 2 , 3 , 4 , 5 , 7 , 9 , 13 , 17 , 25 , 33 , 49 , 65 , 97 , 129 , 193 , 257 , 385 , 513 , 769 , 1025 , 1537 , 2049 , 3073 , 4097 , 6145 , 8193 , 12289 , 16385 , 24577 };
1313static const unsigned int offsetsExtraBits[30 ] = {0 , 0 , 0 , 0 , 1 , 1 , 2 , 2 , 3 , 3 , 4 , 4 , 5 , 5 , 6 , 6 , 7 , 7 , 8 , 8 , 9 , 9 , 10 , 10 , 11 , 11 , 12 , 12 , 13 , 13 };
1414
1515int main () {
16- Image image (" smile .png" );
17-
16+ Image image (" goat .png" );
17+
1818 Format format = image.getFormat ();
1919 LOG (" Size: " << format.width << " x" << format.height );
2020 LOG (" Bit depth: " << (int ) format.bitDepth );
@@ -23,30 +23,35 @@ int main() {
2323 LOG (" Filter method: " << (int ) format.filterMethod );
2424 LOG (" Interlace method: " << (int ) format.interlaceMethod );
2525 LOG (" " );
26-
26+
2727 int index = 0 ;
28+ int count = 0 ;
2829 while (image.chunks [++index]->type != " IDAT" );
30+ int index2 = index;
31+ while (index < image.chunks .size () && image.chunks [index2++]->type == " IDAT" ) count++;
32+ LOG (" IDAT chunk count: " << count);
2933 Chunk pixelChunk = *image.chunks [index];
3034 LOG (" Chunk type: " << pixelChunk.type );
3135 LOG (" Chunk size (bytes): " << pixelChunk.length );
3236 LOG (" " );
33-
37+
3438 std::vector<unsigned char > compressedData = image.extractCompressedPixelData (pixelChunk);
3539 BitArray CMFbits (compressedData[0 ], 8 );
3640 LOG (" CMF:" );
3741 LOG (" \t Hopefully this is 8: " << CMFbits.read (0 , 4 ));
3842 LOG (" \t CINFO: " << CMFbits.read (4 , 4 ));
39-
43+
4044 BitArray flagBits (compressedData[1 ], 8 );
4145 LOG (" FLG:" );
4246 LOG (" \t FDICT: " << (flagBits.read (4 , 1 ) == 1 ? " yep" : " no" ));
4347 bool fDict = flagBits.read (4 , 1 ) != 0 ;
4448 LOG (" \t Checks out: " << ((((CMFbits.read (0 , 8 ) << 8 ) + (flagBits.read (0 , 8 ))) % 31 == 0 ) ? " yeeaaah" : " no... :/" ));
4549 LOG (" " );
46-
50+
4751 BitArray nextBits (compressedData[2 ], 8 );
4852 LOG (" Last block?: " << (nextBits.read (0 , 1 ) ? " yes" : " no" ));
49- switch (nextBits.read (1 , 2 )) {
53+ unsigned short compressionMethod = nextBits.read (1 , 2 );
54+ switch (compressionMethod) {
5055 case 0 :
5156 LOG (" Compression method: uncompressed" );
5257 break ;
@@ -64,9 +69,9 @@ int main() {
6469 for (unsigned int i = 3 ; i < compressedData.size (); i++) {
6570 actualData.pushBack (compressedData[i]);
6671 }
67-
72+
6873 LOG (" \n " );
69-
74+
7075 std::string pngSymbols[288 ];
7176 unsigned int pngLengths[288 ];
7277 for (unsigned int i = 0 ; i < 288 ; i++) {
@@ -79,51 +84,82 @@ int main() {
7984 pngLengths[i] = 7 ;
8085 }
8186 Tree pngTree (pngSymbols, pngLengths, 288 );
82-
87+
8388 std::vector<unsigned int > stream;
8489 stream.reserve ((1 + format.width ) * format.height );
85-
90+
8691 unsigned int end = 0 ;
87- while (true ) {
88- std::stringstream convert (pngTree.uncompressOneCode (actualData, end, &end));
89-
90- unsigned int code = 0 ;
91- convert >> code;
92-
93- if (code < 256 ) {
94- LOG (code);
95- stream.emplace_back (code);
96- } else if (code == 256 ) {
92+ if (compressionMethod == 2 ) {
93+ unsigned int hlit = actualData.read (end, 5 , true ) + 257 ;
94+ end += 5 ;
95+ unsigned int hdist = actualData.read (end, 5 , true ) + 1 ;
96+ end += 5 ;
97+ unsigned int hlen = actualData.read (end, 5 , true ) + 4 ;
98+ end += 4 ;
99+
100+ std::vector<unsigned char > huffman1Lengths;
101+ huffman1Lengths.reserve (19 );
102+ std::vector<unsigned char > huffman1Symbols;
103+ huffman1Symbols.reserve (19 );
104+ {
105+ unsigned int i = 0 ;
106+ for (; i < hlen; i++) {
107+ huffman1Symbols.push_back ((unsigned char ) i);
108+ huffman1Lengths[huffmanTreeOrder[i]] = (unsigned char ) actualData.read (end, 3 , false );
109+ end+=3 ;
110+ }
111+ for (; i < 19 ; i++) {
112+ huffman1Symbols.push_back ((unsigned char )i);
113+ huffman1Lengths[huffmanTreeOrder[i]] = 0 ;
114+ }
115+ }
116+
117+ for (unsigned int i = 0 ; i < 19 ; i++) {
118+ LOG ((unsigned int ) huffman1Lengths[i]);
119+ }
120+ } else if (compressionMethod == 1 ) {
121+ while (true ) {
122+ std::stringstream convert (pngTree.uncompressOneCode (actualData, end, &end));
123+
124+ unsigned int code = 0 ;
125+ convert >> code;
126+
127+ if (code < 256 ) {
128+ LOG (code);
129+ stream.emplace_back (code);
130+ } else if (code == 256 ) {
97131// LOG("\n");
98132// for (auto i : stream)
99133// LOG(i);
100- LOG (" END" );
101- break ;
102- } else {
103- code -= 257 ;
104- unsigned int length = lengths[code];
105- length += actualData.read (end, lengthsExtraBits[code]);
106- end += lengthsExtraBits[code];
107-
108- unsigned int offsetCode = actualData.read (end, 5 , true );
109- end += 5 ;
110- unsigned int offset = offsets[offsetCode];
111- offset += actualData.read (end, offsetsExtraBits[offsetCode]);
112- end += offsetsExtraBits[offsetCode];
113-
114- LOG (" <" << offset << " , " << length << " >" );
115- for (int i = 0 ; i < length; i++) {
116- stream.emplace_back (stream[stream.size () - offset]);
134+ LOG (" END" );
135+ break ;
136+ } else {
137+ code -= 257 ;
138+ unsigned int length = lengths[code];
139+ length += actualData.read (end, lengthsExtraBits[code]);
140+ end += lengthsExtraBits[code];
141+
142+ unsigned int offsetCode = actualData.read (end, 5 , true );
143+ end += 5 ;
144+ unsigned int offset = offsets[offsetCode];
145+ offset += actualData.read (end, offsetsExtraBits[offsetCode]);
146+ end += offsetsExtraBits[offsetCode];
147+
148+ LOG (" <" << length << " , " << offset << " >" );
149+ for (int i = 0 ; i < length; i++) {
150+ stream.emplace_back (stream[stream.size () - offset]);
151+ }
117152 }
118153 }
119154 }
120-
121- LOG (" " );
122-
123-
155+
156+ LOG (" \n " );
157+
158+
159+ #if 0
124160 std::vector<unsigned int> imageArray;
125161 imageArray.reserve(format.width * format.height);
126-
162+
127163 for (int y = 0; y < format.height; y++) {
128164 for (int x = 0; x < format.width; x++) {
129165 int i = 1 + 4 * x + y * (1 + format.width * 4);
@@ -133,10 +169,9 @@ int main() {
133169 imageArray.push_back(stream[i + 3]);
134170 }
135171 }
136-
172+
137173 for (int y = 0; y < format.height; y++) {
138174 for (int x = 0; x < format.width; x++) {
139- // int i = 1 + y + (y * (format.width) + x) * 4;
140175 int i = (y * (format.width) + x) * 4;
141176 int r = imageArray[i];
142177 int g = imageArray[i + 1];
@@ -149,5 +184,7 @@ int main() {
149184 }
150185 std::printf("\n");
151186 }
152-
187+ #endif
188+
189+ return 0 ;
153190}
0 commit comments