summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Rasmussen <sebras@gmail.com>2016-06-26 07:22:22 +0200
committerSebastian Rasmussen <sebras@gmail.com>2016-07-05 02:28:39 +0800
commitd42362b328019e106b1b6bfb267ada7844158b6e (patch)
treeece9821083dc0c8c2c9e5c56a409ec16691dca6d
parent653e62cf843fa04c9bc358130daab0285eb21fe6 (diff)
downloadmupdf-d42362b328019e106b1b6bfb267ada7844158b6e.tar.xz
Support J2K/JP2 files in CBZ.
-rw-r--r--include/mupdf/fitz/compressed-buffer.h2
-rw-r--r--include/mupdf/fitz/image.h1
-rw-r--r--source/cbz/mucbz.c2
-rw-r--r--source/cbz/muimg.c9
-rw-r--r--source/fitz/image.c15
-rw-r--r--source/fitz/load-jpx.c75
6 files changed, 72 insertions, 32 deletions
diff --git a/include/mupdf/fitz/compressed-buffer.h b/include/mupdf/fitz/compressed-buffer.h
index 092d5fe3..1eef070d 100644
--- a/include/mupdf/fitz/compressed-buffer.h
+++ b/include/mupdf/fitz/compressed-buffer.h
@@ -19,7 +19,7 @@ enum
{
FZ_IMAGE_UNKNOWN = 0,
FZ_IMAGE_JPEG = 1,
- FZ_IMAGE_JPX = 2, /* Placeholder until supported */
+ FZ_IMAGE_JPX = 2,
FZ_IMAGE_FAX = 3,
FZ_IMAGE_JBIG2 = 4,
FZ_IMAGE_RAW = 5,
diff --git a/include/mupdf/fitz/image.h b/include/mupdf/fitz/image.h
index 337fd075..bc2879d9 100644
--- a/include/mupdf/fitz/image.h
+++ b/include/mupdf/fitz/image.h
@@ -115,6 +115,7 @@ fz_pixmap *fz_load_gif(fz_context *ctx, unsigned char *data, size_t size);
fz_pixmap *fz_load_bmp(fz_context *ctx, unsigned char *data, size_t size);
void fz_load_jpeg_info(fz_context *ctx, unsigned char *data, size_t size, int *w, int *h, int *xres, int *yres, fz_colorspace **cspace);
+void fz_load_jpx_info(fz_context *ctx, unsigned char *data, size_t size, int *w, int *h, int *xres, int *yres, fz_colorspace **cspace);
void fz_load_png_info(fz_context *ctx, unsigned char *data, size_t size, int *w, int *h, int *xres, int *yres, fz_colorspace **cspace);
void fz_load_tiff_info(fz_context *ctx, unsigned char *data, size_t size, int *w, int *h, int *xres, int *yres, fz_colorspace **cspace);
void fz_load_jxr_info(fz_context *ctx, unsigned char *data, size_t size, int *w, int *h, int *xres, int *yres, fz_colorspace **cspace);
diff --git a/source/cbz/mucbz.c b/source/cbz/mucbz.c
index 74b96268..0b7b4d10 100644
--- a/source/cbz/mucbz.c
+++ b/source/cbz/mucbz.c
@@ -6,7 +6,7 @@ typedef struct cbz_document_s cbz_document;
typedef struct cbz_page_s cbz_page;
static const char *cbz_ext_list[] = {
- ".jpg", ".jpeg", ".png", ".gif", ".bmp", ".tif", ".tiff",
+ ".jpg", ".jpeg", ".png", ".gif", ".bmp", ".tif", ".tiff", ".jpx", ".jp2", ".j2k",
NULL
};
diff --git a/source/cbz/muimg.c b/source/cbz/muimg.c
index d0087fa7..4e0f97df 100644
--- a/source/cbz/muimg.c
+++ b/source/cbz/muimg.c
@@ -159,7 +159,9 @@ img_recognize(fz_context *doc, const char *magic)
if (!fz_strcasecmp(ext, ".png") || !fz_strcasecmp(ext, ".jpg") ||
!fz_strcasecmp(ext, ".jpeg") || !fz_strcasecmp(ext, ".jfif") ||
!fz_strcasecmp(ext, ".jfif-tbnl") || !fz_strcasecmp(ext, ".jpe") ||
- !fz_strcasecmp(ext, ".gif") || !fz_strcasecmp(ext, ".bmp"))
+ !fz_strcasecmp(ext, ".gif") || !fz_strcasecmp(ext, ".bmp") ||
+ !fz_strcasecmp(ext, ".jpx") || !fz_strcasecmp(ext, ".jp2") ||
+ !fz_strcasecmp(ext, ".j2k"))
return 100;
}
if (!strcmp(magic, "png") || !strcmp(magic, "image/png") ||
@@ -167,7 +169,10 @@ img_recognize(fz_context *doc, const char *magic)
!strcmp(magic, "jpeg") || !strcmp(magic, "image/pjpeg") ||
!strcmp(magic, "jpe") || !strcmp(magic, "jfif") ||
!strcmp(magic, "gif") || !strcmp(magic, "image/gif") ||
- !strcmp(magic, "bmp") || !strcmp(magic, "image/bmp"))
+ !strcmp(magic, "bmp") || !strcmp(magic, "image/bmp") ||
+ !strcmp(magic, "jpx") || !strcmp(magic, "image/jpx") ||
+ !strcmp(magic, "jp2") || !strcmp(magic, "image/jp2") ||
+ !strcmp(magic, "j2k"))
return 100;
return 0;
diff --git a/source/fitz/image.c b/source/fitz/image.c
index b4314480..6919808a 100644
--- a/source/fitz/image.c
+++ b/source/fitz/image.c
@@ -410,6 +410,9 @@ compressed_image_get_pixmap(fz_context *ctx, fz_image *image_, fz_irect *subarea
case FZ_IMAGE_JXR:
tile = fz_load_jxr(ctx, image->buffer->buffer->data, image->buffer->buffer->len);
break;
+ case FZ_IMAGE_JPX:
+ tile = fz_load_jpx(ctx, image->buffer->buffer->data, image->buffer->buffer->len, NULL, 0);
+ break;
case FZ_IMAGE_JPEG:
/* Scan JPEG stream and patch missing height values in header */
{
@@ -912,7 +915,17 @@ fz_new_image_from_buffer(fz_context *ctx, fz_buffer *buffer)
bc = fz_malloc_struct(ctx, fz_compressed_buffer);
bc->buffer = fz_keep_buffer(ctx, buffer);
- if (buf[0] == 0xff && buf[1] == 0xd8)
+ if (buf[0] == 0xff && buf[1] == 0x4f)
+ {
+ bc->params.type = FZ_IMAGE_JPX;
+ fz_load_jpx_info(ctx, buf, len, &w, &h, &xres, &yres, &cspace);
+ }
+ else if (buf[0] == 0x00 && buf[1] == 0x00 && buf[2] == 0x00 && buf[3] == 0x0c && buf[4] == 0x6a && buf[5] == 0x50 && buf[6] == 0x20 && buf[7] == 0x20)
+ {
+ bc->params.type = FZ_IMAGE_JPX;
+ fz_load_jpx_info(ctx, buf, len, &w, &h, &xres, &yres, &cspace);
+ }
+ else if (buf[0] == 0xff && buf[1] == 0xd8)
{
bc->params.type = FZ_IMAGE_JPEG;
bc->params.u.jpeg.color_transform = -1;
diff --git a/source/fitz/load-jpx.c b/source/fitz/load-jpx.c
index ab0fb822..c1ed831a 100644
--- a/source/fitz/load-jpx.c
+++ b/source/fitz/load-jpx.c
@@ -69,8 +69,8 @@ static OPJ_BOOL fz_opj_stream_seek(OPJ_OFF_T seek_pos, void * p_user_data)
return OPJ_TRUE;
}
-fz_pixmap *
-fz_load_jpx(fz_context *ctx, unsigned char *data, size_t size, fz_colorspace *defcs, int indexed)
+static fz_pixmap *
+jpx_read_image(fz_context *ctx, unsigned char *data, size_t size, fz_colorspace *defcs, int indexed, int onlymeta)
{
fz_pixmap *img;
opj_dparameters_t params;
@@ -210,40 +210,61 @@ fz_load_jpx(fz_context *ctx, unsigned char *data, size_t size, fz_colorspace *de
fz_rethrow(ctx);
}
- p = img->samples;
- stride = img->stride - w * (n + a);
- for (y = 0; y < h; y++)
+ if (!onlymeta)
{
- for (x = 0; x < w; x++)
+ p = img->samples;
+ stride = img->stride - w * (n + a);
+ for (y = 0; y < h; y++)
{
- for (k = 0; k < n + a; k++)
+ for (x = 0; x < w; x++)
{
- 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 (k = 0; k < n + a; k++)
+ {
+ 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;
+ }
}
+ p += stride;
}
- p += stride;
- }
-
- opj_image_destroy(jpx);
- if (a)
- {
- if (n == 4)
+ if (a)
{
- fz_pixmap *tmp = fz_new_pixmap(ctx, fz_device_rgb(ctx), w, h, 1);
- fz_convert_pixmap(ctx, tmp, img);
- fz_drop_pixmap(ctx, img);
- img = tmp;
+ if (n == 4)
+ {
+ fz_pixmap *tmp = fz_new_pixmap(ctx, fz_device_rgb(ctx), w, h, 1);
+ fz_convert_pixmap(ctx, tmp, img);
+ fz_drop_pixmap(ctx, img);
+ img = tmp;
+ }
+ fz_premultiply_pixmap(ctx, img);
}
- fz_premultiply_pixmap(ctx, img);
}
+ opj_image_destroy(jpx);
+
return img;
}
+
+fz_pixmap *
+fz_load_jpx(fz_context *ctx, unsigned char *data, size_t size, fz_colorspace *defcs, int indexed)
+{
+ return jpx_read_image(ctx, data, size, defcs, indexed, 0);
+}
+
+void
+fz_load_jpx_info(fz_context *ctx, unsigned char *data, size_t size, int *wp, int *hp, int *xresp, int *yresp, fz_colorspace **cspacep)
+{
+ fz_pixmap *img = jpx_read_image(ctx, data, size, NULL, 0, 1);
+
+ *cspacep = fz_keep_colorspace(ctx, img->colorspace);
+ *wp = img->w;
+ *hp = img->h;
+ *xresp = 72; /* openjpeg does not read the JPEG 2000 resc box */
+ *yresp = 72; /* openjpeg does not read the JPEG 2000 resc box */
+}