// ReSharper disable once FunctionComplexityOverflow private static void Fancybasecolorsearch(GLubyte ***srccolors, GLubyte **bestcolor, GLint numxpixels, GLint numypixels) { GLint i, j; GLint * blockerrlin0 = stackalloc GLint[3]; GLint * blockerrlin1 = stackalloc GLint[3]; GLint **blockerrlin = stackalloc GLint *[2]; blockerrlin[0] = blockerrlin0; blockerrlin[1] = blockerrlin1; GLubyte * nrcolor = stackalloc GLubyte[2]; GLint * pixerrorcolorbest = stackalloc GLint[3]; GLubyte enc = 0; GLubyte **cv = stackalloc GLubyte *[4]; GLubyte * cv0 = stackalloc GLubyte[4]; GLubyte * cv1 = stackalloc GLubyte[4]; GLubyte * cv2 = stackalloc GLubyte[4]; GLubyte * cv3 = stackalloc GLubyte[4]; cv[0] = cv0; cv[1] = cv1; cv[2] = cv2; cv[3] = cv3; GLubyte **testcolor = stackalloc GLubyte *[2]; GLubyte * tc0 = stackalloc GLubyte[3]; GLubyte * tc1 = stackalloc GLubyte[3]; testcolor[0] = tc0; testcolor[1] = tc1; if (((bestcolor[0][0] & 0xf8) << 8 | (bestcolor[0][1] & 0xfc) << 3 | bestcolor[0][2] >> 3) < ((bestcolor[1][0] & 0xf8) << 8 | (bestcolor[1][1] & 0xfc) << 3 | bestcolor[1][2] >> 3)) { testcolor[0][0] = bestcolor[0][0]; testcolor[0][1] = bestcolor[0][1]; testcolor[0][2] = bestcolor[0][2]; testcolor[1][0] = bestcolor[1][0]; testcolor[1][1] = bestcolor[1][1]; testcolor[1][2] = bestcolor[1][2]; } else { testcolor[1][0] = bestcolor[0][0]; testcolor[1][1] = bestcolor[0][1]; testcolor[1][2] = bestcolor[0][2]; testcolor[0][0] = bestcolor[1][0]; testcolor[0][1] = bestcolor[1][1]; testcolor[0][2] = bestcolor[1][2]; } for (i = 0; i < 3; i++) { cv[0][i] = testcolor[0][i]; cv[1][i] = testcolor[1][i]; cv[2][i] = (byte)((testcolor[0][i] * 2 + testcolor[1][i]) / 3); cv[3][i] = (byte)((testcolor[0][i] + testcolor[1][i] * 2) / 3); } blockerrlin[0][0] = 0; blockerrlin[0][1] = 0; blockerrlin[0][2] = 0; blockerrlin[1][0] = 0; blockerrlin[1][1] = 0; blockerrlin[1][2] = 0; nrcolor[0] = 0; nrcolor[1] = 0; for (j = 0; j < numypixels; j++) { for (i = 0; i < numxpixels; i++) { var pixerrorbest = 0xffffffff; GLint colors; for (colors = 0; colors < 4; colors++) { var colordist = srccolors[j][i][0] - (cv[colors][0]); var pixerror = (uint)(colordist * colordist * Redweight); var pixerrorred = (uint)colordist; colordist = srccolors[j][i][1] - (cv[colors][1]); pixerror += (uint)(colordist * colordist * Greenweight); var pixerrorgreen = (uint)colordist; colordist = srccolors[j][i][2] - (cv[colors][2]); pixerror += (uint)(colordist * colordist * Blueweight); var pixerrorblue = (uint)colordist; if (pixerror < pixerrorbest) { enc = (byte)colors; pixerrorbest = pixerror; pixerrorcolorbest[0] = (int)pixerrorred; pixerrorcolorbest[1] = (int)pixerrorgreen; pixerrorcolorbest[2] = (int)pixerrorblue; } } GLint z; if (enc == 0) { for (z = 0; z < 3; z++) { blockerrlin[0][z] += 3 * pixerrorcolorbest[z]; } nrcolor[0] += 3; } else if (enc == 2) { for (z = 0; z < 3; z++) { blockerrlin[0][z] += 2 * pixerrorcolorbest[z]; } nrcolor[0] += 2; for (z = 0; z < 3; z++) { blockerrlin[1][z] += 1 * pixerrorcolorbest[z]; } nrcolor[1] += 1; } else if (enc == 3) { for (z = 0; z < 3; z++) { blockerrlin[0][z] += 1 * pixerrorcolorbest[z]; } nrcolor[0] += 1; for (z = 0; z < 3; z++) { blockerrlin[1][z] += 2 * pixerrorcolorbest[z]; } nrcolor[1] += 2; } else if (enc == 1) { for (z = 0; z < 3; z++) { blockerrlin[1][z] += 3 * pixerrorcolorbest[z]; } nrcolor[1] += 3; } } } if (nrcolor[0] == 0) { nrcolor[0] = 1; } if (nrcolor[1] == 0) { nrcolor[1] = 1; } for (j = 0; j < 2; j++) { for (i = 0; i < 3; i++) { var newvalue = testcolor[j][i] + blockerrlin[j][i] / nrcolor[j]; if (newvalue <= 0) { testcolor[j][i] = 0; } else if (newvalue >= 255) { testcolor[j][i] = 255; } else { testcolor[j][i] = (byte)newvalue; } } } if ((Math.Abs(testcolor[0][0] - testcolor[1][0]) < 8) && (Math.Abs(testcolor[0][1] - testcolor[1][1]) < 4) && (Math.Abs(testcolor[0][2] - testcolor[1][2]) < 8)) { var coldiffred = (byte)Math.Abs(testcolor[0][0] - testcolor[1][0]); var coldiffgreen = (byte)(2 * Math.Abs(testcolor[0][1] - testcolor[1][1])); var coldiffblue = (byte)Math.Abs(testcolor[0][2] - testcolor[1][2]); var coldiffmax = coldiffred; if (coldiffmax < coldiffgreen) { coldiffmax = coldiffgreen; } if (coldiffmax < coldiffblue) { coldiffmax = coldiffblue; } if (coldiffmax > 0) { GLubyte factor; if (coldiffmax > 4) { factor = 2; } else if (coldiffmax > 2) { factor = 3; } else { factor = 4; } GLubyte ind0; GLubyte ind1; if (testcolor[1][1] >= testcolor[0][1]) { ind1 = 1; ind0 = 0; } else { ind1 = 0; ind0 = 1; } if ((testcolor[ind1][1] + factor * coldiffgreen) <= 255) { testcolor[ind1][1] += (byte)(factor * coldiffgreen); } else { testcolor[ind1][1] = 255; } if ((testcolor[ind1][0] - testcolor[ind0][1]) > 0) { if ((testcolor[ind1][0] + factor * coldiffred) <= 255) { testcolor[ind1][0] += (byte)(factor * coldiffred); } else { testcolor[ind1][0] = 255; } } else { if ((testcolor[ind0][0] + factor * coldiffred) <= 255) { testcolor[ind0][0] += (byte)(factor * coldiffred); } else { testcolor[ind0][0] = 255; } } if ((testcolor[ind1][2] - testcolor[ind0][2]) > 0) { if ((testcolor[ind1][2] + factor * coldiffblue) <= 255) { testcolor[ind1][2] += (byte)(factor * coldiffblue); } else { testcolor[ind1][2] = 255; } } else { if ((testcolor[ind0][2] + factor * coldiffblue) <= 255) { testcolor[ind0][2] += (byte)(factor * coldiffblue); } else { testcolor[ind0][2] = 255; } } } } if (((testcolor[0][0] & 0xf8) << 8 | (testcolor[0][1] & 0xfc) << 3 | testcolor[0][2] >> 3) < ((testcolor[1][0] & 0xf8) << 8 | (testcolor[1][1] & 0xfc) << 3 | testcolor[1][2]) >> 3) { for (i = 0; i < 3; i++) { bestcolor[0][i] = testcolor[0][i]; bestcolor[1][i] = testcolor[1][i]; } } else { for (i = 0; i < 3; i++) { bestcolor[0][i] = testcolor[1][i]; bestcolor[1][i] = testcolor[0][i]; } } }
public unsafe static extern void GetIntegerv(GLenum pname, [OutAttribute] GLint * @params);
public unsafe static extern void ShaderSource(GLuint shader, GLsizei count, GLchar ** @string, GLint *length);
public unsafe static extern void GetShaderiv(GLuint shader, GLenum pname, [OutAttribute] GLint *pParams);
public unsafe static extern void TexParameteriv(GLenum target, GLenum pname, GLint *@params);