1 /* Copyright (C) 2001-2006 Artifex Software, Inc.
2 All Rights Reserved.
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, modified
8 or distributed except as expressly authorized under the terms of that
9 license. Refer to licensing information at http://www.artifex.com/
10 or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
11 San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information.
12 */
13
14 /* $Id: zfdcte.c 9043 2008-08-28 22:48:19Z giles $ */
15 /* DCTEncode filter creation */
16 #include "memory_.h"
17 #include "stdio_.h" /* for jpeglib.h */
18 #include "jpeglib_.h"
19 #include "ghost.h"
20 #include "oper.h"
21 #include "gsmemory.h"
22 #include "ialloc.h"
23 #include "idict.h"
24 #include "idparam.h"
25 #include "strimpl.h"
26 #include "sdct.h"
27 #include "sjpeg.h"
28 #include "ifilter.h"
29 #include "iparam.h"
30
31 /*#define TEST*/
32 /* Import the parameter processing procedure from sdeparam.c */
33 stream_state_proc_put_params(s_DCTE_put_params, stream_DCT_state);
34 #ifdef TEST
35 stream_state_proc_get_params(s_DCTE_get_params, stream_DCT_state);
36 #endif
37
38 /* <target> <dict> DCTEncode/filter <file> */
39 static int
zDCTE(i_ctx_t * i_ctx_p)40 zDCTE(i_ctx_t *i_ctx_p)
41 {
42 os_ptr op = osp;
43 gs_memory_t *mem = gs_memory_stable(imemory);
44 stream_DCT_state state;
45 dict_param_list list;
46 jpeg_compress_data *jcdp;
47 int code;
48 const ref *dop;
49 uint dspace;
50
51 /* First allocate space for IJG parameters. */
52 jcdp = gs_alloc_struct_immovable(mem, jpeg_compress_data,
53 &st_jpeg_compress_data, "zDCTE");
54 if (jcdp == 0)
55 return_error(e_VMerror);
56 if (s_DCTE_template.set_defaults)
57 (*s_DCTE_template.set_defaults) ((stream_state *) & state);
58 state.data.compress = jcdp;
59 jcdp->memory = state.jpeg_memory = mem; /* set now for allocation */
60 state.report_error = filter_report_error; /* in case create fails */
61 if ((code = gs_jpeg_create_compress(&state)) < 0)
62 goto fail; /* correct to do jpeg_destroy here */
63 /* Read parameters from dictionary */
64 if (r_has_type(op, t_dictionary))
65 dop = op, dspace = r_space(op);
66 else
67 dop = 0, dspace = 0;
68 if ((code = dict_param_list_read(&list, dop, NULL, false, iimemory)) < 0)
69 goto fail;
70 if ((code = s_DCTE_put_params((gs_param_list *) & list, &state)) < 0)
71 goto rel;
72 /* Create the filter. */
73 jcdp->template = s_DCTE_template;
74 /* Make sure we get at least a full scan line of input. */
75 state.scan_line_size = jcdp->cinfo.input_components *
76 jcdp->cinfo.image_width;
77 jcdp->template.min_in_size =
78 max(s_DCTE_template.min_in_size, state.scan_line_size);
79 /* Make sure we can write the user markers in a single go. */
80 jcdp->template.min_out_size =
81 max(s_DCTE_template.min_out_size, state.Markers.size);
82 code = filter_write(i_ctx_p, 0, &jcdp->template,
83 (stream_state *) & state, dspace);
84 if (code >= 0) /* Success! */
85 return code;
86 /* We assume that if filter_write fails, the stream has not been
87 * registered for closing, so s_DCTE_release will never be called.
88 * Therefore we free the allocated memory before failing.
89 */
90 rel:
91 iparam_list_release(&list);
92 fail:
93 gs_jpeg_destroy(&state);
94 gs_free_object(mem, jcdp, "zDCTE fail");
95 return code;
96 }
97
98 #ifdef TEST
99 #include "stream.h"
100 #include "files.h"
101 /* <dict> <filter> <bool> .dcteparams <dict> */
102 static int
zdcteparams(i_ctx_t * i_ctx_p)103 zdcteparams(i_ctx_t *i_ctx_p)
104 {
105 os_ptr op = osp;
106 stream *s;
107 dict_param_list list;
108 int code;
109
110 check_type(*op, t_boolean);
111 check_write_file(s, op - 1);
112 check_type(op[-2], t_dictionary);
113 /* The DCT filters copy the template.... */
114 if (s->state->template->process != s_DCTE_template.process)
115 return_error(e_rangecheck);
116 code = dict_param_list_write(&list, op - 2, NULL, iimemory);
117 if (code < 0)
118 return code;
119 code = s_DCTE_get_params((gs_param_list *) & list,
120 (stream_DCT_state *) s->state,
121 op->value.boolval);
122 iparam_list_release(&list);
123 if (code >= 0)
124 pop(2);
125 return code;
126 }
127 #endif
128
129 /* ------ Initialization procedure ------ */
130
131 const op_def zfdcte_op_defs[] =
132 {
133 #ifdef TEST
134 {"3.dcteparams", zdcteparams},
135 #endif
136 op_def_begin_filter(),
137 {"2DCTEncode", zDCTE},
138 op_def_end(0)
139 };
140