comparison mupdf-source/thirdparty/leptonica/src/pix1.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 pix1.c
29 * <pre>
30 *
31 * The pixN.c {N = 1,2,3,4,5} files are sorted by the type of operation.
32 * The primary functions in these files are:
33 *
34 * pix1.c: constructors, destructors and field accessors
35 * pix2.c: pixel poking of image, pad and border pixels
36 * pix3.c: masking and logical ops, counting, mirrored tiling
37 * pix4.c: histograms, statistics, fg/bg estimation
38 * pix5.c: property measurements, rectangle extraction
39 *
40 *
41 * This file has the basic constructors, destructors and field accessors
42 *
43 * Pix memory management (allows custom allocator and deallocator)
44 * static void *pixdata_malloc()
45 * static void pixdata_free()
46 * void setPixMemoryManager()
47 *
48 * Pix creation
49 * PIX *pixCreate()
50 * PIX *pixCreateNoInit()
51 * PIX *pixCreateTemplate()
52 * PIX *pixCreateTemplateNoInit()
53 * PIX *pixCreateWithCmap()
54 * PIX *pixCreateHeader()
55 * PIX *pixClone()
56 *
57 * Pix destruction
58 * void pixDestroy()
59 * static void pixFree()
60 *
61 * Pix copy
62 * PIX *pixCopy()
63 * l_int32 pixResizeImageData()
64 * l_int32 pixCopyColormap()
65 * l_int32 pixTransferAllData()
66 * l_int32 pixSwapAndDestroy()
67 *
68 * Pix accessors
69 * l_int32 pixGetWidth()
70 * l_int32 pixSetWidth()
71 * l_int32 pixGetHeight()
72 * l_int32 pixSetHeight()
73 * l_int32 pixGetDepth()
74 * l_int32 pixSetDepth()
75 * l_int32 pixGetDimensions()
76 * l_int32 pixSetDimensions()
77 * l_int32 pixCopyDimensions()
78 * l_int32 pixGetSpp()
79 * l_int32 pixSetSpp()
80 * l_int32 pixCopySpp()
81 * l_int32 pixGetWpl()
82 * l_int32 pixSetWpl()
83 * l_uint32 pixGetXRes()
84 * l_int32 pixSetXRes()
85 * l_uint32 pixGetYRes()
86 * l_int32 pixSetYRes()
87 * l_int32 pixGetResolution()
88 * l_int32 pixSetResolution()
89 * l_int32 pixCopyResolution()
90 * l_int32 pixScaleResolution()
91 * l_int32 pixGetInputFormat()
92 * l_int32 pixSetInputFormat()
93 * l_int32 pixCopyInputFormat()
94 * l_int32 pixSetSpecial()
95 * char *pixGetText()
96 * l_int32 pixSetText()
97 * l_int32 pixAddText()
98 * l_int32 pixCopyText()
99 * l_uint8 *pixGetTextCompNew()
100 * l_int32 *pixSetTextCompNew()
101 * PIXCMAP *pixGetColormap()
102 * l_int32 pixSetColormap()
103 * l_int32 pixDestroyColormap()
104 * l_uint32 *pixGetData()
105 * l_int32 pixFreeAndSetData()
106 * l_int32 pixSetData()
107 * l_int32 pixFreeData()
108 * l_uint32 *pixExtractData()
109 *
110 * Pix line ptrs
111 * void **pixGetLinePtrs()
112 *
113 * Pix size comparisons
114 * l_int32 pixSizesEqual()
115 * l_int32 pixMaxAspectRatio()
116 *
117 * Pix debug
118 * l_int32 pixPrintStreamInfo()
119 *
120 *
121 * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
122 * Important notes on direct management of pix image data
123 * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
124 *
125 * Custom allocator and deallocator
126 * --------------------------------
127 *
128 * At the lowest level, you can specify the function that does the
129 * allocation and deallocation of the data field in the pix.
130 * By default, this is malloc and free. However, by calling
131 * setPixMemoryManager(), custom functions can be substituted.
132 * When using this, keep two things in mind:
133 *
134 * (1) Call setPixMemoryManager() before any pix have been allocated
135 * (2) Destroy all pix as usual, in order to prevent leaks.
136 *
137 * In pixalloc.c, we provide an example custom allocator and deallocator.
138 * To use it, you must call pmsCreate() before any pix have been allocated
139 * and pmsDestroy() at the end after all pix have been destroyed.
140 *
141 *
142 * Direct manipulation of the pix data field
143 * -----------------------------------------
144 *
145 * Memory management of the (image) data field in the pix is
146 * handled differently from that in the colormap and text fields.
147 * For colormap and text, the functions pixSetColormap() and
148 * pixSetText() remove the existing heap data and insert the
149 * new data. For the image data, pixSetData() just reassigns the
150 * data field; any existing data will be lost if there isn't
151 * another handle for it.
152 *
153 * Why is pixSetData() limited in this way? Because the image
154 * data can be very large, we need flexible ways to handle it,
155 * particularly when you want to re-use the data in a different
156 * context without making a copy. Here are some different
157 * things you might want to do:
158 *
159 * (1) Use pixCopy(pixd, pixs) where pixd is not the same size
160 * as pixs. This will remove the data in pixd, allocate a
161 * new data field in pixd, and copy the data from pixs, leaving
162 * pixs unchanged.
163 *
164 * (2) Use pixTransferAllData(pixd, &pixs, ...) to transfer the
165 * data from pixs to pixd without making a copy of it. If
166 * pixs is not cloned, this will do the transfer and destroy pixs.
167 * But if the refcount of pixs is greater than 1, it just copies
168 * the data and decrements the ref count.
169 *
170 * (3) Use pixSwapAndDestroy(pixd, &pixs) to replace pixs by an
171 * existing pixd. This is similar to pixTransferAllData(), but
172 * simpler, in that it never makes any copies and if pixs is
173 * cloned, the other references are not changed by this operation.
174 *
175 * (4) Use pixExtractData() to extract the image data from the pix
176 * without copying if possible. This could be used, for example,
177 * to convert from a pix to some other data structure with minimal
178 * heap allocation. After the data is extracated, the pixels can
179 * be munged and used in another context. However, the danger
180 * here is that the pix might have a refcount > 1, in which case
181 * a copy of the data must be made and the input pix left unchanged.
182 * If there are no clones, the image data can be extracted without
183 * a copy, and the data ptr in the pix must be nulled before
184 * destroying it because the pix will no longer 'own' the data.
185 *
186 * We have provided accessors and functions here that should be
187 * sufficient so that you can do anything you want without
188 * explicitly referencing any of the pix member fields.
189 *
190 * However, to avoid memory smashes and leaks when doing special operations
191 * on the pix data field, look carefully at the behavior of the image
192 * data accessors and keep in mind that when you invoke pixDestroy(),
193 * the pix considers itself the owner of all its heap data.
194 * </pre>
195 */
196
197 #ifdef HAVE_CONFIG_H
198 #include <config_auto.h>
199 #endif /* HAVE_CONFIG_H */
200
201 #include <string.h>
202 #include "allheaders.h"
203 #include "pix_internal.h"
204
205 static void pixFree(PIX *pix);
206
207 /*-------------------------------------------------------------------------*
208 * Pix Memory Management *
209 * *
210 * These functions give you the freedom to specify at compile or run *
211 * time the allocator and deallocator to be used for the pix raster *
212 * image data. They have no effect on any other heap allocation, *
213 * including the pix struct itself, which is controlled by the *
214 * #defines in environ.h. *
215 * *
216 * The default functions for allocating pix raster data are malloc and *
217 * free (or leptonica_* custom allocators if LEPTONICA_INTERCEPT_ALLOC *
218 * is defined). Use setPixMemoryManager() to specify other functions *
219 * to use specifically for pix raster image data. *
220 *-------------------------------------------------------------------------*/
221 /*! Pix memory manager */
222 /*
223 * <pre>
224 * Notes:
225 * (1) The allocator and deallocator function types,
226 * alloc_fn and dealloc_fn, are defined in pix.h.
227 * </pre>
228 */
229 struct PixMemoryManager
230 {
231 alloc_fn allocator;
232 dealloc_fn deallocator;
233 };
234
235 /*! Default Pix memory manager */
236 static struct PixMemoryManager pix_mem_manager = {
237 #ifdef LEPTONICA_INTERCEPT_ALLOC
238 &leptonica_malloc,
239 &leptonica_free
240 #else
241 &malloc,
242 &free
243 #endif /* LEPTONICA_INTERCEPT_ALLOC */
244 };
245
246 static void *
247 pixdata_malloc(size_t size)
248 {
249 #ifndef _MSC_VER
250 return (*pix_mem_manager.allocator)(size);
251 #else /* _MSC_VER */
252 /* Under MSVC++, pix_mem_manager is initialized after a call to
253 * pixdata_malloc. Just ignore the custom allocator feature. */
254 return LEPT_MALLOC(size);
255 #endif /* _MSC_VER */
256 }
257
258 static void
259 pixdata_free(void *ptr)
260 {
261 #ifndef _MSC_VER
262 (*pix_mem_manager.deallocator)(ptr);
263 #else /* _MSC_VER */
264 /* Under MSVC++, pix_mem_manager is initialized after a call to
265 * pixdata_malloc. Just ignore the custom allocator feature. */
266 LEPT_FREE(ptr);
267 #endif /* _MSC_VER */
268 }
269
270 /*!
271 * \brief setPixMemoryManager()
272 *
273 * \param[in] allocator [optional] use NULL to skip
274 * \param[in] deallocator [optional] use NULL to skip
275 * \return void
276 *
277 * <pre>
278 * Notes:
279 * (1) Use this to change the alloc and/or dealloc functions;
280 * e.g., setPixMemoryManager(my_malloc, my_free).
281 * (2) The C99 standard (section 6.7.5.3, par. 8) says:
282 * A declaration of a parameter as "function returning type"
283 * shall be adjusted to "pointer to function returning type"
284 * so that it can be in either of these two forms:
285 * (a) type (function-ptr(type, ...))
286 * (b) type ((*function-ptr)(type, ...))
287 * because form (a) is implicitly converted to form (b), as in the
288 * definition of struct PixMemoryManager above. So, for example,
289 * we should be able to declare either of these:
290 * (a) void *(allocator(size_t))
291 * (b) void *((*allocator)(size_t))
292 * However, MSVC++ only accepts the second version.
293 * </pre>
294 */
295 void
296 setPixMemoryManager(alloc_fn allocator,
297 dealloc_fn deallocator)
298 {
299 if (allocator) pix_mem_manager.allocator = allocator;
300 if (deallocator) pix_mem_manager.deallocator = deallocator;
301 }
302
303
304 /*--------------------------------------------------------------------*
305 * Pix Creation *
306 *--------------------------------------------------------------------*/
307 /*!
308 * \brief pixCreate()
309 *
310 * \param[in] width, height, depth
311 * \return pixd with data allocated and initialized to 0,
312 * or NULL on error
313 */
314 PIX *
315 pixCreate(l_int32 width,
316 l_int32 height,
317 l_int32 depth)
318 {
319 PIX *pixd;
320
321 if ((pixd = pixCreateNoInit(width, height, depth)) == NULL)
322 return (PIX *)ERROR_PTR("pixd not made", __func__, NULL);
323 memset(pixd->data, 0, 4LL * pixd->wpl * pixd->h);
324 return pixd;
325 }
326
327
328 /*!
329 * \brief pixCreateNoInit()
330 *
331 * \param[in] width, height, depth
332 * \return pixd with data allocated but not initialized,
333 * or NULL on error
334 *
335 * <pre>
336 * Notes:
337 * (1) Pad bits are set to avoid reading uninitialized data, because
338 * some optimized routines read from pad bits.
339 * (2) Initializing memory is very fast, so this optimization is
340 * not used in the library.
341 * </pre>
342 */
343 PIX *
344 pixCreateNoInit(l_int32 width,
345 l_int32 height,
346 l_int32 depth)
347 {
348 l_int32 wpl;
349 PIX *pixd;
350 l_uint32 *data;
351
352 if ((pixd = pixCreateHeader(width, height, depth)) == NULL)
353 return (PIX *)ERROR_PTR("pixd not made", __func__, NULL);
354 wpl = pixGetWpl(pixd);
355 if ((data = (l_uint32 *)pixdata_malloc(4LL * wpl * height)) == NULL) {
356 pixDestroy(&pixd);
357 return (PIX *)ERROR_PTR("pixdata_malloc fail for data",
358 __func__, NULL);
359 }
360 pixSetData(pixd, data);
361 pixSetPadBits(pixd, 0);
362 return pixd;
363 }
364
365
366 /*!
367 * \brief pixCreateTemplate()
368 *
369 * \param[in] pixs
370 * \return pixd, or NULL on error
371 *
372 * <pre>
373 * Notes:
374 * (1) Makes a Pix of the same size as the input Pix, with the
375 * data array allocated and initialized to 0.
376 * (2) Copies the other fields, including colormap if it exists.
377 * </pre>
378 */
379 PIX *
380 pixCreateTemplate(const PIX *pixs)
381 {
382 PIX *pixd;
383
384 if (!pixs)
385 return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
386
387 if ((pixd = pixCreateTemplateNoInit(pixs)) == NULL)
388 return (PIX *)ERROR_PTR("pixd not made", __func__, NULL);
389 memset(pixd->data, 0, 4LL * pixd->wpl * pixd->h);
390 return pixd;
391 }
392
393
394 /*!
395 * \brief pixCreateTemplateNoInit()
396 *
397 * \param[in] pixs
398 * \return pixd, or NULL on error
399 *
400 * <pre>
401 * Notes:
402 * (1) Makes a Pix of the same size as the input Pix, with
403 * the data array allocated but not initialized to 0.
404 * (2) Copies the other fields, including colormap if it exists.
405 * (3) Pad bits are set to avoid reading uninitialized data, because
406 * some optimized routines read from pad bits.
407 * (4) Initializing memory is very fast, so this optimization is
408 * not used in the library.
409 * </pre>
410 */
411 PIX *
412 pixCreateTemplateNoInit(const PIX *pixs)
413 {
414 l_int32 w, h, d;
415 PIX *pixd;
416
417 if (!pixs)
418 return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
419
420 pixGetDimensions(pixs, &w, &h, &d);
421 if ((pixd = pixCreateNoInit(w, h, d)) == NULL)
422 return (PIX *)ERROR_PTR("pixd not made", __func__, NULL);
423 pixCopySpp(pixd, pixs);
424 pixCopyResolution(pixd, pixs);
425 pixCopyColormap(pixd, pixs);
426 pixCopyText(pixd, pixs);
427 pixCopyInputFormat(pixd, pixs);
428 pixSetPadBits(pixd, 0);
429 return pixd;
430 }
431
432
433 /*!
434 * \brief pixCreateWithCmap()
435 *
436 * \param[in] width
437 * \param[in] height
438 * \param[in] depth 2, 4 or 8 bpp
439 * \param[in] initcolor L_SET_BLACK, L_SET_WHITE
440 * \return pixd with the initialization color assigned to all pixels,
441 * or NULL on error.
442 *
443 * <pre>
444 * Notes:
445 * (1) Creates a pix with a cmap, initialized to value 0.
446 * (2) Initializes the pix black or white by adding that color
447 * to the cmap at index 0.
448 * </pre>
449 */
450 PIX *
451 pixCreateWithCmap(l_int32 width,
452 l_int32 height,
453 l_int32 depth,
454 l_int32 initcolor)
455 {
456 PIX *pix;
457 PIXCMAP *cmap;
458
459 if (depth != 2 && depth != 4 && depth != 8)
460 return (PIX *)ERROR_PTR("depth not 2, 4 or 8 bpp", __func__, NULL);
461
462 if ((pix = pixCreate(width, height, depth)) == NULL)
463 return (PIX *)ERROR_PTR("pix not made", __func__, NULL);
464 cmap = pixcmapCreate(depth);
465 pixSetColormap(pix, cmap);
466 if (initcolor == L_SET_BLACK)
467 pixcmapAddColor(cmap, 0, 0, 0);
468 else /* L_SET_WHITE */
469 pixcmapAddColor(cmap, 255, 255, 255);
470 return pix;
471 }
472
473
474 /*!
475 * \brief pixCreateHeader()
476 *
477 * \param[in] width, height, depth
478 * \return pixd with no data allocated, or NULL on error
479 *
480 * <pre>
481 * Notes:
482 * (1) It is assumed that all 32 bit pix have 3 spp. If there is
483 * a valid alpha channel, this will be set to 4 spp later.
484 * (2) All pixCreate*() functions call pixCreateHeader().
485 If the number of bytes to be allocated is larger than the
486 * maximum value in an int32, we can get overflow, resulting
487 * in a smaller amount of memory actually being allocated.
488 * Later, an attempt to access memory that wasn't allocated will
489 * cause a crash. So to avoid crashing a program (or worse)
490 * with bad (or malicious) input, we limit the requested
491 * allocation of image data in a typesafe way.
492 * </pre>
493 */
494 PIX *
495 pixCreateHeader(l_int32 width,
496 l_int32 height,
497 l_int32 depth)
498 {
499 l_int32 wpl;
500 l_uint64 wpl64, bignum;
501 PIX *pixd;
502
503 if ((depth != 1) && (depth != 2) && (depth != 4) && (depth != 8)
504 && (depth != 16) && (depth != 24) && (depth != 32))
505 return (PIX *)ERROR_PTR("depth must be {1, 2, 4, 8, 16, 24, 32}",
506 __func__, NULL);
507 if (width <= 0)
508 return (PIX *)ERROR_PTR("width must be > 0", __func__, NULL);
509 if (height <= 0)
510 return (PIX *)ERROR_PTR("height must be > 0", __func__, NULL);
511
512 /* Avoid overflow in malloc, malicious or otherwise */
513 wpl64 = ((l_uint64)width * (l_uint64)depth + 31) / 32;
514 if (wpl64 > ((1LL << 24) - 1)) {
515 L_ERROR("requested w = %d, h = %d, d = %d\n",
516 __func__, width, height, depth);
517 return (PIX *)ERROR_PTR("wpl >= 2^24", __func__, NULL);
518 }
519 wpl = (l_int32)wpl64;
520 bignum = 4LL * wpl * height; /* number of bytes to be requested */
521 if (bignum > ((1LL << 31) - 1)) {
522 L_ERROR("requested w = %d, h = %d, d = %d\n",
523 __func__, width, height, depth);
524 return (PIX *)ERROR_PTR("requested bytes >= 2^31", __func__, NULL);
525 }
526
527 #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
528 if (bignum > (1LL << 26)) {
529 L_ERROR("fuzzer requested > 64 MB; refused\n", __func__);
530 return NULL;
531 }
532 if (width > 20000) {
533 L_ERROR("fuzzer requested width > 20K; refused\n", __func__);
534 return NULL;
535 }
536 if (height > 20000) {
537 L_ERROR("fuzzer requested height > 20K; refused\n", __func__);
538 return NULL;
539 }
540 #endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */
541
542 if ((pixd = (PIX *)LEPT_CALLOC(1, sizeof(PIX))) == NULL)
543 return (PIX *)ERROR_PTR("pixd not made", __func__, NULL);
544 pixSetWidth(pixd, width);
545 pixSetHeight(pixd, height);
546 pixSetDepth(pixd, depth);
547 pixSetWpl(pixd, wpl);
548 if (depth == 24 || depth == 32)
549 pixSetSpp(pixd, 3);
550 else
551 pixSetSpp(pixd, 1);
552 pixd->refcount = 1;
553 pixd->informat = IFF_UNKNOWN;
554 return pixd;
555 }
556
557
558 /*!
559 * \brief pixClone()
560 *
561 * \param[in] pixs
562 * \return same pix ptr, or NULL on error
563 *
564 * <pre>
565 * Notes:
566 * (1) A "clone" is simply a handle (ptr) to an existing pix.
567 * It is implemented because (a) images can be large and
568 * hence expensive to copy, and (b) extra handles to a data
569 * structure need to be made with a simple policy to avoid
570 * both double frees and memory leaks. Pix are reference
571 * counted. The side effect of pixClone() is an increase
572 * by 1 in the ref count.
573 * (2) The protocol to be used is:
574 * (a) Whenever you want a new handle to an existing image,
575 * call pixClone(), which just bumps a ref count.
576 * (b) Always call pixDestroy() on all handles. This
577 * decrements the ref count, nulls the handle, and
578 * only destroys the pix when pixDestroy() has been
579 * called on all handles.
580 * </pre>
581 */
582 PIX *
583 pixClone(PIX *pixs)
584 {
585 if (!pixs)
586 return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
587 ++pixs->refcount;
588
589 return pixs;
590 }
591
592
593 /*--------------------------------------------------------------------*
594 * Pix Destruction *
595 *--------------------------------------------------------------------*/
596 /*!
597 * \brief pixDestroy()
598 *
599 * \param[in,out] ppix will be set to null before returning
600 * \return void
601 *
602 * <pre>
603 * Notes:
604 * (1) Decrements the ref count and, if 0, destroys the pix.
605 * (2) Always nulls the input ptr.
606 * </pre>
607 */
608 void
609 pixDestroy(PIX **ppix)
610 {
611 PIX *pix;
612
613 if (!ppix) {
614 L_WARNING("ptr address is null!\n", __func__);
615 return;
616 }
617
618 if ((pix = *ppix) == NULL)
619 return;
620 pixFree(pix);
621 *ppix = NULL;
622 }
623
624
625 /*!
626 * \brief pixFree()
627 *
628 * \param[in] pix
629 * \return void
630 *
631 * <pre>
632 * Notes:
633 * (1) Decrements the ref count and, if 0, destroys the pix.
634 * </pre>
635 */
636 static void
637 pixFree(PIX *pix)
638 {
639 l_uint32 *data;
640 char *text;
641
642 if (!pix) return;
643
644 if (--pix->refcount == 0) {
645 if ((data = pixGetData(pix)) != NULL)
646 pixdata_free(data);
647 if ((text = pixGetText(pix)) != NULL)
648 LEPT_FREE(text);
649 pixDestroyColormap(pix);
650 LEPT_FREE(pix);
651 }
652 return;
653 }
654
655
656 /*-------------------------------------------------------------------------*
657 * Pix Copy *
658 *-------------------------------------------------------------------------*/
659 /*!
660 * \brief pixCopy()
661 *
662 * \param[in] pixd [optional] can be null, equal to pixs,
663 * different from pixs
664 * \param[in] pixs
665 * \return pixd, or NULL on error
666 *
667 * <pre>
668 * Notes:
669 * (1) There are three cases:
670 * (a) pixd == null (makes a new pix; refcount = 1)
671 * (b) pixd == pixs (no-op)
672 * (c) pixd != pixs (data copy; no change in refcount)
673 * If the refcount of pixd > 1, case (c) will side-effect
674 * these handles.
675 * (2) The general pattern of use is:
676 * pixd = pixCopy(pixd, pixs);
677 * This will work for all three cases.
678 * For clarity when the case is known, you can use:
679 * (a) pixd = pixCopy(NULL, pixs);
680 * (c) pixCopy(pixd, pixs);
681 * (3) For case (c), we check if pixs and pixd are the same
682 * size (w,h,d). If so, the data is copied directly.
683 * Otherwise, the data is reallocated to the correct size
684 * and the copy proceeds. The refcount of pixd is unchanged.
685 * (4) This operation, like all others that may involve a pre-existing
686 * pixd, will side-effect any existing clones of pixd.
687 * </pre>
688 */
689 PIX *
690 pixCopy(PIX *pixd, /* can be null */
691 const PIX *pixs)
692 {
693 l_int32 bytes;
694
695 if (!pixs)
696 return (PIX *)ERROR_PTR("pixs not defined", __func__, pixd);
697 if (pixs == pixd)
698 return pixd;
699
700 /* Total bytes in image data */
701 bytes = 4 * pixGetWpl(pixs) * pixGetHeight(pixs);
702
703 /* If we're making a new pix ... */
704 if (!pixd) {
705 if ((pixd = pixCreateTemplate(pixs)) == NULL)
706 return (PIX *)ERROR_PTR("pixd not made", __func__, NULL);
707 memcpy(pixd->data, pixs->data, bytes);
708 return pixd;
709 }
710
711 /* Reallocate image data if sizes are different. If this fails,
712 * pixd hasn't been changed. But we want to signal that the copy
713 * failed, so return NULL. This will cause a memory leak if the
714 * return ptr is assigned to pixd, but that is preferred to proceeding
715 * with an incorrect pixd, and in any event this use case of
716 * pixCopy() -- reallocating into an existing pix -- is infrequent. */
717 if (pixResizeImageData(pixd, pixs) == 1)
718 return (PIX *)ERROR_PTR("reallocation of data failed", __func__, NULL);
719
720 /* Copy non-image data fields */
721 pixCopyColormap(pixd, pixs);
722 pixCopySpp(pixd, pixs);
723 pixCopyResolution(pixd, pixs);
724 pixCopyInputFormat(pixd, pixs);
725 pixCopyText(pixd, pixs);
726
727 /* Copy image data */
728 memcpy(pixd->data, pixs->data, bytes);
729 return pixd;
730 }
731
732
733 /*!
734 * \brief pixResizeImageData()
735 *
736 * \param[in] pixd gets new uninitialized buffer for image data
737 * \param[in] pixs determines the size of the buffer; not changed
738 * \return 0 if OK, 1 on error
739 *
740 * <pre>
741 * Notes:
742 * (1) If the sizes of data in pixs and pixd are unequal, this
743 * frees the existing image data in pixd and allocates
744 * an uninitialized buffer that will hold the required amount
745 * of image data in pixs. The image data from pixs is not
746 * copied into the new buffer.
747 * (2) On failure to allocate, pixd is unchanged.
748 * </pre>
749 */
750 l_ok
751 pixResizeImageData(PIX *pixd,
752 const PIX *pixs)
753 {
754 l_int32 w, h, d, wpl, bytes;
755 l_uint32 *data;
756
757 if (!pixs)
758 return ERROR_INT("pixs not defined", __func__, 1);
759 if (!pixd)
760 return ERROR_INT("pixd not defined", __func__, 1);
761
762 if (pixSizesEqual(pixs, pixd)) /* nothing to do */
763 return 0;
764
765 /* Make sure we can copy the data */
766 pixGetDimensions(pixs, &w, &h, &d);
767 wpl = pixGetWpl(pixs);
768 bytes = 4 * wpl * h;
769 if ((data = (l_uint32 *)pixdata_malloc(bytes)) == NULL)
770 return ERROR_INT("pixdata_malloc fail for data", __func__, 1);
771
772 /* OK, do it */
773 pixSetWidth(pixd, w);
774 pixSetHeight(pixd, h);
775 pixSetDepth(pixd, d);
776 pixSetWpl(pixd, wpl);
777 pixFreeAndSetData(pixd, data); /* free old data and assign new data */
778 pixCopyResolution(pixd, pixs);
779 return 0;
780 }
781
782
783 /*!
784 * \brief pixCopyColormap()
785 *
786 * \param[in] pixd
787 * \param[in] pixs copies the colormap to %pixd
788 * \return 0 if OK, 1 on error
789 *
790 * <pre>
791 * Notes:
792 * (1) This destroys the colormap in pixd, unless the operation is a no-op
793 * </pre>
794 */
795 l_ok
796 pixCopyColormap(PIX *pixd,
797 const PIX *pixs)
798 {
799 l_int32 valid;
800 const PIXCMAP *cmaps;
801 PIXCMAP *cmapd;
802
803 if (!pixs)
804 return ERROR_INT("pixs not defined", __func__, 1);
805 if (!pixd)
806 return ERROR_INT("pixd not defined", __func__, 1);
807 if (pixs == pixd)
808 return 0; /* no-op */
809 if (pixGetDepth(pixs) != pixGetDepth(pixd))
810 return ERROR_INT("depths of pixs and pixd differ", __func__, 1);
811
812 pixDestroyColormap(pixd);
813 if ((cmaps = pixs->colormap) == NULL) /* not an error */
814 return 0;
815 pixcmapIsValid(cmaps, NULL, &valid);
816 if (!valid)
817 return ERROR_INT("cmap not valid", __func__, 1);
818
819 if ((cmapd = pixcmapCopy(cmaps)) == NULL)
820 return ERROR_INT("cmapd not made", __func__, 1);
821 pixSetColormap(pixd, cmapd);
822 return 0;
823 }
824
825
826 /*!
827 * \brief pixTransferAllData()
828 *
829 * \param[in] pixd must be different from pixs
830 * \param[in,out] ppixs will be nulled if refcount goes to 0
831 * \param[in] copytext 1 to copy the text field; 0 to skip
832 * \param[in] copyformat 1 to copy the informat field; 0 to skip
833 * \return 0 if OK, 1 on error
834 *
835 * <pre>
836 * Notes:
837 * (1) This does a complete data transfer from pixs to pixd,
838 * followed by the destruction of pixs (refcount permitting).
839 * (2) If the refcount of pixs is 1, pixs is destroyed. Otherwise,
840 * the data in pixs is copied (rather than transferred) to pixd.
841 * (3) This operation, like all others with a pre-existing pixd,
842 * will side-effect any existing clones of pixd. The pixd
843 * refcount does not change.
844 * (4) When might you use this? Suppose you have an in-place Pix
845 * function (returning void) with the typical signature:
846 * void function-inplace(PIX *pix, ...)
847 * where "..." are non-pointer input parameters, and suppose
848 * further that you sometimes want to return an arbitrary Pix
849 * in place of the input Pix. There are two ways you can do this:
850 * (a) The straightforward way is to change the function
851 * signature to take the address of the Pix ptr:
852 * \code
853 * void function-inplace(PIX **ppix, ...) {
854 * PIX *pixt = function-makenew(*ppix);
855 * pixDestroy(ppix);
856 * *ppix = pixt;
857 * return;
858 * }
859 * \endcode
860 * Here, the input and returned pix are different, as viewed
861 * by the calling function, and the inplace function is
862 * expected to destroy the input pix to avoid a memory leak.
863 * (b) Keep the signature the same and use pixTransferAllData()
864 * to return the new Pix in the input Pix struct:
865 * \code
866 * void function-inplace(PIX *pix, ...) {
867 * PIX *pixt = function-makenew(pix);
868 * pixTransferAllData(pix, &pixt, 0, 0);
869 * // pixDestroy() is called on pixt
870 * return;
871 * }
872 * \endcode
873 * Here, the input and returned pix are the same, as viewed
874 * by the calling function, and the inplace function must
875 * never destroy the input pix, because the calling function
876 * maintains an unchanged handle to it.
877 * </pre>
878 */
879 l_ok
880 pixTransferAllData(PIX *pixd,
881 PIX **ppixs,
882 l_int32 copytext,
883 l_int32 copyformat)
884 {
885 l_int32 nbytes;
886 PIX *pixs;
887
888 if (!ppixs)
889 return ERROR_INT("&pixs not defined", __func__, 1);
890 if ((pixs = *ppixs) == NULL)
891 return ERROR_INT("pixs not defined", __func__, 1);
892 if (!pixd)
893 return ERROR_INT("pixd not defined", __func__, 1);
894 if (pixs == pixd) /* no-op */
895 return ERROR_INT("pixd == pixs", __func__, 1);
896
897 if (pixs->refcount == 1) { /* transfer the data, cmap, text */
898 pixFreeData(pixd); /* dealloc any existing data */
899 pixSetData(pixd, pixGetData(pixs)); /* transfer new data from pixs */
900 pixs->data = NULL; /* pixs no longer owns data */
901 pixDestroyColormap(pixd); /* free the old one, if it exists */
902 pixd->colormap = pixGetColormap(pixs); /* transfer to pixd */
903 pixs->colormap = NULL; /* pixs no longer owns colormap */
904 if (copytext) {
905 pixSetText(pixd, pixGetText(pixs));
906 pixSetText(pixs, NULL);
907 }
908 } else { /* preserve pixs by making a copy of the data, cmap, text */
909 pixResizeImageData(pixd, pixs);
910 nbytes = 4 * pixGetWpl(pixs) * pixGetHeight(pixs);
911 memcpy(pixGetData(pixd), pixGetData(pixs), nbytes);
912 pixCopyColormap(pixd, pixs);
913 if (copytext)
914 pixCopyText(pixd, pixs);
915 }
916
917 pixCopySpp(pixd, pixs);
918 pixCopyResolution(pixd, pixs);
919 pixCopyDimensions(pixd, pixs);
920 if (copyformat)
921 pixCopyInputFormat(pixd, pixs);
922
923 /* This will destroy pixs if data was transferred;
924 * otherwise, it just decrements its refcount. */
925 pixDestroy(ppixs);
926 return 0;
927 }
928
929
930 /*!
931 * \brief pixSwapAndDestroy()
932 *
933 * \param[out] ppixd [optional] input pixd can be null,
934 * and it must be different from pixs
935 * \param[in,out] ppixs will be nulled after the swap
936 * \return 0 if OK, 1 on error
937 *
938 * <pre>
939 * Notes:
940 * (1) Simple operation to change the handle name safely.
941 * After this operation, the original image in pixd has
942 * been destroyed, pixd points to what was pixs, and
943 * the input pixs ptr has been nulled.
944 * (2) This works safely whether or not pixs and pixd are cloned.
945 * If pixs is cloned, the other handles still point to
946 * the original image, with the ref count reduced by 1.
947 * (3) Usage example:
948 * \code
949 * Pix *pix1 = pixRead("...");
950 * Pix *pix2 = function(pix1, ...);
951 * pixSwapAndDestroy(&pix1, &pix2);
952 * pixDestroy(&pix1); // holds what was in pix2
953 * \endcode
954 * Example with clones ([] shows ref count of image generated
955 * by the function):
956 * \code
957 * Pix *pixs = pixRead("...");
958 * Pix *pix1 = pixClone(pixs);
959 * Pix *pix2 = function(pix1, ...); [1]
960 * Pix *pix3 = pixClone(pix2); [1] --> [2]
961 * pixSwapAndDestroy(&pix1, &pix2);
962 * pixDestroy(&pixs); // still holds read image
963 * pixDestroy(&pix1); // holds what was in pix2 [2] --> [1]
964 * pixDestroy(&pix3); // holds what was in pix2 [1] --> [0]
965 * \endcode
966 * </pre>
967 */
968 l_ok
969 pixSwapAndDestroy(PIX **ppixd,
970 PIX **ppixs)
971 {
972 if (!ppixd)
973 return ERROR_INT("&pixd not defined", __func__, 1);
974 if (!ppixs)
975 return ERROR_INT("&pixs not defined", __func__, 1);
976 if (*ppixs == NULL)
977 return ERROR_INT("pixs not defined", __func__, 1);
978 if (ppixs == ppixd) /* no-op */
979 return ERROR_INT("&pixd == &pixs", __func__, 1);
980
981 pixDestroy(ppixd);
982 *ppixd = pixClone(*ppixs);
983 pixDestroy(ppixs);
984 return 0;
985 }
986
987
988 /*--------------------------------------------------------------------*
989 * Pix Accessors *
990 *--------------------------------------------------------------------*/
991 l_int32
992 pixGetWidth(const PIX *pix)
993 {
994 if (!pix)
995 return ERROR_INT("pix not defined", __func__, 0);
996
997 return pix->w;
998 }
999
1000
1001 l_int32
1002 pixSetWidth(PIX *pix,
1003 l_int32 width)
1004 {
1005 if (!pix)
1006 return ERROR_INT("pix not defined", __func__, 1);
1007 if (width < 0) {
1008 pix->w = 0;
1009 return ERROR_INT("width must be >= 0", __func__, 1);
1010 }
1011
1012 pix->w = width;
1013 return 0;
1014 }
1015
1016
1017 l_int32
1018 pixGetHeight(const PIX *pix)
1019 {
1020 if (!pix)
1021 return ERROR_INT("pix not defined", __func__, 0);
1022
1023 return pix->h;
1024 }
1025
1026
1027 l_int32
1028 pixSetHeight(PIX *pix,
1029 l_int32 height)
1030 {
1031 if (!pix)
1032 return ERROR_INT("pix not defined", __func__, 1);
1033 if (height < 0) {
1034 pix->h = 0;
1035 return ERROR_INT("h must be >= 0", __func__, 1);
1036 }
1037
1038 pix->h = height;
1039 return 0;
1040 }
1041
1042
1043 l_int32
1044 pixGetDepth(const PIX *pix)
1045 {
1046 if (!pix)
1047 return ERROR_INT("pix not defined", __func__, 0);
1048
1049 return pix->d;
1050 }
1051
1052
1053 l_int32
1054 pixSetDepth(PIX *pix,
1055 l_int32 depth)
1056 {
1057 if (!pix)
1058 return ERROR_INT("pix not defined", __func__, 1);
1059 if (depth < 1)
1060 return ERROR_INT("d must be >= 1", __func__, 1);
1061
1062 pix->d = depth;
1063 return 0;
1064 }
1065
1066
1067 /*!
1068 * \brief pixGetDimensions()
1069 *
1070 * \param[in] pix
1071 * \param[out] pw, ph, pd [optional] each can be null
1072 * \return 0 if OK, 1 on error
1073 */
1074 l_ok
1075 pixGetDimensions(const PIX *pix,
1076 l_int32 *pw,
1077 l_int32 *ph,
1078 l_int32 *pd)
1079 {
1080 if (pw) *pw = 0;
1081 if (ph) *ph = 0;
1082 if (pd) *pd = 0;
1083 if (!pix)
1084 return ERROR_INT("pix not defined", __func__, 1);
1085 if (pw) *pw = pix->w;
1086 if (ph) *ph = pix->h;
1087 if (pd) *pd = pix->d;
1088 return 0;
1089 }
1090
1091
1092 /*!
1093 * \brief pixSetDimensions()
1094 *
1095 * \param[in] pix
1096 * \param[in] w, h, d use 0 to skip the setting for any of these
1097 * \return 0 if OK, 1 on error
1098 */
1099 l_ok
1100 pixSetDimensions(PIX *pix,
1101 l_int32 w,
1102 l_int32 h,
1103 l_int32 d)
1104 {
1105 if (!pix)
1106 return ERROR_INT("pix not defined", __func__, 1);
1107 if (w > 0) pixSetWidth(pix, w);
1108 if (h > 0) pixSetHeight(pix, h);
1109 if (d > 0) pixSetDepth(pix, d);
1110 return 0;
1111 }
1112
1113
1114 /*!
1115 * \brief pixCopyDimensions()
1116 *
1117 * \param[in] pixd
1118 * \param[in] pixs
1119 * \return 0 if OK, 1 on error
1120 */
1121 l_ok
1122 pixCopyDimensions(PIX *pixd,
1123 const PIX *pixs)
1124 {
1125 if (!pixd)
1126 return ERROR_INT("pixd not defined", __func__, 1);
1127 if (!pixs)
1128 return ERROR_INT("pixs not defined", __func__, 1);
1129 if (pixs == pixd)
1130 return 0; /* no-op */
1131
1132 pixSetWidth(pixd, pixGetWidth(pixs));
1133 pixSetHeight(pixd, pixGetHeight(pixs));
1134 pixSetDepth(pixd, pixGetDepth(pixs));
1135 pixSetWpl(pixd, pixGetWpl(pixs));
1136 return 0;
1137 }
1138
1139
1140 l_int32
1141 pixGetSpp(const PIX *pix)
1142 {
1143 if (!pix)
1144 return ERROR_INT("pix not defined", __func__, 0);
1145
1146 return pix->spp;
1147 }
1148
1149
1150 /*
1151 * \brief pixSetSpp()
1152 *
1153 * \param[in] pix
1154 * \param[in] spp 1, 3 or 4 samples
1155 * \return 0 if OK, 1 on error
1156 *
1157 * <pre>
1158 * Notes:
1159 * (1) For a 32 bpp pix, this can be used to ignore the
1160 * alpha sample (spp == 3) or to use it (spp == 4).
1161 * For example, to write a spp == 4 image without the alpha
1162 * sample (as an rgb pix), call pixSetSpp(pix, 3) and
1163 * then write it out as a png.
1164 * </pre>
1165 */
1166 l_int32
1167 pixSetSpp(PIX *pix,
1168 l_int32 spp)
1169 {
1170 if (!pix)
1171 return ERROR_INT("pix not defined", __func__, 1);
1172 if (spp < 1)
1173 return ERROR_INT("spp must be >= 1", __func__, 1);
1174
1175 pix->spp = spp;
1176 return 0;
1177 }
1178
1179
1180 /*!
1181 * \brief pixCopySpp()
1182 *
1183 * \param[in] pixd
1184 * \param[in] pixs
1185 * \return 0 if OK, 1 on error
1186 */
1187 l_ok
1188 pixCopySpp(PIX *pixd,
1189 const PIX *pixs)
1190 {
1191 if (!pixd)
1192 return ERROR_INT("pixd not defined", __func__, 1);
1193 if (!pixs)
1194 return ERROR_INT("pixs not defined", __func__, 1);
1195 if (pixs == pixd)
1196 return 0; /* no-op */
1197
1198 pixSetSpp(pixd, pixGetSpp(pixs));
1199 return 0;
1200 }
1201
1202
1203 l_int32
1204 pixGetWpl(const PIX *pix)
1205 {
1206 if (!pix)
1207 return ERROR_INT("pix not defined", __func__, 0);
1208 return pix->wpl;
1209 }
1210
1211
1212 l_int32
1213 pixSetWpl(PIX *pix,
1214 l_int32 wpl)
1215 {
1216 if (!pix)
1217 return ERROR_INT("pix not defined", __func__, 1);
1218
1219 pix->wpl = wpl;
1220 return 0;
1221 }
1222
1223
1224 l_int32
1225 pixGetXRes(const PIX *pix)
1226 {
1227 if (!pix)
1228 return ERROR_INT("pix not defined", __func__, 0);
1229 return pix->xres;
1230 }
1231
1232
1233 l_int32
1234 pixSetXRes(PIX *pix,
1235 l_int32 res)
1236 {
1237 if (!pix)
1238 return ERROR_INT("pix not defined", __func__, 1);
1239
1240 pix->xres = res;
1241 return 0;
1242 }
1243
1244
1245 l_int32
1246 pixGetYRes(const PIX *pix)
1247 {
1248 if (!pix)
1249 return ERROR_INT("pix not defined", __func__, 0);
1250 return pix->yres;
1251 }
1252
1253
1254 l_int32
1255 pixSetYRes(PIX *pix,
1256 l_int32 res)
1257 {
1258 if (!pix)
1259 return ERROR_INT("pix not defined", __func__, 1);
1260
1261 pix->yres = res;
1262 return 0;
1263 }
1264
1265
1266 /*!
1267 * \brief pixGetResolution()
1268 *
1269 * \param[in] pix
1270 * \param[out] pxres, pyres [optional] each can be null
1271 * \return 0 if OK, 1 on error
1272 */
1273 l_ok
1274 pixGetResolution(const PIX *pix,
1275 l_int32 *pxres,
1276 l_int32 *pyres)
1277 {
1278 if (pxres) *pxres = 0;
1279 if (pyres) *pyres = 0;
1280 if (!pxres && !pyres)
1281 return ERROR_INT("no output requested", __func__, 1);
1282 if (!pix)
1283 return ERROR_INT("pix not defined", __func__, 1);
1284 if (pxres) *pxres = pix->xres;
1285 if (pyres) *pyres = pix->yres;
1286 return 0;
1287 }
1288
1289
1290 /*!
1291 * \brief pixSetResolution()
1292 *
1293 * \param[in] pix
1294 * \param[in] xres, yres use 0 to skip setting a value for either of these
1295 * \return 0 if OK, 1 on error
1296 */
1297 l_ok
1298 pixSetResolution(PIX *pix,
1299 l_int32 xres,
1300 l_int32 yres)
1301 {
1302 if (!pix)
1303 return ERROR_INT("pix not defined", __func__, 1);
1304 if (xres > 0) pix->xres = xres;
1305 if (yres > 0) pix->yres = yres;
1306 return 0;
1307 }
1308
1309
1310 l_int32
1311 pixCopyResolution(PIX *pixd,
1312 const PIX *pixs)
1313 {
1314 if (!pixs)
1315 return ERROR_INT("pixs not defined", __func__, 1);
1316 if (!pixd)
1317 return ERROR_INT("pixd not defined", __func__, 1);
1318 if (pixs == pixd)
1319 return 0; /* no-op */
1320
1321 pixSetXRes(pixd, pixGetXRes(pixs));
1322 pixSetYRes(pixd, pixGetYRes(pixs));
1323 return 0;
1324 }
1325
1326
1327 l_int32
1328 pixScaleResolution(PIX *pix,
1329 l_float32 xscale,
1330 l_float32 yscale)
1331 {
1332 l_float64 xres, yres;
1333 l_float64 maxres = 100000000.0;
1334
1335 if (!pix)
1336 return ERROR_INT("pix not defined", __func__, 1);
1337 if (xscale <= 0 || yscale <= 0)
1338 return ERROR_INT("invalid scaling ratio", __func__, 1);
1339
1340 xres = (l_float64)xscale * (l_float32)(pix->xres) + 0.5;
1341 yres = (l_float64)yscale * (l_float32)(pix->yres) + 0.5;
1342 pix->xres = (l_uint32)L_MIN(xres, maxres);
1343 pix->yres = (l_uint32)L_MIN(yres, maxres);
1344 return 0;
1345 }
1346
1347
1348 l_int32
1349 pixGetInputFormat(const PIX *pix)
1350 {
1351 if (!pix)
1352 return ERROR_INT("pix not defined", __func__, 0);
1353 return pix->informat;
1354 }
1355
1356
1357 l_int32
1358 pixSetInputFormat(PIX *pix,
1359 l_int32 informat)
1360 {
1361 if (!pix)
1362 return ERROR_INT("pix not defined", __func__, 1);
1363 pix->informat = informat;
1364 return 0;
1365 }
1366
1367
1368 l_int32
1369 pixCopyInputFormat(PIX *pixd,
1370 const PIX *pixs)
1371 {
1372 if (!pixs)
1373 return ERROR_INT("pixs not defined", __func__, 1);
1374 if (!pixd)
1375 return ERROR_INT("pixd not defined", __func__, 1);
1376 if (pixs == pixd)
1377 return 0; /* no-op */
1378
1379 pixSetInputFormat(pixd, pixGetInputFormat(pixs));
1380 return 0;
1381 }
1382
1383
1384 l_int32
1385 pixSetSpecial(PIX *pix,
1386 l_int32 special)
1387 {
1388 if (!pix)
1389 return ERROR_INT("pix not defined", __func__, 1);
1390 pix->special = special;
1391 return 0;
1392 }
1393
1394
1395 /*!
1396 * \brief pixGetText()
1397 *
1398 * \param[in] pix
1399 * \return ptr to existing text string
1400 *
1401 * <pre>
1402 * Notes:
1403 * (1) The text string belongs to the pix:
1404 * * the caller must NOT free it
1405 * * it must not be used after the pix is destroyed
1406 * </pre>
1407 */
1408 char *
1409 pixGetText(PIX *pix)
1410 {
1411 if (!pix)
1412 return (char *)ERROR_PTR("pix not defined", __func__, NULL);
1413 return pix->text;
1414 }
1415
1416
1417 /*!
1418 * \brief pixSetText()
1419 *
1420 * \param[in] pix
1421 * \param[in] textstring can be null
1422 * \return 0 if OK, 1 on error
1423 *
1424 * <pre>
1425 * Notes:
1426 * (1) This removes any existing textstring and puts a copy of
1427 * the input textstring there.
1428 * </pre>
1429 */
1430 l_ok
1431 pixSetText(PIX *pix,
1432 const char *textstring)
1433 {
1434 if (!pix)
1435 return ERROR_INT("pix not defined", __func__, 1);
1436
1437 stringReplace(&pix->text, textstring);
1438 return 0;
1439 }
1440
1441
1442 /*!
1443 * \brief pixAddText()
1444 *
1445 * \param[in] pix
1446 * \param[in] textstring can be null
1447 * \return 0 if OK, 1 on error
1448 *
1449 * <pre>
1450 * Notes:
1451 * (1) This adds the new textstring to any existing text.
1452 * (2) Either or both the existing text and the new text
1453 * string can be null.
1454 * </pre>
1455 */
1456 l_ok
1457 pixAddText(PIX *pix,
1458 const char *textstring)
1459 {
1460 char *newstring;
1461
1462 if (!pix)
1463 return ERROR_INT("pix not defined", __func__, 1);
1464
1465 newstring = stringJoin(pixGetText(pix), textstring);
1466 stringReplace(&pix->text, newstring);
1467 LEPT_FREE(newstring);
1468 return 0;
1469 }
1470
1471
1472 l_int32
1473 pixCopyText(PIX *pixd,
1474 const PIX *pixs)
1475 {
1476 if (!pixs)
1477 return ERROR_INT("pixs not defined", __func__, 1);
1478 if (!pixd)
1479 return ERROR_INT("pixd not defined", __func__, 1);
1480 if (pixs == pixd)
1481 return 0; /* no-op */
1482
1483 pixSetText(pixd, pixs->text);
1484 return 0;
1485 }
1486
1487
1488 /*!
1489 * \brief pixGetTextCompNew()
1490 *
1491 * \param[in] pix
1492 * \param[out] psize this number of bytes of returned binary data
1493 * \return ptr to binary data derived from the text string in the pix,
1494 * after decoding and uncompressing
1495 *
1496 * <pre>
1497 * Notes:
1498 * (1) The ascii string in the text field of the input pix was
1499 * previously stored there using pixSetTextCompNew().
1500 * (2) This retrieves the string and performs ascii85 decoding
1501 * followed by decompression on it. The returned binary data
1502 * is owned by the caller and must be freed.
1503 * </pre>
1504 */
1505 l_uint8 *
1506 pixGetTextCompNew(PIX *pix,
1507 size_t *psize)
1508 {
1509 char *str;
1510
1511 if (!pix)
1512 return (l_uint8 *)ERROR_PTR("pix not defined", __func__, NULL);
1513 str = pixGetText(pix);
1514 return decodeAscii85WithComp(str, strlen(str), psize);
1515 }
1516
1517
1518 /*!
1519 * \brief pixSetTextCompNew()
1520 *
1521 * \param[in] pix
1522 * \param[in] data binary data
1523 * \param[in] size number of bytes of binary data
1524 * \return 0 if OK, 1 on error
1525 *
1526 * <pre>
1527 * Notes:
1528 * (1) This receives binary data and performs compression and ascii85
1529 * encoding on it. The ascii result is stored in the input pix,
1530 * replacing any string that may be there.
1531 * (2) The input %data can be reconstructed using pixGetTextCompNew().
1532 * </pre>
1533 */
1534 l_ok
1535 pixSetTextCompNew(PIX *pix,
1536 const l_uint8 *data,
1537 size_t size)
1538 {
1539 size_t encodesize; /* ignored */
1540
1541 if (!pix)
1542 return ERROR_INT("pix not defined", __func__, 1);
1543
1544 LEPT_FREE(pix->text);
1545 pix->text = encodeAscii85WithComp(data, size, &encodesize);
1546 return 0;
1547 }
1548
1549
1550 PIXCMAP *
1551 pixGetColormap(PIX *pix)
1552 {
1553 if (!pix)
1554 return (PIXCMAP *)ERROR_PTR("pix not defined", __func__, NULL);
1555 return pix->colormap;
1556 }
1557
1558
1559 /*!
1560 * \brief pixSetColormap()
1561 *
1562 * \param[in] pix
1563 * \param[in] colormap optional; can be null.
1564 * \return 0 if OK, 1 on error.
1565 *
1566 * <pre>
1567 * Notes:
1568 * (1) If %colormap is not defined, this is a no-op.
1569 * (2) This destroys any existing colormap before assigning the
1570 * new %colormap to %pix.
1571 * (3) If the colormap is not valid, this returns 1. The caller
1572 * should check if there is a possibility that the pix and
1573 * colormap depths differ.
1574 * (4) This does not do the work of checking pixs for a pixel value
1575 * that is out of bounds for the colormap -- that only needs to
1576 * be done when reading and writing with an I/O library like
1577 * png and gif.
1578 * (5) Because colormaps are not ref counted, the new colormap
1579 * must not belong to any other pix.
1580 * </pre>
1581 */
1582 l_ok
1583 pixSetColormap(PIX *pix,
1584 PIXCMAP *colormap)
1585 {
1586 l_int32 valid;
1587
1588 if (!pix)
1589 return ERROR_INT("pix not defined", __func__, 1);
1590 if (!colormap) return 0;
1591
1592 /* Make sure the colormap doesn't get lost */
1593 pixDestroyColormap(pix);
1594 pix->colormap = colormap;
1595
1596 pixcmapIsValid(colormap, NULL, &valid);
1597 if (!valid)
1598 return ERROR_INT("colormap is not valid", __func__, 1);
1599 return 0;
1600 }
1601
1602
1603 /*!
1604 * \brief pixDestroyColormap()
1605 *
1606 * \param[in] pix
1607 * \return 0 if OK, 1 on error
1608 */
1609 l_ok
1610 pixDestroyColormap(PIX *pix)
1611 {
1612 PIXCMAP *cmap;
1613
1614 if (!pix)
1615 return ERROR_INT("pix not defined", __func__, 1);
1616
1617 if ((cmap = pix->colormap) != NULL) {
1618 pixcmapDestroy(&cmap);
1619 pix->colormap = NULL;
1620 }
1621 return 0;
1622 }
1623
1624
1625 /*!
1626 * \brief pixGetData()
1627 *
1628 * \param[in] pix
1629 * \return ptr to image data
1630 *
1631 * <pre>
1632 * Notes:
1633 * (1) This gives a new handle for the data. The data is still
1634 * owned by the pix, so do not call LEPT_FREE() on it.
1635 * (2) This cannot guarantee that the pix data returned will not
1636 * be changed, so %pix cannot be declared const. And because
1637 * most imaging operations call this for access to the data,
1638 * this prevents them from declaring %pix to be const, even if
1639 * they only use the data for inspection.
1640 * </pre>
1641 */
1642 l_uint32 *
1643 pixGetData(PIX *pix)
1644 {
1645 if (!pix)
1646 return (l_uint32 *)ERROR_PTR("pix not defined", __func__, NULL);
1647 return pix->data;
1648 }
1649
1650
1651 /*!
1652 * \brief pixFreeAndSetData()
1653 *
1654 * \param[in] pix
1655 * \param[in] data
1656 * \return 0 if OK, 1 on error
1657 *
1658 * <pre>
1659 * Notes:
1660 * (1) This frees the existing raster data in the pix and assigns %data.
1661 * </pre>
1662 */
1663 l_int32
1664 pixFreeAndSetData(PIX *pix,
1665 l_uint32 *data)
1666 {
1667 if (!pix)
1668 return ERROR_INT("pix not defined", __func__, 1);
1669
1670 pixFreeData(pix);
1671 pix->data = data;
1672 return 0;
1673 }
1674
1675
1676 /*!
1677 * \brief pixSetData()
1678 *
1679 * \param[in] pix
1680 * \param[in] data
1681 * \return 0 if OK, 1 on error
1682 *
1683 * <pre>
1684 * Notes:
1685 * (1) This does not free any existing data. To free existing
1686 * data, use pixFreeAndSetData() instead.
1687 * </pre>
1688 */
1689 l_int32
1690 pixSetData(PIX *pix,
1691 l_uint32 *data)
1692 {
1693 if (!pix)
1694 return ERROR_INT("pix not defined", __func__, 1);
1695
1696 pix->data = data;
1697 return 0;
1698 }
1699
1700
1701 /*!
1702 * \brief pixFreeData()
1703 *
1704 * \param[in] pix
1705 * \return 0 if OK, 1 on error
1706 *
1707 * <pre>
1708 * Notes:
1709 * (1) This frees the data and sets the pix data ptr to null.
1710 * It should be used before pixSetData() in the situation where
1711 * you want to free any existing data before doing
1712 * a subsequent assignment with pixSetData().
1713 * </pre>
1714 */
1715 l_int32
1716 pixFreeData(PIX *pix)
1717 {
1718 l_uint32 *data;
1719
1720 if (!pix)
1721 return ERROR_INT("pix not defined", __func__, 1);
1722
1723 if ((data = pixGetData(pix)) != NULL) {
1724 pixdata_free(data);
1725 pix->data = NULL;
1726 }
1727 return 0;
1728 }
1729
1730
1731 /*!
1732 * \brief pixExtractData()
1733 *
1734 * \param[in] pix
1735 * \return ptr to data, or null on error
1736 *
1737 * <pre>
1738 * Notes:
1739 * (1) This extracts the pix image data for use in another context.
1740 * The caller still needs to use pixDestroy() on the input pix.
1741 * (2) If refcount == 1, the data is extracted and the
1742 * pix->data ptr is set to NULL.
1743 * (3) If refcount > 1, this simply returns a copy of the data,
1744 * using the pix allocator, and leaving the input pix unchanged.
1745 * </pre>
1746 */
1747 l_uint32 *
1748 pixExtractData(PIX *pixs)
1749 {
1750 l_int32 bytes;
1751 l_uint32 *data, *datas;
1752
1753 if (!pixs)
1754 return (l_uint32 *)ERROR_PTR("pixs not defined", __func__, NULL);
1755
1756 if (pixs->refcount == 1) { /* extract */
1757 data = pixGetData(pixs);
1758 pixSetData(pixs, NULL);
1759 } else { /* refcount > 1; copy */
1760 bytes = 4 * pixGetWpl(pixs) * pixGetHeight(pixs);
1761 datas = pixGetData(pixs);
1762 if ((data = (l_uint32 *)pixdata_malloc(bytes)) == NULL)
1763 return (l_uint32 *)ERROR_PTR("data not made", __func__, NULL);
1764 memcpy(data, datas, bytes);
1765 }
1766
1767 return data;
1768 }
1769
1770
1771 /*--------------------------------------------------------------------*
1772 * Pix line ptrs *
1773 *--------------------------------------------------------------------*/
1774 /*!
1775 * \brief pixGetLinePtrs()
1776 *
1777 * \param[in] pix
1778 * \param[out] psize [optional] array size, which is the pix height
1779 * \return array of line ptrs, or NULL on error
1780 *
1781 * <pre>
1782 * Notes:
1783 * (1) This is intended to be used for fast random pixel access.
1784 * For example, for an 8 bpp image,
1785 * val = GET_DATA_BYTE(lines8[i], j);
1786 * is equivalent to, but much faster than,
1787 * pixGetPixel(pix, j, i, &val);
1788 * (2) How much faster? For 1 bpp, it's from 6 to 10x faster.
1789 * For 8 bpp, it's an amazing 30x faster. So if you are
1790 * doing random access over a substantial part of the image,
1791 * use this line ptr array.
1792 * (3) When random access is used in conjunction with a stack,
1793 * queue or heap, the overall computation time depends on
1794 * the operations performed on each struct that is popped
1795 * or pushed, and whether we are using a priority queue (O(logn))
1796 * or a queue or stack (O(1)). For example, for maze search,
1797 * the overall ratio of time for line ptrs vs. pixGet/Set* is
1798 * Maze type Type Time ratio
1799 * binary queue 0.4
1800 * gray heap (priority queue) 0.6
1801 * (4) Because this returns a void** and the accessors take void*,
1802 * the compiler cannot check the pointer types. It is
1803 * strongly recommended that you adopt a naming scheme for
1804 * the returned ptr arrays that indicates the pixel depth.
1805 * (This follows the original intent of Simonyi's "Hungarian"
1806 * application notation, where naming is used proactively
1807 * to make errors visibly obvious.) By doing this, you can
1808 * tell by inspection if the correct accessor is used.
1809 * For example, for an 8 bpp pixg:
1810 * void **lineg8 = pixGetLinePtrs(pixg, NULL);
1811 * val = GET_DATA_BYTE(lineg8[i], j); // fast access; BYTE, 8
1812 * ...
1813 * LEPT_FREE(lineg8); // don't forget this
1814 * (5) These are convenient for accessing bytes sequentially in an
1815 * 8 bpp grayscale image. People who write image processing code
1816 * on 8 bpp images are accustomed to grabbing pixels directly out
1817 * of the raster array. Note that for little endians, you first
1818 * need to reverse the byte order in each 32-bit word.
1819 * Here's a typical usage pattern:
1820 * pixEndianByteSwap(pix); // always safe; no-op on big-endians
1821 * l_uint8 **lineptrs = (l_uint8 **)pixGetLinePtrs(pix, NULL);
1822 * pixGetDimensions(pix, &w, &h, NULL);
1823 * for (i = 0; i < h; i++) {
1824 * l_uint8 *line = lineptrs[i];
1825 * for (j = 0; j < w; j++) {
1826 * val = line[j];
1827 * ...
1828 * }
1829 * }
1830 * pixEndianByteSwap(pix); // restore big-endian order
1831 * LEPT_FREE(lineptrs);
1832 * This can be done even more simply as follows:
1833 * l_uint8 **lineptrs = pixSetupByteProcessing(pix, &w, &h);
1834 * for (i = 0; i < h; i++) {
1835 * l_uint8 *line = lineptrs[i];
1836 * for (j = 0; j < w; j++) {
1837 * val = line[j];
1838 * ...
1839 * }
1840 * }
1841 * pixCleanupByteProcessing(pix, lineptrs);
1842 * </pre>
1843 */
1844 void **
1845 pixGetLinePtrs(PIX *pix,
1846 l_int32 *psize)
1847 {
1848 l_int32 i, h, wpl;
1849 l_uint32 *data;
1850 void **lines;
1851
1852 if (psize) *psize = 0;
1853 if (!pix)
1854 return (void **)ERROR_PTR("pix not defined", __func__, NULL);
1855
1856 h = pixGetHeight(pix);
1857 if (psize) *psize = h;
1858 if ((lines = (void **)LEPT_CALLOC(h, sizeof(void *))) == NULL)
1859 return (void **)ERROR_PTR("lines not made", __func__, NULL);
1860 wpl = pixGetWpl(pix);
1861 data = pixGetData(pix);
1862 for (i = 0; i < h; i++)
1863 lines[i] = (void *)(data + i * wpl);
1864
1865 return lines;
1866 }
1867
1868
1869 /*--------------------------------------------------------------------*
1870 * Pix Size Comparisons *
1871 *--------------------------------------------------------------------*/
1872 /*!
1873 * \brief pixSizesEqual()
1874 *
1875 * \param[in] pix1, pix2
1876 * \return 1 if the two pix have same {h, w, d}; 0 otherwise.
1877 */
1878 l_int32
1879 pixSizesEqual(const PIX *pix1,
1880 const PIX *pix2)
1881 {
1882 if (!pix1 || !pix2)
1883 return ERROR_INT("pix1 and pix2 not both defined", __func__, 0);
1884
1885 if (pix1 == pix2)
1886 return 1;
1887
1888 if ((pixGetWidth(pix1) != pixGetWidth(pix2)) ||
1889 (pixGetHeight(pix1) != pixGetHeight(pix2)) ||
1890 (pixGetDepth(pix1) != pixGetDepth(pix2)))
1891 return 0;
1892 else
1893 return 1;
1894 }
1895
1896
1897 /*!
1898 * \brief pixMaxAspectRatio()
1899 *
1900 * \param[in] pixs 32 bpp rgb
1901 * \param[out] pratio max aspect ratio, >= 1.0; -1.0 on error
1902 * \return 0 if OK, 1 on error
1903 */
1904 l_ok
1905 pixMaxAspectRatio(PIX *pixs,
1906 l_float32 *pratio)
1907 {
1908 l_int32 w, h;
1909
1910 if (!pratio)
1911 return ERROR_INT("&ratio not defined", __func__, 1);
1912 *pratio = -1.0;
1913 if (!pixs)
1914 return ERROR_INT("pixs not defined", __func__, 1);
1915 pixGetDimensions(pixs, &w, &h, NULL);
1916 if (w == 0 || h == 0) {
1917 L_ERROR("invalid size: w = %d, h = %d\n", __func__, w, h);
1918 return 1;
1919 }
1920
1921 *pratio = L_MAX((l_float32)h / (l_float32)w, (l_float32)w / (l_float32)h);
1922 return 0;
1923 }
1924
1925
1926 /*--------------------------------------------------------------------*
1927 * Print output for debugging *
1928 *--------------------------------------------------------------------*/
1929 extern const char *ImageFileFormatExtensions[];
1930
1931 /*!
1932 * \brief pixPrintStreamInfo()
1933 *
1934 * \param[in] fp file stream
1935 * \param[in] pix
1936 * \param[in] text [optional] identifying string; can be null
1937 * \return 0 if OK, 1 on error
1938 */
1939 l_ok
1940 pixPrintStreamInfo(FILE *fp,
1941 const PIX *pix,
1942 const char *text)
1943 {
1944 l_int32 informat;
1945 const PIXCMAP *cmap;
1946
1947 if (!fp)
1948 return ERROR_INT("fp not defined", __func__, 1);
1949 if (!pix)
1950 return ERROR_INT("pix not defined", __func__, 1);
1951
1952 if (text)
1953 fprintf(fp, " Pix Info for %s:\n", text);
1954 fprintf(fp, " width = %d, height = %d, depth = %d, spp = %d\n",
1955 pixGetWidth(pix), pixGetHeight(pix), pixGetDepth(pix),
1956 pixGetSpp(pix));
1957 fprintf(fp, " wpl = %d, data = %p, refcount = %d\n",
1958 pixGetWpl(pix), pix->data, pix->refcount);
1959 fprintf(fp, " xres = %d, yres = %d\n", pixGetXRes(pix), pixGetYRes(pix));
1960 if ((cmap = pix->colormap) != NULL)
1961 pixcmapWriteStream(fp, cmap);
1962 else
1963 fprintf(fp, " no colormap\n");
1964 informat = pixGetInputFormat(pix);
1965 fprintf(fp, " input format: %d (%s)\n", informat,
1966 ImageFileFormatExtensions[informat]);
1967 if (pix->text != NULL)
1968 fprintf(fp, " text: %s\n", pix->text);
1969
1970 return 0;
1971 }