static bool rpng_image_load_argb_shift(const char *path, struct texture_image *out_img, unsigned a_shift, unsigned r_shift, unsigned g_shift, unsigned b_shift) { if (strstr(path, ".tga")) return rpng_image_load_tga_shift(path, out_img, a_shift, r_shift, g_shift, b_shift); #ifdef HAVE_ZLIB else if (strstr(path, ".png")) { bool ret = rpng_load_image_argb(path, &out_img->pixels, &out_img->width, &out_img->height); RARCH_LOG("[RPNG]: Using RPNG loader.\n"); if (!ret) return false; // This is quite uncommon ... if (a_shift != 24 || r_shift != 16 || g_shift != 8 || b_shift != 0) { uint32_t i, num_pixels, *pixels; num_pixels = out_img->width * out_img->height; pixels = (uint32_t*)out_img->pixels; for (i = 0; i < num_pixels; i++) { uint32_t col = pixels[i]; uint8_t a = (uint8_t)(col >> 24); uint8_t r = (uint8_t)(col >> 16); uint8_t g = (uint8_t)(col >> 8); uint8_t b = (uint8_t)(col >> 0); pixels[i] = (a << a_shift) | (r << r_shift) | (g << g_shift) | (b << b_shift); } }
int img_newImageData(lua_State *L) { int n = lua_gettop(L); if (n != 1) return luaL_error(L, "lutro.image.newImageData requires 1 argument, %d given.", n); const char* path = luaL_checkstring(L, 1); char fullpath[PATH_MAX_LENGTH]; strlcpy(fullpath, settings.gamedir, sizeof(fullpath)); strlcat(fullpath, path, sizeof(fullpath)); bitmap_t* self = (bitmap_t*)lua_newuserdata(L, sizeof(bitmap_t)); rpng_load_image_argb(fullpath, &self->data, &self->width, &self->height); num_imgdatas++; imgdatas = (bitmap_t**)realloc(imgdatas, num_imgdatas * sizeof(bitmap_t)); imgdatas[num_imgdatas-1] = self; if (luaL_newmetatable(L, "ImageData") != 0) { static luaL_Reg imgdata_funcs[] = { { "getWidth", imgdata_getWidth }, { "getHeight", imgdata_getWidth }, { "type", imgdata_type }, { "__gc", imgdata_gc }, {NULL, NULL} }; lua_pushvalue(L, -1); lua_setfield(L, -2, "__index"); lua_pushcfunction(L, imgdata_gc); lua_setfield( L, -2, "__gc" ); luaL_setfuncs(L, imgdata_funcs, 0); } lua_setmetatable(L, -2); return 1; }
static int test_blocking_rpng(const char *in_path) { #ifdef HAVE_IMLIB2 Imlib_Image img; const uint32_t *imlib_data = NULL; #endif const uint32_t test_data[] = { 0xff000000 | 0x50, 0xff000000 | 0x80, 0xff000000 | 0x40, 0xff000000 | 0x88, 0xff000000 | 0x50, 0xff000000 | 0x80, 0xff000000 | 0x40, 0xff000000 | 0x88, 0xff000000 | 0xc3, 0xff000000 | 0xd3, 0xff000000 | 0xc3, 0xff000000 | 0xd3, 0xff000000 | 0xc3, 0xff000000 | 0xd3, 0xff000000 | 0xc3, 0xff000000 | 0xd3, }; uint32_t *data = NULL; unsigned width = 0; unsigned height = 0; if (!rpng_save_image_argb("/tmp/test.png", test_data, 4, 4, 16)) return 1; if (!rpng_load_image_argb(in_path, &data, &width, &height)) return 2; fprintf(stderr, "Path: %s.\n", in_path); fprintf(stderr, "Got image: %u x %u.\n", width, height); #if 0 fprintf(stderr, "\nRPNG:\n"); for (unsigned h = 0; h < height; h++) { unsigned w; for (w = 0; w < width; w++) fprintf(stderr, "[%08x] ", data[h * width + w]); fprintf(stderr, "\n"); } #endif #ifdef HAVE_IMLIB2 /* Validate with imlib2 as well. */ img = imlib_load_image(in_path); if (!img) return 4; imlib_context_set_image(img); width = imlib_image_get_width(); height = imlib_image_get_width(); imlib_data = imlib_image_get_data_for_reading_only(); #if 0 fprintf(stderr, "\nImlib:\n"); for (unsigned h = 0; h < height; h++) { for (unsigned w = 0; w < width; w++) fprintf(stderr, "[%08x] ", imlib_data[h * width + w]); fprintf(stderr, "\n"); } #endif if (memcmp(imlib_data, data, width * height * sizeof(uint32_t)) != 0) { fprintf(stderr, "Imlib and RPNG differs!\n"); return 5; } else fprintf(stderr, "Imlib and RPNG are equivalent!\n"); imlib_free_image(); #endif free(data); return 0; }
int main(int argc, char *argv[]) { if (argc > 2) { fprintf(stderr, "Usage: %s <png file>\n", argv[0]); return 1; } const char *in_path = argc == 2 ? argv[1] : "/tmp/test.png"; const uint32_t test_data[] = { 0xff000000 | 0x50, 0xff000000 | 0x80, 0xff000000 | 0x40, 0xff000000 | 0x88, 0xff000000 | 0x50, 0xff000000 | 0x80, 0xff000000 | 0x40, 0xff000000 | 0x88, 0xff000000 | 0xc3, 0xff000000 | 0xd3, 0xff000000 | 0xc3, 0xff000000 | 0xd3, 0xff000000 | 0xc3, 0xff000000 | 0xd3, 0xff000000 | 0xc3, 0xff000000 | 0xd3, }; if (!rpng_save_image_argb("/tmp/test.png", test_data, 4, 4, 16)) return 1; uint32_t *data = NULL; unsigned width = 0; unsigned height = 0; if (!rpng_load_image_argb(in_path, &data, &width, &height)) return 2; fprintf(stderr, "Got image: %u x %u.\n", width, height); fprintf(stderr, "\nRPNG:\n"); for (unsigned h = 0; h < height; h++) { for (unsigned w = 0; w < width; w++) fprintf(stderr, "[%08x] ", data[h * width + w]); fprintf(stderr, "\n"); } if (width != 4 || height != 4) return 3; // Validate with imlib2 as well. Imlib_Image img = imlib_load_image(in_path); if (!img) return 4; imlib_context_set_image(img); width = imlib_image_get_width(); height = imlib_image_get_width(); const uint32_t *imlib_data = imlib_image_get_data_for_reading_only(); fprintf(stderr, "\nImlib:\n"); for (unsigned h = 0; h < height; h++) { for (unsigned w = 0; w < width; w++) fprintf(stderr, "[%08x] ", imlib_data[h * width + w]); fprintf(stderr, "\n"); } imlib_free_image(); if (memcmp(test_data, data, sizeof(test_data)) != 0) return 5; free(data); }