Commit d830412a authored by Davis King's avatar Davis King

Added a class for reading JPEG image files.

--HG--
extra : convert_revision : svn%3Afdd8eb12-d10e-0410-9acb-85c331704f74/trunk%403855
parent c27bad2f
......@@ -55,6 +55,8 @@ set (DLIB_USE_LAPACK_STR
"Disable this if you don't want to use a LAPACK library" )
set (DLIB_LINK_WITH_LIBPNG_STR
"Disable this if you don't want to link against libpng" )
set (DLIB_LINK_WITH_LIBJPEG_STR
"Disable this if you don't want to link against libjpeg" )
option(DLIB_ISO_CPP_ONLY ${DLIB_ISO_CPP_ONLY_STR} OFF)
option(DLIB_NO_GUI_SUPPORT ${DLIB_NO_GUI_SUPPORT_STR} OFF)
......@@ -63,6 +65,7 @@ option(DLIB_ENABLE_ASSERTS ${DLIB_ENABLE_ASSERTS_STR} OFF)
option(DLIB_USE_BLAS ${DLIB_USE_BLAS_STR} ON)
option(DLIB_USE_LAPACK ${DLIB_USE_LAPACK_STR} ON)
option(DLIB_LINK_WITH_LIBPNG ${DLIB_LINK_WITH_LIBPNG_STR} ON)
option(DLIB_LINK_WITH_LIBJPEG ${DLIB_LINK_WITH_LIBJPEG_STR} ON)
add_library(dlib STATIC all/source.cpp )
......@@ -143,13 +146,24 @@ if (NOT DLIB_ISO_CPP_ONLY)
set(PNG_FIND_QUIETLY ON)
include(FindPNG)
if (PNG_FOUND)
include_directories(${PNG_PNG_INCLUDE_DIR})
include_directories(${PNG_INCLUDE_DIR})
set (dlib_needed_libraries ${dlib_needed_libraries} ${PNG_LIBRARY})
else()
set(DLIB_LINK_WITH_LIBPNG OFF CACHE STRING ${DLIB_LINK_WITH_LIBPNG_STR} FORCE )
endif()
endif()
if (DLIB_LINK_WITH_LIBJPEG)
# try to find libjpeg
include(FindJPEG)
if (JPEG_FOUND)
include_directories(${JPEG_INCLUDE_DIR})
set (dlib_needed_libraries ${dlib_needed_libraries} ${JPEG_LIBRARY})
else()
set(DLIB_LINK_WITH_LIBJPEG OFF CACHE STRING ${DLIB_LINK_WITH_LIBJPEG_STR} FORCE )
endif()
endif()
if (DLIB_USE_BLAS OR DLIB_USE_LAPACK)
# Try to find BLAS and LAPACK
......@@ -190,6 +204,12 @@ else()
remove_global_define(DLIB_PNG_SUPPORT)
endif()
if (DLIB_LINK_WITH_LIBJPEG)
add_global_define(DLIB_JPEG_SUPPORT)
else()
remove_global_define(DLIB_JPEG_SUPPORT)
endif()
if (DLIB_USE_BLAS AND blas_found)
add_global_define(DLIB_USE_BLAS)
......
......@@ -49,6 +49,10 @@
#include "../image_loader/png_loader.cpp"
#endif
#ifdef DLIB_JPEG_SUPPORT
#include "../image_loader/jpeg_loader.cpp"
#endif
#ifndef DLIB_NO_GUI_SUPPORT
#include "../gui_widgets/fonts.cpp"
......
......@@ -5,6 +5,7 @@
#include "image_loader/image_loader.h"
#include "image_loader/png_loader.h"
#include "image_loader/jpeg_loader.h"
#include "image_saver/image_saver.h"
#endif // DLIB_IMAGe_IO_
......
// Copyright (C) 2008 Davis E. King (davis@dlib.net), Nils Labugt
// License: Boost Software License See LICENSE.txt for the full license.
#ifndef DLIB_JPEG_LOADER_CPp_
#define DLIB_JPEG_LOADER_CPp_
// only do anything with this file if DLIB_JPEG_SUPPORT is defined
#ifdef DLIB_JPEG_SUPPORT
#include "../array2d.h"
#include "../pixel.h"
#include "../dir_nav.h"
#include "jpeg_loader.h"
#include <stdio.h>
#include <jpeglib.h>
#include <sstream>
#include <setjmp.h>
namespace dlib
{
// ----------------------------------------------------------------------------------------
jpeg_loader::
jpeg_loader( const char* filename ) : height_( 0 ), width_( 0 ), output_components_(0)
{
read_image( filename );
}
// ----------------------------------------------------------------------------------------
jpeg_loader::
jpeg_loader( const std::string& filename ) : height_( 0 ), width_( 0 ), output_components_(0)
{
read_image( filename.c_str() );
}
// ----------------------------------------------------------------------------------------
jpeg_loader::
jpeg_loader( const dlib::file& f ) : height_( 0 ), width_( 0 ), output_components_(0)
{
read_image( f.full_name().c_str() );
}
// ----------------------------------------------------------------------------------------
bool jpeg_loader::is_gray() const
{
return (output_components_ == 1);
}
// ----------------------------------------------------------------------------------------
bool jpeg_loader::is_rgb() const
{
return (output_components_ == 3);
}
// ----------------------------------------------------------------------------------------
struct jpeg_loader_error_mgr
{
jpeg_error_mgr pub; /* "public" fields */
jmp_buf setjmp_buffer; /* for return to caller */
};
void jpeg_loader_error_exit (j_common_ptr cinfo)
{
/* cinfo->err really points to a jpeg_loader_error_mgr struct, so coerce pointer */
jpeg_loader_error_mgr* myerr = (jpeg_loader_error_mgr*) cinfo->err;
/* Return control to the setjmp point */
longjmp(myerr->setjmp_buffer, 1);
}
// ----------------------------------------------------------------------------------------
void jpeg_loader::read_image( const char* filename )
{
if ( filename == NULL )
{
throw image_load_error("jpeg_loader: invalid filename, it is NULL");
}
FILE *fp = fopen( filename, "rb" );
if ( !fp )
{
throw image_load_error(std::string("jpeg_loader: unable to open file ") + filename);
}
jpeg_decompress_struct cinfo;
jpeg_loader_error_mgr jerr;
cinfo.err = jpeg_std_error(&jerr.pub);
jerr.pub.error_exit = jpeg_loader_error_exit;
/* Establish the setjmp return context for my_error_exit to use. */
if (setjmp(jerr.setjmp_buffer))
{
/* If we get here, the JPEG code has signaled an error.
* We need to clean up the JPEG object, close the input file, and return.
*/
jpeg_destroy_decompress(&cinfo);
fclose(fp);
throw image_load_error(std::string("jpeg_loader: error while reading ") + filename);
}
jpeg_create_decompress(&cinfo);
jpeg_stdio_src(&cinfo, fp);
jpeg_read_header(&cinfo, TRUE);
jpeg_start_decompress(&cinfo);
height_ = cinfo.output_height;
width_ = cinfo.output_width;
output_components_ = cinfo.output_components;
if (output_components_ != 1 &&
output_components_ != 3)
{
fclose( fp );
jpeg_destroy_decompress(&cinfo);
std::ostringstream sout;
sout << "jpeg_loader: Unsupported number of colors (" << output_components_ << ") in file " << filename;
throw image_load_error(sout.str());
}
std::vector<unsigned char*> rows;
rows.resize(height_);
// size the image buffer
data.resize(height_*width_*output_components_);
// setup pointers to each row
for (unsigned long i = 0; i < rows.size(); ++i)
rows[i] = &data[i*width_*output_components_];
// read the data into the buffer
while (cinfo.output_scanline < cinfo.output_height)
{
jpeg_read_scanlines(&cinfo, &rows[cinfo.output_scanline], 100);
}
jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);
fclose( fp );
}
// ----------------------------------------------------------------------------------------
}
#endif // DLIB_JPEG_SUPPORT
#endif // DLIB_JPEG_LOADER_CPp_
// Copyright (C) 2008 Davis E. King (davis@dlib.net), Nils Labugt
// License: Boost Software License See LICENSE.txt for the full license.
#ifndef DLIB_JPEG_IMPORT
#define DLIB_JPEG_IMPORT
#include "jpeg_loader_abstract.h"
#include "../smart_pointers.h"
#include "image_loader.h"
#include "../pixel.h"
#include "../dir_nav.h"
#include <vector>
namespace dlib
{
class jpeg_loader : noncopyable
{
public:
jpeg_loader( const char* filename );
jpeg_loader( const std::string& filename );
jpeg_loader( const dlib::file& f );
bool is_gray() const;
bool is_rgb() const;
template<typename T>
void get_image( T& t) const
{
#ifndef DLIB_JPEG_SUPPORT
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
You are getting this error because you are trying to use the jpeg_loader
object but you haven't defined DLIB_JPEG_SUPPORT. You must do so to use
this object. You must also make sure you set your build environment
to link against the libjpeg library.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
COMPILE_TIME_ASSERT(sizeof(T) == 0);
#endif
t.set_size( height_, width_ );
for ( unsigned n = 0; n < height_;n++ )
{
const unsigned char* v = get_row( n );
for ( unsigned m = 0; m < width_;m++ )
{
if ( is_gray() )
{
unsigned char p = v[m];
assign_pixel( t[n][m], p );
}
else // if ( is_rgb() )
{
rgb_pixel p;
p.red = v[m*3];
p.green = v[m*3+1];
p.blue = v[m*3+2];
assign_pixel( t[n][m], p );
}
}
}
}
private:
const unsigned char* get_row( unsigned long i ) const
{
return &data[i*width_*output_components_];
}
void read_image( const char* filename );
unsigned long height_;
unsigned long width_;
unsigned long output_components_;
std::vector<unsigned char> data;
};
}
#ifdef NO_MAKEFILE
#include "jpeg_loader.cpp"
#endif
#endif // DLIB_JPEG_IMPORT
// Copyright (C) 2008 Davis E. King (davis@dlib.net), Nils Labugt
// License: Boost Software License See LICENSE.txt for the full license.
#undef DLIB_JPEG_IMPORT_ABSTRACT
#ifdef DLIB_JPEG_IMPORT_ABSTRACT
#include "image_loader_abstract.h"
#include "../algs.h"
#include "../pixel.h"
#include "../dir_nav.h"
namespace dlib
{
class jpeg_loader : noncopyable
{
/*!
INITIAL VALUE
Defined by the constructors
WHAT THIS OBJECT REPRESENTS
This object represents a class capable of loading JPEG image files.
Once an instance of it is created to contain a JPEG file from
disk you can obtain the image stored in it via get_image().
!*/
public:
jpeg_loader(
const char* filename
);
/*!
ensures
- loads the JPEG file with the given file name into this object
throws
- std::bad_alloc
- image_load_error
This exception is thrown if there is some error that prevents
us from loading the given JPEG file.
!*/
jpeg_loader(
const std::string& filename
);
/*!
ensures
- loads the JPEG file with the given file name into this object
throws
- std::bad_alloc
- image_load_error
This exception is thrown if there is some error that prevents
us from loading the given JPEG file.
!*/
jpeg_loader(
const dlib::file& f
);
/*!
ensures
- loads the JPEG file with the given file name into this object
throws
- std::bad_alloc
- image_load_error
This exception is thrown if there is some error that prevents
us from loading the given JPEG file.
!*/
~jpeg_loader(
);
/*!
ensures
- all resources associated with *this has been released
!*/
bool is_gray(
) const;
/*!
ensures
- if (this object contains a grayscale image) then
- returns true
- else
- returns false
!*/
bool is_rgb(
) const;
/*!
ensures
- if (this object contains a 3 channel RGB image) then
- returns true
- else
- returns false
!*/
template<
typename image_type
>
void get_image(
image_type& img
) const;
/*!
requires
- image_type == is an implementation of array2d/array2d_kernel_abstract.h
- pixel_traits<typename image_type::type> is defined
ensures
- loads the JPEG image stored in this object into img
!*/
};
}
#endif // DLIB_JPEG_IMPORT_ABSTRACT
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment