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, 2009 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 :
31 : #include <pdf-hash-helper.h>
32 : #include <pdf-stm-f-jbig2.h>
33 :
34 : static int jbig2dec_error_cb (void *data,
35 : const char *msg, Jbig2Severity severity,
36 : int32_t seg_idx);
37 :
38 :
39 : pdf_status_t
40 : pdf_stm_f_jbig2dec_init (pdf_hash_t params,
41 : void **state)
42 0 : {
43 : pdf_stm_f_jbig2dec_t filter_state;
44 : pdf_char_t *global_stream_buffer;
45 : pdf_size_t global_stream_size;
46 :
47 :
48 : /* Allocate the internal state structure */
49 0 : filter_state = pdf_alloc (sizeof (struct pdf_stm_f_jbig2dec_s));
50 0 : if (filter_state == NULL)
51 : {
52 0 : return PDF_ERROR;
53 : }
54 :
55 : /* Initialize fields */
56 0 : filter_state->jbig2_allocator = NULL; /* Use default */
57 0 : filter_state->jbig2_error_cb_fn = jbig2dec_error_cb; /* Use default */
58 0 : filter_state->jbig2_page = NULL;
59 0 : filter_state->index = 0;
60 0 : filter_state->error_p = PDF_FALSE;
61 :
62 : /* Get the global stream contents, if any */
63 0 : if ((pdf_hash_key_p (params, "GlobalStreamsBuffer") == PDF_TRUE) &&
64 : (pdf_hash_key_p (params, "GlobalStreamsSize") == PDF_TRUE))
65 : {
66 : /* Get the parameters from the hash table */
67 0 : pdf_hash_get_string (params,
68 : "GlobalStreamsBuffer",
69 : &global_stream_buffer);
70 0 : pdf_hash_get_size (params,
71 : "GlobalStreamsSize",
72 : &global_stream_size);
73 :
74 : /* Initialize the global context */
75 0 : filter_state->jbig2_context = jbig2_ctx_new (filter_state->jbig2_allocator,
76 : JBIG2_OPTIONS_EMBEDDED,
77 : NULL,
78 : filter_state->jbig2_error_cb_fn,
79 : (void *) filter_state);
80 :
81 0 : jbig2_data_in (filter_state->jbig2_context,
82 : global_stream_buffer,
83 : global_stream_size);
84 0 : filter_state->jbig2_global_context =
85 : jbig2_make_global_ctx (filter_state->jbig2_context);
86 : }
87 : else
88 : {
89 : /* Do not use a global context */
90 0 : filter_state->jbig2_global_context = NULL;
91 : }
92 :
93 0 : filter_state->jbig2_context = jbig2_ctx_new (filter_state->jbig2_allocator,
94 : JBIG2_OPTIONS_EMBEDDED,
95 : filter_state->jbig2_global_context,
96 : filter_state->jbig2_error_cb_fn,
97 : (void *) filter_state);
98 :
99 0 : *state = (void *) filter_state;
100 0 : return PDF_OK;
101 : }
102 :
103 : pdf_status_t
104 : pdf_stm_f_jbig2dec_apply (pdf_hash_t params,
105 : void *state,
106 : pdf_buffer_t in,
107 : pdf_buffer_t out,
108 : pdf_bool_t finish_p)
109 0 : {
110 : pdf_status_t ret;
111 : pdf_stm_f_jbig2dec_t filter_state;
112 : pdf_size_t bytes_to_copy;
113 0 : filter_state = (pdf_stm_f_jbig2dec_t) state;
114 :
115 0 : ret = PDF_OK;
116 :
117 0 : if (finish_p)
118 : {
119 : /* Get the page, if needed */
120 0 : if (filter_state->jbig2_page == NULL)
121 : {
122 : /* Get the page */
123 0 : jbig2_complete_page (filter_state->jbig2_context);
124 0 : filter_state->jbig2_page =
125 : jbig2_page_out (filter_state->jbig2_context);
126 : }
127 :
128 : /* Write out the data in the jbig2 page, if any */
129 0 : if (filter_state->jbig2_page != NULL)
130 : {
131 0 : bytes_to_copy = out->size - out->wp;
132 0 : if ((filter_state->index + bytes_to_copy)
133 : > (filter_state->jbig2_page->height * filter_state->jbig2_page->stride))
134 : {
135 0 : bytes_to_copy = ((filter_state->jbig2_page->height * filter_state->jbig2_page->stride)
136 : - filter_state->index);
137 : }
138 :
139 0 : memcpy (out->data + out->wp,
140 : filter_state->jbig2_page->data + filter_state->index,
141 : bytes_to_copy);
142 :
143 0 : out->wp += bytes_to_copy;
144 0 : filter_state->index += bytes_to_copy;
145 :
146 : /* Determine the output state */
147 0 : if (filter_state->index ==
148 : (filter_state->jbig2_page->height * filter_state->jbig2_page->stride))
149 : {
150 0 : jbig2_release_page(filter_state->jbig2_context,
151 : filter_state->jbig2_page);
152 0 : ret = PDF_EEOF;
153 : }
154 : else
155 : {
156 0 : ret = PDF_ENOUTPUT;
157 : }
158 : }
159 : else
160 : {
161 0 : ret = PDF_EEOF;
162 : }
163 : }
164 : else
165 : {
166 : /* Write input into the decoder */
167 0 : bytes_to_copy = (in->wp - in->rp);
168 0 : jbig2_data_in (filter_state->jbig2_context,
169 : in->data + in->rp,
170 : bytes_to_copy);
171 0 : if (filter_state->error_p == PDF_TRUE)
172 : {
173 0 : return PDF_ERROR;
174 : }
175 :
176 0 : in->rp += bytes_to_copy;
177 :
178 0 : ret = PDF_ENINPUT;
179 : }
180 :
181 0 : return ret;
182 : }
183 :
184 : pdf_status_t
185 : pdf_stm_f_jbig2dec_dealloc_state (void *state)
186 0 : {
187 : pdf_stm_f_jbig2dec_t filter_state;
188 0 : filter_state = (pdf_stm_f_jbig2dec_t) state;
189 :
190 0 : jbig2_ctx_free (filter_state->jbig2_context);
191 0 : pdf_dealloc (filter_state);
192 :
193 0 : return PDF_OK;
194 : }
195 :
196 : /*
197 : * Private functions
198 : */
199 :
200 : static int
201 : jbig2dec_error_cb (void *data,
202 : const char *msg,
203 : Jbig2Severity severity,
204 : int32_t seg_idx)
205 0 : {
206 : pdf_stm_f_jbig2dec_t filter_state;
207 :
208 0 : filter_state = (pdf_stm_f_jbig2dec_t) data;
209 :
210 0 : if (severity == JBIG2_SEVERITY_FATAL)
211 : {
212 0 : filter_state->error_p = PDF_TRUE;
213 : }
214 :
215 0 : return 0;
216 : }
217 :
218 : /* End of pdf-stm-f-jbig2.c */
|