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

Implement predictive termination check #800

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/lib/openjp2/mqc.c
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,7 @@ void opj_mqc_init_enc(opj_mqc_t *mqc, OPJ_BYTE *bp)
assert(*(mqc->bp) != 0xff);

mqc->start = bp;
mqc->end_of_byte_stream_counter = 0;
}

void opj_mqc_encode(opj_mqc_t *mqc, OPJ_UINT32 d)
Expand Down Expand Up @@ -513,6 +514,7 @@ void opj_mqc_init_dec(opj_mqc_t *mqc, OPJ_BYTE *bp, OPJ_UINT32 len,
/* See https://github.com/uclouvain/openjpeg/issues/921 */
opj_mqc_init_dec_common(mqc, bp, len, extra_writable_bytes);
opj_mqc_setcurctx(mqc, 0);
mqc->end_of_byte_stream_counter = 0;
if (len == 0) {
mqc->c = 0xff << 16;
} else {
Expand Down
2 changes: 2 additions & 0 deletions src/lib/openjp2/mqc.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ typedef struct opj_mqc {
OPJ_UINT32 a;
/** number of bits already read or free to write */
OPJ_UINT32 ct;
/* only used by decoder, to count the number of times a terminating 0xFF >0x8F marker is read */
OPJ_UINT32 end_of_byte_stream_counter;
/** pointer to the current position in the buffer */
OPJ_BYTE *bp;
/** pointer to the start of the buffer */
Expand Down
1 change: 1 addition & 0 deletions src/lib/openjp2/mqc_inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ static INLINE OPJ_UINT32 opj_mqc_raw_decode(opj_mqc_t *mqc)
if (l_c > 0x8f) { \
c += 0xff00; \
ct = 8; \
mqc->end_of_byte_stream_counter ++; \
} else { \
mqc->bp++; \
c += l_c << 9; \
Expand Down
52 changes: 48 additions & 4 deletions src/lib/openjp2/t1.c
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,10 @@ static OPJ_BOOL opj_t1_decode_cblk(opj_t1_t *t1,
opj_tcd_cblk_dec_t* cblk,
OPJ_UINT32 orient,
OPJ_UINT32 roishift,
OPJ_UINT32 cblksty);
OPJ_UINT32 cblksty,
opj_event_mgr_t *p_manager,
opj_mutex_t* p_manager_mutex,
OPJ_BOOL check_pterm);

static OPJ_BOOL opj_t1_allocate_buffers(opj_t1_t *t1,
OPJ_UINT32 w,
Expand Down Expand Up @@ -1608,6 +1611,9 @@ typedef struct {
opj_tcd_tilecomp_t* tilec;
opj_tccp_t* tccp;
volatile OPJ_BOOL* pret;
opj_event_mgr_t *p_manager;
opj_mutex_t* p_manager_mutex;
OPJ_BOOL check_pterm;
} opj_t1_cblk_decode_processing_job_t;

static void opj_t1_destroy_wrapper(void* t1)
Expand Down Expand Up @@ -1654,7 +1660,10 @@ static void opj_t1_clbl_decode_processor(void* user_data, opj_tls_t* tls)
cblk,
band->bandno,
(OPJ_UINT32)tccp->roishift,
tccp->cblksty)) {
tccp->cblksty,
job->p_manager,
job->p_manager_mutex,
job->check_pterm)) {
*(job->pret) = OPJ_FALSE;
opj_free(job);
return;
Expand Down Expand Up @@ -1730,7 +1739,10 @@ static void opj_t1_clbl_decode_processor(void* user_data, opj_tls_t* tls)
void opj_t1_decode_cblks(opj_thread_pool_t* tp,
volatile OPJ_BOOL* pret,
opj_tcd_tilecomp_t* tilec,
opj_tccp_t* tccp
opj_tccp_t* tccp,
opj_event_mgr_t *p_manager,
opj_mutex_t* p_manager_mutex,
OPJ_BOOL check_pterm
)
{
OPJ_UINT32 resno, bandno, precno, cblkno;
Expand Down Expand Up @@ -1760,6 +1772,9 @@ void opj_t1_decode_cblks(opj_thread_pool_t* tp,
job->tilec = tilec;
job->tccp = tccp;
job->pret = pret;
job->p_manager_mutex = p_manager_mutex;
job->p_manager = p_manager;
job->check_pterm = check_pterm;
opj_thread_pool_submit_job(tp, opj_t1_clbl_decode_processor, job);
if (!(*pret)) {
return;
Expand All @@ -1777,7 +1792,10 @@ static OPJ_BOOL opj_t1_decode_cblk(opj_t1_t *t1,
opj_tcd_cblk_dec_t* cblk,
OPJ_UINT32 orient,
OPJ_UINT32 roishift,
OPJ_UINT32 cblksty)
OPJ_UINT32 cblksty,
opj_event_mgr_t *p_manager,
opj_mutex_t* p_manager_mutex,
OPJ_BOOL check_pterm)
{
opj_mqc_t *mqc = &(t1->mqc); /* MQC component */

Expand Down Expand Up @@ -1858,6 +1876,32 @@ static OPJ_BOOL opj_t1_decode_cblk(opj_t1_t *t1,
opq_mqc_finish_dec(mqc);
}

if (check_pterm) {
if (mqc->bp + 2 < mqc->end) {
if (p_manager_mutex) {
opj_mutex_lock(p_manager_mutex);
}
opj_event_msg(p_manager, EVT_WARNING,
"PTERM check failure: %d remaining bytes in code block (%d used / %d)\n",
(int)(mqc->end - mqc->bp) - 2,
(int)(mqc->bp - mqc->start),
(int)(mqc->end - mqc->start));
if (p_manager_mutex) {
opj_mutex_unlock(p_manager_mutex);
}
} else if (mqc->end_of_byte_stream_counter > 2) {
if (p_manager_mutex) {
opj_mutex_lock(p_manager_mutex);
}
opj_event_msg(p_manager, EVT_WARNING,
"PTERM check failure: %d synthetized 0xFF markers read\n",
mqc->end_of_byte_stream_counter);
if (p_manager_mutex) {
opj_mutex_unlock(p_manager_mutex);
}
}
}

return OPJ_TRUE;
}

Expand Down
5 changes: 4 additions & 1 deletion src/lib/openjp2/t1.h
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,10 @@ Decode the code-blocks of a tile
void opj_t1_decode_cblks(opj_thread_pool_t* tp,
volatile OPJ_BOOL* pret,
opj_tcd_tilecomp_t* tilec,
opj_tccp_t* tccp);
opj_tccp_t* tccp,
opj_event_mgr_t *p_manager,
opj_mutex_t* p_manager_mutex,
OPJ_BOOL check_pterm);



Expand Down
25 changes: 19 additions & 6 deletions src/lib/openjp2/tcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,8 @@ static OPJ_BOOL opj_tcd_t2_decode(opj_tcd_t *p_tcd,
opj_codestream_index_t *p_cstr_index,
opj_event_mgr_t *p_manager);

static OPJ_BOOL opj_tcd_t1_decode(opj_tcd_t *p_tcd);
static OPJ_BOOL opj_tcd_t1_decode(opj_tcd_t *p_tcd,
opj_event_mgr_t *p_manager);

static OPJ_BOOL opj_tcd_dwt_decode(opj_tcd_t *p_tcd);

Expand Down Expand Up @@ -1421,8 +1422,7 @@ OPJ_BOOL opj_tcd_decode_tile(opj_tcd_t *p_tcd,
/*------------------TIER1-----------------*/

/* FIXME _ProfStart(PGROUP_T1); */
if
(! opj_tcd_t1_decode(p_tcd)) {
if (! opj_tcd_t1_decode(p_tcd, p_manager)) {
return OPJ_FALSE;
}
/* FIXME _ProfStop(PGROUP_T1); */
Expand Down Expand Up @@ -1681,16 +1681,27 @@ static OPJ_BOOL opj_tcd_t2_decode(opj_tcd_t *p_tcd,
return OPJ_TRUE;
}

static OPJ_BOOL opj_tcd_t1_decode(opj_tcd_t *p_tcd)
static OPJ_BOOL opj_tcd_t1_decode(opj_tcd_t *p_tcd, opj_event_mgr_t *p_manager)
{
OPJ_UINT32 compno;
opj_tcd_tile_t * l_tile = p_tcd->tcd_image->tiles;
opj_tcd_tilecomp_t* l_tile_comp = l_tile->comps;
opj_tccp_t * l_tccp = p_tcd->tcp->tccps;
volatile OPJ_BOOL ret = OPJ_TRUE;
OPJ_BOOL check_pterm = OPJ_FALSE;
opj_mutex_t* p_manager_mutex = NULL;

p_manager_mutex = opj_mutex_create();

/* Only enable PTERM check if we decode all layers */
if (p_tcd->tcp->num_layers_to_decode == p_tcd->tcp->numlayers &&
(l_tccp->cblksty & J2K_CCP_CBLKSTY_PTERM) != 0) {
check_pterm = OPJ_TRUE;
}

for (compno = 0; compno < l_tile->numcomps; ++compno) {
opj_t1_decode_cblks(p_tcd->thread_pool, &ret, l_tile_comp, l_tccp);
opj_t1_decode_cblks(p_tcd->thread_pool, &ret, l_tile_comp, l_tccp,
p_manager, p_manager_mutex, check_pterm);
if (!ret) {
break;
}
Expand All @@ -1699,7 +1710,9 @@ static OPJ_BOOL opj_tcd_t1_decode(opj_tcd_t *p_tcd)
}

opj_thread_pool_wait_completion(p_tcd->thread_pool, 0);

if (p_manager_mutex) {
opj_mutex_destroy(p_manager_mutex);
}
return ret;
}

Expand Down