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