Alien-FreeImage

 view release on metacpan or  search on metacpan

src/Source/FreeImageToolkit/Background.cpp  view on Meta::CPAN

				break;
			}
		}
	} else {
		unsigned minimum = UINT_MAX;
		unsigned ncolors = FreeImage_GetColorsUsed(dib);
		BYTE *palette = (BYTE *)FreeImage_GetPalette(dib);
		BYTE red, green, blue;
		if (!IsVisualGreyscaleImage(dib)) {
			red = color->rgbRed;
			green = color->rgbGreen;
			blue = color->rgbBlue;
		} else {
			red = GREY(color->rgbRed, color->rgbGreen, color->rgbBlue);
			green = blue = red;
		}
		for (unsigned i = 0; i < ncolors; i++) {
			unsigned m = abs(palette[FI_RGBA_BLUE] - blue)
					+ abs(palette[FI_RGBA_GREEN] - green)
					+ abs(palette[FI_RGBA_RED] - red);
			if (m < minimum) {
				minimum = m;
				result = i;
				if (m == 0) {
					break;
				}
			}
			palette += sizeof(RGBQUAD);
		}		
	}
	return result;
}

/** @brief Blends an alpha-transparent foreground color over an opaque background
 color.
 
 This function blends the alpha-transparent foreground color fgcolor over the
 background color bgcolor. The background color is considered fully opaque,
 whatever it's alpha value contains, whereas the foreground color is considered
 to be a real RGBA color with an alpha value, which is used for the blend
 operation. The resulting color is returned through the blended parameter.
 @param bgcolor The background color for the blend operation.
 @param fgcolor The foreground color for the blend operation. This color's alpha
 value, stored in the rgbReserved member, is the alpha value used for the blend
 operation.
 @param blended This out parameter takes the blended color and so, returns it to
 the caller. This color's alpha value will be 0xFF (255) so, the blended color
 itself has no transparency. The this argument is not changed, if the function
 fails. 
 @return Returns TRUE on success, FALSE otherwise. This function fails if any of
 the color arguments is a null pointer.
 */
static BOOL
GetAlphaBlendedColor(const RGBQUAD *bgcolor, const RGBQUAD *fgcolor, RGBQUAD *blended) {
	
	if ((!bgcolor) || (!fgcolor) || (!blended)) {
		return FALSE;
	}
	
	BYTE alpha = fgcolor->rgbReserved;
	BYTE not_alpha = ~alpha;
	
	blended->rgbRed   = (BYTE)( ((WORD)fgcolor->rgbRed   * alpha + not_alpha * (WORD)bgcolor->rgbRed)   >> 8 );
	blended->rgbGreen = (BYTE)( ((WORD)fgcolor->rgbGreen * alpha + not_alpha * (WORD)bgcolor->rgbGreen) >> 8) ;
	blended->rgbBlue  = (BYTE)( ((WORD)fgcolor->rgbRed   * alpha + not_alpha * (WORD)bgcolor->rgbBlue)  >> 8 );
	blended->rgbReserved = 0xFF;

	return TRUE;
}

/** @brief Fills a FIT_BITMAP image with the specified color.

 This function does the dirty work for FreeImage_FillBackground for FIT_BITMAP
 images.
 @param dib The image to be filled.
 @param color The color, the specified image should be filled with.
 @param options Options that affect the color search process for palletized images.
 @return Returns TRUE on success, FALSE otherwise. This function fails if any of
 the dib and color is NULL or the provided image is not a FIT_BITMAP image.
 */
static BOOL
FillBackgroundBitmap(FIBITMAP *dib, const RGBQUAD *color, int options) {

	if ((!dib) || (FreeImage_GetImageType(dib) != FIT_BITMAP)) {
		return FALSE;;
	}
	
	if (!color) {
		return FALSE;
	}
	
	const RGBQUAD *color_intl = color;
	unsigned bpp = FreeImage_GetBPP(dib);
	unsigned width = FreeImage_GetWidth(dib);
	unsigned height = FreeImage_GetHeight(dib);
	
	FREE_IMAGE_COLOR_TYPE color_type = FreeImage_GetColorType(dib);
	
	// get a pointer to the first scanline (bottom line)
	BYTE *src_bits = FreeImage_GetScanLine(dib, 0);
	BYTE *dst_bits = src_bits;	
	
	BOOL supports_alpha = ((bpp >= 24) || ((bpp == 8) && (color_type != FIC_PALETTE)));
	
	// Check for RGBA case if bitmap supports alpha 
	// blending (8-bit greyscale, 24- or 32-bit images)
	if (supports_alpha && (options & FI_COLOR_IS_RGBA_COLOR)) {
		
		if (color->rgbReserved == 0) {
			// the fill color is fully transparent; we are done
			return TRUE;
		}
		
		// Only if the fill color is NOT fully opaque, draw it with
		// the (much) slower FreeImage_DrawLine function and return.
		// Since we do not have the FreeImage_DrawLine function in this
		// release, just assume to have an unicolor background and fill
		// all with an 'alpha-blended' color.
		if (color->rgbReserved < 255) {
							
			// If we will draw on an unicolor background, it's
			// faster to draw opaque with an alpha blended color.
			// So, first get the color from the first pixel in the
			// image (bottom-left pixel).
			RGBQUAD bgcolor;



( run in 1.495 second using v1.01-cache-2.11-cpan-9581c071862 )