Esempio n. 1
0
void dng_hue_sat_map::GetDelta (uint32 hueDiv,
								uint32 satDiv,
								uint32 valDiv,
								HSBModify &modify) const
	{

	if (hueDiv >= fHueDivisions ||
		satDiv >= fSatDivisions ||
		valDiv >= fValDivisions ||
		fDeltas.Buffer () == NULL)
		{
		
		DNG_REPORT ("Bad parameters to dng_hue_sat_map::GetDelta");
		
		ThrowProgramError ();
		
		}

	int32 offset = valDiv * fValStep +
				   hueDiv * fHueStep +
				   satDiv;

	const HSBModify *deltas = GetDeltas ();

	modify.fHueShift = deltas [offset].fHueShift;
	modify.fSatScale = deltas [offset].fSatScale;
	modify.fValScale = deltas [offset].fValScale;

	}
Esempio n. 2
0
void dng_mutex::Lock ()
	{
	
	#if qDNGThreadSafe

	dng_mutex *innermostMutex = gInnermostMutexHolder.GetInnermostMutex ();

	if (innermostMutex != NULL)
		{

		if (innermostMutex == this)
			{

			fRecursiveLockCount++;

			return;

			}

		bool lockOrderPreserved = fMutexLevel > innermostMutex->fMutexLevel /* ||
								  (fMutexLevel == innermostMutex->fMutexLevel && innermostMutex < this) */;

		if (!lockOrderPreserved)
			{
			
			DNG_REPORT ("Lock ordering violation.");
			
			#if qDNGDebug
			
			dng_show_message_f ("This mutex: %s v Innermost mutex: %s",
								this->MutexName (),
								innermostMutex->MutexName ());
			
			#endif

			}

		}

	pthread_mutex_lock (&fPthreadMutex);

	fPrevHeldMutex = innermostMutex;

	gInnermostMutexHolder.SetInnermostMutex (this);

	#endif
	
	}
Esempio n. 3
0
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)
		{

		DNG_REPORT ("Unsupported source pixel type");

		ThrowProgramError ();

		}

	if (fDstPixelType != ttShort &&
		fDstPixelType != ttFloat)
		{

		DNG_REPORT ("Unsupported destination pixel type");

		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 (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 (fBlack_1D_rows * 4));

		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];

				}

			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;

				}

			}

		}

	// Calculate scale table, if any.

	if (fSrcPixelType != ttLong)
		{

		// 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;

			}
Esempio n. 4
0
dng_hue_sat_map * dng_hue_sat_map::Interpolate (const dng_hue_sat_map &map1,
											    const dng_hue_sat_map &map2,
											    real64 weight1)
	{
	
	if (weight1 >= 1.0)
		{
		
		if (!map1.IsValid ())
			{
			
			DNG_REPORT ("map1 is not valid");
			
			ThrowProgramError ();
			
			}
			
		return new dng_hue_sat_map (map1);
		
		}
		
	if (weight1 <= 0.0)
		{
		
		if (!map2.IsValid ())
			{
			
			DNG_REPORT ("map2 is not valid");
			
			ThrowProgramError ();
			
			}
			
		return new dng_hue_sat_map (map2);
		
		}
		
	// Both maps must be valid if we are using both.
	
	if (!map1.IsValid () || !map2.IsValid ())
		{
			
		DNG_REPORT ("map1 or map2 is not valid");
		
		ThrowProgramError ();
		
		}
		
	// Must have the same dimensions.
	
	if (map1.fHueDivisions != map2.fHueDivisions ||
		map1.fSatDivisions != map2.fSatDivisions ||
		map1.fValDivisions != map2.fValDivisions)
		{
		
		DNG_REPORT ("map1 and map2 have different sizes");
		
		ThrowProgramError ();
		
		}
		
	// Make table to hold interpolated results.
	
	AutoPtr<dng_hue_sat_map> result (new dng_hue_sat_map);
	
	result->SetDivisions (map1.fHueDivisions,
						  map1.fSatDivisions,
						  map1.fValDivisions);
						  
	// Interpolate between the tables.
	
	real32 w1 = (real32) weight1;
	real32 w2 = 1.0f - w1;
	
	const HSBModify *data1 = map1.GetDeltas ();
	const HSBModify *data2 = map2.GetDeltas ();
	
	HSBModify *data3 = result->GetDeltas ();
	
	uint32 count = map1.DeltasCount ();
	
	for (uint32 index = 0; index < count; index++)
		{
		
		data3->fHueShift = w1 * data1->fHueShift +
						   w2 * data2->fHueShift;
						   
		data3->fSatScale = w1 * data1->fSatScale +
						   w2 * data2->fSatScale;
						   
		data3->fValScale = w1 * data1->fValScale +
						   w2 * data2->fValScale;
						   
		data1++;
		data2++;
		data3++;
		
		}
		
	// Return interpolated tables.
	
	return result.Release ();
		
	}
Esempio n. 5
0
void dng_hue_sat_map::SetDelta (uint32 hueDiv,
								uint32 satDiv,
								uint32 valDiv,
								const HSBModify &modify)
	{

	if (hueDiv >= fHueDivisions ||
		satDiv >= fSatDivisions ||
		valDiv >= fValDivisions ||
		fDeltas.Buffer () == NULL)
		{
		
		DNG_REPORT ("Bad parameters to dng_hue_sat_map::SetDelta");
		
		ThrowProgramError ();
		
		}
		
	// Set this entry.
		
	int32 offset = valDiv * fValStep +
				   hueDiv * fHueStep +
				   satDiv;

	GetDeltas () [offset] = modify;
	
	// The zero saturation entry is required to have a value scale
	// of 1.0f.
	
	if (satDiv == 0)
		{
		
		if (modify.fValScale != 1.0f)
			{
			
			#if qDNGValidate
		
			ReportWarning ("Value scale for zero saturation entries must be 1.0");
						 
			#endif
			
			GetDeltas () [offset] . fValScale = 1.0f;
		
			}
		
		}
		
	// If we are settings the first saturation entry and we have not
	// set the zero saturation entry yet, fill in the zero saturation entry
	// by extrapolating first saturation entry.
	
	if (satDiv == 1)
		{
		
		HSBModify zeroSatModify;
		
		GetDelta (hueDiv, 0, valDiv, zeroSatModify);
		
		if (zeroSatModify.fValScale != 1.0f)
			{
			
			zeroSatModify.fHueShift = modify.fHueShift;
			zeroSatModify.fSatScale = modify.fSatScale;
			zeroSatModify.fValScale = 1.0f;
			
			SetDelta (hueDiv, 0, valDiv, zeroSatModify);
			
			}
		
		}

	}