diff options
author | Gerd Hoffmann <kraxel@redhat.com> | 2017-04-13 00:56:27 +0200 |
---|---|---|
committer | Gerd Hoffmann <kraxel@redhat.com> | 2017-04-13 00:56:27 +0200 |
commit | ec2fd3af076bacdfa90185b3e3bc26dd76f964c7 (patch) | |
tree | 78dfa2f63c3379b5360f8ab7a9521f8ebbf7503f | |
parent | c9b7dad013c6679fc9b78acef049e96258e2b786 (diff) | |
download | drminfo-ec2fd3af076bacdfa90185b3e3bc26dd76f964c7.tar.gz |
image laoder
-rw-r--r-- | Makefile | 14 | ||||
-rw-r--r-- | gtktest.c | 20 | ||||
-rw-r--r-- | image.c | 58 | ||||
-rw-r--r-- | image.h | 1 | ||||
-rw-r--r-- | render.c | 54 | ||||
-rw-r--r-- | render.h | 2 |
6 files changed, 129 insertions, 20 deletions
@@ -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 @@ -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(); @@ -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; +} @@ -0,0 +1 @@ +cairo_surface_t *load_jpeg(const char* filename); @@ -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); +} @@ -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); |