mirror of https://github.com/aap/librw.git
implemented image format registry
This commit is contained in:
parent
fd191856c4
commit
02921ff848
File diff suppressed because it is too large
Load Diff
|
@ -182,6 +182,7 @@ Engine::init(void)
|
|||
|
||||
// core plugin attach here
|
||||
Frame::registerModule();
|
||||
Image::registerModule();
|
||||
Raster::registerModule();
|
||||
Texture::registerModule();
|
||||
|
||||
|
@ -279,6 +280,10 @@ Engine::start(void)
|
|||
|
||||
engine->device.system(DEVICEFINALIZE, nil, 0);
|
||||
|
||||
// Register some image formats. Or should we leave that to the user?
|
||||
Image::registerFileFormat("tga", readTGA, writeTGA);
|
||||
Image::registerFileFormat("bmp", readBMP, writeBMP);
|
||||
|
||||
Engine::state = Started;
|
||||
return 1;
|
||||
}
|
||||
|
|
130
src/image.cpp
130
src/image.cpp
|
@ -21,6 +21,24 @@ namespace rw {
|
|||
|
||||
int32 Image::numAllocated;
|
||||
|
||||
struct FileAssociation
|
||||
{
|
||||
char *extension;
|
||||
Image *(*read)(const char *afilename);
|
||||
void (*write)(Image *image, const char *filename);
|
||||
};
|
||||
|
||||
struct ImageGlobals
|
||||
{
|
||||
char *searchPaths;
|
||||
int numSearchPaths;
|
||||
FileAssociation fileFormats[10];
|
||||
int numFileFormats;
|
||||
};
|
||||
int32 imageModuleOffset;
|
||||
|
||||
#define IMAGEGLOBAL(v) (PLUGINOFFSET(ImageGlobals, engine, imageModuleOffset)->v)
|
||||
|
||||
// Image formats are as follows:
|
||||
// 32 bit has 4 bytes: 8888 RGBA
|
||||
// 24 bit has 3 bytes: 888 RGB
|
||||
|
@ -474,9 +492,6 @@ Image::extractMask(void)
|
|||
return img;
|
||||
}
|
||||
|
||||
static char *searchPaths = nil;
|
||||
int numSearchPaths = 0;
|
||||
|
||||
static char*
|
||||
rwstrdup(const char *s)
|
||||
{
|
||||
|
@ -492,19 +507,20 @@ void
|
|||
Image::setSearchPath(const char *path)
|
||||
{
|
||||
char *p, *end;
|
||||
rwFree(searchPaths);
|
||||
numSearchPaths = 0;
|
||||
ImageGlobals *g = PLUGINOFFSET(ImageGlobals, engine, imageModuleOffset);
|
||||
rwFree(g->searchPaths);
|
||||
g->numSearchPaths = 0;
|
||||
if(path)
|
||||
searchPaths = p = rwstrdup(path);
|
||||
g->searchPaths = p = rwstrdup(path);
|
||||
else{
|
||||
searchPaths = nil;
|
||||
g->searchPaths = nil;
|
||||
return;
|
||||
}
|
||||
while(p && *p){
|
||||
end = strchr(p, ';');
|
||||
if(end)
|
||||
*end++ = '\0';
|
||||
numSearchPaths++;
|
||||
g->numSearchPaths++;
|
||||
p = end;
|
||||
}
|
||||
}
|
||||
|
@ -512,8 +528,9 @@ Image::setSearchPath(const char *path)
|
|||
void
|
||||
Image::printSearchPath(void)
|
||||
{
|
||||
char *p = searchPaths;
|
||||
for(int i = 0; i < numSearchPaths; i++){
|
||||
ImageGlobals *g = PLUGINOFFSET(ImageGlobals, engine, imageModuleOffset);
|
||||
char *p = g->searchPaths;
|
||||
for(int i = 0; i < g->numSearchPaths; i++){
|
||||
printf("%s\n", p);
|
||||
p += strlen(p) + 1;
|
||||
}
|
||||
|
@ -522,19 +539,23 @@ Image::printSearchPath(void)
|
|||
char*
|
||||
Image::getFilename(const char *name)
|
||||
{
|
||||
ImageGlobals *g = PLUGINOFFSET(ImageGlobals, engine, imageModuleOffset);
|
||||
FILE *f;
|
||||
char *s, *p = searchPaths;
|
||||
char *s, *p = g->searchPaths;
|
||||
size_t len = strlen(name)+1;
|
||||
if(numSearchPaths == 0){
|
||||
f = fopen(name, "rb");
|
||||
if(g->numSearchPaths == 0){
|
||||
s = rwstrdup(name);
|
||||
makePath(s);
|
||||
f = fopen(s, "rb");
|
||||
if(f){
|
||||
fclose(f);
|
||||
printf("found %s\n", name);
|
||||
return rwstrdup(name);
|
||||
printf("found %s\n", s);
|
||||
return s;
|
||||
}
|
||||
rwFree(s);
|
||||
return nil;
|
||||
}else
|
||||
for(int i = 0; i < numSearchPaths; i++){
|
||||
for(int i = 0; i < g->numSearchPaths; i++){
|
||||
s = (char*)rwMalloc(strlen(p)+len, MEMDUR_EVENT | ID_IMAGE);
|
||||
if(s == nil){
|
||||
RWERROR((ERR_ALLOC, strlen(p)+len));
|
||||
|
@ -542,6 +563,7 @@ Image::getFilename(const char *name)
|
|||
}
|
||||
strcpy(s, p);
|
||||
strcat(s, name);
|
||||
makePath(s);
|
||||
f = fopen(s, "r");
|
||||
if(f){
|
||||
fclose(f);
|
||||
|
@ -554,4 +576,80 @@ Image::getFilename(const char *name)
|
|||
return nil;
|
||||
}
|
||||
|
||||
Image*
|
||||
Image::read(const char *imageName)
|
||||
{
|
||||
int i;
|
||||
char *filename, *ext, *found;
|
||||
Image *img;
|
||||
|
||||
filename = rwNewT(char, strlen(imageName) + 20, MEMDUR_FUNCTION | ID_TEXTURE);
|
||||
strcpy(filename, imageName);
|
||||
ext = filename + strlen(filename);
|
||||
*ext++ = '.';
|
||||
// Try all supported extensions
|
||||
for(i = 0; i < IMAGEGLOBAL(numFileFormats); i++){
|
||||
if(IMAGEGLOBAL(fileFormats)[i].read == nil)
|
||||
continue;
|
||||
strncpy(ext, IMAGEGLOBAL(fileFormats)[i].extension, 19);
|
||||
found = getFilename(filename);
|
||||
// Found a file
|
||||
if(found){
|
||||
img = IMAGEGLOBAL(fileFormats)[i].read(found);
|
||||
rwFree(found);
|
||||
// It was a valid image of that format
|
||||
if(img){
|
||||
rwFree(filename);
|
||||
return img;
|
||||
}
|
||||
}
|
||||
}
|
||||
rwFree(filename);
|
||||
return nil;
|
||||
}
|
||||
|
||||
bool32
|
||||
Image::registerFileFormat(const char *ext, fileRead read, fileWrite write)
|
||||
{
|
||||
ImageGlobals *g = PLUGINOFFSET(ImageGlobals, engine, imageModuleOffset);
|
||||
if(g->numFileFormats >= nelem(g->fileFormats))
|
||||
return 0;
|
||||
g->fileFormats[g->numFileFormats].extension = rwstrdup(ext);
|
||||
g->fileFormats[g->numFileFormats].read = read;
|
||||
g->fileFormats[g->numFileFormats].write = write;
|
||||
g->numFileFormats++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void*
|
||||
imageOpen(void *object, int32 offset, int32 size)
|
||||
{
|
||||
imageModuleOffset = offset;
|
||||
ImageGlobals *g = PLUGINOFFSET(ImageGlobals, engine, imageModuleOffset);
|
||||
g->searchPaths = nil;
|
||||
g->numSearchPaths = 0;
|
||||
g->numFileFormats = 0;
|
||||
return object;
|
||||
}
|
||||
|
||||
static void*
|
||||
imageClose(void *object, int32 offset, int32 size)
|
||||
{
|
||||
ImageGlobals *g = PLUGINOFFSET(ImageGlobals, engine, imageModuleOffset);
|
||||
int i;
|
||||
rwFree(g->searchPaths);
|
||||
g->searchPaths = nil;
|
||||
g->numSearchPaths = 0;
|
||||
for(i = 0; i < g->numFileFormats; i++)
|
||||
rwFree(g->fileFormats[i].extension);
|
||||
g->numFileFormats = 0;
|
||||
return object;
|
||||
}
|
||||
|
||||
void
|
||||
Image::registerModule(void)
|
||||
{
|
||||
Engine::registerPlugin(sizeof(ImageGlobals), ID_IMAGEMODULE, imageOpen, imageClose);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
15
src/rwbase.h
15
src/rwbase.h
|
@ -596,9 +596,24 @@ enum PluginID
|
|||
enum CoreModuleID
|
||||
{
|
||||
ID_NAMODULE = MAKEPLUGINID(VEND_CRITERIONINT, 0x00),
|
||||
// vector
|
||||
// matrix
|
||||
ID_FRAMEMODULE = MAKEPLUGINID(VEND_CRITERIONINT, 0x03),
|
||||
// stream
|
||||
// camera
|
||||
ID_IMAGEMODULE = MAKEPLUGINID(VEND_CRITERIONINT, 0x06),
|
||||
ID_RASTERMODULE = MAKEPLUGINID(VEND_CRITERIONINT, 0x07),
|
||||
ID_TEXTUREMODULE = MAKEPLUGINID(VEND_CRITERIONINT, 0x08)
|
||||
// pip
|
||||
// immediate
|
||||
// resources
|
||||
// device
|
||||
// color
|
||||
// unused
|
||||
// error
|
||||
// metrics
|
||||
// driver
|
||||
// chunk group
|
||||
};
|
||||
|
||||
#define ECODE(c, s) c
|
||||
|
|
|
@ -149,6 +149,16 @@ struct Image
|
|||
static void setSearchPath(const char*);
|
||||
static void printSearchPath(void);
|
||||
static char *getFilename(const char*);
|
||||
static Image *read(const char *imageName);
|
||||
|
||||
|
||||
typedef Image *(*fileRead)(const char *afilename);
|
||||
typedef void (*fileWrite)(Image *image, const char *filename);
|
||||
static bool32 registerFileFormat(const char *ext, fileRead read, fileWrite write);
|
||||
|
||||
#ifndef RWPUBLIC
|
||||
static void registerModule(void);
|
||||
#endif
|
||||
};
|
||||
|
||||
Image *readTGA(const char *filename);
|
||||
|
|
|
@ -299,23 +299,14 @@ defaultFindCB(const char *name)
|
|||
}
|
||||
|
||||
|
||||
// TODO: no hardcoded file endings
|
||||
// TODO: actually read the mask!
|
||||
static Texture*
|
||||
defaultReadCB(const char *name, const char *mask)
|
||||
{
|
||||
Texture *tex;
|
||||
Image *img;
|
||||
char *n = (char*)rwMalloc(strlen(name) + 5, MEMDUR_FUNCTION | ID_TEXTURE);
|
||||
strcpy(n, name);
|
||||
strcat(n, ".tga");
|
||||
img = readTGA(n);
|
||||
if(img == nil){
|
||||
strcpy(n, name);
|
||||
strcat(n, ".bmp");
|
||||
img = readBMP(n);
|
||||
}
|
||||
rwFree(n);
|
||||
|
||||
img = Image::read(name);
|
||||
if(img){
|
||||
tex = Texture::create(Raster::createFromImage(img));
|
||||
strncpy(tex->name, name, 32);
|
||||
|
|
Loading…
Reference in New Issue