imagescale.c.svn-base
来自「SumatraPDF是一款小型开源的pdf阅读工具。虽然玲珑小巧(只有800多K」· SVN-BASE 代码 · 共 359 行
SVN-BASE
359 行
#include "fitz-base.h"#include "fitz-world.h"#include "fitz-draw.h"typedef unsigned char byte;static inline void srown(byte * restrict src, byte * restrict dst, int w, int denom, int n){ int invdenom = (1<<16) / denom; int x, left, k; unsigned sum[FZ_MAXCOLORS]; left = 0; for (k = 0; k < n; k++) sum[k] = 0; for (x = 0; x < w; x++) { for (k = 0; k < n; k++) sum[k] += src[x * n + k]; if (++left == denom) { left = 0; for (k = 0; k < n; k++) { dst[k] = (sum[k] * invdenom + (1<<15)) >> 16; sum[k] = 0; } dst += n; } } /* left overs */ if (left) for (k = 0; k < n; k++) dst[k] = sum[k] / left;}/* special-case common 1-5 components - the compiler optimizes this */static inline void srowc(byte * restrict src, byte * restrict dst, int w, int denom, int n){ int invdenom = (1<<16) / denom; int x, left; unsigned sum1 = 0; unsigned sum2 = 0; unsigned sum3 = 0; unsigned sum4 = 0; unsigned sum5 = 0; assert(n <= 5); left = 0; for (x = 0; x < w; x++) { sum1 += src[x * n + 0]; /* the compiler eliminates these if-tests */ if (n >= 2) sum2 += src[x * n + 1]; if (n >= 3) sum3 += src[x * n + 2]; if (n >= 4) sum4 += src[x * n + 3]; if (n >= 5) sum5 += src[x * n + 4]; if (++left == denom) { left = 0; dst[0] = (sum1 * invdenom + (1<<15)) >> 16; sum1 = 0; if (n >= 2) { dst[1] = (sum2 * invdenom + (1<<15)) >> 16; sum2 = 0; } if (n >= 3) { dst[2] = (sum3 * invdenom + (1<<15)) >> 16; sum3 = 0; } if (n >= 4) { dst[3] = (sum4 * invdenom + (1<<15)) >> 16; sum4 = 0; } if (n >= 5) { dst[4] = (sum5 * invdenom + (1<<15)) >> 16; sum5 = 0; } dst += n; } } /* left overs */ if (left) { dst[0] = sum1 / left; if (n >=2) dst[1] = sum2 / left; if (n >=3) dst[2] = sum3 / left; if (n >=4) dst[3] = sum4 / left; if (n >=5) dst[4] = sum5 / left; }}static void srow1(byte *src, byte *dst, int w, int denom){ srowc(src, dst, w, denom, 1);}static void srow2(byte *src, byte *dst, int w, int denom){ srowc(src, dst, w, denom, 2);}static void srow4(byte *src, byte *dst, int w, int denom){ srowc(src, dst, w, denom, 4);}static void srow5(byte *src, byte *dst, int w, int denom){ srowc(src, dst, w, denom, 5);}static inline void scoln(byte * restrict src, byte * restrict dst, int w, int denom, int n){ int invdenom = (1<<16) / denom; int x, y, k; byte *s; int sum[FZ_MAXCOLORS]; for (x = 0; x < w; x++) { s = src + (x * n); for (k = 0; k < n; k++) sum[k] = 0; for (y = 0; y < denom; y++) for (k = 0; k < n; k++) sum[k] += s[y * w * n + k]; for (k = 0; k < n; k++) dst[k] = (sum[k] * invdenom + (1<<15)) >> 16; dst += n; }}static void scol1(byte *src, byte *dst, int w, int denom){ scoln(src, dst, w, denom, 1);}static void scol2(byte *src, byte *dst, int w, int denom){ scoln(src, dst, w, denom, 2);}static void scol4(byte *src, byte *dst, int w, int denom){ scoln(src, dst, w, denom, 4);}static void scol5(byte *src, byte *dst, int w, int denom){ scoln(src, dst, w, denom, 5);}void (*fz_srown)(byte *src, byte *dst, int w, int denom, int n) = srown;void (*fz_srow1)(byte *src, byte *dst, int w, int denom) = srow1;void (*fz_srow2)(byte *src, byte *dst, int w, int denom) = srow2;void (*fz_srow4)(byte *src, byte *dst, int w, int denom) = srow4;void (*fz_srow5)(byte *src, byte *dst, int w, int denom) = srow5;void (*fz_scoln)(byte *src, byte *dst, int w, int denom, int n) = scoln;void (*fz_scol1)(byte *src, byte *dst, int w, int denom) = scol1;void (*fz_scol2)(byte *src, byte *dst, int w, int denom) = scol2;void (*fz_scol4)(byte *src, byte *dst, int w, int denom) = scol4;void (*fz_scol5)(byte *src, byte *dst, int w, int denom) = scol5;fz_error *fz_newscaledpixmap(fz_pixmap **dstp, int w, int h, int n, int xdenom, int ydenom){ int ow = (w + xdenom - 1) / xdenom; int oh = (h + ydenom - 1) / ydenom; return fz_newpixmap(dstp, 0, 0, ow, oh, n);}/* TODO: refactor */fz_error *fz_scalepixmaptile(fz_pixmap *dst, int xoffs, int yoffs, fz_pixmap *src, int xdenom, int ydenom){ unsigned char *buf; unsigned char *dstsamples; int y, iy, oy; int ow, oh, n; int remaining; void (*srowx)(byte *src, byte *dst, int w, int denom) = nil; void (*scolx)(byte *src, byte *dst, int w, int denom) = nil; ow = (src->w + xdenom - 1) / xdenom; oh = (src->h + ydenom - 1) / ydenom; xoffs /= xdenom; yoffs /= ydenom; n = src->n; assert(xoffs == 0); /* don't handle stride properly yet */ assert(dst->n == n); assert(dst->w >= xoffs + ow && dst->h >= yoffs + oh); buf = fz_malloc(ow * n * ydenom); if (!buf) return fz_outofmem; switch (n) { case 1: srowx = fz_srow1; scolx = fz_scol1; break; case 2: srowx = fz_srow2; scolx = fz_scol2; break; case 4: srowx = fz_srow4; scolx = fz_scol4; break; case 5: srowx = fz_srow5; scolx = fz_scol5; break; } dstsamples = dst->samples + (yoffs * dst->w + xoffs)*dst->n; if (srowx && scolx) { for (y = 0, oy = 0; y < (src->h / ydenom) * ydenom; y += ydenom, oy++) { for (iy = 0; iy < ydenom; iy++) srowx(src->samples + (y + iy) * src->w * n, buf + iy * ow * n, src->w, xdenom); scolx(buf, dstsamples + oy * dst->w * n, ow, ydenom); } remaining = src->h - y; if (remaining) { for (iy = 0; iy < remaining; iy++) srowx(src->samples + (y + iy) * src->w * n, buf + iy * ow * n, src->w, xdenom); scolx(buf, dstsamples + oy * dst->w * n, ow, ydenom); } } else { for (y = 0, oy = 0; y < (src->h / ydenom) * ydenom; y += ydenom, oy++) { for (iy = 0; iy < ydenom; iy++) fz_srown(src->samples + (y + iy) * src->w * n, buf + iy * ow * n, src->w, xdenom, n); fz_scoln(buf, dstsamples + oy * dst->w * n, ow, ydenom, n); } remaining = src->h - y; if (remaining) { for (iy = 0; iy < remaining; iy++) fz_srown(src->samples + (y + iy) * src->w * n, buf + iy * ow * n, src->w, xdenom, n); fz_scoln(buf, dstsamples + oy * dst->w * n, ow, ydenom, n); } } fz_free(buf); return fz_okay;}fz_error *fz_scalepixmap(fz_pixmap **dstp, fz_pixmap *src, int xdenom, int ydenom){ fz_error *error; fz_pixmap *dst; unsigned char *buf; int y, iy, oy; int ow, oh, n; int remaining; void (*srowx)(byte *src, byte *dst, int w, int denom) = nil; void (*scolx)(byte *src, byte *dst, int w, int denom) = nil; ow = (src->w + xdenom - 1) / xdenom; oh = (src->h + ydenom - 1) / ydenom; n = src->n; buf = fz_malloc(ow * n * ydenom); if (!buf) return fz_outofmem; error = fz_newpixmap(&dst, 0, 0, ow, oh, src->n); if (error) { fz_free(buf); return error; } switch (n) { case 1: srowx = fz_srow1; scolx = fz_scol1; break; case 2: srowx = fz_srow2; scolx = fz_scol2; break; case 4: srowx = fz_srow4; scolx = fz_scol4; break; case 5: srowx = fz_srow5; scolx = fz_scol5; break; } if (srowx && scolx) { for (y = 0, oy = 0; y < (src->h / ydenom) * ydenom; y += ydenom, oy++) { for (iy = 0; iy < ydenom; iy++) srowx(src->samples + (y + iy) * src->w * n, buf + iy * ow * n, src->w, xdenom); scolx(buf, dst->samples + oy * dst->w * n, dst->w, ydenom); } remaining = src->h - y; if (remaining) { for (iy = 0; iy < remaining; iy++) srowx(src->samples + (y + iy) * src->w * n, buf + iy * ow * n, src->w, xdenom); scolx(buf, dst->samples + oy * dst->w * n, dst->w, ydenom); } } else { for (y = 0, oy = 0; y < (src->h / ydenom) * ydenom; y += ydenom, oy++) { for (iy = 0; iy < ydenom; iy++) fz_srown(src->samples + (y + iy) * src->w * n, buf + iy * ow * n, src->w, xdenom, n); fz_scoln(buf, dst->samples + oy * dst->w * n, dst->w, ydenom, n); } remaining = src->h - y; if (remaining) { for (iy = 0; iy < remaining; iy++) fz_srown(src->samples + (y + iy) * src->w * n, buf + iy * ow * n, src->w, xdenom, n); fz_scoln(buf, dst->samples + oy * dst->w * n, dst->w, ydenom, n); } } fz_free(buf); *dstp = dst; return fz_okay;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?