📄 pdf_shade4.c
字号:
#include "fitz.h"#include "mupdf.h"/* this mess is jeong's */typedef struct pdf_tensorpatch_s pdf_tensorpatch;struct pdf_tensorpatch_s { fz_point pole[4][4]; float color[4][FZ_MAXCOLORS];};static fz_error *growshademesh(fz_shade *shade, int amount){ float *newmesh; int newcap; newcap = shade->meshcap + amount; newmesh = fz_realloc(shade->mesh, sizeof(float) * newcap); if (!newmesh) return fz_outofmem; shade->mesh = newmesh; shade->meshcap = newcap; return fz_okay;}fz_error *pdf_loadtype4shade(fz_shade *shade, pdf_xref *xref, fz_obj *shading, fz_obj *ref){ fz_error *error; fz_obj *obj; int bpcoord; int bpcomp; int bpflag; int ncomp; float x0, x1, y0, y1; float c0[FZ_MAXCOLORS]; float c1[FZ_MAXCOLORS]; int i, z; int bitspervertex; int bytepervertex; fz_buffer *buf; int n; int j; float cval[16]; int flag; unsigned int t; float x, y; error = fz_okay; ncomp = shade->cs->n; bpcoord = fz_toint(fz_dictgets(shading, "BitsPerCoordinate")); bpcomp = fz_toint(fz_dictgets(shading, "BitsPerComponent")); bpflag = fz_toint(fz_dictgets(shading, "BitsPerFlag")); obj = fz_dictgets(shading, "Decode"); if (fz_isarray(obj)) { pdf_logshade("decode array\n"); x0 = fz_toreal(fz_arrayget(obj, 0)); x1 = fz_toreal(fz_arrayget(obj, 1)); y0 = fz_toreal(fz_arrayget(obj, 2)); y1 = fz_toreal(fz_arrayget(obj, 3)); for (i=0; i < fz_arraylen(obj) / 2; ++i) { c0[i] = fz_toreal(fz_arrayget(obj, i*2+4)); c1[i] = fz_toreal(fz_arrayget(obj, i*2+5)); } } else { error = fz_throw("syntaxerror: No Decode key in Type 4 Shade"); goto cleanup; } obj = fz_dictgets(shading, "Function"); if (obj) { ncomp = 1; pdf_loadshadefunction(shade, xref, shading, c0[0], c1[0]); } bitspervertex = bpflag + bpcoord * 2 + bpcomp * ncomp; bytepervertex = (bitspervertex+7) / 8; error = pdf_loadstream(&buf, xref, fz_tonum(ref), fz_togen(ref)); if (error) { error = fz_rethrow(error, "unable to load shading stream"); goto cleanup; } shade->usefunction = 0; n = 2 + shade->cs->n; j = 0; for (z = 0; z < (buf->wp - buf->bp) / bytepervertex; ++z) { flag = *buf->rp++; t = *buf->rp++; t = (t << 8) | *buf->rp++; t = (t << 8) | *buf->rp++; x = x0 + (t * (x1 - x0) / (pow(2, 24) - 1)); t = *buf->rp++; t = (t << 8) | *buf->rp++; t = (t << 8) | *buf->rp++; y = y0 + (t * (y1 - y0) / (pow(2, 24) - 1)); for (i=0; i < ncomp; ++i) { t = *buf->rp++; t = (t << 8) | *buf->rp++; } if (flag == 0) { j += n; } if (flag == 1 || flag == 2) { j += 3 * n; } } buf->rp = buf->bp; shade->mesh = (float*) malloc(sizeof(float) * j); /* 8, 24, 16 only */ j = 0; for (z = 0; z < (buf->wp - buf->bp) / bytepervertex; ++z) { flag = *buf->rp++; t = *buf->rp++; t = (t << 8) + *buf->rp++; t = (t << 8) + *buf->rp++; x = x0 + (t * (x1 - x0) / (pow(2, 24) - 1)); t = *buf->rp++; t = (t << 8) + *buf->rp++; t = (t << 8) + *buf->rp++; y = y0 + (t * (y1 - y0) / (pow(2, 24) - 1)); for (i=0; i < ncomp; ++i) { t = *buf->rp++; t = (t << 8) + *buf->rp++; cval[i] = t / (double)(pow(2, 16) - 1); } if (flag == 0) { shade->mesh[j++] = x; shade->mesh[j++] = y; for (i=0; i < ncomp; ++i) { shade->mesh[j++] = cval[i]; } } if (flag == 1) { memcpy(&(shade->mesh[j]), &(shade->mesh[j - 2 * n]), n * sizeof(float)); memcpy(&(shade->mesh[j + 1 * n]), &(shade->mesh[j - 1 * n]), n * sizeof(float)); j+= 2 * n; shade->mesh[j++] = x; shade->mesh[j++] = y; for (i=0; i < ncomp; ++i) { shade->mesh[j++] = cval[i]; } } if (flag == 2) { memcpy(&(shade->mesh[j]), &(shade->mesh[j - 3 * n]), n * sizeof(float)); memcpy(&(shade->mesh[j + 1 * n]), &(shade->mesh[j - 1 * n]), n * sizeof(float)); j+= 2 * n; shade->mesh[j++] = x; shade->mesh[j++] = y; for (i=0; i < ncomp; ++i) { shade->mesh[j++] = cval[i]; } } } shade->meshlen = j / n / 3; fz_dropbuffer(buf); return fz_okay;cleanup: return error;}static intgetdata(fz_stream *stream, int bps){ unsigned int bitmask = (1 << bps) - 1; unsigned int buf = 0; int bits = 0; int s; while (bits < bps) { buf = (buf << 8) | (fz_readbyte(stream) & 0xff); bits += 8; } s = buf >> (bits - bps); if (bps < 32) s = s & bitmask; bits -= bps; return s;}fz_error *pdf_loadtype5shade(fz_shade *shade, pdf_xref *xref, fz_obj *shading, fz_obj *ref){ fz_error *error; fz_stream *stream; fz_obj *obj; int bpcoord; int bpcomp; int vpr, vpc; int ncomp; float x0, x1, y0, y1; float c0[FZ_MAXCOLORS]; float c1[FZ_MAXCOLORS]; int i, n, j; int p, q; unsigned int t; float *x, *y, *c[FZ_MAXCOLORS]; error = fz_okay; ncomp = shade->cs->n; bpcoord = fz_toint(fz_dictgets(shading, "BitsPerCoordinate")); bpcomp = fz_toint(fz_dictgets(shading, "BitsPerComponent")); vpr = fz_toint(fz_dictgets(shading, "VerticesPerRow")); if (vpr < 2) { error = fz_throw("VerticesPerRow must be greater than or equal to 2"); goto cleanup; } obj = fz_dictgets(shading, "Decode"); if (fz_isarray(obj)) { pdf_logshade("decode array\n"); x0 = fz_toreal(fz_arrayget(obj, 0)); x1 = fz_toreal(fz_arrayget(obj, 1)); y0 = fz_toreal(fz_arrayget(obj, 2)); y1 = fz_toreal(fz_arrayget(obj, 3)); for (i=0; i < fz_arraylen(obj) / 2; ++i) { c0[i] = fz_toreal(fz_arrayget(obj, i*2+4)); c1[i] = fz_toreal(fz_arrayget(obj, i*2+5)); } } else { error = fz_throw("syntaxerror: No Decode key in Type 4 Shade"); goto cleanup; } obj = fz_dictgets(shading, "Function"); if (obj) { ncomp = 1; pdf_loadshadefunction(shade, xref, shading, c0[0], c1[0]); shade->usefunction = 1; } else shade->usefunction = 0; n = 2 + shade->cs->n; j = 0;#define BIGNUM 1024 x = fz_malloc(sizeof(float) * vpr * BIGNUM); y = fz_malloc(sizeof(float) * vpr * BIGNUM); for (i = 0; i < ncomp; ++i) { c[i] = fz_malloc(sizeof(float) * vpr * BIGNUM); } q = 0; error = pdf_openstream(&stream, xref, fz_tonum(ref), fz_togen(ref)); if (error) { error = fz_rethrow(error, "unable to open shading stream"); goto cleanup; } while (fz_peekbyte(stream) != EOF) { for (p = 0; p < vpr; ++p) { int idx; idx = q * vpr + p; t = getdata(stream, bpcoord); x[idx] = x0 + (t * (x1 - x0) / ((float)pow(2, bpcoord) - 1)); t = getdata(stream, bpcoord); y[idx] = y0 + (t * (y1 - y0) / ((float)pow(2, bpcoord) - 1)); for (i=0; i < ncomp; ++i) { t = getdata(stream, bpcomp); c[i][idx] = c0[i] + (t * (c1[i] - c0[i]) / (float)(pow(2, bpcomp) - 1)); } } q++; } fz_dropstream(stream);#define ADD_VERTEX(idx) \ {\ int z;\ if (shade->meshlen + 2 + shade->cs->n >= shade->meshcap) \ { \ error = growshademesh(shade, shade->meshcap + 1024); \ if (error) \ goto cleanup; \ } \ shade->mesh[j++] = x[idx];\ shade->mesh[j++] = y[idx];\ for (z = 0; z < shade->cs->n; ++z) \ shade->mesh[j++] = c[z][idx];\ shade->meshlen += 2 + shade->cs->n; \ }\ vpc = q; shade->meshlen = 0; shade->meshcap = 0; shade->mesh = nil; error = growshademesh(shade, 1024); if (error) goto cleanup; j = 0; for (p = 0; p < vpr-1; ++p) { for (q = 0; q < vpc-1; ++q) { ADD_VERTEX(q * vpr + p); ADD_VERTEX(q * vpr + p + 1); ADD_VERTEX((q + 1) * vpr + p + 1); ADD_VERTEX(q * vpr + p); ADD_VERTEX((q + 1) * vpr + p + 1); ADD_VERTEX((q + 1) * vpr + p); } } shade->meshlen /= n; shade->meshlen /= 3; fz_free(x); fz_free(y); for (i = 0; i < ncomp; ++i) { fz_free(c[i]); } return fz_okay;cleanup: return error;}#define SEGMENTATION_DEPTH 2static inline void copyvert(float *dst, float *src, int n){ while (n--) *dst++ = *src++;}static inline void copycolor(float *c, const float *s){ int i; for (i = 0; i<FZ_MAXCOLORS; ++i) c[i] = s[i];}static inline void midcolor(float *c, const float *c1, const float *c2){ int i; for (i = 0; i<FZ_MAXCOLORS; ++i) c[i] = (float)((c1[i] + c2[i]) / 2.0);}static voidfilltensorinterior(pdf_tensorpatch *p){#define lcp1(p0, p3)\ ((p0 + p0 + p3) / 3.0f)#define lcp2(p0, p3)\ ((p0 + p3 + p3) / 3.0f) p->pole[1][1].x = lcp1(p->pole[0][1].x, p->pole[3][1].x) + lcp1(p->pole[1][0].x, p->pole[1][3].x) - lcp1(lcp1(p->pole[0][0].x, p->pole[0][3].x), lcp1(p->pole[3][0].x, p->pole[3][3].x)); p->pole[1][2].x = lcp1(p->pole[0][2].x, p->pole[3][2].x) + lcp2(p->pole[1][0].x, p->pole[1][3].x) - lcp1(lcp2(p->pole[0][0].x, p->pole[0][3].x), lcp2(p->pole[3][0].x, p->pole[3][3].x)); p->pole[2][1].x = lcp2(p->pole[0][1].x, p->pole[3][1].x) + lcp1(p->pole[2][0].x, p->pole[2][3].x) - lcp2(lcp1(p->pole[0][0].x, p->pole[0][3].x), lcp1(p->pole[3][0].x, p->pole[3][3].x)); p->pole[2][2].x = lcp2(p->pole[0][2].x, p->pole[3][2].x) + lcp2(p->pole[2][0].x, p->pole[2][3].x) - lcp2(lcp2(p->pole[0][0].x, p->pole[0][3].x), lcp2(p->pole[3][0].x, p->pole[3][3].x));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -