core/vil/file_formats/vil_jpeg_compressor.cxx
Go to the documentation of this file.
00001 // This is core/vil/file_formats/vil_jpeg_compressor.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_compressor.h"
00014 #include "vil_jpeg_destination_mgr.h"
00015 #include <vil/vil_stream.h>
00016 #include <vcl_iostream.h>
00017 #include <vxl_config.h>
00018 
00019 vil_jpeg_compressor::vil_jpeg_compressor(vil_stream *s)
00020   : stream(s)
00021   , ready(false), quality(75)
00022 {
00023   stream->ref();
00024 
00025   // setup the standard error handler in the jpeg library
00026   jobj.err = jpeg_std_error(&jerr);
00027 
00028   // Zero just in case..
00029   jobj.next_scanline = 0;
00030 
00031   // construct the compression object :
00032   jpeg_create_compress(&jobj);
00033 
00034   // Increase the amount of memory that can be used. 
00035   // Default (1Mb) was too small.  
00036 #if defined(VXL_ADDRESS_BITS) && VXL_ADDRESS_BITS == 32
00037   jobj.mem->max_memory_to_use = 300 * 1024 * 1024;
00038 #elif defined(VXL_ADDRESS_BITS) && VXL_ADDRESS_BITS == 64
00039   jobj.mem->max_memory_to_use = 1024 * 1024 * 1024;
00040 #else
00041   /* use the default memory settings */
00042 #endif
00043 
00044   // set the data destination
00045   vil_jpeg_stream_dst_set(&jobj, stream);
00046 }
00047 
00048 bool vil_jpeg_compressor::write_scanline(unsigned line, JSAMPLE const *scanline)
00049 {
00050   if (!ready) {
00051     // rewind the stream
00052     vil_jpeg_stream_dst_rewind(&jobj, stream);
00053 
00054     //
00055     jobj.next_scanline = 0;
00056 
00057     // set colorspace of input image. FIXME.
00058     switch (jobj.input_components) {
00059      case 1:
00060       jobj.in_color_space = JCS_GRAYSCALE;
00061       break;
00062      case 3:
00063       jobj.in_color_space = JCS_RGB;
00064       break;
00065      default:
00066       vcl_cerr << __FILE__ " : urgh!\n";
00067       return false;
00068     }
00069 
00070     jpeg_set_defaults(&jobj);
00071     jpeg_set_quality(&jobj, quality, TRUE);
00072 
00073     // start compression
00074     bool write_all_tables = true;
00075     jpeg_start_compress (&jobj, write_all_tables);
00076 
00077     //
00078     ready = true;
00079   }
00080 
00081   //
00082   if (line != jobj.next_scanline) {
00083     vcl_cerr << "scanlines must be written in order\n";
00084     return false;
00085   }
00086 
00087   // write the scanline
00088   { JSAMPLE *tmp = const_cast<JSAMPLE*>(scanline);
00089   jpeg_write_scanlines(&jobj, &tmp, 1); }
00090 
00091   // finish if the last scanline is written
00092   if (line == jobj.image_height - 1) {
00093     jpeg_finish_compress(&jobj);
00094     ready = false;
00095   }
00096 
00097   return true;
00098 }
00099 
00100 vil_jpeg_compressor::~vil_jpeg_compressor()
00101 {
00102   // finish compression if necessary
00103   if (ready)
00104     jpeg_finish_compress(&jobj);
00105 
00106   // destroy the compression object
00107   jpeg_destroy_compress(&jobj);
00108 
00109   //
00110   stream->unref();
00111   stream = 0;
00112 }
00113 
00114 void vil_jpeg_compressor::set_quality(int q)
00115 {
00116   quality = q;
00117 }
00118 
00119 int vil_jpeg_compressor::get_quality()
00120 {
00121   return quality;
00122 }