Fixed the maximum number of resolutions a user can discard while decoding.
authorFrancois-Olivier Devaux <fodevaux@users.noreply.github.com>
Tue, 27 Nov 2007 14:00:45 +0000 (14:00 +0000)
committerFrancois-Olivier Devaux <fodevaux@users.noreply.github.com>
Tue, 27 Nov 2007 14:00:45 +0000 (14:00 +0000)
Added an error state in J2K_STATE (j2k.c)

ChangeLog
libopenjpeg/j2k.c
libopenjpeg/j2k.h
libopenjpeg/tcd.c

index 44142241d2c6742362586c2ae41a2af96f6fc79e..8e348eacac03cb83fe6437432b7b02f97052ac6d 100644 (file)
--- 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
index f563b2a63011ae9043f40d796666a12f23fa4d3b..c7a6f4a7c80bb07f959ad3e88b06e686132b2523 100644 (file)
@@ -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;
                }
index 2dc21ec02edd62364e8a07dd5ba5a1764c26456e..5599be47a8dbe5acc326cec00a9b0cf67096816e 100644 (file)
@@ -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;
 
 /* ----------------------------------------------------------------------- */
index 38f6b6ba87b6c5512b57f42dcc3047a97b92db96..95cfd93e05740aed6f8c2f7178e147179001ae5a 100644 (file)
@@ -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;
                        }
                }