void mnit_android_png_read_data(png_structp png_ptr,
png_bytep data, png_size_t length)
{
- struct AAsset *recv = png_get_io_ptr(png_ptr);
- int read = AAsset_read(recv, data, length);
+ struct AAsset *self = png_get_io_ptr(png_ptr);
+ int read = AAsset_read(self, data, length);
}
void mnit_android_png_error_fn(png_structp png_ptr,
png_const_charp error_msg)
fun read(count: Int): nullable String is extern import String.as nullable, NativeString.to_s `{
char *buffer = malloc(sizeof(char) * (count+1));
- int read = AAsset_read(recv, buffer, count);
+ int read = AAsset_read(self, buffer, count);
if (read != count)
return null_String();
else
`}
fun length: Int is extern `{
- return AAsset_getLength(recv);
+ return AAsset_getLength(self);
`}
fun to_fd: Int is extern `{
off_t start;
off_t length;
- int fd = AAsset_openFileDescriptor(recv, &start, &length);
+ int fd = AAsset_openFileDescriptor(self, &start, &length);
return fd;
`}
fun close is extern `{
- AAsset_close(recv);
+ AAsset_close(self);
`}
end
var a = load_asset_from_apk(path)
if a != null then
if path.file_extension == "png" then
- var png = new Opengles1Image.from_android_asset(a)
+ var png = new Opengles1Image.from_android_asset(a)
a.close
return png
else if path.file_extension == "txt" then
end
protected fun load_asset_from_apk(path: String): nullable AndroidAsset is extern import String.to_cstring, AndroidAsset.as nullable, native_app_glue `{
- struct android_app *native_app_glue = App_native_app_glue(recv);
+ struct android_app *native_app_glue = App_native_app_glue(self);
struct AAsset* a = AAssetManager_open(native_app_glue->activity->assetManager, String_to_cstring(path), AASSET_MODE_BUFFER);
if (a == NULL)
{
redef class Opengles1Image
# Read a png from a zipped stream
- new from_android_asset(asset: AndroidAsset) is extern `{
- struct mnit_opengles_Texture *recv = NULL;
+ new from_android_asset(asset: AndroidAsset) import Int.next_pow `{
+ struct mnit_opengles_Texture *self = NULL;
png_structp png_ptr = NULL;
png_infop info_ptr = NULL;
unsigned char *pixels = NULL;
unsigned int i;
+ png_uint_32 width_pow2, height_pow2;
+ unsigned int row_bytes_pow2;
+
unsigned char sig[8];
int sig_read = AAsset_read(asset, sig, 8);
if (png_sig_cmp(sig, 0, sig_read)) {
LOGW("invalide png signature");
return NULL;
}
-
+
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (png_ptr == NULL) {
LOGW("png_create_read_struct failed");
png_read_update_info(png_ptr, info_ptr);
}
- LOGW("w: %i, h: %i", width, height);
+ width_pow2 = Int_next_pow(width, 2);
+ height_pow2 = Int_next_pow(height, 2);
+
+ LOGW("Loading image of w: %i, h: %i, w2: %d, h2: %d",
+ width, height, width_pow2, height_pow2);
row_bytes = png_get_rowbytes(png_ptr, info_ptr);
- pixels = malloc(row_bytes * height);
- row_pointers = (png_bytep*) malloc(sizeof(png_bytep) * height);
+ row_bytes_pow2 = row_bytes * width_pow2 / width;
+ pixels = malloc(row_bytes_pow2 * height_pow2);
+ row_pointers = (png_bytep*)malloc(sizeof(png_bytep) * height_pow2);
for (i=0; i<height; i++)
row_pointers[i] = (png_byte*) malloc(row_bytes);
png_read_image(png_ptr, row_pointers);
for (i = 0; i < height; i++)
- memcpy(pixels + (row_bytes*i),
- row_pointers[i], row_bytes);
+ memcpy(pixels + (row_bytes_pow2*i), row_pointers[i], row_bytes);
+
+ self = mnit_opengles_load_image((const uint_least32_t *)pixels,
+ width, height, width_pow2, height_pow2, has_alpha);
- recv = mnit_opengles_load_image((const uint_least32_t *)pixels, width, height, has_alpha);
- LOGW("OK");
+ // Calculate the size of the client-side memory allocated and freed
+ float size = ((float)row_bytes_pow2) * height_pow2/1024.0/1024.0;
+ static float total_size = 0;
+ total_size += size;
+ LOGI("Loaded OK %fmb out of %fmb", size, total_size);
close_png_ptr:
if (info_ptr != NULL)
}
close_stream:
- return recv;
+ return self;
`}
end
+
+redef universal Int
+ # The first power of `exp` greater or equal to `self`
+ private fun next_pow(exp: Int): Int
+ do
+ var p = 1
+ while p < self do p = p*exp
+ return p
+ end
+end