diff options
author | Nebuleon Fumika | 2013-03-29 22:04:27 -0400 |
---|---|---|
committer | Nebuleon Fumika | 2013-03-29 22:04:27 -0400 |
commit | fa71ce73458c91ef8cbdbdb2f3beeb6d820e25e2 (patch) | |
tree | c501687b952f03a2e6cb7b9f6b3d80d7daeda96c /source | |
parent | 2113821e237995b9a749c367dc9db5db2fffd378 (diff) | |
download | snes9x2005-fa71ce73458c91ef8cbdbdb2f3beeb6d820e25e2.tar.gz snes9x2005-fa71ce73458c91ef8cbdbdb2f3beeb6d820e25e2.tar.bz2 snes9x2005-fa71ce73458c91ef8cbdbdb2f3beeb6d820e25e2.zip |
Optimise the reading of bitmap files.
Diffstat (limited to 'source')
-rw-r--r-- | source/nds/bitmap.c | 42 |
1 files changed, 31 insertions, 11 deletions
diff --git a/source/nds/bitmap.c b/source/nds/bitmap.c index bda4cf7..efeb11c 100644 --- a/source/nds/bitmap.c +++ b/source/nds/bitmap.c @@ -20,6 +20,7 @@ #include "fs_api.h" #include "bitmap.h" +#include "ds2_malloc.h" int BMP_read(char* filename, char *buf, unsigned int width, unsigned int height, unsigned int* type) { @@ -59,16 +60,22 @@ int BMP_read(char* filename, char *buf, unsigned int width, unsigned int height, bmp_header.bfImghead.imColnum= st[23] | (st[24]<<16); bmp_header.bfImghead.imImcolnum= st[25] | (st[26]<<16); - if(bmp_header.bfType != 0x4D42) //"BM" + if(bmp_header.bfType != 0x4D42) { //"BM" + fclose(fp); return BMP_ERR_FORMATE; + } if(bmp_header.bfImghead.imCompess != BI_RGB && - bmp_header.bfImghead.imCompess != BI_BITFIELDS) + bmp_header.bfImghead.imCompess != BI_BITFIELDS) { + fclose(fp); return BMP_ERR_NEED_GO_ON; //This funciton now not support... + } bytepixel= bmp_header.bfImghead.imBitpixel >> 3; - if(bytepixel < 2) //byte per pixel >= 2 + if(bytepixel < 2) { //byte per pixel >= 2 + fclose(fp); return BMP_ERR_NEED_GO_ON; //This funciton now not support... + } *type = bytepixel; @@ -81,16 +88,29 @@ int BMP_read(char* filename, char *buf, unsigned int width, unsigned int height, if(y > sy) y= sy; - //BMP scan from down to up - fpos= (s32)bmp_header.bfImgoffst; - dest= (unsigned char*)buf+(y-1)*x*bytepixel; - for(m= 0; m < y; m++) { - fseek(fp, fpos, SEEK_SET); - fread(dest, 1, x*bytepixel, fp); - fpos += ((sx*bytepixel+3)>>2)<<2; - dest -= x*bytepixel; + // Expect a certain amount of bytes and read them all at once. + unsigned int BytesPerLine = (sx * bytepixel + 3) & ~3; + char* FileBuffer = (char*) malloc(BytesPerLine * (sy - 1) + sx * bytepixel); + if (FileBuffer == NULL) { + fclose(fp); + return BMP_ERR_NEED_GO_ON; // Memory allocation error + } + + fseek(fp, (s32) bmp_header.bfImgoffst, SEEK_SET); + m = fread(FileBuffer, 1, BytesPerLine * (sy - 1) + sx * bytepixel, fp); + + if (m < BytesPerLine * (sy - 1) + sx * bytepixel) { + free(FileBuffer); + fclose(fp); + return BMP_ERR_FORMATE; // incomplete file + } + + // Reorder all the bytes, because scanlines are from bottom to top. + for (m = 0; m < y; m++) { + memcpy(buf + m * x * bytepixel, FileBuffer + (sy - m - 1) * BytesPerLine, x * bytepixel); } + free(FileBuffer); fclose(fp); return BMP_OK; |