bool rpng_nbio_load_image_argb_iterate(uint8_t *buf, struct rpng_t *rpng, unsigned *ret) { unsigned i; struct png_chunk chunk = {0}; if (!read_chunk_header(buf, &chunk)) return false; #if 0 for (i = 0; i < 4; i++) { fprintf(stderr, "chunktype: %c\n", chunk.type[i]); } #endif switch (png_chunk_type(&chunk)) { case PNG_CHUNK_NOOP: default: break; case PNG_CHUNK_ERROR: goto error; case PNG_CHUNK_IHDR: if (rpng->has_ihdr || rpng->has_idat || rpng->has_iend) goto error; if (chunk.size != 13) goto error; if (!png_parse_ihdr(buf, &rpng->ihdr)) goto error; if (!png_process_ihdr(&rpng->ihdr)) goto error; rpng->has_ihdr = true; break; case PNG_CHUNK_PLTE: { unsigned entries = chunk.size / 3; if (!rpng->has_ihdr || rpng->has_plte || rpng->has_iend || rpng->has_idat) goto error; if (chunk.size % 3) goto error; if (!png_read_plte_into_buf(buf, rpng->palette, entries)) goto error; rpng->has_plte = true; } break; case PNG_CHUNK_IDAT: if (!(rpng->has_ihdr) || rpng->has_iend || (rpng->ihdr.color_type == PNG_IHDR_COLOR_PLT && !(rpng->has_plte))) goto error; if (!png_realloc_idat(&chunk, &rpng->idat_buf)) goto error; buf += 8; for (i = 0; i < chunk.size; i++) rpng->idat_buf.data[i + rpng->idat_buf.size] = buf[i]; rpng->idat_buf.size += chunk.size; rpng->has_idat = true; break; case PNG_CHUNK_IEND: if (!(rpng->has_ihdr) || !(rpng->has_idat)) goto error; rpng->has_iend = true; goto error; } *ret = 4 + 4 + chunk.size + 4; return true; error: return false; }
bool rpng_nbio_load_image_argb_iterate(uint8_t *buf, struct rpng_t *rpng) { unsigned i; rpng->chunk.size = 0; rpng->chunk.type[0] = '\0'; if (!read_chunk_header(buf, &rpng->chunk)) return false; #if 0 for (i = 0; i < 4; i++) { fprintf(stderr, "chunktype: %c\n", chunk.type[i]); } #endif switch (png_chunk_type(&rpng->chunk)) { case PNG_CHUNK_NOOP: default: break; case PNG_CHUNK_ERROR: return false; case PNG_CHUNK_IHDR: if (rpng->has_ihdr || rpng->has_idat || rpng->has_iend) return false; if (rpng->chunk.size != 13) return false; if (!png_parse_ihdr(buf, &rpng->ihdr)) return false; rpng->has_ihdr = true; break; case PNG_CHUNK_PLTE: { unsigned entries = rpng->chunk.size / 3; if (!rpng->has_ihdr || rpng->has_plte || rpng->has_iend || rpng->has_idat) return false; if (rpng->chunk.size % 3) return false; if (!png_read_plte_into_buf(buf, rpng->palette, entries)) return false; rpng->has_plte = true; } break; case PNG_CHUNK_IDAT: if (!(rpng->has_ihdr) || rpng->has_iend || (rpng->ihdr.color_type == 3 && !(rpng->has_plte))) return false; if (!png_realloc_idat(&rpng->chunk, &rpng->idat_buf)) return false; buf += 8; for (i = 0; i < rpng->chunk.size; i++) rpng->idat_buf.data[i + rpng->idat_buf.size] = buf[i]; rpng->idat_buf.size += rpng->chunk.size; rpng->has_idat = true; break; case PNG_CHUNK_IEND: if (!(rpng->has_ihdr) || !(rpng->has_idat)) return false; rpng->has_iend = true; return false; } return true; }