/*
 * 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, opj_event_mgr_t *);

/**
 * Writes the Channel Definition 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_cdef(   opj_jp2_t *jp2,
																		 OPJ_UINT32 * p_nb_bytes_written );

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

static 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 recognized.
*/
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 file Header box - JP2 Header box (warning, this is a super box).
 *
 * @param  jp2      the jpeg2000 file codec.
 * @param  stream      the stream to write data to.
 * @param  p_manager  user event manager.
 *
 * @return true if writing was successful.
 */
static OPJ_BOOL opj_jp2_write_jp2h(opj_jp2_t *jp2,
														opj_stream_private_t *stream,
														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 OPJ_BOOL opj_jp2_setup_end_header_writing (opj_jp2_t *jp2, opj_event_mgr_t * p_manager);

/**
 * 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 OPJ_BOOL opj_jp2_setup_end_header_reading (opj_jp2_t *jp2, opj_event_mgr_t * p_manager);

/**
 * 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 recognized, 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 OPJ_BOOL opj_jp2_setup_encoding_validation (opj_jp2_t *jp2, opj_event_mgr_t * p_manager);

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

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

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

static 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 recognized, 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 OPJ_BOOL opj_jp2_setup_decoding_validation (opj_jp2_t *jp2, opj_event_mgr_t * p_manager);

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

/* ----------------------------------------------------------------------- */
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 )
{
	/* 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

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 )
{
	/* 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_calloc(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;
	}

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

static 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_calloc(1,22);
	if (l_ihdr_data == 00) {
		return 00;
	}

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

static 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_calloc(1,l_bpcc_size);
	if (l_bpcc_data == 00) {
		return 00;
	}

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

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
                            )
{
	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;
}
static OPJ_BYTE * opj_jp2_write_cdef(opj_jp2_t *jp2, OPJ_UINT32 * p_nb_bytes_written)
{
	/* room for 8 bytes for box, 2 for n */
	OPJ_UINT32 l_cdef_size = 10;
	OPJ_BYTE * l_cdef_data,* l_current_cdef_ptr;
	OPJ_UINT32 l_value;
	OPJ_UINT16 i;

	/* preconditions */
	assert(jp2 != 00);
	assert(p_nb_bytes_written != 00);
	assert(jp2->color.jp2_cdef != 00);
	assert(jp2->color.jp2_cdef->info != 00);
	assert(jp2->color.jp2_cdef->n > 0U);

	l_cdef_size += 6U * jp2->color.jp2_cdef->n;

	l_cdef_data = (OPJ_BYTE *) opj_malloc(l_cdef_size);
	if (l_cdef_data == 00) {
		return 00;
	}

	l_current_cdef_ptr = l_cdef_data;
	
	opj_write_bytes(l_current_cdef_ptr,l_cdef_size,4);			/* write box size */
	l_current_cdef_ptr += 4;

	opj_write_bytes(l_current_cdef_ptr,JP2_CDEF,4);					/* BPCC */
	l_current_cdef_ptr += 4;

	l_value = jp2->color.jp2_cdef->n;
	opj_write_bytes(l_current_cdef_ptr,l_value,2);					/* N */
	l_current_cdef_ptr += 2;

	for (i = 0U; i < jp2->color.jp2_cdef->n; ++i) {
		l_value = jp2->color.jp2_cdef->info[i].cn;
		opj_write_bytes(l_current_cdef_ptr,l_value,2);					/* Cni */
		l_current_cdef_ptr += 2;
		l_value = jp2->color.jp2_cdef->info[i].typ;
		opj_write_bytes(l_current_cdef_ptr,l_value,2);					/* Typi */
		l_current_cdef_ptr += 2;
		l_value = jp2->color.jp2_cdef->info[i].asoc;
		opj_write_bytes(l_current_cdef_ptr,l_value,2);					/* Asoci */
		l_current_cdef_ptr += 2;
	}
	*p_nb_bytes_written = l_cdef_size;

	return l_cdef_data;
}

static 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_calloc(1,l_colr_size);
	if (l_colr_data == 00) {
		return 00;
	}
	
	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;
}

static 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;
		OPJ_UINT32 nr_channels = image->numcomps; /* FIXME image->numcomps == jp2->numcomps before color is applied ??? */

		/* cdef applies to cmap channels if any */
		if (color->jp2_pclr && color->jp2_pclr->cmap) {
			nr_channels = (OPJ_UINT32)color->jp2_pclr->nr_channels;
		}

		for (i = 0; i < n; i++) {
			if (info[i].cn >= nr_channels) {
				opj_event_msg(p_manager, EVT_ERROR, "Invalid component index %d (>= %d).\n", info[i].cn, nr_channels);
				return OPJ_FALSE;
			}
			if (info[i].asoc == 65535U) continue;

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

		/* issue 397 */
		/* ISO 15444-1 states that if cdef is present, it shall contain a complete list of channel definitions. */
		while (nr_channels > 0)
		{
			for(i = 0; i < n; ++i) {
				if ((OPJ_UINT32)info[i].cn == (nr_channels - 1U)) {
					break;
				}
			}
			if (i == n) {
				opj_event_msg(p_manager, EVT_ERROR, "Incomplete channel definitions.\n");
				return OPJ_FALSE;
			}
			--nr_channels;
		}
	}

	/* 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++) {
			if (cmap[i].mtyp != 0 && cmap[i].mtyp != 1) {
				opj_event_msg(p_manager, EVT_ERROR, "Unexpected MTYP value.\n");
				opj_free(pcol_usage);
				return OPJ_FALSE;
			}
			OPJ_UINT16 pcol = cmap[i].pcol;
			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 != 0) {
				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;
			}
		}
		/* Issue 235/447 weird cmap */
		if (1 && is_sane && (image->numcomps==1U)) {
			for (i = 0; i < nr_channels; i++) {
				if (!pcol_usage[i]) {
					is_sane = 0U;
					opj_event_msg(p_manager, EVT_WARNING, "Component mapping seems wrong. Trying to correct.\n", i);
					break;
				}
			}
			if (!is_sane) {
				is_sane = OPJ_TRUE;
				for (i = 0; i < nr_channels; i++) {
					cmap[i].mtyp = 1U;
					cmap[i].pcol = (OPJ_BYTE) i;
				}
			}
		}
		opj_free(pcol_usage);
		if (!is_sane) {
			return OPJ_FALSE;
		}
	}

	return OPJ_TRUE;
}

/* file9.jp2 */
static 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));
	if (!new_comps) {
		/* FIXME no error code for opj_jp2_apply_pclr */
		/* FIXME event manager error callback */
		return;
	}
	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 ); // probably wrong?
      new_comps[i] = old_comps[cmp];
    }

		/* Palette mapping: */
		new_comps[i].data = (OPJ_INT32*)
				opj_malloc(old_comps[cmp].w * old_comps[cmp].h * sizeof(OPJ_INT32));
		if (!new_comps[i].data) {
			opj_free(new_comps);
			new_comps = NULL;
			/* FIXME no error code for opj_jp2_apply_pclr */
			/* FIXME event manager error callback */
			return;
		}
		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[i].w * new_comps[i].h;

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

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
                            )
{
	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;
	if ((nr_entries == 0U) || (nr_entries > 1024U)) {
		opj_event_msg(p_manager, EVT_ERROR, "Invalid PCLR box. Reports %d entries\n", (int)nr_entries);
		return OPJ_FALSE;
	}

	opj_read_bytes(p_pclr_header_data, &l_value , 1);	/* NPC */
	++p_pclr_header_data;
	nr_channels = (OPJ_UINT16) l_value;
	if (nr_channels == 0U) {
		opj_event_msg(p_manager, EVT_ERROR, "Invalid PCLR box. Reports 0 palette columns\n");
		return OPJ_FALSE;
	}

	if (p_pclr_header_size < 3 + (OPJ_UINT32)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 < (ptrdiff_t)(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;
}

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
                            )
{
	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_BE(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;
}

static void opj_jp2_apply_cdef(opj_image_t *image, opj_jp2_color_t *color, opj_event_mgr_t *manager)
{
	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;
		cn = info[i].cn;
		
		if( cn >= image->numcomps)
		{
			opj_event_msg(manager, EVT_WARNING, "opj_jp2_apply_cdef: cn=%d, numcomps=%d\n", cn, image->numcomps);
			continue;
		}
		if(asoc == 0 || asoc == 65535)
		{
			image->comps[cn].alpha = info[i].typ;
			continue;
		}
		
		acn = (OPJ_UINT16)(asoc - 1);
		if( acn >= image->numcomps )
		{
			opj_event_msg(manager, EVT_WARNING, "opj_jp2_apply_cdef: acn=%d, numcomps=%d\n", acn, image->numcomps);
			continue;
		}
		
		/* Swap only if color channel */
		if((cn != acn) && (info[i].typ == 0))
		{
			opj_image_comp_t saved;
			OPJ_UINT16 j;
			
			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));
			
			/* Swap channels in following channel definitions, don't bother with j <= i that are already processed */
			for (j = (OPJ_UINT16)(i + 1U); j < n ; ++j)
			{
				if (info[j].cn == cn) {
					info[j].cn = acn;
				}
				else if (info[j].cn == acn) {
					info[j].cn = cn;
				}
				/* asoc is related to color index. Do not update. */
			}
		}
		
		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() */

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

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
                            )
{
	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) {
			opj_event_msg(p_manager, EVT_ERROR, "Bad COLR header box (bad size: %d)\n", p_colr_header_size);
			return OPJ_FALSE;
		}
		if ((p_colr_header_size > 7) && (jp2->enumcs != 14)) { /* handled below for CIELab) */
			/* 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 */
			
			/* default values */
			rl = ra = rb = ol = oa = ob = 0;
			il = 0x00443530; /* D50 */
			cielab[1] = 0x44454600;/* DEF */

			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;
			}
			else if(p_colr_header_size != 7)
			{
				opj_event_msg(p_manager, EVT_WARNING, "Bad COLR header box (CIELab, bad size: %d)\n", p_colr_header_size);
			}
			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 = (OPJ_BYTE*)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_calloc(1,(size_t)icc_len);
		if (!jp2->color.icc_profile_buf)
		{
			jp2->color.icc_profile_len = 0;
			return OPJ_FALSE;
		}

		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 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 if (p_image->pdfium_use_colorspace)
				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 )
{
	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_calloc(1,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;
	}

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

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

static 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                                             */
/* ----------------------------------------------------------------------- */

OPJ_BOOL 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;
	OPJ_UINT32 alpha_count;
	OPJ_UINT32 color_channels = 0U;
	OPJ_UINT32 alpha_channel = 0U;
	

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

	/* 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_FALSE;
	}

	if (opj_j2k_setup_encoder(jp2->j2k, parameters, image, p_manager ) == OPJ_FALSE) {
		return OPJ_FALSE;
	}

	/* 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 OPJ_FALSE;
	}
	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");
		/* Memory of jp2->cl will be freed by opj_jp2_destroy */
		return OPJ_FALSE;
	}

	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 */
    }

	/* Channel Definition box */
	/* FIXME not provided by parameters */
	/* We try to do what we can... */
	alpha_count = 0U;
	for (i = 0; i < image->numcomps; i++) {
		if (image->comps[i].alpha != 0) {
			alpha_count++;
			alpha_channel = i;
		}
	}
	if (alpha_count == 1U) { /* no way to deal with more than 1 alpha channel */
		switch (jp2->enumcs) {
			case 16:
			case 18:
				color_channels = 3;
				break;
			case 17:
				color_channels = 1;
				break;
			default:
				alpha_count = 0U;
				break;
		}
		if (alpha_count == 0U) {
			opj_event_msg(p_manager, EVT_WARNING, "Alpha channel specified but unknown enumcs. No cdef box will be created.\n");
		} else if (image->numcomps < (color_channels+1)) {
			opj_event_msg(p_manager, EVT_WARNING, "Alpha channel specified but not enough image components for an automatic cdef box creation.\n");
			alpha_count = 0U;
		} else if ((OPJ_UINT32)alpha_channel < color_channels) {
			opj_event_msg(p_manager, EVT_WARNING, "Alpha channel position conflicts with color channel. No cdef box will be created.\n");
			alpha_count = 0U;
		}
	} else if (alpha_count > 1) {
		opj_event_msg(p_manager, EVT_WARNING, "Multiple alpha channels specified. No cdef box will be created.\n");
	}
	if (alpha_count == 1U) { /* if here, we know what we can do */
		jp2->color.jp2_cdef = (opj_jp2_cdef_t*)opj_malloc(sizeof(opj_jp2_cdef_t));
		if(!jp2->color.jp2_cdef) {
			opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to setup the JP2 encoder\n");
			return OPJ_FALSE;
		}
		/* no memset needed, all values will be overwritten except if jp2->color.jp2_cdef->info allocation fails, */
		/* in which case jp2->color.jp2_cdef->info will be NULL => valid for destruction */
		jp2->color.jp2_cdef->info = (opj_jp2_cdef_info_t*) opj_malloc(image->numcomps * sizeof(opj_jp2_cdef_info_t));
		if (!jp2->color.jp2_cdef->info) {
			/* memory will be freed by opj_jp2_destroy */
			opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to setup the JP2 encoder\n");
			return OPJ_FALSE;
		}
		jp2->color.jp2_cdef->n = (OPJ_UINT16) image->numcomps; /* cast is valid : image->numcomps [1,16384] */
		for (i = 0U; i < color_channels; i++) {
			jp2->color.jp2_cdef->info[i].cn = (OPJ_UINT16)i; /* cast is valid : image->numcomps [1,16384] */
			jp2->color.jp2_cdef->info[i].typ = 0U;
			jp2->color.jp2_cdef->info[i].asoc = (OPJ_UINT16)(i+1U); /* No overflow + cast is valid : image->numcomps [1,16384] */
		}
		for (; i < image->numcomps; i++) {
			if (image->comps[i].alpha != 0) { /* we'll be here exactly once */
				jp2->color.jp2_cdef->info[i].cn = (OPJ_UINT16)i; /* cast is valid : image->numcomps [1,16384] */
				jp2->color.jp2_cdef->info[i].typ = 1U; /* Opacity channel */
				jp2->color.jp2_cdef->info[i].asoc = 0U; /* Apply alpha channel to the whole image */
			} else {
				/* Unknown channel */
				jp2->color.jp2_cdef->info[i].cn = (OPJ_UINT16)i; /* cast is valid : image->numcomps [1,16384] */
				jp2->color.jp2_cdef->info[i].typ = 65535U;
				jp2->color.jp2_cdef->info[i].asoc = 65535U;
			}
		}
	}

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

	jp2->jpip_on = parameters->jpip_on;

	return OPJ_TRUE;
}

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 */
	if (! opj_jp2_setup_end_header_reading(jp2, p_manager)) {
		return OPJ_FALSE;
	}

	/* 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 */
	if (! opj_jp2_setup_end_header_writing(jp2, p_manager)) {
		return OPJ_FALSE;
	}

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

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

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

static OPJ_BOOL opj_jp2_setup_end_header_reading (opj_jp2_t *jp2, opj_event_mgr_t * p_manager)
{
	/* preconditions */
	assert(jp2 != 00);
	assert(p_manager != 00);
	
	if (! opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)opj_jp2_read_header_procedure, p_manager)) {
		return OPJ_FALSE;
	}
	/* DEVELOPER CORNER, add your custom procedures */
	
	return OPJ_TRUE;
}

static 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 & 0x7FU) < 38U); /* 0 is valid, ignore sign for check */
	}

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

static 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;
	const opj_jp2_header_handler_t * l_current_handler_misplaced;
	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_calloc(1,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;
	}

	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 */
        else if (box.length < l_nb_bytes_read) {
			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_handler_misplaced = opj_jp2_img_find_handler(box.type);
		l_current_data_size = box.length - l_nb_bytes_read;

		if ((l_current_handler != 00) || (l_current_handler_misplaced != 00)) {
			if (l_current_handler == 00) {
				opj_event_msg(p_manager, EVT_WARNING, "Found a misplaced '%c%c%c%c' box outside jp2h box\n", (OPJ_BYTE)(box.type>>24), (OPJ_BYTE)(box.type>>16), (OPJ_BYTE)(box.type>>8), (OPJ_BYTE)(box.type>>0));
				if (jp2->jp2_state & JP2_STATE_HEADER) {
					/* read anyway, we already have jp2h */
					l_current_handler = l_current_handler_misplaced;
				} else {
					opj_event_msg(p_manager, EVT_WARNING, "JPEG2000 Header box not read yet, '%c%c%c%c' box will be ignored\n", (OPJ_BYTE)(box.type>>24), (OPJ_BYTE)(box.type>>16), (OPJ_BYTE)(box.type>>8), (OPJ_BYTE)(box.type>>0));
					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;
					}
					continue;
				}
			}
			if ((OPJ_OFF_T)l_current_data_size > opj_stream_get_number_byte_left(stream)) {
				/* do not even try to malloc if we can't read */
				opj_event_msg(p_manager, EVT_ERROR, "Invalid box size %d for box '%c%c%c%c'. Need %d bytes, %d bytes remaining \n", box.length, (OPJ_BYTE)(box.type>>24), (OPJ_BYTE)(box.type>>16), (OPJ_BYTE)(box.type>>8), (OPJ_BYTE)(box.type>>0), l_current_data_size, (OPJ_UINT32)opj_stream_get_number_byte_left(stream));
				opj_free(l_current_data);
				return OPJ_FALSE;
			}
			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 {
            if (!(jp2->jp2_state & JP2_STATE_SIGNATURE)) {
                opj_event_msg(p_manager, EVT_ERROR, "Malformed JP2 file format: first box must be JPEG 2000 signature box\n");
                opj_free(l_current_data);
                return OPJ_FALSE;
            }
            if (!(jp2->jp2_state & JP2_STATE_FILE_TYPE)) {
                opj_event_msg(p_manager, EVT_ERROR, "Malformed JP2 file format: second box must be file type box\n");
                opj_free(l_current_data);
                return OPJ_FALSE;
            }
			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 */
	if (! opj_jp2_setup_encoding_validation (jp2, p_manager)) {
		return OPJ_FALSE;
	}

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

	/* customization of the encoding */
	if (! opj_jp2_setup_header_writing(jp2, p_manager)) {
		return OPJ_FALSE;
	}

	/* 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);
}

static 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_calloc(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;
		}
	}

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

static 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 recognized.
*/
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;
	OPJ_BOOL l_has_ihdr = 0;

	/* 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);
		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;
		}

		if (box.type == JP2_IHDR) {
			l_has_ihdr = 1;
		}

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

	if (l_has_ihdr == 0) {
		opj_event_msg(p_manager, EVT_ERROR, "Stream error while reading JP2 Header box: no 'ihdr' box.\n");
		return OPJ_FALSE;
	}

	jp2->jp2_state |= JP2_STATE_HEADER;

	return OPJ_TRUE;
}

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
                                     )
{
	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;
	}
	if (box->length < *p_number_bytes_read) {
		opj_event_msg(p_manager, EVT_ERROR, "Box length is inconsistent.\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 */
	if (! opj_jp2_setup_decoding_validation (jp2, p_manager)) {
		return OPJ_FALSE;
	}

	/* customization of the encoding */
	if (! opj_jp2_setup_header_reading(jp2, p_manager)) {
		return OPJ_FALSE;
	}

	/* 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);
}

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

	if (! opj_procedure_list_add_procedure(jp2->m_validation_list, (opj_procedure)opj_jp2_default_validation, p_manager)) {
		return OPJ_FALSE;
	}
	/* DEVELOPER CORNER, add your custom validation procedure */
	
	return OPJ_TRUE;
}

static OPJ_BOOL opj_jp2_setup_decoding_validation (opj_jp2_t *jp2, opj_event_mgr_t * p_manager)
{
	/* preconditions */
	assert(jp2 != 00);
	assert(p_manager != 00);
	
	/* DEVELOPER CORNER, add your custom validation procedure */
	
	return OPJ_TRUE;
}

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

	if (! opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)opj_jp2_write_jp, p_manager)) {
		return OPJ_FALSE;
	}
	if (! opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)opj_jp2_write_ftyp, p_manager)) {
		return OPJ_FALSE;
	}
	if (! opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)opj_jp2_write_jp2h, p_manager)) {
		return OPJ_FALSE;
	}
	if( jp2->jpip_on ) {
		if (! opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)opj_jpip_skip_iptr, p_manager)) {
			return OPJ_FALSE;
		}
	}
	if (! opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)opj_jp2_skip_jp2c,p_manager)) {
		return OPJ_FALSE;
	}

	/* DEVELOPER CORNER, insert your custom procedures */

	return OPJ_TRUE;
}

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

	if (! opj_procedure_list_add_procedure(jp2->m_procedure_list,(opj_procedure)opj_jp2_read_header_procedure, p_manager)) {
		return OPJ_FALSE;
	}
	
	/* DEVELOPER CORNER, add your custom procedures */
	
	return OPJ_TRUE;
}

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 if (p_jp2->enumcs == 24)
		p_image->color_space = OPJ_CLRSPC_EYCC;
	else if (p_jp2->enumcs == 12)
		p_image->color_space = OPJ_CLRSPC_CMYK;
	else
		p_image->color_space = OPJ_CLRSPC_UNKNOWN;

	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));
	}
	
	/* Apply the color space if needed */
	if(p_jp2->color.jp2_cdef) {
		opj_jp2_apply_cdef(p_image, &(p_jp2->color), p_manager);
	}

	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_calloc(1,sizeof(opj_jp2_t));
	if (jp2) {

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