/*****************************************************************************/
// Copyright 2006-2012 Adobe Systems Incorporated
// All Rights Reserved.
//
// NOTICE:  Adobe permits you to use, modify, and distribute this file in
// accordance with the terms of the Adobe license agreement accompanying it.
/*****************************************************************************/

/* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_negative.cpp#3 $ */ 
/* $DateTime: 2012/06/14 20:24:41 $ */
/* $Change: 835078 $ */
/* $Author: tknoll $ */

/*****************************************************************************/

#include "dng_negative.h"

#include "dng_1d_table.h"
#include "dng_abort_sniffer.h"
#include "dng_area_task.h"
#include "dng_assertions.h"
#include "dng_bottlenecks.h"
#include "dng_camera_profile.h"
#include "dng_color_space.h"
#include "dng_color_spec.h"
#include "dng_exceptions.h"
#include "dng_globals.h"
#include "dng_host.h"
#include "dng_image.h"
#include "dng_image_writer.h"
#include "dng_info.h"
#include "dng_jpeg_image.h"
#include "dng_linearization_info.h"
#include "dng_memory.h"
#include "dng_memory_stream.h"
#include "dng_misc_opcodes.h"
#include "dng_mosaic_info.h"
#include "dng_preview.h"
#include "dng_resample.h"
#include "dng_safe_arithmetic.h"
#include "dng_simple_image.h"
#include "dng_tag_codes.h"
#include "dng_tag_values.h"
#include "dng_tile_iterator.h"
#include "dng_utils.h"

#if qDNGUseXMP
#include "dng_xmp.h"
#endif

/*****************************************************************************/

dng_noise_profile::dng_noise_profile ()

	:	fNoiseFunctions ()

	{
	
	}

/*****************************************************************************/

dng_noise_profile::dng_noise_profile (const dng_std_vector<dng_noise_function> &functions)

	:	fNoiseFunctions (functions)

	{

	}

/*****************************************************************************/

bool dng_noise_profile::IsValid () const
	{

	if (NumFunctions () == 0 || NumFunctions () > kMaxColorPlanes)
		{
		return false;
		}
	
	for (uint32 plane = 0; plane < NumFunctions (); plane++)
		{
		
		if (!NoiseFunction (plane).IsValid ())
			{
			return false;
			}
		
		}

	return true;
	
	}

/*****************************************************************************/

bool dng_noise_profile::IsValidForNegative (const dng_negative &negative) const
	{
	
	if (!(NumFunctions () == 1 || NumFunctions () == negative.ColorChannels ()))
		{
		return false;
		}

	return IsValid ();

	}

/*****************************************************************************/

const dng_noise_function & dng_noise_profile::NoiseFunction (uint32 plane) const
	{
	
	if (NumFunctions () == 1)
		{
		return fNoiseFunctions.front ();
		}

	DNG_REQUIRE (plane < NumFunctions (), 
				 "Bad plane index argument for NoiseFunction ().");

	return fNoiseFunctions [plane];
	
	}

/*****************************************************************************/

uint32 dng_noise_profile::NumFunctions () const
	{
	return (uint32) fNoiseFunctions.size ();
	}

/*****************************************************************************/

dng_metadata::dng_metadata (dng_host &host)

	:	fHasBaseOrientation 		(false)
	,	fBaseOrientation    		()
	,	fIsMakerNoteSafe			(false)
	,	fMakerNote					()
	,	fExif			    		(host.Make_dng_exif ())
	,	fOriginalExif				()
	,	fIPTCBlock          		()
	,	fIPTCOffset					(kDNGStreamInvalidOffset)
	
	#if qDNGUseXMP
	
	,	fXMP			    		(host.Make_dng_xmp ())
	
	#endif
	
	,	fEmbeddedXMPDigest       	()
	,	fXMPinSidecar	    		(false)
	,	fXMPisNewer		    		(false)
	,	fSourceMIMI					()

	{
	}

/*****************************************************************************/

dng_metadata::~dng_metadata ()
	{
	}
	
/******************************************************************************/

template< class T >
T * CloneAutoPtr (const AutoPtr< T > &ptr)
	{
	
	return ptr.Get () ? ptr->Clone () : NULL;
	
	}

/******************************************************************************/

template< class T, typename U >
T * CloneAutoPtr (const AutoPtr< T > &ptr, U &u)
	{
	
	return ptr.Get () ? ptr->Clone (u) : NULL;
	
	}

/******************************************************************************/

dng_metadata::dng_metadata (const dng_metadata &rhs,
							dng_memory_allocator &allocator)

	:	fHasBaseOrientation 		(rhs.fHasBaseOrientation)
	,	fBaseOrientation    		(rhs.fBaseOrientation)
	,	fIsMakerNoteSafe			(rhs.fIsMakerNoteSafe)
	,	fMakerNote					(CloneAutoPtr (rhs.fMakerNote, allocator))
	,	fExif			    		(CloneAutoPtr (rhs.fExif))
	,	fOriginalExif				(CloneAutoPtr (rhs.fOriginalExif))
	,	fIPTCBlock          		(CloneAutoPtr (rhs.fIPTCBlock, allocator))
	,	fIPTCOffset					(rhs.fIPTCOffset)
	
	#if qDNGUseXMP
	
	,	fXMP			    		(CloneAutoPtr (rhs.fXMP))
	
	#endif
	
	,	fEmbeddedXMPDigest       	(rhs.fEmbeddedXMPDigest)
	,	fXMPinSidecar	    		(rhs.fXMPinSidecar)
	,	fXMPisNewer		    		(rhs.fXMPisNewer)
	,	fSourceMIMI					(rhs.fSourceMIMI)

	{

	}

/******************************************************************************/

dng_metadata * dng_metadata::Clone (dng_memory_allocator &allocator) const
	{
	
	return new dng_metadata (*this, allocator);
	
	}

/******************************************************************************/

void dng_metadata::SetBaseOrientation (const dng_orientation &orientation)
	{
	
	fHasBaseOrientation = true;
	
	fBaseOrientation = orientation;
	
	}
		
/******************************************************************************/

void dng_metadata::ApplyOrientation (const dng_orientation &orientation)
	{
	
	fBaseOrientation += orientation;

	#if qDNGUseXMP
	
	fXMP->SetOrientation (fBaseOrientation);
	
	#endif

	}
				  
/*****************************************************************************/

void dng_metadata::ResetExif (dng_exif * newExif)
	{

	fExif.Reset (newExif);

	}

/******************************************************************************/

dng_memory_block * dng_metadata::BuildExifBlock (dng_memory_allocator &allocator,
												 const dng_resolution *resolution,
												 bool includeIPTC,
												 const dng_jpeg_preview *thumbnail) const
	{
	
	dng_memory_stream stream (allocator);
	
		{
	
		// Create the main IFD
											 
		dng_tiff_directory mainIFD;
		
		// Optionally include the resolution tags.
		
		dng_resolution res;
		
		if (resolution)
			{
			res = *resolution;
			}
	
		tag_urational tagXResolution (tcXResolution, res.fXResolution);
		tag_urational tagYResolution (tcYResolution, res.fYResolution);
		
		tag_uint16 tagResolutionUnit (tcResolutionUnit, res.fResolutionUnit);
		
		if (resolution)
			{
			mainIFD.Add (&tagXResolution   );
			mainIFD.Add (&tagYResolution   );
			mainIFD.Add (&tagResolutionUnit);
			}

		// Optionally include IPTC block.
		
		tag_iptc tagIPTC (IPTCData   (),
						  IPTCLength ());
			
		if (includeIPTC && tagIPTC.Count ())
			{
			mainIFD.Add (&tagIPTC);
			}
							
		// Exif tags.
		
		exif_tag_set exifSet (mainIFD,
							  *GetExif (),
							  IsMakerNoteSafe (),
							  MakerNoteData   (),
							  MakerNoteLength (),
							  false);
							  
		// Figure out the Exif IFD offset.
		
		uint32 exifOffset = 8 + mainIFD.Size ();
		
		exifSet.Locate (exifOffset);
		
		// Thumbnail IFD (if any).
		
		dng_tiff_directory thumbIFD;
		
		tag_uint16 thumbCompression (tcCompression, ccOldJPEG);
		
		tag_urational thumbXResolution (tcXResolution, dng_urational (72, 1));
		tag_urational thumbYResolution (tcYResolution, dng_urational (72, 1));
		
		tag_uint16 thumbResolutionUnit (tcResolutionUnit, ruInch);
		
		tag_uint32 thumbDataOffset (tcJPEGInterchangeFormat      , 0);
		tag_uint32 thumbDataLength (tcJPEGInterchangeFormatLength, 0);
		
		if (thumbnail)
			{
			
			thumbIFD.Add (&thumbCompression);
			
			thumbIFD.Add (&thumbXResolution);
			thumbIFD.Add (&thumbYResolution);
			thumbIFD.Add (&thumbResolutionUnit);
			
			thumbIFD.Add (&thumbDataOffset);
			thumbIFD.Add (&thumbDataLength);
			
			thumbDataLength.Set (thumbnail->fCompressedData->LogicalSize ());
			
			uint32 thumbOffset = exifOffset + exifSet.Size ();
			
			mainIFD.SetChained (thumbOffset);
			
			thumbDataOffset.Set (thumbOffset + thumbIFD.Size ());
			
			}
			
		// Don't write anything unless the main IFD has some tags.
		
		if (mainIFD.Size () != 0)
			{
					
			// Write TIFF Header.
			
			stream.SetWritePosition (0);
			
			stream.Put_uint16 (stream.BigEndian () ? byteOrderMM : byteOrderII);
			
			stream.Put_uint16 (42);
			
			stream.Put_uint32 (8);
			
			// Write the IFDs.
			
			mainIFD.Put (stream);
			
			exifSet.Put (stream);
			
			if (thumbnail)
				{
				
				thumbIFD.Put (stream);
				
				stream.Put (thumbnail->fCompressedData->Buffer      (),
							thumbnail->fCompressedData->LogicalSize ());
				
				}
				
			// Trim the file to this length.
			
			stream.Flush ();
			
			stream.SetLength (stream.Position ());
			
			}
		
		}
		
	return stream.AsMemoryBlock (allocator);
		
	}
			
/******************************************************************************/

void dng_metadata::SetIPTC (AutoPtr<dng_memory_block> &block, uint64 offset)
	{
	
	fIPTCBlock.Reset (block.Release ());
	
	fIPTCOffset = offset;
	
	}
					  
/******************************************************************************/

void dng_metadata::SetIPTC (AutoPtr<dng_memory_block> &block)
	{
	
	SetIPTC (block, kDNGStreamInvalidOffset);
	
	}
					  
/******************************************************************************/

void dng_metadata::ClearIPTC ()
	{
	
	fIPTCBlock.Reset ();
	
	fIPTCOffset = kDNGStreamInvalidOffset;
	
	}
					  
/*****************************************************************************/

const void * dng_metadata::IPTCData () const
	{
	
	if (fIPTCBlock.Get ())
		{
		
		return fIPTCBlock->Buffer ();
		
		}
		
	return NULL;
	
	}

/*****************************************************************************/

uint32 dng_metadata::IPTCLength () const
	{
	
	if (fIPTCBlock.Get ())
		{
		
		return fIPTCBlock->LogicalSize ();
		
		}
		
	return 0;
	
	}
		
/*****************************************************************************/

uint64 dng_metadata::IPTCOffset () const
	{
	
	if (fIPTCBlock.Get ())
		{
		
		return fIPTCOffset;
		
		}
		
	return kDNGStreamInvalidOffset;
	
	}
		
/*****************************************************************************/

dng_fingerprint dng_metadata::IPTCDigest (bool includePadding) const
	{
	
	if (IPTCLength ())
		{
		
		dng_md5_printer printer;
		
		const uint8 *data = (const uint8 *) IPTCData ();
		
		uint32 count = IPTCLength ();
		
		// Because of some stupid ways of storing the IPTC data, the IPTC
		// data might be padded with up to three zeros.  The official Adobe
		// logic is to include these zeros in the digest.  However, older
		// versions of the Camera Raw code did not include the padding zeros
		// in the digest, so we support both methods and allow either to
		// match.
		
		if (!includePadding)
			{
		
			uint32 removed = 0;
			
			while ((removed < 3) && (count > 0) && (data [count - 1] == 0))
				{
				removed++;
				count--;
				}
				
			}
		
		printer.Process (data, count);
						 
		return printer.Result ();
			
		}
	
	return dng_fingerprint ();
	
	}
		
/******************************************************************************/

#if qDNGUseXMP

void dng_metadata::RebuildIPTC (dng_memory_allocator &allocator,
								bool padForTIFF)
	{
	
	ClearIPTC ();
	
	fXMP->RebuildIPTC (*this, allocator, padForTIFF);
	
	dng_fingerprint digest = IPTCDigest ();
	
	fXMP->SetIPTCDigest (digest);
	
	}
			  
/*****************************************************************************/

void dng_metadata::ResetXMP (dng_xmp * newXMP)
	{
	
	fXMP.Reset (newXMP);
	
	}

/*****************************************************************************/

void dng_metadata::ResetXMPSidecarNewer (dng_xmp * newXMP,
										 bool inSidecar,
										 bool isNewer )
	{

	fXMP.Reset (newXMP);

	fXMPinSidecar = inSidecar;

	fXMPisNewer = isNewer;

	}

/*****************************************************************************/

bool dng_metadata::SetXMP (dng_host &host,
						   const void *buffer,
					 	   uint32 count,
					 	   bool xmpInSidecar,
					 	   bool xmpIsNewer)
	{
	
	bool result = false;
	
	try
		{
		
		AutoPtr<dng_xmp> tempXMP (host.Make_dng_xmp ());
		
		tempXMP->Parse (host, buffer, count);
		
		ResetXMPSidecarNewer (tempXMP.Release (), xmpInSidecar, xmpIsNewer);
		
		result = true;
		
		}
		
	catch (dng_exception &except)
		{
		
		// Don't ignore transient errors.
		
		if (host.IsTransientError (except.ErrorCode ()))
			{
			
			throw;
			
			}
			
		// Eat other parsing errors.
		
		}
		
	catch (...)
		{
		
		// Eat unknown parsing exceptions.
		
		}
	
	return result;
	
	}

/*****************************************************************************/

void dng_metadata::SetEmbeddedXMP (dng_host &host,
								   const void *buffer,
								   uint32 count)
	{
	
	if (SetXMP (host, buffer, count))
		{
		
		dng_md5_printer printer;
		
		printer.Process (buffer, count);
		
		fEmbeddedXMPDigest = printer.Result ();
		
		// Remove any sidecar specific tags from embedded XMP.
		
		if (fXMP.Get ())
			{
		
			fXMP->Remove (XMP_NS_PHOTOSHOP, "SidecarForExtension");
			fXMP->Remove (XMP_NS_PHOTOSHOP, "EmbeddedXMPDigest");
			
			}
		
		}
		
	else
		{
		
		fEmbeddedXMPDigest.Clear ();
		
		}

	}

#endif

/*****************************************************************************/

void dng_metadata::SynchronizeMetadata ()
	{
	
	if (!fOriginalExif.Get ())
		{
		
		fOriginalExif.Reset (fExif->Clone ());
		
		}
		
	#if qDNGUseXMP
	
	fXMP->ValidateMetadata ();
	
	fXMP->IngestIPTC (*this, fXMPisNewer);
	
	fXMP->SyncExif (*fExif.Get ());
	
	fXMP->SyncOrientation (*this, fXMPinSidecar);
	
	#endif
	
	}
					
/*****************************************************************************/

void dng_metadata::UpdateDateTime (const dng_date_time_info &dt)
	{
	
	fExif->UpdateDateTime (dt);
	
#if qDNGUseXMP
	fXMP->UpdateDateTime (dt);
#endif
	
	}
					
/*****************************************************************************/

void dng_metadata::UpdateDateTimeToNow ()
	{
	
	dng_date_time_info dt;
	
	CurrentDateTimeAndZone (dt);
	
	UpdateDateTime (dt);
	
	#if qDNGUseXMP
	
	fXMP->UpdateMetadataDate (dt);
	
	#endif
	
	}
					
/*****************************************************************************/

void dng_metadata::UpdateMetadataDateTimeToNow ()
	{
	
	dng_date_time_info dt;
	
	CurrentDateTimeAndZone (dt);
	
#if qDNGUseXMP
	fXMP->UpdateMetadataDate (dt);
#endif
	
	}
					
/*****************************************************************************/

dng_negative::dng_negative (dng_host &host)

	:	fAllocator						(host.Allocator ())
	
	,	fModelName						()
	,	fLocalName						()
	,	fDefaultCropSizeH				()
	,	fDefaultCropSizeV				()
	,	fDefaultCropOriginH				(0, 1)
	,	fDefaultCropOriginV				(0, 1)
	,	fDefaultUserCropT				(0, 1)
	,	fDefaultUserCropL				(0, 1)
	,	fDefaultUserCropB				(1, 1)
	,	fDefaultUserCropR				(1, 1)
	,	fDefaultScaleH					(1, 1)
	,	fDefaultScaleV					(1, 1)
	,	fBestQualityScale				(1, 1)
	,	fOriginalDefaultFinalSize		()
	,	fOriginalBestQualityFinalSize	()
	,	fOriginalDefaultCropSizeH	    ()
	,	fOriginalDefaultCropSizeV	    ()
	,	fRawToFullScaleH				(1.0)
	,	fRawToFullScaleV				(1.0)
	,	fBaselineNoise					(100, 100)
	,	fNoiseReductionApplied			(0, 0)
	,	fNoiseProfile					()
	,	fBaselineExposure				(  0, 100)
	,	fBaselineSharpness				(100, 100)
	,	fChromaBlurRadius				()
	,	fAntiAliasStrength				(100, 100)
	,	fLinearResponseLimit			(100, 100)
	,	fShadowScale					(1, 1)
	,	fColorimetricReference			(crSceneReferred)
	,	fColorChannels					(0)
	,	fAnalogBalance					()
	,	fCameraNeutral					()
	,	fCameraWhiteXY					()
	,	fCameraCalibration1				()
	,	fCameraCalibration2				()
	,	fCameraCalibrationSignature		()
	,	fCameraProfile					()
	,	fAsShotProfileName				()
	,	fRawImageDigest					()
	,	fNewRawImageDigest				()
	,	fRawDataUniqueID				()
	,	fOriginalRawFileName			()
	,	fHasOriginalRawFileData			(false)
	,	fOriginalRawFileData			()
	,	fOriginalRawFileDigest			()
	,	fDNGPrivateData					()
	,	fMetadata						(host)
	,	fLinearizationInfo				()
	,	fMosaicInfo						()
	,	fOpcodeList1					(1)
	,	fOpcodeList2					(2)
	,	fOpcodeList3					(3)
	,	fStage1Image					()
	,	fStage2Image					()
	,	fStage3Image					()
	,	fStage3Gain						(1.0)
	,	fIsPreview						(false)
	,	fIsDamaged						(false)
	,	fRawImageStage					(rawImageStageNone)
	,	fRawImage						()
	,	fRawFloatBitDepth				(0)
	,	fRawJPEGImage					()
	,	fRawJPEGImageDigest				()
	,	fTransparencyMask				()
	,	fRawTransparencyMask			()
	,	fRawTransparencyMaskBitDepth	(0)
	,	fUnflattenedStage3Image			()

	{

	}

/*****************************************************************************/

dng_negative::~dng_negative ()
	{
	
	// Delete any camera profiles owned by this negative.
	
	ClearProfiles ();
		
	}

/******************************************************************************/

void dng_negative::Initialize ()
	{
	
	}

/******************************************************************************/

dng_negative * dng_negative::Make (dng_host &host)
	{
	
	AutoPtr<dng_negative> result (new dng_negative (host));
	
	if (!result.Get ())
		{
		ThrowMemoryFull ();
		}
	
	result->Initialize ();
	
	return result.Release ();
	
	}

/******************************************************************************/

dng_metadata * dng_negative::CloneInternalMetadata () const
	{
	
	return InternalMetadata ().Clone (Allocator ());
	
	}

/******************************************************************************/

dng_orientation dng_negative::ComputeOrientation (const dng_metadata &metadata) const
	{
	
	return metadata.BaseOrientation ();
	
	}
		
/******************************************************************************/

void dng_negative::SetAnalogBalance (const dng_vector &b)
	{
	
	real64 minEntry = b.MinEntry ();
	
	if (b.NotEmpty () && minEntry > 0.0)
		{
		
		fAnalogBalance = b;
	
		fAnalogBalance.Scale (1.0 / minEntry);
		
		fAnalogBalance.Round (1000000.0);
		
		}
		
	else
		{
		
		fAnalogBalance.Clear ();
		
		}
		
	}
					  
/*****************************************************************************/

real64 dng_negative::AnalogBalance (uint32 channel) const
	{
	
	DNG_ASSERT (channel < ColorChannels (), "Channel out of bounds");
	
	if (channel < fAnalogBalance.Count ())
		{
		
		return fAnalogBalance [channel];
		
		}
		
	return 1.0;
	
	}
		
/*****************************************************************************/

dng_urational dng_negative::AnalogBalanceR (uint32 channel) const
	{
	
	dng_urational result;
	
	result.Set_real64 (AnalogBalance (channel), 1000000);
	
	return result;
	
	}

/******************************************************************************/

void dng_negative::SetCameraNeutral (const dng_vector &n)
	{
	
	real64 maxEntry = n.MaxEntry ();
		
	if (n.NotEmpty () && maxEntry > 0.0)
		{
		
		fCameraNeutral = n;
	
		fCameraNeutral.Scale (1.0 / maxEntry);
		
		fCameraNeutral.Round (1000000.0);
		
		}
		
	else
		{
		
		fCameraNeutral.Clear ();
		
		}

	}
	  
/*****************************************************************************/

dng_urational dng_negative::CameraNeutralR (uint32 channel) const
	{
	
	dng_urational result;
	
	result.Set_real64 (CameraNeutral () [channel], 1000000);
	
	return result;
	
	}

/******************************************************************************/

void dng_negative::SetCameraWhiteXY (const dng_xy_coord &coord)
	{
	
	if (coord.IsValid ())
		{
		
		fCameraWhiteXY.x = Round_int32 (coord.x * 1000000.0) / 1000000.0;
		fCameraWhiteXY.y = Round_int32 (coord.y * 1000000.0) / 1000000.0;
		
		}
		
	else
		{
		
		fCameraWhiteXY.Clear ();
		
		}
	
	}
		
/*****************************************************************************/

const dng_xy_coord & dng_negative::CameraWhiteXY () const
	{
	
	DNG_ASSERT (HasCameraWhiteXY (), "Using undefined CameraWhiteXY");

	return fCameraWhiteXY;
	
	}
							   
/*****************************************************************************/

void dng_negative::GetCameraWhiteXY (dng_urational &x,
							   		 dng_urational &y) const
	{
	
	dng_xy_coord coord = CameraWhiteXY ();
	
	x.Set_real64 (coord.x, 1000000);
	y.Set_real64 (coord.y, 1000000);
	
	}
		
/*****************************************************************************/

void dng_negative::SetCameraCalibration1 (const dng_matrix &m)
	{
	
	fCameraCalibration1 = m;
	
	fCameraCalibration1.Round (10000);
	
	}

/******************************************************************************/

void dng_negative::SetCameraCalibration2 (const dng_matrix &m)
	{
	
	fCameraCalibration2 = m;
	
	fCameraCalibration2.Round (10000);
		
	}

/******************************************************************************/

void dng_negative::AddProfile (AutoPtr<dng_camera_profile> &profile)
	{
	
	// Make sure we have a profile to add.
	
	if (!profile.Get ())
		{
		
		return;
		
		}
	
	// We must have some profile name.  Use "embedded" if nothing else.
	
	if (profile->Name ().IsEmpty ())
		{
		
		profile->SetName (kProfileName_Embedded);
		
		}
		
	// Special case support for reading older DNG files which did not store
	// the profile name in the main IFD profile.
	
	if (fCameraProfile.size ())
		{
		
		// See the first profile has a default "embedded" name, and has
		// the same data as the profile we are adding.
		
		if (fCameraProfile [0]->NameIsEmbedded () &&
			fCameraProfile [0]->EqualData (*profile.Get ()))
			{
			
			// If the profile we are deleting was read from DNG
			// then the new profile should be marked as such also.
			
			if (fCameraProfile [0]->WasReadFromDNG ())
				{
				
				profile->SetWasReadFromDNG ();
				
				}
				
			// If the profile we are deleting wasn't read from disk then the new
			// profile should be marked as such also.
			
			if (!fCameraProfile [0]->WasReadFromDisk ())
				{
				
				profile->SetWasReadFromDisk (false);
				
				}
				
			// Delete the profile with default name.
			
			delete fCameraProfile [0];
			
			fCameraProfile [0] = NULL;
			
			fCameraProfile.erase (fCameraProfile.begin ());
			
			}
		
		}
		
	// Duplicate detection logic.  We give a preference to last added profile
	// so the profiles end up in a more consistent order no matter what profiles
	// happen to be embedded in the DNG.
	
	for (uint32 index = 0; index < (uint32) fCameraProfile.size (); index++)
		{

		// Instead of checking for matching fingerprints, we check that the two
		// profiles have the same color and have the same name. This allows two
		// profiles that are identical except for copyright string and embed policy
		// to be considered duplicates.

		const bool equalColorAndSameName = (fCameraProfile [index]->EqualData (*profile.Get ()) &&
											fCameraProfile [index]->Name () == profile->Name ());

		if (equalColorAndSameName)
			{
			
			// If the profile we are deleting was read from DNG
			// then the new profile should be marked as such also.
			
			if (fCameraProfile [index]->WasReadFromDNG ())
				{
				
				profile->SetWasReadFromDNG ();
				
				}
				
			// If the profile we are deleting wasn't read from disk then the new
			// profile should be marked as such also.
			
			if (!fCameraProfile [index]->WasReadFromDisk ())
				{
				
				profile->SetWasReadFromDisk (false);
				
				}
				
			// Delete the duplicate profile.
			
			delete fCameraProfile [index];
			
			fCameraProfile [index] = NULL;
			
			fCameraProfile.erase (fCameraProfile.begin () + index);
			
			break;
			
			}
			
		}
		
	// Now add to profile list.
	
	fCameraProfile.push_back (NULL);
	
	fCameraProfile [fCameraProfile.size () - 1] = profile.Release ();
	
	}
			
/******************************************************************************/

void dng_negative::ClearProfiles ()
	{
	
	// Delete any camera profiles owned by this negative.
	
	for (uint32 index = 0; index < (uint32) fCameraProfile.size (); index++)
		{
		
		if (fCameraProfile [index])
			{
			
			delete fCameraProfile [index];
			
			fCameraProfile [index] = NULL;
			
			}
		
		}
		
	// Now empty list.
	
	fCameraProfile.clear ();
	
	}

/*****************************************************************************/

void dng_negative::ClearProfiles (bool clearBuiltinMatrixProfiles,
								  bool clearReadFromDisk)
	{

	// If neither flag is set, then there's nothing to do.

	if (!clearBuiltinMatrixProfiles &&
		!clearReadFromDisk)
		{
		return;
		}
	
	// Delete any camera profiles in this negative that match the specified criteria.

	dng_std_vector<dng_camera_profile *>::iterator iter = fCameraProfile.begin ();
	dng_std_vector<dng_camera_profile *>::iterator next;
	
	for (; iter != fCameraProfile.end (); iter = next)
		{

		dng_camera_profile *profile = *iter;

		// If the profile is invalid (i.e., NULL pointer), or meets one of the
		// specified criteria, then axe it.

		if (!profile ||
			(clearBuiltinMatrixProfiles && profile->WasBuiltinMatrix ()) ||
			(clearReadFromDisk			&& profile->WasReadFromDisk	 ()))
			{
			
			delete profile;

			next = fCameraProfile.erase (iter);

			}

		// Otherwise, just advance to the next element.

		else
			{
			
			next = iter + 1;
			
			}

		}
	
	}

/******************************************************************************/

uint32 dng_negative::ProfileCount () const
	{
	
	return (uint32) fCameraProfile.size ();
	
	}
		
/******************************************************************************/

const dng_camera_profile & dng_negative::ProfileByIndex (uint32 index) const
	{
	
	DNG_ASSERT (index < ProfileCount (),
				"Invalid index for ProfileByIndex");
				
	return *fCameraProfile [index];
		
	}
		
/*****************************************************************************/

const dng_camera_profile * dng_negative::ProfileByID (const dng_camera_profile_id &id,
													  bool useDefaultIfNoMatch) const
	{
	
	uint32 index;
	
	// If this negative does not have any profiles, we are not going to
	// find a match.
	
	uint32 profileCount = ProfileCount ();
	
	if (profileCount == 0)
		{
		return NULL;
		}
		
	// If we have both a profile name and fingerprint, try matching both.
	
	if (id.Name ().NotEmpty () && id.Fingerprint ().IsValid ())
		{
		
		for (index = 0; index < profileCount; index++)
			{
			
			const dng_camera_profile &profile = ProfileByIndex (index);
			
			if (id.Name        () == profile.Name        () &&
				id.Fingerprint () == profile.Fingerprint ())
				{
				
				return &profile;
				
				}
			
			}

		}
		
	// If we have a name, try matching that.
	
	if (id.Name ().NotEmpty ())
		{
		
		for (index = 0; index < profileCount; index++)
			{
			
			const dng_camera_profile &profile = ProfileByIndex (index);
			
			if (id.Name () == profile.Name ())
				{
				
				return &profile;
				
				}
			
			}

		}
		
	// If we have a valid fingerprint, try matching that.
		
	if (id.Fingerprint ().IsValid ())
		{
		
		for (index = 0; index < profileCount; index++)
			{
			
			const dng_camera_profile &profile = ProfileByIndex (index);
			
			if (id.Fingerprint () == profile.Fingerprint ())
				{
				
				return &profile;
				
				}
			
			}

		}
		
	// Try "upgrading" profile name versions.
	
	if (id.Name ().NotEmpty ())
		{
		
		dng_string baseName;
		int32      version;
		
		SplitCameraProfileName (id.Name (),
								baseName,
								version);
		
		int32 bestIndex   = -1;
		int32 bestVersion = 0;
		
		for (index = 0; index < profileCount; index++)
			{
			
			const dng_camera_profile &profile = ProfileByIndex (index);
			
			if (profile.Name ().StartsWith (baseName.Get ()))
				{
				
				dng_string testBaseName;
				int32      testVersion;
				
				SplitCameraProfileName (profile.Name (),
										testBaseName,
										testVersion);
										
				if (bestIndex == -1 || testVersion > bestVersion)
					{
					
					bestIndex   = index;
					bestVersion = testVersion;
					
					}
					
				}
				
			}
			
		if (bestIndex != -1)
			{
			
			return &ProfileByIndex (bestIndex);
			
			}
		
		}
		
	// Did not find a match any way.  See if we should return a default value.
	
	if (useDefaultIfNoMatch)
		{
		
		return &ProfileByIndex (0);
		
		}
		
	// Found nothing.
	
	return NULL;
		
	}

/*****************************************************************************/

const dng_camera_profile * dng_negative::ComputeCameraProfileToEmbed
										(const dng_metadata & /* metadata */) const
	{
	
	uint32 index;
	
	uint32 count = ProfileCount ();
	
	if (count == 0)
		{
		
		return NULL;
		
		}
		
	// First try to look for the first profile that was already in the DNG
	// when we read it.
	
	for (index = 0; index < count; index++)
		{
		
		const dng_camera_profile &profile (ProfileByIndex (index));
		
		if (profile.WasReadFromDNG ())
			{
			
			return &profile;
			
			}
		
		}
		
	// Next we look for the first profile that is legal to embed.
	
	for (index = 0; index < count; index++)
		{
		
		const dng_camera_profile &profile (ProfileByIndex (index));
		
		if (profile.IsLegalToEmbed ())
			{
			
			return &profile;
			
			}
		
		}
		
	// Else just return the first profile.
	
	return fCameraProfile [0];
	
	}
							   
/*****************************************************************************/

dng_color_spec * dng_negative::MakeColorSpec (const dng_camera_profile_id &id) const
	{

	dng_color_spec *spec = new dng_color_spec (*this, ProfileByID (id));
											   
	if (!spec)
		{
		ThrowMemoryFull ();
		}
		
	return spec;
	
	}
							   
/*****************************************************************************/

dng_fingerprint dng_negative::FindImageDigest (dng_host &host,
											   const dng_image &image) const
	{
	
	dng_md5_printer printer;
	
	dng_pixel_buffer buffer (image.Bounds (), 0, image.Planes (),
		 image.PixelType (), pcInterleaved, NULL);
	
	// Sometimes we expand 8-bit data to 16-bit data while reading or
	// writing, so always compute the digest of 8-bit data as 16-bits.
	
	if (buffer.fPixelType == ttByte)
		{
		buffer.fPixelType = ttShort;
		buffer.fPixelSize = 2;
		}
	
	const uint32 kBufferRows = 16;
	
	uint32 bufferBytes = 0;
	
	if (!SafeUint32Mult (kBufferRows, buffer.fRowStep, &bufferBytes) ||
		 !SafeUint32Mult (bufferBytes, buffer.fPixelSize, &bufferBytes))
		{
		
		ThrowMemoryFull("Arithmetic overflow computing buffer size.");
		
		}
	
	AutoPtr<dng_memory_block> bufferData (host.Allocate (bufferBytes));
	
	buffer.fData = bufferData->Buffer ();
	
	dng_rect area;
	
	dng_tile_iterator iter (dng_point (kBufferRows,
									   image.Width ()),
							image.Bounds ());
							
	while (iter.GetOneTile (area))
		{
		
		host.SniffForAbort ();
		
		buffer.fArea = area;
		
		image.Get (buffer);
		
		uint32 count = buffer.fArea.H () *
					   buffer.fRowStep *
					   buffer.fPixelSize;
					   
		#if qDNGBigEndian
		
		// We need to use the same byte order to compute
		// the digest, no matter the native order.  Little-endian
		// is more common now, so use that.
		
		switch (buffer.fPixelSize)
			{
			
			case 1:
				break;
			
			case 2:
				{
				DoSwapBytes16 ((uint16 *) buffer.fData, count >> 1);
				break;
				}
			
			case 4:
				{
				DoSwapBytes32 ((uint32 *) buffer.fData, count >> 2);
				break;
				}
				
			default:
				{
				DNG_REPORT ("Unexpected pixel size");
				break;
				}
			
			}
		
		#endif

		printer.Process (buffer.fData,
						 count);
		
		}
			
	return printer.Result ();
	
	}
							   
/*****************************************************************************/

void dng_negative::FindRawImageDigest (dng_host &host) const
	{
	
	if (fRawImageDigest.IsNull ())
		{
		
		// Since we are adding the floating point and transparency support 
		// in DNG 1.4, and there are no legacy floating point or transparent
		// DNGs, switch to using the more MP friendly algorithm to compute
		// the digest for these images.
		
		if (RawImage ().PixelType () == ttFloat || RawTransparencyMask ())
			{
			
			FindNewRawImageDigest (host);
			
			fRawImageDigest = fNewRawImageDigest;
			
			}
			
		else
			{
			
			#if qDNGValidate
			
			dng_timer timeScope ("FindRawImageDigest time");

			#endif
		
			fRawImageDigest = FindImageDigest (host, RawImage ());
			
			}
	
		}
	
	}
							   
/*****************************************************************************/

class dng_find_new_raw_image_digest_task : public dng_area_task
	{
	
	private:
	
		enum
			{
			kTileSize = 256
			};
			
		const dng_image &fImage;
		
		uint32 fPixelType;
		uint32 fPixelSize;
		
		uint32 fTilesAcross;
		uint32 fTilesDown;
		
		uint32 fTileCount;
		
		AutoArray<dng_fingerprint> fTileHash;
		
		AutoPtr<dng_memory_block> fBufferData [kMaxMPThreads];
	
	public:
	
		dng_find_new_raw_image_digest_task (const dng_image &image,
											uint32 pixelType)
		
			:	fImage       (image)
			,	fPixelType   (pixelType)
			,	fPixelSize	 (TagTypeSize (pixelType))
			,	fTilesAcross (0)
			,	fTilesDown   (0)
			,	fTileCount   (0)
			,	fTileHash    ()
			
			{
			
			fMinTaskArea = 1;
									
			fUnitCell = dng_point (Min_int32 (kTileSize, fImage.Bounds ().H ()),
								   Min_int32 (kTileSize, fImage.Bounds ().W ()));
								   
			fMaxTileSize = fUnitCell;
						
			}
	
		virtual void Start (uint32 threadCount,
							const dng_point &tileSize,
							dng_memory_allocator *allocator,
							dng_abort_sniffer * /* sniffer */)
			{
			
			if (tileSize != fUnitCell)
				{
				ThrowProgramError ();
				}
				
			fTilesAcross = (fImage.Bounds ().W () + fUnitCell.h - 1) / fUnitCell.h;
			fTilesDown   = (fImage.Bounds ().H () + fUnitCell.v - 1) / fUnitCell.v;
			
			fTileCount = fTilesAcross * fTilesDown;
						 
			fTileHash.Reset (fTileCount);
			
			const uint32 bufferSize =
				ComputeBufferSize(fPixelType, tileSize, fImage.Planes(),
								  padNone);
			
			for (uint32 index = 0; index < threadCount; index++)
				{
				
				fBufferData [index].Reset (allocator->Allocate (bufferSize));
				
				}
			
			}

		virtual void Process (uint32 threadIndex,
							  const dng_rect &tile,
							  dng_abort_sniffer * /* sniffer */)
			{
			
			int32 colIndex = (tile.l - fImage.Bounds ().l) / fUnitCell.h;
			int32 rowIndex = (tile.t - fImage.Bounds ().t) / fUnitCell.v;
			
			DNG_ASSERT (tile.l == fImage.Bounds ().l + colIndex * fUnitCell.h &&
						tile.t == fImage.Bounds ().t + rowIndex * fUnitCell.v,
						"Bad tile origin");
			
			uint32 tileIndex = rowIndex * fTilesAcross + colIndex;
			
			dng_pixel_buffer buffer (tile, 0, fImage.Planes (),
				 fPixelType, pcPlanar,
				 fBufferData [threadIndex]->Buffer ());
			
			fImage.Get (buffer);
			
			uint32 count = buffer.fPlaneStep *
						   buffer.fPlanes *
						   buffer.fPixelSize;
			
			#if qDNGBigEndian
			
			// We need to use the same byte order to compute
			// the digest, no matter the native order.  Little-endian
			// is more common now, so use that.
			
			switch (buffer.fPixelSize)
				{
				
				case 1:
					break;
				
				case 2:
					{
					DoSwapBytes16 ((uint16 *) buffer.fData, count >> 1);
					break;
					}
				
				case 4:
					{
					DoSwapBytes32 ((uint32 *) buffer.fData, count >> 2);
					break;
					}
					
				default:
					{
					DNG_REPORT ("Unexpected pixel size");
					break;
					}
				
				}

			#endif
			
			dng_md5_printer printer;
			
			printer.Process (buffer.fData, count);
							 
			fTileHash [tileIndex] = printer.Result ();
			
			}
			
		dng_fingerprint Result ()
			{
			
			dng_md5_printer printer;
			
			for (uint32 tileIndex = 0; tileIndex < fTileCount; tileIndex++)
				{
				
				printer.Process (fTileHash [tileIndex] . data, 16);
				
				}
				
			return printer.Result ();
			
			}
		
	};

/*****************************************************************************/

void dng_negative::FindNewRawImageDigest (dng_host &host) const
	{
	
	if (fNewRawImageDigest.IsNull ())
		{
		
		#if qDNGValidate
		
		dng_timer timeScope ("FindNewRawImageDigest time");

		#endif
		
		// Find fast digest of the raw image.
		
			{
		
			const dng_image &rawImage = RawImage ();
			
			// Find pixel type that will be saved in the file.  When saving DNGs, we convert
			// some 16-bit data to 8-bit data, so we need to do the matching logic here.
			
			uint32 rawPixelType = rawImage.PixelType ();
			
			if (rawPixelType == ttShort)
				{
			
				// See if we are using a linearization table with <= 256 entries, in which
				// case the useful data will all fit within 8-bits.
				
				const dng_linearization_info *rangeInfo = GetLinearizationInfo ();
			
				if (rangeInfo)
					{

					if (rangeInfo->fLinearizationTable.Get ())
						{
						
						uint32 entries = rangeInfo->fLinearizationTable->LogicalSize () >> 1;
						
						if (entries <= 256)
							{
							
							rawPixelType = ttByte;
							
							}
														
						}
						
					}

				}
			
			// Find the fast digest on the raw image.
				
			dng_find_new_raw_image_digest_task task (rawImage, rawPixelType);
			
			host.PerformAreaTask (task, rawImage.Bounds ());
			
			fNewRawImageDigest = task.Result ();
				
			}
			
		// If there is a transparancy mask, we need to include that in the
		// digest also.
		
		if (RawTransparencyMask () != NULL)
			{
			
			// Find the fast digest on the raw mask.
			
			dng_fingerprint maskDigest;
			
				{
				
				dng_find_new_raw_image_digest_task task (*RawTransparencyMask (),
														 RawTransparencyMask ()->PixelType ());
				
				host.PerformAreaTask (task, RawTransparencyMask ()->Bounds ());
				
				maskDigest = task.Result ();
				
				}
				
			// Combine the two digests into a single digest.
			
			dng_md5_printer printer;
			
			printer.Process (fNewRawImageDigest.data, 16);
			
			printer.Process (maskDigest.data, 16);
			
			fNewRawImageDigest = printer.Result ();
			
			}
		
		}
	
	}
							   
/*****************************************************************************/

void dng_negative::ValidateRawImageDigest (dng_host &host)
	{
	
	if (Stage1Image () && !IsPreview () && (fRawImageDigest   .IsValid () ||
										    fNewRawImageDigest.IsValid ()))
		{
		
		bool isNewDigest = fNewRawImageDigest.IsValid ();
		
		dng_fingerprint &rawDigest = isNewDigest ? fNewRawImageDigest
												 : fRawImageDigest;
		
		// For lossy compressed JPEG images, we need to compare the stored
		// digest to the digest computed from the compressed data, since
		// decompressing lossy JPEG data is itself a lossy process.
		
		if (RawJPEGImageDigest ().IsValid () || RawJPEGImage ())
			{
			
			// Compute the raw JPEG image digest if we have not done so
			// already.
			
			FindRawJPEGImageDigest (host);
			
			if (rawDigest != RawJPEGImageDigest ())
				{
				
				#if qDNGValidate
				
				ReportError ("RawImageDigest does not match raw jpeg image");
				
				#else
				
				SetIsDamaged (true);
				
				#endif
				
				}
			
			}
			
		// Else we can compare the stored digest to the image in memory.
			
		else
			{
		
			dng_fingerprint oldDigest = rawDigest;
			
			try
				{
				
				rawDigest.Clear ();
				
				if (isNewDigest)
					{
					
					FindNewRawImageDigest (host);
					
					}
					
				else
					{
					
					FindRawImageDigest (host);
					
					}
				
				}
				
			catch (...)
				{
				
				rawDigest = oldDigest;
				
				throw;
				
				}
			
			if (oldDigest != rawDigest)
				{
				
				#if qDNGValidate
				
				if (isNewDigest)
					{
					ReportError ("NewRawImageDigest does not match raw image");
					}
				else
					{
					ReportError ("RawImageDigest does not match raw image");
					}
				
				SetIsDamaged (true);
				
				#else
				
				if (!isNewDigest)
					{
				
					// Note that Lightroom 1.4 Windows had a bug that corrupts the
					// first four bytes of the RawImageDigest tag.  So if the last
					// twelve bytes match, this is very likely the result of the
					// bug, and not an actual corrupt file.  So don't report this
					// to the user--just fix it.
					
						{
					
						bool matchLast12 = true;
						
						for (uint32 j = 4; j < 16; j++)
							{
							matchLast12 = matchLast12 && (oldDigest.data [j] == fRawImageDigest.data [j]);
							}
							
						if (matchLast12)
							{
							return;
							}
							
						}
						
					// Sometimes Lightroom 1.4 would corrupt more than the first four
					// bytes, but for all those files that I have seen so far the
					// resulting first four bytes are 0x08 0x00 0x00 0x00.
					
					if (oldDigest.data [0] == 0x08 &&
						oldDigest.data [1] == 0x00 &&
						oldDigest.data [2] == 0x00 &&
						oldDigest.data [3] == 0x00)
						{
						return;
						}
						
					}
					
				SetIsDamaged (true);
				
				#endif
				
				}
				
			}
			
		}
	
	}

/*****************************************************************************/

// If the raw data unique ID is missing, compute one based on a MD5 hash of
// the raw image hash and the model name, plus other commonly changed
// data that can affect rendering.

void dng_negative::FindRawDataUniqueID (dng_host &host) const
	{
	
	if (fRawDataUniqueID.IsNull ())
		{
		
		dng_md5_printer_stream printer;
		
		// If we have a raw jpeg image, it is much faster to
		// use its digest as part of the unique ID since
		// the data size is much smaller.  We cannot use it
		// if there a transparency mask, since that is not
		// included in the RawJPEGImageDigest.
		
		if (RawJPEGImage () && !RawTransparencyMask ())
			{
			
			FindRawJPEGImageDigest (host);
			
			printer.Put (fRawJPEGImageDigest.data, 16);
			
			}
		
		// Include the new raw image digest in the unique ID.
		
		else
			{
		
			FindNewRawImageDigest (host);
					
			printer.Put (fNewRawImageDigest.data, 16);
			
			}
		
		// Include model name.
					
		printer.Put (ModelName ().Get    (),
					 ModelName ().Length ());
					 
		// Include default crop area, since DNG Recover Edges can modify
		// these values and they affect rendering.
					 
		printer.Put_uint32 (fDefaultCropSizeH.n);
		printer.Put_uint32 (fDefaultCropSizeH.d);
		
		printer.Put_uint32 (fDefaultCropSizeV.n);
		printer.Put_uint32 (fDefaultCropSizeV.d);
		
		printer.Put_uint32 (fDefaultCropOriginH.n);
		printer.Put_uint32 (fDefaultCropOriginH.d);
		
		printer.Put_uint32 (fDefaultCropOriginV.n);
		printer.Put_uint32 (fDefaultCropOriginV.d);

		// Include default user crop.

		printer.Put_uint32 (fDefaultUserCropT.n);
		printer.Put_uint32 (fDefaultUserCropT.d);
		
		printer.Put_uint32 (fDefaultUserCropL.n);
		printer.Put_uint32 (fDefaultUserCropL.d);
		
		printer.Put_uint32 (fDefaultUserCropB.n);
		printer.Put_uint32 (fDefaultUserCropB.d);
		
		printer.Put_uint32 (fDefaultUserCropR.n);
		printer.Put_uint32 (fDefaultUserCropR.d);
		
		// Include opcode lists, since lens correction utilities can modify
		// these values and they affect rendering.
		
		fOpcodeList1.FingerprintToStream (printer);
		fOpcodeList2.FingerprintToStream (printer);
		fOpcodeList3.FingerprintToStream (printer);
		
		fRawDataUniqueID = printer.Result ();
	
		}
	
	}
		
/******************************************************************************/

// Forces recomputation of RawDataUniqueID, useful to call
// after modifying the opcode lists, etc.

void dng_negative::RecomputeRawDataUniqueID (dng_host &host)
	{
	
	fRawDataUniqueID.Clear ();
	
	FindRawDataUniqueID (host);
	
	}
		
/******************************************************************************/

void dng_negative::FindOriginalRawFileDigest () const
	{

	if (fOriginalRawFileDigest.IsNull () && fOriginalRawFileData.Get ())
		{
		
		dng_md5_printer printer;
		
		printer.Process (fOriginalRawFileData->Buffer      (),
						 fOriginalRawFileData->LogicalSize ());
					
		fOriginalRawFileDigest = printer.Result ();
	
		}

	}
		
/*****************************************************************************/

void dng_negative::ValidateOriginalRawFileDigest ()
	{
	
	if (fOriginalRawFileDigest.IsValid () && fOriginalRawFileData.Get ())
		{
		
		dng_fingerprint oldDigest = fOriginalRawFileDigest;
		
		try
			{
			
			fOriginalRawFileDigest.Clear ();
			
			FindOriginalRawFileDigest ();
			
			}
			
		catch (...)
			{
			
			fOriginalRawFileDigest = oldDigest;
			
			throw;
			
			}
		
		if (oldDigest != fOriginalRawFileDigest)
			{
			
			#if qDNGValidate
			
			ReportError ("OriginalRawFileDigest does not match OriginalRawFileData");
			
			#else
			
			SetIsDamaged (true);
			
			#endif
			
			// Don't "repair" the original image data digest.  Once it is
			// bad, it stays bad.  The user cannot tell by looking at the image
			// whether the damage is acceptable and can be ignored in the
			// future.
			
			fOriginalRawFileDigest = oldDigest;
			
			}
			
		}
		
	}
							   
/******************************************************************************/

dng_rect dng_negative::DefaultCropArea () const
	{
	
	// First compute the area using simple rounding.
		
	dng_rect result;
	
	result.l = Round_int32 (fDefaultCropOriginH.As_real64 () * fRawToFullScaleH);
	result.t = Round_int32 (fDefaultCropOriginV.As_real64 () * fRawToFullScaleV);
	
	result.r = result.l + Round_int32 (fDefaultCropSizeH.As_real64 () * fRawToFullScaleH);
	result.b = result.t + Round_int32 (fDefaultCropSizeV.As_real64 () * fRawToFullScaleV);
	
	// Sometimes the simple rounding causes the resulting default crop
	// area to slide off the scaled image area.  So we force this not
	// to happen.  We only do this if the image is not stubbed.
		
	const dng_image *image = Stage3Image ();
	
	if (image)
		{
	
		dng_point imageSize = image->Size ();
		
		if (result.r > imageSize.h)
			{
			result.l -= result.r - imageSize.h;
			result.r  = imageSize.h;
			}
			
		if (result.b > imageSize.v)
			{
			result.t -= result.b - imageSize.v;
			result.b  = imageSize.v;
			}
			
		}
		
	return result;
	
	}

/*****************************************************************************/

real64 dng_negative::TotalBaselineExposure (const dng_camera_profile_id &profileID) const
	{
	
	real64 total = BaselineExposure ();

	const dng_camera_profile *profile = ProfileByID (profileID);
	
	if (profile)
		{

		real64 offset = profile->BaselineExposureOffset ().As_real64 ();

		total += offset;
		
		}

	return total;
	
	}

/******************************************************************************/

void dng_negative::SetShadowScale (const dng_urational &scale)
	{
	
	if (scale.d > 0)
		{
		
		real64 s = scale.As_real64 ();
		
		if (s > 0.0 && s <= 1.0)
			{
	
			fShadowScale = scale;
			
			}
		
		}
	
	}
			
/******************************************************************************/

void dng_negative::SetActiveArea (const dng_rect &area)
	{
	
	NeedLinearizationInfo ();
	
	dng_linearization_info &info = *fLinearizationInfo.Get ();
								    
	info.fActiveArea = area;
	
	}

/******************************************************************************/

void dng_negative::SetMaskedAreas (uint32 count,
							 	   const dng_rect *area)
	{
	
	DNG_ASSERT (count <= kMaxMaskedAreas, "Too many masked areas");
	
	NeedLinearizationInfo ();
	
	dng_linearization_info &info = *fLinearizationInfo.Get ();
								    
	info.fMaskedAreaCount = Min_uint32 (count, kMaxMaskedAreas);
	
	for (uint32 index = 0; index < info.fMaskedAreaCount; index++)
		{
		
		info.fMaskedArea [index] = area [index];
		
		}
		
	}
		
/*****************************************************************************/

void dng_negative::SetLinearization (AutoPtr<dng_memory_block> &curve)
	{
	
	NeedLinearizationInfo ();
	
	dng_linearization_info &info = *fLinearizationInfo.Get ();
								    
	info.fLinearizationTable.Reset (curve.Release ());
	
	}
		
/*****************************************************************************/

void dng_negative::SetBlackLevel (real64 black,
								  int32 plane)
	{

	NeedLinearizationInfo ();
	
	dng_linearization_info &info = *fLinearizationInfo.Get ();
								    
	info.fBlackLevelRepeatRows = 1;
	info.fBlackLevelRepeatCols = 1;
	
	if (plane < 0)
		{
		
		for (uint32 j = 0; j < kMaxSamplesPerPixel; j++)
			{
			
			info.fBlackLevel [0] [0] [j] = black;
			
			}
		
		}
		
	else
		{
		
		info.fBlackLevel [0] [0] [plane] = black;
			
		}
	
	info.RoundBlacks ();
		
	}
		
/*****************************************************************************/

void dng_negative::SetQuadBlacks (real64 black0,
						    	  real64 black1,
						    	  real64 black2,
						    	  real64 black3,
								  int32 plane)
	{
	
	NeedLinearizationInfo ();
	
	dng_linearization_info &info = *fLinearizationInfo.Get ();
								    
	info.fBlackLevelRepeatRows = 2;
	info.fBlackLevelRepeatCols = 2;

	if (plane < 0)
		{
	
		for (uint32 j = 0; j < kMaxSamplesPerPixel; j++)
			{

			info.fBlackLevel [0] [0] [j] = black0;
			info.fBlackLevel [0] [1] [j] = black1;
			info.fBlackLevel [1] [0] [j] = black2;
			info.fBlackLevel [1] [1] [j] = black3;

			}

		}

	else
		{
		
		info.fBlackLevel [0] [0] [plane] = black0;
		info.fBlackLevel [0] [1] [plane] = black1;
		info.fBlackLevel [1] [0] [plane] = black2;
		info.fBlackLevel [1] [1] [plane] = black3;
		
		}
		
	info.RoundBlacks ();
		
	}

/*****************************************************************************/

void dng_negative::SetRowBlacks (const real64 *blacks,
				   		   		 uint32 count)
	{
	
	if (count)
		{
	
		NeedLinearizationInfo ();
		
		dng_linearization_info &info = *fLinearizationInfo.Get ();
		
		uint32 byteCount = 0;
		
		if (!SafeUint32Mult (count, (uint32) sizeof (real64), &byteCount))
			{
			
			ThrowMemoryFull("Arithmetic overflow computing byte count.");
			
			}
									    
		info.fBlackDeltaV.Reset (Allocator ().Allocate (byteCount));
		
		DoCopyBytes (blacks,
					 info.fBlackDeltaV->Buffer (),
					 byteCount);
		
		info.RoundBlacks ();
		
		}
		
	else if (fLinearizationInfo.Get ())
		{
		
		dng_linearization_info &info = *fLinearizationInfo.Get ();
		
		info.fBlackDeltaV.Reset ();
	
		}
								    
	}
							
/*****************************************************************************/

void dng_negative::SetColumnBlacks (const real64 *blacks,
					  		  	    uint32 count)
	{
	
	if (count)
		{
	
		NeedLinearizationInfo ();
		
		dng_linearization_info &info = *fLinearizationInfo.Get ();
		
		uint32 byteCount = 0;
		
		if (!SafeUint32Mult (count, (uint32) sizeof (real64), &byteCount))
			{
			
			ThrowMemoryFull("Arithmetic overflow computing byte count.");
			
			}
									    
		info.fBlackDeltaH.Reset (Allocator ().Allocate (byteCount));
		
		DoCopyBytes (blacks,
					 info.fBlackDeltaH->Buffer (),
					 byteCount);
		
		info.RoundBlacks ();
		
		}
		
	else if (fLinearizationInfo.Get ())
		{
		
		dng_linearization_info &info = *fLinearizationInfo.Get ();
									    
		info.fBlackDeltaH.Reset ();
	
		}
								    
	}
							
/*****************************************************************************/

uint32 dng_negative::WhiteLevel (uint32 plane) const
	{
	
	if (fLinearizationInfo.Get ())
		{
		
		const dng_linearization_info &info = *fLinearizationInfo.Get ();
									    
		return Round_uint32 (info.fWhiteLevel [plane]);
									    
		}
		
	if (RawImage ().PixelType () == ttFloat)
		{
		
		return 1;
		
		}
		
	return 0x0FFFF;
	
	}
							
/*****************************************************************************/

void dng_negative::SetWhiteLevel (uint32 white,
							      int32 plane)
	{

	NeedLinearizationInfo ();
	
	dng_linearization_info &info = *fLinearizationInfo.Get ();
								    
	if (plane < 0)
		{
		
		for (uint32 j = 0; j < kMaxSamplesPerPixel; j++)
			{
			
			info.fWhiteLevel [j] = (real64) white;
			
			}
		
		}
		
	else
		{
		
		info.fWhiteLevel [plane] = (real64) white;
			
		}
	
	}

/******************************************************************************/

void dng_negative::SetColorKeys (ColorKeyCode color0,
						   		 ColorKeyCode color1,
						   		 ColorKeyCode color2,
						   		 ColorKeyCode color3)
	{
	
	NeedMosaicInfo ();
	
	dng_mosaic_info &info = *fMosaicInfo.Get ();
							 
	info.fCFAPlaneColor [0] = color0;
	info.fCFAPlaneColor [1] = color1;
	info.fCFAPlaneColor [2] = color2;
	info.fCFAPlaneColor [3] = color3;
	
	}

/******************************************************************************/

void dng_negative::SetBayerMosaic (uint32 phase)
	{
	
	NeedMosaicInfo ();
	
	dng_mosaic_info &info = *fMosaicInfo.Get ();
	
	ColorKeyCode color0 = (ColorKeyCode) info.fCFAPlaneColor [0];
	ColorKeyCode color1 = (ColorKeyCode) info.fCFAPlaneColor [1];
	ColorKeyCode color2 = (ColorKeyCode) info.fCFAPlaneColor [2];
	
	info.fCFAPatternSize = dng_point (2, 2);
	
	switch (phase)
		{
		
		case 0:
			{
			info.fCFAPattern [0] [0] = color1;
			info.fCFAPattern [0] [1] = color0;
			info.fCFAPattern [1] [0] = color2;
			info.fCFAPattern [1] [1] = color1;
			break;
			}
			
		case 1:
			{
			info.fCFAPattern [0] [0] = color0;
			info.fCFAPattern [0] [1] = color1;
			info.fCFAPattern [1] [0] = color1;
			info.fCFAPattern [1] [1] = color2;
			break;
			}
			
		case 2:
			{
			info.fCFAPattern [0] [0] = color2;
			info.fCFAPattern [0] [1] = color1;
			info.fCFAPattern [1] [0] = color1;
			info.fCFAPattern [1] [1] = color0;
			break;
			}
			
		case 3:
			{
			info.fCFAPattern [0] [0] = color1;
			info.fCFAPattern [0] [1] = color2;
			info.fCFAPattern [1] [0] = color0;
			info.fCFAPattern [1] [1] = color1;
			break;
			}
			
		}
		
	info.fColorPlanes = 3;
	
	info.fCFALayout = 1;
	
	}

/******************************************************************************/

void dng_negative::SetFujiMosaic (uint32 phase)
	{
	
	NeedMosaicInfo ();
	
	dng_mosaic_info &info = *fMosaicInfo.Get ();
	
	ColorKeyCode color0 = (ColorKeyCode) info.fCFAPlaneColor [0];
	ColorKeyCode color1 = (ColorKeyCode) info.fCFAPlaneColor [1];
	ColorKeyCode color2 = (ColorKeyCode) info.fCFAPlaneColor [2];
	
	info.fCFAPatternSize = dng_point (2, 4);
	
	switch (phase)
		{
		
		case 0:
			{
			info.fCFAPattern [0] [0] = color0;
			info.fCFAPattern [0] [1] = color1;
			info.fCFAPattern [0] [2] = color2;
			info.fCFAPattern [0] [3] = color1;
			info.fCFAPattern [1] [0] = color2;
			info.fCFAPattern [1] [1] = color1;
			info.fCFAPattern [1] [2] = color0;
			info.fCFAPattern [1] [3] = color1;
			break;
			}
			
		case 1:
			{
			info.fCFAPattern [0] [0] = color2;
			info.fCFAPattern [0] [1] = color1;
			info.fCFAPattern [0] [2] = color0;
			info.fCFAPattern [0] [3] = color1;
			info.fCFAPattern [1] [0] = color0;
			info.fCFAPattern [1] [1] = color1;
			info.fCFAPattern [1] [2] = color2;
			info.fCFAPattern [1] [3] = color1;
			break;
			}
			
		}
		
	info.fColorPlanes = 3;
	
	info.fCFALayout = 2;
			
	}

/*****************************************************************************/

void dng_negative::SetFujiMosaic6x6 (uint32 phase)
	{
	
	NeedMosaicInfo ();
	
	dng_mosaic_info &info = *fMosaicInfo.Get ();
	
	ColorKeyCode color0 = (ColorKeyCode) info.fCFAPlaneColor [0];
	ColorKeyCode color1 = (ColorKeyCode) info.fCFAPlaneColor [1];
	ColorKeyCode color2 = (ColorKeyCode) info.fCFAPlaneColor [2];

	const uint32 patSize = 6;
	
	info.fCFAPatternSize = dng_point (patSize, patSize);

	info.fCFAPattern [0] [0] = color1;
	info.fCFAPattern [0] [1] = color2;
	info.fCFAPattern [0] [2] = color1;
	info.fCFAPattern [0] [3] = color1;
	info.fCFAPattern [0] [4] = color0;
	info.fCFAPattern [0] [5] = color1;

	info.fCFAPattern [1] [0] = color0;
	info.fCFAPattern [1] [1] = color1;
	info.fCFAPattern [1] [2] = color0;
	info.fCFAPattern [1] [3] = color2;
	info.fCFAPattern [1] [4] = color1;
	info.fCFAPattern [1] [5] = color2;

	info.fCFAPattern [2] [0] = color1;
	info.fCFAPattern [2] [1] = color2;
	info.fCFAPattern [2] [2] = color1;
	info.fCFAPattern [2] [3] = color1;
	info.fCFAPattern [2] [4] = color0;
	info.fCFAPattern [2] [5] = color1;

	info.fCFAPattern [3] [0] = color1;
	info.fCFAPattern [3] [1] = color0;
	info.fCFAPattern [3] [2] = color1;
	info.fCFAPattern [3] [3] = color1;
	info.fCFAPattern [3] [4] = color2;
	info.fCFAPattern [3] [5] = color1;

	info.fCFAPattern [4] [0] = color2;
	info.fCFAPattern [4] [1] = color1;
	info.fCFAPattern [4] [2] = color2;
	info.fCFAPattern [4] [3] = color0;
	info.fCFAPattern [4] [4] = color1;
	info.fCFAPattern [4] [5] = color0;

	info.fCFAPattern [5] [0] = color1;
	info.fCFAPattern [5] [1] = color0;
	info.fCFAPattern [5] [2] = color1;
	info.fCFAPattern [5] [3] = color1;
	info.fCFAPattern [5] [4] = color2;
	info.fCFAPattern [5] [5] = color1;

	DNG_REQUIRE (phase >= 0 && phase < patSize * patSize,
				 "Bad phase in SetFujiMosaic6x6.");

	if (phase > 0)
		{
		
		dng_mosaic_info temp = info;

		uint32 phaseRow = phase / patSize;

		uint32 phaseCol = phase - (phaseRow * patSize);

		for (uint32 dstRow = 0; dstRow < patSize; dstRow++)
			{
			
			uint32 srcRow = (dstRow + phaseRow) % patSize;
			
			for (uint32 dstCol = 0; dstCol < patSize; dstCol++)
				{

				uint32 srcCol = (dstCol + phaseCol) % patSize;
			
				temp.fCFAPattern [dstRow] [dstCol] = info.fCFAPattern [srcRow] [srcCol];

				}
			
			}

		info = temp;
		
		}
		
	info.fColorPlanes = 3;
	
	info.fCFALayout = 1;
			
	}

/******************************************************************************/

void dng_negative::SetQuadMosaic (uint32 pattern)
	{
	
	// The pattern of the four colors is assumed to be repeat at least every two
	// columns and eight rows.  The pattern is encoded as a 32-bit integer,
	// with every two bits encoding a color, in scan order for two columns and
	// eight rows (lsb is first).  The usual color coding is:
	//
	// 0 = Green
	// 1 = Magenta
	// 2 = Cyan
	// 3 = Yellow
	//
	// Examples:
	//
	//	PowerShot 600 uses 0xe1e4e1e4:
	//
	//	  0 1 2 3 4 5
	//	0 G M G M G M
	//	1 C Y C Y C Y
	//	2 M G M G M G
	//	3 C Y C Y C Y
	//
	//	PowerShot A5 uses 0x1e4e1e4e:
	//
	//	  0 1 2 3 4 5
	//	0 C Y C Y C Y
	//	1 G M G M G M
	//	2 C Y C Y C Y
	//	3 M G M G M G
	//
	//	PowerShot A50 uses 0x1b4e4b1e:
	//
	//	  0 1 2 3 4 5
	//	0 C Y C Y C Y
	//	1 M G M G M G
	//	2 Y C Y C Y C
	//	3 G M G M G M
	//	4 C Y C Y C Y
	//	5 G M G M G M
	//	6 Y C Y C Y C
	//	7 M G M G M G
	//
	//	PowerShot Pro70 uses 0x1e4b4e1b:
	//
	//	  0 1 2 3 4 5
	//	0 Y C Y C Y C
	//	1 M G M G M G
	//	2 C Y C Y C Y
	//	3 G M G M G M
	//	4 Y C Y C Y C
	//	5 G M G M G M
	//	6 C Y C Y C Y
	//	7 M G M G M G
	//
	//	PowerShots Pro90 and G1 use 0xb4b4b4b4:
	//
	//	  0 1 2 3 4 5
	//	0 G M G M G M
	//	1 Y C Y C Y C

	NeedMosaicInfo ();
	
	dng_mosaic_info &info = *fMosaicInfo.Get ();
							 
	if (((pattern >> 16) & 0x0FFFF) != (pattern & 0x0FFFF))
		{
		info.fCFAPatternSize = dng_point (8, 2);
		}
		
	else if (((pattern >> 8) & 0x0FF) != (pattern & 0x0FF))
		{
		info.fCFAPatternSize = dng_point (4, 2);
		}
		
	else
		{
		info.fCFAPatternSize = dng_point (2, 2);
		}
		
	for (int32 row = 0; row < info.fCFAPatternSize.v; row++)
		{
		
		for (int32 col = 0; col < info.fCFAPatternSize.h; col++)
			{
			
			uint32 index = (pattern >> ((((row << 1) & 14) + (col & 1)) << 1)) & 3;
			
			info.fCFAPattern [row] [col] = info.fCFAPlaneColor [index];
			
			}
			
		}

	info.fColorPlanes = 4;
	
	info.fCFALayout = 1;
			
	}
	
/******************************************************************************/

void dng_negative::SetGreenSplit (uint32 split)
	{
	
	NeedMosaicInfo ();
	
	dng_mosaic_info &info = *fMosaicInfo.Get ();
	
	info.fBayerGreenSplit = split;
	
	}

/*****************************************************************************/

void dng_negative::Parse (dng_host &host,
						  dng_stream &stream,
						  dng_info &info)
	{
	
	// Shared info.
	
	dng_shared &shared = *(info.fShared.Get ());
	
	// Find IFD holding the main raw information.
	
	dng_ifd &rawIFD = *info.fIFD [info.fMainIndex].Get ();
	
	// Model name.
	
	SetModelName (shared.fUniqueCameraModel.Get ());
	
	// Localized model name.
	
	SetLocalName (shared.fLocalizedCameraModel.Get ());
	
	// Base orientation.
	
		{
	
		uint32 orientation = info.fIFD [0]->fOrientation;
		
		if (orientation >= 1 && orientation <= 8)
			{
			
			SetBaseOrientation (dng_orientation::TIFFtoDNG (orientation));
						
			}
			
		}
		
	// Default crop rectangle.
	
	SetDefaultCropSize (rawIFD.fDefaultCropSizeH,
					    rawIFD.fDefaultCropSizeV);

	SetDefaultCropOrigin (rawIFD.fDefaultCropOriginH,
						  rawIFD.fDefaultCropOriginV);

	// Default user crop rectangle.

	SetDefaultUserCrop (rawIFD.fDefaultUserCropT,
						rawIFD.fDefaultUserCropL,
						rawIFD.fDefaultUserCropB,
						rawIFD.fDefaultUserCropR);
						        
	// Default scale.
		
	SetDefaultScale (rawIFD.fDefaultScaleH,
					 rawIFD.fDefaultScaleV);
	
	// Best quality scale.
	
	SetBestQualityScale (rawIFD.fBestQualityScale);
	
	// Baseline noise.

	SetBaselineNoise (shared.fBaselineNoise.As_real64 ());
	
	// NoiseReductionApplied.
	
	SetNoiseReductionApplied (shared.fNoiseReductionApplied);

	// NoiseProfile.

	SetNoiseProfile (shared.fNoiseProfile);
	
	// Baseline exposure.
	
	SetBaselineExposure (shared.fBaselineExposure.As_real64 ());

	// Baseline sharpness.
	
	SetBaselineSharpness (shared.fBaselineSharpness.As_real64 ());

	// Chroma blur radius.
	
	SetChromaBlurRadius (rawIFD.fChromaBlurRadius);

	// Anti-alias filter strength.
	
	SetAntiAliasStrength (rawIFD.fAntiAliasStrength);
		
	// Linear response limit.
	
	SetLinearResponseLimit (shared.fLinearResponseLimit.As_real64 ());
	
	// Shadow scale.
	
	SetShadowScale (shared.fShadowScale);
	
	// Colorimetric reference.
	
	SetColorimetricReference (shared.fColorimetricReference);
	
	// Color channels.
		
	SetColorChannels (shared.fCameraProfile.fColorPlanes);
	
	// Analog balance.
	
	if (shared.fAnalogBalance.NotEmpty ())
		{
		
		SetAnalogBalance (shared.fAnalogBalance);
		
		}

	// Camera calibration matrices

	if (shared.fCameraCalibration1.NotEmpty ())
		{
		
		SetCameraCalibration1 (shared.fCameraCalibration1);
		
		}
		
	if (shared.fCameraCalibration2.NotEmpty ())
		{
		
		SetCameraCalibration2 (shared.fCameraCalibration2);
		
		}
		
	if (shared.fCameraCalibration1.NotEmpty () ||
		shared.fCameraCalibration2.NotEmpty ())
		{
		
		SetCameraCalibrationSignature (shared.fCameraCalibrationSignature.Get ());
		
		}

	// Embedded camera profiles.
	
	if (shared.fCameraProfile.fColorPlanes > 1)
		{
	
		if (qDNGValidate || host.NeedsMeta () || host.NeedsImage ())
			{
			
			// Add profile from main IFD.
			
				{
			
				AutoPtr<dng_camera_profile> profile (new dng_camera_profile ());
				
				dng_camera_profile_info &profileInfo = shared.fCameraProfile;
				
				profile->Parse (stream, profileInfo);
				
				// The main embedded profile must be valid.
				
				if (!profile->IsValid (shared.fCameraProfile.fColorPlanes))
					{
					
					ThrowBadFormat ();
					
					}
				
				profile->SetWasReadFromDNG ();
				
				AddProfile (profile);
				
				}
				
			// Extra profiles.

			for (uint32 index = 0; index < (uint32) shared.fExtraCameraProfiles.size (); index++)
				{
				
				try
					{

					AutoPtr<dng_camera_profile> profile (new dng_camera_profile ());
					
					dng_camera_profile_info &profileInfo = shared.fExtraCameraProfiles [index];
					
					profile->Parse (stream, profileInfo);
					
					if (!profile->IsValid (shared.fCameraProfile.fColorPlanes))
						{
						
						ThrowBadFormat ();
						
						}
					
					profile->SetWasReadFromDNG ();
					
					AddProfile (profile);

					}
					
				catch (dng_exception &except)
					{
					
					// Don't ignore transient errors.
					
					if (host.IsTransientError (except.ErrorCode ()))
						{
						
						throw;
						
						}
				
					// Eat other parsing errors.
			
					#if qDNGValidate
					
					ReportWarning ("Unable to parse extra profile");
					
					#endif
					
					}
			
				}
			
			}
			
		// As shot profile name.
		
		if (shared.fAsShotProfileName.NotEmpty ())
			{
			
			SetAsShotProfileName (shared.fAsShotProfileName.Get ());
			
			}
			
		}
		
	// Raw image data digest.
	
	if (shared.fRawImageDigest.IsValid ())
		{
		
		SetRawImageDigest (shared.fRawImageDigest);
		
		}
			
	// New raw image data digest.
	
	if (shared.fNewRawImageDigest.IsValid ())
		{
		
		SetNewRawImageDigest (shared.fNewRawImageDigest);
		
		}
			
	// Raw data unique ID.
	
	if (shared.fRawDataUniqueID.IsValid ())
		{
		
		SetRawDataUniqueID (shared.fRawDataUniqueID);
		
		}
			
	// Original raw file name.
	
	if (shared.fOriginalRawFileName.NotEmpty ())
		{
		
		SetOriginalRawFileName (shared.fOriginalRawFileName.Get ());
		
		}
		
	// Original raw file data.
	
	if (shared.fOriginalRawFileDataCount)
		{
		
		SetHasOriginalRawFileData (true);
					
		if (host.KeepOriginalFile ())
			{
			
			uint32 count = shared.fOriginalRawFileDataCount;
			
			AutoPtr<dng_memory_block> block (host.Allocate (count));
			
			stream.SetReadPosition (shared.fOriginalRawFileDataOffset);
		
			stream.Get (block->Buffer (), count);
						
			SetOriginalRawFileData (block);
			
			SetOriginalRawFileDigest (shared.fOriginalRawFileDigest);
			
			ValidateOriginalRawFileDigest ();
			
			}
			
		}
			
	// DNG private data.
	
	if (shared.fDNGPrivateDataCount && (host.SaveDNGVersion () != dngVersion_None))
		{
		
		uint32 length = shared.fDNGPrivateDataCount;
		
		AutoPtr<dng_memory_block> block (host.Allocate (length));
		
		stream.SetReadPosition (shared.fDNGPrivateDataOffset);
			
		stream.Get (block->Buffer (), length);
							
		SetPrivateData (block);
			
		}
		
	// Hand off EXIF metadata to negative.
	
	ResetExif (info.fExif.Release ());
	
	// Parse linearization info.
	
	NeedLinearizationInfo ();
	
	fLinearizationInfo.Get ()->Parse (host,
								      stream,
								      info);
								      
	// Parse mosaic info.
	
	if (rawIFD.fPhotometricInterpretation == piCFA)
		{
	
		NeedMosaicInfo ();
		
		fMosaicInfo.Get ()->Parse (host,
							       stream,
							       info);
							  
		}
						  
	// Fill in original sizes.
	
	if (shared.fOriginalDefaultFinalSize.h > 0 &&
		shared.fOriginalDefaultFinalSize.v > 0)
		{
		
		SetOriginalDefaultFinalSize (shared.fOriginalDefaultFinalSize);
		
		SetOriginalBestQualityFinalSize (shared.fOriginalDefaultFinalSize);
		
		SetOriginalDefaultCropSize (dng_urational (shared.fOriginalDefaultFinalSize.h, 1),
									dng_urational (shared.fOriginalDefaultFinalSize.v, 1));
		
		}
		
	if (shared.fOriginalBestQualityFinalSize.h > 0 &&
		shared.fOriginalBestQualityFinalSize.v > 0)
		{
		
		SetOriginalBestQualityFinalSize (shared.fOriginalBestQualityFinalSize);
		
		}
		
	if (shared.fOriginalDefaultCropSizeH.As_real64 () >= 1.0 &&
		shared.fOriginalDefaultCropSizeV.As_real64 () >= 1.0)
		{
		
		SetOriginalDefaultCropSize (shared.fOriginalDefaultCropSizeH,
									shared.fOriginalDefaultCropSizeV);
		
		}
		
	}

/*****************************************************************************/

void dng_negative::SetDefaultOriginalSizes ()
	{
	
	// Fill in original sizes if we don't have them already.
	
	if (OriginalDefaultFinalSize () == dng_point ())
		{
		
		SetOriginalDefaultFinalSize (dng_point (DefaultFinalHeight (),
												DefaultFinalWidth  ()));
		
		}
		
	if (OriginalBestQualityFinalSize () == dng_point ())
		{
		
		SetOriginalBestQualityFinalSize (dng_point (BestQualityFinalHeight (),
													BestQualityFinalWidth  ()));
		
		}
		
	if (OriginalDefaultCropSizeH ().NotValid () ||
		OriginalDefaultCropSizeV ().NotValid ())
		{
		
		SetOriginalDefaultCropSize (DefaultCropSizeH (),
									DefaultCropSizeV ());
		
		}

	}

/*****************************************************************************/

void dng_negative::PostParse (dng_host &host,
						  	  dng_stream &stream,
						  	  dng_info &info)
	{
	
	// Shared info.
	
	dng_shared &shared = *(info.fShared.Get ());
	
	if (host.NeedsMeta ())
		{
		
		// Fill in original sizes if we don't have them already.
		
		SetDefaultOriginalSizes ();
				
		// MakerNote.
		
		if (shared.fMakerNoteCount)
			{
			
			// See if we know if the MakerNote is safe or not.
			
			SetMakerNoteSafety (shared.fMakerNoteSafety == 1);
			
			// If the MakerNote is safe, preserve it as a MakerNote.
			
			if (IsMakerNoteSafe ())
				{

				AutoPtr<dng_memory_block> block (host.Allocate (shared.fMakerNoteCount));
				
				stream.SetReadPosition (shared.fMakerNoteOffset);
					
				stream.Get (block->Buffer (), shared.fMakerNoteCount);
									
				SetMakerNote (block);
							
				}
			
			}
		
		// IPTC metadata.
		
		if (shared.fIPTC_NAA_Count)
			{
			
			AutoPtr<dng_memory_block> block (host.Allocate (shared.fIPTC_NAA_Count));
			
			stream.SetReadPosition (shared.fIPTC_NAA_Offset);
			
			uint64 iptcOffset = stream.PositionInOriginalFile();
			
			stream.Get (block->Buffer      (), 
						block->LogicalSize ());
			
			SetIPTC (block, iptcOffset);
							
			}
		
		// XMP metadata.
		
		#if qDNGUseXMP
		
		if (shared.fXMPCount)
			{
			
			AutoPtr<dng_memory_block> block (host.Allocate (shared.fXMPCount));
			
			stream.SetReadPosition (shared.fXMPOffset);
			
			stream.Get (block->Buffer      (),
						block->LogicalSize ());
						
			Metadata ().SetEmbeddedXMP (host,
									    block->Buffer      (),
									    block->LogicalSize ());
										
			#if qDNGValidate
			
			if (!Metadata ().HaveValidEmbeddedXMP ())
				{
				ReportError ("The embedded XMP is invalid");
				}
			
			#endif
			
			}
				
		#endif
		
		// Color info.
		
		if (!IsMonochrome ())
			{
			
			// If the ColorimetricReference is the ICC profile PCS,
			// then the data must be already be white balanced to the
			// ICC profile PCS white point.
			
			if (ColorimetricReference () == crICCProfilePCS)
				{
				
				ClearCameraNeutral ();
				
				SetCameraWhiteXY (PCStoXY ());
				
				}
				
			else
				{
				  		    
				// AsShotNeutral.
				
				if (shared.fAsShotNeutral.Count () == ColorChannels ())
					{
					
					SetCameraNeutral (shared.fAsShotNeutral);
										
					}
					
				// AsShotWhiteXY.
				
				if (shared.fAsShotWhiteXY.IsValid () && !HasCameraNeutral ())
					{
					
					SetCameraWhiteXY (shared.fAsShotWhiteXY);
					
					}
					
				}
				
			}
					
		}
		
	}
							
/*****************************************************************************/

bool dng_negative::SetFourColorBayer ()
	{
	
	if (ColorChannels () != 3)
		{
		return false;
		}
		
	if (!fMosaicInfo.Get ())
		{
		return false;
		}
		
	if (!fMosaicInfo.Get ()->SetFourColorBayer ())
		{
		return false;
		}
		
	SetColorChannels (4);
	
	if (fCameraNeutral.Count () == 3)
		{
		
		dng_vector n (4);
		
		n [0] = fCameraNeutral [0];
		n [1] = fCameraNeutral [1];
		n [2] = fCameraNeutral [2];
		n [3] = fCameraNeutral [1];
		
		fCameraNeutral = n;
		
		}

	fCameraCalibration1.Clear ();
	fCameraCalibration2.Clear ();
	
	fCameraCalibrationSignature.Clear ();
	
	for (uint32 index = 0; index < (uint32) fCameraProfile.size (); index++)
		{
		
		fCameraProfile [index]->SetFourColorBayer ();
		
		}
			
	return true;
	
	}
					
/*****************************************************************************/

const dng_image & dng_negative::RawImage () const
	{
	
	if (fRawImage.Get ())
		{
		return *fRawImage.Get ();
		}
		
	if (fStage1Image.Get ())
		{
		return *fStage1Image.Get ();
		}
		
	if (fUnflattenedStage3Image.Get ())
		{
		return *fUnflattenedStage3Image.Get ();
		}
		
	DNG_ASSERT (fStage3Image.Get (),
				"dng_negative::RawImage with no raw image");
		    
	return *fStage3Image.Get ();
	
	}

/*****************************************************************************/

const dng_jpeg_image * dng_negative::RawJPEGImage () const
	{

	return fRawJPEGImage.Get ();

	}

/*****************************************************************************/

void dng_negative::SetRawJPEGImage (AutoPtr<dng_jpeg_image> &jpegImage)
	{

	fRawJPEGImage.Reset (jpegImage.Release ());

	}

/*****************************************************************************/

void dng_negative::ClearRawJPEGImage ()
	{
	
	fRawJPEGImage.Reset ();

	}

/*****************************************************************************/

void dng_negative::FindRawJPEGImageDigest (dng_host &host) const
	{
	
	if (fRawJPEGImageDigest.IsNull ())
		{
		
		if (fRawJPEGImage.Get ())
			{
			
			#if qDNGValidate
			
			dng_timer timer ("FindRawJPEGImageDigest time");
			 
			#endif
			
			fRawJPEGImageDigest = fRawJPEGImage->FindDigest (host);
			
			}
			
		else
			{
			
			ThrowProgramError ("No raw JPEG image");
			
			}
		
		}
	
	}
		
/*****************************************************************************/

void dng_negative::ReadStage1Image (dng_host &host,
									dng_stream &stream,
									dng_info &info)
	{
	
	// Allocate image we are reading.
	
	dng_ifd &rawIFD = *info.fIFD [info.fMainIndex].Get ();
	
	fStage1Image.Reset (host.Make_dng_image (rawIFD.Bounds (),
											 rawIFD.fSamplesPerPixel,
											 rawIFD.PixelType ()));
					
	// See if we should grab the compressed JPEG data.
	
	AutoPtr<dng_jpeg_image> jpegImage;
	
	if (host.SaveDNGVersion () >= dngVersion_1_4_0_0 &&
		!host.PreferredSize () &&
		!host.ForPreview () &&
		rawIFD.fCompression == ccLossyJPEG)
		{
		
		jpegImage.Reset (new dng_jpeg_image);
		
		}
		
	// See if we need to compute the digest of the compressed JPEG data
	// while reading.
	
	bool needJPEGDigest = (RawImageDigest    ().IsValid () ||
						   NewRawImageDigest ().IsValid ()) &&
						  rawIFD.fCompression == ccLossyJPEG &&
						  jpegImage.Get () == NULL;
	
	dng_fingerprint jpegDigest;
	
	// Read the image.
	
	rawIFD.ReadImage (host,
					  stream,
					  *fStage1Image.Get (),
					  jpegImage.Get (),
					  needJPEGDigest ? &jpegDigest : NULL);
					  
	// Remember the raw floating point bit depth, if reading from
	// a floating point image.
	
	if (fStage1Image->PixelType () == ttFloat)
		{
		
		SetRawFloatBitDepth (rawIFD.fBitsPerSample [0]);
		
		}
					  
	// Remember the compressed JPEG data if we read it.
	
	if (jpegImage.Get ())
		{
				
		SetRawJPEGImage (jpegImage);
				
		}
		
	// Remember the compressed JPEG digest if we computed it.
	
	if (jpegDigest.IsValid ())
		{
		
		SetRawJPEGImageDigest (jpegDigest);
		
		}
					  
	// We are are reading the main image, we should read the opcode lists
	// also.
	
	if (rawIFD.fOpcodeList1Count)
		{
		
		#if qDNGValidate
		
		if (gVerbose)
			{
			printf ("\nParsing OpcodeList1: ");
			}
			
		#endif
		
		fOpcodeList1.Parse (host,
							stream,
							rawIFD.fOpcodeList1Count,
							rawIFD.fOpcodeList1Offset);
		
		}
		
	if (rawIFD.fOpcodeList2Count)
		{
		
		#if qDNGValidate
		
		if (gVerbose)
			{
			printf ("\nParsing OpcodeList2: ");
			}
			
		#endif
		
		fOpcodeList2.Parse (host,
							stream,
							rawIFD.fOpcodeList2Count,
							rawIFD.fOpcodeList2Offset);
		
		}

	if (rawIFD.fOpcodeList3Count)
		{
		
		#if qDNGValidate
		
		if (gVerbose)
			{
			printf ("\nParsing OpcodeList3: ");
			}
			
		#endif
		
		fOpcodeList3.Parse (host,
							stream,
							rawIFD.fOpcodeList3Count,
							rawIFD.fOpcodeList3Offset);
		
		}

	}
					
/*****************************************************************************/

void dng_negative::SetStage1Image (AutoPtr<dng_image> &image)
	{
	
	fStage1Image.Reset (image.Release ());
	
	}

/*****************************************************************************/

void dng_negative::SetStage2Image (AutoPtr<dng_image> &image)
	{
	
	fStage2Image.Reset (image.Release ());
	
	}

/*****************************************************************************/

void dng_negative::SetStage3Image (AutoPtr<dng_image> &image)
	{
	
	fStage3Image.Reset (image.Release ());
	
	}

/*****************************************************************************/

void dng_negative::DoBuildStage2 (dng_host &host)
	{
	
	dng_image &stage1 = *fStage1Image.Get ();
		
	dng_linearization_info &info = *fLinearizationInfo.Get ();
	
	uint32 pixelType = ttShort;
	
	if (stage1.PixelType () == ttLong ||
		stage1.PixelType () == ttFloat)
		{
		
		pixelType = ttFloat;
		
		}
	
	fStage2Image.Reset (host.Make_dng_image (info.fActiveArea.Size (),
											 stage1.Planes (),
											 pixelType));
								   
	info.Linearize (host,
					stage1,
					*fStage2Image.Get ());
							 
	}
		
/*****************************************************************************/

void dng_negative::DoPostOpcodeList2 (dng_host & /* host */)
	{
	
	// Nothing by default.
	
	}

/*****************************************************************************/

bool dng_negative::NeedDefloatStage2 (dng_host &host)
	{
	
	if (fStage2Image->PixelType () == ttFloat)
		{
		
		if (fRawImageStage >= rawImageStagePostOpcode2 &&
			host.SaveDNGVersion () != dngVersion_None  &&
			host.SaveDNGVersion () <  dngVersion_1_4_0_0)
			{
			
			return true;
			
			}
		
		}
	
	return false;
	
	}
		
/*****************************************************************************/

void dng_negative::DefloatStage2 (dng_host & /* host */)
	{
	
	ThrowNotYetImplemented ("dng_negative::DefloatStage2");
	
	}
		
/*****************************************************************************/

void dng_negative::BuildStage2Image (dng_host &host)
	{
	
	// If reading the negative to save in DNG format, figure out
	// when to grab a copy of the raw data.
	
	if (host.SaveDNGVersion () != dngVersion_None)
		{
		
		// Transparency masks are only supported in DNG version 1.4 and
		// later.  In this case, the flattening of the transparency mask happens
		// on the the stage3 image.  
		
		if (TransparencyMask () && host.SaveDNGVersion () < dngVersion_1_4_0_0)
			{
			fRawImageStage = rawImageStagePostOpcode3;
			}
		
		else if (fOpcodeList3.MinVersion (false) > host.SaveDNGVersion () ||
			     fOpcodeList3.AlwaysApply ())
			{
			fRawImageStage = rawImageStagePostOpcode3;
			}
			
		else if (host.SaveLinearDNG (*this))
			{
			
			// If the opcode list 3 has optional tags that are beyond the
			// the minimum version, and we are saving a linear DNG anyway,
			// then go ahead and apply them.
			
			if (fOpcodeList3.MinVersion (true) > host.SaveDNGVersion ())
				{
				fRawImageStage = rawImageStagePostOpcode3;
				}
				
			else
				{
				fRawImageStage = rawImageStagePreOpcode3;
				}
			
			}
			
		else if (fOpcodeList2.MinVersion (false) > host.SaveDNGVersion () ||
				 fOpcodeList2.AlwaysApply ())
			{
			fRawImageStage = rawImageStagePostOpcode2;
			}
			
		else if (fOpcodeList1.MinVersion (false) > host.SaveDNGVersion () ||
				 fOpcodeList1.AlwaysApply ())
			{
			fRawImageStage = rawImageStagePostOpcode1;
			}
			
		else
			{
			fRawImageStage = rawImageStagePreOpcode1;
			}
			
		// We should not save floating point stage1 images unless the target
		// DNG version is high enough to understand floating point images. 
		// We handle this by converting from floating point to integer if 
		// required after building stage2 image.
		
		if (fStage1Image->PixelType () == ttFloat)
			{
			
			if (fRawImageStage < rawImageStagePostOpcode2)
				{
				
				if (host.SaveDNGVersion () < dngVersion_1_4_0_0)
					{
					
					fRawImageStage = rawImageStagePostOpcode2;
					
					}
					
				}
				
			}
			
		}
		
	// Grab clone of raw image if required.
	
	if (fRawImageStage == rawImageStagePreOpcode1)
		{
		
		fRawImage.Reset (fStage1Image->Clone ());
		
		if (fTransparencyMask.Get ())
			{
			fRawTransparencyMask.Reset (fTransparencyMask->Clone ());
			}
		
		}

	else
		{
		
		// If we are not keeping the most raw image, we need
		// to recompute the raw image digest.
		
		ClearRawImageDigest ();
		
		// If we don't grab the unprocessed stage 1 image, then
		// the raw JPEG image is no longer valid.
		
		ClearRawJPEGImage ();
		
		// Nor is the digest of the raw JPEG data.
		
		ClearRawJPEGImageDigest ();
		
		// We also don't know the raw floating point bit depth.
		
		SetRawFloatBitDepth (0);
		
		}
		
	// Process opcode list 1.
	
	host.ApplyOpcodeList (fOpcodeList1, *this, fStage1Image);
	
	// See if we are done with the opcode list 1.
	
	if (fRawImageStage > rawImageStagePreOpcode1)
		{
		
		fOpcodeList1.Clear ();
		
		}
	
	// Grab clone of raw image if required.
	
	if (fRawImageStage == rawImageStagePostOpcode1)
		{
		
		fRawImage.Reset (fStage1Image->Clone ());
		
		if (fTransparencyMask.Get ())
			{
			fRawTransparencyMask.Reset (fTransparencyMask->Clone ());
			}
		
		}

	// Finalize linearization info.
	
		{
	
		NeedLinearizationInfo ();
	
		dng_linearization_info &info = *fLinearizationInfo.Get ();
		
		info.PostParse (host, *this);
		
		}
		
	// Perform the linearization.
	
	DoBuildStage2 (host);
		
	// Delete the stage1 image now that we have computed the stage 2 image.
	
	fStage1Image.Reset ();
	
	// Are we done with the linearization info.
	
	if (fRawImageStage > rawImageStagePostOpcode1)
		{
		
		ClearLinearizationInfo ();
		
		}
	
	// Process opcode list 2.
	
	host.ApplyOpcodeList (fOpcodeList2, *this, fStage2Image);
	
	// See if we are done with the opcode list 2.
	
	if (fRawImageStage > rawImageStagePostOpcode1)
		{
		
		fOpcodeList2.Clear ();
		
		}
		
	// Hook for any required processing just after opcode list 2.
	
	DoPostOpcodeList2 (host);
		
	// Convert from floating point to integer if required.
	
	if (NeedDefloatStage2 (host))
		{
		
		DefloatStage2 (host);
		
		}
		
	// Grab clone of raw image if required.
	
	if (fRawImageStage == rawImageStagePostOpcode2)
		{
		
		fRawImage.Reset (fStage2Image->Clone ());
		
		if (fTransparencyMask.Get ())
			{
			fRawTransparencyMask.Reset (fTransparencyMask->Clone ());
			}
		
		}
	
	}
									  
/*****************************************************************************/

void dng_negative::DoInterpolateStage3 (dng_host &host,
								        int32 srcPlane)
	{
	
	dng_image &stage2 = *fStage2Image.Get ();
		
	dng_mosaic_info &info = *fMosaicInfo.Get ();
	
	dng_point downScale = info.DownScale (host.MinimumSize   (),
										  host.PreferredSize (),
										  host.CropFactor    ());
	
	if (downScale != dng_point (1, 1))
		{
		SetIsPreview (true);
		}
	
	dng_point dstSize = info.DstSize (downScale);
			
	fStage3Image.Reset (host.Make_dng_image (dng_rect (dstSize),
											 info.fColorPlanes,
											 stage2.PixelType ()));

	if (srcPlane < 0 || srcPlane >= (int32) stage2.Planes ())
		{
		srcPlane = 0;
		}
				
	info.Interpolate (host,
					  *this,
					  stage2,
					  *fStage3Image.Get (),
					  downScale,
					  srcPlane);

	}
									   
/*****************************************************************************/

// Interpolate and merge a multi-channel CFA image.

void dng_negative::DoMergeStage3 (dng_host &host)
	{
	
	// The DNG SDK does not provide multi-channel CFA image merging code.
	// It just grabs the first channel and uses that.
	
	DoInterpolateStage3 (host, 0);
				   
	// Just grabbing the first channel would often result in the very
	// bright image using the baseline exposure value.
	
	fStage3Gain = pow (2.0, BaselineExposure ());
	
	}
									   
/*****************************************************************************/

void dng_negative::DoBuildStage3 (dng_host &host,
								  int32 srcPlane)
	{
	
	// If we don't have a mosaic pattern, then just move the stage 2
	// image on to stage 3.
	
	dng_mosaic_info *info = fMosaicInfo.Get ();

	if (!info || !info->IsColorFilterArray ())
		{
		
		fStage3Image.Reset (fStage2Image.Release ());
		
		}
		
	else
		{
		
		// Remember the size of the stage 2 image.
		
		dng_point stage2_size = fStage2Image->Size ();
		
		// Special case multi-channel CFA interpolation.
		
		if ((fStage2Image->Planes () > 1) && (srcPlane < 0))
			{
			
			DoMergeStage3 (host);
			
			}
			
		// Else do a single channel interpolation.
		
		else
			{
				
			DoInterpolateStage3 (host, srcPlane);
						   
			}
		
		// Calculate the ratio of the stage 3 image size to stage 2 image size.
		
		dng_point stage3_size = fStage3Image->Size ();
		
		fRawToFullScaleH = (real64) stage3_size.h / (real64) stage2_size.h;
		fRawToFullScaleV = (real64) stage3_size.v / (real64) stage2_size.v;
		
		}

	}
									   
/*****************************************************************************/

void dng_negative::BuildStage3Image (dng_host &host,
									 int32 srcPlane)
	{
	
	// Finalize the mosaic information.
	
	dng_mosaic_info *info = fMosaicInfo.Get ();
	
	if (info)
		{
		
		info->PostParse (host, *this);
		
		}
		
	// Do the interpolation as required.
	
	DoBuildStage3 (host, srcPlane);
	
	// Delete the stage2 image now that we have computed the stage 3 image.
	
	fStage2Image.Reset ();
	
	// Are we done with the mosaic info?
	
	if (fRawImageStage >= rawImageStagePreOpcode3)
		{
		
		ClearMosaicInfo ();
		
		// To support saving linear DNG files, to need to account for
		// and upscaling during interpolation.

		if (fRawToFullScaleH > 1.0)
			{
			
			uint32 adjust = Round_uint32 (fRawToFullScaleH);
			
			fDefaultCropSizeH  .n =
				SafeUint32Mult (fDefaultCropSizeH.n, adjust);
			fDefaultCropOriginH.n =
				SafeUint32Mult (fDefaultCropOriginH.n, adjust);
			fDefaultScaleH     .d = SafeUint32Mult (fDefaultScaleH.d, adjust);
			
			fRawToFullScaleH /= (real64) adjust;
			
			}
		
		if (fRawToFullScaleV > 1.0)
			{
			
			uint32 adjust = Round_uint32 (fRawToFullScaleV);
			
			fDefaultCropSizeV  .n =
				SafeUint32Mult (fDefaultCropSizeV.n, adjust);
			fDefaultCropOriginV.n =
				SafeUint32Mult (fDefaultCropOriginV.n, adjust);
			fDefaultScaleV     .d =
				SafeUint32Mult (fDefaultScaleV.d, adjust);
			
			fRawToFullScaleV /= (real64) adjust;
			
			}

		}
		
	// Resample the transparency mask if required.
	
	ResizeTransparencyToMatchStage3 (host);
			
	// Grab clone of raw image if required.
	
	if (fRawImageStage == rawImageStagePreOpcode3)
		{
		
		fRawImage.Reset (fStage3Image->Clone ());
		
		if (fTransparencyMask.Get ())
			{
			fRawTransparencyMask.Reset (fTransparencyMask->Clone ());
			}

		}
		
	// Process opcode list 3.
	
	host.ApplyOpcodeList (fOpcodeList3, *this, fStage3Image);
	
	// See if we are done with the opcode list 3.
	
	if (fRawImageStage > rawImageStagePreOpcode3)
		{
		
		fOpcodeList3.Clear ();
		
		}
		
	// Just in case the opcode list 3 changed the image size, resample the
	// transparency mask again if required.  This is nearly always going
	// to be a fast NOP operation.
	
	ResizeTransparencyToMatchStage3 (host);
 
	// Don't need to grab a copy of raw data at this stage since
	// it is kept around as the stage 3 image.
	
	}
		
/******************************************************************************/

class dng_gamma_encode_proxy : public dng_1d_function
	{
	
	private:
	
		real64 fBlack;
		real64 fWhite;
		
		bool fIsSceneReferred;
		
		real64 scale;
		real64 t1;
		
	public:
		
		dng_gamma_encode_proxy (real64 black,
							    real64 white,
							    bool isSceneReferred)
							   
			:	fBlack (black)
			,	fWhite (white)
			,	fIsSceneReferred (isSceneReferred)
			
			,	scale (1.0 / (fWhite - fBlack))
			,	t1 (1.0 / (27.0 * pow (5.0, 3.0 / 2.0)))
			
			{
			}
			
		virtual real64 Evaluate (real64 x) const
			{
			
			x = Pin_real64 (0.0, (x - fBlack) * scale, 1.0);
			
			real64 y;
			
			if (fIsSceneReferred)
				{
			
				real64 t = pow (sqrt (25920.0 * x * x + 1.0) * t1 + x * (8.0 / 15.0), 1.0 / 3.0);
				
				y = t - 1.0 / (45.0 * t);
				
				DNG_ASSERT (Abs_real64 (x - (y / 16.0 + y * y * y * 15.0 / 16.0)) < 0.0000001,
							"Round trip error");
							
				}
				
			else
				{
				
				y = (sqrt (960.0 * x + 1.0) - 1.0) / 30.0;
				
				DNG_ASSERT (Abs_real64 (x - (y / 16.0 + y * y * (15.0 / 16.0))) < 0.0000001,
							"Round trip error");
							
				}
				
			return y;
			
			}
	
	};

/*****************************************************************************/

class dng_encode_proxy_task: public dng_area_task
	{
	
	private:
	
		const dng_image &fSrcImage;
		
		dng_image &fDstImage;
		
		AutoPtr<dng_memory_block> fTable16 [kMaxColorPlanes];
			
	public:
	
		dng_encode_proxy_task (dng_host &host,
							   const dng_image &srcImage,
							   dng_image &dstImage,
							   const real64 *black,
							   const real64 *white,
							   bool isSceneReferred);
							 
		virtual dng_rect RepeatingTile1 () const
			{
			return fSrcImage.RepeatingTile ();
			}
			
		virtual dng_rect RepeatingTile2 () const
			{
			return fDstImage.RepeatingTile ();
			}
			
		virtual void Process (uint32 threadIndex,
							  const dng_rect &tile,
							  dng_abort_sniffer *sniffer);
								  
	private:
	
		// Hidden copy constructor and assignment operator.
	
		dng_encode_proxy_task (const dng_encode_proxy_task &task);
		
		dng_encode_proxy_task & operator= (const dng_encode_proxy_task &task);
	
	};

/*****************************************************************************/

dng_encode_proxy_task::dng_encode_proxy_task (dng_host &host,
											  const dng_image &srcImage,
										      dng_image &dstImage,
										      const real64 *black,
										      const real64 *white,
										      bool isSceneReferred)
										
	:	fSrcImage (srcImage)
	,	fDstImage (dstImage)
	
	{
	
	for (uint32 plane = 0; plane < fSrcImage.Planes (); plane++)
		{
		
		dng_gamma_encode_proxy gamma (black [plane],
									  white [plane],
									  isSceneReferred);
									  
		dng_1d_table table32;
		
		table32.Initialize (host.Allocator (), gamma);
		
		fTable16 [plane] . Reset (host.Allocate (0x10000 * sizeof (uint16)));
		
		table32.Expand16 (fTable16 [plane]->Buffer_uint16 ());
										 
		}
		
	}

/*****************************************************************************/

void dng_encode_proxy_task::Process (uint32 /* threadIndex */,
								     const dng_rect &tile,
							  	     dng_abort_sniffer * /* sniffer */)
	{
	
	dng_const_tile_buffer srcBuffer (fSrcImage, tile);
	dng_dirty_tile_buffer dstBuffer (fDstImage, tile);
	
	int32 sColStep = srcBuffer.fColStep;
	int32 dColStep = dstBuffer.fColStep;
	
	const uint16 *noise = dng_dither::Get ().NoiseBuffer16 ();
	
	for (uint32 plane = 0; plane < fSrcImage.Planes (); plane++)
		{
		
		const uint16 *map = fTable16 [plane]->Buffer_uint16 ();
		
		for (int32 row = tile.t; row < tile.b; row++)
			{
			
			const uint16 *sPtr = srcBuffer.ConstPixel_uint16 (row, tile.l, plane);
			
			uint8 *dPtr = dstBuffer.DirtyPixel_uint8 (row, tile.l, plane);
			
			const uint16 *rPtr = &noise [(row & dng_dither::kRNGMask) * dng_dither::kRNGSize];

			for (int32 col = tile.l; col < tile.r; col++)
				{
				
				uint32 x = *sPtr;
				
				uint32 r = rPtr [col & dng_dither::kRNGMask];
				
				x = map [x];
				
				x = (((x << 8) - x) + r) >> 16;
				
				*dPtr = (uint8) x;
				
				sPtr += sColStep;
				dPtr += dColStep;
				
				}
			
			}
			
		}
		
	}
								  
/******************************************************************************/

dng_image * dng_negative::EncodeRawProxy (dng_host &host,
										  const dng_image &srcImage,
										  dng_opcode_list &opcodeList) const
	{
	
	if (srcImage.PixelType () != ttShort)
		{
		return NULL;
		}
		
	real64 black [kMaxColorPlanes];
	real64 white [kMaxColorPlanes];
	
	bool isSceneReferred = (ColorimetricReference () == crSceneReferred);
	
		{
		
		const real64 kClipFraction = 0.00001;
	
		uint64 pixels = (uint64) srcImage.Bounds ().H () *
						(uint64) srcImage.Bounds ().W ();
						
		uint32 limit = Round_int32 ((real64) pixels * kClipFraction);
		
		AutoPtr<dng_memory_block> histData (host.Allocate (65536 * sizeof (uint32)));
		
		uint32 *hist = histData->Buffer_uint32 ();
			
		for (uint32 plane = 0; plane < srcImage.Planes (); plane++)
			{
			
			HistogramArea (host,
						   srcImage,
						   srcImage.Bounds (),
						   hist,
						   65535,
						   plane);
						   
			uint32 total = 0;

			uint32 upper = 65535;

			while (total + hist [upper] <= limit && upper > 255)
				{
				
				total += hist [upper];
				
				upper--;
				
				}
	
			total = 0;
			
			uint32 lower = 0;
			
			while (total + hist [lower] <= limit && lower < upper - 255)
				{
				
				total += hist [lower];
				
				lower++;
				
				}
			
			black [plane] = lower / 65535.0;
			white [plane] = upper / 65535.0;
		
			}
			
		}
		
	// Apply the gamma encoding, using dither when downsampling to 8-bit.
	
	AutoPtr<dng_image> dstImage (host.Make_dng_image (srcImage.Bounds (),
													  srcImage.Planes (),
													  ttByte));

		{
		
		dng_encode_proxy_task task (host,
							        srcImage,
									*dstImage,
									black,
									white,
									isSceneReferred);
		
		host.PerformAreaTask (task,
							  srcImage.Bounds ());
	
		}
				  
	// Add opcodes to undo the gamma encoding.
	
		{
	
		for (uint32 plane = 0; plane < srcImage.Planes (); plane++)
			{
			
			dng_area_spec areaSpec (srcImage.Bounds (),
									plane);
			
			real64 coefficient [4];
			
			coefficient [0] = 0.0;
			coefficient [1] = 1.0 / 16.0;
			
			if (isSceneReferred)
				{
				coefficient [2] = 0.0;
				coefficient [3] = 15.0 / 16.0;
				}
			else
				{
				coefficient [2] = 15.0 / 16.0;
				coefficient [3] = 0.0;
				}
			
			coefficient [0] *= white [plane] - black [plane];
			coefficient [1] *= white [plane] - black [plane];
			coefficient [2] *= white [plane] - black [plane];
			coefficient [3] *= white [plane] - black [plane];
			
			coefficient [0] += black [plane];
			
			AutoPtr<dng_opcode> opcode (new dng_opcode_MapPolynomial (areaSpec,
																	  isSceneReferred ? 3 : 2,
																	  coefficient));
																	  
			opcodeList.Append (opcode);
			
			}
			
		}
		
	return dstImage.Release ();
	
	}
									  
/******************************************************************************/

void dng_negative::AdjustProfileForStage3 ()
	{

	// For dng_sdk, the stage3 image's color space is always the same as the
	// raw image's color space.
	
	}
									  
/******************************************************************************/

void dng_negative::ConvertToProxy (dng_host &host,
								   dng_image_writer &writer,
								   uint32 proxySize,
								   uint64 proxyCount)
	{
	
	if (!proxySize)
		{
		proxySize = kMaxImageSide;
		}
	
	if (!proxyCount)
		{
		proxyCount = (uint64) proxySize * proxySize;
		}
	
	// Don't need to private data around in non-full size proxies.
	
	if (proxySize  < kMaxImageSide ||
		proxyCount < kMaxImageSide * kMaxImageSide)
		{
	
		ClearMakerNote ();
		
		ClearPrivateData ();
		
		}
	
	// See if we already have an acceptable proxy image.
	
	if (fRawImage.Get () &&
		fRawImage->PixelType () == ttByte &&
		fRawImage->Bounds () == DefaultCropArea () &&
		fRawImage->Bounds ().H () <= proxySize &&
		fRawImage->Bounds ().W () <= proxySize &&
		(uint64) fRawImage->Bounds ().H () *
		(uint64) fRawImage->Bounds ().W () <= proxyCount &&
		(!GetMosaicInfo () || !GetMosaicInfo ()->IsColorFilterArray ()) &&
		fRawJPEGImage.Get () &&
		(!RawTransparencyMask () || RawTransparencyMask ()->PixelType () == ttByte))
		{
		
		return;
		
		}
		
	if (fRawImage.Get () &&
		fRawImage->PixelType () == ttFloat &&
		fRawImage->Bounds ().H () <= proxySize &&
		fRawImage->Bounds ().W () <= proxySize &&
		(uint64) fRawImage->Bounds ().H () *
		(uint64) fRawImage->Bounds ().W () <= proxyCount &&
		RawFloatBitDepth () == 16 &&
		(!RawTransparencyMask () || RawTransparencyMask ()->PixelType () == ttByte))
		{
		
		return;
		
		}
	
	// Clear any grabbed raw image, since we are going to start
	// building the proxy with the stage3 image.

	fRawImage.Reset ();
	
	ClearRawJPEGImage ();
	
	SetRawFloatBitDepth (0);
	
	ClearLinearizationInfo ();
	
	ClearMosaicInfo ();
	
	fOpcodeList1.Clear ();
	fOpcodeList2.Clear ();
	fOpcodeList3.Clear ();
	
	// Adjust the profile to match the stage 3 image, if required.
	
	AdjustProfileForStage3 ();
	
	// Not saving the raw-most image, do the old raw digest is no
	// longer valid.
		
	ClearRawImageDigest ();
	
	ClearRawJPEGImageDigest ();
	
	// Trim off extra pixels outside the default crop area.
	
	dng_rect defaultCropArea = DefaultCropArea ();
	
	if (Stage3Image ()->Bounds () != defaultCropArea)
		{
		
		fStage3Image->Trim (defaultCropArea);
		
		if (fTransparencyMask.Get ())
			{
			fTransparencyMask->Trim (defaultCropArea);
			}
		
		fDefaultCropOriginH = dng_urational (0, 1);
		fDefaultCropOriginV = dng_urational (0, 1);
		
		}
		
	// Figure out the requested proxy pixel size.
	
	real64 aspectRatio = AspectRatio ();
	
	dng_point newSize (proxySize, proxySize);
	
	if (aspectRatio >= 1.0)
		{
		newSize.v = Max_int32 (1, Round_int32 (proxySize / aspectRatio));
		}
	else
		{
		newSize.h = Max_int32 (1, Round_int32 (proxySize * aspectRatio));
		}
		
	newSize.v = Min_int32 (newSize.v, DefaultFinalHeight ());
	newSize.h = Min_int32 (newSize.h, DefaultFinalWidth  ());
	
	if ((uint64) newSize.v *
	    (uint64) newSize.h > proxyCount)
		{

		if (aspectRatio >= 1.0)
			{
			
			newSize.h = (uint32) sqrt (proxyCount * aspectRatio);
			
			newSize.v = Max_int32 (1, Round_int32 (newSize.h / aspectRatio));
			
			}
			
		else
			{
			
			newSize.v = (uint32) sqrt (proxyCount / aspectRatio);
			
			newSize.h = Max_int32 (1, Round_int32 (newSize.v * aspectRatio));
												   
			}
															   
		}
		
	// If this is fewer pixels, downsample the stage 3 image to that size.
	
	dng_point oldSize = defaultCropArea.Size ();
	
	if ((uint64) newSize.v * (uint64) newSize.h <
		(uint64) oldSize.v * (uint64) oldSize.h)
		{
		
		const dng_image &srcImage (*Stage3Image ());
		
		AutoPtr<dng_image> dstImage (host.Make_dng_image (newSize,
														  srcImage.Planes (),
														  srcImage.PixelType ()));
														  
		host.ResampleImage (srcImage,
							*dstImage);
														 
		fStage3Image.Reset (dstImage.Release ());
		
		fDefaultCropSizeH = dng_urational (newSize.h, 1);
		fDefaultCropSizeV = dng_urational (newSize.v, 1);
		
		fDefaultScaleH = dng_urational (1, 1);
		fDefaultScaleV = dng_urational (1, 1);
		
		fBestQualityScale = dng_urational (1, 1);
		
		fRawToFullScaleH = 1.0;
		fRawToFullScaleV = 1.0;
		
		}
		
	// Convert 32-bit floating point images to 16-bit floating point to
	// save space.
	
	if (Stage3Image ()->PixelType () == ttFloat)
		{
		
		fRawImage.Reset (host.Make_dng_image (Stage3Image ()->Bounds (),
											  Stage3Image ()->Planes (),
											  ttFloat));
		
		LimitFloatBitDepth (host,
							*Stage3Image (),
							*fRawImage,
							16,
							32768.0f);
		
		SetRawFloatBitDepth (16);
		
		SetWhiteLevel (32768);
		
		}
		
	else
		{
		
		// Convert 16-bit deep images to 8-bit deep image for saving.
		
		fRawImage.Reset (EncodeRawProxy (host,
										 *Stage3Image (),
										 fOpcodeList2));
										 
		if (fRawImage.Get ())
			{
			
			SetWhiteLevel (255);
			
			// Compute JPEG compressed version.
			
			if (fRawImage->PixelType () == ttByte &&
				host.SaveDNGVersion () >= dngVersion_1_4_0_0)
				{
			
				AutoPtr<dng_jpeg_image> jpegImage (new dng_jpeg_image);
				
				jpegImage->Encode (host,
								   *this,
								   writer,
								   *fRawImage);
								   
				SetRawJPEGImage (jpegImage);
								   
				}
			
			}
			
		}
		
	// Deal with transparency mask.
	
	if (TransparencyMask ())
		{
		
		const bool convertTo8Bit = true;
		
		ResizeTransparencyToMatchStage3 (host, convertTo8Bit);
		
		fRawTransparencyMask.Reset (fTransparencyMask->Clone ());
		
		}
		
	// Recompute the raw data unique ID, since we changed the image data.
	
	RecomputeRawDataUniqueID (host);
			
	}

/*****************************************************************************/

dng_linearization_info * dng_negative::MakeLinearizationInfo ()
	{
	
	dng_linearization_info *info = new dng_linearization_info ();
	
	if (!info)
		{
		ThrowMemoryFull ();
		}
		
	return info;
	
	}

/*****************************************************************************/

void dng_negative::NeedLinearizationInfo ()
	{
	
	if (!fLinearizationInfo.Get ())
		{
	
		fLinearizationInfo.Reset (MakeLinearizationInfo ());
		
		}
	
	}

/*****************************************************************************/

dng_mosaic_info * dng_negative::MakeMosaicInfo ()
	{
	
	dng_mosaic_info *info = new dng_mosaic_info ();
	
	if (!info)
		{
		ThrowMemoryFull ();
		}
		
	return info;
	
	}

/*****************************************************************************/

void dng_negative::NeedMosaicInfo ()
	{
	
	if (!fMosaicInfo.Get ())
		{
	
		fMosaicInfo.Reset (MakeMosaicInfo ());
		
		}
	
	}

/*****************************************************************************/

void dng_negative::SetTransparencyMask (AutoPtr<dng_image> &image,
										uint32 bitDepth)
	{
	
	fTransparencyMask.Reset (image.Release ());
	
	fRawTransparencyMaskBitDepth = bitDepth;
	
	}

/*****************************************************************************/

const dng_image * dng_negative::TransparencyMask () const
	{
	
	return fTransparencyMask.Get ();
	
	}

/*****************************************************************************/

const dng_image * dng_negative::RawTransparencyMask () const
	{
	
	if (fRawTransparencyMask.Get ())
		{
		
		return fRawTransparencyMask.Get ();
		
		}
		
	return TransparencyMask ();
	
	}

/*****************************************************************************/

uint32 dng_negative::RawTransparencyMaskBitDepth () const
	{
	
	if (fRawTransparencyMaskBitDepth)
		{
	
		return fRawTransparencyMaskBitDepth;
		
		}
		
	const dng_image *mask = RawTransparencyMask ();
	
	if (mask)
		{
		
		switch (mask->PixelType ())
			{
			
			case ttByte:
				return 8;
				
			case ttShort:
				return 16;
				
			case ttFloat:
				return 32;
				
			default:
				ThrowProgramError ();
				
			}
		
		}
		
	return 0;
	
	}
									  
/*****************************************************************************/

void dng_negative::ReadTransparencyMask (dng_host &host,
									     dng_stream &stream,
									     dng_info &info)
	{
	
	if (info.fMaskIndex != -1)
		{
	
		// Allocate image we are reading.
		
		dng_ifd &maskIFD = *info.fIFD [info.fMaskIndex].Get ();
		
		fTransparencyMask.Reset (host.Make_dng_image (maskIFD.Bounds (),
													  1,
													  maskIFD.PixelType ()));
						
		// Read the image.
		
		maskIFD.ReadImage (host,
						   stream,
						   *fTransparencyMask.Get ());
						   
		// Remember the pixel depth.
		
		fRawTransparencyMaskBitDepth = maskIFD.fBitsPerSample [0];
						   
		}

	}

/*****************************************************************************/

void dng_negative::ResizeTransparencyToMatchStage3 (dng_host &host,
													bool convertTo8Bit)
	{
	
	if (TransparencyMask ())
		{
		
		if ((TransparencyMask ()->Bounds () != fStage3Image->Bounds ()) ||
			(TransparencyMask ()->PixelType () != ttByte && convertTo8Bit))
			{
			
			AutoPtr<dng_image> newMask (host.Make_dng_image (fStage3Image->Bounds (),
															 1,
															 convertTo8Bit ?
															 ttByte :
															 TransparencyMask ()->PixelType ()));
									
			host.ResampleImage (*TransparencyMask (),
								*newMask);
						   
			fTransparencyMask.Reset (newMask.Release ());
			
			if (!fRawTransparencyMask.Get ())
				{
				fRawTransparencyMaskBitDepth = 0;
				}
			
			}
			
		}
		
	}

/*****************************************************************************/

bool dng_negative::NeedFlattenTransparency (dng_host & /* host */)
	{
	
	if (TransparencyMask ())
		{
		
		return true;
	
		}
	
	return false;
		
	}
									  
/*****************************************************************************/

void dng_negative::FlattenTransparency (dng_host & /* host */)
	{
	
	ThrowNotYetImplemented ();
	
	}
									  
/*****************************************************************************/

const dng_image * dng_negative::UnflattenedStage3Image () const
	{
	
	if (fUnflattenedStage3Image.Get ())
		{
		
		return fUnflattenedStage3Image.Get ();
		
		}
		
	return fStage3Image.Get ();
		
	}

/*****************************************************************************/
