/*
 * The copyright in this software is being made available under the 2-clauses 
 * BSD License, included below. This software may be subject to other third 
 * party and contributor rights, including patent rights, and no such rights
 * are granted under this license.
 *
 * Copyright (c) 2002-2014, Universite catholique de Louvain (UCL), Belgium
 * Copyright (c) 2002-2014, Professor Benoit Macq
 * Copyright (c) 2001-2003, David Janssens
 * Copyright (c) 2002-2003, Yannick Verschueren
 * Copyright (c) 2003-2007, Francois-Olivier Devaux 
 * Copyright (c) 2003-2014, Antonin Descampe
 * Copyright (c) 2005, Herve Drolon, FreeImage Team
 * Copyright (c) 2010-2011, Kaori Hagihara
 * Copyright (c) 2008, 2011-2012, Centre National d'Etudes Spatiales (CNES), FR 
 * Copyright (c) 2012, CS Systemes d'Information, France
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */
#include "opj_includes.h"

/** @defgroup JP2 JP2 - JPEG-2000 file format reader/writer */
/*@{*/

#define OPJ_BOX_SIZE	1024

/** @name Local static functions */
/*@{*/

/*static void jp2_write_url(opj_cio_t *cio, char *Idx_file);*/

/**
 * 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_size			the size of the image header
 * @param	p_manager					the user event manager.
 *
 * @return	true if the image header is valid, false else.
 */
static OPJ_BOOL opj_jp2_read_ihdr(  opj_jp2_t *jp2,
                                    OPJ_BYTE *p_image_header_data,
                                    OPJ_UINT32 p_image_header_size,
                                    opj_event_mgr_t * p_manager );

/**
 * Writes the Image Header box - Image Header box.
 *
 * @param jp2					jpeg2000 file codec.
 * @param p_nb_bytes_written	pointer to store the nb of bytes written by the function.
 *
 * @return	the data being copied.
*/
static OPJ_BYTE * opj_jp2_write_ihdr(opj_jp2_t *jp2,
                                     OPJ_UINT32 * p_nb_bytes_written );

/**
 * Writes the Bit per Component box.
 *
 * @param	jp2						jpeg2000 file codec.
 * @param	p_nb_bytes_written		pointer to store the nb of bytes written by the function.
 *
 * @return	the data being copied.
*/
static OPJ_BYTE * opj_jp2_write_bpcc(	opj_jp2_t *jp2,
								        OPJ_UINT32 * p_nb_bytes_written );

/**
 * 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_size			the size of the bpc header
 * @param	p_manager					the user event manager.
 *
 * @return	true if the bpc header is valid, fale else.
 */
static OPJ_BOOL opj_jp2_read_bpcc(  opj_jp2_t *jp2,
                                    OPJ_BYTE * p_bpc_header_data,
                                    OPJ_UINT32 p_bpc_header_size,
                                    opj_event_mgr_t * p_manager );

static OPJ_BOOL opj_jp2_read_cdef(	opj_jp2_t * jp2,
                                    OPJ_BYTE * p_cdef_header_data,
									OPJ_UINT32 p_cdef_header_size,
									opj_event_mgr_t * p_manager );

static void opj_jp2_apply_cdef(opj_image_t *image, opj_jp2_color_t *color);

/**
 * Writes the Colour Specification box.
 *
 * @param jp2					jpeg2000 file codec.
 * @param p_nb_bytes_written	pointer to store the nb of bytes written by the function.
 *
 * @return	the data being copied.
*/
static OPJ_BYTE * opj_jp2_write_colr(   opj_jp2_t *jp2,
									    OPJ_UINT32 * p_nb_bytes_written );

/**
 * Writes a FTYP box - File type box
 *
 * @param	cio			the stream to write data to.
 * @param	jp2			the jpeg2000 file codec.
 * @param	p_manager	the user event manager.
 *
 * @return	true if writing was successful.
 */
static OPJ_BOOL opj_jp2_write_ftyp(	opj_jp2_t *jp2,
									opj_stream_private_t *cio,
									opj_event_mgr_t * p_manager );

/**
 * Reads a a FTYP box - File type box
 *
 * @param	p_header_data	the data contained in the FTYP box.
 * @param	jp2				the jpeg2000 file codec.
 * @param	p_header_size	the size of the data contained in the FTYP box.
 * @param	p_manager		the user event manager.
 *
 * @return true if the FTYP box is valid.
 */
static OPJ_BOOL opj_jp2_read_ftyp(	opj_jp2_t *jp2,
									OPJ_BYTE * p_header_data,
									OPJ_UINT32 p_header_size,
									opj_event_mgr_t * p_manager );

OPJ_BOOL opj_jp2_skip_jp2c(	opj_jp2_t *jp2,
						    opj_stream_private_t *cio,
						    opj_event_mgr_t * p_manager );

/**
 * Reads the Jpeg2000 file Header box - JP2 Header box (warning, this is a super box).
 *
 * @param	p_header_data	the data contained in the file header box.
 * @param	jp2				the jpeg2000 file codec.
 * @param	p_header_size	the size of the data contained in the file header box.
 * @param	p_manager		the user event manager.
 *
 * @return true if the JP2 Header box was successfully reconized.
*/
static OPJ_BOOL opj_jp2_read_jp2h(  opj_jp2_t *jp2,
                                    OPJ_BYTE *p_header_data,
                                    OPJ_UINT32 p_header_size,
                                    opj_event_mgr_t * p_manager );

/**
 * 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 writing was successful.
*/
static OPJ_BOOL opj_jp2_write_jp2c(	opj_jp2_t *jp2,
								    opj_stream_private_t *cio,
								    opj_event_mgr_t * p_manager );

#ifdef USE_JPIP
/**
 * Write index Finder box
 * @param cio     the stream to write to.
 * @param	jp2			the jpeg2000 file codec.
 * @param	p_manager	user event manager.
*/
static OPJ_BOOL opj_jpip_write_iptr(	opj_jp2_t *jp2,
								    opj_stream_private_t *cio,
								    opj_event_mgr_t * p_manager );

/**
 * Write index Finder box
 * @param cio     the stream to write to.
 * @param	jp2			the jpeg2000 file codec.
 * @param	p_manager	user event manager.
 */
static OPJ_BOOL opj_jpip_write_cidx(opj_jp2_t *jp2,
  opj_stream_private_t *cio,
  opj_event_mgr_t * p_manager );

/**
 * Write file Index (superbox)
 * @param cio     the stream to write to.
 * @param	jp2			the jpeg2000 file codec.
 * @param	p_manager	user event manager.
 */
static OPJ_BOOL opj_jpip_write_fidx(opj_jp2_t *jp2,
  opj_stream_private_t *cio,
  opj_event_mgr_t * p_manager );
#endif /* USE_JPIP */

/**
 * Reads a jpeg2000 file signature box.
 *
 * @param	p_header_data	the data contained in the signature box.
 * @param	jp2				the jpeg2000 file codec.
 * @param	p_header_size	the size of the data contained in the signature box.
 * @param	p_manager		the user event manager.
 *
 * @return true if the file signature box is valid.
 */
static OPJ_BOOL opj_jp2_read_jp(opj_jp2_t *jp2,
                                OPJ_BYTE * p_header_data,
                                OPJ_UINT32 p_header_size,
                                opj_event_mgr_t * p_manager);

/**
 * Writes a jpeg2000 file signature box.
 *
 * @param cio the stream to write data to.
 * @param	jp2			the jpeg2000 file codec.
 * @param p_manager the user event manager.
 *
 * @return true if writing was successful.
 */
static OPJ_BOOL opj_jp2_write_jp(	opj_jp2_t *jp2,
			    	        	    opj_stream_private_t *cio,
				            		opj_event_mgr_t * p_manager );

/**
Apply collected palette data
@param color Collector for profile, cdef and pclr data
@param image
*/
static void opj_jp2_apply_pclr(opj_image_t *image, opj_jp2_color_t *color);

static void opj_jp2_free_pclr(opj_jp2_color_t *color);

/**
 * Collect palette data
 *
 * @param jp2 JP2 handle
 * @param p_pclr_header_data    FIXME DOC
 * @param p_pclr_header_size    FIXME DOC
 * @param p_manager
 *
 * @return Returns true if successful, returns false otherwise
*/
static OPJ_BOOL opj_jp2_read_pclr(	opj_jp2_t *jp2,
                                    OPJ_BYTE * p_pclr_header_data,
                                    OPJ_UINT32 p_pclr_header_size,
                                    opj_event_mgr_t * p_manager );

/**
 * Collect component mapping data
 *
 * @param jp2                 JP2 handle
 * @param p_cmap_header_data  FIXME DOC
 * @param p_cmap_header_size  FIXME DOC
 * @param p_manager           FIXME DOC
 *
 * @return Returns true if successful, returns false otherwise
*/

static OPJ_BOOL opj_jp2_read_cmap(	opj_jp2_t * jp2,
                                    OPJ_BYTE * p_cmap_header_data,
                                    OPJ_UINT32 p_cmap_header_size,
                                    opj_event_mgr_t * p_manager );

/**
 * Reads the Color Specification box.
 *
 * @param	p_colr_header_data			pointer to actual data (already read from file)
 * @param	jp2							the jpeg2000 file codec.
 * @param	p_colr_header_size			the size of the color header
 * @param	p_manager					the user event manager.
 *
 * @return	true if the bpc header is valid, fale else.
*/
static OPJ_BOOL opj_jp2_read_colr(  opj_jp2_t *jp2,
                                    OPJ_BYTE * p_colr_header_data,
                                    OPJ_UINT32 p_colr_header_size,
                                    opj_event_mgr_t * p_manager );

/*@}*/

/*@}*/

/**
 * Sets up the procedures to do on writing header after the codestream.
 * Developpers wanting to extend the library can add their own writing procedures.
 */
static void opj_jp2_setup_end_header_writing (opj_jp2_t *jp2);

/**
 * Sets up the procedures to do on reading header after the codestream.
 * Developpers wanting to extend the library can add their own writing procedures.
 */
static void opj_jp2_setup_end_header_reading (opj_jp2_t *jp2);

/**
 * Reads a jpeg2000 file header structure.
 *
 * @param jp2 the jpeg2000 file header structure.
 * @param stream the stream to read data from.
 * @param p_manager the user event manager.
 *
 * @return true if the box is valid.
 */
static OPJ_BOOL opj_jp2_read_header_procedure(  opj_jp2_t *jp2,
                                                opj_stream_private_t *stream,
                                                opj_event_mgr_t * p_manager );

/**
 * Excutes the given procedures on the given codec.
 *
 * @param	p_procedure_list	the list of procedures to execute
 * @param	jp2					the jpeg2000 file codec to execute the procedures on.
 * @param	stream					the stream to execute the procedures on.
 * @param	p_manager			the user manager.
 *
 * @return	true				if all the procedures were successfully executed.
 */
static OPJ_BOOL opj_jp2_exec (  opj_jp2_t * jp2,
                                opj_procedure_list_t * p_procedure_list,
                                opj_stream_private_t *stream,
                                opj_event_mgr_t * p_manager );

/**
 * Reads a box header. The box is the way data is packed inside a jpeg2000 file structure.
 *
 * @param	cio						the input stream to read data from.
 * @param	box						the box structure to fill.
 * @param	p_number_bytes_read		pointer to an int that will store the number of bytes read from the stream (shoul usually be 2).
 * @param	p_manager				user event manager.
 *
 * @return	true if the box is reconized, false otherwise
*/
static OPJ_BOOL opj_jp2_read_boxhdr(opj_jp2_box_t *box,
                                    OPJ_UINT32 * p_number_bytes_read,
                                    opj_stream_private_t *cio,
                                    opj_event_mgr_t * p_manager);

/**
 * Sets up the validation ,i.e. adds the procedures to lauch to make sure the codec parameters
 * are valid. Developpers wanting to extend the library can add their own validation procedures.
 */
static void opj_jp2_setup_encoding_validation (opj_jp2_t *jp2);

/**
 * Sets up the procedures to do on writing header. Developpers wanting to extend the library can add their own writing procedures.
 */
static void opj_jp2_setup_header_writing (opj_jp2_t *jp2);

OPJ_BOOL opj_jp2_default_validation (	opj_jp2_t * jp2,
                                        opj_stream_private_t *cio,
                                        opj_event_mgr_t * p_manager );

/**
 * Finds the image execution function related to the given box id.
 *
 * @param	p_id	the id of the handler to fetch.
 *
 * @return	the given handler or NULL if it could not be found.
 */
static const opj_jp2_header_handler_t * opj_jp2_img_find_handler (OPJ_UINT32 p_id);

/**
 * Finds the execution function related to the given box id.
 *
 * @param	p_id	the id of the handler to fetch.
 *
 * @return	the given handler or NULL if it could not be found.
 */
static const opj_jp2_header_handler_t * opj_jp2_find_handler (OPJ_UINT32 p_id );

const opj_jp2_header_handler_t jp2_header [] =
{
	{JP2_JP,opj_jp2_read_jp},
	{JP2_FTYP,opj_jp2_read_ftyp},
	{JP2_JP2H,opj_jp2_read_jp2h}
};

const opj_jp2_header_handler_t jp2_img_header [] =
{
	{JP2_IHDR,opj_jp2_read_ihdr},
	{JP2_COLR,opj_jp2_read_colr},
	{JP2_BPCC,opj_jp2_read_bpcc},
	{JP2_PCLR,opj_jp2_read_pclr},
	{JP2_CMAP,opj_jp2_read_cmap},
	{JP2_CDEF,opj_jp2_read_cdef}

};

/**
 * Reads a box header. The box is the way data is packed inside a jpeg2000 file structure. Data is read from a character string
 *
 * @param	box						the box structure to fill.
 * @param	p_data					the character string to read data from.
 * @param	p_number_bytes_read		pointer to an int that will store the number of bytes read from the stream (shoul usually be 2).
 * @param	p_box_max_size			the maximum number of bytes in the box.
 * @param	p_manager         FIXME DOC
 *
 * @return	true if the box is reconized, false otherwise
*/
static OPJ_BOOL opj_jp2_read_boxhdr_char(   opj_jp2_box_t *box,
                                            OPJ_BYTE * p_data,
                                            OPJ_UINT32 * p_number_bytes_read,
                                            OPJ_UINT32 p_box_max_size,
                                            opj_event_mgr_t * p_manager );

/**
 * Sets up the validation ,i.e. adds the procedures to lauch to make sure the codec parameters
 * are valid. Developpers wanting to extend the library can add their own validation procedures.
 */
static void opj_jp2_setup_decoding_validation (opj_jp2_t *jp2);

/**
 * Sets up the procedures to do on reading header.
 * Developpers wanting to extend the library can add their own writing procedures.
 */
static void opj_jp2_setup_header_reading (opj_jp2_t *jp2);

/* ----------------------------------------------------------------------- */
 OPJ_BOOL opj_jp2_read_boxhdr(opj_jp2_box_t *box,
                              OPJ_UINT32 * p_number_bytes_read,
                              opj_stream_private_t *cio,
                              opj_event_mgr_t * p_manager )
{
	/* read header from file */
	OPJ_BYTE l_data_header [8];

	/* preconditions */
	assert(cio != 00);
	assert(box != 00);
	assert(p_number_bytes_read != 00);
	assert(p_manager != 00);

	*p_number_bytes_read = (OPJ_UINT32)opj_stream_read_data(cio,l_data_header,8,p_manager);
	if (*p_number_bytes_read != 8) {
		return OPJ_FALSE;
	}

	/* process read data */
	opj_read_bytes(l_data_header,&(box->length), 4);
	opj_read_bytes(l_data_header+4,&(box->type), 4);
    
  if(box->length == 0)/* last box */
    {
    const OPJ_OFF_T bleft = opj_stream_get_number_byte_left(cio);
    box->length = (OPJ_UINT32)bleft;
    assert( (OPJ_OFF_T)box->length == bleft );
    return OPJ_TRUE;
    }

	/* do we have a "special very large box ?" */
	/* read then the XLBox */
	if (box->length == 1) {
		OPJ_UINT32 l_xl_part_size;

		OPJ_UINT32 l_nb_bytes_read = (OPJ_UINT32)opj_stream_read_data(cio,l_data_header,8,p_manager);
		if (l_nb_bytes_read != 8) {
			if (l_nb_bytes_read > 0) {
				*p_number_bytes_read += l_nb_bytes_read;
			}

			return OPJ_FALSE;
		}

        *p_number_bytes_read = 16;
		opj_read_bytes(l_data_header,&l_xl_part_size, 4);
		if (l_xl_part_size != 0) {
			opj_event_msg(p_manager, EVT_ERROR, "Cannot handle box sizes higher than 2^32\n");
			return OPJ_FALSE;
		}
		opj_read_bytes(l_data_header+4,&(box->length), 4);
	}
    return OPJ_TRUE;
}

#if 0
static void jp2_write_url(opj_cio_t *cio, char *Idx_file) {
	OPJ_UINT32 i;
	opj_jp2_box_t box;

	box.init_pos = cio_tell(cio);
	cio_skip(cio, 4);
	cio_write(cio, JP2_URL, 4);	/* DBTL */
	cio_write(cio, 0, 1);		/* VERS */
	cio_write(cio, 0, 3);		/* FLAG */

	if(Idx_file) {
		for (i = 0; i < strlen(Idx_file); i++) {
			cio_write(cio, Idx_file[i], 1);
		}
	}

	box.length = cio_tell(cio) - box.init_pos;
	cio_seek(cio, box.init_pos);
	cio_write(cio, box.length, 4);	/* L */
	cio_seek(cio, box.init_pos + box.length);
}
#endif

OPJ_BOOL opj_jp2_read_ihdr( opj_jp2_t *jp2,
                            OPJ_BYTE *p_image_header_data,
                            OPJ_UINT32 p_image_header_size,
                            opj_event_mgr_t * p_manager )
{
	/* preconditions */
	assert(p_image_header_data != 00);
	assert(jp2 != 00);
	assert(p_manager != 00);

	if (p_image_header_size != 14) {
		opj_event_msg(p_manager, EVT_ERROR, "Bad image header box (bad size)\n");
		return OPJ_FALSE;
	}

	opj_read_bytes(p_image_header_data,&(jp2->h),4);			/* HEIGHT */
	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 */
	p_image_header_data += 2;

	/* allocate memory for components */
	jp2->comps = (opj_jp2_comps_t*) opj_malloc(jp2->numcomps * sizeof(opj_jp2_comps_t));
	if (jp2->comps == 0) {
		opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to handle image header (ihdr)\n");
		return OPJ_FALSE;
	}
	memset(jp2->comps,0,jp2->numcomps * sizeof(opj_jp2_comps_t));

	opj_read_bytes(p_image_header_data,&(jp2->bpc),1);			/* BPC */
	++ p_image_header_data;

	opj_read_bytes(p_image_header_data,&(jp2->C),1);			/* C */
	++ p_image_header_data;

	/* Should be equal to 7 cf. chapter about image header box of the norm */
	if (jp2->C != 7){
		opj_event_msg(p_manager, EVT_INFO, "JP2 IHDR box: compression type indicate that the file is not a conforming JP2 file (%d) \n", jp2->C);
	}

	opj_read_bytes(p_image_header_data,&(jp2->UnkC),1);			/* UnkC */
	++ p_image_header_data;
	opj_read_bytes(p_image_header_data,&(jp2->IPR),1);			/* IPR */
	++ p_image_header_data;

	return OPJ_TRUE;
}

OPJ_BYTE * opj_jp2_write_ihdr(opj_jp2_t *jp2,
                              OPJ_UINT32 * p_nb_bytes_written
                              )
{
	OPJ_BYTE * l_ihdr_data,* l_current_ihdr_ptr;
	
	/* preconditions */
	assert(jp2 != 00);
	assert(p_nb_bytes_written != 00);

	/* default image header is 22 bytes wide */
	l_ihdr_data = (OPJ_BYTE *) opj_malloc(22);
	if (l_ihdr_data == 00) {
		return 00;
	}
	memset(l_ihdr_data,0,22);

	l_current_ihdr_ptr = l_ihdr_data;
	
	opj_write_bytes(l_current_ihdr_ptr,22,4);				/* write box size */
	l_current_ihdr_ptr+=4;

	opj_write_bytes(l_current_ihdr_ptr,JP2_IHDR, 4);		/* IHDR */
	l_current_ihdr_ptr+=4;
	
	opj_write_bytes(l_current_ihdr_ptr,jp2->h, 4);		/* HEIGHT */
	l_current_ihdr_ptr+=4;
	
	opj_write_bytes(l_current_ihdr_ptr, jp2->w, 4);		/* WIDTH */
	l_current_ihdr_ptr+=4;
	
	opj_write_bytes(l_current_ihdr_ptr, jp2->numcomps, 2);		/* NC */
	l_current_ihdr_ptr+=2;
	
	opj_write_bytes(l_current_ihdr_ptr, jp2->bpc, 1);		/* BPC */
	++l_current_ihdr_ptr;
	
	opj_write_bytes(l_current_ihdr_ptr, jp2->C, 1);		/* C : Always 7 */
	++l_current_ihdr_ptr;
	
	opj_write_bytes(l_current_ihdr_ptr, jp2->UnkC, 1);		/* UnkC, colorspace unknown */
	++l_current_ihdr_ptr;
	
	opj_write_bytes(l_current_ihdr_ptr, jp2->IPR, 1);		/* IPR, no intellectual property */
	++l_current_ihdr_ptr;
	
	*p_nb_bytes_written = 22;
	
	return l_ihdr_data;
}

OPJ_BYTE * opj_jp2_write_bpcc(	opj_jp2_t *jp2,
						        OPJ_UINT32 * p_nb_bytes_written
                                )
{
	OPJ_UINT32 i;
	/* room for 8 bytes for box and 1 byte for each component */
	OPJ_UINT32 l_bpcc_size = 8 + jp2->numcomps;
	OPJ_BYTE * l_bpcc_data,* l_current_bpcc_ptr;
	
	/* preconditions */
	assert(jp2 != 00);
	assert(p_nb_bytes_written != 00);

	l_bpcc_data = (OPJ_BYTE *) opj_malloc(l_bpcc_size);
	if (l_bpcc_data == 00) {
		return 00;
	}
	memset(l_bpcc_data,0,l_bpcc_size);

	l_current_bpcc_ptr = l_bpcc_data;

	opj_write_bytes(l_current_bpcc_ptr,l_bpcc_size,4);				/* write box size */
	l_current_bpcc_ptr += 4;
	
	opj_write_bytes(l_current_bpcc_ptr,JP2_BPCC,4);					/* BPCC */
	l_current_bpcc_ptr += 4;

	for (i = 0; i < jp2->numcomps; ++i)  {
		opj_write_bytes(l_current_bpcc_ptr, jp2->comps[i].bpcc, 1); /* write each component information */
		++l_current_bpcc_ptr;
	}

	*p_nb_bytes_written = l_bpcc_size;
	
	return l_bpcc_data;
}

OPJ_BOOL opj_jp2_read_bpcc( opj_jp2_t *jp2,
                            OPJ_BYTE * p_bpc_header_data,
                            OPJ_UINT32 p_bpc_header_size,
                            opj_event_mgr_t * p_manager
                            )
{
	OPJ_UINT32 i;

	/* preconditions */
	assert(p_bpc_header_data != 00);
	assert(jp2 != 00);
	assert(p_manager != 00);

	
	if (jp2->bpc != 255 ){
		opj_event_msg(p_manager, EVT_WARNING, "A BPCC header box is available although BPC given by the IHDR box (%d) indicate components bit depth is constant\n",jp2->bpc);
	}

	/* and length is relevant */
	if (p_bpc_header_size != jp2->numcomps) {
		opj_event_msg(p_manager, EVT_ERROR, "Bad BPCC header box (bad size)\n");
		return OPJ_FALSE;
	}

	/* read info for each component */
	for (i = 0; i < jp2->numcomps; ++i) {
		opj_read_bytes(p_bpc_header_data,&jp2->comps[i].bpcc ,1);	/* read each BPCC component */
		++p_bpc_header_data;
	}

	return OPJ_TRUE;
}

OPJ_BYTE * opj_jp2_write_colr(  opj_jp2_t *jp2,
							    OPJ_UINT32 * p_nb_bytes_written
                                )
{
	/* room for 8 bytes for box 3 for common data and variable upon profile*/
	OPJ_UINT32 l_colr_size = 11;
	OPJ_BYTE * l_colr_data,* l_current_colr_ptr;
	
	/* preconditions */
	assert(jp2 != 00);
	assert(p_nb_bytes_written != 00);
    assert(jp2->meth == 1 || jp2->meth == 2);

	switch (jp2->meth) { 
		case 1 :
			l_colr_size += 4; /* EnumCS */
			break;
		case 2 :
            assert(jp2->color.icc_profile_len);	/* ICC profile */
            l_colr_size += jp2->color.icc_profile_len;
			break;
		default :
			return 00;
	}

	l_colr_data = (OPJ_BYTE *) opj_malloc(l_colr_size);
	if (l_colr_data == 00) {
		return 00;
	}
	memset(l_colr_data,0,l_colr_size);
	
	l_current_colr_ptr = l_colr_data;

	opj_write_bytes(l_current_colr_ptr,l_colr_size,4);				/* write box size */
	l_current_colr_ptr += 4;
	
	opj_write_bytes(l_current_colr_ptr,JP2_COLR,4);					/* BPCC */
	l_current_colr_ptr += 4;
	
	opj_write_bytes(l_current_colr_ptr, jp2->meth,1);				/* METH */
	++l_current_colr_ptr;
	
	opj_write_bytes(l_current_colr_ptr, jp2->precedence,1);			/* PRECEDENCE */
	++l_current_colr_ptr;
	
	opj_write_bytes(l_current_colr_ptr, jp2->approx,1);				/* APPROX */
	++l_current_colr_ptr;
	
	if (jp2->meth == 1) { /* Meth value is restricted to 1 or 2 (Table I.9 of part 1) */
        opj_write_bytes(l_current_colr_ptr, jp2->enumcs,4); }       /* EnumCS */
    else {
        if (jp2->meth == 2) {                                      /* ICC profile */
            OPJ_UINT32 i;
            for(i = 0; i < jp2->color.icc_profile_len; ++i) {
                opj_write_bytes(l_current_colr_ptr, jp2->color.icc_profile_buf[i], 1);
                ++l_current_colr_ptr;
            }
        }
	}

	*p_nb_bytes_written = l_colr_size;
	
	return l_colr_data;
}

void opj_jp2_free_pclr(opj_jp2_color_t *color)
{
    opj_free(color->jp2_pclr->channel_sign);
    opj_free(color->jp2_pclr->channel_size);
    opj_free(color->jp2_pclr->entries);

	if(color->jp2_pclr->cmap) opj_free(color->jp2_pclr->cmap);

    opj_free(color->jp2_pclr); color->jp2_pclr = NULL;
}

static OPJ_BOOL opj_jp2_check_color(opj_image_t *image, opj_jp2_color_t *color, opj_event_mgr_t *p_manager)
{
	OPJ_UINT16 i;

	/* testcase 4149.pdf.SIGSEGV.cf7.3501 */
	if (color->jp2_cdef) {
		opj_jp2_cdef_info_t *info = color->jp2_cdef->info;
		OPJ_UINT16 n = color->jp2_cdef->n;

		for (i = 0; i < n; i++) {
			if (info[i].cn >= image->numcomps) {
				opj_event_msg(p_manager, EVT_ERROR, "Invalid component index %d (>= %d).\n", info[i].cn, image->numcomps);
				return OPJ_FALSE;
			}
			if (info[i].asoc > 0 && (OPJ_UINT32)(info[i].asoc - 1) >= image->numcomps) {
				opj_event_msg(p_manager, EVT_ERROR, "Invalid component index %d (>= %d).\n", info[i].asoc - 1, image->numcomps);
				return OPJ_FALSE;
			}
		}
	}

	/* testcases 451.pdf.SIGSEGV.f4c.3723, 451.pdf.SIGSEGV.5b5.3723 and
	   66ea31acbb0f23a2bbc91f64d69a03f5_signal_sigsegv_13937c0_7030_5725.pdf */
	if (color->jp2_pclr && color->jp2_pclr->cmap) {
		OPJ_UINT16 nr_channels = color->jp2_pclr->nr_channels;
		opj_jp2_cmap_comp_t *cmap = color->jp2_pclr->cmap;
		OPJ_BOOL *pcol_usage, is_sane = OPJ_TRUE;

		/* verify that all original components match an existing one */
		for (i = 0; i < nr_channels; i++) {
			if (cmap[i].cmp >= image->numcomps) {
				opj_event_msg(p_manager, EVT_ERROR, "Invalid component index %d (>= %d).\n", cmap[i].cmp, image->numcomps);
				is_sane = OPJ_FALSE;
			}
		}

		pcol_usage = opj_calloc(nr_channels, sizeof(OPJ_BOOL));
		if (!pcol_usage) {
			opj_event_msg(p_manager, EVT_ERROR, "Unexpected OOM.\n");
			return OPJ_FALSE;
		}
		/* verify that no component is targeted more than once */
		for (i = 0; i < nr_channels; i++) {
      OPJ_UINT16 pcol = cmap[i].pcol;
      assert(cmap[i].mtyp == 0 || cmap[i].mtyp == 1);
			if (pcol >= nr_channels) {
				opj_event_msg(p_manager, EVT_ERROR, "Invalid component/palette index for direct mapping %d.\n", pcol);
				is_sane = OPJ_FALSE;
			}
			else if (pcol_usage[pcol] && cmap[i].mtyp == 1) {
				opj_event_msg(p_manager, EVT_ERROR, "Component %d is mapped twice.\n", pcol);
				is_sane = OPJ_FALSE;
			}
      else if (cmap[i].mtyp == 0 && cmap[i].pcol != 0) {
        /* I.5.3.5 PCOL: If the value of the MTYP field for this channel is 0, then
         * the value of this field shall be 0. */
				opj_event_msg(p_manager, EVT_ERROR, "Direct use at #%d however pcol=%d.\n", i, pcol);
				is_sane = OPJ_FALSE;
      }
			else
				pcol_usage[pcol] = OPJ_TRUE;
		}
		/* verify that all components are targeted at least once */
		for (i = 0; i < nr_channels; i++) {
			if (!pcol_usage[i] && cmap[i].mtyp != 0) {
				opj_event_msg(p_manager, EVT_ERROR, "Component %d doesn't have a mapping.\n", i);
				is_sane = OPJ_FALSE;
			}
		}
		opj_free(pcol_usage);
		if (!is_sane) {
			return OPJ_FALSE;
		}
	}

	return OPJ_TRUE;
}

/* file9.jp2 */
void opj_jp2_apply_pclr(opj_image_t *image, opj_jp2_color_t *color)
{
	opj_image_comp_t *old_comps, *new_comps;
	OPJ_BYTE *channel_size, *channel_sign;
	OPJ_UINT32 *entries;
	opj_jp2_cmap_comp_t *cmap;
	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;
	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*)
			opj_malloc(nr_channels * sizeof(opj_image_comp_t));

	for(i = 0; i < nr_channels; ++i) {
		pcol = cmap[i].pcol; cmp = cmap[i].cmp;

		/* Direct use */
    if(cmap[i].mtyp == 0){
      assert( pcol == 0 );
      new_comps[i] = old_comps[cmp];
    } else {
      assert( i == pcol );
      new_comps[pcol] = old_comps[cmp];
    }

		/* Palette mapping: */
		new_comps[i].data = (OPJ_INT32*)
				opj_malloc(old_comps[cmp].w * old_comps[cmp].h * sizeof(OPJ_INT32));
		new_comps[i].prec = channel_size[i];
		new_comps[i].sgnd = channel_sign[i];
	}

	top_k = color->jp2_pclr->nr_entries - 1;

	for(i = 0; i < nr_channels; ++i) {
		/* Palette mapping: */
		cmp = cmap[i].cmp; pcol = cmap[i].pcol;
		src = old_comps[cmp].data;
    assert( src );
		max = new_comps[pcol].w * new_comps[pcol].h;

		/* Direct use: */
    if(cmap[i].mtyp == 0) {
      assert( cmp == 0 );
      dst = new_comps[i].data;
      assert( dst );
      for(j = 0; j < max; ++j) {
        dst[j] = src[j];
      }
    }
    else {
      assert( i == pcol );
      dst = new_comps[pcol].data;
      assert( dst );
      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] = (OPJ_INT32)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);
	}

	opj_free(old_comps);
	image->comps = new_comps;
	image->numcomps = nr_channels;

	opj_jp2_free_pclr(color);

}/* apply_pclr() */

OPJ_BOOL opj_jp2_read_pclr(	opj_jp2_t *jp2,
                            OPJ_BYTE * p_pclr_header_data,
                            OPJ_UINT32 p_pclr_header_size,
                            opj_event_mgr_t * p_manager
                            )
{
	opj_jp2_pclr_t *jp2_pclr;
	OPJ_BYTE *channel_size, *channel_sign;
	OPJ_UINT32 *entries;
	OPJ_UINT16 nr_entries,nr_channels;
	OPJ_UINT16 i, j;
	OPJ_UINT32 l_value;
	OPJ_BYTE *orig_header_data = p_pclr_header_data;

	/* preconditions */
	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;

	if (p_pclr_header_size < 3)
		return OPJ_FALSE;

	opj_read_bytes(p_pclr_header_data, &l_value , 2);	/* NE */
	p_pclr_header_data += 2;
	nr_entries = (OPJ_UINT16) l_value;

	opj_read_bytes(p_pclr_header_data, &l_value , 1);	/* NPC */
	++p_pclr_header_data;
	nr_channels = (OPJ_UINT16) l_value;

	if (p_pclr_header_size < 3 + (OPJ_UINT32)nr_channels || nr_channels == 0 || nr_entries >= (OPJ_UINT32)-1 / nr_channels)
		return OPJ_FALSE;

	entries = (OPJ_UINT32*) opj_malloc((size_t)nr_channels * nr_entries * sizeof(OPJ_UINT32));
    if (!entries)
        return OPJ_FALSE;
	channel_size = (OPJ_BYTE*) opj_malloc(nr_channels);
    if (!channel_size)
    {
        opj_free(entries);
        return OPJ_FALSE;
    }
	channel_sign = (OPJ_BYTE*) opj_malloc(nr_channels);
	if (!channel_sign)
	{
        opj_free(entries);
        opj_free(channel_size);
        return OPJ_FALSE;
	}

	jp2_pclr = (opj_jp2_pclr_t*)opj_malloc(sizeof(opj_jp2_pclr_t));
    if (!jp2_pclr)
    {
        opj_free(entries);
        opj_free(channel_size);
        opj_free(channel_sign);
        return OPJ_FALSE;
    }

	jp2_pclr->channel_sign = channel_sign;
	jp2_pclr->channel_size = channel_size;
	jp2_pclr->entries = entries;
	jp2_pclr->nr_entries = nr_entries;
	jp2_pclr->nr_channels = (OPJ_BYTE) l_value;
	jp2_pclr->cmap = NULL;

	jp2->color.jp2_pclr = jp2_pclr;

	for(i = 0; i < nr_channels; ++i) {
		opj_read_bytes(p_pclr_header_data, &l_value , 1);	/* Bi */
		++p_pclr_header_data;

		channel_size[i] = (OPJ_BYTE)((l_value & 0x7f) + 1);
		channel_sign[i] = (l_value & 0x80) ? 1 : 0;
	}

	for(j = 0; j < nr_entries; ++j) {
		for(i = 0; i < nr_channels; ++i) {
			OPJ_UINT32 bytes_to_read = (OPJ_UINT32)((channel_size[i]+7)>>3);

			if (bytes_to_read > sizeof(OPJ_UINT32))
				bytes_to_read = sizeof(OPJ_UINT32);
			if ((ptrdiff_t)p_pclr_header_size < p_pclr_header_data - orig_header_data + (ptrdiff_t)bytes_to_read)
				return OPJ_FALSE;

			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++;
		}
	}

	return OPJ_TRUE;
}

OPJ_BOOL opj_jp2_read_cmap(	opj_jp2_t * jp2,
                            OPJ_BYTE * p_cmap_header_data,
                            OPJ_UINT32 p_cmap_header_size,
                            opj_event_mgr_t * p_manager
                            )
{
	opj_jp2_cmap_comp_t *cmap;
	OPJ_BYTE i, nr_channels;
	OPJ_UINT32 l_value;

	/* preconditions */
	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) {
		opj_event_msg(p_manager, EVT_ERROR, "Need to read a PCLR box before the CMAP box.\n");
		return OPJ_FALSE;
	}

	/* Part 1, I.5.3.5: 'There shall be at most one Component Mapping box
	 * inside a JP2 Header box' :
	*/
	if(jp2->color.jp2_pclr->cmap) {
		opj_event_msg(p_manager, EVT_ERROR, "Only one CMAP box is allowed.\n");
		return OPJ_FALSE;
	}

	nr_channels = jp2->color.jp2_pclr->nr_channels;
	if (p_cmap_header_size < (OPJ_UINT32)nr_channels * 4) {
		opj_event_msg(p_manager, EVT_ERROR, "Insufficient data for CMAP box.\n");
		return OPJ_FALSE;
	}

	cmap = (opj_jp2_cmap_comp_t*) opj_malloc(nr_channels * sizeof(opj_jp2_cmap_comp_t));
    if (!cmap)
        return OPJ_FALSE;


	for(i = 0; i < nr_channels; ++i) {
		opj_read_bytes(p_cmap_header_data, &l_value, 2);			/* CMP^i */
		p_cmap_header_data +=2;
		cmap[i].cmp = (OPJ_UINT16) l_value;

		opj_read_bytes(p_cmap_header_data, &l_value, 1);			/* MTYP^i */
		++p_cmap_header_data;
		cmap[i].mtyp = (OPJ_BYTE) l_value;

		opj_read_bytes(p_cmap_header_data, &l_value, 1);			/* PCOL^i */
		++p_cmap_header_data;
		cmap[i].pcol = (OPJ_BYTE) l_value;
	}

	jp2->color.jp2_pclr->cmap = cmap;

	return OPJ_TRUE;
}

void opj_jp2_apply_cdef(opj_image_t *image, opj_jp2_color_t *color)
{
	opj_jp2_cdef_info_t *info;
	OPJ_UINT16 i, n, cn, asoc, acn;

	info = color->jp2_cdef->info;
	n = color->jp2_cdef->n;

  for(i = 0; i < n; ++i)
    {
    /* WATCH: acn = asoc - 1 ! */
    asoc = info[i].asoc;
    if(asoc == 0 || asoc == 65535)
      {
      if (i < image->numcomps)
        image->comps[i].alpha = info[i].typ;
      continue;
      }

    cn = info[i].cn; 
    acn = (OPJ_UINT16)(asoc - 1);
    if( cn >= image->numcomps || acn >= image->numcomps )
      {
      fprintf(stderr, "cn=%d, acn=%d, numcomps=%d\n", cn, acn, image->numcomps);
      continue;
      }

		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));

			info[i].asoc = (OPJ_UINT16)(cn + 1);
			info[acn].asoc = (OPJ_UINT16)(info[acn].cn + 1);
		}

		image->comps[cn].alpha = info[i].typ;
	}

	if(color->jp2_cdef->info) opj_free(color->jp2_cdef->info);

	opj_free(color->jp2_cdef); color->jp2_cdef = NULL;

}/* jp2_apply_cdef() */

OPJ_BOOL opj_jp2_read_cdef(	opj_jp2_t * jp2,
                            OPJ_BYTE * p_cdef_header_data,
							OPJ_UINT32 p_cdef_header_size,
							opj_event_mgr_t * p_manager
                            )
{
	opj_jp2_cdef_info_t *cdef_info;
	OPJ_UINT16 i;
	OPJ_UINT32 l_value;

	/* preconditions */
	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.'*/
	if(jp2->color.jp2_cdef) return OPJ_FALSE;

	if (p_cdef_header_size < 2) {
		opj_event_msg(p_manager, EVT_ERROR, "Insufficient data for CDEF box.\n");
		return OPJ_FALSE;
	}

	opj_read_bytes(p_cdef_header_data,&l_value ,2);			/* N */
	p_cdef_header_data+= 2;

	if ( (OPJ_UINT16)l_value == 0){ /* szukw000: FIXME */
		opj_event_msg(p_manager, EVT_ERROR, "Number of channel description is equal to zero in CDEF box.\n");
		return OPJ_FALSE;
	}

	if (p_cdef_header_size < 2 + (OPJ_UINT32)(OPJ_UINT16)l_value * 6) {
		opj_event_msg(p_manager, EVT_ERROR, "Insufficient data for CDEF box.\n");
		return OPJ_FALSE;
	}

	cdef_info = (opj_jp2_cdef_info_t*) opj_malloc(l_value * sizeof(opj_jp2_cdef_info_t));
    if (!cdef_info)
        return OPJ_FALSE;

	jp2->color.jp2_cdef = (opj_jp2_cdef_t*)opj_malloc(sizeof(opj_jp2_cdef_t));
    if(!jp2->color.jp2_cdef)
    {
        opj_free(cdef_info);
        return OPJ_FALSE;
    }
	jp2->color.jp2_cdef->info = cdef_info;
	jp2->color.jp2_cdef->n = (OPJ_UINT16) l_value;

	for(i = 0; i < jp2->color.jp2_cdef->n; ++i) {
		opj_read_bytes(p_cdef_header_data, &l_value, 2);			/* Cn^i */
		p_cdef_header_data +=2;
		cdef_info[i].cn = (OPJ_UINT16) l_value;

		opj_read_bytes(p_cdef_header_data, &l_value, 2);			/* Typ^i */
		p_cdef_header_data +=2;
		cdef_info[i].typ = (OPJ_UINT16) l_value;

		opj_read_bytes(p_cdef_header_data, &l_value, 2);			/* Asoc^i */
		p_cdef_header_data +=2;
		cdef_info[i].asoc = (OPJ_UINT16) l_value;
   }

	return OPJ_TRUE;
}

OPJ_BOOL opj_jp2_read_colr( opj_jp2_t *jp2,
                            OPJ_BYTE * p_colr_header_data,
                            OPJ_UINT32 p_colr_header_size,
                            opj_event_mgr_t * p_manager
                            )
{
	OPJ_UINT32 l_value;

	/* preconditions */
	assert(jp2 != 00);
	assert(p_colr_header_data != 00);
	assert(p_manager != 00);

	if (p_colr_header_size < 3) {
		opj_event_msg(p_manager, EVT_ERROR, "Bad COLR header box (bad size)\n");
		return OPJ_FALSE;
	}

	/* Part 1, I.5.3.3 : 'A conforming JP2 reader shall ignore all Colour
	 * Specification boxes after the first.'
	*/
	if(jp2->color.jp2_has_colr) {
		opj_event_msg(p_manager, EVT_INFO, "A conforming JP2 reader shall ignore all Colour Specification boxes after the first, so we ignore this one.\n");
		p_colr_header_data += p_colr_header_size;
		return OPJ_TRUE;
	}

	opj_read_bytes(p_colr_header_data,&jp2->meth ,1);			/* METH */
	++p_colr_header_data;

	opj_read_bytes(p_colr_header_data,&jp2->precedence ,1);		/* PRECEDENCE */
	++p_colr_header_data;

	opj_read_bytes(p_colr_header_data,&jp2->approx ,1);			/* APPROX */
	++p_colr_header_data;

	if (jp2->meth == 1) {
		if (p_colr_header_size > 7) {
			/* testcase Altona_Technical_v20_x4.pdf */
			opj_event_msg(p_manager, EVT_WARNING, "Bad COLR header box (bad size: %d)\n", p_colr_header_size);
		}

		opj_read_bytes(p_colr_header_data,&jp2->enumcs ,4);			/* EnumCS */
        
		p_colr_header_data += 4;

		if(jp2->enumcs == 14)/* CIELab */
		{
			OPJ_UINT32 *cielab;
			OPJ_UINT32 rl, ol, ra, oa, rb, ob, il;

			cielab = (OPJ_UINT32*)opj_malloc(9 * sizeof(OPJ_UINT32));
			cielab[0] = 14; /* enumcs */

			if(p_colr_header_size == 7)/* default values */
			{
				rl = ra = rb = ol = oa = ob = 0;
				il = 0x00443530; /* D50 */
				cielab[1] = 0x44454600;/* DEF */
			}
			else if(p_colr_header_size == 35)
			{
				opj_read_bytes(p_colr_header_data, &rl, 4);
				p_colr_header_data += 4;
				opj_read_bytes(p_colr_header_data, &ol, 4);
				p_colr_header_data += 4;
				opj_read_bytes(p_colr_header_data, &ra, 4);
				p_colr_header_data += 4;
				opj_read_bytes(p_colr_header_data, &oa, 4);
				p_colr_header_data += 4;
				opj_read_bytes(p_colr_header_data, &rb, 4);
				p_colr_header_data += 4;
				opj_read_bytes(p_colr_header_data, &ob, 4);
				p_colr_header_data += 4;
				opj_read_bytes(p_colr_header_data, &il, 4);
				p_colr_header_data += 4;
				cielab[1] = 0;
			}
			cielab[2] = rl; cielab[4] = ra; cielab[6] = rb;
			cielab[3] = ol; cielab[5] = oa; cielab[7] = ob;
			cielab[8] = il;

			jp2->color.icc_profile_buf = (unsigned char*)cielab;
			jp2->color.icc_profile_len = 0;
		}

        jp2->color.jp2_has_colr = 1;
	}
	else if (jp2->meth == 2) {
		/* ICC profile */
		OPJ_INT32 it_icc_value = 0;
		OPJ_INT32 icc_len = (OPJ_INT32)p_colr_header_size - 3;

		jp2->color.icc_profile_len = (OPJ_UINT32)icc_len;
		jp2->color.icc_profile_buf = (OPJ_BYTE*) opj_malloc((size_t)icc_len);
        if (!jp2->color.icc_profile_buf)
        {
            jp2->color.icc_profile_len = 0;
            return OPJ_FALSE;
        }
		memset(jp2->color.icc_profile_buf, 0, (size_t)icc_len * sizeof(OPJ_BYTE));

		for (it_icc_value = 0; it_icc_value < icc_len; ++it_icc_value)
		{
			opj_read_bytes(p_colr_header_data,&l_value,1);		/* icc values */
			++p_colr_header_data;
			jp2->color.icc_profile_buf[it_icc_value] = (OPJ_BYTE) l_value;
		}
	    
        jp2->color.jp2_has_colr = 1;
	}
	else if (jp2->meth > 2)
    {
        /*	ISO/IEC 15444-1:2004 (E), Table I.9 ?Legal METH values:
        conforming JP2 reader shall ignore the entire Colour Specification box.*/
        opj_event_msg(p_manager, EVT_INFO, "COLR BOX meth value is not a regular value (%d), " 
            "so we will ignore the entire Colour Specification box. \n", jp2->meth);
    }
    return OPJ_TRUE;
}

OPJ_BOOL opj_jp2_decode(opj_jp2_t *jp2,
                        opj_stream_private_t *p_stream,
                        opj_image_t* p_image,
                        opj_event_mgr_t * p_manager)
{
	if (!p_image)
		return OPJ_FALSE;

	/* J2K decoding */
	if( ! opj_j2k_decode(jp2->j2k, p_stream, p_image, p_manager) ) {
		opj_event_msg(p_manager, EVT_ERROR, "Failed to decode the codestream in the JP2 file\n");
		return OPJ_FALSE;
	}

    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
		    p_image->color_space = OPJ_CLRSPC_UNKNOWN;

	    /* Apply the color space if needed */
	    if(jp2->color.jp2_cdef) {
		    opj_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)
			    opj_jp2_free_pclr(&(jp2->color));
		    else
				if(!p_image->useColorSpace)
			    opj_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;
}

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 [3];
	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;
	}
	
	/* 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;
}

OPJ_BOOL opj_jp2_write_ftyp(opj_jp2_t *jp2,
							opj_stream_private_t *cio,
							opj_event_mgr_t * p_manager )
{
	OPJ_UINT32 i;
	OPJ_UINT32 l_ftyp_size = 16 + 4 * jp2->numcl;
	OPJ_BYTE * l_ftyp_data, * l_current_data_ptr;
	OPJ_BOOL l_result;

	/* preconditions */
	assert(cio != 00);
	assert(jp2 != 00);
	assert(p_manager != 00);

	l_ftyp_data = (OPJ_BYTE *) opj_malloc(l_ftyp_size);
	
	if (l_ftyp_data == 00) {
		opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to handle ftyp data\n");
		return OPJ_FALSE;
	}

	memset(l_ftyp_data,0,l_ftyp_size);

	l_current_data_ptr = l_ftyp_data;

	opj_write_bytes(l_current_data_ptr, l_ftyp_size,4); /* box size */
	l_current_data_ptr += 4;

	opj_write_bytes(l_current_data_ptr, JP2_FTYP,4); /* FTYP */
	l_current_data_ptr += 4;

	opj_write_bytes(l_current_data_ptr, jp2->brand,4); /* BR */
	l_current_data_ptr += 4;

	opj_write_bytes(l_current_data_ptr, jp2->minversion,4); /* MinV */
	l_current_data_ptr += 4;

	for (i = 0; i < jp2->numcl; i++)  {
		opj_write_bytes(l_current_data_ptr, jp2->cl[i],4);	/* CL */
	}
	
	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 writing ftyp data to stream\n");
	}

	opj_free(l_ftyp_data);
	
	return l_result;
}

OPJ_BOOL opj_jp2_write_jp2c(opj_jp2_t *jp2,
							opj_stream_private_t *cio,
							opj_event_mgr_t * p_manager )
{
	OPJ_OFF_T j2k_codestream_exit;
	OPJ_BYTE 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,
                    (OPJ_UINT32) (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(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(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(p_manager, EVT_ERROR, "Failed to seek in the stream.\n");
		return OPJ_FALSE;
	}

	return OPJ_TRUE;
}

OPJ_BOOL opj_jp2_write_jp(	opj_jp2_t *jp2,
			    		    opj_stream_private_t *cio,
				    		opj_event_mgr_t * p_manager )
{
	/* 12 bytes will be read */
	OPJ_BYTE l_signature_data [12];

	/* preconditions */
	assert(cio != 00);
	assert(jp2 != 00);
	assert(p_manager != 00);

	/* write box length */
	opj_write_bytes(l_signature_data,12,4);
	/* writes box type */
	opj_write_bytes(l_signature_data+4,JP2_JP,4);
	/* writes magic number*/
	opj_write_bytes(l_signature_data+8,0x0d0a870a,4);
	
	if (opj_stream_write_data(cio,l_signature_data,12,p_manager) != 12) {
		return OPJ_FALSE;
	}

	return OPJ_TRUE;
}

/* ----------------------------------------------------------------------- */
/* JP2 decoder interface                                             */
/* ----------------------------------------------------------------------- */

void opj_jp2_setup_decoder(opj_jp2_t *jp2, opj_dparameters_t *parameters)
{
	/* setup the J2K codec */
	opj_j2k_setup_decoder(jp2->j2k, parameters);

	/* further JP2 initializations go here */
	jp2->color.jp2_has_colr = 0;
    jp2->ignore_pclr_cmap_cdef = parameters->flags & OPJ_DPARAMETERS_IGNORE_PCLR_CMAP_CDEF_FLAG;
}

/* ----------------------------------------------------------------------- */
/* JP2 encoder interface                                             */
/* ----------------------------------------------------------------------- */

void opj_jp2_setup_encoder(	opj_jp2_t *jp2,
                            opj_cparameters_t *parameters,
                            opj_image_t *image,
                            opj_event_mgr_t * p_manager)
{
    OPJ_UINT32 i;
	OPJ_UINT32 depth_0;
  OPJ_UINT32 sign;

	if(!jp2 || !parameters || !image)
		return;

	/* setup the J2K codec */
	/* ------------------- */

	/* Check if number of components respects standard */
	if (image->numcomps < 1 || image->numcomps > 16384) {
		opj_event_msg(p_manager, EVT_ERROR, "Invalid number of components specified while setting up JP2 encoder\n");
		return;
	}

	opj_j2k_setup_encoder(jp2->j2k, parameters, image, p_manager );

	/* setup the JP2 codec */
	/* ------------------- */
	
	/* Profile box */

	jp2->brand = JP2_JP2;	/* BR */
	jp2->minversion = 0;	/* MinV */
	jp2->numcl = 1;
	jp2->cl = (OPJ_UINT32*) opj_malloc(jp2->numcl * sizeof(OPJ_UINT32));
    if (!jp2->cl){
        jp2->cl = NULL;
        opj_event_msg(p_manager, EVT_ERROR, "Not enough memory when setup the JP2 encoder\n");
        return;
    }
	jp2->cl[0] = JP2_JP2;	/* CL0 : JP2 */

	/* Image Header box */

	jp2->numcomps = image->numcomps;	/* NC */
	jp2->comps = (opj_jp2_comps_t*) opj_malloc(jp2->numcomps * sizeof(opj_jp2_comps_t));
    if (!jp2->comps) {
        jp2->comps = NULL;
        opj_event_msg(p_manager, EVT_ERROR, "Not enough memory when setup the JP2 encoder\n");
        return;
    }

	jp2->h = image->y1 - image->y0;		/* HEIGHT */
	jp2->w = image->x1 - image->x0;		/* WIDTH */
	/* BPC */
	depth_0 = image->comps[0].prec - 1;
	sign = image->comps[0].sgnd;
	jp2->bpc = depth_0 + (sign << 7);
	for (i = 1; i < image->numcomps; i++) {
		OPJ_UINT32 depth = image->comps[i].prec - 1;
		sign = image->comps[i].sgnd;
		if (depth_0 != depth)
			jp2->bpc = 255;
	}
	jp2->C = 7;			/* C : Always 7 */
	jp2->UnkC = 0;		/* UnkC, colorspace specified in colr box */
	jp2->IPR = 0;		/* IPR, no intellectual property */
	
	/* BitsPerComponent box */
	for (i = 0; i < image->numcomps; i++) {
		jp2->comps[i].bpcc = image->comps[i].prec - 1 + (image->comps[i].sgnd << 7);
	}

	/* Colour Specification box */
    if(image->icc_profile_len) {
        jp2->meth = 2;
        jp2->enumcs = 0;
    } 
    else {
        jp2->meth = 1;
        if (image->color_space == 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)
            jp2->enumcs = 18;	/* YUV */
    }


	jp2->precedence = 0;	/* PRECEDENCE */
	jp2->approx = 0;		/* APPROX */

	jp2->jpip_on = parameters->jpip_on;
}

OPJ_BOOL opj_jp2_encode(opj_jp2_t *jp2,
						opj_stream_private_t *stream,
						opj_event_mgr_t * p_manager)
{
	return opj_j2k_encode(jp2->j2k, stream, p_manager);
}

OPJ_BOOL opj_jp2_end_decompress(opj_jp2_t *jp2,
                                opj_stream_private_t *cio,
                                opj_event_mgr_t * p_manager
                                )
{
	/* preconditions */
	assert(jp2 != 00);
	assert(cio != 00);
	assert(p_manager != 00);

	/* customization of the end encoding */
	opj_jp2_setup_end_header_reading(jp2);

	/* write header */
	if (! opj_jp2_exec (jp2,jp2->m_procedure_list,cio,p_manager)) {
		return OPJ_FALSE;
	}

	return opj_j2k_end_decompress(jp2->j2k, cio, p_manager);
}

OPJ_BOOL opj_jp2_end_compress(	opj_jp2_t *jp2,
							    opj_stream_private_t *cio,
							    opj_event_mgr_t * p_manager
                                )
{
	/* preconditions */
	assert(jp2 != 00);
	assert(cio != 00);
	assert(p_manager != 00);

	/* customization of the end encoding */
	opj_jp2_setup_end_header_writing(jp2);

	if (! opj_j2k_end_compress(jp2->j2k,cio,p_manager)) {
		return OPJ_FALSE;
	}

	/* write header */
	return opj_jp2_exec(jp2,jp2->m_procedure_list,cio,p_manager);
}

void opj_jp2_setup_end_header_writing (opj_jp2_t *jp2)
{
	/* preconditions */
	assert(jp2 != 00);

#ifdef USE_JPIP
  if( jp2->jpip_on )
    opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)opj_jpip_write_iptr );
#endif
	opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)opj_jp2_write_jp2c );
	/* DEVELOPER CORNER, add your custom procedures */
#ifdef USE_JPIP
  if( jp2->jpip_on )
    {
    opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)opj_jpip_write_cidx );
    opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)opj_jpip_write_fidx );
    }
#endif
}

void opj_jp2_setup_end_header_reading (opj_jp2_t *jp2)
{
	/* preconditions */
	assert(jp2 != 00);
	opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)opj_jp2_read_header_procedure );
	/* DEVELOPER CORNER, add your custom procedures */
}

OPJ_BOOL opj_jp2_default_validation (	opj_jp2_t * jp2,
                                        opj_stream_private_t *cio,
                                        opj_event_mgr_t * p_manager
                                        )
{
	OPJ_BOOL l_is_valid = OPJ_TRUE;
	OPJ_UINT32 i;

	/* preconditions */
	assert(jp2 != 00);
	assert(cio != 00);
	assert(p_manager != 00);

	/* JPEG2000 codec validation */

	/* STATE checking */
	/* make sure the state is at 0 */
	l_is_valid &= (jp2->jp2_state == JP2_STATE_NONE);

	/* make sure not reading a jp2h ???? WEIRD */
	l_is_valid &= (jp2->jp2_img_state == JP2_IMG_STATE_NONE);

	/* POINTER validation */
	/* make sure a j2k codec is present */
	l_is_valid &= (jp2->j2k != 00);

	/* make sure a procedure list is present */
	l_is_valid &= (jp2->m_procedure_list != 00);

	/* make sure a validation list is present */
	l_is_valid &= (jp2->m_validation_list != 00);

	/* PARAMETER VALIDATION */
	/* number of components */
	l_is_valid &= (jp2->numcl > 0);
	/* width */
	l_is_valid &= (jp2->h > 0);
	/* height */
	l_is_valid &= (jp2->w > 0);
	/* precision */
	for (i = 0; i < jp2->numcomps; ++i)	{
		l_is_valid &= (jp2->comps[i].bpcc > 0);
	}

	/* METH */
	l_is_valid &= ((jp2->meth > 0) && (jp2->meth < 3));

	/* stream validation */
	/* back and forth is needed */
	l_is_valid &= opj_stream_has_seek(cio);

	return l_is_valid;
}

OPJ_BOOL opj_jp2_read_header_procedure(  opj_jp2_t *jp2,
                                                opj_stream_private_t *stream,
                                                opj_event_mgr_t * p_manager
                                                )
{
	opj_jp2_box_t box;
	OPJ_UINT32 l_nb_bytes_read;
	const opj_jp2_header_handler_t * l_current_handler;
	OPJ_UINT32 l_last_data_size = OPJ_BOX_SIZE;
	OPJ_UINT32 l_current_data_size;
	OPJ_BYTE * l_current_data = 00;

	/* preconditions */
	assert(stream != 00);
	assert(jp2 != 00);
	assert(p_manager != 00);

	l_current_data = (OPJ_BYTE*)opj_malloc(l_last_data_size);

	if (l_current_data == 00) {
		opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to handle jpeg2000 file header\n");
		return OPJ_FALSE;
	}
	memset(l_current_data, 0 , l_last_data_size);

	while (opj_jp2_read_boxhdr(&box,&l_nb_bytes_read,stream,p_manager)) {
		/* is it the codestream box ? */
		if (box.type == JP2_JP2C) {
			if (jp2->jp2_state & JP2_STATE_HEADER) {
				jp2->jp2_state |= JP2_STATE_CODESTREAM;
                                opj_free(l_current_data);
				return OPJ_TRUE;
			}
			else {
				opj_event_msg(p_manager, EVT_ERROR, "bad placed jpeg codestream\n");
				opj_free(l_current_data);
				return OPJ_FALSE;
			}
		}
		else if	(box.length == 0) {
			opj_event_msg(p_manager, EVT_ERROR, "Cannot handle box of undefined sizes\n");
			opj_free(l_current_data);
			return OPJ_FALSE;
		}
		/* testcase 1851.pdf.SIGSEGV.ce9.948 */
		/* testcase K-5787457125613568 */
		else if	(box.length < l_nb_bytes_read || box.length > opj_stream_get_number_byte_left(stream)) {
			opj_event_msg(p_manager, EVT_ERROR, "invalid box size %d (%x)\n", box.length, box.type);
			opj_free(l_current_data);
			return OPJ_FALSE;
		}

		l_current_handler = opj_jp2_find_handler(box.type);
		l_current_data_size = box.length - l_nb_bytes_read;

		if (l_current_handler != 00) {
			if (l_current_data_size > l_last_data_size) {
				OPJ_BYTE* new_current_data = (OPJ_BYTE*)opj_realloc(l_current_data,l_current_data_size);
				if (!new_current_data) {
					opj_free(l_current_data);
                    opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to handle jpeg2000 box\n");
					return OPJ_FALSE;
				}
                l_current_data = new_current_data;
				l_last_data_size = l_current_data_size;
			}

			l_nb_bytes_read = (OPJ_UINT32)opj_stream_read_data(stream,l_current_data,l_current_data_size,p_manager);
			if (l_nb_bytes_read != l_current_data_size) {
				opj_event_msg(p_manager, EVT_ERROR, "Problem with reading JPEG2000 box, stream error\n");
                opj_free(l_current_data);                
				return OPJ_FALSE;
			}

			if (! l_current_handler->handler(jp2,l_current_data,l_current_data_size,p_manager)) {
				opj_free(l_current_data);
				return OPJ_FALSE;
			}
		}
		else {
			jp2->jp2_state |= JP2_STATE_UNKNOWN;
			if (opj_stream_skip(stream,l_current_data_size,p_manager) != l_current_data_size) {
				opj_event_msg(p_manager, EVT_ERROR, "Problem with skipping JPEG2000 box, stream error\n");
				opj_free(l_current_data);
				return OPJ_FALSE;
			}
		}
	}

	opj_free(l_current_data);

	return OPJ_TRUE;
}

/**
 * Excutes the given procedures on the given codec.
 *
 * @param	p_procedure_list	the list of procedures to execute
 * @param	jp2					the jpeg2000 file codec to execute the procedures on.
 * @param	stream					the stream to execute the procedures on.
 * @param	p_manager			the user manager.
 *
 * @return	true				if all the procedures were successfully executed.
 */
static OPJ_BOOL opj_jp2_exec (  opj_jp2_t * jp2,
                                opj_procedure_list_t * p_procedure_list,
                                opj_stream_private_t *stream,
                                opj_event_mgr_t * p_manager
                                )

{
	OPJ_BOOL (** l_procedure) (opj_jp2_t * jp2, opj_stream_private_t *, opj_event_mgr_t *) = 00;
	OPJ_BOOL l_result = OPJ_TRUE;
	OPJ_UINT32 l_nb_proc, i;

	/* preconditions */
	assert(p_procedure_list != 00);
	assert(jp2 != 00);
	assert(stream != 00);
	assert(p_manager != 00);

	l_nb_proc = opj_procedure_list_get_nb_procedures(p_procedure_list);
	l_procedure = (OPJ_BOOL (**) (opj_jp2_t * jp2, opj_stream_private_t *, opj_event_mgr_t *)) opj_procedure_list_get_first_procedure(p_procedure_list);

	for	(i=0;i<l_nb_proc;++i) {
		l_result = l_result && (*l_procedure) (jp2,stream,p_manager);
		++l_procedure;
	}

	/* and clear the procedure list at the end. */
	opj_procedure_list_clear(p_procedure_list);
	return l_result;
}

OPJ_BOOL opj_jp2_start_compress(opj_jp2_t *jp2,
                                opj_stream_private_t *stream,
                                opj_image_t * p_image,
                                opj_event_mgr_t * p_manager
                                )
{
	/* preconditions */
	assert(jp2 != 00);
	assert(stream != 00);
	assert(p_manager != 00);

	/* customization of the validation */
	opj_jp2_setup_encoding_validation (jp2);

	/* validation of the parameters codec */
	if (! opj_jp2_exec(jp2,jp2->m_validation_list,stream,p_manager)) {
		return OPJ_FALSE;
	}

	/* customization of the encoding */
	opj_jp2_setup_header_writing(jp2);

	/* write header */
	if (! opj_jp2_exec (jp2,jp2->m_procedure_list,stream,p_manager)) {
		return OPJ_FALSE;
	}

	return opj_j2k_start_compress(jp2->j2k,stream,p_image,p_manager);
}

const opj_jp2_header_handler_t * opj_jp2_find_handler (OPJ_UINT32 p_id)
{
	OPJ_UINT32 i, l_handler_size = sizeof(jp2_header) / sizeof(opj_jp2_header_handler_t);

	for (i=0;i<l_handler_size;++i) {
		if (jp2_header[i].id == p_id) {
			return &jp2_header[i];
		}
	}
	return NULL;
}

/**
 * Finds the image execution function related to the given box id.
 *
 * @param	p_id	the id of the handler to fetch.
 *
 * @return	the given handler or 00 if it could not be found.
 */
static const opj_jp2_header_handler_t * opj_jp2_img_find_handler (OPJ_UINT32 p_id)
{
	OPJ_UINT32 i, l_handler_size = sizeof(jp2_img_header) / sizeof(opj_jp2_header_handler_t);
	for (i=0;i<l_handler_size;++i)
	{
		if (jp2_img_header[i].id == p_id) {
			return &jp2_img_header[i];
		}
	}

	return NULL;
}

/**
 * Reads a jpeg2000 file signature box.
 *
 * @param	p_header_data	the data contained in the signature box.
 * @param	jp2				the jpeg2000 file codec.
 * @param	p_header_size	the size of the data contained in the signature box.
 * @param	p_manager		the user event manager.
 *
 * @return true if the file signature box is valid.
 */
static OPJ_BOOL opj_jp2_read_jp(opj_jp2_t *jp2,
                                OPJ_BYTE * p_header_data,
                                OPJ_UINT32 p_header_size,
                                opj_event_mgr_t * p_manager
                                )

{
	OPJ_UINT32 l_magic_number;

	/* preconditions */
	assert(p_header_data != 00);
	assert(jp2 != 00);
	assert(p_manager != 00);

	if (jp2->jp2_state != JP2_STATE_NONE) {
		opj_event_msg(p_manager, EVT_ERROR, "The signature box must be the first box in the file.\n");
		return OPJ_FALSE;
	}

	/* assure length of data is correct (4 -> magic number) */
	if (p_header_size != 4) {
		opj_event_msg(p_manager, EVT_ERROR, "Error with JP signature Box size\n");
		return OPJ_FALSE;
	}

	/* rearrange data */
	opj_read_bytes(p_header_data,&l_magic_number,4);
	if (l_magic_number != 0x0d0a870a ) {
		opj_event_msg(p_manager, EVT_ERROR, "Error with JP Signature : bad magic number\n");
		return OPJ_FALSE;
	}

	jp2->jp2_state |= JP2_STATE_SIGNATURE;

	return OPJ_TRUE;
}

/**
 * Reads a a FTYP box - File type box
 *
 * @param	p_header_data	the data contained in the FTYP box.
 * @param	jp2				the jpeg2000 file codec.
 * @param	p_header_size	the size of the data contained in the FTYP box.
 * @param	p_manager		the user event manager.
 *
 * @return true if the FTYP box is valid.
 */
static OPJ_BOOL opj_jp2_read_ftyp(	opj_jp2_t *jp2,
									OPJ_BYTE * p_header_data,
									OPJ_UINT32 p_header_size,
									opj_event_mgr_t * p_manager
                                    )
{
	OPJ_UINT32 i, l_remaining_bytes;

	/* preconditions */
	assert(p_header_data != 00);
	assert(jp2 != 00);
	assert(p_manager != 00);

	if (jp2->jp2_state != JP2_STATE_SIGNATURE) {
		opj_event_msg(p_manager, EVT_ERROR, "The ftyp box must be the second box in the file.\n");
		return OPJ_FALSE;
	}

	/* assure length of data is correct */
	if (p_header_size < 8) {
		opj_event_msg(p_manager, EVT_ERROR, "Error with FTYP signature Box size\n");
		return OPJ_FALSE;
	}

	opj_read_bytes(p_header_data,&jp2->brand,4);		/* BR */
	p_header_data += 4;

	opj_read_bytes(p_header_data,&jp2->minversion,4);		/* MinV */
	p_header_data += 4;

	l_remaining_bytes = p_header_size - 8;

	/* the number of remaining bytes should be a multiple of 4 */
	if ((l_remaining_bytes & 0x3) != 0) {
		opj_event_msg(p_manager, EVT_ERROR, "Error with FTYP signature Box size\n");
		return OPJ_FALSE;
	}

	/* div by 4 */
	jp2->numcl = l_remaining_bytes >> 2;
	if (jp2->numcl) {
		jp2->cl = (OPJ_UINT32 *) opj_malloc(jp2->numcl * sizeof(OPJ_UINT32));
		if (jp2->cl == 00) {
			opj_event_msg(p_manager, EVT_ERROR, "Not enough memory with FTYP Box\n");
			return OPJ_FALSE;
		}
		memset(jp2->cl,0,jp2->numcl * sizeof(OPJ_UINT32));
	}

	for (i = 0; i < jp2->numcl; ++i)
	{
		opj_read_bytes(p_header_data,&jp2->cl[i],4);		/* CLi */
		p_header_data += 4;
	}

	jp2->jp2_state |= JP2_STATE_FILE_TYPE;

	return OPJ_TRUE;
}

OPJ_BOOL opj_jp2_skip_jp2c(	opj_jp2_t *jp2,
					    	opj_stream_private_t *stream,
					    	opj_event_mgr_t * p_manager )
{
	/* preconditions */
	assert(jp2 != 00);
	assert(stream != 00);
	assert(p_manager != 00);

	jp2->j2k_codestream_offset = opj_stream_tell(stream);

	if (opj_stream_skip(stream,8,p_manager) != 8) {
		return OPJ_FALSE;
	}

	return OPJ_TRUE;
}

static OPJ_BOOL opj_jpip_skip_iptr(	opj_jp2_t *jp2,
  opj_stream_private_t *stream,
  opj_event_mgr_t * p_manager )
{
  /* preconditions */
  assert(jp2 != 00);
  assert(stream != 00);
  assert(p_manager != 00);

  jp2->jpip_iptr_offset = opj_stream_tell(stream);

  if (opj_stream_skip(stream,24,p_manager) != 24) {
    return OPJ_FALSE;
  }

  return OPJ_TRUE;
}

/**
 * Reads the Jpeg2000 file Header box - JP2 Header box (warning, this is a super box).
 *
 * @param	p_header_data	the data contained in the file header box.
 * @param	jp2				the jpeg2000 file codec.
 * @param	p_header_size	the size of the data contained in the file header box.
 * @param	p_manager		the user event manager.
 *
 * @return true if the JP2 Header box was successfully reconized.
*/
static OPJ_BOOL opj_jp2_read_jp2h(  opj_jp2_t *jp2,
                                    OPJ_BYTE *p_header_data,
                                    OPJ_UINT32 p_header_size,
                                    opj_event_mgr_t * p_manager
                                    )
{
	OPJ_UINT32 l_box_size=0, l_current_data_size = 0;
	opj_jp2_box_t box;
	const opj_jp2_header_handler_t * l_current_handler;

	/* preconditions */
	assert(p_header_data != 00);
	assert(jp2 != 00);
	assert(p_manager != 00);

	/* make sure the box is well placed */
	if ((jp2->jp2_state & JP2_STATE_FILE_TYPE) != JP2_STATE_FILE_TYPE ) {
		opj_event_msg(p_manager, EVT_ERROR, "The  box must be the first box in the file.\n");
		return OPJ_FALSE;
	}

	jp2->jp2_img_state = JP2_IMG_STATE_NONE;

	/* iterate while remaining data */
	while (p_header_size > 0) {

		if (! opj_jp2_read_boxhdr_char(&box,p_header_data,&l_box_size,p_header_size, p_manager)) {
			opj_event_msg(p_manager, EVT_ERROR, "Stream error while reading JP2 Header box\n");
			return OPJ_FALSE;
		}

		if (box.length > p_header_size) {
			opj_event_msg(p_manager, EVT_ERROR, "Stream error while reading JP2 Header box: box length is inconsistent.\n");
			return OPJ_FALSE;
		}

		l_current_handler = opj_jp2_img_find_handler(box.type);
		//BUGID:0055999
		//test file: fuzz-signal_sigsegv_6b88de_1123_2509.pdf
		if (box.length < l_box_size) return OPJ_FALSE;
		l_current_data_size = box.length - l_box_size;
		p_header_data += l_box_size;

		if (l_current_handler != 00) {
			if (! l_current_handler->handler(jp2,p_header_data,l_current_data_size,p_manager)) {
				return OPJ_FALSE;
			}
		}
		else {
			jp2->jp2_img_state |= JP2_IMG_STATE_UNKNOWN;
		}

		p_header_data += l_current_data_size;
		p_header_size -= box.length;
	}

	jp2->jp2_state |= JP2_STATE_HEADER;

	return OPJ_TRUE;
}

OPJ_BOOL opj_jp2_read_boxhdr_char(   opj_jp2_box_t *box,
                                     OPJ_BYTE * p_data,
                                     OPJ_UINT32 * p_number_bytes_read,
                                     OPJ_UINT32 p_box_max_size,
                                     opj_event_mgr_t * p_manager
                                     )
{
	OPJ_UINT32 l_value;

	/* preconditions */
	assert(p_data != 00);
	assert(box != 00);
	assert(p_number_bytes_read != 00);
	assert(p_manager != 00);

	if (p_box_max_size < 8) {
		opj_event_msg(p_manager, EVT_ERROR, "Cannot handle box of less than 8 bytes\n");
		return OPJ_FALSE;
	}

	/* process read data */
	opj_read_bytes(p_data, &l_value, 4);
	p_data += 4;
	box->length = (OPJ_UINT32)(l_value);

	opj_read_bytes(p_data, &l_value, 4);
	p_data += 4;
	box->type = (OPJ_UINT32)(l_value);

	*p_number_bytes_read = 8;

	/* do we have a "special very large box ?" */
	/* read then the XLBox */
	if (box->length == 1) {
		OPJ_UINT32 l_xl_part_size;

		if (p_box_max_size < 16) {
			opj_event_msg(p_manager, EVT_ERROR, "Cannot handle XL box of less than 16 bytes\n");
			return OPJ_FALSE;
		}

		opj_read_bytes(p_data,&l_xl_part_size, 4);
		p_data += 4;
		*p_number_bytes_read += 4;

		if (l_xl_part_size != 0) {
			opj_event_msg(p_manager, EVT_ERROR, "Cannot handle box sizes higher than 2^32\n");
			return OPJ_FALSE;
		}

		opj_read_bytes(p_data, &l_value, 4);
		*p_number_bytes_read += 4;
		box->length = (OPJ_UINT32)(l_value);

		if (box->length == 0) {
			opj_event_msg(p_manager, EVT_ERROR, "Cannot handle box of undefined sizes\n");
			return OPJ_FALSE;
		}
	}
	else if (box->length == 0) {
		opj_event_msg(p_manager, EVT_ERROR, "Cannot handle box of undefined sizes\n");
		return OPJ_FALSE;
	}

	return OPJ_TRUE;
}

OPJ_BOOL opj_jp2_read_header(	opj_stream_private_t *p_stream,
                                opj_jp2_t *jp2,
                                opj_image_t ** p_image,
                                opj_event_mgr_t * p_manager
                                )
{
	/* preconditions */
	assert(jp2 != 00);
	assert(p_stream != 00);
	assert(p_manager != 00);

	/* customization of the validation */
	opj_jp2_setup_decoding_validation (jp2);

	/* customization of the encoding */
	opj_jp2_setup_header_reading(jp2);

	/* validation of the parameters codec */
	if (! opj_jp2_exec(jp2,jp2->m_validation_list,p_stream,p_manager)) {
		return OPJ_FALSE;
	}

	/* read header */
	if (! opj_jp2_exec (jp2,jp2->m_procedure_list,p_stream,p_manager)) {
		return OPJ_FALSE;
	}

	return opj_j2k_read_header(	p_stream,
							jp2->j2k,
							p_image,
							p_manager);
}

void opj_jp2_setup_encoding_validation (opj_jp2_t *jp2)
{
	/* preconditions */
	assert(jp2 != 00);

	opj_procedure_list_add_procedure(jp2->m_validation_list, (opj_procedure)opj_jp2_default_validation);
	/* DEVELOPER CORNER, add your custom validation procedure */
}

void opj_jp2_setup_decoding_validation (opj_jp2_t *jp2)
{
	/* preconditions */
	assert(jp2 != 00);
	/* DEVELOPER CORNER, add your custom validation procedure */
}

void opj_jp2_setup_header_writing (opj_jp2_t *jp2)
{
	/* preconditions */
	assert(jp2 != 00);

	opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)opj_jp2_write_jp );
	opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)opj_jp2_write_ftyp );
	opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)opj_jp2_write_jp2h );
  if( jp2->jpip_on )
    opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)opj_jpip_skip_iptr );
	opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)opj_jp2_skip_jp2c );

	/* DEVELOPER CORNER, insert your custom procedures */

}

void opj_jp2_setup_header_reading (opj_jp2_t *jp2)
{
	/* preconditions */
	assert(jp2 != 00);

	opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)opj_jp2_read_header_procedure );
	/* DEVELOPER CORNER, add your custom procedures */
}

OPJ_BOOL opj_jp2_read_tile_header ( opj_jp2_t * p_jp2,
                                    OPJ_UINT32 * p_tile_index,
                                    OPJ_UINT32 * p_data_size,
                                    OPJ_INT32 * p_tile_x0,
                                    OPJ_INT32 * p_tile_y0,
                                    OPJ_INT32 * p_tile_x1,
                                    OPJ_INT32 * p_tile_y1,
                                    OPJ_UINT32 * p_nb_comps,
                                    OPJ_BOOL * p_go_on,
                                    opj_stream_private_t *p_stream,
                                    opj_event_mgr_t * p_manager
                                    )
{
	return opj_j2k_read_tile_header(p_jp2->j2k,
								p_tile_index,
								p_data_size,
								p_tile_x0, p_tile_y0,
								p_tile_x1, p_tile_y1,
								p_nb_comps,
								p_go_on,
								p_stream,
								p_manager);
}

OPJ_BOOL opj_jp2_write_tile (	opj_jp2_t *p_jp2,
					 	 	    OPJ_UINT32 p_tile_index,
					 	 	    OPJ_BYTE * p_data,
					 	 	    OPJ_UINT32 p_data_size,
					 	 	    opj_stream_private_t *p_stream,
					 	 	    opj_event_mgr_t * p_manager
                                )

{
	return opj_j2k_write_tile (p_jp2->j2k,p_tile_index,p_data,p_data_size,p_stream,p_manager);
}

OPJ_BOOL opj_jp2_decode_tile (  opj_jp2_t * p_jp2,
                                OPJ_UINT32 p_tile_index,
                                OPJ_BYTE * p_data,
                                OPJ_UINT32 p_data_size,
                                opj_stream_private_t *p_stream,
                                opj_event_mgr_t * p_manager
                                )
{
	return opj_j2k_decode_tile (p_jp2->j2k,p_tile_index,p_data,p_data_size,p_stream,p_manager);
}

void opj_jp2_destroy(opj_jp2_t *jp2)
{
	if (jp2) {
		/* destroy the J2K codec */
		opj_j2k_destroy(jp2->j2k);
		jp2->j2k = 00;

		if (jp2->comps) {
			opj_free(jp2->comps);
			jp2->comps = 00;
		}

		if (jp2->cl) {
			opj_free(jp2->cl);
			jp2->cl = 00;
		}

		if (jp2->color.icc_profile_buf) {
			opj_free(jp2->color.icc_profile_buf);
			jp2->color.icc_profile_buf = 00;
		}

		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;
		}

		if (jp2->m_validation_list) {
			opj_procedure_list_destroy(jp2->m_validation_list);
			jp2->m_validation_list = 00;
		}

		if (jp2->m_procedure_list) {
			opj_procedure_list_destroy(jp2->m_procedure_list);
			jp2->m_procedure_list = 00;
		}

		opj_free(jp2);
	}
}

OPJ_BOOL opj_jp2_set_decode_area(	opj_jp2_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,
								    opj_event_mgr_t * p_manager
                                    )
{
	return opj_j2k_set_decode_area(p_jp2->j2k, p_image, p_start_x, p_start_y, p_end_x, p_end_y, p_manager);
}

OPJ_BOOL opj_jp2_get_tile(	opj_jp2_t *p_jp2,
                            opj_stream_private_t *p_stream,
                            opj_image_t* p_image,
                            opj_event_mgr_t * p_manager,
                            OPJ_UINT32 tile_index
                            )
{
	if (!p_image)
		return OPJ_FALSE;

	opj_event_msg(p_manager, EVT_WARNING, "JP2 box which are after the codestream will not be read by this function.\n");

	if (! opj_j2k_get_tile(p_jp2->j2k, p_stream, p_image, p_manager, tile_index) ){
		opj_event_msg(p_manager, EVT_ERROR, "Failed to decode the codestream in the JP2 file\n");
		return OPJ_FALSE;
	}

	if (!opj_jp2_check_color(p_image, &(p_jp2->color), p_manager)) {
		return OPJ_FALSE;
	}

	/* Set Image Color Space */
	if (p_jp2->enumcs == 16)
		p_image->color_space = OPJ_CLRSPC_SRGB;
	else if (p_jp2->enumcs == 17)
		p_image->color_space = OPJ_CLRSPC_GRAY;
	else if (p_jp2->enumcs == 18)
		p_image->color_space = OPJ_CLRSPC_SYCC;
	else
		p_image->color_space = OPJ_CLRSPC_UNKNOWN;

	/* Apply the color space if needed */
	if(p_jp2->color.jp2_cdef) {
		opj_jp2_apply_cdef(p_image, &(p_jp2->color));
	}

	if(p_jp2->color.jp2_pclr) {
		/* Part 1, I.5.3.4: Either both or none : */
		if( !p_jp2->color.jp2_pclr->cmap)
			opj_jp2_free_pclr(&(p_jp2->color));
		else
			opj_jp2_apply_pclr(p_image, &(p_jp2->color));
	}

	if(p_jp2->color.icc_profile_buf) {
		p_image->icc_profile_buf = p_jp2->color.icc_profile_buf;
		p_image->icc_profile_len = p_jp2->color.icc_profile_len;
		p_jp2->color.icc_profile_buf = NULL;
	}

	return OPJ_TRUE;
}

/* ----------------------------------------------------------------------- */
/* JP2 encoder interface                                             */
/* ----------------------------------------------------------------------- */

opj_jp2_t* opj_jp2_create(OPJ_BOOL p_is_decoder)
{
	opj_jp2_t *jp2 = (opj_jp2_t*)opj_malloc(sizeof(opj_jp2_t));
	if (jp2) {
		memset(jp2,0,sizeof(opj_jp2_t));

		/* create the J2K codec */
		if (! p_is_decoder) {
			jp2->j2k = opj_j2k_create_compress();
		}
		else {
			jp2->j2k = opj_j2k_create_decompress();
		}

		if (jp2->j2k == 00) {
			opj_jp2_destroy(jp2);
			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) {
			opj_jp2_destroy(jp2);
			return 00;
		}

		/* execution list creation */
		jp2->m_procedure_list = opj_procedure_list_create();
		if (! jp2->m_procedure_list) {
			opj_jp2_destroy(jp2);
			return 00;
		}
	}

	return jp2;
}

void jp2_dump(opj_jp2_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_t* p_jp2)
{
	return j2k_get_cstr_index(p_jp2->j2k);
}

opj_codestream_info_v2_t* jp2_get_cstr_info(opj_jp2_t* p_jp2)
{
	return j2k_get_cstr_info(p_jp2->j2k);
}

OPJ_BOOL opj_jp2_set_decoded_resolution_factor(opj_jp2_t *p_jp2,
                                               OPJ_UINT32 res_factor,
                                               opj_event_mgr_t * p_manager)
{
	return opj_j2k_set_decoded_resolution_factor(p_jp2->j2k, res_factor, p_manager);
}

/* JPIP specific */

#ifdef USE_JPIP
static OPJ_BOOL opj_jpip_write_iptr(opj_jp2_t *jp2,
  opj_stream_private_t *cio,
  opj_event_mgr_t * p_manager )
{
  OPJ_OFF_T j2k_codestream_exit;
  OPJ_BYTE l_data_header [24];

  /* 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, 24, 4); /* size of iptr */
  opj_write_bytes(l_data_header + 4,JPIP_IPTR,4);									   /* IPTR */
#if 0
  opj_write_bytes(l_data_header + 4 + 4, 0, 8); /* offset */
  opj_write_bytes(l_data_header + 8 + 8, 0, 8); /* length */
#else
  opj_write_double(l_data_header + 4 + 4, 0); /* offset */
  opj_write_double(l_data_header + 8 + 8, 0); /* length */
#endif

  if (! opj_stream_seek(cio,jp2->jpip_iptr_offset,p_manager)) {
    opj_event_msg(p_manager, EVT_ERROR, "Failed to seek in the stream.\n");
    return OPJ_FALSE;
  }

  if (opj_stream_write_data(cio,l_data_header,24,p_manager) != 24) {
    opj_event_msg(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(p_manager, EVT_ERROR, "Failed to seek in the stream.\n");
    return OPJ_FALSE;
  }

  return OPJ_TRUE;
}

static OPJ_BOOL opj_jpip_write_fidx(opj_jp2_t *jp2,
  opj_stream_private_t *cio,
  opj_event_mgr_t * p_manager )
{
  OPJ_OFF_T j2k_codestream_exit;
  OPJ_BYTE l_data_header [24];

  /* preconditions */
  assert(jp2 != 00);
  assert(cio != 00);
  assert(p_manager != 00);
  assert(opj_stream_has_seek(cio));

  opj_write_bytes(l_data_header, 24, 4); /* size of iptr */
  opj_write_bytes(l_data_header + 4,JPIP_FIDX,4);									   /* IPTR */
  opj_write_double(l_data_header + 4 + 4, 0); /* offset */
  opj_write_double(l_data_header + 8 + 8, 0); /* length */

  if (opj_stream_write_data(cio,l_data_header,24,p_manager) != 24) {
    opj_event_msg(p_manager, EVT_ERROR, "Failed to seek in the stream.\n");
    return OPJ_FALSE;
  }

  j2k_codestream_exit = opj_stream_tell(cio);
  if (! opj_stream_seek(cio,j2k_codestream_exit,p_manager)) {
    opj_event_msg(p_manager, EVT_ERROR, "Failed to seek in the stream.\n");
    return OPJ_FALSE;
  }

  return OPJ_TRUE;
}

static OPJ_BOOL opj_jpip_write_cidx(opj_jp2_t *jp2,
  opj_stream_private_t *cio,
  opj_event_mgr_t * p_manager )
{
  OPJ_OFF_T j2k_codestream_exit;
  OPJ_BYTE l_data_header [24];

  /* 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, 24, 4); /* size of iptr */
  opj_write_bytes(l_data_header + 4,JPIP_CIDX,4);									   /* IPTR */
#if 0
  opj_write_bytes(l_data_header + 4 + 4, 0, 8); /* offset */
  opj_write_bytes(l_data_header + 8 + 8, 0, 8); /* length */
#else
  opj_write_double(l_data_header + 4 + 4, 0); /* offset */
  opj_write_double(l_data_header + 8 + 8, 0); /* length */
#endif

  if (! opj_stream_seek(cio,j2k_codestream_exit,p_manager)) {
    opj_event_msg(p_manager, EVT_ERROR, "Failed to seek in the stream.\n");
    return OPJ_FALSE;
  }

  if (opj_stream_write_data(cio,l_data_header,24,p_manager) != 24) {
    opj_event_msg(p_manager, EVT_ERROR, "Failed to seek in the stream.\n");
    return OPJ_FALSE;
  }

  j2k_codestream_exit = opj_stream_tell(cio);
  if (! opj_stream_seek(cio,j2k_codestream_exit,p_manager)) {
    opj_event_msg(p_manager, EVT_ERROR, "Failed to seek in the stream.\n");
    return OPJ_FALSE;
  }

  return OPJ_TRUE;
}

#if 0
static void write_prxy( int offset_jp2c, int length_jp2c, int offset_idx, int length_idx, opj_stream_private_t *cio,
  opj_event_mgr_t * p_manager )
{
  OPJ_BYTE l_data_header [8];
  OPJ_OFF_T len, lenp;

  lenp = opj_stream_tell(cio);
  opj_stream_skip(cio, 4, p_manager);         /* L [at the end] */
  opj_write_bytes(l_data_header,JPIP_PRXY,4); /* IPTR           */
  opj_stream_write_data(cio,l_data_header,4,p_manager);

  opj_write_bytes( l_data_header, offset_jp2c, 8); /* OOFF           */
  opj_stream_write_data(cio,l_data_header,8,p_manager);
  opj_write_bytes( l_data_header, length_jp2c, 4); /* OBH part 1     */
  opj_write_bytes( l_data_header+4, JP2_JP2C, 4);  /* OBH part 2     */
  opj_stream_write_data(cio,l_data_header,8,p_manager);

  opj_write_bytes( l_data_header, 1, 1);/* NI             */
  opj_stream_write_data(cio,l_data_header,1,p_manager);

  opj_write_bytes( l_data_header, offset_idx, 8);  /* IOFF           */
  opj_stream_write_data(cio,l_data_header,8,p_manager);
  opj_write_bytes( l_data_header, length_idx, 4);  /* IBH part 1     */
  opj_write_bytes( l_data_header+4, JPIP_CIDX, 4);   /* IBH part 2     */
  opj_stream_write_data(cio,l_data_header,8,p_manager);

  len = opj_stream_tell(cio)-lenp;
  opj_stream_skip(cio, lenp, p_manager);
  opj_write_bytes(l_data_header,len,4);/* L              */
  opj_stream_write_data(cio,l_data_header,4,p_manager);
  opj_stream_seek(cio, lenp+len,p_manager);
}
#endif


#if 0
static int write_fidx( int offset_jp2c, int length_jp2c, int offset_idx, int length_idx, opj_stream_private_t *cio,
  opj_event_mgr_t * p_manager )
{
  OPJ_BYTE l_data_header [4];
  OPJ_OFF_T len, lenp;

  lenp = opj_stream_tell(cio);
  opj_stream_skip(cio, 4, p_manager);
  opj_write_bytes(l_data_header,JPIP_FIDX,4); /* FIDX */
  opj_stream_write_data(cio,l_data_header,4,p_manager);

  write_prxy( offset_jp2c, length_jp2c, offset_idx, length_idx, cio,p_manager);

  len = opj_stream_tell(cio)-lenp;
  opj_stream_skip(cio, lenp, p_manager);
  opj_write_bytes(l_data_header,len,4);/* L              */
  opj_stream_write_data(cio,l_data_header,4,p_manager);
  opj_stream_seek(cio, lenp+len,p_manager);

  return len;
}
#endif
#endif /* USE_JPIP */
