From 4a0d7d86f063b399a7549d20f24cc7f4ae059b0e Mon Sep 17 00:00:00 2001 From: Pierre Joye Date: Wed, 1 Sep 2021 14:05:56 +0700 Subject: Fix #320, should not convert the source to palette --- src/gd_interpolation.c | 34 ++++++++++++++++++++------------- tests/gdimagecopyrotated/CMakeLists.txt | 3 +++ tests/gdimagecopyrotated/bug00320.c | 22 +++++++++++++++++++++ 3 files changed, 46 insertions(+), 13 deletions(-) create mode 100644 tests/gdimagecopyrotated/bug00320.c diff --git a/src/gd_interpolation.c b/src/gd_interpolation.c index 9f743fe..6a4d6c9 100644 --- a/src/gd_interpolation.c +++ b/src/gd_interpolation.c @@ -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; } diff --git a/tests/gdimagecopyrotated/CMakeLists.txt b/tests/gdimagecopyrotated/CMakeLists.txt index 7f1a678..7d4f001 100644 --- a/tests/gdimagecopyrotated/CMakeLists.txt +++ b/tests/gdimagecopyrotated/CMakeLists.txt @@ -1,3 +1,6 @@ +LIST(APPEND TESTS_FILES + bug00320 +) IF(PNG_FOUND) LIST(APPEND TESTS_FILES bug00020 diff --git a/tests/gdimagecopyrotated/bug00320.c b/tests/gdimagecopyrotated/bug00320.c new file mode 100644 index 0000000..72ff363 --- /dev/null +++ b/tests/gdimagecopyrotated/bug00320.c @@ -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(); +} -- cgit v1.2.1