Tizen 2.1 base
[platform/upstream/hplip.git] / prnt / hpijs / gdevijs-krgb-1.5-gs8.61.patch
1 diff -uNr old/gdevijs.c new/gdevijs.c
2 --- old/gdevijs.c       2008-01-15 20:20:07.000000000 -0800
3 +++ new/gdevijs.c       2008-01-17 09:52:54.000000000 -0800
4 @@ -23,15 +23,54 @@
5   * which is a security risk, since any program can be run.
6   * You should use -dSAFER which sets .LockSafetyParams to true 
7   * before opening this device.
8 + *
9 + * 11/26/03 David Suffield (gdevijs-krgb-1.0.patch)
10 + * (c) 2003-2004 Copyright Hewlett-Packard Development Company, LP
11 + *
12 + * 1. Removed hpijs 1.0-1.0.2 workarounds, use hpijs 1.0.3 or higher.
13 + * 2. Added krgb support.
14 + *
15 + * 02/21/05 David Suffield (gdevijs-krgb-1.1.patch)
16 + * 1. Fixed segfault issue with 1-bit color space.
17 + * 2. Fixed z-order issue with colored text on black rectangle.
18 + *
19 + * 02/22/06 David Suffield (gdevijs-krgb-1.2.patch)
20 + * 1. Fixed krgb buffer overflow issue with out-of-band data in fill_rectangle and copy_mono. 
21 + *    This buffer overflow condition occurred with fullbleed print jobs that had k-band images.
22 + * 2. Added Dan Coby (artifex) fix for gsijs_read_string_malloc gs_free *str memory leak.
23 + *
24 + * 06/02/06 David Suffield (gdevijs-krgb-1.3.patch)
25 + * 1. Revisited the krgb buffer overflow issue with out-of-band data in fill_rectangle and 
26 + *    copy_mono. Changed the fill_rectangle and copy_mono to an inner loop buffer check 
27 + *    instead of a outer loop x/y extent check.
28 + * 2. As requested by Ralph Giles, added K 1-bit and 8-bit support for krgb, but only 1-bit is 
29 + *    implemented for now.
30 + *
31 + *    KRGB definition:
32 + *    1. K=1-bit or 8-bit black plane, RGB=24 bit color raster.
33 + *    2. K-plane will only contain objects that are black text and black line drawings.
34 + *    3. RGB raster will not contain K-plane objects.
35 + *    4. K resolution and RGB resolution will be equal.
36 + *    5. K-plane will be byte aligned.
37 + *    6. K-plane 1-bit definition; 1=black, 0=nothing (KRGB).
38 + *    7. K-plane 8-bit definition; 255=black, 0=nothing (KxRGB).
39 + *
40 + * 1/15/08 David Suffield (gdevijs-krgb-1.5.patch)
41 + * 1. Added checks for null forward device in the graphic procedures.
42 + * 2. Corrected the "force banding" code in gsijs_open. Needed for small images (IE: hagaki in landscape).
43 + *
44   */
45  
46  #include "unistd_.h"   /* for dup() */
47  #include <stdlib.h>
48 +#include <fcntl.h>
49  #include "gdevprn.h"
50  #include "gp.h"
51  #include "ijs.h"
52  #include "ijs_client.h"
53  
54 +//#define KRGB_DEBUG
55 +
56  /* This should go into gdevprn.h, or, better yet, gdevprn should
57     acquire an API for changing resolution. */
58  int gdev_prn_maybe_realloc_memory(gx_device_printer *pdev,
59 @@ -49,6 +88,14 @@
60  static dev_proc_put_params(gsijs_put_params);
61  static dev_proc_finish_copydevice(gsijs_finish_copydevice);
62  
63 +/* Following definitions are for krgb support. */
64 +static dev_proc_create_buf_device(gsijs_create_buf_device);
65 +static dev_proc_fill_rectangle(gsijs_fill_rectangle);
66 +static dev_proc_copy_mono(gsijs_copy_mono);
67 +static dev_proc_fill_mask(gsijs_fill_mask);
68 +static dev_proc_fill_path(gsijs_fill_path);
69 +static dev_proc_stroke_path(gsijs_stroke_path);
70 +
71  static const gx_device_procs gsijs_procs = {
72         gsijs_open,
73         NULL,   /* get_initial_matrix */
74 @@ -123,6 +170,15 @@
75  
76      IjsClientCtx *ctx;
77      int ijs_version;
78 +
79 +    /* Additional parameters for krgb support. */
80 +    int krgb_mode;     /* 0=false, 1=true */
81 +    int k_bits;        /* number of bits in k plane, 1 or 8 */
82 +    int k_path;        /* k plane path, 0=false, 1=true */
83 +    int k_width;       /* k plane width in pixels */
84 +    int k_band_size;   /* k plane buffer size in bytes, byte aligned */
85 +    unsigned char *k_band;  /* k plane buffer */
86 +    gx_device_procs prn_procs;  /* banding playback procedures */
87  };
88  
89  #define DEFAULT_DPI 74   /* See gsijs_set_resolution() below. */
90 @@ -150,7 +206,13 @@
91      FALSE,     /* Tumble_set */
92  
93      NULL,      /* IjsClient *ctx */
94 -    0          /* ijs_version */
95 +    0,         /* ijs_version */
96 +    0,          /* krgb_mode */
97 +    0,          /* k_bits */
98 +    0,          /* k_path */
99 +    0,          /* k_width */
100 +    0,          /* k_band_size */
101 +    NULL        /* k_band buffer */
102  };
103  
104  
105 @@ -166,12 +228,314 @@
106  
107  /**************************************************************************/
108  
109 -/* ------ Private definitions ------ */
110 +/* ---------------- Low-level graphic procedures ---------------- */
111 +
112 +static unsigned char xmask[] =
113 +{
114 +   0x80,    /* x=0 */
115 +   0x40,    /* 1 */
116 +   0x20,    /* 2 */
117 +   0x10,    /* 3 */
118 +   0x08,    /* 4 */
119 +   0x04,    /* 5 */
120 +   0x02,    /* 6 */
121 +   0x01     /* 7 */
122 +};
123 +
124 +static int gsijs_fill_rectangle(gx_device * dev, int x, int y, int w, int h,
125 +           gx_color_index color)
126 +{
127 +   gx_device_ijs *ijsdev = (gx_device_ijs *)((gx_device_forward *)dev)->target;
128 +
129 +   if (!ijsdev)
130 +      return 0;  /* no forward device, bug?? */
131 +
132 +   if (ijsdev->krgb_mode && ijsdev->k_path && y >= 0 && x >= 0) 
133 +   {
134 +      int raster = (ijsdev->k_width+7) >> 3;
135 +      register unsigned char *dest;
136 +      int dest_start_bit;
137 +      int band_height = ijsdev->k_band_size/raster;
138 +      int i,j;
139 +      unsigned char *beg = ijsdev->k_band;
140 +      unsigned char *end = ijsdev->k_band+ijsdev->k_band_size;
141 +      unsigned char *p;
142 +
143 +      if (h <= 0 || w <= 0)
144 +         return 0;
145 +
146 +      /* Check for out-of-band graphic. */
147 +      if (x >= ijsdev->k_width || y >= band_height)
148 +         return 0;  /* out-of-band */
149 +
150 +      dest_start_bit = x & 7;
151 +      dest=ijsdev->k_band+(raster*y)+(x >> 3);
152 +
153 +      /* Note x,y orgin 0,0 is stored first byte 0 left to right. */
154 +
155 +      if (color==0x0)
156 +      { 
157 +         /* Color is black, store in k plane band instead of regular band. */
158 +         for (j=0; j<h; j++)
159 +         {
160 +            for (i=0; i<w; i++)
161 +            {
162 +               p = &dest[(dest_start_bit+i)>>3];
163 +               if (p >= beg && p <= end)
164 +                  *p |= xmask[(dest_start_bit+i)&7];
165 +            }
166 +            dest+=raster;    
167 +         }
168 +         return 0;
169 +      }
170 +      else
171 +      {
172 +         /* Color is not black, remove any k plane bits for z-order dependencies, store in regular band. */
173 +         for (j=0; j<h; j++)
174 +         {
175 +            for (i=0; i<w; i++)
176 +            {
177 +               p = &dest[(dest_start_bit+i)>>3];
178 +               if (p >= beg && p <= end)
179 +                  *p &= ~xmask[(dest_start_bit+i)&7];
180 +            }
181 +            dest+=raster;    
182 +         }
183 +      }
184 +   }
185 +
186 +   return (*ijsdev->prn_procs.fill_rectangle)(dev, x, y, w, h, color);
187 +}
188 +
189 +static int gsijs_copy_mono(gx_device * dev, const byte * data,
190 +      int dx, int draster, gx_bitmap_id id,
191 +      int x, int y, int w, int height, gx_color_index zero, gx_color_index one)
192 +{
193 +   gx_device_ijs *ijsdev = (gx_device_ijs *)((gx_device_forward *)dev)->target;
194 +
195 +   if (!ijsdev)
196 +      return 0;  /* no forward device, bug?? */
197 +
198 +   //   if (ijsdev->krgb_mode && ijsdev->k_path && one==0x0) 
199 +   if (ijsdev->krgb_mode && ijsdev->k_path) 
200 +   {
201 +      /* Store in k plane band instead of regular band. */
202 +      int raster = (ijsdev->k_width+7) >> 3;       /* raster width in bytes, byte aligned */
203 +      register unsigned char *dest;
204 +      register const unsigned char *scan;
205 +      int dest_start_bit;
206 +      int scan_start_bit;
207 +      int band_height = ijsdev->k_band_size/raster;
208 +      int i,h=height;
209 +      unsigned char *beg = ijsdev->k_band;
210 +      unsigned char *end = ijsdev->k_band+ijsdev->k_band_size;
211 +      unsigned char *p;
212 +      
213 +      if (h <= 0 || w <= 0)
214 +         return 0;
215 +
216 +      /* Check for out-of-band graphic. */
217 +      if (x >= ijsdev->k_width || y >= band_height)
218 +         return 0;  /* out-of-band */
219 +
220 +      scan=data+(dx >> 3);
221 +      dest_start_bit = x & 7;
222 +      scan_start_bit = dx & 7;
223 +      dest=ijsdev->k_band+(raster*y)+(x >> 3);
224 +
225 +      if (one==0x0)
226 +      {
227 +         /* Color is black, store in k plane band instead of regular band. */
228 +         while (h-- > 0)
229 +         {
230 +            for (i=0; i<w; i++)
231 +            {
232 +               if (scan[(scan_start_bit+i)>>3] & xmask[(scan_start_bit+i)&7])
233 +               {
234 +                  p = &dest[(dest_start_bit+i)>>3];
235 +                  if (p >= beg && p <= end)
236 +                     *p |= xmask[(dest_start_bit+i)&7];
237 +               }
238 +            }
239 +            scan+=draster;
240 +            dest+=raster;
241 +         }
242 +         return 0;
243 +      }
244 +      else
245 +      {
246 +         /* Color is not black, remove any k plane bits for z-order dependencies, store in regular band. */
247 +         while (h-- > 0)
248 +         {
249 +            for (i=0; i<w; i++)
250 +            {
251 +               if (scan[(scan_start_bit+i)>>3] & xmask[(scan_start_bit+i)&7])
252 +               {
253 +                  p = &dest[(dest_start_bit+i)>>3];
254 +                  if (p >= beg && p <= end)
255 +                     *p &= ~xmask[(dest_start_bit+i)&7];
256 +               }
257 +            }
258 +            scan+=draster;
259 +            dest+=raster;
260 +         }
261 +      }   
262 +   }
263 +
264 +   return (*ijsdev->prn_procs.copy_mono)(dev, data, dx, draster, id, x, y, w, height, zero, one);
265 +}
266 +
267 +/* ---------------- High-level graphic procedures ---------------- */
268 +
269 +static int gsijs_fill_mask(gx_device * dev,
270 +      const byte * data, int dx, int raster, gx_bitmap_id id,
271 +      int x, int y, int w, int h,
272 +      const gx_drawing_color * pdcolor, int depth,
273 +      gs_logical_operation_t lop, const gx_clip_path * pcpath)
274 +{
275 +   gx_device_ijs *ijsdev = (gx_device_ijs *)((gx_device_forward *)dev)->target;
276 +   int code;
277 +
278 +   if (!ijsdev)
279 +      return 0;  /* no forward device, bug?? */
280 +
281 +   ijsdev->k_path = 1;
282 +
283 +   code = (*ijsdev->prn_procs.fill_mask)(dev, data, dx, raster, id, x, y, w, h, pdcolor, depth, lop, pcpath);
284 +
285 +   ijsdev->k_path = 0;
286 +
287 +   return code;
288 +}
289 +
290 +static int gsijs_fill_path(gx_device * dev, const gs_imager_state * pis,
291 +      gx_path * ppath, const gx_fill_params * params,
292 +      const gx_drawing_color * pdcolor,
293 +      const gx_clip_path * pcpath)
294 +{
295 +   gx_device_ijs *ijsdev = (gx_device_ijs *)((gx_device_forward *)dev)->target;
296 +   int code;
297 +
298 +   if (!ijsdev)
299 +      return 0;  /* no forward device, bug?? */
300 +
301 +   ijsdev->k_path = 1;
302 +
303 +   code = (*ijsdev->prn_procs.fill_path)(dev, pis, ppath, params, pdcolor, pcpath);
304  
305 -/* Versions 1.0 through 1.0.2 of hpijs report IJS version 0.29, and
306 -   require some workarounds. When more up-to-date hpijs versions
307 -   become ubiquitous, all these workarounds should be removed. */
308 -#define HPIJS_1_0_VERSION 29
309 +   ijsdev->k_path = 0;
310 +
311 +   return 0;
312 +}
313 +
314 +static int gsijs_stroke_path(gx_device * dev, const gs_imager_state * pis,
315 +        gx_path * ppath, const gx_stroke_params * params,
316 +        const gx_drawing_color * pdcolor,
317 +        const gx_clip_path * pcpath)
318 +{
319 +   gx_device_ijs *ijsdev = (gx_device_ijs *)((gx_device_forward *)dev)->target;
320 +   int code;
321 +
322 +   if (!ijsdev)
323 +      return 0;  /* no forward device, bug?? */
324 +
325 +   ijsdev->k_path = 1;
326 +
327 +   code = (*ijsdev->prn_procs.stroke_path)(dev, pis, ppath, params, pdcolor, pcpath);
328 +
329 +   ijsdev->k_path = 0;
330 +
331 +   return code;
332 +}
333 +
334 +/* ---------------- krgb banding playback procedures ---------------- */
335 +
336 +static int gsijs_get_bits(gx_device_printer * pdev, int y, byte * str, byte ** actual_data)
337 +{
338 +   gx_device_ijs *ijsdev = (gx_device_ijs *)pdev;
339 +   gx_device_clist_common *cdev = (gx_device_clist_common *)pdev;
340 +   int band_height = cdev->page_info.band_params.BandHeight;
341 +   int band_number = y/band_height;
342 +   int raster = (ijsdev->k_width+7) >> 3;       /* raster width in bytes, byte aligned */
343 +   int y1=raster*(y-(band_height*band_number));
344
345 +   if (y1 == 0)
346 +   {
347 +      /* First raster for band, clear k_band. Banding playback occurs on first raster. */
348 +      memset(ijsdev->k_band, 0, ijsdev->k_band_size); 
349 +   }
350 +
351 +   return gdev_prn_get_bits(pdev, y, str, actual_data);  /* get raster from regular band */
352 +}
353 +
354 +static int gsijs_k_get_bits(gx_device_printer * pdev, int y, byte ** actual_data)
355 +{
356 +   gx_device_ijs *ijsdev = (gx_device_ijs *)pdev;
357 +   gx_device_clist_common *cdev = (gx_device_clist_common *)pdev;
358 +   int band_height = cdev->page_info.band_params.BandHeight;
359 +   int band_number = y/band_height;
360 +   int raster = (ijsdev->k_width+7) >> 3;       /* raster width in bytes, byte aligned */
361 +   int y1=raster*(y-(band_height*band_number));
362
363 +   *actual_data = ijsdev->k_band+y1;
364 +
365 +   return 0;
366 +}
367 +
368 +static int gsijs_create_buf_device(gx_device **pbdev, gx_device *target,
369 +            const gx_render_plane_t *render_plane, gs_memory_t *mem, gx_band_complexity_t *for_band)
370 +{
371 +   gx_device_ijs *ijsdev = (gx_device_ijs *)target;
372 +   int n_chan = ijsdev->color_info.num_components;
373 +   int code = gx_default_create_buf_device(pbdev, target, render_plane, mem, for_band);
374 +   if (code < 0 || n_chan != 3)
375 +      return code;
376 +
377 +   /* Save buffer (vector) procedures so that we can hook them during banding playback. */
378 +   ijsdev->prn_procs = (*pbdev)->procs;
379 +
380 +   /* Replace buffer procedures with krgb procedures. */
381 +   set_dev_proc(*pbdev, fill_rectangle, gsijs_fill_rectangle);
382 +   set_dev_proc(*pbdev, copy_mono, gsijs_copy_mono);
383 +   set_dev_proc(*pbdev, fill_mask, gsijs_fill_mask);
384 +   set_dev_proc(*pbdev, fill_path, gsijs_fill_path);
385 +   set_dev_proc(*pbdev, stroke_path, gsijs_stroke_path);
386 +
387 +   return code;
388 +}
389 +
390 +/* See if IJS server supports krgb. */
391 +static int
392 +gsijs_set_krgb_mode(gx_device_ijs *ijsdev)
393 +{
394 +    char buf[256];
395 +    int n_chan = ijsdev->color_info.num_components;
396 +    int code;
397 +
398 +    ijsdev->krgb_mode = 0;  /* default is no krgb */
399 +
400 +    if (n_chan != 3)
401 +        return 0;    /* no krgb support, not RGB colorspace */
402 +
403 +    buf[0] = 0;
404 +    code = ijs_client_enum_param(ijsdev->ctx, 0, "ColorSpace", buf, sizeof(buf)-1);
405 +    if (code >= 0)
406 +        buf[code] = 0;
407 +    if (strstr(buf, "KRGB") != NULL)
408 +    {
409 +        ijsdev->krgb_mode = 1;     /* yes KRGB is supported */
410 +        ijsdev->k_bits = 1;        /* KRGB = 1x8x8x8 */ 
411 +    }
412 +    else if (strstr(buf, "KxRGB") != NULL)
413 +    {
414 +        ijsdev->krgb_mode = 1;    /* yes KRGB is supported */
415 +        ijsdev->k_bits = 8;       /* KRGB = 8x8x8x8 */
416 +    }
417 +
418 +    return 0; 
419 +}
420 +
421 +/* ------ Private definitions ------ */
422  
423  static int
424  gsijs_parse_wxh (const char *val, int size, double *pw, double *ph)
425 @@ -209,34 +573,6 @@
426  }
427  
428  /**
429 - * gsijs_set_generic_params_hpijs: Set generic IJS parameters.
430 - *
431 - * This version is specialized for hpijs 1.0 through 1.0.2, and
432 - * accommodates a number of quirks.
433 - **/
434 -static int
435 -gsijs_set_generic_params_hpijs(gx_device_ijs *ijsdev)
436 -{
437 -    char buf[256];
438 -    int code = 0;
439 -
440 -    /* IjsParams, Duplex, and Tumble get set at this point because
441 -       they may affect margins. */
442 -    if (ijsdev->IjsParams) {
443 -       code = gsijs_client_set_param(ijsdev, "IjsParams", ijsdev->IjsParams);
444 -    }
445 -
446 -    if (code == 0 && ijsdev->Duplex_set) {
447 -       int duplex_val;
448 -       
449 -       duplex_val = ijsdev->Duplex ? (ijsdev->IjsTumble ? 1 : 2) : 0;
450 -       sprintf (buf, "%d", duplex_val);
451 -       code = gsijs_client_set_param(ijsdev, "Duplex", buf);
452 -    }
453 -    return code;
454 -}
455 -
456 -/**
457   * gsijs_set_generic_params: Set generic IJS parameters.
458   **/
459  static int
460 @@ -247,9 +583,6 @@
461      int i, j;
462      char *value;
463  
464 -    if (ijsdev->ijs_version == HPIJS_1_0_VERSION)
465 -       return gsijs_set_generic_params_hpijs(ijsdev);
466 -
467      /* Split IjsParams into separate parameters and send to ijs server */
468      value = NULL;
469      for (i=0, j=0; (j < ijsdev->IjsParams_size) && (i < sizeof(buf)-1); j++) {
470 @@ -290,68 +623,6 @@
471  }
472  
473  /**
474 - * gsijs_set_margin_params_hpijs: Do margin negotiation with IJS server.
475 - *
476 - * This version is specialized for hpijs 1.0 through 1.0.2, and
477 - * accommodates a number of quirks.
478 - **/
479 -static int
480 -gsijs_set_margin_params_hpijs(gx_device_ijs *ijsdev)
481 -{
482 -    char buf[256];
483 -    int code = 0;
484 -
485 -    if (code == 0) {
486 -       sprintf(buf, "%d", ijsdev->width);
487 -       code = gsijs_client_set_param(ijsdev, "Width", buf);
488 -    }
489 -    if (code == 0) {
490 -       sprintf(buf, "%d", ijsdev->height);
491 -       code = gsijs_client_set_param(ijsdev, "Height", buf);
492 -    }
493 -
494 -    if (code == 0) {
495 -       double printable_width, printable_height;
496 -       double printable_left, printable_top;
497 -       float m[4];
498 -
499 -       code = ijs_client_get_param(ijsdev->ctx, 0, "PrintableArea",
500 -                                  buf, sizeof(buf));
501 -       if (code == IJS_EUNKPARAM)
502 -           /* IJS server doesn't support margin negotiations.
503 -              That's ok. */
504 -           return 0;
505 -       else if (code >= 0) {
506 -           code = gsijs_parse_wxh(buf, code,
507 -                                   &printable_width, &printable_height);
508 -       }
509 -
510 -       if (code == 0) {
511 -           code = ijs_client_get_param(ijsdev->ctx, 0, "PrintableTopLeft",
512 -                                       buf, sizeof(buf));
513 -           if (code == IJS_EUNKPARAM)
514 -               return 0;
515 -           else if (code >= 0) {
516 -               code = gsijs_parse_wxh(buf, code,
517 -                                       &printable_left, &printable_top);
518 -           }
519 -       }
520 -
521 -       if (code == 0) {
522 -           m[0] = printable_left;
523 -           m[1] = ijsdev->MediaSize[1] * (1.0 / 72) -
524 -             printable_top - printable_height;
525 -           m[2] = ijsdev->MediaSize[0] * (1.0 / 72) -
526 -             printable_left - printable_width;
527 -           m[3] = printable_top;
528 -           gx_device_set_margins((gx_device *)ijsdev, m, true);
529 -       }
530 -    }
531 -
532 -    return code;
533 -}
534 -
535 -/**
536   * gsijs_set_margin_params: Do margin negotiation with IJS server.
537   **/
538  static int
539 @@ -362,9 +633,6 @@
540      int i, j;
541      char *value;
542  
543 -    if (ijsdev->ijs_version == HPIJS_1_0_VERSION)
544 -       return gsijs_set_margin_params_hpijs(ijsdev);
545 -
546      /* Split IjsParams into separate parameters and send to ijs server */
547      value = NULL;
548      for (i=0, j=0; (j < ijsdev->IjsParams_size) && (i < sizeof(buf)-1); j++) {
549 @@ -537,6 +805,11 @@
550         return gs_note_error(gs_error_ioerror);
551      }
552  
553 +    ijsdev->space_params.banding_type = BandingAlways; /* always force banding */
554 +
555 +    /* Set create_buf_device in printer device, so that we can hook the banding playback procedures. */
556 +    ijsdev->printer_procs.buf_procs.create_buf_device = gsijs_create_buf_device;
557 +
558      /* Decide whether to use OutputFile or OutputFD. Note: how to
559         determine this is a tricky question, so we just allow the
560         user to set it.
561 @@ -610,6 +883,9 @@
562      if (code >= 0)
563         code = gsijs_set_margin_params(ijsdev);
564  
565 +    if (code >= 0)
566 +        code = gsijs_set_krgb_mode(ijsdev);
567 +
568      return code;
569  }
570  
571 @@ -690,21 +966,6 @@
572      return min(width, end);
573  }
574  
575 -static int ijs_all_white(unsigned char *data, int size)
576 -{
577 -   int clean = 1;
578 -   int i;
579 -   for (i = 0; i < size; i++)
580 -   {
581 -     if (data[i] != 0xFF)
582 -     {
583 -        clean = 0;
584 -        break;
585 -     }
586 -   }
587 -   return clean;
588 -}
589 -
590  /* Print a page.  Don't use normal printer gdev_prn_output_page 
591   * because it opens the output file.
592   */
593 @@ -715,8 +976,10 @@
594      gx_device_printer *pdev = (gx_device_printer *)dev;
595      int raster = gdev_prn_raster(pdev);
596      int ijs_width, ijs_height;
597 -    int row_bytes;
598 +    int row_bytes, k_row_bytes=0;
599      int n_chan = pdev->color_info.num_components;
600 +    int krgb_mode = ijsdev->krgb_mode;
601 +    int k_bits = ijsdev->k_bits;
602      unsigned char *data;
603      char buf[256];
604      double xres = pdev->HWResolution[0];
605 @@ -732,13 +995,23 @@
606  
607      /* Determine bitmap width and height */
608      ijs_height = gdev_prn_print_scan_lines(dev);
609 -    if (ijsdev->ijs_version == HPIJS_1_0_VERSION) {
610 -       ijs_width = pdev->width;
611 -    } else {
612         ijs_width = gsijs_raster_width(dev);
613 -    }
614 +
615      row_bytes = (ijs_width * pdev->color_info.depth + 7) >> 3;
616  
617 +    if (krgb_mode)
618 +    {
619 +        gx_device_clist_common *cdev = (gx_device_clist_common *)dev;
620 +        int band_height = cdev->page_info.band_params.BandHeight;
621 +        k_row_bytes = (ijs_width + 7) >> 3;
622 +
623 +        /* Create banding buffer for k plane. */
624 +        ijsdev->k_width = ijs_width;
625 +        ijsdev->k_band_size = band_height * k_row_bytes;   
626 +        if ((ijsdev->k_band = gs_malloc(pdev->memory, ijsdev->k_band_size, 1, "gsijs_output_page")) == (unsigned char *)NULL)
627 +           return gs_note_error(gs_error_VMerror);
628 +    }
629 +
630      /* Required page parameters */
631      sprintf(buf, "%d", n_chan);
632      gsijs_client_set_param(ijsdev, "NumChan", buf);
633 @@ -747,44 +1020,71 @@
634  
635      /* This needs to become more sophisticated for DeviceN. */
636      strcpy(buf, (n_chan == 4) ? "DeviceCMYK" : 
637 -       ((n_chan == 3) ? "DeviceRGB" : "DeviceGray"));
638 +       ((n_chan == 3) ? (krgb_mode ? ((k_bits == 1) ? "KRGB" : "KxRGB") : "DeviceRGB") : "DeviceGray"));
639      gsijs_client_set_param(ijsdev, "ColorSpace", buf);
640  
641 -    /* If hpijs 1.0, don't set width and height here, because it
642 -       expects them to be the paper size. */
643 -    if (ijsdev->ijs_version != HPIJS_1_0_VERSION) {
644 -       sprintf(buf, "%d", ijs_width);
645 -       gsijs_client_set_param(ijsdev, "Width", buf);
646 -       sprintf(buf, "%d", ijs_height);
647 -       gsijs_client_set_param(ijsdev, "Height", buf);
648 -    }
649 +    sprintf(buf, "%d", ijs_width);
650 +    gsijs_client_set_param(ijsdev, "Width", buf);
651 +    sprintf(buf, "%d", ijs_height);
652 +    gsijs_client_set_param(ijsdev, "Height", buf);
653  
654      sprintf(buf, "%gx%g", xres, yres);
655      gsijs_client_set_param(ijsdev, "Dpi", buf);
656  
657 +#ifdef KRGB_DEBUG
658 +    int kfd, rgbfd;
659 +    char sz[128];
660 +    kfd = open("/tmp/k.pbm", O_CREAT | O_TRUNC | O_RDWR, 0644);
661 +    rgbfd = open("/tmp/rgb.ppm", O_CREAT | O_TRUNC | O_RDWR, 0644);
662 +    snprintf(sz, sizeof(sz), "P4\n#gdevijs test\n%d\n%d\n", ijs_width, ijs_height);
663 +    write(kfd, sz, strlen(sz));
664 +    snprintf(sz, sizeof(sz), "P6\n#gdevijs test\n%d\n%d\n255\n", ijs_width, ijs_height);
665 +    write(rgbfd, sz, strlen(sz));
666 +#endif
667 +
668      for (i=0; i<num_copies; i++) {
669         unsigned char *actual_data;
670         ijs_client_begin_cmd (ijsdev->ctx, IJS_CMD_BEGIN_PAGE);
671         status = ijs_client_send_cmd_wait(ijsdev->ctx);
672  
673         for (y = 0; y < ijs_height; y++) {
674 -           code = gdev_prn_get_bits(pdev, y, data, &actual_data);
675 -           if (code < 0)
676 -               break;
677 +            if (krgb_mode)
678 +                code = gsijs_get_bits(pdev, y, data, &actual_data);
679 +            else
680 +                code = gdev_prn_get_bits(pdev, y, data, &actual_data);
681 +            if (code < 0)
682 +                break;
683 +#ifdef KRGB_DEBUG
684 +            write(rgbfd, actual_data, row_bytes);
685 +#endif
686 +            status = ijs_client_send_data_wait(ijsdev->ctx, 0, (char *)actual_data, row_bytes);
687 +            if (status)
688 +                break;
689  
690 -           if (ijsdev->ijs_version == HPIJS_1_0_VERSION &&
691 -               ijs_all_white(actual_data, row_bytes))
692 -               status = ijs_client_send_data_wait(ijsdev->ctx, 0, NULL, 0);
693 -           else
694 -               status = ijs_client_send_data_wait(ijsdev->ctx, 0,
695 -                   (char *)actual_data, row_bytes);
696 -           if (status)
697 -               break;
698 +            if (krgb_mode) {
699 +                code = gsijs_k_get_bits(pdev, y, &actual_data);
700 +                if (code < 0)
701 +                    break;
702 +#ifdef KRGB_DEBUG
703 +                write(kfd, actual_data, k_row_bytes);
704 +#endif
705 +                status = ijs_client_send_data_wait(ijsdev->ctx, 0, (char *)actual_data, k_row_bytes);
706 +                if (status)
707 +                    break;
708 +           }
709         }
710         ijs_client_begin_cmd(ijsdev->ctx, IJS_CMD_END_PAGE);
711         status = ijs_client_send_cmd_wait(ijsdev->ctx);
712      }
713  
714 +#ifdef KRGB_DEBUG
715 +    close(kfd);
716 +    close(rgbfd);
717 +#endif
718 +
719 +    if(krgb_mode)
720 +        gs_free(pdev->memory, ijsdev->k_band, ijsdev->k_band_size, 1, "gsijs_output_page");
721 +
722      gs_free_object(pdev->memory, data, "gsijs_output_page");
723  
724      endcode = (pdev->buffer_space && !pdev->is_async_renderer ?
725 @@ -1090,7 +1390,6 @@
726         dprintf2("ijs: Can't set parameter %s=%s\n", key, value);
727      return code;
728  }
729
730  
731  static int
732  gsijs_set_color_format(gx_device_ijs *ijsdev)