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 (); } } }
void dng_image::Get (dng_pixel_buffer &buffer, edge_option edgeOption, uint32 repeatV, uint32 repeatH) const { // Find the overlap with the image bounds. dng_rect overlap = buffer.fArea & fBounds; // Move the overlapping pixels. if (overlap.NotEmpty ()) { dng_pixel_buffer temp (buffer); temp.fArea = overlap; temp.fData = buffer.DirtyPixel (overlap.t, overlap.l, buffer.fPlane); DoGet (temp); } // See if we need to pad the edge values. if ((edgeOption != edge_none) && (overlap != buffer.fArea)) { dng_rect areaT (buffer.fArea); dng_rect areaL (buffer.fArea); dng_rect areaB (buffer.fArea); dng_rect areaR (buffer.fArea); areaT.b = Min_int32 (areaT.b, fBounds.t); areaL.r = Min_int32 (areaL.r, fBounds.l); areaB.t = Max_int32 (areaB.t, fBounds.b); areaR.l = Max_int32 (areaR.l, fBounds.r); dng_rect areaH (buffer.fArea); dng_rect areaV (buffer.fArea); areaH.l = Max_int32 (areaH.l, fBounds.l); areaH.r = Min_int32 (areaH.r, fBounds.r); areaV.t = Max_int32 (areaV.t, fBounds.t); areaV.b = Min_int32 (areaV.b, fBounds.b); // Top left. dng_rect areaTL = areaT & areaL; if (areaTL.NotEmpty ()) { GetEdge (buffer, edgeOption, dng_rect (fBounds.t, fBounds.l, fBounds.t + (int32)repeatV, fBounds.l + (int32)repeatH), areaTL); } // Top middle. dng_rect areaTM = areaT & areaH; if (areaTM.NotEmpty ()) { GetEdge (buffer, edgeOption, dng_rect (fBounds.t, areaTM.l, fBounds.t + (int32)repeatV, areaTM.r), areaTM); } // Top right. dng_rect areaTR = areaT & areaR; if (areaTR.NotEmpty ()) { GetEdge (buffer, edgeOption, dng_rect (fBounds.t, fBounds.r - (int32)repeatH, fBounds.t + (int32)repeatV, fBounds.r), areaTR); } // Left middle. dng_rect areaLM = areaL & areaV; if (areaLM.NotEmpty ()) { GetEdge (buffer, edgeOption, dng_rect (areaLM.t, fBounds.l, areaLM.b, fBounds.l + (int32)repeatH), areaLM); } // Right middle. dng_rect areaRM = areaR & areaV; if (areaRM.NotEmpty ()) { GetEdge (buffer, edgeOption, dng_rect (areaRM.t, fBounds.r - (int32)repeatH, areaRM.b, fBounds.r), areaRM); } // Bottom left. dng_rect areaBL = areaB & areaL; if (areaBL.NotEmpty ()) { GetEdge (buffer, edgeOption, dng_rect (fBounds.b - (int32)repeatV, fBounds.l, fBounds.b, fBounds.l + (int32)repeatH), areaBL); } // Bottom middle. dng_rect areaBM = areaB & areaH; if (areaBM.NotEmpty ()) { GetEdge (buffer, edgeOption, dng_rect (fBounds.b - (int32)repeatV, areaBM.l, fBounds.b, areaBM.r), areaBM); } // Bottom right. dng_rect areaBR = areaB & areaR; if (areaBR.NotEmpty ()) { GetEdge (buffer, edgeOption, dng_rect (fBounds.b - (int32)repeatV, fBounds.r - (int32)repeatH, fBounds.b, fBounds.r), areaBR); } } }
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); } }