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

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

#include "dng_image.h"

#include "dng_assertions.h"
#include "dng_exceptions.h"
#include "dng_orientation.h"
#include "dng_pixel_buffer.h"
#include "dng_tag_types.h"
#include "dng_tile_iterator.h"
#include "dng_utils.h"
						 
/*****************************************************************************/

dng_tile_buffer::dng_tile_buffer (const dng_image &image,
						 		  const dng_rect &tile,
						 		  bool dirty)
						 		  
	:	fImage   (image)
	,	fRefData (NULL)
	
	{
	
	fImage.AcquireTileBuffer (*this,
							  tile,
							  dirty);
	
	}

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

dng_tile_buffer::~dng_tile_buffer ()
	{
	
	fImage.ReleaseTileBuffer (*this);
	
	}

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

dng_const_tile_buffer::dng_const_tile_buffer (const dng_image &image,
						 		  			  const dng_rect &tile)
						 		  			  
	: 	dng_tile_buffer (image, tile, false)
	
	{
	
	}

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

dng_const_tile_buffer::~dng_const_tile_buffer ()
	{
	
	}

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

dng_dirty_tile_buffer::dng_dirty_tile_buffer (dng_image &image,
						 		  			  const dng_rect &tile)
						 		  			  
	: 	dng_tile_buffer (image, tile, true)
	
	{
	
	}

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

dng_dirty_tile_buffer::~dng_dirty_tile_buffer ()
	{
	
	}

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

dng_image::dng_image (const dng_rect &bounds,
				      uint32 planes,
				      uint32 pixelType)

	: 	fBounds    (bounds)
	,	fPlanes    (planes)
	,	fPixelType (pixelType)
	
	{
	
	if (bounds.IsEmpty () || planes == 0 || PixelSize () == 0)
		{
		
		#if qDNGValidate
		
		ReportError ("Fuzz: Attempt to create zero size image");
		
		#endif
		
		ThrowBadFormat ();
		
		}
		
	}

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

dng_image::~dng_image ()
	{
	
	}

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

dng_image * dng_image::Clone () const
	{
	
	ThrowProgramError ("Clone is not supported by this dng_image subclass");

	return NULL;
	
	}

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

void dng_image::SetPixelType (uint32 pixelType)
	{
	
	if (TagTypeSize (pixelType) != PixelSize ())
		{
		
		ThrowProgramError ("Cannot change pixel size for existing image");
		
		}
	
	fPixelType = pixelType;
	
	}
		
/*****************************************************************************/

uint32 dng_image::PixelSize () const
	{
	
	return TagTypeSize (PixelType ());
	
	}

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

uint32 dng_image::PixelRange () const
	{
	
	switch (fPixelType)
		{
		
		case ttByte:
		case ttSByte:
			{
			return 0x0FF;
			}
			
		case ttShort:
		case ttSShort:
			{
			return 0x0FFFF;
			}
			
		case ttLong:
		case ttSLong:
			{
			return 0xFFFFFFFF;
			}
			
		default:
			break;
			
		}
	
	return 0;
	
	}

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

dng_rect dng_image::RepeatingTile () const
	{
	
	return fBounds;
	
	}

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

void dng_image::AcquireTileBuffer (dng_tile_buffer & /* buffer */,
								   const dng_rect & /* area */,
								   bool /* dirty */) const
	{
	
	ThrowProgramError ();
	
	}

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

void dng_image::ReleaseTileBuffer (dng_tile_buffer & /* buffer */) const
	{
	
	}

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

void dng_image::DoGet (dng_pixel_buffer &buffer) const
	{
	
	dng_rect tile;
	
	dng_tile_iterator iter (*this, buffer.fArea);
	
	while (iter.GetOneTile (tile))
		{
		
		dng_const_tile_buffer tileBuffer (*this, tile);
		
		buffer.CopyArea (tileBuffer,
				  		 tile,
				  		 buffer.fPlane,
				  		 buffer.fPlanes);
		
		}
	
	}

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

void dng_image::DoPut (const dng_pixel_buffer &buffer)
	{
	
	dng_rect tile;
	
	dng_tile_iterator iter (*this, buffer.fArea);
	
	while (iter.GetOneTile (tile))
		{
		
		dng_dirty_tile_buffer tileBuffer (*this, tile);
		
		tileBuffer.CopyArea (buffer,
				  		     tile,
				  		     buffer.fPlane,
				  		     buffer.fPlanes);
		
		}
	
	}
	
/*****************************************************************************/

void dng_image::GetRepeat (dng_pixel_buffer &buffer,
				           const dng_rect &srcArea,
				           const dng_rect &dstArea) const
	{
	
	// If we already have the entire srcArea in the
	// buffer, we can just repeat that.
	
	if ((srcArea & buffer.fArea) == srcArea)
		{
		
		buffer.RepeatArea (srcArea,
						   dstArea);
		
		}
		
	// Else we first need to get the srcArea into the buffer area.
	
	else
		{
		
		// Find repeating pattern size.
		
		dng_point repeat = srcArea.Size ();
		
		// Find pattern phase at top-left corner of destination area.
		
		dng_point phase = dng_pixel_buffer::RepeatPhase (srcArea,
													     dstArea);
			
		// Find new source area at top-left of dstArea.
		
		dng_rect newArea = srcArea + (dstArea.TL () -
								      srcArea.TL ());
										 
		// Find quadrant split coordinates.
		
		int32 splitV = newArea.t + repeat.v - phase.v;
		int32 splitH = newArea.l + repeat.h - phase.h;
			
		// Top-left quadrant.
		
		dng_rect dst1 (dng_rect (newArea.t,
					   			 newArea.l,
					   			 splitV,
					   			 splitH) & dstArea);
					    
		if (dst1.NotEmpty ())
			{
			
			dng_pixel_buffer temp (buffer);
			
			temp.fArea = dst1 + (srcArea.TL () -
								 dstArea.TL () +
								 dng_point (phase.v, phase.h));
			
			temp.fData = buffer.DirtyPixel (dst1.t,
									        dst1.l,
									        buffer.fPlane);
									        
			DoGet (temp);
			
			}
			
		// Top-right quadrant.
		
		dng_rect dst2 (dng_rect (newArea.t,
								 splitH,
								 splitV,
								 newArea.r) & dstArea);
								 
		if (dst2.NotEmpty ())
			{
			
			dng_pixel_buffer temp (buffer);
			
			temp.fArea = dst2 + (srcArea.TL () -
								 dstArea.TL () +
								 dng_point (phase.v, -phase.h));
			
			temp.fData = buffer.DirtyPixel (dst2.t,
									        dst2.l,
									        buffer.fPlane);
									        
			DoGet (temp);
			
			}
			
		// Bottom-left quadrant.
		
		dng_rect dst3 (dng_rect (splitV,
								 newArea.l,
								 newArea.b,
								 splitH) & dstArea);
								 
		if (dst3.NotEmpty ())
			{
			
			dng_pixel_buffer temp (buffer);
			
			temp.fArea = dst3 + (srcArea.TL () -
								 dstArea.TL () +
								 dng_point (-phase.v, phase.h));
			
			temp.fData = buffer.DirtyPixel (dst3.t,
									        dst3.l,
									        buffer.fPlane);
									        
			DoGet (temp);
			
			}
			
		// Bottom-right quadrant.
		
		dng_rect dst4 (dng_rect (splitV,
								 splitH,
								 newArea.b,
								 newArea.r) & dstArea);
								 
		if (dst4.NotEmpty ())
			{
			
			dng_pixel_buffer temp (buffer);
			
			temp.fArea = dst4 + (srcArea.TL () -
								 dstArea.TL () +
								 dng_point (-phase.v, -phase.h));
			
			temp.fData = buffer.DirtyPixel (dst4.t,
									        dst4.l,
									        buffer.fPlane);
									        
			DoGet (temp);
			
			} 
					   
		// Replicate this new source area.
		
		buffer.RepeatArea (newArea,
						   dstArea);
		
		}
			
	}
	
/*****************************************************************************/

void dng_image::GetEdge (dng_pixel_buffer &buffer,
					     edge_option edgeOption,
				         const dng_rect &srcArea,
				         const dng_rect &dstArea) const
	{
	
	switch (edgeOption)
		{
		
		case edge_zero:
			{
			
			buffer.SetZero (dstArea,
							buffer.fPlane,
							buffer.fPlanes);
							
			break;
			
			}
			
		case edge_repeat:
			{
			
			GetRepeat (buffer,
					   srcArea,
					   dstArea);
					   
			break;
						
			}
			
		case edge_repeat_zero_last:
			{
			
			if (buffer.fPlanes > 1)
				{
			
				dng_pixel_buffer buffer1 (buffer);
				
				buffer1.fPlanes--;
				
				GetEdge (buffer1,
						 edge_repeat,
						 srcArea,
						 dstArea);
						 
				}
				
			dng_pixel_buffer buffer2 (buffer);
			
			buffer2.fPlane  = buffer.fPlanes - 1;
			buffer2.fPlanes = 1;
			
			buffer2.fData = buffer.DirtyPixel (buffer2.fArea.t,
										  	   buffer2.fArea.l,
										  	   buffer2.fPlane);
										  
			GetEdge (buffer2,
					 edge_zero,
					 srcArea,
					 dstArea);
					 
			break;
			
			}
			
		default:
			{
			
			ThrowProgramError ();
			
			}
			
		}
	
	}
		
/*****************************************************************************/

void dng_image::Get (dng_pixel_buffer &buffer,
					 edge_option edgeOption,
				     uint32 repeatV,
				     uint32 repeatH) const
	{
	
	// Find the overlap with the image bounds.
	
	dng_rect overlap = buffer.fArea & fBounds;
	
	// Move the overlapping pixels.
	
	if (overlap.NotEmpty ())
		{
	
		dng_pixel_buffer temp (buffer);
		
		temp.fArea = overlap;
		
		temp.fData = buffer.DirtyPixel (overlap.t,
								   		overlap.l,
								   		buffer.fPlane);
	
		DoGet (temp);
		
		}
		
	// See if we need to pad the edge values.
	
	if ((edgeOption != edge_none) && (overlap != buffer.fArea))
		{
		
		dng_rect areaT (buffer.fArea);
		dng_rect areaL (buffer.fArea);
		dng_rect areaB (buffer.fArea);
		dng_rect areaR (buffer.fArea);
		
		areaT.b = Min_int32 (areaT.b, fBounds.t);
		areaL.r = Min_int32 (areaL.r, fBounds.l);
		areaB.t = Max_int32 (areaB.t, fBounds.b);
		areaR.l = Max_int32 (areaR.l, fBounds.r);
		
		dng_rect areaH (buffer.fArea);
		dng_rect areaV (buffer.fArea);
		
		areaH.l = Max_int32 (areaH.l, fBounds.l);
		areaH.r = Min_int32 (areaH.r, fBounds.r);
		
		areaV.t = Max_int32 (areaV.t, fBounds.t);
		areaV.b = Min_int32 (areaV.b, fBounds.b);
		
		// Top left.
		
		dng_rect areaTL = areaT & areaL;
		
		if (areaTL.NotEmpty ())
			{
			
			GetEdge (buffer,
					 edgeOption,
					 dng_rect (fBounds.t,
					 		   fBounds.l,
					 		   fBounds.t + (int32)repeatV,
					 		   fBounds.l + (int32)repeatH),
					 areaTL);
			
			}
			
		// Top middle.
		
		dng_rect areaTM = areaT & areaH;
		
		if (areaTM.NotEmpty ())
			{
			
			GetEdge (buffer,
					 edgeOption,
					 dng_rect (fBounds.t,
					 		   areaTM.l,
					 		   fBounds.t + (int32)repeatV,
					 		   areaTM.r),
					 areaTM);
			
			}
		
		// Top right.
		
		dng_rect areaTR = areaT & areaR;
		
		if (areaTR.NotEmpty ())
			{
			
			GetEdge (buffer,
					 edgeOption,
					 dng_rect (fBounds.t,
					 		   fBounds.r - (int32)repeatH,
					 		   fBounds.t + (int32)repeatV,
					 		   fBounds.r),
					 areaTR);
			
			}
			
		// Left middle.
		
		dng_rect areaLM = areaL & areaV;
		
		if (areaLM.NotEmpty ())
			{
			
			GetEdge (buffer,
					 edgeOption,
					 dng_rect (areaLM.t,
					 		   fBounds.l,
					 		   areaLM.b,
					 		   fBounds.l + (int32)repeatH),
					 areaLM);
			
			}
		
		// Right middle.
		
		dng_rect areaRM = areaR & areaV;
		
		if (areaRM.NotEmpty ())
			{
			
			GetEdge (buffer,
					 edgeOption,
					 dng_rect (areaRM.t,
					 		   fBounds.r - (int32)repeatH,
					 		   areaRM.b,
					 		   fBounds.r),
					 areaRM);
			
			}
		
		// Bottom left.
		
		dng_rect areaBL = areaB & areaL;
		
		if (areaBL.NotEmpty ())
			{
			
			GetEdge (buffer,
					 edgeOption,
					 dng_rect (fBounds.b - (int32)repeatV,
					 		   fBounds.l,
					 		   fBounds.b,
					 		   fBounds.l + (int32)repeatH),
					 areaBL);
			
			}
			
		// Bottom middle.
		
		dng_rect areaBM = areaB & areaH;
		
		if (areaBM.NotEmpty ())
			{
			
			GetEdge (buffer,
					 edgeOption,
					 dng_rect (fBounds.b - (int32)repeatV,
					 		   areaBM.l,
					 		   fBounds.b,
					 		   areaBM.r),
					 areaBM);
			
			}
		
		// Bottom right.
		
		dng_rect areaBR = areaB & areaR;
		
		if (areaBR.NotEmpty ())
			{
			
			GetEdge (buffer,
					 edgeOption,
					 dng_rect (fBounds.b - (int32)repeatV,
					 		   fBounds.r - (int32)repeatH,
					 		   fBounds.b,
					 		   fBounds.r),
					 areaBR);
			
			}
			
		}
	
	}
		
/*****************************************************************************/

void dng_image::Put (const dng_pixel_buffer &buffer)
	{
	
	// Move the overlapping pixels.
	
	dng_rect overlap = buffer.fArea & fBounds;
	
	if (overlap.NotEmpty ())
		{
	
		dng_pixel_buffer temp (buffer);
		
		temp.fArea = overlap;
		
		temp.fData = (void *) buffer.ConstPixel (overlap.t,
								   		 		 overlap.l,
								   		 		 buffer.fPlane);
												 
		// Move the overlapping planes.
												 
		if (temp.fPlane < Planes ())
			{
			
			temp.fPlanes = Min_uint32 (temp.fPlanes,
									   Planes () - temp.fPlane);
	
			DoPut (temp);
			
			}
		
		}
		
	}
		
/*****************************************************************************/

void dng_image::Trim (const dng_rect &r)
	{
	
	if (r != Bounds ())
		{
		
		ThrowProgramError ("Trim is not support by this dng_image subclass");
		
		}
	
	}
		
/*****************************************************************************/

void dng_image::Rotate (const dng_orientation &orientation)
	{
	
	if (orientation != dng_orientation::Normal ())
		{
		
		ThrowProgramError ("Rotate is not support by this dng_image subclass");
		
		}
	
	}
		
/*****************************************************************************/

void dng_image::CopyArea (const dng_image &src,
						  const dng_rect &area,
						  uint32 srcPlane,
						  uint32 dstPlane,
						  uint32 planes)
	{

	if (&src == this)
		return;

	dng_tile_iterator destIter(*this, area);
	dng_rect destTileArea;

	while (destIter.GetOneTile(destTileArea))
		{
		dng_tile_iterator srcIter(src, destTileArea);
		dng_rect srcTileArea;

		while (srcIter.GetOneTile(srcTileArea))
			{

			dng_dirty_tile_buffer destTile(*this, srcTileArea);
			dng_const_tile_buffer srcTile(src, srcTileArea);

			destTile.CopyArea (srcTile, srcTileArea, srcPlane, dstPlane, planes);

			}

		}

	}

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

bool dng_image::EqualArea (const dng_image &src,
						   const dng_rect &area,
						   uint32 plane,
						   uint32 planes) const
	{

	if (&src == this)
		return true;

	dng_tile_iterator destIter (*this, area);
	
	dng_rect destTileArea;

	while (destIter.GetOneTile (destTileArea))
		{
		
		dng_tile_iterator srcIter (src, destTileArea);
		
		dng_rect srcTileArea;

		while (srcIter.GetOneTile (srcTileArea))
			{

			dng_const_tile_buffer destTile (*this, srcTileArea);
			dng_const_tile_buffer srcTile  (src  , srcTileArea);

			if (!destTile.EqualArea (srcTile, srcTileArea, plane, planes))
				{
				return false;
				}

			}

		}

	return true;

	}

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

void dng_image::SetConstant (uint32 value,
							 const dng_rect &area)
	{
	
	dng_tile_iterator iter (*this, area);
							
	dng_rect tileArea;
	
	while (iter.GetOneTile (tileArea))
		{
		
		dng_dirty_tile_buffer buffer (*this, tileArea);
		
		buffer.SetConstant (tileArea,
							0,
							fPlanes,
							value);
					
		}

	}

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