summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam James <sam@gentoo.org>2022-03-29 10:27:10 +0100
committerSam James <sam@gentoo.org>2022-04-17 12:53:05 +0100
commit085bde903b9e684c3c1160e4df912bea9a660997 (patch)
treec4f5e6e9f2422e869ca5bc0b944520d451001282 /psi/zdevice.c
parentImport Ghostscript 9.55 (diff)
downloadghostscript-gpl-patches-085bde903b9e684c3c1160e4df912bea9a660997.tar.gz
ghostscript-gpl-patches-085bde903b9e684c3c1160e4df912bea9a660997.tar.bz2
ghostscript-gpl-patches-085bde903b9e684c3c1160e4df912bea9a660997.zip
Import Ghostscript 9.56.0ghostscript-9.56
Signed-off-by: Sam James <sam@gentoo.org>
Diffstat (limited to 'psi/zdevice.c')
-rw-r--r--psi/zdevice.c152
1 files changed, 112 insertions, 40 deletions
diff --git a/psi/zdevice.c b/psi/zdevice.c
index b119a768..99beaff7 100644
--- a/psi/zdevice.c
+++ b/psi/zdevice.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2021 Artifex Software, Inc.
+/* Copyright (C) 2001-2022 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
@@ -36,6 +36,47 @@
#include "gsicc_manage.h"
#include "gxdevsop.h"
+struct_proc_finalize(psi_device_ref_finalize);
+
+static
+ENUM_PTRS_WITH(psi_device_ref_enum_ptrs, psi_device_ref *devref)
+ {
+ return 0;
+ }
+ case 0:
+ {
+ if (devref->device->memory != NULL) {
+ ENUM_RETURN(gx_device_enum_ptr(devref->device));
+ }
+ return 0;
+ }
+ENUM_PTRS_END
+
+static
+RELOC_PTRS_WITH(psi_device_ref_reloc_ptrs, psi_device_ref *devref)
+ if (devref->device->memory != NULL) {
+ devref->device = gx_device_reloc_ptr(devref->device, gcst);
+ }
+RELOC_PTRS_END
+
+gs_private_st_composite_use_final(st_psi_device_ref, psi_device_ref, "psi_device_ref_t",
+ psi_device_ref_enum_ptrs, psi_device_ref_reloc_ptrs, psi_device_ref_finalize);
+
+void
+psi_device_ref_finalize(const gs_memory_t *cmem, void *vptr)
+{
+ psi_device_ref *pdref = (psi_device_ref *)vptr;
+ (void)cmem;
+
+ /* pdref->device->memory == NULL indicates either a device prototype
+ or a device allocated on the stack rather than the heap
+ */
+ if (pdref->device->memory != NULL)
+ rc_decrement(pdref->device, "psi_device_ref_finalize");
+
+ pdref->device = NULL;
+}
+
/* <device> <keep_open> .copydevice2 <newdevice> */
static int
zcopydevice2(i_ctx_t *i_ctx_p)
@@ -43,6 +84,7 @@ zcopydevice2(i_ctx_t *i_ctx_p)
os_ptr op = osp;
gx_device *new_dev;
int code;
+ psi_device_ref *psdev;
check_read_type(op[-1], t_device);
check_type(*op, t_boolean);
@@ -50,12 +92,20 @@ zcopydevice2(i_ctx_t *i_ctx_p)
/* This can happen if we invalidated devices on the stack by calling nulldevice after they were pushed */
return_error(gs_error_undefined);
- code = gs_copydevice2(&new_dev, op[-1].value.pdevice, op->value.boolval,
+ code = gs_copydevice2(&new_dev, op[-1].value.pdevice->device, op->value.boolval,
imemory);
if (code < 0)
return code;
new_dev->memory = imemory;
- make_tav(op - 1, t_device, icurrent_space | a_all, pdevice, new_dev);
+
+ psdev = gs_alloc_struct(imemory, psi_device_ref, &st_psi_device_ref, "zcopydevice2");
+ if (!psdev) {
+ rc_decrement(new_dev, "zcopydevice2");
+ return_error(gs_error_VMerror);
+ }
+ psdev->device = new_dev;
+
+ make_tav(op - 1, t_device, icurrent_space | a_all, pdevice, psdev);
pop(1);
return 0;
}
@@ -68,11 +118,17 @@ zcurrentdevice(i_ctx_t *i_ctx_p)
os_ptr op = osp;
gx_device *dev = gs_currentdevice(igs);
gs_ref_memory_t *mem = (gs_ref_memory_t *) dev->memory;
+ psi_device_ref *psdev;
+
+ psdev = gs_alloc_struct(dev->memory, psi_device_ref, &st_psi_device_ref, "zcurrentdevice");
+ if (!psdev) {
+ return_error(gs_error_VMerror);
+ }
+ psdev->device = dev;
+ rc_increment(dev);
push(1);
- make_tav(op, t_device,
- (mem == 0 ? avm_foreign : imemory_space(mem)) | a_all,
- pdevice, dev);
+ make_tav(op, t_device, imemory_space(mem) | a_all, pdevice, psdev);
return 0;
}
@@ -91,16 +147,22 @@ zcurrentoutputdevice(i_ctx_t *i_ctx_p)
{
os_ptr op = osp;
gx_device *odev = NULL, *dev = gs_currentdevice(igs);
+ psi_device_ref *psdev;
gs_ref_memory_t *mem = (gs_ref_memory_t *) dev->memory;
int code = dev_proc(dev, dev_spec_op)(dev,
gxdso_current_output_device, (void *)&odev, 0);
if (code < 0)
return code;
+ psdev = gs_alloc_struct(dev->memory, psi_device_ref, &st_psi_device_ref, "zcurrentdevice");
+ if (!psdev) {
+ return_error(gs_error_VMerror);
+ }
+ psdev->device = odev;
+ rc_increment(odev);
+
push(1);
- make_tav(op, t_device,
- (mem == 0 ? avm_foreign : imemory_space(mem)) | a_all,
- pdevice, odev);
+ make_tav(op, t_device, imemory_space(mem) | a_all, pdevice, psdev);
return 0;
}
@@ -116,7 +178,7 @@ zdevicename(i_ctx_t *i_ctx_p)
/* This can happen if we invalidated devices on the stack by calling nulldevice after they were pushed */
return_error(gs_error_undefined);
- dname = op->value.pdevice->dname;
+ dname = op->value.pdevice->device->dname;
make_const_string(op, avm_foreign | a_readonly, strlen(dname),
(const byte *)dname);
return 0;
@@ -164,11 +226,12 @@ zgetbitsrect(i_ctx_t *i_ctx_p)
int code;
check_read_type(op[-7], t_device);
- dev = op[-7].value.pdevice;
- if (dev == NULL)
+ if (op[-7].value.pdevice == NULL)
/* This can happen if we invalidated devices on the stack by calling nulldevice after they were pushed */
return_error(gs_error_undefined);
+ dev = op[-7].value.pdevice->device;
+
check_int_leu(op[-6], dev->width);
rect.p.x = op[-6].value.intval;
check_int_leu(op[-5], dev->height);
@@ -238,6 +301,7 @@ zgetdevice(i_ctx_t *i_ctx_p)
{
os_ptr op = osp;
const gx_device *dev;
+ psi_device_ref *psdev;
check_type(*op, t_integer);
if (op->value.intval != (int)(op->value.intval))
@@ -245,10 +309,16 @@ zgetdevice(i_ctx_t *i_ctx_p)
dev = gs_getdevice((int)(op->value.intval));
if (dev == 0) /* index out of range */
return_error(gs_error_rangecheck);
+
+ psdev = gs_alloc_struct(imemory, psi_device_ref, &st_psi_device_ref, "zgetdevice");
+ if (!psdev) {
+ return_error(gs_error_VMerror);
+ }
+ /* gs_getdevice() returns a device prototype, so no reference counting required */
+ psdev->device = (gx_device *)dev;
+
/* Device prototypes are read-only; */
- /* the cast is logically unnecessary. */
- make_tav(op, t_device, avm_foreign | a_readonly, pdevice,
- (gx_device *) dev);
+ make_tav(op, t_device, imemory_space(iimemory) | a_readonly, pdevice, psdev);
return 0;
}
@@ -258,13 +328,21 @@ zgetdefaultdevice(i_ctx_t *i_ctx_p)
{
os_ptr op = osp;
const gx_device *dev;
+ psi_device_ref *psdev;
dev = gs_getdefaultlibdevice(imemory);
if (dev == 0) /* couldn't find a default device */
return_error(gs_error_unknownerror);
+
+ psdev = gs_alloc_struct(imemory, psi_device_ref, &st_psi_device_ref, "zgetdefaultdevice");
+ if (!psdev) {
+ return_error(gs_error_VMerror);
+ }
+ /* gs_getdefaultlibdevice() returns a device prototype, so no reference counting required */
+ psdev->device = (gx_device *)dev;
+
push(1);
- make_tav(op, t_device, avm_foreign | a_readonly, pdevice,
- (gx_device *) dev);
+ make_tav(op, t_device, imemory_space(iimemory) | a_readonly, pdevice, psdev);
return 0;
}
@@ -285,10 +363,12 @@ zget_device_params(i_ctx_t *i_ctx_p, bool is_hardware)
check_type(*op, t_dictionary);
}
rkeys = *op;
- dev = op[-1].value.pdevice;
if (op[-1].value.pdevice == NULL)
/* This can happen if we invalidated devices on the stack by calling nulldevice after they were pushed */
return_error(gs_error_undefined);
+
+ dev = op[-1].value.pdevice->device;
+
ref_stack_pop(&o_stack, 1);
stack_param_list_write(&list, &o_stack, &rkeys, iimemory);
code = gs_get_device_or_hardware_params(dev, (gs_param_list *) & list,
@@ -333,6 +413,7 @@ zmakewordimagedevice(i_ctx_t *i_ctx_p)
const byte *colors;
int colors_size;
int code;
+ psi_device_ref *psdev;
check_int_leu(op[-3], max_uint >> 1); /* width */
check_int_leu(op[-2], max_uint >> 1); /* height */
@@ -368,30 +449,25 @@ zmakewordimagedevice(i_ctx_t *i_ctx_p)
op->value.boolval, true, imemory);
if (code == 0) {
new_dev->memory = imemory;
- make_tav(op - 4, t_device, imemory_space(iimemory) | a_all,
- pdevice, new_dev);
+
+ psdev = gs_alloc_struct(imemory, psi_device_ref, &st_psi_device_ref, "zcurrentdevice");
+ if (!psdev) {
+ rc_decrement(new_dev, "zmakewordimagedevice");
+ return_error(gs_error_VMerror);
+ }
+ psdev->device = new_dev;
+ make_tav(op - 4, t_device, imemory_space(iimemory) | a_all, pdevice, psdev);
pop(4);
}
return code;
}
-static void invalidate_stack_devices(i_ctx_t *i_ctx_p)
-{
- os_ptr op = osbot;
- while (op != ostop) {
- if (r_has_type(op, t_device))
- op->value.pdevice = 0;
- op++;
- }
-}
-
/* - nulldevice - */
/* Note that nulldevice clears the current pagedevice. */
static int
znulldevice(i_ctx_t *i_ctx_p)
{
int code = gs_nulldevice(igs);
- invalidate_stack_devices(i_ctx_p);
clear_pagedevice(istate);
return code;
}
@@ -457,7 +533,7 @@ zputdeviceparams(i_ctx_t *i_ctx_p)
return_error(gs_error_stackunderflow);
check_type_only(*prequire_all, t_boolean);
check_write_type_only(*pdev, t_device);
- dev = pdev->value.pdevice;
+ dev = pdev->value.pdevice->device;
if (dev == NULL)
/* This can happen if we invalidated devices on the stack by calling nulldevice after they were pushed */
return_error(gs_error_undefined);
@@ -509,11 +585,8 @@ zputdeviceparams(i_ctx_t *i_ctx_p)
int
zsetdevice_no_safer(i_ctx_t *i_ctx_p, gx_device *new_dev)
{
- gx_device *dev = gs_currentdevice(igs);
int code;
- dev->ShowpageCount = 0;
-
if (new_dev == NULL)
return gs_note_error(gs_error_undefined);
@@ -521,7 +594,6 @@ zsetdevice_no_safer(i_ctx_t *i_ctx_p, gx_device *new_dev)
if (code < 0)
return code;
- invalidate_stack_devices(i_ctx_p);
clear_pagedevice(istate);
return code;
}
@@ -548,10 +620,10 @@ zsetdevice(i_ctx_t *i_ctx_p)
* it's procs initialised, at this point - but we need to check
* whether we're being asked to change the device here
*/
- if (dev_proc((op->value.pdevice), dev_spec_op) == NULL)
- ndev = op->value.pdevice;
+ if (dev_proc((op->value.pdevice->device), dev_spec_op) == NULL)
+ ndev = op->value.pdevice->device;
else
- code = dev_proc((op->value.pdevice), dev_spec_op)(op->value.pdevice,
+ code = dev_proc((op->value.pdevice->device), dev_spec_op)(op->value.pdevice->device,
gxdso_current_output_device, (void *)&ndev, 0);
if (code < 0)
@@ -561,7 +633,7 @@ zsetdevice(i_ctx_t *i_ctx_p)
if(ndev != odev) /* don't allow a different device */
return_error(gs_error_invalidaccess);
}
- code = zsetdevice_no_safer(i_ctx_p, op->value.pdevice);
+ code = zsetdevice_no_safer(i_ctx_p, op->value.pdevice->device);
make_bool(op, code != 0); /* erase page if 1 */
return code;
}