Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

compression: emit POC marker when only one single POC is requested (f… #1192

Merged
merged 7 commits into from
Apr 25, 2019
107 changes: 46 additions & 61 deletions src/lib/openjp2/j2k.c
Original file line number Diff line number Diff line change
Expand Up @@ -1219,6 +1219,7 @@ static OPJ_BOOL opj_j2k_write_epc(opj_j2k_t *p_j2k,
* A nice message is outputted at errors.
*
* @param p_pocs the progression order changes.
* @param tileno the tile number of interest
* @param p_nb_pocs the number of progression order changes.
* @param p_nb_resolutions the number of resolutions.
* @param numcomps the number of components
Expand All @@ -1228,6 +1229,7 @@ static OPJ_BOOL opj_j2k_write_epc(opj_j2k_t *p_j2k,
* @return true if the pocs are valid.
*/
static OPJ_BOOL opj_j2k_check_poc_val(const opj_poc_t *p_pocs,
OPJ_UINT32 tileno,
OPJ_UINT32 p_nb_pocs,
OPJ_UINT32 p_nb_resolutions,
OPJ_UINT32 numcomps,
Expand Down Expand Up @@ -1615,6 +1617,7 @@ const char *opj_j2k_convert_progression_order(OPJ_PROG_ORDER prg_order)
}

static OPJ_BOOL opj_j2k_check_poc_val(const opj_poc_t *p_pocs,
OPJ_UINT32 tileno,
OPJ_UINT32 p_nb_pocs,
OPJ_UINT32 p_nb_resolutions,
OPJ_UINT32 p_num_comps,
Expand All @@ -1628,7 +1631,8 @@ static OPJ_BOOL opj_j2k_check_poc_val(const opj_poc_t *p_pocs,
OPJ_UINT32 step_r = p_num_comps * step_c;
OPJ_UINT32 step_l = p_nb_resolutions * step_r;
OPJ_BOOL loss = OPJ_FALSE;
OPJ_UINT32 layno0 = 0;

assert(p_nb_pocs > 0);

packet_array = (OPJ_UINT32*) opj_calloc(step_l * p_num_layers,
sizeof(OPJ_UINT32));
Expand All @@ -1638,71 +1642,51 @@ static OPJ_BOOL opj_j2k_check_poc_val(const opj_poc_t *p_pocs,
return OPJ_FALSE;
}

if (p_nb_pocs == 0) {
opj_free(packet_array);
return OPJ_TRUE;
}

index = step_r * p_pocs->resno0;
/* take each resolution for each poc */
for (resno = p_pocs->resno0 ; resno < p_pocs->resno1 ; ++resno) {
OPJ_UINT32 res_index = index + p_pocs->compno0 * step_c;

/* take each comp of each resolution for each poc */
for (compno = p_pocs->compno0 ; compno < p_pocs->compno1 ; ++compno) {
OPJ_UINT32 comp_index = res_index + layno0 * step_l;

/* and finally take each layer of each res of ... */
for (layno = layno0; layno < p_pocs->layno1 ; ++layno) {
/*index = step_r * resno + step_c * compno + step_l * layno;*/
packet_array[comp_index] = 1;
comp_index += step_l;
}

res_index += step_c;
}

index += step_r;
}
++p_pocs;

/* iterate through all the pocs */
for (i = 1; i < p_nb_pocs ; ++i) {
OPJ_UINT32 l_last_layno1 = (p_pocs - 1)->layno1 ;
/* iterate through all the pocs that match our tile of interest. */
for (i = 0; i < p_nb_pocs; ++i) {
const opj_poc_t *poc = &p_pocs[i];
if (tileno + 1 == poc->tile) {
index = step_r * poc->resno0;

layno0 = (p_pocs->layno1 > l_last_layno1) ? l_last_layno1 : 0;
index = step_r * p_pocs->resno0;
/* take each resolution for each poc */
for (resno = poc->resno0 ;
resno < opj_uint_min(poc->resno1, p_nb_resolutions); ++resno) {
OPJ_UINT32 res_index = index + poc->compno0 * step_c;

/* take each resolution for each poc */
for (resno = p_pocs->resno0 ; resno < p_pocs->resno1 ; ++resno) {
OPJ_UINT32 res_index = index + p_pocs->compno0 * step_c;
/* take each comp of each resolution for each poc */
for (compno = poc->compno0 ;
compno < opj_uint_min(poc->compno1, p_num_comps); ++compno) {
/* The layer index always starts at zero for every progression. */
const OPJ_UINT32 layno0 = 0;
OPJ_UINT32 comp_index = res_index + layno0 * step_l;

/* take each comp of each resolution for each poc */
for (compno = p_pocs->compno0 ; compno < p_pocs->compno1 ; ++compno) {
OPJ_UINT32 comp_index = res_index + layno0 * step_l;
/* and finally take each layer of each res of ... */
for (layno = layno0; layno < opj_uint_min(poc->layno1, p_num_layers);
++layno) {
packet_array[comp_index] = 1;
comp_index += step_l;
}

/* and finally take each layer of each res of ... */
for (layno = layno0; layno < p_pocs->layno1 ; ++layno) {
/*index = step_r * resno + step_c * compno + step_l * layno;*/
packet_array[comp_index] = 1;
comp_index += step_l;
res_index += step_c;
}

res_index += step_c;
index += step_r;
}

index += step_r;
}

++p_pocs;
}

index = 0;
for (layno = 0; layno < p_num_layers ; ++layno) {
for (resno = 0; resno < p_nb_resolutions; ++resno) {
for (compno = 0; compno < p_num_comps; ++compno) {
loss |= (packet_array[index] != 1);
/*index = step_r * resno + step_c * compno + step_l * layno;*/
#ifdef DEBUG_VERBOSE
if (packet_array[index] != 1) {
fprintf(stderr,
"Missing packet in POC: layno=%d resno=%d compno=%d\n",
layno, resno, compno);
}
#endif
index += step_c;
}
}
Expand Down Expand Up @@ -7157,13 +7141,6 @@ OPJ_BOOL opj_j2k_setup_encoder(opj_j2k_t *p_j2k,
"Not enough memory to allocate tile coding parameters\n");
return OPJ_FALSE;
}
if (parameters->numpocs) {
/* initialisation of POC */
opj_j2k_check_poc_val(parameters->POC, parameters->numpocs,
(OPJ_UINT32)parameters->numresolution, image->numcomps,
(OPJ_UINT32)parameters->tcp_numlayers, p_manager);
/* TODO MSD use the return value*/
}

for (tileno = 0; tileno < cp->tw * cp->th; tileno++) {
opj_tcp_t *tcp = &cp->tcps[tileno];
Expand Down Expand Up @@ -7197,7 +7174,6 @@ OPJ_BOOL opj_j2k_setup_encoder(opj_j2k_t *p_j2k,

if (parameters->numpocs) {
/* initialisation of POC */
tcp->POC = 1;
for (i = 0; i < parameters->numpocs; i++) {
if (tileno + 1 == parameters->POC[i].tile) {
opj_poc_t *tcp_poc = &tcp->pocs[numpocs_tile];
Expand All @@ -7214,7 +7190,16 @@ OPJ_BOOL opj_j2k_setup_encoder(opj_j2k_t *p_j2k,
}
}

tcp->numpocs = numpocs_tile - 1 ;
if (numpocs_tile) {

/* TODO MSD use the return value*/
opj_j2k_check_poc_val(parameters->POC, tileno, parameters->numpocs,
(OPJ_UINT32)parameters->numresolution, image->numcomps,
(OPJ_UINT32)parameters->tcp_numlayers, p_manager);

tcp->POC = 1;
tcp->numpocs = numpocs_tile - 1 ;
}
} else {
tcp->numpocs = 0;
}
Expand Down Expand Up @@ -11759,7 +11744,7 @@ static OPJ_BOOL opj_j2k_write_first_tile_part(opj_j2k_t *p_j2k,
total_data_size -= l_current_nb_bytes_written;
}
#endif
if (l_cp->tcps[p_j2k->m_current_tile_number].numpocs) {
if (l_cp->tcps[p_j2k->m_current_tile_number].POC) {
l_current_nb_bytes_written = 0;
opj_j2k_write_poc_in_memory(p_j2k, p_data, &l_current_nb_bytes_written,
p_manager);
Expand Down
2 changes: 1 addition & 1 deletion src/lib/openjp2/openjpeg.h
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ typedef struct opj_poc {
OPJ_PROG_ORDER prg1, prg;
/** Progression order string*/
OPJ_CHAR progorder[5];
/** Tile number */
/** Tile number (starting at 1) */
OPJ_UINT32 tile;
/** Start and end values for Tile width and height*/
OPJ_INT32 tx0, tx1, ty0, ty1;
Expand Down
8 changes: 8 additions & 0 deletions src/lib/openjp2/t2.c
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,14 @@ static OPJ_BOOL opj_t2_encode_packet(OPJ_UINT32 tileno,
OPJ_BOOL packet_empty = OPJ_FALSE;
#endif

#ifdef DEBUG_VERBOSE
if (p_t2_mode == FINAL_PASS) {
fprintf(stderr,
"encode packet compono=%d, resno=%d, precno=%d, layno=%d\n",
compno, resno, precno, layno);
}
#endif

/* <SOP 0xff91> */
if (tcp->csty & J2K_CP_CSTY_SOP) {
if (length < 6) {
Expand Down
5 changes: 5 additions & 0 deletions tests/nonregression/test_suite.ctest.in
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,11 @@ opj_compress -i @INPUT_NR_PATH@/Bretagne2.ppm -o @TEMP_PATH@/Bretagne2_empty_ban

opj_compress -i @INPUT_NR_PATH@/issue982.bmp -o @TEMP_PATH@/issue982.j2k -n 1

# Test generating only one POC
opj_compress -i @INPUT_NR_PATH@/byte.tif -o @TEMP_PATH@/byte_one_poc.j2k -n 2 -r 20,1 -POC T1=0,0,2,2,1,CPRL -b 4,4
opj_compress -i @INPUT_NR_PATH@/byte.tif -o @TEMP_PATH@/byte_one_poc_funky_bounds.j2k -n 2 -r 20,1 -POC T1=0,0,65535,33,255,CPRL -b 4,4
opj_compress -i @INPUT_NR_PATH@/byte.tif -o @TEMP_PATH@/byte_one_poc_unrelated_tile.j2k -n 1 -POC T1000=0,0,1,1,1,CPRL

# DECODER TEST SUITE
opj_decompress -i @INPUT_NR_PATH@/Bretagne2.j2k -o @TEMP_PATH@/Bretagne2.j2k.pgx
opj_decompress -i @INPUT_NR_PATH@/_00042.j2k -o @TEMP_PATH@/_00042.j2k.pgx
Expand Down