summaryrefslogtreecommitdiff
path: root/ghostscript-gdevcd8-fixes.patch
blob: 95815468aaf2cfb4d0d8a42fba81e54f7651854c (plain)
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
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
Fixes:
 - cdj850 and cdj1600 were broken, because of terminating *b command
   (by 'Y' or 'V' instead of 'y' or 'v'); now *b is terminated only
   for cdj880
 - do_gcr replaced whole black component by CMY (so everything was
   printed using colour ink!); do_gcr with NOBLACK looks strange,
   like somebody didn't know what he's doing... (see the "XXX" comments);
   now old, actual DOGCR is used, but NOBLACK can be enabled by -dUseBlack=0
   though

Jakub Bogusz <qboosh@pld-linux.org>
--- ghostscript-9.55.0/contrib/gdevcd8.c.orig	2021-09-27 09:44:02.000000000 +0200
+++ ghostscript-9.55.0/contrib/gdevcd8.c	2021-11-27 16:28:48.395077465 +0100
@@ -604,6 +604,7 @@ typedef struct gx_device_cdj850_s {
     StartRasterMode start_raster_mode;	/* output function to start raster mode */
     PrintNonBlankLines print_non_blank_lines;	/* output function to print a non blank line */
     TerminatePage terminate_page;	/* page termination output function */
+    int useblack;		/* use K compound */
 } gx_device_cdj850;
 
 typedef struct {
@@ -659,7 +660,7 @@ typedef struct {
     blackcorrect,\
     start_raster_mode,\
     print_non_blank_line,\
-    terminate_page\
+    terminate_page, 1\
 }
 
 #define cdj_1600_device(procs, dev_name, x_dpi, y_dpi, bpp, print_page, correction, quality, papertype, intensities,ptype,compression,mastergamma,gammavalc,gammavalm,gammavaly,gammavalk,blackcorrect,start_raster_mode,print_non_blank_line,terminate_page)\
@@ -678,7 +679,7 @@ typedef struct {
     blackcorrect,\
     start_raster_mode,\
     print_non_blank_line,\
-    terminate_page\
+    terminate_page, 1\
 }
 
 /* HP2200 and DNJ500 is a RGB printer */
@@ -698,7 +699,7 @@ typedef struct {
     blackcorrect,\
     start_raster_mode,\
     print_non_blank_line,\
-    terminate_page\
+    terminate_page, 1\
 }
 
 /*  Printer-specific functions.  Most printers are handled by the cdj850_xx()
@@ -1077,6 +1078,7 @@ cdj850_get_params(gx_device * pdev, gs_p
     if (code < 0 ||
         (code = param_write_int(plist, "Quality", &cdj850->quality)) < 0 ||
         (code = param_write_int(plist, "Papertype", &cdj850->papertype)) < 0 ||
+        (code = param_write_int(plist, "UseBlack", &cdj850->useblack)) < 0 ||
         (code = param_write_float(plist, "MasterGamma", &cdj850->gammavalc))
         < 0 ||
         (code = param_write_float(plist, "GammaValC", &cdj850->gammavalc)) <
@@ -1100,6 +1102,7 @@ cdj850_put_params(gx_device * pdev, gs_p
 {
     int quality = cdj850->quality;
     int papertype = cdj850->papertype;
+    int useblack = cdj850->useblack;
     float mastergamma = cdj850->mastergamma;
     float gammavalc = cdj850->gammavalc;
     float gammavalm = cdj850->gammavalm;
@@ -1112,6 +1115,7 @@ cdj850_put_params(gx_device * pdev, gs_p
     code = cdj_put_param_int(plist, "BitsPerPixel", &bpp, 1, 32, code);
     code = cdj_put_param_int(plist, "Quality", &quality, 0, 2, code);
     code = cdj_put_param_int(plist, "Papertype", &papertype, 0, 4, code);
+    code = cdj_put_param_int(plist, "UseBlack", &useblack, 0, 1, code);
     code = cdj_put_param_float(plist, "MasterGamma", &mastergamma, 0.1f, 9.0f, code);
     code = cdj_put_param_float(plist, "GammaValC", &gammavalc, 0.0f, 9.0f, code);
     code = cdj_put_param_float(plist, "GammaValM", &gammavalm, 0.0f, 9.0f, code);
@@ -1128,6 +1132,7 @@ cdj850_put_params(gx_device * pdev, gs_p
 
     cdj850->quality = quality;
     cdj850->papertype = papertype;
+    cdj850->useblack = useblack;
     cdj850->mastergamma = mastergamma;
     cdj850->gammavalc = gammavalc;
     cdj850->gammavalm = gammavalm;
@@ -1185,7 +1185,13 @@
                         gx_device_printer * pdev,
                         struct error_val_field *error_values);
 static int
-do_gcr(int bytecount, byte * inbyte, const byte kvalues[256],
+do_gcr_noblack(int bytecount, byte * inbyte, const byte kvalues[256],
+       const byte cvalues[256], const byte mvalues[256],
+       const byte yvalues[256], const int kcorrect[256],
+       word * inword);
+
+static int
+do_gcr_gcr(int bytecount, byte * inbyte, const byte kvalues[256],
        const byte cvalues[256], const byte mvalues[256],
        const byte yvalues[256], const int kcorrect[256],
        word * inword);
@@ -2045,7 +2056,10 @@ send_scan_lines(gx_device_printer * pdev
         }
         /* Skip blank lines if any */
         if (num_blank_lines > 0) {
+            if(cdj850->ptype == DJ880C)
             gp_fprintf(prn_stream, "\033*b%dY", num_blank_lines / (cdj850->yscal + 1));
+            else /* still in *b if not dj880 */
+                fprintf(prn_stream, "%dy", num_blank_lines / (cdj850->yscal + 1));
             memset(data_ptrs->plane_data[0][0], 0,
                    (misc_vars->plane_size * 2 * misc_vars->num_comps));
             memset(data_ptrs->plane_data_c[0][0], 0,
@@ -2055,7 +2069,10 @@ send_scan_lines(gx_device_printer * pdev
         /* all blank lines printed, now for the non-blank lines */
         if (cdj850->yscal && odd(lnum)) {
             /* output a blank black plane for odd lines */
+            if(cdj850->ptype == DJ880C)
             gp_fprintf(prn_stream, "\033*b0V");
+            else /* still in *b if not dj880 */
+                putc('v', prn_stream);
         }
         /* now output all non blank lines */
         while (lnum < lend && llen != 0) {
@@ -2081,9 +2098,11 @@ print_c9plane(gp_file * prn_stream, char
     int out_count = gdev_pcl_mode9compress(plane_size, curr, prev, out_data);
 
     /* and output the data */
-        gp_fprintf(prn_stream, "%d%c", out_count, plane_code);
     if (out_count > 0) {
+        gp_fprintf(prn_stream, "%d%c", out_count, plane_code);
         gp_fwrite(out_data, sizeof(byte), out_count, prn_stream);
+    } else { /* single plane_code is sufficient for cdj850 */
+        putc(plane_code, prn_stream);
     }
 }
 
@@ -2142,15 +2161,22 @@ cdj850_print_non_blank_lines(gx_device_p
     byte *dp = data_ptrs->data[misc_vars->scan + 2];
     int *ep = data_ptrs->errors[misc_vars->scan];
 
-    /* we need cmyk color separation befor all the rest, since
+    /* we need cmyk color separation before all the rest, since
        black may be contained in the color fields. This needs to
        be done on all pixel-rows, since even unused color-bytes
        might generate black */
 
+  if(cdj850->useblack) {
     misc_vars->is_color_data =
-        do_gcr(misc_vars->databuff_size, data_ptrs->data[misc_vars->scan],
+        do_gcr_gcr(misc_vars->databuff_size, data_ptrs->data[misc_vars->scan],
                gamma->k, gamma->c, gamma->m, gamma->y, gamma->correct,
                (word *) data_ptrs->data[misc_vars->scan]);
+  } else {
+    misc_vars->is_color_data =
+       do_gcr_noblack(misc_vars->databuff_size, data_ptrs->data[misc_vars->scan],
+              gamma->k, gamma->c, gamma->m, gamma->y, gamma->correct,
+              (word *) data_ptrs->data[misc_vars->scan]);
+  }
 
     /* dithering the black-plane */
     FSDlinebw(misc_vars->scan, misc_vars->plane_size,
@@ -2220,15 +2246,22 @@ cdj880_print_non_blank_lines(gx_device_p
     byte *dp = data_ptrs->data[misc_vars->scan + 2];
     int *ep = data_ptrs->errors[misc_vars->scan];
 
-    /* we need cmyk color separation befor all the rest, since
+    /* we need cmyk color separation before all the rest, since
        black may be contained in the color fields. This needs to
        be done on all pixel-rows, since even unused color-bytes
        might generate black */
 
+  if(cdj850->useblack) {
+    misc_vars->is_color_data =
+        do_gcr_gcr(misc_vars->databuff_size, data_ptrs->data[misc_vars->scan],
+               gamma->k, gamma->c, gamma->m, gamma->y, gamma->correct,
+               (word *) data_ptrs->data[misc_vars->scan]);
+  } else {
     misc_vars->is_color_data =
-        do_gcr(misc_vars->databuff_size, data_ptrs->data[misc_vars->scan],
+        do_gcr_noblack(misc_vars->databuff_size, data_ptrs->data[misc_vars->scan],
                gamma->k, gamma->c, gamma->m, gamma->y, gamma->correct,
                (word *) data_ptrs->data[misc_vars->scan]);
+  }
 
     /* dithering the black-plane */
     FSDlinebw(misc_vars->scan, misc_vars->plane_size,
@@ -2431,7 +2464,7 @@ do_black_correction(float kvalue, int kc
    do real color separation, here we try a real grey component
    replacement */
 static int
-do_gcr(int bytecount, byte * inbyte, const byte kvalues[256],
+do_gcr_noblack(int bytecount, byte * inbyte, const byte kvalues[256],
        const byte cvalues[256], const byte mvalues[256],
        const byte yvalues[256], const int kcorrect[256],
        word * inword)
@@ -2441,7 +2474,7 @@ do_gcr(int bytecount, byte * inbyte, con
   word last_color_value = 0;
   word *last_color;
 
-  /* initialise *last_color with a dummmy value */
+  /* initialise *last_color with a dummy value */
   last_color = &last_color_value;
   /* Grey component replacement */
   for (i = 0; i < bytecount; i += 4) {
@@ -2471,11 +2504,12 @@ do_gcr(int bytecount, byte * inbyte, con
       /* Test whether we 've already computet the value */
       if (*inword == last_color_value) {
         /* save a copy of the current color before it will be modified */
-        last_color_value = *inword;
+        last_color_value = *inword; /* NOP --q */
 /*	debug_print_string("\n", 1);*/
         /* copy the result of the old value onto the new position */
         *inword = *last_color;
       } else {
+        /* ??? ALL these NOBLACKs will be NOPs after the first NOBLACK! what are they for??? --q */
         /* save a copy of the current color before it will be modified */
         last_color_value = *inword;
   NOBLACK(cyan, magenta, yellow, black);
@@ -2513,6 +2547,7 @@ do_gcr(int bytecount, byte * inbyte, con
           debug_print_string(output, strlen(output));
         }
 #endif /* 0 */
+        /* XXX: how byte could be >255??? --q */
         if (   *cyan > 255)    *cyan = 255;
         if (*magenta > 255) *magenta = 255;
         if ( *yellow > 255)  *yellow = 255;
@@ -2520,6 +2555,96 @@ do_gcr(int bytecount, byte * inbyte, con
         *cyan = *(cvalues + *cyan);
         *magenta = *(mvalues + *magenta);
         *yellow = *(yvalues + *yellow);
+        last_color =  inword; /* save pointer */
+      }/* end current_color */
+    }			/* end of if c+m+y > 0 */
+    *black = *(kvalues + *black);
+    inword = inword + 1;
+  } /* end of for bytecount */
+  return is_color;
+}
+
+static int
+do_gcr_gcr(int bytecount, byte * inbyte, const byte kvalues[256],
+       const byte cvalues[256], const byte mvalues[256],
+       const byte yvalues[256], const int kcorrect[256],
+       word * inword)
+{
+  int i, ucr, kadd, is_color = 0;
+  float uca_fac;
+  byte *black, *cyan, *magenta, *yellow;
+  word last_color_value = 0;
+  word *last_color;
+
+  /* initialise *last_color with a dummy value */
+  last_color = &last_color_value;
+  /* Grey component replacement */
+  for (i = 0; i < bytecount; i += 4) {
+
+    /* Assign to black the current address of  inbyte */
+    black = inbyte++;
+    cyan = inbyte++;
+    magenta = inbyte++;
+    yellow = inbyte++;
+
+    if (*magenta + *yellow + *cyan > 0) {	/* if any color at all */
+
+#if 0
+      if ((*cyan > 0) && (*magenta > 0) && (*yellow > 0))
+      {
+        char output[255];
+        gs_sprintf(output, "%3d %3d %3d %3d - ", *cyan, *magenta, *yellow, *black);
+        debug_print_string(output, strlen(output));
+      }
+#endif /* 0 */
+
+      is_color = 1;
+
+      /* Test whether we 've already computet the value */
+      if (*inword == last_color_value) {
+/*	debug_print_string("\n", 1);*/
+        /* copy the result of the old value onto the new position */
+        *inword = *last_color;
+      } else {
+        /* save a copy of the current color before it will be modified */
+        last_color_value = *inword;
+        if ((*cyan >= *magenta)
+            && (*magenta >= *yellow)
+            && (*yellow > 0)) {	/* if any grey component */
+          DOGCR(cyan, magenta, yellow, black);
+        } else if ((*cyan >= *yellow)
+                   && (*yellow >= *magenta)
+                   && (*magenta > 0)) {
+          DOGCR(cyan, yellow, magenta, black);
+        } else if ((*yellow >= *magenta)
+                   && (*magenta >= *cyan)
+                   && (*cyan > 0)) {
+          DOGCR(yellow, magenta, cyan, black);
+        } else if ((*yellow >= *cyan)
+                   && (*cyan >= *magenta)
+                   && (*magenta > 0)) {
+          DOGCR(yellow, cyan, magenta, black);
+        } else if ((*magenta >= *yellow)
+                   && (*yellow >= *cyan)
+                   && (*cyan > 0)) {
+          DOGCR(magenta, yellow, cyan, black);
+        } else if ((*magenta >= *cyan)
+                   && (*cyan >= *yellow)
+                   && (*yellow > 0)) {
+          DOGCR(magenta, cyan, yellow, black);
+        } else {		/* do gamma only if no black */
+        }
+#if 0
+        if (ucr > 0)
+        {
+          char output[255];
+          gs_sprintf(output, "%3d %3d %3d %3d - %5d\n", *cyan, *magenta, *yellow, *black, ucr);
+          debug_print_string(output, strlen(output));
+        }
+#endif /* 0 */
+        *cyan = *(cvalues + *cyan);
+        *magenta = *(mvalues + *magenta);
+        *yellow = *(yvalues + *yellow);
         last_color =  inword; /* save pointer */
       }/* end current_color */
     }			/* end of if c+m+y > 0 */