X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=src%2Forg%2Fxwt%2Fplat%2FGCJ.cc;h=74589e4f1c48814fc37d165c10375812ecf60f04;hb=2aabdb988d48f5c1cbc155f14ccb96257e83d670;hp=8d1c8b69c3fce7bea45c73efd06983e3c419a92f;hpb=88a934a98c8dbbc944b00f15361eaa7248737543;p=org.ibex.core.git diff --git a/src/org/xwt/plat/GCJ.cc b/src/org/xwt/plat/GCJ.cc index 8d1c8b6..74589e4 100644 --- a/src/org/xwt/plat/GCJ.cc +++ b/src/org/xwt/plat/GCJ.cc @@ -1 +1,156 @@ - +// Copyright 2002 Adam Megacz, see the COPYING file for licensing [LGPL] + +// Inclusions ///////////////////////////////////////////////////////// + +#include +#include +extern "C" { + +// hack for broken Solaris headers +#define _WCHAR_T + +#include +#include +#include +#include "jpeglib.h" +} +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef TRUE +#define TRUE 1 +#endif +using org::xwt::util::Log; + +#define TRUE 1 + +// 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 //////////////////////////////////////////////////////////////// + +typedef struct { + struct jpeg_source_mgr pub; + java::io::InputStream *is; + jbyteArray buf; +} my_source_mgr_t; + +typedef struct { + struct jpeg_error_mgr pub; + jmp_buf setjmp_buffer; +} my_error_mgr_t; + +static void error_exit (j_common_ptr cinfo) { + my_error_mgr_t *myerr = (my_error_mgr_t*) cinfo->err; + longjmp(myerr->setjmp_buffer,1); +} + +static void term_source (j_decompress_ptr cinfo) { } +static void init_source (j_decompress_ptr cinfo) { } + +boolean fill_input_buffer (j_decompress_ptr cinfo) { + my_source_mgr_t* src = (my_source_mgr_t*) cinfo->src; + JOCTET *p = (JOCTET*)elements(src->buf); + jint n; + try { + n = src->is->read(src->buf, 0, src->buf->length); + } catch(java::lang::Throwable *e) { + n = -1; + } + + src->pub.next_input_byte = p; + + if (n <= 0) { + // the JPEG library specifically suggests padding the end with EOF markers + p[0] = 0xff; + p[1] = JPEG_EOI; + src->pub.bytes_in_buffer = 2; + } else { + src->pub.bytes_in_buffer = n; + } + return 1; +} + +void skip_input_data (j_decompress_ptr cinfo, long num_bytes) { + my_source_mgr_t* src = (my_source_mgr_t*) cinfo->src; + + if (num_bytes <= 0) return; + + while (num_bytes > src->pub.bytes_in_buffer) { + num_bytes -= src->pub.bytes_in_buffer; + fill_input_buffer(cinfo); + } + src->pub.next_input_byte += num_bytes; + src->pub.bytes_in_buffer -= num_bytes; +} + +void org::xwt::plat::GCJ::_decodeJPEG(java::io::InputStream* is, org::xwt::Picture* p) { + struct jpeg_decompress_struct cinfo; + my_error_mgr_t jerr; + my_source_mgr_t src; + + src.is = is; + src.buf = JvNewByteArray(16384); + + 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.pub.next_input_byte = NULL; + src.pub.bytes_in_buffer = 0; + + if (setjmp(jerr.setjmp_buffer)) { + // FEATURE - we should handle errors better than this + char msgbuf[JMSG_LENGTH_MAX]; + (jerr.pub.format_message)((j_common_ptr)&cinfo, msgbuf); + Log::info(&GCJ::class$,JvNewStringLatin1(msgbuf)); + jpeg_destroy_decompress(&cinfo); + return; + } + + jpeg_create_decompress(&cinfo); + + cinfo.src = &src.pub; + cinfo.err = jpeg_std_error(&jerr.pub); + jerr.pub.error_exit = error_exit; + + jpeg_read_header(&cinfo,TRUE); + jpeg_start_decompress(&cinfo); + + p->width = cinfo.output_width; + p->height = cinfo.output_height; + p->data = JvNewIntArray(p->width * p->height); + + while (cinfo.output_scanline < cinfo.output_height) { + JSAMPLE *dest = (JSAMPLE*) (elements(p->data) + cinfo.output_scanline * p->width); + jpeg_read_scanlines(&cinfo,&dest,1); + } + jpeg_finish_decompress(&cinfo); + jpeg_destroy_decompress(&cinfo); + + for(int i=0;idata->length;i++) + elements(p->data)[i] |= 0xff000000; // alpha channel +} + +// 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); }