summaryrefslogtreecommitdiff
path: root/thirdparty/etc2comp/EtcImage.cpp
diff options
context:
space:
mode:
authorK. S. Ernest (iFire) Lee <ernest.lee@chibifire.com>2021-04-06 22:05:56 -0700
committerRémi Verschelde <rverschelde@gmail.com>2021-04-13 00:12:12 +0200
commitd840165a324b5c218ca3a4882f030986855c8383 (patch)
tree7c5f4b091ecc647f2b6ed48135945f84c6dc2de9 /thirdparty/etc2comp/EtcImage.cpp
parentb895071895cffcbcda7f4156d7175ba5b8068852 (diff)
Add `etcpak` library for faster ETC/ETC2/S3TC imports.
- `etc` module was renamed to `etcpak` and modified to use the new library. - PKM importer is removed in the process, it's obsolete. - Old library `etc2comp` is removed. - S3TC compression no longer done via `squish` (but decompression still is). - Slight modifications to etcpak sources for MinGW compatibility, to fix LLVM `-Wc++11-narrowing` errors, and to allow using vendored or system libpng. Co-authored-by: Rémi Verschelde <rverschelde@gmail.com>
Diffstat (limited to 'thirdparty/etc2comp/EtcImage.cpp')
-rw-r--r--thirdparty/etc2comp/EtcImage.cpp685
1 files changed, 0 insertions, 685 deletions
diff --git a/thirdparty/etc2comp/EtcImage.cpp b/thirdparty/etc2comp/EtcImage.cpp
deleted file mode 100644
index 7a1058844d..0000000000
--- a/thirdparty/etc2comp/EtcImage.cpp
+++ /dev/null
@@ -1,685 +0,0 @@
-/*
- * Copyright 2015 The Etc2Comp Authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
-EtcImage.cpp
-
-Image is an array of 4x4 blocks that represent the encoding of the source image
-
-*/
-
-#include "EtcConfig.h"
-
-#include <stdlib.h>
-
-#include "EtcImage.h"
-
-#include "Etc.h"
-#include "EtcBlock4x4.h"
-#include "EtcBlock4x4EncodingBits.h"
-#include "EtcSortedBlockList.h"
-
-#if ETC_WINDOWS
-#include <windows.h>
-#endif
-#include <ctime>
-#include <chrono>
-#include <future>
-#include <stdio.h>
-#include <string.h>
-#include <assert.h>
-
-// fix conflict with Block4x4::AlphaMix
-#ifdef OPAQUE
-#undef OPAQUE
-#endif
-#ifdef TRANSPARENT
-#undef TRANSPARENT
-#endif
-
-namespace Etc
-{
-
- // ----------------------------------------------------------------------------------------------------
- //
- Image::Image(void)
- {
- m_encodingStatus = EncodingStatus::SUCCESS;
- m_warningsToCapture = EncodingStatus::SUCCESS;
- m_pafrgbaSource = nullptr;
-
- m_pablock = nullptr;
-
- m_encodingbitsformat = Block4x4EncodingBits::Format::UNKNOWN;
- m_uiEncodingBitsBytes = 0;
- m_paucEncodingBits = nullptr;
-
- m_format = Format::UNKNOWN;
- m_iNumOpaquePixels = 0;
- m_iNumTranslucentPixels = 0;
- m_iNumTransparentPixels = 0;
- }
-
- // ----------------------------------------------------------------------------------------------------
- // constructor using source image
- // used to set state before Encode() is called
- //
- Image::Image(float *a_pafSourceRGBA, unsigned int a_uiSourceWidth,
- unsigned int a_uiSourceHeight,
- ErrorMetric a_errormetric)
- {
- m_encodingStatus = EncodingStatus::SUCCESS;
- m_warningsToCapture = EncodingStatus::SUCCESS;
- m_pafrgbaSource = (ColorFloatRGBA *) a_pafSourceRGBA;
- m_uiSourceWidth = a_uiSourceWidth;
- m_uiSourceHeight = a_uiSourceHeight;
-
- m_uiExtendedWidth = CalcExtendedDimension((unsigned short)m_uiSourceWidth);
- m_uiExtendedHeight = CalcExtendedDimension((unsigned short)m_uiSourceHeight);
-
- m_uiBlockColumns = m_uiExtendedWidth >> 2;
- m_uiBlockRows = m_uiExtendedHeight >> 2;
-
- m_pablock = new Block4x4[GetNumberOfBlocks()];
- assert(m_pablock);
-
- m_format = Format::UNKNOWN;
-
- m_encodingbitsformat = Block4x4EncodingBits::Format::UNKNOWN;
- m_uiEncodingBitsBytes = 0;
- m_paucEncodingBits = nullptr;
-
- m_errormetric = a_errormetric;
- m_fEffort = 0.0f;
-
- m_iEncodeTime_ms = -1;
-
- m_iNumOpaquePixels = 0;
- m_iNumTranslucentPixels = 0;
- m_iNumTransparentPixels = 0;
- m_bVerboseOutput = false;
-
- }
-
- // ----------------------------------------------------------------------------------------------------
- // constructor using encoding bits
- // recreates encoding state using a previously encoded image
- //
- Image::Image(Format a_format,
- unsigned int a_uiSourceWidth, unsigned int a_uiSourceHeight,
- unsigned char *a_paucEncidingBits, unsigned int a_uiEncodingBitsBytes,
- Image *a_pimageSource, ErrorMetric a_errormetric)
- {
- m_encodingStatus = EncodingStatus::SUCCESS;
- m_pafrgbaSource = nullptr;
- m_uiSourceWidth = a_uiSourceWidth;
- m_uiSourceHeight = a_uiSourceHeight;
-
- m_uiExtendedWidth = CalcExtendedDimension((unsigned short)m_uiSourceWidth);
- m_uiExtendedHeight = CalcExtendedDimension((unsigned short)m_uiSourceHeight);
-
- m_uiBlockColumns = m_uiExtendedWidth >> 2;
- m_uiBlockRows = m_uiExtendedHeight >> 2;
-
- unsigned int uiBlocks = GetNumberOfBlocks();
-
- m_pablock = new Block4x4[uiBlocks];
- assert(m_pablock);
-
- m_format = a_format;
-
- m_iNumOpaquePixels = 0;
- m_iNumTranslucentPixels = 0;
- m_iNumTransparentPixels = 0;
-
- m_encodingbitsformat = DetermineEncodingBitsFormat(m_format);
- if (m_encodingbitsformat == Block4x4EncodingBits::Format::UNKNOWN)
- {
- AddToEncodingStatus(ERROR_UNKNOWN_FORMAT);
- return;
- }
- m_uiEncodingBitsBytes = a_uiEncodingBitsBytes;
- m_paucEncodingBits = a_paucEncidingBits;
-
- m_errormetric = a_errormetric;
- m_fEffort = 0.0f;
- m_bVerboseOutput = false;
- m_iEncodeTime_ms = -1;
-
- unsigned char *paucEncodingBits = m_paucEncodingBits;
- unsigned int uiEncodingBitsBytesPerBlock = Block4x4EncodingBits::GetBytesPerBlock(m_encodingbitsformat);
-
- unsigned int uiH = 0;
- unsigned int uiV = 0;
- for (unsigned int uiBlock = 0; uiBlock < uiBlocks; uiBlock++)
- {
- m_pablock[uiBlock].InitFromEtcEncodingBits(a_format, uiH, uiV, paucEncodingBits,
- a_pimageSource, a_errormetric);
- paucEncodingBits += uiEncodingBitsBytesPerBlock;
- uiH += 4;
- if (uiH >= m_uiSourceWidth)
- {
- uiH = 0;
- uiV += 4;
- }
- }
-
- }
-
- // ----------------------------------------------------------------------------------------------------
- //
- Image::~Image(void)
- {
- if (m_pablock != nullptr)
- {
- delete[] m_pablock;
- m_pablock = nullptr;
- }
-
- /*if (m_paucEncodingBits != nullptr)
- {
- delete[] m_paucEncodingBits;
- m_paucEncodingBits = nullptr;
- }*/
- }
-
- // ----------------------------------------------------------------------------------------------------
- // encode an image
- // create a set of encoding bits that conforms to a_format
- // find best fit using a_errormetric
- // explore a range of possible encodings based on a_fEffort (range = [0:100])
- // speed up process using a_uiJobs as the number of process threads (a_uiJobs must not excede a_uiMaxJobs)
- //
- Image::EncodingStatus Image::Encode(Format a_format, ErrorMetric a_errormetric, float a_fEffort, unsigned int a_uiJobs, unsigned int a_uiMaxJobs)
- {
-
- auto start = std::chrono::steady_clock::now();
-
- m_encodingStatus = EncodingStatus::SUCCESS;
-
- m_format = a_format;
- m_errormetric = a_errormetric;
- m_fEffort = a_fEffort;
-
- if (m_errormetric < 0 || m_errormetric > ERROR_METRICS)
- {
- AddToEncodingStatus(ERROR_UNKNOWN_ERROR_METRIC);
- return m_encodingStatus;
- }
-
- if (m_fEffort < ETCCOMP_MIN_EFFORT_LEVEL)
- {
- AddToEncodingStatus(WARNING_EFFORT_OUT_OF_RANGE);
- m_fEffort = ETCCOMP_MIN_EFFORT_LEVEL;
- }
- else if (m_fEffort > ETCCOMP_MAX_EFFORT_LEVEL)
- {
- AddToEncodingStatus(WARNING_EFFORT_OUT_OF_RANGE);
- m_fEffort = ETCCOMP_MAX_EFFORT_LEVEL;
- }
- if (a_uiJobs < 1)
- {
- a_uiJobs = 1;
- AddToEncodingStatus(WARNING_JOBS_OUT_OF_RANGE);
- }
- else if (a_uiJobs > a_uiMaxJobs)
- {
- a_uiJobs = a_uiMaxJobs;
- AddToEncodingStatus(WARNING_JOBS_OUT_OF_RANGE);
- }
-
- m_encodingbitsformat = DetermineEncodingBitsFormat(m_format);
-
- if (m_encodingbitsformat == Block4x4EncodingBits::Format::UNKNOWN)
- {
- AddToEncodingStatus(ERROR_UNKNOWN_FORMAT);
- return m_encodingStatus;
- }
-
- assert(m_paucEncodingBits == nullptr);
- m_uiEncodingBitsBytes = GetNumberOfBlocks() * Block4x4EncodingBits::GetBytesPerBlock(m_encodingbitsformat);
- m_paucEncodingBits = new unsigned char[m_uiEncodingBitsBytes];
-
- InitBlocksAndBlockSorter();
-
-
- std::future<void> *handle = new std::future<void>[a_uiMaxJobs];
-
- unsigned int uiNumThreadsNeeded = 0;
- unsigned int uiUnfinishedBlocks = GetNumberOfBlocks();
-
- uiNumThreadsNeeded = (uiUnfinishedBlocks < a_uiJobs) ? uiUnfinishedBlocks : a_uiJobs;
-
- for (int i = 0; i < (int)uiNumThreadsNeeded - 1; i++)
- {
- handle[i] = async(std::launch::async, &Image::RunFirstPass, this, i, uiNumThreadsNeeded);
- }
-
- RunFirstPass(uiNumThreadsNeeded - 1, uiNumThreadsNeeded);
-
- for (int i = 0; i < (int)uiNumThreadsNeeded - 1; i++)
- {
- handle[i].get();
- }
-
- // perform effort-based encoding
- if (m_fEffort > ETCCOMP_MIN_EFFORT_LEVEL)
- {
- unsigned int uiFinishedBlocks = 0;
- unsigned int uiTotalEffortBlocks = static_cast<unsigned int>(roundf(0.01f * m_fEffort * GetNumberOfBlocks()));
-
- if (m_bVerboseOutput)
- {
- printf("effortblocks = %d\n", uiTotalEffortBlocks);
- }
- unsigned int uiPass = 0;
- while (1)
- {
- if (m_bVerboseOutput)
- {
- uiPass++;
- printf("pass %u\n", uiPass);
- }
- m_psortedblocklist->Sort();
- uiUnfinishedBlocks = m_psortedblocklist->GetNumberOfSortedBlocks();
- uiFinishedBlocks = GetNumberOfBlocks() - uiUnfinishedBlocks;
- if (m_bVerboseOutput)
- {
- printf(" %u unfinished blocks\n", uiUnfinishedBlocks);
- // m_psortedblocklist->Print();
- }
-
-
-
- //stop enocding when we did enough to satify the effort percentage
- if (uiFinishedBlocks >= uiTotalEffortBlocks)
- {
- if (m_bVerboseOutput)
- {
- printf("Finished %d Blocks out of %d\n", uiFinishedBlocks, uiTotalEffortBlocks);
- }
- break;
- }
-
- unsigned int uiIteratedBlocks = 0;
- unsigned int blocksToIterateThisPass = (uiTotalEffortBlocks - uiFinishedBlocks);
- uiNumThreadsNeeded = (uiUnfinishedBlocks < a_uiJobs) ? uiUnfinishedBlocks : a_uiJobs;
-
- if (uiNumThreadsNeeded <= 1)
- {
- //since we already how many blocks each thread will process
- //cap the thread limit to do the proper amount of work, and not more
- uiIteratedBlocks = IterateThroughWorstBlocks(blocksToIterateThisPass, 0, 1);
- }
- else
- {
- //we have a lot of work to do, so lets multi thread it
- std::future<unsigned int> *handleToBlockEncoders = new std::future<unsigned int>[uiNumThreadsNeeded-1];
-
- for (int i = 0; i < (int)uiNumThreadsNeeded - 1; i++)
- {
- handleToBlockEncoders[i] = async(std::launch::async, &Image::IterateThroughWorstBlocks, this, blocksToIterateThisPass, i, uiNumThreadsNeeded);
- }
- uiIteratedBlocks = IterateThroughWorstBlocks(blocksToIterateThisPass, uiNumThreadsNeeded - 1, uiNumThreadsNeeded);
-
- for (int i = 0; i < (int)uiNumThreadsNeeded - 1; i++)
- {
- uiIteratedBlocks += handleToBlockEncoders[i].get();
- }
-
- delete[] handleToBlockEncoders;
- }
-
- if (m_bVerboseOutput)
- {
- printf(" %u iterated blocks\n", uiIteratedBlocks);
- }
- }
- }
-
- // generate Etc2-compatible bit-format 4x4 blocks
- for (int i = 0; i < (int)a_uiJobs - 1; i++)
- {
- handle[i] = async(std::launch::async, &Image::SetEncodingBits, this, i, a_uiJobs);
- }
- SetEncodingBits(a_uiJobs - 1, a_uiJobs);
-
- for (int i = 0; i < (int)a_uiJobs - 1; i++)
- {
- handle[i].get();
- }
-
- auto end = std::chrono::steady_clock::now();
- std::chrono::milliseconds elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
- m_iEncodeTime_ms = (int)elapsed.count();
-
- delete[] handle;
- delete m_psortedblocklist;
- return m_encodingStatus;
- }
-
- // ----------------------------------------------------------------------------------------------------
- // iterate the encoding thru the blocks with the worst error
- // stop when a_uiMaxBlocks blocks have been iterated
- // split the blocks between the process threads using a_uiMultithreadingOffset and a_uiMultithreadingStride
- //
- unsigned int Image::IterateThroughWorstBlocks(unsigned int a_uiMaxBlocks,
- unsigned int a_uiMultithreadingOffset,
- unsigned int a_uiMultithreadingStride)
- {
- assert(a_uiMultithreadingStride > 0);
- unsigned int uiIteratedBlocks = a_uiMultithreadingOffset;
-
- SortedBlockList::Link *plink = m_psortedblocklist->GetLinkToFirstBlock();
- for (plink = plink->Advance(a_uiMultithreadingOffset);
- plink != nullptr;
- plink = plink->Advance(a_uiMultithreadingStride) )
- {
- if (uiIteratedBlocks >= a_uiMaxBlocks)
- {
- break;
- }
-
- plink->GetBlock()->PerformEncodingIteration(m_fEffort);
-
- uiIteratedBlocks += a_uiMultithreadingStride;
- }
-
- return uiIteratedBlocks;
- }
-
- // ----------------------------------------------------------------------------------------------------
- // determine which warnings to check for during Encode() based on encoding format
- //
- void Image::FindEncodingWarningTypesForCurFormat()
- {
- TrackEncodingWarning(WARNING_ALL_TRANSPARENT_PIXELS);
- TrackEncodingWarning(WARNING_SOME_RGBA_NOT_0_TO_1);
- switch (m_format)
- {
- case Image::Format::ETC1:
- case Image::Format::RGB8:
- case Image::Format::SRGB8:
- TrackEncodingWarning(WARNING_SOME_NON_OPAQUE_PIXELS);
- TrackEncodingWarning(WARNING_SOME_TRANSLUCENT_PIXELS);
- break;
-
- case Image::Format::RGB8A1:
- case Image::Format::SRGB8A1:
- TrackEncodingWarning(WARNING_SOME_TRANSLUCENT_PIXELS);
- TrackEncodingWarning(WARNING_ALL_OPAQUE_PIXELS);
- break;
- case Image::Format::RGBA8:
- case Image::Format::SRGBA8:
- TrackEncodingWarning(WARNING_ALL_OPAQUE_PIXELS);
- break;
-
- case Image::Format::R11:
- case Image::Format::SIGNED_R11:
- TrackEncodingWarning(WARNING_SOME_NON_OPAQUE_PIXELS);
- TrackEncodingWarning(WARNING_SOME_TRANSLUCENT_PIXELS);
- TrackEncodingWarning(WARNING_SOME_GREEN_VALUES_ARE_NOT_ZERO);
- TrackEncodingWarning(WARNING_SOME_BLUE_VALUES_ARE_NOT_ZERO);
- break;
-
- case Image::Format::RG11:
- case Image::Format::SIGNED_RG11:
- TrackEncodingWarning(WARNING_SOME_NON_OPAQUE_PIXELS);
- TrackEncodingWarning(WARNING_SOME_TRANSLUCENT_PIXELS);
- TrackEncodingWarning(WARNING_SOME_BLUE_VALUES_ARE_NOT_ZERO);
- break;
- case Image::Format::FORMATS:
- case Image::Format::UNKNOWN:
- default:
- assert(0);
- break;
- }
- }
-
- // ----------------------------------------------------------------------------------------------------
- // examine source pixels to check for warnings
- //
- void Image::FindAndSetEncodingWarnings()
- {
- int numPixels = (m_uiBlockRows * 4) * (m_uiBlockColumns * 4);
- if (m_iNumOpaquePixels == numPixels)
- {
- AddToEncodingStatusIfSignfigant(Image::EncodingStatus::WARNING_ALL_OPAQUE_PIXELS);
- }
- if (m_iNumOpaquePixels < numPixels)
- {
- AddToEncodingStatusIfSignfigant(Image::EncodingStatus::WARNING_SOME_NON_OPAQUE_PIXELS);
- }
- if (m_iNumTranslucentPixels > 0)
- {
- AddToEncodingStatusIfSignfigant(Image::EncodingStatus::WARNING_SOME_TRANSLUCENT_PIXELS);
- }
- if (m_iNumTransparentPixels == numPixels)
- {
- AddToEncodingStatusIfSignfigant(Image::EncodingStatus::WARNING_ALL_TRANSPARENT_PIXELS);
- }
- if (m_numColorValues.fB > 0.0f)
- {
- AddToEncodingStatusIfSignfigant(Image::EncodingStatus::WARNING_SOME_BLUE_VALUES_ARE_NOT_ZERO);
- }
- if (m_numColorValues.fG > 0.0f)
- {
- AddToEncodingStatusIfSignfigant(Image::EncodingStatus::WARNING_SOME_GREEN_VALUES_ARE_NOT_ZERO);
- }
-
- if (m_numOutOfRangeValues.fR > 0.0f || m_numOutOfRangeValues.fG > 0.0f)
- {
- AddToEncodingStatusIfSignfigant(Image::EncodingStatus::WARNING_SOME_RGBA_NOT_0_TO_1);
- }
- if (m_numOutOfRangeValues.fB > 0.0f || m_numOutOfRangeValues.fA > 0.0f)
- {
- AddToEncodingStatusIfSignfigant(Image::EncodingStatus::WARNING_SOME_RGBA_NOT_0_TO_1);
- }
- }
-
- // ----------------------------------------------------------------------------------------------------
- // return a string name for a given image format
- //
- const char * Image::EncodingFormatToString(Image::Format a_format)
- {
- switch (a_format)
- {
- case Image::Format::ETC1:
- return "ETC1";
- case Image::Format::RGB8:
- return "RGB8";
- case Image::Format::SRGB8:
- return "SRGB8";
-
- case Image::Format::RGB8A1:
- return "RGB8A1";
- case Image::Format::SRGB8A1:
- return "SRGB8A1";
- case Image::Format::RGBA8:
- return "RGBA8";
- case Image::Format::SRGBA8:
- return "SRGBA8";
-
- case Image::Format::R11:
- return "R11";
- case Image::Format::SIGNED_R11:
- return "SIGNED_R11";
-
- case Image::Format::RG11:
- return "RG11";
- case Image::Format::SIGNED_RG11:
- return "SIGNED_RG11";
- case Image::Format::FORMATS:
- case Image::Format::UNKNOWN:
- default:
- return "UNKNOWN";
- }
- }
-
- // ----------------------------------------------------------------------------------------------------
- // return a string name for the image's format
- //
- const char * Image::EncodingFormatToString(void)
- {
- return EncodingFormatToString(m_format);
- }
-
- // ----------------------------------------------------------------------------------------------------
- // init image blocks prior to encoding
- // init block sorter for subsequent sortings
- // check for encoding warnings
- //
- void Image::InitBlocksAndBlockSorter(void)
- {
-
- FindEncodingWarningTypesForCurFormat();
-
- // init each block
- Block4x4 *pblock = m_pablock;
- unsigned char *paucEncodingBits = m_paucEncodingBits;
- for (unsigned int uiBlockRow = 0; uiBlockRow < m_uiBlockRows; uiBlockRow++)
- {
- unsigned int uiBlockV = uiBlockRow * 4;
-
- for (unsigned int uiBlockColumn = 0; uiBlockColumn < m_uiBlockColumns; uiBlockColumn++)
- {
- unsigned int uiBlockH = uiBlockColumn * 4;
-
- pblock->InitFromSource(this, uiBlockH, uiBlockV, paucEncodingBits, m_errormetric);
-
- paucEncodingBits += Block4x4EncodingBits::GetBytesPerBlock(m_encodingbitsformat);
-
- pblock++;
- }
- }
-
- FindAndSetEncodingWarnings();
-
- // init block sorter
- {
- m_psortedblocklist = new SortedBlockList(GetNumberOfBlocks(), 100);
-
- for (unsigned int uiBlock = 0; uiBlock < GetNumberOfBlocks(); uiBlock++)
- {
- pblock = &m_pablock[uiBlock];
- m_psortedblocklist->AddBlock(pblock);
- }
- }
-
- }
-
- // ----------------------------------------------------------------------------------------------------
- // run the first pass of the encoder
- // the encoder generally finds a reasonable, fast encoding
- // this is run on all blocks regardless of effort to ensure that all blocks have a valid encoding
- //
- void Image::RunFirstPass(unsigned int a_uiMultithreadingOffset, unsigned int a_uiMultithreadingStride)
- {
- assert(a_uiMultithreadingStride > 0);
-
- for (unsigned int uiBlock = a_uiMultithreadingOffset;
- uiBlock < GetNumberOfBlocks();
- uiBlock += a_uiMultithreadingStride)
- {
- Block4x4 *pblock = &m_pablock[uiBlock];
- pblock->PerformEncodingIteration(m_fEffort);
- }
- }
-
- // ----------------------------------------------------------------------------------------------------
- // set the encoding bits (for the output file) based on the best encoding for each block
- //
- void Image::SetEncodingBits(unsigned int a_uiMultithreadingOffset,
- unsigned int a_uiMultithreadingStride)
- {
- assert(a_uiMultithreadingStride > 0);
-
- for (unsigned int uiBlock = a_uiMultithreadingOffset;
- uiBlock < GetNumberOfBlocks();
- uiBlock += a_uiMultithreadingStride)
- {
- Block4x4 *pblock = &m_pablock[uiBlock];
- pblock->SetEncodingBitsFromEncoding();
- }
-
- }
-
- // ----------------------------------------------------------------------------------------------------
- // return the image error
- // image error is the sum of all block errors
- //
- float Image::GetError(void)
- {
- float fError = 0.0f;
-
- for (unsigned int uiBlock = 0; uiBlock < GetNumberOfBlocks(); uiBlock++)
- {
- Block4x4 *pblock = &m_pablock[uiBlock];
- fError += pblock->GetError();
- }
-
- return fError;
- }
-
- // ----------------------------------------------------------------------------------------------------
- // determine the encoding bits format based on the encoding format
- // the encoding bits format is a family of bit encodings that are shared across various encoding formats
- //
- Block4x4EncodingBits::Format Image::DetermineEncodingBitsFormat(Format a_format)
- {
- Block4x4EncodingBits::Format encodingbitsformat;
-
- // determine encoding bits format from image format
- switch (a_format)
- {
- case Format::ETC1:
- case Format::RGB8:
- case Format::SRGB8:
- encodingbitsformat = Block4x4EncodingBits::Format::RGB8;
- break;
-
- case Format::RGBA8:
- case Format::SRGBA8:
- encodingbitsformat = Block4x4EncodingBits::Format::RGBA8;
- break;
-
- case Format::R11:
- case Format::SIGNED_R11:
- encodingbitsformat = Block4x4EncodingBits::Format::R11;
- break;
-
- case Format::RG11:
- case Format::SIGNED_RG11:
- encodingbitsformat = Block4x4EncodingBits::Format::RG11;
- break;
-
- case Format::RGB8A1:
- case Format::SRGB8A1:
- encodingbitsformat = Block4x4EncodingBits::Format::RGB8A1;
- break;
-
- default:
- encodingbitsformat = Block4x4EncodingBits::Format::UNKNOWN;
- break;
- }
-
- return encodingbitsformat;
- }
-
- // ----------------------------------------------------------------------------------------------------
- //
-
-} // namespace Etc