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; }
dng_matrix::dng_matrix (uint32 rows, uint32 cols) : fRows (0) , fCols (0) { if (rows < 1 || rows > kMaxColorPlanes || cols < 1 || cols > kMaxColorPlanes) { ThrowProgramError (); } fRows = rows; fCols = cols; for (uint32 row = 0; row < fRows; row++) for (uint32 col = 0; col < fCols; col++) { fData [row] [col] = 0.0; } }
dng_memory_block * dng_stream::AsMemoryBlock (dng_memory_allocator &allocator) { Flush (); uint64 len64 = Length (); if (len64 > 0xFFFFFFFF) { ThrowProgramError (); } uint32 len = (uint32) len64; AutoPtr<dng_memory_block> block (allocator.Allocate (len)); if (len) { SetReadPosition (0); Get (block->Buffer (), len); } return block.Release (); }
dng_opcode_MapTable::dng_opcode_MapTable (dng_host &host, const dng_area_spec &areaSpec, const uint16 *table, uint32 count) : dng_inplace_opcode (dngOpcode_MapTable, dngVersion_1_3_0_0, kFlag_None) , fAreaSpec (areaSpec) , fTable () , fCount (count) { if (count == 0 || count > 0x10000) { ThrowProgramError (); } fTable.Reset (host.Allocate (0x10000 * sizeof (uint16))); DoCopyBytes (table, fTable->Buffer (), count * sizeof (uint16)); ReplicateLastEntry (); }
void dng_stream::DoWrite (const void * /* data */, uint32 /* count */, uint64 /* offset */) { ThrowProgramError (); }
uint64 dng_stream::DoGetLength () { ThrowProgramError (); return 0; }
void dng_stream::DoRead (void * /* data */, uint32 /* count */, uint64 /* offset */) { ThrowProgramError (); }
dng_image * dng_image::Clone () const { ThrowProgramError ("Clone is not supported by this dng_image subclass"); return NULL; }
void dng_image::AcquireTileBuffer (dng_tile_buffer & /* buffer */, const dng_rect & /* area */, bool /* dirty */) const { ThrowProgramError (); }
dng_date_time_format dng_date_time_storage_info::Format () const { if (!IsValid ()) ThrowProgramError (); return fFormat; }
uint64 dng_date_time_storage_info::Offset () const { if (!IsValid ()) ThrowProgramError (); return fOffset; }
static void InitInnermostMutex () { int result = pthread_key_create (&gInnermostMutexKey, NULL); DNG_ASSERT (result == 0, "pthread_key_create failed."); if (result != 0) ThrowProgramError (); }
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::Trim (const dng_rect &r) { if (r != Bounds ()) { ThrowProgramError ("Trim is not support by this dng_image subclass"); } }
static void SetInnermostMutex (dng_mutex *mutex) { int result; result = pthread_setspecific (gInnermostMutexKey, (void *)mutex); DNG_ASSERT (result == 0, "pthread_setspecific failed."); if (result != 0) ThrowProgramError (); }
void dng_image::SetPixelType (uint32 pixelType) { if (TagTypeSize (pixelType) != PixelSize ()) { ThrowProgramError ("Cannot change pixel size for existing image"); } fPixelType = pixelType; }
void dng_condition::Broadcast () { int result; result = pthread_cond_broadcast (&fPthreadCondition); DNG_ASSERT (result == 0, "pthread_cond_broadcast failed."); if (result != 0) ThrowProgramError (); }
void dng_condition::Signal () { int result; result = pthread_cond_signal (&fPthreadCondition); DNG_ASSERT (result == 0, "pthread_cond_signal failed."); if (result != 0) ThrowProgramError (); }
void dng_camera_profile::SetFourColorBayer () { uint32 j; if (!IsValid (3)) { ThrowProgramError (); } if (fColorMatrix1.NotEmpty ()) { dng_matrix m (4, 3); for (j = 0; j < 3; j++) { m [0] [j] = fColorMatrix1 [0] [j]; m [1] [j] = fColorMatrix1 [1] [j]; m [2] [j] = fColorMatrix1 [2] [j]; m [3] [j] = fColorMatrix1 [1] [j]; } fColorMatrix1 = m; } if (fColorMatrix2.NotEmpty ()) { dng_matrix m (4, 3); for (j = 0; j < 3; j++) { m [0] [j] = fColorMatrix2 [0] [j]; m [1] [j] = fColorMatrix2 [1] [j]; m [2] [j] = fColorMatrix2 [2] [j]; m [3] [j] = fColorMatrix2 [1] [j]; } fColorMatrix2 = m; } fReductionMatrix1.Clear (); fReductionMatrix2.Clear (); fForwardMatrix1.Clear (); fForwardMatrix2.Clear (); }
dng_condition::dng_condition () : fPthreadCondition () { int result; result = pthread_cond_init (&fPthreadCondition, NULL); DNG_ASSERT (result == 0, "pthread_cond_init failed."); if (result != 0) { ThrowProgramError (); } }
dng_vector::dng_vector (uint32 count) : fCount (0) { if (count < 1 || count > kMaxColorPlanes) { ThrowProgramError (); } fCount = count; for (uint32 index = 0; index < fCount; index++) { fData [index] = 0.0; } }
real64 TickCountInSeconds () { #if qWinOS return GetTickCount () * (1.0 / 1000.0); #elif qMacOS #if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR // TODO: Needs implementation. ThrowProgramError ("TickCountInSeconds() not implemented on iOS"); return 0; #else return TickCount () * (1.0 / 60.0); #endif // TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR #else return TickTimeInSeconds (); #endif }
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 (); } } }
dng_color_spec::dng_color_spec (const dng_negative &negative, const dng_camera_profile *profile) : fChannels (negative.ColorChannels ()) , fTemperature1 (0.0) , fTemperature2 (0.0) , fColorMatrix1 () , fColorMatrix2 () , fForwardMatrix1 () , fForwardMatrix2 () , fReductionMatrix1 () , fReductionMatrix2 () , fCameraCalibration1 () , fCameraCalibration2 () , fAnalogBalance () , fWhiteXY () , fCameraWhite () , fCameraToPCS () , fPCStoCamera () { if (fChannels > 1) { if (!profile || !profile->IsValid (fChannels)) { ThrowBadFormat (); } if (profile->WasStubbed ()) { ThrowProgramError ("Using stubbed profile"); } fTemperature1 = profile->CalibrationTemperature1 (); fTemperature2 = profile->CalibrationTemperature2 (); fColorMatrix1 = profile->ColorMatrix1 (); fColorMatrix2 = profile->ColorMatrix2 (); fForwardMatrix1 = profile->ForwardMatrix1 (); fForwardMatrix2 = profile->ForwardMatrix2 (); fReductionMatrix1 = profile->ReductionMatrix1 (); fReductionMatrix2 = profile->ReductionMatrix2 (); fCameraCalibration1.SetIdentity (fChannels); fCameraCalibration2.SetIdentity (fChannels); if (negative. CameraCalibrationSignature () == profile->ProfileCalibrationSignature ()) { if (negative.CameraCalibration1 ().Rows () == fChannels && negative.CameraCalibration1 ().Cols () == fChannels) { fCameraCalibration1 = negative.CameraCalibration1 (); } if (negative.CameraCalibration2 ().Rows () == fChannels && negative.CameraCalibration2 ().Cols () == fChannels) { fCameraCalibration2 = negative.CameraCalibration2 (); } } fAnalogBalance = dng_matrix (fChannels, fChannels); for (uint32 j = 0; j < fChannels; j++) { fAnalogBalance [j] [j] = negative.AnalogBalance (j); } dng_camera_profile::NormalizeForwardMatrix (fForwardMatrix1); fColorMatrix1 = fAnalogBalance * fCameraCalibration1 * fColorMatrix1; if (!profile->HasColorMatrix2 () || fTemperature1 <= 0.0 || fTemperature2 <= 0.0 || fTemperature1 == fTemperature2) { fTemperature1 = 5000.0; fTemperature2 = 5000.0; fColorMatrix2 = fColorMatrix1; fForwardMatrix2 = fForwardMatrix1; fReductionMatrix2 = fReductionMatrix1; fCameraCalibration2 = fCameraCalibration1; } else { dng_camera_profile::NormalizeForwardMatrix (fForwardMatrix2); fColorMatrix2 = fAnalogBalance * fCameraCalibration2 * fColorMatrix2; // Swap values if temperatures are out of order. if (fTemperature1 > fTemperature2) { real64 temp = fTemperature1; fTemperature1 = fTemperature2; fTemperature2 = temp; dng_matrix T = fColorMatrix1; fColorMatrix1 = fColorMatrix2; fColorMatrix2 = T; T = fForwardMatrix1; fForwardMatrix1 = fForwardMatrix2; fForwardMatrix2 = T; T = fReductionMatrix1; fReductionMatrix1 = fReductionMatrix2; fReductionMatrix2 = T; T = fCameraCalibration1; fCameraCalibration1 = fCameraCalibration2; fCameraCalibration2 = T; } } } }
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); } } }
void dng_stream::DoSetLength (uint64 /* length */) { ThrowProgramError (); }
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_xmp_sdk::InitializeSDK (dng_xmp_namespace * extraNamespaces) { if (!gInitializedXMP) { try { if (!SXMPMeta::Initialize ()) { ThrowProgramError (); } // Register Lightroom beta settings namespace. // We no longer read this but I don't want to cut it out this close // to a release. [bruzenak] { TXMP_STRING_TYPE ss; SXMPMeta::RegisterNamespace (XMP_NS_CRX, "crx", &ss); } // Register CRSS snapshots namespace { TXMP_STRING_TYPE ss; SXMPMeta::RegisterNamespace (XMP_NS_CRSS, "crss", &ss); } // Register extra namespaces. if (extraNamespaces != NULL) { for (; extraNamespaces->fullName != NULL; ++extraNamespaces) { TXMP_STRING_TYPE ss; SXMPMeta::RegisterNamespace (extraNamespaces->fullName, extraNamespaces->shortName, &ss); } } } CATCH_XMP ("Initialization", true) gInitializedXMP = true; } }
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); }