Merge branch 'master' of https://github.com/uclouvain/openjpeg into tier1_optimizatio...
[openjpeg.git] / src / lib / openjp2 / jp2.c
index c14e9a066726673b18cab8d989f95188b377a06a..ea81d0f5d61bf6fb1ac8f4ecc3d82eec7971d925 100644 (file)
@@ -94,7 +94,7 @@ static OPJ_BYTE * opj_jp2_write_bpcc( opj_jp2_t *jp2,
  * @param      p_bpc_header_size                       the size of the bpc header
  * @param      p_manager                                       the user event manager.
  *
- * @return     true if the bpc header is valid, fale else.
+ * @return     true if the bpc header is valid, false else.
  */
 static OPJ_BOOL opj_jp2_read_bpcc(  opj_jp2_t *jp2,
                                     OPJ_BYTE * p_bpc_header_data,
@@ -311,7 +311,7 @@ static OPJ_BOOL opj_jp2_read_cmap(  opj_jp2_t * jp2,
  * @param      p_colr_header_size                      the size of the color header
  * @param      p_manager                                       the user event manager.
  *
- * @return     true if the bpc header is valid, fale else.
+ * @return     true if the bpc header is valid, false else.
 */
 static OPJ_BOOL opj_jp2_read_colr(  opj_jp2_t *jp2,
                                     OPJ_BYTE * p_colr_header_data,
@@ -482,12 +482,16 @@ static OPJ_BOOL opj_jp2_read_boxhdr(opj_jp2_box_t *box,
        opj_read_bytes(l_data_header+4,&(box->type), 4);
     
   if(box->length == 0)/* last box */
-    {
+  {
     const OPJ_OFF_T bleft = opj_stream_get_number_byte_left(cio);
-    box->length = (OPJ_UINT32)bleft;
-    assert( (OPJ_OFF_T)box->length == bleft );
-    return OPJ_TRUE;
+    if (bleft > (OPJ_OFF_T)(0xFFFFFFFFU - 8U)) {
+      opj_event_msg(p_manager, EVT_ERROR, "Cannot handle box sizes higher than 2^32\n");
+      return OPJ_FALSE;
     }
+    box->length = (OPJ_UINT32)bleft + 8U;
+    assert( (OPJ_OFF_T)box->length == bleft + 8 );
+    return OPJ_TRUE;
+  }
 
        /* do we have a "special very large box ?" */
        /* read then the XLBox */
@@ -548,6 +552,11 @@ static OPJ_BOOL opj_jp2_read_ihdr( opj_jp2_t *jp2,
        assert(jp2 != 00);
        assert(p_manager != 00);
 
+       if (jp2->comps != NULL) {
+               opj_event_msg(p_manager, EVT_WARNING, "Ignoring ihdr box. First ihdr box already read\n");
+               return OPJ_TRUE;
+       }
+       
        if (p_image_header_size != 14) {
                opj_event_msg(p_manager, EVT_ERROR, "Bad image header box (bad size)\n");
                return OPJ_FALSE;
@@ -559,6 +568,11 @@ static OPJ_BOOL opj_jp2_read_ihdr( opj_jp2_t *jp2,
        p_image_header_data += 4;
        opj_read_bytes(p_image_header_data,&(jp2->numcomps),2);         /* NC */
        p_image_header_data += 2;
+       
+       if ((jp2->numcomps - 1U) >= 16384U) { /* unsigned underflow is well defined: 1U <= jp2->numcomps <= 16384U */
+               opj_event_msg(p_manager, EVT_ERROR, "Invalid number of components (ihdr)\n");
+               return OPJ_FALSE;
+       }
 
        /* allocate memory for components */
        jp2->comps = (opj_jp2_comps_t*) opj_calloc(jp2->numcomps, sizeof(opj_jp2_comps_t));
@@ -642,12 +656,13 @@ static OPJ_BYTE * opj_jp2_write_bpcc(     opj_jp2_t *jp2,
 {
        OPJ_UINT32 i;
        /* room for 8 bytes for box and 1 byte for each component */
-       OPJ_UINT32 l_bpcc_size = 8 + jp2->numcomps;
+       OPJ_UINT32 l_bpcc_size;
        OPJ_BYTE * l_bpcc_data,* l_current_bpcc_ptr;
        
        /* preconditions */
        assert(jp2 != 00);
        assert(p_nb_bytes_written != 00);
+       l_bpcc_size = 8 + jp2->numcomps;
 
        l_bpcc_data = (OPJ_BYTE *) opj_calloc(1,l_bpcc_size);
        if (l_bpcc_data == 00) {
@@ -1400,6 +1415,10 @@ static OPJ_BOOL opj_jp2_read_colr( opj_jp2_t *jp2,
                        OPJ_UINT32 rl, ol, ra, oa, rb, ob, il;
 
                        cielab = (OPJ_UINT32*)opj_malloc(9 * sizeof(OPJ_UINT32));
+                       if(cielab == NULL){
+                               opj_event_msg(p_manager, EVT_ERROR, "Not enough memory for cielab\n");
+                               return OPJ_FALSE;
+                       }
                        cielab[0] = 14; /* enumcs */
                        
                        /* default values */
@@ -1635,7 +1654,7 @@ static OPJ_BOOL opj_jp2_write_ftyp(opj_jp2_t *jp2,
                                                        opj_event_mgr_t * p_manager )
 {
        OPJ_UINT32 i;
-       OPJ_UINT32 l_ftyp_size = 16 + 4 * jp2->numcl;
+       OPJ_UINT32 l_ftyp_size;
        OPJ_BYTE * l_ftyp_data, * l_current_data_ptr;
        OPJ_BOOL l_result;
 
@@ -1643,6 +1662,7 @@ static OPJ_BOOL opj_jp2_write_ftyp(opj_jp2_t *jp2,
        assert(cio != 00);
        assert(jp2 != 00);
        assert(p_manager != 00);
+       l_ftyp_size = 16 + 4 * jp2->numcl;
 
        l_ftyp_data = (OPJ_BYTE *) opj_calloc(1,l_ftyp_size);
        
@@ -1754,7 +1774,12 @@ void opj_jp2_setup_decoder(opj_jp2_t *jp2, opj_dparameters_t *parameters)
 
        /* further JP2 initializations go here */
        jp2->color.jp2_has_colr = 0;
-    jp2->ignore_pclr_cmap_cdef = parameters->flags & OPJ_DPARAMETERS_IGNORE_PCLR_CMAP_CDEF_FLAG;
+       jp2->ignore_pclr_cmap_cdef = parameters->flags & OPJ_DPARAMETERS_IGNORE_PCLR_CMAP_CDEF_FLAG;
+}
+
+OPJ_BOOL opj_jp2_set_threads(opj_jp2_t *jp2, OPJ_UINT32 num_threads)
+{
+     return opj_j2k_set_threads(jp2->j2k, num_threads);
 }
 
 /* ----------------------------------------------------------------------- */
@@ -1800,7 +1825,6 @@ OPJ_BOOL opj_jp2_setup_encoder(   opj_jp2_t *jp2,
        jp2->numcl = 1;
        jp2->cl = (OPJ_UINT32*) opj_malloc(jp2->numcl * sizeof(OPJ_UINT32));
        if (!jp2->cl){
-               jp2->cl = NULL;
                opj_event_msg(p_manager, EVT_ERROR, "Not enough memory when setup the JP2 encoder\n");
                return OPJ_FALSE;
        }
@@ -1811,7 +1835,6 @@ OPJ_BOOL opj_jp2_setup_encoder(   opj_jp2_t *jp2,
        jp2->numcomps = image->numcomps;        /* NC */
        jp2->comps = (opj_jp2_comps_t*) opj_malloc(jp2->numcomps * sizeof(opj_jp2_comps_t));
        if (!jp2->comps) {
-               jp2->comps = NULL;
                opj_event_msg(p_manager, EVT_ERROR, "Not enough memory when setup the JP2 encoder\n");
                /* Memory of jp2->cl will be freed by opj_jp2_destroy */
                return OPJ_FALSE;
@@ -2112,7 +2135,7 @@ static OPJ_BOOL opj_jp2_read_header_procedure(  opj_jp2_t *jp2,
                if (box.type == JP2_JP2C) {
                        if (jp2->jp2_state & JP2_STATE_HEADER) {
                                jp2->jp2_state |= JP2_STATE_CODESTREAM;
-                                opj_free(l_current_data);
+                               opj_free(l_current_data);
                                return OPJ_TRUE;
                        }
                        else {
@@ -2127,7 +2150,7 @@ static OPJ_BOOL opj_jp2_read_header_procedure(  opj_jp2_t *jp2,
                        return OPJ_FALSE;
                }
                /* testcase 1851.pdf.SIGSEGV.ce9.948 */
-        else if (box.length < l_nb_bytes_read) {
+               else if (box.length < l_nb_bytes_read) {
                        opj_event_msg(p_manager, EVT_ERROR, "invalid box size %d (%x)\n", box.length, box.type);
                        opj_free(l_current_data);
                        return OPJ_FALSE;
@@ -2184,16 +2207,16 @@ static OPJ_BOOL opj_jp2_read_header_procedure(  opj_jp2_t *jp2,
                        }
                }
                else {
-            if (!(jp2->jp2_state & JP2_STATE_SIGNATURE)) {
-                opj_event_msg(p_manager, EVT_ERROR, "Malformed JP2 file format: first box must be JPEG 2000 signature box\n");
-                opj_free(l_current_data);
-                return OPJ_FALSE;
-            }
-            if (!(jp2->jp2_state & JP2_STATE_FILE_TYPE)) {
-                opj_event_msg(p_manager, EVT_ERROR, "Malformed JP2 file format: second box must be file type box\n");
-                opj_free(l_current_data);
-                return OPJ_FALSE;
-            }
+                       if (!(jp2->jp2_state & JP2_STATE_SIGNATURE)) {
+                               opj_event_msg(p_manager, EVT_ERROR, "Malformed JP2 file format: first box must be JPEG 2000 signature box\n");
+                               opj_free(l_current_data);
+                               return OPJ_FALSE;
+                       }
+                       if (!(jp2->jp2_state & JP2_STATE_FILE_TYPE)) {
+                               opj_event_msg(p_manager, EVT_ERROR, "Malformed JP2 file format: second box must be file type box\n");
+                               opj_free(l_current_data);
+                               return OPJ_FALSE;
+                       }
                        jp2->jp2_state |= JP2_STATE_UNKNOWN;
                        if (opj_stream_skip(stream,l_current_data_size,p_manager) != l_current_data_size) {
                                opj_event_msg(p_manager, EVT_ERROR, "Problem with skipping JPEG2000 box, stream error\n");