Leptonica  1.83.1
Image processing and image analysis suite
grayquant.c File Reference
#include <string.h>
#include <math.h>
#include "allheaders.h"

Go to the source code of this file.

Macros

#define DEBUG_UNROLLING   0
 

Functions

static void ditherToBinaryLow (l_uint32 *datad, l_int32 w, l_int32 h, l_int32 wpld, l_uint32 *datas, l_int32 wpls, l_uint32 *bufs1, l_uint32 *bufs2, l_int32 lowerclip, l_int32 upperclip)
 
static void thresholdToBinaryLow (l_uint32 *datad, l_int32 w, l_int32 h, l_int32 wpld, l_uint32 *datas, l_int32 d, l_int32 wpls, l_int32 thresh)
 
static void ditherTo2bppLow (l_uint32 *datad, l_int32 w, l_int32 h, l_int32 wpld, l_uint32 *datas, l_int32 wpls, l_uint32 *bufs1, l_uint32 *bufs2, l_int32 *tabval, l_int32 *tab38, l_int32 *tab14)
 
static void ditherTo2bppLineLow (l_uint32 *lined, l_int32 w, l_uint32 *bufs1, l_uint32 *bufs2, l_int32 *tabval, l_int32 *tab38, l_int32 *tab14, l_int32 lastlineflag)
 
static l_int32 make8To2DitherTables (l_int32 **ptabval, l_int32 **ptab38, l_int32 **ptab14, l_int32 cliptoblack, l_int32 cliptowhite)
 
static void thresholdTo2bppLow (l_uint32 *datad, l_int32 h, l_int32 wpld, l_uint32 *datas, l_int32 wpls, l_int32 *tab)
 
static void thresholdTo4bppLow (l_uint32 *datad, l_int32 h, l_int32 wpld, l_uint32 *datas, l_int32 wpls, l_int32 *tab)
 
static l_int32 * makeGrayQuantTargetTable (l_int32 nlevels, l_int32 depth)
 
static l_int32 makeGrayQuantColormapArb (PIX *pixs, l_int32 *tab, l_int32 outdepth, PIXCMAP **pcmap)
 
static l_int32 numaFillCmapFromHisto (NUMA *na, PIXCMAP *cmap, l_float32 minfract, l_int32 maxsize, l_int32 **plut)
 
PIXpixDitherToBinary (PIX *pixs)
 
PIXpixDitherToBinarySpec (PIX *pixs, l_int32 lowerclip, l_int32 upperclip)
 
void ditherToBinaryLineLow (l_uint32 *lined, l_int32 w, l_uint32 *bufs1, l_uint32 *bufs2, l_int32 lowerclip, l_int32 upperclip, l_int32 lastlineflag)
 
PIXpixThresholdToBinary (PIX *pixs, l_int32 thresh)
 
void thresholdToBinaryLineLow (l_uint32 *lined, l_int32 w, l_uint32 *lines, l_int32 d, l_int32 thresh)
 
PIXpixVarThresholdToBinary (PIX *pixs, PIX *pixg)
 
PIXpixAdaptThresholdToBinary (PIX *pixs, PIX *pixm, l_float32 gamma)
 
PIXpixAdaptThresholdToBinaryGen (PIX *pixs, PIX *pixm, l_float32 gamma, l_int32 blackval, l_int32 whiteval, l_int32 thresh)
 
PIXpixGenerateMaskByValue (PIX *pixs, l_int32 val, l_int32 usecmap)
 
PIXpixGenerateMaskByBand (PIX *pixs, l_int32 lower, l_int32 upper, l_int32 inband, l_int32 usecmap)
 
PIXpixDitherTo2bpp (PIX *pixs, l_int32 cmapflag)
 
PIXpixDitherTo2bppSpec (PIX *pixs, l_int32 lowerclip, l_int32 upperclip, l_int32 cmapflag)
 
PIXpixThresholdTo2bpp (PIX *pixs, l_int32 nlevels, l_int32 cmapflag)
 
PIXpixThresholdTo4bpp (PIX *pixs, l_int32 nlevels, l_int32 cmapflag)
 
PIXpixThresholdOn8bpp (PIX *pixs, l_int32 nlevels, l_int32 cmapflag)
 
PIXpixThresholdGrayArb (PIX *pixs, const char *edgevals, l_int32 outdepth, l_int32 use_average, l_int32 setblack, l_int32 setwhite)
 
l_int32 * makeGrayQuantIndexTable (l_int32 nlevels)
 
l_ok makeGrayQuantTableArb (NUMA *na, l_int32 outdepth, l_int32 **ptab, PIXCMAP **pcmap)
 
PIXpixGenerateMaskByBand32 (PIX *pixs, l_uint32 refval, l_int32 delm, l_int32 delp, l_float32 fractm, l_float32 fractp)
 
PIXpixGenerateMaskByDiscr32 (PIX *pixs, l_uint32 refval1, l_uint32 refval2, l_int32 distflag)
 
PIXpixGrayQuantFromHisto (PIX *pixd, PIX *pixs, PIX *pixm, l_float32 minfract, l_int32 maxsize)
 
PIXpixGrayQuantFromCmap (PIX *pixs, PIXCMAP *cmap, l_int32 mindepth)
 

Detailed Description


     Thresholding from 8 bpp to 1 bpp

         Floyd-Steinberg dithering to binary
             PIX         *pixDitherToBinary()
             PIX         *pixDitherToBinarySpec()
             static void  ditherToBinaryLow()
             void         ditherToBinaryLineLow()

         Simple (pixelwise) binarization with fixed threshold
             PIX         *pixThresholdToBinary()
             static void  thresholdToBinaryLow()
             void         thresholdToBinaryLineLow()

         Binarization with variable threshold
             PIX         *pixVarThresholdToBinary()

         Binarization by adaptive mapping
             PIX         *pixAdaptThresholdToBinary()
             PIX         *pixAdaptThresholdToBinaryGen()

         Generate a binary mask from pixels of particular values
             PIX         *pixGenerateMaskByValue()
             PIX         *pixGenerateMaskByBand()

     Thresholding from 8 bpp to 2 bpp

         Floyd-Steinberg-like dithering to 2 bpp
             PIX         *pixDitherTo2bpp()
             PIX         *pixDitherTo2bppSpec()
             static void  ditherTo2bppLow()
             static void  ditherTo2bppLineLow()
             static l_int32  make8To2DitherTables()

         Simple (pixelwise) thresholding to 2 bpp with optional cmap
             PIX         *pixThresholdTo2bpp()
             static void  thresholdTo2bppLow()

     Simple (pixelwise) thresholding from 8 bpp to 4 bpp
             PIX         *pixThresholdTo4bpp()
             static void  thresholdTo4bppLow()

     Simple (pixelwise) quantization on 8 bpp grayscale
             PIX         *pixThresholdOn8bpp()

     Arbitrary (pixelwise) thresholding from 8 bpp to 2, 4 or 8 bpp
             PIX         *pixThresholdGrayArb()

     Quantization tables for linear thresholds of grayscale images
             l_int32     *makeGrayQuantIndexTable()
             static l_int32  *makeGrayQuantTargetTable()

     Quantization table for arbitrary thresholding of grayscale images
             l_int32      makeGrayQuantTableArb()
             static l_int32   makeGrayQuantColormapArb()

     Thresholding from 32 bpp rgb to 1 bpp
     (really color quantization, but it's better placed in this file)
             PIX         *pixGenerateMaskByBand32()
             PIX         *pixGenerateMaskByDiscr32()

     Histogram-based grayscale quantization
             PIX         *pixGrayQuantFromHisto()
             static l_int32  numaFillCmapFromHisto()

     Color quantize grayscale image using existing colormap
             PIX         *pixGrayQuantFromCmap()

Definition in file grayquant.c.

Function Documentation

◆ ditherTo2bppLineLow()

static void ditherTo2bppLineLow ( l_uint32 *  lined,
l_int32  w,
l_uint32 *  bufs1,
l_uint32 *  bufs2,
l_int32 *  tabval,
l_int32 *  tab38,
l_int32 *  tab14,
l_int32  lastlineflag 
)
static

ditherTo2bppLineLow()

Parameters
[in]linedptr to beginning of dest line
[in]wwidth of image in pixels
[in]bufs1buffer of current source line
[in]bufs2buffer of next source line
[in]tabvalvalue to assign for current pixel
[in]tab38excess value to give to neighboring 3/8 pixels
[in]tab14excess value to give to neighboring 1/4 pixel
[in]lastlineflag0 if not last dest line, 1 if last dest line
Returns
void

Dispatches error diffusion dithering for a single line of the image. If lastlineflag == 0, both source buffers are used; otherwise, only bufs1 is used. We use source buffers because the error is propagated into them, and we don't want to change the input src image.

We break dithering out line by line to make it easier to combine functions like interpolative scaling and error diffusion dithering, as such a combination of operations obviates the need to generate a 2x grayscale image as an intermediary.

Definition at line 1173 of file grayquant.c.

References GET_DATA_BYTE, SET_DATA_BYTE, and SET_DATA_DIBIT.

Referenced by ditherTo2bppLow().

◆ ditherTo2bppLow()

static void ditherTo2bppLow ( l_uint32 *  datad,
l_int32  w,
l_int32  h,
l_int32  wpld,
l_uint32 *  datas,
l_int32  wpls,
l_uint32 *  bufs1,
l_uint32 *  bufs2,
l_int32 *  tabval,
l_int32 *  tab38,
l_int32 *  tab14 
)
static

ditherTo2bppLow()

Low-level function for doing Floyd-Steinberg error diffusion dithering from 8 bpp (datas) to 2 bpp (datad). Two source line buffers, bufs1 and bufs2, are provided, along with three 256-entry lookup tables: tabval gives the output pixel value, tab38 gives the extra (plus or minus) transferred to the pixels directly to the left and below, and tab14 gives the extra transferred to the diagonal below. The choice of 3/8 and 1/4 is traditional but arbitrary when you use a lookup table; the only constraint is that the sum is 1. See other comments below and in grayquant.c.

Definition at line 1115 of file grayquant.c.

References ditherTo2bppLineLow().

◆ ditherToBinaryLineLow()

void ditherToBinaryLineLow ( l_uint32 *  lined,
l_int32  w,
l_uint32 *  bufs1,
l_uint32 *  bufs2,
l_int32  lowerclip,
l_int32  upperclip,
l_int32  lastlineflag 
)

ditherToBinaryLineLow()

Parameters
[in]linedptr to beginning of dest line
[in]wwidth of image in pixels
[in]bufs1buffer of current source line
[in]bufs2buffer of next source line
[in]lowercliplower clip distance to black
[in]upperclipupper clip distance to white
[in]lastlineflag0 if not last dest line, 1 if last dest line
Returns
void

Dispatches FS error diffusion dithering for a single line of the image. If lastlineflag == 0, both source buffers are used; otherwise, only bufs1 is used. We use source buffers because the error is propagated into them, and we don't want to change the input src image.

We break dithering out line by line to make it easier to combine functions like interpolative scaling and error diffusion dithering, as such a combination of operations obviates the need to generate a 2x grayscale image as an intermediary.

Definition at line 322 of file grayquant.c.

References GET_DATA_BYTE, SET_DATA_BIT, and SET_DATA_BYTE.

Referenced by ditherToBinaryLow().

◆ ditherToBinaryLow()

static void ditherToBinaryLow ( l_uint32 *  datad,
l_int32  w,
l_int32  h,
l_int32  wpld,
l_uint32 *  datas,
l_int32  wpls,
l_uint32 *  bufs1,
l_uint32 *  bufs2,
l_int32  lowerclip,
l_int32  upperclip 
)
static

ditherToBinaryLow()

See comments in pixDitherToBinary() in binarize.c

Definition at line 266 of file grayquant.c.

References ditherToBinaryLineLow().

◆ make8To2DitherTables()

static l_int32 make8To2DitherTables ( l_int32 **  ptabval,
l_int32 **  ptab38,
l_int32 **  ptab14,
l_int32  cliptoblack,
l_int32  cliptowhite 
)
static

make8To2DitherTables()

Parameters
[out]ptabvalvalue assigned to output pixel; 0, 1, 2 or 3
[out]ptab38amount propagated to pixels left and below
[out]ptab14amount propagated to pixel to left and down
[in]cliptoblackvalues near 0 where the excess is not propagated
[in]cliptowhitevalues near 255 where the deficit is not propagated
Returns
0 if OK, 1 on error

Definition at line 1251 of file grayquant.c.

◆ makeGrayQuantColormapArb()

static l_int32 makeGrayQuantColormapArb ( PIX pixs,
l_int32 *  tab,
l_int32  outdepth,
PIXCMAP **  pcmap 
)
static

makeGrayQuantColormapArb()

Parameters
[in]pixs8 bpp
[in]tabtable mapping input gray level to cmap index
[in]outdepthof colormap: 1, 2, 4 or 8
[out]pcmapcolormap
Returns
0 if OK, 1 on error
Notes:
     (1) The table is a 256-entry inverse colormap: it maps input gray
         level to colormap index (the bin number).  It is computed
         using makeGrayQuantTableArb().
     (2) The colormap generated here has quantized values at the
         average gray value of the pixels that are in each bin.
     (3) Returns an error if there are not enough levels in the
         output colormap for the number of bins.  The number
         of bins must not exceed 2^outdepth.

Definition at line 1990 of file grayquant.c.

References pixGetData(), and pixGetDimensions().

Referenced by pixThresholdGrayArb().

◆ makeGrayQuantIndexTable()

l_int32* makeGrayQuantIndexTable ( l_int32  nlevels)

makeGrayQuantIndexTable()

Parameters
[in]nlevelsnumber of output levels
Returns
table maps input gray level to colormap index, or NULL on error
Notes:
     (1) 'nlevels' is some number between 2 and 256 (typically 8 or less).
     (2) The table is typically used for quantizing 2, 4 and 8 bpp
         grayscale src pix, and generating a colormapped dest pix.

Definition at line 1818 of file grayquant.c.

◆ makeGrayQuantTableArb()

l_ok makeGrayQuantTableArb ( NUMA na,
l_int32  outdepth,
l_int32 **  ptab,
PIXCMAP **  pcmap 
)

makeGrayQuantTableArb()

Parameters
[in]nanuma of bin boundaries
[in]outdepthof colormap: 1, 2, 4 or 8
[out]ptabtable mapping input gray level to cmap index
[out]pcmapcolormap
Returns
0 if OK, 1 on error
Notes:
     (1) The number of bins is the count of na + 1.
     (2) The bin boundaries in na must be sorted in increasing order.
     (3) The table is an inverse colormap: it maps input gray level
         to colormap index (the bin number).
     (4) The colormap generated here has quantized values at the
         center of each bin.  If you want to use the average gray
         value of pixels within the bin, discard the colormap and
         compute it using makeGrayQuantColormapArb().
     (5) Returns an error if there are not enough levels in the
         output colormap for the number of bins.  The number
         of bins must not exceed 2^outdepth.

Definition at line 1920 of file grayquant.c.

References numaGetCount(), numaGetIValue(), pixcmapAddColor(), and pixcmapCreate().

Referenced by pixThresholdGrayArb().

◆ makeGrayQuantTargetTable()

static l_int32 * makeGrayQuantTargetTable ( l_int32  nlevels,
l_int32  depth 
)
static

makeGrayQuantTargetTable()

Parameters
[in]nlevelsnumber of output levels
[in]depthof dest pix, in bpp; 2, 4 or 8 bpp
Returns
table maps input gray level to thresholded gray level, or NULL on error
Notes:
     (1) nlevels is some number between 2 and 2^(depth)
     (2) The table is used in two similar ways:
          ~ for 8 bpp, it quantizes to a given number of target levels
          ~ for 2 and 4 bpp, it thresholds to appropriate target values
            that will use the full dynamic range of the dest pix.
     (3) For depth = 8, the number of thresholds chosen is
         ('nlevels' - 1), and the 'nlevels' values stored in the
         table are at the two at the extreme ends, (0, 255), plus
         plus ('nlevels' - 2) values chosen at equal intervals between.
         For example, for depth = 8 and 'nlevels' = 3, the two
         threshold values are 3f and bf, and the three target pixel
         values are 0, 7f and ff.
     (4) For depth < 8, we ignore nlevels, and always use the maximum
         number of levels, which is 2^(depth).
         If you want nlevels < the maximum number, you should always
         use a colormap.

Definition at line 1867 of file grayquant.c.

◆ numaFillCmapFromHisto()

static l_int32 numaFillCmapFromHisto ( NUMA na,
PIXCMAP cmap,
l_float32  minfract,
l_int32  maxsize,
l_int32 **  plut 
)
static

numaFillCmapFromHisto()

Parameters
[in]nahistogram of gray values
[in]cmap8 bpp cmap, possibly initialized with color value
[in]minfractminimum fraction of pixels in a set of adjacent histo bins that causes the set to be automatically set aside as a color in the colormap; must be at least 0.01
[in]maxsizemaximum number of adjacent bins allowed to represent a color, regardless of the population of pixels in the bins; must be at least 2
[out]plutlookup table from gray value to colormap index
Returns
0 if OK, 1 on error
Notes:
     (1) This static function must be called from pixGrayQuantFromHisto()

Definition at line 2431 of file grayquant.c.

References numaGetIArray(), numaGetSum(), pixcmapAddColor(), and pixcmapGetCount().

◆ pixAdaptThresholdToBinary()

PIX* pixAdaptThresholdToBinary ( PIX pixs,
PIX pixm,
l_float32  gamma 
)

pixAdaptThresholdToBinary()

Parameters
[in]pixs8 bpp
[in]pixm[optional] 1 bpp image mask; can be null
[in]gammagamma correction; must be > 0.0; typically ~1.0
Returns
pixd 1 bpp, or NULL on error
Notes:
     (1) This is a simple convenience function for doing adaptive
         thresholding on a grayscale image with variable background.
         It uses default parameters appropriate for typical text images.
     (2) pixm is a 1 bpp mask over "image" regions, which are not
         expected to have a white background.  The mask inhibits
         background finding under the fg pixels of the mask.  For
         images with both text and image, the image regions would
         be binarized (or quantized) by a different set of operations.
     (3) As gamma is increased, the foreground pixels are reduced.
     (4) Under the covers:  The default background value for normalization
         is 200, so we choose 170 for 'maxval' in pixGammaTRC.  Likewise,
         the default foreground threshold for normalization is 60,
         so we choose 50 for 'minval' in pixGammaTRC.  Because
         170 was mapped to 255, choosing 200 for the threshold is
         quite safe for avoiding speckle noise from the background.

Definition at line 720 of file grayquant.c.

◆ pixAdaptThresholdToBinaryGen()

PIX* pixAdaptThresholdToBinaryGen ( PIX pixs,
PIX pixm,
l_float32  gamma,
l_int32  blackval,
l_int32  whiteval,
l_int32  thresh 
)

pixAdaptThresholdToBinaryGen()

Parameters
[in]pixs8 bpp
[in]pixm[optional] 1 bpp image mask; can be null
[in]gammagamma correction; must be > 0.0; typically ~1.0
[in]blackvaldark value to set to black (0)
[in]whitevallight value to set to white (255)
[in]threshfinal threshold for binarization
Returns
pixd 1 bpp, or NULL on error
Notes:
     (1) This is a convenience function for doing adaptive thresholding
         on a grayscale image with variable background.  Also see notes
         in pixAdaptThresholdToBinary().
     (2) Reducing gamma increases the foreground (text) pixels.
         Use a low value (e.g., 0.5) for images with light text.
     (3) For normal images, see default args in pixAdaptThresholdToBinary().
         For images with very light text, these values are appropriate:
            gamma     ~0.5
            blackval  ~70
            whiteval  ~190
            thresh    ~200

Definition at line 758 of file grayquant.c.

◆ pixDitherTo2bpp()

PIX* pixDitherTo2bpp ( PIX pixs,
l_int32  cmapflag 
)

pixDitherTo2bpp()

Parameters
[in]pixs8 bpp
[in]cmapflag1 to generate a colormap
Returns
pixd dithered 2 bpp, or NULL on error

An analog of the Floyd-Steinberg error diffusion dithering algorithm is used to "dibitize" an 8 bpp grayscale image to 2 bpp, using equally spaced gray values of 0, 85, 170, and 255, which are served by thresholds of 43, 128 and 213. If cmapflag == 1, the colormap values are set to 0, 85, 170 and 255. If a pixel has a value between 0 and 42, it is dibitized to 0, and the excess above 0 is added to the three neighboring pixels, in the fractions 3/8 to i, j+1, 3/8 to i+1, j) and 1/4 to (i+1, j+1, truncating to 255 if necessary. If a pixel has a value between 43 and 127, it is dibitized to 1, and the excess above 85 is added to the three neighboring pixels as before. If the value is below 85, the excess is subtracted. With a value between 128 and 212, it is dibitized to 2, with the excess on either side of 170 distributed as before. Finally, with a value between 213 and 255, it is dibitized to 3, with the excess below 255 subtracted from the neighbors. We always truncate to 0 or 255. The details can be seen in the lookup table generation.

This function differs from straight dithering in that it allows clipping of grayscale to 0 or 255 if the values are sufficiently close, without distribution of the excess. This uses default values from pix.h to specify the range of lower and upper values near 0 and 255, rsp that are clipped to black and white without propagating the excess. Not propagating the excess has the effect of reducing the snake patterns in parts of the image that are nearly black or white; however, it also prevents any attempt to reproduce gray for those values.

The implementation uses 3 lookup tables for simplicity, and a pair of line buffers to avoid modifying pixs.

Definition at line 1002 of file grayquant.c.

◆ pixDitherTo2bppSpec()

PIX* pixDitherTo2bppSpec ( PIX pixs,
l_int32  lowerclip,
l_int32  upperclip,
l_int32  cmapflag 
)

pixDitherTo2bppSpec()

Parameters
[in]pixs8 bpp
[in]lowercliplower clip distance to black; use 0 for default
[in]upperclipupper clip distance to white; use 0 for default
[in]cmapflag1 to generate a colormap
Returns
pixd dithered 2 bpp, or NULL on error
Notes:
     (1) See comments above in pixDitherTo2bpp() for details.
     (2) The input parameters lowerclip and upperclip specify the range
         of lower and upper values (near 0 and 255, rsp) that are
         clipped to black and white without propagating the excess.
         For that reason, lowerclip and upperclip should be small numbers.

Definition at line 1034 of file grayquant.c.

References pixCreate(), and pixGetDimensions().

◆ pixDitherToBinary()

PIX* pixDitherToBinary ( PIX pixs)

pixDitherToBinary()

Parameters
[in]pixs
Returns
pixd dithered binary, or NULL on error

The Floyd-Steinberg error diffusion dithering algorithm binarizes an 8 bpp grayscale image to a threshold of 128. If a pixel has a value above 127, it is binarized to white and the excess below 255 is subtracted from three neighboring pixels in the fractions 3/8 to i, j+1, 3/8 to i+1, j) and 1/4 to (i+1,j+1, truncating to 0 if necessary. Likewise, if it the pixel has a value below 128, it is binarized to black and the excess above 0 is added to the neighboring pixels, truncating to 255 if necessary.

This function differs from straight dithering in that it allows clipping of grayscale to 0 or 255 if the values are sufficiently close, without distribution of the excess. This uses default values to specify the range of lower and upper values near 0 and 255, rsp that are clipped to black and white without propagating the excess. Not propagating the excess has the effect of reducing the snake patterns in parts of the image that are nearly black or white; however, it also prevents the attempt to reproduce gray for those values.

The implementation is straightforward. It uses a pair of line buffers to avoid changing pixs. It is about the same speed as pixDitherToBinaryLUT(), which uses three LUTs.

Definition at line 175 of file grayquant.c.

◆ pixDitherToBinarySpec()

PIX* pixDitherToBinarySpec ( PIX pixs,
l_int32  lowerclip,
l_int32  upperclip 
)

pixDitherToBinarySpec()

Parameters
[in]pixs
[in]lowercliplower clip distance to black; use 0 for default
[in]upperclipupper clip distance to white; use 0 for default
Returns
pixd dithered binary, or NULL on error
Notes:
     (1) See comments above in pixDitherToBinary() for details.
     (2) The input parameters lowerclip and upperclip specify the range
         of lower and upper values (near 0 and 255, rsp) that are
         clipped to black and white without propagating the excess.
         For that reason, lowerclip and upperclip should be small numbers.

Definition at line 205 of file grayquant.c.

References pixCreate(), and pixGetDimensions().

◆ pixGenerateMaskByBand()

PIX* pixGenerateMaskByBand ( PIX pixs,
l_int32  lower,
l_int32  upper,
l_int32  inband,
l_int32  usecmap 
)

pixGenerateMaskByBand()

Parameters
[in]pixs2, 4 or 8 bpp, or colormapped
[in]lower,uppertwo pixel values from which a range, either between (inband) or outside of (!inband), determines which pixels in pixs cause us to set a 1 in the dest mask
[in]inband1 for finding pixels in [lower, upper]; 0 for finding pixels in [0, lower) union (upper, 255]
[in]usecmap1 to retain cmap values; 0 to convert to gray
Returns
pixd 1 bpp, or NULL on error
Notes:
     (1) Generates a 1 bpp mask pixd, the same size as pixs, where
         the fg pixels in the mask are those either within the specified
         band (for inband == 1) or outside the specified band
         (for inband == 0).
     (2) If pixs is colormapped, usecmap determines if the colormap
         values are used, or if the colormap is removed to gray and
         the gray values are used.  For the latter, it generates
         an approximate grayscale value for each pixel, and then looks
         for gray pixels with the value val.

Definition at line 891 of file grayquant.c.

◆ pixGenerateMaskByBand32()

PIX* pixGenerateMaskByBand32 ( PIX pixs,
l_uint32  refval,
l_int32  delm,
l_int32  delp,
l_float32  fractm,
l_float32  fractp 
)

pixGenerateMaskByBand32()

Parameters
[in]pixs32 bpp
[in]refvalreference rgb value
[in]delmmax amount below the ref value for any component
[in]delpmax amount above the ref value for any component
[in]fractmfractional amount below ref value for all components
[in]fractpfractional amount above ref value for all components
Returns
pixd 1 bpp, or NULL on error
Notes:
     (1) Generates a 1 bpp mask pixd, the same size as pixs, where
         the fg pixels in the mask within a band of rgb values
         surrounding refval.  The band can be chosen in two ways
         for each component:
         (a) Use (delm, delp) to specify how many levels down and up
         (b) Use (fractm, fractp) to specify the fractional
             distance toward 0 and 255, respectively.
         Note that delm and delp must be in [0 ... 255], whereas
         fractm and fractp must be in [0.0 - 1.0].
     (2) Either (delm, delp) or (fractm, fractp) can be used.
         Set each value in the other pair to 0.

Definition at line 2093 of file grayquant.c.

References extractRGBValues(), pixCreate(), and pixGetDimensions().

◆ pixGenerateMaskByDiscr32()

PIX* pixGenerateMaskByDiscr32 ( PIX pixs,
l_uint32  refval1,
l_uint32  refval2,
l_int32  distflag 
)

pixGenerateMaskByDiscr32()

Parameters
[in]pixs32 bpp
[in]refval1reference rgb value
[in]refval2reference rgb value
[in]distflagL_MANHATTAN_DISTANCE, L_EUCLIDEAN_DISTANCE
Returns
pixd 1 bpp, or NULL on error
Notes:
     (1) Generates a 1 bpp mask pixd, the same size as pixs, where
         the fg pixels in the mask are those where the pixel in pixs
         is "closer" to refval1 than to refval2.
     (2) "Closer" can be defined in several ways, such as:
           ~ manhattan distance (L1)
           ~ euclidean distance (L2)
           ~ majority vote of the individual components
         Here, we have a choice of L1 or L2.

Definition at line 2189 of file grayquant.c.

References extractRGBValues(), L_EUCLIDEAN_DISTANCE, L_MANHATTAN_DISTANCE, pixCreate(), and pixGetDimensions().

◆ pixGenerateMaskByValue()

PIX* pixGenerateMaskByValue ( PIX pixs,
l_int32  val,
l_int32  usecmap 
)

pixGenerateMaskByValue()

Parameters
[in]pixs2, 4 or 8 bpp, or colormapped
[in]valof pixels for which we set 1 in dest
[in]usecmap1 to retain cmap values; 0 to convert to gray
Returns
pixd 1 bpp, or NULL on error
Notes:
     (1) val is the pixel value that we are selecting.  It can be
         either a gray value or a colormap index.
     (2) If pixs is colormapped, usecmap determines if the colormap
         index values are used, or if the colormap is removed to gray and
         the gray values are used.  For the latter, it generates
         an approximate grayscale value for each pixel, and then looks
         for gray pixels with the value val.

Definition at line 802 of file grayquant.c.

◆ pixGrayQuantFromCmap()

PIX* pixGrayQuantFromCmap ( PIX pixs,
PIXCMAP cmap,
l_int32  mindepth 
)

pixGrayQuantFromCmap()

Parameters
[in]pixs8 bpp grayscale without cmap
[in]cmapto quantize to; of dest pix
[in]mindepthminimum depth of pixd: can be 2, 4 or 8 bpp
Returns
pixd 2, 4 or 8 bpp, colormapped, or NULL on error
Notes:
     (1) In use, pixs is an 8 bpp grayscale image without a colormap.
         If there is an existing colormap, a warning is issued and
         a copy of the input pixs is returned.

Definition at line 2520 of file grayquant.c.

◆ pixGrayQuantFromHisto()

PIX* pixGrayQuantFromHisto ( PIX pixd,
PIX pixs,
PIX pixm,
l_float32  minfract,
l_int32  maxsize 
)

pixGrayQuantFromHisto()

Parameters
[in]pixd[optional] quantized pix with cmap; can be null
[in]pixs8 bpp gray input pix; not cmapped
[in]pixm[optional] mask over pixels in pixs to quantize
[in]minfractminimum fraction of pixels in a set of adjacent histo bins that causes the set to be automatically set aside as a color in the colormap; must be at least 0.01
[in]maxsizemaximum number of adjacent bins allowed to represent a color, regardless of the population of pixels in the bins; must be at least 2
Returns
pixd 8 bpp, cmapped, or NULL on error
Notes:
     (1) This is useful for quantizing images with relatively few
         colors, but which may have both color and gray pixels.
         If there are color pixels, it is assumed that an input
         rgb image has been color quantized first so that:
           ~ pixd has a colormap describing the color pixels
           ~ pixm is a mask over the non-color pixels in pixd
           ~ the colormap in pixd, and the color pixels in pixd,
             have been repacked to go from 0 to n-1 (n colors)
         If there are no color pixels, pixd and pixm are both null,
         and all pixels in pixs are quantized to gray.
     (2) A 256-entry histogram is built of the gray values in pixs.
         If pixm exists, the pixels contributing to the histogram are
         restricted to the fg of pixm.  A colormap and LUT are generated
         from this histogram.  We break up the array into a set
         of intervals, each one constituting a color in the colormap:
         An interval is identified by summing histogram bins until
         either the sum equals or exceeds the minfract of the total
         number of pixels, or the span itself equals or exceeds maxsize.
         The color of each bin is always an average of the pixels
         that constitute it.
     (3) Note that we do not specify the number of gray colors in
         the colormap.  Instead, we specify two parameters that
         describe the accuracy of the color assignments; this and
         the actual image determine the number of resulting colors.
     (4) If a mask exists and it is not the same size as pixs, make
         a new mask the same size as pixs, with the original mask
         aligned at the UL corners.  Set all additional pixels
         in the (larger) new mask set to 1, causing those pixels
         in pixd to be set as gray.
     (5) We estimate the total number of colors (color plus gray);
         if it exceeds 255, return null.

Definition at line 2301 of file grayquant.c.

◆ pixThresholdGrayArb()

PIX* pixThresholdGrayArb ( PIX pixs,
const char *  edgevals,
l_int32  outdepth,
l_int32  use_average,
l_int32  setblack,
l_int32  setwhite 
)

pixThresholdGrayArb()

Parameters
[in]pixs8 bpp grayscale; can have colormap
[in]edgevalsstring giving edge value of each bin
[in]outdepth0, 2, 4 or 8 bpp; 0 is default for min depth
[in]use_average1 if use the average pixel value in colormap
[in]setblack1 if darkest color is set to black
[in]setwhite1 if lightest color is set to white
Returns
pixd 2, 4 or 8 bpp quantized image with colormap, or NULL on error
Notes:
     (1) This function allows exact specification of the quantization bins.
         The string edgevals is a space-separated set of values
         specifying the dividing points between output quantization bins.
         These threshold values are assigned to the bin with higher
         values, so that each of them is the smallest value in their bin.
     (2) The output image (pixd) depth is specified by outdepth.  The
         number of bins is the number of edgevals + 1.  The
         relation between outdepth and the number of bins is:
              outdepth = 2       nbins <= 4
              outdepth = 4       nbins <= 16
              outdepth = 8       nbins <= 256
         With outdepth == 0, the minimum required depth for the
         given number of bins is used.
         The output pixd has a colormap.
     (3) The last 3 args determine the specific values that go into
         the colormap.
     (4) For use_average:
           ~ if TRUE, the average value of pixels falling in the bin is
             chosen as the representative gray value.  Otherwise,
           ~ if FALSE, the central value of each bin is chosen as
             the representative value.
         The colormap holds the representative value.
     (5) For setblack, if TRUE the darkest color is set to (0,0,0).
     (6) For setwhite, if TRUE the lightest color is set to (255,255,255).
     (7) An alternative to using this function to quantize to
         unequally-spaced bins is to first transform the 8 bpp pixs
         using pixGammaTRC(), and follow this with pixThresholdTo4bpp().

Definition at line 1710 of file grayquant.c.

References L_SORT_INCREASING, makeGrayQuantColormapArb(), makeGrayQuantTableArb(), numaDestroy(), numaGetCount(), numaSort(), parseStringForNumbers(), pixcmapDestroy(), pixcmapSetBlackAndWhite(), pixCreate(), and pixGetDimensions().

◆ pixThresholdOn8bpp()

PIX* pixThresholdOn8bpp ( PIX pixs,
l_int32  nlevels,
l_int32  cmapflag 
)

pixThresholdOn8bpp()

Parameters
[in]pixs8 bpp, can have colormap
[in]nlevelsequally spaced; must be between 2 and 256
[in]cmapflag1 to build colormap; 0 otherwise
Returns
pixd 8 bpp, optionally with colormap, or NULL on error
Notes:
     (1) Valid values for nlevels is the set {2,...,256}.
     (2) Any colormap on the input pixs is removed to 8 bpp grayscale.
     (3) If cmapflag == 1, a colormap of size 'nlevels' is made,
         and the pixel values in pixs are replaced by their
         appropriate color indices.  Otherwise, the pixel values
         are the actual thresholded (i.e., quantized) grayscale values.
     (4) If you don't want the thresholding to be equally spaced,
         first transform the input 8 bpp src using pixGammaTRC().

Definition at line 1611 of file grayquant.c.

◆ pixThresholdTo2bpp()

PIX* pixThresholdTo2bpp ( PIX pixs,
l_int32  nlevels,
l_int32  cmapflag 
)

pixThresholdTo2bpp()

Parameters
[in]pixs8 bpp
[in]nlevelsequally spaced; must be between 2 and 4
[in]cmapflag1 to build colormap; 0 otherwise
Returns
pixd 2 bpp, optionally with colormap, or NULL on error
Notes:
     (1) Valid values for nlevels is the set {2, 3, 4}.
     (2) Any colormap on the input pixs is removed to 8 bpp grayscale.
     (3) This function is typically invoked with cmapflag == 1.
         In the situation where no colormap is desired, nlevels is
         ignored and pixs is thresholded to 4 levels.
     (4) The target output colors are equally spaced, with the
         darkest at 0 and the lightest at 255.  The thresholds are
         chosen halfway between adjacent output values.  A table
         is built that specifies the mapping from src to dest.
     (5) If cmapflag == 1, a colormap of size 'nlevels' is made,
         and the pixel values in pixs are replaced by their
         appropriate color indices.  The number of holdouts,
         4 - nlevels, will be between 0 and 2.
     (6) If you don't want the thresholding to be equally spaced,
         either first transform the 8 bpp src using pixGammaTRC().
         or, if cmapflag == 1, after calling this function you can use
         pixcmapResetColor() to change any individual colors.
     (7) If a colormap is generated, it will specify (to display
         programs) exactly how each level is to be represented in RGB
         space.  When representing text, 3 levels is far better than
         2 because of the antialiasing of the single gray level,
         and 4 levels (black, white and 2 gray levels) is getting
         close to the perceptual quality of a (nearly continuous)
         grayscale image.  With 2 bpp, you can set up a colormap
         and allocate from 2 to 4 levels to represent antialiased text.
         Any left over colormap entries can be used for coloring regions.
         For the same number of levels, the file size of a 2 bpp image
         is about 10% smaller than that of a 4 bpp result for the same
         number of levels.  For both 2 bpp and 4 bpp, using 4 levels you
         get compression far better than that of jpeg, because the
         quantization to 4 levels will remove the jpeg ringing in the
         background near character edges.

Definition at line 1356 of file grayquant.c.

References pixCreate(), and pixGetDimensions().

◆ pixThresholdTo4bpp()

PIX* pixThresholdTo4bpp ( PIX pixs,
l_int32  nlevels,
l_int32  cmapflag 
)

pixThresholdTo4bpp()

Parameters
[in]pixs8 bpp, can have colormap
[in]nlevelsequally spaced; must be between 2 and 16
[in]cmapflag1 to build colormap; 0 otherwise
Returns
pixd 4 bpp, optionally with colormap, or NULL on error
Notes:
     (1) Valid values for nlevels is the set {2, ... 16}.
     (2) Any colormap on the input pixs is removed to 8 bpp grayscale.
     (3) This function is typically invoked with cmapflag == 1.
         In the situation where no colormap is desired, nlevels is
         ignored and pixs is thresholded to 16 levels.
     (4) The target output colors are equally spaced, with the
         darkest at 0 and the lightest at 255.  The thresholds are
         chosen halfway between adjacent output values.  A table
         is built that specifies the mapping from src to dest.
     (5) If cmapflag == 1, a colormap of size 'nlevels' is made,
         and the pixel values in pixs are replaced by their
         appropriate color indices.  The number of holdouts,
         16 - nlevels, will be between 0 and 14.
     (6) If you don't want the thresholding to be equally spaced,
         either first transform the 8 bpp src using pixGammaTRC().
         or, if cmapflag == 1, after calling this function you can use
         pixcmapResetColor() to change any individual colors.
     (7) If a colormap is generated, it will specify, to display
         programs, exactly how each level is to be represented in RGB
         space.  When representing text, 3 levels is far better than
         2 because of the antialiasing of the single gray level,
         and 4 levels (black, white and 2 gray levels) is getting
         close to the perceptual quality of a (nearly continuous)
         grayscale image.  Therefore, with 4 bpp, you can set up a
         colormap, allocate a relatively small fraction of the 16
         possible values to represent antialiased text, and use the
         other colormap entries for other things, such as coloring
         text or background.  Two other reasons for using a small number
         of gray values for antialiased text are (1) PNG compression
         gets worse as the number of levels that are used is increased,
         and (2) using a small number of levels will filter out most of
         the jpeg ringing that is typically introduced near sharp edges
         of text.  This filtering is partly responsible for the improved
         compression.

Definition at line 1496 of file grayquant.c.

References pixCreate(), and pixGetDimensions().

◆ pixThresholdToBinary()

PIX* pixThresholdToBinary ( PIX pixs,
l_int32  thresh 
)

pixThresholdToBinary()

Parameters
[in]pixs4 or 8 bpp
[in]threshthreshold value
Returns
pixd 1 bpp, or NULL on error
Notes:
     (1) If the source pixel is less than the threshold value,
         the dest will be 1; otherwise, it will be 0.
     (2) For example, for 8 bpp src pix, if thresh == 256, the dest
         1 bpp pix is all ones (fg), and if thresh == 0, the dest
         pix is all zeros (bg).

Definition at line 443 of file grayquant.c.

References pixCreate(), and pixGetDimensions().

Referenced by pixBlockrank(), pixThresholdForFgBg(), and recogAverageSamples().

◆ pixVarThresholdToBinary()

PIX* pixVarThresholdToBinary ( PIX pixs,
PIX pixg 
)

pixVarThresholdToBinary()

Parameters
[in]pixs8 bpp
[in]pixg8 bpp; contains threshold values for each pixel
Returns
pixd 1 bpp, or NULL on error
Notes:
     (1) If the pixel in pixs is less than the corresponding pixel
         in pixg, the dest will be 1; otherwise it will be 0.

Definition at line 647 of file grayquant.c.

References pixCreate(), pixGetDimensions(), and pixSizesEqual().

◆ thresholdTo2bppLow()

static void thresholdTo2bppLow ( l_uint32 *  datad,
l_int32  h,
l_int32  wpld,
l_uint32 *  datas,
l_int32  wpls,
l_int32 *  tab 
)
static

thresholdTo2bppLow()

Low-level function for thresholding from 8 bpp (datas) to 2 bpp (datad), using thresholds implicitly defined through tab, a 256-entry lookup table that gives a 2-bit output value for each possible input.

For each line, unroll the loop so that for each 32 bit src word, representing four consecutive 8-bit pixels, we compose one byte of output consisiting of four 2-bit pixels.

Definition at line 1418 of file grayquant.c.

References GET_DATA_BYTE, and SET_DATA_BYTE.

◆ thresholdTo4bppLow()

static void thresholdTo4bppLow ( l_uint32 *  datad,
l_int32  h,
l_int32  wpld,
l_uint32 *  datas,
l_int32  wpls,
l_int32 *  tab 
)
static

thresholdTo4bppLow()

Low-level function for thresholding from 8 bpp (datas) to 4 bpp (datad), using thresholds implicitly defined through tab, a 256-entry lookup table that gives a 4-bit output value for each possible input.

For each line, unroll the loop so that for each 32 bit src word, representing four consecutive 8-bit pixels, we compose two bytes of output consisiting of four 4-bit pixels.

Definition at line 1558 of file grayquant.c.

References GET_DATA_BYTE, and SET_DATA_TWO_BYTES.

◆ thresholdToBinaryLow()

static void thresholdToBinaryLow ( l_uint32 *  datad,
l_int32  w,
l_int32  h,
l_int32  wpld,
l_uint32 *  datas,
l_int32  d,
l_int32  wpls,
l_int32  thresh 
)
static

thresholdToBinaryLow()

If the source pixel is less than thresh, the dest will be 1; otherwise, it will be 0

Definition at line 492 of file grayquant.c.