00001
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "vil_jpeg_decompressor.h"
00014 #include "vil_jpeg_source_mgr.h"
00015 #include <vil/vil_stream.h>
00016 #include <vcl_iostream.h>
00017
00018 #define trace if (true) { } else vcl_cerr
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 vil_jpeg_decompressor::vil_jpeg_decompressor(vil_stream *s)
00035 : stream(s)
00036 , ready(false)
00037 , valid(false)
00038 , biffer(0)
00039 {
00040 stream->ref();
00041
00042
00043 jobj.err = jpeg_std_error(&jerr);
00044
00045
00046 jpeg_create_decompress(&jobj);
00047
00048
00049
00050
00051 vil_jpeg_stream_src_set(&jobj, stream);
00052
00053
00054 vil_jpeg_stream_src_rewind(&jobj, stream);
00055
00056
00057 jpeg_read_header(&jobj, TRUE);
00058
00059
00060
00061 #if 1
00062
00063 jpeg_start_decompress(&jobj);
00064
00065
00066 jpeg_abort_decompress(&jobj);
00067 #endif
00068 }
00069
00070
00071 JSAMPLE const *vil_jpeg_decompressor::read_scanline(unsigned line)
00072 {
00073
00074 if (valid && line == jobj.output_scanline-1)
00075 return biffer;
00076
00077 if (ready && line<jobj.output_scanline) {
00078 trace << "...aborting\n";
00079
00080 jpeg_abort_decompress(&jobj);
00081
00082
00083 ready = false;
00084 valid = false;
00085 }
00086
00087 if (!ready) {
00088 trace << "...restarting\n";
00089
00090
00091 vil_jpeg_stream_src_rewind(&jobj, stream);
00092
00093
00094 jpeg_read_header(&jobj, TRUE);
00095
00096
00097 jpeg_start_decompress(&jobj);
00098
00099
00100 ready = true;
00101 valid = false;
00102 }
00103
00104
00105 if (!biffer) {
00106 trace << "...allocate buffer\n";
00107 unsigned row_size = jobj.output_width * jobj.output_components;
00108 biffer = new JSAMPLE[row_size];
00109 }
00110
00111
00112 #if 0
00113 JSAMPLE *buffer[1] = { biffer };
00114 #else
00115 JSAMPARRAY buffer = &biffer;
00116 #endif
00117
00118
00119 while (jobj.output_scanline <= line) {
00120 if (jpeg_read_scanlines(&jobj, buffer, 1) != 1) {
00121 jpeg_abort_decompress(&jobj);
00122 ready = false;
00123 valid = false;
00124 return 0;
00125 }
00126 }
00127
00128
00129 if (jobj.output_scanline >= jobj.image_height) {
00130 trace << "...reached end\n";
00131 jpeg_finish_decompress(&jobj);
00132 ready = false;
00133 }
00134
00135
00136 valid = true;
00137 return biffer;
00138 }
00139
00140
00141 vil_jpeg_decompressor::~vil_jpeg_decompressor()
00142 {
00143
00144 (*jobj.mem->free_pool) ((j_common_ptr) &jobj, JPOOL_IMAGE);
00145
00146
00147 jpeg_destroy_decompress(&jobj);
00148
00149
00150 stream->unref();
00151 stream = 0;
00152
00153
00154 if (biffer)
00155 delete [] biffer;
00156 biffer = 0;
00157 }