Source

infoh503_starterkit / infoh503_starterkit / TGAFile.cpp

Full commit
#include "TGAFile.hpp"
#include <cstring>
#include <exception>
#include <cassert>

//-----------------------------------------------------------------------------
static unsigned short to_short(unsigned char *bytes)
{
    return bytes[0] | ((char)bytes[1] << 8);
}
//-----------------------------------------------------------------------------
TGAFile::TGAFile()
    :mWidth(0)
    ,mHeight(0)
    ,mBPP(0)
    ,mPixelData(NULL)
{

}
//-----------------------------------------------------------------------------
TGAFile::~TGAFile()
{
    delete[] mPixelData;
}
//-----------------------------------------------------------------------------
TGAFile::RGBPixel TGAFile::getPixel(unsigned short i, unsigned short j) const
{
    assert(i<mWidth && j < mHeight);
    TGAFile::RGBPixel out;

    const int nChannels = mBPP / 8;

    out.r = mPixelData[j*mWidth*nChannels + i];
    out.g = mPixelData[j*mWidth*nChannels + i + 1];
    out.b = mPixelData[j*mWidth*nChannels + i + 2];

    return out;
}
//-----------------------------------------------------------------------------
TGAFile::RGBPixel TGAFile::getPixel(unsigned int index) const
{
    TGAFile::RGBPixel out;
    assert(index < mWidth*mHeight);
    
    const int nChannels = mBPP / 8;

    out.r = mPixelData[index * nChannels + 2];
    out.g = mPixelData[index * nChannels + 1];
    out.b = mPixelData[index * nChannels];

    return out;
}
//-----------------------------------------------------------------------------
void TGAFile::readFromFile(const std::string &_filename)
{
    std::ifstream filestream(_filename.c_str(), std::ios::binary);
                  
    if(filestream.is_open())
    {
        _readHeaderDataFromStream(filestream);
        _readPixelDataFromStream(filestream);
        filestream.close();
    }
    else
        throw std::exception("[TGAFile::readFromFile()] could not open tga file");
}
//-----------------------------------------------------------------------------
void TGAFile::_readHeaderDataFromStream(std::ifstream&_inputstream)
{
    unsigned int headerLength = sizeof(struct tga_header);

    char *headerData = new char[headerLength];
    _inputstream.read(headerData, headerLength);
    memcpy(&mHeader, headerData, headerLength);
    delete[] headerData;

    _checkHeaderData();

    mWidth = to_short(mHeader.width);
    mHeight = to_short(mHeader.height);
    mBPP = (unsigned short) mHeader.bits_per_pixel;
}
//-----------------------------------------------------------------------------
void TGAFile::_readPixelDataFromStream(std::ifstream&_inputstream)
{
    int pixels_size = mWidth * mHeight * mBPP/8;
    mPixelData = new char[pixels_size];
    _inputstream.read(mPixelData, pixels_size);   
}
//-----------------------------------------------------------------------------
void TGAFile::_checkHeaderData()
{
    if (mHeader.data_type_code != 2 || mHeader.bits_per_pixel != 24)
        throw std::exception("input file is not an uncompressed RGB tga file");
}
//-----------------------------------------------------------------------------