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