Пример #1
0
	std::unique_ptr<uint8_t[]> DecodeTga(array_view<uint8_t> data) {

		if (data.size() < sizeof(TgaHeader)) {
			throw TempleException("Not enough data for TGA header");
		}

		auto header = reinterpret_cast<const TgaHeader*>(data.data());

		if (header->colorMapType != TgaColorMapType::TrueColor) {
			throw TempleException("Only true color TGA images are supported.");
		}

		if (header->dataType != TgaDataType::UncompressedRgb) {
			throw TempleException("Only uncompressed RGB TGA images are supported.");
		}

		if (header->bpp != 24 && header->bpp != 32) {
			throw TempleException("Only uncompressed RGB 24-bpp or 32-bpp TGA images are supported.");
		}

		auto result(std::make_unique<uint8_t[]>(header->width * header->height * 4));
		auto dest = result.get();

		// Points to the start of the TGA image data
		auto srcStart = data.data() + sizeof(TgaHeader) + header->imageIdLength;
		auto srcSize = data.size() - sizeof(TgaHeader) - header->imageIdLength;		

		if (header->bpp == 24) {
			auto srcPitch = header->width * 3;
			Expects((int) srcSize >= header->height * srcPitch);			
			for (int y = 0; y < header->height; ++y) {
				auto src = srcStart + (header->height - y - 1) * srcPitch;
				for (int x = 0; x < header->width; ++x) {
					*dest++ = *src++;
					*dest++ = *src++;
					*dest++ = *src++;
					*dest++ = 0xFF; // Fixed alpha
				}
			}
		} else {
			auto srcPitch = header->width * 4;
			Expects((int) srcSize >= header->height * srcPitch);
			for (int y = 0; y < header->height; ++y) {
				auto src = srcStart + (header->height - y - 1) * srcPitch;
				for (int x = 0; x < header->width; ++x) {
					*dest++ = *src++;
					*dest++ = *src++;
					*dest++ = *src++;
					*dest++ = *src++;
				}
			}
		}

		return result;
	}
Пример #2
0
	bool DetectTga(array_view<uint8_t> data, ImageFileInfo& info) {

		if (data.size() < sizeof(TgaHeader)) {
			return false;
		}

		auto header = reinterpret_cast<const TgaHeader*>(data.data());

		if (header->colorMapType != TgaColorMapType::TrueColor) {
			return false; // We don't supported index TGA
		}

		if (header->dataType != TgaDataType::UncompressedRgb) {
			return false; // We only support uncompressed RGB
		}

		if (header->bpp != 24 && header->bpp != 32) {
			return false; // We only support 24 or 32 bit TGAs
		}

		info.width = header->width;
		info.height = header->height;
		info.hasAlpha = (header->bpp == 32);
		info.format = ImageFileFormat::TGA;
		return true;

	}
Пример #3
0
    bool operator == (const array_view & other) const noexcept
    {
        // Pointers to same memory (or both null).
        if (data() == other.data())
        {
            return true;
        }

        // Different sizes, whole sequence can't be identical.
        if (size() != other.size())
        {
            return false;
        }

        // Compare each element:
        return std::equal(begin(), end(), other.begin());
    }
Пример #4
0
wal_bitmap xtk::wal_decode (const array_view<std::uint8_t>& data, const array_view<bitmap::value_type>& colormap) {
    const auto& header = *(const wal_header*)data.data ();
    
    auto _bitmap = wal_bitmap {
        make_bitmap_level (data, colormap, 0, header),
        make_bitmap_level (data, colormap, 1, header),
        make_bitmap_level (data, colormap, 2, header),
        make_bitmap_level (data, colormap, 3, header),
        std::string (header.name,
            strnlen (header.name,
                sizeof (header.name))),
        std::string (header.next_name,
            strnlen (header.next_name,
                sizeof (header.next_name)))
    };
    
    return std::move (_bitmap);
}
Пример #5
0
 array_view(array_view<value_type, OtherLength> other)
     : Length(other.length())
     , m_data(other.data())
 {
 }
Пример #6
0
 bool operator > (const array_view & other) const noexcept
 {
     return data() > other.data();
 }
Пример #7
0
 array_view(array_view<ConvertibleType> other) noexcept
     : m_pointer{ other.data() }
     , m_size_in_items{ other.size() }
 { }
Пример #8
0
bitmap xtk::pcx_decode (const array_view<std::uint8_t>& data) {

    static_assert (sizeof (pcx_header) == 128, "Header length incorrect");

    const auto& header = *(const pcx_header*)data.data();
    
    auto width  = header.xmax - header.xmin + 1;
    auto height = header.ymax - header.ymin + 1;
    
    __xtk_assert (std::invalid_argument, header.vendor_id == 0x0A && header.version >= 5);
    
    xtk::Debug::log(
        "load_pcx: \n"
        "\tversion = %d\n"
        "\tbits_per_pixel = %d\n"
        "\tcolor_planes = %d\n"
        "\twidth = %u\n"
        "\theight = %u\n"
        ,
        header.version,
        header.bits_per_pixel,
        header.color_planes,
        width,
        height
    );
    
    __xtk_assert(std::invalid_argument,
        header.bits_per_pixel == 8 &&
        header.color_planes == 0);
    
    auto buffer = std::make_unique<bitmap::value_type []> (width*height);
    
    auto stream = array_view<const std::uint8_t> {data.begin() + sizeof (header), data.end()};

    auto next_pixel = 0u;
    auto next_sbyte = stream.begin ();
        
    auto palette = xtk::array_view<glm::tvec3<std::uint8_t>> {
        (const glm::tvec3<std::uint8_t> *)data.end () - 256,
        (const glm::tvec3<std::uint8_t> *)data.end ()
    };
    
    while (next_sbyte < stream.end ()) {
        auto rle = *next_sbyte;
        
        ++next_sbyte;
        
        if (rle >= 0xc0) {
            rle &= 0x3f;
            auto pixel = bitmap::value_type (palette [*next_sbyte], 255);
            ++next_sbyte;
            for (auto j = 0; j < rle; ++j) {
                buffer [next_pixel] = pixel;
                ++next_pixel;
                __xtk_assert (std::overflow_error, next_pixel <= width*height);
            }
        }
        else {
            buffer [next_pixel] = bitmap::value_type (palette [rle], 255);
            ++next_pixel;
            __xtk_assert (std::overflow_error, next_pixel <= width*height);
        }
        
        if (next_pixel >= width*height) {
            break;
        }
    }
    
    __xtk_assert (std::invalid_argument, next_pixel == width*height);
    
    return bitmap (std::move (buffer), width, height);
}
Пример #9
0
void
DeepData::init (int npix, int nchan,
                array_view<const TypeDesc> channeltypes,
                array_view<const std::string> channelnames)
{
    clear ();
    m_npixels = npix;
    m_nchannels = nchan;
    ASSERT (channeltypes.size() >= 1);
    if (! m_impl)
        m_impl = new Impl;
    if (int(channeltypes.size()) >= nchan) {
        m_impl->m_channeltypes.assign (channeltypes.data(), channeltypes.data()+nchan);
    } else {
        m_impl->m_channeltypes.clear ();
        m_impl->m_channeltypes.resize (m_nchannels, channeltypes[0]);
    }
    m_impl->m_channelsizes.resize (m_nchannels);
    m_impl->m_channeloffsets.resize (m_nchannels);
    m_impl->m_channelnames.resize (m_nchannels);
    m_impl->m_myalphachannel.resize (m_nchannels, -1);
    m_impl->m_samplesize = 0;
    m_impl->m_nsamples.resize (m_npixels, 0);
    m_impl->m_capacity.resize (m_npixels, 0);
    m_impl->m_cumcapacity.resize (m_npixels, 0);

    // Channel name hunt
    // First, find Z, Zback, A
    for (int c = 0; c < m_nchannels; ++c) {
        size_t size = m_impl->m_channeltypes[c].size();
        m_impl->m_channelsizes[c] = size;
        m_impl->m_channeloffsets[c] = m_impl->m_samplesize;
        m_impl->m_samplesize += size;
        m_impl->m_channelnames[c] = channelnames[c];
        if (m_impl->m_z_channel < 0 && is_or_endswithdot (channelnames[c], "Z"))
            m_impl->m_z_channel = c;
        else if (m_impl->m_zback_channel < 0 && is_or_endswithdot (channelnames[c], "Zback"))
            m_impl->m_zback_channel = c;
        else if (m_impl->m_alpha_channel < 0 && is_or_endswithdot (channelnames[c], "A"))
            m_impl->m_alpha_channel = c;
        else if (m_impl->m_alpha_channel < 0 && is_or_endswithdot (channelnames[c], "Alpha"))
            m_impl->m_alpha_channel = c;
        else if (m_impl->m_AR_channel < 0 && is_or_endswithdot (channelnames[c], "AR"))
            m_impl->m_AR_channel = c;
        else if (m_impl->m_AG_channel < 0 && is_or_endswithdot (channelnames[c], "AG"))
            m_impl->m_AG_channel = c;
        else if (m_impl->m_AB_channel < 0 && is_or_endswithdot (channelnames[c], "AB"))
            m_impl->m_AB_channel = c;
    }
    // Now try to find which alpha corresponds to each channel
    for (int c = 0; c < m_nchannels; ++c) {
        // Skip non-color channels
        if (c == m_impl->m_z_channel || c == m_impl->m_zback_channel ||
            m_impl->m_channeltypes[c] == TypeDesc::UINT32)
            continue;
        string_view name (channelnames[c]);
        // Alpha channels are their own alpha
        if (is_or_endswithdot (name, "A")  || is_or_endswithdot (name, "AR") ||
            is_or_endswithdot (name, "AG") || is_or_endswithdot (name, "AB") ||
            is_or_endswithdot (name, "Alpha")) {
            m_impl->m_myalphachannel[c] = c;
            continue;
        }
        // For anything else, try to find its channel
        string_view prefix = name, suffix = name;
        size_t dot = name.find_last_of ('.');
        if (dot == string_view::npos) { // No dot
            prefix.clear ();
        } else { // dot
            prefix = prefix.substr (0, dot+1);
            suffix = suffix.substr (dot+1);
        }
        std::string targetalpha = std::string(prefix) + "A" + std::string(suffix);
        for (int i = 0; i < m_nchannels; ++i) {
            if (Strutil::iequals (m_impl->m_channelnames[i], targetalpha)) {
                m_impl->m_myalphachannel[c] = i;
                break;
            }
        }
        if (m_impl->m_myalphachannel[c] < 0)
            m_impl->m_myalphachannel[c] = m_impl->m_alpha_channel;
    }
}