+ job->whole_tile_decoding = tcd->whole_tile_decoding;
+ job->resno = resno;
+ job->cblk = cblk;
+ job->band = band;
+ 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;
+ job->mustuse_cblkdatabuffer = opj_thread_pool_get_thread_count(tp) > 1;
+ opj_thread_pool_submit_job(tp, opj_t1_clbl_decode_processor, job);
+#ifdef DEBUG_VERBOSE
+ codeblocks_decoded ++;
+#endif
+ if (!(*pret)) {
+ return;
+ }
+ } /* cblkno */
+ } /* precno */
+ } /* bandno */
+ } /* resno */
+
+#ifdef DEBUG_VERBOSE
+ printf("Leave opj_t1_decode_cblks(). Number decoded: %d\n", codeblocks_decoded);
+#endif
+ return;
+}
+
+
+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_event_mgr_t *p_manager,
+ opj_mutex_t* p_manager_mutex,
+ OPJ_BOOL check_pterm)
+{
+ opj_mqc_t *mqc = &(t1->mqc); /* MQC component */
+
+ OPJ_INT32 bpno_plus_one;
+ OPJ_UINT32 passtype;
+ OPJ_UINT32 segno, passno;
+ OPJ_BYTE* cblkdata = NULL;
+ OPJ_UINT32 cblkdataindex = 0;
+ OPJ_BYTE type = T1_TYPE_MQ; /* BYPASS mode */
+ OPJ_INT32* original_t1_data = NULL;
+
+ mqc->lut_ctxno_zc_orient = lut_ctxno_zc + (orient << 9);
+
+ if (!opj_t1_allocate_buffers(
+ t1,
+ (OPJ_UINT32)(cblk->x1 - cblk->x0),
+ (OPJ_UINT32)(cblk->y1 - cblk->y0))) {
+ return OPJ_FALSE;
+ }
+
+ bpno_plus_one = (OPJ_INT32)(roishift + cblk->numbps);
+ if (bpno_plus_one >= 31) {
+ if (p_manager_mutex) {
+ opj_mutex_lock(p_manager_mutex);
+ }
+ opj_event_msg(p_manager, EVT_WARNING,
+ "opj_t1_decode_cblk(): unsupported bpno_plus_one = %d >= 31\n",
+ bpno_plus_one);
+ if (p_manager_mutex) {
+ opj_mutex_unlock(p_manager_mutex);
+ }
+ return OPJ_FALSE;
+ }
+ passtype = 2;
+
+ opj_mqc_resetstates(mqc);
+ opj_mqc_setstate(mqc, T1_CTXNO_UNI, 0, 46);
+ opj_mqc_setstate(mqc, T1_CTXNO_AGG, 0, 3);
+ opj_mqc_setstate(mqc, T1_CTXNO_ZC, 0, 4);
+
+ /* Even if we have a single chunk, in multi-threaded decoding */
+ /* the insertion of our synthetic marker might potentially override */
+ /* valid codestream of other codeblocks decoded in parallel. */
+ if (cblk->numchunks > 1 || t1->mustuse_cblkdatabuffer) {
+ OPJ_UINT32 i;
+ OPJ_UINT32 cblk_len;
+
+ /* Compute whole codeblock length from chunk lengths */
+ cblk_len = 0;
+ for (i = 0; i < cblk->numchunks; i++) {
+ cblk_len += cblk->chunks[i].len;
+ }
+
+ /* Allocate temporary memory if needed */
+ if (cblk_len + OPJ_COMMON_CBLK_DATA_EXTRA > t1->cblkdatabuffersize) {
+ cblkdata = (OPJ_BYTE*)opj_realloc(t1->cblkdatabuffer,
+ cblk_len + OPJ_COMMON_CBLK_DATA_EXTRA);
+ if (cblkdata == NULL) {
+ return OPJ_FALSE;
+ }
+ t1->cblkdatabuffer = cblkdata;
+ memset(t1->cblkdatabuffer + cblk_len, 0, OPJ_COMMON_CBLK_DATA_EXTRA);
+ t1->cblkdatabuffersize = cblk_len + OPJ_COMMON_CBLK_DATA_EXTRA;
+ }
+
+ /* Concatenate all chunks */
+ cblkdata = t1->cblkdatabuffer;
+ cblk_len = 0;
+ for (i = 0; i < cblk->numchunks; i++) {
+ memcpy(cblkdata + cblk_len, cblk->chunks[i].data, cblk->chunks[i].len);
+ cblk_len += cblk->chunks[i].len;
+ }
+ } else if (cblk->numchunks == 1) {
+ cblkdata = cblk->chunks[0].data;
+ }
+
+ /* For subtile decoding, directly decode in the decoded_data buffer of */
+ /* the code-block. Hack t1->data to point to it, and restore it later */
+ if (cblk->decoded_data) {
+ original_t1_data = t1->data;
+ t1->data = cblk->decoded_data;
+ }
+
+ for (segno = 0; segno < cblk->real_num_segs; ++segno) {
+ opj_tcd_seg_t *seg = &cblk->segs[segno];
+
+ /* BYPASS mode */
+ type = ((bpno_plus_one <= ((OPJ_INT32)(cblk->numbps)) - 4) && (passtype < 2) &&
+ (cblksty & J2K_CCP_CBLKSTY_LAZY)) ? T1_TYPE_RAW : T1_TYPE_MQ;
+
+ if (type == T1_TYPE_RAW) {
+ opj_mqc_raw_init_dec(mqc, cblkdata + cblkdataindex, seg->len,
+ OPJ_COMMON_CBLK_DATA_EXTRA);
+ } else {
+ opj_mqc_init_dec(mqc, cblkdata + cblkdataindex, seg->len,
+ OPJ_COMMON_CBLK_DATA_EXTRA);
+ }
+ cblkdataindex += seg->len;
+
+ for (passno = 0; (passno < seg->real_num_passes) &&
+ (bpno_plus_one >= 1); ++passno) {
+ switch (passtype) {
+ case 0:
+ if (type == T1_TYPE_RAW) {
+ opj_t1_dec_sigpass_raw(t1, bpno_plus_one, (OPJ_INT32)cblksty);
+ } else {
+ opj_t1_dec_sigpass_mqc(t1, bpno_plus_one, (OPJ_INT32)cblksty);
+ }
+ break;
+ case 1:
+ if (type == T1_TYPE_RAW) {
+ opj_t1_dec_refpass_raw(t1, bpno_plus_one);
+ } else {
+ opj_t1_dec_refpass_mqc(t1, bpno_plus_one);
+ }
+ break;
+ case 2:
+ opj_t1_dec_clnpass(t1, bpno_plus_one, (OPJ_INT32)cblksty);
+ break;
+ }
+
+ if ((cblksty & J2K_CCP_CBLKSTY_RESET) && type == T1_TYPE_MQ) {
+ opj_mqc_resetstates(mqc);
+ opj_mqc_setstate(mqc, T1_CTXNO_UNI, 0, 46);
+ opj_mqc_setstate(mqc, T1_CTXNO_AGG, 0, 3);
+ opj_mqc_setstate(mqc, T1_CTXNO_ZC, 0, 4);
+ }
+ if (++passtype == 3) {
+ passtype = 0;
+ bpno_plus_one--;
+ }
+ }
+
+ 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);