summaryrefslogtreecommitdiff
path: root/thirdparty/etc2comp/EtcDifferentialTrys.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'thirdparty/etc2comp/EtcDifferentialTrys.cpp')
-rw-r--r--thirdparty/etc2comp/EtcDifferentialTrys.cpp173
1 files changed, 173 insertions, 0 deletions
diff --git a/thirdparty/etc2comp/EtcDifferentialTrys.cpp b/thirdparty/etc2comp/EtcDifferentialTrys.cpp
new file mode 100644
index 0000000000..ef4cd103d9
--- /dev/null
+++ b/thirdparty/etc2comp/EtcDifferentialTrys.cpp
@@ -0,0 +1,173 @@
+/*
+ * 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