Last active
October 10, 2021 20:10
-
-
Save defremov/eda5e00596f2eded8b85 to your computer and use it in GitHub Desktop.
Add print quality settings to foo2hbpl1 driver for HBPL1 printers, http://www.dechifro.org/hbpl/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/foo2hbpl1.c b/foo2hbpl1.c | |
index fb4f448..d0ad6cd 100644 | |
--- a/foo2hbpl1.c | |
+++ b/foo2hbpl1.c | |
@@ -52,11 +52,38 @@ static char Version[] = "$Id: foo2hbpl1.c,v 1.3 2014/03/30 05:08:32 rick Exp $"; | |
/* | |
* Command line options | |
*/ | |
-int MediaCode = 0; | |
+char *ClutFilePath = NULL; | |
+int DocType = 0; | |
+int OutputColor = 0; | |
+int DraftMode = 0; | |
+int NumCopies = 1; | |
+int Trapping = 0; | |
+int Screen = 0; | |
+int MediaCode = 1; | |
char *Username = NULL; | |
char *Filename = NULL; | |
int Clip[] = { 8,8,8,8 }; | |
+char *cb_cmyk = "CMYK"; | |
+char *cb_lmh = "LMH"; | |
+char ColorBalance[] = | |
+/* +--- L = Low | |
+ |+-- M = Medium | |
+ ||+- H = High | |
+ ||| */ | |
+ "333" /* C = Cyan */ | |
+ "333" /* M = Magenta */ | |
+ "333" /* Y = Yellow */ | |
+ "333"; /* K = Black */ | |
+/* | |
+ 0 = Lighter (-3) | |
+ 1 = Lighter (-2) | |
+ 2 = Lighter (-1) | |
+ * 3 = Normal | |
+ 4 = Darker (+1) | |
+ 5 = Darker (+2) | |
+ 6 = Darker (+3) */ | |
+ | |
void | |
usage(void) | |
{ | |
@@ -73,15 +100,73 @@ usage(void) | |
" | foo2hbpl1 >testpage.zc\n" | |
"\n" | |
"Options:\n" | |
-"-m media Media code to send to printer [1 or 6]\n" | |
-" 1=plain, 2=bond, 3=lwcard, 4=lwgcard, 5=labels,\n" | |
-" 6=envelope, 7=recycled, 8=plain2, 9=bond2,\n" | |
-" 10=lwcard2, 11=lwgcard2, 12=recycled2\n" | |
+"-a values Color balance adjustment [default: %s]\n" | |
+" Argument is a string of 12 adjustment values\n" | |
+" in range of 0..6 each:\n" | |
+" 0 = Lighter (-3)\n" | |
+" 1 = Lighter (-2)\n" | |
+" 2 = Lighter (-1)\n" | |
+" 3 = Normal\n" | |
+" 4 = Darker (+1)\n" | |
+" 5 = Darker (+2)\n" | |
+" 6 = Darker (+3)\n" | |
+" in the following order:\n" | |
+" |C|C|C|M|M|M|Y|Y|Y|K|K|K|\n" | |
+" |l|m|h|l|m|h|l|m|h|l|m|h|\n" | |
+" where C=Cyan, M=Magenta, Y=Yellow, K=Black,\n" | |
+" l=Low, m=Medium, h=High.\n" | |
+"-c Print ppmraw in color mode.\n" | |
+" If not set print in black and white.\n" | |
+" Has no effect if document type (-i option) is 0\n" | |
+"-i type Document type code for print quality\n" | |
+" adjustment of ppmraw input [default: %d]\n" | |
+" 0=No adjustment, 1=Standard, 2=Photos,\n" | |
+" 3=Presentation, 4=Web Pages, 5=POP, 6=None\n" | |
+"-l path Pathname of the file containing color\n" | |
+" look-up tables. Must be specified for\n" | |
+" document types 1..5 in color mode.\n" | |
+"-m media Media code to send to printer [default: %d]\n" | |
+" 1=Plain\n" | |
+" 2=Plain, side 2\n" | |
+" 3=Bond\n" | |
+" 4=Bond, side 2\n" | |
+" 5=Recycled\n" | |
+" 6=Recycled, side 2\n" | |
+" 7=Labels\n" | |
+" 8=Lightweight Cardstock\n" | |
+" 9=Lightweight Cardstock, side 2\n" | |
+" 10=Lightweight Glossy Cardstock\n" | |
+" 11=Lightweight Glossy Cardstock, side 2\n" | |
+" 12=Letterhead\n" | |
+" 13=Letterhead, side 2\n" | |
+" 14=Pre-Printed\n" | |
+" 15=Pre-Printed, side 2\n" | |
+" 16=Hole Punched\n" | |
+" 17=Hole Punched, side 2\n" | |
+" 18=Colored\n" | |
+" 19=Colored, side 2\n" | |
+" 20=Custom Type\n" | |
+" 21=Custom Type, side 2\n" | |
+" 22=Special\n" | |
+" 23=Special, side 2\n" | |
+" 24=Envelope\n" | |
+"-n copies Number of copies, 1..100 [default: %d]\n" | |
+"-s type Screen type code [default: %d]\n" | |
+" 0=Auto, 1=Fineness, 2=Standard, 3=Gradation\n" | |
+"-t Print ppmraw in draft mode.\n" | |
+" Has no effect if document type (-i option) is 0\n" | |
"-u left,top,right,bottom\n" | |
-" Erase margins of specified width [%d,%d,%d,%d]\n" | |
+" Erase margins of specified width\n" | |
+" [default: %d,%d,%d,%d]\n" | |
"-J filename Filename string to send to printer\n" | |
+"-T Turn trapping on.\n" | |
"-U username Username string to send to printer\n" | |
"-V Version %s\n" | |
+ , ColorBalance | |
+ , DocType | |
+ , MediaCode | |
+ , NumCopies | |
+ , Screen | |
, Clip[0], Clip[1], Clip[2], Clip[3] | |
, Version); | |
} | |
@@ -98,6 +183,37 @@ error(int fatal, char *fmt, ...) | |
if (fatal) exit(fatal); | |
} | |
+enum doc_type_id { | |
+ DOC_NORMAL, | |
+ DOC_PHOTO, | |
+ DOC_PRESENTATION, | |
+ DOC_WEB, | |
+ DOC_POP, | |
+ DOC_NONE | |
+}; | |
+ | |
+struct doc_type_jobattr | |
+{ | |
+ int color, mono; | |
+} screen_jobattr_index[] = { | |
+ {61, 64}, // Fineness | |
+ {62, 65}, // Standard | |
+ {63, 66} // Gradation | |
+ }; | |
+ | |
+static const struct doc_type | |
+{ | |
+ int clut_id; | |
+ struct doc_type_jobattr jobattr; | |
+} doc_type_index[] = { | |
+ { 0, {11, 33}}, // Normal | |
+ { 2, {14, 33}}, // Photo | |
+ { 3, {15, 33}}, // Presentation | |
+ { 5, {17, 33}}, // Web | |
+ { 7, {19, 33}}, // POP | |
+ {18, {31, 33}} // Off | |
+ }; | |
+ | |
struct stream | |
{ | |
unsigned char *buf; | |
@@ -262,20 +378,38 @@ start_doc(int color) | |
struct tm *tmp; | |
char datestr[16], timestr[16]; | |
char cname[128] = "My Computer"; | |
+ int i, doc_type_id; | |
+ static const char *doc_type_jobattr_cprucr[] = {"CPR", "UCR"}; | |
+ static const char *doc_type_jobattr_trcscr[] = {"TRC", "SCR"}; | |
+ static const char *doc_type_jobattr_prefix = "TGI"; | |
+ int doc_type_jobattr = 0; | |
+ const struct doc_type_jobattr *s_doc_type_jobattr = NULL; | |
char *mname[] = | |
- { "", | |
- "NORMAL", | |
- "THICK", | |
- "HIGHQUALITY", | |
- "COAT2", | |
- "LABEL", | |
- "ENVELOPE", | |
- "RECYCLED", | |
- "NORMALREV", | |
- "THICKSIDE2", | |
- "HIGHQUALITYREV", | |
- "COATEDPAPER2REV", | |
- "RECYCLEREV", | |
+ { | |
+ "NORMAL", | |
+ "NORMALREV", | |
+ "HIGHQUALITY", | |
+ "HIGHQUALITYREV", | |
+ "RECYCLE", | |
+ "RECYCLEREV", | |
+ "LABEL", | |
+ "THICK", | |
+ "THICKSIDE2", | |
+ "COATEDPAPER2", | |
+ "COATEDPAPER2REV", | |
+ "LETTERHEAD", | |
+ "LETTERHEADREV", | |
+ "PREPRINTED", | |
+ "PREPRINTEDREV", | |
+ "PREPUNCHED", | |
+ "PREPUNCHEDREV", | |
+ "COLOR", | |
+ "COLORREV", | |
+ "USER1", | |
+ "USER1REV", | |
+ "SPECIAL", | |
+ "SPECIALREV", | |
+ "ENVELOPE" | |
}; | |
t = time(NULL); | |
@@ -296,54 +430,98 @@ start_doc(int color) | |
/* Lines end with \n, not \r\n */ | |
printf( | |
- "\033%%-12345X@PJL SET STRINGCODESET=UTF8\n" | |
- "@PJL COMMENT DATE=%s\n" | |
- "@PJL COMMENT TIME=%s\n" | |
- "@PJL COMMENT DNAME=%s\n" | |
- "@PJL JOB MODE=PRINTER\n" | |
- "@PJL SET JOBATTR=\"@LUNA=%s\"\n" | |
- "@PJL SET JOBATTR=\"@TRCH=OFF\"\n" | |
- "@PJL SET DUPLEX=OFF\n" | |
- "@PJL SET BINDING=LONGEDGE\n" | |
- "@PJL SET IWAMANUALDUP=OFF\n" | |
- "@PJL SET JOBATTR=\"@MSIP=%s\"\n" | |
- "@PJL SET RENDERMODE=%s\n" | |
- "@PJL SET ECONOMODE=OFF\n" | |
- "@PJL SET RET=ON\n" | |
- "@PJL SET JOBATTR=\"@IREC=OFF\"\n" | |
- "@PJL SET JOBATTR=\"@TRAP=ON\"\n" | |
- "@PJL SET JOBATTR=\"@JOAU=%s\"\n" | |
- "@PJL SET JOBATTR=\"@CNAM=%s\"\n" | |
- "@PJL SET COPIES=1\n" | |
- "@PJL SET QTY=1\n" | |
- "@PJL SET PAPERDIRECTION=SEF\n" | |
- "@PJL SET RESOLUTION=600\n" | |
- "@PJL SET BITSPERPIXEL=8\n" | |
- "@PJL SET JOBATTR=\"@DRDM=XRC\"\n" | |
- "@PJL SET JOBATTR=\"@TSCR=11\"\n" | |
- "@PJL SET JOBATTR=\"@GSCR=11\"\n" | |
- "@PJL SET JOBATTR=\"@ISCR=12\"\n" | |
- "@PJL SET JOBATTR=\"@TTRC=11\"\n" | |
- "@PJL SET JOBATTR=\"@GTRC=11\"\n" | |
- "@PJL SET JOBATTR=\"@ITRC=12\"\n" | |
- "@PJL SET JOBATTR=\"@TCPR=11\"\n" | |
- "@PJL SET JOBATTR=\"@GCPR=11\"\n" | |
- "@PJL SET JOBATTR=\"@ICPR=12\"\n" | |
- "@PJL SET JOBATTR=\"@TUCR=11\"\n" | |
- "@PJL SET JOBATTR=\"@GUCR=11\"\n" | |
- "@PJL SET JOBATTR=\"@IUCR=12\"\n" | |
- "@PJL SET JOBATTR=\"@BSPM=OFF\"\n" | |
- "@PJL SET JOBATTR=\"@TDFT=0\"\n" | |
- "@PJL SET JOBATTR=\"@GDFT=0\"\n" | |
- "@PJL SET JOBATTR=\"@IDFT=0\"\n" | |
- "@PJL ENTER LANGUAGE=HBPL\n" | |
- , datestr, timestr | |
- , Filename ? Filename : "" | |
- , Username ? Username : "" | |
- , mname[MediaCode] | |
- , color ? "COLOR" : "GRAYSCALE" | |
- , Username ? Username : "" | |
- , cname); | |
+ "\033%%-12345X@PJL JOB MODE=PRINTER\n" | |
+ "@PJL SET STRINGCODESET=UTF8\n" | |
+ ); | |
+ | |
+ printf("@PJL COMMENT DATE=%s\n", datestr); | |
+ printf("@PJL COMMENT TIME=%s\n", timestr); | |
+ printf("@PJL COMMENT DNAME=%s\n", Filename ? Filename : ""); | |
+ printf("@PJL SET JOBATTR=\"@LUNA=%s\"\n", Username ? Username : ""); | |
+ printf("@PJL SET COPIES=%d\n", NumCopies); | |
+ | |
+ printf( | |
+ "@PJL SET JOBATTR=\"@TRCH=OFF\"\n" | |
+ "@PJL SET DUPLEX=OFF\n" | |
+ ); | |
+ | |
+ for (i = 0; i < 12; i++) { | |
+ printf("@PJL SET JOBATTR=\"@AJ%c%c=%c\"\n", | |
+ cb_cmyk[i / 3], cb_lmh[i % 3], ColorBalance[i]); | |
+ } | |
+ | |
+ printf("@PJL SET JOBATTR=\"@APSP=OFF\"\n"); | |
+ | |
+ printf("@PJL SET JOBATTR=\"@MSIP=%s\"\n", mname[MediaCode - 1]); | |
+ printf("@PJL SET RENDERMODE=%s\n", color ? "COLOR" : "GRAYSCALE"); | |
+ printf("@PJL SET ECONOMODE=%s\n", DraftMode ? "ON" : "OFF"); | |
+ | |
+ printf("@PJL SET JOBATTR=\"@IREC=OFF\"\n"); | |
+ | |
+ printf("@PJL SET JOBATTR=\"@TRAP=%s\"\n", | |
+ color && Trapping ? "ON" : "OFF"); | |
+ | |
+ // "ON" only if 'Image Enhancement' option is enabled in original Xerox's driver. | |
+ printf("@PJL SET RET=%s\n", "OFF"); | |
+ | |
+ printf( | |
+ "@PJL SET JOBATTR=\"@TDFT=0\"\n" | |
+ "@PJL SET JOBATTR=\"@GDFT=0\"\n" | |
+ "@PJL SET JOBATTR=\"@IDFT=0\"\n" | |
+ "@PJL SET JOBATTR=\"@NLPP=1\"\n" | |
+ "@PJL SET JOBATTR=\"@HOAD=IC0A809\"\n" | |
+ ); | |
+ | |
+ printf("@PJL SET JOBATTR=\"@JOAU=%s\"\n", Username ? Username : ""); | |
+ printf("@PJL SET JOBATTR=\"@CNAM=%s\"\n", cname); | |
+ | |
+ printf( | |
+ "@PJL SET OUTBIN=FACEDOWN\n" | |
+ "@PJL SET JOBATTR=\"@PODR=NORMAL\"\n" | |
+ "@PJL SET SLIPSHEET=OFF\n" | |
+ "@PJL SET PAPERDIRECTION=SEF\n" | |
+ "@PJL SET RESOLUTION=600\n" | |
+ "@PJL SET BITSPERPIXEL=8\n" | |
+ "@PJL SET JOBATTR=\"@DRDM=RASTER\"\n" | |
+ ); | |
+ | |
+ doc_type_id = DocType == 0 ? 0 : DocType - 1; | |
+ | |
+ if (color) { | |
+ for (i = 0; i < 6; i++) { | |
+ printf("@PJL SET JOBATTR=\"@%c%s=%d\"\n", | |
+ doc_type_jobattr_prefix[i % 3], | |
+ doc_type_jobattr_cprucr[i / 3], | |
+ doc_type_index[doc_type_id].jobattr.color); | |
+ } | |
+ } | |
+ | |
+ if (Screen == 0) { | |
+ s_doc_type_jobattr = &doc_type_index[doc_type_id].jobattr; | |
+ } else { | |
+ s_doc_type_jobattr = &screen_jobattr_index[Screen - 1]; | |
+ } | |
+ doc_type_jobattr = color ? | |
+ s_doc_type_jobattr->color : s_doc_type_jobattr->mono; | |
+ for (i = 0; i < 6; i++) { | |
+ printf("@PJL SET JOBATTR=\"@%c%s=%d\"\n", | |
+ doc_type_jobattr_prefix[i % 3], | |
+ doc_type_jobattr_trcscr[i / 3], | |
+ doc_type_jobattr); | |
+ } | |
+ | |
+ if (!color) { | |
+ printf("@PJL SET JOBATTR=\"@PBLK=OFF\"\n"); | |
+ } | |
+ | |
+ printf("@PJL SET JOBATTR=\"@BANR=DEVICE\"\n"); | |
+ | |
+ if (doc_type_id == DOC_NONE) { | |
+ printf("@PJL SET JOBATTR=\"@FCMS=ON\"\n"); | |
+ } | |
+ | |
+ printf("@PJL ENTER LANGUAGE=HBPL\n"); | |
+ | |
fwrite (reca, 1, sizeof reca, stdout); | |
} | |
@@ -401,11 +579,14 @@ encode_page(int color, int width, int height, char *image) | |
int paper = 510, hsel = 0, off = 0, bit = 0, stat = 0; | |
int margin = width-96; | |
- for (i = 0; i < sizeof papers / sizeof *papers; i++) | |
- if (abs(width-papers[i+1]) < 36 && abs(height-papers[i+2]) < 36) | |
+ for (i = 0; i < sizeof papers / sizeof *papers; i+=3) { | |
+ if (abs(width-papers[i+1]) < 36 && abs(height-papers[i+2]) < 36) { | |
paper = papers[i]; | |
+ break; | |
+ } | |
+ } | |
if (!MediaCode) | |
- MediaCode = paper & 1 ? 6 : 1; | |
+ MediaCode = paper & 1 ? 24 : 1; | |
if (!pagenum) | |
start_doc(color); | |
head[12] = paper >> 1; | |
@@ -532,6 +713,421 @@ encode_page(int color, int width, int height, char *image) | |
#undef BP | |
#undef put_token | |
+#define CLUT_BLK0_OFFSET 0x374 | |
+#define CLUT_OFFSET 0x308 | |
+#define CLUT_SIZE (17 * 17 * 17 * 4) | |
+#define CLUT_BLK_SIZE ((CLUT_OFFSET) + (CLUT_SIZE)) | |
+#define FILE_CLUT_OFFSET(i) ((CLUT_BLK0_OFFSET) + (CLUT_BLK_SIZE) * (i) + (CLUT_OFFSET)) | |
+ | |
+#define CLUT_X_FACT (1 * 4) | |
+#define CLUT_Y_FACT (17 * 4) | |
+#define CLUT_Z_FACT (17 * 17 * 4) | |
+ | |
+#define RGB_TO_GRAY(r, g, b) ((1229 * (r) + 2417 * (g) + 451 * (b)) >> 12) | |
+ | |
+unsigned char* | |
+load_clut(const int clut_id, const char *clut_fname) | |
+{ | |
+ unsigned char *clut; | |
+ FILE *clut_fp; | |
+ | |
+ if ((clut = malloc(CLUT_SIZE * sizeof(char))) == NULL) { | |
+ error(1, "Can't allocate memory for CLUT\n"); | |
+ } | |
+ | |
+ if (!(clut_fp = fopen(clut_fname, "r"))) { | |
+ error(1, "Can't open '%s' for reading\n", clut_fname); | |
+ } | |
+ | |
+ if (fseek(clut_fp, FILE_CLUT_OFFSET(clut_id), SEEK_SET) != 0 | |
+ || fread(clut, sizeof(char), CLUT_SIZE, clut_fp) < CLUT_SIZE) { | |
+ fclose(clut_fp); | |
+ error(1, "Can't read CLUT #%d from '%s'\n", clut_id, clut_fname); | |
+ } | |
+ | |
+ fclose(clut_fp); | |
+ | |
+ return clut; | |
+} | |
+ | |
+// Borrowed from Little Color Management System, http://www.littlecms.com | |
+// Copyright (c) 1998-2012 Marti Maria Saguer | |
+// Licensed under the MIT license | |
+// http://opensource.org/licenses/mit-license.php | |
+ | |
+// Tetrahedral interpolation, using Sakamoto algorithm. | |
+void | |
+rgb_to_kcmy(const unsigned char clut[], unsigned char kcmy[], const unsigned char rgb[]) | |
+{ | |
+ int i; | |
+ int rx, ry, rz; | |
+ int x0, y0, z0; | |
+ int x1, y1, z1; | |
+ const unsigned char *plane; | |
+ int c0, c1, c2, c3; | |
+ | |
+ rx = rgb[0] & 0xf; ry = rgb[1] & 0xf; rz = rgb[2] & 0xf; | |
+ | |
+ if (rgb[0] == 255) { | |
+ x0 = CLUT_X_FACT << 4; x1 = 0; | |
+ } else { | |
+ x0 = (rgb[0] >> 4) * (x1 = CLUT_X_FACT); | |
+ } | |
+ | |
+ if (rgb[1] == 255) { | |
+ y0 = CLUT_Y_FACT << 4; y1 = 0; | |
+ } else { | |
+ y0 = (rgb[1] >> 4) * (y1 = CLUT_Y_FACT); | |
+ } | |
+ | |
+ if (rgb[2] == 255) { | |
+ z0 = CLUT_Z_FACT << 4; z1 = 0; | |
+ } else { | |
+ z0 = (rgb[2] >> 4) * (z1 = CLUT_Z_FACT); | |
+ } | |
+ | |
+ clut = &clut[x0 + y0 + z0]; | |
+ | |
+ if (rx >= ry) { | |
+ if (ry >= rz) { | |
+ y1 += x1; | |
+ z1 += y1; | |
+ for (i = 0; i < 4; i++) { | |
+ plane = &clut[(i - 1) & 3]; // in KCMY order | |
+ c1 = plane[x1]; | |
+ c2 = plane[y1]; | |
+ c3 = plane[z1]; | |
+ c0 = plane[0]; | |
+ c3 -= c2; | |
+ c2 -= c1; | |
+ c1 -= c0; | |
+ kcmy[i] = c0 + ((c1 * rx + c2 * ry + c3 * rz) >> 4); | |
+ } | |
+ } else if (rz >= rx) { | |
+ x1 += z1; | |
+ y1 += x1; | |
+ for (i = 0; i < 4; i++) { | |
+ plane = &clut[(i - 1) & 3]; | |
+ c1 = plane[x1]; | |
+ c2 = plane[y1]; | |
+ c3 = plane[z1]; | |
+ c0 = plane[0]; | |
+ c2 -= c1; | |
+ c1 -= c3; | |
+ c3 -= c0; | |
+ kcmy[i] = c0 + ((c1 * rx + c2 * ry + c3 * rz) >> 4); | |
+ } | |
+ } else { | |
+ z1 += x1; | |
+ y1 += z1; | |
+ for (i = 0; i < 4; i++) { | |
+ plane = &clut[(i - 1) & 3]; | |
+ c1 = plane[x1]; | |
+ c2 = plane[y1]; | |
+ c3 = plane[z1]; | |
+ c0 = plane[0]; | |
+ c2 -= c3; | |
+ c3 -= c1; | |
+ c1 -= c0; | |
+ kcmy[i] = c0 + ((c1 * rx + c2 * ry + c3 * rz) >> 4); | |
+ } | |
+ } | |
+ } else { | |
+ if (rx >= rz) { | |
+ x1 += y1; | |
+ z1 += x1; | |
+ for (i = 0; i < 4; i++) { | |
+ plane = &clut[(i - 1) & 3]; | |
+ c1 = plane[x1]; | |
+ c2 = plane[y1]; | |
+ c3 = plane[z1]; | |
+ c0 = plane[0]; | |
+ c3 -= c1; | |
+ c1 -= c2; | |
+ c2 -= c0; | |
+ kcmy[i] = c0 + ((c1 * rx + c2 * ry + c3 * rz) >> 4); | |
+ } | |
+ } else if (ry >= rz) { | |
+ z1 += y1; | |
+ x1 += z1; | |
+ for (i = 0; i < 4; i++) { | |
+ plane = &clut[(i - 1) & 3]; | |
+ c1 = plane[x1]; | |
+ c2 = plane[y1]; | |
+ c3 = plane[z1]; | |
+ c0 = plane[0]; | |
+ c1 -= c3; | |
+ c3 -= c2; | |
+ c2 -= c0; | |
+ kcmy[i] = c0 + ((c1 * rx + c2 * ry + c3 * rz) >> 4); | |
+ } | |
+ } else { | |
+ y1 += z1; | |
+ x1 += y1; | |
+ for (i = 0; i < 4; i++) { | |
+ plane = &clut[(i - 1) & 3]; | |
+ c1 = plane[x1]; | |
+ c2 = plane[y1]; | |
+ c3 = plane[z1]; | |
+ c0 = plane[0]; | |
+ c1 -= c2; | |
+ c2 -= c3; | |
+ c3 -= c0; | |
+ kcmy[i] = c0 + ((c1 * rx + c2 * ry + c3 * rz) >> 4); | |
+ } | |
+ } | |
+ } | |
+ | |
+ return; | |
+} | |
+ | |
+enum proc_mode { | |
+ PROC_BITMAP, | |
+ PROC_GRAY, | |
+ PROC_RGB_NOADJ, | |
+ PROC_RGB_ADJ_COLOR, | |
+ PROC_RGB_ADJ_COLOR_NONE, | |
+ PROC_RGB_ADJ_COLOR_DRAFT, | |
+ PROC_RGB_ADJ_COLOR_NONE_DRAFT, | |
+ PROC_RGB_ADJ_MONO, | |
+ PROC_RGB_ADJ_MONO_DRAFT, | |
+ PROC_CMYK | |
+}; | |
+ | |
+enum margin_pos { | |
+ LEFT, | |
+ TOP, | |
+ RIGHT, | |
+ BOTTOM, | |
+}; | |
+ | |
+static unsigned char trc_rgb_color_std[] = { | |
+ 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 2, 3, 3, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14, | |
+ 15, 16, 18, 19, 20, 21, 22, 23, 25, 26, 27, 28, 29, 31, 32, 33, 34, 35, | |
+ 36, 37, 38, 40, 41, 42, 43, 44, 45, 46, 47, 48, 50, 51, 52, 53, 54, 55, | |
+ 56, 57, 58, 59, 60, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 74, 75, | |
+ 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 90, 91, 92, 93, 94, | |
+ 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, | |
+ 110, 111, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, | |
+ 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, | |
+ 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, | |
+ 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, | |
+ 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, | |
+ 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, | |
+ 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, | |
+ 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, | |
+ 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, | |
+ 237, 238, 239, 240, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, | |
+ 250, 251, 252, 253, 254, 255 | |
+}; | |
+ | |
+// Identity transformation | |
+static unsigned char trc_rgb_color_none[] = { | |
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, | |
+ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, | |
+ 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, | |
+ 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, | |
+ 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, | |
+ 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, | |
+ 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, | |
+ 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, | |
+ 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, | |
+ 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, | |
+ 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, | |
+ 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, | |
+ 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, | |
+ 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, | |
+ 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, | |
+ 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, | |
+ 248, 249, 250, 251, 252, 253, 254, 255 | |
+}; | |
+ | |
+static unsigned char trc_rgb_gray_std[] = { | |
+ 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 4, 6, 7, 10, 12, 13, 15, 16, 19, 20, | |
+ 23, 23, 26, 27, 28, 31, 32, 34, 35, 36, 38, 40, 41, 43, 44, 45, 46, 48, | |
+ 50, 51, 52, 54, 55, 56, 57, 59, 61, 62, 63, 64, 66, 67, 68, 69, 70, 71, | |
+ 74, 75, 76, 77, 78, 79, 80, 81, 83, 84, 85, 86, 87, 88, 90, 91, 92, 93, | |
+ 94, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, | |
+ 110, 111, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, | |
+ 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, | |
+ 139, 140, 141, 142, 143, 144, 145, 145, 146, 147, 148, 149, 150, 151, | |
+ 152, 153, 154, 155, 156, 157, 158, 159, 159, 160, 161, 162, 163, 164, | |
+ 165, 166, 167, 168, 169, 169, 170, 171, 172, 173, 174, 175, 176, 177, | |
+ 178, 178, 179, 180, 181, 182, 183, 184, 185, 185, 186, 187, 188, 189, | |
+ 190, 191, 192, 192, 193, 194, 195, 196, 197, 198, 198, 199, 200, 201, | |
+ 202, 203, 204, 204, 205, 206, 207, 208, 209, 209, 210, 211, 212, 213, | |
+ 214, 215, 215, 216, 217, 218, 219, 220, 220, 221, 222, 223, 224, 225, | |
+ 225, 226, 227, 228, 229, 229, 230, 231, 232, 233, 234, 234, 235, 236, | |
+ 237, 238, 238, 239, 240, 240, 241, 241, 242, 243, 244, 245, 245, 246, | |
+ 247, 248, 249, 249, 250, 251, 252, 253, 253, 254, 255 | |
+}; | |
+ | |
+static unsigned char trc_rgb_gray_none[] = { | |
+ 0, 1, 1, 2, 2, 3, 4, 6, 7, 8, 10, 11, 13, 15, 16, 18, 20, 21, 23, 24, | |
+ 26, 27, 29, 30, 32, 33, 34, 36, 37, 39, 40, 41, 43, 44, 45, 47, 48, 49, | |
+ 50, 52, 53, 54, 55, 57, 58, 59, 60, 62, 63, 64, 65, 66, 68, 69, 70, 71, | |
+ 72, 73, 75, 76, 77, 78, 79, 80, 81, 82, 84, 85, 86, 87, 88, 89, 90, 91, | |
+ 92, 93, 94, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, | |
+ 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, | |
+ 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, | |
+ 137, 138, 139, 140, 141, 142, 143, 144, 144, 145, 146, 147, 148, 149, | |
+ 150, 151, 152, 153, 154, 155, 156, 157, 158, 158, 159, 160, 161, 162, | |
+ 163, 164, 165, 166, 167, 168, 168, 169, 170, 171, 172, 173, 174, 175, | |
+ 176, 177, 177, 178, 179, 180, 181, 182, 183, 184, 184, 185, 186, 187, | |
+ 188, 189, 190, 191, 191, 192, 193, 194, 195, 196, 197, 197, 198, 199, | |
+ 200, 201, 202, 203, 203, 204, 205, 206, 207, 208, 208, 209, 210, 211, | |
+ 212, 213, 214, 214, 215, 216, 217, 218, 219, 219, 220, 221, 222, 223, | |
+ 224, 224, 225, 226, 227, 228, 228, 229, 230, 231, 232, 233, 233, 234, | |
+ 235, 236, 237, 237, 238, 239, 240, 241, 241, 242, 243, 244, 245, 245, | |
+ 246, 247, 248, 249, 249, 250, 251, 252, 253, 253, 254, 255 | |
+}; | |
+ | |
+static unsigned char trc_draft[] = { | |
+ 0, 0, 1, 2, 2, 3, 4, 4, 5, 6, 7, 7, 8, 9, 9, 10, 11, 11, 12, 13, 14, 14, | |
+ 15, 16, 16, 17, 18, 18, 19, 20, 21, 21, 22, 23, 23, 24, 25, 25, 26, 27, | |
+ 28, 28, 29, 30, 30, 31, 32, 32, 33, 34, 35, 35, 36, 37, 37, 38, 39, 39, | |
+ 40, 41, 42, 42, 43, 44, 44, 45, 46, 46, 47, 48, 49, 49, 50, 51, 51, 52, | |
+ 53, 53, 54, 55, 56, 56, 57, 58, 58, 59, 60, 60, 61, 62, 62, 63, 64, 65, | |
+ 65, 66, 67, 67, 68, 69, 70, 70, 71, 72, 72, 73, 74, 74, 75, 76, 77, 77, | |
+ 78, 79, 79, 80, 81, 81, 82, 83, 84, 84, 85, 86, 86, 87, 88, 88, 89, 90, | |
+ 91, 91, 92, 93, 93, 94, 95, 95, 96, 97, 98, 98, 99, 100, 100, 101, 102, | |
+ 102, 103, 104, 105, 105, 106, 107, 107, 108, 109, 109, 110, 111, 112, | |
+ 112, 113, 114, 114, 115, 116, 116, 117, 118, 118, 119, 120, 121, 121, | |
+ 122, 123, 123, 124, 125, 125, 126, 127, 128, 128, 129, 130, 130, 131, | |
+ 132, 133, 133, 134, 135, 135, 136, 137, 137, 138, 139, 140, 140, 141, | |
+ 142, 142, 143, 144, 144, 145, 146, 147, 147, 148, 149, 149, 150, 151, | |
+ 151, 152, 153, 154, 154, 155, 156, 156, 157, 158, 158, 159, 160, 161, | |
+ 161, 162, 163, 163, 164, 165, 165, 166, 167, 168, 168, 169, 170, 170, | |
+ 171, 172, 172, 173, 174, 175, 175, 176, 177, 177, 178 | |
+}; | |
+ | |
+void | |
+detect_rgb_content(unsigned char *const image, | |
+ const int wide, const int high, const int margins[4], | |
+ int *is_color, int *is_blank) | |
+{ | |
+ const int deep = 3; | |
+ const int byte = wide * deep; | |
+ int i, m[4]; | |
+ int start_row, end_row; | |
+ int start_col, end_col; | |
+ int start_col_off, end_col_off; | |
+ unsigned char *rowp, *end_rowp, *startp, *endp, *p; | |
+ int color_detected = 0; | |
+ int gray_detected = 0; | |
+ | |
+ for (i = 0; i < 4; i++) { | |
+ m[i] = margins[i] < 0 ? 0 : margins[i]; | |
+ } | |
+ | |
+ start_row = m[TOP]; | |
+ end_row = high - m[BOTTOM]; | |
+ start_col = m[LEFT]; | |
+ end_col = wide - m[RIGHT]; | |
+ | |
+ if (start_row < end_row && start_col < end_col) { | |
+ end_rowp = image + (end_row - 1) * byte; | |
+ start_col_off = start_col * deep; | |
+ end_col_off = (end_col - 1) * deep; | |
+ | |
+ for (rowp = image + start_row * byte;; rowp += byte) { | |
+ startp = rowp + start_col_off; | |
+ endp = rowp + end_col_off; | |
+ | |
+ for (p = startp;; p += deep) { | |
+ if (p[0] != p[1] || p[1] != p[2]) { | |
+ color_detected = 1; | |
+ goto end_search; | |
+ } else if (p[0] != 255) { | |
+ gray_detected = 1; | |
+ } | |
+ if (p == endp) { | |
+ break; | |
+ } | |
+ } | |
+ if (rowp == end_rowp) { | |
+ break; | |
+ } | |
+ } | |
+ } | |
+ | |
+end_search: *is_color = color_detected; | |
+ *is_blank = !(color_detected || gray_detected); | |
+ | |
+ return; | |
+} | |
+ | |
+void | |
+apply_trapping(unsigned char *image, int wide, int high, const int margins[4]) | |
+{ | |
+ int byte; | |
+ int i, j, k, m[4], n[24]; | |
+ int skip_mlr, eff_byte; | |
+ unsigned char *p, *row_endp, *img_endp, *np; | |
+ | |
+ for (i = 0; i < 4; i++) { | |
+ m[i] = margins[i] > 1 ? margins[i] : 2; | |
+ } | |
+ | |
+ if (m[TOP] < high - m[BOTTOM] && m[LEFT] < wide - m[RIGHT]) { | |
+ | |
+ byte = wide * 4; | |
+ | |
+ // Array `n` contains relative offsets | |
+ // of the neighbor pixels in a 5x5 window. | |
+ // | |
+ // +----+----+----+----+----+ | |
+ // | 0 | 1 | 2 | 3 | 4 | | |
+ // +----+----+----+----+----+ | |
+ // | 5 | 6 | 7 | 8 | 9 | | |
+ // +----+----+---------+----+ | |
+ // | 10 | 11 | p | 12 | 13 | | |
+ // +----+----+---------+----+ | |
+ // | 14 | 15 | 16 | 17 | 18 | | |
+ // +----+----+----+----+----+ | |
+ // | 19 | 20 | 21 | 22 | 23 | | |
+ // +----+----+----+----+----+ | |
+ | |
+ for (k = 0, i = -2; i < 3; i++) { | |
+ for (j = -2; j < 3; j++) { | |
+ if (i || j) { | |
+ n[k++] = byte * i + 4 * j; | |
+ } | |
+ } | |
+ } | |
+ | |
+ p = image + m[TOP] * byte + m[LEFT] * 4; | |
+ img_endp = image + (high - m[BOTTOM]) * byte - m[RIGHT] * 4; | |
+ skip_mlr = (m[LEFT] + m[RIGHT]) * 4; | |
+ eff_byte = byte - skip_mlr; | |
+ row_endp = p + eff_byte; | |
+ | |
+ for (; p != img_endp; p += 4) { | |
+ if (p == row_endp) { | |
+ p += skip_mlr; | |
+ row_endp = p + eff_byte; | |
+ } | |
+ | |
+ if (p[0] < 204) { | |
+ continue; | |
+ } | |
+ | |
+ for (i = 0; i < 24; i++) { | |
+ np = p + n[i]; | |
+ if (np[0] < 204) { | |
+ for (j = 1; j < 4; j++) { | |
+ if (p[j] < np[j]) { | |
+ p[j] = np[j]; | |
+ } | |
+ } | |
+ } | |
+ } | |
+ } | |
+ } | |
+ | |
+ return; | |
+} | |
+ | |
int | |
getint(FILE *fp) | |
{ | |
@@ -557,6 +1153,15 @@ do_file(FILE *fp) | |
int wide, deep, byte, row, col, i, k; | |
char tupl[128], line[128]; | |
unsigned char *image, *sp, *dp; | |
+ int buf_size, ibuf_size; | |
+ unsigned char *sstart, *dstart; | |
+ int doc_type_id = 0; | |
+ const struct doc_type *s_doc_type; | |
+ unsigned char *clut = NULL; | |
+ enum proc_mode proc_mode; | |
+ unsigned char *trc = trc_rgb_color_none; | |
+ int is_color = 0; | |
+ int is_blank = 0; | |
while ((type = fgetc(fp)) != EOF) | |
{ | |
@@ -566,12 +1171,37 @@ do_file(FILE *fp) | |
{ | |
case '4': | |
deep = 1 + (ideep = 0); | |
+ proc_mode = PROC_BITMAP; | |
goto six; | |
case '5': | |
deep = ideep = 1; | |
+ proc_mode = PROC_GRAY; | |
goto six; | |
case '6': | |
- deep = 1 + (ideep = 3); | |
+ if (DocType != 0) { | |
+ doc_type_id = DocType - 1; | |
+ if (OutputColor) { | |
+ deep = 1 + (ideep = 3); | |
+ if (doc_type_id == DOC_NONE) { | |
+ proc_mode = DraftMode ? | |
+ PROC_RGB_ADJ_COLOR_NONE_DRAFT : PROC_RGB_ADJ_COLOR_NONE; | |
+ } else { | |
+ if (!ClutFilePath) { | |
+ error(1, "CLUT file path (option -l) is not set.\n"); | |
+ } | |
+ proc_mode = DraftMode ? | |
+ PROC_RGB_ADJ_COLOR_DRAFT : PROC_RGB_ADJ_COLOR; | |
+ } | |
+ } else { | |
+ ideep = 3; | |
+ deep = 1; | |
+ proc_mode = DraftMode ? | |
+ PROC_RGB_ADJ_MONO_DRAFT : PROC_RGB_ADJ_MONO; | |
+ } | |
+ } else { | |
+ deep = 1 + (ideep = 3); | |
+ proc_mode = PROC_RGB_NOADJ; | |
+ } | |
six: iwide = getint(fp); | |
ihigh = getint(fp); | |
imax = type == '4' ? 255 : getint(fp); | |
@@ -592,6 +1222,7 @@ six: iwide = getint(fp); | |
strcpy (tupl, line + 9); | |
} while (strcmp(line, "ENDHDR\n")); | |
if (ideep != 4 || strcmp(tupl, "CMYK\n")) goto fail; | |
+ proc_mode = PROC_CMYK; | |
break; | |
default: | |
goto fail; | |
@@ -603,37 +1234,118 @@ six: iwide = getint(fp); | |
else | |
ibyte = wide >> 3; | |
byte = wide * deep; | |
- image = calloc (ihigh+2, byte); | |
+ | |
+ buf_size = (ibyte > byte ? ibyte : byte) * ihigh + byte * 2; | |
+ | |
+ if ((image = malloc(buf_size)) == NULL) { | |
+ error(1, "Can't allocate memory for page buffer\n"); | |
+ } | |
+ | |
+ dstart = image + byte; | |
+ ibuf_size = ibyte * ihigh; | |
+ sstart = image + (buf_size - ibuf_size); | |
+ | |
+ if (fread (sstart, ibuf_size, 1, fp) != 1) { | |
+ error(1, "Error reading image data\n"); | |
+ } | |
+ | |
+ if (ideep == 3 && DocType != 0) { | |
+ detect_rgb_content(sstart, iwide, ihigh, Clip, | |
+ &is_color, &is_blank); | |
+ | |
+ if (doc_type_id == DOC_NONE) { | |
+ trc = is_color ? trc_rgb_color_none : trc_rgb_gray_none; | |
+ } else { | |
+ s_doc_type = &doc_type_index[doc_type_id]; | |
+ clut = load_clut(s_doc_type->clut_id, ClutFilePath); | |
+ trc = is_color ? trc_rgb_color_std : trc_rgb_gray_std; | |
+ } | |
+ } | |
+ | |
for (row = 1; row <= ihigh; row++) | |
{ | |
- i = fread (image, ibyte, 1, fp); | |
- sp = image; | |
- dp = image + row*byte; | |
+ sp = sstart; | |
+ dp = dstart; | |
for (col = 0; col < iwide; col++) | |
{ | |
dp += deep; | |
- switch (ideep) | |
+ switch (proc_mode) | |
{ | |
- case 0: | |
- *dp = ((image[col >> 3] >> (~col & 7)) & 1) * 255; | |
+ case PROC_BITMAP: | |
+ *dp = ((sp[col >> 3] >> (~col & 7)) & 1) * 255; | |
break; | |
- case 1: | |
+ case PROC_GRAY: | |
*dp = ~*sp; | |
break; | |
- case 3: | |
+ case PROC_RGB_NOADJ: | |
for (k = sp[2], i = 0; i < 2; i++) | |
if (k < sp[i]) k = sp[i]; | |
*dp = ~k; | |
for (i = 0; i < 3; i++) | |
dp[i+1] = k ? (k - sp[i]) * 255 / k : 255; | |
break; | |
- case 4: | |
+ case PROC_RGB_ADJ_COLOR: | |
+ for (i = 0; i < 3; i++) { | |
+ sp[i] = trc[sp[i]]; | |
+ } | |
+ rgb_to_kcmy(clut, dp, sp); | |
+ break; | |
+ case PROC_RGB_ADJ_COLOR_NONE: | |
+ for (i = 0; i < 3; i++) { | |
+ sp[i] = trc[sp[i]]; | |
+ } | |
+ for (k = sp[2], i = 0; i < 2; i++) | |
+ if (k < sp[i]) k = sp[i]; | |
+ *dp = ~k; | |
+ for (i = 0; i < 3; i++) | |
+ dp[i+1] = k - sp[i]; | |
+ break; | |
+ case PROC_RGB_ADJ_COLOR_DRAFT: | |
+ for (i = 0; i < 3; i++) { | |
+ sp[i] = trc[sp[i]]; | |
+ } | |
+ rgb_to_kcmy(clut, dp, sp); | |
+ for (i = 0; i < 4; i++) { | |
+ dp[i] = trc_draft[dp[i]]; | |
+ } | |
+ break; | |
+ case PROC_RGB_ADJ_COLOR_NONE_DRAFT: | |
+ for (i = 0; i < 3; i++) { | |
+ sp[i] = trc[sp[i]]; | |
+ } | |
+ for (k = sp[2], i = 0; i < 2; i++) | |
+ if (k < sp[i]) k = sp[i]; | |
+ *dp = ~k; | |
+ for (i = 0; i < 3; i++) | |
+ dp[i+1] = k - sp[i]; | |
+ for (i = 0; i < 4; i++) { | |
+ dp[i] = trc_draft[dp[i]]; | |
+ } | |
+ break; | |
+ case PROC_RGB_ADJ_MONO: | |
+ for (i = 0; i < 3; i++) { | |
+ sp[i] = trc[sp[i]]; | |
+ } | |
+ *dp = ~RGB_TO_GRAY(sp[0], sp[1], sp[2]); | |
+ break; | |
+ case PROC_RGB_ADJ_MONO_DRAFT: | |
+ for (i = 0; i < 3; i++) { | |
+ sp[i] = trc[sp[i]]; | |
+ } | |
+ *dp = ~RGB_TO_GRAY(sp[0], sp[1], sp[2]); | |
+ for (i = 0; i < 4; i++) { | |
+ dp[i] = trc_draft[dp[i]]; | |
+ } | |
+ break; | |
+ case PROC_CMYK: | |
for (i=0; i < 4; i++) | |
dp[i] = sp[((i-1) & 3)]; | |
break; | |
} | |
sp += ideep; | |
} | |
+ sstart += ibyte; | |
+ dstart += byte; | |
for (i = 0; i < deep*Clip[0]; i++) | |
image[row*byte + deep+i] = 0; | |
for (i = deep*(iwide-Clip[2]); i < byte; i++) | |
@@ -641,8 +1353,14 @@ six: iwide = getint(fp); | |
} | |
memset(image+deep, 0, byte*(Clip[1]+1)); | |
memset(image+deep + byte*(ihigh-Clip[3]+1), 0, byte*Clip[3]); | |
+ if (deep == 4 && Trapping) { | |
+ apply_trapping(image + byte + deep, iwide, ihigh, Clip); | |
+ } | |
encode_page(deep > 1, iwide, ihigh, (char *) image); | |
free(image); | |
+ if (ideep == 3 && DocType != 0 && doc_type_id != DOC_NONE) { | |
+ free(clut); | |
+ } | |
} | |
return; | |
fail: | |
@@ -654,15 +1372,61 @@ main(int argc, char *argv[]) | |
{ | |
int c, i; | |
- while ( (c = getopt(argc, argv, "m:u:J:U:V")) != EOF) | |
+ while ( (c = getopt(argc, argv, "a:ci:l:m:s:tu:J:TU:V")) != EOF) | |
switch (c) | |
{ | |
- case 'm': MediaCode = atoi(optarg); break; | |
+ case 'a': | |
+ for (i = 0; i < 12 && optarg[i]; i++) { | |
+ if (optarg[i] >= '0' && optarg[i] <= '6') { | |
+ ColorBalance[i] = optarg[i]; | |
+ } else { | |
+ error(1, "Color balance values must be in range 0..6\n"); | |
+ } | |
+ } | |
+ break; | |
+ case 'c': | |
+ OutputColor = 1; | |
+ break; | |
+ case 'i': | |
+ if (sscanf(optarg, "%d", &DocType) != 1 | |
+ || DocType < 0 || DocType > 6 | |
+ ) { | |
+ error(1, "Document type code must be in range 1..6.\n"); | |
+ } | |
+ break; | |
+ case 'l': if (optarg[0]) ClutFilePath = optarg; break; | |
+ case 'm': | |
+ if (sscanf(optarg, "%d", &MediaCode) != 1 | |
+ || MediaCode < 1 || MediaCode > 24 | |
+ ) { | |
+ error(1, "Media code must be in range 1..24.\n"); | |
+ } | |
+ break; | |
+ case 'n': | |
+ if (sscanf(optarg, "%d", &NumCopies) != 1 | |
+ || NumCopies < 1 || NumCopies > 24 | |
+ ) { | |
+ error(1, "Number of copies must be in range 1..100.\n"); | |
+ } | |
+ break; | |
+ case 's': | |
+ if (sscanf(optarg, "%d", &Screen) != 1 | |
+ || Screen < 0 || Screen > 3 | |
+ ) { | |
+ error(1, "Screen type code must be in range 0..3.\n"); | |
+ } | |
+ break; | |
+ case 't': | |
+ DraftMode = 1; | |
+ break; | |
case 'u': if (sscanf(optarg, "%d,%d,%d,%d", | |
Clip, Clip+1, Clip+2, Clip+3) != 4) | |
error(1, "Must specify four clipping margins!\n"); | |
break; | |
case 'J': if (optarg[0]) Filename = optarg; break; | |
+ case 'T': | |
+ Trapping = 1; | |
+ break; | |
case 'U': if (optarg[0]) Username = optarg; break; | |
case 'V': printf("%s\n", Version); return 0; | |
default: usage(); return 1; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
yeah, got the xerox driver working.
In the xerox ppd are some good examples how modify the ppd.