// // 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 <cstdio> #if defined __APPLE__ && defined __MACH__ # #elif defined USE_SDL # include <SDL.h> # include <SDL_image.h> #elif defined ANDROID_NDK # include <jni.h> # include <android/log.h> #endif #include "core.h" namespace lol { #if defined ANDROID_NDK extern JNIEnv *g_env; extern jobject g_ctx; #endif /* * Image implementation class */ class ImageData { friend class Image; private: vec2i size; Image::format_t format; #if defined __APPLE__ && defined __MACH__ uint8_t *pixels; #elif defined USE_SDL SDL_Surface *img; #elif defined ANDROID_NDK jobject bmp; jintArray array; jint *pixels; #else uint8_t *pixels; #endif }; /* * Public Image class */ Image::Image(char const *path) : data(new ImageData()) { #if defined __APPLE__ && defined __MACH__ NSString *path = [[NSBundle mainBundle] pathForResource:@"ascii" ofType:@"png"]; NSData *pngdata = [[NSData alloc] initWithContentsOfFile:path]; UIImage *image = [[UIImage alloc] initWithData:pngdata]; if (!image) { #if !LOL_RELEASE fprintf(stderr, "ERROR: could not load %s\n", path); #endif exit(1); } int w = CGImageGetWidth(image.CGImage); int h = CGImageGetHeight(image.CGImage); data->size = vec2i(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 for (char const *name = path; *name; name++) if ((data->img = IMG_Load(name))) break; if (!data->img) { #if !LOL_RELEASE fprintf(stderr, "ERROR: could not load %s\n", path); #endif SDL_Quit(); exit(1); } data->size = vec2i(data->img->w, data->img->h); data->format = data->img->format->Amask ? FORMAT_RGBA : FORMAT_RGB; #elif defined ANDROID_NDK jclass cls = g_env->GetObjectClass(g_ctx); jmethodID mid; mid = g_env->GetMethodID(cls, "openImage", "(Ljava/lang/String;)Landroid/graphics/Bitmap;"); jstring name = g_env->NewStringUTF(path); data->bmp = g_env->CallObjectMethod(g_ctx, mid, name); g_env->DeleteLocalRef(name); g_env->NewGlobalRef(data->bmp); /* Get image dimensions */ mid = g_env->GetMethodID(cls, "getWidth", "(Landroid/graphics/Bitmap;)I"); data->size.x = g_env->CallIntMethod(g_ctx, mid, data->bmp); mid = g_env->GetMethodID(cls, "getHeight", "(Landroid/graphics/Bitmap;)I"); data->size.y = g_env->CallIntMethod(g_ctx, mid, data->bmp); /* Get pixels */ data->array = g_env->NewIntArray(data->size.x * data->size.y); g_env->NewGlobalRef(data->array); mid = g_env->GetMethodID(cls, "getPixels", "(Landroid/graphics/Bitmap;[I)V"); g_env->CallVoidMethod(g_ctx, mid, data->bmp, data->array); data->pixels = g_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; #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 } vec2i Image::GetSize() const { return data->size; } Image::format_t Image::GetFormat() const { return data->format; } void * Image::GetData() const { #if defined __APPLE__ && defined __MACH__ return data->pixels; #elif defined USE_SDL return data->img->pixels; #elif defined ANDROID_NDK return data->pixels; #else return data->pixels; #endif } Image::~Image() { #if defined __APPLE__ && defined __MACH__ free(data->pixels); #elif defined USE_SDL SDL_FreeSurface(data->img); #elif defined ANDROID_NDK jclass cls = g_env->GetObjectClass(g_ctx); jmethodID mid; g_env->ReleaseIntArrayElements(data->array, data->pixels, 0); g_env->DeleteGlobalRef(data->array); /* Free image */ mid = g_env->GetMethodID(cls, "closeImage", "(Landroid/graphics/Bitmap;)V"); g_env->CallVoidMethod(g_ctx, mid, data->bmp); g_env->DeleteGlobalRef(data->bmp); #else free(data->pixels); #endif delete data; } } /* namespace lol */