1 # This file is part of NIT (http://www.nitlanguage.org).
3 # Copyright 2012-2014 Alexis Laferrière <alexis.laf@xymus.net>
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
9 # http://www.apache.org/licenses/LICENSE-2.0
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
17 # Implements the `mnit::assets` services with a wraper around the filesystem
18 # API provided by the Android ndk.
20 # This module relies heavily on 3 C libraries:
22 # * zlib (which is included in the Android ndk)
23 # * libpng which must be provided by the Nit compilation framework
35 extern struct android_app *mnit_java_app;
37 void mnit_android_png_read_data(png_structp png_ptr,
38 png_bytep data, png_size_t length)
40 struct AAsset *recv = png_get_io_ptr(png_ptr);
41 int read = AAsset_read(recv, data, length);
43 void mnit_android_png_error_fn(png_structp png_ptr,
44 png_const_charp error_msg)
46 LOGW("libpng error: %s", error_msg);
48 void mnit_android_png_warning_fn(png_structp png_ptr,
49 png_const_charp warning_msg)
51 LOGW("libpng warning: %s", warning_msg);
55 extern class AndroidAsset in "C" `{struct AAsset*`}
57 fun read(count: Int): nullable String is extern import String.as nullable, NativeString.to_s `{
58 char
*buffer
= malloc
(sizeof
(char
) * (count
+1));
59 int read
= AAsset_read(recv
, buffer
, count
);
65 return String_as_nullable(NativeString_to_s(buffer
));
69 fun length: Int is extern `{
70 return AAsset_getLength(recv
);
73 fun to_fd: Int is extern `{
76 int fd
= AAsset_openFileDescriptor(recv
, &start
, &length
);
80 fun close is extern `{
86 redef fun try_loading_asset(path)
88 var a = load_asset_from_apk(path)
90 if path.file_extension == "png" then
91 var png = new Opengles1Image.from_android_asset(a)
94 else if path.file_extension == "txt" then
100 print "didn't get asset {path}"
106 protected fun load_asset_from_apk(path: String): nullable AndroidAsset is extern import String.to_cstring, AndroidAsset.as nullable `{
107 struct
AAsset* a
= AAssetManager_open(mnit_java_app-
>activity-
>assetManager
, String_to_cstring(path
), AASSET_MODE_BUFFER);
111 return null_AndroidAsset
();
115 return AndroidAsset_as_nullable(a
);
120 redef class Opengles1Image
121 # Read a png from a zipped stream
122 new from_android_asset(asset: AndroidAsset) is extern `{
123 struct mnit_opengles_Texture
*recv
= NULL;
125 png_structp png_ptr
= NULL;
126 png_infop info_ptr
= NULL;
128 png_uint_32 width
, height
;
129 int depth
, color_type
;
132 unsigned int row_bytes
;
133 png_bytepp row_pointers
;
134 unsigned char
*pixels
;
137 unsigned char sig
[8];
138 int sig_read
= AAsset_read(asset
, sig
, 8);
139 if (png_sig_cmp
(sig
, 0, sig_read
)) {
140 LOGW("invalide png signature");
144 png_ptr
= png_create_read_struct
(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
145 if (png_ptr
== NULL) {
146 LOGW("png_create_read_struct failed");
149 png_set_error_fn
(png_ptr
, NULL, mnit_android_png_error_fn
, mnit_android_png_warning_fn
);
151 info_ptr
= png_create_info_struct
(png_ptr
);
152 if (info_ptr
== NULL) {
153 LOGW("png_create_info_struct failed");
157 if (setjmp
(png_jmpbuf
(png_ptr
))) {
158 LOGW("reading png file failed");
162 png_set_read_fn
(png_ptr
, (void
*)asset
, mnit_android_png_read_data
);
164 png_set_sig_bytes
(png_ptr
, sig_read
);
166 png_read_info
(png_ptr
, info_ptr
);
168 png_get_IHDR
( png_ptr
, info_ptr
, &width
, &height
,
169 &depth
, &color_type
, NULL, NULL, NULL);
170 if (color_type
== PNG_COLOR_TYPE_RGBA)
172 else if (color_type
== PNG_COLOR_TYPE_RGB)
175 LOGW("unknown color_type");
179 LOGW("w: %i, h: %i", width
, height
);
181 row_bytes
= png_get_rowbytes
(png_ptr
, info_ptr
);
182 pixels
= malloc
(row_bytes
* height
);
183 row_pointers
= (png_bytep
*) malloc
(sizeof
(png_bytep
) * height
);
185 for (i
=0; i
<height
; i
++)
186 row_pointers
[i
] = (png_byte
*) malloc
(row_bytes
);
188 png_read_image
(png_ptr
, row_pointers
);
190 for (i
= 0; i
< height
; i
++)
191 memcpy
(pixels
+ (row_bytes
*i
),
192 row_pointers
[i
], row_bytes
);
194 recv
= mnit_opengles_load_image
((const uint_least32_t
*)pixels
, width
, height
, has_alpha
);
198 if (info_ptr
!= NULL)
199 png_destroy_read_struct
(&png_ptr
, &info_ptr
, NULL);
201 png_destroy_read_struct
(&png_ptr
, NULL, NULL);