void dng_opcode_MapTable::ProcessArea (dng_negative & /* negative */, uint32 /* threadIndex */, dng_pixel_buffer &buffer, const dng_rect &dstArea, const dng_rect & /* imageBounds */) { dng_rect overlap = fAreaSpec.Overlap (dstArea); if (overlap.NotEmpty ()) { for (uint32 plane = fAreaSpec.Plane (); plane < fAreaSpec.Plane () + fAreaSpec.Planes () && plane < buffer.Planes (); plane++) { DoMapArea16 (buffer.DirtyPixel_uint16 (overlap.t, overlap.l, plane), 1, (overlap.H () + fAreaSpec.RowPitch () - 1) / fAreaSpec.RowPitch (), (overlap.W () + fAreaSpec.ColPitch () - 1) / fAreaSpec.ColPitch (), 0, fAreaSpec.RowPitch () * buffer.RowStep (), fAreaSpec.ColPitch (), fTable->Buffer_uint16 ()); } } }
void dng_opcode_GainMap::ProcessArea (dng_negative & /* negative */, uint32 /* threadIndex */, dng_pixel_buffer &buffer, const dng_rect &dstArea, const dng_rect &imageBounds) { dng_rect overlap = fAreaSpec.Overlap (dstArea); if (overlap.NotEmpty ()) { uint32 cols = overlap.W (); uint32 colPitch = fAreaSpec.ColPitch (); for (uint32 plane = fAreaSpec.Plane (); plane < fAreaSpec.Plane () + fAreaSpec.Planes () && plane < buffer.Planes (); plane++) { uint32 mapPlane = Min_uint32 (plane, fGainMap->Planes () - 1); for (int32 row = overlap.t; row < overlap.b; row += fAreaSpec.RowPitch ()) { real32 *dPtr = buffer.DirtyPixel_real32 (row, overlap.l, plane); dng_gain_map_interpolator interp (*fGainMap, imageBounds, row, overlap.l, mapPlane); for (uint32 col = 0; col < cols; col += colPitch) { real32 gain = interp.Interpolate (); dPtr [col] = Min_real32 (dPtr [col] * gain, 1.0f); for (uint32 j = 0; j < colPitch; j++) { interp.Increment (); } } } } } }
void dng_opcode_ScalePerColumn::ProcessArea (dng_negative & /* negative */, uint32 /* threadIndex */, dng_pixel_buffer &buffer, const dng_rect &dstArea, const dng_rect & /* imageBounds */) { dng_rect overlap = fAreaSpec.Overlap (dstArea); if (overlap.NotEmpty ()) { uint32 rows = (overlap.W () + fAreaSpec.RowPitch () - 1) / fAreaSpec.RowPitch (); int32 rowStep = buffer.RowStep () * fAreaSpec.RowPitch (); for (uint32 plane = fAreaSpec.Plane (); plane < fAreaSpec.Plane () + fAreaSpec.Planes () && plane < buffer.Planes (); plane++) { const real32 *table = fTable->Buffer_real32 () + ((overlap.l - fAreaSpec.Area ().l) / fAreaSpec.ColPitch ()); for (int32 col = overlap.l; col < overlap.r; col += fAreaSpec.ColPitch ()) { real32 colScale = *(table++); real32 *dPtr = buffer.DirtyPixel_real32 (overlap.t, col, plane); for (uint32 row = 0; row < rows; row++) { real32 x = dPtr [0]; real32 y = x * colScale; dPtr [0] = Min_real32 (y, 1.0f); dPtr += rowStep; } } } } }
void dng_opcode_DeltaPerRow::ProcessArea (dng_negative & /* negative */, uint32 /* threadIndex */, dng_pixel_buffer &buffer, const dng_rect &dstArea, const dng_rect & /* imageBounds */) { dng_rect overlap = fAreaSpec.Overlap (dstArea); if (overlap.NotEmpty ()) { uint32 cols = overlap.W (); uint32 colPitch = fAreaSpec.ColPitch (); for (uint32 plane = fAreaSpec.Plane (); plane < fAreaSpec.Plane () + fAreaSpec.Planes () && plane < buffer.Planes (); plane++) { const real32 *table = fTable->Buffer_real32 () + ((overlap.t - fAreaSpec.Area ().t) / fAreaSpec.RowPitch ()); for (int32 row = overlap.t; row < overlap.b; row += fAreaSpec.RowPitch ()) { real32 rowDelta = *(table++) * fScale; real32 *dPtr = buffer.DirtyPixel_real32 (row, overlap.l, plane); for (uint32 col = 0; col < cols; col += colPitch) { real32 x = dPtr [col]; real32 y = x + rowDelta; dPtr [col] = Pin_real32 (0.0f, y, 1.0f); } } } } }
void dng_image::Put (const dng_pixel_buffer &buffer) { // Move the overlapping pixels. dng_rect overlap = buffer.fArea & fBounds; if (overlap.NotEmpty ()) { dng_pixel_buffer temp (buffer); temp.fArea = overlap; temp.fData = (void *) buffer.ConstPixel (overlap.t, overlap.l, buffer.fPlane); // Move the overlapping planes. if (temp.fPlane < Planes ()) { temp.fPlanes = Min_uint32 (temp.fPlanes, Planes () - temp.fPlane); DoPut (temp); } } }
void dng_image::DoGet (dng_pixel_buffer &buffer) const { dng_rect tile; dng_tile_iterator iter (*this, buffer.fArea); while (iter.GetOneTile (tile)) { dng_const_tile_buffer tileBuffer (*this, tile); buffer.CopyArea (tileBuffer, tile, buffer.fPlane, buffer.fPlanes); } }
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::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::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_opcode_MapPolynomial::ProcessArea (dng_negative & /* negative */, uint32 /* threadIndex */, dng_pixel_buffer &buffer, const dng_rect &dstArea, const dng_rect & /* imageBounds */) { dng_rect overlap = fAreaSpec.Overlap (dstArea); if (overlap.NotEmpty ()) { uint32 cols = overlap.W (); uint32 colPitch = fAreaSpec.ColPitch (); for (uint32 plane = fAreaSpec.Plane (); plane < fAreaSpec.Plane () + fAreaSpec.Planes () && plane < buffer.Planes (); plane++) { for (int32 row = overlap.t; row < overlap.b; row += fAreaSpec.RowPitch ()) { real32 *dPtr = buffer.DirtyPixel_real32 (row, overlap.l, plane); switch (fDegree) { case 0: { real32 y = Pin_real32 (0.0f, fCoefficient32 [0], 1.0f); for (uint32 col = 0; col < cols; col += colPitch) { dPtr [col] = y; } break; } case 1: { real32 c0 = fCoefficient32 [0]; real32 c1 = fCoefficient32 [1]; if (c0 == 0.0f) { if (c1 > 0.0f) { for (uint32 col = 0; col < cols; col += colPitch) { real32 x = dPtr [col]; real32 y = c1 * x; dPtr [col] = Min_real32 (y, 1.0f); } } else { for (uint32 col = 0; col < cols; col += colPitch) { dPtr [col] = 0.0f; } } } else { for (uint32 col = 0; col < cols; col += colPitch) { real32 x = dPtr [col]; real32 y = c0 + c1 * x; dPtr [col] = Pin_real32 (0.0f, y, 1.0f); } } break; } case 2: { for (uint32 col = 0; col < cols; col += colPitch) { real32 x = dPtr [col]; real32 y = fCoefficient32 [0] + x * (fCoefficient32 [1] + x * (fCoefficient32 [2])); dPtr [col] = Pin_real32 (0.0f, y, 1.0f); } break; } case 3: { for (uint32 col = 0; col < cols; col += colPitch) { real32 x = dPtr [col]; real32 y = fCoefficient32 [0] + x * (fCoefficient32 [1] + x * (fCoefficient32 [2] + x * (fCoefficient32 [3]))); dPtr [col] = Pin_real32 (0.0f, y, 1.0f); } break; } case 4: { for (uint32 col = 0; col < cols; col += colPitch) { real32 x = dPtr [col]; real32 y = fCoefficient32 [0] + x * (fCoefficient32 [1] + x * (fCoefficient32 [2] + x * (fCoefficient32 [3] + x * (fCoefficient32 [4])))); dPtr [col] = Pin_real32 (0.0f, y, 1.0f); } break; } default: { for (uint32 col = 0; col < cols; col += colPitch) { real32 x = dPtr [col]; real32 y = fCoefficient32 [0]; real32 xx = x; for (uint32 j = 1; j <= fDegree; j++) { y += fCoefficient32 [j] * xx; xx *= x; } dPtr [col] = Pin_real32 (0.0f, y, 1.0f); } break; } } } } } }