]> git.ipfire.org Git - thirdparty/cups.git/blob - pstoraster/gdevdgbr.c
Import cups.org releases
[thirdparty/cups.git] / pstoraster / gdevdgbr.c
1 /* Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved.
2
3 This file is part of GNU Ghostscript.
4
5 GNU Ghostscript is distributed in the hope that it will be useful, but
6 WITHOUT ANY WARRANTY. No author or distributor accepts responsibility
7 to anyone for the consequences of using it or for whether it serves any
8 particular purpose or works at all, unless he says so in writing. Refer
9 to the GNU General Public License for full details.
10
11 Everyone is granted permission to copy, modify and redistribute GNU
12 Ghostscript, but only under the conditions described in the GNU General
13 Public License. A copy of this license is supposed to have been given
14 to you along with GNU Ghostscript so you can know your rights and
15 responsibilities. It should be in a file named COPYING. Among other
16 things, the copyright notice and this notice must be preserved on all
17 copies.
18
19 Aladdin Enterprises supports the work of the GNU Project, but is not
20 affiliated with the Free Software Foundation or the GNU Project. GNU
21 Ghostscript, as distributed by Aladdin Enterprises, does not require any
22 GNU software to build or run it.
23 */
24
25 /*$Id$ */
26 /* Default implementation of device get_bits[_rectangle] */
27 #include "gx.h"
28 #include "gserrors.h"
29 #include "gxdevice.h"
30 #include "gxdevmem.h"
31 #include "gxgetbit.h"
32 #include "gxlum.h"
33 #include "gdevmem.h"
34
35 int
36 gx_no_get_bits(gx_device * dev, int y, byte * data, byte ** actual_data)
37 {
38 return_error(gs_error_unknownerror);
39 }
40 int
41 gx_default_get_bits(gx_device * dev, int y, byte * data, byte ** actual_data)
42 { /*
43 * Hand off to get_bits_rectangle, being careful to avoid a
44 * possible recursion loop.
45 */
46 dev_proc_get_bits((*save_get_bits)) = dev_proc(dev, get_bits);
47 gs_int_rect rect;
48 gs_get_bits_params_t params;
49 int code;
50
51 rect.p.x = 0, rect.p.y = y;
52 rect.q.x = dev->width, rect.q.y = y + 1;
53 params.options =
54 (actual_data ? GB_RETURN_POINTER : 0) | GB_RETURN_COPY |
55 (GB_ALIGN_STANDARD | GB_OFFSET_0 | GB_RASTER_STANDARD |
56 /* No depth specified, we always use native colors. */
57 GB_PACKING_CHUNKY | GB_COLORS_NATIVE | GB_ALPHA_NONE);
58 params.x_offset = 0;
59 params.raster = bitmap_raster(dev->width * dev->color_info.depth);
60 params.data[0] = data;
61 set_dev_proc(dev, get_bits, gx_no_get_bits);
62 code = (*dev_proc(dev, get_bits_rectangle))
63 (dev, &rect, &params, NULL);
64 if (actual_data)
65 *actual_data = params.data[0];
66 set_dev_proc(dev, get_bits, save_get_bits);
67 return code;
68 }
69
70 /*
71 * Determine whether we can satisfy a request by simply using the stored
72 * representation.
73 */
74 private bool
75 requested_includes_stored(gs_get_bits_options_t requested,
76 gs_get_bits_options_t stored)
77 {
78 gs_get_bits_options_t both = requested & stored;
79
80 if (!(both & GB_PACKING_ALL))
81 return false;
82 if (both & GB_COLORS_NATIVE)
83 return true;
84 if (both & GB_COLORS_STANDARD_ALL) {
85 if ((both & GB_ALPHA_ALL) && (both & GB_DEPTH_ALL))
86 return true;
87 }
88 return false;
89 }
90
91 /*
92 * Try to implement get_bits_rectangle by returning a pointer.
93 * Note that dev is used only for computing the default raster
94 * and for color_info.depth.
95 * This routine does not check x or h for validity.
96 */
97 int
98 gx_get_bits_return_pointer(gx_device * dev, int x, int h,
99 gs_get_bits_params_t * params, gs_get_bits_options_t stored,
100 byte * stored_base)
101 {
102 gs_get_bits_options_t options = params->options;
103
104 if (!(options & GB_RETURN_POINTER) ||
105 !requested_includes_stored(options, stored)
106 )
107 return -1;
108 /*
109 * See whether we can return the bits in place. Note that even if
110 * offset_any isn't set, x_offset and x don't have to be equal: their
111 * bit offsets only have to match modulo align_bitmap_mod * 8 (to
112 * preserve alignment) if align_any isn't set, or mod 8 (since
113 * byte alignment is always required) if align_any is set.
114 */
115 {
116 int depth = dev->color_info.depth;
117 uint dev_raster = gx_device_raster(dev, 1);
118 uint raster =
119 (options & (GB_RASTER_STANDARD | GB_RASTER_ANY) ? dev_raster :
120 params->raster);
121
122 if (h <= 1 || raster == dev_raster) {
123 int x_offset =
124 (options & GB_OFFSET_ANY ? x :
125 options & GB_OFFSET_0 ? 0 : params->x_offset);
126
127 if (x_offset == x) {
128 params->data[0] = stored_base;
129 params->x_offset = x;
130 } else {
131 uint align_mod =
132 (options & GB_ALIGN_ANY ? 8 : align_bitmap_mod * 8);
133 int bit_offset = x - x_offset;
134 int bytes;
135
136 if (bit_offset & (align_mod - 1))
137 return -1; /* can't align */
138 if (depth & (depth - 1)) {
139 /* step = lcm(depth, align_mod) */
140 int step = depth / igcd(depth, align_mod) * align_mod;
141
142 bytes = bit_offset / step * step;
143 } else {
144 /* Use a faster algorithm if depth is a power of 2. */
145 bytes = bit_offset & (-depth & -align_mod);
146 }
147 params->data[0] = stored_base + arith_rshift(bytes, 3);
148 params->x_offset = (bit_offset - bytes) / depth;
149 }
150 params->options =
151 GB_ALIGN_STANDARD | GB_RETURN_POINTER | GB_RASTER_STANDARD |
152 GB_PACKING_CHUNKY | stored |
153 (params->x_offset == 0 ? GB_OFFSET_0 : GB_OFFSET_SPECIFIED);
154 return 0;
155 }
156 }
157 return -1;
158 }
159
160 /*
161 * Convert pixels between representations, primarily for get_bits_rectangle.
162 * stored indicates how the data are actually stored, and includes:
163 * - one option from the GB_PACKING group;
164 * - if h > 1, one option from the GB_RASTER group;
165 * - optionally (and normally), GB_COLORS_NATIVE;
166 * - optionally, one option each from the GB_COLORS_STANDARD, GB_DEPTH,
167 * and GB_ALPHA groups.
168 * Note that dev is used only for color mapping. This routine assumes that
169 * the stored data are aligned.
170 *
171 * Note: this routine does not check x, w, h for validity.
172 */
173 int
174 gx_get_bits_copy(gx_device * dev, int x, int w, int h,
175 gs_get_bits_params_t * params, gs_get_bits_options_t stored,
176 const byte * src_base, uint dev_raster)
177 {
178 gs_get_bits_options_t options = params->options;
179 byte *data = params->data[0];
180 int depth = dev->color_info.depth;
181 int bit_x = x * depth;
182 const byte *src = src_base;
183
184 /*
185 * If the stored representation matches a requested representation,
186 * we can copy the data without any transformations.
187 */
188 bool direct_copy = requested_includes_stored(options, stored);
189
190 /*
191 * The request must include GB_PACKING_CHUNKY, GB_RETURN_COPY,
192 * and an offset and raster specification.
193 */
194 if ((~options & (GB_PACKING_CHUNKY | GB_RETURN_COPY)) ||
195 !(options & (GB_OFFSET_0 | GB_OFFSET_SPECIFIED)) ||
196 !(options & (GB_RASTER_STANDARD | GB_RASTER_SPECIFIED))
197 )
198 return_error(gs_error_rangecheck);
199 {
200 int x_offset = (options & GB_OFFSET_0 ? 0 : params->x_offset);
201 int end_bit = (x_offset + w) * depth;
202 uint std_raster =
203 (options & GB_ALIGN_STANDARD ? bitmap_raster(end_bit) :
204 (end_bit + 7) >> 3);
205 uint raster =
206 (options & GB_RASTER_STANDARD ? std_raster : params->raster);
207 int dest_bit_x = x_offset * depth;
208 int skew = bit_x - dest_bit_x;
209
210 /*
211 * If the bit positions line up, use bytes_copy_rectangle.
212 * Since bytes_copy_rectangle doesn't require alignment,
213 * the bit positions only have to match within a byte,
214 * not within align_bitmap_mod bytes.
215 */
216 if (!(skew & 7) && direct_copy) {
217 int bit_w = w * depth;
218
219 bytes_copy_rectangle(data + (dest_bit_x >> 3), raster,
220 src + (bit_x >> 3), dev_raster,
221 ((bit_x + bit_w + 7) >> 3) - (bit_x >> 3), h);
222 } else if (direct_copy) {
223 /*
224 * Use the logic already in mem_mono_copy_mono to copy the
225 * bits to the destination. We do this one line at a time,
226 * to avoid having to allocate a line pointer table.
227 */
228 gx_device_memory tdev;
229 byte *line_ptr = data;
230
231 tdev.line_ptrs = &tdev.base;
232 for (; h > 0; line_ptr += raster, src += dev_raster, --h) {
233 /* Make sure the destination is aligned. */
234 int align = alignment_mod(line_ptr, align_bitmap_mod);
235
236 tdev.base = line_ptr - align;
237 (*dev_proc(&mem_mono_device, copy_mono))
238 ((gx_device *) & tdev, src, bit_x, dev_raster, gx_no_bitmap_id,
239 dest_bit_x + (align << 3), 0, w, 1,
240 (gx_color_index) 0, (gx_color_index) 1);
241 }
242 } else if (options & ~stored & GB_COLORS_NATIVE) {
243 /*
244 * Convert standard colors to native. Note that the source
245 * may have depths other than 8 bits per component.
246 */
247 int dest_bit_offset = x_offset * depth;
248 byte *dest_line = data + (dest_bit_offset >> 3);
249 int ncolors =
250 (stored & GB_COLORS_RGB ? 3 : stored & GB_COLORS_CMYK ? 4 :
251 stored & GB_COLORS_GRAY ? 1 : -1);
252 int ncomp = ncolors +
253 ((stored & (GB_ALPHA_FIRST | GB_ALPHA_LAST)) != 0);
254 int src_depth = GB_OPTIONS_DEPTH(stored);
255 int src_bit_offset = x * src_depth * ncomp;
256 const byte *src_line = src_base + (src_bit_offset >> 3);
257 gx_color_value src_max = (1 << src_depth) - 1;
258
259 #define v2cv(value) ((ulong)(value) * gx_max_color_value / src_max)
260 gx_color_value alpha_default = src_max;
261
262 options &= ~GB_COLORS_ALL | GB_COLORS_NATIVE;
263 for (; h > 0; dest_line += raster, src_line += dev_raster, --h) {
264 int i;
265
266 sample_load_declare_setup(src, sbit, src_line,
267 src_bit_offset & 7, src_depth);
268 sample_store_declare_setup(dest, dbit, dbyte, dest_line,
269 dest_bit_offset & 7, depth);
270
271 for (i = 0; i < w; ++i) {
272 int j;
273 gx_color_value v[4], va = alpha_default;
274 gx_color_index pixel;
275
276 /* Fetch the source data. */
277 if (stored & GB_ALPHA_FIRST) {
278 sample_load_next16(va, src, sbit, src_depth);
279 va = v2cv(va);
280 }
281 for (j = 0; j < ncolors; ++j) {
282 gx_color_value vj;
283
284 sample_load_next16(vj, src, sbit, src_depth);
285 v[j] = v2cv(vj);
286 }
287 if (stored & GB_ALPHA_LAST) {
288 sample_load_next16(va, src, sbit, src_depth);
289 va = v2cv(va);
290 }
291 /* Convert and store the pixel value. */
292 switch (ncolors) {
293 case 1:
294 v[2] = v[1] = v[0];
295 case 3:
296 pixel = (*dev_proc(dev, map_rgb_alpha_color))
297 (dev, v[0], v[1], v[2], va);
298 break;
299 case 4:
300 /****** NO ALPHA FOR CMYK ******/
301 pixel = (*dev_proc(dev, map_cmyk_color))
302 (dev, v[0], v[1], v[2], v[3]);
303 break;
304 default:
305 return_error(gs_error_rangecheck);
306 }
307 sample_store_next32(pixel, dest, dbit, depth, dbyte);
308 }
309 sample_store_flush(dest, dbit, depth, dbyte);
310 }
311 } else if (!(options & GB_DEPTH_8)) {
312 /*
313 * We don't support general depths yet, or conversion between
314 * different formats. Punt.
315 */
316 return_error(gs_error_rangecheck);
317 } else {
318 /*
319 * We have to do some conversion to each pixel. This is the
320 * slowest, most general case.
321 */
322 int src_bit_offset = x * depth;
323 const byte *src_line = src_base + (src_bit_offset >> 3);
324 int ncomp =
325 (options & (GB_ALPHA_FIRST | GB_ALPHA_LAST) ? 4 : 3);
326 byte *dest_line = data + x_offset * ncomp;
327
328 /* Pick the representation that's most likely to be useful. */
329 if (options & GB_COLORS_RGB)
330 options &= ~GB_COLORS_STANDARD_ALL | GB_COLORS_RGB;
331 else if (options & GB_COLORS_CMYK)
332 options &= ~GB_COLORS_STANDARD_ALL | GB_COLORS_CMYK;
333 else if (options & GB_COLORS_GRAY)
334 options &= ~GB_COLORS_STANDARD_ALL | GB_COLORS_GRAY;
335 else
336 return_error(gs_error_rangecheck);
337 for (; h > 0; dest_line += raster, src_line += dev_raster, --h) {
338 int i;
339
340 sample_load_declare_setup(src, bit, src_line, src_bit_offset & 7,
341 depth);
342 byte *dest = dest_line;
343
344 for (i = 0; i < w; ++i) {
345 gx_color_index pixel = 0;
346 gx_color_value rgba[4];
347
348 sample_load_next32(pixel, src, bit, depth);
349 (*dev_proc(dev, map_color_rgb_alpha)) (dev, pixel, rgba);
350 if (options & GB_ALPHA_FIRST)
351 *dest++ = gx_color_value_to_byte(rgba[3]);
352 /* Convert to the requested color space. */
353 if (options & GB_COLORS_RGB) {
354 dest[0] = gx_color_value_to_byte(rgba[0]);
355 dest[1] = gx_color_value_to_byte(rgba[1]);
356 dest[2] = gx_color_value_to_byte(rgba[2]);
357 dest += 3;
358 } else if (options & GB_COLORS_CMYK) {
359 /* Use the standard RGB to CMYK algorithm, */
360 /* with maximum black generation and undercolor removal. */
361 gx_color_value white = max(rgba[0], max(rgba[1], rgba[2]));
362
363 dest[0] = gx_color_value_to_byte(white - rgba[0]);
364 dest[1] = gx_color_value_to_byte(white - rgba[1]);
365 dest[2] = gx_color_value_to_byte(white - rgba[2]);
366 dest[3] = gx_color_value_to_byte(gx_max_color_value - white);
367 dest += 4;
368 } else { /* GB_COLORS_GRAY */
369 /* Use the standard RGB to Gray algorithm. */
370 *dest++ = gx_color_value_to_byte(
371 ((rgba[0] * (ulong) lum_red_weight) +
372 (rgba[1] * (ulong) lum_green_weight) +
373 (rgba[2] * (ulong) lum_blue_weight) +
374 (lum_all_weights / 2))
375 / lum_all_weights);
376 }
377 if (options & GB_ALPHA_LAST)
378 *dest++ = gx_color_value_to_byte(rgba[3]);
379 }
380 }
381 }
382 params->options =
383 (options & (GB_COLORS_ALL | GB_ALPHA_ALL)) | GB_PACKING_CHUNKY |
384 (options & GB_COLORS_NATIVE ? 0 : options & GB_DEPTH_ALL) |
385 (options & GB_ALIGN_STANDARD ? GB_ALIGN_STANDARD : GB_ALIGN_ANY) |
386 GB_RETURN_COPY |
387 (x_offset == 0 ? GB_OFFSET_0 : GB_OFFSET_SPECIFIED) |
388 (raster == std_raster ? GB_RASTER_STANDARD : GB_RASTER_SPECIFIED);
389 }
390 return 0;
391 }
392
393 int
394 gx_no_get_bits_rectangle(gx_device * dev, const gs_int_rect * prect,
395 gs_get_bits_params_t * params, gs_int_rect ** unread)
396 {
397 return_error(gs_error_unknownerror);
398 }
399 int
400 gx_default_get_bits_rectangle(gx_device * dev, const gs_int_rect * prect,
401 gs_get_bits_params_t * params, gs_int_rect ** unread)
402 {
403 dev_proc_get_bits_rectangle((*save_get_bits_rectangle)) =
404 dev_proc(dev, get_bits_rectangle);
405 int depth = dev->color_info.depth;
406 uint min_raster = (dev->width * depth + 7) >> 3;
407 gs_get_bits_options_t options = params->options;
408 int code;
409
410 /* Avoid a recursion loop. */
411 set_dev_proc(dev, get_bits_rectangle, gx_no_get_bits_rectangle);
412 /*
413 * If the parameters are right, try to call get_bits directly. Note
414 * that this may fail if a device only implements get_bits_rectangle
415 * (not get_bits) for a limited set of options. Note also that this
416 * must handle the case of the recursive call from within
417 * get_bits_rectangle (see below): because of this, and only because
418 * of this, it must handle partial scan lines.
419 */
420 if (prect->q.y == prect->p.y + 1 &&
421 !(~options &
422 (GB_RETURN_COPY | GB_PACKING_CHUNKY | GB_COLORS_NATIVE)) &&
423 (options & (GB_ALIGN_STANDARD | GB_ALIGN_ANY)) &&
424 ((options & (GB_OFFSET_0 | GB_OFFSET_ANY)) ||
425 ((options & GB_OFFSET_SPECIFIED) && params->x_offset == 0)) &&
426 ((options & (GB_RASTER_STANDARD | GB_RASTER_ANY)) ||
427 ((options & GB_RASTER_SPECIFIED) &&
428 params->raster >= min_raster)) &&
429 unread == NULL
430 ) {
431 byte *data = params->data[0];
432 byte *row = data;
433
434 if (!(prect->p.x == 0 && prect->q.x == dev->width)) {
435 /* Allocate an intermediate row buffer. */
436 row = gs_alloc_bytes(dev->memory, min_raster,
437 "gx_default_get_bits_rectangle");
438
439 if (row == 0) {
440 code = gs_note_error(gs_error_VMerror);
441 goto ret;
442 }
443 }
444 code = (*dev_proc(dev, get_bits))
445 (dev, prect->p.y, row, &params->data[0]);
446 if (code >= 0) {
447 if (row != data) {
448 if (prect->p.x == 0 && params->data[0] != row) {
449 /*
450 * get_bits returned an appropriate pointer: we can
451 * avoid doing any copying.
452 */
453 DO_NOTHING;
454 } else {
455 /* Copy the partial row into the supplied buffer. */
456 int width_bits = (prect->q.x - prect->p.x) * depth;
457 gx_device_memory tdev;
458
459 tdev.width = width_bits;
460 tdev.height = 1;
461 tdev.line_ptrs = &tdev.base;
462 tdev.base = data;
463 code = (*dev_proc(&mem_mono_device, copy_mono))
464 ((gx_device *) & tdev, params->data[0], prect->p.x * depth,
465 min_raster, gx_no_bitmap_id, 0, 0, width_bits, 1,
466 (gx_color_index) 0, (gx_color_index) 1);
467 params->data[0] = data;
468 }
469 gs_free_object(dev->memory, row,
470 "gx_default_get_bits_rectangle");
471 }
472 params->options =
473 GB_ALIGN_STANDARD | GB_OFFSET_0 | GB_PACKING_CHUNKY |
474 GB_ALPHA_NONE | GB_COLORS_NATIVE | GB_RASTER_STANDARD |
475 (params->data[0] == data ? GB_RETURN_COPY : GB_RETURN_POINTER);
476 goto ret;
477 }
478 } {
479 /* Do the transfer row-by-row using a buffer. */
480 int x = prect->p.x, w = prect->q.x - x;
481 int bits_per_pixel = depth;
482 byte *row;
483
484 if (options & GB_COLORS_STANDARD_ALL) {
485 /*
486 * Make sure the row buffer can hold the standard color
487 * representation, in case the device decides to use it.
488 */
489 int bpc = GB_OPTIONS_MAX_DEPTH(options);
490 int nc =
491 (options & GB_COLORS_CMYK ? 4 :
492 options & GB_COLORS_RGB ? 3 : 1) +
493 (options & (GB_ALPHA_ALL - GB_ALPHA_NONE) ? 1 : 0);
494 int bpp = bpc * nc;
495
496 if (bpp > bits_per_pixel)
497 bits_per_pixel = bpp;
498 }
499 row = gs_alloc_bytes(dev->memory, (bits_per_pixel * w + 7) >> 3,
500 "gx_default_get_bits_rectangle");
501 if (row == 0) {
502 code = gs_note_error(gs_error_VMerror);
503 } else {
504 uint dev_raster = gx_device_raster(dev, true);
505 uint raster =
506 (options & GB_RASTER_SPECIFIED ? params->raster :
507 options & GB_ALIGN_STANDARD ? bitmap_raster(depth * w) :
508 (depth * w + 7) >> 3);
509 gs_int_rect rect;
510 gs_get_bits_params_t copy_params;
511 gs_get_bits_options_t copy_options =
512 GB_ALIGN_ANY | (GB_RETURN_COPY | GB_RETURN_POINTER) |
513 (GB_OFFSET_0 | GB_OFFSET_ANY) |
514 (GB_RASTER_STANDARD | GB_RASTER_ANY) | GB_PACKING_CHUNKY |
515 GB_COLORS_NATIVE | (options & (GB_DEPTH_ALL | GB_COLORS_ALL)) |
516 GB_ALPHA_ALL;
517 byte *dest = params->data[0];
518 int y;
519
520 rect.p.x = x, rect.q.x = x + w;
521 code = 0;
522 for (y = prect->p.y; y < prect->q.y; ++y) {
523 rect.p.y = y, rect.q.y = y + 1;
524 copy_params.options = copy_options;
525 copy_params.data[0] = row;
526 code = (*save_get_bits_rectangle)
527 (dev, &rect, &copy_params, NULL);
528 if (code < 0)
529 break;
530 if (copy_params.options & GB_OFFSET_0)
531 copy_params.x_offset = 0;
532 params->data[0] = dest + (y - prect->p.y) * raster;
533 code = gx_get_bits_copy(dev, copy_params.x_offset, w, 1,
534 params, copy_params.options,
535 copy_params.data[0], dev_raster);
536 if (code < 0)
537 break;
538 }
539 gs_free_object(dev->memory, row, "gx_default_get_bits_rectangle");
540 params->data[0] = dest;
541 }
542 }
543 ret:set_dev_proc(dev, get_bits_rectangle, save_get_bits_rectangle);
544 return (code < 0 ? code : 0);
545 }
546
547 /* ------ Debugging printout ------ */
548
549 #ifdef DEBUG
550
551 void
552 debug_print_gb_options(gx_bitmap_format_t options)
553 {
554 static const char *const option_names[] =
555 {
556 GX_BITMAP_FORMAT_NAMES
557 };
558 const char *prev = " ";
559 int i;
560
561 dlprintf1("0x%lx", (ulong) options);
562 for (i = 0; i < sizeof(options) * 8; ++i)
563 if ((options >> i) & 1) {
564 dprintf2("%c%s",
565 (!memcmp(prev, option_names[i], 3) ? '|' : ','),
566 option_names[i]);
567 prev = option_names[i];
568 }
569 dputc('\n');
570 }
571
572 void
573 debug_print_gb_params(gs_get_bits_params_t * params)
574 {
575 gs_get_bits_options_t options = params->options;
576
577 debug_print_gb_options(options);
578 dprintf1("data[0]=0x%lx", (ulong) params->data[0]);
579 if (options & GB_OFFSET_SPECIFIED)
580 dprintf1(" x_offset=%d", params->x_offset);
581 if (options & GB_RASTER_SPECIFIED)
582 dprintf1(" raster=%u", params->raster);
583 dputc('\n');
584 }
585
586 #endif /* DEBUG */