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);