Leptonica 1.84.1
Image processing and image analysis suite
Loading...
Searching...
No Matches
jp2kio.c
Go to the documentation of this file.
1/*====================================================================*
2 - Copyright (C) 2001 Leptonica. All rights reserved.
3 -
4 - Redistribution and use in source and binary forms, with or without
5 - modification, are permitted provided that the following conditions
6 - are met:
7 - 1. Redistributions of source code must retain the above copyright
8 - notice, this list of conditions and the following disclaimer.
9 - 2. Redistributions in binary form must reproduce the above
10 - copyright notice, this list of conditions and the following
11 - disclaimer in the documentation and/or other materials
12 - provided with the distribution.
13 -
14 - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
15 - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
16 - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
17 - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ANY
18 - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22 - OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
23 - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 *====================================================================*/
26
96#ifdef HAVE_CONFIG_H
97#include <config_auto.h>
98#endif /* HAVE_CONFIG_H */
99
100#include <string.h>
101#include "allheaders.h"
102
103/* --------------------------------------------*/
104#if HAVE_LIBJP2K /* defined in environ.h */
105/* --------------------------------------------*/
106
107 /* Leptonica supports versions 2.1 and later */
108#ifdef LIBJP2K_HEADER
109#include LIBJP2K_HEADER
110#else
111#include <openjpeg.h>
112#endif
113
114 /* Static generator of opj_stream from file stream.
115 * In 2.0.1, this functionality is provided by
116 * opj_stream_create_default_file_stream(),
117 * but it was removed in 2.1.0. Because we must have either
118 * a file stream or a memory interface to the compressed data,
119 * it is necessary to recreate the stream interface here. */
120static opj_stream_t *opjCreateStream(FILE *fp, l_int32 is_read);
121
122 /* Static converter pix --> opj_image. Used for compressing pix,
123 * because the codec works on data stored in their raster format. */
124static opj_image_t *pixConvertToOpjImage(PIX *pix);
125
126/*---------------------------------------------------------------------*
127 * Callback event handlers *
128 *---------------------------------------------------------------------*/
129static void error_callback(const char *msg, void *client_data) {
130 (void)client_data;
131 fprintf(stdout, "[ERROR] %s", msg);
132}
133
134static void warning_callback(const char *msg, void *client_data) {
135 (void)client_data;
136 fprintf(stdout, "[WARNING] %s", msg);
137}
138
139static void info_callback(const char *msg, void *client_data) {
140 (void)client_data;
141 fprintf(stdout, "[INFO] %s", msg);
142}
143
144
145/*---------------------------------------------------------------------*
146 * Read jp2k from file (special function) *
147 *---------------------------------------------------------------------*/
187PIX *
188pixReadJp2k(const char *filename,
189 l_uint32 reduction,
190 BOX *box,
191 l_int32 hint,
192 l_int32 debug)
193{
194FILE *fp;
195PIX *pix;
196
197 if (!filename)
198 return (PIX *)ERROR_PTR("filename not defined", __func__, NULL);
199
200 if ((fp = fopenReadStream(filename)) == NULL)
201 return (PIX *)ERROR_PTR_1("image file not found",
202 filename, __func__, NULL);
203 pix = pixReadStreamJp2k(fp, reduction, box, hint, debug);
204 fclose(fp);
205
206 if (!pix)
207 return (PIX *)ERROR_PTR_1("image not returned",
208 filename, __func__, NULL);
209 return pix;
210}
211
212
228PIX *
229pixReadStreamJp2k(FILE *fp,
230 l_uint32 reduction,
231 BOX *box,
232 l_int32 hint,
233 l_int32 debug)
234{
235const char *opjVersion;
236l_int32 i, j, index, bx, by, bw, bh, val, rval, gval, bval, aval;
237l_int32 w, h, wpl, bps, spp, xres, yres, reduce, prec, colorspace;
238l_int32 codec; /* L_J2K_CODEC or L_JP2_CODEC */
239l_uint32 pixel;
240l_uint32 *data, *line;
241opj_dparameters_t parameters; /* decompression parameters */
242opj_image_t *image = NULL;
243opj_codec_t *l_codec = NULL; /* handle to decompressor */
244opj_stream_t *l_stream = NULL; /* opj stream */
245PIX *pix = NULL;
246
247 if (!fp)
248 return (PIX *)ERROR_PTR("fp not defined", __func__, NULL);
249
250 opjVersion = opj_version();
251 if (!opjVersion || opjVersion[0] == '\0')
252 return (PIX *)ERROR_PTR("opj version not defined", __func__, NULL);
253 if (opjVersion[0] - 0x30 < 2 ||
254 (opjVersion[0] == '2' && opjVersion[2] - 0x30 == 0)) {
255 L_ERROR("version is %s; must be 2.1 or higher\n", __func__, opjVersion);
256 return NULL;
257 }
258
259 /* Get the resolution, bits/sample and codec type */
260 rewind(fp);
261 fgetJp2kResolution(fp, &xres, &yres);
262 freadHeaderJp2k(fp, NULL, NULL, &bps, NULL, &codec);
263 rewind(fp);
264 if (codec != L_J2K_CODEC && codec != L_JP2_CODEC) {
265 L_ERROR("valid codec not identified\n", __func__);
266 return NULL;
267 }
268
269 if (bps != 8) {
270 L_ERROR("found %d bps; can only handle 8 bps\n", __func__, bps);
271 return NULL;
272 }
273
274 /* Set decoding parameters to default values */
275 opj_set_default_decoder_parameters(&parameters);
276
277 /* Find and set the reduce parameter, which is log2(reduction).
278 * Valid reductions are powers of 2, and are determined when the
279 * compressed string is made. A request for an invalid reduction
280 * will cause an error in opj_read_header(), and no image will
281 * be returned. */
282 for (reduce = 0; (1L << reduce) < reduction; reduce++) { }
283 if ((1L << reduce) != reduction) {
284 L_ERROR("invalid reduction %d; not power of 2\n", __func__, reduction);
285 return NULL;
286 }
287 parameters.cp_reduce = reduce;
288
289 /* Get a decoder handle */
290 if (codec == L_JP2_CODEC)
291 l_codec = opj_create_decompress(OPJ_CODEC_JP2);
292 else if (codec == L_J2K_CODEC)
293 l_codec = opj_create_decompress(OPJ_CODEC_J2K);
294 if (!l_codec) {
295 L_ERROR("failed to make the codec\n", __func__);
296 return NULL;
297 }
298
299 /* Catch and report events using callbacks */
300 if (debug) {
301 opj_set_info_handler(l_codec, info_callback, NULL);
302 opj_set_warning_handler(l_codec, warning_callback, NULL);
303 opj_set_error_handler(l_codec, error_callback, NULL);
304 }
305
306 /* Setup the decoding parameters using user parameters */
307 if (!opj_setup_decoder(l_codec, &parameters)){
308 L_ERROR("failed to set up decoder\n", __func__);
309 opj_destroy_codec(l_codec);
310 return NULL;
311 }
312
313 /* Open decompression 'stream'. This uses our version of the
314 * function that was removed in 2.1. */
315 if ((l_stream = opjCreateStream(fp, 1)) == NULL) {
316 L_ERROR("failed to open the stream\n", __func__);
317 opj_destroy_codec(l_codec);
318 return NULL;
319 }
320
321 /* Read the main header of the codestream and, if necessary,
322 * the JP2 boxes */
323 if(!opj_read_header(l_stream, l_codec, &image)){
324 L_ERROR("failed to read the header\n", __func__);
325 opj_stream_destroy(l_stream);
326 opj_destroy_codec(l_codec);
327 opj_image_destroy(image);
328 return NULL;
329 }
330
331 /* Set up to decode a rectangular region */
332 if (box) {
333 boxGetGeometry(box, &bx, &by, &bw, &bh);
334 if (!opj_set_decode_area(l_codec, image, bx, by,
335 bx + bw, by + bh)) {
336 L_ERROR("failed to set the region for decoding\n", __func__);
337 opj_stream_destroy(l_stream);
338 opj_destroy_codec(l_codec);
339 opj_image_destroy(image);
340 return NULL;
341 }
342 }
343
344 /* Get the decoded image */
345 if (!(opj_decode(l_codec, l_stream, image) &&
346 opj_end_decompress(l_codec, l_stream))) {
347 L_ERROR("failed to decode the image\n", __func__);
348 opj_destroy_codec(l_codec);
349 opj_stream_destroy(l_stream);
350 opj_image_destroy(image);
351 return NULL;
352 }
353
354 /* Finished with the byte stream and the codec */
355 opj_stream_destroy(l_stream);
356 opj_destroy_codec(l_codec);
357
358 /* Get the image parameters */
359 spp = image->numcomps;
360 w = image->comps[0].w;
361 h = image->comps[0].h;
362 prec = image->comps[0].prec;
363 if (prec != bps)
364 L_WARNING("precision %d != bps %d!\n", __func__, prec, bps);
365 if (debug) {
366 L_INFO("w = %d, h = %d, bps = %d, spp = %d\n",
367 __func__, w, h, bps, spp);
368 colorspace = image->color_space;
369 if (colorspace == OPJ_CLRSPC_SRGB)
370 L_INFO("colorspace is sRGB\n", __func__);
371 else if (colorspace == OPJ_CLRSPC_GRAY)
372 L_INFO("colorspace is grayscale\n", __func__);
373 else if (colorspace == OPJ_CLRSPC_SYCC)
374 L_INFO("colorspace is YUV\n", __func__);
375 }
376
377 /* Convert the image to a pix */
378 if (spp == 1)
379 pix = pixCreate(w, h, 8);
380 else
381 pix = pixCreate(w, h, 32);
382 pixSetInputFormat(pix, IFF_JP2);
383 pixSetResolution(pix, xres, yres);
384 data = pixGetData(pix);
385 wpl = pixGetWpl(pix);
386 index = 0;
387 if (spp == 1) {
388 for (i = 0; i < h; i++) {
389 line = data + i * wpl;
390 for (j = 0; j < w; j++) {
391 val = image->comps[0].data[index];
392 SET_DATA_BYTE(line, j, val);
393 index++;
394 }
395 }
396 } else if (spp == 2) { /* convert to RGBA */
397 for (i = 0; i < h; i++) {
398 line = data + i * wpl;
399 for (j = 0; j < w; j++) {
400 val = image->comps[0].data[index];
401 aval = image->comps[1].data[index];
402 composeRGBAPixel(val, val, val, aval, &pixel);
403 line[j] = pixel;
404 index++;
405 }
406 }
407 } else if (spp >= 3) {
408 for (i = 0; i < h; i++) {
409 line = data + i * wpl;
410 for (j = 0; j < w; j++) {
411 rval = image->comps[0].data[index];
412 gval = image->comps[1].data[index];
413 bval = image->comps[2].data[index];
414 if (spp == 3) {
415 composeRGBPixel(rval, gval, bval, &pixel);
416 } else { /* spp == 4 */
417 aval = image->comps[3].data[index];
418 composeRGBAPixel(rval, gval, bval, aval, &pixel);
419 }
420 line[j] = pixel;
421 index++;
422 }
423 }
424 }
425
426 /* Free the opj image data structure */
427 opj_image_destroy(image);
428
429 return pix;
430}
431
432
433/*---------------------------------------------------------------------*
434 * Write jp2k to file *
435 *---------------------------------------------------------------------*/
465l_ok
466pixWriteJp2k(const char *filename,
467 PIX *pix,
468 l_int32 quality,
469 l_int32 nlevels,
470 l_int32 hint,
471 l_int32 debug)
472{
473FILE *fp;
474
475 if (!pix)
476 return ERROR_INT("pix not defined", __func__, 1);
477 if (!filename)
478 return ERROR_INT("filename not defined", __func__, 1);
479
480 if ((fp = fopenWriteStream(filename, "wb+")) == NULL)
481 return ERROR_INT_1("stream not opened", filename, __func__, 1);
482
483 if (pixWriteStreamJp2k(fp, pix, quality, nlevels, L_JP2_CODEC,
484 hint, debug)) {
485 fclose(fp);
486 return ERROR_INT_1("pix not written to stream", filename, __func__, 1);
487 }
488
489 fclose(fp);
490 return 0;
491}
492
493
510l_ok
511pixWriteStreamJp2k(FILE *fp,
512 PIX *pix,
513 l_int32 quality,
514 l_int32 nlevels,
515 l_int32 codec,
516 l_int32 hint,
517 l_int32 debug)
518{
519l_int32 w, h, d, success;
520l_float32 snr;
521const char *opjVersion;
522PIX *pixs;
523opj_cparameters_t parameters; /* compression parameters */
524opj_stream_t *l_stream = NULL;
525opj_codec_t* l_codec = NULL;;
526opj_image_t *image = NULL;
527
528 if (!fp)
529 return ERROR_INT("stream not open", __func__, 1);
530 if (!pix)
531 return ERROR_INT("pix not defined", __func__, 1);
532
533 snr = (l_float32)quality;
534 if (snr <= 0) snr = 34.0; /* default */
535 if (snr < 27)
536 L_WARNING("SNR = %d < 27; very low\n", __func__, (l_int32)snr);
537 if (snr == 100) snr = 0; /* for lossless */
538 if (snr > 45) {
539 L_WARNING("SNR > 45; using lossless encoding\n", __func__);
540 snr = 0;
541 }
542
543 if (nlevels <= 0) nlevels = 5; /* default */
544 if (nlevels > 10) {
545 L_WARNING("nlevels = %d > 10; setting to 10\n", __func__, nlevels);
546 nlevels = 10;
547 }
548 if (codec != L_JP2_CODEC && codec != L_J2K_CODEC)
549 return ERROR_INT("valid codec not identified\n", __func__, 1);
550
551 opjVersion = opj_version();
552 if (!opjVersion || opjVersion[0] == '\0')
553 return ERROR_INT("opj version not defined", __func__, 1);
554 if (opjVersion[0] - 0x30 < 2 ||
555 (opjVersion[0] == '2' && opjVersion[2] - 0x30 == 0)) {
556 L_ERROR("version is %s; must be 2.1 or higher\n", __func__, opjVersion);
557 return 1;
558 }
559
560 /* Remove colormap if it exists; result is 8 or 32 bpp */
561 pixGetDimensions(pix, &w, &h, &d);
562 if (d == 24) {
563 pixs = pixConvert24To32(pix);
564 } else if (d == 32) {
565 pixs = pixClone(pix);
566 } else if (pixGetColormap(pix) == NULL) {
567 pixs = pixConvertTo8(pix, 0);
568 } else { /* colormap */
569 L_INFO("removing colormap; may be better to compress losslessly\n",
570 __func__);
571 pixs = pixRemoveColormap(pix, REMOVE_CMAP_BASED_ON_SRC);
572 }
573
574 /* Convert to opj image format. */
575 pixSetPadBits(pixs, 0);
576 image = pixConvertToOpjImage(pixs);
577 pixDestroy(&pixs);
578
579 /* Set encoding parameters to default values.
580 * We use one layer with the input SNR. */
581 opj_set_default_encoder_parameters(&parameters);
582 parameters.cp_fixed_quality = 1;
583 parameters.cp_disto_alloc = 0;
584 parameters.cp_fixed_alloc = 0;
585 parameters.tcp_distoratio[0] = snr;
586 parameters.tcp_numlayers = 1;
587 parameters.numresolution = nlevels;
588
589 /* Create comment for codestream */
590 if (parameters.cp_comment == NULL) {
591 const char comment1[] = "Created by Leptonica, version ";
592 const char comment2[] = "; using OpenJPEG, version ";
593 size_t len1 = strlen(comment1);
594 size_t len2 = strlen(comment2);
595 char *version1 = getLeptonicaVersion();
596 const char *version2 = opj_version();
597 len1 += len2 + strlen(version1) + strlen(version2) + 1;
598 parameters.cp_comment = (char *)LEPT_MALLOC(len1);
599 snprintf(parameters.cp_comment, len1, "%s%s%s%s", comment1, version1,
600 comment2, version2);
601 LEPT_FREE(version1);
602 }
603
604 /* Get the encoder handle */
605 if (codec == L_JP2_CODEC)
606 l_codec = opj_create_compress(OPJ_CODEC_JP2);
607 else /* codec == L_J2K_CODEC */
608 l_codec = opj_create_compress(OPJ_CODEC_J2K);
609 if (!l_codec) {
610 opj_image_destroy(image);
611 LEPT_FREE(parameters.cp_comment);
612 return ERROR_INT("failed to get the encoder handle\n", __func__, 1);
613 }
614
615 /* Catch and report events using callbacks */
616 if (debug) {
617 opj_set_info_handler(l_codec, info_callback, NULL);
618 opj_set_warning_handler(l_codec, warning_callback, NULL);
619 opj_set_error_handler(l_codec, error_callback, NULL);
620 }
621
622 /* Set up the encoder */
623 if (!opj_setup_encoder(l_codec, &parameters, image)) {
624 opj_destroy_codec(l_codec);
625 opj_image_destroy(image);
626 LEPT_FREE(parameters.cp_comment);
627 return ERROR_INT("failed to set up the encoder\n", __func__, 1);
628 }
629
630 /* Set the resolution (TBD) */
631
632 /* Open compression stream for writing. This uses our version
633 * of the function that was removed in 2.1. */
634 rewind(fp);
635 if ((l_stream = opjCreateStream(fp, 0)) == NULL) {
636 opj_destroy_codec(l_codec);
637 opj_image_destroy(image);
638 LEPT_FREE(parameters.cp_comment);
639 return ERROR_INT("failed to open l_stream\n", __func__, 1);
640 }
641
642 /* Encode the image */
643 if (!opj_start_compress(l_codec, image, l_stream)) {
644 opj_stream_destroy(l_stream);
645 opj_destroy_codec(l_codec);
646 opj_image_destroy(image);
647 LEPT_FREE(parameters.cp_comment);
648 return ERROR_INT("opj_start_compress failed\n", __func__, 1);
649 }
650 if (!opj_encode(l_codec, l_stream)) {
651 opj_stream_destroy(l_stream);
652 opj_destroy_codec(l_codec);
653 opj_image_destroy(image);
654 LEPT_FREE(parameters.cp_comment);
655 return ERROR_INT("opj_encode failed\n", __func__, 1);
656 }
657 success = opj_end_compress(l_codec, l_stream);
658
659 /* Clean up */
660 opj_stream_destroy(l_stream);
661 opj_destroy_codec(l_codec);
662 opj_image_destroy(image);
663 LEPT_FREE(parameters.cp_comment);
664 if (success)
665 return 0;
666 else
667 return ERROR_INT("opj_end_compress failed\n", __func__, 1);
668}
669
670
683static opj_image_t *
684pixConvertToOpjImage(PIX *pix)
685{
686l_int32 i, j, k, w, h, d, spp, wpl;
687OPJ_COLOR_SPACE colorspace;
688l_int32 *ir = NULL;
689l_int32 *ig = NULL;
690l_int32 *ib = NULL;
691l_int32 *ia = NULL;
692l_uint32 *line, *data;
693opj_image_t *image;
694opj_image_cmptparm_t cmptparm[4];
695
696 if (!pix)
697 return (opj_image_t *)ERROR_PTR("pix not defined", __func__, NULL);
698 pixGetDimensions(pix, &w, &h, &d);
699 if (d != 8 && d != 32) {
700 L_ERROR("invalid depth: %d\n", __func__, d);
701 return NULL;
702 }
703
704 /* Allocate the opj_image. */
705 spp = pixGetSpp(pix);
706 memset(&cmptparm[0], 0, 4 * sizeof(opj_image_cmptparm_t));
707 for (i = 0; i < spp; i++) {
708 cmptparm[i].prec = 8;
709 cmptparm[i].sgnd = 0;
710 cmptparm[i].dx = 1;
711 cmptparm[i].dy = 1;
712 cmptparm[i].w = w;
713 cmptparm[i].h = h;
714 }
715 colorspace = (spp == 1) ? OPJ_CLRSPC_GRAY : OPJ_CLRSPC_SRGB;
716 if ((image = opj_image_create(spp, &cmptparm[0], colorspace)) == NULL)
717 return (opj_image_t *)ERROR_PTR("image not made", __func__, NULL);
718 image->x0 = 0;
719 image->y0 = 0;
720 image->x1 = w;
721 image->y1 = h;
722
723 /* Set the component pointers */
724 ir = image->comps[0].data;
725 if (spp > 1) {
726 ig = image->comps[1].data;
727 ib = image->comps[2].data;
728 }
729 if(spp == 4)
730 ia = image->comps[3].data;
731
732 /* Transfer the data from the pix */
733 data = pixGetData(pix);
734 wpl = pixGetWpl(pix);
735 for (i = 0, k = 0; i < h; i++) {
736 line = data + i * wpl;
737 for (j = 0; j < w; j++, k++) {
738 if (spp == 1) {
739 ir[k] = GET_DATA_BYTE(line, j);
740 } else if (spp > 1) {
741 ir[k] = GET_DATA_BYTE(line + j, COLOR_RED);
742 ig[k] = GET_DATA_BYTE(line + j, COLOR_GREEN);
743 ib[k] = GET_DATA_BYTE(line + j, COLOR_BLUE);
744 }
745 if (spp == 4)
746 ia[k] = GET_DATA_BYTE(line + j, L_ALPHA_CHANNEL);
747 }
748 }
749
750 return image;
751}
752
753
754/*---------------------------------------------------------------------*
755 * Read/write to memory *
756 *---------------------------------------------------------------------*/
776PIX *
777pixReadMemJp2k(const l_uint8 *data,
778 size_t size,
779 l_uint32 reduction,
780 BOX *box,
781 l_int32 hint,
782 l_int32 debug)
783{
784FILE *fp;
785PIX *pix;
786
787 if (!data)
788 return (PIX *)ERROR_PTR("data not defined", __func__, NULL);
789
790 if ((fp = fopenReadFromMemory(data, size)) == NULL)
791 return (PIX *)ERROR_PTR("stream not opened", __func__, NULL);
792 pix = pixReadStreamJp2k(fp, reduction, box, hint, debug);
793 fclose(fp);
794 if (!pix) L_ERROR("pix not read\n", __func__);
795 return pix;
796}
797
798
817l_ok
818pixWriteMemJp2k(l_uint8 **pdata,
819 size_t *psize,
820 PIX *pix,
821 l_int32 quality,
822 l_int32 nlevels,
823 l_int32 hint,
824 l_int32 debug)
825{
826l_int32 ret;
827FILE *fp;
828
829 if (pdata) *pdata = NULL;
830 if (psize) *psize = 0;
831 if (!pdata)
832 return ERROR_INT("&data not defined", __func__, 1 );
833 if (!psize)
834 return ERROR_INT("&size not defined", __func__, 1 );
835 if (!pix)
836 return ERROR_INT("&pix not defined", __func__, 1 );
837
838#if HAVE_FMEMOPEN
839 if ((fp = open_memstream((char **)pdata, psize)) == NULL)
840 return ERROR_INT("stream not opened", __func__, 1);
841 ret = pixWriteStreamJp2k(fp, pix, quality, nlevels, L_JP2_CODEC,
842 hint, debug);
843 fputc('\0', fp);
844 fclose(fp);
845 *psize = *psize - 1;
846#else
847 L_INFO("no fmemopen API --> work-around: writing to a temp file\n", __func__);
848 #ifdef _WIN32
849 if ((fp = fopenWriteWinTempfile()) == NULL)
850 return ERROR_INT("tmpfile stream not opened", __func__, 1);
851 #else
852 if ((fp = tmpfile()) == NULL)
853 return ERROR_INT("tmpfile stream not opened", __func__, 1);
854 #endif /* _WIN32 */
855 ret = pixWriteStreamJp2k(fp, pix, quality, nlevels, L_JP2_CODEC,
856 hint, debug);
857 rewind(fp);
858 *pdata = l_binaryReadStream(fp, psize);
859 fclose(fp);
860#endif /* HAVE_FMEMOPEN */
861 return ret;
862}
863
864
865/*---------------------------------------------------------------------*
866 * Static functions from opj 2.0 to retain file stream interface *
867 *---------------------------------------------------------------------*/
868static l_uint64
869opj_get_user_data_length(FILE *fp) {
870 OPJ_OFF_T length = 0;
871 fseek(fp, 0, SEEK_END);
872 length = (OPJ_OFF_T)ftell(fp);
873 fseek(fp, 0, SEEK_SET);
874 return (l_uint64)length;
875}
876
877static OPJ_SIZE_T
878opj_read_from_file(void *p_buffer, OPJ_SIZE_T p_nb_bytes, FILE *fp) {
879 OPJ_SIZE_T l_nb_read = fread(p_buffer, 1, p_nb_bytes, fp);
880 return l_nb_read ? l_nb_read : (OPJ_SIZE_T) - 1;
881}
882
883static OPJ_SIZE_T
884opj_write_from_file(void *p_buffer, OPJ_SIZE_T p_nb_bytes, FILE *fp)
885{
886 return fwrite(p_buffer, 1, p_nb_bytes, fp);
887}
888
889static OPJ_OFF_T
890opj_skip_from_file(OPJ_OFF_T offset, FILE *fp) {
891 if (fseek(fp, offset, SEEK_CUR)) {
892 return -1;
893 }
894 return offset;
895}
896
897static l_int32
898opj_seek_from_file(OPJ_OFF_T offset, FILE *fp) {
899 if (fseek(fp, offset, SEEK_SET)) {
900 return 0;
901 }
902 return 1;
903}
904
905 /* Static generator of opj_stream from file stream */
906static opj_stream_t *
907opjCreateStream(FILE *fp,
908 l_int32 is_read_stream)
909{
910opj_stream_t *l_stream;
911
912 if (!fp)
913 return (opj_stream_t *)ERROR_PTR("fp not defined", __func__, NULL);
914
915 l_stream = opj_stream_create(OPJ_J2K_STREAM_CHUNK_SIZE, is_read_stream);
916 if (!l_stream)
917 return (opj_stream_t *)ERROR_PTR("stream not made", __func__, NULL);
918
919 opj_stream_set_user_data(l_stream, fp,
920 (opj_stream_free_user_data_fn)NULL);
921 opj_stream_set_user_data_length(l_stream, opj_get_user_data_length(fp));
922 opj_stream_set_read_function(l_stream,
923 (opj_stream_read_fn)opj_read_from_file);
924 opj_stream_set_write_function(l_stream,
925 (opj_stream_write_fn)opj_write_from_file);
926 opj_stream_set_skip_function(l_stream,
927 (opj_stream_skip_fn)opj_skip_from_file);
928 opj_stream_set_seek_function(l_stream,
929 (opj_stream_seek_fn)opj_seek_from_file);
930
931 return l_stream;
932}
933
934/* --------------------------------------------*/
935#endif /* HAVE_LIBJP2K */
936/* --------------------------------------------*/
#define GET_DATA_BYTE(pdata, n)
#define SET_DATA_BYTE(pdata, n, val)
@ L_J2K_CODEC
Definition imageio.h:148
@ L_JP2_CODEC
Definition imageio.h:149
@ COLOR_BLUE
Definition pix.h:330
@ COLOR_RED
Definition pix.h:328
@ L_ALPHA_CHANNEL
Definition pix.h:331
@ COLOR_GREEN
Definition pix.h:329
@ REMOVE_CMAP_BASED_ON_SRC
Definition pix.h:384