mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-29 14:22:25 -06:00
259 lines
8 KiB
C
259 lines
8 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.
|
|
*====================================================================*/
|
|
|
|
|
|
/*
|
|
* binreducelow.c
|
|
*
|
|
* Low-level subsampled reduction
|
|
* void reduceBinary2Low()
|
|
*
|
|
* Low-level threshold reduction
|
|
* void reduceRankBinary2Low()
|
|
* l_uint8 *makeSubsampleTab2x()
|
|
*
|
|
*
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
|
|
#include "allheaders.h"
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------*
|
|
* Low-level subsampled reduction *
|
|
*-------------------------------------------------------------------*/
|
|
/*!
|
|
* reduceBinary2Low()
|
|
*
|
|
* After folding, the data is in bytes 0 and 2 of the word,
|
|
* and the bits in each byte are in the following order
|
|
* (with 0 being the leftmost originating pair and 7 being
|
|
* the rightmost originating pair):
|
|
*
|
|
* 0 4 1 5 2 6 3 7
|
|
*
|
|
* These need to be permuted to
|
|
*
|
|
* 0 1 2 3 4 5 6 7
|
|
*
|
|
* which is done with an 8-bit table generated by
|
|
* makeSubsampleTab2x().
|
|
*
|
|
*/
|
|
void
|
|
reduceBinary2Low(l_uint32 *datad,
|
|
l_int32 wpld,
|
|
l_uint32 *datas,
|
|
l_int32 hs,
|
|
l_int32 wpls,
|
|
l_uint8 *tab)
|
|
{
|
|
l_int32 i, id, j, wplsi;
|
|
l_uint8 byte0, byte1;
|
|
l_uint16 shortd;
|
|
l_uint32 word;
|
|
l_uint32 *lines, *lined;
|
|
|
|
/* e.g., if ws = 65: wd = 32, wpls = 3, wpld = 1 --> trouble */
|
|
wplsi = L_MIN(wpls, 2 * wpld); /* iterate over this number of words */
|
|
|
|
for (i = 0, id = 0; i < hs - 1; i += 2, id++) {
|
|
lines = datas + i * wpls;
|
|
lined = datad + id * wpld;
|
|
for (j = 0; j < wplsi; j++) {
|
|
word = *(lines + j);
|
|
word = word & 0xaaaaaaaa; /* mask */
|
|
word = word | (word << 7); /* fold; data in bytes 0 & 2 */
|
|
byte0 = word >> 24;
|
|
byte1 = (word >> 8) & 0xff;
|
|
shortd = (tab[byte0] << 8) | tab[byte1];
|
|
SET_DATA_TWO_BYTES(lined, j, shortd);
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------------------------*
|
|
* Low-level rank filtered reduction *
|
|
*-------------------------------------------------------------------*/
|
|
/*!
|
|
* reduceRankBinary2Low()
|
|
*
|
|
* Rank filtering is done to the UL corner of each 2x2 pixel block,
|
|
* using only logical operations.
|
|
*
|
|
* Then these pixels are chosen in the 2x subsampling process,
|
|
* subsampled, as described above in reduceBinary2Low().
|
|
*/
|
|
void
|
|
reduceRankBinary2Low(l_uint32 *datad,
|
|
l_int32 wpld,
|
|
l_uint32 *datas,
|
|
l_int32 hs,
|
|
l_int32 wpls,
|
|
l_uint8 *tab,
|
|
l_int32 level)
|
|
{
|
|
l_int32 i, id, j, wplsi;
|
|
l_uint8 byte0, byte1;
|
|
l_uint16 shortd;
|
|
l_uint32 word1, word2, word3, word4;
|
|
l_uint32 *lines, *lined;
|
|
|
|
/* e.g., if ws = 65: wd = 32, wpls = 3, wpld = 1 --> trouble */
|
|
wplsi = L_MIN(wpls, 2 * wpld); /* iterate over this number of words */
|
|
|
|
switch (level)
|
|
{
|
|
|
|
case 1:
|
|
for (i = 0, id = 0; i < hs - 1; i += 2, id++) {
|
|
lines = datas + i * wpls;
|
|
lined = datad + id * wpld;
|
|
for (j = 0; j < wplsi; j++) {
|
|
word1 = *(lines + j);
|
|
word2 = *(lines + wpls + j);
|
|
|
|
/* OR/OR */
|
|
word2 = word1 | word2;
|
|
word2 = word2 | (word2 << 1);
|
|
|
|
word2 = word2 & 0xaaaaaaaa; /* mask */
|
|
word1 = word2 | (word2 << 7); /* fold; data in bytes 0 & 2 */
|
|
byte0 = word1 >> 24;
|
|
byte1 = (word1 >> 8) & 0xff;
|
|
shortd = (tab[byte0] << 8) | tab[byte1];
|
|
SET_DATA_TWO_BYTES(lined, j, shortd);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 2:
|
|
for (i = 0, id = 0; i < hs - 1; i += 2, id++) {
|
|
lines = datas + i * wpls;
|
|
lined = datad + id * wpld;
|
|
for (j = 0; j < wplsi; j++) {
|
|
word1 = *(lines + j);
|
|
word2 = *(lines + wpls + j);
|
|
|
|
/* (AND/OR) OR (OR/AND) */
|
|
word3 = word1 & word2;
|
|
word3 = word3 | (word3 << 1);
|
|
word4 = word1 | word2;
|
|
word4 = word4 & (word4 << 1);
|
|
word2 = word3 | word4;
|
|
|
|
word2 = word2 & 0xaaaaaaaa; /* mask */
|
|
word1 = word2 | (word2 << 7); /* fold; data in bytes 0 & 2 */
|
|
byte0 = word1 >> 24;
|
|
byte1 = (word1 >> 8) & 0xff;
|
|
shortd = (tab[byte0] << 8) | tab[byte1];
|
|
SET_DATA_TWO_BYTES(lined, j, shortd);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 3:
|
|
for (i = 0, id = 0; i < hs - 1; i += 2, id++) {
|
|
lines = datas + i * wpls;
|
|
lined = datad + id * wpld;
|
|
for (j = 0; j < wplsi; j++) {
|
|
word1 = *(lines + j);
|
|
word2 = *(lines + wpls + j);
|
|
|
|
/* (AND/OR) AND (OR/AND) */
|
|
word3 = word1 & word2;
|
|
word3 = word3 | (word3 << 1);
|
|
word4 = word1 | word2;
|
|
word4 = word4 & (word4 << 1);
|
|
word2 = word3 & word4;
|
|
|
|
word2 = word2 & 0xaaaaaaaa; /* mask */
|
|
word1 = word2 | (word2 << 7); /* fold; data in bytes 0 & 2 */
|
|
byte0 = word1 >> 24;
|
|
byte1 = (word1 >> 8) & 0xff;
|
|
shortd = (tab[byte0] << 8) | tab[byte1];
|
|
SET_DATA_TWO_BYTES(lined, j, shortd);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 4:
|
|
for (i = 0, id = 0; i < hs - 1; i += 2, id++) {
|
|
lines = datas + i * wpls;
|
|
lined = datad + id * wpld;
|
|
for (j = 0; j < wplsi; j++) {
|
|
word1 = *(lines + j);
|
|
word2 = *(lines + wpls + j);
|
|
|
|
/* AND/AND */
|
|
word2 = word1 & word2;
|
|
word2 = word2 & (word2 << 1);
|
|
|
|
word2 = word2 & 0xaaaaaaaa; /* mask */
|
|
word1 = word2 | (word2 << 7); /* fold; data in bytes 0 & 2 */
|
|
byte0 = word1 >> 24;
|
|
byte1 = (word1 >> 8) & 0xff;
|
|
shortd = (tab[byte0] << 8) | tab[byte1];
|
|
SET_DATA_TWO_BYTES(lined, j, shortd);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
|
|
/*!
|
|
* makeSubsampleTab2x()
|
|
*
|
|
* This table permutes the bits in a byte, from
|
|
* 0 4 1 5 2 6 3 7
|
|
* to
|
|
* 0 1 2 3 4 5 6 7
|
|
*/
|
|
l_uint8 *
|
|
makeSubsampleTab2x(void)
|
|
{
|
|
l_uint8 *tab;
|
|
l_int32 i;
|
|
|
|
PROCNAME("makeSubsampleTab2x");
|
|
|
|
if ((tab = (l_uint8 *) CALLOC(256, sizeof(l_uint8))) == NULL)
|
|
return (l_uint8 *)ERROR_PTR("tab not made", procName, NULL);
|
|
|
|
for (i = 0; i < 256; i++)
|
|
tab[i] = ((i & 0x01) ) | /* 7 */
|
|
((i & 0x04) >> 1) | /* 6 */
|
|
((i & 0x10) >> 2) | /* 5 */
|
|
((i & 0x40) >> 3) | /* 4 */
|
|
((i & 0x02) << 3) | /* 3 */
|
|
((i & 0x08) << 2) | /* 2 */
|
|
((i & 0x20) << 1) | /* 1 */
|
|
((i & 0x80) ); /* 0 */
|
|
|
|
return tab;
|
|
}
|
|
|