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

#define OPJ_UNUSED(x) (void)x

/** @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, false 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 *stream,
                                  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 image Image.
@param color Collector for profile, cdef and pclr data.
@param p_manager the user event manager.
@return true in case of success
*/
static OPJ_BOOL opj_jp2_apply_pclr(opj_image_t *image,
                                   opj_jp2_color_t *color,
                                   opj_event_mgr_t * p_manager);

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

/**
 * Executes 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 launch 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 launch 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);
        if (bleft > (OPJ_OFF_T)(0xFFFFFFFFU - 8U)) {
            opj_event_msg(p_manager, EVT_ERROR,
                          "Cannot handle box sizes higher than 2^32\n");
            return OPJ_FALSE;
        }
        box->length = (OPJ_UINT32)bleft + 8U;
        assert((OPJ_OFF_T)box->length == bleft + 8);
        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 (jp2->comps != NULL) {
        opj_event_msg(p_manager, EVT_WARNING,
                      "Ignoring ihdr box. First ihdr box already read\n");
        return OPJ_TRUE;
    }

    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;

    if (jp2->h < 1 || jp2->w < 1 || jp2->numcomps < 1) {
        opj_event_msg(p_manager, EVT_ERROR,
                      "Wrong values for: w(%d) h(%d) numcomps(%d) (ihdr)\n",
                      jp2->w, jp2->h, jp2->numcomps);
        return OPJ_FALSE;
    }
    if ((jp2->numcomps - 1U) >=
            16384U) { /* unsigned underflow is well defined: 1U <= jp2->numcomps <= 16384U */
        opj_event_msg(p_manager, EVT_ERROR, "Invalid number of components (ihdr)\n");
        return OPJ_FALSE;
    }

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

    jp2->j2k->m_cp.allow_different_bit_depth_sign = (jp2->bpc == 255);
    jp2->j2k->ihdr_w = jp2->w;
    jp2->j2k->ihdr_h = jp2->h;
    jp2->has_ihdr = 1;

    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;
    OPJ_BYTE * l_bpcc_data, * l_current_bpcc_ptr;

    /* preconditions */
    assert(jp2 != 00);
    assert(p_nb_bytes_written != 00);
    l_bpcc_size = 8 + jp2->numcomps;

    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_BOOL *) opj_calloc(nr_channels, sizeof(OPJ_BOOL));
        if (!pcol_usage) {
            opj_event_msg(p_manager, EVT_ERROR, "Unexpected OOM.\n");
            return OPJ_FALSE;
        }
        /* verify that no component is targeted more than once */
        for (i = 0; i < nr_channels; i++) {
            OPJ_BYTE mtyp = cmap[i].mtyp;
            OPJ_BYTE pcol = cmap[i].pcol;
            /* See ISO 15444-1 Table I.14 – MTYPi field values */
            if (mtyp != 0 && mtyp != 1) {
                opj_event_msg(p_manager, EVT_ERROR,
                              "Invalid value for cmap[%d].mtyp = %d.\n", i,
                              mtyp);
                is_sane = OPJ_FALSE;
            } else 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] && mtyp == 1) {
                opj_event_msg(p_manager, EVT_ERROR, "Component %d is mapped twice.\n", pcol);
                is_sane = OPJ_FALSE;
            } else if (mtyp == 0 && 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 if (mtyp == 1 && pcol != i) {
                /* OpenJPEG implementation limitation. See assert(i == pcol); */
                /* in opj_jp2_apply_pclr() */
                opj_event_msg(p_manager, EVT_ERROR,
                              "Implementation limitation: for palette mapping, "
                              "pcol[%d] should be equal to %d, but is equal "
                              "to %d.\n", i, 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");
                    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 OPJ_BOOL opj_jp2_apply_pclr(opj_image_t *image,
                                   opj_jp2_color_t *color,
                                   opj_event_mgr_t * p_manager)
{
    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;

    for (i = 0; i < nr_channels; ++i) {
        /* Palette mapping: */
        cmp = cmap[i].cmp;
        if (image->comps[cmp].data == NULL) {
            opj_event_msg(p_manager, EVT_ERROR,
                          "image->comps[%d].data == NULL in opj_jp2_apply_pclr().\n", i);
            return OPJ_FALSE;
        }
    }

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

    new_comps = (opj_image_comp_t*)
                opj_malloc(nr_channels * sizeof(opj_image_comp_t));
    if (!new_comps) {
        opj_event_msg(p_manager, EVT_ERROR,
                      "Memory allocation failure in opj_jp2_apply_pclr().\n");
        return OPJ_FALSE;
    }
    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_image_data_alloc(sizeof(OPJ_INT32) * old_comps[cmp].w * old_comps[cmp].h);
        if (!new_comps[i].data) {
            while (i > 0) {
                -- i;
                opj_image_data_free(new_comps[i].data);
            }
            opj_free(new_comps);
            opj_event_msg(p_manager, EVT_ERROR,
                          "Memory allocation failure in opj_jp2_apply_pclr().\n");
            return OPJ_FALSE;
        }
        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_image_data_free(new_comps[j].data);
          }
          opj_free(new_comps);
          new_comps = NULL;
          return OPJ_FALSE;
        }

        /* Direct use: */
        if (cmap[i].mtyp == 0) {
            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_image_data_free(old_comps[i].data);
        }
    }

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

    return OPJ_TRUE;
}/* 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(sizeof(OPJ_UINT32) * nr_channels *
                                       nr_entries);
    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));
            if (cielab == NULL) {
                opj_event_msg(p_manager, EVT_ERROR, "Not enough memory for cielab\n");
                return OPJ_FALSE;
            }
            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->j2k->m_specific_param.m_decoder.m_numcomps_to_decode) {
        /* Bypass all JP2 component transforms */
        return OPJ_TRUE;
    }

    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 (!opj_jp2_apply_pclr(p_image, &(jp2->color), p_manager)) {
                    return OPJ_FALSE;
                }
            }
        }

        /* 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;
    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_size = 16 + 4 * jp2->numcl;

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

    OPJ_UNUSED(jp2);

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

OPJ_BOOL opj_jp2_set_threads(opj_jp2_t *jp2, OPJ_UINT32 num_threads)
{
    return opj_j2k_set_threads(jp2->j2k, num_threads);
}

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

    OPJ_UNUSED(p_manager);

    /* 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) {
                if (jp2->jp2_state & JP2_STATE_CODESTREAM) {
                    /* If we already read the codestream, do not error out */
                    /* Needed for data/input/nonregression/issue254.jp2 */
                    opj_event_msg(p_manager, EVT_WARNING,
                                  "Problem with skipping JPEG2000 box, stream error\n");
                    opj_free(l_current_data);
                    return OPJ_TRUE;
                } else {
                    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;
}

/**
 * Executes 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;
    jp2->has_jp2h = 1;

    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;
    }
    if (jp2->has_jp2h == 0) {
        opj_event_msg(p_manager, EVT_ERROR, "JP2H box missing. Required.\n");
        return OPJ_FALSE;
    }
    if (jp2->has_ihdr == 0) {
        opj_event_msg(p_manager, EVT_ERROR, "IHDR box_missing. Required.\n");
        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);

    OPJ_UNUSED(jp2);
    OPJ_UNUSED(p_manager);

    /* 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_decoded_components(opj_jp2_t *p_jp2,
                                        OPJ_UINT32 numcomps,
                                        const OPJ_UINT32* comps_indices,
                                        opj_event_mgr_t * p_manager)
{
    return opj_j2k_set_decoded_components(p_jp2->j2k,
                                          numcomps, comps_indices,
                                          p_manager);
}

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 (p_jp2->j2k->m_specific_param.m_decoder.m_numcomps_to_decode) {
        /* Bypass all JP2 component transforms */
        return OPJ_TRUE;
    }

    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 {
            if (!opj_jp2_apply_pclr(p_image, &(p_jp2->color), p_manager)) {
                return OPJ_FALSE;
            }
        }
    }

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

/* ----------------------------------------------------------------------- */

OPJ_BOOL opj_jp2_encoder_set_extra_options(
    opj_jp2_t *p_jp2,
    const char* const* p_options,
    opj_event_mgr_t * p_manager)
{
    return opj_j2k_encoder_set_extra_options(p_jp2->j2k, p_options, 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];

    OPJ_UNUSED(jp2);

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

    OPJ_UNUSED(jp2);

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