diff --git a/src/Makefile.am b/src/Makefile.am index e4f7f4f0..eb1b157a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -24,7 +24,12 @@ liblol_a_SOURCES = \ \ shader/shader.cpp shader/shader.h \ \ - image/image.cpp image/image.h \ + image/image.cpp image/image.h image/image-private.h \ + image/codec/android-image.cpp \ + image/codec/ios-image.cpp \ + image/codec/sdl-image.cpp \ + image/codec/ps3-image.cpp \ + image/codec/dummy-image.cpp \ \ loldebug.h \ debug/fps.cpp debug/fps.h debug/sphere.cpp debug/sphere.h \ diff --git a/src/image/codec/android-image.cpp b/src/image/codec/android-image.cpp new file mode 100644 index 00000000..b4b13bf9 --- /dev/null +++ b/src/image/codec/android-image.cpp @@ -0,0 +1,136 @@ +// +// Lol Engine +// +// Copyright: (c) 2010-2011 Sam Hocevar +// This program is free software; you can redistribute it and/or +// modify it under the terms of the Do What The Fuck You Want To +// Public License, Version 2, as published by Sam Hocevar. See +// http://sam.zoy.org/projects/COPYING.WTFPL for more details. +// + +#if defined HAVE_CONFIG_H +# include "config.h" +#endif + +#if defined __ANDROID__ + +#include + +#include +#include + +#include "core.h" +#include "image-private.h" + +using namespace std; + +namespace lol +{ + +extern JavaVM *g_vm; +extern jobject g_activity; + +/* + * Image implementation class + */ + +DECLARE_IMAGE_LOADER(AndroidImageData, 100) +{ +public: + virtual bool Open(char const *); + virtual bool Close(); + + virtual void *GetData() const; + +private: + jobject bmp; + jintArray array; + jint *pixels; +}; + +bool AndroidImageData::Open(char const *path) +{ + JNIEnv *env; + jint res = g_vm->GetEnv((void **)&env, JNI_VERSION_1_2); + if (res < 0) + { +#if !LOL_RELEASE + Log::Error("could not get JVM environment\n"); +#endif + exit(1); + } + jclass cls = env->GetObjectClass(g_activity); + jmethodID mid; + + mid = env->GetMethodID(cls, "openImage", + "(Ljava/lang/String;)Landroid/graphics/Bitmap;"); + jstring name = env->NewStringUTF(path); + bmp = env->CallObjectMethod(g_activity, mid, name); + env->DeleteLocalRef(name); + if (!bmp) + { +#if !LOL_RELEASE + Log::Error("could not load %s\n", path); +#endif + exit(1); + } + env->NewGlobalRef(bmp); + + /* Get image dimensions */ + mid = env->GetMethodID(cls, "getWidth", "(Landroid/graphics/Bitmap;)I"); + size.x = env->CallIntMethod(g_activity, mid, bmp); + mid = env->GetMethodID(cls, "getHeight", "(Landroid/graphics/Bitmap;)I"); + size.y = env->CallIntMethod(g_activity, mid, bmp); + + /* Get pixels */ + array = env->NewIntArray(size.x * size.y); + env->NewGlobalRef(array); + mid = env->GetMethodID(cls, "getPixels", "(Landroid/graphics/Bitmap;[I)V"); + env->CallVoidMethod(g_activity, mid, bmp, array); + + pixels = env->GetIntArrayElements(array, 0); + for (int n = 0; n < size.x * size.y; n++) + { + uint32_t u = pixels[n]; + u = (u & 0xff00ff00) | ((u & 0xff0000) >> 16) | ((u & 0xff) << 16); + pixels[n] = u; + } + format = FORMAT_RGBA; + + return true; +} + +bool AndroidImageData::Close() +{ + JNIEnv *env; + jint res = g_vm->GetEnv((void **)&env, JNI_VERSION_1_2); + if (res < 0) + { +#if !LOL_RELEASE + Log::Error("could not get JVM environment\n"); +#endif + exit(1); + } + jclass cls = env->GetObjectClass(g_activity); + jmethodID mid; + + env->ReleaseIntArrayElements(array, pixels, 0); + env->DeleteGlobalRef(array); + + /* Free image */ + mid = env->GetMethodID(cls, "closeImage", "(Landroid/graphics/Bitmap;)V"); + env->CallVoidMethod(g_activity, mid, bmp); + env->DeleteGlobalRef(bmp); + + return true; +} + +void * AndroidImageData::GetData() const +{ + return pixels; +} + +} /* namespace lol */ + +#endif /* __ANDROID__ */ + diff --git a/src/image/codec/dummy-image.cpp b/src/image/codec/dummy-image.cpp new file mode 100644 index 00000000..3b8a9962 --- /dev/null +++ b/src/image/codec/dummy-image.cpp @@ -0,0 +1,76 @@ +// +// Lol Engine +// +// Copyright: (c) 2010-2011 Sam Hocevar +// This program is free software; you can redistribute it and/or +// modify it under the terms of the Do What The Fuck You Want To +// Public License, Version 2, as published by Sam Hocevar. See +// http://sam.zoy.org/projects/COPYING.WTFPL for more details. +// + +#if defined HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "core.h" +#include "image/image-private.h" + +using namespace std; + +namespace lol +{ + +/* + * Image implementation class + */ + +DECLARE_IMAGE_LOADER(DummyImageData, 0) +{ +public: + virtual bool Open(char const *); + virtual bool Close(); + + virtual void *GetData() const; + +private: + uint8_t *pixels; +}; + +/* + * Public Image class + */ + +bool DummyImageData::Open(char const *path) +{ + size = 256; + format = Image::FORMAT_RGBA; + pixels = (uint8_t *)malloc(256 * 256 * 4 * sizeof(*pixels)); + uint8_t *parser = pixels; + for (int j = 0; j < 256; j++) + for (int i = 0; i < 256; i++) + { + *parser++ = ((i ^ j) & 1) * 0xff; + *parser++ = (uint8_t)i; + *parser++ = (uint8_t)j; + *parser++ = (((i >> 4) ^ (j >> 4)) & 1) * 0xff; + } + + return true; +} + +bool DummyImageData::Close() +{ + free(pixels); + + return true; +} + +void * DummyImageData::GetData() const +{ + return pixels; +} + +} /* namespace lol */ + diff --git a/src/image/codec/ios-image.cpp b/src/image/codec/ios-image.cpp new file mode 100644 index 00000000..b4d440b4 --- /dev/null +++ b/src/image/codec/ios-image.cpp @@ -0,0 +1,101 @@ +// +// Lol Engine +// +// Copyright: (c) 2010-2011 Sam Hocevar +// This program is free software; you can redistribute it and/or +// modify it under the terms of the Do What The Fuck You Want To +// Public License, Version 2, as published by Sam Hocevar. See +// http://sam.zoy.org/projects/COPYING.WTFPL for more details. +// + +#if defined HAVE_CONFIG_H +# include "config.h" +#endif + +#if defined __APPLE__ && defined __MACH__ + +#include +#import + +#include "core.h" + +using namespace std; + +namespace lol +{ + +/* + * Image implementation class + */ + +DECLARE_IMAGE_LOADER(IosImageData, 100) +{ +public: + virtual bool Open(char const *); + virtual bool Close(); + + virtual void *GetData() const; + +private: + uint8_t *pixels; +}; + +/* + * Public Image class + */ + +bool IosImageData::Open(char const *path) +{ + NSString *fullpath = [NSString stringWithUTF8String:path]; + NSArray *chunks = [fullpath componentsSeparatedByString: @"/"]; + NSString *filename = [chunks objectAtIndex: [chunks count] - 1]; + chunks = [filename componentsSeparatedByString: @"."]; + NSString *prefix = [chunks objectAtIndex: 0]; + NSString *mypath = [[NSBundle mainBundle] pathForResource:prefix ofType:@"png"]; + NSData *pngdata = [[NSData alloc] initWithContentsOfFile:mypath]; + UIImage *image = [[UIImage alloc] initWithData:pngdata]; + if (!image) + { +#if !LOL_RELEASE + Log::Error("could not load %s\n", path); +#endif + exit(1); + } + + int w = CGImageGetWidth(image.CGImage); + int h = CGImageGetHeight(image.CGImage); + size = ivec2(w, h); + format = FORMAT_RGBA; + + CGColorSpaceRef cspace = CGColorSpaceCreateDeviceRGB(); + pixels = (uint8_t *)malloc(w * h * 4); + CGContextRef ctx = + CGBitmapContextCreate(pixels, w, h, 8, 4 * w, cspace, + kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big); + CGColorSpaceRelease(cspace); + CGContextClearRect(ctx, CGRectMake(0, 0, w, h)); + CGContextTranslateCTM(ctx, 0, h - h); + CGContextDrawImage(ctx, CGRectMake(0, 0, w, h), image.CGImage); + CGContextRelease(ctx); + [image release]; + [pngdata release]; + + return true; +} + +bool IosImageData::Close() +{ + free(pixels); + + return true; +} + +void * IosImageData::GetData() const +{ + return pixels; +} + +} /* namespace lol */ + +#endif /* defined __APPLE__ && defined __MACH__ */ + diff --git a/src/image/codec/ps3-image.cpp b/src/image/codec/ps3-image.cpp new file mode 100644 index 00000000..3ba5dc10 --- /dev/null +++ b/src/image/codec/ps3-image.cpp @@ -0,0 +1,203 @@ +// +// Lol Engine +// +// Copyright: (c) 2010-2011 Sam Hocevar +// This program is free software; you can redistribute it and/or +// modify it under the terms of the Do What The Fuck You Want To +// Public License, Version 2, as published by Sam Hocevar. See +// http://sam.zoy.org/projects/COPYING.WTFPL for more details. +// + +#if defined HAVE_CONFIG_H +# include "config.h" +#endif + +#if defined __CELLOS_LV2__ + +#include + +#include +#include + +#include "core.h" + +using namespace std; + +namespace lol +{ + +/* + * Image implementation class + */ + +DECLARE_IMAGE_LOADER(Ps3ImageData, 100) +{ +public: + virtual bool Open(char const *); + virtual bool Close(); + + virtual void *GetData() const; + +private: + static void* Malloc(uint32_t size, void* data) { return malloc(size); }; + static int32_t Free(void* ptr, void* data) { free(ptr); return 0; }; + uint8_t *pixels; +}; + +/* + * Public Image class + */ + +bool Ps3ImageData::Open(char const *path) +{ + int32_t err; + + /* Initialise decoding library */ + CellPngDecMainHandle hmain; + + err = cellSysmoduleLoadModule(CELL_SYSMODULE_FS); + if (err != CELL_OK) + { +#if !LOL_RELEASE + Log::Error("could not open Fs sysmodule\n"); +#endif + exit(1); + } + + err = cellSysmoduleLoadModule(CELL_SYSMODULE_PNGDEC); + if (err != CELL_OK) + { +#if !LOL_RELEASE + Log::Error("could not open PngDec sysmodule\n"); +#endif + exit(1); + } + + CellPngDecThreadInParam in_param; + in_param.spuThreadEnable = CELL_PNGDEC_SPU_THREAD_ENABLE; + in_param.ppuThreadPriority = 1000; + in_param.spuThreadPriority = 200; + in_param.cbCtrlMallocFunc = ImageData::Malloc; + in_param.cbCtrlMallocArg = NULL; + in_param.cbCtrlFreeFunc = ImageData::Free; + in_param.cbCtrlFreeArg = NULL; + CellPngDecThreadOutParam out_param; + err = cellPngDecCreate(&hmain, &in_param, &out_param); + if (err != CELL_OK) + { +#if !LOL_RELEASE + Log::Error("could not create PngDec library\n"); +#endif + exit(1); + } + + /* Create decoder */ + CellPngDecSubHandle hsub; + + char file[1024]; + sprintf(file, "/app_home/c:/Users/s.hocevar/lolengine/%s", path); + + CellPngDecSrc dec_src; + dec_src.srcSelect = CELL_PNGDEC_FILE; + dec_src.fileName = file; + dec_src.fileOffset = 0; + dec_src.fileSize = 0; + dec_src.streamPtr = NULL; + dec_src.streamSize = 0; + dec_src.spuThreadEnable = CELL_PNGDEC_SPU_THREAD_ENABLE; + CellPngDecOpnInfo open_info; + err = cellPngDecOpen(hmain, &hsub, &dec_src, &open_info); + if (err != CELL_OK) + { +#if !LOL_RELEASE + Log::Error("could not open %s for decoding\n", file); +#endif + exit(1); + } + + CellPngDecInfo info; + err = cellPngDecReadHeader(hmain, hsub, &info); + if (err != CELL_OK) + { +#if !LOL_RELEASE + Log::Error("could not read image header\n"); +#endif + exit(1); + } + + CellPngDecInParam in_dec_param; + in_dec_param.commandPtr = NULL; + in_dec_param.outputMode = CELL_PNGDEC_TOP_TO_BOTTOM; + in_dec_param.outputColorSpace = CELL_PNGDEC_RGBA; + in_dec_param.outputBitDepth = 8; + in_dec_param.outputPackFlag = CELL_PNGDEC_1BYTE_PER_1PIXEL; + in_dec_param.outputAlphaSelect = CELL_PNGDEC_STREAM_ALPHA; + in_dec_param.outputColorAlpha = 0xff; + CellPngDecOutParam out_dec_param; + err = cellPngDecSetParameter(hmain, hsub, &in_dec_param, &out_dec_param); + if (err != CELL_OK) + { +#if !LOL_RELEASE + Log::Error("could not configure PngDec decoder\n"); +#endif + exit(1); + } + + /* Decode image */ + size = ivec2(info.imageWidth, info.imageHeight); + format = FORMAT_RGBA; + pixels = (uint8_t *)malloc(info.imageWidth * 4 * info.imageHeight); + CellPngDecDataCtrlParam data_ctrl_param; + data_ctrl_param.outputBytesPerLine = info.imageWidth * 4; + CellPngDecDataOutInfo data_out_info; + err = cellPngDecDecodeData(hmain, hsub, pixels, + &data_ctrl_param, &data_out_info); + if (err != CELL_OK) + { +#if !LOL_RELEASE + Log::Error("could not run PngDec decoder\n"); +#endif + exit(1); + } + + /* Close decoder */ + err = cellPngDecClose(hmain, hsub); + if (err != CELL_OK) + { +#if !LOL_RELEASE + Log::Error("could not close PngDec decoder\n"); +#endif + exit(1); + } + + /* Deinitialise library */ + err = cellPngDecDestroy(hmain); + if (err != CELL_OK) + { +#if !LOL_RELEASE + Log::Error("could not destroy PngDec decoder\n"); +#endif + exit(1); + } + err = cellSysmoduleUnloadModule(CELL_SYSMODULE_PNGDEC); + err = cellSysmoduleUnloadModule(CELL_SYSMODULE_FS); + + return true; +} + +bool Ps3ImageData::Close() +{ + free(pixels); + + return true; +} + +void * Ps3ImageData::GetData() const +{ + return pixels; +} + +} /* namespace lol */ + +#endif /* defined __CELLOS_LV2__ */ + diff --git a/src/image/codec/sdl-image.cpp b/src/image/codec/sdl-image.cpp new file mode 100644 index 00000000..63a7c6c2 --- /dev/null +++ b/src/image/codec/sdl-image.cpp @@ -0,0 +1,86 @@ +// +// Lol Engine +// +// Copyright: (c) 2010-2011 Sam Hocevar +// This program is free software; you can redistribute it and/or +// modify it under the terms of the Do What The Fuck You Want To +// Public License, Version 2, as published by Sam Hocevar. See +// http://sam.zoy.org/projects/COPYING.WTFPL for more details. +// + +#if defined HAVE_CONFIG_H +# include "config.h" +#endif + +#if defined USE_SDL_IMAGE + +#include + +#include +#include + +#include "core.h" +#include "image/image-private.h" + +using namespace std; + +namespace lol +{ + +/* + * Image implementation class + */ + +DECLARE_IMAGE_LOADER(SdlImageData, 50) +{ +public: + virtual bool Open(char const *); + virtual bool Close(); + + virtual void *GetData() const; + +private: + SDL_Surface *img; +}; + +/* + * Public Image class + */ + +bool SdlImageData::Open(char const *path) +{ + for (char const *name = path; *name; name++) + if ((img = IMG_Load(name))) + break; + + if (!img) + { +#if !LOL_RELEASE + Log::Error("could not load %s\n", path); +#endif + SDL_Quit(); + exit(1); + } + + size = ivec2(img->w, img->h); + format = img->format->Amask ? Image::FORMAT_RGBA : Image::FORMAT_RGB; + + return true; +} + +bool SdlImageData::Close() +{ + SDL_FreeSurface(img); + + return true; +} + +void * SdlImageData::GetData() const +{ + return img->pixels; +} + +} /* namespace lol */ + +#endif /* defined USE_SDL_IMAGE */ + diff --git a/src/image/image-private.h b/src/image/image-private.h new file mode 100644 index 00000000..b03b1d72 --- /dev/null +++ b/src/image/image-private.h @@ -0,0 +1,127 @@ +// +// Lol Engine +// +// Copyright: (c) 2010-2011 Sam Hocevar +// This program is free software; you can redistribute it and/or +// modify it under the terms of the Do What The Fuck You Want To +// Public License, Version 2, as published by Sam Hocevar. See +// http://sam.zoy.org/projects/COPYING.WTFPL for more details. +// + +// +// The ImageData class +// ------------------- +// + +#if !defined __LOL_IMAGE_PRIVATE_H__ +#define __LOL_IMAGE_PRIVATE_H__ + +#include "image.h" + +namespace lol +{ + +class ImageLoader +{ + friend class Image; + friend class ImageData; + +public: + ImageData *(*fun)(char const *path); + ImageLoader *next; + int priority; + + static bool RegisterAllLoaders(); + + static void RegisterLoader(ImageLoader *loader) + { + Helper(loader); + } + +private: + static ImageData *Load(char const *path) + { + ImageLoader *parser = Helper(NULL); + ImageData *ret = NULL; + + while (parser && !ret) + { + ret = parser->fun(path); + parser = parser->next; + } + + return ret; + } + + static ImageLoader *Helper(ImageLoader *set) + { + static ImageLoader *loaders = NULL; + + if (!set) + return loaders; + + ImageLoader **parser = &loaders; + while (*parser && (*parser)->priority > set->priority) + parser = &(*parser)->next; + set->next = *parser; + *parser = set; + + return NULL; + } +}; + +class ImageData +{ + friend class Image; + +public: + virtual bool Open(char const *) = 0; + virtual bool Close() = 0; + + virtual void *GetData() const = 0; + +protected: + ivec2 size; + Image::format_t format; + +private: +}; + +#define REGISTER_IMAGE_LOADER(name) \ + extern void (Register##name)(); \ + Register##name(); + +#define DECLARE_IMAGE_LOADER(name, prio) \ + template class name##ImageLoader : public ImageLoader \ + { \ + public: \ + name##ImageLoader() \ + { \ + static ImageLoader loader; \ + loader.fun = Load; \ + loader.priority = prio; \ + RegisterLoader(&loader); \ + } \ + static ImageData *Load(char const *path) \ + { \ + T *ret = new T(); \ + if (!ret->Open(path)) \ + { \ + delete ret; \ + return NULL; \ + } \ + return ret; \ + } \ + }; \ + class name; \ + name##ImageLoader name##ImageLoaderInstance; \ + void Register##name() \ + { \ + (void)&name##ImageLoaderInstance; \ + } \ + class name : public ImageData + +} /* namespace lol */ + +#endif // __LOL_IMAGE_PRIVATE_H__ + diff --git a/src/image/image.cpp b/src/image/image.cpp index c55740e3..63a928d3 100644 --- a/src/image/image.cpp +++ b/src/image/image.cpp @@ -14,310 +14,42 @@ #include -#if defined __APPLE__ && defined __MACH__ -# import -#elif defined USE_SDL_IMAGE -# include -# include -#elif defined __ANDROID__ -# include -# include -#elif defined __CELLOS_LV2__ -# include -# include -#endif - #include "core.h" +#include "image-private.h" using namespace std; namespace lol { +bool ImageLoader::RegisterAllLoaders() +{ #if defined __ANDROID__ -extern JavaVM *g_vm; -extern jobject g_activity; + REGISTER_IMAGE_LOADER(AndroidImageData) #endif - -/* - * Image implementation class - */ - -class ImageData -{ - friend class Image; - -private: - ivec2 size; - Image::format_t format; - + REGISTER_IMAGE_LOADER(DummyImageData) #if defined __APPLE__ && defined __MACH__ - uint8_t *pixels; -#elif defined USE_SDL_IMAGE - SDL_Surface *img; -#elif defined __ANDROID__ - jobject bmp; - jintArray array; - jint *pixels; -#elif defined __CELLOS_LV2__ - static void* Malloc(uint32_t size, void* data) { return malloc(size); }; - static int32_t Free(void* ptr, void* data) { free(ptr); return 0; }; - uint8_t *pixels; -#else - uint8_t *pixels; + REGISTER_IMAGE_LOADER(IosImageData) #endif -}; +#if defined __CELLOS_LV2__ + REGISTER_IMAGE_LOADER(Ps3ImageData) +#endif +#if defined USE_SDL_IMAGE + REGISTER_IMAGE_LOADER(SdlImageData) +#endif + + return true; +} /* * Public Image class */ Image::Image(char const *path) - : data(new ImageData()) { -#if defined __APPLE__ && defined __MACH__ - NSString *fullpath = [NSString stringWithUTF8String:path]; - NSArray *chunks = [fullpath componentsSeparatedByString: @"/"]; - NSString *filename = [chunks objectAtIndex: [chunks count] - 1]; - chunks = [filename componentsSeparatedByString: @"."]; - NSString *prefix = [chunks objectAtIndex: 0]; - NSString *mypath = [[NSBundle mainBundle] pathForResource:prefix ofType:@"png"]; - NSData *pngdata = [[NSData alloc] initWithContentsOfFile:mypath]; - UIImage *image = [[UIImage alloc] initWithData:pngdata]; - if (!image) - { -#if !LOL_RELEASE - Log::Error("could not load %s\n", path); -#endif - exit(1); - } - - int w = CGImageGetWidth(image.CGImage); - int h = CGImageGetHeight(image.CGImage); - data->size = ivec2(w, h); - data->format = FORMAT_RGBA; - - CGColorSpaceRef cspace = CGColorSpaceCreateDeviceRGB(); - data->pixels = (uint8_t *)malloc(w * h * 4); - CGContextRef ctx = - CGBitmapContextCreate(data->pixels, w, h, 8, 4 * w, cspace, - kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big); - CGColorSpaceRelease(cspace); - CGContextClearRect(ctx, CGRectMake(0, 0, w, h)); - CGContextTranslateCTM(ctx, 0, h - h); - CGContextDrawImage(ctx, CGRectMake(0, 0, w, h), image.CGImage); - CGContextRelease(ctx); - [image release]; - [pngdata release]; -#elif defined USE_SDL_IMAGE - for (char const *name = path; *name; name++) - if ((data->img = IMG_Load(name))) - break; - - if (!data->img) - { -#if !LOL_RELEASE - Log::Error("could not load %s\n", path); -#endif - SDL_Quit(); - exit(1); - } - - data->size = ivec2(data->img->w, data->img->h); - data->format = data->img->format->Amask ? FORMAT_RGBA : FORMAT_RGB; -#elif defined __ANDROID__ - JNIEnv *env; - jint res = g_vm->GetEnv((void **)&env, JNI_VERSION_1_2); - if (res < 0) - { -#if !LOL_RELEASE - Log::Error("could not get JVM environment\n"); -#endif - exit(1); - } - jclass cls = env->GetObjectClass(g_activity); - jmethodID mid; - - mid = env->GetMethodID(cls, "openImage", - "(Ljava/lang/String;)Landroid/graphics/Bitmap;"); - jstring name = env->NewStringUTF(path); - data->bmp = env->CallObjectMethod(g_activity, mid, name); - env->DeleteLocalRef(name); - if (!data->bmp) - { -#if !LOL_RELEASE - Log::Error("could not load %s\n", path); -#endif - exit(1); - } - env->NewGlobalRef(data->bmp); - - /* Get image dimensions */ - mid = env->GetMethodID(cls, "getWidth", "(Landroid/graphics/Bitmap;)I"); - data->size.x = env->CallIntMethod(g_activity, mid, data->bmp); - mid = env->GetMethodID(cls, "getHeight", "(Landroid/graphics/Bitmap;)I"); - data->size.y = env->CallIntMethod(g_activity, mid, data->bmp); - - /* Get pixels */ - data->array = env->NewIntArray(data->size.x * data->size.y); - env->NewGlobalRef(data->array); - mid = env->GetMethodID(cls, "getPixels", "(Landroid/graphics/Bitmap;[I)V"); - env->CallVoidMethod(g_activity, mid, data->bmp, data->array); - - data->pixels = env->GetIntArrayElements(data->array, 0); - for (int n = 0; n < data->size.x * data->size.y; n++) - { - uint32_t u = data->pixels[n]; - u = (u & 0xff00ff00) | ((u & 0xff0000) >> 16) | ((u & 0xff) << 16); - data->pixels[n] = u; - } - data->format = FORMAT_RGBA; -#elif defined __CELLOS_LV2__ - int32_t err; + static bool unused = ImageLoader::RegisterAllLoaders(); - /* Initialise decoding library */ - CellPngDecMainHandle hmain; - - err = cellSysmoduleLoadModule(CELL_SYSMODULE_FS); - if (err != CELL_OK) - { -#if !LOL_RELEASE - Log::Error("could not open Fs sysmodule\n"); -#endif - exit(1); - } - - err = cellSysmoduleLoadModule(CELL_SYSMODULE_PNGDEC); - if (err != CELL_OK) - { -#if !LOL_RELEASE - Log::Error("could not open PngDec sysmodule\n"); -#endif - exit(1); - } - - CellPngDecThreadInParam in_param; - in_param.spuThreadEnable = CELL_PNGDEC_SPU_THREAD_ENABLE; - in_param.ppuThreadPriority = 1000; - in_param.spuThreadPriority = 200; - in_param.cbCtrlMallocFunc = ImageData::Malloc; - in_param.cbCtrlMallocArg = NULL; - in_param.cbCtrlFreeFunc = ImageData::Free; - in_param.cbCtrlFreeArg = NULL; - CellPngDecThreadOutParam out_param; - err = cellPngDecCreate(&hmain, &in_param, &out_param); - if (err != CELL_OK) - { -#if !LOL_RELEASE - Log::Error("could not create PngDec library\n"); -#endif - exit(1); - } - - /* Create decoder */ - CellPngDecSubHandle hsub; - - char file[1024]; - sprintf(file, "/app_home/c:/Users/s.hocevar/lolengine/%s", path); - - CellPngDecSrc dec_src; - dec_src.srcSelect = CELL_PNGDEC_FILE; - dec_src.fileName = file; - dec_src.fileOffset = 0; - dec_src.fileSize = 0; - dec_src.streamPtr = NULL; - dec_src.streamSize = 0; - dec_src.spuThreadEnable = CELL_PNGDEC_SPU_THREAD_ENABLE; - CellPngDecOpnInfo open_info; - err = cellPngDecOpen(hmain, &hsub, &dec_src, &open_info); - if (err != CELL_OK) - { -#if !LOL_RELEASE - Log::Error("could not open %s for decoding\n", file); -#endif - exit(1); - } - - CellPngDecInfo info; - err = cellPngDecReadHeader(hmain, hsub, &info); - if (err != CELL_OK) - { -#if !LOL_RELEASE - Log::Error("could not read image header\n"); -#endif - exit(1); - } - - CellPngDecInParam in_dec_param; - in_dec_param.commandPtr = NULL; - in_dec_param.outputMode = CELL_PNGDEC_TOP_TO_BOTTOM; - in_dec_param.outputColorSpace = CELL_PNGDEC_RGBA; - in_dec_param.outputBitDepth = 8; - in_dec_param.outputPackFlag = CELL_PNGDEC_1BYTE_PER_1PIXEL; - in_dec_param.outputAlphaSelect = CELL_PNGDEC_STREAM_ALPHA; - in_dec_param.outputColorAlpha = 0xff; - CellPngDecOutParam out_dec_param; - err = cellPngDecSetParameter(hmain, hsub, &in_dec_param, &out_dec_param); - if (err != CELL_OK) - { -#if !LOL_RELEASE - Log::Error("could not configure PngDec decoder\n"); -#endif - exit(1); - } - - /* Decode image */ - data->size = ivec2(info.imageWidth, info.imageHeight); - data->format = FORMAT_RGBA; - data->pixels = (uint8_t *)malloc(info.imageWidth * 4 * info.imageHeight); - CellPngDecDataCtrlParam data_ctrl_param; - data_ctrl_param.outputBytesPerLine = info.imageWidth * 4; - CellPngDecDataOutInfo data_out_info; - err = cellPngDecDecodeData(hmain, hsub, data->pixels, - &data_ctrl_param, &data_out_info); - if (err != CELL_OK) - { -#if !LOL_RELEASE - Log::Error("could not run PngDec decoder\n"); -#endif - exit(1); - } - - /* Close decoder */ - err = cellPngDecClose(hmain, hsub); - if (err != CELL_OK) - { -#if !LOL_RELEASE - Log::Error("could not close PngDec decoder\n"); -#endif - exit(1); - } - - /* Deinitialise library */ - err = cellPngDecDestroy(hmain); - if (err != CELL_OK) - { -#if !LOL_RELEASE - Log::Error("could not destroy PngDec decoder\n"); -#endif - exit(1); - } - err = cellSysmoduleUnloadModule(CELL_SYSMODULE_PNGDEC); - err = cellSysmoduleUnloadModule(CELL_SYSMODULE_FS); -#else - data->size = 256; - data->format = FORMAT_RGBA; - data->pixels = (uint8_t *)malloc(256 * 256 * 4 * sizeof(*data->pixels)); - uint8_t *parser = data->pixels; - for (int j = 0; j < 256; j++) - for (int i = 0; i < 256; i++) - { - *parser++ = ((i ^ j) & 1) * 0xff; - *parser++ = (uint8_t)i; - *parser++ = (uint8_t)j; - *parser++ = (((i >> 4) ^ (j >> 4)) & 1) * 0xff; - } -#endif + data = ImageLoader::Load(path); } ivec2 Image::GetSize() const @@ -332,50 +64,12 @@ Image::format_t Image::GetFormat() const void * Image::GetData() const { -#if defined __APPLE__ && defined __MACH__ - return data->pixels; -#elif defined USE_SDL_IMAGE - return data->img->pixels; -#elif defined __ANDROID__ - return data->pixels; -#elif defined __CELLOS_LV2__ - return data->pixels; -#else - return data->pixels; -#endif + return data->GetData(); } Image::~Image() { -#if defined __APPLE__ && defined __MACH__ - free(data->pixels); -#elif defined USE_SDL_IMAGE - SDL_FreeSurface(data->img); -#elif defined __ANDROID__ - JNIEnv *env; - jint res = g_vm->GetEnv((void **)&env, JNI_VERSION_1_2); - if (res < 0) - { -#if !LOL_RELEASE - Log::Error("could not get JVM environment\n"); -#endif - exit(1); - } - jclass cls = env->GetObjectClass(g_activity); - jmethodID mid; - - env->ReleaseIntArrayElements(data->array, data->pixels, 0); - env->DeleteGlobalRef(data->array); - - /* Free image */ - mid = env->GetMethodID(cls, "closeImage", "(Landroid/graphics/Bitmap;)V"); - env->CallVoidMethod(g_activity, mid, data->bmp); - env->DeleteGlobalRef(data->bmp); -#elif defined __CELLOS_LV2__ - free(data->pixels); -#else - free(data->pixels); -#endif + data->Close(); delete data; }