8 #include <java/lang/RuntimeException.h>
9 #include <java/io/InputStream.h>
10 #include <org/xwt/plat/GCJ.h>
11 #include <org/xwt/plat/GCJ$JPEG.h>
13 #define INPUT_BUF_SIZE (1024 * 16)
16 struct jpeg_source_mgr pub;
17 org::xwt::plat::GCJ$JPEG* myself;
20 void jpeg_error_handler (j_common_ptr cinfo) {
21 jstring message = JvNewStringLatin1(cinfo->err->jpeg_message_table[cinfo->err->msg_code]);
22 throw new java::lang::RuntimeException(message);
25 void term_source (j_decompress_ptr cinfo) { }
26 void init_source (j_decompress_ptr cinfo) { }
28 boolean fill_input_buffer (j_decompress_ptr cinfo) {
29 source_manager* src = (source_manager*)cinfo->src;
30 jint nbytes = src->myself->is->read(src->myself->buffer, 0, INPUT_BUF_SIZE);
32 // the JPEG library specifically suggests padding the end with EOF markers
33 elements(src->myself->buffer)[0] = (jbyte)0xFF;
34 elements(src->myself->buffer)[1] = (jbyte)JPEG_EOI;
37 src->pub.next_input_byte = (JOCTET*)elements(src->myself->buffer);
38 src->pub.bytes_in_buffer = nbytes;
42 void skip_input_data (j_decompress_ptr cinfo, long num_bytes) {
43 source_manager* src = (source_manager*)cinfo->src;
45 while (num_bytes > (long) src->pub.bytes_in_buffer) {
46 num_bytes -= (long) src->pub.bytes_in_buffer;
47 (void) fill_input_buffer(cinfo);
49 src->pub.next_input_byte += (size_t) num_bytes;
50 src->pub.bytes_in_buffer -= (size_t) num_bytes;
54 void org::xwt::plat::GCJ$JPEG::nativeDecompress() {
55 struct jpeg_decompress_struct cinfo;
57 // set up our error handler
58 struct jpeg_error_mgr error_handler;
59 cinfo.err = jpeg_std_error(&error_handler);
60 error_handler.error_exit = &jpeg_error_handler;
62 jpeg_create_decompress(&cinfo);
65 buffer = JvNewByteArray(INPUT_BUF_SIZE);
66 src.pub.init_source = init_source;
67 src.pub.fill_input_buffer = fill_input_buffer;
68 src.pub.skip_input_data = skip_input_data;
69 src.pub.resync_to_restart = jpeg_resync_to_restart;
70 src.pub.term_source = term_source;
72 src.pub.next_input_byte = (JOCTET*)elements(buffer);
73 src.pub.bytes_in_buffer = 0;
74 cinfo.src = (jpeg_source_mgr*)&src;
76 jpeg_read_header(&cinfo, 1);
77 jpeg_start_decompress(&cinfo);
78 width = cinfo.output_width;
79 height = cinfo.output_height;
80 data = JvNewIntArray(width * height);
82 while (cinfo.output_scanline < cinfo.output_height) {
83 JSAMPLE* dest = (JSAMPLE*)(elements(data) + cinfo.output_scanline * width);
84 jpeg_read_scanlines(&cinfo, &dest, 1);
87 jpeg_finish_decompress(&cinfo);
89 // fill in the alpha components
90 for(int i=0; i<data->length; i++)
91 elements(data)[i] |= (jint)0xff000000;
93 } catch (java::lang::Throwable* t) {
94 jpeg_destroy_decompress(&cinfo);
97 jpeg_destroy_decompress(&cinfo);