summaryrefslogtreecommitdiff
path: root/src/testpattern
diff options
context:
space:
mode:
Diffstat (limited to 'src/testpattern')
-rw-r--r--src/testpattern/.cvsignore8
-rw-r--r--src/testpattern/Makefile.am66
-rw-r--r--src/testpattern/testpattern.c554
-rw-r--r--src/testpattern/testpattern.h80
-rw-r--r--src/testpattern/testpattern.sample168
-rw-r--r--src/testpattern/testpatternl.l87
-rw-r--r--src/testpattern/testpatterny.y192
7 files changed, 1155 insertions, 0 deletions
diff --git a/src/testpattern/.cvsignore b/src/testpattern/.cvsignore
new file mode 100644
index 0000000..d9b90da
--- /dev/null
+++ b/src/testpattern/.cvsignore
@@ -0,0 +1,8 @@
+testpatterny.c
+testpatterny.h
+testpatternl.c
+testpattern
+Makefile.in
+Makefile
+.deps
+.libs
diff --git a/src/testpattern/Makefile.am b/src/testpattern/Makefile.am
new file mode 100644
index 0000000..7291d7e
--- /dev/null
+++ b/src/testpattern/Makefile.am
@@ -0,0 +1,66 @@
+## $Id: Makefile.am,v 1.5 2001/09/17 20:37:57 rleigh Exp $
+## Copyright (C) 2000 Roger Leigh
+##
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2, or (at your option)
+## any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+## Process this file with automake to produce Makefile.in.
+
+AUTOMAKE_OPTIONS = 1.4 gnu
+
+@SET_MAKE@
+
+MAINT_CHARSET = latin1
+
+
+## Variables
+
+AM_CFLAGS = $(GNUCFLAGS)
+INCLUDES = @INCLUDES@ $(LIBGIMPPRINT_CFLAGS)
+LIBS = @LIBS@ $(INTLLIBS)
+
+## Programs
+
+TESTPATTERN_BIN = testpattern
+
+bin_PROGRAMS = @TESTPATTERN_BIN@
+
+EXTRA_PROGRAMS = testpattern
+
+LFLAGS = -i
+YFLAGS = -d
+
+testpattern_SOURCES = testpattern.c testpatterny.y testpatternl.l testpattern.h
+testpattern_LDADD = $(LIBGIMPPRINT_LIBS)
+testpattern_DEPENDENCIES = $(LIBGIMPPRINT_LIBS)
+
+testpatternl.o: testpatterny.o
+testpattern.o: testpatterny.o
+
+$(LIBGIMPPRINT_LIBS):
+ cd ../main ; \
+ $(MAKE)
+
+SAMPLE_IMAGES = testpattern.sample
+
+pkgdatadir = $(datadir)/$(PACKAGE)/samples
+
+pkgdata_DATA = @SAMPLE_IMAGES@
+
+## Clean
+
+MAINTAINERCLEANFILES = Makefile.in
+
+DISTCLEANFILES = testpatternl.c testpatterny.c testpatterny.h
+EXTRA_DIST = testpatterny.h testpattern.sample
diff --git a/src/testpattern/testpattern.c b/src/testpattern/testpattern.c
new file mode 100644
index 0000000..5802b97
--- /dev/null
+++ b/src/testpattern/testpattern.c
@@ -0,0 +1,554 @@
+/*
+ * "$Id: testpattern.c,v 1.6 2001/10/01 23:14:00 rlk Exp $"
+ *
+ * Test pattern generator for Gimp-Print
+ *
+ * Copyright 2001 Robert Krawitz <rlk@alum.mit.edu>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * This sample program may be used to generate test patterns. It also
+ * serves as an example of how to use the gimp-print API.
+ *
+ * As the purpose of this program is to allow fine grained control over
+ * the output, it uses the raw CMYK output type. This feeds 16 bits each
+ * of CMYK to the driver. This mode performs no correction on the data;
+ * it passes it directly to the dither engine, performing no color,
+ * density, gamma, etc. correction. Most programs will use one of the
+ * other modes (RGB, density and gamma corrected 8-bit CMYK, grayscale, or
+ * black and white).
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gimp-print/gimp-print.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <math.h>
+#include <string.h>
+#include "testpattern.h"
+
+static const char *Image_get_appname(stp_image_t *image);
+static void Image_progress_conclude(stp_image_t *image);
+static void Image_note_progress(stp_image_t *image,
+ double current, double total);
+static void Image_progress_init(stp_image_t *image);
+static stp_image_status_t Image_get_row(stp_image_t *image,
+ unsigned char *data, int row);
+static int Image_height(stp_image_t *image);
+static int Image_width(stp_image_t *image);
+static int Image_bpp(stp_image_t *image);
+static void Image_init(stp_image_t *image);
+static stp_image_t theImage =
+{
+ Image_init,
+ NULL, /* reset */
+ NULL, /* transpose */
+ NULL, /* hflip */
+ NULL, /* vflip */
+ NULL, /* crop */
+ NULL, /* ccw */
+ NULL, /* cw */
+ NULL, /* 180 */
+ Image_bpp,
+ Image_width,
+ Image_height,
+ Image_get_row,
+ Image_get_appname,
+ Image_progress_init,
+ Image_note_progress,
+ Image_progress_conclude,
+ NULL
+};
+
+double global_c_level = 1.0;
+double global_c_gamma = 1.0;
+double global_m_level = 1.0;
+double global_m_gamma = 1.0;
+double global_y_level = 1.0;
+double global_y_gamma = 1.0;
+double global_k_gamma = 1.0;
+double global_gamma = 1.0;
+int levels = 256;
+double ink_limit = 1.0;
+char *printer = 0;
+char *ink_type = 0;
+char *resolution = 0;
+char *media_source = 0;
+char *media_type = 0;
+char *media_size = 0;
+char *dither_algorithm = 0;
+double density = 1.0;
+double xtop = 0;
+double xleft = 0;
+double hsize = 1.0;
+double vsize = 1.0;
+int noblackline = 0;
+int printer_width, printer_height, bandheight;
+int n_testpatterns = 0;
+
+testpattern_t *the_testpatterns = NULL;
+
+char *
+c_strdup(const char *s)
+{
+ int l = strlen(s);
+ char *ret;
+ if (s[0] == '"' && s[l - 1] == '"')
+ {
+ ret = malloc(l - 1);
+ strncpy(ret, s + 1, l - 2);
+ ret[l - 2] = '\0';
+ }
+ else
+ {
+ ret = malloc(strlen(s) + 1);
+ strcpy(ret, s);
+ }
+ return ret;
+}
+
+testpattern_t *
+get_next_testpattern(void)
+{
+ static int internal_n_testpatterns = 0;
+ if (n_testpatterns == 0)
+ {
+ the_testpatterns = malloc(sizeof(testpattern_t));
+ n_testpatterns = internal_n_testpatterns = 1;
+ return &(the_testpatterns[0]);
+ }
+ else if (n_testpatterns >= internal_n_testpatterns)
+ {
+ internal_n_testpatterns *= 2;
+ the_testpatterns =
+ realloc(the_testpatterns,
+ internal_n_testpatterns * sizeof(testpattern_t));
+ }
+ return &(the_testpatterns[n_testpatterns++]);
+}
+
+static void
+do_help(void)
+{
+ fprintf(stderr, "%s", "\
+Usage: testpattern -p printer [-n ramp_levels] [-I ink_limit] [-i ink_type]\n\
+ [-r resolution] [-s media_source] [-t media_type]\n\
+ [-z media_size] [-d dither_algorithm] [-e density]\n\
+ [-c cyan_level] [-m magenta_level] [-y yellow_level]\n\
+ [-C cyan_gamma] [-M magenta_gamma] [-Y yellow_gamma]\n\
+ [-K black_gamma] [-G gamma] [-q]\n\
+ [-H width] [-V height] [-T top] [-L left]\n\
+ -H, -V, -T, -L expressed as fractions of the printable paper size\n\
+ 0.0 < ink_limit <= 1.0\n\
+ 1 < ramp_levels <= 4096\n\
+ 0.1 <= density <= 2.0\n\
+ 0.0 < cyan_level <= 10.0 same for magenta and yellow.\n");
+ exit(1);
+}
+
+static void
+writefunc(void *file, const char *buf, size_t bytes)
+{
+ FILE *prn = (FILE *)file;
+ fwrite(buf, 1, bytes, prn);
+}
+
+int
+main(int argc, char **argv)
+{
+ int c;
+ stp_vars_t v;
+ stp_printer_t the_printer;
+ stp_papersize_t pt;
+ int left, right, top, bottom;
+ const stp_printfuncs_t *printfuncs;
+ int x, y, owidth;
+ int width, height;
+
+ int retval = yyparse();
+ if (retval)
+ return retval;
+
+ while (1)
+ {
+ c = getopt(argc, argv, "qp:n:l:I:r:s:t:z:d:hC:M:Y:K:e:T:L:H:V:c:m:y:G:");
+ if (c == -1)
+ break;
+ switch (c)
+ {
+ case 'C':
+ global_c_gamma = strtod(optarg, 0);
+ break;
+ case 'I':
+ ink_limit = strtod(optarg, 0);
+ break;
+ case 'G':
+ global_gamma = strtod(optarg, 0);
+ break;
+ case 'H':
+ hsize = strtod(optarg, 0);
+ break;
+ case 'K':
+ global_k_gamma = strtod(optarg, 0);
+ break;
+ case 'L':
+ xleft = strtod(optarg, 0);
+ break;
+ case 'M':
+ global_m_gamma = strtod(optarg, 0);
+ break;
+ case 'T':
+ xtop = strtod(optarg, 0);
+ break;
+ case 'V':
+ vsize = strtod(optarg, 0);
+ break;
+ case 'Y':
+ global_y_gamma = strtod(optarg, 0);
+ break;
+ case 'c':
+ global_c_level = strtod(optarg, 0);
+ break;
+ case 'd':
+ dither_algorithm = c_strdup(optarg);
+ break;
+ case 'e':
+ density = strtod(optarg, 0);
+ break;
+ case 'h':
+ do_help();
+ break;
+ case 'i':
+ ink_type = c_strdup(optarg);
+ break;
+ case 'm':
+ global_m_level = strtod(optarg, 0);
+ break;
+ case 'n':
+ levels = atoi(optarg);
+ break;
+ case 'p':
+ printer = c_strdup(optarg);
+ break;
+ case 'q':
+ noblackline = 1;
+ break;
+ case 'r':
+ resolution = c_strdup(optarg);
+ break;
+ case 's':
+ media_source = c_strdup(optarg);
+ break;
+ case 't':
+ media_type = c_strdup(optarg);
+ break;
+ case 'y':
+ global_y_level = strtod(optarg, 0);
+ break;
+ case 'z':
+ media_size = c_strdup(optarg);
+ break;
+ default:
+ fprintf(stderr, "Unknown option '-%c'\n", c);
+ do_help();
+ break;
+ }
+ }
+ if (!printer ||
+ ink_limit <= 0 || ink_limit > 1.0 ||
+ levels < 1 || levels > 4096 ||
+ global_c_level <= 0 || global_c_level > 10 ||
+ global_m_level <= 0 || global_m_level > 10 ||
+ global_y_level <= 0 || global_y_level > 10 ||
+ xtop < 0 || xtop > 1 || xleft < 0 || xleft > 1 ||
+ xtop + vsize > 1 || xleft + hsize > 1 ||
+ hsize < 0 || hsize > 1 || vsize < 0 || vsize > 1)
+ do_help();
+ stp_init();
+ v = stp_allocate_vars();
+ the_printer = stp_get_printer_by_driver(printer);
+ if (!the_printer)
+ {
+ the_printer = stp_get_printer_by_long_name(printer);
+ if (!the_printer)
+ {
+ int i;
+ fprintf(stderr, "Unknown printer %s\nValid printers are:\n",printer);
+ for (i = 0; i < stp_known_printers(); i++)
+ {
+ the_printer = stp_get_printer_by_index(i);
+ fprintf(stderr, "%-16s%s\n", stp_printer_get_driver(the_printer),
+ stp_printer_get_long_name(the_printer));
+ }
+ return 1;
+ }
+ }
+ stp_set_printer_defaults(v, the_printer, NULL);
+ stp_set_outfunc(v, writefunc);
+ stp_set_errfunc(v, writefunc);
+ stp_set_outdata(v, stdout);
+ stp_set_errdata(v, stderr);
+ printfuncs = stp_printer_get_printfuncs(the_printer);
+ stp_set_density(v, density);
+ if (resolution)
+ stp_set_resolution(v, resolution);
+ if (ink_type)
+ stp_set_ink_type(v, ink_type);
+ if (media_type)
+ stp_set_media_type(v, media_type);
+ if (media_source)
+ stp_set_media_source(v, media_source);
+ if (media_size)
+ stp_set_media_size(v, media_size);
+ if (dither_algorithm)
+ stp_set_dither_algorithm(v, dither_algorithm);
+
+ /*
+ * Most programs will not use OUTPUT_RAW_CMYK; OUTPUT_COLOR or
+ * OUTPUT_GRAYSCALE are more useful for most purposes.
+ */
+ stp_set_output_type(v, OUTPUT_RAW_CMYK);
+
+ pt = stp_get_papersize_by_name(stp_get_media_size(v));
+ if (!pt)
+ {
+ fprintf(stderr, "Papersize %s unknown\n", media_size);
+ return 1;
+ }
+
+ (printfuncs->imageable_area)(the_printer, v, &left, &right, &bottom, &top);
+ (printfuncs->describe_resolution)(the_printer, stp_get_resolution(v),&x, &y);
+ if (x < 0)
+ x = 300;
+ if (y < 0)
+ y = 300;
+
+ width = right - left;
+ height = top - bottom;
+ top -= stp_papersize_get_height(pt);
+ top = top + height * xtop;
+ left = width * xleft;
+ owidth = width;
+ if (levels > width)
+ levels = width;
+
+ width = (width / levels) * levels;
+ height = (height / n_testpatterns) * n_testpatterns;
+ if (hsize > vsize)
+ {
+ stp_set_scaling(v, 100 * hsize);
+ printer_width = width * x / 72;
+ printer_height = vsize / hsize * height * y / 72;
+ }
+ else
+ {
+ stp_set_scaling(v, 100 * vsize);
+ printer_width = hsize / vsize * width * x / 72;
+ printer_height = height * y / 72;
+ }
+
+ bandheight = printer_height / n_testpatterns;
+ stp_set_left(v, left + (hsize * (owidth - width) / 2));
+ stp_set_top(v, top);
+ stp_set_orientation(v, ORIENT_PORTRAIT);
+
+ stp_merge_printvars(v, stp_printer_get_printvars(the_printer));
+ if (stp_printer_get_printfuncs(the_printer)->verify(the_printer, v))
+ (stp_printer_get_printfuncs(the_printer)->print)(the_printer, &theImage, v);
+ else
+ return 1;
+ return 0;
+}
+
+static void
+fill_black(unsigned short *data, size_t len, size_t scount)
+{
+ int i;
+ for (i = 0; i < (len / scount) * scount; i++)
+ {
+ data[3] = ink_limit * 65535;
+ data += 4;
+ }
+}
+
+static void
+fill_colors(unsigned short *data, size_t len, size_t scount, testpattern_t *p)
+{
+ double c_min = p->c_min == -2 ? global_c_level : p->c_min;
+ double m_min = p->m_min == -2 ? global_m_level : p->m_min;
+ double y_min = p->y_min == -2 ? global_y_level : p->y_min;
+ double k_min = p->k_min;
+ double c = p->c == -2 ? global_c_level : p->c;
+ double m = p->m == -2 ? global_m_level : p->m;
+ double y = p->y == -2 ? global_y_level : p->y;
+ double c_gamma = p->c_gamma * global_gamma * global_c_gamma;
+ double m_gamma = p->m_gamma * global_gamma * global_m_gamma;
+ double y_gamma = p->y_gamma * global_gamma * global_y_gamma;
+ double k_gamma = p->k_gamma * global_gamma * global_k_gamma;
+ double k = p->k;
+ double c_level = p->c_level == -2 ? global_c_level : p->c_level;
+ double m_level = p->m_level == -2 ? global_m_level : p->m_level;
+ double y_level = p->y_level == -2 ? global_y_level : p->y_level;
+ double lower = p->lower;
+ double upper = p->upper;
+ int i;
+ int j;
+ int pixels;
+ c -= c_min;
+ m -= m_min;
+ y -= y_min;
+ k -= k_min;
+ if (scount > len)
+ scount = len;
+ pixels = len / scount;
+ for (i = 0; i < scount; i++)
+ {
+ double where = (double) i / ((double) scount - 1);
+ double cmyv;
+ double kv;
+ double val = where;
+ double cc = c_min + val * c;
+ double mm = m_min + val * m;
+ double yy = y_min + val * y;
+ double kk = k_min + k;
+ cc = pow(cc, c_gamma);
+ mm = pow(mm, m_gamma);
+ yy = pow(yy, y_gamma);
+ kk = pow(kk, k_gamma);
+ if (where <= lower)
+ kv = 0;
+ else if (where > upper)
+ kv = where;
+ else
+ kv = (where - lower) * upper / (upper - lower);
+ cmyv = k * (where - kv);
+ kk *= kv;
+ cc += cmyv * c_level;
+ mm += cmyv * m_level;
+ yy += cmyv * y_level;
+ if (cc > 1.0)
+ cc = 1.0;
+ if (mm > 1.0)
+ mm = 1.0;
+ if (yy > 1.0)
+ yy = 1.0;
+ if (kk > 1.0)
+ kk = 1.0;
+ cc *= ink_limit * 65535;
+ mm *= ink_limit * 65535;
+ yy *= ink_limit * 65535;
+ kk *= ink_limit * 65535;
+ for (j = 0; j < pixels; j++)
+ {
+ data[0] = cc;
+ data[1] = mm;
+ data[2] = yy;
+ data[3] = kk;
+ data += 4;
+ }
+ }
+}
+
+static stp_image_status_t
+Image_get_row(stp_image_t *image, unsigned char *data, int row)
+{
+ static int previous_band = -1;
+ int band = row / bandheight;
+ if (previous_band == -2)
+ {
+ memset(data, 0, printer_width * 4 * sizeof(unsigned short));
+ fill_colors((unsigned short *)data, printer_width, levels,
+ &(the_testpatterns[band]));
+ previous_band = band;
+ }
+ else if (row == printer_height - 1)
+ {
+ memset(data, 0, printer_width * 4 * sizeof(unsigned short));
+ fill_black((unsigned short *)data, printer_width, levels);
+ }
+ else if (band >= n_testpatterns)
+ memset(data, 0, printer_width * 4 * sizeof(unsigned short));
+ else if (band != previous_band && band > 0)
+ {
+ memset(data, 0, printer_width * 4 * sizeof(unsigned short));
+ if (noblackline)
+ {
+ fill_colors((unsigned short *)data, printer_width, levels,
+ &(the_testpatterns[band]));
+ previous_band = band;
+ }
+ else
+ {
+ fill_black((unsigned short *)data, printer_width, levels);
+ previous_band = -2;
+ }
+ }
+ return STP_IMAGE_OK;
+}
+
+static int
+Image_bpp(stp_image_t *image)
+{
+ return 8;
+}
+
+static int
+Image_width(stp_image_t *image)
+{
+ return printer_width;
+}
+
+static int
+Image_height(stp_image_t *image)
+{
+ return printer_height;
+}
+
+static void
+Image_init(stp_image_t *image)
+{
+ /* dummy function */
+}
+
+static void
+Image_progress_init(stp_image_t *image)
+{
+ /* dummy function */
+}
+
+/* progress display */
+static void
+Image_note_progress(stp_image_t *image, double current, double total)
+{
+ fprintf(stderr, ".");
+}
+
+static void
+Image_progress_conclude(stp_image_t *image)
+{
+ fprintf(stderr, "\n");
+}
+
+static const char *
+Image_get_appname(stp_image_t *image)
+{
+ return "Test Pattern";
+}
diff --git a/src/testpattern/testpattern.h b/src/testpattern/testpattern.h
new file mode 100644
index 0000000..d2cd2bc
--- /dev/null
+++ b/src/testpattern/testpattern.h
@@ -0,0 +1,80 @@
+/*
+ * "$Id: testpattern.h,v 1.2 2001/08/14 00:12:58 rlk Exp $"
+ *
+ * Test pattern generator for Gimp-Print
+ *
+ * Copyright 2001 Robert Krawitz <rlk@alum.mit.edu>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+typedef struct
+{
+ double c_min;
+ double c;
+ double c_gamma;
+ double m_min;
+ double m;
+ double m_gamma;
+ double y_min;
+ double y;
+ double y_gamma;
+ double k_min;
+ double k;
+ double k_gamma;
+ double c_level;
+ double m_level;
+ double y_level;
+ double lower;
+ double upper;
+} testpattern_t;
+
+extern double global_c_level;
+extern double global_c_gamma;
+extern double global_m_level;
+extern double global_m_gamma;
+extern double global_y_level;
+extern double global_y_gamma;
+extern double global_k_gamma;
+extern double global_gamma;
+extern int levels;
+extern double ink_limit;
+extern char *printer;
+extern char *ink_type;
+extern char *resolution;
+extern char *media_source;
+extern char *media_type;
+extern char *media_size;
+extern char *dither_algorithm;
+extern double density;
+extern double xtop;
+extern double xleft;
+extern double hsize;
+extern double vsize;
+extern int noblackline;
+extern char *c_strdup(const char *s);
+extern testpattern_t *get_next_testpattern(void);
+
+typedef union yylv {
+ int ival;
+ double dval;
+ char *sval;
+} YYSTYPE;
+
+extern YYSTYPE yylval;
+
+#include "testpatterny.h"
+
+
diff --git a/src/testpattern/testpattern.sample b/src/testpattern/testpattern.sample
new file mode 100644
index 0000000..6897962
--- /dev/null
+++ b/src/testpattern/testpattern.sample
@@ -0,0 +1,168 @@
+# Sample test pattern file, for use with Gimp-Print test pattern generator
+
+# Printer/driver settings. Please see src/ghost/README for appropriate
+# values for each of these settings
+# Printer model
+printer escp2-870
+# Resolution, or print quality
+resolution 360sw
+# Media source (if appropriate for your printer)
+media_source Standard
+# Media type (what kind of paper)
+media_type Photo
+# ink_type
+ink_type PhotoCMYK
+# Paper size
+media_size Letter
+# Dither algorithm
+dither_algorithm Ordered
+
+# Note that due to limitations in the lexical analyzer and parser, all
+# floating point values must be specified with a decimal point.
+
+# Placement settings
+# Horizontal size, as fraction of paper width (defaults to 1.0)
+hsize 0.33
+# Vertical size, as fraction of paper width (defaults to 1.0)
+vsize 0.33
+# Left margin, as fraction of paper width (defaults to 0)
+left 0.66
+# Top margin, as fraction of paper width (defaults to 0)
+top 0.66
+
+# Output settings
+# These settings are used as the base values for all ramps. These settings
+# are multiplied by the appropriate values in each pattern definition
+# to compute the effective gamma and conversion values. All of these
+# default to 1.0.
+# Gamma value applied to all inks
+gamma 1.0
+# Additional gamma correction applied to cyan, magenta, yellow, and black inks
+c_gamma 1.0
+m_gamma 1.0
+y_gamma 1.0
+k_gamma 1.0
+# Amount of each ink that should be used when black is converted to CMY.
+# These values must be greater than 0 and must not exceed 10.
+c_level 1.0
+m_level 1.0
+y_level 1.0
+
+# Maximum amount of ink that will be printed, relative to solid coverage.
+# 1.0 means that every dot position that can be printed will be. Normally
+# at high resolutions less ink should be printed. This is similar to
+# density in normal RGB mode, but does not affect photo ink conversion.
+ink_limit 1.0
+
+# Density. Unlike normal RGB mode, the CMYK16 input mode used by the
+# test pattern generator does not automatically scale the amount of ink
+# used by the resolution and paper type (see ink_limit above). The test
+# driver separates the functions of ink limiting and photo ink conversion
+# to allow maximum control over the output.
+density 1.0
+
+# Do we want a thin black line between each band? (default yes)
+blackline 0
+
+# Number of levels in each ramp (default 256)
+levels 16
+
+# Pattern specifiers
+# CYAN MAGENTA YELLOW BLACK BLACK BLACK RAMP ENDPOINTS
+# CONVERSION
+# Min Min Min Min Cyan Lower
+# Max Max Max Max Magenta Upper
+# Gamma Gamma Gamma Gamma Yellow
+
+# 0) White band
+pattern 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0
+# 1) C sweep
+pattern 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 1.0 1.0 1.0 1.0
+# 2) M sweep
+pattern 0.0 0.0 1.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 1.0 1.0 1.0 1.0
+# 3) Y sweep
+pattern 0.0 0.0 1.0 0.0 0.0 1.0 0.0 1.0 1.0 0.0 0.0 1.0 1.0 1.0 1.0 1.0 1.0
+# 4) Pure CMY sweep
+pattern 0.0 1.0 1.0 0.0 1.0 1.0 0.0 1.0 1.0 0.0 0.0 1.0 1.0 1.0 1.0 1.0 1.0
+# 5) K sweep
+pattern 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 1.0 1.0 1.0 1.0 1.0 0.0 0.0
+# 6) Adjusted CMY sweep
+pattern 0.0 -2.0 1.0 0.0 -2.0 1.0 0.0 -2.0 1.0 0.0 0.0 1.0 1.0 1.0 1.0 1.0 1.0
+# 7) Pure CMY sweep
+pattern 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
+# 8) Adjusted CMY sweep
+pattern 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 1.0 1.0 -2.0 -2.0 -2.0 1.0 1.0
+# 9) CMYK, transition band 10-30%
+pattern 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 1.0 1.0 1.0 1.0 1.0 0.1 0.3
+# 10) Adjusted CMYK, transition band 30-70%
+pattern 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 1.0 1.0 -2.0 -2.0 -2.0 0.3 0.7
+# 11) CMYK, transition band 10-99.9%
+pattern 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 1.0 1.0 1.0 1.0 1.0 0.1 0.999
+# 12) CMYK, transition band 30-99.9%
+pattern 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 1.0 1.0 1.0 1.0 1.0 0.3 0.999
+# 13) CMYK, transition band 50-99.9%
+pattern 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 1.0 1.0 1.0 1.0 1.0 0.5 0.999
+# 14) Adjusted CMYK, transition band 10-30%
+pattern 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 1.0 1.0 -2.0 -2.0 -2.0 0.1 0.3
+# 15) CMYK, transition band 30-70%
+pattern 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 1.0 1.0 1.0 1.0 1.0 0.3 0.7
+# 16) Adjusted CMYK, transition band 10-99.9%
+pattern 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 1.0 1.0 -2.0 -2.0 -2.0 0.1 0.999
+# 17) Adjusted CMYK, transition band 30-99.9%
+pattern 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 1.0 1.0 -2.0 -2.0 -2.0 0.3 0.999
+# 18) Adjusted CMYK, transition band 50-99.9%
+pattern 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 1.0 1.0 -2.0 -2.0 -2.0 0.5 0.999
+# 19) Y+M (R) sweep
+pattern 0.0 0.0 1.0 0.0 1.0 1.0 0.0 1.0 1.0 0.0 0.0 1.0 1.0 1.0 1.0 1.0 1.0
+# 20) Y+M+.25C sweep
+pattern 0.0 0.0 1.0 0.0 0.75 1.0 0.0 0.75 1.0 0.0 0.25 1.0 1.0 1.0 1.0 1.0 1.0
+# 21) Y+M+.25C sweep (using K)
+pattern 0.0 0.0 1.0 0.0 0.75 1.0 0.0 0.75 1.0 0.0 0.25 1.0 1.0 1.0 1.0 0.0 0.0
+# 22) Y+M+.5C sweep
+pattern 0.0 0.0 1.0 0.0 0.5 1.0 0.0 0.5 1.0 0.0 0.5 1.0 1.0 1.0 1.0 1.0 1.0
+# 23) Y+M+.5C sweep (using K)
+pattern 0.0 0.0 1.0 0.0 0.5 1.0 0.0 0.5 1.0 0.0 0.5 1.0 1.0 1.0 1.0 0.0 0.0
+# 24) Y+M+.75C sweep
+pattern 0.0 0.0 1.0 0.0 0.25 1.0 0.0 0.25 1.0 0.0 0.75 1.0 1.0 1.0 1.0 1.0 1.0
+# 25) Y+M+.75C sweep (using K)
+pattern 0.0 0.0 1.0 0.0 0.25 1.0 0.0 0.25 1.0 0.0 0.75 1.0 1.0 1.0 1.0 0.0 0.0
+# 26) Y+M+.9C sweep
+pattern 0.0 0.0 1.0 0.0 0.1 1.0 0.0 0.1 1.0 0.0 0.9 1.0 1.0 1.0 1.0 1.0 1.0
+# 27) Y+M+.9C sweep (using K)
+pattern 0.0 0.0 1.0 0.0 0.1 1.0 0.0 0.1 1.0 0.0 0.9 1.0 1.0 1.0 1.0 0.0 0.0
+# 28) C+Y (G) sweep
+pattern 0.0 1.0 1.0 0.0 0.0 1.0 0.0 1.0 1.0 0.0 0.0 1.0 1.0 1.0 1.0 1.0 1.0
+# 29) C+Y+.25M sweep
+pattern 0.0 0.75 1.0 0.0 0.0 1.0 0.0 0.75 1.0 0.0 0.25 1.0 1.0 1.0 1.0 1.0 1.0
+# 30) C+Y+.25M sweep (using K)
+pattern 0.0 0.75 1.0 0.0 0.0 1.0 0.0 0.75 1.0 0.0 0.25 1.0 1.0 1.0 1.0 0.0 0.0
+# 31) C+Y+.5M sweep
+pattern 0.0 0.5 1.0 0.0 0.0 1.0 0.0 0.5 1.0 0.0 0.5 1.0 1.0 1.0 1.0 1.0 1.0
+# 32) C+Y+.5M sweep (using K)
+pattern 0.0 0.5 1.0 0.0 0.0 1.0 0.0 0.5 1.0 0.0 0.5 1.0 1.0 1.0 1.0 0.0 0.0
+# 33) C+Y+.75M sweep
+pattern 0.0 0.25 1.0 0.0 0.0 1.0 0.0 0.25 1.0 0.0 0.75 1.0 1.0 1.0 1.0 1.0 1.0
+# 34) C+Y+.75M sweep (using K)
+pattern 0.0 0.25 1.0 0.0 0.0 1.0 0.0 0.25 1.0 0.0 0.75 1.0 1.0 1.0 1.0 0.0 0.0
+# 35) C+Y+.9M sweep
+pattern 0.0 0.1 1.0 0.0 0.0 1.0 0.0 0.1 1.0 0.0 0.9 1.0 1.0 1.0 1.0 1.0 1.0
+# 36) C+Y+.9M sweep (using K)
+pattern 0.0 0.1 1.0 0.0 0.0 1.0 0.0 0.1 1.0 0.0 0.9 1.0 1.0 1.0 1.0 0.0 0.0
+# 37) C+M (B) sweep
+pattern 0.0 1.0 1.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 1.0 1.0 1.0 1.0
+# 38) C+M+.25Y sweep
+pattern 0.0 0.75 1.0 0.0 0.75 1.0 0.0 0.0 1.0 0.0 0.25 1.0 1.0 1.0 1.0 1.0 1.0
+# 39) C+M+.25Y sweep (using K)
+pattern 0.0 0.75 1.0 0.0 0.75 1.0 0.0 0.0 1.0 0.0 0.25 1.0 1.0 1.0 1.0 0.0 0.0
+# 40) C+M+.5Y sweep
+pattern 0.0 0.5 1.0 0.0 0.5 1.0 0.0 0.0 1.0 0.0 0.5 1.0 1.0 1.0 1.0 1.0 1.0
+# 41) C+M+.5Y sweep (using K)
+pattern 0.0 0.5 1.0 0.0 0.5 1.0 0.0 0.0 1.0 0.0 0.5 1.0 1.0 1.0 1.0 0.0 0.0
+# 42) C+M+.75Y sweep
+pattern 0.0 0.25 1.0 0.0 0.25 1.0 0.0 0.0 1.0 0.0 0.75 1.0 1.0 1.0 1.0 1.0 1.0
+# 43) C+M+.75Y sweep (using K)
+pattern 0.0 0.25 1.0 0.0 0.25 1.0 0.0 0.0 1.0 0.0 0.75 1.0 1.0 1.0 1.0 0.0 0.0
+# 44) C+M+.9Y sweep
+pattern 0.0 0.1 1.0 0.0 0.1 1.0 0.0 0.0 1.0 0.0 0.9 1.0 1.0 1.0 1.0 1.0 1.0
+# 45) C+M+.9Y sweep (using K)
+pattern 0.0 0.1 1.0 0.0 0.1 1.0 0.0 0.0 1.0 0.0 0.9 1.0 1.0 1.0 1.0 0.0 0.0
diff --git a/src/testpattern/testpatternl.l b/src/testpattern/testpatternl.l
new file mode 100644
index 0000000..164cf3a
--- /dev/null
+++ b/src/testpattern/testpatternl.l
@@ -0,0 +1,87 @@
+/*
+ * "$Id: testpatternl.l,v 1.2 2001/08/14 00:12:58 rlk Exp $"
+ *
+ * Test pattern generator for Gimp-Print
+ *
+ * Copyright 2001 Robert Krawitz <rlk@alum.mit.edu>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+%{
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "testpattern.h"
+
+#define YY_NO_UNPUT
+
+int mylineno = 1;
+
+#if 0
+#define DBG(x) fprintf(stderr, "'%s'%s\n", yytext, #x);
+#else
+#define DBG(x)
+#endif
+
+%}
+
+%option noyywrap
+
+digit [0-9]
+integer [-+]?{digit}+
+float [-+]?{digit}+(\.{digit}+)?([eE][-+]?{digit}+)?
+string ([\"][^\"\n]+[\"])|([^ \t\n"]+)
+ws [ \t]+
+
+%%
+
+c_gamma DBG(C_GAMMA) return C_GAMMA;
+m_gamma DBG(M_GAMMA) return M_GAMMA;
+y_gamma DBG(Y_GAMMA) return Y_GAMMA;
+k_gamma DBG(K_GAMMA) return K_GAMMA;
+gamma DBG(GAMMA) return GAMMA;
+c_level DBG(C_LEVEL) return C_LEVEL;
+m_level DBG(M_LEVEL) return M_LEVEL;
+y_level DBG(Y_LEVEL) return Y_LEVEL;
+levels DBG(LEVELS) return LEVELS;
+ink_limit DBG(INK_LIMIT) return INK_LIMIT;
+width DBG(WIDTH) return WIDTH;
+printer DBG(PRINTER) return PRINTER;
+ink_type DBG(INK_TYPE) return INK_TYPE;
+resolution DBG(RESOLUTION) return RESOLUTION;
+media_source DBG(MEDIA_SOURCE) return MEDIA_SOURCE;
+media_type DBG(MEDIA_TYPE) return MEDIA_TYPE;
+media_size DBG(MEDIA_SIZE) return MEDIA_SIZE;
+dither_algorithm DBG(DITHER_ALGORITHM) return DITHER_ALGORITHM;
+density DBG(DENSITY) return DENSITY;
+top DBG(TOP) return TOP;
+left DBG(LEFT) return LEFT;
+hsize DBG(HSIZE) return HSIZE;
+vsize DBG(VSIZE) return VSIZE;
+blackline DBG(BLACKLINE) return BLACKLINE;
+pattern DBG(PATTERN) return PATTERN;
+
+{integer} yylval.ival = atoi(yytext); DBG(tINT) return tINT;
+{float} yylval.dval = strtod(yytext, NULL); DBG(tDOUBLE) return tDOUBLE;
+{string} yylval.sval = c_strdup(yytext); DBG(tSTRING) return tSTRING;
+{ws} DBG(whitespace1) /* Skip blanks/tabs */
+#[^\n]* DBG(comment1) /* Skip comments */
+\n DBG(newline) mylineno++;
diff --git a/src/testpattern/testpatterny.y b/src/testpattern/testpatterny.y
new file mode 100644
index 0000000..f5dc681
--- /dev/null
+++ b/src/testpattern/testpatterny.y
@@ -0,0 +1,192 @@
+/*
+ * "$Id: testpatterny.y,v 1.3 2001/10/27 17:16:39 rlk Exp $"
+ *
+ * Test pattern generator for Gimp-Print
+ *
+ * Copyright 2001 Robert Krawitz <rlk@alum.mit.edu>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+%{
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "testpattern.h"
+
+extern int mylineno;
+
+extern int yylex(void);
+int yyerror(const char *s);
+char *quotestrip(const char *i);
+char *endstrip(const char *i);
+
+extern int mylineno;
+extern char* yytext;
+
+static int yyerror( const char *s )
+{
+ fprintf(stderr,"stdin:%d: %s before '%s'\n",mylineno,s,yytext);
+ return 0;
+}
+
+%}
+
+%token <ival> tINT
+%token <dval> tDOUBLE
+%token <sval> tSTRING
+
+%token C_GAMMA
+%token M_GAMMA
+%token Y_GAMMA
+%token K_GAMMA
+%token GAMMA
+%token C_LEVEL
+%token M_LEVEL
+%token Y_LEVEL
+%token LEVELS
+%token INK_LIMIT
+%token INK
+%token WIDTH
+%token PRINTER
+%token INK_TYPE
+%token RESOLUTION
+%token MEDIA_SOURCE
+%token MEDIA_TYPE
+%token MEDIA_SIZE
+%token DITHER_ALGORITHM
+%token DENSITY
+%token TOP
+%token LEFT
+%token HSIZE
+%token VSIZE
+%token BLACKLINE
+%token PATTERN
+
+%start Rules
+
+%%
+
+global_c_level: C_LEVEL tDOUBLE
+ { global_c_level = $2; }
+;
+global_m_level: M_LEVEL tDOUBLE
+ { global_m_level = $2; }
+;
+global_y_level: Y_LEVEL tDOUBLE
+ { global_y_level = $2; }
+;
+global_c_gamma: C_GAMMA tDOUBLE
+ { global_c_gamma = $2; }
+;
+global_m_gamma: M_GAMMA tDOUBLE
+ { global_m_gamma = $2; }
+;
+global_y_gamma: Y_GAMMA tDOUBLE
+ { global_y_gamma = $2; }
+;
+global_k_gamma: K_GAMMA tDOUBLE
+ { global_k_gamma = $2; }
+;
+global_gamma: GAMMA tDOUBLE
+ { global_gamma = $2; }
+;
+levels: LEVELS tINT
+ { levels = $2; }
+;
+ink_limit: INK_LIMIT tDOUBLE
+ { ink_limit = $2; }
+;
+printer: PRINTER tSTRING
+ { printer = c_strdup($2); }
+;
+ink_type: INK_TYPE tSTRING
+ { ink_type = c_strdup($2); }
+;
+resolution: RESOLUTION tSTRING
+ { resolution = c_strdup($2); }
+;
+media_source: MEDIA_SOURCE tSTRING
+ { media_source = c_strdup($2); }
+;
+media_type: MEDIA_TYPE tSTRING
+ { media_type = c_strdup($2); }
+;
+media_size: MEDIA_SIZE tSTRING
+ { media_size = c_strdup($2); }
+;
+dither_algorithm: DITHER_ALGORITHM tSTRING
+ { dither_algorithm = c_strdup($2); }
+;
+density: DENSITY tDOUBLE
+ { density = $2; }
+;
+top: TOP tDOUBLE
+ { xtop = $2; }
+;
+left: LEFT tDOUBLE
+ { xleft = $2; }
+;
+hsize: HSIZE tDOUBLE
+ { hsize = $2; }
+;
+vsize: VSIZE tDOUBLE
+ { vsize = $2; }
+;
+blackline: BLACKLINE tINT
+ { noblackline = !($2); }
+;
+
+pattern: PATTERN tDOUBLE tDOUBLE tDOUBLE tDOUBLE tDOUBLE tDOUBLE tDOUBLE
+ tDOUBLE tDOUBLE tDOUBLE tDOUBLE tDOUBLE tDOUBLE tDOUBLE tDOUBLE
+ tDOUBLE tDOUBLE
+ {
+ testpattern_t *t = get_next_testpattern();
+ t->c_min = $2;
+ t->c = $3;
+ t->c_gamma = $4;
+ t->m_min = $5;
+ t->m = $6;
+ t->m_gamma = $7;
+ t->y_min = $8;
+ t->y = $9;
+ t->y_gamma = $10;
+ t->k_min = $11;
+ t->k = $12;
+ t->k_gamma = $13;
+ t->c_level = $14;
+ t->m_level = $15;
+ t->y_level = $16;
+ t->lower = $17;
+ t->upper = $18;
+ }
+;
+
+Empty:
+
+Rule: global_c_level | global_m_level | global_y_level
+ | global_c_gamma | global_m_gamma | global_y_gamma | global_k_gamma
+ | global_gamma | levels | ink_limit | printer | ink_type | resolution
+ | media_source | media_type | media_size | dither_algorithm | density
+ | top | left | hsize | vsize | blackline | pattern
+
+Rules: Rules Rule | Empty
+
+%%