Преглед изворни кода

core: implement dynamic registration of image loaders.

legacy
Sam Hocevar sam пре 13 година
родитељ
комит
c61ae1ffa7
8 измењених фајлова са 754 додато и 326 уклоњено
  1. +6
    -1
      src/Makefile.am
  2. +136
    -0
      src/image/codec/android-image.cpp
  3. +76
    -0
      src/image/codec/dummy-image.cpp
  4. +101
    -0
      src/image/codec/ios-image.cpp
  5. +203
    -0
      src/image/codec/ps3-image.cpp
  6. +86
    -0
      src/image/codec/sdl-image.cpp
  7. +127
    -0
      src/image/image-private.h
  8. +19
    -325
      src/image/image.cpp

+ 6
- 1
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 \


+ 136
- 0
src/image/codec/android-image.cpp Прегледај датотеку

@@ -0,0 +1,136 @@
//
// Lol Engine
//
// Copyright: (c) 2010-2011 Sam Hocevar <sam@hocevar.net>
// 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 <cmath>

#include <jni.h>
#include <android/log.h>

#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__ */


+ 76
- 0
src/image/codec/dummy-image.cpp Прегледај датотеку

@@ -0,0 +1,76 @@
//
// Lol Engine
//
// Copyright: (c) 2010-2011 Sam Hocevar <sam@hocevar.net>
// 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 <cmath>

#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 */


+ 101
- 0
src/image/codec/ios-image.cpp Прегледај датотеку

@@ -0,0 +1,101 @@
//
// Lol Engine
//
// Copyright: (c) 2010-2011 Sam Hocevar <sam@hocevar.net>
// 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 <cmath>
#import <UIKit/UIKit.h>

#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__ */


+ 203
- 0
src/image/codec/ps3-image.cpp Прегледај датотеку

@@ -0,0 +1,203 @@
//
// Lol Engine
//
// Copyright: (c) 2010-2011 Sam Hocevar <sam@hocevar.net>
// 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 <cmath>

#include <cell/sysmodule.h>
#include <cell/codec/pngdec.h>

#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__ */


+ 86
- 0
src/image/codec/sdl-image.cpp Прегледај датотеку

@@ -0,0 +1,86 @@
//
// Lol Engine
//
// Copyright: (c) 2010-2011 Sam Hocevar <sam@hocevar.net>
// 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 <cmath>

#include <SDL.h>
#include <SDL_image.h>

#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 */


+ 127
- 0
src/image/image-private.h Прегледај датотеку

@@ -0,0 +1,127 @@
//
// Lol Engine
//
// Copyright: (c) 2010-2011 Sam Hocevar <sam@hocevar.net>
// 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<typename T> 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> name##ImageLoaderInstance; \
void Register##name() \
{ \
(void)&name##ImageLoaderInstance; \
} \
class name : public ImageData

} /* namespace lol */

#endif // __LOL_IMAGE_PRIVATE_H__


+ 19
- 325
src/image/image.cpp Прегледај датотеку

@@ -14,310 +14,42 @@

#include <cmath>

#if defined __APPLE__ && defined __MACH__
# import <UIKit/UIKit.h>
#elif defined USE_SDL_IMAGE
# include <SDL.h>
# include <SDL_image.h>
#elif defined __ANDROID__
# include <jni.h>
# include <android/log.h>
#elif defined __CELLOS_LV2__
# include <cell/sysmodule.h>
# include <cell/codec/pngdec.h>
#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;
}



Loading…
Откажи
Сачувај