mirror of
https://github.com/Relintai/pandemonium_engine.git
synced 2024-12-23 12:26:59 +01:00
174 lines
5.0 KiB
C++
174 lines
5.0 KiB
C++
|
/*
|
||
|
* 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.
|
||
|
*/
|
||
|
|
||
|
/*
|
||
|
EtcDifferentialTrys.cpp
|
||
|
|
||
|
Gathers the results of the various encoding trys for both halves of a 4x4 block for Differential mode
|
||
|
|
||
|
*/
|
||
|
|
||
|
#include "EtcConfig.h"
|
||
|
#include "EtcDifferentialTrys.h"
|
||
|
|
||
|
#include <assert.h>
|
||
|
|
||
|
namespace Etc
|
||
|
{
|
||
|
|
||
|
// ----------------------------------------------------------------------------------------------------
|
||
|
// construct a list of trys (encoding attempts)
|
||
|
//
|
||
|
// a_frgbaColor1 is the basecolor for the first half
|
||
|
// a_frgbaColor2 is the basecolor for the second half
|
||
|
// a_pauiPixelMapping1 is the pixel order for the first half
|
||
|
// a_pauiPixelMapping2 is the pixel order for the second half
|
||
|
// a_uiRadius is the amount to vary the base colors
|
||
|
//
|
||
|
DifferentialTrys::DifferentialTrys(ColorFloatRGBA a_frgbaColor1, ColorFloatRGBA a_frgbaColor2,
|
||
|
const unsigned int *a_pauiPixelMapping1,
|
||
|
const unsigned int *a_pauiPixelMapping2,
|
||
|
unsigned int a_uiRadius,
|
||
|
int a_iGrayOffset1, int a_iGrayOffset2)
|
||
|
{
|
||
|
assert(a_uiRadius <= MAX_RADIUS);
|
||
|
|
||
|
m_boolSeverelyBentColors = false;
|
||
|
|
||
|
ColorFloatRGBA frgbaQuantizedColor1 = a_frgbaColor1.QuantizeR5G5B5();
|
||
|
ColorFloatRGBA frgbaQuantizedColor2 = a_frgbaColor2.QuantizeR5G5B5();
|
||
|
|
||
|
// quantize base colors
|
||
|
// ensure that trys with a_uiRadius don't overflow
|
||
|
int iRed1 = MoveAwayFromEdge(frgbaQuantizedColor1.IntRed(31.0f)+a_iGrayOffset1, a_uiRadius);
|
||
|
int iGreen1 = MoveAwayFromEdge(frgbaQuantizedColor1.IntGreen(31.0f) + a_iGrayOffset1, a_uiRadius);
|
||
|
int iBlue1 = MoveAwayFromEdge(frgbaQuantizedColor1.IntBlue(31.0f) + a_iGrayOffset1, a_uiRadius);
|
||
|
int iRed2 = MoveAwayFromEdge(frgbaQuantizedColor2.IntRed(31.0f) + a_iGrayOffset2, a_uiRadius);
|
||
|
int iGreen2 = MoveAwayFromEdge(frgbaQuantizedColor2.IntGreen(31.0f) + a_iGrayOffset2, a_uiRadius);
|
||
|
int iBlue2 = MoveAwayFromEdge(frgbaQuantizedColor2.IntBlue(31.0f) + a_iGrayOffset2, a_uiRadius);
|
||
|
|
||
|
int iDeltaRed = iRed2 - iRed1;
|
||
|
int iDeltaGreen = iGreen2 - iGreen1;
|
||
|
int iDeltaBlue = iBlue2 - iBlue1;
|
||
|
|
||
|
// make sure components are within range
|
||
|
{
|
||
|
if (iDeltaRed > 3)
|
||
|
{
|
||
|
if (iDeltaRed > 7)
|
||
|
{
|
||
|
m_boolSeverelyBentColors = true;
|
||
|
}
|
||
|
|
||
|
iRed1 += (iDeltaRed - 3) / 2;
|
||
|
iRed2 = iRed1 + 3;
|
||
|
iDeltaRed = 3;
|
||
|
}
|
||
|
else if (iDeltaRed < -4)
|
||
|
{
|
||
|
if (iDeltaRed < -8)
|
||
|
{
|
||
|
m_boolSeverelyBentColors = true;
|
||
|
}
|
||
|
|
||
|
iRed1 += (iDeltaRed + 4) / 2;
|
||
|
iRed2 = iRed1 - 4;
|
||
|
iDeltaRed = -4;
|
||
|
}
|
||
|
assert(iRed1 >= (signed)(0 + a_uiRadius) && iRed1 <= (signed)(31 - a_uiRadius));
|
||
|
assert(iRed2 >= (signed)(0 + a_uiRadius) && iRed2 <= (signed)(31 - a_uiRadius));
|
||
|
assert(iDeltaRed >= -4 && iDeltaRed <= 3);
|
||
|
|
||
|
if (iDeltaGreen > 3)
|
||
|
{
|
||
|
if (iDeltaGreen > 7)
|
||
|
{
|
||
|
m_boolSeverelyBentColors = true;
|
||
|
}
|
||
|
|
||
|
iGreen1 += (iDeltaGreen - 3) / 2;
|
||
|
iGreen2 = iGreen1 + 3;
|
||
|
iDeltaGreen = 3;
|
||
|
}
|
||
|
else if (iDeltaGreen < -4)
|
||
|
{
|
||
|
if (iDeltaGreen < -8)
|
||
|
{
|
||
|
m_boolSeverelyBentColors = true;
|
||
|
}
|
||
|
|
||
|
iGreen1 += (iDeltaGreen + 4) / 2;
|
||
|
iGreen2 = iGreen1 - 4;
|
||
|
iDeltaGreen = -4;
|
||
|
}
|
||
|
assert(iGreen1 >= (signed)(0 + a_uiRadius) && iGreen1 <= (signed)(31 - a_uiRadius));
|
||
|
assert(iGreen2 >= (signed)(0 + a_uiRadius) && iGreen2 <= (signed)(31 - a_uiRadius));
|
||
|
assert(iDeltaGreen >= -4 && iDeltaGreen <= 3);
|
||
|
|
||
|
if (iDeltaBlue > 3)
|
||
|
{
|
||
|
if (iDeltaBlue > 7)
|
||
|
{
|
||
|
m_boolSeverelyBentColors = true;
|
||
|
}
|
||
|
|
||
|
iBlue1 += (iDeltaBlue - 3) / 2;
|
||
|
iBlue2 = iBlue1 + 3;
|
||
|
iDeltaBlue = 3;
|
||
|
}
|
||
|
else if (iDeltaBlue < -4)
|
||
|
{
|
||
|
if (iDeltaBlue < -8)
|
||
|
{
|
||
|
m_boolSeverelyBentColors = true;
|
||
|
}
|
||
|
|
||
|
iBlue1 += (iDeltaBlue + 4) / 2;
|
||
|
iBlue2 = iBlue1 - 4;
|
||
|
iDeltaBlue = -4;
|
||
|
}
|
||
|
assert(iBlue1 >= (signed)(0+a_uiRadius) && iBlue1 <= (signed)(31 - a_uiRadius));
|
||
|
assert(iBlue2 >= (signed)(0 + a_uiRadius) && iBlue2 <= (signed)(31 - a_uiRadius));
|
||
|
assert(iDeltaBlue >= -4 && iDeltaBlue <= 3);
|
||
|
}
|
||
|
|
||
|
m_half1.Init(iRed1, iGreen1, iBlue1, a_pauiPixelMapping1, a_uiRadius);
|
||
|
m_half2.Init(iRed2, iGreen2, iBlue2, a_pauiPixelMapping2, a_uiRadius);
|
||
|
|
||
|
}
|
||
|
|
||
|
// ----------------------------------------------------------------------------------------------------
|
||
|
//
|
||
|
void DifferentialTrys::Half::Init(int a_iRed, int a_iGreen, int a_iBlue,
|
||
|
const unsigned int *a_pauiPixelMapping, unsigned int a_uiRadius)
|
||
|
{
|
||
|
|
||
|
m_iRed = a_iRed;
|
||
|
m_iGreen = a_iGreen;
|
||
|
m_iBlue = a_iBlue;
|
||
|
|
||
|
m_pauiPixelMapping = a_pauiPixelMapping;
|
||
|
m_uiRadius = a_uiRadius;
|
||
|
|
||
|
m_uiTrys = 0;
|
||
|
|
||
|
}
|
||
|
|
||
|
// ----------------------------------------------------------------------------------------------------
|
||
|
//
|
||
|
|
||
|
} // namespace Etc
|