1 // Copyright 2002 Adam Megacz, see the COPYING file for licensing [LGPL]
3 // Inclusions /////////////////////////////////////////////////////////
9 // hack for broken Solaris headers
17 #include <org/xwt/Platform.h>
18 #include <org/xwt/Picture.h>
19 #include <org/xwt/plat/GCJ.h>
20 #include <java/io/InputStream.h>
21 #include <java/io/ByteArrayInputStream.h>
22 #include <java/lang/RuntimeException.h>
23 #include <org/xwt/plat/GCJ.h>
24 #include <org/xwt/util/Log.h>
26 using org::xwt::util::Log;
28 // builtin.xwar /////////////////////////////////////////////////////////
30 extern unsigned char builtin_bytes[];
31 extern int builtin_length;
33 java::io::InputStream* org::xwt::plat::GCJ::_getBuiltinInputStream() {
34 jbyteArray ret = JvNewByteArray(builtin_length);
35 memcpy(elements(ret), builtin_bytes, builtin_length);
36 return new java::io::ByteArrayInputStream(ret);
41 // JPEG ////////////////////////////////////////////////////////////////
44 struct jpeg_source_mgr pub;
45 java::io::InputStream *is;
50 struct jpeg_error_mgr pub;
51 jmp_buf setjmp_buffer;
54 static void error_exit (j_common_ptr cinfo) {
55 my_error_mgr_t *myerr = (my_error_mgr_t*) cinfo->err;
56 longjmp(myerr->setjmp_buffer,1);
59 static void term_source (j_decompress_ptr cinfo) { }
60 static void init_source (j_decompress_ptr cinfo) { }
62 boolean fill_input_buffer (j_decompress_ptr cinfo) {
63 my_source_mgr_t* src = (my_source_mgr_t*) cinfo->src;
64 JOCTET *p = (JOCTET*)elements(src->buf);
67 n = src->is->read(src->buf, 0, src->buf->length);
68 } catch(java::lang::Throwable *e) {
72 src->pub.next_input_byte = p;
75 // the JPEG library specifically suggests padding the end with EOF markers
78 src->pub.bytes_in_buffer = 2;
80 src->pub.bytes_in_buffer = n;
85 void skip_input_data (j_decompress_ptr cinfo, long num_bytes) {
86 my_source_mgr_t* src = (my_source_mgr_t*) cinfo->src;
88 if (num_bytes <= 0) return;
90 while (num_bytes > src->pub.bytes_in_buffer) {
91 num_bytes -= src->pub.bytes_in_buffer;
92 fill_input_buffer(cinfo);
94 src->pub.next_input_byte += num_bytes;
95 src->pub.bytes_in_buffer -= num_bytes;
98 org::xwt::Picture* org::xwt::plat::GCJ::_decodeJPEG(java::io::InputStream* is, jstring name) {
99 struct jpeg_decompress_struct cinfo;
107 src.buf = JvNewByteArray(16384);
109 src.pub.init_source = init_source;
110 src.pub.fill_input_buffer = fill_input_buffer;
111 src.pub.skip_input_data = skip_input_data;
112 src.pub.resync_to_restart = jpeg_resync_to_restart;
113 src.pub.term_source = term_source;
114 src.pub.next_input_byte = NULL;
115 src.pub.bytes_in_buffer = 0;
117 if (setjmp(jerr.setjmp_buffer)) {
118 // FEATURE - we should handle errors better than this
119 char msgbuf[JMSG_LENGTH_MAX];
120 (jerr.pub.format_message)((j_common_ptr)&cinfo, msgbuf);
121 Log::log(&GCJ::class$,JvNewStringLatin1(msgbuf));
122 jpeg_destroy_decompress(&cinfo);
126 jpeg_create_decompress(&cinfo);
128 cinfo.src = &src.pub;
129 cinfo.err = jpeg_std_error(&jerr.pub);
130 jerr.pub.error_exit = error_exit;
132 jpeg_read_header(&cinfo,TRUE);
133 jpeg_start_decompress(&cinfo);
135 width = cinfo.output_width;
136 height = cinfo.output_height;
137 data = JvNewIntArray(width * height);
139 while (cinfo.output_scanline < cinfo.output_height) {
140 JSAMPLE *dest = (JSAMPLE*) (elements(data) + cinfo.output_scanline * width);
141 jpeg_read_scanlines(&cinfo,&dest,1);
143 jpeg_finish_decompress(&cinfo);
144 jpeg_destroy_decompress(&cinfo);
146 for(int i=0;i<data->length;i++)
147 elements(data)[i] |= 0xff000000; // alpha channel
149 return org::xwt::Platform::createPicture(data, width, height);
152 // C++ new/delete operators (JvMalloc never fails)
153 void* operator new(size_t size) { return JvMalloc(size); }
154 void* operator new[](size_t size) { return JvMalloc(size);}
155 void operator delete(void *p) { JvFree(p); }
156 void operator delete[](void *p) { JvFree(p); }