9efbe82fccc33048a5490c13a6627e5c16812990
[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 #include <stdlib.h>
9 #include <stdio.h>
10 #include <setjmp.h>
11 #include "jpeglib.h"
12 }
13 #include <org/xwt/util/JSObject.h>
14 #include <org/xwt/plat/GCJ.h>
15 #include <java/io/InputStream.h>
16 #include <java/io/ByteArrayInputStream.h>
17 #include <java/lang/RuntimeException.h>
18 #include <org/xwt/plat/GCJ.h>
19 #include <org/xwt/plat/GCJ$JPEG.h>
20
21
22
23 // builtin.xwar /////////////////////////////////////////////////////////
24
25 extern unsigned char builtin_xwar[];
26 extern int builtin_xwar_length;
27
28 java::io::InputStream* org::xwt::plat::GCJ::_getBuiltinInputStream() {
29     jbyteArray ret = JvNewByteArray(builtin_xwar_length);
30     memcpy(elements(ret), builtin_xwar, builtin_xwar_length);
31     return new java::io::ByteArrayInputStream(ret);
32 }
33            
34
35
36 // JPEG ////////////////////////////////////////////////////////////////
37
38 #define INPUT_BUF_SIZE (1024 * 16)
39
40 typedef struct {
41     struct jpeg_source_mgr pub;
42     org::xwt::plat::GCJ$JPEG* myself;
43 } source_manager;
44
45 void jpeg_error_handler (j_common_ptr cinfo) {
46   jstring message = JvNewStringLatin1(cinfo->err->jpeg_message_table[cinfo->err->msg_code]);
47   throw new java::lang::RuntimeException(message);
48 }
49
50 void term_source (j_decompress_ptr cinfo) { }
51 void init_source (j_decompress_ptr cinfo) { }
52
53 boolean fill_input_buffer (j_decompress_ptr cinfo) {
54   source_manager* src = (source_manager*)cinfo->src;
55   jint nbytes = src->myself->is->read(src->myself->buffer, 0, INPUT_BUF_SIZE);
56   if (nbytes <= 0) {
57     // the JPEG library specifically suggests padding the end with EOF markers
58     elements(src->myself->buffer)[0] = (jbyte)0xFF;
59     elements(src->myself->buffer)[1] = (jbyte)JPEG_EOI;
60     nbytes = 2;
61   }
62   src->pub.next_input_byte = (JOCTET*)elements(src->myself->buffer);
63   src->pub.bytes_in_buffer = nbytes;
64   return 1;
65 }
66
67 void skip_input_data (j_decompress_ptr cinfo, long num_bytes) {
68   source_manager* src = (source_manager*)cinfo->src;
69   if (num_bytes > 0) {
70     while (num_bytes > (long) src->pub.bytes_in_buffer) {
71       num_bytes -= (long) src->pub.bytes_in_buffer;
72       (void) fill_input_buffer(cinfo);
73     }
74     src->pub.next_input_byte += (size_t) num_bytes;
75     src->pub.bytes_in_buffer -= (size_t) num_bytes;
76   }
77 }
78
79 void org::xwt::plat::GCJ$JPEG::nativeDecompress() {
80     struct jpeg_decompress_struct cinfo;
81   
82     // set up our error handler
83     struct jpeg_error_mgr error_handler;
84     cinfo.err = jpeg_std_error(&error_handler);
85     error_handler.error_exit = &jpeg_error_handler;
86     
87     jpeg_create_decompress(&cinfo);
88     try {
89         source_manager src;
90         buffer = JvNewByteArray(INPUT_BUF_SIZE);
91         src.pub.init_source = init_source;
92         src.pub.fill_input_buffer = fill_input_buffer;
93         src.pub.skip_input_data = skip_input_data;
94         src.pub.resync_to_restart = jpeg_resync_to_restart;
95         src.pub.term_source = term_source;
96         src.myself = this;
97         src.pub.next_input_byte = (JOCTET*)elements(buffer);
98         src.pub.bytes_in_buffer = 0;
99         cinfo.src = (jpeg_source_mgr*)&src;
100
101         jpeg_read_header(&cinfo, 1);
102         jpeg_start_decompress(&cinfo);
103         width = cinfo.output_width;
104         height = cinfo.output_height;
105         data = JvNewIntArray(width * height);
106
107         while (cinfo.output_scanline < cinfo.output_height) {
108           JSAMPLE* dest = (JSAMPLE*)(elements(data) + cinfo.output_scanline * width);
109           jpeg_read_scanlines(&cinfo, &dest, 1);
110         }
111         
112         jpeg_finish_decompress(&cinfo);
113
114         // fill in the alpha components
115         for(int i=0; i<data->length; i++)
116           elements(data)[i] |= (jint)0xff000000;
117
118     } catch (java::lang::Throwable* t) {
119         jpeg_destroy_decompress(&cinfo);
120         throw t;
121     }
122     jpeg_destroy_decompress(&cinfo);
123 }
124