1
/* Copyright (C) 2001-2006 Artifex Software, Inc.
4
This software is provided AS-IS with no warranty, either express or
7
This software is distributed under license and may not be copied, modified
8
or distributed except as expressly authorized under the terms of that
9
license. Refer to licensing information at http://www.artifex.com/
10
or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
11
San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information.
13
/* $Id: gdevdgbr.c 8250 2007-09-25 13:31:24Z giles $ */
14
/* Default implementation of device get_bits[_rectangle] */
25
gx_no_get_bits(gx_device * dev, int y, byte * data, byte ** actual_data)
27
return_error(gs_error_unknownerror);
30
gx_default_get_bits(gx_device * dev, int y, byte * data, byte ** actual_data)
32
* Hand off to get_bits_rectangle, being careful to avoid a
33
* possible recursion loop.
35
dev_proc_get_bits((*save_get_bits)) = dev_proc(dev, get_bits);
37
gs_get_bits_params_t params;
40
rect.p.x = 0, rect.p.y = y;
41
rect.q.x = dev->width, rect.q.y = y + 1;
43
(actual_data ? GB_RETURN_POINTER : 0) | GB_RETURN_COPY |
44
(GB_ALIGN_STANDARD | GB_OFFSET_0 | GB_RASTER_STANDARD |
45
/* No depth specified, we always use native colors. */
46
GB_PACKING_CHUNKY | GB_COLORS_NATIVE | GB_ALPHA_NONE);
48
params.raster = bitmap_raster(dev->width * dev->color_info.depth);
49
params.data[0] = data;
50
set_dev_proc(dev, get_bits, gx_no_get_bits);
51
code = (*dev_proc(dev, get_bits_rectangle))
52
(dev, &rect, ¶ms, NULL);
54
*actual_data = params.data[0];
55
set_dev_proc(dev, get_bits, save_get_bits);
60
* Determine whether we can satisfy a request by simply using the stored
61
* representation. dev is used only for color_info.{num_components, depth}.
64
requested_includes_stored(const gx_device *dev,
65
const gs_get_bits_params_t *requested,
66
const gs_get_bits_params_t *stored)
68
gs_get_bits_options_t both = requested->options & stored->options;
70
if (!(both & GB_PACKING_ALL))
72
if (stored->options & GB_SELECT_PLANES) {
74
* The device only provides a subset of the planes.
75
* Make sure it provides all the requested ones.
78
int n = (stored->options & GB_PACKING_BIT_PLANAR ?
79
dev->color_info.depth : dev->color_info.num_components);
81
if (!(requested->options & GB_SELECT_PLANES) ||
82
!(both & (GB_PACKING_PLANAR || GB_PACKING_BIT_PLANAR))
85
for (i = 0; i < n; ++i)
86
if (requested->data[i] && !stored->data[i])
89
if (both & GB_COLORS_NATIVE)
91
if (both & GB_COLORS_STANDARD_ALL) {
92
if ((both & GB_ALPHA_ALL) && (both & GB_DEPTH_ALL))
99
* Try to implement get_bits_rectangle by returning a pointer.
100
* Note that dev is used only for computing the default raster
101
* and for color_info.depth.
102
* This routine does not check x or h for validity.
105
gx_get_bits_return_pointer(gx_device * dev, int x, int h,
106
gs_get_bits_params_t *params,
107
const gs_get_bits_params_t *stored,
110
gs_get_bits_options_t options = params->options;
111
gs_get_bits_options_t both = options & stored->options;
113
if (!(options & GB_RETURN_POINTER) ||
114
!requested_includes_stored(dev, params, stored)
118
* See whether we can return the bits in place. Note that even if
119
* OFFSET_ANY isn't set, x_offset and x don't have to be equal: their
120
* bit offsets only have to match modulo align_bitmap_mod * 8 (to
121
* preserve alignment) if ALIGN_ANY isn't set, or mod 8 (since
122
* byte alignment is always required) if ALIGN_ANY is set.
125
int depth = dev->color_info.depth;
127
* For PLANAR devices, we assume that each plane consists of
128
* depth/num_components bits. This is wrong in general, but if
129
* the device wants something else, it should implement
130
* get_bits_rectangle itself.
133
(both & GB_PACKING_CHUNKY ?
134
gx_device_raster(dev, true) :
135
both & GB_PACKING_PLANAR ?
136
bitmap_raster(dev->color_info.depth /
137
dev->color_info.num_components * dev->width) :
138
both & GB_PACKING_BIT_PLANAR ?
139
bitmap_raster(dev->width) :
140
0 /* not possible */);
142
(options & (GB_RASTER_STANDARD | GB_RASTER_ANY) ? dev_raster :
146
if (h <= 1 || raster == dev_raster) {
148
(options & GB_OFFSET_ANY ? x :
149
options & GB_OFFSET_0 ? 0 : params->x_offset);
153
params->x_offset = x;
156
(options & GB_ALIGN_ANY ? 8 : align_bitmap_mod * 8);
157
int bit_offset = x - x_offset;
160
if (bit_offset & (align_mod - 1))
161
return -1; /* can't align */
162
if (depth & (depth - 1)) {
163
/* step = lcm(depth, align_mod) */
164
int step = depth / igcd(depth, align_mod) * align_mod;
166
bytes = bit_offset / step * step;
168
/* Use a faster algorithm if depth is a power of 2. */
169
bytes = bit_offset & (-depth & -(int)align_mod);
171
base = stored_base + arith_rshift(bytes, 3);
172
params->x_offset = (bit_offset - bytes) / depth;
175
GB_ALIGN_STANDARD | GB_RETURN_POINTER | GB_RASTER_STANDARD |
176
(stored->options & ~GB_PACKING_ALL) /*see below for PACKING*/ |
177
(params->x_offset == 0 ? GB_OFFSET_0 : GB_OFFSET_SPECIFIED);
178
if (both & GB_PACKING_CHUNKY) {
179
params->options |= GB_PACKING_CHUNKY;
180
params->data[0] = base;
183
(stored->options & GB_PACKING_BIT_PLANAR ?
184
(params->options |= GB_PACKING_BIT_PLANAR,
185
dev->color_info.depth) :
186
(params->options |= GB_PACKING_PLANAR,
187
dev->color_info.num_components));
190
for (i = 0; i < n; ++i)
191
if (!(both & GB_SELECT_PLANES) || stored->data[i] != 0) {
192
params->data[i] = base;
193
base += dev_raster * dev->height;
203
* Implement gx_get_bits_copy (see below) for the case of converting
204
* 4-bit CMYK to 24-bit RGB with standard mapping, used heavily by PCL.
207
gx_get_bits_copy_cmyk_1bit(byte *dest_line, uint dest_raster,
208
const byte *src_line, uint src_raster,
209
int src_bit, int w, int h)
211
for (; h > 0; dest_line += dest_raster, src_line += src_raster, --h) {
212
const byte *src = src_line;
213
byte *dest = dest_line;
214
bool hi = (src_bit & 4) != 0; /* last nibble processed was hi */
217
for (i = w; i > 0; dest += 3, --i) {
219
((hi = !hi)? *src >> 4 : *src++ & 0xf);
222
dest[0] = dest[1] = dest[2] = 0;
224
dest[0] = (byte)((pixel >> 3) - 1);
225
dest[1] = (byte)(((pixel >> 2) & 1) - 1);
226
dest[2] = (byte)(((pixel >> 1) & 1) - 1);
233
* Convert pixels between representations, primarily for get_bits_rectangle.
234
* stored indicates how the data are actually stored, and includes:
235
* - one option from the GB_PACKING group;
236
* - if h > 1, one option from the GB_RASTER group;
237
* - optionally (and normally), GB_COLORS_NATIVE;
238
* - optionally, one option each from the GB_COLORS_STANDARD, GB_DEPTH,
239
* and GB_ALPHA groups.
240
* Note that dev is used only for color mapping. This routine assumes that
241
* the stored data are aligned.
243
* Note: this routine does not check x, w, h for validity.
245
* The code for converting between standard and native colors has been
246
* factored out into single-use procedures strictly for readability.
247
* A good optimizing compiler would compile them in-line.
250
gx_get_bits_std_to_native(gx_device * dev, int x, int w, int h,
251
gs_get_bits_params_t * params,
252
const gs_get_bits_params_t *stored,
253
const byte * src_base, uint dev_raster,
254
int x_offset, uint raster),
255
gx_get_bits_native_to_std(gx_device * dev, int x, int w, int h,
256
gs_get_bits_params_t * params,
257
const gs_get_bits_params_t *stored,
258
const byte * src_base, uint dev_raster,
259
int x_offset, uint raster, uint std_raster);
261
gx_get_bits_copy(gx_device * dev, int x, int w, int h,
262
gs_get_bits_params_t * params,
263
const gs_get_bits_params_t *stored,
264
const byte * src_base, uint dev_raster)
266
gs_get_bits_options_t options = params->options;
267
gs_get_bits_options_t stored_options = stored->options;
268
int x_offset = (options & GB_OFFSET_0 ? 0 : params->x_offset);
269
int depth = dev->color_info.depth;
270
int bit_x = x * depth;
271
const byte *src = src_base;
273
* If the stored representation matches a requested representation,
274
* we can copy the data without any transformations.
276
bool direct_copy = requested_includes_stored(dev, params, stored);
280
* The request must include either GB_PACKING_CHUNKY or
281
* GB_PACKING_PLANAR + GB_SELECT_PLANES, GB_RETURN_COPY,
282
* and an offset and raster specification. In the planar case,
283
* the request must include GB_ALIGN_STANDARD, the stored
284
* representation must include GB_PACKING_CHUNKY, and both must
285
* include GB_COLORS_NATIVE.
287
if ((~options & GB_RETURN_COPY) ||
288
!(options & (GB_OFFSET_0 | GB_OFFSET_SPECIFIED)) ||
289
!(options & (GB_RASTER_STANDARD | GB_RASTER_SPECIFIED))
291
return_error(gs_error_rangecheck);
292
if (options & GB_PACKING_CHUNKY) {
293
byte *data = params->data[0];
294
int end_bit = (x_offset + w) * depth;
296
(options & GB_ALIGN_STANDARD ? bitmap_raster(end_bit) :
299
(options & GB_RASTER_STANDARD ? std_raster : params->raster);
300
int dest_bit_x = x_offset * depth;
301
int skew = bit_x - dest_bit_x;
304
* If the bit positions line up, use bytes_copy_rectangle.
305
* Since bytes_copy_rectangle doesn't require alignment,
306
* the bit positions only have to match within a byte,
307
* not within align_bitmap_mod bytes.
309
if (!(skew & 7) && direct_copy) {
310
int bit_w = w * depth;
312
bytes_copy_rectangle(data + (dest_bit_x >> 3), raster,
313
src + (bit_x >> 3), dev_raster,
314
((bit_x + bit_w + 7) >> 3) - (bit_x >> 3), h);
315
} else if (direct_copy) {
317
* Use the logic already in mem_mono_copy_mono to copy the
318
* bits to the destination. We do this one line at a time,
319
* to avoid having to allocate a line pointer table.
321
gx_device_memory tdev;
322
byte *line_ptr = data;
323
int bit_w = w * depth;
325
tdev.line_ptrs = &tdev.base;
326
for (; h > 0; line_ptr += raster, src += dev_raster, --h) {
327
/* Make sure the destination is aligned. */
328
int align = ALIGNMENT_MOD(line_ptr, align_bitmap_mod);
330
tdev.base = line_ptr - align;
331
/* set up parameters required by copy_mono's fit_copy */
332
tdev.width = dest_bit_x + (align << 3) + bit_w;
334
(*dev_proc(&mem_mono_device, copy_mono))
335
((gx_device *) & tdev, src, bit_x, dev_raster, gx_no_bitmap_id,
336
dest_bit_x + (align << 3), 0, bit_w, 1,
337
(gx_color_index) 0, (gx_color_index) 1);
339
} else if (options & ~stored_options & GB_COLORS_NATIVE) {
340
/* Convert standard colors to native. */
341
code = gx_get_bits_std_to_native(dev, x, w, h, params, stored,
342
src_base, dev_raster,
344
options = params->options;
346
/* Convert native colors to standard. */
347
code = gx_get_bits_native_to_std(dev, x, w, h, params, stored,
348
src_base, dev_raster,
349
x_offset, raster, std_raster);
350
options = params->options;
353
(options & (GB_COLORS_ALL | GB_ALPHA_ALL)) | GB_PACKING_CHUNKY |
354
(options & GB_COLORS_NATIVE ? 0 : options & GB_DEPTH_ALL) |
355
(options & GB_ALIGN_STANDARD ? GB_ALIGN_STANDARD : GB_ALIGN_ANY) |
357
(x_offset == 0 ? GB_OFFSET_0 : GB_OFFSET_SPECIFIED) |
358
(raster == std_raster ? GB_RASTER_STANDARD : GB_RASTER_SPECIFIED);
359
} else if (!(~options &
360
(GB_PACKING_PLANAR | GB_SELECT_PLANES | GB_ALIGN_STANDARD)) &&
361
(stored_options & GB_PACKING_CHUNKY) &&
362
((options & stored_options) & GB_COLORS_NATIVE)
364
int num_planes = dev->color_info.num_components;
365
int dest_depth = depth / num_planes;
366
bits_plane_t source, dest;
370
/* Make sure only one plane is being requested. */
371
for (i = 0; i < num_planes; ++i)
372
if (params->data[i] != 0) {
374
return_error(gs_error_rangecheck); /* > 1 plane */
377
source.data.read = src_base;
378
source.raster = dev_raster;
379
source.depth = depth;
381
dest.data.write = params->data[plane];
383
(options & GB_RASTER_STANDARD ?
384
bitmap_raster((x_offset + w) * dest_depth) : params->raster);
385
dest.depth = dest_depth;
387
return bits_extract_plane(&dest, &source,
388
(num_planes - 1 - plane) * dest_depth,
391
return_error(gs_error_rangecheck);
396
* Convert standard colors to native. Note that the source
397
* may have depths other than 8 bits per component.
400
gx_get_bits_std_to_native(gx_device * dev, int x, int w, int h,
401
gs_get_bits_params_t * params,
402
const gs_get_bits_params_t *stored,
403
const byte * src_base, uint dev_raster,
404
int x_offset, uint raster)
406
int depth = dev->color_info.depth;
407
int dest_bit_offset = x_offset * depth;
408
byte *dest_line = params->data[0] + (dest_bit_offset >> 3);
410
(stored->options & GB_COLORS_RGB ? 3 :
411
stored->options & GB_COLORS_CMYK ? 4 :
412
stored->options & GB_COLORS_GRAY ? 1 : -1);
413
int ncomp = ncolors +
414
((stored->options & (GB_ALPHA_FIRST | GB_ALPHA_LAST)) != 0);
415
int src_depth = GB_OPTIONS_DEPTH(stored->options);
416
int src_bit_offset = x * src_depth * ncomp;
417
const byte *src_line = src_base + (src_bit_offset >> 3);
418
gx_color_value src_max = (1 << src_depth) - 1;
419
#define v2cv(value) ((ulong)(value) * gx_max_color_value / src_max)
420
gx_color_value alpha_default = src_max;
422
params->options &= ~GB_COLORS_ALL | GB_COLORS_NATIVE;
423
for (; h > 0; dest_line += raster, src_line += dev_raster, --h) {
426
sample_load_declare_setup(src, sbit, src_line,
427
src_bit_offset & 7, src_depth);
428
sample_store_declare_setup(dest, dbit, dbyte, dest_line,
429
dest_bit_offset & 7, depth);
431
#define v2frac(value) ((long)(value) * frac_1 / src_max)
433
for (i = 0; i < w; ++i) {
435
frac sc[4], dc[GX_DEVICE_COLOR_MAX_COMPONENTS];
436
gx_color_value v[GX_DEVICE_COLOR_MAX_COMPONENTS], va = alpha_default;
437
gx_color_index pixel;
438
bool do_alpha = false;
439
const gx_cm_color_map_procs * map_procs;
441
map_procs = dev_proc(dev, get_color_mapping_procs)(dev);
443
/* Fetch the source data. */
444
if (stored->options & GB_ALPHA_FIRST) {
445
sample_load_next16(va, src, sbit, src_depth);
449
for (j = 0; j < ncolors; ++j) {
452
sample_load_next16(vj, src, sbit, src_depth);
455
if (stored->options & GB_ALPHA_LAST) {
456
sample_load_next16(va, src, sbit, src_depth);
461
/* Convert and store the pixel value. */
463
for (j = 0; j < ncolors; j++)
464
v[j] = frac2cv(sc[j]);
467
pixel = dev_proc(dev, map_rgb_alpha_color)
468
(dev, v[0], v[1], v[2], va);
473
map_procs->map_gray(dev, sc[0], dc);
476
map_procs->map_rgb(dev, 0, sc[0], sc[1], sc[2], dc);
479
map_procs->map_cmyk(dev, sc[0], sc[1], sc[2], sc[3], dc);
482
return_error(gs_error_rangecheck);
485
for (j = 0; j < dev->color_info.num_components; j++)
486
v[j] = frac2cv(dc[j]);
488
pixel = dev_proc(dev, encode_color)(dev, v);
490
sample_store_next_any(pixel, dest, dbit, depth, dbyte);
492
sample_store_flush(dest, dbit, depth, dbyte);
498
* Convert native colors to standard. Only GB_DEPTH_8 is supported.
501
gx_get_bits_native_to_std(gx_device * dev, int x, int w, int h,
502
gs_get_bits_params_t * params,
503
const gs_get_bits_params_t *stored,
504
const byte * src_base, uint dev_raster,
505
int x_offset, uint raster, uint std_raster)
507
int depth = dev->color_info.depth;
508
int src_bit_offset = x * depth;
509
const byte *src_line = src_base + (src_bit_offset >> 3);
510
gs_get_bits_options_t options = params->options;
512
(options & (GB_ALPHA_FIRST | GB_ALPHA_LAST) ? 4 : 3);
513
byte *dest_line = params->data[0] + x_offset * ncomp;
518
if (!(options & GB_DEPTH_8)) {
520
* We don't support general depths yet, or conversion between
521
* different formats. Punt.
523
return_error(gs_error_rangecheck);
526
/* Pick the representation that's most likely to be useful. */
527
if (options & GB_COLORS_RGB)
528
params->options = options &= ~GB_COLORS_STANDARD_ALL | GB_COLORS_RGB,
530
else if (options & GB_COLORS_CMYK)
531
params->options = options &= ~GB_COLORS_STANDARD_ALL | GB_COLORS_CMYK,
533
else if (options & GB_COLORS_GRAY)
534
params->options = options &= ~GB_COLORS_STANDARD_ALL | GB_COLORS_GRAY,
537
return_error(gs_error_rangecheck);
538
/* Recompute the destination raster based on the color space. */
539
if (options & GB_RASTER_STANDARD) {
540
uint end_byte = (x_offset + w) * dest_bytes;
542
raster = std_raster =
543
(options & GB_ALIGN_STANDARD ?
544
bitmap_raster(end_byte << 3) : end_byte);
546
/* Check for the one special case we care about. */
547
if (((options & (GB_COLORS_RGB | GB_ALPHA_FIRST | GB_ALPHA_LAST))
549
dev_proc(dev, map_color_rgb) == cmyk_1bit_map_color_rgb) {
550
gx_get_bits_copy_cmyk_1bit(dest_line, raster,
551
src_line, dev_raster,
552
src_bit_offset & 7, w, h);
555
if (options & (GB_ALPHA_FIRST | GB_ALPHA_LAST))
557
/* Clear the color translation cache. */
558
for (i = (depth > 4 ? 16 : 1 << depth); --i >= 0; )
560
for (; h > 0; dest_line += raster, src_line += dev_raster, --h) {
561
sample_load_declare_setup(src, bit, src_line,
562
src_bit_offset & 7, depth);
563
byte *dest = dest_line;
565
for (i = 0; i < w; ++i) {
566
gx_color_index pixel = 0;
567
gx_color_value rgba[4];
569
sample_load_next_any(pixel, src, bit, depth);
572
/* Use the value from the cache. */
573
memcpy(dest, mapped[pixel], dest_bytes);
577
mapped[pixel] = dest;
579
(*dev_proc(dev, map_color_rgb_alpha)) (dev, pixel, rgba);
580
if (options & GB_ALPHA_FIRST)
581
*dest++ = gx_color_value_to_byte(rgba[3]);
582
/* Convert to the requested color space. */
583
if (options & GB_COLORS_RGB) {
584
dest[0] = gx_color_value_to_byte(rgba[0]);
585
dest[1] = gx_color_value_to_byte(rgba[1]);
586
dest[2] = gx_color_value_to_byte(rgba[2]);
588
} else if (options & GB_COLORS_CMYK) {
589
/* Use the standard RGB to CMYK algorithm, */
590
/* with maximum black generation and undercolor removal. */
591
gx_color_value white = max(rgba[0], max(rgba[1], rgba[2]));
593
dest[0] = gx_color_value_to_byte(white - rgba[0]);
594
dest[1] = gx_color_value_to_byte(white - rgba[1]);
595
dest[2] = gx_color_value_to_byte(white - rgba[2]);
596
dest[3] = gx_color_value_to_byte(gx_max_color_value - white);
598
} else { /* GB_COLORS_GRAY */
599
/* Use the standard RGB to Gray algorithm. */
600
*dest++ = gx_color_value_to_byte(
601
((rgba[0] * (ulong) lum_red_weight) +
602
(rgba[1] * (ulong) lum_green_weight) +
603
(rgba[2] * (ulong) lum_blue_weight) +
604
(lum_all_weights / 2))
607
if (options & GB_ALPHA_LAST)
608
*dest++ = gx_color_value_to_byte(rgba[3]);
614
/* ------ Default implementations of get_bits_rectangle ------ */
617
gx_no_get_bits_rectangle(gx_device * dev, const gs_int_rect * prect,
618
gs_get_bits_params_t * params, gs_int_rect ** unread)
620
return_error(gs_error_unknownerror);
624
gx_default_get_bits_rectangle(gx_device * dev, const gs_int_rect * prect,
625
gs_get_bits_params_t * params, gs_int_rect ** unread)
627
dev_proc_get_bits_rectangle((*save_get_bits_rectangle)) =
628
dev_proc(dev, get_bits_rectangle);
629
int depth = dev->color_info.depth;
630
uint min_raster = (dev->width * depth + 7) >> 3;
631
gs_get_bits_options_t options = params->options;
634
/* Avoid a recursion loop. */
635
set_dev_proc(dev, get_bits_rectangle, gx_no_get_bits_rectangle);
637
* If the parameters are right, try to call get_bits directly. Note
638
* that this may fail if a device only implements get_bits_rectangle
639
* (not get_bits) for a limited set of options. Note also that this
640
* must handle the case of the recursive call from within
641
* get_bits_rectangle (see below): because of this, and only because
642
* of this, it must handle partial scan lines.
644
if (prect->q.y == prect->p.y + 1 &&
646
(GB_RETURN_COPY | GB_PACKING_CHUNKY | GB_COLORS_NATIVE)) &&
647
(options & (GB_ALIGN_STANDARD | GB_ALIGN_ANY)) &&
648
((options & (GB_OFFSET_0 | GB_OFFSET_ANY)) ||
649
((options & GB_OFFSET_SPECIFIED) && params->x_offset == 0)) &&
650
((options & (GB_RASTER_STANDARD | GB_RASTER_ANY)) ||
651
((options & GB_RASTER_SPECIFIED) &&
652
params->raster >= min_raster)) &&
655
byte *data = params->data[0];
658
if (!(prect->p.x == 0 && prect->q.x == dev->width)) {
659
/* Allocate an intermediate row buffer. */
660
row = gs_alloc_bytes(dev->memory, min_raster,
661
"gx_default_get_bits_rectangle");
664
code = gs_note_error(gs_error_VMerror);
668
code = (*dev_proc(dev, get_bits)) (dev, prect->p.y, row,
669
(params->options & GB_RETURN_POINTER) ? ¶ms->data[0]
673
if (prect->p.x == 0 && params->data[0] != row
674
&& params->options & GB_RETURN_POINTER) {
676
* get_bits returned an appropriate pointer: we can
677
* avoid doing any copying.
681
/* Copy the partial row into the supplied buffer. */
682
int width_bits = (prect->q.x - prect->p.x) * depth;
683
gx_device_memory tdev;
685
tdev.width = width_bits;
687
tdev.line_ptrs = &tdev.base;
689
code = (*dev_proc(&mem_mono_device, copy_mono))
690
((gx_device *) & tdev, row, prect->p.x * depth,
691
min_raster, gx_no_bitmap_id, 0, 0, width_bits, 1,
692
(gx_color_index) 0, (gx_color_index) 1);
693
params->data[0] = data;
695
gs_free_object(dev->memory, row,
696
"gx_default_get_bits_rectangle");
699
GB_ALIGN_STANDARD | GB_OFFSET_0 | GB_PACKING_CHUNKY |
700
GB_ALPHA_NONE | GB_COLORS_NATIVE | GB_RASTER_STANDARD |
701
(params->data[0] == data ? GB_RETURN_COPY : GB_RETURN_POINTER);
705
/* Do the transfer row-by-row using a buffer. */
706
int x = prect->p.x, w = prect->q.x - x;
707
int bits_per_pixel = depth;
710
if (options & GB_COLORS_STANDARD_ALL) {
712
* Make sure the row buffer can hold the standard color
713
* representation, in case the device decides to use it.
715
int bpc = GB_OPTIONS_MAX_DEPTH(options);
717
(options & GB_COLORS_CMYK ? 4 :
718
options & GB_COLORS_RGB ? 3 : 1) +
719
(options & (GB_ALPHA_ALL - GB_ALPHA_NONE) ? 1 : 0);
722
if (bpp > bits_per_pixel)
723
bits_per_pixel = bpp;
725
row = gs_alloc_bytes(dev->memory, (bits_per_pixel * w + 7) >> 3,
726
"gx_default_get_bits_rectangle");
728
code = gs_note_error(gs_error_VMerror);
730
uint dev_raster = gx_device_raster(dev, true);
732
(options & GB_RASTER_SPECIFIED ? params->raster :
733
options & GB_ALIGN_STANDARD ? bitmap_raster(depth * w) :
734
(depth * w + 7) >> 3);
736
gs_get_bits_params_t copy_params;
737
gs_get_bits_options_t copy_options =
738
(GB_ALIGN_STANDARD | GB_ALIGN_ANY) |
739
(GB_RETURN_COPY | GB_RETURN_POINTER) |
740
(GB_OFFSET_0 | GB_OFFSET_ANY) |
741
(GB_RASTER_STANDARD | GB_RASTER_ANY) | GB_PACKING_CHUNKY |
742
GB_COLORS_NATIVE | (options & (GB_DEPTH_ALL | GB_COLORS_ALL)) |
744
byte *dest = params->data[0];
747
rect.p.x = x, rect.q.x = x + w;
749
for (y = prect->p.y; y < prect->q.y; ++y) {
750
rect.p.y = y, rect.q.y = y + 1;
751
copy_params.options = copy_options;
752
copy_params.data[0] = row;
753
code = (*save_get_bits_rectangle)
754
(dev, &rect, ©_params, NULL);
757
if (copy_params.options & GB_OFFSET_0)
758
copy_params.x_offset = 0;
759
params->data[0] = dest + (y - prect->p.y) * raster;
760
code = gx_get_bits_copy(dev, copy_params.x_offset, w, 1,
761
params, ©_params,
762
copy_params.data[0], dev_raster);
766
gs_free_object(dev->memory, row, "gx_default_get_bits_rectangle");
767
params->data[0] = dest;
770
ret:set_dev_proc(dev, get_bits_rectangle, save_get_bits_rectangle);
771
return (code < 0 ? code : 0);