[trunk] clean jp2_read_ihdr_v2 interface
[openjpeg.git] / libopenjpeg / jp2.c
index 84c4f0498e536540f606ef31132269e837650c26..524bfa6a1ea638a75dfbfc0cc8cb254f9bb24d67 100644 (file)
@@ -64,14 +64,12 @@ static opj_bool jp2_read_ihdr(opj_jp2_t *jp2, opj_cio_t *cio);
  * @param      p_image_header_size                     the size of the image header
  * @param      p_manager                                       the user event manager.
  *
- * @return     true if the image header is valid, fale else.
+ * @return     true if the image header is valid, false else.
  */
-static opj_bool jp2_read_ihdr_v2(
-                                                       opj_jp2_v2_t *jp2,
-                                                       unsigned char * p_image_header_data,
-                                                       unsigned int p_image_header_size,
-                                                       struct opj_event_mgr * p_manager
-                                                 );
+static opj_bool jp2_read_ihdr_v2(   opj_jp2_v2_t *jp2,
+                                    OPJ_BYTE *p_image_header_data,
+                                    OPJ_INT32 p_image_header_size,
+                                    opj_event_mgr_t * p_manager );
 
 static void jp2_write_ihdr(opj_jp2_t *jp2, opj_cio_t *cio);
 
@@ -210,6 +208,21 @@ static opj_bool jp2_read_jp2h_v2(
                                        );
 
 static int jp2_write_jp2c(opj_jp2_t *jp2, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info);
+
+
+/**
+ * Writes the Jpeg2000 codestream Header box - JP2C Header box. This function must be called AFTER the coding has been done.
+ *
+ * @param      cio                     the stream to write data to.
+ * @param      jp2                     the jpeg2000 file codec.
+ * @param      p_manager       user event manager.
+ *
+ * @return true if writting was successful.
+*/
+static opj_bool jp2_write_jp2c_v2(     opj_jp2_v2_t *jp2,
+                                                               struct opj_stream_private *cio,
+                                                               struct opj_event_mgr * p_manager );
+
 static opj_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);
 /**
@@ -641,11 +654,10 @@ static opj_bool jp2_read_ihdr(opj_jp2_t *jp2, opj_cio_t *cio) {
  *
  * @return     true if the image header is valid, fale else.
  */
-opj_bool jp2_read_ihdr_v2(
-                                                       opj_jp2_v2_t *jp2,
-                                                       unsigned char * p_image_header_data,
-                                                       unsigned int p_image_header_size,
-                                                       opj_event_mgr_t * p_manager
+opj_bool jp2_read_ihdr_v2(  opj_jp2_v2_t *jp2,
+                            OPJ_BYTE *p_image_header_data,
+                            OPJ_INT32 p_image_header_size,
+                            opj_event_mgr_t * p_manager
                                                  )
 {
        /* preconditions */
@@ -662,7 +674,7 @@ opj_bool jp2_read_ihdr_v2(
        p_image_header_data += 4;
        opj_read_bytes(p_image_header_data,&(jp2->w),4);                        /* WIDTH */
        p_image_header_data += 4;
-       opj_read_bytes(p_image_header_data,&(jp2->numcomps),2);                 /* NC */
+       opj_read_bytes(p_image_header_data,&(jp2->numcomps),2);         /* NC */
        p_image_header_data += 2;
 
        /* allocate memory for components */
@@ -1145,7 +1157,7 @@ static opj_bool jp2_read_pclr(opj_jp2_t *jp2, opj_cio_t *cio,
        for(i = 0; i < nr_channels; ++i)
   {
 /* Cji */
-       *entries++ = cio_read(cio, channel_size[i]>>3);
+       *entries++ = cio_read(cio, (channel_size[i]+7)>>3);
   }
    }
 
@@ -1178,6 +1190,7 @@ opj_bool jp2_read_pclr_v2(        opj_jp2_v2_t *jp2,
        assert(p_pclr_header_data != 00);
        assert(jp2 != 00);
        assert(p_manager != 00);
+  (void)p_pclr_header_size;
 
        if(jp2->color.jp2_pclr)
                return OPJ_FALSE;
@@ -1214,9 +1227,10 @@ opj_bool jp2_read_pclr_v2(       opj_jp2_v2_t *jp2,
 
        for(j = 0; j < nr_entries; ++j) {
                for(i = 0; i < nr_channels; ++i) {
-                       /**entries++ = cio_read(cio, channel_size[i]>>3); */
-                       opj_read_bytes(p_pclr_header_data, &l_value , channel_size[i]>>3);      /* Cji */
-                       p_pclr_header_data += channel_size[i]>>3;
+                       int bytes_to_read = (channel_size[i]+7)>>3;
+
+                       opj_read_bytes(p_pclr_header_data, &l_value , bytes_to_read);   /* Cji */
+                       p_pclr_header_data += bytes_to_read;
                        *entries = (OPJ_UINT32) l_value;
                        entries++;
                }
@@ -1284,6 +1298,7 @@ static opj_bool jp2_read_cmap_v2( opj_jp2_v2_t * jp2,
        assert(jp2 != 00);
        assert(p_cmap_header_data != 00);
        assert(p_manager != 00);
+  (void)p_cmap_header_size;
 
        /* Need nr_channels: */
        if(jp2->color.jp2_pclr == NULL) {
@@ -1414,6 +1429,7 @@ static opj_bool jp2_read_cdef_v2( opj_jp2_v2_t * jp2,
        assert(jp2 != 00);
        assert(p_cdef_header_data != 00);
        assert(p_manager != 00);
+  (void)p_cdef_header_size;
 
        /* Part 1, I.5.3.6: 'The shall be at most one Channel Definition box
         * inside a JP2 Header box.'*/
@@ -1890,7 +1906,7 @@ opj_bool jp2_write_jp2h_v2(       opj_jp2_v2_t *jp2,
        
        /* write super box data on stream */
        if (opj_stream_write_data(cio,l_jp2h_data,8,p_manager) != 8) {
-               opj_event_msg(p_manager, EVT_ERROR, "Stream error while writting JP2 Header box\n");
+               opj_event_msg_v2(p_manager, EVT_ERROR, "Stream error while writing JP2 Header box\n");
                l_result = OPJ_FALSE;
        }
        
@@ -1898,7 +1914,7 @@ opj_bool jp2_write_jp2h_v2(       opj_jp2_v2_t *jp2,
                l_current_writer = l_writers;
                for (i=0;i<l_nb_pass;++i) {
                        if (opj_stream_write_data(cio,l_current_writer->m_data,l_current_writer->m_size,p_manager) != l_current_writer->m_size) {
-                               opj_event_msg(p_manager, EVT_ERROR, "Stream error while writting JP2 Header box\n");
+                               opj_event_msg_v2(p_manager, EVT_ERROR, "Stream error while writting JP2 Header box\n");
                                l_result = OPJ_FALSE;
                                break;
                        }
@@ -1993,7 +2009,7 @@ opj_bool jp2_write_ftyp_v2(       opj_jp2_v2_t *jp2,
        l_result = (opj_stream_write_data(cio,l_ftyp_data,l_ftyp_size,p_manager) == l_ftyp_size);
        if (! l_result)
        {
-               opj_event_msg(p_manager, EVT_ERROR, "Error while writting ftyp data to stream\n");
+               opj_event_msg_v2(p_manager, EVT_ERROR, "Error while writting ftyp data to stream\n");
        }
 
        opj_free(l_ftyp_data);
@@ -2060,6 +2076,50 @@ static int jp2_write_jp2c(opj_jp2_t *jp2, opj_cio_t *cio, opj_image_t *image, op
        return box.length;
 }
 
+/**
+ * Writes the Jpeg2000 codestream Header box - JP2C Header box.
+ *
+ * @param      cio                     the stream to write data to.
+ * @param      jp2                     the jpeg2000 file codec.
+ * @param      p_manager       user event manager.
+ *
+ * @return true if writting was successful.
+*/
+opj_bool jp2_write_jp2c_v2(    opj_jp2_v2_t *jp2,
+                                                       opj_stream_private_t *cio,
+                                                       opj_event_mgr_t * p_manager ) 
+{
+       unsigned int j2k_codestream_exit;
+       unsigned char l_data_header [8];
+       
+       // preconditions
+       assert(jp2 != 00);
+       assert(cio != 00);
+       assert(p_manager != 00);
+       assert(opj_stream_has_seek(cio));
+       
+       j2k_codestream_exit = opj_stream_tell(cio);
+       opj_write_bytes(l_data_header,j2k_codestream_exit - jp2->j2k_codestream_offset,4); /* size of codestream */
+       opj_write_bytes(l_data_header + 4,JP2_JP2C,4);                                                                     /* JP2C */
+
+       if (! opj_stream_seek(cio,jp2->j2k_codestream_offset,p_manager)) {
+               opj_event_msg_v2(p_manager, EVT_ERROR, "Failed to seek in the stream.\n");
+               return OPJ_FALSE;
+       }
+       
+       if (opj_stream_write_data(cio,l_data_header,8,p_manager) != 8) {
+               opj_event_msg_v2(p_manager, EVT_ERROR, "Failed to seek in the stream.\n");
+               return OPJ_FALSE;
+       }
+
+       if (! opj_stream_seek(cio,j2k_codestream_exit,p_manager)) {
+               opj_event_msg_v2(p_manager, EVT_ERROR, "Failed to seek in the stream.\n");
+               return OPJ_FALSE;
+       }
+
+       return OPJ_TRUE;
+}
+
 static opj_bool jp2_read_jp2c(opj_jp2_t *jp2, opj_cio_t *cio, unsigned int *j2k_codestream_length, unsigned int *j2k_codestream_offset) {
        opj_jp2_box_t box;
 
@@ -2497,7 +2557,7 @@ void jp2_setup_end_header_writting (opj_jp2_v2_t *jp2)
        /* preconditions */
        assert(jp2 != 00);
 
-       opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)jp2_write_jp2c );
+       opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)jp2_write_jp2c_v2 );
        /* DEVELOPER CORNER, add your custom procedures */
 }
 
@@ -3403,7 +3463,7 @@ opj_jp2_v2_t* jp2_create(opj_bool p_is_decoder)
 {
        opj_jp2_v2_t *jp2 = (opj_jp2_v2_t*)opj_malloc(sizeof(opj_jp2_v2_t));
        if (jp2) {
-               memset(jp2,0,sizeof(opj_jp2_t));
+               memset(jp2,0,sizeof(opj_jp2_v2_t));
 
                /* create the J2K codec */
                if (! p_is_decoder) {