From 1e705438e469890cabc3c3d1fa0b91ed45b454ff Mon Sep 17 00:00:00 2001 From: Giuseppe Baruffa Date: Tue, 11 Sep 2007 15:21:12 +0000 Subject: [PATCH] JPWL encoding is finalized correctly into the JP2 file format; added an additional structure in opj_codestream_info, to keep a record of the written markers --- ChangeLog | 3 ++ codec/image_to_j2k.c | 16 ++++++-- jpwl/JPWL_image_to_j2k.dsp | 3 +- jpwl/jpwl.c | 78 +++++++++++++++++++++++++++++++------- jpwl/jpwl.h | 13 +++++++ libopenjpeg/j2k.c | 14 ++----- libopenjpeg/openjpeg.h | 20 ++++++++++ 7 files changed, 119 insertions(+), 28 deletions(-) diff --git a/ChangeLog b/ChangeLog index 183d8628..ddb8977c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -5,6 +5,9 @@ What's New for OpenJPEG ! : changed + : added +September 11, 2007 +* [GB] JPWL encoding is finalized correctly into the JP2 file format; added an additional structure in opj_codestream_info, to keep a record of the written markers + September 8, 2007 * [GB] Adapted the JPWL and OPJViewer code to new interface; fixed a samll bug in JPWL which created large EPBs even when null protection was specified diff --git a/codec/image_to_j2k.c b/codec/image_to_j2k.c index 576c0ee9..9c579193 100644 --- a/codec/image_to_j2k.c +++ b/codec/image_to_j2k.c @@ -287,12 +287,22 @@ void encode_help_display() { fprintf(stdout,"decomposition_levels\n"); fprintf(stdout,"[Precincts_size_X_res_Nr Precincts_size_Y_res_Nr]...\n"); fprintf(stdout," [Precincts_size_X_res_0 Precincts_size_Y_res_0]\n"); + fprintf(stdout,"Main_header_start_position\n"); fprintf(stdout,"Main_header_end_position\n"); fprintf(stdout,"Codestream_size\n"); - fprintf(stdout,"Tile_0 start_pos end_Theader end_pos TotalDisto NumPix MaxMSE\n"); - fprintf(stdout,"Tile_1 '' '' '' '' '' ''\n"); + fprintf(stdout,"\n"); + fprintf(stdout,"INFO ON TILES\n"); + fprintf(stdout,"tileno start_pos end_hd end_tile nbparts disto nbpix disto/nbpix\n"); + fprintf(stdout,"Tile_0 start_pos end_Theader end_pos NumParts TotalDisto NumPix MaxMSE\n"); + fprintf(stdout,"Tile_1 '' '' '' '' '' '' ''\n"); fprintf(stdout,"...\n"); - fprintf(stdout,"Tile_Nt '' '' '' '' '' ''\n"); + fprintf(stdout,"Tile_Nt '' '' '' '' '' '' ''\n"); + fprintf(stdout,"...\n"); + fprintf(stdout,"TILE 0 DETAILS\n"); + fprintf(stdout,"part_nb tileno num_packs start_pos end_tph_pos end_pos\n"); + fprintf(stdout,"...\n"); + fprintf(stdout,"Progression_string\n"); + fprintf(stdout,"pack_nb tileno layno resno compno precno start_pos end_ph_pos end_pos disto\n"); fprintf(stdout,"Tpacket_0 Tile layer res. comp. prec. start_pos end_pos disto\n"); fprintf(stdout,"...\n"); fprintf(stdout,"Tpacket_Np '' '' '' '' '' '' '' ''\n"); diff --git a/jpwl/JPWL_image_to_j2k.dsp b/jpwl/JPWL_image_to_j2k.dsp index f7c4e35c..52d5e9aa 100644 --- a/jpwl/JPWL_image_to_j2k.dsp +++ b/jpwl/JPWL_image_to_j2k.dsp @@ -42,7 +42,8 @@ RSC=rc.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MT /W3 /GX /O2 /I "../libopenjpeg" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "OPJ_STATIC" /D "USE_JPWL" /D "USE_JPSEC" /FR /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "../libopenjpeg" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "OPJ_STATIC" /D "USE_JPWL" /D "USE_JPSEC" /FR /FD /c +# SUBTRACT CPP /YX # ADD BASE RSC /l 0x80c /d "NDEBUG" # ADD RSC /l 0x80c /d "NDEBUG" BSC32=bscmake.exe diff --git a/jpwl/jpwl.c b/jpwl/jpwl.c index 7a307839..894e7d3f 100644 --- a/jpwl/jpwl.c +++ b/jpwl/jpwl.c @@ -39,10 +39,10 @@ /** @name Local static variables */ /*@{*/ -/** position of markers to insert */ -static jpwl_marker_t jwmarker[JPWL_MAX_NO_MARKERS]; -/** number of prepared markers */ +/** number of JPWL prepared markers */ static int jwmarker_num; +/** properties of JPWL markers to insert */ +static jpwl_marker_t jwmarker[JPWL_MAX_NO_MARKERS]; /*@}*/ @@ -107,6 +107,57 @@ void jpwl_esd_write(jpwl_esd_ms_t *esdmark, unsigned char *buf); /*-----------------------------------------------------------------*/ +void jpwl_encode(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image) { + + int mm; + + /* let's reset some settings */ + + /* clear the existing markers */ + for (mm = 0; mm < jwmarker_num; mm++) { + + switch (jwmarker[mm].id) { + + case J2K_MS_EPB: + free(jwmarker[mm].epbmark); + break; + + case J2K_MS_EPC: + free(jwmarker[mm].epcmark); + break; + + case J2K_MS_ESD: + free(jwmarker[mm].esdmark); + break; + + case J2K_MS_RED: + free(jwmarker[mm].redmark); + break; + + default: + break; + } + } + + /* clear the marker structure array */ + memset(jwmarker, 0, sizeof(jpwl_marker_t) * JPWL_MAX_NO_MARKERS); + + /* no more markers in the list */ + jwmarker_num = 0; + + /* let's begin creating a marker list, according to user wishes */ + jpwl_prepare_marks(j2k, cio, image); + + /* now we dump the JPWL markers on the codestream */ + jpwl_dump_marks(j2k, cio, image); + + /* do not know exactly what is this for, + but it gets called during index creation */ + j2k->pos_correction = 0; + +} + + void jpwl_prepare_marks(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image) { unsigned short int socsiz_len = 0; @@ -282,7 +333,7 @@ void jpwl_prepare_marks(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image) { jwmarker[jwmarker_num].id = J2K_MS_ESD; /* its type */ jwmarker[jwmarker_num].esdmark = esd_mark; /* the EPB */ /****** jwmarker[jwmarker_num].pos = j2k->cstr_info->tile[tileno].start_pos + sot_len + 2; */ /* after SOT */ - jwmarker[jwmarker_num].pos = soc_pos + j2k->cstr_info->tile[tileno].tp[tpno].tp_start_pos + sot_len + 2; /* after SOT */ + jwmarker[jwmarker_num].pos = j2k->cstr_info->tile[tileno].tp[tpno].tp_start_pos + sot_len + 2; /* after SOT */ jwmarker[jwmarker_num].dpos = (double) jwmarker[jwmarker_num].pos + 0.2; /* not first at all! */ jwmarker[jwmarker_num].len = esd_mark->Lesd; /* its length */ jwmarker[jwmarker_num].len_ready = true; /* ready, yet */ @@ -458,7 +509,7 @@ void jpwl_prepare_marks(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image) { jwmarker[jwmarker_num].id = J2K_MS_EPB; /* its type */ jwmarker[jwmarker_num].epbmark = epb_mark; /* the EPB */ /****** jwmarker[jwmarker_num].pos = j2k->cstr_info->tile[tileno].start_pos + sot_len + 2; */ /* after SOT */ - jwmarker[jwmarker_num].pos = soc_pos + j2k->cstr_info->tile[tileno].tp[tpno].tp_start_pos + sot_len + 2; /* after SOT */ + jwmarker[jwmarker_num].pos = j2k->cstr_info->tile[tileno].tp[tpno].tp_start_pos + sot_len + 2; /* after SOT */ jwmarker[jwmarker_num].dpos = (double) jwmarker[jwmarker_num].pos; /* first first first! */ jwmarker[jwmarker_num].len = epb_mark->Lepb; /* its length */ jwmarker[jwmarker_num].len_ready = true; /* ready */ @@ -647,23 +698,23 @@ void jpwl_dump_marks(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image) { /* Order JPWL markers according to their wishlist position */ qsort((void *) jwmarker, (size_t) jwmarker_num, sizeof (jpwl_marker_t), jpwl_markcomp); - /* compute markers total size */ + /* compute markers total size */ for (mm = 0; mm < jwmarker_num; mm++) { /*printf("%x, %d, %.10f, %d long\n", jwmarker[mm].id, jwmarker[mm].pos, jwmarker[mm].dpos, jwmarker[mm].len);*/ new_size += jwmarker[mm].len + 2; } - /* allocate a temporary buffer of proper size */ + /* allocate a new buffer of proper size */ if (!(jpwl_buf = (unsigned char *) opj_malloc((size_t) new_size * sizeof (unsigned char)))) { - opj_event_msg(j2k->cinfo, EVT_ERROR, "Could not allocate room for JPWL temp codestream buffer\n"); + opj_event_msg(j2k->cinfo, EVT_ERROR, "Could not allocate room for JPWL codestream buffer\n"); exit(1); }; /* copy the jp2 part, if any */ - memcpy(jpwl_buf, cio->buffer, soc_pos); - orig_buf = jpwl_buf; + memcpy(jpwl_buf, cio->buffer, soc_pos); + jpwl_buf += soc_pos; /* cycle through markers */ orig_pos = soc_pos + 0; /* start from the beginning */ @@ -713,8 +764,8 @@ void jpwl_dump_marks(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image) { } /* finish remaining original codestream */ - memcpy(jpwl_buf, cio_getbp(cio), soc_pos + old_size - orig_pos); - jpwl_buf += soc_pos + old_size - orig_pos; + memcpy(jpwl_buf, cio_getbp(cio), old_size - (orig_pos - soc_pos)); + jpwl_buf += old_size - (orig_pos - soc_pos); cio_seek(cio, soc_pos + old_size); /* @@ -814,7 +865,8 @@ void jpwl_dump_marks(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image) { opj_free(cio->buffer); /*cio->cinfo;*/ /* no change */ /*cio->openmode;*/ /* no change */ - cio->buffer = jpwl_buf - new_size - soc_pos; + /*cio->buffer = jpwl_buf - new_size - soc_pos;*/ + cio->buffer = orig_buf; cio->length = new_size + soc_pos; cio->start = jpwl_buf - new_size - soc_pos; cio->end = jpwl_buf - 1; diff --git a/jpwl/jpwl.h b/jpwl/jpwl.h index a18c1480..65edce77 100644 --- a/jpwl/jpwl.h +++ b/jpwl/jpwl.h @@ -205,6 +205,14 @@ typedef struct jpwl_marker { bool data_ready; } jpwl_marker_t; +/** +Encode according to JPWL specs +@param j2k J2K handle +@param cio codestream handle +@param image image handle +*/ +void jpwl_encode(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image); + /** Prepare the list of JPWL markers, after the Part 1 codestream has been finalized (index struct is full) @@ -227,6 +235,7 @@ Read the EPC marker (Error Protection Capability) @param j2k J2K handle */ void j2k_read_epc(opj_j2k_t *j2k); + /** Write the EPC marker (Error Protection Capability), BUT the DL field is always set to 0 (this simplifies the management of EPBs and it is openly stated in the standard @@ -235,21 +244,25 @@ are not yet implemented @param j2k J2K handle */ void j2k_write_epc(opj_j2k_t *j2k); + /** Read the EPB marker (Error Protection Block) @param j2k J2K handle */ void j2k_read_epb(opj_j2k_t *j2k); + /** Write the EPB marker (Error Protection Block) @param j2k J2K handle */ void j2k_write_epb(opj_j2k_t *j2k); + /** Read the ESD marker (Error Sensitivity Descriptor) @param j2k J2K handle */ void j2k_read_esd(opj_j2k_t *j2k); + /** Read the RED marker (Residual Error Descriptor) @param j2k J2K handle diff --git a/libopenjpeg/j2k.c b/libopenjpeg/j2k.c index 727391ef..651ef215 100644 --- a/libopenjpeg/j2k.c +++ b/libopenjpeg/j2k.c @@ -2454,20 +2454,12 @@ bool j2k_encode(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image, opj_codestre #ifdef USE_JPWL /* - preparation of JPWL marker segments: can be finalized only when the whole - codestream is known + preparation of JPWL marker segments */ if(cp->epc_on) { - /* let's begin creating a marker list, according to user wishes */ - jpwl_prepare_marks(j2k, cio, image); - - /* now we dump the JPWL markers on the codestream */ - jpwl_dump_marks(j2k, cio, image); - - /* do not know exactly what is this for, - but it gets called during index creation */ - j2k->pos_correction = 0; + /* encode according to JPWL */ + jpwl_encode(j2k, cio, image); } #endif /* USE_JPWL */ diff --git a/libopenjpeg/openjpeg.h b/libopenjpeg/openjpeg.h index 7021bb54..876c0ab1 100644 --- a/libopenjpeg/openjpeg.h +++ b/libopenjpeg/openjpeg.h @@ -644,6 +644,20 @@ typedef struct opj_tile_info { opj_tp_info_t *tp; } opj_tile_info_t; +/* UniPG>> */ +/** +Marker structure +*/ +typedef struct opj_marker_info_t { + /** marker type */ + unsigned short int type; + /** position in codestream */ + int pos; + /** length, marker val included */ + int len; +} opj_marker_info_t; +/* <> */ + /** number of markers */ + int marknum; + /** list of markers */ + opj_marker_info_t *marker; +/* <