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