33#include "std/memory_access.h"
44#include "compression/huffman.h"
55#include "std/memory.h"
6+ #include "math/math.h"
67
78typedef struct png_chunk_hdr {
89 uint32_t length ;
@@ -34,23 +35,6 @@ typedef union zlib_hdr {
3435 uint16_t hdr ;
3536}__attribute__((packed )) zlib_hdr ;
3637
37- typedef union deflate_dynamic_hdr {
38- struct {
39- uint32_t bfinal : 1 ;
40- uint32_t btype : 2 ;
41- uint32_t hlit : 5 ;
42-
43- uint32_t hdist : 5 ;
44- uint32_t hclen1 : 3 ;
45-
46- uint32_t hclen2 : 1 ;
47- uint32_t rsvd : 7 ;
48-
49- uint32_t rsvd2 : 8 ;
50- };
51- uint32_t value ;
52- } deflate_dynamic_hdr ;
53-
5438huff_tree_node * deflate_decode_codes (uint8_t max_code_length , uint16_t alphabet_length , uint16_t lengths []){
5539 uint8_t bl_count [max_code_length ] = {};
5640 for (int i = 0 ; i < max_code_length ; i ++ ){
@@ -93,7 +77,7 @@ huff_tree_node* deflate_decode_codes(uint8_t max_code_length, uint16_t alphabet_
9377} while(0)
9478
9579#define READ_BITS (from , to , amount , bs , c ) do { \
96- if (bs+ amount > 16) \
80+ if (bs + amount > 16) \
9781 to = (((uint16_t)from[c+2] << (16-bs)) & ((1 << amount) - 1)) | \
9882 (((uint16_t)from[c+1] << (8-bs)) & ((1 << amount) - 1)) | \
9983 (((uint16_t)from[c] >> bs) & ((1 << amount) - 1) ); \
@@ -131,169 +115,182 @@ uint32_t dist_bases[] = {
131115 /*13*/ 16385 , 24577 //28-29
132116};
133117
134- size_t png_load_idat (void * ptr , size_t size , uint8_t * output_buf ){
135- //DEFLATE func
118+ size_t deflate_decode (void * ptr , size_t size , uint8_t * output_buf ){
136119 zlib_hdr hdr = * (zlib_hdr * )ptr ;
137120 if (hdr .cm != 8 ){
138121 printf ("Only DEFLATE is supported" );
139122 }
140123 uintptr_t p = (uintptr_t )ptr + sizeof (zlib_hdr );
141- //TODO: move to deflate header
142- deflate_dynamic_hdr dyn_hdr = (deflate_dynamic_hdr )read_unaligned32 ((uint32_t * )p );
143- uint8_t hclen = (dyn_hdr .hclen1 ) | (dyn_hdr .hclen2 << 3 );
144- printf ("HCLEN %b %b" ,dyn_hdr .hclen1 ,dyn_hdr .hclen2 );
145- printf ("DEFLATE DYNAMIC HEADER. LAST? %i. Type %i. HLIT %i, HDIST %i, HCLEN2 %i" , dyn_hdr .bfinal , dyn_hdr .btype , dyn_hdr .hlit , dyn_hdr .hdist , hclen );
146124
147- p += 2 ;
148- uint8_t bs = 1 ;
149125 uint8_t * bytes = (uint8_t * )p ;
126+ uint8_t bs = 0 ;
150127 int c = 0 ;
151- uint8_t code_order [19 ] = {16 , 17 , 18 , 0 , 8 , 7 , 9 , 6 , 10 , 5 , 11 , 4 , 12 , 3 , 13 , 2 , 14 , 1 , 15 };
152- uint16_t permuted [19 ] = {};
153- for (uint8_t i = 0 ; i < hclen + 4 ; i ++ ){
154- READ_BITS (bytes , permuted [code_order [i ]], 3 , bs , c );
155- printf ("[%i] = %i" ,code_order [i ],permuted [code_order [i ]]);
156- ADVANCE_BIT (bs , c , 3 );
157- }
158- huff_tree_node * huff_decode_nodes = deflate_decode_codes (8 , 19 , permuted );
159-
160- huffman_viz (huff_decode_nodes , 0 , 0 );
161-
162- int tree_data_size = dyn_hdr .hlit + dyn_hdr .hdist + 258 ;
128+ bool final = false;
129+ uintptr_t out_cursor = 0 ;
163130
164- printf ("Expecting to read %i" ,tree_data_size );
131+ while (!final ){
132+ uint8_t hclen = 0 ;//4
133+ uint8_t hdist = 0 ;//5
134+ uint8_t hlit = 0 ;//5
135+ uint8_t btype = 0 ;//2
136+ READ_BITS (bytes , final , 1 , bs , c );
137+ ADVANCE_BIT (bs , c , 1 );
138+ READ_BITS (bytes , btype , 2 , bs , c );
139+ ADVANCE_BIT (bs , c , 2 );
140+ READ_BITS (bytes , hlit , 5 , bs , c );
141+ ADVANCE_BIT (bs , c , 5 );
142+ READ_BITS (bytes , hdist , 5 , bs , c );
143+ ADVANCE_BIT (bs , c , 5 );
144+ READ_BITS (bytes , hclen , 4 , bs , c );
145+ ADVANCE_BIT (bs , c , 4 );
146+ printf ("DEFLATE DYNAMIC HEADER. LAST? %i. Type %i. HLIT %i, HDIST %i, HCLEN %i" , final , btype , hlit , hdist , hclen );
147+
148+ uint8_t code_order [19 ] = {16 , 17 , 18 , 0 , 8 , 7 , 9 , 6 , 10 , 5 , 11 , 4 , 12 , 3 , 13 , 2 , 14 , 1 , 15 };
149+ uint16_t permuted [19 ] = {};
150+ for (uint8_t i = 0 ; i < hclen + 4 ; i ++ ){
151+ READ_BITS (bytes , permuted [code_order [i ]], 3 , bs , c );
152+ ADVANCE_BIT (bs , c , 3 );
153+ }
154+ huff_tree_node * huff_decode_nodes = deflate_decode_codes (8 , 19 , permuted );
155+
156+ huffman_viz (huff_decode_nodes , 0 , 0 );
157+
158+ int tree_data_size = hlit + hdist + 258 ;
165159
166- huff_tree_node * tree_root = huff_decode_nodes ;
160+ printf ( "Expecting to read %i" , tree_data_size ) ;
167161
168- uint16_t * full_huffman = malloc ( sizeof ( uint16_t ) * tree_data_size ) ;
162+ huff_tree_node * tree_root = huff_decode_nodes ;
169163
170- uint16_t last_code_len = 0 ;
164+ uint16_t * full_huffman = malloc ( sizeof ( uint16_t ) * tree_data_size ) ;
171165
172- for (int i = 0 ; i < tree_data_size ;){
173- uint8_t next_bit ;
174- READ_BITS (bytes , next_bit , 1 , bs , c );
175- ADVANCE_BIT (bs , c , 1 );
176- tree_root = huffman_traverse (tree_root , next_bit );
177- if (!tree_root ) {
178- printf ("DEFLATE ERROR: no tree found" );
179- return 0 ;
180- }
181- if (!tree_root -> left && !tree_root -> right ){
182- uint8_t extra = 0 ;
183- switch (tree_root -> entry ){
184- case 16 :
185- READ_BITS (bytes , extra , 2 , bs , c );
186- extra += 3 ;
187- ADVANCE_BIT (bs , c , 2 );
188- for (int j = 0 ; j < extra ; j ++ )
189- full_huffman [i + j ] = last_code_len ;
190- break ;
191- case 17 :
192- READ_BITS (bytes , extra , 3 , bs , c );
193- extra += 3 ;
194- ADVANCE_BIT (bs , c , 3 );
195- for (int j = 0 ; j < extra ; j ++ )
196- full_huffman [i + j ] = 0 ;
197- break ;
198- case 18 :
199- READ_BITS (bytes , extra , 7 , bs , c );
200- extra += 11 ;
201- ADVANCE_BIT (bs , c , 7 );
202- for (int j = 0 ; j < extra ; j ++ )
203- full_huffman [i + j ] = 0 ;
204- break ;
205- default :
206- full_huffman [i ] = tree_root -> entry ;
207- break ;
166+ uint16_t last_code_len = 0 ;
167+
168+ for (int i = 0 ; i < tree_data_size ;){
169+ uint8_t next_bit = 0 ;
170+ READ_BITS (bytes , next_bit , 1 , bs , c );
171+ ADVANCE_BIT (bs , c , 1 );
172+ tree_root = huffman_traverse (tree_root , next_bit );
173+ if (!tree_root ) {
174+ printf ("DEFLATE ERROR: no tree found" );
175+ return 0 ;
176+ }
177+ if (!tree_root -> left && !tree_root -> right ){
178+ uint8_t extra = 0 ;
179+ switch (tree_root -> entry ){
180+ case 16 :
181+ READ_BITS (bytes , extra , 2 , bs , c );
182+ extra += 3 ;
183+ ADVANCE_BIT (bs , c , 2 );
184+ for (int j = 0 ; j < extra ; j ++ )
185+ full_huffman [i + j ] = last_code_len ;
186+ break ;
187+ case 17 :
188+ READ_BITS (bytes , extra , 3 , bs , c );
189+ extra += 3 ;
190+ ADVANCE_BIT (bs , c , 3 );
191+ for (int j = 0 ; j < extra ; j ++ )
192+ full_huffman [i + j ] = 0 ;
193+ break ;
194+ case 18 :
195+ READ_BITS (bytes , extra , 7 , bs , c );
196+ extra += 11 ;
197+ ADVANCE_BIT (bs , c , 7 );
198+ for (int j = 0 ; j < extra ; j ++ )
199+ full_huffman [i + j ] = 0 ;
200+ break ;
201+ default :
202+ full_huffman [i ] = tree_root -> entry ;
203+ break ;
204+ }
205+ tree_root = huff_decode_nodes ;
206+ if (extra )
207+ i += extra ;
208+ else i ++ ;
209+ last_code_len = tree_root -> entry ;
208210 }
209- tree_root = huff_decode_nodes ;
210- if (extra )
211- i += extra ;
212- else i ++ ;
213- last_code_len = tree_root -> entry ;
214211 }
215- }
216- printf ("Finished processing data" );
217- // huffman_free(huff_decode_nodes);
212+ // huffman_free(huff_decode_nodes);
218213
219- printf ("**** LITERAL/LENGTH ****" );
220- huff_tree_node * litlen_tree = deflate_decode_codes (dyn_hdr . hlit + 257 , dyn_hdr . hlit + 257 , full_huffman );
221- huffman_viz (litlen_tree , 0 , 0 );
214+ printf ("**** LITERAL/LENGTH ****" );
215+ huff_tree_node * litlen_tree = deflate_decode_codes (hlit + 257 , hlit + 257 , full_huffman );
216+ huffman_viz (litlen_tree , 0 , 0 );
222217
223- printf ("**** DISTANCE ****" );
224- huff_tree_node * dist_tree = deflate_decode_codes (dyn_hdr . hdist + 1 , dyn_hdr . hdist + 1 , full_huffman + dyn_hdr . hlit + 257 );
218+ printf ("**** DISTANCE ****" );
219+ huff_tree_node * dist_tree = deflate_decode_codes (hdist + 1 , hdist + 1 , full_huffman + hlit + 257 );
225220
226- huffman_viz (dist_tree , 0 , 0 );
227- printf ("**** WOO ****" );
221+ huffman_viz (dist_tree , 0 , 0 );
222+ // printf("**** WOO ****");
228223
229- // free(full_huffman, tree_data_size * sizeof(uint16_t));
224+ // free(full_huffman, tree_data_size * sizeof(uint16_t));
230225
231- tree_root = litlen_tree ;
226+ tree_root = litlen_tree ;
232227
233- uintptr_t out_cursor = 0 ;
234-
235- printf ( "Compressed data at %x" , bytes + c ) ;
236-
237- uint16_t val = 0 ;
238- while ( val != 0x100 ){
239- uint8_t next_bit ;
240- READ_BITS ( bytes , next_bit , 1 , bs , c );
241- ADVANCE_BIT ( bs , c , 1 );
242- tree_root = huffman_traverse ( tree_root , next_bit );
243- if (! tree_root ) {
244- printf ( "DEFLATE ERROR: no tree found" ) ;
245- return 0 ;
246- }
247- if (! tree_root -> left && ! tree_root -> right ){
248- val = tree_root -> entry ;
249- if (val < 0x100 ){
250- output_buf [ out_cursor ] = ( val & 0xFF );
251- // printf("Literal %x",val) ;
252- out_cursor ++ ;
253- } else if ( val == 0x100 ){
254- break ;
255- } else {
256- uint8_t extra = 0 ;
257- if ( val > 264 && val < 285 )
258- extra = ( val - 261 )/ 4 ;
259- uint16_t extra_val = 0 ;
260- READ_BITS ( bytes , extra_val , extra , bs , c );
261- ADVANCE_BIT ( bs , c , extra ) ;
262- uint16_t length = base_lengths [ val - 257 ] + extra_val ;
263- huff_tree_node * dist_node = dist_tree ;
264- while ( dist_node -> left || dist_node -> right ){
265- READ_BITS ( bytes , next_bit , 1 , bs , c );
266- ADVANCE_BIT ( bs , c , 1 );
267- dist_node = huffman_traverse ( dist_node , next_bit );
268- if (! dist_node ){
269- printf ( "DEFLATE ERROR: no tree found" ) ;
270- return 0 ;
228+ printf ( "Compressed data at %x" , bytes + c ) ;
229+
230+ uint16_t val = 0 ;
231+ while ( val != 0x100 ){
232+ uint8_t next_bit = 0 ;
233+ READ_BITS ( bytes , next_bit , 1 , bs , c );
234+ ADVANCE_BIT ( bs , c , 1 ) ;
235+ printf ( "%x" , next_bit );
236+ tree_root = huffman_traverse ( tree_root , next_bit );
237+ if (! tree_root ) {
238+ printf ( "DEFLATE ERROR: no tree found" );
239+ return 0 ;
240+ }
241+ if (! tree_root -> left && ! tree_root -> right ){
242+ val = tree_root -> entry ;
243+ if ( val < 0x100 ){
244+ output_buf [ out_cursor ] = (val & 0xFF );
245+ printf ( "Literal %x" , output_buf [ out_cursor ] );
246+ out_cursor ++ ;
247+ } else if ( val == 0x100 ){
248+ break ;
249+ } else {
250+ uint8_t extra = 0 ;
251+ if ( val > 264 && val < 285 )
252+ extra = ( val - 261 )/ 4 ;
253+ uint16_t extra_val = 0 ;
254+ READ_BITS ( bytes , extra_val , extra , bs , c ) ;
255+ ADVANCE_BIT ( bs , c , extra );
256+ uint16_t length = base_lengths [ val - 257 ] + extra_val ;
257+ huff_tree_node * dist_node = dist_tree ;
258+ while ( dist_node -> left || dist_node -> right ){
259+ READ_BITS ( bytes , next_bit , 1 , bs , c );
260+ ADVANCE_BIT ( bs , c , 1 );
261+ dist_node = huffman_traverse ( dist_node , next_bit );
262+ if (! dist_node ){
263+ printf ( "DEFLATE ERROR: no tree found" );
264+ return 0 ;
265+ }
271266 }
267+ uint16_t dist_base = dist_node -> entry ;
268+ uint8_t extra_dist = 0 ;
269+ uint16_t extra_dist_val = 0 ;
270+ if (dist_base > 3 ){
271+ extra_dist = (dist_base - 2 )/2 ;
272+ READ_BITS (bytes , extra_dist_val , extra_dist , bs , c );
273+ ADVANCE_BIT (bs , c , extra_dist );
274+ }
275+ // printf("Dista base %i + extra %i",dist_base,extra_dist);
276+ uint32_t distance = dist_bases [dist_base ] + extra_dist_val ;
277+ // printf("Last %x",output_buf[out_cursor-1]);
278+ // printf("Copying %i bytes from %i bytes back. %x + %x",length,distance,output_buf, out_cursor);
279+ memcpy (output_buf - distance + out_cursor - 1 , output_buf + out_cursor , length );
280+ printf ("Sanity check 1 %x" ,output_buf [distance + out_cursor ]);
281+ out_cursor += length ;
282+ // printf("Sanity check 2 %x",output_buf[out_cursor-1]);
272283 }
273- uint16_t dist_base = dist_node -> entry ;
274- uint8_t extra_dist = 0 ;
275- uint16_t extra_dist_val = 0 ;
276- if (dist_base > 3 ){
277- extra_dist = (dist_base - 2 )/2 ;
278- READ_BITS (bytes , extra_dist_val , extra_dist , bs , c );
279- ADVANCE_BIT (bs , c , extra_dist );
280- }
281- // printf("Dista base %i + extra %i",dist_base,extra_dist);
282- uint32_t distance = dist_bases [dist_base ] + extra_dist_val ;
283- // printf("Copying %i bytes from %i bytes back. %x + %x",length,distance,output_buf, out_cursor);
284- memcpy (output_buf - distance + out_cursor , output_buf + out_cursor , length );
285- out_cursor += length ;
284+ tree_root = litlen_tree ;
286285 }
287- tree_root = litlen_tree ;
288286 }
289287 }
290288
289+ printf ("Wrote a total of %i bytes" ,out_cursor );
290+
291291 // huffman_free(litlen_tree);
292292 // huffman_free(dist_tree);
293293
294- //TODO: other DEFLATE blocks
295- //TODO: generalize to DEFLATE funcs
296-
297294 return out_cursor ;
298295}
299296
@@ -332,7 +329,6 @@ uint64_t header = *(uint64_t*)file;
332329 uint32_t length = __builtin_bswap32 (hdr -> length );
333330 if (strstart (hdr -> type , "IHDR" , true) == 4 ){
334331 png_ihdr * ihdr = (png_ihdr * )(p + sizeof (png_chunk_hdr ));
335- printf ("Couldn't find png IHDR" );
336332 info = (image_info ){__builtin_bswap32 (ihdr -> width ),__builtin_bswap32 (ihdr -> height )};
337333 }
338334 if (strstart (hdr -> type , "IDAT" , true) == 4 ){
@@ -343,9 +339,12 @@ uint64_t header = *(uint64_t*)file;
343339 if (!out_buf ) out_buf = (uintptr_t )malloc (info .width * info .height * system_bpp );//TODO: bpp might be too big, read image format
344340 printf ("Found some idat %x" ,p + sizeof (png_chunk_hdr ) - (uintptr_t )file );
345341 uintptr_t prev_off = out_off ;
346- out_off += png_load_idat ((void * )(p + sizeof (png_chunk_hdr )), length , (uint8_t * )(out_buf + out_off ));
347- memcpy (buf + prev_off , (void * )out_buf , out_off );
348- // return;
342+ out_off += deflate_decode ((void * )(p + sizeof (png_chunk_hdr )), length , (uint8_t * )(out_buf + out_off ));
343+ memcpy (buf + prev_off , (void * )out_buf , min (out_off , size - prev_off ));
344+ // for (uint32_t i = 0; i < out_off; i++){
345+ // printf("[%i] = %x",i, out_buf[i]);
346+ // }
347+ return ;
349348 }
350349 p += sizeof (png_chunk_hdr ) + __builtin_bswap32 (hdr -> length ) + sizeof (uint32_t );
351350 } while (strstart (hdr -> type , "IEND" , true) != 4 );
0 commit comments