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 * fliphmtgen.c 00018 * 00019 * DWA implementation of hit-miss transforms with auto-generated sels 00020 * for pixOrientDetectDwa() and pixUpDownDetectDwa() in flipdetect.c 00021 * 00022 * PIX *pixFlipFHMTGen() 00023 * static l_int32 flipfhmtgen_low() -- dispatcher 00024 * static void fhmt_1_0() 00025 * static void fhmt_1_1() 00026 * static void fhmt_1_2() 00027 * static void fhmt_1_3() 00028 * 00029 * The code (rearranged) was generated by prog/flipselgen.c 00030 */ 00031 00032 #include <stdio.h> 00033 #include <string.h> 00034 #include "allheaders.h" 00035 00036 static l_int32 NUM_SELS_GENERATED = 4; 00037 static char SEL_NAMES[][10] = {"flipsel1", 00038 "flipsel2", 00039 "flipsel3", 00040 "flipsel4"}; 00041 00042 static l_int32 flipfhmtgen_low(l_uint32 *, l_int32, l_int32, l_int32, l_uint32 *, l_int32, l_int32); 00043 00044 static void fhmt_1_0(l_uint32 *, l_int32, l_int32, l_int32, l_uint32 *, l_int32); 00045 static void fhmt_1_1(l_uint32 *, l_int32, l_int32, l_int32, l_uint32 *, l_int32); 00046 static void fhmt_1_2(l_uint32 *, l_int32, l_int32, l_int32, l_uint32 *, l_int32); 00047 static void fhmt_1_3(l_uint32 *, l_int32, l_int32, l_int32, l_uint32 *, l_int32); 00048 00049 00050 /*---------------------------------------------------------------------* 00051 * Top-level hmt functions * 00052 *---------------------------------------------------------------------*/ 00053 /* 00054 * pixFlipFHMTGen() 00055 * 00056 * Input: pixd (usual 3 choices: null, == pixs, != pixs) 00057 * pixs 00058 * sel name (one of four defined in SEL_NAMES[]) 00059 * Return: pixd 00060 * 00061 * Action: hit-miss transform on pixs by the sel 00062 * N.B.: the sel must have at least one hit, and it 00063 * can have any number of misses. 00064 */ 00065 PIX * 00066 pixFlipFHMTGen(PIX *pixd, 00067 PIX *pixs, 00068 char *selname) 00069 { 00070 l_int32 i, index, found, w, h, wpls, wpld; 00071 l_uint32 *datad, *datas, *datat; 00072 PIX *pixt; 00073 00074 PROCNAME("pixFlipFHMTGen"); 00075 00076 if (!pixs) 00077 return (PIX *)ERROR_PTR("pixs not defined", procName, pixd); 00078 if (pixGetDepth(pixs) != 1) 00079 return (PIX *)ERROR_PTR("pixs must be 1 bpp", procName, pixd); 00080 00081 found = FALSE; 00082 for (i = 0; i < NUM_SELS_GENERATED; i++) { 00083 if (strcmp(selname, SEL_NAMES[i]) == 0) { 00084 found = TRUE; 00085 index = i; 00086 break; 00087 } 00088 } 00089 if (found == FALSE) 00090 return (PIX *)ERROR_PTR("sel index not found", procName, pixd); 00091 00092 if (pixd) { 00093 if (!pixSizesEqual(pixs, pixd)) 00094 return (PIX *)ERROR_PTR("sizes not equal", procName, pixd); 00095 } 00096 else { 00097 if ((pixd = pixCreateTemplate(pixs)) == NULL) 00098 return (PIX *)ERROR_PTR("pixd not made", procName, NULL); 00099 } 00100 00101 wpls = pixGetWpl(pixs); 00102 wpld = pixGetWpl(pixd); 00103 00104 /* The images must be surrounded with ADDED_BORDER white pixels, 00105 * that we'll read from. We fabricate a "proper" 00106 * image as the subimage within the border, having the 00107 * following parameters: */ 00108 w = pixGetWidth(pixs) - 2 * ADDED_BORDER; 00109 h = pixGetHeight(pixs) - 2 * ADDED_BORDER; 00110 datas = pixGetData(pixs) + ADDED_BORDER * wpls + ADDED_BORDER / 32; 00111 datad = pixGetData(pixd) + ADDED_BORDER * wpld + ADDED_BORDER / 32; 00112 00113 if (pixd == pixs) { /* need temp image if in-place */ 00114 if ((pixt = pixCopy(NULL, pixs)) == NULL) 00115 return (PIX *)ERROR_PTR("pixt not made", procName, pixd); 00116 datat = pixGetData(pixt) + ADDED_BORDER * wpls + ADDED_BORDER / 32; 00117 flipfhmtgen_low(datad, w, h, wpld, datat, wpls, index); 00118 pixDestroy(&pixt); 00119 } 00120 else { /* simple and not in-place */ 00121 flipfhmtgen_low(datad, w, h, wpld, datas, wpls, index); 00122 } 00123 00124 return pixd; 00125 } 00126 00127 00128 /*---------------------------------------------------------------------* 00129 * Fast hmt dispatcher * 00130 *---------------------------------------------------------------------*/ 00131 /* 00132 * flipfhmtgen_low() 00133 * 00134 * A dispatcher to appropriate low-level code for flip hmt ops 00135 */ 00136 static l_int32 00137 flipfhmtgen_low(l_uint32 *datad, 00138 l_int32 w, 00139 l_int32 h, 00140 l_int32 wpld, 00141 l_uint32 *datas, 00142 l_int32 wpls, 00143 l_int32 index) 00144 { 00145 00146 switch (index) 00147 { 00148 case 0: 00149 fhmt_1_0(datad, w, h, wpld, datas, wpls); 00150 break; 00151 case 1: 00152 fhmt_1_1(datad, w, h, wpld, datas, wpls); 00153 break; 00154 case 2: 00155 fhmt_1_2(datad, w, h, wpld, datas, wpls); 00156 break; 00157 case 3: 00158 fhmt_1_3(datad, w, h, wpld, datas, wpls); 00159 break; 00160 } 00161 00162 return 0; 00163 } 00164 00165 00166 /*--------------------------------------------------------------------------* 00167 * Low-level auto-generated hmt routines * 00168 *--------------------------------------------------------------------------*/ 00169 /* 00170 * N.B. in all the low-level routines, the part of the image 00171 * that is accessed has been clipped by ADDED_BORDER pixels 00172 * on all four sides. This is done in the higher level 00173 * code by redefining w and h smaller and by moving the 00174 * start-of-image pointers up to the beginning of this 00175 * interior rectangle. 00176 */ 00177 00178 static void 00179 fhmt_1_0(l_uint32 *datad, 00180 l_int32 w, 00181 l_int32 h, 00182 l_int32 wpld, 00183 l_uint32 *datas, 00184 l_int32 wpls) 00185 { 00186 l_int32 i; 00187 register l_int32 j, pwpls; 00188 register l_uint32 *sptr, *dptr; 00189 l_int32 wpls2, wpls3; 00190 00191 wpls2 = 2 * wpls; 00192 wpls3 = 3 * wpls; 00193 pwpls = (l_uint32)(w + 31) / 32; /* proper wpl of src */ 00194 00195 for (i = 0; i < h; i++) { 00196 sptr = datas + i * wpls; 00197 dptr = datad + i * wpld; 00198 for (j = 0; j < pwpls; j++, sptr++, dptr++) { 00199 *dptr = ((*(sptr - wpls) >> 3) | (*(sptr - wpls - 1) << 29)) & 00200 (~*(sptr - wpls)) & 00201 ((~*(sptr - wpls) << 1) | (~*(sptr - wpls + 1) >> 31)) & 00202 ((*(sptr) >> 3) | (*(sptr - 1) << 29)) & 00203 ((~*(sptr) >> 1) | (~*(sptr - 1) << 31)) & 00204 (~*sptr) & 00205 ((~*(sptr) << 1) | (~*(sptr + 1) >> 31)) & 00206 ((*(sptr + wpls) >> 3) | (*(sptr + wpls - 1) << 29)) & 00207 (~*(sptr + wpls)) & 00208 ((*(sptr + wpls2) >> 3) | (*(sptr + wpls2 - 1) << 29)) & 00209 ((*(sptr + wpls3) >> 3) | (*(sptr + wpls3 - 1) << 29)) & 00210 ((*(sptr + wpls3) >> 2) | (*(sptr + wpls3 - 1) << 30)) & 00211 ((*(sptr + wpls3) >> 1) | (*(sptr + wpls3 - 1) << 31)) & 00212 (*(sptr + wpls3)) & 00213 ((*(sptr + wpls3) << 1) | (*(sptr + wpls3 + 1) >> 31)) & 00214 ((*(sptr + wpls3) << 2) | (*(sptr + wpls3 + 1) >> 30)); 00215 } 00216 } 00217 } 00218 00219 00220 static void 00221 fhmt_1_1(l_uint32 *datad, 00222 l_int32 w, 00223 l_int32 h, 00224 l_int32 wpld, 00225 l_uint32 *datas, 00226 l_int32 wpls) 00227 { 00228 l_int32 i; 00229 register l_int32 j, pwpls; 00230 register l_uint32 *sptr, *dptr; 00231 l_int32 wpls2, wpls3; 00232 00233 wpls2 = 2 * wpls; 00234 wpls3 = 3 * wpls; 00235 pwpls = (l_uint32)(w + 31) / 32; /* proper wpl of src */ 00236 00237 for (i = 0; i < h; i++) { 00238 sptr = datas + i * wpls; 00239 dptr = datad + i * wpld; 00240 for (j = 0; j < pwpls; j++, sptr++, dptr++) { 00241 *dptr = ((~*(sptr - wpls) >> 1) | (~*(sptr - wpls - 1) << 31)) & 00242 (~*(sptr - wpls)) & 00243 ((*(sptr - wpls) << 3) | (*(sptr - wpls + 1) >> 29)) & 00244 ((~*(sptr) >> 1) | (~*(sptr - 1) << 31)) & 00245 (~*sptr) & 00246 ((~*(sptr) << 1) | (~*(sptr + 1) >> 31)) & 00247 ((*(sptr) << 3) | (*(sptr + 1) >> 29)) & 00248 (~*(sptr + wpls)) & 00249 ((*(sptr + wpls) << 3) | (*(sptr + wpls + 1) >> 29)) & 00250 ((*(sptr + wpls2) << 3) | (*(sptr + wpls2 + 1) >> 29)) & 00251 ((*(sptr + wpls3) >> 2) | (*(sptr + wpls3 - 1) << 30)) & 00252 ((*(sptr + wpls3) >> 1) | (*(sptr + wpls3 - 1) << 31)) & 00253 (*(sptr + wpls3)) & 00254 ((*(sptr + wpls3) << 1) | (*(sptr + wpls3 + 1) >> 31)) & 00255 ((*(sptr + wpls3) << 2) | (*(sptr + wpls3 + 1) >> 30)) & 00256 ((*(sptr + wpls3) << 3) | (*(sptr + wpls3 + 1) >> 29)); 00257 } 00258 } 00259 } 00260 00261 00262 static void 00263 fhmt_1_2(l_uint32 *datad, 00264 l_int32 w, 00265 l_int32 h, 00266 l_int32 wpld, 00267 l_uint32 *datas, 00268 l_int32 wpls) 00269 { 00270 l_int32 i; 00271 register l_int32 j, pwpls; 00272 register l_uint32 *sptr, *dptr; 00273 l_int32 wpls2, wpls3; 00274 00275 wpls2 = 2 * wpls; 00276 wpls3 = 3 * wpls; 00277 pwpls = (l_uint32)(w + 31) / 32; /* proper wpl of src */ 00278 00279 for (i = 0; i < h; i++) { 00280 sptr = datas + i * wpls; 00281 dptr = datad + i * wpld; 00282 for (j = 0; j < pwpls; j++, sptr++, dptr++) { 00283 *dptr = ((*(sptr - wpls3) >> 3) | (*(sptr - wpls3 - 1) << 29)) & 00284 ((*(sptr - wpls3) >> 2) | (*(sptr - wpls3 - 1) << 30)) & 00285 ((*(sptr - wpls3) >> 1) | (*(sptr - wpls3 - 1) << 31)) & 00286 (*(sptr - wpls3)) & 00287 ((*(sptr - wpls3) << 1) | (*(sptr - wpls3 + 1) >> 31)) & 00288 ((*(sptr - wpls3) << 2) | (*(sptr - wpls3 + 1) >> 30)) & 00289 ((*(sptr - wpls2) >> 3) | (*(sptr - wpls2 - 1) << 29)) & 00290 ((*(sptr - wpls) >> 3) | (*(sptr - wpls - 1) << 29)) & 00291 (~*(sptr - wpls)) & 00292 ((*(sptr) >> 3) | (*(sptr - 1) << 29)) & 00293 ((~*(sptr) >> 1) | (~*(sptr - 1) << 31)) & 00294 (~*sptr) & 00295 ((~*(sptr) << 1) | (~*(sptr + 1) >> 31)) & 00296 ((*(sptr + wpls) >> 3) | (*(sptr + wpls - 1) << 29)) & 00297 (~*(sptr + wpls)) & 00298 ((~*(sptr + wpls) << 1) | (~*(sptr + wpls + 1) >> 31)); 00299 } 00300 } 00301 } 00302 00303 00304 static void 00305 fhmt_1_3(l_uint32 *datad, 00306 l_int32 w, 00307 l_int32 h, 00308 l_int32 wpld, 00309 l_uint32 *datas, 00310 l_int32 wpls) 00311 { 00312 l_int32 i; 00313 register l_int32 j, pwpls; 00314 register l_uint32 *sptr, *dptr; 00315 l_int32 wpls2, wpls3; 00316 00317 wpls2 = 2 * wpls; 00318 wpls3 = 3 * wpls; 00319 pwpls = (l_uint32)(w + 31) / 32; /* proper wpl of src */ 00320 00321 for (i = 0; i < h; i++) { 00322 sptr = datas + i * wpls; 00323 dptr = datad + i * wpld; 00324 for (j = 0; j < pwpls; j++, sptr++, dptr++) { 00325 *dptr = ((*(sptr - wpls3) >> 2) | (*(sptr - wpls3 - 1) << 30)) & 00326 ((*(sptr - wpls3) >> 1) | (*(sptr - wpls3 - 1) << 31)) & 00327 (*(sptr - wpls3)) & 00328 ((*(sptr - wpls3) << 1) | (*(sptr - wpls3 + 1) >> 31)) & 00329 ((*(sptr - wpls3) << 2) | (*(sptr - wpls3 + 1) >> 30)) & 00330 ((*(sptr - wpls3) << 3) | (*(sptr - wpls3 + 1) >> 29)) & 00331 ((*(sptr - wpls2) << 3) | (*(sptr - wpls2 + 1) >> 29)) & 00332 (~*(sptr - wpls)) & 00333 ((*(sptr - wpls) << 3) | (*(sptr - wpls + 1) >> 29)) & 00334 ((~*(sptr) >> 1) | (~*(sptr - 1) << 31)) & 00335 (~*sptr) & 00336 ((~*(sptr) << 1) | (~*(sptr + 1) >> 31)) & 00337 ((*(sptr) << 3) | (*(sptr + 1) >> 29)) & 00338 ((~*(sptr + wpls) >> 1) | (~*(sptr + wpls - 1) << 31)) & 00339 (~*(sptr + wpls)) & 00340 ((*(sptr + wpls) << 3) | (*(sptr + wpls + 1) >> 29)); 00341 } 00342 } 00343 } 00344 00345