aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSylvain Munaut <tnt@246tNt.com>2015-03-11 13:23:12 +0100
committerSylvain Munaut <tnt@246tNt.com>2015-10-25 21:41:22 +0100
commitf33ebdd28b0ae8283020556cbc373d3bf14428b2 (patch)
tree733e63613435784668a05247b7ce68d5bbc6bd1b
parent1780d4b43b7e6bb9452d710d66a541098bcb9ccc (diff)
fosphor/gl_cmap_gen: Add new function to generate GL colormap from a PNG
Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
-rw-r--r--lib/fosphor/Makefile4
-rw-r--r--lib/fosphor/gl_cmap_gen.c92
-rw-r--r--lib/fosphor/gl_cmap_gen.h1
3 files changed, 95 insertions, 2 deletions
diff --git a/lib/fosphor/Makefile b/lib/fosphor/Makefile
index a8fb3bb..051afd4 100644
--- a/lib/fosphor/Makefile
+++ b/lib/fosphor/Makefile
@@ -1,7 +1,7 @@
UNAME=$(shell uname)
CC=gcc
-CFLAGS=-Wall -Werror -O2 `pkg-config freetype2 glfw3 --cflags` -g
-LDLIBS=`pkg-config freetype2 glfw3 --libs` -lm
+CFLAGS=-Wall -Werror -O2 `pkg-config freetype2 glfw3 libpng --cflags` -g
+LDLIBS=`pkg-config freetype2 glfw3 libpng --libs` -lm
ifneq ($(AMDAPPSDKROOT), )
CFLAGS+=-I$(AMDAPPSDKROOT)/include
endif
diff --git a/lib/fosphor/gl_cmap_gen.c b/lib/fosphor/gl_cmap_gen.c
index 2d0c35c..4bc21f8 100644
--- a/lib/fosphor/gl_cmap_gen.c
+++ b/lib/fosphor/gl_cmap_gen.c
@@ -27,10 +27,16 @@
* \brief OpenGL color map generators
*/
+#include <errno.h>
#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
#include <math.h>
+#include <png.h>
+
#include "gl_cmap_gen.h"
+#include "resource.h"
static void
@@ -128,6 +134,33 @@ _set_rgba_from_hsv(uint32_t *rgba, float h, float s, float v)
}
+static inline uint32_t
+_rgba_interpolate(uint32_t *rgba, int sz, int p, int N)
+{
+ int pos_i = (p * (sz-1)) / (N-1);
+ int pos_f = (p * (sz-1)) - (pos_i * (N-1));
+ uint32_t vl, vh, vf = 0;
+ int i;
+
+ if (pos_f == 0)
+ return rgba[pos_i];
+
+ vl = rgba[pos_i];
+ vh = rgba[pos_i+1];
+
+ for (i=0; i<4; i++)
+ {
+ uint32_t nv =
+ ((vl >> (8 * i)) & 0xff) * ((N-1) - pos_f) +
+ ((vh >> (8 * i)) & 0xff) * pos_f;
+
+ vf |= ((nv / (N-1)) & 0xff) << (8 * i);
+ }
+
+ return vf;
+}
+
+
int
fosphor_gl_cmap_histogram(uint32_t *rgba, int N, void *arg)
{
@@ -179,4 +212,63 @@ fosphor_gl_cmap_waterfall(uint32_t *rgba, int N, void *arg)
return 0;
}
+int
+fosphor_gl_cmap_png(uint32_t *rgba, int N, void *arg)
+{
+ const char *rsrc_name = arg;
+ png_image img;
+ const void *png_data = NULL;
+ void *png_rgba = NULL;
+ int png_len, i, rv;
+
+ /* Grab the file */
+ png_data = resource_get(rsrc_name, &png_len);
+ if (!png_data)
+ return -ENOENT;
+
+ /* Read PNG */
+ memset(&img, 0x00, sizeof(img));
+ img.version = PNG_IMAGE_VERSION;
+
+ rv = png_image_begin_read_from_memory(&img, png_data, png_len);
+ if (!rv) {
+ rv = -EINVAL;
+ goto error;
+ }
+
+ img.format = PNG_FORMAT_RGBA;
+
+ png_rgba = malloc(sizeof(uint32_t) * img.width * img.height);
+ if (!png_rgba) {
+ rv = -ENOMEM;
+ goto error;
+ }
+
+ rv = png_image_finish_read(&img,
+ NULL, /* background */
+ png_rgba, /* buffer */
+ sizeof(uint32_t) * img.width, /* row_stride */
+ NULL /* colormap */
+ );
+ if (!rv) {
+ rv = -EINVAL;
+ goto error;
+ }
+
+ /* Interpolate the PNG to the requested linear scale */
+ for (i=0; i<N; i++)
+ rgba[i] = _rgba_interpolate(png_rgba, img.width, i, N);
+
+ /* Done */
+ rv = 0;
+
+error:
+ free(png_rgba);
+
+ if (png_data)
+ resource_put(png_data);
+
+ return rv;
+}
+
/*! @} */
diff --git a/lib/fosphor/gl_cmap_gen.h b/lib/fosphor/gl_cmap_gen.h
index df98878..369ffd0 100644
--- a/lib/fosphor/gl_cmap_gen.h
+++ b/lib/fosphor/gl_cmap_gen.h
@@ -34,6 +34,7 @@
int fosphor_gl_cmap_histogram(uint32_t *rgba, int N, void *arg);
int fosphor_gl_cmap_waterfall(uint32_t *rgba, int N, void *arg);
+int fosphor_gl_cmap_png(uint32_t *rgba, int N, void *rsrc_name);
/*! @} */