2003/09/20 05:03:47
[org.ibex.core.git] / src / org / xwt / plat / GCJ.cc
index e69de29..3050a2b 100644 (file)
@@ -0,0 +1,132 @@
+// Copyright 2002 Adam Megacz, see the COPYING file for licensing [LGPL]
+
+// Inclusions /////////////////////////////////////////////////////////
+
+#include <gcj/cni.h>
+#include <gcj/array.h>
+extern "C" {
+
+// hack for broken Solaris headers
+#define _WCHAR_T
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <setjmp.h>
+#include "jpeglib.h"
+}
+#include <org/xwt/plat/GCJ.h>
+#include <java/io/InputStream.h>
+#include <java/io/ByteArrayInputStream.h>
+#include <java/lang/RuntimeException.h>
+#include <org/xwt/plat/GCJ.h>
+#include <org/xwt/plat/GCJ$JPEG.h>
+
+
+
+// builtin.xwar /////////////////////////////////////////////////////////
+
+extern unsigned char builtin_bytes[];
+extern int builtin_length;
+
+java::io::InputStream* org::xwt::plat::GCJ::_getBuiltinInputStream() {
+    jbyteArray ret = JvNewByteArray(builtin_length);
+    memcpy(elements(ret), builtin_bytes, builtin_length);
+    return new java::io::ByteArrayInputStream(ret);
+}
+
+
+
+// JPEG ////////////////////////////////////////////////////////////////
+
+#define INPUT_BUF_SIZE (1024 * 16)
+
+typedef struct {
+    struct jpeg_source_mgr pub;
+    org::xwt::plat::GCJ$JPEG* myself;
+} source_manager;
+
+void jpeg_error_handler (j_common_ptr cinfo) {
+  jstring message = JvNewStringLatin1(cinfo->err->jpeg_message_table[cinfo->err->msg_code]);
+  throw new java::lang::RuntimeException(message);
+}
+
+void term_source (j_decompress_ptr cinfo) { }
+void init_source (j_decompress_ptr cinfo) { }
+
+boolean fill_input_buffer (j_decompress_ptr cinfo) {
+  source_manager* src = (source_manager*)cinfo->src;
+  jint nbytes = src->myself->is->read(src->myself->buffer, 0, INPUT_BUF_SIZE);
+  if (nbytes <= 0) {
+    // the JPEG library specifically suggests padding the end with EOF markers
+    elements(src->myself->buffer)[0] = (jbyte)0xFF;
+    elements(src->myself->buffer)[1] = (jbyte)JPEG_EOI;
+    nbytes = 2;
+  }
+  src->pub.next_input_byte = (JOCTET*)elements(src->myself->buffer);
+  src->pub.bytes_in_buffer = nbytes;
+  return 1;
+}
+
+void skip_input_data (j_decompress_ptr cinfo, long num_bytes) {
+  source_manager* src = (source_manager*)cinfo->src;
+  if (num_bytes > 0) {
+    while (num_bytes > (long) src->pub.bytes_in_buffer) {
+      num_bytes -= (long) src->pub.bytes_in_buffer;
+      (void) fill_input_buffer(cinfo);
+    }
+    src->pub.next_input_byte += (size_t) num_bytes;
+    src->pub.bytes_in_buffer -= (size_t) num_bytes;
+  }
+}
+
+void org::xwt::plat::GCJ$JPEG::nativeDecompress() {
+    struct jpeg_decompress_struct cinfo;
+  
+    // set up our error handler
+    struct jpeg_error_mgr error_handler;
+    cinfo.err = jpeg_std_error(&error_handler);
+    error_handler.error_exit = &jpeg_error_handler;
+    
+    jpeg_create_decompress(&cinfo);
+    try {
+       source_manager src;
+       buffer = JvNewByteArray(INPUT_BUF_SIZE);
+       src.pub.init_source = init_source;
+       src.pub.fill_input_buffer = fill_input_buffer;
+       src.pub.skip_input_data = skip_input_data;
+       src.pub.resync_to_restart = jpeg_resync_to_restart;
+       src.pub.term_source = term_source;
+       src.myself = this;
+       src.pub.next_input_byte = (JOCTET*)elements(buffer);
+       src.pub.bytes_in_buffer = 0;
+       cinfo.src = (jpeg_source_mgr*)&src;
+
+       jpeg_read_header(&cinfo, 1);
+       jpeg_start_decompress(&cinfo);
+       width = cinfo.output_width;
+       height = cinfo.output_height;
+       data = JvNewIntArray(width * height);
+
+       while (cinfo.output_scanline < cinfo.output_height) {
+         JSAMPLE* dest = (JSAMPLE*)(elements(data) + cinfo.output_scanline * width);
+         jpeg_read_scanlines(&cinfo, &dest, 1);
+       }
+       
+       jpeg_finish_decompress(&cinfo);
+
+       // fill in the alpha components
+       for(int i=0; i<data->length; i++)
+         elements(data)[i] |= (jint)0xff000000;
+
+    } catch (java::lang::Throwable* t) {
+        jpeg_destroy_decompress(&cinfo);
+        throw t;
+    }
+    jpeg_destroy_decompress(&cinfo);
+}
+
+// C++ new/delete operators (JvMalloc never fails)
+void* operator new(size_t size) { return JvMalloc(size); }
+void* operator new[](size_t size) { return JvMalloc(size);}
+void operator delete(void *p) { JvFree(p); }
+void operator delete[](void *p) { JvFree(p); }