summaryrefslogtreecommitdiff
path: root/libre/ghostscript-libre/ghostscript-cups-rgbw.patch
blob: f6ae2dae75de6927a97f7fb81a00f7e5158ab14a (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
diff -up ghostscript-9.04/cups/gdevcups.c.cups-rgbw ghostscript-9.04/cups/gdevcups.c
--- ghostscript-9.04/cups/gdevcups.c.cups-rgbw	2011-08-05 12:12:21.000000000 +0100
+++ ghostscript-9.04/cups/gdevcups.c	2011-08-22 10:54:24.614010581 +0100
@@ -225,6 +225,7 @@ typedef struct gx_device_cups_s
   unsigned short	EncodeLUT[gx_max_color_value + 1];/* RGB value to output color LUT */
   int			Density[CUPS_MAX_VALUE + 1];/* Density LUT */
   int			Matrix[3][3][CUPS_MAX_VALUE + 1];/* Color transform matrix LUT */
+  int                   user_icc;
   int                   cupsRasterVersion;
 
   /* Used by cups_put_params(): */
@@ -426,6 +427,7 @@ gx_device_cups	gs_cups_device =
   {0x00},                                  /* EncodeLUT */
   {0x00},                                  /* Density */
   {0x00},                                  /* Matrix */
+  0,
   3                                     /* cupsRasterVersion */
 };
 
@@ -1182,15 +1184,18 @@ cups_map_cmyk(gx_device *pdev,		/* I - D
 
     case CUPS_CSPACE_RGB :
     case CUPS_CSPACE_RGBW :
+        c0 = c + k;
+        c1 = m + k;
+        c2 = y + k;
         if (cups->header.cupsColorSpace == CUPS_CSPACE_RGBW) {
-	  c0 = c;
-	  c1 = m;
-	  c2 = y;
-	  c3 = k;
-	} else {
-	  c0 = c + k;
-	  c1 = m + k;
-	  c2 = y + k;
+	  if ((k >= frac_1 - 1) ||
+	      ((c0 >= frac_1) && (c1 >= frac_1) && (c2 >= frac_1))) {
+	    c0 = frac_1;
+	    c1 = frac_1;
+	    c2 = frac_1;
+	    c3 = frac_1;
+	  } else
+	    c3 = 0;
 	}
 
         if (c0 < 0)
@@ -1212,11 +1217,12 @@ cups_map_cmyk(gx_device *pdev,		/* I - D
 	out[2] = frac_1 - (frac)cups->Density[c2];
 
         if (cups->header.cupsColorSpace == CUPS_CSPACE_RGBW) {
-	  if (c3 < 0)
-	    c3 = 0;
-	  else if (c3 > frac_1)
-	    c3 = frac_1;
-	  out[3] = frac_1 - (frac)cups->Density[c3];
+	  if (c3 == 0)
+	    out[3] = frac_1;
+	  else if (c3 == frac_1)
+	    out[3] = 0;
+	  else
+	    out[3] = frac_1;
 	}
         break;
 
@@ -2034,10 +2040,15 @@ cups_map_color_rgb(gx_device      *pdev,
         * cups->DecodeLUT actually maps to RGBW, not CMYK...
 	*/
 
-        k = cups->DecodeLUT[c3];
-        c = cups->DecodeLUT[c0] + k - gx_max_color_value;
-        m = cups->DecodeLUT[c1] + k - gx_max_color_value;
-        y = cups->DecodeLUT[c2] + k - gx_max_color_value;
+        if (c3 == 0) {
+	  c = 0;
+	  m = 0;
+	  y = 0;
+	} else {
+	  c = cups->DecodeLUT[c0];
+	  m = cups->DecodeLUT[c1];
+	  y = cups->DecodeLUT[c2];
+	}
 
         if (c > gx_max_color_value)
 	  prgb[0] = gx_max_color_value;
@@ -2282,20 +2293,20 @@ cups_map_rgb_color(gx_device      *pdev,
           switch (cups->header.cupsBitsPerColor)
           {
             default :
-        	i = 0x0e;
+        	i = 0x00;
         	break;
             case 2 :
-        	i = 0xfc;
+        	i = 0x00;
         	break;
             case 4 :
-        	i = 0xfff0;
+        	i = 0x0000;
         	break;
             case 8 :
-        	i = 0xffffff00;
+        	i = 0x00000000;
         	break;
 #ifdef GX_COLOR_INDEX_TYPE
 	    case 16 :
-		i = 0xffffffffffff0000;
+		i = 0x0000000000000000;
 		break;
 #endif /* GX_COLOR_INDEX_TYPE */
           }
@@ -2929,7 +2940,10 @@ cups_put_params(gx_device     *pdev,	/* 
   int                   xflip = 0,
                         yflip = 0;
   int                   found = 0;
-
+  gs_param_string icc_pro_dummy;
+  int old_cmps = cups->color_info.num_components;
+  int old_depth = cups->color_info.depth;
+  
 #ifdef DEBUG
   dprintf2("DEBUG2: cups_put_params(%p, %p)\n", pdev, plist);
 #endif /* DEBUG */
@@ -3024,6 +3038,11 @@ cups_put_params(gx_device     *pdev,	/* 
   margins_set = param_read_float_array(plist, "Margins", &arrayval) == 0;
   color_set   = param_read_int(plist, "cupsColorSpace", &intval) == 0 ||
                 param_read_int(plist, "cupsBitsPerColor", &intval) == 0;
+
+  if (!cups->user_icc) {
+      cups->user_icc = param_read_string(plist, "OutputICCProfile", &icc_pro_dummy) == 0;
+  }
+
   /* We set the old dimensions to 1 if we have a color depth change, so
      that memory reallocation gets forced. This is perhaps not the correct
      approach to prevent crashes like in bug 690435. We keep it for the
@@ -3134,12 +3153,20 @@ cups_put_params(gx_device     *pdev,	/* 
   if ((code = gdev_prn_put_params(pdev, plist)) < 0)
     return (code);
 
+  /* If cups_set_color_info() changed the color model of the device we want to
+   * force the raster memory to be recreated/reinitialized
+   */
+  if (cups->color_info.num_components != old_cmps || cups->color_info.depth != old_depth) {
+      width_old = 0;
+      height_old = 0;
+  }
+  else {
   /* pdev->width/height may have been changed by the call to
    * gdev_prn_put_params()
    */
-  width_old = pdev->width;
-  height_old = pdev->height;
-
+     width_old = pdev->width;
+     height_old = pdev->height;
+  }
  /*
   * Update margins/sizes as needed...
   */
@@ -4044,22 +4071,88 @@ cups_set_color_info(gx_device *pdev)	/* 
     for (k = 0; k <= CUPS_MAX_VALUE; k ++)
       cups->Density[k] = k;
   }
-  /* Set up the ICC profile for ghostscript to use based upon the color space.
-     This is different than the PPD profile above which appears to be some sort
-     of matrix based TRC profile */
-  switch (cups->header.cupsColorSpace) {
-      /* Use RGB profile for this */
-    case CUPS_CSPACE_RGBW:
-      if (pdev->icc_struct == NULL) {
-        pdev->icc_struct = gsicc_new_device_profile_array(pdev->memory);
-      }
-      if (pdev->icc_struct->device_profile[gsDEFAULTPROFILE] == NULL) {
-            code = gsicc_set_device_profile(pdev, pdev->memory, 
-                DEFAULT_RGB_ICC, gsDEFAULTPROFILE);
-      }
-      break;
-    default:
-      break;
+  if (!cups->user_icc) {
+    /* Set up the ICC profile for ghostscript to use based upon the color space.
+       This is different than the PPD profile above which appears to be some sort
+       of matrix based TRC profile */
+    switch (cups->header.cupsColorSpace)
+    {
+      default :
+      case CUPS_CSPACE_RGBW :
+      case CUPS_CSPACE_RGB :
+      case CUPS_CSPACE_RGBA :
+      case CUPS_CSPACE_CMY :
+      case CUPS_CSPACE_YMC :
+#    ifdef CUPS_RASTER_HAVE_COLORIMETRIC
+      case CUPS_CSPACE_CIELab :
+      case CUPS_CSPACE_ICC1 :
+      case CUPS_CSPACE_ICC2 :
+      case CUPS_CSPACE_ICC3 :
+      case CUPS_CSPACE_ICC4 :
+      case CUPS_CSPACE_ICC5 :
+      case CUPS_CSPACE_ICC6 :
+      case CUPS_CSPACE_ICC7 :
+      case CUPS_CSPACE_ICC8 :
+      case CUPS_CSPACE_ICC9 :
+      case CUPS_CSPACE_ICCA :
+      case CUPS_CSPACE_ICCB :
+      case CUPS_CSPACE_ICCC :
+      case CUPS_CSPACE_ICCD :
+      case CUPS_CSPACE_ICCE :
+      case CUPS_CSPACE_ICCF :
+#    endif /* CUPS_RASTER_HAVE_COLORIMETRIC */
+        if (!pdev->icc_struct || (pdev->icc_struct &&
+             pdev->icc_struct->device_profile[gsDEFAULTPROFILE]->data_cs != gsRGB)) {
+
+          if (pdev->icc_struct) {
+              rc_decrement(pdev->icc_struct, "cups_set_color_info");            
+          }
+          pdev->icc_struct = gsicc_new_device_profile_array(pdev->memory);
+
+          code = gsicc_set_device_profile(pdev, pdev->memory, 
+              (char *)DEFAULT_RGB_ICC, gsDEFAULTPROFILE);
+          }
+        break;
+
+      case CUPS_CSPACE_W :
+      case CUPS_CSPACE_WHITE :
+      case CUPS_CSPACE_K :
+      case CUPS_CSPACE_GOLD :
+      case CUPS_CSPACE_SILVER :
+        if (!pdev->icc_struct || (pdev->icc_struct &&
+             pdev->icc_struct->device_profile[gsDEFAULTPROFILE]->data_cs != gsGRAY)) {
+
+          if (pdev->icc_struct) {
+              rc_decrement(pdev->icc_struct, "cups_set_color_info");            
+          }
+          pdev->icc_struct = gsicc_new_device_profile_array(pdev->memory);
+
+          code = gsicc_set_device_profile(pdev, pdev->memory->non_gc_memory, 
+              (char *)DEFAULT_GRAY_ICC, gsDEFAULTPROFILE);
+        }
+        break;
+      case CUPS_CSPACE_KCMYcm :
+#    ifdef CUPS_RASTER_HAVE_COLORIMETRIC
+      case CUPS_CSPACE_CIEXYZ :
+#endif
+      case CUPS_CSPACE_CMYK :
+      case CUPS_CSPACE_YMCK :
+      case CUPS_CSPACE_KCMY :
+      case CUPS_CSPACE_GMCK :
+      case CUPS_CSPACE_GMCS :
+        if (!pdev->icc_struct || (pdev->icc_struct &&
+             pdev->icc_struct->device_profile[gsDEFAULTPROFILE]->data_cs != gsCMYK)) {
+
+          if (pdev->icc_struct) {
+              rc_decrement(pdev->icc_struct, "cups_set_color_info");            
+          }
+          pdev->icc_struct = gsicc_new_device_profile_array(pdev->memory);
+
+          code = gsicc_set_device_profile(pdev, pdev->memory, 
+              (char *)DEFAULT_CMYK_ICC, gsDEFAULTPROFILE);
+          }
+        break;
+    }
   }
 }