summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'base/gsdevice.c')
-rw-r--r--base/gsdevice.c111
1 files changed, 72 insertions, 39 deletions
diff --git a/base/gsdevice.c b/base/gsdevice.c
index 630ed493..b02c324c 100644
--- a/base/gsdevice.c
+++ b/base/gsdevice.c
@@ -37,6 +37,7 @@
#include "gxcspace.h"
#include "gsicc_manage.h"
#include "gscms.h"
+#include "gxgetbit.h"
/* Include the extern for the device list. */
extern_gs_lib_device_list();
@@ -161,17 +162,6 @@ gx_device_reloc_ptr(gx_device * dev, gc_state_t * gcst)
return RELOC_OBJ(dev); /* gcst implicit */
}
-/* Set up the device procedures in the device structure. */
-/* Also copy old fields to new ones. */
-void
-gx_device_set_procs(gx_device * dev)
-{
- if (dev->static_procs != 0) { /* 0 if already populated */
- dev->procs = *dev->static_procs;
- dev->static_procs = 0;
- }
-}
-
/* Flush buffered output to the device */
int
gs_flushpage(gs_gstate * pgs)
@@ -247,10 +237,27 @@ gs_copyscanlines(gx_device * dev, int start_y, byte * data, uint size,
uint count = size / line_size;
uint i;
byte *dest = data;
+ gs_int_rect rect;
+ gs_get_bits_params_t params;
- for (i = 0; i < count; i++, dest += line_size) {
- int code = (*dev_proc(dev, get_bits)) (dev, start_y + i, dest, NULL);
+ rect.p.x = 0;
+ rect.q.x = dev->width;
+ params.x_offset = 0;
+ params.raster = bitmap_raster(dev->width * dev->color_info.depth);
+ for (i = 0; i < count; i++, dest += line_size) {
+ int code;
+
+ rect.p.y = start_y+i;
+ rect.q.y = start_y+i+1;
+
+ params.options = (GB_ALIGN_ANY |
+ GB_RETURN_COPY |
+ GB_OFFSET_0 |
+ GB_RASTER_STANDARD | GB_PACKING_CHUNKY |
+ GB_COLORS_NATIVE | GB_ALPHA_NONE);
+ params.data[0] = dest;
+ code = (*dev_proc(dev, get_bits_rectangle))(dev, &rect, &params);
if (code < 0) {
/* Might just be an overrun. */
if (start_y + i == dev->height)
@@ -356,7 +363,7 @@ gx_device_make_struct_type(gs_memory_struct_type_t *st,
{
if (dev->stype)
*st = *dev->stype;
- else if (dev_proc(dev, get_xfont_procs) == gx_forward_get_xfont_procs)
+ else if (dev_proc(dev, get_page_device) == gx_forward_get_page_device)
*st = st_device_forward;
else
*st = st_device;
@@ -409,34 +416,29 @@ gs_copydevice2(gx_device ** pnew_dev, const gx_device * dev, bool keep_open,
gs_free_object(mem->non_gc_memory, a_std, "gs_copydevice(stype)");
return_error(gs_error_VMerror);
}
- gx_device_init(new_dev, dev, mem, false);
- gx_device_set_procs(new_dev);
+ code = gx_device_init(new_dev, dev, mem, false);
new_dev->stype = new_std;
new_dev->stype_is_dynamic = new_std != std;
/*
* keep_open is very dangerous. On the other hand, so is copydevice in
* general, since it just copies the bits without any regard to pointers
- * (including self-pointers) that they may contain. We handle this by
- * making the default finish_copydevice forbid copying of anything other
- * than the device prototype.
+ * (including self-pointers) that they may contain.
*/
new_dev->is_open = dev->is_open && keep_open;
- fill_dev_proc(new_dev, finish_copydevice, gx_default_finish_copydevice);
- /* We really want to be able to interrogate the device for capabilities
- * and/or preferences right from when it is created, so set dev_spec_op
- * now (if not already set).
- */
- fill_dev_proc(new_dev, dev_spec_op, gx_default_dev_spec_op);
- code = dev_proc(new_dev, finish_copydevice)(new_dev, dev);
if (code < 0) {
gs_free_object(mem, new_dev, "gs_copydevice(device)");
#if 0 /* gs_free_object above calls gx_device_finalize,
- which closes the device and releaszes its stype, i.e. a_std. */
+ which closes the device and releases its stype, i.e. a_std. */
if (a_std)
gs_free_object(dev->memory->non_gc_memory, a_std, "gs_copydevice(stype)");
#endif
return code;
}
+ /* We really want to be able to interrogate the device for capabilities
+ * and/or preferences right from when it is created, so set dev_spec_op
+ * now (if not already set).
+ */
+ fill_dev_proc(new_dev, dev_spec_op, gx_default_dev_spec_op);
*pnew_dev = new_dev;
return 0;
}
@@ -619,15 +621,25 @@ gs_setdevice_no_init(gs_gstate * pgs, gx_device * dev)
}
/* Initialize a just-allocated device. */
-void
+int
gx_device_init(gx_device * dev, const gx_device * proto, gs_memory_t * mem,
bool internal)
{
memcpy(dev, proto, proto->params_size);
- dev->memory = mem;
+ dev->initialize_device_procs = proto->initialize_device_procs;
+ if (dev->initialize_device_procs != NULL)
+ dev->initialize_device_procs(dev);
+ dev->memory = mem; /* must precede initialize_device call so devices can use it */
+ if (dev->procs.initialize_device) {
+ int code = dev->procs.initialize_device(dev);
+ if (code < 0)
+ return code;
+ }
dev->retained = !internal;
rc_init(dev, mem, (internal ? 0 : 1));
rc_increment(dev->icc_struct);
+
+ return 0;
}
void
@@ -635,6 +647,14 @@ gx_device_init_on_stack(gx_device * dev, const gx_device * proto,
gs_memory_t * mem)
{
memcpy(dev, proto, proto->params_size);
+ dev->initialize_device_procs = proto->initialize_device_procs;
+ dev->initialize_device_procs(dev);
+ if (dev->procs.initialize_device) {
+ /* A condition of devices inited on the stack is that they can
+ * never fail to initialize! */
+ (void)dev->procs.initialize_device(dev);
+ }
+ gx_device_fill_in_procs(dev);
dev->memory = mem;
dev->retained = 0;
dev->pad = proto->pad;
@@ -648,8 +668,10 @@ void
gs_make_null_device(gx_device_null *dev_null, gx_device *dev,
gs_memory_t * mem)
{
- gx_device_init((gx_device *)dev_null, (const gx_device *)&gs_null_device,
- mem, true);
+ /* Can never fail */
+ (void)gx_device_init((gx_device *)dev_null,
+ (const gx_device *)&gs_null_device,
+ mem, true);
gx_device_fill_in_procs((gx_device *)dev_null);
gx_device_set_target((gx_device_forward *)dev_null, dev);
if (dev) {
@@ -671,7 +693,6 @@ gs_make_null_device(gx_device_null *dev_null, gx_device *dev,
set_dev_proc(dn, begin_transparency_mask, gx_default_begin_transparency_mask);
set_dev_proc(dn, end_transparency_mask, gx_default_end_transparency_mask);
set_dev_proc(dn, discard_transparency_layer, gx_default_discard_transparency_layer);
- set_dev_proc(dn, pattern_manage, gx_default_pattern_manage);
set_dev_proc(dn, push_transparency_state, gx_default_push_transparency_state);
set_dev_proc(dn, pop_transparency_state, gx_default_pop_transparency_state);
set_dev_proc(dn, put_image, gx_default_put_image);
@@ -787,16 +808,28 @@ gx_set_device_only(gs_gstate * pgs, gx_device * dev)
uint
gx_device_raster(const gx_device * dev, bool pad)
{
- ulong bits = (ulong) dev->width * dev->color_info.depth;
+ int depth = dev->color_info.depth;
+ ulong bits = (ulong) dev->width * depth;
ulong raster;
int l2align;
- if (dev->is_planar)
- {
- int has_tags = device_encodes_tags(dev);
- bits /= (dev->color_info.num_components + has_tags);
- }
+ if (dev->is_planar) {
+ int num_components = dev->color_info.num_components;
+ /* bpc accounts for unused bits, e.g. depth==4, num_comp==3, or depth==8, num_comps==5 */
+ int bpc = depth / num_components;
+ /* depth can be <= num_components if planar and MEM_SET_PARAMS has changed it */
+ if (depth <= num_components || bpc >= 8) {
+ /* tag plane requires at least 8 bits (per component as well as tags) */
+ int has_tags = bpc >= 8 ? device_encodes_tags(dev): 0;
+
+ bits /= (num_components + has_tags);
+ }
+ else {
+ /* depth is original depth, not the plane_depth since it is > num_components */
+ bits /= (depth / bpc);
+ }
+ }
raster = (uint)((bits + 7) >> 3);
if (!pad)
return raster;
@@ -1360,7 +1393,7 @@ bool gx_color_info_equal(const gx_device_color_info * p1, const gx_device_color_
return false;
if (p1->max_components != p2->max_components)
return false;
- if (p1->opmode != p2->opmode)
+ if (p1->opmsupported != p2->opmsupported)
return false;
if (p1->polarity != p2->polarity)
return false;