uclouvain / openjpeg

Official repository of the OpenJPEG project
Other
971 stars 456 forks source link

opj_decode_tile_data takes a long time to decode a very small file #1524

Closed radarhere closed 5 months ago

radarhere commented 5 months ago

Expected behavior and actual behavior.

Expected: Very small files should be quick to decode (or quick to raise an error). Actual: I've found opj_decode_tile_data() takes 52 seconds to process a specific 83 byte image.

Steps to reproduce the problem.

Here is my attempt at a minimal reproduction, removing error handling and other code that is not strictly necessary to demonstrate this. I've attached the 'image' file as a zip. On my Apple M1, running the code prints

Time spent on opj_decode_tile_data 52.414478


typedef struct {
OPJ_UINT32 tile_index;
OPJ_UINT32 data_size;
OPJ_INT32 x0, y0, x1, y1;
OPJ_UINT32 nb_comps;
} JPEG2KTILEINFO;

static OPJ_SIZE_T j2k_read(void p_buffer, OPJ_SIZE_T p_nb_bytes, void p_user_data) { FILE *f = fopen("image", "rb"); fread(p_buffer, 1, 83, f); return 83; }

struct State { UINT8 *buffer; };

struct State state = malloc(sizeof(struct State)); opj_stream_t stream = NULL; opj_image_t image = NULL; opj_codec_t codec = NULL; opj_dparameters_t params;

stream = opj_stream_create(OPJ_J2K_STREAM_CHUNK_SIZE, OPJ_TRUE);

opj_stream_set_read_function(stream, j2k_read);

opj_stream_set_user_data(stream, state, NULL);

opj_stream_set_user_data_length(stream, 83);

opj_set_default_decoder_parameters(&params); params.cp_reduce = 0; params.cp_layer = 0;

codec = opj_create_decompress(OPJ_CODEC_J2K);

opj_setup_decoder(codec, &params);

opj_read_header(stream, codec, &image); JPEG2KTILEINFO tile_info; OPJ_BOOL should_continue;

opj_read_tile_header( codec, stream, &tile_info.tile_index, &tile_info.data_size, &tile_info.x0, &tile_info.y0, &tile_info.x1, &tile_info.y1, &tile_info.nb_comps, &should_continue);

state->buffer = malloc(tile_info.data_size);

clock_t begin = clock(); opj_decode_tile_data( codec, tile_info.tile_index, (OPJ_BYTE *)state->buffer, tile_info.data_size, stream); clock_t end = clock(); double time_spent = (double)(end - begin) / CLOCKS_PER_SEC; printf("Time spent on opj_decode_tile_data %f\n", time_spent);


[image.zip](https://github.com/uclouvain/openjpeg/files/14972879/image.zip)

## Operating system

macOS 14.4.1

## openjpeg version

2.5.2

Thanks for your time.