aboutsummaryrefslogtreecommitdiffstats
path: root/android/utils
diff options
context:
space:
mode:
Diffstat (limited to 'android/utils')
-rw-r--r--android/utils/debug.h2
-rw-r--r--android/utils/jpeg-compress.c197
-rw-r--r--android/utils/jpeg-compress.h93
3 files changed, 292 insertions, 0 deletions
diff --git a/android/utils/debug.h b/android/utils/debug.h
index ec3094d..e97ec43 100644
--- a/android/utils/debug.h
+++ b/android/utils/debug.h
@@ -38,6 +38,8 @@
_VERBOSE_TAG(camera, "camera") \
_VERBOSE_TAG(adevice, "android device connected via port forwarding") \
_VERBOSE_TAG(sensors_port, "sensors emulator connected to android device") \
+ _VERBOSE_TAG(mtport, "multi-touch emulator connected to android device") \
+ _VERBOSE_TAG(mtscreen, "multi-touch screen emulation") \
_VERBOSE_TAG(gles, "hardware OpenGLES emulation") \
_VERBOSE_TAG(adbserver, "ADB server") \
_VERBOSE_TAG(adbclient, "ADB QEMU client") \
diff --git a/android/utils/jpeg-compress.c b/android/utils/jpeg-compress.c
new file mode 100644
index 0000000..2b42a00
--- /dev/null
+++ b/android/utils/jpeg-compress.c
@@ -0,0 +1,197 @@
+/* Copyright (C) 2011 The Android Open Source Project
+**
+** This software is licensed under the terms of the GNU General Public
+** License version 2, as published by the Free Software Foundation, and
+** may be copied, distributed, and modified under those terms.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+*/
+
+#include <stdint.h>
+#include "jinclude.h"
+#include "jpeglib.h"
+#include "jpeg-compress.h"
+#include "panic.h"
+
+/* Implements JPEG destination manager's init_destination routine. */
+static void _on_init_destination(j_compress_ptr cinfo);
+/* Implements JPEG destination manager's empty_output_buffer routine. */
+static boolean _on_empty_output_buffer(j_compress_ptr cinfo);
+/* Implements JPEG destination manager's term_destination routine. */
+static void _on_term_destination(j_compress_ptr cinfo);
+
+/* JPEG compression descriptor. */
+struct AJPEGDesc {
+ /* Common JPEG compression destination manager header. */
+ struct jpeg_destination_mgr common;
+ /* Buffer where to save compressed output. */
+ uint8_t* jpeg_buf;
+ /* Byte size of the 'jpeg_buf' */
+ int size;
+ /* Chunk size to increment the 'jpeg_buf' with on each allocation request. */
+ int chunk_size;
+ /* Size of the header to put in front of the compressed data. */
+ int header_size;
+};
+
+/********************************************************************************
+ * jpeglib callbacks.
+ *******************************************************************************/
+
+/* Implements JPEG destination manager's init_destination routine. */
+static void
+_on_init_destination(j_compress_ptr cinfo)
+{
+ AJPEGDesc* const dst = (AJPEGDesc*)cinfo->dest;
+ if (dst->jpeg_buf == NULL) {
+ /* This is the first time our destination manager is initialized.
+ * Allocate minimal buffer. */
+ dst->size = dst->chunk_size;
+ dst->jpeg_buf = malloc(dst->size);
+ if (dst->jpeg_buf == NULL) {
+ APANIC("Unable to allocate %d bytes for JPEG compression", dst->size);
+ }
+ }
+ /* Initialize common header with entire destination buffer. */
+ dst->common.next_output_byte = dst->jpeg_buf + dst->header_size;
+ dst->common.free_in_buffer = dst->size - dst->header_size;
+}
+
+/* Implements JPEG destination manager's empty_output_buffer routine.
+ * Name is a bit misleading here. This routine is called by the compressor when
+ * output buffer doesn't have enough free space to contain the next chunk of the
+ * compressed data. So, here we should reallocate the output buffer, rather than
+ * "empty" it.
+ */
+static boolean
+_on_empty_output_buffer(j_compress_ptr cinfo)
+{
+ AJPEGDesc* const dst = (AJPEGDesc*)cinfo->dest;
+ /* Save already compressed data size. */
+ const int accumulated = jpeg_compressor_get_jpeg_size(dst);
+
+ /* Reallocate output buffer. */
+ dst->size += dst->chunk_size;
+ dst->jpeg_buf = realloc(dst->jpeg_buf, dst->size);
+ if (dst->jpeg_buf == NULL) {
+ APANIC("Unable to allocate %d bytes for JPEG compression", dst->size);
+ }
+
+ /* Update common header. */
+ dst->common.next_output_byte = dst->jpeg_buf + accumulated + dst->header_size;
+ dst->common.free_in_buffer = dst->size - accumulated - dst->header_size;
+
+ return TRUE;
+}
+
+/* Implements JPEG destination manager's term_destination routine.
+ * We don't do anything here. All the cleanup will be performed when the user
+ * calls jpeg_compressor_destroy. */
+static void
+_on_term_destination(j_compress_ptr cinfo)
+{
+}
+
+/********************************************************************************
+ * JPEG compressor API.
+ *******************************************************************************/
+
+AJPEGDesc*
+jpeg_compressor_create(int header_size, int chunk_size)
+{
+ AJPEGDesc* dsc = (AJPEGDesc*)malloc(sizeof(AJPEGDesc));
+ if (dsc == NULL) {
+ APANIC("Unable to allocate JPEG compression descriptor.");
+ }
+
+ dsc->common.next_output_byte = NULL;
+ dsc->common.free_in_buffer = 0;
+ dsc->common.init_destination = _on_init_destination;
+ dsc->common.empty_output_buffer = _on_empty_output_buffer;
+ dsc->common.term_destination = _on_term_destination;
+ dsc->jpeg_buf = NULL;
+ dsc->size = 0;
+ dsc->chunk_size = chunk_size;
+ dsc->header_size = header_size;
+ return dsc;
+}
+
+void
+jpeg_compressor_destroy(AJPEGDesc* dsc)
+{
+ if (dsc != NULL) {
+ if (dsc->jpeg_buf != NULL) {
+ free(dsc->jpeg_buf);
+ }
+ free(dsc);
+ }
+}
+
+int
+jpeg_compressor_get_jpeg_size(const AJPEGDesc* dsc)
+{
+ return (dsc->jpeg_buf == NULL) ? 0 :
+ (uint8_t*)dsc->common.next_output_byte - dsc->jpeg_buf - dsc->header_size;
+}
+
+void*
+jpeg_compressor_get_buffer(const AJPEGDesc* dsc)
+{
+ return dsc->jpeg_buf;
+}
+
+int
+jpeg_compressor_get_header_size(const AJPEGDesc* dsc)
+{
+ return dsc->header_size;
+}
+
+void
+jpeg_compressor_compress_fb(AJPEGDesc* dsc,
+ int x, int y, int w, int h,
+ int bpp, int bpl,
+ const uint8_t* fb,
+ int jpeg_quality){
+ struct jpeg_compress_struct cinfo = {0};
+ struct jpeg_error_mgr err_mgr;
+
+ /*
+ * Initialize compressin information structure, and start compression
+ */
+
+ cinfo.err = jpeg_std_error(&err_mgr);
+ jpeg_create_compress(&cinfo);
+ cinfo.dest = &dsc->common;
+ cinfo.image_width = w;
+ cinfo.image_height = h;
+
+ /* Decode framebuffer's pixel format. There can be only three:
+ * - RGB565,
+ * - RGBA8888,
+ * - RGBX8888 */
+ if (bpp == 2) {
+ /* This is RGB565 - most commonly used pixel format for framebuffer. */
+ cinfo.input_components = 2;
+ cinfo.in_color_space = JCS_RGB_565;
+ } else {
+ /* RGBA8888, or RGBX8888 - makes no difference here. */
+ cinfo.input_components = 4;
+ cinfo.in_color_space = JCS_RGBA_8888;
+ }
+ jpeg_set_defaults(&cinfo);
+ jpeg_set_quality(&cinfo, jpeg_quality, TRUE);
+ jpeg_start_compress(&cinfo, TRUE);
+
+ /* Line by line compress the region. */
+ while (cinfo.next_scanline < cinfo.image_height) {
+ JSAMPROW rgb = (JSAMPROW)(fb + (cinfo.next_scanline + y) * bpl + x * bpp);
+ jpeg_write_scanlines(&cinfo, (JSAMPARRAY)&rgb, 1);
+ }
+
+ /* Complete the compression. */
+ jpeg_finish_compress(&cinfo);
+ jpeg_destroy_compress(&cinfo);
+}
diff --git a/android/utils/jpeg-compress.h b/android/utils/jpeg-compress.h
new file mode 100644
index 0000000..4e0e61a
--- /dev/null
+++ b/android/utils/jpeg-compress.h
@@ -0,0 +1,93 @@
+/* Copyright (C) 2011 The Android Open Source Project
+**
+** This software is licensed under the terms of the GNU General Public
+** License version 2, as published by the Free Software Foundation, and
+** may be copied, distributed, and modified under those terms.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+*/
+#ifndef _ANDROID_UTILS_JPEG_COMPRESS_H
+#define _ANDROID_UTILS_JPEG_COMPRESS_H
+
+/*
+ * Contains declaration of utility routines that compress an RGB bitmap into
+ * a JPEG image.
+ *
+ * NOTE: This code uses a jpeglib library located in distrib/jpeg-6b. It's a
+ * 3-rd party library that uses its own type definitions that are different from
+ * the ones that are use elsewhere in the emulator code. For instance, in the
+ * emulator built for Windows, sizeof(bool) = 1, while in the jpeglib sizeof(bool) = 4.
+ * So, to simplify dealing with these issues, all the code that uses jpeglib should
+ * be compiled separately, and should include only headers that are used to compile
+ * jpeglib.
+ */
+
+
+/* Declares descriptor for a JPEG compression. */
+typedef struct AJPEGDesc AJPEGDesc;
+
+/* Creates a descriptor that will be used for compression.
+ * Param:
+ * header_size - Number of bytes to allocate for a custom header that should
+ * preceed the actual JPEG buffer. This is useful when sending JPEG
+ * somewhere else along with some extra data about the compressed image.
+ * cunk_size - Number of bytes to increment the compressed buffer with each time
+ * compressor requests more memory.
+ * Return:
+ * Initialized compression descriptor.
+ */
+extern AJPEGDesc* jpeg_compressor_create(int header_size, int chunk_size);
+
+/* Destroys compressor descriptor.
+ * Param:
+ * dsc - Compressin descriptor, obtained with jpeg_compressor_create.
+ */
+extern void jpeg_compressor_destroy(AJPEGDesc* dsc);
+
+/* Returns compressed data size.
+ * Param:
+ * dsc - Compression descriptor, obtained with jpeg_compressor_create.
+ * Return:
+ * Compressed data size.
+ */
+extern int jpeg_compressor_get_jpeg_size(const AJPEGDesc* dsc);
+
+/* Returns compressed buffer.
+ * Param:
+ * dsc - Compression descriptor, obtained with jpeg_compressor_create.
+ * Return:
+ * Compressed buffer. NOTE: if 'header_size' parameter passed to the jpeg_compressor_create
+ * for this descriptor was not zero, this routine returns a pointer to the custom
+ * header. Compressed data follows immediately after that header.
+ */
+extern void* jpeg_compressor_get_buffer(const AJPEGDesc* dsc);
+
+/* Returns size of the custom header placed before the compressed data.
+ * Param:
+ * dsc - Compression descriptor, obtained with jpeg_compressor_create.
+ * Return:
+ * Size of the custom header placed before the compressed data.
+ */
+extern int jpeg_compressor_get_header_size(const AJPEGDesc* dsc);
+
+/* Compresses a framebuffer region into JPEG image.
+ * Param:
+ * dsc - Compression descriptor, obtained with jpeg_compressor_create.
+ * x, y, w, h - Coordinates and sizes of framebuffer region to compress.
+ * bpp - Number of bytes per pixel in the framebuffer.
+ * bpl - Number of bytes per line in the framebuffer.
+ * fb - Beginning of the framebuffer.
+ * jpeg_quality JPEG compression quality. A number from 1 to 100. Note that
+ * value 10 provides pretty decent image for the purpose of multi-touch
+ * emulation.
+ */
+extern void jpeg_compressor_compress_fb(AJPEGDesc* dsc,
+ int x, int y, int w, int h,
+ int bpp, int bpl,
+ const uint8_t* fb,
+ int jpeg_quality);
+
+#endif /* _ANDROID_UTILS_JPEG_COMPRESS_H */