1 | /* |
2 | * The copyright in this software is being made available under the 2-clauses |
3 | * BSD License, included below. This software may be subject to other third |
4 | * party and contributor rights, including patent rights, and no such rights |
5 | * are granted under this license. |
6 | * |
7 | * Copyright (c) 2005, Herve Drolon, FreeImage Team |
8 | * Copyright (c) 2008, 2011-2012, Centre National d'Etudes Spatiales (CNES), FR |
9 | * Copyright (c) 2012, CS Systemes d'Information, France |
10 | * All rights reserved. |
11 | * |
12 | * Redistribution and use in source and binary forms, with or without |
13 | * modification, are permitted provided that the following conditions |
14 | * are met: |
15 | * 1. Redistributions of source code must retain the above copyright |
16 | * notice, this list of conditions and the following disclaimer. |
17 | * 2. Redistributions in binary form must reproduce the above copyright |
18 | * notice, this list of conditions and the following disclaimer in the |
19 | * documentation and/or other materials provided with the distribution. |
20 | * |
21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' |
22 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
25 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
26 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
27 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
28 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
29 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
30 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
31 | * POSSIBILITY OF SUCH DAMAGE. |
32 | */ |
33 | |
34 | #ifdef _WIN32 |
35 | #include <windows.h> |
36 | #endif /* _WIN32 */ |
37 | |
38 | #include "opj_includes.h" |
39 | |
40 | |
41 | /* ---------------------------------------------------------------------- */ |
42 | /* Functions to set the message handlers */ |
43 | |
44 | OPJ_BOOL OPJ_CALLCONV opj_set_info_handler(opj_codec_t * p_codec, |
45 | opj_msg_callback p_callback, |
46 | void * p_user_data) |
47 | { |
48 | opj_codec_private_t * l_codec = (opj_codec_private_t *) p_codec; |
49 | if (! l_codec) { |
50 | return OPJ_FALSE; |
51 | } |
52 | |
53 | l_codec->m_event_mgr.info_handler = p_callback; |
54 | l_codec->m_event_mgr.m_info_data = p_user_data; |
55 | |
56 | return OPJ_TRUE; |
57 | } |
58 | |
59 | OPJ_BOOL OPJ_CALLCONV opj_set_warning_handler(opj_codec_t * p_codec, |
60 | opj_msg_callback p_callback, |
61 | void * p_user_data) |
62 | { |
63 | opj_codec_private_t * l_codec = (opj_codec_private_t *) p_codec; |
64 | if (! l_codec) { |
65 | return OPJ_FALSE; |
66 | } |
67 | |
68 | l_codec->m_event_mgr.warning_handler = p_callback; |
69 | l_codec->m_event_mgr.m_warning_data = p_user_data; |
70 | |
71 | return OPJ_TRUE; |
72 | } |
73 | |
74 | OPJ_BOOL OPJ_CALLCONV opj_set_error_handler(opj_codec_t * p_codec, |
75 | opj_msg_callback p_callback, |
76 | void * p_user_data) |
77 | { |
78 | opj_codec_private_t * l_codec = (opj_codec_private_t *) p_codec; |
79 | if (! l_codec) { |
80 | return OPJ_FALSE; |
81 | } |
82 | |
83 | l_codec->m_event_mgr.error_handler = p_callback; |
84 | l_codec->m_event_mgr.m_error_data = p_user_data; |
85 | |
86 | return OPJ_TRUE; |
87 | } |
88 | |
89 | /* ---------------------------------------------------------------------- */ |
90 | |
91 | static OPJ_SIZE_T opj_read_from_file(void * p_buffer, OPJ_SIZE_T p_nb_bytes, |
92 | FILE * p_file) |
93 | { |
94 | OPJ_SIZE_T l_nb_read = fread(p_buffer, 1, p_nb_bytes, p_file); |
95 | return l_nb_read ? l_nb_read : (OPJ_SIZE_T) - 1; |
96 | } |
97 | |
98 | static OPJ_UINT64 opj_get_data_length_from_file(FILE * p_file) |
99 | { |
100 | OPJ_OFF_T file_length = 0; |
101 | |
102 | OPJ_FSEEK(p_file, 0, SEEK_END); |
103 | file_length = (OPJ_OFF_T)OPJ_FTELL(p_file); |
104 | OPJ_FSEEK(p_file, 0, SEEK_SET); |
105 | |
106 | return (OPJ_UINT64)file_length; |
107 | } |
108 | |
109 | static OPJ_SIZE_T opj_write_from_file(void * p_buffer, OPJ_SIZE_T p_nb_bytes, |
110 | FILE * p_file) |
111 | { |
112 | return fwrite(p_buffer, 1, p_nb_bytes, p_file); |
113 | } |
114 | |
115 | static OPJ_OFF_T opj_skip_from_file(OPJ_OFF_T p_nb_bytes, FILE * p_user_data) |
116 | { |
117 | if (OPJ_FSEEK(p_user_data, p_nb_bytes, SEEK_CUR)) { |
118 | return -1; |
119 | } |
120 | |
121 | return p_nb_bytes; |
122 | } |
123 | |
124 | static OPJ_BOOL opj_seek_from_file(OPJ_OFF_T p_nb_bytes, FILE * p_user_data) |
125 | { |
126 | if (OPJ_FSEEK(p_user_data, p_nb_bytes, SEEK_SET)) { |
127 | return OPJ_FALSE; |
128 | } |
129 | |
130 | return OPJ_TRUE; |
131 | } |
132 | |
133 | /* ---------------------------------------------------------------------- */ |
134 | #ifdef _WIN32 |
135 | #ifndef OPJ_STATIC |
136 | BOOL APIENTRY |
137 | DllMain(HINSTANCE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) |
138 | { |
139 | |
140 | OPJ_ARG_NOT_USED(lpReserved); |
141 | OPJ_ARG_NOT_USED(hModule); |
142 | |
143 | switch (ul_reason_for_call) { |
144 | case DLL_PROCESS_ATTACH : |
145 | break; |
146 | case DLL_PROCESS_DETACH : |
147 | break; |
148 | case DLL_THREAD_ATTACH : |
149 | case DLL_THREAD_DETACH : |
150 | break; |
151 | } |
152 | |
153 | return TRUE; |
154 | } |
155 | #endif /* OPJ_STATIC */ |
156 | #endif /* _WIN32 */ |
157 | |
158 | /* ---------------------------------------------------------------------- */ |
159 | |
160 | const char* OPJ_CALLCONV opj_version(void) |
161 | { |
162 | return OPJ_PACKAGE_VERSION; |
163 | } |
164 | |
165 | /* ---------------------------------------------------------------------- */ |
166 | /* DECOMPRESSION FUNCTIONS*/ |
167 | |
168 | opj_codec_t* OPJ_CALLCONV opj_create_decompress(OPJ_CODEC_FORMAT p_format) |
169 | { |
170 | opj_codec_private_t *l_codec = 00; |
171 | |
172 | l_codec = (opj_codec_private_t*) opj_calloc(1, sizeof(opj_codec_private_t)); |
173 | if (!l_codec) { |
174 | return 00; |
175 | } |
176 | |
177 | l_codec->is_decompressor = 1; |
178 | |
179 | switch (p_format) { |
180 | case OPJ_CODEC_J2K: |
181 | l_codec->opj_dump_codec = (void (*)(void*, OPJ_INT32, FILE*)) j2k_dump; |
182 | |
183 | l_codec->opj_get_codec_info = (opj_codestream_info_v2_t* (*)( |
184 | void*)) j2k_get_cstr_info; |
185 | |
186 | l_codec->opj_get_codec_index = (opj_codestream_index_t* (*)( |
187 | void*)) j2k_get_cstr_index; |
188 | |
189 | l_codec->m_codec_data.m_decompression.opj_decode = |
190 | (OPJ_BOOL(*)(void *, |
191 | struct opj_stream_private *, |
192 | opj_image_t*, struct opj_event_mgr *)) opj_j2k_decode; |
193 | |
194 | l_codec->m_codec_data.m_decompression.opj_end_decompress = |
195 | (OPJ_BOOL(*)(void *, |
196 | struct opj_stream_private *, |
197 | struct opj_event_mgr *)) opj_j2k_end_decompress; |
198 | |
199 | l_codec->m_codec_data.m_decompression.opj_read_header = |
200 | (OPJ_BOOL(*)(struct opj_stream_private *, |
201 | void *, |
202 | opj_image_t **, |
203 | struct opj_event_mgr *)) opj_j2k_read_header; |
204 | |
205 | l_codec->m_codec_data.m_decompression.opj_destroy = |
206 | (void (*)(void *))opj_j2k_destroy; |
207 | |
208 | l_codec->m_codec_data.m_decompression.opj_setup_decoder = |
209 | (void (*)(void *, opj_dparameters_t *)) opj_j2k_setup_decoder; |
210 | |
211 | l_codec->m_codec_data.m_decompression.opj_read_tile_header = |
212 | (OPJ_BOOL(*)(void *, |
213 | OPJ_UINT32*, |
214 | OPJ_UINT32*, |
215 | OPJ_INT32*, OPJ_INT32*, |
216 | OPJ_INT32*, OPJ_INT32*, |
217 | OPJ_UINT32*, |
218 | OPJ_BOOL*, |
219 | struct opj_stream_private *, |
220 | struct opj_event_mgr *)) opj_j2k_read_tile_header; |
221 | |
222 | l_codec->m_codec_data.m_decompression.opj_decode_tile_data = |
223 | (OPJ_BOOL(*)(void *, |
224 | OPJ_UINT32, |
225 | OPJ_BYTE*, |
226 | OPJ_UINT32, |
227 | struct opj_stream_private *, |
228 | struct opj_event_mgr *)) opj_j2k_decode_tile; |
229 | |
230 | l_codec->m_codec_data.m_decompression.opj_set_decode_area = |
231 | (OPJ_BOOL(*)(void *, |
232 | opj_image_t*, |
233 | OPJ_INT32, OPJ_INT32, OPJ_INT32, OPJ_INT32, |
234 | struct opj_event_mgr *)) opj_j2k_set_decode_area; |
235 | |
236 | l_codec->m_codec_data.m_decompression.opj_get_decoded_tile = |
237 | (OPJ_BOOL(*)(void *p_codec, |
238 | opj_stream_private_t *p_cio, |
239 | opj_image_t *p_image, |
240 | struct opj_event_mgr * p_manager, |
241 | OPJ_UINT32 tile_index)) opj_j2k_get_tile; |
242 | |
243 | l_codec->m_codec_data.m_decompression.opj_set_decoded_resolution_factor = |
244 | (OPJ_BOOL(*)(void * p_codec, |
245 | OPJ_UINT32 res_factor, |
246 | struct opj_event_mgr * p_manager)) opj_j2k_set_decoded_resolution_factor; |
247 | |
248 | l_codec->m_codec_data.m_decompression.opj_set_decoded_components = |
249 | (OPJ_BOOL(*)(void * p_codec, |
250 | OPJ_UINT32 numcomps, |
251 | const OPJ_UINT32 * comps_indices, |
252 | struct opj_event_mgr * p_manager)) opj_j2k_set_decoded_components; |
253 | |
254 | l_codec->opj_set_threads = |
255 | (OPJ_BOOL(*)(void * p_codec, OPJ_UINT32 num_threads)) opj_j2k_set_threads; |
256 | |
257 | l_codec->m_codec = opj_j2k_create_decompress(); |
258 | |
259 | if (! l_codec->m_codec) { |
260 | opj_free(l_codec); |
261 | return NULL; |
262 | } |
263 | |
264 | break; |
265 | |
266 | case OPJ_CODEC_JP2: |
267 | /* get a JP2 decoder handle */ |
268 | l_codec->opj_dump_codec = (void (*)(void*, OPJ_INT32, FILE*)) jp2_dump; |
269 | |
270 | l_codec->opj_get_codec_info = (opj_codestream_info_v2_t* (*)( |
271 | void*)) jp2_get_cstr_info; |
272 | |
273 | l_codec->opj_get_codec_index = (opj_codestream_index_t* (*)( |
274 | void*)) jp2_get_cstr_index; |
275 | |
276 | l_codec->m_codec_data.m_decompression.opj_decode = |
277 | (OPJ_BOOL(*)(void *, |
278 | struct opj_stream_private *, |
279 | opj_image_t*, |
280 | struct opj_event_mgr *)) opj_jp2_decode; |
281 | |
282 | l_codec->m_codec_data.m_decompression.opj_end_decompress = |
283 | (OPJ_BOOL(*)(void *, |
284 | struct opj_stream_private *, |
285 | struct opj_event_mgr *)) opj_jp2_end_decompress; |
286 | |
287 | l_codec->m_codec_data.m_decompression.opj_read_header = |
288 | (OPJ_BOOL(*)(struct opj_stream_private *, |
289 | void *, |
290 | opj_image_t **, |
291 | struct opj_event_mgr *)) opj_jp2_read_header; |
292 | |
293 | l_codec->m_codec_data.m_decompression.opj_read_tile_header = |
294 | (OPJ_BOOL(*)(void *, |
295 | OPJ_UINT32*, |
296 | OPJ_UINT32*, |
297 | OPJ_INT32*, |
298 | OPJ_INT32*, |
299 | OPJ_INT32 *, |
300 | OPJ_INT32 *, |
301 | OPJ_UINT32 *, |
302 | OPJ_BOOL *, |
303 | struct opj_stream_private *, |
304 | struct opj_event_mgr *)) opj_jp2_read_tile_header; |
305 | |
306 | l_codec->m_codec_data.m_decompression.opj_decode_tile_data = |
307 | (OPJ_BOOL(*)(void *, |
308 | OPJ_UINT32, OPJ_BYTE*, OPJ_UINT32, |
309 | struct opj_stream_private *, |
310 | struct opj_event_mgr *)) opj_jp2_decode_tile; |
311 | |
312 | l_codec->m_codec_data.m_decompression.opj_destroy = (void (*)( |
313 | void *))opj_jp2_destroy; |
314 | |
315 | l_codec->m_codec_data.m_decompression.opj_setup_decoder = |
316 | (void (*)(void *, opj_dparameters_t *)) opj_jp2_setup_decoder; |
317 | |
318 | l_codec->m_codec_data.m_decompression.opj_set_decode_area = |
319 | (OPJ_BOOL(*)(void *, |
320 | opj_image_t*, |
321 | OPJ_INT32, OPJ_INT32, OPJ_INT32, OPJ_INT32, |
322 | struct opj_event_mgr *)) opj_jp2_set_decode_area; |
323 | |
324 | l_codec->m_codec_data.m_decompression.opj_get_decoded_tile = |
325 | (OPJ_BOOL(*)(void *p_codec, |
326 | opj_stream_private_t *p_cio, |
327 | opj_image_t *p_image, |
328 | struct opj_event_mgr * p_manager, |
329 | OPJ_UINT32 tile_index)) opj_jp2_get_tile; |
330 | |
331 | l_codec->m_codec_data.m_decompression.opj_set_decoded_resolution_factor = |
332 | (OPJ_BOOL(*)(void * p_codec, |
333 | OPJ_UINT32 res_factor, |
334 | opj_event_mgr_t * p_manager)) opj_jp2_set_decoded_resolution_factor; |
335 | |
336 | l_codec->m_codec_data.m_decompression.opj_set_decoded_components = |
337 | (OPJ_BOOL(*)(void * p_codec, |
338 | OPJ_UINT32 numcomps, |
339 | const OPJ_UINT32 * comps_indices, |
340 | struct opj_event_mgr * p_manager)) opj_jp2_set_decoded_components; |
341 | |
342 | l_codec->opj_set_threads = |
343 | (OPJ_BOOL(*)(void * p_codec, OPJ_UINT32 num_threads)) opj_jp2_set_threads; |
344 | |
345 | l_codec->m_codec = opj_jp2_create(OPJ_TRUE); |
346 | |
347 | if (! l_codec->m_codec) { |
348 | opj_free(l_codec); |
349 | return 00; |
350 | } |
351 | |
352 | break; |
353 | case OPJ_CODEC_UNKNOWN: |
354 | case OPJ_CODEC_JPT: |
355 | default: |
356 | opj_free(l_codec); |
357 | return 00; |
358 | } |
359 | |
360 | opj_set_default_event_handler(&(l_codec->m_event_mgr)); |
361 | return (opj_codec_t*) l_codec; |
362 | } |
363 | |
364 | void OPJ_CALLCONV opj_set_default_decoder_parameters(opj_dparameters_t |
365 | *parameters) |
366 | { |
367 | if (parameters) { |
368 | memset(parameters, 0, sizeof(opj_dparameters_t)); |
369 | /* default decoding parameters */ |
370 | parameters->cp_layer = 0; |
371 | parameters->cp_reduce = 0; |
372 | |
373 | parameters->decod_format = -1; |
374 | parameters->cod_format = -1; |
375 | parameters->flags = 0; |
376 | /* UniPG>> */ |
377 | #ifdef USE_JPWL |
378 | parameters->jpwl_correct = OPJ_FALSE; |
379 | parameters->jpwl_exp_comps = JPWL_EXPECTED_COMPONENTS; |
380 | parameters->jpwl_max_tiles = JPWL_MAXIMUM_TILES; |
381 | #endif /* USE_JPWL */ |
382 | /* <<UniPG */ |
383 | } |
384 | } |
385 | |
386 | |
387 | OPJ_BOOL OPJ_CALLCONV opj_codec_set_threads(opj_codec_t *p_codec, |
388 | int num_threads) |
389 | { |
390 | if (p_codec && (num_threads >= 0)) { |
391 | opj_codec_private_t * l_codec = (opj_codec_private_t *) p_codec; |
392 | |
393 | return l_codec->opj_set_threads(l_codec->m_codec, (OPJ_UINT32)num_threads); |
394 | } |
395 | return OPJ_FALSE; |
396 | } |
397 | |
398 | OPJ_BOOL OPJ_CALLCONV opj_setup_decoder(opj_codec_t *p_codec, |
399 | opj_dparameters_t *parameters |
400 | ) |
401 | { |
402 | if (p_codec && parameters) { |
403 | opj_codec_private_t * l_codec = (opj_codec_private_t *) p_codec; |
404 | |
405 | if (! l_codec->is_decompressor) { |
406 | opj_event_msg(&(l_codec->m_event_mgr), EVT_ERROR, |
407 | "Codec provided to the opj_setup_decoder function is not a decompressor handler.\n" ); |
408 | return OPJ_FALSE; |
409 | } |
410 | |
411 | l_codec->m_codec_data.m_decompression.opj_setup_decoder(l_codec->m_codec, |
412 | parameters); |
413 | return OPJ_TRUE; |
414 | } |
415 | return OPJ_FALSE; |
416 | } |
417 | |
418 | OPJ_BOOL OPJ_CALLCONV (opj_stream_t *p_stream, |
419 | opj_codec_t *p_codec, |
420 | opj_image_t **p_image) |
421 | { |
422 | if (p_codec && p_stream) { |
423 | opj_codec_private_t* l_codec = (opj_codec_private_t*) p_codec; |
424 | opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream; |
425 | |
426 | if (! l_codec->is_decompressor) { |
427 | opj_event_msg(&(l_codec->m_event_mgr), EVT_ERROR, |
428 | "Codec provided to the opj_read_header function is not a decompressor handler.\n" ); |
429 | return OPJ_FALSE; |
430 | } |
431 | |
432 | return l_codec->m_codec_data.m_decompression.opj_read_header(l_stream, |
433 | l_codec->m_codec, |
434 | p_image, |
435 | &(l_codec->m_event_mgr)); |
436 | } |
437 | |
438 | return OPJ_FALSE; |
439 | } |
440 | |
441 | |
442 | OPJ_BOOL OPJ_CALLCONV opj_set_decoded_components(opj_codec_t *p_codec, |
443 | OPJ_UINT32 numcomps, |
444 | const OPJ_UINT32* comps_indices, |
445 | OPJ_BOOL apply_color_transforms) |
446 | { |
447 | if (p_codec) { |
448 | opj_codec_private_t * l_codec = (opj_codec_private_t *) p_codec; |
449 | |
450 | if (! l_codec->is_decompressor) { |
451 | opj_event_msg(&(l_codec->m_event_mgr), EVT_ERROR, |
452 | "Codec provided to the opj_set_decoded_components function is not a decompressor handler.\n" ); |
453 | return OPJ_FALSE; |
454 | } |
455 | |
456 | if (apply_color_transforms) { |
457 | opj_event_msg(&(l_codec->m_event_mgr), EVT_ERROR, |
458 | "apply_color_transforms = OPJ_TRUE is not supported.\n" ); |
459 | return OPJ_FALSE; |
460 | } |
461 | |
462 | return l_codec->m_codec_data.m_decompression.opj_set_decoded_components( |
463 | l_codec->m_codec, |
464 | numcomps, |
465 | comps_indices, |
466 | &(l_codec->m_event_mgr)); |
467 | } |
468 | return OPJ_FALSE; |
469 | } |
470 | |
471 | OPJ_BOOL OPJ_CALLCONV opj_decode(opj_codec_t *p_codec, |
472 | opj_stream_t *p_stream, |
473 | opj_image_t* p_image) |
474 | { |
475 | if (p_codec && p_stream) { |
476 | opj_codec_private_t * l_codec = (opj_codec_private_t *) p_codec; |
477 | opj_stream_private_t * l_stream = (opj_stream_private_t *) p_stream; |
478 | |
479 | if (! l_codec->is_decompressor) { |
480 | return OPJ_FALSE; |
481 | } |
482 | |
483 | return l_codec->m_codec_data.m_decompression.opj_decode(l_codec->m_codec, |
484 | l_stream, |
485 | p_image, |
486 | &(l_codec->m_event_mgr)); |
487 | } |
488 | |
489 | return OPJ_FALSE; |
490 | } |
491 | |
492 | OPJ_BOOL OPJ_CALLCONV opj_set_decode_area(opj_codec_t *p_codec, |
493 | opj_image_t* p_image, |
494 | OPJ_INT32 p_start_x, OPJ_INT32 p_start_y, |
495 | OPJ_INT32 p_end_x, OPJ_INT32 p_end_y |
496 | ) |
497 | { |
498 | if (p_codec) { |
499 | opj_codec_private_t * l_codec = (opj_codec_private_t *) p_codec; |
500 | |
501 | if (! l_codec->is_decompressor) { |
502 | return OPJ_FALSE; |
503 | } |
504 | |
505 | return l_codec->m_codec_data.m_decompression.opj_set_decode_area( |
506 | l_codec->m_codec, |
507 | p_image, |
508 | p_start_x, p_start_y, |
509 | p_end_x, p_end_y, |
510 | &(l_codec->m_event_mgr)); |
511 | } |
512 | return OPJ_FALSE; |
513 | } |
514 | |
515 | OPJ_BOOL OPJ_CALLCONV (opj_codec_t *p_codec, |
516 | opj_stream_t * p_stream, |
517 | OPJ_UINT32 * p_tile_index, |
518 | OPJ_UINT32 * p_data_size, |
519 | OPJ_INT32 * p_tile_x0, OPJ_INT32 * p_tile_y0, |
520 | OPJ_INT32 * p_tile_x1, OPJ_INT32 * p_tile_y1, |
521 | OPJ_UINT32 * p_nb_comps, |
522 | OPJ_BOOL * p_should_go_on) |
523 | { |
524 | if (p_codec && p_stream && p_data_size && p_tile_index) { |
525 | opj_codec_private_t * l_codec = (opj_codec_private_t *) p_codec; |
526 | opj_stream_private_t * l_stream = (opj_stream_private_t *) p_stream; |
527 | |
528 | if (! l_codec->is_decompressor) { |
529 | return OPJ_FALSE; |
530 | } |
531 | |
532 | return l_codec->m_codec_data.m_decompression.opj_read_tile_header( |
533 | l_codec->m_codec, |
534 | p_tile_index, |
535 | p_data_size, |
536 | p_tile_x0, p_tile_y0, |
537 | p_tile_x1, p_tile_y1, |
538 | p_nb_comps, |
539 | p_should_go_on, |
540 | l_stream, |
541 | &(l_codec->m_event_mgr)); |
542 | } |
543 | return OPJ_FALSE; |
544 | } |
545 | |
546 | OPJ_BOOL OPJ_CALLCONV opj_decode_tile_data(opj_codec_t *p_codec, |
547 | OPJ_UINT32 p_tile_index, |
548 | OPJ_BYTE * p_data, |
549 | OPJ_UINT32 p_data_size, |
550 | opj_stream_t *p_stream |
551 | ) |
552 | { |
553 | if (p_codec && p_data && p_stream) { |
554 | opj_codec_private_t * l_codec = (opj_codec_private_t *) p_codec; |
555 | opj_stream_private_t * l_stream = (opj_stream_private_t *) p_stream; |
556 | |
557 | if (! l_codec->is_decompressor) { |
558 | return OPJ_FALSE; |
559 | } |
560 | |
561 | return l_codec->m_codec_data.m_decompression.opj_decode_tile_data( |
562 | l_codec->m_codec, |
563 | p_tile_index, |
564 | p_data, |
565 | p_data_size, |
566 | l_stream, |
567 | &(l_codec->m_event_mgr)); |
568 | } |
569 | return OPJ_FALSE; |
570 | } |
571 | |
572 | OPJ_BOOL OPJ_CALLCONV opj_get_decoded_tile(opj_codec_t *p_codec, |
573 | opj_stream_t *p_stream, |
574 | opj_image_t *p_image, |
575 | OPJ_UINT32 tile_index) |
576 | { |
577 | if (p_codec && p_stream) { |
578 | opj_codec_private_t * l_codec = (opj_codec_private_t *) p_codec; |
579 | opj_stream_private_t * l_stream = (opj_stream_private_t *) p_stream; |
580 | |
581 | if (! l_codec->is_decompressor) { |
582 | return OPJ_FALSE; |
583 | } |
584 | |
585 | return l_codec->m_codec_data.m_decompression.opj_get_decoded_tile( |
586 | l_codec->m_codec, |
587 | l_stream, |
588 | p_image, |
589 | &(l_codec->m_event_mgr), |
590 | tile_index); |
591 | } |
592 | |
593 | return OPJ_FALSE; |
594 | } |
595 | |
596 | OPJ_BOOL OPJ_CALLCONV opj_set_decoded_resolution_factor(opj_codec_t *p_codec, |
597 | OPJ_UINT32 res_factor) |
598 | { |
599 | opj_codec_private_t * l_codec = (opj_codec_private_t *) p_codec; |
600 | |
601 | if (!l_codec) { |
602 | return OPJ_FALSE; |
603 | } |
604 | |
605 | return l_codec->m_codec_data.m_decompression.opj_set_decoded_resolution_factor( |
606 | l_codec->m_codec, |
607 | res_factor, |
608 | &(l_codec->m_event_mgr)); |
609 | } |
610 | |
611 | /* ---------------------------------------------------------------------- */ |
612 | /* COMPRESSION FUNCTIONS*/ |
613 | |
614 | opj_codec_t* OPJ_CALLCONV opj_create_compress(OPJ_CODEC_FORMAT p_format) |
615 | { |
616 | opj_codec_private_t *l_codec = 00; |
617 | |
618 | l_codec = (opj_codec_private_t*)opj_calloc(1, sizeof(opj_codec_private_t)); |
619 | if (!l_codec) { |
620 | return 00; |
621 | } |
622 | |
623 | l_codec->is_decompressor = 0; |
624 | |
625 | switch (p_format) { |
626 | case OPJ_CODEC_J2K: |
627 | l_codec->m_codec_data.m_compression.opj_encode = (OPJ_BOOL(*)(void *, |
628 | struct opj_stream_private *, |
629 | struct opj_event_mgr *)) opj_j2k_encode; |
630 | |
631 | l_codec->m_codec_data.m_compression.opj_end_compress = (OPJ_BOOL(*)(void *, |
632 | struct opj_stream_private *, |
633 | struct opj_event_mgr *)) opj_j2k_end_compress; |
634 | |
635 | l_codec->m_codec_data.m_compression.opj_start_compress = (OPJ_BOOL(*)(void *, |
636 | struct opj_stream_private *, |
637 | struct opj_image *, |
638 | struct opj_event_mgr *)) opj_j2k_start_compress; |
639 | |
640 | l_codec->m_codec_data.m_compression.opj_write_tile = (OPJ_BOOL(*)(void *, |
641 | OPJ_UINT32, |
642 | OPJ_BYTE*, |
643 | OPJ_UINT32, |
644 | struct opj_stream_private *, |
645 | struct opj_event_mgr *)) opj_j2k_write_tile; |
646 | |
647 | l_codec->m_codec_data.m_compression.opj_destroy = (void (*)( |
648 | void *)) opj_j2k_destroy; |
649 | |
650 | l_codec->m_codec_data.m_compression.opj_setup_encoder = (OPJ_BOOL(*)(void *, |
651 | opj_cparameters_t *, |
652 | struct opj_image *, |
653 | struct opj_event_mgr *)) opj_j2k_setup_encoder; |
654 | |
655 | l_codec->m_codec = opj_j2k_create_compress(); |
656 | if (! l_codec->m_codec) { |
657 | opj_free(l_codec); |
658 | return 00; |
659 | } |
660 | |
661 | break; |
662 | |
663 | case OPJ_CODEC_JP2: |
664 | /* get a JP2 decoder handle */ |
665 | l_codec->m_codec_data.m_compression.opj_encode = (OPJ_BOOL(*)(void *, |
666 | struct opj_stream_private *, |
667 | struct opj_event_mgr *)) opj_jp2_encode; |
668 | |
669 | l_codec->m_codec_data.m_compression.opj_end_compress = (OPJ_BOOL(*)(void *, |
670 | struct opj_stream_private *, |
671 | struct opj_event_mgr *)) opj_jp2_end_compress; |
672 | |
673 | l_codec->m_codec_data.m_compression.opj_start_compress = (OPJ_BOOL(*)(void *, |
674 | struct opj_stream_private *, |
675 | struct opj_image *, |
676 | struct opj_event_mgr *)) opj_jp2_start_compress; |
677 | |
678 | l_codec->m_codec_data.m_compression.opj_write_tile = (OPJ_BOOL(*)(void *, |
679 | OPJ_UINT32, |
680 | OPJ_BYTE*, |
681 | OPJ_UINT32, |
682 | struct opj_stream_private *, |
683 | struct opj_event_mgr *)) opj_jp2_write_tile; |
684 | |
685 | l_codec->m_codec_data.m_compression.opj_destroy = (void (*)( |
686 | void *)) opj_jp2_destroy; |
687 | |
688 | l_codec->m_codec_data.m_compression.opj_setup_encoder = (OPJ_BOOL(*)(void *, |
689 | opj_cparameters_t *, |
690 | struct opj_image *, |
691 | struct opj_event_mgr *)) opj_jp2_setup_encoder; |
692 | |
693 | l_codec->m_codec = opj_jp2_create(OPJ_FALSE); |
694 | if (! l_codec->m_codec) { |
695 | opj_free(l_codec); |
696 | return 00; |
697 | } |
698 | |
699 | break; |
700 | |
701 | case OPJ_CODEC_UNKNOWN: |
702 | case OPJ_CODEC_JPT: |
703 | default: |
704 | opj_free(l_codec); |
705 | return 00; |
706 | } |
707 | |
708 | opj_set_default_event_handler(&(l_codec->m_event_mgr)); |
709 | return (opj_codec_t*) l_codec; |
710 | } |
711 | |
712 | void OPJ_CALLCONV opj_set_default_encoder_parameters(opj_cparameters_t |
713 | *parameters) |
714 | { |
715 | if (parameters) { |
716 | memset(parameters, 0, sizeof(opj_cparameters_t)); |
717 | /* default coding parameters */ |
718 | parameters->cp_cinema = OPJ_OFF; /* DEPRECATED */ |
719 | parameters->rsiz = OPJ_PROFILE_NONE; |
720 | parameters->max_comp_size = 0; |
721 | parameters->numresolution = 6; |
722 | parameters->cp_rsiz = OPJ_STD_RSIZ; /* DEPRECATED */ |
723 | parameters->cblockw_init = 64; |
724 | parameters->cblockh_init = 64; |
725 | parameters->prog_order = OPJ_LRCP; |
726 | parameters->roi_compno = -1; /* no ROI */ |
727 | parameters->subsampling_dx = 1; |
728 | parameters->subsampling_dy = 1; |
729 | parameters->tp_on = 0; |
730 | parameters->decod_format = -1; |
731 | parameters->cod_format = -1; |
732 | parameters->tcp_rates[0] = 0; |
733 | parameters->tcp_numlayers = 0; |
734 | parameters->cp_disto_alloc = 0; |
735 | parameters->cp_fixed_alloc = 0; |
736 | parameters->cp_fixed_quality = 0; |
737 | parameters->jpip_on = OPJ_FALSE; |
738 | /* UniPG>> */ |
739 | #ifdef USE_JPWL |
740 | parameters->jpwl_epc_on = OPJ_FALSE; |
741 | parameters->jpwl_hprot_MH = -1; /* -1 means unassigned */ |
742 | { |
743 | int i; |
744 | for (i = 0; i < JPWL_MAX_NO_TILESPECS; i++) { |
745 | parameters->jpwl_hprot_TPH_tileno[i] = -1; /* unassigned */ |
746 | parameters->jpwl_hprot_TPH[i] = 0; /* absent */ |
747 | } |
748 | }; |
749 | { |
750 | int i; |
751 | for (i = 0; i < JPWL_MAX_NO_PACKSPECS; i++) { |
752 | parameters->jpwl_pprot_tileno[i] = -1; /* unassigned */ |
753 | parameters->jpwl_pprot_packno[i] = -1; /* unassigned */ |
754 | parameters->jpwl_pprot[i] = 0; /* absent */ |
755 | } |
756 | }; |
757 | parameters->jpwl_sens_size = 0; /* 0 means no ESD */ |
758 | parameters->jpwl_sens_addr = 0; /* 0 means auto */ |
759 | parameters->jpwl_sens_range = 0; /* 0 means packet */ |
760 | parameters->jpwl_sens_MH = -1; /* -1 means unassigned */ |
761 | { |
762 | int i; |
763 | for (i = 0; i < JPWL_MAX_NO_TILESPECS; i++) { |
764 | parameters->jpwl_sens_TPH_tileno[i] = -1; /* unassigned */ |
765 | parameters->jpwl_sens_TPH[i] = -1; /* absent */ |
766 | } |
767 | }; |
768 | #endif /* USE_JPWL */ |
769 | /* <<UniPG */ |
770 | } |
771 | } |
772 | |
773 | OPJ_BOOL OPJ_CALLCONV opj_setup_encoder(opj_codec_t *p_codec, |
774 | opj_cparameters_t *parameters, |
775 | opj_image_t *p_image) |
776 | { |
777 | if (p_codec && parameters && p_image) { |
778 | opj_codec_private_t * l_codec = (opj_codec_private_t *) p_codec; |
779 | |
780 | if (! l_codec->is_decompressor) { |
781 | return l_codec->m_codec_data.m_compression.opj_setup_encoder(l_codec->m_codec, |
782 | parameters, |
783 | p_image, |
784 | &(l_codec->m_event_mgr)); |
785 | } |
786 | } |
787 | |
788 | return OPJ_FALSE; |
789 | } |
790 | |
791 | OPJ_BOOL OPJ_CALLCONV opj_start_compress(opj_codec_t *p_codec, |
792 | opj_image_t * p_image, |
793 | opj_stream_t *p_stream) |
794 | { |
795 | if (p_codec && p_stream) { |
796 | opj_codec_private_t * l_codec = (opj_codec_private_t *) p_codec; |
797 | opj_stream_private_t * l_stream = (opj_stream_private_t *) p_stream; |
798 | |
799 | if (! l_codec->is_decompressor) { |
800 | return l_codec->m_codec_data.m_compression.opj_start_compress(l_codec->m_codec, |
801 | l_stream, |
802 | p_image, |
803 | &(l_codec->m_event_mgr)); |
804 | } |
805 | } |
806 | |
807 | return OPJ_FALSE; |
808 | } |
809 | |
810 | OPJ_BOOL OPJ_CALLCONV opj_encode(opj_codec_t *p_info, opj_stream_t *p_stream) |
811 | { |
812 | if (p_info && p_stream) { |
813 | opj_codec_private_t * l_codec = (opj_codec_private_t *) p_info; |
814 | opj_stream_private_t * l_stream = (opj_stream_private_t *) p_stream; |
815 | |
816 | if (! l_codec->is_decompressor) { |
817 | return l_codec->m_codec_data.m_compression.opj_encode(l_codec->m_codec, |
818 | l_stream, |
819 | &(l_codec->m_event_mgr)); |
820 | } |
821 | } |
822 | |
823 | return OPJ_FALSE; |
824 | |
825 | } |
826 | |
827 | OPJ_BOOL OPJ_CALLCONV opj_end_compress(opj_codec_t *p_codec, |
828 | opj_stream_t *p_stream) |
829 | { |
830 | if (p_codec && p_stream) { |
831 | opj_codec_private_t * l_codec = (opj_codec_private_t *) p_codec; |
832 | opj_stream_private_t * l_stream = (opj_stream_private_t *) p_stream; |
833 | |
834 | if (! l_codec->is_decompressor) { |
835 | return l_codec->m_codec_data.m_compression.opj_end_compress(l_codec->m_codec, |
836 | l_stream, |
837 | &(l_codec->m_event_mgr)); |
838 | } |
839 | } |
840 | return OPJ_FALSE; |
841 | |
842 | } |
843 | |
844 | OPJ_BOOL OPJ_CALLCONV opj_end_decompress(opj_codec_t *p_codec, |
845 | opj_stream_t *p_stream) |
846 | { |
847 | if (p_codec && p_stream) { |
848 | opj_codec_private_t * l_codec = (opj_codec_private_t *) p_codec; |
849 | opj_stream_private_t * l_stream = (opj_stream_private_t *) p_stream; |
850 | |
851 | if (! l_codec->is_decompressor) { |
852 | return OPJ_FALSE; |
853 | } |
854 | |
855 | return l_codec->m_codec_data.m_decompression.opj_end_decompress( |
856 | l_codec->m_codec, |
857 | l_stream, |
858 | &(l_codec->m_event_mgr)); |
859 | } |
860 | |
861 | return OPJ_FALSE; |
862 | } |
863 | |
864 | OPJ_BOOL OPJ_CALLCONV opj_set_MCT(opj_cparameters_t *parameters, |
865 | OPJ_FLOAT32 * pEncodingMatrix, |
866 | OPJ_INT32 * p_dc_shift, OPJ_UINT32 pNbComp) |
867 | { |
868 | OPJ_UINT32 l_matrix_size = pNbComp * pNbComp * (OPJ_UINT32)sizeof(OPJ_FLOAT32); |
869 | OPJ_UINT32 l_dc_shift_size = pNbComp * (OPJ_UINT32)sizeof(OPJ_INT32); |
870 | OPJ_UINT32 l_mct_total_size = l_matrix_size + l_dc_shift_size; |
871 | |
872 | /* add MCT capability */ |
873 | if (OPJ_IS_PART2(parameters->rsiz)) { |
874 | parameters->rsiz |= OPJ_EXTENSION_MCT; |
875 | } else { |
876 | parameters->rsiz = ((OPJ_PROFILE_PART2) | (OPJ_EXTENSION_MCT)); |
877 | } |
878 | parameters->irreversible = 1; |
879 | |
880 | /* use array based MCT */ |
881 | parameters->tcp_mct = 2; |
882 | parameters->mct_data = opj_malloc(l_mct_total_size); |
883 | if (! parameters->mct_data) { |
884 | return OPJ_FALSE; |
885 | } |
886 | |
887 | memcpy(parameters->mct_data, pEncodingMatrix, l_matrix_size); |
888 | memcpy(((OPJ_BYTE *) parameters->mct_data) + l_matrix_size, p_dc_shift, |
889 | l_dc_shift_size); |
890 | |
891 | return OPJ_TRUE; |
892 | } |
893 | |
894 | OPJ_BOOL OPJ_CALLCONV opj_write_tile(opj_codec_t *p_codec, |
895 | OPJ_UINT32 p_tile_index, |
896 | OPJ_BYTE * p_data, |
897 | OPJ_UINT32 p_data_size, |
898 | opj_stream_t *p_stream) |
899 | { |
900 | if (p_codec && p_stream && p_data) { |
901 | opj_codec_private_t * l_codec = (opj_codec_private_t *) p_codec; |
902 | opj_stream_private_t * l_stream = (opj_stream_private_t *) p_stream; |
903 | |
904 | if (l_codec->is_decompressor) { |
905 | return OPJ_FALSE; |
906 | } |
907 | |
908 | return l_codec->m_codec_data.m_compression.opj_write_tile(l_codec->m_codec, |
909 | p_tile_index, |
910 | p_data, |
911 | p_data_size, |
912 | l_stream, |
913 | &(l_codec->m_event_mgr)); |
914 | } |
915 | |
916 | return OPJ_FALSE; |
917 | } |
918 | |
919 | /* ---------------------------------------------------------------------- */ |
920 | |
921 | void OPJ_CALLCONV opj_destroy_codec(opj_codec_t *p_codec) |
922 | { |
923 | if (p_codec) { |
924 | opj_codec_private_t * l_codec = (opj_codec_private_t *) p_codec; |
925 | |
926 | if (l_codec->is_decompressor) { |
927 | l_codec->m_codec_data.m_decompression.opj_destroy(l_codec->m_codec); |
928 | } else { |
929 | l_codec->m_codec_data.m_compression.opj_destroy(l_codec->m_codec); |
930 | } |
931 | |
932 | l_codec->m_codec = 00; |
933 | opj_free(l_codec); |
934 | } |
935 | } |
936 | |
937 | /* ---------------------------------------------------------------------- */ |
938 | |
939 | void OPJ_CALLCONV opj_dump_codec(opj_codec_t *p_codec, |
940 | OPJ_INT32 info_flag, |
941 | FILE* output_stream) |
942 | { |
943 | if (p_codec) { |
944 | opj_codec_private_t* l_codec = (opj_codec_private_t*) p_codec; |
945 | |
946 | l_codec->opj_dump_codec(l_codec->m_codec, info_flag, output_stream); |
947 | return; |
948 | } |
949 | |
950 | /* TODO return error */ |
951 | /* fprintf(stderr, "[ERROR] Input parameter of the dump_codec function are incorrect.\n"); */ |
952 | return; |
953 | } |
954 | |
955 | opj_codestream_info_v2_t* OPJ_CALLCONV opj_get_cstr_info(opj_codec_t *p_codec) |
956 | { |
957 | if (p_codec) { |
958 | opj_codec_private_t* l_codec = (opj_codec_private_t*) p_codec; |
959 | |
960 | return l_codec->opj_get_codec_info(l_codec->m_codec); |
961 | } |
962 | |
963 | return NULL; |
964 | } |
965 | |
966 | void OPJ_CALLCONV opj_destroy_cstr_info(opj_codestream_info_v2_t **cstr_info) |
967 | { |
968 | if (cstr_info) { |
969 | |
970 | if ((*cstr_info)->m_default_tile_info.tccp_info) { |
971 | opj_free((*cstr_info)->m_default_tile_info.tccp_info); |
972 | } |
973 | |
974 | if ((*cstr_info)->tile_info) { |
975 | /* FIXME not used for the moment*/ |
976 | } |
977 | |
978 | opj_free((*cstr_info)); |
979 | (*cstr_info) = NULL; |
980 | } |
981 | } |
982 | |
983 | opj_codestream_index_t * OPJ_CALLCONV opj_get_cstr_index(opj_codec_t *p_codec) |
984 | { |
985 | if (p_codec) { |
986 | opj_codec_private_t* l_codec = (opj_codec_private_t*) p_codec; |
987 | |
988 | return l_codec->opj_get_codec_index(l_codec->m_codec); |
989 | } |
990 | |
991 | return NULL; |
992 | } |
993 | |
994 | void OPJ_CALLCONV opj_destroy_cstr_index(opj_codestream_index_t **p_cstr_index) |
995 | { |
996 | if (*p_cstr_index) { |
997 | j2k_destroy_cstr_index(*p_cstr_index); |
998 | (*p_cstr_index) = NULL; |
999 | } |
1000 | } |
1001 | |
1002 | opj_stream_t* OPJ_CALLCONV opj_stream_create_default_file_stream( |
1003 | const char *fname, OPJ_BOOL p_is_read_stream) |
1004 | { |
1005 | return opj_stream_create_file_stream(fname, OPJ_J2K_STREAM_CHUNK_SIZE, |
1006 | p_is_read_stream); |
1007 | } |
1008 | |
1009 | opj_stream_t* OPJ_CALLCONV opj_stream_create_file_stream( |
1010 | const char *fname, |
1011 | OPJ_SIZE_T p_size, |
1012 | OPJ_BOOL p_is_read_stream) |
1013 | { |
1014 | opj_stream_t* l_stream = 00; |
1015 | FILE *p_file; |
1016 | const char *mode; |
1017 | |
1018 | if (! fname) { |
1019 | return NULL; |
1020 | } |
1021 | |
1022 | if (p_is_read_stream) { |
1023 | mode = "rb" ; |
1024 | } else { |
1025 | mode = "wb" ; |
1026 | } |
1027 | |
1028 | p_file = fopen(fname, mode); |
1029 | |
1030 | if (! p_file) { |
1031 | return NULL; |
1032 | } |
1033 | |
1034 | l_stream = opj_stream_create(p_size, p_is_read_stream); |
1035 | if (! l_stream) { |
1036 | fclose(p_file); |
1037 | return NULL; |
1038 | } |
1039 | |
1040 | opj_stream_set_user_data(l_stream, p_file, |
1041 | (opj_stream_free_user_data_fn) fclose); |
1042 | opj_stream_set_user_data_length(l_stream, |
1043 | opj_get_data_length_from_file(p_file)); |
1044 | opj_stream_set_read_function(l_stream, (opj_stream_read_fn) opj_read_from_file); |
1045 | opj_stream_set_write_function(l_stream, |
1046 | (opj_stream_write_fn) opj_write_from_file); |
1047 | opj_stream_set_skip_function(l_stream, (opj_stream_skip_fn) opj_skip_from_file); |
1048 | opj_stream_set_seek_function(l_stream, (opj_stream_seek_fn) opj_seek_from_file); |
1049 | |
1050 | return l_stream; |
1051 | } |
1052 | |
1053 | |
1054 | void* OPJ_CALLCONV opj_image_data_alloc(OPJ_SIZE_T size) |
1055 | { |
1056 | void* ret = opj_aligned_malloc(size); |
1057 | /* printf("opj_image_data_alloc %p\n", ret); */ |
1058 | return ret; |
1059 | } |
1060 | |
1061 | void OPJ_CALLCONV opj_image_data_free(void* ptr) |
1062 | { |
1063 | /* printf("opj_image_data_free %p\n", ptr); */ |
1064 | opj_aligned_free(ptr); |
1065 | } |
1066 | |