embox

Форк
0
/
png.c 
1061 строка · 26.7 Кб
1
/**
2
 * @file
3
 * @brief lib for read and draw PNG
4
 *
5
 * @date May 10, 2019
6
 * @author Filipp Chubukov
7
 */
8

9
#include <stdio.h>
10
#include <stdlib.h>
11
#include <inttypes.h>
12
#include <stdbool.h>
13
#include <sys/stat.h>
14
#include <fcntl.h>
15
#include <unistd.h>
16
#include <string.h>
17
#include <sys/mman.h>
18
#include <sys/ioctl.h>
19
#include <lib/png.h>
20
#include <arpa/inet.h>
21
#include <util/log.h>
22
#include <fs/file_format.h>
23

24
#define CHUNK_INFO_LEN 12 /* 4 = length, 4 = name, 4 = crc */
25

26
/* 256 literals, end code, length codes + 2 unused codes */
27
#define NUMBER_OF_CODE_SYMBOLS 288
28

29
/* the distance codes have their own symbols, 30 used, 2 unused */
30
#define NUMBER_OF_DISTANCE_SYMBOLS 32
31

32
/* lengths codes */
33
#define NUMBER_OF_LENGTH_CODES 19
34
#define FIRST_LENGTH_INDEX 257
35
#define LAST_LENGTH_INDEX 285
36

37
/**
38
 * the base of distances(the bits of distance
39
 * codes appear after length codes and use their own huffman tree)
40
 */
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};
44

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};
49

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};
54

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};
59
/**
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
62
 */
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};
65

66
static const char *list_of_chunks = "IDATIENDbKGDcHRMdSIGeXIFgAMAhISTiCCPiTXtpHYssBITsPLTsRGBsTERtEXttIMEtRNSzTXt";
67

68
#define READBIT(bitpointer, bitstream) ((bitstream[bitpointer >> 3] >> (bitpointer & 0x7)) & (uint8_t)1)
69

70
#define IHDR_END 33 /* position of end of IHDR chunk */
71
#define IHDR_SIZE 13 /* len of IHDR data */
72

73
void png_unload(struct png *png_data) {
74
	png_data->width = 0;
75
	png_data->height = 0;
76
	png_data->color = 0;
77
	png_data->image_size = 0;
78

79
	free(png_data->image);
80
}
81

82
struct png_header {
83
	uint32_t width;
84
	uint32_t height;
85

86
	uint8_t bit_depth;
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 */
91
};
92

93
/* def Huffmantree struct and functions to work with it */
94
typedef struct HuffmanTree {
95
	int *tree2d;
96
	int *tree1d;
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 */
100
} HuffmanTree;
101

102
static void HuffmanTree_init(HuffmanTree* tree) {
103
	tree->tree2d = 0;
104
	tree->tree1d = 0;
105
	tree->lengths = 0;
106
}
107

108
static void HuffmanTree_cleanup(HuffmanTree* tree) {
109
	free(tree->tree2d);
110
	free(tree->tree1d);
111
	free(tree->lengths);
112
}
113

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) {
117
	int pos = 0, tmp;
118
	/* endless 'for' until get symbol or get error */
119
	for (;;) {
120
		if (*bp >= inbitlength) {
121
			return -1; /* error: end of input memory reached without endcode */
122
		}
123
		tmp = tree->tree2d[(pos << 1) + READBIT(*bp, in)];
124
		(*bp)++;
125

126
		if (tmp < tree->num_of_codes) {
127
			return tmp; /*get decoded symbol, return it*/
128
		} else {
129
			pos = tmp - tree->num_of_codes; /* not yet symbol, continue */
130
		}
131

132
		if (pos >= tree->num_of_codes) {
133
			return -1; /* error: it appeared outside the codetree */
134
		}
135
	}
136
}
137

138
/*
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.
144
 */
145
static int make_tree2d(HuffmanTree *tree) {
146
	int nodefill_info = 0;
147
	int pos = 0; /* pos in the tree */
148
	int i, n;
149

150
	tree->tree2d = (int*)malloc(tree->num_of_codes * 2 * sizeof(int));
151
	if (!tree->tree2d) {
152
		log_error("Malloc error.");
153
		return ENOMEM;
154
	}
155

156
	for (n = 0; n < tree->num_of_codes * 2; n++) {
157
		tree->tree2d[n] = 6666; /* 6666 means not filled */
158
	}
159

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 */ {
162

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 */
167
					pos = 0;
168
				} else {
169
					/* put address of the next step, it's (nodefilled + 1) */
170
					nodefill_info++;
171
					/* addresses encoded with numcodes added to it */
172
					tree->tree2d[2 * pos + bit] = nodefill_info + tree->num_of_codes;
173
					pos = nodefill_info;
174
				}
175
			} else {
176
				pos = tree->tree2d[2 * pos + bit] - tree->num_of_codes;
177
			}
178
		}
179
	}
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 */
183
		}
184
	}
185
	return 0;
186
}
187

188
/*
189
 * Second step of making tree.
190
 * num_of_codes, lengths need to be filled.
191
 * return 0 with success or error.
192
 */
193
static int make_tree_second_step(HuffmanTree *tree) {
194
	int blcount[tree->maxbitlen + 1];
195
	int nextcode[tree->maxbitlen + 1];
196
	int bits, i;
197

198
	for (i = 0; i < tree->maxbitlen + 1; i++) {
199
		blcount[i] = 0;
200
		nextcode[i] = 0;
201
	}
202

203
	tree->tree1d = (int*)malloc(tree->num_of_codes * sizeof(int));
204
	if (!tree->tree1d) {
205
		log_error("Malloc error.");
206
		return ENOMEM;
207
	} else {
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]]++;
211
		}
212

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;
216
		}
217

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]]++;
221
		}
222
	}
223
	return make_tree2d(tree);
224
}
225

226
/*
227
 * first step of making tree, generate the tree as defined
228
 * by Deflate.
229
 * return 0 with success of error.
230
 */
231
static int make_tree_first_step(HuffmanTree *tree, int *bitlen,
232
					int number_of_codes, int maxbitlen) {
233
	int i;
234

235
	tree->lengths = (int*)malloc(number_of_codes * sizeof(int));
236
	if (!tree->lengths) {
237
		log_error("Malloc error.");
238
		return ENOMEM;
239
	}
240

241
	for (i = 0; i != number_of_codes; i++) {
242
		tree->lengths[i] = bitlen[i];
243
	}
244

245
	tree->num_of_codes = number_of_codes; /* number of symbols */
246
	tree->maxbitlen = maxbitlen;
247

248
	return make_tree_second_step(tree);
249
}
250

251
/* fun for reading bits from stream */
252
static int read_bits_from_stream(int *bitpointer, uint8_t *bitstream, int nbits) {
253
	int result = 0, i;
254
	for (i = 0; i != nbits; i++) {
255
		result += ((int)READBIT(*bitpointer, bitstream)) << i;
256
		(*bitpointer)++;
257
	}
258
	return result;
259
}
260

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) {
264
	int err = 0;
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];
270
	/*
271
	 * the bit lengths of the huffman tree used for
272
	 * compress bitlen_ll and bitlen_d
273
	 */
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;
282

283
	HuffmanTree_init(&cl_tree);
284

285
	while (!err) {
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++) {
288
			if (i < HCLEN) {
289
				bitlen_cl[CLCL_ORDER[i]] = read_bits_from_stream(bp, in, 3);
290
			} else {
291
				bitlen_cl[CLCL_ORDER[i]] = 0; /*if not, it must stay 0*/
292
			}
293
		}
294
		err = make_tree_first_step(&cl_tree, bitlen_cl, NUMBER_OF_LENGTH_CODES, 7);
295
		if (err) {
296
			break;
297
		}
298
		/* now we can use this tree to read the lengths for cl_tree */
299

300
		for (i = 0; i != NUMBER_OF_CODE_SYMBOLS; i++) {
301
			bitlen_ll[i] = 0;
302
		}
303

304
		for (i = 0; i != NUMBER_OF_DISTANCE_SYMBOLS; i++) {
305
			bitlen_d[i] = 0;
306
		}
307
		/**
308
		 * i is the current symbol we're reading in the part
309
		 * that contains the code lengths of lit/len and dist codes
310
		 */
311
		i = 0;
312

313
		while (i < HLIT + HDIST) {
314

315
			code = huffman_decode_symbol(in, bp, &cl_tree, in_bitlen);
316

317
			if (code <= 15) /* a length code */ {
318
				if (i < HLIT) {
319
					bitlen_ll[i] = code;
320
				} else {
321
					bitlen_d[i - HLIT] = code;
322
				}
323
				i++;
324
			} else if (code == 16) /* repeat previous */ {
325
				replength = 3; /* read in the 2 bits that indicate repeat length (3-6) */
326

327
				if (i == 0) {
328
					err = -1; /* can't repeat previous if i is 0 */
329
					break;
330
				}
331

332
				if ((*bp + 2) > in_bitlen) {
333
					err = -1; /* error, bit pointer jumps past memory */
334
					break;
335
				}
336
				replength += read_bits_from_stream(bp, in, 2);
337

338
				if (i < HLIT + 1) {
339
					value = bitlen_ll[i - 1];
340
				} else {
341
					value = bitlen_d[i - HLIT - 1];
342
				}
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 */
347
						break;
348
					}
349
					if (i < HLIT) {
350
						bitlen_ll[i] = value;
351
					} else {
352
						bitlen_d[i - HLIT] = value;
353
					}
354
					i++;
355
				}
356
			} else if (code == 17) /* repeat "0" 3-10 times */ {
357
				replength = 3; /* read in the bits that indicate repeat length */
358

359
				if ((*bp + 3) > in_bitlen) {
360
					err = -1; /* error, bit pointer jumps past memory */
361
					break;
362
				}
363

364
				replength += read_bits_from_stream(bp, in, 3);
365

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 */
370
					}
371

372
					if (i < HLIT) {
373
						bitlen_ll[i] = 0;
374
					} else {
375
						bitlen_d[i - HLIT] = 0;
376
					}
377
					i++;
378
				}
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 */
383
					break;
384
				}
385
				replength += read_bits_from_stream(bp, in, 7);
386

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 */
391
						break;
392
					}
393
					if (i < HLIT) {
394
						bitlen_ll[i] = 0;
395
					} else {
396
						bitlen_d[i - HLIT] = 0;
397
					}
398
					i++;
399
				}
400
			} else {
401
				if (code == -1) {
402
					err = -1; /* error in decodesymbol fun */
403
					break;
404
				}
405
			}
406
		}
407
		if (err) {
408
			break;
409
		}
410

411
		if (bitlen_ll[256] == 0) {
412
			err = -1; /* the length of the end code 256 must be larger than 0 */
413
			break;
414
		}
415

416
		/* generate the code trees */
417
		err = make_tree_first_step(ll_tree, bitlen_ll, NUMBER_OF_CODE_SYMBOLS, 15);
418

419
		if (err) {
420
			break;
421
		}
422

423
		err = make_tree_first_step(dist_tree, bitlen_d, NUMBER_OF_DISTANCE_SYMBOLS, 15);
424

425
		break; /* end of while (!err) */
426
	}
427
	HuffmanTree_cleanup(&cl_tree);
428
	return err;
429
}
430

431
/* get the dist_tree with fixed huffman */
432
static int build_fixed_dist_tree(HuffmanTree *tree) {
433
	int i;
434
	int bitlen[NUMBER_OF_DISTANCE_SYMBOLS];
435

436
	for (i = 0; i != NUMBER_OF_DISTANCE_SYMBOLS; i++) {
437
		bitlen[i] = 5;
438
	}
439

440
	return make_tree_first_step(tree, bitlen, NUMBER_OF_DISTANCE_SYMBOLS, 15);
441
}
442

443
/* get the ll_tree with fixed huffman */
444
static int build_fixed_ll_tree(HuffmanTree *tree) {
445
	int i, err = 0;
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 */
449
		bitlen[i] = 8;
450
	}
451

452
	for (i = 144; i <= 255; i++) { /* codes from 110010000 to 111111111 */
453
		bitlen[i] = 9;
454
	}
455

456
	for (i = 256; i <= 279; i++) { /* codes from 0000000 to 0010111 */
457
		bitlen[i] = 7;
458
	}
459

460
	for (i = 280; i <= 287; i++) { /* codes from 11000000 to 11000111 */
461
		bitlen[i] = 8;
462
	}
463

464
	err = make_tree_first_step(tree, bitlen, NUMBER_OF_CODE_SYMBOLS, 15);
465
	return err;
466
}
467

468
/* get the trees with fixed huffman blocks */
469
static int build_fixed_trees(HuffmanTree *ll_tree, HuffmanTree *dist_tree) {
470
	int err;
471
	err = build_fixed_ll_tree(ll_tree);
472
	if (!err) {
473
		err = build_fixed_dist_tree(dist_tree);
474
	}
475
	return err;
476
}
477

478
static int inflate_huffman(uint8_t *out, uint8_t *in, int *bp,
479
								int *pos, int in_length, int btype) {
480
	int err = 0;
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;
488

489
	/* build Huffman trees */
490
	HuffmanTree_init(&ll_tree);
491
	HuffmanTree_init(&dist_tree);
492

493
	if (btype == 1) {
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);
497
	}
498

499
	while (true) { /* decode symbols until error or end */
500
		l_code = huffman_decode_symbol(in, bp, &ll_tree, in_bitlen);  /* lit symbol */
501

502
		if (l_code <= 255) {
503
			out[*pos] = (uint8_t)l_code;
504
			(*pos)++;
505
		} else if (l_code >= FIRST_LENGTH_INDEX && l_code <= LAST_LENGTH_INDEX) {
506

507
			/* step 1: get length_base */
508
			length_base = LENGTH_BASE[l_code - FIRST_LENGTH_INDEX];
509

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);
513

514
			/* step 3: get distance code and distance */
515
			dist_code = huffman_decode_symbol(in, bp, &dist_tree, in_bitlen);
516

517
			if (dist_code == -1) { /* decode_symbol return -1 */
518
				err = 2; /* TODO table of errors */
519
				break;
520
			}
521

522
			if (dist_code > 29) { /* distance code cant be 30-32 */
523
				err = 3;
524
				break;
525
			}
526
			dist = DISTANCE_BASE[dist_code];
527

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);
531

532
			/* step 5: fill in all the out[n] values based on the length and dist */
533
			first_pos = (*pos);
534
			back = first_pos - dist;
535
			if (dist < length_base) {
536
				for (forw = 0; forw < length_base; forw++) {
537
					out[(*pos)++] = out[back++];
538
				}
539
			} else {
540
				memcpy(out + *pos, out + back, length_base);
541
				*pos += length_base;
542
			}
543

544
		} else if (l_code == 256) {
545
			break; /* end of code */
546

547
		} else if (l_code == -1) { /* decodesymbol return -1 */
548
			err = 2;
549
			break;
550
		}
551
	}
552
	HuffmanTree_cleanup(&ll_tree);
553
	HuffmanTree_cleanup(&dist_tree);
554

555
	return err;
556
}
557

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);
562

563
	if (pc < pa && pc < pb) {
564
		return (uint8_t)c;
565
	} else if (pb < pa) {
566
		return (uint8_t)b;
567
	} else {
568
		return (uint8_t)a;
569
	}
570
}
571

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) {
574

575
	int i;
576
	switch(filterType) {
577
		case 0:
578
			for (i = 0; i != length; i++) {
579
				recon[i] = scanline[i];
580
			}
581
			break;
582

583
		case 1:
584
			for (i = 0; i != bytewidth; i++) {
585
				recon[i] = scanline[i];
586
			}
587

588
			for (i = bytewidth; i < length; i++) {
589
				recon[i] = scanline[i] + recon[i - bytewidth];
590
			}
591
			break;
592

593
		case 2:
594
			if (precon) {
595
				for (i = 0; i != length; i++) {
596
					recon[i] = scanline[i] + precon[i];
597
				}
598
			} else {
599
				for (i = 0; i != length; i++) {
600
					recon[i] = scanline[i];
601
				}
602
			}
603
			break;
604

605
		case 3:
606
			if (precon) {
607
				for (i = 0; i != bytewidth; i++) {
608
					recon[i] = scanline[i] + (precon[i] >> 1);
609
				}
610
				for (i = bytewidth; i < length; i++) {
611
					recon[i] = scanline[i] + ((recon[i - bytewidth] + precon[i]) >> 1);
612
				}
613
			} else {
614
				for (i = 0; i != bytewidth; i++) {
615
					recon[i] = scanline[i];
616
				}
617
				for (i = bytewidth; i < length; i++) {
618
					recon[i] = scanline[i] + (recon[i - bytewidth] >> 1);
619
				}
620
			}
621
			break;
622

623
		case 4:
624
			if (precon) {
625
				for (i = 0; i != bytewidth; i++) {
626
					recon[i] = (scanline[i] + precon[i]);
627
				}
628
				for (i = bytewidth; i < length; i++) {
629
					recon[i] = (scanline[i] + predictor(recon[i - bytewidth], precon[i], precon[i - bytewidth]));
630
				}
631
			} else {
632
				for (i = 0; i != bytewidth; i++) {
633
					recon[i] = scanline[i];
634
				}
635
				for (i = bytewidth; i < length; i++) {
636
					recon[i] = (scanline[i] + recon[i - bytewidth]);
637
				}
638
			}
639
			break;
640

641
		default:
642
			return -1; /* error in filter */
643
		}
644
		return 0;
645
}
646

647
static int unfilter_first_step(uint8_t *out, const uint8_t *in, int w, int h, int bpp) {
648
	int i;
649
	uint8_t* prevline = 0;
650

651
	int bytewidth = (bpp + 7) / 8;
652
	int linebytes = (w * bpp + 7) / 8;
653

654
	for (i = 0; i < h; i++) {
655
		int outindex = linebytes * i;
656
		int inindex = (1 + linebytes) * i;
657
		uint8_t filterType = in[inindex];
658

659
		if (unfilter_second_step(&out[outindex], &in[inindex + 1],
660
			prevline, bytewidth, filterType, linebytes) == -1) {
661
				log_error("Error in filter");
662
				return -1;
663
			}
664

665
		prevline = &out[outindex];
666
	}
667
	return 0;
668
}
669

670
/**
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)
675
 * 4)Steps:
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
679
*/
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);
684
	} else {
685
		log_error("Adam7 not supported.");
686
		return -1;
687
	}
688
	return 0;
689
}
690

691
/**
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)
696
*/
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) */
701
	int bpp;
702
	int final = 0;
703

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.");
707
		return ENOMEM;
708
	}
709

710
	while(!final) {
711
		final = (uint8_t)(READBIT(bp, in));
712
		bp++;
713
		btype = 1u * (int)(READBIT(bp, in));
714
		bp++;
715
		btype += 2u * (int)(READBIT(bp, in));
716
		bp++;
717
		if (inflate_huffman(Huffman_out, in, &bp, &pos, inlen, btype) != 0) {
718
			log_error("Error : can't decode IDAT chunk.");
719
			free(Huffman_out);
720
			return -1;
721
		}
722
	}
723
	bpp = png_head->color_type * png_head->bit_depth;
724

725
	if (png_head->color_type == PNG_GRSA) {
726
		uint8_t *out_greyscale = (uint8_t*)malloc(png_head->width * png_head->height * PNG_GRSA);
727

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");
731
			free(out_greyscale);
732
			free(Huffman_out);
733
			return -1;
734
		}
735

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];
739
		}
740
		free(out_greyscale);
741
	} else {
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");
745
			free(Huffman_out);
746
			return -1;
747
		}
748
	}
749
	free(Huffman_out);
750
	return 0;
751
}
752

753

754

755
/* return pos of chunk if list of chunks or -1 if error */
756
static int ident_chunk(uint8_t *chunk_name) {
757
	int pos = 0;
758

759
	while(pos < 19) {
760
		if (memcmp(list_of_chunks, chunk_name, 4) == 0) {
761
			list_of_chunks -= pos * 4;
762
			return pos;
763
		}
764
		list_of_chunks += 4;
765
		pos++;
766
	}
767
	return -1;
768
}
769

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;
774

775
	while (true) {
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.");
779
			return -1;
780
		}
781
		if (read(fd, chunk_name, sizeof(chunk_name)) != sizeof(chunk_name)) {
782
			log_error("Can't read chunk.");
783
			return -1;
784
		}
785

786
		chunk_num = ident_chunk(chunk_name);
787

788
		if (chunk_num == 1) {
789
			/* IEND chunk */
790
			return idat_size;
791
		}
792
		switch (chunk_num) {
793
			case 0:
794
				/* IDAT chunk */
795
				idat_size += (int)htonl(chunk_length);
796
				break;
797

798
			case -1:
799
				/* invalid chunk */
800
				log_error("Error : invalid png file.");
801
				return -1;
802

803
			default:
804
				/*one of not important chunks */
805
				break;
806
		}
807

808
		pos += CHUNK_INFO_LEN + (int)htonl(chunk_length);
809
	}
810
}
811

812
/* Read IHDR chunk and get info */
813
static int read_IHDR(int fd, struct png_header *png_head) {
814

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.");
818
		return -1;
819
	}
820
	png_head->width = (int)htonl(png_head->width);
821
	png_head->height = (int)htonl(png_head->height);
822

823
	switch (png_head->color_type) {
824
		case 1:
825
			log_error("pallete images are not supporting.");
826
			return -1;
827
		case 2:
828
			png_head->color_type = PNG_TRCL;
829
			break;
830

831
		case 4:
832
			png_head->color_type = PNG_GRSA;
833
			break;
834

835
		case 6:
836
			png_head->color_type = PNG_TRCLA;
837
			break;
838

839
		default:
840
			log_error("Error : invalid color type.");
841
			return -1;
842
		}
843

844
	if (png_head->compression_method != 0) {
845
		log_error("Error : invalid compression method.");
846
		return -1;
847
	}
848

849
	if (png_head->filter_method != 0) {
850
		log_error("Error : invalid filter method.");
851
		return -1;
852
	}
853

854
	if (png_head->interlace_method != 0 && png_head->interlace_method != 1) {
855
		log_error("Error : invalid interlace method");
856
		return -1;
857
	}
858
	return 0;
859
}
860

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) {
863
	return;
864
}
865

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;
871

872
	/**
873
	 * IDAT_flag
874
	 * 1 - one IDAT was found
875
	 * 0 - IDAT not yet met
876
	 */
877
	int flag_IDAT = 0;
878

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.");
882
		return -1;
883
	}
884

885
	if ((int)htonl(chunk_length) != IHDR_SIZE) {
886
		log_error("Error : invalid length of IHDR data.");
887
		return -1;
888
	}
889

890
	if (read(fd, chunk_name, sizeof(chunk_name)) != sizeof(chunk_name)) {
891
		log_error("Error : can't read IHDR chunk.");
892
		return -1;
893
	}
894

895
	if (memcmp(chunk_name, "IHDR", sizeof(chunk_name)) != 0) {
896
		log_error("Error : invalid IHDR chunk.");
897
		return -1;
898
	}
899

900
	if (read_IHDR(fd, &png_head) != 0) {
901
		return -1;
902
	}
903

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;
909
	} else {
910
		png_data->image_size = png_head.width * png_head.height * PNG_TRCLA;
911
	}
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.");
916
		return ENOMEM;
917
	}
918

919
	idat_size = count_IDAT(fd);
920
	idat_data = (uint8_t*)malloc(idat_size);
921
	if (idat_data == NULL) {
922
		log_error("Malloc error.");
923
		return ENOMEM;
924
	}
925

926
	/**
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
931
	 */
932
	while (true) {
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);
937
			free(idat_data);
938
			return -1;
939
		}
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);
943
			free(idat_data);
944
			return -1;
945
		}
946

947
		chunk_num = ident_chunk(chunk_name);
948

949
		if (chunk_num == 1) {
950
			/* IEND chunk */
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);
954
				free(idat_data);
955
				return -1;
956
			}
957
			if (!flag_IDAT) {
958
				log_error("Error : there is no IDAT chunk in the file");
959
				free(png_data->image);
960
				free(idat_data);
961
				return -1;
962
			}
963
			break;
964
		}
965

966
		switch (chunk_num) {
967
			case 0:
968
				if (!flag_IDAT) {
969
					if (read(fd, zlib, sizeof(zlib)) != sizeof(zlib)) {
970
						log_error("Error : can't read chunk.");
971
						free(png_data->image);
972
						free(idat_data);
973
						return -1;
974
					}
975
					idat_addsize = (int)htonl(chunk_length) - 2;
976
				} else {
977
					idat_addsize = (int)htonl(chunk_length);
978
				}
979
				idat_buffer = (uint8_t*)malloc(idat_addsize);
980
				if (idat_buffer == NULL) {
981
					log_error("Malloc error.");
982
					free(png_data->image);
983
					free(idat_data);
984
					return ENOMEM;
985
				}
986

987
				if (read(fd, idat_buffer, idat_addsize) != idat_addsize) {
988
					log_error("Error : can't read chunk.");
989
					free(png_data->image);
990
					free(idat_data);
991
					free(idat_buffer);
992
					return -1;
993
				}
994

995
				for (i = 0; i < idat_addsize; i++) {
996
					idat_data[idat_oldsize + i] = idat_buffer[i];
997
				}
998
				idat_oldsize += idat_addsize;
999
				free(idat_buffer);
1000
				flag_IDAT = 1;
1001

1002
				break;
1003

1004
			case -1:
1005
				if (flag_IDAT == 1) {
1006
					log_error("Warning : IDAT was successfull decoded, but IEND was not found");
1007
					free(idat_data);
1008
					return 0;
1009
				}
1010
				log_error("Error : invalid png file.");
1011
				free(png_data->image);
1012
				free(idat_data);
1013
				return -1;
1014

1015
			default:
1016
				read_chunk(fd, chunk_name);
1017
				break;
1018
		}
1019

1020
		pos += CHUNK_INFO_LEN + (int)htonl(chunk_length);
1021
	}
1022
	free(idat_data);
1023
	return 0;
1024
}
1025

1026
int png_load(char *file_name, struct png *png_data) {
1027

1028
	uint8_t signature[8];
1029

1030
	if (file_name == NULL) {
1031
		return EINVAL;
1032
	}
1033

1034
	if (png_data == NULL) {
1035
		return EINVAL;
1036
	}
1037

1038
	int fd = open(file_name, O_RDONLY);
1039
	if (fd == -1) {
1040
		log_error("Error : can't open file.");
1041
		return -1;
1042
	}
1043

1044
	if (read(fd, signature, sizeof(signature)) != sizeof(signature)) {
1045
		log_error("Error : can't read signature of file.");
1046
		close(fd);
1047
		return -1;
1048
	}
1049

1050
	if (raw_get_file_format(signature) != PNG_FILE) {
1051
		log_error("Error : it's not PNG file");
1052
		close(fd);
1053
		return -1;
1054
	}
1055

1056
	if (png_read(fd, png_data) != 0) {
1057
		close(fd);
1058
		return -1;
1059
	}
1060
	return 0;
1061
}
1062

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.