ktx.h revision 99ffe24200d8940ceba20f6fbf8c460f994d3cd1
1 2/* 3 * Copyright 2014 Google Inc. 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8 9 10#ifndef SkKTXFile_DEFINED 11#define SkKTXFile_DEFINED 12 13#include "SkData.h" 14#include "SkTypes.h" 15#include "SkTDArray.h" 16#include "SkString.h" 17#include "SkRefCnt.h" 18 19class SkStreamRewindable; 20 21// KTX Image File 22// --- 23// KTX is a general texture data storage file format ratified by the Khronos Group. As an 24// overview, a KTX file contains all of the appropriate values needed to fully specify a 25// texture in an OpenGL application, including the use of compressed data. 26// 27// A full format specification can be found here: 28// http://www.khronos.org/opengles/sdk/tools/KTX/file_format_spec/ 29 30class SkKTXFile { 31public: 32 // The ownership of the data remains with the caller. This class is intended 33 // to be used as a logical wrapper around the data in order to properly 34 // access the pixels. 35 SkKTXFile(SkData* data) 36 : fData(data), fSwapBytes(false) 37 { 38 data->ref(); 39 fValid = this->readKTXFile(fData->bytes(), fData->size()); 40 } 41 42 bool valid() const { return fValid; } 43 44 int width() const { return static_cast<int>(fHeader.fPixelWidth); } 45 int height() const { return static_cast<int>(fHeader.fPixelHeight); } 46 47 const uint8_t *pixelData(int mipmap = 0) const { 48 SkASSERT(!this->valid() || mipmap < fPixelData.count()); 49 return this->valid() ? fPixelData[mipmap].data() : NULL; 50 } 51 52 int numMipmaps() const { return static_cast<int>(fHeader.fNumberOfMipmapLevels); } 53 54 bool isETC1() const; 55 bool isRGBA8() const; 56 bool isRGB8() const; 57 58 static bool is_ktx(const uint8_t *data); 59 static bool is_ktx(SkStreamRewindable* stream); 60 61private: 62 63 // The blob holding the file data. 64 SkAutoTUnref<SkData> fData; 65 66 // This header captures all of the data that describes the format 67 // of the image data in a KTX file. 68 struct Header { 69 uint32_t fGLType; 70 uint32_t fGLTypeSize; 71 uint32_t fGLFormat; 72 uint32_t fGLInternalFormat; 73 uint32_t fGLBaseInternalFormat; 74 uint32_t fPixelWidth; 75 uint32_t fPixelHeight; 76 uint32_t fPixelDepth; 77 uint32_t fNumberOfArrayElements; 78 uint32_t fNumberOfFaces; 79 uint32_t fNumberOfMipmapLevels; 80 uint32_t fBytesOfKeyValueData; 81 82 Header() { memset(this, 0, sizeof(*this)); } 83 } fHeader; 84 85 // A Key Value pair stored in the KTX file. There may be 86 // arbitrarily many of these. 87 class KeyValue { 88 public: 89 KeyValue(size_t size) : fDataSz(size) { } 90 bool readKeyAndValue(const uint8_t *data); 91 92 private: 93 const size_t fDataSz; 94 SkString fKey; 95 SkString fValue; 96 }; 97 98 // The pixel data for a single mipmap level in an image. Based on how 99 // the rest of the data is stored, this may be compressed, a cubemap, etc. 100 // The header will describe the format of this data. 101 class PixelData { 102 public: 103 PixelData(const uint8_t *ptr, size_t sz) : fDataSz(sz), fDataPtr(ptr) { } 104 const uint8_t *data() const { return fDataPtr; } 105 size_t dataSize() const { return fDataSz; } 106 private: 107 const size_t fDataSz; 108 const uint8_t *fDataPtr; 109 }; 110 111 // This function is only called once from the constructor. It loads the data 112 // and populates the appropriate fields of this class 113 // (fKeyValuePairs, fPixelData, fSwapBytes) 114 bool readKTXFile(const uint8_t *data, size_t dataLen); 115 116 SkTArray<KeyValue> fKeyValuePairs; 117 SkTDArray<PixelData> fPixelData; 118 bool fValid; 119 120 // If the endianness of the platform is different than the file, 121 // then we need to do proper byte swapping. 122 bool fSwapBytes; 123 124 // Read an integer from a buffer, advance the buffer, and swap 125 // bytes if fSwapBytes is set 126 uint32_t readInt(const uint8_t** buf, size_t* bytesLeft) const; 127}; 128 129#endif // SkKTXFile_DEFINED 130