| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819 |
- /*
- * 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.
- */
- /*
- EtcBlock4x4Encoding_RGB8A1.cpp contains:
- Block4x4Encoding_RGB8A1
- Block4x4Encoding_RGB8A1_Opaque
- Block4x4Encoding_RGB8A1_Transparent
- These encoders are used when targetting file format RGB8A1.
- Block4x4Encoding_RGB8A1_Opaque is used when all pixels in the 4x4 block are opaque
- Block4x4Encoding_RGB8A1_Transparent is used when all pixels in the 4x4 block are transparent
- Block4x4Encoding_RGB8A1 is used when there is a mixture of alphas in the 4x4 block
- */
- #include "EtcConfig.h"
- #include "EtcBlock4x4Encoding_RGB8A1.h"
- #include "EtcBlock4x4.h"
- #include "EtcBlock4x4EncodingBits.h"
- #include "EtcBlock4x4Encoding_RGB8.h"
- #include <stdio.h>
- #include <string.h>
- #include <assert.h>
- namespace Etc
- {
-
- // ####################################################################################################
- // Block4x4Encoding_RGB8A1
- // ####################################################################################################
- float Block4x4Encoding_RGB8A1::s_aafCwOpaqueUnsetTable[CW_RANGES][SELECTORS] =
- {
- { 0.0f / 255.0f, 8.0f / 255.0f, 0.0f / 255.0f, -8.0f / 255.0f },
- { 0.0f / 255.0f, 17.0f / 255.0f, 0.0f / 255.0f, -17.0f / 255.0f },
- { 0.0f / 255.0f, 29.0f / 255.0f, 0.0f / 255.0f, -29.0f / 255.0f },
- { 0.0f / 255.0f, 42.0f / 255.0f, 0.0f / 255.0f, -42.0f / 255.0f },
- { 0.0f / 255.0f, 60.0f / 255.0f, 0.0f / 255.0f, -60.0f / 255.0f },
- { 0.0f / 255.0f, 80.0f / 255.0f, 0.0f / 255.0f, -80.0f / 255.0f },
- { 0.0f / 255.0f, 106.0f / 255.0f, 0.0f / 255.0f, -106.0f / 255.0f },
- { 0.0f / 255.0f, 183.0f / 255.0f, 0.0f / 255.0f, -183.0f / 255.0f }
- };
- // ----------------------------------------------------------------------------------------------------
- //
- Block4x4Encoding_RGB8A1::Block4x4Encoding_RGB8A1(void)
- {
- m_pencodingbitsRGB8 = nullptr;
- m_boolOpaque = false;
- m_boolTransparent = false;
- m_boolPunchThroughPixels = true;
- }
- Block4x4Encoding_RGB8A1::~Block4x4Encoding_RGB8A1(void) {}
- // ----------------------------------------------------------------------------------------------------
- // initialization prior to encoding
- // a_pblockParent points to the block associated with this encoding
- // a_errormetric is used to choose the best encoding
- // a_pafrgbaSource points to a 4x4 block subset of the source image
- // a_paucEncodingBits points to the final encoding bits
- //
- void Block4x4Encoding_RGB8A1::InitFromSource(Block4x4 *a_pblockParent,
- ColorFloatRGBA *a_pafrgbaSource,
- unsigned char *a_paucEncodingBits,
- ErrorMetric a_errormetric)
- {
- Block4x4Encoding_RGB8::InitFromSource(a_pblockParent,
- a_pafrgbaSource,
- a_paucEncodingBits,
- a_errormetric);
- m_boolOpaque = a_pblockParent->GetSourceAlphaMix() == Block4x4::SourceAlphaMix::OPAQUE;
- m_boolTransparent = a_pblockParent->GetSourceAlphaMix() == Block4x4::SourceAlphaMix::TRANSPARENT;
- m_boolPunchThroughPixels = a_pblockParent->HasPunchThroughPixels();
- for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
- {
- if (m_pafrgbaSource[uiPixel].fA >= 0.5f)
- {
- m_afDecodedAlphas[uiPixel] = 1.0f;
- }
- else
- {
- m_afDecodedAlphas[uiPixel] = 0.0f;
- }
- }
- }
- // ----------------------------------------------------------------------------------------------------
- // initialization from the encoding bits of a previous encoding
- // a_pblockParent points to the block associated with this encoding
- // a_errormetric is used to choose the best encoding
- // a_pafrgbaSource points to a 4x4 block subset of the source image
- // a_paucEncodingBits points to the final encoding bits of a previous encoding
- //
- void Block4x4Encoding_RGB8A1::InitFromEncodingBits(Block4x4 *a_pblockParent,
- unsigned char *a_paucEncodingBits,
- ColorFloatRGBA *a_pafrgbaSource,
- ErrorMetric a_errormetric)
- {
- InitFromEncodingBits_ETC1(a_pblockParent,
- a_paucEncodingBits,
- a_pafrgbaSource,
- a_errormetric);
- m_pencodingbitsRGB8 = (Block4x4EncodingBits_RGB8 *)a_paucEncodingBits;
- // detect if there is a T, H or Planar mode present
- int iRed1 = m_pencodingbitsRGB8->differential.red1;
- int iDRed2 = m_pencodingbitsRGB8->differential.dred2;
- int iRed2 = iRed1 + iDRed2;
- int iGreen1 = m_pencodingbitsRGB8->differential.green1;
- int iDGreen2 = m_pencodingbitsRGB8->differential.dgreen2;
- int iGreen2 = iGreen1 + iDGreen2;
- int iBlue1 = m_pencodingbitsRGB8->differential.blue1;
- int iDBlue2 = m_pencodingbitsRGB8->differential.dblue2;
- int iBlue2 = iBlue1 + iDBlue2;
- if (iRed2 < 0 || iRed2 > 31)
- {
- InitFromEncodingBits_T();
- }
- else if (iGreen2 < 0 || iGreen2 > 31)
- {
- InitFromEncodingBits_H();
- }
- else if (iBlue2 < 0 || iBlue2 > 31)
- {
- Block4x4Encoding_RGB8::InitFromEncodingBits_Planar();
- }
- }
- // ----------------------------------------------------------------------------------------------------
- // initialization from the encoding bits of a previous encoding assuming the encoding is an ETC1 mode.
- // if it isn't an ETC1 mode, this will be overwritten later
- //
- void Block4x4Encoding_RGB8A1::InitFromEncodingBits_ETC1(Block4x4 *a_pblockParent,
- unsigned char *a_paucEncodingBits,
- ColorFloatRGBA *a_pafrgbaSource,
- ErrorMetric a_errormetric)
- {
- Block4x4Encoding::Init(a_pblockParent, a_pafrgbaSource,
- a_errormetric);
- m_pencodingbitsRGB8 = (Block4x4EncodingBits_RGB8 *)a_paucEncodingBits;
- m_mode = MODE_ETC1;
- m_boolDiff = true;
- m_boolFlip = m_pencodingbitsRGB8->differential.flip;
- m_boolOpaque = m_pencodingbitsRGB8->differential.diff;
- int iR2 = m_pencodingbitsRGB8->differential.red1 + m_pencodingbitsRGB8->differential.dred2;
- if (iR2 < 0)
- {
- iR2 = 0;
- }
- else if (iR2 > 31)
- {
- iR2 = 31;
- }
- int iG2 = m_pencodingbitsRGB8->differential.green1 + m_pencodingbitsRGB8->differential.dgreen2;
- if (iG2 < 0)
- {
- iG2 = 0;
- }
- else if (iG2 > 31)
- {
- iG2 = 31;
- }
- int iB2 = m_pencodingbitsRGB8->differential.blue1 + m_pencodingbitsRGB8->differential.dblue2;
- if (iB2 < 0)
- {
- iB2 = 0;
- }
- else if (iB2 > 31)
- {
- iB2 = 31;
- }
- m_frgbaColor1 = ColorFloatRGBA::ConvertFromRGB5(m_pencodingbitsRGB8->differential.red1, m_pencodingbitsRGB8->differential.green1, m_pencodingbitsRGB8->differential.blue1);
- m_frgbaColor2 = ColorFloatRGBA::ConvertFromRGB5((unsigned char)iR2, (unsigned char)iG2, (unsigned char)iB2);
- m_uiCW1 = m_pencodingbitsRGB8->differential.cw1;
- m_uiCW2 = m_pencodingbitsRGB8->differential.cw2;
- Block4x4Encoding_ETC1::InitFromEncodingBits_Selectors();
- Decode_ETC1();
- CalcBlockError();
- }
- // ----------------------------------------------------------------------------------------------------
- // initialization from the encoding bits of a previous encoding if T mode is detected
- //
- void Block4x4Encoding_RGB8A1::InitFromEncodingBits_T(void)
- {
- m_mode = MODE_T;
- unsigned char ucRed1 = (unsigned char)((m_pencodingbitsRGB8->t.red1a << 2) +
- m_pencodingbitsRGB8->t.red1b);
- unsigned char ucGreen1 = m_pencodingbitsRGB8->t.green1;
- unsigned char ucBlue1 = m_pencodingbitsRGB8->t.blue1;
- unsigned char ucRed2 = m_pencodingbitsRGB8->t.red2;
- unsigned char ucGreen2 = m_pencodingbitsRGB8->t.green2;
- unsigned char ucBlue2 = m_pencodingbitsRGB8->t.blue2;
- m_frgbaColor1 = ColorFloatRGBA::ConvertFromRGB4(ucRed1, ucGreen1, ucBlue1);
- m_frgbaColor2 = ColorFloatRGBA::ConvertFromRGB4(ucRed2, ucGreen2, ucBlue2);
- m_uiCW1 = (m_pencodingbitsRGB8->t.da << 1) + m_pencodingbitsRGB8->t.db;
- Block4x4Encoding_ETC1::InitFromEncodingBits_Selectors();
- DecodePixels_T();
- CalcBlockError();
- }
- // ----------------------------------------------------------------------------------------------------
- // initialization from the encoding bits of a previous encoding if H mode is detected
- //
- void Block4x4Encoding_RGB8A1::InitFromEncodingBits_H(void)
- {
- m_mode = MODE_H;
- unsigned char ucRed1 = m_pencodingbitsRGB8->h.red1;
- unsigned char ucGreen1 = (unsigned char)((m_pencodingbitsRGB8->h.green1a << 1) +
- m_pencodingbitsRGB8->h.green1b);
- unsigned char ucBlue1 = (unsigned char)((m_pencodingbitsRGB8->h.blue1a << 3) +
- (m_pencodingbitsRGB8->h.blue1b << 1) +
- m_pencodingbitsRGB8->h.blue1c);
- unsigned char ucRed2 = m_pencodingbitsRGB8->h.red2;
- unsigned char ucGreen2 = (unsigned char)((m_pencodingbitsRGB8->h.green2a << 1) +
- m_pencodingbitsRGB8->h.green2b);
- unsigned char ucBlue2 = m_pencodingbitsRGB8->h.blue2;
- m_frgbaColor1 = ColorFloatRGBA::ConvertFromRGB4(ucRed1, ucGreen1, ucBlue1);
- m_frgbaColor2 = ColorFloatRGBA::ConvertFromRGB4(ucRed2, ucGreen2, ucBlue2);
- // used to determine the LSB of the CW
- unsigned int uiRGB1 = (unsigned int)(((int)ucRed1 << 16) + ((int)ucGreen1 << 8) + (int)ucBlue1);
- unsigned int uiRGB2 = (unsigned int)(((int)ucRed2 << 16) + ((int)ucGreen2 << 8) + (int)ucBlue2);
- m_uiCW1 = (m_pencodingbitsRGB8->h.da << 2) + (m_pencodingbitsRGB8->h.db << 1);
- if (uiRGB1 >= uiRGB2)
- {
- m_uiCW1++;
- }
- Block4x4Encoding_ETC1::InitFromEncodingBits_Selectors();
- DecodePixels_H();
- CalcBlockError();
- }
- // ----------------------------------------------------------------------------------------------------
- // for ETC1 modes, set the decoded colors and decoded alpha based on the encoding state
- //
- void Block4x4Encoding_RGB8A1::Decode_ETC1(void)
- {
- const unsigned int *pauiPixelOrder = m_boolFlip ? s_auiPixelOrderFlip1 : s_auiPixelOrderFlip0;
- for (unsigned int uiPixelOrder = 0; uiPixelOrder < PIXELS; uiPixelOrder++)
- {
- ColorFloatRGBA *pfrgbaCenter = uiPixelOrder < 8 ? &m_frgbaColor1 : &m_frgbaColor2;
- unsigned int uiCW = uiPixelOrder < 8 ? m_uiCW1 : m_uiCW2;
- unsigned int uiPixel = pauiPixelOrder[uiPixelOrder];
- float fDelta;
- if (m_boolOpaque)
- fDelta = Block4x4Encoding_ETC1::s_aafCwTable[uiCW][m_auiSelectors[uiPixel]];
- else
- fDelta = s_aafCwOpaqueUnsetTable[uiCW][m_auiSelectors[uiPixel]];
- if (m_boolOpaque == false && m_auiSelectors[uiPixel] == TRANSPARENT_SELECTOR)
- {
- m_afrgbaDecodedColors[uiPixel] = ColorFloatRGBA();
- m_afDecodedAlphas[uiPixel] = 0.0f;
- }
- else
- {
- m_afrgbaDecodedColors[uiPixel] = (*pfrgbaCenter + fDelta).ClampRGB();
- m_afDecodedAlphas[uiPixel] = 1.0f;
- }
- }
- }
- // ----------------------------------------------------------------------------------------------------
- // for T mode, set the decoded colors and decoded alpha based on the encoding state
- //
- void Block4x4Encoding_RGB8A1::DecodePixels_T(void)
- {
- float fDistance = s_afTHDistanceTable[m_uiCW1];
- ColorFloatRGBA frgbaDistance(fDistance, fDistance, fDistance, 0.0f);
- for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
- {
- switch (m_auiSelectors[uiPixel])
- {
- case 0:
- m_afrgbaDecodedColors[uiPixel] = m_frgbaColor1;
- m_afDecodedAlphas[uiPixel] = 1.0f;
- break;
- case 1:
- m_afrgbaDecodedColors[uiPixel] = (m_frgbaColor2 + frgbaDistance).ClampRGB();
- m_afDecodedAlphas[uiPixel] = 1.0f;
- break;
- case 2:
- if (m_boolOpaque == false)
- {
- m_afrgbaDecodedColors[uiPixel] = ColorFloatRGBA();
- m_afDecodedAlphas[uiPixel] = 0.0f;
- }
- else
- {
- m_afrgbaDecodedColors[uiPixel] = m_frgbaColor2;
- m_afDecodedAlphas[uiPixel] = 1.0f;
- }
- break;
- case 3:
- m_afrgbaDecodedColors[uiPixel] = (m_frgbaColor2 - frgbaDistance).ClampRGB();
- m_afDecodedAlphas[uiPixel] = 1.0f;
- break;
- }
- }
- }
- // ----------------------------------------------------------------------------------------------------
- // for H mode, set the decoded colors and decoded alpha based on the encoding state
- //
- void Block4x4Encoding_RGB8A1::DecodePixels_H(void)
- {
- float fDistance = s_afTHDistanceTable[m_uiCW1];
- ColorFloatRGBA frgbaDistance(fDistance, fDistance, fDistance, 0.0f);
- for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
- {
- switch (m_auiSelectors[uiPixel])
- {
- case 0:
- m_afrgbaDecodedColors[uiPixel] = (m_frgbaColor1 + frgbaDistance).ClampRGB();
- m_afDecodedAlphas[uiPixel] = 1.0f;
- break;
- case 1:
- m_afrgbaDecodedColors[uiPixel] = (m_frgbaColor1 - frgbaDistance).ClampRGB();
- m_afDecodedAlphas[uiPixel] = 1.0f;
- break;
- case 2:
- if (m_boolOpaque == false)
- {
- m_afrgbaDecodedColors[uiPixel] = ColorFloatRGBA();
- m_afDecodedAlphas[uiPixel] = 0.0f;
- }
- else
- {
- m_afrgbaDecodedColors[uiPixel] = (m_frgbaColor2 + frgbaDistance).ClampRGB();
- m_afDecodedAlphas[uiPixel] = 1.0f;
- }
- break;
- case 3:
- m_afrgbaDecodedColors[uiPixel] = (m_frgbaColor2 - frgbaDistance).ClampRGB();
- m_afDecodedAlphas[uiPixel] = 1.0f;
- break;
- }
- }
- }
- // ----------------------------------------------------------------------------------------------------
- // perform a single encoding iteration
- // replace the encoding if a better encoding was found
- // subsequent iterations generally take longer for each iteration
- // set m_boolDone if encoding is perfect or encoding is finished based on a_fEffort
- //
- // RGB8A1 can't use individual mode
- // RGB8A1 with transparent pixels can't use planar mode
- //
- void Block4x4Encoding_RGB8A1::PerformIteration(float a_fEffort)
- {
- assert(!m_boolOpaque);
- assert(!m_boolTransparent);
- assert(!m_boolDone);
- switch (m_uiEncodingIterations)
- {
- case 0:
- PerformFirstIteration();
- break;
- case 1:
- TryDifferential(m_boolMostLikelyFlip, 1, 0, 0);
- break;
- case 2:
- TryDifferential(!m_boolMostLikelyFlip, 1, 0, 0);
- if (a_fEffort <= 39.5f)
- {
- m_boolDone = true;
- }
- break;
- case 3:
- Block4x4Encoding_RGB8::CalculateBaseColorsForTAndH();
- TryT(1);
- TryH(1);
- if (a_fEffort <= 49.5f)
- {
- m_boolDone = true;
- }
- break;
- case 4:
- TryDegenerates1();
- if (a_fEffort <= 59.5f)
- {
- m_boolDone = true;
- }
- break;
- case 5:
- TryDegenerates2();
- if (a_fEffort <= 69.5f)
- {
- m_boolDone = true;
- }
- break;
- case 6:
- TryDegenerates3();
- if (a_fEffort <= 79.5f)
- {
- m_boolDone = true;
- }
- break;
- case 7:
- TryDegenerates4();
- m_boolDone = true;
- break;
- default:
- assert(0);
- break;
- }
- m_uiEncodingIterations++;
- SetDoneIfPerfect();
- }
- // ----------------------------------------------------------------------------------------------------
- // find best initial encoding to ensure block has a valid encoding
- //
- void Block4x4Encoding_RGB8A1::PerformFirstIteration(void)
- {
- Block4x4Encoding_ETC1::CalculateMostLikelyFlip();
- m_fError = FLT_MAX;
- TryDifferential(m_boolMostLikelyFlip, 0, 0, 0);
- SetDoneIfPerfect();
- if (m_boolDone)
- {
- return;
- }
- TryDifferential(!m_boolMostLikelyFlip, 0, 0, 0);
- SetDoneIfPerfect();
- }
- // ----------------------------------------------------------------------------------------------------
- // mostly copied from ETC1
- // differences:
- // Block4x4Encoding_RGB8A1 encodingTry = *this;
- //
- void Block4x4Encoding_RGB8A1::TryDifferential(bool a_boolFlip, unsigned int a_uiRadius,
- int a_iGrayOffset1, int a_iGrayOffset2)
- {
- ColorFloatRGBA frgbaColor1;
- ColorFloatRGBA frgbaColor2;
- const unsigned int *pauiPixelMapping1;
- const unsigned int *pauiPixelMapping2;
- if (a_boolFlip)
- {
- frgbaColor1 = m_frgbaSourceAverageTop;
- frgbaColor2 = m_frgbaSourceAverageBottom;
- pauiPixelMapping1 = s_auiTopPixelMapping;
- pauiPixelMapping2 = s_auiBottomPixelMapping;
- }
- else
- {
- frgbaColor1 = m_frgbaSourceAverageLeft;
- frgbaColor2 = m_frgbaSourceAverageRight;
- pauiPixelMapping1 = s_auiLeftPixelMapping;
- pauiPixelMapping2 = s_auiRightPixelMapping;
- }
- DifferentialTrys trys(frgbaColor1, frgbaColor2, pauiPixelMapping1, pauiPixelMapping2,
- a_uiRadius, a_iGrayOffset1, a_iGrayOffset2);
- Block4x4Encoding_RGB8A1 encodingTry = *this;
- encodingTry.m_boolFlip = a_boolFlip;
- encodingTry.TryDifferentialHalf(&trys.m_half1);
- encodingTry.TryDifferentialHalf(&trys.m_half2);
- // find best halves that are within differential range
- DifferentialTrys::Try *ptryBest1 = nullptr;
- DifferentialTrys::Try *ptryBest2 = nullptr;
- encodingTry.m_fError = FLT_MAX;
- // see if the best of each half are in differential range
- int iDRed = trys.m_half2.m_ptryBest->m_iRed - trys.m_half1.m_ptryBest->m_iRed;
- int iDGreen = trys.m_half2.m_ptryBest->m_iGreen - trys.m_half1.m_ptryBest->m_iGreen;
- int iDBlue = trys.m_half2.m_ptryBest->m_iBlue - trys.m_half1.m_ptryBest->m_iBlue;
- if (iDRed >= -4 && iDRed <= 3 && iDGreen >= -4 && iDGreen <= 3 && iDBlue >= -4 && iDBlue <= 3)
- {
- ptryBest1 = trys.m_half1.m_ptryBest;
- ptryBest2 = trys.m_half2.m_ptryBest;
- encodingTry.m_fError = trys.m_half1.m_ptryBest->m_fError + trys.m_half2.m_ptryBest->m_fError;
- }
- else
- {
- // else, find the next best halves that are in differential range
- for (DifferentialTrys::Try *ptry1 = &trys.m_half1.m_atry[0];
- ptry1 < &trys.m_half1.m_atry[trys.m_half1.m_uiTrys];
- ptry1++)
- {
- for (DifferentialTrys::Try *ptry2 = &trys.m_half2.m_atry[0];
- ptry2 < &trys.m_half2.m_atry[trys.m_half2.m_uiTrys];
- ptry2++)
- {
- iDRed = ptry2->m_iRed - ptry1->m_iRed;
- bool boolValidRedDelta = iDRed <= 3 && iDRed >= -4;
- iDGreen = ptry2->m_iGreen - ptry1->m_iGreen;
- bool boolValidGreenDelta = iDGreen <= 3 && iDGreen >= -4;
- iDBlue = ptry2->m_iBlue - ptry1->m_iBlue;
- bool boolValidBlueDelta = iDBlue <= 3 && iDBlue >= -4;
- if (boolValidRedDelta && boolValidGreenDelta && boolValidBlueDelta)
- {
- float fError = ptry1->m_fError + ptry2->m_fError;
- if (fError < encodingTry.m_fError)
- {
- encodingTry.m_fError = fError;
- ptryBest1 = ptry1;
- ptryBest2 = ptry2;
- }
- }
- }
- }
- assert(encodingTry.m_fError < FLT_MAX);
- assert(ptryBest1 != nullptr);
- assert(ptryBest2 != nullptr);
- }
- if (encodingTry.m_fError < m_fError)
- {
- m_mode = MODE_ETC1;
- m_boolDiff = true;
- m_boolFlip = encodingTry.m_boolFlip;
- m_frgbaColor1 = ColorFloatRGBA::ConvertFromRGB5((unsigned char)ptryBest1->m_iRed, (unsigned char)ptryBest1->m_iGreen, (unsigned char)ptryBest1->m_iBlue);
- m_frgbaColor2 = ColorFloatRGBA::ConvertFromRGB5((unsigned char)ptryBest2->m_iRed, (unsigned char)ptryBest2->m_iGreen, (unsigned char)ptryBest2->m_iBlue);
- m_uiCW1 = ptryBest1->m_uiCW;
- m_uiCW2 = ptryBest2->m_uiCW;
- m_fError = 0.0f;
- for (unsigned int uiPixelOrder = 0; uiPixelOrder < PIXELS / 2; uiPixelOrder++)
- {
- unsigned int uiPixel1 = pauiPixelMapping1[uiPixelOrder];
- unsigned int uiPixel2 = pauiPixelMapping2[uiPixelOrder];
- unsigned int uiSelector1 = ptryBest1->m_auiSelectors[uiPixelOrder];
- unsigned int uiSelector2 = ptryBest2->m_auiSelectors[uiPixelOrder];
- m_auiSelectors[uiPixel1] = uiSelector1;
- m_auiSelectors[uiPixel2] = ptryBest2->m_auiSelectors[uiPixelOrder];
- if (uiSelector1 == TRANSPARENT_SELECTOR)
- {
- m_afrgbaDecodedColors[uiPixel1] = ColorFloatRGBA();
- m_afDecodedAlphas[uiPixel1] = 0.0f;
- }
- else
- {
- float fDeltaRGB1 = s_aafCwOpaqueUnsetTable[m_uiCW1][uiSelector1];
- m_afrgbaDecodedColors[uiPixel1] = (m_frgbaColor1 + fDeltaRGB1).ClampRGB();
- m_afDecodedAlphas[uiPixel1] = 1.0f;
- }
- if (uiSelector2 == TRANSPARENT_SELECTOR)
- {
- m_afrgbaDecodedColors[uiPixel2] = ColorFloatRGBA();
- m_afDecodedAlphas[uiPixel2] = 0.0f;
- }
- else
- {
- float fDeltaRGB2 = s_aafCwOpaqueUnsetTable[m_uiCW2][uiSelector2];
- m_afrgbaDecodedColors[uiPixel2] = (m_frgbaColor2 + fDeltaRGB2).ClampRGB();
- m_afDecodedAlphas[uiPixel2] = 1.0f;
- }
- float fDeltaA1 = m_afDecodedAlphas[uiPixel1] - m_pafrgbaSource[uiPixel1].fA;
- m_fError += fDeltaA1 * fDeltaA1;
- float fDeltaA2 = m_afDecodedAlphas[uiPixel2] - m_pafrgbaSource[uiPixel2].fA;
- m_fError += fDeltaA2 * fDeltaA2;
- }
- m_fError1 = ptryBest1->m_fError;
- m_fError2 = ptryBest2->m_fError;
- m_boolSeverelyBentDifferentialColors = trys.m_boolSeverelyBentColors;
- m_fError = m_fError1 + m_fError2;
- // sanity check
- {
- int iRed1 = m_frgbaColor1.IntRed(31.0f);
- int iGreen1 = m_frgbaColor1.IntGreen(31.0f);
- int iBlue1 = m_frgbaColor1.IntBlue(31.0f);
- int iRed2 = m_frgbaColor2.IntRed(31.0f);
- int iGreen2 = m_frgbaColor2.IntGreen(31.0f);
- int iBlue2 = m_frgbaColor2.IntBlue(31.0f);
- iDRed = iRed2 - iRed1;
- iDGreen = iGreen2 - iGreen1;
- iDBlue = iBlue2 - iBlue1;
- assert(iDRed >= -4 && iDRed < 4);
- assert(iDGreen >= -4 && iDGreen < 4);
- assert(iDBlue >= -4 && iDBlue < 4);
- }
- }
- }
- // ----------------------------------------------------------------------------------------------------
- // mostly copied from ETC1
- // differences:
- // uses s_aafCwOpaqueUnsetTable
- // color for selector set to 0,0,0,0
- //
- void Block4x4Encoding_RGB8A1::TryDifferentialHalf(DifferentialTrys::Half *a_phalf)
- {
- a_phalf->m_ptryBest = nullptr;
- float fBestTryError = FLT_MAX;
- a_phalf->m_uiTrys = 0;
- for (int iRed = a_phalf->m_iRed - (int)a_phalf->m_uiRadius;
- iRed <= a_phalf->m_iRed + (int)a_phalf->m_uiRadius;
- iRed++)
- {
- assert(iRed >= 0 && iRed <= 31);
- for (int iGreen = a_phalf->m_iGreen - (int)a_phalf->m_uiRadius;
- iGreen <= a_phalf->m_iGreen + (int)a_phalf->m_uiRadius;
- iGreen++)
- {
- assert(iGreen >= 0 && iGreen <= 31);
- for (int iBlue = a_phalf->m_iBlue - (int)a_phalf->m_uiRadius;
- iBlue <= a_phalf->m_iBlue + (int)a_phalf->m_uiRadius;
- iBlue++)
- {
- assert(iBlue >= 0 && iBlue <= 31);
- DifferentialTrys::Try *ptry = &a_phalf->m_atry[a_phalf->m_uiTrys];
- assert(ptry < &a_phalf->m_atry[DifferentialTrys::Half::MAX_TRYS]);
- ptry->m_iRed = iRed;
- ptry->m_iGreen = iGreen;
- ptry->m_iBlue = iBlue;
- ptry->m_fError = FLT_MAX;
- ColorFloatRGBA frgbaColor = ColorFloatRGBA::ConvertFromRGB5((unsigned char)iRed, (unsigned char)iGreen, (unsigned char)iBlue);
- // try each CW
- for (unsigned int uiCW = 0; uiCW < CW_RANGES; uiCW++)
- {
- unsigned int auiPixelSelectors[PIXELS / 2];
- ColorFloatRGBA afrgbaDecodedColors[PIXELS / 2];
- float afPixelErrors[PIXELS / 2] = { FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX,
- FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX };
- // pre-compute decoded pixels for each selector
- ColorFloatRGBA afrgbaSelectors[SELECTORS];
- assert(SELECTORS == 4);
- afrgbaSelectors[0] = (frgbaColor + s_aafCwOpaqueUnsetTable[uiCW][0]).ClampRGB();
- afrgbaSelectors[1] = (frgbaColor + s_aafCwOpaqueUnsetTable[uiCW][1]).ClampRGB();
- afrgbaSelectors[2] = ColorFloatRGBA();
- afrgbaSelectors[3] = (frgbaColor + s_aafCwOpaqueUnsetTable[uiCW][3]).ClampRGB();
- for (unsigned int uiPixel = 0; uiPixel < 8; uiPixel++)
- {
- ColorFloatRGBA *pfrgbaSourcePixel = &m_pafrgbaSource[a_phalf->m_pauiPixelMapping[uiPixel]];
- ColorFloatRGBA frgbaDecodedPixel;
- for (unsigned int uiSelector = 0; uiSelector < SELECTORS; uiSelector++)
- {
- if (pfrgbaSourcePixel->fA < 0.5f)
- {
- uiSelector = TRANSPARENT_SELECTOR;
- }
- else if (uiSelector == TRANSPARENT_SELECTOR)
- {
- continue;
- }
- frgbaDecodedPixel = afrgbaSelectors[uiSelector];
- float fPixelError;
-
- fPixelError = CalcPixelError(frgbaDecodedPixel, m_afDecodedAlphas[a_phalf->m_pauiPixelMapping[uiPixel]],
- *pfrgbaSourcePixel);
- if (fPixelError < afPixelErrors[uiPixel])
- {
- auiPixelSelectors[uiPixel] = uiSelector;
- afrgbaDecodedColors[uiPixel] = frgbaDecodedPixel;
- afPixelErrors[uiPixel] = fPixelError;
- }
- if (uiSelector == TRANSPARENT_SELECTOR)
- {
- break;
- }
- }
- }
- // add up all pixel errors
- float fCWError = 0.0f;
- for (unsigned int uiPixel = 0; uiPixel < 8; uiPixel++)
- {
- fCWError += afPixelErrors[uiPixel];
- }
- // if best CW so far
- if (fCWError < ptry->m_fError)
- {
- ptry->m_uiCW = uiCW;
- for (unsigned int uiPixel = 0; uiPixel < 8; uiPixel++)
- {
- ptry->m_auiSelectors[uiPixel] = auiPixelSelectors[uiPixel];
- }
- ptry->m_fError = fCWError;
- }
- }
- if (ptry->m_fError < fBestTryError)
- {
- a_phalf->m_ptryBest = ptry;
- fBestTryError = ptry->m_fError;
- }
- assert(ptry->m_fError < FLT_MAX);
- a_phalf->m_uiTrys++;
- }
- }
- }
- }
- // ----------------------------------------------------------------------------------------------------
- // try encoding in T mode
- // save this encoding if it improves the error
- //
- // since pixels that use base color1 don't use the distance table, color1 and color2 can be twiddled independently
- // better encoding can be found if TWIDDLE_RADIUS is set to 2, but it will be much slower
- //
- void Block4x4Encoding_RGB8A1::TryT(unsigned int a_uiRadius)
- {
- Block4x4Encoding_RGB8A1 encodingTry = *this;
- // init "try"
- {
- encodingTry.m_mode = MODE_T;
- encodingTry.m_boolDiff = true;
- encodingTry.m_boolFlip = false;
- encodingTry.m_fError = FLT_MAX;
- }
- int iColor1Red = m_frgbaOriginalColor1_TAndH.IntRed(15.0f);
- int iColor1Green = m_frgbaOriginalColor1_TAndH.IntGreen(15.0f);
- int iColor1Blue = m_frgbaOriginalColor1_TAndH.IntBlue(15.0f);
- int iMinRed1 = iColor1Red - (int)a_uiRadius;
- if (iMinRed1 < 0)
- {
- iMinRed1 = 0;
- }
- int iMaxRed1 = iColor1Red + (int)a_uiRadius;
- if (iMaxRed1 > 15)
- {
- iMinRed1 = 15;
- }
- int iMinGreen1 = iColor1Green - (int)a_uiRadius;
- if (iMinGreen1 < 0)
- {
- iMinGreen1 = 0;
- }
- int iMaxGreen1 = iColor1Green + (int)a_uiRadius;
- if (iMaxGreen1 > 15)
- {
- iMinGreen1 = 15;
- }
- int iMinBlue1 = iColor1Blue - (int)a_uiRadius;
- if (iMinBlue1 < 0)
- {
- iMinBlue1 = 0;
- }
- int iMaxBlue1 = iColor1Blue + (int)a_uiRadius;
- if (iMaxBlue1 > 15)
- {
- iMinBlue1 = 15;
- }
- int iColor2Red = m_frgbaOriginalColor2_TAndH.IntRed(15.0f);
- int iColor2Green = m_frgbaOriginalColor2_TAndH.IntGreen(15.0f);
- int iColor2Blue = m_frgbaOriginalColor2_TAndH.IntBlue(15.0f);
- int iMinRed2 = iColor2Red - (int)a_uiRadius;
- if (iMinRed2 < 0)
- {
- iMinRed2 = 0;
- }
- int iMaxRed2 = iColor2Red + (int)a_uiRadius;
- if (iMaxRed2 > 15)
- {
- iMinRed2 = 15;
- }
- int iMinGreen2 = iColor2Green - (int)a_uiRadius;
- if (iMinGreen2 < 0)
- {
- iMinGreen2 = 0;
- }
- int iMaxGreen2 = iColor2Green + (int)a_uiRadius;
- if (iMaxGreen2 > 15)
- {
- iMinGreen2 = 15;
- }
- int iMinBlue2 = iColor2Blue - (int)a_uiRadius;
- if (iMinBlue2 < 0)
- {
- iMinBlue2 = 0;
- }
- int iMaxBlue2 = iColor2Blue + (int)a_uiRadius;
- if (iMaxBlue2 > 15)
- {
- iMinBlue2 = 15;
- }
- for (unsigned int uiDistance = 0; uiDistance < TH_DISTANCES; uiDistance++)
- {
- encodingTry.m_uiCW1 = uiDistance;
- // twiddle m_frgbaOriginalColor2_TAndH
- // twiddle color2 first, since it affects 3 selectors, while color1 only affects one selector
- //
- for (int iRed2 = iMinRed2; iRed2 <= iMaxRed2; iRed2++)
- {
- for (int iGreen2 = iMinGreen2; iGreen2 <= iMaxGreen2; iGreen2++)
- {
- for (int iBlue2 = iMinBlue2; iBlue2 <= iMaxBlue2; iBlue2++)
- {
- for (unsigned int uiBaseColorSwaps = 0; uiBaseColorSwaps < 2; uiBaseColorSwaps++)
- {
- if (uiBaseColorSwaps == 0)
- {
- encodingTry.m_frgbaColor1 = m_frgbaOriginalColor1_TAndH;
- encodingTry.m_frgbaColor2 = ColorFloatRGBA::ConvertFromRGB4((unsigned char)iRed2, (unsigned char)iGreen2, (unsigned char)iBlue2);
- }
- else
- {
- encodingTry.m_frgbaColor1 = ColorFloatRGBA::ConvertFromRGB4((unsigned char)iRed2, (unsigned char)iGreen2, (unsigned char)iBlue2);
- encodingTry.m_frgbaColor2 = m_frgbaOriginalColor1_TAndH;
- }
- encodingTry.TryT_BestSelectorCombination();
- if (encodingTry.m_fError < m_fError)
- {
- m_mode = encodingTry.m_mode;
- m_boolDiff = encodingTry.m_boolDiff;
- m_boolFlip = encodingTry.m_boolFlip;
- m_frgbaColor1 = encodingTry.m_frgbaColor1;
- m_frgbaColor2 = encodingTry.m_frgbaColor2;
- m_uiCW1 = encodingTry.m_uiCW1;
- for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
- {
- m_auiSelectors[uiPixel] = encodingTry.m_auiSelectors[uiPixel];
- m_afrgbaDecodedColors[uiPixel] = encodingTry.m_afrgbaDecodedColors[uiPixel];
- }
- m_fError = encodingTry.m_fError;
- }
- }
- }
- }
- }
- // twiddle m_frgbaOriginalColor1_TAndH
- for (int iRed1 = iMinRed1; iRed1 <= iMaxRed1; iRed1++)
- {
- for (int iGreen1 = iMinGreen1; iGreen1 <= iMaxGreen1; iGreen1++)
- {
- for (int iBlue1 = iMinBlue1; iBlue1 <= iMaxBlue1; iBlue1++)
- {
- for (unsigned int uiBaseColorSwaps = 0; uiBaseColorSwaps < 2; uiBaseColorSwaps++)
- {
- if (uiBaseColorSwaps == 0)
- {
- encodingTry.m_frgbaColor1 = ColorFloatRGBA::ConvertFromRGB4((unsigned char)iRed1, (unsigned char)iGreen1, (unsigned char)iBlue1);
- encodingTry.m_frgbaColor2 = m_frgbaOriginalColor2_TAndH;
- }
- else
- {
- encodingTry.m_frgbaColor1 = m_frgbaOriginalColor2_TAndH;
- encodingTry.m_frgbaColor2 = ColorFloatRGBA::ConvertFromRGB4((unsigned char)iRed1, (unsigned char)iGreen1, (unsigned char)iBlue1);
- }
- encodingTry.TryT_BestSelectorCombination();
- if (encodingTry.m_fError < m_fError)
- {
- m_mode = encodingTry.m_mode;
- m_boolDiff = encodingTry.m_boolDiff;
- m_boolFlip = encodingTry.m_boolFlip;
- m_frgbaColor1 = encodingTry.m_frgbaColor1;
- m_frgbaColor2 = encodingTry.m_frgbaColor2;
- m_uiCW1 = encodingTry.m_uiCW1;
- for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
- {
- m_auiSelectors[uiPixel] = encodingTry.m_auiSelectors[uiPixel];
- m_afrgbaDecodedColors[uiPixel] = encodingTry.m_afrgbaDecodedColors[uiPixel];
- }
- m_fError = encodingTry.m_fError;
- }
- }
- }
- }
- }
- }
- }
- // ----------------------------------------------------------------------------------------------------
- // find best selector combination for TryT
- // called on an encodingTry
- //
- void Block4x4Encoding_RGB8A1::TryT_BestSelectorCombination(void)
- {
- float fDistance = s_afTHDistanceTable[m_uiCW1];
- unsigned int auiBestPixelSelectors[PIXELS];
- float afBestPixelErrors[PIXELS] = { FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX,
- FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX };
- ColorFloatRGBA afrgbaBestDecodedPixels[PIXELS];
- ColorFloatRGBA afrgbaDecodedPixel[SELECTORS];
- assert(SELECTORS == 4);
- afrgbaDecodedPixel[0] = m_frgbaColor1;
- afrgbaDecodedPixel[1] = (m_frgbaColor2 + fDistance).ClampRGB();
- afrgbaDecodedPixel[2] = ColorFloatRGBA();
- afrgbaDecodedPixel[3] = (m_frgbaColor2 - fDistance).ClampRGB();
- // try each selector
- for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
- {
- unsigned int uiMinSelector = 0;
- unsigned int uiMaxSelector = SELECTORS - 1;
- if (m_pafrgbaSource[uiPixel].fA < 0.5f)
- {
- uiMinSelector = 2;
- uiMaxSelector = 2;
- }
- for (unsigned int uiSelector = uiMinSelector; uiSelector <= uiMaxSelector; uiSelector++)
- {
- float fPixelError = CalcPixelError(afrgbaDecodedPixel[uiSelector], m_afDecodedAlphas[uiPixel],
- m_pafrgbaSource[uiPixel]);
- if (fPixelError < afBestPixelErrors[uiPixel])
- {
- afBestPixelErrors[uiPixel] = fPixelError;
- auiBestPixelSelectors[uiPixel] = uiSelector;
- afrgbaBestDecodedPixels[uiPixel] = afrgbaDecodedPixel[uiSelector];
- }
- }
- }
-
- // add up all of the pixel errors
- float fBlockError = 0.0f;
- for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
- {
- fBlockError += afBestPixelErrors[uiPixel];
- }
- if (fBlockError < m_fError)
- {
- m_fError = fBlockError;
- for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
- {
- m_auiSelectors[uiPixel] = auiBestPixelSelectors[uiPixel];
- m_afrgbaDecodedColors[uiPixel] = afrgbaBestDecodedPixels[uiPixel];
- }
- }
- }
- // ----------------------------------------------------------------------------------------------------
- // try encoding in H mode
- // save this encoding if it improves the error
- //
- // since all pixels use the distance table, color1 and color2 can NOT be twiddled independently
- // TWIDDLE_RADIUS of 2 is WAY too slow
- //
- void Block4x4Encoding_RGB8A1::TryH(unsigned int a_uiRadius)
- {
- Block4x4Encoding_RGB8A1 encodingTry = *this;
- // init "try"
- {
- encodingTry.m_mode = MODE_H;
- encodingTry.m_boolDiff = true;
- encodingTry.m_boolFlip = false;
- encodingTry.m_fError = FLT_MAX;
- }
- int iColor1Red = m_frgbaOriginalColor1_TAndH.IntRed(15.0f);
- int iColor1Green = m_frgbaOriginalColor1_TAndH.IntGreen(15.0f);
- int iColor1Blue = m_frgbaOriginalColor1_TAndH.IntBlue(15.0f);
- int iMinRed1 = iColor1Red - (int)a_uiRadius;
- if (iMinRed1 < 0)
- {
- iMinRed1 = 0;
- }
- int iMaxRed1 = iColor1Red + (int)a_uiRadius;
- if (iMaxRed1 > 15)
- {
- iMinRed1 = 15;
- }
- int iMinGreen1 = iColor1Green - (int)a_uiRadius;
- if (iMinGreen1 < 0)
- {
- iMinGreen1 = 0;
- }
- int iMaxGreen1 = iColor1Green + (int)a_uiRadius;
- if (iMaxGreen1 > 15)
- {
- iMinGreen1 = 15;
- }
- int iMinBlue1 = iColor1Blue - (int)a_uiRadius;
- if (iMinBlue1 < 0)
- {
- iMinBlue1 = 0;
- }
- int iMaxBlue1 = iColor1Blue + (int)a_uiRadius;
- if (iMaxBlue1 > 15)
- {
- iMinBlue1 = 15;
- }
- int iColor2Red = m_frgbaOriginalColor2_TAndH.IntRed(15.0f);
- int iColor2Green = m_frgbaOriginalColor2_TAndH.IntGreen(15.0f);
- int iColor2Blue = m_frgbaOriginalColor2_TAndH.IntBlue(15.0f);
- int iMinRed2 = iColor2Red - (int)a_uiRadius;
- if (iMinRed2 < 0)
- {
- iMinRed2 = 0;
- }
- int iMaxRed2 = iColor2Red + (int)a_uiRadius;
- if (iMaxRed2 > 15)
- {
- iMinRed2 = 15;
- }
- int iMinGreen2 = iColor2Green - (int)a_uiRadius;
- if (iMinGreen2 < 0)
- {
- iMinGreen2 = 0;
- }
- int iMaxGreen2 = iColor2Green + (int)a_uiRadius;
- if (iMaxGreen2 > 15)
- {
- iMinGreen2 = 15;
- }
- int iMinBlue2 = iColor2Blue - (int)a_uiRadius;
- if (iMinBlue2 < 0)
- {
- iMinBlue2 = 0;
- }
- int iMaxBlue2 = iColor2Blue + (int)a_uiRadius;
- if (iMaxBlue2 > 15)
- {
- iMinBlue2 = 15;
- }
- for (unsigned int uiDistance = 0; uiDistance < TH_DISTANCES; uiDistance++)
- {
- encodingTry.m_uiCW1 = uiDistance;
- // twiddle m_frgbaOriginalColor1_TAndH
- for (int iRed1 = iMinRed1; iRed1 <= iMaxRed1; iRed1++)
- {
- for (int iGreen1 = iMinGreen1; iGreen1 <= iMaxGreen1; iGreen1++)
- {
- for (int iBlue1 = iMinBlue1; iBlue1 <= iMaxBlue1; iBlue1++)
- {
- encodingTry.m_frgbaColor1 = ColorFloatRGBA::ConvertFromRGB4((unsigned char)iRed1, (unsigned char)iGreen1, (unsigned char)iBlue1);
- encodingTry.m_frgbaColor2 = m_frgbaOriginalColor2_TAndH;
- // if color1 == color2, H encoding issues can pop up, so abort
- if (iRed1 == iColor2Red && iGreen1 == iColor2Green && iBlue1 == iColor2Blue)
- {
- continue;
- }
- encodingTry.TryH_BestSelectorCombination();
- if (encodingTry.m_fError < m_fError)
- {
- m_mode = encodingTry.m_mode;
- m_boolDiff = encodingTry.m_boolDiff;
- m_boolFlip = encodingTry.m_boolFlip;
- m_frgbaColor1 = encodingTry.m_frgbaColor1;
- m_frgbaColor2 = encodingTry.m_frgbaColor2;
- m_uiCW1 = encodingTry.m_uiCW1;
- for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
- {
- m_auiSelectors[uiPixel] = encodingTry.m_auiSelectors[uiPixel];
- m_afrgbaDecodedColors[uiPixel] = encodingTry.m_afrgbaDecodedColors[uiPixel];
- }
- m_fError = encodingTry.m_fError;
- }
- }
- }
- }
- // twiddle m_frgbaOriginalColor2_TAndH
- for (int iRed2 = iMinRed2; iRed2 <= iMaxRed2; iRed2++)
- {
- for (int iGreen2 = iMinGreen2; iGreen2 <= iMaxGreen2; iGreen2++)
- {
- for (int iBlue2 = iMinBlue2; iBlue2 <= iMaxBlue2; iBlue2++)
- {
- encodingTry.m_frgbaColor1 = m_frgbaOriginalColor1_TAndH;
- encodingTry.m_frgbaColor2 = ColorFloatRGBA::ConvertFromRGB4((unsigned char)iRed2, (unsigned char)iGreen2, (unsigned char)iBlue2);
- // if color1 == color2, H encoding issues can pop up, so abort
- if (iRed2 == iColor1Red && iGreen2 == iColor1Green && iBlue2 == iColor1Blue)
- {
- continue;
- }
- encodingTry.TryH_BestSelectorCombination();
- if (encodingTry.m_fError < m_fError)
- {
- m_mode = encodingTry.m_mode;
- m_boolDiff = encodingTry.m_boolDiff;
- m_boolFlip = encodingTry.m_boolFlip;
- m_frgbaColor1 = encodingTry.m_frgbaColor1;
- m_frgbaColor2 = encodingTry.m_frgbaColor2;
- m_uiCW1 = encodingTry.m_uiCW1;
- for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
- {
- m_auiSelectors[uiPixel] = encodingTry.m_auiSelectors[uiPixel];
- m_afrgbaDecodedColors[uiPixel] = encodingTry.m_afrgbaDecodedColors[uiPixel];
- }
- m_fError = encodingTry.m_fError;
- }
- }
- }
- }
- }
- }
- // ----------------------------------------------------------------------------------------------------
- // find best selector combination for TryH
- // called on an encodingTry
- //
- void Block4x4Encoding_RGB8A1::TryH_BestSelectorCombination(void)
- {
- // abort if colors and CW will pose an encoding problem
- {
- unsigned int uiRed1 = (unsigned int)m_frgbaColor1.IntRed(255.0f);
- unsigned int uiGreen1 = (unsigned int)m_frgbaColor1.IntGreen(255.0f);
- unsigned int uiBlue1 = (unsigned int)m_frgbaColor1.IntBlue(255.0f);
- unsigned int uiColorValue1 = (uiRed1 << 16) + (uiGreen1 << 8) + uiBlue1;
- unsigned int uiRed2 = (unsigned int)m_frgbaColor2.IntRed(255.0f);
- unsigned int uiGreen2 = (unsigned int)m_frgbaColor2.IntGreen(255.0f);
- unsigned int uiBlue2 = (unsigned int)m_frgbaColor2.IntBlue(255.0f);
- unsigned int uiColorValue2 = (uiRed2 << 16) + (uiGreen2 << 8) + uiBlue2;
- unsigned int uiCWLsb = m_uiCW1 & 1;
- if ((uiColorValue1 >= (uiColorValue2 & uiCWLsb)) == 0 ||
- (uiColorValue1 < (uiColorValue2 & uiCWLsb)) == 1)
- {
- return;
- }
- }
- float fDistance = s_afTHDistanceTable[m_uiCW1];
- unsigned int auiBestPixelSelectors[PIXELS];
- float afBestPixelErrors[PIXELS] = { FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX,
- FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX };
- ColorFloatRGBA afrgbaBestDecodedPixels[PIXELS];
- ColorFloatRGBA afrgbaDecodedPixel[SELECTORS];
- assert(SELECTORS == 4);
- afrgbaDecodedPixel[0] = (m_frgbaColor1 + fDistance).ClampRGB();
- afrgbaDecodedPixel[1] = (m_frgbaColor1 - fDistance).ClampRGB();
- afrgbaDecodedPixel[2] = ColorFloatRGBA();;
- afrgbaDecodedPixel[3] = (m_frgbaColor2 - fDistance).ClampRGB();
- // try each selector
- for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
- {
- unsigned int uiMinSelector = 0;
- unsigned int uiMaxSelector = SELECTORS - 1;
- if (m_pafrgbaSource[uiPixel].fA < 0.5f)
- {
- uiMinSelector = 2;
- uiMaxSelector = 2;
- }
- for (unsigned int uiSelector = uiMinSelector; uiSelector <= uiMaxSelector; uiSelector++)
- {
- float fPixelError = CalcPixelError(afrgbaDecodedPixel[uiSelector], m_afDecodedAlphas[uiPixel],
- m_pafrgbaSource[uiPixel]);
- if (fPixelError < afBestPixelErrors[uiPixel])
- {
- afBestPixelErrors[uiPixel] = fPixelError;
- auiBestPixelSelectors[uiPixel] = uiSelector;
- afrgbaBestDecodedPixels[uiPixel] = afrgbaDecodedPixel[uiSelector];
- }
- }
- }
-
- // add up all of the pixel errors
- float fBlockError = 0.0f;
- for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
- {
- fBlockError += afBestPixelErrors[uiPixel];
- }
- if (fBlockError < m_fError)
- {
- m_fError = fBlockError;
- for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
- {
- m_auiSelectors[uiPixel] = auiBestPixelSelectors[uiPixel];
- m_afrgbaDecodedColors[uiPixel] = afrgbaBestDecodedPixels[uiPixel];
- }
- }
- }
- // ----------------------------------------------------------------------------------------------------
- // try version 1 of the degenerate search
- // degenerate encodings use basecolor movement and a subset of the selectors to find useful encodings
- // each subsequent version of the degenerate search uses more basecolor movement and is less likely to
- // be successfull
- //
- void Block4x4Encoding_RGB8A1::TryDegenerates1(void)
- {
- TryDifferential(m_boolMostLikelyFlip, 1, -2, 0);
- TryDifferential(m_boolMostLikelyFlip, 1, 2, 0);
- TryDifferential(m_boolMostLikelyFlip, 1, 0, 2);
- TryDifferential(m_boolMostLikelyFlip, 1, 0, -2);
- }
- // ----------------------------------------------------------------------------------------------------
- // try version 2 of the degenerate search
- // degenerate encodings use basecolor movement and a subset of the selectors to find useful encodings
- // each subsequent version of the degenerate search uses more basecolor movement and is less likely to
- // be successfull
- //
- void Block4x4Encoding_RGB8A1::TryDegenerates2(void)
- {
- TryDifferential(!m_boolMostLikelyFlip, 1, -2, 0);
- TryDifferential(!m_boolMostLikelyFlip, 1, 2, 0);
- TryDifferential(!m_boolMostLikelyFlip, 1, 0, 2);
- TryDifferential(!m_boolMostLikelyFlip, 1, 0, -2);
- }
- // ----------------------------------------------------------------------------------------------------
- // try version 3 of the degenerate search
- // degenerate encodings use basecolor movement and a subset of the selectors to find useful encodings
- // each subsequent version of the degenerate search uses more basecolor movement and is less likely to
- // be successfull
- //
- void Block4x4Encoding_RGB8A1::TryDegenerates3(void)
- {
- TryDifferential(m_boolMostLikelyFlip, 1, -2, -2);
- TryDifferential(m_boolMostLikelyFlip, 1, -2, 2);
- TryDifferential(m_boolMostLikelyFlip, 1, 2, -2);
- TryDifferential(m_boolMostLikelyFlip, 1, 2, 2);
- }
- // ----------------------------------------------------------------------------------------------------
- // try version 4 of the degenerate search
- // degenerate encodings use basecolor movement and a subset of the selectors to find useful encodings
- // each subsequent version of the degenerate search uses more basecolor movement and is less likely to
- // be successfull
- //
- void Block4x4Encoding_RGB8A1::TryDegenerates4(void)
- {
- TryDifferential(m_boolMostLikelyFlip, 1, -4, 0);
- TryDifferential(m_boolMostLikelyFlip, 1, 4, 0);
- TryDifferential(m_boolMostLikelyFlip, 1, 0, 4);
- TryDifferential(m_boolMostLikelyFlip, 1, 0, -4);
- }
- // ----------------------------------------------------------------------------------------------------
- // set the encoding bits based on encoding state
- //
- void Block4x4Encoding_RGB8A1::SetEncodingBits(void)
- {
- switch (m_mode)
- {
- case MODE_ETC1:
- SetEncodingBits_ETC1();
- break;
- case MODE_T:
- SetEncodingBits_T();
- break;
- case MODE_H:
- SetEncodingBits_H();
- break;
- case MODE_PLANAR:
- Block4x4Encoding_RGB8::SetEncodingBits_Planar();
- break;
- default:
- assert(false);
- }
- }
- // ----------------------------------------------------------------------------------------------------
- // set the encoding bits based on encoding state if ETC1 mode
- //
- void Block4x4Encoding_RGB8A1::SetEncodingBits_ETC1(void)
- {
- // there is no individual mode in RGB8A1
- assert(m_boolDiff);
- int iRed1 = m_frgbaColor1.IntRed(31.0f);
- int iGreen1 = m_frgbaColor1.IntGreen(31.0f);
- int iBlue1 = m_frgbaColor1.IntBlue(31.0f);
- int iRed2 = m_frgbaColor2.IntRed(31.0f);
- int iGreen2 = m_frgbaColor2.IntGreen(31.0f);
- int iBlue2 = m_frgbaColor2.IntBlue(31.0f);
- int iDRed2 = iRed2 - iRed1;
- int iDGreen2 = iGreen2 - iGreen1;
- int iDBlue2 = iBlue2 - iBlue1;
- assert(iDRed2 >= -4 && iDRed2 < 4);
- assert(iDGreen2 >= -4 && iDGreen2 < 4);
- assert(iDBlue2 >= -4 && iDBlue2 < 4);
- m_pencodingbitsRGB8->differential.red1 = iRed1;
- m_pencodingbitsRGB8->differential.green1 = iGreen1;
- m_pencodingbitsRGB8->differential.blue1 = iBlue1;
- m_pencodingbitsRGB8->differential.dred2 = iDRed2;
- m_pencodingbitsRGB8->differential.dgreen2 = iDGreen2;
- m_pencodingbitsRGB8->differential.dblue2 = iDBlue2;
- m_pencodingbitsRGB8->individual.cw1 = m_uiCW1;
- m_pencodingbitsRGB8->individual.cw2 = m_uiCW2;
- SetEncodingBits_Selectors();
- // in RGB8A1 encoding bits, opaque replaces differential
- m_pencodingbitsRGB8->differential.diff = !m_boolPunchThroughPixels;
- m_pencodingbitsRGB8->individual.flip = m_boolFlip;
- }
- // ----------------------------------------------------------------------------------------------------
- // set the encoding bits based on encoding state if T mode
- //
- void Block4x4Encoding_RGB8A1::SetEncodingBits_T(void)
- {
- static const bool SANITY_CHECK = true;
- assert(m_mode == MODE_T);
- assert(m_boolDiff == true);
- unsigned int uiRed1 = (unsigned int)m_frgbaColor1.IntRed(15.0f);
- unsigned int uiGreen1 = (unsigned int)m_frgbaColor1.IntGreen(15.0f);
- unsigned int uiBlue1 = (unsigned int)m_frgbaColor1.IntBlue(15.0f);
- unsigned int uiRed2 = (unsigned int)m_frgbaColor2.IntRed(15.0f);
- unsigned int uiGreen2 = (unsigned int)m_frgbaColor2.IntGreen(15.0f);
- unsigned int uiBlue2 = (unsigned int)m_frgbaColor2.IntBlue(15.0f);
- m_pencodingbitsRGB8->t.red1a = uiRed1 >> 2;
- m_pencodingbitsRGB8->t.red1b = uiRed1;
- m_pencodingbitsRGB8->t.green1 = uiGreen1;
- m_pencodingbitsRGB8->t.blue1 = uiBlue1;
- m_pencodingbitsRGB8->t.red2 = uiRed2;
- m_pencodingbitsRGB8->t.green2 = uiGreen2;
- m_pencodingbitsRGB8->t.blue2 = uiBlue2;
- m_pencodingbitsRGB8->t.da = m_uiCW1 >> 1;
- m_pencodingbitsRGB8->t.db = m_uiCW1;
- // in RGB8A1 encoding bits, opaque replaces differential
- m_pencodingbitsRGB8->differential.diff = !m_boolPunchThroughPixels;
- Block4x4Encoding_ETC1::SetEncodingBits_Selectors();
- // create an invalid R differential to trigger T mode
- m_pencodingbitsRGB8->t.detect1 = 0;
- m_pencodingbitsRGB8->t.detect2 = 0;
- int iRed2 = (int)m_pencodingbitsRGB8->differential.red1 + (int)m_pencodingbitsRGB8->differential.dred2;
- if (iRed2 >= 4)
- {
- m_pencodingbitsRGB8->t.detect1 = 7;
- m_pencodingbitsRGB8->t.detect2 = 0;
- }
- else
- {
- m_pencodingbitsRGB8->t.detect1 = 0;
- m_pencodingbitsRGB8->t.detect2 = 1;
- }
- if (SANITY_CHECK)
- {
- iRed2 = (int)m_pencodingbitsRGB8->differential.red1 + (int)m_pencodingbitsRGB8->differential.dred2;
- // make sure red overflows
- assert(iRed2 < 0 || iRed2 > 31);
- }
- }
- // ----------------------------------------------------------------------------------------------------
- // set the encoding bits based on encoding state if H mode
- //
- // colors and selectors may need to swap in order to generate lsb of distance index
- //
- void Block4x4Encoding_RGB8A1::SetEncodingBits_H(void)
- {
- static const bool SANITY_CHECK = true;
- assert(m_mode == MODE_H);
- assert(m_boolDiff == true);
- unsigned int uiRed1 = (unsigned int)m_frgbaColor1.IntRed(15.0f);
- unsigned int uiGreen1 = (unsigned int)m_frgbaColor1.IntGreen(15.0f);
- unsigned int uiBlue1 = (unsigned int)m_frgbaColor1.IntBlue(15.0f);
- unsigned int uiRed2 = (unsigned int)m_frgbaColor2.IntRed(15.0f);
- unsigned int uiGreen2 = (unsigned int)m_frgbaColor2.IntGreen(15.0f);
- unsigned int uiBlue2 = (unsigned int)m_frgbaColor2.IntBlue(15.0f);
- unsigned int uiColor1 = (uiRed1 << 16) + (uiGreen1 << 8) + uiBlue1;
- unsigned int uiColor2 = (uiRed2 << 16) + (uiGreen2 << 8) + uiBlue2;
- bool boolOddDistance = m_uiCW1 & 1;
- bool boolSwapColors = (uiColor1 < uiColor2) ^ !boolOddDistance;
- if (boolSwapColors)
- {
- m_pencodingbitsRGB8->h.red1 = uiRed2;
- m_pencodingbitsRGB8->h.green1a = uiGreen2 >> 1;
- m_pencodingbitsRGB8->h.green1b = uiGreen2;
- m_pencodingbitsRGB8->h.blue1a = uiBlue2 >> 3;
- m_pencodingbitsRGB8->h.blue1b = uiBlue2 >> 1;
- m_pencodingbitsRGB8->h.blue1c = uiBlue2;
- m_pencodingbitsRGB8->h.red2 = uiRed1;
- m_pencodingbitsRGB8->h.green2a = uiGreen1 >> 1;
- m_pencodingbitsRGB8->h.green2b = uiGreen1;
- m_pencodingbitsRGB8->h.blue2 = uiBlue1;
- m_pencodingbitsRGB8->h.da = m_uiCW1 >> 2;
- m_pencodingbitsRGB8->h.db = m_uiCW1 >> 1;
- }
- else
- {
- m_pencodingbitsRGB8->h.red1 = uiRed1;
- m_pencodingbitsRGB8->h.green1a = uiGreen1 >> 1;
- m_pencodingbitsRGB8->h.green1b = uiGreen1;
- m_pencodingbitsRGB8->h.blue1a = uiBlue1 >> 3;
- m_pencodingbitsRGB8->h.blue1b = uiBlue1 >> 1;
- m_pencodingbitsRGB8->h.blue1c = uiBlue1;
- m_pencodingbitsRGB8->h.red2 = uiRed2;
- m_pencodingbitsRGB8->h.green2a = uiGreen2 >> 1;
- m_pencodingbitsRGB8->h.green2b = uiGreen2;
- m_pencodingbitsRGB8->h.blue2 = uiBlue2;
- m_pencodingbitsRGB8->h.da = m_uiCW1 >> 2;
- m_pencodingbitsRGB8->h.db = m_uiCW1 >> 1;
- }
- // in RGB8A1 encoding bits, opaque replaces differential
- m_pencodingbitsRGB8->differential.diff = !m_boolPunchThroughPixels;
- Block4x4Encoding_ETC1::SetEncodingBits_Selectors();
- if (boolSwapColors)
- {
- m_pencodingbitsRGB8->h.selectors ^= 0x0000FFFF;
- }
- // create an invalid R differential to trigger T mode
- m_pencodingbitsRGB8->h.detect1 = 0;
- m_pencodingbitsRGB8->h.detect2 = 0;
- m_pencodingbitsRGB8->h.detect3 = 0;
- int iRed2 = (int)m_pencodingbitsRGB8->differential.red1 + (int)m_pencodingbitsRGB8->differential.dred2;
- int iGreen2 = (int)m_pencodingbitsRGB8->differential.green1 + (int)m_pencodingbitsRGB8->differential.dgreen2;
- if (iRed2 < 0 || iRed2 > 31)
- {
- m_pencodingbitsRGB8->h.detect1 = 1;
- }
- if (iGreen2 >= 4)
- {
- m_pencodingbitsRGB8->h.detect2 = 7;
- m_pencodingbitsRGB8->h.detect3 = 0;
- }
- else
- {
- m_pencodingbitsRGB8->h.detect2 = 0;
- m_pencodingbitsRGB8->h.detect3 = 1;
- }
- if (SANITY_CHECK)
- {
- iRed2 = (int)m_pencodingbitsRGB8->differential.red1 + (int)m_pencodingbitsRGB8->differential.dred2;
- iGreen2 = (int)m_pencodingbitsRGB8->differential.green1 + (int)m_pencodingbitsRGB8->differential.dgreen2;
- // make sure red doesn't overflow and green does
- assert(iRed2 >= 0 && iRed2 <= 31);
- assert(iGreen2 < 0 || iGreen2 > 31);
- }
- }
- // ####################################################################################################
- // Block4x4Encoding_RGB8A1_Opaque
- // ####################################################################################################
- // ----------------------------------------------------------------------------------------------------
- // perform a single encoding iteration
- // replace the encoding if a better encoding was found
- // subsequent iterations generally take longer for each iteration
- // set m_boolDone if encoding is perfect or encoding is finished based on a_fEffort
- //
- void Block4x4Encoding_RGB8A1_Opaque::PerformIteration(float a_fEffort)
- {
- assert(!m_boolPunchThroughPixels);
- assert(!m_boolTransparent);
- assert(!m_boolDone);
- switch (m_uiEncodingIterations)
- {
- case 0:
- PerformFirstIteration();
- break;
- case 1:
- Block4x4Encoding_ETC1::TryDifferential(m_boolMostLikelyFlip, 1, 0, 0);
- break;
- case 2:
- Block4x4Encoding_ETC1::TryDifferential(!m_boolMostLikelyFlip, 1, 0, 0);
- break;
- case 3:
- Block4x4Encoding_RGB8::TryPlanar(1);
- break;
- case 4:
- Block4x4Encoding_RGB8::TryTAndH(1);
- if (a_fEffort <= 49.5f)
- {
- m_boolDone = true;
- }
- break;
- case 5:
- Block4x4Encoding_ETC1::TryDegenerates1();
- if (a_fEffort <= 59.5f)
- {
- m_boolDone = true;
- }
- break;
- case 6:
- Block4x4Encoding_ETC1::TryDegenerates2();
- if (a_fEffort <= 69.5f)
- {
- m_boolDone = true;
- }
- break;
- case 7:
- Block4x4Encoding_ETC1::TryDegenerates3();
- if (a_fEffort <= 79.5f)
- {
- m_boolDone = true;
- }
- break;
- case 8:
- Block4x4Encoding_ETC1::TryDegenerates4();
- m_boolDone = true;
- break;
- default:
- assert(0);
- break;
- }
- m_uiEncodingIterations++;
- SetDoneIfPerfect();
- }
- // ----------------------------------------------------------------------------------------------------
- // find best initial encoding to ensure block has a valid encoding
- //
- void Block4x4Encoding_RGB8A1_Opaque::PerformFirstIteration(void)
- {
-
- // set decoded alphas
- // calculate alpha error
- m_fError = 0.0f;
- for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
- {
- m_afDecodedAlphas[uiPixel] = 1.0f;
- float fDeltaA = 1.0f - m_pafrgbaSource[uiPixel].fA;
- m_fError += fDeltaA * fDeltaA;
- }
- CalculateMostLikelyFlip();
- m_fError = FLT_MAX;
- Block4x4Encoding_ETC1::TryDifferential(m_boolMostLikelyFlip, 0, 0, 0);
- SetDoneIfPerfect();
- if (m_boolDone)
- {
- return;
- }
- Block4x4Encoding_ETC1::TryDifferential(!m_boolMostLikelyFlip, 0, 0, 0);
- SetDoneIfPerfect();
- if (m_boolDone)
- {
- return;
- }
- Block4x4Encoding_RGB8::TryPlanar(0);
- SetDoneIfPerfect();
- if (m_boolDone)
- {
- return;
- }
- Block4x4Encoding_RGB8::TryTAndH(0);
- SetDoneIfPerfect();
- }
- // ####################################################################################################
- // Block4x4Encoding_RGB8A1_Transparent
- // ####################################################################################################
- // ----------------------------------------------------------------------------------------------------
- // perform a single encoding iteration
- // replace the encoding if a better encoding was found
- // subsequent iterations generally take longer for each iteration
- // set m_boolDone if encoding is perfect or encoding is finished based on a_fEffort
- //
- void Block4x4Encoding_RGB8A1_Transparent::PerformIteration(float )
- {
- assert(!m_boolOpaque);
- assert(m_boolTransparent);
- assert(!m_boolDone);
- assert(m_uiEncodingIterations == 0);
- m_mode = MODE_ETC1;
- m_boolDiff = true;
- m_boolFlip = false;
- m_uiCW1 = 0;
- m_uiCW2 = 0;
- m_frgbaColor1 = ColorFloatRGBA();
- m_frgbaColor2 = ColorFloatRGBA();
- for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
- {
- m_auiSelectors[uiPixel] = TRANSPARENT_SELECTOR;
- m_afrgbaDecodedColors[uiPixel] = ColorFloatRGBA();
- m_afDecodedAlphas[uiPixel] = 0.0f;
- }
- CalcBlockError();
- m_boolDone = true;
- m_uiEncodingIterations++;
- }
- // ----------------------------------------------------------------------------------------------------
- //
- }
|