summaryrefslogtreecommitdiffhomepage
path: root/src/textures.c
diff options
context:
space:
mode:
authorraysan5 <[email protected]>2020-06-10 21:21:37 +0200
committerraysan5 <[email protected]>2020-06-10 21:21:37 +0200
commit4745ebeed5e80040437853efbc0c20464f12739f (patch)
treef6a87eaf60005ff63b04f9be742eb978f5bd9669 /src/textures.c
parentdea0279a743e087128028296b718408258a1edb8 (diff)
downloadraylib-4745ebeed5e80040437853efbc0c20464f12739f.tar.gz
raylib-4745ebeed5e80040437853efbc0c20464f12739f.zip
REVIEWED: ImageResizeCanvas(), optimization #1218
Optimized to avoid ImageCrop() calls, now we define the source image rectangle and we just copy that data over the new canvas.
Diffstat (limited to 'src/textures.c')
-rw-r--r--src/textures.c51
1 files changed, 25 insertions, 26 deletions
diff --git a/src/textures.c b/src/textures.c
index 50a4d36e..e717d0d3 100644
--- a/src/textures.c
+++ b/src/textures.c
@@ -1301,34 +1301,27 @@ void ImageResizeCanvas(Image *image, int newWidth, int newHeight, int offsetX, i
if (image->format >= COMPRESSED_DXT1_RGB) TRACELOG(LOG_WARNING, "Image manipulation not supported for compressed formats");
else if ((newWidth != image->width) || (newHeight != image->height))
{
- // Support offsets out of canvas new size -> original image is cropped
+ Rectangle srcRec = { 0, 0, image->width, image->height };
+ Vector2 dstPos = { offsetX, offsetY };
+
if (offsetX < 0)
{
- ImageCrop(image, (Rectangle) { -(float)offsetX, 0, (float)(image->width + offsetX), (float)image->height });
- offsetX = 0;
- }
- else if (offsetX > (newWidth - image->width))
- {
- ImageCrop(image, (Rectangle) { 0, 0, (float)(image->width - (offsetX - (newWidth - image->width))), (float)image->height });
- offsetX = newWidth - image->width;
+ srcRec.x = -offsetX;
+ srcRec.width += offsetX;
+ dstPos.x = 0;
}
+ else if ((offsetX + image->width) > newWidth) srcRec.width = newWidth - offsetX;
if (offsetY < 0)
{
- ImageCrop(image, (Rectangle) { 0, -(float)offsetY, (float)image->width, (float)(image->height + offsetY) });
- offsetY = 0;
- }
- else if (offsetY > (newHeight - image->height))
- {
- ImageCrop(image, (Rectangle) { 0, 0, (float)image->width, (float)(image->height - (offsetY - (newHeight - image->height))) });
- offsetY = newHeight - image->height;
- }
-
- if ((newWidth < image->width) || (newHeight < image->height))
- {
- Rectangle crop = { (float)offsetX, (float)offsetY, (float)newWidth, (float)newHeight };
- ImageCrop(image, crop);
+ srcRec.y = -offsetY;
+ srcRec.height += offsetY;
+ dstPos.y = 0;
}
+ else if ((offsetY + image->height) > newHeight) srcRec.height = newHeight - offsetY;
+
+ if (newWidth < srcRec.width) srcRec.width = newWidth;
+ if (newHeight < srcRec.height) srcRec.height = newHeight;
int dataSize = GetPixelDataSize(image->width, image->height, image->format);
int bytesPerPixel = dataSize/(image->width*image->height);
@@ -1337,10 +1330,12 @@ void ImageResizeCanvas(Image *image, int newWidth, int newHeight, int offsetX, i
// TODO: Fill resizedData with fill color (must be formatted to image->format)
- for (int y = 0, offsetSize = (offsetY*newWidth + offsetX)*bytesPerPixel; y < image->height; y++)
+ int dstOffsetSize = ((int)dstPos.y*newWidth + (int)dstPos.x)*bytesPerPixel;
+
+ for (int y = 0; y < (int)srcRec.height; y++)
{
- memcpy(resizedData + offsetSize, ((unsigned char *)image->data) + y*image->width*bytesPerPixel, image->width*bytesPerPixel);
- offsetSize += (newWidth*bytesPerPixel);
+ memcpy(resizedData + dstOffsetSize, ((unsigned char *)image->data) + ((y + (int)srcRec.y)*image->width + (int)srcRec.x)*bytesPerPixel, (int)srcRec.width*bytesPerPixel);
+ dstOffsetSize += (newWidth*bytesPerPixel);
}
RL_FREE(image->data);
@@ -2444,11 +2439,16 @@ void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec, Color
srcRec.height = src.height - srcRec.y;
TRACELOG(LOG_WARNING, "IMAGE: Source rectangle height out of bounds, rescaled height: %i", srcRec.height);
}
+
+ // TODO: OPTIMIZATION: Avoid ImageCrop(), not required, it should be enough to know the src/dst rectangles to copy data
Image srcCopy = ImageCopy(src); // Make a copy of source image to work with it
// Crop source image to desired source rectangle (if required)
- if ((src.width != (int)srcRec.width) && (src.height != (int)srcRec.height)) ImageCrop(&srcCopy, srcRec);
+ if ((src.width != (int)srcRec.width) && (src.height != (int)srcRec.height))
+ {
+ ImageCrop(&srcCopy, srcRec);
+ }
// Scale source image in case destination rec size is different than source rec size
if (((int)dstRec.width != (int)srcRec.width) || ((int)dstRec.height != (int)srcRec.height))
@@ -2494,7 +2494,6 @@ void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec, Color
Vector4 ftint = ColorNormalize(tint); // Normalized color tint
// Blit pixels, copy source image into destination
- // TODO: Maybe out-of-bounds blitting could be considered here instead of so much cropping
for (int j = (int)dstRec.y; j < (int)(dstRec.y + dstRec.height); j++)
{
for (int i = (int)dstRec.x; i < (int)(dstRec.x + dstRec.width); i++)