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