mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-17 14:16:10 -06:00
226 lines
6.5 KiB
C
226 lines
6.5 KiB
C
/*====================================================================*
|
|
- Copyright (C) 2001 Leptonica. All rights reserved.
|
|
- This software is distributed in the hope that it will be
|
|
- useful, but with NO WARRANTY OF ANY KIND.
|
|
- No author or distributor accepts responsibility to anyone for the
|
|
- consequences of using this software, or for whether it serves any
|
|
- particular purpose or works at all, unless he or she says so in
|
|
- writing. Everyone is granted permission to copy, modify and
|
|
- redistribute this source code, for commercial or non-commercial
|
|
- purposes, with the following restrictions: (1) the origin of this
|
|
- source code must not be misrepresented; (2) modified versions must
|
|
- be plainly marked as such; and (3) this notice may not be removed
|
|
- or altered from any source or modified source distribution.
|
|
*====================================================================*/
|
|
|
|
/*
|
|
* binreduce.c
|
|
*
|
|
* Subsampled reduction
|
|
*
|
|
* PIX *pixReduceBinary2()
|
|
*
|
|
* Rank filtered reductions
|
|
*
|
|
* PIX *pixReduceRankBinaryCascade()
|
|
* PIX *pixReduceRankBinary2()
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include "allheaders.h"
|
|
|
|
|
|
/*------------------------------------------------------------------*
|
|
* Subsampled reduction *
|
|
*------------------------------------------------------------------*/
|
|
/*!
|
|
* pixReduceBinary2()
|
|
*
|
|
* Input: pixs
|
|
* tab (<optional>; if null, a table is made here
|
|
* and destroyed before exit)
|
|
* Return: pixd (2x subsampled), or null on error
|
|
*/
|
|
PIX *
|
|
pixReduceBinary2(PIX *pixs,
|
|
l_uint8 *intab)
|
|
{
|
|
l_uint8 *tab;
|
|
l_int32 ws, hs, wpls, wpld;
|
|
l_uint32 *datas, *datad;
|
|
PIX *pixd;
|
|
|
|
PROCNAME("pixReduceBinary2");
|
|
|
|
if (!pixs)
|
|
return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
|
|
|
|
if (pixGetDepth(pixs) != 1)
|
|
return (PIX *)ERROR_PTR("pixs not binary", procName, NULL);
|
|
|
|
if (intab) /* use input table */
|
|
tab = intab;
|
|
else {
|
|
if ((tab = makeSubsampleTab2x()) == NULL)
|
|
return (PIX *)ERROR_PTR("tab not made", procName, NULL);
|
|
}
|
|
|
|
ws = pixGetWidth(pixs);
|
|
hs = pixGetHeight(pixs);
|
|
if (hs <= 1)
|
|
return (PIX *)ERROR_PTR("hs must be at least 2", procName, NULL);
|
|
wpls = pixGetWpl(pixs);
|
|
datas = pixGetData(pixs);
|
|
|
|
if ((pixd = pixCreate(ws / 2, hs / 2, 1)) == NULL)
|
|
return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
|
|
pixCopyResolution(pixd, pixs);
|
|
pixScaleResolution(pixd, 0.5, 0.5);
|
|
wpld = pixGetWpl(pixd);
|
|
datad = pixGetData(pixd);
|
|
|
|
reduceBinary2Low(datad, wpld, datas, hs, wpls, tab);
|
|
|
|
if (intab == NULL)
|
|
FREE(tab);
|
|
|
|
return pixd;
|
|
}
|
|
|
|
|
|
/*------------------------------------------------------------------*
|
|
* Rank filtered binary reductions *
|
|
*------------------------------------------------------------------*/
|
|
/*!
|
|
* pixReduceRankBinaryCascade()
|
|
*
|
|
* Input: pixs (1 bpp)
|
|
* level1, ... level 4 (thresholds, in the set {0, 1, 2, 3, 4})
|
|
* Return: pixd, or null on error
|
|
*
|
|
* Notes:
|
|
* (1) This performs up to four cascaded 2x rank reductions.
|
|
* (2) Use level = 0 to truncate the cascade.
|
|
*/
|
|
PIX *
|
|
pixReduceRankBinaryCascade(PIX *pixs,
|
|
l_int32 level1,
|
|
l_int32 level2,
|
|
l_int32 level3,
|
|
l_int32 level4)
|
|
{
|
|
PIX *pix1, *pix2, *pix3, *pix4;
|
|
l_uint8 *tab;
|
|
|
|
PROCNAME("pixReduceRankBinaryCascade");
|
|
|
|
if (!pixs)
|
|
return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
|
|
if (pixGetDepth(pixs) != 1)
|
|
return (PIX *)ERROR_PTR("pixs must be binary", procName, NULL);
|
|
if (level1 > 4 || level2 > 4 || level3 > 4 || level4 > 4)
|
|
return (PIX *)ERROR_PTR("levels must not exceed 4", procName, NULL);
|
|
|
|
if (level1 <= 0) {
|
|
L_WARNING("no reduction because level1 not > 0", procName);
|
|
return pixCopy(NULL, pixs);
|
|
}
|
|
|
|
if ((tab = makeSubsampleTab2x()) == NULL)
|
|
return (PIX *)ERROR_PTR("tab not made", procName, NULL);
|
|
|
|
pix1 = pixReduceRankBinary2(pixs, level1, tab);
|
|
if (level2 <= 0) {
|
|
FREE(tab);
|
|
return pix1;
|
|
}
|
|
|
|
pix2 = pixReduceRankBinary2(pix1, level2, tab);
|
|
pixDestroy(&pix1);
|
|
if (level3 <= 0) {
|
|
FREE(tab);
|
|
return pix2;
|
|
}
|
|
|
|
pix3 = pixReduceRankBinary2(pix2, level3, tab);
|
|
pixDestroy(&pix2);
|
|
if (level4 <= 0) {
|
|
FREE(tab);
|
|
return pix3;
|
|
}
|
|
|
|
pix4 = pixReduceRankBinary2(pix3, level4, tab);
|
|
pixDestroy(&pix3);
|
|
FREE(tab);
|
|
return pix4;
|
|
}
|
|
|
|
|
|
/*!
|
|
* pixReduceRankBinary2()
|
|
*
|
|
* Input: pixs (1 bpp)
|
|
* level (rank threshold: 1, 2, 3, 4)
|
|
* intab (<optional>; if null, a table is made here
|
|
* and destroyed before exit)
|
|
* Return: pixd (1 bpp, 2x rank threshold reduced), or null on error
|
|
*
|
|
* Notes:
|
|
* (1) pixd is downscaled by 2x from pixs.
|
|
* (2) The rank threshold specifies the minimum number of ON
|
|
* pixels in each 2x2 region of pixs that are required to
|
|
* set the corresponding pixel ON in pixd.
|
|
*/
|
|
PIX *
|
|
pixReduceRankBinary2(PIX *pixs,
|
|
l_int32 level,
|
|
l_uint8 *intab)
|
|
{
|
|
l_uint8 *tab;
|
|
l_int32 ws, hs, wpls, wpld;
|
|
l_uint32 *datas, *datad;
|
|
PIX *pixd;
|
|
|
|
PROCNAME("pixReduceRankBinary2");
|
|
|
|
if (!pixs)
|
|
return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
|
|
|
|
if (pixGetDepth(pixs) != 1)
|
|
return (PIX *)ERROR_PTR("pixs not binary", procName, NULL);
|
|
if (level < 1 || level > 4)
|
|
return (PIX *)ERROR_PTR("level must be in set {1,2,3,4}",
|
|
procName, NULL);
|
|
|
|
if (intab) /* use input table */
|
|
tab = intab;
|
|
else {
|
|
if ((tab = makeSubsampleTab2x()) == NULL)
|
|
return (PIX *)ERROR_PTR("tab not made", procName, NULL);
|
|
}
|
|
|
|
ws = pixGetWidth(pixs);
|
|
hs = pixGetHeight(pixs);
|
|
if (hs <= 1)
|
|
return (PIX *)ERROR_PTR("hs must be at least 2", procName, NULL);
|
|
wpls = pixGetWpl(pixs);
|
|
datas = pixGetData(pixs);
|
|
|
|
if ((pixd = pixCreate(ws / 2, hs / 2, 1)) == NULL)
|
|
return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
|
|
pixCopyResolution(pixd, pixs);
|
|
pixScaleResolution(pixd, 0.5, 0.5);
|
|
wpld = pixGetWpl(pixd);
|
|
datad = pixGetData(pixd);
|
|
|
|
reduceRankBinary2Low(datad, wpld, datas, hs, wpls, tab, level);
|
|
|
|
if (!intab)
|
|
FREE(tab);
|
|
|
|
return pixd;
|
|
}
|
|
|
|
|