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