Skip to content

Commit

Permalink
Fix rotation of images with odd number of rows (#6926)
Browse files Browse the repository at this point in the history
* Fix line in middle of 180 degree rotated image

For images with an odd number of rows, a 180 degree rotation resulted in
one row of un-rotated pixels because it was effectively rotated twice.

* Replace verbose swap with std::swap
  • Loading branch information
Lawrence37 authored Feb 4, 2024
1 parent 0d0834c commit 2f7c2e9
Showing 1 changed file with 47 additions and 27 deletions.
74 changes: 47 additions & 27 deletions rtengine/iimage.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
*/
#pragma once

#include <utility>
#include <vector>

#include <lcms2.h>
Expand Down Expand Up @@ -396,7 +397,7 @@ class PlanarWhateverData : virtual public ImageDatas

swap(rotatedImg);
} else if (deg == 180) {
int height2 = height / 2 + (height & 1);
int height2 = height / 2;

#ifdef _OPENMP
// difficult to find a cutoff value where parallelization is counter productive because of processor's data cache collision...
Expand All @@ -406,13 +407,22 @@ class PlanarWhateverData : virtual public ImageDatas

for (int i = 0; i < height2; i++) {
for (int j = 0; j < width; j++) {
T tmp;
int x = width - 1 - j;
int y = height - 1 - i;

tmp = v(i, j);
v(i, j) = v(y, x);
v(y, x) = tmp;
std::swap(v(i, j), v(y, x));
}
}

// Middle row of odd-height images: only go half way otherwise the
// pixels will be swapped twice.
if (height & 1) {
int i = height / 2;
int width2 = width / 2;
for (int j = 0; j < width2; j++) {
int x = width - 1 - j;

std::swap(v(i, j), v(i, x));
}
}
#ifdef _OPENMP
Expand Down Expand Up @@ -828,7 +838,7 @@ class PlanarRGBData : virtual public ImageDatas

swap(rotatedImg);
} else if (deg == 180) {
int height2 = height / 2 + (height & 1);
int height2 = height / 2;

#ifdef _OPENMP
// difficult to find a cutoff value where parallelization is counter productive because of processor's data cache collision...
Expand All @@ -838,21 +848,26 @@ class PlanarRGBData : virtual public ImageDatas

for (int i = 0; i < height2; i++) {
for (int j = 0; j < width; j++) {
T tmp;
int x = width - 1 - j;
int y = height - 1 - i;

tmp = r(i, j);
r(i, j) = r(y, x);
r(y, x) = tmp;
std::swap(r(i, j), r(y, x));
std::swap(g(i, j), g(y, x));
std::swap(b(i, j), b(y, x));
}
}

tmp = g(i, j);
g(i, j) = g(y, x);
g(y, x) = tmp;
// Middle row of odd-height images: only go half way otherwise the
// pixels will be swapped twice.
if (height & 1) {
int i = height / 2;
int width2 = width / 2;
for (int j = 0; j < width2; j++) {
int x = width - 1 - j;

tmp = b(i, j);
b(i, j) = b(y, x);
b(y, x) = tmp;
std::swap(r(i, j), r(i, x));
std::swap(g(i, j), g(i, x));
std::swap(b(i, j), b(i, x));
}
}
#ifdef _OPENMP
Expand Down Expand Up @@ -1481,26 +1496,31 @@ class ChunkyRGBData : virtual public ImageDatas

swap(rotatedImg);
} else if (deg == 180) {
int height2 = height / 2 + (height & 1);
int height2 = height / 2;

// Maybe not sufficiently optimized, but will do what it has to do
for (int i = 0; i < height2; i++) {
for (int j = 0; j < width; j++) {
T tmp;
int x = width - 1 - j;
int y = height - 1 - i;

tmp = r(i, j);
r(i, j) = r(y, x);
r(y, x) = tmp;
std::swap(r(i, j), r(y, x));
std::swap(g(i, j), g(y, x));
std::swap(b(i, j), b(y, x));
}
}

tmp = g(i, j);
g(i, j) = g(y, x);
g(y, x) = tmp;
// Middle row of odd-height images: only go half way otherwise the
// pixels will be swapped twice.
if (height & 1) {
int i = height / 2;
int width2 = width / 2;
for (int j = 0; j < width2; j++) {
int x = width - 1 - j;

tmp = b(i, j);
b(i, j) = b(y, x);
b(y, x) = tmp;
std::swap(r(i, j), r(i, x));
std::swap(g(i, j), g(i, x));
std::swap(b(i, j), b(i, x));
}
}
}
Expand Down

0 comments on commit 2f7c2e9

Please sign in to comment.