// Returns: // -4 = no preview // -2 = load still in progress or failed int CHexEditDoc::GetBmpInfo(CString &format, CString &bpp, CString &width, CString &height) { // Clear strings in case of error return format = ""; bpp = width = height = ""; if (pthread6_ == NULL) return -4; // no bitmap preview for this file format = "Unknown"; // Protect access to shared data CSingleLock sl(&docdata_, TRUE); if (preview_dib_ == NULL) return -2; ASSERT(preview_fif_ != FREE_IMAGE_FORMAT(-999)); if (preview_fif_ > FIF_UNKNOWN && preview_fif_ <= FIF_RAW) { format = CString(format_name[int(preview_fif_)]); bpp.Format("%d bits/pixel", preview_bpp_); width.Format("%u pixels", preview_width_); height.Format("%u pixels", preview_height_); } return 0; }
// Returns: // -3 = no disk file int CHexEditDoc::GetDiskBmpInfo(CString &format, CString &bpp, CString &width, CString &height) { // Clear strings in case of error return format = "Unknown"; bpp = width = height = ""; //if (pthread6_ == NULL) // return -4; // no bitmap preview for this file if (pfile1_ == NULL) return -3; // Protect access to shared data CSingleLock sl(&docdata_, TRUE); // If we don't have the any info on the disk bitmap if (preview_file_fif_ == FREE_IMAGE_FORMAT(-999)) { preview_file_fif_ = FIF_UNKNOWN; // Wrap FreeImage stuff in try block as FreeImage_Load may have memory access violations on bad data try { FIBITMAP * dib = NULL; // Load info about bitmap from the disk file // (Unfortunately we have to load the whole bitmap into memory to get his info.) preview_file_fif_ = FreeImage_GetFileType(pfile1_->GetFilePath()); if (preview_file_fif_ > FIF_UNKNOWN && (dib = FreeImage_Load(preview_file_fif_, pfile1_->GetFilePath())) != NULL) { preview_file_bpp_ = FreeImage_GetBPP(dib); preview_file_width_ = FreeImage_GetWidth(dib); preview_file_height_ = FreeImage_GetHeight(dib); FreeImage_Unload(dib); } else preview_file_fif_ = FIF_UNKNOWN; } catch (...) { preview_file_fif_ = FIF_UNKNOWN; } } if (preview_file_fif_ > FIF_UNKNOWN && preview_file_fif_ <= FIF_RAW) { format = CString(format_name[int(preview_file_fif_)]); bpp.Format("%d bits/pixel", preview_file_bpp_); width.Format("%u pixels", preview_file_width_); height.Format("%u pixels", preview_file_height_); } return 0; }
static void saveImage(ofPixels_<PixelType> & pix, ofBuffer & buffer, ofImageFormat format, ofImageQualityType qualityLevel) { //thanks to alvaro casinelli for the implementation ofInitFreeImage(); if (pix.isAllocated() == false){ ofLog(OF_LOG_ERROR,"error saving image - pixels aren't allocated"); return; } #ifdef TARGET_LITTLE_ENDIAN if(sizeof(PixelType) == 1) { pix.swapRgb(); } #endif FIBITMAP * bmp = getBmpFromPixels(pix); #ifdef TARGET_LITTLE_ENDIAN if(sizeof(PixelType) == 1) { pix.swapRgb(); } #endif if (bmp) // bitmap successfully created { // (b) open a memory stream to compress the image onto mem_buffer: // FIMEMORY *hmem = FreeImage_OpenMemory(); // (c) encode and save the image to the memory (on dib FIBITMAP image): // if(FREE_IMAGE_FORMAT(format) == FIF_JPEG) { int quality = JPEG_QUALITYSUPERB; switch(qualityLevel) { case OF_IMAGE_QUALITY_WORST: quality = JPEG_QUALITYBAD; break; case OF_IMAGE_QUALITY_LOW: quality = JPEG_QUALITYAVERAGE; break; case OF_IMAGE_QUALITY_MEDIUM: quality = JPEG_QUALITYNORMAL; break; case OF_IMAGE_QUALITY_HIGH: quality = JPEG_QUALITYGOOD; break; case OF_IMAGE_QUALITY_BEST: quality = JPEG_QUALITYSUPERB; break; } FreeImage_SaveToMemory(FIF_JPEG, bmp, hmem, quality); }else{ FreeImage_SaveToMemory((FREE_IMAGE_FORMAT)format, bmp, hmem); } /* NOTE: at this point, hmem contains the entire data in memory stored in fif format. the amount of space used by the memory is equal to file_size: long file_size = FreeImage_TellMemory(hmem); but can also be retrieved by FreeImage_AcquireMemory that retrieves both the length of the buffer, and the buffer memory address. */ #ifdef TARGET_WIN32 DWORD size_in_bytes = 0; #else uint32_t size_in_bytes = 0; #endif // Save compressed data on mem_buffer // note: FreeImage_AquireMemory allocates space for aux_mem_buffer): // unsigned char *mem_buffer = NULL; if (!FreeImage_AcquireMemory(hmem, &mem_buffer, &size_in_bytes)) cout << "Error aquiring compressed image from memory" << endl; /* Now, before closing the memory stream, copy the content of mem_buffer to an auxiliary buffer */ buffer.set((char*)mem_buffer,size_in_bytes); // Finally, close the FIBITMAP object, or we will get a memory leak: FreeImage_Unload(bmp); // Close the memory stream (otherwise we may get a memory leak). FreeImage_CloseMemory(hmem); } }
static bool saveImage(const ofPixels_<PixelType> & _pix, ofBuffer & buffer, ofImageFormat format, ofImageQualityType qualityLevel) { // thanks to alvaro casinelli for the implementation ofInitFreeImage(); if (_pix.isAllocated() == false){ ofLogError("ofImage","saveImage(): couldn't save to ofBuffer, pixels are not allocated"); return false; } if(format==OF_IMAGE_FORMAT_JPEG && (_pix.getNumChannels()==4 || _pix.getBitsPerChannel() > 8)){ ofPixels pix3 = _pix; pix3.setNumChannels(3); return saveImage(pix3,buffer,format,qualityLevel); } FIBITMAP * bmp = nullptr; #ifdef TARGET_LITTLE_ENDIAN if(sizeof(PixelType) == 1 && (_pix.getPixelFormat()==OF_PIXELS_RGB || _pix.getPixelFormat()==OF_PIXELS_RGBA)) { // Make a local copy. ofPixels_<PixelType> pix = _pix; pix.swapRgb(); bmp = getBmpFromPixels(pix); }else{ #endif bmp = getBmpFromPixels(_pix); #ifdef TARGET_LITTLE_ENDIAN } #endif if (bmp) // bitmap successfully created { bool returnValue; // (b) open a memory stream to compress the image onto mem_buffer: // FIMEMORY *hmem = FreeImage_OpenMemory(); // (c) encode and save the image to the memory (on dib FIBITMAP image): // if(FREE_IMAGE_FORMAT(format) == FIF_JPEG) { int quality = JPEG_QUALITYSUPERB; switch(qualityLevel) { case OF_IMAGE_QUALITY_WORST: quality = JPEG_QUALITYBAD; break; case OF_IMAGE_QUALITY_LOW: quality = JPEG_QUALITYAVERAGE; break; case OF_IMAGE_QUALITY_MEDIUM: quality = JPEG_QUALITYNORMAL; break; case OF_IMAGE_QUALITY_HIGH: quality = JPEG_QUALITYGOOD; break; case OF_IMAGE_QUALITY_BEST: quality = JPEG_QUALITYSUPERB; break; } returnValue = FreeImage_SaveToMemory(FIF_JPEG, bmp, hmem, quality); }else{ returnValue = FreeImage_SaveToMemory((FREE_IMAGE_FORMAT)format, bmp, hmem); } /* NOTE: at this point, hmem contains the entire data in memory stored in fif format. the amount of space used by the memory is equal to file_size: long file_size = FreeImage_TellMemory(hmem); but can also be retrieved by FreeImage_AcquireMemory that retrieves both the length of the buffer, and the buffer memory address. */ #ifdef TARGET_WIN32 DWORD size_in_bytes = 0; #else std::uint32_t size_in_bytes = 0; #endif // Save compressed data on mem_buffer // note: FreeImage_AquireMemory allocates space for aux_mem_buffer): // unsigned char *mem_buffer = nullptr; if (!FreeImage_AcquireMemory(hmem, &mem_buffer, &size_in_bytes)){ ofLogError("ofImage") << "saveImage(): couldn't save to ofBuffer, aquiring compressed image from memory failed"; return false; } /* Now, before closing the memory stream, copy the content of mem_buffer to an auxiliary buffer */ buffer.set((char*)mem_buffer,size_in_bytes); // Finally, close the FIBITMAP object, or we will get a memory leak: FreeImage_Unload(bmp); // Close the memory stream (otherwise we may get a memory leak). FreeImage_CloseMemory(hmem); return returnValue; }else{ return false; } }