Re: JPEG Support For Libcairo

"Enrico Weigelt, metux IT consult" <[email protected]>
Newsgroups gmane.comp.lib.cairo
Message-ID <[email protected]>
On 28.12.2015 15:12, Bernhard Fischer wrote:
> I implemented two small functions which read/write JPEG into/from a Cairo 
> image surface.

Added it to cairo tree - see patches.


-- 

mit freundlichen Grüßen
--
Enrico Weigelt,
metux IT consulting
+49-151-27565287

-- 
cairo mailing list
[email protected]
http://lists.cairographics.org/mailman/listinfo/cairo
0003-jpeg-build-rules-for-jpeg-functions.patch (text/x-patch, 1.6 KB)
From f5c26f8c56b6cf6da96ece3c8527c7b1af8d7970 Mon Sep 17 00:00:00 2001
From: "Enrico Weigelt, metux IT consult" <[email protected]>
Date: Tue, 29 Dec 2015 02:59:36 +0100
Subject: [PATCH 3/3] jpeg: build rules for jpeg functions

---
 configure.ac         | 12 ++++++++++++
 src/Makefile.sources |  3 +++
 2 files changed, 15 insertions(+)

diff --git a/configure.ac b/configure.ac
index 2ce1959..a0cca2b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -344,6 +344,18 @@ CAIRO_ENABLE_FUNCTIONS(png, PNG, yes, [
 ])
 
 dnl ===========================================================================
+
+CAIRO_ENABLE_FUNCTIONS(jpeg, JPEG, yes, [
+  use_jpeg=no
+  PKG_CHECK_MODULES(jpeg, libjpeg, use_jpeg="yes", use_jpeg="no")
+
+  dnl try to find it the classical way
+  if test "$use_jpeg" = "no" ; then
+    AC_CHECK_LIB(jpeg,jpeg_start_compress,jpeg_LIBS="-ljpeg"; use_jpeg="yes",use_jpeg="no")
+  fi
+])
+
+dnl ===========================================================================
 CAIRO_ENABLE_SURFACE_BACKEND(gl, OpenGL, no, [
   gl_REQUIRES="gl"
   PKG_CHECK_MODULES(gl, $gl_REQUIRES,, [
diff --git a/src/Makefile.sources b/src/Makefile.sources
index fac24d7..f33000a 100644
--- a/src/Makefile.sources
+++ b/src/Makefile.sources
@@ -271,6 +271,9 @@ cairo_sources += $(_cairo_pdf_operators_sources)
 
 cairo_png_sources = cairo-png.c
 
+cairo_jpeg_sources = imagesource/cairo-jpeg.c
+cairo_jpeg_headers = imagesource/cairo-jpeg.h
+
 cairo_ps_headers = cairo-ps.h
 cairo_ps_private = cairo-ps-surface-private.h
 cairo_ps_sources = cairo-ps-surface.c
-- 
2.6.4.442.g545299f
0002-jpeg-public-header-for-jpeg-related-functions.patch (text/x-patch, 1.7 KB)
From 0ca9321153f5132f60eb878e9dca07bb530e3643 Mon Sep 17 00:00:00 2001
From: "Enrico Weigelt, metux IT consult" <[email protected]>
Date: Tue, 29 Dec 2015 02:11:17 +0100
Subject: [PATCH 2/3] jpeg: public header for jpeg-related functions

---
 src/imagesource/cairo-jpeg.h | 40 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 40 insertions(+)
 create mode 100644 src/imagesource/cairo-jpeg.h

diff --git a/src/imagesource/cairo-jpeg.h b/src/imagesource/cairo-jpeg.h
new file mode 100644
index 0000000..7f9db36
--- /dev/null
+++ b/src/imagesource/cairo-jpeg.h
@@ -0,0 +1,40 @@
+#ifndef __CAIRO_JPEG_H_PUB
+#define __CAIRO_JPEG_H_PUB
+
+/**
+ * Public interface for Cairo's public JPEG API.
+ *
+ * Only available when Cairo was compiled w/ JPEG support
+ */
+
+#include <cairo.h>
+
+/**
+ * Create a new image surface from JPEG image file.
+ *
+ * @param	fn		name of the jpeg file.
+ *
+ * @return	pointer to cairo_surface_t structure.
+ *		may never be NULL, but the surface be in error state
+ */
+cairo_surface_t *cairo_image_surface_create_from_jpeg(const char *fn);
+
+/**
+ * Store image surface into JPEG file.
+ *
+ * @param	sfc	pointer to image surface structure
+ *			currently only supports the following pixel formats:
+ *			CAIRO_FORMAT_ARGB32 or CAIRO_FORMAT_RGB24
+ * @param	fn	JPEG target filename
+ * @param	quality	Compression quality, 0-100.
+ *
+ * @return	CAIRO_STATUS_SUCCESS (0)	if everything went fine
+ *		CAIRO_STATUS_FILE_NOT_FOUND	if file could not be opened
+ *						(errno is set accordingly)
+ *		CAIRO_STATUS_INVALID_FORMAT	if sfc has an invalid format
+ */
+cairo_status_t cairo_image_surface_write_to_jpeg(cairo_surface_t *sfc,
+						 const char *fn,
+						 int quality);
+
+#endif /* __CAIRO_JPEG_H_PUB */
-- 
2.6.4.442.g545299f
0001-jpeg-added-jpeg-load-store-sources.patch (text/x-patch, 5.8 KB)
From a45124526f0a10e98e66b27c587e643cbcb3a4b3 Mon Sep 17 00:00:00 2001
From: "Bernhard R. Fischer, 2048R/5C5FFD47" <[email protected]>
Date: Tue, 29 Dec 2015 02:10:41 +0100
Subject: [PATCH 1/3] jpeg: added jpeg load/store sources

---
 src/imagesource/cairo-jpeg.c | 152 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 152 insertions(+)
 create mode 100644 src/imagesource/cairo-jpeg.c

diff --git a/src/imagesource/cairo-jpeg.c b/src/imagesource/cairo-jpeg.c
new file mode 100644
index 0000000..dc1303d
--- /dev/null
+++ b/src/imagesource/cairo-jpeg.c
@@ -0,0 +1,152 @@
+/*! This file contains two functions for reading and writing JPEG files from
+ * and to Cairo image surfaces. It uses the functions from the libjpeg.
+ * Most of the code is directly derived from the online example at
+ * http://libjpeg-turbo.virtualgl.org/Documentation/Documentation
+ *
+ * cairo_status_t cairo_image_surface_write_to_jpeg(cairo_surface_t *sfc, const char *filename, int quality)
+ * cairo_surface_t *cairo_image_surface_create_from_jpeg(const char *filename);
+ *
+ * The functions parameters and return values are described below directly at the functions.
+ *
+ * To compile the code you need to have installed the packages libcairo2-dev
+ * and libjpeg-dev.
+ * Compile with
+ * gcc -Wall -g `pkg-config cairo libjpeg --cflags --libs` cairo_jpg.c
+ *
+ * @author Bernhard R. Fischer, 2048R/5C5FFD47 [email protected]
+ * @version 2015/12/28
+ * @license This code is free software. Do whatever you like to do with it.
+ */
+
+#include <stdio.h>
+#include <cairo.h>
+#include <jpeglib.h>
+
+
+/*! This function creates a JPEG file from a Cairo image surface.
+ * @param sfc Pointer to a Cairo *image* surface. Its format must either be
+ * CAIRO_FORMAT_ARGB32 or CAIRO_FORMAT_RGB24. Other formats are not supported
+ * by this function, yet.
+ * @param filename Pointer to filename of the destination file.
+ * @param quality Compression quality, 0-100.
+ * @return On success, the function returns 0. If the file could not be opened,
+ * CAIRO_STATUS_FILE_NOT_FOUND is returned and errno is set according to fopen(3). If sfc has an invalid
+ *  format CAIRO_STATUS_INVALID_FORMAT is returned.
+ */
+cairo_status_t cairo_image_surface_write_to_jpeg(cairo_surface_t *sfc, const char *filename, int quality)
+{
+   struct jpeg_compress_struct cinfo;
+   struct jpeg_error_mgr jerr;
+   FILE *outfile;
+   JSAMPROW row_pointer[1];
+
+   // check valid input format
+   if (cairo_surface_get_type(sfc) != CAIRO_SURFACE_TYPE_IMAGE &&
+         cairo_image_surface_get_format(sfc) != CAIRO_FORMAT_ARGB32 &&
+         cairo_image_surface_get_format(sfc) != CAIRO_FORMAT_RGB24)
+      return CAIRO_STATUS_INVALID_FORMAT;
+
+   // finish queued drawing operations
+   cairo_surface_flush(sfc);
+
+   // init jpeg compression structures
+   cinfo.err = jpeg_std_error(&jerr);
+   jpeg_create_compress(&cinfo);
+
+   // open file
+   if ((outfile = fopen(filename, "wb")) == NULL)
+      return CAIRO_STATUS_FILE_NOT_FOUND;
+
+   // set compression parameters
+   jpeg_stdio_dest(&cinfo, outfile);
+   cinfo.image_width = cairo_image_surface_get_width(sfc);
+   cinfo.image_height = cairo_image_surface_get_height(sfc);
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+   cinfo.in_color_space = JCS_EXT_BGRX;
+#else
+   cinfo.in_color_space = JCS_EXT_XRGB;
+#endif
+   cinfo.input_components = 4;
+   jpeg_set_defaults(&cinfo);
+   jpeg_set_quality(&cinfo, quality, TRUE);
+
+   // start compressor
+   jpeg_start_compress(&cinfo, TRUE);
+
+   // loop over all lines and compress
+   while (cinfo.next_scanline < cinfo.image_height)
+   {
+      row_pointer[0] = cairo_image_surface_get_data(sfc) + (cinfo.next_scanline
+            * cairo_image_surface_get_stride(sfc));
+      (void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
+   }
+
+   // finalize and close everything
+   jpeg_finish_compress(&cinfo);
+   fclose(outfile);
+   jpeg_destroy_compress(&cinfo);
+
+   return CAIRO_STATUS_SUCCESS;
+}
+
+
+/*! This function reads an JPEG image from a file an creates a Cairo image
+ * surface.
+ * @param filename Pointer to filename of JPEG file.
+ * @return Returns a pointer to a cairo_surface_t structure. It should be
+ * checked with cairo_surface_status() for errors.
+ */
+cairo_surface_t *cairo_image_surface_create_from_jpeg(const char *filename)
+{
+   struct jpeg_decompress_struct cinfo;
+   struct jpeg_error_mgr jerr;
+   FILE * infile;
+   JSAMPROW row_pointer[1];
+   cairo_surface_t *sfc;
+
+   // open input file
+   if ((infile = fopen(filename, "rb")) == NULL)
+      //return NULL;
+      return cairo_image_surface_create(CAIRO_FORMAT_INVALID, 0, 0);
+
+   // initialize jpeg decompression structures
+   cinfo.err = jpeg_std_error(&jerr);
+   jpeg_create_decompress(&cinfo);
+   jpeg_stdio_src(&cinfo, infile);
+   (void) jpeg_read_header(&cinfo, TRUE);
+
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+   cinfo.out_color_space = JCS_EXT_BGRA;
+#else
+   cinfo.out_color_space = JCS_EXT_ARGB;
+#endif
+
+   // start decompressor
+   (void) jpeg_start_decompress(&cinfo);
+
+   // create Cairo image surface
+   sfc = cairo_image_surface_create(CAIRO_FORMAT_RGB24, cinfo.output_width, cinfo.output_height);
+   if (cairo_surface_status(sfc) != CAIRO_STATUS_SUCCESS)
+   {
+      fclose(infile);
+      jpeg_destroy_decompress(&cinfo);
+      return sfc;
+   }
+
+
+   // loop over all scanlines and fill Cairo image surface
+   while (cinfo.output_scanline < cinfo.output_height)
+   {
+      row_pointer[0] = cairo_image_surface_get_data(sfc) +
+         (cinfo.output_scanline * cairo_image_surface_get_stride(sfc));
+      (void) jpeg_read_scanlines(&cinfo, row_pointer, 1);
+   }
+
+   // finish and close everything
+   cairo_surface_mark_dirty(sfc);
+   (void) jpeg_finish_decompress(&cinfo);
+   jpeg_destroy_decompress(&cinfo);
+   fclose(infile);
+
+   return sfc;
+}
-- 
2.6.4.442.g545299f
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.