+ if (!jp2->ignore_pclr_cmap_cdef) {
+ if (!opj_jp2_check_color(p_image, &(jp2->color), p_manager)) {
+ return OPJ_FALSE;
+ }
+
+ /* Set Image Color Space */
+ if (jp2->enumcs == 16) {
+ p_image->color_space = OPJ_CLRSPC_SRGB;
+ } else if (jp2->enumcs == 17) {
+ p_image->color_space = OPJ_CLRSPC_GRAY;
+ } else if (jp2->enumcs == 18) {
+ p_image->color_space = OPJ_CLRSPC_SYCC;
+ } else if (jp2->enumcs == 24) {
+ p_image->color_space = OPJ_CLRSPC_EYCC;
+ } else if (jp2->enumcs == 12) {
+ p_image->color_space = OPJ_CLRSPC_CMYK;
+ } else {
+ p_image->color_space = OPJ_CLRSPC_UNKNOWN;
+ }
+
+ if (jp2->color.jp2_pclr) {
+ /* Part 1, I.5.3.4: Either both or none : */
+ if (!jp2->color.jp2_pclr->cmap) {
+ opj_jp2_free_pclr(&(jp2->color));
+ } else {
+ opj_jp2_apply_pclr(p_image, &(jp2->color));
+ }
+ }
+
+ /* Apply the color space if needed */
+ if (jp2->color.jp2_cdef) {
+ opj_jp2_apply_cdef(p_image, &(jp2->color), p_manager);
+ }
+
+ 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;
+}
+
+static OPJ_BOOL opj_jp2_write_jp2h(opj_jp2_t *jp2,
+ opj_stream_private_t *stream,
+ opj_event_mgr_t * p_manager
+ )
+{
+ opj_jp2_img_header_writer_handler_t l_writers [4];
+ opj_jp2_img_header_writer_handler_t * l_current_writer;
+
+ OPJ_INT32 i, l_nb_pass;
+ /* size of data for super box*/
+ OPJ_UINT32 l_jp2h_size = 8;
+ OPJ_BOOL l_result = OPJ_TRUE;
+
+ /* to store the data of the super box */
+ OPJ_BYTE l_jp2h_data [8];
+
+ /* preconditions */
+ assert(stream != 00);
+ assert(jp2 != 00);
+ assert(p_manager != 00);
+
+ memset(l_writers, 0, sizeof(l_writers));
+
+ if (jp2->bpc == 255) {
+ l_nb_pass = 3;
+ l_writers[0].handler = opj_jp2_write_ihdr;
+ l_writers[1].handler = opj_jp2_write_bpcc;
+ l_writers[2].handler = opj_jp2_write_colr;
+ } else {
+ l_nb_pass = 2;
+ l_writers[0].handler = opj_jp2_write_ihdr;
+ l_writers[1].handler = opj_jp2_write_colr;
+ }
+
+ if (jp2->color.jp2_cdef != NULL) {
+ l_writers[l_nb_pass].handler = opj_jp2_write_cdef;
+ l_nb_pass++;
+ }
+
+ /* write box header */
+ /* write JP2H type */
+ opj_write_bytes(l_jp2h_data + 4, JP2_JP2H, 4);
+
+ l_current_writer = l_writers;
+ for (i = 0; i < l_nb_pass; ++i) {
+ l_current_writer->m_data = l_current_writer->handler(jp2,
+ &(l_current_writer->m_size));
+ if (l_current_writer->m_data == 00) {
+ opj_event_msg(p_manager, EVT_ERROR,
+ "Not enough memory to hold JP2 Header data\n");
+ l_result = OPJ_FALSE;
+ break;
+ }
+
+ l_jp2h_size += l_current_writer->m_size;
+ ++l_current_writer;
+ }
+
+ if (! l_result) {
+ l_current_writer = l_writers;
+ for (i = 0; i < l_nb_pass; ++i) {
+ if (l_current_writer->m_data != 00) {
+ opj_free(l_current_writer->m_data);
+ }
+ ++l_current_writer;
+ }
+
+ return OPJ_FALSE;
+ }
+
+ /* write super box size */
+ opj_write_bytes(l_jp2h_data, l_jp2h_size, 4);
+
+ /* write super box data on stream */
+ if (opj_stream_write_data(stream, l_jp2h_data, 8, p_manager) != 8) {
+ opj_event_msg(p_manager, EVT_ERROR,
+ "Stream error while writing JP2 Header box\n");
+ l_result = OPJ_FALSE;
+ }
+
+ if (l_result) {
+ l_current_writer = l_writers;
+ for (i = 0; i < l_nb_pass; ++i) {
+ if (opj_stream_write_data(stream, 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 writing JP2 Header box\n");
+ l_result = OPJ_FALSE;
+ break;
+ }
+ ++l_current_writer;
+ }
+ }
+
+ l_current_writer = l_writers;
+
+ /* cleanup */
+ for (i = 0; i < l_nb_pass; ++i) {
+ if (l_current_writer->m_data != 00) {
+ opj_free(l_current_writer->m_data);
+ }
+ ++l_current_writer;
+ }
+
+ return l_result;
+}
+
+static OPJ_BOOL opj_jp2_write_ftyp(opj_jp2_t *jp2,
+ opj_stream_private_t *cio,
+ opj_event_mgr_t * p_manager)