[trunk] Add internal implementation to dump all tiles/comp info
[openjpeg.git] / src / lib / openjp2 / j2k.c
index a9b42697b1c671feef4fd9461bc9c467353043a5..8790fc3399a14b3cc6d3f4177eab6f82ad9f13fd 100644 (file)
@@ -3175,6 +3175,8 @@ static OPJ_BOOL opj_j2k_read_poc (  opj_j2k_t *p_j2k,
                 opj_read_bytes(p_header_data,&(l_current_poc->compno0),l_comp_room);    /* CSpoc_i */
                 p_header_data+=l_comp_room;
                 opj_read_bytes(p_header_data,&(l_current_poc->layno1),2);                               /* LYEpoc_i */
+                /* make sure layer end is in acceptable bounds */
+                l_current_poc->layno1 = opj_uint_min(l_current_poc->layno1, l_tcp->numlayers);
                 p_header_data+=2;
                 opj_read_bytes(p_header_data,&(l_current_poc->resno1),1);                               /* REpoc_i */
                 ++p_header_data;
@@ -3553,6 +3555,17 @@ OPJ_BOOL j2k_read_ppm_v3 (
                 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_TRUE;
+                  }
+
                 /* First PPM marker: Initialization */
                 l_cp->ppm_len = l_N_ppm;
                 l_cp->ppm_data_read = 0;
@@ -3587,6 +3600,16 @@ OPJ_BOOL j2k_read_ppm_v3 (
                                 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_TRUE;
+                                  }
                                 /* 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);
@@ -3632,7 +3655,7 @@ OPJ_BOOL j2k_read_ppm_v3 (
                 l_remaining_data = p_header_size;
 
                 /* Next Ippm series is a complete series ?*/
-                if (l_remaining_data > l_N_ppm) {
+                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");
@@ -3780,6 +3803,7 @@ static OPJ_BOOL opj_j2k_read_ppt (  opj_j2k_t *p_j2k,
                 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");
@@ -7619,6 +7643,7 @@ OPJ_BOOL opj_j2k_decode_tile (  opj_j2k_t * p_j2k,
                                                                 p_j2k->cstr_index) ) {
                 opj_j2k_tcp_destroy(l_tcp);
                 p_j2k->m_specific_param.m_decoder.m_state |= 0x8000;/*FIXME J2K_DEC_STATE_ERR;*/
+                opj_event_msg(p_manager, EVT_ERROR, "Failed to decode.\n");
                 return OPJ_FALSE;
         }
 
@@ -8651,6 +8676,58 @@ void opj_j2k_copy_tile_quantization_parameters( opj_j2k_t *p_j2k )
         }
 }
 
+static void opj_j2k_dump_tile_info( opj_tcp_t * l_default_tile,OPJ_INT32 numcomps,FILE* out_stream)
+{
+        if (l_default_tile)
+        {
+                OPJ_INT32 compno;
+
+                fprintf(out_stream, "\t default tile {\n");
+                fprintf(out_stream, "\t\t csty=%#x\n", l_default_tile->csty);
+                fprintf(out_stream, "\t\t prg=%#x\n", l_default_tile->prg);
+                fprintf(out_stream, "\t\t numlayers=%d\n", l_default_tile->numlayers);
+                fprintf(out_stream, "\t\t mct=%x\n", l_default_tile->mct);
+
+                for (compno = 0; compno < numcomps; compno++) {
+                        opj_tccp_t *l_tccp = &(l_default_tile->tccps[compno]);
+                        OPJ_UINT32 resno;
+      OPJ_INT32 bandno, numbands;
+
+                        /* coding style*/
+                        fprintf(out_stream, "\t\t comp %d {\n", compno);
+                        fprintf(out_stream, "\t\t\t csty=%#x\n", l_tccp->csty);
+                        fprintf(out_stream, "\t\t\t numresolutions=%d\n", l_tccp->numresolutions);
+                        fprintf(out_stream, "\t\t\t cblkw=2^%d\n", l_tccp->cblkw);
+                        fprintf(out_stream, "\t\t\t cblkh=2^%d\n", l_tccp->cblkh);
+                        fprintf(out_stream, "\t\t\t cblksty=%#x\n", l_tccp->cblksty);
+                        fprintf(out_stream, "\t\t\t qmfbid=%d\n", l_tccp->qmfbid);
+
+                        fprintf(out_stream, "\t\t\t preccintsize (w,h)=");
+                        for (resno = 0; resno < l_tccp->numresolutions; resno++) {
+                                fprintf(out_stream, "(%d,%d) ", l_tccp->prcw[resno], l_tccp->prch[resno]);
+                        }
+                        fprintf(out_stream, "\n");
+
+                        /* quantization style*/
+                        fprintf(out_stream, "\t\t\t qntsty=%d\n", l_tccp->qntsty);
+                        fprintf(out_stream, "\t\t\t numgbits=%d\n", l_tccp->numgbits);
+                        fprintf(out_stream, "\t\t\t stepsizes (m,e)=");
+                        numbands = (l_tccp->qntsty == J2K_CCP_QNTSTY_SIQNT) ? 1 : (OPJ_INT32)l_tccp->numresolutions * 3 - 2;
+                        for (bandno = 0; bandno < numbands; bandno++) {
+                                fprintf(out_stream, "(%d,%d) ", l_tccp->stepsizes[bandno].mant,
+                                        l_tccp->stepsizes[bandno].expn);
+                        }
+                        fprintf(out_stream, "\n");
+
+                        /* RGN value*/
+                        fprintf(out_stream, "\t\t\t roishift=%d\n", l_tccp->roishift);
+
+                        fprintf(out_stream, "\t\t }\n");
+                } /*end of component of default tile*/
+                fprintf(out_stream, "\t }\n"); /*end of default tile*/
+            }
+}
+
 void j2k_dump (opj_j2k_t* p_j2k, OPJ_INT32 flag, FILE* out_stream)
 {
         /* Check if the flag is compatible with j2k file*/
@@ -8669,6 +8746,16 @@ void j2k_dump (opj_j2k_t* p_j2k, OPJ_INT32 flag, FILE* out_stream)
         if (flag & OPJ_J2K_MH_INFO){
                 opj_j2k_dump_MH_info(p_j2k, out_stream);
         }
+        /* Dump all tile/codestream info */
+        if (flag & OPJ_J2K_TCH_INFO){
+          OPJ_UINT32 l_nb_tiles = p_j2k->m_cp.th * p_j2k->m_cp.tw;
+          OPJ_UINT32 i;
+          opj_tcp_t * l_tcp = p_j2k->m_cp.tcps;
+          for (i=0;i<l_nb_tiles;++i) {
+            opj_j2k_dump_tile_info( l_tcp,(OPJ_INT32)p_j2k->m_private_image->numcomps, out_stream);
+            ++l_tcp;
+          }
+        }
 
         /* Dump the codestream info of the current tile */
         if (flag & OPJ_J2K_TH_INFO){
@@ -8755,70 +8842,17 @@ 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)
 {
-        opj_tcp_t * l_default_tile=NULL;
 
         fprintf(out_stream, "Codestream info from main header: {\n");
 
         fprintf(out_stream, "\t tx0=%d, ty0=%d\n", p_j2k->m_cp.tx0, p_j2k->m_cp.ty0);
         fprintf(out_stream, "\t tdx=%d, tdy=%d\n", p_j2k->m_cp.tdx, p_j2k->m_cp.tdy);
         fprintf(out_stream, "\t tw=%d, th=%d\n", p_j2k->m_cp.tw, p_j2k->m_cp.th);
-
-        l_default_tile = p_j2k->m_specific_param.m_decoder.m_default_tcp;
-        if (l_default_tile)
-        {
-                OPJ_INT32 compno;
-                OPJ_INT32 numcomps = (OPJ_INT32)p_j2k->m_private_image->numcomps;
-
-                fprintf(out_stream, "\t default tile {\n");
-                fprintf(out_stream, "\t\t csty=%#x\n", l_default_tile->csty);
-                fprintf(out_stream, "\t\t prg=%#x\n", l_default_tile->prg);
-                fprintf(out_stream, "\t\t numlayers=%d\n", l_default_tile->numlayers);
-                fprintf(out_stream, "\t\t mct=%x\n", l_default_tile->mct);
-
-                for (compno = 0; compno < numcomps; compno++) {
-                        opj_tccp_t *l_tccp = &(l_default_tile->tccps[compno]);
-                        OPJ_UINT32 resno;
-      OPJ_INT32 bandno, numbands;
-
-                        /* coding style*/
-                        fprintf(out_stream, "\t\t comp %d {\n", compno);
-                        fprintf(out_stream, "\t\t\t csty=%#x\n", l_tccp->csty);
-                        fprintf(out_stream, "\t\t\t numresolutions=%d\n", l_tccp->numresolutions);
-                        fprintf(out_stream, "\t\t\t cblkw=2^%d\n", l_tccp->cblkw);
-                        fprintf(out_stream, "\t\t\t cblkh=2^%d\n", l_tccp->cblkh);
-                        fprintf(out_stream, "\t\t\t cblksty=%#x\n", l_tccp->cblksty);
-                        fprintf(out_stream, "\t\t\t qmfbid=%d\n", l_tccp->qmfbid);
-
-                        fprintf(out_stream, "\t\t\t preccintsize (w,h)=");
-                        for (resno = 0; resno < l_tccp->numresolutions; resno++) {
-                                fprintf(out_stream, "(%d,%d) ", l_tccp->prcw[resno], l_tccp->prch[resno]);
-                        }
-                        fprintf(out_stream, "\n");
-
-                        /* quantization style*/
-                        fprintf(out_stream, "\t\t\t qntsty=%d\n", l_tccp->qntsty);
-                        fprintf(out_stream, "\t\t\t numgbits=%d\n", l_tccp->numgbits);
-                        fprintf(out_stream, "\t\t\t stepsizes (m,e)=");
-                        numbands = (l_tccp->qntsty == J2K_CCP_QNTSTY_SIQNT) ? 1 : (OPJ_INT32)l_tccp->numresolutions * 3 - 2;
-                        for (bandno = 0; bandno < numbands; bandno++) {
-                                fprintf(out_stream, "(%d,%d) ", l_tccp->stepsizes[bandno].mant,
-                                        l_tccp->stepsizes[bandno].expn);
-                        }
-                        fprintf(out_stream, "\n");
-
-                        /* RGN value*/
-                        fprintf(out_stream, "\t\t\t roishift=%d\n", l_tccp->roishift);
-
-                        fprintf(out_stream, "\t\t }\n");
-                } /*end of component of default tile*/
-                fprintf(out_stream, "\t }\n"); /*end of default tile*/
-
-        }
-
+        opj_j2k_dump_tile_info(p_j2k->m_specific_param.m_decoder.m_default_tcp,(OPJ_INT32)p_j2k->m_private_image->numcomps, out_stream);
         fprintf(out_stream, "}\n");
-
 }
 
 void j2k_dump_image_header(opj_image_t* img_header, OPJ_BOOL dev_dump_flag, FILE* out_stream)
@@ -9120,6 +9154,7 @@ OPJ_BOOL opj_j2k_decode_tiles ( opj_j2k_t *p_j2k,
 
                 if (! opj_j2k_decode_tile(p_j2k,l_current_tile_no,l_current_data,l_data_size,p_stream,p_manager)) {
                         opj_free(l_current_data);
+                        opj_event_msg(p_manager, EVT_ERROR, "Failed to decode tile %d/%d\n", l_current_tile_no +1, p_j2k->m_cp.th * p_j2k->m_cp.tw);
                         return OPJ_FALSE;
                 }
                 opj_event_msg(p_manager, EVT_INFO, "Tile %d/%d has been decoded.\n", l_current_tile_no +1, p_j2k->m_cp.th * p_j2k->m_cp.tw);
@@ -9318,6 +9353,13 @@ OPJ_BOOL opj_j2k_decode(opj_j2k_t * p_j2k,
         for (compno = 0; compno < p_image->numcomps; compno++) {
                 p_image->comps[compno].resno_decoded = p_j2k->m_output_image->comps[compno].resno_decoded;
                 p_image->comps[compno].data = p_j2k->m_output_image->comps[compno].data;
+#if 0
+                char fn[256];
+                sprintf( fn, "/tmp/%d.raw", compno );
+                FILE *debug = fopen( fn, "wb" );
+                fwrite( p_image->comps[compno].data, sizeof(OPJ_INT32), p_image->comps[compno].w * p_image->comps[compno].h, debug );
+                fclose( debug );
+#endif
                 p_j2k->m_output_image->comps[compno].data = NULL;
         }