Leptonica 1.68
C Image Processing Library

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