Alien-FreeImage

 view release on metacpan or  search on metacpan

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

		return NULL;
	}
}

/**
Load the Bayer matrix (unprocessed raw data) as a FIT_UINT16 image. 
Note that some formats don't have a Bayer matrix (e.g. Foveon, Canon sRAW, demosaiced DNG files). 
@param RawProcessor Libraw handle
@return Returns the loaded dib if successfull, returns NULL otherwise
*/
static FIBITMAP * 
libraw_LoadUnprocessedData(LibRaw *RawProcessor) {
	FIBITMAP *dib = NULL;

	try {
		// unpack data
		if(RawProcessor->unpack() != LIBRAW_SUCCESS) {
			throw "LibRaw : failed to unpack data";
		}

		// check for a supported Bayer format
		if(!(RawProcessor->imgdata.idata.filters || RawProcessor->imgdata.idata.colors == 1)) {
			throw "LibRaw : only Bayer-pattern RAW files are supported";
		}

		// allocate output dib
		const unsigned width = RawProcessor->imgdata.sizes.raw_width;
		const unsigned height = RawProcessor->imgdata.sizes.raw_height;
		const size_t line_size = width * sizeof(WORD);
		const WORD *src_bits = (WORD*)RawProcessor->imgdata.rawdata.raw_image;

		if(src_bits) {
			dib = FreeImage_AllocateT(FIT_UINT16, width, height);
		}
		if(!dib) {
			throw FI_MSG_ERROR_DIB_MEMORY;
		}

		// retrieve the raw image
		for(unsigned y = 0; y < height; y++) {
			WORD *dst_bits = (WORD*)FreeImage_GetScanLine(dib, height - 1 - y);
			memcpy(dst_bits, src_bits, line_size);
			src_bits += width;
		}

		// store metadata needed for post-processing
		{
			char value[512];

			const libraw_image_sizes_t *sizes = &RawProcessor->imgdata.sizes;

			// image output width & height
			{
				sprintf(value, "%d", sizes->iwidth);
				FreeImage_SetMetadataKeyValue(FIMD_COMMENTS, dib, "Raw.Output.Width", value);
				
				sprintf(value, "%d", sizes->iheight);
				FreeImage_SetMetadataKeyValue(FIMD_COMMENTS, dib, "Raw.Output.Height", value);
			}

			// image output frame
			{
				const unsigned f_left = sizes->left_margin;
				const unsigned f_top = sizes->top_margin;
				const unsigned f_width = sizes->width;
				const unsigned f_height = sizes->height;
				
				sprintf(value, "%d", f_left);
				FreeImage_SetMetadataKeyValue(FIMD_COMMENTS, dib, "Raw.Frame.Left", value);

				sprintf(value, "%d", f_top);
				FreeImage_SetMetadataKeyValue(FIMD_COMMENTS, dib, "Raw.Frame.Top", value);

				sprintf(value, "%d", f_width);
				FreeImage_SetMetadataKeyValue(FIMD_COMMENTS, dib, "Raw.Frame.Width", value);

				sprintf(value, "%d", f_height);
				FreeImage_SetMetadataKeyValue(FIMD_COMMENTS, dib, "Raw.Frame.Height", value);
			}

			// Bayer pattern
			// Mask describing the order of color pixels in the matrix. 
			// This field describe 16 pixels (8 rows with two pixels in each, from left to right and from top to bottom). 

			if(RawProcessor->imgdata.idata.filters) {
				// description of colors numbered from 0 to 3 (RGBG,RGBE,GMCY, or GBTG)
				char *cdesc = RawProcessor->imgdata.idata.cdesc;
				if(!cdesc[3]) {
					cdesc[3] = 'G';
				}
				char *pattern = &value[0];
				for(int i = 0; i < 16; i++) {
					pattern[i] = cdesc[ RawProcessor->fcol(i >> 1, i & 1) ];
				}
				pattern[16] = 0;

				FreeImage_SetMetadataKeyValue(FIMD_COMMENTS, dib, "Raw.BayerPattern", value);
			}
		}
	
		return dib;

	} catch(const char *text) {
		FreeImage_Unload(dib);
		FreeImage_OutputMessageProc(s_format_id, text);
		return NULL;
	}
}

// ==========================================================
// Plugin Implementation
// ==========================================================

static const char * DLL_CALLCONV
Format() {
	return "RAW";
}

static const char * DLL_CALLCONV
Description() {
	return "RAW camera image";



( run in 0.560 second using v1.01-cache-2.11-cpan-df04353d9ac )