GLubyte* Texture::loadToBitmap(std::string path, bool flip) { const char* pathCStr = path.c_str(); FREE_IMAGE_FORMAT format = FIF_UNKNOWN; format = FreeImage_GetFileType(pathCStr); if (format == FIF_UNKNOWN) format = FreeImage_GetFIFFromFilename(pathCStr); if (format == FIF_UNKNOWN) { std::cout << "Failed to load image at " << pathCStr << std::endl; return nullptr; } if (!FreeImage_FIFSupportsReading(format)) { std::cout << "Detected image format cannot be read! " << pathCStr << std::endl; return nullptr; } m_bitmap = FreeImage_Load(format, pathCStr); if (flip) FreeImage_FlipVertical(m_bitmap); GLint bitsPerPixel = FreeImage_GetBPP(m_bitmap); if (bitsPerPixel == 32) m_bitmap32 = m_bitmap; else m_bitmap32 = FreeImage_ConvertTo32Bits(m_bitmap); m_width = FreeImage_GetWidth(m_bitmap32); m_height = FreeImage_GetHeight(m_bitmap32); return FreeImage_GetBits(m_bitmap32); }
void TextureLoader::load(GLuint* tex_name, FREE_IMAGE_FORMAT fif, const char* file) { FIBITMAP* image = FreeImage_Load(fif, file); int tex_width = FreeImage_GetWidth(image); int tex_height = FreeImage_GetHeight(image); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glGenTextures(1, tex_name); glBindTexture(GL_TEXTURE_2D, *tex_name); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_DECAL); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_DECAL); //printf("BPP: %d\n", FreeImage_GetBPP(image)); int bpp = FreeImage_GetBPP(image) / 8; GLenum format = GL_RGBA; if(bpp == 3) format = GL_RGB; gluBuild2DMipmaps(GL_TEXTURE_2D, bpp, tex_width, tex_height, format, GL_UNSIGNED_BYTE, FreeImage_GetBits(image)); }
Texture::Texture(const char* file) { FREE_IMAGE_FORMAT fif = FIF_UNKNOWN; FIBITMAP* dib = nullptr; fif = FreeImage_GetFileType(file, 0); if (fif == FIF_UNKNOWN) fif = FreeImage_GetFIFFromFilename(file); if (fif != FIF_UNKNOWN) { if (FreeImage_FIFSupportsReading(fif)) dib = FreeImage_Load(fif, file); BYTE* pixels = FreeImage_GetBits(dib); int width = FreeImage_GetWidth(dib); int height = FreeImage_GetHeight(dib); int bits = FreeImage_GetBPP(dib); int size = width * height * (bits / 8); BYTE* result = new BYTE[size]; memcpy(result, pixels, size); FreeImage_Unload(dib); glGenTextures(1, &m_ID); glBindTexture(GL_TEXTURE_2D, m_ID); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, result ? result : NULL); glBindTexture(GL_TEXTURE_2D, 0); } else { m_ID = -1; } }
/** * Helper to encapsulate Bpp conversion using FreeImage, taking into consideration color type. Creates a new bitmap if needed. Can return the same one. * @param pHandle FIBITMAP as defined by the Freeimage library. * @param pNewBpp the new bpp that the supplied FIBITMAP is to be coverted to. */ FIBITMAP* FreeImageHelper::convertBpp(FIBITMAP* pHandle, int pNewBpp) { //Convert the bit depth FIBITMAP *converted = NULL; //Convert Bpp only if needed if (pNewBpp != static_cast<int>(FreeImage_GetBPP(pHandle))) { //Transform bpp to the pixel format switch (pNewBpp) { case (4): converted = FreeImage_ConvertTo4Bits(pHandle); break; case (8): converted = FreeImage_ConvertTo8Bits(pHandle); break; case(16): converted = FreeImage_ConvertTo16Bits565(pHandle); //There's option of 16Bits555. But leaves unused bits. Chosen 565 because it's most common break; case(24): converted = FreeImage_ConvertTo24Bits(pHandle); break; case(32): { converted = FreeImage_ConvertTo32Bits (pHandle); } break; default: converted = NULL; break; } } else { //No change, just set 'converted' handle to current one converted = pHandle; } return converted; }
/** * Freeimage format to Indielib format. * @param pHandle the FIBITMAP that is used for calculation */ int FreeImageHelper::calculateINDFormat(FIBITMAP* pHandle) { FREE_IMAGE_TYPE imgType = FreeImage_GetImageType(pHandle); //Bitmap type (most common) if (FIT_BITMAP == imgType) { //Depending on the freeimage color type analysis, we determine our IND_ColorFormat FREE_IMAGE_COLOR_TYPE colorType = FreeImage_GetColorType(pHandle); if (FIC_MINISBLACK == colorType || FIC_MINISWHITE == colorType) { return IND_LUMINANCE; } else if (FIC_PALETTE == colorType) { return IND_COLOUR_INDEX; } else if (FIC_RGB == colorType) { //HACK: This is because when converting to 32 bits, even though there is alpha channel, //the color analysis function returns FIC_RGB, as alpha is opaque. We rely on that to know //if we have alpha channel so it's not good. if (FreeImage_GetBPP(pHandle) == 32) { return IND_RGBA; } else { return IND_RGB; } } else if (FIC_RGBALPHA == colorType) { return IND_RGBA; } } //TODO: OTHER IMAGE TYPES //Failure return IND_UNKNOWN; }
static void TestFIA_IO(CuTest* tc) { FIBITMAP *dib1 = NULL, *dib2 = NULL; FREE_IMAGE_TYPE type; int bpp, err; const char *file = TEST_DATA_DIR "001.tif"; dib1 = FIA_LoadFIBFromFile(file); CuAssertTrue(tc, dib1 != NULL); bpp = FreeImage_GetBPP(dib1); type = FreeImage_GetImageType(dib1); CuAssertTrue(tc, bpp == 24); CuAssertTrue(tc, type == FIT_BITMAP); err = FIA_SaveFIBToFile (dib1, TEST_DATA_OUTPUT_DIR "/IO/save-colour-test.bmp", BIT8); CuAssertTrue(tc, err == FIA_SUCCESS); dib2 = FIA_LoadFIBFromFile(TEST_DATA_OUTPUT_DIR "/IO/save-colour-test.bmp"); err = FIA_BitwiseCompare(dib1, dib2); FreeImage_Unload(dib1); FreeImage_Unload(dib2); }
bitmap_ptr finalize(bool showProgress = true) { if (chunks.empty()) { return nullptr; } if (showProgress) { std::cout << "Adding all accepted chunks to the final image\n"; } const auto it = chunks.begin(); bitmap_ptr firstChunk = GenericLoader(*it); auto currentHeight = 0; const auto type = FreeImage_GetImageType(firstChunk.get()); const auto bpp = FreeImage_GetBPP(firstChunk.get()); bitmap_ptr finalImage(FreeImage_AllocateT(type, width, height, bpp)); auto RGBChunkWorker = [=, &finalImage, ¤tHeight](const std::string& el) { bitmap_ptr chunk = GenericLoader(el); auto chunkHeight = FreeImage_GetHeight(chunk.get()); auto chunk_img = FreeImage_Copy(chunk.get(), 0, 0, this->width, chunkHeight); if (chunk_img) { FreeImage_Paste(finalImage.get(), chunk_img, 0, currentHeight, 256); } currentHeight += chunkHeight; }; std::for_each(chunks.begin(), chunks.end(), RGBChunkWorker); return finalImage; }
void FreeImageStack::loadImage(unsigned int iSlice, npp::ImageNPP_8u_C1 & rImage) const { NPP_ASSERT_MSG(iSlice < slices(), "Slice index exceeded number of slices in stack."); FIBITMAP * pBitmap = FreeImage_LockPage(pImageStack_, iSlice); NPP_ASSERT_NOT_NULL(pBitmap); // make sure this is an 8-bit single channel image NPP_DEBUG_ASSERT(FreeImage_GetColorType(pBitmap) == FIC_MINISBLACK); NPP_DEBUG_ASSERT(FreeImage_GetBPP(pBitmap) == 8); NPP_DEBUG_ASSERT(FreeImage_GetWidth(pBitmap) == nWidth_); NPP_DEBUG_ASSERT(FreeImage_GetHeight(pBitmap) == nHeight_); unsigned int nSrcPitch = FreeImage_GetPitch(pBitmap); unsigned char * pSrcData = FreeImage_GetBits(pBitmap); if (rImage.width() == nWidth_ && rImage.height() == nHeight_) { NPP_CHECK_CUDA(cudaMemcpy2D(rImage.data(), rImage.pitch(), pSrcData, nSrcPitch, nWidth_, nHeight_, cudaMemcpyHostToDevice)); } else { // create new NPP image npp::ImageNPP_8u_C1 oImage(nWidth_, nHeight_); // transfer slice data into new device image NPP_CHECK_CUDA(cudaMemcpy2D(oImage.data(), oImage.pitch(), pSrcData, nSrcPitch, nWidth_, nHeight_, cudaMemcpyHostToDevice)); // swap the result image with the reference passed into this method rImage.swap(oImage); } // release locked slice FreeImage_UnlockPage(pImageStack_, pBitmap, FALSE); }
FIBITMAP* DLL_CALLCONV FIA_ShiftImageEdgeToCenter(FIBITMAP *src) { int width = FreeImage_GetWidth(src); int height = FreeImage_GetHeight(src); int xhalf = (width / 2); int yhalf = (height / 2); int bytes_pp = FreeImage_GetBPP(src) / 8; int xhalf_bytes = xhalf * bytes_pp; //std::cout << "width " << width << std::endl; //std::cout << "xhalf " << xhalf << std::endl; FIBITMAP *dst = FIA_CloneImageType(src, width, height); for(int y=0; y < yhalf; y++) { BYTE* srcbits = (BYTE *) FIA_GetScanLineFromTop(src, y); BYTE* outbits = (BYTE *) FIA_GetScanLineFromTop(dst, y + yhalf); memcpy(outbits + xhalf_bytes, srcbits, xhalf_bytes); memcpy(outbits, srcbits + xhalf_bytes, xhalf_bytes); } for(int y=yhalf; y < height; y++) { BYTE* srcbits = (BYTE *) FIA_GetScanLineFromTop(src, y); BYTE* outbits = (BYTE *) FIA_GetScanLineFromTop(dst, y - yhalf); memcpy(outbits + xhalf_bytes, srcbits, xhalf_bytes); memcpy(outbits, srcbits + xhalf_bytes, xhalf_bytes); } return dst; }
/** Invert only color components, skipping Alpha/Black (Can be useful as public/utility function) */ static BOOL invertColor(FIBITMAP* dib) { FREE_IMAGE_TYPE type = FreeImage_GetImageType(dib); const unsigned Bpp = FreeImage_GetBPP(dib)/8; if((type == FIT_BITMAP && Bpp == 4) || type == FIT_RGBA16) { const unsigned width = FreeImage_GetWidth(dib); const unsigned height = FreeImage_GetHeight(dib); BYTE *line_start = FreeImage_GetScanLine(dib, 0); const unsigned pitch = FreeImage_GetPitch(dib); const unsigned triBpp = Bpp - (Bpp == 4 ? 1 : 2); for(unsigned y = 0; y < height; y++) { BYTE *line = line_start; for(unsigned x = 0; x < width; x++) { for(unsigned b=0; b < triBpp; ++b) { line[b] = ~line[b]; } line += Bpp; } line_start += pitch; } return TRUE; } else { return FreeImage_Invert(dib); } }
HBITMAP BmpFilterLoadBitmap(BOOL *bIsTransparent, const wchar_t *ptszFilename) { FIBITMAP *dib = (FIBITMAP*)Image_Load(ptszFilename, IMGL_RETURNDIB); if (dib == nullptr) return nullptr; FIBITMAP *dib32 = nullptr; if (FreeImage_GetBPP(dib) != 32) { dib32 = FreeImage_ConvertTo32Bits(dib); FreeImage_Unload(dib); } else dib32 = dib; if (dib32 == nullptr) return nullptr; if (FreeImage_IsTransparent(dib32)) if (bIsTransparent) *bIsTransparent = TRUE; if (FreeImage_GetWidth(dib32) > 128 || FreeImage_GetHeight(dib32) > 128) { FIBITMAP *dib_new = FreeImage_MakeThumbnail(dib32, 128, FALSE); FreeImage_Unload(dib32); if (dib_new == nullptr) return nullptr; dib32 = dib_new; } HBITMAP bitmap = FreeImage_CreateHBITMAPFromDIB(dib32); FreeImage_Unload(dib32); FreeImage_CorrectBitmap32Alpha(bitmap, FALSE); return bitmap; }
template<class Tdst, class Tsrc> FIBITMAP* CONVERT_TYPE<Tdst, Tsrc>::convert(FIBITMAP *src, FREE_IMAGE_TYPE dst_type) { FIBITMAP *dst = NULL; unsigned width = FreeImage_GetWidth(src); unsigned height = FreeImage_GetHeight(src); unsigned bpp = FreeImage_GetBPP(src); // allocate dst image dst = FreeImage_AllocateT(dst_type, width, height, bpp, FreeImage_GetRedMask(src), FreeImage_GetGreenMask(src), FreeImage_GetBlueMask(src)); if(!dst) return NULL; // convert from src_type to dst_type for(unsigned y = 0; y < height; y++) { const Tsrc *src_bits = reinterpret_cast<Tsrc*>(FreeImage_GetScanLine(src, y)); Tdst *dst_bits = reinterpret_cast<Tdst*>(FreeImage_GetScanLine(dst, y)); for(unsigned x = 0; x < width; x++) { *dst_bits++ = static_cast<Tdst>(*src_bits++); } } return dst; }
BOOL DLL_CALLCONV FreeImage_GetBackgroundColor(FIBITMAP *dib, RGBQUAD *bkcolor) { if(dib && bkcolor) { if(FreeImage_HasBackgroundColor(dib)) { // get the background color RGBQUAD *bkgnd_color = &((FREEIMAGEHEADER *)dib->data)->bkgnd_color; memcpy(bkcolor, bkgnd_color, sizeof(RGBQUAD)); // get the background index if(FreeImage_GetBPP(dib) == 8) { RGBQUAD *pal = FreeImage_GetPalette(dib); for(unsigned i = 0; i < FreeImage_GetColorsUsed(dib); i++) { if(bkgnd_color->rgbRed == pal[i].rgbRed) { if(bkgnd_color->rgbGreen == pal[i].rgbGreen) { if(bkgnd_color->rgbBlue == pal[i].rgbBlue) { bkcolor->rgbReserved = (BYTE)i; return TRUE; } } } } } bkcolor->rgbReserved = 0; return TRUE; } } return FALSE; }
std::shared_ptr<FIBITMAP> load_image(const std::wstring& filename) { if(!boost::filesystem::exists(filename)) BOOST_THROW_EXCEPTION(file_not_found() << boost::errinfo_file_name(narrow(filename))); FREE_IMAGE_FORMAT fif = FIF_UNKNOWN; fif = FreeImage_GetFileTypeU(filename.c_str(), 0); if(fif == FIF_UNKNOWN) fif = FreeImage_GetFIFFromFilenameU(filename.c_str()); if(fif == FIF_UNKNOWN || !FreeImage_FIFSupportsReading(fif)) BOOST_THROW_EXCEPTION(invalid_argument() << msg_info("Unsupported image format.")); auto bitmap = std::shared_ptr<FIBITMAP>(FreeImage_LoadU(fif, filename.c_str(), 0), FreeImage_Unload); if(FreeImage_GetBPP(bitmap.get()) != 32) { bitmap = std::shared_ptr<FIBITMAP>(FreeImage_ConvertTo32Bits(bitmap.get()), FreeImage_Unload); if(!bitmap) BOOST_THROW_EXCEPTION(invalid_argument() << msg_info("Unsupported image format.")); } //PNG-images need to be premultiplied with their alpha if(fif == FIF_PNG) { image_view<bgra_pixel> original_view(FreeImage_GetBits(bitmap.get()), FreeImage_GetWidth(bitmap.get()), FreeImage_GetHeight(bitmap.get())); premultiply(original_view); } return bitmap; }
static void TestFIA_ColourTextTest(CuTest* tc) { const char *file = TEST_DATA_DIR "fly.bmp"; int bpp; FIBITMAP *src = FIA_LoadFIBFromFile(file); CuAssertTrue(tc, src != NULL); FIBITMAP *dst = FreeImage_ConvertTo24Bits(src); FIA_DrawHorizontalColourText (dst, 10, 10, FIA_AGG_FONT_VERDANA_12_BOLD, "A quick brown fox jumps over the lazy dog 0123456789", FIA_RGBQUAD(0, 255, 0)); FIA_DrawHorizontalColourText (dst, 10, 40, FIA_AGG_FONT_VERDANA_16, "A quick brown fox jumps over the lazy dog 0123456789", FIA_RGBQUAD(0, 0, 255)); FIA_DrawHorizontalColourText (dst, 10, 60, FIA_AGG_FONT_GSE_8x16_BOLD, "A quick brown fox jumps over the lazy dog 0123456789", FIA_RGBQUAD(0, 255, 255)); FIA_DrawHorizontalColourText (dst, 1000, 600, FIA_AGG_FONT_GSE_8x16_BOLD, "A quick brown fox jumps over the lazy dog 0123456789", FIA_RGBQUAD(0, 255, 255)); FIA_DrawHorizontalColourText (dst, -500, -600, FIA_AGG_FONT_GSE_8x16_BOLD, "A quick brown fox jumps over the lazy dog 0123456789", FIA_RGBQUAD(0, 255, 255)); FIA_DrawHorizontalColourText (dst, 0, 200, FIA_AGG_FONT_GSE_8x16_BOLD, "A quick brown fox jumps over the lazy dog 0123456789", FIA_RGBQUAD(0, 255, 255)); FIA_DrawHorizontalColourText (dst, 0, 300, FIA_AGG_FONT_GSE_8x16_BOLD, "A quick brown fox jumps over the lazy dog 0123456789", FIA_RGBQUAD(0, 255, 255)); bpp = FreeImage_GetBPP(dst); CuAssertTrue(tc, dst != NULL); FIA_SaveFIBToFile(dst, TEST_DATA_OUTPUT_DIR "Drawing/TestFIA_ColourTextTest.bmp", BIT24); FreeImage_Unload(src); FreeImage_Unload(dst); }
Texture::Texture(std::string path) : m_path(path) { Texture* previousTexture = TextureStore::get(m_path); if (previousTexture != nullptr) { m_location = previousTexture->getLocation(); m_width = previousTexture->getWidth(); m_height = previousTexture->getHeight(); return; } TextureStore::add(this); GLubyte* textureData = loadToBitmap(m_path); glGenTextures(1, &m_location); glBindTexture(GL_TEXTURE_2D, m_location); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_width, m_height, 0, GL_BGRA, GL_UNSIGNED_BYTE, textureData); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glGenerateMipmap(GL_TEXTURE_2D); GLuint bitsPerPixel = FreeImage_GetBPP(m_bitmap); FreeImage_Unload(m_bitmap32); if (bitsPerPixel != 32) FreeImage_Unload(m_bitmap); }
/** Pre-multiplies a 32-bit image's red-, green- and blue channels with it's alpha channel for to be used with e.g. the Windows GDI function AlphaBlend(). The transformation changes the red-, green- and blue channels according to the following equation: channel(x, y) = channel(x, y) * alpha_channel(x, y) / 255 @param dib Input/Output dib to be premultiplied @return Returns TRUE on success, FALSE otherwise (e.g. when the bitdepth of the source dib cannot be handled). */ BOOL DLL_CALLCONV FreeImage_PreMultiplyWithAlpha(FIBITMAP *dib) { if (!dib) return FALSE; if ((FreeImage_GetBPP(dib) != 32) || (FreeImage_GetImageType(dib) != FIT_BITMAP)) { return FALSE; } int width = FreeImage_GetWidth(dib); int height = FreeImage_GetHeight(dib); for(int y = 0; y < height; y++) { BYTE *bits = FreeImage_GetScanLine(dib, y); for (int x = 0; x < width; x++, bits += 4) { const BYTE alpha = bits[FI_RGBA_ALPHA]; // slightly faster: care for two special cases if(alpha == 0x00) { // special case for alpha == 0x00 // color * 0x00 / 0xFF = 0x00 bits[FI_RGBA_BLUE] = 0x00; bits[FI_RGBA_GREEN] = 0x00; bits[FI_RGBA_RED] = 0x00; } else if(alpha == 0xFF) { // nothing to do for alpha == 0xFF // color * 0xFF / 0xFF = color continue; } else { bits[FI_RGBA_BLUE] = (BYTE)((alpha * (WORD)bits[FI_RGBA_BLUE]) / 255); bits[FI_RGBA_GREEN] = (BYTE)((alpha * (WORD)bits[FI_RGBA_GREEN]) / 255); bits[FI_RGBA_RED] = (BYTE)((alpha * (WORD)bits[FI_RGBA_RED]) / 255); } } } return TRUE; }
FreeImageStack::FreeImageStack(const std::string & rFileName): sFileName_(rFileName) , pImageStack_(0) , nWidth_(0) , nHeight_(0) , pBitmap_32f_(0) , nMaxXY_(0) , nMaxOffset_(0) { // open the bitmap pImageStack_ = FreeImage_OpenMultiBitmap(FIF_TIFF, (sFileName_ + ".tif").c_str(), FALSE, // create new TRUE, // open read-only FALSE, // keep all slices in memory TIFF_DEFAULT); NPP_ASSERT_NOT_NULL(pImageStack_); NPP_ASSERT_NOT_NULL(slices()); FIBITMAP * pBitmap = FreeImage_LockPage(pImageStack_, 0); // store away the size of the first image // this information is later used to insure that all slices // accessed are of the same size. if they are not an exception // is thrown when such a deviating slice is being accessed nWidth_ = FreeImage_GetWidth(pBitmap); nHeight_ = FreeImage_GetHeight(pBitmap); NPP_ASSERT(FreeImage_GetColorType(pBitmap) == FIC_MINISBLACK); NPP_ASSERT(FreeImage_GetBPP(pBitmap) == 8); FreeImage_UnlockPage(pImageStack_, pBitmap, FALSE); }
Image *Image::New(FIBITMAP* dib) { NanScope(); Local<Value> arg = NanNew<Integer>(0); Local<Object> obj = NanNew<FunctionTemplate>(constructor_template)->GetFunction()->NewInstance(1, &arg); Image *image = ObjectWrap::Unwrap<Image>(obj); int w,h,pitch; FREE_IMAGE_TYPE type = FreeImage_GetImageType(dib); obj->SetInternalField(0, NanNew<External>(dib)); obj->Set(NanNew<String>("width"), NanNew<Integer>(w=FreeImage_GetWidth(dib))); obj->Set(NanNew<String>("height"), NanNew<Integer>(h=FreeImage_GetHeight(dib))); obj->Set(NanNew<String>("bpp"), NanNew<Integer>((int)FreeImage_GetBPP(dib))); obj->Set(NanNew<String>("pitch"), NanNew<Integer>(pitch=FreeImage_GetPitch(dib))); obj->Set(NanNew<String>("type"), NanNew<Integer>(type)); obj->Set(NanNew<String>("redMask"), NanNew<Integer>((int)FreeImage_GetRedMask(dib))); obj->Set(NanNew<String>("greenMask"), NanNew<Integer>((int)FreeImage_GetGreenMask(dib))); obj->Set(NanNew<String>("blueMask"), NanNew<Integer>((int)FreeImage_GetBlueMask(dib))); BYTE *bits = FreeImage_GetBits(dib); obj->Set(NanNew<String>("buffer"), NanNewBufferHandle((char*) bits, h * pitch)); return image; }
bool FreeimagelibPlugin::LoadDoc(cpcl::IOStream *input, plcl::Doc **r) { FREE_IMAGE_FORMAT fif = (FREE_IMAGE_FORMAT)freeimagelib_format; FreeimagelibStuff stuff(input); boost::shared_ptr<FIBITMAP> fibitmap(FreeImage_LoadFromHandle(fif, &stuff.io, stuff.io_handle), FreeImage_Unload); if (!fibitmap) { cpcl::Error(cpcl::StringPieceFromLiteral("FreeimagelibPlugin::LoadDoc(): unable to load image")); return false; } if (FreeImage_GetImageType(fibitmap.get()) != FIT_BITMAP) { boost::shared_ptr<FIBITMAP> tmp(FreeImage_ConvertToType(fibitmap.get(), FIT_BITMAP), FreeImage_Unload); if (!tmp || (FreeImage_GetImageType(tmp.get()) != FIT_BITMAP)) { cpcl::Error(cpcl::StringPieceFromLiteral("FreeimagelibPlugin::LoadDoc(): unable to convert the image to FIT_BITMAP")); return false; } fibitmap = tmp; } unsigned int const bpp = FreeImage_GetBPP(fibitmap.get()); if (!(bpp == 24 || bpp == 32)) { boost::shared_ptr<FIBITMAP> tmp((bpp > 32) ? FreeImage_ConvertTo32Bits(fibitmap.get()) : FreeImage_ConvertTo24Bits(fibitmap.get()), FreeImage_Unload); if (!tmp) { cpcl::Trace(CPCL_TRACE_LEVEL_ERROR, "FreeimagelibPlugin::LoadDoc(): unable to convert image with bpp %u", bpp); } fibitmap = tmp; } if (r) *r = new FreeimagelibDoc(fibitmap); return true; }
BOOL fipImage::saveU(const wchar_t* lpszPathName, int flag) const { FREE_IMAGE_FORMAT fif = FIF_UNKNOWN; BOOL bSuccess = FALSE; // Try to guess the file format from the file extension fif = FreeImage_GetFIFFromFilenameU(lpszPathName); if(fif != FIF_UNKNOWN ) { // Check that the dib can be saved in this format BOOL bCanSave; FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(_dib); if(image_type == FIT_BITMAP) { // standard bitmap type WORD bpp = FreeImage_GetBPP(_dib); bCanSave = (FreeImage_FIFSupportsWriting(fif) && FreeImage_FIFSupportsExportBPP(fif, bpp)); } else { // special bitmap type bCanSave = FreeImage_FIFSupportsExportType(fif, image_type); } if(bCanSave) { bSuccess = FreeImage_SaveU(fif, _dib, lpszPathName, flag); return bSuccess; } } return bSuccess; }
BOOL fipImage::rotate(double angle, const void *bkcolor) { if(_dib) { switch(FreeImage_GetImageType(_dib)) { case FIT_BITMAP: switch(FreeImage_GetBPP(_dib)) { case 1: case 8: case 24: case 32: break; default: return FALSE; } break; case FIT_UINT16: case FIT_RGB16: case FIT_RGBA16: case FIT_FLOAT: case FIT_RGBF: case FIT_RGBAF: break; default: return FALSE; break; } FIBITMAP *rotated = FreeImage_Rotate(_dib, angle, bkcolor); return replace(rotated); } return FALSE; }
/** @brief Inverts each pixel data. @param src Input image to be processed. @return Returns TRUE if successful, FALSE otherwise. */ BOOL DLL_CALLCONV FreeImage_Invert(FIBITMAP *src) { unsigned i, x, y, k; BYTE *bits; if (!src) return FALSE; int bpp = FreeImage_GetBPP(src); switch(bpp) { case 1 : case 4 : case 8 : { // if the dib has a colormap, just invert it // else, keep the linear grayscale if (FreeImage_GetColorType(src) == FIC_PALETTE) { RGBQUAD *pal = FreeImage_GetPalette(src); for(i = 0; i < FreeImage_GetColorsUsed(src); i++) { pal[i].rgbRed = 255 - pal[i].rgbRed; pal[i].rgbGreen = 255 - pal[i].rgbGreen; pal[i].rgbBlue = 255 - pal[i].rgbBlue; } } else { for(y = 0; y < FreeImage_GetHeight(src); y++) { bits = FreeImage_GetScanLine(src, y); for (x = 0; x < FreeImage_GetLine(src); x++) { bits[x] = ~bits[x]; } } } break; } case 24 : case 32 : { unsigned bytespp = FreeImage_GetLine(src) / FreeImage_GetWidth(src); for(y = 0; y < FreeImage_GetHeight(src); y++) { bits = FreeImage_GetScanLine(src, y); for(x = 0; x < FreeImage_GetWidth(src); x++) { for(k = 0; k < bytespp; k++) { bits[k] = ~bits[k]; } bits += bytespp; } } break; } } return TRUE; }
/////////////////////////////////////////////////////////////////////////// /// /// @fn bool glLoadTexture(const std::string& nomFichier, unsigned int& idTexture, /// bool genererTexture) /// /// Cette fonction crée une texture OpenGL à partir d'une image contenu /// dans un fichier. FreeImage est utilisée pour lire l'image, donc tous /// les formats reconnues par cette librairie devraient être supportés. /// /// @param[in] nomFichier : Le nom du fichier image à charger. /// @param[out] idTexture : L'identificateur de la texture créée. /// @param[in] genererTexture : Doit-on demander à OpenGL de générer un numéro /// de texture au préalable? /// /// @return Vrai si le chargement a réussi, faux autrement. /// /////////////////////////////////////////////////////////////////////////// bool glLoadTexture(const std::string& nomFichier, unsigned int& idTexture, bool genererTexture) { // Ce code de lecture générique d'un fichier provient de la // documentation de FreeImage FREE_IMAGE_FORMAT format = FIF_UNKNOWN; // check the file signature and deduce its format // (the second argument is currently not used by FreeImage) format = FreeImage_GetFileType(nomFichier.c_str(), 0); if(format == FIF_UNKNOWN) { // no signature ? // try to guess the file format from the file extension format = FreeImage_GetFIFFromFilename(nomFichier.c_str()); } // check that the plugin has reading capabilities ... if((format == FIF_UNKNOWN) || !FreeImage_FIFSupportsReading(format)) { utilitaire::afficherErreur( std::string("Format du fichier image \"") + std::string(nomFichier.c_str()) + std::string("\" non supporté") ); return false; } // ok, let's load the file FIBITMAP* dib = FreeImage_Load(format, nomFichier.c_str(), 0); if (dib == 0) { utilitaire::afficherErreur( std::string("Erreur à la lecture du fichier \"") + std::string(nomFichier.c_str()) + std::string("\"") ); return false; } FIBITMAP* dib32 = FreeImage_ConvertTo32Bits(dib); if (dib32 == 0) { utilitaire::afficherErreur( std::string("Incapable de convertir le fichier \"") + std::string(nomFichier.c_str()) + std::string("\" en 32 bpp.") ); FreeImage_Unload(dib); return false; } int pitch = FreeImage_GetPitch(dib32); glCreateTexture( FreeImage_GetBits(dib32), FreeImage_GetWidth(dib32), FreeImage_GetHeight(dib32), FreeImage_GetBPP(dib32), FreeImage_GetPitch(dib32), idTexture, genererTexture ); FreeImage_Unload(dib32); FreeImage_Unload(dib); return true; }
bool ImageFile::load(const std::string& fname) { FREE_IMAGE_FORMAT fiFormat = FreeImage_GetFileType(fname.c_str(), 0); if (fiFormat == FIF_UNKNOWN) return false; FIBITMAP* image = FreeImage_Load(fiFormat, fname.c_str()); if (!image) return false; if (FreeImage_GetBPP(image) != 32) { FIBITMAP* convertedImage = FreeImage_ConvertTo32Bits(image); FreeImage_Unload(image); image = convertedImage; } mBytesPerPixel = FreeImage_GetBPP(image) / 8; mPixelFormat = PF_UBYTE_RGBA; mWidth = FreeImage_GetWidth(image); mHeight = FreeImage_GetHeight(image); mLevels = 1; for (uint8 i = 0; i < 16; i++) _DELETE_ARRAY_IF(mImageData[i]); // Allocate 1 level uint8* destData = new uint8[mWidth * mHeight * mBytesPerPixel]; mImageData[0] = destData; uint8* srcData = FreeImage_GetBits(image); for (uint32 i = 0; i < mWidth; i++) { for (uint32 j = 0; j < mHeight; j++) { uint32 s = j * 4 * mWidth + i * 4; destData[s + 0] = srcData[s + 2]; // R, B destData[s + 1] = srcData[s + 1]; // G, G destData[s + 2] = srcData[s + 0]; // B, R destData[s + 3] = srcData[s + 3]; // A, A } } FreeImage_Unload(image); mIsLoaded = true; }
double ApplyCurve(FIBITMAP *src, FIBITMAP *dst, std::vector<cp> ctpts, int threadcount) { _mark(); unsigned spitch = FreeImage_GetPitch(src); unsigned dpitch = FreeImage_GetPitch(dst); unsigned w = FreeImage_GetWidth(src); unsigned h = FreeImage_GetHeight(src); BYTE * srcbits = FreeImage_GetBits(src); BYTE * dstbits = FreeImage_GetBits(dst); Curve c; BYTE LUT8[256]; WORD LUT16[65536]; c.setControlPoints(ctpts); int bpp = FreeImage_GetBPP(src); if (bpp == 24) { c.clampto(0.0,255.0); for (int x=0; x<256; x++) { LUT8[x] = (BYTE)floor(c.getpoint(x) + 0.5); } #pragma omp parallel for num_threads(threadcount) for(unsigned y = 0; y < h; y++) { for(unsigned x = 0; x < w; x++) { BYTE * bdstpix = (BYTE *) dstbits + dpitch*y + 3*x; BYTE *pixel = (BYTE *) (srcbits + spitch*y + 3*x); bdstpix[FI_RGBA_RED] = LUT8[pixel[FI_RGBA_RED]]; bdstpix[FI_RGBA_GREEN] = LUT8[pixel[FI_RGBA_GREEN]]; bdstpix[FI_RGBA_BLUE] = LUT8[pixel[FI_RGBA_BLUE]]; //bdstpix[FI_RGBA_RED] = ((BYTE *) LUT8)[pixel[FI_RGBA_RED]]; //bdstpix[FI_RGBA_GREEN] = ((BYTE *) LUT8)[pixel[FI_RGBA_GREEN]]; //bdstpix[FI_RGBA_BLUE] = ((BYTE *) LUT8)[pixel[FI_RGBA_BLUE]]; } } } if (bpp == 48) { c.scalepoints(256.0); c.clampto(0.0,65535.0); for (int x=0; x<65536; x++) { LUT16[x] = (WORD)floor(c.getpoint(x) + 0.5); } #pragma omp parallel for num_threads(threadcount) for(unsigned y = 0; y < h; y++) { for(unsigned x = 0; x < w; x++) { FIRGB16 * wdstpix = (FIRGB16 *) (dstbits + dpitch*y + 6*x); FIRGB16 * pixel = (FIRGB16 *) (srcbits + spitch*y + 6*x); wdstpix->red = LUT16[pixel->red]; wdstpix->green = LUT16[pixel->green]; wdstpix->blue = LUT16[pixel->blue]; //wdstpix->red = ((WORD *) LUT16)[pixel->red]; //wdstpix->green = ((WORD *) LUT16)[pixel->green]; //wdstpix->blue = ((WORD *) LUT16)[pixel->blue]; } } } return _duration(); }
unsigned char* GLES2Texture::loadImage(const char *filename, int& colorDepth) { //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(filename, 0); //if still unknown, try to guess the file format from the file extension if(fif == FIF_UNKNOWN) fif = FreeImage_GetFIFFromFilename(filename); //if still unkown, return failure if(fif == FIF_UNKNOWN) return NULL; //check that the plugin has reading capabilities and load the file if(FreeImage_FIFSupportsReading(fif)) dib = FreeImage_Load(fif, filename); //if the image failed to load, return failure if(!dib) return NULL; int datasize = FreeImage_GetDIBSize(dib); //retrieve the image data bits = FreeImage_GetBits(dib); //get the image width and height width = FreeImage_GetWidth(dib); height = FreeImage_GetHeight(dib); //get the image bpp colorDepth = FreeImage_GetBPP(dib); //if this somehow one of these failed (they shouldn't), return failure if((bits == 0) || (width == 0) || (height == 0)) return NULL; mWidth = width; mHeight = height; // BGRA 转成 RGBA unsigned char* buffer = new unsigned char[datasize]; int i=0; for (i=0; i<datasize; i+=4) { (buffer+i)[0] = (bits+i)[2]; (buffer+i)[1] = (bits+i)[1]; (buffer+i)[2] = (bits+i)[0]; (buffer+i)[3] = (bits+i)[3]; } //Free FreeImage's copy of the data FreeImage_Unload(dib); return buffer; }
BOOL fipImage::rotateEx(double angle, double x_shift, double y_shift, double x_origin, double y_origin, BOOL use_mask) { if(_dib) { if(FreeImage_GetBPP(_dib) >= 8) { FIBITMAP *rotated = FreeImage_RotateEx(_dib, angle, x_shift, y_shift, x_origin, y_origin, use_mask); return replace(rotated); } } return FALSE; }
double ApplyLUT(FIBITMAP *src, FIBITMAP *dst, char * LUT, int threadcount) { _mark(); unsigned spitch = FreeImage_GetPitch(src); unsigned dpitch = FreeImage_GetPitch(dst); unsigned w = FreeImage_GetWidth(src); unsigned h = FreeImage_GetHeight(src); BYTE * srcbits = FreeImage_GetBits(src); BYTE * dstbits = FreeImage_GetBits(dst); BYTE LUT8[256]; WORD LUT16[65536]; int bpp = FreeImage_GetBPP(src); if (bpp == 24) { for (int x=0; x<256; x++) { LUT8[x] = ((BYTE *) LUT)[x];; } #pragma omp parallel for num_threads(threadcount) for(unsigned y = 0; y < h; y++) { for(unsigned x = 0; x < w; x++) { BYTE * bdstpix = (BYTE *) (dstbits + dpitch*y + 3*x); BYTE * pixel = (BYTE *) (srcbits + spitch*y + 3*x); bdstpix[FI_RGBA_RED] = LUT8[pixel[FI_RGBA_RED]]; bdstpix[FI_RGBA_GREEN] = LUT8[pixel[FI_RGBA_GREEN]]; bdstpix[FI_RGBA_BLUE] = LUT8[pixel[FI_RGBA_BLUE]]; //bdstpix[FI_RGBA_RED] = ((BYTE *) LUT8)[pixel[FI_RGBA_RED]]; //bdstpix[FI_RGBA_GREEN] = ((BYTE *) LUT8)[pixel[FI_RGBA_GREEN]]; //bdstpix[FI_RGBA_BLUE] = ((BYTE *) LUT8)[pixel[FI_RGBA_BLUE]]; } } } if (bpp == 48) { for (int x=0; x<65536; x++) { LUT16[x] = ((WORD *)LUT)[x]; } #pragma omp parallel for num_threads(threadcount) for(unsigned y = 0; y < h-1; y++) { for(unsigned x = 0; x < w-1; x++) { FIRGB16 * wdstpix = (FIRGB16 *) (dstbits + dpitch*y + 6*x); FIRGB16 * pixel = (FIRGB16 *) (srcbits + spitch*y + 6*x); wdstpix->red = LUT16[pixel->red]; wdstpix->green = LUT16[pixel->green]; wdstpix->blue = LUT16[pixel->blue]; //wdstpix->red = ((WORD *) LUT16)[pixel->red]; //wdstpix->green = ((WORD *) LUT16)[pixel->green]; //wdstpix->blue = ((WORD *) LUT16)[pixel->blue]; } } } return _duration(); }
void FreeImage::setFormat( Format format ) { if ( format == Format::UNDEFINED ) return; _updateFormat( format ); if ( isLoaded() && this -> BPP != FreeImage_GetBPP( this -> freeImage ) ) _updateBPP(); }