+// Copyright 2002 Adam Megacz, see the COPYING file for licensing [LGPL]
+
+// Inclusions /////////////////////////////////////////////////////////
+
+#include <gcj/cni.h>
+#include <gcj/array.h>
+extern "C" {
+#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>
+
+
+
+// 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;