From 9e5d165e79499cffe11a85ebc1b1ff320d52953b Mon Sep 17 00:00:00 2001 From: Francois-Olivier Devaux Date: Tue, 27 Nov 2007 14:00:45 +0000 Subject: [PATCH] Fixed the maximum number of resolutions a user can discard while decoding. Added an error state in J2K_STATE (j2k.c) --- ChangeLog | 2 ++ libopenjpeg/j2k.c | 24 ++++++++++++++++++++---- libopenjpeg/j2k.h | 3 ++- libopenjpeg/tcd.c | 4 ++-- 4 files changed, 26 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 44142241..8e348eac 100644 --- a/ChangeLog +++ b/ChangeLog @@ -9,6 +9,8 @@ November 14, 2007 + [FOD] Created the file index.c in the codec directory. This file handles the creation of index files, at encoding and decoding. * [FOD] Fixed bugs during the creation of the index (PCRL progression order) +* [FOD] Fixed the maximum number of resolutions a user can discard while decoding. + Added an error state in J2K_STATE (j2k.c) November 14, 2007 ! [FOD] - First Patch by Callum Lerwick. Instead of reinventing realloc, j2k_read_sod now just uses opj_realloc in j2k.c diff --git a/libopenjpeg/j2k.c b/libopenjpeg/j2k.c index f563b2a6..c7a6f4a7 100644 --- a/libopenjpeg/j2k.c +++ b/libopenjpeg/j2k.c @@ -750,8 +750,13 @@ static void j2k_read_cox(opj_j2k_t *j2k, int compno) { tccp->numresolutions = cio_read(cio, 1) + 1; /* SPcox (D) */ - /* check the reduce value */ - cp->reduce = int_min((tccp->numresolutions)-1, cp->reduce); + // If user wants to remove more resolutions than the codestream contains, return error + if (cp->reduce >= tccp->numresolutions) { + opj_event_msg(j2k->cinfo, EVT_ERROR, "Error decoding component %d.\nThe number of resolutions to remove is higher than the number " + "of resolutions of this component\nModify the cp_reduce parameter.\n\n", compno); + j2k->state |= J2K_STATE_ERR; + } + tccp->cblkw = cio_read(cio, 1) + 2; /* SPcox (E) */ tccp->cblkh = cio_read(cio, 1) + 2; /* SPcox (F) */ tccp->cblksty = cio_read(cio, 1); /* SPcox (G) */ @@ -1586,6 +1591,7 @@ static void j2k_write_eoc(opj_j2k_t *j2k) { static void j2k_read_eoc(opj_j2k_t *j2k) { int i, tileno; + bool success; /* if packets should be decoded */ if (j2k->cp->limit_decoding != DECODE_ALL_BUT_PACKETS) { @@ -1594,10 +1600,14 @@ static void j2k_read_eoc(opj_j2k_t *j2k) { for (i = 0; i < j2k->cp->tileno_size; i++) { tcd_malloc_decode_tile(tcd, j2k->image, j2k->cp, i, j2k->cstr_info); tileno = j2k->cp->tileno[i]; - tcd_decode_tile(tcd, j2k->tile_data[tileno], j2k->tile_len[tileno], tileno, j2k->cstr_info); + success = tcd_decode_tile(tcd, j2k->tile_data[tileno], j2k->tile_len[tileno], tileno, j2k->cstr_info); opj_free(j2k->tile_data[tileno]); j2k->tile_data[tileno] = NULL; tcd_free_decode_tile(tcd, i); + if (success == false) { + j2k->state |= J2K_STATE_ERR; + break; + } } tcd_free_decode(tcd); tcd_destroy(tcd); @@ -1610,7 +1620,10 @@ static void j2k_read_eoc(opj_j2k_t *j2k) { j2k->tile_data[tileno] = NULL; } } - j2k->state = J2K_STATE_MT; + if (j2k->state & J2K_STATE_ERR) + j2k->state = J2K_STATE_MT + J2K_STATE_ERR; + else + j2k->state = J2K_STATE_MT; } typedef struct opj_dec_mstabent { @@ -1900,6 +1913,9 @@ opj_image_t* j2k_decode(opj_j2k_t *j2k, opj_cio_t *cio, opj_codestream_info_t *c if (e->handler) { (*e->handler)(j2k); } + if (j2k->state & J2K_STATE_ERR) + return NULL; + if (j2k->state == J2K_STATE_MT) { break; } diff --git a/libopenjpeg/j2k.h b/libopenjpeg/j2k.h index 2dc21ec0..5599be47 100644 --- a/libopenjpeg/j2k.h +++ b/libopenjpeg/j2k.h @@ -104,7 +104,8 @@ typedef enum J2K_STATUS { J2K_STATE_TPHSOT = 0x0008, /**< the decoding process is in a tile part header and expects a SOT marker */ J2K_STATE_TPH = 0x0010, /**< the decoding process is in a tile part header */ J2K_STATE_MT = 0x0020, /**< the EOC marker has just been read */ - J2K_STATE_NEOC = 0x0040 /**< the decoding process must not expect a EOC marker because the codestream is truncated */ + J2K_STATE_NEOC = 0x0040, /**< the decoding process must not expect a EOC marker because the codestream is truncated */ + J2K_STATE_ERR = 0x0080 /**< the decoding process has encountered an error */ } J2K_STATUS; /* ----------------------------------------------------------------------- */ diff --git a/libopenjpeg/tcd.c b/libopenjpeg/tcd.c index 38f6b6ba..95cfd93e 100644 --- a/libopenjpeg/tcd.c +++ b/libopenjpeg/tcd.c @@ -1384,9 +1384,9 @@ bool tcd_decode_tile(opj_tcd_t *tcd, unsigned char *src, int len, int tileno, op if (tcd->cp->reduce != 0) { tcd->image->comps[compno].resno_decoded = tile->comps[compno].numresolutions - tcd->cp->reduce - 1; - if (tcd->image->comps[compno].resno_decoded < 1) { + if (tcd->image->comps[compno].resno_decoded < 0) { opj_event_msg(tcd->cinfo, EVT_ERROR, "Error decoding tile. The number of resolutions to remove is higher than the number " - " of resolutions in the original codestream\nModify the cp_reduce parameter.\n"); + "of resolutions in the original codestream\nModify the cp_reduce parameter.\n"); return false; } }