From fb29f601f1d5e4c74af9c0d7f53cdf9b57f2cb85 Mon Sep 17 00:00:00 2001 From: inmarket Date: Sun, 5 Jan 2014 00:02:53 +1000 Subject: Start of GFILE module --- src/gfile/gfile.c | 225 +++++++++++++++++++++++++++++++++++++++++++++++ src/gfile/gfile.mk | 1 + src/gfile/inc_fatfs.c | 15 ++++ src/gfile/inc_nativefs.c | 81 +++++++++++++++++ src/gfile/inc_ramfs.c | 15 ++++ src/gfile/inc_romfs.c | 97 ++++++++++++++++++++ 6 files changed, 434 insertions(+) create mode 100644 src/gfile/gfile.c create mode 100644 src/gfile/gfile.mk create mode 100644 src/gfile/inc_fatfs.c create mode 100644 src/gfile/inc_nativefs.c create mode 100644 src/gfile/inc_ramfs.c create mode 100644 src/gfile/inc_romfs.c (limited to 'src') diff --git a/src/gfile/gfile.c b/src/gfile/gfile.c new file mode 100644 index 00000000..bf76e8bc --- /dev/null +++ b/src/gfile/gfile.c @@ -0,0 +1,225 @@ +/* + * This file is subject to the terms of the GFX License. If a copy of + * the license was not distributed with this file, you can obtain one at: + * + * http://ugfx.org/license.html + */ + +/** + * @file src/gfile/gfile.c + * @brief GFILE code. + * + */ + +#define GFILE_IMPLEMENTATION +#include "gfx.h" + +#if GFX_USE_GFILE + +// The chain of FileSystems +#define GFILE_CHAINHEAD 0 + +// The table of GFILE's +static GFILE gfileArr[GFILE_MAX_GFILES]; +GFILE *gfileStdIn; +GFILE *gfileStdOut; +GFILE *gfileStdErr; + +/** + * The order of the file-systems below determines the order + * that they are searched to find a file. + * The last defined is the first searched. + */ + +/******************************************************** + * The RAM file-system VMT + ********************************************************/ +#if GFILE_NEED_RAMFS + #include "../src/gfile/inc_ramfs.c" +#endif + +/******************************************************** + * The FAT file-system VMT + ********************************************************/ +#ifndef GFILE_NEED_FATFS + #include "../src/gfile/inc_fatfs.c" +#endif + +/******************************************************** + * The native file-system + ********************************************************/ +#if GFILE_NEED_NATIVEFS + #include "../src/gfile/inc_nativefs.c" +#endif + +/******************************************************** + * The ROM file-system VMT + ********************************************************/ +#if GFILE_NEED_ROMFS + #include "../src/gfile/inc_romfs.c" +#endif + +/******************************************************** + * IO routines + ********************************************************/ + +/** + * The chain of file systems. + */ +static const GFILEVMT const * FsChain = GFILE_CHAINHEAD; + +/** + * The init routine + */ +void _gfileInit(void) { + #if GFILE_NEED_NATIVEFS + NativeStdIn.flags = GFILEFLG_OPEN|GFILEFLG_READ; + NativeStdIn.vmt = &FsNativeVMT; + NativeStdIn.obj = (void *)stdin; + NativeStdIn.pos = 0; + gfileStdIn = &NativeStdIn; + NativeStdOut.flags = GFILEFLG_OPEN|GFILEFLG_WRITE|GFILEFLG_APPEND; + NativeStdOut.vmt = &FsNativeVMT; + NativeStdOut.obj = (void *)stdout; + NativeStdOut.pos = 0; + gfileStdOut = &NativeStdOut; + NativeStdErr.flags = GFILEFLG_OPEN|GFILEFLG_WRITE|GFILEFLG_APPEND; + NativeStdErr.vmt = &FsNativeVMT; + NativeStdErr.obj = (void *)stderr; + NativeStdErr.pos = 0; + gfileStdErr = &NativeStdErr; + #endif +} + +bool_t gfileExists(const char *fname) { + const GFILEVMT *p; + + if (fname[0] && fname[1] == '|') { + for(p = FsChain; p; p = p->next) { + if (p->prefix == fname[0]) + return p->exists && p->exists(fname+2); + } + } else { + for(p = FsChain; p; p = p->next) { + if (p->exists && p->exists(fname)) + return TRUE; + } + } + return FALSE; +} + +bool_t gfileDelete(const char *fname) { + const GFILEVMT *p; + + if (fname[0] && fname[1] == '|') { + for(p = FsChain; p; p = p->next) { + if (p->prefix == fname[0]) + return p->del && p->del(fname+2); + } + } else { + for(p = FsChain; p; p = p->next) { + if (p->del && p->del(fname)) + return TRUE; + } + } + return FALSE; +} + +long int gfileGetFilesize(const char *fname) { + const GFILEVMT *p; + + if (fname[0] && fname[1] == '|') { + for(p = FsChain; p; p = p->next) { + if (p->prefix == fname[0]) + return p->filesize ? p->filesize(fname+2) : -1; + } + } else { + long int res; + + for(p = FsChain; p; p = p->next) { + if (p->filesize && (res = p->filesize(fname)) != -1) + return res; + } + } + return -1; +} + +bool_t gfileRename(const char *oldname, const char *newname) { + const GFILEVMT *p; + + if ((oldname[0] && oldname[1] == '|') || (newname[0] && newname[1])) { + char ch; + + if (oldname[0] && oldname[1] == '|') { + ch = oldname[0]; + oldname += 2; + if (newname[0] && newname[1] == '|') { + if (newname[0] != ch) + return FALSE; + newname += 2; + } + } else { + ch = newname[0]; + newname += 2; + } + for(p = FsChain; p; p = p->next) { + if (p->prefix == ch) + return p->ren && p->ren(oldname, newname); + } + } else { + for(p = FsChain; p; p = p->next) { + if (p->ren && p->ren(oldname,newname)) + return TRUE; + } + } + return FALSE; +} + +GFILE *gfileOpen(const char *fname, const char *mode) { + +} + +void gfileClose(GFILE *f) { + +} + +size_t gfileRead(GFILE *f, char *buf, size_t len) { + +} + +size_t gfileWrite(GFILE *f, const char *buf, size_t len) { + +} + +long int gfileGetPos(GFILE *f) { + +} + +bool_t gfileSetPos(GFILE *f, long int pos) { + +} + +long int gfileGetSize(GFILE *f) { + +} + +/******************************************************** + * printg routines + ********************************************************/ +#if GFILE_NEED_PRINTG +#endif + +/******************************************************** + * scang routines + ********************************************************/ +#if GFILE_NEED_SCANG +#endif + +/******************************************************** + * stdio emulation routines + ********************************************************/ +#ifndef GFILE_NEED_STDIO + #define GFILE_NEED_STDIO FALSE +#endif + +#endif /* GFX_USE_GFILE */ diff --git a/src/gfile/gfile.mk b/src/gfile/gfile.mk new file mode 100644 index 00000000..381bd6f6 --- /dev/null +++ b/src/gfile/gfile.mk @@ -0,0 +1 @@ +GFXSRC += $(GFXLIB)/src/gfile/gfile.c diff --git a/src/gfile/inc_fatfs.c b/src/gfile/inc_fatfs.c new file mode 100644 index 00000000..d49cfe7a --- /dev/null +++ b/src/gfile/inc_fatfs.c @@ -0,0 +1,15 @@ +/* + * This file is subject to the terms of the GFX License. If a copy of + * the license was not distributed with this file, you can obtain one at: + * + * http://ugfx.org/license.html + */ + +/** + * This file is included by src/gfile/gfile.c + */ + +/******************************************************** + * The FAT file-system VMT + ********************************************************/ +#error "GFILE: FATFS Not implemented yet" diff --git a/src/gfile/inc_nativefs.c b/src/gfile/inc_nativefs.c new file mode 100644 index 00000000..7828ff84 --- /dev/null +++ b/src/gfile/inc_nativefs.c @@ -0,0 +1,81 @@ +/* + * This file is subject to the terms of the GFX License. If a copy of + * the license was not distributed with this file, you can obtain one at: + * + * http://ugfx.org/license.html + */ + +/** + * This file is included by src/gfile/gfile.c + */ + +/******************************************************** + * The native file-system + ********************************************************/ + +#include +#include +#include +#include + +static GFILE NativeStdIn; +static GFILE NativeStdOut; +static GFILE NativeStdErr; + +static bool_t NativeDel(const char *fname); +static bool_t NativeExists(const char *fname); +static long int NativeFilesize(const char *fname); +static bool_t NativeRen(const char *oldname, const char *newname); +static bool_t NativeOpen(GFILE *f, const char *fname, const char *mode); +static void NativeClose(GFILE *f); +static int NativeRead(GFILE *f, char *buf, int size); +static int NativeWrite(GFILE *f, char *buf, int size); +static bool_t NativeSetpos(GFILE *f, long int pos); +static long int NativeGetsize(GFILE *f); +static bool_t NativeEof(GFILE *f); + +static const GFILEVMT FsNativeVMT = { + GFILE_CHAINHEAD, // next + 'N', // prefix + #if !defined(WIN32) && !GFX_USE_OS_WIN32 + GFSFLG_CASESENSITIVE| + #endif + GFSFLG_WRITEABLE|GFSFLG_SEEKABLE|GFSFLG_FAST, // flags + NativeDel, NativeExists, NativeFilesize, NativeRen, + NativeOpen, NativeClose, NativeRead, NativeWrite, + NativeSetpos, NativeGetsize, NativeEof, +}; +#undef GFILE_CHAINHEAD +#define GFILE_CHAINHEAD &FsNativeVMT + +static bool_t NativeDel(const char *fname) { return remove(fname) ? FALSE : TRUE; } +static bool_t NativeExists(const char *fname) { return access(fname, 0) ? FALSE : TRUE; } +static long int NativeFilesize(const char *fname) { + struct stat st; + if (stat(fname, &st)) return -1; + return st.st_size; +} +static bool_t NativeRen(const char *oldname, const char *newname) { return rename(oldname, newname) ? FALSE : TRUE }; +static bool_t NativeOpen(GFILE *f, const char *fname, const char *mode) { + FILE *fd; + + if (!(fd = fopen(fname, mode))) + return FALSE; + f->vmt = &FsNativeVMT; + f->obj = (void *)fd; + return TRUE; +} +static void NativeClose(GFILE *f) { fclose((FILE *)f->obj); } +static int NativeRead(GFILE *f, char *buf, int size) { return fread(buf, 1, size, (FILE *)f->obj); } +static int NativeWrite(GFILE *f, char *buf, int size) { return fwrite(buf, 1, size, (FILE *)f->obj); } +static bool_t NativeSetpos(GFILE *f, long int pos) { + if (fseek((FILE *)f->obj, pos, SEEK_SET)) return FALSE; + f->pos = pos; + return TRUE; +} +static long int NativeGetsize(GFILE *f) { + struct stat st; + if (fstat(fileno((FILE *)f->obj), &st)) return -1; + return st.st_size; +} +static bool_t NativeEof(GFILE *f) { return feof((FILE *)f->obj) ? TRUE : FALSE; } diff --git a/src/gfile/inc_ramfs.c b/src/gfile/inc_ramfs.c new file mode 100644 index 00000000..b0f0d052 --- /dev/null +++ b/src/gfile/inc_ramfs.c @@ -0,0 +1,15 @@ +/* + * This file is subject to the terms of the GFX License. If a copy of + * the license was not distributed with this file, you can obtain one at: + * + * http://ugfx.org/license.html + */ + +/** + * This file is included by src/gfile/gfile.c + */ + +/******************************************************** + * The RAM file-system VMT + ********************************************************/ +#error "GFILE: RAMFS Not implemented yet" diff --git a/src/gfile/inc_romfs.c b/src/gfile/inc_romfs.c new file mode 100644 index 00000000..321dc9b1 --- /dev/null +++ b/src/gfile/inc_romfs.c @@ -0,0 +1,97 @@ +/* + * This file is subject to the terms of the GFX License. If a copy of + * the license was not distributed with this file, you can obtain one at: + * + * http://ugfx.org/license.html + */ + +/** + * This file is included by src/gfile/gfile.c + */ + +/******************************************************** + * The ROM file-system VMT + ********************************************************/ + +#include + +typedef struct ROMFS_DIRENTRY { + const struct ROMFS_DIRENTRY * next; + const char * name; + long int size; + const char * file; +} ROMFS_DIRENTRY; + +#define ROMFS_DIRENTRY_HEAD 0 + +#include "romfs_files.h" + +static const ROMFS_DIRENTRY const *FsROMHead = ROMFS_DIRENTRY_HEAD; + +static bool_t ROMExists(const char *fname); +static long int ROMFilesize(const char *fname); +static bool_t ROMOpen(GFILE *f, const char *fname, const char *mode); +static void ROMClose(GFILE *f); +static int ROMRead(GFILE *f, char *buf, int size); +static bool_t ROMSetpos(GFILE *f, long int pos); +static long int ROMGetsize(GFILE *f); +static bool_t ROMEof(GFILE *f); + +static const GFILEVMT FsROMVMT = { + GFILE_CHAINHEAD, // next + 'S', // prefix + GFSFLG_CASESENSITIVE|GFSFLG_SEEKABLE|GFSFLG_FAST, // flags + 0, ROMExists, ROMFilesize, 0, + ROMOpen, ROMClose, ROMRead, 0, + ROMSetpos, ROMGetsize, ROMEof, +}; +#undef GFILE_CHAINHEAD +#define GFILE_CHAINHEAD &FsROMVMT + +static ROMFS_DIRENTRY *ROMFindFile(const char *fname) { + const ROMFS_DIRENTRY *p; + + for(p = FsROMHead; p; p = p->next) { + if (!strcmp(p->name, fname)) + break; + } + return p; +} +static bool_t ROMExists(const char *fname) { return ROMFindFile(fname) != 0; } +static long int ROMFilesize(const char *fname) { + const ROMFS_DIRENTRY *p; + + if (!(p = ROMFindFile(fname))) return -1; + return p->size; +} +static bool_t ROMOpen(GFILE *f, const char *fname, const char *mode) { + const ROMFS_DIRENTRY *p; + + // Check mode + if (mode[0] != 'r') return FALSE; + while(*++mode) { + switch(*mode) { + case '+': case 'w': case 'a': + return FALSE; + } + } + + if (!(p = ROMFindFile(fname))) return FALSE; + f->vmt = &FsROMVMT; + f->obj = (void *)p; + return TRUE; +} +static void ROMClose(GFILE *f) { (void)f; } +static int ROMRead(GFILE *f, char *buf, int size) { + const ROMFS_DIRENTRY *p; + + p = (const ROMFS_DIRENTRY *)f->obj; + if (p->size - f->pos < size) + size = p->size - f->pos; + if (size <= 0) return 0; + memcpy(buf, p->file+f->pos, size); + return size; +} +static bool_t ROMSetpos(GFILE *f, long int pos) { return pos <= ((const ROMFS_DIRENTRY *)f->obj)->size; } +static long int ROMGetsize(GFILE *f) { return ((const ROMFS_DIRENTRY *)f->obj)->size; } +static bool_t ROMEof(GFILE *f) { return f->pos >= ((const ROMFS_DIRENTRY *)f->obj)->size; } -- cgit v1.2.3 From c5ab2adbf0c14a6d0d4e2245a616d01de4b88214 Mon Sep 17 00:00:00 2001 From: inmarket Date: Fri, 24 Jan 2014 19:33:28 +1000 Subject: More code for GFile --- src/gfile/gfile.c | 93 ++++++++++++++++++++++++++++++++++++++++++++++-- src/gfile/inc_nativefs.c | 23 ++++++++++-- src/gfile/inc_romfs.c | 14 ++------ 3 files changed, 113 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/gfile/gfile.c b/src/gfile/gfile.c index bf76e8bc..83e487a1 100644 --- a/src/gfile/gfile.c +++ b/src/gfile/gfile.c @@ -147,7 +147,7 @@ long int gfileGetFilesize(const char *fname) { bool_t gfileRename(const char *oldname, const char *newname) { const GFILEVMT *p; - if ((oldname[0] && oldname[1] == '|') || (newname[0] && newname[1])) { + if ((oldname[0] && oldname[1] == '|') || (newname[0] && newname[1] == '|')) { char ch; if (oldname[0] && oldname[1] == '|') { @@ -155,6 +155,7 @@ bool_t gfileRename(const char *oldname, const char *newname) { oldname += 2; if (newname[0] && newname[1] == '|') { if (newname[0] != ch) + // Both oldname and newname are fs specific but different ones. return FALSE; newname += 2; } @@ -175,12 +176,100 @@ bool_t gfileRename(const char *oldname, const char *newname) { return FALSE; } +static uint16_t mode2flags(const char *mode) { + uint16_t flags; + + switch(mode[0]) { + case 'r': + flags = GFILEFLG_READ|GFILEFLG_MUSTEXIST; + while (*++mode) { + switch(mode[0]) { + case '+': flags |= GFILEFLG_WRITE; break; + case 'b': flags |= GFILEFLG_BINARY; break; + } + } + return flags; + case 'w': + flags = GFILEFLG_WRITE|GFILEFLG_TRUNC; + while (*++mode) { + switch(mode[0]) { + case '+': flags |= GFILEFLG_READ; break; + case 'b': flags |= GFILEFLG_BINARY; break; + case 'x': flags |= GFILEFLG_MUSTNOTEXIST; break; + } + } + return flags; + case 'a': + flags = GFILEFLG_WRITE|GFILEFLG_APPEND; + while (*++mode) { + switch(mode[0]) { + case '+': flags |= GFILEFLG_READ; break; + case 'b': flags |= GFILEFLG_BINARY; break; + case 'x': flags |= GFILEFLG_MUSTNOTEXIST; break; + } + } + return flags; + } + return 0; +} + +static bool_t testopen(const GFILEVMT *p, GFILE *f, const char *fname) { + // If we want write but the fs doesn't allow it then return + if ((f->flags & GFILEFLG_WRITE) && !(p->flags & GFSFLG_WRITEABLE)) + return FALSE; + + // Try to open + if (!p->open || !p->open(f, fname)) + return FALSE; + + // File is open - fill in all the details + f->vmt = p; + f->err = 0; + f->pos = 0; + f->flags |= GFILEFLG_OPEN; + if (p->flags & GFSFLG_SEEKABLE) + f->flags |= GFILEFLG_CANSEEK; + return TRUE; +} + GFILE *gfileOpen(const char *fname, const char *mode) { + GFILE *f; + const GFILEVMT *p; + + // First find an available GFILE slot. + for (f = gfileArr; f < &gfileArr[GFILE_MAX_GFILES]; f++) { + if (!(f->flags & GFILEFLG_OPEN)) { + + // Get the requested mode + if (!(f->flags = mode2flags(mode))) + return FALSE; + + // Try to open the file + if (fname[0] && fname[1] == '|') { + for(p = FsChain; p; p = p->next) { + if (p->prefix == fname[0]) + return testopen(p, f, fname+2); + } + } else { + for(p = FsChain; p; p = p->next) { + if (testopen(p, f, fname)) + return TRUE; + } + } + // File not found + return FALSE; + } + } + + // No available slot + return FALSE; } void gfileClose(GFILE *f) { - + // Make sure it is one of the system GFILE's + if (f < gfileArr || f >= &gfileArr[GFILE_MAX_GFILES]) + return; } size_t gfileRead(GFILE *f, char *buf, size_t len) { diff --git a/src/gfile/inc_nativefs.c b/src/gfile/inc_nativefs.c index 7828ff84..ccf1d40a 100644 --- a/src/gfile/inc_nativefs.c +++ b/src/gfile/inc_nativefs.c @@ -36,11 +36,11 @@ static bool_t NativeEof(GFILE *f); static const GFILEVMT FsNativeVMT = { GFILE_CHAINHEAD, // next - 'N', // prefix #if !defined(WIN32) && !GFX_USE_OS_WIN32 GFSFLG_CASESENSITIVE| #endif GFSFLG_WRITEABLE|GFSFLG_SEEKABLE|GFSFLG_FAST, // flags + 'N', // prefix NativeDel, NativeExists, NativeFilesize, NativeRen, NativeOpen, NativeClose, NativeRead, NativeWrite, NativeSetpos, NativeGetsize, NativeEof, @@ -48,6 +48,23 @@ static const GFILEVMT FsNativeVMT = { #undef GFILE_CHAINHEAD #define GFILE_CHAINHEAD &FsNativeVMT +static char *flags2mode(char *buf, uint16_t flags) { + if (flags & GFILEFLG_MUSTEXIST) + *buf = 'r'; + else if (flags & GFILEFLG_APPEND) + *buf = 'a'; + else + *buf = 'w'; + buf++; + if ((flags & (GFILEFLG_READ|GFILEFLG_WRITE)) == (GFILEFLG_READ|GFILEFLG_WRITE)) + *buf++ = '+'; + if (flags & GFILEFLG_BINARY) + *buf++ = 'b'; + if (flags & GFILEFLG_MUSTNOTEXIST) + *buf++ = 'x'; + *buf++ = 0; +} + static bool_t NativeDel(const char *fname) { return remove(fname) ? FALSE : TRUE; } static bool_t NativeExists(const char *fname) { return access(fname, 0) ? FALSE : TRUE; } static long int NativeFilesize(const char *fname) { @@ -56,12 +73,12 @@ static long int NativeFilesize(const char *fname) { return st.st_size; } static bool_t NativeRen(const char *oldname, const char *newname) { return rename(oldname, newname) ? FALSE : TRUE }; -static bool_t NativeOpen(GFILE *f, const char *fname, const char *mode) { +static bool_t NativeOpen(GFILE *f, const char *fname) { FILE *fd; + char mode[5]; if (!(fd = fopen(fname, mode))) return FALSE; - f->vmt = &FsNativeVMT; f->obj = (void *)fd; return TRUE; } diff --git a/src/gfile/inc_romfs.c b/src/gfile/inc_romfs.c index 321dc9b1..170b9a6c 100644 --- a/src/gfile/inc_romfs.c +++ b/src/gfile/inc_romfs.c @@ -39,8 +39,8 @@ static bool_t ROMEof(GFILE *f); static const GFILEVMT FsROMVMT = { GFILE_CHAINHEAD, // next - 'S', // prefix GFSFLG_CASESENSITIVE|GFSFLG_SEEKABLE|GFSFLG_FAST, // flags + 'S', // prefix 0, ROMExists, ROMFilesize, 0, ROMOpen, ROMClose, ROMRead, 0, ROMSetpos, ROMGetsize, ROMEof, @@ -64,20 +64,10 @@ static long int ROMFilesize(const char *fname) { if (!(p = ROMFindFile(fname))) return -1; return p->size; } -static bool_t ROMOpen(GFILE *f, const char *fname, const char *mode) { +static bool_t ROMOpen(GFILE *f, const char *fname) { const ROMFS_DIRENTRY *p; - // Check mode - if (mode[0] != 'r') return FALSE; - while(*++mode) { - switch(*mode) { - case '+': case 'w': case 'a': - return FALSE; - } - } - if (!(p = ROMFindFile(fname))) return FALSE; - f->vmt = &FsROMVMT; f->obj = (void *)p; return TRUE; } -- cgit v1.2.3 From 5bba108949ed1f97b18f1ea732553da369e8beb0 Mon Sep 17 00:00:00 2001 From: inmarket Date: Wed, 29 Jan 2014 00:37:16 +1000 Subject: More GFile code --- src/gfile/gfile.c | 526 +++++++++++++++++++++++++++++++++++++++-------- src/gfile/inc_nativefs.c | 14 +- src/gfile/inc_romfs.c | 2 +- 3 files changed, 452 insertions(+), 90 deletions(-) (limited to 'src') diff --git a/src/gfile/gfile.c b/src/gfile/gfile.c index 83e487a1..e42dc2af 100644 --- a/src/gfile/gfile.c +++ b/src/gfile/gfile.c @@ -91,87 +91,98 @@ void _gfileInit(void) { #endif } -bool_t gfileExists(const char *fname) { +bool_t gfileExists(const char *fname) { const GFILEVMT *p; - if (fname[0] && fname[1] == '|') { - for(p = FsChain; p; p = p->next) { - if (p->prefix == fname[0]) - return p->exists && p->exists(fname+2); - } - } else { - for(p = FsChain; p; p = p->next) { - if (p->exists && p->exists(fname)) - return TRUE; + #if GFILE_ALLOW_DEVICESPECIFIC + if (fname[0] && fname[1] == '|') { + for(p = FsChain; p; p = p->next) { + if (p->prefix == fname[0]) + return p->exists && p->exists(fname+2); + } + return FALSE; } + #endif + + for(p = FsChain; p; p = p->next) { + if (p->exists && p->exists(fname)) + return TRUE; } return FALSE; } -bool_t gfileDelete(const char *fname) { +bool_t gfileDelete(const char *fname) { const GFILEVMT *p; - if (fname[0] && fname[1] == '|') { - for(p = FsChain; p; p = p->next) { - if (p->prefix == fname[0]) - return p->del && p->del(fname+2); - } - } else { - for(p = FsChain; p; p = p->next) { - if (p->del && p->del(fname)) - return TRUE; + #if GFILE_ALLOW_DEVICESPECIFIC + if (fname[0] && fname[1] == '|') { + for(p = FsChain; p; p = p->next) { + if (p->prefix == fname[0]) + return p->del && p->del(fname+2); + } + return FALSE; } + #endif + + for(p = FsChain; p; p = p->next) { + if (p->del && p->del(fname)) + return TRUE; } return FALSE; } long int gfileGetFilesize(const char *fname) { const GFILEVMT *p; + long int res; - if (fname[0] && fname[1] == '|') { - for(p = FsChain; p; p = p->next) { - if (p->prefix == fname[0]) - return p->filesize ? p->filesize(fname+2) : -1; + #if GFILE_ALLOW_DEVICESPECIFIC + if (fname[0] && fname[1] == '|') { + for(p = FsChain; p; p = p->next) { + if (p->prefix == fname[0]) + return p->filesize ? p->filesize(fname+2) : -1; + } + return -1; } - } else { - long int res; + #endif - for(p = FsChain; p; p = p->next) { - if (p->filesize && (res = p->filesize(fname)) != -1) - return res; - } + for(p = FsChain; p; p = p->next) { + if (p->filesize && (res = p->filesize(fname)) != -1) + return res; } return -1; } -bool_t gfileRename(const char *oldname, const char *newname) { +bool_t gfileRename(const char *oldname, const char *newname) { const GFILEVMT *p; - if ((oldname[0] && oldname[1] == '|') || (newname[0] && newname[1] == '|')) { - char ch; - - if (oldname[0] && oldname[1] == '|') { - ch = oldname[0]; - oldname += 2; - if (newname[0] && newname[1] == '|') { - if (newname[0] != ch) - // Both oldname and newname are fs specific but different ones. - return FALSE; + #if GFILE_ALLOW_DEVICESPECIFIC + if ((oldname[0] && oldname[1] == '|') || (newname[0] && newname[1] == '|')) { + char ch; + + if (oldname[0] && oldname[1] == '|') { + ch = oldname[0]; + oldname += 2; + if (newname[0] && newname[1] == '|') { + if (newname[0] != ch) + // Both oldname and newname are fs specific but different ones. + return FALSE; + newname += 2; + } + } else { + ch = newname[0]; newname += 2; } - } else { - ch = newname[0]; - newname += 2; - } - for(p = FsChain; p; p = p->next) { - if (p->prefix == ch) - return p->ren && p->ren(oldname, newname); - } - } else { - for(p = FsChain; p; p = p->next) { - if (p->ren && p->ren(oldname,newname)) - return TRUE; + for(p = FsChain; p; p = p->next) { + if (p->prefix == ch) + return p->ren && p->ren(oldname, newname); + } + return FALSE; } + #endif + + for(p = FsChain; p; p = p->next) { + if (p->ren && p->ren(oldname,newname)) + return TRUE; } return FALSE; } @@ -233,32 +244,47 @@ static bool_t testopen(const GFILEVMT *p, GFILE *f, const char *fname) { } GFILE *gfileOpen(const char *fname, const char *mode) { - GFILE *f; + uint16_t flags; + GFILE * f; const GFILEVMT *p; + // Get the requested mode + if (!(flags = mode2flags(mode))) + return FALSE; + + #if GFILE_ALLOW_DEVICESPECIFIC + if (fname[0] && fname[1] == '|') { + // First find an available GFILE slot. + for (f = gfileArr; f < &gfileArr[GFILE_MAX_GFILES]; f++) { + if (!(f->flags & GFILEFLG_OPEN)) { + // Try to open the file + f->flags = flags; + for(p = FsChain; p; p = p->next) { + if (p->prefix == fname[0]) + return testopen(p, f, fname+2); + } + // File not found + break; + } + } + + // No available slot + return FALSE; + } + #endif + // First find an available GFILE slot. for (f = gfileArr; f < &gfileArr[GFILE_MAX_GFILES]; f++) { if (!(f->flags & GFILEFLG_OPEN)) { - // Get the requested mode - if (!(f->flags = mode2flags(mode))) - return FALSE; - // Try to open the file - if (fname[0] && fname[1] == '|') { - for(p = FsChain; p; p = p->next) { - if (p->prefix == fname[0]) - return testopen(p, f, fname+2); - } - } else { - for(p = FsChain; p; p = p->next) { - if (testopen(p, f, fname)) - return TRUE; - } + f->flags = flags; + for(p = FsChain; p; p = p->next) { + if (testopen(p, f, fname)) + return TRUE; } - // File not found - return FALSE; + break; } } @@ -267,48 +293,384 @@ GFILE *gfileOpen(const char *fname, const char *mode) { } void gfileClose(GFILE *f) { - // Make sure it is one of the system GFILE's - if (f < gfileArr || f >= &gfileArr[GFILE_MAX_GFILES]) + if (!(f->flags & GFILEFLG_OPEN)) return; + if (f->vmt->close) + f->vmt->close(f); + f->flags = 0; } -size_t gfileRead(GFILE *f, char *buf, size_t len) { - +size_t gfileRead(GFILE *f, char *buf, size_t len) { + size_t res; + + if ((f->flags & (GFILEFLG_OPEN|GFILEFLG_READ)) != (GFILEFLG_OPEN|GFILEFLG_READ)) + return 0; + if (!f->vmt->read) + return 0; + if ((res = f->vmt->read(f, buf, len)) <= 0) + return 0; + f->pos += res; + return res; } -size_t gfileWrite(GFILE *f, const char *buf, size_t len) { - +size_t gfileWrite(GFILE *f, const char *buf, size_t len) { + size_t res; + + if ((f->flags & (GFILEFLG_OPEN|GFILEFLG_WRITE)) != (GFILEFLG_OPEN|GFILEFLG_WRITE)) + return 0; + if (!f->vmt->write) + return 0; + if ((res = f->vmt->write(f, buf, len)) <= 0) + return 0; + f->pos += res; + return res; } -long int gfileGetPos(GFILE *f) { - +long int gfileGetPos(GFILE *f) { + if (!(f->flags & GFILEFLG_OPEN)) + return 0; + return f->pos; } bool_t gfileSetPos(GFILE *f, long int pos) { - + if (!(f->flags & GFILEFLG_OPEN)) + return FALSE; + if (!f->vmt->setpos || !f->vmt->setpos(f, pos)) + return FALSE; + f->pos = pos; } -long int gfileGetSize(GFILE *f) { +long int gfileGetSize(GFILE *f) { + if (!(f->flags & GFILEFLG_OPEN)) + return 0; + if (!f->vmt->getsize) + return 0; + return f->vmt->getsize(f); +} +bool_t gfileEOF(GFILE *f) { + if (!(f->flags & GFILEFLG_OPEN)) + return TRUE; + if (!f->vmt->eof) + return TRUE; + return f->vmt->eof(f); } +/******************************************************** + * String VMT routines + ********************************************************/ +#if GFILE_NEED_STRINGS && (GFILE_NEED_PRINTG || GFILE_NEED_SCANG) + #include + + // Special String VMT + static int StringRead(GFILE *f, char *buf, int size) { + memcpy(buf, (char *)f->obj+f->pos, size); + return size; + } + static int StringWrite(GFILE *f, const char *buf, int size) { + memcpy((char *)f->obj+f->pos, buf, size); + return size; + } + static const GFILEVMT StringVMT = { + 0, // next + 0, // flags + '_', // prefix + 0, 0, 0, 0, + 0, 0, StringRead, StringWrite, + 0, 0, 0, + }; +#endif + /******************************************************** * printg routines ********************************************************/ #if GFILE_NEED_PRINTG + #include + + #define MAX_FILLER 11 + #define FLOAT_PRECISION 100000 + + int fnprintg(GFILE *f, int maxlen, const char *fmt, ...) { + int res; + va_list ap; + + va_start(ap, fmt); + res = vfnprintg(f, maxlen, fmt, ap); + va_end(ap); + return res; + } + + static char *ltoa_wd(char *p, long num, unsigned radix, long divisor) { + int i; + char * q; + + if (!divisor) divisor = num; + + q = p + MAX_FILLER; + do { + i = (int)(num % radix); + i += '0'; + if (i > '9') + i += 'A' - '0' - 10; + *--q = i; + num /= radix; + } while ((divisor /= radix) != 0); + + i = (int)(p + MAX_FILLER - q); + do { + *p++ = *q++; + } while (--i); + + return p; + } + + int vfnprintg(GFILE *f, int maxlen, const char *fmt, va_list arg) { + int ret; + char *p, *s, c, filler; + int i, precision, width; + bool_t is_long, left_align; + long l; + #if GFILE_ALLOW_FLOATS + float f; + char tmpbuf[2*MAX_FILLER + 1]; + #else + char tmpbuf[MAX_FILLER + 1]; + #endif + + ret = 0; + if (maxlen < 0) + return 0; + if (!maxlen) + maxlen = -1; + + while (*fmt) { + if (*fmt != '%') { + gfileWrite(f, fmt, 1); + ret++; if (--maxlen) return ret; + fmt++; + continue; + } + fmt++; + + p = s = tmpbuf; + left_align = FALSE; + filler = ' '; + width = 0; + precision = 0; + + if (*fmt == '-') { + fmt++; + left_align = TRUE; + } + if (*fmt == '.') { + fmt++; + filler = '0'; + } + + while (1) { + c = *fmt++; + if (c >= '0' && c <= '9') + c -= '0'; + else if (c == '*') + c = va_arg(ap, int); + else + break; + width = width * 10 + c; + } + if (c == '.') { + while (1) { + c = *fmt++; + if (c >= '0' && c <= '9') + c -= '0'; + else if (c == '*') + c = va_arg(ap, int); + else + break; + precision = precision * 10 + c; + } + } + /* Long modifier.*/ + if (c == 'l' || c == 'L') { + is_long = TRUE; + if (*fmt) + c = *fmt++; + } + else + is_long = (c >= 'A') && (c <= 'Z'); + + /* Command decoding.*/ + switch (c) { + case 0: + return ret; + case 'c': + filler = ' '; + *p++ = va_arg(ap, int); + break; + case 's': + filler = ' '; + if ((s = va_arg(ap, char *)) == 0) + s = "(null)"; + if (precision == 0) + precision = 32767; + for (p = s; *p && (--precision >= 0); p++); + break; + case 'D': + case 'd': + if (is_long) + l = va_arg(ap, long); + else + l = va_arg(ap, int); + if (l < 0) { + *p++ = '-'; + l = -l; + } + p = ltoa_wd(p, l, 10, 0); + break; + #if GFILE_ALLOW_FLOATS + case 'f': + f = (float) va_arg(ap, double); + if (f < 0) { + *p++ = '-'; + f = -f; + } + l = f; + p = ltoa_wd(p, l, 10, 0); + *p++ = '.'; + l = (f - l) * FLOAT_PRECISION; + p = ltoa_wd(p, l, 10, FLOAT_PRECISION / 10); + break; + #endif + case 'X': + case 'x': + c = 16; + goto unsigned_common; + case 'U': + case 'u': + c = 10; + goto unsigned_common; + case 'O': + case 'o': + c = 8; + unsigned_common: + if (is_long) + l = va_arg(ap, long); + else + l = va_arg(ap, int); + p = ltoa_wd(p, l, c, 0); + break; + default: + *p++ = c; + break; + } + + i = (int)(p - s); + if ((width -= i) < 0) + width = 0; + if (left_align == FALSE) + width = -width; + if (width < 0) { + if (*s == '-' && filler == '0') { + gfileWrite(f, s++, 1); + ret++; if (--maxlen) return ret; + i--; + } + do { + gfileWrite(f, &filler, 1); + ret++; if (--maxlen) return ret; + } while (++width != 0); + } + while (--i >= 0) { + gfileWrite(f, s++, 1); + ret++; if (--maxlen) return ret; + } + while (width) { + gfileWrite(f, &filler, 1); + ret++; if (--maxlen) return ret; + width--; + } + } + return ret; + } + + #if GFILE_NEED_STRINGS + int snprintg(char *buf, int maxlen, const char *fmt, ...) { + int res; + GFILE f; + va_list ap; + + if (maxlen <= 1) { + if (maxlen == 1) + *buf = 0; + return 0; + } + f.flags = GFILEFLG_OPEN|GFILEFLG_WRITE; + f.vmt = &StringVMT; + f.pos = 0; + f.obj = buf; + va_start(ap, fmt); + res = vfnprintg(&f, maxlen-1, fmt, ap); + va_end(ap); + buf[res] = 0; + return res; + } + int vsnprintg(char *buf, int maxlen, const char *fmt, va_list arg) { + int res; + GFILE f; + + if (maxlen <= 1) { + if (maxlen == 1) + *buf = 0; + return 0; + } + f.flags = GFILEFLG_OPEN|GFILEFLG_WRITE; + f.vmt = &StringVMT; + f.pos = 0; + f.obj = buf; + res = vfnprintg(&f, maxlen-1, fmt, arg); + buf[res] = 0; + return res; + } + #endif #endif /******************************************************** * scang routines ********************************************************/ #if GFILE_NEED_SCANG + #error "GFILE-SCANG: Not implemented yet" #endif /******************************************************** * stdio emulation routines ********************************************************/ -#ifndef GFILE_NEED_STDIO - #define GFILE_NEED_STDIO FALSE +#if GFILE_NEED_STDIO + size_t gstdioRead(void * ptr, size_t size, size_t count, FILE *f) { + return gfileRead(f, ptr, size*count)/size; + } + size_t gstdioWrite(const void * ptr, size_t size, size_t count, FILE *f) { + return gfileWrite(f, ptr, size*count)/size; + } + int gstdioSeek(FILE *f, size_t offset, int origin) { + switch(origin) { + case SEEK_SET: + break; + case SEEK_CUR: + offset += f->pos; + break; + case SEEK_END: + offset += gfileGetSize(f); + break; + default: + return -1; + } + return gfileSetPos(f, offset) ? 0 : -1; + } + int gstdioGetpos(FILE *f, long int *pos) { + if (!(f->flags & GFILEFLG_OPEN)) + return -1; + *pos = f->pos; + return 0; + } #endif #endif /* GFX_USE_GFILE */ diff --git a/src/gfile/inc_nativefs.c b/src/gfile/inc_nativefs.c index ccf1d40a..df5e7861 100644 --- a/src/gfile/inc_nativefs.c +++ b/src/gfile/inc_nativefs.c @@ -26,17 +26,19 @@ static bool_t NativeDel(const char *fname); static bool_t NativeExists(const char *fname); static long int NativeFilesize(const char *fname); static bool_t NativeRen(const char *oldname, const char *newname); -static bool_t NativeOpen(GFILE *f, const char *fname, const char *mode); +static bool_t NativeOpen(GFILE *f, const char *fname); static void NativeClose(GFILE *f); static int NativeRead(GFILE *f, char *buf, int size); -static int NativeWrite(GFILE *f, char *buf, int size); +static int NativeWrite(GFILE *f, const char *buf, int size); static bool_t NativeSetpos(GFILE *f, long int pos); static long int NativeGetsize(GFILE *f); static bool_t NativeEof(GFILE *f); static const GFILEVMT FsNativeVMT = { GFILE_CHAINHEAD, // next - #if !defined(WIN32) && !GFX_USE_OS_WIN32 + #if defined(WIN32) || GFX_USE_OS_WIN32 + GFSFLG_TEXTMODES| + #else GFSFLG_CASESENSITIVE| #endif GFSFLG_WRITEABLE|GFSFLG_SEEKABLE|GFSFLG_FAST, // flags @@ -84,11 +86,9 @@ static bool_t NativeOpen(GFILE *f, const char *fname) { } static void NativeClose(GFILE *f) { fclose((FILE *)f->obj); } static int NativeRead(GFILE *f, char *buf, int size) { return fread(buf, 1, size, (FILE *)f->obj); } -static int NativeWrite(GFILE *f, char *buf, int size) { return fwrite(buf, 1, size, (FILE *)f->obj); } +static int NativeWrite(GFILE *f, const char *buf, int size) { return fwrite(buf, 1, size, (FILE *)f->obj); } static bool_t NativeSetpos(GFILE *f, long int pos) { - if (fseek((FILE *)f->obj, pos, SEEK_SET)) return FALSE; - f->pos = pos; - return TRUE; + return fseek((FILE *)f->obj, pos, SEEK_SET) ? FALSE : TRUE; } static long int NativeGetsize(GFILE *f) { struct stat st; diff --git a/src/gfile/inc_romfs.c b/src/gfile/inc_romfs.c index 170b9a6c..5a780554 100644 --- a/src/gfile/inc_romfs.c +++ b/src/gfile/inc_romfs.c @@ -30,7 +30,7 @@ static const ROMFS_DIRENTRY const *FsROMHead = ROMFS_DIRENTRY_HEAD; static bool_t ROMExists(const char *fname); static long int ROMFilesize(const char *fname); -static bool_t ROMOpen(GFILE *f, const char *fname, const char *mode); +static bool_t ROMOpen(GFILE *f, const char *fname); static void ROMClose(GFILE *f); static int ROMRead(GFILE *f, char *buf, int size); static bool_t ROMSetpos(GFILE *f, long int pos); -- cgit v1.2.3 From a6c22fc364c25e8673488f0f5c36e3538546d898 Mon Sep 17 00:00:00 2001 From: Joel Bodenmann Date: Sun, 2 Feb 2014 20:01:54 +0100 Subject: added _gfileDeinit() dummy --- src/gfile/gfile.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/gfile/gfile.c b/src/gfile/gfile.c index e42dc2af..59dade1f 100644 --- a/src/gfile/gfile.c +++ b/src/gfile/gfile.c @@ -68,10 +68,8 @@ GFILE *gfileStdErr; */ static const GFILEVMT const * FsChain = GFILE_CHAINHEAD; -/** - * The init routine - */ -void _gfileInit(void) { +void _gfileInit(void) +{ #if GFILE_NEED_NATIVEFS NativeStdIn.flags = GFILEFLG_OPEN|GFILEFLG_READ; NativeStdIn.vmt = &FsNativeVMT; @@ -91,6 +89,11 @@ void _gfileInit(void) { #endif } +void _gfileDeinit(void) +{ + /* ToDo */ +} + bool_t gfileExists(const char *fname) { const GFILEVMT *p; -- cgit v1.2.3 From 79d913f16dbaa17520521c645176cdbbffbb746a Mon Sep 17 00:00:00 2001 From: inmarket Date: Mon, 3 Feb 2014 18:16:22 +1000 Subject: More gFile stuff --- src/gfile/gfile.c | 233 ++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 219 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/gfile/gfile.c b/src/gfile/gfile.c index 59dade1f..f9c306e4 100644 --- a/src/gfile/gfile.c +++ b/src/gfile/gfile.c @@ -68,8 +68,10 @@ GFILE *gfileStdErr; */ static const GFILEVMT const * FsChain = GFILE_CHAINHEAD; -void _gfileInit(void) -{ +/** + * The init routine + */ +void _gfileInit(void) { #if GFILE_NEED_NATIVEFS NativeStdIn.flags = GFILEFLG_OPEN|GFILEFLG_READ; NativeStdIn.vmt = &FsNativeVMT; @@ -296,7 +298,7 @@ GFILE *gfileOpen(const char *fname, const char *mode) { } void gfileClose(GFILE *f) { - if (!(f->flags & GFILEFLG_OPEN)) + if (!f || !(f->flags & GFILEFLG_OPEN)) return; if (f->vmt->close) f->vmt->close(f); @@ -306,7 +308,7 @@ void gfileClose(GFILE *f) { size_t gfileRead(GFILE *f, char *buf, size_t len) { size_t res; - if ((f->flags & (GFILEFLG_OPEN|GFILEFLG_READ)) != (GFILEFLG_OPEN|GFILEFLG_READ)) + if (!f || (f->flags & (GFILEFLG_OPEN|GFILEFLG_READ)) != (GFILEFLG_OPEN|GFILEFLG_READ)) return 0; if (!f->vmt->read) return 0; @@ -319,7 +321,7 @@ size_t gfileRead(GFILE *f, char *buf, size_t len) { size_t gfileWrite(GFILE *f, const char *buf, size_t len) { size_t res; - if ((f->flags & (GFILEFLG_OPEN|GFILEFLG_WRITE)) != (GFILEFLG_OPEN|GFILEFLG_WRITE)) + if (!f || (f->flags & (GFILEFLG_OPEN|GFILEFLG_WRITE)) != (GFILEFLG_OPEN|GFILEFLG_WRITE)) return 0; if (!f->vmt->write) return 0; @@ -330,13 +332,13 @@ size_t gfileWrite(GFILE *f, const char *buf, size_t len) { } long int gfileGetPos(GFILE *f) { - if (!(f->flags & GFILEFLG_OPEN)) + if (!f || !(f->flags & GFILEFLG_OPEN)) return 0; return f->pos; } bool_t gfileSetPos(GFILE *f, long int pos) { - if (!(f->flags & GFILEFLG_OPEN)) + if (!f || !(f->flags & GFILEFLG_OPEN)) return FALSE; if (!f->vmt->setpos || !f->vmt->setpos(f, pos)) return FALSE; @@ -344,7 +346,7 @@ bool_t gfileSetPos(GFILE *f, long int pos) { } long int gfileGetSize(GFILE *f) { - if (!(f->flags & GFILEFLG_OPEN)) + if (!f || !(f->flags & GFILEFLG_OPEN)) return 0; if (!f->vmt->getsize) return 0; @@ -352,7 +354,7 @@ long int gfileGetSize(GFILE *f) { } bool_t gfileEOF(GFILE *f) { - if (!(f->flags & GFILEFLG_OPEN)) + if (!f || !(f->flags & GFILEFLG_OPEN)) return TRUE; if (!f->vmt->eof) return TRUE; @@ -367,12 +369,16 @@ bool_t gfileEOF(GFILE *f) { // Special String VMT static int StringRead(GFILE *f, char *buf, int size) { - memcpy(buf, (char *)f->obj+f->pos, size); - return size; + // size must be 1 for a complete read + if (!((char *)f->obj)[f->pos]) + return 0; + buf[0] = ((char *)f->obj)[f->pos]; + return 1; } static int StringWrite(GFILE *f, const char *buf, int size) { - memcpy((char *)f->obj+f->pos, buf, size); - return size; + // size must be 1 for a complete write + ((char *)f->obj)[f->pos] = buf[0]; + return 1; } static const GFILEVMT StringVMT = { 0, // next @@ -640,7 +646,206 @@ bool_t gfileEOF(GFILE *f) { * scang routines ********************************************************/ #if GFILE_NEED_SCANG - #error "GFILE-SCANG: Not implemented yet" + int fscang(GFILE *f, const char *fmt, ...) { + int res; + va_list ap; + + va_start(ap, fmt); + res = vfscang(f, fmt, ap); + va_end(ap); + return res; + } + + int vfscang(GFILE *f, const char *fmt, va_list arg) { + int res, width, size, base; + char c; + bool_t assign; + void *p; + + for(res = 0; *fmt; fmt++) { + switch(*fmt) { + case ' ': case '\t': case '\r': case '\n': case '\v': case '\f': + break; + + case '%': + fmt++; + assign = TRUE; + width = 0; + size = 1; + + if (*fmt == '*') { + fmt++; + assign = FALSE; + } + while(*fmt >= '0' && *fmt <= '9') + width = width * 10 + (*fmt++ - '0'); + if (*fmt == 'h') { + fmt++; + size = 0; + } else if (*fmt == 'l') { + fmt++; + size = 2; + } else if (*fmt == 'L') { + fmt++; + size = 3; + } + switch(*fmt) { + case 0: + return res; + case '%': + goto matchchar; + case 'c': + if (!width) { + while(1) { + if (!gfileRead(f, &c, 1)) return res; + switch(c) { + case ' ': case '\t': case '\r': + case '\n': case '\v': case '\f': continue; + } + break; + } + width = 1; + } else { + if (!gfileRead(f, &c, 1)) return res; + } + if (assign) { + p = va_arg(ap, char *); + res++; + *((char *)p)++ = c; + } + while(--width) { + if (!gfileRead(f, &c, 1)) return res; + if (assign) *((char *)p)++ = c; + } + break; + case 's': + while(1) { + if (!gfileRead(f, &c, 1)) return res; + switch(c) { + case ' ': case '\t': case '\r': + case '\n': case '\v': case '\f': continue; + } + break; + } + if (assign) { + p = va_arg(ap, char *); + res++; + *((char *)p)++ = c; + } + if (width) { + while(--width) { + if (!gfileRead(f, &c, 1)) { + if (assign) *((char *)p) = 0; + return res; + } + if (assign) *((char *)p)++ = c; + } + } else { + while(1) { + if (!gfileRead(f, &c, 1)) { + if (assign) *((char *)p) = 0; + return res; + } + switch(c) { + case ' ': case '\t': case '\r': + case '\n': case '\v': case '\f': break; + default: + if (assign) *((char *)p)++ = c; + continue; + } + break; + } + //ungetch(c); + } + if (assign) *((char *)p) = 0; + break; + case 'd': + case 'i': + case 'o': + case 'u': + case 'x': + case 'b': + /* + while (isspace (*buf)) + buf++; + if (*s == 'd' || *s == 'u') + base = 10; + else if (*s == 'x') + base = 16; + else if (*s == 'o') + base = 8; + else if (*s == 'b') + base = 2; + if (!width) { + if (isspace (*(s + 1)) || *(s + 1) == 0) + width = strcspn (buf, ISSPACE); + else + width = strchr (buf, *(s + 1)) - buf; + } + strncpy (tmp, buf, width); + tmp[width] = '\0'; + buf += width; + if (!noassign) + atob (va_arg (ap, u_int32_t *), tmp, base); + } + if (!noassign) + count++; + */ + + #if GFILE_ALLOW_FLOATS + case 'e': case 'f': case 'g': + #endif + default: + return res; + } + + break; + + default: + matchchar: + while(1) { + if (!gfileRead(f, &c, 1)) return res; + switch(c) { + case ' ': case '\t': case '\r': + case '\n': case '\v': case '\f': continue; + } + break; + } + if (c != *fmt) return res; + break; + } + } + return res; + } + + #if GFILE_NEED_STRINGS + int sscang(const char *buf, const char *fmt, ...) { + int res; + GFILE f; + va_list ap; + + f.flags = GFILEFLG_OPEN|GFILEFLG_READ; + f.vmt = &StringVMT; + f.pos = 0; + f.obj = buf; + va_start(ap, fmt); + res = vfscang(&f, fmt, ap); + va_end(ap); + return res; + } + + int vsscang(const char *buf, const char *fmt, va_list arg) { + int res; + GFILE f; + + f.flags = GFILEFLG_OPEN|GFILEFLG_READ; + f.vmt = &StringVMT; + f.pos = 0; + f.obj = buf; + res = vfscang(&f, fmt, arg); + return res; + } + #endif #endif /******************************************************** -- cgit v1.2.3 From e72e2705381558ff2347543ed21b853a1168858c Mon Sep 17 00:00:00 2001 From: inmarket Date: Fri, 7 Feb 2014 01:34:38 +1000 Subject: Add support for GFILEs based on BaseFileStreams and Memory Pointers --- src/gfile/gfile.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++- src/gfile/inc_chibiosfs.c | 46 ++++++++++++++++++++++++++++ src/gfile/inc_memfs.c | 41 +++++++++++++++++++++++++ 3 files changed, 162 insertions(+), 1 deletion(-) create mode 100644 src/gfile/inc_chibiosfs.c create mode 100644 src/gfile/inc_memfs.c (limited to 'src') diff --git a/src/gfile/gfile.c b/src/gfile/gfile.c index f9c306e4..23985367 100644 --- a/src/gfile/gfile.c +++ b/src/gfile/gfile.c @@ -31,6 +31,20 @@ GFILE *gfileStdErr; * The last defined is the first searched. */ +/******************************************************** + * The ChibiOS BaseFileStream VMT + ********************************************************/ +#if GFILE_NEED_CHIBIOSFS && GFX_USE_OS_CHIBIOS + #include "../src/gfile/inc_chibiosfs.c" +#endif + +/******************************************************** + * The Memory Pointer VMT + ********************************************************/ +#if GFILE_NEED_MEMFS + #include "../src/gfile/inc_memfs.c" +#endif + /******************************************************** * The RAM file-system VMT ********************************************************/ @@ -297,6 +311,66 @@ GFILE *gfileOpen(const char *fname, const char *mode) { return FALSE; } +#if GFILE_NEED_CHIBIOSFS && GFX_USE_OS_CHIBIOS + GFILE * gfileOpenBaseFileStream(void *BaseFileStreamPtr, const char *mode) { + GFILE * f; + + // First find an available GFILE slot. + for (f = gfileArr; f < &gfileArr[GFILE_MAX_GFILES]; f++) { + if (!(f->flags & GFILEFLG_OPEN)) { + // Get the flags + if (!(f->flags = mode2flags(mode))) + return FALSE; + + // If we want write but the fs doesn't allow it then return + if ((f->flags & GFILEFLG_WRITE) && !(FsCHIBIOSVMT.flags & GFSFLG_WRITEABLE)) + return FALSE; + + // File is open - fill in all the details + f->vmt = &FsCHIBIOSVMT; + f->fd = BaseFileStreamPtr; + f->err = 0; + f->pos = 0; + f->flags |= GFILEFLG_OPEN|GFILEFLG_CANSEEK; + return TRUE; + } + } + + // No available slot + return FALSE; + } +#endif + +#if GFILE_NEED_MEMFS + GFILE * gfileOpenMemory(void *memptr, const char *mode) { + GFILE * f; + + // First find an available GFILE slot. + for (f = gfileArr; f < &gfileArr[GFILE_MAX_GFILES]; f++) { + if (!(f->flags & GFILEFLG_OPEN)) { + // Get the flags + if (!(f->flags = mode2flags(mode))) + return FALSE; + + // If we want write but the fs doesn't allow it then return + if ((f->flags & GFILEFLG_WRITE) && !(FsMemVMT.flags & GFSFLG_WRITEABLE)) + return FALSE; + + // File is open - fill in all the details + f->vmt = &FsMemVMT; + f->fd = memptr; + f->err = 0; + f->pos = 0; + f->flags |= GFILEFLG_OPEN|GFILEFLG_CANSEEK; + return TRUE; + } + } + + // No available slot + return FALSE; + } +#endif + void gfileClose(GFILE *f) { if (!f || !(f->flags & GFILEFLG_OPEN)) return; @@ -357,7 +431,7 @@ bool_t gfileEOF(GFILE *f) { if (!f || !(f->flags & GFILEFLG_OPEN)) return TRUE; if (!f->vmt->eof) - return TRUE; + return FALSE; return f->vmt->eof(f); } diff --git a/src/gfile/inc_chibiosfs.c b/src/gfile/inc_chibiosfs.c new file mode 100644 index 00000000..b30a675f --- /dev/null +++ b/src/gfile/inc_chibiosfs.c @@ -0,0 +1,46 @@ +/* + * This file is subject to the terms of the GFX License. If a copy of + * the license was not distributed with this file, you can obtain one at: + * + * http://ugfx.org/license.html + */ + +/** + * This file is included by src/gfile/gfile.c + */ + +/******************************************************** + * The ChibiOS BaseFileStream file-system VMT + ********************************************************/ + +static void ChibiOSBFSClose(GFILE *f); +static int ChibiOSBFSRead(GFILE *f, char *buf, int size); +static int ChibiOSBFSWrite(GFILE *f, char *buf, int size); +static bool_t ChibiOSBFSSetpos(GFILE *f, long int pos); +static long int ChibiOSBFSGetsize(GFILE *f); +static bool_t ChibiOSBFSEof(GFILE *f); + +static const GFILEVMT FsCHIBIOSVMT = { + 0, // next + GFSFLG_SEEKABLE|GFSFLG_WRITEABLE, // flags + 0, // prefix + 0, 0, 0, 0, + 0, ChibiOSBFSClose, ChibiOSBFSRead, ChibiOSBFSWrite, + ChibiOSBFSSetpos, ChibiOSBFSGetsize, ChibiOSBFSEof, +}; + +static void ChibiOSBFSClose(GFILE *f) { + chFileStreamClose(((BaseFileStream *)f->fd)); +} +static int ChibiOSBFSRead(GFILE *f, char *buf, int size) { + return chSequentialStreamRead(((BaseFileStream *)f->fd), (uint8_t *)buf, size); +} +static int ChibiOSBFSWrite(GFILE *f, char *buf, int size) { + return chSequentialStreamWrite(((BaseFileStream *)f->fd), (uint8_t *)buf, size); +} +static bool_t ChibiOSBFSSetpos(GFILE *f, long int pos) { + chFileStreamSeek(((BaseFileStream *)f->fd), pos); + return TRUE; +} +static long int ChibiOSBFSGetsize(GFILE *f) { return chFileStreamGetSize(((BaseFileStream *)f->fd)); } +static bool_t ChibiOSBFSEof(GFILE *f) { return f->pos >= chFileStreamGetSize(((BaseFileStream *)f->fd)); } diff --git a/src/gfile/inc_memfs.c b/src/gfile/inc_memfs.c new file mode 100644 index 00000000..fee089ce --- /dev/null +++ b/src/gfile/inc_memfs.c @@ -0,0 +1,41 @@ +/* + * This file is subject to the terms of the GFX License. If a copy of + * the license was not distributed with this file, you can obtain one at: + * + * http://ugfx.org/license.html + */ + +/** + * This file is included by src/gfile/gfile.c + */ + +/******************************************************** + * The Memory pointer file-system VMT + ********************************************************/ + +#include + +static int MEMRead(GFILE *f, char *buf, int size); +static int MEMWrite(GFILE *f, char *buf, int size); +static bool_t MEMSetpos(GFILE *f, long int pos); + +static const GFILEVMT FsMemVMT = { + 0, // next + GFSFLG_SEEKABLE|GFSFLG_WRITEABLE, // flags + 0, // prefix + 0, 0, 0, 0, + 0, 0, MEMRead, MEMWrite, + MEMSetpos, 0, 0, +}; + +static int MEMRead(GFILE *f, char *buf, int size) { + memset(buf, ((char *)f->fd)+f->pos, size); + return size; +} +static int MEMWrite(GFILE *f, char *buf, int size) { + memset(((char *)f->fd)+f->pos, buf, size); + return size; +} +static bool_t MEMSetpos(GFILE *f, long int pos) { + return TRUE; +} -- cgit v1.2.3 From 71aeb15d58dc306b3cf5027ca151be40cf5a5890 Mon Sep 17 00:00:00 2001 From: inmarket Date: Fri, 7 Feb 2014 01:36:31 +1000 Subject: Start changing GDISP images to use a simpler API based on GFILE's. --- src/gdisp/image.c | 225 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 127 insertions(+), 98 deletions(-) (limited to 'src') diff --git a/src/gdisp/image.c b/src/gdisp/image.c index 62af0aeb..dd219289 100644 --- a/src/gdisp/image.c +++ b/src/gdisp/image.c @@ -18,6 +18,77 @@ #include +static gdispImageError imageOpen(gdispImage *img) { + gdispImageError err; + + img->bgcolor = White; + for(img->fns = ImageHandlers; img->fns < ImageHandlers+sizeof(ImageHandlers)/sizeof(ImageHandlers[0]); img->fns++) { + err = img->fns->open(img); + if (err != GDISP_IMAGE_ERR_BADFORMAT) { + if (!(err & GDISP_IMAGE_ERR_UNRECOVERABLE)) + return err; + goto unrecoverable; + } + img->io.fns->seek(&img->io, 0); + } + + err = GDISP_IMAGE_ERR_BADFORMAT; + img->type = GDISP_IMAGE_TYPE_UNKNOWN; + +unrecoverable: + img->fns->close(img); + img->flags = 0; + img->fns = 0; + img->priv = 0; + return err; +} + +gdispImageError + DEPRECATED("If possible please use gdispImageOpenFile(), gdispImageOpenMemory() or gdispImageOpenBaseFileStream() instead") + gdispImageOpen(gdispImage *img) { + return imageOpen(img); +} + +#if GDISP_NEED_IMAGE_NATIVE + extern gdispImageError gdispImageOpen_NATIVE(gdispImage *img); + extern void gdispImageClose_NATIVE(gdispImage *img); + extern gdispImageError gdispImageCache_NATIVE(gdispImage *img); + extern gdispImageError gdispGImageDraw_NATIVE(GDisplay *g, gdispImage *img, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t sx, coord_t sy); + extern delaytime_t gdispImageNext_NATIVE(gdispImage *img); +#endif + +#if GDISP_NEED_IMAGE_GIF + extern gdispImageError gdispImageOpen_GIF(gdispImage *img); + extern void gdispImageClose_GIF(gdispImage *img); + extern gdispImageError gdispImageCache_GIF(gdispImage *img); + extern gdispImageError gdispGImageDraw_GIF(GDisplay *g, gdispImage *img, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t sx, coord_t sy); + extern delaytime_t gdispImageNext_GIF(gdispImage *img); +#endif + +#if GDISP_NEED_IMAGE_BMP + extern gdispImageError gdispImageOpen_BMP(gdispImage *img); + extern void gdispImageClose_BMP(gdispImage *img); + extern gdispImageError gdispImageCache_BMP(gdispImage *img); + extern gdispImageError gdispGImageDraw_BMP(GDisplay *g, gdispImage *img, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t sx, coord_t sy); + extern delaytime_t gdispImageNext_BMP(gdispImage *img); +#endif + +#if GDISP_NEED_IMAGE_JPG + extern gdispImageError gdispImageOpen_JPG(gdispImage *img); + extern void gdispImageClose_JPG(gdispImage *img); + extern gdispImageError gdispImageCache_JPG(gdispImage *img); + extern gdispImageError gdispGImageDraw_JPG(GDisplay *g, gdispImage *img, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t sx, coord_t sy); + extern delaytime_t gdispImageNext_JPG(gdispImage *img); +#endif + +#if GDISP_NEED_IMAGE_PNG + extern gdispImageError gdispImageOpen_PNG(gdispImage *img); + extern void gdispImageClose_PNG(gdispImage *img); + extern gdispImageError gdispImageCache_PNG(gdispImage *img); + extern gdispImageError gdispGImageDraw_PNG(GDisplay *g, gdispImage *img, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t sx, coord_t sy); + extern delaytime_t gdispImageNext_PNG(gdispImage *img); +#endif + /* The structure defining the routines for image drawing */ typedef struct gdispImageHandlers { gdispImageError (*open)(gdispImage *img); /* The open function */ @@ -59,128 +130,86 @@ static gdispImageHandlers ImageHandlers[] = { #endif }; -static size_t ImageMemoryRead(struct gdispImageIO *pio, void *buf, size_t len) { - if (pio->fd == (void *)-1) return 0; - memcpy(buf, ((const char *)pio->fd)+pio->pos, len); +static size_t ImageGFileRead(struct gdispImageIO *pio, void *buf, size_t len) { + if (!pio->fd) return 0; + len = gfileRead((GFILE *)pio->fd, buf, len); + if ((int)len < 0) len = 0; pio->pos += len; return len; } -static void ImageMemorySeek(struct gdispImageIO *pio, size_t pos) { - if (pio->fd == (void *)-1) return; - pio->pos = pos; +static void ImageGFileSeek(struct gdispImageIO *pio, size_t pos) { + if (!pio->fd) return; + if (pio->pos != pos) { + gfileSetPos((GFILE *)pio->fd, pos); + pio->pos = pos; + } } -static void ImageMemoryClose(struct gdispImageIO *pio) { - pio->fd = (void *)-1; +static void ImageGFileClose(struct gdispImageIO *pio) { + if (!pio->fd) return; + gfileClose((GFILE *)pio->fd); + pio->fd = 0; pio->pos = 0; } -static const gdispImageIOFunctions ImageMemoryFunctions = - { ImageMemoryRead, ImageMemorySeek, ImageMemoryClose }; +static const gdispImageIOFunctions ImageGFileFunctions = + { ImageGFileRead, ImageGFileSeek, ImageGFileClose }; -bool_t gdispImageSetMemoryReader(gdispImage *img, const void *memimage) { - img->io.fns = &ImageMemoryFunctions; - img->io.pos = 0; - img->io.fd = memimage; - return TRUE; -} - -#if GFX_USE_OS_CHIBIOS - static size_t ImageBaseFileStreamRead(struct gdispImageIO *pio, void *buf, size_t len) { - if (pio->fd == (void *)-1) return 0; - len = chSequentialStreamRead(((BaseFileStream *)pio->fd), (uint8_t *)buf, len); - pio->pos += len; - return len; - } - - static void ImageBaseFileStreamSeek(struct gdispImageIO *pio, size_t pos) { - if (pio->fd == (void *)-1) return; - if (pio->pos != pos) { - chFileStreamSeek(((BaseFileStream *)pio->fd), pos); - pio->pos = pos; - } - } - - static void ImageBaseFileStreamClose(struct gdispImageIO *pio) { - if (pio->fd == (void *)-1) return; - chFileStreamClose(((BaseFileStream *)pio->fd)); - pio->fd = (void *)-1; - pio->pos = 0; +#if GFILE_NEED_MEMFS + gdispImageError gdispImageOpenMemory(gdispImage *img, const void *memimage) { + img->io.fns = &ImageGFileFunctions; + img->io.pos = 0; + img->io.fd = gfileOpenMemory(memimage, "rb"); + if (!img->io.fd) + return GDISP_IMAGE_ERR_NOSUCHFILE; + return imageOpen(img); } - static const gdispImageIOFunctions ImageBaseFileStreamFunctions = - { ImageBaseFileStreamRead, ImageBaseFileStreamSeek, ImageBaseFileStreamClose }; - - bool_t gdispImageSetBaseFileStreamReader(gdispImage *img, void *BaseFileStreamPtr) { - img->io.fns = &ImageBaseFileStreamFunctions; + bool_t DEPRECATED("Use gdispImageOpenMemory() instead. GFX_USE_GFILE, GFILE_NEED_MEMFS must also be TRUE") gdispImageSetMemoryReader(gdispImage *img, const void *memimage) { + img->io.fns = &ImageGFileFunctions; img->io.pos = 0; - img->io.fd = BaseFileStreamPtr; - return TRUE; + img->io.fd = gfileOpenMemory(memimage, "rb"); + return img->io.fd != 0; } #endif -#if defined(WIN32) || GFX_USE_OS_WIN32 || GFX_USE_OS_LINUX || GFX_USE_OS_OSX - #include - - static size_t ImageFileRead(struct gdispImageIO *pio, void *buf, size_t len) { - if (!pio->fd) return 0; - len = fread(buf, 1, len, (FILE *)pio->fd); - if ((int)len < 0) len = 0; - pio->pos += len; - return len; - } - - static void ImageFileSeek(struct gdispImageIO *pio, size_t pos) { - if (!pio->fd) return; - if (pio->pos != pos) { - fseek((FILE *)pio->fd, pos, SEEK_SET); - pio->pos = pos; - } - } - - static void ImageFileClose(struct gdispImageIO *pio) { - if (!pio->fd) return; - fclose((FILE *)pio->fd); - pio->fd = 0; - pio->pos = 0; - } - - static const gdispImageIOFunctions ImageFileFunctions = - { ImageFileRead, ImageFileSeek, ImageFileClose }; +gdispImageError gdispImageOpenFile(gdispImage *img, const char *filename) { + img->io.fns = &ImageGFileFunctions; + img->io.pos = 0; + img->io.fd = gfileOpen(filename, "rb"); + if (!img->io.fd) + return GDISP_IMAGE_ERR_NOSUCHFILE; + return imageOpen(img); +} - bool_t gdispImageSetFileReader(gdispImage *img, const char *filename) { - img->io.fns = &ImageFileFunctions; +#if defined(WIN32) || GFX_USE_OS_WIN32 || GFX_USE_OS_LINUX || GFX_USE_OS_OSX + bool_t DEPRECATED("Please use gdispImageOpenFile() instead. GFX_USE_GFILE must also be TRUE") gdispImageSetFileReader(gdispImage *img, const char *filename) { + img->io.fns = &ImageGFileFunctions; img->io.pos = 0; - #if defined(WIN32) || GFX_USE_OS_WIN32 - img->io.fd = (void *)fopen(filename, "rb"); - #else - img->io.fd = (void *)fopen(filename, "r"); - #endif - + img->io.fd = gfileOpen(filename, "rb"); return img->io.fd != 0; } #endif -gdispImageError gdispImageOpen(gdispImage *img) { - gdispImageError err; +#if GFILE_NEED_CHIBIOSFS && GFX_USE_OS_CHIBIOS + bool_t DEPRECATED("Use gdispImageOpenBaseFileStream() instead. GFX_USE_GFILE, GFILE_NEED_CHIBIOSFS must also be TRUE") gdispImageSetBaseFileStreamReader(gdispImage *img, void *BaseFileStreamPtr) { + img->io.fns = &ImageGFileFunctions; + img->io.pos = 0; + img->io.fd = gfileOpenBaseFileStream(BaseFileStreamPtr, "rb"); + return img->io.fd != 0; + } - img->bgcolor = White; - for(img->fns = ImageHandlers; img->fns < ImageHandlers+sizeof(ImageHandlers)/sizeof(ImageHandlers[0]); img->fns++) { - err = img->fns->open(img); - if (err != GDISP_IMAGE_ERR_BADFORMAT) { - if ((err & GDISP_IMAGE_ERR_UNRECOVERABLE)) - img->fns = 0; - return err; - } - img->io.fns->seek(&img->io, 0); + gdispImageError gdispImageOpenBaseFileStream(gdispImage *img, void *BaseFileStreamPtr) { + img->io.fns = &ImageGFileFunctions; + img->io.pos = 0; + img->io.fd = gfileOpenBaseFileStream(BaseFileStreamPtr, "rb"); + if (!img->io.fd) + return GDISP_IMAGE_ERR_NOSUCHFILE; + return imageOpen(img); } - img->type = GDISP_IMAGE_TYPE_UNKNOWN; - img->flags = 0; - img->fns = 0; - img->priv = 0; - return GDISP_IMAGE_ERR_BADFORMAT; -} + +#endif void gdispImageClose(gdispImage *img) { if (img->fns) -- cgit v1.2.3 From b74686bdf075c51e3779d3118b50a91950647f07 Mon Sep 17 00:00:00 2001 From: inmarket Date: Fri, 7 Feb 2014 13:59:02 +1000 Subject: Removing compiler warnings from new list code --- src/gwin/list.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/gwin/list.c b/src/gwin/list.c index 972ea1ab..08e6a96d 100644 --- a/src/gwin/list.c +++ b/src/gwin/list.c @@ -172,6 +172,7 @@ static void gwinListDefaultDraw(GWidgetObject* gw, void* param) { const gfxQueueASyncItem* qi; int item, i; coord_t iheight; + (void) x; iheight = gdispGetFontMetric(gw->g.font, fontHeight) + VERTICAL_PADDING; @@ -202,8 +203,7 @@ static void gwinListDefaultDraw(GWidgetObject* gw, void* param) { // a mouse down has occurred over the list area static void MouseDown(GWidgetObject* gw, coord_t x, coord_t y) { - const gfxQueueASyncItem* qi; - int item, i, pgsz; + int pgsz; coord_t iheight; (void) x; -- cgit v1.2.3 From a86bab4a77ea6a4cd34e011c15535fc8da8a1ba6 Mon Sep 17 00:00:00 2001 From: inmarket Date: Fri, 7 Feb 2014 14:04:43 +1000 Subject: Updates to GFILE code --- src/gfile/gfile.c | 88 ++++++++++++++++++++++++++++++++++------------- src/gfile/inc_chibiosfs.c | 8 ++--- src/gfile/inc_memfs.c | 14 ++++---- src/gfile/inc_nativefs.c | 8 ++--- src/gfile/inc_romfs.c | 4 +-- 5 files changed, 82 insertions(+), 40 deletions(-) (limited to 'src') diff --git a/src/gfile/gfile.c b/src/gfile/gfile.c index 23985367..9edafea4 100644 --- a/src/gfile/gfile.c +++ b/src/gfile/gfile.c @@ -12,10 +12,52 @@ */ #define GFILE_IMPLEMENTATION + #include "gfx.h" #if GFX_USE_GFILE +struct GFILE { + const struct GFILEVMT * vmt; + uint16_t flags; + #define GFILEFLG_OPEN 0x0001 // File is open + #define GFILEFLG_READ 0x0002 // Read the file + #define GFILEFLG_WRITE 0x0004 // Write the file + #define GFILEFLG_APPEND 0x0008 // Append on each write + #define GFILEFLG_BINARY 0x0010 // Treat as a binary file + #define GFILEFLG_DELONCLOSE 0x0020 // Delete on close + #define GFILEFLG_CANSEEK 0x0040 // Seek operations are valid + #define GFILEFLG_FAILONBLOCK 0x0080 // Fail on a blocking call + #define GFILEFLG_MUSTEXIST 0x0100 // On open file must exist + #define GFILEFLG_MUSTNOTEXIST 0x0200 // On open file must not exist + #define GFILEFLG_TRUNC 0x0400 // On open truncate the file + void * obj; + long int pos; +}; + +typedef struct GFILEVMT { + const struct GFILEVMT * next; + uint8_t flags; + #define GFSFLG_WRITEABLE 0x0001 + #define GFSFLG_CASESENSITIVE 0x0002 + #define GFSFLG_SEEKABLE 0x0004 + #define GFSFLG_FAST 0x0010 + #define GFSFLG_SMALL 0x0020 + #define GFSFLG_TEXTMODES 0x0040 + char prefix; + bool_t (*del) (const char *fname); + bool_t (*exists) (const char *fname); + long int (*filesize) (const char *fname); + bool_t (*ren) (const char *oldname, const char *newname); + bool_t (*open) (GFILE *f, const char *fname); + void (*close) (GFILE *f); + int (*read) (GFILE *f, void *buf, int size); + int (*write) (GFILE *f, const void *buf, int size); + bool_t (*setpos) (GFILE *f, long int pos); + long int (*getsize) (GFILE *f); + bool_t (*eof) (GFILE *f); +} GFILEVMT; + // The chain of FileSystems #define GFILE_CHAINHEAD 0 @@ -254,7 +296,6 @@ static bool_t testopen(const GFILEVMT *p, GFILE *f, const char *fname) { // File is open - fill in all the details f->vmt = p; - f->err = 0; f->pos = 0; f->flags |= GFILEFLG_OPEN; if (p->flags & GFSFLG_SEEKABLE) @@ -269,7 +310,7 @@ GFILE *gfileOpen(const char *fname, const char *mode) { // Get the requested mode if (!(flags = mode2flags(mode))) - return FALSE; + return 0; #if GFILE_ALLOW_DEVICESPECIFIC if (fname[0] && fname[1] == '|') { @@ -280,7 +321,7 @@ GFILE *gfileOpen(const char *fname, const char *mode) { f->flags = flags; for(p = FsChain; p; p = p->next) { if (p->prefix == fname[0]) - return testopen(p, f, fname+2); + return testopen(p, f, fname+2) ? f : 0; } // File not found break; @@ -288,7 +329,7 @@ GFILE *gfileOpen(const char *fname, const char *mode) { } // No available slot - return FALSE; + return 0; } #endif @@ -300,7 +341,7 @@ GFILE *gfileOpen(const char *fname, const char *mode) { f->flags = flags; for(p = FsChain; p; p = p->next) { if (testopen(p, f, fname)) - return TRUE; + return f; } // File not found break; @@ -308,7 +349,7 @@ GFILE *gfileOpen(const char *fname, const char *mode) { } // No available slot - return FALSE; + return 0; } #if GFILE_NEED_CHIBIOSFS && GFX_USE_OS_CHIBIOS @@ -320,24 +361,23 @@ GFILE *gfileOpen(const char *fname, const char *mode) { if (!(f->flags & GFILEFLG_OPEN)) { // Get the flags if (!(f->flags = mode2flags(mode))) - return FALSE; + return 0; // If we want write but the fs doesn't allow it then return if ((f->flags & GFILEFLG_WRITE) && !(FsCHIBIOSVMT.flags & GFSFLG_WRITEABLE)) - return FALSE; + return 0; // File is open - fill in all the details f->vmt = &FsCHIBIOSVMT; - f->fd = BaseFileStreamPtr; - f->err = 0; + f->obj = BaseFileStreamPtr; f->pos = 0; f->flags |= GFILEFLG_OPEN|GFILEFLG_CANSEEK; - return TRUE; + return f; } } // No available slot - return FALSE; + return 0; } #endif @@ -350,24 +390,23 @@ GFILE *gfileOpen(const char *fname, const char *mode) { if (!(f->flags & GFILEFLG_OPEN)) { // Get the flags if (!(f->flags = mode2flags(mode))) - return FALSE; + return 0; // If we want write but the fs doesn't allow it then return if ((f->flags & GFILEFLG_WRITE) && !(FsMemVMT.flags & GFSFLG_WRITEABLE)) - return FALSE; + return 0; // File is open - fill in all the details f->vmt = &FsMemVMT; - f->fd = memptr; - f->err = 0; + f->obj = memptr; f->pos = 0; f->flags |= GFILEFLG_OPEN|GFILEFLG_CANSEEK; - return TRUE; + return f; } } // No available slot - return FALSE; + return 0; } #endif @@ -379,7 +418,7 @@ void gfileClose(GFILE *f) { f->flags = 0; } -size_t gfileRead(GFILE *f, char *buf, size_t len) { +size_t gfileRead(GFILE *f, void *buf, size_t len) { size_t res; if (!f || (f->flags & (GFILEFLG_OPEN|GFILEFLG_READ)) != (GFILEFLG_OPEN|GFILEFLG_READ)) @@ -392,7 +431,7 @@ size_t gfileRead(GFILE *f, char *buf, size_t len) { return res; } -size_t gfileWrite(GFILE *f, const char *buf, size_t len) { +size_t gfileWrite(GFILE *f, const void *buf, size_t len) { size_t res; if (!f || (f->flags & (GFILEFLG_OPEN|GFILEFLG_WRITE)) != (GFILEFLG_OPEN|GFILEFLG_WRITE)) @@ -417,6 +456,7 @@ bool_t gfileSetPos(GFILE *f, long int pos) { if (!f->vmt->setpos || !f->vmt->setpos(f, pos)) return FALSE; f->pos = pos; + return TRUE; } long int gfileGetSize(GFILE *f) { @@ -442,16 +482,16 @@ bool_t gfileEOF(GFILE *f) { #include // Special String VMT - static int StringRead(GFILE *f, char *buf, int size) { + static int StringRead(GFILE *f, void *buf, int size) { // size must be 1 for a complete read if (!((char *)f->obj)[f->pos]) return 0; - buf[0] = ((char *)f->obj)[f->pos]; + ((char *)buf)[0] = ((char *)f->obj)[f->pos]; return 1; } - static int StringWrite(GFILE *f, const char *buf, int size) { + static int StringWrite(GFILE *f, const void *buf, int size) { // size must be 1 for a complete write - ((char *)f->obj)[f->pos] = buf[0]; + ((char *)f->obj)[f->pos] = ((char *)buf)[0]; return 1; } static const GFILEVMT StringVMT = { diff --git a/src/gfile/inc_chibiosfs.c b/src/gfile/inc_chibiosfs.c index b30a675f..87b8c110 100644 --- a/src/gfile/inc_chibiosfs.c +++ b/src/gfile/inc_chibiosfs.c @@ -14,8 +14,8 @@ ********************************************************/ static void ChibiOSBFSClose(GFILE *f); -static int ChibiOSBFSRead(GFILE *f, char *buf, int size); -static int ChibiOSBFSWrite(GFILE *f, char *buf, int size); +static int ChibiOSBFSRead(GFILE *f, void *buf, int size); +static int ChibiOSBFSWrite(GFILE *f, const void *buf, int size); static bool_t ChibiOSBFSSetpos(GFILE *f, long int pos); static long int ChibiOSBFSGetsize(GFILE *f); static bool_t ChibiOSBFSEof(GFILE *f); @@ -32,10 +32,10 @@ static const GFILEVMT FsCHIBIOSVMT = { static void ChibiOSBFSClose(GFILE *f) { chFileStreamClose(((BaseFileStream *)f->fd)); } -static int ChibiOSBFSRead(GFILE *f, char *buf, int size) { +static int ChibiOSBFSRead(GFILE *f, void *buf, int size) { return chSequentialStreamRead(((BaseFileStream *)f->fd), (uint8_t *)buf, size); } -static int ChibiOSBFSWrite(GFILE *f, char *buf, int size) { +static int ChibiOSBFSWrite(GFILE *f, const void *buf, int size) { return chSequentialStreamWrite(((BaseFileStream *)f->fd), (uint8_t *)buf, size); } static bool_t ChibiOSBFSSetpos(GFILE *f, long int pos) { diff --git a/src/gfile/inc_memfs.c b/src/gfile/inc_memfs.c index fee089ce..434150d8 100644 --- a/src/gfile/inc_memfs.c +++ b/src/gfile/inc_memfs.c @@ -15,8 +15,8 @@ #include -static int MEMRead(GFILE *f, char *buf, int size); -static int MEMWrite(GFILE *f, char *buf, int size); +static int MEMRead(GFILE *f, void *buf, int size); +static int MEMWrite(GFILE *f, const void *buf, int size); static bool_t MEMSetpos(GFILE *f, long int pos); static const GFILEVMT FsMemVMT = { @@ -28,14 +28,16 @@ static const GFILEVMT FsMemVMT = { MEMSetpos, 0, 0, }; -static int MEMRead(GFILE *f, char *buf, int size) { - memset(buf, ((char *)f->fd)+f->pos, size); +static int MEMRead(GFILE *f, void *buf, int size) { + memcpy(buf, ((char *)f->obj)+f->pos, size); return size; } -static int MEMWrite(GFILE *f, char *buf, int size) { - memset(((char *)f->fd)+f->pos, buf, size); +static int MEMWrite(GFILE *f, const void *buf, int size) { + memcpy(((char *)f->obj)+f->pos, buf, size); return size; } static bool_t MEMSetpos(GFILE *f, long int pos) { + (void) f; + (void) pos; return TRUE; } diff --git a/src/gfile/inc_nativefs.c b/src/gfile/inc_nativefs.c index df5e7861..390a885d 100644 --- a/src/gfile/inc_nativefs.c +++ b/src/gfile/inc_nativefs.c @@ -28,8 +28,8 @@ static long int NativeFilesize(const char *fname); static bool_t NativeRen(const char *oldname, const char *newname); static bool_t NativeOpen(GFILE *f, const char *fname); static void NativeClose(GFILE *f); -static int NativeRead(GFILE *f, char *buf, int size); -static int NativeWrite(GFILE *f, const char *buf, int size); +static int NativeRead(GFILE *f, void *buf, int size); +static int NativeWrite(GFILE *f, const void *buf, int size); static bool_t NativeSetpos(GFILE *f, long int pos); static long int NativeGetsize(GFILE *f); static bool_t NativeEof(GFILE *f); @@ -85,8 +85,8 @@ static bool_t NativeOpen(GFILE *f, const char *fname) { return TRUE; } static void NativeClose(GFILE *f) { fclose((FILE *)f->obj); } -static int NativeRead(GFILE *f, char *buf, int size) { return fread(buf, 1, size, (FILE *)f->obj); } -static int NativeWrite(GFILE *f, const char *buf, int size) { return fwrite(buf, 1, size, (FILE *)f->obj); } +static int NativeRead(GFILE *f, void *buf, int size) { return fread(buf, 1, size, (FILE *)f->obj); } +static int NativeWrite(GFILE *f, const void *buf, int size) { return fwrite(buf, 1, size, (FILE *)f->obj); } static bool_t NativeSetpos(GFILE *f, long int pos) { return fseek((FILE *)f->obj, pos, SEEK_SET) ? FALSE : TRUE; } diff --git a/src/gfile/inc_romfs.c b/src/gfile/inc_romfs.c index 5a780554..8d0e32c1 100644 --- a/src/gfile/inc_romfs.c +++ b/src/gfile/inc_romfs.c @@ -32,7 +32,7 @@ static bool_t ROMExists(const char *fname); static long int ROMFilesize(const char *fname); static bool_t ROMOpen(GFILE *f, const char *fname); static void ROMClose(GFILE *f); -static int ROMRead(GFILE *f, char *buf, int size); +static int ROMRead(GFILE *f, void *buf, int size); static bool_t ROMSetpos(GFILE *f, long int pos); static long int ROMGetsize(GFILE *f); static bool_t ROMEof(GFILE *f); @@ -72,7 +72,7 @@ static bool_t ROMOpen(GFILE *f, const char *fname) { return TRUE; } static void ROMClose(GFILE *f) { (void)f; } -static int ROMRead(GFILE *f, char *buf, int size) { +static int ROMRead(GFILE *f, void *buf, int size) { const ROMFS_DIRENTRY *p; p = (const ROMFS_DIRENTRY *)f->obj; -- cgit v1.2.3 From 695bcbee5b84cd2e152baca91c58bdc2e971b0d1 Mon Sep 17 00:00:00 2001 From: inmarket Date: Fri, 7 Feb 2014 14:06:08 +1000 Subject: Update GDISP image code to fully use new GFILE's --- src/gdisp/image.c | 153 ++++++++++++++++------------------------------- src/gdisp/image_bmp.c | 93 ++++++++++++++-------------- src/gdisp/image_gif.c | 105 ++++++++++++++++---------------- src/gdisp/image_native.c | 29 +++++---- 4 files changed, 164 insertions(+), 216 deletions(-) (limited to 'src') diff --git a/src/gdisp/image.c b/src/gdisp/image.c index dd219289..2b8395b0 100644 --- a/src/gdisp/image.c +++ b/src/gdisp/image.c @@ -16,39 +16,6 @@ #if GFX_USE_GDISP && GDISP_NEED_IMAGE -#include - -static gdispImageError imageOpen(gdispImage *img) { - gdispImageError err; - - img->bgcolor = White; - for(img->fns = ImageHandlers; img->fns < ImageHandlers+sizeof(ImageHandlers)/sizeof(ImageHandlers[0]); img->fns++) { - err = img->fns->open(img); - if (err != GDISP_IMAGE_ERR_BADFORMAT) { - if (!(err & GDISP_IMAGE_ERR_UNRECOVERABLE)) - return err; - goto unrecoverable; - } - img->io.fns->seek(&img->io, 0); - } - - err = GDISP_IMAGE_ERR_BADFORMAT; - img->type = GDISP_IMAGE_TYPE_UNKNOWN; - -unrecoverable: - img->fns->close(img); - img->flags = 0; - img->fns = 0; - img->priv = 0; - return err; -} - -gdispImageError - DEPRECATED("If possible please use gdispImageOpenFile(), gdispImageOpenMemory() or gdispImageOpenBaseFileStream() instead") - gdispImageOpen(gdispImage *img) { - return imageOpen(img); -} - #if GDISP_NEED_IMAGE_NATIVE extern gdispImageError gdispImageOpen_NATIVE(gdispImage *img); extern void gdispImageClose_NATIVE(gdispImage *img); @@ -130,92 +97,76 @@ static gdispImageHandlers ImageHandlers[] = { #endif }; -static size_t ImageGFileRead(struct gdispImageIO *pio, void *buf, size_t len) { - if (!pio->fd) return 0; - len = gfileRead((GFILE *)pio->fd, buf, len); - if ((int)len < 0) len = 0; - pio->pos += len; - return len; -} - -static void ImageGFileSeek(struct gdispImageIO *pio, size_t pos) { - if (!pio->fd) return; - if (pio->pos != pos) { - gfileSetPos((GFILE *)pio->fd, pos); - pio->pos = pos; - } -} - -static void ImageGFileClose(struct gdispImageIO *pio) { - if (!pio->fd) return; - gfileClose((GFILE *)pio->fd); - pio->fd = 0; - pio->pos = 0; +gdispImageError + DEPRECATED("Use gdispImageOpenGFile() instead") + gdispImageOpen(gdispImage *img) { + return gdispImageOpenGFile(img, img->f); } -static const gdispImageIOFunctions ImageGFileFunctions = - { ImageGFileRead, ImageGFileSeek, ImageGFileClose }; - #if GFILE_NEED_MEMFS - gdispImageError gdispImageOpenMemory(gdispImage *img, const void *memimage) { - img->io.fns = &ImageGFileFunctions; - img->io.pos = 0; - img->io.fd = gfileOpenMemory(memimage, "rb"); - if (!img->io.fd) - return GDISP_IMAGE_ERR_NOSUCHFILE; - return imageOpen(img); - } - - bool_t DEPRECATED("Use gdispImageOpenMemory() instead. GFX_USE_GFILE, GFILE_NEED_MEMFS must also be TRUE") gdispImageSetMemoryReader(gdispImage *img, const void *memimage) { - img->io.fns = &ImageGFileFunctions; - img->io.pos = 0; - img->io.fd = gfileOpenMemory(memimage, "rb"); - return img->io.fd != 0; + bool_t + DEPRECATED("Use gdispImageOpenMemory() instead") + gdispImageSetMemoryReader(gdispImage *img, const void *memimage) { + img->f = gfileOpenMemory((void *)memimage, "rb"); + return img->f != 0; } #endif -gdispImageError gdispImageOpenFile(gdispImage *img, const char *filename) { - img->io.fns = &ImageGFileFunctions; - img->io.pos = 0; - img->io.fd = gfileOpen(filename, "rb"); - if (!img->io.fd) - return GDISP_IMAGE_ERR_NOSUCHFILE; - return imageOpen(img); -} - #if defined(WIN32) || GFX_USE_OS_WIN32 || GFX_USE_OS_LINUX || GFX_USE_OS_OSX - bool_t DEPRECATED("Please use gdispImageOpenFile() instead. GFX_USE_GFILE must also be TRUE") gdispImageSetFileReader(gdispImage *img, const char *filename) { - img->io.fns = &ImageGFileFunctions; - img->io.pos = 0; - img->io.fd = gfileOpen(filename, "rb"); - return img->io.fd != 0; + bool_t + DEPRECATED("Use gdispImageOpenFile() instead") + gdispImageSetFileReader(gdispImage *img, const char *filename) { + img->f = gfileOpen(filename, "rb"); + return img->f != 0; } #endif #if GFILE_NEED_CHIBIOSFS && GFX_USE_OS_CHIBIOS - bool_t DEPRECATED("Use gdispImageOpenBaseFileStream() instead. GFX_USE_GFILE, GFILE_NEED_CHIBIOSFS must also be TRUE") gdispImageSetBaseFileStreamReader(gdispImage *img, void *BaseFileStreamPtr) { - img->io.fns = &ImageGFileFunctions; - img->io.pos = 0; - img->io.fd = gfileOpenBaseFileStream(BaseFileStreamPtr, "rb"); - return img->io.fd != 0; + bool_t + DEPRECATED("Use gdispImageOpenBaseFileStream() instead") + gdispImageSetBaseFileStreamReader(gdispImage *img, void *BaseFileStreamPtr) { + img->f = gfileOpenBaseFileStream(BaseFileStreamPtr, "rb"); + return img->f != 0; } +#endif + +gdispImageError gdispImageOpenGFile(gdispImage *img, GFILE *f) { + gdispImageError err; - gdispImageError gdispImageOpenBaseFileStream(gdispImage *img, void *BaseFileStreamPtr) { - img->io.fns = &ImageGFileFunctions; - img->io.pos = 0; - img->io.fd = gfileOpenBaseFileStream(BaseFileStreamPtr, "rb"); - if (!img->io.fd) - return GDISP_IMAGE_ERR_NOSUCHFILE; - return imageOpen(img); + if (!f) + return GDISP_IMAGE_ERR_NOSUCHFILE; + img->f = f; + img->bgcolor = White; + for(img->fns = ImageHandlers; img->fns < ImageHandlers+sizeof(ImageHandlers)/sizeof(ImageHandlers[0]); img->fns++) { + err = img->fns->open(img); + if (err != GDISP_IMAGE_ERR_BADFORMAT) { + if ((err & GDISP_IMAGE_ERR_UNRECOVERABLE)) + goto unrecoverable; + + // Everything is possible + return err; + } + + // Try the next decoder + gfileSetPos(img->f, 0); } -#endif + err = GDISP_IMAGE_ERR_BADFORMAT; + img->type = GDISP_IMAGE_TYPE_UNKNOWN; + +unrecoverable: + gfileClose(img->f); + img->f = 0; + img->flags = 0; + img->fns = 0; + img->priv = 0; + return err; +} void gdispImageClose(gdispImage *img) { if (img->fns) img->fns->close(img); - else - img->io.fns->close(&img->io); + gfileClose(img->f); img->type = GDISP_IMAGE_TYPE_UNKNOWN; img->flags = 0; img->fns = 0; @@ -223,7 +174,7 @@ void gdispImageClose(gdispImage *img) { } bool_t gdispImageIsOpen(gdispImage *img) { - return img->type != GDISP_IMAGE_TYPE_UNKNOWN && img->fns != 0; + return img->fns != 0; } void gdispImageSetBgColor(gdispImage *img, color_t bgcolor) { diff --git a/src/gdisp/image_bmp.c b/src/gdisp/image_bmp.c index 158d6edc..8ff40ca0 100644 --- a/src/gdisp/image_bmp.c +++ b/src/gdisp/image_bmp.c @@ -118,6 +118,19 @@ typedef struct gdispImagePrivate { pixel_t buf[BLIT_BUFFER_SIZE]; } gdispImagePrivate; +void gdispImageClose_BMP(gdispImage *img) { + if (img->priv) { +#if GDISP_NEED_IMAGE_BMP_1 || GDISP_NEED_IMAGE_BMP_4 || GDISP_NEED_IMAGE_BMP_4_RLE || GDISP_NEED_IMAGE_BMP_8 || GDISP_NEED_IMAGE_BMP_8_RLE + if (img->priv->palette) + gdispImageFree(img, (void *)img->priv->palette, img->priv->palsize*sizeof(color_t)); +#endif + if (img->priv->frame0cache) + gdispImageFree(img, (void *)img->priv->frame0cache, img->width*img->height*sizeof(pixel_t)); + gdispImageFree(img, (void *)img->priv, sizeof(gdispImagePrivate)); + img->priv = 0; + } +} + gdispImageError gdispImageOpen_BMP(gdispImage *img) { gdispImagePrivate *priv; uint8_t hdr[2]; @@ -126,7 +139,7 @@ gdispImageError gdispImageOpen_BMP(gdispImage *img) { uint32_t offsetColorTable; /* Read the file identifier */ - if (img->io.fns->read(&img->io, hdr, 2) != 2) + if (gfileRead(img->f, hdr, 2) != 2) return GDISP_IMAGE_ERR_BADFORMAT; // It can't be us /* Process the BITMAPFILEHEADER structure */ @@ -154,18 +167,18 @@ gdispImageError gdispImageOpen_BMP(gdispImage *img) { #endif /* Skip the size field and the 2 reserved fields */ - if (img->io.fns->read(&img->io, priv->buf, 8) != 8) + if (gfileRead(img->f, priv->buf, 8) != 8) goto baddatacleanup; /* Get the offset to the bitmap data */ - if (img->io.fns->read(&img->io, &priv->frame0pos, 4) != 4) + if (gfileRead(img->f, &priv->frame0pos, 4) != 4) goto baddatacleanup; CONVERT_FROM_DWORD_LE(priv->frame0pos); /* Process the BITMAPCOREHEADER structure */ /* Get the offset to the colour data */ - if (img->io.fns->read(&img->io, &offsetColorTable, 4) != 4) + if (gfileRead(img->f, &offsetColorTable, 4) != 4) goto baddatacleanup; CONVERT_FROM_DWORD_LE(offsetColorTable); offsetColorTable += 14; // Add the size of the BITMAPFILEHEADER @@ -175,7 +188,7 @@ gdispImageError gdispImageOpen_BMP(gdispImage *img) { img->priv->bmpflags |= BMP_V2; // Read the header - if (img->io.fns->read(&img->io, priv->buf, 12-4) != 12-4) + if (gfileRead(img->f, priv->buf, 12-4) != 12-4) goto baddatacleanup; // Get the width img->width = *(uint16_t *)(((uint8_t *)priv->buf)+0); @@ -224,7 +237,7 @@ gdispImageError gdispImageOpen_BMP(gdispImage *img) { priv->bmpflags |= BMP_V4; // Read the header - if (img->io.fns->read(&img->io, priv->buf, 40-4) != 40-4) + if (gfileRead(img->f, priv->buf, 40-4) != 40-4) goto baddatacleanup; // Get the width adword = *(uint32_t *)(((uint8_t *)priv->buf)+0); @@ -327,18 +340,18 @@ gdispImageError gdispImageOpen_BMP(gdispImage *img) { #if GDISP_NEED_IMAGE_BMP_1 || GDISP_NEED_IMAGE_BMP_4 || GDISP_NEED_IMAGE_BMP_4_RLE || GDISP_NEED_IMAGE_BMP_8 || GDISP_NEED_IMAGE_BMP_8_RLE /* Load the palette tables */ if (priv->bmpflags & BMP_PALETTE) { - img->io.fns->seek(&img->io, offsetColorTable); + gfileSetPos(img->f, offsetColorTable); if (!(priv->palette = (color_t *)gdispImageAlloc(img, priv->palsize*sizeof(color_t)))) return GDISP_IMAGE_ERR_NOMEMORY; if (priv->bmpflags & BMP_V2) { for(aword = 0; aword < priv->palsize; aword++) { - if (img->io.fns->read(&img->io, &priv->buf, 3) != 3) goto baddatacleanup; + if (gfileRead(img->f, &priv->buf, 3) != 3) goto baddatacleanup; priv->palette[aword] = RGB2COLOR(((uint8_t *)priv->buf)[2], ((uint8_t *)priv->buf)[1], ((uint8_t *)priv->buf)[0]); } } else { for(aword = 0; aword < priv->palsize; aword++) { - if (img->io.fns->read(&img->io, &priv->buf, 4) != 4) goto baddatacleanup; + if (gfileRead(img->f, &priv->buf, 4) != 4) goto baddatacleanup; priv->palette[aword] = RGB2COLOR(((uint8_t *)priv->buf)[2], ((uint8_t *)priv->buf)[1], ((uint8_t *)priv->buf)[0]); } } @@ -349,15 +362,15 @@ gdispImageError gdispImageOpen_BMP(gdispImage *img) { #if GDISP_NEED_IMAGE_BMP_16 || GDISP_NEED_IMAGE_BMP_32 /* Load the bit masks */ if (priv->bmpflags & BMP_COMP_MASK) { - img->io.fns->seek(&img->io, offsetColorTable); - if (img->io.fns->read(&img->io, &priv->maskred, 4) != 4) goto baddatacleanup; + gfileSetPos(img->f, offsetColorTable); + if (gfileRead(img->f, &priv->maskred, 4) != 4) goto baddatacleanup; CONVERT_FROM_DWORD_LE(priv->maskred); - if (img->io.fns->read(&img->io, &priv->maskgreen, 4) != 4) goto baddatacleanup; + if (gfileRead(img->f, &priv->maskgreen, 4) != 4) goto baddatacleanup; CONVERT_FROM_DWORD_LE(priv->maskgreen); - if (img->io.fns->read(&img->io, &priv->maskblue, 4) != 4) goto baddatacleanup; + if (gfileRead(img->f, &priv->maskblue, 4) != 4) goto baddatacleanup; CONVERT_FROM_DWORD_LE(priv->maskblue); if (priv->bmpflags & BMP_V4) { - if (img->io.fns->read(&img->io, &priv->maskalpha, 4) != 4) goto baddatacleanup; + if (gfileRead(img->f, &priv->maskalpha, 4) != 4) goto baddatacleanup; CONVERT_FROM_DWORD_LE(priv->maskalpha); } else priv->maskalpha = 0; @@ -419,20 +432,6 @@ unsupportedcleanup: return GDISP_IMAGE_ERR_UNSUPPORTED; // Not supported } -void gdispImageClose_BMP(gdispImage *img) { - if (img->priv) { -#if GDISP_NEED_IMAGE_BMP_1 || GDISP_NEED_IMAGE_BMP_4 || GDISP_NEED_IMAGE_BMP_4_RLE || GDISP_NEED_IMAGE_BMP_8 || GDISP_NEED_IMAGE_BMP_8_RLE - if (img->priv->palette) - gdispImageFree(img, (void *)img->priv->palette, img->priv->palsize*sizeof(color_t)); -#endif - if (img->priv->frame0cache) - gdispImageFree(img, (void *)img->priv->frame0cache, img->width*img->height*sizeof(pixel_t)); - gdispImageFree(img, (void *)img->priv, sizeof(gdispImagePrivate)); - img->priv = 0; - } - img->io.fns->close(&img->io); -} - static coord_t getPixels(gdispImage *img, coord_t x) { gdispImagePrivate * priv; color_t * pc; @@ -454,7 +453,7 @@ static coord_t getPixels(gdispImage *img, coord_t x) { len = 0; while(x < img->width && len <= BLIT_BUFFER_SIZE-32) { - if (img->io.fns->read(&img->io, &b, 4) != 4) + if (gfileRead(img->f, &b, 4) != 4) return 0; for(m=0x80; m; m >>= 1, pc++) @@ -499,7 +498,7 @@ static coord_t getPixels(gdispImage *img, coord_t x) { return len; } else if (priv->bmpflags & BMP_RLE_ABS) { while (priv->rlerun && len <= BLIT_BUFFER_SIZE-2 && x < img->width) { - if (img->io.fns->read(&img->io, &b, 1) != 1) + if (gfileRead(img->f, &b, 1) != 1) return 0; *pc++ = priv->palette[b[0] >> 4]; priv->rlerun--; @@ -514,8 +513,8 @@ static coord_t getPixels(gdispImage *img, coord_t x) { } if (priv->rlerun) // Return if we have more run to do return len; - if ((img->io.pos - priv->frame0pos)&1) { // Make sure we are on a word boundary - if (img->io.fns->read(&img->io, &b, 1) != 1) + if ((gfileGetPos(img->f) - priv->frame0pos)&1) { // Make sure we are on a word boundary + if (gfileRead(img->f, &b, 1) != 1) return 0; } } @@ -524,7 +523,7 @@ static coord_t getPixels(gdispImage *img, coord_t x) { priv->bmpflags &= ~(BMP_RLE_ENC|BMP_RLE_ABS); // There are always at least 2 bytes in an RLE code - if (img->io.fns->read(&img->io, &b, 2) != 2) + if (gfileRead(img->f, &b, 2) != 2) return 0; if (b[0]) { // Encoded mode @@ -541,7 +540,7 @@ static coord_t getPixels(gdispImage *img, coord_t x) { return len; } else if (b[1] == 2) { // Delta x, y // There are always at least 2 bytes in an RLE code - if (img->io.fns->read(&img->io, &b, 2) != 2) + if (gfileRead(img->f, &b, 2) != 2) return 0; priv->rlerun = b[0] + (uint16_t)b[1] * img->width; priv->rlecode = 0; // Who knows what color this should really be @@ -559,7 +558,7 @@ static coord_t getPixels(gdispImage *img, coord_t x) { uint8_t b[4]; while(x < img->width && len <= BLIT_BUFFER_SIZE-8) { - if (img->io.fns->read(&img->io, &b, 4) != 4) + if (gfileRead(img->f, &b, 4) != 4) return 0; *pc++ = priv->palette[b[0] >> 4]; @@ -599,7 +598,7 @@ static coord_t getPixels(gdispImage *img, coord_t x) { return len; } else if (priv->bmpflags & BMP_RLE_ABS) { while (priv->rlerun && len < BLIT_BUFFER_SIZE && x < img->width) { - if (img->io.fns->read(&img->io, &b, 1) != 1) + if (gfileRead(img->f, &b, 1) != 1) return 0; *pc++ = priv->palette[b[0]]; priv->rlerun--; @@ -608,8 +607,8 @@ static coord_t getPixels(gdispImage *img, coord_t x) { } if (priv->rlerun) // Return if we have more run to do return len; - if ((img->io.pos - priv->frame0pos)&1) { // Make sure we are on a word boundary - if (img->io.fns->read(&img->io, &b, 1) != 1) + if ((gfileGetPos(img->f) - priv->frame0pos)&1) { // Make sure we are on a word boundary + if (gfileRead(img->f, &b, 1) != 1) return 0; } } @@ -618,7 +617,7 @@ static coord_t getPixels(gdispImage *img, coord_t x) { priv->bmpflags &= ~(BMP_RLE_ENC|BMP_RLE_ABS); // There are always at least 2 bytes in an RLE code - if (img->io.fns->read(&img->io, &b, 2) != 2) + if (gfileRead(img->f, &b, 2) != 2) return 0; if (b[0]) { // Encoded mode @@ -635,7 +634,7 @@ static coord_t getPixels(gdispImage *img, coord_t x) { return len; } else if (b[1] == 2) { // Delta x, y // There are always at least 2 bytes in an RLE code - if (img->io.fns->read(&img->io, &b, 2) != 2) + if (gfileRead(img->f, &b, 2) != 2) return GDISP_IMAGE_ERR_BADDATA; priv->rlerun = b[0] + (uint16_t)b[1] * img->width; priv->rlecode = 0; // Who knows what color this should really be @@ -653,7 +652,7 @@ static coord_t getPixels(gdispImage *img, coord_t x) { uint8_t b[4]; while(x < img->width && len <= BLIT_BUFFER_SIZE-4) { - if (img->io.fns->read(&img->io, &b, 4) != 4) + if (gfileRead(img->f, &b, 4) != 4) return 0; *pc++ = priv->palette[b[0]]; @@ -675,7 +674,7 @@ static coord_t getPixels(gdispImage *img, coord_t x) { color_t r, g, b; while(x < img->width && len <= BLIT_BUFFER_SIZE-2) { - if (img->io.fns->read(&img->io, &w, 4) != 4) + if (gfileRead(img->f, &w, 4) != 4) return 0; CONVERT_FROM_WORD_LE(w[0]); CONVERT_FROM_WORD_LE(w[1]); @@ -720,7 +719,7 @@ static coord_t getPixels(gdispImage *img, coord_t x) { uint8_t b[3]; while(x < img->width && len < BLIT_BUFFER_SIZE) { - if (img->io.fns->read(&img->io, &b, 3) != 3) + if (gfileRead(img->f, &b, 3) != 3) return 0; *pc++ = RGB2COLOR(b[2], b[1], b[0]); x++; @@ -729,7 +728,7 @@ static coord_t getPixels(gdispImage *img, coord_t x) { if (x >= img->width) { // Make sure we have read a multiple of 4 bytes for the line - if ((x & 3) && img->io.fns->read(&img->io, &b, x & 3) != (x & 3)) + if ((x & 3) && gfileRead(img->f, &b, x & 3) != (x & 3)) return 0; } } @@ -743,7 +742,7 @@ static coord_t getPixels(gdispImage *img, coord_t x) { color_t r, g, b; while(x < img->width && len < BLIT_BUFFER_SIZE) { - if (img->io.fns->read(&img->io, &dw, 4) != 4) + if (gfileRead(img->f, &dw, 4) != 4) return 0; CONVERT_FROM_DWORD_LE(dw); if (priv->shiftred < 0) @@ -791,7 +790,7 @@ gdispImageError gdispImageCache_BMP(gdispImage *img) { return GDISP_IMAGE_ERR_NOMEMORY; /* Read the entire bitmap into cache */ - img->io.fns->seek(&img->io, priv->frame0pos); + gfileSetPos(img->f, priv->frame0pos); #if GDISP_NEED_IMAGE_BMP_4_RLE || GDISP_NEED_IMAGE_BMP_8_RLE priv->rlerun = 0; priv->rlecode = 0; @@ -847,7 +846,7 @@ gdispImageError gdispGImageDraw_BMP(GDisplay *g, gdispImage *img, coord_t x, coo } /* Start decoding from the beginning */ - img->io.fns->seek(&img->io, priv->frame0pos); + gfileSetPos(img->f, priv->frame0pos); #if GDISP_NEED_IMAGE_BMP_4_RLE || GDISP_NEED_IMAGE_BMP_8_RLE priv->rlerun = 0; priv->rlecode = 0; diff --git a/src/gdisp/image_gif.c b/src/gdisp/image_gif.c index 1ff72ff0..06f4ef6a 100644 --- a/src/gdisp/image_gif.c +++ b/src/gdisp/image_gif.c @@ -172,9 +172,9 @@ static gdispImageError startDecode(gdispImage *img) { // Local palette decode->maxpixel = priv->frame.palsize-1; decode->palette = (color_t *)(decode+1); - img->io.fns->seek(&img->io, priv->frame.pospal); + gfileSetPos(img->f, priv->frame.pospal); for(cnt = 0; cnt < priv->frame.palsize; cnt++) { - if (img->io.fns->read(&img->io, &decode->buf, 3) != 3) + if (gfileRead(img->f, &decode->buf, 3) != 3) goto baddatacleanup; decode->palette[cnt] = RGB2COLOR(decode->buf[0], decode->buf[1], decode->buf[2]); } @@ -188,8 +188,8 @@ static gdispImageError startDecode(gdispImage *img) { } // Get the initial lzw code size and values - img->io.fns->seek(&img->io, priv->frame.posimg); - if (img->io.fns->read(&img->io, &decode->bitsperpixel, 1) != 1 || decode->bitsperpixel >= MAX_CODE_BITS) + gfileSetPos(img->f, priv->frame.posimg); + if (gfileRead(img->f, &decode->bitsperpixel, 1) != 1 || decode->bitsperpixel >= MAX_CODE_BITS) goto baddatacleanup; decode->code_clear = 1 << decode->bitsperpixel; decode->code_eof = decode->code_clear + 1; @@ -273,8 +273,8 @@ static uint16_t getbytes(gdispImage *img) { // Get another code - a code is made up of decode->bitspercode bits. while (decode->shiftbits < decode->bitspercode) { // Get a byte - we may have to start a new data block - if ((!decode->blocksz && (img->io.fns->read(&img->io, &decode->blocksz, 1) != 1 || !decode->blocksz)) - || img->io.fns->read(&img->io, &bdata, 1) != 1) { + if ((!decode->blocksz && (gfileRead(img->f, &decode->blocksz, 1) != 1 || !decode->blocksz)) + || gfileRead(img->f, &bdata, 1) != 1) { // Pretend we got the EOF code - some encoders seem to just end the file decode->code_last = decode->code_eof; return cnt; @@ -302,8 +302,8 @@ static uint16_t getbytes(gdispImage *img) { if (code == decode->code_eof) { // Skip to the end of the data blocks do { - img->io.fns->seek(&img->io, img->io.pos+decode->blocksz); - } while (img->io.fns->read(&img->io, &decode->blocksz, 1) == 1 && decode->blocksz); + gfileSetPos(img->f, gfileGetPos(img->f)+decode->blocksz); + } while (gfileRead(img->f, &decode->blocksz, 1) == 1 && decode->blocksz); // Mark the end decode->code_last = decode->code_eof; @@ -398,8 +398,8 @@ static gdispImageError initFrame(gdispImage *img) { priv->dispose.height = priv->frame.height; // Check for a cached version of this image - for(cache=priv->cache; cache && cache->frame.posstart <= img->io.pos; cache=cache->next) { - if (cache->frame.posstart == img->io.pos) { + for(cache=priv->cache; cache && cache->frame.posstart <= (size_t)gfileGetPos(img->f); cache=cache->next) { + if (cache->frame.posstart == (size_t)gfileGetPos(img->f)) { priv->frame = cache->frame; priv->curcache = cache; return GDISP_IMAGE_ERR_OK; @@ -408,20 +408,20 @@ static gdispImageError initFrame(gdispImage *img) { // Get ready for a new image priv->curcache = 0; - priv->frame.posstart = img->io.pos; + priv->frame.posstart = gfileGetPos(img->f); priv->frame.flags = 0; priv->frame.delay = 0; priv->frame.palsize = 0; // Process blocks until we reach the image descriptor while(1) { - if (img->io.fns->read(&img->io, &blocktype, 1) != 1) + if (gfileRead(img->f, &blocktype, 1) != 1) return GDISP_IMAGE_ERR_BADDATA; switch(blocktype) { case 0x2C: //',' - IMAGE_DESC_RECORD_TYPE; // Read the Image Descriptor - if (img->io.fns->read(&img->io, priv->buf, 9) != 9) + if (gfileRead(img->f, priv->buf, 9) != 9) return GDISP_IMAGE_ERR_BADDATA; priv->frame.x = *(uint16_t *)(((uint8_t *)priv->buf)+0); CONVERT_FROM_WORD_LE(priv->frame.x); @@ -437,7 +437,7 @@ static gdispImageError initFrame(gdispImage *img) { priv->frame.flags |= GIFL_INTERLACE; // We are ready to go for the actual palette read and image decode - priv->frame.pospal = img->io.pos; + priv->frame.pospal = gfileGetPos(img->f); priv->frame.posimg = priv->frame.pospal+priv->frame.palsize*3; priv->frame.posend = 0; @@ -448,13 +448,13 @@ static gdispImageError initFrame(gdispImage *img) { case 0x21: //'!' - EXTENSION_RECORD_TYPE; // Read the extension type - if (img->io.fns->read(&img->io, &blocktype, 1) != 1) + if (gfileRead(img->f, &blocktype, 1) != 1) return GDISP_IMAGE_ERR_BADDATA; switch(blocktype) { case 0xF9: // EXTENSION - Graphics Control Block // Read the GCB - if (img->io.fns->read(&img->io, priv->buf, 6) != 6) + if (gfileRead(img->f, priv->buf, 6) != 6) return GDISP_IMAGE_ERR_BADDATA; // Check we have read a 4 byte data block and a data block terminator (0) if (((uint8_t *)priv->buf)[0] != 4 || ((uint8_t *)priv->buf)[5] != 0) @@ -485,7 +485,7 @@ static gdispImageError initFrame(gdispImage *img) { if (priv->flags & GIF_LOOP) goto skipdatablocks; // Read the Application header - if (img->io.fns->read(&img->io, priv->buf, 16) != 16) + if (gfileRead(img->f, priv->buf, 16) != 16) return GDISP_IMAGE_ERR_BADDATA; // Check we have read a 11 byte data block if (((uint8_t *)priv->buf)[0] != 11 && ((uint8_t *)priv->buf)[12] != 3) @@ -516,11 +516,11 @@ static gdispImageError initFrame(gdispImage *img) { // We don't understand this extension - just skip it by skipping data blocks skipdatablocks: while(1) { - if (img->io.fns->read(&img->io, &blocksz, 1) != 1) + if (gfileRead(img->f, &blocksz, 1) != 1) return GDISP_IMAGE_ERR_BADDATA; if (!blocksz) break; - img->io.fns->seek(&img->io, img->io.pos + blocksz); + gfileSetPos(img->f, gfileGetPos(img->f) + blocksz); } break; } @@ -537,7 +537,7 @@ static gdispImageError initFrame(gdispImage *img) { } // Seek back to frame0 - img->io.fns->seek(&img->io, priv->frame0pos); + gfileSetPos(img->f, priv->frame0pos); return GDISP_IMAGE_LOOP; default: // UNDEFINED_RECORD_TYPE; @@ -546,13 +546,34 @@ static gdispImageError initFrame(gdispImage *img) { } } +void gdispImageClose_GIF(gdispImage *img) { + gdispImagePrivate * priv; + imgcache * cache; + imgcache * ncache; + + priv = img->priv; + if (priv) { + // Free any stored frames + cache = priv->cache; + while(cache) { + ncache = cache->next; + gdispImageFree(img, (void *)cache, sizeof(imgcache)+cache->frame.width*cache->frame.height+cache->frame.palsize*sizeof(color_t)); + cache = ncache; + } + if (priv->palette) + gdispImageFree(img, (void *)priv->palette, priv->palsize*sizeof(color_t)); + gdispImageFree(img, (void *)img->priv, sizeof(gdispImagePrivate)); + img->priv = 0; + } +} + gdispImageError gdispImageOpen_GIF(gdispImage *img) { gdispImagePrivate *priv; uint8_t hdr[6]; uint16_t aword; /* Read the file identifier */ - if (img->io.fns->read(&img->io, hdr, 6) != 6) + if (gfileRead(img->f, hdr, 6) != 6) return GDISP_IMAGE_ERR_BADFORMAT; // It can't be us /* Process the GIFFILEHEADER structure */ @@ -580,7 +601,7 @@ gdispImageError gdispImageOpen_GIF(gdispImage *img) { /* Process the Screen Descriptor structure */ // Read the screen descriptor - if (img->io.fns->read(&img->io, priv->buf, 7) != 7) + if (gfileRead(img->f, priv->buf, 7) != 7) goto baddatacleanup; // Get the width img->width = *(uint16_t *)(((uint8_t *)priv->buf)+0); @@ -596,7 +617,7 @@ gdispImageError gdispImageOpen_GIF(gdispImage *img) { goto nomemcleanup; // Read the global palette for(aword = 0; aword < priv->palsize; aword++) { - if (img->io.fns->read(&img->io, &priv->buf, 3) != 3) + if (gfileRead(img->f, &priv->buf, 3) != 3) goto baddatacleanup; priv->palette[aword] = RGB2COLOR(((uint8_t *)priv->buf)[0], ((uint8_t *)priv->buf)[1], ((uint8_t *)priv->buf)[2]); } @@ -604,7 +625,7 @@ gdispImageError gdispImageOpen_GIF(gdispImage *img) { priv->bgcolor = ((uint8_t *)priv->buf)[5]; // Save the fram0pos - priv->frame0pos = img->io.pos; + priv->frame0pos = gfileGetPos(img->f); // Read the first frame descriptor switch(initFrame(img)) { @@ -628,28 +649,6 @@ gdispImageError gdispImageOpen_GIF(gdispImage *img) { } } -void gdispImageClose_GIF(gdispImage *img) { - gdispImagePrivate * priv; - imgcache * cache; - imgcache * ncache; - - priv = img->priv; - if (priv) { - // Free any stored frames - cache = priv->cache; - while(cache) { - ncache = cache->next; - gdispImageFree(img, (void *)cache, sizeof(imgcache)+cache->frame.width*cache->frame.height+cache->frame.palsize*sizeof(color_t)); - cache = ncache; - } - if (priv->palette) - gdispImageFree(img, (void *)priv->palette, priv->palsize*sizeof(color_t)); - gdispImageFree(img, (void *)img->priv, sizeof(gdispImagePrivate)); - img->priv = 0; - } - img->io.fns->close(&img->io); -} - gdispImageError gdispImageCache_GIF(gdispImage *img) { gdispImagePrivate * priv; imgcache * cache; @@ -786,7 +785,7 @@ gdispImageError gdispImageCache_GIF(gdispImage *img) { } // We could be pedantic here but extra bytes won't hurt us while(getbytes(img)); - priv->frame.posend = cache->frame.posend = img->io.pos; + priv->frame.posend = cache->frame.posend = gfileGetPos(img->f); // Save everything priv->curcache = cache; @@ -1150,7 +1149,7 @@ gdispImageError gdispGImageDraw_GIF(GDisplay *g, gdispImage *img, coord_t x, coo } // We could be pedantic here but extra bytes won't hurt us while (getbytes(img)); - priv->frame.posend = img->io.pos; + priv->frame.posend = gfileGetPos(img->f); stopDecode(img); return GDISP_IMAGE_ERR_OK; @@ -1173,19 +1172,19 @@ delaytime_t gdispImageNext_GIF(gdispImage *img) { // We need to get to the end of this frame if (!priv->frame.posend) { // We don't know where the end of the frame is yet - find it! - img->io.fns->seek(&img->io, priv->frame.posimg+1); // Skip the code size byte too + gfileSetPos(img->f, priv->frame.posimg+1); // Skip the code size byte too while(1) { - if (img->io.fns->read(&img->io, &blocksz, 1) != 1) + if (gfileRead(img->f, &blocksz, 1) != 1) return TIME_INFINITE; if (!blocksz) break; - img->io.fns->seek(&img->io, img->io.pos + blocksz); + gfileSetPos(img->f, gfileGetPos(img->f) + blocksz); } - priv->frame.posend = img->io.pos; + priv->frame.posend = gfileGetPos(img->f); } // Seek to the end of this frame - img->io.fns->seek(&img->io, priv->frame.posend); + gfileSetPos(img->f, priv->frame.posend); // Read the next frame descriptor for(blocksz=0; blocksz < 2; blocksz++) { // 2 loops max to prevent cycling forever with a bad file diff --git a/src/gdisp/image_native.c b/src/gdisp/image_native.c index 7f249ae8..c458531e 100644 --- a/src/gdisp/image_native.c +++ b/src/gdisp/image_native.c @@ -33,11 +33,20 @@ typedef struct gdispImagePrivate { pixel_t buf[BLIT_BUFFER_SIZE]; } gdispImagePrivate; +void gdispImageClose_NATIVE(gdispImage *img) { + if (img->priv) { + if (img->priv->frame0cache) + gdispImageFree(img, (void *)img->priv->frame0cache, img->width * img->height * sizeof(pixel_t)); + gdispImageFree(img, (void *)img->priv, sizeof(gdispImagePrivate)); + img->priv = 0; + } +} + gdispImageError gdispImageOpen_NATIVE(gdispImage *img) { uint8_t hdr[HEADER_SIZE]; /* Read the 8 byte header */ - if (img->io.fns->read(&img->io, hdr, 8) != 8) + if (gfileRead(img->f, hdr, 8) != 8) return GDISP_IMAGE_ERR_BADFORMAT; // It can't be us if (hdr[0] != 'N' || hdr[1] != 'I') @@ -60,16 +69,6 @@ gdispImageError gdispImageOpen_NATIVE(gdispImage *img) { return GDISP_IMAGE_ERR_OK; } -void gdispImageClose_NATIVE(gdispImage *img) { - if (img->priv) { - if (img->priv->frame0cache) - gdispImageFree(img, (void *)img->priv->frame0cache, img->width * img->height * sizeof(pixel_t)); - gdispImageFree(img, (void *)img->priv, sizeof(gdispImagePrivate)); - img->priv = 0; - } - img->io.fns->close(&img->io); -} - gdispImageError gdispImageCache_NATIVE(gdispImage *img) { size_t len; @@ -84,8 +83,8 @@ gdispImageError gdispImageCache_NATIVE(gdispImage *img) { return GDISP_IMAGE_ERR_NOMEMORY; /* Read the entire bitmap into cache */ - img->io.fns->seek(&img->io, FRAME0POS); - if (img->io.fns->read(&img->io, img->priv->frame0cache, len) != len) + gfileSetPos(img->f, FRAME0POS); + if (gfileRead(img->f, img->priv->frame0cache, len) != len) return GDISP_IMAGE_ERR_BADDATA; return GDISP_IMAGE_ERR_OK; @@ -112,12 +111,12 @@ gdispImageError gdispImageGDraw_NATIVE(GDisplay *g, gdispImage *img, coord_t x, /* Cycle through the lines */ for(;cy;cy--, y++) { /* Move to the start of the line */ - img->io.fns->seek(&img->io, pos); + gfileSetPos(img->f, pos); /* Draw the line in chunks using BitBlt */ for(mx = x, mcx = cx; mcx > 0; mcx -= len, mx += len) { // Read the data - len = img->io.fns->read(&img->io, + len = gfileRead(img->f, img->priv->buf, mcx > BLIT_BUFFER_SIZE ? (BLIT_BUFFER_SIZE*sizeof(pixel_t)) : (mcx * sizeof(pixel_t))) / sizeof(pixel_t); -- cgit v1.2.3 From bd4827922708efc85c878ebd17ca6a8c88bc75b5 Mon Sep 17 00:00:00 2001 From: inmarket Date: Fri, 7 Feb 2014 14:07:29 +1000 Subject: Update gwin Images to properly use new GFILE based images --- src/gwin/gimage.c | 55 ++----------------------------------------------------- 1 file changed, 2 insertions(+), 53 deletions(-) (limited to 'src') diff --git a/src/gwin/gimage.c b/src/gwin/gimage.c index b1f8e078..e4032b96 100644 --- a/src/gwin/gimage.c +++ b/src/gwin/gimage.c @@ -139,37 +139,11 @@ GHandle gwinGImageCreate(GDisplay *g, GImageObject *gobj, GWindowInit *pInit) { return (GHandle)gobj; } -bool_t gwinImageOpenMemory(GHandle gh, const void* memory) { +bool_t gwinImageOpenGFile(GHandle gh, GFILE *f) { if (gdispImageIsOpen(&widget(gh)->image)) gdispImageClose(&widget(gh)->image); - if (!gdispImageSetMemoryReader(&widget(gh)->image, memory)) - return FALSE; - - if (gdispImageOpen(&widget(gh)->image) != GDISP_IMAGE_ERR_OK) - return FALSE; - - if ((gh->flags & GWIN_FLG_VISIBLE)) { - // Setting the clip here shouldn't be necessary if the redraw doesn't overdraw - // but we put it in for safety anyway - #if GDISP_NEED_CLIP - gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height); - #endif - _redraw(gh); - } - - return TRUE; -} - -#if defined(WIN32) || GFX_USE_OS_WIN32 || GFX_USE_OS_LINUX || GFX_USE_OS_OSX || defined(__DOXYGEN__) -bool_t gwinImageOpenFile(GHandle gh, const char* filename) { - if (gdispImageIsOpen(&widget(gh)->image)) - gdispImageClose(&widget(gh)->image); - - if (!gdispImageSetFileReader(&widget(gh)->image, filename)) - return FALSE; - - if (gdispImageOpen(&widget(gh)->image) != GDISP_IMAGE_ERR_OK) + if ((gdispImageOpenGFile(&widget(gh)->image, f) & GDISP_IMAGE_ERR_UNRECOVERABLE)) return FALSE; if ((gh->flags & GWIN_FLG_VISIBLE)) { @@ -183,31 +157,6 @@ bool_t gwinImageOpenFile(GHandle gh, const char* filename) { return TRUE; } -#endif - -#if GFX_USE_OS_CHIBIOS || defined(__DOXYGEN__) -bool_t gwinImageOpenStream(GHandle gh, void *streamPtr) { - if (gdispImageIsOpen(&widget(gh)->image)) - gdispImageClose(&widget(gh)->image); - - if (!gdispImageSetBaseFileStreamReader(&widget(gh)->image, streamPtr)) - return FALSE; - - if (gdispImageOpen(&widget(gh)->image) != GDISP_IMAGE_ERR_OK) - return FALSE; - - if ((gh->flags & GWIN_FLG_VISIBLE)) { - // Setting the clip here shouldn't be necessary if the redraw doesn't overdraw - // but we put it in for safety anyway - #if GDISP_NEED_CLIP - gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height); - #endif - _redraw(gh); - } - - return TRUE; -} -#endif gdispImageError gwinImageCache(GHandle gh) { return gdispImageCache(&widget(gh)->image); -- cgit v1.2.3 From f7d6b9b58e4e8d979004026b41c1bfd275218fb9 Mon Sep 17 00:00:00 2001 From: inmarket Date: Fri, 7 Feb 2014 18:43:39 +1000 Subject: Bug fixes to GFILE. --- src/gfile/inc_nativefs.c | 28 ++++++++++++++++------------ src/gfile/inc_romfs.c | 20 ++++++++++++++------ 2 files changed, 30 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/gfile/inc_nativefs.c b/src/gfile/inc_nativefs.c index 390a885d..4ecb2004 100644 --- a/src/gfile/inc_nativefs.c +++ b/src/gfile/inc_nativefs.c @@ -16,7 +16,7 @@ #include #include #include -#include +//#include static GFILE NativeStdIn; static GFILE NativeStdOut; @@ -50,7 +50,7 @@ static const GFILEVMT FsNativeVMT = { #undef GFILE_CHAINHEAD #define GFILE_CHAINHEAD &FsNativeVMT -static char *flags2mode(char *buf, uint16_t flags) { +static void flags2mode(char *buf, uint16_t flags) { if (flags & GFILEFLG_MUSTEXIST) *buf = 'r'; else if (flags & GFILEFLG_APPEND) @@ -67,32 +67,36 @@ static char *flags2mode(char *buf, uint16_t flags) { *buf++ = 0; } -static bool_t NativeDel(const char *fname) { return remove(fname) ? FALSE : TRUE; } -static bool_t NativeExists(const char *fname) { return access(fname, 0) ? FALSE : TRUE; } +static bool_t NativeDel(const char *fname) { return remove(fname) ? FALSE : TRUE; } +static void NativeClose(GFILE *f) { fclose((FILE *)f->obj); } +static int NativeRead(GFILE *f, void *buf, int size) { return fread(buf, 1, size, (FILE *)f->obj); } +static int NativeWrite(GFILE *f, const void *buf, int size) { return fwrite(buf, 1, size, (FILE *)f->obj); } +static bool_t NativeSetpos(GFILE *f, long int pos) { return fseek((FILE *)f->obj, pos, SEEK_SET) ? FALSE : TRUE; } +static bool_t NativeEof(GFILE *f) { return feof((FILE *)f->obj) ? TRUE : FALSE; } +static bool_t NativeRen(const char *oldname, const char *newname) { return rename(oldname, newname) ? FALSE : TRUE; } +static bool_t NativeExists(const char *fname) { + // We define access this way so we don't have to include which may + // (and does under windows) contain conflicting definitions for types such as uint16_t. + extern int access(const char *pathname, int mode); + return access(fname, 0) ? FALSE : TRUE; +} static long int NativeFilesize(const char *fname) { struct stat st; if (stat(fname, &st)) return -1; return st.st_size; } -static bool_t NativeRen(const char *oldname, const char *newname) { return rename(oldname, newname) ? FALSE : TRUE }; static bool_t NativeOpen(GFILE *f, const char *fname) { FILE *fd; char mode[5]; + flags2mode(mode, f->flags); if (!(fd = fopen(fname, mode))) return FALSE; f->obj = (void *)fd; return TRUE; } -static void NativeClose(GFILE *f) { fclose((FILE *)f->obj); } -static int NativeRead(GFILE *f, void *buf, int size) { return fread(buf, 1, size, (FILE *)f->obj); } -static int NativeWrite(GFILE *f, const void *buf, int size) { return fwrite(buf, 1, size, (FILE *)f->obj); } -static bool_t NativeSetpos(GFILE *f, long int pos) { - return fseek((FILE *)f->obj, pos, SEEK_SET) ? FALSE : TRUE; -} static long int NativeGetsize(GFILE *f) { struct stat st; if (fstat(fileno((FILE *)f->obj), &st)) return -1; return st.st_size; } -static bool_t NativeEof(GFILE *f) { return feof((FILE *)f->obj) ? TRUE : FALSE; } diff --git a/src/gfile/inc_romfs.c b/src/gfile/inc_romfs.c index 8d0e32c1..49c1b173 100644 --- a/src/gfile/inc_romfs.c +++ b/src/gfile/inc_romfs.c @@ -15,11 +15,19 @@ #include +// What directory file formats do we understand +#define ROMFS_DIR_VER_MAX 0x0000 + +// Compression Formats +#define ROMFS_CMP_UNCOMPRESSED 0 + typedef struct ROMFS_DIRENTRY { - const struct ROMFS_DIRENTRY * next; - const char * name; - long int size; - const char * file; + uint16_t ver; // Directory Entry Version + uint16_t cmp; // Compression format + const struct ROMFS_DIRENTRY * next; // The next entry + const char * name; // The file name + long int size; // The file size + const char * file; // The file data } ROMFS_DIRENTRY; #define ROMFS_DIRENTRY_HEAD 0 @@ -48,11 +56,11 @@ static const GFILEVMT FsROMVMT = { #undef GFILE_CHAINHEAD #define GFILE_CHAINHEAD &FsROMVMT -static ROMFS_DIRENTRY *ROMFindFile(const char *fname) { +static const ROMFS_DIRENTRY *ROMFindFile(const char *fname) { const ROMFS_DIRENTRY *p; for(p = FsROMHead; p; p = p->next) { - if (!strcmp(p->name, fname)) + if (p->ver <= ROMFS_DIR_VER_MAX && p->cmp == ROMFS_CMP_UNCOMPRESSED && !strcmp(p->name, fname)) break; } return p; -- cgit v1.2.3