Branch data Line data Source code
1 : : /* -*- mode: C -*-
2 : : *
3 : : * File: pdf-stm-f-jbig2.c
4 : : * Date: Fri Nov 21 01:12:48 2008
5 : : *
6 : : * GNU PDF Library - JBIG2 encoder/decoder
7 : : *
8 : : */
9 : :
10 : : /* Copyright (C) 2008-2011 Free Software Foundation, Inc. */
11 : :
12 : : /* This program is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU General Public License as published by
14 : : * the Free Software Foundation, either version 3 of the License, or
15 : : * (at your option) any later version.
16 : : *
17 : : * This program is distributed in the hope that it will be useful,
18 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 : : * GNU General Public License for more details.
21 : : *
22 : : * You should have received a copy of the GNU General Public License
23 : : * along with this program. If not, see <http://www.gnu.org/licenses/>.
24 : : */
25 : :
26 : :
27 : : #include <config.h>
28 : :
29 : : #include <string.h>
30 : : #include <stdint.h>
31 : :
32 : : #include <jbig2.h>
33 : :
34 : : #include <pdf-hash-helper.h>
35 : : #include <pdf-stm-f-jbig2.h>
36 : : #include <pdf-types.h>
37 : : #include <pdf-types-buffer.h>
38 : : #include <pdf-hash.h>
39 : :
40 : : /* Define JBIG2 decoder */
41 : 0 : PDF_STM_FILTER_DEFINE (pdf_stm_f_jbig2dec_get,
42 : : stm_f_jbig2dec_init,
43 : : stm_f_jbig2dec_apply,
44 : : stm_f_jbig2dec_deinit);
45 : :
46 : : #define JBIG2_PARAM_GLOBAL_STREAMS_BUFFER "GlobalStreamsBuffer"
47 : : #define JBIG2_PARAM_GLOBAL_STREAMS_SIZE "GlobalStreamsSize"
48 : :
49 : : /* Internal state */
50 : : struct pdf_stm_f_jbig2dec_s
51 : : {
52 : : Jbig2Allocator *jbig2_allocator;
53 : : Jbig2Ctx *jbig2_context;
54 : : Jbig2GlobalCtx *jbig2_global_context;
55 : : Jbig2ErrorCallback jbig2_error_cb_fn;
56 : : Jbig2Image *jbig2_page;
57 : : pdf_size_t index;
58 : : pdf_bool_t error_p;
59 : : pdf_size_t data_size;
60 : : };
61 : :
62 : : static int jbig2dec_error_cb (void *data,
63 : : const char *msg,
64 : : Jbig2Severity severity,
65 : : int32_t seg_idx);
66 : :
67 : : static pdf_bool_t
68 : 0 : stm_f_jbig2dec_init (const pdf_hash_t *params,
69 : : void **state,
70 : : pdf_error_t **error)
71 : : {
72 : : struct pdf_stm_f_jbig2dec_s *filter_state;
73 : : pdf_char_t *global_stream_buffer;
74 : : pdf_size_t global_stream_size;
75 : :
76 : : /* Allocate the internal state structure */
77 : 0 : filter_state = pdf_alloc (sizeof (struct pdf_stm_f_jbig2dec_s));
78 [ # # ]: 0 : if (!filter_state)
79 : : {
80 : 0 : pdf_set_error (error,
81 : : PDF_EDOMAIN_BASE_STM,
82 : : PDF_ENOMEM,
83 : : "cannot create LZW encoder internal state: "
84 : : "couldn't allocate %lu bytes",
85 : : (unsigned long)sizeof (struct pdf_stm_f_jbig2dec_s));
86 : 0 : return PDF_FALSE;
87 : : }
88 : :
89 : : /* Initialize fields */
90 : 0 : filter_state->jbig2_allocator = NULL; /* Use default */
91 : 0 : filter_state->jbig2_error_cb_fn = jbig2dec_error_cb; /* Use default */
92 : 0 : filter_state->jbig2_page = NULL;
93 : 0 : filter_state->index = 0;
94 : 0 : filter_state->error_p = PDF_FALSE;
95 : :
96 : : /* Get the global stream contents, if any */
97 [ # # ][ # # ]: 0 : if (params &&
[ # # ]
98 : : pdf_hash_key_p (params, JBIG2_PARAM_GLOBAL_STREAMS_BUFFER) == PDF_TRUE &&
99 : : pdf_hash_key_p (params, JBIG2_PARAM_GLOBAL_STREAMS_SIZE) == PDF_TRUE)
100 : : {
101 : : /* Get the parameters from the hash table */
102 : 0 : global_stream_buffer = (pdf_char_t *) pdf_hash_get_string (params,
103 : : JBIG2_PARAM_GLOBAL_STREAMS_BUFFER);
104 : 0 : global_stream_size = pdf_hash_get_size (params,
105 : : JBIG2_PARAM_GLOBAL_STREAMS_SIZE);
106 : :
107 : : /* Initialize the global context */
108 : 0 : filter_state->jbig2_context = jbig2_ctx_new (filter_state->jbig2_allocator,
109 : : JBIG2_OPTIONS_EMBEDDED,
110 : : NULL,
111 : : filter_state->jbig2_error_cb_fn,
112 : : (void *) filter_state);
113 : :
114 : : /* Note. The data passed in this global stream buffer is consumed right
115 : : * away, there is no need to ensure that the global_stream_buffer is kept
116 : : * alive as long as the filter lives */
117 : 0 : jbig2_data_in (filter_state->jbig2_context,
118 : : (pdf_uchar_t *) global_stream_buffer,
119 : : global_stream_size);
120 : 0 : filter_state->jbig2_global_context =
121 : 0 : jbig2_make_global_ctx (filter_state->jbig2_context);
122 : : }
123 : : else
124 : : {
125 : : /* Do not use a global context */
126 : 0 : filter_state->jbig2_global_context = NULL;
127 : : }
128 : :
129 : 0 : filter_state->jbig2_context = jbig2_ctx_new (filter_state->jbig2_allocator,
130 : : JBIG2_OPTIONS_EMBEDDED,
131 : : filter_state->jbig2_global_context,
132 : : filter_state->jbig2_error_cb_fn,
133 : : (void *) filter_state);
134 : :
135 : 0 : *state = (void *) filter_state;
136 : 0 : return PDF_TRUE;
137 : : }
138 : :
139 : : static void
140 : 0 : stm_f_jbig2dec_deinit (void *state)
141 : : {
142 : 0 : struct pdf_stm_f_jbig2dec_s *filter_state = state;
143 : :
144 : 0 : jbig2_ctx_free (filter_state->jbig2_context);
145 : 0 : pdf_dealloc (filter_state);
146 : 0 : }
147 : :
148 : : static enum pdf_stm_filter_apply_status_e
149 : 0 : stm_f_jbig2dec_apply (void *state,
150 : : pdf_buffer_t *in,
151 : : pdf_buffer_t *out,
152 : : pdf_bool_t finish,
153 : : pdf_error_t **error)
154 : : {
155 : 0 : struct pdf_stm_f_jbig2dec_s *filter_state = state;
156 : : pdf_size_t bytes_to_copy;
157 : :
158 [ # # ]: 0 : if (finish)
159 : : {
160 : : /* Get the page, if needed */
161 [ # # ]: 0 : if (filter_state->jbig2_page == NULL)
162 : : {
163 : : /* Get the page */
164 : 0 : jbig2_complete_page (filter_state->jbig2_context);
165 : 0 : filter_state->jbig2_page =
166 : 0 : jbig2_page_out (filter_state->jbig2_context);
167 : : }
168 : :
169 [ # # ]: 0 : if (filter_state->jbig2_page == NULL)
170 : 0 : return PDF_STM_FILTER_APPLY_STATUS_EOF;
171 : :
172 : : /* Write out the data in the jbig2 page, if any */
173 : 0 : bytes_to_copy = out->size - out->wp;
174 [ # # ]: 0 : if ((filter_state->index + bytes_to_copy) >
175 : 0 : (filter_state->jbig2_page->height *
176 : 0 : filter_state->jbig2_page->stride))
177 : : {
178 : 0 : bytes_to_copy = ((filter_state->jbig2_page->height *
179 : 0 : filter_state->jbig2_page->stride)
180 : : - filter_state->index);
181 : : }
182 : :
183 : 0 : memcpy (out->data + out->wp,
184 : 0 : filter_state->jbig2_page->data + filter_state->index,
185 : : bytes_to_copy);
186 : :
187 : 0 : out->wp += bytes_to_copy;
188 : 0 : filter_state->index += bytes_to_copy;
189 : :
190 : : /* Determine the output state */
191 [ # # ]: 0 : if (filter_state->index ==
192 : 0 : (filter_state->jbig2_page->height *
193 : 0 : filter_state->jbig2_page->stride))
194 : : {
195 : 0 : jbig2_release_page(filter_state->jbig2_context,
196 : : filter_state->jbig2_page);
197 : 0 : return PDF_STM_FILTER_APPLY_STATUS_EOF;
198 : : }
199 : :
200 : 0 : return PDF_STM_FILTER_APPLY_STATUS_NO_OUTPUT;
201 : : }
202 : :
203 : : /* Write input into the decoder */
204 [ # # ]: 0 : PDF_ASSERT (in->wp >= in->rp);
205 : 0 : bytes_to_copy = (in->wp - in->rp);
206 : 0 : jbig2_data_in (filter_state->jbig2_context,
207 : : (pdf_uchar_t *) (in->data + in->rp),
208 : : bytes_to_copy);
209 : :
210 : : /* If any error, propagate it */
211 [ # # ]: 0 : if (filter_state->error_p == PDF_TRUE)
212 : : {
213 : 0 : pdf_set_error (error,
214 : : PDF_EDOMAIN_BASE_STM,
215 : : PDF_ERROR,
216 : : "jbig2dec error detected");
217 : 0 : return PDF_STM_FILTER_APPLY_STATUS_ERROR;
218 : : }
219 : :
220 : 0 : in->rp += bytes_to_copy;
221 : :
222 : 0 : return PDF_STM_FILTER_APPLY_STATUS_NO_INPUT;
223 : : }
224 : :
225 : : /*
226 : : * Private functions
227 : : */
228 : :
229 : : static int
230 : 0 : jbig2dec_error_cb (void *data,
231 : : const char *msg,
232 : : Jbig2Severity severity,
233 : : int32_t seg_idx)
234 : : {
235 : 0 : struct pdf_stm_f_jbig2dec_s *filter_state = data;
236 : :
237 [ # # ]: 0 : if (severity == JBIG2_SEVERITY_FATAL)
238 : 0 : filter_state->error_p = PDF_TRUE;
239 : :
240 : 0 : return 0;
241 : : }
242 : :
243 : : /* End of pdf-stm-f-jbig2.c */
|