mirror of http://192.168.1.51:8099/lmh188/twain3.0
353 lines
13 KiB
C
353 lines
13 KiB
C
|
/*====================================================================*
|
||
|
- Copyright (C) 2001 Leptonica. All rights reserved.
|
||
|
-
|
||
|
- Redistribution and use in source and binary forms, with or without
|
||
|
- modification, are permitted provided that the following conditions
|
||
|
- are met:
|
||
|
- 1. Redistributions of source code must retain the above copyright
|
||
|
- notice, this list of conditions and the following disclaimer.
|
||
|
- 2. Redistributions in binary form must reproduce the above
|
||
|
- copyright notice, this list of conditions and the following
|
||
|
- disclaimer in the documentation and/or other materials
|
||
|
- provided with the distribution.
|
||
|
-
|
||
|
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||
|
- ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||
|
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||
|
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ANY
|
||
|
- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||
|
- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||
|
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||
|
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||
|
- OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||
|
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||
|
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||
|
*====================================================================*/
|
||
|
|
||
|
/*
|
||
|
* fliphmtgen.c
|
||
|
*
|
||
|
* DWA implementation of hit-miss transforms with auto-generated sels
|
||
|
* for pixOrientDetectDwa() and pixUpDownDetectDwa() in flipdetect.c
|
||
|
*
|
||
|
* PIX *pixFlipFHMTGen()
|
||
|
* static l_int32 flipfhmtgen_low() -- dispatcher
|
||
|
* static void fhmt_1_0()
|
||
|
* static void fhmt_1_1()
|
||
|
* static void fhmt_1_2()
|
||
|
* static void fhmt_1_3()
|
||
|
*
|
||
|
* The code (rearranged) was generated by prog/flipselgen.c
|
||
|
*/
|
||
|
|
||
|
#include <string.h>
|
||
|
#include "allheaders.h"
|
||
|
|
||
|
static l_int32 NUM_SELS_GENERATED = 4;
|
||
|
static char SEL_NAMES[][10] = {"flipsel1",
|
||
|
"flipsel2",
|
||
|
"flipsel3",
|
||
|
"flipsel4"};
|
||
|
|
||
|
static l_int32 flipfhmtgen_low(l_uint32 *, l_int32, l_int32, l_int32, l_uint32 *, l_int32, l_int32);
|
||
|
|
||
|
static void fhmt_1_0(l_uint32 *, l_int32, l_int32, l_int32, l_uint32 *, l_int32);
|
||
|
static void fhmt_1_1(l_uint32 *, l_int32, l_int32, l_int32, l_uint32 *, l_int32);
|
||
|
static void fhmt_1_2(l_uint32 *, l_int32, l_int32, l_int32, l_uint32 *, l_int32);
|
||
|
static void fhmt_1_3(l_uint32 *, l_int32, l_int32, l_int32, l_uint32 *, l_int32);
|
||
|
|
||
|
|
||
|
/*---------------------------------------------------------------------*
|
||
|
* Top-level hmt functions *
|
||
|
*---------------------------------------------------------------------*/
|
||
|
/*
|
||
|
* pixFlipFHMTGen()
|
||
|
*
|
||
|
* Input: pixd (usual 3 choices: null, == pixs, != pixs)
|
||
|
* pixs
|
||
|
* sel name (one of four defined in SEL_NAMES[])
|
||
|
* Return: pixd
|
||
|
*
|
||
|
* Notes:
|
||
|
* Action: hit-miss transform on pixs by the sel
|
||
|
* N.B.: the sel must have at least one hit, and it
|
||
|
* can have any number of misses.
|
||
|
*/
|
||
|
PIX *
|
||
|
pixFlipFHMTGen(PIX *pixd,
|
||
|
PIX *pixs,
|
||
|
const char *selname)
|
||
|
{
|
||
|
l_int32 i, index, found, w, h, wpls, wpld;
|
||
|
l_uint32 *datad, *datas, *datat;
|
||
|
PIX *pixt;
|
||
|
|
||
|
PROCNAME("pixFlipFHMTGen");
|
||
|
|
||
|
if (!pixs)
|
||
|
return (PIX *)ERROR_PTR("pixs not defined", procName, pixd);
|
||
|
if (pixGetDepth(pixs) != 1)
|
||
|
return (PIX *)ERROR_PTR("pixs must be 1 bpp", procName, pixd);
|
||
|
|
||
|
found = FALSE;
|
||
|
for (i = 0; i < NUM_SELS_GENERATED; i++) {
|
||
|
if (strcmp(selname, SEL_NAMES[i]) == 0) {
|
||
|
found = TRUE;
|
||
|
index = i;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
if (found == FALSE)
|
||
|
return (PIX *)ERROR_PTR("sel index not found", procName, pixd);
|
||
|
|
||
|
if (pixd) {
|
||
|
if (!pixSizesEqual(pixs, pixd))
|
||
|
return (PIX *)ERROR_PTR("sizes not equal", procName, pixd);
|
||
|
} else {
|
||
|
if ((pixd = pixCreateTemplate(pixs)) == NULL)
|
||
|
return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
|
||
|
}
|
||
|
|
||
|
wpls = pixGetWpl(pixs);
|
||
|
wpld = pixGetWpl(pixd);
|
||
|
|
||
|
/* The images must be surrounded with ADDED_BORDER white pixels,
|
||
|
* that we'll read from. We fabricate a "proper"
|
||
|
* image as the subimage within the border, having the
|
||
|
* following parameters: */
|
||
|
w = pixGetWidth(pixs) - 2 * ADDED_BORDER;
|
||
|
h = pixGetHeight(pixs) - 2 * ADDED_BORDER;
|
||
|
datas = pixGetData(pixs) + ADDED_BORDER * wpls + ADDED_BORDER / 32;
|
||
|
datad = pixGetData(pixd) + ADDED_BORDER * wpld + ADDED_BORDER / 32;
|
||
|
|
||
|
if (pixd == pixs) { /* need temp image if in-place */
|
||
|
if ((pixt = pixCopy(NULL, pixs)) == NULL)
|
||
|
return (PIX *)ERROR_PTR("pixt not made", procName, pixd);
|
||
|
datat = pixGetData(pixt) + ADDED_BORDER * wpls + ADDED_BORDER / 32;
|
||
|
flipfhmtgen_low(datad, w, h, wpld, datat, wpls, index);
|
||
|
pixDestroy(&pixt);
|
||
|
} else { /* simple and not in-place */
|
||
|
flipfhmtgen_low(datad, w, h, wpld, datas, wpls, index);
|
||
|
}
|
||
|
|
||
|
return pixd;
|
||
|
}
|
||
|
|
||
|
|
||
|
/*---------------------------------------------------------------------*
|
||
|
* Fast hmt dispatcher *
|
||
|
*---------------------------------------------------------------------*/
|
||
|
/*
|
||
|
* flipfhmtgen_low()
|
||
|
*
|
||
|
* A dispatcher to appropriate low-level code for flip hmt ops
|
||
|
*/
|
||
|
static l_int32
|
||
|
flipfhmtgen_low(l_uint32 *datad,
|
||
|
l_int32 w,
|
||
|
l_int32 h,
|
||
|
l_int32 wpld,
|
||
|
l_uint32 *datas,
|
||
|
l_int32 wpls,
|
||
|
l_int32 index)
|
||
|
{
|
||
|
|
||
|
switch (index)
|
||
|
{
|
||
|
case 0:
|
||
|
fhmt_1_0(datad, w, h, wpld, datas, wpls);
|
||
|
break;
|
||
|
case 1:
|
||
|
fhmt_1_1(datad, w, h, wpld, datas, wpls);
|
||
|
break;
|
||
|
case 2:
|
||
|
fhmt_1_2(datad, w, h, wpld, datas, wpls);
|
||
|
break;
|
||
|
case 3:
|
||
|
fhmt_1_3(datad, w, h, wpld, datas, wpls);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
/*--------------------------------------------------------------------------*
|
||
|
* Low-level auto-generated hmt routines *
|
||
|
*--------------------------------------------------------------------------*/
|
||
|
/*
|
||
|
* N.B. in all the low-level routines, the part of the image
|
||
|
* that is accessed has been clipped by ADDED_BORDER pixels
|
||
|
* on all four sides. This is done in the higher level
|
||
|
* code by redefining w and h smaller and by moving the
|
||
|
* start-of-image pointers up to the beginning of this
|
||
|
* interior rectangle.
|
||
|
*/
|
||
|
|
||
|
static void
|
||
|
fhmt_1_0(l_uint32 *datad,
|
||
|
l_int32 w,
|
||
|
l_int32 h,
|
||
|
l_int32 wpld,
|
||
|
l_uint32 *datas,
|
||
|
l_int32 wpls)
|
||
|
{
|
||
|
l_int32 i;
|
||
|
l_int32 j, pwpls;
|
||
|
l_uint32 *sptr, *dptr;
|
||
|
l_int32 wpls2, wpls3;
|
||
|
|
||
|
wpls2 = 2 * wpls;
|
||
|
wpls3 = 3 * wpls;
|
||
|
pwpls = (l_uint32)(w + 31) / 32; /* proper wpl of src */
|
||
|
|
||
|
for (i = 0; i < h; i++) {
|
||
|
sptr = datas + i * wpls;
|
||
|
dptr = datad + i * wpld;
|
||
|
for (j = 0; j < pwpls; j++, sptr++, dptr++) {
|
||
|
*dptr = ((*(sptr - wpls) >> 3) | (*(sptr - wpls - 1) << 29)) &
|
||
|
(~*(sptr - wpls)) &
|
||
|
((~*(sptr - wpls) << 1) | (~*(sptr - wpls + 1) >> 31)) &
|
||
|
((*(sptr) >> 3) | (*(sptr - 1) << 29)) &
|
||
|
((~*(sptr) >> 1) | (~*(sptr - 1) << 31)) &
|
||
|
(~*sptr) &
|
||
|
((~*(sptr) << 1) | (~*(sptr + 1) >> 31)) &
|
||
|
((*(sptr + wpls) >> 3) | (*(sptr + wpls - 1) << 29)) &
|
||
|
(~*(sptr + wpls)) &
|
||
|
((*(sptr + wpls2) >> 3) | (*(sptr + wpls2 - 1) << 29)) &
|
||
|
((*(sptr + wpls3) >> 3) | (*(sptr + wpls3 - 1) << 29)) &
|
||
|
((*(sptr + wpls3) >> 2) | (*(sptr + wpls3 - 1) << 30)) &
|
||
|
((*(sptr + wpls3) >> 1) | (*(sptr + wpls3 - 1) << 31)) &
|
||
|
(*(sptr + wpls3)) &
|
||
|
((*(sptr + wpls3) << 1) | (*(sptr + wpls3 + 1) >> 31)) &
|
||
|
((*(sptr + wpls3) << 2) | (*(sptr + wpls3 + 1) >> 30));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
static void
|
||
|
fhmt_1_1(l_uint32 *datad,
|
||
|
l_int32 w,
|
||
|
l_int32 h,
|
||
|
l_int32 wpld,
|
||
|
l_uint32 *datas,
|
||
|
l_int32 wpls)
|
||
|
{
|
||
|
l_int32 i;
|
||
|
l_int32 j, pwpls;
|
||
|
l_uint32 *sptr, *dptr;
|
||
|
l_int32 wpls2, wpls3;
|
||
|
|
||
|
wpls2 = 2 * wpls;
|
||
|
wpls3 = 3 * wpls;
|
||
|
pwpls = (l_uint32)(w + 31) / 32; /* proper wpl of src */
|
||
|
|
||
|
for (i = 0; i < h; i++) {
|
||
|
sptr = datas + i * wpls;
|
||
|
dptr = datad + i * wpld;
|
||
|
for (j = 0; j < pwpls; j++, sptr++, dptr++) {
|
||
|
*dptr = ((~*(sptr - wpls) >> 1) | (~*(sptr - wpls - 1) << 31)) &
|
||
|
(~*(sptr - wpls)) &
|
||
|
((*(sptr - wpls) << 3) | (*(sptr - wpls + 1) >> 29)) &
|
||
|
((~*(sptr) >> 1) | (~*(sptr - 1) << 31)) &
|
||
|
(~*sptr) &
|
||
|
((~*(sptr) << 1) | (~*(sptr + 1) >> 31)) &
|
||
|
((*(sptr) << 3) | (*(sptr + 1) >> 29)) &
|
||
|
(~*(sptr + wpls)) &
|
||
|
((*(sptr + wpls) << 3) | (*(sptr + wpls + 1) >> 29)) &
|
||
|
((*(sptr + wpls2) << 3) | (*(sptr + wpls2 + 1) >> 29)) &
|
||
|
((*(sptr + wpls3) >> 2) | (*(sptr + wpls3 - 1) << 30)) &
|
||
|
((*(sptr + wpls3) >> 1) | (*(sptr + wpls3 - 1) << 31)) &
|
||
|
(*(sptr + wpls3)) &
|
||
|
((*(sptr + wpls3) << 1) | (*(sptr + wpls3 + 1) >> 31)) &
|
||
|
((*(sptr + wpls3) << 2) | (*(sptr + wpls3 + 1) >> 30)) &
|
||
|
((*(sptr + wpls3) << 3) | (*(sptr + wpls3 + 1) >> 29));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
static void
|
||
|
fhmt_1_2(l_uint32 *datad,
|
||
|
l_int32 w,
|
||
|
l_int32 h,
|
||
|
l_int32 wpld,
|
||
|
l_uint32 *datas,
|
||
|
l_int32 wpls)
|
||
|
{
|
||
|
l_int32 i;
|
||
|
l_int32 j, pwpls;
|
||
|
l_uint32 *sptr, *dptr;
|
||
|
l_int32 wpls2, wpls3;
|
||
|
|
||
|
wpls2 = 2 * wpls;
|
||
|
wpls3 = 3 * wpls;
|
||
|
pwpls = (l_uint32)(w + 31) / 32; /* proper wpl of src */
|
||
|
|
||
|
for (i = 0; i < h; i++) {
|
||
|
sptr = datas + i * wpls;
|
||
|
dptr = datad + i * wpld;
|
||
|
for (j = 0; j < pwpls; j++, sptr++, dptr++) {
|
||
|
*dptr = ((*(sptr - wpls3) >> 3) | (*(sptr - wpls3 - 1) << 29)) &
|
||
|
((*(sptr - wpls3) >> 2) | (*(sptr - wpls3 - 1) << 30)) &
|
||
|
((*(sptr - wpls3) >> 1) | (*(sptr - wpls3 - 1) << 31)) &
|
||
|
(*(sptr - wpls3)) &
|
||
|
((*(sptr - wpls3) << 1) | (*(sptr - wpls3 + 1) >> 31)) &
|
||
|
((*(sptr - wpls3) << 2) | (*(sptr - wpls3 + 1) >> 30)) &
|
||
|
((*(sptr - wpls2) >> 3) | (*(sptr - wpls2 - 1) << 29)) &
|
||
|
((*(sptr - wpls) >> 3) | (*(sptr - wpls - 1) << 29)) &
|
||
|
(~*(sptr - wpls)) &
|
||
|
((*(sptr) >> 3) | (*(sptr - 1) << 29)) &
|
||
|
((~*(sptr) >> 1) | (~*(sptr - 1) << 31)) &
|
||
|
(~*sptr) &
|
||
|
((~*(sptr) << 1) | (~*(sptr + 1) >> 31)) &
|
||
|
((*(sptr + wpls) >> 3) | (*(sptr + wpls - 1) << 29)) &
|
||
|
(~*(sptr + wpls)) &
|
||
|
((~*(sptr + wpls) << 1) | (~*(sptr + wpls + 1) >> 31));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
static void
|
||
|
fhmt_1_3(l_uint32 *datad,
|
||
|
l_int32 w,
|
||
|
l_int32 h,
|
||
|
l_int32 wpld,
|
||
|
l_uint32 *datas,
|
||
|
l_int32 wpls)
|
||
|
{
|
||
|
l_int32 i;
|
||
|
l_int32 j, pwpls;
|
||
|
l_uint32 *sptr, *dptr;
|
||
|
l_int32 wpls2, wpls3;
|
||
|
|
||
|
wpls2 = 2 * wpls;
|
||
|
wpls3 = 3 * wpls;
|
||
|
pwpls = (l_uint32)(w + 31) / 32; /* proper wpl of src */
|
||
|
|
||
|
for (i = 0; i < h; i++) {
|
||
|
sptr = datas + i * wpls;
|
||
|
dptr = datad + i * wpld;
|
||
|
for (j = 0; j < pwpls; j++, sptr++, dptr++) {
|
||
|
*dptr = ((*(sptr - wpls3) >> 2) | (*(sptr - wpls3 - 1) << 30)) &
|
||
|
((*(sptr - wpls3) >> 1) | (*(sptr - wpls3 - 1) << 31)) &
|
||
|
(*(sptr - wpls3)) &
|
||
|
((*(sptr - wpls3) << 1) | (*(sptr - wpls3 + 1) >> 31)) &
|
||
|
((*(sptr - wpls3) << 2) | (*(sptr - wpls3 + 1) >> 30)) &
|
||
|
((*(sptr - wpls3) << 3) | (*(sptr - wpls3 + 1) >> 29)) &
|
||
|
((*(sptr - wpls2) << 3) | (*(sptr - wpls2 + 1) >> 29)) &
|
||
|
(~*(sptr - wpls)) &
|
||
|
((*(sptr - wpls) << 3) | (*(sptr - wpls + 1) >> 29)) &
|
||
|
((~*(sptr) >> 1) | (~*(sptr - 1) << 31)) &
|
||
|
(~*sptr) &
|
||
|
((~*(sptr) << 1) | (~*(sptr + 1) >> 31)) &
|
||
|
((*(sptr) << 3) | (*(sptr + 1) >> 29)) &
|
||
|
((~*(sptr + wpls) >> 1) | (~*(sptr + wpls - 1) << 31)) &
|
||
|
(~*(sptr + wpls)) &
|
||
|
((*(sptr + wpls) << 3) | (*(sptr + wpls + 1) >> 29));
|
||
|
}
|
||
|
}
|
||
|
}
|