source: trunk/src/image.cpp @ 734

Last change on this file since 734 was 734, checked in by sam, 11 years ago

core: create a logger class to reduce printf usage.

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