46     m_monochrome_out(false)
 
   53     m_monochrome_out = monochrome_out ;
 
   58     return decodeFile( readType(path) , path , out , scale_to_fit ) ;
 
   63     return decodeFile( image_type , path , out , scale_to_fit ) ;
 
   73             file.open( path.
str().c_str() ) ;
 
   76             throw Error( 
"cannot open [" + path.
str() + 
"]" ) ;
 
   79     catch( std::exception & )
 
   81         if( do_throw ) throw ;
 
   88     G_DEBUG( 
"Gr::ImageDecoder::decodeFile: path=[" << path << 
"] type=[" << type_in << 
"]" ) ;
 
   90     int scale = scale_to_fit ? scale_to_fit(type_in) : m_scale ;
 
   92     if( type_in.
isJpeg() && jpegAvailable() )
 
   94         m_jpeg.setup( scale , m_monochrome_out ) ;
 
   95         m_jpeg.decode( out , path ) ;
 
   97     else if( type_in.
isPng() && pngAvailable() )
 
   99         m_png.setup( scale , m_monochrome_out ) ;
 
  100         m_png.decode( out , path ) ;
 
  102     else if( type_in.
isPnm() )
 
  104         m_pnm.setup( scale , m_monochrome_out ) ;
 
  105         m_pnm.decode( out , path ) ;
 
  109         throw Error( 
"invalid file format" , path.
str() ) ;
 
  111     return rawtype(out) ;
 
  116     return decodeBuffer( type_in , data.data() , data.size() , out , scale_to_fit ) ;
 
  121     return decodeBuffer( type_in , p , n , out , scale_to_fit ) ;
 
  126     G_DEBUG( 
"Gr::ImageDecoder::decodeBuffer: size=" << n << 
" type=[" << type_in << 
"]" ) ;
 
  128     int scale = scale_to_fit ? scale_to_fit(type_in) : m_scale ;
 
  130     if( type_in.
isJpeg() && jpegAvailable() )
 
  132         m_jpeg.setup( scale , m_monochrome_out ) ;
 
  133         m_jpeg.decode( out , p , n ) ;
 
  135     else if( type_in.
isPng() && pngAvailable() )
 
  137         m_png.setup( scale , m_monochrome_out ) ;
 
  138         m_png.decode( out , p , n ) ;
 
  140     else if( type_in.
isPnm() )
 
  142         m_pnm.setup( scale , m_monochrome_out ) ;
 
  143         m_pnm.decode( out , p , n ) ;
 
  145     else if( type_in.
isRaw() )
 
  148         ImageType type_out = 
ImageType::raw( type_in , scale , m_monochrome_out ) ;
 
  149         out.
resize( type_out.dx() , type_out.dy() , type_out.channels() ) ;
 
  150         out.
copyIn( p , n , type_in.
dx() , type_in.
dy() , type_in.
channels() , 
true , scale ) ;
 
  154         throw Error( 
"invalid format" ) ;
 
  156     return rawtype( out ) ;
 
  161     G_DEBUG( 
"Gr::ImageDecoder::decode: ImageBuffer type=[" << type_in << 
"]" ) ;
 
  163     int scale = scale_to_fit ? scale_to_fit(type_in) : m_scale ;
 
  165     if( type_in.
isJpeg() && jpegAvailable() )
 
  167         m_jpeg.setup( scale , m_monochrome_out ) ;
 
  168         m_jpeg.decode( out , image_buffer ) ;
 
  170     else if( type_in.
isPng() && pngAvailable() )
 
  172         m_png.setup( scale , m_monochrome_out ) ;
 
  173         m_png.decode( out , image_buffer ) ;
 
  175     else if( type_in.
isPnm() )
 
  177         m_pnm.setup( scale , m_monochrome_out ) ;
 
  178         m_pnm.decode( out , image_buffer ) ;
 
  180     else if( type_in.
isRaw() )
 
  185         out.
copyIn( image_buffer , type_in.
dx() , type_in.
dy() , type_in.
channels() , 
true , scale ) ;
 
  189         throw Error( 
"invalid format" ) ;
 
  191     return rawtype( out ) ;
 
  197     G_ASSERT( out_store.
type() == ImageData::Contiguous ) ;
 
  200     if( type_in.
isPnm() )
 
  201         pnm_info = 
PnmInfo( p , size_in ) ;
 
  204     if( type_in.
isJpeg() && jpegAvailable() )
 
  206         m_jpeg.setup( m_scale , m_monochrome_out ) ;
 
  207         m_jpeg.decode( out_store , p , size_in ) ;
 
  208         p = 
reinterpret_cast<char*
>( out_store.
p() ) ;
 
  209         type_out = rawtype( out_store ) ;
 
  211     else if( type_in.
isPng() && pngAvailable() )
 
  213         m_png.setup( m_scale , m_monochrome_out ) ;
 
  214         m_png.decode( out_store , p , size_in ) ;
 
  215         p = 
reinterpret_cast<char*
>( out_store.
p() ) ;
 
  216         type_out = rawtype( out_store ) ;
 
  218     else if( type_in.
isPnm() && pnm_info.binary8() && 
 
  219         ( m_scale > 1 || type_in.
channels() != (m_monochrome_out?1:type_in.
channels()) ) )
 
  222         type_out = 
ImageType::raw( type_in , m_scale , m_monochrome_out ) ;
 
  223         if( size_in <= pnm_info.offset() || (size_in-pnm_info.offset()) != type_out.
size() ) 
 
  224             throw Error( 
"invalid pnm size" ) ;
 
  225         std::memmove( p , p+pnm_info.offset() , size_in-pnm_info.offset() ) ;
 
  228         unsigned char * p_out = 
reinterpret_cast<unsigned char*
>(p) ;
 
  229         const unsigned char * p_in = p_out ;
 
  230         size_t dp_in = sizet( m_scale , type_in.
channels() ) ;
 
  231         for( 
int y = 0 ; y < type_in.
dy() ; y += m_scale )
 
  233             for( 
int x = 0 ; x < type_in.
dx() ; x += m_scale , p += dp_in )
 
  235                 if( m_monochrome_out && type_in.
channels() == 3 )
 
  237                 else if( m_monochrome_out )
 
  240                     { *p_out++ = p_in[0] ; *p_out++ = p_in[1] ; *p_out++ = p_in[2] ; }
 
  244     else if( type_in.
isPnm() && pnm_info.binary8() )
 
  247         type_out = 
ImageType::raw( type_in , m_scale , m_monochrome_out ) ;
 
  248         if( size_in <= pnm_info.offset() || (size_in-pnm_info.offset()) != type_out.
size() ) 
 
  249             throw Error( 
"invalid pnm size" ) ;
 
  250         std::memmove( p , p+pnm_info.offset() , size_in-pnm_info.offset() ) ;
 
  252     else if( type_in.
isPnm() )
 
  254         m_pnm.setup( m_scale , m_monochrome_out ) ;
 
  255         m_pnm.decode( out_store , p , size_in ) ;
 
  256         p = 
reinterpret_cast<char*
>( out_store.
p() ) ;
 
  257         type_out = rawtype( out_store ) ;
 
  259     else if( type_in.
isRaw() && (m_scale > 1 || type_in.
channels() != (m_monochrome_out?1:type_in.
channels()) ) )
 
  261         type_out = 
ImageType::raw( type_in , m_scale , m_monochrome_out ) ;
 
  262         unsigned char * p_out = 
reinterpret_cast<unsigned char*
>(p) ;
 
  263         const unsigned char * p_in = p_out ;
 
  264         size_t dp_in = sizet( m_scale , type_in.
channels() ) ;
 
  265         for( 
int y = 0 ; y < type_in.
dy() ; y += m_scale )
 
  267             for( 
int x = 0 ; x < type_in.
dx() ; x += m_scale , p += dp_in )
 
  269                 if( m_monochrome_out && type_in.
channels() == 3 )
 
  271                 else if( m_monochrome_out )
 
  274                     { *p_out++ = p_in[0] ; *p_out++ = p_in[1] ; *p_out++ = p_in[2] ; }
 
  278     else if( type_in.
isRaw() )
 
  284         throw Error( 
"invalid format" ) ;
 
  289 bool Gr::ImageDecoder::jpegAvailable()
 
  292         G_WARNING_ONCE( 
"Gr::ImageDecoder::jpegAvailable: no jpeg library built-in" ) ;
 
  296 bool Gr::ImageDecoder::pngAvailable()
 
  299         G_WARNING_ONCE( 
"Gr::ImageDecoder::jpegAvailable: no png library built-in" ) ;
 
  305 int Gr::ImageDecoder::ScaleToFit::operator()( 
const ImageType & type )
 const 
  312     G_ASSERT( ff >= 0 && dx > 0 && dy > 0 ) ;
 
  313     if( !type.valid() ) 
return 1 ;
 
  314     int image_dx = type.dx() ; 
if( ff > 0 ) image_dx -= (image_dx/ff) ;
 
  315     int image_dy = type.dy() ; 
if( ff > 0 ) image_dy -= (image_dy/ff) ;
 
  316     int scale_x = (image_dx+dx-1) / std::max(1,dx) ;
 
  317     int scale_y = (image_dy+dy-1) / std::max(1,dy) ;
 
  320         G_ASSERT( scaled(image_dx,scale_x) <= dx ) ;
 
  321         G_ASSERT( scaled(image_dy,scale_y) <= dy ) ;
 
  322         if( scale_x > 1 ) G_ASSERT( scaled(image_dx,scale_x-1) > dx ) ;
 
  323         if( scale_y > 1 ) G_ASSERT( scaled(image_dy,scale_y-1) > dy ) ;
 
  326     int result = std::max( scale_x , scale_y ) ;
 
  330 Gr::ImageDecoder::ScaleToFit::operator bool()
 const 
  332     const bool zero = dx <= 0 && dy <= 0 ;
 
std::string str() const 
Returns the path string. 
 
bool isRaw() const 
Returns true if a raw image type. 
 
int dx() const 
Returns the width. 
 
ImageType decodeInPlace(ImageType type_in, char *&p, size_t size_in, ImageData &store)
Decodes an image buffer with raw decoding done in-place. 
 
A holder for image data, having eight bits per sample and one or three channels. 
 
void setup(int scale, bool monochrome_out)
Sets the scale factor. 
 
void resize(int dx, int dy, int channels)
Resizes the image data. 
 
bool isJpeg() const 
Returns true if a jpeg image type. 
 
int channels() const 
Returns the number of channels. 
 
Type type() const 
Returns the contiguous/segmented enumeration. 
 
An encapsulation of image type, including width, height and number of channels, with support for a st...
 
A class which acquires the process's special privileges on construction and releases them on destruct...
 
Vectors ImageBuffer
An ImageBuffer is used to hold raw image data, typically in more than one chunk. 
 
static ImageType raw(int dx, int dy, int channels)
Factory function for a raw image type. 
 
size_t size() const 
Returns the product of dx, dy and channels. 
 
ImageDecoder()
Default constructor. 
 
static bool available()
Returns true if a jpeg library is available. 
 
bool isPng() const 
Returns true if a png image type. 
 
int dy() const 
Returns the image height. 
 
void copyIn(const char *data_in, size_t data_size_in, int dx_in, int dy_in, int channels_in, bool use_colourspace=false, int scale=1)
Copies the image in from a raw buffer, with channel-count adjustment and optional scaling...
 
int channels() const 
Returns the number of channels (zero, one or three). 
 
static ImageType readType(const G::Path &path, bool do_throw=true)
A convenience function to read a file's image type. 
 
unsigned char y_int(unsigned char r, unsigned char g, unsigned char b)
A fast conversion from rgb to y. 
 
const unsigned char * p() const 
Returns a const pointer to the image data, but throws if the data is not contiguous. 
 
int dx() const 
Returns the image width. 
 
ImageType decode(const G::Path &path_in, ImageData &out, const ScaleToFit &=ScaleToFit())
Decodes a file, with a scale-to-fit option. 
 
Describes scale-to-fit target dimensions. 
 
A structure holding portable-anymap metadata. 
 
int dy() const 
Returns the height. 
 
static bool available()
Returns true if the png library is available. 
 
A Path object represents a file system path. 
 
bool isPnm() const 
Returns true if a pnm image type.