Leptonica 1.68
C Image Processing Library

pix1.c

Go to the documentation of this file.
00001 /*====================================================================*
00002  -  Copyright (C) 2001 Leptonica.  All rights reserved.
00003  -  This software is distributed in the hope that it will be
00004  -  useful, but with NO WARRANTY OF ANY KIND.
00005  -  No author or distributor accepts responsibility to anyone for the
00006  -  consequences of using this software, or for whether it serves any
00007  -  particular purpose or works at all, unless he or she says so in
00008  -  writing.  Everyone is granted permission to copy, modify and
00009  -  redistribute this source code, for commercial or non-commercial
00010  -  purposes, with the following restrictions: (1) the origin of this
00011  -  source code must not be misrepresented; (2) modified versions must
00012  -  be plainly marked as such; and (3) this notice may not be removed
00013  -  or altered from any source or modified source distribution.
00014  *====================================================================*/
00015 
00016 /*
00017  *  pix1.c
00018  *
00019  *    The pixN.c {N = 1,2,3,4,5} files are sorted by the type of operation.
00020  *    The primary functions in these files are:
00021  *
00022  *        pix1.c: constructors, destructors and field accessors
00023  *        pix2.c: pixel poking of image, pad and border pixels
00024  *        pix3.c: masking and logical ops, counting, mirrored tiling
00025  *        pix4.c: histograms, statistics, fg/bg estimation
00026  *        pix5.c: property measurements, rectangle extraction
00027  *
00028  *
00029  *    This file has the basic constructors, destructors and field accessors
00030  *
00031  *    Pix memory management (allows custom allocator and deallocator)
00032  *          static void  *pix_malloc()
00033  *          static void   pix_free()
00034  *          void          setPixMemoryManager()
00035  *
00036  *    Pix creation
00037  *          PIX          *pixCreate()
00038  *          PIX          *pixCreateNoInit()
00039  *          PIX          *pixCreateTemplate()
00040  *          PIX          *pixCreateTemplateNoInit()
00041  *          PIX          *pixCreateHeader()
00042  *          PIX          *pixClone()
00043  *
00044  *    Pix destruction
00045  *          void          pixDestroy()
00046  *          static void   pixFree()
00047  *
00048  *    Pix copy
00049  *          PIX          *pixCopy()
00050  *          l_int32       pixResizeImageData()
00051  *          l_int32       pixCopyColormap()
00052  *          l_int32       pixSizesEqual()
00053  *          l_int32       pixTransferAllData()
00054  *
00055  *    Pix accessors
00056  *          l_int32       pixGetWidth()
00057  *          l_int32       pixSetWidth()
00058  *          l_int32       pixGetHeight()
00059  *          l_int32       pixSetHeight()
00060  *          l_int32       pixGetDepth()
00061  *          l_int32       pixSetDepth()
00062  *          l_int32       pixGetDimensions()
00063  *          l_int32       pixSetDimensions()
00064  *          l_int32       pixCopyDimensions()
00065  *          l_int32       pixGetWpl()
00066  *          l_int32       pixSetWpl()
00067  *          l_int32       pixGetRefcount()
00068  *          l_int32       pixChangeRefcount()
00069  *          l_uint32      pixGetXRes()
00070  *          l_int32       pixSetXRes()
00071  *          l_uint32      pixGetYRes()
00072  *          l_int32       pixSetYRes()
00073  *          l_int32       pixGetResolution()
00074  *          l_int32       pixSetResolution()
00075  *          l_int32       pixCopyResolution()
00076  *          l_int32       pixScaleResolution()
00077  *          l_int32       pixGetInputFormat()
00078  *          l_int32       pixSetInputFormat()
00079  *          l_int32       pixCopyInputFormat()
00080  *          char         *pixGetText()
00081  *          l_int32       pixSetText()
00082  *          l_int32       pixAddText()
00083  *          l_int32       pixCopyText()
00084  *          PIXCMAP      *pixGetColormap()
00085  *          l_int32       pixSetColormap()
00086  *          l_int32       pixDestroyColormap()
00087  *          l_uint32     *pixGetData()
00088  *          l_int32       pixSetData()
00089  *          l_uint32     *pixExtractData()
00090  *          l_int32       pixFreeData()
00091  *
00092  *    Pix line ptrs
00093  *          void        **pixGetLinePtrs()
00094  *
00095  *    Pix debug
00096  *          l_int32       pixPrintStreamInfo()
00097  *
00098  *
00099  *  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00100  *      Important notes on direct management of pix image data 
00101  *  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00102  *
00103  *  Custom allocator and deallocator
00104  *  --------------------------------
00105  *
00106  *  At the lowest level, you can specify the function that does the
00107  *  allocation and deallocation of the data field in the pix.
00108  *  By default, this is malloc and free.  However, by calling
00109  *  setPixMemoryManager(), custom functions can be substituted.
00110  *  When using this, keep two things in mind:
00111  *
00112  *   (1) Call setPixMemoryManager() before any pix have been allocated
00113  *   (2) Destroy all pix as usual, in order to prevent leaks.
00114  *
00115  *  In pixalloc.c, we provide an example custom allocator and deallocator.
00116  *  To use it, you must call pmsCreate() before any pix have been allocated
00117  *  and pmsDestroy() at the end after all pix have been destroyed.
00118  *
00119  *
00120  *  Direct manipulation of the pix data field
00121  *  -----------------------------------------
00122  *
00123  *  Memory management of the (image) data field in the pix is
00124  *  handled differently from that in the colormap or text fields.
00125  *  For colormap and text, the functions pixSetColormap() and
00126  *  pixSetText() remove the existing heap data and insert the
00127  *  new data.  For the image data, pixSetData() just reassigns the
00128  *  data field; any existing data will be lost if there isn't
00129  *  another handle for it.
00130  *
00131  *  Why is pixSetData() limited in this way?  Because the image
00132  *  data can be very large, we need flexible ways to handle it,
00133  *  particularly when you want to re-use the data in a different
00134  *  context without making a copy.  Here are some different
00135  *  things you might want to do:
00136  *
00137  *  (1) Use pixCopy(pixd, pixs) where pixd is not the same size
00138  *      as pixs.  This will remove the data in pixd, allocate a
00139  *      new data field in pixd, and copy the data from pixs, leaving
00140  *      pixs unchanged.
00141  *
00142  *  (2) Use pixTransferAllData(pixd, &pixs, ...) to transfer the
00143  *      data from pixs to pixd without making a copy of it.  If
00144  *      pixs is not cloned, this will do the transfer and destroy pixs.
00145  *      But if the refcount of pixs is greater than 1, it just copies
00146  *      the data and decrements the ref count.
00147  *
00148  *  (3) Use pixExtractData() to extract the image data from the pix
00149  *      without copying if possible.  This could be used, for example,
00150  *      to convert from a pix to some other data structure with minimal
00151  *      heap allocation.  After the data is extracated, the pixels can
00152  *      be munged and used in another context.  However, the danger
00153  *      here is that the pix might have a refcount > 1, in which case
00154  *      a copy of the data must be made and the input pix left unchanged.
00155  *      If there are no clones, the image data can be extracted without
00156  *      a copy, and the data ptr in the pix must be nulled before
00157  *      destroying it because the pix will no longer 'own' the data.
00158  *
00159  *  We have provided accessors and functions here that should be
00160  *  sufficient so that you can do anything you want without
00161  *  explicitly referencing any of the pix member fields.
00162  *
00163  *  However, to avoid memory smashes and leaks when doing special operations
00164  *  on the pix data field, look carefully at the behavior of the image
00165  *  data accessors and keep in mind that when you invoke pixDestroy(),
00166  *  the pix considers itself the owner of all its heap data.
00167  */
00168 
00169 #include <stdio.h>
00170 #include <stdlib.h>
00171 #include <string.h>
00172 #include "allheaders.h"
00173 
00174 static void pixFree(PIX *pix);
00175 
00176 
00177 /*-------------------------------------------------------------------------*
00178  *                        Pix Memory Management                            *
00179  *                                                                         *
00180  *  These functions give you the freedom to specify at compile or run      *
00181  *  time the allocator and deallocator to be used for pix.  It has no      *
00182  *  effect on memory management for other data structs, which are          *
00183  *  controlled by the #defines in environ.h.  Likewise, the #defines       *
00184  *  in environ.h have no effect on the pix memory management.              *
00185  *  The default functions are malloc and free.  Use setPixMemoryManager()  *
00186  *  to specify other functions to use.                                     *
00187  *-------------------------------------------------------------------------*/
00188 struct PixMemoryManager
00189 {
00190     void     *(*allocator)(size_t);
00191     void      (*deallocator)(void *);
00192 };
00193 
00194 static struct PixMemoryManager  pix_mem_manager = {
00195     &malloc,
00196     &free
00197 };
00198     
00199 static void *
00200 pix_malloc(size_t  size)
00201 {
00202 #ifndef _MSC_VER
00203     return (*pix_mem_manager.allocator)(size);
00204 #else  /* _MSC_VER */
00205     /* Under MSVC++, pix_mem_manager is initialized after a call
00206      * to pix_malloc.  Just ignore the custom allocator feature. */
00207     return malloc(size);
00208 #endif  /* _MSC_VER */
00209 }
00210 
00211 static void
00212 pix_free(void  *ptr)
00213 {
00214 #ifndef _MSC_VER
00215     (*pix_mem_manager.deallocator)(ptr);
00216     return;
00217 #else  /* _MSC_VER */
00218     /* Under MSVC++, pix_mem_manager is initialized after a call
00219      * to pix_malloc.  Just ignore the custom allocator feature. */
00220     free(ptr);
00221     return;
00222 #endif  /* _MSC_VER */
00223 }
00224 
00225 /*!
00226  *  setPixMemoryManager()
00227  *
00228  *      Input: allocator (<optional>; use null to skip)
00229  *             deallocator (<optional>; use null to skip)
00230  *      Return: void
00231  *
00232  *  Notes:
00233  *      (1) Use this to change the alloc and/or dealloc functions;
00234  *          e.g., setPixMemoryManager(my_malloc, my_free).
00235  */
00236 #ifndef _MSC_VER
00237 void
00238 setPixMemoryManager(void  *(allocator(size_t)),
00239                     void  (deallocator(void *)))
00240 {
00241     if (allocator) pix_mem_manager.allocator = allocator;
00242     if (deallocator) pix_mem_manager.deallocator = deallocator;
00243     return;
00244 }
00245 #else  /* _MSC_VER */
00246     /* MSVC++ wants type (*fun)(types...) syntax */
00247 void
00248 setPixMemoryManager(void  *((*allocator)(size_t)),
00249                     void  ((*deallocator)(void *)))
00250 {
00251     if (allocator) pix_mem_manager.allocator = allocator;
00252     if (deallocator) pix_mem_manager.deallocator = deallocator;
00253     return;
00254 }
00255 #endif /* _MSC_VER */
00256 
00257 
00258 /*--------------------------------------------------------------------*
00259  *                              Pix Creation                          *
00260  *--------------------------------------------------------------------*/
00261 /*!
00262  *  pixCreate()
00263  *
00264  *      Input:  width, height, depth
00265  *      Return: pixd (with data allocated and initialized to 0),
00266  *                    or null on error
00267  */
00268 PIX *
00269 pixCreate(l_int32  width,
00270           l_int32  height,
00271           l_int32  depth)
00272 {
00273 PIX  *pixd;
00274 
00275     PROCNAME("pixCreate");
00276 
00277     if ((pixd = pixCreateNoInit(width, height, depth)) == NULL)
00278         return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
00279     memset(pixd->data, 0, 4 * pixd->wpl * pixd->h);
00280     return pixd;
00281 }
00282 
00283 
00284 /*!
00285  *  pixCreateNoInit()
00286  *
00287  *      Input:  width, height, depth
00288  *      Return: pixd (with data allocated but not initialized),
00289  *                    or null on error
00290  *
00291  *  Notes:
00292  *      (1) Must set pad bits to avoid reading unitialized data, because
00293  *          some optimized routines (e.g., pixConnComp()) read from pad bits.
00294  */
00295 PIX *
00296 pixCreateNoInit(l_int32  width,
00297                 l_int32  height,
00298                 l_int32  depth)
00299 {
00300 l_int32    wpl;
00301 PIX       *pixd;
00302 l_uint32  *data;
00303 
00304     PROCNAME("pixCreateNoInit");
00305     if ((pixd = pixCreateHeader(width, height, depth)) == NULL)
00306         return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
00307     wpl = pixGetWpl(pixd);
00308     if ((data = (l_uint32 *)pix_malloc(4 * wpl * height)) == NULL)
00309         return (PIX *)ERROR_PTR("pix_malloc fail for data", procName, NULL);
00310     pixSetData(pixd, data);
00311     pixSetPadBits(pixd, 0);
00312     return pixd;
00313 }
00314 
00315 
00316 /*!
00317  *  pixCreateTemplate()
00318  *
00319  *      Input:  pixs
00320  *      Return: pixd, or null on error
00321  *
00322  *  Notes:
00323  *      (1) Makes a Pix of the same size as the input Pix, with the
00324  *          data array allocated and initialized to 0.
00325  *      (2) Copies the other fields, including colormap if it exists.
00326  */
00327 PIX *
00328 pixCreateTemplate(PIX  *pixs)
00329 {
00330 PIX  *pixd;
00331 
00332     PROCNAME("pixCreateTemplate");
00333 
00334     if (!pixs)
00335         return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
00336 
00337     if ((pixd = pixCreateTemplateNoInit(pixs)) == NULL)
00338         return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
00339     memset(pixd->data, 0, 4 * pixd->wpl * pixd->h);
00340     return pixd;
00341 }
00342 
00343 
00344 /*!
00345  *  pixCreateTemplateNoInit()
00346  *
00347  *      Input:  pixs
00348  *      Return: pixd, or null on error
00349  *
00350  *  Notes:
00351  *      (1) Makes a Pix of the same size as the input Pix, with
00352  *          the data array allocated but not initialized to 0.
00353  *      (2) Copies the other fields, including colormap if it exists.
00354  */
00355 PIX *
00356 pixCreateTemplateNoInit(PIX  *pixs)
00357 {
00358 l_int32  w, h, d;
00359 PIX     *pixd;
00360 
00361     PROCNAME("pixCreateTemplateNoInit");
00362 
00363     if (!pixs)
00364         return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
00365 
00366     pixGetDimensions(pixs, &w, &h, &d);
00367     if ((pixd = pixCreateNoInit(w, h, d)) == NULL)
00368         return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
00369     pixCopyResolution(pixd, pixs);
00370     pixCopyColormap(pixd, pixs);
00371     pixCopyText(pixd, pixs);
00372     pixCopyInputFormat(pixd, pixs);
00373 
00374     return pixd;
00375 }
00376 
00377 
00378 /*!
00379  *  pixCreateHeader()
00380  *
00381  *      Input:  width, height, depth
00382  *      Return: pixd (with no data allocated), or null on error
00383  */
00384 PIX *
00385 pixCreateHeader(l_int32  width,
00386                 l_int32  height,
00387                 l_int32  depth)
00388 {
00389 l_int32  wpl;
00390 PIX     *pixd;
00391 
00392     PROCNAME("pixCreateHeader");
00393 
00394     if ((depth != 1) && (depth != 2) && (depth != 4) && (depth != 8)
00395          && (depth != 16) && (depth != 24) && (depth != 32))
00396         return (PIX *)ERROR_PTR("depth must be {1, 2, 4, 8, 16, 24, 32}",
00397                                 procName, NULL);
00398     if (width <= 0)
00399         return (PIX *)ERROR_PTR("width must be > 0", procName, NULL);
00400     if (height <= 0)
00401         return (PIX *)ERROR_PTR("height must be > 0", procName, NULL);
00402 
00403     if ((pixd = (PIX *)CALLOC(1, sizeof(PIX))) == NULL)
00404         return (PIX *)ERROR_PTR("CALLOC fail for pixd", procName, NULL);
00405     pixSetWidth(pixd, width);
00406     pixSetHeight(pixd, height);
00407     pixSetDepth(pixd, depth);
00408     wpl = (width * depth + 31) / 32;
00409     pixSetWpl(pixd, wpl);
00410 
00411     pixd->refcount = 1;
00412     pixd->informat = IFF_UNKNOWN;
00413     return pixd;
00414 }
00415 
00416 
00417 /*!
00418  *  pixClone()
00419  *
00420  *      Input:  pix
00421  *      Return: same pix (ptr), or null on error
00422  *
00423  *  Notes:
00424  *      (1) A "clone" is simply a handle (ptr) to an existing pix.
00425  *          It is implemented because (a) images can be large and
00426  *          hence expensive to copy, and (b) extra handles to a data
00427  *          structure need to be made with a simple policy to avoid
00428  *          both double frees and memory leaks.  Pix are reference
00429  *          counted.  The side effect of pixClone() is an increase
00430  *          by 1 in the ref count.
00431  *      (2) The protocol to be used is:
00432  *          (a) Whenever you want a new handle to an existing image,
00433  *              call pixClone(), which just bumps a ref count.
00434  *          (b) Always call pixDestroy() on all handles.  This
00435  *              decrements the ref count, nulls the handle, and
00436  *              only destroys the pix when pixDestroy() has been
00437  *              called on all handles.
00438  */
00439 PIX *
00440 pixClone(PIX  *pixs)
00441 {
00442     PROCNAME("pixClone");
00443 
00444     if (!pixs)
00445         return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
00446     pixChangeRefcount(pixs, 1);
00447 
00448     return pixs;
00449 }
00450 
00451 
00452 /*--------------------------------------------------------------------*
00453  *                           Pix Destruction                          *
00454  *--------------------------------------------------------------------*/
00455 /*!
00456  *  pixDestroy()
00457  *
00458  *      Input:  &pix <will be nulled>
00459  *      Return: void
00460  *
00461  *  Notes:
00462  *      (1) Decrements the ref count and, if 0, destroys the pix.
00463  *      (2) Always nulls the input ptr.
00464  */
00465 void
00466 pixDestroy(PIX  **ppix)
00467 {
00468 PIX  *pix;
00469 
00470     PROCNAME("pixDestroy");
00471 
00472     if (!ppix) {
00473         L_WARNING("ptr address is null!", procName);
00474         return;
00475     }
00476 
00477     if ((pix = *ppix) == NULL)
00478         return;
00479 
00480     pixFree(pix);
00481     *ppix = NULL;
00482     return;
00483 }
00484 
00485 
00486 /*!
00487  *  pixFree()
00488  *
00489  *      Input:  pix
00490  *      Return: void
00491  *
00492  *  Notes:
00493  *      (1) Decrements the ref count and, if 0, destroys the pix.
00494  */
00495 static void
00496 pixFree(PIX  *pix)
00497 {
00498 l_uint32  *data;
00499 char      *text;
00500 
00501     if (!pix) return;
00502 
00503     pixChangeRefcount(pix, -1);
00504     if (pixGetRefcount(pix) <= 0) {
00505         if ((data = pixGetData(pix)) != NULL)
00506             pix_free(data);
00507         if ((text = pixGetText(pix)) != NULL)
00508             FREE(text);
00509         pixDestroyColormap(pix);
00510         FREE(pix);
00511     }
00512     return;
00513 }
00514 
00515 
00516 /*-------------------------------------------------------------------------*
00517  *                                 Pix Copy                                *
00518  *-------------------------------------------------------------------------*/
00519 /*!
00520  *  pixCopy()
00521  *
00522  *      Input:  pixd (<optional>; can be null, or equal to pixs,
00523  *                    or different from pixs)
00524  *              pixs
00525  *      Return: pixd, or null on error
00526  *
00527  *  Notes:
00528  *      (1) There are three cases:
00529  *            (a) pixd == null  (makes a new pix; refcount = 1)
00530  *            (b) pixd == pixs  (no-op)
00531  *            (c) pixd != pixs  (data copy; no change in refcount)
00532  *          If the refcount of pixd > 1, case (c) will side-effect
00533  *          these handles.
00534  *      (2) The general pattern of use is:
00535  *             pixd = pixCopy(pixd, pixs);
00536  *          This will work for all three cases.
00537  *          For clarity when the case is known, you can use:
00538  *            (a) pixd = pixCopy(NULL, pixs);
00539  *            (c) pixCopy(pixd, pixs);
00540  *      (3) For case (c), we check if pixs and pixd are the same
00541  *          size (w,h,d).  If so, the data is copied directly.
00542  *          Otherwise, the data is reallocated to the correct size
00543  *          and the copy proceeds.  The refcount of pixd is unchanged.
00544  *      (4) This operation, like all others that may involve a pre-existing
00545  *          pixd, will side-effect any existing clones of pixd.
00546  */
00547 PIX *
00548 pixCopy(PIX  *pixd,   /* can be null */
00549         PIX  *pixs)
00550 {
00551 l_int32    bytes;
00552 l_uint32  *datas, *datad;
00553 
00554     PROCNAME("pixCopy");
00555 
00556     if (!pixs)
00557         return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
00558     if (pixs == pixd)
00559         return pixd;
00560 
00561         /* Total bytes in image data */
00562     bytes = 4 * pixGetWpl(pixs) * pixGetHeight(pixs);
00563 
00564         /* If we're making a new pix ... */
00565     if (!pixd) {
00566         if ((pixd = pixCreateTemplate(pixs)) == NULL)
00567             return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
00568         datas = pixGetData(pixs);
00569         datad = pixGetData(pixd);
00570         memcpy((char *)datad, (char *)datas, bytes);
00571         return pixd;
00572     }
00573 
00574         /* Reallocate image data if sizes are different */
00575     if (pixResizeImageData(pixd, pixs) == 1)
00576         return (PIX *)ERROR_PTR("reallocation of data failed", procName, NULL);
00577 
00578         /* Copy non-image data fields */
00579     pixCopyColormap(pixd, pixs);
00580     pixCopyResolution(pixd, pixs);
00581     pixCopyInputFormat(pixd, pixs);
00582     pixCopyText(pixd, pixs);
00583 
00584         /* Copy image data */
00585     datas = pixGetData(pixs);
00586     datad = pixGetData(pixd);
00587     memcpy((char*)datad, (char*)datas, bytes);
00588     return pixd;
00589 }
00590 
00591 
00592 /*!
00593  *  pixResizeImageData()
00594  *
00595  *      Input:  pixd (gets new uninitialized buffer for image data)
00596  *              pixs (determines the size of the buffer; not changed)
00597  *      Return: 0 if OK, 1 on error
00598  *
00599  *  Notes:
00600  *      (1) This removes any existing image data from pixd and
00601  *          allocates an uninitialized buffer that will hold the
00602  *          amount of image data that is in pixs.
00603  */
00604 l_int32
00605 pixResizeImageData(PIX  *pixd,
00606                    PIX  *pixs)
00607 {
00608 l_int32    w, h, d, wpl, bytes;
00609 l_uint32  *data;
00610 
00611     PROCNAME("pixResizeImageData");
00612 
00613     if (!pixs)
00614         return ERROR_INT("pixs not defined", procName, 1);
00615     if (!pixd)
00616         return ERROR_INT("pixd not defined", procName, 1);
00617 
00618     if (pixSizesEqual(pixs, pixd))  /* nothing to do */
00619         return 0;
00620 
00621     pixGetDimensions(pixs, &w, &h, &d);
00622     wpl = pixGetWpl(pixs);
00623     pixSetWidth(pixd, w);
00624     pixSetHeight(pixd, h);
00625     pixSetDepth(pixd, d);
00626     pixSetWpl(pixd, wpl);
00627     bytes = 4 * wpl * h;
00628     pixFreeData(pixd);  /* free any existing image data */
00629     if ((data = (l_uint32 *)pix_malloc(bytes)) == NULL)
00630         return ERROR_INT("pix_malloc fail for data", procName, 1);
00631     pixSetData(pixd, data);
00632     return 0;
00633 }
00634 
00635 
00636 /*!
00637  *  pixCopyColormap()
00638  *
00639  *      Input:  src and dest Pix
00640  *      Return: 0 if OK, 1 on error
00641  *
00642  *  Notes:
00643  *      (1) This always destroys any colormap in pixd (except if
00644  *          the operation is a no-op.
00645  */
00646 l_int32
00647 pixCopyColormap(PIX  *pixd,
00648                 PIX  *pixs)
00649 {
00650 PIXCMAP  *cmaps, *cmapd;
00651 
00652     PROCNAME("pixCopyColormap");
00653 
00654     if (!pixs)
00655         return ERROR_INT("pixs not defined", procName, 1);
00656     if (!pixd)
00657         return ERROR_INT("pixd not defined", procName, 1);
00658     if (pixs == pixd)
00659         return 0;   /* no-op */
00660 
00661     pixDestroyColormap(pixd);
00662     if ((cmaps = pixGetColormap(pixs)) == NULL)  /* not an error */
00663         return 0;
00664 
00665     if ((cmapd = pixcmapCopy(cmaps)) == NULL)
00666         return ERROR_INT("cmapd not made", procName, 1);
00667     pixSetColormap(pixd, cmapd);
00668 
00669     return 0;
00670 }
00671 
00672 
00673 /*!
00674  *  pixSizesEqual()
00675  *
00676  *      Input:  two pix
00677  *      Return: 1 if the two pix have same {h, w, d}; 0 otherwise.
00678  */
00679 l_int32
00680 pixSizesEqual(PIX  *pix1,
00681               PIX  *pix2)
00682 {
00683     PROCNAME("pixSizesEqual");
00684 
00685     if (!pix1 || !pix2)
00686         return ERROR_INT("pix1 and pix2 not both defined", procName, 0);
00687 
00688     if (pix1 == pix2)
00689         return 1;
00690 
00691     if ((pixGetWidth(pix1) != pixGetWidth(pix2)) ||
00692         (pixGetHeight(pix1) != pixGetHeight(pix2)) ||
00693         (pixGetDepth(pix1) != pixGetDepth(pix2)))
00694         return 0;
00695     else
00696         return 1;
00697 }
00698 
00699 
00700 /*!
00701  *  pixTransferAllData()
00702  *
00703  *      Input:  pixd (must be different from pixs)
00704  *              &pixs (will be nulled if refcount goes to 0)
00705  *              copytext (1 to copy the text field; 0 to skip)
00706  *              copyformat (1 to copy the informat field; 0 to skip)
00707  *      Return: 0 if OK, 1 on error
00708  *
00709  *  Notes:
00710  *      (1) This does a complete data transfer from pixs to pixd,
00711  *          followed by the destruction of pixs (refcount permitting).
00712  *      (2) If the refcount of pixs is 1, pixs is destroyed.  Otherwise,
00713  *          the data in pixs is copied (rather than transferred) to pixd.
00714  *      (3) This operation, like all others with a pre-existing pixd,
00715  *          will side-effect any existing clones of pixd.  The pixd
00716  *          refcount does not change.
00717  *      (4) When might you use this?  Suppose you have an in-place Pix
00718  *          function (returning void) with the typical signature:
00719  *              void function-inplace(PIX *pix, ...)
00720  *          where "..." are non-pointer input parameters, and suppose
00721  *          further that you sometimes want to return an arbitrary Pix
00722  *          in place of the input Pix.  There are two ways you can do this:
00723  *          (a) The straightforward way is to change the function
00724  *              signature to take the address of the Pix ptr:
00725  *                  void function-inplace(PIX **ppix, ...) {
00726  *                      PIX *pixt = function-makenew(*ppix);
00727  *                      pixDestroy(ppix);
00728  *                      *ppix = pixt;
00729  *                      return;
00730  *                  }
00731  *              Here, the input and returned pix are different, as viewed
00732  *              by the calling function, and the inplace function is
00733  *              expected to destroy the input pix to avoid a memory leak.
00734  *          (b) Keep the signature the same and use pixTransferAllData()
00735  *              to return the new Pix in the input Pix struct:
00736  *                  void function-inplace(PIX *pix, ...) {
00737  *                      PIX *pixt = function-makenew(pix);
00738  *                      pixTransferAllData(pix, &pixt, 0, 0);
00739  *                               // pixDestroy() is called on pixt
00740  *                      return;
00741  *                  }
00742  *              Here, the input and returned pix are the same, as viewed
00743  *              by the calling function, and the inplace function must
00744  *              never destroy the input pix, because the calling function
00745  *              maintains an unchanged handle to it.
00746  */
00747 l_int32
00748 pixTransferAllData(PIX     *pixd,
00749                    PIX    **ppixs,
00750                    l_int32  copytext,
00751                    l_int32  copyformat)
00752 {
00753 l_int32  nbytes;
00754 PIX     *pixs;
00755 
00756     PROCNAME("pixTransferAllData");
00757 
00758     if (!ppixs)
00759         return ERROR_INT("&pixs not defined", procName, 1);
00760     if ((pixs = *ppixs) == NULL)
00761         return ERROR_INT("pixs not defined", procName, 1);
00762     if (!pixd)
00763         return ERROR_INT("pixd not defined", procName, 1);
00764     if (pixs == pixd)  /* no-op */
00765         return ERROR_INT("pixd == pixs", procName, 1);
00766 
00767     if (pixGetRefcount(pixs) == 1) {  /* transfer the data, cmap, text */
00768         pixFreeData(pixd);  /* dealloc any existing data */
00769         pixSetData(pixd, pixGetData(pixs));  /* transfer new data from pixs */
00770         pixs->data = NULL;  /* pixs no longer owns data */
00771         pixSetColormap(pixd, pixGetColormap(pixs));  /* frees old; sets new */
00772         pixs->colormap = NULL;  /* pixs no longer owns colormap */
00773         if (copytext) {
00774             pixSetText(pixd, pixGetText(pixs));
00775             pixSetText(pixs, NULL);
00776         }
00777     } else {  /* preserve pixs by making a copy of the data, cmap, text */
00778         pixResizeImageData(pixd, pixs);
00779         nbytes = 4 * pixGetWpl(pixs) * pixGetHeight(pixs);
00780         memcpy((char *)pixGetData(pixd), (char *)pixGetData(pixs), nbytes);
00781         pixCopyColormap(pixd, pixs);
00782         if (copytext)
00783             pixCopyText(pixd, pixs);
00784     }
00785   
00786     pixCopyResolution(pixd, pixs);
00787     pixCopyDimensions(pixd, pixs);
00788     if (copyformat)
00789         pixCopyInputFormat(pixd, pixs);
00790 
00791         /* This will destroy pixs if data was transferred;
00792          * otherwise, it just decrements its refcount. */
00793     pixDestroy(ppixs);
00794     return 0;
00795 }
00796         
00797 
00798 
00799 /*--------------------------------------------------------------------*
00800  *                                Accessors                           *
00801  *--------------------------------------------------------------------*/
00802 l_int32
00803 pixGetWidth(PIX  *pix)
00804 {
00805     PROCNAME("pixGetWidth");
00806 
00807     if (!pix)
00808         return ERROR_INT("pix not defined", procName, UNDEF);
00809 
00810     return pix->w;
00811 }
00812 
00813 
00814 l_int32
00815 pixSetWidth(PIX     *pix,
00816             l_int32  width)
00817 {
00818     PROCNAME("pixSetWidth");
00819 
00820     if (!pix)
00821         return ERROR_INT("pix not defined", procName, 1);
00822     if (width < 0) {
00823         pix->w = 0;
00824         return ERROR_INT("width must be >= 0", procName, 1);
00825     }
00826 
00827     pix->w = width;
00828     return 0;
00829 }
00830 
00831 
00832 l_int32
00833 pixGetHeight(PIX  *pix)
00834 {
00835     PROCNAME("pixGetHeight");
00836 
00837     if (!pix)
00838         return ERROR_INT("pix not defined", procName, UNDEF);
00839 
00840     return pix->h;
00841 }
00842 
00843 
00844 l_int32
00845 pixSetHeight(PIX     *pix,
00846              l_int32  height)
00847 {
00848     PROCNAME("pixSetHeight");
00849 
00850     if (!pix)
00851         return ERROR_INT("pix not defined", procName, 1);
00852     if (height < 0) {
00853         pix->h = 0;
00854         return ERROR_INT("h must be >= 0", procName, 1);
00855     }
00856 
00857     pix->h = height;
00858     return 0;
00859 }
00860 
00861 
00862 l_int32
00863 pixGetDepth(PIX  *pix)
00864 {
00865     PROCNAME("pixGetDepth");
00866 
00867     if (!pix)
00868         return ERROR_INT("pix not defined", procName, UNDEF);
00869 
00870     return pix->d;
00871 }
00872 
00873 
00874 l_int32
00875 pixSetDepth(PIX     *pix,
00876             l_int32  depth)
00877 {
00878     PROCNAME("pixSetDepth");
00879 
00880     if (!pix)
00881         return ERROR_INT("pix not defined", procName, 1);
00882     if (depth < 1)
00883         return ERROR_INT("d must be >= 1", procName, 1);
00884 
00885     pix->d = depth;
00886     return 0;
00887 }
00888 
00889 
00890 /*!
00891  *  pixGetDimensions()
00892  *
00893  *      Input:  pix
00894  *              &w, &h, &d (<optional return>; each can be null)
00895  *      Return: 0 if OK, 1 on error
00896  */
00897 l_int32
00898 pixGetDimensions(PIX      *pix,
00899                  l_int32  *pw,
00900                  l_int32  *ph,
00901                  l_int32  *pd)
00902 {
00903     PROCNAME("pixGetDimensions");
00904 
00905     if (pw) *pw = 0;
00906     if (ph) *ph = 0;
00907     if (pd) *pd = 0;
00908     if (!pix)
00909         return ERROR_INT("pix not defined", procName, 1);
00910     if (pw) *pw = pix->w;
00911     if (ph) *ph = pix->h;
00912     if (pd) *pd = pix->d;
00913     return 0;
00914 }
00915 
00916 
00917 /*!
00918  *  pixSetDimensions()
00919  *
00920  *      Input:  pix
00921  *              w, h, d (use 0 to skip the setting for any of these)
00922  *      Return: 0 if OK, 1 on error
00923  */
00924 l_int32
00925 pixSetDimensions(PIX     *pix,
00926                  l_int32  w,
00927                  l_int32  h,
00928                  l_int32  d)
00929 {
00930     PROCNAME("pixSetDimensions");
00931 
00932     if (!pix)
00933         return ERROR_INT("pix not defined", procName, 1);
00934     if (w > 0) pixSetWidth(pix, w);
00935     if (h > 0) pixSetHeight(pix, h);
00936     if (d > 0) pixSetDepth(pix, d);
00937     return 0;
00938 }
00939 
00940 
00941 /*!
00942  *  pixCopyDimensions()
00943  *
00944  *      Input:  pixd
00945  *              pixd
00946  *      Return: 0 if OK, 1 on error
00947  */
00948 l_int32
00949 pixCopyDimensions(PIX  *pixd,
00950                   PIX  *pixs)
00951 {
00952     PROCNAME("pixCopyDimensions");
00953 
00954     if (!pixd)
00955         return ERROR_INT("pixd not defined", procName, 1);
00956     if (!pixs)
00957         return ERROR_INT("pixs not defined", procName, 1);
00958     if (pixs == pixd)
00959         return 0;   /* no-op */
00960 
00961     pixSetWidth(pixd, pixGetWidth(pixs));
00962     pixSetHeight(pixd, pixGetHeight(pixs));
00963     pixSetDepth(pixd, pixGetDepth(pixs));
00964     pixSetWpl(pixd, pixGetWpl(pixs));
00965     return 0;
00966 }
00967 
00968 
00969 l_int32
00970 pixGetWpl(PIX  *pix)
00971 {
00972     PROCNAME("pixGetWpl");
00973 
00974     if (!pix)
00975         return ERROR_INT("pix not defined", procName, UNDEF);
00976     return pix->wpl;
00977 }
00978 
00979 
00980 l_int32
00981 pixSetWpl(PIX     *pix,
00982           l_int32  wpl)
00983 {
00984     PROCNAME("pixSetWpl");
00985 
00986     if (!pix)
00987         return ERROR_INT("pix not defined", procName, 1);
00988 
00989     pix->wpl = wpl;
00990     return 0;
00991 }
00992 
00993 
00994 l_int32
00995 pixGetRefcount(PIX  *pix)
00996 {
00997     PROCNAME("pixGetRefcount");
00998 
00999     if (!pix)
01000         return ERROR_INT("pix not defined", procName, UNDEF);
01001     return pix->refcount;
01002 }
01003 
01004 
01005 l_int32
01006 pixChangeRefcount(PIX     *pix,
01007                   l_int32  delta)
01008 {
01009     PROCNAME("pixChangeRefcount");
01010 
01011     if (!pix)
01012         return ERROR_INT("pix not defined", procName, 1);
01013 
01014     pix->refcount += delta;
01015     return 0;
01016 }
01017 
01018 
01019 l_int32
01020 pixGetXRes(PIX  *pix)
01021 {
01022     PROCNAME("pixGetXRes");
01023 
01024     if (!pix)
01025         return ERROR_INT("pix not defined", procName, 0);
01026     return pix->xres;
01027 }
01028 
01029 
01030 l_int32
01031 pixSetXRes(PIX     *pix,
01032            l_int32  res)
01033 {
01034     PROCNAME("pixSetXRes");
01035 
01036     if (!pix)
01037         return ERROR_INT("pix not defined", procName, 1);
01038 
01039     pix->xres = res;
01040     return 0;
01041 }
01042 
01043 
01044 l_int32
01045 pixGetYRes(PIX  *pix)
01046 {
01047     PROCNAME("pixGetYRes");
01048 
01049     if (!pix)
01050         return ERROR_INT("pix not defined", procName, 0);
01051     return pix->yres;
01052 }
01053 
01054 
01055 l_int32
01056 pixSetYRes(PIX     *pix,
01057            l_int32  res)
01058 {
01059     PROCNAME("pixSetYRes");
01060 
01061     if (!pix)
01062         return ERROR_INT("pix not defined", procName, 1);
01063 
01064     pix->yres = res;
01065     return 0;
01066 }
01067 
01068 
01069 /*!
01070  *  pixGetResolution()
01071  *
01072  *      Input:  pix
01073  *              &xres, &yres (<optional return>; each can be null)
01074  *      Return: 0 if OK, 1 on error
01075  */
01076 l_int32
01077 pixGetResolution(PIX      *pix,
01078                  l_int32  *pxres,
01079                  l_int32  *pyres)
01080 {
01081     PROCNAME("pixGetResolution");
01082 
01083     if (!pix)
01084         return ERROR_INT("pix not defined", procName, 1);
01085     if (pxres) *pxres = pix->xres;
01086     if (pyres) *pyres = pix->yres;
01087     return 0;
01088 }
01089 
01090 
01091 /*!
01092  *  pixSetResolution()
01093  *
01094  *      Input:  pix
01095  *              xres, yres (use 0 to skip the setting for either of these)
01096  *      Return: 0 if OK, 1 on error
01097  */
01098 l_int32
01099 pixSetResolution(PIX     *pix,
01100                  l_int32  xres,
01101                  l_int32  yres)
01102 {
01103     PROCNAME("pixSetResolution");
01104 
01105     if (!pix)
01106         return ERROR_INT("pix not defined", procName, 1);
01107     if (xres > 0) pix->xres = xres;
01108     if (yres > 0) pix->yres = yres;
01109     return 0;
01110 }
01111 
01112 
01113 l_int32
01114 pixCopyResolution(PIX  *pixd,
01115                   PIX  *pixs)
01116 {
01117     PROCNAME("pixCopyResolution");
01118 
01119     if (!pixs)
01120         return ERROR_INT("pixs not defined", procName, 1);
01121     if (!pixd)
01122         return ERROR_INT("pixd not defined", procName, 1);
01123     if (pixs == pixd)
01124         return 0;   /* no-op */
01125 
01126     pixSetXRes(pixd, pixGetXRes(pixs));
01127     pixSetYRes(pixd, pixGetYRes(pixs));
01128     return 0;
01129 }
01130 
01131 
01132 l_int32
01133 pixScaleResolution(PIX       *pix,
01134                    l_float32  xscale,
01135                    l_float32  yscale)
01136 {
01137     PROCNAME("pixScaleResolution");
01138 
01139     if (!pix)
01140         return ERROR_INT("pix not defined", procName, 1);
01141 
01142     if (pix->xres != 0 && pix->yres != 0) {
01143         pix->xres = (l_uint32)(xscale * (l_float32)(pix->xres) + 0.5);
01144         pix->yres = (l_uint32)(yscale * (l_float32)(pix->yres) + 0.5);
01145     }
01146     return 0;
01147 }
01148 
01149 
01150 l_int32
01151 pixGetInputFormat(PIX  *pix)
01152 {
01153     PROCNAME("pixGetInputFormat");
01154 
01155     if (!pix)
01156         return ERROR_INT("pix not defined", procName, UNDEF);
01157     return pix->informat;
01158 }
01159 
01160 
01161 l_int32
01162 pixSetInputFormat(PIX     *pix,
01163                   l_int32  informat)
01164 {
01165     PROCNAME("pixSetInputFormat");
01166 
01167     if (!pix)
01168         return ERROR_INT("pix not defined", procName, 1);
01169 
01170     pix->informat = informat;
01171     return 0;
01172 }
01173 
01174 
01175 l_int32
01176 pixCopyInputFormat(PIX  *pixd,
01177                    PIX  *pixs)
01178 {
01179     PROCNAME("pixCopyInputFormat");
01180 
01181     if (!pixs)
01182         return ERROR_INT("pixs not defined", procName, 1);
01183     if (!pixd)
01184         return ERROR_INT("pixd not defined", procName, 1);
01185     if (pixs == pixd)
01186         return 0;   /* no-op */
01187 
01188     pixSetInputFormat(pixd, pixGetInputFormat(pixs));
01189     return 0;
01190 }
01191 
01192 
01193 /*!
01194  *  pixGetText()
01195  *
01196  *      Input:  pix
01197  *      Return: ptr to existing text string
01198  *
01199  *  Notes:
01200  *      (1) The text string belongs to the pix.  The caller must
01201  *          NOT free it!
01202  */
01203 char *
01204 pixGetText(PIX  *pix)
01205 {
01206     PROCNAME("pixGetText");
01207 
01208     if (!pix)
01209         return (char *)ERROR_PTR("pix not defined", procName, NULL);
01210     return pix->text;
01211 }
01212 
01213 
01214 /*!
01215  *  pixSetText()
01216  *
01217  *      Input:  pix
01218  *              textstring (can be null)
01219  *      Return: 0 if OK, 1 on error
01220  *
01221  *  Notes:
01222  *      (1) This removes any existing textstring and puts a copy of
01223  *          the input textstring there.
01224  */
01225 l_int32
01226 pixSetText(PIX         *pix,
01227            const char  *textstring)
01228 {
01229     PROCNAME("pixSetText");
01230 
01231     if (!pix)
01232         return ERROR_INT("pix not defined", procName, 1);
01233 
01234     stringReplace(&pix->text, textstring);
01235     return 0;
01236 }
01237 
01238 
01239 /*!
01240  *  pixAddText()
01241  *
01242  *      Input:  pix
01243  *              textstring
01244  *      Return: 0 if OK, 1 on error
01245  *
01246  *  Notes:
01247  *      (1) This adds the new textstring to any existing text.
01248  *      (2) Either or both the existing text and the new text
01249  *          string can be null.
01250  */
01251 l_int32
01252 pixAddText(PIX         *pix,
01253            const char  *textstring)
01254 {
01255 char  *newstring;
01256 
01257     PROCNAME("pixAddText");
01258 
01259     if (!pix)
01260         return ERROR_INT("pix not defined", procName, 1);
01261 
01262     newstring = stringJoin(pixGetText(pix), textstring);
01263     stringReplace(&pix->text, newstring);
01264     FREE(newstring);
01265     return 0;
01266 }
01267 
01268 
01269 l_int32
01270 pixCopyText(PIX  *pixd,
01271             PIX  *pixs)
01272 {
01273     PROCNAME("pixCopyText");
01274 
01275     if (!pixs)
01276         return ERROR_INT("pixs not defined", procName, 1);
01277     if (!pixd)
01278         return ERROR_INT("pixd not defined", procName, 1);
01279     if (pixs == pixd)
01280         return 0;   /* no-op */
01281 
01282     pixSetText(pixd, pixGetText(pixs));
01283     return 0;
01284 }
01285 
01286 
01287 PIXCMAP *
01288 pixGetColormap(PIX  *pix)
01289 {
01290     PROCNAME("pixGetColormap");
01291 
01292     if (!pix)
01293         return (PIXCMAP *)ERROR_PTR("pix not defined", procName, NULL);
01294     return pix->colormap;
01295 }
01296 
01297 
01298 /*!
01299  *  pixSetColormap()
01300  *
01301  *      Input:  pix
01302  *              colormap (to be assigned)
01303  *      Return: 0 if OK, 1 on error.
01304  *
01305  *  Notes:
01306  *      (1) Unlike with the pix data field, pixSetColormap() destroys
01307  *          any existing colormap before assigning the new one.
01308  *          Because colormaps are not ref counted, it is important that
01309  *          the new colormap does not belong to any other pix.
01310  */
01311 l_int32
01312 pixSetColormap(PIX      *pix,
01313                PIXCMAP  *colormap)
01314 {
01315     PROCNAME("pixSetColormap");
01316 
01317     if (!pix)
01318         return ERROR_INT("pix not defined", procName, 1);
01319 
01320     pixDestroyColormap(pix);
01321     pix->colormap = colormap;
01322     return 0;
01323 }
01324 
01325 
01326 /*!
01327  *  pixDestroyColormap()
01328  *
01329  *      Input:  pix
01330  *      Return: 0 if OK, 1 on error
01331  */
01332 l_int32
01333 pixDestroyColormap(PIX  *pix)
01334 {
01335 PIXCMAP  *cmap;
01336 
01337     PROCNAME("pixDestroyColormap");
01338 
01339     if (!pix)
01340         return ERROR_INT("pix not defined", procName, 1);
01341 
01342     if ((cmap = pix->colormap) != NULL) {
01343         pixcmapDestroy(&cmap);
01344         pix->colormap = NULL;
01345     }
01346     return 0;
01347 }
01348 
01349 
01350 /*!
01351  *  pixGetData()
01352  *
01353  *  Notes:
01354  *      (1) This gives a new handle for the data.  The data is still
01355  *          owned by the pix, so do not call FREE() on it.
01356  */
01357 l_uint32 *
01358 pixGetData(PIX  *pix)
01359 {
01360     PROCNAME("pixGetData");
01361 
01362     if (!pix)
01363         return (l_uint32 *)ERROR_PTR("pix not defined", procName, NULL);
01364     return pix->data;
01365 }
01366 
01367 
01368 /*!
01369  *  pixSetData()
01370  *
01371  *  Notes:
01372  *      (1) This does not free any existing data.  To free existing
01373  *          data, use pixFreeData() before pixSetData().
01374  */
01375 l_int32
01376 pixSetData(PIX       *pix,
01377            l_uint32  *data)
01378 {
01379     PROCNAME("pixSetData");
01380 
01381     if (!pix)
01382         return ERROR_INT("pix not defined", procName, 1);
01383 
01384     pix->data = data;
01385     return 0;
01386 }
01387 
01388 
01389 /*!
01390  *  pixExtractData()
01391  *
01392  *  Notes:
01393  *      (1) This extracts the pix image data for use in another context.
01394  *          The caller still needs to use pixDestroy() on the input pix.
01395  *      (2) If refcount == 1, the data is extracted and the
01396  *          pix->data ptr is set to NULL.
01397  *      (3) If refcount > 1, this simply returns a copy of the data,
01398  *          using the pix allocator, and leaving the input pix unchanged.
01399  */
01400 l_uint32 *
01401 pixExtractData(PIX  *pixs)
01402 {
01403 l_int32    count, bytes;
01404 l_uint32  *data, *datas;
01405 
01406     PROCNAME("pixExtractData");
01407 
01408     if (!pixs)
01409         return (l_uint32 *)ERROR_PTR("pixs not defined", procName, NULL);
01410 
01411     count = pixGetRefcount(pixs);
01412     if (count == 1) {  /* extract */
01413         data = pixGetData(pixs);
01414         pixSetData(pixs, NULL);
01415     }
01416     else {  /* refcount > 1; copy */
01417         bytes = 4 * pixGetWpl(pixs) * pixGetHeight(pixs);
01418         datas = pixGetData(pixs);
01419         if ((data = (l_uint32 *)pix_malloc(bytes)) == NULL)
01420             return (l_uint32 *)ERROR_PTR("data not made", procName, NULL);
01421         memcpy((char *)data, (char *)datas, bytes);
01422     }
01423 
01424     return data;
01425 }
01426 
01427 
01428 /*!
01429  *  pixFreeData()
01430  *
01431  *  Notes:
01432  *      (1) This frees the data and sets the pix data ptr to null.
01433  *          It should be used before pixSetData() in the situation where
01434  *          you want to free any existing data before doing
01435  *          a subsequent assignment with pixSetData().
01436  */
01437 l_int32
01438 pixFreeData(PIX  *pix)
01439 {
01440 l_uint32  *data;
01441 
01442     PROCNAME("pixFreeData");
01443 
01444     if (!pix)
01445         return ERROR_INT("pix not defined", procName, 1);
01446 
01447     if ((data = pixGetData(pix)) != NULL) {
01448         pix_free(data);
01449         pix->data = NULL;
01450     }
01451     return 0;
01452 }
01453 
01454 
01455 /*--------------------------------------------------------------------*
01456  *                          Pix line ptrs                             *
01457  *--------------------------------------------------------------------*/
01458 /*!
01459  *  pixGetLinePtrs()
01460  *
01461  *      Input:  pix
01462  *              &size (<optional return> array size, which is the pix height)
01463  *      Return: array of line ptrs, or null on error
01464  *
01465  *  Notes:
01466  *      (1) This is intended to be used for fast random pixel access.
01467  *          For example, for an 8 bpp image,
01468  *              val = GET_DATA_BYTE(lines8[i], j);
01469  *          is equivalent to, but much faster than,
01470  *              pixGetPixel(pix, j, i, &val);
01471  *      (2) How much faster?  For 1 bpp, it's from 6 to 10x faster.
01472  *          For 8 bpp, it's an amazing 30x faster.  So if you are
01473  *          doing random access over a substantial part of the image,
01474  *          use this line ptr array.
01475  *      (3) When random access is used in conjunction with a stack,
01476  *          queue or heap, the overall computation time depends on
01477  *          the operations performed on each struct that is popped
01478  *          or pushed, and whether we are using a priority queue (O(logn))
01479  *          or a queue or stack (O(1)).  For example, for maze search,
01480  *          the overall ratio of time for line ptrs vs. pixGet/Set* is
01481  *             Maze type     Type                   Time ratio
01482  *               binary      queue                     0.4
01483  *               gray        heap (priority queue)     0.6
01484  *      (4) Because this returns a void** and the accessors take void*,
01485  *          the compiler cannot check the pointer types.  It is
01486  *          strongly recommended that you adopt a naming scheme for
01487  *          the returned ptr arrays that indicates the pixel depth.
01488  *          (This follows the original intent of Simonyi's "Hungarian"
01489  *          application notation, where naming is used proactively
01490  *          to make errors visibly obvious.)  By doing this, you can
01491  *          tell by inspection if the correct accessor is used.
01492  *          For example, for an 8 bpp pixg:
01493  *              void **lineg8 = pixGetLinePtrs(pixg, NULL);
01494  *              val = GET_DATA_BYTE(lineg8[i], j);  // fast access; BYTE, 8
01495  *              ...
01496  *              FREE(lineg8);  // don't forget this
01497  *      (5) These are convenient for accessing bytes sequentially in an
01498  *          8 bpp grayscale image.  People who write image processing code
01499  *          on 8 bpp images are accustomed to grabbing pixels directly out
01500  *          of the raster array.  Note that for little endians, you first
01501  *          need to reverse the byte order in each 32-bit word.
01502  *          Here's a typical usage pattern:
01503  *              pixEndianByteSwap(pix);   // always safe; no-op on big-endians
01504  *              l_uint8 **lineptrs = (l_uint8 **)pixGetLinePtrs(pix, NULL);
01505  *              pixGetDimensions(pix, &w, &h, NULL);
01506  *              for (i = 0; i < h; i++) {
01507  *                  l_uint8 *line = lineptrs[i];
01508  *                  for (j = 0; j < w; j++) {
01509  *                      val = line[j];
01510  *                      ...
01511  *                  }
01512  *              }
01513  *              pixEndianByteSwap(pix);  // restore big-endian order
01514  *              FREE(lineptrs);
01515  *          This can be done even more simply as follows:
01516  *              l_uint8 **lineptrs = pixSetupByteProcessing(pix, &w, &h);
01517  *              for (i = 0; i < h; i++) {
01518  *                  l_uint8 *line = lineptrs[i];
01519  *                  for (j = 0; j < w; j++) {
01520  *                      val = line[j];
01521  *                      ...
01522  *                  }
01523  *              }
01524  *              pixCleanupByteProcessing(pix, lineptrs);
01525  */
01526 void **
01527 pixGetLinePtrs(PIX      *pix,
01528                l_int32  *psize)
01529 {
01530 l_int32    i, h, wpl;
01531 l_uint32  *data;
01532 void     **lines;
01533 
01534     PROCNAME("pixGetLinePtrs");
01535 
01536     if (!pix)
01537         return (void **)ERROR_PTR("pix not defined", procName, NULL);
01538 
01539     h = pixGetHeight(pix);
01540     if (psize) *psize = h;
01541     if ((lines = (void **)CALLOC(h, sizeof(void *))) == NULL)
01542         return (void **)ERROR_PTR("lines not made", procName, NULL);
01543     wpl = pixGetWpl(pix);
01544     data = pixGetData(pix);
01545     for (i = 0; i < h; i++)
01546         lines[i] = (void *)(data + i * wpl);
01547 
01548     return lines;
01549 }
01550 
01551 
01552 /*--------------------------------------------------------------------*
01553  *                    Print output for debugging                      *
01554  *--------------------------------------------------------------------*/
01555 extern const char *ImageFileFormatExtensions[];
01556 
01557 /*!
01558  *  pixPrintStreamInfo()
01559  *
01560  *      Input:  fp (file stream)
01561  *              pix
01562  *              text (<optional> identifying string; can be null)
01563  *      Return: 0 if OK, 1 on error
01564  */
01565 l_int32
01566 pixPrintStreamInfo(FILE        *fp,
01567                    PIX         *pix,
01568                    const char  *text)
01569 {
01570 l_int32   informat;
01571 PIXCMAP  *cmap;
01572 
01573     PROCNAME("pixPrintStreamInfo");
01574 
01575     if (!fp)
01576         return ERROR_INT("fp not defined", procName, 1);
01577     if (!pix)
01578         return ERROR_INT("pix not defined", procName, 1);
01579 
01580     if (text)
01581         fprintf(fp, "  Pix Info for %s:\n", text);
01582     fprintf(fp, "    width = %d, height = %d, depth = %d\n",
01583                pixGetWidth(pix), pixGetHeight(pix), pixGetDepth(pix));
01584     fprintf(fp, "    wpl = %d, data = %p, refcount = %d\n",
01585                pixGetWpl(pix), pixGetData(pix), pixGetRefcount(pix));
01586     if ((cmap = pixGetColormap(pix)) != NULL)
01587         pixcmapWriteStream(fp, cmap);
01588     else
01589         fprintf(fp, "    no colormap\n");
01590     informat = pixGetInputFormat(pix);
01591     fprintf(fp, "    input format: %d (%s)\n", informat,
01592             ImageFileFormatExtensions[informat]);
01593 
01594     return 0;
01595 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines