From 0cac0c5c0a261ac68f06793f488767f3f161fd4d Mon Sep 17 00:00:00 2001 From: Pavel Krajcevski Date: Wed, 12 Mar 2014 19:26:39 -0400 Subject: [PATCH] Add .astc file loader --- IO/CMakeLists.txt | 5 + IO/include/ImageFileFormat.h | 1 + IO/src/ImageFile.cpp | 8 ++ IO/src/ImageLoaderASTC.cpp | 233 +++++++++++++++++++++++++++++++++++ IO/src/ImageLoaderASTC.h | 70 +++++++++++ 5 files changed, 317 insertions(+) create mode 100644 IO/src/ImageLoaderASTC.cpp create mode 100644 IO/src/ImageLoaderASTC.h diff --git a/IO/CMakeLists.txt b/IO/CMakeLists.txt index 272e624..0c5c6da 100644 --- a/IO/CMakeLists.txt +++ b/IO/CMakeLists.txt @@ -99,6 +99,11 @@ SET( HEADERS ${HEADERS} "src/ImageLoaderKTX.h" ) SET( SOURCES ${SOURCES} "src/ImageWriterKTX.cpp" ) SET( HEADERS ${HEADERS} "src/ImageWriterKTX.h" ) +# Add ASTC loader +# This supports the Mali ASTC evaluation codec. +SET( SOURCES ${SOURCES} "src/ImageLoaderASTC.cpp" ) +SET( HEADERS ${HEADERS} "src/ImageLoaderASTC.h" ) + FIND_PACKAGE( OpenGL ) IF(OPENGL_FOUND) INCLUDE_DIRECTORIES( ${OPENGL_INCLUDE_DIRS} ) diff --git a/IO/include/ImageFileFormat.h b/IO/include/ImageFileFormat.h index fc4557e..4c3438d 100644 --- a/IO/include/ImageFileFormat.h +++ b/IO/include/ImageFileFormat.h @@ -49,6 +49,7 @@ enum EImageFileFormat { eFileFormat_PVR, eFileFormat_TGA, eFileFormat_KTX, + eFileFormat_ASTC, kNumImageFileFormats }; diff --git a/IO/src/ImageFile.cpp b/IO/src/ImageFile.cpp index 60e4479..1fe183b 100644 --- a/IO/src/ImageFile.cpp +++ b/IO/src/ImageFile.cpp @@ -66,6 +66,7 @@ #endif #include "ImageLoaderTGA.h" +#include "ImageLoaderASTC.h" #include "ImageLoaderKTX.h" #include "ImageWriterKTX.h" @@ -213,6 +214,10 @@ FasTC::Image<> *ImageFile::LoadImage() const { loader = new ImageLoaderKTX(m_FileData, m_FileDataSz); break; + case eFileFormat_ASTC: + loader = new ImageLoaderASTC(m_FileData, m_FileDataSz); + break; + default: fprintf(stderr, "Unable to load image: unknown file format.\n"); return NULL; @@ -264,6 +269,9 @@ EImageFileFormat ImageFile::DetectFileFormat(const CHAR *filename) { else if(strcmp(ext, ".ktx") == 0) { return eFileFormat_KTX; } + else if(strcmp(ext, ".astc") == 0) { + return eFileFormat_ASTC; + } return kNumImageFileFormats; } diff --git a/IO/src/ImageLoaderASTC.cpp b/IO/src/ImageLoaderASTC.cpp new file mode 100644 index 0000000..ebf81c0 --- /dev/null +++ b/IO/src/ImageLoaderASTC.cpp @@ -0,0 +1,233 @@ +/* FasTC + * Copyright (c) 2014 University of North Carolina at Chapel Hill. + * All rights reserved. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for educational, research, and non-profit purposes, without + * fee, and without a written agreement is hereby granted, provided that the + * above copyright notice, this paragraph, and the following four paragraphs + * appear in all copies. + * + * Permission to incorporate this software into commercial products may be + * obtained by contacting the authors or the Office of Technology Development + * at the University of North Carolina at Chapel Hill . + * + * This software program and documentation are copyrighted by the University of + * North Carolina at Chapel Hill. The software program and documentation are + * supplied "as is," without any accompanying services from the University of + * North Carolina at Chapel Hill or the authors. The University of North + * Carolina at Chapel Hill and the authors do not warrant that the operation of + * the program will be uninterrupted or error-free. The end-user understands + * that the program was developed for research purposes and is advised not to + * rely exclusively on the program for any reason. + * + * IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE + * AUTHORS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF + * THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA + * AT CHAPEL HILL OR THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY + * DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY + * STATUTORY WARRANTY OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON + * AN "AS IS" BASIS, AND THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND + * THE AUTHORS HAVE NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, + * ENHANCEMENTS, OR MODIFICATIONS. + * + * Please send all BUG REPORTS to . + * + * The authors may be contacted via: + * + * Pavel Krajcevski + * Dept of Computer Science + * 201 S Columbia St + * Frederick P. Brooks, Jr. Computer Science Bldg + * Chapel Hill, NC 27599-3175 + * USA + * + * + */ + +#include "ImageLoaderASTC.h" + +#include +#include +#include +#include +#include + +#include "TexCompTypes.h" +#include "CompressionFormat.h" +#include "ScopedAllocator.h" + +#include "GLDefines.h" +#include "Image.h" +#include "CompressedImage.h" + +static bool GetFormatForBlockDimensions(FasTC::ECompressionFormat &out, + uint32 blockWidth, uint32 blockHeight) { + switch((blockWidth << 4) | blockHeight) { + case ((4 << 4) | 4): + out = FasTC::eCompressionFormat_ASTC4x4; + break; + case ((5 << 4) | 4): + out = FasTC::eCompressionFormat_ASTC5x4; + break; + case ((5 << 4) | 5): + out = FasTC::eCompressionFormat_ASTC5x5; + break; + case ((6 << 4) | 5): + out = FasTC::eCompressionFormat_ASTC6x5; + break; + case ((6 << 4) | 6): + out = FasTC::eCompressionFormat_ASTC6x6; + break; + case ((8 << 4) | 5): + out = FasTC::eCompressionFormat_ASTC8x5; + break; + case ((8 << 4) | 6): + out = FasTC::eCompressionFormat_ASTC8x6; + break; + case ((8 << 4) | 8): + out = FasTC::eCompressionFormat_ASTC8x8; + break; + case ((10 << 4) | 5): + out = FasTC::eCompressionFormat_ASTC10x5; + break; + case ((10 << 4) | 6): + out = FasTC::eCompressionFormat_ASTC10x6; + break; + case ((10 << 4) | 8): + out = FasTC::eCompressionFormat_ASTC10x8; + break; + case ((10 << 4) | 10): + out = FasTC::eCompressionFormat_ASTC10x10; + break; + case ((12 << 4) | 10): + out = FasTC::eCompressionFormat_ASTC12x10; + break; + case ((12 << 4) | 12): + out = FasTC::eCompressionFormat_ASTC12x12; + break; + + default: + fprintf(stderr, "Unsupported block dimensions (%d, %d)\n", blockWidth, blockHeight); + return false; + } + + return true; +} + +ImageLoaderASTC::ImageLoaderASTC(const uint8 *rawData, const int32 rawDataSz) + : ImageLoader(rawData, rawDataSz), m_BlockSizeX(0), m_BlockSizeY(0) +{ } + +ImageLoaderASTC::~ImageLoaderASTC() { } + +FasTC::Image<> *ImageLoaderASTC::LoadImage() { + + // Get rid of the pixel data if it exists... + if(m_PixelData) { + delete m_PixelData; + m_PixelData = NULL; + } + + if(!ReadData()) { + return NULL; + } + + FasTC::ECompressionFormat fmt; + if(!GetFormatForBlockDimensions(fmt, m_BlockSizeX, m_BlockSizeY)) { + return NULL; + } + + return new CompressedImage(m_Width, m_Height, fmt, m_PixelData); +} + +template +static inline void Reverse(T &v) { + uint8 *vp = reinterpret_cast(&v); + for(uint32 i = 0; i < sizeof(T) >> 1; i++) { + std::swap(vp[i], vp[sizeof(T) - 1 - i]); + } +} + +uint32 ReadThreeWideInt(const uint8 *data, const bool bLittleEndian) { + uint32 result = *(reinterpret_cast(data)); + if(!bLittleEndian) { + Reverse(result); + } + result &= 0xFFFFFF; + return result; +} + +bool ImageLoaderASTC::ReadData() { + + const uint8 *data = m_RawData; + uint32 magic = reinterpret_cast(data)[0]; + + // Read the magic bytes at the beginning. + bool bLittleEndian = m_RawData[0] == (magic & 0xFF); + bool OK = false; + if(bLittleEndian && magic == 0x5CA1AB13) { + OK = true; + } else if(!bLittleEndian && magic == 0x13ABA15C) { + OK = true; + } + + if(!OK) return false; + data += 4; + + // The next byte is the block width + uint8 blockWidth = *data; + data++; + uint8 blockHeight = *data; + data++; + uint8 blockDepth = *data; + data++; + + assert(blockWidth <= 12); + assert(blockHeight <= 12); + if(blockDepth != 1) { + fprintf(stderr, "3D compressed textures unsupported!\n"); + return false; + } + + uint32 pixelWidth = ReadThreeWideInt(data, bLittleEndian); + data += 3; + + uint32 pixelHeight = ReadThreeWideInt(data, bLittleEndian); + data += 3; + + uint32 pixelDepth = ReadThreeWideInt(data, bLittleEndian); + data += 3; + + if(pixelDepth != 1) { + fprintf(stderr, "3D compressed textures unsupported!\n"); + return false; + } + + assert(data - m_RawData == 16); + + // Figure out the format based on the block size... + FasTC::ECompressionFormat fmt; + if(!GetFormatForBlockDimensions(fmt, blockWidth, blockHeight)) { + return false; + } + + m_BlockSizeX = blockWidth; + m_BlockSizeY = blockHeight; + m_Width = pixelWidth; + m_Height = pixelHeight; + + uint32 uncompressedSize = pixelWidth * pixelHeight * 4; + uint32 compressedSize = CompressedImage::GetCompressedSize(uncompressedSize, fmt); + + assert(compressedSize + 16 == m_NumRawDataBytes); + m_PixelData = new uint8[compressedSize]; + memcpy(m_PixelData, data, compressedSize); + return true; +} + diff --git a/IO/src/ImageLoaderASTC.h b/IO/src/ImageLoaderASTC.h new file mode 100644 index 0000000..529e1b8 --- /dev/null +++ b/IO/src/ImageLoaderASTC.h @@ -0,0 +1,70 @@ +/* FasTC + * Copyright (c) 2014 University of North Carolina at Chapel Hill. + * All rights reserved. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for educational, research, and non-profit purposes, without + * fee, and without a written agreement is hereby granted, provided that the + * above copyright notice, this paragraph, and the following four paragraphs + * appear in all copies. + * + * Permission to incorporate this software into commercial products may be + * obtained by contacting the authors or the Office of Technology Development + * at the University of North Carolina at Chapel Hill . + * + * This software program and documentation are copyrighted by the University of + * North Carolina at Chapel Hill. The software program and documentation are + * supplied "as is," without any accompanying services from the University of + * North Carolina at Chapel Hill or the authors. The University of North + * Carolina at Chapel Hill and the authors do not warrant that the operation of + * the program will be uninterrupted or error-free. The end-user understands + * that the program was developed for research purposes and is advised not to + * rely exclusively on the program for any reason. + * + * IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE + * AUTHORS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF + * THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA + * AT CHAPEL HILL OR THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY + * DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY + * STATUTORY WARRANTY OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON + * AN "AS IS" BASIS, AND THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND + * THE AUTHORS HAVE NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, + * ENHANCEMENTS, OR MODIFICATIONS. + * + * Please send all BUG REPORTS to . + * + * The authors may be contacted via: + * + * Pavel Krajcevski + * Dept of Computer Science + * 201 S Columbia St + * Frederick P. Brooks, Jr. Computer Science Bldg + * Chapel Hill, NC 27599-3175 + * USA + * + * + */ + +#ifndef _IO_SRC_IMAGE_LOADER_ASTC_H_ +#define _IO_SRC_IMAGE_LOADER_ASTC_H_ + +#include "ImageLoader.h" + +class ImageLoaderASTC : public ImageLoader { + private: + uint8 m_BlockSizeX; + uint8 m_BlockSizeY; + public: + ImageLoaderASTC(const uint8 *rawData, const int32 rawDataSz); + virtual ~ImageLoaderASTC(); + + virtual bool ReadData(); + virtual FasTC::Image<> *LoadImage(); +}; + +#endif // _IO_SRC_IMAGE_LOADER_ASTC_H_