📄 imagereader.cpp
字号:
#include <img/ImageReader.h>
#include <io/InputStream.h>
#include <string.h>
#include <stdint.h>
#include <assert.h>
#include <ctype.h>
#include <config.h>
using namespace io;
using namespace gr;
using namespace lang;
#define OPTIMIZE
namespace img
{
ImageReader::ImageReader( InputStream* in, FileFormat filefmt ) :
m_in( in ),
m_width( 0 ),
m_height( 0 ),
m_bitsPerPixel( 0 ),
m_pitch( 0 ),
m_surfaces( 0 ),
m_scanlinebuffer(),
m_fmt(),
m_palfmt(),
m_filefmt( filefmt ),
m_bottomUp( false )
{
m_scanlinebuffer.resize(1024);
switch ( m_filefmt )
{
//case FILEFORMAT_BMP: readHeader_bmp(); break;
case FILEFORMAT_TGA: readHeader_tga(); break;
//case FILEFORMAT_JPG: readHeader_jpg(); break;
default: INTERNAL_ERROR(); // throwError( IOException( Format("Unsupported image file format while reading {0}", m_in->toString()) ) );
}
}
ImageReader::~ImageReader()
{
}
bool ImageReader::nextSurface()
{
return m_surfaces-- > 0;
}
void ImageReader::readSurface( void* bits, int pitch, int w, int h, SurfaceFormat fmt,
const void* pal, SurfaceFormat palfmt )
{
assert( w == surfaceWidth() );
assert( h == surfaceHeight() );
switch ( m_filefmt )
{
//case FILEFORMAT_BMP: readScanlines( bits, pitch, w, h, fmt, pal, palfmt ); break;
case FILEFORMAT_TGA: readScanlines( bits, pitch, w, h, fmt, pal, palfmt ); break;
//case FILEFORMAT_JPG: readSurface_jpg( bits, pitch, w, h, fmt, pal, palfmt ); break;
default: INTERNAL_ERROR(); // throwError( IOException( Format("Unsupported image file format while reading {0}", m_in->toString()) ) );
}
}
int ImageReader::surfaces() const
{
return m_surfaces;
}
SurfaceFormat ImageReader::format() const
{
return m_fmt;
}
const void* ImageReader::paletteData() const
{
return &m_colormap[0][0];
}
SurfaceFormat ImageReader::paletteFormat() const
{
return m_palfmt;
}
int ImageReader::surfaceWidth() const
{
return m_width;
}
int ImageReader::surfaceHeight() const
{
return m_height;
}
ImageReader::FileFormat ImageReader::guessFileFormat( const char* )
{
return ImageReader::FILEFORMAT_TGA;
}
void ImageReader::readFully( io::InputStream* in, void* buf, int bytes )
{
if ( in->read(buf,bytes) != bytes )
INTERNAL_ERROR(); // throwError( IOException( Format("Failed to {0} bytes from {1}", bytes, in->toString()) ) );
}
void ImageReader::readColorMap( InputStream* in, int entrysize, int entries, uint8_t* colormap )
{
uint8_t colr[4];
for ( int i = 0 ; i < entries ; ++i )
{
memset( colr, 0, sizeof(colr) );
readFully( in, colr, entrysize );
colormap[i*4+0] = colr[2];
colormap[i*4+1] = colr[1];
colormap[i*4+2] = colr[0];
colormap[i*4+3] = colr[3];
}
}
uint16_t ImageReader::getUInt16LE( const void* data, int offset )
{
const uint8_t* bytes = reinterpret_cast<const uint8_t*>(data) + offset;
return uint16_t( ( unsigned(bytes[1]) << 8 ) + unsigned(bytes[0]) );
}
uint32_t ImageReader::getUInt32LE( const void* data, int offset )
{
const uint8_t* bytes = reinterpret_cast<const uint8_t*>(data) + offset;
return ( uint32_t(bytes[3]) << 24 ) + ( uint32_t(bytes[2]) << 16 ) + ( uint32_t(bytes[1]) << 8 ) + uint32_t(bytes[0]);
}
void ImageReader::readScanlines( void* bits, int pitch, int /*w*/, int /*h*/, SurfaceFormat fmt,
const void* pal, SurfaceFormat palfmt )
{
// make sure we have big enough scanline buffer,
// but use dynamic allocation only if absolutely necessary
if ( m_scanlinebuffer.size() < m_pitch )
{
m_scanlinebuffer.resize( m_pitch );
}
uint8_t* scanlinebuffer = m_scanlinebuffer.begin();
// read pixels
#ifdef OPTIMIZE
assert( fmt.type() == m_fmt.type() );
int j1 = m_height - 1;
uint8_t* dst = reinterpret_cast<uint8_t*>(bits) + j1*pitch;
#endif
for ( int j = 0 ; j < m_height ; j++ )
{
#ifdef OPTIMIZE
m_in->read( dst, m_pitch );
dst -= pitch;
#else // non-OPTIMIZE
switch ( m_filefmt )
{
case FILEFORMAT_BMP:
case FILEFORMAT_TGA:
readFully( m_in, scanlinebuffer, m_pitch );
break;
//case FILEFORMAT_JPG:
// readScanline_jpg( scanlinebuffer );
// break;
default:
INTERNAL_ERROR(); // throwError( IOException( Format("Unsupported image file format while reading {0}", m_in->toString()) ) );
}
int j1 = j;
if ( m_bottomUp )
j1 = m_height - j - 1;
uint8_t* dst = reinterpret_cast<uint8_t*>(bits) + j1*pitch;
fmt.copyPixels( dst, palfmt, pal, m_fmt, scanlinebuffer, m_palfmt, &m_colormap[0][0], m_width );
#endif
}
}
} // img
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -