Leptonica  1.54
Файл colorquant2.c
#include <string.h>
#include <math.h>
#include "allheaders.h"

Классы

struct  L_Box3d
 

Макросы

#define DEBUG_MC_COLORS   0
 
#define DEBUG_SPLIT_AXES   0
 

Определения типов

typedef struct L_Box3d L_BOX3D
 

Функции

static PIXCMAPpixcmapGenerateFromHisto (PIX *pixs, l_int32 depth, l_int32 *histo, l_int32 histosize, l_int32 sigbits)
 
static PIXpixQuantizeWithColormap (PIX *pixs, l_int32 ditherflag, l_int32 outdepth, PIXCMAP *cmap, l_int32 *indexmap, l_int32 mapsize, l_int32 sigbits)
 
static void getColorIndexMedianCut (l_uint32 pixel, l_int32 rshift, l_uint32 mask, l_int32 sigbits, l_int32 *pindex)
 
static L_BOX3DpixGetColorRegion (PIX *pixs, l_int32 sigbits, l_int32 subsample)
 
static l_int32 medianCutApply (l_int32 *histo, l_int32 sigbits, L_BOX3D *vbox, L_BOX3D **pvbox1, L_BOX3D **pvbox2)
 
static PIXCMAPpixcmapGenerateFromMedianCuts (L_HEAP *lh, l_int32 *histo, l_int32 sigbits)
 
static l_int32 vboxGetAverageColor (L_BOX3D *vbox, l_int32 *histo, l_int32 sigbits, l_int32 index, l_int32 *prval, l_int32 *pgval, l_int32 *pbval)
 
static l_int32 vboxGetCount (L_BOX3D *vbox, l_int32 *histo, l_int32 sigbits)
 
static l_int32 vboxGetVolume (L_BOX3D *vbox)
 
static L_BOX3Dbox3dCreate (l_int32 r1, l_int32 r2, l_int32 g1, l_int32 g2, l_int32 b1, l_int32 b2)
 
static L_BOX3Dbox3dCopy (L_BOX3D *vbox)
 
PIXpixMedianCutQuant (PIX *pixs, l_int32 ditherflag)
 
PIXpixMedianCutQuantGeneral (PIX *pixs, l_int32 ditherflag, l_int32 outdepth, l_int32 maxcolors, l_int32 sigbits, l_int32 maxsub, l_int32 checkbw)
 
PIXpixMedianCutQuantMixed (PIX *pixs, l_int32 ncolor, l_int32 ngray, l_int32 darkthresh, l_int32 lightthresh, l_int32 diffthresh)
 
PIXpixFewColorsMedianCutQuantMixed (PIX *pixs, l_int32 ncolor, l_int32 ngray, l_int32 maxncolors, l_int32 darkthresh, l_int32 lightthresh, l_int32 diffthresh)
 
l_int32pixMedianCutHisto (PIX *pixs, l_int32 sigbits, l_int32 subsample)
 

Переменные

static const l_int32 DEFAULT_SIG_BITS = 5
 
static const l_int32 MAX_ITERS_ALLOWED = 5000
 
static const l_float32 FRACT_BY_POPULATION = 0.85
 
static const l_int32 DIF_CAP = 100
 

Макросы

◆ DEBUG_MC_COLORS

#define DEBUG_MC_COLORS   0

◆ DEBUG_SPLIT_AXES

#define DEBUG_SPLIT_AXES   0

Типы

◆ L_BOX3D

typedef struct L_Box3d L_BOX3D

Функции

◆ box3dCopy()

static L_BOX3D * box3dCopy ( L_BOX3D vbox)
static

◆ box3dCreate()

static L_BOX3D * box3dCreate ( l_int32  r1,
l_int32  r2,
l_int32  g1,
l_int32  g2,
l_int32  b1,
l_int32  b2 
)
static

◆ getColorIndexMedianCut()

static void getColorIndexMedianCut ( l_uint32  pixel,
l_int32  rshift,
l_uint32  mask,
l_int32  sigbits,
l_int32 pindex 
)
static

getColorIndexMedianCut()

Input:  pixel (32 bit rgb)
        rshift (of component: 8 - sigbits)
        mask (over sigbits)
        sigbits
        &index (<return> rgb index value)
Return: void

Notes: (1) This is used on each pixel in the source image. No checking is done on input values.

◆ medianCutApply()

static l_int32 medianCutApply ( l_int32 histo,
l_int32  sigbits,
L_BOX3D vbox,
L_BOX3D **  pvbox1,
L_BOX3D **  pvbox2 
)
static

medianCutApply()

Input:  histo  (array; in rgb colorspace)
        sigbits
        vbox (input 3D box)
        &vbox1, vbox2 (<return> vbox split in two parts)
Return: 0 if OK, 1 on error

◆ pixcmapGenerateFromHisto()

static PIXCMAP * pixcmapGenerateFromHisto ( PIX pixs,
l_int32  depth,
l_int32 histo,
l_int32  histosize,
l_int32  sigbits 
)
static

pixcmapGenerateFromHisto()

Input:  pixs  (32 bpp; rgb color)
        depth (of colormap)
        histo
        histosize
        sigbits
Return: colormap, or null on error

Notes: (1) This is used when the number of colors in the histo is not greater than maxcolors. (2) As a side-effect, the histo becomes an inverse colormap, labeling the cmap indices for each existing color.

◆ pixcmapGenerateFromMedianCuts()

static PIXCMAP * pixcmapGenerateFromMedianCuts ( L_HEAP lh,
l_int32 histo,
l_int32  sigbits 
)
static

pixcmapGenerateFromMedianCuts()

Input:  lh (priority queue of pointers to vboxes)
        histo
        sigbits (valid: 5 or 6)
Return: cmap, or null on error

Notes: (1) Each vbox in the heap represents a color in the colormap. (2) As a side-effect, the histo becomes an inverse colormap, where the part of the array correpsonding to each vbox is labeled with the cmap index for that vbox. Then for each rgb pixel, the colormap index is found directly by mapping the rgb value to the histo array index.

◆ pixFewColorsMedianCutQuantMixed()

PIX* pixFewColorsMedianCutQuantMixed ( PIX pixs,
l_int32  ncolor,
l_int32  ngray,
l_int32  maxncolors,
l_int32  darkthresh,
l_int32  lightthresh,
l_int32  diffthresh 
)

pixFewColorsMedianCutQuantMixed()

Input:  pixs (32 bpp rgb)
        ncolor (number of colors to be assigned to pixels with
                 significant color)
        ngray (number of gray colors to be used; must be >= 2)
        maxncolors (maximum number of colors to be returned
                   from pixColorsForQuantization(); use 0 for default)
        darkthresh (threshold near black; if the lightest component
                    is below this, the pixel is not considered to
                    be gray or color; use 0 for default)
        lightthresh (threshold near white; if the darkest component
                     is above this, the pixel is not considered to
                     be gray or color; use 0 for default)
        diffthresh (thresh for the max difference between component
                    values; for differences below this, the pixel
                    is considered to be gray; use 0 for default)
                    considered gray; use 0 for default)
Return: pixd (8 bpp, median cut quantized for pixels that are
              not gray; gray pixels are quantized separately
              over the full gray range); null if too many colors
              or on error

Notes: (1) This is the "few colors" version of pixMedianCutQuantMixed(). It fails (returns NULL) if it finds more than maxncolors, but otherwise it gives the same result. (2) Recommended input parameters are: @maxncolors: 20 @darkthresh: 20 @lightthresh: 244 @diffthresh: 15 (any higher can miss colors differing slightly from gray) (3) Both ncolor and ngray should be at least equal to maxncolors. If they're not, they are automatically increased, and a warning is given. (4) If very little color content is found, the input is converted to gray and quantized in equal intervals. (5) This can be useful for quantizing orthographically generated images such as color maps, where there may be more than 256 colors because of aliasing or jpeg artifacts on text or lines, but there are a relatively small number of solid colors. (6) Example of usage: // Try to quantize, using default values for mixed med cut Pix *pixq = pixFewColorsMedianCutQuantMixed(pixs, 100, 20, 0, 0, 0, 0); if (!pixq) // too many colors; don't quantize pixq = pixClone(pixs);

◆ pixGetColorRegion()

static L_BOX3D * pixGetColorRegion ( PIX pixs,
l_int32  sigbits,
l_int32  subsample 
)
static

pixGetColorRegion()

Input:  pixs  (32 bpp; rgb color)
        sigbits (valid: 5, 6)
        subsample (integer > 0)
Return: vbox (minimum 3D box in color space enclosing all pixels),
        or null on error

Notes: (1) Computes the minimum 3D box in color space enclosing all pixels in the image.

◆ pixMedianCutHisto()

l_int32* pixMedianCutHisto ( PIX pixs,
l_int32  sigbits,
l_int32  subsample 
)

pixMedianCutHisto()

Input:  pixs  (32 bpp; rgb color)
        sigbits (valid: 5 or 6)
        subsample (integer > 0)
Return: histo (1-d array, giving the number of pixels in
               each quantized region of color space), or null on error

Notes: (1) Array is indexed by (3 * sigbits) bits. The array size is 2^(3 * sigbits). (2) Indexing into the array from rgb uses red sigbits as most significant and blue as least.

◆ pixMedianCutQuant()

PIX* pixMedianCutQuant ( PIX pixs,
l_int32  ditherflag 
)

pixMedianCutQuant()

Input:  pixs  (32 bpp; rgb color)
        ditherflag (1 for dither; 0 for no dither)
Return: pixd (8 bit with colormap), or null on error

Notes: (1) Simple interface. See pixMedianCutQuantGeneral() for use of defaulted parameters.

◆ pixMedianCutQuantGeneral()

PIX* pixMedianCutQuantGeneral ( PIX pixs,
l_int32  ditherflag,
l_int32  outdepth,
l_int32  maxcolors,
l_int32  sigbits,
l_int32  maxsub,
l_int32  checkbw 
)

pixMedianCutQuantGeneral()

Input:  pixs  (32 bpp; rgb color)
        ditherflag (1 for dither; 0 for no dither)
        outdepth (output depth; valid: 0, 1, 2, 4, 8)
        maxcolors (between 2 and 256)
        sigbits (valid: 5 or 6; use 0 for default)
        maxsub (max subsampling, integer; use 0 for default;
                1 for no subsampling)
        checkbw (1 to check if color content is very small,
                 0 to assume there is sufficient color)
Return: pixd (8 bit with colormap), or null on error

Notes: (1) @maxcolors must be in the range [2 ... 256]. (2) Use @outdepth = 0 to have the output depth computed as the minimum required to hold the actual colors found, given the @maxcolors constraint. (3) Use @outdepth = 1, 2, 4 or 8 to specify the output depth. In that case, @maxcolors must not exceed 2^(outdepth). (4) If there are fewer quantized colors in the image than @maxcolors, the colormap is simply generated from those colors. (5) @maxsub is the maximum allowed subsampling to be used in the computation of the color histogram and region of occupied color space. The subsampling is chosen internally for efficiency, based on the image size, but this parameter limits it. Use @maxsub = 0 for the internal default, which is the maximum allowed subsampling. Use @maxsub = 1 to prevent subsampling. In general use @maxsub >= 1 to specify the maximum subsampling to be allowed, where the actual subsampling will be the minimum of this value and the internally determined default value. (6) If the image appears gray because either most of the pixels are gray or most of the pixels are essentially black or white, the image is trivially quantized with a grayscale colormap. The reason is that median cut divides the color space into rectangular regions, and it does a very poor job if all the pixels are near the diagonal of the color space cube.

◆ pixMedianCutQuantMixed()

PIX* pixMedianCutQuantMixed ( PIX pixs,
l_int32  ncolor,
l_int32  ngray,
l_int32  darkthresh,
l_int32  lightthresh,
l_int32  diffthresh 
)

pixMedianCutQuantMixed()

Input:  pixs  (32 bpp; rgb color)
        ncolor (maximum number of colors assigned to pixels with
                significant color)
        ngray (number of gray colors to be used; must be >= 2)
        darkthresh (threshold near black; if the lightest component
                    is below this, the pixel is not considered to
                    be gray or color; uses 0 for default)
        lightthresh (threshold near white; if the darkest component
                     is above this, the pixel is not considered to
                     be gray or color; use 0 for default)
        diffthresh (thresh for the max difference between component
                    values; for differences below this, the pixel
                    is considered to be gray; use 0 for default)
Return: pixd (8 bpp cmapped), or null on error

Notes: (1) ncolor + ngray must not exceed 255. (2) The method makes use of pixMedianCutQuantGeneral() with minimal addition. (a) Preprocess the image, setting all pixels with little color to black, and populating an auxiliary 8 bpp image with the expected colormap values corresponding to the set of quantized gray values. (b) Color quantize the altered input image to n + 1 colors. (c) Augment the colormap with the gray indices, and substitute the gray quantized values from the auxiliary image for those in the color quantized output that had been quantized as black. (3) Median cut color quantization is relatively poor for grayscale images with many colors, when compared to octcube quantization. Thus, for images with both gray and color, it is important to quantize the gray pixels by another method. Here, we are conservative in detecting color, preferring to use a few extra bits to encode colorful pixels that push them to gray. This is particularly reasonable with this function, because it handles the gray and color pixels separately, using median cut color quantization for the color pixels and equal-bin grayscale quantization for the non-color pixels.

◆ pixQuantizeWithColormap()

static PIX * pixQuantizeWithColormap ( PIX pixs,
l_int32  ditherflag,
l_int32  outdepth,
PIXCMAP cmap,
l_int32 indexmap,
l_int32  mapsize,
l_int32  sigbits 
)
static

pixQuantizeWithColormap()

Input:  pixs  (32 bpp; rgb color)
        ditherflag (1 for dither; 0 for no dither)
        outdepth
        cmap
        indexmap
        histosize
        sigbits
Return: pixd (quantized to colormap), or null on error

Notes: (1) The indexmap is a LUT that takes the rgb indices of the pixel and returns the index into the colormap. (2) If ditherflag is 1, @outdepth is ignored and the output depth is set to 8.

◆ vboxGetAverageColor()

static l_int32 vboxGetAverageColor ( L_BOX3D vbox,
l_int32 histo,
l_int32  sigbits,
l_int32  index,
l_int32 prval,
l_int32 pgval,
l_int32 pbval 
)
static

vboxGetAverageColor()

Input:  vbox (3d region of color space for one quantized color)
        histo
        sigbits (valid: 5 or 6)
        index (if >= 0, assign to all colors in histo in this vbox)
        &rval, &gval, &bval (<returned> average color)
Return: cmap, or null on error

Notes: (1) The vbox represents one color in the colormap. (2) If index >= 0, as a side-effect, all array elements in the histo corresponding to the vbox are labeled with this cmap index for that vbox. Otherwise, the histo array is not changed. (3) The vbox is quantized in sigbits. So the actual 8-bit color components are found by multiplying the quantized value by either 4 or 8. We must add 0.5 to the quantized index before multiplying to get the approximate 8-bit color in the center of the vbox; otherwise we get values on the lower corner.

◆ vboxGetCount()

static l_int32 vboxGetCount ( L_BOX3D vbox,
l_int32 histo,
l_int32  sigbits 
)
static

vboxGetCount()

Input:  vbox (3d region of color space for one quantized color)
        histo
        sigbits (valid: 5 or 6)
Return: number of image pixels in this region, or 0 on error

◆ vboxGetVolume()

static l_int32 vboxGetVolume ( L_BOX3D vbox)
static

vboxGetVolume()

Input:  vbox (3d region of color space for one quantized color)
Return: quantized volume of vbox, or 0 on error

Переменные

◆ DEFAULT_SIG_BITS

const l_int32 DEFAULT_SIG_BITS = 5
static

◆ DIF_CAP

const l_int32 DIF_CAP = 100
static

◆ FRACT_BY_POPULATION

const l_float32 FRACT_BY_POPULATION = 0.85
static

◆ MAX_ITERS_ALLOWED

const l_int32 MAX_ITERS_ALLOWED = 5000
static