summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/gd_interpolation.c34
-rw-r--r--tests/gdimagecopyrotated/CMakeLists.txt3
-rw-r--r--tests/gdimagecopyrotated/bug00320.c22
3 files changed, 46 insertions, 13 deletions
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();
+}