jpegparser.cc

Go to the documentation of this file.
00001 
00003 
00004 //
00005 // Copyright (c) 2002-2004 California Institute of Technology
00006 // Copyright (c) 2004-2007 University of Southern California
00007 // Rob Peters <rjpeters at usc dot edu>
00008 //
00009 // created: Mon Nov 11 15:16:06 2002
00010 // commit: $Id: jpegparser.cc 10065 2007-04-12 05:54:56Z rjpeters $
00011 // $HeadURL: file:///lab/rjpeters/svnrepo/code/trunk/groovx/src/media/jpegparser.cc $
00012 //
00013 // --------------------------------------------------------------------
00014 //
00015 // This file is part of GroovX.
00016 //   [http://ilab.usc.edu/rjpeters/groovx/]
00017 //
00018 // GroovX is free software; you can redistribute it and/or modify it
00019 // under the terms of the GNU General Public License as published by
00020 // the Free Software Foundation; either version 2 of the License, or
00021 // (at your option) any later version.
00022 //
00023 // GroovX is distributed in the hope that it will be useful, but
00024 // WITHOUT ANY WARRANTY; without even the implied warranty of
00025 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00026 // General Public License for more details.
00027 //
00028 // You should have received a copy of the GNU General Public License
00029 // along with GroovX; if not, write to the Free Software Foundation,
00030 // Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
00031 //
00033 
00034 #ifndef GROOVX_MEDIA_JPEGPARSER_CC_UTC20050626084018_DEFINED
00035 #define GROOVX_MEDIA_JPEGPARSER_CC_UTC20050626084018_DEFINED
00036 
00037 #include "jpegparser.h"
00038 
00039 #ifndef HAVE_LIBJPEG
00040 
00041 #include "rutz/error.h"
00042 
00043 void media::load_jpeg(const char* /*filename*/, media::bmap_data& /*data*/)
00044 {
00045   throw rutz::error("jpeg image files are not supported in this build",
00046                     SRC_POS);
00047 }
00048 
00049 #else
00050 
00051 #include "geom/vec2.h"
00052 
00053 #include "media/bmapdata.h"
00054 
00055 #include "rutz/error.h"
00056 #include "rutz/sfmt.h"
00057 
00058 #include <csetjmp>
00059 #include <cstdio>
00060 extern "C"
00061 {
00062 #include <jpeglib.h>
00063 }
00064 #include "rutz/trace.h"
00065 
00066 namespace
00067 {
00068   struct jpeg_aux
00069   {
00070     FILE* infile;
00071     jmp_buf* jmp_state;
00072   };
00073 
00074   void cleanup(jpeg_decompress_struct* cinfo)
00075   {
00076     GVX_TRACE("<jpegparser.cc>::cleanup");
00077 
00078     jpeg_aux* aux = static_cast<jpeg_aux*>(cinfo->client_data);
00079     if (aux->infile != 0)
00080       fclose(aux->infile);
00081     jpeg_destroy_decompress(cinfo);
00082   }
00083 
00084   void jpeg_error_exit(j_common_ptr cinfo)
00085   {
00086     // Since we longjmp out of here, DON'T use any C++ objects that need to
00087     // have destructors run!
00088 
00089     cinfo->err->output_message(cinfo);
00090 
00091     jpeg_aux* aux = static_cast<jpeg_aux*>(cinfo->client_data);
00092     longjmp(*(aux->jmp_state), 1);
00093   }
00094 }
00095 
00096 #define SETJMP_TRY(statement)                            \
00097 do {                                                     \
00098   if (setjmp(state) == 0)                                \
00099     {                                                    \
00100       statement;                                         \
00101     }                                                    \
00102   else                                                   \
00103     {                                                    \
00104       throw rutz::error(#statement " failed", SRC_POS);  \
00105     }                                                    \
00106 } while (0)
00107 
00108 void media::load_jpeg(const char* filename, media::bmap_data& data)
00109 {
00110 GVX_TRACE("media::load_jpeg");
00111 
00112   if (BITS_IN_JSAMPLE != 8)
00113     {
00114       throw rutz::error("jpeg library must be built for 8 bits-per-sample",
00115                         SRC_POS);
00116     }
00117 
00118   jmp_buf state;
00119 
00120   // 1. Allocate and initialize the JPEG decompression object
00121   jpeg_decompress_struct cinfo;
00122   jpeg_error_mgr jerr;
00123 
00124   jpeg_aux aux;
00125   aux.infile = 0;
00126   aux.jmp_state = &state;
00127   cinfo.client_data = static_cast<void*>(&aux);
00128 
00129   cinfo.err = jpeg_std_error(&jerr);
00130   cinfo.err->error_exit = &jpeg_error_exit;
00131 
00132   SETJMP_TRY(jpeg_create_decompress(&cinfo));
00133 
00134   // 2. Specify the source of the compressed data (i.e., the input file)
00135   aux.infile = fopen(filename, "rb");
00136 
00137   if (aux.infile == 0)
00138     {
00139       throw rutz::error(rutz::sfmt("couldn't open '%s' for reading",
00140                                    filename), SRC_POS);
00141     }
00142 
00143 
00144   SETJMP_TRY(jpeg_stdio_src(&cinfo, aux.infile));
00145 
00146   // 3. Call jpeg_read_header() to obtain image info
00147   SETJMP_TRY(jpeg_read_header(&cinfo, TRUE));
00148 
00149   // 4. Set parameters for decompression
00150 
00151   // 5. Start decompression
00152   SETJMP_TRY(jpeg_start_decompress(&cinfo));
00153 
00154   // cinfo.output_width
00155   // cinfo.output_height
00156   // cinfo.out_color_components
00157   // cinfo.output_components
00158 
00159   // 6. Read scanlines
00160   media::bmap_data new_data(geom::vec2<int>(cinfo.output_width,
00161                                             cinfo.output_height),
00162                             cinfo.output_components*BITS_IN_JSAMPLE,
00163                             1);
00164 
00165   while (cinfo.output_scanline < cinfo.output_height)
00166     {
00167       JSAMPLE* dest = new_data.row_ptr(cinfo.output_scanline);
00168 
00169       SETJMP_TRY(jpeg_read_scanlines(&cinfo,
00170                                      &dest,
00171                                      /* max lines */ 1));
00172     }
00173 
00174   // 7. finish decompression
00175   SETJMP_TRY(jpeg_finish_decompress(&cinfo));
00176 
00177   // 8. cleanup
00178   cleanup(&cinfo);
00179 
00180   data.swap(new_data);
00181 }
00182 
00183 #endif // HAVE_LIBJPEG
00184 
00185 static const char __attribute__((used)) vcid_groovx_media_jpegparser_cc_utc20050626084018[] = "$Id: jpegparser.cc 10065 2007-04-12 05:54:56Z rjpeters $ $HeadURL: file:
00186 #endif // !GROOVX_MEDIA_JPEGPARSER_CC_UTC20050626084018_DEFINED

The software described here is Copyright (c) 1998-2005, Rob Peters.
This page was generated Wed Dec 3 06:49:39 2008 by Doxygen version 1.5.5.