10 #include <java/lang/RuntimeException.h>
11 #include <java/io/InputStream.h>
12 #include <org/xwt/plat/GCJ.h>
13 #include <org/xwt/plat/GCJ$JPEG.h>
15 #define INPUT_BUF_SIZE (1024 * 16)
18 struct jpeg_source_mgr pub;
19 org::xwt::plat::GCJ$JPEG* myself;
22 void jpeg_error_handler (j_common_ptr cinfo) {
23 jstring message = JvNewStringLatin1(cinfo->err->jpeg_message_table[cinfo->err->msg_code]);
24 throw new java::lang::RuntimeException(message);
27 void term_source (j_decompress_ptr cinfo) { }
28 void init_source (j_decompress_ptr cinfo) { }
30 boolean fill_input_buffer (j_decompress_ptr cinfo) {
31 source_manager* src = (source_manager*)cinfo->src;
32 jint nbytes = src->myself->is->read(src->myself->buffer, 0, INPUT_BUF_SIZE);
34 // the JPEG library specifically suggests padding the end with EOF markers
35 elements(src->myself->buffer)[0] = (jbyte)0xFF;
36 elements(src->myself->buffer)[1] = (jbyte)JPEG_EOI;
39 src->pub.next_input_byte = (JOCTET*)elements(src->myself->buffer);
40 src->pub.bytes_in_buffer = nbytes;
44 void skip_input_data (j_decompress_ptr cinfo, long num_bytes) {
45 source_manager* src = (source_manager*)cinfo->src;
47 while (num_bytes > (long) src->pub.bytes_in_buffer) {
48 num_bytes -= (long) src->pub.bytes_in_buffer;
49 (void) fill_input_buffer(cinfo);
51 src->pub.next_input_byte += (size_t) num_bytes;
52 src->pub.bytes_in_buffer -= (size_t) num_bytes;
56 void org::xwt::plat::GCJ$JPEG::nativeDecompress() {
57 struct jpeg_decompress_struct cinfo;
59 // set up our error handler
60 struct jpeg_error_mgr error_handler;
61 cinfo.err = jpeg_std_error(&error_handler);
62 error_handler.error_exit = &jpeg_error_handler;
64 jpeg_create_decompress(&cinfo);
67 buffer = JvNewByteArray(INPUT_BUF_SIZE);
68 src.pub.init_source = init_source;
69 src.pub.fill_input_buffer = fill_input_buffer;
70 src.pub.skip_input_data = skip_input_data;
71 src.pub.resync_to_restart = jpeg_resync_to_restart;
72 src.pub.term_source = term_source;
74 src.pub.next_input_byte = (JOCTET*)elements(buffer);
75 src.pub.bytes_in_buffer = 0;
76 cinfo.src = (jpeg_source_mgr*)&src;
78 jpeg_read_header(&cinfo, 1);
79 jpeg_start_decompress(&cinfo);
80 width = cinfo.output_width;
81 height = cinfo.output_height;
82 data = JvNewIntArray(width * height);
84 while (cinfo.output_scanline < cinfo.output_height) {
85 JSAMPLE* dest = (JSAMPLE*)(elements(data) + cinfo.output_scanline * width);
86 jpeg_read_scanlines(&cinfo, &dest, 1);
89 jpeg_finish_decompress(&cinfo);
91 // fill in the alpha components
92 for(int i=0; i<data->length; i++)
93 elements(data)[i] |= (jint)0xff000000;
95 } catch (java::lang::Throwable* t) {
96 jpeg_destroy_decompress(&cinfo);
99 jpeg_destroy_decompress(&cinfo);