<commit_before>#include "TGATexture.h"
#include <fstream>
#include <vector>
#include <algorithm>

// all possible image types
// described in TGA format specification
enum class tga_image_type : uint8_t
{
    none         = 0,  // no image data
    colormap     = 1,  // uncompressed, colormap
    bgr          = 2,  // uncompressed, bgr
    mono         = 3,  // uncompressed, black-white image
    colormap_rle = 9,  // compressed, colormap
    bgr_rle      = 10, // compressed, bgr
    mono_rle     = 11  // compressed, black-white image
};

TGATexture::TGATexture()
    :_texture(), _textureView()
{
    memset(&_textureInfo, 0, sizeof(_textureInfo));
}

void TGATexture::load(const std::string& filename, ID3D11Device* device)
{
    // in case if texture exists
    // we need to release all resources
    _texture.reset();
    _textureView.reset();

    std::ifstream stream(filename, std::ios_base::beg | std::ios_base::binary);
    stream.exceptions(std::ios_base::failbit | std::ios_base::badbit | std::ios_base::eofbit);

    // reading tga image header
    struct 
    {
        uint8_t data1[2];
        tga_image_type tga_type;
        uint8_t data2[5];
        // 0,0 point for origin x,y
        // is bottom left
        uint16_t x_origin;
        uint16_t y_origin;
        uint16_t width;
        uint16_t height;
        uint8_t bpp;
        uint8_t data3;
    } img_header;
    stream.read(reinterpret_cast<char*>(&img_header), sizeof(img_header));

    if ((img_header.bpp != sizeof(uint32_t) * 8)     || // image should be 32 bpp
        (img_header.tga_type != tga_image_type::bgr))  // image shouldn't be compressed with RLE
    {
        stream.setstate(std::ios_base::failbit);
    }

    _textureInfo.width = img_header.width;
    _textureInfo.height = img_header.height;
    _textureInfo.bpp = img_header.bpp;

    size_t imgSize = img_header.height * img_header.width;
    std::vector<uint32_t> tmpData(imgSize);
    tmpData.shrink_to_fit();
    stream.read(reinterpret_cast<char*>(tmpData.data()), imgSize * sizeof(uint32_t));
    stream.close();
<commit_msg>Targa RLE is now supported<commit_after>#include "TGATexture.h"
#include <fstream>
#include <vector>
#include <algorithm>

// all possible image types
// described in TGA format specification
enum class tga_image_type : uint8_t
{
    none         = 0,  // no image data
    colormap     = 1,  // uncompressed, colormap
    bgr          = 2,  // uncompressed, bgr
    mono         = 3,  // uncompressed, black-white image
    colormap_rle = 9,  // compressed, colormap
    bgr_rle      = 10, // compressed, bgr
    mono_rle     = 11  // compressed, black-white image
};

namespace ifstream_helpers
{
    template<typename T>
    inline void read(std::ifstream& stream, T* data, const size_t& count = 1)
    {
        stream.read(reinterpret_cast<char*>(data), sizeof(T) * count);
    }

    template<typename T>
    inline void read(std::ifstream& stream, T& data, const size_t& count = 1)
    {
        stream.read(reinterpret_cast<char*>(&data), sizeof(T) * count);
    }
}

// TGATexture class
TGATexture::TGATexture()
    :_texture(), _textureView()
{
    memset(&_textureInfo, 0, sizeof(_textureInfo));
}

void TGATexture::load(const std::string& filename, ID3D11Device* device)
{
    // in case if texture exists
    // we need to release all resources
    _texture.reset();
    _textureView.reset();

    std::ifstream stream(filename, std::ios_base::beg | std::ios_base::binary);
    stream.exceptions(std::ios_base::failbit | std::ios_base::badbit | std::ios_base::eofbit);

    // reading tga image header
    struct 
    {
        uint8_t data1[2];
        tga_image_type tga_type;
        uint8_t data2[5];
        // 0,0 point for origin x,y
        // is bottom left
        uint16_t x_origin;
        uint16_t y_origin;
        uint16_t width;
        uint16_t height;
        uint8_t bpp;
        uint8_t data3;
    } img_header;
    ifstream_helpers::read(stream, img_header);

    if (img_header.bpp != sizeof(uint32_t) * 8) // image should be 32 bpp
    {
        stream.setstate(std::ios_base::failbit);
    }

    _textureInfo.width = img_header.width;
    _textureInfo.height = img_header.height;
    _textureInfo.bpp = img_header.bpp;

    size_t imgSize = img_header.height * img_header.width;
    std::vector<uint32_t> tmpData(imgSize);
    tmpData.shrink_to_fit();
    if (img_header.tga_type == tga_image_type::bgr)
    {
        ifstream_helpers::read(stream, tmpData.data(), imgSize * sizeof(uint32_t));
    }
    else if (img_header.tga_type == tga_image_type::bgr_rle)
    {
        size_t loadedCount = 0;
        uint8_t tmpByte;

        while(loadedCount < tmpData.size())
        {
            ifstream_helpers::read(stream, tmpByte);
            size_t pointCount = (tmpByte & ~0x80) + 1;
            if (tmpByte & 0x80) // RLE packet
            {
                uint32_t tmpPacket;
                ifstream_helpers::read(stream, tmpPacket);
                std::fill_n(tmpData.begin() + loadedCount, pointCount, tmpPacket);
            }
            else // RAW packet
            {
                for(size_t i = 0; i < pointCount; ++i)
                {
                    ifstream_helpers::read(stream, tmpData[loadedCount + i]);
                }
            }
            loadedCount += pointCount;
        }
    }
    else // unsupported format
    {
        stream.setstate(std::ios_base::failbit);
    }
    stream.close();

{'fraction_non_alphanumeric': 0.1182933528657755, 'fraction_numerical': 0.01794543123969969, 'mean_word_length': 2.5012820512820513, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7105924', 'n_tokens_mistral': 1918, 'n_tokens_neox': 1817, 'n_words': 389}