Solving issue 1719: "RT copies second-last row and column into the last row and column in non-raw images".

This commit is contained in:
natureh 510
2013-03-04 22:58:46 +01:00
parent d649b9a8c0
commit 5cab1357f4
3 changed files with 242 additions and 105 deletions

View File

@@ -130,14 +130,15 @@ void Image16::getStdImage (ColorTemp ctemp, int tran, Imagefloat* image, Preview
transform (pp, tran, sx1, sy1, sx2, sy2); transform (pp, tran, sx1, sy1, sx2, sy2);
int imwidth=image->width,imheight=image->height; int imwidth=image->width; // Destination image
int imheight=image->height; // Destination image
if (((tran & TR_ROT) == TR_R90)||((tran & TR_ROT) == TR_R270)) { if (((tran & TR_ROT) == TR_R90)||((tran & TR_ROT) == TR_R270)) {
int swap = imwidth; int swap = imwidth;
imwidth=imheight; imwidth=imheight;
imheight=swap; imheight=swap;
} }
int istart = sy1; int maxx=width; // Source image
int maxx=width,maxy=height; int maxy=height; // Source image
int mtran = tran & TR_ROT; int mtran = tran & TR_ROT;
int skip = pp.skip; int skip = pp.skip;
@@ -147,6 +148,9 @@ void Image16::getStdImage (ColorTemp ctemp, int tran, Imagefloat* image, Preview
// switched to using ints for the red/green/blue channel buffer. // switched to using ints for the red/green/blue channel buffer.
// Incidentally this improves accuracy too. // Incidentally this improves accuracy too.
float area=skip*skip; float area=skip*skip;
float rm2=rm;
float gm2=gm;
float bm2=bm;
rm/=area; rm/=area;
gm/=area; gm/=area;
bm/=area; bm/=area;
@@ -167,49 +171,89 @@ void Image16::getStdImage (ColorTemp ctemp, int tran, Imagefloat* image, Preview
#ifdef _OPENMP #ifdef _OPENMP
#pragma omp for #pragma omp for
#endif #endif
for (int ix=0;ix<imheight;ix++) { // Iterating all the rows of the destination image
int i=istart+skip*ix;if (i>=maxy-skip) i=maxy-skip-1; // avoid trouble for (int iy=0; iy<imheight; iy++) {
for (int j=0,jx=sx1; j<imwidth; j++,jx+=skip) { if (skip==1) {
if (jx>=maxx-skip) jx=maxx-skip-1; // avoid trouble // special case (speedup for 1:1 scale)
// i: source image, first line of the current destination row
int src_y=sy1+iy;
float rtot,gtot,btot; // overflow security check, not sure that it's necessary
rtot=gtot=btot=0; if (src_y>=maxy)
continue;
for (int m=0; m<skip; m++) for (int dst_x=0,src_x=sx1; dst_x<imwidth; dst_x++,src_x++) {
for (int n=0; n<skip; n++) { // overflow security check, not sure that it's necessary
rtot += Color::igamma_srgb(r(i+m, jx+n)); if (src_x>=maxx)
gtot += Color::igamma_srgb(g(i+m, jx+n)); continue;
btot += Color::igamma_srgb(b(i+m, jx+n));
lineR[dst_x] = r(src_y, src_x);
lineG[dst_x] = g(src_y, src_x);
lineB[dst_x] = b(src_y, src_x);
}
}
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<imwidth; dst_x++,src_x+=skip) {
if (src_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_y<src_sub_height; src_sub_y++)
for (int src_sub_x=0; src_sub_x<src_sub_width; src_sub_x++) {
rtot += r(src_y+src_sub_y, src_x+src_sub_x);
gtot += g(src_y+src_sub_y, src_x+src_sub_x);
btot += b(src_y+src_sub_y, src_x+src_sub_x);
}
// convert back to gamma and clip
if (src_sub_width == skip && src_sub_height == skip) {
// Common case where the sub-region is complete
lineR[dst_x] = CLIP(rm*rtot);
lineG[dst_x] = CLIP(gm*gtot);
lineB[dst_x] = CLIP(bm*btot);
} }
// convert back to gamma and clip else {
lineR[j] = GCLIP(rm*rtot); // computing a special factor for this incomplete sub-region
lineG[j] = GCLIP(gm*gtot); float area = src_sub_width*src_sub_height;
lineB[j] = GCLIP(bm*btot); lineR[dst_x] = CLIP(rm2*rtot/area);
lineG[dst_x] = CLIP(gm2*gtot/area);
lineB[dst_x] = CLIP(bm2*btot/area);
}
}
} }
if (mtran == TR_NONE) if (mtran == TR_NONE)
for (int j=0,jx=sx1; j<imwidth; j++,jx+=skip) { for (int dst_x=0,src_x=sx1; dst_x<imwidth; dst_x++,src_x+=skip) {
image->r(ix, j) = lineR[j]; image->r(iy, dst_x) = lineR[dst_x];
image->g(ix, j) = lineG[j]; image->g(iy, dst_x) = lineG[dst_x];
image->b(ix, j) = lineB[j]; image->b(iy, dst_x) = lineB[dst_x];
} }
else if (mtran == TR_R180) else if (mtran == TR_R180)
for (int j=0; j<imwidth; j++) { for (int dst_x=0; dst_x<imwidth; dst_x++) {
image->r(imheight-1-ix, imwidth-1-j) = lineR[j]; image->r(imheight-1-iy, imwidth-1-dst_x) = lineR[dst_x];
image->g(imheight-1-ix, imwidth-1-j) = lineG[j]; image->g(imheight-1-iy, imwidth-1-dst_x) = lineG[dst_x];
image->b(imheight-1-ix, imwidth-1-j) = lineB[j]; image->b(imheight-1-iy, imwidth-1-dst_x) = lineB[dst_x];
} }
else if (mtran == TR_R90) else if (mtran == TR_R90)
for (int j=0,jx=sx1; j<imwidth; j++,jx+=skip) { for (int dst_x=0,src_x=sx1; dst_x<imwidth; dst_x++,src_x+=skip) {
image->r(j, imheight-1-ix) = lineR[j]; image->r(dst_x, imheight-1-iy) = lineR[dst_x];
image->g(j, imheight-1-ix) = lineG[j]; image->g(dst_x, imheight-1-iy) = lineG[dst_x];
image->b(j, imheight-1-ix) = lineB[j]; image->b(dst_x, imheight-1-iy) = lineB[dst_x];
} }
else if (mtran == TR_R270) else if (mtran == TR_R270)
for (int j=0,jx=sx1; j<imwidth; j++,jx+=skip) { for (int dst_x=0,src_x=sx1; dst_x<imwidth; dst_x++,src_x+=skip) {
image->r(imwidth-1-j, ix) = lineR[j]; image->r(imwidth-1-dst_x, iy) = lineR[dst_x];
image->g(imwidth-1-j, ix) = lineG[j]; image->g(imwidth-1-dst_x, iy) = lineG[dst_x];
image->b(imwidth-1-j, ix) = lineB[j]; image->b(imwidth-1-dst_x, iy) = lineB[dst_x];
} }
} }
#ifdef _OPENMP #ifdef _OPENMP

View File

@@ -99,14 +99,15 @@ void Image8::getStdImage (ColorTemp ctemp, int tran, Imagefloat* image, PreviewP
transform (pp, tran, sx1, sy1, sx2, sy2); transform (pp, tran, sx1, sy1, sx2, sy2);
int imwidth=image->width,imheight=image->height; int imwidth=image->width; // Destination image
int imheight=image->height; // Destination image
if (((tran & TR_ROT) == TR_R90)||((tran & TR_ROT) == TR_R270)) { if (((tran & TR_ROT) == TR_R90)||((tran & TR_ROT) == TR_R270)) {
int swap = imwidth; int swap = imwidth;
imwidth=imheight; imwidth=imheight;
imheight=swap; imheight=swap;
} }
int istart = sy1; int maxx=width; // Source image
int maxx=width,maxy=height; int maxy=height; // Source image
int mtran = tran & TR_ROT; int mtran = tran & TR_ROT;
int skip = pp.skip; int skip = pp.skip;
@@ -116,6 +117,9 @@ void Image8::getStdImage (ColorTemp ctemp, int tran, Imagefloat* image, PreviewP
// switched to using ints for the red/green/blue channel buffer. // switched to using ints for the red/green/blue channel buffer.
// Incidentally this improves accuracy too. // Incidentally this improves accuracy too.
float area=skip*skip; float area=skip*skip;
float rm2=rm;
float gm2=gm;
float bm2=bm;
rm/=area; rm/=area;
gm/=area; gm/=area;
bm/=area; bm/=area;
@@ -136,53 +140,98 @@ void Image8::getStdImage (ColorTemp ctemp, int tran, Imagefloat* image, PreviewP
#ifdef _OPENMP #ifdef _OPENMP
#pragma omp for #pragma omp for
#endif #endif
for (int ix=0;ix<imheight;ix++) { // Iterating all the rows of the destination image
int i=istart+skip*ix;if (i>=maxy-skip) i=maxy-skip-1; // avoid trouble for (int iy=0; iy<imheight; iy++) {
for (int j=0,jx=sx1; j<imwidth; j++,jx+=skip) { if (skip==1) {
if (jx>=maxx-skip) jx=maxx-skip-1; // avoid trouble // special case (speedup for 1:1 scale)
// i: source image, first line of the current destination row
int src_y=sy1+iy;
float rtot,gtot,btot; // overflow security check, not sure that it's necessary
rtot=gtot=btot=0; if (src_y>=maxy)
continue;
for (int m=0; m<skip; m++) for (int dst_x=0,src_x=sx1; dst_x<imwidth; dst_x++,src_x++) {
for (int n=0; n<skip; n++) { float r_, g_, b_;
unsigned short r_, g_, b_;
convertTo(r(i+m, jx+n), r_); // overflow security check, not sure that it's necessary
convertTo(g(i+m, jx+n), g_); if (src_x>=maxx)
convertTo(b(i+m, jx+n), b_); continue;
rtot += Color::igamma_srgb(r_);
gtot += Color::igamma_srgb(g_); convertTo(r(src_y, src_x), r_);
btot += Color::igamma_srgb(b_); convertTo(g(src_y, src_x), g_);
convertTo(b(src_y, src_x), b_);
lineR[dst_x] = r_;
lineG[dst_x] = g_;
lineB[dst_x] = 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<imwidth; dst_x++,src_x+=skip) {
if (src_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_y<src_sub_height; src_sub_y++)
for (int src_sub_x=0; src_sub_x<src_sub_width; src_sub_x++) {
float r_, g_, b_;
convertTo(r(src_y+src_sub_y, src_x+src_sub_x), r_);
convertTo(g(src_y+src_sub_y, src_x+src_sub_x), g_);
convertTo(b(src_y+src_sub_y, src_x+src_sub_x), b_);
rtot += r_;
gtot += g_;
btot += b_;
}
// convert back to gamma and clip
if (src_sub_width == skip && src_sub_height == skip) {
// Common case where the sub-region is complete
lineR[dst_x] = CLIP(rm*rtot);
lineG[dst_x] = CLIP(gm*gtot);
lineB[dst_x] = CLIP(bm*btot);
} }
// convert back to gamma and clip else {
lineR[j] = GCLIP(rm*rtot); // computing a special factor for this incomplete sub-region
lineG[j] = GCLIP(gm*gtot); float area = src_sub_width*src_sub_height;
lineB[j] = GCLIP(bm*btot); lineR[dst_x] = CLIP(rm2*rtot/area);
lineG[dst_x] = CLIP(gm2*gtot/area);
lineB[dst_x] = CLIP(bm2*btot/area);
}
}
} }
if (mtran == TR_NONE) if (mtran == TR_NONE)
for (int j=0,jx=sx1; j<imwidth; j++,jx+=skip) { for (int dst_x=0,src_x=sx1; dst_x<imwidth; dst_x++,src_x+=skip) {
image->r(ix, j) = lineR[j]; image->r(iy, dst_x) = lineR[dst_x];
image->g(ix, j) = lineG[j]; image->g(iy, dst_x) = lineG[dst_x];
image->b(ix, j) = lineB[j]; image->b(iy, dst_x) = lineB[dst_x];
} }
else if (mtran == TR_R180) else if (mtran == TR_R180)
for (int j=0; j<imwidth; j++) { for (int dst_x=0; dst_x<imwidth; dst_x++) {
image->r(imheight-1-ix, imwidth-1-j) = lineR[j]; image->r(imheight-1-iy, imwidth-1-dst_x) = lineR[dst_x];
image->g(imheight-1-ix, imwidth-1-j) = lineG[j]; image->g(imheight-1-iy, imwidth-1-dst_x) = lineG[dst_x];
image->b(imheight-1-ix, imwidth-1-j) = lineB[j]; image->b(imheight-1-iy, imwidth-1-dst_x) = lineB[dst_x];
} }
else if (mtran == TR_R90) else if (mtran == TR_R90)
for (int j=0,jx=sx1; j<imwidth; j++,jx+=skip) { for (int dst_x=0,src_x=sx1; dst_x<imwidth; dst_x++,src_x+=skip) {
image->r(j, imheight-1-ix) = lineR[j]; image->r(dst_x, imheight-1-iy) = lineR[dst_x];
image->g(j, imheight-1-ix) = lineG[j]; image->g(dst_x, imheight-1-iy) = lineG[dst_x];
image->b(j, imheight-1-ix) = lineB[j]; image->b(dst_x, imheight-1-iy) = lineB[dst_x];
} }
else if (mtran == TR_R270) else if (mtran == TR_R270)
for (int j=0,jx=sx1; j<imwidth; j++,jx+=skip) { for (int dst_x=0,src_x=sx1; dst_x<imwidth; dst_x++,src_x+=skip) {
image->r(imwidth-1-j, ix) = lineR[j]; image->r(imwidth-1-dst_x, iy) = lineR[dst_x];
image->g(imwidth-1-j, ix) = lineG[j]; image->g(imwidth-1-dst_x, iy) = lineG[dst_x];
image->b(imwidth-1-j, ix) = lineB[j]; image->b(imwidth-1-dst_x, iy) = lineB[dst_x];
} }
} }
#ifdef _OPENMP #ifdef _OPENMP

View File

@@ -126,14 +126,15 @@ void Imagefloat::getStdImage (ColorTemp ctemp, int tran, Imagefloat* image, Prev
transform (pp, tran, sx1, sy1, sx2, sy2); transform (pp, tran, sx1, sy1, sx2, sy2);
int imwidth=image->width,imheight=image->height; int imwidth=image->width; // Destination image
int imheight=image->height; // Destination image
if (((tran & TR_ROT) == TR_R90)||((tran & TR_ROT) == TR_R270)) { if (((tran & TR_ROT) == TR_R90)||((tran & TR_ROT) == TR_R270)) {
int swap = imwidth; int swap = imwidth;
imwidth=imheight; imwidth=imheight;
imheight=swap; imheight=swap;
} }
int istart = sy1; int maxx=width; // Source image
int maxx=width,maxy=height; int maxy=height; // Source image
int mtran = tran & TR_ROT; int mtran = tran & TR_ROT;
int skip = pp.skip; int skip = pp.skip;
@@ -141,6 +142,9 @@ void Imagefloat::getStdImage (ColorTemp ctemp, int tran, Imagefloat* image, Prev
// switched to using ints for the red/green/blue channel buffer. // switched to using ints for the red/green/blue channel buffer.
// Incidentally this improves accuracy too. // Incidentally this improves accuracy too.
float area=skip*skip; float area=skip*skip;
float rm2=rm;
float gm2=gm;
float bm2=bm;
rm/=area; rm/=area;
gm/=area; gm/=area;
bm/=area; bm/=area;
@@ -159,48 +163,88 @@ void Imagefloat::getStdImage (ColorTemp ctemp, int tran, Imagefloat* image, Prev
#ifdef _OPENMP #ifdef _OPENMP
#pragma omp for #pragma omp for
#endif #endif
for (int ix=0;ix<imheight;ix++) { for (int iy=0; iy<imheight; iy++) {
int i=istart+skip*ix;if (i>=maxy-skip) i=maxy-skip-1; // avoid trouble if (skip==1) {
for (int j=0,jx=sx1; j<imwidth; j++,jx+=skip) { // special case (speedup for 1:1 scale)
if (jx>=maxx-skip) jx=maxx-skip-1; // avoid trouble // i: source image, first line of the current destination row
int src_y=sy1+iy;
float rtot,gtot,btot; // overflow security check, not sure that it's necessary
rtot=gtot=btot=0; if (src_y>=maxy)
continue;
for (int m=0; m<skip; m++) for (int dst_x=0,src_x=sx1; dst_x<imwidth; dst_x++,src_x++) {
for (int n=0; n<skip; n++) { // overflow security check, not sure that it's necessary
rtot += r(i+m, jx+n); if (src_x>=maxx)
gtot += g(i+m, jx+n); continue;
btot += b(i+m, jx+n);
lineR[dst_x] = r(src_y, src_x);
lineG[dst_x] = g(src_y, src_x);
lineB[dst_x] = b(src_y, src_x);
}
}
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<imwidth; dst_x++,src_x+=skip) {
if (src_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_y<src_sub_height; src_sub_y++)
for (int src_sub_x=0; src_sub_x<src_sub_width; src_sub_x++) {
rtot += r(src_y+src_sub_y, src_x+src_sub_x);
gtot += g(src_y+src_sub_y, src_x+src_sub_x);
btot += b(src_y+src_sub_y, src_x+src_sub_x);
}
// convert back to gamma and clip
if (src_sub_width == skip && src_sub_height == skip) {
// Common case where the sub-region is complete
lineR[dst_x] = CLIP(rm*rtot);
lineG[dst_x] = CLIP(gm*gtot);
lineB[dst_x] = CLIP(bm*btot);
} }
lineR[j] = CLIP(rm*rtot); else {
lineG[j] = CLIP(gm*gtot); // computing a special factor for this incomplete sub-region
lineB[j] = CLIP(bm*btot); float area = src_sub_width*src_sub_height;
lineR[dst_x] = CLIP(rm2*rtot/area);
lineG[dst_x] = CLIP(gm2*gtot/area);
lineB[dst_x] = CLIP(bm2*btot/area);
}
}
} }
if (mtran == TR_NONE) if (mtran == TR_NONE)
for (int j=0,jx=sx1; j<imwidth; j++,jx+=skip) { for (int dst_x=0,src_x=sx1; dst_x<imwidth; dst_x++,src_x+=skip) {
image->r(ix, j) = lineR[j]; image->r(iy, dst_x) = lineR[dst_x];
image->g(ix, j) = lineG[j]; image->g(iy, dst_x) = lineG[dst_x];
image->b(ix, j) = lineB[j]; image->b(iy, dst_x) = lineB[dst_x];
} }
else if (mtran == TR_R180) else if (mtran == TR_R180)
for (int j=0; j<imwidth; j++) { for (int dst_x=0; dst_x<imwidth; dst_x++) {
image->r(imheight-1-ix, imwidth-1-j) = lineR[j]; image->r(imheight-1-iy, imwidth-1-dst_x) = lineR[dst_x];
image->g(imheight-1-ix, imwidth-1-j) = lineG[j]; image->g(imheight-1-iy, imwidth-1-dst_x) = lineG[dst_x];
image->b(imheight-1-ix, imwidth-1-j) = lineB[j]; image->b(imheight-1-iy, imwidth-1-dst_x) = lineB[dst_x];
} }
else if (mtran == TR_R90) else if (mtran == TR_R90)
for (int j=0,jx=sx1; j<imwidth; j++,jx+=skip) { for (int dst_x=0,src_x=sx1; dst_x<imwidth; dst_x++,src_x+=skip) {
image->r(j, imheight-1-ix) = lineR[j]; image->r(dst_x, imheight-1-iy) = lineR[dst_x];
image->g(j, imheight-1-ix) = lineG[j]; image->g(dst_x, imheight-1-iy) = lineG[dst_x];
image->b(j, imheight-1-ix) = lineB[j]; image->b(dst_x, imheight-1-iy) = lineB[dst_x];
} }
else if (mtran == TR_R270) else if (mtran == TR_R270)
for (int j=0,jx=sx1; j<imwidth; j++,jx+=skip) { for (int dst_x=0,src_x=sx1; dst_x<imwidth; dst_x++,src_x+=skip) {
image->r(imwidth-1-j, ix) = lineR[j]; image->r(imwidth-1-dst_x, iy) = lineR[dst_x];
image->g(imwidth-1-j, ix) = lineG[j]; image->g(imwidth-1-dst_x, iy) = lineG[dst_x];
image->b(imwidth-1-j, ix) = lineB[j]; image->b(imwidth-1-dst_x, iy) = lineB[dst_x];
} }
} }
#ifdef _OPENMP #ifdef _OPENMP