summaryrefslogtreecommitdiff
path: root/fitz/res_pixmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'fitz/res_pixmap.c')
-rw-r--r--fitz/res_pixmap.c1062
1 files changed, 0 insertions, 1062 deletions
diff --git a/fitz/res_pixmap.c b/fitz/res_pixmap.c
deleted file mode 100644
index 7391c17e..00000000
--- a/fitz/res_pixmap.c
+++ /dev/null
@@ -1,1062 +0,0 @@
-#include "mupdf/fitz.h"
-
-fz_pixmap *
-fz_keep_pixmap(fz_context *ctx, fz_pixmap *pix)
-{
- return (fz_pixmap *)fz_keep_storable(ctx, &pix->storable);
-}
-
-void
-fz_drop_pixmap(fz_context *ctx, fz_pixmap *pix)
-{
- fz_drop_storable(ctx, &pix->storable);
-}
-
-void
-fz_free_pixmap_imp(fz_context *ctx, fz_storable *pix_)
-{
- fz_pixmap *pix = (fz_pixmap *)pix_;
-
- if (pix->colorspace)
- fz_drop_colorspace(ctx, pix->colorspace);
- if (pix->free_samples)
- fz_free(ctx, pix->samples);
- fz_free(ctx, pix);
-}
-
-fz_pixmap *
-fz_new_pixmap_with_data(fz_context *ctx, fz_colorspace *colorspace, int w, int h, unsigned char *samples)
-{
- fz_pixmap *pix;
-
- if (w < 0 || h < 0)
- fz_throw(ctx, FZ_ERROR_GENERIC, "Illegal dimensions for pixmap %d %d", w, h);
-
- pix = fz_malloc_struct(ctx, fz_pixmap);
- FZ_INIT_STORABLE(pix, 1, fz_free_pixmap_imp);
- pix->x = 0;
- pix->y = 0;
- pix->w = w;
- pix->h = h;
- pix->interpolate = 1;
- pix->xres = 96;
- pix->yres = 96;
- pix->colorspace = NULL;
- pix->n = 1;
-
- if (colorspace)
- {
- pix->colorspace = fz_keep_colorspace(ctx, colorspace);
- pix->n = 1 + colorspace->n;
- }
-
- pix->samples = samples;
- if (samples)
- {
- pix->free_samples = 0;
- }
- else
- {
- fz_try(ctx)
- {
- if (pix->w + pix->n - 1 > INT_MAX / pix->n)
- fz_throw(ctx, FZ_ERROR_GENERIC, "overly wide image");
- pix->samples = fz_malloc_array(ctx, pix->h, pix->w * pix->n);
- }
- fz_catch(ctx)
- {
- if (colorspace)
- fz_drop_colorspace(ctx, colorspace);
- fz_free(ctx, pix);
- fz_rethrow(ctx);
- }
- pix->free_samples = 1;
- }
-
- return pix;
-}
-
-fz_pixmap *
-fz_new_pixmap(fz_context *ctx, fz_colorspace *colorspace, int w, int h)
-{
- return fz_new_pixmap_with_data(ctx, colorspace, w, h, NULL);
-}
-
-fz_pixmap *
-fz_new_pixmap_with_bbox(fz_context *ctx, fz_colorspace *colorspace, const fz_irect *r)
-{
- fz_pixmap *pixmap;
- pixmap = fz_new_pixmap(ctx, colorspace, r->x1 - r->x0, r->y1 - r->y0);
- pixmap->x = r->x0;
- pixmap->y = r->y0;
- return pixmap;
-}
-
-fz_pixmap *
-fz_new_pixmap_with_bbox_and_data(fz_context *ctx, fz_colorspace *colorspace, const fz_irect *r, unsigned char *samples)
-{
- fz_pixmap *pixmap = fz_new_pixmap_with_data(ctx, colorspace, r->x1 - r->x0, r->y1 - r->y0, samples);
- pixmap->x = r->x0;
- pixmap->y = r->y0;
- return pixmap;
-}
-
-fz_irect *
-fz_pixmap_bbox(fz_context *ctx, fz_pixmap *pix, fz_irect *bbox)
-{
- bbox->x0 = pix->x;
- bbox->y0 = pix->y;
- bbox->x1 = pix->x + pix->w;
- bbox->y1 = pix->y + pix->h;
- return bbox;
-}
-
-fz_irect *
-fz_pixmap_bbox_no_ctx(fz_pixmap *pix, fz_irect *bbox)
-{
- bbox->x0 = pix->x;
- bbox->y0 = pix->y;
- bbox->x1 = pix->x + pix->w;
- bbox->y1 = pix->y + pix->h;
- return bbox;
-}
-
-int
-fz_pixmap_width(fz_context *ctx, fz_pixmap *pix)
-{
- return pix->w;
-}
-
-int
-fz_pixmap_height(fz_context *ctx, fz_pixmap *pix)
-{
- return pix->h;
-}
-
-void
-fz_clear_pixmap(fz_context *ctx, fz_pixmap *pix)
-{
- memset(pix->samples, 0, (unsigned int)(pix->w * pix->h * pix->n));
-}
-
-void
-fz_clear_pixmap_with_value(fz_context *ctx, fz_pixmap *pix, int value)
-{
- if (value == 255)
- {
- memset(pix->samples, 255, (unsigned int)(pix->w * pix->h * pix->n));
- }
- else
- {
- int k, x, y;
- unsigned char *s = pix->samples;
- for (y = 0; y < pix->h; y++)
- {
- for (x = 0; x < pix->w; x++)
- {
- for (k = 0; k < pix->n - 1; k++)
- *s++ = value;
- *s++ = 255;
- }
- }
- }
-}
-
-void
-fz_copy_pixmap_rect(fz_context *ctx, fz_pixmap *dest, fz_pixmap *src, const fz_irect *b)
-{
- const unsigned char *srcp;
- unsigned char *destp;
- int x, y, w, destspan, srcspan;
- fz_irect local_b, bb;
-
- local_b = *b;
- fz_intersect_irect(&local_b, fz_pixmap_bbox(ctx, dest, &bb));
- fz_intersect_irect(&local_b, fz_pixmap_bbox(ctx, src, &bb));
- w = local_b.x1 - local_b.x0;
- y = local_b.y1 - local_b.y0;
- if (w <= 0 || y <= 0)
- return;
-
- srcspan = src->w * src->n;
- srcp = src->samples + (unsigned int)(srcspan * (local_b.y0 - src->y) + src->n * (local_b.x0 - src->x));
- destspan = dest->w * dest->n;
- destp = dest->samples + (unsigned int)(destspan * (local_b.y0 - dest->y) + dest->n * (local_b.x0 - dest->x));
-
- if (src->n == dest->n)
- {
- w *= src->n;
- do
- {
- memcpy(destp, srcp, w);
- srcp += srcspan;
- destp += destspan;
- }
- while (--y);
- }
- else if (src->n == 2 && dest->n == 4)
- {
- /* Copy, and convert from grey+alpha to rgb+alpha */
- srcspan -= w*2;
- destspan -= w*4;
- do
- {
- for (x = w; x > 0; x--)
- {
- unsigned char v = *srcp++;
- unsigned char a = *srcp++;
- *destp++ = v;
- *destp++ = v;
- *destp++ = v;
- *destp++ = a;
- }
- srcp += srcspan;
- destp += destspan;
- }
- while (--y);
- }
- else if (src->n == 4 && dest->n == 2)
- {
- /* Copy, and convert from rgb+alpha to grey+alpha */
- srcspan -= w*4;
- destspan -= w*2;
- do
- {
- for (x = w; x > 0; x--)
- {
- int v;
- v = *srcp++;
- v += *srcp++;
- v += *srcp++;
- *destp++ = (unsigned char)((v+1)/3);
- *destp++ = *srcp++;
- }
- srcp += srcspan;
- destp += destspan;
- }
- while (--y);
- }
- else
- {
- /* FIXME: Crap conversion */
- int z;
- int sn = src->n-1;
- int dn = dest->n-1;
-
- srcspan -= w*src->n;
- destspan -= w*dest->n;
- do
- {
- for (x = w; x > 0; x--)
- {
- int v = 0;
- for (z = sn; z > 0; z--)
- v += *srcp++;
- v = (v * dn + (sn>>1)) / sn;
- for (z = dn; z > 0; z--)
- *destp++ = (unsigned char)v;
- *destp++ = *srcp++;
- }
- srcp += srcspan;
- destp += destspan;
- }
- while (--y);
- }
-}
-
-void
-fz_clear_pixmap_rect_with_value(fz_context *ctx, fz_pixmap *dest, int value, const fz_irect *b)
-{
- unsigned char *destp;
- int x, y, w, k, destspan;
- fz_irect bb;
- fz_irect local_b = *b;
-
- fz_intersect_irect(&local_b, fz_pixmap_bbox(ctx, dest, &bb));
- w = local_b.x1 - local_b.x0;
- y = local_b.y1 - local_b.y0;
- if (w <= 0 || y <= 0)
- return;
-
- destspan = dest->w * dest->n;
- destp = dest->samples + (unsigned int)(destspan * (local_b.y0 - dest->y) + dest->n * (local_b.x0 - dest->x));
- if (value == 255)
- do
- {
- memset(destp, 255, (unsigned int)(w * dest->n));
- destp += destspan;
- }
- while (--y);
- else
- do
- {
- unsigned char *s = destp;
- for (x = 0; x < w; x++)
- {
- for (k = 0; k < dest->n - 1; k++)
- *s++ = value;
- *s++ = 255;
- }
- destp += destspan;
- }
- while (--y);
-}
-
-void
-fz_premultiply_pixmap(fz_context *ctx, fz_pixmap *pix)
-{
- unsigned char *s = pix->samples;
- unsigned char a;
- int k, x, y;
-
- for (y = 0; y < pix->h; y++)
- {
- for (x = 0; x < pix->w; x++)
- {
- a = s[pix->n - 1];
- for (k = 0; k < pix->n - 1; k++)
- s[k] = fz_mul255(s[k], a);
- s += pix->n;
- }
- }
-}
-
-void
-fz_unmultiply_pixmap(fz_context *ctx, fz_pixmap *pix)
-{
- unsigned char *s = pix->samples;
- int a, inva;
- int k, x, y;
-
- for (y = 0; y < pix->h; y++)
- {
- for (x = 0; x < pix->w; x++)
- {
- a = s[pix->n - 1];
- inva = a ? 255 * 256 / a : 0;
- for (k = 0; k < pix->n - 1; k++)
- s[k] = (s[k] * inva) >> 8;
- s += pix->n;
- }
- }
-}
-
-fz_pixmap *
-fz_alpha_from_gray(fz_context *ctx, fz_pixmap *gray, int luminosity)
-{
- fz_pixmap *alpha;
- unsigned char *sp, *dp;
- int len;
- fz_irect bbox;
-
- assert(gray->n == 2);
-
- alpha = fz_new_pixmap_with_bbox(ctx, NULL, fz_pixmap_bbox(ctx, gray, &bbox));
- dp = alpha->samples;
- sp = gray->samples;
- if (!luminosity)
- sp ++;
-
- len = gray->w * gray->h;
- while (len--)
- {
- *dp++ = sp[0];
- sp += 2;
- }
-
- return alpha;
-}
-
-void
-fz_invert_pixmap(fz_context *ctx, fz_pixmap *pix)
-{
- unsigned char *s = pix->samples;
- int k, x, y;
-
- for (y = 0; y < pix->h; y++)
- {
- for (x = 0; x < pix->w; x++)
- {
- for (k = 0; k < pix->n - 1; k++)
- s[k] = 255 - s[k];
- s += pix->n;
- }
- }
-}
-
-void fz_invert_pixmap_rect(fz_pixmap *image, const fz_irect *rect)
-{
- unsigned char *p;
- int x, y, n;
-
- int x0 = fz_clampi(rect->x0 - image->x, 0, image->w - 1);
- int x1 = fz_clampi(rect->x1 - image->x, 0, image->w - 1);
- int y0 = fz_clampi(rect->y0 - image->y, 0, image->h - 1);
- int y1 = fz_clampi(rect->y1 - image->y, 0, image->h - 1);
-
- for (y = y0; y < y1; y++)
- {
- p = image->samples + (unsigned int)((y * image->w + x0) * image->n);
- for (x = x0; x < x1; x++)
- {
- for (n = image->n; n > 1; n--, p++)
- *p = 255 - *p;
- p++;
- }
- }
-}
-
-void
-fz_gamma_pixmap(fz_context *ctx, fz_pixmap *pix, float gamma)
-{
- unsigned char gamma_map[256];
- unsigned char *s = pix->samples;
- int k, x, y;
-
- for (k = 0; k < 256; k++)
- gamma_map[k] = pow(k / 255.0f, gamma) * 255;
-
- for (y = 0; y < pix->h; y++)
- {
- for (x = 0; x < pix->w; x++)
- {
- for (k = 0; k < pix->n - 1; k++)
- s[k] = gamma_map[s[k]];
- s += pix->n;
- }
- }
-}
-
-/*
- * Write pixmap to PNM file (without alpha channel)
- */
-
-void
-fz_write_pnm(fz_context *ctx, fz_pixmap *pixmap, char *filename)
-{
- FILE *fp;
- unsigned char *p;
- int len;
-
- if (pixmap->n != 1 && pixmap->n != 2 && pixmap->n != 4)
- fz_throw(ctx, FZ_ERROR_GENERIC, "pixmap must be grayscale or rgb to write as pnm");
-
- fp = fopen(filename, "wb");
- if (!fp)
- fz_throw(ctx, FZ_ERROR_GENERIC, "cannot open file '%s': %s", filename, strerror(errno));
-
- if (pixmap->n == 1 || pixmap->n == 2)
- fprintf(fp, "P5\n");
- if (pixmap->n == 4)
- fprintf(fp, "P6\n");
- fprintf(fp, "%d %d\n", pixmap->w, pixmap->h);
- fprintf(fp, "255\n");
-
- len = pixmap->w * pixmap->h;
- p = pixmap->samples;
-
- switch (pixmap->n)
- {
- case 1:
- fwrite(p, 1, len, fp);
- break;
- case 2:
- while (len--)
- {
- putc(p[0], fp);
- p += 2;
- }
- break;
- case 4:
- while (len--)
- {
- putc(p[0], fp);
- putc(p[1], fp);
- putc(p[2], fp);
- p += 4;
- }
- }
-
- fclose(fp);
-}
-
-/*
- * Write pixmap to PAM file (with or without alpha channel)
- */
-
-void
-fz_write_pam(fz_context *ctx, fz_pixmap *pixmap, char *filename, int savealpha)
-{
- unsigned char *sp;
- int y, w, k;
- FILE *fp;
-
- int sn = pixmap->n;
- int dn = pixmap->n;
- if (!savealpha && dn > 1)
- dn--;
-
- fp = fopen(filename, "wb");
- if (!fp)
- fz_throw(ctx, FZ_ERROR_GENERIC, "cannot open file '%s': %s", filename, strerror(errno));
-
- fprintf(fp, "P7\n");
- fprintf(fp, "WIDTH %d\n", pixmap->w);
- fprintf(fp, "HEIGHT %d\n", pixmap->h);
- fprintf(fp, "DEPTH %d\n", dn);
- fprintf(fp, "MAXVAL 255\n");
- if (pixmap->colorspace)
- fprintf(fp, "# COLORSPACE %s\n", pixmap->colorspace->name);
- switch (dn)
- {
- case 1: fprintf(fp, "TUPLTYPE GRAYSCALE\n"); break;
- case 2: if (sn == 2) fprintf(fp, "TUPLTYPE GRAYSCALE_ALPHA\n"); break;
- case 3: if (sn == 4) fprintf(fp, "TUPLTYPE RGB\n"); break;
- case 4: if (sn == 4) fprintf(fp, "TUPLTYPE RGB_ALPHA\n"); break;
- }
- fprintf(fp, "ENDHDR\n");
-
- sp = pixmap->samples;
- for (y = 0; y < pixmap->h; y++)
- {
- w = pixmap->w;
- while (w--)
- {
- for (k = 0; k < dn; k++)
- putc(sp[k], fp);
- sp += sn;
- }
- }
-
- fclose(fp);
-}
-
-/*
- * Write pixmap to PNG file (with or without alpha channel)
- */
-
-#include <zlib.h>
-
-static inline void big32(unsigned char *buf, unsigned int v)
-{
- buf[0] = (v >> 24) & 0xff;
- buf[1] = (v >> 16) & 0xff;
- buf[2] = (v >> 8) & 0xff;
- buf[3] = (v) & 0xff;
-}
-
-static void putchunk(char *tag, unsigned char *data, int size, fz_output *out)
-{
- unsigned int sum;
- fz_write_int32be(out, size);
- fz_write(out, tag, 4);
- fz_write(out, data, size);
- sum = crc32(0, NULL, 0);
- sum = crc32(sum, (unsigned char*)tag, 4);
- sum = crc32(sum, data, size);
- fz_write_int32be(out, sum);
-}
-
-void
-fz_write_png(fz_context *ctx, fz_pixmap *pixmap, char *filename, int savealpha)
-{
- FILE *fp = fopen(filename, "wb");
- fz_output *out = NULL;
-
- if (!fp)
- {
- fz_throw(ctx, FZ_ERROR_GENERIC, "cannot open file '%s': %s", filename, strerror(errno));
- }
-
- fz_var(out);
-
- fz_try(ctx)
- {
- out = fz_new_output_with_file(ctx, fp);
- fz_output_png(out, pixmap, savealpha);
- }
- fz_always(ctx)
- {
- fz_close_output(out);
- fclose(fp);
- }
- fz_catch(ctx)
- {
- fz_rethrow(ctx);
- }
-}
-
-void
-fz_output_png(fz_output *out, const fz_pixmap *pixmap, int savealpha)
-{
- static const unsigned char pngsig[8] = { 137, 80, 78, 71, 13, 10, 26, 10 };
- unsigned char head[13];
- unsigned char *udata = NULL;
- unsigned char *cdata = NULL;
- unsigned char *sp, *dp;
- uLong usize, csize;
- int y, x, k, sn, dn;
- int color;
- int err;
- fz_context *ctx;
-
- if (!out || !pixmap)
- return;
-
- ctx = out->ctx;
-
- fz_var(udata);
- fz_var(cdata);
-
- if (pixmap->n != 1 && pixmap->n != 2 && pixmap->n != 4)
- fz_throw(ctx, FZ_ERROR_GENERIC, "pixmap must be grayscale or rgb to write as png");
-
- sn = pixmap->n;
- dn = pixmap->n;
- if (!savealpha && dn > 1)
- dn--;
-
- switch (dn)
- {
- default:
- case 1: color = 0; break;
- case 2: color = 4; break;
- case 3: color = 2; break;
- case 4: color = 6; break;
- }
-
- usize = (pixmap->w * dn + 1) * pixmap->h;
- csize = compressBound(usize);
- fz_try(ctx)
- {
- udata = fz_malloc(ctx, usize);
- cdata = fz_malloc(ctx, csize);
- }
- fz_catch(ctx)
- {
- fz_free(ctx, udata);
- fz_rethrow(ctx);
- }
-
- sp = pixmap->samples;
- dp = udata;
- for (y = 0; y < pixmap->h; y++)
- {
- *dp++ = 1; /* sub prediction filter */
- for (x = 0; x < pixmap->w; x++)
- {
- for (k = 0; k < dn; k++)
- {
- if (x == 0)
- dp[k] = sp[k];
- else
- dp[k] = sp[k] - sp[k-sn];
- }
- sp += sn;
- dp += dn;
- }
- }
-
- err = compress(cdata, &csize, udata, usize);
- if (err != Z_OK)
- {
- fz_free(ctx, udata);
- fz_free(ctx, cdata);
- fz_throw(ctx, FZ_ERROR_GENERIC, "cannot compress image data");
- }
-
- big32(head+0, pixmap->w);
- big32(head+4, pixmap->h);
- head[8] = 8; /* depth */
- head[9] = color;
- head[10] = 0; /* compression */
- head[11] = 0; /* filter */
- head[12] = 0; /* interlace */
-
- fz_write(out, pngsig, 8);
- putchunk("IHDR", head, 13, out);
- putchunk("IDAT", cdata, csize, out);
- putchunk("IEND", head, 0, out);
-
- fz_free(ctx, udata);
- fz_free(ctx, cdata);
-}
-
-fz_buffer *
-fz_image_as_png(fz_context *ctx, fz_image *image, int w, int h)
-{
- fz_pixmap *pix = fz_image_get_pixmap(ctx, image, image->w, image->h);
- fz_buffer *buf = NULL;
- fz_output *out;
-
- fz_var(buf);
- fz_var(out);
-
- fz_try(ctx)
- {
- if (pix->colorspace != fz_device_gray(ctx) || pix->colorspace != fz_device_rgb(ctx))
- {
- fz_pixmap *pix2 = fz_new_pixmap(ctx, fz_device_rgb(ctx), pix->w, pix->h);
- fz_convert_pixmap(ctx, pix2, pix);
- fz_drop_pixmap(ctx, pix);
- pix = pix2;
- }
- buf = fz_new_buffer(ctx, 1024);
- out = fz_new_output_with_buffer(ctx, buf);
- fz_output_png(out, pix, 0);
- }
- fz_always(ctx)
- {
- fz_close_output(out);
- fz_drop_pixmap(ctx, pix);
- }
- fz_catch(ctx)
- {
- fz_drop_buffer(ctx, buf);
- fz_rethrow(ctx);
- }
- return buf;
-}
-
-unsigned int
-fz_pixmap_size(fz_context *ctx, fz_pixmap * pix)
-{
- if (pix == NULL)
- return 0;
- return sizeof(*pix) + pix->n * pix->w * pix->h;
-}
-
-#ifdef ARCH_ARM
-static void
-fz_subsample_pixmap_ARM(unsigned char *ptr, int w, int h, int f, int factor,
- int n, int fwd, int back, int back2, int fwd2,
- int divX, int back4, int fwd4, int fwd3,
- int divY, int back5, int divXY)
-__attribute__((naked));
-
-static void
-fz_subsample_pixmap_ARM(unsigned char *ptr, int w, int h, int f, int factor,
- int n, int fwd, int back, int back2, int fwd2,
- int divX, int back4, int fwd4, int fwd3,
- int divY, int back5, int divXY)
-{
- asm volatile(
- ENTER_ARM
- "stmfd r13!,{r1,r4-r11,r14} \n"
- "@STACK:r1,<9>,factor,n,fwd,back,back2,fwd2,divX,back4,fwd4,fwd3,divY,back5,divXY\n"
- "@ r0 = src = ptr \n"
- "@ r1 = w \n"
- "@ r2 = h \n"
- "@ r3 = f \n"
- "mov r9, r0 @ r9 = dst = ptr \n"
- "ldr r6, [r13,#4*12] @ r6 = fwd \n"
- "ldr r7, [r13,#4*13] @ r7 = back \n"
- "subs r2, r2, r3 @ r2 = h -= f \n"
- "blt 11f @ Skip if less than a full row \n"
- "1: @ for (y = h; y > 0; y--) { \n"
- "ldr r1, [r13] @ r1 = w \n"
- "subs r1, r1, r3 @ r1 = w -= f \n"
- "blt 6f @ Skip if less than a full col \n"
- "ldr r4, [r13,#4*10] @ r4 = factor \n"
- "ldr r8, [r13,#4*14] @ r8 = back2 \n"
- "ldr r12,[r13,#4*15] @ r12= fwd2 \n"
- "2: @ for (x = w; x > 0; x--) { \n"
- "ldr r5, [r13,#4*11] @ for (nn = n; nn > 0; n--) { \n"
- "3: @ \n"
- "mov r14,#0 @ r14= v = 0 \n"
- "sub r5, r5, r3, LSL #8 @ for (xx = f; xx > 0; x--) { \n"
- "4: @ \n"
- "add r5, r5, r3, LSL #16 @ for (yy = f; yy > 0; y--) { \n"
- "5: @ \n"
- "ldrb r11,[r0], r6 @ r11= *src src += fwd \n"
- "subs r5, r5, #1<<16 @ xx-- \n"
- "add r14,r14,r11 @ v += r11 \n"
- "bgt 5b @ } \n"
- "sub r0, r0, r7 @ src -= back \n"
- "adds r5, r5, #1<<8 @ yy-- \n"
- "blt 4b @ } \n"
- "mov r14,r14,LSR r4 @ r14 = v >>= factor \n"
- "strb r14,[r9], #1 @ *d++ = r14 \n"
- "sub r0, r0, r8 @ s -= back2 \n"
- "subs r5, r5, #1 @ n-- \n"
- "bgt 3b @ } \n"
- "add r0, r0, r12 @ s += fwd2 \n"
- "subs r1, r1, r3 @ x -= f \n"
- "bge 2b @ } \n"
- "6: @ Less than a full column left \n"
- "adds r1, r1, r3 @ x += f \n"
- "beq 11f @ if (x == 0) next row \n"
- "@ r0 = src \n"
- "@ r1 = x \n"
- "@ r2 = y \n"
- "@ r3 = f \n"
- "@ r4 = factor \n"
- "@ r6 = fwd \n"
- "@ r7 = back \n"
- "@STACK:r1,<9>,factor,n,fwd,back,back2,fwd2,divX,back4,fwd4,fwd3,divY,back5,divXY\n"
- "ldr r5, [r13,#4*11] @ for (nn = n; nn > 0; n--) { \n"
- "ldr r4, [r13,#4*16] @ r4 = divX \n"
- "ldr r8, [r13,#4*17] @ r8 = back4 \n"
- "ldr r12,[r13,#4*18] @ r12= fwd4 \n"
- "8: @ \n"
- "mov r14,#0 @ r14= v = 0 \n"
- "sub r5, r5, r1, LSL #8 @ for (xx = x; xx > 0; x--) { \n"
- "9: @ \n"
- "add r5, r5, r3, LSL #16 @ for (yy = f; yy > 0; y--) { \n"
- "10: @ \n"
- "ldrb r11,[r0], r6 @ r11= *src src += fwd \n"
- "subs r5, r5, #1<<16 @ xx-- \n"
- "add r14,r14,r11 @ v += r11 \n"
- "bgt 10b @ } \n"
- "sub r0, r0, r7 @ src -= back \n"
- "adds r5, r5, #1<<8 @ yy-- \n"
- "blt 9b @ } \n"
- "mul r14,r4, r14 @ r14= v *= divX \n"
- "mov r14,r14,LSR #16 @ r14= v >>= 16 \n"
- "strb r14,[r9], #1 @ *d++ = r14 \n"
- "sub r0, r0, r8 @ s -= back4 \n"
- "subs r5, r5, #1 @ n-- \n"
- "bgt 8b @ } \n"
- "add r0, r0, r12 @ s += fwd4 \n"
- "11: @ \n"
- "ldr r14,[r13,#4*19] @ r14 = fwd3 \n"
- "subs r2, r2, r3 @ h -= f \n"
- "add r0, r0, r14 @ s += fwd3 \n"
- "bge 1b @ } \n"
- "adds r2, r2, r3 @ h += f \n"
- "beq 21f @ if no stray row, end \n"
- "@ So doing one last (partial) row \n"
- "@STACK:r1,<9>,factor,n,fwd,back,back2,fwd2,divX,back4,fwd4,fwd3,divY,back5,divXY\n"
- "@ r0 = src = ptr \n"
- "@ r1 = w \n"
- "@ r2 = h \n"
- "@ r3 = f \n"
- "@ r4 = factor \n"
- "@ r5 = n \n"
- "@ r6 = fwd \n"
- "12: @ for (y = h; y > 0; y--) { \n"
- "ldr r1, [r13] @ r1 = w \n"
- "ldr r7, [r13,#4*21] @ r7 = back5 \n"
- "ldr r8, [r13,#4*14] @ r8 = back2 \n"
- "subs r1, r1, r3 @ r1 = w -= f \n"
- "blt 17f @ Skip if less than a full col \n"
- "ldr r4, [r13,#4*20] @ r4 = divY \n"
- "ldr r12,[r13,#4*15] @ r12= fwd2 \n"
- "13: @ for (x = w; x > 0; x--) { \n"
- "ldr r5, [r13,#4*11] @ for (nn = n; nn > 0; n--) { \n"
- "14: @ \n"
- "mov r14,#0 @ r14= v = 0 \n"
- "sub r5, r5, r3, LSL #8 @ for (xx = f; xx > 0; x--) { \n"
- "15: @ \n"
- "add r5, r5, r2, LSL #16 @ for (yy = y; yy > 0; y--) { \n"
- "16: @ \n"
- "ldrb r11,[r0], r6 @ r11= *src src += fwd \n"
- "subs r5, r5, #1<<16 @ xx-- \n"
- "add r14,r14,r11 @ v += r11 \n"
- "bgt 16b @ } \n"
- "sub r0, r0, r7 @ src -= back5 \n"
- "adds r5, r5, #1<<8 @ yy-- \n"
- "blt 15b @ } \n"
- "mul r14,r4, r14 @ r14 = x *= divY \n"
- "mov r14,r14,LSR #16 @ r14 = v >>= 16 \n"
- "strb r14,[r9], #1 @ *d++ = r14 \n"
- "sub r0, r0, r8 @ s -= back2 \n"
- "subs r5, r5, #1 @ n-- \n"
- "bgt 14b @ } \n"
- "add r0, r0, r12 @ s += fwd2 \n"
- "subs r1, r1, r3 @ x -= f \n"
- "bge 13b @ } \n"
- "17: @ Less than a full column left \n"
- "adds r1, r1, r3 @ x += f \n"
- "beq 21f @ if (x == 0) end \n"
- "@ r0 = src \n"
- "@ r1 = x \n"
- "@ r2 = y \n"
- "@ r3 = f \n"
- "@ r4 = factor \n"
- "@ r6 = fwd \n"
- "@ r7 = back5 \n"
- "@ r8 = back2 \n"
- "@STACK:r1,<9>,factor,n,fwd,back,back2,fwd2,divX,back4,fwd4,fwd3,divY,back5,divXY\n"
- "ldr r4, [r13,#4*22] @ r4 = divXY \n"
- "ldr r5, [r13,#4*11] @ for (nn = n; nn > 0; n--) { \n"
- "18: @ \n"
- "mov r14,#0 @ r14= v = 0 \n"
- "sub r5, r5, r1, LSL #8 @ for (xx = x; xx > 0; x--) { \n"
- "19: @ \n"
- "add r5, r5, r2, LSL #16 @ for (yy = y; yy > 0; y--) { \n"
- "20: @ \n"
- "ldrb r11,[r0],r6 @ r11= *src src += fwd \n"
- "subs r5, r5, #1<<16 @ xx-- \n"
- "add r14,r14,r11 @ v += r11 \n"
- "bgt 20b @ } \n"
- "sub r0, r0, r7 @ src -= back5 \n"
- "adds r5, r5, #1<<8 @ yy-- \n"
- "blt 19b @ } \n"
- "mul r14,r4, r14 @ r14= v *= divX \n"
- "mov r14,r14,LSR #16 @ r14= v >>= 16 \n"
- "strb r14,[r9], #1 @ *d++ = r14 \n"
- "sub r0, r0, r8 @ s -= back2 \n"
- "subs r5, r5, #1 @ n-- \n"
- "bgt 18b @ } \n"
- "21: @ \n"
- "ldmfd r13!,{r1,r4-r11,PC} @ pop, return to thumb \n"
- ENTER_THUMB
- );
-}
-
-#endif
-
-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;
-#ifdef ARCH_ARM
- {
- int strayX = w%f;
- int divX = (strayX ? 65536/(strayX*f) : 0);
- int fwd4 = (strayX-1) * n;
- int back4 = strayX*n-1;
- int strayY = h%f;
- int divY = (strayY ? 65536/(strayY*f) : 0);
- int back5 = fwd * strayY - n;
- int divXY = (strayY*strayX ? 65536/(strayX*strayY) : 0);
- fz_subsample_pixmap_ARM(s, w, h, f, factor, n, fwd, back,
- back2, fwd2, divX, back4, fwd4, fwd3,
- divY, back5, divXY);
- }
-#else
- 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 (xx = x; xx > 0; xx--)
- {
- 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;
- int back5 = fwd * y - n;
- 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 -= back5;
- }
- *d++ = v / div;
- s -= back2;
- }
- s += fwd2;
- }
- /* Do any stray at the end of the stray line */
- x += f;
- if (x > 0)
- {
- div = x * y;
- for (nn = n; nn > 0; nn--)
- {
- int v = 0;
- for (xx = x; xx > 0; xx--)
- {
- for (yy = y; yy > 0; yy--)
- {
- v += *s;
- s += fwd;
- }
- s -= back5;
- }
- *d++ = v / div;
- s -= back2;
- }
- }
- }
-#endif
- tile->w = dst_w;
- tile->h = dst_h;
- tile->samples = fz_resize_array(ctx, tile->samples, dst_w * n, dst_h);
-}
-
-void
-fz_pixmap_set_resolution(fz_pixmap *pix, int res)
-{
- pix->xres = res;
- pix->yres = res;
-}
-
-void
-fz_md5_pixmap(fz_pixmap *pix, unsigned char digest[16])
-{
- fz_md5 md5;
-
- fz_md5_init(&md5);
- if (pix)
- fz_md5_update(&md5, pix->samples, pix->w * pix->h * pix->n);
- fz_md5_final(&md5, digest);
-}