fixed a bug in mqc.c (see https://groups.google.com/d/topic/openjpeg/kQ1PbZUd19k...
[openjpeg.git] / libopenjpeg / jp2.c
index 02f3adb676f42addf5ddcf5baa844e6d2c85fd42..62085a701b8b0ae8009968785584beebe15f50d4 100644 (file)
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGE.
  */
-#include <opj_config.h>
-#ifdef HAVE_LIBLCMS2
-#include <math.h>
-#include <lcms2.h>
-#endif
-#ifdef HAVE_LIBLCMS1
-#include <math.h>
-#include <lcms.h>
-#endif
 #include "opj_includes.h"
-#include "opj_convert.h"
 
 /** @defgroup JP2 JP2 - JPEG-2000 file format reader/writer */
 /*@{*/
@@ -93,11 +83,47 @@ static bool jp2_read_jp(opj_jp2_t *jp2, opj_cio_t *cio);
 Decode the structure of a JP2 file
 @param jp2 JP2 handle
 @param cio Input buffer stream
+@param color Collector for profile, cdef and pclr data
 @return Returns true if successful, returns false otherwise
 */
 static bool jp2_read_struct(opj_jp2_t *jp2, opj_cio_t *cio,
-       struct extension *ext);
-
+       opj_jp2_color_t *color);
+/**
+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);
+/**
+Collect palette data
+@param jp2 JP2 handle
+@param cio Input buffer stream
+@param box
+@param color Collector for profile, cdef and pclr data
+@return Returns true if successful, returns false otherwise
+*/
+static bool jp2_read_pclr(opj_jp2_t *jp2, opj_cio_t *cio,
+    opj_jp2_box_t *box, opj_jp2_color_t *color);
+/**
+Collect component mapping data
+@param jp2 JP2 handle
+@param cio Input buffer stream
+@param box
+@param color Collector for profile, cdef and pclr data
+@return Returns true if successful, returns false otherwise
+*/
+static bool jp2_read_cmap(opj_jp2_t *jp2, opj_cio_t *cio,
+    opj_jp2_box_t *box, opj_jp2_color_t *color);
+/**
+Collect colour specification data
+@param jp2 JP2 handle
+@param cio Input buffer stream
+@param box
+@param color Collector for profile, cdef and pclr data
+@return Returns true if successful, returns false otherwise
+*/
+static bool jp2_read_colr(opj_jp2_t *jp2, opj_cio_t *cio,
+    opj_jp2_box_t *box, opj_jp2_color_t *color);
 /*@}*/
 
 /*@}*/
@@ -267,32 +293,32 @@ static void jp2_write_colr(opj_jp2_t *jp2, opj_cio_t *cio) {
        cio_seek(cio, box.init_pos + box.length);
 }
 
-static void jp2_free_pclr(struct extension *ext)
+static void jp2_free_pclr(opj_jp2_color_t *color)
 {
-    opj_free(ext->jp2_pclr->channel_sign);
-    opj_free(ext->jp2_pclr->channel_size);
-    opj_free(ext->jp2_pclr->entries);
+    opj_free(color->jp2_pclr->channel_sign);
+    opj_free(color->jp2_pclr->channel_size);
+    opj_free(color->jp2_pclr->entries);
 
-       if(ext->jp2_pclr->cmap) opj_free(ext->jp2_pclr->cmap);
+       if(color->jp2_pclr->cmap) opj_free(color->jp2_pclr->cmap);
 
-    opj_free(ext->jp2_pclr); ext->jp2_pclr = NULL;
+    opj_free(color->jp2_pclr); color->jp2_pclr = NULL;
 }
 
-static void free_ext_data(struct extension *ext)
+static void free_color_data(opj_jp2_color_t *color)
 {
-       if(ext->jp2_pclr)
+       if(color->jp2_pclr)
    {
-       jp2_free_pclr(ext);
+       jp2_free_pclr(color);
    }
-       if(ext->jp2_cdef) 
+       if(color->jp2_cdef) 
    {
-       if(ext->jp2_cdef->info) opj_free(ext->jp2_cdef->info);
-       opj_free(ext->jp2_cdef);
+       if(color->jp2_cdef->info) opj_free(color->jp2_cdef->info);
+       opj_free(color->jp2_cdef);
    }
-       if(ext->jp2_profile_buf) opj_free(ext->jp2_profile_buf);
+       if(color->icc_profile_buf) opj_free(color->icc_profile_buf);
 }
 
-static void jp2_apply_pclr(struct extension *ext, opj_image_t *image)
+static void jp2_apply_pclr(opj_jp2_color_t *color, opj_image_t *image)
 {
        opj_image_comp_t *old_comps, *new_comps;
        unsigned char *channel_size, *channel_sign;
@@ -303,11 +329,11 @@ static void jp2_apply_pclr(struct extension *ext, opj_image_t *image)
        unsigned short i, nr_channels, cmp, pcol;
        int k, top_k;
 
-       channel_size = ext->jp2_pclr->channel_size;
-       channel_sign = ext->jp2_pclr->channel_sign;
-       entries = ext->jp2_pclr->entries;
-       cmap = ext->jp2_pclr->cmap;
-       nr_channels = ext->jp2_pclr->nr_channels;
+       channel_size = color->jp2_pclr->channel_size;
+       channel_sign = color->jp2_pclr->channel_sign;
+       entries = color->jp2_pclr->entries;
+       cmap = color->jp2_pclr->cmap;
+       nr_channels = color->jp2_pclr->nr_channels;
 
        old_comps = image->comps;
        new_comps = (opj_image_comp_t*)
@@ -329,7 +355,7 @@ static void jp2_apply_pclr(struct extension *ext, opj_image_t *image)
        new_comps[pcol].prec = channel_size[i];
        new_comps[pcol].sgnd = channel_sign[i];
    }
-       top_k = ext->jp2_pclr->nr_entries - 1;
+       top_k = color->jp2_pclr->nr_entries - 1;
 
        for(i = 0; i < nr_channels; ++i)
    {
@@ -359,12 +385,12 @@ static void jp2_apply_pclr(struct extension *ext, opj_image_t *image)
        image->comps = new_comps;
        image->numcomps = nr_channels;
 
-       jp2_free_pclr(ext);
+       jp2_free_pclr(color);
 
 }/* apply_pclr() */
 
 static bool jp2_read_pclr(opj_jp2_t *jp2, opj_cio_t *cio,
-       opj_jp2_box_t *box, struct extension *ext)
+       opj_jp2_box_t *box, opj_jp2_color_t *color)
 {
        opj_jp2_pclr_t *jp2_pclr;
        unsigned char *channel_size, *channel_sign;
@@ -376,7 +402,7 @@ static bool jp2_read_pclr(opj_jp2_t *jp2, opj_cio_t *cio,
 /* Part 1, I.5.3.4: 'There shall be at most one Palette box inside
  * a JP2 Header box' :
 */
-       if(ext->jp2_pclr) return false;
+       if(color->jp2_pclr) return false;
 
        nr_entries = cio_read(cio, 2); /* NE */
        nr_channels = cio_read(cio, 1);/* NPC */
@@ -394,7 +420,7 @@ static bool jp2_read_pclr(opj_jp2_t *jp2, opj_cio_t *cio,
        jp2_pclr->nr_channels = nr_channels;
        jp2_pclr->cmap = NULL;
 
-       ext->jp2_pclr = jp2_pclr;
+       color->jp2_pclr = jp2_pclr;
 
        for(i = 0; i < nr_channels; ++i)
    {
@@ -416,20 +442,20 @@ static bool jp2_read_pclr(opj_jp2_t *jp2, opj_cio_t *cio,
 }/* jp2_read_pclr() */
 
 static bool jp2_read_cmap(opj_jp2_t *jp2, opj_cio_t *cio,
-       opj_jp2_box_t *box, struct extension *ext)
+       opj_jp2_box_t *box, opj_jp2_color_t *color)
 {
        opj_jp2_cmap_comp_t *cmap;
        unsigned short i, nr_channels;
 
 /* Need nr_channels: */
-       if(ext->jp2_pclr == NULL) return false;
+       if(color->jp2_pclr == NULL) return false;
 
 /* Part 1, I.5.3.5: 'There shall be at most one Component Mapping box
  * inside a JP2 Header box' :
 */
-       if(ext->jp2_pclr->cmap) return false;
+       if(color->jp2_pclr->cmap) return false;
 
-       nr_channels = ext->jp2_pclr->nr_channels;
+       nr_channels = color->jp2_pclr->nr_channels;
        cmap = (opj_jp2_cmap_comp_t*)
         opj_malloc(nr_channels * sizeof(opj_jp2_cmap_comp_t));
 
@@ -440,20 +466,20 @@ static bool jp2_read_cmap(opj_jp2_t *jp2, opj_cio_t *cio,
        cmap[i].pcol = cio_read(cio, 1);
 
    }
-       ext->jp2_pclr->cmap = cmap;
+       color->jp2_pclr->cmap = cmap;
 
        return true;
 }/* jp2_read_cmap() */
 
-static void jp2_apply_cdef(opj_image_t *image, struct extension *ext)
+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;
 
        color_space = image->color_space;
-       info = ext->jp2_cdef->info;
-       n = ext->jp2_cdef->n;
+       info = color->jp2_cdef->info;
+       n = color->jp2_cdef->n;
 
        for(i = 0; i < n; ++i)
    {
@@ -474,14 +500,14 @@ static void jp2_apply_cdef(opj_image_t *image, struct extension *ext)
        info[acn].asoc = info[acn].cn + 1;
   }
    }
-       if(ext->jp2_cdef->info) opj_free(ext->jp2_cdef->info);
+       if(color->jp2_cdef->info) opj_free(color->jp2_cdef->info);
 
-       opj_free(ext->jp2_cdef); ext->jp2_cdef = NULL;
+       opj_free(color->jp2_cdef); color->jp2_cdef = NULL;
 
 }/* jp2_apply_cdef() */
 
 static bool jp2_read_cdef(opj_jp2_t *jp2, opj_cio_t *cio,
-       opj_jp2_box_t *box, struct extension *ext)
+       opj_jp2_box_t *box, opj_jp2_color_t *color)
 {
        opj_jp2_cdef_info_t *info;
        unsigned short i, n;
@@ -489,16 +515,16 @@ static bool jp2_read_cdef(opj_jp2_t *jp2, opj_cio_t *cio,
 /* Part 1, I.5.3.6: 'The shall be at most one Channel Definition box
  * inside a JP2 Header box.' 
 */
-       if(ext->jp2_cdef) return false;
+       if(color->jp2_cdef) return false;
 
        if((n = cio_read(cio, 2)) == 0) return false; /* szukw000: FIXME */
 
        info = (opj_jp2_cdef_info_t*)
         opj_malloc(n * sizeof(opj_jp2_cdef_info_t));
 
-       ext->jp2_cdef = (opj_jp2_cdef_t*)opj_malloc(sizeof(opj_jp2_cdef_t));
-       ext->jp2_cdef->info = info;
-       ext->jp2_cdef->n = n;
+       color->jp2_cdef = (opj_jp2_cdef_t*)opj_malloc(sizeof(opj_jp2_cdef_t));
+       color->jp2_cdef->info = info;
+       color->jp2_cdef->n = n;
 
        for(i = 0; i < n; ++i)
    {
@@ -511,7 +537,7 @@ static bool jp2_read_cdef(opj_jp2_t *jp2, opj_cio_t *cio,
 }/* jp2_read_cdef() */
 
 static bool jp2_read_colr(opj_jp2_t *jp2, opj_cio_t *cio,
-       opj_jp2_box_t *box, struct extension *ext
+       opj_jp2_box_t *box, opj_jp2_color_t *color
 {
        int skip_len;
     opj_common_ptr cinfo;
@@ -519,7 +545,7 @@ static bool jp2_read_colr(opj_jp2_t *jp2, opj_cio_t *cio,
 /* Part 1, I.5.3.3 : 'A conforming JP2 reader shall ignore all Colour
  * Specification boxes after the first.' 
 */
-       if(ext->jp2_has_colr) return false;
+       if(color->jp2_has_colr) return false;
 
        cinfo = jp2->cinfo;
 
@@ -545,12 +571,12 @@ static bool jp2_read_colr(opj_jp2_t *jp2, opj_cio_t *cio,
        unsigned char *start;
 
        start = cio_getbp(cio);
-       ext->jp2_profile_buf = (unsigned char*)opj_malloc(skip_len);
-       ext->jp2_profile_len = skip_len;
+       color->icc_profile_buf = (unsigned char*)opj_malloc(skip_len);
+       color->icc_profile_len = skip_len;
 
        cio_skip(cio, box->init_pos + box->length - cio_tell(cio));
 
-       memcpy(ext->jp2_profile_buf, start, skip_len);
+       memcpy(color->icc_profile_buf, start, skip_len);
   }
    }
 
@@ -559,216 +585,15 @@ static bool jp2_read_colr(opj_jp2_t *jp2, opj_cio_t *cio,
        opj_event_msg(cinfo, EVT_ERROR, "Error with COLR Box\n");
        return false;
    }
-       ext->jp2_has_colr = 1;
+       color->jp2_has_colr = 1;
 
        return true;
 }/* jp2_read_colr() */
 
-#if defined(HAVE_LIBLCMS2) || defined(HAVE_LIBLCMS1)
-#ifdef HAVE_LIBLCMS1
-/* Bob Friesenhahn proposed:*/
-#define cmsSigXYZData   icSigXYZData
-#define cmsSigLabData   icSigLabData
-#define cmsSigCmykData  icSigCmykData
-#define cmsSigYCbCrData icSigYCbCrData
-#define cmsSigLuvData   icSigLuvData
-#define cmsSigGrayData  icSigGrayData
-#define cmsSigRgbData   icSigRgbData
-#define cmsUInt32Number DWORD
-
-#define cmsColorSpaceSignature icColorSpaceSignature
-#define cmsGetHeaderRenderingIntent cmsTakeRenderingIntent
-
-#endif /* HAVE_LIBLCMS1 */
-
-static void jp2_apply_profile(struct extension *ext, opj_image_t *image)
-{
-       cmsHPROFILE in_prof, out_prof;
-       cmsHTRANSFORM transform;
-       cmsColorSpaceSignature in_space, out_space;
-       cmsUInt32Number intent, in_type, out_type, nr_samples;
-       int *r, *g, *b;
-       int prec, i, max, max_w, max_h;
-       OPJ_COLOR_SPACE oldspace;
-
-       in_prof = 
-        cmsOpenProfileFromMem(ext->jp2_profile_buf, ext->jp2_profile_len);
-       in_space = cmsGetPCS(in_prof);
-       out_space = cmsGetColorSpace(in_prof);
-       intent = cmsGetHeaderRenderingIntent(in_prof);
-
-       
-       max_w = image->comps[0].w; max_h = image->comps[0].h;
-       prec = image->comps[0].prec;
-       oldspace = image->color_space;
-
-       if(out_space == cmsSigRgbData) /* enumCS 16 */
-   {
-       in_type = TYPE_RGB_16;
-       out_type = TYPE_RGB_16;
-       out_prof = cmsCreate_sRGBProfile();
-       image->color_space = CLRSPC_SRGB;
-   }
-       else
-       if(out_space == cmsSigGrayData) /* enumCS 17 */
-   {
-       in_type = TYPE_GRAY_8;
-       out_type = TYPE_RGB_8;
-       out_prof = cmsCreate_sRGBProfile();
-       image->color_space = CLRSPC_SRGB;
-   }
-       else
-       if(out_space == cmsSigYCbCrData) /* enumCS 18 */
-   {
-       in_type = TYPE_YCbCr_16;
-       out_type = TYPE_RGB_16;
-       out_prof = cmsCreate_sRGBProfile();
-       image->color_space = CLRSPC_SRGB;
-   }
-       else
-   {
-#ifdef DEBUG_PROFILE
-fprintf(stderr,"%s:%d: jp2_apply_profile\n\tICC Profile has unknown "
-"output colorspace(%#x)(%c%c%c%c)\n\tICC Profile ignored.\n",
-__FILE__,__LINE__,out_space,
-(out_space>>24) & 0xff,(out_space>>16) & 0xff,
-(out_space>>8) & 0xff, out_space & 0xff);
-#endif
-       return;
-   }
-
-#ifdef DEBUG_PROFILE
-fprintf(stderr,"%s:%d:jp2_apply_profile\n\tchannels(%d) prec(%d) w(%d) h(%d)"
-"\n\tprofile: in(%p) out(%p)\n",__FILE__,__LINE__,image->numcomps,prec,
-max_w,max_h, (void*)in_prof,(void*)out_prof);
-
-fprintf(stderr,"\trender_intent (%u)\n\t"
-"color_space: in(%#x)(%c%c%c%c)   out:(%#x)(%c%c%c%c)\n\t"
-"       type: in(%u)              out:(%u)\n",
-intent,
-in_space,
-(in_space>>24) & 0xff,(in_space>>16) & 0xff,
-(in_space>>8) & 0xff, in_space & 0xff,
-
-out_space,
-(out_space>>24) & 0xff,(out_space>>16) & 0xff,
-(out_space>>8) & 0xff, out_space & 0xff,
-
-in_type,out_type
- );
-#endif /* DEBUG_PROFILE */
-
-       transform = cmsCreateTransform(in_prof, in_type,
-        out_prof, out_type, intent, 0);
-
-#ifdef HAVE_LIBLCMS2
-/* Possible for: LCMS_VERSION >= 2000 :*/
-       cmsCloseProfile(in_prof);
-       cmsCloseProfile(out_prof);
-#endif
-
-       if(transform == NULL)
-   {
-#ifdef DEBUG_PROFILE
-fprintf(stderr,"%s:%d:jp2_apply_profile\n\tcmsCreateTransform failed. "
-"ICC Profile ignored.\n",__FILE__,__LINE__);
-#endif
-       image->color_space = oldspace;
-#ifdef HAVE_LIBLCMS1
-       cmsCloseProfile(in_prof);
-       cmsCloseProfile(out_prof);
-#endif
-       return;
-   }
-
-       if(image->numcomps > 2)/* RGB, RGBA */
-   {
-       unsigned short *inbuf, *outbuf, *in, *out;
-       max = max_w * max_h; nr_samples = max * 3 * sizeof(unsigned short);
-       in = inbuf = (unsigned short*)opj_malloc(nr_samples);
-       out = outbuf = (unsigned short*)opj_malloc(nr_samples);
-
-       r = image->comps[0].data;
-       g = image->comps[1].data;
-       b = image->comps[2].data;
-
-       for(i = 0; i < max; ++i)
-  {
-       *in++ = (unsigned short)*r++;
-       *in++ = (unsigned short)*g++;
-       *in++ = (unsigned short)*b++;
-  }
-
-       cmsDoTransform(transform, inbuf, outbuf, max);
-
-       r = image->comps[0].data;
-       g = image->comps[1].data;
-       b = image->comps[2].data;
-
-       for(i = 0; i < max; ++i)
-  {
-       *r++ = (int)*out++;
-       *g++ = (int)*out++;
-       *b++ = (int)*out++;
-  }
-       opj_free(inbuf); opj_free(outbuf);
-   }
-       else /* GRAY, GRAYA */
-   {
-       unsigned char *in, *inbuf, *out, *outbuf;
-
-       max = max_w * max_h; nr_samples = max * 3 * sizeof(unsigned char);
-       in = inbuf = (unsigned char*)opj_malloc(nr_samples);
-       out = outbuf = (unsigned char*)opj_malloc(nr_samples);
-
-       image->comps = (opj_image_comp_t*)
-        opj_realloc(image->comps, (image->numcomps+2)*sizeof(opj_image_comp_t));
-
-       if(image->numcomps == 2)
-        image->comps[3] = image->comps[1];
-
-       image->comps[1] = image->comps[0];
-       image->comps[2] = image->comps[0];
-
-       image->comps[1].data = (int*)opj_calloc(max, sizeof(int));
-       image->comps[2].data = (int*)opj_calloc(max, sizeof(int));
-
-       image->numcomps += 2;
-
-       r = image->comps[0].data;
-
-       for(i = 0; i < max; ++i)
-  {
-       *in++ = (unsigned char)*r++;
-  }
-       cmsDoTransform(transform, inbuf, outbuf, max);
-
-       r = image->comps[0].data;
-       g = image->comps[1].data;
-       b = image->comps[2].data;
-
-       for(i = 0; i < max; ++i)
-  {
-       *r++ = (int)*out++; *g++ = (int)*out++; *b++ = (int)*out++;
-  }
-       opj_free(inbuf); opj_free(outbuf);
-
-   }/* if(image->numcomps */
-
-       cmsDeleteTransform(transform);
-
-#ifdef HAVE_LIBLCMS1
-       cmsCloseProfile(in_prof);
-       cmsCloseProfile(out_prof);
-#endif
-}/* jp2_apply_profile() */
-
-#endif /* HAVE_LIBLCMS2 || HAVE_LIBLCMS1 */
-
-bool jp2_read_jp2h(opj_jp2_t *jp2, opj_cio_t *cio, struct extension *ext) 
+bool jp2_read_jp2h(opj_jp2_t *jp2, opj_cio_t *cio, opj_jp2_color_t *color) 
 {
        opj_jp2_box_t box;
-       unsigned int jp2h_end;
+       int jp2h_end;
 
        opj_common_ptr cinfo = jp2->cinfo;
 
@@ -805,7 +630,7 @@ bool jp2_read_jp2h(opj_jp2_t *jp2, opj_cio_t *cio, struct extension *ext)
    {
        if(box.type == JP2_COLR)
   {
-       if( !jp2_read_colr(jp2, cio, &box, ext))
+       if( !jp2_read_colr(jp2, cio, &box, color))
  {
     cio_seek(cio, box.init_pos + 8);
     cio_skip(cio, box.length - 8);
@@ -815,7 +640,7 @@ bool jp2_read_jp2h(opj_jp2_t *jp2, opj_cio_t *cio, struct extension *ext)
   }
     if(box.type == JP2_CDEF)
   {
-    if( !jp2_read_cdef(jp2, cio, &box, ext))
+    if( !jp2_read_cdef(jp2, cio, &box, color))
  {
     cio_seek(cio, box.init_pos + 8);
     cio_skip(cio, box.length - 8);
@@ -825,7 +650,7 @@ bool jp2_read_jp2h(opj_jp2_t *jp2, opj_cio_t *cio, struct extension *ext)
   }
     if(box.type == JP2_PCLR)
   {
-    if( !jp2_read_pclr(jp2, cio, &box, ext))
+    if( !jp2_read_pclr(jp2, cio, &box, color))
  {
     cio_seek(cio, box.init_pos + 8);
     cio_skip(cio, box.length - 8);
@@ -835,7 +660,7 @@ bool jp2_read_jp2h(opj_jp2_t *jp2, opj_cio_t *cio, struct extension *ext)
   }
     if(box.type == JP2_CMAP)
   {
-    if( !jp2_read_cmap(jp2, cio, &box, ext))
+    if( !jp2_read_cmap(jp2, cio, &box, color))
  {
     cio_seek(cio, box.init_pos + 8);
     cio_skip(cio, box.length - 8);
@@ -852,28 +677,28 @@ bool jp2_read_jp2h(opj_jp2_t *jp2, opj_cio_t *cio, struct extension *ext)
        cio_seek(cio, jp2h_end);
 
 /* Part 1, I.5.3.3 : 'must contain at least one' */
-       return (ext->jp2_has_colr == 1);
+       return (color->jp2_has_colr == 1);
 
 }/* jp2_read_jp2h() */
 
-opj_image_t* jp2_decode(opj_jp2_t *jp2, opj_cio_t *cio, 
+opj_image_t* opj_jp2_decode(opj_jp2_t *jp2, opj_cio_t *cio, 
        opj_codestream_info_t *cstr_info) 
 {
        opj_common_ptr cinfo;
        opj_image_t *image = NULL;
-       struct extension ext;
+       opj_jp2_color_t color;
 
        if(!jp2 || !cio) 
    {
        return NULL;
    }
-       memset(&ext, 0, sizeof(struct extension));
+       memset(&color, 0, sizeof(opj_jp2_color_t));
        cinfo = jp2->cinfo;
 
 /* JP2 decoding */
-       if(!jp2_read_struct(jp2, cio, &ext)) 
+       if(!jp2_read_struct(jp2, cio, &color)) 
    {
-       free_ext_data(&ext);
+       free_color_data(&color);
        opj_event_msg(cinfo, EVT_ERROR, "Failed to decode jp2 structure\n");
        return NULL;
    }
@@ -883,7 +708,7 @@ opj_image_t* jp2_decode(opj_jp2_t *jp2, opj_cio_t *cio,
 
        if(!image) 
    {
-       free_ext_data(&ext);
+       free_color_data(&color);
        opj_event_msg(cinfo, EVT_ERROR, "Failed to decode J2K image\n");
        return NULL;
    }
@@ -898,33 +723,27 @@ opj_image_t* jp2_decode(opj_jp2_t *jp2, opj_cio_t *cio,
        else
                image->color_space = CLRSPC_UNKNOWN;
 
-       if(ext.jp2_cdef)
+       if(color.jp2_cdef)
    {
-       jp2_apply_cdef(image, &ext);
+       jp2_apply_cdef(image, &color);
    }
-       if(ext.jp2_pclr)
+       if(color.jp2_pclr)
    {
 /* Part 1, I.5.3.4: Either both or none : */
-       if( !ext.jp2_pclr->cmap) 
-        jp2_free_pclr(&ext);
+       if( !color.jp2_pclr->cmap) 
+        jp2_free_pclr(&color);
        else
-        jp2_apply_pclr(&ext, image);
+        jp2_apply_pclr(&color, image);
    }
-       if(ext.jp2_profile_buf)
-   {
-#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) 
-       jp2_apply_profile(&ext, image);
-#endif
-       opj_free(ext.jp2_profile_buf);
-   }
-       else
-       if(image->color_space == CLRSPC_SYCC)
+       if(color.icc_profile_buf)
    {
-       opj_convert_sycc_to_rgb(image);
+       image->icc_profile_buf = color.icc_profile_buf;
+       color.icc_profile_buf = NULL;
+       image->icc_profile_len = color.icc_profile_len;
    }
        return image;
 
-}/* jp2_decode() */
+}/* opj_jp2_decode() */
 
 
 void jp2_write_jp2h(opj_jp2_t *jp2, opj_cio_t *cio) {
@@ -1084,12 +903,12 @@ static bool jp2_read_jp(opj_jp2_t *jp2, opj_cio_t *cio) {
 
 
 static bool jp2_read_struct(opj_jp2_t *jp2, opj_cio_t *cio,
-       struct extension *ext) {
+       opj_jp2_color_t *color) {
        if (!jp2_read_jp(jp2, cio))
                return false;
        if (!jp2_read_ftyp(jp2, cio))
                return false;
-       if (!jp2_read_jp2h(jp2, cio, ext))
+       if (!jp2_read_jp2h(jp2, cio, color))
                return false;
        if (!jp2_read_jp2c(jp2, cio, &jp2->j2k_codestream_length, &jp2->j2k_codestream_offset))
                return false;
@@ -1233,7 +1052,7 @@ void jp2_setup_encoder(opj_jp2_t *jp2, opj_cparameters_t *parameters, opj_image_
        }
        if (jp2->meth == 1) {
                if (image->color_space == 1)
-                       jp2->enumcs = 16;       /* sRGB as defined by IEC 61966�2�1 */
+                       jp2->enumcs = 16;       /* sRGB as defined by IEC 61966-2.1 */
                else if (image->color_space == 2)
                        jp2->enumcs = 17;       /* greyscale */
                else if (image->color_space == 3)
@@ -1246,7 +1065,7 @@ void jp2_setup_encoder(opj_jp2_t *jp2, opj_cparameters_t *parameters, opj_image_
 
 }
 
-bool jp2_encode(opj_jp2_t *jp2, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info) {
+bool opj_jp2_encode(opj_jp2_t *jp2, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info) {
 
        /* JP2 encoding */