core/vil1/file_formats/vil1_jpeg_decompressor.cxx

Go to the documentation of this file.
00001 // This is core/vil1/file_formats/vil1_jpeg_decompressor.cxx
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005 //:
00006 // \file
00007 // \author fsm
00008 
00009 #include "vil1_jpeg_decompressor.h"
00010 #include "vil1_jpeg_source_mgr.h"
00011 #include <vil1/vil1_stream.h>
00012 #include <vcl_iostream.h>
00013 
00014 #define trace if (true) { } else vcl_cerr
00015 
00016 //: using jpeg decompressor objects :
00017 // -# supply an error manager, e.g. with jpeg_std_err().
00018 //    this *must* be done before initializing the object.
00019 // -# initialize with jpeg_create_decompress().
00020 // -# supply a data stream, e.g. with jpeg_std_source().
00021 // -# call jpeg_read_header() to start reading the data stream. this will read
00022 //    to the start of the compressed data and store various tables and parameters.
00023 //    if you just want the image parameters and not the data, it's ok to stop
00024 //    now, so long as you call jpeg_abort_decompress() or jpeg_destroy_decompress()
00025 //    to release resources.
00026 // -# call jpeg_finish_decompress() if you read all the data. if you only read
00027 //    some of the data, call jpeg_abort_decompress().
00028 // -# destruct the object with jpeg_destroy_decompress().
00029 
00030 vil1_jpeg_decompressor::vil1_jpeg_decompressor(vil1_stream *s)
00031   : stream(s)
00032   , ready(false)
00033   , valid(false)
00034   , biffer(0)
00035 {
00036   stream->ref();
00037 
00038   // setup the standard error handler in the jpeg library
00039   jobj.err = jpeg_std_error(&jerr);
00040 
00041   // construct the decompression object :
00042   jpeg_create_decompress(&jobj);
00043 
00044   // we need to read the header here, in order to get parameters such as size.
00045   //
00046   // set the data source
00047   vil1_jpeg_stream_src_set(&jobj, stream);
00048 
00049   // rewind the stream
00050   vil1_jpeg_stream_src_rewind(&jobj, stream);
00051 
00052   // now we may read the header.
00053   jpeg_read_header(&jobj, TRUE);
00054 
00055   // This seems to be necessary. jpeglib.h claims that one can use
00056   // jpeg_calc_output_dimensions() instead, but I never bothered to try.
00057 #if 1
00058   // bogus decompression to get image parameters.
00059   jpeg_start_decompress(&jobj);
00060 
00061   // this aborts the decompression, but doesn't destroy the object.
00062   jpeg_abort_decompress(&jobj);
00063 #endif
00064 }
00065 
00066 // read the given scanline, skipping/rewinding as required.
00067 JSAMPLE const *vil1_jpeg_decompressor::read_scanline(unsigned line) {
00068   // if the client tries to read the same scanline again, it should be free.
00069   if (valid && line == jobj.output_scanline-1)
00070     return biffer;
00071 
00072   if (ready && line<jobj.output_scanline) {
00073     trace << "...aborting\n";
00074     // bah! have to restart
00075     jpeg_abort_decompress(&jobj);
00076 
00077     //
00078     ready = false;
00079     valid = false;
00080   }
00081 
00082   if (!ready) {
00083     trace << "...restarting\n";
00084 
00085     // rewind stream
00086     vil1_jpeg_stream_src_rewind(&jobj, stream);
00087 
00088     // read header
00089     jpeg_read_header(&jobj, TRUE);
00090 
00091     // start decompression
00092     jpeg_start_decompress(&jobj);
00093 
00094     //
00095     ready = true;
00096     valid = false;
00097   }
00098 
00099   // allocate scanline buffer, if necessary.
00100   if (!biffer) {
00101     trace << "...allocate buffer\n";
00102     unsigned row_size = jobj.output_width * jobj.output_components;
00103     biffer = new JSAMPLE[row_size];
00104   }
00105 
00106   // 'buffer' is a pointer to a 1-element array whose 0th element is biffer.
00107 #if 0
00108   JSAMPLE *buffer[1] = { biffer };
00109 #else
00110   JSAMPARRAY buffer = &biffer;
00111 #endif
00112 
00113   // read till we've read the line we want :
00114   while (jobj.output_scanline <= line) {
00115     if (jpeg_read_scanlines(&jobj, buffer, 1) != 1) {
00116       jpeg_abort_decompress(&jobj);
00117       ready = false;
00118       valid = false;
00119       return 0;
00120     }
00121   }
00122 
00123   // end reached ?
00124   if (jobj.output_scanline >= jobj.image_height) {
00125     trace << "...reached end\n";
00126     jpeg_finish_decompress(&jobj); // this will call vil1_jpeg_term_source()
00127     ready = false;
00128   }
00129 
00130   // success.
00131   valid = true; // even if we have reached the end.
00132   return biffer;
00133 }
00134 
00135 
00136 vil1_jpeg_decompressor::~vil1_jpeg_decompressor() {
00137   // destroy the pool associated with jobj
00138   (*jobj.mem->free_pool) ((j_common_ptr) &jobj, JPOOL_IMAGE);
00139 
00140   // destroy the decompression object
00141   jpeg_destroy_decompress(&jobj);
00142 
00143   //
00144   stream->unref();
00145   stream = 0;
00146 
00147   //
00148   if (biffer)
00149     delete [] biffer;
00150   biffer = 0;
00151 }

Generated on Sat Nov 22 05:08:28 2008 for core/vil1 by  doxygen 1.5.1