Alien-FreeImage

 view release on metacpan or  search on metacpan

src/Source/FreeImage/BitmapAccess.cpp  view on Meta::CPAN

//
// Use at your own risk!
// ==========================================================

#ifdef _MSC_VER 
#pragma warning (disable : 4786) // identifier was truncated to 'number' characters
#endif 

#include <stdlib.h>
#if defined(_WIN32) || defined(_WIN64) || defined(__MINGW32__)
#include <malloc.h>
#endif // _WIN32 || _WIN64 || __MINGW32__

#include "FreeImage.h"
#include "FreeImageIO.h"
#include "Utilities.h"
#include "MapIntrospector.h"

#include "../Metadata/FreeImageTag.h"

/**
Constants for the BITMAPINFOHEADER::biCompression field
BI_RGB:
The bitmap is in uncompressed red green blue (RGB) format that is not compressed and does not use color masks.
BI_BITFIELDS:
The bitmap is not compressed and the color table consists of three DWORD color masks that specify the red, green, and blue components, 
respectively, of each pixel. This is valid when used with 16 and 32-bits per pixel bitmaps.
*/
#ifndef _WINGDI_
#define BI_RGB       0L
#define BI_BITFIELDS 3L
#endif // _WINGDI_

// ----------------------------------------------------------
//  Metadata definitions
// ----------------------------------------------------------

/** helper for map<key, value> where value is a pointer to a FreeImage tag */
typedef std::map<std::string, FITAG*> TAGMAP;

/** helper for map<FREE_IMAGE_MDMODEL, TAGMAP*> */
typedef std::map<int, TAGMAP*> METADATAMAP;

/** helper for metadata iterator */
FI_STRUCT (METADATAHEADER) { 
	long pos;		//! current position when iterating the map
	TAGMAP *tagmap;	//! pointer to the tag map
};

// ----------------------------------------------------------
//  FIBITMAP definition
// ----------------------------------------------------------

/**
FreeImage header structure
*/
FI_STRUCT (FREEIMAGEHEADER) {
	/** data type - bitmap, array of long, double, complex, etc */
	FREE_IMAGE_TYPE type;

	/** background color used for RGB transparency */
	RGBQUAD bkgnd_color;

	/**@name transparency management */
	//@{
	/**
	why another table ? for easy transparency table retrieval !
	transparency could be stored in the palette, which is better
	overall, but it requires quite some changes and it will render
	FreeImage_GetTransparencyTable obsolete in its current form;
	*/
	BYTE transparent_table[256];
	/** number of transparent colors */
	int  transparency_count;
	/** TRUE if the image is transparent */
	BOOL transparent;
	//@}

	/** space to hold ICC profile */
	FIICCPROFILE iccProfile;

	/** contains a list of metadata models attached to the bitmap */
	METADATAMAP *metadata;

	/** FALSE if the FIBITMAP only contains the header and no pixel data */
	BOOL has_pixels;

	/** optionally contains a thumbnail attached to the bitmap */
	FIBITMAP *thumbnail;

	/**@name external pixel buffer management */
	//@{
	/** pointer to user provided pixels, NULL otherwise */
	BYTE *external_bits;
	/** user provided pitch, 0 otherwise */
	unsigned external_pitch;
	//@}

	//BYTE filler[1];			 // fill to 32-bit alignment
};

// ----------------------------------------------------------
//  FREEIMAGERGBMASKS definition
// ----------------------------------------------------------

/**
RGB mask structure - mainly used for 16-bit RGB555 / RGB 565 FIBITMAP
*/
FI_STRUCT (FREEIMAGERGBMASKS) {
	unsigned red_mask;		//! bit layout of the red components
	unsigned green_mask;	//! bit layout of the green components
	unsigned blue_mask;		//! bit layout of the blue components
};

// ----------------------------------------------------------
//  Memory allocation on a specified alignment boundary
// ----------------------------------------------------------

#if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__)

void* FreeImage_Aligned_Malloc(size_t amount, size_t alignment) {

src/Source/FreeImage/BitmapAccess.cpp  view on Meta::CPAN

			// check for 16-bit RGB (565 or 555)
			masks = FreeImage_GetRGBMasks(dib);
			if (masks) {
				return masks->red_mask;
			}
			return FreeImage_GetBPP(dib) >= 24 ? FI_RGBA_RED_MASK : 0;
		default:
			return 0;
	}
}

unsigned DLL_CALLCONV
FreeImage_GetGreenMask(FIBITMAP *dib) {
	FREEIMAGERGBMASKS *masks = NULL;
	FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(dib);
	switch(image_type) {
		case FIT_BITMAP:
			// check for 16-bit RGB (565 or 555)
			masks = FreeImage_GetRGBMasks(dib);
			if (masks) {
				return masks->green_mask;
			}
			return FreeImage_GetBPP(dib) >= 24 ? FI_RGBA_GREEN_MASK : 0;
		default:
			return 0;
	}
}

unsigned DLL_CALLCONV
FreeImage_GetBlueMask(FIBITMAP *dib) {
	FREEIMAGERGBMASKS *masks = NULL;
	FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(dib);
	switch(image_type) {
		case FIT_BITMAP:
			// check for 16-bit RGB (565 or 555)
			masks = FreeImage_GetRGBMasks(dib);
			if (masks) {
				return masks->blue_mask;
			}
			return FreeImage_GetBPP(dib) >= 24 ? FI_RGBA_BLUE_MASK : 0;
		default:
			return 0;
	}
}

// ----------------------------------------------------------

BOOL DLL_CALLCONV
FreeImage_HasBackgroundColor(FIBITMAP *dib) {
	if(dib) {
		RGBQUAD *bkgnd_color = &((FREEIMAGEHEADER *)dib->data)->bkgnd_color;
		return (bkgnd_color->rgbReserved != 0) ? TRUE : FALSE;
	}
	return FALSE;
}

BOOL DLL_CALLCONV
FreeImage_GetBackgroundColor(FIBITMAP *dib, RGBQUAD *bkcolor) {
	if(dib && bkcolor) {
		if(FreeImage_HasBackgroundColor(dib)) {
			// get the background color
			RGBQUAD *bkgnd_color = &((FREEIMAGEHEADER *)dib->data)->bkgnd_color;
			memcpy(bkcolor, bkgnd_color, sizeof(RGBQUAD));
			// get the background index
			if(FreeImage_GetBPP(dib) == 8) {
				RGBQUAD *pal = FreeImage_GetPalette(dib);
				for(unsigned i = 0; i < FreeImage_GetColorsUsed(dib); i++) {
					if(bkgnd_color->rgbRed == pal[i].rgbRed) {
						if(bkgnd_color->rgbGreen == pal[i].rgbGreen) {
							if(bkgnd_color->rgbBlue == pal[i].rgbBlue) {
								bkcolor->rgbReserved = (BYTE)i;
								return TRUE;
							}
						}
					}
				}
			}

			bkcolor->rgbReserved = 0;

			return TRUE;
		}
	}

	return FALSE;
}

BOOL DLL_CALLCONV 
FreeImage_SetBackgroundColor(FIBITMAP *dib, RGBQUAD *bkcolor) {
	if(dib) {
		RGBQUAD *bkgnd_color = &((FREEIMAGEHEADER *)dib->data)->bkgnd_color;
		if(bkcolor) {
			// set the background color
			memcpy(bkgnd_color, bkcolor, sizeof(RGBQUAD));
			// enable the file background color
			bkgnd_color->rgbReserved = 1;
		} else {
			// clear and disable the file background color
			memset(bkgnd_color, 0, sizeof(RGBQUAD));
		}
		return TRUE;
	}

	return FALSE;
}

// ----------------------------------------------------------

BOOL DLL_CALLCONV
FreeImage_IsTransparent(FIBITMAP *dib) {
	if(dib) {
		FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(dib);
		switch(image_type) {
			case FIT_BITMAP:
				if(FreeImage_GetBPP(dib) == 32) {
					if(FreeImage_GetColorType(dib) == FIC_RGBALPHA) {
						return TRUE;
					}
				} else {
					return ((FREEIMAGEHEADER *)dib->data)->transparent ? TRUE : FALSE;
				}
				break;
			case FIT_RGBA16:
			case FIT_RGBAF:
				return TRUE;
			default:
				break;
		}
	}
	return FALSE;
}

BYTE * DLL_CALLCONV
FreeImage_GetTransparencyTable(FIBITMAP *dib) {
	return dib ? ((FREEIMAGEHEADER *)dib->data)->transparent_table : NULL;
}

void DLL_CALLCONV
FreeImage_SetTransparent(FIBITMAP *dib, BOOL enabled) {
	if (dib) {
		if ((FreeImage_GetBPP(dib) <= 8) || (FreeImage_GetBPP(dib) == 32)) {
			((FREEIMAGEHEADER *)dib->data)->transparent = enabled;
		} else {
			((FREEIMAGEHEADER *)dib->data)->transparent = FALSE;
		}
	}
}

unsigned DLL_CALLCONV
FreeImage_GetTransparencyCount(FIBITMAP *dib) {
	return dib ? ((FREEIMAGEHEADER *)dib->data)->transparency_count : 0;
}

void DLL_CALLCONV
FreeImage_SetTransparencyTable(FIBITMAP *dib, BYTE *table, int count) {
	if (dib) {
		count = MAX(0, MIN(count, 256));
		if (FreeImage_GetBPP(dib) <= 8) {



( run in 0.835 second using v1.01-cache-2.11-cpan-0d23b851a93 )