summaryrefslogtreecommitdiff
path: root/fitzdraw/pixmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'fitzdraw/pixmap.c')
-rw-r--r--fitzdraw/pixmap.c188
1 files changed, 188 insertions, 0 deletions
diff --git a/fitzdraw/pixmap.c b/fitzdraw/pixmap.c
new file mode 100644
index 00000000..077009f8
--- /dev/null
+++ b/fitzdraw/pixmap.c
@@ -0,0 +1,188 @@
+#include "fitz-base.h"
+#include "fitz-world.h"
+#include "fitz-draw.h"
+
+fz_error *
+fz_newpixmap(fz_pixmap **pixp, int x, int y, int w, int h, int n)
+{
+ fz_pixmap *pix;
+
+ pix = *pixp = fz_malloc(sizeof(fz_pixmap));
+ if (!pix)
+ return fz_outofmem;
+
+ pix->x = x;
+ pix->y = y;
+ pix->w = w;
+ pix->h = h;
+ pix->n = n;
+
+ pix->samples = fz_malloc(pix->w * pix->h * pix->n * sizeof(fz_sample));
+ if (!pix->samples) {
+ fz_free(pix);
+ return fz_outofmem;
+ }
+
+ return fz_okay;
+}
+
+fz_error *
+fz_newpixmapwithrect(fz_pixmap **pixp, fz_irect r, int n)
+{
+ return fz_newpixmap(pixp,
+ r.x0, r.y0,
+ r.x1 - r.x0,
+ r.y1 - r.y0, n);
+}
+
+fz_error *
+fz_newpixmapcopy(fz_pixmap **pixp, fz_pixmap *old)
+{
+ fz_error *error;
+ error = fz_newpixmap(pixp, old->x, old->y, old->w, old->h, old->n);
+ if (error)
+ return error;
+ memcpy((*pixp)->samples, old->samples, old->w * old->h * old->n);
+ return fz_okay;
+}
+
+void
+fz_droppixmap(fz_pixmap *pix)
+{
+ fz_free(pix->samples);
+ fz_free(pix);
+}
+
+void
+fz_clearpixmap(fz_pixmap *pix)
+{
+ memset(pix->samples, 0, pix->w * pix->h * pix->n * sizeof(fz_sample));
+}
+
+void
+fz_gammapixmap(fz_pixmap *pix, float gamma)
+{
+ unsigned char table[256];
+ int n = pix->w * pix->h * pix->n;
+ unsigned char *p = pix->samples;
+ int i;
+ for (i = 0; i < 256; i++)
+ table[i] = CLAMP(pow(i / 255.0, gamma) * 255.0, 0, 255);
+ while (n--)
+ {
+ *p = table[*p];
+ p++;
+ }
+}
+
+void
+fz_debugpixmap(fz_pixmap *pix, char *prefix)
+{
+ static int counter = 0;
+ char colorname[40];
+ char alphaname[40];
+ FILE *color = NULL;
+ FILE *alpha = NULL;
+ int x, y;
+
+ sprintf(alphaname, "%s-%04d-alpha.pgm", prefix, counter);
+ alpha = fopen(alphaname, "wb");
+ if (!alpha)
+ goto cleanup;
+
+ if (pix->n > 1)
+ {
+ if (pix->n > 2)
+ sprintf(colorname, "%s-%04d-color.ppm", prefix, counter);
+ else
+ sprintf(colorname, "%s-%04d-color.pgm", prefix, counter);
+
+ color = fopen(colorname, "wb");
+ if (!color)
+ goto cleanup;
+ }
+
+ counter ++;
+
+ if (pix->n == 5)
+ {
+ fprintf(alpha, "P5\n%d %d\n255\n", pix->w, pix->h);
+ fprintf(color, "P6\n%d %d\n255\n", pix->w, pix->h);
+
+ for (y = 0; y < pix->h; y++)
+ {
+ for (x = 0; x < pix->w; x++)
+ {
+ int a = pix->samples[x * pix->n + y * pix->w * pix->n + 0];
+ int cc = pix->samples[x * pix->n + y * pix->w * pix->n + 1];
+ int mm = pix->samples[x * pix->n + y * pix->w * pix->n + 2];
+ int yy = pix->samples[x * pix->n + y * pix->w * pix->n + 3];
+ int kk = pix->samples[x * pix->n + y * pix->w * pix->n + 4];
+ int r = 255 - MIN(cc + kk, 255);
+ int g = 255 - MIN(mm + kk, 255);
+ int b = 255 - MIN(yy + kk, 255);
+ fputc(a, alpha);
+ fputc(r, color);
+ fputc(g, color);
+ fputc(b, color);
+ }
+ }
+ }
+
+ else if (pix->n == 4)
+ {
+ fprintf(alpha, "P5\n%d %d\n255\n", pix->w, pix->h);
+ fprintf(color, "P6\n%d %d\n255\n", pix->w, pix->h);
+
+ for (y = 0; y < pix->h; y++)
+ {
+ for (x = 0; x < pix->w; x++)
+ {
+ int a = pix->samples[x * pix->n + y * pix->w * pix->n + 0];
+ int r = pix->samples[x * pix->n + y * pix->w * pix->n + 1];
+ int g = pix->samples[x * pix->n + y * pix->w * pix->n + 2];
+ int b = pix->samples[x * pix->n + y * pix->w * pix->n + 3];
+ fputc(a, alpha);
+ fputc(r, color);
+ fputc(g, color);
+ fputc(b, color);
+ }
+ }
+ }
+
+ else if (pix->n == 2)
+ {
+ fprintf(alpha, "P5\n%d %d\n255\n", pix->w, pix->h);
+ fprintf(color, "P5\n%d %d\n255\n", pix->w, pix->h);
+
+ for (y = 0; y < pix->h; y++)
+ {
+ for (x = 0; x < pix->w; x++)
+ {
+ int a = pix->samples[x * pix->n + y * pix->w * pix->n + 0];
+ int g = pix->samples[x * pix->n + y * pix->w * pix->n + 1];
+ fputc(a, alpha);
+ fputc(g, color);
+ }
+ }
+ }
+
+ else if (pix->n == 1)
+ {
+ fprintf(alpha, "P5\n%d %d\n255\n", pix->w, pix->h);
+
+ for (y = 0; y < pix->h; y++)
+ {
+ for (x = 0; x < pix->w; x++)
+ {
+ int g = pix->samples[x * pix->n + y * pix->w * pix->n + 0];
+ fputc(g, alpha);
+ }
+ }
+ }
+
+cleanup:
+ if (alpha) fclose(alpha);
+ if (color) fclose(color);
+}
+