/*
 * 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 */
	opj_free(jp2->comps);
	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;
	/* Overflow check: prevent integer overflow */
	for (i = 0; i < nr_channels; ++i) {
		cmp = cmap[i].cmp;
		if (old_comps[cmp].h == 0 || old_comps[cmp].w > ((OPJ_UINT32)-1) / sizeof(OPJ_INT32) / old_comps[cmp].h) {
			return;
		}
	}

	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;
		dst = new_comps[i].data;
		max = new_comps[i].w * new_comps[i].h;

		/* Prevent null pointer access */
		if (!src || !dst) {
			for (j = 0; j < nr_channels; ++j) {
				opj_free(new_comps[j].data);
			}
			opj_free(new_comps);
			new_comps = NULL;
			return;
		}

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