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; }
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 }
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; }
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 (); }
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); } } }