You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@guacamole.apache.org by mj...@apache.org on 2016/03/20 03:24:58 UTC
[28/50] incubator-guacamole-server git commit: GUAC-236: Do not use
features specific to libjpeg-turbo. Ensure compatibility with libjpeg.
GUAC-236: Do not use features specific to libjpeg-turbo. Ensure compatibility with libjpeg.
Project: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/commit/fd430e8b
Tree: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/tree/fd430e8b
Diff: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/diff/fd430e8b
Branch: refs/heads/master
Commit: fd430e8b696a432a93c578930a0a7ab6f9127d5d
Parents: a1822c5
Author: Michael Jumper <mi...@guac-dev.org>
Authored: Wed Mar 16 11:56:04 2016 -0700
Committer: Michael Jumper <mi...@guac-dev.org>
Committed: Wed Mar 16 11:56:04 2016 -0700
----------------------------------------------------------------------
src/guacenc/jpeg.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 68 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/fd430e8b/src/guacenc/jpeg.c
----------------------------------------------------------------------
diff --git a/src/guacenc/jpeg.c b/src/guacenc/jpeg.c
index dfed2d1..c1b9062 100644
--- a/src/guacenc/jpeg.c
+++ b/src/guacenc/jpeg.c
@@ -32,6 +32,58 @@
#include <stdlib.h>
+/**
+ * Translates libjpeg's 24-bit RGB format into Cairo's 32-bit ARGB32 / RGB24
+ * format. The red, green, and blue components from the libjpeg pixel are
+ * copied verbatim, while the extra high byte used within Cairo is set to 0xFF.
+ *
+ * @param src
+ * A pointer to the first byte of the 24-bit RGB pixel within a libjpeg
+ * scanline buffer.
+ *
+ * @return
+ * A 32-bit Cairo ARGB32 / RGB24 pixel value equivalent to the libjpeg
+ * pixel at the given pointer.
+ */
+static uint32_t guacenc_jpeg_translate_rgb(const unsigned char* src) {
+
+ /* Pull components from source */
+ int r = *(src++);
+ int g = *(src++);
+ int b = *(src++);
+
+ /* Translate to 32-bit integer compatible with Cairo */
+ return 0xFF000000 | (r << 16) | (g << 8) | b;
+
+}
+
+/**
+ * Copies the data from a libjpeg scanline buffer into a row of image data
+ * within a Cairo surface, translating each pixel as necessary.
+ *
+ * @param dst
+ * The destination buffer into which the scanline should be copied.
+ *
+ * @param src
+ * The libjpeg scanline buffer that should be copied into the
+ * destination buffer.
+ *
+ * @param width
+ * The number of pixels available within both the scanline buffer and the
+ * destination buffer.
+ */
+static void guacenc_jpeg_copy_scanline(unsigned char* dst,
+ const unsigned char* src, int width) {
+
+ uint32_t* current = (uint32_t*) dst;
+
+ /* Copy all pixels from source to destination, translating for Cairo */
+ for (; width > 0; width--, src += 3) {
+ *(current++) = guacenc_jpeg_translate_rgb(src);
+ }
+
+}
+
cairo_surface_t* guacenc_jpeg_decoder(unsigned char* data, int length) {
struct jpeg_decompress_struct cinfo;
@@ -52,13 +104,16 @@ cairo_surface_t* guacenc_jpeg_decoder(unsigned char* data, int length) {
}
/* Begin decompression */
- cinfo.out_color_space = JCS_EXT_BGRX;
+ cinfo.out_color_space = JCS_RGB;
jpeg_start_decompress(&cinfo);
/* Pull JPEG dimensions from decompressor */
int width = cinfo.output_width;
int height = cinfo.output_height;
+ /* Allocate sufficient buffer space for one JPEG scanline */
+ unsigned char* jpeg_scanline = malloc(width * 3);
+
/* Create blank Cairo surface (no transparency in JPEG) */
cairo_surface_t* surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24,
width, height);
@@ -69,11 +124,22 @@ cairo_surface_t* guacenc_jpeg_decoder(unsigned char* data, int length) {
/* Read JPEG into surface */
while (cinfo.output_scanline < height) {
- unsigned char* buffers[1] = { row };
+
+ /* Read single scanline */
+ unsigned char* buffers[1] = { jpeg_scanline };
jpeg_read_scanlines(&cinfo, buffers, 1);
+
+ /* Copy scanline to Cairo surface */
+ guacenc_jpeg_copy_scanline(row, jpeg_scanline, width);
+
+ /* Advance to next row of Cairo surface */
row += stride;
+
}
+ /* Scanline buffer is no longer needed */
+ free(jpeg_scanline);
+
/* End decompression */
jpeg_finish_decompress(&cinfo);