cairo-util: Add helper to load jpeg files
authorKristian Høgsberg <krh@bitplanet.net>
Thu, 20 Oct 2011 17:11:12 +0000 (13:11 -0400)
committerKristian Høgsberg <krh@bitplanet.net>
Thu, 20 Oct 2011 17:11:12 +0000 (13:11 -0400)
clients/cairo-util.c
clients/cairo-util.h
clients/desktop-shell.c
configure.ac

index 184f58e..502f4b8 100644 (file)
@@ -28,6 +28,8 @@
 #include <cairo.h>
 #include "cairo-util.h"
 
+#include <jpeglib.h>
+
 #define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0])
 
 void
@@ -286,3 +288,55 @@ rounded_rect(cairo_t *cr, int x0, int y0, int x1, int y1, int radius)
        cairo_arc(cr, x0 + radius, y1 - radius, radius, M_PI / 2, M_PI);
        cairo_close_path(cr);
 }
+
+cairo_surface_t *
+load_jpeg(const char *filename)
+{
+       struct jpeg_decompress_struct cinfo;
+       struct jpeg_error_mgr jerr;
+       FILE *fp;
+       int stride, i;
+       JSAMPLE *data, *rows[4];
+
+       cinfo.err = jpeg_std_error(&jerr);
+       jpeg_create_decompress(&cinfo);
+
+       fp = fopen(filename, "rb");
+       if (fp == NULL) {
+               fprintf(stderr, "can't open %s\n", filename);
+               return NULL;
+       }
+       jpeg_stdio_src(&cinfo, fp);
+
+       jpeg_read_header(&cinfo, TRUE);
+
+       cinfo.out_color_space = JCS_EXT_BGRX;
+       jpeg_start_decompress(&cinfo);
+
+       stride = cairo_format_stride_for_width(CAIRO_FORMAT_RGB24,
+                                              cinfo.output_width);
+       data = malloc(stride * cinfo.output_height);
+       if (data == NULL) {
+               fprintf(stderr, "couldn't allocate image data\n");
+               return NULL;
+       }
+
+       while (cinfo.output_scanline < cinfo.output_height) {
+               for (i = 0; i < ARRAY_LENGTH(rows); i++, p += stride)
+                       rows[i] = data + (cinfo.output_scanline + i) * stride;
+
+               jpeg_read_scanlines(&cinfo, rows, ARRAY_LENGTH(rows));
+       }
+
+       jpeg_finish_decompress(&cinfo);
+
+       fclose(fp);
+
+       jpeg_destroy_decompress(&cinfo);
+
+       return cairo_image_surface_create_for_data (data,
+                                                   CAIRO_FORMAT_RGB24,
+                                                   cinfo.output_width,
+                                                   cinfo.output_height,
+                                                   stride);
+}
index e490b9f..07613ac 100644 (file)
@@ -40,4 +40,7 @@ tile_source(cairo_t *cr, cairo_surface_t *surface,
 void
 rounded_rect(cairo_t *cr, int x0, int y0, int x1, int y1, int radius);
 
+cairo_surface_t *
+load_jpeg(const char *filename);
+
 #endif
index 7ad6f02..016d720 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/input.h>
 
 #include "wayland-client.h"
+#include "cairo-util.h"
 #include "window.h"
 
 #include <desktop-shell-client-protocol.h>
@@ -241,7 +242,7 @@ background_draw(struct window *window, int width, int height, const char *path)
        cairo_paint(cr);
 
        if (path) {
-               image = cairo_image_surface_create_from_png(path);
+               image = load_jpeg(path);
                pattern = cairo_pattern_create_for_surface(image);
                sx = (double) cairo_image_surface_get_width(image) / width;
                sy = (double) cairo_image_surface_get_height(image) / height;
@@ -250,6 +251,7 @@ background_draw(struct window *window, int width, int height, const char *path)
                cairo_set_source(cr, pattern);
                cairo_pattern_destroy (pattern);
                cairo_paint(cr);
+               cairo_surface_destroy(image);
        }
 
        cairo_destroy(cr);
index f19c4e7..e278a1c 100644 (file)
@@ -113,6 +113,14 @@ if test x$enable_clients == xyes; then
   AS_IF([test "x$have_cairo_egl" = "xyes"],
         [AC_DEFINE([HAVE_CAIRO_EGL], [1], [Have cairo-egl])],
         [AC_MSG_WARN([Cairo-EGL not found - clients will use cairo image])])
+
+  AC_CHECK_LIB([jpeg], [jpeg_CreateDecompress], have_jpeglib=yes)
+  if test x$have_jpeglib == xyes; then
+    CLIENT_LIBS="$CLIENT_LIBS -ljpeg"
+  else
+    AC_ERROR([libjpeg not found])
+  fi
+
 fi
 
 AM_CONDITIONAL(HAVE_POPPLER, test "x$have_poppler" = "xyes")