void testRGBAChannels(FREE_IMAGE_TYPE image_type, unsigned width, unsigned height, BOOL bUseAlpha) { BOOL bResult = FALSE; // create a test image FIBITMAP *src = FreeImage_AllocateT(image_type, width, height); assert(src != NULL); // test get/set channel // ------------------------- { FIBITMAP *channel = FreeImage_GetChannel(src, FICC_GREEN); assert(channel != NULL); bResult = FreeImage_SetChannel(src, channel, FICC_GREEN); assert(bResult); FreeImage_Unload(channel); } if(bUseAlpha) { FIBITMAP *alpha = FreeImage_GetChannel(src, FICC_ALPHA); assert(alpha != NULL); bResult = FreeImage_SetChannel(src, alpha, FICC_ALPHA); assert(bResult); FreeImage_Unload(alpha); } FreeImage_Unload(src); }
BOOL fipImage::splitChannels(fipImage& RedChannel, fipImage& GreenChannel, fipImage& BlueChannel) { if(_dib) { RedChannel = FreeImage_GetChannel(_dib, FICC_RED); GreenChannel = FreeImage_GetChannel(_dib, FICC_GREEN); BlueChannel = FreeImage_GetChannel(_dib, FICC_BLUE); return (RedChannel.isValid() && GreenChannel.isValid() && BlueChannel.isValid()); } return FALSE; }
int DLL_CALLCONV FIA_ExtractColourPlanes (FIBITMAP *src, FIBITMAP **R, FIBITMAP **G, FIBITMAP **B) { if (FIA_IsGreyScale(src)) return FIA_ERROR; *R = FreeImage_GetChannel(src, FICC_RED); *G = FreeImage_GetChannel(src, FICC_GREEN); *B = FreeImage_GetChannel(src, FICC_BLUE); return FIA_SUCCESS; }
BOOL fipImage::getChannel(fipImage& image, FREE_IMAGE_COLOR_CHANNEL channel) const { if(_dib) { image = FreeImage_GetChannel(_dib, channel); return image.isValid(); } return FALSE; }
void test32BitsChannels(unsigned width, unsigned height) { BOOL bResult = FALSE; // create a test 8-bit image FIBITMAP *src = createZonePlateImage(width, height, 128); if(src != NULL) { // convert to 32-bit FIBITMAP *tmp = FreeImage_ConvertTo32Bits(src); FreeImage_Unload(src); src = tmp; } assert(src != NULL); // save for further examination bResult = FreeImage_Save(FIF_PNG, src, "zoneplate.png", PNG_DEFAULT); assert(bResult); // test get/set channel // ------------------------- FIBITMAP *channel = FreeImage_GetChannel(src, FICC_ALPHA); assert(channel != NULL); bResult = FreeImage_SetChannel(src, channel, FICC_ALPHA); assert(bResult); FreeImage_Unload(channel); FreeImage_Unload(src); }
FIBITMAP *loadDIB(const std::string &url) { // figure out if the file exists if(!fs::exists(url)) { printf("poImage: image file not found (%s)\n", url.c_str()); return NULL; } loadFreeImageIfNeeded(); FREE_IMAGE_FORMAT fif = FIF_UNKNOWN; fif = FreeImage_GetFileType(url.c_str()); // if(fif == FIF_UNKNOWN) // fif = FreeImage_GetFIFFromFilename(url.c_str()); if(fif == FIF_UNKNOWN) { printf("poImage: image isn't a supported file type (%s)\n", url.c_str()); return NULL; } FIBITMAP *dib = NULL; if(FreeImage_FIFSupportsReading(fif)) dib = FreeImage_Load(fif, url.c_str()); if(!dib) { printf("poImage: image file not found (%s)\n", url.c_str()); return NULL; } unsigned bpp = FreeImage_GetBPP(dib); if(bpp == 24 || bpp == 32) { // there has got to be a more efficient way of doing this FIBITMAP *red = FreeImage_GetChannel(dib,FICC_RED); FIBITMAP *blue = FreeImage_GetChannel(dib,FICC_BLUE); FreeImage_SetChannel(dib,red,FICC_BLUE); FreeImage_SetChannel(dib,blue,FICC_RED); FreeImage_Unload(red); FreeImage_Unload(blue); } return dib; }
/** Write a FIBITMAP to a JNG stream @param format_id ID of the caller @param io Stream i/o functions @param dib Image to be saved @param handle Stream handle @param flags Saving flags @return Returns TRUE if successful, returns FALSE otherwise */ BOOL mng_WriteJNG(int format_id, FreeImageIO *io, FIBITMAP *dib, fi_handle handle, int flags) { DWORD jng_width = 0; DWORD jng_height = 0; BYTE jng_color_type = 0; BYTE jng_image_sample_depth = 8; BYTE jng_image_compression_method = 8; // 8: ISO-10918-1 Huffman-coded baseline JPEG. BYTE jng_image_interlace_method = 0; BYTE jng_alpha_sample_depth = 0; BYTE jng_alpha_compression_method = 0; BYTE jng_alpha_filter_method = 0; BYTE jng_alpha_interlace_method = 0; BYTE buffer[16]; FIMEMORY *hJngMemory = NULL; FIMEMORY *hJpegMemory = NULL; FIMEMORY *hPngMemory = NULL; FIBITMAP *dib_rgb = NULL; FIBITMAP *dib_alpha = NULL; if(!dib || (FreeImage_GetImageType(dib) != FIT_BITMAP)) { return FALSE; } unsigned bpp = FreeImage_GetBPP(dib); switch(bpp) { case 8: if(FreeImage_GetColorType(dib) == FIC_MINISBLACK) { dib_rgb = dib; jng_color_type = MNG_COLORTYPE_JPEGGRAY; } else { // JPEG plugin will convert other types (FIC_MINISWHITE, FIC_PALETTE) to 24-bit on the fly //dib_rgb = FreeImage_ConvertTo24Bits(dib); dib_rgb = dib; jng_color_type = MNG_COLORTYPE_JPEGCOLOR; } break; case 24: dib_rgb = dib; jng_color_type = MNG_COLORTYPE_JPEGCOLOR; break; case 32: dib_rgb = FreeImage_ConvertTo24Bits(dib); jng_color_type = MNG_COLORTYPE_JPEGCOLORA; jng_alpha_sample_depth = 8; break; default: return FALSE; } jng_width = (DWORD)FreeImage_GetWidth(dib); jng_height = (DWORD)FreeImage_GetHeight(dib); try { hJngMemory = FreeImage_OpenMemory(); // --- write JNG file signature --- FreeImage_WriteMemory(g_jng_signature, 1, 8, hJngMemory); // --- write a JHDR chunk --- SwapLong(&jng_width); SwapLong(&jng_height); memcpy(&buffer[0], &jng_width, 4); memcpy(&buffer[4], &jng_height, 4); SwapLong(&jng_width); SwapLong(&jng_height); buffer[8] = jng_color_type; buffer[9] = jng_image_sample_depth; buffer[10] = jng_image_compression_method; buffer[11] = jng_image_interlace_method; buffer[12] = jng_alpha_sample_depth; buffer[13] = jng_alpha_compression_method; buffer[14] = jng_alpha_filter_method; buffer[15] = jng_alpha_interlace_method; mng_WriteChunk(mng_JHDR, &buffer[0], 16, hJngMemory); // --- write a sequence of JDAT chunks --- hJpegMemory = FreeImage_OpenMemory(); flags |= JPEG_BASELINE; if(!FreeImage_SaveToMemory(FIF_JPEG, dib_rgb, hJpegMemory, flags)) { throw (const char*)NULL; } if(dib_rgb != dib) { FreeImage_Unload(dib_rgb); dib_rgb = NULL; } { BYTE *jpeg_data = NULL; DWORD size_in_bytes = 0; // get a pointer to the stream buffer FreeImage_AcquireMemory(hJpegMemory, &jpeg_data, &size_in_bytes); // write chunks for(DWORD k = 0; k < size_in_bytes;) { DWORD bytes_left = size_in_bytes - k; DWORD chunk_size = MIN(JPEG_CHUNK_SIZE, bytes_left); mng_WriteChunk(mng_JDAT, &jpeg_data[k], chunk_size, hJngMemory); k += chunk_size; } } FreeImage_CloseMemory(hJpegMemory); hJpegMemory = NULL; // --- write alpha layer as a sequence of IDAT chunk --- if((bpp == 32) && (jng_color_type == MNG_COLORTYPE_JPEGCOLORA)) { dib_alpha = FreeImage_GetChannel(dib, FICC_ALPHA); hPngMemory = FreeImage_OpenMemory(); if(!FreeImage_SaveToMemory(FIF_PNG, dib_alpha, hPngMemory, PNG_DEFAULT)) { throw (const char*)NULL; } FreeImage_Unload(dib_alpha); dib_alpha = NULL; // get the IDAT chunk { BOOL bResult = FALSE; DWORD start_pos = 0; DWORD next_pos = 0; long offset = 8; do { // find the next IDAT chunk from 'offset' position bResult = mng_FindChunk(hPngMemory, mng_IDAT, offset, &start_pos, &next_pos); if(!bResult) break; BYTE *png_data = NULL; DWORD size_in_bytes = 0; // get a pointer to the stream buffer FreeImage_AcquireMemory(hPngMemory, &png_data, &size_in_bytes); // write the IDAT chunk mng_WriteChunk(mng_IDAT, &png_data[start_pos+8], next_pos - start_pos - 12, hJngMemory); offset = next_pos; } while(bResult); } FreeImage_CloseMemory(hPngMemory); hPngMemory = NULL; } // --- write a IEND chunk --- mng_WriteChunk(mng_IEND, NULL, 0, hJngMemory); // write the JNG on output stream { BYTE *jng_data = NULL; DWORD size_in_bytes = 0; FreeImage_AcquireMemory(hJngMemory, &jng_data, &size_in_bytes); io->write_proc(jng_data, 1, size_in_bytes, handle); } FreeImage_CloseMemory(hJngMemory); FreeImage_CloseMemory(hJpegMemory); FreeImage_CloseMemory(hPngMemory); return TRUE; } catch(const char *text) { FreeImage_CloseMemory(hJngMemory); FreeImage_CloseMemory(hJpegMemory); FreeImage_CloseMemory(hPngMemory); if(dib_rgb && (dib_rgb != dib)) { FreeImage_Unload(dib_rgb); } FreeImage_Unload(dib_alpha); if(text) { FreeImage_OutputMessageProc(format_id, text); } return FALSE; } }