[trunk] Backout r1513 for now.
[openjpeg.git] / libopenjpeg / jp2.c
index 43766b14dc2ee4bd26267d3ea2143c8d173b53fd..f60e9e49b41dd3aa0559cd3c59c8faaf6005c45d 100644 (file)
@@ -191,7 +191,7 @@ Apply collected palette data
 @param color Collector for profile, cdef and pclr data
 @param image 
 */
-static void jp2_apply_pclr(opj_jp2_color_t *color, opj_image_t *image);
+static void jp2_apply_pclr(opj_image_t *image, opj_jp2_color_t *color);
 /**
 Collect palette data
 @param jp2 JP2 handle
@@ -542,10 +542,9 @@ static opj_bool jp2_read_ihdr(opj_jp2_t *jp2, opj_cio_t *cio) {
 /**
  * Reads a IHDR box - Image Header box
  *
- * @param      p_image_header_data                     pointer to actual data (already read from file)
  * @param      jp2                                                     the jpeg2000 file codec.
+ * @param      p_image_header_data                     pointer to actual data (already read from file)
  * @param      p_image_header_size                     the size of the image header
- * @param      p_image_header_max_size         maximum size of the header, any size bigger than this value should result the function to output false.
  * @param      p_manager                                       the user event manager.
  *
  * @return     true if the image header is valid, fale else.
@@ -675,13 +674,12 @@ static opj_bool jp2_read_bpcc(opj_jp2_t *jp2, opj_cio_t *cio) {
 /**
  * Reads a Bit per Component box.
  *
- * @param      p_bpc_header_data                       pointer to actual data (already read from file)
  * @param      jp2                                                     the jpeg2000 file codec.
+ * @param      p_bpc_header_data                       pointer to actual data (already read from file)
  * @param      p_bpc_header_size                       pointer that will hold the size of the bpc header
- * @param      p_bpc_header_max_size           maximum size of the header, any size bigger than this value should result the function to output false.
  * @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 otherwise.
  */
 opj_bool jp2_read_bpcc_v2(     opj_jp2_v2_t *jp2,
                                                        unsigned char * p_bpc_header_data,
@@ -763,16 +761,17 @@ static void free_color_data(opj_jp2_color_t *color)
        if(color->icc_profile_buf) opj_free(color->icc_profile_buf);
 }
 
-static void jp2_apply_pclr(opj_jp2_color_t *color, opj_image_t *image)
+
+static void jp2_apply_pclr(opj_image_t *image, opj_jp2_color_t *color)
 {
        opj_image_comp_t *old_comps, *new_comps;
-       unsigned char *channel_size, *channel_sign;
-       unsigned int *entries;
+       OPJ_BYTE *channel_size, *channel_sign;
+       OPJ_UINT32 *entries;
        opj_jp2_cmap_comp_t *cmap;
-       int *src, *dst;
-       unsigned int j, max;
-       unsigned short i, nr_channels, cmp, pcol;
-       int k, top_k;
+       OPJ_INT32 *src, *dst;
+       OPJ_UINT32 j, max;
+       OPJ_UINT16 i, nr_channels, cmp, pcol;
+       OPJ_INT32 k, top_k;
 
        channel_size = color->jp2_pclr->channel_size;
        channel_sign = color->jp2_pclr->channel_sign;
@@ -782,50 +781,52 @@ static void jp2_apply_pclr(opj_jp2_color_t *color, opj_image_t *image)
 
        old_comps = image->comps;
        new_comps = (opj_image_comp_t*)
-        opj_malloc(nr_channels * sizeof(opj_image_comp_t));
+                       opj_malloc(nr_channels * sizeof(opj_image_comp_t));
 
-       for(i = 0; i < nr_channels; ++i)
-   {
-       pcol = cmap[i].pcol; cmp = cmap[i].cmp;
+       for(i = 0; i < nr_channels; ++i) {
+               pcol = cmap[i].pcol; cmp = cmap[i].cmp;
 
-       new_comps[pcol] = old_comps[cmp];
+               new_comps[pcol] = old_comps[cmp];
+
+               /* Direct use */
+               if(cmap[i].mtyp == 0){
+                       old_comps[cmp].data = NULL; continue;
+               }
+
+               /* Palette mapping: */
+               new_comps[pcol].data = (int*)
+                               opj_malloc(old_comps[cmp].w * old_comps[cmp].h * sizeof(int));
+               new_comps[pcol].prec = channel_size[i];
+               new_comps[pcol].sgnd = channel_sign[i];
+       }
 
-       if(cmap[i].mtyp == 0) /* Direct use */
-  {
-       old_comps[cmp].data = NULL; continue;
-  }
-/* Palette mapping: */
-       new_comps[pcol].data = (int*)
-        opj_malloc(old_comps[cmp].w * old_comps[cmp].h * sizeof(int));
-       new_comps[pcol].prec = channel_size[i];
-       new_comps[pcol].sgnd = channel_sign[i];
-   }
        top_k = color->jp2_pclr->nr_entries - 1;
 
-       for(i = 0; i < nr_channels; ++i)
-   {
-/* Direct use: */
-       if(cmap[i].mtyp == 0) continue;
+       for(i = 0; i < nr_channels; ++i) {
+               /* Direct use: */
+               if(cmap[i].mtyp == 0) continue;
 
-/* Palette mapping: */
-       cmp = cmap[i].cmp; pcol = cmap[i].pcol;
-       src = old_comps[cmp].data; 
-       dst = new_comps[pcol].data;
-       max = new_comps[pcol].w * new_comps[pcol].h;
+               /* Palette mapping: */
+               cmp = cmap[i].cmp; pcol = cmap[i].pcol;
+               src = old_comps[cmp].data;
+               dst = new_comps[pcol].data;
+               max = new_comps[pcol].w * new_comps[pcol].h;
+
+               for(j = 0; j < max; ++j)
+               {
+                       /* The index */
+                       if((k = src[j]) < 0) k = 0; else if(k > top_k) k = top_k;
+
+                       /* The colour */
+                       dst[j] = entries[k * nr_channels + pcol];
+               }
+       }
 
-       for(j = 0; j < max; ++j)
-  {
-/* The index */
-       if((k = src[j]) < 0) k = 0; else if(k > top_k) k = top_k;
-/* The colour */
-       dst[j] = entries[k * nr_channels + pcol];
-  }
-   }
        max = image->numcomps;
-       for(i = 0; i < max; ++i)
-   {
-       if(old_comps[i].data) opj_free(old_comps[i].data);
-   }
+       for(i = 0; i < max; ++i) {
+               if(old_comps[i].data) opj_free(old_comps[i].data);
+       }
+
        opj_free(old_comps);
        image->comps = new_comps;
        image->numcomps = nr_channels;
@@ -834,6 +835,7 @@ static void jp2_apply_pclr(opj_jp2_color_t *color, opj_image_t *image)
 
 }/* apply_pclr() */
 
+
 static opj_bool jp2_read_pclr(opj_jp2_t *jp2, opj_cio_t *cio,
        opj_jp2_box_t *box, opj_jp2_color_t *color)
 {
@@ -892,10 +894,9 @@ static opj_bool jp2_read_pclr(opj_jp2_t *jp2, opj_cio_t *cio,
 /**
  * Reads a palette box.
  *
- * @param      p_bpc_header_data                       pointer to actual data (already read from file)
  * @param      jp2                                                     the jpeg2000 file codec.
- * @param      p_bpc_header_size                       pointer that will hold the size of the bpc header
- * @param      p_bpc_header_max_size           maximum size of the header, any size bigger than this value should result the function to output false.
+ * @param      p_pclr_header_data                      pointer to actual data (already read from file)
+ * @param      p_pclr_header_size                      pointer that will hold the size of the PCLR header
  * @param      p_manager                                       the user event manager.
  *
  * @return     true if the bpc header is valid, fale else.
@@ -1062,32 +1063,33 @@ static opj_bool jp2_read_cmap_v2(       opj_jp2_v2_t * jp2,
 static void jp2_apply_cdef(opj_image_t *image, opj_jp2_color_t *color)
 {
        opj_jp2_cdef_info_t *info;
-       int color_space;
-       unsigned short i, n, cn, typ, asoc, acn;
+       OPJ_INT32 color_space;
+       OPJ_UINT16 i, n, cn, typ, asoc, acn;
 
        color_space = image->color_space;
        info = color->jp2_cdef->info;
        n = color->jp2_cdef->n;
 
        for(i = 0; i < n; ++i)
-   {
-/* WATCH: acn = asoc - 1 ! */
-       if((asoc = info[i].asoc) == 0) continue;
+       {
+               /* WATCH: acn = asoc - 1 ! */
+               if((asoc = info[i].asoc) == 0) continue;
 
-       cn = info[i].cn; typ = info[i].typ; acn = asoc - 1;
+               cn = info[i].cn; typ = info[i].typ; acn = asoc - 1;
 
-       if(cn != acn)
-  {
-       opj_image_comp_t saved;
+               if(cn != acn)
+               {
+                       opj_image_comp_t saved;
 
-       memcpy(&saved, &image->comps[cn], sizeof(opj_image_comp_t));
-       memcpy(&image->comps[cn], &image->comps[acn], sizeof(opj_image_comp_t));
-       memcpy(&image->comps[acn], &saved, sizeof(opj_image_comp_t));
+                       memcpy(&saved, &image->comps[cn], sizeof(opj_image_comp_t));
+                       memcpy(&image->comps[cn], &image->comps[acn], sizeof(opj_image_comp_t));
+                       memcpy(&image->comps[acn], &saved, sizeof(opj_image_comp_t));
+
+                       info[i].asoc = cn + 1;
+                       info[acn].asoc = info[acn].cn + 1;
+               }
+       }
 
-       info[i].asoc = cn + 1;
-       info[acn].asoc = info[acn].cn + 1;
-  }
-   }
        if(color->jp2_cdef->info) opj_free(color->jp2_cdef->info);
 
        opj_free(color->jp2_cdef); color->jp2_cdef = NULL;
@@ -1372,7 +1374,7 @@ opj_bool jp2_read_jp2h(opj_jp2_t *jp2, opj_cio_t *cio, opj_jp2_color_t *color)
     jp2_read_boxhdr(cinfo, cio, &box);
     continue;
   }
-    if(box.type == JP2_CDEF)
+    if(box.type == JP2_CDEF && !jp2->ignore_pclr_cmap_cdef)
   {
     if( !jp2_read_cdef(jp2, cio, &box, color))
  {
@@ -1382,7 +1384,7 @@ opj_bool jp2_read_jp2h(opj_jp2_t *jp2, opj_cio_t *cio, opj_jp2_color_t *color)
     jp2_read_boxhdr(cinfo, cio, &box);
     continue;
   }
-    if(box.type == JP2_PCLR)
+    if(box.type == JP2_PCLR && !jp2->ignore_pclr_cmap_cdef)
   {
     if( !jp2_read_pclr(jp2, cio, &box, color))
  {
@@ -1392,7 +1394,7 @@ opj_bool jp2_read_jp2h(opj_jp2_t *jp2, opj_cio_t *cio, opj_jp2_color_t *color)
     jp2_read_boxhdr(cinfo, cio, &box);
     continue;
   }
-    if(box.type == JP2_CMAP)
+    if(box.type == JP2_CMAP && !jp2->ignore_pclr_cmap_cdef)
   {
     if( !jp2_read_cmap(jp2, cio, &box, color))
  {
@@ -1446,8 +1448,10 @@ opj_image_t* opj_jp2_decode(opj_jp2_t *jp2, opj_cio_t *cio,
        opj_event_msg(cinfo, EVT_ERROR, "Failed to decode J2K image\n");
        return NULL;
    }
+   
+    if (!jp2->ignore_pclr_cmap_cdef){
 
-/* Set Image Color Space */
+    /* Set Image Color Space */
        if (jp2->enumcs == 16)
                image->color_space = CLRSPC_SRGB;
        else if (jp2->enumcs == 17)
@@ -1467,7 +1471,7 @@ opj_image_t* opj_jp2_decode(opj_jp2_t *jp2, opj_cio_t *cio,
        if( !color.jp2_pclr->cmap) 
         jp2_free_pclr(&color);
        else
-        jp2_apply_pclr(&color, image);
+        jp2_apply_pclr(image, &color);
    }
        if(color.icc_profile_buf)
    {
@@ -1475,10 +1479,58 @@ opj_image_t* opj_jp2_decode(opj_jp2_t *jp2, opj_cio_t *cio,
        color.icc_profile_buf = NULL;
        image->icc_profile_len = color.icc_profile_len;
    }
+   }
+   
        return image;
 
 }/* opj_jp2_decode() */
 
+opj_bool jp2_decode_v2(        opj_jp2_v2_t *jp2,
+                                               struct opj_stream_private *cio,
+                                               opj_image_t* p_image,
+                                               struct opj_event_mgr * p_manager)
+{
+       if (!p_image)
+               return OPJ_FALSE;
+
+       /* J2K decoding */
+       if( ! j2k_decode_v2(jp2->j2k, cio, p_image, p_manager) ) {
+               opj_event_msg_v2(p_manager, EVT_ERROR, "Failed to decode the codestream in the JP2 file\n");
+               return OPJ_FALSE;
+       }
+
+       /* Set Image Color Space */
+       if (jp2->enumcs == 16)
+               p_image->color_space = CLRSPC_SRGB;
+       else if (jp2->enumcs == 17)
+               p_image->color_space = CLRSPC_GRAY;
+       else if (jp2->enumcs == 18)
+               p_image->color_space = CLRSPC_SYCC;
+       else
+               p_image->color_space = CLRSPC_UNKNOWN;
+
+       /* Apply the color space if needed */
+       if(jp2->color.jp2_cdef) {
+               jp2_apply_cdef(p_image, &(jp2->color));
+       }
+
+       if(jp2->color.jp2_pclr) {
+               /* Part 1, I.5.3.4: Either both or none : */
+               if( !jp2->color.jp2_pclr->cmap)
+                       jp2_free_pclr(&(jp2->color));
+               else
+                       jp2_apply_pclr(p_image, &(jp2->color));
+       }
+
+       if(jp2->color.icc_profile_buf) {
+               p_image->icc_profile_buf = jp2->color.icc_profile_buf;
+               p_image->icc_profile_len = jp2->color.icc_profile_len;
+               jp2->color.icc_profile_buf = NULL;
+       }
+
+       return OPJ_TRUE;
+}
+
 
 void jp2_write_jp2h(opj_jp2_t *jp2, opj_cio_t *cio) {
        opj_jp2_box_t box;
@@ -1659,7 +1711,7 @@ static int write_fidx( int offset_jp2c, int length_jp2c, int offset_idx, int len
   cio_skip( cio, 4);              /* L [at the end] */
   cio_write( cio, JPIP_FIDX, 4);  /* IPTR           */
   
-  write_prxy( offset_jp2c, length_jp2c, offset_idx, offset_jp2c, cio);
+  write_prxy( offset_jp2c, length_jp2c, offset_idx, length_idx, cio);
 
   len = cio_tell( cio)-lenp;
   cio_seek( cio, lenp);
@@ -1748,6 +1800,7 @@ void jp2_setup_decoder(opj_jp2_t *jp2, opj_dparameters_t *parameters) {
        /* setup the J2K codec */
        j2k_setup_decoder(jp2->j2k, parameters);
        /* further JP2 initializations go here */
+       jp2->ignore_pclr_cmap_cdef = parameters->flags & OPJ_DPARAMETERS_IGNORE_PCLR_CMAP_CDEF_FLAG;
 }
 
 void jp2_setup_decoder_v2(opj_jp2_v2_t *jp2, opj_dparameters_t *parameters)
@@ -1862,7 +1915,7 @@ void jp2_setup_encoder(opj_jp2_t *jp2, opj_cparameters_t *parameters, opj_image_
 
 opj_bool opj_jp2_encode(opj_jp2_t *jp2, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info) {
 
-       int pos_iptr, pos_cidx, pos_jp2c, len_jp2c, end_pos, pos_fidx, len_fidx;
+       int pos_iptr, pos_cidx, pos_jp2c, len_jp2c, len_cidx, end_pos, pos_fidx, len_fidx;
 
        /* JP2 encoding */
 
@@ -1889,10 +1942,10 @@ opj_bool opj_jp2_encode(opj_jp2_t *jp2, opj_cio_t *cio, opj_image_t *image, opj_
        if( jp2->jpip_on){
          pos_cidx = cio_tell( cio);
          
-         write_cidx( pos_jp2c+8, cio, image, *cstr_info, len_jp2c-8);
+         len_cidx = write_cidx( pos_jp2c+8, cio, image, *cstr_info, len_jp2c-8);
          
          pos_fidx = cio_tell( cio);
-         len_fidx = write_fidx( pos_jp2c, len_jp2c, pos_cidx, cio_tell(cio), cio);
+         len_fidx = write_fidx( pos_jp2c, len_jp2c, pos_cidx, len_cidx, cio);
          
          end_pos = cio_tell( cio);
          
@@ -1999,6 +2052,10 @@ opj_bool jp2_read_header_procedure(
                if (l_current_handler != 00) {
                        if (l_current_data_size > l_last_data_size) {
                                l_current_data = (unsigned char*)opj_realloc(l_current_data,l_current_data_size);
+                               if (!l_current_data){
+                                       opj_free(l_current_data);
+                                       return OPJ_FALSE;
+                               }
                                l_last_data_size = l_current_data_size;
                        }
 
@@ -2390,11 +2447,11 @@ static opj_bool jp2_read_boxhdr_char(
  */
 opj_bool jp2_read_header(      struct opj_stream_private *p_stream,
                                                        opj_jp2_v2_t *jp2,
-                                                       opj_file_info_t * p_file_info,
+                                                       opj_image_t** p_image,
                                                        struct opj_event_mgr * p_manager
                                                        )
 {
-       // preconditions
+       /* preconditions */
        assert(jp2 != 00);
        assert(p_stream != 00);
        assert(p_manager != 00);
@@ -2417,7 +2474,7 @@ opj_bool jp2_read_header( struct opj_stream_private *p_stream,
 
        return j2k_read_header( p_stream,
                                                        jp2->j2k,
-                                                       p_file_info,
+                                                       p_image,
                                                        p_manager);
 }
 
@@ -2479,7 +2536,7 @@ opj_bool jp2_read_tile_header(    opj_jp2_v2_t * p_jp2,
  * @param      p_stream                        the stream to write data to.
  * @param      p_manager       the user event manager.
  */
-opj_bool opj_jp2_decode_tile (
+opj_bool jp2_decode_tile (
                                        opj_jp2_v2_t * p_jp2,
                                        OPJ_UINT32 p_tile_index,
                                        OPJ_BYTE * p_data,
@@ -2519,11 +2576,33 @@ void jp2_destroy(opj_jp2_v2_t *jp2)
                }
 
                if (jp2->color.jp2_cdef) {
+                       if (jp2->color.jp2_cdef->info) {
+                               opj_free(jp2->color.jp2_cdef->info);
+                               jp2->color.jp2_cdef->info = NULL;
+                       }
+
                        opj_free(jp2->color.jp2_cdef);
                        jp2->color.jp2_cdef = 00;
                }
 
                if (jp2->color.jp2_pclr) {
+                       if (jp2->color.jp2_pclr->cmap) {
+                               opj_free(jp2->color.jp2_pclr->cmap);
+                               jp2->color.jp2_pclr->cmap = NULL;
+                       }
+                       if (jp2->color.jp2_pclr->channel_sign) {
+                               opj_free(jp2->color.jp2_pclr->channel_sign);
+                               jp2->color.jp2_pclr->channel_sign = NULL;
+                       }
+                       if (jp2->color.jp2_pclr->channel_size) {
+                               opj_free(jp2->color.jp2_pclr->channel_size);
+                               jp2->color.jp2_pclr->channel_size = NULL;
+                       }
+                       if (jp2->color.jp2_pclr->entries) {
+                               opj_free(jp2->color.jp2_pclr->entries);
+                               jp2->color.jp2_pclr->entries = NULL;
+                       }
+
                        opj_free(jp2->color.jp2_pclr);
                        jp2->color.jp2_pclr = 00;
                }
@@ -2554,13 +2633,75 @@ void jp2_destroy(opj_jp2_v2_t *jp2)
  * @return     true                    if the area could be set.
  */
 opj_bool jp2_set_decode_area(  opj_jp2_v2_t *p_jp2,
+                                                               opj_image_t* p_image,
                                                                OPJ_INT32 p_start_x, OPJ_INT32 p_start_y,
                                                                OPJ_INT32 p_end_x, OPJ_INT32 p_end_y,
                                                                struct opj_event_mgr * p_manager )
 {
-       return j2k_set_decode_area(p_jp2->j2k, p_start_x, p_start_y, p_end_x, p_end_y, p_manager);
+       return j2k_set_decode_area(p_jp2->j2k, p_image, p_start_x, p_start_y, p_end_x, p_end_y, p_manager);
 }
 
+/**
+ * Get the decoded tile.
+ *
+ * @param      jp2                     the jpeg2000 codec.
+ * @param      p_stream                input_stream
+ * @param      p_image                 output image.   .
+ * @param      p_manager               the user event manager
+ * @param      tile_index              index of the tile we want decode
+ *
+ * @return     true                    if succeed.
+ */
+opj_bool jp2_get_tile( opj_jp2_v2_t *jp2,
+                                               opj_stream_private_t *p_stream,
+                                               opj_image_t* p_image,
+                                               struct opj_event_mgr * p_manager,
+                                               OPJ_UINT32 tile_index )
+{
+       if (!p_image)
+               return OPJ_FALSE;
+
+       opj_event_msg_v2(p_manager, EVT_WARNING, "JP2 box which are after the codestream will not be read by this function.\n");
+
+       if (! j2k_get_tile(jp2->j2k, p_stream, p_image, p_manager, tile_index) ){
+               opj_event_msg_v2(p_manager, EVT_ERROR, "Failed to decode the codestream in the JP2 file\n");
+               return OPJ_FALSE;
+       }
+
+       /* Set Image Color Space */
+       if (jp2->enumcs == 16)
+               p_image->color_space = CLRSPC_SRGB;
+       else if (jp2->enumcs == 17)
+               p_image->color_space = CLRSPC_GRAY;
+       else if (jp2->enumcs == 18)
+               p_image->color_space = CLRSPC_SYCC;
+       else
+               p_image->color_space = CLRSPC_UNKNOWN;
+
+       /* Apply the color space if needed */
+       if(jp2->color.jp2_cdef) {
+               jp2_apply_cdef(p_image, &(jp2->color));
+       }
+
+       if(jp2->color.jp2_pclr) {
+               /* Part 1, I.5.3.4: Either both or none : */
+               if( !jp2->color.jp2_pclr->cmap)
+                       jp2_free_pclr(&(jp2->color));
+               else
+                       jp2_apply_pclr(p_image, &(jp2->color));
+       }
+
+       if(jp2->color.icc_profile_buf) {
+               p_image->icc_profile_buf = jp2->color.icc_profile_buf;
+               p_image->icc_profile_len = jp2->color.icc_profile_len;
+               jp2->color.icc_profile_buf = NULL;
+       }
+
+       return OPJ_TRUE;
+}
+
+
+
 /* ----------------------------------------------------------------------- */
 /* JP2 encoder interface                                             */
 /* ----------------------------------------------------------------------- */
@@ -2584,6 +2725,13 @@ opj_jp2_v2_t* jp2_create(opj_bool p_is_decoder)
                        return 00;
                }
 
+               /* Color structure */
+               jp2->color.icc_profile_buf = NULL;
+               jp2->color.icc_profile_len = 0;
+               jp2->color.jp2_cdef = NULL;
+               jp2->color.jp2_pclr = NULL;
+               jp2->color.jp2_has_colr = 0;
+
                // validation list creation
                jp2->m_validation_list = opj_procedure_list_create();
                if (! jp2->m_validation_list) {
@@ -2601,3 +2749,29 @@ opj_jp2_v2_t* jp2_create(opj_bool p_is_decoder)
 
        return jp2;
 }
+
+void jp2_dump(opj_jp2_v2_t* p_jp2, OPJ_INT32 flag, FILE* out_stream)
+{
+       /* preconditions */
+       assert(p_jp2 != 00);
+
+       j2k_dump(p_jp2->j2k,
+                                       flag,
+                                       out_stream);
+}
+
+opj_codestream_index_t* jp2_get_cstr_index(opj_jp2_v2_t* p_jp2)
+{
+       return j2k_get_cstr_index(p_jp2->j2k);
+}
+
+opj_codestream_info_v2_t* jp2_get_cstr_info(opj_jp2_v2_t* p_jp2)
+{
+       return j2k_get_cstr_info(p_jp2->j2k);
+}
+
+opj_bool jp2_set_decoded_resolution_factor(opj_jp2_v2_t *p_jp2, OPJ_UINT32 res_factor, opj_event_mgr_t * p_manager)
+{
+       return j2k_set_decoded_resolution_factor(p_jp2->j2k, res_factor, p_manager);
+}
+