Leptonica 1.68
C Image Processing Library
|
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