read a PNG, the result will be in the same color type as the PNG (hence "generic")*/
| 4579 | |
| 4580 | /*read a PNG, the result will be in the same color type as the PNG (hence "generic")*/ |
| 4581 | static void decodeGeneric(unsigned char** out, unsigned* w, unsigned* h, |
| 4582 | LodePNGState* state, |
| 4583 | const unsigned char* in, size_t insize) |
| 4584 | { |
| 4585 | unsigned char IEND = 0; |
| 4586 | const unsigned char* chunk; |
| 4587 | size_t i; |
| 4588 | ucvector idat; /*the data from idat chunks*/ |
| 4589 | ucvector scanlines; |
| 4590 | size_t predict; |
| 4591 | size_t outsize = 0; |
| 4592 | |
| 4593 | /*for unknown chunk order*/ |
| 4594 | unsigned unknown = 0; |
| 4595 | #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS |
| 4596 | unsigned critical_pos = 1; /*1 = after IHDR, 2 = after PLTE, 3 = after IDAT*/ |
| 4597 | #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ |
| 4598 | |
| 4599 | /*provide some proper output values if error will happen*/ |
| 4600 | *out = 0; |
| 4601 | |
| 4602 | state->error = lodepng_inspect(w, h, state, in, insize); /*reads header and resets other parameters in state->info_png*/ |
| 4603 | if(state->error) return; |
| 4604 | |
| 4605 | if(lodepng_pixel_overflow(*w, *h, &state->info_png.color, &state->info_raw)) |
| 4606 | { |
| 4607 | CERROR_RETURN(state->error, 92); /*overflow possible due to amount of pixels*/ |
| 4608 | } |
| 4609 | |
| 4610 | ucvector_init(&idat); |
| 4611 | chunk = &in[33]; /*first byte of the first chunk after the header*/ |
| 4612 | |
| 4613 | /*loop through the chunks, ignoring unknown chunks and stopping at IEND chunk. |
| 4614 | IDAT data is put at the start of the in buffer*/ |
| 4615 | while(!IEND && !state->error) |
| 4616 | { |
| 4617 | unsigned chunkLength; |
| 4618 | const unsigned char* data; /*the data in the chunk*/ |
| 4619 | |
| 4620 | /*error: size of the in buffer too small to contain next chunk*/ |
| 4621 | if((size_t)((chunk - in) + 12) > insize || chunk < in) |
| 4622 | { |
| 4623 | if(state->decoder.ignore_end) break; /*other errors may still happen though*/ |
| 4624 | CERROR_BREAK(state->error, 30); |
| 4625 | } |
| 4626 | |
| 4627 | /*length of the data of the chunk, excluding the length bytes, chunk type and CRC bytes*/ |
| 4628 | chunkLength = lodepng_chunk_length(chunk); |
| 4629 | /*error: chunk length larger than the max PNG chunk size*/ |
| 4630 | if(chunkLength > 2147483647) |
| 4631 | { |
| 4632 | if(state->decoder.ignore_end) break; /*other errors may still happen though*/ |
| 4633 | CERROR_BREAK(state->error, 63); |
| 4634 | } |
| 4635 | |
| 4636 | if((size_t)((chunk - in) + chunkLength + 12) > insize || (chunk + chunkLength + 12) < in) |
| 4637 | { |
| 4638 | CERROR_BREAK(state->error, 64); /*error: size of the in buffer too small to contain next chunk*/ |
no test coverage detected