From 7a3942aaab964082b08f61210dd5c4d3075b02ff Mon Sep 17 00:00:00 2001 From: Andrey Skvortsov Date: Sat, 11 Sep 2010 23:05:36 -0700 Subject: [PATCH] Bilinear demosaic from dcraw + omp support. Faster then light! Great for previews. --- rtengine/rawimagesource.cc | 113 ++++++++++++++++++++++++++++++++++++- rtengine/rawimagesource.h | 5 +- rtengine/settings.h | 2 +- rtgui/preferences.cc | 7 ++- 4 files changed, 121 insertions(+), 6 deletions(-) diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index 903b1258d..0bf4d34ca 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -906,9 +906,11 @@ int RawImageSource::load (Glib::ustring fname) { vng4_demosaic (); else if (settings->demosaicMethod=="ahd") ahd_demosaic (); + else if (settings->demosaicMethod=="bilinear") + bilinear_demosaic(); //else if (settings->demosaicMethod=="ppg") // ppg_demosaic (); - else if (settings->demosaicMethod=="amaze") + else if (settings->demosaicMethod=="amaze") amaze_demosaic_RT ();//Emil's code for AMaZE else if (settings->demosaicMethod=="dcb") dcb_demosaic(settings->dcb_iterations, settings->dcb_enhance? 1:0); @@ -2339,13 +2341,14 @@ void RawImageSource::ppg_demosaic() free (image); } -void RawImageSource::border_interpolate(int border, ushort (*image)[4]) +void RawImageSource::border_interpolate(int border, ushort (*image)[4], int start, int end) { unsigned row, col, y, x, f, c, sum[8]; int width=W, height=H; int colors = 3; - for (row=0; row < height; row++) + if (end == 0 )end = H; + for (row=start; row < end; row++) for (col=0; col < width; col++) { if (col==border && row >= border && row < height-border) col = width-border; @@ -2363,6 +2366,110 @@ void RawImageSource::border_interpolate(int border, ushort (*image)[4]) } } +void RawImageSource::bilinear_interpolate_block(ushort (*image)[4], int start, int end) +{ + ushort (*pix); + int i, *ip, sum[4]; + int width=W; + int colors = 3; + + for (int row = start; row < end; row++) + for (int col=1; col < width-1; col++) { + pix = image[row*width+col]; + ip = blcode[row & 15][col & 15]; + memset (sum, 0, sizeof sum); + for (i=8; i--; ip+=3) + sum[ip[2]] += pix[ip[0]] << ip[1]; + for (i=colors; --i; ip+=2) + pix[ip[0]] = sum[ip[0]] * ip[1] >> 8; + } + + for (int i=start; idata[ii][jj]; + + //if (verbose) fprintf (stderr,_("Bilinear interpolation...\n")); + if (plistener) { + plistener->setProgressStr ("Demosaicing..."); + plistener->setProgress (0.0); + } + + for (row=0; row < 16; row++) + for (col=0; col < 16; col++) { + ip = blcode[row][col]; + memset (sum, 0, sizeof sum); + for (y=-1; y <= 1; y++) + for (x=-1; x <= 1; x++) { + shift = (y==0) + (x==0); + if (shift == 2) continue; + color = fc(row+y,col+x); + *ip++ = (width*y + x)*4 + color; + *ip++ = shift; + *ip++ = color; + sum[color] += 1 << shift; + } + FORCC + if (c != fc(row,col)) { + *ip++ = c; + *ip++ = 256 / sum[c]; + } + } + + red = new unsigned short*[H]; + green = new unsigned short*[H]; + blue = new unsigned short*[H]; + +#ifdef _OPENMP + #pragma omp parallel + { + int tid = omp_get_thread_num(); + int nthreads = omp_get_num_threads(); + int blk = W/nthreads; + + int start = 0; + if (tid == 0) start = 1; + if (tidsetProgress (1.0); + free (image); +} + /* Adaptive Homogeneity-Directed interpolation is based on the work of Keigo Hirakawa, Thomas Parks, and Paul Lee. diff --git a/rtengine/rawimagesource.h b/rtengine/rawimagesource.h index 61a0ee574..9ccb257ab 100644 --- a/rtengine/rawimagesource.h +++ b/rtengine/rawimagesource.h @@ -65,6 +65,7 @@ class RawImageSource : public ImageSource { char** needhr; // for color propagation int max[3]; double defGain; + int blcode[16][16][32]; bool full; Glib::ustring oldmethod; cmsHPROFILE camProfile; @@ -154,7 +155,9 @@ class RawImageSource : public ImageSource { void amaze_demosaic_RT ();//Emil's code for AMaZE void dcb_demosaic(int iterations, int dcb_enhance); void ahd_demosaic(); - void border_interpolate(int border, ushort (*image)[4]); + void bilinear_demosaic(); + void bilinear_interpolate_block(ushort (*image)[4], int start, int end); + void border_interpolate(int border, ushort (*image)[4], int start = 0, int end = 0); void dcb_initTileLimits(int &colMin, int &rowMin, int &colMax, int &rowMax, int x0, int y0, int border); void fill_raw( ushort (*cache )[4], int x0, int y0, ushort** rawData); void fill_border( ushort (*cache )[4], int border, int x0, int y0); diff --git a/rtengine/settings.h b/rtengine/settings.h index fe2fc8380..6ef87dbbf 100644 --- a/rtengine/settings.h +++ b/rtengine/settings.h @@ -25,7 +25,7 @@ namespace rtengine { class Settings { public: bool dualThreadEnabled; ///< If true, the image processing operations with utilize two processor cores (if possible) - std::string demosaicMethod; ///< The algorithm used for demosaicing. Can be "eahd", "hphd" or "vng4". + std::string demosaicMethod; ///< The algorithm used for demosaicing. Can be "eahd", "hphd", "ahd", "vng4", "amaze", "bilinear". int colorCorrectionSteps; ///< The number of color correction steps applied right after the demosaicing Glib::ustring iccDirectory; ///< The directory containing the possible output icc profiles int colorimetricIntent; ///< Colorimetric intent used at color space conversions diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index b3efff886..7a85010b2 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -264,9 +264,10 @@ Gtk::Widget* Preferences::getProcParamsPanel () { dmethod->append_text ("HPHD"); dmethod->append_text ("VNG-4"); //dmethod->append_text ("PPG"); - dmethod->append_text ("AMaZE");//Emil's code for AMaZE + dmethod->append_text ("AMaZE");//Emil's code for AMaZE dmethod->append_text ("DCB"); dmethod->append_text ("AHD"); + dmethod->append_text ("Bilinear"); Gtk::Label* cclab = Gtk::manage (new Gtk::Label (M("PREFERENCES_FALSECOLOR")+":")); ccSteps = Gtk::manage (new Gtk::SpinButton ()); ccSteps->set_digits (0); @@ -748,6 +749,8 @@ void Preferences::storePreferences () { moptions.rtSettings.demosaicMethod = "dcb"; else if (dmethod->get_active_row_number()==5) moptions.rtSettings.demosaicMethod = "ahd"; + else if (dmethod->get_active_row_number()==6) + moptions.rtSettings.demosaicMethod = "bilinear"; moptions.rtSettings.dcb_iterations=(int)dcbIterations->get_value(); moptions.rtSettings.dcb_enhance=dcbEnhance->get_active(); moptions.rtSettings.ca_autocorrect=caAutoCorrect->get_active();//Emil's CA correction @@ -848,6 +851,8 @@ void Preferences::fillPreferences () { dmethod->set_active (4); else if (moptions.rtSettings.demosaicMethod=="ahd") dmethod->set_active (5); + else if (moptions.rtSettings.demosaicMethod=="bilinear") + dmethod->set_active (6); dcbEnhance->set_active(moptions.rtSettings.dcb_enhance); dcbIterations->set_value(moptions.rtSettings.dcb_iterations); dcbEnhance->set_sensitive(moptions.rtSettings.demosaicMethod=="dcb");