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 #include "ktx.h" 10 #include "SkBitmap.h" 11 #include "SkStream.h" 12 #include "SkEndian.h" 13 14 #include "gl/GrGLDefines.h" 15 #include "GrConfig.h" 16 17 #include "etc1.h" 18 19 static inline uint32_t compressed_fmt_to_gl_define(SkTextureCompressor::Format fmt) { 20 static const uint32_t kGLDefineMap[SkTextureCompressor::kFormatCnt] = { 21 GR_GL_COMPRESSED_LUMINANCE_LATC1, // kLATC_Format 22 GR_GL_COMPRESSED_R11_EAC, // kR11_EAC_Format 23 GR_GL_COMPRESSED_ETC1_RGB8, // kETC1_Format 24 GR_GL_COMPRESSED_RGBA_ASTC_4x4, // kASTC_4x4_Format 25 GR_GL_COMPRESSED_RGBA_ASTC_5x4, // kASTC_5x4_Format 26 GR_GL_COMPRESSED_RGBA_ASTC_5x5, // kASTC_5x5_Format 27 GR_GL_COMPRESSED_RGBA_ASTC_6x5, // kASTC_6x5_Format 28 GR_GL_COMPRESSED_RGBA_ASTC_6x6, // kASTC_6x6_Format 29 GR_GL_COMPRESSED_RGBA_ASTC_8x5, // kASTC_8x5_Format 30 GR_GL_COMPRESSED_RGBA_ASTC_8x6, // kASTC_8x6_Format 31 GR_GL_COMPRESSED_RGBA_ASTC_8x8, // kASTC_8x8_Format 32 GR_GL_COMPRESSED_RGBA_ASTC_10x5, // kASTC_10x5_Format 33 GR_GL_COMPRESSED_RGBA_ASTC_10x6, // kASTC_10x6_Format 34 GR_GL_COMPRESSED_RGBA_ASTC_10x8, // kASTC_10x8_Format 35 GR_GL_COMPRESSED_RGBA_ASTC_10x10, // kASTC_10x10_Format 36 GR_GL_COMPRESSED_RGBA_ASTC_12x10, // kASTC_12x10_Format 37 GR_GL_COMPRESSED_RGBA_ASTC_12x12, // kASTC_12x12_Format 38 }; 39 40 GR_STATIC_ASSERT(0 == SkTextureCompressor::kLATC_Format); 41 GR_STATIC_ASSERT(1 == SkTextureCompressor::kR11_EAC_Format); 42 GR_STATIC_ASSERT(2 == SkTextureCompressor::kETC1_Format); 43 GR_STATIC_ASSERT(3 == SkTextureCompressor::kASTC_4x4_Format); 44 GR_STATIC_ASSERT(4 == SkTextureCompressor::kASTC_5x4_Format); 45 GR_STATIC_ASSERT(5 == SkTextureCompressor::kASTC_5x5_Format); 46 GR_STATIC_ASSERT(6 == SkTextureCompressor::kASTC_6x5_Format); 47 GR_STATIC_ASSERT(7 == SkTextureCompressor::kASTC_6x6_Format); 48 GR_STATIC_ASSERT(8 == SkTextureCompressor::kASTC_8x5_Format); 49 GR_STATIC_ASSERT(9 == SkTextureCompressor::kASTC_8x6_Format); 50 GR_STATIC_ASSERT(10 == SkTextureCompressor::kASTC_8x8_Format); 51 GR_STATIC_ASSERT(11 == SkTextureCompressor::kASTC_10x5_Format); 52 GR_STATIC_ASSERT(12 == SkTextureCompressor::kASTC_10x6_Format); 53 GR_STATIC_ASSERT(13 == SkTextureCompressor::kASTC_10x8_Format); 54 GR_STATIC_ASSERT(14 == SkTextureCompressor::kASTC_10x10_Format); 55 GR_STATIC_ASSERT(15 == SkTextureCompressor::kASTC_12x10_Format); 56 GR_STATIC_ASSERT(16 == SkTextureCompressor::kASTC_12x12_Format); 57 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kGLDefineMap) == SkTextureCompressor::kFormatCnt); 58 59 return kGLDefineMap[fmt]; 60 } 61 62 #define KTX_FILE_IDENTIFIER_SIZE 12 63 static const uint8_t KTX_FILE_IDENTIFIER[KTX_FILE_IDENTIFIER_SIZE] = { 64 0xAB, 0x4B, 0x54, 0x58, 0x20, 0x31, 0x31, 0xBB, 0x0D, 0x0A, 0x1A, 0x0A 65 }; 66 67 static const uint32_t kKTX_ENDIANNESS_CODE = 0x04030201; 68 69 bool SkKTXFile::KeyValue::readKeyAndValue(const uint8_t* data) { 70 const char *key = reinterpret_cast<const char *>(data); 71 const char *value = key; 72 73 size_t bytesRead = 0; 74 while (*value != '\0' && bytesRead < this->fDataSz) { 75 ++bytesRead; 76 ++value; 77 } 78 79 // Error of some sort.. 80 if (bytesRead >= this->fDataSz) { 81 return false; 82 } 83 84 // Read the zero terminator 85 ++bytesRead; 86 ++value; 87 88 size_t bytesLeft = this->fDataSz - bytesRead; 89 90 // We ignore the null terminator when setting the string value. 91 this->fKey.set(key, bytesRead - 1); 92 if (bytesLeft > 0) { 93 this->fValue.set(value, bytesLeft - 1); 94 } else { 95 return false; 96 } 97 98 return true; 99 } 100 101 bool SkKTXFile::KeyValue::writeKeyAndValueForKTX(SkWStream* strm) { 102 size_t bytesWritten = 0; 103 if (!strm->write(&(this->fDataSz), 4)) { 104 return false; 105 } 106 107 bytesWritten += 4; 108 109 // Here we know that C-strings must end with a null terminating 110 // character, so when we get a c_str(), it will have as many 111 // bytes of data as size() returns plus a zero, so we just 112 // write size() + 1 bytes into the stream. 113 114 size_t keySize = this->fKey.size() + 1; 115 if (!strm->write(this->fKey.c_str(), keySize)) { 116 return false; 117 } 118 119 bytesWritten += keySize; 120 121 size_t valueSize = this->fValue.size() + 1; 122 if (!strm->write(this->fValue.c_str(), valueSize)) { 123 return false; 124 } 125 126 bytesWritten += valueSize; 127 128 size_t bytesWrittenPadFour = (bytesWritten + 3) & ~3; 129 uint8_t nullBuf[4] = { 0, 0, 0, 0 }; 130 131 size_t padding = bytesWrittenPadFour - bytesWritten; 132 SkASSERT(padding < 4); 133 134 return strm->write(nullBuf, padding); 135 } 136 137 uint32_t SkKTXFile::readInt(const uint8_t** buf, size_t* bytesLeft) const { 138 SkASSERT(buf && bytesLeft); 139 140 uint32_t result; 141 142 if (*bytesLeft < 4) { 143 SkASSERT(false); 144 return 0; 145 } 146 147 memcpy(&result, *buf, 4); 148 *buf += 4; 149 150 if (fSwapBytes) { 151 SkEndianSwap32(result); 152 } 153 154 *bytesLeft -= 4; 155 156 return result; 157 } 158 159 SkString SkKTXFile::getValueForKey(const SkString& key) const { 160 const KeyValue *begin = this->fKeyValuePairs.begin(); 161 const KeyValue *end = this->fKeyValuePairs.end(); 162 for (const KeyValue *kv = begin; kv != end; ++kv) { 163 if (kv->key() == key) { 164 return kv->value(); 165 } 166 } 167 return SkString(); 168 } 169 170 bool SkKTXFile::isCompressedFormat(SkTextureCompressor::Format fmt) const { 171 if (!this->valid()) { 172 return false; 173 } 174 175 // This has many aliases 176 bool isFmt = false; 177 if (fmt == SkTextureCompressor::kLATC_Format) { 178 isFmt = GR_GL_COMPRESSED_RED_RGTC1 == fHeader.fGLInternalFormat || 179 GR_GL_COMPRESSED_3DC_X == fHeader.fGLInternalFormat; 180 } 181 182 return isFmt || compressed_fmt_to_gl_define(fmt) == fHeader.fGLInternalFormat; 183 } 184 185 bool SkKTXFile::isRGBA8() const { 186 return this->valid() && GR_GL_RGBA8 == fHeader.fGLInternalFormat; 187 } 188 189 bool SkKTXFile::isRGB8() const { 190 return this->valid() && GR_GL_RGB8 == fHeader.fGLInternalFormat; 191 } 192 193 bool SkKTXFile::readKTXFile(const uint8_t* data, size_t dataLen) { 194 const uint8_t *buf = data; 195 size_t bytesLeft = dataLen; 196 197 // Make sure original KTX header is there... this should have been checked 198 // already by a call to is_ktx() 199 SkASSERT(bytesLeft > KTX_FILE_IDENTIFIER_SIZE); 200 SkASSERT(0 == memcmp(KTX_FILE_IDENTIFIER, buf, KTX_FILE_IDENTIFIER_SIZE)); 201 buf += KTX_FILE_IDENTIFIER_SIZE; 202 bytesLeft -= KTX_FILE_IDENTIFIER_SIZE; 203 204 // Read header, but first make sure that we have the proper space: we need 205 // two 32-bit ints: 1 for endianness, and another for the mandatory image 206 // size after the header. 207 if (bytesLeft < 8 + sizeof(Header)) { 208 return false; 209 } 210 211 uint32_t endianness = this->readInt(&buf, &bytesLeft); 212 fSwapBytes = kKTX_ENDIANNESS_CODE != endianness; 213 214 // Read header values 215 fHeader.fGLType = this->readInt(&buf, &bytesLeft); 216 fHeader.fGLTypeSize = this->readInt(&buf, &bytesLeft); 217 fHeader.fGLFormat = this->readInt(&buf, &bytesLeft); 218 fHeader.fGLInternalFormat = this->readInt(&buf, &bytesLeft); 219 fHeader.fGLBaseInternalFormat = this->readInt(&buf, &bytesLeft); 220 fHeader.fPixelWidth = this->readInt(&buf, &bytesLeft); 221 fHeader.fPixelHeight = this->readInt(&buf, &bytesLeft); 222 fHeader.fPixelDepth = this->readInt(&buf, &bytesLeft); 223 fHeader.fNumberOfArrayElements = this->readInt(&buf, &bytesLeft); 224 fHeader.fNumberOfFaces = this->readInt(&buf, &bytesLeft); 225 fHeader.fNumberOfMipmapLevels = this->readInt(&buf, &bytesLeft); 226 fHeader.fBytesOfKeyValueData = this->readInt(&buf, &bytesLeft); 227 228 // Check for things that we understand... 229 { 230 // First, we only support compressed formats and single byte 231 // representations at the moment. If the internal format is 232 // compressed, the the GLType field in the header must be zero. 233 // In the future, we may support additional data types (such 234 // as GL_UNSIGNED_SHORT_5_6_5) 235 if (fHeader.fGLType != 0 && fHeader.fGLType != GR_GL_UNSIGNED_BYTE) { 236 return false; 237 } 238 239 // This means that for well-formatted KTX files, the glTypeSize 240 // field must be one... 241 if (fHeader.fGLTypeSize != 1) { 242 return false; 243 } 244 245 // We don't support 3D textures. 246 if (fHeader.fPixelDepth > 1) { 247 return false; 248 } 249 250 // We don't support texture arrays 251 if (fHeader.fNumberOfArrayElements > 1) { 252 return false; 253 } 254 255 // We don't support cube maps 256 if (fHeader.fNumberOfFaces > 1) { 257 return false; 258 } 259 260 // We don't support width and/or height <= 0 261 if (fHeader.fPixelWidth <= 0 || fHeader.fPixelHeight <= 0) { 262 return false; 263 } 264 } 265 266 // Make sure that we have enough bytes left for the key/value 267 // data according to what was said in the header. 268 if (bytesLeft < fHeader.fBytesOfKeyValueData) { 269 return false; 270 } 271 272 // Next read the key value pairs 273 size_t keyValueBytesRead = 0; 274 while (keyValueBytesRead < fHeader.fBytesOfKeyValueData) { 275 uint32_t keyValueBytes = this->readInt(&buf, &bytesLeft); 276 keyValueBytesRead += 4; 277 278 if (keyValueBytes > bytesLeft) { 279 return false; 280 } 281 282 KeyValue kv(keyValueBytes); 283 if (!kv.readKeyAndValue(buf)) { 284 return false; 285 } 286 287 fKeyValuePairs.push_back(kv); 288 289 uint32_t keyValueBytesPadded = (keyValueBytes + 3) & ~3; 290 buf += keyValueBytesPadded; 291 keyValueBytesRead += keyValueBytesPadded; 292 bytesLeft -= keyValueBytesPadded; 293 } 294 295 // Read the pixel data... 296 int mipmaps = SkMax32(fHeader.fNumberOfMipmapLevels, 1); 297 SkASSERT(mipmaps == 1); 298 299 int arrayElements = SkMax32(fHeader.fNumberOfArrayElements, 1); 300 SkASSERT(arrayElements == 1); 301 302 int faces = SkMax32(fHeader.fNumberOfFaces, 1); 303 SkASSERT(faces == 1); 304 305 int depth = SkMax32(fHeader.fPixelDepth, 1); 306 SkASSERT(depth == 1); 307 308 for (int mipmap = 0; mipmap < mipmaps; ++mipmap) { 309 // Make sure that we have at least 4 more bytes for the first image size 310 if (bytesLeft < 4) { 311 return false; 312 } 313 314 uint32_t imgSize = this->readInt(&buf, &bytesLeft); 315 316 // Truncated file. 317 if (bytesLeft < imgSize) { 318 return false; 319 } 320 321 // !FIXME! If support is ever added for cube maps then the padding 322 // needs to be taken into account here. 323 for (int arrayElement = 0; arrayElement < arrayElements; ++arrayElement) { 324 for (int face = 0; face < faces; ++face) { 325 for (int z = 0; z < depth; ++z) { 326 PixelData pd(buf, imgSize); 327 fPixelData.append(1, &pd); 328 } 329 } 330 } 331 332 uint32_t imgSizePadded = (imgSize + 3) & ~3; 333 buf += imgSizePadded; 334 bytesLeft -= imgSizePadded; 335 } 336 337 return bytesLeft == 0; 338 } 339 340 bool SkKTXFile::is_ktx(const uint8_t *data) { 341 return 0 == memcmp(KTX_FILE_IDENTIFIER, data, KTX_FILE_IDENTIFIER_SIZE); 342 } 343 344 bool SkKTXFile::is_ktx(SkStreamRewindable* stream) { 345 // Read the KTX header and make sure it's valid. 346 unsigned char buf[KTX_FILE_IDENTIFIER_SIZE]; 347 bool largeEnough = 348 stream->read((void*)buf, KTX_FILE_IDENTIFIER_SIZE) == KTX_FILE_IDENTIFIER_SIZE; 349 stream->rewind(); 350 if (!largeEnough) { 351 return false; 352 } 353 return is_ktx(buf); 354 } 355 356 SkKTXFile::KeyValue SkKTXFile::CreateKeyValue(const char *cstrKey, const char *cstrValue) { 357 SkString key(cstrKey); 358 SkString value(cstrValue); 359 360 // Size of buffer is length of string plus the null terminators... 361 size_t size = key.size() + 1 + value.size() + 1; 362 363 SkAutoSMalloc<256> buf(size); 364 uint8_t* kvBuf = reinterpret_cast<uint8_t*>(buf.get()); 365 memcpy(kvBuf, key.c_str(), key.size() + 1); 366 memcpy(kvBuf + key.size() + 1, value.c_str(), value.size() + 1); 367 368 KeyValue kv(size); 369 SkAssertResult(kv.readKeyAndValue(kvBuf)); 370 return kv; 371 } 372 373 bool SkKTXFile::WriteETC1ToKTX(SkWStream* stream, const uint8_t *etc1Data, 374 uint32_t width, uint32_t height) { 375 // First thing's first, write out the magic identifier and endianness... 376 if (!stream->write(KTX_FILE_IDENTIFIER, KTX_FILE_IDENTIFIER_SIZE)) { 377 return false; 378 } 379 380 if (!stream->write(&kKTX_ENDIANNESS_CODE, 4)) { 381 return false; 382 } 383 384 Header hdr; 385 hdr.fGLType = 0; 386 hdr.fGLTypeSize = 1; 387 hdr.fGLFormat = 0; 388 hdr.fGLInternalFormat = GR_GL_COMPRESSED_ETC1_RGB8; 389 hdr.fGLBaseInternalFormat = GR_GL_RGB; 390 hdr.fPixelWidth = width; 391 hdr.fPixelHeight = height; 392 hdr.fNumberOfArrayElements = 0; 393 hdr.fNumberOfFaces = 1; 394 hdr.fNumberOfMipmapLevels = 1; 395 396 // !FIXME! The spec suggests that we put KTXOrientation as a 397 // key value pair in the header, but that means that we'd have to 398 // pipe through the bitmap's orientation to properly do that. 399 hdr.fBytesOfKeyValueData = 0; 400 401 // Write the header 402 if (!stream->write(&hdr, sizeof(hdr))) { 403 return false; 404 } 405 406 // Write the size of the image data 407 etc1_uint32 dataSize = etc1_get_encoded_data_size(width, height); 408 if (!stream->write(&dataSize, 4)) { 409 return false; 410 } 411 412 // Write the actual image data 413 if (!stream->write(etc1Data, dataSize)) { 414 return false; 415 } 416 417 return true; 418 } 419 420 bool SkKTXFile::WriteBitmapToKTX(SkWStream* stream, const SkBitmap& bitmap) { 421 const SkColorType ct = bitmap.colorType(); 422 SkAutoLockPixels alp(bitmap); 423 424 const int width = bitmap.width(); 425 const int height = bitmap.width(); 426 const uint8_t* src = reinterpret_cast<uint8_t*>(bitmap.getPixels()); 427 if (NULL == bitmap.getPixels()) { 428 return false; 429 } 430 431 // First thing's first, write out the magic identifier and endianness... 432 if (!stream->write(KTX_FILE_IDENTIFIER, KTX_FILE_IDENTIFIER_SIZE) || 433 !stream->write(&kKTX_ENDIANNESS_CODE, 4)) { 434 return false; 435 } 436 437 // Collect our key/value pairs... 438 SkTArray<KeyValue> kvPairs; 439 440 // Next, write the header based on the bitmap's config. 441 Header hdr; 442 switch (ct) { 443 case kIndex_8_SkColorType: 444 // There is a compressed format for this, but we don't support it yet. 445 SkDebugf("Writing indexed bitmap to KTX unsupported.\n"); 446 // VVV fall through VVV 447 default: 448 case kUnknown_SkColorType: 449 // Bitmap hasn't been configured. 450 return false; 451 452 case kAlpha_8_SkColorType: 453 hdr.fGLType = GR_GL_UNSIGNED_BYTE; 454 hdr.fGLTypeSize = 1; 455 hdr.fGLFormat = GR_GL_RED; 456 hdr.fGLInternalFormat = GR_GL_R8; 457 hdr.fGLBaseInternalFormat = GR_GL_RED; 458 break; 459 460 case kRGB_565_SkColorType: 461 hdr.fGLType = GR_GL_UNSIGNED_SHORT_5_6_5; 462 hdr.fGLTypeSize = 2; 463 hdr.fGLFormat = GR_GL_RGB; 464 hdr.fGLInternalFormat = GR_GL_RGB; 465 hdr.fGLBaseInternalFormat = GR_GL_RGB; 466 break; 467 468 case kARGB_4444_SkColorType: 469 hdr.fGLType = GR_GL_UNSIGNED_SHORT_4_4_4_4; 470 hdr.fGLTypeSize = 2; 471 hdr.fGLFormat = GR_GL_RGBA; 472 hdr.fGLInternalFormat = GR_GL_RGBA4; 473 hdr.fGLBaseInternalFormat = GR_GL_RGBA; 474 kvPairs.push_back(CreateKeyValue("KTXPremultipliedAlpha", "True")); 475 break; 476 477 case kN32_SkColorType: 478 hdr.fGLType = GR_GL_UNSIGNED_BYTE; 479 hdr.fGLTypeSize = 1; 480 hdr.fGLFormat = GR_GL_RGBA; 481 hdr.fGLInternalFormat = GR_GL_RGBA8; 482 hdr.fGLBaseInternalFormat = GR_GL_RGBA; 483 kvPairs.push_back(CreateKeyValue("KTXPremultipliedAlpha", "True")); 484 break; 485 } 486 487 // Everything else in the header is shared. 488 hdr.fPixelWidth = width; 489 hdr.fPixelHeight = height; 490 hdr.fNumberOfArrayElements = 0; 491 hdr.fNumberOfFaces = 1; 492 hdr.fNumberOfMipmapLevels = 1; 493 494 // Calculate the key value data size 495 hdr.fBytesOfKeyValueData = 0; 496 for (KeyValue *kv = kvPairs.begin(); kv != kvPairs.end(); ++kv) { 497 // Key value size is the size of the key value data, 498 // four bytes for saying how big the key value size is 499 // and then additional bytes for padding to four byte boundary 500 size_t kvsize = kv->size(); 501 kvsize += 4; 502 kvsize = (kvsize + 3) & ~3; 503 hdr.fBytesOfKeyValueData = SkToU32(hdr.fBytesOfKeyValueData + kvsize); 504 } 505 506 // Write the header 507 if (!stream->write(&hdr, sizeof(hdr))) { 508 return false; 509 } 510 511 // Write out each key value pair 512 for (KeyValue *kv = kvPairs.begin(); kv != kvPairs.end(); ++kv) { 513 if (!kv->writeKeyAndValueForKTX(stream)) { 514 return false; 515 } 516 } 517 518 // Calculate the size of the data 519 int bpp = bitmap.bytesPerPixel(); 520 uint32_t dataSz = bpp * width * height; 521 522 if (0 >= bpp) { 523 return false; 524 } 525 526 // Write it into the buffer 527 if (!stream->write(&dataSz, 4)) { 528 return false; 529 } 530 531 // Write the pixel data... 532 const uint8_t* rowPtr = src; 533 if (kN32_SkColorType == ct) { 534 for (int j = 0; j < height; ++j) { 535 const uint32_t* pixelsPtr = reinterpret_cast<const uint32_t*>(rowPtr); 536 for (int i = 0; i < width; ++i) { 537 uint32_t pixel = pixelsPtr[i]; 538 uint8_t dstPixel[4]; 539 dstPixel[0] = pixel >> SK_R32_SHIFT; 540 dstPixel[1] = pixel >> SK_G32_SHIFT; 541 dstPixel[2] = pixel >> SK_B32_SHIFT; 542 dstPixel[3] = pixel >> SK_A32_SHIFT; 543 if (!stream->write(dstPixel, 4)) { 544 return false; 545 } 546 } 547 rowPtr += bitmap.rowBytes(); 548 } 549 } else { 550 for (int i = 0; i < height; ++i) { 551 if (!stream->write(rowPtr, bpp*width)) { 552 return false; 553 } 554 rowPtr += bitmap.rowBytes(); 555 } 556 } 557 558 return true; 559 } 560