diff options
Diffstat (limited to 'chromium/third_party/angle/samples/angle/sample_util/tga_utils.cpp')
-rw-r--r-- | chromium/third_party/angle/samples/angle/sample_util/tga_utils.cpp | 122 |
1 files changed, 122 insertions, 0 deletions
diff --git a/chromium/third_party/angle/samples/angle/sample_util/tga_utils.cpp b/chromium/third_party/angle/samples/angle/sample_util/tga_utils.cpp new file mode 100644 index 00000000000..3e2d6e12c9f --- /dev/null +++ b/chromium/third_party/angle/samples/angle/sample_util/tga_utils.cpp @@ -0,0 +1,122 @@ +// +// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "tga_utils.h" + +#include <iostream> +#include <fstream> +#include <string> +#include <cstdint> + +TGAImage::TGAImage() + : data(0), width(0), height(0) +{ +} + +struct TGAHeader +{ + uint8_t idSize; + uint8_t mapType; + uint8_t imageType; + uint16_t paletteStart; + uint16_t paletteSize; + uint8_t paletteEntryDepth; + uint16_t x; + uint16_t y; + uint16_t width; + uint16_t height; + uint8_t colorDepth; + uint8_t descriptor; +}; + +#define INVERTED_BIT (1 << 5) + +template <typename dataType> +void readBinary(std::ifstream &stream, dataType &item) +{ + stream.read(reinterpret_cast<char *>(&item), sizeof(dataType)); +} + +template <typename dataType> +void readBinary(std::ifstream &stream, std::vector<dataType> &items) +{ + stream.read(reinterpret_cast<char *>(items.data()), sizeof(dataType) * items.size()); +} + +bool LoadTGAImageFromFile(const std::string &path, TGAImage *image) +{ + std::ifstream stream(path, std::ios::binary); + if (!stream) + { + std::cerr << "error opening tga file " << path << " for reading.\n"; + return false; + } + + TGAHeader header; + readBinary(stream, header.idSize); + readBinary(stream, header.mapType); + readBinary(stream, header.imageType); + readBinary(stream, header.paletteStart); + readBinary(stream, header.paletteSize); + readBinary(stream, header.paletteEntryDepth); + readBinary(stream, header.x); + readBinary(stream, header.y); + readBinary(stream, header.width); + readBinary(stream, header.height); + readBinary(stream, header.colorDepth); + readBinary(stream, header.descriptor); + + image->width = header.width; + image->height = header.height; + + size_t pixelComponentCount = header.colorDepth / CHAR_BIT; + std::vector<unsigned char> buffer(header.width * header.height * pixelComponentCount); + readBinary(stream, buffer); + + image->data.reserve(header.width * header.height); + + for (size_t y = 0; y < header.height; y++) + { + size_t rowIdx = ((header.descriptor & INVERTED_BIT) ? (header.height - 1 - y) : y) * header.width * pixelComponentCount; + for (size_t x = 0; x < header.width; x++) + { + size_t pixelIdx = rowIdx + x * pixelComponentCount; + + Byte4 pixel; + pixel[0] = (pixelComponentCount > 2) ? buffer[pixelIdx + 2] : 0; + pixel[2] = (pixelComponentCount > 0) ? buffer[pixelIdx + 0] : 0; + pixel[1] = (pixelComponentCount > 1) ? buffer[pixelIdx + 1] : 0; + pixel[3] = (pixelComponentCount > 3) ? buffer[pixelIdx + 3] : 255; + + image->data.push_back(pixel); + } + } + + std::cout << "loaded image " << path << ".\n"; + + return true; +} + +GLuint LoadTextureFromTGAImage(const TGAImage &image) +{ + if (image.width > 0 && image.height > 0) + { + GLuint texture; + glGenTextures(1, &texture); + glBindTexture(GL_TEXTURE_2D, texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, static_cast<GLsizei>(image.width), static_cast<GLsizei>(image.height), 0, + GL_RGBA, GL_UNSIGNED_BYTE, image.data.data()); + glGenerateMipmap(GL_TEXTURE_2D); + return texture; + } + else + { + return 0; + } +} |