Example #1
0
    void Visualize() {
      int bWidth, bHeight, iWidth, iHeight, spls, splCount, stride;
      long bLength, iLength, byteLen = 0, i, j, spl;
      float currSpl;
      double palOffs, palScale, min, max, offs, scale;
      VisPaletteType palType;
      bool isDone, doRepop, isPalRel;
      FloatColor liveClr, currClr;

      double[] result;
      bool[] isAlive;
      FloatColor[] palette;
      byte[] bytes = new byte[0];

      BitmapSource src;

      while (true) {
        startEvent.WaitOne();

        lock (queueLock) {
          bWidth = this.bWidth;
          bHeight = this.bHeight;
          iWidth = this.iWidth;
          iHeight = this.iHeight;
          spls = this.spls;
          splCount = spls * spls;
          bLength = this.bLength;
          iLength = iWidth * iHeight;
          stride = iWidth * bpp;
          result = this.result;
          isAlive = this.isAlive;
          isDone = this.isDone;
          palette = this.palette;
          liveClr = this.liveClr;
          palType = this.paletteType;
          palOffs = this.offs;
          palScale = this.scale;

          doRepop = this.byteLen != byteLen;
          byteLen = this.byteLen;
        }

        if (bWidth == 0 || bHeight == 0) continue;

        if (doRepop)
          bytes = new byte[byteLen];


        offs = isDone ? palOffs : 0;
        isPalRel = palType == VisPaletteType.Relative || !isDone;

        if (isPalRel) {
          min = double.MaxValue;
          max = double.MinValue;

          for (i = 1; i < bLength; i++) {
            if (!isAlive[i]) {
              min = Math.Min(min, result[i]);
              max = Math.Max(max, result[i]);
            }
          }

          Console.WriteLine($"[Visualizer] Current minimum: {min}; current maximum: {max}.");

          offs -= min;
          scale = (isDone ? palScale * (palette.Length - 1) : 1) / (max - min);
        }
        else scale = (palType == VisPaletteType.CyclicSingle ? 1 : palette.Length) / palScale;

        if (isDone) {
          for (int row = 0; row < iHeight; row++) {
            for (int col = 0; col < iWidth; col++) {
              i = (col + row * bWidth) * spls;
              j = (col + row * iWidth) * bpp;

              currClr = new FloatColor(0, 0, 0, 0);

              for (int sRow = 0; sRow < spls; sRow++) {
                for (int sCol = 0; sCol < spls; sCol++) {
                  spl = i + sCol + sRow * bWidth;

                  currClr += isAlive[spl] ? liveClr : isPalRel ? GetColor(palette, liveClr, (result[spl] + offs) * scale) : GetColor(palette, liveClr, Math.Log(result[spl] + 1) * scale);
                }
              }

              currClr /= splCount;

              bytes[j] = (byte)(currClr.B * 255);
              bytes[j + 1] = (byte)(currClr.G * 255);
              bytes[j + 2] = (byte)(currClr.R * 255);
              bytes[j + 3] = (byte)(currClr.A * 255);
            }
          }
        }
        else {
          for (int row = 0; row < iHeight; row++) {
            for (int col = 0; col < iWidth; col++) {
              i = (col + row * bWidth) * spls;
              j = (col + row * iWidth) * bpp;

              currSpl = 0;

              for (int sRow = 0; sRow < spls; sRow++) {
                for (int sCol = 0; sCol < spls; sCol++) {
                  spl = i + sCol + sRow * bWidth;

                  currSpl += isAlive[spl] ? 0 : (float)((result[spl] + offs) * scale);
                }
              }

              currSpl /= splCount;

              bytes[j] =
                bytes[j + 1] =
                bytes[j + 2] = (byte)(Math.Max(0, Math.Min(1, currSpl)) * 255);
              bytes[j + 3] = (byte)255;
            }
          }
        }

        src = BitmapSource.Create(iWidth, iHeight, dpiX, dpiY, PixelFormats.Bgra32, null, bytes, stride);

        Source = src.GetAsFrozen() as BitmapSource;

        visualized?.Invoke(this);
      }
    }