/*****************************************************************************/
// Copyright 2006-2011 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_linearization_info.cpp#1 $ */ 
/* $DateTime: 2012/05/30 13:28:51 $ */
/* $Change: 832332 $ */
/* $Author: tknoll $ */

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

#include "dng_linearization_info.h"

#include "dng_area_task.h"
#include "dng_exceptions.h"
#include "dng_host.h"
#include "dng_image.h"
#include "dng_info.h"
#include "dng_negative.h"
#include "dng_pixel_buffer.h"
#include "dng_safe_arithmetic.h"
#include "dng_tag_types.h"
#include "dng_tile_iterator.h"
#include "dng_utils.h"

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

class dng_linearize_plane
	{
	
	private:
	
		const dng_image & fSrcImage;
		      dng_image & fDstImage;
		      
		uint32 fPlane;
	
		dng_rect fActiveArea;
		      
		uint32 fSrcPixelType;
		uint32 fDstPixelType;
		
		bool fReal32;
		
		real32 fScale;
		
		AutoPtr<dng_memory_block> fScale_buffer;
		
		uint32 fBlack_2D_rows;
		uint32 fBlack_2D_cols;
		
		AutoPtr<dng_memory_block> fBlack_2D_buffer;
		
		uint32 fBlack_1D_rows;
		
		AutoPtr<dng_memory_block> fBlack_1D_buffer;
		
	public:
	
		dng_linearize_plane (dng_host &host,
							 dng_linearization_info &info,
							 const dng_image &srcImage,
							 dng_image &dstImage,
							 uint32 plane);
							 
		~dng_linearize_plane ();
		
		void Process (const dng_rect &tile);
								  
	};

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

dng_linearize_plane::dng_linearize_plane (dng_host &host,
										  dng_linearization_info &info,
										  const dng_image &srcImage,
										  dng_image &dstImage,
										  uint32 plane)
							 
	:	fSrcImage (srcImage)
	,	fDstImage (dstImage)
	,	fPlane (plane)
	,	fActiveArea (info.fActiveArea)
	,	fSrcPixelType (srcImage.PixelType ())
	,	fDstPixelType (dstImage.PixelType ())
	,	fReal32 (false)
	,	fScale (0.0f)
	,	fScale_buffer ()
	,	fBlack_2D_rows (0)
	,	fBlack_2D_cols (0)
	,	fBlack_2D_buffer ()
	,	fBlack_1D_rows (0)
	,	fBlack_1D_buffer ()
	
	{
	
	uint32 j;
	uint32 k;
	
	// Make sure the source pixel type is supported.
	
	if (fSrcPixelType != ttByte  &&
		fSrcPixelType != ttShort &&
		fSrcPixelType != ttLong  &&
		fSrcPixelType != ttFloat)
		{
		
		DNG_REPORT ("Unsupported source pixel type");
		
		ThrowProgramError ();
		
		}
		
	if (fDstPixelType != ttShort &&
		fDstPixelType != ttFloat)
		{
		
		DNG_REPORT ("Unsupported destination pixel type");
		
		ThrowProgramError ();
		
		}
	
	if (fSrcPixelType == ttFloat &&
		fDstPixelType != ttFloat)
		{
		
		DNG_REPORT ("Cannot convert floating point stage1 to non-floating stage2");
		
		ThrowProgramError ();
		
		}
	
	// Are we using floating point math?
	
	fReal32 = (fSrcPixelType == ttLong ||
			   fDstPixelType == ttFloat);
	
	// Find the scale for this plane.
	
	real64 maxBlack = info.MaxBlackLevel (plane);
	
	real64 minRange = info.fWhiteLevel [plane] - maxBlack;
	
	if (minRange <= 0.0)
		{
		ThrowBadFormat ();
		}
		
	real64 scale = 1.0 / minRange;
	
	fScale = (real32) scale;
		
	// Calculate two-dimensional black pattern, if any.
	
	if (info.fBlackDeltaH.Get ())
		{
		
		fBlack_2D_rows = info.fBlackLevelRepeatRows;
		fBlack_2D_cols = info.fActiveArea.W ();
		
		}
		
	else if (info.fBlackLevelRepeatCols > 1)
		{
		
		fBlack_2D_rows = info.fBlackLevelRepeatRows;
		fBlack_2D_cols = info.fBlackLevelRepeatCols;
		
		}
		
	if (fBlack_2D_rows)
		{
		
		fBlack_2D_buffer.Reset (host.Allocate (
			SafeUint32Mult (fBlack_2D_rows, fBlack_2D_cols, 4)));
		
		for (j = 0; j < fBlack_2D_rows; j++)
			{
			
			for (k = 0;  k < fBlack_2D_cols; k++)
				{
				
				real64 x = info.fBlackLevel [j]
											[k % info.fBlackLevelRepeatCols]
											[plane];
				
				if (info.fBlackDeltaH.Get ())
					{
					
					x += info.fBlackDeltaH->Buffer_real64 () [k];
					
					}
					
				x *= scale;
					
				uint32 index = j * fBlack_2D_cols + k;
				
				if (fReal32)
					{
					
					fBlack_2D_buffer->Buffer_real32 () [index] = (real32) x;
					
					}
					
				else
					{
					
					x *= 0x0FFFF * 256.0;
					
					int32 y = Round_int32 (x);
					
					fBlack_2D_buffer->Buffer_int32 () [index] = y;
					
					}
				
				}
				
			}
				
		}
		
	// Calculate one-dimensional (per row) black pattern, if any.
	
	if (info.fBlackDeltaV.Get ())
		{
		
		fBlack_1D_rows = info.fActiveArea.H ();
		
		}
		
	else if (fBlack_2D_rows == 0 &&
			 (info.fBlackLevelRepeatRows > 1 || fSrcPixelType != ttShort))
		{
		
		fBlack_1D_rows = info.fBlackLevelRepeatRows;
		
		}
		
	if (fBlack_1D_rows)
		{
		
		fBlack_1D_buffer.Reset (host.Allocate (
			SafeUint32Mult(fBlack_1D_rows, 4)));
		
		bool allZero = true;
		
		for (j = 0; j < fBlack_1D_rows; j++)
			{
			
			real64 x = 0.0;
			
			if (fBlack_2D_rows == 0)
				{
				
				x = info.fBlackLevel [j % info.fBlackLevelRepeatRows] 
									 [0] 
									 [plane];
				
				}
			
			if (info.fBlackDeltaV.Get ())
				{
				
				x += info.fBlackDeltaV->Buffer_real64 () [j];
				
				}
				
			allZero = allZero && (x == 0.0);
				
			x *= scale;
			
			if (fReal32)
				{
				
				fBlack_1D_buffer->Buffer_real32 () [j] = (real32) x;
				
				}
				
			else
				{
				
				x *= 0x0FFFF * 256.0;
				
				int32 y = Round_int32 (x);
				
				fBlack_1D_buffer->Buffer_int32 () [j] = y;
				
				}
			
			}
			
		if (allZero)
			{
			
			fBlack_1D_rows = 0;
			
			fBlack_1D_buffer.Reset ();
			
			}
			
		}
		
	// Calculate scale table, if any.
	
	if (fSrcPixelType != ttLong &&
		fSrcPixelType != ttFloat)
		{
		
		// Find linearization table, if any.
			
		uint16 *lut = NULL;
		
		uint32 lutEntries = 0;
		
		if (info.fLinearizationTable.Get ())
			{
			
			lut = info.fLinearizationTable->Buffer_uint16 ();
			
			lutEntries = info.fLinearizationTable->LogicalSize () >> 1;
			
			}
			
		// If the black level does not vary from pixel to pixel, then
		// the entire process can be a single LUT.
		
		if (fBlack_1D_rows == 0 &&
		    fBlack_2D_rows == 0)
			{
		
			fScale_buffer.Reset (host.Allocate (0x10000 *
											    TagTypeSize (fDstPixelType)));
											    
			for (j = 0; j < 0x10000; j++)
				{
				
				uint32 x = j;
				
				// Apply linearization table, if any.
				
				if (lut)
					{
					
					x = Min_uint32 (x, lutEntries - 1);
					
					x = lut [x];
					
					}
					
				// Subtract constant black level.
				
				real64 y = x - info.fBlackLevel [0] [0] [plane];
				
				// Apply scale.
				
				y *= scale;
				
				// We can burn in the clipping also.
				
				y = Pin_real64 (0.0, y, 1.0);
				
				// Store output value in table.
				
				if (fDstPixelType == ttShort)
					{
					
					uint16 z = (uint16) Round_uint32 (y * 0x0FFFF);
					
					fScale_buffer->Buffer_uint16 () [j] = z;
					
					}
					
				else
					{
					
					fScale_buffer->Buffer_real32 () [j] = (real32) y;
					
					}
				
				}
				
			}
		
		// Else we only do the scaling operation in the scale table.
		
		else
			{
		
			fScale_buffer.Reset (host.Allocate (0x10000 * 4));
											    
			for (j = 0; j < 0x10000; j++)
				{
				
				uint32 x = j;
				
				// Apply linearization table, if any.
				
				if (lut)
					{
					
					x = Min_uint32 (x, lutEntries - 1);
					
					x = lut [x];
					
					}
					
				// Apply scale.
				
				real64 y = x * scale;
					
				// Store output value in table.
				
				if (fReal32)
					{
					
					fScale_buffer->Buffer_real32 () [j] = (real32) y;
					
					}
					
				else
					{
					
					int32 z = Round_int32 (y * 0x0FFFF * 256.0);
					
					fScale_buffer->Buffer_int32 () [j] = z;
					
					}
				
				}
				
			}
		
		}
		
	}
							 
/*****************************************************************************/

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

void dng_linearize_plane::Process (const dng_rect &srcTile)
	{

	// Process tile.
	
	dng_rect dstTile = srcTile - fActiveArea.TL ();
		
	dng_const_tile_buffer srcBuffer (fSrcImage, srcTile);
	dng_dirty_tile_buffer dstBuffer (fDstImage, dstTile);
	
	int32 sStep = srcBuffer.fColStep;
	int32 dStep = dstBuffer.fColStep;
	
	uint32 count = srcTile.W ();
	
	uint32 dstCol = dstTile.l;

	uint32 rows = srcTile.H ();

	for (uint32 row = 0; row < rows; row++)
		{

		uint32 dstRow = dstTile.t + row;
	
		const void *sPtr = srcBuffer.ConstPixel (srcTile.t + row,
											     srcTile.l,
											     fPlane);
	
		void *dPtr = dstBuffer.DirtyPixel (dstRow,
										   dstCol,
										   fPlane);
										   
		// Floating point source case.
		
		if (fSrcPixelType == ttFloat)
			{
			
			real32 scale = fScale;
			
			const real32 *srcPtr = (const real32 *) sPtr;
			
			real32 *dstPtr = (real32 *) dPtr;
			
			// Optimize scale only case, which is the most common.
			
			if (fBlack_1D_rows == 0 &&
				fBlack_2D_cols == 0)
				{
			
				for (uint32 j = 0; j < count; j++)
					{
					
					*dstPtr = (*srcPtr) * scale;
					
					srcPtr += sStep;
					dstPtr += dStep;
					
					}
					
				}
				
			else
				{
			
				real32 b1 = 0.0f;
				
				if (fBlack_1D_rows)
					{
					b1 = fBlack_1D_buffer->Buffer_real32 () [dstRow % fBlack_1D_rows];
					}
					
				const real32 *b2 = NULL;
				
				uint32 b2_count = fBlack_2D_cols;
				uint32 b2_phase = 0;
				
				if (b2_count)
					{
					
					b2 = fBlack_2D_buffer->Buffer_real32 () +
						 b2_count * (dstRow % fBlack_2D_rows);
							 
					b2_phase = dstCol % b2_count;
					
					}
					
				for (uint32 j = 0; j < count; j++)
					{
					
					real32 x = (*srcPtr) * scale - b1;
					
					if (b2_count)
						{
					
						x -= b2 [b2_phase];
						
						if (++b2_phase == b2_count)
							{
							b2_phase = 0;
							}
							
						}
					
					*dstPtr = x;
					
					srcPtr += sStep;
					dstPtr += dStep;
					
					}
					
				}

			}
										   
		// Simple LUT case.
		
		else if (fBlack_1D_rows == 0 &&
				 fBlack_2D_rows == 0 && fSrcPixelType != ttLong)
			{
			
			if (fDstPixelType == ttShort)
				{
				
				const uint16 *lut = fScale_buffer->Buffer_uint16 ();
				
				uint16 *dstPtr = (uint16 *) dPtr;
				
				if (fSrcPixelType == ttByte)
					{
					
					const uint8 *srcPtr = (const uint8 *) sPtr;
			
					for (uint32 j = 0; j < count; j++)
						{
						
						*dstPtr = lut [*srcPtr];
						
						srcPtr += sStep;
						dstPtr += dStep;
						
						}
						
					}
					
				else
					{

					const uint16 *srcPtr = (const uint16 *) sPtr;
			
					for (uint32 j = 0; j < count; j++)
						{
						
						*dstPtr = lut [*srcPtr];
						
						srcPtr += sStep;
						dstPtr += dStep;
						
						}
						
					}
					
				}
				
			else
				{
				
				const real32 *lut = fScale_buffer->Buffer_real32 ();
				
				real32 *dstPtr = (real32 *) dPtr;

				if (fSrcPixelType == ttByte)
					{
					
					const uint8 *srcPtr = (const uint8 *) sPtr;
			
					for (uint32 j = 0; j < count; j++)
						{
						
						*dstPtr = lut [*srcPtr];
						
						srcPtr += sStep;
						dstPtr += dStep;
						
						}
						
					}
					
				else
					{
					
					const uint16 *srcPtr = (const uint16 *) sPtr;
			
					for (uint32 j = 0; j < count; j++)
						{
						
						*dstPtr = lut [*srcPtr];
						
						srcPtr += sStep;
						dstPtr += dStep;
						
						}
						
					}
				
				}
			
			}
			
		// Integer math case.
		
		else if (!fReal32)
			{
			
			const int32 *lut = fScale_buffer->Buffer_int32 ();
			
			int32 b1 = 0;
			
			if (fBlack_1D_rows)
				{
				b1 = fBlack_1D_buffer->Buffer_int32 () [dstRow % fBlack_1D_rows];
				}
				
			const int32 *b2 = NULL;
			
			uint32 b2_count = fBlack_2D_cols;
			uint32 b2_phase = 0;
			
			if (b2_count)
				{
				
				b2 = fBlack_2D_buffer->Buffer_int32 () +
					 b2_count * (dstRow % fBlack_2D_rows);
						 
				b2_phase = dstCol % b2_count;
				
				}
				
			uint16 *dstPtr = (uint16 *) dPtr;

			b1 -= 128;		// Rounding for 8 bit shift
			
			if (fSrcPixelType == ttByte)
				{
			
				const uint8 *srcPtr = (const uint8 *) sPtr;
				
				for (uint32 j = 0; j < count; j++)
					{
					
					int32 x = lut [*srcPtr] - b1;
					
					if (b2_count)
						{
					
						x -= b2 [b2_phase];
						
						if (++b2_phase == b2_count)
							{
							b2_phase = 0;
							}
							
						}
						
					x >>= 8;
						
					*dstPtr = Pin_uint16 (x);
					
					srcPtr += sStep;
					dstPtr += dStep;
					
					}
					
				}
				
			else
				{
			
				const uint16 *srcPtr = (const uint16 *) sPtr;
				
				for (uint32 j = 0; j < count; j++)
					{
					
					int32 x = lut [*srcPtr] - b1;
					
					if (b2_count)
						{
					
						x -= b2 [b2_phase];
						
						if (++b2_phase == b2_count)
							{
							b2_phase = 0;
							}
							
						}
						
					x >>= 8;
						
					*dstPtr = Pin_uint16 (x);
					
					srcPtr += sStep;
					dstPtr += dStep;
					
					}
					
				}
					
			}
			
		// Floating point math cases.
		
		else
			{
					
			real32 b1 = 0.0f;
			
			if (fBlack_1D_rows)
				{
				b1 = fBlack_1D_buffer->Buffer_real32 () [dstRow % fBlack_1D_rows];
				}
				
			const real32 *b2 = NULL;
			
			uint32 b2_count = fBlack_2D_cols;
			uint32 b2_phase = 0;
			
			if (b2_count)
				{
				
				b2 = fBlack_2D_buffer->Buffer_real32 () +
					 b2_count * (dstRow % fBlack_2D_rows);
						 
				b2_phase = dstCol % b2_count;
				
				}
				
			// Case 1: uint8/uint16 -> real32
				
			if (fSrcPixelType != ttLong)
				{
				
				const real32 *lut = fScale_buffer->Buffer_real32 ();
				
				real32 *dstPtr = (real32 *) dPtr;
				
				if (fSrcPixelType == ttByte)
					{
				
					const uint8 *srcPtr = (const uint8 *) sPtr;
				
					for (uint32 j = 0; j < count; j++)
						{
						
						real32 x = lut [*srcPtr] - b1;
						
						if (b2_count)
							{
						
							x -= b2 [b2_phase];
							
							if (++b2_phase == b2_count)
								{
								b2_phase = 0;
								}
								
							}
						
						x = Pin_real32 (0.0f, x, 1.0f);
						
						*dstPtr = x;
						
						srcPtr += sStep;
						dstPtr += dStep;
						
						}
						
					}
					
				else
					{
				
					const uint16 *srcPtr = (const uint16 *) sPtr;
				
					for (uint32 j = 0; j < count; j++)
						{
						
						real32 x = lut [*srcPtr] - b1;
						
						if (b2_count)
							{
						
							x -= b2 [b2_phase];
							
							if (++b2_phase == b2_count)
								{
								b2_phase = 0;
								}
								
							}
						
						x = Pin_real32 (0.0f, x, 1.0f);
						
						*dstPtr = x;
						
						srcPtr += sStep;
						dstPtr += dStep;
						
						}
						
					}
					
				}
				
			// Otherwise source is uint32
			
			else
				{
				
				real32 scale = fScale;
				
				const uint32 *srcPtr = (const uint32 *) sPtr;
				
				// Case 2: uint32 -> real32
				
				if (fDstPixelType == ttFloat)
					{
					
					real32 *dstPtr = (real32 *) dPtr;
					
					for (uint32 j = 0; j < count; j++)
						{
						
						real32 x = ((real32) *srcPtr) * scale - b1;
						
						if (b2_count)
							{
						
							x -= b2 [b2_phase];
							
							if (++b2_phase == b2_count)
								{
								b2_phase = 0;
								}
								
							}
						
						x = Pin_real32 (0.0f, x, 1.0f);
						
						*dstPtr = x;
						
						srcPtr += sStep;
						dstPtr += dStep;
						
						}
				
					}
					
				// Case 3: uint32 -> uint16
				
				else
					{
					
					uint16 *dstPtr = (uint16 *) dPtr;
					
					real32 dstScale = (real32) 0x0FFFF;
					
					for (uint32 j = 0; j < count; j++)
						{
						
						real32 x = ((real32) *srcPtr) * scale - b1;
						
						if (b2_count)
							{
						
							x -= b2 [b2_phase];
							
							if (++b2_phase == b2_count)
								{
								b2_phase = 0;
								}
								
							}
						
						x = Pin_real32 (0.0f, x, 1.0f);
						
						*dstPtr = (uint16) (x * dstScale + 0.5f);
						
						srcPtr += sStep;
						dstPtr += dStep;
						
						}
				
					}
				
				}
		
			}
		
		}
	
	}
	
/*****************************************************************************/

class dng_linearize_image: public dng_area_task
	{
	
	private:
	
		const dng_image & fSrcImage;
		      dng_image & fDstImage;
			  
		dng_rect fActiveArea;
		      
		AutoPtr<dng_linearize_plane> fPlaneTask [kMaxColorPlanes];
		
	public:
	
		dng_linearize_image (dng_host &host,
							 dng_linearization_info &info,
							 const dng_image &srcImage,
							 dng_image &dstImage);
							 
		virtual ~dng_linearize_image ();
		
		virtual dng_rect RepeatingTile1 () const;
							 
		virtual dng_rect RepeatingTile2 () const;
		
		virtual void Process (uint32 threadIndex,
							  const dng_rect &tile,
							  dng_abort_sniffer *sniffer);
								  
	};

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

dng_linearize_image::dng_linearize_image (dng_host &host,
										  dng_linearization_info &info,
										  const dng_image &srcImage,
										  dng_image &dstImage)
							 
	:	fSrcImage   (srcImage)
	,	fDstImage   (dstImage)
	,	fActiveArea (info.fActiveArea)
	
	{
	
	// Build linearization table for each plane.
	
	for (uint32 plane = 0; plane < srcImage.Planes (); plane++)
		{
		
		fPlaneTask [plane].Reset (new dng_linearize_plane (host,
														   info,
														   srcImage,
														   dstImage,
														   plane));
														   
		}

	// Adjust maximum tile size.
		
	fMaxTileSize = dng_point (1024, 1024);
		
	}
							 
/*****************************************************************************/

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

dng_rect dng_linearize_image::RepeatingTile1 () const
	{
	
	return fSrcImage.RepeatingTile ();
	
	}
							 
/*****************************************************************************/

dng_rect dng_linearize_image::RepeatingTile2 () const
	{
	
	return fDstImage.RepeatingTile () + fActiveArea.TL ();
	
	}
							 
/*****************************************************************************/

void dng_linearize_image::Process (uint32 /* threadIndex */,
							  	   const dng_rect &srcTile,
							  	   dng_abort_sniffer * /* sniffer */)
	{

	// Process each plane.
	
	for (uint32 plane = 0; plane < fSrcImage.Planes (); plane++)
		{
		
		fPlaneTask [plane]->Process (srcTile);
														   
		}
		
	}
	
/*****************************************************************************/

dng_linearization_info::dng_linearization_info ()

	:	fActiveArea ()
	,	fMaskedAreaCount (0)
	,	fLinearizationTable ()
	,	fBlackLevelRepeatRows (1)
	,	fBlackLevelRepeatCols (1)
	,	fBlackDeltaH ()
	,	fBlackDeltaV ()
	,	fBlackDenom (256)
	
	{
	
	uint32 j;
	uint32 k;
	uint32 n;
	
	for (j = 0; j < kMaxBlackPattern; j++)
		for (k = 0; k < kMaxBlackPattern; k++)
			for (n = 0; n < kMaxSamplesPerPixel; n++)
				{
				fBlackLevel [j] [k] [n] = 0.0;
				}
				
	for (n = 0; n < kMaxSamplesPerPixel; n++)
		{
		fWhiteLevel [n] = 65535.0;
		}
			
	}
	
/*****************************************************************************/

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

void dng_linearization_info::RoundBlacks ()
	{
	
	uint32 j;
	uint32 k;
	uint32 n;
	
	real64 maxAbs = 0.0;
	
	for (j = 0; j < fBlackLevelRepeatRows; j++)
		for (k = 0; k < fBlackLevelRepeatCols; k++)
			for (n = 0; n < kMaxSamplesPerPixel; n++)
				{
				
				maxAbs = Max_real64 (maxAbs,
									 Abs_real64 (fBlackLevel [j] [k] [n]));
				
				}
				
	uint32 count = RowBlackCount ();
				
	for (j = 0; j < count; j++)
		{
		
		maxAbs = Max_real64 (maxAbs,
							 Abs_real64 (fBlackDeltaV->Buffer_real64 () [j]));
				
		}
		
	count = ColumnBlackCount ();
				
	for (j = 0; j < count; j++)
		{
		
		maxAbs = Max_real64 (maxAbs,
							 Abs_real64 (fBlackDeltaH->Buffer_real64 () [j]));
				
		
		}
		
	fBlackDenom = 256;
	
	while (fBlackDenom > 1 && (maxAbs * fBlackDenom) >= 30000.0 * 65536.0)
		{
		fBlackDenom >>= 1;
		}
	
	for (j = 0; j < fBlackLevelRepeatRows; j++)
		for (k = 0; k < fBlackLevelRepeatCols; k++)
			for (n = 0; n < kMaxSamplesPerPixel; n++)
				{
				
				fBlackLevel [j] [k] [n] = BlackLevel (j, k, n).As_real64 ();
				
				}
				
	count = RowBlackCount ();
				
	for (j = 0; j < count; j++)
		{
		
		fBlackDeltaV->Buffer_real64 () [j] = RowBlack (j).As_real64 ();
		
		}
		
	count = ColumnBlackCount ();
				
	for (j = 0; j < count; j++)
		{
		
		fBlackDeltaH->Buffer_real64 () [j] = ColumnBlack (j).As_real64 ();
		
		}
	
	}
		
/*****************************************************************************/

void dng_linearization_info::Parse (dng_host &host,
								    dng_stream &stream,
								    dng_info &info)
	{
	
	uint32 j;
	uint32 k;
	uint32 n;
	
	// Find main image IFD.
	
	dng_ifd &rawIFD = *info.fIFD [info.fMainIndex].Get ();
	
	// Copy active area.
	
	fActiveArea = rawIFD.fActiveArea;
	
	// Copy masked areas.
	
	fMaskedAreaCount = rawIFD.fMaskedAreaCount;
	
	for (j = 0; j < fMaskedAreaCount; j++)
		{
		fMaskedArea [j] = rawIFD.fMaskedArea [j];
		}
		
	// Read linearization LUT.
	
	if (rawIFD.fLinearizationTableCount)
		{
		
		uint32 size = SafeUint32Mult (rawIFD.fLinearizationTableCount,
									  static_cast<uint32> (sizeof (uint16)));
		
		fLinearizationTable.Reset (host.Allocate (size));
												      
		uint16 *table = fLinearizationTable->Buffer_uint16 ();
		
		stream.SetReadPosition (rawIFD.fLinearizationTableOffset);
		
		for (j = 0; j < rawIFD.fLinearizationTableCount; j++)
			{
			table [j] = stream.Get_uint16 ();
			}
					
		}
		
	// Copy black level pattern.
	
	fBlackLevelRepeatRows = rawIFD.fBlackLevelRepeatRows;
	fBlackLevelRepeatCols = rawIFD.fBlackLevelRepeatCols;
	
	for (j = 0; j < kMaxBlackPattern; j++)
		for (k = 0; k < kMaxBlackPattern; k++)
			for (n = 0; n < kMaxSamplesPerPixel; n++)
				{
				fBlackLevel [j] [k] [n] = rawIFD.fBlackLevel [j] [k] [n];
				}
	
	// Read BlackDeltaH.
							   
	if (rawIFD.fBlackLevelDeltaHCount)
		{
		
		uint32 size = SafeUint32Mult (rawIFD.fBlackLevelDeltaHCount,
									  static_cast<uint32> (sizeof (real64)));
		
		fBlackDeltaH.Reset (host.Allocate (size));
		
		real64 *blacks = fBlackDeltaH->Buffer_real64 ();
		
		stream.SetReadPosition (rawIFD.fBlackLevelDeltaHOffset);
		
		for (j = 0; j < rawIFD.fBlackLevelDeltaHCount; j++)
			{
			blacks [j] = stream.TagValue_real64 (rawIFD.fBlackLevelDeltaHType);
			}
			
		}
		
	// Read BlackDeltaV.
							   
	if (rawIFD.fBlackLevelDeltaVCount)
		{
		
		uint32 size = SafeUint32Mult (rawIFD.fBlackLevelDeltaVCount,
									  static_cast<uint32> (sizeof (real64)));
		
		fBlackDeltaV.Reset (host.Allocate (size));
		
		real64 *blacks = fBlackDeltaV->Buffer_real64 ();
		
		stream.SetReadPosition (rawIFD.fBlackLevelDeltaVOffset);
		
		for (j = 0; j < rawIFD.fBlackLevelDeltaVCount; j++)
			{
			blacks [j] = stream.TagValue_real64 (rawIFD.fBlackLevelDeltaVType);
			}
			
		}
		
	// Copy white level.
		
	for (n = 0; n < kMaxSamplesPerPixel; n++)
		{
		fWhiteLevel [n] = rawIFD.fWhiteLevel [n];
		}
		
	// Round off black levels.
		
	RoundBlacks ();

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

void dng_linearization_info::PostParse (dng_host & /* host */,
										dng_negative &negative)
	{
	
	if (fActiveArea.IsEmpty ())
		{
		
		fActiveArea = negative.Stage1Image ()->Bounds ();
		
		}
	
	}

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

real64 dng_linearization_info::MaxBlackLevel (uint32 plane) const
	{
	
	uint32 j;
	uint32 k;
	
	// Find maximum value of fBlackDeltaH for each phase of black pattern.
	
	real64 maxDeltaH [kMaxBlackPattern];
	
	for (j = 0; j < fBlackLevelRepeatCols; j++)
		{
		maxDeltaH [j] = 0.0;
		}
		
	if (fBlackDeltaH.Get ())
		{
		
		real64 *table = fBlackDeltaH->Buffer_real64 ();
		
		uint32 entries = fBlackDeltaH->LogicalSize () / (uint32) sizeof (table [0]);
		
		for (j = 0; j < entries; j++)
			{
			
			real64 &entry = maxDeltaH [j % fBlackLevelRepeatCols];
			
			if (j < fBlackLevelRepeatCols)
				{
				entry = table [j];
				}
			else
				{
				entry = Max_real64 (entry, table [j]);
				}
			
			}
		
		}
		
	// Find maximum value of fBlackDeltaV for each phase of black pattern.
		
	real64 maxDeltaV [kMaxBlackPattern];
	
	for (j = 0; j < fBlackLevelRepeatRows; j++)
		{
		maxDeltaV [j] = 0.0;
		}
		
	if (fBlackDeltaV.Get ())
		{
		
		real64 *table = fBlackDeltaV->Buffer_real64 ();
		
		uint32 entries = fBlackDeltaV->LogicalSize () / (uint32) sizeof (table [0]);
		
		for (j = 0; j < entries; j++)
			{
			
			real64 &entry = maxDeltaV [j % fBlackLevelRepeatRows];
			
			if (j < fBlackLevelRepeatRows)
				{
				entry = table [j];
				}
			else
				{
				entry = Max_real64 (entry, table [j]);
				}
			
			}
		
		}
		
	// Now scan the pattern and find the maximum value after row and column
	// deltas.
		
	real64 maxBlack = 0.0;
	
	for (j = 0; j < fBlackLevelRepeatRows; j++)
		{
		
		for (k = 0; k < fBlackLevelRepeatCols; k++)
			{
			
			real64 black = fBlackLevel [j] [k] [plane];
			
			black += maxDeltaH [k];
			black += maxDeltaV [j];
			 			   
			if (j == 0 && k == 0)
				{
				maxBlack = black;
				}
			else
				{
				maxBlack = Max_real64 (maxBlack, black);
				}
			
			}
			
		}
		
	return maxBlack;
		
	}
				
/*****************************************************************************/

void dng_linearization_info::Linearize (dng_host &host,
										const dng_image &srcImage,
										dng_image &dstImage)
	{
	
	dng_linearize_image processor (host,
								   *this,
								   srcImage,
								   dstImage);
								   
	host.PerformAreaTask (processor,
						  fActiveArea);
						
	}
				
/*****************************************************************************/

dng_urational dng_linearization_info::BlackLevel (uint32 row,
												  uint32 col,
												  uint32 plane) const
	{
	
	dng_urational r;
	
	r.Set_real64 (fBlackLevel [row] [col] [plane], fBlackDenom);
	
	return r;
	
	}
				
/*****************************************************************************/

uint32 dng_linearization_info::RowBlackCount () const
	{
	
	if (fBlackDeltaV.Get ())
		{
		
		return fBlackDeltaV->LogicalSize () >> 3;
		
		}
		
	return 0;
		
	}
				
/*****************************************************************************/

dng_srational dng_linearization_info::RowBlack (uint32 row) const
	{
	
	if (fBlackDeltaV.Get ())
		{
		
		dng_srational r;
		
		r.Set_real64 (fBlackDeltaV->Buffer_real64 () [row], fBlackDenom);
		
		return r;
		
		}
		
	return dng_srational (0, 1);
	
	}
		
/*****************************************************************************/

uint32 dng_linearization_info::ColumnBlackCount () const
	{
	
	if (fBlackDeltaH.Get ())
		{
		
		return fBlackDeltaH->LogicalSize () >> 3;
		
		}
		
	return 0;
		
	}
				
/*****************************************************************************/

dng_srational dng_linearization_info::ColumnBlack (uint32 col) const
	{
	
	if (fBlackDeltaH.Get ())
		{
		
		dng_srational r;
		
		r.Set_real64 (fBlackDeltaH->Buffer_real64 () [col], fBlackDenom);
		
		return r;
		
		}
		
	return dng_srational (0, 1);
	
	}
		
/*****************************************************************************/
