Home | History | Annotate | Download | only in sample_util
      1 //
      2 // Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
      3 // Use of this source code is governed by a BSD-style license that can be
      4 // found in the LICENSE file.
      5 //
      6 
      7 #include "tga_utils.h"
      8 
      9 #include <iostream>
     10 #include <fstream>
     11 #include <string>
     12 #include <cstdint>
     13 
     14 TGAImage::TGAImage()
     15     : data(0), width(0), height(0)
     16 {
     17 }
     18 
     19 struct TGAHeader
     20 {
     21     uint8_t idSize;
     22     uint8_t mapType;
     23     uint8_t imageType;
     24     uint16_t paletteStart;
     25     uint16_t paletteSize;
     26     uint8_t paletteEntryDepth;
     27     uint16_t x;
     28     uint16_t y;
     29     uint16_t width;
     30     uint16_t height;
     31     uint8_t colorDepth;
     32     uint8_t descriptor;
     33 };
     34 
     35 #define INVERTED_BIT (1 << 5)
     36 
     37 template <typename dataType>
     38 void readBinary(std::ifstream &stream, dataType &item)
     39 {
     40     stream.read(reinterpret_cast<char *>(&item), sizeof(dataType));
     41 }
     42 
     43 template <typename dataType>
     44 void readBinary(std::ifstream &stream, std::vector<dataType> &items)
     45 {
     46     stream.read(reinterpret_cast<char *>(items.data()), sizeof(dataType) * items.size());
     47 }
     48 
     49 bool LoadTGAImageFromFile(const std::string &path, TGAImage *image)
     50 {
     51     std::ifstream stream(path, std::ios::binary);
     52     if (!stream)
     53     {
     54         std::cerr << "error opening tga file " << path << " for reading.\n";
     55         return false;
     56     }
     57 
     58     TGAHeader header;
     59     readBinary(stream, header.idSize);
     60     readBinary(stream, header.mapType);
     61     readBinary(stream, header.imageType);
     62     readBinary(stream, header.paletteStart);
     63     readBinary(stream, header.paletteSize);
     64     readBinary(stream, header.paletteEntryDepth);
     65     readBinary(stream, header.x);
     66     readBinary(stream, header.y);
     67     readBinary(stream, header.width);
     68     readBinary(stream, header.height);
     69     readBinary(stream, header.colorDepth);
     70     readBinary(stream, header.descriptor);
     71 
     72     image->width = header.width;
     73     image->height = header.height;
     74 
     75     size_t pixelComponentCount = header.colorDepth / CHAR_BIT;
     76     std::vector<unsigned char> buffer(header.width * header.height * pixelComponentCount);
     77     readBinary(stream, buffer);
     78 
     79     image->data.reserve(header.width * header.height);
     80 
     81     for (size_t y = 0; y < header.height; y++)
     82     {
     83         size_t rowIdx = ((header.descriptor & INVERTED_BIT) ? (header.height - 1 - y) : y) * header.width * pixelComponentCount;
     84         for (size_t x = 0; x < header.width; x++)
     85         {
     86             size_t pixelIdx = rowIdx + x * pixelComponentCount;
     87 
     88             Byte4 pixel;
     89             pixel[0] = (pixelComponentCount > 2) ? buffer[pixelIdx + 2] : 0;
     90             pixel[2] = (pixelComponentCount > 0) ? buffer[pixelIdx + 0] : 0;
     91             pixel[1] = (pixelComponentCount > 1) ? buffer[pixelIdx + 1] : 0;
     92             pixel[3] = (pixelComponentCount > 3) ? buffer[pixelIdx + 3] : 255;
     93 
     94             image->data.push_back(pixel);
     95         }
     96     }
     97 
     98     std::cout << "loaded image " << path << ".\n";
     99 
    100     return true;
    101 }
    102 
    103 GLuint LoadTextureFromTGAImage(const TGAImage &image)
    104 {
    105     if (image.width > 0 && image.height > 0)
    106     {
    107         GLuint texture;
    108         glGenTextures(1, &texture);
    109         glBindTexture(GL_TEXTURE_2D, texture);
    110         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
    111         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    112         glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    113         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, static_cast<GLsizei>(image.width), static_cast<GLsizei>(image.height), 0,
    114                      GL_RGBA, GL_UNSIGNED_BYTE, image.data.data());
    115         glGenerateMipmap(GL_TEXTURE_2D);
    116         return texture;
    117     }
    118     else
    119     {
    120         return 0;
    121     }
    122 }
    123