merge with dev

This commit is contained in:
Desmis
2019-06-26 07:37:29 +02:00
18 changed files with 883 additions and 728 deletions

View File

@@ -932,542 +932,6 @@ void RawImageSource::convertColorSpace(Imagefloat* image, const ColorManagementP
colorSpaceConversion(image, cmp, wb, pre_mul, embProfile, camProfile, imatrices.xyz_cam, (static_cast<const FramesData*>(getMetaData()))->getCamera());
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
/* interpolateBadPixelsBayer: correct raw pixels looking at the bitmap
* takes into consideration if there are multiple bad pixels in the neighbourhood
*/
int RawImageSource::interpolateBadPixelsBayer(PixelsMap &bitmapBads, array2D<float> &rawData)
{
static const float eps = 1.f;
int counter = 0;
#ifdef _OPENMP
#pragma omp parallel for reduction(+:counter) schedule(dynamic,16)
#endif
for (int row = 2; row < H - 2; row++) {
for (int col = 2; col < W - 2; col++) {
int sk = bitmapBads.skipIfZero(col, row); //optimization for a stripe all zero
if (sk) {
col += sk - 1; //-1 is because of col++ in cycle
continue;
}
if (!bitmapBads.get(col, row)) {
continue;
}
float wtdsum = 0.f, norm = 0.f;
// diagonal interpolation
if (FC(row, col) == 1) {
// green channel. We can use closer pixels than for red or blue channel. Distance to centre pixel is sqrt(2) => weighting is 0.70710678
// For green channel following pixels will be used for interpolation. Pixel to be interpolated is in centre.
// 1 means that pixel is used in this step, if itself and his counterpart are not marked bad
// 0 0 0 0 0
// 0 1 0 1 0
// 0 0 0 0 0
// 0 1 0 1 0
// 0 0 0 0 0
for (int dx = -1; dx <= 1; dx += 2) {
if (bitmapBads.get(col + dx, row - 1) || bitmapBads.get(col - dx, row + 1)) {
continue;
}
float dirwt = 0.70710678f / (fabsf(rawData[row - 1][col + dx] - rawData[row + 1][col - dx]) + eps);
wtdsum += dirwt * (rawData[row - 1][col + dx] + rawData[row + 1][col - dx]);
norm += dirwt;
}
} else {
// red and blue channel. Distance to centre pixel is sqrt(8) => weighting is 0.35355339
// For red and blue channel following pixels will be used for interpolation. Pixel to be interpolated is in centre.
// 1 means that pixel is used in this step, if itself and his counterpart are not marked bad
// 1 0 0 0 1
// 0 0 0 0 0
// 0 0 0 0 0
// 0 0 0 0 0
// 1 0 0 0 1
for (int dx = -2; dx <= 2; dx += 4) {
if (bitmapBads.get(col + dx, row - 2) || bitmapBads.get(col - dx, row + 2)) {
continue;
}
float dirwt = 0.35355339f / (fabsf(rawData[row - 2][col + dx] - rawData[row + 2][col - dx]) + eps);
wtdsum += dirwt * (rawData[row - 2][col + dx] + rawData[row + 2][col - dx]);
norm += dirwt;
}
}
// channel independent. Distance to centre pixel is 2 => weighting is 0.5
// Additionally for all channel following pixels will be used for interpolation. Pixel to be interpolated is in centre.
// 1 means that pixel is used in this step, if itself and his counterpart are not marked bad
// 0 0 1 0 0
// 0 0 0 0 0
// 1 0 0 0 1
// 0 0 0 0 0
// 0 0 1 0 0
// horizontal interpolation
if (!(bitmapBads.get(col - 2, row) || bitmapBads.get(col + 2, row))) {
float dirwt = 0.5f / (fabsf(rawData[row][col - 2] - rawData[row][col + 2]) + eps);
wtdsum += dirwt * (rawData[row][col - 2] + rawData[row][col + 2]);
norm += dirwt;
}
// vertical interpolation
if (!(bitmapBads.get(col, row - 2) || bitmapBads.get(col, row + 2))) {
float dirwt = 0.5f / (fabsf(rawData[row - 2][col] - rawData[row + 2][col]) + eps);
wtdsum += dirwt * (rawData[row - 2][col] + rawData[row + 2][col]);
norm += dirwt;
}
if (LIKELY(norm > 0.f)) { // This means, we found at least one pair of valid pixels in the steps above, likelihood of this case is about 99.999%
rawData[row][col] = wtdsum / (2.f * norm); //gradient weighted average, Factor of 2.f is an optimization to avoid multiplications in former steps
counter++;
} else { //backup plan -- simple average. Same method for all channels. We could improve this, but it's really unlikely that this case happens
int tot = 0;
float sum = 0;
for (int dy = -2; dy <= 2; dy += 2) {
for (int dx = -2; dx <= 2; dx += 2) {
if (bitmapBads.get(col + dx, row + dy)) {
continue;
}
sum += rawData[row + dy][col + dx];
tot++;
}
}
if (tot > 0) {
rawData[row][col] = sum / tot;
counter ++;
}
}
}
}
return counter; // Number of interpolated pixels.
}
/* interpolateBadPixels3Colours: correct raw pixels looking at the bitmap
* takes into consideration if there are multiple bad pixels in the neighbourhood
*/
int RawImageSource::interpolateBadPixelsNColours(PixelsMap &bitmapBads, const int colours)
{
static const float eps = 1.f;
int counter = 0;
#ifdef _OPENMP
#pragma omp parallel for reduction(+:counter) schedule(dynamic,16)
#endif
for (int row = 2; row < H - 2; row++) {
for (int col = 2; col < W - 2; col++) {
int sk = bitmapBads.skipIfZero(col, row); //optimization for a stripe all zero
if (sk) {
col += sk - 1; //-1 is because of col++ in cycle
continue;
}
if (!bitmapBads.get(col, row)) {
continue;
}
float wtdsum[colours], norm[colours];
for (int i = 0; i < colours; ++i) {
wtdsum[i] = norm[i] = 0.f;
}
// diagonal interpolation
for (int dx = -1; dx <= 1; dx += 2) {
if (bitmapBads.get(col + dx, row - 1) || bitmapBads.get(col - dx, row + 1)) {
continue;
}
for (int c = 0; c < colours; c++) {
float dirwt = 0.70710678f / (fabsf(rawData[row - 1][(col + dx) * colours + c] - rawData[row + 1][(col - dx) * colours + c]) + eps);
wtdsum[c] += dirwt * (rawData[row - 1][(col + dx) * colours + c] + rawData[row + 1][(col - dx) * colours + c]);
norm[c] += dirwt;
}
}
// horizontal interpolation
if (!(bitmapBads.get(col - 1, row) || bitmapBads.get(col + 1, row))) {
for (int c = 0; c < colours; c++) {
float dirwt = 1.f / (fabsf(rawData[row][(col - 1) * colours + c] - rawData[row][(col + 1) * colours + c]) + eps);
wtdsum[c] += dirwt * (rawData[row][(col - 1) * colours + c] + rawData[row][(col + 1) * colours + c]);
norm[c] += dirwt;
}
}
// vertical interpolation
if (!(bitmapBads.get(col, row - 1) || bitmapBads.get(col, row + 1))) {
for (int c = 0; c < colours; c++) {
float dirwt = 1.f / (fabsf(rawData[row - 1][col * colours + c] - rawData[row + 1][col * colours + c]) + eps);
wtdsum[c] += dirwt * (rawData[row - 1][col * colours + c] + rawData[row + 1][col * colours + c]);
norm[c] += dirwt;
}
}
if (LIKELY(norm[0] > 0.f)) { // This means, we found at least one pair of valid pixels in the steps above, likelihood of this case is about 99.999%
for (int c = 0; c < colours; c++) {
rawData[row][col * colours + c] = wtdsum[c] / (2.f * norm[c]); //gradient weighted average, Factor of 2.f is an optimization to avoid multiplications in former steps
}
counter++;
} else { //backup plan -- simple average. Same method for all channels. We could improve this, but it's really unlikely that this case happens
int tot = 0;
float sum[colours];
for (int i = 0; i < colours; ++i) {
sum[i] = 0.f;
}
for (int dy = -2; dy <= 2; dy += 2) {
for (int dx = -2; dx <= 2; dx += 2) {
if (bitmapBads.get(col + dx, row + dy)) {
continue;
}
for (int c = 0; c < colours; c++) {
sum[c] += rawData[row + dy][(col + dx) * colours + c];
}
tot++;
}
}
if (tot > 0) {
for (int c = 0; c < colours; c++) {
rawData[row][col * colours + c] = sum[c] / tot;
}
counter ++;
}
}
}
}
return counter; // Number of interpolated pixels.
}
/* interpolateBadPixelsXtrans: correct raw pixels looking at the bitmap
* takes into consideration if there are multiple bad pixels in the neighbourhood
*/
int RawImageSource::interpolateBadPixelsXtrans(PixelsMap &bitmapBads)
{
static const float eps = 1.f;
int counter = 0;
#ifdef _OPENMP
#pragma omp parallel for reduction(+:counter) schedule(dynamic,16)
#endif
for (int row = 2; row < H - 2; row++) {
for (int col = 2; col < W - 2; col++) {
int skip = bitmapBads.skipIfZero(col, row); //optimization for a stripe all zero
if (skip) {
col += skip - 1; //-1 is because of col++ in cycle
continue;
}
if (!bitmapBads.get(col, row)) {
continue;
}
float wtdsum = 0.f, norm = 0.f;
unsigned int pixelColor = ri->XTRANSFC(row, col);
if (pixelColor == 1) {
// green channel. A green pixel can either be a solitary green pixel or a member of a 2x2 square of green pixels
if (ri->XTRANSFC(row, col - 1) == ri->XTRANSFC(row, col + 1)) {
// If left and right neighbour have same colour, then this is a solitary green pixel
// For these the following pixels will be used for interpolation. Pixel to be interpolated is in centre and marked with a P.
// Pairs of pixels used in this step are numbered. A pair will be used if none of the pixels of the pair is marked bad
// 0 means, the pixel has a different colour and will not be used
// 0 1 0 2 0
// 3 5 0 6 4
// 0 0 P 0 0
// 4 6 0 5 3
// 0 2 0 1 0
for (int dx = -1; dx <= 1; dx += 2) { // pixels marked 5 or 6 in above example. Distance to P is sqrt(2) => weighting is 0.70710678f
if (bitmapBads.get(col + dx, row - 1) || bitmapBads.get(col - dx, row + 1)) {
continue;
}
float dirwt = 0.70710678f / (fabsf(rawData[row - 1][col + dx] - rawData[row + 1][col - dx]) + eps);
wtdsum += dirwt * (rawData[row - 1][col + dx] + rawData[row + 1][col - dx]);
norm += dirwt;
}
for (int dx = -1; dx <= 1; dx += 2) { // pixels marked 1 or 2 on above example. Distance to P is sqrt(5) => weighting is 0.44721359f
if (bitmapBads.get(col + dx, row - 2) || bitmapBads.get(col - dx, row + 2)) {
continue;
}
float dirwt = 0.44721359f / (fabsf(rawData[row - 2][col + dx] - rawData[row + 2][col - dx]) + eps);
wtdsum += dirwt * (rawData[row - 2][col + dx] + rawData[row + 2][col - dx]);
norm += dirwt;
}
for (int dx = -2; dx <= 2; dx += 4) { // pixels marked 3 or 4 on above example. Distance to P is sqrt(5) => weighting is 0.44721359f
if (bitmapBads.get(col + dx, row - 1) || bitmapBads.get(col - dx, row + 1)) {
continue;
}
float dirwt = 0.44721359f / (fabsf(rawData[row - 1][col + dx] - rawData[row + 1][col - dx]) + eps);
wtdsum += dirwt * (rawData[row - 1][col + dx] + rawData[row + 1][col - dx]);
norm += dirwt;
}
} else {
// this is a member of a 2x2 square of green pixels
// For these the following pixels will be used for interpolation. Pixel to be interpolated is at position P in the example.
// Pairs of pixels used in this step are numbered. A pair will be used if none of the pixels of the pair is marked bad
// 0 means, the pixel has a different colour and will not be used
// 1 0 0 3
// 0 P 2 0
// 0 2 1 0
// 3 0 0 0
// pixels marked 1 in above example. Distance to P is sqrt(2) => weighting is 0.70710678f
int offset1 = ri->XTRANSFC(row - 1, col - 1) == ri->XTRANSFC(row + 1, col + 1) ? 1 : -1;
if (!(bitmapBads.get(col - offset1, row - 1) || bitmapBads.get(col + offset1, row + 1))) {
float dirwt = 0.70710678f / (fabsf(rawData[row - 1][col - offset1] - rawData[row + 1][col + offset1]) + eps);
wtdsum += dirwt * (rawData[row - 1][col - offset1] + rawData[row + 1][col + offset1]);
norm += dirwt;
}
// pixels marked 2 in above example. Distance to P is 1 => weighting is 1.f
int offsety = (ri->XTRANSFC(row - 1, col) != 1 ? 1 : -1);
int offsetx = offset1 * offsety;
if (!(bitmapBads.get(col + offsetx, row) || bitmapBads.get(col, row + offsety))) {
float dirwt = 1.f / (fabsf(rawData[row][col + offsetx] - rawData[row + offsety][col]) + eps);
wtdsum += dirwt * (rawData[row][col + offsetx] + rawData[row + offsety][col]);
norm += dirwt;
}
int offsety2 = -offsety;
int offsetx2 = -offsetx;
offsetx *= 2;
offsety *= 2;
// pixels marked 3 in above example. Distance to P is sqrt(5) => weighting is 0.44721359f
if (!(bitmapBads.get(col + offsetx, row + offsety2) || bitmapBads.get(col + offsetx2, row + offsety))) {
float dirwt = 0.44721359f / (fabsf(rawData[row + offsety2][col + offsetx] - rawData[row + offsety][col + offsetx2]) + eps);
wtdsum += dirwt * (rawData[row + offsety2][col + offsetx] + rawData[row + offsety][col + offsetx2]);
norm += dirwt;
}
}
} else {
// red and blue channel.
// Each red or blue pixel has exactly one neighbour of same colour in distance 2 and four neighbours of same colour which can be reached by a move of a knight in chess.
// For the distance 2 pixel (marked with an X) we generate a virtual counterpart (marked with a V)
// For red and blue channel following pixels will be used for interpolation. Pixel to be interpolated is in centre and marked with a P.
// Pairs of pixels used in this step are numbered except for distance 2 pixels which are marked X and V. A pair will be used if none of the pixels of the pair is marked bad
// 0 1 0 0 0 0 0 X 0 0 remaining cases are symmetric
// 0 0 0 0 2 1 0 0 0 2
// X 0 P 0 V 0 0 P 0 0
// 0 0 0 0 1 0 0 0 0 0
// 0 2 0 0 0 0 2 V 1 0
// Find two knight moves landing on a pixel of same colour as the pixel to be interpolated.
// If we look at first and last row of 5x5 square, we will find exactly two knight pixels.
// Additionally we know that the column of this pixel has 1 or -1 horizontal distance to the centre pixel
// When we find a knight pixel, we get its counterpart, which has distance (+-3,+-3), where the signs of distance depend on the corner of the found knight pixel.
// These pixels are marked 1 or 2 in above examples. Distance to P is sqrt(5) => weighting is 0.44721359f
// The following loop simply scans the four possible places. To keep things simple, it does not stop after finding two knight pixels, because it will not find more than two
for (int d1 = -2, offsety = 3; d1 <= 2; d1 += 4, offsety -= 6) {
for (int d2 = -1, offsetx = 3; d2 < 1; d2 += 2, offsetx -= 6) {
if (ri->XTRANSFC(row + d1, col + d2) == pixelColor) {
if (!(bitmapBads.get(col + d2, row + d1) || bitmapBads.get(col + d2 + offsetx, row + d1 + offsety))) {
float dirwt = 0.44721359f / (fabsf(rawData[row + d1][col + d2] - rawData[row + d1 + offsety][col + d2 + offsetx]) + eps);
wtdsum += dirwt * (rawData[row + d1][col + d2] + rawData[row + d1 + offsety][col + d2 + offsetx]);
norm += dirwt;
}
}
}
}
// now scan for the pixel of same colour in distance 2 in each direction (marked with an X in above examples).
bool distance2PixelFound = false;
int dx, dy;
// check horizontal
for (dx = -2, dy = 0; dx <= 2 && !distance2PixelFound; dx += 4)
if (ri->XTRANSFC(row, col + dx) == pixelColor) {
distance2PixelFound = true;
break;
}
if (!distance2PixelFound)
// no distance 2 pixel on horizontal, check vertical
for (dx = 0, dy = -2; dy <= 2 && !distance2PixelFound; dy += 4)
if (ri->XTRANSFC(row + dy, col) == pixelColor) {
distance2PixelFound = true;
break;
}
// calculate the value of its virtual counterpart (marked with a V in above examples)
float virtualPixel;
if (dy == 0) {
virtualPixel = 0.5f * (rawData[row - 1][col - dx] + rawData[row + 1][col - dx]);
} else {
virtualPixel = 0.5f * (rawData[row - dy][col - 1] + rawData[row - dy][col + 1]);
}
// and weight as usual. Distance to P is 2 => weighting is 0.5f
float dirwt = 0.5f / (fabsf(virtualPixel - rawData[row + dy][col + dx]) + eps);
wtdsum += dirwt * (virtualPixel + rawData[row + dy][col + dx]);
norm += dirwt;
}
if (LIKELY(norm > 0.f)) { // This means, we found at least one pair of valid pixels in the steps above, likelihood of this case is about 99.999%
rawData[row][col] = wtdsum / (2.f * norm); //gradient weighted average, Factor of 2.f is an optimization to avoid multiplications in former steps
counter++;
}
}
}
return counter; // Number of interpolated pixels.
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
/* Search for hot or dead pixels in the image and update the map
* For each pixel compare its value to the average of similar colour surrounding
* (Taken from Emil Martinec idea)
* (Optimized by Ingo Weyrich 2013 and 2015)
*/
int RawImageSource::findHotDeadPixels( PixelsMap &bpMap, float thresh, bool findHotPixels, bool findDeadPixels )
{
float varthresh = (20.0 * (thresh / 100.0) + 1.0) / 24.f;
// allocate temporary buffer
float* cfablur;
cfablur = (float (*)) malloc(H * W * sizeof * cfablur);
// counter for dead or hot pixels
int counter = 0;
#ifdef _OPENMP
#pragma omp parallel
#endif
{
#ifdef _OPENMP
#pragma omp for schedule(dynamic,16) nowait
#endif
for (int i = 2; i < H - 2; i++) {
for (int j = 2; j < W - 2; j++) {
const float& temp = median(rawData[i - 2][j - 2], rawData[i - 2][j], rawData[i - 2][j + 2],
rawData[i][j - 2], rawData[i][j], rawData[i][j + 2],
rawData[i + 2][j - 2], rawData[i + 2][j], rawData[i + 2][j + 2]);
cfablur[i * W + j] = rawData[i][j] - temp;
}
}
// process borders. Former version calculated the median using mirrored border which does not make sense because the original pixel loses weight
// Setting the difference between pixel and median for border pixels to zero should do the job not worse then former version
#ifdef _OPENMP
#pragma omp single
#endif
{
for (int i = 0; i < 2; i++) {
for (int j = 0; j < W; j++) {
cfablur[i * W + j] = 0.f;
}
}
for (int i = 2; i < H - 2; i++) {
for (int j = 0; j < 2; j++) {
cfablur[i * W + j] = 0.f;
}
for (int j = W - 2; j < W; j++) {
cfablur[i * W + j] = 0.f;
}
}
for (int i = H - 2; i < H; i++) {
for (int j = 0; j < W; j++) {
cfablur[i * W + j] = 0.f;
}
}
}
#ifdef _OPENMP
#pragma omp barrier // barrier because of nowait clause above
#pragma omp for reduction(+:counter) schedule(dynamic,16)
#endif
//cfa pixel heat/death evaluation
for (int rr = 2; rr < H - 2; rr++) {
int rrmWpcc = rr * W + 2;
for (int cc = 2; cc < W - 2; cc++, rrmWpcc++) {
//evaluate pixel for heat/death
float pixdev = cfablur[rrmWpcc];
if (pixdev == 0.f) {
continue;
}
if ((!findDeadPixels) && pixdev < 0) {
continue;
}
if ((!findHotPixels) && pixdev > 0) {
continue;
}
pixdev = fabsf(pixdev);
float hfnbrave = -pixdev;
#ifdef __SSE2__
// sum up 5*4 = 20 values using SSE
// 10 fabs function calls and float 10 additions with SSE
vfloat sum = vabsf(LVFU(cfablur[(rr - 2) * W + cc - 2])) + vabsf(LVFU(cfablur[(rr - 1) * W + cc - 2]));
sum += vabsf(LVFU(cfablur[(rr) * W + cc - 2]));
sum += vabsf(LVFU(cfablur[(rr + 1) * W + cc - 2]));
sum += vabsf(LVFU(cfablur[(rr + 2) * W + cc - 2]));
// horizontally add the values and add the result to hfnbrave
hfnbrave += vhadd(sum);
// add remaining 5 values of last column
for (int mm = rr - 2; mm <= rr + 2; mm++) {
hfnbrave += fabsf(cfablur[mm * W + cc + 2]);
}
#else
// 25 fabs function calls and 25 float additions without SSE
for (int mm = rr - 2; mm <= rr + 2; mm++) {
for (int nn = cc - 2; nn <= cc + 2; nn++) {
hfnbrave += fabsf(cfablur[mm * W + nn]);
}
}
#endif
if (pixdev > varthresh * hfnbrave) {
// mark the pixel as "bad"
bpMap.set(cc, rr);
counter++;
}
}//end of pixel evaluation
}
}//end of parallel processing
free(cfablur);
return counter;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void RawImageSource::getFullSize(int& w, int& h, int tr)
{
@@ -1747,23 +1211,13 @@ void RawImageSource::preprocess(const RAWParams &raw, const LensProfParams &lens
printf("Subtracting Darkframe:%s\n", rid->get_filename().c_str());
}
PixelsMap *bitmapBads = nullptr;
std::unique_ptr<PixelsMap> bitmapBads;
int totBP = 0; // Hold count of bad pixels to correct
if (ri->zeroIsBad()) { // mark all pixels with value zero as bad, has to be called before FF and DF. dcraw sets this flag only for some cameras (mainly Panasonic and Leica)
bitmapBads = new PixelsMap(W, H);
#ifdef _OPENMP
#pragma omp parallel for reduction(+:totBP) schedule(dynamic,16)
#endif
for (int i = 0; i < H; i++)
for (int j = 0; j < W; j++) {
if (ri->data[i][j] == 0.f) {
bitmapBads->set(j, i);
totBP++;
}
}
bitmapBads.reset(new PixelsMap(W, H));
totBP = findZeroPixels(*(bitmapBads.get()));
if (settings->verbose) {
printf("%d pixels with value zero marked as bad pixels\n", totBP);
@@ -1830,7 +1284,7 @@ void RawImageSource::preprocess(const RAWParams &raw, const LensProfParams &lens
if (bp) {
if (!bitmapBads) {
bitmapBads = new PixelsMap(W, H);
bitmapBads.reset(new PixelsMap(W, H));
}
totBP += bitmapBads->set(*bp);
@@ -1851,7 +1305,7 @@ void RawImageSource::preprocess(const RAWParams &raw, const LensProfParams &lens
if (bp) {
if (!bitmapBads) {
bitmapBads = new PixelsMap(W, H);
bitmapBads.reset(new PixelsMap(W, H));
}
totBP += bitmapBads->set(*bp);
@@ -1928,10 +1382,10 @@ void RawImageSource::preprocess(const RAWParams &raw, const LensProfParams &lens
}
if (!bitmapBads) {
bitmapBads = new PixelsMap(W, H);
bitmapBads.reset(new PixelsMap(W, H));
}
int nFound = findHotDeadPixels(*bitmapBads, raw.hotdeadpix_thresh, raw.hotPixelFilter, raw.deadPixelFilter);
int nFound = findHotDeadPixels(*(bitmapBads.get()), raw.hotdeadpix_thresh, raw.hotPixelFilter, raw.deadPixelFilter );
totBP += nFound;
if (settings->verbose && nFound > 0) {
@@ -1943,10 +1397,10 @@ void RawImageSource::preprocess(const RAWParams &raw, const LensProfParams &lens
PDAFLinesFilter f(ri);
if (!bitmapBads) {
bitmapBads = new PixelsMap(W, H);
bitmapBads.reset(new PixelsMap(W, H));
}
int n = f.mark(rawData, *bitmapBads);
int n = f.mark(rawData, *(bitmapBads.get()));
totBP += n;
if (n > 0) {
@@ -2010,15 +1464,15 @@ void RawImageSource::preprocess(const RAWParams &raw, const LensProfParams &lens
if (ri->getSensorType() == ST_BAYER) {
if (numFrames == 4) {
for (int i = 0; i < 4; ++i) {
interpolateBadPixelsBayer(*bitmapBads, *rawDataFrames[i]);
interpolateBadPixelsBayer(*(bitmapBads.get()), *rawDataFrames[i]);
}
} else {
interpolateBadPixelsBayer(*bitmapBads, rawData);
interpolateBadPixelsBayer(*(bitmapBads.get()), rawData);
}
} else if (ri->getSensorType() == ST_FUJI_XTRANS) {
interpolateBadPixelsXtrans(*bitmapBads);
interpolateBadPixelsXtrans(*(bitmapBads.get()));
} else {
interpolateBadPixelsNColours(*bitmapBads, ri->get_colors());
interpolateBadPixelsNColours(*(bitmapBads.get()), ri->get_colors());
}
}
@@ -2072,10 +1526,6 @@ void RawImageSource::preprocess(const RAWParams &raw, const LensProfParams &lens
printf("Preprocessing: %d usec\n", t2.etime(t1));
}
if (bitmapBads) {
delete bitmapBads;
}
rawDirty = true;
return;
}