aboutsummaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorNebuleon Fumika2013-03-29 22:04:27 -0400
committerNebuleon Fumika2013-03-29 22:04:27 -0400
commitfa71ce73458c91ef8cbdbdb2f3beeb6d820e25e2 (patch)
treec501687b952f03a2e6cb7b9f6b3d80d7daeda96c /source
parent2113821e237995b9a749c367dc9db5db2fffd378 (diff)
downloadsnes9x2005-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.c42
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;