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/plat/GCJ$JPEG.h>
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 ////////////////////////////////////////////////////////////////
43 #define INPUT_BUF_SIZE (1024 * 16)
46 struct jpeg_source_mgr pub;
47 org::xwt::plat::GCJ$JPEG* myself;
50 void jpeg_error_handler (j_common_ptr cinfo) {
51 jstring message = JvNewStringLatin1(cinfo->err->jpeg_message_table[cinfo->err->msg_code]);
52 throw new java::lang::RuntimeException(message);
55 void term_source (j_decompress_ptr cinfo) { }
56 void init_source (j_decompress_ptr cinfo) { }
58 boolean fill_input_buffer (j_decompress_ptr cinfo) {
59 source_manager* src = (source_manager*)cinfo->src;
60 jint nbytes = src->myself->is->read(src->myself->buffer, 0, INPUT_BUF_SIZE);
62 // the JPEG library specifically suggests padding the end with EOF markers
63 elements(src->myself->buffer)[0] = (jbyte)0xFF;
64 elements(src->myself->buffer)[1] = (jbyte)JPEG_EOI;
67 src->pub.next_input_byte = (JOCTET*)elements(src->myself->buffer);
68 src->pub.bytes_in_buffer = nbytes;
72 void skip_input_data (j_decompress_ptr cinfo, long num_bytes) {
73 source_manager* src = (source_manager*)cinfo->src;
75 while (num_bytes > (long) src->pub.bytes_in_buffer) {
76 num_bytes -= (long) src->pub.bytes_in_buffer;
77 (void) fill_input_buffer(cinfo);
79 src->pub.next_input_byte += (size_t) num_bytes;
80 src->pub.bytes_in_buffer -= (size_t) num_bytes;
84 org::xwt::Picture* org::xwt::plat::GCJ$JPEG::_decodeJPEG(java::io::InputStream* is, jstring name) {
85 struct jpeg_decompress_struct cinfo;
90 // set up our error handler
91 struct jpeg_error_mgr error_handler;
92 cinfo.err = jpeg_std_error(&error_handler);
93 error_handler.error_exit = &jpeg_error_handler;
95 jpeg_create_decompress(&cinfo);
98 buffer = JvNewByteArray(INPUT_BUF_SIZE);
99 src.pub.init_source = init_source;
100 src.pub.fill_input_buffer = fill_input_buffer;
101 src.pub.skip_input_data = skip_input_data;
102 src.pub.resync_to_restart = jpeg_resync_to_restart;
103 src.pub.term_source = term_source;
105 src.pub.next_input_byte = (JOCTET*)elements(buffer);
106 src.pub.bytes_in_buffer = 0;
107 cinfo.src = (jpeg_source_mgr*)&src;
109 jpeg_read_header(&cinfo, 1);
110 jpeg_start_decompress(&cinfo);
111 width = cinfo.output_width;
112 height = cinfo.output_height;
113 data = JvNewIntArray(width * height);
115 while (cinfo.output_scanline < cinfo.output_height) {
116 JSAMPLE* dest = (JSAMPLE*)(elements(data) + cinfo.output_scanline * width);
117 jpeg_read_scanlines(&cinfo, &dest, 1);
120 jpeg_finish_decompress(&cinfo);
122 // fill in the alpha components
123 for(int i=0; i<data->length; i++)
124 elements(data)[i] |= (jint)0xff000000;
126 } catch (java::lang::Throwable* t) {
127 jpeg_destroy_decompress(&cinfo);
130 jpeg_destroy_decompress(&cinfo);
131 return org::xwt::Platform::createPicture(data, width, height);
134 // C++ new/delete operators (JvMalloc never fails)
135 void* operator new(size_t size) { return JvMalloc(size); }
136 void* operator new[](size_t size) { return JvMalloc(size);}
137 void operator delete(void *p) { JvFree(p); }
138 void operator delete[](void *p) { JvFree(p); }