1 /* Copyright (C) 2001-2012 Artifex Software, Inc.
2 All Rights Reserved.
3
4 This software is provided AS-IS with no warranty, either express or
5 implied.
6
7 This software is distributed under license and may not be copied,
8 modified or distributed except as expressly authorized under the terms
9 of the license contained in the file LICENSE in this distribution.
10
11 Refer to licensing information at http://www.artifex.com or contact
12 Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael,
13 CA 94903, U.S.A., +1(415)492-9861, for further information.
14 */
15
16 /* Default implementation of device get_bits[_rectangle] */
17 #include "memory_.h"
18 #include "gx.h"
19 #include "gserrors.h"
20 #include "gxdevice.h"
21 #include "gxdevmem.h"
22 #include "gxgetbit.h"
23 #include "gxlum.h"
24 #include "gdevmem.h"
25 #include "gxdevsop.h"
26
27 int
gx_no_get_bits(gx_device * dev,int y,byte * data,byte ** actual_data)28 gx_no_get_bits(gx_device * dev, int y, byte * data, byte ** actual_data)
29 {
30 return_error(gs_error_unknownerror);
31 }
32 int
gx_default_get_bits(gx_device * dev,int y,byte * data,byte ** actual_data)33 gx_default_get_bits(gx_device * dev, int y, byte * data, byte ** actual_data)
34 { /*
35 * Hand off to get_bits_rectangle, being careful to avoid a
36 * possible recursion loop.
37 */
38 dev_proc_get_bits((*save_get_bits)) = dev_proc(dev, get_bits);
39 gs_int_rect rect;
40 gs_get_bits_params_t params;
41 int code;
42
43 rect.p.x = 0, rect.p.y = y;
44 rect.q.x = dev->width, rect.q.y = y + 1;
45 params.options =
46 (actual_data ? GB_RETURN_POINTER : 0) | GB_RETURN_COPY |
47 (GB_ALIGN_STANDARD | GB_OFFSET_0 | GB_RASTER_STANDARD |
48 /* No depth specified, we always use native colors. */
49 GB_PACKING_CHUNKY | GB_COLORS_NATIVE | GB_ALPHA_NONE);
50 params.x_offset = 0;
51 params.raster = bitmap_raster(dev->width * dev->color_info.depth);
52 params.data[0] = data;
53 set_dev_proc(dev, get_bits, gx_no_get_bits);
54 code = (*dev_proc(dev, get_bits_rectangle))
55 (dev, &rect, ¶ms, NULL);
56 if (actual_data)
57 *actual_data = params.data[0];
58 set_dev_proc(dev, get_bits, save_get_bits);
59 return code;
60 }
61
62 /*
63 * Determine whether we can satisfy a request by simply using the stored
64 * representation. dev is used only for color_info.{num_components, depth}.
65 */
66 static bool
requested_includes_stored(const gx_device * dev,const gs_get_bits_params_t * requested,const gs_get_bits_params_t * stored)67 requested_includes_stored(const gx_device *dev,
68 const gs_get_bits_params_t *requested,
69 const gs_get_bits_params_t *stored)
70 {
71 gs_get_bits_options_t both = requested->options & stored->options;
72
73 if (!(both & GB_PACKING_ALL))
74 return false;
75 if (stored->options & GB_SELECT_PLANES) {
76 /*
77 * The device only provides a subset of the planes.
78 * Make sure it provides all the requested ones.
79 */
80 int i;
81 int n = (stored->options & GB_PACKING_BIT_PLANAR ?
82 dev->color_info.depth : dev->color_info.num_components);
83
84 if (!(requested->options & GB_SELECT_PLANES) ||
85 !(both & (GB_PACKING_PLANAR || GB_PACKING_BIT_PLANAR))
86 )
87 return false;
88 for (i = 0; i < n; ++i)
89 if (requested->data[i] && !stored->data[i])
90 return false;
91 }
92 if (both & GB_COLORS_NATIVE)
93 return true;
94 if (both & GB_COLORS_STANDARD_ALL) {
95 if ((both & GB_ALPHA_ALL) && (both & GB_DEPTH_ALL))
96 return true;
97 }
98 return false;
99 }
100
101 /*
102 * Try to implement get_bits_rectangle by returning a pointer.
103 * Note that dev is used only for computing the default raster
104 * and for color_info.depth.
105 * This routine does not check x or h for validity.
106 */
107 int
gx_get_bits_return_pointer(gx_device * dev,int x,int h,gs_get_bits_params_t * params,const gs_get_bits_params_t * stored,byte ** stored_base)108 gx_get_bits_return_pointer(gx_device * dev, int x, int h,
109 gs_get_bits_params_t *params,
110 const gs_get_bits_params_t *stored,
111 byte **stored_base)
112 {
113 gs_get_bits_options_t options = params->options;
114 gs_get_bits_options_t both = options & stored->options;
115
116 if (!(options & GB_RETURN_POINTER) ||
117 !requested_includes_stored(dev, params, stored)
118 )
119 return -1;
120 /*
121 * See whether we can return the bits in place. Note that even if
122 * OFFSET_ANY isn't set, x_offset and x don't have to be equal: their
123 * bit offsets only have to match modulo align_bitmap_mod * 8 (to
124 * preserve alignment) if ALIGN_ANY isn't set, or mod 8 (since
125 * byte alignment is always required) if ALIGN_ANY is set.
126 */
127 {
128 int depth = dev->color_info.depth;
129 /*
130 * For PLANAR devices, we assume that each plane consists of
131 * depth/num_components bits. This is wrong in general, but if
132 * the device wants something else, it should implement
133 * get_bits_rectangle itself.
134 */
135 uint dev_raster =
136 (both & GB_PACKING_CHUNKY ?
137 gx_device_raster(dev, true) :
138 both & GB_PACKING_PLANAR ?
139 bitmap_raster(dev->color_info.depth /
140 dev->color_info.num_components * dev->width) :
141 both & GB_PACKING_BIT_PLANAR ?
142 bitmap_raster(dev->width) :
143 0 /* not possible */);
144 uint raster =
145 (options & (GB_RASTER_STANDARD | GB_RASTER_ANY) ? dev_raster :
146 params->raster);
147 byte *base;
148
149 if (h <= 1 || raster == dev_raster) {
150 int x_offset =
151 (options & GB_OFFSET_ANY ? x :
152 options & GB_OFFSET_0 ? 0 : params->x_offset);
153
154 if (x_offset == x) {
155 base = stored_base[0];
156 params->x_offset = x;
157 } else {
158 uint align_mod =
159 (options & GB_ALIGN_ANY ? 8 : align_bitmap_mod * 8);
160 int bit_offset = x - x_offset;
161 int bytes;
162
163 if (bit_offset & (align_mod - 1))
164 return -1; /* can't align */
165 if (depth & (depth - 1)) {
166 /* step = lcm(depth, align_mod) */
167 int step = depth / igcd(depth, align_mod) * align_mod;
168
169 bytes = bit_offset / step * step;
170 } else {
171 /* Use a faster algorithm if depth is a power of 2. */
172 bytes = bit_offset & (-depth & -(int)align_mod);
173 }
174 base = stored_base[0] + arith_rshift(bytes, 3);
175 params->x_offset = (bit_offset - bytes) / depth;
176 }
177 params->options =
178 GB_ALIGN_STANDARD | GB_RETURN_POINTER | GB_RASTER_STANDARD |
179 (stored->options & ~GB_PACKING_ALL) /*see below for PACKING*/ |
180 (params->x_offset == 0 ? GB_OFFSET_0 : GB_OFFSET_SPECIFIED);
181 if (both & GB_PACKING_CHUNKY) {
182 params->options |= GB_PACKING_CHUNKY;
183 params->data[0] = base;
184 } else {
185 int n =
186 (stored->options & GB_PACKING_BIT_PLANAR ?
187 (params->options |= GB_PACKING_BIT_PLANAR,
188 dev->color_info.depth) :
189 (params->options |= GB_PACKING_PLANAR,
190 dev->color_info.num_components));
191 int i;
192
193 for (i = 0; i < n; ++i) {
194 if (!(both & GB_SELECT_PLANES) || stored->data[i] != 0) {
195 params->data[i] = base;
196 }
197 if (i < n-1) {
198 base += stored_base[dev->height]-stored_base[0];
199 stored_base += dev->height;
200 }
201 }
202 }
203 return 0;
204 }
205 }
206 return -1;
207 }
208
209 /*
210 * Implement gx_get_bits_copy (see below) for the case of converting
211 * 4-bit CMYK to 24-bit RGB with standard mapping, used heavily by PCL.
212 */
213 static void
gx_get_bits_copy_cmyk_1bit(byte * dest_line,uint dest_raster,const byte * src_line,uint src_raster,int src_bit,int w,int h)214 gx_get_bits_copy_cmyk_1bit(byte *dest_line, uint dest_raster,
215 const byte *src_line, uint src_raster,
216 int src_bit, int w, int h)
217 {
218 for (; h > 0; dest_line += dest_raster, src_line += src_raster, --h) {
219 const byte *src = src_line;
220 byte *dest = dest_line;
221 bool hi = (src_bit & 4) != 0; /* last nibble processed was hi */
222 int i;
223
224 for (i = w; i > 0; dest += 3, --i) {
225 uint pixel =
226 ((hi = !hi)? *src >> 4 : *src++ & 0xf);
227
228 if (pixel & 1)
229 dest[0] = dest[1] = dest[2] = 0;
230 else {
231 dest[0] = (byte)((pixel >> 3) - 1);
232 dest[1] = (byte)(((pixel >> 2) & 1) - 1);
233 dest[2] = (byte)(((pixel >> 1) & 1) - 1);
234 }
235 }
236 }
237 }
238
239 /*
240 * Convert pixels between representations, primarily for get_bits_rectangle.
241 * stored indicates how the data are actually stored, and includes:
242 * - one option from the GB_PACKING group;
243 * - if h > 1, one option from the GB_RASTER group;
244 * - optionally (and normally), GB_COLORS_NATIVE;
245 * - optionally, one option each from the GB_COLORS_STANDARD, GB_DEPTH,
246 * and GB_ALPHA groups.
247 * Note that dev is used only for color mapping. This routine assumes that
248 * the stored data are aligned.
249 *
250 * Note: this routine does not check x, w, h for validity.
251 *
252 * The code for converting between standard and native colors has been
253 * factored out into single-use procedures strictly for readability.
254 * A good optimizing compiler would compile them in-line.
255 */
256 static int
257 gx_get_bits_std_to_native(gx_device * dev, int x, int w, int h,
258 gs_get_bits_params_t * params,
259 const gs_get_bits_params_t *stored,
260 const byte * src_base, uint dev_raster,
261 int x_offset, uint raster),
262 gx_get_bits_native_to_std(gx_device * dev, int x, int w, int h,
263 gs_get_bits_params_t * params,
264 const gs_get_bits_params_t *stored,
265 const byte * src_base, uint dev_raster,
266 int x_offset, uint raster, uint std_raster);
267 int
gx_get_bits_copy(gx_device * dev,int x,int w,int h,gs_get_bits_params_t * params,const gs_get_bits_params_t * stored,const byte * src_base,uint dev_raster)268 gx_get_bits_copy(gx_device * dev, int x, int w, int h,
269 gs_get_bits_params_t * params,
270 const gs_get_bits_params_t *stored,
271 const byte * src_base, uint dev_raster)
272 {
273 gs_get_bits_options_t options = params->options;
274 gs_get_bits_options_t stored_options = stored->options;
275 int x_offset = (options & GB_OFFSET_0 ? 0 : params->x_offset);
276 int depth = dev->color_info.depth;
277 int bit_x = x * depth;
278 const byte *src = src_base;
279 /*
280 * If the stored representation matches a requested representation,
281 * we can copy the data without any transformations.
282 */
283 bool direct_copy = requested_includes_stored(dev, params, stored);
284 int code = 0;
285
286 /*
287 * The request must include either GB_PACKING_CHUNKY or
288 * GB_PACKING_PLANAR + GB_SELECT_PLANES, GB_RETURN_COPY,
289 * and an offset and raster specification. In the planar case,
290 * the request must include GB_ALIGN_STANDARD, the stored
291 * representation must include GB_PACKING_CHUNKY, and both must
292 * include GB_COLORS_NATIVE.
293 */
294 if ((~options & GB_RETURN_COPY) ||
295 !(options & (GB_OFFSET_0 | GB_OFFSET_SPECIFIED)) ||
296 !(options & (GB_RASTER_STANDARD | GB_RASTER_SPECIFIED))
297 )
298 return_error(gs_error_rangecheck);
299 if (options & GB_PACKING_CHUNKY) {
300 byte *data = params->data[0];
301 int end_bit = (x_offset + w) * depth;
302 uint std_raster =
303 (options & GB_ALIGN_STANDARD ? bitmap_raster(end_bit) :
304 (end_bit + 7) >> 3);
305 uint raster =
306 (options & GB_RASTER_STANDARD ? std_raster : params->raster);
307 int dest_bit_x = x_offset * depth;
308 int skew = bit_x - dest_bit_x;
309
310 /*
311 * If the bit positions line up, use bytes_copy_rectangle.
312 * Since bytes_copy_rectangle doesn't require alignment,
313 * the bit positions only have to match within a byte,
314 * not within align_bitmap_mod bytes.
315 */
316 if (!(skew & 7) && direct_copy) {
317 int bit_w = w * depth;
318
319 bytes_copy_rectangle(data + (dest_bit_x >> 3), raster,
320 src + (bit_x >> 3), dev_raster,
321 ((bit_x + bit_w + 7) >> 3) - (bit_x >> 3), h);
322 } else if (direct_copy) {
323 /*
324 * Use the logic already in mem_mono_copy_mono to copy the
325 * bits to the destination. We do this one line at a time,
326 * to avoid having to allocate a line pointer table.
327 */
328 gx_device_memory tdev;
329 byte *line_ptr = data;
330 int bit_w = w * depth;
331
332 tdev.line_ptrs = &tdev.base;
333 for (; h > 0; line_ptr += raster, src += dev_raster, --h) {
334 /* Make sure the destination is aligned. */
335 int align = ALIGNMENT_MOD(line_ptr, align_bitmap_mod);
336
337 tdev.base = line_ptr - align;
338 /* set up parameters required by copy_mono's fit_copy */
339 tdev.width = dest_bit_x + (align << 3) + bit_w;
340 tdev.height = 1;
341 (*dev_proc(&mem_mono_device, copy_mono))
342 ((gx_device *) & tdev, src, bit_x, dev_raster, gx_no_bitmap_id,
343 dest_bit_x + (align << 3), 0, bit_w, 1,
344 (gx_color_index) 0, (gx_color_index) 1);
345 }
346 } else if (options & ~stored_options & GB_COLORS_NATIVE) {
347 /* Convert standard colors to native. */
348 code = gx_get_bits_std_to_native(dev, x, w, h, params, stored,
349 src_base, dev_raster,
350 x_offset, raster);
351 options = params->options;
352 } else {
353 /* Convert native colors to standard. */
354 code = gx_get_bits_native_to_std(dev, x, w, h, params, stored,
355 src_base, dev_raster,
356 x_offset, raster, std_raster);
357 options = params->options;
358 }
359 params->options =
360 (options & (GB_COLORS_ALL | GB_ALPHA_ALL)) | GB_PACKING_CHUNKY |
361 (options & GB_COLORS_NATIVE ? 0 : options & GB_DEPTH_ALL) |
362 (options & GB_ALIGN_STANDARD ? GB_ALIGN_STANDARD : GB_ALIGN_ANY) |
363 GB_RETURN_COPY |
364 (x_offset == 0 ? GB_OFFSET_0 : GB_OFFSET_SPECIFIED) |
365 (raster == std_raster ? GB_RASTER_STANDARD : GB_RASTER_SPECIFIED);
366 } else if (!(~options &
367 (GB_PACKING_PLANAR | GB_SELECT_PLANES | GB_ALIGN_STANDARD)) &&
368 (stored_options & GB_PACKING_CHUNKY) &&
369 ((options & stored_options) & GB_COLORS_NATIVE)
370 ) {
371 int num_planes = dev->color_info.num_components;
372 int dest_depth = depth / num_planes;
373 bits_plane_t source, dest;
374 int plane = -1;
375 int i;
376
377 /* Make sure only one plane is being requested. */
378 for (i = 0; i < num_planes; ++i)
379 if (params->data[i] != 0) {
380 if (plane >= 0)
381 return_error(gs_error_rangecheck); /* > 1 plane */
382 plane = i;
383 }
384 source.data.read = src_base;
385 source.raster = dev_raster;
386 source.depth = depth;
387 source.x = x;
388 dest.data.write = params->data[plane];
389 dest.raster =
390 (options & GB_RASTER_STANDARD ?
391 bitmap_raster((x_offset + w) * dest_depth) : params->raster);
392 dest.depth = dest_depth;
393 dest.x = x_offset;
394 return bits_extract_plane(&dest, &source,
395 (num_planes - 1 - plane) * dest_depth,
396 w, h);
397 } else
398 return_error(gs_error_rangecheck);
399 return code;
400 }
401
402 /*
403 * Convert standard colors to native. Note that the source
404 * may have depths other than 8 bits per component.
405 */
406 static int
gx_get_bits_std_to_native(gx_device * dev,int x,int w,int h,gs_get_bits_params_t * params,const gs_get_bits_params_t * stored,const byte * src_base,uint dev_raster,int x_offset,uint raster)407 gx_get_bits_std_to_native(gx_device * dev, int x, int w, int h,
408 gs_get_bits_params_t * params,
409 const gs_get_bits_params_t *stored,
410 const byte * src_base, uint dev_raster,
411 int x_offset, uint raster)
412 {
413 int depth = dev->color_info.depth;
414 int dest_bit_offset = x_offset * depth;
415 byte *dest_line = params->data[0] + (dest_bit_offset >> 3);
416 int ncolors =
417 (stored->options & GB_COLORS_RGB ? 3 :
418 stored->options & GB_COLORS_CMYK ? 4 :
419 stored->options & GB_COLORS_GRAY ? 1 : -1);
420 int ncomp = ncolors +
421 ((stored->options & (GB_ALPHA_FIRST | GB_ALPHA_LAST)) != 0);
422 int src_depth = GB_OPTIONS_DEPTH(stored->options);
423 int src_bit_offset = x * src_depth * ncomp;
424 const byte *src_line = src_base + (src_bit_offset >> 3);
425 gx_color_value src_max = (1 << src_depth) - 1;
426 #define v2cv(value) ((ulong)(value) * gx_max_color_value / src_max)
427 gx_color_value alpha_default = src_max;
428
429 params->options &= ~GB_COLORS_ALL | GB_COLORS_NATIVE;
430 for (; h > 0; dest_line += raster, src_line += dev_raster, --h) {
431 int i;
432
433 sample_load_declare_setup(src, sbit, src_line,
434 src_bit_offset & 7, src_depth);
435 sample_store_declare_setup(dest, dbit, dbyte, dest_line,
436 dest_bit_offset & 7, depth);
437
438 #define v2frac(value) ((long)(value) * frac_1 / src_max)
439
440 for (i = 0; i < w; ++i) {
441 int j;
442 frac sc[4], dc[GX_DEVICE_COLOR_MAX_COMPONENTS];
443 gx_color_value v[GX_DEVICE_COLOR_MAX_COMPONENTS], va = alpha_default;
444 gx_color_index pixel;
445 bool do_alpha = false;
446 const gx_cm_color_map_procs * map_procs;
447
448 map_procs = dev_proc(dev, get_color_mapping_procs)(dev);
449
450 /* Fetch the source data. */
451 if (stored->options & GB_ALPHA_FIRST) {
452 sample_load_next16(va, src, sbit, src_depth);
453 va = v2cv(va);
454 do_alpha = true;
455 }
456 for (j = 0; j < ncolors; ++j) {
457 gx_color_value vj;
458
459 sample_load_next16(vj, src, sbit, src_depth);
460 sc[j] = v2frac(vj);
461 }
462 if (stored->options & GB_ALPHA_LAST) {
463 sample_load_next16(va, src, sbit, src_depth);
464 va = v2cv(va);
465 do_alpha = true;
466 }
467
468 /* Convert and store the pixel value. */
469 if (do_alpha) {
470 for (j = 0; j < ncolors; j++)
471 v[j] = frac2cv(sc[j]);
472 if (ncolors == 1)
473 v[2] = v[1] = v[0];
474 pixel = dev_proc(dev, map_rgb_alpha_color)
475 (dev, v[0], v[1], v[2], va);
476 } else {
477
478 switch (ncolors) {
479 case 1:
480 map_procs->map_gray(dev, sc[0], dc);
481 break;
482 case 3:
483 map_procs->map_rgb(dev, 0, sc[0], sc[1], sc[2], dc);
484 break;
485 case 4:
486 map_procs->map_cmyk(dev, sc[0], sc[1], sc[2], sc[3], dc);
487 break;
488 default:
489 return_error(gs_error_rangecheck);
490 }
491
492 for (j = 0; j < dev->color_info.num_components; j++)
493 v[j] = frac2cv(dc[j]);
494
495 pixel = dev_proc(dev, encode_color)(dev, v);
496 }
497 sample_store_next_any(pixel, dest, dbit, depth, dbyte);
498 }
499 sample_store_flush(dest, dbit, depth, dbyte);
500 }
501 return 0;
502 }
503
504 /*
505 * Convert native colors to standard. Only GB_DEPTH_8 is supported.
506 */
507 static int
gx_get_bits_native_to_std(gx_device * dev,int x,int w,int h,gs_get_bits_params_t * params,const gs_get_bits_params_t * stored,const byte * src_base,uint dev_raster,int x_offset,uint raster,uint std_raster)508 gx_get_bits_native_to_std(gx_device * dev, int x, int w, int h,
509 gs_get_bits_params_t * params,
510 const gs_get_bits_params_t *stored,
511 const byte * src_base, uint dev_raster,
512 int x_offset, uint raster, uint std_raster)
513 {
514 int depth = dev->color_info.depth;
515 int src_bit_offset = x * depth;
516 const byte *src_line = src_base + (src_bit_offset >> 3);
517 gs_get_bits_options_t options = params->options;
518 int ncomp =
519 (options & (GB_ALPHA_FIRST | GB_ALPHA_LAST) ? 4 : 3);
520 byte *dest_line = params->data[0] + x_offset * ncomp;
521 byte *mapped[16];
522 int dest_bytes;
523 int i;
524
525 if (!(options & GB_DEPTH_8)) {
526 /*
527 * We don't support general depths yet, or conversion between
528 * different formats. Punt.
529 */
530 return_error(gs_error_rangecheck);
531 }
532
533 /* Pick the representation that's most likely to be useful. */
534 if (options & GB_COLORS_RGB)
535 params->options = options &= ~GB_COLORS_STANDARD_ALL | GB_COLORS_RGB,
536 dest_bytes = 3;
537 else if (options & GB_COLORS_CMYK)
538 params->options = options &= ~GB_COLORS_STANDARD_ALL | GB_COLORS_CMYK,
539 dest_bytes = 4;
540 else if (options & GB_COLORS_GRAY)
541 params->options = options &= ~GB_COLORS_STANDARD_ALL | GB_COLORS_GRAY,
542 dest_bytes = 1;
543 else
544 return_error(gs_error_rangecheck);
545 /* Recompute the destination raster based on the color space. */
546 if (options & GB_RASTER_STANDARD) {
547 uint end_byte = (x_offset + w) * dest_bytes;
548
549 raster = std_raster =
550 (options & GB_ALIGN_STANDARD ?
551 bitmap_raster(end_byte << 3) : end_byte);
552 }
553 /* Check for the one special case we care about, namely that we have a
554 * device that uses cmyk_1bit_map_cmyk_color, or equivalent. We do not
555 * check function pointers directly, as this is defeated by forwarding
556 * devices, but rather use a dev_spec_op. */
557 if (((options & (GB_COLORS_RGB | GB_ALPHA_FIRST | GB_ALPHA_LAST))
558 == GB_COLORS_RGB) &&
559 (dev_proc(dev, dev_spec_op)(dev, gxdso_is_std_cmyk_1bit, NULL, 0) > 0)) {
560 gx_get_bits_copy_cmyk_1bit(dest_line, raster,
561 src_line, dev_raster,
562 src_bit_offset & 7, w, h);
563 return 0;
564 }
565 if (options & (GB_ALPHA_FIRST | GB_ALPHA_LAST))
566 ++dest_bytes;
567 /* Clear the color translation cache. */
568 for (i = (depth > 4 ? 16 : 1 << depth); --i >= 0; )
569 mapped[i] = 0;
570 for (; h > 0; dest_line += raster, src_line += dev_raster, --h) {
571 sample_load_declare_setup(src, bit, src_line,
572 src_bit_offset & 7, depth);
573 byte *dest = dest_line;
574
575 for (i = 0; i < w; ++i) {
576 gx_color_index pixel = 0;
577 gx_color_value rgba[4];
578
579 sample_load_next_any(pixel, src, bit, depth);
580 if (pixel < 16) {
581 if (mapped[pixel]) {
582 /* Use the value from the cache. */
583 memcpy(dest, mapped[pixel], dest_bytes);
584 dest += dest_bytes;
585 continue;
586 }
587 mapped[pixel] = dest;
588 }
589 (*dev_proc(dev, map_color_rgb_alpha)) (dev, pixel, rgba);
590 if (options & GB_ALPHA_FIRST)
591 *dest++ = gx_color_value_to_byte(rgba[3]);
592 /* Convert to the requested color space. */
593 if (options & GB_COLORS_RGB) {
594 dest[0] = gx_color_value_to_byte(rgba[0]);
595 dest[1] = gx_color_value_to_byte(rgba[1]);
596 dest[2] = gx_color_value_to_byte(rgba[2]);
597 dest += 3;
598 } else if (options & GB_COLORS_CMYK) {
599 /* Use the standard RGB to CMYK algorithm, */
600 /* with maximum black generation and undercolor removal. */
601 gx_color_value white = max(rgba[0], max(rgba[1], rgba[2]));
602
603 dest[0] = gx_color_value_to_byte(white - rgba[0]);
604 dest[1] = gx_color_value_to_byte(white - rgba[1]);
605 dest[2] = gx_color_value_to_byte(white - rgba[2]);
606 dest[3] = gx_color_value_to_byte(gx_max_color_value - white);
607 dest += 4;
608 } else { /* GB_COLORS_GRAY */
609 /* Use the standard RGB to Gray algorithm. */
610 *dest++ = gx_color_value_to_byte(
611 ((rgba[0] * (ulong) lum_red_weight) +
612 (rgba[1] * (ulong) lum_green_weight) +
613 (rgba[2] * (ulong) lum_blue_weight) +
614 (lum_all_weights / 2))
615 / lum_all_weights);
616 }
617 if (options & GB_ALPHA_LAST)
618 *dest++ = gx_color_value_to_byte(rgba[3]);
619 }
620 }
621 return 0;
622 }
623
624 /* ------ Default implementations of get_bits_rectangle ------ */
625
626 int
gx_no_get_bits_rectangle(gx_device * dev,const gs_int_rect * prect,gs_get_bits_params_t * params,gs_int_rect ** unread)627 gx_no_get_bits_rectangle(gx_device * dev, const gs_int_rect * prect,
628 gs_get_bits_params_t * params, gs_int_rect ** unread)
629 {
630 return_error(gs_error_unknownerror);
631 }
632
633 int
gx_default_get_bits_rectangle(gx_device * dev,const gs_int_rect * prect,gs_get_bits_params_t * params,gs_int_rect ** unread)634 gx_default_get_bits_rectangle(gx_device * dev, const gs_int_rect * prect,
635 gs_get_bits_params_t * params, gs_int_rect ** unread)
636 {
637 dev_proc_get_bits_rectangle((*save_get_bits_rectangle)) =
638 dev_proc(dev, get_bits_rectangle);
639 int depth = dev->color_info.depth;
640 uint min_raster = (dev->width * depth + 7) >> 3;
641 gs_get_bits_options_t options = params->options;
642 int code;
643
644 /* Avoid a recursion loop. */
645 set_dev_proc(dev, get_bits_rectangle, gx_no_get_bits_rectangle);
646 /*
647 * If the parameters are right, try to call get_bits directly. Note
648 * that this may fail if a device only implements get_bits_rectangle
649 * (not get_bits) for a limited set of options. Note also that this
650 * must handle the case of the recursive call from within
651 * get_bits_rectangle (see below): because of this, and only because
652 * of this, it must handle partial scan lines.
653 */
654 if (prect->q.y == prect->p.y + 1 &&
655 !(~options &
656 (GB_RETURN_COPY | GB_PACKING_CHUNKY | GB_COLORS_NATIVE)) &&
657 (options & (GB_ALIGN_STANDARD | GB_ALIGN_ANY)) &&
658 ((options & (GB_OFFSET_0 | GB_OFFSET_ANY)) ||
659 ((options & GB_OFFSET_SPECIFIED) && params->x_offset == 0)) &&
660 ((options & (GB_RASTER_STANDARD | GB_RASTER_ANY)) ||
661 ((options & GB_RASTER_SPECIFIED) &&
662 params->raster >= min_raster)) &&
663 unread == NULL
664 ) {
665 byte *data = params->data[0];
666 byte *row = data;
667
668 if (!(prect->p.x == 0 && prect->q.x == dev->width)) {
669 /* Allocate an intermediate row buffer. */
670 row = gs_alloc_bytes(dev->memory, min_raster,
671 "gx_default_get_bits_rectangle");
672
673 if (row == 0) {
674 code = gs_note_error(gs_error_VMerror);
675 goto ret;
676 }
677 }
678 code = (*dev_proc(dev, get_bits)) (dev, prect->p.y, row,
679 (params->options & GB_RETURN_POINTER) ? ¶ms->data[0]
680 : NULL );
681 if (code >= 0) {
682 if (row != data) {
683 if (prect->p.x == 0 && params->data[0] != row
684 && params->options & GB_RETURN_POINTER) {
685 /*
686 * get_bits returned an appropriate pointer: we can
687 * avoid doing any copying.
688 */
689 DO_NOTHING;
690 } else {
691 /* Copy the partial row into the supplied buffer. */
692 int width_bits = (prect->q.x - prect->p.x) * depth;
693 gx_device_memory tdev;
694
695 tdev.width = width_bits;
696 tdev.height = 1;
697 tdev.line_ptrs = &tdev.base;
698 tdev.base = data;
699 tdev.raster = bitmap_raster(width_bits);
700 code = (*dev_proc(&mem_mono_device, copy_mono))
701 ((gx_device *) & tdev,
702 (params->options & GB_RETURN_POINTER) ? params->data[0] : row,
703 prect->p.x * depth,
704 min_raster, gx_no_bitmap_id, 0, 0, width_bits, 1,
705 (gx_color_index) 0, (gx_color_index) 1);
706 params->data[0] = data;
707 }
708 gs_free_object(dev->memory, row,
709 "gx_default_get_bits_rectangle");
710 }
711 params->options =
712 GB_ALIGN_STANDARD | GB_OFFSET_0 | GB_PACKING_CHUNKY |
713 GB_ALPHA_NONE | GB_COLORS_NATIVE | GB_RASTER_STANDARD |
714 (params->data[0] == data ? GB_RETURN_COPY : GB_RETURN_POINTER);
715 goto ret;
716 }
717 } {
718 /* Do the transfer row-by-row using a buffer. */
719 int x = prect->p.x, w = prect->q.x - x;
720 int bits_per_pixel = depth;
721 byte *row;
722
723 if (options & GB_COLORS_STANDARD_ALL) {
724 /*
725 * Make sure the row buffer can hold the standard color
726 * representation, in case the device decides to use it.
727 */
728 int bpc = GB_OPTIONS_MAX_DEPTH(options);
729 int nc =
730 (options & GB_COLORS_CMYK ? 4 :
731 options & GB_COLORS_RGB ? 3 : 1) +
732 (options & (GB_ALPHA_ALL - GB_ALPHA_NONE) ? 1 : 0);
733 int bpp = bpc * nc;
734
735 if (bpp > bits_per_pixel)
736 bits_per_pixel = bpp;
737 }
738 row = gs_alloc_bytes(dev->memory, (bits_per_pixel * w + 7) >> 3,
739 "gx_default_get_bits_rectangle");
740 if (row == 0) {
741 code = gs_note_error(gs_error_VMerror);
742 } else {
743 uint dev_raster = gx_device_raster(dev, true);
744 uint raster =
745 (options & GB_RASTER_SPECIFIED ? params->raster :
746 options & GB_ALIGN_STANDARD ? bitmap_raster(depth * w) :
747 (depth * w + 7) >> 3);
748 gs_int_rect rect;
749 gs_get_bits_params_t copy_params;
750 gs_get_bits_options_t copy_options =
751 (GB_ALIGN_STANDARD | GB_ALIGN_ANY) |
752 (GB_RETURN_COPY | GB_RETURN_POINTER) |
753 (GB_OFFSET_0 | GB_OFFSET_ANY) |
754 (GB_RASTER_STANDARD | GB_RASTER_ANY) | GB_PACKING_CHUNKY |
755 GB_COLORS_NATIVE | (options & (GB_DEPTH_ALL | GB_COLORS_ALL)) |
756 GB_ALPHA_ALL;
757 byte *dest = params->data[0];
758 int y;
759
760 rect.p.x = x, rect.q.x = x + w;
761 code = 0;
762 for (y = prect->p.y; y < prect->q.y; ++y) {
763 rect.p.y = y, rect.q.y = y + 1;
764 copy_params.options = copy_options;
765 copy_params.data[0] = row;
766 code = (*save_get_bits_rectangle)
767 (dev, &rect, ©_params, NULL);
768 if (code < 0)
769 break;
770 if (copy_params.options & GB_OFFSET_0)
771 copy_params.x_offset = 0;
772 params->data[0] = dest + (y - prect->p.y) * raster;
773 code = gx_get_bits_copy(dev, copy_params.x_offset, w, 1,
774 params, ©_params,
775 copy_params.data[0], dev_raster);
776 if (code < 0)
777 break;
778 }
779 gs_free_object(dev->memory, row, "gx_default_get_bits_rectangle");
780 params->data[0] = dest;
781 }
782 }
783 ret:set_dev_proc(dev, get_bits_rectangle, save_get_bits_rectangle);
784 return (code < 0 ? code : 0);
785 }
786