static bool png_parse_ihdr(uint8_t *buf, struct png_ihdr *ihdr) { buf += 4 + 4; ihdr->width = dword_be(buf + 0); ihdr->height = dword_be(buf + 4); ihdr->depth = buf[8]; ihdr->color_type = buf[9]; ihdr->compression = buf[10]; ihdr->filter = buf[11]; ihdr->interlace = buf[12]; if (ihdr->width == 0 || ihdr->height == 0) return false; return true; }
static bool read_chunk_header(FILE *file, struct png_chunk *chunk) { uint8_t dword[4] = {0}; if (fread(dword, 1, 4, file) != 4) return false; chunk->size = dword_be(dword); if (fread(chunk->type, 1, 4, file) != 4) return false; return true; }
static bool png_parse_ihdr_fio(FILE **fd, struct png_chunk *chunk, struct png_ihdr *ihdr) { if (!png_read_chunk(fd, chunk)) return false; if (chunk->size != 13) return false; ihdr->width = dword_be(chunk->data + 0); ihdr->height = dword_be(chunk->data + 4); ihdr->depth = chunk->data[8]; ihdr->color_type = chunk->data[9]; ihdr->compression = chunk->data[10]; ihdr->filter = chunk->data[11]; ihdr->interlace = chunk->data[12]; if (ihdr->width == 0 || ihdr->height == 0) return false; return true; }
static bool read_chunk_header(uint8_t *buf, struct png_chunk *chunk) { unsigned i; uint8_t dword[4] = {0}; for (i = 0; i < 4; i++) dword[i] = buf[i]; chunk->size = dword_be(dword); for (i = 0; i < 4; i++) chunk->type[i] = buf[i + 4]; return true; }
static bool png_parse_ihdr(FILE *file, struct png_chunk *chunk, struct png_ihdr *ihdr) { unsigned i; bool ret = true; if (!png_read_chunk(file, chunk)) return false; if (chunk->size != 13) GOTO_END_ERROR(); ihdr->width = dword_be(chunk->data + 0); ihdr->height = dword_be(chunk->data + 4); ihdr->depth = chunk->data[8]; ihdr->color_type = chunk->data[9]; ihdr->compression = chunk->data[10]; ihdr->filter = chunk->data[11]; ihdr->interlace = chunk->data[12]; if (ihdr->width == 0 || ihdr->height == 0) GOTO_END_ERROR(); if (ihdr->color_type == 2 || ihdr->color_type == 4 || ihdr->color_type == 6) { if (ihdr->depth != 8 && ihdr->depth != 16) GOTO_END_ERROR(); } else if (ihdr->color_type == 0) { static const unsigned valid_bpp[] = { 1, 2, 4, 8, 16 }; bool correct_bpp = false; for (i = 0; i < ARRAY_SIZE(valid_bpp); i++) { if (valid_bpp[i] == ihdr->depth) { correct_bpp = true; break; } } if (!correct_bpp) GOTO_END_ERROR(); } else if (ihdr->color_type == 3) { static const unsigned valid_bpp[] = { 1, 2, 4, 8 }; bool correct_bpp = false; for (i = 0; i < ARRAY_SIZE(valid_bpp); i++) { if (valid_bpp[i] == ihdr->depth) { correct_bpp = true; break; } } if (!correct_bpp) GOTO_END_ERROR(); } else GOTO_END_ERROR(); #ifdef RPNG_TEST fprintf(stderr, "IHDR: (%u x %u), bpc = %u, palette = %s, color = %s, alpha = %s, adam7 = %s.\n", ihdr->width, ihdr->height, ihdr->depth, ihdr->color_type == 3 ? "yes" : "no", ihdr->color_type & 2 ? "yes" : "no", ihdr->color_type & 4 ? "yes" : "no", ihdr->interlace == 1 ? "yes" : "no"); #endif if (ihdr->compression != 0) GOTO_END_ERROR(); //if (ihdr->interlace != 0) // No Adam7 supported. // GOTO_END_ERROR(); end: png_free_chunk(chunk); return ret; }
static bool png_parse_ihdr(uint8_t *buf, struct png_ihdr *ihdr) { unsigned i; bool ret = true; buf += 4 + 4; ihdr->width = dword_be(buf + 0); ihdr->height = dword_be(buf + 4); ihdr->depth = buf[8]; ihdr->color_type = buf[9]; ihdr->compression = buf[10]; ihdr->filter = buf[11]; ihdr->interlace = buf[12]; if (ihdr->width == 0 || ihdr->height == 0) GOTO_END_ERROR(); if (ihdr->color_type == 2 || ihdr->color_type == 4 || ihdr->color_type == 6) { if (ihdr->depth != 8 && ihdr->depth != 16) GOTO_END_ERROR(); } else if (ihdr->color_type == 0) { static const unsigned valid_bpp[] = { 1, 2, 4, 8, 16 }; bool correct_bpp = false; for (i = 0; i < ARRAY_SIZE(valid_bpp); i++) { if (valid_bpp[i] == ihdr->depth) { correct_bpp = true; break; } } if (!correct_bpp) GOTO_END_ERROR(); } else if (ihdr->color_type == 3) { static const unsigned valid_bpp[] = { 1, 2, 4, 8 }; bool correct_bpp = false; for (i = 0; i < ARRAY_SIZE(valid_bpp); i++) { if (valid_bpp[i] == ihdr->depth) { correct_bpp = true; break; } } if (!correct_bpp) GOTO_END_ERROR(); } else GOTO_END_ERROR(); #ifdef RPNG_TEST fprintf(stderr, "IHDR: (%u x %u), bpc = %u, palette = %s, color = %s, alpha = %s, adam7 = %s.\n", ihdr->width, ihdr->height, ihdr->depth, ihdr->color_type == 3 ? "yes" : "no", ihdr->color_type & 2 ? "yes" : "no", ihdr->color_type & 4 ? "yes" : "no", ihdr->interlace == 1 ? "yes" : "no"); #endif if (ihdr->compression != 0) GOTO_END_ERROR(); #if 0 if (ihdr->interlace != 0) /* No Adam7 supported. */ GOTO_END_ERROR(); #endif end: return ret; }