public void BlendLineShallow(sPixel col, OutputMatrix output) { _AlphaBlend(1, 4, output.Reference(_SCALE - 1, 0), col); _AlphaBlend(1, 4, output.Reference(_SCALE - 2, 2), col); _AlphaBlend(3, 4, output.Reference(_SCALE - 1, 1), col); output.Reference(_SCALE - 1, 2).SetPixel(col); }
public void BlendCorner(sPixel col, OutputMatrix output) { //model a round corner _AlphaBlend(68, 100, output.Reference(3, 3), col); //exact: 0.6848532563 _AlphaBlend(9, 100, output.Reference(3, 2), col); //0.08677704501 _AlphaBlend(9, 100, output.Reference(2, 3), col); //0.08677704501 }
public void BlendLineSteep(sPixel col, OutputMatrix output) { _AlphaBlend(1, 4, output.Reference(0, _SCALE - 1), col); _AlphaBlend(1, 4, output.Reference(2, _SCALE - 2), col); _AlphaBlend(3, 4, output.Reference(1, _SCALE - 1), col); output.Reference(2, _SCALE - 1).SetPixel(col); }
public void BlendCorner(sPixel col, OutputMatrix output) { //model a round corner _AlphaBlend(45, 100, output.Reference(2, 2), col); //exact: 0.4545939598 //alphaBlend(14, 1000, out.ref(2, 1), col); //0.01413008627 -> negligable //alphaBlend(14, 1000, out.ref(1, 2), col); //0.01413008627 }
public void BlendLineSteepAndShallow(sPixel col, OutputMatrix output) { _AlphaBlend(1, 4, output.Reference(2, 0), col); _AlphaBlend(1, 4, output.Reference(0, 2), col); _AlphaBlend(3, 4, output.Reference(2, 1), col); _AlphaBlend(3, 4, output.Reference(1, 2), col); output.Reference(2, 2).SetPixel(col); }
public void BlendCorner(sPixel col, OutputMatrix output) { //model a round corner _AlphaBlend(97, 100, output.Reference(5, 5), col); //exact: 0.9711013910 _AlphaBlend(42, 100, output.Reference(4, 5), col); //0.4236372243 _AlphaBlend(42, 100, output.Reference(5, 4), col); //0.4236372243 _AlphaBlend(6, 100, output.Reference(5, 3), col); //0.05652034508 _AlphaBlend(6, 100, output.Reference(3, 5), col); //0.05652034508 }
public void BlendLineDiagonal(sPixel col, OutputMatrix output) { _AlphaBlend(1, 8, output.Reference(_SCALE - 1, _SCALE / 2), col); _AlphaBlend(1, 8, output.Reference(_SCALE - 2, _SCALE / 2 + 1), col); _AlphaBlend(1, 8, output.Reference(_SCALE - 3, _SCALE / 2 + 2), col); _AlphaBlend(7, 8, output.Reference(4, 3), col); _AlphaBlend(7, 8, output.Reference(3, 4), col); output.Reference(4, 4).SetPixel(col); }
public void BlendCorner(sPixel col, OutputMatrix output) { //model a round corner _AlphaBlend(86, 100, output.Reference(4, 4), col); //exact: 0.8631434088 _AlphaBlend(23, 100, output.Reference(4, 3), col); //0.2306749731 _AlphaBlend(23, 100, output.Reference(3, 4), col); //0.2306749731 //alphaBlend(8, 1000, out.ref(4, 2), col); //0.008384061834 -> negligable //alphaBlend(8, 1000, out.ref(2, 4), col); //0.008384061834 }
/// <summary> /// Рисует найденные прямоугольники <seealso cref="Rect"/>. /// </summary> public void DrawFaceRectangles() { if(OutputMatrix != null) { foreach(var faceRectangle in DetectedFaces) { OutputMatrix.DrawRect(faceRectangle); } } }
public void BlendLineSteepAndShallow(sPixel col, OutputMatrix output) { _AlphaBlend(3, 4, output.Reference(3, 1), col); _AlphaBlend(3, 4, output.Reference(1, 3), col); _AlphaBlend(1, 4, output.Reference(3, 0), col); _AlphaBlend(1, 4, output.Reference(0, 3), col); _AlphaBlend(1, 3, output.Reference(2, 2), col); //[!] fixes 1/4 used in xBR output.Reference(3, 3).SetPixel(col); output.Reference(3, 2).SetPixel(col); output.Reference(2, 3).SetPixel(col); }
public bool HW1() { string dbgout = ""; DebugLog.Log("HW1 - Simple"); InputMatrix in1 = new InputMatrix(5); SubZone sz1 = new SubZone(5); OutputMatrix out1 = new OutputMatrix(5); in1.setUpSubZone(sz1); sz1.setDownSubZones(in1); sz1.setUpSubZone(out1); out1.addInputs(sz1); DebugLog.Log("Learn"); bool[][] in_p1 = new bool[][] { new bool[] { true, false, false, false, false }, new bool[] { false, true, false, false, false }, new bool[] { false, false, true, false, false }, new bool[] { false, false, false, true, false }, new bool[] { false, false, false, false, true }, }; for (int i = 0; i < in_p1.Length; i++) { in1.setBooleans(in_p1[i]); sz1.setColumnNeurons(i, in1.inputs); } for (int n = 0; n < in_p1.Length; n++) { out1.reset(); DebugLog.Log("Analyse " + n + " pattern"); in1.setBooleans(in_p1[n]); dbgout = ""; for (int i = 0; i < in1.inputs.Length; i++) { dbgout += (in1.inputs[i].active > 0.8f ? "A" : "_") + " "; } DebugLog.Log("Pattern : " + dbgout); in1.sendSignals(); sz1.analyze(); dbgout = ""; for (int i = 0; i < out1.inputs.Length; i++) { dbgout += (out1.inputsActives[i] > 0.8f ? "A" : "_") + " "; } DebugLog.Log("Columns : " + dbgout); out1.reset(); } //sz1.teach(); return(true); }
public void BlendLineSteepAndShallow(sPixel col, OutputMatrix output) { _AlphaBlend(1, 4, output.Reference(0, _SCALE - 1), col); _AlphaBlend(1, 4, output.Reference(2, _SCALE - 2), col); _AlphaBlend(3, 4, output.Reference(1, _SCALE - 1), col); _AlphaBlend(1, 4, output.Reference(_SCALE - 1, 0), col); _AlphaBlend(1, 4, output.Reference(_SCALE - 2, 2), col); _AlphaBlend(3, 4, output.Reference(_SCALE - 1, 1), col); output.Reference(2, _SCALE - 1).SetPixel(col); output.Reference(3, _SCALE - 1).SetPixel(col); output.Reference(_SCALE - 1, 2).SetPixel(col); output.Reference(_SCALE - 1, 3).SetPixel(col); output.Reference(4, _SCALE - 1).SetPixel(col); _AlphaBlend(2, 3, output.Reference(3, 3), col); }
public void BlendCorner(sPixel col, OutputMatrix output) { //model a round corner _AlphaBlend(45, 100, output.Reference(2, 2), col); //exact: 0.4545939598 //alphaBlend(14, 1000, out.ref(2, 1), col); //0.01413008627 -> negligable //alphaBlend(14, 1000, out.ref(1, 2), col); //0.01413008627 }
public void BlendCorner(sPixel col, OutputMatrix output) { //model a round corner _AlphaBlend(21, 100, output.Reference(1, 1), col); //exact: 1 - pi/4 = 0.2146018366 }
public static void ScaleImage(ScaleSize scaleSize, sPixel[] src, sPixel[] trg, int srcWidth, int srcHeight, int xFirst, int yFirst, int xLast, int yLast) { yFirst = Math.Max(yFirst, 0); yLast = Math.Min(yLast, srcHeight); if (yFirst >= yLast || srcWidth <= 0) return; var trgWidth = srcWidth * scaleSize.size; //temporary buffer for "on the fly preprocessing" var preProcBuffer = new byte[srcWidth]; var ker4 = new Kernel_4X4(); var preProcessCornersColorDist = new ColorDistA(); //initialize preprocessing buffer for first row: //detect upper left and right corner blending //this cannot be optimized for adjacent processing //stripes; we must not allow for a memory race condition! if (yFirst > 0) { var y = yFirst - 1; var sM1 = srcWidth * Math.Max(y - 1, 0); var s0 = srcWidth * y; //center line var sP1 = srcWidth * Math.Min(y + 1, srcHeight - 1); var sP2 = srcWidth * Math.Min(y + 2, srcHeight - 1); for (var x = xFirst; x < xLast; ++x) { var xM1 = Math.Max(x - 1, 0); var xP1 = Math.Min(x + 1, srcWidth - 1); var xP2 = Math.Min(x + 2, srcWidth - 1); //read sequentially from memory as far as possible ker4.b = src[sM1 + x]; ker4.c = src[sM1 + xP1]; ker4.e = src[s0 + xM1]; ker4.f = src[s0 + x]; ker4.g = src[s0 + xP1]; ker4.h = src[s0 + xP2]; ker4.i = src[sP1 + xM1]; ker4.j = src[sP1 + x]; ker4.k = src[sP1 + xP1]; ker4.l = src[sP1 + xP2]; ker4.n = src[sP2 + x]; ker4.o = src[sP2 + xP1]; var blendResult = new BlendResult(); _PreProcessCorners(ker4, blendResult, preProcessCornersColorDist); // writes to blendResult /* preprocessing blend result: --------- | F | G | //evalute corner between F, G, J, K ----|---| //input pixel is at position F | J | K | --------- */ preProcBuffer[x] = BlendInfo.SetTopR(preProcBuffer[x], blendResult.j); if (x + 1 < srcWidth) preProcBuffer[x + 1] = BlendInfo.SetTopL(preProcBuffer[x + 1], blendResult.k); } } var eqColorThres = _Square(_CONFIGURATION.equalColorTolerance); var scalePixelColorEq = new ColorEqA(eqColorThres); var scalePixelColorDist = new ColorDistA(); var outputMatrix = new OutputMatrix(scaleSize.size, trg, trgWidth); var ker3 = new Kernel_3X3(); for (var y = yFirst; y < yLast; ++y) { //consider MT "striped" access var trgi = scaleSize.size * y * trgWidth; var sM1 = srcWidth * Math.Max(y - 1, 0); var s0 = srcWidth * y; //center line var sP1 = srcWidth * Math.Min(y + 1, srcHeight - 1); var sP2 = srcWidth * Math.Min(y + 2, srcHeight - 1); byte blendXy1 = 0; for (var x = xFirst; x < xLast; ++x, trgi += scaleSize.size) { var xM1 = Math.Max(x - 1, 0); var xP1 = Math.Min(x + 1, srcWidth - 1); var xP2 = Math.Min(x + 2, srcWidth - 1); //evaluate the four corners on bottom-right of current pixel //blend_xy for current (x, y) position byte blendXy; { //read sequentially from memory as far as possible ker4.b = src[sM1 + x]; ker4.c = src[sM1 + xP1]; ker4.e = src[s0 + xM1]; ker4.f = src[s0 + x]; ker4.g = src[s0 + xP1]; ker4.h = src[s0 + xP2]; ker4.i = src[sP1 + xM1]; ker4.j = src[sP1 + x]; ker4.k = src[sP1 + xP1]; ker4.l = src[sP1 + xP2]; ker4.n = src[sP2 + x]; ker4.o = src[sP2 + xP1]; var blendResult = new BlendResult(); _PreProcessCorners(ker4, blendResult, preProcessCornersColorDist); // writes to blendResult /* preprocessing blend result: --------- | F | G | //evaluate corner between F, G, J, K ----|---| //current input pixel is at position F | J | K | --------- */ //all four corners of (x, y) have been determined at //this point due to processing sequence! blendXy = BlendInfo.SetBottomR(preProcBuffer[x], blendResult.f); //set 2nd known corner for (x, y + 1) blendXy1 = BlendInfo.SetTopR(blendXy1, blendResult.j); //store on current buffer position for use on next row preProcBuffer[x] = blendXy1; //set 1st known corner for (x + 1, y + 1) and //buffer for use on next column blendXy1 = BlendInfo.SetTopL(0, blendResult.k); if (x + 1 < srcWidth) //set 3rd known corner for (x + 1, y) preProcBuffer[x + 1] = BlendInfo.SetBottomL(preProcBuffer[x + 1], blendResult.g); } //fill block of size scale * scale with the given color // //place *after* preprocessing step, to not overwrite the // //results while processing the the last pixel! _FillBlock(trg, trgi, trgWidth, src[s0 + x], scaleSize.size); //blend four corners of current pixel if (blendXy == 0) continue; const int a = 0, b = 1, c = 2, d = 3, e = 4, f = 5, g = 6, h = 7, i = 8; //read sequentially from memory as far as possible ker3._[a] = src[sM1 + xM1]; ker3._[b] = src[sM1 + x]; ker3._[c] = src[sM1 + xP1]; ker3._[d] = src[s0 + xM1]; ker3._[e] = src[s0 + x]; ker3._[f] = src[s0 + xP1]; ker3._[g] = src[sP1 + xM1]; ker3._[h] = src[sP1 + x]; ker3._[i] = src[sP1 + xP1]; _ScalePixel(scaleSize.scaler, RotationDegree.Rot0, ker3, trg, trgi, trgWidth, blendXy, scalePixelColorEq, scalePixelColorDist, outputMatrix); _ScalePixel(scaleSize.scaler, RotationDegree.Rot90, ker3, trg, trgi, trgWidth, blendXy, scalePixelColorEq, scalePixelColorDist, outputMatrix); _ScalePixel(scaleSize.scaler, RotationDegree.Rot180, ker3, trg, trgi, trgWidth, blendXy, scalePixelColorEq, scalePixelColorDist, outputMatrix); _ScalePixel(scaleSize.scaler, RotationDegree.Rot270, ker3, trg, trgi, trgWidth, blendXy, scalePixelColorEq, scalePixelColorDist, outputMatrix); } } }
public void HW2() { string dbgout = ""; DebugLog.Log("HW2 - Sequence"); InputMatrix in1 = new InputMatrix(5); SubZone sz1 = new SubZone(5); OutputMatrix out1 = new OutputMatrix(5); in1.setUpSubZone(sz1); sz1.setDownSubZones(in1); sz1.setUpSubZone(out1); out1.addInputs(sz1); DebugLog.Log("Learn"); bool[][] in_p1 = new bool[][] { new bool[] { true, true, false, false, false }, new bool[] { false, true, true, false, false }, }; for (int i = 0; i < in_p1.Length; i++) { in1.setBooleans(in_p1[i]); sz1.setColumnNeurons(0, in1.inputs); } bool[][] in_p2 = new bool[][] { new bool[] { false, false, true, true, false }, new bool[] { false, false, false, true, true }, }; for (int i = 0; i < in_p2.Length; i++) { in1.setBooleans(in_p2[i]); sz1.setColumnNeurons(1, in1.inputs); } bool[][] in_p3 = new bool[][] { new bool[] { false, false, true, true, false }, new bool[] { false, true, true, false, false }, new bool[] { true, true, false, false, false }, }; for (int i = 0; i < in_p3.Length; i++) { in1.setBooleans(in_p3[i]); sz1.setColumnNeurons(2, in1.inputs); } bool[][] in_p4 = new bool[][] { new bool[] { true, false, false, false, true }, new bool[] { false, true, false, true, false }, new bool[] { false, false, true, false, false }, }; for (int i = 0; i < in_p4.Length; i++) { in1.setBooleans(in_p4[i]); sz1.setColumnNeurons(3, in1.inputs); } bool[][] in_p5 = new bool[][] { new bool[] { true, false, false, false, false }, new bool[] { false, true, false, false, false }, new bool[] { false, false, true, false, false }, new bool[] { false, false, false, true, false }, new bool[] { false, false, false, false, true }, }; for (int i = 0; i < in_p5.Length; i++) { in1.setBooleans(in_p5[i]); sz1.setColumnNeurons(4, in1.inputs); } bool[][] in_p = new bool[][] { new bool[] { true, false, false, false, false }, // 5 new bool[] { false, true, false, false, false }, // 5 new bool[] { false, false, true, false, false }, // 5 new bool[] { false, false, false, true, false }, // 5 new bool[] { false, false, false, false, true }, // 5 new bool[] { false, false, false, true, true }, // _ new bool[] { false, false, true, true, false }, // 2, 3 new bool[] { false, true, true, false, false }, // 3 new bool[] { true, true, false, false, false }, // 3, 1 new bool[] { false, true, true, false, false }, // 1 new bool[] { false, false, true, true, false }, // 2 new bool[] { false, false, false, true, true }, // 2 new bool[] { true, false, false, false, true }, // 4 new bool[] { false, true, false, true, false }, // 4 new bool[] { false, false, true, false, false }, // 4 new bool[] { false, false, false, true, false }, // _ new bool[] { false, false, false, false, true }, // _ new bool[] { true, false, false, false, false }, // 5 new bool[] { false, true, false, false, false }, // 5 new bool[] { false, false, true, false, false }, // 5 new bool[] { true, false, false, false, true }, // 4 new bool[] { false, true, false, true, false }, // 4 new bool[] { false, false, true, true, false }, // 3 new bool[] { false, true, true, false, false }, // 3 new bool[] { true, true, false, false, false }, // 3 new bool[] { true, false, false, false, true }, // 4 new bool[] { true, true, false, false, false }, // 1 new bool[] { false, true, true, false, false }, // 1 new bool[] { false, false, true, true, false }, // 3 new bool[] { false, false, false, true, true }, // _ }; bool[][] in_e = new bool[][] { new bool[] { false, false, false, false, true }, // 5 new bool[] { false, false, false, false, true }, // 5 new bool[] { false, false, false, false, true }, // 5 new bool[] { false, false, false, false, true }, // 5 new bool[] { false, false, false, false, true }, // 5 new bool[] { false, false, false, false, false }, // _ new bool[] { false, true, true, false, false }, // 2, 3 new bool[] { false, false, true, false, false }, // 3 new bool[] { true, false, true, false, false }, // 3, 1 new bool[] { true, false, false, false, false }, // 1 new bool[] { false, true, false, false, true }, // 2, 5 new bool[] { false, true, false, false, false }, // 2 new bool[] { false, false, false, true, false }, // 4 new bool[] { false, false, false, true, false }, // 4 new bool[] { false, false, false, true, false }, // 4 new bool[] { false, false, false, false, false }, // _ new bool[] { false, false, false, false, false }, // _ new bool[] { false, false, false, false, true }, // 5 new bool[] { false, false, false, false, true }, // 5 new bool[] { false, false, false, false, true }, // 5 new bool[] { false, false, false, true, false }, // 4 new bool[] { false, false, false, true, false }, // 4 new bool[] { false, true, true, false, false }, // 3, 2 new bool[] { false, false, true, false, false }, // 3 new bool[] { false, false, true, false, false }, // 3 new bool[] { false, false, false, true, false }, // 4 new bool[] { true, false, false, false, false }, // 1 new bool[] { true, false, false, false, false }, // 1 new bool[] { false, true, false, false, false }, // 2 new bool[] { false, true, false, false, false }, // 2 }; for (int n = 0; n < in_p.Length; n++) { DebugLog.Log("Analyse " + n + " pattern"); in1.setBooleans(in_p[n]); dbgout = ""; for (int i = 0; i < in1.inputs.Length; i++) { dbgout += (in1.inputs[i].active > 0.8f ? "A" : "_") + " "; } DebugLog.Log("Pattern : " + dbgout); dbgout = ""; for (int i = 0; i < in1.inputs.Length; i++) { dbgout += (in_e[n][i] ? "A" : "_") + " "; } DebugLog.Log("Etalon : " + dbgout); in1.sendSignals(); sz1.analyze(); dbgout = ""; for (int i = 0; i < out1.inputs.Length; i++) { dbgout += (out1.inputsActives[i] > 0.8f ? "A" : "_") + " "; } DebugLog.Log("Columns : " + dbgout); dbgout = ""; for (int i = 0; i < out1.inputs.Length; i++) { dbgout += (in1.inputs[i].prediction >= 0.5f ? "A" : "_") + " "; } DebugLog.Log("Prediction : " + dbgout); out1.reset(); } //sz1.teach(); }
public void BlendLineSteepAndShallow(sPixel col, OutputMatrix output) { _AlphaBlend(1, 4, output.Reference(1, 0), col); _AlphaBlend(1, 4, output.Reference(0, 1), col); _AlphaBlend(5, 6, output.Reference(1, 1), col); //[!] fixes 7/8 used in xBR }
public void BlendLineShallow(sPixel col, OutputMatrix output) { _AlphaBlend(1, 4, output.Reference(_SCALE - 1, 0), col); _AlphaBlend(3, 4, output.Reference(_SCALE - 1, 1), col); }
public void BlendLineSteepAndShallow(sPixel col, OutputMatrix output) { _AlphaBlend(1, 4, output.Reference(2, 0), col); _AlphaBlend(1, 4, output.Reference(0, 2), col); _AlphaBlend(3, 4, output.Reference(2, 1), col); _AlphaBlend(3, 4, output.Reference(1, 2), col); output.Reference(2, 2).SetPixel(col); }
public void BlendLineSteepAndShallow(sPixel col, OutputMatrix output) { _AlphaBlend(1, 4, output.Reference(1, 0), col); _AlphaBlend(1, 4, output.Reference(0, 1), col); _AlphaBlend(5, 6, output.Reference(1, 1), col); //[!] fixes 7/8 used in xBR }
public void BlendLineSteep(sPixel col, OutputMatrix output) { _AlphaBlend(1, 4, output.Reference(0, _SCALE - 1), col); _AlphaBlend(1, 4, output.Reference(2, _SCALE - 2), col); _AlphaBlend(1, 4, output.Reference(4, _SCALE - 3), col); _AlphaBlend(3, 4, output.Reference(1, _SCALE - 1), col); _AlphaBlend(3, 4, output.Reference(3, _SCALE - 2), col); output.Reference(2, _SCALE - 1).SetPixel(col); output.Reference(3, _SCALE - 1).SetPixel(col); output.Reference(4, _SCALE - 1).SetPixel(col); output.Reference(4, _SCALE - 2).SetPixel(col); }
public void BlendLineSteepAndShallow(sPixel col, OutputMatrix output) { _AlphaBlend(1, 4, output.Reference(0, _SCALE - 1), col); _AlphaBlend(1, 4, output.Reference(2, _SCALE - 2), col); _AlphaBlend(3, 4, output.Reference(1, _SCALE - 1), col); _AlphaBlend(1, 4, output.Reference(_SCALE - 1, 0), col); _AlphaBlend(1, 4, output.Reference(_SCALE - 2, 2), col); _AlphaBlend(3, 4, output.Reference(_SCALE - 1, 1), col); output.Reference(2, _SCALE - 1).SetPixel(col); output.Reference(3, _SCALE - 1).SetPixel(col); output.Reference(_SCALE - 1, 2).SetPixel(col); output.Reference(_SCALE - 1, 3).SetPixel(col); output.Reference(4, _SCALE - 1).SetPixel(col); _AlphaBlend(2, 3, output.Reference(3, 3), col); }
public void BlendLineShallow(sPixel col, OutputMatrix output) { _AlphaBlend(1, 4, output.Reference(_SCALE - 1, 0), col); _AlphaBlend(1, 4, output.Reference(_SCALE - 2, 2), col); _AlphaBlend(1, 4, output.Reference(_SCALE - 3, 4), col); _AlphaBlend(3, 4, output.Reference(_SCALE - 1, 1), col); _AlphaBlend(3, 4, output.Reference(_SCALE - 2, 3), col); output.Reference(_SCALE - 1, 2).SetPixel(col); output.Reference(_SCALE - 1, 3).SetPixel(col); output.Reference(_SCALE - 1, 4).SetPixel(col); output.Reference(_SCALE - 2, 4).SetPixel(col); }
public void BlendCorner(sPixel col, OutputMatrix output) { //model a round corner _AlphaBlend(68, 100, output.Reference(3, 3), col); //exact: 0.6848532563 _AlphaBlend(9, 100, output.Reference(3, 2), col); //0.08677704501 _AlphaBlend(9, 100, output.Reference(2, 3), col); //0.08677704501 }
public void BlendLineSteepAndShallow(sPixel col, OutputMatrix output) { _AlphaBlend(3, 4, output.Reference(3, 1), col); _AlphaBlend(3, 4, output.Reference(1, 3), col); _AlphaBlend(1, 4, output.Reference(3, 0), col); _AlphaBlend(1, 4, output.Reference(0, 3), col); _AlphaBlend(1, 3, output.Reference(2, 2), col); //[!] fixes 1/4 used in xBR output.Reference(3, 3).SetPixel(col); output.Reference(3, 2).SetPixel(col); output.Reference(2, 3).SetPixel(col); }
/* * input kernel area naming convention: * ------------- | A | B | C | | ----|---|---| | D | E | F | //input pixel is at position E | ----|---|---| | G | H | I | | ------------- */ private static void _ScalePixel( IScaler scaler, RotationDegree rotDeg, Kernel_3X3 ker, sPixel[] trg, int trgi, int trgWidth, byte blendInfo, //result of preprocessing all four corners of pixel "e" IColorEq scalePixelColorEq, IColorDist scalePixelColorDist, OutputMatrix outputMatrix ) { //int a = kernel._[Rot._[(0 << 2) + rotDeg]]; var b = ker._[Rot._[(1 << 2) + (int)rotDeg]]; var c = ker._[Rot._[(2 << 2) + (int)rotDeg]]; var d = ker._[Rot._[(3 << 2) + (int)rotDeg]]; var e = ker._[Rot._[(4 << 2) + (int)rotDeg]]; var f = ker._[Rot._[(5 << 2) + (int)rotDeg]]; var g = ker._[Rot._[(6 << 2) + (int)rotDeg]]; var h = ker._[Rot._[(7 << 2) + (int)rotDeg]]; var i = ker._[Rot._[(8 << 2) + (int)rotDeg]]; var blend = BlendInfo.Rotate(blendInfo, rotDeg); if (BlendInfo.GetBottomR(blend) == BlendType.BlendNone) { return; } var eq = scalePixelColorEq; var dist = scalePixelColorDist; bool doLineBlend; if (BlendInfo.GetBottomR(blend) >= BlendType.BlendDominant) { doLineBlend = true; } //make sure there is no second blending in an adjacent //rotation for this pixel: handles insular pixels, mario eyes //but support double-blending for 90? corners else if (BlendInfo.GetTopR(blend) != BlendType.BlendNone && !eq._(e, g)) { doLineBlend = false; } else if (BlendInfo.GetBottomL(blend) != BlendType.BlendNone && !eq._(e, c)) { doLineBlend = false; } //no full blending for L-shapes; blend corner only (handles "mario mushroom eyes") else if (eq._(g, h) && eq._(h, i) && eq._(i, f) && eq._(f, c) && !eq._(e, i)) { doLineBlend = false; } else { doLineBlend = true; } //choose most similar color var px = dist._(e, f) <= dist._(e, h) ? f : h; var output = outputMatrix; output.Move(rotDeg, trgi); if (!doLineBlend) { scaler.BlendCorner(px, output); return; } //test sample: 70% of values max(fg, hc) / min(fg, hc) //are between 1.1 and 3.7 with median being 1.9 var fg = dist._(f, g); var hc = dist._(h, c); var haveShallowLine = _CONFIGURATION.steepDirectionThreshold * fg <= hc && e != g && d != g; var haveSteepLine = _CONFIGURATION.steepDirectionThreshold * hc <= fg && e != c && b != c; if (haveShallowLine) { if (haveSteepLine) { scaler.BlendLineSteepAndShallow(px, output); } else { scaler.BlendLineShallow(px, output); } } else { if (haveSteepLine) { scaler.BlendLineSteep(px, output); } else { scaler.BlendLineDiagonal(px, output); } } }
public static void Main(string[] args) { /* * XorShift160 lol = new XorShift160(); * double runningSum = 0; * * while (!Console.KeyAvailable) * { * Console.WriteLine(lol.NextDouble()); * } * return; */ IStateMatrix A = new StateMatrix(2, 2); A.SetValue(0, 0, 0); A.SetValue(0, 1, 1); A.SetValue(1, 0, 0); A.SetValue(1, 0, 0); /* * var c = new CompiledMatrix<IStateMatrix>(A); * c.Compile(); */ IInputMatrix B = new InputMatrix(2, 1); B.SetValue(0, 0, 0); B.SetValue(1, 0, 1); IOutputMatrix C = new OutputMatrix(2, 2); C.SetValue(0, 0, 1); C.SetValue(0, 1, 0); C.SetValue(1, 0, 0); C.SetValue(1, 1, 1); IFeedthroughMatrix D = new FeedthroughMatrix(2, 1); D.SetValue(0, 0, 0); D.SetValue(1, 0, 0); ControlVector u = new ControlVector(1); u.SetValue(0, 1); // TODO: Construct vectors and matrices by factory and let the simulation driver compile them after every external change IStateVector x = new StateVector(2); /* * IStateVector dx = new StateVector(x.Length); * IStateVector dxu = new StateVector(x.Length); * IOutputVector y = new OutputVector(C.Rows); * IOutputVector yu = new OutputVector(C.Rows); */ CancellationTokenSource cts = new CancellationTokenSource(); CancellationToken ct = cts.Token; Semaphore startCalculation = new Semaphore(0, 2); Semaphore calculationDone = new Semaphore(0, 2); SimulationTime simulationTime = new SimulationTime(); IStateVector dx = new StateVector(x.Length); Task inputToState = new Task(() => { IStateVector dxu = new StateVector(x.Length); while (!ct.IsCancellationRequested) { startCalculation.WaitOne(); Thread.MemoryBarrier(); A.Transform(x, ref dx); B.Transform(u, ref dxu); // TODO: TransformAndAdd() dx.AddInPlace(dxu); Thread.MemoryBarrier(); calculationDone.Release(); } }); IOutputVector y = new OutputVector(C.Rows); Task stateToOutput = new Task(() => { IOutputVector yu = new OutputVector(C.Rows); while (!ct.IsCancellationRequested) { startCalculation.WaitOne(); Thread.MemoryBarrier(); C.Transform(x, ref y); D.Transform(u, ref yu); // TODO: TransformAndAdd() y.AddInPlace(yu); Thread.MemoryBarrier(); calculationDone.Release(); } }); Task control = new Task(() => { Stopwatch watch = Stopwatch.StartNew(); int steps = 0; while (!ct.IsCancellationRequested) { // wait for a new u to be applied // TODO: apply control vector startCalculation.Release(2); // wait for y calculationDone.WaitOne(); calculationDone.WaitOne(); Thread.MemoryBarrier(); // wait for state vector to be changeable // TODO: perform real transformation x.AddInPlace(dx); // discrete integration, T=1 // video killed the radio star if (steps % 1000 == 0) { var localY = y; double thingy = steps / watch.Elapsed.TotalSeconds; Trace.WriteLine(simulationTime.Time + " Position: " + localY.GetValue(0) + ", Velocity: " + localY.GetValue(1) + ", Acceleration: " + u.GetValue(0) + ", throughput: " + thingy); } // cancel out acceleration if (steps++ == 10) { u.SetValue(0, 0); } // advance simulation time simulationTime.Add(TimeSpan.FromSeconds(1)); } }); inputToState.Start(); stateToOutput.Start(); control.Start(); Console.ReadKey(true); cts.Cancel(); /* * while (!Console.KeyAvailable) * { * A.Transform(x, ref dx); * B.Transform(u, ref dxu); // TODO: TransformAndAdd() * dx.AddInPlace(dxu); * * // TODO: perform transformation * x.AddInPlace(dx); // discrete integration, T=1 * * C.Transform(x, ref y); * D.Transform(u, ref yu); // TODO: TransformAndAdd() * y.AddInPlace(yu); * * // video killed the radio star * if (steps%1000 == 0) * { * Trace.WriteLine("Position: " + y[0] + ", Velocity: " + y[1] + ", Acceleration: " + u[0] + ", throughput: " + steps/watch.Elapsed.TotalSeconds); * } * * // cancel out acceleration * if (steps++ == 10) * { * u[0] = 0; * } * } */ }
public static void ScaleImage(ScaleSize scaleSize, sPixel[] src, sPixel[] trg, int srcWidth, int srcHeight, int xFirst, int yFirst, int xLast, int yLast) { yFirst = Math.Max(yFirst, 0); yLast = Math.Min(yLast, srcHeight); if (yFirst >= yLast || srcWidth <= 0) { return; } var trgWidth = srcWidth * scaleSize.size; //temporary buffer for "on the fly preprocessing" var preProcBuffer = new byte[srcWidth]; var ker4 = new Kernel_4X4(); var preProcessCornersColorDist = new ColorDistA(); //initialize preprocessing buffer for first row: //detect upper left and right corner blending //this cannot be optimized for adjacent processing //stripes; we must not allow for a memory race condition! if (yFirst > 0) { var y = yFirst - 1; var sM1 = srcWidth * Math.Max(y - 1, 0); var s0 = srcWidth * y; //center line var sP1 = srcWidth * Math.Min(y + 1, srcHeight - 1); var sP2 = srcWidth * Math.Min(y + 2, srcHeight - 1); for (var x = xFirst; x < xLast; ++x) { var xM1 = Math.Max(x - 1, 0); var xP1 = Math.Min(x + 1, srcWidth - 1); var xP2 = Math.Min(x + 2, srcWidth - 1); //read sequentially from memory as far as possible ker4.b = src[sM1 + x]; ker4.c = src[sM1 + xP1]; ker4.e = src[s0 + xM1]; ker4.f = src[s0 + x]; ker4.g = src[s0 + xP1]; ker4.h = src[s0 + xP2]; ker4.i = src[sP1 + xM1]; ker4.j = src[sP1 + x]; ker4.k = src[sP1 + xP1]; ker4.l = src[sP1 + xP2]; ker4.n = src[sP2 + x]; ker4.o = src[sP2 + xP1]; var blendResult = new BlendResult(); _PreProcessCorners(ker4, blendResult, preProcessCornersColorDist); // writes to blendResult /* * preprocessing blend result: * --------- | F | G | //evalute corner between F, G, J, K | ----|---| //input pixel is at position F | J | K | | --------- */ preProcBuffer[x] = BlendInfo.SetTopR(preProcBuffer[x], blendResult.j); if (x + 1 < srcWidth) { preProcBuffer[x + 1] = BlendInfo.SetTopL(preProcBuffer[x + 1], blendResult.k); } } } var eqColorThres = _Square(_CONFIGURATION.equalColorTolerance); var scalePixelColorEq = new ColorEqA(eqColorThres); var scalePixelColorDist = new ColorDistA(); var outputMatrix = new OutputMatrix(scaleSize.size, trg, trgWidth); var ker3 = new Kernel_3X3(); for (var y = yFirst; y < yLast; ++y) { //consider MT "striped" access var trgi = scaleSize.size * y * trgWidth; var sM1 = srcWidth * Math.Max(y - 1, 0); var s0 = srcWidth * y; //center line var sP1 = srcWidth * Math.Min(y + 1, srcHeight - 1); var sP2 = srcWidth * Math.Min(y + 2, srcHeight - 1); byte blendXy1 = 0; for (var x = xFirst; x < xLast; ++x, trgi += scaleSize.size) { var xM1 = Math.Max(x - 1, 0); var xP1 = Math.Min(x + 1, srcWidth - 1); var xP2 = Math.Min(x + 2, srcWidth - 1); //evaluate the four corners on bottom-right of current pixel //blend_xy for current (x, y) position byte blendXy; { //read sequentially from memory as far as possible ker4.b = src[sM1 + x]; ker4.c = src[sM1 + xP1]; ker4.e = src[s0 + xM1]; ker4.f = src[s0 + x]; ker4.g = src[s0 + xP1]; ker4.h = src[s0 + xP2]; ker4.i = src[sP1 + xM1]; ker4.j = src[sP1 + x]; ker4.k = src[sP1 + xP1]; ker4.l = src[sP1 + xP2]; ker4.n = src[sP2 + x]; ker4.o = src[sP2 + xP1]; var blendResult = new BlendResult(); _PreProcessCorners(ker4, blendResult, preProcessCornersColorDist); // writes to blendResult /* * preprocessing blend result: * --------- | F | G | //evaluate corner between F, G, J, K | ----|---| //current input pixel is at position F | J | K | | --------- */ //all four corners of (x, y) have been determined at //this point due to processing sequence! blendXy = BlendInfo.SetBottomR(preProcBuffer[x], blendResult.f); //set 2nd known corner for (x, y + 1) blendXy1 = BlendInfo.SetTopR(blendXy1, blendResult.j); //store on current buffer position for use on next row preProcBuffer[x] = blendXy1; //set 1st known corner for (x + 1, y + 1) and //buffer for use on next column blendXy1 = BlendInfo.SetTopL(0, blendResult.k); if (x + 1 < srcWidth) { //set 3rd known corner for (x + 1, y) preProcBuffer[x + 1] = BlendInfo.SetBottomL(preProcBuffer[x + 1], blendResult.g); } } //fill block of size scale * scale with the given color // //place *after* preprocessing step, to not overwrite the // //results while processing the the last pixel! _FillBlock(trg, trgi, trgWidth, src[s0 + x], scaleSize.size); //blend four corners of current pixel if (blendXy == 0) { continue; } const int a = 0, b = 1, c = 2, d = 3, e = 4, f = 5, g = 6, h = 7, i = 8; //read sequentially from memory as far as possible ker3._[a] = src[sM1 + xM1]; ker3._[b] = src[sM1 + x]; ker3._[c] = src[sM1 + xP1]; ker3._[d] = src[s0 + xM1]; ker3._[e] = src[s0 + x]; ker3._[f] = src[s0 + xP1]; ker3._[g] = src[sP1 + xM1]; ker3._[h] = src[sP1 + x]; ker3._[i] = src[sP1 + xP1]; _ScalePixel(scaleSize.scaler, RotationDegree.Rot0, ker3, trg, trgi, trgWidth, blendXy, scalePixelColorEq, scalePixelColorDist, outputMatrix); _ScalePixel(scaleSize.scaler, RotationDegree.Rot90, ker3, trg, trgi, trgWidth, blendXy, scalePixelColorEq, scalePixelColorDist, outputMatrix); _ScalePixel(scaleSize.scaler, RotationDegree.Rot180, ker3, trg, trgi, trgWidth, blendXy, scalePixelColorEq, scalePixelColorDist, outputMatrix); _ScalePixel(scaleSize.scaler, RotationDegree.Rot270, ker3, trg, trgi, trgWidth, blendXy, scalePixelColorEq, scalePixelColorDist, outputMatrix); } } }
public void HW4() { string dbgout = ""; DebugLog.Log("HW4 - Motor"); InputMatrix in1 = new InputMatrix(5); SubZone sz1 = new SubZone(5); OutputMatrix out1 = new OutputMatrix(5); in1.setUpSubZone(sz1); sz1.setDownSubZones(in1); sz1.setUpSubZone(out1); out1.setDownSubZones(sz1); out1.addInputs(sz1); DebugLog.Log("Learn"); bool[][] in_p2 = new bool[][] { new bool[] { false, false, true, true, false }, new bool[] { false, false, false, true, true }, }; for (int i = 0; i < in_p2.Length; i++) { in1.setBooleans(in_p2[i]); sz1.setColumnNeurons(1, in1.inputs); } bool[][] in_p3 = new bool[][] { new bool[] { false, false, true, true, false }, new bool[] { false, true, true, false, false }, new bool[] { true, true, false, false, false }, }; for (int i = 0; i < in_p3.Length; i++) { in1.setBooleans(in_p3[i]); sz1.setColumnNeurons(2, in1.inputs); } bool[][] in_p = new bool[][] { new bool[] { false, false, false, true, false }, // _ new bool[] { false, false, true, true, false }, // 2,3 }; for (int n = 0; n < in_p.Length; n++) { DebugLog.Log("Analyse " + n + " pattern"); in1.setBooleans(in_p[n]); dbgout = ""; for (int i = 0; i < in1.inputs.Length; i++) { dbgout += (in1.inputs[i].active > 0.8f ? "A" : "_") + " "; } DebugLog.Log("Pattern : " + dbgout); in1.sendSignals(); sz1.analyze(); dbgout = ""; for (int i = 0; i < out1.inputs.Length; i++) { dbgout += (out1.inputsActives[i] > 0.8f ? "A" : "_") + " "; } DebugLog.Log("Columns : " + dbgout); dbgout = ""; for (int i = 0; i < out1.inputs.Length; i++) { dbgout += (in1.inputs[i].prediction >= 0.5f ? "A" : "_") + " "; } DebugLog.Log("Prediction : " + dbgout); for (int p = 0; p < 5; p++) { DebugLog.Log("Motor " + p + " pattern"); out1.outSignalMotor(p); dbgout = ""; for (int i = 0; i < in1.inputs.Length; i++) { dbgout += (in1.getMotorValues()[i] >= 0.5f ? "A" : "_") + " "; } DebugLog.Log("Motor : " + dbgout); in1.reset(); } out1.reset(); } sz1.onDeactive(); }
public void BlendCorner(sPixel col, OutputMatrix output) { //model a round corner _AlphaBlend(21, 100, output.Reference(1, 1), col); //exact: 1 - pi/4 = 0.2146018366 }
public GamePanelField(OutputMatrix output) : base(output) { }
public void BlendLineSteep(sPixel col, OutputMatrix output) { _AlphaBlend(1, 4, output.Reference(0, _SCALE - 1), col); _AlphaBlend(3, 4, output.Reference(1, _SCALE - 1), col); }
internal abstract void BlendLineShallow(Color16 color, ref OutputMatrix matrix);
public void BlendLineDiagonal(sPixel col, OutputMatrix output) { _AlphaBlend(1, 8, output.Reference(1, 2), col); _AlphaBlend(1, 8, output.Reference(2, 1), col); _AlphaBlend(7, 8, output.Reference(2, 2), col); }
internal abstract void BlendLineDiagonal(Color16 color, ref OutputMatrix matrix);
/* input kernel area naming convention: ------------- | A | B | C | ----|---|---| | D | E | F | //input pixel is at position E ----|---|---| | G | H | I | ------------- */ private static void _ScalePixel( IScaler scaler, RotationDegree rotDeg, Kernel_3X3 ker, sPixel[] trg, int trgi, int trgWidth, byte blendInfo,//result of preprocessing all four corners of pixel "e" IColorEq scalePixelColorEq, IColorDist scalePixelColorDist, OutputMatrix outputMatrix ) { //int a = kernel._[Rot._[(0 << 2) + rotDeg]]; var b = ker._[Rot._[(1 << 2) + (int)rotDeg]]; var c = ker._[Rot._[(2 << 2) + (int)rotDeg]]; var d = ker._[Rot._[(3 << 2) + (int)rotDeg]]; var e = ker._[Rot._[(4 << 2) + (int)rotDeg]]; var f = ker._[Rot._[(5 << 2) + (int)rotDeg]]; var g = ker._[Rot._[(6 << 2) + (int)rotDeg]]; var h = ker._[Rot._[(7 << 2) + (int)rotDeg]]; var i = ker._[Rot._[(8 << 2) + (int)rotDeg]]; var blend = BlendInfo.Rotate(blendInfo, rotDeg); if (BlendInfo.GetBottomR(blend) == BlendType.BlendNone) return; var eq = scalePixelColorEq; var dist = scalePixelColorDist; bool doLineBlend; if (BlendInfo.GetBottomR(blend) >= BlendType.BlendDominant) doLineBlend = true; //make sure there is no second blending in an adjacent //rotation for this pixel: handles insular pixels, mario eyes //but support double-blending for 90? corners else if (BlendInfo.GetTopR(blend) != BlendType.BlendNone && !eq._(e, g)) doLineBlend = false; else if (BlendInfo.GetBottomL(blend) != BlendType.BlendNone && !eq._(e, c)) doLineBlend = false; //no full blending for L-shapes; blend corner only (handles "mario mushroom eyes") else if (eq._(g, h) && eq._(h, i) && eq._(i, f) && eq._(f, c) && !eq._(e, i)) doLineBlend = false; else doLineBlend = true; //choose most similar color var px = dist._(e, f) <= dist._(e, h) ? f : h; var output = outputMatrix; output.Move(rotDeg, trgi); if (!doLineBlend) { scaler.BlendCorner(px, output); return; } //test sample: 70% of values max(fg, hc) / min(fg, hc) //are between 1.1 and 3.7 with median being 1.9 var fg = dist._(f, g); var hc = dist._(h, c); var haveShallowLine = _CONFIGURATION.steepDirectionThreshold * fg <= hc && e != g && d != g; var haveSteepLine = _CONFIGURATION.steepDirectionThreshold * hc <= fg && e != c && b != c; if (haveShallowLine) { if (haveSteepLine) scaler.BlendLineSteepAndShallow(px, output); else scaler.BlendLineShallow(px, output); } else { if (haveSteepLine) scaler.BlendLineSteep(px, output); else scaler.BlendLineDiagonal(px, output); } }
internal abstract void BlendCorner(Color16 color, ref OutputMatrix matrix);
public void BlendLineDiagonal(sPixel col, OutputMatrix output) { _AlphaBlend(1, 8, output.Reference(_SCALE - 1, _SCALE / 2), col); _AlphaBlend(1, 8, output.Reference(_SCALE - 2, _SCALE / 2 + 1), col); _AlphaBlend(1, 8, output.Reference(_SCALE - 3, _SCALE / 2 + 2), col); _AlphaBlend(7, 8, output.Reference(4, 3), col); _AlphaBlend(7, 8, output.Reference(3, 4), col); output.Reference(4, 4).SetPixel(col); }
public void BlendLineDiagonal(sPixel col, OutputMatrix output) { _AlphaBlend(1, 8, output.Reference(1, 2), col); _AlphaBlend(1, 8, output.Reference(2, 1), col); _AlphaBlend(7, 8, output.Reference(2, 2), col); }
public void BlendCorner(sPixel col, OutputMatrix output) { //model a round corner _AlphaBlend(86, 100, output.Reference(4, 4), col); //exact: 0.8631434088 _AlphaBlend(23, 100, output.Reference(4, 3), col); //0.2306749731 _AlphaBlend(23, 100, output.Reference(3, 4), col); //0.2306749731 //alphaBlend(8, 1000, out.ref(4, 2), col); //0.008384061834 -> negligable //alphaBlend(8, 1000, out.ref(2, 4), col); //0.008384061834 }
public MainPanel(OutputMatrix output) : base(output) { }
//scaler policy: see "Scaler2x" reference implementation private void ScaleImageImpl(int[] src, int[] trg, int srcWidth, int srcHeight, int yFirst, int yLast) { yFirst = Math.Max(yFirst, 0); yLast = Math.Min(yLast, srcHeight); if (yFirst >= yLast || srcWidth <= 0) { return; } var trgWidth = srcWidth * _scaler.Scale; //temporary buffer for "on the fly preprocessing" var preProcBuffer = new char[srcWidth]; var ker4 = new Kernel4x4(); //initialize preprocessing buffer for first row: //detect upper left and right corner blending //this cannot be optimized for adjacent processing //stripes; we must not allow for a memory race condition! if (yFirst > 0) { var y = yFirst - 1; var sM1 = srcWidth * Math.Max(y - 1, 0); var s0 = srcWidth * y; //center line var sP1 = srcWidth * Math.Min(y + 1, srcHeight - 1); var sP2 = srcWidth * Math.Min(y + 2, srcHeight - 1); for (var x = 0; x < srcWidth; ++x) { var xM1 = Math.Max(x - 1, 0); var xP1 = Math.Min(x + 1, srcWidth - 1); var xP2 = Math.Min(x + 2, srcWidth - 1); //read sequentially from memory as far as possible ker4.A = src[sM1 + xM1]; ker4.B = src[sM1 + x]; ker4.C = src[sM1 + xP1]; ker4.D = src[sM1 + xP2]; ker4.E = src[s0 + xM1]; ker4.F = src[s0 + x]; ker4.G = src[s0 + xP1]; ker4.H = src[s0 + xP2]; ker4.I = src[sP1 + xM1]; ker4.J = src[sP1 + x]; ker4.K = src[sP1 + xP1]; ker4.L = src[sP1 + xP2]; ker4.M = src[sP2 + xM1]; ker4.N = src[sP2 + x]; ker4.O = src[sP2 + xP1]; ker4.P = src[sP2 + xP2]; PreProcessCorners(ker4); // writes to blendResult /* * preprocessing blend result: * --------- | F | G | //evalute corner between F, G, J, K | ----|---| //input pixel is at position F | J | K | | --------- */ preProcBuffer[x] = preProcBuffer[x].SetTopR(_blendResult.J); if (x + 1 < srcWidth) { preProcBuffer[x + 1] = preProcBuffer[x + 1].SetTopL(_blendResult.K); } } } _outputMatrix = new OutputMatrix(_scaler.Scale, trg, trgWidth); var ker3 = new Kernel3x3(); for (var y = yFirst; y < yLast; ++y) { //consider MT "striped" access var trgi = _scaler.Scale * y * trgWidth; var sM1 = srcWidth * Math.Max(y - 1, 0); var s0 = srcWidth * y; //center line var sP1 = srcWidth * Math.Min(y + 1, srcHeight - 1); var sP2 = srcWidth * Math.Min(y + 2, srcHeight - 1); var blendXy1 = (char)0; for (var x = 0; x < srcWidth; ++x, trgi += _scaler.Scale) { var xM1 = Math.Max(x - 1, 0); var xP1 = Math.Min(x + 1, srcWidth - 1); var xP2 = Math.Min(x + 2, srcWidth - 1); //evaluate the four corners on bottom-right of current pixel //blend_xy for current (x, y) position //read sequentially from memory as far as possible ker4.A = src[sM1 + xM1]; ker4.B = src[sM1 + x]; ker4.C = src[sM1 + xP1]; ker4.D = src[sM1 + xP2]; ker4.E = src[s0 + xM1]; ker4.F = src[s0 + x]; ker4.G = src[s0 + xP1]; ker4.H = src[s0 + xP2]; ker4.I = src[sP1 + xM1]; ker4.J = src[sP1 + x]; ker4.K = src[sP1 + xP1]; ker4.L = src[sP1 + xP2]; ker4.M = src[sP2 + xM1]; ker4.N = src[sP2 + x]; ker4.O = src[sP2 + xP1]; ker4.P = src[sP2 + xP2]; PreProcessCorners(ker4); // writes to blendResult /* * preprocessing blend result: * --------- | F | G | //evaluate corner between F, G, J, K | ----|---| //current input pixel is at position F | J | K | | --------- */ //all four corners of (x, y) have been determined at //this point due to processing sequence! var blendXy = preProcBuffer[x].SetBottomR(_blendResult.F); //set 2nd known corner for (x, y + 1) blendXy1 = blendXy1.SetTopR(_blendResult.J); //store on current buffer position for use on next row preProcBuffer[x] = blendXy1; //set 1st known corner for (x + 1, y + 1) and //buffer for use on next column blendXy1 = ((char)0).SetTopL(_blendResult.K); if (x + 1 < srcWidth) { //set 3rd known corner for (x + 1, y) preProcBuffer[x + 1] = preProcBuffer[x + 1].SetBottomL(_blendResult.G); } //fill block of size scale * scale with the given color // //place *after* preprocessing step, to not overwrite the // //results while processing the the last pixel! FillBlock(trg, trgi, trgWidth, src[s0 + x], _scaler.Scale); //blend four corners of current pixel if (blendXy == 0) { continue; } const int a = 0, b = 1, c = 2, d = 3, e = 4, f = 5, g = 6, h = 7, i = 8; //read sequentially from memory as far as possible ker3._[a] = src[sM1 + xM1]; ker3._[b] = src[sM1 + x]; ker3._[c] = src[sM1 + xP1]; ker3._[d] = src[s0 + xM1]; ker3._[e] = src[s0 + x]; ker3._[f] = src[s0 + xP1]; ker3._[g] = src[sP1 + xM1]; ker3._[h] = src[sP1 + x]; ker3._[i] = src[sP1 + xP1]; ScalePixel(_scaler, (int)RotationDegree.R0, ker3, trgi, blendXy); ScalePixel(_scaler, (int)RotationDegree.R90, ker3, trgi, blendXy); ScalePixel(_scaler, (int)RotationDegree.R180, ker3, trgi, blendXy); ScalePixel(_scaler, (int)RotationDegree.R270, ker3, trgi, blendXy); } } }
public GamePanelTextOut(OutputMatrix output) : base(output) { }