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); }
//加载图片 //以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; }
//!!!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; }
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; } } }
/** @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; }
/** * @return the width of the image (in points) */ unsigned long fipImage::getWidth() const{ return FreeImage_GetWidth( pImageData ); }
// 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 }
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; }
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; }