void ofImage_<PixelType>::changeTypeOfPixels(ofPixels_<PixelType> &pix, ofImageType newType){ int oldType = pix.getImageType(); if (oldType == newType) { return; // no need to reallocate } FIBITMAP * bmp = getBmpFromPixels(pix); FIBITMAP * convertedBmp = nullptr; switch (newType){ case OF_IMAGE_GRAYSCALE: convertedBmp = FreeImage_ConvertToGreyscale(bmp); break; case OF_IMAGE_COLOR: convertedBmp = FreeImage_ConvertTo24Bits(bmp); break; case OF_IMAGE_COLOR_ALPHA: convertedBmp = FreeImage_ConvertTo32Bits(bmp); break; default: ofLogError("ofImage") << "changeTypeOfPixels(): unknown image type: " << newType; break; } putBmpIntoPixels(convertedBmp, pix, false); if (bmp != nullptr) { FreeImage_Unload(bmp); } if (convertedBmp != nullptr) { FreeImage_Unload(convertedBmp); } }
BOOL fipImage::convertToGrayscale() { if(_dib) { FIBITMAP *dib8 = FreeImage_ConvertToGreyscale(_dib); return replace(dib8); } return FALSE; }
//---------------------------------------------------- void ofImage::changeTypeOfPixels(ofPixels &pix, ofImageType newType){ if (pix.getImageType() == newType) return; FIBITMAP * bmp = getBmpFromPixels(pix); FIBITMAP * convertedBmp = NULL; // check if we need to reallocate the texture. bool bNeedNewTexture = false; int oldType = pix.getImageType(); if (newType > oldType){ bNeedNewTexture = true; } // new type ! switch (newType){ //------------------------------------ case OF_IMAGE_GRAYSCALE: convertedBmp = FreeImage_ConvertToGreyscale(bmp); break; //------------------------------------ case OF_IMAGE_COLOR: convertedBmp = FreeImage_ConvertTo24Bits(bmp); if (bNeedNewTexture){ tex.clear(); tex.allocate(pixels.getWidth(), pixels.getHeight(), GL_RGB); } break; //------------------------------------ case OF_IMAGE_COLOR_ALPHA: convertedBmp = FreeImage_ConvertTo32Bits(bmp); if (bNeedNewTexture){ tex.clear(); tex.allocate(pixels.getWidth(), pixels.getHeight(), GL_RGBA); } break; default: ofLog(OF_LOG_ERROR,"ofImage: format not supported"); } putBmpIntoPixels(convertedBmp, pix, false); if (bmp != NULL) FreeImage_Unload(bmp); if (convertedBmp != NULL) FreeImage_Unload(convertedBmp); }
//---------------------------------------------------- void ofImage::changeTypeOfPixels(ofPixels &pix, int newType){ if (pix.ofImageType == newType) return; FIBITMAP * bmp = getBmpFromPixels(pix); FIBITMAP * convertedBmp = NULL; // check if we need to reallocate the texture. bool bNeedNewTexture = false; int oldType = pix.ofImageType; if (newType > oldType){ bNeedNewTexture = true; } // new type ! switch (newType){ //------------------------------------ case OF_IMAGE_GRAYSCALE: convertedBmp = FreeImage_ConvertToGreyscale(bmp); break; //------------------------------------ case OF_IMAGE_COLOR: convertedBmp = FreeImage_ConvertTo24Bits(bmp); if (bNeedNewTexture){ tex.clear(); tex.allocate(myPixels.width, myPixels.height, GL_RGB); } break; //------------------------------------ case OF_IMAGE_COLOR_ALPHA: convertedBmp = FreeImage_ConvertTo32Bits(bmp); if (bNeedNewTexture){ tex.clear(); tex.allocate(myPixels.width, myPixels.height, GL_RGBA); } break; } putBmpIntoPixels(convertedBmp, pix); if (bmp != NULL) FreeImage_Unload(bmp); if (convertedBmp != NULL) FreeImage_Unload(convertedBmp); }
/* * Changes the handle to a grayscale image */ HBITMAP MakeGrayscale(HBITMAP hBitmap) { if (hBitmap) { FIBITMAP *dib = FreeImage_CreateDIBFromHBITMAP(hBitmap); if (dib) { FIBITMAP *dib_new = FreeImage_ConvertToGreyscale(dib); FreeImage_Unload(dib); if (dib_new) { DeleteObject(hBitmap); HBITMAP hbm_new = FreeImage_CreateHBITMAPFromDIB(dib_new); FreeImage_Unload(dib_new); return hbm_new; } } } return hBitmap; }
void ofImage_<PixelType>::changeTypeOfPixels(ofPixels_<PixelType> &pix, ofImageType newType){ int oldType = pix.getImageType(); if (oldType == newType) { return; // no need to reallocate } FIBITMAP * bmp = getBmpFromPixels(pix); FIBITMAP * convertedBmp = NULL; switch (newType){ case OF_IMAGE_GRAYSCALE: convertedBmp = FreeImage_ConvertToGreyscale(bmp); break; case OF_IMAGE_COLOR: convertedBmp = FreeImage_ConvertTo24Bits(bmp); break; case OF_IMAGE_COLOR_ALPHA: convertedBmp = FreeImage_ConvertTo32Bits(bmp); break; default: ofLogError("ofImage") << "changeTypeOfPixels(): unknown image type: " << newType; break; } putBmpIntoPixels(convertedBmp, pix, false); if (bmp != NULL) { FreeImage_Unload(bmp); } if (convertedBmp != NULL) { FreeImage_Unload(convertedBmp); } if(bUseTexture){ // always reallocate the texture. if ofTexture doesn't need reallocation, // it doesn't have to. but it needs to change the internal format. tex.allocate(pixels.getWidth(), pixels.getHeight(), ofGetGlInternalFormat(pixels)); if(ofGetGLProgrammableRenderer() && (pixels.getNumChannels()==1 || pixels.getNumChannels()==2)){ tex.setRGToRGBASwizzles(true); } } }
void ofImage_<PixelType>::changeTypeOfPixels(ofPixels_<PixelType> &pix, ofImageType newType){ int oldType = pix.getImageType(); if (oldType == newType) { return; // no need to reallocate } FIBITMAP * bmp = getBmpFromPixels(pix); FIBITMAP * convertedBmp = NULL; switch (newType){ case OF_IMAGE_GRAYSCALE: convertedBmp = FreeImage_ConvertToGreyscale(bmp); break; case OF_IMAGE_COLOR: convertedBmp = FreeImage_ConvertTo24Bits(bmp); break; case OF_IMAGE_COLOR_ALPHA: convertedBmp = FreeImage_ConvertTo32Bits(bmp); break; default: ofLog(OF_LOG_ERROR, "changeTypeOfPixels: format not supported"); break; } putBmpIntoPixels(convertedBmp, pix, false); if (bmp != NULL) { FreeImage_Unload(bmp); } if (convertedBmp != NULL) { FreeImage_Unload(convertedBmp); } if(bUseTexture){ // always reallocate the texture. if ofTexture doesn't need reallocation, // it doesn't have to. but it needs to change the internal format. tex.allocate(pixels.getWidth(), pixels.getHeight(), ofGetGlInternalFormat(pixels)); } }
/** * This method converts the image to grayscale. * * @return true if the image was converted to grayscale, else false */ bool fipImage::convertToGrayscale(){ pImageData = FreeImage_ConvertToGreyscale( pImageData ); return isGrayscale(); }
static FIMULTIBITMAP* ReadFromAvi(const char* filename) { int err=0; AVIFileInit(); PAVISTREAM pavi; // Handle To An Open Stream if( AVIStreamOpenFromFile(&pavi, filename, streamtypeVIDEO, 0, OF_READ, NULL) != 0) { AVIFileExit(); return NULL; } AVISTREAMINFO psi; // Pointer To A Structure Containing Stream Info AVIStreamInfo(pavi, &psi, sizeof(psi)); // Reads Information About The Stream Into psi int width = psi.rcFrame.right-psi.rcFrame.left; // Width Is Right Side Of Frame Minus Left int height = psi.rcFrame.bottom-psi.rcFrame.top; // Height Is Bottom Of Frame Minus Top int frameCount = AVIStreamLength(pavi); // The Last Frame Of The Stream double mpf = AVIStreamSampleToTime(pavi, frameCount) / (double)frameCount; // Calculate Rough Milliseconds Per Frame PGETFRAME pgf = AVIStreamGetFrameOpen(pavi, NULL); // Create The PGETFRAME Using Our Request Mode if (pgf==NULL) { // An Error Occurred Opening The Frame error("Failed To Open frame from AVI"); } //HDC hdc = GetDC(0); HDRAWDIB hdd = DrawDibOpen(); // Handle For Our Dib BITMAPINFOHEADER bmih; // Header Information For DrawDibDraw Decoding bmih.biSize = sizeof (BITMAPINFOHEADER); // Size Of The BitmapInfoHeader bmih.biPlanes = 1; // Bitplanes bmih.biBitCount = 24; // Bits Format We Want (24 Bit, 3 Bytes) bmih.biWidth = width; // Width We Want (256 Pixels) bmih.biHeight = height; // Height We Want (256 Pixels) bmih.biCompression = BI_RGB; // Requested Mode = RGB char *data; // Pointer To Texture Data HBITMAP hBitmap = CreateDIBSection(hdc, (BITMAPINFO*)(&bmih), DIB_RGB_COLORS, (void**)(&data), NULL, NULL); SelectObject(hdc, hBitmap); // Select hBitmap Into Our Device Context (hdc) // create a new freeimage anim someError=false; FIMULTIBITMAP* ret = FreeImage_OpenMultiBitmap(FIF_TIFF, "temp.tiff", TRUE, FALSE); if (!ret || someError) { error("Couldnt create multibitmap"); } for (int frame=0; frame<frameCount; frame++) { fprintf(stderr, "Loading frame %i\n", frame); // Grab Data From The AVI Stream LPBITMAPINFOHEADER lpbi = (LPBITMAPINFOHEADER)AVIStreamGetFrame(pgf, frame); // Pointer To Data Returned By AVIStreamGetFrame // (Skip The Header Info To Get To The Data) char* pdata = (char *)lpbi + lpbi->biSize + lpbi->biClrUsed * sizeof(RGBQUAD); // Convert Data To Requested Bitmap Format DrawDibDraw(hdd, hdc, 0, 0, width, height, lpbi, pdata, 0, 0, width, height, 0); // copy into the freeimage thing FIBITMAP* fiBitmap = FreeImage_ConvertFromRawBits((BYTE*)data, width, height, width*3, 24, 0xFF0000, 0x00FF00, 0x0000FF); /* BYTE* src = (BYTE*)data; for (int y=0; y<height; y++) { BYTE* dst = FreeImage_GetScanLine(fiBitmap, y); for (int x=0; x<width; x++) { //src++; *dst++ = *src++; *dst++ = *src++; *dst++ = *src++; } } */ FIBITMAP* grayBitmap = FreeImage_ConvertToGreyscale(fiBitmap); FreeImage_Unload(fiBitmap); FreeImage_AppendPage(ret, grayBitmap); } FreeImage_CloseMultiBitmap(ret); ret = FreeImage_OpenMultiBitmap(FIF_TIFF, "temp.tiff", FALSE, TRUE); DeleteObject(hBitmap); // Delete The Device Dependant Bitmap Object DrawDibClose(hdd); // Closes The DrawDib Device Context AVIStreamGetFrameClose(pgf); // Deallocates The GetFrame Resources AVIStreamRelease(pavi); // Release The Stream AVIFileExit(); // Release The File return ret; }
virtual bool load(const std::string& filename, Array &lat) { FREE_IMAGE_FORMAT type = FreeImage_GetFIFFromFilename(filename.c_str()); if(type == FIF_UNKNOWN) { AL_WARN("image format not recognized: %s", filename.c_str()); return false; } if(!FreeImage_FIFSupportsReading(type)) { AL_WARN("image format not supported: %s", filename.c_str()); return false; } destroy(); mImage = FreeImage_Load(type, filename.c_str(), 0); if (mImage == NULL) { AL_WARN("image failed to load: %s", filename.c_str()); return false; } FREE_IMAGE_COLOR_TYPE colorType = FreeImage_GetColorType(mImage); switch(colorType) { case FIC_MINISBLACK: case FIC_MINISWHITE: { FIBITMAP *res = FreeImage_ConvertToGreyscale(mImage); FreeImage_Unload(mImage); mImage = res; } break; case FIC_PALETTE: { if(FreeImage_IsTransparent(mImage)) { FIBITMAP *res = FreeImage_ConvertTo32Bits(mImage); FreeImage_Unload(mImage); mImage = res; } else { FIBITMAP *res = FreeImage_ConvertTo24Bits(mImage); FreeImage_Unload(mImage); mImage = res; } } break; case FIC_CMYK: { AL_WARN("CMYK images currently not supported"); return false; } break; default: break; } // flip vertical for OpenGL: //FreeImage_FlipVertical(mImage); //Freeimage is not tightly packed, so we use //a custom method instead of one of the Matrix //utility methods int planes = getPlanes(); AlloTy ty = getDataType(); int w, h; getDim(w, h); lat.format(planes, ty, w, h); Image::Format format = Image::getFormat(planes); switch(format) { case Image::LUMINANCE: { char *o_pix = (char *)(lat.data.ptr); int rowstride = lat.header.stride[1]; for(unsigned j = 0; j < lat.header.dim[1]; ++j) { char *pix = (char *)FreeImage_GetScanLine(mImage, j); memcpy(o_pix, pix, rowstride); o_pix += rowstride; } } break; case Image::RGB: { switch(lat.header.type) { case AlloUInt8Ty: { char *bp = (char *)(lat.data.ptr); int rowstride = lat.header.stride[1]; for(unsigned j = 0; j < lat.header.dim[1]; ++j) { RGBTRIPLE * pix = (RGBTRIPLE *)FreeImage_GetScanLine(mImage, j); Image::RGBPix<uint8_t> *o_pix = (Image::RGBPix<uint8_t> *)(bp + j*rowstride); for(unsigned i=0; i < lat.header.dim[0]; ++i) { o_pix->r = pix->rgbtRed; o_pix->g = pix->rgbtGreen; o_pix->b = pix->rgbtBlue; ++pix; ++o_pix; } } } break; case AlloFloat32Ty: { char *o_pix = (char *)(lat.data.ptr); int rowstride = lat.header.stride[1]; for(unsigned j = 0; j < lat.header.dim[1]; ++j) { char *pix = (char *)FreeImage_GetScanLine(mImage, j); memcpy(o_pix, pix, rowstride); o_pix += rowstride; } } break; default: break; } } break; case Image::RGBA: { switch(lat.header.type) { case AlloUInt8Ty: { char *bp = (char *)(lat.data.ptr); int rowstride = lat.header.stride[1]; for(unsigned j = 0; j < lat.header.dim[1]; ++j) { RGBQUAD *pix = (RGBQUAD *)FreeImage_GetScanLine(mImage, j); Image::RGBAPix<uint8_t> *o_pix = (Image::RGBAPix<uint8_t> *)(bp + j*rowstride); for(unsigned i=0; i < lat.header.dim[0]; ++i) { o_pix->r = pix->rgbRed; o_pix->g = pix->rgbGreen; o_pix->b = pix->rgbBlue; o_pix->a = pix->rgbReserved; ++pix; ++o_pix; } } } break; case AlloFloat32Ty: { char *o_pix = (char *)(lat.data.ptr); int rowstride = lat.header.stride[1]; for(unsigned j = 0; j < lat.header.dim[1]; ++j) { char *pix = (char *)FreeImage_GetScanLine(mImage, j); memcpy(o_pix, pix, rowstride); o_pix += rowstride; } } break; default: break; } } break; default: AL_WARN("image data not understood"); destroy(); return false; } return true; }
//--------------------------------------------------------------------- Codec::DecodeResult FreeImageCodec::decode(DataStreamPtr& input) const { // Set error handler FreeImage_SetOutputMessage(FreeImageLoadErrorHandler); // Buffer stream into memory (TODO: override IO functions instead?) MemoryDataStream memStream(input, true); FIMEMORY* fiMem = FreeImage_OpenMemory(memStream.getPtr(), static_cast<DWORD>(memStream.size())); FIBITMAP* fiBitmap = FreeImage_LoadFromMemory( (FREE_IMAGE_FORMAT)mFreeImageType, fiMem); if (!fiBitmap) { OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, "Error decoding image", "FreeImageCodec::decode"); } ImageData* imgData = OGRE_NEW ImageData(); MemoryDataStreamPtr output; imgData->depth = 1; // only 2D formats handled by this codec imgData->width = FreeImage_GetWidth(fiBitmap); imgData->height = FreeImage_GetHeight(fiBitmap); imgData->num_mipmaps = 0; // no mipmaps in non-DDS imgData->flags = 0; // Must derive format first, this may perform conversions FREE_IMAGE_TYPE imageType = FreeImage_GetImageType(fiBitmap); FREE_IMAGE_COLOR_TYPE colourType = FreeImage_GetColorType(fiBitmap); unsigned bpp = FreeImage_GetBPP(fiBitmap); switch(imageType) { case FIT_UNKNOWN: case FIT_COMPLEX: case FIT_UINT32: case FIT_INT32: case FIT_DOUBLE: default: OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Unknown or unsupported image format", "FreeImageCodec::decode"); break; case FIT_BITMAP: // Standard image type // Perform any colour conversions for greyscale if (colourType == FIC_MINISWHITE || colourType == FIC_MINISBLACK) { FIBITMAP* newBitmap = FreeImage_ConvertToGreyscale(fiBitmap); // free old bitmap and replace FreeImage_Unload(fiBitmap); fiBitmap = newBitmap; // get new formats bpp = FreeImage_GetBPP(fiBitmap); colourType = FreeImage_GetColorType(fiBitmap); } // Perform any colour conversions for RGB else if (bpp < 8 || colourType == FIC_PALETTE || colourType == FIC_CMYK) { FIBITMAP* newBitmap = NULL; if (FreeImage_IsTransparent(fiBitmap)) { // convert to 32 bit to preserve the transparency // (the alpha byte will be 0 if pixel is transparent) newBitmap = FreeImage_ConvertTo32Bits(fiBitmap); } else { // no transparency - only 3 bytes are needed newBitmap = FreeImage_ConvertTo24Bits(fiBitmap); } // free old bitmap and replace FreeImage_Unload(fiBitmap); fiBitmap = newBitmap; // get new formats bpp = FreeImage_GetBPP(fiBitmap); colourType = FreeImage_GetColorType(fiBitmap); } // by this stage, 8-bit is greyscale, 16/24/32 bit are RGB[A] switch(bpp) { case 8: imgData->format = PF_L8; break; case 16: // Determine 555 or 565 from green mask // cannot be 16-bit greyscale since that's FIT_UINT16 if(FreeImage_GetGreenMask(fiBitmap) == FI16_565_GREEN_MASK) { imgData->format = PF_R5G6B5; } else { // FreeImage doesn't support 4444 format so must be 1555 imgData->format = PF_A1R5G5B5; } break; case 24: // FreeImage differs per platform // PF_BYTE_BGR[A] for little endian (== PF_ARGB native) // PF_BYTE_RGB[A] for big endian (== PF_RGBA native) #if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_RGB imgData->format = PF_BYTE_RGB; #else imgData->format = PF_BYTE_BGR; #endif break; case 32: #if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_RGB imgData->format = PF_BYTE_RGBA; #else imgData->format = PF_BYTE_BGRA; #endif break; }; break; case FIT_UINT16: case FIT_INT16: // 16-bit greyscale imgData->format = PF_L16; break; case FIT_FLOAT: // Single-component floating point data imgData->format = PF_FLOAT32_R; break; case FIT_RGB16: imgData->format = PF_SHORT_RGB; break; case FIT_RGBA16: imgData->format = PF_SHORT_RGBA; break; case FIT_RGBF: imgData->format = PF_FLOAT32_RGB; break; case FIT_RGBAF: imgData->format = PF_FLOAT32_RGBA; break; }; unsigned char* srcData = FreeImage_GetBits(fiBitmap); unsigned srcPitch = FreeImage_GetPitch(fiBitmap); // Final data - invert image and trim pitch at the same time size_t dstPitch = imgData->width * PixelUtil::getNumElemBytes(imgData->format); imgData->size = dstPitch * imgData->height; // Bind output buffer output.bind(OGRE_NEW MemoryDataStream(imgData->size)); uchar* pSrc; uchar* pDst = output->getPtr(); for (size_t y = 0; y < imgData->height; ++y) { pSrc = srcData + (imgData->height - y - 1) * srcPitch; memcpy(pDst, pSrc, dstPitch); pDst += dstPitch; } FreeImage_Unload(fiBitmap); FreeImage_CloseMemory(fiMem); DecodeResult ret; ret.first = output; ret.second = CodecDataPtr(imgData); return ret; }
//--------------------------------------------------------------------- FIBITMAP* FreeImageCodec::encode(MemoryDataStreamPtr& input, CodecDataPtr& pData) const { // Set error handler FreeImage_SetOutputMessage(FreeImageSaveErrorHandler); FIBITMAP* ret = 0; ImageData* pImgData = static_cast< ImageData * >( pData.getPointer() ); PixelBox src(pImgData->width, pImgData->height, pImgData->depth, pImgData->format, input->getPtr()); // The required format, which will adjust to the format // actually supported by FreeImage. PixelFormat requiredFormat = pImgData->format; // determine the settings FREE_IMAGE_TYPE imageType; PixelFormat determiningFormat = pImgData->format; switch(determiningFormat) { case PF_R5G6B5: case PF_B5G6R5: case PF_R8G8B8: case PF_B8G8R8: case PF_A8R8G8B8: case PF_X8R8G8B8: case PF_A8B8G8R8: case PF_X8B8G8R8: case PF_B8G8R8A8: case PF_R8G8B8A8: case PF_A4L4: case PF_BYTE_LA: case PF_R3G3B2: case PF_A4R4G4B4: case PF_A1R5G5B5: case PF_A2R10G10B10: case PF_A2B10G10R10: // I'd like to be able to use r/g/b masks to get FreeImage to load the data // in it's existing format, but that doesn't work, FreeImage needs to have // data in RGB[A] (big endian) and BGR[A] (little endian), always. if (PixelUtil::hasAlpha(determiningFormat)) { #if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_RGB requiredFormat = PF_BYTE_RGBA; #else requiredFormat = PF_BYTE_BGRA; #endif } else { #if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_RGB requiredFormat = PF_BYTE_RGB; #else requiredFormat = PF_BYTE_BGR; #endif } // fall through case PF_L8: case PF_A8: imageType = FIT_BITMAP; break; case PF_L16: imageType = FIT_UINT16; break; case PF_SHORT_GR: requiredFormat = PF_SHORT_RGB; // fall through case PF_SHORT_RGB: imageType = FIT_RGB16; break; case PF_SHORT_RGBA: imageType = FIT_RGBA16; break; case PF_FLOAT16_R: requiredFormat = PF_FLOAT32_R; // fall through case PF_FLOAT32_R: imageType = FIT_FLOAT; break; case PF_FLOAT16_GR: case PF_FLOAT16_RGB: case PF_FLOAT32_GR: requiredFormat = PF_FLOAT32_RGB; // fall through case PF_FLOAT32_RGB: imageType = FIT_RGBF; break; case PF_FLOAT16_RGBA: requiredFormat = PF_FLOAT32_RGBA; // fall through case PF_FLOAT32_RGBA: imageType = FIT_RGBAF; break; default: OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Invalid image format", "FreeImageCodec::encode"); }; // Check support for this image type & bit depth if (!FreeImage_FIFSupportsExportType((FREE_IMAGE_FORMAT)mFreeImageType, imageType) || !FreeImage_FIFSupportsExportBPP((FREE_IMAGE_FORMAT)mFreeImageType, (int)PixelUtil::getNumElemBits(requiredFormat))) { // Ok, need to allocate a fallback // Only deal with RGBA -> RGB for now switch (requiredFormat) { case PF_BYTE_RGBA: requiredFormat = PF_BYTE_RGB; break; case PF_BYTE_BGRA: requiredFormat = PF_BYTE_BGR; break; default: break; }; } bool conversionRequired = false; unsigned char* srcData = input->getPtr(); // Check BPP unsigned bpp = static_cast<unsigned>(PixelUtil::getNumElemBits(requiredFormat)); if (!FreeImage_FIFSupportsExportBPP((FREE_IMAGE_FORMAT)mFreeImageType, (int)bpp)) { if (bpp == 32 && PixelUtil::hasAlpha(pImgData->format) && FreeImage_FIFSupportsExportBPP((FREE_IMAGE_FORMAT)mFreeImageType, 24)) { // drop to 24 bit (lose alpha) #if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_RGB requiredFormat = PF_BYTE_RGB; #else requiredFormat = PF_BYTE_BGR; #endif bpp = 24; } else if (bpp == 128 && PixelUtil::hasAlpha(pImgData->format) && FreeImage_FIFSupportsExportBPP((FREE_IMAGE_FORMAT)mFreeImageType, 96)) { // drop to 96-bit floating point requiredFormat = PF_FLOAT32_RGB; } } PixelBox convBox(pImgData->width, pImgData->height, 1, requiredFormat); if (requiredFormat != pImgData->format) { conversionRequired = true; // Allocate memory convBox.data = OGRE_ALLOC_T(uchar, convBox.getConsecutiveSize(), MEMCATEGORY_GENERAL); // perform conversion and reassign source PixelBox src(pImgData->width, pImgData->height, 1, pImgData->format, input->getPtr()); PixelUtil::bulkPixelConversion(src, convBox); srcData = static_cast<unsigned char*>(convBox.data); } ret = FreeImage_AllocateT( imageType, static_cast<int>(pImgData->width), static_cast<int>(pImgData->height), bpp); if (!ret) { if (conversionRequired) OGRE_FREE(convBox.data, MEMCATEGORY_GENERAL); OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "FreeImage_AllocateT failed - possibly out of memory. ", __FUNCTION__); } if (requiredFormat == PF_L8 || requiredFormat == PF_A8) { // Must explicitly tell FreeImage that this is greyscale by setting // a "grey" palette (otherwise it will save as a normal RGB // palettized image). FIBITMAP *tmp = FreeImage_ConvertToGreyscale(ret); FreeImage_Unload(ret); ret = tmp; } size_t dstPitch = FreeImage_GetPitch(ret); size_t srcPitch = pImgData->width * PixelUtil::getNumElemBytes(requiredFormat); // Copy data, invert scanlines and respect FreeImage pitch uchar* pSrc; uchar* pDst = FreeImage_GetBits(ret); for (size_t y = 0; y < pImgData->height; ++y) { pSrc = srcData + (pImgData->height - y - 1) * srcPitch; memcpy(pDst, pSrc, srcPitch); pDst += dstPitch; } if (conversionRequired) { // delete temporary conversion area OGRE_FREE(convBox.data, MEMCATEGORY_GENERAL); } return ret; }
bool FreeImageLoader::load(OS::IStream* file,video::ImageInfo* t2d,video::ETextureType target){ if(m_isDummy) return false; if(!t2d)return false; //image format //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); byte* data = new byte[file->length()]; //file->read(data,file->length()); DWORD sz=0; FIMEMORY* mem = FreeImage_OpenMemory((BYTE*)data, static_cast<DWORD>(file->length())); //FreeImage_AcquireMemory(mem, &data, &sz); file->read(data, file->length()); //check that the plugin has reading capabilities and load the file if(FreeImage_FIFSupportsReading(m_FTType)) dib = FreeImage_LoadFromMemory(m_FTType, mem); FreeImage_CloseMemory(mem); delete[] data; //if the image failed to load, return failure if(!dib) return false; //retrieve the image data bits = FreeImage_GetBits(dib); //get the image width and height width = FreeImage_GetWidth(dib); height = FreeImage_GetHeight(dib); //if this somehow one of these failed (they shouldn't), return failure if((bits == 0) || (width == 0) || (height == 0)) return false; FREE_IMAGE_TYPE imageType = FreeImage_GetImageType(dib); FREE_IMAGE_COLOR_TYPE colourType = FreeImage_GetColorType(dib); unsigned bpp = FreeImage_GetBPP(dib); video::EPixelFormat imageFormat; switch(imageType) { case FIT_BITMAP: // Standard image type // Perform any colour conversions for greyscale if (colourType == FIC_MINISWHITE || colourType == FIC_MINISBLACK) { FIBITMAP* newBitmap = FreeImage_ConvertToGreyscale(dib); // free old bitmap and replace FreeImage_Unload(dib); dib = newBitmap; // get new formats bpp = FreeImage_GetBPP(dib); colourType = FreeImage_GetColorType(dib); } // Perform any colour conversions for RGB else if (bpp < 8 || colourType == FIC_PALETTE || colourType == FIC_CMYK) { FIBITMAP* newBitmap = FreeImage_ConvertTo24Bits(dib); // free old bitmap and replace FreeImage_Unload(dib); dib = newBitmap; // get new formats bpp = FreeImage_GetBPP(dib); colourType = FreeImage_GetColorType(dib); } // by this stage, 8-bit is greyscale, 16/24/32 bit are RGB[A] switch(bpp) { case 8: imageFormat = video::EPixel_LUMINANCE8; break; case 16: { FIBITMAP* newBitmap = FreeImage_ConvertTo24Bits(dib); // free old bitmap and replace FreeImage_Unload(dib); dib = newBitmap; // get new formats bpp = FreeImage_GetBPP(dib); colourType = FreeImage_GetColorType(dib); imageFormat = video::EPixel_B8G8R8; } break; case 24: imageFormat = video::EPixel_B8G8R8; break; case 32: imageFormat = video::EPixel_B8G8R8A8; break; }; break; case FIT_RGBF: imageFormat = video::EPixel_Float16_RGB; break; case FIT_RGBAF: imageFormat = video::EPixel_Float16_RGBA; break; case FIT_FLOAT: case FIT_UINT16: case FIT_INT16: case FIT_RGB16: case FIT_RGBA16: case FIT_UNKNOWN: case FIT_COMPLEX: case FIT_UINT32: case FIT_INT32: case FIT_DOUBLE: default: gLogManager.log(mT("Loading unsupported image: ")+core::string(file->getStreamName()),ELL_ERROR); break; }; unsigned char* srcData = FreeImage_GetBits(dib); unsigned srcPitch = FreeImage_GetPitch(dib); /* // Final data - invert image and trim pitch at the same time size_t dstPitch = imgData->width * PixelUtil::getNumElemBytes(imgData->format); imgData->size = dstPitch * imgData->height; // Bind output buffer output.bind(OGRE_NEW MemoryDataStream(imgData->size)); uchar* pSrc; uchar* pDst = output->getPtr(); for (size_t y = 0; y < imgData->height; ++y) { pSrc = srcData + (imgData->height - y - 1) * srcPitch; mraySystem::memCopy(pDst, pSrc, dstPitch); pDst += dstPitch; }*/ t2d->createData(math::vector3di(width,height,1),imageFormat); size_t dstPitch = width * video::PixelUtil::getPixelDescription(imageFormat).elemSizeB; uchar* pSrc; uchar* pDst = t2d->imageData; for (size_t y = 0; y < height; ++y) { pSrc = srcData + (height - y - 1) * srcPitch; mraySystem::memCopy(pDst, pSrc, dstPitch); pDst += dstPitch; } FreeImage_Unload(dib); // FreeImage_CloseMemory(fiMem); //return success return true; }
FIBITMAP * DLL_CALLCONV FreeImage_ConvertToFloat(FIBITMAP *dib) { FIBITMAP *src = NULL; FIBITMAP *dst = NULL; if(!FreeImage_HasPixels(dib)) return NULL; FREE_IMAGE_TYPE src_type = FreeImage_GetImageType(dib); // check for allowed conversions switch(src_type) { case FIT_BITMAP: { // allow conversion from 8-bit if((FreeImage_GetBPP(dib) == 8) && (FreeImage_GetColorType(dib) == FIC_MINISBLACK)) { src = dib; } else { src = FreeImage_ConvertToGreyscale(dib); if(!src) return NULL; } break; } case FIT_UINT16: case FIT_RGB16: case FIT_RGBA16: case FIT_RGBF: case FIT_RGBAF: src = dib; break; case FIT_FLOAT: // float type : clone the src return FreeImage_Clone(dib); default: return NULL; } // allocate dst image const unsigned width = FreeImage_GetWidth(src); const unsigned height = FreeImage_GetHeight(src); dst = FreeImage_AllocateT(FIT_FLOAT, width, height); if(!dst) { if(src != dib) { FreeImage_Unload(src); } return NULL; } // copy metadata from src to dst FreeImage_CloneMetadata(dst, src); // convert from src type to float const unsigned src_pitch = FreeImage_GetPitch(src); const unsigned dst_pitch = FreeImage_GetPitch(dst); const BYTE *src_bits = (BYTE*)FreeImage_GetBits(src); BYTE *dst_bits = (BYTE*)FreeImage_GetBits(dst); switch(src_type) { case FIT_BITMAP: { for(unsigned y = 0; y < height; y++) { const BYTE *src_pixel = (BYTE*)src_bits; float *dst_pixel = (float*)dst_bits; for(unsigned x = 0; x < width; x++) { // convert and scale to the range [0..1] dst_pixel[x] = (float)(src_pixel[x]) / 255; } src_bits += src_pitch; dst_bits += dst_pitch; } } break; case FIT_UINT16: { for(unsigned y = 0; y < height; y++) { const WORD *src_pixel = (WORD*)src_bits; float *dst_pixel = (float*)dst_bits; for(unsigned x = 0; x < width; x++) { // convert and scale to the range [0..1] dst_pixel[x] = (float)(src_pixel[x]) / 65535; } src_bits += src_pitch; dst_bits += dst_pitch; } } break; case FIT_RGB16: { for(unsigned y = 0; y < height; y++) { const FIRGB16 *src_pixel = (FIRGB16*)src_bits; float *dst_pixel = (float*)dst_bits; for(unsigned x = 0; x < width; x++) { // convert and scale to the range [0..1] dst_pixel[x] = LUMA_REC709(src_pixel[x].red, src_pixel[x].green, src_pixel[x].blue) / 65535.0F; } src_bits += src_pitch; dst_bits += dst_pitch; } } break; case FIT_RGBA16: { for(unsigned y = 0; y < height; y++) { const FIRGBA16 *src_pixel = (FIRGBA16*)src_bits; float *dst_pixel = (float*)dst_bits; for(unsigned x = 0; x < width; x++) { // convert and scale to the range [0..1] dst_pixel[x] = LUMA_REC709(src_pixel[x].red, src_pixel[x].green, src_pixel[x].blue) / 65535.0F; } src_bits += src_pitch; dst_bits += dst_pitch; } } break; case FIT_RGBF: { for(unsigned y = 0; y < height; y++) { const FIRGBF *src_pixel = (FIRGBF*)src_bits; float *dst_pixel = (float*)dst_bits; for(unsigned x = 0; x < width; x++) { // convert (assume pixel values are in the range [0..1]) dst_pixel[x] = LUMA_REC709(src_pixel[x].red, src_pixel[x].green, src_pixel[x].blue); } src_bits += src_pitch; dst_bits += dst_pitch; } } break; case FIT_RGBAF: { for(unsigned y = 0; y < height; y++) { const FIRGBAF *src_pixel = (FIRGBAF*)src_bits; float *dst_pixel = (float*)dst_bits; for(unsigned x = 0; x < width; x++) { // convert (assume pixel values are in the range [0..1]) dst_pixel[x] = LUMA_REC709(src_pixel[x].red, src_pixel[x].green, src_pixel[x].blue); } src_bits += src_pitch; dst_bits += dst_pitch; } } break; } if(src != dib) { FreeImage_Unload(src); } return dst; }
void GBitmap::init(ByteStream &ref, int aborder) { GMonitorLock lock(monitor()); #if HAVE_FREEIMAGE FIBITMAP *dib = ref.fiLoadImage(0); if (dib == NULL) G_THROW("File format unrecognized by FreeImage."); { FIBITMAP *dib2 = FreeImage_ConvertToGreyscale(dib); FreeImage_Unload(dib); if (dib2 == NULL) { G_THROW("Failed to convert the bitmap to grayscale bitmap."); } dib = dib2; } // Read image size int acolumns = FreeImage_GetWidth(dib); int arows = FreeImage_GetHeight(dib); init(arows, acolumns, aborder); // Returns the width of the bitmap in bytes, rounded to the next 32-bit boundary, // also known as "pitch" or "stride" or "scan width". unsigned pitch = FreeImage_GetPitch(dib); const unsigned char* bits = (const unsigned char*)FreeImage_GetBits(dib); // the pointer to the 1 pixel // Read image data grays = 256; unsigned char *row = bytes_data + border; for (int y = 0; y < nrows; y++) { const unsigned char *rgb = bits + y*pitch; for (int x = 0; x < ncolumns; x++) { row[x] = 255 - rgb[x]; } row += bytes_per_row; } FreeImage_Unload(dib); #else // Get magic number char magic[2]; magic[0] = magic[1] = 0; ref.readall((void*)magic, sizeof(magic)); char lookahead = '\n'; int acolumns = read_integer(lookahead, ref); int arows = read_integer(lookahead, ref); int maxval = 1; init(arows, acolumns, aborder); // go reading file if (magic[0]=='P') { switch(magic[1]) { case '1': grays = 2; read_pbm_text(ref); return; case '2': maxval = read_integer(lookahead, ref); if (maxval > 65535) G_THROW("Cannot read PGM with depth greater than 16 bits."); grays = (maxval>255 ? 256 : maxval+1); read_pgm_text(ref, maxval); return; case '4': grays = 2; read_pbm_raw(ref); return; case '5': maxval = read_integer(lookahead, ref); if (maxval > 65535) G_THROW("Cannot read PGM with depth greater than 16 bits."); grays = (maxval>255 ? 256 : maxval+1); read_pgm_raw(ref, maxval); return; } } else if (magic[0]=='R') { switch(magic[1]) { case '4': grays = 2; read_rle_raw(ref); return; } } G_THROW( ERR_MSG("GBitmap.bad_format") ); #endif }
bool convert(const std::string &filename) { std::string file = removePath(filename); std::string outFile = getPrefix(filename, '.') + ".cfrt"; /* Retrieve file format */ FREE_IMAGE_FORMAT fif = FreeImage_GetFileType(filename.c_str(), 0); if (fif == FIF_UNKNOWN) fif = FreeImage_GetFIFFromFilename(filename.c_str()); if (fif == FIF_UNKNOWN) { std::cout << "Unknown file format " << file << std::endl; return false; } /* Load image */ FIBITMAP *dib = nullptr; if (FreeImage_FIFSupportsReading(fif)) dib = FreeImage_Load(fif, filename.c_str()); if (!dib) { std::cout << "Failed to load " << file << std::endl; return false; } /* Convert to standard format if necessary */ if (FreeImage_GetImageType(dib) != FIT_BITMAP) { FIBITMAP *tmp = dib; dib = FreeImage_ConvertToStandardType(dib); FreeImage_Unload(tmp); if (!dib) { std::cout << "Failed to convert " << file << " to standard type." << std::endl; return false; } } /* Convert bpp if needed */ unsigned int bpp = FreeImage_GetBPP(dib); if (bpp <= 8) { FIBITMAP *tmp = dib; dib = FreeImage_ConvertToGreyscale(dib); FreeImage_Unload(tmp); bpp = 8; if (!dib || FreeImage_GetBPP(dib) != 8) bpp = 0; } else if (bpp > 32) { FIBITMAP *tmp = dib; dib = FreeImage_ConvertTo32Bits(dib); FreeImage_Unload(tmp); bpp = 32; if (!dib || FreeImage_GetBPP(dib) != 32) bpp = 0; } /* Get image information */ unsigned int width = FreeImage_GetWidth(dib); unsigned int height = FreeImage_GetHeight(dib); unsigned int bytes = 1; unsigned int channels = 0; switch (bpp) { case 8: channels = 1; break; case 24: channels = 3; break; case 32: channels = 4; break; default: bpp = 0; } /* Check if image is valid */ if (!dib || bpp == 0 || width == 0 || height == 0 || !FreeImage_HasPixels(dib)) { if (dib) FreeImage_Unload(dib); std::cout << "Invalid image " << file << std::endl; return false; } std::cout << file << " Loaded. Converting.\n"; /* Create CFR texture */ CFR::Texture texture( width, height, 1, channels, bytes ); /* Set texture pixels */ for (unsigned int y = 0; y < height; y++) { BYTE* bits = FreeImage_GetScanLine(dib, height - y - 1); for (unsigned int x = 0; x < width; x++) { CFR::Pixel8 pixel(0, 0, 0, 0); BYTE *p = bits + (channels * x); if (channels >= 1) pixel.r = p[FI_RGBA_RED]; if (channels >= 2) pixel.g = p[FI_RGBA_GREEN]; if (channels >= 3) pixel.b = p[FI_RGBA_BLUE]; if (channels >= 4) pixel.a = p[FI_RGBA_ALPHA]; texture.setPixel8(pixel, x, y, 0); } } /* Unload image */ FreeImage_Unload(dib); /* Save texture */ try { texture.saveToFile(outFile); } catch (CFR::Exception &fail) { std::cout << "Failed to save " << removePath(outFile) << ": " << fail.what() << std::endl; } return true; }
void task_glow_precalc() { FIMULTIBITMAP* anim = inputanim; float thresh=0.5; float gain=2.0; float blur=1.5; int frameskip=1; sscanf(args[1].c_str(), "%f", &thresh); sscanf(args[2].c_str(), "%f", &gain); sscanf(args[3].c_str(), "%f", &blur); sscanf(args[4].c_str(), "%i", &frameskip); int frameCount = FreeImage_GetPageCount(anim); vector<double> fb; for (int frame=0; frame<frameCount/frameskip; frame++) { FIBITMAP* fiBitmap = FreeImage_LockPage(anim, frame*frameskip); FIBITMAP* grayBitmap = FreeImage_ConvertToGreyscale(fiBitmap); FreeImage_UnlockPage(anim, fiBitmap, FALSE); int width = FreeImage_GetWidth(grayBitmap); int height = FreeImage_GetHeight(grayBitmap); // put into an array of doubles (phew) fb.resize(width*height); for (int y=0; y<height; y++) { BYTE* src = FreeImage_GetScanLine(grayBitmap, y); double* dst = &fb[y*width]; for (int x=0; x<width; x++) { *dst++ = *src++ * (1.0/255); } } // threshold for (int i=0; i<(int)fb.size(); i++) { double& v = fb[i]; v = (v-thresh)*gain; if (v<0) v=0; } // blur Blur(fb, width, height, blur); // put it back into greyBitmap for (int y=0; y<height; y++) { BYTE* dst = FreeImage_GetScanLine(grayBitmap, y); double* src = &fb[y*width]; for (int x=0; x<width; x++) { double v = *src++ * 256; if (v<0) v=0; if (v>255) v=255; *dst++ = int(v); } } // downsample it to glowgrid FIBITMAP* smallBitmap = FreeImage_Rescale(grayBitmap, GLOWGRID_W, GLOWGRID_H, FILTER_BSPLINE); // print result (should use 4bpp not 8?) for (int y=0; y<GLOWGRID_H; y++) { BYTE* src = FreeImage_GetScanLine(smallBitmap, y); for (int x=0; x<GLOWGRID_W; x++) { putchar( *src++ ); } } } }
FIBITMAP * DLL_CALLCONV FreeImage_ConvertToUINT16(FIBITMAP *dib) { FIBITMAP *src = NULL; FIBITMAP *dst = NULL; if(!FreeImage_HasPixels(dib)) return NULL; const FREE_IMAGE_TYPE src_type = FreeImage_GetImageType(dib); // check for allowed conversions switch(src_type) { case FIT_BITMAP: { // convert to greyscale if needed if((FreeImage_GetBPP(dib) == 8) && (FreeImage_GetColorType(dib) == FIC_MINISBLACK)) { src = dib; } else { src = FreeImage_ConvertToGreyscale(dib); if(!src) return NULL; } break; } case FIT_UINT16: // UINT16 type : clone the src return FreeImage_Clone(dib); break; case FIT_RGB16: // allow conversion from 48-bit RGB src = dib; break; case FIT_RGBA16: // allow conversion from 64-bit RGBA (ignore the alpha channel) src = dib; break; default: return NULL; } // allocate dst image const unsigned width = FreeImage_GetWidth(src); const unsigned height = FreeImage_GetHeight(src); dst = FreeImage_AllocateT(FIT_UINT16, width, height); if(!dst) return NULL; // copy metadata from src to dst FreeImage_CloneMetadata(dst, src); // convert from src type to UINT16 switch(src_type) { case FIT_BITMAP: { for(unsigned y = 0; y < height; y++) { const BYTE *src_bits = (BYTE*)FreeImage_GetScanLine(src, y); WORD *dst_bits = (WORD*)FreeImage_GetScanLine(dst, y); for(unsigned x = 0; x < width; x++) { dst_bits[x] = src_bits[x] << 8; } } } break; case FIT_RGB16: { for(unsigned y = 0; y < height; y++) { const FIRGB16 *src_bits = (FIRGB16*)FreeImage_GetScanLine(src, y); WORD *dst_bits = (WORD*)FreeImage_GetScanLine(dst, y); for(unsigned x = 0; x < width; x++) { // convert to grey dst_bits[x] = (WORD)LUMA_REC709(src_bits[x].red, src_bits[x].green, src_bits[x].blue); } } } break; case FIT_RGBA16: { for(unsigned y = 0; y < height; y++) { const FIRGBA16 *src_bits = (FIRGBA16*)FreeImage_GetScanLine(src, y); WORD *dst_bits = (WORD*)FreeImage_GetScanLine(dst, y); for(unsigned x = 0; x < width; x++) { // convert to grey dst_bits[x] = (WORD)LUMA_REC709(src_bits[x].red, src_bits[x].green, src_bits[x].blue); } } } break; default: break; } if(src != dib) { FreeImage_Unload(src); } return dst; }
/*! * \brief IPLFileIO::loadFile * \param filename * \param image pass by pointer reference, because we need to change the pointer * \return */ bool IPLFileIO::loadFile(const std::string filename, IPLImage*& image, std::string& information) { std::string formatNames[37] = {"BMP", "ICO", "JPEG", "JNG", "KOALA", "LBM", "MNG", "PBM", "PBMRAW", "PCD", "PCX", "PGM", "PGMRAW", "PNG", "PPM", "PPMRAW", "RAS", "TARGA", "TIFF", "WBMP", "PSD", "CUT", "XBM", "XPM", "DDS", "GIF", "HDR", "FAXG3", "SGI", "EXR", "J2K", "JP2", "PFM", "PICT", "RAW", "WEBP", "JXR"}; std::string typeNames[13] = {"UNKNOWN", "BITMAP", "UINT16", "INT16", "UINT32", "INT32", "FLOAT", "DOUBLE", "COMPLEX", "RGB16", "RGBA16", "RGBF", "RGBAF"}; FREE_IMAGE_FORMAT format = FIF_UNKNOWN; format = FreeImage_GetFileType(filename.c_str()); if(format == FIF_UNKNOWN) { return false; } FIBITMAP *dib = FreeImage_Load(format, filename.c_str()); int width = FreeImage_GetWidth(dib); int height = FreeImage_GetHeight(dib); // all files need to be flipped FreeImage_FlipVertical(dib); if(FreeImage_GetBPP(dib) == 8) { // grayscale images // convert to 32 bit FIBITMAP *dib2 = FreeImage_ConvertToGreyscale(dib); // clear old image delete image; // create new instance with the right dimensions image = new IPLImage(IPLData::IMAGE_GRAYSCALE, width, height); for(int y = 0; y < height; y++) { for(int x = 0; x < width; x++) { BYTE value; FreeImage_GetPixelIndex(dib2, x, y, &value); image->plane(0)->p(x, y) = (value * FACTOR_TO_FLOAT); } } FreeImage_Unload(dib2); } else { // color images // convert to 32 bit FIBITMAP *dib2 = FreeImage_ConvertTo32Bits(dib); // clear old image delete image; // create new instance with the right dimensions image = new IPLImage(IPLData::IMAGE_COLOR, width, height); for(int y = 0; y < height; y++) { for(int x = 0; x < width; x++) { RGBQUAD rgb; FreeImage_GetPixelColor(dib2, x, y, &rgb); image->plane(0)->p(x, y) = (rgb.rgbRed * FACTOR_TO_FLOAT); // R image->plane(1)->p(x, y) = (rgb.rgbGreen * FACTOR_TO_FLOAT); // G image->plane(2)->p(x, y) = (rgb.rgbBlue * FACTOR_TO_FLOAT); // B } } FreeImage_Unload(dib2); } FREE_IMAGE_TYPE type = FreeImage_GetImageType(dib); // collect information std::stringstream s; s << "<b>Type: </b>" << typeNames[type] << "\n"; s << "<b>Format: </b>" << formatNames[format] << "\n"; s << "<b>Bits per Pixel: </b>" << FreeImage_GetBPP(dib) << "\n"; s << "<b>Width: </b>" << width << "\n"; s << "<b>Height: </b>" << height << ""; information = s.str(); // free temporary memory FreeImage_Unload(dib); return true; }
bool IPLFileIO::loadMemory(void* mem, IPLImage*& image) { FIMEMORY* hmem = (FIMEMORY*) mem; FREE_IMAGE_FORMAT fif = FIF_UNKNOWN; FreeImage_SeekMemory(hmem, 0L, SEEK_SET); fif = FreeImage_GetFileTypeFromMemory(hmem, 0); if(fif == FIF_UNKNOWN) { // always close the memory stream FreeImage_CloseMemory(hmem); return false; } FIBITMAP *dib = FreeImage_LoadFromMemory(fif, hmem); int width = FreeImage_GetWidth(dib); int height = FreeImage_GetHeight(dib); // all files need to be flipped FreeImage_FlipVertical(dib); if(FreeImage_GetBPP(dib) == 8) { // grayscale images // convert to 32 bit FIBITMAP *dib2 = FreeImage_ConvertToGreyscale(dib); // clear old image delete image; // create new instance with the right dimensions image = new IPLImage(IPLData::IMAGE_GRAYSCALE, width, height); for(int y = 0; y < height; y++) { for(int x = 0; x < width; x++) { BYTE value; FreeImage_GetPixelIndex(dib2, x, y, &value); image->plane(0)->p(x, y) = (value * FACTOR_TO_FLOAT); } } FreeImage_Unload(dib2); } else { // color images // convert to 32 bit FIBITMAP *dib2 = FreeImage_ConvertTo32Bits(dib); // clear old image delete image; // create new instance with the right dimensions image = new IPLImage(IPLData::IMAGE_COLOR, width, height); for(int y = 0; y < height; y++) { for(int x = 0; x < width; x++) { RGBQUAD rgb; FreeImage_GetPixelColor(dib2, x, y, &rgb); image->plane(0)->p(x, y) = (rgb.rgbRed * FACTOR_TO_FLOAT); // R image->plane(1)->p(x, y) = (rgb.rgbGreen * FACTOR_TO_FLOAT); // G image->plane(2)->p(x, y) = (rgb.rgbBlue * FACTOR_TO_FLOAT); // B } } FreeImage_Unload(dib2); } // always close the memory stream FreeImage_CloseMemory(hmem); // free temporary memory FreeImage_Unload(dib); return true; }