Merge pull request #968 from rouault/reduce_memory_decoding
Reduce memory decoding
This commit is contained in:
commit
3b1b067266
|
@ -122,9 +122,9 @@ static void sycc444_to_rgb(opj_image_t *img)
|
||||||
cb = img->comps[1].data;
|
cb = img->comps[1].data;
|
||||||
cr = img->comps[2].data;
|
cr = img->comps[2].data;
|
||||||
|
|
||||||
d0 = r = (int*)malloc(sizeof(int) * max);
|
d0 = r = (int*)opj_image_data_alloc(sizeof(int) * max);
|
||||||
d1 = g = (int*)malloc(sizeof(int) * max);
|
d1 = g = (int*)opj_image_data_alloc(sizeof(int) * max);
|
||||||
d2 = b = (int*)malloc(sizeof(int) * max);
|
d2 = b = (int*)opj_image_data_alloc(sizeof(int) * max);
|
||||||
|
|
||||||
if (r == NULL || g == NULL || b == NULL) {
|
if (r == NULL || g == NULL || b == NULL) {
|
||||||
goto fails;
|
goto fails;
|
||||||
|
@ -139,19 +139,19 @@ static void sycc444_to_rgb(opj_image_t *img)
|
||||||
++g;
|
++g;
|
||||||
++b;
|
++b;
|
||||||
}
|
}
|
||||||
free(img->comps[0].data);
|
opj_image_data_free(img->comps[0].data);
|
||||||
img->comps[0].data = d0;
|
img->comps[0].data = d0;
|
||||||
free(img->comps[1].data);
|
opj_image_data_free(img->comps[1].data);
|
||||||
img->comps[1].data = d1;
|
img->comps[1].data = d1;
|
||||||
free(img->comps[2].data);
|
opj_image_data_free(img->comps[2].data);
|
||||||
img->comps[2].data = d2;
|
img->comps[2].data = d2;
|
||||||
img->color_space = OPJ_CLRSPC_SRGB;
|
img->color_space = OPJ_CLRSPC_SRGB;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
fails:
|
fails:
|
||||||
free(r);
|
opj_image_data_free(r);
|
||||||
free(g);
|
opj_image_data_free(g);
|
||||||
free(b);
|
opj_image_data_free(b);
|
||||||
}/* sycc444_to_rgb() */
|
}/* sycc444_to_rgb() */
|
||||||
|
|
||||||
static void sycc422_to_rgb(opj_image_t *img)
|
static void sycc422_to_rgb(opj_image_t *img)
|
||||||
|
@ -174,9 +174,9 @@ static void sycc422_to_rgb(opj_image_t *img)
|
||||||
cb = img->comps[1].data;
|
cb = img->comps[1].data;
|
||||||
cr = img->comps[2].data;
|
cr = img->comps[2].data;
|
||||||
|
|
||||||
d0 = r = (int*)malloc(sizeof(int) * max);
|
d0 = r = (int*)opj_image_data_alloc(sizeof(int) * max);
|
||||||
d1 = g = (int*)malloc(sizeof(int) * max);
|
d1 = g = (int*)opj_image_data_alloc(sizeof(int) * max);
|
||||||
d2 = b = (int*)malloc(sizeof(int) * max);
|
d2 = b = (int*)opj_image_data_alloc(sizeof(int) * max);
|
||||||
|
|
||||||
if (r == NULL || g == NULL || b == NULL) {
|
if (r == NULL || g == NULL || b == NULL) {
|
||||||
goto fails;
|
goto fails;
|
||||||
|
@ -222,11 +222,11 @@ static void sycc422_to_rgb(opj_image_t *img)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
free(img->comps[0].data);
|
opj_image_data_free(img->comps[0].data);
|
||||||
img->comps[0].data = d0;
|
img->comps[0].data = d0;
|
||||||
free(img->comps[1].data);
|
opj_image_data_free(img->comps[1].data);
|
||||||
img->comps[1].data = d1;
|
img->comps[1].data = d1;
|
||||||
free(img->comps[2].data);
|
opj_image_data_free(img->comps[2].data);
|
||||||
img->comps[2].data = d2;
|
img->comps[2].data = d2;
|
||||||
|
|
||||||
img->comps[1].w = img->comps[2].w = img->comps[0].w;
|
img->comps[1].w = img->comps[2].w = img->comps[0].w;
|
||||||
|
@ -237,9 +237,9 @@ static void sycc422_to_rgb(opj_image_t *img)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
fails:
|
fails:
|
||||||
free(r);
|
opj_image_data_free(r);
|
||||||
free(g);
|
opj_image_data_free(g);
|
||||||
free(b);
|
opj_image_data_free(b);
|
||||||
}/* sycc422_to_rgb() */
|
}/* sycc422_to_rgb() */
|
||||||
|
|
||||||
static void sycc420_to_rgb(opj_image_t *img)
|
static void sycc420_to_rgb(opj_image_t *img)
|
||||||
|
@ -262,9 +262,9 @@ static void sycc420_to_rgb(opj_image_t *img)
|
||||||
cb = img->comps[1].data;
|
cb = img->comps[1].data;
|
||||||
cr = img->comps[2].data;
|
cr = img->comps[2].data;
|
||||||
|
|
||||||
d0 = r = (int*)malloc(sizeof(int) * max);
|
d0 = r = (int*)opj_image_data_alloc(sizeof(int) * max);
|
||||||
d1 = g = (int*)malloc(sizeof(int) * max);
|
d1 = g = (int*)opj_image_data_alloc(sizeof(int) * max);
|
||||||
d2 = b = (int*)malloc(sizeof(int) * max);
|
d2 = b = (int*)opj_image_data_alloc(sizeof(int) * max);
|
||||||
|
|
||||||
if (r == NULL || g == NULL || b == NULL) {
|
if (r == NULL || g == NULL || b == NULL) {
|
||||||
goto fails;
|
goto fails;
|
||||||
|
@ -380,11 +380,11 @@ static void sycc420_to_rgb(opj_image_t *img)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
free(img->comps[0].data);
|
opj_image_data_free(img->comps[0].data);
|
||||||
img->comps[0].data = d0;
|
img->comps[0].data = d0;
|
||||||
free(img->comps[1].data);
|
opj_image_data_free(img->comps[1].data);
|
||||||
img->comps[1].data = d1;
|
img->comps[1].data = d1;
|
||||||
free(img->comps[2].data);
|
opj_image_data_free(img->comps[2].data);
|
||||||
img->comps[2].data = d2;
|
img->comps[2].data = d2;
|
||||||
|
|
||||||
img->comps[1].w = img->comps[2].w = img->comps[0].w;
|
img->comps[1].w = img->comps[2].w = img->comps[0].w;
|
||||||
|
@ -395,9 +395,9 @@ static void sycc420_to_rgb(opj_image_t *img)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
fails:
|
fails:
|
||||||
free(r);
|
opj_image_data_free(r);
|
||||||
free(g);
|
opj_image_data_free(g);
|
||||||
free(b);
|
opj_image_data_free(b);
|
||||||
}/* sycc420_to_rgb() */
|
}/* sycc420_to_rgb() */
|
||||||
|
|
||||||
void color_sycc_to_rgb(opj_image_t *img)
|
void color_sycc_to_rgb(opj_image_t *img)
|
||||||
|
@ -574,8 +574,8 @@ void color_apply_icc_profile(opj_image_t *image)
|
||||||
|
|
||||||
max = max_w * max_h;
|
max = max_w * max_h;
|
||||||
nr_samples = (size_t)(max * 3U * sizeof(unsigned char));
|
nr_samples = (size_t)(max * 3U * sizeof(unsigned char));
|
||||||
in = inbuf = (unsigned char*)malloc(nr_samples);
|
in = inbuf = (unsigned char*)opj_image_data_alloc(nr_samples);
|
||||||
out = outbuf = (unsigned char*)malloc(nr_samples);
|
out = outbuf = (unsigned char*)opj_image_data_alloc(nr_samples);
|
||||||
|
|
||||||
if (inbuf == NULL || outbuf == NULL) {
|
if (inbuf == NULL || outbuf == NULL) {
|
||||||
goto fails0;
|
goto fails0;
|
||||||
|
@ -605,15 +605,15 @@ void color_apply_icc_profile(opj_image_t *image)
|
||||||
ok = 1;
|
ok = 1;
|
||||||
|
|
||||||
fails0:
|
fails0:
|
||||||
free(inbuf);
|
opj_image_data_free(inbuf);
|
||||||
free(outbuf);
|
opj_image_data_free(outbuf);
|
||||||
} else { /* prec > 8 */
|
} else { /* prec > 8 */
|
||||||
unsigned short *inbuf, *outbuf, *in, *out;
|
unsigned short *inbuf, *outbuf, *in, *out;
|
||||||
|
|
||||||
max = max_w * max_h;
|
max = max_w * max_h;
|
||||||
nr_samples = (size_t)(max * 3U * sizeof(unsigned short));
|
nr_samples = (size_t)(max * 3U * sizeof(unsigned short));
|
||||||
in = inbuf = (unsigned short*)malloc(nr_samples);
|
in = inbuf = (unsigned short*)opj_image_data_alloc(nr_samples);
|
||||||
out = outbuf = (unsigned short*)malloc(nr_samples);
|
out = outbuf = (unsigned short*)opj_image_data_alloc(nr_samples);
|
||||||
|
|
||||||
if (inbuf == NULL || outbuf == NULL) {
|
if (inbuf == NULL || outbuf == NULL) {
|
||||||
goto fails1;
|
goto fails1;
|
||||||
|
@ -643,8 +643,8 @@ fails0:
|
||||||
ok = 1;
|
ok = 1;
|
||||||
|
|
||||||
fails1:
|
fails1:
|
||||||
free(inbuf);
|
opj_image_data_free(inbuf);
|
||||||
free(outbuf);
|
opj_image_data_free(outbuf);
|
||||||
}
|
}
|
||||||
} else { /* image->numcomps <= 2 : GRAY, GRAYA */
|
} else { /* image->numcomps <= 2 : GRAY, GRAYA */
|
||||||
if (prec <= 8) {
|
if (prec <= 8) {
|
||||||
|
@ -653,10 +653,10 @@ fails1:
|
||||||
|
|
||||||
max = max_w * max_h;
|
max = max_w * max_h;
|
||||||
nr_samples = (size_t)(max * 3 * sizeof(unsigned char));
|
nr_samples = (size_t)(max * 3 * sizeof(unsigned char));
|
||||||
in = inbuf = (unsigned char*)malloc(nr_samples);
|
in = inbuf = (unsigned char*)opj_image_data_alloc(nr_samples);
|
||||||
out = outbuf = (unsigned char*)malloc(nr_samples);
|
out = outbuf = (unsigned char*)opj_image_data_alloc(nr_samples);
|
||||||
g = (int*)calloc((size_t)max, sizeof(int));
|
g = (int*)opj_image_data_alloc((size_t)max * sizeof(int));
|
||||||
b = (int*)calloc((size_t)max, sizeof(int));
|
b = (int*)opj_image_data_alloc((size_t)max * sizeof(int));
|
||||||
|
|
||||||
if (inbuf == NULL || outbuf == NULL || g == NULL || b == NULL) {
|
if (inbuf == NULL || outbuf == NULL || g == NULL || b == NULL) {
|
||||||
goto fails2;
|
goto fails2;
|
||||||
|
@ -703,20 +703,20 @@ fails1:
|
||||||
ok = 1;
|
ok = 1;
|
||||||
|
|
||||||
fails2:
|
fails2:
|
||||||
free(inbuf);
|
opj_image_data_free(inbuf);
|
||||||
free(outbuf);
|
opj_image_data_free(outbuf);
|
||||||
free(g);
|
opj_image_data_free(g);
|
||||||
free(b);
|
opj_image_data_free(b);
|
||||||
} else { /* prec > 8 */
|
} else { /* prec > 8 */
|
||||||
unsigned short *in, *inbuf, *out, *outbuf;
|
unsigned short *in, *inbuf, *out, *outbuf;
|
||||||
opj_image_comp_t *new_comps;
|
opj_image_comp_t *new_comps;
|
||||||
|
|
||||||
max = max_w * max_h;
|
max = max_w * max_h;
|
||||||
nr_samples = (size_t)(max * 3U * sizeof(unsigned short));
|
nr_samples = (size_t)(max * 3U * sizeof(unsigned short));
|
||||||
in = inbuf = (unsigned short*)malloc(nr_samples);
|
in = inbuf = (unsigned short*)opj_image_data_alloc(nr_samples);
|
||||||
out = outbuf = (unsigned short*)malloc(nr_samples);
|
out = outbuf = (unsigned short*)opj_image_data_alloc(nr_samples);
|
||||||
g = (int*)calloc((size_t)max, sizeof(int));
|
g = (int*)opj_image_data_alloc((size_t)max * sizeof(int));
|
||||||
b = (int*)calloc((size_t)max, sizeof(int));
|
b = (int*)opj_image_data_alloc((size_t)max * sizeof(int));
|
||||||
|
|
||||||
if (inbuf == NULL || outbuf == NULL || g == NULL || b == NULL) {
|
if (inbuf == NULL || outbuf == NULL || g == NULL || b == NULL) {
|
||||||
goto fails3;
|
goto fails3;
|
||||||
|
@ -763,10 +763,10 @@ fails2:
|
||||||
ok = 1;
|
ok = 1;
|
||||||
|
|
||||||
fails3:
|
fails3:
|
||||||
free(inbuf);
|
opj_image_data_free(inbuf);
|
||||||
free(outbuf);
|
opj_image_data_free(outbuf);
|
||||||
free(g);
|
opj_image_data_free(g);
|
||||||
free(b);
|
opj_image_data_free(b);
|
||||||
}
|
}
|
||||||
}/* if(image->numcomps > 2) */
|
}/* if(image->numcomps > 2) */
|
||||||
|
|
||||||
|
@ -881,9 +881,9 @@ void color_cielab_to_rgb(opj_image_t *image)
|
||||||
|
|
||||||
max = image->comps[0].w * image->comps[0].h;
|
max = image->comps[0].w * image->comps[0].h;
|
||||||
|
|
||||||
red = dst0 = (int*)malloc(max * sizeof(int));
|
red = dst0 = (int*)opj_image_data_alloc(max * sizeof(int));
|
||||||
green = dst1 = (int*)malloc(max * sizeof(int));
|
green = dst1 = (int*)opj_image_data_alloc(max * sizeof(int));
|
||||||
blue = dst2 = (int*)malloc(max * sizeof(int));
|
blue = dst2 = (int*)opj_image_data_alloc(max * sizeof(int));
|
||||||
|
|
||||||
if (red == NULL || green == NULL || blue == NULL) {
|
if (red == NULL || green == NULL || blue == NULL) {
|
||||||
goto fails;
|
goto fails;
|
||||||
|
@ -917,11 +917,11 @@ void color_cielab_to_rgb(opj_image_t *image)
|
||||||
cmsCloseProfile(in);
|
cmsCloseProfile(in);
|
||||||
cmsCloseProfile(out);
|
cmsCloseProfile(out);
|
||||||
#endif
|
#endif
|
||||||
free(src0);
|
opj_image_data_free(src0);
|
||||||
image->comps[0].data = dst0;
|
image->comps[0].data = dst0;
|
||||||
free(src1);
|
opj_image_data_free(src1);
|
||||||
image->comps[1].data = dst1;
|
image->comps[1].data = dst1;
|
||||||
free(src2);
|
opj_image_data_free(src2);
|
||||||
image->comps[2].data = dst2;
|
image->comps[2].data = dst2;
|
||||||
|
|
||||||
image->color_space = new_space;
|
image->color_space = new_space;
|
||||||
|
@ -938,13 +938,13 @@ fails:
|
||||||
cmsCloseProfile(out);
|
cmsCloseProfile(out);
|
||||||
#endif
|
#endif
|
||||||
if (red) {
|
if (red) {
|
||||||
free(red);
|
opj_image_data_free(red);
|
||||||
}
|
}
|
||||||
if (green) {
|
if (green) {
|
||||||
free(green);
|
opj_image_data_free(green);
|
||||||
}
|
}
|
||||||
if (blue) {
|
if (blue) {
|
||||||
free(blue);
|
opj_image_data_free(blue);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1004,7 +1004,7 @@ void color_cmyk_to_rgb(opj_image_t *image)
|
||||||
image->comps[2].data[i] = (int)(255.0F * Y * K); /* B */
|
image->comps[2].data[i] = (int)(255.0F * Y * K); /* B */
|
||||||
}
|
}
|
||||||
|
|
||||||
free(image->comps[3].data);
|
opj_image_data_free(image->comps[3].data);
|
||||||
image->comps[3].data = NULL;
|
image->comps[3].data = NULL;
|
||||||
image->comps[0].prec = 8;
|
image->comps[0].prec = 8;
|
||||||
image->comps[1].prec = 8;
|
image->comps[1].prec = 8;
|
||||||
|
|
|
@ -68,19 +68,21 @@ opj_image_t* OPJ_CALLCONV opj_image_create(OPJ_UINT32 numcmpts,
|
||||||
comp->prec = cmptparms[compno].prec;
|
comp->prec = cmptparms[compno].prec;
|
||||||
comp->bpp = cmptparms[compno].bpp;
|
comp->bpp = cmptparms[compno].bpp;
|
||||||
comp->sgnd = cmptparms[compno].sgnd;
|
comp->sgnd = cmptparms[compno].sgnd;
|
||||||
if (comp->h != 0 && (OPJ_SIZE_T)comp->w > SIZE_MAX / comp->h) {
|
if (comp->h != 0 &&
|
||||||
|
(OPJ_SIZE_T)comp->w > SIZE_MAX / comp->h / sizeof(OPJ_INT32)) {
|
||||||
// TODO event manager
|
// TODO event manager
|
||||||
opj_image_destroy(image);
|
opj_image_destroy(image);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
comp->data = (OPJ_INT32*) opj_calloc((OPJ_SIZE_T)comp->w * comp->h,
|
comp->data = (OPJ_INT32*) opj_image_data_alloc(
|
||||||
sizeof(OPJ_INT32));
|
(size_t)comp->w * comp->h * sizeof(OPJ_INT32));
|
||||||
if (!comp->data) {
|
if (!comp->data) {
|
||||||
/* TODO replace with event manager, breaks API */
|
/* TODO replace with event manager, breaks API */
|
||||||
/* fprintf(stderr,"Unable to allocate memory for image.\n"); */
|
/* fprintf(stderr,"Unable to allocate memory for image.\n"); */
|
||||||
opj_image_destroy(image);
|
opj_image_destroy(image);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
memset(comp->data, 0, (size_t)comp->w * comp->h * sizeof(OPJ_INT32));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,7 +99,7 @@ void OPJ_CALLCONV opj_image_destroy(opj_image_t *image)
|
||||||
for (compno = 0; compno < image->numcomps; compno++) {
|
for (compno = 0; compno < image->numcomps; compno++) {
|
||||||
opj_image_comp_t *image_comp = &(image->comps[compno]);
|
opj_image_comp_t *image_comp = &(image->comps[compno]);
|
||||||
if (image_comp->data) {
|
if (image_comp->data) {
|
||||||
opj_free(image_comp->data);
|
opj_image_data_free(image_comp->data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
opj_free(image->comps);
|
opj_free(image->comps);
|
||||||
|
|
|
@ -4684,15 +4684,35 @@ static OPJ_BOOL opj_j2k_read_sod(opj_j2k_t *p_j2k,
|
||||||
"Tile part length size inconsistent with stream length\n");
|
"Tile part length size inconsistent with stream length\n");
|
||||||
return OPJ_FALSE;
|
return OPJ_FALSE;
|
||||||
}
|
}
|
||||||
|
if (p_j2k->m_specific_param.m_decoder.m_sot_length >
|
||||||
|
UINT_MAX - OPJ_COMMON_CBLK_DATA_EXTRA) {
|
||||||
|
opj_event_msg(p_manager, EVT_ERROR,
|
||||||
|
"p_j2k->m_specific_param.m_decoder.m_sot_length > "
|
||||||
|
"UINT_MAX - OPJ_COMMON_CBLK_DATA_EXTRA");
|
||||||
|
return OPJ_FALSE;
|
||||||
|
}
|
||||||
|
/* Add a margin of OPJ_COMMON_CBLK_DATA_EXTRA to the allocation we */
|
||||||
|
/* do so that opj_mqc_init_dec_common() can safely add a synthetic */
|
||||||
|
/* 0xFFFF marker. */
|
||||||
if (! *l_current_data) {
|
if (! *l_current_data) {
|
||||||
/* LH: oddly enough, in this path, l_tile_len!=0.
|
/* LH: oddly enough, in this path, l_tile_len!=0.
|
||||||
* TODO: If this was consistent, we could simplify the code to only use realloc(), as realloc(0,...) default to malloc(0,...).
|
* TODO: If this was consistent, we could simplify the code to only use realloc(), as realloc(0,...) default to malloc(0,...).
|
||||||
*/
|
*/
|
||||||
*l_current_data = (OPJ_BYTE*) opj_malloc(
|
*l_current_data = (OPJ_BYTE*) opj_malloc(
|
||||||
p_j2k->m_specific_param.m_decoder.m_sot_length);
|
p_j2k->m_specific_param.m_decoder.m_sot_length + OPJ_COMMON_CBLK_DATA_EXTRA);
|
||||||
} else {
|
} else {
|
||||||
OPJ_BYTE *l_new_current_data = (OPJ_BYTE *) opj_realloc(*l_current_data,
|
OPJ_BYTE *l_new_current_data;
|
||||||
*l_tile_len + p_j2k->m_specific_param.m_decoder.m_sot_length);
|
if (*l_tile_len > UINT_MAX - OPJ_COMMON_CBLK_DATA_EXTRA -
|
||||||
|
p_j2k->m_specific_param.m_decoder.m_sot_length) {
|
||||||
|
opj_event_msg(p_manager, EVT_ERROR,
|
||||||
|
"*l_tile_len > UINT_MAX - OPJ_COMMON_CBLK_DATA_EXTRA - "
|
||||||
|
"p_j2k->m_specific_param.m_decoder.m_sot_length");
|
||||||
|
return OPJ_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
l_new_current_data = (OPJ_BYTE *) opj_realloc(*l_current_data,
|
||||||
|
*l_tile_len + p_j2k->m_specific_param.m_decoder.m_sot_length +
|
||||||
|
OPJ_COMMON_CBLK_DATA_EXTRA);
|
||||||
if (! l_new_current_data) {
|
if (! l_new_current_data) {
|
||||||
opj_free(*l_current_data);
|
opj_free(*l_current_data);
|
||||||
/*nothing more is done as l_current_data will be set to null, and just
|
/*nothing more is done as l_current_data will be set to null, and just
|
||||||
|
@ -8716,6 +8736,10 @@ OPJ_BOOL opj_j2k_decode_tile(opj_j2k_t * p_j2k,
|
||||||
return OPJ_FALSE;
|
return OPJ_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* p_data can be set to NULL when the call will take care of using */
|
||||||
|
/* itself the TCD data. This is typically the case for whole single */
|
||||||
|
/* tile decoding optimization. */
|
||||||
|
if (p_data != NULL) {
|
||||||
if (! opj_tcd_update_tile_data(p_j2k->m_tcd, p_data, p_data_size)) {
|
if (! opj_tcd_update_tile_data(p_j2k->m_tcd, p_data, p_data_size)) {
|
||||||
return OPJ_FALSE;
|
return OPJ_FALSE;
|
||||||
}
|
}
|
||||||
|
@ -8725,6 +8749,7 @@ OPJ_BOOL opj_j2k_decode_tile(opj_j2k_t * p_j2k,
|
||||||
/*opj_j2k_tcp_destroy(l_tcp);
|
/*opj_j2k_tcp_destroy(l_tcp);
|
||||||
p_j2k->m_tcd->tcp = 0;*/
|
p_j2k->m_tcd->tcp = 0;*/
|
||||||
opj_j2k_tcp_data_destroy(l_tcp);
|
opj_j2k_tcp_data_destroy(l_tcp);
|
||||||
|
}
|
||||||
|
|
||||||
p_j2k->m_specific_param.m_decoder.m_can_decode = 0;
|
p_j2k->m_specific_param.m_decoder.m_can_decode = 0;
|
||||||
p_j2k->m_specific_param.m_decoder.m_state &= (~(OPJ_UINT32)J2K_STATE_DATA);
|
p_j2k->m_specific_param.m_decoder.m_state &= (~(OPJ_UINT32)J2K_STATE_DATA);
|
||||||
|
@ -8793,15 +8818,18 @@ static OPJ_BOOL opj_j2k_update_image_data(opj_tcd_t * p_tcd, OPJ_BYTE * p_data,
|
||||||
OPJ_SIZE_T l_width = l_img_comp_dest->w;
|
OPJ_SIZE_T l_width = l_img_comp_dest->w;
|
||||||
OPJ_SIZE_T l_height = l_img_comp_dest->h;
|
OPJ_SIZE_T l_height = l_img_comp_dest->h;
|
||||||
|
|
||||||
if ((l_height == 0U) || (l_width > (SIZE_MAX / l_height))) {
|
if ((l_height == 0U) || (l_width > (SIZE_MAX / l_height)) ||
|
||||||
|
l_width * l_height > SIZE_MAX / sizeof(OPJ_INT32)) {
|
||||||
/* would overflow */
|
/* would overflow */
|
||||||
return OPJ_FALSE;
|
return OPJ_FALSE;
|
||||||
}
|
}
|
||||||
l_img_comp_dest->data = (OPJ_INT32*) opj_calloc(l_width * l_height,
|
l_img_comp_dest->data = (OPJ_INT32*) opj_image_data_alloc(l_width * l_height *
|
||||||
sizeof(OPJ_INT32));
|
sizeof(OPJ_INT32));
|
||||||
if (! l_img_comp_dest->data) {
|
if (! l_img_comp_dest->data) {
|
||||||
return OPJ_FALSE;
|
return OPJ_FALSE;
|
||||||
}
|
}
|
||||||
|
/* Do we really need this memset ? */
|
||||||
|
memset(l_img_comp_dest->data, 0, l_width * l_height * sizeof(OPJ_INT32));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Copy info from decoded comp image to output image */
|
/* Copy info from decoded comp image to output image */
|
||||||
|
@ -10381,6 +10409,47 @@ static OPJ_BOOL opj_j2k_decode_tiles(opj_j2k_t *p_j2k,
|
||||||
OPJ_BYTE * l_current_data;
|
OPJ_BYTE * l_current_data;
|
||||||
OPJ_UINT32 nr_tiles = 0;
|
OPJ_UINT32 nr_tiles = 0;
|
||||||
|
|
||||||
|
/* Particular case for whole single tile decoding */
|
||||||
|
/* We can avoid allocating intermediate tile buffers */
|
||||||
|
if (p_j2k->m_cp.tw == 1 && p_j2k->m_cp.th == 1 &&
|
||||||
|
p_j2k->m_cp.tx0 == 0 && p_j2k->m_cp.ty0 == 0 &&
|
||||||
|
p_j2k->m_output_image->x0 == 0 &&
|
||||||
|
p_j2k->m_output_image->y0 == 0 &&
|
||||||
|
p_j2k->m_output_image->x1 == p_j2k->m_cp.tdx &&
|
||||||
|
p_j2k->m_output_image->y1 == p_j2k->m_cp.tdy &&
|
||||||
|
p_j2k->m_output_image->comps[0].factor == 0) {
|
||||||
|
OPJ_UINT32 i;
|
||||||
|
if (! opj_j2k_read_tile_header(p_j2k,
|
||||||
|
&l_current_tile_no,
|
||||||
|
&l_data_size,
|
||||||
|
&l_tile_x0, &l_tile_y0,
|
||||||
|
&l_tile_x1, &l_tile_y1,
|
||||||
|
&l_nb_comps,
|
||||||
|
&l_go_on,
|
||||||
|
p_stream,
|
||||||
|
p_manager)) {
|
||||||
|
return OPJ_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! opj_j2k_decode_tile(p_j2k, l_current_tile_no, NULL, 0,
|
||||||
|
p_stream, p_manager)) {
|
||||||
|
opj_event_msg(p_manager, EVT_ERROR, "Failed to decode tile 1/1\n");
|
||||||
|
return OPJ_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Transfer TCD data to output image data */
|
||||||
|
for (i = 0; i < p_j2k->m_output_image->numcomps; i++) {
|
||||||
|
opj_image_data_free(p_j2k->m_output_image->comps[i].data);
|
||||||
|
p_j2k->m_output_image->comps[i].data =
|
||||||
|
p_j2k->m_tcd->tcd_image->tiles->comps[i].data;
|
||||||
|
p_j2k->m_output_image->comps[i].resno_decoded =
|
||||||
|
p_j2k->m_tcd->image->comps[i].resno_decoded;
|
||||||
|
p_j2k->m_tcd->tcd_image->tiles->comps[i].data = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return OPJ_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
l_current_data = (OPJ_BYTE*)opj_malloc(1000);
|
l_current_data = (OPJ_BYTE*)opj_malloc(1000);
|
||||||
if (! l_current_data) {
|
if (! l_current_data) {
|
||||||
opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to decode tiles\n");
|
opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to decode tiles\n");
|
||||||
|
@ -10775,7 +10844,7 @@ OPJ_BOOL opj_j2k_get_tile(opj_j2k_t *p_j2k,
|
||||||
p_j2k->m_output_image->comps[compno].resno_decoded;
|
p_j2k->m_output_image->comps[compno].resno_decoded;
|
||||||
|
|
||||||
if (p_image->comps[compno].data) {
|
if (p_image->comps[compno].data) {
|
||||||
opj_free(p_image->comps[compno].data);
|
opj_image_data_free(p_image->comps[compno].data);
|
||||||
}
|
}
|
||||||
|
|
||||||
p_image->comps[compno].data = p_j2k->m_output_image->comps[compno].data;
|
p_image->comps[compno].data = p_j2k->m_output_image->comps[compno].data;
|
||||||
|
|
|
@ -1065,7 +1065,7 @@ static OPJ_BOOL opj_jp2_apply_pclr(opj_image_t *image,
|
||||||
|
|
||||||
/* Palette mapping: */
|
/* Palette mapping: */
|
||||||
new_comps[i].data = (OPJ_INT32*)
|
new_comps[i].data = (OPJ_INT32*)
|
||||||
opj_malloc(old_comps[cmp].w * old_comps[cmp].h * sizeof(OPJ_INT32));
|
opj_image_data_alloc(old_comps[cmp].w * old_comps[cmp].h * sizeof(OPJ_INT32));
|
||||||
if (!new_comps[i].data) {
|
if (!new_comps[i].data) {
|
||||||
while (i > 0) {
|
while (i > 0) {
|
||||||
-- i;
|
-- i;
|
||||||
|
@ -1119,7 +1119,7 @@ static OPJ_BOOL opj_jp2_apply_pclr(opj_image_t *image,
|
||||||
max = image->numcomps;
|
max = image->numcomps;
|
||||||
for (i = 0; i < max; ++i) {
|
for (i = 0; i < max; ++i) {
|
||||||
if (old_comps[i].data) {
|
if (old_comps[i].data) {
|
||||||
opj_free(old_comps[i].data);
|
opj_image_data_free(old_comps[i].data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1007,3 +1007,17 @@ opj_stream_t* OPJ_CALLCONV opj_stream_create_file_stream(
|
||||||
|
|
||||||
return l_stream;
|
return l_stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void* OPJ_CALLCONV opj_image_data_alloc(OPJ_SIZE_T size)
|
||||||
|
{
|
||||||
|
void* ret = opj_aligned_malloc(size);
|
||||||
|
/* printf("opj_image_data_alloc %p\n", ret); */
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OPJ_CALLCONV opj_image_data_free(void* ptr)
|
||||||
|
{
|
||||||
|
/* printf("opj_image_data_free %p\n", ptr); */
|
||||||
|
opj_aligned_free(ptr);
|
||||||
|
}
|
||||||
|
|
|
@ -1093,6 +1093,27 @@ OPJ_API void OPJ_CALLCONV opj_image_destroy(opj_image_t *image);
|
||||||
OPJ_API opj_image_t* OPJ_CALLCONV opj_image_tile_create(OPJ_UINT32 numcmpts,
|
OPJ_API opj_image_t* OPJ_CALLCONV opj_image_tile_create(OPJ_UINT32 numcmpts,
|
||||||
opj_image_cmptparm_t *cmptparms, OPJ_COLOR_SPACE clrspc);
|
opj_image_cmptparm_t *cmptparms, OPJ_COLOR_SPACE clrspc);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allocator for opj_image_t->comps[].data
|
||||||
|
* To be paired with opj_image_data_free.
|
||||||
|
*
|
||||||
|
* @param size number of bytes to allocate
|
||||||
|
*
|
||||||
|
* @return a new pointer if successful, NULL otherwise.
|
||||||
|
* @since 2.2.0
|
||||||
|
*/
|
||||||
|
OPJ_API void* OPJ_CALLCONV opj_image_data_alloc(OPJ_SIZE_T size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor for opj_image_t->comps[].data
|
||||||
|
* To be paired with opj_image_data_alloc.
|
||||||
|
*
|
||||||
|
* @param ptr Pointer to free
|
||||||
|
*
|
||||||
|
* @since 2.2.0
|
||||||
|
*/
|
||||||
|
OPJ_API void OPJ_CALLCONV opj_image_data_free(void* ptr);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
==========================================================
|
==========================================================
|
||||||
stream functions definitions
|
stream functions definitions
|
||||||
|
|
|
@ -36,7 +36,6 @@
|
||||||
Common constants shared among several modules
|
Common constants shared among several modules
|
||||||
==========================================================
|
==========================================================
|
||||||
*/
|
*/
|
||||||
#define OPJ_COMMON_DEFAULT_CBLK_DATA_SIZE 8192
|
|
||||||
#define OPJ_COMMON_CBLK_DATA_EXTRA 2 /**< Margin for a fake FFFF marker */
|
#define OPJ_COMMON_CBLK_DATA_EXTRA 2 /**< Margin for a fake FFFF marker */
|
||||||
|
|
||||||
#endif /* OPJ_COMMMON_H */
|
#endif /* OPJ_COMMMON_H */
|
||||||
|
|
|
@ -1604,6 +1604,8 @@ void opj_t1_destroy(opj_t1_t *p_t1)
|
||||||
p_t1->flags = 00;
|
p_t1->flags = 00;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
opj_free(p_t1->cblkdatabuffer);
|
||||||
|
|
||||||
opj_free(p_t1);
|
opj_free(p_t1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1613,6 +1615,7 @@ typedef struct {
|
||||||
opj_tcd_band_t* band;
|
opj_tcd_band_t* band;
|
||||||
opj_tcd_tilecomp_t* tilec;
|
opj_tcd_tilecomp_t* tilec;
|
||||||
opj_tccp_t* tccp;
|
opj_tccp_t* tccp;
|
||||||
|
OPJ_BOOL mustuse_cblkdatabuffer;
|
||||||
volatile OPJ_BOOL* pret;
|
volatile OPJ_BOOL* pret;
|
||||||
opj_event_mgr_t *p_manager;
|
opj_event_mgr_t *p_manager;
|
||||||
opj_mutex_t* p_manager_mutex;
|
opj_mutex_t* p_manager_mutex;
|
||||||
|
@ -1657,6 +1660,7 @@ static void opj_t1_clbl_decode_processor(void* user_data, opj_tls_t* tls)
|
||||||
t1 = opj_t1_create(OPJ_FALSE);
|
t1 = opj_t1_create(OPJ_FALSE);
|
||||||
opj_tls_set(tls, OPJ_TLS_KEY_T1, t1, opj_t1_destroy_wrapper);
|
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(
|
if (OPJ_FALSE == opj_t1_decode_cblk(
|
||||||
t1,
|
t1,
|
||||||
|
@ -1786,6 +1790,7 @@ void opj_t1_decode_cblks(opj_thread_pool_t* tp,
|
||||||
job->p_manager_mutex = p_manager_mutex;
|
job->p_manager_mutex = p_manager_mutex;
|
||||||
job->p_manager = p_manager;
|
job->p_manager = p_manager;
|
||||||
job->check_pterm = check_pterm;
|
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);
|
opj_thread_pool_submit_job(tp, opj_t1_clbl_decode_processor, job);
|
||||||
if (!(*pret)) {
|
if (!(*pret)) {
|
||||||
return;
|
return;
|
||||||
|
@ -1813,6 +1818,8 @@ static OPJ_BOOL opj_t1_decode_cblk(opj_t1_t *t1,
|
||||||
OPJ_INT32 bpno_plus_one;
|
OPJ_INT32 bpno_plus_one;
|
||||||
OPJ_UINT32 passtype;
|
OPJ_UINT32 passtype;
|
||||||
OPJ_UINT32 segno, passno;
|
OPJ_UINT32 segno, passno;
|
||||||
|
OPJ_BYTE* cblkdata = NULL;
|
||||||
|
OPJ_UINT32 cblkdataindex = 0;
|
||||||
OPJ_BYTE type = T1_TYPE_MQ; /* BYPASS mode */
|
OPJ_BYTE type = T1_TYPE_MQ; /* BYPASS mode */
|
||||||
|
|
||||||
mqc->lut_ctxno_zc_orient = lut_ctxno_zc + (orient << 9);
|
mqc->lut_ctxno_zc_orient = lut_ctxno_zc + (orient << 9);
|
||||||
|
@ -1844,23 +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_AGG, 0, 3);
|
||||||
opj_mqc_setstate(mqc, T1_CTXNO_ZC, 0, 4);
|
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) {
|
for (segno = 0; segno < cblk->real_num_segs; ++segno) {
|
||||||
opj_tcd_seg_t *seg = &cblk->segs[segno];
|
opj_tcd_seg_t *seg = &cblk->segs[segno];
|
||||||
|
|
||||||
/* BYPASS mode */
|
/* BYPASS mode */
|
||||||
type = ((bpno_plus_one <= ((OPJ_INT32)(cblk->numbps)) - 4) && (passtype < 2) &&
|
type = ((bpno_plus_one <= ((OPJ_INT32)(cblk->numbps)) - 4) && (passtype < 2) &&
|
||||||
(cblksty & J2K_CCP_CBLKSTY_LAZY)) ? T1_TYPE_RAW : T1_TYPE_MQ;
|
(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) {
|
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);
|
OPJ_COMMON_CBLK_DATA_EXTRA);
|
||||||
} else {
|
} 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);
|
OPJ_COMMON_CBLK_DATA_EXTRA);
|
||||||
}
|
}
|
||||||
|
cblkdataindex += seg->len;
|
||||||
|
|
||||||
for (passno = 0; (passno < seg->real_num_passes) &&
|
for (passno = 0; (passno < seg->real_num_passes) &&
|
||||||
(bpno_plus_one >= 1); ++passno) {
|
(bpno_plus_one >= 1); ++passno) {
|
||||||
|
|
|
@ -200,6 +200,14 @@ typedef struct opj_t1 {
|
||||||
OPJ_UINT32 flagssize;
|
OPJ_UINT32 flagssize;
|
||||||
OPJ_UINT32 data_stride;
|
OPJ_UINT32 data_stride;
|
||||||
OPJ_BOOL encoder;
|
OPJ_BOOL encoder;
|
||||||
|
|
||||||
|
/* Thre 3 variables below are only used by the decoder */
|
||||||
|
/* 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;
|
} opj_t1_t;
|
||||||
|
|
||||||
/** @name Exported functions */
|
/** @name Exported functions */
|
||||||
|
|
|
@ -1245,7 +1245,6 @@ static OPJ_BOOL opj_t2_read_packet_data(opj_t2_t* p_t2,
|
||||||
if (!l_cblk->numsegs) {
|
if (!l_cblk->numsegs) {
|
||||||
l_seg = l_cblk->segs;
|
l_seg = l_cblk->segs;
|
||||||
++l_cblk->numsegs;
|
++l_cblk->numsegs;
|
||||||
l_cblk->data_current_size = 0;
|
|
||||||
} else {
|
} else {
|
||||||
l_seg = &l_cblk->segs[l_cblk->numsegs - 1];
|
l_seg = &l_cblk->segs[l_cblk->numsegs - 1];
|
||||||
|
|
||||||
|
@ -1287,46 +1286,31 @@ static OPJ_BOOL opj_t2_read_packet_data(opj_t2_t* p_t2,
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* USE_JPWL */
|
#endif /* USE_JPWL */
|
||||||
/* Check possible overflow on size */
|
|
||||||
if ((l_cblk->data_current_size + l_seg->newlen + OPJ_COMMON_CBLK_DATA_EXTRA) <
|
if (l_cblk->numchunks == l_cblk->numchunksalloc) {
|
||||||
l_cblk->data_current_size) {
|
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_cblk->chunks,
|
||||||
|
l_numchunksalloc * sizeof(opj_tcd_seg_data_chunk_t));
|
||||||
|
if (l_chunks == NULL) {
|
||||||
opj_event_msg(p_manager, EVT_ERROR,
|
opj_event_msg(p_manager, EVT_ERROR,
|
||||||
"read: segment too long (%d) with current size (%d > %d) for codeblock %d (p=%d, b=%d, r=%d, c=%d)\n",
|
"cannot allocate opj_tcd_seg_data_chunk_t* array");
|
||||||
l_seg->newlen, l_cblk->data_current_size, 0xFFFFFFFF - l_seg->newlen, cblkno,
|
|
||||||
p_pi->precno, bandno, p_pi->resno, p_pi->compno);
|
|
||||||
return OPJ_FALSE;
|
return OPJ_FALSE;
|
||||||
}
|
}
|
||||||
/* Check if the cblk->data have allocated enough memory */
|
l_cblk->chunks = l_chunks;
|
||||||
if ((l_cblk->data_current_size + l_seg->newlen + OPJ_COMMON_CBLK_DATA_EXTRA) >
|
l_cblk->numchunksalloc = l_numchunksalloc;
|
||||||
l_cblk->data_max_size) {
|
|
||||||
OPJ_BYTE* new_cblk_data = (OPJ_BYTE*) opj_realloc(l_cblk->data,
|
|
||||||
l_cblk->data_current_size + l_seg->newlen + OPJ_COMMON_CBLK_DATA_EXTRA);
|
|
||||||
if (! new_cblk_data) {
|
|
||||||
opj_free(l_cblk->data);
|
|
||||||
l_cblk->data = NULL;
|
|
||||||
l_cblk->data_max_size = 0;
|
|
||||||
/* opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to realloc code block cata!\n"); */
|
|
||||||
return OPJ_FALSE;
|
|
||||||
}
|
|
||||||
l_cblk->data_max_size = l_cblk->data_current_size + l_seg->newlen +
|
|
||||||
OPJ_COMMON_CBLK_DATA_EXTRA;
|
|
||||||
l_cblk->data = new_cblk_data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(l_cblk->data + l_cblk->data_current_size, l_current_data, l_seg->newlen);
|
l_cblk->chunks[l_cblk->numchunks].data = l_current_data;
|
||||||
|
l_cblk->chunks[l_cblk->numchunks].len = l_seg->newlen;
|
||||||
if (l_seg->numpasses == 0) {
|
l_cblk->numchunks ++;
|
||||||
l_seg->data = &l_cblk->data;
|
|
||||||
l_seg->dataindex = l_cblk->data_current_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
l_current_data += l_seg->newlen;
|
l_current_data += l_seg->newlen;
|
||||||
|
l_seg->len += l_seg->newlen;
|
||||||
l_seg->numpasses += l_seg->numnewpasses;
|
l_seg->numpasses += l_seg->numnewpasses;
|
||||||
l_cblk->numnewpasses -= l_seg->numnewpasses;
|
l_cblk->numnewpasses -= l_seg->numnewpasses;
|
||||||
|
|
||||||
l_seg->real_num_passes = l_seg->numpasses;
|
l_seg->real_num_passes = l_seg->numpasses;
|
||||||
l_cblk->data_current_size += l_seg->newlen;
|
|
||||||
l_seg->len += l_seg->newlen;
|
|
||||||
|
|
||||||
if (l_cblk->numnewpasses > 0) {
|
if (l_cblk->numnewpasses > 0) {
|
||||||
++l_seg;
|
++l_seg;
|
||||||
|
@ -1391,7 +1375,6 @@ static OPJ_BOOL opj_t2_skip_packet_data(opj_t2_t* p_t2,
|
||||||
if (!l_cblk->numsegs) {
|
if (!l_cblk->numsegs) {
|
||||||
l_seg = l_cblk->segs;
|
l_seg = l_cblk->segs;
|
||||||
++l_cblk->numsegs;
|
++l_cblk->numsegs;
|
||||||
l_cblk->data_current_size = 0;
|
|
||||||
} else {
|
} else {
|
||||||
l_seg = &l_cblk->segs[l_cblk->numsegs - 1];
|
l_seg = &l_cblk->segs[l_cblk->numsegs - 1];
|
||||||
|
|
||||||
|
@ -1464,22 +1447,23 @@ static OPJ_BOOL opj_t2_init_seg(opj_tcd_cblk_dec_t* cblk,
|
||||||
|
|
||||||
if (l_nb_segs > cblk->m_current_max_segs) {
|
if (l_nb_segs > cblk->m_current_max_segs) {
|
||||||
opj_tcd_seg_t* new_segs;
|
opj_tcd_seg_t* new_segs;
|
||||||
cblk->m_current_max_segs += OPJ_J2K_DEFAULT_NB_SEGS;
|
OPJ_UINT32 l_m_current_max_segs = cblk->m_current_max_segs +
|
||||||
|
OPJ_J2K_DEFAULT_NB_SEGS;
|
||||||
|
|
||||||
new_segs = (opj_tcd_seg_t*) opj_realloc(cblk->segs,
|
new_segs = (opj_tcd_seg_t*) opj_realloc(cblk->segs,
|
||||||
cblk->m_current_max_segs * sizeof(opj_tcd_seg_t));
|
l_m_current_max_segs * sizeof(opj_tcd_seg_t));
|
||||||
if (! new_segs) {
|
if (! new_segs) {
|
||||||
opj_free(cblk->segs);
|
|
||||||
cblk->segs = NULL;
|
|
||||||
cblk->m_current_max_segs = 0;
|
|
||||||
/* opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to initialize segment %d\n", l_nb_segs); */
|
/* opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to initialize segment %d\n", l_nb_segs); */
|
||||||
return OPJ_FALSE;
|
return OPJ_FALSE;
|
||||||
}
|
}
|
||||||
cblk->segs = new_segs;
|
cblk->segs = new_segs;
|
||||||
|
memset(new_segs + cblk->m_current_max_segs,
|
||||||
|
0, OPJ_J2K_DEFAULT_NB_SEGS * sizeof(opj_tcd_seg_t));
|
||||||
|
cblk->m_current_max_segs = l_m_current_max_segs;
|
||||||
}
|
}
|
||||||
|
|
||||||
seg = &cblk->segs[index];
|
seg = &cblk->segs[index];
|
||||||
memset(seg, 0, sizeof(opj_tcd_seg_t));
|
opj_tcd_reinit_segment(seg);
|
||||||
|
|
||||||
if (cblksty & J2K_CCP_CBLKSTY_TERMALL) {
|
if (cblksty & J2K_CCP_CBLKSTY_TERMALL) {
|
||||||
seg->maxpasses = 1;
|
seg->maxpasses = 1;
|
||||||
|
@ -1491,6 +1475,10 @@ static OPJ_BOOL opj_t2_init_seg(opj_tcd_cblk_dec_t* cblk,
|
||||||
((seg - 1)->maxpasses == 10)) ? 2 : 1;
|
((seg - 1)->maxpasses == 10)) ? 2 : 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
/* See paragraph "B.10.6 Number of coding passes" of the standard.
|
||||||
|
* Probably that 109 must be interpreted a (Mb-1)*3 + 1 with Mb=37,
|
||||||
|
* Mb being the maximum number of bit-planes available for the
|
||||||
|
* representation of coefficients in the sub-band */
|
||||||
seg->maxpasses = 109;
|
seg->maxpasses = 109;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -674,7 +674,7 @@ OPJ_BOOL opj_alloc_tile_component_data(opj_tcd_tilecomp_t *l_tilec)
|
||||||
if ((l_tilec->data == 00) ||
|
if ((l_tilec->data == 00) ||
|
||||||
((l_tilec->data_size_needed > l_tilec->data_size) &&
|
((l_tilec->data_size_needed > l_tilec->data_size) &&
|
||||||
(l_tilec->ownsData == OPJ_FALSE))) {
|
(l_tilec->ownsData == OPJ_FALSE))) {
|
||||||
l_tilec->data = (OPJ_INT32 *) opj_aligned_malloc(l_tilec->data_size_needed);
|
l_tilec->data = (OPJ_INT32 *) opj_image_data_alloc(l_tilec->data_size_needed);
|
||||||
if (! l_tilec->data) {
|
if (! l_tilec->data) {
|
||||||
return OPJ_FALSE;
|
return OPJ_FALSE;
|
||||||
}
|
}
|
||||||
|
@ -683,8 +683,8 @@ OPJ_BOOL opj_alloc_tile_component_data(opj_tcd_tilecomp_t *l_tilec)
|
||||||
l_tilec->ownsData = OPJ_TRUE;
|
l_tilec->ownsData = OPJ_TRUE;
|
||||||
} else if (l_tilec->data_size_needed > l_tilec->data_size) {
|
} else if (l_tilec->data_size_needed > l_tilec->data_size) {
|
||||||
/* We don't need to keep old data */
|
/* We don't need to keep old data */
|
||||||
opj_aligned_free(l_tilec->data);
|
opj_image_data_free(l_tilec->data);
|
||||||
l_tilec->data = (OPJ_INT32 *) opj_aligned_malloc(l_tilec->data_size_needed);
|
l_tilec->data = (OPJ_INT32 *) opj_image_data_alloc(l_tilec->data_size_needed);
|
||||||
if (! l_tilec->data) {
|
if (! l_tilec->data) {
|
||||||
l_tilec->data_size = 0;
|
l_tilec->data_size = 0;
|
||||||
l_tilec->data_size_needed = 0;
|
l_tilec->data_size_needed = 0;
|
||||||
|
@ -965,8 +965,10 @@ static INLINE OPJ_BOOL opj_tcd_init_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no,
|
||||||
numbps = (OPJ_INT32)(l_image_comp->prec + l_gain);
|
numbps = (OPJ_INT32)(l_image_comp->prec + l_gain);
|
||||||
l_band->stepsize = (OPJ_FLOAT32)(((1.0 + l_step_size->mant / 2048.0) * pow(2.0,
|
l_band->stepsize = (OPJ_FLOAT32)(((1.0 + l_step_size->mant / 2048.0) * pow(2.0,
|
||||||
(OPJ_INT32)(numbps - l_step_size->expn)))) * fraction;
|
(OPJ_INT32)(numbps - l_step_size->expn)))) * fraction;
|
||||||
|
/* Mb value of Equation E-2 in "E.1 Inverse quantization
|
||||||
|
* procedure" of the standard */
|
||||||
l_band->numbps = l_step_size->expn + (OPJ_INT32)l_tccp->numgbits -
|
l_band->numbps = l_step_size->expn + (OPJ_INT32)l_tccp->numgbits -
|
||||||
1; /* WHY -1 ? */
|
1;
|
||||||
|
|
||||||
if (!l_band->precincts && (l_nb_precincts > 0U)) {
|
if (!l_band->precincts && (l_nb_precincts > 0U)) {
|
||||||
l_band->precincts = (opj_tcd_precinct_t *) opj_malloc(/*3 * */
|
l_band->precincts = (opj_tcd_precinct_t *) opj_malloc(/*3 * */
|
||||||
|
@ -1208,20 +1210,19 @@ static OPJ_BOOL opj_tcd_code_block_enc_allocate_data(opj_tcd_cblk_enc_t *
|
||||||
return OPJ_TRUE;
|
return OPJ_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void opj_tcd_reinit_segment(opj_tcd_seg_t* seg)
|
||||||
|
{
|
||||||
|
memset(seg, 0, sizeof(opj_tcd_seg_t));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allocates memory for a decoding code block.
|
* Allocates memory for a decoding code block.
|
||||||
*/
|
*/
|
||||||
static OPJ_BOOL opj_tcd_code_block_dec_allocate(opj_tcd_cblk_dec_t *
|
static OPJ_BOOL opj_tcd_code_block_dec_allocate(opj_tcd_cblk_dec_t *
|
||||||
p_code_block)
|
p_code_block)
|
||||||
{
|
{
|
||||||
if (! p_code_block->data) {
|
if (! p_code_block->segs) {
|
||||||
|
|
||||||
p_code_block->data = (OPJ_BYTE*) opj_malloc(OPJ_COMMON_DEFAULT_CBLK_DATA_SIZE);
|
|
||||||
if (! p_code_block->data) {
|
|
||||||
return OPJ_FALSE;
|
|
||||||
}
|
|
||||||
p_code_block->data_max_size = OPJ_COMMON_DEFAULT_CBLK_DATA_SIZE;
|
|
||||||
/*fprintf(stderr, "Allocate 8192 elements of code_block->data\n");*/
|
|
||||||
|
|
||||||
p_code_block->segs = (opj_tcd_seg_t *) opj_calloc(OPJ_J2K_DEFAULT_NB_SEGS,
|
p_code_block->segs = (opj_tcd_seg_t *) opj_calloc(OPJ_J2K_DEFAULT_NB_SEGS,
|
||||||
sizeof(opj_tcd_seg_t));
|
sizeof(opj_tcd_seg_t));
|
||||||
|
@ -1234,16 +1235,20 @@ static OPJ_BOOL opj_tcd_code_block_dec_allocate(opj_tcd_cblk_dec_t *
|
||||||
/*fprintf(stderr, "m_current_max_segs of code_block->data = %d\n", p_code_block->m_current_max_segs);*/
|
/*fprintf(stderr, "m_current_max_segs of code_block->data = %d\n", p_code_block->m_current_max_segs);*/
|
||||||
} else {
|
} else {
|
||||||
/* sanitize */
|
/* sanitize */
|
||||||
OPJ_BYTE* l_data = p_code_block->data;
|
|
||||||
OPJ_UINT32 l_data_max_size = p_code_block->data_max_size;
|
|
||||||
opj_tcd_seg_t * l_segs = p_code_block->segs;
|
opj_tcd_seg_t * l_segs = p_code_block->segs;
|
||||||
OPJ_UINT32 l_current_max_segs = p_code_block->m_current_max_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));
|
memset(p_code_block, 0, sizeof(opj_tcd_cblk_dec_t));
|
||||||
p_code_block->data = l_data;
|
|
||||||
p_code_block->data_max_size = l_data_max_size;
|
|
||||||
p_code_block->segs = l_segs;
|
p_code_block->segs = l_segs;
|
||||||
p_code_block->m_current_max_segs = l_current_max_segs;
|
p_code_block->m_current_max_segs = l_current_max_segs;
|
||||||
|
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;
|
return OPJ_TRUE;
|
||||||
|
@ -1645,7 +1650,7 @@ static void opj_tcd_free_tile(opj_tcd_t *p_tcd)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (l_tile_comp->ownsData && l_tile_comp->data) {
|
if (l_tile_comp->ownsData && l_tile_comp->data) {
|
||||||
opj_aligned_free(l_tile_comp->data);
|
opj_image_data_free(l_tile_comp->data);
|
||||||
l_tile_comp->data = 00;
|
l_tile_comp->data = 00;
|
||||||
l_tile_comp->ownsData = 0;
|
l_tile_comp->ownsData = 0;
|
||||||
l_tile_comp->data_size = 0;
|
l_tile_comp->data_size = 0;
|
||||||
|
@ -1946,16 +1951,16 @@ static void opj_tcd_code_block_dec_deallocate(opj_tcd_precinct_t * p_precinct)
|
||||||
|
|
||||||
for (cblkno = 0; cblkno < l_nb_code_blocks; ++cblkno) {
|
for (cblkno = 0; cblkno < l_nb_code_blocks; ++cblkno) {
|
||||||
|
|
||||||
if (l_code_block->data) {
|
|
||||||
opj_free(l_code_block->data);
|
|
||||||
l_code_block->data = 00;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (l_code_block->segs) {
|
if (l_code_block->segs) {
|
||||||
opj_free(l_code_block->segs);
|
opj_free(l_code_block->segs);
|
||||||
l_code_block->segs = 00;
|
l_code_block->segs = 00;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (l_code_block->chunks) {
|
||||||
|
opj_free(l_code_block->chunks);
|
||||||
|
l_code_block->chunks = 00;
|
||||||
|
}
|
||||||
|
|
||||||
++l_code_block;
|
++l_code_block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,19 +49,6 @@ each other. The functions in TCD.C are used by other functions in J2K.C.
|
||||||
/** @defgroup TCD TCD - Implementation of a tile coder/decoder */
|
/** @defgroup TCD TCD - Implementation of a tile coder/decoder */
|
||||||
/*@{*/
|
/*@{*/
|
||||||
|
|
||||||
/**
|
|
||||||
FIXME DOC
|
|
||||||
*/
|
|
||||||
typedef struct opj_tcd_seg {
|
|
||||||
OPJ_BYTE ** data;
|
|
||||||
OPJ_UINT32 dataindex;
|
|
||||||
OPJ_UINT32 numpasses;
|
|
||||||
OPJ_UINT32 real_num_passes;
|
|
||||||
OPJ_UINT32 len;
|
|
||||||
OPJ_UINT32 maxpasses;
|
|
||||||
OPJ_UINT32 numnewpasses;
|
|
||||||
OPJ_UINT32 newlen;
|
|
||||||
} opj_tcd_seg_t;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
FIXME DOC
|
FIXME DOC
|
||||||
|
@ -102,19 +89,50 @@ typedef struct opj_tcd_cblk_enc {
|
||||||
} opj_tcd_cblk_enc_t;
|
} opj_tcd_cblk_enc_t;
|
||||||
|
|
||||||
|
|
||||||
|
/** Chunk of codestream data that is part of a code block */
|
||||||
|
typedef struct opj_tcd_seg_data_chunk {
|
||||||
|
/* 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;
|
||||||
|
|
||||||
|
/** Segment of a code-block.
|
||||||
|
* A segment represent a number of consecutive coding passes, without termination
|
||||||
|
* of MQC or RAW between them. */
|
||||||
|
typedef struct opj_tcd_seg {
|
||||||
|
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 {
|
typedef struct opj_tcd_cblk_dec {
|
||||||
OPJ_BYTE * data; /* Data */
|
|
||||||
opj_tcd_seg_t* segs; /* segments information */
|
opj_tcd_seg_t* segs; /* segments information */
|
||||||
OPJ_INT32 x0, y0, x1,
|
opj_tcd_seg_data_chunk_t* chunks; /* Array of chunks */
|
||||||
y1; /* position of the code-blocks : left upper corner (x0, y0) right low corner (x1,y1) */
|
/* 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 numbps;
|
||||||
|
/* number of bits for len, for the current packet. Transitory value */
|
||||||
OPJ_UINT32 numlenbits;
|
OPJ_UINT32 numlenbits;
|
||||||
OPJ_UINT32 data_max_size; /* Size of allocated data buffer */
|
/* number of pass added to the code-blocks, for the current packet. Transitory value */
|
||||||
OPJ_UINT32 data_current_size; /* Size of used data buffer */
|
OPJ_UINT32 numnewpasses;
|
||||||
OPJ_UINT32 numnewpasses; /* number of pass added to the code-blocks */
|
/* number of segments, including those of packet we skip */
|
||||||
OPJ_UINT32 numsegs; /* number of segments */
|
OPJ_UINT32 numsegs;
|
||||||
|
/* number of segments, to be used for code block decoding */
|
||||||
OPJ_UINT32 real_num_segs;
|
OPJ_UINT32 real_num_segs;
|
||||||
OPJ_UINT32 m_current_max_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;
|
} opj_tcd_cblk_dec_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -381,6 +399,9 @@ 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);
|
OPJ_BOOL opj_tcd_is_band_empty(opj_tcd_band_t* band);
|
||||||
|
|
||||||
|
/** Reinitialize a segment */
|
||||||
|
void opj_tcd_reinit_segment(opj_tcd_seg_t* seg);
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------- */
|
/* ----------------------------------------------------------------------- */
|
||||||
/*@}*/
|
/*@}*/
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue