p_t1->flags = 00;
}
+ opj_free(p_t1->cblkdatabuffer);
+
opj_free(p_t1);
}
opj_tcd_band_t* band;
opj_tcd_tilecomp_t* tilec;
opj_tccp_t* tccp;
+ OPJ_BOOL mustuse_cblkdatabuffer;
volatile OPJ_BOOL* pret;
opj_event_mgr_t *p_manager;
opj_mutex_t* p_manager_mutex;
t1 = opj_t1_create(OPJ_FALSE);
opj_tls_set(tls, OPJ_TLS_KEY_T1, t1, opj_t1_destroy_wrapper);
}
+ t1->mustuse_cblkdatabuffer = job->mustuse_cblkdatabuffer;
if (OPJ_FALSE == opj_t1_decode_cblk(
t1,
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);
if (!(*pret)) {
return;
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 */
mqc->lut_ctxno_zc_orient = lut_ctxno_zc + (orient << 9);
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 (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;
- /* FIXME: slviewer gets here with a null pointer. Why? Partially downloaded and/or corrupt textures? */
- if (seg->data == 00) {
- continue;
- }
+
if (type == T1_TYPE_RAW) {
- opj_mqc_raw_init_dec(mqc, (*seg->data) + seg->dataindex, seg->len,
+ opj_mqc_raw_init_dec(mqc, cblkdata + cblkdataindex, seg->len,
OPJ_COMMON_CBLK_DATA_EXTRA);
} else {
- opj_mqc_init_dec(mqc, (*seg->data) + seg->dataindex, seg->len,
+ 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) {