diff options
-rw-r--r-- | fitz/fitz-internal.h | 1 | ||||
-rw-r--r-- | fitz/res_colorspace.c | 25 | ||||
-rw-r--r-- | fitz/res_pixmap.c | 120 | ||||
-rw-r--r-- | pdf/pdf_image.c | 24 |
4 files changed, 163 insertions, 7 deletions
diff --git a/fitz/fitz-internal.h b/fitz/fitz-internal.h index 528fb50a..2f1d137e 100644 --- a/fitz/fitz-internal.h +++ b/fitz/fitz-internal.h @@ -836,6 +836,7 @@ fz_pixmap *fz_alpha_from_gray(fz_context *ctx, fz_pixmap *gray, int luminosity); unsigned int fz_pixmap_size(fz_context *ctx, fz_pixmap *pix); fz_pixmap *fz_scale_pixmap(fz_context *ctx, fz_pixmap *src, float x, float y, float w, float h, fz_bbox *clip); +void fz_subsample_pixmap(fz_context *ctx, fz_pixmap *tile, int factor); fz_bbox fz_pixmap_bbox_no_ctx(fz_pixmap *src); diff --git a/fitz/res_colorspace.c b/fitz/res_colorspace.c index 7b36ac1e..edda776d 100644 --- a/fitz/res_colorspace.c +++ b/fitz/res_colorspace.c @@ -316,6 +316,31 @@ static void fast_cmyk_to_gray(fz_pixmap *dst, fz_pixmap *src) } } +#if 0 +static void +fast_cmyk_to_rgb_ARM(unsigned char *dst, unsigned char *src, int n) +{ + asm volatile( + ENTER_ARM + "stmfd r13!,{r4-r12,r14} \n" + "@ r0 = dst \n" + "@ r1 = src \n" + "@ r2 = weights \n" + "mov r4, #0 @ r4 = CMYK = 0 \n" + "mvn r5, #0xFF000000 @ r5 = RGB = FFFFFF \n" + "1: \n" + "ldr r3, [r1], #4 @ r3 = cmyk \n" + "cmp r3, r4 @ if (cmyk == CMYK) \n" + "beq match @ goto match \n" + "cmp r3, #0 @ if (cmyk = 0000) \n" + "beq black @ + + "ldmfd r13!,{r4-r7,r9,PC} @ pop, return to thumb \n" + ENTER_THUMB + ); +} +#endif + static void fast_cmyk_to_rgb(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src) { unsigned char *s = src->samples; diff --git a/fitz/res_pixmap.c b/fitz/res_pixmap.c index f7fbf239..a3ae7562 100644 --- a/fitz/res_pixmap.c +++ b/fitz/res_pixmap.c @@ -687,3 +687,123 @@ fz_drop_image(fz_context *ctx, fz_image *image) { fz_drop_storable(ctx, &image->storable); } + +void +fz_subsample_pixmap(fz_context *ctx, fz_pixmap *tile, int factor) +{ + int dst_w, dst_h, w, h, fwd, fwd2, fwd3, back, back2, x, y, n, xx, yy, nn, f; + unsigned char *s, *d; + + if (!tile) + return; + s = d = tile->samples; + f = 1<<factor; + w = tile->w; + h = tile->h; + n = tile->n; + dst_w = (w + f-1)>>factor; + dst_h = (h + f-1)>>factor; + fwd = w*n; + back = f*fwd-n; + back2 = f*n-1; + fwd2 = (f-1)*n; + fwd3 = (f-1)*fwd; + factor *= 2; + for (y = h - f; y >= 0; y -= f) + { + for (x = w - f; x >= 0; x -= f) + { + for (nn = n; nn > 0; nn--) + { + int v = 0; + for (xx = f; xx > 0; xx--) + { + for (yy = f; yy > 0; yy--) + { + v += *s; + s += fwd; + } + s -= back; + } + *d++ = v >> factor; + s -= back2; + } + s += fwd2; + } + /* Do any strays */ + x += f; + if (x > 0) + { + int div = x * f; + int fwd4 = (x-1) * n; + int back4 = x*n-1; + for (nn = n; nn > 0; nn--) + { + int v = 0; + for (;x > 0; x--) + { + for (yy = f; yy > 0; yy--) + { + v += *s; + s += fwd; + } + s -= back; + } + *d++ = v / div; + s -= back4; + } + s += fwd4; + } + s += fwd3; + } + /* Do any stray line */ + y += f; + if (y > 0) + { + int div = y * f; + back = fwd * y - 1; + for (x = w - f; x >= 0; x -= f) + { + for (nn = n; nn > 0; nn--) + { + int v = 0; + for (xx = f; xx > 0; xx--) + { + for (yy = y; yy > 0; yy--) + { + v += *s; + s += fwd; + } + s -= back; + } + *d++ = v / div; + s -= back2; + } + s += fwd2; + } + /* Do any stray at the end of the stray line */ + x += f; + if (x > 0) + { + int div = x * y; + for (nn = n; nn > 0; nn--) + { + int v = 0; + for (;x > 0; x--) + { + for (; y > 0; y--) + { + v += *s; + s += fwd; + } + s -= back; + } + *d++ = v / div; + s -= back2; + } + } + } + tile->w = dst_w; + tile->h = dst_h; + tile->samples = fz_resize_array(ctx, tile->samples, dst_w * n, dst_h); +} diff --git a/pdf/pdf_image.c b/pdf/pdf_image.c index 27a13100..ead7db49 100644 --- a/pdf/pdf_image.c +++ b/pdf/pdf_image.c @@ -99,15 +99,15 @@ static fz_store_type pdf_image_store_type = }; static fz_pixmap * -decomp_image_from_stream(fz_context *ctx, fz_stream *stm, pdf_image *image, int in_line, int indexed, int l2factor, int cache) +decomp_image_from_stream(fz_context *ctx, fz_stream *stm, pdf_image *image, int in_line, int indexed, int l2factor, int native_l2factor, int cache) { fz_pixmap *tile = NULL; fz_pixmap *existing_tile; int stride, len, i; unsigned char *samples = NULL; - int f = 1<<l2factor; - int w = (image->base.w + f-1) >> l2factor; - int h = (image->base.h + f-1) >> l2factor; + int f = 1<<native_l2factor; + int w = (image->base.w + f-1) >> native_l2factor; + int h = (image->base.h + f-1) >> native_l2factor; pdf_image_key *key; fz_var(tile); @@ -195,6 +195,14 @@ decomp_image_from_stream(fz_context *ctx, fz_stream *stm, pdf_image *image, int fz_rethrow(ctx); } + /* Now apply any extra subsampling required */ + if (l2factor - native_l2factor > 0) + { + if (l2factor - native_l2factor > 8) + l2factor = native_l2factor + 8; + fz_subsample_pixmap(ctx, tile, l2factor - native_l2factor); + } + if (!cache) return tile; @@ -249,6 +257,7 @@ pdf_image_get_pixmap(fz_context *ctx, fz_image *image_, int w, int h) fz_stream *stm; int l2factor; pdf_image_key key; + int native_l2factor; /* Check for 'simple' images which are just pixmaps */ if (image->buffer == NULL) @@ -285,9 +294,10 @@ pdf_image_get_pixmap(fz_context *ctx, fz_image *image_, int w, int h) while (key.l2factor >= 0); /* We need to make a new one. */ - stm = fz_open_image_decomp_stream(ctx, image->buffer, &l2factor); + native_l2factor = l2factor; + stm = fz_open_image_decomp_stream(ctx, image->buffer, &native_l2factor); - return decomp_image_from_stream(ctx, stm, image, 0, 0, l2factor, 1); + return decomp_image_from_stream(ctx, stm, image, 0, 0, l2factor, native_l2factor, 1); } static pdf_image * @@ -450,7 +460,7 @@ pdf_load_image_imp(pdf_document *xref, pdf_obj *rdb, pdf_obj *dict, fz_stream *c stm = pdf_open_stream(xref, pdf_to_num(dict), pdf_to_gen(dict)); } - image->tile = decomp_image_from_stream(ctx, stm, image, cstm != NULL, indexed, 0, 0); + image->tile = decomp_image_from_stream(ctx, stm, image, cstm != NULL, indexed, 0, 0, 0); } fz_catch(ctx) { |