bool Image::load(const char* filename) { const uint32_t argb_r = 0xFF000000u; const uint32_t argb_g = 0x00FF0000u; const uint32_t argb_b = 0x0000FF00u; const uint32_t argb_a = 0x000000FFu; FREE_IMAGE_FORMAT format; FIBITMAP* bitmap; FIBITMAP* rgbamap; int32_t w, h; // Unload if image already loaded to protect from memory leak unload(); // Get filetype format = FreeImage_GetFileType(filename); if (format == FIF_UNKNOWN) { fprintf(stderr, "Failed to ascertain filetype of %s\n", filename); return false; } // Load image bitmap = FreeImage_Load(format, filename); if (bitmap == nullptr) { fprintf(stderr, "Failed to load %s\n", filename); return false; } // Get width and height w = FreeImage_GetWidth(bitmap); h = FreeImage_GetHeight(bitmap); // Convert to RGBA if not already rgbamap = FreeImage_ConvertTo32Bits(bitmap); int32_t scan_width = FreeImage_GetPitch(rgbamap); // Make copy int32_t size = h * scan_width; _pixels = malloc(size); FreeImage_ConvertToRawBits((BYTE*)_pixels, bitmap, scan_width, 32, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK, true); _width = w; _height = h; // Unload FreeImage bitmaps FreeImage_Unload(bitmap); FreeImage_Unload(rgbamap); return true; }
//---------------------------------------------------- void ofImage::putBmpIntoPixels(FIBITMAP * bmp, ofPixels &pix){ int width = FreeImage_GetWidth(bmp); int height = FreeImage_GetHeight(bmp); int bpp = FreeImage_GetBPP(bmp); int bytesPerPixel = bpp / 8; //------------------------------------------ // call the allocation routine (which checks if really need to allocate) here: allocatePixels(pix, width, height, bpp); FreeImage_ConvertToRawBits(pix.pixels, bmp, width*bytesPerPixel, bpp, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK, true); // get bits }
// Takes an image from the frame buffer and compresses it int writeFrame(FIMEMORY *fiBuffer, FIBITMAP *fiImage, unsigned char imageType) { /* char msg[1024]; sprintf_s(msg, 1024, "imageType: %i", imageType); MessageBox(NULL,msg,"ADES DEBUG", MB_OK); */ imageType = 2; int errStatus = 1; u_short imageWidth, imageHeight; unsigned width, height, pitch, line; BYTE *bits; // Package image using correct compression switch(imageType) { case 0: // Send a raw frame // Get image characteristics width = FreeImage_GetWidth(fiImage); height = FreeImage_GetHeight(fiImage); pitch = FreeImage_GetPitch(fiImage); line = FreeImage_GetLine(fiImage); // Write out width and height errStatus = FreeImage_SeekMemory(fiBuffer, 0, SEEK_SET); if (errStatus != 1) break; imageWidth = htons(width); errStatus = FreeImage_WriteMemory( &imageWidth, 2, 1, fiBuffer ); if (errStatus != 1) break; imageHeight = htons(height); errStatus = FreeImage_WriteMemory( &imageHeight, 2, 1, fiBuffer ); if (errStatus != 1) break; // Write out image (convert the bitmap to raw bits, top-left pixel first) bits = (BYTE*)malloc(height * pitch); FreeImage_ConvertToRawBits(bits, fiImage, pitch, 24, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK, TRUE); errStatus = FreeImage_WriteMemory( bits, height*pitch*sizeof(BYTE), 1, fiBuffer ); free(bits); if (errStatus != 1) break; break; default: // Send a jpg frame errStatus = FreeImage_SeekMemory(fiBuffer, 0, SEEK_SET); if (errStatus != 1) break; errStatus = FreeImage_SaveToMemory(FIF_JPEG, fiImage, fiBuffer, convertToJpegFlag(imageType)); if (errStatus != 1) break; break; } // Clean up and exit return errStatus; }
//---------------------------------------------------- void putBmpIntoPixels(FIBITMAP * bmp, ofPixels &pix, bool swapForLittleEndian = true){ int width = FreeImage_GetWidth(bmp); int height = FreeImage_GetHeight(bmp); int bpp = FreeImage_GetBPP(bmp); FIBITMAP * bmpTemp = NULL; switch (bpp){ case 8: if (FreeImage_GetColorType(bmp) == FIC_PALETTE) { bmpTemp = FreeImage_ConvertTo24Bits(bmp); bmp = bmpTemp; bpp = FreeImage_GetBPP(bmp); } else { // do nothing we are grayscale } break; case 24: // do nothing we are color break; case 32: // do nothing we are colorAlpha break; default: bmpTemp = FreeImage_ConvertTo24Bits(bmp); bmp = bmpTemp; bpp = FreeImage_GetBPP(bmp); break; } int bytesPerPixel = bpp / 8; pix.allocate(width, height, bpp); FreeImage_ConvertToRawBits(pix.getPixels(), bmp, width*bytesPerPixel, bpp, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK, true); // get bits if (bmpTemp != NULL) FreeImage_Unload(bmpTemp); #ifdef TARGET_LITTLE_ENDIAN if(swapForLittleEndian) pix.swapRgb(); #endif }
const QByteArray ImageLoaderFreeImage::bits() const { const unsigned int bitsPerLine = m_widthPixels * bitsPerPixel(); const unsigned int bytesPerLine = (unsigned int)ceil(bitsPerLine/8.0); const unsigned int imageBytesCount = bytesPerLine * m_heightPixels; QByteArray result(imageBytesCount, 0); char *destination = result.data(); FreeImage_ConvertToRawBits((BYTE*)destination, m_bitmap, bytesPerLine, bitsPerPixel(), FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK, hasFreeImageVersionCorrectTopDownInConvertBits()); const unsigned long numberOfPixels = m_widthPixels * m_heightPixels; #if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR if (colorDataType() == Types::ColorTypeRGB && bitsPerPixel() == 24) { for (unsigned int pixelIndex = 0; pixelIndex < numberOfPixels; pixelIndex++) { char *pixelPtr = destination + pixelIndex*3; const char temp = pixelPtr[0]; pixelPtr[0] = pixelPtr[2]; pixelPtr[2] = temp; pixelPtr+=3; } } else if (colorDataType() == Types::ColorTypeRGBA && bitsPerPixel() == 32) { unsigned int* argbDestination = (unsigned int*)destination; for (unsigned int pixelIndex = 0; pixelIndex < numberOfPixels; pixelIndex++) { *argbDestination = qToBigEndian(*argbDestination); argbDestination++; } } else #endif // FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR if (colorDataType() == Types::ColorTypeRGB && bitsPerPixel() == 48) { // Apparently, the 48 bit data has to be reordered on Windows and ppc/i386 OSX // TODO: So maybe this swap belongs into the PDFwriter. Investigate. unsigned short* rgb48Destination = (unsigned short*)destination; const unsigned long numberOfSwaps = numberOfPixels * 3; // Words are swapped for (unsigned int pixelIndex = 0; pixelIndex < numberOfSwaps; pixelIndex++) { *rgb48Destination = qToBigEndian(*rgb48Destination); rgb48Destination++; } } return result; }
//---------------------------------------------------------------------------------------------------------------------- // //---------------------------------------------------------------------------------------------------------------------- void azImage::Initialize() { azSz szFilePath = azL("F://Dev//Aztec//Bin//Debug//Test.png"); FreeImage_Initialise(); fipImage oFreeImage; #ifdef UNICODE azBool bLoaded = (0 != oFreeImage.loadU(szFilePath)); #else // UNICODE azBool bLoaded = (0 != oFreeImage.load(szFilePath)); #endif // UNICODE azAssert(bLoaded, "Image extension or format not supported"); azAssert(oFreeImage.getBitsPerPixel() <= 32, "More than 32 BPP images not yet supported, there will be some data loss"); // Always convert to RGBA 32 bits azBool bConverted = (0 != oFreeImage.convertTo32Bits()); azAssert(bConverted, "Image recognized but we failed to convert it to 32 BPP"); m_uWidth = oFreeImage.getWidth(); m_uHeight = oFreeImage.getHeight(); m_uBpp = oFreeImage.getBitsPerPixel(); azAssert(m_uBpp == 32, "Convert didn't work properly"); azUInt uBufferSize = GetBufferSize(); m_abData = azNewArray(azByte, uBufferSize); // There is no C++ wrapping for this method. FreeImage_ConvertToRawBits(m_abData, oFreeImage, oFreeImage.getScanWidth(), m_uBpp, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK, true); oFreeImage.clear(); FreeImage_DeInitialise(); }
void TerrainHeightField::LoadFromHeightMap(const char* filename, int dstW, int dstH) { m_width = dstW; m_height = dstH; FREE_IMAGE_FORMAT ft=FreeImage_GetFileType(filename); FIBITMAP* pdata=FreeImage_Load(ft, filename); FIBITMAP* presdata = pdata; unsigned int w=FreeImage_GetWidth(pdata); unsigned int h = FreeImage_GetHeight(pdata); if (w != dstW || h != dstH) { presdata = FreeImage_Rescale(pdata, dstW, dstH); } unsigned int nPixSize = FreeImage_GetBPP(presdata) / 8; unsigned int lPitch = dstW*nPixSize; unsigned int bufferSize = lPitch*dstH; m_pData = new unsigned char[bufferSize]; FreeImage_ConvertToRawBits(m_pData, presdata, lPitch, FreeImage_GetBPP(presdata), FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK, TRUE); FreeImage_Unload(pdata); FreeImage_Unload(presdata); }
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) || (wcsstr(sFilePathName.c_str(), L".ico") != NULL) || (wcsstr(sFilePathName.c_str(), L".cur") != 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; } } }
Texture* FreeImageImageCodec::load(const RawDataContainer& data, Texture* result) { int len = (int)data.getSize(); FIMEMORY *mem = 0; FIBITMAP *img = 0; Texture *retval = 0; try { mem = FreeImage_OpenMemory(static_cast<BYTE*>(const_cast<std::uint8_t*>(data.getDataPtr())), len); if (mem == 0) throw MemoryException("Unable to open memory stream, FreeImage_OpenMemory failed"); FREE_IMAGE_FORMAT fif = FreeImage_GetFileTypeFromMemory(mem, len); if (fif == FIF_UNKNOWN) // it may be that it's TARGA or MNG { fif = FIF_TARGA; img = FreeImage_LoadFromMemory(fif, mem, 0); if (img == 0) { fif = FIF_MNG; img = FreeImage_LoadFromMemory(fif, mem, 0); } } else img = FreeImage_LoadFromMemory(fif, mem, 0); if (img == 0) throw GenericException("Unable to load image, FreeImage_LoadFromMemory failed"); FIBITMAP *newImg = FreeImage_ConvertTo32Bits(img); if (newImg == 0) throw GenericException("Unable to convert image, FreeImage_ConvertTo32Bits failed"); FreeImage_Unload(img); img = newImg; newImg = 0; // FreeImage pixel format for little-endian architecture (which CEGUI // supports) is like BGRA. We need to convert that to RGBA. // // It is now: // RED_MASK 0x00FF0000 // GREEN_MASK 0x0000FF00 // BLUE_MASK 0x000000FF // ALPHA_MASK 0xFF000000 // // It should be: // RED_MASK 0x000000FF // GREEN_MASK 0x0000FF00 // BLUE_MASK 0x00FF0000 // ALPHA_MASK 0xFF000000 unsigned int pitch = FreeImage_GetPitch(img); unsigned int height = FreeImage_GetHeight(img); unsigned int width = FreeImage_GetWidth(img); std::uint8_t *rawBuf = new std::uint8_t[width * height << 2]; // convert the bitmap to raw bits (top-left pixel first) FreeImage_ConvertToRawBits(rawBuf, img, pitch, 32, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK, true); // We need to convert pixel format a little // NB: little endian only - I think(!) #if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR for (unsigned int i = 0; i < height; ++i) { for (unsigned int j = 0; j < width; ++j) { unsigned int p = *(((unsigned int*)(rawBuf + i * pitch)) + j); unsigned int r = (p >> 16) & 0x000000FF; unsigned int b = (p << 16) & 0x00FF0000; p &= 0xFF00FF00; p |= r | b; // write the adjusted pixel back *(((unsigned int*)(rawBuf + i * pitch)) + j) = p; } } #endif FreeImage_Unload(img); img = 0; result->loadFromMemory(rawBuf, Sizef(width, height), Texture::PF_RGBA); delete [] rawBuf; retval = result; } catch (Exception&) { } if (img != 0) FreeImage_Unload(img); if (mem != 0) FreeImage_CloseMemory(mem); return retval; }
void ConvertToHeader(const char* inFile, const char* outFile, i32 posX, i32 posY, i32 sizeX, i32 sizeY, i32 numX, i32 numY, i32 colorNum, u32 transColor, const char* name, Compressor comp, LangageInterface* lang) { FIBITMAP *dib, *dib32; i32 i, j, nx, ny, bit, minX, maxX, minY, maxY, width, height, totalBytes = 0; std::string outData; RGB24 c24; GRB8 c8; u8 byte = 0; dib = LoadImage(inFile); // open and load the file using the default load option if(dib != NULL) { // Get 32 bits version dib32 = FreeImage_ConvertTo32Bits(dib); FreeImage_Unload(dib); // free the original dib i32 imageX = FreeImage_GetWidth(dib32); i32 imageY = FreeImage_GetHeight(dib32); i32 scanWidth = FreeImage_GetPitch(dib32); i32 bpp = FreeImage_GetBPP(dib32); BYTE *bits = new BYTE[scanWidth * imageY]; FreeImage_ConvertToRawBits(bits, dib32, scanWidth, 32, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK, TRUE); FreeImage_Unload(dib32); // Build header file outData += lang->Header(VERSION, name); for(ny = 0; ny < numY; ny++) { for(nx = 0; nx < numX; nx++) { // Compute bound for crop compression if(comp != COMPRESS_None) { minX = sizeX; maxX = 0; minY = sizeY; maxY = 0; for(j = 0; j < sizeY; j++) { for(i = 0; i < sizeX; i++) { i32 pixel = posX + i + (nx * sizeX) + ((posY + j + (ny * sizeY)) * imageX); u32 argb = ((u32*)bits)[pixel]; if((argb & 0xFFFFFF) != transColor) { if(i < minX) minX = i; if(i > maxX) maxX = i; if(j < minY) minY = j; if(j > maxY) maxY = j; } } } width = maxX > minX ? 1 + maxX - minX : 0; height = maxY > minY ? 1 + maxY - minY : 0; } // Print sprite header outData += lang->SpriteBegin(nx + ny * numX); if(comp == COMPRESS_Crop256) { outData += lang->Line4Bytes(u8(minX), u8(minY), u8(width), u8(height), "minX minY sizeX sizeY"); totalBytes += 4; } else if(comp == COMPRESS_Crop32) { if(width == 0 || height == 0) { outData += lang->Line1Byte(0x80, "no data"); totalBytes += 1; } else { minX >>= 3; maxX >>= 3; width = maxX - minX; minY &= 0x1F; // Clamp to 5bits (0-31) height--; height &= 0x1F; if(minX == 0 && minY == 0) { outData += lang->Line1Byte(u8(0x80 + (width << 5) + height), "sizeX(2b)|sizeY(5b)"); totalBytes += 1; } else { outData += lang->Line2Bytes(u8((minX << 5) + minY), u8(0x80 + (width << 5) + height), "minX(2b)|minY(5b) sizeX(2b)|sizeY(5b)"); totalBytes += 2; } minX *= 8; maxX = (maxX * 8) + 7; width = (width + 1) * 8; } } else if(comp == COMPRESS_Crop16) { minX &= 0x0F; // Clamp to 4bits (0-15) width &= 0x0F; minY &= 0x0F; height &= 0x0F; outData += lang->Line2Bytes(u8((minX << 4) + minY), u8(((width) << 4) + (height)), "minX|minY sizeX|sizeY"); totalBytes += 2; } else if(comp == COMPRESS_CropLine16) { outData += lang->Line1Byte(u8((minY << 4) + (height)), "minY|sizeY"); totalBytes += 1; } // Print sprite content for(j = 0; j < sizeY; j++) { if((comp == COMPRESS_None) || ((j >= minY) && (j <= maxY))) { outData += lang->LineBegin(); if(comp == COMPRESS_CropLine16) // for line-crop, we need to recompute minX&maxX for each line { minX = sizeX; maxX = 0; for(i = 0; i < sizeX; i++) { i32 pixel = posX + i + (nx * sizeX) + ((posY + j + (ny * sizeY)) * imageX); u32 argb = ((u32*)bits)[pixel]; if((argb & 0xFFFFFF) != transColor) { if(i < minX) minX = i; if(i > maxX) maxX = i; } } outData += lang->Line1Byte(u8((minX << 4) + (1 + maxX - minX)), "minX|sizeX"); } for(i = 0; i < sizeX; i++) { if((comp == COMPRESS_None) || ((i >= minX) && (i <= maxX))) { i32 pixel = posX + i + (nx * sizeX) + ((posY + j + (ny * sizeY)) * imageX); u32 argb = ((u32*)bits)[pixel]; if(colorNum == 256) { // convert to 8 bits GRB if((argb & 0xFFFFFF) == transColor) { c8 = 0; } else { c24 = RGB24(argb); c8 = GRB8(c24); if(c8 == 0) { if(c24.G > c24.R) c8 = 0x20; else c8 = 0x04; } } outData += lang->Data8Bits((u8)c8); totalBytes++; } else if(colorNum == 16) { } else if(colorNum == 2) { bit = pixel & 0x7; if((argb & 0xFFFFFF) != transColor) byte |= 1 << (7 - bit); if((pixel & 0x7) == 0x7) { outData += lang->Data1Bit(byte); totalBytes++; byte = 0; } } } } outData += lang->LineEnd(); } } } }
//---------------------------------------------------- bool ofImage::loadImageIntoPixels(string fileName, ofPixels &pix){ int width, height, bpp; fileName = ofToDataPath(fileName); bool bLoaded = false; FIBITMAP * bmp = NULL; FREE_IMAGE_FORMAT fif = FIF_UNKNOWN; fif = FreeImage_GetFileType(fileName.c_str(), 0); if(fif == FIF_UNKNOWN) { // or guess via filename fif = FreeImage_GetFIFFromFilename(fileName.c_str()); } if((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsReading(fif)) { bmp = FreeImage_Load(fif, fileName.c_str(), 0); bLoaded = true; if (bmp == NULL){ bLoaded = false; } } //----------------------------- if (bLoaded ){ width = FreeImage_GetWidth(bmp); height = FreeImage_GetHeight(bmp); bpp = FreeImage_GetBPP(bmp); bool bPallette = (FreeImage_GetColorType(bmp) == FIC_PALETTE); switch (bpp){ case 8: if (bPallette) { FIBITMAP * bmpTemp = FreeImage_ConvertTo24Bits(bmp); if (bmp != NULL) FreeImage_Unload(bmp); bmp = bmpTemp; bpp = FreeImage_GetBPP(bmp); } else { // do nothing we are grayscale } break; case 24: // do nothing we are color break; case 32: // do nothing we are colorAlpha break; default: FIBITMAP * bmpTemp = FreeImage_ConvertTo24Bits(bmp); if (bmp != NULL) FreeImage_Unload(bmp); bmp = bmpTemp; bpp = FreeImage_GetBPP(bmp); } int byteCount = bpp / 8; //------------------------------------------ // call the allocation routine (which checks if really need to allocate) here: allocatePixels(pix, width, height, bpp); FreeImage_ConvertToRawBits(pix.pixels, bmp, width*byteCount, bpp, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK, true); // get bits //------------------------------------------ // RGB or RGBA swap // this can be done with some ill pointer math. // anyone game? // #ifdef TARGET_LITTLE_ENDIAN if (byteCount != 1) swapRgb(pix); #endif //------------------------------------------ } else { width = height = bpp = 0; } if (bmp != NULL){ FreeImage_Unload(bmp); } return bLoaded; }
bool ofMemoryImage::loadFromDataIntoPixels(const unsigned char * datasource, int len, ofPixels &pix ) { int width, height, bpp; bool bLoaded = false; FIBITMAP * bmp = NULL; FIMEMORY *hmem = NULL; hmem = FreeImage_OpenMemory((Byte *)datasource, len); if (hmem == NULL) { printf("couldn't create memory handle! \n"); } cout << "memory open " << endl; //get the file type! FREE_IMAGE_FORMAT fif = FreeImage_GetFileTypeFromMemory(hmem); cout << "image format "<< fif << endl; if((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsReading(fif)) { bmp = FreeImage_LoadFromMemory(fif, hmem, 0); if (bmp == NULL) { cout << "we could not load from memory!! " << endl; } else { FreeImage_CloseMemory(hmem); } bLoaded = true; if (bmp == NULL) { bLoaded = false; cout << "we are not loadded " << endl; } } if (bLoaded ) { width = FreeImage_GetWidth(bmp); height = FreeImage_GetHeight(bmp); bpp = FreeImage_GetBPP(bmp); bool bPallette = (FreeImage_GetColorType(bmp) == FIC_PALETTE); switch (bpp) { case 8: if (bPallette) { FIBITMAP * bmpTemp = FreeImage_ConvertTo24Bits(bmp); if (bmp != NULL) FreeImage_Unload(bmp); bmp = bmpTemp; bpp = FreeImage_GetBPP(bmp); } else { // do nothing we are grayscale } break; case 24: // do nothing we are color break; case 32: // do nothing we are colorAlpha break; default: FIBITMAP * bmpTemp = FreeImage_ConvertTo24Bits(bmp); if (bmp != NULL) FreeImage_Unload(bmp); bmp = bmpTemp; bpp = FreeImage_GetBPP(bmp); } int byteCount = bpp / 8; //------------------------------------------ // call the allocation routine (which checks if really need to allocate) here: allocatePixels(pix, width, height, bpp); FreeImage_ConvertToRawBits(pix.pixels, bmp, width*byteCount, bpp, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK, false); // get bits //------------------------------------------ // RGB or RGBA swap // this can be done with some ill pointer math. // anyone game? // #ifdef TARGET_LITTLE_ENDIAN if (byteCount != 1) swapRgb(pix); #endif //------------------------------------------ } else { width = height = bpp = 0; } if (bmp != NULL) { FreeImage_Unload(bmp); } cout << bLoaded << endl; return bLoaded; }
Texture* loadTexture(const std::string& filename, bool useCompression) { std::string _loggerCat = "loadTexture"; #if defined( GHOUL_USE_DEVIL ) ilInit(); iluInit(); //ilOriginFunc(IL_ORIGIN_LOWER_LEFT); //ilEnable(IL_ORIGIN_SET); ILboolean loadSuccess = ilLoadImage(filename.c_str()); if (!loadSuccess) { ILenum error = ilGetError(); LERROR("Error while loading image '" << filename << "': " << iluErrorString(error)); return nullptr; } ILint imageFormat = ilGetInteger(IL_IMAGE_FORMAT); ILint imageType = ilGetInteger(IL_IMAGE_TYPE); ILint imageByte = ilGetInteger(IL_IMAGE_BYTES_PER_PIXEL); ILint width = ilGetInteger(IL_IMAGE_WIDTH); ILint height = ilGetInteger(IL_IMAGE_HEIGHT); ILint depth = ilGetInteger(IL_IMAGE_DEPTH); // Copy data from common data store to own address space ILubyte* data = new ILubyte[width * height * imageByte]; ilCopyPixels(0, 0, 0, width, height, 1, imageFormat, IL_UNSIGNED_BYTE, data); glm::size3_t size(width, height, depth); Texture::Format format; switch (imageFormat) { case IL_RGB: format = Texture::Format::RGB; break; case IL_RGBA: format = Texture::Format::RGBA; break; case IL_BGR: format = Texture::Format::BGR; break; case IL_BGRA: format = Texture::Format::BGRA; break; default: LERROR("Could not read image file '" << filename << "' of format: '" << imageFormat << "'"); return nullptr; } GLenum type; switch (imageType) { case IL_UNSIGNED_BYTE: type = GL_UNSIGNED_BYTE; break; case IL_BYTE: type = GL_BYTE; break; case IL_UNSIGNED_SHORT: type = GL_UNSIGNED_SHORT; break; case IL_SHORT: type = GL_SHORT; break; case IL_UNSIGNED_INT: type = GL_UNSIGNED_INT; break; case IL_INT: type = GL_INT; break; case IL_FLOAT: type = GL_FLOAT; break; default: LERROR("Could not read image file '" << filename << "' of data type: '" << imageType << "'"); return nullptr; } #elif defined( GHOUL_USE_FREEIMAGE) //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); //OpenGL's image ID to map to GLuint gl_texID; //check the file signature and deduce its format fif = FreeImage_GetFileType(filename.c_str(), 0); //if still unknown, try to guess the file format from the file extension if (fif == FIF_UNKNOWN) fif = FreeImage_GetFIFFromFilename(filename.c_str()); //if still unkown, return failure if (fif == FIF_UNKNOWN) return nullptr; //check that the plugin has reading capabilities and load the file if (FreeImage_FIFSupportsReading(fif)) dib = FreeImage_Load(fif, filename.c_str()); //if the image failed to load, return failure if (!dib) return nullptr; //retrieve the image data bits = FreeImage_GetBits(dib); //get the image width and height width = FreeImage_GetWidth(dib); height = FreeImage_GetHeight(dib); glm::size3_t size(width, height, 1); //if this somehow one of these failed (they shouldn't), return failure if ((bits == 0) || (width == 0) || (height == 0)) return nullptr; FREE_IMAGE_TYPE imageType = FreeImage_GetImageType(dib); FREE_IMAGE_COLOR_TYPE colorType = FreeImage_GetColorType(dib); BITMAPINFOHEADER* infoheader = FreeImage_GetInfoHeader(dib); /* FIT_UNKNOWN = 0, // unknown type FIT_BITMAP = 1, // standard image : 1-, 4-, 8-, 16-, 24-, 32-bit FIT_UINT16 = 2, // array of unsigned short : unsigned 16-bit FIT_INT16 = 3, // array of short : signed 16-bit FIT_UINT32 = 4, // array of unsigned long : unsigned 32-bit FIT_INT32 = 5, // array of long : signed 32-bit FIT_FLOAT = 6, // array of float : 32-bit IEEE floating point FIT_DOUBLE = 7, // array of double : 64-bit IEEE floating point FIT_COMPLEX = 8, // array of FICOMPLEX : 2 x 64-bit IEEE floating point FIT_RGB16 = 9, // 48-bit RGB image : 3 x 16-bit FIT_RGBA16 = 10, // 64-bit RGBA image : 4 x 16-bit FIT_RGBF = 11, // 96-bit RGB float image : 3 x 32-bit IEEE floating point FIT_RGBAF = 12 // 128-bit RGBA float image : 4 x 32-bit IEEE floating point FI_ENUM(FREE_IMAGE_COLOR_TYPE) { FIC_MINISWHITE = 0, // min value is white FIC_MINISBLACK = 1, // min value is black FIC_RGB = 2, // RGB color model FIC_PALETTE = 3, // color map indexed FIC_RGBALPHA = 4, // RGB color model with alpha channel FIC_CMYK = 5 // CMYK color model }; */ if (imageType != FIT_BITMAP) { LERROR("Could not read image file '" << filename << "' of data type: '" << imageType << "'"); return nullptr; } GLenum type = GL_UNSIGNED_BYTE; Texture::Format format; switch (colorType) { case FIC_RGB: format = Texture::Format::RGB; break; case FIC_RGBALPHA: format = Texture::Format::RGBA; break; default: LERROR("Could not read image file '" << filename << "' of color type: '" << colorType << "'"); return nullptr; } int imageByte = FreeImage_GetBPP(dib); unsigned int pitch = FreeImage_GetPitch(dib); BYTE* data = new BYTE[width * height * imageByte/8]; FreeImage_ConvertToRawBits(data, dib, pitch, imageByte, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK, TRUE); FreeImage_Unload(dib); // Swap red and blue channels, cannot use GL_BGR in OpenGL core profile for (size_t i = 0; i < width * height; ++i) { size_t index = i * imageByte / 8; std::swap(data[index], data[index + 2]); } #endif Texture* result; if (useCompression) { switch (format) { case Texture::Format::RGB: result = new Texture(data, size, format, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, type); break; case Texture::Format::RGBA: result = new Texture(data, size, format, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, type); break; default: LERROR("Could not assign compressed format for: '" << GLint(format) << "'. Using no compression instead"); result = new Texture(data, size, format, static_cast<int>(format), type); break; } } else result = new Texture(data, size, format, static_cast<int>(format), type); return result; }