c9d336d3da3f92ae0b042bad3f404fe52cda4173
[org.ibex.core.git] / src / org / xwt / plat / GCJ.cc
1 // Copyright 2002 Adam Megacz, see the COPYING file for licensing [LGPL]
2
3 // Inclusions /////////////////////////////////////////////////////////
4
5 #include <gcj/cni.h>
6 #include <gcj/array.h>
7 extern "C" {
8
9 // hack for broken Solaris headers
10 #define _WCHAR_T
11
12 #include <stdlib.h>
13 #include <stdio.h>
14 #include <setjmp.h>
15 #include "jpeglib.h"
16 }
17 #include <org/xwt/plat/GCJ.h>
18 #include <java/io/InputStream.h>
19 #include <java/io/ByteArrayInputStream.h>
20 #include <java/lang/RuntimeException.h>
21 #include <org/xwt/plat/GCJ.h>
22 #include <org/xwt/plat/GCJ$JPEG.h>
23
24
25
26 // builtin.xwar /////////////////////////////////////////////////////////
27
28 extern unsigned char builtin_xwar[];
29 extern int builtin_xwar_length;
30
31 java::io::InputStream* org::xwt::plat::GCJ::_getBuiltinInputStream() {
32     jbyteArray ret = JvNewByteArray(builtin_xwar_length);
33     memcpy(elements(ret), builtin_xwar, builtin_xwar_length);
34     return new java::io::ByteArrayInputStream(ret);
35 }
36            
37
38 // freetype.mips /////////////////////////////////////////////////////////
39
40 extern unsigned char freetype_mips[];
41 extern int freetype_mips_length;
42
43 java::io::InputStream* org::xwt::plat::GCJ::_getFreetypeInputStream() {
44     jbyteArray ret = JvNewByteArray(freetype_mips_length);
45     memcpy(elements(ret), freetype_mips, freetype_mips_length);
46     return new java::io::ByteArrayInputStream(ret);
47 }
48            
49
50
51
52 // JPEG ////////////////////////////////////////////////////////////////
53
54 #define INPUT_BUF_SIZE (1024 * 16)
55
56 typedef struct {
57     struct jpeg_source_mgr pub;
58     org::xwt::plat::GCJ$JPEG* myself;
59 } source_manager;
60
61 void jpeg_error_handler (j_common_ptr cinfo) {
62   jstring message = JvNewStringLatin1(cinfo->err->jpeg_message_table[cinfo->err->msg_code]);
63   throw new java::lang::RuntimeException(message);
64 }
65
66 void term_source (j_decompress_ptr cinfo) { }
67 void init_source (j_decompress_ptr cinfo) { }
68
69 boolean fill_input_buffer (j_decompress_ptr cinfo) {
70   source_manager* src = (source_manager*)cinfo->src;
71   jint nbytes = src->myself->is->read(src->myself->buffer, 0, INPUT_BUF_SIZE);
72   if (nbytes <= 0) {
73     // the JPEG library specifically suggests padding the end with EOF markers
74     elements(src->myself->buffer)[0] = (jbyte)0xFF;
75     elements(src->myself->buffer)[1] = (jbyte)JPEG_EOI;
76     nbytes = 2;
77   }
78   src->pub.next_input_byte = (JOCTET*)elements(src->myself->buffer);
79   src->pub.bytes_in_buffer = nbytes;
80   return 1;
81 }
82
83 void skip_input_data (j_decompress_ptr cinfo, long num_bytes) {
84   source_manager* src = (source_manager*)cinfo->src;
85   if (num_bytes > 0) {
86     while (num_bytes > (long) src->pub.bytes_in_buffer) {
87       num_bytes -= (long) src->pub.bytes_in_buffer;
88       (void) fill_input_buffer(cinfo);
89     }
90     src->pub.next_input_byte += (size_t) num_bytes;
91     src->pub.bytes_in_buffer -= (size_t) num_bytes;
92   }
93 }
94
95 void org::xwt::plat::GCJ$JPEG::nativeDecompress() {
96     struct jpeg_decompress_struct cinfo;
97   
98     // set up our error handler
99     struct jpeg_error_mgr error_handler;
100     cinfo.err = jpeg_std_error(&error_handler);
101     error_handler.error_exit = &jpeg_error_handler;
102     
103     jpeg_create_decompress(&cinfo);
104     try {
105         source_manager src;
106         buffer = JvNewByteArray(INPUT_BUF_SIZE);
107         src.pub.init_source = init_source;
108         src.pub.fill_input_buffer = fill_input_buffer;
109         src.pub.skip_input_data = skip_input_data;
110         src.pub.resync_to_restart = jpeg_resync_to_restart;
111         src.pub.term_source = term_source;
112         src.myself = this;
113         src.pub.next_input_byte = (JOCTET*)elements(buffer);
114         src.pub.bytes_in_buffer = 0;
115         cinfo.src = (jpeg_source_mgr*)&src;
116
117         jpeg_read_header(&cinfo, 1);
118         jpeg_start_decompress(&cinfo);
119         width = cinfo.output_width;
120         height = cinfo.output_height;
121         data = JvNewIntArray(width * height);
122
123         while (cinfo.output_scanline < cinfo.output_height) {
124           JSAMPLE* dest = (JSAMPLE*)(elements(data) + cinfo.output_scanline * width);
125           jpeg_read_scanlines(&cinfo, &dest, 1);
126         }
127         
128         jpeg_finish_decompress(&cinfo);
129
130         // fill in the alpha components
131         for(int i=0; i<data->length; i++)
132           elements(data)[i] |= (jint)0xff000000;
133
134     } catch (java::lang::Throwable* t) {
135         jpeg_destroy_decompress(&cinfo);
136         throw t;
137     }
138     jpeg_destroy_decompress(&cinfo);
139 }
140
141 // C++ new/delete operators (JvMalloc never fails)
142 void* operator new(size_t size) { return JvMalloc(size); }
143 void* operator new[](size_t size) { return JvMalloc(size);}
144 void operator delete(void *p) { JvFree(p); }
145 void operator delete[](void *p) { JvFree(p); }