1 /*
2 Copyright (C) 2001 artofcode LLC.
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 For more information about licensing, please refer to
12 http://www.ghostscript.com/licensing/. For information on
13 commercial licensing, go to http://www.artifex.com/licensing/ or
14 contact Artifex Software, Inc., 101 Lucas Valley Road #110,
15 San Rafael, CA 94903, U.S.A., +1(415)492-9861.
16
17 Author: Raph Levien <raph@artofcode.com>
18 */
19 /* $Id: gsdfilt.c,v 1.9 2004/03/11 14:50:50 igor Exp $ */
20 /* Functions for managing the device filter stack */
21
22 #include "ctype_.h"
23 #include "memory_.h" /* for memchr, memcpy */
24 #include "string_.h"
25 #include "gx.h"
26 #include "gp.h"
27 #include "gscdefs.h" /* for gs_lib_device_list */
28 #include "gserrors.h"
29 #include "gsfname.h"
30 #include "gsstruct.h"
31 #include "gspath.h" /* gs_initclip prototype */
32 #include "gspaint.h" /* gs_erasepage prototype */
33 #include "gsmatrix.h" /* for gscoord.h */
34 #include "gscoord.h" /* for gs_initmatrix */
35 #include "gzstate.h"
36 #include "gxcmap.h"
37 #include "gxdevice.h"
38 #include "gxdevmem.h"
39 #include "gxiodev.h"
40
41 #include "gsdfilt.h"
42
43 gs_private_st_ptrs3(st_gs_device_filter_stack, gs_device_filter_stack_t,
44 "gs_device_filter_stack",
45 gs_device_filter_stack_enum_ptrs,
46 gs_device_filter_stack_reloc_ptrs,
47 next, df, next_device);
48
49 gs_public_st_simple(st_gs_device_filter, gs_device_filter_t,
50 "gs_device_filter");
51
52 int
gs_push_device_filter(gs_memory_t * mem,gs_state * pgs,gs_device_filter_t * df)53 gs_push_device_filter(gs_memory_t *mem, gs_state *pgs, gs_device_filter_t *df)
54 {
55 gs_device_filter_stack_t *dfs;
56 gx_device *new_dev = NULL;
57 int code;
58
59 dfs = gs_alloc_struct(mem, gs_device_filter_stack_t,
60 &st_gs_device_filter_stack, "gs_push_device_filter");
61 if (dfs == NULL)
62 return_error(gs_error_VMerror);
63 rc_increment(pgs->device);
64 dfs->next_device = pgs->device;
65 code = df->push(df, mem, pgs, &new_dev, pgs->device);
66 if (code < 0) {
67 gs_free_object(mem, dfs, "gs_push_device_filter");
68 return code;
69 }
70 dfs->next = pgs->dfilter_stack;
71 pgs->dfilter_stack = dfs;
72 dfs->df = df;
73 rc_init(dfs, mem, 1);
74 gs_setdevice_no_init(pgs, new_dev);
75 rc_decrement_only(new_dev, "gs_push_device_filter");
76 return code;
77 }
78
79 int
gs_pop_device_filter(gs_memory_t * mem,gs_state * pgs)80 gs_pop_device_filter(gs_memory_t *mem, gs_state *pgs)
81 {
82 gs_device_filter_stack_t *dfs_tos = pgs->dfilter_stack;
83 gx_device *tos_device = pgs->device;
84 gs_device_filter_t *df;
85 int code;
86
87 if (dfs_tos == NULL)
88 return_error(gs_error_rangecheck);
89 df = dfs_tos->df;
90 pgs->dfilter_stack = dfs_tos->next;
91 code = df->prepop(df, mem, pgs, tos_device);
92 rc_increment(tos_device);
93 gs_setdevice_no_init(pgs, dfs_tos->next_device);
94 rc_decrement_only(dfs_tos->next_device, "gs_pop_device_filter");
95 dfs_tos->df = NULL;
96 rc_decrement_only(dfs_tos, "gs_pop_device_filter");
97 code = df->postpop(df, mem, pgs, tos_device);
98 rc_decrement_only(tos_device, "gs_pop_device_filter");
99 return code;
100 }
101
102 int
gs_clear_device_filters(gs_memory_t * mem,gs_state * pgs)103 gs_clear_device_filters(gs_memory_t *mem, gs_state *pgs)
104 {
105 int code;
106
107 while (pgs->dfilter_stack != NULL) {
108 if ((code = gs_pop_device_filter(mem, pgs)) < 0)
109 return code;
110 }
111 return 0;
112 }
113