summaryrefslogtreecommitdiff
path: root/source/fitz/load-jpx.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/fitz/load-jpx.c')
-rw-r--r--source/fitz/load-jpx.c159
1 files changed, 56 insertions, 103 deletions
diff --git a/source/fitz/load-jpx.c b/source/fitz/load-jpx.c
index a1c39f9f..fb4e66de 100644
--- a/source/fitz/load-jpx.c
+++ b/source/fitz/load-jpx.c
@@ -634,18 +634,6 @@ static OPJ_BOOL fz_opj_stream_seek(OPJ_OFF_T seek_pos, void * p_user_data)
return OPJ_TRUE;
}
-static int
-l2subfactor(fz_context *ctx, unsigned int max_w, unsigned int w)
-{
- int i;
-
- for (i = 0; max_w != 0 && w != max_w; i++)
- max_w >>= 1;
- if (max_w == 0)
- return -1;
- return i;
-}
-
static fz_pixmap *
jpx_read_image(fz_context *ctx, fz_jpxd *state, const unsigned char *data, size_t size, fz_colorspace *defcs, int onlymeta)
{
@@ -654,15 +642,10 @@ jpx_read_image(fz_context *ctx, fz_jpxd *state, const unsigned char *data, size_
opj_codec_t *codec;
opj_image_t *jpx;
opj_stream_t *stream;
- unsigned char *p;
OPJ_CODEC_FORMAT format;
- int a, n, w, h, depth, sgnd;
- int x, y, k, v, stride;
+ int a, n, w, h;
+ int x, y, k;
stream_block sb;
- unsigned int max_w, max_h;
- int sub_w[FZ_MAX_COLORS];
- int sub_h[FZ_MAX_COLORS];
- int upsample_required = 0;
OPJ_UINT32 i;
fz_var(img);
@@ -724,9 +707,6 @@ jpx_read_image(fz_context *ctx, fz_jpxd *state, const unsigned char *data, size_
if (!jpx)
fz_throw(ctx, FZ_ERROR_GENERIC, "opj_decode failed");
- depth = jpx->comps[0].prec;
- sgnd = jpx->comps[0].sgnd;
-
/* Count number of alpha and color channels */
n = a = 0;
for (i = 0; i < jpx->numcomps; ++i)
@@ -737,6 +717,22 @@ jpx_read_image(fz_context *ctx, fz_jpxd *state, const unsigned char *data, size_
++n;
}
+ for (k = 1; k < n + a; k++)
+ {
+ if (!jpx->comps[k].data)
+ {
+ opj_image_destroy(jpx);
+ fz_throw(ctx, FZ_ERROR_GENERIC, "image components are missing data");
+ }
+ }
+
+ state->width = w = jpx->x1 - jpx->x0;
+ state->height = h = jpx->y1 - jpx->y0;
+ state->xres = 72; /* openjpeg does not read the JPEG 2000 resc box */
+ state->yres = 72; /* openjpeg does not read the JPEG 2000 resc box */
+
+ state->cs = NULL;
+
if (defcs)
{
if (fz_colorspace_n(ctx, defcs) == n)
@@ -765,44 +761,6 @@ jpx_read_image(fz_context *ctx, fz_jpxd *state, const unsigned char *data, size_
}
}
- max_w = jpx->comps[0].w;
- max_h = jpx->comps[0].h;
- for (k = 1; k < n + a; k++)
- {
- if (max_w < jpx->comps[k].w)
- max_w = jpx->comps[k].w;
- if (max_h < jpx->comps[k].w)
- max_h = jpx->comps[k].h;
- if (!jpx->comps[k].data)
- {
- opj_image_destroy(jpx);
- fz_throw(ctx, FZ_ERROR_GENERIC, "image components are missing data");
- }
- if (jpx->comps[k].prec != jpx->comps[0].prec)
- {
- opj_image_destroy(jpx);
- fz_throw(ctx, FZ_ERROR_GENERIC, "image components have different precision");
- }
- }
-
- for (k = 0; k < n + a; k++)
- {
- sub_w[k] = l2subfactor(ctx, max_w, jpx->comps[k].w);
- sub_h[k] = l2subfactor(ctx, max_h, jpx->comps[k].h);
- if (sub_w[k] == -1 || sub_h[k] == -1)
- {
- opj_image_destroy(jpx);
- fz_throw(ctx, FZ_ERROR_GENERIC, "image components are of incompatible dimensions");
- }
- if (sub_w[k] != 0 || sub_h[k] != 0)
- upsample_required = 1;
- }
-
- state->width = w = (int)max_w;
- state->height = h = (int)max_h;
- state->xres = 72; /* openjpeg does not read the JPEG 2000 resc box */
- state->yres = 72; /* openjpeg does not read the JPEG 2000 resc box */
-
if (onlymeta)
{
opj_image_destroy(jpx);
@@ -811,58 +769,53 @@ jpx_read_image(fz_context *ctx, fz_jpxd *state, const unsigned char *data, size_
fz_try(ctx)
{
+ unsigned char *samples;
+ int stride, comps;
+
a = !!a; /* ignore any superfluous alpha channels */
img = fz_new_pixmap(ctx, state->cs, w, h, NULL, a);
+ stride = fz_pixmap_stride(ctx, img);
+ comps = fz_pixmap_components(ctx, img);
+ samples = fz_pixmap_samples(ctx, img);
- p = img->samples;
- if (upsample_required)
- {
- stride = img->stride;
- for (y = 0; y < h; y++)
- {
- for (k = 0; k < n + a; k++)
- {
- int sh = sub_h[k];
- int sw = sub_w[k];
- int yy = (y>>sh) * (jpx->comps[k].w >> sw);
- OPJ_INT32 *data = &jpx->comps[k].data[yy];
- for (x = 0; x < w; x ++)
- {
- v = data[x>>sw];
- if (sgnd)
- v = v + (1 << (depth - 1));
- if (depth > 8)
- v = v >> (depth - 8);
- else if (depth < 8)
- v = v << (8 - depth);
- *p = v;
- p += n + a;
- }
- p += 1 - w * (n + a);
- }
- p += stride - (n + a);
- }
- }
- else
+ fz_clear_pixmap_with_value(ctx, img, 0);
+
+ for (k = 0; k < comps; k++)
{
- stride = img->stride - w * (n + a);
- for (y = 0; y < h; y++)
+ opj_image_comp_t *comp = &(jpx->comps[k]);
+ int oy = comp->y0 * comp->dy - jpx->y0;
+ int ox = comp->x0 * comp->dx - jpx->x0;
+
+ for (y = 0; y < comp->h; y++)
{
- for (x = 0; x < w; x++)
+ for (x = 0; x < comp->w; x++)
{
- for (k = 0; k < n + a; k++)
+ OPJ_INT32 v;
+ int dx;
+ int dy;
+
+ v = comp->data[y * comp->w + x];
+
+ if (comp->sgnd)
+ v = v + (1 << (comp->prec - 1));
+ if (comp->prec > 8)
+ v = v >> (comp->prec - 8);
+ else if (comp->prec < 8)
+ v = v << (8 - comp->prec);
+
+ for (dy = 0; dy < comp->dy; dy++)
{
- v = jpx->comps[k].data[y * w + x];
- if (sgnd)
- v = v + (1 << (depth - 1));
- if (depth > 8)
- v = v >> (depth - 8);
- else if (depth < 8)
- v = v << (8 - depth);
- *p++ = v;
+ for (dx = 0; dx < comp->dx; dx++)
+ {
+ int xx = ox + x * comp->dx + dx;
+ int yy = oy + y * comp->dy + dy;
+
+ if (xx < w && yy < h)
+ samples[yy * stride + xx * comps + k] = v;
+ }
}
+
}
- p += stride;
}
}