本文整理汇总了C++中pixGetData函数的典型用法代码示例。如果您正苦于以下问题:C++ pixGetData函数的具体用法?C++ pixGetData怎么用?C++ pixGetData使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了pixGetData函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: DegradeImage
// Degrade the pix as if by a print/copy/scan cycle with exposure > 0
// corresponding to darkening on the copier and <0 lighter and 0 not copied.
// Exposures in [-2,2] are most useful, with -3 and 3 being extreme.
// If rotation is NULL, rotation is skipped. If *rotation is non-zero, the pix
// is rotated by *rotation else it is randomly rotated and *rotation is
// modified.
// HOW IT WORKS:
// Most of the process is really dictated by the fact that the minimum
// available convolution is 3X3, which is too big really to simulate a
// good quality print/scan process. (2X2 would be better.)
// 1 pixel wide inputs are heavily smeared by the 3X3 convolution, making the
// images generally biased to being too light, so most of the work is to make
// them darker. 3 levels of thickening/darkening are achieved with 2 dilations,
// (using a greyscale erosion) one heavy (by being before convolution) and one
// light (after convolution).
// With no dilation, after covolution, the images are so light that a heavy
// constant offset is required to make the 0 image look reasonable. A simple
// constant offset multiple of exposure to undo this value is enough to achieve
// all the required lightening. This gives the advantage that exposure level 1
// with a single dilation gives a good impression of the broken-yet-too-dark
// problem that is often seen in scans.
// A small random rotation gives some varying greyscale values on the edges,
// and some random salt and pepper noise on top helps to realistically jaggy-up
// the edges.
// Finally a greyscale ramp provides a continuum of effects between exposure
// levels.
Pix* DegradeImage(Pix* input, int exposure, float* rotation) {
Pix* pix = pixConvertTo8(input, false);
pixDestroy(&input);
input = pix;
int width = pixGetWidth(input);
int height = pixGetHeight(input);
if (exposure >= 2) {
// An erosion simulates the spreading darkening of a dark copy.
// This is backwards to binary morphology,
// see http://www.leptonica.com/grayscale-morphology.html
pix = input;
input = pixErodeGray(pix, 3, 3);
pixDestroy(&pix);
}
// A convolution is essential to any mode as no scanner produces an
// image as sharp as the electronic image.
pix = pixBlockconv(input, 1, 1);
pixDestroy(&input);
// A small random rotation helps to make the edges jaggy in a realistic way.
if (rotation != NULL) {
float radians_clockwise;
if (*rotation) {
radians_clockwise = *rotation;
} else {
radians_clockwise = (2.0*rand_r(&random_seed)/RAND_MAX - 1.0) *
kRotationRange;
}
input = pixRotate(pix, radians_clockwise,
L_ROTATE_AREA_MAP, L_BRING_IN_WHITE,
0, 0);
// Rotate the boxes to match.
*rotation = radians_clockwise;
pixDestroy(&pix);
} else {
input = pix;
}
if (exposure >= 3 || exposure == 1) {
// Erosion after the convolution is not as heavy as before, so it is
// good for level 1 and in addition as a level 3.
// This is backwards to binary morphology,
// see http://www.leptonica.com/grayscale-morphology.html
pix = input;
input = pixErodeGray(pix, 3, 3);
pixDestroy(&pix);
}
// The convolution really needed to be 2x2 to be realistic enough, but
// we only have 3x3, so we have to bias the image darker or lose thin
// strokes.
int erosion_offset = 0;
// For light and 0 exposure, there is no dilation, so compensate for the
// convolution with a big darkening bias which is undone for lighter
// exposures.
if (exposure <= 0)
erosion_offset = -3 * kExposureFactor;
// Add in a general offset of the greyscales for the exposure level so
// a threshold of 128 gives a reasonable binary result.
erosion_offset -= exposure * kExposureFactor;
// Add a gradual fade over the page and a small amount of salt and pepper
// noise to simulate noise in the sensor/paper fibres and varying
// illumination.
l_uint32* data = pixGetData(input);
for (int y = 0; y < height; ++y) {
for (int x = 0; x < width; ++x) {
int pixel = GET_DATA_BYTE(data, x);
pixel += rand_r(&random_seed) % (kSaltnPepper*2 + 1) - kSaltnPepper;
if (height + width > kMinRampSize)
pixel -= (2*x + y) * 32 / (height + width);
pixel += erosion_offset;
if (pixel < 0)
pixel = 0;
if (pixel > 255)
pixel = 255;
//.........这里部分代码省略.........
示例2: pixReadStreamPng
//.........这里部分代码省略.........
else if (spp == 2) {
d = 2 * bit_depth;
L_WARNING("there shouldn't be 2 spp!", procName);
}
else /* spp == 3 (rgb), spp == 4 (rgba) */
d = 4 * bit_depth;
/* Remove if/when this is implemented for all bit_depths */
if (spp == 3 && bit_depth != 8) {
fprintf(stderr, "Help: spp = 3 and depth = %d != 8\n!!", bit_depth);
return (PIX *)ERROR_PTR("not implemented for this depth",
procName, NULL);
}
if (color_type == PNG_COLOR_TYPE_PALETTE ||
color_type == PNG_COLOR_MASK_PALETTE) { /* generate a colormap */
png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette);
cmap = pixcmapCreate(d); /* spp == 1 */
for (cindex = 0; cindex < num_palette; cindex++) {
rval = palette[cindex].red;
gval = palette[cindex].green;
bval = palette[cindex].blue;
pixcmapAddColor(cmap, rval, gval, bval);
}
}
else
cmap = NULL;
if ((pix = pixCreate(w, h, d)) == NULL) {
png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
return (PIX *)ERROR_PTR("pix not made", procName, NULL);
}
wpl = pixGetWpl(pix);
data = pixGetData(pix);
pixSetColormap(pix, cmap);
if (spp == 1) { /* copy straight from buffer to pix */
for (i = 0; i < h; i++) {
line = data + i * wpl;
rowptr = row_pointers[i];
for (j = 0; j < rowbytes; j++) {
SET_DATA_BYTE(line, j, rowptr[j]);
}
}
}
else { /* spp == 3 or spp == 4 */
for (i = 0; i < h; i++) {
ppixel = data + i * wpl;
rowptr = row_pointers[i];
for (j = k = 0; j < w; j++) {
SET_DATA_BYTE(ppixel, COLOR_RED, rowptr[k++]);
SET_DATA_BYTE(ppixel, COLOR_GREEN, rowptr[k++]);
SET_DATA_BYTE(ppixel, COLOR_BLUE, rowptr[k++]);
if (spp == 4)
SET_DATA_BYTE(ppixel, L_ALPHA_CHANNEL, rowptr[k++]);
ppixel++;
}
}
}
#if DEBUG
if (cmap) {
for (i = 0; i < 16; i++) {
fprintf(stderr, "[%d] = %d\n", i,
((l_uint8 *)(cmap->array))[i]);
}
示例3: pixSeedfill8BB
/*!
* \brief pixSeedfill8BB()
*
* \param[in] pixs 1 bpp
* \param[in] stack for holding fillsegs
* \param[in] x,y location of seed pixel
* \return box or NULL on error.
*
* <pre>
* Notes:
* (1) This is Paul Heckbert's stack-based 8-cc seedfill algorithm.
* (2) This operates on the input 1 bpp pix to remove the fg seed
* pixel, at (x,y), and all pixels that are 8-connected to it.
* The seed pixel at (x,y) must initially be ON.
* (3) Returns the bounding box of the erased 8-cc component.
* (4) Reference: see Paul Heckbert's stack-based seed fill algorithm
* in "Graphic Gems", ed. Andrew Glassner, Academic
* Press, 1990. The algorithm description is given
* on pp. 275-277; working C code is on pp. 721-722.)
* The code here follows Heckbert's closely, except
* the leak checks are changed for 8 connectivity.
* See comments on pixSeedfill4BB() for more details.
* </pre>
*/
BOX *
pixSeedfill8BB(PIX *pixs,
L_STACK *stack,
l_int32 x,
l_int32 y)
{
l_int32 w, h, xstart, wpl, x1, x2, dy;
l_int32 xmax, ymax;
l_int32 minx, maxx, miny, maxy; /* for bounding box of this c.c. */
l_uint32 *data, *line;
BOX *box;
PROCNAME("pixSeedfill8BB");
if (!pixs || pixGetDepth(pixs) != 1)
return (BOX *)ERROR_PTR("pixs undefined or not 1 bpp", procName, NULL);
if (!stack)
return (BOX *)ERROR_PTR("stack not defined", procName, NULL);
if (!stack->auxstack)
stack->auxstack = lstackCreate(0);
pixGetDimensions(pixs, &w, &h, NULL);
xmax = w - 1;
ymax = h - 1;
data = pixGetData(pixs);
wpl = pixGetWpl(pixs);
line = data + y * wpl;
/* Check pix value of seed; must be ON */
if (x < 0 || x > xmax || y < 0 || y > ymax || (GET_DATA_BIT(line, x) == 0))
return NULL;
/* Init stack to seed:
* Must first init b.b. values to prevent valgrind from complaining;
* then init b.b. boundaries correctly to seed. */
minx = miny = 100000;
maxx = maxy = 0;
pushFillsegBB(stack, x, x, y, 1, ymax, &minx, &maxx, &miny, &maxy);
pushFillsegBB(stack, x, x, y + 1, -1, ymax, &minx, &maxx, &miny, &maxy);
minx = maxx = x;
miny = maxy = y;
while (lstackGetCount(stack) > 0)
{
/* Pop segment off stack and fill a neighboring scan line */
popFillseg(stack, &x1, &x2, &y, &dy);
line = data + y * wpl;
/* A segment of scanline y - dy for x1 <= x <= x2 was
* previously filled. We now explore adjacent pixels
* in scan line y. There are three regions: to the
* left of x1, between x1 and x2, and to the right of x2.
* These regions are handled differently. Leaks are
* possible expansions beyond the previous segment and
* going back in the -dy direction. These can happen
* for x < x1 and for x > x2. Any "leak" segments
* are plugged with a push in the -dy (opposite) direction.
* And any segments found anywhere are always extended
* in the +dy direction. */
for (x = x1 - 1; x >= 0 && (GET_DATA_BIT(line, x) == 1); x--)
CLEAR_DATA_BIT(line,x);
if (x >= x1 - 1) /* pix at x1 - 1 was off and was not cleared */
goto skip;
xstart = x + 1;
if (xstart < x1) /* leak on left? */
pushFillsegBB(stack, xstart, x1 - 1, y, -dy,
ymax, &minx, &maxx, &miny, &maxy);
x = x1;
do {
for (; x <= xmax && (GET_DATA_BIT(line, x) == 1); x++)
CLEAR_DATA_BIT(line, x);
pushFillsegBB(stack, xstart, x - 1, y, dy,
ymax, &minx, &maxx, &miny, &maxy);
if (x > x2) /* leak on right? */
pushFillsegBB(stack, x2 + 1, x - 1, y, -dy,
//.........这里部分代码省略.........
示例4: pixSauvolaGetThreshold
/*!
* pixSauvolaGetThreshold()
*
* Input: pixm (8 bpp grayscale; not colormapped)
* pixms (32 bpp)
* factor (factor for reducing threshold due to variance; >= 0)
* &pixsd (<optional return> local standard deviation)
* Return: pixd (8 bpp, sauvola threshold values), or null on error
*
* Notes:
* (1) The Sauvola threshold is determined from the formula:
* t = m * (1 - k * (1 - s / 128))
* where:
* t = local threshold
* m = local mean
* k = @factor (>= 0) [ typ. 0.35 ]
* s = local standard deviation, which is maximized at
* 127.5 when half the samples are 0 and half are 255.
* (2) See pixSauvolaBinarize() for other details.
* (3) Important definitions and relations for computing averages:
* v == pixel value
* E(p) == expected value of p == average of p over some pixel set
* S(v) == square of v == v * v
* mv == E(v) == expected pixel value == mean value
* ms == E(S(v)) == expected square of pixel values
* == mean square value
* var == variance == expected square of deviation from mean
* == E(S(v - mv)) = E(S(v) - 2 * S(v * mv) + S(mv))
* = E(S(v)) - S(mv)
* = ms - mv * mv
* s == standard deviation = sqrt(var)
* So for evaluating the standard deviation in the Sauvola
* threshold, we take
* s = sqrt(ms - mv * mv)
*/
PIX *
pixSauvolaGetThreshold(PIX *pixm,
PIX *pixms,
l_float32 factor,
PIX **ppixsd)
{
l_int32 i, j, w, h, tabsize, wplm, wplms, wplsd, wpld, usetab;
l_int32 mv, ms, var, thresh;
l_uint32 *datam, *datams, *datasd, *datad;
l_uint32 *linem, *linems, *linesd, *lined;
l_float32 sd;
l_float32 *tab; /* of 2^16 square roots */
PIX *pixsd, *pixd;
PROCNAME("pixSauvolaGetThreshold");
if (ppixsd) *ppixsd = NULL;
if (!pixm || pixGetDepth(pixm) != 8)
return (PIX *)ERROR_PTR("pixm undefined or not 8 bpp", procName, NULL);
if (pixGetColormap(pixm))
return (PIX *)ERROR_PTR("pixm is colormapped", procName, NULL);
if (!pixms || pixGetDepth(pixms) != 32)
return (PIX *)ERROR_PTR("pixms undefined or not 32 bpp",
procName, NULL);
if (factor < 0.0)
return (PIX *)ERROR_PTR("factor must be >= 0", procName, NULL);
/* Only make a table of 2^16 square roots if there
* are enough pixels to justify it. */
pixGetDimensions(pixm, &w, &h, NULL);
usetab = (w * h > 100000) ? 1 : 0;
if (usetab) {
tabsize = 1 << 16;
tab = (l_float32 *)CALLOC(tabsize, sizeof(l_float32));
for (i = 0; i < tabsize; i++)
tab[i] = (l_float32)sqrt((l_float64)i);
}
pixd = pixCreate(w, h, 8);
if (ppixsd) {
pixsd = pixCreate(w, h, 8);
*ppixsd = pixsd;
}
datam = pixGetData(pixm);
datams = pixGetData(pixms);
if (ppixsd) datasd = pixGetData(pixsd);
datad = pixGetData(pixd);
wplm = pixGetWpl(pixm);
wplms = pixGetWpl(pixms);
if (ppixsd) wplsd = pixGetWpl(pixsd);
wpld = pixGetWpl(pixd);
for (i = 0; i < h; i++) {
linem = datam + i * wplm;
linems = datams + i * wplms;
if (ppixsd) linesd = datasd + i * wplsd;
lined = datad + i * wpld;
for (j = 0; j < w; j++) {
mv = GET_DATA_BYTE(linem, j);
ms = linems[j];
var = ms - mv * mv;
if (usetab)
sd = tab[var];
else
sd = (l_float32)sqrt((l_float32)var);
if (ppixsd) SET_DATA_BYTE(linesd, j, (l_int32)sd);
//.........这里部分代码省略.........
示例5: pixReadMemBmp
//.........这里部分代码省略.........
/* Read the colormap entry data from bmp. The RGBA_QUAD colormap
* entries are used for both bmp and leptonica colormaps. */
memcpy(cmapBuf, cdata + BMP_FHBYTES + BMP_IHBYTES,
sizeof(RGBA_QUAD) * cmapEntries);
}
/* Make a 32 bpp pix if depth is 24 bpp */
d = (depth == 24) ? 32 : depth;
if ((pix = pixCreate(width, height, d)) == NULL) {
LEPT_FREE(cmapBuf);
return (PIX *)ERROR_PTR( "pix not made", procName, NULL);
}
pixSetXRes(pix, (l_int32)((l_float32)xres / 39.37 + 0.5)); /* to ppi */
pixSetYRes(pix, (l_int32)((l_float32)yres / 39.37 + 0.5)); /* to ppi */
pixSetInputFormat(pix, IFF_BMP);
pixWpl = pixGetWpl(pix);
pixBpl = 4 * pixWpl;
/* Convert the bmp colormap to a pixcmap */
cmap = NULL;
if (cmapEntries > 0) { /* import the colormap to the pix cmap */
cmap = pixcmapCreate(L_MIN(d, 8));
LEPT_FREE(cmap->array); /* remove generated cmap array */
cmap->array = (void *)cmapBuf; /* and replace */
cmap->n = L_MIN(cmapEntries, 256);
for (i = 0; i < cmap->n; i++) /* set all colors opaque */
pixcmapSetAlpha (cmap, i, 255);
}
pixSetColormap(pix, cmap);
/* Acquire the image data. Image origin for bmp is at lower right. */
fdata = (l_uint8 *)cdata + offset; /* start of the bmp image data */
pixdata = pixGetData(pix);
if (depth != 24) { /* typ. 1 or 8 bpp */
data = (l_uint8 *)pixdata + pixBpl * (height - 1);
for (i = 0; i < height; i++) {
memcpy(data, fdata, fdatabpl);
fdata += fdatabpl;
data -= pixBpl;
}
} else { /* 24 bpp file; 32 bpp pix
* Note: for bmp files, pel[0] is blue, pel[1] is green,
* and pel[2] is red. This is opposite to the storage
* in the pix, which puts the red pixel in the 0 byte,
* the green in the 1 byte and the blue in the 2 byte.
* Note also that all words are endian flipped after
* assignment on L_LITTLE_ENDIAN platforms.
*
* We can then make these assignments for little endians:
* SET_DATA_BYTE(pword, 1, pel[0]); blue
* SET_DATA_BYTE(pword, 2, pel[1]); green
* SET_DATA_BYTE(pword, 3, pel[2]); red
* This looks like:
* 3 (R) 2 (G) 1 (B) 0
* |-----------|------------|-----------|-----------|
* and after byte flipping:
* 3 2 (B) 1 (G) 0 (R)
* |-----------|------------|-----------|-----------|
*
* For big endians we set:
* SET_DATA_BYTE(pword, 2, pel[0]); blue
* SET_DATA_BYTE(pword, 1, pel[1]); green
* SET_DATA_BYTE(pword, 0, pel[2]); red
* This looks like:
* 0 (R) 1 (G) 2 (B) 3
示例6: pixSetSelectCmap
/*!
* pixSetSelectCmap()
*
* Input: pixs (1, 2, 4 or 8 bpp, with colormap)
* box (<optional> region to set color; can be NULL)
* sindex (colormap index of pixels to be changed)
* rval, gval, bval (new color to paint)
* Return: 0 if OK, 1 on error
*
* Note:
* (1) This is an in-place operation.
* (2) It sets all pixels in region that have the color specified
* by the colormap index 'sindex' to the new color.
* (3) sindex must be in the existing colormap; otherwise an
* error is returned.
* (4) If the new color exists in the colormap, it is used;
* otherwise, it is added to the colormap. If it cannot be
* added because the colormap is full, an error is returned.
* (5) If box is NULL, applies function to the entire image; otherwise,
* clips the operation to the intersection of the box and pix.
* (6) An DC of use would be to set to a specific color all
* the light (background) pixels within a certain region of
* a 3-level 2 bpp image, while leaving light pixels outside
* this region unchanged.
*/
l_int32
pixSetSelectCmap(PIX *pixs,
BOX *box,
l_int32 sindex,
l_int32 rval,
l_int32 gval,
l_int32 bval)
{
l_int32 i, j, w, h, d, n, x1, y1, x2, y2, bw, bh, val, wpls;
l_int32 index; /* of new color to be set */
l_uint32 *lines, *datas;
PIXCMAP *cmap;
PROCNAME("pixSetSelectCmap");
if (!pixs)
return ERROR_INT("pixs not defined", procName, 1);
if ((cmap = pixGetColormap(pixs)) == NULL)
return ERROR_INT("no colormap", procName, 1);
d = pixGetDepth(pixs);
if (d != 1 && d != 2 && d != 4 && d != 8)
return ERROR_INT("depth not in {1,2,4,8}", procName, 1);
/* Add new color if necessary; get index of this color in cmap */
n = pixcmapGetCount(cmap);
if (sindex >= n)
return ERROR_INT("sindex too large; no cmap entry", procName, 1);
if (pixcmapGetIndex(cmap, rval, gval, bval, &index)) { /* not found */
if (pixcmapAddColor(cmap, rval, gval, bval))
return ERROR_INT("error adding cmap entry", procName, 1);
else
index = n; /* we've added one color */
}
/* Determine the region of substitution */
pixGetDimensions(pixs, &w, &h, NULL);
if (!box) {
x1 = y1 = 0;
x2 = w;
y2 = h;
} else {
boxGetGeometry(box, &x1, &y1, &bw, &bh);
x2 = x1 + bw - 1;
y2 = y1 + bh - 1;
}
/* Replace pixel value sindex by index in the region */
datas = pixGetData(pixs);
wpls = pixGetWpl(pixs);
for (i = y1; i <= y2; i++) {
if (i < 0 || i >= h) /* clip */
continue;
lines = datas + i * wpls;
for (j = x1; j <= x2; j++) {
if (j < 0 || j >= w) /* clip */
continue;
switch (d) {
case 1:
val = GET_DATA_BIT(lines, j);
if (val == sindex) {
if (index == 0)
CLEAR_DATA_BIT(lines, j);
else
SET_DATA_BIT(lines, j);
}
break;
case 2:
val = GET_DATA_DIBIT(lines, j);
if (val == sindex)
SET_DATA_DIBIT(lines, j, index);
break;
case 4:
val = GET_DATA_QBIT(lines, j);
if (val == sindex)
SET_DATA_QBIT(lines, j, index);
//.........这里部分代码省略.........
示例7: pixGetData
// Adds sub-pixel resolution EdgeOffsets for the outline if the supplied
// pix is 8-bit. Does nothing otherwise.
// Operation: Consider the following near-horizontal line:
// _________
// |________
// |________
// At *every* position along this line, the gradient direction will be close
// to vertical. Extrapoaltion/interpolation of the position of the threshold
// that was used to binarize the image gives a more precise vertical position
// for each horizontal step, and the conflict in step direction and gradient
// direction can be used to ignore the vertical steps.
void C_OUTLINE::ComputeEdgeOffsets(int threshold, Pix* pix) {
if (pixGetDepth(pix) != 8) return;
const l_uint32* data = pixGetData(pix);
int wpl = pixGetWpl(pix);
int width = pixGetWidth(pix);
int height = pixGetHeight(pix);
bool negative = flag(COUT_INVERSE);
delete [] offsets;
offsets = new EdgeOffset[stepcount];
ICOORD pos = start;
ICOORD prev_gradient;
ComputeGradient(data, wpl, pos.x(), height - pos.y(), width, height,
&prev_gradient);
for (int s = 0; s < stepcount; ++s) {
ICOORD step_vec = step(s);
TPOINT pt1(pos);
pos += step_vec;
TPOINT pt2(pos);
ICOORD next_gradient;
ComputeGradient(data, wpl, pos.x(), height - pos.y(), width, height,
&next_gradient);
// Use the sum of the prev and next as the working gradient.
ICOORD gradient = prev_gradient + next_gradient;
// best_diff will be manipulated to be always positive.
int best_diff = 0;
// offset will be the extrapolation of the location of the greyscale
// threshold from the edge with the largest difference, relative to the
// location of the binary edge.
int offset = 0;
if (pt1.y == pt2.y && abs(gradient.y()) * 2 >= abs(gradient.x())) {
// Horizontal step. diff_sign == 1 indicates black above.
int diff_sign = (pt1.x > pt2.x) == negative ? 1 : -1;
int x = MIN(pt1.x, pt2.x);
int y = height - pt1.y;
int best_sum = 0;
int best_y = y;
EvaluateVerticalDiff(data, wpl, diff_sign, x, y, height,
&best_diff, &best_sum, &best_y);
// Find the strongest edge.
int test_y = y;
do {
++test_y;
} while (EvaluateVerticalDiff(data, wpl, diff_sign, x, test_y, height,
&best_diff, &best_sum, &best_y));
test_y = y;
do {
--test_y;
} while (EvaluateVerticalDiff(data, wpl, diff_sign, x, test_y, height,
&best_diff, &best_sum, &best_y));
offset = diff_sign * (best_sum / 2 - threshold) +
(y - best_y) * best_diff;
} else if (pt1.x == pt2.x && abs(gradient.x()) * 2 >= abs(gradient.y())) {
// Vertical step. diff_sign == 1 indicates black on the left.
int diff_sign = (pt1.y > pt2.y) == negative ? 1 : -1;
int x = pt1.x;
int y = height - MAX(pt1.y, pt2.y);
const l_uint32* line = pixGetData(pix) + y * wpl;
int best_sum = 0;
int best_x = x;
EvaluateHorizontalDiff(line, diff_sign, x, width,
&best_diff, &best_sum, &best_x);
// Find the strongest edge.
int test_x = x;
do {
++test_x;
} while (EvaluateHorizontalDiff(line, diff_sign, test_x, width,
&best_diff, &best_sum, &best_x));
test_x = x;
do {
--test_x;
} while (EvaluateHorizontalDiff(line, diff_sign, test_x, width,
&best_diff, &best_sum, &best_x));
offset = diff_sign * (threshold - best_sum / 2) +
(best_x - x) * best_diff;
}
offsets[s].offset_numerator =
static_cast<inT8>(ClipToRange(offset, -MAX_INT8, MAX_INT8));
offsets[s].pixel_diff = static_cast<uinT8>(ClipToRange(best_diff, 0 ,
MAX_UINT8));
if (negative) gradient = -gradient;
// Compute gradient angle quantized to 256 directions, rotated by 64 (pi/2)
// to convert from gradient direction to edge direction.
offsets[s].direction =
Modulo(FCOORD::binary_angle_plus_pi(gradient.angle()) + 64, 256);
prev_gradient = next_gradient;
}
}
示例8: pixReadStreamJpeg
//.........这里部分代码省略.........
pixSetInputFormat(pix, IFF_JFIF_JPEG);
if (!rowbuffer || !pix) {
LEPT_FREE(rowbuffer);
pixDestroy(&pix);
return (PIX *)ERROR_PTR("rowbuffer or pix not made", procName, NULL);
}
/* Initialize decompression. Set up a colormap for color
* quantization if requested. */
if (spp == 1) { /* Grayscale or colormapped */
jpeg_start_decompress(&cinfo);
} else { /* Color; spp == 3 or YCCK or CMYK */
if (cmapflag == 0) { /* 24 bit color in 32 bit pix or YCCK/CMYK */
cinfo.quantize_colors = FALSE;
jpeg_start_decompress(&cinfo);
} else { /* Color quantize to 8 bits */
cinfo.quantize_colors = TRUE;
cinfo.desired_number_of_colors = 256;
jpeg_start_decompress(&cinfo);
/* Construct a pix cmap */
cmap = pixcmapCreate(8);
ncolors = cinfo.actual_number_of_colors;
for (cindex = 0; cindex < ncolors; cindex++) {
rval = cinfo.colormap[0][cindex];
gval = cinfo.colormap[1][cindex];
bval = cinfo.colormap[2][cindex];
pixcmapAddColor(cmap, rval, gval, bval);
}
pixSetColormap(pix, cmap);
}
}
wpl = pixGetWpl(pix);
data = pixGetData(pix);
/* Decompress. Unfortunately, we cannot use the return value
* from jpeg_read_scanlines() to determine if there was a problem
* with the data; it always appears to return 1. We can only
* tell from the warnings during decoding, such as "premature
* end of data segment". The default behavior is to return an
* image even if there are warnings. However, by setting the
* hint to have the same bit flag as L_JPEG_FAIL_ON_BAD_DATA,
* no image will be returned if there are any warnings. */
for (i = 0; i < h; i++) {
if (jpeg_read_scanlines(&cinfo, &rowbuffer, (JDIMENSION)1) == 0) {
L_ERROR("read error at scanline %d\n", procName, i);
pixDestroy(&pix);
jpeg_destroy_decompress(&cinfo);
LEPT_FREE(rowbuffer);
return (PIX *)ERROR_PTR("bad data", procName, NULL);
}
/* -- 24 bit color -- */
if ((spp == 3 && cmapflag == 0) || ycck || cmyk) {
ppixel = data + i * wpl;
if (spp == 3) {
for (j = k = 0; j < w; j++) {
SET_DATA_BYTE(ppixel, COLOR_RED, rowbuffer[k++]);
SET_DATA_BYTE(ppixel, COLOR_GREEN, rowbuffer[k++]);
SET_DATA_BYTE(ppixel, COLOR_BLUE, rowbuffer[k++]);
ppixel++;
}
} else {
/* This is a conversion from CMYK -> RGB that ignores
color profiles, and is invoked when the image header
claims to be in CMYK or YCCK colorspace. If in YCCK,
示例9: pixWriteStreamJpeg
//.........这里部分代码省略.........
/* Initialize the jpeg structs for compression */
jpeg_create_compress(&cinfo);
jpeg_stdio_dest(&cinfo, fp);
cinfo.image_width = w;
cinfo.image_height = h;
/* Set the color space and number of components */
d = pixGetDepth(pix);
if (d == 8) {
colorflag = 0; /* 8 bpp grayscale; no cmap */
cinfo.input_components = 1;
cinfo.in_color_space = JCS_GRAYSCALE;
} else { /* d == 32 || d == 24 */
colorflag = 1; /* rgb */
cinfo.input_components = 3;
cinfo.in_color_space = JCS_RGB;
}
jpeg_set_defaults(&cinfo);
/* Setting optimize_coding to TRUE seems to improve compression
* by approx 2-4 percent, and increases comp time by approx 20%. */
cinfo.optimize_coding = FALSE;
/* Set resolution in pixels/in (density_unit: 1 = in, 2 = cm) */
xres = pixGetXRes(pix);
yres = pixGetYRes(pix);
if ((xres != 0) && (yres != 0)) {
cinfo.density_unit = 1; /* designates pixels per inch */
cinfo.X_density = xres;
cinfo.Y_density = yres;
}
/* Set the quality and progressive parameters */
jpeg_set_quality(&cinfo, quality, TRUE);
if (progressive)
jpeg_simple_progression(&cinfo);
/* Set the chroma subsampling parameters. This is done in
* YUV color space. The Y (intensity) channel is never subsampled.
* The standard subsampling is 2x2 on both the U and V channels.
* Notation on this is confusing. For a nice illustrations, see
* http://en.wikipedia.org/wiki/Chroma_subsampling
* The standard subsampling is written as 4:2:0.
* We allow high quality where there is no subsampling on the
* chroma channels: denoted as 4:4:4. */
if (pixs->special == L_NO_CHROMA_SAMPLING_JPEG) {
cinfo.comp_info[0].h_samp_factor = 1;
cinfo.comp_info[0].v_samp_factor = 1;
cinfo.comp_info[1].h_samp_factor = 1;
cinfo.comp_info[1].v_samp_factor = 1;
cinfo.comp_info[2].h_samp_factor = 1;
cinfo.comp_info[2].v_samp_factor = 1;
}
jpeg_start_compress(&cinfo, TRUE);
if ((text = pixGetText(pix)))
jpeg_write_marker(&cinfo, JPEG_COM, (const JOCTET *)text, strlen(text));
/* Allocate row buffer */
spp = cinfo.input_components;
rowsamples = spp * w;
if ((rowbuffer = (JSAMPROW)LEPT_CALLOC(sizeof(JSAMPLE), rowsamples))
== NULL) {
pixDestroy(&pix);
return ERROR_INT("calloc fail for rowbuffer", procName, 1);
}
data = pixGetData(pix);
wpl = pixGetWpl(pix);
for (i = 0; i < h; i++) {
line = data + i * wpl;
if (colorflag == 0) { /* 8 bpp gray */
for (j = 0; j < w; j++)
rowbuffer[j] = GET_DATA_BYTE(line, j);
} else { /* colorflag == 1 */
if (d == 24) { /* See note 3 above; special case of 24 bpp rgb */
jpeg_write_scanlines(&cinfo, (JSAMPROW *)&line, 1);
} else { /* standard 32 bpp rgb */
ppixel = line;
for (j = k = 0; j < w; j++) {
rowbuffer[k++] = GET_DATA_BYTE(ppixel, COLOR_RED);
rowbuffer[k++] = GET_DATA_BYTE(ppixel, COLOR_GREEN);
rowbuffer[k++] = GET_DATA_BYTE(ppixel, COLOR_BLUE);
ppixel++;
}
}
}
if (d != 24)
jpeg_write_scanlines(&cinfo, &rowbuffer, 1);
}
jpeg_finish_compress(&cinfo);
pixDestroy(&pix);
LEPT_FREE(rowbuffer);
jpeg_destroy_compress(&cinfo);
return 0;
}
示例10: pixProjectiveSampled
/*!
* pixProjectiveSampled()
*
* Input: pixs (all depths)
* vc (vector of 8 coefficients for projective transformation)
* incolor (L_BRING_IN_WHITE, L_BRING_IN_BLACK)
* Return: pixd, or null on error
*
* Notes:
* (1) Brings in either black or white pixels from the boundary.
* (2) Retains colormap, which you can do for a sampled transform..
* (3) For 8 or 32 bpp, much better quality is obtained by the
* somewhat slower pixProjective(). See that function
* for relative timings between sampled and interpolated.
*/
PIX *
pixProjectiveSampled(PIX *pixs,
l_float32 *vc,
l_int32 incolor)
{
l_int32 i, j, w, h, d, x, y, wpls, wpld, color, cmapindex;
l_uint32 val;
l_uint32 *datas, *datad, *lines, *lined;
PIX *pixd;
PIXCMAP *cmap;
PROCNAME("pixProjectiveSampled");
if (!pixs)
return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
if (!vc)
return (PIX *)ERROR_PTR("vc not defined", procName, NULL);
if (incolor != L_BRING_IN_WHITE && incolor != L_BRING_IN_BLACK)
return (PIX *)ERROR_PTR("invalid incolor", procName, NULL);
pixGetDimensions(pixs, &w, &h, &d);
if (d != 1 && d != 2 && d != 4 && d != 8 && d != 32)
return (PIX *)ERROR_PTR("depth not 1, 2, 4, 8 or 16", procName, NULL);
/* Init all dest pixels to color to be brought in from outside */
pixd = pixCreateTemplate(pixs);
if ((cmap = pixGetColormap(pixs)) != NULL) {
if (incolor == L_BRING_IN_WHITE)
color = 1;
else
color = 0;
pixcmapAddBlackOrWhite(cmap, color, &cmapindex);
pixSetAllArbitrary(pixd, cmapindex);
}
else {
if ((d == 1 && incolor == L_BRING_IN_WHITE) ||
(d > 1 && incolor == L_BRING_IN_BLACK))
pixClearAll(pixd);
else
pixSetAll(pixd);
}
/* Scan over the dest pixels */
datas = pixGetData(pixs);
wpls = pixGetWpl(pixs);
datad = pixGetData(pixd);
wpld = pixGetWpl(pixd);
for (i = 0; i < h; i++) {
lined = datad + i * wpld;
for (j = 0; j < w; j++) {
projectiveXformSampledPt(vc, j, i, &x, &y);
if (x < 0 || y < 0 || x >=w || y >= h)
continue;
lines = datas + y * wpls;
if (d == 1) {
val = GET_DATA_BIT(lines, x);
SET_DATA_BIT_VAL(lined, j, val);
}
else if (d == 8) {
val = GET_DATA_BYTE(lines, x);
SET_DATA_BYTE(lined, j, val);
}
else if (d == 32) {
lined[j] = lines[x];
}
else if (d == 2) {
val = GET_DATA_DIBIT(lines, x);
SET_DATA_DIBIT(lined, j, val);
}
else if (d == 4) {
val = GET_DATA_QBIT(lines, x);
SET_DATA_QBIT(lined, j, val);
}
}
}
return pixd;
}
示例11: pixExpandBinaryPower2
/*!
* pixExpandBinaryPower2()
*
* Input: pixs (1 bpp)
* factor (expansion factor: 1, 2, 4, 8, 16)
* Return: pixd (expanded 1 bpp by replication), or null on error
*/
PIX *
pixExpandBinaryPower2(PIX *pixs,
l_int32 factor)
{
l_uint8 sval;
l_uint16 *tab2;
l_int32 i, j, k, w, h, d, wd, hd, wpls, wpld, sdibits, sqbits, sbytes;
l_uint32 *datas, *datad, *lines, *lined, *tab4, *tab8;
PIX *pixd;
PROCNAME("pixExpandBinaryPower2");
if (!pixs)
return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
pixGetDimensions(pixs, &w, &h, &d);
if (d != 1)
return (PIX *)ERROR_PTR("pixs not binary", procName, NULL);
if (factor == 1)
return pixCopy(NULL, pixs);
if (factor != 2 && factor != 4 && factor != 8 && factor != 16)
return (PIX *)ERROR_PTR("factor must be in {2,4,8,16}", procName, NULL);
wpls = pixGetWpl(pixs);
datas = pixGetData(pixs);
wd = factor * w;
hd = factor * h;
if ((pixd = pixCreate(wd, hd, 1)) == NULL)
return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
pixCopyResolution(pixd, pixs);
pixScaleResolution(pixd, (l_float32)factor, (l_float32)factor);
wpld = pixGetWpl(pixd);
datad = pixGetData(pixd);
if (factor == 2) {
if ((tab2 = makeExpandTab2x()) == NULL)
return (PIX *)ERROR_PTR("tab2 not made", procName, NULL);
sbytes = (w + 7) / 8;
for (i = 0; i < h; i++) {
lines = datas + i * wpls;
lined = datad + 2 * i * wpld;
for (j = 0; j < sbytes; j++) {
sval = GET_DATA_BYTE(lines, j);
SET_DATA_TWO_BYTES(lined, j, tab2[sval]);
}
memcpy((char *)(lined + wpld), (char *)lined, 4 * wpld);
}
FREE(tab2);
} else if (factor == 4) {
if ((tab4 = makeExpandTab4x()) == NULL)
return (PIX *)ERROR_PTR("tab4 not made", procName, NULL);
sbytes = (w + 7) / 8;
for (i = 0; i < h; i++) {
lines = datas + i * wpls;
lined = datad + 4 * i * wpld;
for (j = 0; j < sbytes; j++) {
sval = GET_DATA_BYTE(lines, j);
lined[j] = tab4[sval];
}
for (k = 1; k < 4; k++)
memcpy((char *)(lined + k * wpld), (char *)lined, 4 * wpld);
}
FREE(tab4);
} else if (factor == 8) {
if ((tab8 = makeExpandTab8x()) == NULL)
return (PIX *)ERROR_PTR("tab8 not made", procName, NULL);
sqbits = (w + 3) / 4;
for (i = 0; i < h; i++) {
lines = datas + i * wpls;
lined = datad + 8 * i * wpld;
for (j = 0; j < sqbits; j++) {
sval = GET_DATA_QBIT(lines, j);
if (sval > 15)
L_WARNING("sval = %d; should be < 16\n", procName, sval);
lined[j] = tab8[sval];
}
for (k = 1; k < 8; k++)
memcpy((char *)(lined + k * wpld), (char *)lined, 4 * wpld);
}
FREE(tab8);
} else { /* factor == 16 */
sdibits = (w + 1) / 2;
for (i = 0; i < h; i++) {
lines = datas + i * wpls;
lined = datad + 16 * i * wpld;
for (j = 0; j < sdibits; j++) {
sval = GET_DATA_DIBIT(lines, j);
lined[j] = expandtab16[sval];
}
for (k = 1; k < 16; k++)
memcpy((char *)(lined + k * wpld), (char *)lined, 4 * wpld);
}
}
return pixd;
//.........这里部分代码省略.........
示例12: pixAssignToNearestColor
/*!
* \brief pixAssignToNearestColor()
*
* \param[in] pixd 8 bpp, colormapped
* \param[in] pixs 32 bpp; 24-bit color
* \param[in] pixm [optional] 1 bpp
* \param[in] level of octcube used for finding nearest color in cmap
* \param[in] countarray [optional] ptr to array, in which we can store
* the number of pixels found in each color in
* the colormap in pixd
* \return 0 if OK, 1 on error
*
* <pre>
* Notes:
* (1) This is used in phase 2 of color segmentation, where pixs
* is the original input image to pixColorSegment(), and
* pixd is the colormapped image returned from
* pixColorSegmentCluster(). It is also used, with a mask,
* in phase 4.
* (2) This is an in-place operation.
* (3) The colormap in pixd is unchanged.
* (4) pixs and pixd must be the same size (w, h).
* (5) The selection mask pixm can be null. If it exists, it must
* be the same size as pixs and pixd, and only pixels
* corresponding to fg in pixm are assigned. Set to
* NULL if all pixels in pixd are to be assigned.
* (6) The countarray can be null. If it exists, it is pre-allocated
* and of a size at least equal to the size of the colormap in pixd.
* (7) This does a best-fit (non-greedy) assignment of pixels to
* existing clusters. Specifically, it assigns each pixel
* in pixd to the color index in the pixd colormap that has a
* color closest to the corresponding rgb pixel in pixs.
* (8) 'level' is the octcube level used to quickly find the nearest
* color in the colormap for each pixel. For color segmentation,
* this parameter is set to LEVEL_IN_OCTCUBE.
* (9) We build a mapping table from octcube to colormap index so
* that this function can run in a time (otherwise) independent
* of the number of colors in the colormap. This avoids a
* brute-force search for the closest colormap color to each
* pixel in the image.
* </pre>
*/
l_ok
pixAssignToNearestColor(PIX *pixd,
PIX *pixs,
PIX *pixm,
l_int32 level,
l_int32 *countarray)
{
l_int32 w, h, wpls, wpld, wplm, i, j, success;
l_int32 rval, gval, bval, index;
l_int32 *cmaptab;
l_uint32 octindex;
l_uint32 *rtab, *gtab, *btab;
l_uint32 *ppixel;
l_uint32 *datas, *datad, *datam, *lines, *lined, *linem;
PIXCMAP *cmap;
PROCNAME("pixAssignToNearestColor");
if (!pixd)
return ERROR_INT("pixd not defined", procName, 1);
if ((cmap = pixGetColormap(pixd)) == NULL)
return ERROR_INT("cmap not found", procName, 1);
if (!pixs)
return ERROR_INT("pixs not defined", procName, 1);
if (pixGetDepth(pixs) != 32)
return ERROR_INT("pixs not 32 bpp", procName, 1);
if (level < 1 || level > 6)
return ERROR_INT("level not in [1 ... 6]", procName, 1);
/* Set up the tables to map rgb to the nearest colormap index */
success = TRUE;
makeRGBToIndexTables(&rtab, >ab, &btab, level);
cmaptab = pixcmapToOctcubeLUT(cmap, level, L_MANHATTAN_DISTANCE);
if (!rtab || !gtab || !btab || !cmaptab) {
L_ERROR("failure to make a table\n", procName);
success = FALSE;
goto cleanup_arrays;
}
pixGetDimensions(pixs, &w, &h, NULL);
datas = pixGetData(pixs);
datad = pixGetData(pixd);
wpls = pixGetWpl(pixs);
wpld = pixGetWpl(pixd);
if (pixm) {
datam = pixGetData(pixm);
wplm = pixGetWpl(pixm);
}
for (i = 0; i < h; i++) {
lines = datas + i * wpls;
lined = datad + i * wpld;
if (pixm)
linem = datam + i * wplm;
for (j = 0; j < w; j++) {
if (pixm) {
if (!GET_DATA_BIT(linem, j))
continue;
}
//.........这里部分代码省略.........
示例13: pixColorSegmentTryCluster
/*!
* \brief pixColorSegmentTryCluster()
*
* \param[in] pixd
* \param[in] pixs
* \param[in] maxdist
* \param[in] maxcolors
* \param[in] debugflag 1 for debug output; 0 otherwise
* \return 0 if OK, 1 on error
*
* <pre>
* Notes:
* This function should only be called from pixColorSegCluster()
* </pre>
*/
static l_int32
pixColorSegmentTryCluster(PIX *pixd,
PIX *pixs,
l_int32 maxdist,
l_int32 maxcolors,
l_int32 debugflag)
{
l_int32 rmap[256], gmap[256], bmap[256];
l_int32 w, h, wpls, wpld, i, j, k, found, ret, index, ncolors;
l_int32 rval, gval, bval, dist2, maxdist2;
l_int32 countarray[256];
l_int32 rsum[256], gsum[256], bsum[256];
l_uint32 *ppixel;
l_uint32 *datas, *datad, *lines, *lined;
PIXCMAP *cmap;
PROCNAME("pixColorSegmentTryCluster");
if (!pixs)
return ERROR_INT("pixs not defined", procName, 1);
if (!pixd)
return ERROR_INT("pixd not defined", procName, 1);
w = pixGetWidth(pixs);
h = pixGetHeight(pixs);
maxdist2 = maxdist * maxdist;
cmap = pixGetColormap(pixd);
pixcmapClear(cmap);
for (k = 0; k < 256; k++) {
rsum[k] = gsum[k] = bsum[k] = 0;
rmap[k] = gmap[k] = bmap[k] = 0;
}
datas = pixGetData(pixs);
datad = pixGetData(pixd);
wpls = pixGetWpl(pixs);
wpld = pixGetWpl(pixd);
ncolors = 0;
for (i = 0; i < h; i++) {
lines = datas + i * wpls;
lined = datad + i * wpld;
for (j = 0; j < w; j++) {
ppixel = lines + j;
rval = GET_DATA_BYTE(ppixel, COLOR_RED);
gval = GET_DATA_BYTE(ppixel, COLOR_GREEN);
bval = GET_DATA_BYTE(ppixel, COLOR_BLUE);
ncolors = pixcmapGetCount(cmap);
found = FALSE;
for (k = 0; k < ncolors; k++) {
dist2 = (rval - rmap[k]) * (rval - rmap[k]) +
(gval - gmap[k]) * (gval - gmap[k]) +
(bval - bmap[k]) * (bval - bmap[k]);
if (dist2 <= maxdist2) { /* take it; greedy */
found = TRUE;
SET_DATA_BYTE(lined, j, k);
countarray[k]++;
rsum[k] += rval;
gsum[k] += gval;
bsum[k] += bval;
break;
}
}
if (!found) { /* Add a new color */
ret = pixcmapAddNewColor(cmap, rval, gval, bval, &index);
/* fprintf(stderr,
"index = %d, (i,j) = (%d,%d), rgb = (%d, %d, %d)\n",
index, i, j, rval, gval, bval); */
if (ret == 0 && index < maxcolors) {
countarray[index] = 1;
SET_DATA_BYTE(lined, j, index);
rmap[index] = rval;
gmap[index] = gval;
bmap[index] = bval;
rsum[index] = rval;
gsum[index] = gval;
bsum[index] = bval;
} else {
if (debugflag) {
L_INFO("maxcolors exceeded for maxdist = %d\n",
procName, maxdist);
}
return 1;
}
}
}
//.........这里部分代码省略.........
示例14: pixColorGrayCmap
/*!
* pixColorGrayCmap()
*
* Input: pixs (2, 4 or 8 bpp, with colormap)
* box (<optional> region to set color; can be NULL)
* type (L_PAINT_LIGHT, L_PAINT_DARK)
* rval, gval, bval (target color)
* Return: 0 if OK, 1 on error
*
* Notes:
* (1) This is an in-place operation.
* (2) If type == L_PAINT_LIGHT, it colorizes non-black pixels,
* preserving antialiasing.
* If type == L_PAINT_DARK, it colorizes non-white pixels,
* preserving antialiasing.
* (3) If box is NULL, applies function to the entire image; otherwise,
* clips the operation to the intersection of the box and pix.
* (4) This can also be called through pixColorGray().
* (5) This increases the colormap size by the number of
* different gray (non-black or non-white) colors in the
* input colormap. If there is not enough room in the colormap
* for this expansion, it returns 1 (error), and the caller
* should check the return value. If an error is returned
* and the cmap is only 2 or 4 bpp, the pix can be converted
* to 8 bpp and this function will succeed if run again on
* a larger colormap.
* (6) Using the darkness of each original pixel in the rect,
* it generates a new color (based on the input rgb values).
* If type == L_PAINT_LIGHT, the new color is a (generally)
* darken-to-black version of the input rgb color, where the
* amount of darkening increases with the darkness of the
* original pixel color.
* If type == L_PAINT_DARK, the new color is a (generally)
* faded-to-white version of the input rgb color, where the
* amount of fading increases with the brightness of the
* original pixel color.
*/
l_int32
pixColorGrayCmap(PIX *pixs,
BOX *box,
l_int32 type,
l_int32 rval,
l_int32 gval,
l_int32 bval)
{
l_int32 i, j, w, h, d, x1, y1, x2, y2, bw, bh, wpl;
l_int32 val, nval;
l_int32 *map;
l_uint32 *line, *data;
NUMA *na;
PIX *pixt;
PIXCMAP *cmap, *cmapc;
PROCNAME("pixColorGrayCmap");
if (!pixs)
return ERROR_INT("pixs not defined", procName, 1);
if ((cmap = pixGetColormap(pixs)) == NULL)
return ERROR_INT("no colormap", procName, 1);
d = pixGetDepth(pixs);
if (d != 2 && d != 4 && d != 8)
return ERROR_INT("depth not in {2, 4, 8}", procName, 1);
if (type != L_PAINT_DARK && type != L_PAINT_LIGHT)
return ERROR_INT("invalid type", procName, 1);
/* If 2 bpp or 4 bpp, see if the new colors will fit into
* the existing colormap. If not, convert in-place to 8 bpp. */
if (d == 2 || d == 4) {
cmapc = pixcmapCopy(cmap); /* experiment with a copy */
if (addColorizedGrayToCmap(cmapc, type, rval, gval, bval, NULL)) {
pixt = pixConvertTo8(pixs, 1);
pixTransferAllData(pixs, &pixt, 0, 0);
}
pixcmapDestroy(&cmapc);
}
/* Find gray colors, add the corresponding new colors,
* and set up a mapping table from gray to new.
* That table has the value 256 for all colors that are
* not to be mapped. */
cmap = pixGetColormap(pixs);
if (addColorizedGrayToCmap(cmap, type, rval, gval, bval, &na)) {
numaDestroy(&na);
return ERROR_INT("no room; cmap full", procName, 1);
}
map = numaGetIArray(na);
/* Determine the region of substitution */
pixGetDimensions(pixs, &w, &h, &d); /* d may be different */
data = pixGetData(pixs);
wpl = pixGetWpl(pixs);
if (!box) {
x1 = y1 = 0;
x2 = w;
y2 = h;
}
else {
boxGetGeometry(box, &x1, &y1, &bw, &bh);
x2 = x1 + bw - 1;
y2 = y1 + bh - 1;
//.........这里部分代码省略.........
示例15: pixSetSelectMaskedCmap
/*!
* pixSetSelectMaskedCmap()
*
* Input: pixs (2, 4 or 8 bpp, with colormap)
* pixm (<optional> 1 bpp mask; no-op if NULL)
* x, y (UL corner of mask relative to pixs)
* sindex (colormap index of pixels in pixs to be changed)
* rval, gval, bval (new color to substitute)
* Return: 0 if OK, 1 on error
*
* Note:
* (1) This is an in-place operation.
* (2) This paints through the fg of pixm and replaces all pixels
* in pixs that have a particular value (sindex) with the new color.
* (3) If pixm == NULL, a warning is given.
* (4) sindex must be in the existing colormap; otherwise an
* error is returned.
* (5) If the new color exists in the colormap, it is used;
* otherwise, it is added to the colormap. If the colormap
* is full, an error is returned.
*/
l_int32
pixSetSelectMaskedCmap(PIX *pixs,
PIX *pixm,
l_int32 x,
l_int32 y,
l_int32 sindex,
l_int32 rval,
l_int32 gval,
l_int32 bval)
{
l_int32 i, j, w, h, d, n, wm, hm, wpls, wplm, val;
l_int32 index; /* of new color to be set */
l_uint32 *lines, *linem, *datas, *datam;
PIXCMAP *cmap;
PROCNAME("pixSetSelectMaskedCmap");
if (!pixs)
return ERROR_INT("pixs not defined", procName, 1);
if ((cmap = pixGetColormap(pixs)) == NULL)
return ERROR_INT("no colormap", procName, 1);
if (!pixm) {
L_WARNING("no mask; nothing to do\n", procName);
return 0;
}
d = pixGetDepth(pixs);
if (d != 2 && d != 4 && d != 8)
return ERROR_INT("depth not in {2, 4, 8}", procName, 1);
/* add new color if necessary; get index of this color in cmap */
n = pixcmapGetCount(cmap);
if (sindex >= n)
return ERROR_INT("sindex too large; no cmap entry", procName, 1);
if (pixcmapGetIndex(cmap, rval, gval, bval, &index)) { /* not found */
if (pixcmapAddColor(cmap, rval, gval, bval))
return ERROR_INT("error adding cmap entry", procName, 1);
else
index = n; /* we've added one color */
}
/* replace pixel value sindex by index when fg pixel in pixmc
* overlays it */
w = pixGetWidth(pixs);
h = pixGetHeight(pixs);
datas = pixGetData(pixs);
wpls = pixGetWpl(pixs);
wm = pixGetWidth(pixm);
hm = pixGetHeight(pixm);
datam = pixGetData(pixm);
wplm = pixGetWpl(pixm);
for (i = 0; i < hm; i++) {
if (i + y < 0 || i + y >= h) continue;
lines = datas + (y + i) * wpls;
linem = datam + i * wplm;
for (j = 0; j < wm; j++) {
if (j + x < 0 || j + x >= w) continue;
if (GET_DATA_BIT(linem, j)) {
switch (d) {
case 1:
val = GET_DATA_BIT(lines, x + j);
if (val == sindex) {
if (index == 0)
CLEAR_DATA_BIT(lines, x + j);
else
SET_DATA_BIT(lines, x + j);
}
break;
case 2:
val = GET_DATA_DIBIT(lines, x + j);
if (val == sindex)
SET_DATA_DIBIT(lines, x + j, index);
break;
case 4:
val = GET_DATA_QBIT(lines, x + j);
if (val == sindex)
SET_DATA_QBIT(lines, x + j, index);
break;
case 8:
//.........这里部分代码省略.........