OpenJPEG: update to 2.1 from 1.5
authorCampbell Barton <ideasman42@gmail.com>
Thu, 9 Jun 2016 11:56:29 +0000 (21:56 +1000)
committerCampbell Barton <ideasman42@gmail.com>
Tue, 12 Jul 2016 13:13:30 +0000 (23:13 +1000)
Stream handling has changed so this required changes to how files & memory are accessed.

61 files changed:
build_files/cmake/Modules/FindOpenJPEG.cmake
extern/libopenjpeg/CMakeLists.txt
extern/libopenjpeg/bio.c
extern/libopenjpeg/bio.h
extern/libopenjpeg/cidx_manager.c
extern/libopenjpeg/cidx_manager.h
extern/libopenjpeg/cio.c
extern/libopenjpeg/cio.h
extern/libopenjpeg/dwt.c
extern/libopenjpeg/dwt.h
extern/libopenjpeg/event.c
extern/libopenjpeg/event.h
extern/libopenjpeg/function_list.c [new file with mode: 0644]
extern/libopenjpeg/function_list.h [new file with mode: 0644]
extern/libopenjpeg/image.c
extern/libopenjpeg/image.h
extern/libopenjpeg/indexbox_manager.h
extern/libopenjpeg/invert.c [new file with mode: 0644]
extern/libopenjpeg/invert.h [moved from extern/libopenjpeg/jpt.h with 50% similarity]
extern/libopenjpeg/j2k.c
extern/libopenjpeg/j2k.h
extern/libopenjpeg/jp2.c
extern/libopenjpeg/jp2.h
extern/libopenjpeg/jpt.c [deleted file]
extern/libopenjpeg/mct.c
extern/libopenjpeg/mct.h
extern/libopenjpeg/mqc.c
extern/libopenjpeg/mqc.h
extern/libopenjpeg/openjpeg.c
extern/libopenjpeg/openjpeg.h
extern/libopenjpeg/opj_clock.c [moved from extern/libopenjpeg/j2k_lib.c with 80% similarity]
extern/libopenjpeg/opj_clock.h [moved from extern/libopenjpeg/j2k_lib.h with 78% similarity]
extern/libopenjpeg/opj_codec.h [new file with mode: 0644]
extern/libopenjpeg/opj_config.h
extern/libopenjpeg/opj_config_private.h [new file with mode: 0644]
extern/libopenjpeg/opj_includes.h
extern/libopenjpeg/opj_intmath.h [moved from extern/libopenjpeg/int.h with 54% similarity]
extern/libopenjpeg/opj_inttypes.h [moved from extern/libopenjpeg/license.txt with 66% similarity]
extern/libopenjpeg/opj_malloc.h
extern/libopenjpeg/opj_stdint.h [moved from extern/libopenjpeg/fix.h with 56% similarity]
extern/libopenjpeg/phix_manager.c
extern/libopenjpeg/pi.c
extern/libopenjpeg/pi.h
extern/libopenjpeg/ppix_manager.c
extern/libopenjpeg/raw.c
extern/libopenjpeg/raw.h
extern/libopenjpeg/t1.c
extern/libopenjpeg/t1.h
extern/libopenjpeg/t1_generate_luts.c [new file with mode: 0644]
extern/libopenjpeg/t1_luts.h
extern/libopenjpeg/t2.c
extern/libopenjpeg/t2.h
extern/libopenjpeg/tcd.c
extern/libopenjpeg/tcd.h
extern/libopenjpeg/tgt.c
extern/libopenjpeg/tgt.h
extern/libopenjpeg/thix_manager.c
extern/libopenjpeg/tpix_manager.c
source/blender/imbuf/intern/IMB_filetype.h
source/blender/imbuf/intern/filetype.c
source/blender/imbuf/intern/jp2.c

index d765103..1f82591 100644 (file)
@@ -41,13 +41,14 @@ FIND_PATH(OPENJPEG_INCLUDE_DIR
   HINTS
     ${_openjpeg_SEARCH_DIRS}
   PATH_SUFFIXES
+    openjpeg-2.1
+    include/openjpeg-2.1
     include
-    include/openjpeg-1.5
 )
 
 FIND_LIBRARY(OPENJPEG_LIBRARY
   NAMES
-    openjpeg
+    openjp2
   HINTS
     ${_openjpeg_SEARCH_DIRS}
   PATH_SUFFIXES
index ad49eee..0af2a90 100644 (file)
@@ -31,49 +31,56 @@ set(INC_SYS
 
 )
 
-add_definitions(${OPENJPEG_DEFINES})
+add_definitions(${OPENJPEG_DEFINES} -DUSE_JPIP)
 
 set(SRC
        bio.c
+       cidx_manager.c
        cio.c
        dwt.c
        event.c
+       function_list.c
        image.c
+       invert.c
        j2k.c
-       j2k_lib.c
        jp2.c
-       jpt.c
        mct.c
        mqc.c
        openjpeg.c
+       opj_clock.c
+       phix_manager.c
        pi.c
+       ppix_manager.c
        raw.c
        t1.c
+       t1_generate_luts.c
        t2.c
        tcd.c
        tgt.c
-       cidx_manager.c
-       phix_manager.c
-       ppix_manager.c
        thix_manager.c
        tpix_manager.c
 
        bio.h
+       cidx_manager.h
        cio.h
        dwt.h
        event.h
-       fix.h
+       function_list.h
        image.h
-       int.h
+       indexbox_manager.h
+       invert.h
        j2k.h
-       j2k_lib.h
        jp2.h
-       jpt.h
        mct.h
        mqc.h
        openjpeg.h
+       opj_clock.h
+       opj_codec.h
        opj_includes.h
+       opj_intmath.h
+       opj_inttypes.h
        opj_malloc.h
+       opj_stdint.h
        pi.h
        raw.h
        t1.h
@@ -81,9 +88,6 @@ set(SRC
        t2.h
        tcd.h
        tgt.h
-       cidx_manager.h
-       indexbox_manager.h
-       opj_config.h
 )
 
 blender_add_lib(extern_openjpeg "${SRC}" "${INC}" "${INC_SYS}")
index f04f3e5..5d49580 100644 (file)
@@ -1,9 +1,15 @@
 /*
- * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
- * Copyright (c) 2002-2007, Professor Benoit Macq
+ * 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 and Antonin Descampe
+ * Copyright (c) 2003-2007, Francois-Olivier Devaux 
+ * Copyright (c) 2003-2014, Antonin Descampe
  * Copyright (c) 2005, Herve Drolon, FreeImage Team
  * All rights reserved.
  *
@@ -42,25 +48,25 @@ Write a bit
 @param bio BIO handle
 @param b Bit to write (0 or 1)
 */
-static void bio_putbit(opj_bio_t *bio, unsigned int b);
+static void opj_bio_putbit(opj_bio_t *bio, OPJ_UINT32 b);
 /**
 Read a bit
 @param bio BIO handle
 @return Returns the read bit
 */
-static int bio_getbit(opj_bio_t *bio);
+static OPJ_UINT32 opj_bio_getbit(opj_bio_t *bio);
 /**
 Write a byte
 @param bio BIO handle
-@return Returns 0 if successful, returns 1 otherwise
+@return Returns OPJ_TRUE if successful, returns OPJ_FALSE otherwise
 */
-static int bio_byteout(opj_bio_t *bio);
+static OPJ_BOOL opj_bio_byteout(opj_bio_t *bio);
 /**
 Read a byte
 @param bio BIO handle
-@return Returns 0 if successful, returns 1 otherwise
+@return Returns OPJ_TRUE if successful, returns OPJ_FALSE otherwise
 */
-static int bio_bytein(opj_bio_t *bio);
+static OPJ_BOOL opj_bio_bytein(opj_bio_t *bio);
 
 /*@}*/
 
@@ -72,37 +78,37 @@ static int bio_bytein(opj_bio_t *bio);
 ==========================================================
 */
 
-static int bio_byteout(opj_bio_t *bio) {
+OPJ_BOOL opj_bio_byteout(opj_bio_t *bio) {
        bio->buf = (bio->buf << 8) & 0xffff;
        bio->ct = bio->buf == 0xff00 ? 7 : 8;
        if (bio->bp >= bio->end) {
-               return 1;
+               return OPJ_FALSE;
        }
-       *bio->bp++ = (unsigned char)(bio->buf >> 8);
-       return 0;
+       *bio->bp++ = (OPJ_BYTE)(bio->buf >> 8);
+       return OPJ_TRUE;
 }
 
-static int bio_bytein(opj_bio_t *bio) {
+OPJ_BOOL opj_bio_bytein(opj_bio_t *bio) {
        bio->buf = (bio->buf << 8) & 0xffff;
        bio->ct = bio->buf == 0xff00 ? 7 : 8;
        if (bio->bp >= bio->end) {
-               return 1;
+               return OPJ_FALSE;
        }
        bio->buf |= *bio->bp++;
-       return 0;
+       return OPJ_TRUE;
 }
 
-static void bio_putbit(opj_bio_t *bio, unsigned int b) {
+void opj_bio_putbit(opj_bio_t *bio, OPJ_UINT32 b) {
        if (bio->ct == 0) {
-               bio_byteout(bio);
+               opj_bio_byteout(bio); /* MSD: why not check the return value of this function ? */
        }
        bio->ct--;
        bio->buf |= b << bio->ct;
 }
 
-static int bio_getbit(opj_bio_t *bio) {
+OPJ_UINT32 opj_bio_getbit(opj_bio_t *bio) {
        if (bio->ct == 0) {
-               bio_bytein(bio);
+               opj_bio_bytein(bio); /* MSD: why not check the return value of this function ? */
        }
        bio->ct--;
        return (bio->buf >> bio->ct) & 1;
@@ -114,22 +120,22 @@ static int bio_getbit(opj_bio_t *bio) {
 ==========================================================
 */
 
-opj_bio_t* bio_create(void) {
+opj_bio_t* opj_bio_create(void) {
        opj_bio_t *bio = (opj_bio_t*)opj_malloc(sizeof(opj_bio_t));
        return bio;
 }
 
-void bio_destroy(opj_bio_t *bio) {
+void opj_bio_destroy(opj_bio_t *bio) {
        if(bio) {
                opj_free(bio);
        }
 }
 
-int bio_numbytes(opj_bio_t *bio) {
-       return (int)(bio->bp - bio->start);
+ptrdiff_t opj_bio_numbytes(opj_bio_t *bio) {
+       return (bio->bp - bio->start);
 }
 
-void bio_init_enc(opj_bio_t *bio, unsigned char *bp, int len) {
+void opj_bio_init_enc(opj_bio_t *bio, OPJ_BYTE *bp, OPJ_UINT32 len) {
        bio->start = bp;
        bio->end = bp + len;
        bio->bp = bp;
@@ -137,7 +143,7 @@ void bio_init_enc(opj_bio_t *bio, unsigned char *bp, int len) {
        bio->ct = 8;
 }
 
-void bio_init_dec(opj_bio_t *bio, unsigned char *bp, int len) {
+void opj_bio_init_dec(opj_bio_t *bio, OPJ_BYTE *bp, OPJ_UINT32 len) {
        bio->start = bp;
        bio->end = bp + len;
        bio->bp = bp;
@@ -145,43 +151,44 @@ void bio_init_dec(opj_bio_t *bio, unsigned char *bp, int len) {
        bio->ct = 0;
 }
 
-void bio_write(opj_bio_t *bio, int v, int n) {
-       int i;
-       for (i = n - 1; i >= 0; i--) {
-               bio_putbit(bio, (v >> i) & 1);
+void opj_bio_write(opj_bio_t *bio, OPJ_UINT32 v, OPJ_UINT32 n) {
+       OPJ_UINT32 i;
+       for (i = n - 1; i < n; i--) {
+               opj_bio_putbit(bio, (v >> i) & 1);
        }
 }
 
-int bio_read(opj_bio_t *bio, int n) {
-       int i, v;
+OPJ_UINT32 opj_bio_read(opj_bio_t *bio, OPJ_UINT32 n) {
+       OPJ_UINT32 i;
+    OPJ_UINT32 v;
        v = 0;
-       for (i = n - 1; i >= 0; i--) {
-               v += bio_getbit(bio) << i;
+       for (i = n - 1; i < n; i--) {
+               v += opj_bio_getbit(bio) << i;
        }
        return v;
 }
 
-int bio_flush(opj_bio_t *bio) {
+OPJ_BOOL opj_bio_flush(opj_bio_t *bio) {
        bio->ct = 0;
-       if (bio_byteout(bio)) {
-               return 1;
+       if (! opj_bio_byteout(bio)) {
+               return OPJ_FALSE;
        }
        if (bio->ct == 7) {
                bio->ct = 0;
-               if (bio_byteout(bio)) {
-                       return 1;
+               if (! opj_bio_byteout(bio)) {
+                       return OPJ_FALSE;
                }
        }
-       return 0;
+       return OPJ_TRUE;
 }
 
-int bio_inalign(opj_bio_t *bio) {
+OPJ_BOOL opj_bio_inalign(opj_bio_t *bio) {
        bio->ct = 0;
        if ((bio->buf & 0xff) == 0xff) {
-               if (bio_bytein(bio)) {
-                       return 1;
+               if (! opj_bio_bytein(bio)) {
+                       return OPJ_FALSE;
                }
                bio->ct = 0;
        }
-       return 0;
+       return OPJ_TRUE;
 }
index 764d7cb..fba2428 100644 (file)
@@ -1,9 +1,15 @@
 /*
- * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
- * Copyright (c) 2002-2007, Professor Benoit Macq
+ * 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 and Antonin Descampe
+ * Copyright (c) 2003-2007, Francois-Olivier Devaux 
+ * Copyright (c) 2003-2014, Antonin Descampe
  * Copyright (c) 2005, Herve Drolon, FreeImage Team
  * All rights reserved.
  *
@@ -31,6 +37,9 @@
 
 #ifndef __BIO_H
 #define __BIO_H
+
+#include <stddef.h> /* ptrdiff_t */
+
 /** 
 @file bio.h
 @brief Implementation of an individual bit input-output (BIO)
@@ -46,15 +55,15 @@ Individual bit input-output stream (BIO)
 */
 typedef struct opj_bio {
        /** pointer to the start of the buffer */
-       unsigned char *start;
+       OPJ_BYTE *start;
        /** pointer to the end of the buffer */
-       unsigned char *end;
+       OPJ_BYTE *end;
        /** pointer to the present position in the buffer */
-       unsigned char *bp;
+       OPJ_BYTE *bp;
        /** temporary place where each byte is read or written */
-       unsigned int buf;
+       OPJ_UINT32 buf;
        /** coder : number of bits free to write. decoder : number of bits read */
-       int ct;
+       OPJ_UINT32 ct;
 } opj_bio_t;
 
 /** @name Exported functions */
@@ -64,58 +73,58 @@ typedef struct opj_bio {
 Create a new BIO handle 
 @return Returns a new BIO handle if successful, returns NULL otherwise
 */
-opj_bio_t* bio_create(void);
+opj_bio_t* opj_bio_create(void);
 /**
 Destroy a previously created BIO handle
 @param bio BIO handle to destroy
 */
-void bio_destroy(opj_bio_t *bio);
+void opj_bio_destroy(opj_bio_t *bio);
 /**
 Number of bytes written.
 @param bio BIO handle
 @return Returns the number of bytes written
 */
-int bio_numbytes(opj_bio_t *bio);
+ptrdiff_t opj_bio_numbytes(opj_bio_t *bio);
 /**
 Init encoder
 @param bio BIO handle
 @param bp Output buffer
 @param len Output buffer length 
 */
-void bio_init_enc(opj_bio_t *bio, unsigned char *bp, int len);
+void opj_bio_init_enc(opj_bio_t *bio, OPJ_BYTE *bp, OPJ_UINT32 len);
 /**
 Init decoder
 @param bio BIO handle
 @param bp Input buffer
 @param len Input buffer length 
 */
-void bio_init_dec(opj_bio_t *bio, unsigned char *bp, int len);
+void opj_bio_init_dec(opj_bio_t *bio, OPJ_BYTE *bp, OPJ_UINT32 len);
 /**
 Write bits
 @param bio BIO handle
 @param v Value of bits
 @param n Number of bits to write
 */
-void bio_write(opj_bio_t *bio, int v, int n);
+void opj_bio_write(opj_bio_t *bio, OPJ_UINT32 v, OPJ_UINT32 n);
 /**
 Read bits
 @param bio BIO handle
 @param n Number of bits to read 
 @return Returns the corresponding read number
 */
-int bio_read(opj_bio_t *bio, int n);
+OPJ_UINT32 opj_bio_read(opj_bio_t *bio, OPJ_UINT32 n);
 /**
 Flush bits
 @param bio BIO handle
-@return Returns 1 if successful, returns 0 otherwise
+@return Returns OPJ_TRUE if successful, returns OPJ_FALSE otherwise
 */
-int bio_flush(opj_bio_t *bio);
+OPJ_BOOL opj_bio_flush(opj_bio_t *bio);
 /**
 Passes the ending bits (coming from flushing)
 @param bio BIO handle
-@return Returns 1 if successful, returns 0 otherwise
+@return Returns OPJ_TRUE if successful, returns OPJ_FALSE otherwise
 */
-int bio_inalign(opj_bio_t *bio);
+OPJ_BOOL opj_bio_inalign(opj_bio_t *bio);
 /* ----------------------------------------------------------------------- */
 /*@}*/
 
index f3b251f..ff2dbda 100644 (file)
@@ -1,8 +1,8 @@
 /*
  * $Id: cidx_manager.c 897 2011-08-28 21:43:57Z Kaori.Hagihara@gmail.com $
  *
- * Copyright (c) 2002-2011, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
- * Copyright (c) 2002-2011, Professor Benoit Macq
+ * Copyright (c) 2002-2014, Universite catholique de Louvain (UCL), Belgium
+ * Copyright (c) 2002-2014, Professor Benoit Macq
  * Copyright (c) 2003-2004, Yannick Verschueren
  * Copyright (c) 2010-2011, Kaori Hagihara
  * All rights reserved.
  * @param[in] clen length of j2k codestream
  * @param[in] cio  file output handle
  */
-void write_cptr(int coff, int clen, opj_cio_t *cio);
 
+void opj_write_cptr(int coff, int clen, opj_stream_private_t *cio,
+              opj_event_mgr_t * p_manager );
 
-/* 
- * Write main header index table (box)
- *
- * @param[in] coff offset of j2k codestream
- * @param[in] cstr_info codestream information
- * @param[in] cio  file output handle
- * @return         length of mainmhix box
- */
-int write_mainmhix( int coff, opj_codestream_info_t cstr_info, opj_cio_t *cio);
 
 
-/* 
- * Check if EPH option is used
- *
- * @param[in] coff    offset of j2k codestream
- * @param[in] markers marker information
- * @param[in] marknum number of markers
- * @param[in] cio     file output handle
- * @return            true if EPH is used
- */
-opj_bool check_EPHuse( int coff, opj_marker_info_t *markers, int marknum, opj_cio_t *cio);
 
 
-int write_cidx( int offset, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t cstr_info, int j2klen)
+int opj_write_cidx( int offset, opj_stream_private_t *cio, opj_codestream_info_t cstr_info, int j2klen,
+              opj_event_mgr_t * p_manager )
 {
-  int len, i, lenp;
+  int i;
+  OPJ_OFF_T lenp;
+  OPJ_UINT32 len;
   opj_jp2_box_t *box;
   int num_box = 0;
-  opj_bool  EPHused;
-  (void)image; /* unused ? */
+  OPJ_BOOL  EPHused;
+  OPJ_BYTE l_data_header [4];
 
   lenp = -1;
   box = (opj_jp2_box_t *)opj_calloc( 32, sizeof(opj_jp2_box_t));
@@ -79,133 +64,176 @@ int write_cidx( int offset, opj_cio_t *cio, opj_image_t *image, opj_codestream_i
   for (i=0;i<2;i++){
   
     if(i)
-      cio_seek( cio, lenp);
+      opj_stream_seek(cio,lenp,p_manager);
+
 
-    lenp = cio_tell( cio);
+    lenp = opj_stream_tell (cio);
 
-    cio_skip( cio, 4);              /* L [at the end] */
-    cio_write( cio, JPIP_CIDX, 4);  /* CIDX           */
-    write_cptr( offset, cstr_info.codestream_size, cio);
+    opj_stream_skip(cio, 4, p_manager); /* L [at the end] */
 
-    write_manf( i, num_box, box, cio);
+    opj_write_bytes(l_data_header,JPIP_CIDX,4); /* CIDX */
+    opj_stream_write_data(cio,l_data_header,4,p_manager);
+
+    opj_write_cptr( offset, cstr_info.codestream_size, cio,p_manager);
+
+    opj_write_manf( i, num_box, box, cio,p_manager);
     
     num_box = 0;
-    box[num_box].length = write_mainmhix( offset, cstr_info, cio);
+    box[num_box].length = (OPJ_UINT32)opj_write_mainmhix( offset, cstr_info, cio,p_manager);
     box[num_box].type = JPIP_MHIX;
     num_box++;
 
-    box[num_box].length = write_tpix( offset, cstr_info, j2klen, cio);
+    box[num_box].length = (OPJ_UINT32)opj_write_tpix( offset, cstr_info, j2klen, cio,p_manager);
     box[num_box].type = JPIP_TPIX;
     num_box++;
       
-    box[num_box].length = write_thix( offset, cstr_info, cio);
+    box[num_box].length = (OPJ_UINT32)opj_write_thix( offset, cstr_info, cio, p_manager);
     box[num_box].type = JPIP_THIX;
     num_box++;
 
-    EPHused = check_EPHuse( offset, cstr_info.marker, cstr_info.marknum, cio);
+    EPHused = opj_check_EPHuse( offset, cstr_info.marker, cstr_info.marknum, cio,p_manager);
       
-    box[num_box].length = write_ppix( offset, cstr_info, EPHused, j2klen, cio);
+    box[num_box].length = (OPJ_UINT32)opj_write_ppix( offset, cstr_info, EPHused, j2klen, cio,p_manager);
     box[num_box].type = JPIP_PPIX;
     num_box++;
     
-    box[num_box].length = write_phix( offset, cstr_info, EPHused, j2klen, cio);
+    box[num_box].length = (OPJ_UINT32)opj_write_phix( offset, cstr_info, EPHused, j2klen, cio,p_manager);
     box[num_box].type = JPIP_PHIX;
     num_box++;
       
-    len = cio_tell( cio)-lenp;
-    cio_seek( cio, lenp);
-    cio_write( cio, len, 4);        /* L             */
-    cio_seek( cio, lenp+len);
+    len = (OPJ_UINT32) (opj_stream_tell(cio)-lenp);
+    opj_stream_seek(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);
   }
 
   opj_free( box);
   
-  return len;
+  return (int)len;
 }
 
-void write_cptr(int coff, int clen, opj_cio_t *cio)
+
+
+void opj_write_cptr(int coff, int clen, opj_stream_private_t *cio,
+              opj_event_mgr_t * p_manager )
 {
-  int len, lenp;
-
-  lenp = cio_tell( cio);
-  cio_skip( cio, 4);               /* L [at the end]     */
-  cio_write( cio, JPIP_CPTR, 4);   /* T                  */
-  cio_write( cio, 0, 2);           /* DR  A PRECISER !!  */
-  cio_write( cio, 0, 2);           /* CONT               */
-  cio_write( cio, coff, 8);    /* COFF A PRECISER !! */
-  cio_write( cio, clen, 8);    /* CLEN               */
-  len = cio_tell( cio) - lenp;
-  cio_seek( cio, lenp);
-  cio_write( cio, len, 4);         /* L                  */
-  cio_seek( cio, lenp+len);
+  OPJ_BYTE l_data_header [3*8];
+  OPJ_UINT32 len;
+  OPJ_OFF_T lenp;
+
+
+  lenp = opj_stream_tell(cio);
+  opj_stream_skip( cio, 4, p_manager);               /* L [at the end]     */
+  opj_write_bytes( l_data_header, JPIP_CPTR, 4);   /* T                  */
+  opj_write_bytes( l_data_header+4, 0, 2);           /* DR  A PRECISER !!  */
+  opj_write_bytes( l_data_header+6, 0, 2);           /* CONT               */
+  opj_write_bytes( l_data_header+8, (OPJ_UINT32)coff, 8);    /* COFF A PRECISER !! */
+  opj_write_bytes( l_data_header+16, (OPJ_UINT32)clen, 8);    /* CLEN               */
+  opj_stream_write_data(cio,l_data_header,3*8,p_manager);
+
+  len = (OPJ_UINT32) (opj_stream_tell(cio) - lenp);
+  opj_stream_seek(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);
+
 }
 
-void write_manf(int second, int v, opj_jp2_box_t *box, opj_cio_t *cio)
+
+
+void opj_write_manf(int second, 
+                    int v, 
+                    opj_jp2_box_t *box, 
+                    opj_stream_private_t *cio,
+                    opj_event_mgr_t * p_manager )
 {
-  int len, lenp, i;
+  OPJ_BYTE l_data_header [4];
+  int i;
+  OPJ_UINT32 len;
+  OPJ_OFF_T lenp;
   
-  lenp = cio_tell( cio); 
-  cio_skip( cio, 4);                         /* L [at the end]                    */
-  cio_write( cio, JPIP_MANF,4);              /* T                                 */
+  lenp = opj_stream_tell(cio);
+  opj_stream_skip( cio, 4, p_manager);             /* L [at the end]     */
+  opj_write_bytes( l_data_header, JPIP_MANF, 4);   /* T                  */
+  opj_stream_write_data(cio,l_data_header,4,p_manager);
 
   if (second){                          /* Write only during the second pass */
     for( i=0; i<v; i++){
-      cio_write( cio, box[i].length, 4);  /* Box length                     */ 
-      cio_write( cio, box[i].type, 4); /* Box type                       */
+      opj_write_bytes( l_data_header, box[i].length, 4); /* Box length                     */
+      opj_stream_write_data(cio,l_data_header,4,p_manager);
+      opj_write_bytes( l_data_header, box[i].type, 4); /* Box type                       */
+      opj_stream_write_data(cio,l_data_header,4,p_manager);
     }
   }
 
-  len = cio_tell( cio) - lenp;
-  cio_seek( cio, lenp);
-  cio_write( cio, len, 4);                   /* L                                 */
-  cio_seek( cio, lenp+len);
+  len = (OPJ_UINT32) (opj_stream_tell(cio) - lenp);
+  opj_stream_seek(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);
 }
 
-int write_mainmhix( int coff, opj_codestream_info_t cstr_info, opj_cio_t *cio)
+
+int opj_write_mainmhix( int coff, opj_codestream_info_t cstr_info, opj_stream_private_t *cio,
+              opj_event_mgr_t * p_manager )
 {
-  int i;
-  int len, lenp;
+  OPJ_BYTE l_data_header [8];
+  OPJ_UINT32 i;
+  OPJ_UINT32 len;
+  OPJ_OFF_T lenp;
   
-  lenp = cio_tell( cio);
-  cio_skip( cio, 4);                               /* L [at the end]                    */
-  cio_write( cio, JPIP_MHIX, 4);                   /* MHIX                              */
-
-  cio_write( cio, cstr_info.main_head_end-cstr_info.main_head_start+1, 8);        /* TLEN                              */
-
-  for(i = 1; i < cstr_info.marknum; i++){    /* Marker restricted to 1 apparition, skip SOC marker */
-    cio_write( cio, cstr_info.marker[i].type, 2);
-    cio_write( cio, 0, 2);
-    cio_write( cio, cstr_info.marker[i].pos-coff, 8);
-    cio_write( cio, cstr_info.marker[i].len, 2);
+  lenp = opj_stream_tell (cio);
+  opj_stream_skip(cio, 4, p_manager);               /* L [at the end]                    */
+  opj_write_bytes(l_data_header,JPIP_MHIX,4);       /* MHIX                              */
+  opj_stream_write_data(cio,l_data_header,4,p_manager);
+
+  opj_write_bytes(l_data_header, (OPJ_UINT32)(cstr_info.main_head_end-cstr_info.main_head_start+1), 8);        /* TLEN                              */
+  opj_stream_write_data(cio,l_data_header,8,p_manager);
+
+  for(i = 1; i < (OPJ_UINT32)cstr_info.marknum; i++){    /* Marker restricted to 1 apparition, skip SOC marker */
+    opj_write_bytes( l_data_header, cstr_info.marker[i].type, 2);
+    opj_write_bytes( l_data_header+2, 0, 2);
+    opj_stream_write_data(cio,l_data_header,4,p_manager);
+    opj_write_bytes( l_data_header,(OPJ_UINT32) (cstr_info.marker[i].pos-coff), 8);
+    opj_stream_write_data(cio,l_data_header,8,p_manager);
+    opj_write_bytes( l_data_header, (OPJ_UINT32)cstr_info.marker[i].len, 2);
+    opj_stream_write_data(cio,l_data_header,2,p_manager);
   }
 
-  len = cio_tell( cio) - lenp;
-  cio_seek( cio, lenp);
-  cio_write( cio, len, 4);        /* L           */
-  cio_seek( cio, lenp+len);
+  len = (OPJ_UINT32) (opj_stream_tell(cio)-lenp);
+  opj_stream_seek(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;
+  return (int)len;
 }
 
-opj_bool check_EPHuse( int coff, opj_marker_info_t *markers, int marknum, opj_cio_t *cio)
+OPJ_BOOL opj_check_EPHuse( int coff, opj_marker_info_t *markers, int marknum, opj_stream_private_t *cio,
+              opj_event_mgr_t * p_manager )
 {
-  opj_bool EPHused = OPJ_FALSE;
+  OPJ_BYTE l_data_header [4];
+  OPJ_BOOL EPHused = OPJ_FALSE;
   int i=0;
-  int org_pos;
+  OPJ_OFF_T org_pos;
   unsigned int Scod;
 
-  for(i = 0; i < marknum; i++){
-    if( markers[i].type == J2K_MS_COD){
-      org_pos = cio_tell( cio);
-      cio_seek( cio, coff+markers[i].pos+2);
-      
-      Scod = cio_read( cio, 1);
+  for(i = 0; i < marknum; i++)
+    {
+    if( markers[i].type == J2K_MS_COD)
+      {
+      org_pos = opj_stream_tell(cio);
+      opj_stream_seek(cio, coff+markers[i].pos+2,p_manager);
+
+      opj_stream_read_data(cio,l_data_header,1,p_manager);
+      opj_read_bytes(l_data_header,&Scod,1);
       if( ((Scod >> 2) & 1))
-       EPHused = OPJ_TRUE;
-      cio_seek( cio, org_pos);
+        EPHused = OPJ_TRUE;
+      opj_stream_seek( cio, org_pos, p_manager);
 
       break;
-    }
-  }    
+      }
+    }    
   return EPHused;
 }
index 23eebd5..d0bbef8 100644 (file)
@@ -1,8 +1,8 @@
 /*
  * $Id: cidx_manager.h 897 2011-08-28 21:43:57Z Kaori.Hagihara@gmail.com $
  *
- * Copyright (c) 2002-2011, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
- * Copyright (c) 2002-2011, Professor Benoit Macq
+ * Copyright (c) 2002-2014, Universite catholique de Louvain (UCL), Belgium
+ * Copyright (c) 2002-2014, Professor Benoit Macq
  * Copyright (c) 2003-2004, Yannick Verschueren
  * Copyright (c) 2010-2011, Kaori Hagihara
  * All rights reserved.
  * @param[in] j2klen    length of j2k codestream
  * @return              length of cidx box
  */
-int write_cidx( int offset, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t cstr_info, int j2klen);
+int opj_write_cidx( int offset, opj_stream_private_t *cio, opj_codestream_info_t cstr_info, int j2klen,
+              opj_event_mgr_t * p_manager );
 
+/* 
+ * Check if EPH option is used
+ *
+ * @param[in] coff    offset of j2k codestream
+ * @param[in] markers marker information
+ * @param[in] marknum number of markers
+ * @param[in] cio     file output handle
+ * @return            true if EPH is used
+ */
+OPJ_BOOL opj_check_EPHuse( int coff, opj_marker_info_t *markers, int marknum, opj_stream_private_t *cio,
+              opj_event_mgr_t * p_manager );
 
 #endif      /* !CIDX_MANAGER_H_ */
index 97cccea..1fc2393 100644 (file)
@@ -1,10 +1,18 @@
 /*
- * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
- * Copyright (c) 2002-2007, Professor Benoit Macq
+ * 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 and Antonin Descampe
+ * Copyright (c) 2003-2007, Francois-Olivier Devaux 
+ * Copyright (c) 2003-2014, Antonin Descampe
  * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * 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
  */
 
 #include "opj_includes.h"
-#include <assert.h>
 
 /* ----------------------------------------------------------------------- */
 
-opj_cio_t* OPJ_CALLCONV opj_cio_open(opj_common_ptr cinfo, unsigned char *buffer, int length) {
-       opj_cp_t *cp = NULL;
-       opj_cio_t *cio = (opj_cio_t*)opj_malloc(sizeof(opj_cio_t));
-       if(!cio) return NULL;
-       cio->cinfo = cinfo;
-       if(buffer && length) {
-               /* wrap a user buffer containing the encoded image */
-               cio->openmode = OPJ_STREAM_READ;
-               cio->buffer = buffer;
-               cio->length = length;
-       }
-       else if(!buffer && !length && cinfo) {
-               /* allocate a buffer for the encoded image */
-               cio->openmode = OPJ_STREAM_WRITE;
-               switch(cinfo->codec_format) {
-                       case CODEC_J2K:
-                               cp = ((opj_j2k_t*)cinfo->j2k_handle)->cp;
-                               break;
-                       case CODEC_JP2:
-                               cp = ((opj_jp2_t*)cinfo->jp2_handle)->j2k->cp;
-                               break;
-                       default:
-                               opj_free(cio);
-                               return NULL;
-               }
-               cio->length = (unsigned int) (0.1625 * cp->img_size + 2000); /* 0.1625 = 1.3/8 and 2000 bytes as a minimum for headers */
-               cio->buffer = (unsigned char *)opj_malloc(cio->length);
-               if(!cio->buffer) {
-                       opj_event_msg(cio->cinfo, EVT_ERROR, "Error allocating memory for compressed bitstream\n");
-                       opj_free(cio);
-                       return NULL;
-               }
+
+/* ----------------------------------------------------------------------- */
+
+void opj_write_bytes_BE (OPJ_BYTE * p_buffer, OPJ_UINT32 p_value, OPJ_UINT32 p_nb_bytes)
+{
+       const OPJ_BYTE * l_data_ptr = ((const OPJ_BYTE *) &p_value) + p_nb_bytes;
+
+       assert(p_nb_bytes > 0 && p_nb_bytes <=  sizeof(OPJ_UINT32));
+
+       memcpy(p_buffer,l_data_ptr,p_nb_bytes);
+}
+
+void opj_write_bytes_LE (OPJ_BYTE * p_buffer, OPJ_UINT32 p_value, OPJ_UINT32 p_nb_bytes)
+{
+       const OPJ_BYTE * l_data_ptr = ((const OPJ_BYTE *) &p_value) + p_nb_bytes - 1;
+       OPJ_UINT32 i;
+
+       assert(p_nb_bytes > 0 && p_nb_bytes <= sizeof(OPJ_UINT32));
+
+       for     (i=0;i<p_nb_bytes;++i) {
+               *(p_buffer++) = *(l_data_ptr--);
+       }
+}
+
+void opj_read_bytes_BE(const OPJ_BYTE * p_buffer, OPJ_UINT32 * p_value, OPJ_UINT32 p_nb_bytes)
+{
+       OPJ_BYTE * l_data_ptr = ((OPJ_BYTE *) p_value);
+
+       assert(p_nb_bytes > 0 && p_nb_bytes <= sizeof(OPJ_UINT32));
+
+       *p_value = 0;
+       memcpy(l_data_ptr+4-p_nb_bytes,p_buffer,p_nb_bytes);
+}
+
+void opj_read_bytes_LE(const OPJ_BYTE * p_buffer, OPJ_UINT32 * p_value, OPJ_UINT32 p_nb_bytes)
+{
+       OPJ_BYTE * l_data_ptr = ((OPJ_BYTE *) p_value) + p_nb_bytes-1;
+       OPJ_UINT32 i;
+
+       assert(p_nb_bytes > 0 && p_nb_bytes <= sizeof(OPJ_UINT32));
+
+       *p_value = 0;
+       for (i=0;i<p_nb_bytes;++i) {
+               *(l_data_ptr--) = *(p_buffer++);
+       }
+}
+
+void opj_write_double_BE(OPJ_BYTE * p_buffer, OPJ_FLOAT64 p_value)
+{
+       const OPJ_BYTE * l_data_ptr = ((const OPJ_BYTE *) &p_value);
+       memcpy(p_buffer,l_data_ptr,sizeof(OPJ_FLOAT64));
+}
+
+void opj_write_double_LE(OPJ_BYTE * p_buffer, OPJ_FLOAT64 p_value)
+{
+       const OPJ_BYTE * l_data_ptr = ((const OPJ_BYTE *) &p_value) + sizeof(OPJ_FLOAT64) - 1;
+       OPJ_UINT32 i;
+       for     (i=0;i<sizeof(OPJ_FLOAT64);++i) {
+               *(p_buffer++) = *(l_data_ptr--);
+       }
+}
+
+void opj_read_double_BE(const OPJ_BYTE * p_buffer, OPJ_FLOAT64 * p_value)
+{
+       OPJ_BYTE * l_data_ptr = ((OPJ_BYTE *) p_value);
+       memcpy(l_data_ptr,p_buffer,sizeof(OPJ_FLOAT64));
+}
+
+void opj_read_double_LE(const OPJ_BYTE * p_buffer, OPJ_FLOAT64 * p_value)
+{
+       OPJ_BYTE * l_data_ptr = ((OPJ_BYTE *) p_value) + sizeof(OPJ_FLOAT64)-1;
+       OPJ_UINT32 i;
+       for (i=0;i<sizeof(OPJ_FLOAT64);++i) {
+               *(l_data_ptr--) = *(p_buffer++);
+       }
+}
+
+void opj_write_float_BE(OPJ_BYTE * p_buffer, OPJ_FLOAT32 p_value)
+{
+       const OPJ_BYTE * l_data_ptr = ((const OPJ_BYTE *) &p_value);
+       memcpy(p_buffer,l_data_ptr,sizeof(OPJ_FLOAT32));
+}
+
+void opj_write_float_LE(OPJ_BYTE * p_buffer, OPJ_FLOAT32 p_value)
+{
+       const OPJ_BYTE * l_data_ptr = ((const OPJ_BYTE *) &p_value) + sizeof(OPJ_FLOAT32) - 1;
+       OPJ_UINT32 i;
+       for     (i=0;i<sizeof(OPJ_FLOAT32);++i) {
+               *(p_buffer++) = *(l_data_ptr--);
+       }
+}
+
+void opj_read_float_BE(const OPJ_BYTE * p_buffer, OPJ_FLOAT32 * p_value)
+{
+       OPJ_BYTE * l_data_ptr = ((OPJ_BYTE *) p_value);
+       memcpy(l_data_ptr,p_buffer,sizeof(OPJ_FLOAT32));
+}
+
+void opj_read_float_LE(const OPJ_BYTE * p_buffer, OPJ_FLOAT32 * p_value)
+{
+       OPJ_BYTE * l_data_ptr = ((OPJ_BYTE *) p_value) + sizeof(OPJ_FLOAT32)-1;
+       OPJ_UINT32 i;
+       for     (i=0;i<sizeof(OPJ_FLOAT32);++i) {
+               *(l_data_ptr--) = *(p_buffer++);
+       }
+}
+
+opj_stream_t* OPJ_CALLCONV opj_stream_create(OPJ_SIZE_T p_buffer_size,OPJ_BOOL l_is_input)
+{
+       opj_stream_private_t * l_stream = 00;
+       l_stream = (opj_stream_private_t*) opj_malloc(sizeof(opj_stream_private_t));
+       if (! l_stream) {
+               return 00;
+       }
+
+       memset(l_stream,0,sizeof(opj_stream_private_t));
+       l_stream->m_buffer_size = p_buffer_size;
+       l_stream->m_stored_data = (OPJ_BYTE *) opj_malloc(p_buffer_size);
+       if (! l_stream->m_stored_data) {
+               opj_free(l_stream);
+               return 00;
+       }
+
+       l_stream->m_current_data = l_stream->m_stored_data;
+
+       if (l_is_input) {
+               l_stream->m_status |= opj_stream_e_input;
+               l_stream->m_opj_skip = opj_stream_read_skip;
+               l_stream->m_opj_seek = opj_stream_read_seek;
        }
        else {
-               opj_free(cio);
-               return NULL;
+               l_stream->m_status |= opj_stream_e_output;
+               l_stream->m_opj_skip = opj_stream_write_skip;
+               l_stream->m_opj_seek = opj_stream_write_seek;
        }
 
-       /* Initialize byte IO */
-       cio->start = cio->buffer;
-       cio->end = cio->buffer + cio->length;
-       cio->bp = cio->buffer;
+       l_stream->m_read_fn = opj_stream_default_read;
+       l_stream->m_write_fn = opj_stream_default_write;
+       l_stream->m_skip_fn = opj_stream_default_skip;
+       l_stream->m_seek_fn = opj_stream_default_seek;
 
-       return cio;
+       return (opj_stream_t *) l_stream;
 }
 
-void OPJ_CALLCONV opj_cio_close(opj_cio_t *cio) {
-       if(cio) {
-               if(cio->openmode == OPJ_STREAM_WRITE) {
-                       /* destroy the allocated buffer */
-                       opj_free(cio->buffer);
+opj_stream_t* OPJ_CALLCONV opj_stream_default_create(OPJ_BOOL l_is_input)
+{
+       return opj_stream_create(OPJ_J2K_STREAM_CHUNK_SIZE,l_is_input);
+}
+
+void OPJ_CALLCONV opj_stream_destroy(opj_stream_t* p_stream)
+{
+       opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream;
+       
+       if (l_stream) {
+               if (l_stream->m_free_user_data_fn) {
+                       l_stream->m_free_user_data_fn(l_stream->m_user_data);
                }
-               /* destroy the cio */
-               opj_free(cio);
+               opj_free(l_stream->m_stored_data);
+               l_stream->m_stored_data = 00;
+               opj_free(l_stream);
        }
 }
 
+void OPJ_CALLCONV opj_stream_set_read_function(opj_stream_t* p_stream, opj_stream_read_fn p_function)
+{
+       opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream;
 
-/* ----------------------------------------------------------------------- */
+       if ((!l_stream) || (! (l_stream->m_status & opj_stream_e_input))) {
+               return;
+       }
 
-/*
- * Get position in byte stream.
- */
-int OPJ_CALLCONV cio_tell(opj_cio_t *cio) {
-       return cio->bp - cio->start;
+       l_stream->m_read_fn = p_function;
 }
 
-/*
- * Set position in byte stream.
- *
- * pos : position, in number of bytes, from the beginning of the stream
- */
-void OPJ_CALLCONV cio_seek(opj_cio_t *cio, int pos) {
-  assert((cio->start + pos) <= cio->end);
-       cio->bp = cio->start + pos;
+void OPJ_CALLCONV opj_stream_set_seek_function(opj_stream_t* p_stream, opj_stream_seek_fn p_function)
+{
+       opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream;
+       
+       if (!l_stream) {
+               return;
+       }
+       l_stream->m_seek_fn = p_function;
 }
 
-/*
- * Number of bytes left before the end of the stream.
- */
-int cio_numbytesleft(opj_cio_t *cio) {
-  assert((cio->end - cio->bp) >= 0);
-       return cio->end - cio->bp;
+void OPJ_CALLCONV opj_stream_set_write_function(opj_stream_t* p_stream, opj_stream_write_fn p_function)
+{
+       opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream;
+       
+       if ((!l_stream )|| (! (l_stream->m_status & opj_stream_e_output))) {
+               return;
+       }
+
+       l_stream->m_write_fn = p_function;
 }
 
-/*
- * Get pointer to the current position in the stream.
- */
-unsigned char *cio_getbp(opj_cio_t *cio) {
-       return cio->bp;
+void OPJ_CALLCONV opj_stream_set_skip_function(opj_stream_t* p_stream, opj_stream_skip_fn p_function)
+{
+       opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream;
+       
+       if (! l_stream) {
+               return;
+       }
+
+       l_stream->m_skip_fn = p_function;
 }
 
-/*
- * Write a byte.
- */
-opj_bool cio_byteout(opj_cio_t *cio, unsigned char v) {
-       if (cio->bp >= cio->end) {
-               opj_event_msg(cio->cinfo, EVT_ERROR, "write error\n");
-               return OPJ_FALSE;
+void OPJ_CALLCONV opj_stream_set_user_data(opj_stream_t* p_stream, void * p_data, opj_stream_free_user_data_fn p_function)
+{
+       opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream;
+       if (!l_stream)
+               return;
+       l_stream->m_user_data = p_data;
+  l_stream->m_free_user_data_fn = p_function;
+}
+
+void OPJ_CALLCONV opj_stream_set_user_data_length(opj_stream_t* p_stream, OPJ_UINT64 data_length)
+{
+       opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream;
+       if (!l_stream)
+               return;
+       l_stream->m_user_data_length = data_length;
+}
+
+OPJ_SIZE_T opj_stream_read_data (opj_stream_private_t * p_stream,OPJ_BYTE * p_buffer, OPJ_SIZE_T p_size, opj_event_mgr_t * p_event_mgr)
+{
+       OPJ_SIZE_T l_read_nb_bytes = 0;
+       if (p_stream->m_bytes_in_buffer >= p_size) {
+               memcpy(p_buffer,p_stream->m_current_data,p_size);
+               p_stream->m_current_data += p_size;
+               p_stream->m_bytes_in_buffer -= p_size;
+               l_read_nb_bytes += p_size;
+               p_stream->m_byte_offset += (OPJ_OFF_T)p_size;
+               return l_read_nb_bytes;
        }
-       *cio->bp++ = v;
+
+       /* we are now in the case when the remaining data if not sufficient */
+       if (p_stream->m_status & opj_stream_e_end) {
+               l_read_nb_bytes += p_stream->m_bytes_in_buffer;
+               memcpy(p_buffer,p_stream->m_current_data,p_stream->m_bytes_in_buffer);
+               p_stream->m_current_data += p_stream->m_bytes_in_buffer;
+               p_stream->m_byte_offset += (OPJ_OFF_T)p_stream->m_bytes_in_buffer;
+               p_stream->m_bytes_in_buffer = 0;
+               return l_read_nb_bytes ? l_read_nb_bytes : (OPJ_SIZE_T)-1;
+       }
+
+       /* the flag is not set, we copy data and then do an actual read on the stream */
+       if (p_stream->m_bytes_in_buffer) {
+               l_read_nb_bytes += p_stream->m_bytes_in_buffer;
+               memcpy(p_buffer,p_stream->m_current_data,p_stream->m_bytes_in_buffer);
+               p_stream->m_current_data = p_stream->m_stored_data;
+               p_buffer += p_stream->m_bytes_in_buffer;
+               p_size -= p_stream->m_bytes_in_buffer;
+               p_stream->m_byte_offset += (OPJ_OFF_T)p_stream->m_bytes_in_buffer;
+               p_stream->m_bytes_in_buffer = 0;
+       }
+       else {
+    /* case where we are already at the end of the buffer
+       so reset the m_current_data to point to the start of the
+       stored buffer to get ready to read from disk*/
+               p_stream->m_current_data = p_stream->m_stored_data;
+       }
+
+       while(1){
+               /* we should read less than a chunk -> read a chunk */
+               if (p_size < p_stream->m_buffer_size) {
+                       /* we should do an actual read on the media */
+                       p_stream->m_bytes_in_buffer = p_stream->m_read_fn(p_stream->m_stored_data,p_stream->m_buffer_size,p_stream->m_user_data);
+
+                       if (p_stream->m_bytes_in_buffer == (OPJ_SIZE_T)-1) {
+                               /* end of stream */
+                               opj_event_msg(p_event_mgr, EVT_INFO, "Stream reached its end !\n");
+
+                               p_stream->m_bytes_in_buffer = 0;
+                               p_stream->m_status |= opj_stream_e_end;
+                               /* end of stream */
+                               return l_read_nb_bytes ? l_read_nb_bytes : (OPJ_SIZE_T)-1;
+                       }
+                       else if (p_stream->m_bytes_in_buffer < p_size) {
+                               /* not enough data */
+                               l_read_nb_bytes += p_stream->m_bytes_in_buffer;
+                               memcpy(p_buffer,p_stream->m_current_data,p_stream->m_bytes_in_buffer);
+                               p_stream->m_current_data = p_stream->m_stored_data;
+                               p_buffer += p_stream->m_bytes_in_buffer;
+                               p_size -= p_stream->m_bytes_in_buffer;
+                               p_stream->m_byte_offset += (OPJ_OFF_T)p_stream->m_bytes_in_buffer;
+                               p_stream->m_bytes_in_buffer = 0;
+                       }
+                       else {
+                               l_read_nb_bytes += p_size;
+                               memcpy(p_buffer,p_stream->m_current_data,p_size);
+                               p_stream->m_current_data += p_size;
+                               p_stream->m_bytes_in_buffer -= p_size;
+                               p_stream->m_byte_offset += (OPJ_OFF_T)p_size;
+                               return l_read_nb_bytes;
+                       }
+               }
+               else {
+                       /* direct read on the dest buffer */
+                       p_stream->m_bytes_in_buffer = p_stream->m_read_fn(p_buffer,p_size,p_stream->m_user_data);
+
+                       if (p_stream->m_bytes_in_buffer == (OPJ_SIZE_T)-1) {
+                               /*  end of stream */
+                               opj_event_msg(p_event_mgr, EVT_INFO, "Stream reached its end !\n");
+
+                               p_stream->m_bytes_in_buffer = 0;
+                               p_stream->m_status |= opj_stream_e_end;
+                               /* end of stream */
+                               return l_read_nb_bytes ? l_read_nb_bytes : (OPJ_SIZE_T)-1;
+                       }
+                       else if (p_stream->m_bytes_in_buffer < p_size) {
+                               /* not enough data */
+                               l_read_nb_bytes += p_stream->m_bytes_in_buffer;
+                               p_stream->m_current_data = p_stream->m_stored_data;
+                               p_buffer += p_stream->m_bytes_in_buffer;
+                               p_size -= p_stream->m_bytes_in_buffer;
+                               p_stream->m_byte_offset += (OPJ_OFF_T)p_stream->m_bytes_in_buffer;
+                               p_stream->m_bytes_in_buffer = 0;
+                       }
+                       else {
+                               /* we have read the exact size */
+                               l_read_nb_bytes += p_stream->m_bytes_in_buffer;
+                               p_stream->m_byte_offset += (OPJ_OFF_T)p_stream->m_bytes_in_buffer;
+                               p_stream->m_current_data = p_stream->m_stored_data;
+                               p_stream->m_bytes_in_buffer = 0;
+                               return l_read_nb_bytes;
+                       }
+               }
+       }
+}
+
+OPJ_SIZE_T opj_stream_write_data (opj_stream_private_t * p_stream,
+                                                                 const OPJ_BYTE * p_buffer,
+                                                                 OPJ_SIZE_T p_size, 
+                                                                 opj_event_mgr_t * p_event_mgr)
+{
+       OPJ_SIZE_T l_remaining_bytes = 0;
+       OPJ_SIZE_T l_write_nb_bytes = 0;
+
+       if (p_stream->m_status & opj_stream_e_error) {
+               return (OPJ_SIZE_T)-1;
+       }
+
+       while(1) {
+               l_remaining_bytes = p_stream->m_buffer_size - p_stream->m_bytes_in_buffer;
+               
+               /* we have more memory than required */
+               if (l_remaining_bytes >= p_size) {
+                       memcpy(p_stream->m_current_data, p_buffer, p_size);
+                       
+                       p_stream->m_current_data += p_size;
+                       p_stream->m_bytes_in_buffer += p_size;
+                       l_write_nb_bytes += p_size;
+                       p_stream->m_byte_offset += (OPJ_OFF_T)p_size;
+                       
+                       return l_write_nb_bytes;
+               }
+
+               /* we copy data and then do an actual read on the stream */
+               if (l_remaining_bytes) {
+                       l_write_nb_bytes += l_remaining_bytes;
+                       
+                       memcpy(p_stream->m_current_data,p_buffer,l_remaining_bytes);
+                       
+                       p_stream->m_current_data = p_stream->m_stored_data;
+                       
+                       p_buffer += l_remaining_bytes;
+                       p_size -= l_remaining_bytes;
+                       p_stream->m_bytes_in_buffer += l_remaining_bytes;
+                       p_stream->m_byte_offset += (OPJ_OFF_T)l_remaining_bytes;
+               }
+
+               if (! opj_stream_flush(p_stream, p_event_mgr)) {
+                       return (OPJ_SIZE_T)-1;
+               }
+       }
+
+}
+
+OPJ_BOOL opj_stream_flush (opj_stream_private_t * p_stream, opj_event_mgr_t * p_event_mgr)
+{
+       /* the number of bytes written on the media. */
+       OPJ_SIZE_T l_current_write_nb_bytes = 0;
+
+       p_stream->m_current_data = p_stream->m_stored_data;
+
+       while (p_stream->m_bytes_in_buffer) {
+               /* we should do an actual write on the media */
+               l_current_write_nb_bytes = p_stream->m_write_fn(p_stream->m_current_data,
+                                                                                                               p_stream->m_bytes_in_buffer,
+                                                                                                               p_stream->m_user_data);
+               
+               if (l_current_write_nb_bytes == (OPJ_SIZE_T)-1) {
+                       p_stream->m_status |= opj_stream_e_error;
+                       opj_event_msg(p_event_mgr, EVT_INFO, "Error on writing stream!\n");
+
+                       return OPJ_FALSE;
+               }
+
+               p_stream->m_current_data += l_current_write_nb_bytes;
+               p_stream->m_bytes_in_buffer -= l_current_write_nb_bytes;
+       }
+
+       p_stream->m_current_data = p_stream->m_stored_data;
+       
        return OPJ_TRUE;
 }
 
-/*
- * Read a byte.
- */
-unsigned char cio_bytein(opj_cio_t *cio) {
-  assert(cio->bp >= cio->start);
-       if (cio->bp >= cio->end) {
-               opj_event_msg(cio->cinfo, EVT_ERROR, "read error: passed the end of the codestream (start = %d, current = %d, end = %d\n", cio->start, cio->bp, cio->end);
-               return 0;
+OPJ_OFF_T opj_stream_read_skip (opj_stream_private_t * p_stream, OPJ_OFF_T p_size, opj_event_mgr_t * p_event_mgr)
+{
+       OPJ_OFF_T l_skip_nb_bytes = 0;
+       OPJ_OFF_T l_current_skip_nb_bytes = 0;
+       
+       assert( p_size >= 0 );
+       
+       if (p_stream->m_bytes_in_buffer >= (OPJ_SIZE_T)p_size) {
+               p_stream->m_current_data += p_size;
+               /* it is safe to cast p_size to OPJ_SIZE_T since it is <= m_bytes_in_buffer
+               which is of type OPJ_SIZE_T */
+               p_stream->m_bytes_in_buffer -= (OPJ_SIZE_T)p_size;
+               l_skip_nb_bytes += p_size;
+               p_stream->m_byte_offset += l_skip_nb_bytes;
+               return l_skip_nb_bytes;
        }
-       return *cio->bp++;
+
+       /* we are now in the case when the remaining data if not sufficient */
+       if (p_stream->m_status & opj_stream_e_end) {
+               l_skip_nb_bytes += (OPJ_OFF_T)p_stream->m_bytes_in_buffer;
+               p_stream->m_current_data += p_stream->m_bytes_in_buffer;
+               p_stream->m_bytes_in_buffer = 0;
+               p_stream->m_byte_offset += l_skip_nb_bytes;
+               return l_skip_nb_bytes ? l_skip_nb_bytes : (OPJ_OFF_T) -1;
+       }
+
+       /* the flag is not set, we copy data and then do an actual skip on the stream */
+       if (p_stream->m_bytes_in_buffer) {
+               l_skip_nb_bytes += (OPJ_OFF_T)p_stream->m_bytes_in_buffer;
+               p_stream->m_current_data = p_stream->m_stored_data;
+               p_size -= (OPJ_OFF_T)p_stream->m_bytes_in_buffer;
+               p_stream->m_bytes_in_buffer = 0;
+       }
+
+       while (p_size > 0) {
+               /* we should do an actual skip on the media */
+               l_current_skip_nb_bytes = p_stream->m_skip_fn(p_size, p_stream->m_user_data);
+               if (l_current_skip_nb_bytes == (OPJ_OFF_T) -1) {
+                       opj_event_msg(p_event_mgr, EVT_INFO, "Stream reached its end !\n");
+
+                       p_stream->m_status |= opj_stream_e_end;
+                       p_stream->m_byte_offset += l_skip_nb_bytes;
+                       /* end if stream */
+                       return l_skip_nb_bytes ? l_skip_nb_bytes : (OPJ_OFF_T) -1;
+               }
+               p_size -= l_current_skip_nb_bytes;
+               l_skip_nb_bytes += l_current_skip_nb_bytes;
+       }
+
+       p_stream->m_byte_offset += l_skip_nb_bytes;
+       
+       return l_skip_nb_bytes;
 }
 
-/*
- * Write some bytes.
- *
- * v : value to write
- * n : number of bytes to write
- */
-unsigned int cio_write(opj_cio_t *cio, unsigned int64 v, int n) {
-       int i;
-       for (i = n - 1; i >= 0; i--) {
-               if( !cio_byteout(cio, (unsigned char) ((v >> (i << 3)) & 0xff)) )
-                       return 0;
+OPJ_OFF_T opj_stream_write_skip (opj_stream_private_t * p_stream, OPJ_OFF_T p_size, opj_event_mgr_t * p_event_mgr)
+{
+       OPJ_BOOL l_is_written = 0;
+       OPJ_OFF_T l_current_skip_nb_bytes = 0;
+       OPJ_OFF_T l_skip_nb_bytes = 0;
+
+       if (p_stream->m_status & opj_stream_e_error) {
+               return (OPJ_OFF_T) -1;
+       }
+
+       /* we should flush data */
+       l_is_written = opj_stream_flush (p_stream, p_event_mgr);
+       if (! l_is_written) {
+               p_stream->m_status |= opj_stream_e_error;
+               p_stream->m_bytes_in_buffer = 0;
+               return (OPJ_OFF_T) -1;
+       }
+       /* then skip */
+
+       while (p_size > 0) {
+               /* we should do an actual skip on the media */
+               l_current_skip_nb_bytes = p_stream->m_skip_fn(p_size, p_stream->m_user_data);
+               
+               if (l_current_skip_nb_bytes == (OPJ_OFF_T)-1) {
+                       opj_event_msg(p_event_mgr, EVT_INFO, "Stream error!\n");
+
+                       p_stream->m_status |= opj_stream_e_error;
+                       p_stream->m_byte_offset += l_skip_nb_bytes;
+                       /* end if stream */
+                       return l_skip_nb_bytes ? l_skip_nb_bytes : (OPJ_OFF_T)-1;
+               }
+               p_size -= l_current_skip_nb_bytes;
+               l_skip_nb_bytes += l_current_skip_nb_bytes;
        }
-       return n;
+
+       p_stream->m_byte_offset += l_skip_nb_bytes;
+       
+       return l_skip_nb_bytes;
 }
 
-/*
- * Read some bytes.
- *
- * n : number of bytes to read
- *
- * return : value of the n bytes read
- */
-unsigned int cio_read(opj_cio_t *cio, int n) {
-       int i;
-       unsigned int v;
-       v = 0;
-       for (i = n - 1; i >= 0; i--) {
-               v += (unsigned int)cio_bytein(cio) << (i << 3);
+OPJ_OFF_T opj_stream_tell (const opj_stream_private_t * p_stream)
+{
+       return p_stream->m_byte_offset;
+}
+
+OPJ_OFF_T opj_stream_get_number_byte_left (const opj_stream_private_t * p_stream)
+{
+  assert( p_stream->m_byte_offset >= 0 );
+  assert( p_stream->m_user_data_length >= (OPJ_UINT64)p_stream->m_byte_offset);
+  return p_stream->m_user_data_length ?
+                               (OPJ_OFF_T)(p_stream->m_user_data_length) - p_stream->m_byte_offset :
+                               0;
+}
+
+OPJ_OFF_T opj_stream_skip (opj_stream_private_t * p_stream, OPJ_OFF_T p_size, opj_event_mgr_t * p_event_mgr)
+{
+       assert(p_size >= 0);
+       return p_stream->m_opj_skip(p_stream,p_size,p_event_mgr);
+}
+
+OPJ_BOOL opj_stream_read_seek (opj_stream_private_t * p_stream, OPJ_OFF_T p_size, opj_event_mgr_t * p_event_mgr)
+{
+       OPJ_ARG_NOT_USED(p_event_mgr);
+       p_stream->m_current_data = p_stream->m_stored_data;
+       p_stream->m_bytes_in_buffer = 0;
+
+       if( !(p_stream->m_seek_fn(p_size,p_stream->m_user_data)) ) {
+               p_stream->m_status |= opj_stream_e_end;
+               return OPJ_FALSE;
+       }
+       else {
+               /* reset stream status */
+               p_stream->m_status &= (~opj_stream_e_end);
+               p_stream->m_byte_offset = p_size;
+
+       }
+
+       return OPJ_TRUE;
+}
+
+OPJ_BOOL opj_stream_write_seek (opj_stream_private_t * p_stream, OPJ_OFF_T p_size, opj_event_mgr_t * p_event_mgr)
+{
+       if (! opj_stream_flush(p_stream,p_event_mgr)) {
+               p_stream->m_status |= opj_stream_e_error;
+               return OPJ_FALSE;
        }
-       return v;
+
+       p_stream->m_current_data = p_stream->m_stored_data;
+       p_stream->m_bytes_in_buffer = 0;
+
+       if (! p_stream->m_seek_fn(p_size,p_stream->m_user_data)) {
+               p_stream->m_status |= opj_stream_e_error;
+               return OPJ_FALSE;
+       }
+       else {
+               p_stream->m_byte_offset = p_size;
+       }
+
+       return OPJ_TRUE;
 }
 
-/* 
- * Skip some bytes.
- *
- * n : number of bytes to skip
- */
-void cio_skip(opj_cio_t *cio, int n) {
-  assert((cio->bp + n) >= cio->bp);
-  if (((cio->bp + n) < cio->start) || ((cio->bp + n) > cio->end)) {
-    assert(0);
-  }
-       cio->bp += n;
+OPJ_BOOL opj_stream_seek (opj_stream_private_t * p_stream, OPJ_OFF_T p_size, struct opj_event_mgr * p_event_mgr)
+{
+       assert(p_size >= 0);
+       return p_stream->m_opj_seek(p_stream,p_size,p_event_mgr);
+}
+
+OPJ_BOOL opj_stream_has_seek (const opj_stream_private_t * p_stream)
+{
+       return p_stream->m_seek_fn != opj_stream_default_seek;
 }
 
+OPJ_SIZE_T opj_stream_default_read (void * p_buffer, OPJ_SIZE_T p_nb_bytes, void * p_user_data)
+{
+       OPJ_ARG_NOT_USED(p_buffer);
+       OPJ_ARG_NOT_USED(p_nb_bytes);
+       OPJ_ARG_NOT_USED(p_user_data);
+       return (OPJ_SIZE_T) -1;
+}
 
+OPJ_SIZE_T opj_stream_default_write (void * p_buffer, OPJ_SIZE_T p_nb_bytes, void * p_user_data)
+{
+       OPJ_ARG_NOT_USED(p_buffer);
+       OPJ_ARG_NOT_USED(p_nb_bytes);
+       OPJ_ARG_NOT_USED(p_user_data);
+       return (OPJ_SIZE_T) -1;
+}
 
+OPJ_OFF_T opj_stream_default_skip (OPJ_OFF_T p_nb_bytes, void * p_user_data)
+{
+       OPJ_ARG_NOT_USED(p_nb_bytes);
+       OPJ_ARG_NOT_USED(p_user_data);
+       return (OPJ_OFF_T) -1;
+}
+
+OPJ_BOOL opj_stream_default_seek (OPJ_OFF_T p_nb_bytes, void * p_user_data)
+{
+       OPJ_ARG_NOT_USED(p_nb_bytes);
+       OPJ_ARG_NOT_USED(p_user_data);
+       return OPJ_FALSE;
+}
index e627431..6dfa5bb 100644 (file)
@@ -1,10 +1,18 @@
 /*
- * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
- * Copyright (c) 2002-2007, Professor Benoit Macq
+ * 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 and Antonin Descampe
+ * Copyright (c) 2003-2007, Francois-Olivier Devaux 
+ * Copyright (c) 2003-2014, Antonin Descampe
  * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * 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
 
 #ifndef __CIO_H
 #define __CIO_H
-
-#if defined(_MSC_VER) || defined(__BORLANDC__)
-#define int64 __int64
-#else
-#define int64 long long
-#endif
-
 /**
 @file cio.h
 @brief Implementation of a byte input-output process (CIO)
@@ -48,46 +49,351 @@ The functions in CIO.C have for goal to realize a byte input / output process.
 /** @defgroup CIO CIO - byte input-output stream */
 /*@{*/
 
+#include "opj_config_private.h"
+
+/* ----------------------------------------------------------------------- */
+
+#if defined(OPJ_BIG_ENDIAN)
+       #define opj_write_bytes         opj_write_bytes_BE
+       #define opj_read_bytes          opj_read_bytes_BE
+       #define opj_write_double        opj_write_double_BE
+       #define opj_read_double         opj_read_double_BE
+       #define opj_write_float         opj_write_float_BE
+       #define opj_read_float          opj_read_float_BE
+#else
+       #define opj_write_bytes         opj_write_bytes_LE
+       #define opj_read_bytes          opj_read_bytes_LE
+       #define opj_write_double        opj_write_double_LE
+       #define opj_read_double         opj_read_double_LE
+       #define opj_write_float         opj_write_float_LE
+       #define opj_read_float          opj_read_float_LE
+#endif
+
+
+
+typedef enum
+{
+       opj_signed_sentinel             = -1, /* do not use in code */
+       opj_stream_e_output             = 0x1,
+       opj_stream_e_input              = 0x2,
+       opj_stream_e_end                = 0x4,
+       opj_stream_e_error              = 0x8
+}
+opj_stream_flag ;
+
+/**
+Byte input-output stream.
+*/
+typedef struct opj_stream_private
+{
+       /**
+        * User data, be it files, ... The actual data depends on the type of the stream.
+        */
+       void *                                  m_user_data;
+
+       /**
+        * Pointer to function to free m_user_data (NULL at initialization)
+        * when destroying the stream. If pointer is NULL the function is not
+        * called and the m_user_data is not freed (even if non-NULL).
+        */
+       opj_stream_free_user_data_fn            m_free_user_data_fn;
+
+       /**
+        * User data length
+        */
+       OPJ_UINT64                              m_user_data_length;
+
+       /**
+        * Pointer to actual read function (NULL at the initialization of the cio.
+        */
+       opj_stream_read_fn              m_read_fn;
+
+       /**
+        * Pointer to actual write function (NULL at the initialization of the cio.
+        */
+       opj_stream_write_fn             m_write_fn;
+
+       /**
+        * Pointer to actual skip function (NULL at the initialization of the cio.
+        * There is no seek function to prevent from back and forth slow procedures.
+        */
+       opj_stream_skip_fn              m_skip_fn;
+
+       /**
+        * Pointer to actual seek function (if available).
+        */
+       opj_stream_seek_fn              m_seek_fn;
+
+       /**
+        * Actual data stored into the stream if readed from. Data is read by chunk of fixed size.
+        * you should never access this data directly.
+        */
+       OPJ_BYTE *                                      m_stored_data;
+
+       /**
+        * Pointer to the current read data.
+        */
+       OPJ_BYTE *                                      m_current_data;
+
+    /**
+    * FIXME DOC.
+    */
+       OPJ_OFF_T (* m_opj_skip)(struct opj_stream_private * ,OPJ_OFF_T , struct opj_event_mgr *);
+
+    /**
+    * FIXME DOC.
+    */
+       OPJ_BOOL (* m_opj_seek) (struct opj_stream_private * , OPJ_OFF_T , struct opj_event_mgr *);
+
+       /**
+        * number of bytes containing in the buffer.
+        */
+       OPJ_SIZE_T                      m_bytes_in_buffer;
+
+       /**
+        * The number of bytes read/written from the beginning of the stream
+        */
+       OPJ_OFF_T                       m_byte_offset;
+
+       /**
+        * The size of the buffer.
+        */
+       OPJ_SIZE_T                      m_buffer_size;
+
+       /**
+        * Flags to tell the status of the stream.
+        */
+       opj_stream_flag m_status;
+
+}
+opj_stream_private_t;
+
 /** @name Exported functions (see also openjpeg.h) */
 /*@{*/
 /* ----------------------------------------------------------------------- */
 /**
-Number of bytes left before the end of the stream
-@param cio CIO handle
-@return Returns the number of bytes before the end of the stream
+ * Write some bytes to the given data buffer, this function is used in Big Endian cpus.
+ * @param p_buffer             pointer the data buffer to write data to.
+ * @param p_value              the value to write
+ * @param p_nb_bytes   the number of bytes to write
 */
-int cio_numbytesleft(opj_cio_t *cio);
+void opj_write_bytes_BE (OPJ_BYTE * p_buffer, OPJ_UINT32 p_value, OPJ_UINT32 p_nb_bytes);
+
 /**
-Get pointer to the current position in the stream
-@param cio CIO handle
-@return Returns a pointer to the current position
-*/
-unsigned char *cio_getbp(opj_cio_t *cio);
+ * Reads some bytes from the given data buffer, this function is used in Big Endian cpus.
+ * @param p_buffer             pointer the data buffer to read data from.
+ * @param p_value              pointer to the value that will store the data.
+ * @param p_nb_bytes   the nb bytes to read.
+ * @return                             the number of bytes read or -1 if an error occured.
+ */
+void opj_read_bytes_BE(const OPJ_BYTE * p_buffer, OPJ_UINT32 * p_value, OPJ_UINT32 p_nb_bytes);
+
 /**
-Write some bytes
-@param cio CIO handle
-@param v Value to write
-@param n Number of bytes to write
-@return Returns the number of bytes written or 0 if an error occured
+ * Write some bytes to the given data buffer, this function is used in Little Endian cpus.
+ * @param p_buffer             pointer the data buffer to write data to.
+ * @param p_value              the value to write
+ * @param p_nb_bytes   the number of bytes to write
+ * @return                             the number of bytes written or -1 if an error occured
 */
-unsigned int cio_write(opj_cio_t *cio, unsigned int64 v, int n);
+void opj_write_bytes_LE (OPJ_BYTE * p_buffer, OPJ_UINT32 p_value, OPJ_UINT32 p_nb_bytes);
+
 /**
-Read some bytes
-@param cio CIO handle
-@param n Number of bytes to read
-@return Returns the value of the n bytes read
-*/
-unsigned int cio_read(opj_cio_t *cio, int n);
+ * Reads some bytes from the given data buffer, this function is used in Little Endian cpus.
+ * @param p_buffer             pointer the data buffer to read data from.
+ * @param p_value              pointer to the value that will store the data.
+ * @param p_nb_bytes   the nb bytes to read.
+ * @return                             the number of bytes read or -1 if an error occured.
+ */
+void opj_read_bytes_LE(const OPJ_BYTE * p_buffer, OPJ_UINT32 * p_value, OPJ_UINT32 p_nb_bytes);
+
+
 /**
-Skip some bytes
-@param cio CIO handle
-@param n Number of bytes to skip
-*/
-void cio_skip(opj_cio_t *cio, int n);
+ * Write some bytes to the given data buffer, this function is used in Little Endian cpus.
+ * @param p_buffer             pointer the data buffer to write data to.
+ * @param p_value              the value to write
+ */
+void opj_write_double_LE(OPJ_BYTE * p_buffer, OPJ_FLOAT64 p_value);
+
+/***
+ * Write some bytes to the given data buffer, this function is used in Big Endian cpus.
+ * @param p_buffer             pointer the data buffer to write data to.
+ * @param p_value              the value to write
+ */
+void opj_write_double_BE(OPJ_BYTE * p_buffer, OPJ_FLOAT64 p_value);
+
+/**
+ * Reads some bytes from the given data buffer, this function is used in Little Endian cpus.
+ * @param p_buffer             pointer the data buffer to read data from.
+ * @param p_value              pointer to the value that will store the data.
+ */
+void opj_read_double_LE(const OPJ_BYTE * p_buffer, OPJ_FLOAT64 * p_value);
+
+/**
+ * Reads some bytes from the given data buffer, this function is used in Big Endian cpus.
+ * @param p_buffer             pointer the data buffer to read data from.
+ * @param p_value              pointer to the value that will store the data.
+ */
+void opj_read_double_BE(const OPJ_BYTE * p_buffer, OPJ_FLOAT64 * p_value);
+
+/**
+ * Reads some bytes from the given data buffer, this function is used in Little Endian cpus.
+ * @param p_buffer             pointer the data buffer to read data from.
+ * @param p_value              pointer to the value that will store the data.
+ */
+void opj_read_float_LE(const OPJ_BYTE * p_buffer, OPJ_FLOAT32 * p_value);
+
+/**
+ * Reads some bytes from the given data buffer, this function is used in Big Endian cpus.
+ * @param p_buffer             pointer the data buffer to read data from.
+ * @param p_value              pointer to the value that will store the data.
+ */
+void opj_read_float_BE(const OPJ_BYTE * p_buffer, OPJ_FLOAT32 * p_value);
+
+/**
+ * Write some bytes to the given data buffer, this function is used in Little Endian cpus.
+ * @param p_buffer             pointer the data buffer to write data to.
+ * @param p_value              the value to write
+ */
+void opj_write_float_LE(OPJ_BYTE * p_buffer, OPJ_FLOAT32 p_value);
+
+/***
+ * Write some bytes to the given data buffer, this function is used in Big Endian cpus.
+ * @param p_buffer             pointer the data buffer to write data to.
+ * @param p_value              the value to write
+ */
+void opj_write_float_BE(OPJ_BYTE * p_buffer, OPJ_FLOAT32 p_value);
+
+/**
+ * Reads some bytes from the stream.
+ * @param              p_stream        the stream to read data from.
+ * @param              p_buffer        pointer to the data buffer that will receive the data.
+ * @param              p_size          number of bytes to read.
+ * @param              p_event_mgr     the user event manager to be notified of special events.
+ * @return             the number of bytes read, or -1 if an error occured or if the stream is at the end.
+ */
+OPJ_SIZE_T opj_stream_read_data (opj_stream_private_t * p_stream,OPJ_BYTE * p_buffer, OPJ_SIZE_T p_size, struct opj_event_mgr * p_event_mgr);
+
+/**
+ * Writes some bytes to the stream.
+ * @param              p_stream        the stream to write data to.
+ * @param              p_buffer        pointer to the data buffer holds the data to be writtent.
+ * @param              p_size          number of bytes to write.
+ * @param              p_event_mgr     the user event manager to be notified of special events.
+ * @return             the number of bytes writtent, or -1 if an error occured.
+ */
+OPJ_SIZE_T opj_stream_write_data (opj_stream_private_t * p_stream,const OPJ_BYTE * p_buffer, OPJ_SIZE_T p_size, struct opj_event_mgr * p_event_mgr);
+
+/**
+ * Writes the content of the stream buffer to the stream.
+ * @param              p_stream        the stream to write data to.
+ * @param              p_event_mgr     the user event manager to be notified of special events.
+ * @return             true if the data could be flushed, false else.
+ */
+OPJ_BOOL opj_stream_flush (opj_stream_private_t * p_stream, struct opj_event_mgr * p_event_mgr);
+
+/**
+ * Skips a number of bytes from the stream.
+ * @param              p_stream        the stream to skip data from.
+ * @param              p_size          the number of bytes to skip.
+ * @param              p_event_mgr     the user event manager to be notified of special events.
+ * @return             the number of bytes skipped, or -1 if an error occured.
+ */
+OPJ_OFF_T opj_stream_skip (opj_stream_private_t * p_stream,OPJ_OFF_T p_size, struct opj_event_mgr * p_event_mgr);
+
+/**
+ * Tells the byte offset on the stream (similar to ftell).
+ *
+ * @param              p_stream        the stream to get the information from.
+ *
+ * @return             the current position o fthe stream.
+ */
+OPJ_OFF_T opj_stream_tell (const opj_stream_private_t * p_stream);
+
+
+/**
+ * Get the number of bytes left before the end of the stream (similar to cio_numbytesleft).
+ *
+ * @param              p_stream        the stream to get the information from.
+ *
+ * @return             Number of bytes left before the end of the stream.
+ */
+OPJ_OFF_T opj_stream_get_number_byte_left (const opj_stream_private_t * p_stream);
+
+/**
+ * Skips a number of bytes from the stream.
+ * @param              p_stream        the stream to skip data from.
+ * @param              p_size          the number of bytes to skip.
+ * @param              p_event_mgr     the user event manager to be notified of special events.
+ * @return             the number of bytes skipped, or -1 if an error occured.
+ */
+OPJ_OFF_T opj_stream_write_skip (opj_stream_private_t * p_stream, OPJ_OFF_T p_size, struct opj_event_mgr * p_event_mgr);
+
+/**
+ * Skips a number of bytes from the stream.
+ * @param              p_stream        the stream to skip data from.
+ * @param              p_size          the number of bytes to skip.
+ * @param              p_event_mgr     the user event manager to be notified of special events.
+ * @return             the number of bytes skipped, or -1 if an error occured.
+ */
+OPJ_OFF_T opj_stream_read_skip (opj_stream_private_t * p_stream, OPJ_OFF_T p_size, struct opj_event_mgr * p_event_mgr);
+
+/**
+ * Skips a number of bytes from the stream.
+ * @param              p_stream        the stream to skip data from.
+ * @param              p_size          the number of bytes to skip.
+ * @param              p_event_mgr     the user event manager to be notified of special events.
+ * @return             OPJ_TRUE if success, or OPJ_FALSE if an error occured.
+ */
+OPJ_BOOL opj_stream_read_seek (opj_stream_private_t * p_stream, OPJ_OFF_T p_size, struct opj_event_mgr * p_event_mgr);
+
+/**
+ * Skips a number of bytes from the stream.
+ * @param              p_stream        the stream to skip data from.
+ * @param              p_size          the number of bytes to skip.
+ * @param              p_event_mgr     the user event manager to be notified of special events.
+ * @return             the number of bytes skipped, or -1 if an error occured.
+ */
+OPJ_BOOL opj_stream_write_seek (opj_stream_private_t * p_stream, OPJ_OFF_T p_size, struct opj_event_mgr * p_event_mgr);
+
+/**
+ * Seeks a number of bytes from the stream.
+ * @param              p_stream        the stream to skip data from.
+ * @param              p_size          the number of bytes to skip.
+ * @param              p_event_mgr     the user event manager to be notified of special events.
+ * @return             true if the stream is seekable.
+ */
+OPJ_BOOL opj_stream_seek (opj_stream_private_t * p_stream, OPJ_OFF_T p_size, struct opj_event_mgr * p_event_mgr);
+
+/**
+ * Tells if the given stream is seekable.
+ */
+OPJ_BOOL opj_stream_has_seek (const opj_stream_private_t * p_stream);
+
+/**
+ * FIXME DOC.
+ */
+OPJ_SIZE_T opj_stream_default_read (void * p_buffer, OPJ_SIZE_T p_nb_bytes, void * p_user_data);
+
+/**
+ * FIXME DOC.
+ */
+OPJ_SIZE_T opj_stream_default_write (void * p_buffer, OPJ_SIZE_T p_nb_bytes, void * p_user_data);
+
+/**
+ * FIXME DOC.
+ */
+OPJ_OFF_T opj_stream_default_skip (OPJ_OFF_T p_nb_bytes, void * p_user_data);
+
+/**
+ * FIXME DOC.
+ */
+OPJ_BOOL opj_stream_default_seek (OPJ_OFF_T p_nb_bytes, void * p_user_data);
+
 /* ----------------------------------------------------------------------- */
 /*@}*/
 
 /*@}*/
 
+
 #endif /* __CIO_H */
 
index 0fbfc20..e1f8a33 100644 (file)
@@ -1,9 +1,15 @@
 /*
- * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
- * Copyright (c) 2002-2007, Professor Benoit Macq
+ * 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 and Antonin Descampe
+ * Copyright (c) 2003-2007, Francois-Olivier Devaux 
+ * Copyright (c) 2003-2014, Antonin Descampe
  * Copyright (c) 2005, Herve Drolon, FreeImage Team
  * Copyright (c) 2007, Jonathan Ballard <dzonatas@dzonux.net>
  * Copyright (c) 2007, Callum Lerwick <seg@haxxed.com>
 /** @defgroup DWT DWT - Implementation of a discrete wavelet transform */
 /*@{*/
 
-#define WS(i) v->mem[(i)*2]
-#define WD(i) v->mem[(1+(i)*2)]
+#define OPJ_WS(i) v->mem[(i)*2]
+#define OPJ_WD(i) v->mem[(1+(i)*2)]
 
 /** @name Local data structures */
 /*@{*/
 
 typedef struct dwt_local {
-       int* mem;
-       int dn;
-       int sn;
-       int cas;
-} dwt_t;
+       OPJ_INT32* mem;
+       OPJ_INT32 dn;
+       OPJ_INT32 sn;
+       OPJ_INT32 cas;
+} opj_dwt_t;
 
 typedef union {
-       float   f[4];
-} v4;
+       OPJ_FLOAT32     f[4];
+} opj_v4_t;
 
 typedef struct v4dwt_local {
-       v4*     wavelet ;
-       int             dn ;
-       int             sn ;
-       int             cas ;
-} v4dwt_t ;
+       opj_v4_t*       wavelet ;
+       OPJ_INT32               dn ;
+       OPJ_INT32               sn ;
+       OPJ_INT32               cas ;
+} opj_v4dwt_t ;
 
-static const float dwt_alpha =  1.586134342f; /*  12994 */
-static const float dwt_beta  =  0.052980118f; /*    434 */
-static const float dwt_gamma = -0.882911075f; /*  -7233 */
-static const float dwt_delta = -0.443506852f; /*  -3633 */
+static const OPJ_FLOAT32 opj_dwt_alpha =  1.586134342f; /*  12994 */
+static const OPJ_FLOAT32 opj_dwt_beta  =  0.052980118f; /*    434 */
+static const OPJ_FLOAT32 opj_dwt_gamma = -0.882911075f; /*  -7233 */
+static const OPJ_FLOAT32 opj_dwt_delta = -0.443506852f; /*  -3633 */
 
-static const float K      = 1.230174105f; /*  10078 */
-/* FIXME: What is this constant? */
-static const float c13318 = 1.625732422f;
+static const OPJ_FLOAT32 opj_K      = 1.230174105f; /*  10078 */
+static const OPJ_FLOAT32 opj_c13318 = 1.625732422f;
 
 /*@}*/
 
 /**
 Virtual function type for wavelet transform in 1-D 
 */
-typedef void (*DWT1DFN)(dwt_t* v);
+typedef void (*DWT1DFN)(opj_dwt_t* v);
 
 /** @name Local static functions */
 /*@{*/
@@ -86,56 +91,83 @@ typedef void (*DWT1DFN)(dwt_t* v);
 /**
 Forward lazy transform (horizontal)
 */
-static void dwt_deinterleave_h(int *a, int *b, int dn, int sn, int cas);
+static void opj_dwt_deinterleave_h(OPJ_INT32 *a, OPJ_INT32 *b, OPJ_INT32 dn, OPJ_INT32 sn, OPJ_INT32 cas);
 /**
 Forward lazy transform (vertical)
 */
-static void dwt_deinterleave_v(int *a, int *b, int dn, int sn, int x, int cas);
+static void opj_dwt_deinterleave_v(OPJ_INT32 *a, OPJ_INT32 *b, OPJ_INT32 dn, OPJ_INT32 sn, OPJ_INT32 x, OPJ_INT32 cas);
 /**
 Inverse lazy transform (horizontal)
 */
-static void dwt_interleave_h(dwt_t* h, int *a);
+static void opj_dwt_interleave_h(opj_dwt_t* h, OPJ_INT32 *a);
 /**
 Inverse lazy transform (vertical)
 */
-static void dwt_interleave_v(dwt_t* v, int *a, int x);
+static void opj_dwt_interleave_v(opj_dwt_t* v, OPJ_INT32 *a, OPJ_INT32 x);
 /**
 Forward 5-3 wavelet transform in 1-D
 */
-static void dwt_encode_1(int *a, int dn, int sn, int cas);
+static void opj_dwt_encode_1(OPJ_INT32 *a, OPJ_INT32 dn, OPJ_INT32 sn, OPJ_INT32 cas);
 /**
 Inverse 5-3 wavelet transform in 1-D
 */
-static void dwt_decode_1(dwt_t *v);
+static void opj_dwt_decode_1(opj_dwt_t *v);
+static void opj_dwt_decode_1_(OPJ_INT32 *a, OPJ_INT32 dn, OPJ_INT32 sn, OPJ_INT32 cas);
 /**
 Forward 9-7 wavelet transform in 1-D
 */
-static void dwt_encode_1_real(int *a, int dn, int sn, int cas);
+static void opj_dwt_encode_1_real(OPJ_INT32 *a, OPJ_INT32 dn, OPJ_INT32 sn, OPJ_INT32 cas);
 /**
 Explicit calculation of the Quantization Stepsizes 
 */
-static void dwt_encode_stepsize(int stepsize, int numbps, opj_stepsize_t *bandno_stepsize);
+static void opj_dwt_encode_stepsize(OPJ_INT32 stepsize, OPJ_INT32 numbps, opj_stepsize_t *bandno_stepsize);
 /**
 Inverse wavelet transform in 2-D.
 */
-static void dwt_decode_tile(opj_tcd_tilecomp_t* tilec, int i, DWT1DFN fn);
+static OPJ_BOOL opj_dwt_decode_tile(opj_tcd_tilecomp_t* tilec, OPJ_UINT32 i, DWT1DFN fn);
+
+static OPJ_BOOL opj_dwt_encode_procedure(      opj_tcd_tilecomp_t * tilec,
+                                                                                   void (*p_function)(OPJ_INT32 *, OPJ_INT32,OPJ_INT32,OPJ_INT32) );
+
+static OPJ_UINT32 opj_dwt_max_resolution(opj_tcd_resolution_t* restrict r, OPJ_UINT32 i);
+
+/* <summary>                             */
+/* Inverse 9-7 wavelet transform in 1-D. */
+/* </summary>                            */
+static void opj_v4dwt_decode(opj_v4dwt_t* restrict dwt);
+
+static void opj_v4dwt_interleave_h(opj_v4dwt_t* restrict w, OPJ_FLOAT32* restrict a, OPJ_INT32 x, OPJ_INT32 size);
+
+static void opj_v4dwt_interleave_v(opj_v4dwt_t* restrict v , OPJ_FLOAT32* restrict a , OPJ_INT32 x, OPJ_INT32 nb_elts_read);
+
+#ifdef __SSE__
+static void opj_v4dwt_decode_step1_sse(opj_v4_t* w, OPJ_INT32 count, const __m128 c);
+
+static void opj_v4dwt_decode_step2_sse(opj_v4_t* l, opj_v4_t* w, OPJ_INT32 k, OPJ_INT32 m, __m128 c);
+
+#else
+static void opj_v4dwt_decode_step1(opj_v4_t* w, OPJ_INT32 count, const OPJ_FLOAT32 c);
+
+static void opj_v4dwt_decode_step2(opj_v4_t* l, opj_v4_t* w, OPJ_INT32 k, OPJ_INT32 m, OPJ_FLOAT32 c);
+
+#endif
 
 /*@}*/
 
 /*@}*/
 
-#define S(i) a[(i)*2]
-#define D(i) a[(1+(i)*2)]
-#define S_(i) ((i)<0?S(0):((i)>=sn?S(sn-1):S(i)))
-#define D_(i) ((i)<0?D(0):((i)>=dn?D(dn-1):D(i)))
+#define OPJ_S(i) a[(i)*2]
+#define OPJ_D(i) a[(1+(i)*2)]
+#define OPJ_S_(i) ((i)<0?OPJ_S(0):((i)>=sn?OPJ_S(sn-1):OPJ_S(i)))
+#define OPJ_D_(i) ((i)<0?OPJ_D(0):((i)>=dn?OPJ_D(dn-1):OPJ_D(i)))
 /* new */
-#define SS_(i) ((i)<0?S(0):((i)>=dn?S(dn-1):S(i)))
-#define DD_(i) ((i)<0?D(0):((i)>=sn?D(sn-1):D(i)))
+#define OPJ_SS_(i) ((i)<0?OPJ_S(0):((i)>=dn?OPJ_S(dn-1):OPJ_S(i)))
+#define OPJ_DD_(i) ((i)<0?OPJ_D(0):((i)>=sn?OPJ_D(sn-1):OPJ_D(i)))
 
 /* <summary>                                                              */
 /* This table contains the norms of the 5-3 wavelets for different bands. */
 /* </summary>                                                             */
-static const double dwt_norms[4][10] = {
+static const OPJ_FLOAT64 opj_dwt_norms[4][10] = {
        {1.000, 1.500, 2.750, 5.375, 10.68, 21.34, 42.67, 85.33, 170.7, 341.3},
        {1.038, 1.592, 2.919, 5.703, 11.33, 22.64, 45.25, 90.48, 180.9},
        {1.038, 1.592, 2.919, 5.703, 11.33, 22.64, 45.25, 90.48, 180.9},
@@ -145,7 +177,7 @@ static const double dwt_norms[4][10] = {
 /* <summary>                                                              */
 /* This table contains the norms of the 9-7 wavelets for different bands. */
 /* </summary>                                                             */
-static const double dwt_norms_real[4][10] = {
+static const OPJ_FLOAT64 opj_dwt_norms_real[4][10] = {
        {1.000, 1.965, 4.177, 8.403, 16.90, 33.84, 67.69, 135.3, 270.6, 540.9},
        {2.022, 3.989, 8.355, 17.04, 34.27, 68.63, 137.3, 274.6, 549.0},
        {2.022, 3.989, 8.355, 17.04, 34.27, 68.63, 137.3, 274.6, 549.0},
@@ -161,28 +193,57 @@ static const double dwt_norms_real[4][10] = {
 /* <summary>                                    */
 /* Forward lazy transform (horizontal).  */
 /* </summary>                            */ 
-static void dwt_deinterleave_h(int *a, int *b, int dn, int sn, int cas) {
-       int i;
-    for (i=0; i<sn; i++) b[i]=a[2*i+cas];
-    for (i=0; i<dn; i++) b[sn+i]=a[(2*i+1-cas)];
+void opj_dwt_deinterleave_h(OPJ_INT32 *a, OPJ_INT32 *b, OPJ_INT32 dn, OPJ_INT32 sn, OPJ_INT32 cas) {
+       OPJ_INT32 i;
+       OPJ_INT32 * l_dest = b;
+       OPJ_INT32 * l_src = a+cas;
+
+    for (i=0; i<sn; ++i) {
+               *l_dest++ = *l_src;
+               l_src += 2;
+       }
+       
+    l_dest = b + sn;
+       l_src = a + 1 - cas;
+
+    for        (i=0; i<dn; ++i)  {
+               *l_dest++=*l_src;
+               l_src += 2;
+       }
 }
 
 /* <summary>                             */  
 /* Forward lazy transform (vertical).    */
 /* </summary>                            */ 
-static void dwt_deinterleave_v(int *a, int *b, int dn, int sn, int x, int cas) {
-    int i;
-    for (i=0; i<sn; i++) b[i*x]=a[2*i+cas];
-    for (i=0; i<dn; i++) b[(sn+i)*x]=a[(2*i+1-cas)];
+void opj_dwt_deinterleave_v(OPJ_INT32 *a, OPJ_INT32 *b, OPJ_INT32 dn, OPJ_INT32 sn, OPJ_INT32 x, OPJ_INT32 cas) {
+    OPJ_INT32 i = sn;
+       OPJ_INT32 * l_dest = b;
+       OPJ_INT32 * l_src = a+cas;
+
+    while (i--) {
+               *l_dest = *l_src;
+               l_dest += x;
+               l_src += 2;
+               } /* b[i*x]=a[2*i+cas]; */
+
+       l_dest = b + sn * x;
+       l_src = a + 1 - cas;
+       
+       i = dn;
+    while (i--) {
+               *l_dest = *l_src;
+               l_dest += x;
+               l_src += 2;
+        } /*b[(sn+i)*x]=a[(2*i+1-cas)];*/
 }
 
 /* <summary>                             */
 /* Inverse lazy transform (horizontal).  */
 /* </summary>                            */
-static void dwt_interleave_h(dwt_t* h, int *a) {
-    int *ai = a;
-    int *bi = h->mem + h->cas;
-    int  i     = h->sn;
+void opj_dwt_interleave_h(opj_dwt_t* h, OPJ_INT32 *a) {
+    OPJ_INT32 *ai = a;
+    OPJ_INT32 *bi = h->mem + h->cas;
+    OPJ_INT32  i       = h->sn;
     while( i-- ) {
       *bi = *(ai++);
          bi += 2;
@@ -199,10 +260,10 @@ static void dwt_interleave_h(dwt_t* h, int *a) {
 /* <summary>                             */  
 /* Inverse lazy transform (vertical).    */
 /* </summary>                            */ 
-static void dwt_interleave_v(dwt_t* v, int *a, int x) {
-    int *ai = a;
-    int *bi = v->mem + v->cas;
-    int  i = v->sn;
+void opj_dwt_interleave_v(opj_dwt_t* v, OPJ_INT32 *a, OPJ_INT32 x) {
+    OPJ_INT32 *ai = a;
+    OPJ_INT32 *bi = v->mem + v->cas;
+    OPJ_INT32  i = v->sn;
     while( i-- ) {
       *bi = *ai;
          bi += 2;
@@ -222,20 +283,20 @@ static void dwt_interleave_v(dwt_t* v, int *a, int x) {
 /* <summary>                            */
 /* Forward 5-3 wavelet transform in 1-D. */
 /* </summary>                           */
-static void dwt_encode_1(int *a, int dn, int sn, int cas) {
-       int i;
+void opj_dwt_encode_1(OPJ_INT32 *a, OPJ_INT32 dn, OPJ_INT32 sn, OPJ_INT32 cas) {
+       OPJ_INT32 i;
        
        if (!cas) {
                if ((dn > 0) || (sn > 1)) {     /* NEW :  CASE ONE ELEMENT */
-                       for (i = 0; i < dn; i++) D(i) -= (S_(i) + S_(i + 1)) >> 1;
-                       for (i = 0; i < sn; i++) S(i) += (D_(i - 1) + D_(i) + 2) >> 2;
+                       for (i = 0; i < dn; i++) OPJ_D(i) -= (OPJ_S_(i) + OPJ_S_(i + 1)) >> 1;
+                       for (i = 0; i < sn; i++) OPJ_S(i) += (OPJ_D_(i - 1) + OPJ_D_(i) + 2) >> 2;
                }
        } else {
                if (!sn && dn == 1)                 /* NEW :  CASE ONE ELEMENT */
-                       S(0) *= 2;
+                       OPJ_S(0) *= 2;
                else {
-                       for (i = 0; i < dn; i++) S(i) -= (DD_(i) + DD_(i - 1)) >> 1;
-                       for (i = 0; i < sn; i++) D(i) += (SS_(i) + SS_(i + 1) + 2) >> 2;
+                       for (i = 0; i < dn; i++) OPJ_S(i) -= (OPJ_DD_(i) + OPJ_DD_(i - 1)) >> 1;
+                       for (i = 0; i < sn; i++) OPJ_D(i) += (OPJ_SS_(i) + OPJ_SS_(i + 1) + 2) >> 2;
                }
        }
 }
@@ -243,20 +304,20 @@ static void dwt_encode_1(int *a, int dn, int sn, int cas) {
 /* <summary>                            */
 /* Inverse 5-3 wavelet transform in 1-D. */
 /* </summary>                           */ 
-static void dwt_decode_1_(int *a, int dn, int sn, int cas) {
-       int i;
+void opj_dwt_decode_1_(OPJ_INT32 *a, OPJ_INT32 dn, OPJ_INT32 sn, OPJ_INT32 cas) {
+       OPJ_INT32 i;
        
        if (!cas) {
                if ((dn > 0) || (sn > 1)) { /* NEW :  CASE ONE ELEMENT */
-                       for (i = 0; i < sn; i++) S(i) -= (D_(i - 1) + D_(i) + 2) >> 2;
-                       for (i = 0; i < dn; i++) D(i) += (S_(i) + S_(i + 1)) >> 1;
+                       for (i = 0; i < sn; i++) OPJ_S(i) -= (OPJ_D_(i - 1) + OPJ_D_(i) + 2) >> 2;
+                       for (i = 0; i < dn; i++) OPJ_D(i) += (OPJ_S_(i) + OPJ_S_(i + 1)) >> 1;
                }
        } else {
                if (!sn  && dn == 1)          /* NEW :  CASE ONE ELEMENT */
-                       S(0) /= 2;
+                       OPJ_S(0) /= 2;
                else {
-                       for (i = 0; i < sn; i++) D(i) -= (SS_(i) + SS_(i + 1) + 2) >> 2;
-                       for (i = 0; i < dn; i++) S(i) += (DD_(i) + DD_(i - 1)) >> 1;
+                       for (i = 0; i < sn; i++) OPJ_D(i) -= (OPJ_SS_(i) + OPJ_SS_(i + 1) + 2) >> 2;
+                       for (i = 0; i < dn; i++) OPJ_S(i) += (OPJ_DD_(i) + OPJ_DD_(i - 1)) >> 1;
                }
        }
 }
@@ -264,52 +325,52 @@ static void dwt_decode_1_(int *a, int dn, int sn, int cas) {
 /* <summary>                            */
 /* Inverse 5-3 wavelet transform in 1-D. */
 /* </summary>                           */ 
-static void dwt_decode_1(dwt_t *v) {
-       dwt_decode_1_(v->mem, v->dn, v->sn, v->cas);
+void opj_dwt_decode_1(opj_dwt_t *v) {
+       opj_dwt_decode_1_(v->mem, v->dn, v->sn, v->cas);
 }
 
 /* <summary>                             */
 /* Forward 9-7 wavelet transform in 1-D. */
 /* </summary>                            */
-static void dwt_encode_1_real(int *a, int dn, int sn, int cas) {
-       int i;
+void opj_dwt_encode_1_real(OPJ_INT32 *a, OPJ_INT32 dn, OPJ_INT32 sn, OPJ_INT32 cas) {
+       OPJ_INT32 i;
        if (!cas) {
                if ((dn > 0) || (sn > 1)) {     /* NEW :  CASE ONE ELEMENT */
                        for (i = 0; i < dn; i++)
-                               D(i) -= fix_mul(S_(i) + S_(i + 1), 12993);
+                               OPJ_D(i) -= opj_int_fix_mul(OPJ_S_(i) + OPJ_S_(i + 1), 12993);
                        for (i = 0; i < sn; i++)
-                               S(i) -= fix_mul(D_(i - 1) + D_(i), 434);
+                               OPJ_S(i) -= opj_int_fix_mul(OPJ_D_(i - 1) + OPJ_D_(i), 434);
                        for (i = 0; i < dn; i++)
-                               D(i) += fix_mul(S_(i) + S_(i + 1), 7233);
+                               OPJ_D(i) += opj_int_fix_mul(OPJ_S_(i) + OPJ_S_(i + 1), 7233);
                        for (i = 0; i < sn; i++)
-                               S(i) += fix_mul(D_(i - 1) + D_(i), 3633);
+                               OPJ_S(i) += opj_int_fix_mul(OPJ_D_(i - 1) + OPJ_D_(i), 3633);
                        for (i = 0; i < dn; i++)
-                               D(i) = fix_mul(D(i), 5038);     /*5038 */
+                               OPJ_D(i) = opj_int_fix_mul(OPJ_D(i), 5038);     /*5038 */
                        for (i = 0; i < sn; i++)
-                               S(i) = fix_mul(S(i), 6659);     /*6660 */
+                               OPJ_S(i) = opj_int_fix_mul(OPJ_S(i), 6659);     /*6660 */
                }
        } else {
                if ((sn > 0) || (dn > 1)) {     /* NEW :  CASE ONE ELEMENT */
                        for (i = 0; i < dn; i++)
-                               S(i) -= fix_mul(DD_(i) + DD_(i - 1), 12993);
+                               OPJ_S(i) -= opj_int_fix_mul(OPJ_DD_(i) + OPJ_DD_(i - 1), 12993);
                        for (i = 0; i < sn; i++)
-                               D(i) -= fix_mul(SS_(i) + SS_(i + 1), 434);
+                               OPJ_D(i) -= opj_int_fix_mul(OPJ_SS_(i) + OPJ_SS_(i + 1), 434);
                        for (i = 0; i < dn; i++)
-                               S(i) += fix_mul(DD_(i) + DD_(i - 1), 7233);
+                               OPJ_S(i) += opj_int_fix_mul(OPJ_DD_(i) + OPJ_DD_(i - 1), 7233);
                        for (i = 0; i < sn; i++)
-                               D(i) += fix_mul(SS_(i) + SS_(i + 1), 3633);
+                               OPJ_D(i) += opj_int_fix_mul(OPJ_SS_(i) + OPJ_SS_(i + 1), 3633);
                        for (i = 0; i < dn; i++)
-                               S(i) = fix_mul(S(i), 5038);     /*5038 */
+                               OPJ_S(i) = opj_int_fix_mul(OPJ_S(i), 5038);     /*5038 */
                        for (i = 0; i < sn; i++)
-                               D(i) = fix_mul(D(i), 6659);     /*6660 */
+                               OPJ_D(i) = opj_int_fix_mul(OPJ_D(i), 6659);     /*6660 */
                }
        }
 }
 
-static void dwt_encode_stepsize(int stepsize, int numbps, opj_stepsize_t *bandno_stepsize) {
-       int p, n;
-       p = int_floorlog2(stepsize) - 13;
-       n = 11 - int_floorlog2(stepsize);
+void opj_dwt_encode_stepsize(OPJ_INT32 stepsize, OPJ_INT32 numbps, opj_stepsize_t *bandno_stepsize) {
+       OPJ_INT32 p, n;
+       p = opj_int_floorlog2(stepsize) - 13;
+       n = 11 - opj_int_floorlog2(stepsize);
        bandno_stepsize->mant = (n < 0 ? stepsize >> -n : stepsize << n) & 0x7ff;
        bandno_stepsize->expn = numbps - p;
 }
@@ -320,74 +381,105 @@ static void dwt_encode_stepsize(int stepsize, int numbps, opj_stepsize_t *bandno
 ==========================================================
 */
 
+
 /* <summary>                            */
 /* Forward 5-3 wavelet transform in 2-D. */
 /* </summary>                           */
-void dwt_encode(opj_tcd_tilecomp_t * tilec) {
-       int i, j, k;
-       int *a = NULL;
-       int *aj = NULL;
-       int *bj = NULL;
-       int w, l;
-       
+INLINE OPJ_BOOL opj_dwt_encode_procedure(opj_tcd_tilecomp_t * tilec,void (*p_function)(OPJ_INT32 *, OPJ_INT32,OPJ_INT32,OPJ_INT32) )
+{
+       OPJ_INT32 i, j, k;
+       OPJ_INT32 *a = 00;
+       OPJ_INT32 *aj = 00;
+       OPJ_INT32 *bj = 00;
+       OPJ_INT32 w, l;
+
+       OPJ_INT32 rw;                   /* width of the resolution level computed   */
+       OPJ_INT32 rh;                   /* height of the resolution level computed  */
+       OPJ_UINT32 l_data_size;
+
+       opj_tcd_resolution_t * l_cur_res = 0;
+       opj_tcd_resolution_t * l_last_res = 0;
+
        w = tilec->x1-tilec->x0;
-       l = tilec->numresolutions-1;
+       l = (OPJ_INT32)tilec->numresolutions-1;
        a = tilec->data;
-       
-       for (i = 0; i < l; i++) {
-               int rw;                 /* width of the resolution level computed                                                           */
-               int rh;                 /* height of the resolution level computed                                                          */
-               int rw1;                /* width of the resolution level once lower than computed one                                       */
-               int rh1;                /* height of the resolution level once lower than computed one                                      */
-               int cas_col;    /* 0 = non inversion on horizontal filtering 1 = inversion between low-pass and high-pass filtering */
-               int cas_row;    /* 0 = non inversion on vertical filtering 1 = inversion between low-pass and high-pass filtering   */
-               int dn, sn;
-               
-               rw = tilec->resolutions[l - i].x1 - tilec->resolutions[l - i].x0;
-               rh = tilec->resolutions[l - i].y1 - tilec->resolutions[l - i].y0;
-               rw1= tilec->resolutions[l - i - 1].x1 - tilec->resolutions[l - i - 1].x0;
-               rh1= tilec->resolutions[l - i - 1].y1 - tilec->resolutions[l - i - 1].y0;
-               
-               cas_row = tilec->resolutions[l - i].x0 % 2;
-               cas_col = tilec->resolutions[l - i].y0 % 2;
-        
+
+       l_cur_res = tilec->resolutions + l;
+       l_last_res = l_cur_res - 1;
+
+       l_data_size = opj_dwt_max_resolution( tilec->resolutions,tilec->numresolutions) * (OPJ_UINT32)sizeof(OPJ_INT32);
+       bj = (OPJ_INT32*)opj_malloc((size_t)l_data_size);
+       if (! bj) {
+               return OPJ_FALSE;
+       }
+       i = l;
+
+       while (i--) {
+               OPJ_INT32 rw1;          /* width of the resolution level once lower than computed one                                       */
+               OPJ_INT32 rh1;          /* height of the resolution level once lower than computed one                                      */
+               OPJ_INT32 cas_col;      /* 0 = non inversion on horizontal filtering 1 = inversion between low-pass and high-pass filtering */
+               OPJ_INT32 cas_row;      /* 0 = non inversion on vertical filtering 1 = inversion between low-pass and high-pass filtering   */
+               OPJ_INT32 dn, sn;
+
+               rw  = l_cur_res->x1 - l_cur_res->x0;
+               rh  = l_cur_res->y1 - l_cur_res->y0;
+               rw1 = l_last_res->x1 - l_last_res->x0;
+               rh1 = l_last_res->y1 - l_last_res->y0;
+
+               cas_row = l_cur_res->x0 & 1;
+               cas_col = l_cur_res->y0 & 1;
+
                sn = rh1;
                dn = rh - rh1;
-               bj = (int*)opj_malloc(rh * sizeof(int));
-               for (j = 0; j < rw; j++) {
+               for (j = 0; j < rw; ++j) {
                        aj = a + j;
-                       for (k = 0; k < rh; k++)  bj[k] = aj[k*w];
-                       dwt_encode_1(bj, dn, sn, cas_col);
-                       dwt_deinterleave_v(bj, aj, dn, sn, w, cas_col);
+                       for (k = 0; k < rh; ++k) {
+                               bj[k] = aj[k*w];
+                       }
+
+                       (*p_function) (bj, dn, sn, cas_col);
+
+                       opj_dwt_deinterleave_v(bj, aj, dn, sn, w, cas_col);
                }
-               opj_free(bj);
-               
+
                sn = rw1;
                dn = rw - rw1;
-               bj = (int*)opj_malloc(rw * sizeof(int));
+
                for (j = 0; j < rh; j++) {
                        aj = a + j * w;
                        for (k = 0; k < rw; k++)  bj[k] = aj[k];
-                       dwt_encode_1(bj, dn, sn, cas_row);
-                       dwt_deinterleave_h(bj, aj, dn, sn, cas_row);
+                       (*p_function) (bj, dn, sn, cas_row);
+                       opj_dwt_deinterleave_h(bj, aj, dn, sn, cas_row);
                }
-               opj_free(bj);
+
+               l_cur_res = l_last_res;
+
+               --l_last_res;
        }
+
+       opj_free(bj);
+       return OPJ_TRUE;
 }
 
+/* Forward 5-3 wavelet transform in 2-D. */
+/* </summary>                           */
+OPJ_BOOL opj_dwt_encode(opj_tcd_tilecomp_t * tilec)
+{
+       return opj_dwt_encode_procedure(tilec,opj_dwt_encode_1);
+}
 
 /* <summary>                            */
 /* Inverse 5-3 wavelet transform in 2-D. */
 /* </summary>                           */
-void dwt_decode(opj_tcd_tilecomp_t* tilec, int numres) {
-       dwt_decode_tile(tilec, numres, &dwt_decode_1);
+OPJ_BOOL opj_dwt_decode(opj_tcd_tilecomp_t* tilec, OPJ_UINT32 numres) {
+       return opj_dwt_decode_tile(tilec, numres, &opj_dwt_decode_1);
 }
 
 
 /* <summary>                          */
 /* Get gain of 5-3 wavelet transform. */
 /* </summary>                         */
-int dwt_getgain(int orient) {
+OPJ_UINT32 opj_dwt_getgain(OPJ_UINT32 orient) {
        if (orient == 0)
                return 0;
        if (orient == 1 || orient == 2)
@@ -398,71 +490,22 @@ int dwt_getgain(int orient) {
 /* <summary>                */
 /* Get norm of 5-3 wavelet. */
 /* </summary>               */
-double dwt_getnorm(int level, int orient) {
-       return dwt_norms[orient][level];
+OPJ_FLOAT64 opj_dwt_getnorm(OPJ_UINT32 level, OPJ_UINT32 orient) {
+       return opj_dwt_norms[orient][level];
 }
 
 /* <summary>                             */
 /* Forward 9-7 wavelet transform in 2-D. */
 /* </summary>                            */
-
-void dwt_encode_real(opj_tcd_tilecomp_t * tilec) {
-       int i, j, k;
-       int *a = NULL;
-       int *aj = NULL;
-       int *bj = NULL;
-       int w, l;
-       
-       w = tilec->x1-tilec->x0;
-       l = tilec->numresolutions-1;
-       a = tilec->data;
-       
-       for (i = 0; i < l; i++) {
-               int rw;                 /* width of the resolution level computed                                                     */
-               int rh;                 /* height of the resolution level computed                                                    */
-               int rw1;                /* width of the resolution level once lower than computed one                                 */
-               int rh1;                /* height of the resolution level once lower than computed one                                */
-               int cas_col;    /* 0 = non inversion on horizontal filtering 1 = inversion between low-pass and high-pass filtering */
-               int cas_row;    /* 0 = non inversion on vertical filtering 1 = inversion between low-pass and high-pass filtering   */
-               int dn, sn;
-               
-               rw = tilec->resolutions[l - i].x1 - tilec->resolutions[l - i].x0;
-               rh = tilec->resolutions[l - i].y1 - tilec->resolutions[l - i].y0;
-               rw1= tilec->resolutions[l - i - 1].x1 - tilec->resolutions[l - i - 1].x0;
-               rh1= tilec->resolutions[l - i - 1].y1 - tilec->resolutions[l - i - 1].y0;
-               
-               cas_row = tilec->resolutions[l - i].x0 % 2;
-               cas_col = tilec->resolutions[l - i].y0 % 2;
-               
-               sn = rh1;
-               dn = rh - rh1;
-               bj = (int*)opj_malloc(rh * sizeof(int));
-               for (j = 0; j < rw; j++) {
-                       aj = a + j;
-                       for (k = 0; k < rh; k++)  bj[k] = aj[k*w];
-                       dwt_encode_1_real(bj, dn, sn, cas_col);
-                       dwt_deinterleave_v(bj, aj, dn, sn, w, cas_col);
-               }
-               opj_free(bj);
-               
-               sn = rw1;
-               dn = rw - rw1;
-               bj = (int*)opj_malloc(rw * sizeof(int));
-               for (j = 0; j < rh; j++) {
-                       aj = a + j * w;
-                       for (k = 0; k < rw; k++)  bj[k] = aj[k];
-                       dwt_encode_1_real(bj, dn, sn, cas_row);
-                       dwt_deinterleave_h(bj, aj, dn, sn, cas_row);
-               }
-               opj_free(bj);
-       }
+OPJ_BOOL opj_dwt_encode_real(opj_tcd_tilecomp_t * tilec)
+{
+       return opj_dwt_encode_procedure(tilec,opj_dwt_encode_1_real);
 }
 
-
 /* <summary>                          */
 /* Get gain of 9-7 wavelet transform. */
 /* </summary>                         */
-int dwt_getgain_real(int orient) {
+OPJ_UINT32 opj_dwt_getgain_real(OPJ_UINT32 orient) {
        (void)orient;
        return 0;
 }
@@ -470,16 +513,16 @@ int dwt_getgain_real(int orient) {
 /* <summary>                */
 /* Get norm of 9-7 wavelet. */
 /* </summary>               */
-double dwt_getnorm_real(int level, int orient) {
-       return dwt_norms_real[orient][level];
+OPJ_FLOAT64 opj_dwt_getnorm_real(OPJ_UINT32 level, OPJ_UINT32 orient) {
+       return opj_dwt_norms_real[orient][level];
 }
 
-void dwt_calc_explicit_stepsizes(opj_tccp_t * tccp, int prec) {
-       int numbands, bandno;
+void opj_dwt_calc_explicit_stepsizes(opj_tccp_t * tccp, OPJ_UINT32 prec) {
+       OPJ_UINT32 numbands, bandno;
        numbands = 3 * tccp->numresolutions - 2;
        for (bandno = 0; bandno < numbands; bandno++) {
-               double stepsize;
-               int resno, level, orient, gain;
+               OPJ_FLOAT64 stepsize;
+               OPJ_UINT32 resno, level, orient, gain;
 
                resno = (bandno == 0) ? 0 : ((bandno - 1) / 3 + 1);
                orient = (bandno == 0) ? 0 : ((bandno - 1) % 3 + 1);
@@ -488,74 +531,77 @@ void dwt_calc_explicit_stepsizes(opj_tccp_t * tccp, int prec) {
                if (tccp->qntsty == J2K_CCP_QNTSTY_NOQNT) {
                        stepsize = 1.0;
                } else {
-                       double norm = dwt_norms_real[orient][level];
+                       OPJ_FLOAT64 norm = opj_dwt_norms_real[orient][level];
                        stepsize = (1 << (gain)) / norm;
                }
-               dwt_encode_stepsize((int) floor(stepsize * 8192.0), prec + gain, &tccp->stepsizes[bandno]);
+               opj_dwt_encode_stepsize((OPJ_INT32) floor(stepsize * 8192.0), (OPJ_INT32)(prec + gain), &tccp->stepsizes[bandno]);
        }
 }
 
-
 /* <summary>                             */
 /* Determine maximum computed resolution level for inverse wavelet transform */
 /* </summary>                            */
-static int dwt_decode_max_resolution(opj_tcd_resolution_t* restrict r, int i) {
-       int mr  = 1;
-       int w;
+OPJ_UINT32 opj_dwt_max_resolution(opj_tcd_resolution_t* restrict r, OPJ_UINT32 i) {
+       OPJ_UINT32 mr   = 0;
+       OPJ_UINT32 w;
        while( --i ) {
-               r++;
-               if( mr < ( w = r->x1 - r->x0 ) )
+               ++r;
+               if( mr < ( w = (OPJ_UINT32)(r->x1 - r->x0) ) )
                        mr = w ;
-               if( mr < ( w = r->y1 - r->y0 ) )
+               if( mr < ( w = (OPJ_UINT32)(r->y1 - r->y0) ) )
                        mr = w ;
        }
        return mr ;
 }
 
-
 /* <summary>                            */
 /* Inverse wavelet transform in 2-D.     */
 /* </summary>                           */
-static void dwt_decode_tile(opj_tcd_tilecomp_t* tilec, int numres, DWT1DFN dwt_1D) {
-       dwt_t h;
-       dwt_t v;
+OPJ_BOOL opj_dwt_decode_tile(opj_tcd_tilecomp_t* tilec, OPJ_UINT32 numres, DWT1DFN dwt_1D) {
+       opj_dwt_t h;
+       opj_dwt_t v;
 
        opj_tcd_resolution_t* tr = tilec->resolutions;
 
-       int rw = tr->x1 - tr->x0;       /* width of the resolution level computed */
-       int rh = tr->y1 - tr->y0;       /* height of the resolution level computed */
+       OPJ_UINT32 rw = (OPJ_UINT32)(tr->x1 - tr->x0);  /* width of the resolution level computed */
+       OPJ_UINT32 rh = (OPJ_UINT32)(tr->y1 - tr->y0);  /* height of the resolution level computed */
+
+       OPJ_UINT32 w = (OPJ_UINT32)(tilec->x1 - tilec->x0);
 
-       int w = tilec->x1 - tilec->x0;
+       h.mem = (OPJ_INT32*)
+       opj_aligned_malloc(opj_dwt_max_resolution(tr, numres) * sizeof(OPJ_INT32));
+       if (! h.mem){
+               return OPJ_FALSE;
+       }
 
-       h.mem = (int*)opj_aligned_malloc(dwt_decode_max_resolution(tr, numres) * sizeof(int));
        v.mem = h.mem;
 
        while( --numres) {
-               int * restrict tiledp = tilec->data;
-               int j;
+               OPJ_INT32 * restrict tiledp = tilec->data;
+               OPJ_UINT32 j;
 
                ++tr;
-               h.sn = rw;
-               v.sn = rh;
+               h.sn = (OPJ_INT32)rw;
+               v.sn = (OPJ_INT32)rh;
 
-               rw = tr->x1 - tr->x0;
-               rh = tr->y1 - tr->y0;
+               rw = (OPJ_UINT32)(tr->x1 - tr->x0);
+               rh = (OPJ_UINT32)(tr->y1 - tr->y0);
 
-               h.dn = rw - h.sn;
+               h.dn = (OPJ_INT32)(rw - (OPJ_UINT32)h.sn);
                h.cas = tr->x0 % 2;
 
                for(j = 0; j < rh; ++j) {
-                       dwt_interleave_h(&h, &tiledp[j*w]);
+                       opj_dwt_interleave_h(&h, &tiledp[j*w]);
                        (dwt_1D)(&h);
-                       memcpy(&tiledp[j*w], h.mem, rw * sizeof(int));
+                       memcpy(&tiledp[j*w], h.mem, rw * sizeof(OPJ_INT32));
                }
 
-               v.dn = rh - v.sn;
+               v.dn = (OPJ_INT32)(rh - (OPJ_UINT32)v.sn);
                v.cas = tr->y0 % 2;
 
                for(j = 0; j < rw; ++j){
-                       int k;
-                       dwt_interleave_v(&v, &tiledp[j], w);
+                       OPJ_UINT32 k;
+                       opj_dwt_interleave_v(&v, &tiledp[j], (OPJ_INT32)w);
                        (dwt_1D)(&v);
                        for(k = 0; k < rh; ++k) {
                                tiledp[k * w + j] = v.mem[k];
@@ -563,17 +609,19 @@ static void dwt_decode_tile(opj_tcd_tilecomp_t* tilec, int numres, DWT1DFN dwt_1
                }
        }
        opj_aligned_free(h.mem);
+       return OPJ_TRUE;
 }
 
-static void v4dwt_interleave_h(v4dwt_t* restrict w, float* restrict a, int x, int size){
-       float* restrict bi = (float*) (w->wavelet + w->cas);
-       int count = w->sn;
-       int i, k;
+void opj_v4dwt_interleave_h(opj_v4dwt_t* restrict w, OPJ_FLOAT32* restrict a, OPJ_INT32 x, OPJ_INT32 size){
+       OPJ_FLOAT32* restrict bi = (OPJ_FLOAT32*) (w->wavelet + w->cas);
+       OPJ_INT32 count = w->sn;
+       OPJ_INT32 i, k;
+
        for(k = 0; k < 2; ++k){
-               if (count + 3 * x < size && ((size_t) a & 0x0f) == 0 && ((size_t) bi & 0x0f) == 0 && (x & 0x0f) == 0) {
+               if ( count + 3 * x < size && ((size_t) a & 0x0f) == 0 && ((size_t) bi & 0x0f) == 0 && (x & 0x0f) == 0 ) {
                        /* Fast code path */
                        for(i = 0; i < count; ++i){
-                               int j = i;
+                               OPJ_INT32 j = i;
                                bi[i*8    ] = a[j];
                                j += x;
                                bi[i*8 + 1] = a[j];
@@ -582,47 +630,52 @@ static void v4dwt_interleave_h(v4dwt_t* restrict w, float* restrict a, int x, in
                                j += x;
                                bi[i*8 + 3] = a[j];
                        }
-               } else {
-                       /* Slow code path */
-               for(i = 0; i < count; ++i){
-                       int j = i;
-                       bi[i*8    ] = a[j];
-                       j += x;
-                       if(j > size) continue;
-                       bi[i*8 + 1] = a[j];
-                       j += x;
-                       if(j > size) continue;
-                       bi[i*8 + 2] = a[j];
-                       j += x;
-                       if(j > size) continue;
-                       bi[i*8 + 3] = a[j];
                }
+               else {
+                       /* Slow code path */
+                       for(i = 0; i < count; ++i){
+                               OPJ_INT32 j = i;
+                               bi[i*8    ] = a[j];
+                               j += x;
+                               if(j >= size) continue;
+                               bi[i*8 + 1] = a[j];
+                               j += x;
+                               if(j >= size) continue;
+                               bi[i*8 + 2] = a[j];
+                               j += x;
+                               if(j >= size) continue;
+                               bi[i*8 + 3] = a[j]; /* This one*/
+                       }
                }
-               bi = (float*) (w->wavelet + 1 - w->cas);
+
+               bi = (OPJ_FLOAT32*) (w->wavelet + 1 - w->cas);
                a += w->sn;
                size -= w->sn;
                count = w->dn;
        }
 }
 
-static void v4dwt_interleave_v(v4dwt_t* restrict v , float* restrict a , int x){
-       v4* restrict bi = v->wavelet + v->cas;
-       int i;
+void opj_v4dwt_interleave_v(opj_v4dwt_t* restrict v , OPJ_FLOAT32* restrict a , OPJ_INT32 x, OPJ_INT32 nb_elts_read){
+       opj_v4_t* restrict bi = v->wavelet + v->cas;
+       OPJ_INT32 i;
+
        for(i = 0; i < v->sn; ++i){
-               memcpy(&bi[i*2], &a[i*x], 4 * sizeof(float));
+               memcpy(&bi[i*2], &a[i*x], (size_t)nb_elts_read * sizeof(OPJ_FLOAT32));
        }
+
        a += v->sn * x;
        bi = v->wavelet + 1 - v->cas;
+
        for(i = 0; i < v->dn; ++i){
-               memcpy(&bi[i*2], &a[i*x], 4 * sizeof(float));
+               memcpy(&bi[i*2], &a[i*x], (size_t)nb_elts_read * sizeof(OPJ_FLOAT32));
        }
 }
 
 #ifdef __SSE__
 
-static void v4dwt_decode_step1_sse(v4* w, int count, const __m128 c){
+void opj_v4dwt_decode_step1_sse(opj_v4_t* w, OPJ_INT32 count, const __m128 c){
        __m128* restrict vw = (__m128*) w;
-       int i;
+       OPJ_INT32 i;
        /* 4x unrolled loop */
        for(i = 0; i < count >> 2; ++i){
                *vw = _mm_mul_ps(*vw, c);
@@ -641,10 +694,10 @@ static void v4dwt_decode_step1_sse(v4* w, int count, const __m128 c){
        }
 }
 
-static void v4dwt_decode_step2_sse(v4* l, v4* w, int k, int m, __m128 c){
+void opj_v4dwt_decode_step2_sse(opj_v4_t* l, opj_v4_t* w, OPJ_INT32 k, OPJ_INT32 m, __m128 c){
        __m128* restrict vl = (__m128*) l;
        __m128* restrict vw = (__m128*) w;
-       int i;
+       OPJ_INT32 i;
        __m128 tmp1, tmp2, tmp3;
        tmp1 = vl[0];
        for(i = 0; i < m; ++i){
@@ -669,14 +722,15 @@ static void v4dwt_decode_step2_sse(v4* l, v4* w, int k, int m, __m128 c){
 
 #else
 
-static void v4dwt_decode_step1(v4* w, int count, const float c){
-       float* restrict fw = (float*) w;
-       int i;
+void opj_v4dwt_decode_step1(opj_v4_t* w, OPJ_INT32 count, const OPJ_FLOAT32 c)
+{
+       OPJ_FLOAT32* restrict fw = (OPJ_FLOAT32*) w;
+       OPJ_INT32 i;
        for(i = 0; i < count; ++i){
-               float tmp1 = fw[i*8    ];
-               float tmp2 = fw[i*8 + 1];
-               float tmp3 = fw[i*8 + 2];
-               float tmp4 = fw[i*8 + 3];
+               OPJ_FLOAT32 tmp1 = fw[i*8    ];
+               OPJ_FLOAT32 tmp2 = fw[i*8 + 1];
+               OPJ_FLOAT32 tmp3 = fw[i*8 + 2];
+               OPJ_FLOAT32 tmp4 = fw[i*8 + 3];
                fw[i*8    ] = tmp1 * c;
                fw[i*8 + 1] = tmp2 * c;
                fw[i*8 + 2] = tmp3 * c;
@@ -684,23 +738,24 @@ static void v4dwt_decode_step1(v4* w, int count, const float c){
        }
 }
 
-static void v4dwt_decode_step2(v4* l, v4* w, int k, int m, float c){
-       float* restrict fl = (float*) l;
-       float* restrict fw = (float*) w;
-       int i;
+void opj_v4dwt_decode_step2(opj_v4_t* l, opj_v4_t* w, OPJ_INT32 k, OPJ_INT32 m, OPJ_FLOAT32 c)
+{
+       OPJ_FLOAT32* restrict fl = (OPJ_FLOAT32*) l;
+       OPJ_FLOAT32* restrict fw = (OPJ_FLOAT32*) w;
+       OPJ_INT32 i;
        for(i = 0; i < m; ++i){
-               float tmp1_1 = fl[0];
-               float tmp1_2 = fl[1];
-               float tmp1_3 = fl[2];
-               float tmp1_4 = fl[3];
-               float tmp2_1 = fw[-4];
-               float tmp2_2 = fw[-3];
-               float tmp2_3 = fw[-2];
-               float tmp2_4 = fw[-1];
-               float tmp3_1 = fw[0];
-               float tmp3_2 = fw[1];
-               float tmp3_3 = fw[2];
-               float tmp3_4 = fw[3];
+               OPJ_FLOAT32 tmp1_1 = fl[0];
+               OPJ_FLOAT32 tmp1_2 = fl[1];
+               OPJ_FLOAT32 tmp1_3 = fl[2];
+               OPJ_FLOAT32 tmp1_4 = fl[3];
+               OPJ_FLOAT32 tmp2_1 = fw[-4];
+               OPJ_FLOAT32 tmp2_2 = fw[-3];
+               OPJ_FLOAT32 tmp2_3 = fw[-2];
+               OPJ_FLOAT32 tmp2_4 = fw[-1];
+               OPJ_FLOAT32 tmp3_1 = fw[0];
+               OPJ_FLOAT32 tmp3_2 = fw[1];
+               OPJ_FLOAT32 tmp3_3 = fw[2];
+               OPJ_FLOAT32 tmp3_4 = fw[3];
                fw[-4] = tmp2_1 + ((tmp1_1 + tmp3_1) * c);
                fw[-3] = tmp2_2 + ((tmp1_2 + tmp3_2) * c);
                fw[-2] = tmp2_3 + ((tmp1_3 + tmp3_3) * c);
@@ -709,20 +764,20 @@ static void v4dwt_decode_step2(v4* l, v4* w, int k, int m, float c){
                fw += 8;
        }
        if(m < k){
-               float c1;
-               float c2;
-               float c3;
-               float c4;
+               OPJ_FLOAT32 c1;
+               OPJ_FLOAT32 c2;
+               OPJ_FLOAT32 c3;
+               OPJ_FLOAT32 c4;
                c += c;
                c1 = fl[0] * c;
                c2 = fl[1] * c;
                c3 = fl[2] * c;
                c4 = fl[3] * c;
                for(; m < k; ++m){
-                       float tmp1 = fw[-4];
-                       float tmp2 = fw[-3];
-                       float tmp3 = fw[-2];
-                       float tmp4 = fw[-1];
+                       OPJ_FLOAT32 tmp1 = fw[-4];
+                       OPJ_FLOAT32 tmp2 = fw[-3];
+                       OPJ_FLOAT32 tmp3 = fw[-2];
+                       OPJ_FLOAT32 tmp4 = fw[-1];
                        fw[-4] = tmp1 + c1;
                        fw[-3] = tmp2 + c2;
                        fw[-2] = tmp3 + c3;
@@ -737,8 +792,9 @@ static void v4dwt_decode_step2(v4* l, v4* w, int k, int m, float c){
 /* <summary>                             */
 /* Inverse 9-7 wavelet transform in 1-D. */
 /* </summary>                            */
-static void v4dwt_decode(v4dwt_t* restrict dwt){
-       int a, b;
+void opj_v4dwt_decode(opj_v4dwt_t* restrict dwt)
+{
+       OPJ_INT32 a, b;
        if(dwt->cas == 0) {
                if(!((dwt->dn > 0) || (dwt->sn > 1))){
                        return;
@@ -753,106 +809,117 @@ static void v4dwt_decode(v4dwt_t* restrict dwt){
                b = 0;
        }
 #ifdef __SSE__
-       v4dwt_decode_step1_sse(dwt->wavelet+a, dwt->sn, _mm_set1_ps(K));
-       v4dwt_decode_step1_sse(dwt->wavelet+b, dwt->dn, _mm_set1_ps(c13318));
-       v4dwt_decode_step2_sse(dwt->wavelet+b, dwt->wavelet+a+1, dwt->sn, int_min(dwt->sn, dwt->dn-a), _mm_set1_ps(dwt_delta));
-       v4dwt_decode_step2_sse(dwt->wavelet+a, dwt->wavelet+b+1, dwt->dn, int_min(dwt->dn, dwt->sn-b), _mm_set1_ps(dwt_gamma));
-       v4dwt_decode_step2_sse(dwt->wavelet+b, dwt->wavelet+a+1, dwt->sn, int_min(dwt->sn, dwt->dn-a), _mm_set1_ps(dwt_beta));
-       v4dwt_decode_step2_sse(dwt->wavelet+a, dwt->wavelet+b+1, dwt->dn, int_min(dwt->dn, dwt->sn-b), _mm_set1_ps(dwt_alpha));
+       opj_v4dwt_decode_step1_sse(dwt->wavelet+a, dwt->sn, _mm_set1_ps(opj_K));
+       opj_v4dwt_decode_step1_sse(dwt->wavelet+b, dwt->dn, _mm_set1_ps(opj_c13318));
+       opj_v4dwt_decode_step2_sse(dwt->wavelet+b, dwt->wavelet+a+1, dwt->sn, opj_int_min(dwt->sn, dwt->dn-a), _mm_set1_ps(opj_dwt_delta));
+       opj_v4dwt_decode_step2_sse(dwt->wavelet+a, dwt->wavelet+b+1, dwt->dn, opj_int_min(dwt->dn, dwt->sn-b), _mm_set1_ps(opj_dwt_gamma));
+       opj_v4dwt_decode_step2_sse(dwt->wavelet+b, dwt->wavelet+a+1, dwt->sn, opj_int_min(dwt->sn, dwt->dn-a), _mm_set1_ps(opj_dwt_beta));
+       opj_v4dwt_decode_step2_sse(dwt->wavelet+a, dwt->wavelet+b+1, dwt->dn, opj_int_min(dwt->dn, dwt->sn-b), _mm_set1_ps(opj_dwt_alpha));
 #else
-       v4dwt_decode_step1(dwt->wavelet+a, dwt->sn, K);
-       v4dwt_decode_step1(dwt->wavelet+b, dwt->dn, c13318);
-       v4dwt_decode_step2(dwt->wavelet+b, dwt->wavelet+a+1, dwt->sn, int_min(dwt->sn, dwt->dn-a), dwt_delta);
-       v4dwt_decode_step2(dwt->wavelet+a, dwt->wavelet+b+1, dwt->dn, int_min(dwt->dn, dwt->sn-b), dwt_gamma);
-       v4dwt_decode_step2(dwt->wavelet+b, dwt->wavelet+a+1, dwt->sn, int_min(dwt->sn, dwt->dn-a), dwt_beta);
-       v4dwt_decode_step2(dwt->wavelet+a, dwt->wavelet+b+1, dwt->dn, int_min(dwt->dn, dwt->sn-b), dwt_alpha);
+       opj_v4dwt_decode_step1(dwt->wavelet+a, dwt->sn, opj_K);
+       opj_v4dwt_decode_step1(dwt->wavelet+b, dwt->dn, opj_c13318);
+       opj_v4dwt_decode_step2(dwt->wavelet+b, dwt->wavelet+a+1, dwt->sn, opj_int_min(dwt->sn, dwt->dn-a), opj_dwt_delta);
+       opj_v4dwt_decode_step2(dwt->wavelet+a, dwt->wavelet+b+1, dwt->dn, opj_int_min(dwt->dn, dwt->sn-b), opj_dwt_gamma);
+       opj_v4dwt_decode_step2(dwt->wavelet+b, dwt->wavelet+a+1, dwt->sn, opj_int_min(dwt->sn, dwt->dn-a), opj_dwt_beta);
+       opj_v4dwt_decode_step2(dwt->wavelet+a, dwt->wavelet+b+1, dwt->dn, opj_int_min(dwt->dn, dwt->sn-b), opj_dwt_alpha);
 #endif
 }
 
+
 /* <summary>                             */
 /* Inverse 9-7 wavelet transform in 2-D. */
 /* </summary>                            */
-void dwt_decode_real(opj_tcd_tilecomp_t* restrict tilec, int numres){
-       v4dwt_t h;
-       v4dwt_t v;
+OPJ_BOOL opj_dwt_decode_real(opj_tcd_tilecomp_t* restrict tilec, OPJ_UINT32 numres)
+{
+       opj_v4dwt_t h;
+       opj_v4dwt_t v;
 
        opj_tcd_resolution_t* res = tilec->resolutions;
 
-       int rw = res->x1 - res->x0;     /* width of the resolution level computed */
-       int rh = res->y1 - res->y0;     /* height of the resolution level computed */
+       OPJ_UINT32 rw = (OPJ_UINT32)(res->x1 - res->x0);        /* width of the resolution level computed */
+       OPJ_UINT32 rh = (OPJ_UINT32)(res->y1 - res->y0);        /* height of the resolution level computed */
 
-       int w = tilec->x1 - tilec->x0;
+       OPJ_UINT32 w = (OPJ_UINT32)(tilec->x1 - tilec->x0);
 
-       h.wavelet = (v4*) opj_aligned_malloc((dwt_decode_max_resolution(res, numres)+5) * sizeof(v4));
+       h.wavelet = (opj_v4_t*) opj_aligned_malloc((opj_dwt_max_resolution(res, numres)+5) * sizeof(opj_v4_t));
        v.wavelet = h.wavelet;
 
        while( --numres) {
-               float * restrict aj = (float*) tilec->data;
-               int bufsize = (tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0);
-               int j;
+               OPJ_FLOAT32 * restrict aj = (OPJ_FLOAT32*) tilec->data;
+               OPJ_UINT32 bufsize = (OPJ_UINT32)((tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0));
+               OPJ_INT32 j;
 
-               h.sn = rw;
-               v.sn = rh;
+               h.sn = (OPJ_INT32)rw;
+               v.sn = (OPJ_INT32)rh;
 
                ++res;
 
-               rw = res->x1 - res->x0; /* width of the resolution level computed */
-               rh = res->y1 - res->y0; /* height of the resolution level computed */
+               rw = (OPJ_UINT32)(res->x1 - res->x0);   /* width of the resolution level computed */
+               rh = (OPJ_UINT32)(res->y1 - res->y0);   /* height of the resolution level computed */
 
-               h.dn = rw - h.sn;
+               h.dn = (OPJ_INT32)(rw - (OPJ_UINT32)h.sn);
                h.cas = res->x0 % 2;
 
-               for(j = rh; j > 3; j -= 4){
-                       int k;
-                       v4dwt_interleave_h(&h, aj, w, bufsize);
-                       v4dwt_decode(&h);
-                               for(k = rw; --k >= 0;){
-                                       aj[k    ] = h.wavelet[k].f[0];
-                                       aj[k+w  ] = h.wavelet[k].f[1];
-                                       aj[k+w*2] = h.wavelet[k].f[2];
-                                       aj[k+w*3] = h.wavelet[k].f[3];
-                               }
+               for(j = (OPJ_INT32)rh; j > 3; j -= 4) {
+                       OPJ_INT32 k;
+                       opj_v4dwt_interleave_h(&h, aj, (OPJ_INT32)w, (OPJ_INT32)bufsize);
+                       opj_v4dwt_decode(&h);
+
+                       for(k = (OPJ_INT32)rw; --k >= 0;){
+                               aj[k               ] = h.wavelet[k].f[0];
+                               aj[k+(OPJ_INT32)w  ] = h.wavelet[k].f[1];
+                               aj[k+(OPJ_INT32)w*2] = h.wavelet[k].f[2];
+                               aj[k+(OPJ_INT32)w*3] = h.wavelet[k].f[3];
+                       }
+
                        aj += w*4;
                        bufsize -= w*4;
                }
+
                if (rh & 0x03) {
-                               int k;
+                       OPJ_INT32 k;
                        j = rh & 0x03;
-                       v4dwt_interleave_h(&h, aj, w, bufsize);
-                       v4dwt_decode(&h);
-                               for(k = rw; --k >= 0;){
-                                       switch(j) {
-                                               case 3: aj[k+w*2] = h.wavelet[k].f[2];
-                                               case 2: aj[k+w  ] = h.wavelet[k].f[1];
-                                               case 1: aj[k    ] = h.wavelet[k].f[0];
-                                       }
+                       opj_v4dwt_interleave_h(&h, aj, (OPJ_INT32)w, (OPJ_INT32)bufsize);
+                       opj_v4dwt_decode(&h);
+                       for(k = (OPJ_INT32)rw; --k >= 0;){
+                               switch(j) {
+                                       case 3: aj[k+(OPJ_INT32)w*2] = h.wavelet[k].f[2];
+                                       case 2: aj[k+(OPJ_INT32)w  ] = h.wavelet[k].f[1];
+                                       case 1: aj[k               ] = h.wavelet[k].f[0];
                                }
                        }
+               }
 
-               v.dn = rh - v.sn;
+               v.dn = (OPJ_INT32)(rh - (OPJ_UINT32)v.sn);
                v.cas = res->y0 % 2;
 
-               aj = (float*) tilec->data;
-               for(j = rw; j > 3; j -= 4){
-                       int k;
-                       v4dwt_interleave_v(&v, aj, w);
-                       v4dwt_decode(&v);
-                               for(k = 0; k < rh; ++k){
-                                       memcpy(&aj[k*w], &v.wavelet[k], 4 * sizeof(float));
-                               }
+               aj = (OPJ_FLOAT32*) tilec->data;
+               for(j = (OPJ_INT32)rw; j > 3; j -= 4){
+                       OPJ_UINT32 k;
+
+                       opj_v4dwt_interleave_v(&v, aj, (OPJ_INT32)w, 4);
+                       opj_v4dwt_decode(&v);
+
+                       for(k = 0; k < rh; ++k){
+                               memcpy(&aj[k*w], &v.wavelet[k], 4 * sizeof(OPJ_FLOAT32));
+                       }
                        aj += 4;
                }
+
                if (rw & 0x03){
-                               int k;
+                       OPJ_UINT32 k;
+
                        j = rw & 0x03;
-                       v4dwt_interleave_v(&v, aj, w);
-                       v4dwt_decode(&v);
-                               for(k = 0; k < rh; ++k){
-                                       memcpy(&aj[k*w], &v.wavelet[k], j * sizeof(float));
-                               }
+
+                       opj_v4dwt_interleave_v(&v, aj, (OPJ_INT32)w, j);
+                       opj_v4dwt_decode(&v);
+
+                       for(k = 0; k < rh; ++k){
+                               memcpy(&aj[k*w], &v.wavelet[k], (size_t)j * sizeof(OPJ_FLOAT32));
                        }
+               }
        }
 
        opj_aligned_free(h.wavelet);
+       return OPJ_TRUE;
 }
-
index adf73e5..f8b57bc 100644 (file)
@@ -1,9 +1,15 @@
 /*
- * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
- * Copyright (c) 2002-2007, Professor Benoit Macq
+ * 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 and Antonin Descampe
+ * Copyright (c) 2003-2007, Francois-Olivier Devaux 
+ * Copyright (c) 2003-2014, Antonin Descampe
  * Copyright (c) 2005, Herve Drolon, FreeImage Team
  * All rights reserved.
  *
@@ -52,59 +58,62 @@ Forward 5-3 wavelet tranform in 2-D.
 Apply a reversible DWT transform to a component of an image.
 @param tilec Tile component information (current tile)
 */
-void dwt_encode(opj_tcd_tilecomp_t * tilec);
+OPJ_BOOL opj_dwt_encode(opj_tcd_tilecomp_t * tilec);
+
 /**
 Inverse 5-3 wavelet tranform in 2-D.
 Apply a reversible inverse DWT transform to a component of an image.
 @param tilec Tile component information (current tile)
 @param numres Number of resolution levels to decode
 */
-void dwt_decode(opj_tcd_tilecomp_t* tilec, int numres);
+OPJ_BOOL opj_dwt_decode(opj_tcd_tilecomp_t* tilec, OPJ_UINT32 numres);
+
 /**
 Get the gain of a subband for the reversible 5-3 DWT.
 @param orient Number that identifies the subband (0->LL, 1->HL, 2->LH, 3->HH)
 @return Returns 0 if orient = 0, returns 1 if orient = 1 or 2, returns 2 otherwise
 */
-int dwt_getgain(int orient);
+OPJ_UINT32 opj_dwt_getgain(OPJ_UINT32 orient) ;
 /**
 Get the norm of a wavelet function of a subband at a specified level for the reversible 5-3 DWT.
 @param level Level of the wavelet function
 @param orient Band of the wavelet function
 @return Returns the norm of the wavelet function
 */
-double dwt_getnorm(int level, int orient);
+OPJ_FLOAT64 opj_dwt_getnorm(OPJ_UINT32 level, OPJ_UINT32 orient);
 /**
 Forward 9-7 wavelet transform in 2-D. 
 Apply an irreversible DWT transform to a component of an image.
 @param tilec Tile component information (current tile)
 */
-void dwt_encode_real(opj_tcd_tilecomp_t * tilec);
+OPJ_BOOL opj_dwt_encode_real(opj_tcd_tilecomp_t * tilec);
 /**
 Inverse 9-7 wavelet transform in 2-D. 
 Apply an irreversible inverse DWT transform to a component of an image.
 @param tilec Tile component information (current tile)
 @param numres Number of resolution levels to decode
 */
-void dwt_decode_real(opj_tcd_tilecomp_t* tilec, int numres);
+OPJ_BOOL opj_dwt_decode_real(opj_tcd_tilecomp_t* restrict tilec, OPJ_UINT32 numres);
+
 /**
 Get the gain of a subband for the irreversible 9-7 DWT.
 @param orient Number that identifies the subband (0->LL, 1->HL, 2->LH, 3->HH)
 @return Returns the gain of the 9-7 wavelet transform
 */
-int dwt_getgain_real(int orient);
+OPJ_UINT32 opj_dwt_getgain_real(OPJ_UINT32 orient);
 /**
 Get the norm of a wavelet function of a subband at a specified level for the irreversible 9-7 DWT
 @param level Level of the wavelet function
 @param orient Band of the wavelet function
 @return Returns the norm of the 9-7 wavelet
 */
-double dwt_getnorm_real(int level, int orient);
+OPJ_FLOAT64 opj_dwt_getnorm_real(OPJ_UINT32 level, OPJ_UINT32 orient);
 /**
 Explicit calculation of the Quantization Stepsizes 
 @param tccp Tile-component coding parameters
 @param prec Precint analyzed
 */
-void dwt_calc_explicit_stepsizes(opj_tccp_t * tccp, int prec);
+void opj_dwt_calc_explicit_stepsizes(opj_tccp_t * tccp, OPJ_UINT32 prec);
 /* ----------------------------------------------------------------------- */
 /*@}*/
 
index 38db33a..b6034b4 100644 (file)
@@ -1,5 +1,12 @@
 /*
+ * 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) 2005, Herve Drolon, FreeImage Team
+ * 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
@@ -60,62 +67,80 @@ _itoa(int i, char *a, int r) {
 
 #endif /* !_WIN32 */
 #endif
+
 /* ----------------------------------------------------------------------- */
+/**
+ * Default callback function.
+ * Do nothing.
+ */
+static void opj_default_callback (const char *msg, void *client_data)
+{
+    OPJ_ARG_NOT_USED(msg);
+    OPJ_ARG_NOT_USED(client_data);
+}
 
-opj_event_mgr_t* OPJ_CALLCONV opj_set_event_mgr(opj_common_ptr cinfo, opj_event_mgr_t *event_mgr, void *context) {
-       if(cinfo) {
-               opj_event_mgr_t *previous = cinfo->event_mgr;
-               cinfo->event_mgr = event_mgr;
-               cinfo->client_data = context;
-               return previous;
-       }
+/* ----------------------------------------------------------------------- */
 
-       return NULL;
-}
 
-opj_bool opj_event_msg(opj_common_ptr cinfo, int event_type, const char *fmt, ...) {
-#define MSG_SIZE 512 /* 512 bytes should be more than enough for a short message */
-       opj_msg_callback msg_handler = NULL;
+/* ----------------------------------------------------------------------- */
+OPJ_BOOL opj_event_msg(opj_event_mgr_t* p_event_mgr, OPJ_INT32 event_type, const char *fmt, ...) {
+#define OPJ_MSG_SIZE 512 /* 512 bytes should be more than enough for a short message */
+       opj_msg_callback msg_handler = 00;
+       void * l_data = 00;
 
-       opj_event_mgr_t *event_mgr = cinfo->event_mgr;
-       if(event_mgr != NULL) {
+       if(p_event_mgr != 00) {
                switch(event_type) {
                        case EVT_ERROR:
-                               msg_handler = event_mgr->error_handler;
+                               msg_handler = p_event_mgr->error_handler;
+                               l_data = p_event_mgr->m_error_data;
                                break;
                        case EVT_WARNING:
-                               msg_handler = event_mgr->warning_handler;
+                               msg_handler = p_event_mgr->warning_handler;
+                               l_data = p_event_mgr->m_warning_data;
                                break;
                        case EVT_INFO:
-                               msg_handler = event_mgr->info_handler;
+                               msg_handler = p_event_mgr->info_handler;
+                               l_data = p_event_mgr->m_info_data;
                                break;
                        default:
                                break;
                }
-               if(msg_handler == NULL) {
+               if(msg_handler == 00) {
                        return OPJ_FALSE;
                }
        } else {
                return OPJ_FALSE;
        }
 
-       if ((fmt != NULL) && (event_mgr != NULL)) {
+       if ((fmt != 00) && (p_event_mgr != 00)) {
                va_list arg;
-               int str_length/*, i, j*/; /* UniPG */
-               char message[MSG_SIZE];
+               size_t str_length/*, i, j*/; /* UniPG */
+               char message[OPJ_MSG_SIZE];
+               memset(message, 0, OPJ_MSG_SIZE);
                /* initialize the optional parameter list */
                va_start(arg, fmt);
+               /* check the length of the format string */
+               str_length = (strlen(fmt) > OPJ_MSG_SIZE) ? OPJ_MSG_SIZE : strlen(fmt);
+        (void)str_length;
                /* parse the format string and put the result in 'message' */
-               str_length = vsnprintf(message, MSG_SIZE, fmt, arg); /* UniPG */
+               vsnprintf(message, OPJ_MSG_SIZE, fmt, arg); /* UniPG */
                /* deinitialize the optional parameter list */
                va_end(arg);
 
                /* output the message to the user program */
-    if( str_length > -1 && str_length < MSG_SIZE )
-      msg_handler(message, cinfo->client_data);
-    else return OPJ_FALSE;
+               msg_handler(message, l_data);
        }
 
        return OPJ_TRUE;
 }
 
+void opj_set_default_event_handler(opj_event_mgr_t * p_manager)
+{
+       p_manager->m_error_data = 00;
+       p_manager->m_warning_data = 00;
+       p_manager->m_info_data = 00;
+       p_manager->error_handler = opj_default_callback;
+       p_manager->info_handler = opj_default_callback;
+       p_manager->warning_handler = opj_default_callback;
+}
+
index 9c59787..88e0395 100644 (file)
@@ -1,5 +1,12 @@
 /*
+ * 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) 2005, Herve Drolon, FreeImage Team
+ * 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
 
 The functions in EVENT.C have for goal to send output messages (errors, warnings, debug) to the user.
 */
+/**
+Message handler object
+used for 
+<ul>
+<li>Error messages
+<li>Warning messages
+<li>Debugging messages
+</ul>
+*/
+typedef struct opj_event_mgr 
+{
+       /** Data to call the event manager upon */
+       void *                  m_error_data;
+       /** Data to call the event manager upon */
+       void *                  m_warning_data;
+       /** Data to call the event manager upon */
+       void *                  m_info_data;
+       /** Error message callback if available, NULL otherwise */
+       opj_msg_callback error_handler;
+       /** Warning message callback if available, NULL otherwise */
+       opj_msg_callback warning_handler;
+       /** Debug message callback if available, NULL otherwise */
+       opj_msg_callback info_handler;
+} opj_event_mgr_t;
+
 
 #define EVT_ERROR      1       /**< Error event type */
 #define EVT_WARNING    2       /**< Warning event type */
@@ -42,15 +74,27 @@ The functions in EVENT.C have for goal to send output messages (errors, warnings
 /** @name Exported functions (see also openjpeg.h) */
 /*@{*/
 /* ----------------------------------------------------------------------- */
+
+
+/* ----------------------------------------------------------------------- */
+
 /**
-Write formatted data to a string and send the string to a user callback. 
-@param cinfo Codec context info
-@param event_type Event type or callback to use to send the message
-@param fmt Format-control string (plus optionnal arguments)
-@return Returns true if successful, returns false otherwise
-*/
-opj_bool opj_event_msg(opj_common_ptr cinfo, int event_type, const char *fmt, ...);
+ * Write formatted data to a string and send the string to a user callback.
+ *
+ * @param event_mgr                    Event handler
+ * @param event_type           Event type or callback to use to send the message
+ * @param fmt                          Format-control string (plus optional arguments)
+ *
+ * @return Returns true if successful, returns false otherwise
+ */
+OPJ_BOOL opj_event_msg(opj_event_mgr_t* event_mgr, OPJ_INT32 event_type, const char *fmt, ...);
 /* ----------------------------------------------------------------------- */
+
+/**
+ * Set the event manager with the default callback function for the 3 levels.
+ */
+void opj_set_default_event_handler(opj_event_mgr_t * p_manager);
+
 /*@}*/
 
 /*@}*/
diff --git a/extern/libopenjpeg/function_list.c b/extern/libopenjpeg/function_list.c
new file mode 100644 (file)
index 0000000..4c8aae6
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ * 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) 2008, Jerome Fimes, Communications & Systemes <jerome.fimes@c-s.fr>
+ * 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"
+
+/**
+ * Default size of the validation list, if not sufficient, data will be reallocated with a double size.
+ */
+#define OPJ_VALIDATION_SIZE 10
+
+opj_procedure_list_t *  opj_procedure_list_create()
+{
+        /* memory allocation */
+        opj_procedure_list_t * l_validation = (opj_procedure_list_t *) opj_malloc(sizeof(opj_procedure_list_t));
+        if (! l_validation)
+        {
+                return 00;
+        }
+        /* initialization */
+        memset(l_validation,0,sizeof(opj_procedure_list_t));
+        l_validation->m_nb_max_procedures = OPJ_VALIDATION_SIZE;
+        l_validation->m_procedures = (opj_procedure*)opj_malloc(
+                OPJ_VALIDATION_SIZE * sizeof(opj_procedure));
+        if (! l_validation->m_procedures)
+        {
+                opj_free(l_validation);
+                return 00;
+        }
+        memset(l_validation->m_procedures,0,OPJ_VALIDATION_SIZE * sizeof(opj_procedure));
+        return l_validation;
+}
+
+void  opj_procedure_list_destroy(opj_procedure_list_t * p_list)
+{
+        if (! p_list)
+        {
+                return;
+        }
+        /* initialization */
+        if (p_list->m_procedures)
+        {
+                opj_free(p_list->m_procedures);
+        }
+        opj_free(p_list);
+}
+
+OPJ_BOOL opj_procedure_list_add_procedure (opj_procedure_list_t * p_validation_list, opj_procedure p_procedure)
+{
+        if (p_validation_list->m_nb_max_procedures == p_validation_list->m_nb_procedures)
+        {
+                opj_procedure * new_procedures;
+
+                p_validation_list->m_nb_max_procedures += OPJ_VALIDATION_SIZE;
+                new_procedures = (opj_procedure*)opj_realloc(
+                        p_validation_list->m_procedures,
+                        p_validation_list->m_nb_max_procedures * sizeof(opj_procedure));
+                if (! new_procedures)
+                {
+                        opj_free(p_validation_list->m_procedures);
+                        p_validation_list->m_nb_max_procedures = 0;
+                        p_validation_list->m_nb_procedures = 0;
+                        /* opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to add a new validation procedure\n"); */
+                        fprintf(stderr, "Not enough memory to add a new validation procedure\n");
+                        
+                        return OPJ_FALSE;
+                }
+                else
+                {
+                        p_validation_list->m_procedures = new_procedures;
+                }
+        }
+        p_validation_list->m_procedures[p_validation_list->m_nb_procedures] = p_procedure;
+        ++p_validation_list->m_nb_procedures;
+
+        return OPJ_TRUE;
+}
+
+OPJ_UINT32 opj_procedure_list_get_nb_procedures (opj_procedure_list_t * p_validation_list)
+{
+        return p_validation_list->m_nb_procedures;
+}
+
+opj_procedure* opj_procedure_list_get_first_procedure (opj_procedure_list_t * p_validation_list)
+{
+        return p_validation_list->m_procedures;
+}
+
+void opj_procedure_list_clear (opj_procedure_list_t * p_validation_list)
+{
+        p_validation_list->m_nb_procedures = 0;
+}
diff --git a/extern/libopenjpeg/function_list.h b/extern/libopenjpeg/function_list.h
new file mode 100644 (file)
index 0000000..749ad9e
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ * 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) 2008, Jerome Fimes, Communications & Systemes <jerome.fimes@c-s.fr>
+ * 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.
+ */
+
+#ifndef __FUNCTION_LIST_H
+#define __FUNCTION_LIST_H
+
+/** 
+ * @file function_list.h
+ * @brief Implementation of a list of procedures.
+
+ * The functions in validation.c aims to have access to a list of procedures.
+*/
+
+/** @defgroup VAL VAL - validation procedure*/
+/*@{*/
+
+/**************************************************************************************************
+ ***************************************** FORWARD DECLARATION ************************************
+ **************************************************************************************************/
+
+/**
+ * declare a function pointer
+ */
+typedef void (*opj_procedure)(void);
+
+/**
+ * A list of procedures.
+*/
+typedef struct opj_procedure_list 
+{
+       /**
+        * The number of validation procedures.
+        */
+       OPJ_UINT32 m_nb_procedures;
+       /**
+        * The number of the array of validation procedures.
+        */
+       OPJ_UINT32 m_nb_max_procedures;
+       /**
+        * The array of procedures.
+        */
+       opj_procedure * m_procedures;
+
+} opj_procedure_list_t;
+
+/* ----------------------------------------------------------------------- */
+
+/**
+ * Creates a validation list.
+ *
+ * @return     the newly created validation list.
+ */
+opj_procedure_list_t *  opj_procedure_list_create(void);
+
+/**
+ * Destroys a validation list.
+ *
+ * @param p_list the list to destroy.
+ */
+void  opj_procedure_list_destroy(opj_procedure_list_t * p_list);
+
+/**
+ * Adds a new validation procedure.
+ *
+ * @param      p_validation_list the list of procedure to modify.
+ * @param      p_procedure             the procedure to add.
+ *
+ * @return     OPJ_TRUE if the procedure could be added.
+ */
+OPJ_BOOL opj_procedure_list_add_procedure (opj_procedure_list_t * p_validation_list, opj_procedure p_procedure);
+
+/**
+ * Gets the number of validation procedures.
+ *
+ * @param      p_validation_list the list of procedure to modify.
+ *
+ * @return the number of validation procedures.
+ */
+OPJ_UINT32 opj_procedure_list_get_nb_procedures (opj_procedure_list_t * p_validation_list);
+
+/**
+ * Gets the pointer on the first validation procedure. This function is similar to the C++
+ * iterator class to iterate through all the procedures inside the validation list.
+ * the caller does not take ownership of the pointer.
+ *
+ * @param      p_validation_list the list of procedure to get the first procedure from.
+ *
+ * @return     a pointer to the first procedure.
+ */
+opj_procedure* opj_procedure_list_get_first_procedure (opj_procedure_list_t * p_validation_list);
+
+
+/**
+ * Clears the list of validation procedures.
+ *
+ * @param      p_validation_list the list of procedure to clear.
+ *
+ */
+void opj_procedure_list_clear (opj_procedure_list_t * p_validation_list);
+/*@}*/
+
+#endif /* __FUNCTION_LIST_H */
+
index 579fd73..2c3540c 100644 (file)
@@ -1,4 +1,9 @@
 /*
+ * 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) 2005, Herve Drolon, FreeImage Team
  * All rights reserved.
  *
@@ -31,8 +36,8 @@ opj_image_t* opj_image_create0(void) {
        return image;
 }
 
-opj_image_t* OPJ_CALLCONV opj_image_create(int numcmpts, opj_image_cmptparm_t *cmptparms, OPJ_COLOR_SPACE clrspc) {
-       int compno;
+opj_image_t* OPJ_CALLCONV opj_image_create(OPJ_UINT32 numcmpts, opj_image_cmptparm_t *cmptparms, OPJ_COLOR_SPACE clrspc) {
+       OPJ_UINT32 compno;
        opj_image_t *image = NULL;
 
        image = (opj_image_t*) opj_calloc(1, sizeof(opj_image_t));
@@ -58,7 +63,7 @@ opj_image_t* OPJ_CALLCONV opj_image_create(int numcmpts, opj_image_cmptparm_t *c
                        comp->prec = cmptparms[compno].prec;
                        comp->bpp = cmptparms[compno].bpp;
                        comp->sgnd = cmptparms[compno].sgnd;
-                       comp->data = (int*) opj_calloc(comp->w * comp->h, sizeof(int));
+                       comp->data = (OPJ_INT32*) opj_calloc(comp->w * comp->h, sizeof(OPJ_INT32));
                        if(!comp->data) {
                                fprintf(stderr,"Unable to allocate memory for image.\n");
                                opj_image_destroy(image);
@@ -71,19 +76,165 @@ opj_image_t* OPJ_CALLCONV opj_image_create(int numcmpts, opj_image_cmptparm_t *c
 }
 
 void OPJ_CALLCONV opj_image_destroy(opj_image_t *image) {
-       int i;
        if(image) {
                if(image->comps) {
+                       OPJ_UINT32 compno;
+
                        /* image components */
-                       for(i = 0; i < image->numcomps; i++) {
-                               opj_image_comp_t *image_comp = &image->comps[i];
+                       for(compno = 0; compno < image->numcomps; compno++) {
+                               opj_image_comp_t *image_comp = &(image->comps[compno]);
                                if(image_comp->data) {
                                        opj_free(image_comp->data);
                                }
                        }
                        opj_free(image->comps);
                }
+
+               if(image->icc_profile_buf) {
+                       opj_free(image->icc_profile_buf);
+               }
+
                opj_free(image);
        }
 }
 
+/**
+ * Updates the components characteristics of the image from the coding parameters.
+ *
+ * @param p_image_header       the image header to update.
+ * @param p_cp                         the coding parameters from which to update the image.
+ */
+void opj_image_comp_header_update(opj_image_t * p_image_header, const struct opj_cp * p_cp)
+{
+       OPJ_UINT32 i, l_width, l_height;
+       OPJ_INT32 l_x0, l_y0, l_x1, l_y1;
+       OPJ_INT32 l_comp_x0, l_comp_y0, l_comp_x1, l_comp_y1;
+       opj_image_comp_t* l_img_comp = NULL;
+
+       l_x0 = opj_int_max((OPJ_INT32)p_cp->tx0 , (OPJ_INT32)p_image_header->x0);
+       l_y0 = opj_int_max((OPJ_INT32)p_cp->ty0 , (OPJ_INT32)p_image_header->y0);
+       l_x1 = opj_int_min((OPJ_INT32)(p_cp->tx0 + p_cp->tw * p_cp->tdx), (OPJ_INT32)p_image_header->x1);
+       l_y1 = opj_int_min((OPJ_INT32)(p_cp->ty0 + p_cp->th * p_cp->tdy), (OPJ_INT32)p_image_header->y1);
+
+       l_img_comp = p_image_header->comps;
+       for     (i = 0; i < p_image_header->numcomps; ++i) {
+               l_comp_x0 = opj_int_ceildiv(l_x0, (OPJ_INT32)l_img_comp->dx);
+               l_comp_y0 = opj_int_ceildiv(l_y0, (OPJ_INT32)l_img_comp->dy);
+               l_comp_x1 = opj_int_ceildiv(l_x1, (OPJ_INT32)l_img_comp->dx);
+               l_comp_y1 = opj_int_ceildiv(l_y1, (OPJ_INT32)l_img_comp->dy);
+               l_width = (OPJ_UINT32)opj_int_ceildivpow2(l_comp_x1 - l_comp_x0, (OPJ_INT32)l_img_comp->factor);
+               l_height = (OPJ_UINT32)opj_int_ceildivpow2(l_comp_y1 - l_comp_y0, (OPJ_INT32)l_img_comp->factor);
+               l_img_comp->w = l_width;
+               l_img_comp->h = l_height;
+               l_img_comp->x0 = (OPJ_UINT32)l_comp_x0/*l_x0*/;
+               l_img_comp->y0 = (OPJ_UINT32)l_comp_y0/*l_y0*/;
+               ++l_img_comp;
+       }
+}
+
+
+/**
+ * Copy only header of image and its component header (no data are copied)
+ * if dest image have data, they will be freed
+ *
+ * @param      p_image_src             the src image
+ * @param      p_image_dest    the dest image
+ *
+ */
+void opj_copy_image_header(const opj_image_t* p_image_src, opj_image_t* p_image_dest)
+{
+       OPJ_UINT32 compno;
+
+       /* preconditions */
+       assert(p_image_src != 00);
+       assert(p_image_dest != 00);
+
+       p_image_dest->x0 = p_image_src->x0;
+       p_image_dest->y0 = p_image_src->y0;
+       p_image_dest->x1 = p_image_src->x1;
+       p_image_dest->y1 = p_image_src->y1;
+
+       if (p_image_dest->comps){
+               for(compno = 0; compno < p_image_dest->numcomps; compno++) {
+                       opj_image_comp_t *image_comp = &(p_image_dest->comps[compno]);
+                       if(image_comp->data) {
+                               opj_free(image_comp->data);
+                       }
+               }
+               opj_free(p_image_dest->comps);
+               p_image_dest->comps = NULL;
+       }
+
+       p_image_dest->numcomps = p_image_src->numcomps;
+
+       p_image_dest->comps = (opj_image_comp_t*) opj_malloc(p_image_dest->numcomps * sizeof(opj_image_comp_t));
+       if (!p_image_dest->comps){
+               p_image_dest->comps = NULL;
+               p_image_dest->numcomps = 0;
+               return;
+       }
+
+       for (compno=0; compno < p_image_dest->numcomps; compno++){
+               memcpy( &(p_image_dest->comps[compno]),
+                               &(p_image_src->comps[compno]),
+                               sizeof(opj_image_comp_t));
+               p_image_dest->comps[compno].data = NULL;
+       }
+
+       p_image_dest->color_space = p_image_src->color_space;
+       p_image_dest->icc_profile_len = p_image_src->icc_profile_len;
+
+       if (p_image_dest->icc_profile_len) {
+               p_image_dest->icc_profile_buf = (OPJ_BYTE*)opj_malloc(p_image_dest->icc_profile_len);
+               if (!p_image_dest->icc_profile_buf){
+                       p_image_dest->icc_profile_buf = NULL;
+                       p_image_dest->icc_profile_len = 0;
+                       return;
+               }
+               memcpy( p_image_dest->icc_profile_buf,
+                               p_image_src->icc_profile_buf,
+                               p_image_src->icc_profile_len);
+               }
+               else
+                       p_image_dest->icc_profile_buf = NULL;
+
+       return;
+}
+
+opj_image_t* OPJ_CALLCONV opj_image_tile_create(OPJ_UINT32 numcmpts, opj_image_cmptparm_t *cmptparms, OPJ_COLOR_SPACE clrspc) {
+       OPJ_UINT32 compno;
+       opj_image_t *image = 00;
+
+       image = (opj_image_t*) opj_malloc(sizeof(opj_image_t));
+       if (image)
+       {
+               memset(image,0,sizeof(opj_image_t));
+               
+               image->color_space = clrspc;
+               image->numcomps = numcmpts;
+               
+               /* allocate memory for the per-component information */
+               image->comps = (opj_image_comp_t*)opj_malloc(image->numcomps * sizeof(opj_image_comp_t));
+               if (!image->comps) {
+                       opj_image_destroy(image);
+                       return 00;
+               }
+               memset(image->comps,0,image->numcomps * sizeof(opj_image_comp_t));
+               
+               /* create the individual image components */
+               for(compno = 0; compno < numcmpts; compno++) {
+                       opj_image_comp_t *comp = &image->comps[compno];
+                       comp->dx = cmptparms[compno].dx;
+                       comp->dy = cmptparms[compno].dy;
+                       comp->w = cmptparms[compno].w;
+                       comp->h = cmptparms[compno].h;
+                       comp->x0 = cmptparms[compno].x0;
+                       comp->y0 = cmptparms[compno].y0;
+                       comp->prec = cmptparms[compno].prec;
+                       comp->sgnd = cmptparms[compno].sgnd;
+                       comp->data = 0;
+               }
+       }
+
+       return image;
+}
index f828b5b..e0e2772 100644 (file)
@@ -1,4 +1,9 @@
 /*
+ * 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) 2005, Herve Drolon, FreeImage Team
  * All rights reserved.
  *
 The functions in IMAGE.C have for goal to realize operations on images.
 */
 
+struct opj_image;
+struct opj_cp;
+
 /** @defgroup IMAGE IMAGE - Implementation of operations on images */
 /*@{*/
 
 /**
-Create an empty image
-@todo this function should be removed
-@return returns an empty image if successful, returns NULL otherwise
-*/
+ * Create an empty image
+ *
+ * @return returns an empty image if successful, returns NULL otherwise
+ */
 opj_image_t* opj_image_create0(void);
 
+
+
+/**
+ * Updates the components characteristics of the image from the coding parameters.
+ *
+ * @param p_image_header               the image header to update.
+ * @param p_cp                                 the coding parameters from which to update the image.
+ */
+void opj_image_comp_header_update(opj_image_t * p_image, const struct opj_cp* p_cp);
+
+void opj_copy_image_header(const opj_image_t* p_image_src, opj_image_t* p_image_dest);
+
 /*@}*/
 
 #endif /* __IMAGE_H */
index 7364df6..ec5525f 100644 (file)
@@ -1,8 +1,8 @@
 /*
  * $Id: indexbox_manager.h 897 2011-08-28 21:43:57Z Kaori.Hagihara@gmail.com $
  *
- * Copyright (c) 2002-2011, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
- * Copyright (c) 2002-2011, Professor Benoit Macq
+ * Copyright (c) 2002-2014, Universite catholique de Louvain (UCL), Belgium
+ * Copyright (c) 2002-2014, Professor Benoit Macq
  * Copyright (c) 2003-2004, Yannick Verschueren
  * Copyright (c) 2010-2011, Kaori Hagihara
  * All rights reserved.
@@ -65,7 +65,8 @@
  * @param[in] cio       file output handle
  * @return              length of tpix box
  */
-int write_tpix( int coff, opj_codestream_info_t cstr_info, int j2klen, opj_cio_t *cio);
+int opj_write_tpix( int coff, opj_codestream_info_t cstr_info, int j2klen, opj_stream_private_t *cio,
+              opj_event_mgr_t * p_manager );
 
 
 /* 
@@ -76,7 +77,7 @@ int write_tpix( int coff, opj_codestream_info_t cstr_info, int j2klen, opj_cio_t
  * @param[in] cio       file output handle
  * @return              length of thix box
  */
-int write_thix( int coff, opj_codestream_info_t cstr_info, opj_cio_t *cio);
+int opj_write_thix( int coff, opj_codestream_info_t cstr_info, opj_stream_private_t *cio, opj_event_mgr_t * p_manager );
 
 
 /* 
@@ -89,7 +90,8 @@ int write_thix( int coff, opj_codestream_info_t cstr_info, opj_cio_t *cio);
  * @param[in] cio       file output handle
  * @return              length of ppix box
  */
-int write_ppix( int coff, opj_codestream_info_t cstr_info, opj_bool EPHused, int j2klen, opj_cio_t *cio);
+int opj_write_ppix( int coff, opj_codestream_info_t cstr_info, OPJ_BOOL EPHused, int j2klen, opj_stream_private_t *cio,
+              opj_event_mgr_t * p_manager );
 
 
 /* 
@@ -102,7 +104,8 @@ int write_ppix( int coff, opj_codestream_info_t cstr_info, opj_bool EPHused, int
  * @param[in] cio       file output handle
  * @return              length of ppix box
  */
-int write_phix( int coff, opj_codestream_info_t cstr_info, opj_bool EPHused, int j2klen, opj_cio_t *cio);
+int opj_write_phix( int coff, opj_codestream_info_t cstr_info, OPJ_BOOL EPHused, int j2klen, opj_stream_private_t *cio,
+              opj_event_mgr_t * p_manager );
 
 /* 
  * Wriet manifest box (box)
@@ -112,7 +115,34 @@ int write_phix( int coff, opj_codestream_info_t cstr_info, opj_bool EPHused, int
  * @param[in] box    box to be manifested
  * @param[in] cio    file output handle
  */
-void write_manf(int second, int v, opj_jp2_box_t *box, opj_cio_t *cio);
 
+void opj_write_manf(int second, 
+                    int v, 
+                    opj_jp2_box_t *box, 
+                    opj_stream_private_t *cio,
+                    opj_event_mgr_t * p_manager );
+
+/* 
+ * Write main header index table (box)
+ *
+ * @param[in] coff offset of j2k codestream
+ * @param[in] cstr_info codestream information
+ * @param[in] cio  file output handle
+ * @return         length of mainmhix box
+ */
+int opj_write_mainmhix( int coff, opj_codestream_info_t cstr_info, opj_stream_private_t *cio,
+              opj_event_mgr_t * p_manager );
+
+int opj_write_phixfaix( int coff, int compno, opj_codestream_info_t cstr_info, OPJ_BOOL EPHused, int j2klen, opj_stream_private_t *cio,
+              opj_event_mgr_t * p_manager );
+
+int opj_write_ppixfaix( int coff, int compno, opj_codestream_info_t cstr_info, OPJ_BOOL EPHused, int j2klen, opj_stream_private_t *cio,
+              opj_event_mgr_t * p_manager );
+
+int opj_write_tilemhix( int coff, opj_codestream_info_t cstr_info, int tileno, opj_stream_private_t *cio,
+              opj_event_mgr_t * p_manager );
+
+int opj_write_tpixfaix( int coff, int compno, opj_codestream_info_t cstr_info, int j2klen, opj_stream_private_t *cio,
+              opj_event_mgr_t * p_manager );
 
 #endif      /* !INDEXBOX_MANAGER_H_ */
diff --git a/extern/libopenjpeg/invert.c b/extern/libopenjpeg/invert.c
new file mode 100644 (file)
index 0000000..4c1ee78
--- /dev/null
@@ -0,0 +1,294 @@
+/*
+ * 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) 2008, Jerome Fimes, Communications & Systemes <jerome.fimes@c-s.fr>
+ * 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"
+
+/** 
+ * LUP decomposition
+ */
+static OPJ_BOOL opj_lupDecompose(OPJ_FLOAT32 * matrix,
+                                 OPJ_UINT32 * permutations, 
+                                 OPJ_FLOAT32 * p_swap_area,
+                                 OPJ_UINT32 nb_compo);
+/** 
+ * LUP solving
+ */
+static void opj_lupSolve(OPJ_FLOAT32 * pResult, 
+                         OPJ_FLOAT32* pMatrix, 
+                         OPJ_FLOAT32* pVector, 
+                         OPJ_UINT32* pPermutations, 
+                         OPJ_UINT32 nb_compo,
+                         OPJ_FLOAT32 * p_intermediate_data);
+
+/** 
+ *LUP inversion (call with the result of lupDecompose)
+ */
+static void opj_lupInvert ( OPJ_FLOAT32 * pSrcMatrix,
+                            OPJ_FLOAT32 * pDestMatrix,
+                            OPJ_UINT32 nb_compo,
+                            OPJ_UINT32 * pPermutations,
+                            OPJ_FLOAT32 * p_src_temp,
+                            OPJ_FLOAT32 * p_dest_temp,
+                            OPJ_FLOAT32 * p_swap_area);
+
+/*
+==========================================================
+   Matric inversion interface
+==========================================================
+*/
+/**
+ * Matrix inversion.
+ */
+OPJ_BOOL opj_matrix_inversion_f(OPJ_FLOAT32 * pSrcMatrix,
+                                OPJ_FLOAT32 * pDestMatrix, 
+                                OPJ_UINT32 nb_compo)
+{
+       OPJ_BYTE * l_data = 00;
+       OPJ_UINT32 l_permutation_size = nb_compo * (OPJ_UINT32)sizeof(OPJ_UINT32);
+       OPJ_UINT32 l_swap_size = nb_compo * (OPJ_UINT32)sizeof(OPJ_FLOAT32);
+       OPJ_UINT32 l_total_size = l_permutation_size + 3 * l_swap_size;
+       OPJ_UINT32 * lPermutations = 00;
+       OPJ_FLOAT32 * l_double_data = 00;
+
+       l_data = (OPJ_BYTE *) opj_malloc(l_total_size);
+       if (l_data == 0) {
+               return OPJ_FALSE;
+       }
+       lPermutations = (OPJ_UINT32 *) l_data;
+       l_double_data = (OPJ_FLOAT32 *) (l_data + l_permutation_size);
+       memset(lPermutations,0,l_permutation_size);
+
+       if(! opj_lupDecompose(pSrcMatrix,lPermutations,l_double_data,nb_compo)) {
+               opj_free(l_data);
+               return OPJ_FALSE;
+       }
+       
+    opj_lupInvert(pSrcMatrix,pDestMatrix,nb_compo,lPermutations,l_double_data,l_double_data + nb_compo,l_double_data + 2*nb_compo);
+       opj_free(l_data);
+       
+    return OPJ_TRUE;
+}
+
+
+/*
+==========================================================
+   Local functions
+==========================================================
+*/
+OPJ_BOOL opj_lupDecompose(OPJ_FLOAT32 * matrix,OPJ_UINT32 * permutations, 
+                          OPJ_FLOAT32 * p_swap_area,
+                          OPJ_UINT32 nb_compo) 
+{
+       OPJ_UINT32 * tmpPermutations = permutations;
+       OPJ_UINT32 * dstPermutations;
+       OPJ_UINT32 k2=0,t;
+       OPJ_FLOAT32 temp;
+       OPJ_UINT32 i,j,k;
+       OPJ_FLOAT32 p;
+       OPJ_UINT32 lLastColum = nb_compo - 1;
+       OPJ_UINT32 lSwapSize = nb_compo * (OPJ_UINT32)sizeof(OPJ_FLOAT32);
+       OPJ_FLOAT32 * lTmpMatrix = matrix;
+       OPJ_FLOAT32 * lColumnMatrix,* lDestMatrix;
+       OPJ_UINT32 offset = 1;
+       OPJ_UINT32 lStride = nb_compo-1;
+
+       /*initialize permutations */
+       for (i = 0; i < nb_compo; ++i) 
+       {
+       *tmpPermutations++ = i;
+       }
+       /* now make a pivot with colum switch */
+       tmpPermutations = permutations;
+       for (k = 0; k < lLastColum; ++k) {
+               p = 0.0;
+
+               /* take the middle element */
+               lColumnMatrix = lTmpMatrix + k;
+               
+               /* make permutation with the biggest value in the column */
+        for (i = k; i < nb_compo; ++i) {
+                       temp = ((*lColumnMatrix > 0) ? *lColumnMatrix : -(*lColumnMatrix));
+               if (temp > p) {
+                       p = temp;
+                       k2 = i;
+               }
+                       /* next line */
+                       lColumnMatrix += nb_compo;
+       }
+
+       /* a whole rest of 0 -> non singular */
+       if (p == 0.0) {
+               return OPJ_FALSE;
+               }
+
+               /* should we permute ? */
+               if (k2 != k) {
+                       /*exchange of line */
+               /* k2 > k */
+                       dstPermutations = tmpPermutations + k2 - k;
+                       /* swap indices */
+                       t = *tmpPermutations;
+               *tmpPermutations = *dstPermutations;
+               *dstPermutations = t;
+
+                       /* and swap entire line. */
+                       lColumnMatrix = lTmpMatrix + (k2 - k) * nb_compo;
+                       memcpy(p_swap_area,lColumnMatrix,lSwapSize);
+                       memcpy(lColumnMatrix,lTmpMatrix,lSwapSize);
+                       memcpy(lTmpMatrix,p_swap_area,lSwapSize);
+               }
+
+               /* now update data in the rest of the line and line after */
+               lDestMatrix = lTmpMatrix + k;
+               lColumnMatrix = lDestMatrix + nb_compo;
+               /* take the middle element */
+               temp = *(lDestMatrix++);
+
+               /* now compute up data (i.e. coeff up of the diagonal). */
+       for (i = offset; i < nb_compo; ++i)  {
+                       /*lColumnMatrix; */
+                       /* divide the lower column elements by the diagonal value */
+
+                       /* matrix[i][k] /= matrix[k][k]; */
+               /* p = matrix[i][k] */
+                       p = *lColumnMatrix / temp;
+                       *(lColumnMatrix++) = p;
+               
+            for (j = /* k + 1 */ offset; j < nb_compo; ++j) {
+                               /* matrix[i][j] -= matrix[i][k] * matrix[k][j]; */
+                       *(lColumnMatrix++) -= p * (*(lDestMatrix++));
+                       }
+                       /* come back to the k+1th element */
+                       lDestMatrix -= lStride;
+                       /* go to kth element of the next line */
+                       lColumnMatrix += k;
+       }
+
+               /* offset is now k+2 */
+               ++offset;
+               /* 1 element less for stride */
+               --lStride;
+               /* next line */
+               lTmpMatrix+=nb_compo;
+               /* next permutation element */
+               ++tmpPermutations;
+       }
+    return OPJ_TRUE;
+}
+               
+void opj_lupSolve (OPJ_FLOAT32 * pResult, 
+                   OPJ_FLOAT32 * pMatrix, 
+                   OPJ_FLOAT32 * pVector, 
+                   OPJ_UINT32* pPermutations, 
+                   OPJ_UINT32 nb_compo,OPJ_FLOAT32 * p_intermediate_data) 
+{
+       OPJ_INT32 k;
+    OPJ_UINT32 i,j;
+       OPJ_FLOAT32 sum;
+       OPJ_FLOAT32 u;
+    OPJ_UINT32 lStride = nb_compo+1;
+       OPJ_FLOAT32 * lCurrentPtr;
+       OPJ_FLOAT32 * lIntermediatePtr;
+       OPJ_FLOAT32 * lDestPtr;
+       OPJ_FLOAT32 * lTmpMatrix;
+       OPJ_FLOAT32 * lLineMatrix = pMatrix;
+       OPJ_FLOAT32 * lBeginPtr = pResult + nb_compo - 1;
+       OPJ_FLOAT32 * lGeneratedData;
+       OPJ_UINT32 * lCurrentPermutationPtr = pPermutations;
+
+       
+       lIntermediatePtr = p_intermediate_data;
+       lGeneratedData = p_intermediate_data + nb_compo - 1;
+       
+    for (i = 0; i < nb_compo; ++i) {
+               sum = 0.0;
+               lCurrentPtr = p_intermediate_data;
+               lTmpMatrix = lLineMatrix;
+        for (j = 1; j <= i; ++j) 
+               {
+                       /* sum += matrix[i][j-1] * y[j-1]; */
+               sum += (*(lTmpMatrix++)) * (*(lCurrentPtr++));
+        }
+               /*y[i] = pVector[pPermutations[i]] - sum; */
+        *(lIntermediatePtr++) = pVector[*(lCurrentPermutationPtr++)] - sum;
+               lLineMatrix += nb_compo;
+       }
+
+       /* we take the last point of the matrix */
+       lLineMatrix = pMatrix + nb_compo*nb_compo - 1;
+
+       /* and we take after the last point of the destination vector */
+       lDestPtr = pResult + nb_compo;
+
+
+    assert(nb_compo != 0);
+       for (k = (OPJ_INT32)nb_compo - 1; k != -1 ; --k) {
+               sum = 0.0;
+               lTmpMatrix = lLineMatrix;
+        u = *(lTmpMatrix++);
+               lCurrentPtr = lDestPtr--;
+        for (j = (OPJ_UINT32)(k + 1); j < nb_compo; ++j) {
+                       /* sum += matrix[k][j] * x[j] */
+               sum += (*(lTmpMatrix++)) * (*(lCurrentPtr++));
+               }
+               /*x[k] = (y[k] - sum) / u; */
+        *(lBeginPtr--) = (*(lGeneratedData--) - sum) / u;
+               lLineMatrix -= lStride;
+       }
+}
+    
+
+void opj_lupInvert (OPJ_FLOAT32 * pSrcMatrix,
+                    OPJ_FLOAT32 * pDestMatrix,
+                    OPJ_UINT32 nb_compo,
+                    OPJ_UINT32 * pPermutations,
+                    OPJ_FLOAT32 * p_src_temp,
+                    OPJ_FLOAT32 * p_dest_temp,
+                    OPJ_FLOAT32 * p_swap_area )
+{
+       OPJ_UINT32 j,i;
+       OPJ_FLOAT32 * lCurrentPtr;
+       OPJ_FLOAT32 * lLineMatrix = pDestMatrix;
+       OPJ_UINT32 lSwapSize = nb_compo * (OPJ_UINT32)sizeof(OPJ_FLOAT32);
+
+       for (j = 0; j < nb_compo; ++j) {
+               lCurrentPtr = lLineMatrix++;
+        memset(p_src_temp,0,lSwapSize);
+       p_src_temp[j] = 1.0;
+               opj_lupSolve(p_dest_temp,pSrcMatrix,p_src_temp, pPermutations, nb_compo , p_swap_area);
+
+               for (i = 0; i < nb_compo; ++i) {
+               *(lCurrentPtr) = p_dest_temp[i];
+                       lCurrentPtr+=nb_compo;
+       }
+    }
+}
+
similarity index 50%
rename from extern/libopenjpeg/jpt.h
rename to extern/libopenjpeg/invert.h
index eb01f98..2fae8e5 100644 (file)
@@ -1,8 +1,10 @@
 /*
- * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
- * Copyright (c) 2002-2007, Professor Benoit Macq
- * Copyright (c) 2002-2003, Yannick Verschueren
- * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * 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) 2008, Jerome Fimes, Communications & Systemes <jerome.fimes@c-s.fr>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef __JPT_H
-#define __JPT_H
+#ifndef __INVERT_H
+#define __INVERT_H
 /**
-@file jpt.h
-@brief JPT-stream reader (JPEG 2000, JPIP)
+@file invert.h
+@brief Implementation of the matrix inversion
 
-JPT-stream functions are implemented in J2K.C. 
+The function in INVERT.H compute a matrix inversion with a LUP method
 */
 
-/**
-Message Header JPT stream structure
-*/
-typedef struct opj_jpt_msg_header {
-       /** In-class Identifier */
-       unsigned int Id;
-       /** Last byte information */
-       unsigned int last_byte; 
-       /** Class Identifier */
-       unsigned int Class_Id;  
-       /** CSn : index identifier */
-       unsigned int CSn_Id;
-       /** Message offset */
-       unsigned int Msg_offset;
-       /** Message length */
-       unsigned int Msg_length;
-       /** Auxiliary for JPP case */
-       unsigned int Layer_nb;
-} opj_jpt_msg_header_t;
-
+/** @defgroup INVERT INVERT - Implementation of a matrix inversion */
+/*@{*/
+/** @name Exported functions */
+/*@{*/
 /* ----------------------------------------------------------------------- */
 
 /**
-Initialize the value of the message header structure 
-@param header Message header structure
-*/
-void jpt_init_msg_header(opj_jpt_msg_header_t * header);
+ * Calculates a n x n double matrix inversion with a LUP method. Data is aligned, rows after rows (or columns after columns).
+ * The function does not take ownership of any memory block, data must be fred by the user.
+ *
+ * @param pSrcMatrix   the matrix to invert.
+ * @param pDestMatrix  data to store the inverted matrix. 
+ * @param n size of the matrix
+ * @return OPJ_TRUE if the inversion is successful, OPJ_FALSE if the matrix is singular.
+ */
+OPJ_BOOL opj_matrix_inversion_f(OPJ_FLOAT32 * pSrcMatrix,
+                                OPJ_FLOAT32 * pDestMatrix, 
+                                OPJ_UINT32 nb_compo);
+/* ----------------------------------------------------------------------- */
+/*@}*/
 
-/**
-Read the message header for a JPP/JPT - stream
-@param cinfo Codec context info
-@param cio CIO handle
-@param header Message header structure
-*/
-void jpt_read_msg_header(opj_common_ptr cinfo, opj_cio_t *cio, opj_jpt_msg_header_t *header);
+/*@}*/
 
-#endif
+#endif /* __INVERT_H */ 
index 93e5c9e..881cc72 100644 (file)
@@ -1,12 +1,21 @@
 /*
- * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
- * Copyright (c) 2002-2007, Professor Benoit Macq
+ * 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 and Antonin Descampe
+ * Copyright (c) 2003-2007, Francois-Olivier Devaux 
+ * Copyright (c) 2003-2014, Antonin Descampe
  * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * Copyright (c) 2008, Jerome Fimes, Communications & Systemes <jerome.fimes@c-s.fr>
  * Copyright (c) 2006-2007, Parvatha Elangovan
  * Copyright (c) 2010-2011, Kaori Hagihara
+ * Copyright (c) 2011-2012, Centre National d'Etudes Spatiales (CNES), France 
+ * Copyright (c) 2012, CS Systemes d'Information, France
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -32,7 +41,6 @@
  */
 
 #include "opj_includes.h"
-#include <assert.h>
 
 /** @defgroup J2K J2K - JPEG-2000 codestream reader/writer */
 /*@{*/
 /*@{*/
 
 /**
-Write the SOC marker (Start Of Codestream)
-@param j2k J2K handle
+ * Sets up the procedures to do on reading header. Developpers wanting to extend the library can add their own reading procedures.
+ */
+static void opj_j2k_setup_header_reading (opj_j2k_t *p_j2k);
+
+/**
+ * The read header procedure.
+ */
+static OPJ_BOOL opj_j2k_read_header_procedure(  opj_j2k_t *p_j2k,
+                                                opj_stream_private_t *p_stream,
+                                                opj_event_mgr_t * p_manager);
+
+/**
+ * The default encoding validation procedure without any extension.
+ *
+ * @param       p_j2k                   the jpeg2000 codec to validate.
+ * @param       p_stream                the input stream to validate.
+ * @param       p_manager               the user event manager.
+ *
+ * @return true if the parameters are correct.
+ */
+static OPJ_BOOL opj_j2k_encoding_validation (   opj_j2k_t * p_j2k,
+                                                opj_stream_private_t *p_stream,
+                                                opj_event_mgr_t * p_manager );
+
+/**
+ * The default decoding validation procedure without any extension.
+ *
+ * @param       p_j2k                   the jpeg2000 codec to validate.
+ * @param       p_stream                                the input stream to validate.
+ * @param       p_manager               the user event manager.
+ *
+ * @return true if the parameters are correct.
+ */
+static OPJ_BOOL opj_j2k_decoding_validation (   opj_j2k_t * p_j2k,
+                                                opj_stream_private_t *p_stream,
+                                                opj_event_mgr_t * p_manager );
+
+/**
+ * Sets up the validation ,i.e. adds the procedures to lauch to make sure the codec parameters
+ * are valid. Developpers wanting to extend the library can add their own validation procedures.
+ */
+static void opj_j2k_setup_encoding_validation (opj_j2k_t *p_j2k);
+
+/**
+ * Sets up the validation ,i.e. adds the procedures to lauch to make sure the codec parameters
+ * are valid. Developpers wanting to extend the library can add their own validation procedures.
+ */
+static void opj_j2k_setup_decoding_validation (opj_j2k_t *p_j2k);
+
+/**
+ * Sets up the validation ,i.e. adds the procedures to lauch to make sure the codec parameters
+ * are valid. Developpers wanting to extend the library can add their own validation procedures.
+ */
+static void opj_j2k_setup_end_compress (opj_j2k_t *p_j2k);
+
+/**
+ * The mct encoding validation procedure.
+ *
+ * @param       p_j2k                   the jpeg2000 codec to validate.
+ * @param       p_stream                                the input stream to validate.
+ * @param       p_manager               the user event manager.
+ *
+ * @return true if the parameters are correct.
+ */
+static OPJ_BOOL opj_j2k_mct_validation (opj_j2k_t * p_j2k,
+                                        opj_stream_private_t *p_stream,
+                                        opj_event_mgr_t * p_manager );
+
+/**
+ * Builds the tcd decoder to use to decode tile.
+ */
+static OPJ_BOOL opj_j2k_build_decoder ( opj_j2k_t * p_j2k,
+                                        opj_stream_private_t *p_stream,
+                                        opj_event_mgr_t * p_manager );
+/**
+ * Builds the tcd encoder to use to encode tile.
+ */
+static OPJ_BOOL opj_j2k_build_encoder ( opj_j2k_t * p_j2k,
+                                        opj_stream_private_t *p_stream,
+                                        opj_event_mgr_t * p_manager );
+
+/**
+ * Creates a tile-coder decoder.
+ *
+ * @param       p_stream                        the stream to write data to.
+ * @param       p_j2k                           J2K codec.
+ * @param       p_manager                   the user event manager.
+*/
+static OPJ_BOOL opj_j2k_create_tcd(     opj_j2k_t *p_j2k,
+                                                                    opj_stream_private_t *p_stream,
+                                                                    opj_event_mgr_t * p_manager );
+
+/**
+ * Excutes the given procedures on the given codec.
+ *
+ * @param       p_procedure_list        the list of procedures to execute
+ * @param       p_j2k                           the jpeg2000 codec to execute the procedures on.
+ * @param       p_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_j2k_exec (  opj_j2k_t * p_j2k,
+                            opj_procedure_list_t * p_procedure_list,
+                            opj_stream_private_t *p_stream,
+                            opj_event_mgr_t * p_manager);
+
+/**
+ * Updates the rates of the tcp.
+ *
+ * @param       p_stream                                the stream to write data to.
+ * @param       p_j2k                           J2K codec.
+ * @param       p_manager               the user event manager.
+*/
+static OPJ_BOOL opj_j2k_update_rates(   opj_j2k_t *p_j2k,
+                                                                            opj_stream_private_t *p_stream,
+                                                                            opj_event_mgr_t * p_manager );
+
+/**
+ * Copies the decoding tile parameters onto all the tile parameters.
+ * Creates also the tile decoder.
+ */
+static OPJ_BOOL opj_j2k_copy_default_tcp_and_create_tcd (       opj_j2k_t * p_j2k,
+                                                            opj_stream_private_t *p_stream,
+                                                            opj_event_mgr_t * p_manager );
+
+/**
+ * Destroys the memory associated with the decoding of headers.
+ */
+static OPJ_BOOL opj_j2k_destroy_header_memory ( opj_j2k_t * p_j2k,
+                                                opj_stream_private_t *p_stream,
+                                                opj_event_mgr_t * p_manager );
+
+/**
+ * Reads the lookup table containing all the marker, status and action, and returns the handler associated
+ * with the marker value.
+ * @param       p_id            Marker value to look up
+ *
+ * @return      the handler associated with the id.
+*/
+static const struct opj_dec_memory_marker_handler * opj_j2k_get_marker_handler (OPJ_UINT32 p_id);
+
+/**
+ * Destroys a tile coding parameter structure.
+ *
+ * @param       p_tcp           the tile coding parameter to destroy.
+ */
+static void opj_j2k_tcp_destroy (opj_tcp_t *p_tcp);
+
+/**
+ * Destroys the data inside a tile coding parameter structure.
+ *
+ * @param       p_tcp           the tile coding parameter which contain data to destroy.
+ */
+static void opj_j2k_tcp_data_destroy (opj_tcp_t *p_tcp);
+
+/**
+ * Destroys a coding parameter structure.
+ *
+ * @param       p_cp            the coding parameter to destroy.
+ */
+static void opj_j2k_cp_destroy (opj_cp_t *p_cp);
+
+/**
+ * Writes a SPCod or SPCoc element, i.e. the coding style of a given component of a tile.
+ *
+ * @param       p_j2k           J2K codec.
+ * @param       p_tile_no       FIXME DOC
+ * @param       p_comp_no       the component number to output.
+ * @param       p_data          FIXME DOC
+ * @param       p_header_size   FIXME DOC
+ * @param       p_manager       the user event manager.
+ *
+ * @return FIXME DOC
+*/
+static OPJ_BOOL opj_j2k_write_SPCod_SPCoc(      opj_j2k_t *p_j2k,
+                                                                                    OPJ_UINT32 p_tile_no,
+                                                                                    OPJ_UINT32 p_comp_no,
+                                                                                    OPJ_BYTE * p_data,
+                                                                                    OPJ_UINT32 * p_header_size,
+                                                                                    opj_event_mgr_t * p_manager );
+
+/**
+ * Gets the size taken by writing a SPCod or SPCoc for the given tile and component.
+ *
+ * @param       p_j2k                   the J2K codec.
+ * @param       p_tile_no               the tile index.
+ * @param       p_comp_no               the component being outputted.
+ *
+ * @return      the number of bytes taken by the SPCod element.
+ */
+static OPJ_UINT32 opj_j2k_get_SPCod_SPCoc_size (opj_j2k_t *p_j2k,
+                                                                                            OPJ_UINT32 p_tile_no,
+                                                                                            OPJ_UINT32 p_comp_no );
+
+/**
+ * Reads a SPCod or SPCoc element, i.e. the coding style of a given component of a tile.
+ * @param       p_j2k           the jpeg2000 codec.
+ * @param       compno          FIXME DOC
+ * @param       p_header_data   the data contained in the COM box.
+ * @param       p_header_size   the size of the data contained in the COM marker.
+ * @param       p_manager       the user event manager.
+*/
+static OPJ_BOOL opj_j2k_read_SPCod_SPCoc(   opj_j2k_t *p_j2k,
+                                            OPJ_UINT32 compno,
+                                            OPJ_BYTE * p_header_data,
+                                            OPJ_UINT32 * p_header_size,
+                                            opj_event_mgr_t * p_manager );
+
+/**
+ * Gets the size taken by writing SQcd or SQcc element, i.e. the quantization values of a band in the QCD or QCC.
+ *
+ * @param       p_tile_no               the tile index.
+ * @param       p_comp_no               the component being outputted.
+ * @param       p_j2k                   the J2K codec.
+ *
+ * @return      the number of bytes taken by the SPCod element.
+ */
+static OPJ_UINT32 opj_j2k_get_SQcd_SQcc_size (  opj_j2k_t *p_j2k,
+                                                                                    OPJ_UINT32 p_tile_no,
+                                                                                    OPJ_UINT32 p_comp_no );
+
+/**
+ * Writes a SQcd or SQcc element, i.e. the quantization values of a band in the QCD or QCC.
+ *
+ * @param       p_tile_no               the tile to output.
+ * @param       p_comp_no               the component number to output.
+ * @param       p_data                  the data buffer.
+ * @param       p_header_size   pointer to the size of the data buffer, it is changed by the function.
+ * @param       p_j2k                   J2K codec.
+ * @param       p_manager               the user event manager.
+ *
+*/
+static OPJ_BOOL opj_j2k_write_SQcd_SQcc(opj_j2k_t *p_j2k,
+                                                                            OPJ_UINT32 p_tile_no,
+                                                                            OPJ_UINT32 p_comp_no,
+                                                                            OPJ_BYTE * p_data,
+                                                                            OPJ_UINT32 * p_header_size,
+                                                                            opj_event_mgr_t * p_manager);
+
+/**
+ * Updates the Tile Length Marker.
+ */
+static void opj_j2k_update_tlm ( opj_j2k_t * p_j2k, OPJ_UINT32 p_tile_part_size);
+
+/**
+ * Reads a SQcd or SQcc element, i.e. the quantization values of a band in the QCD or QCC.
+ *
+ * @param       p_j2k           J2K codec.
+ * @param       compno          the component number to output.
+ * @param       p_header_data   the data buffer.
+ * @param       p_header_size   pointer to the size of the data buffer, it is changed by the function.
+ * @param       p_manager       the user event manager.
+ *
+*/
+static OPJ_BOOL opj_j2k_read_SQcd_SQcc( opj_j2k_t *p_j2k,
+                                        OPJ_UINT32 compno,
+                                        OPJ_BYTE * p_header_data,
+                                        OPJ_UINT32 * p_header_size,
+                                        opj_event_mgr_t * p_manager );
+
+/**
+ * Copies the tile component parameters of all the component from the first tile component.
+ *
+ * @param               p_j2k           the J2k codec.
+ */
+static void opj_j2k_copy_tile_component_parameters( opj_j2k_t *p_j2k );
+
+/**
+ * Copies the tile quantization parameters of all the component from the first tile component.
+ *
+ * @param               p_j2k           the J2k codec.
+ */
+static void opj_j2k_copy_tile_quantization_parameters( opj_j2k_t *p_j2k );
+
+/**
+ * Reads the tiles.
+ */
+static OPJ_BOOL opj_j2k_decode_tiles (  opj_j2k_t *p_j2k,
+                                        opj_stream_private_t *p_stream,
+                                        opj_event_mgr_t * p_manager);
+
+static OPJ_BOOL opj_j2k_pre_write_tile ( opj_j2k_t * p_j2k,
+                                                                             OPJ_UINT32 p_tile_index,
+                                                                             opj_stream_private_t *p_stream,
+                                                                             opj_event_mgr_t * p_manager );
+
+static OPJ_BOOL opj_j2k_update_image_data (opj_tcd_t * p_tcd, OPJ_BYTE * p_data, opj_image_t* p_output_image);
+
+static void opj_j2k_get_tile_data (opj_tcd_t * p_tcd, OPJ_BYTE * p_data);
+
+static OPJ_BOOL opj_j2k_post_write_tile (opj_j2k_t * p_j2k,
+                                                                             OPJ_BYTE * p_data,
+                                                                             OPJ_UINT32 p_data_size,
+                                                                             opj_stream_private_t *p_stream,
+                                                                             opj_event_mgr_t * p_manager );
+
+/**
+ * Sets up the procedures to do on writing header.
+ * Developers wanting to extend the library can add their own writing procedures.
+ */
+static void opj_j2k_setup_header_writing (opj_j2k_t *p_j2k);
+
+static OPJ_BOOL opj_j2k_write_first_tile_part(  opj_j2k_t *p_j2k,
+                                                                                            OPJ_BYTE * p_data,
+                                                                                            OPJ_UINT32 * p_data_written,
+                                                                                            OPJ_UINT32 p_total_data_size,
+                                                                                            opj_stream_private_t *p_stream,
+                                                                                            struct opj_event_mgr * p_manager );
+
+static OPJ_BOOL opj_j2k_write_all_tile_parts(   opj_j2k_t *p_j2k,
+                                                                                            OPJ_BYTE * p_data,
+                                                                                            OPJ_UINT32 * p_data_written,
+                                                                                            OPJ_UINT32 p_total_data_size,
+                                                                                            opj_stream_private_t *p_stream,
+                                                                                            struct opj_event_mgr * p_manager );
+
+/**
+ * Gets the offset of the header.
+ *
+ * @param       p_stream                the stream to write data to.
+ * @param       p_j2k                   J2K codec.
+ * @param       p_manager               the user event manager.
+*/
+static OPJ_BOOL opj_j2k_get_end_header( opj_j2k_t *p_j2k,
+                                        opj_stream_private_t *p_stream,
+                                        opj_event_mgr_t * p_manager );
+
+static OPJ_BOOL opj_j2k_allocate_tile_element_cstr_index(opj_j2k_t *p_j2k);
+
+/*
+ * -----------------------------------------------------------------------
+ * -----------------------------------------------------------------------
+ * -----------------------------------------------------------------------
+ */
+
+/**
+ * Writes the SOC marker (Start Of Codestream)
+ *
+ * @param       p_stream                        the stream to write data to.
+ * @param       p_j2k                   J2K codec.
+ * @param       p_manager       the user event manager.
 */
-static void j2k_write_soc(opj_j2k_t *j2k);
+static OPJ_BOOL opj_j2k_write_soc(      opj_j2k_t *p_j2k,
+                                                        opj_stream_private_t *p_stream,
+                                                            opj_event_mgr_t * p_manager );
+
 /**
-Read the SOC marker (Start of Codestream)
-@param j2k J2K handle
+ * Reads a SOC marker (Start of Codestream)
+ * @param       p_j2k           the jpeg2000 file codec.
+ * @param       p_stream        XXX needs data
+ * @param       p_manager       the user event manager.
 */
-static void j2k_read_soc(opj_j2k_t *j2k);
+static OPJ_BOOL opj_j2k_read_soc(   opj_j2k_t *p_j2k,
+                                    opj_stream_private_t *p_stream,
+                                    opj_event_mgr_t * p_manager );
+
 /**
-Write the SIZ marker (image and tile size)
-@param j2k J2K handle
+ * Writes the SIZ marker (image and tile size)
+ *
+ * @param       p_j2k           J2K codec.
+ * @param       p_stream        the stream to write data to.
+ * @param       p_manager       the user event manager.
 */
-static void j2k_write_siz(opj_j2k_t *j2k);
+static OPJ_BOOL opj_j2k_write_siz(      opj_j2k_t *p_j2k,
+                                                                opj_stream_private_t *p_stream,
+                                                                opj_event_mgr_t * p_manager );
+
 /**
-Read the SIZ marker (image and tile size)
-@param j2k J2K handle
+ * Reads a SIZ marker (image and tile size)
+ * @param       p_j2k           the jpeg2000 file codec.
+ * @param       p_header_data   the data contained in the SIZ box.
+ * @param       p_header_size   the size of the data contained in the SIZ marker.
+ * @param       p_manager       the user event manager.
 */
-static void j2k_read_siz(opj_j2k_t *j2k);
+static OPJ_BOOL opj_j2k_read_siz(opj_j2k_t *p_j2k,
+                                 OPJ_BYTE * p_header_data,
+                                 OPJ_UINT32 p_header_size,
+                                 opj_event_mgr_t * p_manager);
+
 /**
-Write the COM marker (comment)
-@param j2k J2K handle
+ * Writes the COM marker (comment)
+ *
+ * @param       p_stream                        the stream to write data to.
+ * @param       p_j2k                   J2K codec.
+ * @param       p_manager       the user event manager.
 */
-static void j2k_write_com(opj_j2k_t *j2k);
+static OPJ_BOOL opj_j2k_write_com(      opj_j2k_t *p_j2k,
+                                                                        opj_stream_private_t *p_stream,
+                                                                        opj_event_mgr_t * p_manager );
+
 /**
-Read the COM marker (comment)
-@param j2k J2K handle
+ * Reads a COM marker (comments)
+ * @param       p_j2k           the jpeg2000 file codec.
+ * @param       p_header_data   the data contained in the COM box.
+ * @param       p_header_size   the size of the data contained in the COM marker.
+ * @param       p_manager       the user event manager.
 */
-static void j2k_read_com(opj_j2k_t *j2k);
+static OPJ_BOOL opj_j2k_read_com (  opj_j2k_t *p_j2k,
+                                    OPJ_BYTE * p_header_data,
+                                    OPJ_UINT32 p_header_size,
+                                    opj_event_mgr_t * p_manager );
 /**
-Write the value concerning the specified component in the marker COD and COC
-@param j2k J2K handle
-@param compno Number of the component concerned by the information written
+ * Writes the COD marker (Coding style default)
+ *
+ * @param       p_stream                        the stream to write data to.
+ * @param       p_j2k                   J2K codec.
+ * @param       p_manager       the user event manager.
 */
-static void j2k_write_cox(opj_j2k_t *j2k, int compno);
+static OPJ_BOOL opj_j2k_write_cod(      opj_j2k_t *p_j2k,
+                                                                        opj_stream_private_t *p_stream,
+                                                                        opj_event_mgr_t * p_manager );
+
 /**
-Read the value concerning the specified component in the marker COD and COC
-@param j2k J2K handle
-@param compno Number of the component concerned by the information read
+ * Reads a COD marker (Coding Styke defaults)
+ * @param       p_header_data   the data contained in the COD box.
+ * @param       p_j2k                   the jpeg2000 codec.
+ * @param       p_header_size   the size of the data contained in the COD marker.
+ * @param       p_manager               the user event manager.
 */
-static void j2k_read_cox(opj_j2k_t *j2k, int compno);
+static OPJ_BOOL opj_j2k_read_cod (  opj_j2k_t *p_j2k,
+                                    OPJ_BYTE * p_header_data,
+                                    OPJ_UINT32 p_header_size,
+                                    opj_event_mgr_t * p_manager);
+
+#if 0
 /**
-Write the COD marker (coding style default)
-@param j2k J2K handle
+ * Writes the COC marker (Coding style component)
+ *
+ * @param       p_j2k       J2K codec.
+ * @param       p_comp_no   the index of the component to output.
+ * @param       p_stream    the stream to write data to.
+ * @param       p_manager   the user event manager.
 */
-static void j2k_write_cod(opj_j2k_t *j2k);
+static OPJ_BOOL opj_j2k_write_coc(  opj_j2k_t *p_j2k,
+                                                                OPJ_UINT32 p_comp_no,
+                                                                opj_stream_private_t *p_stream,
+                                                                opj_event_mgr_t * p_manager );
+#endif
+
+#if 0
 /**
-Read the COD marker (coding style default)
-@param j2k J2K handle
+ * Writes the COC marker (Coding style component)
+ *
+ * @param       p_j2k                   J2K codec.
+ * @param       p_comp_no               the index of the component to output.
+ * @param       p_data          FIXME DOC
+ * @param       p_data_written  FIXME DOC
+ * @param       p_manager               the user event manager.
 */
-static void j2k_read_cod(opj_j2k_t *j2k);
+static void opj_j2k_write_coc_in_memory(opj_j2k_t *p_j2k,
+                                                                            OPJ_UINT32 p_comp_no,
+                                                                            OPJ_BYTE * p_data,
+                                                                            OPJ_UINT32 * p_data_written,
+                                                                            opj_event_mgr_t * p_manager );
+#endif
+
+/**
+ * Gets the maximum size taken by a coc.
+ *
+ * @param       p_j2k   the jpeg2000 codec to use.
+ */
+static OPJ_UINT32 opj_j2k_get_max_coc_size(opj_j2k_t *p_j2k);
+
 /**
-Write the COC marker (coding style component)
-@param j2k J2K handle
-@param compno Number of the component concerned by the information written
+ * Reads a COC marker (Coding Style Component)
+ * @param       p_header_data   the data contained in the COC box.
+ * @param       p_j2k                   the jpeg2000 codec.
+ * @param       p_header_size   the size of the data contained in the COC marker.
+ * @param       p_manager               the user event manager.
 */
-static void j2k_write_coc(opj_j2k_t *j2k, int compno);
+static OPJ_BOOL opj_j2k_read_coc (  opj_j2k_t *p_j2k,
+                                    OPJ_BYTE * p_header_data,
+                                    OPJ_UINT32 p_header_size,
+                                    opj_event_mgr_t * p_manager );
+
 /**
-Read the COC marker (coding style component)
-@param j2k J2K handle
+ * Writes the QCD marker (quantization default)
+ *
+ * @param       p_j2k                   J2K codec.
+ * @param       p_stream                the stream to write data to.
+ * @param       p_manager               the user event manager.
 */
-static void j2k_read_coc(opj_j2k_t *j2k);
+static OPJ_BOOL opj_j2k_write_qcd(      opj_j2k_t *p_j2k,
+                                                                        opj_stream_private_t *p_stream,
+                                                                        opj_event_mgr_t * p_manager );
+
 /**
-Write the value concerning the specified component in the marker QCD and QCC
-@param j2k J2K handle
-@param compno Number of the component concerned by the information written
+ * Reads a QCD marker (Quantization defaults)
+ * @param       p_header_data   the data contained in the QCD box.
+ * @param       p_j2k                   the jpeg2000 codec.
+ * @param       p_header_size   the size of the data contained in the QCD marker.
+ * @param       p_manager               the user event manager.
 */
-static void j2k_write_qcx(opj_j2k_t *j2k, int compno);
+static OPJ_BOOL opj_j2k_read_qcd (  opj_j2k_t *p_j2k,
+                                    OPJ_BYTE * p_header_data,
+                                    OPJ_UINT32 p_header_size,
+                                    opj_event_mgr_t * p_manager );
+#if 0
 /**
-Read the value concerning the specified component in the marker QCD and QCC
-@param j2k J2K handle
-@param compno Number of the component concern by the information read
-@param len Length of the information in the QCX part of the marker QCD/QCC
+ * Writes the QCC marker (quantization component)
+ *
+ * @param       p_comp_no       the index of the component to output.
+ * @param       p_stream                the stream to write data to.
+ * @param       p_j2k                   J2K codec.
+ * @param       p_manager               the user event manager.
 */
-static void j2k_read_qcx(opj_j2k_t *j2k, int compno, int len);
+static OPJ_BOOL opj_j2k_write_qcc(      opj_j2k_t *p_j2k,
+                                                                        OPJ_UINT32 p_comp_no,
+                                                                        opj_stream_private_t *p_stream,
+                                                                        opj_event_mgr_t * p_manager );
+#endif
+
+#if 0
 /**
-Write the QCD marker (quantization default)
-@param j2k J2K handle
+ * Writes the QCC marker (quantization component)
+ *
+ * @param       p_j2k           J2K codec.
+ * @param       p_comp_no       the index of the component to output.
+ * @param       p_data          FIXME DOC
+ * @param       p_data_written  the stream to write data to.
+ * @param       p_manager       the user event manager.
 */
-static void j2k_write_qcd(opj_j2k_t *j2k);
+static void opj_j2k_write_qcc_in_memory(opj_j2k_t *p_j2k,
+                                                                            OPJ_UINT32 p_comp_no,
+                                                                            OPJ_BYTE * p_data,
+                                                                            OPJ_UINT32 * p_data_written,
+                                                                            opj_event_mgr_t * p_manager );
+#endif
+
+/**
+ * Gets the maximum size taken by a qcc.
+ */
+static OPJ_UINT32 opj_j2k_get_max_qcc_size (opj_j2k_t *p_j2k);
+
 /**
-Read the QCD marker (quantization default)
-@param j2k J2K handle
+ * Reads a QCC marker (Quantization component)
+ * @param       p_header_data   the data contained in the QCC box.
+ * @param       p_j2k                   the jpeg2000 codec.
+ * @param       p_header_size   the size of the data contained in the QCC marker.
+ * @param       p_manager               the user event manager.
 */
-static void j2k_read_qcd(opj_j2k_t *j2k);
+static OPJ_BOOL opj_j2k_read_qcc(   opj_j2k_t *p_j2k,
+                                    OPJ_BYTE * p_header_data,
+                                    OPJ_UINT32 p_header_size,
+                                    opj_event_mgr_t * p_manager);
 /**
-Write the QCC marker (quantization component)
-@param j2k J2K handle
-@param compno Number of the component concerned by the information written
+ * Writes the POC marker (Progression Order Change)
+ *
+ * @param       p_stream                                the stream to write data to.
+ * @param       p_j2k                           J2K codec.
+ * @param       p_manager               the user event manager.
 */
-static void j2k_write_qcc(opj_j2k_t *j2k, int compno);
+static OPJ_BOOL opj_j2k_write_poc(      opj_j2k_t *p_j2k,
+                                                                        opj_stream_private_t *p_stream,
+                                                                        opj_event_mgr_t * p_manager );
+/**
+ * Writes the POC marker (Progression Order Change)
+ *
+ * @param       p_j2k          J2K codec.
+ * @param       p_data         FIXME DOC
+ * @param       p_data_written the stream to write data to.
+ * @param       p_manager      the user event manager.
+ */
+static void opj_j2k_write_poc_in_memory(opj_j2k_t *p_j2k,
+                                                                            OPJ_BYTE * p_data,
+                                                                            OPJ_UINT32 * p_data_written,
+                                                                            opj_event_mgr_t * p_manager );
+/**
+ * Gets the maximum size taken by the writing of a POC.
+ */
+static OPJ_UINT32 opj_j2k_get_max_poc_size(opj_j2k_t *p_j2k);
+
 /**
-Read the QCC marker (quantization component)
-@param j2k J2K handle
+ * Reads a POC marker (Progression Order Change)
+ *
+ * @param       p_header_data   the data contained in the POC box.
+ * @param       p_j2k                   the jpeg2000 codec.
+ * @param       p_header_size   the size of the data contained in the POC marker.
+ * @param       p_manager               the user event manager.
 */
-static void j2k_read_qcc(opj_j2k_t *j2k);
+static OPJ_BOOL opj_j2k_read_poc (  opj_j2k_t *p_j2k,
+                                    OPJ_BYTE * p_header_data,
+                                    OPJ_UINT32 p_header_size,
+                                    opj_event_mgr_t * p_manager );
+
+/**
+ * Gets the maximum size taken by the toc headers of all the tile parts of any given tile.
+ */
+static OPJ_UINT32 opj_j2k_get_max_toc_size (opj_j2k_t *p_j2k);
+
+/**
+ * Gets the maximum size taken by the headers of the SOT.
+ *
+ * @param       p_j2k   the jpeg2000 codec to use.
+ */
+static OPJ_UINT32 opj_j2k_get_specific_header_sizes(opj_j2k_t *p_j2k);
+
 /**
-Write the POC marker (progression order change)
-@param j2k J2K handle
+ * Reads a CRG marker (Component registration)
+ *
+ * @param       p_header_data   the data contained in the TLM box.
+ * @param       p_j2k                   the jpeg2000 codec.
+ * @param       p_header_size   the size of the data contained in the TLM marker.
+ * @param       p_manager               the user event manager.
 */
-static void j2k_write_poc(opj_j2k_t *j2k);
+static OPJ_BOOL opj_j2k_read_crg (  opj_j2k_t *p_j2k,
+                                    OPJ_BYTE * p_header_data,
+                                    OPJ_UINT32 p_header_size,
+                                    opj_event_mgr_t * p_manager );
 /**
-Read the POC marker (progression order change)
-@param j2k J2K handle
+ * Reads a TLM marker (Tile Length Marker)
+ *
+ * @param       p_header_data   the data contained in the TLM box.
+ * @param       p_j2k                   the jpeg2000 codec.
+ * @param       p_header_size   the size of the data contained in the TLM marker.
+ * @param       p_manager               the user event manager.
 */
-static void j2k_read_poc(opj_j2k_t *j2k);
+static OPJ_BOOL opj_j2k_read_tlm (  opj_j2k_t *p_j2k,
+                                    OPJ_BYTE * p_header_data,
+                                    OPJ_UINT32 p_header_size,
+                                    opj_event_mgr_t * p_manager);
+
 /**
-Read the CRG marker (component registration)
-@param j2k J2K handle
+ * Writes the updated tlm.
+ *
+ * @param       p_stream                the stream to write data to.
+ * @param       p_j2k                   J2K codec.
+ * @param       p_manager               the user event manager.
 */
-static void j2k_read_crg(opj_j2k_t *j2k);
+static OPJ_BOOL opj_j2k_write_updated_tlm(      opj_j2k_t *p_j2k,
+                                            opj_stream_private_t *p_stream,
+                                            opj_event_mgr_t * p_manager );
+
 /**
-Read the TLM marker (tile-part lengths)
-@param j2k J2K handle
+ * Reads a PLM marker (Packet length, main header marker)
+ *
+ * @param       p_header_data   the data contained in the TLM box.
+ * @param       p_j2k                   the jpeg2000 codec.
+ * @param       p_header_size   the size of the data contained in the TLM marker.
+ * @param       p_manager               the user event manager.
 */
-static void j2k_read_tlm(opj_j2k_t *j2k);
+static OPJ_BOOL opj_j2k_read_plm (  opj_j2k_t *p_j2k,
+                                    OPJ_BYTE * p_header_data,
+                                    OPJ_UINT32 p_header_size,
+                                    opj_event_mgr_t * p_manager);
 /**
-Read the PLM marker (packet length, main header)
-@param j2k J2K handle
+ * Reads a PLT marker (Packet length, tile-part header)
+ *
+ * @param       p_header_data   the data contained in the PLT box.
+ * @param       p_j2k                   the jpeg2000 codec.
+ * @param       p_header_size   the size of the data contained in the PLT marker.
+ * @param       p_manager               the user event manager.
 */
-static void j2k_read_plm(opj_j2k_t *j2k);
+static OPJ_BOOL opj_j2k_read_plt (  opj_j2k_t *p_j2k,
+                                    OPJ_BYTE * p_header_data,
+                                    OPJ_UINT32 p_header_size,
+                                    opj_event_mgr_t * p_manager );
+
+#if 0
 /**
-Read the PLT marker (packet length, tile-part header)
-@param j2k J2K handle
+ * Reads a PPM marker (Packed packet headers, main header)
+ *
+ * @param       p_header_data   the data contained in the POC box.
+ * @param       p_j2k                   the jpeg2000 codec.
+ * @param       p_header_size   the size of the data contained in the POC marker.
+ * @param       p_manager               the user event manager.
 */
-static void j2k_read_plt(opj_j2k_t *j2k);
+static OPJ_BOOL j2k_read_ppm_v2 (
+                                                opj_j2k_t *p_j2k,
+                                                OPJ_BYTE * p_header_data,
+                                                OPJ_UINT32 p_header_size,
+                                                struct opj_event_mgr * p_manager
+                                        );
+#endif
+
+static OPJ_BOOL j2k_read_ppm_v3 (
+                                                opj_j2k_t *p_j2k,
+                                                OPJ_BYTE * p_header_data,
+                                                OPJ_UINT32 p_header_size,
+                                                opj_event_mgr_t * p_manager );
+
 /**
-Read the PPM marker (packet packet headers, main header)
-@param j2k J2K handle
+ * Reads a PPT marker (Packed packet headers, tile-part header)
+ *
+ * @param       p_header_data   the data contained in the PPT box.
+ * @param       p_j2k                   the jpeg2000 codec.
+ * @param       p_header_size   the size of the data contained in the PPT marker.
+ * @param       p_manager               the user event manager.
 */
-static void j2k_read_ppm(opj_j2k_t *j2k);
+static OPJ_BOOL opj_j2k_read_ppt (  opj_j2k_t *p_j2k,
+                                    OPJ_BYTE * p_header_data,
+                                    OPJ_UINT32 p_header_size,
+                                    opj_event_mgr_t * p_manager );
 /**
-Read the PPT marker (packet packet headers, tile-part header)
-@param j2k J2K handle
+ * Writes the TLM marker (Tile Length Marker)
+ *
+ * @param       p_stream                                the stream to write data to.
+ * @param       p_j2k                           J2K codec.
+ * @param       p_manager               the user event manager.
 */
-static void j2k_read_ppt(opj_j2k_t *j2k);
+static OPJ_BOOL opj_j2k_write_tlm(      opj_j2k_t *p_j2k,
+                                                                        opj_stream_private_t *p_stream,
+                                                                        opj_event_mgr_t * p_manager );
+
 /**
-Write the TLM marker (Mainheader)
-@param j2k J2K handle
+ * Writes the SOT marker (Start of tile-part)
+ *
+ * @param       p_j2k            J2K codec.
+ * @param       p_data           FIXME DOC
+ * @param       p_data_written   FIXME DOC
+ * @param       p_stream         the stream to write data to.
+ * @param       p_manager        the user event manager.
 */
-static void j2k_write_tlm(opj_j2k_t *j2k);
+static OPJ_BOOL opj_j2k_write_sot(      opj_j2k_t *p_j2k,
+                                                                        OPJ_BYTE * p_data,
+                                                                        OPJ_UINT32 * p_data_written,
+                                                                        const opj_stream_private_t *p_stream,
+                                                                        opj_event_mgr_t * p_manager );
+
 /**
-Write the SOT marker (start of tile-part)
-@param j2k J2K handle
+ * Reads a PPT marker (Packed packet headers, tile-part header)
+ *
+ * @param       p_header_data   the data contained in the PPT box.
+ * @param       p_j2k                   the jpeg2000 codec.
+ * @param       p_header_size   the size of the data contained in the PPT marker.
+ * @param       p_manager               the user event manager.
 */
-static void j2k_write_sot(opj_j2k_t *j2k);
+static OPJ_BOOL opj_j2k_read_sot (  opj_j2k_t *p_j2k,
+                                    OPJ_BYTE * p_header_data,
+                                    OPJ_UINT32 p_header_size,
+                                    opj_event_mgr_t * p_manager );
 /**
-Read the SOT marker (start of tile-part)
-@param j2k J2K handle
+ * Writes the SOD marker (Start of data)
+ *
+ * @param       p_j2k               J2K codec.
+ * @param       p_tile_coder        FIXME DOC
+ * @param       p_data              FIXME DOC
+ * @param       p_data_written      FIXME DOC
+ * @param       p_total_data_size   FIXME DOC
+ * @param       p_stream            the stream to write data to.
+ * @param       p_manager           the user event manager.
 */
-static void j2k_read_sot(opj_j2k_t *j2k);
+static OPJ_BOOL opj_j2k_write_sod(      opj_j2k_t *p_j2k,
+                                                                        opj_tcd_t * p_tile_coder,
+                                                                        OPJ_BYTE * p_data,
+                                                                        OPJ_UINT32 * p_data_written,
+                                                                        OPJ_UINT32 p_total_data_size,
+                                                                        const opj_stream_private_t *p_stream,
+                                                                        opj_event_mgr_t * p_manager );
+
 /**
-Write the SOD marker (start of data)
-@param j2k J2K handle
-@param tile_coder Pointer to a TCD handle
+ * Reads a SOD marker (Start Of Data)
+ *
+ * @param       p_j2k                   the jpeg2000 codec.
+ * @param       p_stream                FIXME DOC
+ * @param       p_manager               the user event manager.
 */
-static void j2k_write_sod(opj_j2k_t *j2k, void *tile_coder);
+static OPJ_BOOL opj_j2k_read_sod(   opj_j2k_t *p_j2k,
+                                    opj_stream_private_t *p_stream,
+                                    opj_event_mgr_t * p_manager );
+
+void opj_j2k_update_tlm (opj_j2k_t * p_j2k, OPJ_UINT32 p_tile_part_size )
+{
+        opj_write_bytes(p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_current,p_j2k->m_current_tile_number,1);            /* PSOT */
+        ++p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_current;
+
+        opj_write_bytes(p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_current,p_tile_part_size,4);                                        /* PSOT */
+        p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_current += 4;
+}
+
 /**
-Read the SOD marker (start of data)
-@param j2k J2K handle
+ * Writes the RGN marker (Region Of Interest)
+ *
+ * @param       p_tile_no               the tile to output
+ * @param       p_comp_no               the component to output
+ * @param       nb_comps                the number of components
+ * @param       p_stream                the stream to write data to.
+ * @param       p_j2k                   J2K codec.
+ * @param       p_manager               the user event manager.
 */
-static void j2k_read_sod(opj_j2k_t *j2k);
+static OPJ_BOOL opj_j2k_write_rgn(  opj_j2k_t *p_j2k,
+                                    OPJ_UINT32 p_tile_no,
+                                    OPJ_UINT32 p_comp_no,
+                                    OPJ_UINT32 nb_comps,
+                                    opj_stream_private_t *p_stream,
+                                    opj_event_mgr_t * p_manager );
+
 /**
-Write the RGN marker (region-of-interest)
-@param j2k J2K handle
-@param compno Number of the component concerned by the information written
-@param tileno Number of the tile concerned by the information written
+ * Reads a RGN marker (Region Of Interest)
+ *
+ * @param       p_header_data   the data contained in the POC box.
+ * @param       p_j2k                   the jpeg2000 codec.
+ * @param       p_header_size   the size of the data contained in the POC marker.
+ * @param       p_manager               the user event manager.
 */
-static void j2k_write_rgn(opj_j2k_t *j2k, int compno, int tileno);
+static OPJ_BOOL opj_j2k_read_rgn (opj_j2k_t *p_j2k,
+                                  OPJ_BYTE * p_header_data,
+                                  OPJ_UINT32 p_header_size,
+                                  opj_event_mgr_t * p_manager );
+
 /**
-Read the RGN marker (region-of-interest)
-@param j2k J2K handle
+ * Writes the EOC marker (End of Codestream)
+ *
+ * @param       p_stream                the stream to write data to.
+ * @param       p_j2k                   J2K codec.
+ * @param       p_manager               the user event manager.
 */
-static void j2k_read_rgn(opj_j2k_t *j2k);
+static OPJ_BOOL opj_j2k_write_eoc(      opj_j2k_t *p_j2k,
+                                    opj_stream_private_t *p_stream,
+                                    opj_event_mgr_t * p_manager );
+
+#if 0
 /**
-Write the EOC marker (end of codestream)
-@param j2k J2K handle
+ * Reads a EOC marker (End Of Codestream)
+ *
+ * @param       p_j2k                   the jpeg2000 codec.
+ * @param       p_stream                FIXME DOC
+ * @param       p_manager               the user event manager.
 */
-static void j2k_write_eoc(opj_j2k_t *j2k);
+static OPJ_BOOL opj_j2k_read_eoc (      opj_j2k_t *p_j2k,
+                                                                opj_stream_private_t *p_stream,
+                                                                opj_event_mgr_t * p_manager );
+#endif
+
 /**
-Read the EOC marker (end of codestream)
-@param j2k J2K handle
+ * Writes the CBD-MCT-MCC-MCO markers (Multi components transform)
+ *
+ * @param       p_stream                        the stream to write data to.
+ * @param       p_j2k                   J2K codec.
+ * @param       p_manager       the user event manager.
 */
-static void j2k_read_eoc(opj_j2k_t *j2k);
+static OPJ_BOOL opj_j2k_write_mct_data_group(   opj_j2k_t *p_j2k,
+                                                opj_stream_private_t *p_stream,
+                                                opj_event_mgr_t * p_manager );
+
 /**
-Read an unknown marker
-@param j2k J2K handle
+ * Inits the Info
+ *
+ * @param       p_stream                the stream to write data to.
+ * @param       p_j2k                   J2K codec.
+ * @param       p_manager               the user event manager.
 */
-static void j2k_read_unk(opj_j2k_t *j2k);
+static OPJ_BOOL opj_j2k_init_info(      opj_j2k_t *p_j2k,
+                                    opj_stream_private_t *p_stream,
+                                    opj_event_mgr_t * p_manager );
+
 /**
 Add main header marker information
-@param cstr_info Codestream information structure
-@param type marker type
-@param pos byte offset of marker segment
-@param len length of marker segment
+@param cstr_index    Codestream information structure
+@param type         marker type
+@param pos          byte offset of marker segment
+@param len          length of marker segment
  */
-static void j2k_add_mhmarker(opj_codestream_info_t *cstr_info, unsigned short int type, int pos, int len);
+static OPJ_BOOL opj_j2k_add_mhmarker(opj_codestream_index_t *cstr_index, OPJ_UINT32 type, OPJ_OFF_T pos, OPJ_UINT32 len) ;
 /**
 Add tile header marker information
-@param tileno tile index number
-@param cstr_info Codestream information structure
-@param type marker type
-@param pos byte offset of marker segment
-@param len length of marker segment
+@param tileno       tile index number
+@param cstr_index   Codestream information structure
+@param type         marker type
+@param pos          byte offset of marker segment
+@param len          length of marker segment
  */
-static void j2k_add_tlmarker( int tileno, opj_codestream_info_t *cstr_info, unsigned short int type, int pos, int len);
+static OPJ_BOOL opj_j2k_add_tlmarker(OPJ_UINT32 tileno, opj_codestream_index_t *cstr_index, OPJ_UINT32 type, OPJ_OFF_T pos, OPJ_UINT32 len);
+
+/**
+ * Reads an unknown marker
+ *
+ * @param       p_j2k                   the jpeg2000 codec.
+ * @param       p_stream                the stream object to read from.
+ * @param       output_marker           FIXME DOC
+ * @param       p_manager               the user event manager.
+ *
+ * @return      true                    if the marker could be deduced.
+*/
+static OPJ_BOOL opj_j2k_read_unk( opj_j2k_t *p_j2k,
+                                  opj_stream_private_t *p_stream,
+                                  OPJ_UINT32 *output_marker,
+                                  opj_event_mgr_t * p_manager );
+
+/**
+ * Writes the MCT marker (Multiple Component Transform)
+ *
+ * @param       p_j2k           J2K codec.
+ * @param       p_mct_record    FIXME DOC
+ * @param       p_stream        the stream to write data to.
+ * @param       p_manager       the user event manager.
+*/
+static OPJ_BOOL opj_j2k_write_mct_record(       opj_j2k_t *p_j2k,
+                                                                                    opj_mct_data_t * p_mct_record,
+                                            opj_stream_private_t *p_stream,
+                                            opj_event_mgr_t * p_manager );
+
+/**
+ * Reads a MCT marker (Multiple Component Transform)
+ *
+ * @param       p_header_data   the data contained in the MCT box.
+ * @param       p_j2k                   the jpeg2000 codec.
+ * @param       p_header_size   the size of the data contained in the MCT marker.
+ * @param       p_manager               the user event manager.
+*/
+static OPJ_BOOL opj_j2k_read_mct (      opj_j2k_t *p_j2k,
+                                                                    OPJ_BYTE * p_header_data,
+                                                                    OPJ_UINT32 p_header_size,
+                                                                    opj_event_mgr_t * p_manager );
+
+/**
+ * Writes the MCC marker (Multiple Component Collection)
+ *
+ * @param       p_j2k                   J2K codec.
+ * @param       p_mcc_record            FIXME DOC
+ * @param       p_stream                the stream to write data to.
+ * @param       p_manager               the user event manager.
+*/
+static OPJ_BOOL opj_j2k_write_mcc_record(   opj_j2k_t *p_j2k,
+                                            opj_simple_mcc_decorrelation_data_t * p_mcc_record,
+                                            opj_stream_private_t *p_stream,
+                                            opj_event_mgr_t * p_manager );
+
+/**
+ * Reads a MCC marker (Multiple Component Collection)
+ *
+ * @param       p_header_data   the data contained in the MCC box.
+ * @param       p_j2k                   the jpeg2000 codec.
+ * @param       p_header_size   the size of the data contained in the MCC marker.
+ * @param       p_manager               the user event manager.
+*/
+static OPJ_BOOL opj_j2k_read_mcc (      opj_j2k_t *p_j2k,
+                                                                    OPJ_BYTE * p_header_data,
+                                                                    OPJ_UINT32 p_header_size,
+                                                                    opj_event_mgr_t * p_manager );
+
+/**
+ * Writes the MCO marker (Multiple component transformation ordering)
+ *
+ * @param       p_stream                                the stream to write data to.
+ * @param       p_j2k                           J2K codec.
+ * @param       p_manager               the user event manager.
+*/
+static OPJ_BOOL opj_j2k_write_mco(      opj_j2k_t *p_j2k,
+                                    opj_stream_private_t *p_stream,
+                                    opj_event_mgr_t * p_manager );
+
+/**
+ * Reads a MCO marker (Multiple Component Transform Ordering)
+ *
+ * @param       p_header_data   the data contained in the MCO box.
+ * @param       p_j2k                   the jpeg2000 codec.
+ * @param       p_header_size   the size of the data contained in the MCO marker.
+ * @param       p_manager               the user event manager.
+*/
+static OPJ_BOOL opj_j2k_read_mco (      opj_j2k_t *p_j2k,
+                                                                    OPJ_BYTE * p_header_data,
+                                                                    OPJ_UINT32 p_header_size,
+                                                                    opj_event_mgr_t * p_manager );
+
+static OPJ_BOOL opj_j2k_add_mct(opj_tcp_t * p_tcp, opj_image_t * p_image, OPJ_UINT32 p_index);
+
+static void  opj_j2k_read_int16_to_float (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem);
+static void  opj_j2k_read_int32_to_float (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem);
+static void  opj_j2k_read_float32_to_float (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem);
+static void  opj_j2k_read_float64_to_float (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem);
+
+static void  opj_j2k_read_int16_to_int32 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem);
+static void  opj_j2k_read_int32_to_int32 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem);
+static void  opj_j2k_read_float32_to_int32 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem);
+static void  opj_j2k_read_float64_to_int32 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem);
+
+static void  opj_j2k_write_float_to_int16 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem);
+static void  opj_j2k_write_float_to_int32 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem);
+static void  opj_j2k_write_float_to_float (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem);
+static void  opj_j2k_write_float_to_float64 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem);
+
+/**
+ * Ends the encoding, i.e. frees memory.
+ *
+ * @param       p_stream                the stream to write data to.
+ * @param       p_j2k                   J2K codec.
+ * @param       p_manager               the user event manager.
+*/
+static OPJ_BOOL opj_j2k_end_encoding(   opj_j2k_t *p_j2k,
+                                                                            opj_stream_private_t *p_stream,
+                                                                            opj_event_mgr_t * p_manager );
+
+/**
+ * Writes the CBD marker (Component bit depth definition)
+ *
+ * @param       p_stream                                the stream to write data to.
+ * @param       p_j2k                           J2K codec.
+ * @param       p_manager               the user event manager.
+*/
+static OPJ_BOOL opj_j2k_write_cbd(      opj_j2k_t *p_j2k,
+                                                                    opj_stream_private_t *p_stream,
+                                                                        opj_event_mgr_t * p_manager );
+
+/**
+ * Reads a CBD marker (Component bit depth definition)
+ * @param       p_header_data   the data contained in the CBD box.
+ * @param       p_j2k                   the jpeg2000 codec.
+ * @param       p_header_size   the size of the data contained in the CBD marker.
+ * @param       p_manager               the user event manager.
+*/
+static OPJ_BOOL opj_j2k_read_cbd (      opj_j2k_t *p_j2k,
+                                                                OPJ_BYTE * p_header_data,
+                                                                OPJ_UINT32 p_header_size,
+                                                                opj_event_mgr_t * p_manager);
+
+#if 0
+/**
+ * Writes COC marker for each component.
+ *
+ * @param       p_stream                the stream to write data to.
+ * @param       p_j2k                   J2K codec.
+ * @param       p_manager               the user event manager.
+*/
+static OPJ_BOOL opj_j2k_write_all_coc( opj_j2k_t *p_j2k,
+                                                                        opj_stream_private_t *p_stream,
+                                                                        opj_event_mgr_t * p_manager );
+#endif
+
+#if 0
+/**
+ * Writes QCC marker for each component.
+ *
+ * @param       p_stream                the stream to write data to.
+ * @param       p_j2k                   J2K codec.
+ * @param       p_manager               the user event manager.
+*/
+static OPJ_BOOL opj_j2k_write_all_qcc( opj_j2k_t *p_j2k,
+                                                                        opj_stream_private_t *p_stream,
+                                                                        opj_event_mgr_t * p_manager );
+#endif
+
+/**
+ * Writes regions of interests.
+ *
+ * @param       p_stream                the stream to write data to.
+ * @param       p_j2k                   J2K codec.
+ * @param       p_manager               the user event manager.
+*/
+static OPJ_BOOL opj_j2k_write_regions(  opj_j2k_t *p_j2k,
+                                                                        opj_stream_private_t *p_stream,
+                                                                        opj_event_mgr_t * p_manager );
+
+/**
+ * Writes EPC ????
+ *
+ * @param       p_stream                the stream to write data to.
+ * @param       p_j2k                   J2K codec.
+ * @param       p_manager               the user event manager.
+*/
+static OPJ_BOOL opj_j2k_write_epc(      opj_j2k_t *p_j2k,
+                                                                    opj_stream_private_t *p_stream,
+                                                                    opj_event_mgr_t * p_manager );
+
+/**
+ * Checks the progression order changes values. Tells of the poc given as input are valid.
+ * A nice message is outputted at errors.
+ *
+ * @param       p_pocs                  the progression order changes.
+ * @param       p_nb_pocs               the number of progression order changes.
+ * @param       p_nb_resolutions        the number of resolutions.
+ * @param       numcomps                the number of components
+ * @param       numlayers               the number of layers.
+ * @param       p_manager               the user event manager.
+ *
+ * @return      true if the pocs are valid.
+ */
+static OPJ_BOOL opj_j2k_check_poc_val(  const opj_poc_t *p_pocs,
+                                                                            OPJ_UINT32 p_nb_pocs,
+                                                                            OPJ_UINT32 p_nb_resolutions,
+                                                                            OPJ_UINT32 numcomps,
+                                                                            OPJ_UINT32 numlayers,
+                                                                            opj_event_mgr_t * p_manager);
+
+/**
+ * Gets the number of tile parts used for the given change of progression (if any) and the given tile.
+ *
+ * @param               cp                      the coding parameters.
+ * @param               pino            the offset of the given poc (i.e. its position in the coding parameter).
+ * @param               tileno          the given tile.
+ *
+ * @return              the number of tile parts.
+ */
+static OPJ_UINT32 opj_j2k_get_num_tp( opj_cp_t *cp, OPJ_UINT32 pino, OPJ_UINT32 tileno);
+
+/**
+ * Calculates the total number of tile parts needed by the encoder to
+ * encode such an image. If not enough memory is available, then the function return false.
+ *
+ * @param       p_nb_tiles      pointer that will hold the number of tile parts.
+ * @param       cp                      the coding parameters for the image.
+ * @param       image           the image to encode.
+ * @param       p_j2k                   the p_j2k encoder.
+ * @param       p_manager       the user event manager.
+ *
+ * @return true if the function was successful, false else.
+ */
+static OPJ_BOOL opj_j2k_calculate_tp(   opj_j2k_t *p_j2k,
+                                                                            opj_cp_t *cp,
+                                                                            OPJ_UINT32 * p_nb_tiles,
+                                                                            opj_image_t *image,
+                                                                            opj_event_mgr_t * p_manager);
+
+static void opj_j2k_dump_MH_info(opj_j2k_t* p_j2k, FILE* out_stream);
+
+static void opj_j2k_dump_MH_index(opj_j2k_t* p_j2k, FILE* out_stream);
+
+static opj_codestream_index_t* opj_j2k_create_cstr_index(void);
+
+static OPJ_FLOAT32 opj_j2k_get_tp_stride (opj_tcp_t * p_tcp);
+
+static OPJ_FLOAT32 opj_j2k_get_default_stride (opj_tcp_t * p_tcp);
+
+static int opj_j2k_initialise_4K_poc(opj_poc_t *POC, int numres);
+
+static void opj_j2k_set_cinema_parameters(opj_cparameters_t *parameters, opj_image_t *image, opj_event_mgr_t *p_manager);
+
+static OPJ_BOOL opj_j2k_is_cinema_compliant(opj_image_t *image, OPJ_UINT16 rsiz, opj_event_mgr_t *p_manager);
+
+/*@}*/
+
+/*@}*/
+
+/* ----------------------------------------------------------------------- */
+typedef struct j2k_prog_order{
+        OPJ_PROG_ORDER enum_prog;
+        char str_prog[5];
+}j2k_prog_order_t;
+
+j2k_prog_order_t j2k_prog_order_list[] = {
+        {OPJ_CPRL, "CPRL"},
+        {OPJ_LRCP, "LRCP"},
+        {OPJ_PCRL, "PCRL"},
+        {OPJ_RLCP, "RLCP"},
+        {OPJ_RPCL, "RPCL"},
+        {(OPJ_PROG_ORDER)-1, ""}
+};
+
+/**
+ * FIXME DOC
+ */
+static const OPJ_UINT32 MCT_ELEMENT_SIZE [] =
+{
+        2,
+        4,
+        4,
+        8
+};
+
+typedef void (* opj_j2k_mct_function) (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem);
+
+const opj_j2k_mct_function j2k_mct_read_functions_to_float [] =
+{
+        opj_j2k_read_int16_to_float,
+        opj_j2k_read_int32_to_float,
+        opj_j2k_read_float32_to_float,
+        opj_j2k_read_float64_to_float
+};
+
+const opj_j2k_mct_function j2k_mct_read_functions_to_int32 [] =
+{
+        opj_j2k_read_int16_to_int32,
+        opj_j2k_read_int32_to_int32,
+        opj_j2k_read_float32_to_int32,
+        opj_j2k_read_float64_to_int32
+};
+
+const opj_j2k_mct_function j2k_mct_write_functions_from_float [] =
+{
+        opj_j2k_write_float_to_int16,
+        opj_j2k_write_float_to_int32,
+        opj_j2k_write_float_to_float,
+        opj_j2k_write_float_to_float64
+};
+
+typedef struct opj_dec_memory_marker_handler
+{
+        /** marker value */
+        OPJ_UINT32 id;
+        /** value of the state when the marker can appear */
+        OPJ_UINT32 states;
+        /** action linked to the marker */
+        OPJ_BOOL (*handler) (   opj_j2k_t *p_j2k,
+                            OPJ_BYTE * p_header_data,
+                            OPJ_UINT32 p_header_size,
+                            opj_event_mgr_t * p_manager );
+}
+opj_dec_memory_marker_handler_t;
+
+const opj_dec_memory_marker_handler_t j2k_memory_marker_handler_tab [] =
+{
+  {J2K_MS_SOT, J2K_STATE_MH | J2K_STATE_TPHSOT, opj_j2k_read_sot},
+  {J2K_MS_COD, J2K_STATE_MH | J2K_STATE_TPH, opj_j2k_read_cod},
+  {J2K_MS_COC, J2K_STATE_MH | J2K_STATE_TPH, opj_j2k_read_coc},
+  {J2K_MS_RGN, J2K_STATE_MH | J2K_STATE_TPH, opj_j2k_read_rgn},
+  {J2K_MS_QCD, J2K_STATE_MH | J2K_STATE_TPH, opj_j2k_read_qcd},
+  {J2K_MS_QCC, J2K_STATE_MH | J2K_STATE_TPH, opj_j2k_read_qcc},
+  {J2K_MS_POC, J2K_STATE_MH | J2K_STATE_TPH, opj_j2k_read_poc},
+  {J2K_MS_SIZ, J2K_STATE_MHSIZ, opj_j2k_read_siz},
+  {J2K_MS_TLM, J2K_STATE_MH, opj_j2k_read_tlm},
+  {J2K_MS_PLM, J2K_STATE_MH, opj_j2k_read_plm},
+  {J2K_MS_PLT, J2K_STATE_TPH, opj_j2k_read_plt},
+  {J2K_MS_PPM, J2K_STATE_MH, j2k_read_ppm_v3},
+  {J2K_MS_PPT, J2K_STATE_TPH, opj_j2k_read_ppt},
+  {J2K_MS_SOP, 0, 0},
+  {J2K_MS_CRG, J2K_STATE_MH, opj_j2k_read_crg},
+  {J2K_MS_COM, J2K_STATE_MH | J2K_STATE_TPH, opj_j2k_read_com},
+  {J2K_MS_MCT, J2K_STATE_MH | J2K_STATE_TPH, opj_j2k_read_mct},
+  {J2K_MS_CBD, J2K_STATE_MH , opj_j2k_read_cbd},
+  {J2K_MS_MCC, J2K_STATE_MH | J2K_STATE_TPH, opj_j2k_read_mcc},
+  {J2K_MS_MCO, J2K_STATE_MH | J2K_STATE_TPH, opj_j2k_read_mco},
+#ifdef USE_JPWL
+#ifdef TODO_MS /* remove these functions which are not commpatible with the v2 API */
+  {J2K_MS_EPC, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_epc},
+  {J2K_MS_EPB, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_epb},
+  {J2K_MS_ESD, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_esd},
+  {J2K_MS_RED, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_red},
+#endif
+#endif /* USE_JPWL */
+#ifdef USE_JPSEC
+  {J2K_MS_SEC, J2K_DEC_STATE_MH, j2k_read_sec},
+  {J2K_MS_INSEC, 0, j2k_read_insec}
+#endif /* USE_JPSEC */
+  {J2K_MS_UNK, J2K_STATE_MH | J2K_STATE_TPH, 0}/*opj_j2k_read_unk is directly used*/
+};
+
+void  opj_j2k_read_int16_to_float (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem)
+{
+        OPJ_BYTE * l_src_data = (OPJ_BYTE *) p_src_data;
+        OPJ_FLOAT32 * l_dest_data = (OPJ_FLOAT32 *) p_dest_data;
+        OPJ_UINT32 i;
+        OPJ_UINT32 l_temp;
+
+        for (i=0;i<p_nb_elem;++i) {
+                opj_read_bytes(l_src_data,&l_temp,2);
+
+                l_src_data+=sizeof(OPJ_INT16);
+
+                *(l_dest_data++) = (OPJ_FLOAT32) l_temp;
+        }
+}
+
+void  opj_j2k_read_int32_to_float (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem)
+{
+        OPJ_BYTE * l_src_data = (OPJ_BYTE *) p_src_data;
+        OPJ_FLOAT32 * l_dest_data = (OPJ_FLOAT32 *) p_dest_data;
+        OPJ_UINT32 i;
+        OPJ_UINT32 l_temp;
+
+        for (i=0;i<p_nb_elem;++i) {
+                opj_read_bytes(l_src_data,&l_temp,4);
+
+                l_src_data+=sizeof(OPJ_INT32);
+
+                *(l_dest_data++) = (OPJ_FLOAT32) l_temp;
+        }
+}
+
+void  opj_j2k_read_float32_to_float (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem)
+{
+        OPJ_BYTE * l_src_data = (OPJ_BYTE *) p_src_data;
+        OPJ_FLOAT32 * l_dest_data = (OPJ_FLOAT32 *) p_dest_data;
+        OPJ_UINT32 i;
+        OPJ_FLOAT32 l_temp;
+
+        for (i=0;i<p_nb_elem;++i) {
+                opj_read_float(l_src_data,&l_temp);
+
+                l_src_data+=sizeof(OPJ_FLOAT32);
+
+                *(l_dest_data++) = l_temp;
+        }
+}
+
+void  opj_j2k_read_float64_to_float (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem)
+{
+        OPJ_BYTE * l_src_data = (OPJ_BYTE *) p_src_data;
+        OPJ_FLOAT32 * l_dest_data = (OPJ_FLOAT32 *) p_dest_data;
+        OPJ_UINT32 i;
+        OPJ_FLOAT64 l_temp;
+
+        for (i=0;i<p_nb_elem;++i) {
+                opj_read_double(l_src_data,&l_temp);
+
+                l_src_data+=sizeof(OPJ_FLOAT64);
+
+                *(l_dest_data++) = (OPJ_FLOAT32) l_temp;
+        }
+}
+
+void  opj_j2k_read_int16_to_int32 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem)
+{
+        OPJ_BYTE * l_src_data = (OPJ_BYTE *) p_src_data;
+        OPJ_INT32 * l_dest_data = (OPJ_INT32 *) p_dest_data;
+        OPJ_UINT32 i;
+        OPJ_UINT32 l_temp;
+
+        for (i=0;i<p_nb_elem;++i) {
+                opj_read_bytes(l_src_data,&l_temp,2);
+
+                l_src_data+=sizeof(OPJ_INT16);
+
+                *(l_dest_data++) = (OPJ_INT32) l_temp;
+        }
+}
+
+void  opj_j2k_read_int32_to_int32 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem)
+{
+        OPJ_BYTE * l_src_data = (OPJ_BYTE *) p_src_data;
+        OPJ_INT32 * l_dest_data = (OPJ_INT32 *) p_dest_data;
+        OPJ_UINT32 i;
+        OPJ_UINT32 l_temp;
+
+        for (i=0;i<p_nb_elem;++i) {
+                opj_read_bytes(l_src_data,&l_temp,4);
+
+                l_src_data+=sizeof(OPJ_INT32);
+
+                *(l_dest_data++) = (OPJ_INT32) l_temp;
+        }
+}
+
+void  opj_j2k_read_float32_to_int32 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem)
+{
+        OPJ_BYTE * l_src_data = (OPJ_BYTE *) p_src_data;
+        OPJ_INT32 * l_dest_data = (OPJ_INT32 *) p_dest_data;
+        OPJ_UINT32 i;
+        OPJ_FLOAT32 l_temp;
+
+        for (i=0;i<p_nb_elem;++i) {
+                opj_read_float(l_src_data,&l_temp);
+
+                l_src_data+=sizeof(OPJ_FLOAT32);
+
+                *(l_dest_data++) = (OPJ_INT32) l_temp;
+        }
+}
+
+void  opj_j2k_read_float64_to_int32 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem)
+{
+        OPJ_BYTE * l_src_data = (OPJ_BYTE *) p_src_data;
+        OPJ_INT32 * l_dest_data = (OPJ_INT32 *) p_dest_data;
+        OPJ_UINT32 i;
+        OPJ_FLOAT64 l_temp;
+
+        for (i=0;i<p_nb_elem;++i) {
+                opj_read_double(l_src_data,&l_temp);
+
+                l_src_data+=sizeof(OPJ_FLOAT64);
+
+                *(l_dest_data++) = (OPJ_INT32) l_temp;
+        }
+}
+
+void  opj_j2k_write_float_to_int16 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem)
+{
+        OPJ_BYTE * l_dest_data = (OPJ_BYTE *) p_dest_data;
+        OPJ_FLOAT32 * l_src_data = (OPJ_FLOAT32 *) p_src_data;
+        OPJ_UINT32 i;
+        OPJ_UINT32 l_temp;
+
+        for (i=0;i<p_nb_elem;++i) {
+                l_temp = (OPJ_UINT32) *(l_src_data++);
+
+                opj_write_bytes(l_dest_data,l_temp,sizeof(OPJ_INT16));
+
+                l_dest_data+=sizeof(OPJ_INT16);
+        }
+}
+
+void opj_j2k_write_float_to_int32 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem)
+{
+        OPJ_BYTE * l_dest_data = (OPJ_BYTE *) p_dest_data;
+        OPJ_FLOAT32 * l_src_data = (OPJ_FLOAT32 *) p_src_data;
+        OPJ_UINT32 i;
+        OPJ_UINT32 l_temp;
+
+        for (i=0;i<p_nb_elem;++i) {
+                l_temp = (OPJ_UINT32) *(l_src_data++);
+
+                opj_write_bytes(l_dest_data,l_temp,sizeof(OPJ_INT32));
+
+                l_dest_data+=sizeof(OPJ_INT32);
+        }
+}
+
+void  opj_j2k_write_float_to_float (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem)
+{
+        OPJ_BYTE * l_dest_data = (OPJ_BYTE *) p_dest_data;
+        OPJ_FLOAT32 * l_src_data = (OPJ_FLOAT32 *) p_src_data;
+        OPJ_UINT32 i;
+        OPJ_FLOAT32 l_temp;
+
+        for (i=0;i<p_nb_elem;++i) {
+                l_temp = (OPJ_FLOAT32) *(l_src_data++);
+
+                opj_write_float(l_dest_data,l_temp);
+
+                l_dest_data+=sizeof(OPJ_FLOAT32);
+        }
+}
+
+void  opj_j2k_write_float_to_float64 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem)
+{
+        OPJ_BYTE * l_dest_data = (OPJ_BYTE *) p_dest_data;
+        OPJ_FLOAT32 * l_src_data = (OPJ_FLOAT32 *) p_src_data;
+        OPJ_UINT32 i;
+        OPJ_FLOAT64 l_temp;
+
+        for (i=0;i<p_nb_elem;++i) {
+                l_temp = (OPJ_FLOAT64) *(l_src_data++);
+
+                opj_write_double(l_dest_data,l_temp);
+
+                l_dest_data+=sizeof(OPJ_FLOAT64);
+        }
+}
+
+char *opj_j2k_convert_progression_order(OPJ_PROG_ORDER prg_order){
+        j2k_prog_order_t *po;
+        for(po = j2k_prog_order_list; po->enum_prog != -1; po++ ){
+                if(po->enum_prog == prg_order){
+                        return po->str_prog;
+                }
+        }
+        return po->str_prog;
+}
+
+OPJ_BOOL opj_j2k_check_poc_val( const opj_poc_t *p_pocs,
+                                                        OPJ_UINT32 p_nb_pocs,
+                                                        OPJ_UINT32 p_nb_resolutions,
+                                                        OPJ_UINT32 p_num_comps,
+                                                        OPJ_UINT32 p_num_layers,
+                                                        opj_event_mgr_t * p_manager)
+{
+        OPJ_UINT32* packet_array;
+        OPJ_UINT32 index , resno, compno, layno;
+        OPJ_UINT32 i;
+        OPJ_UINT32 step_c = 1;
+        OPJ_UINT32 step_r = p_num_comps * step_c;
+        OPJ_UINT32 step_l = p_nb_resolutions * step_r;
+        OPJ_BOOL loss = OPJ_FALSE;
+        OPJ_UINT32 layno0 = 0;
+
+        packet_array = (OPJ_UINT32*) opj_calloc(step_l * p_num_layers, sizeof(OPJ_UINT32));
+        if (packet_array == 00) {
+                opj_event_msg(p_manager , EVT_ERROR, "Not enough memory for checking the poc values.\n");
+                return OPJ_FALSE;
+        }
+        memset(packet_array,0,step_l * p_num_layers* sizeof(OPJ_UINT32));
+
+        if (p_nb_pocs == 0) {
+        opj_free(packet_array);
+                return OPJ_TRUE;
+        }
+
+        index = step_r * p_pocs->resno0;
+        /* take each resolution for each poc */
+        for (resno = p_pocs->resno0 ; resno < p_pocs->resno1 ; ++resno)
+        {
+                OPJ_UINT32 res_index = index + p_pocs->compno0 * step_c;
+
+                /* take each comp of each resolution for each poc */
+                for (compno = p_pocs->compno0 ; compno < p_pocs->compno1 ; ++compno) {
+                        OPJ_UINT32 comp_index = res_index + layno0 * step_l;
+
+                        /* and finally take each layer of each res of ... */
+                        for (layno = layno0; layno < p_pocs->layno1 ; ++layno) {
+                                /*index = step_r * resno + step_c * compno + step_l * layno;*/
+                                packet_array[comp_index] = 1;
+                                comp_index += step_l;
+                        }
+
+                        res_index += step_c;
+                }
+
+                index += step_r;
+        }
+        ++p_pocs;
+
+        /* iterate through all the pocs */
+        for (i = 1; i < p_nb_pocs ; ++i) {
+                OPJ_UINT32 l_last_layno1 = (p_pocs-1)->layno1 ;
+
+                layno0 = (p_pocs->layno1 > l_last_layno1)? l_last_layno1 : 0;
+                index = step_r * p_pocs->resno0;
+
+                /* take each resolution for each poc */
+                for (resno = p_pocs->resno0 ; resno < p_pocs->resno1 ; ++resno) {
+                        OPJ_UINT32 res_index = index + p_pocs->compno0 * step_c;
+
+                        /* take each comp of each resolution for each poc */
+                        for (compno = p_pocs->compno0 ; compno < p_pocs->compno1 ; ++compno) {
+                                OPJ_UINT32 comp_index = res_index + layno0 * step_l;
+
+                                /* and finally take each layer of each res of ... */
+                                for (layno = layno0; layno < p_pocs->layno1 ; ++layno) {
+                                        /*index = step_r * resno + step_c * compno + step_l * layno;*/
+                                        packet_array[comp_index] = 1;
+                                        comp_index += step_l;
+                                }
+
+                                res_index += step_c;
+                        }
+
+                        index += step_r;
+                }
+
+                ++p_pocs;
+        }
+
+        index = 0;
+        for (layno = 0; layno < p_num_layers ; ++layno) {
+                for (resno = 0; resno < p_nb_resolutions; ++resno) {
+                        for (compno = 0; compno < p_num_comps; ++compno) {
+                                loss |= (packet_array[index]!=1);
+                                /*index = step_r * resno + step_c * compno + step_l * layno;*/
+                                index += step_c;
+                        }
+                }
+        }
+
+        if (loss) {
+                opj_event_msg(p_manager , EVT_ERROR, "Missing packets possible loss of data\n");
+        }
+
+        opj_free(packet_array);
+
+        return !loss;
+}
+
+/* ----------------------------------------------------------------------- */
+
+OPJ_UINT32 opj_j2k_get_num_tp(opj_cp_t *cp, OPJ_UINT32 pino, OPJ_UINT32 tileno)
+{
+        const OPJ_CHAR *prog = 00;
+        OPJ_INT32 i;
+        OPJ_UINT32 tpnum = 1;
+        opj_tcp_t *tcp = 00;
+        opj_poc_t * l_current_poc = 00;
+
+        /*  preconditions */
+        assert(tileno < (cp->tw * cp->th));
+        assert(pino < (cp->tcps[tileno].numpocs + 1));
+
+        /* get the given tile coding parameter */
+        tcp = &cp->tcps[tileno];
+        assert(tcp != 00);
+
+        l_current_poc = &(tcp->pocs[pino]);
+        assert(l_current_poc != 0);
+
+        /* get the progression order as a character string */
+        prog = opj_j2k_convert_progression_order(tcp->prg);
+        assert(strlen(prog) > 0);
+
+        if (cp->m_specific_param.m_enc.m_tp_on == 1) {
+                for (i=0;i<4;++i) {
+                        switch (prog[i])
+                        {
+                                /* component wise */
+                                case 'C':
+                                        tpnum *= l_current_poc->compE;
+                                        break;
+                                /* resolution wise */
+                                case 'R':
+                                        tpnum *= l_current_poc->resE;
+                                        break;
+                                /* precinct wise */
+                                case 'P':
+                                        tpnum *= l_current_poc->prcE;
+                                        break;
+                                /* layer wise */
+                                case 'L':
+                                        tpnum *= l_current_poc->layE;
+                                        break;
+                        }
+                        /* whould we split here ? */
+                        if ( cp->m_specific_param.m_enc.m_tp_flag == prog[i] ) {
+                                cp->m_specific_param.m_enc.m_tp_pos=i;
+                                break;
+                        }
+                }
+        }
+        else {
+                tpnum=1;
+        }
+
+        return tpnum;
+}
+
+OPJ_BOOL opj_j2k_calculate_tp(  opj_j2k_t *p_j2k,
+                                                        opj_cp_t *cp,
+                                                        OPJ_UINT32 * p_nb_tiles,
+                                                        opj_image_t *image,
+                                                        opj_event_mgr_t * p_manager
+                                )
+{
+        OPJ_UINT32 pino,tileno;
+        OPJ_UINT32 l_nb_tiles;
+        opj_tcp_t *tcp;
+
+        /* preconditions */
+        assert(p_nb_tiles != 00);
+        assert(cp != 00);
+        assert(image != 00);
+        assert(p_j2k != 00);
+        assert(p_manager != 00);
+
+        l_nb_tiles = cp->tw * cp->th;
+        * p_nb_tiles = 0;
+        tcp = cp->tcps;
+
+        /* INDEX >> */
+        /* TODO mergeV2: check this part which use cstr_info */
+        /*if (p_j2k->cstr_info) {
+                opj_tile_info_t * l_info_tile_ptr = p_j2k->cstr_info->tile;
+
+                for (tileno = 0; tileno < l_nb_tiles; ++tileno) {
+                        OPJ_UINT32 cur_totnum_tp = 0;
+
+                        opj_pi_update_encoding_parameters(image,cp,tileno);
+
+                        for (pino = 0; pino <= tcp->numpocs; ++pino)
+                        {
+                                OPJ_UINT32 tp_num = opj_j2k_get_num_tp(cp,pino,tileno);
+
+                                *p_nb_tiles = *p_nb_tiles + tp_num;
+
+                                cur_totnum_tp += tp_num;
+                        }
+
+                        tcp->m_nb_tile_parts = cur_totnum_tp;
+
+                        l_info_tile_ptr->tp = (opj_tp_info_t *) opj_malloc(cur_totnum_tp * sizeof(opj_tp_info_t));
+                        if (l_info_tile_ptr->tp == 00) {
+                                return OPJ_FALSE;
+                        }
+
+                        memset(l_info_tile_ptr->tp,0,cur_totnum_tp * sizeof(opj_tp_info_t));
+
+                        l_info_tile_ptr->num_tps = cur_totnum_tp;
+
+                        ++l_info_tile_ptr;
+                        ++tcp;
+                }
+        }
+        else */{
+                for (tileno = 0; tileno < l_nb_tiles; ++tileno) {
+                        OPJ_UINT32 cur_totnum_tp = 0;
+
+                        opj_pi_update_encoding_parameters(image,cp,tileno);
+
+                        for (pino = 0; pino <= tcp->numpocs; ++pino) {
+                                OPJ_UINT32 tp_num = opj_j2k_get_num_tp(cp,pino,tileno);
+
+                                *p_nb_tiles = *p_nb_tiles + tp_num;
+
+                                cur_totnum_tp += tp_num;
+                        }
+                        tcp->m_nb_tile_parts = cur_totnum_tp;
+
+                        ++tcp;
+                }
+        }
+
+        return OPJ_TRUE;
+}
+
+OPJ_BOOL opj_j2k_write_soc(     opj_j2k_t *p_j2k,
+                                                opj_stream_private_t *p_stream,
+                                                    opj_event_mgr_t * p_manager )
+{
+        /* 2 bytes will be written */
+        OPJ_BYTE * l_start_stream = 00;
+
+        /* preconditions */
+        assert(p_stream != 00);
+        assert(p_j2k != 00);
+        assert(p_manager != 00);
+
+        l_start_stream = p_j2k->m_specific_param.m_encoder.m_header_tile_data;
+
+        /* write SOC identifier */
+        opj_write_bytes(l_start_stream,J2K_MS_SOC,2);
+
+        if (opj_stream_write_data(p_stream,l_start_stream,2,p_manager) != 2) {
+                return OPJ_FALSE;
+        }
+
+/* UniPG>> */
+#ifdef USE_JPWL
+        /* update markers struct */
+/*
+        OPJ_BOOL res = j2k_add_marker(p_j2k->cstr_info, J2K_MS_SOC, p_stream_tell(p_stream) - 2, 2);
+*/
+  assert( 0 && "TODO" );
+#endif /* USE_JPWL */
+/* <<UniPG */
+
+        return OPJ_TRUE;
+}
+
+/**
+ * Reads a SOC marker (Start of Codestream)
+ * @param       p_j2k           the jpeg2000 file codec.
+ * @param       p_stream        FIXME DOC
+ * @param       p_manager       the user event manager.
+*/
+static OPJ_BOOL opj_j2k_read_soc(   opj_j2k_t *p_j2k,
+                                    opj_stream_private_t *p_stream,
+                                    opj_event_mgr_t * p_manager
+                                    )
+{
+        OPJ_BYTE l_data [2];
+        OPJ_UINT32 l_marker;
+
+        /* preconditions */
+        assert(p_j2k != 00);
+        assert(p_manager != 00);
+        assert(p_stream != 00);
+
+        if (opj_stream_read_data(p_stream,l_data,2,p_manager) != 2) {
+                return OPJ_FALSE;
+        }
+
+        opj_read_bytes(l_data,&l_marker,2);
+        if (l_marker != J2K_MS_SOC) {
+                return OPJ_FALSE;
+        }
+
+        /* Next marker should be a SIZ marker in the main header */
+        p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_MHSIZ;
+
+        /* FIXME move it in a index structure included in p_j2k*/
+        p_j2k->cstr_index->main_head_start = opj_stream_tell(p_stream) - 2;
+
+        opj_event_msg(p_manager, EVT_INFO, "Start to read j2k main header (%d).\n", p_j2k->cstr_index->main_head_start);
+
+        /* Add the marker to the codestream index*/
+        if (OPJ_FALSE == opj_j2k_add_mhmarker(p_j2k->cstr_index, J2K_MS_SOC, p_j2k->cstr_index->main_head_start, 2)) {
+                opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to add mh marker\n");
+                return OPJ_FALSE;
+        }
+        return OPJ_TRUE;
+}
+
+OPJ_BOOL opj_j2k_write_siz(     opj_j2k_t *p_j2k,
+                                                        opj_stream_private_t *p_stream,
+                                                        opj_event_mgr_t * p_manager )
+{
+        OPJ_UINT32 i;
+        OPJ_UINT32 l_size_len;
+        OPJ_BYTE * l_current_ptr;
+        opj_image_t * l_image = 00;
+        opj_cp_t *cp = 00;
+        opj_image_comp_t * l_img_comp = 00;
+
+        /* preconditions */
+        assert(p_stream != 00);
+        assert(p_j2k != 00);
+        assert(p_manager != 00);
+
+        l_image = p_j2k->m_private_image;
+        cp = &(p_j2k->m_cp);
+        l_size_len = 40 + 3 * l_image->numcomps;
+        l_img_comp = l_image->comps;
+
+        if (l_size_len > p_j2k->m_specific_param.m_encoder.m_header_tile_data_size) {
+
+                OPJ_BYTE *new_header_tile_data = (OPJ_BYTE *) opj_realloc(p_j2k->m_specific_param.m_encoder.m_header_tile_data, l_size_len);
+                if (! new_header_tile_data) {
+                        opj_free(p_j2k->m_specific_param.m_encoder.m_header_tile_data);
+                        p_j2k->m_specific_param.m_encoder.m_header_tile_data = NULL;
+                        p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = 0;
+                        opj_event_msg(p_manager, EVT_ERROR, "Not enough memory for the SIZ marker\n");
+                        return OPJ_FALSE;
+                }
+                p_j2k->m_specific_param.m_encoder.m_header_tile_data = new_header_tile_data;
+                p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = l_size_len;
+        }
+
+        l_current_ptr = p_j2k->m_specific_param.m_encoder.m_header_tile_data;
+
+        /* write SOC identifier */
+        opj_write_bytes(l_current_ptr,J2K_MS_SIZ,2);    /* SIZ */
+        l_current_ptr+=2;
+
+        opj_write_bytes(l_current_ptr,l_size_len-2,2); /* L_SIZ */
+        l_current_ptr+=2;
+
+        opj_write_bytes(l_current_ptr, cp->rsiz, 2);    /* Rsiz (capabilities) */
+        l_current_ptr+=2;
+
+        opj_write_bytes(l_current_ptr, l_image->x1, 4); /* Xsiz */
+        l_current_ptr+=4;
+
+        opj_write_bytes(l_current_ptr, l_image->y1, 4); /* Ysiz */
+        l_current_ptr+=4;
+
+        opj_write_bytes(l_current_ptr, l_image->x0, 4); /* X0siz */
+        l_current_ptr+=4;
+
+        opj_write_bytes(l_current_ptr, l_image->y0, 4); /* Y0siz */
+        l_current_ptr+=4;
+
+        opj_write_bytes(l_current_ptr, cp->tdx, 4);             /* XTsiz */
+        l_current_ptr+=4;
+
+        opj_write_bytes(l_current_ptr, cp->tdy, 4);             /* YTsiz */
+        l_current_ptr+=4;
+
+        opj_write_bytes(l_current_ptr, cp->tx0, 4);             /* XT0siz */
+        l_current_ptr+=4;
+
+        opj_write_bytes(l_current_ptr, cp->ty0, 4);             /* YT0siz */
+        l_current_ptr+=4;
+
+        opj_write_bytes(l_current_ptr, l_image->numcomps, 2);   /* Csiz */
+        l_current_ptr+=2;
+
+        for (i = 0; i < l_image->numcomps; ++i) {
+                /* TODO here with MCT ? */
+                opj_write_bytes(l_current_ptr, l_img_comp->prec - 1 + (l_img_comp->sgnd << 7), 1);      /* Ssiz_i */
+                ++l_current_ptr;
+
+                opj_write_bytes(l_current_ptr, l_img_comp->dx, 1);      /* XRsiz_i */
+                ++l_current_ptr;
+
+                opj_write_bytes(l_current_ptr, l_img_comp->dy, 1);      /* YRsiz_i */
+                ++l_current_ptr;
+
+                ++l_img_comp;
+        }
+
+        if (opj_stream_write_data(p_stream,p_j2k->m_specific_param.m_encoder.m_header_tile_data,l_size_len,p_manager) != l_size_len) {
+                return OPJ_FALSE;
+        }
+
+        return OPJ_TRUE;
+}
+
+/**
+ * Reads a SIZ marker (image and tile size)
+ * @param       p_j2k           the jpeg2000 file codec.
+ * @param       p_header_data   the data contained in the SIZ box.
+ * @param       p_header_size   the size of the data contained in the SIZ marker.
+ * @param       p_manager       the user event manager.
+*/
+static OPJ_BOOL opj_j2k_read_siz(opj_j2k_t *p_j2k,
+                                 OPJ_BYTE * p_header_data,
+                                 OPJ_UINT32 p_header_size,
+                                 opj_event_mgr_t * p_manager
+                                 )
+{
+        OPJ_UINT32 i;
+        OPJ_UINT32 l_nb_comp;
+        OPJ_UINT32 l_nb_comp_remain;
+        OPJ_UINT32 l_remaining_size;
+        OPJ_UINT32 l_nb_tiles;
+        OPJ_UINT32 l_tmp;
+        opj_image_t *l_image = 00;
+        opj_cp_t *l_cp = 00;
+        opj_image_comp_t * l_img_comp = 00;
+        opj_tcp_t * l_current_tile_param = 00;
+
+        /* preconditions */
+        assert(p_j2k != 00);
+        assert(p_manager != 00);
+        assert(p_header_data != 00);
+
+        l_image = p_j2k->m_private_image;
+        l_cp = &(p_j2k->m_cp);
+
+        /* minimum size == 39 - 3 (= minimum component parameter) */
+        if (p_header_size < 36) {
+                opj_event_msg(p_manager, EVT_ERROR, "Error with SIZ marker size\n");
+                return OPJ_FALSE;
+        }
+
+        l_remaining_size = p_header_size - 36;
+        l_nb_comp = l_remaining_size / 3;
+        l_nb_comp_remain = l_remaining_size % 3;
+        if (l_nb_comp_remain != 0){
+                opj_event_msg(p_manager, EVT_ERROR, "Error with SIZ marker size\n");
+                return OPJ_FALSE;
+        }
+
+        opj_read_bytes(p_header_data,&l_tmp ,2);                                                /* Rsiz (capabilities) */
+        p_header_data+=2;
+        l_cp->rsiz = (OPJ_UINT16) l_tmp;
+        opj_read_bytes(p_header_data, (OPJ_UINT32*) &l_image->x1, 4);   /* Xsiz */
+        p_header_data+=4;
+        opj_read_bytes(p_header_data, (OPJ_UINT32*) &l_image->y1, 4);   /* Ysiz */
+        p_header_data+=4;
+        opj_read_bytes(p_header_data, (OPJ_UINT32*) &l_image->x0, 4);   /* X0siz */
+        p_header_data+=4;
+        opj_read_bytes(p_header_data, (OPJ_UINT32*) &l_image->y0, 4);   /* Y0siz */
+        p_header_data+=4;
+        opj_read_bytes(p_header_data, (OPJ_UINT32*) &l_cp->tdx, 4);             /* XTsiz */
+        p_header_data+=4;
+        opj_read_bytes(p_header_data, (OPJ_UINT32*) &l_cp->tdy, 4);             /* YTsiz */
+        p_header_data+=4;
+        opj_read_bytes(p_header_data, (OPJ_UINT32*) &l_cp->tx0, 4);             /* XT0siz */
+        p_header_data+=4;
+        opj_read_bytes(p_header_data, (OPJ_UINT32*) &l_cp->ty0, 4);             /* YT0siz */
+        p_header_data+=4;
+        opj_read_bytes(p_header_data, (OPJ_UINT32*) &l_tmp, 2);                 /* Csiz */
+        p_header_data+=2;
+        if (l_tmp < 16385)
+                l_image->numcomps = (OPJ_UINT16) l_tmp;
+        else {
+                opj_event_msg(p_manager, EVT_ERROR, "Error with SIZ marker: number of component is illegal -> %d\n", l_tmp);
+                return OPJ_FALSE;
+        }
+
+        if (l_image->numcomps != l_nb_comp) {
+                opj_event_msg(p_manager, EVT_ERROR, "Error with SIZ marker: number of component is not compatible with the remaining number of parameters ( %d vs %d)\n", l_image->numcomps, l_nb_comp);
+                return OPJ_FALSE;
+        }
+
+        /* testcase 4035.pdf.SIGSEGV.d8b.3375 */
+        if (l_image->x0 > l_image->x1 || l_image->y0 > l_image->y1) {
+                opj_event_msg(p_manager, EVT_ERROR, "Error with SIZ marker: negative image size (%d x %d)\n", l_image->x1 - l_image->x0, l_image->y1 - l_image->y0);
+                return OPJ_FALSE;
+        }
+        /* testcase 2539.pdf.SIGFPE.706.1712 (also 3622.pdf.SIGFPE.706.2916 and 4008.pdf.SIGFPE.706.3345 and maybe more) */
+        if (!(l_cp->tdx * l_cp->tdy)) {
+                opj_event_msg(p_manager, EVT_ERROR, "Error with SIZ marker: invalid tile size (tdx: %d, tdy: %d)\n", l_cp->tdx, l_cp->tdy);
+                return OPJ_FALSE;
+        }
+
+        /* testcase 1610.pdf.SIGSEGV.59c.681 */
+        if (((OPJ_UINT64)l_image->x1) * ((OPJ_UINT64)l_image->y1) != (l_image->x1 * l_image->y1)) {
+                opj_event_msg(p_manager, EVT_ERROR, "Prevent buffer overflow (x1: %d, y1: %d)\n", l_image->x1, l_image->y1);
+                return OPJ_FALSE;
+        }
+
+#ifdef USE_JPWL
+        if (l_cp->correct) {
+                /* if JPWL is on, we check whether TX errors have damaged
+                  too much the SIZ parameters */
+                if (!(l_image->x1 * l_image->y1)) {
+                        opj_event_msg(p_manager, EVT_ERROR,
+                                "JPWL: bad image size (%d x %d)\n",
+                                l_image->x1, l_image->y1);
+                        if (!JPWL_ASSUME || JPWL_ASSUME) {
+                                opj_event_msg(p_manager, EVT_ERROR, "JPWL: giving up\n");
+                                return OPJ_FALSE;
+                        }
+                }
+
+        /* FIXME check previously in the function so why keep this piece of code ? Need by the norm ?
+                if (l_image->numcomps != ((len - 38) / 3)) {
+                        opj_event_msg(p_manager, JPWL_ASSUME ? EVT_WARNING : EVT_ERROR,
+                                "JPWL: Csiz is %d => space in SIZ only for %d comps.!!!\n",
+                                l_image->numcomps, ((len - 38) / 3));
+                        if (!JPWL_ASSUME) {
+                                opj_event_msg(p_manager, EVT_ERROR, "JPWL: giving up\n");
+                                return OPJ_FALSE;
+                        }
+        */              /* we try to correct */
+        /*              opj_event_msg(p_manager, EVT_WARNING, "- trying to adjust this\n");
+                        if (l_image->numcomps < ((len - 38) / 3)) {
+                                len = 38 + 3 * l_image->numcomps;
+                                opj_event_msg(p_manager, EVT_WARNING, "- setting Lsiz to %d => HYPOTHESIS!!!\n",
+                                        len);
+                        } else {
+                                l_image->numcomps = ((len - 38) / 3);
+                                opj_event_msg(p_manager, EVT_WARNING, "- setting Csiz to %d => HYPOTHESIS!!!\n",
+                                        l_image->numcomps);
+                        }
+                }
+        */
+
+                /* update components number in the jpwl_exp_comps filed */
+                l_cp->exp_comps = l_image->numcomps;
+        }
+#endif /* USE_JPWL */
+
+        /* Allocate the resulting image components */
+        l_image->comps = (opj_image_comp_t*) opj_calloc(l_image->numcomps, sizeof(opj_image_comp_t));
+        if (l_image->comps == 00){
+                l_image->numcomps = 0;
+                opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to take in charge SIZ marker\n");
+                return OPJ_FALSE;
+        }
+
+        memset(l_image->comps,0,l_image->numcomps * sizeof(opj_image_comp_t));
+        l_img_comp = l_image->comps;
+
+        /* Read the component information */
+        for (i = 0; i < l_image->numcomps; ++i){
+                OPJ_UINT32 tmp;
+                opj_read_bytes(p_header_data,&tmp,1);   /* Ssiz_i */
+                ++p_header_data;
+                l_img_comp->prec = (tmp & 0x7f) + 1;
+                l_img_comp->sgnd = tmp >> 7;
+                opj_read_bytes(p_header_data,&tmp,1);   /* XRsiz_i */
+                ++p_header_data;
+                l_img_comp->dx = (OPJ_UINT32)tmp; /* should be between 1 and 255 */
+                opj_read_bytes(p_header_data,&tmp,1);   /* YRsiz_i */
+                ++p_header_data;
+                l_img_comp->dy = (OPJ_UINT32)tmp; /* should be between 1 and 255 */
+                if( l_img_comp->dx < 1 || l_img_comp->dx > 255 ||
+                    l_img_comp->dy < 1 || l_img_comp->dy > 255 ) {
+                    opj_event_msg(p_manager, EVT_ERROR,
+                                  "Invalid values for comp = %d : dx=%u dy=%u\n (should be between 1 and 255 according the JPEG2000 norm)",
+                                  i, l_img_comp->dx, l_img_comp->dy);
+                    return OPJ_FALSE;
+                }
+
+#ifdef USE_JPWL
+                if (l_cp->correct) {
+                /* if JPWL is on, we check whether TX errors have damaged
+                        too much the SIZ parameters, again */
+                        if (!(l_image->comps[i].dx * l_image->comps[i].dy)) {
+                                opj_event_msg(p_manager, JPWL_ASSUME ? EVT_WARNING : EVT_ERROR,
+                                        "JPWL: bad XRsiz_%d/YRsiz_%d (%d x %d)\n",
+                                        i, i, l_image->comps[i].dx, l_image->comps[i].dy);
+                                if (!JPWL_ASSUME) {
+                                        opj_event_msg(p_manager, EVT_ERROR, "JPWL: giving up\n");
+                                        return OPJ_FALSE;
+                                }
+                                /* we try to correct */
+                                opj_event_msg(p_manager, EVT_WARNING, "- trying to adjust them\n");
+                                if (!l_image->comps[i].dx) {
+                                        l_image->comps[i].dx = 1;
+                                        opj_event_msg(p_manager, EVT_WARNING, "- setting XRsiz_%d to %d => HYPOTHESIS!!!\n",
+                                                i, l_image->comps[i].dx);
+                                }
+                                if (!l_image->comps[i].dy) {
+                                        l_image->comps[i].dy = 1;
+                                        opj_event_msg(p_manager, EVT_WARNING, "- setting YRsiz_%d to %d => HYPOTHESIS!!!\n",
+                                                i, l_image->comps[i].dy);
+                                }
+                        }
+                }
+#endif /* USE_JPWL */
+                l_img_comp->resno_decoded = 0;                                                          /* number of resolution decoded */
+                l_img_comp->factor = l_cp->m_specific_param.m_dec.m_reduce; /* reducing factor per component */
+                ++l_img_comp;
+        }
+
+        /* Compute the number of tiles */
+        l_cp->tw = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)(l_image->x1 - l_cp->tx0), (OPJ_INT32)l_cp->tdx);
+        l_cp->th = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)(l_image->y1 - l_cp->ty0), (OPJ_INT32)l_cp->tdy);
+
+        /* Check that the number of tiles is valid */
+        if (l_cp->tw == 0 || l_cp->th == 0 || l_cp->tw > 65535 / l_cp->th) {
+            opj_event_msg(  p_manager, EVT_ERROR, 
+                            "Invalid number of tiles : %u x %u (maximum fixed by jpeg2000 norm is 65535 tiles)\n",
+                            l_cp->tw, l_cp->th);
+            return OPJ_FALSE;
+        }
+        l_nb_tiles = l_cp->tw * l_cp->th;
+
+        /* Define the tiles which will be decoded */
+        if (p_j2k->m_specific_param.m_decoder.m_discard_tiles) {
+                p_j2k->m_specific_param.m_decoder.m_start_tile_x = (p_j2k->m_specific_param.m_decoder.m_start_tile_x - l_cp->tx0) / l_cp->tdx;
+                p_j2k->m_specific_param.m_decoder.m_start_tile_y = (p_j2k->m_specific_param.m_decoder.m_start_tile_y - l_cp->ty0) / l_cp->tdy;
+                p_j2k->m_specific_param.m_decoder.m_end_tile_x = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)(p_j2k->m_specific_param.m_decoder.m_end_tile_x - l_cp->tx0), (OPJ_INT32)l_cp->tdx);
+                p_j2k->m_specific_param.m_decoder.m_end_tile_y = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)(p_j2k->m_specific_param.m_decoder.m_end_tile_y - l_cp->ty0), (OPJ_INT32)l_cp->tdy);
+        }
+        else {
+                p_j2k->m_specific_param.m_decoder.m_start_tile_x = 0;
+                p_j2k->m_specific_param.m_decoder.m_start_tile_y = 0;
+                p_j2k->m_specific_param.m_decoder.m_end_tile_x = l_cp->tw;
+                p_j2k->m_specific_param.m_decoder.m_end_tile_y = l_cp->th;
+        }
+
+#ifdef USE_JPWL
+        if (l_cp->correct) {
+                /* if JPWL is on, we check whether TX errors have damaged
+                  too much the SIZ parameters */
+                if ((l_cp->tw < 1) || (l_cp->th < 1) || (l_cp->tw > l_cp->max_tiles) || (l_cp->th > l_cp->max_tiles)) {
+                        opj_event_msg(p_manager, JPWL_ASSUME ? EVT_WARNING : EVT_ERROR,
+                                "JPWL: bad number of tiles (%d x %d)\n",
+                                l_cp->tw, l_cp->th);
+                        if (!JPWL_ASSUME) {
+                                opj_event_msg(p_manager, EVT_ERROR, "JPWL: giving up\n");
+                                return OPJ_FALSE;
+                        }
+                        /* we try to correct */
+                        opj_event_msg(p_manager, EVT_WARNING, "- trying to adjust them\n");
+                        if (l_cp->tw < 1) {
+                                l_cp->tw= 1;
+                                opj_event_msg(p_manager, EVT_WARNING, "- setting %d tiles in x => HYPOTHESIS!!!\n",
+                                                l_cp->tw);
+                        }
+                        if (l_cp->tw > l_cp->max_tiles) {
+                                l_cp->tw= 1;
+                                opj_event_msg(p_manager, EVT_WARNING, "- too large x, increase expectance of %d\n"
+                                        "- setting %d tiles in x => HYPOTHESIS!!!\n",
+                                        l_cp->max_tiles, l_cp->tw);
+                        }
+                        if (l_cp->th < 1) {
+                                l_cp->th= 1;
+                                opj_event_msg(p_manager, EVT_WARNING, "- setting %d tiles in y => HYPOTHESIS!!!\n",
+                                                l_cp->th);
+                        }
+                        if (l_cp->th > l_cp->max_tiles) {
+                                l_cp->th= 1;
+                                opj_event_msg(p_manager, EVT_WARNING, "- too large y, increase expectance of %d to continue\n",
+                                        "- setting %d tiles in y => HYPOTHESIS!!!\n",
+                                        l_cp->max_tiles, l_cp->th);
+                        }
+                }
+        }
+#endif /* USE_JPWL */
+
+        /* memory allocations */
+        l_cp->tcps = (opj_tcp_t*) opj_calloc(l_nb_tiles, sizeof(opj_tcp_t));
+        if (l_cp->tcps == 00) {
+                opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to take in charge SIZ marker\n");
+                return OPJ_FALSE;
+        }
+        memset(l_cp->tcps,0,l_nb_tiles*sizeof(opj_tcp_t));
+
+#ifdef USE_JPWL
+        if (l_cp->correct) {
+                if (!l_cp->tcps) {
+                        opj_event_msg(p_manager, JPWL_ASSUME ? EVT_WARNING : EVT_ERROR,
+                                "JPWL: could not alloc tcps field of cp\n");
+                        if (!JPWL_ASSUME || JPWL_ASSUME) {
+                                opj_event_msg(p_manager, EVT_ERROR, "JPWL: giving up\n");
+                                return OPJ_FALSE;
+                        }
+                }
+        }
+#endif /* USE_JPWL */
+
+        p_j2k->m_specific_param.m_decoder.m_default_tcp->tccps =
+                        (opj_tccp_t*) opj_calloc(l_image->numcomps, sizeof(opj_tccp_t));
+        if(p_j2k->m_specific_param.m_decoder.m_default_tcp->tccps  == 00) {
+                opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to take in charge SIZ marker\n");
+                return OPJ_FALSE;
+        }
+        memset(p_j2k->m_specific_param.m_decoder.m_default_tcp->tccps ,0,l_image->numcomps*sizeof(opj_tccp_t));
+
+        p_j2k->m_specific_param.m_decoder.m_default_tcp->m_mct_records =
+                        (opj_mct_data_t*)opj_malloc(OPJ_J2K_MCT_DEFAULT_NB_RECORDS * sizeof(opj_mct_data_t));
+
+        if (! p_j2k->m_specific_param.m_decoder.m_default_tcp->m_mct_records) {
+                opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to take in charge SIZ marker\n");
+                return OPJ_FALSE;
+        }
+        memset(p_j2k->m_specific_param.m_decoder.m_default_tcp->m_mct_records,0,OPJ_J2K_MCT_DEFAULT_NB_RECORDS * sizeof(opj_mct_data_t));
+        p_j2k->m_specific_param.m_decoder.m_default_tcp->m_nb_max_mct_records = OPJ_J2K_MCT_DEFAULT_NB_RECORDS;
+
+        p_j2k->m_specific_param.m_decoder.m_default_tcp->m_mcc_records =
+                        (opj_simple_mcc_decorrelation_data_t*)
+                        opj_malloc(OPJ_J2K_MCC_DEFAULT_NB_RECORDS * sizeof(opj_simple_mcc_decorrelation_data_t));
+
+        if (! p_j2k->m_specific_param.m_decoder.m_default_tcp->m_mcc_records) {
+                opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to take in charge SIZ marker\n");
+                return OPJ_FALSE;
+        }
+        memset(p_j2k->m_specific_param.m_decoder.m_default_tcp->m_mcc_records,0,OPJ_J2K_MCC_DEFAULT_NB_RECORDS * sizeof(opj_simple_mcc_decorrelation_data_t));
+        p_j2k->m_specific_param.m_decoder.m_default_tcp->m_nb_max_mcc_records = OPJ_J2K_MCC_DEFAULT_NB_RECORDS;
+
+        /* set up default dc level shift */
+        for (i=0;i<l_image->numcomps;++i) {
+                if (! l_image->comps[i].sgnd) {
+                        p_j2k->m_specific_param.m_decoder.m_default_tcp->tccps[i].m_dc_level_shift = 1 << (l_image->comps[i].prec - 1);
+                }
+        }
+
+        l_current_tile_param = l_cp->tcps;
+        for     (i = 0; i < l_nb_tiles; ++i) {
+                l_current_tile_param->tccps = (opj_tccp_t*) opj_malloc(l_image->numcomps * sizeof(opj_tccp_t));
+                if (l_current_tile_param->tccps == 00) {
+                        opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to take in charge SIZ marker\n");
+                        return OPJ_FALSE;
+                }
+                memset(l_current_tile_param->tccps,0,l_image->numcomps * sizeof(opj_tccp_t));
+
+                ++l_current_tile_param;
+        }
+
+        p_j2k->m_specific_param.m_decoder.m_state =  J2K_STATE_MH; /* FIXME J2K_DEC_STATE_MH; */
+        opj_image_comp_header_update(l_image,l_cp);
+
+        return OPJ_TRUE;
+}
+
+OPJ_BOOL opj_j2k_write_com(     opj_j2k_t *p_j2k,
+                                                        opj_stream_private_t *p_stream,
+                                                        opj_event_mgr_t * p_manager
+                            )
+{
+        OPJ_UINT32 l_comment_size;
+        OPJ_UINT32 l_total_com_size;
+        const OPJ_CHAR *l_comment;
+        OPJ_BYTE * l_current_ptr = 00;
+
+        /* preconditions */
+        assert(p_j2k != 00);
+        assert(p_stream != 00);
+        assert(p_manager != 00);
+
+        l_comment = p_j2k->m_cp.comment;
+        l_comment_size = (OPJ_UINT32)strlen(l_comment);
+        l_total_com_size = l_comment_size + 6;
+
+        if (l_total_com_size > p_j2k->m_specific_param.m_encoder.m_header_tile_data_size) {
+                OPJ_BYTE *new_header_tile_data = (OPJ_BYTE *) opj_realloc(p_j2k->m_specific_param.m_encoder.m_header_tile_data, l_total_com_size);
+                if (! new_header_tile_data) {
+                        opj_free(p_j2k->m_specific_param.m_encoder.m_header_tile_data);
+                        p_j2k->m_specific_param.m_encoder.m_header_tile_data = NULL;
+                        p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = 0;
+                        opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to write the COM marker\n");
+                        return OPJ_FALSE;
+                }
+                p_j2k->m_specific_param.m_encoder.m_header_tile_data = new_header_tile_data;
+                p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = l_total_com_size;
+        }
+
+        l_current_ptr = p_j2k->m_specific_param.m_encoder.m_header_tile_data;
+
+        opj_write_bytes(l_current_ptr,J2K_MS_COM , 2);  /* COM */
+        l_current_ptr+=2;
+
+        opj_write_bytes(l_current_ptr,l_total_com_size - 2 , 2);        /* L_COM */
+        l_current_ptr+=2;
+
+        opj_write_bytes(l_current_ptr,1 , 2);   /* General use (IS 8859-15:1999 (Latin) values) */
+        l_current_ptr+=2;
+
+        memcpy( l_current_ptr,l_comment,l_comment_size);
+
+        if (opj_stream_write_data(p_stream,p_j2k->m_specific_param.m_encoder.m_header_tile_data,l_total_com_size,p_manager) != l_total_com_size) {
+                return OPJ_FALSE;
+        }
+
+        return OPJ_TRUE;
+}
+
+/**
+ * Reads a COM marker (comments)
+ * @param       p_j2k           the jpeg2000 file codec.
+ * @param       p_header_data   the data contained in the COM box.
+ * @param       p_header_size   the size of the data contained in the COM marker.
+ * @param       p_manager               the user event manager.
+*/
+static OPJ_BOOL opj_j2k_read_com (  opj_j2k_t *p_j2k,
+                                    OPJ_BYTE * p_header_data,
+                                    OPJ_UINT32 p_header_size,
+                                    opj_event_mgr_t * p_manager
+                                    )
+{
+        /* preconditions */
+        assert(p_j2k != 00);
+        assert(p_manager != 00);
+        assert(p_header_data != 00);
+  (void)p_header_size;
+
+        return OPJ_TRUE;
+}
+
+OPJ_BOOL opj_j2k_write_cod(     opj_j2k_t *p_j2k,
+                                                        opj_stream_private_t *p_stream,
+                                                        opj_event_mgr_t * p_manager )
+{
+        opj_cp_t *l_cp = 00;
+        opj_tcp_t *l_tcp = 00;
+        OPJ_UINT32 l_code_size,l_remaining_size;
+        OPJ_BYTE * l_current_data = 00;
+
+        /* preconditions */
+        assert(p_j2k != 00);
+        assert(p_manager != 00);
+        assert(p_stream != 00);
+
+        l_cp = &(p_j2k->m_cp);
+        l_tcp = &l_cp->tcps[p_j2k->m_current_tile_number];
+        l_code_size = 9 + opj_j2k_get_SPCod_SPCoc_size(p_j2k,p_j2k->m_current_tile_number,0);
+        l_remaining_size = l_code_size;
+
+        if (l_code_size > p_j2k->m_specific_param.m_encoder.m_header_tile_data_size) {
+                OPJ_BYTE *new_header_tile_data = (OPJ_BYTE *) opj_realloc(p_j2k->m_specific_param.m_encoder.m_header_tile_data, l_code_size);
+                if (! new_header_tile_data) {
+                        opj_free(p_j2k->m_specific_param.m_encoder.m_header_tile_data);
+                        p_j2k->m_specific_param.m_encoder.m_header_tile_data = NULL;
+                        p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = 0;
+                        opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to write COD marker\n");
+                        return OPJ_FALSE;
+                }
+                p_j2k->m_specific_param.m_encoder.m_header_tile_data = new_header_tile_data;
+                p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = l_code_size;
+        }
+
+        l_current_data = p_j2k->m_specific_param.m_encoder.m_header_tile_data;
+
+        opj_write_bytes(l_current_data,J2K_MS_COD,2);           /* COD */
+        l_current_data += 2;
+
+        opj_write_bytes(l_current_data,l_code_size-2,2);        /* L_COD */
+        l_current_data += 2;
+
+        opj_write_bytes(l_current_data,l_tcp->csty,1);          /* Scod */
+        ++l_current_data;
+
+        opj_write_bytes(l_current_data,l_tcp->prg,1);           /* SGcod (A) */
+        ++l_current_data;
+
+        opj_write_bytes(l_current_data,l_tcp->numlayers,2);     /* SGcod (B) */
+        l_current_data+=2;
+
+        opj_write_bytes(l_current_data,l_tcp->mct,1);           /* SGcod (C) */
+        ++l_current_data;
+
+        l_remaining_size -= 9;
+
+        if (! opj_j2k_write_SPCod_SPCoc(p_j2k,p_j2k->m_current_tile_number,0,l_current_data,&l_remaining_size,p_manager)) {
+                opj_event_msg(p_manager, EVT_ERROR, "Error writing COD marker\n");
+                return OPJ_FALSE;
+        }
+
+        if (l_remaining_size != 0) {
+                opj_event_msg(p_manager, EVT_ERROR, "Error writing COD marker\n");
+                return OPJ_FALSE;
+        }
+
+        if (opj_stream_write_data(p_stream,p_j2k->m_specific_param.m_encoder.m_header_tile_data,l_code_size,p_manager) != l_code_size) {
+                return OPJ_FALSE;
+        }
+
+        return OPJ_TRUE;
+}
+
+/**
+ * Reads a COD marker (Coding Styke defaults)
+ * @param       p_header_data   the data contained in the COD box.
+ * @param       p_j2k                   the jpeg2000 codec.
+ * @param       p_header_size   the size of the data contained in the COD marker.
+ * @param       p_manager               the user event manager.
+*/
+static OPJ_BOOL opj_j2k_read_cod (  opj_j2k_t *p_j2k,
+                                    OPJ_BYTE * p_header_data,
+                                    OPJ_UINT32 p_header_size,
+                                    opj_event_mgr_t * p_manager
+                                    )
+{
+        /* loop */
+        OPJ_UINT32 i;
+        OPJ_UINT32 l_tmp;
+        opj_cp_t *l_cp = 00;
+        opj_tcp_t *l_tcp = 00;
+        opj_image_t *l_image = 00;
+
+        /* preconditions */
+        assert(p_header_data != 00);
+        assert(p_j2k != 00);
+        assert(p_manager != 00);
+
+        l_image = p_j2k->m_private_image;
+        l_cp = &(p_j2k->m_cp);
+
+        /* If we are in the first tile-part header of the current tile */
+        l_tcp = (p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_TPH) ?
+                                &l_cp->tcps[p_j2k->m_current_tile_number] :
+                                p_j2k->m_specific_param.m_decoder.m_default_tcp;
+
+        /* Make sure room is sufficient */
+        if (p_header_size < 5) {
+                opj_event_msg(p_manager, EVT_ERROR, "Error reading COD marker\n");
+                return OPJ_FALSE;
+        }
+
+        opj_read_bytes(p_header_data,&l_tcp->csty,1);           /* Scod */
+        ++p_header_data;
+        opj_read_bytes(p_header_data,&l_tmp,1);                         /* SGcod (A) */
+        ++p_header_data;
+        l_tcp->prg = (OPJ_PROG_ORDER) l_tmp;
+        opj_read_bytes(p_header_data,&l_tcp->numlayers,2);      /* SGcod (B) */
+        p_header_data+=2;
+
+        /* If user didn't set a number layer to decode take the max specify in the codestream. */
+        if      (l_cp->m_specific_param.m_dec.m_layer) {
+                l_tcp->num_layers_to_decode = l_cp->m_specific_param.m_dec.m_layer;
+        }
+        else {
+                l_tcp->num_layers_to_decode = l_tcp->numlayers;
+        }
+
+        opj_read_bytes(p_header_data,&l_tcp->mct,1);