Alien-FreeImage

 view release on metacpan or  search on metacpan

src/Source/FreeImage/PluginRAW.cpp  view on Meta::CPAN


static int s_format_id;

// ==========================================================
// Internal functions
// ==========================================================

// ----------------------------------------------------------
//   FreeImage datastream wrapper
// ----------------------------------------------------------

class LibRaw_freeimage_datastream : public LibRaw_abstract_datastream {
private: 
	FreeImageIO *_io;
	fi_handle _handle;
	long _eof;
	INT64 _fsize;

public:
	LibRaw_freeimage_datastream(FreeImageIO *io, fi_handle handle) : _io(io), _handle(handle) {
		long start_pos = io->tell_proc(handle);
		io->seek_proc(handle, 0, SEEK_END);
		_eof = io->tell_proc(handle);
		_fsize = _eof - start_pos;
		io->seek_proc(handle, start_pos, SEEK_SET);
	}

	~LibRaw_freeimage_datastream() {
	}

    int valid() { 
		return (_io && _handle);
	}

    int read(void *buffer, size_t size, size_t count) { 
		if(substream) return substream->read(buffer, size, count);
		return _io->read_proc(buffer, (unsigned)size, (unsigned)count, _handle);
	}

    int seek(INT64 offset, int origin) { 
        if(substream) return substream->seek(offset, origin);
		return _io->seek_proc(_handle, (long)offset, origin);
	}

    INT64 tell() { 
		if(substream) return substream->tell();
        return _io->tell_proc(_handle);
    }
	
	INT64 size() {
		return _fsize;
	}

    int get_char() { 
		int c = 0;
		if(substream) return substream->get_char();
		if(!_io->read_proc(&c, 1, 1, _handle)) return -1;
		return c;
   }
	
	char* gets(char *buffer, int length) { 
		if (substream) return substream->gets(buffer, length);
		memset(buffer, 0, length);
		for(int i = 0; i < length; i++) {
			if(!_io->read_proc(&buffer[i], 1, 1, _handle))
				return NULL;
			if(buffer[i] == 0x0A)
				break;
		}
		return buffer;
	}

	int scanf_one(const char *fmt, void* val) {
		std::string buffer;
		char element = 0;
		bool bDone = false;
		if(substream) return substream->scanf_one(fmt,val);				
		do {
			if(_io->read_proc(&element, 1, 1, _handle) == 1) {
				switch(element) {
					case '0':
					case '\n':
					case ' ':
					case '\t':
						bDone = true;
						break;
					default:
						break;
				}
				buffer.append(&element, 1);
			} else {
				return 0;
			}
		} while(!bDone);

		return sscanf(buffer.c_str(), fmt, val);
	}

	int eof() { 
		if(substream) return substream->eof();
        return (_io->tell_proc(_handle) >= _eof);
    }

	void * make_jas_stream() {
		return NULL;
	}
};

// ----------------------------------------------------------

/**
Convert a processed raw data array to a FIBITMAP
@param RawProcessor LibRaw handle containing the processed raw image
@return Returns the converted dib if successfull, returns NULL otherwise
*/
static FIBITMAP * 
libraw_ConvertProcessedRawToDib(LibRaw *RawProcessor) {
	FIBITMAP *dib = NULL;
    int width, height, colors, bpp;

	try {
		int bgr = 0;	// pixel copy order: RGB if (bgr == 0) and BGR otherwise

		// get image info

src/Source/FreeImage/PluginRAW.cpp  view on Meta::CPAN

	FIBITMAP *dib = NULL;
	LibRaw *RawProcessor = NULL;

	BOOL header_only = (flags & FIF_LOAD_NOPIXELS) == FIF_LOAD_NOPIXELS;

	try {
		// do not declare RawProcessor on the stack as it may be huge (300 KB)
		RawProcessor = new(std::nothrow) LibRaw;
		if(!RawProcessor) {
			throw FI_MSG_ERROR_MEMORY;
		}

		// wrap the input datastream
		LibRaw_freeimage_datastream datastream(io, handle);

		// set decoding parameters
		// the following parameters affect data reading
		// --------------------------------------------

		// (-s [0..N-1]) Select one raw image from input file
		RawProcessor->imgdata.params.shot_select = 0;
		// (-w) Use camera white balance, if possible (otherwise, fallback to auto_wb)
		RawProcessor->imgdata.params.use_camera_wb = 1;
		// (-M) Use any color matrix from the camera metadata. This option only affects Olympus, Leaf, and Phase One cameras.
		RawProcessor->imgdata.params.use_camera_matrix = 1;
		// (-h) outputs the image in 50% size
		RawProcessor->imgdata.params.half_size = ((flags & RAW_HALFSIZE) == RAW_HALFSIZE) ? 1 : 0;

		// open the datastream
		if(RawProcessor->open_datastream(&datastream) != LIBRAW_SUCCESS) {
			throw "LibRaw : failed to open input stream (unknown format)";
		}

		if(header_only) {
			// header only mode
			dib = FreeImage_AllocateHeaderT(header_only, FIT_RGB16, RawProcessor->imgdata.sizes.width, RawProcessor->imgdata.sizes.height);
		}
		else if((flags & RAW_UNPROCESSED) == RAW_UNPROCESSED) {
			// load raw data without post-processing (i.e. as a Bayer matrix)
			dib = libraw_LoadUnprocessedData(RawProcessor);
		}
		else if((flags & RAW_PREVIEW) == RAW_PREVIEW) {
			// try to get the embedded JPEG
			dib = libraw_LoadEmbeddedPreview(RawProcessor, 0);
			if(!dib) {
				// no JPEG preview: try to load as 8-bit/sample (i.e. RGB 24-bit)
				dib = libraw_LoadRawData(RawProcessor, 8);
			}
		} 
		else if((flags & RAW_DISPLAY) == RAW_DISPLAY) {
			// load raw data as 8-bit/sample (i.e. RGB 24-bit)
			dib = libraw_LoadRawData(RawProcessor, 8);
		} 
		else {
			// default: load raw data as linear 16-bit/sample (i.e. RGB 48-bit)
			dib = libraw_LoadRawData(RawProcessor, 16);
		}

		// save ICC profile if present
		if(dib && (NULL != RawProcessor->imgdata.color.profile)) {
			FreeImage_CreateICCProfile(dib, RawProcessor->imgdata.color.profile, RawProcessor->imgdata.color.profile_length);
		}

		// try to get JPEG embedded Exif metadata
		if(dib && !((flags & RAW_PREVIEW) == RAW_PREVIEW)) {
			FIBITMAP *metadata_dib = libraw_LoadEmbeddedPreview(RawProcessor, FIF_LOAD_NOPIXELS);
			if(metadata_dib) {
				FreeImage_CloneMetadata(dib, metadata_dib);
				FreeImage_Unload(metadata_dib);
			}
		}

		// clean-up internal memory allocations
		RawProcessor->recycle();
		delete RawProcessor;

		return dib;

	} catch(const char *text) {
		if(RawProcessor) {
			RawProcessor->recycle();
			delete RawProcessor;
		}
		if(dib) {
			FreeImage_Unload(dib);
		}
		FreeImage_OutputMessageProc(s_format_id, text);
	}

	return NULL;
}

// ==========================================================
//   Init
// ==========================================================

void DLL_CALLCONV
InitRAW(Plugin *plugin, int format_id) {
	s_format_id = format_id;

	plugin->format_proc = Format;
	plugin->description_proc = Description;
	plugin->extension_proc = Extension;
	plugin->regexpr_proc = RegExpr;
	plugin->open_proc = NULL;
	plugin->close_proc = NULL;
	plugin->pagecount_proc = NULL;
	plugin->pagecapability_proc = NULL;
	plugin->load_proc = Load;
	plugin->save_proc = NULL;
	plugin->validate_proc = Validate;
	plugin->mime_proc = MimeType;
	plugin->supports_export_bpp_proc = SupportsExportDepth;
	plugin->supports_export_type_proc = SupportsExportType;
	plugin->supports_icc_profiles_proc = SupportsICCProfiles;
	plugin->supports_no_pixels_proc = SupportsNoPixels;
}



( run in 0.435 second using v1.01-cache-2.11-cpan-119454b85a5 )