Skip to content

Commit 4baa1b1

Browse files
authoredFeb 9, 2022
decode: expose zlib FLEVEL for images (#204)
1 parent 93b2e4e commit 4baa1b1

File tree

2 files changed

+54
-1
lines changed

2 files changed

+54
-1
lines changed
 

‎spng/spng.c

+22-1
Original file line numberDiff line numberDiff line change
@@ -3623,10 +3623,31 @@ int spng_decode_image(spng_ctx *ctx, void *out, size_t len, int fmt, int flags)
36233623
if(len < ctx->image_size) return SPNG_EBUFSIZ;
36243624
}
36253625

3626+
uint32_t bytes_read = 0;
3627+
3628+
ret = read_idat_bytes(ctx, &bytes_read);
3629+
if(ret) return decode_err(ctx, ret);
3630+
3631+
if(bytes_read > 1)
3632+
{
3633+
int valid = read_u16(ctx->data) % 31 ? 0 : 1;
3634+
3635+
unsigned flg = ctx->data[1];
3636+
unsigned flevel = flg >> 6;
3637+
int compression_level = Z_DEFAULT_COMPRESSION;
3638+
3639+
if(flevel == 0) compression_level = 0; /* fastest */
3640+
else if(flevel == 1) compression_level = 1; /* fast */
3641+
else if(flevel == 2) compression_level = 6; /* default */
3642+
else if(flevel == 3) compression_level = 9; /* slowest, max compression */
3643+
3644+
if(valid) ctx->image_options.compression_level = compression_level;
3645+
}
3646+
36263647
ret = spng__inflate_init(ctx, ctx->image_options.window_bits);
36273648
if(ret) return decode_err(ctx, ret);
36283649

3629-
ctx->zstream.avail_in = 0;
3650+
ctx->zstream.avail_in = bytes_read;
36303651
ctx->zstream.next_in = ctx->data;
36313652

36323653
size_t scanline_buf_size = ctx->subimage[ctx->widest_pass].scanline_width;

‎tests/testsuite.c

+32
Original file line numberDiff line numberDiff line change
@@ -1422,6 +1422,10 @@ static int extended_tests(FILE *file, int fmt)
14221422
struct spng_plte plte = {0};
14231423
static unsigned char chunk_data[9000];
14241424

1425+
/* NOTE: This value is compressed to 2 bits by zlib, it's not a 1:1 mapping */
1426+
int compression_level = 0;
1427+
int expected_compression_level = 0;
1428+
14251429
spng_set_png_file(dec, file);
14261430

14271431
spng_get_ihdr(dec, &ihdr);
@@ -1435,6 +1439,7 @@ static int extended_tests(FILE *file, int fmt)
14351439
enc = spng_ctx_new(SPNG_CTX_ENCODER);
14361440

14371441
spng_set_option(enc, SPNG_ENCODE_TO_BUFFER, 1);
1442+
spng_set_option(enc, SPNG_IMG_COMPRESSION_LEVEL, compression_level);
14381443

14391444
spng_set_ihdr(enc, &ihdr);
14401445

@@ -1475,6 +1480,31 @@ static int extended_tests(FILE *file, int fmt)
14751480
}
14761481

14771482
spng_ctx_free(enc);
1483+
enc = NULL;
1484+
1485+
/* Verify the image's zlib FLEVEL */
1486+
spng_ctx_free(dec);
1487+
dec = spng_ctx_new(0);
1488+
1489+
spng_set_png_buffer(dec, encoded, bytes_encoded);
1490+
1491+
spng_decode_image(dec, NULL, 0, SPNG_FMT_PNG, SPNG_DECODE_PROGRESSIVE);
1492+
1493+
ret = spng_get_option(dec, SPNG_IMG_COMPRESSION_LEVEL, &compression_level);
1494+
1495+
if(ret || (compression_level != expected_compression_level) )
1496+
{
1497+
if(ret) printf("error getting image compression level: %s\n", spng_strerror(ret));
1498+
else
1499+
{
1500+
printf("unexpected compression level (expected %d, got %d)\n",
1501+
expected_compression_level,
1502+
compression_level);
1503+
ret = 1;
1504+
}
1505+
1506+
goto cleanup;
1507+
}
14781508

14791509
/* Reencode the same image but to a stream this time */
14801510
enc = spng_ctx_new(SPNG_CTX_ENCODER);
@@ -1483,6 +1513,8 @@ static int extended_tests(FILE *file, int fmt)
14831513

14841514
spng_set_png_stream(enc, stream_write_checked, &state);
14851515

1516+
spng_set_option(enc, SPNG_IMG_COMPRESSION_LEVEL, compression_level);
1517+
14861518
spng_set_ihdr(enc, &ihdr);
14871519

14881520
if(plte.n_entries) spng_set_plte(enc, &plte);

0 commit comments

Comments
 (0)
Please sign in to comment.