Defines three new functions
[openjpeg.git] / src / lib / openjp2 / j2k.c
index 6730154704924bb2068f89544699e42721f25a24..bdc56959f05aa70ad61b58d269be270577160fc0 100644 (file)
@@ -718,28 +718,28 @@ static OPJ_BOOL opj_j2k_read_plt (  opj_j2k_t *p_j2k,
                                     OPJ_UINT32 p_header_size,
                                     opj_event_mgr_t * p_manager );
 
-#if 0
 /**
- * Reads a PPM marker (Packed packet headers, main header)
+ * Reads a PPM marker (Packed 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 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 );
+static OPJ_BOOL opj_j2k_read_ppm (
+                                                                                                                                                opj_j2k_t *p_j2k,
+                                                                                                                                                OPJ_BYTE * p_header_data,
+                                                                                                                                                OPJ_UINT32 p_header_size,
+                                                                                                                                                opj_event_mgr_t * p_manager );
+
+/**
+ * Merges all PPM markers read (Packed headers, main header)
+ *
+ * @param       p_cp      main coding parameters.
+ * @param       p_manager the user event manager.
+ */
+static OPJ_BOOL opj_j2k_merge_ppm ( opj_cp_t *p_cp, opj_event_mgr_t * p_manager );
 
 /**
  * Reads a PPT marker (Packed packet headers, tile-part header)
@@ -753,6 +753,17 @@ 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 );
+
+/**
+ * Merges all PPT markers read (Packed headers, tile-part header)
+ *
+ * @param       p_tcp   the tile.
+ * @param       p_manager               the user event manager.
+ */
+static OPJ_BOOL opj_j2k_merge_ppt (  opj_tcp_t *p_tcp,
+                                                                                                                                          opj_event_mgr_t * p_manager );
+
+
 /**
  * Writes the TLM marker (Tile Length Marker)
  *
@@ -841,7 +852,7 @@ 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 )
+static 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;
@@ -1221,7 +1232,7 @@ typedef struct j2k_prog_order{
         char str_prog[5];
 }j2k_prog_order_t;
 
-j2k_prog_order_t j2k_prog_order_list[] = {
+static j2k_prog_order_t j2k_prog_order_list[] = {
         {OPJ_CPRL, "CPRL"},
         {OPJ_LRCP, "LRCP"},
         {OPJ_PCRL, "PCRL"},
@@ -1243,7 +1254,7 @@ static const OPJ_UINT32 MCT_ELEMENT_SIZE [] =
 
 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 [] =
+static const opj_j2k_mct_function j2k_mct_read_functions_to_float [] =
 {
         opj_j2k_read_int16_to_float,
         opj_j2k_read_int32_to_float,
@@ -1251,7 +1262,7 @@ const opj_j2k_mct_function j2k_mct_read_functions_to_float [] =
         opj_j2k_read_float64_to_float
 };
 
-const opj_j2k_mct_function j2k_mct_read_functions_to_int32 [] =
+static const opj_j2k_mct_function j2k_mct_read_functions_to_int32 [] =
 {
         opj_j2k_read_int16_to_int32,
         opj_j2k_read_int32_to_int32,
@@ -1259,7 +1270,7 @@ const opj_j2k_mct_function j2k_mct_read_functions_to_int32 [] =
         opj_j2k_read_float64_to_int32
 };
 
-const opj_j2k_mct_function j2k_mct_write_functions_from_float [] =
+static const opj_j2k_mct_function j2k_mct_write_functions_from_float [] =
 {
         opj_j2k_write_float_to_int16,
         opj_j2k_write_float_to_int32,
@@ -1281,7 +1292,7 @@ typedef struct opj_dec_memory_marker_handler
 }
 opj_dec_memory_marker_handler_t;
 
-const opj_dec_memory_marker_handler_t j2k_memory_marker_handler_tab [] =
+static 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},
@@ -1294,7 +1305,7 @@ const opj_dec_memory_marker_handler_t j2k_memory_marker_handler_tab [] =
   {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_PPM, J2K_STATE_MH, opj_j2k_read_ppm},
   {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},
@@ -1318,7 +1329,7 @@ const opj_dec_memory_marker_handler_t j2k_memory_marker_handler_tab [] =
   {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)
+static 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;
@@ -1334,7 +1345,7 @@ void  opj_j2k_read_int16_to_float (const void * p_src_data, void * p_dest_data,
         }
 }
 
-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_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;
@@ -1350,7 +1361,7 @@ void  opj_j2k_read_int32_to_float (const void * p_src_data, void * p_dest_data,
         }
 }
 
-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_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;
@@ -1366,7 +1377,7 @@ void  opj_j2k_read_float32_to_float (const void * p_src_data, void * p_dest_data
         }
 }
 
-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_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;
@@ -1382,7 +1393,7 @@ void  opj_j2k_read_float64_to_float (const void * p_src_data, void * p_dest_data
         }
 }
 
-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_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;
@@ -1398,7 +1409,7 @@ void  opj_j2k_read_int16_to_int32 (const void * p_src_data, void * p_dest_data,
         }
 }
 
-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_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;
@@ -1414,7 +1425,7 @@ void  opj_j2k_read_int32_to_int32 (const void * p_src_data, void * p_dest_data,
         }
 }
 
-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_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;
@@ -1430,7 +1441,7 @@ void  opj_j2k_read_float32_to_int32 (const void * p_src_data, void * p_dest_data
         }
 }
 
-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_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;
@@ -1446,7 +1457,7 @@ void  opj_j2k_read_float64_to_int32 (const void * p_src_data, void * p_dest_data
         }
 }
 
-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_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;
@@ -1462,7 +1473,7 @@ void  opj_j2k_write_float_to_int16 (const void * p_src_data, void * p_dest_data,
         }
 }
 
-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_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;
@@ -1478,7 +1489,7 @@ void opj_j2k_write_float_to_int32 (const void * p_src_data, void * p_dest_data,
         }
 }
 
-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_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;
@@ -1494,7 +1505,7 @@ void  opj_j2k_write_float_to_float (const void * p_src_data, void * p_dest_data,
         }
 }
 
-void  opj_j2k_write_float_to_float64 (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)
 {
         OPJ_BYTE * l_dest_data = (OPJ_BYTE *) p_dest_data;
         OPJ_FLOAT32 * l_src_data = (OPJ_FLOAT32 *) p_src_data;
@@ -1520,7 +1531,7 @@ char *opj_j2k_convert_progression_order(OPJ_PROG_ORDER prg_order){
         return po->str_prog;
 }
 
-OPJ_BOOL opj_j2k_check_poc_val( const opj_poc_t *p_pocs,
+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 p_num_comps,
@@ -1624,7 +1635,7 @@ OPJ_BOOL opj_j2k_check_poc_val( const opj_poc_t *p_pocs,
 
 /* ----------------------------------------------------------------------- */
 
-OPJ_UINT32 opj_j2k_get_num_tp(opj_cp_t *cp, OPJ_UINT32 pino, OPJ_UINT32 tileno)
+static 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;
@@ -1682,7 +1693,7 @@ OPJ_UINT32 opj_j2k_get_num_tp(opj_cp_t *cp, OPJ_UINT32 pino, OPJ_UINT32 tileno)
         return tpnum;
 }
 
-OPJ_BOOL opj_j2k_calculate_tp(  opj_j2k_t *p_j2k,
+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,
@@ -1760,7 +1771,7 @@ OPJ_BOOL opj_j2k_calculate_tp(  opj_j2k_t *p_j2k,
         return OPJ_TRUE;
 }
 
-OPJ_BOOL opj_j2k_write_soc(     opj_j2k_t *p_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 )
 {
@@ -1838,7 +1849,7 @@ static OPJ_BOOL opj_j2k_read_soc(   opj_j2k_t *p_j2k,
         return OPJ_TRUE;
 }
 
-OPJ_BOOL opj_j2k_write_siz(     opj_j2k_t *p_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 )
 {
@@ -2031,14 +2042,8 @@ static OPJ_BOOL opj_j2k_read_siz(opj_j2k_t *p_j2k,
         }
 
         /* testcase issue427-illegal-tile-offset.jp2 */
-        l_tx1 = l_cp->tx0 + l_cp->tdx;
-        if (l_tx1 < l_cp->tx0) { /* manage overflow */
-                l_tx1 = 0xFFFFFFFFU;
-        }
-        l_ty1 = l_cp->ty0 + l_cp->tdy;
-        if (l_ty1 < l_cp->ty0) { /* manage overflow */
-                l_ty1 = 0xFFFFFFFFU;
-        }
+        l_tx1 = opj_uint_adds(l_cp->tx0, l_cp->tdx); /* manage overflow */
+        l_ty1 = opj_uint_adds(l_cp->ty0, l_cp->tdy); /* manage overflow */
         if ((l_cp->tx0 > l_image->x0) || (l_cp->ty0 > l_image->y0) || (l_tx1 <= l_image->x0) || (l_ty1 <= l_image->y0) ) {
                 opj_event_msg(p_manager, EVT_ERROR, "Error with SIZ marker: illegal tile offset\n");
                 return OPJ_FALSE;
@@ -2286,7 +2291,7 @@ static OPJ_BOOL opj_j2k_read_siz(opj_j2k_t *p_j2k,
         return OPJ_TRUE;
 }
 
-OPJ_BOOL opj_j2k_write_com(     opj_j2k_t *p_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
                             )
@@ -2360,7 +2365,7 @@ static OPJ_BOOL opj_j2k_read_com (  opj_j2k_t *p_j2k,
         return OPJ_TRUE;
 }
 
-OPJ_BOOL opj_j2k_write_cod(     opj_j2k_t *p_j2k,
+static OPJ_BOOL opj_j2k_write_cod(     opj_j2k_t *p_j2k,
                                                         opj_stream_private_t *p_stream,
                                                         opj_event_mgr_t * p_manager )
 {
@@ -2546,7 +2551,7 @@ static OPJ_BOOL opj_j2k_read_cod (  opj_j2k_t *p_j2k,
 }
 
 #if 0
-OPJ_BOOL opj_j2k_write_coc( opj_j2k_t *p_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 )
@@ -2593,7 +2598,7 @@ OPJ_BOOL opj_j2k_write_coc( opj_j2k_t *p_j2k,
 #endif
 
 #if 0
-void opj_j2k_write_coc_in_memory(   opj_j2k_t *p_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,
@@ -2639,7 +2644,7 @@ void opj_j2k_write_coc_in_memory(   opj_j2k_t *p_j2k,
 }
 #endif
 
-OPJ_UINT32 opj_j2k_get_max_coc_size(opj_j2k_t *p_j2k)
+static OPJ_UINT32 opj_j2k_get_max_coc_size(opj_j2k_t *p_j2k)
 {
         OPJ_UINT32 i,j;
         OPJ_UINT32 l_nb_comp;
@@ -2721,7 +2726,7 @@ static OPJ_BOOL opj_j2k_read_coc (  opj_j2k_t *p_j2k,
         return OPJ_TRUE;
 }
 
-OPJ_BOOL opj_j2k_write_qcd(     opj_j2k_t *p_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
                             )
@@ -2812,7 +2817,7 @@ static OPJ_BOOL opj_j2k_read_qcd (  opj_j2k_t *p_j2k,
 }
 
 #if 0
-OPJ_BOOL opj_j2k_write_qcc(     opj_j2k_t *p_j2k,
+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
@@ -2853,7 +2858,7 @@ OPJ_BOOL opj_j2k_write_qcc(     opj_j2k_t *p_j2k,
 #endif
 
 #if 0
-void opj_j2k_write_qcc_in_memory(   opj_j2k_t *p_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,
@@ -2903,7 +2908,7 @@ void opj_j2k_write_qcc_in_memory(   opj_j2k_t *p_j2k,
 }
 #endif
 
-OPJ_UINT32 opj_j2k_get_max_qcc_size (opj_j2k_t *p_j2k)
+static OPJ_UINT32 opj_j2k_get_max_qcc_size (opj_j2k_t *p_j2k)
 {
         return opj_j2k_get_max_coc_size(p_j2k);
 }
@@ -2995,7 +3000,7 @@ static OPJ_BOOL opj_j2k_read_qcc(   opj_j2k_t *p_j2k,
         return OPJ_TRUE;
 }
 
-OPJ_BOOL opj_j2k_write_poc(     opj_j2k_t *p_j2k,
+static OPJ_BOOL opj_j2k_write_poc(     opj_j2k_t *p_j2k,
                                                         opj_stream_private_t *p_stream,
                                                         opj_event_mgr_t * p_manager
                             )
@@ -3046,7 +3051,7 @@ OPJ_BOOL opj_j2k_write_poc(     opj_j2k_t *p_j2k,
         return OPJ_TRUE;
 }
 
-void opj_j2k_write_poc_in_memory(   opj_j2k_t *p_j2k,
+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
@@ -3121,7 +3126,7 @@ void opj_j2k_write_poc_in_memory(   opj_j2k_t *p_j2k,
         *p_data_written = l_poc_size;
 }
 
-OPJ_UINT32 opj_j2k_get_max_poc_size(opj_j2k_t *p_j2k)
+static OPJ_UINT32 opj_j2k_get_max_poc_size(opj_j2k_t *p_j2k)
 {
         opj_tcp_t * l_tcp = 00;
         OPJ_UINT32 l_nb_tiles = 0;
@@ -3141,7 +3146,7 @@ OPJ_UINT32 opj_j2k_get_max_poc_size(opj_j2k_t *p_j2k)
         return 4 + 9 * l_max_poc;
 }
 
-OPJ_UINT32 opj_j2k_get_max_toc_size (opj_j2k_t *p_j2k)
+static OPJ_UINT32 opj_j2k_get_max_toc_size (opj_j2k_t *p_j2k)
 {
         OPJ_UINT32 i;
         OPJ_UINT32 l_nb_tiles;
@@ -3160,7 +3165,7 @@ OPJ_UINT32 opj_j2k_get_max_toc_size (opj_j2k_t *p_j2k)
         return 12 * l_max;
 }
 
-OPJ_UINT32 opj_j2k_get_specific_header_sizes(opj_j2k_t *p_j2k)
+static OPJ_UINT32 opj_j2k_get_specific_header_sizes(opj_j2k_t *p_j2k)
 {
         OPJ_UINT32 l_nb_bytes = 0;
         OPJ_UINT32 l_nb_comps;
@@ -3490,382 +3495,220 @@ static OPJ_BOOL opj_j2k_read_plt (  opj_j2k_t *p_j2k,
         return OPJ_TRUE;
 }
 
-#if 0
-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
-                                        )
-{
-
-        opj_cp_t *l_cp = 00;
-        OPJ_UINT32 l_remaining_data, l_Z_ppm, l_N_ppm;
-
-        /* preconditions */
-        assert(p_header_data != 00);
-        assert(p_j2k != 00);
-        assert(p_manager != 00);
-
-        if (p_header_size < 1) {
-                opj_event_msg(p_manager, EVT_ERROR, "Error reading PPM marker\n");
-                return OPJ_FALSE;
-        }
-
-        l_cp = &(p_j2k->m_cp);
-        l_cp->ppm = 1;
-
-        opj_read_bytes(p_header_data,&l_Z_ppm,1);               /* Z_ppm */
-        ++p_header_data;
-        --p_header_size;
-
-        /* First PPM marker */
-        if (l_Z_ppm == 0) {
-                if (p_header_size < 4) {
-                        opj_event_msg(p_manager, EVT_ERROR, "Error reading PPM marker\n");
-                        return OPJ_FALSE;
-                }
-
-                opj_read_bytes(p_header_data,&l_N_ppm,4);               /* N_ppm */
-                p_header_data+=4;
-                p_header_size-=4;
-
-                /* First PPM marker: Initialization */
-                l_cp->ppm_len = l_N_ppm;
-                l_cp->ppm_data_size = 0;
-
-                l_cp->ppm_buffer = (OPJ_BYTE *) opj_malloc(l_cp->ppm_len);
-                if (l_cp->ppm_buffer == 00) {
-                        opj_event_msg(p_manager, EVT_ERROR, "Not enough memory reading ppm marker\n");
-                        return OPJ_FALSE;
-                }
-                memset(l_cp->ppm_buffer,0,l_cp->ppm_len);
-
-                l_cp->ppm_data = l_cp->ppm_buffer;
-        }
-
-        while (1) {
-                if (l_cp->ppm_data_size == l_cp->ppm_len) {
-                        if (p_header_size >= 4) {
-                                /* read a N_ppm */
-                                opj_read_bytes(p_header_data,&l_N_ppm,4);               /* N_ppm */
-                                p_header_data+=4;
-                                p_header_size-=4;
-                                l_cp->ppm_len += l_N_ppm ;
-
-                                OPJ_BYTE *new_ppm_buffer = (OPJ_BYTE *) opj_realloc(l_cp->ppm_buffer, l_cp->ppm_len);
-                                if (! new_ppm_buffer) {
-                                        opj_free(l_cp->ppm_buffer);
-                                        l_cp->ppm_buffer = NULL;
-                                        l_cp->ppm_len = 0;
-                                        l_cp->ppm_data = NULL;
-                                        opj_event_msg(p_manager, EVT_ERROR, "Not enough memory reading ppm marker\n");
-                                        return OPJ_FALSE;
-                                }
-                                l_cp->ppm_buffer = new_ppm_buffer;
-                                memset(l_cp->ppm_buffer+l_cp->ppm_data_size,0,l_N_ppm);
-                                l_cp->ppm_data = l_cp->ppm_buffer;
-                        }
-                        else {
-                                return OPJ_FALSE;
-                        }
-                }
-
-                l_remaining_data = l_cp->ppm_len - l_cp->ppm_data_size;
+/**
+ * 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.
+ */
 
-                if (l_remaining_data <= p_header_size) {
-                        /* we must store less information than available in the packet */
-                        memcpy(l_cp->ppm_buffer + l_cp->ppm_data_size , p_header_data , l_remaining_data);
-                        l_cp->ppm_data_size = l_cp->ppm_len;
-                        p_header_size -= l_remaining_data;
-                        p_header_data += l_remaining_data;
-                }
-                else {
-                        memcpy(l_cp->ppm_buffer + l_cp->ppm_data_size , p_header_data , p_header_size);
-                        l_cp->ppm_data_size += p_header_size;
-                        p_header_data += p_header_size;
-                        p_header_size = 0;
-                        break;
-                }
-        }
+static OPJ_BOOL opj_j2k_read_ppm (
+                                                                                                                                       opj_j2k_t *p_j2k,
+                                                                                                                                       OPJ_BYTE * p_header_data,
+                                                                                                                                       OPJ_UINT32 p_header_size,
+                                                                                                                                       opj_event_mgr_t * p_manager )
+{
+       opj_cp_t *l_cp = 00;
+       OPJ_UINT32 l_Z_ppm;
+       
+       /* preconditions */
+       assert(p_header_data != 00);
+       assert(p_j2k != 00);
+       assert(p_manager != 00);
+       
+       /* We need to have the Z_ppm element + 1 byte of Nppm/Ippm at minimum */
+       if (p_header_size < 2) {
+               opj_event_msg(p_manager, EVT_ERROR, "Error reading PPM marker\n");
+               return OPJ_FALSE;
+       }
+       
+       l_cp = &(p_j2k->m_cp);
+       l_cp->ppm = 1;
+       
+       opj_read_bytes(p_header_data,&l_Z_ppm,1);               /* Z_ppm */
+       ++p_header_data;
+       --p_header_size;
+       
+       /* check allocation needed */
+       if (l_cp->ppm_markers == NULL) { /* first PPM marker */
+               OPJ_UINT32 l_newCount = l_Z_ppm + 1U; /* can't overflow, l_Z_ppm is UINT8 */
+               assert(l_cp->ppm_markers_count == 0U);
+               
+               l_cp->ppm_markers = (opj_ppx *) opj_calloc(l_newCount, sizeof(opj_ppx));
+               if (l_cp->ppm_markers == NULL) {
+                       opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read PPM marker\n");
+                       return OPJ_FALSE;
+               }
+               l_cp->ppm_markers_count = l_newCount;
+       } else if (l_cp->ppm_markers_count <= l_Z_ppm) {
+               OPJ_UINT32 l_newCount = l_Z_ppm + 1U; /* can't overflow, l_Z_ppm is UINT8 */
+               opj_ppx *new_ppm_markers;
+               new_ppm_markers = (opj_ppx *) opj_realloc(l_cp->ppm_markers, l_newCount * sizeof(opj_ppx));
+               if (new_ppm_markers == NULL) {
+                       /* clean up to be done on l_cp destruction */
+                       opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read PPM marker\n");
+                       return OPJ_FALSE;
+               }
+               l_cp->ppm_markers = new_ppm_markers;
+               memset(l_cp->ppm_markers + l_cp->ppm_markers_count, 0, (l_newCount - l_cp->ppm_markers_count) * sizeof(opj_ppx));
+               l_cp->ppm_markers_count = l_newCount;
+       }
+       
+       if (l_cp->ppm_markers[l_Z_ppm].m_data != NULL) {
+               /* clean up to be done on l_cp destruction */
+               opj_event_msg(p_manager, EVT_ERROR, "Zppm %u already read\n", l_Z_ppm);
+               return OPJ_FALSE;
+       }
+       
+       l_cp->ppm_markers[l_Z_ppm].m_data = opj_malloc(p_header_size);
+       if (l_cp->ppm_markers[l_Z_ppm].m_data == NULL) {
+               /* clean up to be done on l_cp destruction */
+               opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read PPM marker\n");
+               return OPJ_FALSE;
+       }
+       l_cp->ppm_markers[l_Z_ppm].m_data_size = p_header_size;
+       memcpy(l_cp->ppm_markers[l_Z_ppm].m_data, p_header_data, p_header_size);
 
-        return OPJ_TRUE;
+       return OPJ_TRUE;
 }
-#endif
 
-OPJ_BOOL j2k_read_ppm_v3 (
-                                                opj_j2k_t *p_j2k,
-                                                OPJ_BYTE * p_header_data,
-                                                OPJ_UINT32 p_header_size,
-                                                struct opj_event_mgr * p_manager
-                                        )
+/**
+ * Merges all PPM markers read (Packed headers, main header)
+ *
+ * @param       p_cp      main coding parameters.
+ * @param       p_manager the user event manager.
+ */
+static OPJ_BOOL opj_j2k_merge_ppm ( opj_cp_t *p_cp, opj_event_mgr_t * p_manager )
 {
-        opj_cp_t *l_cp = 00;
-        OPJ_UINT32 l_remaining_data, l_Z_ppm, l_N_ppm;
-
-        /* preconditions */
-        assert(p_header_data != 00);
-        assert(p_j2k != 00);
-        assert(p_manager != 00);
-
-        /* Minimum size of PPM marker is equal to the size of Zppm element */
-        if (p_header_size < 1) {
-                opj_event_msg(p_manager, EVT_ERROR, "Error reading PPM marker\n");
-                return OPJ_FALSE;
-        }
-
-        l_cp = &(p_j2k->m_cp);
-        l_cp->ppm = 1;
-
-        opj_read_bytes(p_header_data,&l_Z_ppm,1);               /* Z_ppm */
-        ++p_header_data;
-        --p_header_size;
-
-        /* First PPM marker */
-        if (l_Z_ppm == 0) {
-                if (l_cp->ppm_data != NULL) {
-                        opj_event_msg(p_manager, EVT_ERROR, "Zppm O already processed. Found twice.\n");
-                        opj_free(l_cp->ppm_data);
-                        l_cp->ppm_data = NULL;
-                        l_cp->ppm_buffer = NULL;
-                        l_cp->ppm = 0; /* do not use PPM */
-                        return OPJ_FALSE;
-                }
-                /* We need now at least the Nppm^0 element */
-                if (p_header_size < 4) {
-                        opj_event_msg(p_manager, EVT_ERROR, "Error reading PPM marker\n");
-                        return OPJ_FALSE;
-                }
-
-                opj_read_bytes(p_header_data,&l_N_ppm,4);               /* First N_ppm */
-                p_header_data+=4;
-                p_header_size-=4;
-
-                /* sanity check: how much bytes is left for Ippm */
-                if( p_header_size < l_N_ppm )
-                  {
-                  opj_event_msg(p_manager, EVT_ERROR, "Not enough bytes (%u) to hold Ippm series (%u), Index (%d)\n", p_header_size, l_N_ppm, l_Z_ppm );
-                  opj_free(l_cp->ppm_data);
-                  l_cp->ppm_data = NULL;
-                  l_cp->ppm_buffer = NULL;
-                  l_cp->ppm = 0; /* do not use PPM */
-                  return OPJ_FALSE;
-                  }
-
-                /* First PPM marker: Initialization */
-                l_cp->ppm_len = l_N_ppm;
-                l_cp->ppm_data_read = 0;
-
-                l_cp->ppm_data = (OPJ_BYTE *) opj_calloc(1,l_cp->ppm_len);
-                l_cp->ppm_buffer = l_cp->ppm_data;
-                if (l_cp->ppm_data == 00) {
-                        opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read ppm marker\n");
-                        return OPJ_FALSE;
-                }
-
-                l_cp->ppm_data_current = l_cp->ppm_data;
-
-                /*l_cp->ppm_data = l_cp->ppm_buffer;*/
-        }
-        else {
-                if (p_header_size < 4) {
-                        opj_event_msg(p_manager, EVT_WARNING, "Empty PPM marker\n");
-                        return OPJ_TRUE;
-                }
-                else {
-                        /* Uncompleted Ippm series in the previous PPM marker?*/
-                        if (l_cp->ppm_data_read < l_cp->ppm_len) {
-                                /* Get the place where add the remaining Ippm series*/
-                                l_cp->ppm_data_current = &(l_cp->ppm_data[l_cp->ppm_data_read]);
-                                l_N_ppm = l_cp->ppm_len - l_cp->ppm_data_read;
-                        }
-                        else {
-                                OPJ_BYTE *new_ppm_data;
-                                opj_read_bytes(p_header_data,&l_N_ppm,4);               /* First N_ppm */
-                                p_header_data+=4;
-                                p_header_size-=4;
-
-                                /* sanity check: how much bytes is left for Ippm */
-                                if( p_header_size < l_N_ppm )
-                                  {
-                                  opj_event_msg(p_manager, EVT_ERROR, "Not enough bytes (%u) to hold Ippm series (%u), Index (%d)\n", p_header_size, l_N_ppm, l_Z_ppm );
-                                  opj_free(l_cp->ppm_data);
-                                  l_cp->ppm_data = NULL;
-                                  l_cp->ppm_buffer = NULL;
-                                  l_cp->ppm = 0; /* do not use PPM */
-                                  return OPJ_FALSE;
-                                  }
-                                /* Increase the size of ppm_data to add the new Ippm series*/
-                                assert(l_cp->ppm_data == l_cp->ppm_buffer && "We need ppm_data and ppm_buffer to be the same when reallocating");
-                                new_ppm_data = (OPJ_BYTE *) opj_realloc(l_cp->ppm_data, l_cp->ppm_len + l_N_ppm);
-                                if (! new_ppm_data) {
-                                        opj_free(l_cp->ppm_data);
-                                        l_cp->ppm_data = NULL;
-                                        l_cp->ppm_buffer = NULL;  /* TODO: no need for a new local variable: ppm_buffer and ppm_data are enough */
-                                        l_cp->ppm_len = 0;
-                                        opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to increase the size of ppm_data to add the new Ippm series\n");
-                                        return OPJ_FALSE;
-                                }
-                                l_cp->ppm_data = new_ppm_data;
-                                l_cp->ppm_buffer = l_cp->ppm_data;
-
-                                /* Keep the position of the place where concatenate the new series*/
-                                l_cp->ppm_data_current = &(l_cp->ppm_data[l_cp->ppm_len]);
-                                l_cp->ppm_len += l_N_ppm;
-                        }
-                }
-        }
-
-        l_remaining_data = p_header_size;
-
-        while (l_remaining_data >= l_N_ppm) {
-                /* read a complete Ippm series*/
-                memcpy(l_cp->ppm_data_current, p_header_data, l_N_ppm);
-                p_header_size -= l_N_ppm;
-                p_header_data += l_N_ppm;
-
-                l_cp->ppm_data_read += l_N_ppm; /* Increase the number of data read*/
-
-                if (p_header_size)
-                {
-                        if (p_header_size < 4) {
-                                opj_free(l_cp->ppm_data);
-                                l_cp->ppm_data = NULL;
-                                l_cp->ppm_buffer = NULL;  /* TODO: no need for a new local variable: ppm_buffer and ppm_data are enough */
-                                l_cp->ppm_len = 0;
-                                l_cp->ppm = 0;
-                                opj_event_msg(p_manager, EVT_ERROR, "Error reading PPM marker\n");
-                                return OPJ_FALSE;
-                        }
-                        opj_read_bytes(p_header_data,&l_N_ppm,4);               /* N_ppm^i */
-                        p_header_data+=4;
-                        p_header_size-=4;
-                }
-                else {
-                        l_remaining_data = p_header_size;
-                        break;
-                }
-
-                l_remaining_data = p_header_size;
-
-                /* Next Ippm series is a complete series ?*/
-                if (l_remaining_data >= l_N_ppm) {
-                        OPJ_BYTE *new_ppm_data;
-                        /* Increase the size of ppm_data to add the new Ippm series*/
-                        assert(l_cp->ppm_data == l_cp->ppm_buffer && "We need ppm_data and ppm_buffer to be the same when reallocating");
-                        /* Overflow check */
-                        if ((l_cp->ppm_len + l_N_ppm) < l_N_ppm) {
-                                opj_free(l_cp->ppm_data);
-                                l_cp->ppm_data = NULL;
-                                l_cp->ppm_buffer = NULL;  /* TODO: no need for a new local variable: ppm_buffer and ppm_data are enough */
-                                l_cp->ppm_len = 0;
-                                opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to increase the size of ppm_data to add the new (complete) Ippm series\n");
-                                return OPJ_FALSE;
-                        }
-                        new_ppm_data = (OPJ_BYTE *) opj_realloc(l_cp->ppm_data, l_cp->ppm_len + l_N_ppm);
-                        if (! new_ppm_data) {
-                                opj_free(l_cp->ppm_data);
-                                l_cp->ppm_data = NULL;
-                                l_cp->ppm_buffer = NULL;  /* TODO: no need for a new local variable: ppm_buffer and ppm_data are enough */
-                                l_cp->ppm_len = 0;
-                                opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to increase the size of ppm_data to add the new (complete) Ippm series\n");
-                                return OPJ_FALSE;
-                        }
-                        l_cp->ppm_data = new_ppm_data;
-                        l_cp->ppm_buffer = l_cp->ppm_data;
-
-                        /* Keep the position of the place where concatenate the new series */
-                        l_cp->ppm_data_current = &(l_cp->ppm_data[l_cp->ppm_len]);
-                        l_cp->ppm_len += l_N_ppm;
-                }
-
-        }
-
-        /* Need to read an incomplete Ippm series*/
-        if (l_remaining_data) {
-                OPJ_BYTE *new_ppm_data;
-                assert(l_cp->ppm_data == l_cp->ppm_buffer && "We need ppm_data and ppm_buffer to be the same when reallocating");
-
-                /* Overflow check */
-                if ((l_cp->ppm_len + l_N_ppm) < l_N_ppm) {
-                        opj_free(l_cp->ppm_data);
-                        l_cp->ppm_data = NULL;
-                        l_cp->ppm_buffer = NULL;  /* TODO: no need for a new local variable: ppm_buffer and ppm_data are enough */
-                        l_cp->ppm_len = 0;
-                        opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to increase the size of ppm_data to add the new (complete) Ippm series\n");
-                        return OPJ_FALSE;
-                }
-                new_ppm_data = (OPJ_BYTE *) opj_realloc(l_cp->ppm_data, l_cp->ppm_len + l_N_ppm);
-                if (! new_ppm_data) {
-                        opj_free(l_cp->ppm_data);
-                        l_cp->ppm_data = NULL;
-                        l_cp->ppm_buffer = NULL;  /* TODO: no need for a new local variable: ppm_buffer and ppm_data are enough */
-                        l_cp->ppm_len = 0;
-                        opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to increase the size of ppm_data to add the new (incomplete) Ippm series\n");
-                        return OPJ_FALSE;
-                }
-                l_cp->ppm_data = new_ppm_data;
-                l_cp->ppm_buffer = l_cp->ppm_data;
-
-                /* Keep the position of the place where concatenate the new series*/
-                l_cp->ppm_data_current = &(l_cp->ppm_data[l_cp->ppm_len]);
-                l_cp->ppm_len += l_N_ppm;
-
-                /* Read incomplete Ippm series*/
-                memcpy(l_cp->ppm_data_current, p_header_data, l_remaining_data);
-                p_header_size -= l_remaining_data;
-                p_header_data += l_remaining_data;
-
-                l_cp->ppm_data_read += l_remaining_data; /* Increase the number of data read*/
-        }
-
-#ifdef CLEAN_MSD
-
-                if (l_cp->ppm_data_size == l_cp->ppm_len) {
-                        if (p_header_size >= 4) {
-                                /* read a N_ppm*/
-                                opj_read_bytes(p_header_data,&l_N_ppm,4);               /* N_ppm */
-                                p_header_data+=4;
-                                p_header_size-=4;
-                                l_cp->ppm_len += l_N_ppm ;
-
-                                OPJ_BYTE *new_ppm_buffer = (OPJ_BYTE *) opj_realloc(l_cp->ppm_buffer, l_cp->ppm_len);
-                                if (! new_ppm_buffer) {
-                                        opj_free(l_cp->ppm_buffer);
-                                        l_cp->ppm_buffer = NULL;
-                                        l_cp->ppm_len = 0;
-                                        opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read ppm marker\n");
-                                        return OPJ_FALSE;
-                                }
-                                l_cp->ppm_buffer = new_ppm_buffer;
-                                memset(l_cp->ppm_buffer+l_cp->ppm_data_size,0,l_N_ppm);
-
-                                l_cp->ppm_data = l_cp->ppm_buffer;
-                        }
-                        else {
-                                return OPJ_FALSE;
-                        }
-                }
-
-                l_remaining_data = l_cp->ppm_len - l_cp->ppm_data_size;
+       OPJ_UINT32 i, l_ppm_data_size, l_N_ppm_remaining;
+       
+       /* preconditions */
+       assert(p_cp != 00);
+       assert(p_manager != 00);
+       assert(p_cp->ppm_buffer == NULL);
+       
+       if (p_cp->ppm == 0U) {
+               return OPJ_TRUE;
+       }
+       
+       l_ppm_data_size = 0U;
+       l_N_ppm_remaining = 0U;
+       for (i = 0U; i < p_cp->ppm_markers_count; ++i) {
+               if (p_cp->ppm_markers[i].m_data != NULL) { /* standard doesn't seem to require contiguous Zppm */
+                       OPJ_UINT32 l_N_ppm;
+                       OPJ_UINT32 l_data_size = p_cp->ppm_markers[i].m_data_size;
+                       const OPJ_BYTE* l_data = p_cp->ppm_markers[i].m_data;
+                       
+                       if (l_N_ppm_remaining >= l_data_size) {
+                               l_N_ppm_remaining -= l_data_size;
+                               l_data_size = 0U;
+                       } else {
+                               l_data += l_N_ppm_remaining;
+                               l_data_size -= l_N_ppm_remaining;
+                               l_N_ppm_remaining = 0U;
+                       }
+                       
+                       if (l_data_size > 0U) {
+                               do
+                               {
+                                       /* read Nppm */
+                                       if (l_data_size < 4U) {
+                                               /* clean up to be done on l_cp destruction */
+                                               opj_event_msg(p_manager, EVT_ERROR, "Not enough bytes to read Nppm\n");
+                                               return OPJ_FALSE;
+                                       }
+                                       opj_read_bytes(l_data, &l_N_ppm, 4);
+                                       l_data+=4;
+                                       l_data_size-=4;
+                                       l_ppm_data_size += l_N_ppm; /* can't overflow, max 256 markers of max 65536 bytes, that is when PPM markers are not corrupted which is checked elsewhere */
+                                       
+                                       if (l_data_size >= l_N_ppm) {
+                                               l_data_size -= l_N_ppm;
+                                               l_data += l_N_ppm;
+                                       } else {
+                                               l_N_ppm_remaining = l_N_ppm - l_data_size;
+                                               l_data_size = 0U;
+                                       }
+                               } while (l_data_size > 0U);
+                       }
+               }
+       }
+       
+       if (l_N_ppm_remaining != 0U) {
+               /* clean up to be done on l_cp destruction */
+               opj_event_msg(p_manager, EVT_ERROR, "Corrupted PPM markers\n");
+               return OPJ_FALSE;
+       }
+       
+       p_cp->ppm_buffer = (OPJ_BYTE *) opj_malloc(l_ppm_data_size);
+       if (p_cp->ppm_buffer == 00) {
+               opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read PPM marker\n");
+               return OPJ_FALSE;
+       }
+       p_cp->ppm_len = l_ppm_data_size;
+       l_ppm_data_size = 0U;
+       l_N_ppm_remaining = 0U;
+       for (i = 0U; i < p_cp->ppm_markers_count; ++i) {
+               if (p_cp->ppm_markers[i].m_data != NULL) { /* standard doesn't seem to require contiguous Zppm */
+                       OPJ_UINT32 l_N_ppm;
+                       OPJ_UINT32 l_data_size = p_cp->ppm_markers[i].m_data_size;
+                       const OPJ_BYTE* l_data = p_cp->ppm_markers[i].m_data;
+                       
+                       if (l_N_ppm_remaining >= l_data_size) {
+                               memcpy(p_cp->ppm_buffer + l_ppm_data_size, l_data, l_data_size);
+                               l_ppm_data_size += l_data_size;
+                               l_N_ppm_remaining -= l_data_size;
+                               l_data_size = 0U;
+                       } else {
+                               memcpy(p_cp->ppm_buffer + l_ppm_data_size, l_data, l_N_ppm_remaining);
+                               l_ppm_data_size += l_N_ppm_remaining;
+                               l_data += l_N_ppm_remaining;
+                               l_data_size -= l_N_ppm_remaining;
+                               l_N_ppm_remaining = 0U;
+                       }
 
-                if (l_remaining_data <= p_header_size) {
-                        /* we must store less information than available in the packet */
-                        memcpy(l_cp->ppm_buffer + l_cp->ppm_data_size , p_header_data , l_remaining_data);
-                        l_cp->ppm_data_size = l_cp->ppm_len;
-                        p_header_size -= l_remaining_data;
-                        p_header_data += l_remaining_data;
-                }
-                else {
-                        memcpy(l_cp->ppm_buffer + l_cp->ppm_data_size , p_header_data , p_header_size);
-                        l_cp->ppm_data_size += p_header_size;
-                        p_header_data += p_header_size;
-                        p_header_size = 0;
-                        break;
-                }
-        }
-#endif
-        return OPJ_TRUE;
+                       if (l_data_size > 0U) {
+                               do
+                               {
+                                       /* read Nppm */
+                                       if (l_data_size < 4U) {
+                                               /* clean up to be done on l_cp destruction */
+                                               opj_event_msg(p_manager, EVT_ERROR, "Not enough bytes to read Nppm\n");
+                                               return OPJ_FALSE;
+                                       }
+                                       opj_read_bytes(l_data, &l_N_ppm, 4);
+                                       l_data+=4;
+                                       l_data_size-=4;
+                                       
+                                       if (l_data_size >= l_N_ppm) {
+                                               memcpy(p_cp->ppm_buffer + l_ppm_data_size, l_data, l_N_ppm);
+                                               l_ppm_data_size += l_N_ppm;
+                                               l_data_size -= l_N_ppm;
+                                               l_data += l_N_ppm;
+                                       } else {
+                                               memcpy(p_cp->ppm_buffer + l_ppm_data_size, l_data, l_data_size);
+                                               l_ppm_data_size += l_data_size;
+                                               l_N_ppm_remaining = l_N_ppm - l_data_size;
+                                               l_data_size = 0U;
+                                       }
+                               } while (l_data_size > 0U);
+                       }
+                       opj_free(p_cp->ppm_markers[i].m_data);
+                       p_cp->ppm_markers[i].m_data = NULL;
+                       p_cp->ppm_markers[i].m_data_size = 0U;
+               }
+       }
+       
+       p_cp->ppm_data = p_cp->ppm_buffer;
+       p_cp->ppm_data_size = p_cp->ppm_len;
+       
+       p_cp->ppm_markers_count = 0U;
+       opj_free(p_cp->ppm_markers);
+       p_cp->ppm_markers = NULL;
+       
+       return OPJ_TRUE;
 }
 
 /**
@@ -3882,77 +3725,127 @@ static OPJ_BOOL opj_j2k_read_ppt (  opj_j2k_t *p_j2k,
                                     opj_event_mgr_t * p_manager
                                     )
 {
-        opj_cp_t *l_cp = 00;
-        opj_tcp_t *l_tcp = 00;
-        OPJ_UINT32 l_Z_ppt;
+       opj_cp_t *l_cp = 00;
+       opj_tcp_t *l_tcp = 00;
+       OPJ_UINT32 l_Z_ppt;
 
-        /* preconditions */
-        assert(p_header_data != 00);
-        assert(p_j2k != 00);
-        assert(p_manager != 00);
-
-        /* We need to have the Z_ppt element at minimum */
-        if (p_header_size < 1) {
-                opj_event_msg(p_manager, EVT_ERROR, "Error reading PPT marker\n");
-                return OPJ_FALSE;
-        }
-
-        l_cp = &(p_j2k->m_cp);
-        if (l_cp->ppm){
-                opj_event_msg(p_manager, EVT_ERROR, "Error reading PPT marker: packet header have been previously found in the main header (PPM marker).\n");
-                return OPJ_FALSE;
-        }
-
-        l_tcp = &(l_cp->tcps[p_j2k->m_current_tile_number]);
-        l_tcp->ppt = 1;
-
-        opj_read_bytes(p_header_data,&l_Z_ppt,1);               /* Z_ppt */
-        ++p_header_data;
-        --p_header_size;
-
-        /* Allocate buffer to read the packet header */
-        if (l_Z_ppt == 0) {
-                /* First PPT marker */
-                l_tcp->ppt_data_size = 0;
-                l_tcp->ppt_len = p_header_size;
-
-                opj_free(l_tcp->ppt_buffer);
-                l_tcp->ppt_buffer = (OPJ_BYTE *) opj_calloc(l_tcp->ppt_len, sizeof(OPJ_BYTE) );
-                if (l_tcp->ppt_buffer == 00) {
-                        opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read PPT marker\n");
-                        return OPJ_FALSE;
-                }
-                l_tcp->ppt_data = l_tcp->ppt_buffer;
+       /* preconditions */
+       assert(p_header_data != 00);
+       assert(p_j2k != 00);
+       assert(p_manager != 00);
 
-                /* memset(l_tcp->ppt_buffer,0,l_tcp->ppt_len); */
-        }
-        else {
-                OPJ_BYTE *new_ppt_buffer;
-                l_tcp->ppt_len += p_header_size;
-
-                new_ppt_buffer = (OPJ_BYTE *) opj_realloc(l_tcp->ppt_buffer, l_tcp->ppt_len);
-                if (! new_ppt_buffer) {
-                        opj_free(l_tcp->ppt_buffer);
-                        l_tcp->ppt_buffer = NULL;
-                        l_tcp->ppt_len = 0;
-                        opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read PPT marker\n");
-                        return OPJ_FALSE;
-                }
-                l_tcp->ppt_buffer = new_ppt_buffer;
-                l_tcp->ppt_data = l_tcp->ppt_buffer;
+       /* We need to have the Z_ppt element + 1 byte of Ippt at minimum */
+       if (p_header_size < 2) {
+               opj_event_msg(p_manager, EVT_ERROR, "Error reading PPT marker\n");
+               return OPJ_FALSE;
+       }
 
-                memset(l_tcp->ppt_buffer+l_tcp->ppt_data_size,0,p_header_size);
-        }
+       l_cp = &(p_j2k->m_cp);
+       if (l_cp->ppm){
+               opj_event_msg(p_manager, EVT_ERROR, "Error reading PPT marker: packet header have been previously found in the main header (PPM marker).\n");
+               return OPJ_FALSE;
+       }
 
-        /* Read packet header from buffer */
-        memcpy(l_tcp->ppt_buffer+l_tcp->ppt_data_size,p_header_data,p_header_size);
+       l_tcp = &(l_cp->tcps[p_j2k->m_current_tile_number]);
+       l_tcp->ppt = 1;
 
-        l_tcp->ppt_data_size += p_header_size;
+       opj_read_bytes(p_header_data,&l_Z_ppt,1);               /* Z_ppt */
+       ++p_header_data;
+       --p_header_size;
+       
+       /* check allocation needed */
+       if (l_tcp->ppt_markers == NULL) { /* first PPT marker */
+               OPJ_UINT32 l_newCount = l_Z_ppt + 1U; /* can't overflow, l_Z_ppt is UINT8 */
+               assert(l_tcp->ppt_markers_count == 0U);
+               
+               l_tcp->ppt_markers = (opj_ppx *) opj_calloc(l_newCount, sizeof(opj_ppx));
+               if (l_tcp->ppt_markers == NULL) {
+                       opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read PPT marker\n");
+                       return OPJ_FALSE;
+               }
+               l_tcp->ppt_markers_count = l_newCount;
+       } else if (l_tcp->ppt_markers_count <= l_Z_ppt) {
+               OPJ_UINT32 l_newCount = l_Z_ppt + 1U; /* can't overflow, l_Z_ppt is UINT8 */
+               opj_ppx *new_ppt_markers;
+               new_ppt_markers = (opj_ppx *) opj_realloc(l_tcp->ppt_markers, l_newCount * sizeof(opj_ppx));
+               if (new_ppt_markers == NULL) {
+                       /* clean up to be done on l_tcp destruction */
+                       opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read PPT marker\n");
+                       return OPJ_FALSE;
+               }
+               l_tcp->ppt_markers = new_ppt_markers;
+               memset(l_tcp->ppt_markers + l_tcp->ppt_markers_count, 0, (l_newCount - l_tcp->ppt_markers_count) * sizeof(opj_ppx));
+               l_tcp->ppt_markers_count = l_newCount;
+       }
+       
+       if (l_tcp->ppt_markers[l_Z_ppt].m_data != NULL) {
+               /* clean up to be done on l_tcp destruction */
+               opj_event_msg(p_manager, EVT_ERROR, "Zppt %u already read\n", l_Z_ppt);
+               return OPJ_FALSE;
+       }
+       
+       l_tcp->ppt_markers[l_Z_ppt].m_data = opj_malloc(p_header_size);
+       if (l_tcp->ppt_markers[l_Z_ppt].m_data == NULL) {
+               /* clean up to be done on l_tcp destruction */
+               opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read PPT marker\n");
+               return OPJ_FALSE;
+       }
+       l_tcp->ppt_markers[l_Z_ppt].m_data_size = p_header_size;
+       memcpy(l_tcp->ppt_markers[l_Z_ppt].m_data, p_header_data, p_header_size);
+       return OPJ_TRUE;
+}
 
-        return OPJ_TRUE;
+/**
+ * Merges all PPT markers read (Packed packet headers, tile-part header)
+ *
+ * @param       p_tcp   the tile.
+ * @param       p_manager               the user event manager.
+ */
+static OPJ_BOOL opj_j2k_merge_ppt(opj_tcp_t *p_tcp, opj_event_mgr_t * p_manager)
+{
+       OPJ_UINT32 i, l_ppt_data_size;
+       /* preconditions */
+       assert(p_tcp != 00);
+       assert(p_manager != 00);
+       assert(p_tcp->ppt_buffer == NULL);
+       
+       if (p_tcp->ppt == 0U) {
+               return OPJ_TRUE;
+       }
+       
+       l_ppt_data_size = 0U;
+       for (i = 0U; i < p_tcp->ppt_markers_count; ++i) {
+               l_ppt_data_size += p_tcp->ppt_markers[i].m_data_size; /* can't overflow, max 256 markers of max 65536 bytes */
+       }
+       
+       p_tcp->ppt_buffer = (OPJ_BYTE *) opj_malloc(l_ppt_data_size);
+       if (p_tcp->ppt_buffer == 00) {
+               opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read PPT marker\n");
+               return OPJ_FALSE;
+       }
+       p_tcp->ppt_len = l_ppt_data_size;
+       l_ppt_data_size = 0U;
+       for (i = 0U; i < p_tcp->ppt_markers_count; ++i) {
+               if (p_tcp->ppt_markers[i].m_data != NULL) { /* standard doesn't seem to require contiguous Zppt */
+                       memcpy(p_tcp->ppt_buffer + l_ppt_data_size, p_tcp->ppt_markers[i].m_data, p_tcp->ppt_markers[i].m_data_size);
+                       l_ppt_data_size += p_tcp->ppt_markers[i].m_data_size; /* can't overflow, max 256 markers of max 65536 bytes */
+                       
+                       opj_free(p_tcp->ppt_markers[i].m_data);
+                       p_tcp->ppt_markers[i].m_data = NULL;
+                       p_tcp->ppt_markers[i].m_data_size = 0U;
+               }
+       }
+       
+       p_tcp->ppt_markers_count = 0U;
+       opj_free(p_tcp->ppt_markers);
+       p_tcp->ppt_markers = NULL;
+       
+       p_tcp->ppt_data = p_tcp->ppt_buffer;
+       p_tcp->ppt_data_size = p_tcp->ppt_len;
+       return OPJ_TRUE;
 }
 
-OPJ_BOOL opj_j2k_write_tlm(     opj_j2k_t *p_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
                             )
@@ -4006,7 +3899,7 @@ OPJ_BOOL opj_j2k_write_tlm(     opj_j2k_t *p_j2k,
         return OPJ_TRUE;
 }
 
-OPJ_BOOL opj_j2k_write_sot(     opj_j2k_t *p_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,
@@ -4079,7 +3972,7 @@ static OPJ_BOOL opj_j2k_get_sot_values(OPJ_BYTE *  p_header_data,
        return OPJ_TRUE;
 }
 
-OPJ_BOOL opj_j2k_read_sot ( opj_j2k_t *p_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 )
@@ -4336,7 +4229,7 @@ OPJ_BOOL opj_j2k_read_sot ( opj_j2k_t *p_j2k,
                 return OPJ_TRUE;
         }
 
-OPJ_BOOL opj_j2k_write_sod(     opj_j2k_t *p_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,
@@ -4410,7 +4303,7 @@ OPJ_BOOL opj_j2k_write_sod(     opj_j2k_t *p_j2k,
         return OPJ_TRUE;
 }
 
-OPJ_BOOL opj_j2k_read_sod (opj_j2k_t *p_j2k,
+static OPJ_BOOL opj_j2k_read_sod (opj_j2k_t *p_j2k,
                            opj_stream_private_t *p_stream,
                                                    opj_event_mgr_t * p_manager
                            )
@@ -4531,7 +4424,7 @@ OPJ_BOOL opj_j2k_read_sod (opj_j2k_t *p_j2k,
         return OPJ_TRUE;
 }
 
- OPJ_BOOL opj_j2k_write_rgn(opj_j2k_t *p_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,
@@ -4588,7 +4481,7 @@ OPJ_BOOL opj_j2k_read_sod (opj_j2k_t *p_j2k,
         return OPJ_TRUE;
 }
 
-OPJ_BOOL opj_j2k_write_eoc(     opj_j2k_t *p_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
                             )
@@ -4698,18 +4591,18 @@ static OPJ_BOOL opj_j2k_read_rgn (opj_j2k_t *p_j2k,
 
 }
 
-OPJ_FLOAT32 opj_j2k_get_tp_stride (opj_tcp_t * p_tcp)
+static OPJ_FLOAT32 opj_j2k_get_tp_stride (opj_tcp_t * p_tcp)
 {
         return (OPJ_FLOAT32) ((p_tcp->m_nb_tile_parts - 1) * 14);
 }
 
-OPJ_FLOAT32 opj_j2k_get_default_stride (opj_tcp_t * p_tcp)
+static OPJ_FLOAT32 opj_j2k_get_default_stride (opj_tcp_t * p_tcp)
 {
     (void)p_tcp;
     return 0;
 }
 
-OPJ_BOOL opj_j2k_update_rates(  opj_j2k_t *p_j2k,
+static OPJ_BOOL opj_j2k_update_rates(  opj_j2k_t *p_j2k,
                                                             opj_stream_private_t *p_stream,
                                                             opj_event_mgr_t * p_manager )
 {
@@ -4872,7 +4765,7 @@ OPJ_BOOL opj_j2k_update_rates(  opj_j2k_t *p_j2k,
 }
 
 #if 0
-OPJ_BOOL opj_j2k_read_eoc (     opj_j2k_t *p_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 )
 {
@@ -4922,7 +4815,7 @@ OPJ_BOOL opj_j2k_read_eoc (     opj_j2k_t *p_j2k,
 }
 #endif
 
-OPJ_BOOL opj_j2k_get_end_header(opj_j2k_t *p_j2k,
+static OPJ_BOOL opj_j2k_get_end_header(opj_j2k_t *p_j2k,
                                                         struct opj_stream_private *p_stream,
                                                         struct opj_event_mgr * p_manager )
 {
@@ -4936,7 +4829,7 @@ OPJ_BOOL opj_j2k_get_end_header(opj_j2k_t *p_j2k,
         return OPJ_TRUE;
 }
 
-OPJ_BOOL opj_j2k_write_mct_data_group(  opj_j2k_t *p_j2k,
+static OPJ_BOOL opj_j2k_write_mct_data_group(  opj_j2k_t *p_j2k,
                                                                         struct opj_stream_private *p_stream,
                                                                         struct opj_event_mgr * p_manager )
 {
@@ -4985,7 +4878,7 @@ OPJ_BOOL opj_j2k_write_mct_data_group(  opj_j2k_t *p_j2k,
 }
 
 #if 0
-OPJ_BOOL opj_j2k_write_all_coc(opj_j2k_t *p_j2k,
+static OPJ_BOOL opj_j2k_write_all_coc(opj_j2k_t *p_j2k,
                                                                         struct opj_stream_private *p_stream,
                                                                         struct opj_event_mgr * p_manager )
 {
@@ -5008,7 +4901,7 @@ OPJ_BOOL opj_j2k_write_all_coc(opj_j2k_t *p_j2k,
 #endif
 
 #if 0
-OPJ_BOOL opj_j2k_write_all_qcc(opj_j2k_t *p_j2k,
+static OPJ_BOOL opj_j2k_write_all_qcc(opj_j2k_t *p_j2k,
                                                                         struct opj_stream_private *p_stream,
                                                                         struct opj_event_mgr * p_manager )
 {
@@ -5031,7 +4924,7 @@ OPJ_BOOL opj_j2k_write_all_qcc(opj_j2k_t *p_j2k,
 #endif
 
 
-OPJ_BOOL opj_j2k_write_regions( opj_j2k_t *p_j2k,
+static OPJ_BOOL opj_j2k_write_regions( opj_j2k_t *p_j2k,
                                                         struct opj_stream_private *p_stream,
                                                         struct opj_event_mgr * p_manager )
 {
@@ -5059,7 +4952,7 @@ OPJ_BOOL opj_j2k_write_regions( opj_j2k_t *p_j2k,
         return OPJ_TRUE;
 }
 
-OPJ_BOOL opj_j2k_write_epc(     opj_j2k_t *p_j2k,
+static OPJ_BOOL opj_j2k_write_epc(     opj_j2k_t *p_j2k,
                                                 struct opj_stream_private *p_stream,
                                                 struct opj_event_mgr * p_manager )
 {
@@ -5097,7 +4990,7 @@ OPJ_BOOL opj_j2k_write_epc(     opj_j2k_t *p_j2k,
         return OPJ_TRUE;
 }
 
-OPJ_BOOL opj_j2k_read_unk (     opj_j2k_t *p_j2k,
+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
@@ -5114,7 +5007,7 @@ OPJ_BOOL opj_j2k_read_unk (     opj_j2k_t *p_j2k,
 
         opj_event_msg(p_manager, EVT_WARNING, "Unknown marker\n");
 
-        while(1) {
+               for (;;) {
                 /* Try to read 2 bytes (the next marker ID) from stream and copy them into the buffer*/
                 if (opj_stream_read_data(p_stream,p_j2k->m_specific_param.m_decoder.m_header_data,2,p_manager) != 2) {
                         opj_event_msg(p_manager, EVT_ERROR, "Stream too short\n");
@@ -5159,7 +5052,7 @@ OPJ_BOOL opj_j2k_read_unk (     opj_j2k_t *p_j2k,
         return OPJ_TRUE;
 }
 
-OPJ_BOOL opj_j2k_write_mct_record(      opj_j2k_t *p_j2k,
+static OPJ_BOOL opj_j2k_write_mct_record(      opj_j2k_t *p_j2k,
                                                                 opj_mct_data_t * p_mct_record,
                                                                 struct opj_stream_private *p_stream,
                                                                 struct opj_event_mgr * p_manager )
@@ -5331,7 +5224,7 @@ static OPJ_BOOL opj_j2k_read_mct (      opj_j2k_t *p_j2k,
         return OPJ_TRUE;
 }
 
-OPJ_BOOL opj_j2k_write_mcc_record(      opj_j2k_t *p_j2k,
+static OPJ_BOOL opj_j2k_write_mcc_record(      opj_j2k_t *p_j2k,
                                                                 struct opj_simple_mcc_decorrelation_data * p_mcc_record,
                                                                 struct opj_stream_private *p_stream,
                                                                 struct opj_event_mgr * p_manager )
@@ -5434,7 +5327,7 @@ OPJ_BOOL opj_j2k_write_mcc_record(      opj_j2k_t *p_j2k,
         return OPJ_TRUE;
 }
 
-OPJ_BOOL opj_j2k_read_mcc (     opj_j2k_t *p_j2k,
+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 )
@@ -5649,7 +5542,7 @@ OPJ_BOOL opj_j2k_read_mcc (     opj_j2k_t *p_j2k,
         return OPJ_TRUE;
 }
 
-OPJ_BOOL opj_j2k_write_mco(     opj_j2k_t *p_j2k,
+static OPJ_BOOL opj_j2k_write_mco(     opj_j2k_t *p_j2k,
                                                 struct opj_stream_private *p_stream,
                                                 struct opj_event_mgr * p_manager
                                   )
@@ -5779,7 +5672,7 @@ static OPJ_BOOL opj_j2k_read_mco (      opj_j2k_t *p_j2k,
         return OPJ_TRUE;
 }
 
-OPJ_BOOL opj_j2k_add_mct(opj_tcp_t * p_tcp, opj_image_t * p_image, OPJ_UINT32 p_index)
+static OPJ_BOOL opj_j2k_add_mct(opj_tcp_t * p_tcp, opj_image_t * p_image, OPJ_UINT32 p_index)
 {
         OPJ_UINT32 i;
         opj_simple_mcc_decorrelation_data_t * l_mcc_record;
@@ -5861,7 +5754,7 @@ OPJ_BOOL opj_j2k_add_mct(opj_tcp_t * p_tcp, opj_image_t * p_image, OPJ_UINT32 p_
         return OPJ_TRUE;
 }
 
-OPJ_BOOL opj_j2k_write_cbd( opj_j2k_t *p_j2k,
+static OPJ_BOOL opj_j2k_write_cbd( opj_j2k_t *p_j2k,
                                                 struct opj_stream_private *p_stream,
                                                 struct opj_event_mgr * p_manager )
 {
@@ -6027,7 +5920,7 @@ opj_j2k_t* opj_j2k_create_compress(void)
         return l_j2k;
 }
 
-int opj_j2k_initialise_4K_poc(opj_poc_t *POC, int numres){
+static int opj_j2k_initialise_4K_poc(opj_poc_t *POC, int numres){
     POC[0].tile  = 1;
     POC[0].resno0  = 0;
     POC[0].compno0 = 0;
@@ -6045,7 +5938,7 @@ int opj_j2k_initialise_4K_poc(opj_poc_t *POC, int numres){
     return 2;
 }
 
-void opj_j2k_set_cinema_parameters(opj_cparameters_t *parameters, opj_image_t *image, opj_event_mgr_t *p_manager)
+static void opj_j2k_set_cinema_parameters(opj_cparameters_t *parameters, opj_image_t *image, opj_event_mgr_t *p_manager)
 {
     /* Configure cinema parameters */
     int i;
@@ -6182,7 +6075,7 @@ void opj_j2k_set_cinema_parameters(opj_cparameters_t *parameters, opj_image_t *i
 
 }
 
-OPJ_BOOL opj_j2k_is_cinema_compliant(opj_image_t *image, OPJ_UINT16 rsiz, 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)
 {
     OPJ_UINT32 i;
 
@@ -6882,7 +6775,7 @@ OPJ_BOOL opj_j2k_read_header(   opj_stream_private_t *p_stream,
         return OPJ_TRUE;
 }
 
-void opj_j2k_setup_header_reading (opj_j2k_t *p_j2k)
+static void opj_j2k_setup_header_reading (opj_j2k_t *p_j2k)
 {
         /* preconditions*/
         assert(p_j2k != 00);
@@ -6894,7 +6787,7 @@ void opj_j2k_setup_header_reading (opj_j2k_t *p_j2k)
 
 }
 
-void opj_j2k_setup_decoding_validation (opj_j2k_t *p_j2k)
+static void opj_j2k_setup_decoding_validation (opj_j2k_t *p_j2k)
 {
         /* preconditions*/
         assert(p_j2k != 00);
@@ -6905,7 +6798,7 @@ void opj_j2k_setup_decoding_validation (opj_j2k_t *p_j2k)
 
 }
 
-OPJ_BOOL opj_j2k_mct_validation (       opj_j2k_t * p_j2k,
+static OPJ_BOOL opj_j2k_mct_validation (       opj_j2k_t * p_j2k,
                                                                 opj_stream_private_t *p_stream,
                                                                 opj_event_mgr_t * p_manager )
 {
@@ -7091,7 +6984,7 @@ OPJ_BOOL opj_j2k_setup_mct_encoding(opj_tcp_t * p_tcp, opj_image_t * p_image)
         return OPJ_TRUE;
 }
 
-OPJ_BOOL opj_j2k_build_decoder (opj_j2k_t * p_j2k,
+static OPJ_BOOL opj_j2k_build_decoder (opj_j2k_t * p_j2k,
                                                             opj_stream_private_t *p_stream,
                                                             opj_event_mgr_t * p_manager )
 {
@@ -7103,7 +6996,7 @@ OPJ_BOOL opj_j2k_build_decoder (opj_j2k_t * p_j2k,
         return OPJ_TRUE;
 }
 
-OPJ_BOOL opj_j2k_build_encoder (opj_j2k_t * p_j2k,
+static OPJ_BOOL opj_j2k_build_encoder (opj_j2k_t * p_j2k,
                                                         opj_stream_private_t *p_stream,
                                                         opj_event_mgr_t * p_manager )
 {
@@ -7115,7 +7008,7 @@ OPJ_BOOL opj_j2k_build_encoder (opj_j2k_t * p_j2k,
         return OPJ_TRUE;
 }
 
-OPJ_BOOL opj_j2k_encoding_validation (  opj_j2k_t * p_j2k,
+static OPJ_BOOL opj_j2k_encoding_validation (  opj_j2k_t * p_j2k,
                                                                             opj_stream_private_t *p_stream,
                                                                             opj_event_mgr_t * p_manager )
 {
@@ -7158,7 +7051,7 @@ OPJ_BOOL opj_j2k_encoding_validation (  opj_j2k_t * p_j2k,
         return l_is_valid;
 }
 
-OPJ_BOOL opj_j2k_decoding_validation (  opj_j2k_t *p_j2k,
+static OPJ_BOOL opj_j2k_decoding_validation (  opj_j2k_t *p_j2k,
                                         opj_stream_private_t *p_stream,
                                         opj_event_mgr_t * p_manager
                                         )
@@ -7188,7 +7081,7 @@ OPJ_BOOL opj_j2k_decoding_validation (  opj_j2k_t *p_j2k,
         return l_is_valid;
 }
 
-OPJ_BOOL opj_j2k_read_header_procedure( opj_j2k_t *p_j2k,
+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)
 {
@@ -7334,6 +7227,11 @@ OPJ_BOOL opj_j2k_read_header_procedure( opj_j2k_t *p_j2k,
             opj_event_msg(p_manager, EVT_ERROR, "required QCD marker not found in main header\n");
             return OPJ_FALSE;
         }
+       
+        if (! opj_j2k_merge_ppm(&(p_j2k->m_cp), p_manager)) {
+            opj_event_msg(p_manager, EVT_ERROR, "Failed to merge PPM data\n");
+            return OPJ_FALSE;
+        }
 
         opj_event_msg(p_manager, EVT_INFO, "Main header has been correctly decoded.\n");
 
@@ -7346,7 +7244,7 @@ OPJ_BOOL opj_j2k_read_header_procedure( opj_j2k_t *p_j2k,
         return OPJ_TRUE;
 }
 
-OPJ_BOOL opj_j2k_exec ( opj_j2k_t * p_j2k,
+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 )
@@ -7514,7 +7412,7 @@ static OPJ_BOOL opj_j2k_copy_default_tcp_and_create_tcd (       opj_j2k_t * p_j2
         return OPJ_TRUE;
 }
 
-const opj_dec_memory_marker_handler_t * opj_j2k_get_marker_handler (OPJ_UINT32 p_id)
+static const opj_dec_memory_marker_handler_t * opj_j2k_get_marker_handler (OPJ_UINT32 p_id)
 {
         const opj_dec_memory_marker_handler_t *e;
         for (e = j2k_memory_marker_handler_tab; e->id != 0; ++e) {
@@ -7627,66 +7525,78 @@ void j2k_destroy_cstr_index (opj_codestream_index_t *p_cstr_ind)
         }
 }
 
-void opj_j2k_tcp_destroy (opj_tcp_t *p_tcp)
+static void opj_j2k_tcp_destroy (opj_tcp_t *p_tcp)
 {
-        if (p_tcp == 00) {
-                return;
-        }
-
-        if (p_tcp->ppt_buffer != 00) {
-                opj_free(p_tcp->ppt_buffer);
-                p_tcp->ppt_buffer = 00;
-        }
-
-        if (p_tcp->tccps != 00) {
-                opj_free(p_tcp->tccps);
-                p_tcp->tccps = 00;
-        }
-
-        if (p_tcp->m_mct_coding_matrix != 00) {
-                opj_free(p_tcp->m_mct_coding_matrix);
-                p_tcp->m_mct_coding_matrix = 00;
-        }
-
-        if (p_tcp->m_mct_decoding_matrix != 00) {
-                opj_free(p_tcp->m_mct_decoding_matrix);
-                p_tcp->m_mct_decoding_matrix = 00;
-        }
-
-        if (p_tcp->m_mcc_records) {
-                opj_free(p_tcp->m_mcc_records);
-                p_tcp->m_mcc_records = 00;
-                p_tcp->m_nb_max_mcc_records = 0;
-                p_tcp->m_nb_mcc_records = 0;
-        }
-
-        if (p_tcp->m_mct_records) {
-                opj_mct_data_t * l_mct_data = p_tcp->m_mct_records;
-                OPJ_UINT32 i;
-
-                for (i=0;i<p_tcp->m_nb_mct_records;++i) {
-                        if (l_mct_data->m_data) {
-                                opj_free(l_mct_data->m_data);
-                                l_mct_data->m_data = 00;
-                        }
-
-                        ++l_mct_data;
-                }
-
-                opj_free(p_tcp->m_mct_records);
-                p_tcp->m_mct_records = 00;
-        }
+       if (p_tcp == 00) {
+               return;
+       }
+       
+       if (p_tcp->ppt_markers != 00) {
+               OPJ_UINT32 i;
+               for (i = 0U; i < p_tcp->ppt_markers_count; ++i) {
+                       if (p_tcp->ppt_markers[i].m_data != NULL) {
+                               opj_free(p_tcp->ppt_markers[i].m_data);
+                       }
+               }
+               p_tcp->ppt_markers_count = 0U;
+               opj_free(p_tcp->ppt_markers);
+               p_tcp->ppt_markers = NULL;
+       }
+       
+       if (p_tcp->ppt_buffer != 00) {
+               opj_free(p_tcp->ppt_buffer);
+               p_tcp->ppt_buffer = 00;
+       }
+       
+       if (p_tcp->tccps != 00) {
+               opj_free(p_tcp->tccps);
+               p_tcp->tccps = 00;
+       }
+       
+       if (p_tcp->m_mct_coding_matrix != 00) {
+               opj_free(p_tcp->m_mct_coding_matrix);
+               p_tcp->m_mct_coding_matrix = 00;
+       }
+       
+       if (p_tcp->m_mct_decoding_matrix != 00) {
+               opj_free(p_tcp->m_mct_decoding_matrix);
+               p_tcp->m_mct_decoding_matrix = 00;
+       }
+       
+       if (p_tcp->m_mcc_records) {
+               opj_free(p_tcp->m_mcc_records);
+               p_tcp->m_mcc_records = 00;
+               p_tcp->m_nb_max_mcc_records = 0;
+               p_tcp->m_nb_mcc_records = 0;
+       }
+       
+       if (p_tcp->m_mct_records) {
+               opj_mct_data_t * l_mct_data = p_tcp->m_mct_records;
+               OPJ_UINT32 i;
+               
+               for (i=0;i<p_tcp->m_nb_mct_records;++i) {
+                       if (l_mct_data->m_data) {
+                               opj_free(l_mct_data->m_data);
+                               l_mct_data->m_data = 00;
+                       }
+                       
+                       ++l_mct_data;
+               }
+               
+               opj_free(p_tcp->m_mct_records);
+               p_tcp->m_mct_records = 00;
+       }
 
-        if (p_tcp->mct_norms != 00) {
-                opj_free(p_tcp->mct_norms);
-                p_tcp->mct_norms = 00;
-        }
+       if (p_tcp->mct_norms != 00) {
+               opj_free(p_tcp->mct_norms);
+               p_tcp->mct_norms = 00;
+       }
 
-        opj_j2k_tcp_data_destroy(p_tcp);
+       opj_j2k_tcp_data_destroy(p_tcp);
 
 }
 
-void opj_j2k_tcp_data_destroy (opj_tcp_t *p_tcp)
+static void opj_j2k_tcp_data_destroy (opj_tcp_t *p_tcp)
 {
         if (p_tcp->m_data) {
                 opj_free(p_tcp->m_data);
@@ -7695,39 +7605,50 @@ void opj_j2k_tcp_data_destroy (opj_tcp_t *p_tcp)
         }
 }
 
-void opj_j2k_cp_destroy (opj_cp_t *p_cp)
+static void opj_j2k_cp_destroy (opj_cp_t *p_cp)
 {
-        OPJ_UINT32 l_nb_tiles;
-        opj_tcp_t * l_current_tile = 00;
-        OPJ_UINT32 i;
+       OPJ_UINT32 l_nb_tiles;
+       opj_tcp_t * l_current_tile = 00;
 
-        if (p_cp == 00)
-        {
-                return;
-        }
-        if (p_cp->tcps != 00)
-        {
-                l_current_tile = p_cp->tcps;
-                l_nb_tiles = p_cp->th * p_cp->tw;
-
-                for (i = 0; i < l_nb_tiles; ++i)
-                {
-                        opj_j2k_tcp_destroy(l_current_tile);
-                        ++l_current_tile;
-                }
-                opj_free(p_cp->tcps);
-                p_cp->tcps = 00;
-        }
-        opj_free(p_cp->ppm_buffer);
-        p_cp->ppm_buffer = 00;
-        p_cp->ppm_data = NULL; /* ppm_data belongs to the allocated buffer pointed by ppm_buffer */
-        opj_free(p_cp->comment);
-        p_cp->comment = 00;
-        if (! p_cp->m_is_decoder)
-        {
-                opj_free(p_cp->m_specific_param.m_enc.m_matrice);
-                p_cp->m_specific_param.m_enc.m_matrice = 00;
-        }
+       if (p_cp == 00)
+       {
+               return;
+       }
+       if (p_cp->tcps != 00)
+       {
+               OPJ_UINT32 i;
+               l_current_tile = p_cp->tcps;
+               l_nb_tiles = p_cp->th * p_cp->tw;
+               
+               for (i = 0U; i < l_nb_tiles; ++i)
+               {
+                       opj_j2k_tcp_destroy(l_current_tile);
+                       ++l_current_tile;
+               }
+               opj_free(p_cp->tcps);
+               p_cp->tcps = 00;
+       }
+       if (p_cp->ppm_markers != 00) {
+               OPJ_UINT32 i;
+               for (i = 0U; i < p_cp->ppm_markers_count; ++i) {
+                       if (p_cp->ppm_markers[i].m_data != NULL) {
+                               opj_free(p_cp->ppm_markers[i].m_data);
+                       }
+               }
+               p_cp->ppm_markers_count = 0U;
+               opj_free(p_cp->ppm_markers);
+               p_cp->ppm_markers = NULL;
+       }
+       opj_free(p_cp->ppm_buffer);
+       p_cp->ppm_buffer = 00;
+       p_cp->ppm_data = NULL; /* ppm_data belongs to the allocated buffer pointed by ppm_buffer */
+       opj_free(p_cp->comment);
+       p_cp->comment = 00;
+       if (! p_cp->m_is_decoder)
+       {
+               opj_free(p_cp->m_specific_param.m_enc.m_matrice);
+               p_cp->m_specific_param.m_enc.m_matrice = 00;
+       }
 }
 
 static OPJ_BOOL opj_j2k_need_nb_tile_parts_correction(opj_stream_private_t *p_stream, OPJ_UINT32 tile_no, OPJ_BOOL* p_correction_needed, opj_event_mgr_t * p_manager )
@@ -7842,7 +7763,6 @@ OPJ_BOOL opj_j2k_read_tile_header(      opj_j2k_t * p_j2k,
         OPJ_UINT32 l_marker_size;
         const opj_dec_memory_marker_handler_t * l_marker_handler = 00;
         opj_tcp_t * l_tcp = NULL;
-        OPJ_UINT32 l_nb_tiles;
 
         /* preconditions */
         assert(p_stream != 00);
@@ -8054,8 +7974,8 @@ OPJ_BOOL opj_j2k_read_tile_header(      opj_j2k_t * p_j2k,
 
         /* FIXME DOC ???*/
         if ( ! p_j2k->m_specific_param.m_decoder.m_can_decode) {
+                OPJ_UINT32 l_nb_tiles = p_j2k->m_cp.th * p_j2k->m_cp.tw;
                 l_tcp = p_j2k->m_cp.tcps + p_j2k->m_current_tile_number;
-                l_nb_tiles = p_j2k->m_cp.th * p_j2k->m_cp.tw;
 
                 while( (p_j2k->m_current_tile_number < l_nb_tiles) && (l_tcp->m_data == 00) ) {
                         ++p_j2k->m_current_tile_number;
@@ -8068,6 +7988,10 @@ OPJ_BOOL opj_j2k_read_tile_header(      opj_j2k_t * p_j2k,
                 }
         }
 
+        if (! opj_j2k_merge_ppt(p_j2k->m_cp.tcps + p_j2k->m_current_tile_number, p_manager)) {
+                opj_event_msg(p_manager, EVT_ERROR, "Failed to merge PPT data\n");
+                return OPJ_FALSE;
+        }
         /*FIXME ???*/
         if (! opj_tcd_init_decode_tile(p_j2k->m_tcd, p_j2k->m_current_tile_number)) {
                 opj_event_msg(p_manager, EVT_ERROR, "Cannot decode tile, memory error\n");
@@ -8174,7 +8098,7 @@ OPJ_BOOL opj_j2k_decode_tile (  opj_j2k_t * p_j2k,
         return OPJ_TRUE;
 }
 
-OPJ_BOOL opj_j2k_update_image_data (opj_tcd_t * p_tcd, OPJ_BYTE * p_data, opj_image_t* p_output_image)
+static OPJ_BOOL opj_j2k_update_image_data (opj_tcd_t * p_tcd, OPJ_BYTE * p_data, opj_image_t* p_output_image)
 {
         OPJ_UINT32 i,j,k = 0;
         OPJ_UINT32 l_width_src,l_height_src;
@@ -8648,7 +8572,7 @@ opj_j2k_t* opj_j2k_create_decompress(void)
         return l_j2k;
 }
 
-opj_codestream_index_t* opj_j2k_create_cstr_index(void)
+static opj_codestream_index_t* opj_j2k_create_cstr_index(void)
 {
         opj_codestream_index_t* cstr_index = (opj_codestream_index_t*)
                         opj_calloc(1,sizeof(opj_codestream_index_t));
@@ -8667,7 +8591,7 @@ opj_codestream_index_t* opj_j2k_create_cstr_index(void)
         return cstr_index;
 }
 
-OPJ_UINT32 opj_j2k_get_SPCod_SPCoc_size (       opj_j2k_t *p_j2k,
+static OPJ_UINT32 opj_j2k_get_SPCod_SPCoc_size (       opj_j2k_t *p_j2k,
                                                                                 OPJ_UINT32 p_tile_no,
                                                                                 OPJ_UINT32 p_comp_no )
 {
@@ -8694,7 +8618,7 @@ OPJ_UINT32 opj_j2k_get_SPCod_SPCoc_size (       opj_j2k_t *p_j2k,
         }
 }
 
-OPJ_BOOL opj_j2k_write_SPCod_SPCoc(     opj_j2k_t *p_j2k,
+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,
@@ -8760,7 +8684,7 @@ OPJ_BOOL opj_j2k_write_SPCod_SPCoc(     opj_j2k_t *p_j2k,
         return OPJ_TRUE;
 }
 
-OPJ_BOOL opj_j2k_read_SPCod_SPCoc(  opj_j2k_t *p_j2k,
+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,
@@ -8883,7 +8807,7 @@ OPJ_BOOL opj_j2k_read_SPCod_SPCoc(  opj_j2k_t *p_j2k,
         return OPJ_TRUE;
 }
 
-void opj_j2k_copy_tile_component_parameters( opj_j2k_t *p_j2k )
+static void opj_j2k_copy_tile_component_parameters( opj_j2k_t *p_j2k )
 {
         /* loop */
         OPJ_UINT32 i;
@@ -8916,7 +8840,7 @@ void opj_j2k_copy_tile_component_parameters( opj_j2k_t *p_j2k )
         }
 }
 
-OPJ_UINT32 opj_j2k_get_SQcd_SQcc_size ( opj_j2k_t *p_j2k,
+static OPJ_UINT32 opj_j2k_get_SQcd_SQcc_size ( opj_j2k_t *p_j2k,
                                                                         OPJ_UINT32 p_tile_no,
                                                                         OPJ_UINT32 p_comp_no )
 {
@@ -8947,7 +8871,7 @@ OPJ_UINT32 opj_j2k_get_SQcd_SQcc_size ( opj_j2k_t *p_j2k,
         }
 }
 
-OPJ_BOOL opj_j2k_write_SQcd_SQcc(       opj_j2k_t *p_j2k,
+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,
@@ -9020,7 +8944,7 @@ OPJ_BOOL opj_j2k_write_SQcd_SQcc(       opj_j2k_t *p_j2k,
         return OPJ_TRUE;
 }
 
-OPJ_BOOL opj_j2k_read_SQcd_SQcc(opj_j2k_t *p_j2k,
+static OPJ_BOOL opj_j2k_read_SQcd_SQcc(opj_j2k_t *p_j2k,
                                                             OPJ_UINT32 p_comp_no,
                                                             OPJ_BYTE* p_header_data,
                                                             OPJ_UINT32 * p_header_size,
@@ -9137,7 +9061,7 @@ OPJ_BOOL opj_j2k_read_SQcd_SQcc(opj_j2k_t *p_j2k,
         return OPJ_TRUE;
 }
 
-void opj_j2k_copy_tile_quantization_parameters( opj_j2k_t *p_j2k )
+static void opj_j2k_copy_tile_quantization_parameters( opj_j2k_t *p_j2k )
 {
         OPJ_UINT32 i;
         opj_cp_t *l_cp = NULL;
@@ -9264,7 +9188,7 @@ void j2k_dump (opj_j2k_t* p_j2k, OPJ_INT32 flag, FILE* out_stream)
 
 }
 
-void opj_j2k_dump_MH_index(opj_j2k_t* p_j2k, FILE* out_stream)
+static void opj_j2k_dump_MH_index(opj_j2k_t* p_j2k, FILE* out_stream)
 {
         opj_codestream_index_t* cstr_index = p_j2k->cstr_index;
         OPJ_UINT32 it_marker, it_tile, it_tile_part;
@@ -9333,7 +9257,7 @@ void opj_j2k_dump_MH_index(opj_j2k_t* p_j2k, FILE* out_stream)
 }
 
 
-void opj_j2k_dump_MH_info(opj_j2k_t* p_j2k, FILE* out_stream)
+static void opj_j2k_dump_MH_info(opj_j2k_t* p_j2k, FILE* out_stream)
 {
 
         fprintf(out_stream, "Codestream info from main header: {\n");
@@ -9573,7 +9497,7 @@ opj_codestream_index_t* j2k_get_cstr_index(opj_j2k_t* p_j2k)
         return l_cstr_index;
 }
 
-OPJ_BOOL opj_j2k_allocate_tile_element_cstr_index(opj_j2k_t *p_j2k)
+static OPJ_BOOL opj_j2k_allocate_tile_element_cstr_index(opj_j2k_t *p_j2k)
 {
         OPJ_UINT32 it_tile=0;
 
@@ -9594,7 +9518,7 @@ OPJ_BOOL opj_j2k_allocate_tile_element_cstr_index(opj_j2k_t *p_j2k)
         return OPJ_TRUE;
 }
 
-OPJ_BOOL opj_j2k_decode_tiles ( opj_j2k_t *p_j2k,
+static OPJ_BOOL opj_j2k_decode_tiles ( opj_j2k_t *p_j2k,
                                                             opj_stream_private_t *p_stream,
                                                             opj_event_mgr_t * p_manager)
 {
@@ -9613,7 +9537,7 @@ OPJ_BOOL opj_j2k_decode_tiles ( opj_j2k_t *p_j2k,
         }
         l_max_data_size = 1000;
 
-        while (OPJ_TRUE) {
+               for (;;) {
                 if (! opj_j2k_read_tile_header( p_j2k,
                                         &l_current_tile_no,
                                         &l_data_size,
@@ -9736,7 +9660,7 @@ static OPJ_BOOL opj_j2k_decode_one_tile (       opj_j2k_t *p_j2k,
                                 p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_TPHSOT;
                 }
 
-        while (OPJ_TRUE) {
+               for (;;) {
                 if (! opj_j2k_read_tile_header( p_j2k,
                                         &l_current_tile_no,
                                         &l_data_size,
@@ -10021,7 +9945,6 @@ OPJ_BOOL opj_j2k_encode(opj_j2k_t * p_j2k,
                                                                                                                }
                                                                                                                return OPJ_FALSE;
                                                                                                        }
-                                                                                                       opj_alloc_tile_component_data(l_tilec);
                         }
                 }
                 l_current_tile_size = opj_tcd_get_encoded_tile_size(p_j2k->m_tcd);
@@ -10125,7 +10048,7 @@ OPJ_BOOL opj_j2k_start_compress(opj_j2k_t *p_j2k,
         return OPJ_TRUE;
 }
 
-OPJ_BOOL opj_j2k_pre_write_tile (       opj_j2k_t * p_j2k,
+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 )
@@ -10150,7 +10073,7 @@ OPJ_BOOL opj_j2k_pre_write_tile (       opj_j2k_t * p_j2k,
         return OPJ_TRUE;
 }
 
-void opj_get_tile_dimensions(opj_image_t * l_image,
+static void opj_get_tile_dimensions(opj_image_t * l_image,
                              opj_tcd_tilecomp_t * l_tilec,
                              opj_image_comp_t * l_img_comp,
                              OPJ_UINT32* l_size_comp,
@@ -10181,7 +10104,7 @@ void opj_get_tile_dimensions(opj_image_t * l_image,
        *l_tile_offset = ((OPJ_UINT32)l_tilec->x0 - *l_offset_x) + ((OPJ_UINT32)l_tilec->y0 - *l_offset_y) * *l_image_width;
 }
 
-void opj_j2k_get_tile_data (opj_tcd_t * p_tcd, OPJ_BYTE * p_data)
+static void opj_j2k_get_tile_data (opj_tcd_t * p_tcd, OPJ_BYTE * p_data)
 {
         OPJ_UINT32 i,j,k = 0;
 
@@ -10274,7 +10197,7 @@ void opj_j2k_get_tile_data (opj_tcd_t * p_tcd, OPJ_BYTE * p_data)
         }
 }
 
-OPJ_BOOL opj_j2k_post_write_tile (      opj_j2k_t * p_j2k,
+static OPJ_BOOL opj_j2k_post_write_tile (      opj_j2k_t * p_j2k,
                                                                 opj_stream_private_t *p_stream,
                                                                 opj_event_mgr_t * p_manager )
 {
@@ -10316,7 +10239,7 @@ OPJ_BOOL opj_j2k_post_write_tile (      opj_j2k_t * p_j2k,
         return OPJ_TRUE;
 }
 
-void opj_j2k_setup_end_compress (opj_j2k_t *p_j2k)
+static void opj_j2k_setup_end_compress (opj_j2k_t *p_j2k)
 {
         /* preconditions */
         assert(p_j2k != 00);
@@ -10333,7 +10256,7 @@ void opj_j2k_setup_end_compress (opj_j2k_t *p_j2k)
         opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_destroy_header_memory);
 }
 
-void opj_j2k_setup_encoding_validation (opj_j2k_t *p_j2k)
+static void opj_j2k_setup_encoding_validation (opj_j2k_t *p_j2k)
 {
         /* preconditions */
         assert(p_j2k != 00);
@@ -10345,7 +10268,7 @@ void opj_j2k_setup_encoding_validation (opj_j2k_t *p_j2k)
         opj_procedure_list_add_procedure(p_j2k->m_validation_list, (opj_procedure)opj_j2k_mct_validation);
 }
 
-void opj_j2k_setup_header_writing (opj_j2k_t *p_j2k)
+static void opj_j2k_setup_header_writing (opj_j2k_t *p_j2k)
 {
         /* preconditions */
         assert(p_j2k != 00);
@@ -10388,7 +10311,7 @@ void opj_j2k_setup_header_writing (opj_j2k_t *p_j2k)
         opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_update_rates);
 }
 
-OPJ_BOOL opj_j2k_write_first_tile_part (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,
@@ -10468,7 +10391,7 @@ OPJ_BOOL opj_j2k_write_first_tile_part (opj_j2k_t *p_j2k,
         return OPJ_TRUE;
 }
 
-OPJ_BOOL opj_j2k_write_all_tile_parts(  opj_j2k_t *p_j2k,
+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,
@@ -10579,7 +10502,7 @@ OPJ_BOOL opj_j2k_write_all_tile_parts(  opj_j2k_t *p_j2k,
         return OPJ_TRUE;
 }
 
-OPJ_BOOL opj_j2k_write_updated_tlm( opj_j2k_t *p_j2k,
+static OPJ_BOOL opj_j2k_write_updated_tlm( opj_j2k_t *p_j2k,
                                                                     struct opj_stream_private *p_stream,
                                                                     struct opj_event_mgr * p_manager )
 {
@@ -10610,7 +10533,7 @@ OPJ_BOOL opj_j2k_write_updated_tlm( opj_j2k_t *p_j2k,
         return OPJ_TRUE;
 }
 
-OPJ_BOOL opj_j2k_end_encoding(  opj_j2k_t *p_j2k,
+static OPJ_BOOL opj_j2k_end_encoding(  opj_j2k_t *p_j2k,
                                                         struct opj_stream_private *p_stream,
                                                         struct opj_event_mgr * p_manager )
 {
@@ -10661,7 +10584,7 @@ static OPJ_BOOL opj_j2k_destroy_header_memory ( opj_j2k_t * p_j2k,
         return OPJ_TRUE;
 }
 
-OPJ_BOOL opj_j2k_init_info(     opj_j2k_t *p_j2k,
+static OPJ_BOOL opj_j2k_init_info(     opj_j2k_t *p_j2k,
                                                 struct opj_stream_private *p_stream,
                                                 struct opj_event_mgr * p_manager )
 {