static inline void fz_paint_affine_solid_g2rgb_near(byte *dp, byte *sp, int sw, int sh, int u, int v, int fa, int fb, int w, byte *hp) { while (w--) { int ui = u >> 16; int vi = v >> 16; if (ui >= 0 && ui < sw && vi >= 0 && vi < sh) { byte *sample = sp + ((vi * sw + ui) * 2); int x = sample[0]; int a = sample[1]; int t = 255 - a; dp[0] = x + fz_mul255(dp[0], t); dp[1] = x + fz_mul255(dp[1], t); dp[2] = x + fz_mul255(dp[2], t); dp[3] = a + fz_mul255(dp[3], t); if (hp) hp[0] = a + fz_mul255(hp[0], t); } dp += 4; if (hp) hp++; u += fa; v += fb; } }
static void img_w3i1o4(byte *rgb, FZ_PSRC, FZ_PDST, FZ_PCTM) { byte rgb0 = rgb[0]; byte rgb1 = rgb[1]; byte rgb2 = rgb[2]; byte sa, ssa; while (h--) { byte *dstp = dst0; int u = u0; int v = v0; int w = w0; while (w--) { sa = samplemask(src, srcw, srch, u, v); ssa = 255 - sa; dstp[0] = sa + fz_mul255(dstp[0], ssa); dstp[1] = rgb0 + fz_mul255((short)dstp[1] - rgb0, ssa); dstp[2] = rgb1 + fz_mul255((short)dstp[2] - rgb1, ssa); dstp[3] = rgb2 + fz_mul255((short)dstp[3] - rgb2, ssa); dstp += 4; u += fa; v += fb; } dst0 += dstw; u0 += fc; v0 += fd; } }
static inline void fz_paint_affine_solid_g2rgb_lerp(byte *dp, byte *sp, int sw, int sh, int u, int v, int fa, int fb, int w, byte *hp) { while (w--) { int ui = u >> 16; int vi = v >> 16; if (ui >= 0 && ui < sw && vi >= 0 && vi < sh) { int uf = u & 0xffff; int vf = v & 0xffff; byte *a = sample_nearest(sp, sw, sh, 2, ui, vi); byte *b = sample_nearest(sp, sw, sh, 2, ui+1, vi); byte *c = sample_nearest(sp, sw, sh, 2, ui, vi+1); byte *d = sample_nearest(sp, sw, sh, 2, ui+1, vi+1); int y = bilerp(a[1], b[1], c[1], d[1], uf, vf); int t = 255 - y; int x = bilerp(a[0], b[0], c[0], d[0], uf, vf); dp[0] = x + fz_mul255(dp[0], t); dp[1] = x + fz_mul255(dp[1], t); dp[2] = x + fz_mul255(dp[2], t); dp[3] = y + fz_mul255(dp[3], t); if (hp) hp[0] = y + fz_mul255(hp[0], t); } dp += 4; if (hp) hp++; u += fa; v += fb; } }
static void img_w4i1o4(byte *argb, FZ_LPSRC, FZ_PDST, FZ_PCTM) { byte alpha = argb[0]; byte r = argb[4]; byte g = argb[5]; byte b = argb[6]; byte cov; byte ca; while (h--) { byte *dstp = dst0; int u = u0; int v = v0; int w = w0; checktile(src, v>>16); while (w--) { cov = samplemask(src, srcw, srch, u, v); ca = fz_mul255(cov, alpha); dstp[0] = ca + fz_mul255(dstp[0], 255 - ca); dstp[1] = fz_mul255((short)r - dstp[1], ca) + dstp[1]; dstp[2] = fz_mul255((short)g - dstp[2], ca) + dstp[2]; dstp[3] = fz_mul255((short)b - dstp[3], ca) + dstp[3]; dstp += 4; u += fa; v += fb; } dst0 += dstw; u0 += fc; v0 += fd; } }
static inline void fz_paint_affine_alpha_N_near(byte *dp, byte *sp, int sw, int sh, int u, int v, int fa, int fb, int w, int n, int alpha, byte *hp) { int k; int n1 = n-1; if (fa == 0) { int ui = u >> 16; if (ui < 0 || ui >= sw) return; sp += ui * n; sw *= n; while (w--) { int vi = v >> 16; if (vi >= 0 && vi < sh) { byte *sample = sp + (vi * sw); int a = fz_mul255(sample[n-1], alpha); int t = 255 - a; for (k = 0; k < n1; k++) dp[k] = fz_mul255(sample[k], alpha) + fz_mul255(dp[k], t); dp[n1] = a + fz_mul255(dp[n1], t); if (hp) hp[0] = a + fz_mul255(hp[0], t); } dp += n; if (hp) hp++; v += fb; } }
static inline void fz_paint_affine_N_near(byte *dp, byte *sp, int sw, int sh, int u, int v, int fa, int fb, int w, int n, byte *hp) { int k; int n1 = n-1; while (w--) { int ui = u >> 16; int vi = v >> 16; if (ui >= 0 && ui < sw && vi >= 0 && vi < sh) { byte *sample = sp + ((vi * sw + ui) * n); int a = sample[n1]; int t = 255 - a; for (k = 0; k < n1; k++) dp[k] = sample[k] + fz_mul255(dp[k], t); dp[n1] = a + fz_mul255(dp[n1], t); if (hp) hp[0] = a + fz_mul255(hp[0], t); } dp += n; if (hp) hp++; u += fa; v += fb; } }
static void img_4o4(FZ_PSRC, FZ_PDST, FZ_PCTM) { byte argb[4]; byte ssa; while (h--) { byte *dstp = dst0; int u = u0; int v = v0; int w = w0; while (w--) { sampleargb(src, srcw, srch, u, v, argb); ssa = 255 - argb[0]; dstp[0] = argb[0] + fz_mul255(dstp[0], ssa); dstp[1] = argb[1] + fz_mul255(dstp[1], ssa); dstp[2] = argb[2] + fz_mul255(dstp[2], ssa); dstp[3] = argb[3] + fz_mul255(dstp[3], ssa); dstp += 4; u += fa; v += fb; } dst0 += dstw; u0 += fc; v0 += fd; } }
void fz_paint_shade(fz_shade *shade, fz_matrix ctm, fz_pixmap *dest, fz_bbox bbox) { unsigned char clut[256][FZ_MAX_COLORS]; fz_pixmap *temp, *conv; float color[FZ_MAX_COLORS]; int i, k; ctm = fz_concat(shade->matrix, ctm); if (shade->use_function) { for (i = 0; i < 256; i++) { fz_convert_color(shade->colorspace, shade->function[i], dest->colorspace, color); for (k = 0; k < dest->colorspace->n; k++) clut[i][k] = color[k] * 255; clut[i][k] = shade->function[i][shade->colorspace->n] * 255; } conv = fz_new_pixmap_with_rect(dest->colorspace, bbox); temp = fz_new_pixmap_with_rect(fz_device_gray, bbox); fz_clear_pixmap(temp); } else { temp = dest; } switch (shade->type) { case FZ_LINEAR: fz_paint_linear(shade, ctm, temp, bbox); break; case FZ_RADIAL: fz_paint_radial(shade, ctm, temp, bbox); break; case FZ_MESH: fz_paint_mesh(shade, ctm, temp, bbox); break; } if (shade->use_function) { unsigned char *s = temp->samples; unsigned char *d = conv->samples; int len = temp->w * temp->h; while (len--) { int v = *s++; int a = fz_mul255(*s++, clut[v][conv->n - 1]); for (k = 0; k < conv->n - 1; k++) *d++ = fz_mul255(clut[v][k], a); *d++ = a; } fz_paint_pixmap(dest, conv, 255); fz_drop_pixmap(conv); fz_drop_pixmap(temp); } }
static void fastcmyktogray(fz_pixmap *src, fz_pixmap *dst) { unsigned char *s = src->samples; unsigned char *d = dst->samples; int n = src->w * src->h; while (n--) { unsigned char c = fz_mul255(s[1], 77); unsigned char m = fz_mul255(s[2], 150); unsigned char y = fz_mul255(s[3], 28); d[0] = s[0]; d[1] = 255 - MIN(c + m + y + s[4], 255); s += 5; d += 2; } }
static void img_1o1(FZ_LPSRC, FZ_PDST, FZ_PCTM) { byte srca; while (h--) { byte *dstp = dst0; int u = u0; int v = v0; int w = w0; checktile(src, v>>16); while (w--) { srca = samplemask(src, srcw, srch, u, v); dstp[0] = srca + fz_mul255(dstp[0], 255 - srca); dstp ++; u += fa; v += fb; } dst0 += dstw; u0 += fc; v0 += fd; } }
static int fz_softlight_byte(int bd, int s) { /* review this */ if (s < 128) { return bd - fz_mul255(fz_mul255((255 - (s<<1)), bd), 255 - bd); } else { int dbd; if (bd < 64) dbd = fz_mul255(fz_mul255((bd << 4) - 12, bd) + 4, bd); else dbd = (int)sqrtf(255.0f * bd); return bd + fz_mul255(((s<<1) - 255), (dbd - bd)); } }
static void fast_cmyk_to_gray(fz_pixmap *dst, fz_pixmap *src) { unsigned char *s = src->samples; unsigned char *d = dst->samples; int n = src->w * src->h; while (n--) { unsigned char c = fz_mul255(s[0], 77); unsigned char m = fz_mul255(s[1], 150); unsigned char y = fz_mul255(s[2], 28); d[0] = 255 - (unsigned char)fz_mini(c + m + y + s[3], 255); d[1] = s[4]; s += 5; d += 2; } }
static int fz_hardlight_byte(int bd, int s) { int s2 = s << 1; if (s <= 127) return fz_mul255(bd, s2); else return fz_screen_byte(bd, s2); }
static void img_4o4(FZ_PSRC, FZ_PDST, FZ_PCTM) { byte argb[4]; byte ssa; while (h--) { byte *dstp = dst0; int u = u0; int v = v0; int w = w0; while (w--) { #if 0 // bilerp is pretty and slow. dont do it w/o hw, hardcore assembly skillz or a // 1ghz cpu. int ui = u >> 16; int vi = v >> 16; byte *tp = getargb(src, srcw, srch, ui, vi); argb[0] = tp[0]; argb[1] = tp[1]; argb[2] = tp[2]; argb[3] = tp[3]; #else sampleargb(src, srcw, srch, u, v, argb); #endif ssa = 255 - argb[0]; dstp[0] = argb[0] + fz_mul255(dstp[0], ssa); dstp[1] = argb[1] + fz_mul255(dstp[1], ssa); dstp[2] = argb[2] + fz_mul255(dstp[2], ssa); dstp[3] = argb[3] + fz_mul255(dstp[3], ssa); dstp += 4; u += fa; v += fb; } dst0 += dstw; u0 += fc; v0 += fd; } }
static inline void fz_paint_affine_alpha_N_lerp(byte *dp, byte *sp, int sw, int sh, int u, int v, int fa, int fb, int w, int n, int alpha, byte *hp) { int k; int n1 = n-1; while (w--) { int ui = u >> 16; int vi = v >> 16; if (ui >= 0 && ui < sw && vi >= 0 && vi < sh) { int uf = u & 0xffff; int vf = v & 0xffff; byte *a = sample_nearest(sp, sw, sh, n, ui, vi); byte *b = sample_nearest(sp, sw, sh, n, ui+1, vi); byte *c = sample_nearest(sp, sw, sh, n, ui, vi+1); byte *d = sample_nearest(sp, sw, sh, n, ui+1, vi+1); int xa = bilerp(a[n1], b[n1], c[n1], d[n1], uf, vf); int t; xa = fz_mul255(xa, alpha); t = 255 - xa; for (k = 0; k < n1; k++) { int x = bilerp(a[k], b[k], c[k], d[k], uf, vf); dp[k] = fz_mul255(x, alpha) + fz_mul255(dp[k], t); } dp[n1] = xa + fz_mul255(dp[n1], t); if (hp) hp[0] = xa + fz_mul255(hp[0], t); } dp += n; if (hp) hp++; u += fa; v += fb; } }
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; } } }
fz_pixmap * pdf_expand_indexed_pixmap(fz_pixmap *src) { struct indexed *idx; fz_pixmap *dst; unsigned char *s, *d; int y, x, k, n, high; unsigned char *lookup; assert(src->colorspace->to_rgb == indexed_to_rgb); assert(src->n == 2); idx = src->colorspace->data; high = idx->high; lookup = idx->lookup; n = idx->base->n; dst = fz_new_pixmap_with_rect(idx->base, fz_bound_pixmap(src)); s = src->samples; d = dst->samples; for (y = 0; y < src->h; y++) { for (x = 0; x < src->w; x++) { int v = *s++; int a = *s++; v = MIN(v, high); for (k = 0; k < n; k++) *d++ = fz_mul255(lookup[v * n + k], a); *d++ = a; } } if (src->mask) dst->mask = fz_keep_pixmap(src->mask); dst->interpolate = src->interpolate; return dst; }
fz_pixmap * pdf_expand_indexed_pixmap(fz_context *ctx, fz_pixmap *src) { struct indexed *idx; fz_pixmap *dst; unsigned char *s, *d; int y, x, k, n, high; unsigned char *lookup; fz_irect bbox; assert(src->colorspace->to_rgb == indexed_to_rgb); assert(src->n == 2); idx = src->colorspace->data; high = idx->high; lookup = idx->lookup; n = idx->base->n; dst = fz_new_pixmap_with_bbox(ctx, idx->base, fz_pixmap_bbox(ctx, src, &bbox)); s = src->samples; d = dst->samples; for (y = 0; y < src->h; y++) { for (x = 0; x < src->w; x++) { int v = *s++; int a = *s++; v = fz_mini(v, high); for (k = 0; k < n; k++) *d++ = fz_mul255(lookup[v * n + k], a); *d++ = a; } } dst->interpolate = src->interpolate; return dst; }
void fz_paint_shade(fz_context *ctx, fz_shade *shade, const fz_matrix *ctm, fz_pixmap *dest, const fz_irect *bbox) { unsigned char clut[256][FZ_MAX_COLORS]; fz_pixmap *temp = NULL; fz_pixmap *conv = NULL; float color[FZ_MAX_COLORS]; struct paint_tri_data ptd; int i, k; fz_matrix local_ctm; fz_var(temp); fz_var(conv); fz_try(ctx) { fz_concat(&local_ctm, &shade->matrix, ctm); if (shade->use_function) { fz_color_converter cc; fz_find_color_converter(&cc, ctx, dest->colorspace, shade->colorspace); for (i = 0; i < 256; i++) { cc.convert(&cc, color, shade->function[i]); for (k = 0; k < dest->colorspace->n; k++) clut[i][k] = color[k] * 255; clut[i][k] = shade->function[i][shade->colorspace->n] * 255; } conv = fz_new_pixmap_with_bbox(ctx, dest->colorspace, bbox); temp = fz_new_pixmap_with_bbox(ctx, fz_device_gray, bbox); fz_clear_pixmap(ctx, temp); } else { temp = dest; } ptd.ctx = ctx; ptd.dest = temp; ptd.shade = shade; ptd.bbox = bbox; fz_process_mesh(ctx, shade, &local_ctm, &do_paint_tri, &ptd); if (shade->use_function) { unsigned char *s = temp->samples; unsigned char *d = conv->samples; int len = temp->w * temp->h; while (len--) { int v = *s++; int a = fz_mul255(*s++, clut[v][conv->n - 1]); for (k = 0; k < conv->n - 1; k++) *d++ = fz_mul255(clut[v][k], a); *d++ = a; } fz_paint_pixmap(dest, conv, 255); fz_drop_pixmap(ctx, conv); fz_drop_pixmap(ctx, temp); } } fz_catch(ctx) { fz_drop_pixmap(ctx, conv); fz_drop_pixmap(ctx, temp); fz_rethrow(ctx); } }
static int fz_screen_byte(int bd, int s) { return bd + s - fz_mul255(bd, s); }
fz_error fz_rendershade(fz_shade *shade, fz_matrix ctm, fz_colorspace *destcs, fz_pixmap *dest) { unsigned char clut[256][3]; unsigned char *s, *d; fz_error error; fz_pixmap *temp; float rgb[3]; float tri[3][MAXN]; fz_point p; int i, j, k, n; assert(dest->n == 4); ctm = fz_concat(shade->matrix, ctm); if (shade->usefunction) { n = 3; error = fz_newpixmap(&temp, dest->x, dest->y, dest->w, dest->h, 2); if (error) return error; } else if (shade->cs != destcs) { n = 2 + shade->cs->n; error = fz_newpixmap(&temp, dest->x, dest->y, dest->w, dest->h, shade->cs->n + 1); if (error) return error; } else { n = 2 + shade->cs->n; temp = dest; } fz_clearpixmap(temp); for (i = 0; i < shade->meshlen; i++) { for (k = 0; k < 3; k++) { p.x = shade->mesh[(i * 3 + k) * n + 0]; p.y = shade->mesh[(i * 3 + k) * n + 1]; p = fz_transformpoint(ctm, p); if (isnan(p.y) || isnan(p.x)) // How is this happening? goto baddata; tri[k][0] = p.x; tri[k][1] = p.y; for (j = 2; j < n; j++) tri[k][j] = shade->mesh[( i * 3 + k) * n + j] * 255; } fz_drawtriangle(temp, tri[0], tri[1], tri[2], n); baddata: ; } if (shade->usefunction) { for (i = 0; i < 256; i++) { fz_convertcolor(shade->cs, shade->function[i], destcs, rgb); clut[i][0] = rgb[0] * 255; clut[i][1] = rgb[1] * 255; clut[i][2] = rgb[2] * 255; } n = temp->w * temp->h; s = temp->samples; d = dest->samples; while (n--) { d[0] = s[0]; d[1] = fz_mul255(s[0], clut[s[1]][0]); d[2] = fz_mul255(s[0], clut[s[1]][1]); d[3] = fz_mul255(s[0], clut[s[1]][2]); s += 2; d += 4; } fz_droppixmap(temp); } else if (shade->cs != destcs) { fz_convertpixmap(shade->cs, temp, destcs, dest); fz_droppixmap(temp); } return fz_okay; }
static int fz_exclusion_byte(int bd, int s) { return bd + s - (fz_mul255(bd, s)<<1); }