void NRFilter::filterImage() { DColor col; int progress; int width = m_orgImage.width(); int height = m_orgImage.height(); float clip = m_orgImage.sixteenBit() ? 65535.0 : 255.0; // Allocate buffers. for (int c = 0; c < 3; ++c) { d->fimg[c] = new float[width * height]; } d->buffer[1] = new float[width * height]; d->buffer[2] = new float[width * height]; // Read the full image and convert pixel values to float [0,1]. int j = 0; for (int y = 0; runningFlag() && (y < height); ++y) { for (int x = 0; runningFlag() && (x < width); ++x) { col = m_orgImage.getPixelColor(x, y); d->fimg[0][j] = col.red() / clip; d->fimg[1][j] = col.green() / clip; d->fimg[2][j] = col.blue() / clip; ++j; } } postProgress(10); // do colour model conversion sRGB[0,1] -> YCrCb. if (runningFlag()) { srgb2ycbcr(d->fimg, width * height); } postProgress(20); // denoise the channels individually for (int c = 0; runningFlag() && (c < 3); ++c) { d->buffer[0] = d->fimg[c]; if (d->settings.thresholds[c] > 0.0) { waveletDenoise(d->buffer, width, height, d->settings.thresholds[c], d->settings.softness[c]); progress = (int)(30.0 + ((double)c * 60.0) / 4); if (progress % 5 == 0) { postProgress(progress); } } } // Retransform the image data to sRGB[0,1]. if (runningFlag()) { ycbcr2srgb(d->fimg, width * height); } postProgress(80); // clip the values for (int c = 0; runningFlag() && (c < 3); ++c) { for (int i = 0; i < width * height; ++i) { d->fimg[c][i] = qBound(0.0F, d->fimg[c][i] * clip, clip); } } postProgress(90); // Write back the full image and convert pixel values from float [0,1]. j = 0; for (int y = 0; runningFlag() && (y < height); ++y) { for (int x = 0; x < width; ++x) { col.setRed((int)(d->fimg[0][j] + 0.5)); col.setGreen((int)(d->fimg[1][j] + 0.5)); col.setBlue((int)(d->fimg[2][j] + 0.5)); col.setAlpha(m_orgImage.getPixelColor(x, y).alpha()); ++j; m_destImage.setPixelColor(x, y, col); } } postProgress(100); // Free buffers. for (int c = 0; c < 3; ++c) { delete [] d->fimg[c]; } delete [] d->buffer[1]; delete [] d->buffer[2]; }