Pushing jpeg codec support, used in xrdp's offscreen surface remoting technique....
authorJim Grandy <jgrandy@authentic8.com>
Tue, 26 Jun 2012 23:57:18 +0000 (16:57 -0700)
committerJim Grandy <jgrandy@authentic8.com>
Tue, 26 Jun 2012 23:57:18 +0000 (16:57 -0700)
client/X11/xf_graphics.c
include/freerdp/codec/jpeg.h [new file with mode: 0644]
libfreerdp-cache/bitmap.c
libfreerdp-codec/CMakeLists.txt
libfreerdp-codec/jpeg.c [new file with mode: 0644]
libfreerdp-core/capabilities.c
libfreerdp-gdi/graphics.c

index f88a29d..ce9e028 100644 (file)
@@ -25,6 +25,7 @@
 #endif
 
 #include <freerdp/codec/bitmap.h>
+#include <freerdp/codec/jpeg.h>
 
 #include "xf_graphics.h"
 
@@ -116,7 +117,14 @@ void xf_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap,
        else
                bitmap->data = (uint8*) xrealloc(bitmap->data, size);
 
-       if (compressed)
+       if (compressed == 2)
+       {
+               if (!jpeg_decompress(data, bitmap->data, width, height, length, bpp))
+               {
+                       printf("jpeg Decompression Failed\n");
+               }
+       }
+       else if (compressed)
        {
                boolean status;
 
diff --git a/include/freerdp/codec/jpeg.h b/include/freerdp/codec/jpeg.h
new file mode 100644 (file)
index 0000000..36540d9
--- /dev/null
@@ -0,0 +1,28 @@
+/**
+ * FreeRDP: A Remote Desktop Protocol Client
+ * Compressed Bitmap
+ *
+ * Copyright 2012 Jay Sorg <jay.sorg@gmail.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __JPEG_H
+#define __JPEG_H
+
+#include <freerdp/types.h>
+
+boolean
+jpeg_decompress(uint8* input, uint8* output, int width, int height, int size, int bpp);
+
+#endif /* __BITMAP_H */
index a382bfe..6d42d26 100644 (file)
@@ -102,9 +102,18 @@ void update_gdi_cache_bitmap_v2(rdpContext* context, CACHE_BITMAP_V2_ORDER* cach
                cache_bitmap_v2->bitmapBpp = context->instance->settings->color_depth;
        }
 
-       bitmap->Decompress(context, bitmap,
-                       cache_bitmap_v2->bitmapDataStream, cache_bitmap_v2->bitmapWidth, cache_bitmap_v2->bitmapHeight,
-                       cache_bitmap_v2->bitmapBpp, cache_bitmap_v2->bitmapLength, cache_bitmap_v2->compressed);
+       if (cache_bitmap_v2->compressed && (cache_bitmap_v2->flags & 0x80))
+       {
+               bitmap->Decompress(context, bitmap,
+                               cache_bitmap_v2->bitmapDataStream, cache_bitmap_v2->bitmapWidth, cache_bitmap_v2->bitmapHeight,
+                               cache_bitmap_v2->bitmapBpp, cache_bitmap_v2->bitmapLength, 2);
+       }
+       else
+       {
+               bitmap->Decompress(context, bitmap,
+                               cache_bitmap_v2->bitmapDataStream, cache_bitmap_v2->bitmapWidth, cache_bitmap_v2->bitmapHeight,
+                               cache_bitmap_v2->bitmapBpp, cache_bitmap_v2->bitmapLength, cache_bitmap_v2->compressed);
+       }
 
        bitmap->New(context, bitmap);
 
index 78d7610..442b5fb 100644 (file)
@@ -44,6 +44,7 @@ set(FREERDP_CODEC_SRCS
        nsc_types.h
        mppc_dec.c
        mppc_enc.c
+       jpeg.c
 )
 
 if(WITH_SSE2)
@@ -67,7 +68,7 @@ endif()
 add_library(freerdp-codec ${FREERDP_CODEC_SRCS})
 
 set_target_properties(freerdp-codec PROPERTIES VERSION ${FREERDP_VERSION_FULL} SOVERSION ${FREERDP_VERSION} PREFIX "lib")
-target_link_libraries(freerdp-codec freerdp-utils)
+target_link_libraries(freerdp-codec freerdp-utils jpeg)
 
 install(TARGETS freerdp-codec DESTINATION ${CMAKE_INSTALL_LIBDIR})
 
diff --git a/libfreerdp-codec/jpeg.c b/libfreerdp-codec/jpeg.c
new file mode 100644 (file)
index 0000000..ac96def
--- /dev/null
@@ -0,0 +1,141 @@
+/**
+ * FreeRDP: A Remote Desktop Protocol Client
+ * Compressed jpeg
+ *
+ * Copyright 2012 Jay Sorg <jay.sorg@gmail.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <freerdp/utils/stream.h>
+#include <freerdp/utils/memory.h>
+#include <freerdp/codec/color.h>
+
+#define HAVE_BOOLEAN
+#include <jpeglib.h>
+
+struct mydata_decomp
+{
+       char* data;
+       int data_bytes;
+};
+
+/*****************************************************************************/
+static void my_init_source(j_decompress_ptr cinfo)
+{
+}
+
+/*****************************************************************************/
+static boolean my_fill_input_buffer(j_decompress_ptr cinfo)
+{
+       struct mydata_decomp* md;
+
+       md = (struct mydata_decomp*)(cinfo->client_data);
+       cinfo->src->next_input_byte = (unsigned char*)(md->data);
+       cinfo->src->bytes_in_buffer = md->data_bytes;
+       return 1;
+}
+
+/*****************************************************************************/
+static void my_skip_input_data(j_decompress_ptr cinfo, long num_bytes)
+{
+}
+
+/*****************************************************************************/
+static boolean my_resync_to_restart(j_decompress_ptr cinfo, int desired)
+{
+       return 1;
+}
+
+/*****************************************************************************/
+static void my_term_source(j_decompress_ptr cinfo)
+{
+}
+
+/*****************************************************************************/
+int
+do_decompress(char* comp_data, int comp_data_bytes,
+              int* width, int* height, int* bpp,
+              char* decomp_data, int* decomp_data_bytes)
+{
+       struct jpeg_decompress_struct cinfo;
+       struct jpeg_error_mgr jerr;
+       struct jpeg_source_mgr src_mgr;
+       struct mydata_decomp md;
+       JSAMPROW row_pointer[1];
+
+       memset(&cinfo, 0, sizeof(cinfo));
+       cinfo.err = jpeg_std_error(&jerr);
+       jpeg_create_decompress(&cinfo);
+
+       memset(&src_mgr, 0, sizeof(src_mgr));
+       cinfo.src = &src_mgr;
+       src_mgr.init_source = my_init_source;
+       src_mgr.fill_input_buffer = my_fill_input_buffer;
+       src_mgr.skip_input_data = my_skip_input_data;
+       src_mgr.resync_to_restart = my_resync_to_restart;
+       src_mgr.term_source = my_term_source;
+
+       memset(&md, 0, sizeof(md));
+       md.data = comp_data;
+       md.data_bytes = comp_data_bytes;
+       cinfo.client_data = &md;
+
+       jpeg_read_header(&cinfo, 1);
+
+       cinfo.out_color_space = JCS_RGB;
+
+       *width = cinfo.image_width;
+       *height = cinfo.image_height;
+       *bpp = cinfo.num_components * 8;
+
+       jpeg_start_decompress(&cinfo);
+
+       while(cinfo.output_scanline < cinfo.image_height)
+       {
+               row_pointer[0] = (JSAMPROW) decomp_data;
+               jpeg_read_scanlines(&cinfo, row_pointer, 1);
+               decomp_data += cinfo.image_width * cinfo.num_components;
+       }
+       *decomp_data_bytes = cinfo.output_width *
+                       cinfo.output_height * cinfo.num_components;
+       jpeg_finish_decompress(&cinfo);
+       jpeg_destroy_decompress(&cinfo);
+       return 0;
+}
+
+/* jpeg decompress */
+boolean
+jpeg_decompress(uint8 * input, uint8 * output, int width, int height, int size, int bpp)
+{
+       int lwidth;
+       int lheight;
+       int lbpp;
+       int ldecomp_data_bytes;
+
+       if (bpp != 24)
+       {
+               return 0;
+       }
+       if (do_decompress((char*)input, size,
+                       &lwidth, &lheight, &lbpp,
+                       (char*)output, &ldecomp_data_bytes) != 0)
+       {
+               return 0;
+       }
+       if (lwidth != width || lheight != height || lbpp != bpp)
+       {
+               return 0;
+       }
+       return 1;
+}
index 001b38f..43615cd 100644 (file)
@@ -1014,6 +1014,7 @@ void rdp_write_bitmap_cache_v2_capability_set(STREAM* s, rdpSettings* settings)
        header = rdp_capability_set_start(s);
 
        cacheFlags = ALLOW_CACHE_WAITING_LIST_FLAG;
+       cacheFlags |= 0x80; /* jpeg hack */
 
        if (settings->persistent_bitmap_cache)
                cacheFlags |= PERSISTENT_KEYS_EXPECTED_FLAG;
index 0481633..d83ed20 100644 (file)
@@ -22,6 +22,7 @@
 #include <freerdp/gdi/shape.h>
 #include <freerdp/gdi/region.h>
 #include <freerdp/gdi/bitmap.h>
+#include <freerdp/codec/jpeg.h>
 #include <freerdp/gdi/drawing.h>
 #include <freerdp/gdi/clipping.h>
 #include <freerdp/codec/color.h>
@@ -98,7 +99,14 @@ void gdi_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap,
        else
                bitmap->data = (uint8*) xrealloc(bitmap->data, size);
 
-       if (compressed)
+       if (compressed == 2)
+       {
+               if (!jpeg_decompress(data, bitmap->data, width, height, length, bpp))
+               {
+                       printf("jpeg Decompression Failed\n");
+               }
+       }
+       else if (compressed)
        {
                boolean status;