questionable patch: merge of a lot of stuff from the svg branch
[org.ibex.core.git] / src / org / ibex / plat / GCJ.cc
1 // Copyright 2000-2005 the Contributors, as shown in the revision logs.
2 // Licensed under the GNU General Public License version 2 ("the License").
3 // You may not use this file except in compliance with the License.
4
5 // Inclusions /////////////////////////////////////////////////////////
6
7 #include <gcj/cni.h>
8 #include <gcj/array.h>
9 #include <org/ibex/plat/Platform.h>
10 #include <org/ibex/graphics/Picture.h>
11 #include <org/ibex/plat/GCJ.h>
12 #include <java/io/InputStream.h>
13 #include <java/io/ByteArrayInputStream.h>
14 #include <java/lang/RuntimeException.h>
15 #include <org/ibex/plat/GCJ.h>
16 #include <org/ibex/util/Log.h>
17 extern "C" {
18
19 // hack for broken Solaris headers
20 #define _WCHAR_T
21
22 #include <stdlib.h>
23 #include <stdio.h>
24 #include <setjmp.h>
25 #include "jpeglib.h"
26 }
27
28 #ifdef TRUE
29 #undef TRUE
30 #endif
31 #define TRUE 1
32 using org::ibex::util::Log;
33
34 // builtin.xwar /////////////////////////////////////////////////////////
35
36 extern unsigned char builtin_bytes[];
37 extern int builtin_length;
38
39 java::io::InputStream* org::ibex::plat::GCJ::_getBuiltinInputStream() {
40     jbyteArray ret = JvNewByteArray(builtin_length);
41     memcpy(elements(ret), builtin_bytes, builtin_length);
42     return new java::io::ByteArrayInputStream(ret);
43 }
44
45
46
47 // JPEG ////////////////////////////////////////////////////////////////
48
49 typedef struct {
50     struct jpeg_source_mgr pub;
51     java::io::InputStream *is;
52     jbyteArray buf;
53 } my_source_mgr_t;
54
55 typedef struct {
56     struct jpeg_error_mgr pub;
57     jmp_buf setjmp_buffer;
58 } my_error_mgr_t;
59
60 static void error_exit (j_common_ptr cinfo) {
61     my_error_mgr_t *myerr = (my_error_mgr_t*) cinfo->err;
62     longjmp(myerr->setjmp_buffer,1);
63 }
64
65 static void term_source (j_decompress_ptr cinfo) { }
66 static void init_source (j_decompress_ptr cinfo) { }
67
68 boolean fill_input_buffer (j_decompress_ptr cinfo) {
69     my_source_mgr_t* src = (my_source_mgr_t*) cinfo->src;
70     JOCTET *p = (JOCTET*)elements(src->buf);
71     jint n;
72     try {
73         n = src->is->read(src->buf, 0, src->buf->length);
74     } catch(java::lang::Throwable *e) {
75         n = -1;
76     }
77     
78     src->pub.next_input_byte = p;
79     
80     if (n <= 0) {
81         // the JPEG library specifically suggests padding the end with EOF markers
82         p[0] = 0xff;
83         p[1] = JPEG_EOI;
84         src->pub.bytes_in_buffer = 2;
85     } else {
86         src->pub.bytes_in_buffer = n;
87     }
88     return 1;
89 }
90
91 void skip_input_data (j_decompress_ptr cinfo, long num_bytes) {
92     my_source_mgr_t* src = (my_source_mgr_t*) cinfo->src;
93     
94     if (num_bytes <= 0) return; 
95     
96     while (num_bytes > src->pub.bytes_in_buffer) {
97         num_bytes -= src->pub.bytes_in_buffer;
98         fill_input_buffer(cinfo);
99     }
100     src->pub.next_input_byte += num_bytes;
101     src->pub.bytes_in_buffer -= num_bytes;
102 }
103
104 void org::ibex::plat::GCJ::_decodeJPEG(java::io::InputStream* is, org::ibex::graphics::Picture* p) {
105     struct jpeg_decompress_struct cinfo;
106     my_error_mgr_t jerr;
107     my_source_mgr_t src;
108     
109     src.is = is;
110     src.buf = JvNewByteArray(16384);
111     
112     src.pub.init_source = init_source;
113     src.pub.fill_input_buffer = fill_input_buffer;
114     src.pub.skip_input_data = skip_input_data;
115     src.pub.resync_to_restart = jpeg_resync_to_restart;
116     src.pub.term_source = term_source;
117     src.pub.next_input_byte = NULL;
118     src.pub.bytes_in_buffer = 0;
119     
120     if (setjmp(jerr.setjmp_buffer)) {
121         // FEATURE - we should handle errors better than this
122         char msgbuf[JMSG_LENGTH_MAX];
123         (jerr.pub.format_message)((j_common_ptr)&cinfo, msgbuf);
124         Log::info(&GCJ::class$,JvNewStringLatin1(msgbuf));
125         jpeg_destroy_decompress(&cinfo);
126         return;
127     }
128   
129     jpeg_create_decompress(&cinfo);
130     
131     cinfo.src = &src.pub;
132     cinfo.err = jpeg_std_error(&jerr.pub);
133     jerr.pub.error_exit = error_exit;
134     
135     jpeg_read_header(&cinfo,TRUE);
136     jpeg_start_decompress(&cinfo);
137     
138     p->width = cinfo.output_width;
139     p->height = cinfo.output_height;
140     p->data = JvNewIntArray(p->width * p->height);
141     
142     while (cinfo.output_scanline < cinfo.output_height) {
143         JSAMPLE *dest = (JSAMPLE*) (elements(p->data) + cinfo.output_scanline * p->width);
144         jpeg_read_scanlines(&cinfo,&dest,1);
145     }
146     jpeg_finish_decompress(&cinfo);
147     jpeg_destroy_decompress(&cinfo);
148     
149     for(int i=0;i<p->data->length;i++)
150         elements(p->data)[i] |= 0xff000000; // alpha channel
151 }
152
153 // C++ new/delete operators (JvMalloc never fails)
154 void* operator new(size_t size) { return JvMalloc(size); }
155 void* operator new[](size_t size) { return JvMalloc(size);}
156 void operator delete(void *p) { JvFree(p); }
157 void operator delete[](void *p) { JvFree(p); }