From 61ad17013c74cd36cfec7ddee80a9ae77784456e Mon Sep 17 00:00:00 2001 From: janrinze Date: Mon, 13 Dec 2010 20:37:28 +0100 Subject: [PATCH] improve zoomed preview with gamma correction on non raw files --- rtengine/rawimagesource.cc | 69 +++++++++++---------- rtengine/stdimagesource.cc | 123 +++++++++++++++++-------------------- 2 files changed, 92 insertions(+), 100 deletions(-) diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index dc369c5e8..8e735296e 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -30,7 +30,6 @@ #include - #ifdef _OPENMP #include #endif @@ -235,69 +234,71 @@ void RawImageSource::getImage (ColorTemp ctemp, int tran, Image16* image, Previe imwidth = maximwidth; if (!fuji && imheight>maximheight) imheight = maximheight; + int maxx=this->W,maxy=this->H,skip=pp.skip; + + if (sx1+skip*imwidth>maxx) imwidth --; // very hard to fix this situation without an 'if' in the loop. + double area=skip*skip; + rm/=area; + gm/=area; + bm/=area; + #ifdef _OPENMP #pragma omp parallel { #endif // render the requested image part - unsigned short* red = new unsigned short[imwidth]; - unsigned short* grn = new unsigned short[imwidth]; - unsigned short* blue = new unsigned short[imwidth]; + unsigned short* line_red = new unsigned short [imwidth]; + unsigned short* line_grn = new unsigned short [imwidth]; + unsigned short* line_blue = new unsigned short [imwidth]; + - int maxx=this->W,maxy=this->H; #ifdef _OPENMP #pragma omp for #endif - for (int ix=0; ixisBayer()) { - for (int j=0,jx=sx1; jmaxy-skip) i=maxy-skip; // avoid trouble + if (ri->isBayer()) { + for (int j=0,jx=sx1; jred[i+m][jx+n]; - gtot += this->green[i+m][jx+n]; - btot += this->blue[i+m][jx+n]; - boxarea++; + rtot += red[i+m][jx+n]; + gtot += green[i+m][jx+n]; + btot += blue[i+m][jx+n]; } - if (boxarea<1) boxarea=1; - red[j] = CLIP(rm*rtot/boxarea); - grn[j] = CLIP(gm*gtot/boxarea); - blue[j] = CLIP(bm*btot/boxarea); + line_red[j] = CLIP(rm*rtot); + line_grn[j] = CLIP(gm*gtot); + line_blue[j] = CLIP(bm*btot); } } else { - for (int j=0,jx=sx1; jwidth and image->height int imwidth = (sx2 - sx1) / pp.skip + ((sx2 - sx1) % pp.skip > 0); int imheight = (sy2 - sy1) / pp.skip + ((sy2 - sy1) % pp.skip > 0); - - int istart = sy1, iend = sy2, ix = 0; - if (first) { - iend = istart; - while (iend<(sy1+sy2)/2) { - iend+=pp.skip; - } - } - else { - while (istart<(sy1+sy2)/2) { - ix++; - istart+=pp.skip; - } - } - +*/ + int imwidth=image->width,imheight=image->height; + int istart = sy1; + int maxx=img->width,maxy=img->height; int mtran = tran; int skip = pp.skip; + if ((sx1 + skip*imwidth)>maxx) imwidth -- ; // we have a boundary condition that can cause errors + + // improve speed by integrating the area division into the multipliers + // switched to using ints for the red/green/blue channel buffer. + // Incidentally this improves accuracy too. + double area=skip*skip; + rm/=area; + gm/=area; + bm/=area; + #ifdef _OPENMP #pragma omp parallel { #endif - unsigned short* red = new unsigned short[imwidth]; - unsigned short* grn = new unsigned short[imwidth]; - unsigned short* blue = new unsigned short[imwidth]; - - int maxx=img->width,maxy=img->height; - int b_ix=ix; + int *line_red = new int[imwidth]; + int *line_green = new int[imwidth]; + int *line_blue = new int[imwidth]; + #ifdef _OPENMP -#pragma omp for private(ix) +#pragma omp for #endif - for (int i=istart; iwidth){ - for (int j=0,jx=sx1; jmaxy-skip) i=maxy-skip; // avoid trouble + for (int j=0,jx=sx1; jr[i+m][jx+n]; - gtot += img->g[i+m][jx+n]; - btot += img->b[i+m][jx+n]; - boxarea++; + + for (int m=0; mr[i+m][jx+n]); + gtot += CurveFactory::igamma_srgb(img->g[i+m][jx+n]); + btot += CurveFactory::igamma_srgb(img->b[i+m][jx+n]); } - if (boxarea<1) boxarea=1; - red[j] = round(rtot/boxarea); - grn[j] = round(gtot/boxarea); - blue[j] = round(btot/boxarea); - } + line_red[j] = rtot; + line_green[j] = gtot; + line_blue[j] = btot; + } + +// covert back to gamma and clip +#define GCLIP( x ) CurveFactory::gamma_srgb(CLIP(x)) + // if (hrp.enabled) // hlRecovery (red, grn, blue, i, sx1, sx2, pp.skip); if ((mtran & TR_ROT) == TR_R180) for (int j=0; jr[imheight-1-ix][imwidth-1-j] = (int)CLIP(rm*red[j]); - image->g[imheight-1-ix][imwidth-1-j] = (int)CLIP(gm*grn[j]); - image->b[imheight-1-ix][imwidth-1-j] = (int)CLIP(bm*blue[j]); + image->r[imheight-1-ix][imwidth-1-j] = (int)GCLIP(rm*line_red[j]); + image->g[imheight-1-ix][imwidth-1-j] = (int)GCLIP(gm*line_green[j]); + image->b[imheight-1-ix][imwidth-1-j] = (int)GCLIP(bm*line_blue[j]); } else if ((mtran & TR_ROT) == TR_R90) for (int j=0,jx=sx1; jr[j][imheight-1-ix] = (int)CLIP(rm*red[j]); - image->g[j][imheight-1-ix] = (int)CLIP(gm*grn[j]); - image->b[j][imheight-1-ix] = (int)CLIP(bm*blue[j]); + image->r[j][imheight-1-ix] = (int)GCLIP(rm*line_red[j]); + image->g[j][imheight-1-ix] = (int)GCLIP(gm*line_green[j]); + image->b[j][imheight-1-ix] = (int)GCLIP(bm*line_blue[j]); } else if ((mtran & TR_ROT) == TR_R270) for (int j=0,jx=sx1; jr[imwidth-1-j][ix] = (int)CLIP(rm*red[j]); - image->g[imwidth-1-j][ix] = (int)CLIP(gm*grn[j]); - image->b[imwidth-1-j][ix] = (int)CLIP(bm*blue[j]); + image->r[imwidth-1-j][ix] = (int)GCLIP(rm*line_red[j]); + image->g[imwidth-1-j][ix] = (int)GCLIP(gm*line_green[j]); + image->b[imwidth-1-j][ix] = (int)GCLIP(bm*line_blue[j]); } else { for (int j=0,jx=sx1; jr[ix][j] = (int)CLIP(rm*red[j]); - image->g[ix][j] = (int)CLIP(gm*grn[j]); - image->b[ix][j] = (int)CLIP(bm*blue[j]); + image->r[ix][j] = (int)GCLIP(rm*line_red[j]); + image->g[ix][j] = (int)GCLIP(gm*line_green[j]); + image->b[ix][j] = (int)GCLIP(bm*line_blue[j]); } } } - - delete [] red; - delete [] grn; - delete [] blue; +#undef GCLIP + delete [] line_red; + delete [] line_green; + delete [] line_blue; #ifdef _OPENMP } #endif @@ -257,16 +256,8 @@ void StdImageSource::getImage (ColorTemp ctemp, int tran, Image16* image, Previe // if (hrp.enabled==true && hrmap[0]==NULL) // updateHLRecoveryMap (); - if (settings->dualThreadEnabled) { - Glib::Thread *thread1 = Glib::Thread::create(sigc::bind(sigc::mem_fun(*this, &StdImageSource::getImage_), ctemp, tran, image, pp, true, hrp), 0, true, true, Glib::THREAD_PRIORITY_NORMAL); - Glib::Thread *thread2 = Glib::Thread::create(sigc::bind(sigc::mem_fun(*this, &StdImageSource::getImage_), ctemp, tran, image, pp, false, hrp), 0, true, true, Glib::THREAD_PRIORITY_NORMAL); - thread1->join (); - thread2->join (); - } - else { - getImage_ (ctemp, tran, image, pp, true, hrp); - getImage_ (ctemp, tran, image, pp, false, hrp); - } + // the code will use OpenMP as of now. + getImage_ (ctemp, tran, image, pp, true, hrp); colorSpaceConversion (image, cmp, embProfile);