void poImage::load(uint w, uint h, uint c, const ubyte *pix) { if(bitmap) { totalAllocatedImageMemorySize -= FreeImage_GetDIBSize(bitmap); FreeImage_Unload(bitmap); } if(pix != NULL) bitmap = FreeImage_ConvertFromRawBits(const_cast<ubyte*>(pix), w, h, w*c, c*8, 0,0,0); else { bitmap = FreeImage_Allocate(w, h, c*8); char black[] = {0,0,0,0}; FreeImage_FillBackground(bitmap, black); } totalAllocatedImageMemorySize += FreeImage_GetDIBSize(bitmap); }
void poImage::fill(poColor c) { unsigned char color[4] = {c.R*255, c.G*255, c.B*255, c.A*255}; FreeImage_FillBackground(bitmap, color); }
void poImage::clear() { ubyte color[] = {0,0,0,0}; FreeImage_FillBackground(bitmap, &color[0]); }
/** @brief Allocates a new image of the specified type, width, height and bit depth and optionally fills it with the specified color. This function is an extension to FreeImage_AllocateT, which additionally supports specifying a palette to be set for the newly create image, as well as specifying a background color, the newly created image should initially be filled with. Basically, this function internally relies on function FreeImage_AllocateT, followed by a call to FreeImage_FillBackground. This is why both parameters color and options behave the same as it is documented for function FreeImage_FillBackground. So, please refer to the documentation of FreeImage_FillBackground to learn more about parameters color and options. The palette specified through parameter palette is only copied to the newly created image, if its image type is FIT_BITMAP and the desired bit depth is smaller than or equal to 8 bits per pixel. In other words, the palette parameter is only taken into account for palletized images. However, if the preceding conditions match and if palette is not NULL, the memory pointed to by the palette pointer is assumed to be at least as large as size of a fully populated palette for the desired bit depth. So, for an 8-bit image, this size is 256 x sizeof(RGBQUAD), for an 4-bit image it is 16 x sizeof(RGBQUAD) and it is 2 x sizeof(RGBQUAD) for a 1-bit image. In other words, this function does not support partial palettes. However, specifying a palette is not necessarily needed, even for palletized images. This function is capable of implicitly creating a palette, if parameter palette is NULL. If the specified background color is a greyscale value (red = green = blue) or if option FI_COLOR_ALPHA_IS_INDEX is specified, a greyscale palette is created. For a 1-bit image, only if the specified background color is either black or white, a monochrome palette, consisting of black and white only is created. In any case, the darker colors are stored at the smaller palette indices. If the specified background color is not a greyscale value, or is neither black nor white for a 1-bit image, solely this single color is injected into the otherwise black-initialized palette. For this operation, option FI_COLOR_ALPHA_IS_INDEX is implicit, so the specified color is applied to the palette entry, specified by the background color's rgbReserved member. The image is then filled with this palette index. This function returns a newly created image as function FreeImage_AllocateT does, if both parameters color and palette are NULL. If only color is NULL, the palette pointed to by parameter palette is initially set for the new image, if a palletized image of type FIT_BITMAP is created. However, in the latter case, this function returns an image, whose pixels are all initialized with zeros so, the image will be filled with the color of the first palette entry. @param type Specifies the image type of the new image. @param width The desired width in pixels of the new image. @param height The desired height in pixels of the new image. @param bpp The desired bit depth of the new image. @param color A pointer to the color value to be used for filling the image. The memory pointed to by this pointer is always assumed to be at least as large as the image's color value but never smaller than the size of an RGBQUAD structure. @param options Options that affect the color search process for palletized images. @param red_mask Specifies the bits used to store the red components of a pixel. @param green_mask Specifies the bits used to store the green components of a pixel. @param blue_mask Specifies the bits used to store the blue components of a pixel. @return Returns a pointer to a newly allocated image on success, NULL otherwise. */ FIBITMAP * DLL_CALLCONV FreeImage_AllocateExT(FREE_IMAGE_TYPE type, int width, int height, int bpp, const void *color, int options, const RGBQUAD *palette, unsigned red_mask, unsigned green_mask, unsigned blue_mask) { FIBITMAP *bitmap = FreeImage_AllocateT(type, width, height, bpp, red_mask, green_mask, blue_mask); if (!color) { if ((palette) && (type == FIT_BITMAP) && (bpp <= 8)) { memcpy(FreeImage_GetPalette(bitmap), palette, FreeImage_GetColorsUsed(bitmap) * sizeof(RGBQUAD)); } return bitmap; } if (bitmap != NULL) { // Only fill the new bitmap if the specified color // differs from "black", that is not all bytes of the // color are equal to zero. switch (bpp) { case 1: { // although 1-bit implies FIT_BITMAP, better get an unsigned // color and palette unsigned *urgb = (unsigned *)color; unsigned *upal = (unsigned *)FreeImage_GetPalette(bitmap); RGBQUAD rgbq = RGBQUAD(); if (palette != NULL) { // clone the specified palette memcpy(FreeImage_GetPalette(bitmap), palette, 2 * sizeof(RGBQUAD)); } else if (options & FI_COLOR_ALPHA_IS_INDEX) { CREATE_GREYSCALE_PALETTE(upal, 2); } else { // check, whether the specified color is either black or white if ((*urgb & 0xFFFFFF) == 0x000000) { // in any case build a FIC_MINISBLACK palette CREATE_GREYSCALE_PALETTE(upal, 2); color = &rgbq; } else if ((*urgb & 0xFFFFFF) == 0xFFFFFF) { // in any case build a FIC_MINISBLACK palette CREATE_GREYSCALE_PALETTE(upal, 2); rgbq.rgbReserved = 1; color = &rgbq; } else { // Otherwise inject the specified color into the so far // black-only palette. We use color->rgbReserved as the // desired palette index. BYTE index = ((RGBQUAD *)color)->rgbReserved & 0x01; upal[index] = *urgb & 0x00FFFFFF; } options |= FI_COLOR_ALPHA_IS_INDEX; } // and defer to FreeImage_FillBackground FreeImage_FillBackground(bitmap, color, options); break; } case 4: { // 4-bit implies FIT_BITMAP so, get a RGBQUAD color RGBQUAD *rgb = (RGBQUAD *)color; RGBQUAD *pal = FreeImage_GetPalette(bitmap); RGBQUAD rgbq = RGBQUAD(); if (palette != NULL) { // clone the specified palette memcpy(pal, palette, 16 * sizeof(RGBQUAD)); } else if (options & FI_COLOR_ALPHA_IS_INDEX) { CREATE_GREYSCALE_PALETTE(pal, 16); } else { // check, whether the specified color is a grey one if ((rgb->rgbRed == rgb->rgbGreen) && (rgb->rgbRed == rgb->rgbBlue)) { // if so, build a greyscale palette CREATE_GREYSCALE_PALETTE(pal, 16); rgbq.rgbReserved = rgb->rgbRed >> 4; color = &rgbq; } else { // Otherwise inject the specified color into the so far // black-only palette. We use color->rgbReserved as the // desired palette index. BYTE index = (rgb->rgbReserved & 0x0F); ((unsigned *)pal)[index] = *((unsigned *)rgb) & 0x00FFFFFF; } options |= FI_COLOR_ALPHA_IS_INDEX; } // and defer to FreeImage_FillBackground FreeImage_FillBackground(bitmap, color, options); break; } case 8: { // 8-bit implies FIT_BITMAP so, get a RGBQUAD color RGBQUAD *rgb = (RGBQUAD *)color; RGBQUAD *pal = FreeImage_GetPalette(bitmap); RGBQUAD rgbq; if (palette != NULL) { // clone the specified palette memcpy(pal, palette, 256 * sizeof(RGBQUAD)); } else if (options & FI_COLOR_ALPHA_IS_INDEX) { CREATE_GREYSCALE_PALETTE(pal, 256); } else { // check, whether the specified color is a grey one if ((rgb->rgbRed == rgb->rgbGreen) && (rgb->rgbRed == rgb->rgbBlue)) { // if so, build a greyscale palette CREATE_GREYSCALE_PALETTE(pal, 256); rgbq.rgbReserved = rgb->rgbRed; color = &rgbq; } else { // Otherwise inject the specified color into the so far // black-only palette. We use color->rgbReserved as the // desired palette index. BYTE index = rgb->rgbReserved; ((unsigned *)pal)[index] = *((unsigned *)rgb) & 0x00FFFFFF; } options |= FI_COLOR_ALPHA_IS_INDEX; } // and defer to FreeImage_FillBackground FreeImage_FillBackground(bitmap, color, options); break; } case 16: { WORD wcolor = (type == FIT_BITMAP) ? RGBQUAD_TO_WORD(bitmap, ((RGBQUAD *)color)) : *((WORD *)color); if (wcolor != 0) { FreeImage_FillBackground(bitmap, color, options); } break; } default: { int bytespp = bpp / 8; for (int i = 0; i < bytespp; i++) { if (((BYTE *)color)[i] != 0) { FreeImage_FillBackground(bitmap, color, options); break; } } break; } }