comparison mupdf-source/thirdparty/leptonica/src/pixabasic.c @ 2:b50eed0cc0ef upstream

ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4. The directory name has changed: no version number in the expanded directory now.
author Franz Glasner <fzglas.hg@dom66.de>
date Mon, 15 Sep 2025 11:43:07 +0200
parents
children
comparison
equal deleted inserted replaced
1:1d09e1dec1d9 2:b50eed0cc0ef
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
27 /*!
28 * \file pixabasic.c
29 * <pre>
30 *
31 * Pixa creation, destruction, copying
32 * PIXA *pixaCreate()
33 * PIXA *pixaCreateFromPix()
34 * PIXA *pixaCreateFromBoxa()
35 * PIXA *pixaSplitPix()
36 * void pixaDestroy()
37 * PIXA *pixaCopy()
38 *
39 * Pixa addition
40 * l_int32 pixaAddPix()
41 * l_int32 pixaAddBox()
42 * static l_int32 pixaExtendArray()
43 * l_int32 pixaExtendArrayToSize()
44 *
45 * Pixa accessors
46 * l_int32 pixaGetCount()
47 * PIX *pixaGetPix()
48 * l_int32 pixaGetPixDimensions()
49 * BOXA *pixaGetBoxa()
50 * l_int32 pixaGetBoxaCount()
51 * BOX *pixaGetBox()
52 * l_int32 pixaGetBoxGeometry()
53 * l_int32 pixaSetBoxa()
54 * PIX **pixaGetPixArray()
55 * l_int32 pixaVerifyDepth()
56 * l_int32 pixaVerifyDimensions()
57 * l_int32 pixaIsFull()
58 * l_int32 pixaCountText()
59 * l_int32 pixaSetText()
60 * void ***pixaGetLinePtrs()
61 *
62 * Pixa output info
63 * l_int32 pixaWriteStreamInfo()
64 *
65 * Pixa array modifiers
66 * l_int32 pixaReplacePix()
67 * l_int32 pixaInsertPix()
68 * l_int32 pixaRemovePix()
69 * l_int32 pixaRemovePixAndSave()
70 * l_int32 pixaRemoveSelected()
71 * l_int32 pixaInitFull()
72 * l_int32 pixaClear()
73 *
74 * Pixa and Pixaa combination
75 * l_int32 pixaJoin()
76 * PIXA *pixaInterleave()
77 * l_int32 pixaaJoin()
78 *
79 * Pixaa creation, destruction
80 * PIXAA *pixaaCreate()
81 * PIXAA *pixaaCreateFromPixa()
82 * void pixaaDestroy()
83 *
84 * Pixaa addition
85 * l_int32 pixaaAddPixa()
86 * static l_int32 pixaaExtendArray()
87 * l_int32 pixaaAddPix()
88 * l_int32 pixaaAddBox()
89 *
90 * Pixaa accessors
91 * l_int32 pixaaGetCount()
92 * PIXA *pixaaGetPixa()
93 * BOXA *pixaaGetBoxa()
94 * PIX *pixaaGetPix()
95 * l_int32 pixaaVerifyDepth()
96 * l_int32 pixaaVerifyDimensions()
97 * l_int32 pixaaIsFull()
98 *
99 * Pixaa array modifiers
100 * l_int32 pixaaInitFull()
101 * l_int32 pixaaReplacePixa()
102 * l_int32 pixaaClear()
103 * l_int32 pixaaTruncate()
104 *
105 * Pixa serialized I/O (requires png support)
106 * PIXA *pixaRead()
107 * PIXA *pixaReadStream()
108 * PIXA *pixaReadMem()
109 * l_int32 pixaWriteDebug()
110 * l_int32 pixaWrite()
111 * l_int32 pixaWriteStream()
112 * l_int32 pixaWriteMem()
113 * PIXA *pixaReadBoth()
114 *
115 * Pixaa serialized I/O (requires png support)
116 * PIXAA *pixaaReadFromFiles()
117 * PIXAA *pixaaRead()
118 * PIXAA *pixaaReadStream()
119 * PIXAA *pixaaReadMem()
120 * l_int32 pixaaWrite()
121 * l_int32 pixaaWriteStream()
122 * l_int32 pixaaWriteMem()
123 *
124 *
125 * Important note on reference counting:
126 * Reference counting for the Pixa is analogous to that for the Boxa.
127 * See pix.h for details. pixaCopy() provides three possible modes
128 * of copy. The basic rule is that however a Pixa is obtained
129 * (e.g., from pixaCreate*(), pixaCopy(), or a Pixaa accessor),
130 * it is necessary to call pixaDestroy() on it.
131 * </pre>
132 */
133
134 #ifdef HAVE_CONFIG_H
135 #include <config_auto.h>
136 #endif /* HAVE_CONFIG_H */
137
138 #include <string.h>
139 #include "allheaders.h"
140 #include "pix_internal.h"
141
142 /* Bounds on array sizes */
143 static const size_t MaxInitPtrArraySize = 100000;
144 static const size_t MaxPixaPtrArraySize = 5000000;
145 static const size_t MaxPixaaPtrArraySize = 1000000;
146 static const size_t InitialPtrArraySize = 20; /*!< n'importe quoi */
147
148 /* Static functions */
149 static l_int32 pixaExtendArray(PIXA *pixa);
150 static l_int32 pixaaExtendArray(PIXAA *paa);
151
152 /*---------------------------------------------------------------------*
153 * Pixa creation, destruction, copy *
154 *---------------------------------------------------------------------*/
155 /*!
156 * \brief pixaCreate()
157 *
158 * \param[in] n initial number of ptrs
159 * \return pixa, or NULL on error
160 *
161 * <pre>
162 * Notes:
163 * (1) This creates an empty boxa.
164 * </pre>
165 */
166 PIXA *
167 pixaCreate(l_int32 n)
168 {
169 PIXA *pixa;
170
171 if (n <= 0 || n > MaxInitPtrArraySize)
172 n = InitialPtrArraySize;
173
174 pixa = (PIXA *)LEPT_CALLOC(1, sizeof(PIXA));
175 pixa->n = 0;
176 pixa->nalloc = n;
177 pixa->refcount = 1;
178 pixa->pix = (PIX **)LEPT_CALLOC(n, sizeof(PIX *));
179 pixa->boxa = boxaCreate(n);
180 if (!pixa->pix || !pixa->boxa) {
181 pixaDestroy(&pixa);
182 return (PIXA *)ERROR_PTR("pix or boxa not made", __func__, NULL);
183 }
184 return pixa;
185 }
186
187
188 /*!
189 * \brief pixaCreateFromPix()
190 *
191 * \param[in] pixs with individual components on a lattice
192 * \param[in] n number of components
193 * \param[in] cellw width of each cell
194 * \param[in] cellh height of each cell
195 * \return pixa, or NULL on error
196 *
197 * <pre>
198 * Notes:
199 * (1) For bpp = 1, we truncate each retrieved pix to the ON
200 * pixels, which we assume for now start at (0,0)
201 * </pre>
202 */
203 PIXA *
204 pixaCreateFromPix(PIX *pixs,
205 l_int32 n,
206 l_int32 cellw,
207 l_int32 cellh)
208 {
209 l_int32 w, h, d, nw, nh, i, j, index;
210 PIX *pix1, *pix2;
211 PIXA *pixa;
212
213 if (!pixs)
214 return (PIXA *)ERROR_PTR("pixs not defined", __func__, NULL);
215 if (n <= 0)
216 return (PIXA *)ERROR_PTR("n must be > 0", __func__, NULL);
217
218 if ((pixa = pixaCreate(n)) == NULL)
219 return (PIXA *)ERROR_PTR("pixa not made", __func__, NULL);
220 pixGetDimensions(pixs, &w, &h, &d);
221 if ((pix1 = pixCreate(cellw, cellh, d)) == NULL) {
222 pixaDestroy(&pixa);
223 return (PIXA *)ERROR_PTR("pix1 not made", __func__, NULL);
224 }
225
226 nw = (w + cellw - 1) / cellw;
227 nh = (h + cellh - 1) / cellh;
228 for (i = 0, index = 0; i < nh; i++) {
229 for (j = 0; j < nw && index < n; j++, index++) {
230 pixRasterop(pix1, 0, 0, cellw, cellh, PIX_SRC, pixs,
231 j * cellw, i * cellh);
232 if (d == 1 && !pixClipToForeground(pix1, &pix2, NULL))
233 pixaAddPix(pixa, pix2, L_INSERT);
234 else
235 pixaAddPix(pixa, pix1, L_COPY);
236 }
237 }
238
239 pixDestroy(&pix1);
240 return pixa;
241 }
242
243
244 /*!
245 * \brief pixaCreateFromBoxa()
246 *
247 * \param[in] pixs
248 * \param[in] boxa
249 * \param[in] start first box to use
250 * \param[in] num number of boxes; use 0 to go to the end
251 * \param[out] pcropwarn [optional] TRUE if the boxa extent
252 * is larger than pixs.
253 * \return pixad, or NULL on error
254 *
255 * <pre>
256 * Notes:
257 * (1) This simply extracts from pixs the region corresponding to each
258 * box in the boxa. To extract all the regions, set both %start
259 * and %num to 0.
260 * (2) The 5th arg is optional. If the extent of the boxa exceeds the
261 * size of the pixa, so that some boxes are either clipped
262 * or entirely outside the pix, a warning is returned as TRUE.
263 * (3) pixad will have only the properly clipped elements, and
264 * the internal boxa will be correct.
265 * </pre>
266 */
267 PIXA *
268 pixaCreateFromBoxa(PIX *pixs,
269 BOXA *boxa,
270 l_int32 start,
271 l_int32 num,
272 l_int32 *pcropwarn)
273 {
274 l_int32 i, n, end, w, h, wbox, hbox, cropwarn;
275 BOX *box, *boxc;
276 PIX *pixd;
277 PIXA *pixad;
278
279 if (!pixs)
280 return (PIXA *)ERROR_PTR("pixs not defined", __func__, NULL);
281 if (!boxa)
282 return (PIXA *)ERROR_PTR("boxa not defined", __func__, NULL);
283 if (num < 0)
284 return (PIXA *)ERROR_PTR("num must be >= 0", __func__, NULL);
285
286 n = boxaGetCount(boxa);
287 end = (num == 0) ? n - 1 : L_MIN(start + num - 1, n - 1);
288 if ((pixad = pixaCreate(end - start + 1)) == NULL)
289 return (PIXA *)ERROR_PTR("pixad not made", __func__, NULL);
290
291 boxaGetExtent(boxa, &wbox, &hbox, NULL);
292 pixGetDimensions(pixs, &w, &h, NULL);
293 cropwarn = FALSE;
294 if (wbox > w || hbox > h)
295 cropwarn = TRUE;
296 if (pcropwarn)
297 *pcropwarn = cropwarn;
298
299 for (i = start; i <= end; i++) {
300 box = boxaGetBox(boxa, i, L_COPY);
301 if (cropwarn) { /* if box is outside pixs, pixd is NULL */
302 pixd = pixClipRectangle(pixs, box, &boxc); /* may be NULL */
303 if (pixd) {
304 pixaAddPix(pixad, pixd, L_INSERT);
305 pixaAddBox(pixad, boxc, L_INSERT);
306 }
307 boxDestroy(&box);
308 } else {
309 pixd = pixClipRectangle(pixs, box, NULL);
310 pixaAddPix(pixad, pixd, L_INSERT);
311 pixaAddBox(pixad, box, L_INSERT);
312 }
313 }
314
315 return pixad;
316 }
317
318
319 /*!
320 * \brief pixaSplitPix()
321 *
322 * \param[in] pixs with individual components on a lattice
323 * \param[in] nx number of mosaic cells horizontally
324 * \param[in] ny number of mosaic cells vertically
325 * \param[in] borderwidth of added border on all sides
326 * \param[in] bordercolor in our RGBA format: 0xrrggbbaa
327 * \return pixa, or NULL on error
328 *
329 * <pre>
330 * Notes:
331 * (1) This is a variant on pixaCreateFromPix(), where we
332 * simply divide the image up into (approximately) equal
333 * subunits. If you want the subimages to have essentially
334 * the same aspect ratio as the input pix, use nx = ny.
335 * (2) If borderwidth is 0, we ignore the input bordercolor and
336 * redefine it to white.
337 * (3) The bordercolor is always used to initialize each tiled pix,
338 * so that if the src is clipped, the unblitted part will
339 * be this color. This avoids 1 pixel wide black stripes at the
340 * left and lower edges.
341 * </pre>
342 */
343 PIXA *
344 pixaSplitPix(PIX *pixs,
345 l_int32 nx,
346 l_int32 ny,
347 l_int32 borderwidth,
348 l_uint32 bordercolor)
349 {
350 l_int32 w, h, d, cellw, cellh, i, j;
351 PIX *pix1;
352 PIXA *pixa;
353
354 if (!pixs)
355 return (PIXA *)ERROR_PTR("pixs not defined", __func__, NULL);
356 if (nx <= 0 || ny <= 0)
357 return (PIXA *)ERROR_PTR("nx and ny must be > 0", __func__, NULL);
358 borderwidth = L_MAX(0, borderwidth);
359
360 if ((pixa = pixaCreate(nx * ny)) == NULL)
361 return (PIXA *)ERROR_PTR("pixa not made", __func__, NULL);
362 pixGetDimensions(pixs, &w, &h, &d);
363 cellw = (w + nx - 1) / nx; /* round up */
364 cellh = (h + ny - 1) / ny;
365
366 for (i = 0; i < ny; i++) {
367 for (j = 0; j < nx; j++) {
368 if ((pix1 = pixCreate(cellw + 2 * borderwidth,
369 cellh + 2 * borderwidth, d)) == NULL) {
370 pixaDestroy(&pixa);
371 return (PIXA *)ERROR_PTR("pix1 not made", __func__, NULL);
372 }
373 pixCopyColormap(pix1, pixs);
374 if (borderwidth == 0) { /* initialize full image to white */
375 if (d == 1)
376 pixClearAll(pix1);
377 else
378 pixSetAll(pix1);
379 } else {
380 pixSetAllArbitrary(pix1, bordercolor);
381 }
382 pixRasterop(pix1, borderwidth, borderwidth, cellw, cellh,
383 PIX_SRC, pixs, j * cellw, i * cellh);
384 pixaAddPix(pixa, pix1, L_INSERT);
385 }
386 }
387
388 return pixa;
389 }
390
391
392 /*!
393 * \brief pixaDestroy()
394 *
395 * \param[in,out] ppixa use ptr address so it will be nulled
396 *
397 * <pre>
398 * Notes:
399 * (1) Decrements the ref count and, if 0, destroys the pixa.
400 * (2) Always nulls the input ptr.
401 * </pre>
402 */
403 void
404 pixaDestroy(PIXA **ppixa)
405 {
406 l_int32 i;
407 PIXA *pixa;
408
409 if (ppixa == NULL) {
410 L_WARNING("ptr address is NULL!\n", __func__);
411 return;
412 }
413
414 if ((pixa = *ppixa) == NULL)
415 return;
416
417 /* Decrement the refcount. If it is 0, destroy the pixa. */
418 if (--pixa->refcount == 0) {
419 for (i = 0; i < pixa->n; i++)
420 pixDestroy(&pixa->pix[i]);
421 LEPT_FREE(pixa->pix);
422 boxaDestroy(&pixa->boxa);
423 LEPT_FREE(pixa);
424 }
425
426 *ppixa = NULL;
427 }
428
429
430 /*!
431 * \brief pixaCopy()
432 *
433 * \param[in] pixa
434 * \param[in] copyflag see pix.h for details:
435 * L_COPY makes a new pixa and copies each pix and each box;
436 * L_CLONE gives a new ref-counted handle to the input pixa;
437 * L_COPY_CLONE makes a new pixa and inserts clones of
438 * all pix and boxes
439 * \return new pixa, or NULL on error
440 */
441 PIXA *
442 pixaCopy(PIXA *pixa,
443 l_int32 copyflag)
444 {
445 l_int32 i, nb;
446 BOX *boxc = NULL;
447 PIX *pixc;
448 PIXA *pixac;
449
450 if (!pixa)
451 return (PIXA *)ERROR_PTR("pixa not defined", __func__, NULL);
452
453 if (copyflag == L_CLONE) {
454 ++pixa->refcount;
455 return pixa;
456 }
457
458 if (copyflag != L_COPY && copyflag != L_COPY_CLONE)
459 return (PIXA *)ERROR_PTR("invalid copyflag", __func__, NULL);
460
461 if ((pixac = pixaCreate(pixa->n)) == NULL)
462 return (PIXA *)ERROR_PTR("pixac not made", __func__, NULL);
463 nb = pixaGetBoxaCount(pixa);
464 for (i = 0; i < pixa->n; i++) {
465 if (copyflag == L_COPY) {
466 pixc = pixaGetPix(pixa, i, L_COPY);
467 if (i < nb) boxc = pixaGetBox(pixa, i, L_COPY);
468 } else { /* copy-clone */
469 pixc = pixaGetPix(pixa, i, L_CLONE);
470 if (i < nb) boxc = pixaGetBox(pixa, i, L_CLONE);
471 }
472 pixaAddPix(pixac, pixc, L_INSERT);
473 if (i < nb) pixaAddBox(pixac, boxc, L_INSERT);
474 }
475
476 return pixac;
477 }
478
479
480
481 /*---------------------------------------------------------------------*
482 * Pixa addition *
483 *---------------------------------------------------------------------*/
484 /*!
485 * \brief pixaAddPix()
486 *
487 * \param[in] pixa
488 * \param[in] pix to be added
489 * \param[in] copyflag L_INSERT, L_COPY, L_CLONE
490 * \return 0 if OK; 1 on error
491 */
492 l_ok
493 pixaAddPix(PIXA *pixa,
494 PIX *pix,
495 l_int32 copyflag)
496 {
497 l_int32 n;
498 PIX *pixc;
499
500 if (!pixa)
501 return ERROR_INT("pixa not defined", __func__, 1);
502 if (!pix)
503 return ERROR_INT("pix not defined", __func__, 1);
504
505 if (copyflag == L_INSERT)
506 pixc = pix;
507 else if (copyflag == L_COPY)
508 pixc = pixCopy(NULL, pix);
509 else if (copyflag == L_CLONE)
510 pixc = pixClone(pix);
511 else
512 return ERROR_INT("invalid copyflag", __func__, 1);
513 if (!pixc)
514 return ERROR_INT("pixc not made", __func__, 1);
515
516 n = pixaGetCount(pixa);
517 if (n >= pixa->nalloc) {
518 if (pixaExtendArray(pixa)) {
519 if (copyflag != L_INSERT)
520 pixDestroy(&pixc);
521 return ERROR_INT("extension failed", __func__, 1);
522 }
523 }
524
525 pixa->pix[n] = pixc;
526 pixa->n++;
527 return 0;
528 }
529
530
531 /*!
532 * \brief pixaAddBox()
533 *
534 * \param[in] pixa
535 * \param[in] box
536 * \param[in] copyflag L_INSERT, L_COPY, L_CLONE
537 * \return 0 if OK, 1 on error
538 */
539 l_ok
540 pixaAddBox(PIXA *pixa,
541 BOX *box,
542 l_int32 copyflag)
543 {
544 if (!pixa)
545 return ERROR_INT("pixa not defined", __func__, 1);
546 if (!box)
547 return ERROR_INT("box not defined", __func__, 1);
548 if (copyflag != L_INSERT && copyflag != L_COPY && copyflag != L_CLONE)
549 return ERROR_INT("invalid copyflag", __func__, 1);
550
551 boxaAddBox(pixa->boxa, box, copyflag);
552 return 0;
553 }
554
555
556 /*!
557 * \brief pixaExtendArray()
558 *
559 * \param[in] pixa
560 * \return 0 if OK; 1 on error
561 *
562 * <pre>
563 * Notes:
564 * (1) Doubles the size of the pixa and boxa ptr arrays.
565 * (2) The max number of pix in the array is 5 million.
566 * </pre>
567 */
568 static l_int32
569 pixaExtendArray(PIXA *pixa)
570 {
571 if (!pixa)
572 return ERROR_INT("pixa not defined", __func__, 1);
573
574 return pixaExtendArrayToSize(pixa, 2 * pixa->nalloc);
575 }
576
577
578 /*!
579 * \brief pixaExtendArrayToSize()
580 *
581 * \param[in] pixa
582 * \param[in] size number of pix ptrs in new array
583 * \return 0 if OK; 1 on error
584 *
585 * <pre>
586 * Notes:
587 * (1) If necessary, reallocs new pixa and boxa ptrs arrays to %size.
588 * The pixa and boxa ptr arrays must always be equal in size.
589 * (2) The max number of pix ptrs is 5M.
590 * </pre>
591 */
592 l_ok
593 pixaExtendArrayToSize(PIXA *pixa,
594 size_t size)
595 {
596 size_t oldsize, newsize;
597
598 if (!pixa)
599 return ERROR_INT("pixa not defined", __func__, 1);
600 if (pixa->nalloc > MaxPixaPtrArraySize) /* belt & suspenders */
601 return ERROR_INT("pixa has too many ptrs", __func__, 1);
602 if (size > MaxPixaPtrArraySize)
603 return ERROR_INT("size > 5M ptrs; too large", __func__, 1);
604 if (size <= pixa->nalloc) {
605 L_INFO("size too small; no extension\n", __func__);
606 return 0;
607 }
608
609 oldsize = pixa->nalloc * sizeof(PIX *);
610 newsize = size * sizeof(PIX *);
611 if ((pixa->pix = (PIX **)reallocNew((void **)&pixa->pix,
612 oldsize, newsize)) == NULL)
613 return ERROR_INT("new ptr array not returned", __func__, 1);
614 pixa->nalloc = size;
615 return boxaExtendArrayToSize(pixa->boxa, size);
616 }
617
618
619 /*---------------------------------------------------------------------*
620 * Pixa accessors *
621 *---------------------------------------------------------------------*/
622 /*!
623 * \brief pixaGetCount()
624 *
625 * \param[in] pixa
626 * \return count, or 0 if no pixa
627 */
628 l_int32
629 pixaGetCount(PIXA *pixa)
630 {
631 if (!pixa)
632 return ERROR_INT("pixa not defined", __func__, 0);
633
634 return pixa->n;
635 }
636
637
638 /*!
639 * \brief pixaGetPix()
640 *
641 * \param[in] pixa
642 * \param[in] index to the index-th pix
643 * \param[in] accesstype L_COPY or L_CLONE
644 * \return pix, or NULL on error
645 */
646 PIX *
647 pixaGetPix(PIXA *pixa,
648 l_int32 index,
649 l_int32 accesstype)
650 {
651 PIX *pix;
652
653 if (!pixa)
654 return (PIX *)ERROR_PTR("pixa not defined", __func__, NULL);
655 if (index < 0 || index >= pixa->n)
656 return (PIX *)ERROR_PTR("index not valid", __func__, NULL);
657 if ((pix = pixa->pix[index]) == NULL) {
658 L_ERROR("no pix at pixa[%d]\n", __func__, index);
659 return (PIX *)ERROR_PTR("pix not found!", __func__, NULL);
660 }
661
662 if (accesstype == L_COPY)
663 return pixCopy(NULL, pix);
664 else if (accesstype == L_CLONE)
665 return pixClone(pix);
666 else
667 return (PIX *)ERROR_PTR("invalid accesstype", __func__, NULL);
668 }
669
670
671 /*!
672 * \brief pixaGetPixDimensions()
673 *
674 * \param[in] pixa
675 * \param[in] index to the index-th box
676 * \param[out] pw, ph, pd [optional] each can be null
677 * \return 0 if OK, 1 on error
678 */
679 l_ok
680 pixaGetPixDimensions(PIXA *pixa,
681 l_int32 index,
682 l_int32 *pw,
683 l_int32 *ph,
684 l_int32 *pd)
685 {
686 PIX *pix;
687
688 if (pw) *pw = 0;
689 if (ph) *ph = 0;
690 if (pd) *pd = 0;
691 if (!pixa)
692 return ERROR_INT("pixa not defined", __func__, 1);
693 if (index < 0 || index >= pixa->n)
694 return ERROR_INT("index not valid", __func__, 1);
695
696 if ((pix = pixaGetPix(pixa, index, L_CLONE)) == NULL)
697 return ERROR_INT("pix not found!", __func__, 1);
698 pixGetDimensions(pix, pw, ph, pd);
699 pixDestroy(&pix);
700 return 0;
701 }
702
703
704 /*!
705 * \brief pixaGetBoxa()
706 *
707 * \param[in] pixa
708 * \param[in] accesstype L_COPY, L_CLONE, L_COPY_CLONE
709 * \return boxa, or NULL on error
710 */
711 BOXA *
712 pixaGetBoxa(PIXA *pixa,
713 l_int32 accesstype)
714 {
715 if (!pixa)
716 return (BOXA *)ERROR_PTR("pixa not defined", __func__, NULL);
717 if (!pixa->boxa)
718 return (BOXA *)ERROR_PTR("boxa not defined", __func__, NULL);
719 if (accesstype != L_COPY && accesstype != L_CLONE &&
720 accesstype != L_COPY_CLONE)
721 return (BOXA *)ERROR_PTR("invalid accesstype", __func__, NULL);
722
723 return boxaCopy(pixa->boxa, accesstype);
724 }
725
726
727 /*!
728 * \brief pixaGetBoxaCount()
729 *
730 * \param[in] pixa
731 * \return count, or 0 on error
732 */
733 l_int32
734 pixaGetBoxaCount(PIXA *pixa)
735 {
736 if (!pixa)
737 return ERROR_INT("pixa not defined", __func__, 0);
738
739 return boxaGetCount(pixa->boxa);
740 }
741
742
743 /*!
744 * \brief pixaGetBox()
745 *
746 * \param[in] pixa
747 * \param[in] index to the index-th pix
748 * \param[in] accesstype L_COPY or L_CLONE
749 * \return box if null, not automatically an error, or NULL on error
750 *
751 * <pre>
752 * Notes:
753 * (1) There is always a boxa with a pixa, and it is initialized so
754 * that each box ptr is NULL.
755 * (2) In general, we expect that there is either a box associated
756 * with each pix, or no boxes at all in the boxa.
757 * (3) Having no boxes is thus not an automatic error. Whether it
758 * is an actual error is determined by the calling program.
759 * If the caller expects to get a box, it is an error; see, e.g.,
760 * pixaGetBoxGeometry().
761 * </pre>
762 */
763 BOX *
764 pixaGetBox(PIXA *pixa,
765 l_int32 index,
766 l_int32 accesstype)
767 {
768 BOX *box;
769
770 if (!pixa)
771 return (BOX *)ERROR_PTR("pixa not defined", __func__, NULL);
772 if (!pixa->boxa)
773 return (BOX *)ERROR_PTR("boxa not defined", __func__, NULL);
774 if (index < 0 || index >= pixa->boxa->n)
775 return (BOX *)ERROR_PTR("index not valid", __func__, NULL);
776 if (accesstype != L_COPY && accesstype != L_CLONE)
777 return (BOX *)ERROR_PTR("invalid accesstype", __func__, NULL);
778
779 box = pixa->boxa->box[index];
780 if (box) {
781 if (accesstype == L_COPY)
782 return boxCopy(box);
783 else /* accesstype == L_CLONE */
784 return boxClone(box);
785 } else {
786 return NULL;
787 }
788 }
789
790
791 /*!
792 * \brief pixaGetBoxGeometry()
793 *
794 * \param[in] pixa
795 * \param[in] index to the index-th box
796 * \param[out] px, py, pw, ph [optional] each can be null
797 * \return 0 if OK, 1 on error
798 */
799 l_ok
800 pixaGetBoxGeometry(PIXA *pixa,
801 l_int32 index,
802 l_int32 *px,
803 l_int32 *py,
804 l_int32 *pw,
805 l_int32 *ph)
806 {
807 BOX *box;
808
809 if (px) *px = 0;
810 if (py) *py = 0;
811 if (pw) *pw = 0;
812 if (ph) *ph = 0;
813 if (!pixa)
814 return ERROR_INT("pixa not defined", __func__, 1);
815 if (index < 0 || index >= pixa->n)
816 return ERROR_INT("index not valid", __func__, 1);
817
818 if ((box = pixaGetBox(pixa, index, L_CLONE)) == NULL)
819 return ERROR_INT("box not found!", __func__, 1);
820 boxGetGeometry(box, px, py, pw, ph);
821 boxDestroy(&box);
822 return 0;
823 }
824
825
826 /*!
827 * \brief pixaSetBoxa()
828 *
829 * \param[in] pixa
830 * \param[in] boxa
831 * \param[in] accesstype L_INSERT, L_COPY, L_CLONE
832 * \return 0 if OK, 1 on error
833 *
834 * <pre>
835 * Notes:
836 * (1) This destroys the existing boxa in the pixa.
837 * </pre>
838 */
839 l_ok
840 pixaSetBoxa(PIXA *pixa,
841 BOXA *boxa,
842 l_int32 accesstype)
843 {
844 if (!pixa)
845 return ERROR_INT("pixa not defined", __func__, 1);
846 if (!boxa)
847 return ERROR_INT("boxa not defined", __func__, 1);
848 if (accesstype != L_INSERT && accesstype != L_COPY &&
849 accesstype != L_CLONE)
850 return ERROR_INT("invalid access type", __func__, 1);
851
852 boxaDestroy(&pixa->boxa);
853 if (accesstype == L_INSERT)
854 pixa->boxa = boxa;
855 else
856 pixa->boxa = boxaCopy(boxa, accesstype);
857
858 return 0;
859 }
860
861
862 /*!
863 * \brief pixaGetPixArray()
864 *
865 * \param[in] pixa
866 * \return pix array, or NULL on error
867 *
868 * <pre>
869 * Notes:
870 * (1) This returns a ptr to the actual array. The array is
871 * owned by the pixa, so it must not be destroyed.
872 * (2) The caller should always check if the return value is NULL
873 * before accessing any of the pix ptrs in this array!
874 * </pre>
875 */
876 PIX **
877 pixaGetPixArray(PIXA *pixa)
878 {
879 if (!pixa)
880 return (PIX **)ERROR_PTR("pixa not defined", __func__, NULL);
881
882 return pixa->pix;
883 }
884
885
886 /*!
887 * \brief pixaVerifyDepth()
888 *
889 * \param[in] pixa
890 * \param[out] psame 1 if depth is the same for all pix; 0 otherwise
891 * \param[out] pmaxd [optional] max depth of all pix
892 * \return 0 if OK, 1 on error
893 *
894 * <pre>
895 * Notes:
896 * (1) It is considered to be an error if there are no pix.
897 * </pre>
898 */
899 l_ok
900 pixaVerifyDepth(PIXA *pixa,
901 l_int32 *psame,
902 l_int32 *pmaxd)
903 {
904 l_int32 i, n, d, maxd, same;
905
906 if (pmaxd) *pmaxd = 0;
907 if (!psame)
908 return ERROR_INT("psame not defined", __func__, 1);
909 if (!pixa)
910 return ERROR_INT("pixa not defined", __func__, 1);
911 if ((n = pixaGetCount(pixa)) == 0)
912 return ERROR_INT("no pix in pixa", __func__, 1);
913
914 same = 1;
915 pixaGetPixDimensions(pixa, 0, NULL, NULL, &maxd);
916 for (i = 1; i < n; i++) {
917 if (pixaGetPixDimensions(pixa, i, NULL, NULL, &d))
918 return ERROR_INT("pix depth not found", __func__, 1);
919 maxd = L_MAX(maxd, d);
920 if (d != maxd)
921 same = 0;
922 }
923 *psame = same;
924 if (pmaxd) *pmaxd = maxd;
925 return 0;
926 }
927
928
929 /*!
930 * \brief pixaVerifyDimensions()
931 *
932 * \param[in] pixa
933 * \param[out] psame 1 if dimensions are the same for all pix; 0 otherwise
934 * \param[out] pmaxw [optional] max width of all pix
935 * \param[out] pmaxh [optional] max height of all pix
936 * \return 0 if OK, 1 on error
937 *
938 * <pre>
939 * Notes:
940 * (1) It is considered to be an error if there are no pix.
941 * </pre>
942 */
943 l_ok
944 pixaVerifyDimensions(PIXA *pixa,
945 l_int32 *psame,
946 l_int32 *pmaxw,
947 l_int32 *pmaxh)
948 {
949 l_int32 i, n, w, h, maxw, maxh, same;
950
951 if (pmaxw) *pmaxw = 0;
952 if (pmaxh) *pmaxh = 0;
953 if (!psame)
954 return ERROR_INT("psame not defined", __func__, 1);
955 *psame = 0;
956 if (!pixa)
957 return ERROR_INT("pixa not defined", __func__, 1);
958 if ((n = pixaGetCount(pixa)) == 0)
959 return ERROR_INT("no pix in pixa", __func__, 1);
960
961 same = 1;
962 pixaGetPixDimensions(pixa, 0, &maxw, &maxh, NULL);
963 for (i = 1; i < n; i++) {
964 if (pixaGetPixDimensions(pixa, i, &w, &h, NULL))
965 return ERROR_INT("pix dimensions not found", __func__, 1);
966 maxw = L_MAX(maxw, w);
967 maxh = L_MAX(maxh, h);
968 if (w != maxw || h != maxh)
969 same = 0;
970 }
971 *psame = same;
972 if (pmaxw) *pmaxw = maxw;
973 if (pmaxh) *pmaxh = maxh;
974 return 0;
975 }
976
977
978 /*!
979 * \brief pixaIsFull()
980 *
981 * \param[in] pixa
982 * \param[out] pfullpa [optional] 1 if pixa is full
983 * \param[out] pfullba [optional] 1 if boxa is full
984 * \return 0 if OK, 1 on error
985 *
986 * <pre>
987 * Notes:
988 * (1) A pixa is "full" if the array of pix is fully
989 * occupied from index 0 to index (pixa->n - 1).
990 * </pre>
991 */
992 l_ok
993 pixaIsFull(PIXA *pixa,
994 l_int32 *pfullpa,
995 l_int32 *pfullba)
996 {
997 l_int32 i, n, full;
998 BOXA *boxa;
999 PIX *pix;
1000
1001 if (pfullpa) *pfullpa = 0;
1002 if (pfullba) *pfullba = 0;
1003 if (!pixa)
1004 return ERROR_INT("pixa not defined", __func__, 1);
1005
1006 n = pixaGetCount(pixa);
1007 if (pfullpa) {
1008 full = 1;
1009 for (i = 0; i < n; i++) {
1010 if ((pix = pixaGetPix(pixa, i, L_CLONE)) == NULL) {
1011 full = 0;
1012 break;
1013 }
1014 pixDestroy(&pix);
1015 }
1016 *pfullpa = full;
1017 }
1018 if (pfullba) {
1019 boxa = pixaGetBoxa(pixa, L_CLONE);
1020 boxaIsFull(boxa, pfullba);
1021 boxaDestroy(&boxa);
1022 }
1023 return 0;
1024 }
1025
1026
1027 /*!
1028 * \brief pixaCountText()
1029 *
1030 * \param[in] pixa
1031 * \param[out] pntext number of pix with non-empty text strings
1032 * \return 0 if OK, 1 on error.
1033 *
1034 * <pre>
1035 * Notes:
1036 * (1) All pix have non-empty text strings if the returned value %ntext
1037 * equals the pixa count.
1038 * </pre>
1039 */
1040 l_ok
1041 pixaCountText(PIXA *pixa,
1042 l_int32 *pntext)
1043 {
1044 char *text;
1045 l_int32 i, n;
1046 PIX *pix;
1047
1048 if (!pntext)
1049 return ERROR_INT("&ntext not defined", __func__, 1);
1050 *pntext = 0;
1051 if (!pixa)
1052 return ERROR_INT("pixa not defined", __func__, 1);
1053
1054 n = pixaGetCount(pixa);
1055 for (i = 0; i < n; i++) {
1056 if ((pix = pixaGetPix(pixa, i, L_CLONE)) == NULL)
1057 continue;
1058 text = pixGetText(pix);
1059 if (text && strlen(text) > 0)
1060 (*pntext)++;
1061 pixDestroy(&pix);
1062 }
1063
1064 return 0;
1065 }
1066
1067
1068 /*!
1069 * \brief pixaSetText()
1070 *
1071 * \param[in] pixa
1072 * \param[in] text [optional] single text string, to insert in each pix
1073 * \param[in] sa [optional] array of text strings, to insert in each pix
1074 * \return 0 if OK, 1 on error.
1075 *
1076 * <pre>
1077 * Notes:
1078 * (1) To clear all the text fields, use %sa == NULL and %text == NULL.
1079 * (2) Otherwise, this replaces all text fields with a copy of a string,
1080 * either the same string or a string from %sa.
1081 * (3) To set all the text fields to the same value %text, use %sa = NULL.
1082 * (4) If %sa is defined, ignore %text and use the strings in %sa.
1083 * %sa must have the same count as %pixa.
1084 * </pre>
1085 */
1086 l_ok
1087 pixaSetText(PIXA *pixa,
1088 const char *text,
1089 SARRAY *sa)
1090 {
1091 char *str;
1092 l_int32 i, n;
1093 PIX *pix;
1094
1095 if (!pixa)
1096 return ERROR_INT("pixa not defined", __func__, 1);
1097
1098 n = pixaGetCount(pixa);
1099 if (sa && (sarrayGetCount(sa) != n))
1100 return ERROR_INT("pixa and sa sizes differ", __func__, 1);
1101
1102 if (!sa) {
1103 for (i = 0; i < n; i++) {
1104 if ((pix = pixaGetPix(pixa, i, L_CLONE)) == NULL)
1105 continue;
1106 pixSetText(pix, text);
1107 pixDestroy(&pix);
1108 }
1109 return 0;
1110 }
1111
1112 for (i = 0; i < n; i++) {
1113 if ((pix = pixaGetPix(pixa, i, L_CLONE)) == NULL)
1114 continue;
1115 str = sarrayGetString(sa, i, L_NOCOPY);
1116 pixSetText(pix, str);
1117 pixDestroy(&pix);
1118 }
1119
1120 return 0;
1121 }
1122
1123
1124 /*!
1125 * \brief pixaGetLinePtrs()
1126 *
1127 * \param[in] pixa of pix that all have the same depth
1128 * \param[out] psize [optional] number of pix in the pixa
1129 * \return array of array of line ptrs, or NULL on error
1130 *
1131 * <pre>
1132 * Notes:
1133 * (1) See pixGetLinePtrs() for details.
1134 * (2) It is best if all pix in the pixa are the same size.
1135 * The size of each line ptr array is equal to the height
1136 * of the pix that it refers to.
1137 * (3) This is an array of arrays. To destroy it:
1138 * for (i = 0; i < size; i++)
1139 * LEPT_FREE(lineset[i]);
1140 * LEPT_FREE(lineset);
1141 * </pre>
1142 */
1143 void ***
1144 pixaGetLinePtrs(PIXA *pixa,
1145 l_int32 *psize)
1146 {
1147 l_int32 i, n, same;
1148 void **lineptrs;
1149 void ***lineset;
1150 PIX *pix;
1151
1152 if (psize) *psize = 0;
1153 if (!pixa)
1154 return (void ***)ERROR_PTR("pixa not defined", __func__, NULL);
1155 pixaVerifyDepth(pixa, &same, NULL);
1156 if (!same)
1157 return (void ***)ERROR_PTR("pixa not all same depth", __func__, NULL);
1158 n = pixaGetCount(pixa);
1159 if (psize) *psize = n;
1160 if ((lineset = (void ***)LEPT_CALLOC(n, sizeof(void **))) == NULL)
1161 return (void ***)ERROR_PTR("lineset not made", __func__, NULL);
1162 for (i = 0; i < n; i++) {
1163 pix = pixaGetPix(pixa, i, L_CLONE);
1164 lineptrs = pixGetLinePtrs(pix, NULL);
1165 lineset[i] = lineptrs;
1166 pixDestroy(&pix);
1167 }
1168
1169 return lineset;
1170 }
1171
1172
1173 /*---------------------------------------------------------------------*
1174 * Pixa output info *
1175 *---------------------------------------------------------------------*/
1176 /*!
1177 * \brief pixaWriteStreamInfo()
1178 *
1179 * \param[in] fp file stream
1180 * \param[in] pixa
1181 * \return 0 if OK, 1 on error.
1182 *
1183 * <pre>
1184 * Notes:
1185 * (1) For each pix in the pixa, write out the pix dimensions, spp,
1186 * text string (if it exists), and cmap info.
1187 * </pre>
1188 */
1189 l_ok
1190 pixaWriteStreamInfo(FILE *fp,
1191 PIXA *pixa)
1192 {
1193 char *text;
1194 l_int32 i, n, w, h, d, spp, count, hastext;
1195 PIX *pix;
1196 PIXCMAP *cmap;
1197
1198 if (!fp)
1199 return ERROR_INT("stream not defined", __func__, 1);
1200 if (!pixa)
1201 return ERROR_INT("pixa not defined", __func__, 1);
1202
1203 n = pixaGetCount(pixa);
1204 for (i = 0; i < n; i++) {
1205 if ((pix = pixaGetPix(pixa, i, L_CLONE)) == NULL) {
1206 fprintf(fp, "%d: no pix at this index\n", i);
1207 continue;
1208 }
1209 pixGetDimensions(pix, &w, &h, &d);
1210 spp = pixGetSpp(pix);
1211 text = pixGetText(pix);
1212 hastext = (text && strlen(text) > 0);
1213 if ((cmap = pixGetColormap(pix)) != NULL)
1214 count = pixcmapGetCount(cmap);
1215 fprintf(fp, "Pix %d: w = %d, h = %d, d = %d, spp = %d",
1216 i, w, h, d, spp);
1217 if (cmap) fprintf(fp, ", cmap(%d colors)", count);
1218 if (hastext) fprintf(fp, ", text = %s", text);
1219 fprintf(fp, "\n");
1220 pixDestroy(&pix);
1221 }
1222
1223 return 0;
1224 }
1225
1226
1227 /*---------------------------------------------------------------------*
1228 * Pixa array modifiers *
1229 *---------------------------------------------------------------------*/
1230 /*!
1231 * \brief pixaReplacePix()
1232 *
1233 * \param[in] pixa
1234 * \param[in] index to the index-th pix
1235 * \param[in] pix insert to replace existing one
1236 * \param[in] box [optional] insert to replace existing
1237 * \return 0 if OK, 1 on error
1238 *
1239 * <pre>
1240 * Notes:
1241 * (1) In-place replacement of one pix.
1242 * (2) The previous pix at that location is destroyed.
1243 * </pre>
1244 */
1245 l_ok
1246 pixaReplacePix(PIXA *pixa,
1247 l_int32 index,
1248 PIX *pix,
1249 BOX *box)
1250 {
1251 BOXA *boxa;
1252
1253 if (!pixa)
1254 return ERROR_INT("pixa not defined", __func__, 1);
1255 if (index < 0 || index >= pixa->n)
1256 return ERROR_INT("index not valid", __func__, 1);
1257 if (!pix)
1258 return ERROR_INT("pix not defined", __func__, 1);
1259
1260 pixDestroy(&(pixa->pix[index]));
1261 pixa->pix[index] = pix;
1262
1263 if (box) {
1264 boxa = pixa->boxa;
1265 if (index > boxa->n)
1266 return ERROR_INT("boxa index not valid", __func__, 1);
1267 boxaReplaceBox(boxa, index, box);
1268 }
1269
1270 return 0;
1271 }
1272
1273
1274 /*!
1275 * \brief pixaInsertPix()
1276 *
1277 * \param[in] pixa
1278 * \param[in] index at which pix is to be inserted
1279 * \param[in] pixs new pix to be inserted
1280 * \param[in] box [optional] new box to be inserted
1281 * \return 0 if OK, 1 on error
1282 *
1283 * <pre>
1284 * Notes:
1285 * (1) This shifts pixa[i] --> pixa[i + 1] for all i >= index,
1286 * and then inserts at pixa[index].
1287 * (2) To insert at the beginning of the array, set index = 0.
1288 * (3) It should not be used repeatedly on large arrays,
1289 * because the function is O(n).
1290 * (4) To append a pix to a pixa, it's easier to use pixaAddPix().
1291 * </pre>
1292 */
1293 l_ok
1294 pixaInsertPix(PIXA *pixa,
1295 l_int32 index,
1296 PIX *pixs,
1297 BOX *box)
1298 {
1299 l_int32 i, n;
1300
1301 if (!pixa)
1302 return ERROR_INT("pixa not defined", __func__, 1);
1303 n = pixaGetCount(pixa);
1304 if (index < 0 || index > n) {
1305 L_ERROR("index %d not in [0,...,%d]\n", __func__, index, n);
1306 return 1;
1307 }
1308 if (!pixs)
1309 return ERROR_INT("pixs not defined", __func__, 1);
1310
1311 if (n >= pixa->nalloc) { /* extend both ptr arrays */
1312 if (pixaExtendArray(pixa))
1313 return ERROR_INT("extension failed", __func__, 1);
1314 if (boxaExtendArray(pixa->boxa))
1315 return ERROR_INT("extension failed", __func__, 1);
1316 }
1317 pixa->n++;
1318 for (i = n; i > index; i--)
1319 pixa->pix[i] = pixa->pix[i - 1];
1320 pixa->pix[index] = pixs;
1321
1322 /* Optionally, insert the box */
1323 if (box)
1324 boxaInsertBox(pixa->boxa, index, box);
1325 return 0;
1326 }
1327
1328
1329 /*!
1330 * \brief pixaRemovePix()
1331 *
1332 * \param[in] pixa
1333 * \param[in] index of pix to be removed
1334 * \return 0 if OK, 1 on error
1335 *
1336 * <pre>
1337 * Notes:
1338 * (1) This shifts pixa[i] --> pixa[i - 1] for all i > index.
1339 * (2) It should not be used repeatedly on large arrays,
1340 * because the function is O(n).
1341 * (3) The corresponding box is removed as well, if it exists.
1342 * </pre>
1343 */
1344 l_ok
1345 pixaRemovePix(PIXA *pixa,
1346 l_int32 index)
1347 {
1348 l_int32 i, n, nbox;
1349 BOXA *boxa;
1350 PIX **array;
1351
1352 if (!pixa)
1353 return ERROR_INT("pixa not defined", __func__, 1);
1354 n = pixaGetCount(pixa);
1355 if (index < 0 || index >= n) {
1356 L_ERROR("index %d not in [0,...,%d]\n", __func__, index, n - 1);
1357 return 1;
1358 }
1359
1360 /* Remove the pix */
1361 array = pixa->pix;
1362 pixDestroy(&array[index]);
1363 for (i = index + 1; i < n; i++)
1364 array[i - 1] = array[i];
1365 array[n - 1] = NULL;
1366 pixa->n--;
1367
1368 /* Remove the box if it exists */
1369 boxa = pixa->boxa;
1370 nbox = boxaGetCount(boxa);
1371 if (index < nbox)
1372 boxaRemoveBox(boxa, index);
1373
1374 return 0;
1375 }
1376
1377
1378 /*!
1379 * \brief pixaRemovePixAndSave()
1380 *
1381 * \param[in] pixa
1382 * \param[in] index of pix to be removed
1383 * \param[out] ppix [optional] removed pix
1384 * \param[out] pbox [optional] removed box
1385 * \return 0 if OK, 1 on error
1386 *
1387 * <pre>
1388 * Notes:
1389 * (1) This shifts pixa[i] --> pixa[i - 1] for all i > index.
1390 * (2) It should not be used repeatedly on large arrays,
1391 * because the function is O(n).
1392 * (3) The corresponding box is removed as well, if it exists.
1393 * (4) The removed pix and box can either be retained or destroyed.
1394 * </pre>
1395 */
1396 l_ok
1397 pixaRemovePixAndSave(PIXA *pixa,
1398 l_int32 index,
1399 PIX **ppix,
1400 BOX **pbox)
1401 {
1402 l_int32 i, n, nbox;
1403 BOXA *boxa;
1404 PIX **array;
1405
1406 if (ppix) *ppix = NULL;
1407 if (pbox) *pbox = NULL;
1408 if (!pixa)
1409 return ERROR_INT("pixa not defined", __func__, 1);
1410 n = pixaGetCount(pixa);
1411 if (index < 0 || index >= n) {
1412 L_ERROR("index %d not in [0,...,%d]\n", __func__, index, n - 1);
1413 return 1;
1414 }
1415
1416 /* Remove the pix */
1417 array = pixa->pix;
1418 if (ppix)
1419 *ppix = pixaGetPix(pixa, index, L_CLONE);
1420 pixDestroy(&array[index]);
1421 for (i = index + 1; i < n; i++)
1422 array[i - 1] = array[i];
1423 array[n - 1] = NULL;
1424 pixa->n--;
1425
1426 /* Remove the box if it exists */
1427 boxa = pixa->boxa;
1428 nbox = boxaGetCount(boxa);
1429 if (index < nbox)
1430 boxaRemoveBoxAndSave(boxa, index, pbox);
1431
1432 return 0;
1433 }
1434
1435
1436 /*!
1437 * \brief pixaRemoveSelected()
1438 *
1439 * \param[in] pixa
1440 * \param[in] naindex numa of indices of pix to be removed
1441 * \return 0 if OK, 1 on error
1442 *
1443 * <pre>
1444 * Notes:
1445 * (1) This gives error messages for invalid indices
1446 * </pre>
1447 */
1448 l_ok
1449 pixaRemoveSelected(PIXA *pixa,
1450 NUMA *naindex)
1451 {
1452 l_int32 i, n, index;
1453 NUMA *na1;
1454
1455 if (!pixa)
1456 return ERROR_INT("pixa not defined", __func__, 1);
1457 if (!naindex)
1458 return ERROR_INT("naindex not defined", __func__, 1);
1459 if ((n = numaGetCount(naindex)) == 0)
1460 return ERROR_INT("naindex is empty", __func__, 1);
1461
1462 /* Remove from highest indices first */
1463 na1 = numaSort(NULL, naindex, L_SORT_DECREASING);
1464 for (i = 0; i < n; i++) {
1465 numaGetIValue(na1, i, &index);
1466 pixaRemovePix(pixa, index);
1467 }
1468 numaDestroy(&na1);
1469 return 0;
1470 }
1471
1472
1473 /*!
1474 * \brief pixaInitFull()
1475 *
1476 * \param[in] pixa typically empty
1477 * \param[in] pix [optional] to be replicated to the entire pixa ptr array
1478 * \param[in] box [optional] to be replicated to the entire boxa ptr array
1479 * \return 0 if OK, 1 on error
1480 *
1481 * <pre>
1482 * Notes:
1483 * (1) This initializes a pixa by filling up the entire pix ptr array
1484 * with copies of %pix. If %pix == NULL, we use a tiny placeholder
1485 * pix (w = h = d = 1). Any existing pix are destroyed.
1486 * It also optionally fills the boxa with copies of %box.
1487 * After this operation, the numbers of pix and (optionally)
1488 * boxes are equal to the number of allocated ptrs.
1489 * (2) Note that we use pixaReplacePix() instead of pixaInsertPix().
1490 * They both have the same effect when inserting into a NULL ptr
1491 * in the pixa ptr array:
1492 * (3) If the boxa is not initialized (i.e., filled with boxes),
1493 * later insertion of boxes will cause an error, because the
1494 * 'n' field is 0.
1495 * (4) Example usage. This function is useful to prepare for a
1496 * random insertion (or replacement) of pix into a pixa.
1497 * To randomly insert pix into a pixa, without boxes, up to
1498 * some index "max":
1499 * Pixa *pixa = pixaCreate(max);
1500 * pixaInitFull(pixa, NULL, NULL);
1501 * An existing pixa with a smaller ptr array can also be reused:
1502 * pixaExtendArrayToSize(pixa, max);
1503 * pixaInitFull(pixa, NULL, NULL);
1504 * The initialization allows the pixa to always be properly
1505 * filled, even if all pix (and boxes) are not later replaced.
1506 * </pre>
1507 */
1508 l_ok
1509 pixaInitFull(PIXA *pixa,
1510 PIX *pix,
1511 BOX *box)
1512 {
1513 l_int32 i, n;
1514 PIX *pix1;
1515
1516 if (!pixa)
1517 return ERROR_INT("pixa not defined", __func__, 1);
1518
1519 n = pixa->nalloc;
1520 pixa->n = n;
1521 for (i = 0; i < n; i++) {
1522 if (pix)
1523 pix1 = pixCopy(NULL, pix);
1524 else
1525 pix1 = pixCreate(1, 1, 1);
1526 pixaReplacePix(pixa, i, pix1, NULL);
1527 }
1528 if (box)
1529 boxaInitFull(pixa->boxa, box);
1530
1531 return 0;
1532 }
1533
1534
1535 /*!
1536 * \brief pixaClear()
1537 *
1538 * \param[in] pixa
1539 * \return 0 if OK, 1 on error
1540 *
1541 * <pre>
1542 * Notes:
1543 * (1) This destroys all pix in the pixa, as well as
1544 * all boxes in the boxa. The ptrs in the pix ptr array
1545 * are all null'd. The number of allocated pix, n, is set to 0.
1546 * </pre>
1547 */
1548 l_ok
1549 pixaClear(PIXA *pixa)
1550 {
1551 l_int32 i, n;
1552
1553 if (!pixa)
1554 return ERROR_INT("pixa not defined", __func__, 1);
1555
1556 n = pixaGetCount(pixa);
1557 for (i = 0; i < n; i++)
1558 pixDestroy(&pixa->pix[i]);
1559 pixa->n = 0;
1560 return boxaClear(pixa->boxa);
1561 }
1562
1563
1564 /*---------------------------------------------------------------------*
1565 * Pixa and Pixaa combination *
1566 *---------------------------------------------------------------------*/
1567 /*!
1568 * \brief pixaJoin()
1569 *
1570 * \param[in] pixad dest pixa; add to this one
1571 * \param[in] pixas [optional] source pixa; add from this one
1572 * \param[in] istart starting index in pixas
1573 * \param[in] iend ending index in pixas; use -1 to cat all
1574 * \return 0 if OK, 1 on error
1575 *
1576 * <pre>
1577 * Notes:
1578 * (1) This appends a clone of each indicated pix in pixas to pixad
1579 * (2) istart < 0 is taken to mean 'read from the start' (istart = 0)
1580 * (3) iend < 0 means 'read to the end'
1581 * (4) If pixas is NULL or contains no pix, this is a no-op.
1582 * </pre>
1583 */
1584 l_ok
1585 pixaJoin(PIXA *pixad,
1586 PIXA *pixas,
1587 l_int32 istart,
1588 l_int32 iend)
1589 {
1590 l_int32 i, n, nb;
1591 BOXA *boxas, *boxad;
1592 PIX *pix;
1593
1594 if (!pixad)
1595 return ERROR_INT("pixad not defined", __func__, 1);
1596 if (!pixas || ((n = pixaGetCount(pixas)) == 0))
1597 return 0;
1598
1599 if (istart < 0)
1600 istart = 0;
1601 if (iend < 0 || iend >= n)
1602 iend = n - 1;
1603 if (istart > iend)
1604 return ERROR_INT("istart > iend; nothing to add", __func__, 1);
1605
1606 for (i = istart; i <= iend; i++) {
1607 pix = pixaGetPix(pixas, i, L_CLONE);
1608 pixaAddPix(pixad, pix, L_INSERT);
1609 }
1610
1611 boxas = pixaGetBoxa(pixas, L_CLONE);
1612 boxad = pixaGetBoxa(pixad, L_CLONE);
1613 nb = pixaGetBoxaCount(pixas);
1614 iend = L_MIN(iend, nb - 1);
1615 boxaJoin(boxad, boxas, istart, iend);
1616 boxaDestroy(&boxas); /* just the clones */
1617 boxaDestroy(&boxad);
1618 return 0;
1619 }
1620
1621
1622 /*!
1623 * \brief pixaInterleave()
1624 *
1625 * \param[in] pixa1 first src pixa
1626 * \param[in] pixa2 second src pixa
1627 * \param[in] copyflag L_CLONE, L_COPY
1628 * \return pixa interleaved from sources, or NULL on error.
1629 *
1630 * <pre>
1631 * Notes:
1632 * (1) %copyflag determines if the pix are copied or cloned.
1633 * The boxes, if they exist, are copied.
1634 * (2) If the two pixa have different sizes, a warning is issued,
1635 * and the number of pairs returned is the minimum size.
1636 * </pre>
1637 */
1638 PIXA *
1639 pixaInterleave(PIXA *pixa1,
1640 PIXA *pixa2,
1641 l_int32 copyflag)
1642 {
1643 l_int32 i, n1, n2, n, nb1, nb2;
1644 BOX *box;
1645 PIX *pix;
1646 PIXA *pixad;
1647
1648 if (!pixa1)
1649 return (PIXA *)ERROR_PTR("pixa1 not defined", __func__, NULL);
1650 if (!pixa2)
1651 return (PIXA *)ERROR_PTR("pixa2 not defined", __func__, NULL);
1652 if (copyflag != L_COPY && copyflag != L_CLONE)
1653 return (PIXA *)ERROR_PTR("invalid copyflag", __func__, NULL);
1654 n1 = pixaGetCount(pixa1);
1655 n2 = pixaGetCount(pixa2);
1656 n = L_MIN(n1, n2);
1657 if (n == 0)
1658 return (PIXA *)ERROR_PTR("at least one input pixa is empty",
1659 __func__, NULL);
1660 if (n1 != n2)
1661 L_WARNING("counts differ: %d != %d\n", __func__, n1, n2);
1662
1663 pixad = pixaCreate(2 * n);
1664 nb1 = pixaGetBoxaCount(pixa1);
1665 nb2 = pixaGetBoxaCount(pixa2);
1666 for (i = 0; i < n; i++) {
1667 pix = pixaGetPix(pixa1, i, copyflag);
1668 pixaAddPix(pixad, pix, L_INSERT);
1669 if (i < nb1) {
1670 box = pixaGetBox(pixa1, i, L_COPY);
1671 pixaAddBox(pixad, box, L_INSERT);
1672 }
1673 pix = pixaGetPix(pixa2, i, copyflag);
1674 pixaAddPix(pixad, pix, L_INSERT);
1675 if (i < nb2) {
1676 box = pixaGetBox(pixa2, i, L_COPY);
1677 pixaAddBox(pixad, box, L_INSERT);
1678 }
1679 }
1680
1681 return pixad;
1682 }
1683
1684
1685 /*!
1686 * \brief pixaaJoin()
1687 *
1688 * \param[in] paad dest pixaa; add to this one
1689 * \param[in] paas [optional] source pixaa; add from this one
1690 * \param[in] istart starting index in pixaas
1691 * \param[in] iend ending index in pixaas; use -1 to cat all
1692 * \return 0 if OK, 1 on error
1693 *
1694 * <pre>
1695 * Notes:
1696 * (1) This appends a clone of each indicated pixa in paas to pixaad
1697 * (2) istart < 0 is taken to mean 'read from the start' (istart = 0)
1698 * (3) iend < 0 means 'read to the end'
1699 * </pre>
1700 */
1701 l_ok
1702 pixaaJoin(PIXAA *paad,
1703 PIXAA *paas,
1704 l_int32 istart,
1705 l_int32 iend)
1706 {
1707 l_int32 i, n;
1708 PIXA *pixa;
1709
1710 if (!paad)
1711 return ERROR_INT("pixaad not defined", __func__, 1);
1712 if (!paas)
1713 return 0;
1714
1715 if (istart < 0)
1716 istart = 0;
1717 n = pixaaGetCount(paas, NULL);
1718 if (iend < 0 || iend >= n)
1719 iend = n - 1;
1720 if (istart > iend)
1721 return ERROR_INT("istart > iend; nothing to add", __func__, 1);
1722
1723 for (i = istart; i <= iend; i++) {
1724 pixa = pixaaGetPixa(paas, i, L_CLONE);
1725 pixaaAddPixa(paad, pixa, L_INSERT);
1726 }
1727
1728 return 0;
1729 }
1730
1731
1732 /*---------------------------------------------------------------------*
1733 * Pixaa creation and destruction *
1734 *---------------------------------------------------------------------*/
1735 /*!
1736 * \brief pixaaCreate()
1737 *
1738 * \param[in] n initial number of pixa ptrs
1739 * \return paa, or NULL on error
1740 *
1741 * <pre>
1742 * Notes:
1743 * (1) A pixaa provides a 2-level hierarchy of images.
1744 * A common use is for segmentation masks, which are
1745 * inexpensive to store in png format.
1746 * (2) For example, suppose you want a mask for each textline
1747 * in a two-column page. The textline masks for each column
1748 * can be represented by a pixa, of which there are 2 in the pixaa.
1749 * The boxes for the textline mask components within a column
1750 * can have their origin referred to the column rather than the page.
1751 * Then the boxa field can be used to represent the two box (regions)
1752 * for the columns, and the (x,y) components of each box can
1753 * be used to get the absolute position of the textlines on
1754 * the page.
1755 * </pre>
1756 */
1757 PIXAA *
1758 pixaaCreate(l_int32 n)
1759 {
1760 PIXAA *paa;
1761
1762 if (n <= 0 || n > MaxInitPtrArraySize)
1763 n = InitialPtrArraySize;
1764
1765 paa = (PIXAA *)LEPT_CALLOC(1, sizeof(PIXAA));
1766 paa->n = 0;
1767 paa->nalloc = n;
1768 if ((paa->pixa = (PIXA **)LEPT_CALLOC(n, sizeof(PIXA *))) == NULL) {
1769 pixaaDestroy(&paa);
1770 return (PIXAA *)ERROR_PTR("pixa ptrs not made", __func__, NULL);
1771 }
1772 paa->boxa = boxaCreate(n);
1773
1774 return paa;
1775 }
1776
1777
1778 /*!
1779 * \brief pixaaCreateFromPixa()
1780 *
1781 * \param[in] pixa
1782 * \param[in] n number specifying subdivision of pixa
1783 * \param[in] type L_CHOOSE_CONSECUTIVE, L_CHOOSE_SKIP_BY
1784 * \param[in] copyflag L_CLONE, L_COPY
1785 * \return paa, or NULL on error
1786 *
1787 * <pre>
1788 * Notes:
1789 * (1) This subdivides a pixa into a set of smaller pixa that
1790 * are accumulated into a pixaa.
1791 * (2) If type == L_CHOOSE_CONSECUTIVE, the first 'n' pix are
1792 * put in a pixa and added to pixaa, then the next 'n', etc.
1793 * If type == L_CHOOSE_SKIP_BY, the first pixa is made by
1794 * aggregating pix[0], pix[n], pix[2*n], etc.
1795 * (3) The copyflag specifies if each new pix is a copy or a clone.
1796 * </pre>
1797 */
1798 PIXAA *
1799 pixaaCreateFromPixa(PIXA *pixa,
1800 l_int32 n,
1801 l_int32 type,
1802 l_int32 copyflag)
1803 {
1804 l_int32 count, i, j, npixa;
1805 PIX *pix;
1806 PIXA *pixat = NULL;
1807 PIXAA *paa;
1808
1809 if (!pixa)
1810 return (PIXAA *)ERROR_PTR("pixa not defined", __func__, NULL);
1811 count = pixaGetCount(pixa);
1812 if (count == 0)
1813 return (PIXAA *)ERROR_PTR("no pix in pixa", __func__, NULL);
1814 if (n <= 0)
1815 return (PIXAA *)ERROR_PTR("n must be > 0", __func__, NULL);
1816 if (type != L_CHOOSE_CONSECUTIVE && type != L_CHOOSE_SKIP_BY)
1817 return (PIXAA *)ERROR_PTR("invalid type", __func__, NULL);
1818 if (copyflag != L_CLONE && copyflag != L_COPY)
1819 return (PIXAA *)ERROR_PTR("invalid copyflag", __func__, NULL);
1820
1821 if (type == L_CHOOSE_CONSECUTIVE)
1822 npixa = (count + n - 1) / n;
1823 else /* L_CHOOSE_SKIP_BY */
1824 npixa = L_MIN(n, count);
1825 paa = pixaaCreate(npixa);
1826 if (type == L_CHOOSE_CONSECUTIVE) {
1827 for (i = 0; i < count; i++) {
1828 if (i % n == 0)
1829 pixat = pixaCreate(n);
1830 pix = pixaGetPix(pixa, i, copyflag);
1831 pixaAddPix(pixat, pix, L_INSERT);
1832 if (i % n == n - 1)
1833 pixaaAddPixa(paa, pixat, L_INSERT);
1834 }
1835 if (i % n != 0)
1836 pixaaAddPixa(paa, pixat, L_INSERT);
1837 } else { /* L_CHOOSE_SKIP_BY */
1838 for (i = 0; i < npixa; i++) {
1839 pixat = pixaCreate(count / npixa + 1);
1840 for (j = i; j < count; j += n) {
1841 pix = pixaGetPix(pixa, j, copyflag);
1842 pixaAddPix(pixat, pix, L_INSERT);
1843 }
1844 pixaaAddPixa(paa, pixat, L_INSERT);
1845 }
1846 }
1847
1848 return paa;
1849 }
1850
1851
1852 /*!
1853 * \brief pixaaDestroy()
1854 *
1855 * \param[in,out] ppaa use ptr address so it will be nulled
1856 * \return void
1857 */
1858 void
1859 pixaaDestroy(PIXAA **ppaa)
1860 {
1861 l_int32 i;
1862 PIXAA *paa;
1863
1864 if (ppaa == NULL) {
1865 L_WARNING("ptr address is NULL!\n", __func__);
1866 return;
1867 }
1868
1869 if ((paa = *ppaa) == NULL)
1870 return;
1871
1872 for (i = 0; i < paa->n; i++)
1873 pixaDestroy(&paa->pixa[i]);
1874 LEPT_FREE(paa->pixa);
1875 boxaDestroy(&paa->boxa);
1876 LEPT_FREE(paa);
1877 *ppaa = NULL;
1878 }
1879
1880
1881 /*---------------------------------------------------------------------*
1882 * Pixaa addition *
1883 *---------------------------------------------------------------------*/
1884 /*!
1885 * \brief pixaaAddPixa()
1886 *
1887 * \param[in] paa
1888 * \param[in] pixa to be added
1889 * \param[in] copyflag:
1890 * L_INSERT inserts the pixa directly;
1891 * L_COPY makes a new pixa and copies each pix and each box;
1892 * L_CLONE gives a new handle to the input pixa;
1893 * L_COPY_CLONE makes a new pixa and inserts clones of
1894 * all pix and boxes
1895 * \return 0 if OK; 1 on error
1896 */
1897 l_ok
1898 pixaaAddPixa(PIXAA *paa,
1899 PIXA *pixa,
1900 l_int32 copyflag)
1901 {
1902 l_int32 n;
1903 PIXA *pixac;
1904
1905 if (!paa)
1906 return ERROR_INT("paa not defined", __func__, 1);
1907 if (!pixa)
1908 return ERROR_INT("pixa not defined", __func__, 1);
1909 if (copyflag != L_INSERT && copyflag != L_COPY &&
1910 copyflag != L_CLONE && copyflag != L_COPY_CLONE)
1911 return ERROR_INT("invalid copyflag", __func__, 1);
1912
1913 if (copyflag == L_INSERT) {
1914 pixac = pixa;
1915 } else {
1916 if ((pixac = pixaCopy(pixa, copyflag)) == NULL)
1917 return ERROR_INT("pixac not made", __func__, 1);
1918 }
1919
1920 n = pixaaGetCount(paa, NULL);
1921 if (n >= paa->nalloc) {
1922 if (pixaaExtendArray(paa)) {
1923 if (copyflag != L_INSERT)
1924 pixaDestroy(&pixac);
1925 return ERROR_INT("extension failed", __func__, 1);
1926 }
1927 }
1928 paa->pixa[n] = pixac;
1929 paa->n++;
1930 return 0;
1931 }
1932
1933
1934 /*!
1935 * \brief pixaaExtendArray()
1936 *
1937 * \param[in] paa
1938 * \return 0 if OK; 1 on error
1939 *
1940 * <pre>
1941 * Notes:
1942 * (1) The max number of pixa ptrs is 1M.
1943 * </pre>
1944 */
1945 static l_int32
1946 pixaaExtendArray(PIXAA *paa)
1947 {
1948 size_t oldsize, newsize;
1949
1950 if (!paa)
1951 return ERROR_INT("paa not defined", __func__, 1);
1952 if (paa->nalloc > MaxPixaaPtrArraySize) /* belt & suspenders */
1953 return ERROR_INT("paa has too many ptrs", __func__, 1);
1954 oldsize = paa->nalloc * sizeof(PIXA *);
1955 newsize = 2 * oldsize;
1956 if (newsize > 8 * MaxPixaaPtrArraySize)
1957 return ERROR_INT("newsize > 8 MB; too large", __func__, 1);
1958
1959 if ((paa->pixa = (PIXA **)reallocNew((void **)&paa->pixa,
1960 oldsize, newsize)) == NULL)
1961 return ERROR_INT("new ptr array not returned", __func__, 1);
1962
1963 paa->nalloc *= 2;
1964 return 0;
1965 }
1966
1967
1968 /*!
1969 * \brief pixaaAddPix()
1970 *
1971 * \param[in] paa input paa
1972 * \param[in] index index of pixa in paa
1973 * \param[in] pix to be added
1974 * \param[in] box [optional] to be added
1975 * \param[in] copyflag L_INSERT, L_COPY, L_CLONE
1976 * \return 0 if OK; 1 on error
1977 */
1978 l_ok
1979 pixaaAddPix(PIXAA *paa,
1980 l_int32 index,
1981 PIX *pix,
1982 BOX *box,
1983 l_int32 copyflag)
1984 {
1985 PIXA *pixa;
1986
1987 if (!paa)
1988 return ERROR_INT("paa not defined", __func__, 1);
1989 if (!pix)
1990 return ERROR_INT("pix not defined", __func__, 1);
1991
1992 if ((pixa = pixaaGetPixa(paa, index, L_CLONE)) == NULL)
1993 return ERROR_INT("pixa not found", __func__, 1);
1994 pixaAddPix(pixa, pix, copyflag);
1995 if (box) pixaAddBox(pixa, box, copyflag);
1996 pixaDestroy(&pixa);
1997 return 0;
1998 }
1999
2000
2001 /*!
2002 * \brief pixaaAddBox()
2003 *
2004 * \param[in] paa
2005 * \param[in] box
2006 * \param[in] copyflag L_INSERT, L_COPY, L_CLONE
2007 * \return 0 if OK, 1 on error
2008 *
2009 * <pre>
2010 * Notes:
2011 * (1) The box can be used, for example, to hold the support region
2012 * of a pixa that is being added to the pixaa.
2013 * </pre>
2014 */
2015 l_ok
2016 pixaaAddBox(PIXAA *paa,
2017 BOX *box,
2018 l_int32 copyflag)
2019 {
2020 if (!paa)
2021 return ERROR_INT("paa not defined", __func__, 1);
2022 if (!box)
2023 return ERROR_INT("box not defined", __func__, 1);
2024 if (copyflag != L_INSERT && copyflag != L_COPY && copyflag != L_CLONE)
2025 return ERROR_INT("invalid copyflag", __func__, 1);
2026
2027 boxaAddBox(paa->boxa, box, copyflag);
2028 return 0;
2029 }
2030
2031
2032
2033 /*---------------------------------------------------------------------*
2034 * Pixaa accessors *
2035 *---------------------------------------------------------------------*/
2036 /*!
2037 * \brief pixaaGetCount()
2038 *
2039 * \param[in] paa
2040 * \param[out] pna [optional] number of pix in each pixa
2041 * \return count, or 0 if no pixaa
2042 *
2043 * <pre>
2044 * Notes:
2045 * (1) If paa is empty, a returned na will also be empty.
2046 * </pre>
2047 */
2048 l_int32
2049 pixaaGetCount(PIXAA *paa,
2050 NUMA **pna)
2051 {
2052 l_int32 i, n;
2053 NUMA *na;
2054 PIXA *pixa;
2055
2056 if (pna) *pna = NULL;
2057 if (!paa)
2058 return ERROR_INT("paa not defined", __func__, 0);
2059
2060 n = paa->n;
2061 if (pna) {
2062 if ((na = numaCreate(n)) == NULL)
2063 return ERROR_INT("na not made", __func__, 0);
2064 *pna = na;
2065 for (i = 0; i < n; i++) {
2066 pixa = pixaaGetPixa(paa, i, L_CLONE);
2067 numaAddNumber(na, pixaGetCount(pixa));
2068 pixaDestroy(&pixa);
2069 }
2070 }
2071 return n;
2072 }
2073
2074
2075 /*!
2076 * \brief pixaaGetPixa()
2077 *
2078 * \param[in] paa
2079 * \param[in] index to the index-th pixa
2080 * \param[in] accesstype L_COPY, L_CLONE, L_COPY_CLONE
2081 * \return pixa, or NULL on error
2082 *
2083 * <pre>
2084 * Notes:
2085 * (1) L_COPY makes a new pixa with a copy of every pix
2086 * (2) L_CLONE just makes a new reference to the pixa,
2087 * and bumps the counter. You would use this, for example,
2088 * when you need to extract some data from a pix within a
2089 * pixa within a pixaa.
2090 * (3) L_COPY_CLONE makes a new pixa with a clone of every pix
2091 * and box
2092 * (4) In all cases, you must invoke pixaDestroy() on the returned pixa
2093 * </pre>
2094 */
2095 PIXA *
2096 pixaaGetPixa(PIXAA *paa,
2097 l_int32 index,
2098 l_int32 accesstype)
2099 {
2100 PIXA *pixa;
2101
2102 if (!paa)
2103 return (PIXA *)ERROR_PTR("paa not defined", __func__, NULL);
2104 if (index < 0 || index >= paa->n)
2105 return (PIXA *)ERROR_PTR("index not valid", __func__, NULL);
2106 if (accesstype != L_COPY && accesstype != L_CLONE &&
2107 accesstype != L_COPY_CLONE)
2108 return (PIXA *)ERROR_PTR("invalid accesstype", __func__, NULL);
2109
2110 if ((pixa = paa->pixa[index]) == NULL) { /* shouldn't happen! */
2111 L_ERROR("missing pixa[%d]\n", __func__, index);
2112 return (PIXA *)ERROR_PTR("pixa not found at index", __func__, NULL);
2113 }
2114 return pixaCopy(pixa, accesstype);
2115 }
2116
2117
2118 /*!
2119 * \brief pixaaGetBoxa()
2120 *
2121 * \param[in] paa
2122 * \param[in] accesstype L_COPY, L_CLONE
2123 * \return boxa, or NULL on error
2124 *
2125 * <pre>
2126 * Notes:
2127 * (1) L_COPY returns a copy; L_CLONE returns a new reference to the boxa.
2128 * (2) In both cases, invoke boxaDestroy() on the returned boxa.
2129 * </pre>
2130 */
2131 BOXA *
2132 pixaaGetBoxa(PIXAA *paa,
2133 l_int32 accesstype)
2134 {
2135 if (!paa)
2136 return (BOXA *)ERROR_PTR("paa not defined", __func__, NULL);
2137 if (accesstype != L_COPY && accesstype != L_CLONE)
2138 return (BOXA *)ERROR_PTR("invalid access type", __func__, NULL);
2139
2140 return boxaCopy(paa->boxa, accesstype);
2141 }
2142
2143
2144 /*!
2145 * \brief pixaaGetPix()
2146 *
2147 * \param[in] paa
2148 * \param[in] index index into the pixa array in the pixaa
2149 * \param[in] ipix index into the pix array in the pixa
2150 * \param[in] accessflag L_COPY or L_CLONE
2151 * \return pix, or NULL on error
2152 */
2153 PIX *
2154 pixaaGetPix(PIXAA *paa,
2155 l_int32 index,
2156 l_int32 ipix,
2157 l_int32 accessflag)
2158 {
2159 PIX *pix;
2160 PIXA *pixa;
2161
2162 if ((pixa = pixaaGetPixa(paa, index, L_CLONE)) == NULL)
2163 return (PIX *)ERROR_PTR("pixa not retrieved", __func__, NULL);
2164 if ((pix = pixaGetPix(pixa, ipix, accessflag)) == NULL)
2165 L_ERROR("pix not retrieved\n", __func__);
2166 pixaDestroy(&pixa);
2167 return pix;
2168 }
2169
2170
2171 /*!
2172 * \brief pixaaVerifyDepth()
2173 *
2174 * \param[in] paa
2175 * \param[out] psame 1 if all pix have the same depth; 0 otherwise
2176 * \param[out] pmaxd [optional] max depth of all pix in pixaa
2177 * \return 0 if OK; 1 on error
2178 *
2179 * <pre>
2180 * Notes:
2181 * (1) It is considered to be an error if any pixa have no pix.
2182 * </pre>
2183 */
2184 l_ok
2185 pixaaVerifyDepth(PIXAA *paa,
2186 l_int32 *psame,
2187 l_int32 *pmaxd)
2188 {
2189 l_int32 i, n, d, maxd, same, samed;
2190 PIXA *pixa;
2191
2192 if (pmaxd) *pmaxd = 0;
2193 if (!psame)
2194 return ERROR_INT("psame not defined", __func__, 1);
2195 *psame = 0;
2196 if (!paa)
2197 return ERROR_INT("paa not defined", __func__, 1);
2198 if ((n = pixaaGetCount(paa, NULL)) == 0)
2199 return ERROR_INT("no pixa in paa", __func__, 1);
2200
2201 pixa = pixaaGetPixa(paa, 0, L_CLONE);
2202 pixaVerifyDepth(pixa, &same, &maxd); /* init same, maxd with first pixa */
2203 pixaDestroy(&pixa);
2204 for (i = 1; i < n; i++) {
2205 pixa = pixaaGetPixa(paa, i, L_CLONE);
2206 pixaVerifyDepth(pixa, &samed, &d);
2207 pixaDestroy(&pixa);
2208 maxd = L_MAX(maxd, d);
2209 if (!samed || maxd != d)
2210 same = 0;
2211 }
2212 *psame = same;
2213 if (pmaxd) *pmaxd = maxd;
2214 return 0;
2215 }
2216
2217
2218 /*!
2219 * \brief pixaaVerifyDimensions()
2220 *
2221 * \param[in] paa
2222 * \param[out] psame 1 if all pix have the same depth; 0 otherwise
2223 * \param[out] pmaxw [optional] max width of all pix in pixaa
2224 * \param[out] pmaxh [optional] max height of all pix in pixaa
2225 * \return 0 if OK; 1 on error
2226 *
2227 * <pre>
2228 * Notes:
2229 * (1) It is considered to be an error if any pixa have no pix.
2230 * </pre>
2231 */
2232 l_ok
2233 pixaaVerifyDimensions(PIXAA *paa,
2234 l_int32 *psame,
2235 l_int32 *pmaxw,
2236 l_int32 *pmaxh)
2237 {
2238 l_int32 i, n, w, h, maxw, maxh, same, same2;
2239 PIXA *pixa;
2240
2241 if (pmaxw) *pmaxw = 0;
2242 if (pmaxh) *pmaxh = 0;
2243 if (!psame)
2244 return ERROR_INT("psame not defined", __func__, 1);
2245 *psame = 0;
2246 if (!paa)
2247 return ERROR_INT("paa not defined", __func__, 1);
2248 if ((n = pixaaGetCount(paa, NULL)) == 0)
2249 return ERROR_INT("no pixa in paa", __func__, 1);
2250
2251 /* Init same; init maxw and maxh from first pixa */
2252 pixa = pixaaGetPixa(paa, 0, L_CLONE);
2253 pixaVerifyDimensions(pixa, &same, &maxw, &maxh);
2254 pixaDestroy(&pixa);
2255
2256 for (i = 1; i < n; i++) {
2257 pixa = pixaaGetPixa(paa, i, L_CLONE);
2258 pixaVerifyDimensions(pixa, &same2, &w, &h);
2259 pixaDestroy(&pixa);
2260 maxw = L_MAX(maxw, w);
2261 maxh = L_MAX(maxh, h);
2262 if (!same2 || maxw != w || maxh != h)
2263 same = 0;
2264 }
2265 *psame = same;
2266 if (pmaxw) *pmaxw = maxw;
2267 if (pmaxh) *pmaxh = maxh;
2268 return 0;
2269 }
2270
2271
2272 /*!
2273 * \brief pixaaIsFull()
2274 *
2275 * \param[in] paa
2276 * \param[out] pfull 1 if all pixa in the paa have full pix arrays
2277 * \return return 0 if OK, 1 on error
2278 *
2279 * <pre>
2280 * Notes:
2281 * (1) Does not require boxa associated with each pixa to be full.
2282 * </pre>
2283 */
2284 l_int32
2285 pixaaIsFull(PIXAA *paa,
2286 l_int32 *pfull)
2287 {
2288 l_int32 i, n, full;
2289 PIXA *pixa;
2290
2291 if (!pfull)
2292 return ERROR_INT("&full not defined", __func__, 0);
2293 *pfull = 0;
2294 if (!paa)
2295 return ERROR_INT("paa not defined", __func__, 0);
2296
2297 n = pixaaGetCount(paa, NULL);
2298 full = 1;
2299 for (i = 0; i < n; i++) {
2300 pixa = pixaaGetPixa(paa, i, L_CLONE);
2301 pixaIsFull(pixa, &full, NULL);
2302 pixaDestroy(&pixa);
2303 if (!full) break;
2304 }
2305 *pfull = full;
2306 return 0;
2307 }
2308
2309
2310 /*---------------------------------------------------------------------*
2311 * Pixaa array modifiers *
2312 *---------------------------------------------------------------------*/
2313 /*!
2314 * \brief pixaaInitFull()
2315 *
2316 * \param[in] paa typically empty
2317 * \param[in] pixa to be replicated into the entire pixa ptr array
2318 * \return 0 if OK, 1 on error
2319 *
2320 * <pre>
2321 * Notes:
2322 * (1) This initializes a pixaa by filling up the entire pixa ptr array
2323 * with copies of %pixa. Any existing pixa are destroyed.
2324 * (2) Example usage. This function is useful to prepare for a
2325 * random insertion (or replacement) of pixa into a pixaa.
2326 * To randomly insert pixa into a pixaa, up to some index "max":
2327 * Pixaa *paa = pixaaCreate(max);
2328 * Pixa *pixa = pixaCreate(1); // if you want little memory
2329 * pixaaInitFull(paa, pixa); // copy it to entire array
2330 * pixaDestroy(&pixa); // no longer needed
2331 * The initialization allows the pixaa to always be properly filled.
2332 * </pre>
2333 */
2334 l_ok
2335 pixaaInitFull(PIXAA *paa,
2336 PIXA *pixa)
2337 {
2338 l_int32 i, n;
2339 PIXA *pixat;
2340
2341 if (!paa)
2342 return ERROR_INT("paa not defined", __func__, 1);
2343 if (!pixa)
2344 return ERROR_INT("pixa not defined", __func__, 1);
2345
2346 n = paa->nalloc;
2347 paa->n = n;
2348 for (i = 0; i < n; i++) {
2349 pixat = pixaCopy(pixa, L_COPY);
2350 pixaaReplacePixa(paa, i, pixat);
2351 }
2352
2353 return 0;
2354 }
2355
2356
2357 /*!
2358 * \brief pixaaReplacePixa()
2359 *
2360 * \param[in] paa
2361 * \param[in] index to the index-th pixa
2362 * \param[in] pixa insert to replace existing one
2363 * \return 0 if OK, 1 on error
2364 *
2365 * <pre>
2366 * Notes:
2367 * (1) This allows random insertion of a pixa into a pixaa, with
2368 * destruction of any existing pixa at that location.
2369 * The input pixa is now owned by the pixaa.
2370 * (2) No other pixa in the array are affected.
2371 * (3) The index must be within the allowed set.
2372 * </pre>
2373 */
2374 l_ok
2375 pixaaReplacePixa(PIXAA *paa,
2376 l_int32 index,
2377 PIXA *pixa)
2378 {
2379
2380 if (!paa)
2381 return ERROR_INT("paa not defined", __func__, 1);
2382 if (index < 0 || index >= paa->n)
2383 return ERROR_INT("index not valid", __func__, 1);
2384 if (!pixa)
2385 return ERROR_INT("pixa not defined", __func__, 1);
2386
2387 pixaDestroy(&(paa->pixa[index]));
2388 paa->pixa[index] = pixa;
2389 return 0;
2390 }
2391
2392
2393 /*!
2394 * \brief pixaaClear()
2395 *
2396 * \param[in] paa
2397 * \return 0 if OK, 1 on error
2398 *
2399 * <pre>
2400 * Notes:
2401 * (1) This destroys all pixa in the pixaa, and nulls the ptrs
2402 * in the pixa ptr array.
2403 * </pre>
2404 */
2405 l_ok
2406 pixaaClear(PIXAA *paa)
2407 {
2408 l_int32 i, n;
2409
2410 if (!paa)
2411 return ERROR_INT("paa not defined", __func__, 1);
2412
2413 n = pixaaGetCount(paa, NULL);
2414 for (i = 0; i < n; i++)
2415 pixaDestroy(&paa->pixa[i]);
2416 paa->n = 0;
2417 return 0;
2418 }
2419
2420
2421 /*!
2422 * \brief pixaaTruncate()
2423 *
2424 * \param[in] paa
2425 * \return 0 if OK, 1 on error
2426 *
2427 * <pre>
2428 * Notes:
2429 * (1) This identifies the largest index containing a pixa that
2430 * has any pix within it, destroys all pixa above that index,
2431 * and resets the count.
2432 * </pre>
2433 */
2434 l_ok
2435 pixaaTruncate(PIXAA *paa)
2436 {
2437 l_int32 i, n, np;
2438 PIXA *pixa;
2439
2440 if (!paa)
2441 return ERROR_INT("paa not defined", __func__, 1);
2442
2443 n = pixaaGetCount(paa, NULL);
2444 for (i = n - 1; i >= 0; i--) {
2445 pixa = pixaaGetPixa(paa, i, L_CLONE);
2446 if (!pixa) {
2447 paa->n--;
2448 continue;
2449 }
2450 np = pixaGetCount(pixa);
2451 pixaDestroy(&pixa);
2452 if (np == 0) {
2453 pixaDestroy(&paa->pixa[i]);
2454 paa->n--;
2455 } else {
2456 break;
2457 }
2458 }
2459 return 0;
2460 }
2461
2462
2463
2464 /*---------------------------------------------------------------------*
2465 * Pixa serialized I/O *
2466 *---------------------------------------------------------------------*/
2467 /*!
2468 * \brief pixaRead()
2469 *
2470 * \param[in] filename
2471 * \return pixa, or NULL on error
2472 *
2473 * <pre>
2474 * Notes:
2475 * (1) The pix are stored in the file as png.
2476 * If the png library is not linked, this will fail.
2477 * </pre>
2478 */
2479 PIXA *
2480 pixaRead(const char *filename)
2481 {
2482 FILE *fp;
2483 PIXA *pixa;
2484
2485 #if !HAVE_LIBPNG /* defined in environ.h and config_auto.h */
2486 return (PIXA *)ERROR_PTR("no libpng: can't read data", __func__, NULL);
2487 #endif /* !HAVE_LIBPNG */
2488
2489 if (!filename)
2490 return (PIXA *)ERROR_PTR("filename not defined", __func__, NULL);
2491
2492 if ((fp = fopenReadStream(filename)) == NULL)
2493 return (PIXA *)ERROR_PTR_1("stream not opened",
2494 filename, __func__, NULL);
2495 pixa = pixaReadStream(fp);
2496 fclose(fp);
2497 if (!pixa)
2498 return (PIXA *)ERROR_PTR_1("pixa not read",
2499 filename, __func__, NULL);
2500 return pixa;
2501 }
2502
2503
2504 /*!
2505 * \brief pixaReadStream()
2506 *
2507 * \param[in] fp file stream
2508 * \return pixa, or NULL on error
2509 *
2510 * <pre>
2511 * Notes:
2512 * (1) The pix are stored in the file as png.
2513 * If the png library is not linked, this will fail.
2514 * (2) It is OK for the pixa to be empty.
2515 * </pre>
2516 */
2517 PIXA *
2518 pixaReadStream(FILE *fp)
2519 {
2520 l_int32 n, i, xres, yres, version;
2521 l_int32 ignore;
2522 BOXA *boxa;
2523 PIX *pix;
2524 PIXA *pixa;
2525
2526 #if !HAVE_LIBPNG /* defined in environ.h and config_auto.h */
2527 return (PIXA *)ERROR_PTR("no libpng: can't read data", __func__, NULL);
2528 #endif /* !HAVE_LIBPNG */
2529
2530 if (!fp)
2531 return (PIXA *)ERROR_PTR("stream not defined", __func__, NULL);
2532
2533 if (fscanf(fp, "\nPixa Version %d\n", &version) != 1)
2534 return (PIXA *)ERROR_PTR("not a pixa file", __func__, NULL);
2535 if (version != PIXA_VERSION_NUMBER)
2536 return (PIXA *)ERROR_PTR("invalid pixa version", __func__, NULL);
2537 if (fscanf(fp, "Number of pix = %d\n", &n) != 1)
2538 return (PIXA *)ERROR_PTR("not a pixa file", __func__, NULL);
2539 if (n < 0)
2540 return (PIXA *)ERROR_PTR("num pix ptrs < 0", __func__, NULL);
2541 if (n > MaxPixaPtrArraySize)
2542 return (PIXA *)ERROR_PTR("too many pix ptrs", __func__, NULL);
2543 if (n == 0) L_INFO("the pixa is empty\n", __func__);
2544
2545 if ((boxa = boxaReadStream(fp)) == NULL)
2546 return (PIXA *)ERROR_PTR("boxa not made", __func__, NULL);
2547 if ((pixa = pixaCreate(n)) == NULL) {
2548 boxaDestroy(&boxa);
2549 return (PIXA *)ERROR_PTR("pixa not made", __func__, NULL);
2550 }
2551 boxaDestroy(&pixa->boxa);
2552 pixa->boxa = boxa;
2553
2554 for (i = 0; i < n; i++) {
2555 if ((fscanf(fp, " pix[%d]: xres = %d, yres = %d\n",
2556 &ignore, &xres, &yres)) != 3) {
2557 pixaDestroy(&pixa);
2558 return (PIXA *)ERROR_PTR("res reading error", __func__, NULL);
2559 }
2560 if ((pix = pixReadStreamPng(fp)) == NULL) {
2561 pixaDestroy(&pixa);
2562 return (PIXA *)ERROR_PTR("pix not read", __func__, NULL);
2563 }
2564 pixSetXRes(pix, xres);
2565 pixSetYRes(pix, yres);
2566 pixaAddPix(pixa, pix, L_INSERT);
2567 }
2568 return pixa;
2569 }
2570
2571
2572 /*!
2573 * \brief pixaReadMem()
2574 *
2575 * \param[in] data of serialized pixa
2576 * \param[in] size of data in bytes
2577 * \return pixa, or NULL on error
2578 */
2579 PIXA *
2580 pixaReadMem(const l_uint8 *data,
2581 size_t size)
2582 {
2583 FILE *fp;
2584 PIXA *pixa;
2585
2586 if (!data)
2587 return (PIXA *)ERROR_PTR("data not defined", __func__, NULL);
2588 if ((fp = fopenReadFromMemory(data, size)) == NULL)
2589 return (PIXA *)ERROR_PTR("stream not opened", __func__, NULL);
2590
2591 pixa = pixaReadStream(fp);
2592 fclose(fp);
2593 if (!pixa) L_ERROR("pixa not read\n", __func__);
2594 return pixa;
2595 }
2596
2597
2598 /*!
2599 * \brief pixaWriteDebug()
2600 *
2601 * \param[in] fname
2602 * \param[in] pixa
2603 * \return 0 if OK; 1 on error
2604 *
2605 * <pre>
2606 * Notes:
2607 * (1) Debug version, intended for use in the library when writing
2608 * to files in a temp directory with names that are compiled in.
2609 * This is used instead of pixaWrite() for all such library calls.
2610 * (2) The global variable LeptDebugOK defaults to 0, and can be set
2611 * or cleared by the function setLeptDebugOK().
2612 * </pre>
2613 */
2614 l_ok
2615 pixaWriteDebug(const char *fname,
2616 PIXA *pixa)
2617 {
2618 if (LeptDebugOK) {
2619 return pixaWrite(fname, pixa);
2620 } else {
2621 L_INFO("write to named temp file %s is disabled\n", __func__, fname);
2622 return 0;
2623 }
2624 }
2625
2626
2627 /*!
2628 * \brief pixaWrite()
2629 *
2630 * \param[in] filename
2631 * \param[in] pixa
2632 * \return 0 if OK, 1 on error
2633 *
2634 * <pre>
2635 * Notes:
2636 * (1) The pix are stored in the file as png.
2637 * If the png library is not linked, this will fail.
2638 * </pre>
2639 */
2640 l_ok
2641 pixaWrite(const char *filename,
2642 PIXA *pixa)
2643 {
2644 l_int32 ret;
2645 FILE *fp;
2646
2647 #if !HAVE_LIBPNG /* defined in environ.h and config_auto.h */
2648 return ERROR_INT("no libpng: can't write data", __func__, 1);
2649 #endif /* !HAVE_LIBPNG */
2650
2651 if (!filename)
2652 return ERROR_INT("filename not defined", __func__, 1);
2653 if (!pixa)
2654 return ERROR_INT("pixa not defined", __func__, 1);
2655
2656 if ((fp = fopenWriteStream(filename, "wb")) == NULL)
2657 return ERROR_INT_1("stream not opened", filename, __func__, 1);
2658 ret = pixaWriteStream(fp, pixa);
2659 fclose(fp);
2660 if (ret)
2661 return ERROR_INT_1("pixa not written to stream", filename, __func__, 1);
2662 return 0;
2663 }
2664
2665
2666 /*!
2667 * \brief pixaWriteStream()
2668 *
2669 * \param[in] fp file stream opened for "wb"
2670 * \param[in] pixa
2671 * \return 0 if OK, 1 on error
2672 *
2673 * <pre>
2674 * Notes:
2675 * (1) The pix are stored in the file as png.
2676 * If the png library is not linked, this will fail.
2677 * </pre>
2678 */
2679 l_ok
2680 pixaWriteStream(FILE *fp,
2681 PIXA *pixa)
2682 {
2683 l_int32 n, i;
2684 PIX *pix;
2685
2686 #if !HAVE_LIBPNG /* defined in environ.h and config_auto.h */
2687 return ERROR_INT("no libpng: can't write data", __func__, 1);
2688 #endif /* !HAVE_LIBPNG */
2689
2690 if (!fp)
2691 return ERROR_INT("stream not defined", __func__, 1);
2692 if (!pixa)
2693 return ERROR_INT("pixa not defined", __func__, 1);
2694
2695 n = pixaGetCount(pixa);
2696 fprintf(fp, "\nPixa Version %d\n", PIXA_VERSION_NUMBER);
2697 fprintf(fp, "Number of pix = %d\n", n);
2698 boxaWriteStream(fp, pixa->boxa);
2699 for (i = 0; i < n; i++) {
2700 if ((pix = pixaGetPix(pixa, i, L_CLONE)) == NULL)
2701 return ERROR_INT("pix not found", __func__, 1);
2702 fprintf(fp, " pix[%d]: xres = %d, yres = %d\n",
2703 i, pix->xres, pix->yres);
2704 pixWriteStreamPng(fp, pix, 0.0);
2705 pixDestroy(&pix);
2706 }
2707 return 0;
2708 }
2709
2710
2711 /*!
2712 * \brief pixaWriteMem()
2713 *
2714 * \param[out] pdata data of serialized pixa
2715 * \param[out] psize size of returned data
2716 * \param[in] pixa
2717 * \return 0 if OK, 1 on error
2718 *
2719 * <pre>
2720 * Notes:
2721 * (1) Serializes a pixa in memory and puts the result in a buffer.
2722 * </pre>
2723 */
2724 l_ok
2725 pixaWriteMem(l_uint8 **pdata,
2726 size_t *psize,
2727 PIXA *pixa)
2728 {
2729 l_int32 ret;
2730 FILE *fp;
2731
2732 if (pdata) *pdata = NULL;
2733 if (psize) *psize = 0;
2734 if (!pdata)
2735 return ERROR_INT("&data not defined", __func__, 1);
2736 if (!psize)
2737 return ERROR_INT("&size not defined", __func__, 1);
2738 if (!pixa)
2739 return ERROR_INT("pixa not defined", __func__, 1);
2740
2741 #if HAVE_FMEMOPEN
2742 if ((fp = open_memstream((char **)pdata, psize)) == NULL)
2743 return ERROR_INT("stream not opened", __func__, 1);
2744 ret = pixaWriteStream(fp, pixa);
2745 fputc('\0', fp);
2746 fclose(fp);
2747 if (*psize > 0) *psize = *psize - 1;
2748 #else
2749 L_INFO("no fmemopen API --> work-around: write to temp file\n", __func__);
2750 #ifdef _WIN32
2751 if ((fp = fopenWriteWinTempfile()) == NULL)
2752 return ERROR_INT("tmpfile stream not opened", __func__, 1);
2753 #else
2754 if ((fp = tmpfile()) == NULL)
2755 return ERROR_INT("tmpfile stream not opened", __func__, 1);
2756 #endif /* _WIN32 */
2757 ret = pixaWriteStream(fp, pixa);
2758 rewind(fp);
2759 *pdata = l_binaryReadStream(fp, psize);
2760 fclose(fp);
2761 #endif /* HAVE_FMEMOPEN */
2762 return ret;
2763 }
2764
2765
2766 /*!
2767 * \brief pixaReadBoth()
2768 *
2769 * \param[in] filename
2770 * \return pixa, or NULL on error
2771 *
2772 * <pre>
2773 * Notes:
2774 * (1) This reads serialized files of either a pixa or a pixacomp,
2775 * and returns a pixa in memory. It requires png and jpeg libraries.
2776 * </pre>
2777 */
2778 PIXA *
2779 pixaReadBoth(const char *filename)
2780 {
2781 char buf[32];
2782 char *sname;
2783 PIXA *pixa;
2784 PIXAC *pac;
2785
2786 if (!filename)
2787 return (PIXA *)ERROR_PTR("filename not defined", __func__, NULL);
2788
2789 l_getStructStrFromFile(filename, L_STR_NAME, &sname);
2790 if (!sname)
2791 return (PIXA *)ERROR_PTR("struct name not found", __func__, NULL);
2792 snprintf(buf, sizeof(buf), "%s", sname);
2793 LEPT_FREE(sname);
2794
2795 if (strcmp(buf, "Pixacomp") == 0) {
2796 if ((pac = pixacompRead(filename)) == NULL)
2797 return (PIXA *)ERROR_PTR("pac not made", __func__, NULL);
2798 pixa = pixaCreateFromPixacomp(pac, L_COPY);
2799 pixacompDestroy(&pac);
2800 } else if (strcmp(buf, "Pixa") == 0) {
2801 if ((pixa = pixaRead(filename)) == NULL)
2802 return (PIXA *)ERROR_PTR("pixa not made", __func__, NULL);
2803 } else {
2804 return (PIXA *)ERROR_PTR("invalid file type", __func__, NULL);
2805 }
2806 return pixa;
2807 }
2808
2809
2810 /*---------------------------------------------------------------------*
2811 * Pixaa serialized I/O *
2812 *---------------------------------------------------------------------*/
2813 /*!
2814 * \brief pixaaReadFromFiles()
2815 *
2816 * \param[in] dirname directory
2817 * \param[in] substr [optional] substring filter on filenames; can be NULL
2818 * \param[in] first 0-based
2819 * \param[in] nfiles use 0 for everything from %first to the end
2820 * \return paa, or NULL on error or if no pixa files are found.
2821 *
2822 * <pre>
2823 * Notes:
2824 * (1) The files must be serialized pixa files (e.g., *.pa)
2825 * If some files cannot be read, warnings are issued.
2826 * (2) Use %substr to filter filenames in the directory. If
2827 * %substr == NULL, this takes all files.
2828 * (3) After filtering, use %first and %nfiles to select
2829 * a contiguous set of files, that have been lexically
2830 * sorted in increasing order.
2831 * </pre>
2832 */
2833 PIXAA *
2834 pixaaReadFromFiles(const char *dirname,
2835 const char *substr,
2836 l_int32 first,
2837 l_int32 nfiles)
2838 {
2839 char *fname;
2840 l_int32 i, n;
2841 PIXA *pixa;
2842 PIXAA *paa;
2843 SARRAY *sa;
2844
2845 if (!dirname)
2846 return (PIXAA *)ERROR_PTR("dirname not defined", __func__, NULL);
2847
2848 sa = getSortedPathnamesInDirectory(dirname, substr, first, nfiles);
2849 if (!sa || ((n = sarrayGetCount(sa)) == 0)) {
2850 sarrayDestroy(&sa);
2851 return (PIXAA *)ERROR_PTR("no pixa files found", __func__, NULL);
2852 }
2853
2854 paa = pixaaCreate(n);
2855 for (i = 0; i < n; i++) {
2856 fname = sarrayGetString(sa, i, L_NOCOPY);
2857 if ((pixa = pixaRead(fname)) == NULL) {
2858 L_ERROR("pixa not read for %d-th file", __func__, i);
2859 continue;
2860 }
2861 pixaaAddPixa(paa, pixa, L_INSERT);
2862 }
2863
2864 sarrayDestroy(&sa);
2865 return paa;
2866 }
2867
2868
2869 /*!
2870 * \brief pixaaRead()
2871 *
2872 * \param[in] filename
2873 * \return paa, or NULL on error
2874 *
2875 * <pre>
2876 * Notes:
2877 * (1) The pix are stored in the file as png.
2878 * If the png library is not linked, this will fail.
2879 * </pre>
2880 */
2881 PIXAA *
2882 pixaaRead(const char *filename)
2883 {
2884 FILE *fp;
2885 PIXAA *paa;
2886
2887 #if !HAVE_LIBPNG /* defined in environ.h and config_auto.h */
2888 return (PIXAA *)ERROR_PTR("no libpng: can't read data", __func__, NULL);
2889 #endif /* !HAVE_LIBPNG */
2890
2891 if (!filename)
2892 return (PIXAA *)ERROR_PTR("filename not defined", __func__, NULL);
2893
2894 if ((fp = fopenReadStream(filename)) == NULL)
2895 return (PIXAA *)ERROR_PTR_1("stream not opened",
2896 filename, __func__, NULL);
2897 paa = pixaaReadStream(fp);
2898 fclose(fp);
2899 if (!paa)
2900 return (PIXAA *)ERROR_PTR_1("paa not read", filename, __func__, NULL);
2901 return paa;
2902 }
2903
2904
2905 /*!
2906 * \brief pixaaReadStream()
2907 *
2908 * \param[in] fp file stream
2909 * \return paa, or NULL on error
2910 *
2911 * <pre>
2912 * Notes:
2913 * (1) The pix are stored in the file as png.
2914 * If the png library is not linked, this will fail.
2915 * (2) It is OK for the pixaa to be empty.
2916 * </pre>
2917 */
2918 PIXAA *
2919 pixaaReadStream(FILE *fp)
2920 {
2921 l_int32 n, i, version;
2922 l_int32 ignore;
2923 BOXA *boxa;
2924 PIXA *pixa;
2925 PIXAA *paa;
2926
2927 #if !HAVE_LIBPNG /* defined in environ.h and config_auto.h */
2928 return (PIXAA *)ERROR_PTR("no libpng: can't read data", __func__, NULL);
2929 #endif /* !HAVE_LIBPNG */
2930
2931 if (!fp)
2932 return (PIXAA *)ERROR_PTR("stream not defined", __func__, NULL);
2933
2934 if (fscanf(fp, "\nPixaa Version %d\n", &version) != 1)
2935 return (PIXAA *)ERROR_PTR("not a pixaa file", __func__, NULL);
2936 if (version != PIXAA_VERSION_NUMBER)
2937 return (PIXAA *)ERROR_PTR("invalid pixaa version", __func__, NULL);
2938 if (fscanf(fp, "Number of pixa = %d\n", &n) != 1)
2939 return (PIXAA *)ERROR_PTR("not a pixaa file", __func__, NULL);
2940 if (n < 0)
2941 return (PIXAA *)ERROR_PTR("num pixa ptrs < 0", __func__, NULL);
2942 if (n > MaxPixaaPtrArraySize)
2943 return (PIXAA *)ERROR_PTR("too many pixa ptrs", __func__, NULL);
2944 if (n == 0) L_INFO("the pixaa is empty\n", __func__);
2945
2946 if ((paa = pixaaCreate(n)) == NULL)
2947 return (PIXAA *)ERROR_PTR("paa not made", __func__, NULL);
2948 if ((boxa = boxaReadStream(fp)) == NULL) {
2949 pixaaDestroy(&paa);
2950 return (PIXAA *)ERROR_PTR("boxa not made", __func__, NULL);
2951 }
2952 boxaDestroy(&paa->boxa);
2953 paa->boxa = boxa;
2954
2955 for (i = 0; i < n; i++) {
2956 if ((fscanf(fp, "\n\n --------------- pixa[%d] ---------------\n",
2957 &ignore)) != 1) {
2958 pixaaDestroy(&paa);
2959 return (PIXAA *)ERROR_PTR("text reading", __func__, NULL);
2960 }
2961 if ((pixa = pixaReadStream(fp)) == NULL) {
2962 pixaaDestroy(&paa);
2963 return (PIXAA *)ERROR_PTR("pixa not read", __func__, NULL);
2964 }
2965 pixaaAddPixa(paa, pixa, L_INSERT);
2966 }
2967
2968 return paa;
2969 }
2970
2971
2972 /*!
2973 * \brief pixaaReadMem()
2974 *
2975 * \param[in] data of serialized pixaa
2976 * \param[in] size of data in bytes
2977 * \return paa, or NULL on error
2978 */
2979 PIXAA *
2980 pixaaReadMem(const l_uint8 *data,
2981 size_t size)
2982 {
2983 FILE *fp;
2984 PIXAA *paa;
2985
2986 if (!data)
2987 return (PIXAA *)ERROR_PTR("data not defined", __func__, NULL);
2988 if ((fp = fopenReadFromMemory(data, size)) == NULL)
2989 return (PIXAA *)ERROR_PTR("stream not opened", __func__, NULL);
2990
2991 paa = pixaaReadStream(fp);
2992 fclose(fp);
2993 if (!paa) L_ERROR("paa not read\n", __func__);
2994 return paa;
2995 }
2996
2997
2998 /*!
2999 * \brief pixaaWrite()
3000 *
3001 * \param[in] filename
3002 * \param[in] paa
3003 * \return 0 if OK, 1 on error
3004 *
3005 * <pre>
3006 * Notes:
3007 * (1) The pix are stored in the file as png.
3008 * If the png library is not linked, this will fail.
3009 * </pre>
3010 */
3011 l_ok
3012 pixaaWrite(const char *filename,
3013 PIXAA *paa)
3014 {
3015 l_int32 ret;
3016 FILE *fp;
3017
3018 #if !HAVE_LIBPNG /* defined in environ.h and config_auto.h */
3019 return ERROR_INT("no libpng: can't read data", __func__, 1);
3020 #endif /* !HAVE_LIBPNG */
3021
3022 if (!filename)
3023 return ERROR_INT("filename not defined", __func__, 1);
3024 if (!paa)
3025 return ERROR_INT("paa not defined", __func__, 1);
3026
3027 if ((fp = fopenWriteStream(filename, "wb")) == NULL)
3028 return ERROR_INT_1("stream not opened", filename, __func__, 1);
3029 ret = pixaaWriteStream(fp, paa);
3030 fclose(fp);
3031 if (ret)
3032 return ERROR_INT_1("paa not written to stream", filename, __func__, 1);
3033 return 0;
3034 }
3035
3036
3037 /*!
3038 * \brief pixaaWriteStream()
3039 *
3040 * \param[in] fp file stream opened for "wb"
3041 * \param[in] paa
3042 * \return 0 if OK, 1 on error
3043 *
3044 * <pre>
3045 * Notes:
3046 * (1) The pix are stored in the file as png.
3047 * If the png library is not linked, this will fail.
3048 * </pre>
3049 */
3050 l_ok
3051 pixaaWriteStream(FILE *fp,
3052 PIXAA *paa)
3053 {
3054 l_int32 n, i;
3055 PIXA *pixa;
3056
3057 #if !HAVE_LIBPNG /* defined in environ.h and config_auto.h */
3058 return ERROR_INT("no libpng: can't read data", __func__, 1);
3059 #endif /* !HAVE_LIBPNG */
3060
3061 if (!fp)
3062 return ERROR_INT("stream not defined", __func__, 1);
3063 if (!paa)
3064 return ERROR_INT("paa not defined", __func__, 1);
3065
3066 n = pixaaGetCount(paa, NULL);
3067 fprintf(fp, "\nPixaa Version %d\n", PIXAA_VERSION_NUMBER);
3068 fprintf(fp, "Number of pixa = %d\n", n);
3069 boxaWriteStream(fp, paa->boxa);
3070 for (i = 0; i < n; i++) {
3071 if ((pixa = pixaaGetPixa(paa, i, L_CLONE)) == NULL)
3072 return ERROR_INT("pixa not found", __func__, 1);
3073 fprintf(fp, "\n\n --------------- pixa[%d] ---------------\n", i);
3074 pixaWriteStream(fp, pixa);
3075 pixaDestroy(&pixa);
3076 }
3077 return 0;
3078 }
3079
3080
3081 /*!
3082 * \brief pixaaWriteMem()
3083 *
3084 * \param[out] pdata data of serialized pixaa
3085 * \param[out] psize size of returned data
3086 * \param[in] paa
3087 * \return 0 if OK, 1 on error
3088 *
3089 * <pre>
3090 * Notes:
3091 * (1) Serializes a pixaa in memory and puts the result in a buffer.
3092 * </pre>
3093 */
3094 l_ok
3095 pixaaWriteMem(l_uint8 **pdata,
3096 size_t *psize,
3097 PIXAA *paa)
3098 {
3099 l_int32 ret;
3100 FILE *fp;
3101
3102 if (pdata) *pdata = NULL;
3103 if (psize) *psize = 0;
3104 if (!pdata)
3105 return ERROR_INT("&data not defined", __func__, 1);
3106 if (!psize)
3107 return ERROR_INT("&size not defined", __func__, 1);
3108 if (!paa)
3109 return ERROR_INT("paa not defined", __func__, 1);
3110
3111 #if HAVE_FMEMOPEN
3112 if ((fp = open_memstream((char **)pdata, psize)) == NULL)
3113 return ERROR_INT("stream not opened", __func__, 1);
3114 ret = pixaaWriteStream(fp, paa);
3115 fputc('\0', fp);
3116 fclose(fp);
3117 if (*psize > 0) *psize = *psize - 1;
3118 #else
3119 L_INFO("no fmemopen API --> work-around: write to temp file\n", __func__);
3120 #ifdef _WIN32
3121 if ((fp = fopenWriteWinTempfile()) == NULL)
3122 return ERROR_INT("tmpfile stream not opened", __func__, 1);
3123 #else
3124 if ((fp = tmpfile()) == NULL)
3125 return ERROR_INT("tmpfile stream not opened", __func__, 1);
3126 #endif /* _WIN32 */
3127 ret = pixaaWriteStream(fp, paa);
3128 rewind(fp);
3129 *pdata = l_binaryReadStream(fp, psize);
3130 fclose(fp);
3131 #endif /* HAVE_FMEMOPEN */
3132 return ret;
3133 }
3134