1 /* Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved.
3 This file is part of GNU Ghostscript.
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.
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
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.
26 /* Default implementation of device get_bits[_rectangle] */
36 gx_no_get_bits(gx_device
* dev
, int y
, byte
* data
, byte
** actual_data
)
38 return_error(gs_error_unknownerror
);
41 gx_default_get_bits(gx_device
* dev
, int y
, byte
* data
, byte
** actual_data
)
43 * Hand off to get_bits_rectangle, being careful to avoid a
44 * possible recursion loop.
46 dev_proc_get_bits((*save_get_bits
)) = dev_proc(dev
, get_bits
);
48 gs_get_bits_params_t params
;
51 rect
.p
.x
= 0, rect
.p
.y
= y
;
52 rect
.q
.x
= dev
->width
, rect
.q
.y
= y
+ 1;
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
);
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
, ¶ms
, NULL
);
65 *actual_data
= params
.data
[0];
66 set_dev_proc(dev
, get_bits
, save_get_bits
);
71 * Determine whether we can satisfy a request by simply using the stored
75 requested_includes_stored(gs_get_bits_options_t requested
,
76 gs_get_bits_options_t stored
)
78 gs_get_bits_options_t both
= requested
& stored
;
80 if (!(both
& GB_PACKING_ALL
))
82 if (both
& GB_COLORS_NATIVE
)
84 if (both
& GB_COLORS_STANDARD_ALL
) {
85 if ((both
& GB_ALPHA_ALL
) && (both
& GB_DEPTH_ALL
))
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.
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
,
102 gs_get_bits_options_t options
= params
->options
;
104 if (!(options
& GB_RETURN_POINTER
) ||
105 !requested_includes_stored(options
, stored
)
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.
116 int depth
= dev
->color_info
.depth
;
117 uint dev_raster
= gx_device_raster(dev
, 1);
119 (options
& (GB_RASTER_STANDARD
| GB_RASTER_ANY
) ? dev_raster
:
122 if (h
<= 1 || raster
== dev_raster
) {
124 (options
& GB_OFFSET_ANY
? x
:
125 options
& GB_OFFSET_0
? 0 : params
->x_offset
);
128 params
->data
[0] = stored_base
;
129 params
->x_offset
= x
;
132 (options
& GB_ALIGN_ANY
? 8 : align_bitmap_mod
* 8);
133 int bit_offset
= x
- x_offset
;
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
;
142 bytes
= bit_offset
/ step
* step
;
144 /* Use a faster algorithm if depth is a power of 2. */
145 bytes
= bit_offset
& (-depth
& -align_mod
);
147 params
->data
[0] = stored_base
+ arith_rshift(bytes
, 3);
148 params
->x_offset
= (bit_offset
- bytes
) / depth
;
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
);
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.
171 * Note: this routine does not check x, w, h for validity.
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
)
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
;
185 * If the stored representation matches a requested representation,
186 * we can copy the data without any transformations.
188 bool direct_copy
= requested_includes_stored(options
, stored
);
191 * The request must include GB_PACKING_CHUNKY, GB_RETURN_COPY,
192 * and an offset and raster specification.
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
))
198 return_error(gs_error_rangecheck
);
200 int x_offset
= (options
& GB_OFFSET_0
? 0 : params
->x_offset
);
201 int end_bit
= (x_offset
+ w
) * depth
;
203 (options
& GB_ALIGN_STANDARD
? bitmap_raster(end_bit
) :
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
;
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.
216 if (!(skew
& 7) && direct_copy
) {
217 int bit_w
= w
* depth
;
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
) {
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.
228 gx_device_memory tdev
;
229 byte
*line_ptr
= data
;
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
);
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);
242 } else if (options
& ~stored
& GB_COLORS_NATIVE
) {
244 * Convert standard colors to native. Note that the source
245 * may have depths other than 8 bits per component.
247 int dest_bit_offset
= x_offset
* depth
;
248 byte
*dest_line
= data
+ (dest_bit_offset
>> 3);
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;
259 #define v2cv(value) ((ulong)(value) * gx_max_color_value / src_max)
260 gx_color_value alpha_default
= src_max
;
262 options
&= ~GB_COLORS_ALL
| GB_COLORS_NATIVE
;
263 for (; h
> 0; dest_line
+= raster
, src_line
+= dev_raster
, --h
) {
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
);
271 for (i
= 0; i
< w
; ++i
) {
273 gx_color_value v
[4], va
= alpha_default
;
274 gx_color_index pixel
;
276 /* Fetch the source data. */
277 if (stored
& GB_ALPHA_FIRST
) {
278 sample_load_next16(va
, src
, sbit
, src_depth
);
281 for (j
= 0; j
< ncolors
; ++j
) {
284 sample_load_next16(vj
, src
, sbit
, src_depth
);
287 if (stored
& GB_ALPHA_LAST
) {
288 sample_load_next16(va
, src
, sbit
, src_depth
);
291 /* Convert and store the pixel value. */
296 pixel
= (*dev_proc(dev
, map_rgb_alpha_color
))
297 (dev
, v
[0], v
[1], v
[2], va
);
300 /****** NO ALPHA FOR CMYK ******/
301 pixel
= (*dev_proc(dev
, map_cmyk_color
))
302 (dev
, v
[0], v
[1], v
[2], v
[3]);
305 return_error(gs_error_rangecheck
);
307 sample_store_next32(pixel
, dest
, dbit
, depth
, dbyte
);
309 sample_store_flush(dest
, dbit
, depth
, dbyte
);
311 } else if (!(options
& GB_DEPTH_8
)) {
313 * We don't support general depths yet, or conversion between
314 * different formats. Punt.
316 return_error(gs_error_rangecheck
);
319 * We have to do some conversion to each pixel. This is the
320 * slowest, most general case.
322 int src_bit_offset
= x
* depth
;
323 const byte
*src_line
= src_base
+ (src_bit_offset
>> 3);
325 (options
& (GB_ALPHA_FIRST
| GB_ALPHA_LAST
) ? 4 : 3);
326 byte
*dest_line
= data
+ x_offset
* ncomp
;
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
;
336 return_error(gs_error_rangecheck
);
337 for (; h
> 0; dest_line
+= raster
, src_line
+= dev_raster
, --h
) {
340 sample_load_declare_setup(src
, bit
, src_line
, src_bit_offset
& 7,
342 byte
*dest
= dest_line
;
344 for (i
= 0; i
< w
; ++i
) {
345 gx_color_index pixel
= 0;
346 gx_color_value rgba
[4];
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]);
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]));
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
);
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))
377 if (options
& GB_ALPHA_LAST
)
378 *dest
++ = gx_color_value_to_byte(rgba
[3]);
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
) |
387 (x_offset
== 0 ? GB_OFFSET_0
: GB_OFFSET_SPECIFIED
) |
388 (raster
== std_raster
? GB_RASTER_STANDARD
: GB_RASTER_SPECIFIED
);
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
)
397 return_error(gs_error_unknownerror
);
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
)
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
;
410 /* Avoid a recursion loop. */
411 set_dev_proc(dev
, get_bits_rectangle
, gx_no_get_bits_rectangle
);
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.
420 if (prect
->q
.y
== prect
->p
.y
+ 1 &&
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
)) &&
431 byte
*data
= params
->data
[0];
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");
440 code
= gs_note_error(gs_error_VMerror
);
444 code
= (*dev_proc(dev
, get_bits
))
445 (dev
, prect
->p
.y
, row
, ¶ms
->data
[0]);
448 if (prect
->p
.x
== 0 && params
->data
[0] != row
) {
450 * get_bits returned an appropriate pointer: we can
451 * avoid doing any copying.
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
;
459 tdev
.width
= width_bits
;
461 tdev
.line_ptrs
= &tdev
.base
;
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
;
469 gs_free_object(dev
->memory
, row
,
470 "gx_default_get_bits_rectangle");
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
);
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
;
484 if (options
& GB_COLORS_STANDARD_ALL
) {
486 * Make sure the row buffer can hold the standard color
487 * representation, in case the device decides to use it.
489 int bpc
= GB_OPTIONS_MAX_DEPTH(options
);
491 (options
& GB_COLORS_CMYK
? 4 :
492 options
& GB_COLORS_RGB
? 3 : 1) +
493 (options
& (GB_ALPHA_ALL
- GB_ALPHA_NONE
) ? 1 : 0);
496 if (bpp
> bits_per_pixel
)
497 bits_per_pixel
= bpp
;
499 row
= gs_alloc_bytes(dev
->memory
, (bits_per_pixel
* w
+ 7) >> 3,
500 "gx_default_get_bits_rectangle");
502 code
= gs_note_error(gs_error_VMerror
);
504 uint dev_raster
= gx_device_raster(dev
, true);
506 (options
& GB_RASTER_SPECIFIED
? params
->raster
:
507 options
& GB_ALIGN_STANDARD
? bitmap_raster(depth
* w
) :
508 (depth
* w
+ 7) >> 3);
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
)) |
517 byte
*dest
= params
->data
[0];
520 rect
.p
.x
= x
, rect
.q
.x
= x
+ w
;
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
, ©_params
, NULL
);
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
);
539 gs_free_object(dev
->memory
, row
, "gx_default_get_bits_rectangle");
540 params
->data
[0] = dest
;
543 ret
:set_dev_proc(dev
, get_bits_rectangle
, save_get_bits_rectangle
);
544 return (code
< 0 ? code
: 0);
547 /* ------ Debugging printout ------ */
552 debug_print_gb_options(gx_bitmap_format_t options
)
554 static const char *const option_names
[] =
556 GX_BITMAP_FORMAT_NAMES
558 const char *prev
= " ";
561 dlprintf1("0x%lx", (ulong
) options
);
562 for (i
= 0; i
< sizeof(options
) * 8; ++i
)
563 if ((options
>> i
) & 1) {
565 (!memcmp(prev
, option_names
[i
], 3) ? '|' : ','),
567 prev
= option_names
[i
];
573 debug_print_gb_params(gs_get_bits_params_t
* params
)
575 gs_get_bits_options_t options
= params
->options
;
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
);