Leptonica 1.85.0
Image processing and image analysis suite
Loading...
Searching...
No Matches
pixcomp.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
151#ifdef HAVE_CONFIG_H
152#include <config_auto.h>
153#endif /* HAVE_CONFIG_H */
154
155#include <string.h>
156#include "allheaders.h"
157#include "pix_internal.h"
158
159 /* Bounds on pixacomp array size */
160static const l_uint32 MaxPtrArraySize = 1000000;
161static const l_int32 InitialPtrArraySize = 20;
163 /* Bound on size for a compressed data string */
164static const size_t MaxDataSize = 1000000000; /* 1 GB */
165
166 /* These two globals are defined in writefile.c */
167extern l_int32 NumImageFileFormatExtensions;
168extern const char *ImageFileFormatExtensions[];
169
170 /* Static functions */
171static l_int32 pixacompExtendArray(PIXAC *pixac);
172static l_int32 pixcompFastConvertToPdfData(PIXC *pixc, const char *title,
173 l_uint8 **pdata, size_t *pnbytes);
174
175
176/*---------------------------------------------------------------------*
177 * Pixcomp creation and destruction *
178 *---------------------------------------------------------------------*/
194PIXC *
196 l_int32 comptype)
197{
198size_t size;
199char *text;
200l_int32 ret, format;
201l_uint8 *data;
202PIXC *pixc;
203
204 if (!pix)
205 return (PIXC *)ERROR_PTR("pix not defined", __func__, NULL);
206 if (comptype != IFF_DEFAULT && comptype != IFF_TIFF_G4 &&
207 comptype != IFF_PNG && comptype != IFF_JFIF_JPEG)
208 return (PIXC *)ERROR_PTR("invalid comptype", __func__, NULL);
209
210 pixc = (PIXC *)LEPT_CALLOC(1, sizeof(PIXC));
211 pixGetDimensions(pix, &pixc->w, &pixc->h, &pixc->d);
212 pixGetResolution(pix, &pixc->xres, &pixc->yres);
213 if (pixGetColormap(pix))
214 pixc->cmapflag = 1;
215 if ((text = pixGetText(pix)) != NULL)
216 pixc->text = stringNew(text);
217
218 pixcompDetermineFormat(comptype, pixc->d, pixc->cmapflag, &format);
219 pixc->comptype = format;
220 ret = pixWriteMem(&data, &size, pix, format);
221 if (ret) {
222 L_ERROR("write to memory failed\n", __func__);
223 pixcompDestroy(&pixc);
224 return NULL;
225 }
226 pixc->data = data;
227 pixc->size = size;
228
229 return pixc;
230}
231
232
248PIXC *
250 size_t size,
251 l_int32 copyflag)
252{
253l_int32 format, w, h, d, bps, spp, iscmap;
254PIXC *pixc;
255
256 if (!data)
257 return (PIXC *)ERROR_PTR("data not defined", __func__, NULL);
258 if (copyflag != L_INSERT && copyflag != L_COPY)
259 return (PIXC *)ERROR_PTR("invalid copyflag", __func__, NULL);
260
261 if (pixReadHeaderMem(data, size, &format, &w, &h, &bps, &spp, &iscmap) == 1)
262 return (PIXC *)ERROR_PTR("header data not read", __func__, NULL);
263 pixc = (PIXC *)LEPT_CALLOC(1, sizeof(PIXC));
264 d = (spp == 3) ? 32 : bps * spp;
265 pixc->w = w;
266 pixc->h = h;
267 pixc->d = d;
268 pixc->comptype = format;
269 pixc->cmapflag = iscmap;
270 if (copyflag == L_INSERT)
271 pixc->data = data;
272 else
273 pixc->data = l_binaryCopy(data, size);
274 pixc->size = size;
275 return pixc;
276}
277
278
294PIXC *
295pixcompCreateFromFile(const char *filename,
296 l_int32 comptype)
297{
298l_int32 format;
299size_t nbytes;
300l_uint8 *data;
301PIX *pix;
302PIXC *pixc;
303
304 if (!filename)
305 return (PIXC *)ERROR_PTR("filename not defined", __func__, NULL);
306 if (comptype != IFF_DEFAULT && comptype != IFF_TIFF_G4 &&
307 comptype != IFF_PNG && comptype != IFF_JFIF_JPEG)
308 return (PIXC *)ERROR_PTR("invalid comptype", __func__, NULL);
309
310 findFileFormat(filename, &format);
311 if (format == IFF_UNKNOWN) {
312 L_ERROR("unreadable file: %s\n", __func__, filename);
313 return NULL;
314 }
315
316 /* Can we accept the encoded file directly? Remember that
317 * png is the "universal" compression type, so if requested
318 * it takes precedence. Otherwise, if the file is already
319 * compressed in g4 or jpeg, just accept the string. */
320 if ((format == IFF_TIFF_G4 && comptype != IFF_PNG) ||
321 (format == IFF_JFIF_JPEG && comptype != IFF_PNG))
322 comptype = format;
323 if (comptype != IFF_DEFAULT && comptype == format) {
324 data = l_binaryRead(filename, &nbytes);
325 if ((pixc = pixcompCreateFromString(data, nbytes, L_INSERT)) == NULL) {
326 LEPT_FREE(data);
327 return (PIXC *)ERROR_PTR("pixc not made (string)", __func__, NULL);
328 }
329 return pixc;
330 }
331
332 /* Need to recompress in the default format */
333 if ((pix = pixRead(filename)) == NULL)
334 return (PIXC *)ERROR_PTR("pix not read", __func__, NULL);
335 if ((pixc = pixcompCreateFromPix(pix, comptype)) == NULL) {
336 pixDestroy(&pix);
337 return (PIXC *)ERROR_PTR("pixc not made", __func__, NULL);
338 }
339 pixDestroy(&pix);
340 return pixc;
341}
342
343
355void
357{
358PIXC *pixc;
359
360 if (!ppixc) {
361 L_WARNING("ptr address is null!\n", __func__);
362 return;
363 }
364
365 if ((pixc = *ppixc) == NULL)
366 return;
367
368 LEPT_FREE(pixc->data);
369 if (pixc->text)
370 LEPT_FREE(pixc->text);
371 LEPT_FREE(pixc);
372 *ppixc = NULL;
373}
374
375
387PIXC *
389{
390size_t size;
391l_uint8 *datas, *datad;
392PIXC *pixcd;
393
394 if (!pixcs)
395 return (PIXC *)ERROR_PTR("pixcs not defined", __func__, NULL);
396 size = pixcs->size;
397 if (size > MaxDataSize)
398 return (PIXC *)ERROR_PTR("size > 1 GB; too big", __func__, NULL);
399
400 pixcd = (PIXC *)LEPT_CALLOC(1, sizeof(PIXC));
401 pixcd->w = pixcs->w;
402 pixcd->h = pixcs->h;
403 pixcd->d = pixcs->d;
404 pixcd->xres = pixcs->xres;
405 pixcd->yres = pixcs->yres;
406 pixcd->comptype = pixcs->comptype;
407 if (pixcs->text != NULL)
408 pixcd->text = stringNew(pixcs->text);
409 pixcd->cmapflag = pixcs->cmapflag;
410
411 /* Copy image data */
412 datas = pixcs->data;
413 if ((datad = (l_uint8 *)LEPT_CALLOC(size, sizeof(l_int8))) == NULL) {
414 pixcompDestroy(&pixcd);
415 return (PIXC *)ERROR_PTR("pixcd not made", __func__, NULL);
416 }
417 memcpy(datad, datas, size);
418 pixcd->data = datad;
419 pixcd->size = size;
420 return pixcd;
421}
422
423
424/*---------------------------------------------------------------------*
425 * Pixcomp accessors *
426 *---------------------------------------------------------------------*/
434l_ok
436 l_int32 *pw,
437 l_int32 *ph,
438 l_int32 *pd)
439{
440 if (!pixc)
441 return ERROR_INT("pixc not defined", __func__, 1);
442 if (pw) *pw = pixc->w;
443 if (ph) *ph = pixc->h;
444 if (pd) *pd = pixc->d;
445 return 0;
446}
447
448
456l_ok
458 l_int32 *pxres,
459 l_int32 *pyres,
460 l_int32 *pcomptype,
461 l_int32 *pcmapflag)
462{
463 if (!pixc)
464 return ERROR_INT("pixc not defined", __func__, 1);
465 if (pxres) *pxres = pixc->xres;
466 if (pyres) *pyres = pixc->yres;
467 if (pcomptype) *pcomptype = pixc->comptype;
468 if (pcmapflag) *pcmapflag = pixc->cmapflag;
469 return 0;
470}
471
472
473/*---------------------------------------------------------------------*
474 * Pixcomp compression selection *
475 *---------------------------------------------------------------------*/
500l_ok
501pixcompDetermineFormat(l_int32 comptype,
502 l_int32 d,
503 l_int32 cmapflag,
504 l_int32 *pformat)
505{
506
507 if (!pformat)
508 return ERROR_INT("&format not defined", __func__, 1);
509 *pformat = IFF_PNG; /* init value and default */
510 if (comptype != IFF_DEFAULT && comptype != IFF_TIFF_G4 &&
511 comptype != IFF_PNG && comptype != IFF_JFIF_JPEG)
512 return ERROR_INT("invalid comptype", __func__, 1);
513
514 if (comptype == IFF_DEFAULT) {
515 if (d == 1)
516 *pformat = IFF_TIFF_G4;
517 else if (d == 16)
518 *pformat = IFF_PNG;
519 else if (d >= 8 && !cmapflag)
520 *pformat = IFF_JFIF_JPEG;
521 } else if (comptype == IFF_TIFF_G4 && d == 1) {
522 *pformat = IFF_TIFF_G4;
523 } else if (comptype == IFF_JFIF_JPEG && d >= 8 && !cmapflag) {
524 *pformat = IFF_JFIF_JPEG;
525 }
526
527 return 0;
528}
529
530
531/*---------------------------------------------------------------------*
532 * Pixcomp conversion to Pix *
533 *---------------------------------------------------------------------*/
540PIX *
542{
543l_int32 w, h, d, cmapinpix, format;
544PIX *pix;
545
546 if (!pixc)
547 return (PIX *)ERROR_PTR("pixc not defined", __func__, NULL);
548
549 if ((pix = pixReadMem(pixc->data, pixc->size)) == NULL)
550 return (PIX *)ERROR_PTR("pix not read", __func__, NULL);
551 pixSetResolution(pix, pixc->xres, pixc->yres);
552 if (pixc->text)
553 pixSetText(pix, pixc->text);
554
555 /* Check fields for consistency */
556 pixGetDimensions(pix, &w, &h, &d);
557 if (pixc->w != w) {
558 L_INFO("pix width %d != pixc width %d\n", __func__, w, pixc->w);
559 L_ERROR("pix width %d != pixc width\n", __func__, w);
560 }
561 if (pixc->h != h)
562 L_ERROR("pix height %d != pixc height\n", __func__, h);
563 if (pixc->d != d) {
564 if (pixc->d == 16) /* we strip 16 --> 8 bpp by default */
565 L_WARNING("pix depth %d != pixc depth 16\n", __func__, d);
566 else
567 L_ERROR("pix depth %d != pixc depth\n", __func__, d);
568 }
569 cmapinpix = (pixGetColormap(pix) != NULL);
570 if ((cmapinpix && !pixc->cmapflag) || (!cmapinpix && pixc->cmapflag))
571 L_ERROR("pix cmap flag inconsistent\n", __func__);
572 format = pixGetInputFormat(pix);
573 if (format != pixc->comptype) {
574 L_ERROR("pix comptype %d not equal to pixc comptype\n",
575 __func__, format);
576 }
577
578 return pix;
579}
580
581
582/*---------------------------------------------------------------------*
583 * Pixacomp creation and destruction *
584 *---------------------------------------------------------------------*/
591PIXAC *
593{
594PIXAC *pixac;
595
596 if (n <= 0 || n > (l_int32)MaxPtrArraySize)
598
599 pixac = (PIXAC *)LEPT_CALLOC(1, sizeof(PIXAC));
600 pixac->n = 0;
601 pixac->nalloc = n;
602 pixac->offset = 0;
603 if ((pixac->pixc = (PIXC **)LEPT_CALLOC(n, sizeof(PIXC *))) == NULL) {
604 pixacompDestroy(&pixac);
605 return (PIXAC *)ERROR_PTR("pixc ptrs not made", __func__, NULL);
606 }
607 if ((pixac->boxa = boxaCreate(n)) == NULL) {
608 pixacompDestroy(&pixac);
609 return (PIXAC *)ERROR_PTR("boxa not made", __func__, NULL);
610 }
611
612 return pixac;
613}
614
615
654PIXAC *
656 l_int32 offset,
657 PIX *pix,
658 l_int32 comptype)
659{
660l_int32 i;
661PIX *pixt;
662PIXC *pixc;
663PIXAC *pixac;
664
665 if (n <= 0 || n > (l_int32)MaxPtrArraySize)
666 return (PIXAC *)ERROR_PTR("n out of valid bounds", __func__, NULL);
667 if (pix) {
668 if (comptype != IFF_DEFAULT && comptype != IFF_TIFF_G4 &&
669 comptype != IFF_PNG && comptype != IFF_JFIF_JPEG)
670 return (PIXAC *)ERROR_PTR("invalid comptype", __func__, NULL);
671 } else {
672 comptype = IFF_TIFF_G4;
673 }
674 if (offset < 0) {
675 L_WARNING("offset < 0; setting to 0\n", __func__);
676 offset = 0;
677 }
678
679 if ((pixac = pixacompCreate(n)) == NULL)
680 return (PIXAC *)ERROR_PTR("pixac not made", __func__, NULL);
681 pixacompSetOffset(pixac, offset);
682 if (pix)
683 pixt = pixClone(pix);
684 else
685 pixt = pixCreate(1, 1, 1);
686 for (i = 0; i < n; i++) {
687 pixc = pixcompCreateFromPix(pixt, comptype);
688 pixacompAddPixcomp(pixac, pixc, L_INSERT);
689 }
690 pixDestroy(&pixt);
691
692 return pixac;
693}
694
695
716PIXAC *
718 l_int32 comptype,
719 l_int32 accesstype)
720{
721l_int32 i, n;
722BOXA *boxa;
723PIX *pix;
724PIXAC *pixac;
725
726 if (!pixa)
727 return (PIXAC *)ERROR_PTR("pixa not defined", __func__, NULL);
728 if (comptype != IFF_DEFAULT && comptype != IFF_TIFF_G4 &&
729 comptype != IFF_PNG && comptype != IFF_JFIF_JPEG)
730 return (PIXAC *)ERROR_PTR("invalid comptype", __func__, NULL);
731 if (accesstype != L_COPY && accesstype != L_CLONE &&
732 accesstype != L_COPY_CLONE)
733 return (PIXAC *)ERROR_PTR("invalid accesstype", __func__, NULL);
734
735 n = pixaGetCount(pixa);
736 if ((pixac = pixacompCreate(n)) == NULL)
737 return (PIXAC *)ERROR_PTR("pixac not made", __func__, NULL);
738 for (i = 0; i < n; i++) {
739 pix = pixaGetPix(pixa, i, L_CLONE);
740 pixacompAddPix(pixac, pix, comptype);
741 pixDestroy(&pix);
742 }
743 if ((boxa = pixaGetBoxa(pixa, accesstype)) != NULL) {
744 boxaDestroy(&pixac->boxa);
745 pixac->boxa = boxa;
746 }
747
748 return pixac;
749}
750
751
773PIXAC *
774pixacompCreateFromFiles(const char *dirname,
775 const char *substr,
776 l_int32 comptype)
777{
778PIXAC *pixac;
779SARRAY *sa;
780
781 if (!dirname)
782 return (PIXAC *)ERROR_PTR("dirname not defined", __func__, NULL);
783 if (comptype != IFF_DEFAULT && comptype != IFF_TIFF_G4 &&
784 comptype != IFF_PNG && comptype != IFF_JFIF_JPEG)
785 return (PIXAC *)ERROR_PTR("invalid comptype", __func__, NULL);
786
787 if ((sa = getSortedPathnamesInDirectory(dirname, substr, 0, 0)) == NULL)
788 return (PIXAC *)ERROR_PTR("sa not made", __func__, NULL);
789 pixac = pixacompCreateFromSA(sa, comptype);
790 sarrayDestroy(&sa);
791 return pixac;
792}
793
794
810PIXAC *
812 l_int32 comptype)
813{
814char *str;
815l_int32 i, n;
816PIXC *pixc;
817PIXAC *pixac;
818
819 if (!sa)
820 return (PIXAC *)ERROR_PTR("sarray not defined", __func__, NULL);
821 if (comptype != IFF_DEFAULT && comptype != IFF_TIFF_G4 &&
822 comptype != IFF_PNG && comptype != IFF_JFIF_JPEG)
823 return (PIXAC *)ERROR_PTR("invalid comptype", __func__, NULL);
824
825 n = sarrayGetCount(sa);
826 pixac = pixacompCreate(n);
827 for (i = 0; i < n; i++) {
828 str = sarrayGetString(sa, i, L_NOCOPY);
829 if ((pixc = pixcompCreateFromFile(str, comptype)) == NULL) {
830 L_ERROR("pixc not read from file: %s\n", __func__, str);
831 continue;
832 }
833 pixacompAddPixcomp(pixac, pixc, L_INSERT);
834 }
835 return pixac;
836}
837
838
850void
852{
853l_int32 i;
854PIXAC *pixac;
855
856 if (ppixac == NULL) {
857 L_WARNING("ptr address is NULL!\n", __func__);
858 return;
859 }
860
861 if ((pixac = *ppixac) == NULL)
862 return;
863
864 for (i = 0; i < pixac->n; i++)
865 pixcompDestroy(&pixac->pixc[i]);
866 LEPT_FREE(pixac->pixc);
867 boxaDestroy(&pixac->boxa);
868 LEPT_FREE(pixac);
869 *ppixac = NULL;
870}
871
872
873/*---------------------------------------------------------------------*
874 * Pixacomp addition *
875 *---------------------------------------------------------------------*/
893l_ok
895 PIX *pix,
896 l_int32 comptype)
897{
898l_int32 cmapflag, format;
899PIXC *pixc;
900
901 if (!pixac)
902 return ERROR_INT("pixac not defined", __func__, 1);
903 if (!pix)
904 return ERROR_INT("pix not defined", __func__, 1);
905 if (comptype != IFF_DEFAULT && comptype != IFF_TIFF_G4 &&
906 comptype != IFF_PNG && comptype != IFF_JFIF_JPEG)
907 return ERROR_INT("invalid format", __func__, 1);
908
909 cmapflag = pixGetColormap(pix) ? 1 : 0;
910 pixcompDetermineFormat(comptype, pixGetDepth(pix), cmapflag, &format);
911 if ((pixc = pixcompCreateFromPix(pix, format)) == NULL)
912 return ERROR_INT("pixc not made", __func__, 1);
913 pixacompAddPixcomp(pixac, pixc, L_INSERT);
914 return 0;
915}
916
917
933l_ok
935 PIXC *pixc,
936 l_int32 copyflag)
937{
938l_int32 n;
939
940 if (!pixac)
941 return ERROR_INT("pixac not defined", __func__, 1);
942 if (!pixc)
943 return ERROR_INT("pixc not defined", __func__, 1);
944 if (copyflag != L_INSERT && copyflag != L_COPY)
945 return ERROR_INT("invalid copyflag", __func__, 1);
946
947 n = pixac->n;
948 if (n >= pixac->nalloc) {
949 if (pixacompExtendArray(pixac))
950 return ERROR_INT("extension failed", __func__, 1);
951 }
952
953 if (copyflag == L_INSERT)
954 pixac->pixc[n] = pixc;
955 else /* L_COPY */
956 pixac->pixc[n] = pixcompCopy(pixc);
957 pixac->n++;
958
959 return 0;
960}
961
962
978static l_int32
980{
981size_t oldsize, newsize;
982
983 if (!pixac)
984 return ERROR_INT("pixac not defined", __func__, 1);
985 if (pixac->nalloc > (l_int32)MaxPtrArraySize) /* belt & suspenders */
986 return ERROR_INT("pixac has too many ptrs", __func__, 1);
987 oldsize = pixac->nalloc * sizeof(PIXC *);
988 newsize = 2 * oldsize;
989 if (newsize > 8 * MaxPtrArraySize) /* ptrs for 1M pixcomp */
990 return ERROR_INT("newsize > 8 MB; too large", __func__, 1);
991
992 if ((pixac->pixc = (PIXC **)reallocNew((void **)&pixac->pixc,
993 oldsize, newsize)) == NULL)
994 return ERROR_INT("new ptr array not returned", __func__, 1);
995 pixac->nalloc *= 2;
996 boxaExtendArray(pixac->boxa);
997 return 0;
998}
999
1000
1018l_ok
1020 l_int32 index,
1021 PIX *pix,
1022 l_int32 comptype)
1023{
1024l_int32 n, aindex;
1025PIXC *pixc;
1026
1027 if (!pixac)
1028 return ERROR_INT("pixac not defined", __func__, 1);
1029 n = pixacompGetCount(pixac);
1030 aindex = index - pixac->offset;
1031 if (aindex < 0 || aindex >= n)
1032 return ERROR_INT("array index out of bounds", __func__, 1);
1033 if (!pix)
1034 return ERROR_INT("pix not defined", __func__, 1);
1035 if (comptype != IFF_DEFAULT && comptype != IFF_TIFF_G4 &&
1036 comptype != IFF_PNG && comptype != IFF_JFIF_JPEG)
1037 return ERROR_INT("invalid format", __func__, 1);
1038
1039 pixc = pixcompCreateFromPix(pix, comptype);
1040 pixacompReplacePixcomp(pixac, index, pixc);
1041 return 0;
1042}
1043
1044
1061l_ok
1063 l_int32 index,
1064 PIXC *pixc)
1065{
1066l_int32 n, aindex;
1067PIXC *pixct;
1068
1069 if (!pixac)
1070 return ERROR_INT("pixac not defined", __func__, 1);
1071 n = pixacompGetCount(pixac);
1072 aindex = index - pixac->offset;
1073 if (aindex < 0 || aindex >= n)
1074 return ERROR_INT("array index out of bounds", __func__, 1);
1075 if (!pixc)
1076 return ERROR_INT("pixc not defined", __func__, 1);
1077
1078 pixct = pixacompGetPixcomp(pixac, index, L_NOCOPY); /* use %index */
1079 pixcompDestroy(&pixct);
1080 pixac->pixc[aindex] = pixc; /* replace; use array index */
1081
1082 return 0;
1083}
1084
1085
1094l_ok
1096 BOX *box,
1097 l_int32 copyflag)
1098{
1099 if (!pixac)
1100 return ERROR_INT("pixac not defined", __func__, 1);
1101 if (!box)
1102 return ERROR_INT("box not defined", __func__, 1);
1103 if (copyflag != L_INSERT && copyflag != L_COPY)
1104 return ERROR_INT("invalid copyflag", __func__, 1);
1105
1106 boxaAddBox(pixac->boxa, box, copyflag);
1107 return 0;
1108}
1109
1110
1111/*---------------------------------------------------------------------*
1112 * Pixacomp accessors *
1113 *---------------------------------------------------------------------*/
1120l_int32
1122{
1123 if (!pixac)
1124 return ERROR_INT("pixac not defined", __func__, 0);
1125
1126 return pixac->n;
1127}
1128
1129
1146PIXC *
1148 l_int32 index,
1149 l_int32 copyflag)
1150{
1151l_int32 aindex;
1152
1153 if (!pixac)
1154 return (PIXC *)ERROR_PTR("pixac not defined", __func__, NULL);
1155 if (copyflag != L_NOCOPY && copyflag != L_COPY)
1156 return (PIXC *)ERROR_PTR("invalid copyflag", __func__, NULL);
1157 aindex = index - pixac->offset;
1158 if (aindex < 0 || aindex >= pixac->n)
1159 return (PIXC *)ERROR_PTR("array index not valid", __func__, NULL);
1160
1161 if (copyflag == L_NOCOPY)
1162 return pixac->pixc[aindex];
1163 else /* L_COPY */
1164 return pixcompCopy(pixac->pixc[aindex]);
1165}
1166
1167
1181PIX *
1183 l_int32 index)
1184{
1185l_int32 aindex;
1186PIXC *pixc;
1187
1188 if (!pixac)
1189 return (PIX *)ERROR_PTR("pixac not defined", __func__, NULL);
1190 aindex = index - pixac->offset;
1191 if (aindex < 0 || aindex >= pixac->n)
1192 return (PIX *)ERROR_PTR("array index not valid", __func__, NULL);
1193
1194 pixc = pixacompGetPixcomp(pixac, index, L_NOCOPY);
1195 return pixCreateFromPixcomp(pixc);
1196}
1197
1198
1214l_ok
1216 l_int32 index,
1217 l_int32 *pw,
1218 l_int32 *ph,
1219 l_int32 *pd)
1220{
1221l_int32 aindex;
1222PIXC *pixc;
1223
1224 if (!pixac)
1225 return ERROR_INT("pixac not defined", __func__, 1);
1226 aindex = index - pixac->offset;
1227 if (aindex < 0 || aindex >= pixac->n)
1228 return ERROR_INT("array index not valid", __func__, 1);
1229
1230 if ((pixc = pixac->pixc[aindex]) == NULL)
1231 return ERROR_INT("pixc not found!", __func__, 1);
1232 pixcompGetDimensions(pixc, pw, ph, pd);
1233 return 0;
1234}
1235
1236
1244BOXA *
1246 l_int32 accesstype)
1247{
1248 if (!pixac)
1249 return (BOXA *)ERROR_PTR("pixac not defined", __func__, NULL);
1250 if (!pixac->boxa)
1251 return (BOXA *)ERROR_PTR("boxa not defined", __func__, NULL);
1252 if (accesstype != L_COPY && accesstype != L_CLONE &&
1253 accesstype != L_COPY_CLONE)
1254 return (BOXA *)ERROR_PTR("invalid accesstype", __func__, NULL);
1255
1256 return boxaCopy(pixac->boxa, accesstype);
1257}
1258
1259
1266l_int32
1268{
1269 if (!pixac)
1270 return ERROR_INT("pixac not defined", __func__, 0);
1271
1272 return boxaGetCount(pixac->boxa);
1273}
1274
1275
1299BOX *
1301 l_int32 index,
1302 l_int32 accesstype)
1303{
1304l_int32 aindex;
1305BOX *box;
1306
1307 if (!pixac)
1308 return (BOX *)ERROR_PTR("pixac not defined", __func__, NULL);
1309 if (!pixac->boxa)
1310 return (BOX *)ERROR_PTR("boxa not defined", __func__, NULL);
1311 aindex = index - pixac->offset;
1312 if (aindex < 0 || aindex >= pixac->boxa->n)
1313 return (BOX *)ERROR_PTR("array index not valid", __func__, NULL);
1314 if (accesstype != L_COPY && accesstype != L_CLONE)
1315 return (BOX *)ERROR_PTR("invalid accesstype", __func__, NULL);
1316
1317 box = pixac->boxa->box[aindex];
1318 if (box) {
1319 if (accesstype == L_COPY)
1320 return boxCopy(box);
1321 else /* accesstype == L_CLONE */
1322 return boxClone(box);
1323 } else {
1324 return NULL;
1325 }
1326}
1327
1328
1344l_ok
1346 l_int32 index,
1347 l_int32 *px,
1348 l_int32 *py,
1349 l_int32 *pw,
1350 l_int32 *ph)
1351{
1352l_int32 aindex;
1353BOX *box;
1354
1355 if (!pixac)
1356 return ERROR_INT("pixac not defined", __func__, 1);
1357 aindex = index - pixac->offset;
1358 if (aindex < 0 || aindex >= pixac->n)
1359 return ERROR_INT("array index not valid", __func__, 1);
1360
1361 if ((box = pixacompGetBox(pixac, aindex, L_CLONE)) == NULL)
1362 return ERROR_INT("box not found!", __func__, 1);
1363 boxGetGeometry(box, px, py, pw, ph);
1364 boxDestroy(&box);
1365 return 0;
1366}
1367
1368
1382l_int32
1384{
1385 if (!pixac)
1386 return ERROR_INT("pixac not defined", __func__, 0);
1387 return pixac->offset;
1388}
1389
1390
1405l_ok
1407 l_int32 offset)
1408{
1409 if (!pixac)
1410 return ERROR_INT("pixac not defined", __func__, 1);
1411 pixac->offset = L_MAX(0, offset);
1412 return 0;
1413}
1414
1415
1416/*---------------------------------------------------------------------*
1417 * Pixacomp conversion to Pixa *
1418 *---------------------------------------------------------------------*/
1433PIXA *
1435 l_int32 accesstype)
1436{
1437l_int32 i, n, offset;
1438PIX *pix;
1439PIXA *pixa;
1440
1441 if (!pixac)
1442 return (PIXA *)ERROR_PTR("pixac not defined", __func__, NULL);
1443 if (accesstype != L_COPY && accesstype != L_CLONE &&
1444 accesstype != L_COPY_CLONE)
1445 return (PIXA *)ERROR_PTR("invalid accesstype", __func__, NULL);
1446
1447 n = pixacompGetCount(pixac);
1448 offset = pixacompGetOffset(pixac);
1449 pixacompSetOffset(pixac, 0);
1450 if ((pixa = pixaCreate(n)) == NULL)
1451 return (PIXA *)ERROR_PTR("pixa not made", __func__, NULL);
1452 for (i = 0; i < n; i++) {
1453 if ((pix = pixacompGetPix(pixac, i)) == NULL) {
1454 L_WARNING("pix %d not made\n", __func__, i);
1455 continue;
1456 }
1457 pixaAddPix(pixa, pix, L_INSERT);
1458 }
1459 if (pixa->boxa) {
1460 boxaDestroy(&pixa->boxa);
1461 pixa->boxa = pixacompGetBoxa(pixac, accesstype);
1462 }
1463 pixacompSetOffset(pixac, offset);
1464
1465 return pixa;
1466}
1467
1468
1469/*---------------------------------------------------------------------*
1470 * Combining pixacomp
1471 *---------------------------------------------------------------------*/
1489l_ok
1491 PIXAC *pixacs,
1492 l_int32 istart,
1493 l_int32 iend)
1494{
1495l_int32 i, n, nb;
1496BOXA *boxas, *boxad;
1497PIXC *pixc;
1498
1499 if (!pixacd)
1500 return ERROR_INT("pixacd not defined", __func__, 1);
1501 if (!pixacs || ((n = pixacompGetCount(pixacs)) == 0))
1502 return 0;
1503
1504 if (istart < 0)
1505 istart = 0;
1506 if (iend < 0 || iend >= n)
1507 iend = n - 1;
1508 if (istart > iend)
1509 return ERROR_INT("istart > iend; nothing to add", __func__, 1);
1510
1511 for (i = istart; i <= iend; i++) {
1512 pixc = pixacompGetPixcomp(pixacs, i, L_NOCOPY);
1513 pixacompAddPixcomp(pixacd, pixc, L_COPY);
1514 }
1515
1516 boxas = pixacompGetBoxa(pixacs, L_CLONE);
1517 boxad = pixacompGetBoxa(pixacd, L_CLONE);
1518 nb = pixacompGetBoxaCount(pixacs);
1519 iend = L_MIN(iend, nb - 1);
1520 boxaJoin(boxad, boxas, istart, iend);
1521 boxaDestroy(&boxas); /* just the clones */
1522 boxaDestroy(&boxad); /* ditto */
1523 return 0;
1524}
1525
1526
1540PIXAC *
1542 PIXAC *pixac2)
1543{
1544l_int32 i, n1, n2, n, nb1, nb2;
1545BOX *box;
1546PIXC *pixc1, *pixc2;
1547PIXAC *pixacd;
1548
1549 if (!pixac1)
1550 return (PIXAC *)ERROR_PTR("pixac1 not defined", __func__, NULL);
1551 if (!pixac2)
1552 return (PIXAC *)ERROR_PTR("pixac2 not defined", __func__, NULL);
1553 n1 = pixacompGetCount(pixac1);
1554 n2 = pixacompGetCount(pixac2);
1555 n = L_MIN(n1, n2);
1556 if (n == 0)
1557 return (PIXAC *)ERROR_PTR("at least one input pixac is empty",
1558 __func__, NULL);
1559 if (n1 != n2)
1560 L_WARNING("counts differ: %d != %d\n", __func__, n1, n2);
1561
1562 pixacd = pixacompCreate(2 * n);
1563 nb1 = pixacompGetBoxaCount(pixac1);
1564 nb2 = pixacompGetBoxaCount(pixac2);
1565 for (i = 0; i < n; i++) {
1566 pixc1 = pixacompGetPixcomp(pixac1, i, L_COPY);
1567 pixacompAddPixcomp(pixacd, pixc1, L_INSERT);
1568 if (i < nb1) {
1569 box = pixacompGetBox(pixac1, i, L_COPY);
1570 pixacompAddBox(pixacd, box, L_INSERT);
1571 }
1572 pixc2 = pixacompGetPixcomp(pixac2, i, L_COPY);
1573 pixacompAddPixcomp(pixacd, pixc2, L_INSERT);
1574 if (i < nb2) {
1575 box = pixacompGetBox(pixac2, i, L_COPY);
1576 pixacompAddBox(pixacd, box, L_INSERT);
1577 }
1578 }
1579
1580 return pixacd;
1581}
1582
1583
1584/*---------------------------------------------------------------------*
1585 * Pixacomp serialized I/O *
1586 *---------------------------------------------------------------------*/
1600PIXAC *
1601pixacompRead(const char *filename)
1602{
1603FILE *fp;
1604PIXAC *pixac;
1605
1606 if (!filename)
1607 return (PIXAC *)ERROR_PTR("filename not defined", __func__, NULL);
1608
1609 if ((fp = fopenReadStream(filename)) == NULL)
1610 return (PIXAC *)ERROR_PTR_1("stream not opened",
1611 filename, __func__, NULL);
1612 pixac = pixacompReadStream(fp);
1613 fclose(fp);
1614 if (!pixac)
1615 return (PIXAC *)ERROR_PTR_1("pixac not read",
1616 filename, __func__, NULL);
1617 return pixac;
1618}
1619
1620
1632PIXAC *
1634{
1635char buf[256];
1636l_uint8 *data;
1637l_int32 n, offset, i, w, h, d, ignore;
1638l_int32 comptype, cmapflag, version, xres, yres;
1639size_t size;
1640BOXA *boxa;
1641PIXC *pixc;
1642PIXAC *pixac;
1643
1644 if (!fp)
1645 return (PIXAC *)ERROR_PTR("stream not defined", __func__, NULL);
1646
1647 if (fscanf(fp, "\nPixacomp Version %d\n", &version) != 1)
1648 return (PIXAC *)ERROR_PTR("not a pixacomp file", __func__, NULL);
1649 if (version != PIXACOMP_VERSION_NUMBER)
1650 return (PIXAC *)ERROR_PTR("invalid pixacomp version", __func__, NULL);
1651 if (fscanf(fp, "Number of pixcomp = %d\n", &n) != 1)
1652 return (PIXAC *)ERROR_PTR("not a pixacomp file", __func__, NULL);
1653 if (fscanf(fp, "Offset of index into array = %d", &offset) != 1)
1654 return (PIXAC *)ERROR_PTR("offset not read", __func__, NULL);
1655 if (n < 0)
1656 return (PIXAC *)ERROR_PTR("num pixcomp ptrs < 0", __func__, NULL);
1657 if (n > (l_int32)MaxPtrArraySize)
1658 return (PIXAC *)ERROR_PTR("too many pixcomp ptrs", __func__, NULL);
1659 if (n == 0) L_INFO("the pixacomp is empty\n", __func__);
1660
1661 if ((pixac = pixacompCreate(n)) == NULL)
1662 return (PIXAC *)ERROR_PTR("pixac not made", __func__, NULL);
1663 if ((boxa = boxaReadStream(fp)) == NULL) {
1664 pixacompDestroy(&pixac);
1665 return (PIXAC *)ERROR_PTR("boxa not made", __func__, NULL);
1666 }
1667 boxaDestroy(&pixac->boxa); /* empty */
1668 pixac->boxa = boxa;
1669 pixacompSetOffset(pixac, offset);
1670
1671 for (i = 0; i < n; i++) {
1672 if (fscanf(fp, "\nPixcomp[%d]: w = %d, h = %d, d = %d\n",
1673 &ignore, &w, &h, &d) != 4) {
1674 pixacompDestroy(&pixac);
1675 return (PIXAC *)ERROR_PTR("dimension reading", __func__, NULL);
1676 }
1677 if (fscanf(fp, " comptype = %d, size = %zu, cmapflag = %d\n",
1678 &comptype, &size, &cmapflag) != 3) {
1679 pixacompDestroy(&pixac);
1680 return (PIXAC *)ERROR_PTR("comptype/size reading", __func__, NULL);
1681 }
1682 if (size > MaxDataSize) {
1683 pixacompDestroy(&pixac);
1684 L_ERROR("data size = %zu is too big", __func__, size);
1685 return NULL;
1686 }
1687
1688 /* Use fgets() and sscanf(); not fscanf(), for the last
1689 * bit of header data before the binary data. The reason is
1690 * that fscanf throws away white space, and if the binary data
1691 * happens to begin with ascii character(s) that are white
1692 * space, it will swallow them and all will be lost! */
1693 if (fgets(buf, sizeof(buf), fp) == NULL) {
1694 pixacompDestroy(&pixac);
1695 return (PIXAC *)ERROR_PTR("fgets read fail", __func__, NULL);
1696 }
1697 if (sscanf(buf, " xres = %d, yres = %d\n", &xres, &yres) != 2) {
1698 pixacompDestroy(&pixac);
1699 return (PIXAC *)ERROR_PTR("read fail for res", __func__, NULL);
1700 }
1701 if ((data = (l_uint8 *)LEPT_CALLOC(1, size)) == NULL) {
1702 pixacompDestroy(&pixac);
1703 return (PIXAC *)ERROR_PTR("calloc fail for data", __func__, NULL);
1704 }
1705 if (fread(data, 1, size, fp) != size) {
1706 pixacompDestroy(&pixac);
1707 LEPT_FREE(data);
1708 return (PIXAC *)ERROR_PTR("error reading data", __func__, NULL);
1709 }
1710 fgetc(fp); /* swallow the ending nl */
1711 pixc = (PIXC *)LEPT_CALLOC(1, sizeof(PIXC));
1712 pixc->w = w;
1713 pixc->h = h;
1714 pixc->d = d;
1715 pixc->xres = xres;
1716 pixc->yres = yres;
1717 pixc->comptype = comptype;
1718 pixc->cmapflag = cmapflag;
1719 pixc->data = data;
1720 pixc->size = size;
1721 pixacompAddPixcomp(pixac, pixc, L_INSERT);
1722 }
1723 return pixac;
1724}
1725
1726
1739PIXAC *
1740pixacompReadMem(const l_uint8 *data,
1741 size_t size)
1742{
1743FILE *fp;
1744PIXAC *pixac;
1745
1746 if (!data)
1747 return (PIXAC *)ERROR_PTR("data not defined", __func__, NULL);
1748 if ((fp = fopenReadFromMemory(data, size)) == NULL)
1749 return (PIXAC *)ERROR_PTR("stream not opened", __func__, NULL);
1750
1751 pixac = pixacompReadStream(fp);
1752 fclose(fp);
1753 if (!pixac) L_ERROR("pixac not read\n", __func__);
1754 return pixac;
1755}
1756
1757
1772l_ok
1773pixacompWrite(const char *filename,
1774 PIXAC *pixac)
1775{
1776l_int32 ret;
1777FILE *fp;
1778
1779 if (!filename)
1780 return ERROR_INT("filename not defined", __func__, 1);
1781 if (!pixac)
1782 return ERROR_INT("pixacomp not defined", __func__, 1);
1783
1784 if ((fp = fopenWriteStream(filename, "wb")) == NULL)
1785 return ERROR_INT_1("stream not opened", filename, __func__, 1);
1786 ret = pixacompWriteStream(fp, pixac);
1787 fclose(fp);
1788 if (ret)
1789 return ERROR_INT_1("pixacomp not written to stream",
1790 filename, __func__, 1);
1791 return 0;
1792}
1793
1794
1802l_ok
1804 PIXAC *pixac)
1805{
1806l_int32 n, i;
1807PIXC *pixc;
1808
1809 if (!fp)
1810 return ERROR_INT("stream not defined", __func__, 1);
1811 if (!pixac)
1812 return ERROR_INT("pixac not defined", __func__, 1);
1813
1814 n = pixacompGetCount(pixac);
1815 fprintf(fp, "\nPixacomp Version %d\n", PIXACOMP_VERSION_NUMBER);
1816 fprintf(fp, "Number of pixcomp = %d\n", n);
1817 fprintf(fp, "Offset of index into array = %d", pixac->offset);
1818 boxaWriteStream(fp, pixac->boxa);
1819 for (i = 0; i < n; i++) {
1820 if ((pixc = pixacompGetPixcomp(pixac, pixac->offset + i, L_NOCOPY))
1821 == NULL)
1822 return ERROR_INT("pixc not found", __func__, 1);
1823 fprintf(fp, "\nPixcomp[%d]: w = %d, h = %d, d = %d\n",
1824 i, pixc->w, pixc->h, pixc->d);
1825 fprintf(fp, " comptype = %d, size = %zu, cmapflag = %d\n",
1826 pixc->comptype, pixc->size, pixc->cmapflag);
1827 fprintf(fp, " xres = %d, yres = %d\n", pixc->xres, pixc->yres);
1828 fwrite(pixc->data, 1, pixc->size, fp);
1829 fprintf(fp, "\n");
1830 }
1831 return 0;
1832}
1833
1834
1848l_ok
1849pixacompWriteMem(l_uint8 **pdata,
1850 size_t *psize,
1851 PIXAC *pixac)
1852{
1853l_int32 ret;
1854FILE *fp;
1855
1856 if (pdata) *pdata = NULL;
1857 if (psize) *psize = 0;
1858 if (!pdata)
1859 return ERROR_INT("&data not defined", __func__, 1);
1860 if (!psize)
1861 return ERROR_INT("&size not defined", __func__, 1);
1862 if (!pixac)
1863 return ERROR_INT("&pixac not defined", __func__, 1);
1864
1865#if HAVE_FMEMOPEN
1866 if ((fp = open_memstream((char **)pdata, psize)) == NULL)
1867 return ERROR_INT("stream not opened", __func__, 1);
1868 ret = pixacompWriteStream(fp, pixac);
1869 fputc('\0', fp);
1870 fclose(fp);
1871 if (*psize > 0) *psize = *psize - 1;
1872#else
1873 L_INFO("no fmemopen API --> work-around: write to temp file\n", __func__);
1874 #ifdef _WIN32
1875 if ((fp = fopenWriteWinTempfile()) == NULL)
1876 return ERROR_INT("tmpfile stream not opened", __func__, 1);
1877 #else
1878 if ((fp = tmpfile()) == NULL)
1879 return ERROR_INT("tmpfile stream not opened", __func__, 1);
1880 #endif /* _WIN32 */
1881 ret = pixacompWriteStream(fp, pixac);
1882 rewind(fp);
1883 *pdata = l_binaryReadStream(fp, psize);
1884 fclose(fp);
1885#endif /* HAVE_FMEMOPEN */
1886 return ret;
1887}
1888
1889
1890/*--------------------------------------------------------------------*
1891 * Conversion to pdf *
1892 *--------------------------------------------------------------------*/
1925l_ok
1927 l_int32 res,
1928 l_float32 scalefactor,
1929 l_int32 type,
1930 l_int32 quality,
1931 const char *title,
1932 const char *fileout)
1933{
1934l_uint8 *data;
1935l_int32 ret;
1936size_t nbytes;
1937
1938 if (!pixac)
1939 return ERROR_INT("pixac not defined", __func__, 1);
1940
1941 ret = pixacompConvertToPdfData(pixac, res, scalefactor, type, quality,
1942 title, &data, &nbytes);
1943 if (ret) {
1944 LEPT_FREE(data);
1945 return ERROR_INT("conversion to pdf failed", __func__, 1);
1946 }
1947
1948 ret = l_binaryWrite(fileout, "w", data, nbytes);
1949 LEPT_FREE(data);
1950 if (ret)
1951 L_ERROR("pdf data not written to file\n", __func__);
1952 return ret;
1953}
1954
1955
1976l_ok
1978 l_int32 res,
1979 l_float32 scalefactor,
1980 l_int32 type,
1981 l_int32 quality,
1982 const char *title,
1983 l_uint8 **pdata,
1984 size_t *pnbytes)
1985{
1986l_uint8 *imdata;
1987l_int32 i, n, ret, scaledres, pagetype;
1988size_t imbytes;
1989L_BYTEA *ba;
1990PIX *pixs, *pix;
1991L_PTRA *pa_data;
1992
1993 if (!pdata)
1994 return ERROR_INT("&data not defined", __func__, 1);
1995 *pdata = NULL;
1996 if (!pnbytes)
1997 return ERROR_INT("&nbytes not defined", __func__, 1);
1998 *pnbytes = 0;
1999 if (!pixac)
2000 return ERROR_INT("pixac not defined", __func__, 1);
2001 if (scalefactor <= 0.0) scalefactor = 1.0;
2002 if (type != L_DEFAULT_ENCODE && type != L_JPEG_ENCODE &&
2003 type != L_G4_ENCODE && type != L_FLATE_ENCODE &&
2004 type != L_JP2K_ENCODE) {
2005 L_WARNING("invalid compression type; using per-page default\n",
2006 __func__);
2007 type = L_DEFAULT_ENCODE;
2008 }
2009
2010 /* Generate all the encoded pdf strings */
2011 n = pixacompGetCount(pixac);
2012 pa_data = ptraCreate(n);
2013 for (i = 0; i < n; i++) {
2014 if ((pixs =
2015 pixacompGetPix(pixac, pixacompGetOffset(pixac) + i)) == NULL) {
2016 L_ERROR("pix[%d] not retrieved\n", __func__, i);
2017 continue;
2018 }
2019 if (pixGetWidth(pixs) == 1) { /* used sometimes as placeholders */
2020 L_INFO("placeholder image[%d] has w = 1\n", __func__, i);
2021 pixDestroy(&pixs);
2022 continue;
2023 }
2024 if (scalefactor != 1.0)
2025 pix = pixScale(pixs, scalefactor, scalefactor);
2026 else
2027 pix = pixClone(pixs);
2028 pixDestroy(&pixs);
2029 scaledres = (l_int32)(res * scalefactor);
2030
2031 /* Select the encoding type */
2032 if (type != L_DEFAULT_ENCODE) {
2033 pagetype = type;
2034 } else if (selectDefaultPdfEncoding(pix, &pagetype) != 0) {
2035 L_ERROR("encoding type selection failed for pix[%d]\n",
2036 __func__, i);
2037 pixDestroy(&pix);
2038 continue;
2039 }
2040
2041 ret = pixConvertToPdfData(pix, pagetype, quality, &imdata, &imbytes,
2042 0, 0, scaledres, title, NULL, 0);
2043 pixDestroy(&pix);
2044 if (ret) {
2045 L_ERROR("pdf encoding failed for pix[%d]\n", __func__, i);
2046 continue;
2047 }
2048 ba = l_byteaInitFromMem(imdata, imbytes);
2049 LEPT_FREE(imdata);
2050 ptraAdd(pa_data, ba);
2051 }
2052 ptraGetActualCount(pa_data, &n);
2053 if (n == 0) {
2054 L_ERROR("no pdf files made\n", __func__);
2055 ptraDestroy(&pa_data, FALSE, FALSE);
2056 return 1;
2057 }
2058
2059 /* Concatenate them */
2060 ret = ptraConcatenatePdfToData(pa_data, NULL, pdata, pnbytes);
2061
2062 ptraGetActualCount(pa_data, &n); /* recalculate in case it changes */
2063 for (i = 0; i < n; i++) {
2064 ba = (L_BYTEA *)ptraRemove(pa_data, i, L_NO_COMPACTION);
2065 l_byteaDestroy(&ba);
2066 }
2067 ptraDestroy(&pa_data, FALSE, FALSE);
2068 return ret;
2069}
2070
2071
2090l_ok
2092 const char *title,
2093 l_uint8 **pdata,
2094 size_t *pnbytes)
2095{
2096l_uint8 *imdata;
2097l_int32 i, n, ret, comptype;
2098size_t imbytes;
2099L_BYTEA *ba;
2100PIXC *pixc;
2101L_PTRA *pa_data;
2102
2103 if (!pdata)
2104 return ERROR_INT("&data not defined", __func__, 1);
2105 *pdata = NULL;
2106 if (!pnbytes)
2107 return ERROR_INT("&nbytes not defined", __func__, 1);
2108 *pnbytes = 0;
2109 if (!pixac)
2110 return ERROR_INT("pixac not defined", __func__, 1);
2111
2112 /* Generate all the encoded pdf strings */
2113 n = pixacompGetCount(pixac);
2114 pa_data = ptraCreate(n);
2115 for (i = 0; i < n; i++) {
2116 if ((pixc = pixacompGetPixcomp(pixac, i, L_NOCOPY)) == NULL) {
2117 L_ERROR("pixc[%d] not retrieved\n", __func__, i);
2118 continue;
2119 }
2120 pixcompGetParameters(pixc, NULL, NULL, &comptype, NULL);
2121 if (comptype != IFF_JFIF_JPEG) {
2122 L_ERROR("pixc[%d] not jpeg compressed\n", __func__, i);
2123 continue;
2124 }
2125 ret = pixcompFastConvertToPdfData(pixc, title, &imdata, &imbytes);
2126 if (ret) {
2127 L_ERROR("pdf encoding failed for pixc[%d]\n", __func__, i);
2128 continue;
2129 }
2130 ba = l_byteaInitFromMem(imdata, imbytes);
2131 LEPT_FREE(imdata);
2132 ptraAdd(pa_data, ba);
2133 }
2134 ptraGetActualCount(pa_data, &n);
2135 if (n == 0) {
2136 L_ERROR("no pdf files made\n", __func__);
2137 ptraDestroy(&pa_data, FALSE, FALSE);
2138 return 1;
2139 }
2140
2141 /* Concatenate them */
2142 ret = ptraConcatenatePdfToData(pa_data, NULL, pdata, pnbytes);
2143
2144 /* Clean up */
2145 ptraGetActualCount(pa_data, &n); /* recalculate in case it changes */
2146 for (i = 0; i < n; i++) {
2147 ba = (L_BYTEA *)ptraRemove(pa_data, i, L_NO_COMPACTION);
2148 l_byteaDestroy(&ba);
2149 }
2150 ptraDestroy(&pa_data, FALSE, FALSE);
2151 return ret;
2152}
2153
2154
2173static l_int32
2175 const char *title,
2176 l_uint8 **pdata,
2177 size_t *pnbytes)
2178{
2179l_uint8 *data;
2180L_COMP_DATA *cid;
2181
2182 if (!pdata)
2183 return ERROR_INT("&data not defined", __func__, 1);
2184 *pdata = NULL;
2185 if (!pnbytes)
2186 return ERROR_INT("&nbytes not defined", __func__, 1);
2187 *pnbytes = 0;
2188 if (!pixc)
2189 return ERROR_INT("pixc not defined", __func__, 1);
2190
2191 /* Make a copy of the data */
2192 data = l_binaryCopy(pixc->data, pixc->size);
2193 cid = l_generateJpegDataMem(data, pixc->size, 0);
2194
2195 /* Note: cid is destroyed, along with data, by this function */
2196 return cidConvertToPdfData(cid, title, pdata, pnbytes);
2197}
2198
2199
2200/*--------------------------------------------------------------------*
2201 * Output for debugging *
2202 *--------------------------------------------------------------------*/
2211l_ok
2213 PIXAC *pixac,
2214 const char *text)
2215{
2216l_int32 i, n, nboxes;
2217PIXC *pixc;
2218
2219 if (!fp)
2220 return ERROR_INT("fp not defined", __func__, 1);
2221 if (!pixac)
2222 return ERROR_INT("pixac not defined", __func__, 1);
2223
2224 if (text)
2225 fprintf(fp, "Pixacomp Info for %s:\n", text);
2226 else
2227 fprintf(fp, "Pixacomp Info:\n");
2228 n = pixacompGetCount(pixac);
2229 nboxes = pixacompGetBoxaCount(pixac);
2230 fprintf(fp, "Number of pixcomp: %d\n", n);
2231 fprintf(fp, "Size of pixcomp array alloc: %d\n", pixac->nalloc);
2232 fprintf(fp, "Offset of index into array: %d\n", pixac->offset);
2233 if (nboxes > 0)
2234 fprintf(fp, "Boxa has %d boxes\n", nboxes);
2235 else
2236 fprintf(fp, "Boxa is empty\n");
2237 for (i = 0; i < n; i++) {
2238 pixc = pixacompGetPixcomp(pixac, pixac->offset + i, L_NOCOPY);
2239 pixcompWriteStreamInfo(fp, pixc, NULL);
2240 }
2241 return 0;
2242}
2243
2244
2253l_ok
2255 PIXC *pixc,
2256 const char *text)
2257{
2258 if (!fp)
2259 return ERROR_INT("fp not defined", __func__, 1);
2260 if (!pixc)
2261 return ERROR_INT("pixc not defined", __func__, 1);
2262
2263 if (text)
2264 fprintf(fp, " Pixcomp Info for %s:", text);
2265 else
2266 fprintf(fp, " Pixcomp Info:");
2267 fprintf(fp, " width = %d, height = %d, depth = %d\n",
2268 pixc->w, pixc->h, pixc->d);
2269 fprintf(fp, " xres = %d, yres = %d, size in bytes = %zu\n",
2270 pixc->xres, pixc->yres, pixc->size);
2271 if (pixc->cmapflag)
2272 fprintf(fp, " has colormap\n");
2273 else
2274 fprintf(fp, " no colormap\n");
2275 if (pixc->comptype < NumImageFileFormatExtensions) {
2276 fprintf(fp, " comptype = %s (%d)\n",
2277 ImageFileFormatExtensions[pixc->comptype], pixc->comptype);
2278 } else {
2279 fprintf(fp, " Error!! Invalid comptype index: %d\n", pixc->comptype);
2280 }
2281 return 0;
2282}
2283
2284
2307PIX *
2309 l_int32 outdepth,
2310 l_int32 tilewidth,
2311 l_int32 ncols,
2312 l_int32 background,
2313 l_int32 spacing,
2314 l_int32 border)
2315{
2316PIX *pixd;
2317PIXA *pixa;
2318
2319 if (!pixac)
2320 return (PIX *)ERROR_PTR("pixac not defined", __func__, NULL);
2321
2322 if ((pixa = pixaCreateFromPixacomp(pixac, L_COPY)) == NULL)
2323 return (PIX *)ERROR_PTR("pixa not made", __func__, NULL);
2324
2325 pixd = pixaDisplayTiledAndScaled(pixa, outdepth, tilewidth, ncols,
2326 background, spacing, border);
2327 pixaDestroy(&pixa);
2328 return pixd;
2329}
2330
2331
2339l_ok
2341 const char *subdir)
2342{
2343char buf[128];
2344l_int32 i, n;
2345PIXC *pixc;
2346
2347 if (!pixac)
2348 return ERROR_INT("pixac not defined", __func__, 1);
2349
2350 if (lept_mkdir(subdir) > 0)
2351 return ERROR_INT("invalid subdir", __func__, 1);
2352
2353 n = pixacompGetCount(pixac);
2354 for (i = 0; i < n; i++) {
2355 pixc = pixacompGetPixcomp(pixac, i, L_NOCOPY);
2356 snprintf(buf, sizeof(buf), "/tmp/%s/%03d", subdir, i);
2357 pixcompWriteFile(buf, pixc);
2358 }
2359 return 0;
2360}
2361
2362extern const char *ImageFileFormatExtensions[];
2363
2377l_ok
2378pixcompWriteFile(const char *rootname,
2379 PIXC *pixc)
2380{
2381char buf[128];
2382
2383 if (!pixc)
2384 return ERROR_INT("pixc not defined", __func__, 1);
2385
2386 snprintf(buf, sizeof(buf), "%s.%s", rootname,
2387 ImageFileFormatExtensions[pixc->comptype]);
2388 l_binaryWrite(buf, "w", pixc->data, pixc->size);
2389 return 0;
2390}
@ L_DEFAULT_ENCODE
Definition imageio.h:158
@ L_FLATE_ENCODE
Definition imageio.h:161
@ L_G4_ENCODE
Definition imageio.h:160
@ L_JP2K_ENCODE
Definition imageio.h:162
@ L_JPEG_ENCODE
Definition imageio.h:159
@ L_COPY
Definition pix.h:505
@ L_CLONE
Definition pix.h:506
@ L_COPY_CLONE
Definition pix.h:507
@ L_NOCOPY
Definition pix.h:503
@ L_INSERT
Definition pix.h:504
#define PIXACOMP_VERSION_NUMBER
l_ok pixacompJoin(PIXAC *pixacd, PIXAC *pixacs, l_int32 istart, l_int32 iend)
pixacompJoin()
Definition pixcomp.c:1490
PIXAC * pixacompCreateFromFiles(const char *dirname, const char *substr, l_int32 comptype)
pixacompCreateFromFiles()
Definition pixcomp.c:774
void pixacompDestroy(PIXAC **ppixac)
pixacompDestroy()
Definition pixcomp.c:851
l_ok pixacompFastConvertToPdfData(PIXAC *pixac, const char *title, l_uint8 **pdata, size_t *pnbytes)
pixacompFastConvertToPdfData()
Definition pixcomp.c:2091
l_ok pixacompWriteStream(FILE *fp, PIXAC *pixac)
pixacompWriteStream()
Definition pixcomp.c:1803
l_ok pixacompWrite(const char *filename, PIXAC *pixac)
pixacompWrite()
Definition pixcomp.c:1773
void pixcompDestroy(PIXC **ppixc)
pixcompDestroy()
Definition pixcomp.c:356
l_ok pixacompWriteMem(l_uint8 **pdata, size_t *psize, PIXAC *pixac)
pixacompWriteMem()
Definition pixcomp.c:1849
static const l_int32 InitialPtrArraySize
Definition pixcomp.c:161
PIX * pixacompDisplayTiledAndScaled(PIXAC *pixac, l_int32 outdepth, l_int32 tilewidth, l_int32 ncols, l_int32 background, l_int32 spacing, l_int32 border)
pixacompDisplayTiledAndScaled()
Definition pixcomp.c:2308
PIXC * pixcompCreateFromFile(const char *filename, l_int32 comptype)
pixcompCreateFromFile()
Definition pixcomp.c:295
BOXA * pixacompGetBoxa(PIXAC *pixac, l_int32 accesstype)
pixacompGetBoxa()
Definition pixcomp.c:1245
l_ok pixacompConvertToPdfData(PIXAC *pixac, l_int32 res, l_float32 scalefactor, l_int32 type, l_int32 quality, const char *title, l_uint8 **pdata, size_t *pnbytes)
pixacompConvertToPdfData()
Definition pixcomp.c:1977
PIXAC * pixacompReadStream(FILE *fp)
pixacompReadStream()
Definition pixcomp.c:1633
PIX * pixCreateFromPixcomp(PIXC *pixc)
pixCreateFromPixcomp()
Definition pixcomp.c:541
PIXAC * pixacompCreateFromPixa(PIXA *pixa, l_int32 comptype, l_int32 accesstype)
pixacompCreateFromPixa()
Definition pixcomp.c:717
l_int32 pixacompGetBoxaCount(PIXAC *pixac)
pixacompGetBoxaCount()
Definition pixcomp.c:1267
PIXC * pixacompGetPixcomp(PIXAC *pixac, l_int32 index, l_int32 copyflag)
pixacompGetPixcomp()
Definition pixcomp.c:1147
PIXAC * pixacompInterleave(PIXAC *pixac1, PIXAC *pixac2)
pixacompInterleave()
Definition pixcomp.c:1541
l_ok pixcompGetParameters(PIXC *pixc, l_int32 *pxres, l_int32 *pyres, l_int32 *pcomptype, l_int32 *pcmapflag)
pixcompGetParameters()
Definition pixcomp.c:457
l_ok pixcompWriteFile(const char *rootname, PIXC *pixc)
pixcompWriteFile()
Definition pixcomp.c:2378
l_ok pixacompReplacePix(PIXAC *pixac, l_int32 index, PIX *pix, l_int32 comptype)
pixacompReplacePix()
Definition pixcomp.c:1019
PIXAC * pixacompRead(const char *filename)
pixacompRead()
Definition pixcomp.c:1601
PIXC * pixcompCreateFromPix(PIX *pix, l_int32 comptype)
pixcompCreateFromPix()
Definition pixcomp.c:195
static l_int32 pixacompExtendArray(PIXAC *pixac)
pixacompExtendArray()
Definition pixcomp.c:979
l_ok pixcompGetDimensions(PIXC *pixc, l_int32 *pw, l_int32 *ph, l_int32 *pd)
pixcompGetDimensions()
Definition pixcomp.c:435
l_ok pixacompConvertToPdf(PIXAC *pixac, l_int32 res, l_float32 scalefactor, l_int32 type, l_int32 quality, const char *title, const char *fileout)
pixacompConvertToPdf()
Definition pixcomp.c:1926
l_ok pixacompSetOffset(PIXAC *pixac, l_int32 offset)
pixacompSetOffset()
Definition pixcomp.c:1406
static l_int32 pixcompFastConvertToPdfData(PIXC *pixc, const char *title, l_uint8 **pdata, size_t *pnbytes)
pixcompFastConvertToPdfData()
Definition pixcomp.c:2174
PIXAC * pixacompCreateWithInit(l_int32 n, l_int32 offset, PIX *pix, l_int32 comptype)
pixacompCreateWithInit()
Definition pixcomp.c:655
l_ok pixacompWriteStreamInfo(FILE *fp, PIXAC *pixac, const char *text)
pixacompWriteStreamInfo()
Definition pixcomp.c:2212
PIXA * pixaCreateFromPixacomp(PIXAC *pixac, l_int32 accesstype)
pixaCreateFromPixacomp()
Definition pixcomp.c:1434
PIXC * pixcompCreateFromString(l_uint8 *data, size_t size, l_int32 copyflag)
pixcompCreateFromString()
Definition pixcomp.c:249
l_ok pixacompGetBoxGeometry(PIXAC *pixac, l_int32 index, l_int32 *px, l_int32 *py, l_int32 *pw, l_int32 *ph)
pixacompGetBoxGeometry()
Definition pixcomp.c:1345
l_int32 pixacompGetOffset(PIXAC *pixac)
pixacompGetOffset()
Definition pixcomp.c:1383
l_int32 pixacompGetCount(PIXAC *pixac)
pixacompGetCount()
Definition pixcomp.c:1121
l_ok pixacompAddPix(PIXAC *pixac, PIX *pix, l_int32 comptype)
pixacompAddPix()
Definition pixcomp.c:894
l_ok pixacompAddBox(PIXAC *pixac, BOX *box, l_int32 copyflag)
pixacompAddBox()
Definition pixcomp.c:1095
l_ok pixacompAddPixcomp(PIXAC *pixac, PIXC *pixc, l_int32 copyflag)
pixacompAddPixcomp()
Definition pixcomp.c:934
l_ok pixcompDetermineFormat(l_int32 comptype, l_int32 d, l_int32 cmapflag, l_int32 *pformat)
pixcompDetermineFormat()
Definition pixcomp.c:501
PIXAC * pixacompCreateFromSA(SARRAY *sa, l_int32 comptype)
pixacompCreateFromSA()
Definition pixcomp.c:811
PIXAC * pixacompReadMem(const l_uint8 *data, size_t size)
pixacompReadMem()
Definition pixcomp.c:1740
l_ok pixacompWriteFiles(PIXAC *pixac, const char *subdir)
pixacompWriteFiles()
Definition pixcomp.c:2340
PIX * pixacompGetPix(PIXAC *pixac, l_int32 index)
pixacompGetPix()
Definition pixcomp.c:1182
BOX * pixacompGetBox(PIXAC *pixac, l_int32 index, l_int32 accesstype)
pixacompGetBox()
Definition pixcomp.c:1300
l_ok pixcompWriteStreamInfo(FILE *fp, PIXC *pixc, const char *text)
pixcompWriteStreamInfo()
Definition pixcomp.c:2254
l_ok pixacompReplacePixcomp(PIXAC *pixac, l_int32 index, PIXC *pixc)
pixacompReplacePixcomp()
Definition pixcomp.c:1062
l_ok pixacompGetPixDimensions(PIXAC *pixac, l_int32 index, l_int32 *pw, l_int32 *ph, l_int32 *pd)
pixacompGetPixDimensions()
Definition pixcomp.c:1215
PIXC * pixcompCopy(PIXC *pixcs)
pixcompCopy()
Definition pixcomp.c:388
PIXAC * pixacompCreate(l_int32 n)
pixacompCreate()
Definition pixcomp.c:592
@ L_NO_COMPACTION
Definition ptra.h:79
l_int32 n
struct Box ** box
Definition ptra.h:54
l_int32 w
size_t size
l_uint8 * data
l_int32 cmapflag
l_int32 xres
char * text
l_int32 yres
l_int32 d
l_int32 h
l_int32 comptype
l_int32 offset
l_int32 nalloc
l_int32 n
struct PixComp ** pixc
struct Boxa * boxa
struct Boxa * boxa