/** Get the embedded JPEG preview image from RAW picture with included Exif Data. @param RawProcessor Libraw handle @param flags JPEG load flags @return Returns the loaded dib if successfull, returns NULL otherwise */ static FIBITMAP * libraw_LoadEmbeddedPreview(LibRaw& RawProcessor, int flags) { FIBITMAP *dib = NULL; libraw_processed_image_t *thumb_image = NULL; try { // unpack data if(RawProcessor.unpack_thumb() != LIBRAW_SUCCESS) { // run silently "LibRaw : failed to run unpack_thumb" return NULL; } // retrieve thumb image int error_code = 0; thumb_image = RawProcessor.dcraw_make_mem_thumb(&error_code); if(thumb_image) { if(thumb_image->type != LIBRAW_IMAGE_BITMAP) { // attach the binary data to a memory stream FIMEMORY *hmem = FreeImage_OpenMemory((BYTE*)thumb_image->data, (DWORD)thumb_image->data_size); // get the file type FREE_IMAGE_FORMAT fif = FreeImage_GetFileTypeFromMemory(hmem, 0); if(fif == FIF_JPEG) { // rotate according to Exif orientation flags |= JPEG_EXIFROTATE; } // load an image from the memory stream dib = FreeImage_LoadFromMemory(fif, hmem, flags); // close the stream FreeImage_CloseMemory(hmem); } else { // convert processed data to output dib dib = libraw_ConvertToDib(thumb_image); } } else { throw "LibRaw : failed to run dcraw_make_mem_thumb"; } // clean-up and return RawProcessor.dcraw_clear_mem(thumb_image); return dib; } catch(const char *text) { // clean-up and return if(thumb_image) { RawProcessor.dcraw_clear_mem(thumb_image); } if(text != NULL) { FreeImage_OutputMessageProc(s_format_id, text); } } return NULL; }
/** Load raw data and convert to FIBITMAP @param RawProcessor Libraw handle @param bitspersample Output bitdepth (8- or 16-bit) @return Returns the loaded dib if successfull, returns NULL otherwise */ static FIBITMAP * libraw_LoadRawData(LibRaw& RawProcessor, int bitspersample) { FIBITMAP *dib = NULL; libraw_processed_image_t *processed_image = NULL; try { // set decoding parameters // ----------------------- // (-6) 16-bit or 8-bit RawProcessor.imgdata.params.output_bps = bitspersample; // (-g power toe_slope) if(bitspersample == 16) { // set -g 1 1 for linear curve RawProcessor.imgdata.params.gamm[0] = 1; RawProcessor.imgdata.params.gamm[1] = 1; } else if(bitspersample == 8) { // by default settings for rec. BT.709 are used: power 2.222 (i.e. gamm[0]=1/2.222) and slope 4.5 RawProcessor.imgdata.params.gamm[0] = 1/2.222; RawProcessor.imgdata.params.gamm[1] = 4.5; } // (-w) Use camera white balance, if possible (otherwise, fallback to auto_wb) RawProcessor.imgdata.params.use_camera_wb = 1; // (-a) Use automatic white balance obtained after averaging over the entire image RawProcessor.imgdata.params.use_auto_wb = 1; // (-q 3) Adaptive homogeneity-directed demosaicing algorithm (AHD) RawProcessor.imgdata.params.user_qual = 3; // RAW data filtration mode during data unpacking and postprocessing RawProcessor.imgdata.params.filtering_mode = LIBRAW_FILTERING_AUTOMATIC; // ----------------------- // unpack data if(RawProcessor.unpack() != LIBRAW_SUCCESS) { throw "LibRaw : failed to unpack data"; } // process data (... most consuming task ...) if(RawProcessor.dcraw_process() != LIBRAW_SUCCESS) { throw "LibRaw : failed to process data"; } // retrieve processed image int error_code = 0; processed_image = RawProcessor.dcraw_make_mem_image(&error_code); if(processed_image) { // type SHOULD be LIBRAW_IMAGE_BITMAP, but we'll check if(processed_image->type != LIBRAW_IMAGE_BITMAP) { throw "invalid image type"; } // only 3-color images supported... if(processed_image->colors != 3) { throw "only 3-color images supported"; } } else { throw "LibRaw : failed to run dcraw_make_mem_image"; } // convert processed data to output dib dib = libraw_ConvertToDib(processed_image); // clean-up and return RawProcessor.dcraw_clear_mem(processed_image); return dib; } catch(const char *text) { // clean-up and return if(processed_image) { RawProcessor.dcraw_clear_mem(processed_image); } FreeImage_OutputMessageProc(s_format_id, text); } return NULL; }