Пример #1
0
void Image::_load(string sFilename)
{
	errlog << "Load " << sFilename << endl;
	//image format
	FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;
	//pointer to the image, once loaded
	FIBITMAP *dib(0);
	//pointer to the image data
	BYTE* bits(0);
	//image width and height
	unsigned int width(0), height(0);
	
	//check the file signature and deduce its format
	fif = FreeImage_GetFileType(sFilename.c_str(), 0);
	//if still unknown, try to guess the file format from the file extension
	if(fif == FIF_UNKNOWN) 
		fif = FreeImage_GetFIFFromFilename(sFilename.c_str());
	//if still unkown, return failure
	if(fif == FIF_UNKNOWN)
	{
		errlog << "Unknown image type for file " << sFilename << endl;
		return;
	}
  
	//check that the plugin has reading capabilities and load the file
	if(FreeImage_FIFSupportsReading(fif))
		dib = FreeImage_Load(fif, sFilename.c_str());
	else
		errlog << "File " << sFilename << " doesn't support reading." << endl;
	//if the image failed to load, return failure
	if(!dib)
	{
		errlog << "Error loading image " << sFilename.c_str() << endl;
		return;
	}  
	//retrieve the image data
  
	//get the image width and height
	width = FreeImage_GetWidth(dib);
	height = FreeImage_GetHeight(dib);
 
	int mode, modeflip;
	if(FreeImage_GetBPP(dib) == 24) // RGB 24bit
	{
#ifdef __BIG_ENDIAN__
		mode = GL_RGB;
		modeflip = GL_RGB;
#else
		mode = GL_RGB;
		modeflip = GL_BGR;
#endif
	}
	else if(FreeImage_GetBPP(dib) == 32)  // RGBA 32bit
	{
#ifdef __BIG_ENDIAN__
		mode = GL_RGBA;
		modeflip = GL_RGBA;
#else
		mode = GL_RGBA;
		modeflip = GL_BGRA;
#endif
	}
  
	bits = FreeImage_GetBits(dib);	//if this somehow one of these failed (they shouldn't), return failure
	if((bits == 0) || (width == 0) || (height == 0))
	{
		errlog << "Something went terribly horribly wrong with getting image bits; just sit and wait for the singularity" << endl;
		return;
	}
  
	//generate an OpenGL texture ID for this texture
	m_iWidth = width;
	m_iHeight = height;
	glGenTextures(1, &m_hTex);
	//bind to the new texture ID
	glBindTexture(GL_TEXTURE_2D, m_hTex);
	//store the texture data for OpenGL use
#ifdef __BIG_ENDIAN__
	m_iRealWidth = power_of_two(width);
	m_iRealHeight = power_of_two(height);
	FIBITMAP *bitmap2 = FreeImage_Allocate(m_iRealWidth, m_iRealHeight, FreeImage_GetBPP(dib));
	FreeImage_FlipVertical(dib);
	FreeImage_Paste(bitmap2, dib, 0, 0, 255);
	FreeImage_FlipVertical(bitmap2);
	bits = FreeImage_GetBits(bitmap2);
	glTexImage2D(GL_TEXTURE_2D, 0, mode, m_iRealWidth, m_iRealHeight, 0, modeflip, GL_UNSIGNED_BYTE, bits);
	FreeImage_Unload(bitmap2);
#else
	glTexImage2D(GL_TEXTURE_2D, 0, mode, width, height, 0, modeflip, GL_UNSIGNED_BYTE, bits);
#endif
  
	if(g_imageBlur)
	{
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
	}
	else //If you want things pixellated
	{
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
	}
	
	//Free FreeImage's copy of the data
	FreeImage_Unload(dib);
}
Пример #2
0
//加载图片
//以RGBA格式存储图片
static bool LoadImg(const char* fname,GLint nID)
{
    
    //初始化FreeImage
    FreeImage_Initialise(TRUE);
    
    //定义图片格式为未知
    FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;
    
    //获取图片格式
    fif = FreeImage_GetFileType(fname,0);
    
    //根据获取格式读取图片数据
    FIBITMAP* bitmap = FreeImage_Load(fif,fname,0);
    
    if(!bitmap)
    {
        printf("load error!\n");
        return false;
    }
    
    int x,y;
    RGBQUAD m_rgb;
    
    //获取图片长宽
    width = (int)FreeImage_GetWidth(bitmap);
    height = (int)FreeImage_GetHeight(bitmap);
    
    imgBuf = new unsigned char[width*height*4];
    
    //获取图片数据
    //按RGBA格式保存到数组中
    for(y=0;y<height;y++)
    {
        for(x=0;x<width;x++)
        {
            //获取像素值
            FreeImage_GetPixelColor(bitmap,x,y,&m_rgb);
            
            //将RGB值存入数组
            imgBuf[y*width*4+x*4+0] = m_rgb.rgbRed;
            imgBuf[y*width*4+x*4+1] = m_rgb.rgbGreen;
            imgBuf[y*width*4+x*4+2] = m_rgb.rgbBlue;
            
            //判断是否透明图片
            //如果是就取alpha值保存
            if(FreeImage_IsTransparent(bitmap))
                imgBuf[y*width*4+x*4+3] = m_rgb.rgbReserved;
            else
                imgBuf[y*width*4+x*4+3] = 255;
        }
    }
    
    //绑定纹理ID
    
    if(nID==0)
    {
        glGenTextures(1, &g_texture1);
        glBindTexture(GL_TEXTURE_2D, g_texture1);
    }
    else
    {
        glGenTextures(1, &g_texture2);
        glBindTexture(GL_TEXTURE_2D, g_texture2);
    }
    
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, imgBuf);
    
    //释放FreeImage
    delete imgBuf;
    FreeImage_Unload(bitmap);
    return true;
}
	FIBITMAP* finalize(bool showProgress = false) {
		if (chunks.empty()) {
			return NULL;
		}
		if (showProgress) {
			printf("Adding all accepted chunks to the final image\n");
		}

		std::list<FIBITMAP*>::iterator it = chunks.begin();
		unsigned int width = FreeImage_GetWidth(*it);
		unsigned int height = FreeImage_GetHeight(*it);

		FIBITMAP *finalImage = FreeImage_Copy(*it, 0, height, width, 0);
	


		for (it++; it != chunks.end(); it++) {
				for(unsigned int y = 0 ; y < height ; y++) {
					FIRGBAF *srcbits = (FIRGBAF *) FreeImage_GetScanLine(*it, y);
					FIRGBAF *dstbits = (FIRGBAF *) FreeImage_GetScanLine(finalImage, y);
					for(unsigned int x = 0 ; x < width  ; x++) {
						dstbits[x].red += srcbits[x].red;
						dstbits[x].blue += srcbits[x].blue;
						dstbits[x].green += srcbits[x].green;
					}
				}
		}

	/*	unsigned int numParts = chunks.size();
		unsigned int chunkHeight = 12;
		unsigned int chunkWidth = 427;

		unsigned int lastHeight = height -1 - chunkHeight;
		unsigned int lastWidth = chunkWidth;
		unsigned int restWidth = chunkWidth;
		for (it++; it != chunks.end(); it++) {
			printf("lastHeight = %d, lastWidth = %d restWidth = %d\n", lastHeight, lastWidth, restWidth);
			bool continueChunk = true;
			while (continueChunk) {
				printf("lastHeight = %d, lastWidth = %d restWidth = %d\n", lastHeight, lastWidth, restWidth);
				continueChunk = false;
				for(unsigned int y = lastHeight ; y < min(height, lastHeight + chunkHeight + 1) ; y++) {
					FIRGBAF *srcbits = (FIRGBAF *) FreeImage_GetScanLine(*it, y);
					FIRGBAF *dstbits = (FIRGBAF *) FreeImage_GetScanLine(finalImage, y);
					for(unsigned int x = lastWidth ; x < min(width, lastWidth + restWidth)  ; x++) {
						//printf("y = %d x= %d\n", y, x);
						dstbits[x].red = srcbits[x].red;	
						dstbits[x].green = srcbits[x].green;
						dstbits[x].blue = srcbits[x].blue;	
					}
				}
				if (width < lastWidth + restWidth) {
						continueChunk = true;
						lastHeight -= chunkHeight - 1;
						restWidth -= width - lastWidth;
						lastWidth = 0;
				} else {
						lastWidth += restWidth;
						restWidth = chunkWidth;
				}
			}
		}*/

		
		return finalImage;
	}
Пример #4
0
//!!!be sure to release memory before return null
ResHandler* WIPResourceManager::alloc(const char* filename, WIPResourceType type)
{
    ResHandler* res = new ResHandler;
    switch (type)
    {
    case TEXT:
    {

    }
    break;
    case TEXTURE:
    {
        TextureData *data = new TextureData;
        //初始化FreeImage
        FreeImage_Initialise(TRUE);

        FIBITMAP* bmpConverted = NULL;
        FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;
        fif = FreeImage_GetFileType(filename);
        if (fif == FIF_UNKNOWN)
            fif = FreeImage_GetFIFFromFilename(filename);
        if ((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsReading(fif))
        {

            FIBITMAP *dib = FreeImage_Load(fif, filename);

            if (!dib)
            {
                printf("[fatal error]: \"%s\" load error!\n", filename);
                delete data;
                delete_handler(res);
                return NULL;
            }

            // we are top left, FIBITMAP is bottom left
            FreeImage_FlipVertical(dib);
            //get infomation
            FREE_IMAGE_TYPE imgType = FreeImage_GetImageType(dib);
            FREE_IMAGE_COLOR_TYPE colorType = FreeImage_GetColorType(dib);
            unsigned int bpp = FreeImage_GetBPP(dib);

            data->bpp = bpp;
            data->color_type = colorType;
            data->image_type = imgType;
            data->channel = 4;

            int x, y;
            RGBQUAD m_rgb;

            //获取图片长宽
            int width = (int)FreeImage_GetWidth(dib);
            int height = (int)FreeImage_GetHeight(dib);

            unsigned char* imgBuf = new unsigned char[width*height * 4];



            bool is_tr = FreeImage_IsTransparent(dib);

            bool is_little = FreeImage_IsLittleEndian();
            //获取图片数据
            //按RGBA格式保存到数组中
            for (y = 0; y<height; y++)
            {
                for (x = 0; x<width; x++)
                {
                    //获取像素值
                    FreeImage_GetPixelColor(dib, x, y, &m_rgb);

                    if (is_little)
                    {
                        imgBuf[y*width * 4 + x * 4 + 0] = m_rgb.rgbRed;
                        imgBuf[y*width * 4 + x * 4 + 1] = m_rgb.rgbGreen;
                        imgBuf[y*width * 4 + x * 4 + 2] = m_rgb.rgbBlue;
                        //判断是否透明图片
                        //如果是就取alpha值保存
                        if (is_tr)
                            imgBuf[y*width * 4 + x * 4 + 3] = m_rgb.rgbReserved;
                        else
                            imgBuf[y*width * 4 + x * 4 + 3] = 255;
                    }
                    else
                    {
                        //大端警告!
                        //Big Endian Warnning!
                        printf("Note:This is a Big endian!\n");
                    }
                }
            }


            data->width = width;
            data->height = height;
            data->size = height*width * 4;


            FreeImage_Unload(dib);

            res->file_name = filename;
            res->extra = data;
            res->nref = 1;
            res->ptr = imgBuf;
            res->size = width*height * 4;
            res->type = TEXTURE;

            _map[filename] = res;

            return res;
        }
    }
    break;

    case SOUND:
    {
    }
    default:
        return res;
        break;
    }
    delete_handler(res);
    return NULL;
}
Пример #5
0
bool CPicture::Load(tstring sFilePathName)
{
	bool bResult = false;
	bIsIcon = false;
	lpIcons = NULL;
	//CFile PictureFile;
	//CFileException e;
	FreePictureData(); // Important - Avoid Leaks...

	// No-op if no file specified
	if (sFilePathName.empty())
		return true;

	// Load & initialize the GDI+ library if available
	HMODULE hGdiPlusLib = AtlLoadSystemLibraryUsingFullPath(_T("gdiplus.dll"));
	if (hGdiPlusLib && GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL) == Ok)
	{
		bHaveGDIPlus = true;
	}
	// Since we loaded the gdiplus.dll only to check if it's available, we
	// can safely free the library here again - GdiplusStartup() loaded it too
	// and reference counting will make sure that it stays loaded until GdiplusShutdown()
	// is called.
	FreeLibrary(hGdiPlusLib);

	// Attempt to load using GDI+ if available
	if (bHaveGDIPlus)
	{
		pBitmap = new Bitmap(sFilePathName.c_str(), FALSE);
		GUID guid;
		pBitmap->GetRawFormat(&guid);

		if (pBitmap->GetLastStatus() != Ok)
		{
			delete pBitmap;
			pBitmap = NULL;
		}

		// gdiplus only loads the first icon found in an icon file
		// so we have to handle icon files ourselves :(

		// Even though gdiplus can load icons, it can't load the new
		// icons from Vista - in Vista, the icon format changed slightly.
		// But the LoadIcon/LoadImage API still can load those icons,
		// at least those dimensions which are also used on pre-Vista
		// systems.
		// For that reason, we don't rely on gdiplus telling us if
		// the image format is "icon" or not, we also check the
		// file extension for ".ico".
		std::transform(sFilePathName.begin(), sFilePathName.end(), sFilePathName.begin(), ::tolower);
		bIsIcon = (guid == ImageFormatIcon) || (_tcsstr(sFilePathName.c_str(), _T(".ico")) != NULL);
		bIsTiff = (guid == ImageFormatTIFF) || (_tcsstr(sFilePathName.c_str(), _T(".tiff")) != NULL);
		m_Name = sFilePathName;

		if (bIsIcon)
		{
			// Icon file, get special treatment...
			if (pBitmap)
			{
				// Cleanup first...
				delete (pBitmap);
				pBitmap = NULL;
				bIsIcon = true;
			}

			CAutoFile hFile = CreateFile(sFilePathName.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
			if (hFile)
			{
				BY_HANDLE_FILE_INFORMATION fileinfo;
				if (GetFileInformationByHandle(hFile, &fileinfo))
				{
					lpIcons = new BYTE[fileinfo.nFileSizeLow];
					DWORD readbytes;
					if (ReadFile(hFile, lpIcons, fileinfo.nFileSizeLow, &readbytes, NULL))
					{
						// we have the icon. Now gather the information we need later
						if (readbytes >= sizeof(ICONDIR))
						{
							// we are going to open same file second time so we have to close the file now
							hFile.CloseHandle();

							LPICONDIR lpIconDir = (LPICONDIR)lpIcons;
							if ((lpIconDir->idCount) && ((lpIconDir->idCount * sizeof(ICONDIR)) <= fileinfo.nFileSizeLow))
							{
								try
								{
									bResult = false;
									nCurrentIcon = 0;
									hIcons = new HICON[lpIconDir->idCount];
									// check that the pointers point to data that we just loaded
									if (((BYTE*)lpIconDir->idEntries > (BYTE*)lpIconDir) && 
										(((BYTE*)lpIconDir->idEntries) + (lpIconDir->idCount * sizeof(ICONDIRENTRY)) < ((BYTE*)lpIconDir) + fileinfo.nFileSizeLow))
									{
										m_Width = lpIconDir->idEntries[0].bWidth;
										m_Height = lpIconDir->idEntries[0].bHeight;
										bResult = true;
										for (int i=0; i<lpIconDir->idCount; ++i)
										{
											hIcons[i] = (HICON)LoadImage(NULL, sFilePathName.c_str(), IMAGE_ICON,
																		 lpIconDir->idEntries[i].bWidth,
																		 lpIconDir->idEntries[i].bHeight,
																		 LR_LOADFROMFILE);
											if (hIcons[i] == NULL)
											{
												// if the icon couldn't be loaded, the data is most likely corrupt
												delete [] lpIcons;
												lpIcons = NULL;
												bResult = false;
												break;
											}
										}
									}
								}
								catch (...)
								{
									delete [] lpIcons;
									lpIcons = NULL;
									bResult = false;
								}
							}
							else
							{
								delete [] lpIcons;
								lpIcons = NULL;
								bResult = false;
							}
						}
						else
						{
							delete [] lpIcons;
							lpIcons = NULL;
							bResult = false;
						}
					}
					else
					{
						delete [] lpIcons;
						lpIcons = NULL;
					}
				}
			}
		}
		else if (pBitmap)	// Image loaded successfully with GDI+
		{
			m_Height = pBitmap->GetHeight();
			m_Width = pBitmap->GetWidth();
			bResult = true;
		}

		// If still failed to load the file...
		if (!bResult)
		{
			// Attempt to load the FreeImage library as an optional DLL to support additional formats

			// NOTE: Currently just loading via FreeImage & using GDI+ for drawing.
			// It might be nice to remove this dependency in the future.
			HMODULE hFreeImageLib = LoadLibrary(_T("FreeImage.dll"));

			// FreeImage DLL functions
			typedef const char* (__stdcall *FreeImage_GetVersion_t)(void);
			typedef int			(__stdcall *FreeImage_GetFileType_t)(const TCHAR *filename, int size);
			typedef int			(__stdcall *FreeImage_GetFIFFromFilename_t)(const TCHAR *filename);
			typedef void*		(__stdcall *FreeImage_Load_t)(int format, const TCHAR *filename, int flags);
			typedef void		(__stdcall *FreeImage_Unload_t)(void* dib);
			typedef int			(__stdcall *FreeImage_GetColorType_t)(void* dib);
			typedef unsigned	(__stdcall *FreeImage_GetWidth_t)(void* dib);
			typedef unsigned	(__stdcall *FreeImage_GetHeight_t)(void* dib);
			typedef void		(__stdcall *FreeImage_ConvertToRawBits_t)(BYTE *bits, void *dib, int pitch, unsigned bpp, unsigned red_mask, unsigned green_mask, unsigned blue_mask, BOOL topdown);

			//FreeImage_GetVersion_t FreeImage_GetVersion = NULL;
			FreeImage_GetFileType_t FreeImage_GetFileType = NULL;
			FreeImage_GetFIFFromFilename_t FreeImage_GetFIFFromFilename = NULL;
			FreeImage_Load_t FreeImage_Load = NULL;
			FreeImage_Unload_t FreeImage_Unload = NULL;
			//FreeImage_GetColorType_t FreeImage_GetColorType = NULL;
			FreeImage_GetWidth_t FreeImage_GetWidth = NULL;
			FreeImage_GetHeight_t FreeImage_GetHeight = NULL;
			FreeImage_ConvertToRawBits_t  FreeImage_ConvertToRawBits = NULL;

			if (hFreeImageLib)
			{
				bool exportsValid = true;

				//FreeImage_GetVersion = (FreeImage_GetVersion_t)s_GetProcAddressEx(hFreeImageLib, "_FreeImage_GetVersion@0", valid);
				FreeImage_GetWidth = (FreeImage_GetWidth_t)s_GetProcAddressEx(hFreeImageLib, "_FreeImage_GetWidth@4", exportsValid);
				FreeImage_GetHeight = (FreeImage_GetHeight_t)s_GetProcAddressEx(hFreeImageLib, "_FreeImage_GetHeight@4", exportsValid);
				FreeImage_Unload = (FreeImage_Unload_t)s_GetProcAddressEx(hFreeImageLib, "_FreeImage_Unload@4", exportsValid);
				FreeImage_ConvertToRawBits = (FreeImage_ConvertToRawBits_t)s_GetProcAddressEx(hFreeImageLib, "_FreeImage_ConvertToRawBits@32", exportsValid);

#ifdef UNICODE
				FreeImage_GetFileType = (FreeImage_GetFileType_t)s_GetProcAddressEx(hFreeImageLib, "_FreeImage_GetFileTypeU@8", exportsValid);
				FreeImage_GetFIFFromFilename = (FreeImage_GetFIFFromFilename_t)s_GetProcAddressEx(hFreeImageLib, "_FreeImage_GetFIFFromFilenameU@4", exportsValid);
				FreeImage_Load = (FreeImage_Load_t)s_GetProcAddressEx(hFreeImageLib, "_FreeImage_LoadU@12", exportsValid);
#else
				FreeImage_GetFileType = (FreeImage_GetFileType_t)s_GetProcAddressEx(hFreeImageLib, "_FreeImage_GetFileType@8", exportsValid);
				FreeImage_GetFIFFromFilename = (FreeImage_GetFIFFromFilename_t)s_GetProcAddressEx(hFreeImageLib, "_FreeImage_GetFIFFromFilename@4", exportsValid);
				FreeImage_Load = (FreeImage_Load_t)s_GetProcAddressEx(hFreeImageLib, "_FreeImage_Load@12", exportsValid);
#endif

				//const char* version = FreeImage_GetVersion();

				// Check the DLL is using compatible exports
				if (exportsValid)
				{
					// Derive file type from file header.
					int fileType = FreeImage_GetFileType(sFilePathName.c_str(), 0);
					if (fileType < 0)
					{
						// No file header available, attempt to parse file name for extension.
						fileType = FreeImage_GetFIFFromFilename(sFilePathName.c_str());
					}

					// If we have a valid file type
					if (fileType >= 0)
					{
						void* dib = FreeImage_Load(fileType, sFilePathName.c_str(), 0);

						if (dib)
						{
							unsigned width = FreeImage_GetWidth(dib);
							unsigned height = FreeImage_GetHeight(dib);

							// Create a GDI+ bitmap to load into...
							pBitmap = new Bitmap(width, height, PixelFormat32bppARGB);

							if (pBitmap && pBitmap->GetLastStatus() == Ok)
							{
								// Write & convert the loaded data into the GDI+ Bitmap
								Rect rect(0, 0, width, height);
								BitmapData bitmapData;
								if (pBitmap->LockBits(&rect, ImageLockModeWrite, PixelFormat32bppARGB, &bitmapData) == Ok)
								{
									FreeImage_ConvertToRawBits((BYTE*)bitmapData.Scan0, dib, bitmapData.Stride, 32, 0xff << RED_SHIFT, 0xff << GREEN_SHIFT, 0xff << BLUE_SHIFT, FALSE);

									pBitmap->UnlockBits(&bitmapData);

									m_Width = width;
									m_Height = height;
									bResult = true;
								}
								else    // Failed to lock the destination Bitmap
								{
									delete pBitmap;
									pBitmap = NULL;
								}
							}
							else    // Bitmap allocation failed
							{
								delete pBitmap;
								pBitmap = NULL;
							}

							FreeImage_Unload(dib);
							dib = NULL;
						}
					}
				}

				FreeLibrary(hFreeImageLib);
				hFreeImageLib = NULL;
			}
		}
	}
Пример #6
0
/** @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;
			if (bpp == 8) {
				bgcolor = FreeImage_GetPalette(dib)[*src_bits];
			} else {	
				bgcolor.rgbBlue = src_bits[FI_RGBA_BLUE];
				bgcolor.rgbGreen = src_bits[FI_RGBA_GREEN];
				bgcolor.rgbRed = src_bits[FI_RGBA_RED];
				bgcolor.rgbReserved = 0xFF;
			}
			RGBQUAD blend;
			GetAlphaBlendedColor(&bgcolor, color_intl, &blend);
			color_intl = &blend;
		}
	}
	
	int index = (bpp <= 8) ? GetPaletteIndex(dib, color_intl, options, &color_type) : 0;
	if (index == -1) {
		// No palette index found for a palletized
		// image. This should never happen...
		return FALSE;
	}
	
	// first, build the first scanline (line 0)
	switch (bpp) {
		case 1: {
			unsigned bytes = (width / 8);
			memset(dst_bits, ((index == 1) ? 0xFF : 0x00), bytes);
			//int n = width % 8;
			int n = width & 7;
			if (n) {
				if (index == 1) {
					// set n leftmost bits
					dst_bits[bytes] |= (0xFF << (8 - n));
				} else {
					// clear n leftmost bits
					dst_bits[bytes] &= (0xFF >> n);
				}
			}
			break;
		}
		case 4: {
			unsigned bytes = (width / 2);
			memset(dst_bits, (index | (index << 4)), bytes);
			//if (bytes % 2) {
			if (bytes & 1) {
				dst_bits[bytes] &= 0x0F;
				dst_bits[bytes] |= (index << 4);
			}
			break;
		}
		case 8: {
			memset(dst_bits, index, FreeImage_GetLine(dib));
			break;
		}
		case 16: {
			WORD wcolor = RGBQUAD_TO_WORD(dib, color_intl);
			for (unsigned x = 0; x < width; x++) {
				((WORD *)dst_bits)[x] = wcolor;
			}
			break;
		}
		case 24: {
			RGBTRIPLE rgbt = *((RGBTRIPLE *)color_intl);
			for (unsigned x = 0; x < width; x++) {
				((RGBTRIPLE *)dst_bits)[x] = rgbt;
			}
			break;
		}
		case 32: {
			RGBQUAD rgbq;
			rgbq.rgbBlue = ((RGBTRIPLE *)color_intl)->rgbtBlue;
			rgbq.rgbGreen = ((RGBTRIPLE *)color_intl)->rgbtGreen;
			rgbq.rgbRed = ((RGBTRIPLE *)color_intl)->rgbtRed;
			rgbq.rgbReserved = 0xFF;
			for (unsigned x = 0; x < width; x++) {
				((RGBQUAD *)dst_bits)[x] = rgbq;
			}
			break;
		}
		default:
			return FALSE;
	}

	// Then, copy the first scanline into all following scanlines.
	// 'src_bits' is a pointer to the first scanline and is already
	// set up correctly.
	if (src_bits) {
		unsigned pitch = FreeImage_GetPitch(dib);
		unsigned bytes = FreeImage_GetLine(dib);
		dst_bits = src_bits + pitch;
		for (unsigned y = 1; y < height; y++) {
			memcpy(dst_bits, src_bits, bytes);
			dst_bits += pitch;
		}
	}
	return TRUE;
}
Пример #7
0
/**
 * @return the width of the image (in points)
 */
unsigned long fipImage::getWidth() const{

	return FreeImage_GetWidth( pImageData );
}
Пример #8
0
// This is what does the work in the background thread
UINT CHexEditDoc::RunPreviewThread()
{
	// Keep looping until we are told to die
	for (;;)
	{
		// Signal that we are waiting then wait for start_preview_event_ to be pulsed
		{
			CSingleLock sl(&docdata_, TRUE);
			preview_state_ = WAITING;
		}
		TRACE1("+++ BGPreview: waiting for %p\n", this);
		DWORD wait_status = ::WaitForSingleObject(HANDLE(start_preview_event_), INFINITE);
		docdata_.Lock();
		preview_state_ = SCANNING;
		docdata_.Unlock();
		start_preview_event_.ResetEvent();
		ASSERT(wait_status == WAIT_OBJECT_0);
		TRACE1("+++ BGPreview: got event for %p\n", this);

		if (PreviewProcessStop())
			continue;

		// Reset for new scan
		docdata_.Lock();
		preview_fin_ = false;
		preview_address_ = 0;
		if (preview_dib_ != NULL)
		{
			FreeImage_Unload(preview_dib_);
			preview_dib_ = NULL;
		}
		docdata_.Unlock();

		FREE_IMAGE_FORMAT fif = FreeImage_GetFileTypeFromHandle(&fi_funcs, this);
		FIBITMAP * dib;
		// Catch FreeImage_Load exceptions since it has been known to have memory access violations on bad data
		try
		{
			dib = FreeImage_LoadFromHandle(fif, &fi_funcs, this);
		}
		catch (...)
		{
			dib = NULL;
		}
		int bpp = FreeImage_GetBPP(dib);
		unsigned width = FreeImage_GetWidth(dib);
		unsigned height = FreeImage_GetHeight(dib);

		TRACE1("+++ BGPreview: finished load for %p\n", this);
		docdata_.Lock();
		preview_fin_ = true;
		preview_address_ = 0;
		preview_dib_ = dib;

		// Save info about the bitmap just loaded
		preview_fif_ = fif;
		preview_bpp_ = bpp;
		preview_width_ = width;
		preview_height_ = height;
		docdata_.Unlock();
	}
	return 0;   // never reached
}
Пример #9
0
static BOOL DLL_CALLCONV
Save(FreeImageIO *io, FIBITMAP *dib, fi_handle handle, int page, int flags, void *data) {
	BOOL bIsFlipped = FALSE;		// FreeImage DIB are upside-down relative to usual graphic conventions
	PKPixelFormatGUID guid_format;	// image format
	PKPixelInfo pixelInfo;			// image specifications
	BOOL bHasAlpha = FALSE;			// is alpha layer present ?

	PKImageEncode *pEncoder = NULL;		// encoder interface
	ERR error_code = 0;					// error code as returned by the interface

	// get the I/O stream wrapper
	WMPStream *pEncodeStream = (WMPStream*)data;

	if(!dib || !handle || !pEncodeStream) {
		return FALSE;
	}

	try {
		// get image dimensions
		unsigned width = FreeImage_GetWidth(dib);
		unsigned height = FreeImage_GetHeight(dib);

		// check JPEG-XR limits
		if((width < MB_WIDTH_PIXEL) || (height < MB_HEIGHT_PIXEL)) {
			FreeImage_OutputMessageProc(s_format_id, "Unsupported image size: width x height = %d x %d", width, height);
			throw (const char*)NULL;
		}

		// get output pixel format
		error_code = GetOutputPixelFormat(dib, &guid_format, &bHasAlpha);
		JXR_CHECK(error_code);
		pixelInfo.pGUIDPixFmt = &guid_format;
		error_code = PixelFormatLookup(&pixelInfo, LOOKUP_FORWARD);
		JXR_CHECK(error_code);

		// create a JXR encoder interface and initialize function pointers with *_WMP functions
		error_code = PKImageEncode_Create_WMP(&pEncoder);
		JXR_CHECK(error_code);

		// attach the stream to the encoder and set all encoder parameters to zero ...
		error_code = pEncoder->Initialize(pEncoder, pEncodeStream, &pEncoder->WMP.wmiSCP, sizeof(CWMIStrCodecParam));
		JXR_CHECK(error_code);

		// ... then configure the encoder
		SetEncoderParameters(&pEncoder->WMP.wmiSCP, &pixelInfo, flags, bHasAlpha);

		// set pixel format
		pEncoder->SetPixelFormat(pEncoder, guid_format);

		// set image size
		pEncoder->SetSize(pEncoder, width, height);
		
		// set resolution (convert from universal units to English units)
		float resX = (float)(unsigned)(0.5F + 0.0254F * FreeImage_GetDotsPerMeterX(dib));
		float resY = (float)(unsigned)(0.5F + 0.0254F * FreeImage_GetDotsPerMeterY(dib));
		pEncoder->SetResolution(pEncoder, resX, resY);

		// set metadata
		WriteMetadata(pEncoder, dib);

		// write metadata & pixels
		// -----------------------

		// dib coordinates are upside-down relative to usual conventions
		bIsFlipped = FreeImage_FlipVertical(dib);

		// get a pointer to dst pixel data
		BYTE *dib_bits = FreeImage_GetBits(dib);

		// get dst pitch (count of BYTE for stride)
		const unsigned cbStride = FreeImage_GetPitch(dib);

		// write metadata + pixels on output
		error_code = pEncoder->WritePixels(pEncoder, height, dib_bits, cbStride);
		JXR_CHECK(error_code);

		// recover dib coordinates
		FreeImage_FlipVertical(dib);

		// free the encoder
		pEncoder->Release(&pEncoder);
		assert(pEncoder == NULL);
		
		return TRUE;

	} catch (const char *message) {
		if(bIsFlipped) {
			// recover dib coordinates
			FreeImage_FlipVertical(dib);
		}
		if(pEncoder) {
			// free the encoder
			pEncoder->Release(&pEncoder);
			assert(pEncoder == NULL);
		}
		if(NULL != message) {
			FreeImage_OutputMessageProc(s_format_id, message);
		}
	}

	return FALSE;
}
Пример #10
0
entity* entityManager::loadEntity(string fileName)
{
    string data;
    entity* newObj = new entity(simConfig);

    //now load each of THOSE files, this time creating an entity based on their data
    ifstream objectFile;
    objectFile.open(fileName);
    int line = 0; //tracks what stage of file loading we are in
    
    //objectFile>>data;
    getline(objectFile, data);

    //if it failed to open, skip over this file
    if(!objectFile.good())
    {
        cout<<"Failed to load object! "<<fileName<<endl;
        delete newObj;

        return NULL;
    }

    while(objectFile.good())
    {
        if(line>=10) // all objects past number 8 should be moons
        {
            //create a new entity for our shiny new object
            entity* newMoon = loadEntity(data);
            
            if(newMoon!=NULL)
            {
                //add them to the object list
                newMoon->next = head;
                head = newMoon;
                entityCount++; 
                //newMoon->next = newObj->children;
                //newObj->children = newMoon;

                newMoon->parent = newObj;
            }      
        }
        else
        {
            switch(line)
            {
                case 0:
                    newObj->name = data;
                    cout<<"Object name: "<<data<<endl;
                    break;
                case 2:
                    newObj->orbitalPeriod = atof(data.c_str());
                    break;
                case 3:
                    newObj->rotationPeriod = atof(data.c_str());
                    break;
                case 4:
                    newObj->semimajorAxis = atof(data.c_str());
                    break;
                case 5:
                    newObj->diameter = atof(data.c_str());
                    break;
                case 6:
                    newObj->tilt = atof(data.c_str());
                    break;
                case 7:
                    newObj->orbitTilt = atof(data.c_str());
                    break;
                case 8:
                    newObj->rotationPeriod *= atoi(data.c_str());
                    break;
                case 9://check if we need a camera of this object
                    if(atoi(data.c_str()) == 1)
                    {
                    Camera* newCamera = new Camera(newObj);
                    if(simConfig->presetCameras == NULL)
                        simConfig->presetCameras = newCamera;
                    else
                    {
                        Camera* iterator = simConfig->presetCameras;
                        while(iterator->next!=NULL)
                            iterator = iterator->next;

                        iterator->next = newCamera;
                    }
                    cout<<"New camera created for "<<newObj->name<<"!"<<endl;
                }
                break;
            case 1:
                cout<<"Model file path: "<<data<<endl;

                //oh god monster code section//open the file
                const aiScene* scene = import.ReadFile("../bin/models/"+data+newObj->name+".obj", aiProcess_Triangulate);

                if(scene != NULL)
                {

                    //iterate across the meshes in the scene
                    for(unsigned int mIndex = 0; mIndex < scene->mNumMeshes; mIndex++)
                    {
                        aiMesh* m = scene->mMeshes[mIndex];
                        //iterate across faces in the mesh
                        for(unsigned int fIndex = 0; fIndex < m->mNumFaces; fIndex++)
                        {
                            aiFace* f = &(m->mFaces[fIndex]);
                            //iterate across indices in the face
                            for(unsigned int iIndex = 0; iIndex < f->mNumIndices; iIndex++)
                            {
                                const int index = f->mIndices[iIndex];

                                //push each vertex onto the entity vertices
                                Vertex v;
                                v.position[0] = m->mVertices[index].x;
                                v.position[1] = m->mVertices[index].y;
                                v.position[2] = m->mVertices[index].z;

                                //get the material
                                aiMaterial* material = scene->mMaterials[m->mMaterialIndex];
                                aiColor3D color (0.f,0.f,0.f);
                                material->Get(AI_MATKEY_COLOR_DIFFUSE,color);

                                if(m->HasTextureCoords(0))
                                {

                                    aiVector3D textureCoord = m->mTextureCoords[0][index];

                                    v.uv[0] = textureCoord.x;
                                    v.uv[1] = textureCoord.y;
                                }
                                else
                                {
                                    v.uv[0] = 0.0f;
                                    v.uv[1] = 0.0f;
                                }

                                newObj->vertices.push_back(v);
                            }
                        }

                        //get texture file name
                        aiString fname;
                        char newname[512];
                        string textPath = "../bin/models/" + data;

                        strcpy(newname, textPath.c_str());
                        
                        scene->mMaterials[m->mMaterialIndex]->GetTexture(aiTextureType_DIFFUSE, 0, &fname);

                        //add mat name to end of it
                        strcat(newname, fname.data);

                        //give it its texture
                        newObj->texID = simConfig->texCount;
                        simConfig->texCount++;

                        FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;

                        BYTE * bits(0);
                        FIBITMAP * dib(0);
                        fif = FreeImage_GetFileType(newname, 0);
                        //if still unknown, try to guess the file format from the file extension
                        if(fif == FIF_UNKNOWN)
                            fif = FreeImage_GetFIFFromFilename(newname);

                        if(fif == FIF_UNKNOWN)
                            cout<<"WE DON'T KNOW WHAT FIF THIS IS!"<<endl;

                        if(FreeImage_FIFSupportsReading(fif))
                            dib = FreeImage_Load(fif, newname, 0);
                        else
                            cout<<"Bad texture file format!"<<endl;

                        if(!dib)
                        {
                            cout<<"Dib failed to load! Are your file paths set up properly?? "<<newname<<endl;
                        }

                        bits = FreeImage_GetBits(dib);
                        //get the image width and height
                        newObj->texWidth = FreeImage_GetWidth(dib);
                        newObj->texHeight = FreeImage_GetHeight(dib);
                        cout<<"Texture "<<newname<<" image size: "<<newObj->texWidth<<"px by "<<newObj->texHeight<<"px"<<endl;
                        //if this somehow one of these failed (they shouldn't), return failure

                        //generate an OpenGL texture ID for this texture
                        glGenTextures(1, &newObj->texID);
                        glBindTexture( GL_TEXTURE_2D, newObj->texID);
                        //store the texture data for OpenGL use
                        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
                        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, newObj->texWidth, newObj->texHeight, 0, GL_BGR, GL_UNSIGNED_BYTE, bits);

                        FreeImage_Unload(dib);
                    }
                }
                break;
            }
        }

        line++;

        objectFile>>data;
    }
    objectFile.close();

    return newObj;
}