Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – planix.SVN – Blame – /os/branches/feature_unix/sys/src/cmd/gs/src/gxdcolor.c – Rev 2

Subversion Repositories planix.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/* Copyright (C) 1996, 2000 Aladdin Enterprises.  All rights reserved.
2
 
3
  This software is provided AS-IS with no warranty, either express or
4
  implied.
5
 
6
  This software is distributed under license and may not be copied,
7
  modified or distributed except as expressly authorized under the terms
8
  of the license contained in the file LICENSE in this distribution.
9
 
10
  For more information about licensing, please refer to
11
  http://www.ghostscript.com/licensing/. For information on
12
  commercial licensing, go to http://www.artifex.com/licensing/ or
13
  contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14
  San Rafael, CA  94903, U.S.A., +1(415)492-9861.
15
*/
16
 
17
/*$Id: gxdcolor.c,v 1.13 2005/06/20 08:59:23 igor Exp $ */
18
/* Pure and null device color implementation */
19
#include "gx.h"
20
#include "memory_.h"
21
#include "gserrors.h"
22
#include "gsbittab.h"
23
#include "gxdcolor.h"
24
#include "gxdevice.h"
25
#include "gxdevcli.h"
26
 
27
/* Define the standard device color types. */
28
 
29
/* 'none' means the color is not defined. */
30
private dev_color_proc_save_dc(gx_dc_no_save_dc);
31
private dev_color_proc_get_dev_halftone(gx_dc_no_get_dev_halftone);
32
private dev_color_proc_load(gx_dc_no_load);
33
private dev_color_proc_fill_rectangle(gx_dc_no_fill_rectangle);
34
private dev_color_proc_fill_masked(gx_dc_no_fill_masked);
35
private dev_color_proc_equal(gx_dc_no_equal);
36
private dev_color_proc_write(gx_dc_no_write);
37
private dev_color_proc_read(gx_dc_no_read);
38
private dev_color_proc_get_nonzero_comps(gx_dc_no_get_nonzero_comps);
39
const gx_device_color_type_t gx_dc_type_data_none = {
40
    &st_bytes,
41
    gx_dc_no_save_dc, gx_dc_no_get_dev_halftone, gx_dc_no_get_phase,
42
    gx_dc_no_load, gx_dc_no_fill_rectangle, gx_dc_no_fill_masked,
43
    gx_dc_no_equal, gx_dc_no_write, gx_dc_no_read, gx_dc_no_get_nonzero_comps
44
};
45
#undef gx_dc_type_none
46
const gx_device_color_type_t *const gx_dc_type_none = &gx_dc_type_data_none;
47
#define gx_dc_type_none (&gx_dc_type_data_none)
48
 
49
/* 'null' means the color has no effect when used for drawing. */
50
private dev_color_proc_load(gx_dc_null_load);
51
private dev_color_proc_fill_rectangle(gx_dc_null_fill_rectangle);
52
private dev_color_proc_fill_masked(gx_dc_null_fill_masked);
53
private dev_color_proc_equal(gx_dc_null_equal);
54
private dev_color_proc_read(gx_dc_null_read);
55
const gx_device_color_type_t gx_dc_type_data_null = {
56
    &st_bytes,
57
    gx_dc_no_save_dc, gx_dc_no_get_dev_halftone, gx_dc_no_get_phase,
58
    gx_dc_null_load, gx_dc_null_fill_rectangle, gx_dc_null_fill_masked,
59
    gx_dc_null_equal, gx_dc_no_write, gx_dc_null_read, gx_dc_no_get_nonzero_comps
60
};
61
#undef gx_dc_type_null
62
const gx_device_color_type_t *const gx_dc_type_null = &gx_dc_type_data_null;
63
#define gx_dc_type_null (&gx_dc_type_data_null)
64
 
65
private dev_color_proc_save_dc(gx_dc_pure_save_dc);
66
private dev_color_proc_load(gx_dc_pure_load);
67
private dev_color_proc_fill_rectangle(gx_dc_pure_fill_rectangle);
68
private dev_color_proc_fill_masked(gx_dc_pure_fill_masked);
69
private dev_color_proc_equal(gx_dc_pure_equal);
70
private dev_color_proc_write(gx_dc_pure_write);
71
private dev_color_proc_read(gx_dc_pure_read);
72
const gx_device_color_type_t gx_dc_type_data_pure = {
73
    &st_bytes,
74
    gx_dc_pure_save_dc, gx_dc_no_get_dev_halftone, gx_dc_no_get_phase,
75
    gx_dc_pure_load, gx_dc_pure_fill_rectangle, gx_dc_pure_fill_masked,
76
    gx_dc_pure_equal, gx_dc_pure_write, gx_dc_pure_read,
77
    gx_dc_pure_get_nonzero_comps
78
};
79
#undef gx_dc_type_pure
80
const gx_device_color_type_t *const gx_dc_type_pure = &gx_dc_type_data_pure;
81
#define gx_dc_type_pure (&gx_dc_type_data_pure)
82
 
83
/*
84
 * Get the black and white pixel values of a device.
85
 */
86
gx_color_index
87
gx_device_black(gx_device *dev)
88
{
89
    if (dev->cached_colors.black == gx_no_color_index) {
90
	const gx_cm_color_map_procs * cm_procs = dev_proc(dev, get_color_mapping_procs)(dev);
91
        int i, ncomps = dev->color_info.num_components;
92
        frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
93
        gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
94
 
95
    	/* Get color components for black (gray = 0) */
96
    	cm_procs->map_gray(dev, frac_0, cm_comps);
97
 
98
        for (i = 0; i < ncomps; i++)
99
            cv[i] = frac2cv(cm_comps[i]);
100
 
101
	dev->cached_colors.black = dev_proc(dev, encode_color)(dev, cv);
102
    }
103
    return dev->cached_colors.black;
104
}
105
gx_color_index
106
gx_device_white(gx_device *dev)
107
{
108
    if (dev->cached_colors.white == gx_no_color_index) {
109
	const gx_cm_color_map_procs * cm_procs = dev_proc(dev, get_color_mapping_procs)(dev);
110
        int i, ncomps = dev->color_info.num_components;
111
        frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
112
        gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
113
 
114
    	/* Get color components for white (gray = 1) */
115
    	cm_procs->map_gray(dev, frac_1, cm_comps);
116
 
117
        for (i = 0; i < ncomps; i++)
118
            cv[i] = frac2cv(cm_comps[i]);
119
 
120
	dev->cached_colors.white = dev_proc(dev, encode_color)(dev, cv);
121
    }
122
    return dev->cached_colors.white;
123
}
124
 
125
/* Clear the color cache. */
126
void
127
gx_device_decache_colors(gx_device *dev)
128
{
129
    dev->cached_colors.black = dev->cached_colors.white = gx_no_color_index;
130
}
131
 
132
/* Set a null RasterOp source. */
133
private const gx_rop_source_t gx_rop_no_source_0 = {gx_rop_no_source_body(0)};
134
private const gx_rop_source_t gx_rop_no_source_1 = {gx_rop_no_source_body(1)};
135
void
136
gx_set_rop_no_source(const gx_rop_source_t **psource,
137
		     gx_rop_source_t *pno_source, gx_device *dev)
138
{
139
    gx_color_index black;
140
 
141
top:
142
    black = dev->cached_colors.black;
143
    if (black == 0)
144
	*psource = &gx_rop_no_source_0;
145
    else if (black == 1)
146
	*psource = &gx_rop_no_source_1;
147
    else if (black == gx_no_color_index) {	/* cache not loaded */
148
	discard(gx_device_black(dev));
149
	goto top;
150
    } else {
151
	*pno_source = gx_rop_no_source_0;
152
	gx_rop_source_set_color(pno_source, black);
153
	*psource = pno_source;
154
    }
155
}
156
 
157
/*
158
 * Test device colors for equality.  Testing for equality is done
159
 * for determining when cache values, etc. can be used.  Thus these
160
 * routines should err toward false responses if there is any question
161
 * about the equality of the two device colors.
162
 */
163
bool
164
gx_device_color_equal(const gx_device_color *pdevc1,
165
		      const gx_device_color *pdevc2)
166
{
167
    return pdevc1->type->equal(pdevc1, pdevc2);
168
}
169
 
170
/*
171
 * Return a device color type index. This index is used by the command
172
 * list processor to identify a device color type, as the type pointer
173
 * itself is meaningful only within a single address space.
174
 *
175
 * Currently, we ignore the pattern device colors as they cannot be
176
 * passed through the command list.
177
 *
178
 * Returns gs_error_unknownerror for an unrecognized type.
179
 */
180
private  const gx_device_color_type_t * dc_color_type_table[] = {
181
    gx_dc_type_none,            /* unset device color */
182
    gx_dc_type_null,            /* blank (transparent) device color */
183
    gx_dc_type_pure,            /* pure device color */
184
    /* gx_dc_type_pattern, */   /* patterns - not used in command list */
185
    gx_dc_type_ht_binary,       /* binary halftone device colors */
186
    gx_dc_type_ht_colored,      /* general halftone device colors */
187
    gx_dc_type_wts              /* well-tempered screen device colors */
188
};
189
 
190
int
191
gx_get_dc_type_index(const gx_device_color * pdevc)
192
{
193
    const gx_device_color_type_t *  type = pdevc->type;
194
    int                             num_types, i;
195
 
196
    num_types = sizeof(dc_color_type_table) / sizeof(dc_color_type_table[0]);
197
    for (i = 0; i < num_types && type != dc_color_type_table[i]; i++)
198
        ;
199
 
200
    return i < num_types ? i : gs_error_unknownerror;
201
}
202
 
203
/* map a device color type index into the associated method vector */
204
const gx_device_color_type_t *
205
gx_get_dc_type_from_index(int i)
206
{
207
    if ( i >= 0                                                          &&
208
         i < sizeof(dc_color_type_table) / sizeof(dc_color_type_table[0])  )
209
        return dc_color_type_table[i];
210
    else
211
        return 0;
212
}
213
 
214
/* ------ Canonical get_phase methods ------ */
215
bool
216
gx_dc_no_get_phase(const gx_device_color * pdevc, gs_int_point * pphase)
217
{
218
    return false;
219
}
220
 
221
bool
222
gx_dc_ht_get_phase(const gx_device_color * pdevc, gs_int_point * pphase)
223
{
224
    *pphase = pdevc->phase;
225
    return true;
226
}
227
 
228
/* ------ Undefined color ------ */
229
private void
230
gx_dc_no_save_dc(const gx_device_color * pdevc, gx_device_color_saved * psdc)
231
{
232
    psdc->type = pdevc->type;
233
}
234
 
235
private const gx_device_halftone *
236
gx_dc_no_get_dev_halftone(const gx_device_color * pdevc)
237
{
238
    return 0;
239
}
240
 
241
private int
242
gx_dc_no_load(gx_device_color *pdevc, const gs_imager_state *ignore_pis,
243
	      gx_device *ignore_dev, gs_color_select_t ignore_select)
244
{
245
    return 0;
246
}
247
 
248
private int
249
gx_dc_no_fill_rectangle(const gx_device_color *pdevc, int x, int y,
250
			int w, int h, gx_device *dev,
251
			gs_logical_operation_t lop,
252
			const gx_rop_source_t *source)
253
{
254
    gx_device_color filler;
255
 
256
    if (w <= 0 || h <= 0)
257
	return 0;
258
    if (lop_uses_T(lop))
259
	return_error(gs_error_Fatal);
260
    set_nonclient_dev_color(&filler, 0);   /* any valid value for dev will do */
261
    return gx_dc_pure_fill_rectangle(&filler, x, y, w, h, dev, lop, source);
262
}
263
 
264
private int
265
gx_dc_no_fill_masked(const gx_device_color *pdevc, const byte *data,
266
		     int data_x, int raster, gx_bitmap_id id,
267
		     int x, int y, int w, int h, gx_device *dev,
268
		     gs_logical_operation_t lop, bool invert)
269
{
270
    if (w <= 0 || h <= 0)
271
	return 0;
272
    return_error(gs_error_Fatal);
273
}
274
 
275
private bool
276
gx_dc_no_equal(const gx_device_color *pdevc1, const gx_device_color *pdevc2)
277
{
278
    return false;
279
}
280
 
281
private int
282
gx_dc_no_write(
283
    const gx_device_color *         pdevc,      /* ignored */
284
    const gx_device_color_saved *   psdc,       /* ignored */
285
    const gx_device *               dev,        /* ignored */
286
    byte *                          data,       /* ignored */
287
    uint *                          psize )
288
{
289
    *psize = 0;
290
    return psdc != 0 && psdc->type == pdevc->type ? 1 : 0;
291
}
292
 
293
private int
294
gx_dc_no_read(
295
    gx_device_color *       pdevc,
296
    const gs_imager_state * pis,                /* ignored */
297
    const gx_device_color * prior_devc,         /* ignored */
298
    const gx_device *       dev,                /* ignored */
299
    const byte *            pdata,              /* ignored */
300
    uint                    size,               /* ignored */
301
    gs_memory_t *           mem )               /* ignored */
302
{
303
    pdevc->type = gx_dc_type_none;
304
    return 0;
305
}
306
 
307
private int
308
gx_dc_no_get_nonzero_comps(
309
    const gx_device_color * pdevc_ignored,
310
    const gx_device *       dev_ignored,
311
    gx_color_index *        pcomp_bits_ignored )
312
{
313
    return 0;
314
}
315
 
316
/* ------ Null color ------ */
317
 
318
private int
319
gx_dc_null_load(gx_device_color *pdevc, const gs_imager_state *ignore_pis,
320
		gx_device *ignore_dev, gs_color_select_t ignore_select)
321
{
322
    return 0;
323
}
324
 
325
private int
326
gx_dc_null_fill_rectangle(const gx_device_color * pdevc, int x, int y,
327
			  int w, int h, gx_device * dev,
328
			  gs_logical_operation_t lop,
329
			  const gx_rop_source_t * source)
330
{
331
    return 0;
332
}
333
 
334
private int
335
gx_dc_null_fill_masked(const gx_device_color * pdevc, const byte * data,
336
		       int data_x, int raster, gx_bitmap_id id,
337
		       int x, int y, int w, int h, gx_device * dev,
338
		       gs_logical_operation_t lop, bool invert)
339
{
340
    return 0;
341
}
342
 
343
private bool
344
gx_dc_null_equal(const gx_device_color * pdevc1, const gx_device_color * pdevc2)
345
{
346
    return pdevc2->type == pdevc1->type;
347
}
348
 
349
private int
350
gx_dc_null_read(
351
    gx_device_color *       pdevc,
352
    const gs_imager_state * pis,                /* ignored */
353
    const gx_device_color * prior_devc,         /* ignored */
354
    const gx_device *       dev,                /* ignored */
355
    const byte *            pdata,              /* ignored */
356
    uint                    size,               /* ignored */
357
    gs_memory_t *           mem )               /* ignored */
358
{
359
    pdevc->type = gx_dc_type_null;
360
    return 0;
361
}
362
 
363
/* ------ Pure color ------ */
364
 
365
private void
366
gx_dc_pure_save_dc(const gx_device_color * pdevc, gx_device_color_saved * psdc)
367
{
368
    psdc->type = pdevc->type;
369
    psdc->colors.pure = pdevc->colors.pure;
370
}
371
 
372
private int
373
gx_dc_pure_load(gx_device_color * pdevc, const gs_imager_state * ignore_pis,
374
		gx_device * ignore_dev, gs_color_select_t ignore_select)
375
{
376
    return 0;
377
}
378
 
379
/* Fill a rectangle with a pure color. */
380
/* Note that we treat this as "texture" for RasterOp. */
381
private int
382
gx_dc_pure_fill_rectangle(const gx_device_color * pdevc, int x, int y,
383
		  int w, int h, gx_device * dev, gs_logical_operation_t lop,
384
			  const gx_rop_source_t * source)
385
{
386
    if (source == NULL && lop_no_S_is_T(lop))
387
	return (*dev_proc(dev, fill_rectangle)) (dev, x, y, w, h,
388
						 pdevc->colors.pure);
389
    {
390
	gx_color_index colors[2];
391
	gx_rop_source_t no_source;
392
 
393
	colors[0] = colors[1] = pdevc->colors.pure;
394
	if (source == NULL)
395
	    set_rop_no_source(source, no_source, dev);
396
	return (*dev_proc(dev, strip_copy_rop))
397
	    (dev, source->sdata, source->sourcex, source->sraster,
398
	     source->id, (source->use_scolors ? source->scolors : NULL),
399
	     NULL /*arbitrary */ , colors, x, y, w, h, 0, 0, lop);
400
    }
401
}
402
 
403
/* Fill a mask with a pure color. */
404
/* Note that there is no source in this case: the mask is the source. */
405
private int
406
gx_dc_pure_fill_masked(const gx_device_color * pdevc, const byte * data,
407
	int data_x, int raster, gx_bitmap_id id, int x, int y, int w, int h,
408
		   gx_device * dev, gs_logical_operation_t lop, bool invert)
409
{
410
    if (lop_no_S_is_T(lop)) {
411
	gx_color_index color0, color1;
412
 
413
	if (invert)
414
	    color0 = pdevc->colors.pure, color1 = gx_no_color_index;
415
	else
416
	    color1 = pdevc->colors.pure, color0 = gx_no_color_index;
417
	return (*dev_proc(dev, copy_mono))
418
	    (dev, data, data_x, raster, id, x, y, w, h, color0, color1);
419
    } {
420
	gx_color_index scolors[2];
421
	gx_color_index tcolors[2];
422
 
423
	scolors[0] = gx_device_black(dev);
424
	scolors[1] = gx_device_white(dev);
425
	tcolors[0] = tcolors[1] = pdevc->colors.pure;
426
	return (*dev_proc(dev, strip_copy_rop))
427
	    (dev, data, data_x, raster, id, scolors,
428
	     NULL, tcolors, x, y, w, h, 0, 0,
429
	     (invert ? rop3_invert_S(lop) : lop) | lop_S_transparent);
430
    }
431
}
432
 
433
private bool
434
gx_dc_pure_equal(const gx_device_color * pdevc1, const gx_device_color * pdevc2)
435
{
436
    return pdevc2->type == pdevc1->type &&
437
	gx_dc_pure_color(pdevc1) == gx_dc_pure_color(pdevc2);
438
}
439
 
440
/*
441
 * Serialize a pure color.
442
 *
443
 * Operands:
444
 *
445
 *  pdevc       pointer to device color to be serialized
446
 *
447
 *  psdc        pointer ot saved version of last serialized color (for
448
 *              this band); this is ignored
449
 *  
450
 *  dev         pointer to the current device, used to retrieve process
451
 *              color model information
452
 *
453
 *  pdata       pointer to buffer in which to write the data
454
 *
455
 *  psize       pointer to a location that, on entry, contains the size of
456
 *              the buffer pointed to by pdata; on return, the size of
457
 *              the data required or actually used will be written here.
458
 *
459
 * Returns:
460
 *
461
 *  1, with *psize set to 0, if *pdevc and *psdc represent the same color
462
 *
463
 *  0, with *psize set to the amount of data written, if everything OK
464
 *
465
 *  gs_error_rangecheck, with *psize set to the size of buffer required,
466
 *  if *psize was not large enough
467
 *
468
 *  < 0, != gs_error_rangecheck, in the event of some other error; in this
469
 *  case *psize is not changed.
470
 */
471
private int
472
gx_dc_pure_write(
473
    const gx_device_color *         pdevc,
474
    const gx_device_color_saved *   psdc,       /* ignored */
475
    const gx_device *               dev,
476
    byte *                          pdata,
477
    uint *                          psize )
478
{
479
    if ( psdc != 0                              &&
480
         psdc->type == pdevc->type              &&
481
         psdc->colors.pure == pdevc->colors.pure  ) {
482
        *psize = 0;
483
        return 1;
484
    } else
485
        return gx_dc_write_color(pdevc->colors.pure, dev, pdata, psize);
486
}
487
 
488
/*
489
 * Reconstruct a pure device color from its serial representation.
490
 *
491
 * Operands:
492
 *
493
 *  pdevc       pointer to the location in which to write the
494
 *              reconstructed device color
495
 *
496
 *  pis         pointer to the current imager state (ignored here)
497
 *
498
 *  prior_devc  pointer to the current device color (this is provided
499
 *              separately because the device color is not part of the
500
 *              imager state; it is ignored here)
501
 *
502
 *  dev         pointer to the current device, used to retrieve process
503
 *              color model information
504
 *
505
 *  pdata       pointer to the buffer to be read
506
 *
507
 *  size        size of the buffer to be read; this should be large
508
 *              enough to hold the entire color description
509
 *
510
 *  mem         pointer to the memory to be used for allocations
511
 *              (ignored here)
512
 *
513
 * Returns:
514
 *
515
 *  # of bytes read if everthing OK, < 0 in the event of an error
516
 */
517
private int
518
gx_dc_pure_read(
519
    gx_device_color *       pdevc,
520
    const gs_imager_state * pis,                /* ignored */
521
    const gx_device_color * prior_devc,         /* ignored */
522
    const gx_device *       dev,
523
    const byte *            pdata,
524
    uint                    size,
525
    gs_memory_t *           mem )               /* ignored */
526
{
527
    pdevc->type = gx_dc_type_pure;
528
    return gx_dc_read_color(&pdevc->colors.pure, dev, pdata, size);
529
}
530
 
531
int
532
gx_dc_pure_get_nonzero_comps(
533
    const gx_device_color * pdevc,
534
    const gx_device *       dev,
535
    gx_color_index *        pcomp_bits )
536
{
537
    int                     code;
538
    gx_color_value          cvals[GX_DEVICE_COLOR_MAX_COMPONENTS];
539
 
540
    code = dev_proc(dev, decode_color)( (gx_device *)dev,
541
                                         pdevc->colors.pure,
542
                                         cvals );
543
    if (code >= 0) {
544
        int             i, ncomps = dev->color_info.num_components;
545
        gx_color_index  mask = 0x1, comp_bits = 0;
546
 
547
        for (i = 0; i < ncomps; i++, mask <<= 1) {
548
            if (cvals[i] != 0)
549
                comp_bits |= mask;
550
        }
551
        *pcomp_bits = comp_bits;
552
        code = 0;
553
    }
554
 
555
    return code;
556
}
557
 
558
/* ------ Halftone color initialization ------ */
559
 
560
void
561
gx_complete_halftone(gx_device_color *pdevc, int num_comps, gx_device_halftone *pdht)
562
{
563
    int i, mask = 0;
564
 
565
    pdevc->type = gx_dc_type_ht_colored;
566
    pdevc->colors.colored.c_ht = pdht;
567
    pdevc->colors.colored.num_components = num_comps;
568
    pdevc->colors.colored.alpha = max_ushort;
569
    for (i = 0; i < num_comps; i++)
570
        mask |= ((pdevc->colors.colored.c_level[i] != 0 ? 1 : 0) << i);
571
    pdevc->colors.colored.plane_mask = mask;
572
}
573
 
574
/* ------ Default implementations ------ */
575
 
576
/* Fill a mask with a color by parsing the mask into rectangles. */
577
int
578
gx_dc_default_fill_masked(const gx_device_color * pdevc, const byte * data,
579
	int data_x, int raster, gx_bitmap_id id, int x, int y, int w, int h,
580
		   gx_device * dev, gs_logical_operation_t lop, bool invert)
581
{
582
    int lbit = data_x & 7;
583
    const byte *row = data + (data_x >> 3);
584
    uint one = (invert ? 0 : 0xff);
585
    uint zero = one ^ 0xff;
586
    int iy;
587
 
588
    for (iy = 0; iy < h; ++iy, row += raster) {
589
	const byte *p = row;
590
	int bit = lbit;
591
	int left = w;
592
	int l0;
593
 
594
	while (left) {
595
	    int run, code;
596
 
597
	    /* Skip a run of zeros. */
598
	    run = byte_bit_run_length[bit][*p ^ one];
599
	    if (run) {
600
		if (run < 8) {
601
		    if (run >= left)
602
			break;	/* end of row while skipping */
603
		    bit += run, left -= run;
604
		} else if ((run -= 8) >= left)
605
		    break;	/* end of row while skipping */
606
		else {
607
		    left -= run;
608
		    ++p;
609
		    while (left > 8 && *p == zero)
610
			left -= 8, ++p;
611
		    run = byte_bit_run_length_0[*p ^ one];
612
		    if (run >= left)	/* run < 8 unless very last byte */
613
			break;	/* end of row while skipping */
614
		    else
615
			bit = run & 7, left -= run;
616
		}
617
	    }
618
	    l0 = left;
619
	    /* Scan a run of ones, and then paint it. */
620
	    run = byte_bit_run_length[bit][*p ^ zero];
621
	    if (run < 8) {
622
		if (run >= left)
623
		    left = 0;
624
		else
625
		    bit += run, left -= run;
626
	    } else if ((run -= 8) >= left)
627
		left = 0;
628
	    else {
629
		left -= run;
630
		++p;
631
		while (left > 8 && *p == one)
632
		    left -= 8, ++p;
633
		run = byte_bit_run_length_0[*p ^ zero];
634
		if (run >= left)	/* run < 8 unless very last byte */
635
		    left = 0;
636
		else
637
		    bit = run & 7, left -= run;
638
	    }
639
	    code = gx_device_color_fill_rectangle(pdevc,
640
			  x + w - l0, y + iy, l0 - left, 1, dev, lop, NULL);
641
	    if (code < 0)
642
		return code;
643
	}
644
    }
645
    return 0;
646
}
647
 
648
/* ------ Serialization identification support ------ */
649
 
650
/*
651
 * Utility to write a color index.  Currently, a very simple mechanism
652
 * is used, much simpler than that used by other command-list writers. This
653
 * should be sufficient for most situations.
654
 *
655
 * Operands:
656
 *
657
 *  color       color to be serialized.
658
 *
659
 *  dev         pointer to the current device, used to retrieve process
660
 *              color model information
661
 *
662
 *  pdata       pointer to buffer in which to write the data
663
 *
664
 *  psize       pointer to a location that, on entry, contains the size of
665
 *              the buffer pointed to by pdata; on return, the size of
666
 *              the data required or actually used will be written here.
667
 *
668
 * Returns:
669
 *
670
 *  0, with *psize set to the amount of data written, if everything OK
671
 *
672
 *  gs_error_rangecheck, with *psize set to the size of buffer required,
673
 *  if *psize was not large enough
674
 *
675
 *  < 0, != gs_error_rangecheck, in the event of some other error; in this
676
 *  case *psize is not changed.
677
 */
678
int
679
gx_dc_write_color(
680
    gx_color_index      color,
681
    const gx_device *   dev,
682
    byte *              pdata,
683
    uint *              psize )
684
{
685
    int                 depth = dev->color_info.depth;
686
    int                 num_bytes = (depth + 8) >> 3;   /* NB: +8, not +7 */
687
 
688
    /* gx_no_color_index is encoded as a single byte */
689
    if (color == gx_no_color_index)
690
        num_bytes = 1;
691
 
692
    /* check for adequate space */
693
    if (*psize < num_bytes) {
694
        *psize = num_bytes;
695
        return gs_error_rangecheck;
696
    }
697
    *psize = num_bytes;
698
 
699
    /* gx_no_color_index is a single byte of 0xff */
700
    if (color == gx_no_color_index) {
701
        *psize = 1;
702
        *pdata = 0xff;
703
    } else {
704
        if (depth < 8 * arch_sizeof_color_index)
705
            color &= ((gx_color_index)1 << depth) - 1;
706
        while (--num_bytes >= 0) {
707
            pdata[num_bytes] = color & 0xff;
708
            color >>= 8;
709
        }
710
    }
711
    return 0;
712
}
713
 
714
/*
715
 * Utility to reconstruct device color from its serial representation.
716
 *
717
 * Operands:
718
 *
719
 *  pcolor      pointer to the location in which to write the
720
 *              reconstucted color
721
 *
722
 *  dev         pointer to the current device, used to retrieve process
723
 *              color model information
724
 *
725
 *  pdata       pointer to the buffer to be read
726
 *
727
 *  size        size of the buffer to be read; this is expected to be
728
 *              large enough for the full color
729
 *
730
 * Returns: # of bytes read, or < 0 in the event of an error
731
 */
732
int
733
gx_dc_read_color(
734
    gx_color_index *    pcolor,
735
    const gx_device *   dev,
736
    const byte *        pdata,
737
    int                 size )
738
{
739
    gx_color_index      color = 0;
740
    int                 depth = dev->color_info.depth;
741
    int                 i, num_bytes = (depth + 8) >> 3;   /* NB: +8, not +7 */
742
 
743
    /* check that enough data has been provided */
744
    if (size < 1 || (pdata[0] != 0xff && size < num_bytes))
745
        return gs_error_rangecheck;
746
 
747
    /* check of gx_no_color_index */
748
    if (pdata[0] == 0xff) {
749
        *pcolor = gx_no_color_index;
750
        return 1;
751
    }
752
 
753
    /* num_bytes > arch_sizeof_color_index, discard first byte */
754
    for (i = (num_bytes >= arch_sizeof_color_index ? 1 : 0); i < num_bytes; i++)
755
        color = (color << 8) | pdata[i];
756
    *pcolor = color;
757
    return num_bytes;
758
}