Leptonica 1.68
C Image Processing Library

pixacc.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 /*
00018  *   pixacc.c
00019  *
00020  *      Pixacc creation, destruction
00021  *           PIXACC   *pixaccCreate()
00022  *           PIXACC   *pixaccCreateWithPix()
00023  *           void      pixaccDestroy()
00024  *
00025  *      Pixacc finalization
00026  *           PIX      *pixaccFinal()
00027  *
00028  *      Pixacc accessors
00029  *           PIX      *pixaccGetPix()
00030  *           l_int32   pixaccGetOffset()
00031  *
00032  *      Pixacc accumulators
00033  *           l_int32   pixaccAdd()
00034  *           l_int32   pixaccSubtract()
00035  *           l_int32   pixaccMultConst()
00036  *           l_int32   pixaccMultConstAccumulate()
00037  *
00038  *  This is a simple interface for some of the pixel arithmetic operations 
00039  *  in pixarith.c.  These are easy to code up, but not as fast as
00040  *  hand-coded functions that do arithmetic on corresponding pixels.
00041  *
00042  *  Suppose you want to make a linear combination of pix1 and pix2:
00043  *     pixd = 0.4 * pix1 + 0.6 * pix2
00044  *  where pix1 and pix2 are the same size and have depth 'd'.  Then:
00045  *     Pixacc *pacc = pixaccCreateWithPix(pix1, 0);  // first; addition only
00046  *     pixaccMultConst(pacc, 0.4);
00047  *     pixaccMultConstAccumulate(pacc, pix2, 0.6);  // Add in 0.6 of the second
00048  *     pixd = pixaccFinal(pacc, d);  // Get the result
00049  *     pixaccDestroy(&pacc);
00050  */
00051 
00052 #include <stdio.h>
00053 #include <stdlib.h>
00054 #include "allheaders.h"
00055 
00056 
00057 /*---------------------------------------------------------------------*
00058  *                     Pixacc creation, destruction                    *
00059  *---------------------------------------------------------------------*/
00060 /*!
00061  *  pixaccCreate()
00062  *
00063  *      Input:  w, h (of 32 bpp internal Pix)
00064  *              negflag (0 if only positive numbers are involved;
00065  *                       1 if there will be negative numbers)
00066  *      Return: pixacc, or null on error
00067  *
00068  *  Notes:
00069  *      (1) Use @negflag = 1 for safety if any negative numbers are going
00070  *          to be used in the chain of operations.  Negative numbers
00071  *          arise, e.g., by subtracting a pix, or by adding a pix
00072  *          that has been pre-multiplied by a negative number.
00073  *      (2) Initializes the internal 32 bpp pix, similarly to the
00074  *          initialization in pixInitAccumulate().
00075  */
00076 PIXACC *
00077 pixaccCreate(l_int32  w,
00078              l_int32  h,
00079              l_int32  negflag)
00080 {
00081 PIXACC  *pixacc;
00082 
00083     PROCNAME("pixaccCreate");
00084 
00085     if ((pixacc = (PIXACC *)CALLOC(1, sizeof(PIXACC))) == NULL)
00086         return (PIXACC *)ERROR_PTR("pixacc not made", procName, NULL);
00087     pixacc->w = w;
00088     pixacc->h = h;
00089     
00090     if ((pixacc->pix = pixCreate(w, h, 32)) == NULL)
00091         return (PIXACC *)ERROR_PTR("pix not made", procName, NULL);
00092 
00093     if (negflag) {
00094         pixacc->offset = 0x40000000;
00095         pixSetAllArbitrary(pixacc->pix, pixacc->offset);
00096     }
00097 
00098     return pixacc;
00099 }
00100 
00101 
00102 /*!
00103  *  pixaccCreateWithPix()
00104  *
00105  *      Input:  pix
00106  *              negflag (0 if only positive numbers are involved;
00107  *                       1 if there will be negative numbers)
00108  *      Return: pixacc, or null on error
00109  *
00110  *  Notes:
00111  *      (1) See pixaccCreate()
00112  */
00113 PIXACC *
00114 pixaccCreateWithPix(PIX     *pix,
00115                     l_int32  negflag)
00116 {
00117 l_int32  w, h;
00118 PIXACC  *pixacc;
00119 
00120     PROCNAME("pixaccCreateWithPix");
00121 
00122     if (!pix)
00123         return (PIXACC *)ERROR_PTR("pix not defined", procName, NULL);
00124 
00125     pixGetDimensions(pix, &w, &h, NULL);
00126     pixacc = pixaccCreate(w, h, negflag);
00127     pixaccAdd(pixacc, pix);
00128     return pixacc;
00129 }
00130 
00131 
00132 /*!
00133  *  pixaccDestroy()
00134  *
00135  *      Input:  &pixacc (<can be null>)
00136  *      Return: void
00137  *
00138  *  Notes:
00139  *      (1) Always nulls the input ptr.
00140  */
00141 void
00142 pixaccDestroy(PIXACC  **ppixacc)
00143 {
00144 PIXACC  *pixacc;
00145 
00146     PROCNAME("pixaccDestroy");
00147 
00148     if (ppixacc == NULL) {
00149         L_WARNING("ptr address is NULL!", procName);
00150         return;
00151     }
00152 
00153     if ((pixacc = *ppixacc) == NULL)
00154         return;
00155 
00156     pixDestroy(&pixacc->pix);
00157     FREE(pixacc);
00158     *ppixacc = NULL;
00159     return;
00160 }
00161 
00162 
00163 /*---------------------------------------------------------------------*
00164  *                            Pixacc finalization                      *
00165  *---------------------------------------------------------------------*/
00166 /*!
00167  *  pixaccFinal()
00168  *
00169  *      Input:  pixacc
00170  *              outdepth (8, 16 or 32 bpp)
00171  *      Return: pixd (8 , 16 or 32 bpp), or null on error
00172  */
00173 PIX *
00174 pixaccFinal(PIXACC  *pixacc,
00175             l_int32  outdepth)
00176 {
00177     PROCNAME("pixaccFinal");
00178 
00179     if (!pixacc)
00180         return (PIX *)ERROR_PTR("pixacc not defined", procName, NULL);
00181 
00182     return pixFinalAccumulate(pixaccGetPix(pixacc), pixaccGetOffset(pixacc),
00183                               outdepth);
00184 }
00185 
00186 
00187 /*---------------------------------------------------------------------*
00188  *                            Pixacc accessors                         *
00189  *---------------------------------------------------------------------*/
00190 /*!
00191  *  pixaccGetPix()
00192  *
00193  *      Input:  pixacc
00194  *      Return: pix, or null on error
00195  */
00196 PIX *
00197 pixaccGetPix(PIXACC  *pixacc)
00198 {
00199     PROCNAME("pixaccGetPix");
00200 
00201     if (!pixacc)
00202         return (PIX *)ERROR_PTR("pixacc not defined", procName, NULL);
00203     return pixacc->pix;
00204 }
00205 
00206 
00207 /*!
00208  *  pixaccGetOffset()
00209  *
00210  *      Input:  pixacc
00211  *      Return: offset, or -1 on error
00212  */
00213 l_int32
00214 pixaccGetOffset(PIXACC  *pixacc)
00215 {
00216     PROCNAME("pixaccGetOffset");
00217 
00218     if (!pixacc)
00219         return ERROR_INT("pixacc not defined", procName, -1);
00220     return pixacc->offset;
00221 }
00222 
00223 
00224 /*---------------------------------------------------------------------*
00225  *                          Pixacc accumulators                        *
00226  *---------------------------------------------------------------------*/
00227 /*!
00228  *  pixaccAdd()
00229  *
00230  *      Input:  pixacc
00231  *              pix (to be added)
00232  *      Return: 0 if OK, 1 on error
00233  */
00234 l_int32
00235 pixaccAdd(PIXACC  *pixacc,
00236           PIX     *pix)
00237 {
00238     PROCNAME("pixaccAdd");
00239 
00240     if (!pixacc)
00241         return ERROR_INT("pixacc not defined", procName, 1);
00242     if (!pix)
00243         return ERROR_INT("pix not defined", procName, 1);
00244     pixAccumulate(pixaccGetPix(pixacc), pix, L_ARITH_ADD);
00245     return 0;
00246 }
00247 
00248 
00249 /*!
00250  *  pixaccSubtract()
00251  *
00252  *      Input:  pixacc
00253  *              pix (to be subtracted)
00254  *      Return: 0 if OK, 1 on error
00255  */
00256 l_int32
00257 pixaccSubtract(PIXACC  *pixacc,
00258                PIX     *pix)
00259 {
00260     PROCNAME("pixaccSubtract");
00261 
00262     if (!pixacc)
00263         return ERROR_INT("pixacc not defined", procName, 1);
00264     if (!pix)
00265         return ERROR_INT("pix not defined", procName, 1);
00266     pixAccumulate(pixaccGetPix(pixacc), pix, L_ARITH_SUBTRACT);
00267     return 0;
00268 }
00269 
00270 
00271 /*!
00272  *  pixaccMultConst()
00273  *
00274  *      Input:  pixacc
00275  *              factor
00276  *      Return: 0 if OK, 1 on error
00277  */
00278 l_int32
00279 pixaccMultConst(PIXACC    *pixacc,
00280                 l_float32  factor)
00281 {
00282     PROCNAME("pixaccMultConst");
00283 
00284     if (!pixacc)
00285         return ERROR_INT("pixacc not defined", procName, 1);
00286     pixMultConstAccumulate(pixaccGetPix(pixacc), factor,
00287                            pixaccGetOffset(pixacc));
00288     return 0;
00289 }
00290 
00291 
00292 /*!
00293  *  pixaccMultConstAccumulate()
00294  *
00295  *      Input:  pixacc
00296  *              pix
00297  *              factor
00298  *      Return: 0 if OK, 1 on error
00299  *
00300  *  Notes:
00301  *      (1) This creates a temp pix that is @pix multiplied by the
00302  *          constant @factor.  It then adds that into @pixacc.
00303  */
00304 l_int32
00305 pixaccMultConstAccumulate(PIXACC    *pixacc,
00306                           PIX       *pix,
00307                           l_float32  factor)
00308 {
00309 l_int32  w, h, d, negflag;
00310 PIX     *pixt;
00311 PIXACC  *pacct;
00312 
00313     PROCNAME("pixaccMultConstAccumulate");
00314 
00315     if (!pixacc)
00316         return ERROR_INT("pixacc not defined", procName, 1);
00317     if (!pix)
00318         return ERROR_INT("pix not defined", procName, 1);
00319 
00320     if (factor == 0.0) return 0;
00321 
00322     pixGetDimensions(pix, &w, &h, &d);
00323     negflag = (factor > 0.0) ? 0 : 1;
00324     pacct = pixaccCreate(w, h, negflag);
00325     pixaccAdd(pacct, pix);
00326     pixaccMultConst(pacct, factor);
00327     pixt = pixaccFinal(pacct, d);
00328     pixaccAdd(pixacc, pixt);
00329 
00330     pixaccDestroy(&pacct);
00331     pixDestroy(&pixt);
00332     return 0;
00333 }
00334 
00335 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines