Leptonica 1.83.1
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
150
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;
162
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 > 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 > 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 > 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("stream not opened", __func__, NULL);
1611 pixac = pixacompReadStream(fp);
1612 fclose(fp);
1613 if (!pixac)
1614 return (PIXAC *)ERROR_PTR("pixac not read", __func__, NULL);
1615 return pixac;
1616}
1617
1618
1630PIXAC *
1632{
1633char buf[256];
1634l_uint8 *data;
1635l_int32 n, offset, i, w, h, d, ignore;
1636l_int32 comptype, cmapflag, version, xres, yres;
1637size_t size;
1638BOXA *boxa;
1639PIXC *pixc;
1640PIXAC *pixac;
1641
1642 if (!fp)
1643 return (PIXAC *)ERROR_PTR("stream not defined", __func__, NULL);
1644
1645 if (fscanf(fp, "\nPixacomp Version %d\n", &version) != 1)
1646 return (PIXAC *)ERROR_PTR("not a pixacomp file", __func__, NULL);
1647 if (version != PIXACOMP_VERSION_NUMBER)
1648 return (PIXAC *)ERROR_PTR("invalid pixacomp version", __func__, NULL);
1649 if (fscanf(fp, "Number of pixcomp = %d\n", &n) != 1)
1650 return (PIXAC *)ERROR_PTR("not a pixacomp file", __func__, NULL);
1651 if (fscanf(fp, "Offset of index into array = %d", &offset) != 1)
1652 return (PIXAC *)ERROR_PTR("offset not read", __func__, NULL);
1653 if (n < 0)
1654 return (PIXAC *)ERROR_PTR("num pixcomp ptrs < 0", __func__, NULL);
1655 if (n > MaxPtrArraySize)
1656 return (PIXAC *)ERROR_PTR("too many pixcomp ptrs", __func__, NULL);
1657 if (n == 0) L_INFO("the pixacomp is empty\n", __func__);
1658
1659 if ((pixac = pixacompCreate(n)) == NULL)
1660 return (PIXAC *)ERROR_PTR("pixac not made", __func__, NULL);
1661 if ((boxa = boxaReadStream(fp)) == NULL) {
1662 pixacompDestroy(&pixac);
1663 return (PIXAC *)ERROR_PTR("boxa not made", __func__, NULL);
1664 }
1665 boxaDestroy(&pixac->boxa); /* empty */
1666 pixac->boxa = boxa;
1667 pixacompSetOffset(pixac, offset);
1668
1669 for (i = 0; i < n; i++) {
1670 if (fscanf(fp, "\nPixcomp[%d]: w = %d, h = %d, d = %d\n",
1671 &ignore, &w, &h, &d) != 4) {
1672 pixacompDestroy(&pixac);
1673 return (PIXAC *)ERROR_PTR("dimension reading", __func__, NULL);
1674 }
1675 if (fscanf(fp, " comptype = %d, size = %zu, cmapflag = %d\n",
1676 &comptype, &size, &cmapflag) != 3) {
1677 pixacompDestroy(&pixac);
1678 return (PIXAC *)ERROR_PTR("comptype/size reading", __func__, NULL);
1679 }
1680 if (size > MaxDataSize) {
1681 pixacompDestroy(&pixac);
1682 L_ERROR("data size = %zu is too big", __func__, size);
1683 return NULL;
1684 }
1685
1686 /* Use fgets() and sscanf(); not fscanf(), for the last
1687 * bit of header data before the binary data. The reason is
1688 * that fscanf throws away white space, and if the binary data
1689 * happens to begin with ascii character(s) that are white
1690 * space, it will swallow them and all will be lost! */
1691 if (fgets(buf, sizeof(buf), fp) == NULL) {
1692 pixacompDestroy(&pixac);
1693 return (PIXAC *)ERROR_PTR("fgets read fail", __func__, NULL);
1694 }
1695 if (sscanf(buf, " xres = %d, yres = %d\n", &xres, &yres) != 2) {
1696 pixacompDestroy(&pixac);
1697 return (PIXAC *)ERROR_PTR("read fail for res", __func__, NULL);
1698 }
1699 if ((data = (l_uint8 *)LEPT_CALLOC(1, size)) == NULL) {
1700 pixacompDestroy(&pixac);
1701 return (PIXAC *)ERROR_PTR("calloc fail for data", __func__, NULL);
1702 }
1703 if (fread(data, 1, size, fp) != size) {
1704 pixacompDestroy(&pixac);
1705 LEPT_FREE(data);
1706 return (PIXAC *)ERROR_PTR("error reading data", __func__, NULL);
1707 }
1708 fgetc(fp); /* swallow the ending nl */
1709 pixc = (PIXC *)LEPT_CALLOC(1, sizeof(PIXC));
1710 pixc->w = w;
1711 pixc->h = h;
1712 pixc->d = d;
1713 pixc->xres = xres;
1714 pixc->yres = yres;
1715 pixc->comptype = comptype;
1716 pixc->cmapflag = cmapflag;
1717 pixc->data = data;
1718 pixc->size = size;
1719 pixacompAddPixcomp(pixac, pixc, L_INSERT);
1720 }
1721 return pixac;
1722}
1723
1724
1737PIXAC *
1738pixacompReadMem(const l_uint8 *data,
1739 size_t size)
1740{
1741FILE *fp;
1742PIXAC *pixac;
1743
1744 if (!data)
1745 return (PIXAC *)ERROR_PTR("data not defined", __func__, NULL);
1746 if ((fp = fopenReadFromMemory(data, size)) == NULL)
1747 return (PIXAC *)ERROR_PTR("stream not opened", __func__, NULL);
1748
1749 pixac = pixacompReadStream(fp);
1750 fclose(fp);
1751 if (!pixac) L_ERROR("pixac not read\n", __func__);
1752 return pixac;
1753}
1754
1755
1770l_ok
1771pixacompWrite(const char *filename,
1772 PIXAC *pixac)
1773{
1774l_int32 ret;
1775FILE *fp;
1776
1777 if (!filename)
1778 return ERROR_INT("filename not defined", __func__, 1);
1779 if (!pixac)
1780 return ERROR_INT("pixacomp not defined", __func__, 1);
1781
1782 if ((fp = fopenWriteStream(filename, "wb")) == NULL)
1783 return ERROR_INT("stream not opened", __func__, 1);
1784 ret = pixacompWriteStream(fp, pixac);
1785 fclose(fp);
1786 if (ret)
1787 return ERROR_INT("pixacomp not written to stream", __func__, 1);
1788 return 0;
1789}
1790
1791
1799l_ok
1801 PIXAC *pixac)
1802{
1803l_int32 n, i;
1804PIXC *pixc;
1805
1806 if (!fp)
1807 return ERROR_INT("stream not defined", __func__, 1);
1808 if (!pixac)
1809 return ERROR_INT("pixac not defined", __func__, 1);
1810
1811 n = pixacompGetCount(pixac);
1812 fprintf(fp, "\nPixacomp Version %d\n", PIXACOMP_VERSION_NUMBER);
1813 fprintf(fp, "Number of pixcomp = %d\n", n);
1814 fprintf(fp, "Offset of index into array = %d", pixac->offset);
1815 boxaWriteStream(fp, pixac->boxa);
1816 for (i = 0; i < n; i++) {
1817 if ((pixc = pixacompGetPixcomp(pixac, pixac->offset + i, L_NOCOPY))
1818 == NULL)
1819 return ERROR_INT("pixc not found", __func__, 1);
1820 fprintf(fp, "\nPixcomp[%d]: w = %d, h = %d, d = %d\n",
1821 i, pixc->w, pixc->h, pixc->d);
1822 fprintf(fp, " comptype = %d, size = %zu, cmapflag = %d\n",
1823 pixc->comptype, pixc->size, pixc->cmapflag);
1824 fprintf(fp, " xres = %d, yres = %d\n", pixc->xres, pixc->yres);
1825 fwrite(pixc->data, 1, pixc->size, fp);
1826 fprintf(fp, "\n");
1827 }
1828 return 0;
1829}
1830
1831
1845l_ok
1846pixacompWriteMem(l_uint8 **pdata,
1847 size_t *psize,
1848 PIXAC *pixac)
1849{
1850l_int32 ret;
1851FILE *fp;
1852
1853 if (pdata) *pdata = NULL;
1854 if (psize) *psize = 0;
1855 if (!pdata)
1856 return ERROR_INT("&data not defined", __func__, 1);
1857 if (!psize)
1858 return ERROR_INT("&size not defined", __func__, 1);
1859 if (!pixac)
1860 return ERROR_INT("&pixac not defined", __func__, 1);
1861
1862#if HAVE_FMEMOPEN
1863 if ((fp = open_memstream((char **)pdata, psize)) == NULL)
1864 return ERROR_INT("stream not opened", __func__, 1);
1865 ret = pixacompWriteStream(fp, pixac);
1866 fputc('\0', fp);
1867 fclose(fp);
1868 *psize = *psize - 1;
1869#else
1870 L_INFO("work-around: writing to a temp file\n", __func__);
1871 #ifdef _WIN32
1872 if ((fp = fopenWriteWinTempfile()) == NULL)
1873 return ERROR_INT("tmpfile stream not opened", __func__, 1);
1874 #else
1875 if ((fp = tmpfile()) == NULL)
1876 return ERROR_INT("tmpfile stream not opened", __func__, 1);
1877 #endif /* _WIN32 */
1878 ret = pixacompWriteStream(fp, pixac);
1879 rewind(fp);
1880 *pdata = l_binaryReadStream(fp, psize);
1881 fclose(fp);
1882#endif /* HAVE_FMEMOPEN */
1883 return ret;
1884}
1885
1886
1887/*--------------------------------------------------------------------*
1888 * Conversion to pdf *
1889 *--------------------------------------------------------------------*/
1922l_ok
1924 l_int32 res,
1925 l_float32 scalefactor,
1926 l_int32 type,
1927 l_int32 quality,
1928 const char *title,
1929 const char *fileout)
1930{
1931l_uint8 *data;
1932l_int32 ret;
1933size_t nbytes;
1934
1935 if (!pixac)
1936 return ERROR_INT("pixac not defined", __func__, 1);
1937
1938 ret = pixacompConvertToPdfData(pixac, res, scalefactor, type, quality,
1939 title, &data, &nbytes);
1940 if (ret) {
1941 LEPT_FREE(data);
1942 return ERROR_INT("conversion to pdf failed", __func__, 1);
1943 }
1944
1945 ret = l_binaryWrite(fileout, "w", data, nbytes);
1946 LEPT_FREE(data);
1947 if (ret)
1948 L_ERROR("pdf data not written to file\n", __func__);
1949 return ret;
1950}
1951
1952
1973l_ok
1975 l_int32 res,
1976 l_float32 scalefactor,
1977 l_int32 type,
1978 l_int32 quality,
1979 const char *title,
1980 l_uint8 **pdata,
1981 size_t *pnbytes)
1982{
1983l_uint8 *imdata;
1984l_int32 i, n, ret, scaledres, pagetype;
1985size_t imbytes;
1986L_BYTEA *ba;
1987PIX *pixs, *pix;
1988L_PTRA *pa_data;
1989
1990 if (!pdata)
1991 return ERROR_INT("&data not defined", __func__, 1);
1992 *pdata = NULL;
1993 if (!pnbytes)
1994 return ERROR_INT("&nbytes not defined", __func__, 1);
1995 *pnbytes = 0;
1996 if (!pixac)
1997 return ERROR_INT("pixac not defined", __func__, 1);
1998 if (scalefactor <= 0.0) scalefactor = 1.0;
1999 if (type != L_DEFAULT_ENCODE && type != L_JPEG_ENCODE &&
2000 type != L_G4_ENCODE && type != L_FLATE_ENCODE &&
2001 type != L_JP2K_ENCODE) {
2002 L_WARNING("invalid compression type; using per-page default\n",
2003 __func__);
2004 type = L_DEFAULT_ENCODE;
2005 }
2006
2007 /* Generate all the encoded pdf strings */
2008 n = pixacompGetCount(pixac);
2009 pa_data = ptraCreate(n);
2010 for (i = 0; i < n; i++) {
2011 if ((pixs =
2012 pixacompGetPix(pixac, pixacompGetOffset(pixac) + i)) == NULL) {
2013 L_ERROR("pix[%d] not retrieved\n", __func__, i);
2014 continue;
2015 }
2016 if (pixGetWidth(pixs) == 1) { /* used sometimes as placeholders */
2017 L_INFO("placeholder image[%d] has w = 1\n", __func__, i);
2018 pixDestroy(&pixs);
2019 continue;
2020 }
2021 if (scalefactor != 1.0)
2022 pix = pixScale(pixs, scalefactor, scalefactor);
2023 else
2024 pix = pixClone(pixs);
2025 pixDestroy(&pixs);
2026 scaledres = (l_int32)(res * scalefactor);
2027
2028 /* Select the encoding type */
2029 if (type != L_DEFAULT_ENCODE) {
2030 pagetype = type;
2031 } else if (selectDefaultPdfEncoding(pix, &pagetype) != 0) {
2032 L_ERROR("encoding type selection failed for pix[%d]\n",
2033 __func__, i);
2034 pixDestroy(&pix);
2035 continue;
2036 }
2037
2038 ret = pixConvertToPdfData(pix, pagetype, quality, &imdata, &imbytes,
2039 0, 0, scaledres, title, NULL, 0);
2040 pixDestroy(&pix);
2041 if (ret) {
2042 L_ERROR("pdf encoding failed for pix[%d]\n", __func__, i);
2043 continue;
2044 }
2045 ba = l_byteaInitFromMem(imdata, imbytes);
2046 LEPT_FREE(imdata);
2047 ptraAdd(pa_data, ba);
2048 }
2049 ptraGetActualCount(pa_data, &n);
2050 if (n == 0) {
2051 L_ERROR("no pdf files made\n", __func__);
2052 ptraDestroy(&pa_data, FALSE, FALSE);
2053 return 1;
2054 }
2055
2056 /* Concatenate them */
2057 ret = ptraConcatenatePdfToData(pa_data, NULL, pdata, pnbytes);
2058
2059 ptraGetActualCount(pa_data, &n); /* recalculate in case it changes */
2060 for (i = 0; i < n; i++) {
2061 ba = (L_BYTEA *)ptraRemove(pa_data, i, L_NO_COMPACTION);
2062 l_byteaDestroy(&ba);
2063 }
2064 ptraDestroy(&pa_data, FALSE, FALSE);
2065 return ret;
2066}
2067
2068
2087l_ok
2089 const char *title,
2090 l_uint8 **pdata,
2091 size_t *pnbytes)
2092{
2093l_uint8 *imdata;
2094l_int32 i, n, ret, comptype;
2095size_t imbytes;
2096L_BYTEA *ba;
2097PIXC *pixc;
2098L_PTRA *pa_data;
2099
2100 if (!pdata)
2101 return ERROR_INT("&data not defined", __func__, 1);
2102 *pdata = NULL;
2103 if (!pnbytes)
2104 return ERROR_INT("&nbytes not defined", __func__, 1);
2105 *pnbytes = 0;
2106 if (!pixac)
2107 return ERROR_INT("pixac not defined", __func__, 1);
2108
2109 /* Generate all the encoded pdf strings */
2110 n = pixacompGetCount(pixac);
2111 pa_data = ptraCreate(n);
2112 for (i = 0; i < n; i++) {
2113 if ((pixc = pixacompGetPixcomp(pixac, i, L_NOCOPY)) == NULL) {
2114 L_ERROR("pixc[%d] not retrieved\n", __func__, i);
2115 continue;
2116 }
2117 pixcompGetParameters(pixc, NULL, NULL, &comptype, NULL);
2118 if (comptype != IFF_JFIF_JPEG) {
2119 L_ERROR("pixc[%d] not jpeg compressed\n", __func__, i);
2120 continue;
2121 }
2122 ret = pixcompFastConvertToPdfData(pixc, title, &imdata, &imbytes);
2123 if (ret) {
2124 L_ERROR("pdf encoding failed for pixc[%d]\n", __func__, i);
2125 continue;
2126 }
2127 ba = l_byteaInitFromMem(imdata, imbytes);
2128 LEPT_FREE(imdata);
2129 ptraAdd(pa_data, ba);
2130 }
2131 ptraGetActualCount(pa_data, &n);
2132 if (n == 0) {
2133 L_ERROR("no pdf files made\n", __func__);
2134 ptraDestroy(&pa_data, FALSE, FALSE);
2135 return 1;
2136 }
2137
2138 /* Concatenate them */
2139 ret = ptraConcatenatePdfToData(pa_data, NULL, pdata, pnbytes);
2140
2141 /* Clean up */
2142 ptraGetActualCount(pa_data, &n); /* recalculate in case it changes */
2143 for (i = 0; i < n; i++) {
2144 ba = (L_BYTEA *)ptraRemove(pa_data, i, L_NO_COMPACTION);
2145 l_byteaDestroy(&ba);
2146 }
2147 ptraDestroy(&pa_data, FALSE, FALSE);
2148 return ret;
2149}
2150
2151
2170static l_int32
2172 const char *title,
2173 l_uint8 **pdata,
2174 size_t *pnbytes)
2175{
2176l_uint8 *data;
2177L_COMP_DATA *cid;
2178
2179 if (!pdata)
2180 return ERROR_INT("&data not defined", __func__, 1);
2181 *pdata = NULL;
2182 if (!pnbytes)
2183 return ERROR_INT("&nbytes not defined", __func__, 1);
2184 *pnbytes = 0;
2185 if (!pixc)
2186 return ERROR_INT("pixc not defined", __func__, 1);
2187
2188 /* Make a copy of the data */
2189 data = l_binaryCopy(pixc->data, pixc->size);
2190 cid = l_generateJpegDataMem(data, pixc->size, 0);
2191
2192 /* Note: cid is destroyed, along with data, by this function */
2193 return cidConvertToPdfData(cid, title, pdata, pnbytes);
2194}
2195
2196
2197/*--------------------------------------------------------------------*
2198 * Output for debugging *
2199 *--------------------------------------------------------------------*/
2208l_ok
2210 PIXAC *pixac,
2211 const char *text)
2212{
2213l_int32 i, n, nboxes;
2214PIXC *pixc;
2215
2216 if (!fp)
2217 return ERROR_INT("fp not defined", __func__, 1);
2218 if (!pixac)
2219 return ERROR_INT("pixac not defined", __func__, 1);
2220
2221 if (text)
2222 fprintf(fp, "Pixacomp Info for %s:\n", text);
2223 else
2224 fprintf(fp, "Pixacomp Info:\n");
2225 n = pixacompGetCount(pixac);
2226 nboxes = pixacompGetBoxaCount(pixac);
2227 fprintf(fp, "Number of pixcomp: %d\n", n);
2228 fprintf(fp, "Size of pixcomp array alloc: %d\n", pixac->nalloc);
2229 fprintf(fp, "Offset of index into array: %d\n", pixac->offset);
2230 if (nboxes > 0)
2231 fprintf(fp, "Boxa has %d boxes\n", nboxes);
2232 else
2233 fprintf(fp, "Boxa is empty\n");
2234 for (i = 0; i < n; i++) {
2235 pixc = pixacompGetPixcomp(pixac, pixac->offset + i, L_NOCOPY);
2236 pixcompWriteStreamInfo(fp, pixc, NULL);
2237 }
2238 return 0;
2239}
2240
2241
2250l_ok
2252 PIXC *pixc,
2253 const char *text)
2254{
2255 if (!fp)
2256 return ERROR_INT("fp not defined", __func__, 1);
2257 if (!pixc)
2258 return ERROR_INT("pixc not defined", __func__, 1);
2259
2260 if (text)
2261 fprintf(fp, " Pixcomp Info for %s:", text);
2262 else
2263 fprintf(fp, " Pixcomp Info:");
2264 fprintf(fp, " width = %d, height = %d, depth = %d\n",
2265 pixc->w, pixc->h, pixc->d);
2266 fprintf(fp, " xres = %d, yres = %d, size in bytes = %zu\n",
2267 pixc->xres, pixc->yres, pixc->size);
2268 if (pixc->cmapflag)
2269 fprintf(fp, " has colormap\n");
2270 else
2271 fprintf(fp, " no colormap\n");
2272 if (pixc->comptype < NumImageFileFormatExtensions) {
2273 fprintf(fp, " comptype = %s (%d)\n",
2274 ImageFileFormatExtensions[pixc->comptype], pixc->comptype);
2275 } else {
2276 fprintf(fp, " Error!! Invalid comptype index: %d\n", pixc->comptype);
2277 }
2278 return 0;
2279}
2280
2281
2304PIX *
2306 l_int32 outdepth,
2307 l_int32 tilewidth,
2308 l_int32 ncols,
2309 l_int32 background,
2310 l_int32 spacing,
2311 l_int32 border)
2312{
2313PIX *pixd;
2314PIXA *pixa;
2315
2316 if (!pixac)
2317 return (PIX *)ERROR_PTR("pixac not defined", __func__, NULL);
2318
2319 if ((pixa = pixaCreateFromPixacomp(pixac, L_COPY)) == NULL)
2320 return (PIX *)ERROR_PTR("pixa not made", __func__, NULL);
2321
2322 pixd = pixaDisplayTiledAndScaled(pixa, outdepth, tilewidth, ncols,
2323 background, spacing, border);
2324 pixaDestroy(&pixa);
2325 return pixd;
2326}
2327
2328
2336l_ok
2338 const char *subdir)
2339{
2340char buf[128];
2341l_int32 i, n;
2342PIXC *pixc;
2343
2344 if (!pixac)
2345 return ERROR_INT("pixac not defined", __func__, 1);
2346
2347 if (lept_mkdir(subdir) > 0)
2348 return ERROR_INT("invalid subdir", __func__, 1);
2349
2350 n = pixacompGetCount(pixac);
2351 for (i = 0; i < n; i++) {
2352 pixc = pixacompGetPixcomp(pixac, i, L_NOCOPY);
2353 snprintf(buf, sizeof(buf), "/tmp/%s/%03d", subdir, i);
2354 pixcompWriteFile(buf, pixc);
2355 }
2356 return 0;
2357}
2358
2359extern const char *ImageFileFormatExtensions[];
2360
2374l_ok
2375pixcompWriteFile(const char *rootname,
2376 PIXC *pixc)
2377{
2378char buf[128];
2379
2380 if (!pixc)
2381 return ERROR_INT("pixc not defined", __func__, 1);
2382
2383 snprintf(buf, sizeof(buf), "%s.%s", rootname,
2384 ImageFileFormatExtensions[pixc->comptype]);
2385 l_binaryWrite(buf, "w", pixc->data, pixc->size);
2386 return 0;
2387}
struct L_Bytea L_BYTEA
Definition array.h:84
struct Sarray SARRAY
Definition array.h:81
static const size_t InitialPtrArraySize
Definition boxbasic.c:143
@ 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
struct Pix PIX
Definition pix.h:228
struct Box BOX
Definition pix.h:252
struct PixaComp PIXAC
Definition pix.h:303
struct Pixa PIXA
Definition pix.h:243
struct PixComp PIXC
Definition pix.h:300
struct Boxa BOXA
Definition pix.h:255
#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:2088
l_ok pixacompWriteStream(FILE *fp, PIXAC *pixac)
pixacompWriteStream()
Definition pixcomp.c:1800
l_ok pixacompWrite(const char *filename, PIXAC *pixac)
pixacompWrite()
Definition pixcomp.c:1771
void pixcompDestroy(PIXC **ppixc)
pixcompDestroy()
Definition pixcomp.c:356
l_ok pixacompWriteMem(l_uint8 **pdata, size_t *psize, PIXAC *pixac)
pixacompWriteMem()
Definition pixcomp.c:1846
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:2305
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:1974
PIXAC * pixacompReadStream(FILE *fp)
pixacompReadStream()
Definition pixcomp.c:1631
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:2375
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:1923
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:2171
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:2209
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:1738
l_ok pixacompWriteFiles(PIXAC *pixac, const char *subdir)
pixacompWriteFiles()
Definition pixcomp.c:2337
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:2251
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
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