/* * This file is part of RawTherapee. * * Copyright (c) 2004-2010 Gabor Horvath * * RawTherapee is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * RawTherapee is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ #include #include #include "image8.h" #include "rtengine.h" using namespace rtengine; Image8::Image8 () { } Image8::Image8 (int w, int h) { allocate (w, h); } Image8::~Image8 () { } void Image8::getScanline (int row, unsigned char* buffer, int bps) { if (data==NULL) return; if (bps==8) memcpy (buffer, data + row*width*3, width*3); else if (bps==16) { unsigned short* sbuffer = (unsigned short*) buffer; for (int i=0, ix = row*width*3; i> 8; break; } default: // Other type are ignored, but could be implemented if necessary break; } } Image8* Image8::copy () { Image8* cp = new Image8 (width, height); copyData(cp); return cp; } void Image8::getStdImage (ColorTemp ctemp, int tran, Imagefloat* image, PreviewProps pp, bool first, procparams::ToneCurveParams hrp) { // compute channel multipliers double drm, dgm, dbm; ctemp.getMultipliers (drm, dgm, dbm); float rm=drm,gm=dgm,bm=dbm; rm = 1.0 / rm; gm = 1.0 / gm; bm = 1.0 / bm; float mul_lum = 0.299*rm + 0.587*gm + 0.114*bm; rm /= mul_lum; gm /= mul_lum; bm /= mul_lum; int sx1, sy1, sx2, sy2; transform (pp, tran, sx1, sy1, sx2, sy2); int imwidth=image->width; // Destination image int imheight=image->height; // Destination image if (((tran & TR_ROT) == TR_R90)||((tran & TR_ROT) == TR_R270)) { int swap = imwidth; imwidth=imheight; imheight=swap; } int maxx=width; // Source image int maxy=height; // Source image int mtran = tran & TR_ROT; 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. float area=skip*skip; float rm2=rm; float gm2=gm; float bm2=bm; rm/=area; gm/=area; bm/=area; #define GCLIP( x ) Color::gamma_srgb(CLIP(x)) #ifdef _OPENMP #pragma omp parallel { #endif AlignedBuffer abR(imwidth); AlignedBuffer abG(imwidth); AlignedBuffer abB(imwidth); float *lineR = abR.data; float *lineG = abG.data; float *lineB = abB.data; #ifdef _OPENMP #pragma omp for #endif // Iterating all the rows of the destination image for (int iy=0; iy=maxy) continue; for (int dst_x=0,src_x=sx1; dst_x=maxx) continue; convertTo(r(src_y, src_x), r_); convertTo(g(src_y, src_x), g_); convertTo(b(src_y, src_x), b_); lineR[dst_x] = CLIP(rm2*r_); lineG[dst_x] = CLIP(gm2*g_); lineB[dst_x] = CLIP(bm2*b_); } } else { // source image, first line of the current destination row int src_y=sy1+skip*iy; if (src_y>=maxy) continue; for (int dst_x=0,src_x=sx1; dst_x=maxx) continue; int src_sub_width = MIN(maxx-src_x, skip); int src_sub_height = MIN(maxy-src_y, skip); float rtot,gtot,btot; // RGB accumulators rtot=gtot=btot=0.; for (int src_sub_y=0; src_sub_yr(iy, dst_x) = lineR[dst_x]; image->g(iy, dst_x) = lineG[dst_x]; image->b(iy, dst_x) = lineB[dst_x]; } else if (mtran == TR_R180) for (int dst_x=0; dst_xr(imheight-1-iy, imwidth-1-dst_x) = lineR[dst_x]; image->g(imheight-1-iy, imwidth-1-dst_x) = lineG[dst_x]; image->b(imheight-1-iy, imwidth-1-dst_x) = lineB[dst_x]; } else if (mtran == TR_R90) for (int dst_x=0,src_x=sx1; dst_xr(dst_x, imheight-1-iy) = lineR[dst_x]; image->g(dst_x, imheight-1-iy) = lineG[dst_x]; image->b(dst_x, imheight-1-iy) = lineB[dst_x]; } else if (mtran == TR_R270) for (int dst_x=0,src_x=sx1; dst_xr(imwidth-1-dst_x, iy) = lineR[dst_x]; image->g(imwidth-1-dst_x, iy) = lineG[dst_x]; image->b(imwidth-1-dst_x, iy) = lineB[dst_x]; } } #ifdef _OPENMP } #endif #undef GCLIP }