fixed a bug in image_to_j2k.c that was preventing the 'r' option to work properly...
[openjpeg.git] / libopenjpeg / jp2.c
index e224f4c6c82c93ff5b3cf09d1712ffbf33b3602f..b2831cfb0b5940d9b4594bb4d90a53aca528e0dd 100644 (file)
@@ -1,7 +1,10 @@
 /*
- * Copyright (c) 2004, Yannick Verschueren
- * Copyright (c) 2005, Herv� Drolon, FreeImage Team
- * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium
+ * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
+ * Copyright (c) 2002-2007, Professor Benoit Macq
+ * Copyright (c) 2001-2003, David Janssens
+ * Copyright (c) 2002-2003, Yannick Verschueren
+ * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -56,19 +59,6 @@ static bool jp2_read_bpcc(opj_jp2_t *jp2, opj_cio_t *cio);
 static void jp2_write_colr(opj_jp2_t *jp2, opj_cio_t *cio);
 static bool jp2_read_colr(opj_jp2_t *jp2, opj_cio_t *cio);
 /**
-Write the JP2H box - JP2 Header box
-@param jp2 JP2 handle
-@param cio Output buffer stream
-*/
-static void jp2_write_jp2h(opj_jp2_t *jp2, opj_cio_t *cio);
-/**
-Read the JP2H box - JP2 Header box
-@param jp2 JP2 handle
-@param cio Input buffer stream
-@return Returns true if successful, returns false otherwise
-*/
-static bool jp2_read_jp2h(opj_jp2_t *jp2, opj_cio_t *cio);
-/**
 Write the FTYP box - File type box
 @param jp2 JP2 handle
 @param cio Output buffer stream
@@ -81,7 +71,7 @@ Read the FTYP box - File type box
 @return Returns true if successful, returns false otherwise
 */
 static bool jp2_read_ftyp(opj_jp2_t *jp2, opj_cio_t *cio);
-static int jp2_write_jp2c(opj_jp2_t *jp2, opj_cio_t *cio, char *index);
+static int jp2_write_jp2c(opj_jp2_t *jp2, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info);
 static bool jp2_read_jp2c(opj_jp2_t *jp2, opj_cio_t *cio, unsigned int *j2k_codestream_length, unsigned int *j2k_codestream_offset);
 static void jp2_write_jp(opj_cio_t *cio);
 /**
@@ -305,7 +295,7 @@ static bool jp2_read_colr(opj_jp2_t *jp2, opj_cio_t *cio) {
        return true;
 }
 
-static void jp2_write_jp2h(opj_jp2_t *jp2, opj_cio_t *cio) {
+void jp2_write_jp2h(opj_jp2_t *jp2, opj_cio_t *cio) {
        opj_jp2_box_t box;
 
        box.init_pos = cio_tell(cio);
@@ -325,7 +315,7 @@ static void jp2_write_jp2h(opj_jp2_t *jp2, opj_cio_t *cio) {
        cio_seek(cio, box.init_pos + box.length);
 }
 
-static bool jp2_read_jp2h(opj_jp2_t *jp2, opj_cio_t *cio) {
+bool jp2_read_jp2h(opj_jp2_t *jp2, opj_cio_t *cio) {
        opj_jp2_box_t box;
        int skip_len;
 
@@ -414,12 +404,11 @@ static bool jp2_read_ftyp(opj_jp2_t *jp2, opj_cio_t *cio) {
        return true;
 }
 
-static int jp2_write_jp2c(opj_jp2_t *jp2, opj_cio_t *cio, char *index) {
+static int jp2_write_jp2c(opj_jp2_t *jp2, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info) {
        unsigned int j2k_codestream_offset, j2k_codestream_length;
        opj_jp2_box_t box;
 
        opj_j2k_t *j2k = jp2->j2k;
-       opj_image_t *image = jp2->image;
 
        box.init_pos = cio_tell(cio);
        cio_skip(cio, 4);
@@ -427,7 +416,7 @@ static int jp2_write_jp2c(opj_jp2_t *jp2, opj_cio_t *cio, char *index) {
 
        /* J2K encoding */
        j2k_codestream_offset = cio_tell(cio);
-       if(!j2k_encode(j2k, cio, image, index)) {
+       if(!j2k_encode(j2k, cio, image, cstr_info)) {
                opj_event_msg(j2k->cinfo, EVT_ERROR, "Failed to encode image\n");
                return 0;
        }
@@ -518,7 +507,7 @@ static bool jp2_read_struct(opj_jp2_t *jp2, opj_cio_t *cio) {
 /* ----------------------------------------------------------------------- */
 
 opj_jp2_t* jp2_create_decompress(opj_common_ptr cinfo) {
-       opj_jp2_t *jp2 = (opj_jp2_t*)opj_malloc(sizeof(opj_jp2_t));
+       opj_jp2_t *jp2 = (opj_jp2_t*) opj_calloc(1, sizeof(opj_jp2_t));
        if(jp2) {
                jp2->cinfo = cinfo;
                /* create the J2K codec */
@@ -552,7 +541,7 @@ void jp2_setup_decoder(opj_jp2_t *jp2, opj_dparameters_t *parameters) {
        /* further JP2 initializations go here */
 }
 
-opj_image_t* jp2_decode(opj_jp2_t *jp2, opj_cio_t *cio) {
+opj_image_t* 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;
 
@@ -569,11 +558,22 @@ opj_image_t* jp2_decode(opj_jp2_t *jp2, opj_cio_t *cio) {
        }
 
        /* J2K decoding */
-       image = j2k_decode(jp2->j2k, cio);
+       image = j2k_decode(jp2->j2k, cio, cstr_info);
        if(!image) {
                opj_event_msg(cinfo, EVT_ERROR, "Failed to decode J2K image\n");
+               return NULL;
        }
 
+       /* Set Image Color Space */
+       if (jp2->enumcs == 16)
+               image->color_space = CLRSPC_SRGB;
+       else if (jp2->enumcs == 17)
+               image->color_space = CLRSPC_GRAY;
+       else if (jp2->enumcs == 18)
+               image->color_space = CLRSPC_SYCC;
+       else
+               image->color_space = CLRSPC_UNKNOWN;
+
        return image;
 }
 
@@ -620,6 +620,12 @@ void jp2_setup_encoder(opj_jp2_t *jp2, opj_cparameters_t *parameters, opj_image_
        /* setup the J2K codec */
        /* ------------------- */
 
+       /* Check if number of components respects standard */
+       if (image->numcomps < 1 || image->numcomps > 16384) {
+               opj_event_msg(jp2->cinfo, EVT_ERROR, "Invalid number of components specified while setting up JP2 encoder\n");
+               return;
+       }
+
        j2k_setup_encoder(jp2->j2k, parameters, image);
 
        /* setup the JP2 codec */
@@ -635,8 +641,6 @@ void jp2_setup_encoder(opj_jp2_t *jp2, opj_cparameters_t *parameters, opj_image_
 
        /* Image Header box */
 
-       jp2->image = image;
-
        jp2->numcomps = image->numcomps;        /* NC */
        jp2->comps = (opj_jp2_comps_t*) opj_malloc(jp2->numcomps * sizeof(opj_jp2_comps_t));
        jp2->h = image->y1 - image->y0;         /* HEIGHT */
@@ -683,8 +687,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, char *index) {
-       (void)image;
+bool jp2_encode(opj_jp2_t *jp2, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info) {
 
        /* JP2 encoding */
 
@@ -697,7 +700,7 @@ bool jp2_encode(opj_jp2_t *jp2, opj_cio_t *cio, opj_image_t *image, char *index)
 
        /* J2K encoding */
 
-       if(!jp2_write_jp2c(jp2, cio, index)) {
+       if(!jp2_write_jp2c(jp2, cio, image, cstr_info)) {
                opj_event_msg(jp2->cinfo, EVT_ERROR, "Failed to encode image\n");
                return false;
        }