src/blend.c
l_int32
pixBlendCmap(PIX     *pixs,
             PIX     *pixb,
             l_int32  x,
             l_int32  y,
             l_int32  sindex)
{
l_int32    rval, gval, bval;
l_int32    i, j, w, h, d, ncb, wb, hb, wpls;
l_int32    index, val, nadded;
l_int32    lut[256];
l_uint32   pval;
l_uint32  *lines, *datas;
PIXCMAP   *cmaps, *cmapb, *cmapsc;

    PROCNAME("pixBlendCmap");

    if (!pixs)
        return ERROR_INT("pixs not defined", procName, 1);
    if (!pixb)
        return ERROR_INT("pixb not defined", procName, 1);
    if ((cmaps = pixGetColormap(pixs)) == NULL)
        return ERROR_INT("no colormap in pixs", procName, 1);
    if ((cmapb = pixGetColormap(pixb)) == NULL)
        return ERROR_INT("no colormap in pixb", procName, 1);
    ncb = pixcmapGetCount(cmapb);

        /* Make a copy of cmaps; we'll add to this if necessary
         * and substitute at the end if we found there was enough room
         * to hold all the new colors. */
    cmapsc = pixcmapCopy(cmaps);

    pixGetDimensions(pixs, &w, &h, &d);
    if (d != 2 && d != 4 && d != 8)
        return ERROR_INT("depth not in {2,4,8}", procName, 1);

        /* Add new colors if necessary; get mapping array between
         * cmaps and cmapb. */
    for (i = 0, nadded = 0; i < ncb; i++) {
        pixcmapGetColor(cmapb, i, &rval, &gval, &bval);
        if (pixcmapGetIndex(cmapsc, rval, gval, bval, &index)) { /* not found */
            if (pixcmapAddColor(cmapsc, rval, gval, bval)) {
                pixcmapDestroy(&cmapsc);
                return ERROR_INT("not enough room in cmaps", procName, 1);
            }
            lut[i] = pixcmapGetCount(cmapsc) - 1;
            nadded++;
        }
        else
            lut[i] = index;
    }

        /* Replace cmaps if colors have been added. */
    if (nadded == 0)
        pixcmapDestroy(&cmapsc);
    else
        pixSetColormap(pixs, cmapsc);

        /* Replace each pixel value sindex by mapped colormap index when
         * a blender pixel in pixbc overlays it. */
    datas = pixGetData(pixs);
    wpls = pixGetWpl(pixs);
    pixGetDimensions(pixb, &wb, &hb, NULL);
    for (i = 0; i < hb; i++) {
        if (i + y < 0  || i + y >= h) continue;
        lines = datas + (y + i) * wpls;
        for (j = 0; j < wb; j++) {
            if (j + x < 0  || j + x >= w) continue;
            switch (d) {
            case 2:
                val = GET_DATA_DIBIT(lines, x + j);
                if (val == sindex) {
                    pixGetPixel(pixb, j, i, &pval);
                    SET_DATA_DIBIT(lines, x + j, lut[pval]);
                }
                break;
            case 4:
                val = GET_DATA_QBIT(lines, x + j);
                if (val == sindex) {
                    pixGetPixel(pixb, j, i, &pval);
                    SET_DATA_QBIT(lines, x + j, lut[pval]);
                }
                break;
            case 8:
                val = GET_DATA_BYTE(lines, x + j);
                if (val == sindex) {
                    pixGetPixel(pixb, j, i, &pval);
                    SET_DATA_BYTE(lines, x + j, lut[pval]);
                }
                break;
            default:
                return ERROR_INT("depth not in {2,4,8}", procName, 1);
            }
        }
    }

    return 0;
}
/*!
 *  pixBlendCmap()
 *
 *      Input:  pixs (2, 4 or 8 bpp, with colormap)
 *              pixb (colormapped blender)
 *              x, y (UL corner of blender relative to pixs)
 *              sindex (colormap index of pixels in pixs to be changed)
 *      Return: 0 if OK, 1 on error
 *
 *  Note:
 *      (1) This function combines two colormaps, and replaces the pixels
 *          in pixs that have a specified color value with those in pixb.
 *      (2) sindex must be in the existing colormap; otherwise an
 *          error is returned.  In use, sindex will typically be the index
 *          for white (255, 255, 255).
 *      (3) Blender colors that already exist in the colormap are used;
 *          others are added.  If any blender colors cannot be
 *          stored in the colormap, an error is returned.
 *      (4) In the implementation, a mapping is generated from each
 *          original blender colormap index to the corresponding index
 *          in the expanded colormap for pixs.  Then for each pixel in
 *          pixs with value sindex, and which is covered by a blender pixel,
 *          the new index corresponding to the blender pixel is substituted
 *          for sindex.
 */
pixBlendCmap()
Input:  pixs (2, 4 or 8 bpp, with colormap)
pixb (colormapped blender)
x, y (UL corner of blender relative to pixs)
sindex (colormap index of pixels in pixs to be changed)
Return: 0 if OK, 1 on error

(1) This function combines two colormaps, and replaces the pixels
in pixs that have a specified color value with those in pixb.
(2) sindex must be in the existing colormap; otherwise an
error is returned.  In use, sindex will typically be the index
for white (255, 255, 255).
(3) Blender colors that already exist in the colormap are used;
others are added.  If any blender colors cannot be
stored in the colormap, an error is returned.
(4) In the implementation, a mapping is generated from each
original blender colormap index to the corresponding index
in the expanded colormap for pixs.  Then for each pixel in
pixs with value sindex, and which is covered by a blender pixel,
the new index corresponding to the blender pixel is substituted
for sindex.
pixBlendCmap () Input : pixs ( 2 4 or 8 bpp with colormap ) pixb ( colormapped blender ) x y ( UL corner of blender relative to pixs ) sindex ( colormap index of pixels in pixs to be changed ) Return : 0 if OK 1 on error ( 1 ) This function combines two colormaps and replaces the pixels in pixs that have a specified color value with those in pixb . ( 2 ) sindex must be in the existing colormap ; otherwise an error is returned . In use sindex will typically be the index for white ( 255 255 255 ) . ( 3 ) Blender colors that already exist in the colormap are used ; others are added . If any blender colors cannot be stored in the colormap an error is returned . ( 4 ) In the implementation a mapping is generated from each original blender colormap index to the corresponding index in the expanded colormap for pixs . Then for each pixel in pixs with value sindex and which is covered by a blender pixel the new index corresponding to the blender pixel is substituted for sindex .
l_int32
pixBlendCmap(PIX     *pixs,
             PIX     *pixb,
             l_int32  x,
             l_int32  y,
             l_int32  sindex)
{
l_int32    rval, gval, bval;
l_int32    i, j, w, h, d, ncb, wb, hb, wpls;
l_int32    index, val, nadded;
l_int32    lut[256];
l_uint32   pval;
l_uint32  *lines, *datas;
PIXCMAP   *cmaps, *cmapb, *cmapsc;
    PROCNAME("pixBlendCmap");
    if (!pixs)
        return ERROR_INT("pixs not defined", procName, 1);
    if (!pixb)
        return ERROR_INT("pixb not defined", procName, 1);
    if ((cmaps = pixGetColormap(pixs)) == NULL)
        return ERROR_INT("no colormap in pixs", procName, 1);
    if ((cmapb = pixGetColormap(pixb)) == NULL)
        return ERROR_INT("no colormap in pixb", procName, 1);
    ncb = pixcmapGetCount(cmapb);
    cmapsc = pixcmapCopy(cmaps);
    pixGetDimensions(pixs, &w, &h, &d);
    if (d != 2 && d != 4 && d != 8)
        return ERROR_INT("depth not in {2,4,8}", procName, 1);
    for (i = 0, nadded = 0; i < ncb; i++) {
        pixcmapGetColor(cmapb, i, &rval, &gval, &bval);
        if (pixcmapGetIndex(cmapsc, rval, gval, bval, &index)) { 
            if (pixcmapAddColor(cmapsc, rval, gval, bval)) {
                pixcmapDestroy(&cmapsc);
                return ERROR_INT("not enough room in cmaps", procName, 1);
            }
            lut[i] = pixcmapGetCount(cmapsc) - 1;
            nadded++;
        }
        else
            lut[i] = index;
    }
    if (nadded == 0)
        pixcmapDestroy(&cmapsc);
    else
        pixSetColormap(pixs, cmapsc);
    datas = pixGetData(pixs);
    wpls = pixGetWpl(pixs);
    pixGetDimensions(pixb, &wb, &hb, NULL);
    for (i = 0; i < hb; i++) {
        if (i + y < 0  || i + y >= h) continue;
        lines = datas + (y + i) * wpls;
        for (j = 0; j < wb; j++) {
            if (j + x < 0  || j + x >= w) continue;
            switch (d) {
            case 2:
                val = GET_DATA_DIBIT(lines, x + j);
                if (val == sindex) {
                    pixGetPixel(pixb, j, i, &pval);
                    SET_DATA_DIBIT(lines, x + j, lut[pval]);
                }
                break;
            case 4:
                val = GET_DATA_QBIT(lines, x + j);
                if (val == sindex) {
                    pixGetPixel(pixb, j, i, &pval);
                    SET_DATA_QBIT(lines, x + j, lut[pval]);
                }
                break;
            case 8:
                val = GET_DATA_BYTE(lines, x + j);
                if (val == sindex) {
                    pixGetPixel(pixb, j, i, &pval);
                    SET_DATA_BYTE(lines, x + j, lut[pval]);
                }
                break;
            default:
                return ERROR_INT("depth not in {2,4,8}", procName, 1);
            }
        }
    }
    return 0;
}
l_int32 pixBlendCmap ( PIX * pixs , PIX * pixb , l_int32 x , l_int32 y , l_int32 sindex ) { l_int32 rval , gval , bval ; l_int32 i , j , w , h , d , ncb , wb , hb , wpls ; l_int32 index , val , nadded ; l_int32 lut [ 256 ] ; l_uint32 pval ; l_uint32 * lines , * datas ; PIXCMAP * cmaps , * cmapb , * cmapsc ; PROCNAME ( " " ) ; if ( ! pixs ) return ERROR_INT ( " " , procName , 1 ) ; if ( ! pixb ) return ERROR_INT ( " " , procName , 1 ) ; if ( ( cmaps = pixGetColormap ( pixs ) ) == NULL ) return ERROR_INT ( " " , procName , 1 ) ; if ( ( cmapb = pixGetColormap ( pixb ) ) == NULL ) return ERROR_INT ( " " , procName , 1 ) ; ncb = pixcmapGetCount ( cmapb ) ; cmapsc = pixcmapCopy ( cmaps ) ; pixGetDimensions ( pixs , & w , & h , & d ) ; if ( d != 2 && d != 4 && d != 8 ) return ERROR_INT ( " " , procName , 1 ) ; for ( i = 0 , nadded = 0 ; i < ncb ; i ++ ) { pixcmapGetColor ( cmapb , i , & rval , & gval , & bval ) ; if ( pixcmapGetIndex ( cmapsc , rval , gval , bval , & index ) ) { if ( pixcmapAddColor ( cmapsc , rval , gval , bval ) ) { pixcmapDestroy ( & cmapsc ) ; return ERROR_INT ( " " , procName , 1 ) ; } lut [ i ] = pixcmapGetCount ( cmapsc ) - 1 ; nadded ++ ; } else lut [ i ] = index ; } if ( nadded == 0 ) pixcmapDestroy ( & cmapsc ) ; else pixSetColormap ( pixs , cmapsc ) ; datas = pixGetData ( pixs ) ; wpls = pixGetWpl ( pixs ) ; pixGetDimensions ( pixb , & wb , & hb , NULL ) ; for ( i = 0 ; i < hb ; i ++ ) { if ( i + y < 0 || i + y >= h ) continue ; lines = datas + ( y + i ) * wpls ; for ( j = 0 ; j < wb ; j ++ ) { if ( j + x < 0 || j + x >= w ) continue ; switch ( d ) { case 2 : val = GET_DATA_DIBIT ( lines , x + j ) ; if ( val == sindex ) { pixGetPixel ( pixb , j , i , & pval ) ; SET_DATA_DIBIT ( lines , x + j , lut [ pval ] ) ; } break ; case 4 : val = GET_DATA_QBIT ( lines , x + j ) ; if ( val == sindex ) { pixGetPixel ( pixb , j , i , & pval ) ; SET_DATA_QBIT ( lines , x + j , lut [ pval ] ) ; } break ; case 8 : val = GET_DATA_BYTE ( lines , x + j ) ; if ( val == sindex ) { pixGetPixel ( pixb , j , i , & pval ) ; SET_DATA_BYTE ( lines , x + j , lut [ pval ] ) ; } break ; default : return ERROR_INT ( " " , procName , 1 ) ; } } } return 0 ; }
pixBlendCmap()
      Input:  pixs (2, 4 or 8 bpp, with colormap)
              pixb (colormapped blender)
              x, y (UL corner of blender relative to pixs)
              sindex (colormap index of pixels in pixs to be changed)
      Return: 0 if OK, 1 on error
pixBlendCmap () Input : pixs ( 2 4 or 8 bpp with colormap ) pixb ( colormapped blender ) x y ( UL corner of blender relative to pixs ) sindex ( colormap index of pixels in pixs to be changed ) Return : 0 if OK 1 on error
/* Make a copy of cmaps; we'll add to this if necessary
         * and substitute at the end if we found there was enough room
         * to hold all the new colors. */ /* Add new colors if necessary; get mapping array between
         * cmaps and cmapb. */ /* not found */ /* Replace cmaps if colors have been added. */ /* Replace each pixel value sindex by mapped colormap index when
         * a blender pixel in pixbc overlays it. */