summaryrefslogtreecommitdiff
path: root/core/src/fxcodec/fx_libopenjpeg
diff options
context:
space:
mode:
Diffstat (limited to 'core/src/fxcodec/fx_libopenjpeg')
-rw-r--r--core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/bio.c9
-rw-r--r--core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/j2k.c42
-rw-r--r--core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/jp2.c46
-rw-r--r--core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/mct.c232
-rw-r--r--core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/openjpeg.h34
-rw-r--r--core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/opj_includes.h4
-rw-r--r--core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/opj_intmath.h28
-rw-r--r--core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/pi.c13
-rw-r--r--core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/t1.c28
-rw-r--r--core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/t1.h4
-rw-r--r--core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/t2.c4
-rw-r--r--core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/tcd.c163
-rw-r--r--core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/tcd.h17
13 files changed, 485 insertions, 139 deletions
diff --git a/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/bio.c b/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/bio.c
index 5d49580178..3ce6492753 100644
--- a/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/bio.c
+++ b/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/bio.c
@@ -81,7 +81,7 @@ static OPJ_BOOL opj_bio_bytein(opj_bio_t *bio);
OPJ_BOOL opj_bio_byteout(opj_bio_t *bio) {
bio->buf = (bio->buf << 8) & 0xffff;
bio->ct = bio->buf == 0xff00 ? 7 : 8;
- if (bio->bp >= bio->end) {
+ if ((OPJ_SIZE_T)bio->bp >= (OPJ_SIZE_T)bio->end) {
return OPJ_FALSE;
}
*bio->bp++ = (OPJ_BYTE)(bio->buf >> 8);
@@ -91,7 +91,7 @@ OPJ_BOOL opj_bio_byteout(opj_bio_t *bio) {
OPJ_BOOL opj_bio_bytein(opj_bio_t *bio) {
bio->buf = (bio->buf << 8) & 0xffff;
bio->ct = bio->buf == 0xff00 ? 7 : 8;
- if (bio->bp >= bio->end) {
+ if ((OPJ_SIZE_T)bio->bp >= (OPJ_SIZE_T)bio->end) {
return OPJ_FALSE;
}
bio->buf |= *bio->bp++;
@@ -169,12 +169,10 @@ OPJ_UINT32 opj_bio_read(opj_bio_t *bio, OPJ_UINT32 n) {
}
OPJ_BOOL opj_bio_flush(opj_bio_t *bio) {
- bio->ct = 0;
if (! opj_bio_byteout(bio)) {
return OPJ_FALSE;
}
if (bio->ct == 7) {
- bio->ct = 0;
if (! opj_bio_byteout(bio)) {
return OPJ_FALSE;
}
@@ -183,12 +181,11 @@ OPJ_BOOL opj_bio_flush(opj_bio_t *bio) {
}
OPJ_BOOL opj_bio_inalign(opj_bio_t *bio) {
- bio->ct = 0;
if ((bio->buf & 0xff) == 0xff) {
if (! opj_bio_bytein(bio)) {
return OPJ_FALSE;
}
- bio->ct = 0;
}
+ bio->ct = 0;
return OPJ_TRUE;
}
diff --git a/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/j2k.c b/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/j2k.c
index 4a1c103f4b..f944ad1afb 100644
--- a/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/j2k.c
+++ b/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/j2k.c
@@ -1919,7 +1919,7 @@ static OPJ_BOOL opj_j2k_read_siz(opj_j2k_t *p_j2k,
OPJ_UINT32 l_nb_comp_remain;
OPJ_UINT32 l_remaining_size;
OPJ_UINT32 l_nb_tiles;
- OPJ_UINT32 l_tmp;
+ OPJ_UINT32 l_tmp, l_tx1, l_ty1;
opj_image_t *l_image = 00;
opj_cp_t *l_cp = 00;
opj_image_comp_t * l_img_comp = 00;
@@ -1981,8 +1981,9 @@ static OPJ_BOOL opj_j2k_read_siz(opj_j2k_t *p_j2k,
}
/* testcase 4035.pdf.SIGSEGV.d8b.3375 */
- if (l_image->x0 > l_image->x1 || l_image->y0 > l_image->y1) {
- opj_event_msg(p_manager, EVT_ERROR, "Error with SIZ marker: negative image size (%d x %d)\n", l_image->x1 - l_image->x0, l_image->y1 - l_image->y0);
+ /* testcase issue427-null-image-size.jp2 */
+ if ((l_image->x0 >= l_image->x1) || (l_image->y0 >= l_image->y1)) {
+ opj_event_msg(p_manager, EVT_ERROR, "Error with SIZ marker: negative or zero image size (%d x %d)\n", l_image->x1 - l_image->x0, l_image->y1 - l_image->y0);
return OPJ_FALSE;
}
/* testcase 2539.pdf.SIGFPE.706.1712 (also 3622.pdf.SIGFPE.706.2916 and 4008.pdf.SIGFPE.706.3345 and maybe more) */
@@ -1997,6 +1998,20 @@ static OPJ_BOOL opj_j2k_read_siz(opj_j2k_t *p_j2k,
return OPJ_FALSE;
}
+ /* testcase issue427-illegal-tile-offset.jp2 */
+ l_tx1 = l_cp->tx0 + l_cp->tdx;
+ if (l_tx1 < l_cp->tx0) { /* manage overflow */
+ l_tx1 = 0xFFFFFFFFU;
+ }
+ l_ty1 = l_cp->ty0 + l_cp->tdy;
+ if (l_ty1 < l_cp->ty0) { /* manage overflow */
+ l_ty1 = 0xFFFFFFFFU;
+ }
+ if ((l_cp->tx0 > l_image->x0) || (l_cp->ty0 > l_image->y0) || (l_tx1 <= l_image->x0) || (l_ty1 <= l_image->y0) ) {
+ opj_event_msg(p_manager, EVT_ERROR, "Error with SIZ marker: illegal tile offset\n");
+ return OPJ_FALSE;
+ }
+
#ifdef USE_JPWL
if (l_cp->correct) {
/* if JPWL is on, we check whether TX errors have damaged
@@ -5221,6 +5236,7 @@ static OPJ_BOOL opj_j2k_read_mct ( opj_j2k_t *p_j2k,
}
l_mct_data = l_tcp->m_mct_records + l_tcp->m_nb_mct_records;
+ ++l_tcp->m_nb_mct_records;
}
if (l_mct_data->m_data) {
@@ -5249,7 +5265,6 @@ static OPJ_BOOL opj_j2k_read_mct ( opj_j2k_t *p_j2k,
memcpy(l_mct_data->m_data,p_header_data,p_header_size);
l_mct_data->m_data_size = p_header_size;
- ++l_tcp->m_nb_mct_records;
return OPJ_TRUE;
}
@@ -6571,7 +6586,7 @@ OPJ_BOOL opj_j2k_setup_encoder( opj_j2k_t *p_j2k,
}
}
else {
- if(tcp->mct==1 && image->numcomps == 3) { /* RGB->YCC MCT is enabled */
+ if(tcp->mct==1 && image->numcomps >= 3) { /* RGB->YCC MCT is enabled */
if ((image->comps[0].dx != image->comps[1].dx) ||
(image->comps[0].dx != image->comps[2].dx) ||
(image->comps[0].dy != image->comps[1].dy) ||
@@ -7059,21 +7074,20 @@ OPJ_BOOL opj_j2k_encoding_validation ( opj_j2k_t * p_j2k,
/* make sure a validation list is present */
l_is_valid &= (p_j2k->m_validation_list != 00);
- /* ISO 15444-1:2004 states between 1 & 33 (0 -> 32) */
- /* 33 (32) would always fail the 2 checks below (if a cast to 64bits was done) */
- /* 32 (31) would always fail the 2 checks below (if a cast to 64bits was done) */
- /* FIXME Shall we change OPJ_J2K_MAXRLVLS to 31 ? */
- if ((p_j2k->m_cp.tcps->tccps->numresolutions <= 0) || (p_j2k->m_cp.tcps->tccps->numresolutions > 31)) {
+ /* ISO 15444-1:2004 states between 1 & 33 (0 -> 32) */
+ /* 33 (32) would always fail the check below (if a cast to 64bits was done) */
+ /* FIXME Shall we change OPJ_J2K_MAXRLVLS to 32 ? */
+ if ((p_j2k->m_cp.tcps->tccps->numresolutions <= 0) || (p_j2k->m_cp.tcps->tccps->numresolutions > 32)) {
opj_event_msg(p_manager, EVT_ERROR, "Number of resolutions is too high in comparison to the size of tiles\n");
return OPJ_FALSE;
}
- if ((p_j2k->m_cp.tdx) < (OPJ_UINT32) (1 << p_j2k->m_cp.tcps->tccps->numresolutions)) {
+ if ((p_j2k->m_cp.tdx) < (OPJ_UINT32) (1 << (p_j2k->m_cp.tcps->tccps->numresolutions - 1U))) {
opj_event_msg(p_manager, EVT_ERROR, "Number of resolutions is too high in comparison to the size of tiles\n");
return OPJ_FALSE;
}
- if ((p_j2k->m_cp.tdy) < (OPJ_UINT32) (1 << p_j2k->m_cp.tcps->tccps->numresolutions)) {
+ if ((p_j2k->m_cp.tdy) < (OPJ_UINT32) (1 << (p_j2k->m_cp.tcps->tccps->numresolutions - 1U))) {
opj_event_msg(p_manager, EVT_ERROR, "Number of resolutions is too high in comparison to the size of tiles\n");
return OPJ_FALSE;
}
@@ -7151,7 +7165,7 @@ OPJ_BOOL opj_j2k_read_header_procedure( opj_j2k_t *p_j2k,
/* Check if the current marker ID is valid */
if (l_current_marker < 0xff00) {
- opj_event_msg(p_manager, EVT_ERROR, "We expected read a marker ID (0xff--) instead of %.8x\n", l_current_marker);
+ opj_event_msg(p_manager, EVT_ERROR, "A marker ID was expected (0xff--) instead of %.8x\n", l_current_marker);
return OPJ_FALSE;
}
@@ -9776,7 +9790,7 @@ OPJ_BOOL opj_j2k_encode(opj_j2k_t * p_j2k,
assert(p_j2k != 00);
assert(p_stream != 00);
assert(p_manager != 00);
-
+
p_tcd = p_j2k->m_tcd;
l_nb_tiles = p_j2k->m_cp.th * p_j2k->m_cp.tw;
diff --git a/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/jp2.c b/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/jp2.c
index 1830c11a19..aafbe199d6 100644
--- a/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/jp2.c
+++ b/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/jp2.c
@@ -706,7 +706,7 @@ static OPJ_BYTE * opj_jp2_write_cdef(opj_jp2_t *jp2, OPJ_UINT32 * p_nb_bytes_wri
assert(jp2->color.jp2_cdef->info != 00);
assert(jp2->color.jp2_cdef->n > 0U);
- l_cdef_size += 6 * jp2->color.jp2_cdef->n;
+ l_cdef_size += 6U * jp2->color.jp2_cdef->n;
l_cdef_data = (OPJ_BYTE *) opj_malloc(l_cdef_size);
if (l_cdef_data == 00) {
@@ -714,7 +714,7 @@ static OPJ_BYTE * opj_jp2_write_cdef(opj_jp2_t *jp2, OPJ_UINT32 * p_nb_bytes_wri
}
l_current_cdef_ptr = l_cdef_data;
-
+
opj_write_bytes(l_current_cdef_ptr,l_cdef_size,4); /* write box size */
l_current_cdef_ptr += 4;
@@ -1184,16 +1184,16 @@ void opj_jp2_apply_cdef(opj_image_t *image, opj_jp2_color_t *color)
{
opj_jp2_cdef_info_t *info;
OPJ_UINT16 i, n, cn, asoc, acn;
-
+
info = color->jp2_cdef->info;
n = color->jp2_cdef->n;
-
+
for(i = 0; i < n; ++i)
{
/* WATCH: acn = asoc - 1 ! */
asoc = info[i].asoc;
cn = info[i].cn;
-
+
if( cn >= image->numcomps)
{
fprintf(stderr, "cn=%d, numcomps=%d\n", cn, image->numcomps);
@@ -1204,26 +1204,26 @@ void opj_jp2_apply_cdef(opj_image_t *image, opj_jp2_color_t *color)
image->comps[cn].alpha = info[i].typ;
continue;
}
-
+
acn = (OPJ_UINT16)(asoc - 1);
if( acn >= image->numcomps )
{
fprintf(stderr, "acn=%d, numcomps=%d\n", acn, image->numcomps);
continue;
}
-
+
/* Swap only if color channel */
if((cn != acn) && (info[i].typ == 0))
{
opj_image_comp_t saved;
OPJ_UINT16 j;
-
+
memcpy(&saved, &image->comps[cn], sizeof(opj_image_comp_t));
memcpy(&image->comps[cn], &image->comps[acn], sizeof(opj_image_comp_t));
memcpy(&image->comps[acn], &saved, sizeof(opj_image_comp_t));
-
+
/* Swap channels in following channel definitions, don't bother with j <= i that are already processed */
- for (j = i + 1; j < n ; ++j)
+ for (j = (OPJ_UINT16)(i + 1U); j < n ; ++j)
{
if (info[j].cn == cn) {
info[j].cn = acn;
@@ -1234,14 +1234,14 @@ void opj_jp2_apply_cdef(opj_image_t *image, opj_jp2_color_t *color)
/* asoc is related to color index. Do not update. */
}
}
-
+
image->comps[cn].alpha = info[i].typ;
}
-
+
if(color->jp2_cdef->info) opj_free(color->jp2_cdef->info);
-
+
opj_free(color->jp2_cdef); color->jp2_cdef = NULL;
-
+
}/* jp2_apply_cdef() */
OPJ_BOOL opj_jp2_read_cdef( opj_jp2_t * jp2,
@@ -1487,7 +1487,7 @@ OPJ_BOOL opj_jp2_write_jp2h(opj_jp2_t *jp2,
l_writers[l_nb_pass].handler = opj_jp2_write_cdef;
l_nb_pass++;
}
-
+
/* write box header */
/* write JP2H type */
opj_write_bytes(l_jp2h_data+4,JP2_JP2H,4);
@@ -1693,7 +1693,7 @@ OPJ_BOOL opj_jp2_setup_encoder( opj_jp2_t *jp2,
OPJ_UINT32 alpha_count;
OPJ_UINT32 color_channels = 0U;
OPJ_UINT32 alpha_channel = 0U;
-
+
if(!jp2 || !parameters || !image)
return OPJ_FALSE;
@@ -1969,7 +1969,7 @@ OPJ_BOOL opj_jp2_default_validation ( opj_jp2_t * jp2,
l_is_valid &= (jp2->w > 0);
/* precision */
for (i = 0; i < jp2->numcomps; ++i) {
- l_is_valid &= (jp2->comps[i].bpcc > 0);
+ l_is_valid &= ((jp2->comps[i].bpcc & 0x7FU) < 38U); /* 0 is valid, ignore sign for check */
}
/* METH */
@@ -2066,6 +2066,16 @@ OPJ_BOOL opj_jp2_read_header_procedure( opj_jp2_t *jp2,
}
}
else {
+ if (!(jp2->jp2_state & JP2_STATE_SIGNATURE)) {
+ opj_event_msg(p_manager, EVT_ERROR, "Malformed JP2 file format: first box must be JPEG 2000 signature box\n");
+ opj_free(l_current_data);
+ return OPJ_FALSE;
+ }
+ if (!(jp2->jp2_state & JP2_STATE_FILE_TYPE)) {
+ opj_event_msg(p_manager, EVT_ERROR, "Malformed JP2 file format: second box must be file type box\n");
+ opj_free(l_current_data);
+ return OPJ_FALSE;
+ }
jp2->jp2_state |= JP2_STATE_UNKNOWN;
if (opj_stream_skip(stream,l_current_data_size,p_manager) != l_current_data_size) {
opj_event_msg(p_manager, EVT_ERROR, "Problem with skipping JPEG2000 box, stream error\n");
@@ -2719,7 +2729,7 @@ OPJ_BOOL opj_jp2_get_tile( opj_jp2_t *p_jp2,
else
opj_jp2_apply_pclr(p_image, &(p_jp2->color));
}
-
+
/* Apply the color space if needed */
if(p_jp2->color.jp2_cdef) {
opj_jp2_apply_cdef(p_image, &(p_jp2->color));
diff --git a/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/mct.c b/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/mct.c
index 60ee0969d5..a0da099660 100644
--- a/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/mct.c
+++ b/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/mct.c
@@ -40,6 +40,12 @@
#ifdef __SSE__
#include <xmmintrin.h>
#endif
+#ifdef __SSE2__
+#include <emmintrin.h>
+#endif
+#ifdef __SSE4_1__
+#include <smmintrin.h>
+#endif
#include "opj_includes.h"
@@ -66,14 +72,33 @@ const OPJ_FLOAT64 * opj_mct_get_mct_norms_real ()
/* <summary> */
/* Foward reversible MCT. */
/* </summary> */
+#ifdef __SSE2__
void opj_mct_encode(
OPJ_INT32* restrict c0,
OPJ_INT32* restrict c1,
OPJ_INT32* restrict c2,
OPJ_UINT32 n)
{
- OPJ_UINT32 i;
- for(i = 0; i < n; ++i) {
+ OPJ_SIZE_T i;
+ const OPJ_SIZE_T len = n;
+
+ for(i = 0; i < (len & ~3U); i += 4) {
+ __m128i y, u, v;
+ __m128i r = _mm_load_si128((const __m128i *)&(c0[i]));
+ __m128i g = _mm_load_si128((const __m128i *)&(c1[i]));
+ __m128i b = _mm_load_si128((const __m128i *)&(c2[i]));
+ y = _mm_add_epi32(g, g);
+ y = _mm_add_epi32(y, b);
+ y = _mm_add_epi32(y, r);
+ y = _mm_srai_epi32(y, 2);
+ u = _mm_sub_epi32(b, g);
+ v = _mm_sub_epi32(r, g);
+ _mm_store_si128((__m128i *)&(c0[i]), y);
+ _mm_store_si128((__m128i *)&(c1[i]), u);
+ _mm_store_si128((__m128i *)&(c2[i]), v);
+ }
+
+ for(; i < len; ++i) {
OPJ_INT32 r = c0[i];
OPJ_INT32 g = c1[i];
OPJ_INT32 b = c2[i];
@@ -85,10 +110,69 @@ void opj_mct_encode(
c2[i] = v;
}
}
+#else
+void opj_mct_encode(
+ OPJ_INT32* restrict c0,
+ OPJ_INT32* restrict c1,
+ OPJ_INT32* restrict c2,
+ OPJ_UINT32 n)
+{
+ OPJ_SIZE_T i;
+ const OPJ_SIZE_T len = n;
+
+ for(i = 0; i < len; ++i) {
+ OPJ_INT32 r = c0[i];
+ OPJ_INT32 g = c1[i];
+ OPJ_INT32 b = c2[i];
+ OPJ_INT32 y = (r + (g * 2) + b) >> 2;
+ OPJ_INT32 u = b - g;
+ OPJ_INT32 v = r - g;
+ c0[i] = y;
+ c1[i] = u;
+ c2[i] = v;
+ }
+}
+#endif
/* <summary> */
/* Inverse reversible MCT. */
/* </summary> */
+#ifdef __SSE2__
+void opj_mct_decode(
+ OPJ_INT32* restrict c0,
+ OPJ_INT32* restrict c1,
+ OPJ_INT32* restrict c2,
+ OPJ_UINT32 n)
+{
+ OPJ_SIZE_T i;
+ const OPJ_SIZE_T len = n;
+
+ for(i = 0; i < (len & ~3U); i += 4) {
+ __m128i r, g, b;
+ __m128i y = _mm_load_si128((const __m128i *)&(c0[i]));
+ __m128i u = _mm_load_si128((const __m128i *)&(c1[i]));
+ __m128i v = _mm_load_si128((const __m128i *)&(c2[i]));
+ g = y;
+ g = _mm_sub_epi32(g, _mm_srai_epi32(_mm_add_epi32(u, v), 2));
+ r = _mm_add_epi32(v, g);
+ b = _mm_add_epi32(u, g);
+ _mm_store_si128((__m128i *)&(c0[i]), r);
+ _mm_store_si128((__m128i *)&(c1[i]), g);
+ _mm_store_si128((__m128i *)&(c2[i]), b);
+ }
+ for (; i < len; ++i) {
+ OPJ_INT32 y = c0[i];
+ OPJ_INT32 u = c1[i];
+ OPJ_INT32 v = c2[i];
+ OPJ_INT32 g = y - ((u + v) >> 2);
+ OPJ_INT32 r = v + g;
+ OPJ_INT32 b = u + g;
+ c0[i] = r;
+ c1[i] = g;
+ c2[i] = b;
+ }
+}
+#else
void opj_mct_decode(
OPJ_INT32* restrict c0,
OPJ_INT32* restrict c1,
@@ -108,6 +192,7 @@ void opj_mct_decode(
c2[i] = b;
}
}
+#endif
/* <summary> */
/* Get norm of basis function of reversible MCT. */
@@ -119,6 +204,148 @@ OPJ_FLOAT64 opj_mct_getnorm(OPJ_UINT32 compno) {
/* <summary> */
/* Foward irreversible MCT. */
/* </summary> */
+#ifdef __SSE4_1__
+void opj_mct_encode_real(
+ OPJ_INT32* restrict c0,
+ OPJ_INT32* restrict c1,
+ OPJ_INT32* restrict c2,
+ OPJ_UINT32 n)
+{
+ OPJ_SIZE_T i;
+ const OPJ_SIZE_T len = n;
+
+ const __m128i ry = _mm_set1_epi32(2449);
+ const __m128i gy = _mm_set1_epi32(4809);
+ const __m128i by = _mm_set1_epi32(934);
+ const __m128i ru = _mm_set1_epi32(1382);
+ const __m128i gu = _mm_set1_epi32(2714);
+ /* const __m128i bu = _mm_set1_epi32(4096); */
+ /* const __m128i rv = _mm_set1_epi32(4096); */
+ const __m128i gv = _mm_set1_epi32(3430);
+ const __m128i bv = _mm_set1_epi32(666);
+ const __m128i mulround = _mm_shuffle_epi32(_mm_cvtsi32_si128(4096), _MM_SHUFFLE(1, 0, 1, 0));
+
+ for(i = 0; i < (len & ~3U); i += 4) {
+ __m128i lo, hi;
+ __m128i y, u, v;
+ __m128i r = _mm_load_si128((const __m128i *)&(c0[i]));
+ __m128i g = _mm_load_si128((const __m128i *)&(c1[i]));
+ __m128i b = _mm_load_si128((const __m128i *)&(c2[i]));
+
+ lo = r;
+ hi = _mm_shuffle_epi32(r, _MM_SHUFFLE(3, 3, 1, 1));
+ lo = _mm_mul_epi32(lo, ry);
+ hi = _mm_mul_epi32(hi, ry);
+ lo = _mm_add_epi64(lo, mulround);
+ hi = _mm_add_epi64(hi, mulround);
+ lo = _mm_srli_epi64(lo, 13);
+ hi = _mm_slli_epi64(hi, 32-13);
+ y = _mm_blend_epi16(lo, hi, 0xCC);
+
+ lo = g;
+ hi = _mm_shuffle_epi32(g, _MM_SHUFFLE(3, 3, 1, 1));
+ lo = _mm_mul_epi32(lo, gy);
+ hi = _mm_mul_epi32(hi, gy);
+ lo = _mm_add_epi64(lo, mulround);
+ hi = _mm_add_epi64(hi, mulround);
+ lo = _mm_srli_epi64(lo, 13);
+ hi = _mm_slli_epi64(hi, 32-13);
+ y = _mm_add_epi32(y, _mm_blend_epi16(lo, hi, 0xCC));
+
+ lo = b;
+ hi = _mm_shuffle_epi32(b, _MM_SHUFFLE(3, 3, 1, 1));
+ lo = _mm_mul_epi32(lo, by);
+ hi = _mm_mul_epi32(hi, by);
+ lo = _mm_add_epi64(lo, mulround);
+ hi = _mm_add_epi64(hi, mulround);
+ lo = _mm_srli_epi64(lo, 13);
+ hi = _mm_slli_epi64(hi, 32-13);
+ y = _mm_add_epi32(y, _mm_blend_epi16(lo, hi, 0xCC));
+ _mm_store_si128((__m128i *)&(c0[i]), y);
+
+ /*lo = b;
+ hi = _mm_shuffle_epi32(b, _MM_SHUFFLE(3, 3, 1, 1));
+ lo = _mm_mul_epi32(lo, mulround);
+ hi = _mm_mul_epi32(hi, mulround);*/
+ lo = _mm_cvtepi32_epi64(_mm_shuffle_epi32(b, _MM_SHUFFLE(3, 2, 2, 0)));
+ hi = _mm_cvtepi32_epi64(_mm_shuffle_epi32(b, _MM_SHUFFLE(3, 2, 3, 1)));
+ lo = _mm_slli_epi64(lo, 12);
+ hi = _mm_slli_epi64(hi, 12);
+ lo = _mm_add_epi64(lo, mulround);
+ hi = _mm_add_epi64(hi, mulround);
+ lo = _mm_srli_epi64(lo, 13);
+ hi = _mm_slli_epi64(hi, 32-13);
+ u = _mm_blend_epi16(lo, hi, 0xCC);
+
+ lo = r;
+ hi = _mm_shuffle_epi32(r, _MM_SHUFFLE(3, 3, 1, 1));
+ lo = _mm_mul_epi32(lo, ru);
+ hi = _mm_mul_epi32(hi, ru);
+ lo = _mm_add_epi64(lo, mulround);
+ hi = _mm_add_epi64(hi, mulround);
+ lo = _mm_srli_epi64(lo, 13);
+ hi = _mm_slli_epi64(hi, 32-13);
+ u = _mm_sub_epi32(u, _mm_blend_epi16(lo, hi, 0xCC));
+
+ lo = g;
+ hi = _mm_shuffle_epi32(g, _MM_SHUFFLE(3, 3, 1, 1));
+ lo = _mm_mul_epi32(lo, gu);
+ hi = _mm_mul_epi32(hi, gu);
+ lo = _mm_add_epi64(lo, mulround);
+ hi = _mm_add_epi64(hi, mulround);
+ lo = _mm_srli_epi64(lo, 13);
+ hi = _mm_slli_epi64(hi, 32-13);
+ u = _mm_sub_epi32(u, _mm_blend_epi16(lo, hi, 0xCC));
+ _mm_store_si128((__m128i *)&(c1[i]), u);
+
+ /*lo = r;
+ hi = _mm_shuffle_epi32(r, _MM_SHUFFLE(3, 3, 1, 1));
+ lo = _mm_mul_epi32(lo, mulround);
+ hi = _mm_mul_epi32(hi, mulround);*/
+ lo = _mm_cvtepi32_epi64(_mm_shuffle_epi32(r, _MM_SHUFFLE(3, 2, 2, 0)));
+ hi = _mm_cvtepi32_epi64(_mm_shuffle_epi32(r, _MM_SHUFFLE(3, 2, 3, 1)));
+ lo = _mm_slli_epi64(lo, 12);
+ hi = _mm_slli_epi64(hi, 12);
+ lo = _mm_add_epi64(lo, mulround);
+ hi = _mm_add_epi64(hi, mulround);
+ lo = _mm_srli_epi64(lo, 13);
+ hi = _mm_slli_epi64(hi, 32-13);
+ v = _mm_blend_epi16(lo, hi, 0xCC);
+
+ lo = g;
+ hi = _mm_shuffle_epi32(g, _MM_SHUFFLE(3, 3, 1, 1));
+ lo = _mm_mul_epi32(lo, gv);
+ hi = _mm_mul_epi32(hi, gv);
+ lo = _mm_add_epi64(lo, mulround);
+ hi = _mm_add_epi64(hi, mulround);
+ lo = _mm_srli_epi64(lo, 13);
+ hi = _mm_slli_epi64(hi, 32-13);
+ v = _mm_sub_epi32(v, _mm_blend_epi16(lo, hi, 0xCC));
+
+ lo = b;
+ hi = _mm_shuffle_epi32(b, _MM_SHUFFLE(3, 3, 1, 1));
+ lo = _mm_mul_epi32(lo, bv);
+ hi = _mm_mul_epi32(hi, bv);
+ lo = _mm_add_epi64(lo, mulround);
+ hi = _mm_add_epi64(hi, mulround);
+ lo = _mm_srli_epi64(lo, 13);
+ hi = _mm_slli_epi64(hi, 32-13);
+ v = _mm_sub_epi32(v, _mm_blend_epi16(lo, hi, 0xCC));
+ _mm_store_si128((__m128i *)&(c2[i]), v);
+ }
+ for(; i < len; ++i) {
+ OPJ_INT32 r = c0[i];
+ OPJ_INT32 g = c1[i];
+ OPJ_INT32 b = c2[i];
+ OPJ_INT32 y = opj_int_fix_mul(r, 2449) + opj_int_fix_mul(g, 4809) + opj_int_fix_mul(b, 934);
+ OPJ_INT32 u = -opj_int_fix_mul(r, 1382) - opj_int_fix_mul(g, 2714) + opj_int_fix_mul(b, 4096);
+ OPJ_INT32 v = opj_int_fix_mul(r, 4096) - opj_int_fix_mul(g, 3430) - opj_int_fix_mul(b, 666);
+ c0[i] = y;
+ c1[i] = u;
+ c2[i] = v;
+ }
+}
+#else
void opj_mct_encode_real(
OPJ_INT32* restrict c0,
OPJ_INT32* restrict c1,
@@ -138,6 +365,7 @@ void opj_mct_encode_real(
c2[i] = v;
}
}
+#endif
/* <summary> */
/* Inverse irreversible MCT. */
diff --git a/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/openjpeg.h b/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/openjpeg.h
index b1e1c294c8..4a8e75ce5a 100644
--- a/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/openjpeg.h
+++ b/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/openjpeg.h
@@ -76,10 +76,36 @@ Most compilers implement their own version of this keyword ...
#define OPJ_DEPRECATED(func) func
#endif
-// PDFium doesn't need to export any of these methods.
-#define OPJ_API
-#define OPJ_LOCAL
-#define OPJ_CALLCONV
+#if defined(OPJ_STATIC) || !defined(_WIN32)
+/* http://gcc.gnu.org/wiki/Visibility */
+# if __GNUC__ >= 4
+# if defined(OPJ_STATIC) /* static library uses "hidden" */
+# define OPJ_API __attribute__ ((visibility ("hidden")))
+# else
+# define OPJ_API __attribute__ ((visibility ("default")))
+# endif
+# define OPJ_LOCAL __attribute__ ((visibility ("hidden")))
+# else
+# define OPJ_API
+# define OPJ_LOCAL
+# endif
+# define OPJ_CALLCONV
+#else
+# define OPJ_CALLCONV __stdcall
+/*
+The following ifdef block is the standard way of creating macros which make exporting
+from a DLL simpler. All files within this DLL are compiled with the OPJ_EXPORTS
+symbol defined on the command line. this symbol should not be defined on any project
+that uses this DLL. This way any other project whose source files include this file see
+OPJ_API functions as being imported from a DLL, wheras this DLL sees symbols
+defined with this macro as being exported.
+*/
+# if defined(OPJ_EXPORTS) || defined(DLL_EXPORT)
+# define OPJ_API __declspec(dllexport)
+# else
+# define OPJ_API __declspec(dllimport)
+# endif /* OPJ_EXPORTS */
+#endif /* !OPJ_STATIC || !_WIN32 */
typedef int OPJ_BOOL;
#define OPJ_TRUE 1
diff --git a/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/opj_includes.h b/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/opj_includes.h
index d9238b1bfd..e3d4686488 100644
--- a/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/opj_includes.h
+++ b/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/opj_includes.h
@@ -136,6 +136,10 @@ static INLINE long lrintf(float f){
}
#endif
+#if defined(_MSC_VER) && (_MSC_VER < 1400)
+ #define vsnprintf _vsnprintf
+#endif
+
#include "opj_inttypes.h"
#include "opj_clock.h"
#include "opj_malloc.h"
diff --git a/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/opj_intmath.h b/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/opj_intmath.h
index dc89895301..4e299469de 100644
--- a/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/opj_intmath.h
+++ b/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/opj_intmath.h
@@ -82,6 +82,15 @@ static INLINE OPJ_UINT32 opj_uint_max(OPJ_UINT32 a, OPJ_UINT32 b) {
}
/**
+ Get the saturated sum of two unsigned integers
+ @return Returns saturated sum of a+b
+ */
+static INLINE OPJ_UINT32 opj_uint_adds(OPJ_UINT32 a, OPJ_UINT32 b) {
+ OPJ_UINT64 sum = (OPJ_UINT64)a + (OPJ_UINT64)b;
+ return -(OPJ_UINT32)(sum >> 32) | (OPJ_UINT32)sum;
+}
+
+/**
Clamp an integer inside an interval
@return
<ul>
@@ -108,7 +117,7 @@ Divide an integer and round upwards
@return Returns a divided by b
*/
static INLINE OPJ_INT32 opj_int_ceildiv(OPJ_INT32 a, OPJ_INT32 b) {
- assert(b);
+ assert(b);
return (a + b - 1) / b;
}
@@ -117,6 +126,7 @@ Divide an integer and round upwards
@return Returns a divided by b
*/
static INLINE OPJ_UINT32 opj_uint_ceildiv(OPJ_UINT32 a, OPJ_UINT32 b) {
+ assert(b);
return (a + b - 1) / b;
}
@@ -165,9 +175,19 @@ Multiply two fixed-precision rational numbers.
@return Returns a * b
*/
static INLINE OPJ_INT32 opj_int_fix_mul(OPJ_INT32 a, OPJ_INT32 b) {
- OPJ_INT64 temp = (OPJ_INT64) a * (OPJ_INT64) b ;
- temp += temp & 4096;
- return (OPJ_INT32) (temp >> 13) ;
+ OPJ_INT64 temp = (OPJ_INT64) a * (OPJ_INT64) b ;
+ temp += 4096;
+ assert((temp >> 13) <= (OPJ_INT64)0x7FFFFFFF);
+ assert((temp >> 13) >= (-(OPJ_INT64)0x7FFFFFFF - (OPJ_INT64)1));
+ return (OPJ_INT32) (temp >> 13);
+}
+
+static INLINE OPJ_INT32 opj_int_fix_mul_t1(OPJ_INT32 a, OPJ_INT32 b) {
+ OPJ_INT64 temp = (OPJ_INT64) a * (OPJ_INT64) b ;
+ temp += 4096;
+ assert((temp >> (13 + 11 - T1_NMSEDEC_FRACBITS)) <= (OPJ_INT64)0x7FFFFFFF);
+ assert((temp >> (13 + 11 - T1_NMSEDEC_FRACBITS)) >= (-(OPJ_INT64)0x7FFFFFFF - (OPJ_INT64)1));
+ return (OPJ_INT32) (temp >> (13 + 11 - T1_NMSEDEC_FRACBITS)) ;
}
/* ----------------------------------------------------------------------- */
diff --git a/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/pi.c b/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/pi.c
index 65ff6263e0..393a1e5540 100644
--- a/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/pi.c
+++ b/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/pi.c
@@ -693,6 +693,9 @@ void opj_get_all_encoding_parameters( const opj_image_t *p_image,
/* position in x and y of tile*/
OPJ_UINT32 p, q;
+ /* non-corrected (in regard to image offset) tile offset */
+ OPJ_UINT32 l_tx0, l_ty0;
+
/* preconditions in debug*/
assert(p_cp != 00);
assert(p_image != 00);
@@ -708,10 +711,12 @@ void opj_get_all_encoding_parameters( const opj_image_t *p_image,
q = tileno / p_cp->tw;
/* here calculation of tx0, tx1, ty0, ty1, maxprec, l_dx and l_dy */
- *p_tx0 = opj_int_max((OPJ_INT32)(p_cp->tx0 + p * p_cp->tdx), (OPJ_INT32)p_image->x0);
- *p_tx1 = opj_int_min((OPJ_INT32)(p_cp->tx0 + (p + 1) * p_cp->tdx), (OPJ_INT32)p_image->x1);
- *p_ty0 = opj_int_max((OPJ_INT32)(p_cp->ty0 + q * p_cp->tdy), (OPJ_INT32)p_image->y0);
- *p_ty1 = opj_int_min((OPJ_INT32)(p_cp->ty0 + (q + 1) * p_cp->tdy), (OPJ_INT32)p_image->y1);
+ l_tx0 = p_cp->tx0 + p * p_cp->tdx; /* can't be greater than p_image->x1 so won't overflow */
+ *p_tx0 = (OPJ_INT32)opj_uint_max(l_tx0, p_image->x0);
+ *p_tx1 = (OPJ_INT32)opj_uint_min(opj_uint_adds(l_tx0, p_cp->tdx), p_image->x1);
+ l_ty0 = p_cp->ty0 + q * p_cp->tdy; /* can't be greater than p_image->y1 so won't overflow */
+ *p_ty0 = (OPJ_INT32)opj_uint_max(l_ty0, p_image->y0);
+ *p_ty1 = (OPJ_INT32)opj_uint_min(opj_uint_adds(l_ty0, p_cp->tdy), p_image->y1);
/* max precision and resolution is 0 (can only grow)*/
*p_max_prec = 0;
diff --git a/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/t1.c b/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/t1.c
index 11b72a33ff..8cb230f48e 100644
--- a/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/t1.c
+++ b/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/t1.c
@@ -265,7 +265,8 @@ static OPJ_FLOAT64 opj_t1_getwmsedec(
OPJ_UINT32 qmfbid,
OPJ_FLOAT64 stepsize,
OPJ_UINT32 numcomps,
- const OPJ_FLOAT64 * mct_norms);
+ const OPJ_FLOAT64 * mct_norms,
+ OPJ_UINT32 mct_numcomps);
static void opj_t1_encode_cblk( opj_t1_t *t1,
opj_tcd_cblk_enc_t* cblk,
@@ -277,7 +278,8 @@ static void opj_t1_encode_cblk( opj_t1_t *t1,
OPJ_UINT32 cblksty,
OPJ_UINT32 numcomps,
opj_tcd_tile_t * tile,
- const OPJ_FLOAT64 * mct_norms);
+ const OPJ_FLOAT64 * mct_norms,
+ OPJ_UINT32 mct_numcomps);
/**
Decode 1 code-block
@@ -1137,12 +1139,13 @@ static OPJ_FLOAT64 opj_t1_getwmsedec(
OPJ_UINT32 qmfbid,
OPJ_FLOAT64 stepsize,
OPJ_UINT32 numcomps,
- const OPJ_FLOAT64 * mct_norms)
+ const OPJ_FLOAT64 * mct_norms,
+ OPJ_UINT32 mct_numcomps)
{
OPJ_FLOAT64 w1 = 1, w2, wmsedec;
- OPJ_ARG_NOT_USED(numcomps);
+ OPJ_ARG_NOT_USED(numcomps);
- if (mct_norms) {
+ if (mct_norms && (compno < mct_numcomps)) {
w1 = mct_norms[compno];
}
@@ -1462,7 +1465,8 @@ OPJ_BOOL opj_t1_decode_cblk(opj_t1_t *t1,
OPJ_BOOL opj_t1_encode_cblks( opj_t1_t *t1,
opj_tcd_tile_t *tile,
opj_tcp_t *tcp,
- const OPJ_FLOAT64 * mct_norms
+ const OPJ_FLOAT64 * mct_norms,
+ OPJ_UINT32 mct_numcomps
)
{
OPJ_UINT32 compno, resno, bandno, precno, cblkno;
@@ -1530,9 +1534,9 @@ OPJ_BOOL opj_t1_encode_cblks( opj_t1_t *t1,
for (i = 0; i < cblk_w; ++i) {
OPJ_INT32 tmp = tiledp[tileIndex];
tiledp[tileIndex] =
- opj_int_fix_mul(
+ opj_int_fix_mul_t1(
tmp,
- bandconst) >> (11 - T1_NMSEDEC_FRACBITS);
+ bandconst);
tileIndex++;
}
tileIndex += tileLineAdvance;
@@ -1550,7 +1554,8 @@ OPJ_BOOL opj_t1_encode_cblks( opj_t1_t *t1,
tccp->cblksty,
tile->numcomps,
tile,
- mct_norms);
+ mct_norms,
+ mct_numcomps);
} /* cblkno */
} /* precno */
@@ -1571,7 +1576,8 @@ void opj_t1_encode_cblk(opj_t1_t *t1,
OPJ_UINT32 cblksty,
OPJ_UINT32 numcomps,
opj_tcd_tile_t * tile,
- const OPJ_FLOAT64 * mct_norms)
+ const OPJ_FLOAT64 * mct_norms,
+ OPJ_UINT32 mct_numcomps)
{
OPJ_FLOAT64 cumwmsedec = 0.0;
@@ -1626,7 +1632,7 @@ void opj_t1_encode_cblk(opj_t1_t *t1,
}
/* fixed_quality */
- tempwmsedec = opj_t1_getwmsedec(nmsedec, compno, level, orient, bpno, qmfbid, stepsize, numcomps,mct_norms) ;
+ tempwmsedec = opj_t1_getwmsedec(nmsedec, compno, level, orient, bpno, qmfbid, stepsize, numcomps,mct_norms, mct_numcomps) ;
cumwmsedec += tempwmsedec;
tile->distotile += tempwmsedec;
diff --git a/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/t1.h b/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/t1.h
index e1d41ed56f..3bc0ad9ea7 100644
--- a/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/t1.h
+++ b/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/t1.h
@@ -126,11 +126,13 @@ Encode the code-blocks of a tile
@param tile The tile to encode
@param tcp Tile coding parameters
@param mct_norms FIXME DOC
+@param mct_numcomps Number of components used for MCT
*/
OPJ_BOOL opj_t1_encode_cblks( opj_t1_t *t1,
opj_tcd_tile_t *tile,
opj_tcp_t *tcp,
- const OPJ_FLOAT64 * mct_norms);
+ const OPJ_FLOAT64 * mct_norms,
+ OPJ_UINT32 mct_numcomps);
/**
Decode the code-blocks of a tile
diff --git a/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/t2.c b/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/t2.c
index d0d63d2bd0..6f0ac91569 100644
--- a/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/t2.c
+++ b/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/t2.c
@@ -388,13 +388,13 @@ OPJ_BOOL opj_t2_decode_packets( opj_t2_t *p_t2,
* and no l_img_comp->resno_decoded are computed
*/
OPJ_BOOL* first_pass_failed = NULL;
-
+
if (l_current_pi->poc.prg == OPJ_PROG_UNKNOWN) {
/* TODO ADE : add an error */
opj_pi_destroy(l_pi, l_nb_pocs);
return OPJ_FALSE;
}
-
+
first_pass_failed = (OPJ_BOOL*)opj_malloc(l_image->numcomps * sizeof(OPJ_BOOL));
if (!first_pass_failed)
{
diff --git a/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/tcd.c b/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/tcd.c
index 6c04f3d8b7..f62312027d 100644
--- a/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/tcd.c
+++ b/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/tcd.c
@@ -120,11 +120,16 @@ static OPJ_BOOL opj_tcd_code_block_dec_allocate (opj_tcd_cblk_dec_t * p_code_blo
static void opj_tcd_code_block_dec_deallocate (opj_tcd_precinct_t * p_precinct);
/**
- * Allocates memory for an encoding code block.
+ * Allocates memory for an encoding code block (but not data).
*/
static OPJ_BOOL opj_tcd_code_block_enc_allocate (opj_tcd_cblk_enc_t * p_code_block);
/**
+ * Allocates data for an encoding code block
+ */
+static OPJ_BOOL opj_tcd_code_block_enc_allocate_data (opj_tcd_cblk_enc_t * p_code_block);
+
+/**
* Deallocates the encoding data of the given precinct.
*/
static void opj_tcd_code_block_enc_deallocate (opj_tcd_precinct_t * p_precinct);
@@ -670,6 +675,7 @@ static INLINE OPJ_BOOL opj_tcd_init_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no,
OPJ_UINT32 l_pdx, l_pdy;
OPJ_UINT32 l_gain;
OPJ_INT32 l_x0b, l_y0b;
+ OPJ_UINT32 l_tx0, l_ty0;
/* extent of precincts , top left, bottom right**/
OPJ_INT32 l_tl_prc_x_start, l_tl_prc_y_start, l_br_prc_x_end, l_br_prc_y_end;
/* number of precinct for a resolution */
@@ -682,7 +688,7 @@ static INLINE OPJ_BOOL opj_tcd_init_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no,
OPJ_UINT32 l_nb_code_blocks_size;
/* size of data for a tile */
OPJ_UINT32 l_data_size;
-
+
l_cp = p_tcd->cp;
l_tcp = &(l_cp->tcps[p_tile_no]);
l_tile = p_tcd->tcd_image->tiles;
@@ -690,23 +696,26 @@ static INLINE OPJ_BOOL opj_tcd_init_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no,
l_tilec = l_tile->comps;
l_image = p_tcd->image;
l_image_comp = p_tcd->image->comps;
-
+
p = p_tile_no % l_cp->tw; /* tile coordinates */
q = p_tile_no / l_cp->tw;
/*fprintf(stderr, "Tile coordinate = %d,%d\n", p, q);*/
-
+
/* 4 borders of the tile rescale on the image if necessary */
- l_tile->x0 = opj_int_max((OPJ_INT32)(l_cp->tx0 + p * l_cp->tdx), (OPJ_INT32)l_image->x0);
- l_tile->y0 = opj_int_max((OPJ_INT32)(l_cp->ty0 + q * l_cp->tdy), (OPJ_INT32)l_image->y0);
- l_tile->x1 = opj_int_min((OPJ_INT32)(l_cp->tx0 + (p + 1) * l_cp->tdx), (OPJ_INT32)l_image->x1);
- l_tile->y1 = opj_int_min((OPJ_INT32)(l_cp->ty0 + (q + 1) * l_cp->tdy), (OPJ_INT32)l_image->y1);
+ l_tx0 = l_cp->tx0 + p * l_cp->tdx; /* can't be greater than l_image->x1 so won't overflow */
+ l_tile->x0 = (OPJ_INT32)opj_uint_max(l_tx0, l_image->x0);
+ l_tile->x1 = (OPJ_INT32)opj_uint_min(opj_uint_adds(l_tx0, l_cp->tdx), l_image->x1);
+ l_ty0 = l_cp->ty0 + q * l_cp->tdy; /* can't be greater than l_image->y1 so won't overflow */
+ l_tile->y0 = (OPJ_INT32)opj_uint_max(l_ty0, l_image->y0);
+ l_tile->y1 = (OPJ_INT32)opj_uint_min(opj_uint_adds(l_ty0, l_cp->tdy), l_image->y1);
+
/* testcase 1888.pdf.asan.35.988 */
if (l_tccp->numresolutions == 0) {
fprintf(stderr, "tiles require at least one resolution\n");
return OPJ_FALSE;
}
/*fprintf(stderr, "Tile border = %d,%d,%d,%d\n", l_tile->x0, l_tile->y0,l_tile->x1,l_tile->y1);*/
-
+
/*tile->numcomps = image->numcomps; */
for (compno = 0; compno < l_tile->numcomps; ++compno) {
/*fprintf(stderr, "compno = %d/%d\n", compno, l_tile->numcomps);*/
@@ -717,7 +726,7 @@ static INLINE OPJ_BOOL opj_tcd_init_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no,
l_tilec->x1 = opj_int_ceildiv(l_tile->x1, (OPJ_INT32)l_image_comp->dx);
l_tilec->y1 = opj_int_ceildiv(l_tile->y1, (OPJ_INT32)l_image_comp->dy);
/*fprintf(stderr, "\tTile compo border = %d,%d,%d,%d\n", l_tilec->x0, l_tilec->y0,l_tilec->x1,l_tilec->y1);*/
-
+
/* compute l_data_size with overflow check */
l_data_size = (OPJ_UINT32)(l_tilec->x1 - l_tilec->x0);
if ((((OPJ_UINT32)-1) / l_data_size) < (OPJ_UINT32)(l_tilec->y1 - l_tilec->y0)) {
@@ -725,7 +734,7 @@ static INLINE OPJ_BOOL opj_tcd_init_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no,
return OPJ_FALSE;
}
l_data_size = l_data_size * (OPJ_UINT32)(l_tilec->y1 - l_tilec->y0);
-
+
if ((((OPJ_UINT32)-1) / (OPJ_UINT32)sizeof(OPJ_UINT32)) < l_data_size) {
/* TODO event */
return OPJ_FALSE;
@@ -738,14 +747,14 @@ static INLINE OPJ_BOOL opj_tcd_init_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no,
else {
l_tilec->minimum_num_resolutions = l_tccp->numresolutions - l_cp->m_specific_param.m_dec.m_reduce;
}
-
+
l_tilec->data_size_needed = l_data_size;
if (p_tcd->m_is_decoder && !opj_alloc_tile_component_data(l_tilec)) {
return OPJ_FALSE;
}
-
+
l_data_size = l_tilec->numresolutions * (OPJ_UINT32)sizeof(opj_tcd_resolution_t);
-
+
if (l_tilec->resolutions == 00) {
l_tilec->resolutions = (opj_tcd_resolution_t *) opj_malloc(l_data_size);
if (! l_tilec->resolutions ) {
@@ -770,7 +779,7 @@ static INLINE OPJ_BOOL opj_tcd_init_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no,
memset(((OPJ_BYTE*) l_tilec->resolutions)+l_tilec->resolutions_size,0,l_data_size - l_tilec->resolutions_size);
l_tilec->resolutions_size = l_data_size;
}
-
+
l_level_no = l_tilec->numresolutions - 1;
l_res = l_tilec->resolutions;
l_step_size = l_tccp->stepsizes;
@@ -781,13 +790,13 @@ static INLINE OPJ_BOOL opj_tcd_init_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no,
l_gain_ptr = &opj_dwt_getgain;
}
/*fprintf(stderr, "\tlevel_no=%d\n",l_level_no);*/
-
+
for (resno = 0; resno < l_tilec->numresolutions; ++resno) {
/*fprintf(stderr, "\t\tresno = %d/%d\n", resno, l_tilec->numresolutions);*/
OPJ_INT32 tlcbgxstart, tlcbgystart /*, brcbgxend, brcbgyend*/;
OPJ_UINT32 cbgwidthexpn, cbgheightexpn;
OPJ_UINT32 cblkwidthexpn, cblkheightexpn;
-
+
/* border for each resolution level (global) */
l_res->x0 = opj_int_ceildivpow2(l_tilec->x0, (OPJ_INT32)l_level_no);
l_res->y0 = opj_int_ceildivpow2(l_tilec->y0, (OPJ_INT32)l_level_no);
@@ -804,11 +813,11 @@ static INLINE OPJ_BOOL opj_tcd_init_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no,
l_br_prc_x_end = opj_int_ceildivpow2(l_res->x1, (OPJ_INT32)l_pdx) << l_pdx;
l_br_prc_y_end = opj_int_ceildivpow2(l_res->y1, (OPJ_INT32)l_pdy) << l_pdy;
/*fprintf(stderr, "\t\t\tprc_x_start=%d, prc_y_start=%d, br_prc_x_end=%d, br_prc_y_end=%d \n", l_tl_prc_x_start, l_tl_prc_y_start, l_br_prc_x_end ,l_br_prc_y_end );*/
-
+
l_res->pw = (l_res->x0 == l_res->x1) ? 0 : (OPJ_UINT32)((l_br_prc_x_end - l_tl_prc_x_start) >> l_pdx);
l_res->ph = (l_res->y0 == l_res->y1) ? 0 : (OPJ_UINT32)((l_br_prc_y_end - l_tl_prc_y_start) >> l_pdy);
/*fprintf(stderr, "\t\t\tres_pw=%d, res_ph=%d\n", l_res->pw, l_res->ph );*/
-
+
l_nb_precincts = l_res->pw * l_res->ph;
l_nb_precinct_size = l_nb_precincts * (OPJ_UINT32)sizeof(opj_tcd_precinct_t);
if (resno == 0) {
@@ -829,15 +838,15 @@ static INLINE OPJ_BOOL opj_tcd_init_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no,
cbgheightexpn = l_pdy - 1;
l_res->numbands = 3;
}
-
+
cblkwidthexpn = opj_uint_min(l_tccp->cblkw, cbgwidthexpn);
cblkheightexpn = opj_uint_min(l_tccp->cblkh, cbgheightexpn);
l_band = l_res->bands;
-
+
for (bandno = 0; bandno < l_res->numbands; ++bandno) {
OPJ_INT32 numbps;
/*fprintf(stderr, "\t\t\tband_no=%d/%d\n", bandno, l_res->numbands );*/
-
+
if (resno == 0) {
l_band->bandno = 0 ;
l_band->x0 = opj_int_ceildivpow2(l_tilec->x0, (OPJ_INT32)l_level_no);
@@ -857,13 +866,13 @@ static INLINE OPJ_BOOL opj_tcd_init_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no,
l_band->x1 = opj_int_ceildivpow2(l_tilec->x1 - (1 << l_level_no) * l_x0b, (OPJ_INT32)(l_level_no + 1));
l_band->y1 = opj_int_ceildivpow2(l_tilec->y1 - (1 << l_level_no) * l_y0b, (OPJ_INT32)(l_level_no + 1));
}
-
+
/** avoid an if with storing function pointer */
l_gain = (*l_gain_ptr) (l_band->bandno);
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, (OPJ_INT32) (numbps - l_step_size->expn)))) * fraction;
l_band->numbps = l_step_size->expn + (OPJ_INT32)l_tccp->numgbits - 1; /* WHY -1 ? */
-
+
if (! l_band->precincts) {
l_band->precincts = (opj_tcd_precinct_t *) opj_malloc( /*3 * */ l_nb_precinct_size);
if (! l_band->precincts) {
@@ -874,7 +883,7 @@ static INLINE OPJ_BOOL opj_tcd_init_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no,
l_band->precincts_data_size = l_nb_precinct_size;
}
else if (l_band->precincts_data_size < l_nb_precinct_size) {
-
+
opj_tcd_precinct_t * new_precincts = (opj_tcd_precinct_t *) opj_realloc(l_band->precincts,/*3 * */ l_nb_precinct_size);
if (! new_precincts) {
/* opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to handle band precints\n"); */
@@ -889,7 +898,7 @@ static INLINE OPJ_BOOL opj_tcd_init_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no,
memset(((OPJ_BYTE *) l_band->precincts) + l_band->precincts_data_size,0,l_nb_precinct_size - l_band->precincts_data_size);
l_band->precincts_data_size = l_nb_precinct_size;
}
-
+
l_current_precinct = l_band->precincts;
for (precno = 0; precno < l_nb_precincts; ++precno) {
OPJ_INT32 tlcblkxstart, tlcblkystart, brcblkxend, brcblkyend;
@@ -899,16 +908,16 @@ static INLINE OPJ_BOOL opj_tcd_init_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no,
OPJ_INT32 cbgyend = cbgystart + (1 << cbgheightexpn);
/*fprintf(stderr, "\t precno=%d; bandno=%d, resno=%d; compno=%d\n", precno, bandno , resno, compno);*/
/*fprintf(stderr, "\t tlcbgxstart(=%d) + (precno(=%d) percent res->pw(=%d)) * (1 << cbgwidthexpn(=%d)) \n",tlcbgxstart,precno,l_res->pw,cbgwidthexpn);*/
-
+
/* precinct size (global) */
/*fprintf(stderr, "\t cbgxstart=%d, l_band->x0 = %d \n",cbgxstart, l_band->x0);*/
-
+
l_current_precinct->x0 = opj_int_max(cbgxstart, l_band->x0);
l_current_precinct->y0 = opj_int_max(cbgystart, l_band->y0);
l_current_precinct->x1 = opj_int_min(cbgxend, l_band->x1);
l_current_precinct->y1 = opj_int_min(cbgyend, l_band->y1);
/*fprintf(stderr, "\t prc_x0=%d; prc_y0=%d, prc_x1=%d; prc_y1=%d\n",l_current_precinct->x0, l_current_precinct->y0 ,l_current_precinct->x1, l_current_precinct->y1);*/
-
+
tlcblkxstart = opj_int_floordivpow2(l_current_precinct->x0, (OPJ_INT32)cblkwidthexpn) << cblkwidthexpn;
/*fprintf(stderr, "\t tlcblkxstart =%d\n",tlcblkxstart );*/
tlcblkystart = opj_int_floordivpow2(l_current_precinct->y0, (OPJ_INT32)cblkheightexpn) << cblkheightexpn;
@@ -919,20 +928,20 @@ static INLINE OPJ_BOOL opj_tcd_init_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no,
/*fprintf(stderr, "\t brcblkyend =%d\n",brcblkyend );*/
l_current_precinct->cw = (OPJ_UINT32)((brcblkxend - tlcblkxstart) >> cblkwidthexpn);
l_current_precinct->ch = (OPJ_UINT32)((brcblkyend - tlcblkystart) >> cblkheightexpn);
-
+
l_nb_code_blocks = l_current_precinct->cw * l_current_precinct->ch;
/*fprintf(stderr, "\t\t\t\t precinct_cw = %d x recinct_ch = %d\n",l_current_precinct->cw, l_current_precinct->ch); */
l_nb_code_blocks_size = l_nb_code_blocks * (OPJ_UINT32)sizeof_block;
-
+
if (! l_current_precinct->cblks.blocks) {
l_current_precinct->cblks.blocks = opj_malloc(l_nb_code_blocks_size);
if (! l_current_precinct->cblks.blocks ) {
return OPJ_FALSE;
}
/*fprintf(stderr, "\t\t\t\tAllocate cblks of a precinct (opj_tcd_cblk_dec_t): %d\n",l_nb_code_blocks_size);*/
-
+
memset(l_current_precinct->cblks.blocks,0,l_nb_code_blocks_size);
-
+
l_current_precinct->block_size = l_nb_code_blocks_size;
}
else if (l_nb_code_blocks_size > l_current_precinct->block_size) {
@@ -947,14 +956,14 @@ static INLINE OPJ_BOOL opj_tcd_init_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no,
}
l_current_precinct->cblks.blocks = new_blocks;
/*fprintf(stderr, "\t\t\t\tReallocate cblks of a precinct (opj_tcd_cblk_dec_t): from %d to %d\n",l_current_precinct->block_size, l_nb_code_blocks_size); */
-
+
memset(((OPJ_BYTE *) l_current_precinct->cblks.blocks) + l_current_precinct->block_size
,0
,l_nb_code_blocks_size - l_current_precinct->block_size);
-
+
l_current_precinct->block_size = l_nb_code_blocks_size;
}
-
+
if (! l_current_precinct->incltree) {
l_current_precinct->incltree = opj_tgt_create(l_current_precinct->cw,
l_current_precinct->ch);
@@ -992,10 +1001,10 @@ static INLINE OPJ_BOOL opj_tcd_init_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no,
OPJ_INT32 cblkystart = tlcblkystart + (OPJ_INT32)(cblkno / l_current_precinct->cw) * (1 << cblkheightexpn);
OPJ_INT32 cblkxend = cblkxstart + (1 << cblkwidthexpn);
OPJ_INT32 cblkyend = cblkystart + (1 << cblkheightexpn);
-
+
if (isEncoder) {
opj_tcd_cblk_enc_t* l_code_block = l_current_precinct->cblks.enc + cblkno;
-
+
if (! opj_tcd_code_block_enc_allocate(l_code_block)) {
return OPJ_FALSE;
}
@@ -1004,9 +1013,13 @@ static INLINE OPJ_BOOL opj_tcd_init_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no,
l_code_block->y0 = opj_int_max(cblkystart, l_current_precinct->y0);
l_code_block->x1 = opj_int_min(cblkxend, l_current_precinct->x1);
l_code_block->y1 = opj_int_min(cblkyend, l_current_precinct->y1);
+
+ if (! opj_tcd_code_block_enc_allocate_data(l_code_block)) {
+ return OPJ_FALSE;
+ }
} else {
opj_tcd_cblk_dec_t* l_code_block = l_current_precinct->cblks.dec + cblkno;
-
+
if (! opj_tcd_code_block_dec_allocate(l_code_block)) {
return OPJ_FALSE;
}
@@ -1043,39 +1056,56 @@ OPJ_BOOL opj_tcd_init_decode_tile (opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no)
}
/**
- * Allocates memory for an encoding code block.
+ * Allocates memory for an encoding code block (but not data memory).
*/
-OPJ_BOOL opj_tcd_code_block_enc_allocate (opj_tcd_cblk_enc_t * p_code_block)
+static OPJ_BOOL opj_tcd_code_block_enc_allocate (opj_tcd_cblk_enc_t * p_code_block)
{
- if (! p_code_block->data) {
-
- p_code_block->data = (OPJ_BYTE*) opj_malloc(OPJ_J2K_DEFAULT_CBLK_DATA_SIZE*2); /*why +1 ?*/
- if(! p_code_block->data) {
- return OPJ_FALSE;
- }
-
- p_code_block->data[0] = 0;
- p_code_block->data+=1;
-
- /* no memset since data */
- p_code_block->layers = (opj_tcd_layer_t*) opj_calloc(100, sizeof(opj_tcd_layer_t));
- if (! p_code_block->layers) {
- return OPJ_FALSE;
- }
-
- p_code_block->passes = (opj_tcd_pass_t*) opj_calloc(100, sizeof(opj_tcd_pass_t));
- if (! p_code_block->passes) {
- return OPJ_FALSE;
- }
- }
+ if (! p_code_block->layers) {
+ /* no memset since data */
+ p_code_block->layers = (opj_tcd_layer_t*) opj_calloc(100, sizeof(opj_tcd_layer_t));
+ if (! p_code_block->layers) {
+ return OPJ_FALSE;
+ }
+ }
+ if (! p_code_block->passes) {
+ p_code_block->passes = (opj_tcd_pass_t*) opj_calloc(100, sizeof(opj_tcd_pass_t));
+ if (! p_code_block->passes) {
+ return OPJ_FALSE;
+ }
+ }
+ return OPJ_TRUE;
+}
- return OPJ_TRUE;
+/**
+ * Allocates data memory for an encoding code block.
+ */
+static OPJ_BOOL opj_tcd_code_block_enc_allocate_data (opj_tcd_cblk_enc_t * p_code_block)
+{
+ OPJ_UINT32 l_data_size;
+
+ l_data_size = (OPJ_UINT32)((p_code_block->x1 - p_code_block->x0) * (p_code_block->y1 - p_code_block->y0) * (OPJ_INT32)sizeof(OPJ_UINT32));
+
+ if (l_data_size > p_code_block->data_size) {
+ if (p_code_block->data) {
+ opj_free(p_code_block->data - 1); /* again, why -1 */
+ }
+ p_code_block->data = (OPJ_BYTE*) opj_malloc(l_data_size);
+ if(! p_code_block->data) {
+ p_code_block->data_size = 0U;
+ return OPJ_FALSE;
+ }
+ p_code_block->data_size = l_data_size;
+
+ p_code_block->data[0] = 0;
+ p_code_block->data+=1; /*why +1 ?*/
+ }
+ return OPJ_TRUE;
}
/**
* Allocates memory for a decoding code block.
*/
-OPJ_BOOL opj_tcd_code_block_dec_allocate (opj_tcd_cblk_dec_t * p_code_block)
+static OPJ_BOOL opj_tcd_code_block_dec_allocate (opj_tcd_cblk_dec_t * p_code_block)
{
if (! p_code_block->data) {
@@ -1989,6 +2019,7 @@ OPJ_BOOL opj_tcd_t1_encode ( opj_tcd_t *p_tcd )
{
opj_t1_t * l_t1;
const OPJ_FLOAT64 * l_mct_norms;
+ OPJ_UINT32 l_mct_numcomps = 0U;
opj_tcp_t * l_tcp = p_tcd->tcp;
l_t1 = opj_t1_create(OPJ_TRUE);
@@ -1997,6 +2028,7 @@ OPJ_BOOL opj_tcd_t1_encode ( opj_tcd_t *p_tcd )
}
if (l_tcp->mct == 1) {
+ l_mct_numcomps = 3U;
/* irreversible encoding */
if (l_tcp->tccps->qmfbid == 0) {
l_mct_norms = opj_mct_get_mct_norms_real();
@@ -2006,10 +2038,11 @@ OPJ_BOOL opj_tcd_t1_encode ( opj_tcd_t *p_tcd )
}
}
else {
+ l_mct_numcomps = p_tcd->image->numcomps;
l_mct_norms = (const OPJ_FLOAT64 *) (l_tcp->mct_norms);
}
- if (! opj_t1_encode_cblks(l_t1, p_tcd->tcd_image->tiles , l_tcp, l_mct_norms)) {
+ if (! opj_t1_encode_cblks(l_t1, p_tcd->tcd_image->tiles , l_tcp, l_mct_norms, l_mct_numcomps)) {
opj_t1_destroy(l_t1);
return OPJ_FALSE;
}
diff --git a/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/tcd.h b/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/tcd.h
index 3cb38d26c5..9bef0fe7d9 100644
--- a/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/tcd.h
+++ b/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/tcd.h
@@ -87,15 +87,16 @@ typedef struct opj_tcd_layer {
FIXME DOC
*/
typedef struct opj_tcd_cblk_enc {
- OPJ_BYTE* data; /* Data */
- opj_tcd_layer_t* layers; /* layer information */
- opj_tcd_pass_t* passes; /* information about the passes */
- OPJ_INT32 x0, y0, x1, y1; /* dimension of the code-blocks : left upper corner (x0, y0) right low corner (x1,y1) */
+ OPJ_BYTE* data; /* Data */
+ opj_tcd_layer_t* layers; /* layer information */
+ opj_tcd_pass_t* passes; /* information about the passes */
+ OPJ_INT32 x0, y0, x1, y1; /* dimension of the code-blocks : left upper corner (x0, y0) right low corner (x1,y1) */
OPJ_UINT32 numbps;
OPJ_UINT32 numlenbits;
- OPJ_UINT32 numpasses; /* number of pass already done for the code-blocks */
- OPJ_UINT32 numpassesinlayers; /* number of passes in the layer */
- OPJ_UINT32 totalpasses; /* total number of passes */
+ OPJ_UINT32 data_size; /* Size of allocated data buffer */
+ OPJ_UINT32 numpasses; /* number of pass already done for the code-blocks */
+ OPJ_UINT32 numpassesinlayers; /* number of passes in the layer */
+ OPJ_UINT32 totalpasses; /* total number of passes */
} opj_tcd_cblk_enc_t;
@@ -105,7 +106,7 @@ typedef struct opj_tcd_cblk_dec {
OPJ_INT32 x0, y0, x1, y1; /* position of the code-blocks : left upper corner (x0, y0) right low corner (x1,y1) */
OPJ_UINT32 numbps;
OPJ_UINT32 numlenbits;
- OPJ_UINT32 data_max_size; /* Size of allocated data buffer */
+ OPJ_UINT32 data_max_size; /* Size of allocated data buffer */
OPJ_UINT32 data_current_size; /* Size of used data buffer */
OPJ_UINT32 numnewpasses; /* number of pass added to the code-blocks */
OPJ_UINT32 numsegs; /* number of segments */