Fix #320, should not convert the source to palette

master
Pierre Joye 2021-09-01 14:05:56 +07:00
parent 88a407780d
commit 4a0d7d86f0
3 changed files with 46 additions and 13 deletions

View File

@ -1829,19 +1829,19 @@ BGD_DECLARE(gdImagePtr) gdImageRotateInterpolated(const gdImagePtr src, const fl
case later. Keep the two decimal precisions so smaller rotation steps can be done, useful for
slow animations, f.e. */
const int angle_rounded = fmod((int) floorf(angle * 100), 360 * 100);
gdImagePtr src_tc = src;
int src_cloned = 0;
if (src == NULL || bgcolor < 0) {
return NULL;
}
/* impact perf a bit, but not that much. Implementation for palette
images can be done at a later point.
*/
if (src->trueColor == 0) {
if (!gdImageTrueColor(src)) {
if (bgcolor < gdMaxColors) {
bgcolor = gdTrueColorAlpha(src->red[bgcolor], src->green[bgcolor], src->blue[bgcolor], src->alpha[bgcolor]);
}
gdImagePaletteToTrueColor(src);
src_tc = gdImageClone(src);
gdImagePaletteToTrueColor(src_tc);
src_cloned = 1;
}
/* 0 && 90 degrees multiple rotation, 0 rotation simply clones the return image and convert it
@ -1853,38 +1853,46 @@ BGD_DECLARE(gdImagePtr) gdImageRotateInterpolated(const gdImagePtr src, const fl
if (dst == NULL) {
return NULL;
}
if (dst->trueColor == 0) {
gdImagePaletteToTrueColor(dst);
}
if (src_cloned) gdImageDestroy(src_tc);
return dst;
}
case -27000:
case 9000:
if (src_cloned) gdImageDestroy(src_tc);
return gdImageRotate90(src, 0);
case -18000:
case 18000:
if (src_cloned) gdImageDestroy(src);
return gdImageRotate180(src, 0);
case -9000:
case 27000:
if (src_cloned) gdImageDestroy(src_tc);
return gdImageRotate270(src, 0);
}
if (src->interpolation_id < 1 || src->interpolation_id > GD_METHOD_COUNT) {
if (src_cloned) gdImageDestroy(src_tc);
return NULL;
}
switch (src->interpolation_id) {
case GD_NEAREST_NEIGHBOUR:
return gdImageRotateNearestNeighbour(src, angle, bgcolor);
case GD_NEAREST_NEIGHBOUR: {
gdImagePtr res = gdImageRotateNearestNeighbour(src, angle, bgcolor);
if (src_cloned) gdImageDestroy(src_tc);
return res;
break;
}
case GD_BILINEAR_FIXED:
case GD_BICUBIC_FIXED:
default:
return gdImageRotateGeneric(src, angle, bgcolor);
default: {
gdImagePtr res = gdImageRotateGeneric(src, angle, bgcolor);
if (src_cloned) gdImageDestroy(src_tc);
return res;
}
}
return NULL;
}

View File

@ -1,3 +1,6 @@
LIST(APPEND TESTS_FILES
bug00320
)
IF(PNG_FOUND)
LIST(APPEND TESTS_FILES
bug00020

View File

@ -0,0 +1,22 @@
#include "gd.h"
#include "gdtest.h"
#define width 20
int main()
{
gdImagePtr src, dst;
int black;
src = gdImageCreate(10, 10);
black = gdImageColorAllocate(src, 0, 0, 0);
gdTestAssert(gdImageTrueColor(src) == 0);
dst = gdImageRotateInterpolated(src, 30.0, black);
gdTestAssert(dst != NULL);
gdTestAssert(gdImageTrueColor(src) == 0);
gdImageDestroy(src);
gdImageDestroy(dst);
return gdNumFailures();
}