src/blend.c
l_int32
pixColorGray(PIX     *pixs,
             BOX     *box,
             l_int32  type,
             l_int32  thresh,
             l_int32  rval,
             l_int32  gval,
             l_int32  bval)
{
l_int32    i, j, w, h, d, wpl, x1, x2, y1, y2, bw, bh;
l_int32    nrval, ngval, nbval, aveval;
l_float32  factor;
l_uint32   val32;
l_uint32  *line, *data;
PIX       *pixt;
PIXCMAP   *cmap;

    PROCNAME("pixColorGray");

    if (!pixs)
        return ERROR_INT("pixs not defined", procName, 1);
    if (type != L_PAINT_LIGHT && type != L_PAINT_DARK)
        return ERROR_INT("invalid type", procName, 1);

    cmap = pixGetColormap(pixs);
    pixGetDimensions(pixs, &w, &h, &d);
    if (!cmap && d != 8 && d != 32)
        return ERROR_INT("pixs not cmapped, 8 bpp or rgb", procName, 1);
    if (cmap)
        return pixColorGrayCmap(pixs, box, type, rval, gval, bval);

        /* rgb or 8 bpp gray image; check the thresh */
    if (type == L_PAINT_LIGHT) {  /* thresh should be low */
        if (thresh >= 255)
            return ERROR_INT("thresh must be < 255; else this is a no-op",
                             procName, 1);
        if (thresh > 127)
            L_WARNING("threshold set very high", procName);
    }
    else {  /* type == L_PAINT_DARK; thresh should be high */
        if (thresh <= 0)
            return ERROR_INT("thresh must be > 0; else this is a no-op",
                             procName, 1);
        if (thresh < 128)
            L_WARNING("threshold set very low", procName);
    }

    if (d == 8) {
        pixt = pixConvertTo32(pixs);
        pixTransferAllData(pixs, &pixt, 1, 0);
    }

    if (!box) {
        x1 = y1 = 0;
        x2 = w;
        y2 = h;
    }
    else {
        boxGetGeometry(box, &x1, &y1, &bw, &bh);
        x2 = x1 + bw - 1;
        y2 = y1 + bh - 1;
    }

    data = pixGetData(pixs);
    wpl = pixGetWpl(pixs);
    factor = 1. / 255.;
    for (i = y1; i <= y2; i++) {
        if (i < 0 || i >= h)
            continue;
        line = data + i * wpl;
        for (j = x1; j <= x2; j++) {
            if (j < 0 || j >= w)
                continue;
            val32 = *(line + j);
            aveval = ((val32 >> 24) + ((val32 >> 16) & 0xff) +
                      ((val32 >> 8) & 0xff)) / 3;
            if (type == L_PAINT_LIGHT) {
                if (aveval < thresh)  /* skip sufficiently dark pixels */
                    continue;
                nrval = (l_int32)(rval * aveval * factor);
                ngval = (l_int32)(gval * aveval * factor);
                nbval = (l_int32)(bval * aveval * factor);
            }
            else {  /* type == L_PAINT_DARK */
                if (aveval > thresh)  /* skip sufficiently light pixels */
                    continue;
                nrval = rval + (l_int32)((255. - rval) * aveval * factor);
                ngval = gval + (l_int32)((255. - gval) * aveval * factor);
                nbval = bval + (l_int32)((255. - bval) * aveval * factor);
            }
            composeRGBPixel(nrval, ngval, nbval, &val32);
            *(line + j) = val32;
        }
    }

    return 0;
}
/*!
 *  pixColorGray()
 *
 *      Input:  pixs (8 bpp gray, rgb or colormapped image)
 *              box (<optional> region in which to apply color; can be NULL)
 *              type (L_PAINT_LIGHT, L_PAINT_DARK)
 *              thresh (average value below/above which pixel is unchanged)
 *              rval, gval, bval (new color to paint)
 *      Return: 0 if OK; 1 on error
 *
 *  Notes:
 *      (1) This is an in-place operation; pixs is modified.
 *          If pixs is colormapped, the operation will add colors to the
 *          colormap.  Otherwise, pixs will be converted to 32 bpp rgb if
 *          it is initially 8 bpp gray.
 *      (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) If colormapped, calls pixColorGrayCmap(), which applies the
 *          coloring algorithm only to pixels that are strictly gray.
 *      (5) For RGB, determines a "gray" value by averaging; then uses this
 *          value, plus the input rgb target, to generate the output
 *          pixel values.
 *      (6) thresh is only used for rgb; it is ignored for colormapped pix.
 *          If type == L_PAINT_LIGHT, use thresh = 0 if all pixels are to
 *          be colored (black pixels will be unaltered).
 *          In situations where there are a lot of black pixels,
 *          setting thresh > 0 will make the function considerably
 *          more efficient without affecting the final result.
 *          If type == L_PAINT_DARK, use thresh = 255 if all pixels
 *          are to be colored (white pixels will be unaltered).
 *          In situations where there are a lot of white pixels,
 *          setting thresh < 255 will make the function considerably
 *          more efficient without affecting the final result.
 */
pixColorGray()
Input:  pixs (8 bpp gray, rgb or colormapped image)
box ( region in which to apply color; can be NULL)
type (L_PAINT_LIGHT, L_PAINT_DARK)
thresh (average value below/above which pixel is unchanged)
rval, gval, bval (new color to paint)
Return: 0 if OK; 1 on error

(1) This is an in-place operation; pixs is modified.
If pixs is colormapped, the operation will add colors to the
colormap.  Otherwise, pixs will be converted to 32 bpp rgb if
it is initially 8 bpp gray.
(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) If colormapped, calls pixColorGrayCmap(), which applies the
coloring algorithm only to pixels that are strictly gray.
(5) For RGB, determines a "gray" value by averaging; then uses this
value, plus the input rgb target, to generate the output
pixel values.
(6) thresh is only used for rgb; it is ignored for colormapped pix.
If type == L_PAINT_LIGHT, use thresh = 0 if all pixels are to
be colored (black pixels will be unaltered).
In situations where there are a lot of black pixels,
setting thresh > 0 will make the function considerably
more efficient without affecting the final result.
If type == L_PAINT_DARK, use thresh = 255 if all pixels
are to be colored (white pixels will be unaltered).
In situations where there are a lot of white pixels,
setting thresh < 255 will make the function considerably
more efficient without affecting the final result.
pixColorGray () Input : pixs ( 8 bpp gray rgb or colormapped image ) box ( region in which to apply color ; can be NULL ) type ( L_PAINT_LIGHT L_PAINT_DARK ) thresh ( average value below / above which pixel is unchanged ) rval gval bval ( new color to paint ) Return : 0 if OK ; 1 on error ( 1 ) This is an in - place operation ; pixs is modified . If pixs is colormapped the operation will add colors to the colormap . Otherwise pixs will be converted to 32 bpp rgb if it is initially 8 bpp gray . ( 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 ) If colormapped calls pixColorGrayCmap () which applies the coloring algorithm only to pixels that are strictly gray . ( 5 ) For RGB determines a " gray " value by averaging ; then uses this value plus the input rgb target to generate the output pixel values . ( 6 ) thresh is only used for rgb ; it is ignored for colormapped pix . If type == L_PAINT_LIGHT use thresh = 0 if all pixels are to be colored ( black pixels will be unaltered ) . In situations where there are a lot of black pixels setting thresh > 0 will make the function considerably more efficient without affecting the final result . If type == L_PAINT_DARK use thresh = 255 if all pixels are to be colored ( white pixels will be unaltered ) . In situations where there are a lot of white pixels setting thresh < 255 will make the function considerably more efficient without affecting the final result .
l_int32
pixColorGray(PIX     *pixs,
             BOX     *box,
             l_int32  type,
             l_int32  thresh,
             l_int32  rval,
             l_int32  gval,
             l_int32  bval)
{
l_int32    i, j, w, h, d, wpl, x1, x2, y1, y2, bw, bh;
l_int32    nrval, ngval, nbval, aveval;
l_float32  factor;
l_uint32   val32;
l_uint32  *line, *data;
PIX       *pixt;
PIXCMAP   *cmap;
    PROCNAME("pixColorGray");
    if (!pixs)
        return ERROR_INT("pixs not defined", procName, 1);
    if (type != L_PAINT_LIGHT && type != L_PAINT_DARK)
        return ERROR_INT("invalid type", procName, 1);
    cmap = pixGetColormap(pixs);
    pixGetDimensions(pixs, &w, &h, &d);
    if (!cmap && d != 8 && d != 32)
        return ERROR_INT("pixs not cmapped, 8 bpp or rgb", procName, 1);
    if (cmap)
        return pixColorGrayCmap(pixs, box, type, rval, gval, bval);
    if (type == L_PAINT_LIGHT) {  
        if (thresh >= 255)
            return ERROR_INT("thresh must be < 255; else this is a no-op",
                             procName, 1);
        if (thresh > 127)
            L_WARNING("threshold set very high", procName);
    }
    else {  
        if (thresh <= 0)
            return ERROR_INT("thresh must be > 0; else this is a no-op",
                             procName, 1);
        if (thresh < 128)
            L_WARNING("threshold set very low", procName);
    }
    if (d == 8) {
        pixt = pixConvertTo32(pixs);
        pixTransferAllData(pixs, &pixt, 1, 0);
    }
    if (!box) {
        x1 = y1 = 0;
        x2 = w;
        y2 = h;
    }
    else {
        boxGetGeometry(box, &x1, &y1, &bw, &bh);
        x2 = x1 + bw - 1;
        y2 = y1 + bh - 1;
    }
    data = pixGetData(pixs);
    wpl = pixGetWpl(pixs);
    factor = 1. / 255.;
    for (i = y1; i <= y2; i++) {
        if (i < 0 || i >= h)
            continue;
        line = data + i * wpl;
        for (j = x1; j <= x2; j++) {
            if (j < 0 || j >= w)
                continue;
            val32 = *(line + j);
            aveval = ((val32 >> 24) + ((val32 >> 16) & 0xff) +
                      ((val32 >> 8) & 0xff)) / 3;
            if (type == L_PAINT_LIGHT) {
                if (aveval < thresh)  
                    continue;
                nrval = (l_int32)(rval * aveval * factor);
                ngval = (l_int32)(gval * aveval * factor);
                nbval = (l_int32)(bval * aveval * factor);
            }
            else {  
                if (aveval > thresh)  
                    continue;
                nrval = rval + (l_int32)((255. - rval) * aveval * factor);
                ngval = gval + (l_int32)((255. - gval) * aveval * factor);
                nbval = bval + (l_int32)((255. - bval) * aveval * factor);
            }
            composeRGBPixel(nrval, ngval, nbval, &val32);
            *(line + j) = val32;
        }
    }
    return 0;
}
l_int32 pixColorGray ( PIX * pixs , BOX * box , l_int32 type , l_int32 thresh , l_int32 rval , l_int32 gval , l_int32 bval ) { l_int32 i , j , w , h , d , wpl , x1 , x2 , y1 , y2 , bw , bh ; l_int32 nrval , ngval , nbval , aveval ; l_float32 factor ; l_uint32 val32 ; l_uint32 * line , * data ; PIX * pixt ; PIXCMAP * cmap ; PROCNAME ( " " ) ; if ( ! pixs ) return ERROR_INT ( " " , procName , 1 ) ; if ( type != L_PAINT_LIGHT && type != L_PAINT_DARK ) return ERROR_INT ( " " , procName , 1 ) ; cmap = pixGetColormap ( pixs ) ; pixGetDimensions ( pixs , & w , & h , & d ) ; if ( ! cmap && d != 8 && d != 32 ) return ERROR_INT ( " " , procName , 1 ) ; if ( cmap ) return pixColorGrayCmap ( pixs , box , type , rval , gval , bval ) ; if ( type == L_PAINT_LIGHT ) { if ( thresh >= 255 ) return ERROR_INT ( " " , procName , 1 ) ; if ( thresh > 127 ) L_WARNING ( " " , procName ) ; } else { if ( thresh <= 0 ) return ERROR_INT ( " " , procName , 1 ) ; if ( thresh < 128 ) L_WARNING ( " " , procName ) ; } if ( d == 8 ) { pixt = pixConvertTo32 ( pixs ) ; pixTransferAllData ( pixs , & pixt , 1 , 0 ) ; } if ( ! box ) { x1 = y1 = 0 ; x2 = w ; y2 = h ; } else { boxGetGeometry ( box , & x1 , & y1 , & bw , & bh ) ; x2 = x1 + bw - 1 ; y2 = y1 + bh - 1 ; } data = pixGetData ( pixs ) ; wpl = pixGetWpl ( pixs ) ; factor = 1. / 255. ; for ( i = y1 ; i <= y2 ; i ++ ) { if ( i < 0 || i >= h ) continue ; line = data + i * wpl ; for ( j = x1 ; j <= x2 ; j ++ ) { if ( j < 0 || j >= w ) continue ; val32 = * ( line + j ) ; aveval = ( ( val32 >> 24 ) + ( ( val32 >> 16 ) & 0xff ) + ( ( val32 >> 8 ) & 0xff ) ) / 3 ; if ( type == L_PAINT_LIGHT ) { if ( aveval < thresh ) continue ; nrval = ( l_int32 ) ( rval * aveval * factor ) ; ngval = ( l_int32 ) ( gval * aveval * factor ) ; nbval = ( l_int32 ) ( bval * aveval * factor ) ; } else { if ( aveval > thresh ) continue ; nrval = rval + ( l_int32 ) ( ( 255. - rval ) * aveval * factor ) ; ngval = gval + ( l_int32 ) ( ( 255. - gval ) * aveval * factor ) ; nbval = bval + ( l_int32 ) ( ( 255. - bval ) * aveval * factor ) ; } composeRGBPixel ( nrval , ngval , nbval , & val32 ) ; * ( line + j ) = val32 ; } } return 0 ; }
pixColorGray()
      Input:  pixs (8 bpp gray, rgb or colormapped image)
              box (<optional> region in which to apply color; can be NULL)
              type (L_PAINT_LIGHT, L_PAINT_DARK)
              thresh (average value below/above which pixel is unchanged)
              rval, gval, bval (new color to paint)
      Return: 0 if OK; 1 on error
pixColorGray () Input : pixs ( 8 bpp gray rgb or colormapped image ) box ( <optional > region in which to apply color ; can be NULL ) type ( L_PAINT_LIGHT L_PAINT_DARK ) thresh ( average value below / above which pixel is unchanged ) rval gval bval ( new color to paint ) Return : 0 if OK ; 1 on error
/* rgb or 8 bpp gray image; check the thresh */ /* thresh should be low */ /* type == L_PAINT_DARK; thresh should be high */ /* skip sufficiently dark pixels */ /* type == L_PAINT_DARK */ /* skip sufficiently light pixels */