source: trunk/src/image.cpp @ 735

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

core: get rid of now useless <cstdio> includes.

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