Leptonica 1.68
C Image Processing Library

fliphmtgen.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  *    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 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines