parent
08238a0ac2
commit
3f50ffaefd
|
@ -1975,6 +1975,51 @@ BGD_DECLARE(int) gdTransformAffineGetImage(gdImagePtr *dst,
|
|||
}
|
||||
}
|
||||
|
||||
/** Function: getPixelRgbInterpolated
|
||||
* get the index of the image's colors
|
||||
*
|
||||
* Parameters:
|
||||
* im - Image to draw the transformed image
|
||||
* tcolor - TrueColor
|
||||
*
|
||||
* Return:
|
||||
* index of colors
|
||||
*/
|
||||
static int getPixelRgbInterpolated(gdImagePtr im, const int tcolor)
|
||||
{
|
||||
unsigned char r, g, b, a;
|
||||
int ct;
|
||||
|
||||
b = (unsigned char)tcolor;
|
||||
g = (unsigned char)tcolor >> 8;
|
||||
r = (unsigned char)tcolor >> 16;
|
||||
a = (unsigned char)tcolor >> 24;
|
||||
|
||||
b = CLAMP(b, 0, 255);
|
||||
g = CLAMP(g, 0, 255);
|
||||
r = CLAMP(r, 0, 255);
|
||||
a = CLAMP(a, 0, 127);
|
||||
|
||||
for (int i = 0; i < im->colorsTotal; i++) {
|
||||
if (im->red[i] == r && im->green[i] == g && im->blue[i] == b && im->alpha[i] == a) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
ct = im->colorsTotal;
|
||||
if (ct == gdMaxColors) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
im->colorsTotal++;
|
||||
im->red[ct] = r;
|
||||
im->green[ct] = g;
|
||||
im->blue[ct] = b;
|
||||
im->alpha[ct] = a;
|
||||
im->open[ct] = 0;
|
||||
|
||||
return ct;
|
||||
}
|
||||
/**
|
||||
* Function: gdTransformAffineCopy
|
||||
* Applies an affine transformation to a region and copy the result
|
||||
|
@ -2011,8 +2056,11 @@ BGD_DECLARE(int) gdTransformAffineCopy(gdImagePtr dst,
|
|||
gdImageSetInterpolationMethod(src, GD_BICUBIC);
|
||||
}
|
||||
|
||||
|
||||
gdImageClipRectangle(src, src_region);
|
||||
c1x = src_region->x;
|
||||
c1y = src_region->y;
|
||||
c2x = src_region->x + src_region->width -1;
|
||||
c2y = src_region->y + src_region->height -1;
|
||||
|
||||
if (src_region->x > 0 || src_region->y > 0
|
||||
|| src_region->width < gdImageSX(src)
|
||||
|
@ -2036,8 +2084,6 @@ BGD_DECLARE(int) gdTransformAffineCopy(gdImagePtr dst,
|
|||
return GD_FALSE;
|
||||
}
|
||||
|
||||
gdImageGetClip(dst, &c1x, &c1y, &c2x, &c2y);
|
||||
|
||||
end_x = bbox.width + abs(bbox.x);
|
||||
end_y = bbox.height + abs(bbox.y);
|
||||
|
||||
|
@ -2053,18 +2099,24 @@ BGD_DECLARE(int) gdTransformAffineCopy(gdImagePtr dst,
|
|||
if (dst->alphaBlendingFlag) {
|
||||
for (y = bbox.y; y <= end_y; y++) {
|
||||
pt.y = y + 0.5;
|
||||
for (x = 0; x <= end_x; x++) {
|
||||
for (x = bbox.x; x <= end_x; x++) {
|
||||
pt.x = x + 0.5;
|
||||
gdAffineApplyToPointF(&src_pt, &pt, inv);
|
||||
gdImageSetPixel(dst, dst_x + x, dst_y + y, getPixelInterpolated(src, src_offset_x + src_pt.x, src_offset_y + src_pt.y, 0));
|
||||
if (floor(src_offset_x + src_pt.x) < c1x
|
||||
|| floor(src_offset_x + src_pt.x) > c2x
|
||||
|| floor(src_offset_y + src_pt.y) < c1y
|
||||
|| floor(src_offset_y + src_pt.y) > c2y) {
|
||||
continue;
|
||||
}
|
||||
gdImageSetPixel(dst, dst_x + x, dst_y + y, getPixelInterpolated(src, (int)(src_offset_x + src_pt.x), (int)(src_offset_y + src_pt.y), 0));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (y = 0; y <= end_y; y++) {
|
||||
for (y = bbox.y; y <= end_y; y++) {
|
||||
unsigned char *dst_p = NULL;
|
||||
int *tdst_p = NULL;
|
||||
|
||||
pt.y = y + 0.5 + bbox.y;
|
||||
pt.y = y + 0.5;
|
||||
if ((dst_y + y) < 0 || ((dst_y + y) > gdImageSY(dst) -1)) {
|
||||
continue;
|
||||
}
|
||||
|
@ -2074,17 +2126,23 @@ BGD_DECLARE(int) gdTransformAffineCopy(gdImagePtr dst,
|
|||
dst_p = dst->pixels[dst_y + y] + dst_x;
|
||||
}
|
||||
|
||||
for (x = 0; x <= end_x; x++) {
|
||||
pt.x = x + 0.5 + bbox.x;
|
||||
for (x = bbox.x; x <= end_x; x++) {
|
||||
pt.x = x + 0.5;
|
||||
gdAffineApplyToPointF(&src_pt, &pt, inv);
|
||||
|
||||
if ((dst_x + x) < 0 || (dst_x + x) > (gdImageSX(dst) - 1)) {
|
||||
break;
|
||||
}
|
||||
if (floor(src_offset_x + src_pt.x) < c1x
|
||||
|| floor(src_offset_x + src_pt.x) > c2x
|
||||
|| floor(src_offset_y + src_pt.y) < c1y
|
||||
|| floor(src_offset_y + src_pt.y) > c2y) {
|
||||
continue;
|
||||
}
|
||||
if (dst->trueColor) {
|
||||
*(tdst_p++) = getPixelInterpolated(src, src_offset_x + src_pt.x, src_offset_y + src_pt.y, -1);
|
||||
*(tdst_p + dst_x + x) = getPixelInterpolated(src, (int)(src_offset_x + src_pt.x), (int)(src_offset_y + src_pt.y), -1);
|
||||
} else {
|
||||
*(dst_p++) = getPixelInterpolated(src, src_offset_x + src_pt.x, src_offset_y + src_pt.y, -1);
|
||||
*(dst_p + dst_x + x) = getPixelRgbInterpolated(dst, getPixelInterpolated(src, (int)(src_offset_x + src_pt.x), (int)(src_offset_y + src_pt.y), -1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2148,8 +2206,8 @@ BGD_DECLARE(int) gdTransformAffineBoundingBox(gdRectPtr src, const double affine
|
|||
}
|
||||
bbox->x = (int) min.x;
|
||||
bbox->y = (int) min.y;
|
||||
bbox->width = (int) ceil((max.x - min.x)) + 1;
|
||||
bbox->height = (int) ceil(max.y - min.y) + 1;
|
||||
bbox->width = (int) ceil((max.x - min.x));
|
||||
bbox->height = (int) ceil(max.y - min.y);
|
||||
|
||||
return GD_TRUE;
|
||||
}
|
||||
|
|
|
@ -63,7 +63,7 @@ BGD_DECLARE(int) gdAffineInvert (double dst[6], const double src[6])
|
|||
{
|
||||
double r_det = (src[0] * src[3] - src[1] * src[2]);
|
||||
|
||||
if (r_det <= 0.0) {
|
||||
if (fabs(r_det) <= 0.0) {
|
||||
return GD_FALSE;
|
||||
}
|
||||
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 32 KiB |
|
@ -24,7 +24,7 @@ int main()
|
|||
if (gdTransformAffineBoundingBox(&area, affine, &bbox) != GD_TRUE) {
|
||||
return 1;
|
||||
}
|
||||
if (!(bbox.x ==-253 && bbox.y ==-228 && bbox.width == 298 && bbox.height == 230)) {
|
||||
if (!(bbox.x ==-253 && bbox.y ==-228 && bbox.width == 297 && bbox.height == 229)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/github_bug_00583
|
||||
/github_bug_00585
|
||||
/github_bug_00586
|
||||
/github_bug_00596
|
||||
|
|
|
@ -2,6 +2,7 @@ LIST(APPEND TESTS_FILES
|
|||
github_bug_00583
|
||||
github_bug_00585
|
||||
github_bug_00586
|
||||
github_bug_00596
|
||||
)
|
||||
|
||||
ADD_GD_TESTS()
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
libgd_test_programs += \
|
||||
gdtransformaffinecopy/github_bug_00583 \
|
||||
gdtransformaffinecopy/github_bug_00585 \
|
||||
gdtransformaffinecopy/github_bug_00586
|
||||
gdtransformaffinecopy/github_bug_00586 \
|
||||
gdtransformaffinecopy/github_bug_00596
|
||||
|
||||
EXTRA_DIST += \
|
||||
gdtransformaffinecopy/CMakeLists.txt
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
/**
|
||||
* Test gdTransformAffineCopy() run error
|
||||
*
|
||||
* See <https://github.com/libgd/libgd/issues/596>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "gd.h"
|
||||
#include "gdtest.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
double matrix[] = {1, 0, 0, 1, 0, 0};
|
||||
gdImagePtr src, dst;
|
||||
gdRect rect = {0, 0, 16, 16};
|
||||
int white, green;
|
||||
int status = 0;
|
||||
int res;
|
||||
int actual_color = 0;
|
||||
int expected_color = 0x00ff00;
|
||||
|
||||
src = gdImageCreateTrueColor(16, 16);
|
||||
gdTestAssert(src != NULL);
|
||||
white = gdImageColorAllocate(src, 255, 255, 255);
|
||||
gdImageFilledRectangle(src, 0, 0, 16, 16, white);
|
||||
|
||||
dst = gdImageCreateTrueColor(50, 50);
|
||||
gdTestAssert(dst != NULL);
|
||||
green = gdImageColorAllocate(dst, 0, 255, 0);
|
||||
gdImageFilledRectangle(dst, 0, 0, 50, 50, green);
|
||||
|
||||
res = gdTransformAffineCopy(dst, 4, 4, src, &rect, matrix);
|
||||
gdTestAssert(res != GD_FALSE);
|
||||
|
||||
status = gdNumFailures();
|
||||
actual_color = gdImageGetPixel(dst, 20, 5);
|
||||
status = (actual_color == expected_color) ? status : 1;
|
||||
|
||||
gdImageDestroy(src);
|
||||
gdImageDestroy(dst);
|
||||
return status;
|
||||
}
|
Loading…
Reference in New Issue