The linear interpolation done by matrix_transform_bg() (also called
when rotating images) called floor() on the ordinate both in the
caller and in the interpolation code, which seemed to confuse the compiler
supplied with the gcc supplied with 32-bit strawberry perl 5.26.0.
I suspect a value just barely below an integer was being stored in the
FPU and then rounded up to that integer when converted to a double,
which then caused an off-by-one error in interpolation.
if (channels == 1 || channels == 3) {
for (ch = 0; ch < channels; ++ch)
out.channel[ch] = ((1-pos) * before.channel[ch] + pos * after.channel[ch]) + 0.5;
if (channels == 1 || channels == 3) {
for (ch = 0; ch < channels; ++ch)
out.channel[ch] = ((1-pos) * before.channel[ch] + pos * after.channel[ch]) + 0.5;
if (channels == 1 || channels == 3) {
for (ch = 0; ch < channels; ++ch)
out.channel[ch] = (1-pos) * before.channel[ch] + pos * after.channel[ch];
if (channels == 1 || channels == 3) {
for (ch = 0; ch < channels; ++ch)
out.channel[ch] = (1-pos) * before.channel[ch] + pos * after.channel[ch];
if (fabs(sz) > 0.0000001
&& sx >= -1 && sx < src->xsize
&& sy >= -1 && sy < src->ysize) {
if (fabs(sz) > 0.0000001
&& sx >= -1 && sx < src->xsize
&& sy >= -1 && sy < src->ysize) {
- i_img_dim bx = floor(sx);
- i_img_dim by = floor(sy);
+ double fsx = floor(sx);
+ double fsy = floor(sy);
+ i_img_dim bx = fsx;
+ i_img_dim by = fsy;
ROT_DEBUG(fprintf(stderr, "map " i_DFp " to %g,%g\n", i_DFcp(x, y), sx, sy));
ROT_DEBUG(fprintf(stderr, "map " i_DFp " to %g,%g\n", i_DFcp(x, y), sx, sy));
- if (sx != bx) {
- if (sy != by) {
+ if (sx != fsx) {
+ double dx = sx - fsx;
+ if (sy != fsy) {
IM_COLOR c[2][2];
IM_COLOR ci2[2];
IM_COLOR c[2][2];
IM_COLOR ci2[2];
ROT_DEBUG(fprintf(stderr, " both non-int\n"));
for (i = 0; i < 2; ++i)
for (j = 0; j < 2; ++j)
if (IM_GPIX(src, bx+i, by+j, &c[j][i]))
c[j][i] = back;
for (j = 0; j < 2; ++j)
ROT_DEBUG(fprintf(stderr, " both non-int\n"));
for (i = 0; i < 2; ++i)
for (j = 0; j < 2; ++j)
if (IM_GPIX(src, bx+i, by+j, &c[j][i]))
c[j][i] = back;
for (j = 0; j < 2; ++j)
- ci2[j] = interp_i_color(c[j][0], c[j][1], sx, src->channels);
- vals[x] = interp_i_color(ci2[0], ci2[1], sy, src->channels);
+ ci2[j] = interp_i_color(c[j][0], c[j][1], dx, src->channels);
+ vals[x] = interp_i_color(ci2[0], ci2[1], dy, src->channels);
}
else {
IM_COLOR ci2[2];
}
else {
IM_COLOR ci2[2];
for (i = 0; i < 2; ++i)
if (IM_GPIX(src, bx+i, sy, ci2+i))
ci2[i] = back;
for (i = 0; i < 2; ++i)
if (IM_GPIX(src, bx+i, sy, ci2+i))
ci2[i] = back;
- vals[x] = interp_i_color(ci2[0], ci2[1], sx, src->channels);
+ vals[x] = interp_i_color(ci2[0], ci2[1], dx, src->channels);
- if (sy != (i_img_dim)sy) {
ROT_DEBUG(fprintf(stderr, " x int, y non-int\n"));
for (i = 0; i < 2; ++i)
if (IM_GPIX(src, bx, by+i, ci2+i))
ci2[i] = back;
ROT_DEBUG(fprintf(stderr, " x int, y non-int\n"));
for (i = 0; i < 2; ++i)
if (IM_GPIX(src, bx, by+i, ci2+i))
ci2[i] = back;
- vals[x] = interp_i_color(ci2[0], ci2[1], sy, src->channels);
+ vals[x] = interp_i_color(ci2[0], ci2[1], dy, src->channels);
}
else {
ROT_DEBUG(fprintf(stderr, " both int\n"));
/* all the world's an integer */
}
else {
ROT_DEBUG(fprintf(stderr, " both int\n"));
/* all the world's an integer */
- if (IM_GPIX(src, sx, sy, vals+x))
+ if (IM_GPIX(src, bx, by, vals+x))