summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lib/openjp2/t1.c89
-rw-r--r--src/lib/openjp2/t1.h10
-rw-r--r--src/lib/openjp2/t2.c17
-rw-r--r--src/lib/openjp2/tcd.c17
-rw-r--r--src/lib/openjp2/tcd.h58
5 files changed, 99 insertions, 92 deletions
diff --git a/src/lib/openjp2/t1.c b/src/lib/openjp2/t1.c
index f932599b..bd1a8800 100644
--- a/src/lib/openjp2/t1.c
+++ b/src/lib/openjp2/t1.c
@@ -1604,7 +1604,7 @@ void opj_t1_destroy(opj_t1_t *p_t1)
p_t1->flags = 00;
}
- opj_free(p_t1->segdatabuffer);
+ opj_free(p_t1->cblkdatabuffer);
opj_free(p_t1);
}
@@ -1615,7 +1615,7 @@ typedef struct {
opj_tcd_band_t* band;
opj_tcd_tilecomp_t* tilec;
opj_tccp_t* tccp;
- OPJ_BOOL mustuse_segdatabuffer;
+ OPJ_BOOL mustuse_cblkdatabuffer;
volatile OPJ_BOOL* pret;
opj_event_mgr_t *p_manager;
opj_mutex_t* p_manager_mutex;
@@ -1660,7 +1660,7 @@ static void opj_t1_clbl_decode_processor(void* user_data, opj_tls_t* tls)
t1 = opj_t1_create(OPJ_FALSE);
opj_tls_set(tls, OPJ_TLS_KEY_T1, t1, opj_t1_destroy_wrapper);
}
- t1->mustuse_segdatabuffer = job->mustuse_segdatabuffer;
+ t1->mustuse_cblkdatabuffer = job->mustuse_cblkdatabuffer;
if (OPJ_FALSE == opj_t1_decode_cblk(
t1,
@@ -1790,7 +1790,7 @@ void opj_t1_decode_cblks(opj_thread_pool_t* tp,
job->p_manager_mutex = p_manager_mutex;
job->p_manager = p_manager;
job->check_pterm = check_pterm;
- job->mustuse_segdatabuffer = opj_thread_pool_get_thread_count(tp) > 1;
+ 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;
@@ -1818,6 +1818,8 @@ static OPJ_BOOL opj_t1_decode_cblk(opj_t1_t *t1,
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);
@@ -1849,58 +1851,57 @@ static OPJ_BOOL opj_t1_decode_cblk(opj_t1_t *t1,
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];
- OPJ_BYTE* segdata;
- OPJ_UINT32 seglen;
/* BYPASS mode */
type = ((bpno_plus_one <= ((OPJ_INT32)(cblk->numbps)) - 4) && (passtype < 2) &&
(cblksty & J2K_CCP_CBLKSTY_LAZY)) ? T1_TYPE_RAW : T1_TYPE_MQ;
- /* Even if we have a single chunk, in mulithtreaded decoding */
- /* the insertion of our synthetic marker might potentially override */
- /* valid codestream of other codeblocks decoded in parallel. */
- if (seg->numchunks == 1 && !(t1->mustuse_segdatabuffer)) {
- segdata = seg->chunks[0].data;
- seglen = seg->chunks[0].len;
- } else {
- OPJ_UINT32 i;
-
- /* Compute whole segment length from chunk lengths */
- seglen = 0;
- for (i = 0; i < seg->numchunks; i++) {
- seglen += seg->chunks[i].len;
- }
-
- /* Allocate temporary memory if needed */
- if (seglen + OPJ_COMMON_CBLK_DATA_EXTRA > t1->segdatabuffersize) {
- segdata = (OPJ_BYTE*)opj_realloc(t1->segdatabuffer,
- seglen + OPJ_COMMON_CBLK_DATA_EXTRA);
- if (segdata == NULL) {
- return OPJ_FALSE;
- }
- t1->segdatabuffer = segdata;
- memset(t1->segdatabuffer + seglen, 0, OPJ_COMMON_CBLK_DATA_EXTRA);
- t1->segdatabuffersize = seglen + OPJ_COMMON_CBLK_DATA_EXTRA;
- }
-
- /* Concatenate all segments chunks */
- segdata = t1->segdatabuffer;
- seglen = 0;
- for (i = 0; i < seg->numchunks; i++) {
- memcpy(segdata + seglen, seg->chunks[i].data, seg->chunks[i].len);
- seglen += seg->chunks[i].len;
- }
- }
-
if (type == T1_TYPE_RAW) {
- opj_mqc_raw_init_dec(mqc, segdata, seglen,
+ opj_mqc_raw_init_dec(mqc, cblkdata + cblkdataindex, seg->len,
OPJ_COMMON_CBLK_DATA_EXTRA);
} else {
- opj_mqc_init_dec(mqc, segdata, seglen,
+ 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) {
diff --git a/src/lib/openjp2/t1.h b/src/lib/openjp2/t1.h
index da8b0c80..5aa6a07b 100644
--- a/src/lib/openjp2/t1.h
+++ b/src/lib/openjp2/t1.h
@@ -202,10 +202,12 @@ typedef struct opj_t1 {
OPJ_BOOL encoder;
/* Thre 3 variables below are only used by the decoder */
- OPJ_BOOL mustuse_segdatabuffer; /* set to TRUE in multithreaded context */
- OPJ_BYTE
- *segdatabuffer; /* Temporary buffer to concatenate all chunks of a segment */
- OPJ_UINT32 segdatabuffersize; /* Maximum size available in segdatabuffer */
+ /* set to TRUE in multithreaded context */
+ OPJ_BOOL mustuse_cblkdatabuffer;
+ /* Temporary buffer to concatenate all chunks of a codebock */
+ OPJ_BYTE *cblkdatabuffer;
+ /* Maximum size available in cblkdatabuffer */
+ OPJ_UINT32 cblkdatabuffersize;
} opj_t1_t;
/** @name Exported functions */
diff --git a/src/lib/openjp2/t2.c b/src/lib/openjp2/t2.c
index 5d5e33ea..c8cfcc26 100644
--- a/src/lib/openjp2/t2.c
+++ b/src/lib/openjp2/t2.c
@@ -1287,25 +1287,26 @@ static OPJ_BOOL opj_t2_read_packet_data(opj_t2_t* p_t2,
#endif /* USE_JPWL */
- if (l_seg->numchunks == l_seg->numchunksalloc) {
- OPJ_UINT32 l_numchunksalloc = l_seg->numchunksalloc * 2 + 1;
+ if (l_cblk->numchunks == l_cblk->numchunksalloc) {
+ OPJ_UINT32 l_numchunksalloc = l_cblk->numchunksalloc * 2 + 1;
opj_tcd_seg_data_chunk_t* l_chunks =
- (opj_tcd_seg_data_chunk_t*)opj_realloc(l_seg->chunks,
+ (opj_tcd_seg_data_chunk_t*)opj_realloc(l_cblk->chunks,
l_numchunksalloc * sizeof(opj_tcd_seg_data_chunk_t));
if (l_chunks == NULL) {
opj_event_msg(p_manager, EVT_ERROR,
"cannot allocate opj_tcd_seg_data_chunk_t* array");
return OPJ_FALSE;
}
- l_seg->chunks = l_chunks;
- l_seg->numchunksalloc = l_numchunksalloc;
+ l_cblk->chunks = l_chunks;
+ l_cblk->numchunksalloc = l_numchunksalloc;
}
- l_seg->chunks[l_seg->numchunks].data = l_current_data;
- l_seg->chunks[l_seg->numchunks].len = l_seg->newlen;
- l_seg->numchunks ++;
+ l_cblk->chunks[l_cblk->numchunks].data = l_current_data;
+ l_cblk->chunks[l_cblk->numchunks].len = l_seg->newlen;
+ l_cblk->numchunks ++;
l_current_data += l_seg->newlen;
+ l_seg->len += l_seg->newlen;
l_seg->numpasses += l_seg->numnewpasses;
l_cblk->numnewpasses -= l_seg->numnewpasses;
diff --git a/src/lib/openjp2/tcd.c b/src/lib/openjp2/tcd.c
index 4c4839d0..dd9faced 100644
--- a/src/lib/openjp2/tcd.c
+++ b/src/lib/openjp2/tcd.c
@@ -1213,11 +1213,7 @@ static OPJ_BOOL opj_tcd_code_block_enc_allocate_data(opj_tcd_cblk_enc_t *
void opj_tcd_reinit_segment(opj_tcd_seg_t* seg)
{
- opj_tcd_seg_data_chunk_t *l_chunks = seg->chunks;
- OPJ_UINT32 l_numchunksalloc = seg->numchunksalloc;
memset(seg, 0, sizeof(opj_tcd_seg_t));
- seg->chunks = l_chunks;
- seg->numchunksalloc = l_numchunksalloc;
}
/**
@@ -1241,6 +1237,8 @@ static OPJ_BOOL opj_tcd_code_block_dec_allocate(opj_tcd_cblk_dec_t *
/* sanitize */
opj_tcd_seg_t * l_segs = p_code_block->segs;
OPJ_UINT32 l_current_max_segs = p_code_block->m_current_max_segs;
+ opj_tcd_seg_data_chunk_t* l_chunks = p_code_block->chunks;
+ OPJ_UINT32 l_numchunksalloc = p_code_block->numchunksalloc;
OPJ_UINT32 i;
memset(p_code_block, 0, sizeof(opj_tcd_cblk_dec_t));
@@ -1249,6 +1247,8 @@ static OPJ_BOOL opj_tcd_code_block_dec_allocate(opj_tcd_cblk_dec_t *
for (i = 0; i < l_current_max_segs; ++i) {
opj_tcd_reinit_segment(&l_segs[i]);
}
+ p_code_block->chunks = l_chunks;
+ p_code_block->numchunksalloc = l_numchunksalloc;
}
return OPJ_TRUE;
@@ -1952,14 +1952,15 @@ static void opj_tcd_code_block_dec_deallocate(opj_tcd_precinct_t * p_precinct)
for (cblkno = 0; cblkno < l_nb_code_blocks; ++cblkno) {
if (l_code_block->segs) {
- OPJ_UINT32 i;
- for (i = 0; i < l_code_block->m_current_max_segs; ++ i) {
- opj_free(l_code_block->segs[i].chunks);
- }
opj_free(l_code_block->segs);
l_code_block->segs = 00;
}
+ if (l_code_block->chunks) {
+ opj_free(l_code_block->chunks);
+ l_code_block->chunks = 00;
+ }
+
++l_code_block;
}
diff --git a/src/lib/openjp2/tcd.h b/src/lib/openjp2/tcd.h
index 0de888d5..29cd8829 100644
--- a/src/lib/openjp2/tcd.h
+++ b/src/lib/openjp2/tcd.h
@@ -89,12 +89,12 @@ typedef struct opj_tcd_cblk_enc {
} opj_tcd_cblk_enc_t;
-/** Chunk of codestream data that is part of a T1 segment */
+/** Chunk of codestream data that is part of a code block */
typedef struct opj_tcd_seg_data_chunk {
- OPJ_BYTE *
- data; /* Point to tilepart buffer. We don't make a copy !
- So the tilepart buffer must be kept alive
- as long as we need to decode the codeblocks */
+ /* Point to tilepart buffer. We don't make a copy !
+ So the tilepart buffer must be kept alive
+ as long as we need to decode the codeblocks */
+ OPJ_BYTE * data;
OPJ_UINT32 len; /* Usable length of data */
} opj_tcd_seg_data_chunk_t;
@@ -102,35 +102,37 @@ typedef struct opj_tcd_seg_data_chunk {
* A segment represent a number of consecutive coding passes, without termination
* of MQC or RAW between them. */
typedef struct opj_tcd_seg {
- opj_tcd_seg_data_chunk_t* chunks; /* Array of chunks */
- OPJ_UINT32 numchunks; /* Number of valid chunks items */
- OPJ_UINT32 numchunksalloc; /* Number of chunks item allocated */
- OPJ_UINT32
- numpasses; /* Number of passes decoded. Including those that we skip */
- OPJ_UINT32
- real_num_passes; /* Number of passes actually to be decoded. To be used for code-block decoding */
- OPJ_UINT32 maxpasses; /* Maximum number of passes for this segment */
- OPJ_UINT32
- numnewpasses; /* Number of new passes for current packed. Transitory value */
- OPJ_UINT32
- newlen; /* Codestream length for this segment for current packed. Transitory value */
+ OPJ_UINT32 len; /* Size of data related to this segment */
+ /* Number of passes decoded. Including those that we skip */
+ OPJ_UINT32 numpasses;
+ /* Number of passes actually to be decoded. To be used for code-block decoding */
+ OPJ_UINT32 real_num_passes;
+ /* Maximum number of passes for this segment */
+ OPJ_UINT32 maxpasses;
+ /* Number of new passes for current packed. Transitory value */
+ OPJ_UINT32 numnewpasses;
+ /* Codestream length for this segment for current packed. Transitory value */
+ OPJ_UINT32 newlen;
} opj_tcd_seg_t;
/* Code-block for decoding */
typedef struct opj_tcd_cblk_dec {
opj_tcd_seg_t* segs; /* segments information */
- OPJ_INT32 x0, y0, x1,
- y1; /* position of the code-blocks : left upper corner (x0, y0) right low corner (x1,y1) */
+ opj_tcd_seg_data_chunk_t* chunks; /* Array of chunks */
+ /* position of the code-blocks : left upper corner (x0, y0) right low corner (x1,y1) */
+ OPJ_INT32 x0, y0, x1, y1;
OPJ_UINT32 numbps;
- OPJ_UINT32
- numlenbits; /* number of bits for len,, for the current packet. Transitory value */
- OPJ_UINT32
- numnewpasses; /* number of pass added to the code-blocks, for the current packet. Transitory value */
- OPJ_UINT32
- numsegs; /* number of segments, including those of packet we skip */
- OPJ_UINT32
- real_num_segs; /* number of segments, to be used for code block decoding */
+ /* number of bits for len, for the current packet. Transitory value */
+ OPJ_UINT32 numlenbits;
+ /* number of pass added to the code-blocks, for the current packet. Transitory value */
+ OPJ_UINT32 numnewpasses;
+ /* number of segments, including those of packet we skip */
+ OPJ_UINT32 numsegs;
+ /* number of segments, to be used for code block decoding */
+ OPJ_UINT32 real_num_segs;
OPJ_UINT32 m_current_max_segs; /* allocated number of segs[] items */
+ OPJ_UINT32 numchunks; /* Number of valid chunks items */
+ OPJ_UINT32 numchunksalloc; /* Number of chunks item allocated */
} opj_tcd_cblk_dec_t;
/**
@@ -397,7 +399,7 @@ OPJ_BOOL opj_alloc_tile_component_data(opj_tcd_tilecomp_t *l_tilec);
*/
OPJ_BOOL opj_tcd_is_band_empty(opj_tcd_band_t* band);
-/** Reinitialize a segment, without deallocating its chunks array */
+/** Reinitialize a segment */
void opj_tcd_reinit_segment(opj_tcd_seg_t* seg);
/* ----------------------------------------------------------------------- */