aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGerd Hoffmann <kraxel@redhat.com>2017-04-13 00:56:27 +0200
committerGerd Hoffmann <kraxel@redhat.com>2017-04-13 00:56:27 +0200
commitec2fd3af076bacdfa90185b3e3bc26dd76f964c7 (patch)
tree78dfa2f63c3379b5360f8ab7a9521f8ebbf7503f
parentc9b7dad013c6679fc9b78acef049e96258e2b786 (diff)
downloaddrminfo-ec2fd3af076bacdfa90185b3e3bc26dd76f964c7.tar.gz
image laoder
-rw-r--r--Makefile14
-rw-r--r--gtktest.c20
-rw-r--r--image.c58
-rw-r--r--image.h1
-rw-r--r--render.c54
-rw-r--r--render.h2
6 files changed, 129 insertions, 20 deletions
diff --git a/Makefile b/Makefile
index 7ac827d..dc89829 100644
--- a/Makefile
+++ b/Makefile
@@ -7,11 +7,13 @@ TARGETS := drminfo drmtest gtktest
drminfo : CFLAGS += $(shell pkg-config --cflags libdrm)
drminfo : LDLIBS += $(shell pkg-config --libs libdrm)
-drmtest : CFLAGS += $(shell pkg-config --cflags libdrm gbm epoxy cairo cairo-gl)
-drmtest : LDLIBS += $(shell pkg-config --libs libdrm gbm epoxy cairo cairo-gl)
+drmtest : CFLAGS += $(shell pkg-config --cflags libdrm gbm epoxy cairo cairo-gl pixman-1)
+drmtest : LDLIBS += $(shell pkg-config --libs libdrm gbm epoxy cairo cairo-gl pixman-1)
+drmtest : LDLIBS += -ljpeg
-gtktest : CFLAGS += $(shell pkg-config --cflags gtk+-3.0 cairo)
-gtktest : LDLIBS += $(shell pkg-config --libs gtk+-3.0 cairo)
+gtktest : CFLAGS += $(shell pkg-config --cflags gtk+-3.0 cairo pixman-1)
+gtktest : LDLIBS += $(shell pkg-config --libs gtk+-3.0 cairo pixman-1)
+gtktest : LDLIBS += -ljpeg
all: $(TARGETS)
@@ -20,5 +22,5 @@ clean:
rm -f *~ *.o
drminfo: drminfo.o drmtools.o
-drmtest: drmtest.o drmtools.o render.o
-gtktest: gtktest.o render.o
+drmtest: drmtest.o drmtools.o render.o image.o
+gtktest: gtktest.o render.o image.o
diff --git a/gtktest.c b/gtktest.c
index 43cb2dc..4174029 100644
--- a/gtktest.c
+++ b/gtktest.c
@@ -1,7 +1,11 @@
+#include <stdio.h>
#include <cairo.h>
#include <gtk/gtk.h>
#include "render.h"
+#include "image.h"
+
+cairo_surface_t *image;
static gboolean on_draw_event(GtkWidget *widget, cairo_t *cr,
gpointer user_data)
@@ -11,9 +15,14 @@ static gboolean on_draw_event(GtkWidget *widget, cairo_t *cr,
width = gtk_widget_get_allocated_width(widget);
height = gtk_widget_get_allocated_height(widget);
- snprintf(info, sizeof(info), "gtktest: %dx%d",
- width, height);
- render_test(cr, width, height, info, NULL);
+
+ if (image) {
+ render_image(cr, width, height, image);
+ } else {
+ snprintf(info, sizeof(info), "gtktest: %dx%d",
+ width, height);
+ render_test(cr, width, height, info, NULL);
+ }
return FALSE;
}
@@ -38,6 +47,11 @@ int main(int argc, char *argv[])
gtk_window_set_default_size(GTK_WINDOW(window), 640, 480);
gtk_window_set_title(GTK_WINDOW(window), "gtktest");
+ if (argv[1]) {
+ fprintf(stderr, "loading %s ...\n", argv[1]);
+ image = load_jpeg(argv[1]);
+ }
+
gtk_widget_show_all(window);
gtk_main();
diff --git a/image.c b/image.c
new file mode 100644
index 0000000..62e3da1
--- /dev/null
+++ b/image.c
@@ -0,0 +1,58 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <endian.h>
+
+#include <jpeglib.h>
+#include <jerror.h>
+#include <cairo.h>
+
+#include "image.h"
+
+cairo_surface_t *load_jpeg(const char* filename)
+{
+ struct jpeg_decompress_struct info;
+ struct jpeg_error_mgr err;
+ cairo_surface_t *surface;
+ uint8_t *rowptr[1];
+ FILE* file;
+
+ file = fopen(filename, "rb");
+ if (!file) {
+ fprintf(stderr, "open %s: %s\n", filename, strerror(errno));
+ exit(1);
+ }
+
+ info.err = jpeg_std_error(&err);
+ jpeg_create_decompress(&info);
+
+ jpeg_stdio_src(&info, file);
+ jpeg_read_header(&info, TRUE);
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ info.out_color_space = JCS_EXT_BGRX;
+#else
+ info.out_color_space = JCS_EXT_XRGB;
+#endif
+ jpeg_start_decompress(&info);
+
+ surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, /* 32bpp, native endian */
+ info.output_width,
+ info.output_height);
+ if (cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS) {
+ fprintf(stderr, "cairo_image_surface_create failed\n");
+ exit(1);
+ }
+
+ while (info.output_scanline < info.output_height) {
+ rowptr[0] = (uint8_t *)cairo_image_surface_get_data(surface) +
+ cairo_image_surface_get_stride(surface) * info.output_scanline;
+ jpeg_read_scanlines(&info, rowptr, 1);
+ }
+ jpeg_finish_decompress(&info);
+
+ fclose(file);
+ return surface;
+}
diff --git a/image.h b/image.h
new file mode 100644
index 0000000..887ce3e
--- /dev/null
+++ b/image.h
@@ -0,0 +1 @@
+cairo_surface_t *load_jpeg(const char* filename);
diff --git a/render.c b/render.c
index 70f02af..9aac29c 100644
--- a/render.c
+++ b/render.c
@@ -1,3 +1,4 @@
+#include <stdio.h>
#include <stddef.h>
#include <cairo.h>
@@ -15,9 +16,9 @@ static void render_color_bar(cairo_t *cr, int x, int y, int w, int h,
gr = cairo_pattern_create_linear(x, y+h/2, w, y+h/2);
cairo_pattern_add_color_stop_rgb(gr, 0, 0, 0, 0);
cairo_pattern_add_color_stop_rgb(gr, 1, r, g, b);
- cairo_rectangle (cr, x, y, w, h);
- cairo_set_source (cr, gr);
- cairo_fill (cr);
+ cairo_rectangle(cr, x, y, w, h);
+ cairo_set_source(cr, gr);
+ cairo_fill(cr);
cairo_pattern_destroy(gr);
cairo_select_font_face(cr, "mono",
@@ -26,7 +27,7 @@ static void render_color_bar(cairo_t *cr, int x, int y, int w, int h,
if (l2) {
cairo_set_source_rgb(cr, 1, 1, 1);
cairo_set_font_size(cr, h/2 - pad);
- cairo_font_extents (cr, &ext);
+ cairo_font_extents(cr, &ext);
cairo_move_to(cr, x + pad, y + pad + ext.ascent);
cairo_show_text(cr, l1);
cairo_move_to(cr, x + pad, y + pad + ext.ascent + ext.height);
@@ -34,7 +35,7 @@ static void render_color_bar(cairo_t *cr, int x, int y, int w, int h,
} else {
cairo_set_source_rgb(cr, r, g, b);
cairo_set_font_size(cr, h - 2*pad);
- cairo_font_extents (cr, &ext);
+ cairo_font_extents(cr, &ext);
cairo_move_to(cr, x + pad, y + pad + ext.ascent);
cairo_show_text(cr, l1);
}
@@ -49,13 +50,13 @@ void render_test(cairo_t *cr, int width, int height, const char *l1, const char
bar -= 10;
cairo_set_source_rgb(cr, 0, 0, 0);
- cairo_rectangle (cr, 0, 0, width, height);
- cairo_fill (cr);
+ cairo_rectangle(cr, 0, 0, width, height);
+ cairo_fill(cr);
- cairo_set_line_width (cr, 1);
- cairo_set_source_rgb (cr, 1, 1, 1);
- cairo_rectangle (cr, pad - 0.5, pad - 0.5, width - 2*pad + 1, 7*bar + 1);
- cairo_stroke (cr);
+ cairo_set_line_width(cr, 2);
+ cairo_set_source_rgb(cr, 1, 1, 1);
+ cairo_rectangle(cr, pad - 1, pad - 1, width - 2*pad + 2, 7*bar + 2);
+ cairo_stroke(cr);
render_color_bar(cr, pad, bar * 0 + pad, width - 2*pad, bar,
0.6, 0.6, 0.6, l1, l2);
@@ -69,4 +70,35 @@ void render_test(cairo_t *cr, int width, int height, const char *l1, const char
cairo_show_page(cr);
}
+void render_image(cairo_t *cr, int width, int height, cairo_surface_t *image)
+{
+ double xs, ys, dx, dy;
+ int iw, ih;
+
+ cairo_set_source_rgb(cr, 0, 0, 0);
+ cairo_rectangle(cr, 0, 0, width, height);
+ cairo_fill(cr);
+
+ iw = cairo_image_surface_get_width(image);
+ ih = cairo_image_surface_get_height(image);
+ xs = (double)width / iw;
+ ys = (double)height / ih;
+
+ if (xs > ys) {
+ xs = ys;
+ dx = (width - xs * iw) / 2;
+ dy = 0;
+ } else {
+ ys = xs;
+ dx = 0;
+ dy = (height - ys * ih) / 2;
+ }
+
+ cairo_translate(cr, dx, dy);
+ cairo_scale(cr, xs, ys);
+ cairo_set_source_surface(cr, image, 0, 0);
+ cairo_rectangle(cr, 0, 0, iw, ih);
+ cairo_fill(cr);
+ cairo_show_page(cr);
+}
diff --git a/render.h b/render.h
index 2a15568..07e7654 100644
--- a/render.h
+++ b/render.h
@@ -1,2 +1,4 @@
void render_test(cairo_t *cr, int width, int height,
const char *l1, const char *l2);
+void render_image(cairo_t *cr, int width, int height,
+ cairo_surface_t *image);