void LimitFloatBitDepth (dng_host &host, const dng_image &srcImage, dng_image &dstImage, uint32 bitDepth, real32 scale) { DNG_ASSERT (srcImage.PixelType () == ttFloat, "Floating point image expected"); DNG_ASSERT (dstImage.PixelType () == ttFloat, "Floating point image expected"); dng_limit_float_depth_task task (srcImage, dstImage, bitDepth, scale); host.PerformAreaTask (task, dstImage.Bounds ()); }
dng_filter_task::dng_filter_task (const dng_image &srcImage, dng_image &dstImage) : fSrcImage (srcImage) , fDstImage (dstImage) , fSrcPlane (0 ) , fSrcPlanes (srcImage.Planes ()) , fSrcPixelType (srcImage.PixelType ()) , fDstPlane (0 ) , fDstPlanes (dstImage.Planes ()) , fDstPixelType (dstImage.PixelType ()) , fSrcRepeat (1, 1) { }
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; }
void HistogramArea (dng_host & /* host */, const dng_image &image, const dng_rect &area, uint32 *hist, uint32 maxValue, uint32 plane) { DNG_ASSERT (image.PixelType () == ttShort, "Unsupported pixel type"); DoZeroBytes (hist, (maxValue + 1) * (uint32) sizeof (uint32)); dng_rect tile; dng_tile_iterator iter (image, area); while (iter.GetOneTile (tile)) { dng_const_tile_buffer buffer (image, tile); const void *sPtr = buffer.ConstPixel (tile.t, tile.l, plane); uint32 count0 = 1; uint32 count1 = tile.H (); uint32 count2 = tile.W (); int32 step0 = 0; int32 step1 = buffer.fRowStep; int32 step2 = buffer.fColStep; OptimizeOrder (sPtr, buffer.fPixelSize, count0, count1, count2, step0, step1, step2); DNG_ASSERT (count0 == 1, "OptimizeOrder logic error"); const uint16 *s1 = (const uint16 *) sPtr; for (uint32 row = 0; row < count1; row++) { if (maxValue == 0x0FFFF && step2 == 1) { for (uint32 col = 0; col < count2; col++) { uint32 x = s1 [col]; hist [x] ++; } } else { const uint16 *s2 = s1; for (uint32 col = 0; col < count2; col++) { uint32 x = s2 [0]; if (x <= maxValue) { hist [x] ++; } s2 += step2; } } s1 += step1; } } }