Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Increased performance for png art loading by 2.5-3x #996

Merged
merged 1 commit into from
Jun 16, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
56 changes: 37 additions & 19 deletions src/textures.c
Original file line number Diff line number Diff line change
Expand Up @@ -306,10 +306,10 @@ typedef struct

static png_texture_t pngTexture;

static int texPngEnd(png_structp pngPtr, png_infop infoPtr, FILE *file, int status)
AKuHAK marked this conversation as resolved.
Show resolved Hide resolved
static int texPngEnd(png_structp pngPtr, png_infop infoPtr, void *pFileBuffer, int status)
{
if (file != NULL)
fclose(file);
if (pFileBuffer != NULL)
free(pFileBuffer);

if (infoPtr != NULL)
png_destroy_read_struct(&pngPtr, &infoPtr, (png_infopp)NULL);
Expand Down Expand Up @@ -465,15 +465,36 @@ static int texPngLoadAll(GSTEXTURE *texture, const char *filePath, int texId)
png_infop infoPtr = NULL;
png_voidp readData = NULL;
png_rw_ptr readFunction = NULL;
FILE *file = NULL;
void **PngFileBufferPtr;
void *PngFileBufferPtr;
void *pFileBuffer = NULL;

if (filePath) {
file = fopen(filePath, "rb");
if (file == NULL)
int fd = open(filePath, O_RDONLY, 0);
if (fd == -1)
return ERR_BAD_FILE;

readFunction = NULL; // Use default reading function.
int fileSize = lseek(fd, 0, SEEK_END);
lseek(fd, 0, SEEK_SET);

pFileBuffer = malloc(fileSize);
if (pFileBuffer == NULL) {
close(fd);
return ERR_BAD_FILE; // There's no out of memory error...
}

int readSize = read(fd, pFileBuffer, fileSize);
close(fd);
fd = -1;

if (readSize != fileSize) {
LOG("texPngLoadAll: failed to read file %s\n", filePath);
free(pFileBuffer);
return ERR_BAD_FILE;
}

PngFileBufferPtr = pFileBuffer;
readData = &PngFileBufferPtr;
readFunction = &texPngReadMemFunction;
} else {
if (texId == -1)
return ERR_BAD_FILE;
Expand All @@ -487,19 +508,16 @@ static int texPngLoadAll(GSTEXTURE *texture, const char *filePath, int texId)

pngPtr = png_create_read_struct(PNG_LIBPNG_VER_STRING, (png_voidp)NULL, NULL, NULL);
if (!pngPtr)
return texPngEnd(pngPtr, infoPtr, file, ERR_READ_STRUCT);
return texPngEnd(pngPtr, infoPtr, pFileBuffer, ERR_READ_STRUCT);

infoPtr = png_create_info_struct(pngPtr);
if (!infoPtr)
return texPngEnd(pngPtr, infoPtr, file, ERR_INFO_STRUCT);
return texPngEnd(pngPtr, infoPtr, pFileBuffer, ERR_INFO_STRUCT);

if (setjmp(png_jmpbuf(pngPtr)))
return texPngEnd(pngPtr, infoPtr, file, ERR_SET_JMP);
return texPngEnd(pngPtr, infoPtr, pFileBuffer, ERR_SET_JMP);

if (readFunction != NULL)
png_set_read_fn(pngPtr, readData, readFunction);
else
png_init_io(pngPtr, file);
png_set_read_fn(pngPtr, readData, readFunction);

unsigned int sigRead = 0;
png_set_sig_bytes(pngPtr, sigRead);
Expand Down Expand Up @@ -556,21 +574,21 @@ static int texPngLoadAll(GSTEXTURE *texture, const char *filePath, int texId)

texPngReadPixels = &texPngReadPixels8;
} else
return texPngEnd(pngPtr, infoPtr, file, ERR_BAD_DEPTH);
return texPngEnd(pngPtr, infoPtr, pFileBuffer, ERR_BAD_DEPTH);
break;
default:
return texPngEnd(pngPtr, infoPtr, file, ERR_BAD_DEPTH);
return texPngEnd(pngPtr, infoPtr, pFileBuffer, ERR_BAD_DEPTH);
}

if (texSizeValidate(texture->Width, texture->Height, texture->PSM) < 0) {
texFree(texture);

return texPngEnd(pngPtr, infoPtr, file, ERR_BAD_DIMENSION);
return texPngEnd(pngPtr, infoPtr, pFileBuffer, ERR_BAD_DIMENSION);
}

texPngReadData(texture, pngPtr, infoPtr, texPngReadPixels);

return texPngEnd(pngPtr, infoPtr, file, 0);
return texPngEnd(pngPtr, infoPtr, pFileBuffer, 0);
}

static int texPngLoad(GSTEXTURE *texture, const char *filePath)
Expand Down