void LibRaw::deflate_dng_load_raw()
{
	struct tiff_ifd_t * ifd = &tiff_ifd[0];
	while (ifd < &tiff_ifd[libraw_internal_data.identify_data.tiff_nifds] && ifd->offset != libraw_internal_data.unpacker_data.data_offset) ++ifd;
	if (ifd == &tiff_ifd[libraw_internal_data.identify_data.tiff_nifds])
	{
		throw LIBRAW_EXCEPTION_DECODE_RAW;
	}

	float *float_raw_image=0;
	float max = 0.f;

	if(ifd->samples!=1 && ifd->samples!=3 && ifd->samples !=4)
		throw LIBRAW_EXCEPTION_DECODE_RAW; // Only float deflated supported

	if(libraw_internal_data.unpacker_data.tiff_samples != ifd->samples)
		throw LIBRAW_EXCEPTION_DECODE_RAW; // Wrong IFD


	size_t tilesH = (imgdata.sizes.raw_width + libraw_internal_data.unpacker_data.tile_width - 1) / libraw_internal_data.unpacker_data.tile_width;
	size_t tilesV = (imgdata.sizes.raw_height + libraw_internal_data.unpacker_data.tile_length - 1) / libraw_internal_data.unpacker_data.tile_length;
	size_t tileCnt = tilesH * tilesV;


	if (ifd->sample_format == 3)
	{  // Floating point data
		float_raw_image = (float*)calloc(tileCnt*libraw_internal_data.unpacker_data.tile_length* libraw_internal_data.unpacker_data.tile_width * ifd->samples,sizeof(float));
		//imgdata.color.maximum = 65535;
		//imgdata.color.black = 0;
		//memset(imgdata.color.cblack,0,sizeof(imgdata.color.cblack));
	}
	else
		throw LIBRAW_EXCEPTION_DECODE_RAW; // Only float deflated supported

	int xFactor;
	switch(ifd->predictor)
	{
		case 3:
		default:
			xFactor = 1; break;
		case 34894: xFactor = 2; break;
		case 34895: xFactor = 4; break;
	}

	if (libraw_internal_data.unpacker_data.tile_length < INT_MAX)
	{
		if(tileCnt<1 || tileCnt > 1000000)
			throw LIBRAW_EXCEPTION_DECODE_RAW;

		size_t *tOffsets = (size_t*)malloc(tileCnt*sizeof(size_t));
		for (int t = 0; t < tileCnt; ++t)
			tOffsets[t] = get4();

		size_t *tBytes = (size_t*) malloc(tileCnt*sizeof(size_t));
		unsigned long maxBytesInTile = 0;
		if (tileCnt == 1)
			tBytes[0] = maxBytesInTile = ifd->bytes;
		else
		{
			libraw_internal_data.internal_data.input->seek(ifd->bytes, SEEK_SET);
			for (size_t t = 0; t < tileCnt; ++t)
			{
				tBytes[t] = get4();
				maxBytesInTile = MAX(maxBytesInTile,tBytes[t]);
			}
		}
		unsigned tilePixels = libraw_internal_data.unpacker_data.tile_width * libraw_internal_data.unpacker_data.tile_length;
		unsigned pixelSize = sizeof(float)*ifd->samples;
		unsigned tileBytes = tilePixels*pixelSize;
		unsigned tileRowBytes = libraw_internal_data.unpacker_data.tile_width*pixelSize;

		unsigned char *cBuffer = (unsigned char*)malloc(maxBytesInTile);
		unsigned char *uBuffer = (unsigned char*)malloc(tileBytes+tileRowBytes); // extra row for decoding

		for (size_t y = 0, t = 0; y < imgdata.sizes.raw_height; y += libraw_internal_data.unpacker_data.tile_length)
		{
			for (size_t x = 0; x < imgdata.sizes.raw_width; x += libraw_internal_data.unpacker_data.tile_width, ++t)
			{
				libraw_internal_data.internal_data.input->seek(tOffsets[t], SEEK_SET);
				libraw_internal_data.internal_data.input->read(cBuffer, 1, tBytes[t]);
				unsigned long dstLen = tileBytes;
				int err = uncompress(uBuffer+tileRowBytes, &dstLen, cBuffer, tBytes[t]);
				if (err != Z_OK)
				{
					free(tOffsets);
					free(tBytes);
					free(cBuffer);
					free(uBuffer);
					throw LIBRAW_EXCEPTION_DECODE_RAW;
					return;
				}
				else
				{
					int bytesps = ifd->bps >> 3;
					size_t rowsInTile = y + libraw_internal_data.unpacker_data.tile_length > imgdata.sizes.raw_height ? imgdata.sizes.raw_height - y : libraw_internal_data.unpacker_data.tile_length;
					size_t colsInTile= x + libraw_internal_data.unpacker_data.tile_width > imgdata.sizes.raw_width ? imgdata.sizes.raw_width - x : libraw_internal_data.unpacker_data.tile_width;

					for (size_t row = 0; row < rowsInTile; ++row) // do not process full tile if not needed
					{
						unsigned char* dst = uBuffer + row*libraw_internal_data.unpacker_data.tile_width*bytesps*ifd->samples;
						unsigned char* src = dst+tileRowBytes;
						DecodeFPDelta (src,dst,
							libraw_internal_data.unpacker_data.tile_width/ xFactor,
							ifd->samples * xFactor,
							bytesps);
						float lmax = expandFloats(dst, libraw_internal_data.unpacker_data.tile_width*ifd->samples, bytesps);
						max = MAX(max,lmax);
						unsigned char* dst2 = (unsigned char*)&float_raw_image[((y+row)*imgdata.sizes.raw_width + x)*ifd->samples];
						memmove(dst2,dst,colsInTile*ifd->samples*sizeof(float));
					}
				}
			}
		}
		free(tOffsets);
		free(tBytes);
		free(cBuffer);
		free(uBuffer);
	}
	imgdata.color.fmaximum = max;

	// Set fields according to data format

	imgdata.rawdata.raw_alloc = float_raw_image;
	if(ifd->samples == 1)
	{
		imgdata.rawdata.float_image = float_raw_image;
		imgdata.rawdata.sizes.raw_pitch = imgdata.sizes.raw_pitch = imgdata.sizes.raw_width*4;
	}
	else if(ifd->samples == 3)
	{
		imgdata.rawdata.float3_image = (float(*)[3])float_raw_image;
		imgdata.rawdata.sizes.raw_pitch = imgdata.sizes.raw_pitch = imgdata.sizes.raw_width*12;
	}
	else if(ifd->samples == 4)
	{
		imgdata.rawdata.float4_image = (float(*)[4])float_raw_image;
		imgdata.rawdata.sizes.raw_pitch = imgdata.sizes.raw_pitch = imgdata.sizes.raw_width*16;
	}

	if(imgdata.params.raw_processing_options & LIBRAW_PROCESSING_CONVERTFLOAT_TO_INT)
		convertFloatToInt(); // with default settings
}