aboutsummaryrefslogtreecommitdiffstats
path: root/minui/resources.c
diff options
context:
space:
mode:
Diffstat (limited to 'minui/resources.c')
-rw-r--r--minui/resources.c103
1 files changed, 32 insertions, 71 deletions
diff --git a/minui/resources.c b/minui/resources.c
index 91b01eb..df813cb 100644
--- a/minui/resources.c
+++ b/minui/resources.c
@@ -27,25 +27,26 @@
#include <linux/fb.h>
#include <linux/kd.h>
-#include <pixelflinger/pixelflinger.h>
-
#include <png.h>
#include "minui.h"
extern char* locale;
-// libpng gives "undefined reference to 'pow'" errors, and I have no
-// idea how to convince the build system to link with -lm. We don't
-// need this functionality (it's used for gamma adjustment) so provide
-// a dummy implementation to satisfy the linker.
-double pow(double x, double y) {
- return x * y;
+#define SURFACE_DATA_ALIGNMENT 8
+
+static gr_surface malloc_surface(size_t data_size) {
+ unsigned char* temp = malloc(sizeof(GRSurface) + data_size + SURFACE_DATA_ALIGNMENT);
+ if (temp == NULL) return NULL;
+ gr_surface surface = (gr_surface) temp;
+ surface->data = temp + sizeof(GRSurface) +
+ (SURFACE_DATA_ALIGNMENT - (sizeof(GRSurface) % SURFACE_DATA_ALIGNMENT));
+ return surface;
}
int res_create_surface(const char* name, gr_surface* pSurface) {
char resPath[256];
- GGLSurface* surface = NULL;
+ gr_surface surface = NULL;
int result = 0;
unsigned char header[8];
png_structp png_ptr = NULL;
@@ -100,9 +101,8 @@ int res_create_surface(const char* name, gr_surface* pSurface) {
int channels = png_get_channels(png_ptr, info_ptr);
- if (!(bit_depth == 8 &&
+ if (!(bit_depth <= 8 &&
((channels == 3 && color_type == PNG_COLOR_TYPE_RGB) ||
- (channels == 4 && color_type == PNG_COLOR_TYPE_RGBA) ||
(channels == 1 && (color_type == PNG_COLOR_TYPE_PALETTE ||
color_type == PNG_COLOR_TYPE_GRAY))))) {
return -7;
@@ -110,38 +110,20 @@ int res_create_surface(const char* name, gr_surface* pSurface) {
}
size_t stride = (color_type == PNG_COLOR_TYPE_GRAY ? 1 : 4) * width;
- size_t pixelSize = stride * height;
- surface = malloc(sizeof(GGLSurface) + pixelSize);
+ surface = malloc_surface(stride * height);
if (surface == NULL) {
result = -8;
goto exit;
}
- unsigned char* pData = (unsigned char*) (surface + 1);
- surface->version = sizeof(GGLSurface);
+ unsigned char* pData = surface->data;
surface->width = width;
surface->height = height;
- surface->stride = width; /* Yes, pixels, not bytes */
- surface->data = pData;
-
- if (channels == 3) {
- surface->format = GGL_PIXEL_FORMAT_RGBX_8888;
- } else if (color_type == PNG_COLOR_TYPE_PALETTE) {
- surface->format = GGL_PIXEL_FORMAT_RGBA_8888;
- } else if (channels == 1) {
- surface->format = GGL_PIXEL_FORMAT_L_8;
- } else {
- surface->format = GGL_PIXEL_FORMAT_RGBA_8888;
- }
+ surface->row_bytes = stride;
+ surface->pixel_bytes = (color_type == PNG_COLOR_TYPE_GRAY ? 1 : 4);
int alpha = (channels == 4);
- if (color_type == PNG_COLOR_TYPE_PALETTE) {
- png_set_palette_to_rgb(png_ptr);
- }
- if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
- png_set_tRNS_to_alpha(png_ptr);
- alpha = 1;
- }
+ png_set_expand(png_ptr);
if (color_type == PNG_COLOR_TYPE_GRAY) {
alpha = 1;
}
@@ -196,7 +178,7 @@ int res_create_multi_surface(const char* name, int* frames, gr_surface** pSurfac
png_structp png_ptr = NULL;
png_infop info_ptr = NULL;
int i;
- GGLSurface** surface = NULL;
+ gr_surface* surface = NULL;
*pSurface = NULL;
*frames = -1;
@@ -248,9 +230,8 @@ int res_create_multi_surface(const char* name, int* frames, gr_surface** pSurfac
int channels = png_get_channels(png_ptr, info_ptr);
- if (!(bit_depth == 8 &&
+ if (!(bit_depth <= 8 &&
((channels == 3 && color_type == PNG_COLOR_TYPE_RGB) ||
- (channels == 4 && color_type == PNG_COLOR_TYPE_RGBA) ||
(channels == 1 && (color_type == PNG_COLOR_TYPE_PALETTE ||
color_type == PNG_COLOR_TYPE_GRAY))))) {
return -7;
@@ -279,38 +260,21 @@ int res_create_multi_surface(const char* name, int* frames, gr_surface** pSurfac
size_t stride = (color_type == PNG_COLOR_TYPE_GRAY ? 1 : 4) * width;
size_t pixelSize = stride * height / *frames;
- surface = malloc(*frames * sizeof(GGLSurface*));
+ surface = malloc(*frames * sizeof(gr_surface));
if (surface == NULL) {
result = -8;
goto exit;
}
for (i = 0; i < *frames; ++i) {
- surface[i] = malloc(sizeof(GGLSurface) + pixelSize);
- surface[i]->version = sizeof(GGLSurface);
+ surface[i] = malloc_surface(pixelSize);
surface[i]->width = width;
surface[i]->height = height / *frames;
- surface[i]->stride = width; /* Yes, pixels, not bytes */
- surface[i]->data = (unsigned char*) (surface[i] + 1);
-
- if (channels == 3) {
- surface[i]->format = GGL_PIXEL_FORMAT_RGBX_8888;
- } else if (color_type == PNG_COLOR_TYPE_PALETTE) {
- surface[i]->format = GGL_PIXEL_FORMAT_RGBA_8888;
- } else if (channels == 1) {
- surface[i]->format = GGL_PIXEL_FORMAT_L_8;
- } else {
- surface[i]->format = GGL_PIXEL_FORMAT_RGBA_8888;
- }
+ surface[i]->row_bytes = stride;
+ surface[i]->pixel_bytes = (color_type == PNG_COLOR_TYPE_GRAY ? 1 : 4);
}
int alpha = (channels == 4);
- if (color_type == PNG_COLOR_TYPE_PALETTE) {
- png_set_palette_to_rgb(png_ptr);
- }
- if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
- png_set_tRNS_to_alpha(png_ptr);
- alpha = 1;
- }
+ png_set_expand(png_ptr);
if (color_type == PNG_COLOR_TYPE_GRAY) {
alpha = 1;
}
@@ -384,7 +348,7 @@ static int matches_locale(const char* loc) {
int res_create_localized_surface(const char* name, gr_surface* pSurface) {
char resPath[256];
- GGLSurface* surface = NULL;
+ gr_surface surface = NULL;
int result = 0;
unsigned char header[8];
png_structp png_ptr = NULL;
@@ -438,12 +402,14 @@ int res_create_localized_surface(const char* name, gr_surface* pSurface) {
&color_type, NULL, NULL, NULL);
int channels = png_get_channels(png_ptr, info_ptr);
- if (!(bit_depth == 8 &&
+ if (!(bit_depth <= 8 &&
(channels == 1 && color_type == PNG_COLOR_TYPE_GRAY))) {
return -7;
goto exit;
}
+ png_set_expand(png_ptr);
+
unsigned char* row = malloc(width);
png_uint_32 y;
for (y = 0; y < height; ++y) {
@@ -456,19 +422,17 @@ int res_create_localized_surface(const char* name, gr_surface* pSurface) {
if (y+1+h >= height || matches_locale(loc)) {
printf(" %20s: %s (%d x %d @ %d)\n", name, loc, w, h, y);
- surface = malloc(sizeof(GGLSurface));
+ surface = malloc_surface(w*h);
if (surface == NULL) {
result = -8;
goto exit;
}
- unsigned char* pData = malloc(w*h);
+ unsigned char* pData = surface->data;
- surface->version = sizeof(GGLSurface);
surface->width = w;
surface->height = h;
- surface->stride = w; /* Yes, pixels, not bytes */
- surface->data = pData;
- surface->format = GGL_PIXEL_FORMAT_A_8;
+ surface->row_bytes = w;
+ surface->pixel_bytes = 1;
int i;
for (i = 0; i < h; ++i, ++y) {
@@ -501,8 +465,5 @@ exit:
}
void res_free_surface(gr_surface surface) {
- GGLSurface* pSurface = (GGLSurface*) surface;
- if (pSurface) {
- free(pSurface);
- }
+ free(surface);
}