mirror of
https://github.com/libretro/RetroArch.git
synced 2025-04-02 10:51:52 -04:00
(RPNG) PNG decoder - proper namespacing of functions, general cleanups
This commit is contained in:
parent
342d3da620
commit
33c9f56df0
1 changed files with 110 additions and 120 deletions
|
@ -126,7 +126,7 @@ struct rpng
|
|||
bool has_trns;
|
||||
};
|
||||
|
||||
static const struct adam7_pass passes[] = {
|
||||
static const struct adam7_pass rpng_passes[] = {
|
||||
{ 0, 0, 8, 8 },
|
||||
{ 4, 0, 8, 8 },
|
||||
{ 0, 4, 4, 8 },
|
||||
|
@ -136,13 +136,13 @@ static const struct adam7_pass passes[] = {
|
|||
{ 0, 1, 1, 2 },
|
||||
};
|
||||
|
||||
static INLINE uint32_t dword_be(const uint8_t *buf)
|
||||
static INLINE uint32_t rpng_dword_be(const uint8_t *buf)
|
||||
{
|
||||
return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | (buf[3] << 0);
|
||||
}
|
||||
|
||||
#if defined(DEBUG) || defined(RPNG_TEST)
|
||||
static bool png_process_ihdr(struct png_ihdr *ihdr)
|
||||
static bool rpng_process_ihdr(struct png_ihdr *ihdr)
|
||||
{
|
||||
uint8_t ihdr_depth = ihdr->depth;
|
||||
|
||||
|
@ -190,7 +190,7 @@ static bool png_process_ihdr(struct png_ihdr *ihdr)
|
|||
return true;
|
||||
}
|
||||
#else
|
||||
static bool png_process_ihdr(struct png_ihdr *ihdr)
|
||||
static bool rpng_process_ihdr(struct png_ihdr *ihdr)
|
||||
{
|
||||
uint8_t ihdr_depth = ihdr->depth;
|
||||
|
||||
|
@ -220,10 +220,10 @@ static bool png_process_ihdr(struct png_ihdr *ihdr)
|
|||
}
|
||||
#endif
|
||||
|
||||
static void png_reverse_filter_copy_line_rgb(uint32_t *data,
|
||||
static void rpng_reverse_filter_copy_line_rgb(uint32_t *data,
|
||||
const uint8_t *decoded, unsigned width, unsigned bpp)
|
||||
{
|
||||
unsigned i;
|
||||
int i;
|
||||
|
||||
bpp /= 8;
|
||||
|
||||
|
@ -241,10 +241,10 @@ static void png_reverse_filter_copy_line_rgb(uint32_t *data,
|
|||
}
|
||||
}
|
||||
|
||||
static void png_reverse_filter_copy_line_rgba(uint32_t *data,
|
||||
static void rpng_reverse_filter_copy_line_rgba(uint32_t *data,
|
||||
const uint8_t *decoded, unsigned width, unsigned bpp)
|
||||
{
|
||||
unsigned i;
|
||||
int i;
|
||||
|
||||
bpp /= 8;
|
||||
|
||||
|
@ -263,10 +263,11 @@ static void png_reverse_filter_copy_line_rgba(uint32_t *data,
|
|||
}
|
||||
}
|
||||
|
||||
static void png_reverse_filter_copy_line_bw(uint32_t *data,
|
||||
static void rpng_reverse_filter_copy_line_bw(uint32_t *data,
|
||||
const uint8_t *decoded, unsigned width, unsigned depth)
|
||||
{
|
||||
unsigned i, bit;
|
||||
int i;
|
||||
unsigned bit;
|
||||
static const unsigned mul_table[] = { 0, 0xff, 0x55, 0, 0x11, 0, 0, 0, 0x01 };
|
||||
unsigned mul, mask;
|
||||
|
||||
|
@ -295,11 +296,11 @@ static void png_reverse_filter_copy_line_bw(uint32_t *data,
|
|||
}
|
||||
}
|
||||
|
||||
static void png_reverse_filter_copy_line_gray_alpha(uint32_t *data,
|
||||
static void rpng_reverse_filter_copy_line_gray_alpha(uint32_t *data,
|
||||
const uint8_t *decoded, unsigned width,
|
||||
unsigned bpp)
|
||||
{
|
||||
unsigned i;
|
||||
int i;
|
||||
|
||||
bpp /= 8;
|
||||
|
||||
|
@ -316,7 +317,7 @@ static void png_reverse_filter_copy_line_gray_alpha(uint32_t *data,
|
|||
}
|
||||
}
|
||||
|
||||
static void png_reverse_filter_copy_line_plt(uint32_t *data,
|
||||
static void rpng_reverse_filter_copy_line_plt(uint32_t *data,
|
||||
const uint8_t *decoded, unsigned width,
|
||||
unsigned depth, const uint32_t *palette)
|
||||
{
|
||||
|
@ -325,7 +326,7 @@ static void png_reverse_filter_copy_line_plt(uint32_t *data,
|
|||
case 1:
|
||||
{
|
||||
unsigned w = width / 8;
|
||||
unsigned i;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < w; i++, decoded++)
|
||||
{
|
||||
|
@ -363,7 +364,7 @@ static void png_reverse_filter_copy_line_plt(uint32_t *data,
|
|||
case 2:
|
||||
{
|
||||
unsigned w = width / 4;
|
||||
unsigned i;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < w; i++, decoded++)
|
||||
{
|
||||
|
@ -389,7 +390,7 @@ static void png_reverse_filter_copy_line_plt(uint32_t *data,
|
|||
case 4:
|
||||
{
|
||||
unsigned w = width / 2;
|
||||
unsigned i;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < w; i++, decoded++)
|
||||
{
|
||||
|
@ -404,7 +405,7 @@ static void png_reverse_filter_copy_line_plt(uint32_t *data,
|
|||
|
||||
case 8:
|
||||
{
|
||||
unsigned i;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < width; i++, decoded++, data++)
|
||||
*data = palette[*decoded];
|
||||
|
@ -413,7 +414,7 @@ static void png_reverse_filter_copy_line_plt(uint32_t *data,
|
|||
}
|
||||
}
|
||||
|
||||
static void png_pass_geom(const struct png_ihdr *ihdr,
|
||||
static void rpng_pass_geom(const struct png_ihdr *ihdr,
|
||||
unsigned width, unsigned height,
|
||||
unsigned *bpp_out, unsigned *pitch_out, size_t *pass_size)
|
||||
{
|
||||
|
@ -454,7 +455,7 @@ static void png_pass_geom(const struct png_ihdr *ihdr,
|
|||
*pitch_out = pitch;
|
||||
}
|
||||
|
||||
static void png_reverse_filter_adam7_deinterlace_pass(uint32_t *data,
|
||||
static void rpng_reverse_filter_adam7_deinterlace_pass(uint32_t *data,
|
||||
const struct png_ihdr *ihdr,
|
||||
const uint32_t *input, unsigned pass_width, unsigned pass_height,
|
||||
const struct adam7_pass *pass)
|
||||
|
@ -473,7 +474,7 @@ static void png_reverse_filter_adam7_deinterlace_pass(uint32_t *data,
|
|||
}
|
||||
}
|
||||
|
||||
static void png_reverse_filter_deinit(struct rpng_process *pngp)
|
||||
static void rpng_reverse_filter_deinit(struct rpng_process *pngp)
|
||||
{
|
||||
if (!pngp)
|
||||
return;
|
||||
|
@ -488,33 +489,32 @@ static void png_reverse_filter_deinit(struct rpng_process *pngp)
|
|||
pngp->h = 0;
|
||||
}
|
||||
|
||||
static int png_reverse_filter_init(const struct png_ihdr *ihdr,
|
||||
static int rpng_reverse_filter_init(const struct png_ihdr *ihdr,
|
||||
struct rpng_process *pngp)
|
||||
{
|
||||
size_t pass_size;
|
||||
|
||||
if (!pngp->adam7_pass_initialized && ihdr->interlace)
|
||||
{
|
||||
if (ihdr->width <= passes[pngp->pass_pos].x ||
|
||||
ihdr->height <= passes[pngp->pass_pos].y) /* Empty pass */
|
||||
if ( ihdr->width <= rpng_passes[pngp->pass_pos].x
|
||||
|| ihdr->height <= rpng_passes[pngp->pass_pos].y) /* Empty pass */
|
||||
return 1;
|
||||
|
||||
pngp->pass_width = (ihdr->width -
|
||||
passes[pngp->pass_pos].x + passes[pngp->pass_pos].stride_x - 1) / passes[pngp->pass_pos].stride_x;
|
||||
pngp->pass_height = (ihdr->height - passes[pngp->pass_pos].y +
|
||||
passes[pngp->pass_pos].stride_y - 1) / passes[pngp->pass_pos].stride_y;
|
||||
rpng_passes[pngp->pass_pos].x + rpng_passes[pngp->pass_pos].stride_x
|
||||
- 1) / rpng_passes[pngp->pass_pos].stride_x;
|
||||
pngp->pass_height = (ihdr->height - rpng_passes[pngp->pass_pos].y +
|
||||
rpng_passes[pngp->pass_pos].stride_y - 1) / rpng_passes[pngp->pass_pos].stride_y;
|
||||
|
||||
pngp->data = (uint32_t*)malloc(
|
||||
pngp->pass_width * pngp->pass_height * sizeof(uint32_t));
|
||||
|
||||
if (!pngp->data)
|
||||
if (!(pngp->data = (uint32_t*)malloc(
|
||||
pngp->pass_width * pngp->pass_height * sizeof(uint32_t))))
|
||||
return -1;
|
||||
|
||||
pngp->ihdr = *ihdr;
|
||||
pngp->ihdr.width = pngp->pass_width;
|
||||
pngp->ihdr.height = pngp->pass_height;
|
||||
|
||||
png_pass_geom(&pngp->ihdr, pngp->pass_width,
|
||||
rpng_pass_geom(&pngp->ihdr, pngp->pass_width,
|
||||
pngp->pass_height, NULL, NULL, &pngp->pass_size);
|
||||
|
||||
if (pngp->pass_size > pngp->total_out)
|
||||
|
@ -532,7 +532,7 @@ static int png_reverse_filter_init(const struct png_ihdr *ihdr,
|
|||
if (pngp->pass_initialized)
|
||||
return 0;
|
||||
|
||||
png_pass_geom(ihdr, ihdr->width, ihdr->height, &pngp->bpp, &pngp->pitch, &pass_size);
|
||||
rpng_pass_geom(ihdr, ihdr->width, ihdr->height, &pngp->bpp, &pngp->pitch, &pass_size);
|
||||
|
||||
if (pngp->total_out < pass_size)
|
||||
return -1;
|
||||
|
@ -551,11 +551,12 @@ static int png_reverse_filter_init(const struct png_ihdr *ihdr,
|
|||
return 0;
|
||||
|
||||
error:
|
||||
png_reverse_filter_deinit(pngp);
|
||||
rpng_reverse_filter_deinit(pngp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int png_reverse_filter_copy_line(uint32_t *data, const struct png_ihdr *ihdr,
|
||||
static int rpng_reverse_filter_copy_line(uint32_t *data,
|
||||
const struct png_ihdr *ihdr,
|
||||
struct rpng_process *pngp, unsigned filter)
|
||||
{
|
||||
unsigned i;
|
||||
|
@ -603,21 +604,22 @@ static int png_reverse_filter_copy_line(uint32_t *data, const struct png_ihdr *i
|
|||
switch (ihdr->color_type)
|
||||
{
|
||||
case PNG_IHDR_COLOR_GRAY:
|
||||
png_reverse_filter_copy_line_bw(data, pngp->decoded_scanline, ihdr->width, ihdr->depth);
|
||||
rpng_reverse_filter_copy_line_bw(data, pngp->decoded_scanline, ihdr->width, ihdr->depth);
|
||||
break;
|
||||
case PNG_IHDR_COLOR_RGB:
|
||||
png_reverse_filter_copy_line_rgb(data, pngp->decoded_scanline, ihdr->width, ihdr->depth);
|
||||
rpng_reverse_filter_copy_line_rgb(data, pngp->decoded_scanline, ihdr->width, ihdr->depth);
|
||||
break;
|
||||
case PNG_IHDR_COLOR_PLT:
|
||||
png_reverse_filter_copy_line_plt(data, pngp->decoded_scanline, ihdr->width,
|
||||
rpng_reverse_filter_copy_line_plt(
|
||||
data, pngp->decoded_scanline, ihdr->width,
|
||||
ihdr->depth, pngp->palette);
|
||||
break;
|
||||
case PNG_IHDR_COLOR_GRAY_ALPHA:
|
||||
png_reverse_filter_copy_line_gray_alpha(data, pngp->decoded_scanline, ihdr->width,
|
||||
rpng_reverse_filter_copy_line_gray_alpha(data, pngp->decoded_scanline, ihdr->width,
|
||||
ihdr->depth);
|
||||
break;
|
||||
case PNG_IHDR_COLOR_RGBA:
|
||||
png_reverse_filter_copy_line_rgba(data, pngp->decoded_scanline, ihdr->width, ihdr->depth);
|
||||
rpng_reverse_filter_copy_line_rgba(data, pngp->decoded_scanline, ihdr->width, ihdr->depth);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -626,7 +628,8 @@ static int png_reverse_filter_copy_line(uint32_t *data, const struct png_ihdr *i
|
|||
return IMAGE_PROCESS_NEXT;
|
||||
}
|
||||
|
||||
static int png_reverse_filter_regular_iterate(uint32_t **data, const struct png_ihdr *ihdr,
|
||||
static int rpng_reverse_filter_regular_iterate(
|
||||
uint32_t **data, const struct png_ihdr *ihdr,
|
||||
struct rpng_process *pngp)
|
||||
{
|
||||
int ret = IMAGE_PROCESS_END;
|
||||
|
@ -634,7 +637,7 @@ static int png_reverse_filter_regular_iterate(uint32_t **data, const struct png_
|
|||
{
|
||||
unsigned filter = *pngp->inflate_buf++;
|
||||
pngp->restore_buf_size += 1;
|
||||
ret = png_reverse_filter_copy_line(*data,
|
||||
ret = rpng_reverse_filter_copy_line(*data,
|
||||
ihdr, pngp, filter);
|
||||
if (ret == IMAGE_PROCESS_END || ret == IMAGE_PROCESS_ERROR_END)
|
||||
goto end;
|
||||
|
@ -652,7 +655,7 @@ static int png_reverse_filter_regular_iterate(uint32_t **data, const struct png_
|
|||
return IMAGE_PROCESS_NEXT;
|
||||
|
||||
end:
|
||||
png_reverse_filter_deinit(pngp);
|
||||
rpng_reverse_filter_deinit(pngp);
|
||||
|
||||
pngp->inflate_buf -= pngp->restore_buf_size;
|
||||
*data -= pngp->data_restore_buf_size;
|
||||
|
@ -660,28 +663,28 @@ end:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int png_reverse_filter_adam7_iterate(uint32_t **data_,
|
||||
static int rpng_reverse_filter_adam7_iterate(uint32_t **data_,
|
||||
const struct png_ihdr *ihdr,
|
||||
struct rpng_process *pngp)
|
||||
{
|
||||
int ret = 0;
|
||||
bool to_next = pngp->pass_pos < ARRAY_SIZE(passes);
|
||||
bool to_next = pngp->pass_pos < ARRAY_SIZE(rpng_passes);
|
||||
uint32_t *data = *data_;
|
||||
|
||||
if (!to_next)
|
||||
return IMAGE_PROCESS_END;
|
||||
|
||||
if ((ret = png_reverse_filter_init(ihdr, pngp)) == 1)
|
||||
if ((ret = rpng_reverse_filter_init(ihdr, pngp)) == 1)
|
||||
return IMAGE_PROCESS_NEXT;
|
||||
else if (ret == -1)
|
||||
return IMAGE_PROCESS_ERROR_END;
|
||||
|
||||
if (png_reverse_filter_init(&pngp->ihdr, pngp) == -1)
|
||||
if (rpng_reverse_filter_init(&pngp->ihdr, pngp) == -1)
|
||||
return IMAGE_PROCESS_ERROR;
|
||||
|
||||
do
|
||||
{
|
||||
ret = png_reverse_filter_regular_iterate(&pngp->data,
|
||||
ret = rpng_reverse_filter_regular_iterate(&pngp->data,
|
||||
&pngp->ihdr, pngp);
|
||||
} while (ret == IMAGE_PROCESS_NEXT);
|
||||
|
||||
|
@ -693,8 +696,9 @@ static int png_reverse_filter_adam7_iterate(uint32_t **data_,
|
|||
|
||||
pngp->total_out -= pngp->pass_size;
|
||||
|
||||
png_reverse_filter_adam7_deinterlace_pass(data,
|
||||
ihdr, pngp->data, pngp->pass_width, pngp->pass_height, &passes[pngp->pass_pos]);
|
||||
rpng_reverse_filter_adam7_deinterlace_pass(data,
|
||||
ihdr, pngp->data, pngp->pass_width, pngp->pass_height,
|
||||
&rpng_passes[pngp->pass_pos]);
|
||||
|
||||
free(pngp->data);
|
||||
|
||||
|
@ -707,11 +711,11 @@ static int png_reverse_filter_adam7_iterate(uint32_t **data_,
|
|||
return IMAGE_PROCESS_NEXT;
|
||||
}
|
||||
|
||||
static int png_reverse_filter_adam7(uint32_t **data_,
|
||||
static int rpng_reverse_filter_adam7(uint32_t **data_,
|
||||
const struct png_ihdr *ihdr,
|
||||
struct rpng_process *pngp)
|
||||
{
|
||||
int ret = png_reverse_filter_adam7_iterate(data_,
|
||||
int ret = rpng_reverse_filter_adam7_iterate(data_,
|
||||
ihdr, pngp);
|
||||
|
||||
switch (ret)
|
||||
|
@ -738,18 +742,8 @@ static int png_reverse_filter_adam7(uint32_t **data_,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int png_reverse_filter_iterate(rpng_t *rpng, uint32_t **data)
|
||||
{
|
||||
if (!rpng)
|
||||
return false;
|
||||
|
||||
if (rpng->ihdr.interlace && rpng->process)
|
||||
return png_reverse_filter_adam7(data, &rpng->ihdr, rpng->process);
|
||||
|
||||
return png_reverse_filter_regular_iterate(data, &rpng->ihdr, rpng->process);
|
||||
}
|
||||
|
||||
static int rpng_load_image_argb_process_inflate_init(rpng_t *rpng, uint32_t **data)
|
||||
static int rpng_load_image_argb_process_inflate_init(
|
||||
rpng_t *rpng, uint32_t **data)
|
||||
{
|
||||
bool zstatus;
|
||||
enum trans_stream_error terror;
|
||||
|
@ -793,7 +787,7 @@ end:
|
|||
process->palette = rpng->palette;
|
||||
|
||||
if (rpng->ihdr.interlace != 1)
|
||||
if (png_reverse_filter_init(&rpng->ihdr, process) == -1)
|
||||
if (rpng_reverse_filter_init(&rpng->ihdr, process) == -1)
|
||||
goto false_end;
|
||||
|
||||
process->inflate_initialized = true;
|
||||
|
@ -805,33 +799,7 @@ false_end:
|
|||
return -1;
|
||||
}
|
||||
|
||||
static bool png_read_plte(uint8_t *buf,
|
||||
uint32_t *buffer, unsigned entries)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < entries; i++)
|
||||
{
|
||||
uint32_t r = buf[3 * i + 0];
|
||||
uint32_t g = buf[3 * i + 1];
|
||||
uint32_t b = buf[3 * i + 2];
|
||||
buffer[i] = (r << 16) | (g << 8) | (b << 0) | (0xffu << 24);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool png_read_trns(uint8_t *buf, uint32_t *palette, unsigned entries)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < entries; i++, buf++, palette++)
|
||||
*palette = (*palette & 0x00ffffff) | (unsigned)*buf << 24;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool png_realloc_idat(struct idat_buffer *buf, uint32_t chunk_size)
|
||||
static bool rpng_realloc_idat(struct idat_buffer *buf, uint32_t chunk_size)
|
||||
{
|
||||
uint8_t *new_buffer = (uint8_t*)realloc(buf->data, buf->size + chunk_size);
|
||||
|
||||
|
@ -884,7 +852,7 @@ static struct rpng_process *rpng_process_init(rpng_t *rpng)
|
|||
process->stream = NULL;
|
||||
process->stream_backend = trans_stream_get_zlib_inflate_backend();
|
||||
|
||||
png_pass_geom(&rpng->ihdr, rpng->ihdr.width,
|
||||
rpng_pass_geom(&rpng->ihdr, rpng->ihdr.width,
|
||||
rpng->ihdr.height, NULL, NULL, &process->inflate_buf_size);
|
||||
if (rpng->ihdr.interlace == 1) /* To be sure. */
|
||||
process->inflate_buf_size *= 2;
|
||||
|
@ -926,10 +894,18 @@ error:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static enum png_chunk_type read_chunk_header(
|
||||
/**
|
||||
* rpng_read_chunk_header:
|
||||
*
|
||||
* Leaf function.
|
||||
*
|
||||
* @return The PNG type of the memory chunk (i.e. IHDR, IDAT, IEND,
|
||||
PLTE, and/or tRNS)
|
||||
**/
|
||||
static enum png_chunk_type rpng_read_chunk_header(
|
||||
uint8_t *buf, uint32_t chunk_size)
|
||||
{
|
||||
unsigned i;
|
||||
int i;
|
||||
char type[4];
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
|
@ -1001,13 +977,13 @@ bool rpng_iterate_image(rpng_t *rpng)
|
|||
if (rpng->buff_end - buf < 8)
|
||||
return false;
|
||||
|
||||
chunk_size = dword_be(buf);
|
||||
chunk_size = rpng_dword_be(buf);
|
||||
|
||||
/* Check whether chunk will overflow the data buffer */
|
||||
if (buf + 8 + chunk_size > rpng->buff_end)
|
||||
return false;
|
||||
|
||||
switch (read_chunk_header(buf, chunk_size))
|
||||
switch (rpng_read_chunk_header(buf, chunk_size))
|
||||
{
|
||||
case PNG_CHUNK_NOOP:
|
||||
default:
|
||||
|
@ -1025,8 +1001,8 @@ bool rpng_iterate_image(rpng_t *rpng)
|
|||
|
||||
buf += 4 + 4;
|
||||
|
||||
rpng->ihdr.width = dword_be(buf + 0);
|
||||
rpng->ihdr.height = dword_be(buf + 4);
|
||||
rpng->ihdr.width = rpng_dword_be(buf + 0);
|
||||
rpng->ihdr.height = rpng_dword_be(buf + 4);
|
||||
rpng->ihdr.depth = buf[8];
|
||||
rpng->ihdr.color_type = buf[9];
|
||||
rpng->ihdr.compression = buf[10];
|
||||
|
@ -1039,7 +1015,7 @@ bool rpng_iterate_image(rpng_t *rpng)
|
|||
|| (uint64_t)rpng->ihdr.width*rpng->ihdr.height*sizeof(uint32_t) >= 0x80000000)
|
||||
return false;
|
||||
|
||||
if (!png_process_ihdr(&rpng->ihdr))
|
||||
if (!rpng_process_ihdr(&rpng->ihdr))
|
||||
return false;
|
||||
|
||||
if (rpng->ihdr.compression != 0)
|
||||
|
@ -1055,8 +1031,14 @@ bool rpng_iterate_image(rpng_t *rpng)
|
|||
|
||||
case PNG_CHUNK_PLTE:
|
||||
{
|
||||
int i;
|
||||
unsigned entries = chunk_size / 3;
|
||||
|
||||
if (entries > 256)
|
||||
return false;
|
||||
if (chunk_size % 3)
|
||||
return false;
|
||||
|
||||
if ( !rpng->has_ihdr
|
||||
|| rpng->has_plte
|
||||
|| rpng->has_iend
|
||||
|
@ -1064,16 +1046,15 @@ bool rpng_iterate_image(rpng_t *rpng)
|
|||
|| rpng->has_trns)
|
||||
return false;
|
||||
|
||||
if (chunk_size % 3)
|
||||
return false;
|
||||
|
||||
if (entries > 256)
|
||||
return false;
|
||||
|
||||
buf += 8;
|
||||
|
||||
if (!png_read_plte(buf, rpng->palette, entries))
|
||||
return false;
|
||||
for (i = 0; i < (int)entries; i++)
|
||||
{
|
||||
uint32_t r = buf[3 * i + 0];
|
||||
uint32_t g = buf[3 * i + 1];
|
||||
uint32_t b = buf[3 * i + 2];
|
||||
rpng->palette[i] = (r << 16) | (g << 8) | (b << 0) | (0xffu << 24);
|
||||
}
|
||||
|
||||
rpng->has_plte = true;
|
||||
}
|
||||
|
@ -1085,14 +1066,17 @@ bool rpng_iterate_image(rpng_t *rpng)
|
|||
|
||||
if (rpng->ihdr.color_type == PNG_IHDR_COLOR_PLT)
|
||||
{
|
||||
int i;
|
||||
uint32_t *palette;
|
||||
/* we should compare with the number of palette entries */
|
||||
if (chunk_size > 256)
|
||||
return false;
|
||||
|
||||
buf += 8;
|
||||
buf += 8;
|
||||
palette = rpng->palette;
|
||||
|
||||
if (!png_read_trns(buf, rpng->palette, chunk_size))
|
||||
return false;
|
||||
for (i = 0; i < chunk_size; i++, buf++, palette++)
|
||||
*palette = (*palette & 0x00ffffff) | (unsigned)*buf << 24;
|
||||
}
|
||||
/* TODO: support colorkey in grayscale and truecolor images */
|
||||
|
||||
|
@ -1103,7 +1087,7 @@ bool rpng_iterate_image(rpng_t *rpng)
|
|||
if (!(rpng->has_ihdr) || rpng->has_iend || (rpng->ihdr.color_type == PNG_IHDR_COLOR_PLT && !(rpng->has_plte)))
|
||||
return false;
|
||||
|
||||
if (!png_realloc_idat(&rpng->idat_buf, chunk_size))
|
||||
if (!rpng_realloc_idat(&rpng->idat_buf, chunk_size))
|
||||
return false;
|
||||
|
||||
buf += 8;
|
||||
|
@ -1137,8 +1121,6 @@ int rpng_process_image(rpng_t *rpng,
|
|||
{
|
||||
uint32_t **data = (uint32_t**)_data;
|
||||
|
||||
(void)size;
|
||||
|
||||
if (!rpng->process)
|
||||
{
|
||||
struct rpng_process *process = rpng_process_init(rpng);
|
||||
|
@ -1160,7 +1142,9 @@ int rpng_process_image(rpng_t *rpng,
|
|||
*width = rpng->ihdr.width;
|
||||
*height = rpng->ihdr.height;
|
||||
|
||||
return png_reverse_filter_iterate(rpng, data);
|
||||
if (rpng->ihdr.interlace && rpng->process)
|
||||
return rpng_reverse_filter_adam7(data, &rpng->ihdr, rpng->process);
|
||||
return rpng_reverse_filter_regular_iterate(data, &rpng->ihdr, rpng->process);
|
||||
|
||||
error:
|
||||
if (rpng->process)
|
||||
|
@ -1218,14 +1202,20 @@ bool rpng_start(rpng_t *rpng)
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* rpng_is_valid:
|
||||
*
|
||||
* Check if @rpng is a valid PNG image.
|
||||
* Must contain an IHDR chunk, one or more IDAT
|
||||
* chunks, and an IEND chunk.
|
||||
*
|
||||
* Leaf function.
|
||||
*
|
||||
* @return true if it's a valid PNG image, otherwise false.
|
||||
**/
|
||||
bool rpng_is_valid(rpng_t *rpng)
|
||||
{
|
||||
/* A valid PNG image must contain an IHDR chunk,
|
||||
* one or more IDAT chunks, and an IEND chunk */
|
||||
if (rpng && rpng->has_ihdr && rpng->has_idat && rpng->has_iend)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
return (rpng && rpng->has_ihdr && rpng->has_idat && rpng->has_iend);
|
||||
}
|
||||
|
||||
bool rpng_set_buf_ptr(rpng_t *rpng, void *data, size_t len)
|
||||
|
|
Loading…
Add table
Reference in a new issue