aboutsummaryrefslogtreecommitdiffhomepage
path: root/third_party
diff options
context:
space:
mode:
authorGravatar Leon Scroggins III <scroggo@google.com>2016-12-15 12:20:46 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2016-12-15 21:15:54 +0000
commitada12ab0557a1f540e775288e2ce44f64fcd8c7e (patch)
tree2763c7b58e32ff5a39b91ffa55f75c9b8c5300d8 /third_party
parent1b9924ffb7602fd6871359aee0a9660cefbaa812 (diff)
Remove all KTX support
It is untested and unused. Change-Id: I010ff4ad942738f362d42a99af4edbbb1cb0cd71 Reviewed-on: https://skia-review.googlesource.com/6142 Commit-Queue: Leon Scroggins <scroggo@google.com> Reviewed-by: Mike Klein <mtklein@chromium.org> Reviewed-by: Robert Phillips <robertphillips@google.com>
Diffstat (limited to 'third_party')
-rw-r--r--third_party/ktx/ktx.cpp565
-rw-r--r--third_party/ktx/ktx.h145
2 files changed, 0 insertions, 710 deletions
diff --git a/third_party/ktx/ktx.cpp b/third_party/ktx/ktx.cpp
deleted file mode 100644
index ba3ba1fc27..0000000000
--- a/third_party/ktx/ktx.cpp
+++ /dev/null
@@ -1,565 +0,0 @@
-/*
- * Copyright 2014 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "ktx.h"
-#include "SkBitmap.h"
-#include "SkStream.h"
-#include "SkEndian.h"
-
-#include "gl/GrGLDefines.h"
-#include "GrConfig.h"
-
-#include "etc1.h"
-
-static inline uint32_t compressed_fmt_to_gl_define(SkTextureCompressor::Format fmt) {
- static const uint32_t kGLDefineMap[SkTextureCompressor::kFormatCnt] = {
- GR_GL_COMPRESSED_LUMINANCE_LATC1, // kLATC_Format
- GR_GL_COMPRESSED_R11_EAC, // kR11_EAC_Format
- GR_GL_COMPRESSED_ETC1_RGB8, // kETC1_Format
- GR_GL_COMPRESSED_RGBA_ASTC_4x4, // kASTC_4x4_Format
- GR_GL_COMPRESSED_RGBA_ASTC_5x4, // kASTC_5x4_Format
- GR_GL_COMPRESSED_RGBA_ASTC_5x5, // kASTC_5x5_Format
- GR_GL_COMPRESSED_RGBA_ASTC_6x5, // kASTC_6x5_Format
- GR_GL_COMPRESSED_RGBA_ASTC_6x6, // kASTC_6x6_Format
- GR_GL_COMPRESSED_RGBA_ASTC_8x5, // kASTC_8x5_Format
- GR_GL_COMPRESSED_RGBA_ASTC_8x6, // kASTC_8x6_Format
- GR_GL_COMPRESSED_RGBA_ASTC_8x8, // kASTC_8x8_Format
- GR_GL_COMPRESSED_RGBA_ASTC_10x5, // kASTC_10x5_Format
- GR_GL_COMPRESSED_RGBA_ASTC_10x6, // kASTC_10x6_Format
- GR_GL_COMPRESSED_RGBA_ASTC_10x8, // kASTC_10x8_Format
- GR_GL_COMPRESSED_RGBA_ASTC_10x10, // kASTC_10x10_Format
- GR_GL_COMPRESSED_RGBA_ASTC_12x10, // kASTC_12x10_Format
- GR_GL_COMPRESSED_RGBA_ASTC_12x12, // kASTC_12x12_Format
- };
-
- GR_STATIC_ASSERT(0 == SkTextureCompressor::kLATC_Format);
- GR_STATIC_ASSERT(1 == SkTextureCompressor::kR11_EAC_Format);
- GR_STATIC_ASSERT(2 == SkTextureCompressor::kETC1_Format);
- GR_STATIC_ASSERT(3 == SkTextureCompressor::kASTC_4x4_Format);
- GR_STATIC_ASSERT(4 == SkTextureCompressor::kASTC_5x4_Format);
- GR_STATIC_ASSERT(5 == SkTextureCompressor::kASTC_5x5_Format);
- GR_STATIC_ASSERT(6 == SkTextureCompressor::kASTC_6x5_Format);
- GR_STATIC_ASSERT(7 == SkTextureCompressor::kASTC_6x6_Format);
- GR_STATIC_ASSERT(8 == SkTextureCompressor::kASTC_8x5_Format);
- GR_STATIC_ASSERT(9 == SkTextureCompressor::kASTC_8x6_Format);
- GR_STATIC_ASSERT(10 == SkTextureCompressor::kASTC_8x8_Format);
- GR_STATIC_ASSERT(11 == SkTextureCompressor::kASTC_10x5_Format);
- GR_STATIC_ASSERT(12 == SkTextureCompressor::kASTC_10x6_Format);
- GR_STATIC_ASSERT(13 == SkTextureCompressor::kASTC_10x8_Format);
- GR_STATIC_ASSERT(14 == SkTextureCompressor::kASTC_10x10_Format);
- GR_STATIC_ASSERT(15 == SkTextureCompressor::kASTC_12x10_Format);
- GR_STATIC_ASSERT(16 == SkTextureCompressor::kASTC_12x12_Format);
- GR_STATIC_ASSERT(SK_ARRAY_COUNT(kGLDefineMap) == SkTextureCompressor::kFormatCnt);
-
- return kGLDefineMap[fmt];
-}
-
-#define KTX_FILE_IDENTIFIER_SIZE 12
-static const uint8_t KTX_FILE_IDENTIFIER[KTX_FILE_IDENTIFIER_SIZE] = {
- 0xAB, 0x4B, 0x54, 0x58, 0x20, 0x31, 0x31, 0xBB, 0x0D, 0x0A, 0x1A, 0x0A
-};
-
-static const uint32_t kKTX_ENDIANNESS_CODE = 0x04030201;
-
-bool SkKTXFile::KeyValue::readKeyAndValue(const uint8_t* data) {
- const char *key = reinterpret_cast<const char *>(data);
- const char *value = key;
-
- size_t bytesRead = 0;
- while (*value != '\0' && bytesRead < this->fDataSz) {
- ++bytesRead;
- ++value;
- }
-
- // Error of some sort..
- if (bytesRead >= this->fDataSz) {
- return false;
- }
-
- // Read the zero terminator
- ++bytesRead;
- ++value;
-
- size_t bytesLeft = this->fDataSz - bytesRead;
-
- // We ignore the null terminator when setting the string value.
- this->fKey.set(key, bytesRead - 1);
- if (bytesLeft > 0) {
- this->fValue.set(value, bytesLeft - 1);
- } else {
- return false;
- }
-
- return true;
-}
-
-bool SkKTXFile::KeyValue::writeKeyAndValueForKTX(SkWStream* strm) {
- size_t bytesWritten = 0;
- if (!strm->write(&(this->fDataSz), 4)) {
- return false;
- }
-
- bytesWritten += 4;
-
- // Here we know that C-strings must end with a null terminating
- // character, so when we get a c_str(), it will have as many
- // bytes of data as size() returns plus a zero, so we just
- // write size() + 1 bytes into the stream.
-
- size_t keySize = this->fKey.size() + 1;
- if (!strm->write(this->fKey.c_str(), keySize)) {
- return false;
- }
-
- bytesWritten += keySize;
-
- size_t valueSize = this->fValue.size() + 1;
- if (!strm->write(this->fValue.c_str(), valueSize)) {
- return false;
- }
-
- bytesWritten += valueSize;
-
- size_t bytesWrittenPadFour = (bytesWritten + 3) & ~3;
- uint8_t nullBuf[4] = { 0, 0, 0, 0 };
-
- size_t padding = bytesWrittenPadFour - bytesWritten;
- SkASSERT(padding < 4);
-
- return strm->write(nullBuf, padding);
-}
-
-uint32_t SkKTXFile::readInt(const uint8_t** buf, size_t* bytesLeft) const {
- SkASSERT(buf && bytesLeft);
-
- uint32_t result;
-
- if (*bytesLeft < 4) {
- SkASSERT(false);
- return 0;
- }
-
- memcpy(&result, *buf, 4);
- *buf += 4;
-
- if (fSwapBytes) {
- SkEndianSwap32(result);
- }
-
- *bytesLeft -= 4;
-
- return result;
-}
-
-SkString SkKTXFile::getValueForKey(const SkString& key) const {
- const KeyValue *begin = this->fKeyValuePairs.begin();
- const KeyValue *end = this->fKeyValuePairs.end();
- for (const KeyValue *kv = begin; kv != end; ++kv) {
- if (kv->key() == key) {
- return kv->value();
- }
- }
- return SkString();
-}
-
-bool SkKTXFile::isCompressedFormat(SkTextureCompressor::Format fmt) const {
- if (!this->valid()) {
- return false;
- }
-
- // This has many aliases
- bool isFmt = false;
- if (fmt == SkTextureCompressor::kLATC_Format) {
- isFmt = GR_GL_COMPRESSED_RED_RGTC1 == fHeader.fGLInternalFormat ||
- GR_GL_COMPRESSED_3DC_X == fHeader.fGLInternalFormat;
- }
-
- return isFmt || compressed_fmt_to_gl_define(fmt) == fHeader.fGLInternalFormat;
-}
-
-bool SkKTXFile::isRGBA8() const {
- return this->valid() && GR_GL_RGBA8 == fHeader.fGLInternalFormat;
-}
-
-bool SkKTXFile::isRGB8() const {
- return this->valid() && GR_GL_RGB8 == fHeader.fGLInternalFormat;
-}
-
-bool SkKTXFile::readKTXFile(const uint8_t* data, size_t dataLen) {
- const uint8_t *buf = data;
- size_t bytesLeft = dataLen;
-
- // Make sure original KTX header is there... this should have been checked
- // already by a call to is_ktx()
- SkASSERT(bytesLeft > KTX_FILE_IDENTIFIER_SIZE);
- SkASSERT(0 == memcmp(KTX_FILE_IDENTIFIER, buf, KTX_FILE_IDENTIFIER_SIZE));
- buf += KTX_FILE_IDENTIFIER_SIZE;
- bytesLeft -= KTX_FILE_IDENTIFIER_SIZE;
-
- // Read header, but first make sure that we have the proper space: we need
- // two 32-bit ints: 1 for endianness, and another for the mandatory image
- // size after the header.
- if (bytesLeft < 8 + sizeof(Header)) {
- return false;
- }
-
- uint32_t endianness = this->readInt(&buf, &bytesLeft);
- fSwapBytes = kKTX_ENDIANNESS_CODE != endianness;
-
- // Read header values
- fHeader.fGLType = this->readInt(&buf, &bytesLeft);
- fHeader.fGLTypeSize = this->readInt(&buf, &bytesLeft);
- fHeader.fGLFormat = this->readInt(&buf, &bytesLeft);
- fHeader.fGLInternalFormat = this->readInt(&buf, &bytesLeft);
- fHeader.fGLBaseInternalFormat = this->readInt(&buf, &bytesLeft);
- fHeader.fPixelWidth = this->readInt(&buf, &bytesLeft);
- fHeader.fPixelHeight = this->readInt(&buf, &bytesLeft);
- fHeader.fPixelDepth = this->readInt(&buf, &bytesLeft);
- fHeader.fNumberOfArrayElements = this->readInt(&buf, &bytesLeft);
- fHeader.fNumberOfFaces = this->readInt(&buf, &bytesLeft);
- fHeader.fNumberOfMipmapLevels = this->readInt(&buf, &bytesLeft);
- fHeader.fBytesOfKeyValueData = this->readInt(&buf, &bytesLeft);
-
- // Check for things that we understand...
- {
- // First, we only support compressed formats and single byte
- // representations at the moment. If the internal format is
- // compressed, the the GLType field in the header must be zero.
- // In the future, we may support additional data types (such
- // as GL_UNSIGNED_SHORT_5_6_5)
- if (fHeader.fGLType != 0 && fHeader.fGLType != GR_GL_UNSIGNED_BYTE) {
- return false;
- }
-
- // This means that for well-formatted KTX files, the glTypeSize
- // field must be one...
- if (fHeader.fGLTypeSize != 1) {
- return false;
- }
-
- // We don't support 3D textures.
- if (fHeader.fPixelDepth > 1) {
- return false;
- }
-
- // We don't support texture arrays
- if (fHeader.fNumberOfArrayElements > 1) {
- return false;
- }
-
- // We don't support cube maps
- if (fHeader.fNumberOfFaces > 1) {
- return false;
- }
-
- // We don't support width and/or height <= 0
- if (fHeader.fPixelWidth <= 0 || fHeader.fPixelHeight <= 0) {
- return false;
- }
- }
-
- // Make sure that we have enough bytes left for the key/value
- // data according to what was said in the header.
- if (bytesLeft < fHeader.fBytesOfKeyValueData) {
- return false;
- }
-
- // Next read the key value pairs
- size_t keyValueBytesRead = 0;
- while (keyValueBytesRead < fHeader.fBytesOfKeyValueData) {
- uint32_t keyValueBytes = this->readInt(&buf, &bytesLeft);
- keyValueBytesRead += 4;
-
- if (keyValueBytes > bytesLeft) {
- return false;
- }
-
- KeyValue kv(keyValueBytes);
- if (!kv.readKeyAndValue(buf)) {
- return false;
- }
-
- fKeyValuePairs.push_back(kv);
-
- uint32_t keyValueBytesPadded = (keyValueBytes + 3) & ~3;
- buf += keyValueBytesPadded;
- keyValueBytesRead += keyValueBytesPadded;
- bytesLeft -= keyValueBytesPadded;
- }
-
- // Read the pixel data...
- int mipmaps = SkMax32(fHeader.fNumberOfMipmapLevels, 1);
- SkASSERT(mipmaps == 1);
-
- int arrayElements = SkMax32(fHeader.fNumberOfArrayElements, 1);
- SkASSERT(arrayElements == 1);
-
- int faces = SkMax32(fHeader.fNumberOfFaces, 1);
- SkASSERT(faces == 1);
-
- int depth = SkMax32(fHeader.fPixelDepth, 1);
- SkASSERT(depth == 1);
-
- for (int mipmap = 0; mipmap < mipmaps; ++mipmap) {
- // Make sure that we have at least 4 more bytes for the first image size
- if (bytesLeft < 4) {
- return false;
- }
-
- uint32_t imgSize = this->readInt(&buf, &bytesLeft);
-
- // Truncated file.
- if (bytesLeft < imgSize) {
- return false;
- }
-
- // !FIXME! If support is ever added for cube maps then the padding
- // needs to be taken into account here.
- for (int arrayElement = 0; arrayElement < arrayElements; ++arrayElement) {
- for (int face = 0; face < faces; ++face) {
- for (int z = 0; z < depth; ++z) {
- PixelData pd(buf, imgSize);
- fPixelData.append(1, &pd);
- }
- }
- }
-
- uint32_t imgSizePadded = (imgSize + 3) & ~3;
- buf += imgSizePadded;
- bytesLeft -= imgSizePadded;
- }
-
- return bytesLeft == 0;
-}
-
-bool SkKTXFile::is_ktx(const uint8_t data[], size_t size) {
- return size >= KTX_FILE_IDENTIFIER_SIZE &&
- 0 == memcmp(KTX_FILE_IDENTIFIER, data, KTX_FILE_IDENTIFIER_SIZE);
-}
-
-bool SkKTXFile::is_ktx(SkStreamRewindable* stream) {
- // Read the KTX header and make sure it's valid.
- unsigned char buf[KTX_FILE_IDENTIFIER_SIZE];
- bool largeEnough =
- stream->read((void*)buf, KTX_FILE_IDENTIFIER_SIZE) == KTX_FILE_IDENTIFIER_SIZE;
- stream->rewind();
- if (!largeEnough) {
- return false;
- }
- return is_ktx(buf, KTX_FILE_IDENTIFIER_SIZE);
-}
-
-SkKTXFile::KeyValue SkKTXFile::CreateKeyValue(const char *cstrKey, const char *cstrValue) {
- SkString key(cstrKey);
- SkString value(cstrValue);
-
- // Size of buffer is length of string plus the null terminators...
- size_t size = key.size() + 1 + value.size() + 1;
-
- SkAutoSMalloc<256> buf(size);
- uint8_t* kvBuf = reinterpret_cast<uint8_t*>(buf.get());
- memcpy(kvBuf, key.c_str(), key.size() + 1);
- memcpy(kvBuf + key.size() + 1, value.c_str(), value.size() + 1);
-
- KeyValue kv(size);
- SkAssertResult(kv.readKeyAndValue(kvBuf));
- return kv;
-}
-
-bool SkKTXFile::WriteETC1ToKTX(SkWStream* stream, const uint8_t *etc1Data,
- uint32_t width, uint32_t height) {
- // First thing's first, write out the magic identifier and endianness...
- if (!stream->write(KTX_FILE_IDENTIFIER, KTX_FILE_IDENTIFIER_SIZE)) {
- return false;
- }
-
- if (!stream->write(&kKTX_ENDIANNESS_CODE, 4)) {
- return false;
- }
-
- Header hdr;
- hdr.fGLType = 0;
- hdr.fGLTypeSize = 1;
- hdr.fGLFormat = 0;
- hdr.fGLInternalFormat = GR_GL_COMPRESSED_ETC1_RGB8;
- hdr.fGLBaseInternalFormat = GR_GL_RGB;
- hdr.fPixelWidth = width;
- hdr.fPixelHeight = height;
- hdr.fNumberOfArrayElements = 0;
- hdr.fNumberOfFaces = 1;
- hdr.fNumberOfMipmapLevels = 1;
-
- // !FIXME! The spec suggests that we put KTXOrientation as a
- // key value pair in the header, but that means that we'd have to
- // pipe through the pixmap's orientation to properly do that.
- hdr.fBytesOfKeyValueData = 0;
-
- // Write the header
- if (!stream->write(&hdr, sizeof(hdr))) {
- return false;
- }
-
- // Write the size of the image data
- etc1_uint32 dataSize = etc1_get_encoded_data_size(width, height);
- if (!stream->write(&dataSize, 4)) {
- return false;
- }
-
- // Write the actual image data
- if (!stream->write(etc1Data, dataSize)) {
- return false;
- }
-
- return true;
-}
-
-bool SkKTXFile::WritePixmapToKTX(SkWStream* stream, const SkPixmap& pixmap) {
- const SkColorType ct = pixmap.colorType();
-
- const int width = pixmap.width();
- const int height = pixmap.height();
- const uint8_t* src = reinterpret_cast<const uint8_t*>(pixmap.addr());
- if (!src) {
- return false;
- }
- const size_t rowBytes = pixmap.rowBytes();
- const int bytesPerPixel = pixmap.info().bytesPerPixel();
-
- // First thing's first, write out the magic identifier and endianness...
- if (!stream->write(KTX_FILE_IDENTIFIER, KTX_FILE_IDENTIFIER_SIZE) ||
- !stream->write(&kKTX_ENDIANNESS_CODE, 4)) {
- return false;
- }
-
- // Collect our key/value pairs...
- SkTArray<KeyValue> kvPairs;
-
- // Next, write the header based on the pixmap's config.
- Header hdr;
- switch (ct) {
- case kIndex_8_SkColorType:
- // There is a compressed format for this, but we don't support it yet.
- SkDebugf("Writing indexed pixmap to KTX unsupported.\n");
- // VVV fall through VVV
- default:
- case kUnknown_SkColorType:
- // Pixmap hasn't been configured.
- return false;
-
- case kAlpha_8_SkColorType:
- hdr.fGLType = GR_GL_UNSIGNED_BYTE;
- hdr.fGLTypeSize = 1;
- hdr.fGLFormat = GR_GL_RED;
- hdr.fGLInternalFormat = GR_GL_R8;
- hdr.fGLBaseInternalFormat = GR_GL_RED;
- break;
-
- case kRGB_565_SkColorType:
- hdr.fGLType = GR_GL_UNSIGNED_SHORT_5_6_5;
- hdr.fGLTypeSize = 2;
- hdr.fGLFormat = GR_GL_RGB;
- hdr.fGLInternalFormat = GR_GL_RGB;
- hdr.fGLBaseInternalFormat = GR_GL_RGB;
- break;
-
- case kARGB_4444_SkColorType:
- hdr.fGLType = GR_GL_UNSIGNED_SHORT_4_4_4_4;
- hdr.fGLTypeSize = 2;
- hdr.fGLFormat = GR_GL_RGBA;
- hdr.fGLInternalFormat = GR_GL_RGBA4;
- hdr.fGLBaseInternalFormat = GR_GL_RGBA;
- kvPairs.push_back(CreateKeyValue("KTXPremultipliedAlpha", "True"));
- break;
-
- case kN32_SkColorType:
- hdr.fGLType = GR_GL_UNSIGNED_BYTE;
- hdr.fGLTypeSize = 1;
- hdr.fGLFormat = GR_GL_RGBA;
- hdr.fGLInternalFormat = GR_GL_RGBA8;
- hdr.fGLBaseInternalFormat = GR_GL_RGBA;
- kvPairs.push_back(CreateKeyValue("KTXPremultipliedAlpha", "True"));
- break;
- }
-
- // Everything else in the header is shared.
- hdr.fPixelWidth = width;
- hdr.fPixelHeight = height;
- hdr.fNumberOfArrayElements = 0;
- hdr.fNumberOfFaces = 1;
- hdr.fNumberOfMipmapLevels = 1;
-
- // Calculate the key value data size
- hdr.fBytesOfKeyValueData = 0;
- for (KeyValue *kv = kvPairs.begin(); kv != kvPairs.end(); ++kv) {
- // Key value size is the size of the key value data,
- // four bytes for saying how big the key value size is
- // and then additional bytes for padding to four byte boundary
- size_t kvsize = kv->size();
- kvsize += 4;
- kvsize = (kvsize + 3) & ~3;
- hdr.fBytesOfKeyValueData = SkToU32(hdr.fBytesOfKeyValueData + kvsize);
- }
-
- // Write the header
- if (!stream->write(&hdr, sizeof(hdr))) {
- return false;
- }
-
- // Write out each key value pair
- for (KeyValue *kv = kvPairs.begin(); kv != kvPairs.end(); ++kv) {
- if (!kv->writeKeyAndValueForKTX(stream)) {
- return false;
- }
- }
-
- // Calculate the size of the data
- uint32_t dataSz = bytesPerPixel * width * height;
-
- if (0 >= bytesPerPixel) {
- return false;
- }
-
- // Write it into the buffer
- if (!stream->write(&dataSz, 4)) {
- return false;
- }
-
- // Write the pixel data...
- const uint8_t* rowPtr = src;
- if (kN32_SkColorType == ct) {
- for (int j = 0; j < height; ++j) {
- const uint32_t* pixelsPtr = reinterpret_cast<const uint32_t*>(rowPtr);
- for (int i = 0; i < width; ++i) {
- uint32_t pixel = pixelsPtr[i];
- uint8_t dstPixel[4];
- dstPixel[0] = pixel >> SK_R32_SHIFT;
- dstPixel[1] = pixel >> SK_G32_SHIFT;
- dstPixel[2] = pixel >> SK_B32_SHIFT;
- dstPixel[3] = pixel >> SK_A32_SHIFT;
- if (!stream->write(dstPixel, 4)) {
- return false;
- }
- }
- rowPtr += rowBytes;
- }
- } else {
- for (int i = 0; i < height; ++i) {
- if (!stream->write(rowPtr, bytesPerPixel * width)) {
- return false;
- }
- rowPtr += rowBytes;
- }
- }
-
- return true;
-}
-
-bool SkKTXFile::WriteBitmapToKTX(SkWStream* stream, const SkBitmap& bitmap) {
- SkAutoLockPixels autoLockPixels(bitmap);
- SkPixmap pixmap;
- return bitmap.peekPixels(&pixmap) && SkKTXFile::WritePixmapToKTX(stream, pixmap);
-}
diff --git a/third_party/ktx/ktx.h b/third_party/ktx/ktx.h
deleted file mode 100644
index 3aaea15726..0000000000
--- a/third_party/ktx/ktx.h
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright 2014 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-
-#ifndef SkKTXFile_DEFINED
-#define SkKTXFile_DEFINED
-
-#include "SkData.h"
-#include "SkTextureCompressor.h"
-#include "SkTypes.h"
-#include "SkTDArray.h"
-#include "SkString.h"
-#include "SkRefCnt.h"
-
-class SkBitmap;
-class SkPixmap;
-class SkStreamRewindable;
-class SkWStream;
-
-// KTX Image File
-// ---
-// KTX is a general texture data storage file format ratified by the Khronos Group. As an
-// overview, a KTX file contains all of the appropriate values needed to fully specify a
-// texture in an OpenGL application, including the use of compressed data.
-//
-// A full format specification can be found here:
-// http://www.khronos.org/opengles/sdk/tools/KTX/file_format_spec/
-
-class SkKTXFile {
-public:
- // The ownership of the data remains with the caller. This class is intended
- // to be used as a logical wrapper around the data in order to properly
- // access the pixels.
- SkKTXFile(SkData* data) : fData(data), fSwapBytes(false) {
- data->ref();
- fValid = this->readKTXFile(fData->bytes(), fData->size());
- }
-
- bool valid() const { return fValid; }
-
- int width() const { return static_cast<int>(fHeader.fPixelWidth); }
- int height() const { return static_cast<int>(fHeader.fPixelHeight); }
-
- const uint8_t *pixelData(int mipmap = 0) const {
- SkASSERT(!this->valid() || mipmap < fPixelData.count());
- return this->valid() ? fPixelData[mipmap].data() : NULL;
- }
-
- // If the decoded KTX file has the following key, then it will
- // return the associated value. If not found, the empty string
- // is returned.
- SkString getValueForKey(const SkString& key) const;
-
- int numMipmaps() const { return static_cast<int>(fHeader.fNumberOfMipmapLevels); }
-
- bool isCompressedFormat(SkTextureCompressor::Format fmt) const;
- bool isRGBA8() const;
- bool isRGB8() const;
-
- static bool is_ktx(const uint8_t data[], size_t size);
- static bool is_ktx(SkStreamRewindable* stream);
-
- static bool WriteETC1ToKTX(SkWStream* stream, const uint8_t *etc1Data,
- uint32_t width, uint32_t height);
- static bool WritePixmapToKTX(SkWStream* stream, const SkPixmap& pixmap);
- static bool WriteBitmapToKTX(SkWStream* stream, const SkBitmap& bitmap);
-
-private:
-
- // The blob holding the file data.
- sk_sp<SkData> fData;
-
- // This header captures all of the data that describes the format
- // of the image data in a KTX file.
- struct Header {
- uint32_t fGLType;
- uint32_t fGLTypeSize;
- uint32_t fGLFormat;
- uint32_t fGLInternalFormat;
- uint32_t fGLBaseInternalFormat;
- uint32_t fPixelWidth;
- uint32_t fPixelHeight;
- uint32_t fPixelDepth;
- uint32_t fNumberOfArrayElements;
- uint32_t fNumberOfFaces;
- uint32_t fNumberOfMipmapLevels;
- uint32_t fBytesOfKeyValueData;
-
- Header() { memset(this, 0, sizeof(*this)); }
- } fHeader;
-
- // A Key Value pair stored in the KTX file. There may be
- // arbitrarily many of these.
- class KeyValue {
- public:
- KeyValue(size_t size) : fDataSz(size) { }
- bool readKeyAndValue(const uint8_t *data);
- size_t size() const { return fDataSz; }
- const SkString& key() const { return fKey; }
- const SkString& value() const { return fValue; }
- bool writeKeyAndValueForKTX(SkWStream* strm);
- private:
- const size_t fDataSz;
- SkString fKey;
- SkString fValue;
- };
-
- static KeyValue CreateKeyValue(const char *key, const char *value);
-
- // The pixel data for a single mipmap level in an image. Based on how
- // the rest of the data is stored, this may be compressed, a cubemap, etc.
- // The header will describe the format of this data.
- class PixelData {
- public:
- PixelData(const uint8_t *ptr, size_t sz) : fDataSz(sz), fDataPtr(ptr) { }
- const uint8_t *data() const { return fDataPtr; }
- size_t dataSize() const { return fDataSz; }
- private:
- const size_t fDataSz;
- const uint8_t *fDataPtr;
- };
-
- // This function is only called once from the constructor. It loads the data
- // and populates the appropriate fields of this class
- // (fKeyValuePairs, fPixelData, fSwapBytes)
- bool readKTXFile(const uint8_t *data, size_t dataLen);
-
- SkTArray<KeyValue> fKeyValuePairs;
- SkTDArray<PixelData> fPixelData;
- bool fValid;
-
- // If the endianness of the platform is different than the file,
- // then we need to do proper byte swapping.
- bool fSwapBytes;
-
- // Read an integer from a buffer, advance the buffer, and swap
- // bytes if fSwapBytes is set
- uint32_t readInt(const uint8_t** buf, size_t* bytesLeft) const;
-};
-
-#endif // SkKTXFile_DEFINED