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 /* 00018 * binreducelow.c 00019 * 00020 * Low-level subsampled reduction 00021 * void reduceBinary2Low() 00022 * 00023 * Low-level threshold reduction 00024 * void reduceRankBinary2Low() 00025 * l_uint8 *makeSubsampleTab2x() 00026 * 00027 * 00028 */ 00029 00030 #include <stdio.h> 00031 #include <string.h> 00032 #include <stdlib.h> 00033 00034 #include "allheaders.h" 00035 00036 00037 00038 /*-------------------------------------------------------------------* 00039 * Low-level subsampled reduction * 00040 *-------------------------------------------------------------------*/ 00041 /*! 00042 * reduceBinary2Low() 00043 * 00044 * After folding, the data is in bytes 0 and 2 of the word, 00045 * and the bits in each byte are in the following order 00046 * (with 0 being the leftmost originating pair and 7 being 00047 * the rightmost originating pair): 00048 * 00049 * 0 4 1 5 2 6 3 7 00050 * 00051 * These need to be permuted to 00052 * 00053 * 0 1 2 3 4 5 6 7 00054 * 00055 * which is done with an 8-bit table generated by 00056 * makeSubsampleTab2x(). 00057 * 00058 */ 00059 void 00060 reduceBinary2Low(l_uint32 *datad, 00061 l_int32 wpld, 00062 l_uint32 *datas, 00063 l_int32 hs, 00064 l_int32 wpls, 00065 l_uint8 *tab) 00066 { 00067 l_int32 i, id, j, wplsi; 00068 l_uint8 byte0, byte1; 00069 l_uint16 shortd; 00070 l_uint32 word; 00071 l_uint32 *lines, *lined; 00072 00073 /* e.g., if ws = 65: wd = 32, wpls = 3, wpld = 1 --> trouble */ 00074 wplsi = L_MIN(wpls, 2 * wpld); /* iterate over this number of words */ 00075 00076 for (i = 0, id = 0; i < hs - 1; i += 2, id++) { 00077 lines = datas + i * wpls; 00078 lined = datad + id * wpld; 00079 for (j = 0; j < wplsi; j++) { 00080 word = *(lines + j); 00081 word = word & 0xaaaaaaaa; /* mask */ 00082 word = word | (word << 7); /* fold; data in bytes 0 & 2 */ 00083 byte0 = word >> 24; 00084 byte1 = (word >> 8) & 0xff; 00085 shortd = (tab[byte0] << 8) | tab[byte1]; 00086 SET_DATA_TWO_BYTES(lined, j, shortd); 00087 } 00088 } 00089 00090 return; 00091 } 00092 00093 00094 /*-------------------------------------------------------------------* 00095 * Low-level rank filtered reduction * 00096 *-------------------------------------------------------------------*/ 00097 /*! 00098 * reduceRankBinary2Low() 00099 * 00100 * Rank filtering is done to the UL corner of each 2x2 pixel block, 00101 * using only logical operations. 00102 * 00103 * Then these pixels are chosen in the 2x subsampling process, 00104 * subsampled, as described above in reduceBinary2Low(). 00105 */ 00106 void 00107 reduceRankBinary2Low(l_uint32 *datad, 00108 l_int32 wpld, 00109 l_uint32 *datas, 00110 l_int32 hs, 00111 l_int32 wpls, 00112 l_uint8 *tab, 00113 l_int32 level) 00114 { 00115 l_int32 i, id, j, wplsi; 00116 l_uint8 byte0, byte1; 00117 l_uint16 shortd; 00118 l_uint32 word1, word2, word3, word4; 00119 l_uint32 *lines, *lined; 00120 00121 /* e.g., if ws = 65: wd = 32, wpls = 3, wpld = 1 --> trouble */ 00122 wplsi = L_MIN(wpls, 2 * wpld); /* iterate over this number of words */ 00123 00124 switch (level) 00125 { 00126 00127 case 1: 00128 for (i = 0, id = 0; i < hs - 1; i += 2, id++) { 00129 lines = datas + i * wpls; 00130 lined = datad + id * wpld; 00131 for (j = 0; j < wplsi; j++) { 00132 word1 = *(lines + j); 00133 word2 = *(lines + wpls + j); 00134 00135 /* OR/OR */ 00136 word2 = word1 | word2; 00137 word2 = word2 | (word2 << 1); 00138 00139 word2 = word2 & 0xaaaaaaaa; /* mask */ 00140 word1 = word2 | (word2 << 7); /* fold; data in bytes 0 & 2 */ 00141 byte0 = word1 >> 24; 00142 byte1 = (word1 >> 8) & 0xff; 00143 shortd = (tab[byte0] << 8) | tab[byte1]; 00144 SET_DATA_TWO_BYTES(lined, j, shortd); 00145 } 00146 } 00147 break; 00148 00149 case 2: 00150 for (i = 0, id = 0; i < hs - 1; i += 2, id++) { 00151 lines = datas + i * wpls; 00152 lined = datad + id * wpld; 00153 for (j = 0; j < wplsi; j++) { 00154 word1 = *(lines + j); 00155 word2 = *(lines + wpls + j); 00156 00157 /* (AND/OR) OR (OR/AND) */ 00158 word3 = word1 & word2; 00159 word3 = word3 | (word3 << 1); 00160 word4 = word1 | word2; 00161 word4 = word4 & (word4 << 1); 00162 word2 = word3 | word4; 00163 00164 word2 = word2 & 0xaaaaaaaa; /* mask */ 00165 word1 = word2 | (word2 << 7); /* fold; data in bytes 0 & 2 */ 00166 byte0 = word1 >> 24; 00167 byte1 = (word1 >> 8) & 0xff; 00168 shortd = (tab[byte0] << 8) | tab[byte1]; 00169 SET_DATA_TWO_BYTES(lined, j, shortd); 00170 } 00171 } 00172 break; 00173 00174 case 3: 00175 for (i = 0, id = 0; i < hs - 1; i += 2, id++) { 00176 lines = datas + i * wpls; 00177 lined = datad + id * wpld; 00178 for (j = 0; j < wplsi; j++) { 00179 word1 = *(lines + j); 00180 word2 = *(lines + wpls + j); 00181 00182 /* (AND/OR) AND (OR/AND) */ 00183 word3 = word1 & word2; 00184 word3 = word3 | (word3 << 1); 00185 word4 = word1 | word2; 00186 word4 = word4 & (word4 << 1); 00187 word2 = word3 & word4; 00188 00189 word2 = word2 & 0xaaaaaaaa; /* mask */ 00190 word1 = word2 | (word2 << 7); /* fold; data in bytes 0 & 2 */ 00191 byte0 = word1 >> 24; 00192 byte1 = (word1 >> 8) & 0xff; 00193 shortd = (tab[byte0] << 8) | tab[byte1]; 00194 SET_DATA_TWO_BYTES(lined, j, shortd); 00195 } 00196 } 00197 break; 00198 00199 case 4: 00200 for (i = 0, id = 0; i < hs - 1; i += 2, id++) { 00201 lines = datas + i * wpls; 00202 lined = datad + id * wpld; 00203 for (j = 0; j < wplsi; j++) { 00204 word1 = *(lines + j); 00205 word2 = *(lines + wpls + j); 00206 00207 /* AND/AND */ 00208 word2 = word1 & word2; 00209 word2 = word2 & (word2 << 1); 00210 00211 word2 = word2 & 0xaaaaaaaa; /* mask */ 00212 word1 = word2 | (word2 << 7); /* fold; data in bytes 0 & 2 */ 00213 byte0 = word1 >> 24; 00214 byte1 = (word1 >> 8) & 0xff; 00215 shortd = (tab[byte0] << 8) | tab[byte1]; 00216 SET_DATA_TWO_BYTES(lined, j, shortd); 00217 } 00218 } 00219 break; 00220 } 00221 00222 return; 00223 } 00224 00225 00226 00227 00228 /*! 00229 * makeSubsampleTab2x() 00230 * 00231 * This table permutes the bits in a byte, from 00232 * 0 4 1 5 2 6 3 7 00233 * to 00234 * 0 1 2 3 4 5 6 7 00235 */ 00236 l_uint8 * 00237 makeSubsampleTab2x(void) 00238 { 00239 l_uint8 *tab; 00240 l_int32 i; 00241 00242 PROCNAME("makeSubsampleTab2x"); 00243 00244 if ((tab = (l_uint8 *) CALLOC(256, sizeof(l_uint8))) == NULL) 00245 return (l_uint8 *)ERROR_PTR("tab not made", procName, NULL); 00246 00247 for (i = 0; i < 256; i++) 00248 tab[i] = ((i & 0x01) ) | /* 7 */ 00249 ((i & 0x04) >> 1) | /* 6 */ 00250 ((i & 0x10) >> 2) | /* 5 */ 00251 ((i & 0x40) >> 3) | /* 4 */ 00252 ((i & 0x02) << 3) | /* 3 */ 00253 ((i & 0x08) << 2) | /* 2 */ 00254 ((i & 0x20) << 1) | /* 1 */ 00255 ((i & 0x80) ); /* 0 */ 00256 00257 return tab; 00258 } 00259