source: trunk/src/image.cpp @ 758

Last change on this file since 758 was 758, checked in by sam, 10 years ago

ps3: start a minimal PS3 port using PSGL, but not CG yet.

File size: 5.6 KB
Line 
1//
2// Lol Engine
3//
4// Copyright: (c) 2010-2011 Sam Hocevar <sam@hocevar.net>
5//   This program is free software; you can redistribute it and/or
6//   modify it under the terms of the Do What The Fuck You Want To
7//   Public License, Version 2, as published by Sam Hocevar. See
8//   http://sam.zoy.org/projects/COPYING.WTFPL for more details.
9//
10
11#if defined HAVE_CONFIG_H
12#   include "config.h"
13#endif
14
15#include <cmath>
16
17#if defined __APPLE__ && defined __MACH__
18#   import <UIKit/UIKit.h>
19#elif defined USE_SDL
20#   include <SDL.h>
21#   include <SDL_image.h>
22#elif defined ANDROID_NDK
23#   include <jni.h>
24#   include <android/log.h>
25#endif
26
27#include "core.h"
28
29using namespace std;
30
31namespace lol
32{
33
34#if defined ANDROID_NDK
35extern JNIEnv *g_env;
36extern jobject g_ctx;
37#endif
38
39/*
40 * Image implementation class
41 */
42
43class ImageData
44{
45    friend class Image;
46
47private:
48    vec2i size;
49    Image::format_t format;
50
51#if defined __APPLE__ && defined __MACH__
52    uint8_t *pixels;
53#elif defined USE_SDL
54    SDL_Surface *img;
55#elif defined ANDROID_NDK
56    jobject bmp;
57    jintArray array;
58    jint *pixels;
59#else
60    uint8_t *pixels;
61#endif
62};
63
64/*
65 * Public Image class
66 */
67
68Image::Image(char const *path)
69  : data(new ImageData())
70{
71#if defined __APPLE__ && defined __MACH__
72        NSString *fullpath = [NSString stringWithUTF8String:path];
73        NSArray *chunks = [fullpath componentsSeparatedByString: @"/"];
74        NSString *filename = [chunks objectAtIndex: [chunks count] - 1];
75        chunks = [filename componentsSeparatedByString: @"."];
76        NSString *prefix = [chunks objectAtIndex: 0];
77    NSString *mypath = [[NSBundle mainBundle] pathForResource:prefix ofType:@"png"];
78    NSData *pngdata = [[NSData alloc] initWithContentsOfFile:mypath];
79    UIImage *image = [[UIImage alloc] initWithData:pngdata];
80    if (!image)
81    {
82#if !LOL_RELEASE
83        Log::Error("could not load %s\n", path);
84#endif
85        exit(1);
86    }
87
88    int w = CGImageGetWidth(image.CGImage);
89    int h = CGImageGetHeight(image.CGImage);
90    data->size = vec2i(w, h);
91    data->format = FORMAT_RGBA;
92
93    CGColorSpaceRef cspace = CGColorSpaceCreateDeviceRGB();
94    data->pixels = (uint8_t *)malloc(w * h * 4);
95    CGContextRef ctx =
96            CGBitmapContextCreate(data->pixels, w, h, 8, 4 * w, cspace,
97                    kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
98    CGColorSpaceRelease(cspace);
99    CGContextClearRect(ctx, CGRectMake(0, 0, w, h));
100    CGContextTranslateCTM(ctx, 0, h - h);
101    CGContextDrawImage(ctx, CGRectMake(0, 0, w, h), image.CGImage);
102    CGContextRelease(ctx);
103    [image release];
104    [pngdata release];
105#elif defined USE_SDL
106    for (char const *name = path; *name; name++)
107        if ((data->img = IMG_Load(name)))
108            break;
109
110    if (!data->img)
111    {
112#if !LOL_RELEASE
113        Log::Error("could not load %s\n", path);
114#endif
115        SDL_Quit();
116        exit(1);
117    }
118
119    data->size = vec2i(data->img->w, data->img->h);
120    data->format = data->img->format->Amask ? FORMAT_RGBA : FORMAT_RGB;
121#elif defined ANDROID_NDK
122    jclass cls = g_env->GetObjectClass(g_ctx);
123    jmethodID mid;
124
125    mid = g_env->GetMethodID(cls, "openImage",
126                             "(Ljava/lang/String;)Landroid/graphics/Bitmap;");
127    jstring name = g_env->NewStringUTF(path);
128    data->bmp = g_env->CallObjectMethod(g_ctx, mid, name);
129    g_env->DeleteLocalRef(name);
130    g_env->NewGlobalRef(data->bmp);
131
132    /* Get image dimensions */
133    mid = g_env->GetMethodID(cls, "getWidth", "(Landroid/graphics/Bitmap;)I");
134    data->size.x = g_env->CallIntMethod(g_ctx, mid, data->bmp);
135    mid = g_env->GetMethodID(cls, "getHeight", "(Landroid/graphics/Bitmap;)I");
136    data->size.y = g_env->CallIntMethod(g_ctx, mid, data->bmp);
137
138    /* Get pixels */
139    data->array = g_env->NewIntArray(data->size.x * data->size.y);
140    g_env->NewGlobalRef(data->array);
141    mid = g_env->GetMethodID(cls, "getPixels", "(Landroid/graphics/Bitmap;[I)V");
142    g_env->CallVoidMethod(g_ctx, mid, data->bmp, data->array);
143
144    data->pixels = g_env->GetIntArrayElements(data->array, 0);
145    for (int n = 0; n < data->size.x * data->size.y; n++)
146    {
147        uint32_t u = data->pixels[n];
148        u = (u & 0xff00ff00) | ((u & 0xff0000) >> 16) | ((u & 0xff) << 16);
149        data->pixels[n] = u;
150    }
151    data->format = FORMAT_RGBA;
152#else
153    data->size = 256;
154    data->format = FORMAT_RGBA;
155    data->pixels = (uint8_t *)malloc(256 * 256 * 4 * sizeof(*data->pixels));
156    uint8_t *parser = data->pixels;
157    for (int j = 0; j < 256; j++)
158        for (int i = 0; i < 256; i++)
159        {
160            *parser++ = ((i ^ j) & 1) * 0xff;
161            *parser++ = (uint8_t)i;
162            *parser++ = (uint8_t)j;
163            *parser++ = (((i >> 4) ^ (j >> 4)) & 1) * 0xff;
164        }
165#endif
166}
167
168vec2i Image::GetSize() const
169{
170    return data->size;
171}
172
173Image::format_t Image::GetFormat() const
174{
175    return data->format;
176}
177
178void * Image::GetData() const
179{
180#if defined __APPLE__ && defined __MACH__
181    return data->pixels;
182#elif defined USE_SDL
183    return data->img->pixels;
184#elif defined ANDROID_NDK
185    return data->pixels;
186#else
187    return data->pixels;
188#endif
189}
190
191Image::~Image()
192{
193#if defined __APPLE__ && defined __MACH__
194    free(data->pixels);
195#elif defined USE_SDL
196    SDL_FreeSurface(data->img);
197#elif defined ANDROID_NDK
198    jclass cls = g_env->GetObjectClass(g_ctx);
199    jmethodID mid;
200
201    g_env->ReleaseIntArrayElements(data->array, data->pixels, 0);
202    g_env->DeleteGlobalRef(data->array);
203
204    /* Free image */
205    mid = g_env->GetMethodID(cls, "closeImage", "(Landroid/graphics/Bitmap;)V");
206    g_env->CallVoidMethod(g_ctx, mid, data->bmp);
207    g_env->DeleteGlobalRef(data->bmp);
208#else
209    free(data->pixels);
210#endif
211    delete data;
212}
213
214} /* namespace lol */
215
Note: See TracBrowser for help on using the repository browser.