コード例 #1
0
static void splitRGBAtoBitBlt(FIBITMAP * &image, FIBITMAP *&mask)
{
    unsigned int img_w   = FreeImage_GetWidth(image);
    unsigned int img_h   = FreeImage_GetHeight(image);

    mask = FreeImage_AllocateT(FIT_BITMAP,
                               img_w, img_h,
                               FreeImage_GetBPP(image),
                               FreeImage_GetRedMask(image),
                               FreeImage_GetGreenMask(image),
                               FreeImage_GetBlueMask(image));

    RGBQUAD Fpix;
    RGBQUAD Npix = {0x0, 0x0, 0x0, 0xFF};

    for(unsigned int y = 0; (y < img_h); y++)
    {
        for(unsigned int x = 0; (x < img_w); x++)
        {
            FreeImage_GetPixelColor(image, x, y, &Fpix);

            uint8_t grey = (255 - Fpix.rgbReserved);
            Npix.rgbRed  = grey;
            Npix.rgbGreen= grey;
            Npix.rgbBlue = grey;
            Npix.rgbReserved = 255;

            Fpix.rgbRed  = subtractAlpha(Fpix.rgbRed, grey);
            Fpix.rgbGreen= subtractAlpha(Fpix.rgbGreen, grey);
            Fpix.rgbBlue = subtractAlpha(Fpix.rgbBlue, grey);
            Fpix.rgbReserved = 255;

            FreeImage_SetPixelColor(image, x, y, &Fpix);
            FreeImage_SetPixelColor(mask,  x, y, &Npix);
        }
    }
}
コード例 #2
0
ファイル: PluginBMP.cpp プロジェクト: MichaelH13/sdkpub
static BOOL DLL_CALLCONV
Save(FreeImageIO *io, FIBITMAP *dib, fi_handle handle, int page, int flags, void *data) {
	if ((dib != NULL) && (handle != NULL)) {
		// write the file header

		BITMAPFILEHEADER bitmapfileheader;
		bitmapfileheader.bfType = 0x4D42;
		bitmapfileheader.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + FreeImage_GetHeight(dib) * FreeImage_GetPitch(dib);
		bitmapfileheader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + FreeImage_GetColorsUsed(dib) * sizeof(RGBQUAD);
		bitmapfileheader.bfReserved1 = 0;
		bitmapfileheader.bfReserved2 = 0;

		// take care of the bit fields data of any

		bool bit_fields = (FreeImage_GetBPP(dib) == 16);

		if (bit_fields) {
			bitmapfileheader.bfSize += 3 * sizeof(DWORD);
			bitmapfileheader.bfOffBits += 3 * sizeof(DWORD);
		}

#ifdef FREEIMAGE_BIGENDIAN
		SwapFileHeader(&bitmapfileheader);
#endif
		if (io->write_proc(&bitmapfileheader, sizeof(BITMAPFILEHEADER), 1, handle) != 1)
			return FALSE;		

		// update the bitmap info header

		BITMAPINFOHEADER bih = *FreeImage_GetInfoHeader(dib);

		if (bit_fields)
			bih.biCompression = BI_BITFIELDS;
		else if ((bih.biBitCount == 8) && (flags & BMP_SAVE_RLE))
			bih.biCompression = BI_RLE8;
		else
			bih.biCompression = BI_RGB;

		// write the bitmap info header

#ifdef FREEIMAGE_BIGENDIAN
		SwapInfoHeader(&bih);
#endif
		if (io->write_proc(&bih, sizeof(BITMAPINFOHEADER), 1, handle) != 1)
			return FALSE;

		// write the bit fields when we are dealing with a 16 bit BMP

		if (bit_fields) {
			DWORD d;

			d = FreeImage_GetRedMask(dib);

			if (io->write_proc(&d, sizeof(DWORD), 1, handle) != 1)
				return FALSE;

			d = FreeImage_GetGreenMask(dib);

			if (io->write_proc(&d, sizeof(DWORD), 1, handle) != 1)
				return FALSE;

			d = FreeImage_GetBlueMask(dib);

			if (io->write_proc(&d, sizeof(DWORD), 1, handle) != 1)
				return FALSE;
		}

		// write the palette

		if (FreeImage_GetPalette(dib) != NULL) {
			RGBQUAD *pal = FreeImage_GetPalette(dib);
			FILE_BGRA bgra;
			for(unsigned i = 0; i < FreeImage_GetColorsUsed(dib); i++ ) {
				bgra.b = pal[i].rgbBlue;
				bgra.g = pal[i].rgbGreen;
				bgra.r = pal[i].rgbRed;
				bgra.a = pal[i].rgbReserved;
				if (io->write_proc(&bgra, sizeof(FILE_BGRA), 1, handle) != 1)
					return FALSE;
			}
		}

		// write the bitmap data... if RLE compression is enable, use it

		unsigned bpp = FreeImage_GetBPP(dib);
		if ((bpp == 8) && (flags & BMP_SAVE_RLE)) {
			BYTE *buffer = new BYTE[FreeImage_GetPitch(dib) * 2];

			for (DWORD i = 0; i < FreeImage_GetHeight(dib); ++i) {
				int size = RLEEncodeLine(buffer, FreeImage_GetScanLine(dib, i), FreeImage_GetLine(dib));

				if (io->write_proc(buffer, size, 1, handle) != 1) {
					delete [] buffer;
					return FALSE;
				}
			}

			buffer[0] = RLE_COMMAND;
			buffer[1] = RLE_ENDOFBITMAP;

			if (io->write_proc(buffer, 2, 1, handle) != 1) {
				delete [] buffer;
				return FALSE;
			}

			delete [] buffer;
#ifdef FREEIMAGE_BIGENDIAN
		} else if (bpp == 16) {
			WORD pixel;
			for(int y = 0; y < FreeImage_GetHeight(dib); y++) {
				BYTE *line = FreeImage_GetScanLine(dib, y);
				for(int x = 0; x < FreeImage_GetWidth(dib); x++) {
					pixel = ((WORD *)line)[x];
					SwapShort(&pixel);
					if (io->write_proc(&pixel, sizeof(WORD), 1, handle) != 1)
						return FALSE;
				}
			}
		} else if (bpp == 24) {
			FILE_BGR bgr;
			for(int y = 0; y < FreeImage_GetHeight(dib); y++) {
				BYTE *line = FreeImage_GetScanLine(dib, y);
				for(int x = 0; x < FreeImage_GetWidth(dib); x++) {
					RGBTRIPLE *triple = ((RGBTRIPLE *)line)+x;
					bgr.b = triple->rgbtBlue;
					bgr.g = triple->rgbtGreen;
					bgr.r = triple->rgbtRed;
					if (io->write_proc(&bgr, sizeof(FILE_BGR), 1, handle) != 1)
						return FALSE;
				}
			}
		} else if (bpp == 32) {
			FILE_BGRA bgra;
			for(int y = 0; y < FreeImage_GetHeight(dib); y++) {
				BYTE *line = FreeImage_GetScanLine(dib, y);
				for(int x = 0; x < FreeImage_GetWidth(dib); x++) {
					RGBQUAD *quad = ((RGBQUAD *)line)+x;
					bgra.b = quad->rgbBlue;
					bgra.g = quad->rgbGreen;
					bgra.r = quad->rgbRed;
					bgra.a = quad->rgbReserved;
					if (io->write_proc(&bgra, sizeof(FILE_BGRA), 1, handle) != 1)
						return FALSE;
				}
			}
#endif
		} else if (io->write_proc(FreeImage_GetBits(dib), FreeImage_GetHeight(dib) * FreeImage_GetPitch(dib), 1, handle) != 1) {
			return FALSE;
		}

		return TRUE;
	} else {
		return FALSE;
	}
}
コード例 #3
0
FIBITMAP * DLL_CALLCONV
FreeImage_Clone(FIBITMAP *dib) {
	if(!dib) return NULL;

	unsigned width  = FreeImage_GetWidth(dib);
	unsigned height = FreeImage_GetHeight(dib);
	unsigned bpp    = FreeImage_GetBPP(dib);
	
	// allocate a new dib
	FIBITMAP *new_dib = FreeImage_AllocateT(FreeImage_GetImageType(dib), width, height, bpp, 
			FreeImage_GetRedMask(dib), FreeImage_GetGreenMask(dib), FreeImage_GetBlueMask(dib));

	if (new_dib) {
		// save ICC profile links
		FIICCPROFILE *src_iccProfile = FreeImage_GetICCProfile(dib);
		FIICCPROFILE *dst_iccProfile = FreeImage_GetICCProfile(new_dib);

		// save metadata links
		METADATAMAP *src_metadata = ((FREEIMAGEHEADER *)dib->data)->metadata;
		METADATAMAP *dst_metadata = ((FREEIMAGEHEADER *)new_dib->data)->metadata;

		// calculate the size of a FreeImage image
		// align the palette and the pixels on a FIBITMAP_ALIGNMENT bytes alignment boundary
		// palette is aligned on a 16 bytes boundary
		// pixels are aligned on a 16 bytes boundary

		unsigned dib_size = FreeImage_GetImageSize(width, height, bpp); 

		// copy the bitmap + internal pointers (remember to restore new_dib internal pointers later)
		memcpy(new_dib->data, dib->data, dib_size);

		// reset ICC profile link for new_dib
		memset(dst_iccProfile, 0, sizeof(FIICCPROFILE));

		// restore metadata link for new_dib
		((FREEIMAGEHEADER *)new_dib->data)->metadata = dst_metadata;

		// copy possible ICC profile
		FreeImage_CreateICCProfile(new_dib, src_iccProfile->data, src_iccProfile->size);
		dst_iccProfile->flags = src_iccProfile->flags;

		// copy metadata models
		for(METADATAMAP::iterator i = (*src_metadata).begin(); i != (*src_metadata).end(); i++) {
			int model = (*i).first;
			TAGMAP *src_tagmap = (*i).second;

			if(src_tagmap) {
				// create a metadata model
				TAGMAP *dst_tagmap = new TAGMAP();

				// fill the model
				for(TAGMAP::iterator j = src_tagmap->begin(); j != src_tagmap->end(); j++) {
					std::string dst_key = (*j).first;
					FITAG *dst_tag = FreeImage_CloneTag( (*j).second );

					// assign key and tag value
					(*dst_tagmap)[dst_key] = dst_tag;
				}

				// assign model and tagmap
				(*dst_metadata)[model] = dst_tagmap;
			}
		}

		return new_dib;
	}

	return NULL;
}
コード例 #4
0
    //---------------------------------------------------------------------
    Codec::DecodeResult FreeImageCodec::decode(DataStreamPtr& input) const
    {
		// Set error handler
		FreeImage_SetOutputMessage(FreeImageLoadErrorHandler);

		// Buffer stream into memory (TODO: override IO functions instead?)
		MemoryDataStream memStream(input, true);

		FIMEMORY* fiMem = 
			FreeImage_OpenMemory(memStream.getPtr(), static_cast<DWORD>(memStream.size()));

		FIBITMAP* fiBitmap = FreeImage_LoadFromMemory(
			(FREE_IMAGE_FORMAT)mFreeImageType, fiMem);
		if (!fiBitmap)
		{
			OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, 
				"Error decoding image", 
				"FreeImageCodec::decode");
		}


		ImageData* imgData = OGRE_NEW ImageData();
		MemoryDataStreamPtr output;

		imgData->depth = 1; // only 2D formats handled by this codec
		imgData->width = FreeImage_GetWidth(fiBitmap);
		imgData->height = FreeImage_GetHeight(fiBitmap);
        imgData->num_mipmaps = 0; // no mipmaps in non-DDS 
        imgData->flags = 0;

		// Must derive format first, this may perform conversions
		
		FREE_IMAGE_TYPE imageType = FreeImage_GetImageType(fiBitmap);
		FREE_IMAGE_COLOR_TYPE colourType = FreeImage_GetColorType(fiBitmap);
		unsigned bpp = FreeImage_GetBPP(fiBitmap);

		switch(imageType)
		{
		case FIT_UNKNOWN:
		case FIT_COMPLEX:
		case FIT_UINT32:
		case FIT_INT32:
		case FIT_DOUBLE:
        default:
			OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, 
				"Unknown or unsupported image format", 
				"FreeImageCodec::decode");
				
			break;
		case FIT_BITMAP:
			// Standard image type
			// Perform any colour conversions for greyscale
			if (colourType == FIC_MINISWHITE || colourType == FIC_MINISBLACK)
			{
				FIBITMAP* newBitmap = FreeImage_ConvertToGreyscale(fiBitmap);
				// free old bitmap and replace
				FreeImage_Unload(fiBitmap);
				fiBitmap = newBitmap;
				// get new formats
				bpp = FreeImage_GetBPP(fiBitmap);
				colourType = FreeImage_GetColorType(fiBitmap);
			}
			// Perform any colour conversions for RGB
			else if (bpp < 8 || colourType == FIC_PALETTE || colourType == FIC_CMYK)
			{
				FIBITMAP* newBitmap =  NULL;	
				if (FreeImage_IsTransparent(fiBitmap))
				{
					// convert to 32 bit to preserve the transparency 
					// (the alpha byte will be 0 if pixel is transparent)
					newBitmap = FreeImage_ConvertTo32Bits(fiBitmap);
				}
				else
				{
					// no transparency - only 3 bytes are needed
					newBitmap = FreeImage_ConvertTo24Bits(fiBitmap);
				}

				// free old bitmap and replace
				FreeImage_Unload(fiBitmap);
				fiBitmap = newBitmap;
				// get new formats
				bpp = FreeImage_GetBPP(fiBitmap);
				colourType = FreeImage_GetColorType(fiBitmap);
			}

			// by this stage, 8-bit is greyscale, 16/24/32 bit are RGB[A]
			switch(bpp)
			{
			case 8:
				imgData->format = PF_L8;
				break;
			case 16:
				// Determine 555 or 565 from green mask
				// cannot be 16-bit greyscale since that's FIT_UINT16
				if(FreeImage_GetGreenMask(fiBitmap) == FI16_565_GREEN_MASK)
				{
					imgData->format = PF_R5G6B5;
				}
				else
				{
					// FreeImage doesn't support 4444 format so must be 1555
					imgData->format = PF_A1R5G5B5;
				}
				break;
			case 24:
				// FreeImage differs per platform
				//     PF_BYTE_BGR[A] for little endian (== PF_ARGB native)
				//     PF_BYTE_RGB[A] for big endian (== PF_RGBA native)
#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_RGB
				imgData->format = PF_BYTE_RGB;
#else
				imgData->format = PF_BYTE_BGR;
#endif
				break;
			case 32:
#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_RGB
				imgData->format = PF_BYTE_RGBA;
#else
				imgData->format = PF_BYTE_BGRA;
#endif
				break;
				
				
			};
			break;
		case FIT_UINT16:
		case FIT_INT16:
			// 16-bit greyscale
			imgData->format = PF_L16;
			break;
		case FIT_FLOAT:
			// Single-component floating point data
			imgData->format = PF_FLOAT32_R;
			break;
		case FIT_RGB16:
			imgData->format = PF_SHORT_RGB;
			break;
		case FIT_RGBA16:
			imgData->format = PF_SHORT_RGBA;
			break;
		case FIT_RGBF:
			imgData->format = PF_FLOAT32_RGB;
			break;
		case FIT_RGBAF:
			imgData->format = PF_FLOAT32_RGBA;
			break;
			
			
		};

		unsigned char* srcData = FreeImage_GetBits(fiBitmap);
		unsigned srcPitch = FreeImage_GetPitch(fiBitmap);

		// Final data - invert image and trim pitch at the same time
		size_t dstPitch = imgData->width * PixelUtil::getNumElemBytes(imgData->format);
		imgData->size = dstPitch * imgData->height;
        // Bind output buffer
        output.bind(OGRE_NEW MemoryDataStream(imgData->size));

		uchar* pSrc;
		uchar* pDst = output->getPtr();
		for (size_t y = 0; y < imgData->height; ++y)
		{
			pSrc = srcData + (imgData->height - y - 1) * srcPitch;
			memcpy(pDst, pSrc, dstPitch);
			pDst += dstPitch;
		}

		
		FreeImage_Unload(fiBitmap);
		FreeImage_CloseMemory(fiMem);


        DecodeResult ret;
        ret.first = output;
        ret.second = CodecDataPtr(imgData);
		return ret;

    }
コード例 #5
0
/*
==================
Return OpenGL format and type depending on IndieLib defined quality and type
This methot converts source image as needed
==================
*/
void OpenGLTextureBuilder::getGLFormat(IND_Surface *pNewSurface, IND_Image* pImage,GLint *pGLInternalFormat, GLint *pGLFormat, GLint *pGLType) {
    
    assert(pNewSurface);
    assert(pImage);
    assert(pGLFormat);
    assert(pGLType);

    if (!pGLFormat || !pGLType || !pNewSurface || !pImage)
        return;

    //TODO: Review image loading to support luminance+alpha. Now only supports Luminance without alpha
	int colorFormat = pImage->getFormatInt();
	int bpp = pImage->getBpp();
	//Check image color format
	switch (colorFormat) {
		case IND_LUMINANCE:
			//TODO: Other bpp
			*pGLInternalFormat = GL_LUMINANCE;
			*pGLFormat = GL_LUMINANCE;
			if (8 == bpp) {
				//No alpha channel by default
            pNewSurface->_surface->_attributes._type = IND_OPAQUE;
				//GL type
				*pGLType = GL_UNSIGNED_BYTE;
			} else if (16 == bpp) {
				//No alpha channel by default
				pNewSurface->_surface->_attributes._type = IND_OPAQUE;
            //GL types
				*pGLType = GL_UNSIGNED_SHORT_5_6_5;
			} else {
				*pGLInternalFormat = GL_NONE;
				*pGLFormat = GL_NONE;
				*pGLType = GL_NONE;
				g_debug->header("Not supported format of image! texture not loaded" , DebugApi::LogHeaderWarning);
                }

			break;
		case (IND_RGB):
				*pGLInternalFormat = GL_RGB;

			if (16 == bpp) {
				FIBITMAP* fib = pImage->getFreeImageHandle();
                *pGLFormat = GL_RGB;
				//Check if 565 RGB
				if ((FreeImage_GetRedMask(fib) == FI16_565_RED_MASK) 
					&& (FreeImage_GetGreenMask(fib) == FI16_565_GREEN_MASK) 
					&& (FreeImage_GetBlueMask(fib) == FI16_565_BLUE_MASK)) {
                *pGLType = GL_UNSIGNED_SHORT_5_6_5;
				} else {
					*pGLInternalFormat = GL_NONE;
					*pGLFormat = GL_NONE;
					*pGLType = GL_NONE;
					g_debug->header("Not supported format of image! texture not loaded" , DebugApi::LogHeaderWarning);
            }
			} else if (32 == bpp) {
				//FreeImage loads channel order differently depending on processor endianess (24 and 32 bits).
#if FI_RGBA_BLUE > FI_RGBA_RED
                *pGLFormat = GL_RGB;  //Generally for MacOSX and Big Endian Linux / Unix
#else
				*pGLFormat = GL_BGR;  //Generally for Windows and Linux (little Endian)
#endif
                *pGLType = GL_UNSIGNED_BYTE;
			} else {
				*pGLInternalFormat = GL_NONE;
				*pGLFormat = GL_NONE;
				*pGLType = GL_NONE;
				g_debug->header("Not supported format of image! texture not loaded" , DebugApi::LogHeaderWarning);
                }
			break;
		case (IND_RGBA): 
			if (16 == bpp) {
				*pGLInternalFormat = GL_RGBA;
                *pGLFormat = GL_RGBA; 
                *pGLType = GL_UNSIGNED_SHORT_4_4_4_4;
			} else if (32 == bpp) {
				*pGLInternalFormat = GL_RGBA;
				//FreeImage loads channel order differently depending on processor endianess (24 and 32 bits).
#if FI_RGBA_BLUE > FI_RGBA_RED
                *pGLFormat = GL_RGBA;  //Generally for MacOSX and Big Endian Linux / Unix
#else
				*pGLFormat = GL_BGRA;  //Generally for Windows and Linux (little Endian)
#endif
                *pGLType = GL_UNSIGNED_BYTE;
			} else {
				*pGLInternalFormat = GL_NONE;
				*pGLFormat = GL_NONE;
				*pGLType = GL_NONE;
				g_debug->header("Not supported format of image! texture not loaded" , DebugApi::LogHeaderWarning);
            }

            break;
		case (IND_COLOUR_INDEX):
		default:
			*pGLInternalFormat = GL_NONE;
            *pGLFormat = GL_NONE;
			*pGLType = GL_NONE;
            g_debug->header("Not supported format of image! texture not loaded" , DebugApi::LogHeaderWarning);
            break;
    }        
}
コード例 #6
0
ファイル: BitmapAccess.cpp プロジェクト: FlyApple/_3rdParty
FIBITMAP * DLL_CALLCONV
FreeImage_Clone(FIBITMAP *dib) {
	if(!dib) {
		return NULL;
	}

	FREE_IMAGE_TYPE type = FreeImage_GetImageType(dib);
	unsigned width	= FreeImage_GetWidth(dib);
	unsigned height	= FreeImage_GetHeight(dib);
	unsigned bpp	= FreeImage_GetBPP(dib);

	const BYTE *ext_bits = ((FREEIMAGEHEADER *)dib->data)->external_bits;
	
	// check for pixel availability ...
	BOOL header_only = FreeImage_HasPixels(dib) ? FALSE : TRUE;

	// check whether this image has masks defined ...
	BOOL need_masks = (bpp == 16 && type == FIT_BITMAP) ? TRUE : FALSE;

	// allocate a new dib
	FIBITMAP *new_dib = FreeImage_AllocateHeaderT(header_only, type, width, height, bpp,
			FreeImage_GetRedMask(dib), FreeImage_GetGreenMask(dib), FreeImage_GetBlueMask(dib));

	if (new_dib) {
		// save ICC profile links
		FIICCPROFILE *src_iccProfile = FreeImage_GetICCProfile(dib);
		FIICCPROFILE *dst_iccProfile = FreeImage_GetICCProfile(new_dib);

		// save metadata links
		METADATAMAP *src_metadata = ((FREEIMAGEHEADER *)dib->data)->metadata;
		METADATAMAP *dst_metadata = ((FREEIMAGEHEADER *)new_dib->data)->metadata;

		// calculate the size of the src image
		// align the palette and the pixels on a FIBITMAP_ALIGNMENT bytes alignment boundary
		// palette is aligned on a 16 bytes boundary
		// pixels are aligned on a 16 bytes boundary
		
		// when using a user provided pixel buffer, force a 'header only' calculation		

		size_t dib_size = FreeImage_GetInternalImageSize(header_only || ext_bits, width, height, bpp, need_masks);

		// copy the bitmap + internal pointers (remember to restore new_dib internal pointers later)
		memcpy(new_dib->data, dib->data, dib_size);

		// reset ICC profile link for new_dib
		memset(dst_iccProfile, 0, sizeof(FIICCPROFILE));

		// restore metadata link for new_dib
		((FREEIMAGEHEADER *)new_dib->data)->metadata = dst_metadata;

		// reset thumbnail link for new_dib
		((FREEIMAGEHEADER *)new_dib->data)->thumbnail = NULL;

		// copy possible ICC profile
		FreeImage_CreateICCProfile(new_dib, src_iccProfile->data, src_iccProfile->size);
		dst_iccProfile->flags = src_iccProfile->flags;

		// copy metadata models
		for(METADATAMAP::iterator i = (*src_metadata).begin(); i != (*src_metadata).end(); i++) {
			int model = (*i).first;
			TAGMAP *src_tagmap = (*i).second;

			if(src_tagmap) {
				// create a metadata model
				TAGMAP *dst_tagmap = new(std::nothrow) TAGMAP();

				if(dst_tagmap) {
					// fill the model
					for(TAGMAP::iterator j = src_tagmap->begin(); j != src_tagmap->end(); j++) {
						std::string dst_key = (*j).first;
						FITAG *dst_tag = FreeImage_CloneTag( (*j).second );

						// assign key and tag value
						(*dst_tagmap)[dst_key] = dst_tag;
					}

					// assign model and tagmap
					(*dst_metadata)[model] = dst_tagmap;
				}
			}
		}

		// copy the thumbnail
		FreeImage_SetThumbnail(new_dib, FreeImage_GetThumbnail(dib));

		// copy user provided pixel buffer (if any)
		if(ext_bits) {
			const unsigned pitch = FreeImage_GetPitch(dib);
			const unsigned linesize = FreeImage_GetLine(dib);
			for(unsigned y = 0; y < height; y++) {
				memcpy(FreeImage_GetScanLine(new_dib, y), ext_bits, linesize);
				ext_bits += pitch;
			}
		}

		return new_dib;
	}

	return NULL;
}
コード例 #7
0
ファイル: Resize.cpp プロジェクト: MichaelH13/sdkpub
FIBITMAP* CResizeEngine::scale(FIBITMAP *src, unsigned dst_width, unsigned dst_height) { 
	DWORD src_width  = FreeImage_GetWidth(src); 
	DWORD src_height = FreeImage_GetHeight(src);

	unsigned redMask	= FreeImage_GetRedMask(src);
	unsigned greenMask	= FreeImage_GetGreenMask(src);
	unsigned blueMask	= FreeImage_GetBlueMask(src);

	unsigned bpp = FreeImage_GetBPP(src);

	FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(src);

	// allocate the dst image
	FIBITMAP *dst = FreeImage_AllocateT(image_type, dst_width, dst_height, bpp, redMask, greenMask, blueMask);
	if(!dst) return NULL;
	
	if(bpp == 8) {
		if(FreeImage_GetColorType(src) == FIC_MINISWHITE) {
			// build an inverted greyscale palette
			RGBQUAD *dst_pal = FreeImage_GetPalette(dst);
			for(int i = 0; i < 256; i++) {
				dst_pal[i].rgbRed = dst_pal[i].rgbGreen =
					dst_pal[i].rgbBlue = (BYTE)(255 - i);
			}
		} else {
			// build a greyscale palette
			RGBQUAD *dst_pal = FreeImage_GetPalette(dst);
			for(int i = 0; i < 256; i++) {
				dst_pal[i].rgbRed = dst_pal[i].rgbGreen =
					dst_pal[i].rgbBlue = (BYTE)i;
			}
		}
	}

	// decide which filtering order (xy or yx) is faster for this mapping by
	// counting convolution multiplies

	if(dst_width*src_height <= dst_height*src_width) {
		// xy filtering
		// -------------

		// allocate a temporary image
		FIBITMAP *tmp = FreeImage_AllocateT(image_type, dst_width, src_height, bpp, redMask, greenMask, blueMask);
		if(!tmp) {
			FreeImage_Unload(dst);
			return NULL;
		}

		// scale source image horizontally into temporary image
		horizontalFilter(src, src_width, src_height, tmp, dst_width, src_height);

		// scale temporary image vertically into result image    
		verticalFilter(tmp, dst_width, src_height, dst, dst_width, dst_height);

		// free temporary image
		FreeImage_Unload(tmp);

	} else {
		// yx filtering
		// -------------

		// allocate a temporary image
		FIBITMAP *tmp = FreeImage_AllocateT(image_type, src_width, dst_height, bpp, redMask, greenMask, blueMask);
		if(!tmp) {
			FreeImage_Unload(dst);
			return NULL;
		}

		// scale source image vertically into temporary image
		verticalFilter(src, src_width, src_height, tmp, src_width, dst_height);

		// scale temporary image horizontally into result image    
		horizontalFilter(tmp, src_width, dst_height, dst, dst_width, dst_height);

		// free temporary image
		FreeImage_Unload(tmp);
	}

	return dst;
} 
コード例 #8
0
ファイル: PluginJXR.cpp プロジェクト: TLeonardUK/MicroBuild
/**
Scan input dib format and return the equivalent PKPixelFormatGUID format for saving
@param dib Image to be saved
@param guid_format (returned value) GUID format
@param bHasAlpha (returned value) TRUE if an alpha layer is present
@return Returns TRUE if successful, returns FALSE otherwise
*/
static ERR
GetOutputPixelFormat(FIBITMAP *dib, PKPixelFormatGUID *guid_format, BOOL *bHasAlpha) {
	const FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(dib);
	const unsigned bpp = FreeImage_GetBPP(dib);
	const FREE_IMAGE_COLOR_TYPE color_type = FreeImage_GetColorType(dib);

	*guid_format = GUID_PKPixelFormatDontCare;
	*bHasAlpha = FALSE;

	switch(image_type) {
		case FIT_BITMAP:	// standard image	: 1-, 4-, 8-, 16-, 24-, 32-bit
			switch(bpp) {
				case 1:
					// assume FIC_MINISBLACK
					if(color_type == FIC_MINISBLACK) {
						*guid_format = GUID_PKPixelFormatBlackWhite;
					}
					break;
				case 8:
					// assume FIC_MINISBLACK
					if(color_type == FIC_MINISBLACK) {
						*guid_format = GUID_PKPixelFormat8bppGray;
					}
					break;
				case 16:
					if ((FreeImage_GetRedMask(dib) == FI16_565_RED_MASK) && (FreeImage_GetGreenMask(dib) == FI16_565_GREEN_MASK) && (FreeImage_GetBlueMask(dib) == FI16_565_BLUE_MASK)) {
						*guid_format = GUID_PKPixelFormat16bppRGB565;
					} else {
						// includes case where all the masks are 0
						*guid_format = GUID_PKPixelFormat16bppRGB555;
					}
					break;
#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR
				case 24:
					*guid_format = GUID_PKPixelFormat24bppBGR;
					break;
				case 32:
					*guid_format = GUID_PKPixelFormat32bppBGRA;
					*bHasAlpha = TRUE;
					break;
#elif FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_RGB
				case 24:
					*guid_format = GUID_PKPixelFormat24bppRGB;
					break;
				case 32:
					*guid_format = GUID_PKPixelFormat32bppRGBA;
					*bHasAlpha = TRUE;
					break;
#endif
				case 4:
				default:
					// not supported
					break;
			}
			break;
		case FIT_UINT16:	// array of unsigned short	: unsigned 16-bit
			*guid_format = GUID_PKPixelFormat16bppGray;
			break;
		case FIT_FLOAT:		// array of float			: 32-bit IEEE floating point
			*guid_format = GUID_PKPixelFormat32bppGrayFloat;
			break;
		case FIT_RGB16:		// 48-bit RGB image			: 3 x 16-bit
			*guid_format = GUID_PKPixelFormat48bppRGB;
			break;
		case FIT_RGBA16:	// 64-bit RGBA image		: 4 x 16-bit
			*guid_format = GUID_PKPixelFormat64bppRGBA;
			*bHasAlpha = TRUE;
			break;
		case FIT_RGBF:		// 96-bit RGB float image	: 3 x 32-bit IEEE floating point
			*guid_format = GUID_PKPixelFormat96bppRGBFloat;
			break;
		case FIT_RGBAF:		// 128-bit RGBA float image	: 4 x 32-bit IEEE floating point
			*guid_format = GUID_PKPixelFormat128bppRGBAFloat;
			*bHasAlpha = TRUE;
			break;

		case FIT_INT16:		// array of short			: signed 16-bit
		case FIT_UINT32:	// array of unsigned long	: unsigned 32-bit
		case FIT_INT32:		// array of long			: signed 32-bit
		case FIT_DOUBLE:	// array of double			: 64-bit IEEE floating point
		case FIT_COMPLEX:	// array of FICOMPLEX		: 2 x 64-bit IEEE floating point

		default:
			// unsupported format
			break;
	}

	return (*guid_format != GUID_PKPixelFormatDontCare) ? WMP_errSuccess : WMP_errUnsupportedFormat;
}