3
* @brief lib for read and draw PNG
6
* @author Filipp Chubukov
22
#include <fs/file_format.h>
24
#define CHUNK_INFO_LEN 12 /* 4 = length, 4 = name, 4 = crc */
26
/* 256 literals, end code, length codes + 2 unused codes */
27
#define NUMBER_OF_CODE_SYMBOLS 288
29
/* the distance codes have their own symbols, 30 used, 2 unused */
30
#define NUMBER_OF_DISTANCE_SYMBOLS 32
33
#define NUMBER_OF_LENGTH_CODES 19
34
#define FIRST_LENGTH_INDEX 257
35
#define LAST_LENGTH_INDEX 285
38
* the base of distances(the bits of distance
39
* codes appear after length codes and use their own huffman tree)
41
static const int DISTANCE_BASE[30]
42
= {1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513,
43
769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577};
45
/* addit bits of distances (added to base)*/
46
static const int DISTANCE_ADDITIONAL[30]
47
= {0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8,
48
8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13};
50
/* represented by codes 257-285 */
51
static const int LENGTH_BASE[29]
52
= {3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59,
53
67, 83, 99, 115, 131, 163, 195, 227, 258};
55
/* addit bits with codes 257-285 (added to base length) */
56
static const int LENGTH_ADDITIONAL[29]
57
= {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
58
4, 4, 4, 4, 5, 5, 5, 5, 0};
60
* the order in which "code length alphabet code lengths" are stored, out of this
61
* the huffman tree of the dynamic huffman tree lengths is generated
63
static const int CLCL_ORDER[NUMBER_OF_LENGTH_CODES]
64
= {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
66
static const char *list_of_chunks = "IDATIENDbKGDcHRMdSIGeXIFgAMAhISTiCCPiTXtpHYssBITsPLTsRGBsTERtEXttIMEtRNSzTXt";
68
#define READBIT(bitpointer, bitstream) ((bitstream[bitpointer >> 3] >> (bitpointer & 0x7)) & (uint8_t)1)
70
#define IHDR_END 33 /* position of end of IHDR chunk */
71
#define IHDR_SIZE 13 /* len of IHDR data */
73
void png_unload(struct png *png_data) {
77
png_data->image_size = 0;
79
free(png_data->image);
87
uint8_t color_type; /* 1 - plt, 2 - RGB, 4 or 6 - RGBA */
88
uint8_t compression_method; /* == 0 - deflate */
89
uint8_t filter_method; /* == 0 */
90
uint8_t interlace_method; /* 0 - standart, 1 - Adam7 */
93
/* def Huffmantree struct and functions to work with it */
94
typedef struct HuffmanTree {
97
int *lengths; /* lengths of the codes(tree1d) */
98
int maxbitlen; /* max bits that single code can get */
99
int num_of_codes; /* number of symbols in the alph */
102
static void HuffmanTree_init(HuffmanTree* tree) {
108
static void HuffmanTree_cleanup(HuffmanTree* tree) {
114
/* fun to decode symbols, return decoded symbol or error(-1) */
115
static int huffman_decode_symbol(uint8_t* in, int* bp,
116
HuffmanTree* tree, int inbitlength) {
118
/* endless 'for' until get symbol or get error */
120
if (*bp >= inbitlength) {
121
return -1; /* error: end of input memory reached without endcode */
123
tmp = tree->tree2d[(pos << 1) + READBIT(*bp, in)];
126
if (tmp < tree->num_of_codes) {
127
return tmp; /*get decoded symbol, return it*/
129
pos = tmp - tree->num_of_codes; /* not yet symbol, continue */
132
if (pos >= tree->num_of_codes) {
133
return -1; /* error: it appeared outside the codetree */
139
* make from tree1d[] tree2d[][]. value = 6666 means not init
140
* value < number_of_codes is a codes
141
* value >= number_of_codes is an address to another bit
142
* The 2 rows are the 2 possible bit values (0 or 1), there are as
143
* many columns as codes - 1.
145
static int make_tree2d(HuffmanTree *tree) {
146
int nodefill_info = 0;
147
int pos = 0; /* pos in the tree */
150
tree->tree2d = (int*)malloc(tree->num_of_codes * 2 * sizeof(int));
152
log_error("Malloc error.");
156
for (n = 0; n < tree->num_of_codes * 2; n++) {
157
tree->tree2d[n] = 6666; /* 6666 means not filled */
160
for (n = 0; n < tree->num_of_codes; n++) /* the codes */ {
161
for (i = 0; i != tree->lengths[n]; i++) /* the bits for this code */ {
163
uint8_t bit = (uint8_t)((tree->tree1d[n] >> (tree->lengths[n] - i - 1)) & 1);
164
if (tree->tree2d[2 * pos + bit] == 6666) /* not yet filled */ {
165
if (i + 1 == tree->lengths[n]) /* last bit */ {
166
tree->tree2d[2 * pos + bit] = n; /* put the current code in it */
169
/* put address of the next step, it's (nodefilled + 1) */
171
/* addresses encoded with numcodes added to it */
172
tree->tree2d[2 * pos + bit] = nodefill_info + tree->num_of_codes;
176
pos = tree->tree2d[2 * pos + bit] - tree->num_of_codes;
180
for (n = 0; n < tree->num_of_codes * 2; n++) {
181
if (tree->tree2d[n] == 6666) {
182
tree->tree2d[n] = 0; /* remove possible remaining 6666 */
189
* Second step of making tree.
190
* num_of_codes, lengths need to be filled.
191
* return 0 with success or error.
193
static int make_tree_second_step(HuffmanTree *tree) {
194
int blcount[tree->maxbitlen + 1];
195
int nextcode[tree->maxbitlen + 1];
198
for (i = 0; i < tree->maxbitlen + 1; i++) {
203
tree->tree1d = (int*)malloc(tree->num_of_codes * sizeof(int));
205
log_error("Malloc error.");
208
/* step 1: count number of instances of each code length */
209
for (bits = 0; bits != tree->num_of_codes; bits++) {
210
blcount[tree->lengths[bits]]++;
213
/* step 2: generate the nextcode values */
214
for (bits = 1; bits <= tree->maxbitlen; bits++) {
215
nextcode[bits] = (nextcode[bits - 1] + blcount[bits - 1]) << 1;
218
/* step 3: generate all the codes */
219
for (i = 0; i != tree->num_of_codes; i++) {
220
if (tree->lengths[i] != 0) tree->tree1d[i] = nextcode[tree->lengths[i]]++;
223
return make_tree2d(tree);
227
* first step of making tree, generate the tree as defined
229
* return 0 with success of error.
231
static int make_tree_first_step(HuffmanTree *tree, int *bitlen,
232
int number_of_codes, int maxbitlen) {
235
tree->lengths = (int*)malloc(number_of_codes * sizeof(int));
236
if (!tree->lengths) {
237
log_error("Malloc error.");
241
for (i = 0; i != number_of_codes; i++) {
242
tree->lengths[i] = bitlen[i];
245
tree->num_of_codes = number_of_codes; /* number of symbols */
246
tree->maxbitlen = maxbitlen;
248
return make_tree_second_step(tree);
251
/* fun for reading bits from stream */
252
static int read_bits_from_stream(int *bitpointer, uint8_t *bitstream, int nbits) {
254
for (i = 0; i != nbits; i++) {
255
result += ((int)READBIT(*bitpointer, bitstream)) << i;
261
/* get the tree with dynamic huffman blocks */
262
static int build_dynamic_trees(HuffmanTree *ll_tree, HuffmanTree *dist_tree,
263
uint8_t *in, int *bp, int inlen) {
265
int n, HLIT, HDIST, HCLEN, i;
266
int in_bitlen = inlen * 8;
267
HuffmanTree cl_tree; /* the huffman tree for compressed huffman trees */
268
int bitlen_ll[NUMBER_OF_CODE_SYMBOLS]; /* lit,len code lengths */
269
int bitlen_d[NUMBER_OF_DISTANCE_SYMBOLS];
271
* the bit lengths of the huffman tree used for
272
* compress bitlen_ll and bitlen_d
274
int bitlen_cl[NUMBER_OF_LENGTH_CODES];
275
int replength, value, code;
276
/* number of literal/length codes + 257 added by spec */
277
HLIT = read_bits_from_stream(bp, in, 5) + 257;
278
/* number of distance codes + 1 added by spec */
279
HDIST = read_bits_from_stream(bp, in, 5) + 1;
280
/* number of code length codes + 4 added by spec */
281
HCLEN = read_bits_from_stream(bp, in, 4) + 4;
283
HuffmanTree_init(&cl_tree);
286
/* read the code length codes out of 3 * (amount of code length codes) bits */
287
for (i = 0; i != NUMBER_OF_LENGTH_CODES; i++) {
289
bitlen_cl[CLCL_ORDER[i]] = read_bits_from_stream(bp, in, 3);
291
bitlen_cl[CLCL_ORDER[i]] = 0; /*if not, it must stay 0*/
294
err = make_tree_first_step(&cl_tree, bitlen_cl, NUMBER_OF_LENGTH_CODES, 7);
298
/* now we can use this tree to read the lengths for cl_tree */
300
for (i = 0; i != NUMBER_OF_CODE_SYMBOLS; i++) {
304
for (i = 0; i != NUMBER_OF_DISTANCE_SYMBOLS; i++) {
308
* i is the current symbol we're reading in the part
309
* that contains the code lengths of lit/len and dist codes
313
while (i < HLIT + HDIST) {
315
code = huffman_decode_symbol(in, bp, &cl_tree, in_bitlen);
317
if (code <= 15) /* a length code */ {
321
bitlen_d[i - HLIT] = code;
324
} else if (code == 16) /* repeat previous */ {
325
replength = 3; /* read in the 2 bits that indicate repeat length (3-6) */
328
err = -1; /* can't repeat previous if i is 0 */
332
if ((*bp + 2) > in_bitlen) {
333
err = -1; /* error, bit pointer jumps past memory */
336
replength += read_bits_from_stream(bp, in, 2);
339
value = bitlen_ll[i - 1];
341
value = bitlen_d[i - HLIT - 1];
343
/* repeat this value in the next lengths */
344
for (n = 0; n < replength; n++) {
345
if (i >= HLIT + HDIST) {
346
err = -1; /* error: i is larger than the amount of codes */
350
bitlen_ll[i] = value;
352
bitlen_d[i - HLIT] = value;
356
} else if (code == 17) /* repeat "0" 3-10 times */ {
357
replength = 3; /* read in the bits that indicate repeat length */
359
if ((*bp + 3) > in_bitlen) {
360
err = -1; /* error, bit pointer jumps past memory */
364
replength += read_bits_from_stream(bp, in, 3);
366
/* repeat this value in the next lengths */
367
for (n = 0; n < replength; n++) {
368
if (i >= HLIT + HDIST) {
369
return -1; /* error: i is larger than the amount of codes */
375
bitlen_d[i - HLIT] = 0;
379
} else if (code == 18) /* repeat "0" 11-138 times */ {
380
replength = 11; /* read in the bits that indicate repeat length */
381
if ((*bp + 7) > in_bitlen) {
382
err = -1; /* error, bit pointer jumps past memory */
385
replength += read_bits_from_stream(bp, in, 7);
387
/* repeat this value in the next lengths */
388
for (n = 0; n < replength; n++) {
389
if (i >= HLIT + HDIST) {
390
err = -1; /* error: i is larger than the amount of codes */
396
bitlen_d[i - HLIT] = 0;
402
err = -1; /* error in decodesymbol fun */
411
if (bitlen_ll[256] == 0) {
412
err = -1; /* the length of the end code 256 must be larger than 0 */
416
/* generate the code trees */
417
err = make_tree_first_step(ll_tree, bitlen_ll, NUMBER_OF_CODE_SYMBOLS, 15);
423
err = make_tree_first_step(dist_tree, bitlen_d, NUMBER_OF_DISTANCE_SYMBOLS, 15);
425
break; /* end of while (!err) */
427
HuffmanTree_cleanup(&cl_tree);
431
/* get the dist_tree with fixed huffman */
432
static int build_fixed_dist_tree(HuffmanTree *tree) {
434
int bitlen[NUMBER_OF_DISTANCE_SYMBOLS];
436
for (i = 0; i != NUMBER_OF_DISTANCE_SYMBOLS; i++) {
440
return make_tree_first_step(tree, bitlen, NUMBER_OF_DISTANCE_SYMBOLS, 15);
443
/* get the ll_tree with fixed huffman */
444
static int build_fixed_ll_tree(HuffmanTree *tree) {
446
int bitlen[NUMBER_OF_CODE_SYMBOLS];
447
/* fill bit lengths according unpacked values */
448
for (i = 0; i <= 143; i++) { /* codes from 00110000 to 10111111 */
452
for (i = 144; i <= 255; i++) { /* codes from 110010000 to 111111111 */
456
for (i = 256; i <= 279; i++) { /* codes from 0000000 to 0010111 */
460
for (i = 280; i <= 287; i++) { /* codes from 11000000 to 11000111 */
464
err = make_tree_first_step(tree, bitlen, NUMBER_OF_CODE_SYMBOLS, 15);
468
/* get the trees with fixed huffman blocks */
469
static int build_fixed_trees(HuffmanTree *ll_tree, HuffmanTree *dist_tree) {
471
err = build_fixed_ll_tree(ll_tree);
473
err = build_fixed_dist_tree(dist_tree);
478
static int inflate_huffman(uint8_t *out, uint8_t *in, int *bp,
479
int *pos, int in_length, int btype) {
481
HuffmanTree ll_tree; /* literal and length codes */
482
HuffmanTree dist_tree; /* distance codes */
483
int in_bitlen = in_length * 8;
484
int l_code, length_base; /* ll code and length */
485
int dist_code, dist; /* distance code and distance */
486
int addit_bits_ll, addit_bits_d; /* extra bits for length and distance */
487
int first_pos, forw, back;
489
/* build Huffman trees */
490
HuffmanTree_init(&ll_tree);
491
HuffmanTree_init(&dist_tree);
494
err = build_fixed_trees(&ll_tree, &dist_tree);
495
} else if (btype == 2) {
496
err = build_dynamic_trees(&ll_tree, &dist_tree, in, bp, in_length);
499
while (true) { /* decode symbols until error or end */
500
l_code = huffman_decode_symbol(in, bp, &ll_tree, in_bitlen); /* lit symbol */
503
out[*pos] = (uint8_t)l_code;
505
} else if (l_code >= FIRST_LENGTH_INDEX && l_code <= LAST_LENGTH_INDEX) {
507
/* step 1: get length_base */
508
length_base = LENGTH_BASE[l_code - FIRST_LENGTH_INDEX];
510
/* step 2: get additional bits and add them value to length_base */
511
addit_bits_ll = LENGTH_ADDITIONAL[l_code - FIRST_LENGTH_INDEX];
512
length_base += read_bits_from_stream(bp, in, addit_bits_ll);
514
/* step 3: get distance code and distance */
515
dist_code = huffman_decode_symbol(in, bp, &dist_tree, in_bitlen);
517
if (dist_code == -1) { /* decode_symbol return -1 */
518
err = 2; /* TODO table of errors */
522
if (dist_code > 29) { /* distance code cant be 30-32 */
526
dist = DISTANCE_BASE[dist_code];
528
/* step 4: get extra bits from distance */
529
addit_bits_d = DISTANCE_ADDITIONAL[dist_code];
530
dist += read_bits_from_stream(bp, in, addit_bits_d);
532
/* step 5: fill in all the out[n] values based on the length and dist */
534
back = first_pos - dist;
535
if (dist < length_base) {
536
for (forw = 0; forw < length_base; forw++) {
537
out[(*pos)++] = out[back++];
540
memcpy(out + *pos, out + back, length_base);
544
} else if (l_code == 256) {
545
break; /* end of code */
547
} else if (l_code == -1) { /* decodesymbol return -1 */
552
HuffmanTree_cleanup(&ll_tree);
553
HuffmanTree_cleanup(&dist_tree);
558
static uint8_t predictor(short a, short b, short c) {
559
short pa = abs(b - c);
560
short pb = abs(a - c);
561
short pc = abs(a + b - c - c);
563
if (pc < pa && pc < pb) {
565
} else if (pb < pa) {
572
static int unfilter_second_step(uint8_t *recon, const uint8_t *scanline,
573
const uint8_t *precon, int bytewidth, uint8_t filterType, int length) {
578
for (i = 0; i != length; i++) {
579
recon[i] = scanline[i];
584
for (i = 0; i != bytewidth; i++) {
585
recon[i] = scanline[i];
588
for (i = bytewidth; i < length; i++) {
589
recon[i] = scanline[i] + recon[i - bytewidth];
595
for (i = 0; i != length; i++) {
596
recon[i] = scanline[i] + precon[i];
599
for (i = 0; i != length; i++) {
600
recon[i] = scanline[i];
607
for (i = 0; i != bytewidth; i++) {
608
recon[i] = scanline[i] + (precon[i] >> 1);
610
for (i = bytewidth; i < length; i++) {
611
recon[i] = scanline[i] + ((recon[i - bytewidth] + precon[i]) >> 1);
614
for (i = 0; i != bytewidth; i++) {
615
recon[i] = scanline[i];
617
for (i = bytewidth; i < length; i++) {
618
recon[i] = scanline[i] + (recon[i - bytewidth] >> 1);
625
for (i = 0; i != bytewidth; i++) {
626
recon[i] = (scanline[i] + precon[i]);
628
for (i = bytewidth; i < length; i++) {
629
recon[i] = (scanline[i] + predictor(recon[i - bytewidth], precon[i], precon[i - bytewidth]));
632
for (i = 0; i != bytewidth; i++) {
633
recon[i] = scanline[i];
635
for (i = bytewidth; i < length; i++) {
636
recon[i] = (scanline[i] + recon[i - bytewidth]);
642
return -1; /* error in filter */
647
static int unfilter_first_step(uint8_t *out, const uint8_t *in, int w, int h, int bpp) {
649
uint8_t* prevline = 0;
651
int bytewidth = (bpp + 7) / 8;
652
int linebytes = (w * bpp + 7) / 8;
654
for (i = 0; i < h; i++) {
655
int outindex = linebytes * i;
656
int inindex = (1 + linebytes) * i;
657
uint8_t filterType = in[inindex];
659
if (unfilter_second_step(&out[outindex], &in[inindex + 1],
660
prevline, bytewidth, filterType, linebytes) == -1) {
661
log_error("Error in filter");
665
prevline = &out[outindex];
671
* 1)This function converts the filtered-padded-interlaced data in img
672
* 2)out: big enough for contain full image,
673
* 3)in: contain the full decompressed data from
674
* the IDAT chunks (with filter index bytes and possible padding bits)
676
* a) if no Adam7: 1) unfilter 2) TODO: remove padding bits (if bpp < 8)
677
* b) TODO: if adam7: 1) 7x unfilter 2) 7x remove padding bits 3) Adam7_deinterlace
678
* return 0 - success or error
680
static int after_decode_unfilter(uint8_t *out, uint8_t *in, int w, int h, int interflace, int bpp) {
681
if (interflace == 0) {
682
/* TODO removePaddingBits */
683
unfilter_first_step(out, in, w, h, bpp);
685
log_error("Adam7 not supported.");
692
* this function start of decoding IDAT
693
* out : buffer for decoded image, big enough for img
694
* in : contain IDAT bytes
695
* inlen : length of in(without zlib_head)
697
static int inflate(uint8_t *out, uint8_t *in, int inlen, struct png_header *png_head) {
698
int i, bp = 0;/* bit point in in */
699
int pos = 0;/*pos in out */
700
int btype;/* huffman type (1 - fixed/2 - dynamic) */
704
uint8_t *Huffman_out = (uint8_t*)malloc(png_head->width * png_head->height * 5);
705
if (Huffman_out == NULL) {
706
log_error("Malloc error.");
711
final = (uint8_t)(READBIT(bp, in));
713
btype = 1u * (int)(READBIT(bp, in));
715
btype += 2u * (int)(READBIT(bp, in));
717
if (inflate_huffman(Huffman_out, in, &bp, &pos, inlen, btype) != 0) {
718
log_error("Error : can't decode IDAT chunk.");
723
bpp = png_head->color_type * png_head->bit_depth;
725
if (png_head->color_type == PNG_GRSA) {
726
uint8_t *out_greyscale = (uint8_t*)malloc(png_head->width * png_head->height * PNG_GRSA);
728
if (after_decode_unfilter(out_greyscale, Huffman_out, png_head->width, png_head->height,
729
png_head->interlace_method, bpp) != 0) {
730
log_error("Error while unfilter");
736
for (i = 0; i < png_head->width * png_head->height; i++, out += 4) {
737
out[0] = out[1] = out[2] = out_greyscale[i * 2];
738
out[3] = out_greyscale[i * 2 + 1];
742
if (after_decode_unfilter(out, Huffman_out, png_head->width, png_head->height,
743
png_head->interlace_method, bpp) != 0) {
744
log_error("Error while unfilter");
755
/* return pos of chunk if list of chunks or -1 if error */
756
static int ident_chunk(uint8_t *chunk_name) {
760
if (memcmp(list_of_chunks, chunk_name, 4) == 0) {
761
list_of_chunks -= pos * 4;
770
static int count_IDAT(int fd) {
771
int chunk_num, pos = IHDR_END, idat_size = 0;
772
uint8_t chunk_name[4];
773
uint32_t chunk_length;
776
lseek(fd, pos, SEEK_SET);
777
if (read(fd, &chunk_length, sizeof(chunk_length)) != sizeof(chunk_length)) {
778
log_error("Can't read chunk.");
781
if (read(fd, chunk_name, sizeof(chunk_name)) != sizeof(chunk_name)) {
782
log_error("Can't read chunk.");
786
chunk_num = ident_chunk(chunk_name);
788
if (chunk_num == 1) {
795
idat_size += (int)htonl(chunk_length);
800
log_error("Error : invalid png file.");
804
/*one of not important chunks */
808
pos += CHUNK_INFO_LEN + (int)htonl(chunk_length);
812
/* Read IHDR chunk and get info */
813
static int read_IHDR(int fd, struct png_header *png_head) {
815
/* read and check IHDR data */
816
if (read(fd, png_head, IHDR_SIZE) != IHDR_SIZE) {
817
log_error("Error : can't read IHDR chunk.");
820
png_head->width = (int)htonl(png_head->width);
821
png_head->height = (int)htonl(png_head->height);
823
switch (png_head->color_type) {
825
log_error("pallete images are not supporting.");
828
png_head->color_type = PNG_TRCL;
832
png_head->color_type = PNG_GRSA;
836
png_head->color_type = PNG_TRCLA;
840
log_error("Error : invalid color type.");
844
if (png_head->compression_method != 0) {
845
log_error("Error : invalid compression method.");
849
if (png_head->filter_method != 0) {
850
log_error("Error : invalid filter method.");
854
if (png_head->interlace_method != 0 && png_head->interlace_method != 1) {
855
log_error("Error : invalid interlace method");
861
/* Now lib support main chunks and this fun is stub for work with other chunks*/
862
static void read_chunk(int fd, uint8_t *chunk_name) {
866
static int png_read(int fd, struct png *png_data) {
867
struct png_header png_head;
868
uint32_t chunk_length;
869
uint8_t *idat_buffer, *idat_data, chunk_name[4], zlib[2];
870
int chunk_num, i, idat_size, idat_oldsize = 0, idat_addsize, pos = IHDR_END;
874
* 1 - one IDAT was found
875
* 0 - IDAT not yet met
879
/* read IHDR chunk and put file info in struct png_header */
880
if (read(fd, &chunk_length, sizeof(chunk_length)) != sizeof(chunk_length)) {
881
log_error("Error : can't read IHDR chunk.");
885
if ((int)htonl(chunk_length) != IHDR_SIZE) {
886
log_error("Error : invalid length of IHDR data.");
890
if (read(fd, chunk_name, sizeof(chunk_name)) != sizeof(chunk_name)) {
891
log_error("Error : can't read IHDR chunk.");
895
if (memcmp(chunk_name, "IHDR", sizeof(chunk_name)) != 0) {
896
log_error("Error : invalid IHDR chunk.");
900
if (read_IHDR(fd, &png_head) != 0) {
904
png_data->width = png_head.width;
905
png_data->height = png_head.height;
906
png_data->color = png_head.color_type;
907
if (png_head.color_type == PNG_TRCL) {
908
png_data->image_size = png_head.width * png_head.height * PNG_TRCL;
910
png_data->image_size = png_head.width * png_head.height * PNG_TRCLA;
912
/* malloc mem for image */
913
png_data->image = (uint8_t*)malloc(png_data->image_size);
914
if (png_data->image == NULL) {
915
log_error("Malloc error.");
919
idat_size = count_IDAT(fd);
920
idat_data = (uint8_t*)malloc(idat_size);
921
if (idat_data == NULL) {
922
log_error("Malloc error.");
927
* Reading chunks until IEND
928
* its simple version and support just important chunks
929
* fun read_chunk is a stub
930
* TODO add reading of other chunks
933
lseek(fd, pos, SEEK_SET);
934
if (read(fd, &chunk_length, sizeof(chunk_length)) != sizeof(chunk_length)) {
935
log_error("Error : can't read chunk.");
936
free(png_data->image);
940
if (read(fd, chunk_name, sizeof(chunk_name)) != sizeof(chunk_name)) {
941
log_error("Error : can't read chunk.");
942
free(png_data->image);
947
chunk_num = ident_chunk(chunk_name);
949
if (chunk_num == 1) {
951
if (inflate(png_data->image, idat_data, idat_oldsize - sizeof(zlib), &png_head) != 0) {
952
log_error("Error while decode IDAT.");
953
free(png_data->image);
958
log_error("Error : there is no IDAT chunk in the file");
959
free(png_data->image);
969
if (read(fd, zlib, sizeof(zlib)) != sizeof(zlib)) {
970
log_error("Error : can't read chunk.");
971
free(png_data->image);
975
idat_addsize = (int)htonl(chunk_length) - 2;
977
idat_addsize = (int)htonl(chunk_length);
979
idat_buffer = (uint8_t*)malloc(idat_addsize);
980
if (idat_buffer == NULL) {
981
log_error("Malloc error.");
982
free(png_data->image);
987
if (read(fd, idat_buffer, idat_addsize) != idat_addsize) {
988
log_error("Error : can't read chunk.");
989
free(png_data->image);
995
for (i = 0; i < idat_addsize; i++) {
996
idat_data[idat_oldsize + i] = idat_buffer[i];
998
idat_oldsize += idat_addsize;
1005
if (flag_IDAT == 1) {
1006
log_error("Warning : IDAT was successfull decoded, but IEND was not found");
1010
log_error("Error : invalid png file.");
1011
free(png_data->image);
1016
read_chunk(fd, chunk_name);
1020
pos += CHUNK_INFO_LEN + (int)htonl(chunk_length);
1026
int png_load(char *file_name, struct png *png_data) {
1028
uint8_t signature[8];
1030
if (file_name == NULL) {
1034
if (png_data == NULL) {
1038
int fd = open(file_name, O_RDONLY);
1040
log_error("Error : can't open file.");
1044
if (read(fd, signature, sizeof(signature)) != sizeof(signature)) {
1045
log_error("Error : can't read signature of file.");
1050
if (raw_get_file_format(signature) != PNG_FILE) {
1051
log_error("Error : it's not PNG file");
1056
if (png_read(fd, png_data) != 0) {