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