void dng_simple_image::Trim (const dng_rect &r)
	{
	
	fBounds.t = 0;
	fBounds.l = 0;
	
	fBounds.b = r.H ();
	fBounds.r = r.W ();
	
	fBuffer.fData = fBuffer.DirtyPixel (r.t, r.l);
								   
	fBuffer.fArea = fBounds;
	
	}
dng_simple_image::dng_simple_image (const dng_rect &bounds,
									uint32 planes,
								    uint32 pixelType,
								    uint32 pixelRange,
								    dng_memory_allocator &allocator)
								    
	:	dng_image (bounds,
				   planes,
				   pixelType,
				   pixelRange)
				   
	,	fMemory ()
	,	fBuffer ()
				   
	{
	
	uint32 pixelSize = TagTypeSize (pixelType);
	
	uint32 bytes = bounds.H () * bounds.W () * planes * pixelSize;
				   
	fMemory.Reset (allocator.Allocate (bytes));
	
	fBuffer.fArea = bounds;
	
	fBuffer.fPlane  = 0;
	fBuffer.fPlanes = planes;
	
	fBuffer.fRowStep   = planes * bounds.W ();
	fBuffer.fColStep   = planes;
	fBuffer.fPlaneStep = 1;
	
	fBuffer.fPixelType  = pixelType;
	fBuffer.fPixelSize  = pixelSize;
	fBuffer.fPixelRange = pixelRange;
	
	fBuffer.fData = fMemory->Buffer ();
	
	}
void dng_tile_iterator::Initialize (const dng_rect &tile,
						 			const dng_rect &area)
	{
	
	fArea = area;
	
	if (area.IsEmpty ())
		{
		
		fVerticalPage =  0;
		fBottomPage   = -1;
		
		return;
		
		}
	
	int32 vOffset = tile.t;
	int32 hOffset = tile.l;
	
	int32 tileHeight = tile.b - vOffset;
	int32 tileWidth  = tile.r - hOffset;
	
	fTileHeight = tileHeight;
	fTileWidth  = tileWidth;
	
	fLeftPage  = (fArea.l - hOffset    ) / tileWidth;
	fRightPage = (fArea.r - hOffset - 1) / tileWidth;
	
	fHorizontalPage = fLeftPage;
	
	fTopPage    = (fArea.t - vOffset    ) / tileHeight;
	fBottomPage = (fArea.b - vOffset - 1) / tileHeight;
	
	fVerticalPage = fTopPage;
	
	fTileLeft = fHorizontalPage * tileWidth  + hOffset;
	fTileTop  = fVerticalPage   * tileHeight + vOffset;

	fRowLeft = fTileLeft;
			
	}
dng_simple_image::dng_simple_image (const dng_rect &bounds,
									uint32 planes,
								    uint32 pixelType,
								    dng_memory_allocator &allocator)
								    
	:	dng_image (bounds,
				   planes,
				   pixelType)
				   
	,	fMemory    ()
	,	fAllocator (allocator)
				   
	{
	
	uint32 bytes =
		ComputeBufferSize (pixelType, bounds.Size (), planes, pad16Bytes);
				   
	fMemory.Reset (allocator.Allocate (bytes));
	
	fBuffer = dng_pixel_buffer (bounds, 0, planes, pixelType, pcInterleaved, fMemory->Buffer ());
	
	}
Exemple #5
0
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 ();
		
		}
		
	}
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_limit_float_depth_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);
	
	uint32 count0 = tile.H ();
	uint32 count1 = tile.W ();
	uint32 count2 = fDstImage.Planes ();
	
	int32 sStep0 = srcBuffer.fRowStep;
	int32 sStep1 = srcBuffer.fColStep;
	int32 sStep2 = srcBuffer.fPlaneStep;
	
	int32 dStep0 = dstBuffer.fRowStep;
	int32 dStep1 = dstBuffer.fColStep;
	int32 dStep2 = dstBuffer.fPlaneStep;

	const void *sPtr = srcBuffer.ConstPixel (tile.t,
											 tile.l,
											 0);
											 
		  void *dPtr = dstBuffer.DirtyPixel (tile.t,
											 tile.l,
											 0);

	OptimizeOrder (sPtr,
			       dPtr,
				   srcBuffer.fPixelSize,
				   dstBuffer.fPixelSize,
				   count0,
				   count1,
				   count2,
				   sStep0,
				   sStep1,
				   sStep2,
				   dStep0,
				   dStep1,
				   dStep2);
				   
	const real32 *sPtr0 = (const real32 *) sPtr;
		  real32 *dPtr0 = (      real32 *) dPtr;
		  
	real32 scale = fScale;
		  
	bool limit16 = (fBitDepth == 16);
	bool limit24 = (fBitDepth == 24);
				   
	for (uint32 index0 = 0; index0 < count0; index0++)
		{
		
		const real32 *sPtr1 = sPtr0;
			  real32 *dPtr1 = dPtr0;
			  
		for (uint32 index1 = 0; index1 < count1; index1++)
			{
			
			// If the scale is a NOP, and the data is packed solid, we can just do memory
			// copy.
			
			if (scale == 1.0f && sStep2 == 1 && dStep2 == 1)
				{
				
				if (dPtr1 != sPtr1)			// srcImage != dstImage
					{
				
					memcpy (dPtr1, sPtr1, count2 * (uint32) sizeof (real32));
					
					}
				
				}
				
			else
				{
			
				const real32 *sPtr2 = sPtr1;
					  real32 *dPtr2 = dPtr1;
					  
				for (uint32 index2 = 0; index2 < count2; index2++)
					{
					
					real32 x = sPtr2 [0];
					
					x *= scale;
					
					dPtr2 [0] = x;
					
					sPtr2 += sStep2;
					dPtr2 += dStep2;
					
					}
					
				}
				
			// The data is now in the destination buffer.
				
			if (limit16)
				{
			
				uint32 *dPtr2 = (uint32 *) dPtr1;
					  
				for (uint32 index2 = 0; index2 < count2; index2++)
					{
					
					uint32 x = dPtr2 [0];
					
					uint16 y = DNG_FloatToHalf (x);
					
					x = DNG_HalfToFloat (y);
											
					dPtr2 [0] = x;
					
					dPtr2 += dStep2;
					
					}
					
				}
				
			else if (limit24)
				{
			
				uint32 *dPtr2 = (uint32 *) dPtr1;
					  
				for (uint32 index2 = 0; index2 < count2; index2++)
					{
					
					uint32 x = dPtr2 [0];
											
					uint8 temp [3];
					
					DNG_FloatToFP24 (x, temp);
					
					x = DNG_FP24ToFloat (temp);
					
					dPtr2 [0] = x;
					
					dPtr2 += dStep2;
					
					}
					
				}
			  
			sPtr1 += sStep1;
			dPtr1 += dStep1;
			
			}
				   
		sPtr0 += sStep0;
		dPtr0 += dStep0;
		
		}
				   	
	}
void dng_filter_task::Process (uint32 threadIndex,
							   const dng_rect &area,
							   dng_abort_sniffer * /* sniffer */)
	{
	
	// Find source area for this destination area.
	
	dng_rect srcArea = SrcArea (area);
					  
	// Setup srcBuffer.
	
	dng_pixel_buffer srcBuffer;
	
	srcBuffer.fArea = srcArea;
								
	srcBuffer.fPlane  = fSrcPlane;
	srcBuffer.fPlanes = fSrcPlanes;
	
	srcBuffer.fPixelType  = fSrcPixelType;
	srcBuffer.fPixelSize  = TagTypeSize (fSrcPixelType);
	
	srcBuffer.fPlaneStep = RoundUpForPixelSize (srcArea.W (),
											    srcBuffer.fPixelSize);
	
	srcBuffer.fRowStep = srcBuffer.fPlaneStep *
						 srcBuffer.fPlanes;
	
	if (fSrcPixelType == fSrcImage.PixelType ())
		{
		
		srcBuffer.fPixelRange = fSrcImage.PixelRange ();
		
		}
		
	else switch (fSrcPixelType)
		{
		
		case ttByte:
		case ttSByte:
			{
			srcBuffer.fPixelRange = 0x0FF;
			break;
			}
		
		case ttShort:
		case ttSShort:
			{
			srcBuffer.fPixelRange = 0x0FFFF;
			break;
			}
		
		case ttLong:
		case ttSLong:
			{
			srcBuffer.fPixelRange = 0xFFFFFFFF;
			break;
			}
			
		case ttFloat:
			break;
			
		default:
			ThrowProgramError ();
		
		}
		
	srcBuffer.fData = fSrcBuffer [threadIndex]->Buffer ();
	
	// Setup dstBuffer.
	
	dng_pixel_buffer dstBuffer;
	
	dstBuffer.fArea = area;
	
	dstBuffer.fPlane  = fDstPlane;
	dstBuffer.fPlanes = fDstPlanes;
	
	dstBuffer.fPixelType  = fDstPixelType;
	dstBuffer.fPixelSize  = TagTypeSize (fDstPixelType);
	
	dstBuffer.fPlaneStep = RoundUpForPixelSize (area.W (),
												dstBuffer.fPixelSize);
	
	dstBuffer.fRowStep = dstBuffer.fPlaneStep *
						 dstBuffer.fPlanes;
	
	if (fDstPixelType == fDstImage.PixelType ())
		{
		
		dstBuffer.fPixelRange = fDstImage.PixelRange ();
		
		}
		
	else switch (fDstPixelType)
		{
		
		case ttByte:
		case ttSByte:
			{
			dstBuffer.fPixelRange = 0x0FF;
			break;
			}
		
		case ttShort:
		case ttSShort:
			{
			dstBuffer.fPixelRange = 0x0FFFF;
			break;
			}
		
		case ttLong:
		case ttSLong:
			{
			dstBuffer.fPixelRange = 0xFFFFFFFF;
			break;
			}
			
		case ttFloat:
			break;
			
		default:
			ThrowProgramError ();
		
		}
		
	dstBuffer.fData = fDstBuffer [threadIndex]->Buffer ();
	
	// Get source pixels.
	
	fSrcImage.Get (srcBuffer,
				   dng_image::edge_repeat,
				   fSrcRepeat.v,
				   fSrcRepeat.h);
				   
	// Process area.
	
	ProcessArea (threadIndex,
				 srcBuffer,
				 dstBuffer);

	// Save result pixels.
	
	fDstImage.Put (dstBuffer);
	
	}
void dng_filter_task::Process (uint32 threadIndex,
							   const dng_rect &area,
							   dng_abort_sniffer * /* sniffer */)
	{
	
	// Find source area for this destination area.
	
	dng_rect srcArea = SrcArea (area);
					  
	// Setup srcBuffer.
	
	dng_pixel_buffer srcBuffer;
	
	srcBuffer.fArea = srcArea;
								
	srcBuffer.fPlane  = fSrcPlane;
	srcBuffer.fPlanes = fSrcPlanes;
	
	srcBuffer.fPixelType  = fSrcPixelType;
	srcBuffer.fPixelSize  = TagTypeSize (fSrcPixelType);
	
	srcBuffer.fPlaneStep = RoundUpForPixelSize (srcArea.W (),
											    srcBuffer.fPixelSize);
	
	srcBuffer.fRowStep = srcBuffer.fPlaneStep *
						 srcBuffer.fPlanes;
		
	srcBuffer.fData = fSrcBuffer [threadIndex]->Buffer ();
	
	// Setup dstBuffer.
	
	dng_pixel_buffer dstBuffer;
	
	dstBuffer.fArea = area;
	
	dstBuffer.fPlane  = fDstPlane;
	dstBuffer.fPlanes = fDstPlanes;
	
	dstBuffer.fPixelType  = fDstPixelType;
	dstBuffer.fPixelSize  = TagTypeSize (fDstPixelType);
	
	dstBuffer.fPlaneStep = RoundUpForPixelSize (area.W (),
												dstBuffer.fPixelSize);
	
	dstBuffer.fRowStep = dstBuffer.fPlaneStep *
						 dstBuffer.fPlanes;
			
	dstBuffer.fData = fDstBuffer [threadIndex]->Buffer ();
	
	// Get source pixels.
	
	fSrcImage.Get (srcBuffer,
				   dng_image::edge_repeat,
				   fSrcRepeat.v,
				   fSrcRepeat.h);
				   
	// Process area.
	
	ProcessArea (threadIndex,
				 srcBuffer,
				 dstBuffer);

	// Save result pixels.
	
	fDstImage.Put (dstBuffer);
	
	}
Exemple #10
0
dng_gain_map_interpolator::dng_gain_map_interpolator (const dng_gain_map &map,
													  const dng_rect &mapBounds,
													  int32 row,
													  int32 column,
													  uint32 plane)

	:	fMap (map)
	
	,	fScale (1.0 / mapBounds.H (),
				1.0 / mapBounds.W ())
	
	,	fOffset (0.5 - mapBounds.t,
				 0.5 - mapBounds.l)
	
	,	fColumn (column)
	,	fPlane  (plane)
	
	,	fRowIndex1 (0)
	,	fRowIndex2 (0)
	,	fRowFract  (0.0f)
	
	,	fResetColumn (0)
	
	,	fValueBase  (0.0f)
	,	fValueStep  (0.0f)
	,	fValueIndex (0.0f)
	
	{
	
	real64 rowIndexF = (fScale.v * (row + fOffset.v) -
						fMap.Origin ().v) / fMap.Spacing ().v;
	
	if (rowIndexF <= 0.0)
		{
		
		fRowIndex1 = 0;
		fRowIndex2 = 0;
		
		fRowFract = 0.0f;

		}
		
	else
		{
		
		fRowIndex1 = (uint32) rowIndexF;
		
		if ((int32) fRowIndex1 >= fMap.Points ().v - 1)
			{
			
			fRowIndex1 = fMap.Points ().v - 1;
			fRowIndex2 = fRowIndex1;
			
			fRowFract = 0.0f;
			
			}
			
		else
			{
			
			fRowIndex2 = fRowIndex1 + 1;
			
			fRowFract = (real32) (rowIndexF - (real64) fRowIndex1);
			
			}
			
		}
	
	ResetColumn ();
		
	}