7 Commits

Author SHA1 Message Date
Ray
f00317bead Added required library 2026-07-11 17:01:09 +02:00
Ray
8805ab3ee2 Update rmodels.c 2026-07-11 16:57:49 +02:00
Ray
ebec978443 REVIEWED: TextJoin(), TextSubtext(), TextInsert*() - ROS: CLN-018 2026-07-11 16:45:56 +02:00
Ray
cfe56d97ea REVIEWED: GetPixelDataSize(), avoid allocations >2GB - ROS: CLN-013
REVIEWED: `GenImageColor()`, `ImageRotate()`
2026-07-11 16:42:57 +02:00
Ray
97d2b0146c REVIEWED: Replace assert() by runtime checks - ROS: CLN-012 2026-07-11 16:22:05 +02:00
Ray
c31666fe2a REVIEWED: ImageFromImage() - ROS: CLN-007 2026-07-11 16:20:41 +02:00
Ray
ab35e0f712 REVIEWED: LoadAutomationEventList() - ROS: CLN-005, CLN-006 2026-07-11 16:18:34 +02:00
6 changed files with 134 additions and 85 deletions

View File

@ -1020,7 +1020,12 @@ static int parseLine(Command *command, const char *p, unsigned int p_len,
int triangulate) {
char linebuf[4096];
const char *token;
assert(p_len < 4095);
// @raysan5:
// WARNING: If -DNDEBUG is set when compiling, assertions will not
// be present in the compiled binary, replacing by a runtime check
//assert(p_len < 4095);
if (p_len > 4095) return 0;
memcpy(linebuf, p, p_len);
linebuf[p_len] = '\0';
@ -1102,8 +1107,12 @@ static int parseLine(Command *command, const char *p, unsigned int p_len,
tinyobj_vertex_index_t i1;
tinyobj_vertex_index_t i2 = f[1];
assert(3 * num_f < TINYOBJ_MAX_FACES_PER_F_LINE);
// @raysan5:
// WARNING: If -DNDEBUG is set when compiling, assertions will not
// be present in the compiled binary, replacing by a runtime check
//assert(3 * num_f < TINYOBJ_MAX_FACES_PER_F_LINE);
if (3*num_f > TINYOBJ_MAX_FACES_PER_F_LINE) return 0;
for (k = 2; k < num_f; k++) {
i1 = i2;
i2 = f[k];
@ -1119,7 +1128,13 @@ static int parseLine(Command *command, const char *p, unsigned int p_len,
} else {
unsigned int k = 0;
assert(num_f < TINYOBJ_MAX_FACES_PER_F_LINE);
// @raysan5:
// WARNING: If -DNDEBUG is set when compiling, assertions will not
// be present in the compiled binary, replacing by a runtime check
//assert(num_f < TINYOBJ_MAX_FACES_PER_F_LINE);
if (num_f > TINYOBJ_MAX_FACES_PER_F_LINE) return 0;
for (k = 0; k < num_f; k++) {
command->f[k] = f[k];
}

View File

@ -3601,10 +3601,14 @@ AutomationEventList LoadAutomationEventList(const char *fileName)
case 'c': sscanf(buffer, "c %i", &list.count); break;
case 'e':
{
sscanf(buffer, "e %d %d %d %d %d %d %[^\n]s", &list.events[counter].frame, &list.events[counter].type,
&list.events[counter].params[0], &list.events[counter].params[1], &list.events[counter].params[2], &list.events[counter].params[3], eventDesc);
if (counter < list.capacity)
{
sscanf(buffer, "e %d %d %d %d %d %d %63[^\n]s", &list.events[counter].frame, &list.events[counter].type,
&list.events[counter].params[0], &list.events[counter].params[1], &list.events[counter].params[2], &list.events[counter].params[3], eventDesc);
counter++;
counter++;
}
else TRACELOG(LOG_WARNING, "AUTOMATION: Event goes beyond automated list capacity (MAX: %i): %s", buffer, list.capacity);
} break;
default: break;
}

View File

@ -847,11 +847,11 @@ RLAPI void rlLoadDrawQuad(void); // Load and draw a quad
#define SW_CALLOC(n,sz) RL_CALLOC(n, sz)
#define SW_REALLOC(ptr, newSz) RL_REALLOC(ptr, newSz)
#define SW_FREE(ptr) RL_FREE(ptr)
#include "external/rlsw.h" // OpenGL 1.1 software implementation
#include "external/rlsw.h" // OpenGL 1.1 software implementation
#else
#if defined(__APPLE__)
#include <OpenGL/gl.h> // OpenGL 1.1 library for OSX
#include <OpenGL/glext.h> // OpenGL extensions library
#include <OpenGL/gl.h> // OpenGL 1.1 library for OSX
#include <OpenGL/glext.h> // OpenGL extensions library
#else
// APIENTRY for OpenGL function pointer declarations is required
#if !defined(APIENTRY)
@ -866,7 +866,7 @@ RLAPI void rlLoadDrawQuad(void); // Load and draw a quad
#define WINGDIAPI __declspec(dllimport)
#endif
#include <GL/gl.h> // OpenGL 1.1 library
#include <GL/gl.h> // OpenGL 1.1 library
#endif
#endif
#endif
@ -907,9 +907,10 @@ RLAPI void rlLoadDrawQuad(void); // Load and draw a quad
#endif
#endif
#include <stdlib.h> // Required for: calloc(), free()
#include <string.h> // Required for: strcmp(), strlen() [Used in rlglInit(), on extensions loading]
#include <math.h> // Required for: sqrtf(), sinf(), cosf(), floor(), log()
#include <stdlib.h> // Required for: calloc(), free()
#include <string.h> // Required for: strcmp(), strlen() [Used in rlglInit(), on extensions loading]
#include <math.h> // Required for: sqrtf(), sinf(), cosf(), floor(), log()
#include <limits.h> // Required for: INT_MAX
//----------------------------------------------------------------------------------
// Defines and Macros
@ -5236,7 +5237,9 @@ static int rlGetPixelDataSize(int width, int height, int format)
{
int blockWidth = (width + 3)/4;
int blockHeight = (height + 3)/4;
dataSize = blockWidth*blockHeight*8;
unsigned long long dataSizeBytes = blockWidth*blockHeight*8;
if (dataSizeBytes < INT_MAX) dataSize = (int)dataSizeBytes;
} break;
case RL_PIXELFORMAT_COMPRESSED_DXT3_RGBA:
case RL_PIXELFORMAT_COMPRESSED_DXT5_RGBA:
@ -5245,13 +5248,17 @@ static int rlGetPixelDataSize(int width, int height, int format)
{
int blockWidth = (width + 3)/4;
int blockHeight = (height + 3)/4;
dataSize = blockWidth*blockHeight*16;
unsigned long long dataSizeBytes = blockWidth*blockHeight*16;
if (dataSizeBytes < INT_MAX) dataSize = (int)dataSizeBytes;
} break;
case RL_PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA: // 4 bytes per each 4x4 block
{
int blockWidth = (width + 3)/4;
int blockHeight = (height + 3)/4;
dataSize = blockWidth*blockHeight*4;
unsigned long long dataSizeBytes = blockWidth*blockHeight*4;
if (dataSizeBytes < INT_MAX) dataSize = (int)dataSizeBytes;
} break;
default: break;
}
@ -5260,9 +5267,11 @@ static int rlGetPixelDataSize(int width, int height, int format)
if ((format >= RL_PIXELFORMAT_UNCOMPRESSED_GRAYSCALE) &&
(format <= RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16A16))
{
double bytesPerPixel = (double)bpp/8.0;
dataSize = (int)(bytesPerPixel*width*height); // Total data size in bytes
unsigned long long dataSizeBytes = (width*height*bpp) >> 3; // Get size in bytes (dividing by 8)
if (dataSizeBytes < INT_MAX) dataSize = (int)dataSizeBytes;
}
if (dataSize == 0) TRACELOG(LOG_WARNING, "Requested image size is larger than 2GB, it can not be allocated");
return dataSize;
}

View File

@ -2320,7 +2320,7 @@ void UpdateModelAnimation(Model model, ModelAnimation anim, float frame)
Matrix currentPoseMatrix = { 0 };
// Update all bones and bone matrices of model
for (int boneIndex = 0; boneIndex < model.skeleton.boneCount; boneIndex++)
for (unsigned int boneIndex = 0; boneIndex < model.skeleton.boneCount; boneIndex++)
{
// Compute interpolated pose between current and next frame
// NOTE: Storing animation frame data in model.currentPose
@ -2390,7 +2390,7 @@ void UpdateModelAnimationEx(Model model, ModelAnimation animA, float frameA, Mod
Matrix bindPoseMatrix = { 0 };
Matrix currentPoseMatrix = { 0 };
for (int boneIndex = 0; boneIndex < model.skeleton.boneCount; boneIndex++)
for (unsigned int boneIndex = 0; boneIndex < model.skeleton.boneCount; boneIndex++)
{
// Get frame-interpolation for first animation
Vector3 frameATranslation = Vector3Lerp(
@ -5013,7 +5013,7 @@ static Model LoadIQM(const char *fileName)
// Initialize runtime animation data: current pose and bone matrices
model.currentPose = (Transform *)RL_CALLOC(model.skeleton.boneCount, sizeof(Transform));
model.boneMatrices = (Matrix *)RL_CALLOC(model.skeleton.boneCount, sizeof(Matrix));
for (int j = 0; j < model.skeleton.boneCount; j++) model.boneMatrices[j] = MatrixIdentity();
for (unsigned int j = 0; j < model.skeleton.boneCount; j++) model.boneMatrices[j] = MatrixIdentity();
UnloadFileData(fileData);
@ -5241,7 +5241,7 @@ static ModelAnimation *LoadModelAnimationsIQM(const char *fileName, int *animCou
// Build frameposes
for (unsigned int frame = 0; frame < anim[a].num_frames; frame++)
{
for (int i = 0; i < animations[a].boneCount; i++)
for (unsigned int i = 0; i < animations[a].boneCount; i++)
{
if (bones[i].parent >= 0)
{
@ -5371,7 +5371,7 @@ static Image LoadImageFromCgltfImage(cgltf_image *cgltfImage, const char *texPat
// Load bone info from GLTF skin data
static BoneInfo *LoadBoneInfoGLTF(cgltf_skin skin, unsigned int *boneCount)
{
*boneCount = skin.joints_count;
*boneCount = (unsigned int)skin.joints_count;
BoneInfo *bones = (BoneInfo *)RL_CALLOC(skin.joints_count, sizeof(BoneInfo));
for (unsigned int i = 0; i < skin.joints_count; i++)
@ -6144,7 +6144,7 @@ static Model LoadGLTF(const char *fileName)
model.skeleton.bones = LoadBoneInfoGLTF(skin, &model.skeleton.boneCount);
model.skeleton.bindPose = (Transform *)RL_CALLOC(model.skeleton.boneCount, sizeof(Transform));
for (int i = 0; i < model.skeleton.boneCount; i++)
for (unsigned int i = 0; i < model.skeleton.boneCount; i++)
{
Matrix bindMatrix = { 0 };
cgltf_float inverseBindTransform[16] = { 0 };
@ -6309,7 +6309,7 @@ static Model LoadGLTF(const char *fileName)
if ((data->skins_count > 0) && !hasJoints && (node->parent != NULL) && (node->parent->mesh == NULL))
{
int parentBoneId = -1;
for (int joint = 0; joint < model.skeleton.boneCount; joint++)
for (unsigned int joint = 0; joint < model.skeleton.boneCount; joint++)
{
if (data->skins[0].joints[joint] == node->parent)
{
@ -6347,7 +6347,7 @@ static Model LoadGLTF(const char *fileName)
// Initialize runtime animation data: current pose and bone matrices
model.currentPose = (Transform *)RL_CALLOC(model.skeleton.boneCount, sizeof(Transform));
model.boneMatrices = (Matrix *)RL_CALLOC(model.skeleton.boneCount, sizeof(Matrix));
for (int j = 0; j < model.skeleton.boneCount; j++) model.boneMatrices[j] = MatrixIdentity();
for (unsigned int j = 0; j < model.skeleton.boneCount; j++) model.boneMatrices[j] = MatrixIdentity();
//----------------------------------------------------------------------------------------------------
// Free unused allocated memory in case of no bones defined
@ -6670,7 +6670,7 @@ static ModelAnimation *LoadModelAnimationsGLTF(const char *fileName, int *animCo
animations[a].keyframePoses[j] = (Transform *)RL_CALLOC(animations[a].boneCount, sizeof(Transform));
float time = (float)j / GLTF_FRAMERATE;
for (int k = 0; k < animations[a].boneCount; k++)
for (unsigned int k = 0; k < animations[a].boneCount; k++)
{
Vector3 translation = {skin.joints[k]->translation[0], skin.joints[k]->translation[1], skin.joints[k]->translation[2]};
Quaternion rotation = {skin.joints[k]->rotation[0], skin.joints[k]->rotation[1], skin.joints[k]->rotation[2], skin.joints[k]->rotation[3]};
@ -7204,7 +7204,7 @@ static Model LoadM3D(const char *fileName)
// Initialize runtime animation data: current pose and bone matrices
model.currentPose = (Transform *)RL_CALLOC(model.skeleton.boneCount, sizeof(Transform));
model.boneMatrices = (Matrix *)RL_CALLOC(model.skeleton.boneCount, sizeof(Matrix));
for (int j = 0; j < model.skeleton.boneCount; j++) model.boneMatrices[j] = MatrixIdentity();
for (unsigned int j = 0; j < model.skeleton.boneCount; j++) model.boneMatrices[j] = MatrixIdentity();
}
m3d_free(m3d);

View File

@ -1699,7 +1699,7 @@ const char *TextSubtext(const char *text, int position, int length)
static char buffer[MAX_TEXT_BUFFER_LENGTH] = { 0 };
memset(buffer, 0, MAX_TEXT_BUFFER_LENGTH);
if (text != NULL)
if ((text != NULL) && (position > 0) && (length > 0))
{
int textLength = TextLength(text);
@ -1975,10 +1975,11 @@ char *TextInsert(const char *text, const char *insert, int position)
{
static char buffer[MAX_TEXT_BUFFER_LENGTH] = { 0 };
memset(buffer, 0, MAX_TEXT_BUFFER_LENGTH);
int textLen = TextLength(text);
if ((text != NULL) && (insert != NULL))
if ((text != NULL) && (insert != NULL) && (position >= 0))
{
int textLen = TextLength(text);
if (position > textLen) position = textLen; // End of text string
int insertLen = TextLength(insert);
if ((textLen + insertLen) < (MAX_TEXT_BUFFER_LENGTH - 1))
@ -1987,7 +1988,7 @@ char *TextInsert(const char *text, const char *insert, int position)
for (int i = 0; i < position; i++) buffer[i] = text[i];
for (int i = position; i < insertLen + position; i++) buffer[i] = insert[i - position];
for (int i = (insertLen + position); i < (textLen + insertLen); i++) buffer[i] = text[i];
for (int i = (insertLen + position); i < (textLen + insertLen); i++) buffer[i] = text[i - insertLen];
buffer[textLen + insertLen] = '\0'; // Add EOL
}
@ -2002,17 +2003,18 @@ char *TextInsert(const char *text, const char *insert, int position)
char *TextInsertAlloc(const char *text, const char *insert, int position)
{
char *result = NULL;
int textLen = TextLength(text);
if ((text != NULL) && (insert != NULL))
if ((text != NULL) && (insert != NULL) && (position >= 0))
{
int textLen = TextLength(text);
if (position > textLen) position = textLen; // End of text string
int insertLen = TextLength(insert);
result = (char *)RL_MALLOC(textLen + insertLen + 1);
for (int i = 0; i < position; i++) result[i] = text[i];
for (int i = position; i < insertLen + position; i++) result[i] = insert[i - position];
for (int i = (insertLen + position); i < (textLen + insertLen); i++) result[i] = text[i];
for (int i = position; i < (insertLen + position); i++) result[i] = insert[i - position];
for (int i = (insertLen + position); i < (textLen + insertLen + position); i++) result[i] = text[i - insertLen];
result[textLen + insertLen] = '\0'; // Add EOL
}
@ -2036,7 +2038,7 @@ char *TextJoin(char **textList, int count, const char *delimiter)
int textLength = TextLength(textList[i]);
// Make sure joined text could fit inside MAX_TEXT_BUFFER_LENGTH
if ((totalLength + textLength) < MAX_TEXT_BUFFER_LENGTH)
if ((totalLength + textLength + delimiterLen) < MAX_TEXT_BUFFER_LENGTH)
{
memcpy(textPtr, textList[i], textLength);
totalLength += textLength;

View File

@ -70,6 +70,7 @@
#include <string.h> // Required for: strlen() [Used in ImageTextEx()], strcmp() [Used in LoadImageFromMemory()/LoadImageAnimFromMemory()/ExportImageToMemory()]
#include <math.h> // Required for: fabsf() [Used in DrawTextureRec()]
#include <stdio.h> // Required for: sprintf() [Used in ExportImageAsCode()]
#include <limits.h> // Required for: INT_MAX
// Support only desired texture formats on stb_image
#if !SUPPORT_FILEFORMAT_BMP
@ -843,9 +844,10 @@ bool ExportImageAsCode(Image image, const char *fileName)
// Generate image: plain color
Image GenImageColor(int width, int height, Color color)
{
Color *pixels = (Color *)RL_CALLOC(width*height, sizeof(Color));
int dataSize = GetPixelDataSize(width, height, PIXELFORMAT_UNCOMPRESSED_R8G8B8A8);
Color *pixels = (Color *)RL_CALLOC(dataSize, 1);
for (int i = 0; i < width*height; i++) pixels[i] = color;
for (int i = 0; (pixels != NULL) && (i < width*height); i++) pixels[i] = color;
Image image = {
.data = pixels,
@ -1228,18 +1230,25 @@ Image ImageFromImage(Image image, Rectangle rec)
{
Image result = { 0 };
int bytesPerPixel = GetPixelDataSize(1, 1, image.format);
result.width = (int)rec.width;
result.height = (int)rec.height;
result.data = RL_CALLOC((int)rec.width*(int)rec.height*bytesPerPixel, 1);
result.format = image.format;
result.mipmaps = 1;
for (int y = 0; y < (int)rec.height; y++)
// Basic rectangle validation: size smaller than image size
if ((rec.x > 0) && (rec.y > 0) && (rec.width > 0) && (rec.height > 0) &&
(((int)rec.x + (int)rec.width) < image.width) &&
(((int)rec.y + (int)rec.height) < image.height))
{
memcpy(((unsigned char *)result.data) + y*(int)rec.width*bytesPerPixel, ((unsigned char *)image.data) + ((y + (int)rec.y)*image.width + (int)rec.x)*bytesPerPixel, (int)rec.width*bytesPerPixel);
int bytesPerPixel = GetPixelDataSize(1, 1, image.format);
result.width = (int)rec.width;
result.height = (int)rec.height;
result.data = RL_CALLOC((int)rec.width*(int)rec.height*bytesPerPixel, 1);
result.format = image.format;
result.mipmaps = 1;
for (int y = 0; y < (int)rec.height; y++)
{
memcpy(((unsigned char *)result.data) + y*(int)rec.width*bytesPerPixel, ((unsigned char *)image.data) + ((y + (int)rec.y)*image.width + (int)rec.x)*bytesPerPixel, (int)rec.width*bytesPerPixel);
}
}
else TRACELOG(LOG_WARNING, "IMAGE: Rectangle provided for ImageToImage not valid");
return result;
}
@ -2684,45 +2693,48 @@ void ImageRotate(Image *image, int degrees)
int width = (int)(fabsf(image->width*cosRadius) + fabsf(image->height*sinRadius));
int height = (int)(fabsf(image->height*cosRadius) + fabsf(image->width*sinRadius));
int bytesPerPixel = GetPixelDataSize(1, 1, image->format);
unsigned char *rotatedData = (unsigned char *)RL_CALLOC(width*height, bytesPerPixel);
int bytesPerPixel = GetPixelDataSize(width, height, image->format);
unsigned char *rotatedData = (unsigned char *)RL_CALLOC(bytesPerPixel, 1);
for (int y = 0; y < height; y++)
if (rotatedData != NULL)
{
for (int x = 0; x < width; x++)
for (int y = 0; y < height; y++)
{
float oldX = ((x - width/2.0f)*cosRadius + (y - height/2.0f)*sinRadius) + image->width/2.0f;
float oldY = ((y - height/2.0f)*cosRadius - (x - width/2.0f)*sinRadius) + image->height/2.0f;
if ((oldX >= 0) && (oldX < image->width) && (oldY >= 0) && (oldY < image->height))
for (int x = 0; x < width; x++)
{
int x1 = (int)floorf(oldX);
int y1 = (int)floorf(oldY);
int x2 = MIN(x1 + 1, image->width - 1);
int y2 = MIN(y1 + 1, image->height - 1);
float oldX = ((x - width/2.0f)*cosRadius + (y - height/2.0f)*sinRadius) + image->width/2.0f;
float oldY = ((y - height/2.0f)*cosRadius - (x - width/2.0f)*sinRadius) + image->height/2.0f;
float px = oldX - x1;
float py = oldY - y1;
for (int i = 0; i < bytesPerPixel; i++)
if ((oldX >= 0) && (oldX < image->width) && (oldY >= 0) && (oldY < image->height))
{
float f1 = ((unsigned char *)image->data)[(y1*image->width + x1)*bytesPerPixel + i];
float f2 = ((unsigned char *)image->data)[(y1*image->width + x2)*bytesPerPixel + i];
float f3 = ((unsigned char *)image->data)[(y2*image->width + x1)*bytesPerPixel + i];
float f4 = ((unsigned char *)image->data)[(y2*image->width + x2)*bytesPerPixel + i];
int x1 = (int)floorf(oldX);
int y1 = (int)floorf(oldY);
int x2 = MIN(x1 + 1, image->width - 1);
int y2 = MIN(y1 + 1, image->height - 1);
float val = f1*(1 - px)*(1 - py) + f2*px*(1 - py) + f3*(1 - px)*py + f4*px*py;
float px = oldX - x1;
float py = oldY - y1;
rotatedData[(y*width + x)*bytesPerPixel + i] = (unsigned char)val;
for (int i = 0; i < bytesPerPixel; i++)
{
float f1 = ((unsigned char *)image->data)[(y1*image->width + x1)*bytesPerPixel + i];
float f2 = ((unsigned char *)image->data)[(y1*image->width + x2)*bytesPerPixel + i];
float f3 = ((unsigned char *)image->data)[(y2*image->width + x1)*bytesPerPixel + i];
float f4 = ((unsigned char *)image->data)[(y2*image->width + x2)*bytesPerPixel + i];
float val = f1*(1 - px)*(1 - py) + f2*px*(1 - py) + f3*(1 - px)*py + f4*px*py;
rotatedData[(y*width + x)*bytesPerPixel + i] = (unsigned char)val;
}
}
}
}
}
RL_FREE(image->data);
image->data = rotatedData;
image->width = width;
image->height = height;
RL_FREE(image->data);
image->data = rotatedData;
image->width = width;
image->height = height;
}
}
}
@ -5501,17 +5513,24 @@ int GetPixelDataSize(int width, int height, int format)
case PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA: bpp = 2; break;
default: break;
}
unsigned long long dataSizeBytes = (width*height*bpp) >> 3; // Get size in bytes (dividing by 8)
double bytesPerPixel = (double)bpp/8.0;
dataSize = (int)(bytesPerPixel*width*height); // Total data size in bytes
// Most compressed formats works on 4x4 blocks,
// if texture is smaller, minimum dataSize is 8 or 16
if ((width < 4) && (height < 4))
if (dataSizeBytes < INT_MAX)
{
if ((format >= PIXELFORMAT_COMPRESSED_DXT1_RGB) && (format < PIXELFORMAT_COMPRESSED_DXT3_RGBA)) dataSize = 8;
else if ((format >= PIXELFORMAT_COMPRESSED_DXT3_RGBA) && (format < PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA)) dataSize = 16;
dataSize = (int)dataSizeBytes;
// Most compressed formats works on 4x4 blocks,
// if texture is smaller, minimum dataSize is 8 or 16
if ((width < 4) && (height < 4))
{
if ((format >= PIXELFORMAT_COMPRESSED_DXT1_RGB) && (format < PIXELFORMAT_COMPRESSED_DXT3_RGBA)) dataSize = 8;
else if ((format >= PIXELFORMAT_COMPRESSED_DXT3_RGBA) && (format < PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA)) dataSize = 16;
}
}
// NOTE: In case required image data larger than 2GB, no memory allocated at all (NULL)
if (dataSize == 0) TRACELOG(LOG_WARNING, "Requested image size is larger than 2GB, it can not be allocated");
return dataSize;
}