1 /* Copyright (C) 1994, 2000 artofcode LLC. All rights reserved.
2
3 This program is free software; you can redistribute it and/or modify it
4 under the terms of the GNU General Public License as published by the
5 Free Software Foundation; either version 2 of the License, or (at your
6 option) any later version.
7
8 This program is distributed in the hope that it will be useful, but
9 WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 General Public License for more details.
12
13 You should have received a copy of the GNU General Public License along
14 with this program; if not, write to the Free Software Foundation, Inc.,
15 59 Temple Place, Suite 330, Boston, MA, 02111-1307.
16
17 */
18
19 /*$Id: zfdcte.c,v 1.5.2.1.2.1 2003/01/17 00:49:06 giles Exp $ */
20 /* DCTEncode filter creation */
21 #include "memory_.h"
22 #include "stdio_.h" /* for jpeglib.h */
23 #include "jpeglib_.h"
24 #include "ghost.h"
25 #include "oper.h"
26 #include "gsmalloc.h" /* for gs_memory_default */
27 #include "ialloc.h"
28 #include "idict.h"
29 #include "idparam.h"
30 #include "strimpl.h"
31 #include "sdct.h"
32 #include "sjpeg.h"
33 #include "ifilter.h"
34 #include "iparam.h"
35
36 /*#define TEST*/
37 /* Import the parameter processing procedure from sdeparam.c */
38 stream_state_proc_put_params(s_DCTE_put_params, stream_DCT_state);
39 #ifdef TEST
40 stream_state_proc_get_params(s_DCTE_get_params, stream_DCT_state);
41 #endif
42
43 /* <target> <dict> DCTEncode/filter <file> */
44 private int
zDCTE(i_ctx_t * i_ctx_p)45 zDCTE(i_ctx_t *i_ctx_p)
46 {
47 os_ptr op = osp;
48 gs_memory_t *mem = &gs_memory_default;
49 stream_DCT_state state;
50 dict_param_list list;
51 jpeg_compress_data *jcdp;
52 int code;
53 const ref *dop;
54 uint dspace;
55
56 /* First allocate space for IJG parameters. */
57 jcdp = gs_alloc_struct_immovable(mem, jpeg_compress_data,
58 &st_jpeg_compress_data, "zDCTE");
59 if (jcdp == 0)
60 return_error(e_VMerror);
61 if (s_DCTE_template.set_defaults)
62 (*s_DCTE_template.set_defaults) ((stream_state *) & state);
63 state.data.compress = jcdp;
64 jcdp->memory = state.jpeg_memory = mem; /* set now for allocation */
65 state.report_error = filter_report_error; /* in case create fails */
66 if ((code = gs_jpeg_create_compress(&state)) < 0)
67 goto fail; /* correct to do jpeg_destroy here */
68 /* Read parameters from dictionary */
69 if (r_has_type(op, t_dictionary))
70 dop = op, dspace = r_space(op);
71 else
72 dop = 0, dspace = 0;
73 if ((code = dict_param_list_read(&list, dop, NULL, false, iimemory)) < 0)
74 goto fail;
75 if ((code = s_DCTE_put_params((gs_param_list *) & list, &state)) < 0)
76 goto rel;
77 /* Create the filter. */
78 jcdp->template = s_DCTE_template;
79 /* Make sure we get at least a full scan line of input. */
80 state.scan_line_size = jcdp->cinfo.input_components *
81 jcdp->cinfo.image_width;
82 jcdp->template.min_in_size =
83 max(s_DCTE_template.min_in_size, state.scan_line_size);
84 /* Make sure we can write the user markers in a single go. */
85 jcdp->template.min_out_size =
86 max(s_DCTE_template.min_out_size, state.Markers.size);
87 code = filter_write(i_ctx_p, 0, &jcdp->template,
88 (stream_state *) & state, dspace);
89 if (code >= 0) /* Success! */
90 return code;
91 /* We assume that if filter_write fails, the stream has not been
92 * registered for closing, so s_DCTE_release will never be called.
93 * Therefore we free the allocated memory before failing.
94 */
95 rel:
96 iparam_list_release(&list);
97 fail:
98 gs_jpeg_destroy(&state);
99 gs_free_object(mem, jcdp, "zDCTE fail");
100 return code;
101 }
102
103 #ifdef TEST
104 #include "stream.h"
105 #include "files.h"
106 /* <dict> <filter> <bool> .dcteparams <dict> */
107 private int
zdcteparams(i_ctx_t * i_ctx_p)108 zdcteparams(i_ctx_t *i_ctx_p)
109 {
110 os_ptr op = osp;
111 stream *s;
112 dict_param_list list;
113 int code;
114
115 check_type(*op, t_boolean);
116 check_write_file(s, op - 1);
117 check_type(op[-2], t_dictionary);
118 /* The DCT filters copy the template.... */
119 if (s->state->template->process != s_DCTE_template.process)
120 return_error(e_rangecheck);
121 code = dict_param_list_write(&list, op - 2, NULL, iimemory);
122 if (code < 0)
123 return code;
124 code = s_DCTE_get_params((gs_param_list *) & list,
125 (stream_DCT_state *) s->state,
126 op->value.boolval);
127 iparam_list_release(&list);
128 if (code >= 0)
129 pop(2);
130 return code;
131 }
132 #endif
133
134 /* ------ Initialization procedure ------ */
135
136 const op_def zfdcte_op_defs[] =
137 {
138 #ifdef TEST
139 {"3.dcteparams", zdcteparams},
140 #endif
141 op_def_begin_filter(),
142 {"2DCTEncode", zDCTE},
143 op_def_end(0)
144 };
145