Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members | Related Pages

vil_jpeg_decompressor.cxx

Go to the documentation of this file.
00001 // This is core/vil/file_formats/vil_jpeg_decompressor.cxx
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005 //:
00006 // \file
00007 // \author fsm
00008 // \verbatim
00009 //  Modifications
00010 //     11 Oct 2002 Ian Scott - converted to vil
00011 //\endverbatim
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 //: using jpeg decompressor objects :
00021 // -# supply an error manager, e.g. with jpeg_std_err().
00022 //    this *must* be done before initializing the object.
00023 // -# initialize with jpeg_create_decompress().
00024 // -# supply a data stream, e.g. with jpeg_std_source().
00025 // -# call jpeg_read_header() to start reading the data stream. this will read
00026 //    to the start of the compressed data and store various tables and parameters.
00027 //    if you just want the image parameters and not the data, it's ok to stop
00028 //    now, so long as you call jpeg_abort_decompress() or jpeg_destroy_decompress()
00029 //    to release resources.
00030 // -# call jpeg_finish_decompress() if you read all the data. if you only read
00031 //    some of the data, call jpeg_abort_decompress().
00032 // -# destruct the object with jpeg_destroy_decompress().
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   // setup the standard error handler in the jpeg library
00043   jobj.err = jpeg_std_error(&jerr);
00044 
00045   // construct the decompression object :
00046   jpeg_create_decompress(&jobj);
00047 
00048   // we need to read the header here, in order to get parameters such as size.
00049   //
00050   // set the data source
00051   vil_jpeg_stream_src_set(&jobj, stream);
00052 
00053   // rewind the stream
00054   vil_jpeg_stream_src_rewind(&jobj, stream);
00055 
00056   // now we may read the header.
00057   jpeg_read_header(&jobj, TRUE);
00058 
00059   // This seems to be necessary. jpeglib.h claims that one can use
00060   // jpeg_calc_output_dimensions() instead, but I never bothered to try.
00061 #if 1
00062   // bogus decompression to get image parameters.
00063   jpeg_start_decompress(&jobj);
00064 
00065   // this aborts the decompression, but doesn't destroy the object.
00066   jpeg_abort_decompress(&jobj);
00067 #endif
00068 }
00069 
00070 // read the given scanline, skipping/rewinding as required.
00071 JSAMPLE const *vil_jpeg_decompressor::read_scanline(unsigned line)
00072 {
00073   // if the client tries to read the same scanline again, it should be free.
00074   if (valid && line == jobj.output_scanline-1)
00075     return biffer;
00076 
00077   if (ready && line<jobj.output_scanline) {
00078     trace << "...aborting\n";
00079     // bah! have to restart
00080     jpeg_abort_decompress(&jobj);
00081 
00082     //
00083     ready = false;
00084     valid = false;
00085   }
00086 
00087   if (!ready) {
00088     trace << "...restarting\n";
00089 
00090     // rewind stream
00091     vil_jpeg_stream_src_rewind(&jobj, stream);
00092 
00093     // read header
00094     jpeg_read_header(&jobj, TRUE);
00095 
00096     // start decompression
00097     jpeg_start_decompress(&jobj);
00098 
00099     //
00100     ready = true;
00101     valid = false;
00102   }
00103 
00104   // allocate scanline buffer, if necessary.
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   // 'buffer' is a pointer to a 1-element array whose 0th element is biffer.
00112 #if 0
00113   JSAMPLE *buffer[1] = { biffer };
00114 #else
00115   JSAMPARRAY buffer = &biffer;
00116 #endif
00117 
00118   // read till we've read the line we want :
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   // end reached ?
00129   if (jobj.output_scanline >= jobj.image_height) {
00130     trace << "...reached end\n";
00131     jpeg_finish_decompress(&jobj); // this will call vil_jpeg_term_source()
00132     ready = false;
00133   }
00134 
00135   // success.
00136   valid = true; // even if we have reached the end.
00137   return biffer;
00138 }
00139 
00140 
00141 vil_jpeg_decompressor::~vil_jpeg_decompressor()
00142 {
00143   // destroy the pool associated with jobj
00144   (*jobj.mem->free_pool) ((j_common_ptr) &jobj, JPOOL_IMAGE);
00145 
00146   // destroy the decompression object
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 }

Generated on Thu Jan 10 14:39:59 2008 for core/vil by  doxygen 1.4.4