jpeg_reader.cpp

Go to the documentation of this file.
00001 /*
00002   CLAW - a C++ Library Absolutely Wonderful
00003 
00004   CLAW is a free library without any particular aim but being useful to 
00005   anyone.
00006 
00007   Copyright (C) 2005-2008 Julien Jorge
00008 
00009   This library is free software; you can redistribute it and/or
00010   modify it under the terms of the GNU Lesser General Public
00011   License as published by the Free Software Foundation; either
00012   version 2.1 of the License, or (at your option) any later version.
00013 
00014   This library is distributed in the hope that it will be useful,
00015   but WITHOUT ANY WARRANTY; without even the implied warranty of
00016   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017   Lesser General Public License for more details.
00018 
00019   You should have received a copy of the GNU Lesser General Public
00020   License along with this library; if not, write to the Free Software
00021   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00022 
00023   contact: julien_jorge@yahoo.fr
00024 */
00030 #include <claw/jpeg.hpp>
00031 #include <claw/jpeg_error_manager.hpp>
00032 
00033 #include <claw/exception.hpp>
00034 #include <claw/assert.hpp>
00035 
00036 /*----------------------------------------------------------------------------*/
00041 METHODDEF(void)
00042   claw__graphic__jpeg__source_manager__init_source(j_decompress_ptr cinfo)
00043 {
00044   // nothing to do
00045 } // claw__graphic__jpeg__source_manager__init_source()
00046 
00047 /*----------------------------------------------------------------------------*/
00052 METHODDEF(boolean)
00053   claw__graphic__jpeg__source_manager__fill_input_buffer(j_decompress_ptr cinfo)
00054 {
00055   claw::graphic::jpeg::reader::source_manager* self =
00056     (claw::graphic::jpeg::reader::source_manager*)cinfo->client_data;
00057 
00058   CLAW_PRECOND( &self->pub == cinfo->src );
00059 
00060   return self->fill_input_buffer();
00061 } // claw__graphic__jpeg__source_manager__fill_input_buffer()
00062 
00063 /*----------------------------------------------------------------------------*/
00069 METHODDEF(void)
00070   claw__graphic__jpeg__source_manager__skip_input_data(j_decompress_ptr cinfo,
00071                                                        long num_bytes)
00072 {
00073   claw::graphic::jpeg::reader::source_manager* self =
00074     (claw::graphic::jpeg::reader::source_manager*)cinfo->client_data;
00075 
00076   CLAW_PRECOND( &self->pub == cinfo->src );
00077 
00078   return self->skip_input_data(num_bytes);
00079 } // claw__graphic__jpeg__source_manager__skip_input_data()
00080 
00081 /*----------------------------------------------------------------------------*/
00086 METHODDEF(void)
00087   claw__graphic__jpeg__source_manager__term_source(j_decompress_ptr cinfo)
00088 {
00089   // nothing to do
00090 } // claw__graphic__jpeg__source_manager__term_source()
00091 
00092 /*----------------------------------------------------------------------------*/
00097 claw::graphic::jpeg::reader::source_manager::source_manager( std::istream& is )
00098   : m_input(is), m_buffer_size(1024), m_stream_position(0)
00099 {
00100   std::istream::pos_type pos = is.tellg();
00101 
00102   is.seekg( 0 , std::ios_base::end );
00103   m_stream_size = is.tellg() ;
00104 
00105   is.seekg( pos, std::ios_base::beg ) ;
00106 
00107   m_buffer = new JOCTET[m_buffer_size];
00108   pub.bytes_in_buffer = 0;
00109 } // jpeg::reader::source_manager::source_manager()
00110 
00111 /*----------------------------------------------------------------------------*/
00115 claw::graphic::jpeg::reader::source_manager::~source_manager()
00116 {
00117   delete[] m_buffer;
00118 } // jpeg::reader::source_manager::~source_manager()
00119 
00120 /*----------------------------------------------------------------------------*/
00124 boolean
00125 claw::graphic::jpeg::reader::source_manager::fill_input_buffer()
00126 {
00127   unsigned int n = std::min( m_buffer_size, m_stream_size - m_stream_position );
00128   m_input.read( (char*)m_buffer, n );
00129 
00130   pub.next_input_byte = m_buffer;
00131   pub.bytes_in_buffer = n;
00132 
00133   m_stream_position += n;
00134 
00135   if (m_input)
00136     return TRUE;
00137   else
00138     return FALSE;
00139 } // jpeg::reader::source_manager::fill_input_buffer()
00140 
00141 /*----------------------------------------------------------------------------*/
00146 void
00147 claw::graphic::jpeg::reader::source_manager::skip_input_data(long num_bytes)
00148 {
00149   CLAW_PRECOND(num_bytes >=0);
00150 
00151   if ( (size_t)num_bytes <= pub.bytes_in_buffer )
00152     {
00153       pub.next_input_byte += num_bytes;
00154       pub.bytes_in_buffer -= num_bytes;
00155     }
00156   else
00157     {
00158       num_bytes -= pub.bytes_in_buffer;
00159       
00160       long div = num_bytes / m_buffer_size;
00161       long rest = num_bytes % m_buffer_size;
00162 
00163       for (long i=0; i!=(div+1); ++i)
00164         fill_input_buffer();
00165 
00166       pub.next_input_byte += rest;
00167       pub.bytes_in_buffer -= rest;
00168     }
00169 } // jpeg::reader::source_manager::skip_input_data()
00170 
00171 
00172 
00173 
00174 /*----------------------------------------------------------------------------*/
00178 claw::graphic::rgba_pixel_8
00179 claw::graphic::jpeg::reader::RGB_to_pixel32::operator()
00180   ( const JSAMPLE* pixel ) const
00181 {
00182   rgba_pixel_8 result;
00183 
00184   result.components.alpha = 255;
00185   result.components.red = pixel[0];
00186   result.components.green = pixel[1];
00187   result.components.blue = pixel[2];
00188 
00189   return result;
00190 } // jpeg::reader::RGB_to_pixel32::operator()()
00191 
00192 /*----------------------------------------------------------------------------*/
00196 claw::graphic::rgba_pixel_8
00197 claw::graphic::jpeg::reader::grayscale_to_pixel32::operator()
00198   ( const JSAMPLE* pixel ) const
00199 {
00200   rgba_pixel_8 result;
00201 
00202   result.components.alpha = 255;
00203   result.components.red = pixel[0];
00204   result.components.green = pixel[0];
00205   result.components.blue = pixel[0];
00206 
00207   return result;
00208 } // jpeg::reader::grayscale_to_pixel32::operator()()
00209 
00210 
00211 
00212 
00213 /*----------------------------------------------------------------------------*/
00218 claw::graphic::jpeg::reader::reader( image& img )
00219   : m_image( img )
00220 {
00221 
00222 } // jpeg::reader::reader()
00223 
00224 /*----------------------------------------------------------------------------*/
00231 claw::graphic::jpeg::reader::reader( image& img, std::istream& f )
00232   : m_image( img )
00233 {
00234   load(f);
00235 } // jpeg::reader::reader()
00236 
00237 /*----------------------------------------------------------------------------*/
00242 void claw::graphic::jpeg::reader::load( std::istream& f )
00243 {
00244   CLAW_PRECOND( !!f );
00245 
00246   std::istream::pos_type init_pos = f.tellg();
00247 
00248   try
00249     {
00250       read_from_file(f);
00251     }
00252   catch(...)
00253     {
00254       f.clear();
00255       f.seekg( init_pos, std::ios_base::beg );
00256       throw;
00257     }
00258 } // jpeg::reader::load()
00259 
00260 /*----------------------------------------------------------------------------*/
00265 void claw::graphic::jpeg::reader::read_from_file( std::istream& f )
00266 {
00267   source_manager infile(f);
00268   jpeg_decompress_struct cinfo;
00269   error_manager jerr;
00270 
00271   cinfo.err = jpeg_std_error(&jerr.pub);
00272   
00273   if ( setjmp(jerr.setjmp_buffer) )
00274     throw CLAW_EXCEPTION(jerr.error_string);
00275 
00276   create_decompress_info( cinfo, infile );
00277   jerr.pub.error_exit = jpeg__error_manager__error_exit;
00278   
00279   try
00280     {
00281       decompress(f, cinfo);
00282       jpeg_destroy_decompress(&cinfo);
00283     }
00284   catch(...)
00285     {
00286       jpeg_destroy_decompress(&cinfo);
00287       throw;
00288     }
00289 } // jpeg::reader::read_from_file()
00290 
00291 /*----------------------------------------------------------------------------*/
00297 void claw::graphic::jpeg::reader::decompress
00298 ( std::istream& f, jpeg_decompress_struct& cinfo )
00299 {
00300   error_manager jerr;
00301   jpeg_error_mgr* jerr_saved = cinfo.err;
00302 
00303   cinfo.err = jpeg_std_error(&jerr.pub);
00304   jerr.pub.error_exit = jpeg__error_manager__error_exit;
00305 
00306   if ( setjmp(jerr.setjmp_buffer) )
00307     {
00308       jpeg_abort_decompress(&cinfo);
00309       throw CLAW_EXCEPTION(jerr.error_string);
00310     }
00311 
00312   jpeg_read_header(&cinfo, TRUE);
00313   jpeg_start_decompress( &cinfo );
00314 
00315   try
00316     {
00317       m_image.set_size( cinfo.image_width, cinfo.image_height );
00318 
00319       if ( cinfo.out_color_components == 3 )
00320         read_data( cinfo, RGB_to_pixel32() );
00321       else if ( cinfo.out_color_components == 1 )
00322         read_data( cinfo, grayscale_to_pixel32() );
00323       else
00324         throw CLAW_EXCEPTION( "invalid number of colors per channel" );
00325 
00326       jpeg_finish_decompress(&cinfo);
00327     }
00328   catch(...)
00329     {
00330       jpeg_abort_decompress(&cinfo);
00331       throw;
00332     }
00333 
00334   cinfo.err = jerr_saved;
00335 } // jpeg::reader::decompress()
00336 
00337 /*----------------------------------------------------------------------------*/
00343 void claw::graphic::jpeg::reader::create_decompress_info
00344 ( jpeg_decompress_struct& cinfo, source_manager& infile ) const
00345 {
00346   jpeg_create_decompress(&cinfo);
00347 
00348   cinfo.src = &infile.pub;
00349   cinfo.client_data = &infile;
00350 
00351   infile.pub.fill_input_buffer =
00352     claw__graphic__jpeg__source_manager__fill_input_buffer;
00353   infile.pub.skip_input_data =
00354     claw__graphic__jpeg__source_manager__skip_input_data;
00355   infile.pub.init_source = claw__graphic__jpeg__source_manager__init_source;
00356   infile.pub.resync_to_restart = jpeg_resync_to_restart;
00357   infile.pub.term_source = claw__graphic__jpeg__source_manager__term_source;
00358 } // jpeg::reader::create_decompress_info()

Generated on 9 Nov 2009 for CLAW Library (a C++ Library Absolutely Wonderful) by  doxygen 1.6.1