Repository: mxgmn/MarkovJunior
File: source/Graphics.cs (C#)

Code before:
        catch (Exception) { return (null, -1, -1, -1); }
    }

    public static void SaveBitmap(int[] data, int width, int height, string filename)
    {
        Bitmap result = new(width, height);
        var bits = result.LockBits(new Rectangle(0, 0, result.Width, result.Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
        System.Runtime.InteropServices.Marshal.Copy(data, 0, bits.Scan0, data.Length);
        result.UnlockBits(bits);
        result.Save(filename);
    }

    public static (int[], int, int) Render(byte[] state, int MX, int MY, int MZ, int[] colors, int pixelsize, int MARGIN) => MZ == 1 ? BitmapRender(state, MX, MY, colors, pixelsize, MARGIN) : IsometricRender(state, MX, MY, MZ, colors, pixelsize, MARGIN);

    public static (int[], int, int) BitmapRender(byte[] state, int MX, int MY, int[] colors, int pixelsize, int MARGIN)
    {
        int WIDTH = MARGIN + MX * pixelsize, HEIGHT = MY * pixelsize;
        int TOTALWIDTH = WIDTH, TOTALHEIGHT = HEIGHT;
        //int TOTALWIDTH = 189 + MARGIN, TOTALHEIGHT = 189;
        int[] bitmap = new int[TOTALWIDTH * TOTALHEIGHT];
        for (int i = 0; i < bitmap.Length; i++) bitmap[i] = GUI.BACKGROUND;
        //for (int i = 0; i < bitmap.Length; i++) bitmap[i] = 255 << 24;

        int DX = (TOTALWIDTH - WIDTH) / 2;
        int DY = (TOTALHEIGHT - HEIGHT) / 2;

        for (int y = 0; y < MY; y++) for (int x = 0; x < MX; x++)
            {
                int c = colors[state[x + y * MX]];
                for (int dy = 0; dy < pixelsize; dy++) for (int dx = 0; dx < pixelsize; dx++)
                    {
                        int SX = DX + x * pixelsize + dx;
                        int SY = DY + y * pixelsize + dy;
                        if (SX < 0 || SX >= TOTALWIDTH - MARGIN || SY < 0 || SY >= TOTALHEIGHT) continue;
                        bitmap[MARGIN + SX + SY * TOTALWIDTH] = c;
                    }
            }
        return (bitmap, TOTALWIDTH, TOTALHEIGHT);
    }

    static readonly Dictionary<int, Sprite> sprites = new();
    public static (int[], int, int) IsometricRender(byte[] state, int MX, int MY, int MZ, int[] colors, int blocksize, int MARGIN)
    {
        var voxels = new List<Voxel>[MX + MY + MZ - 2];
        var visibleVoxels = new List<Voxel>[MX + MY + MZ - 2];
        for (int i = 0; i < voxels.Length; i++)
        {
            voxels[i] = new List<Voxel>();
            visibleVoxels[i] = new List<Voxel>();
        }
        bool[] visible = new bool[MX * MY * MZ]; //нужен для быстрой работы с transparent

Review comment (suggestion):
You can use a `using` and skip the whole allocation + copy by wrapping the source directly:
```suggestion
        fixed (int* pData = data)
        {
            using var image = Image.WrapMemory<Bgra32>(pData, width, height);

            image.SaveAsPng(filename);
        }
```
A couple notes:
- Need to add `<AllowUnsafeBlocks>true</AllowUnsafeBlocks>` to the .csproj for this
- Make sure to **add width/height validation** as well before this suggested code.

Code after:
                }
            }

            image.Dispose();
            return (result, width, height, 1);
        }
        catch (Exception)
        {
            return (null, -1, -1, -1);
        }
    }

    public static void SaveBitmap(int[] data, int width, int height, string filename)
    {
        var formattedData = new Bgra32[data.Length];
        for (var i = 0; i < data.Length; i += 1)
        {
            formattedData[i] = new Bgra32
            {
                Bgra = unchecked((uint) data[i])
            };
        }

        var image = Image.WrapMemory(Configuration.Default, new Memory<Bgra32>(formattedData), width, height);
        image.SaveAsPng(filename);
        image.Dispose();
    }

    public static (int[], int, int) Render(byte[] state, int MX, int MY, int MZ, int[] colors, int pixelsize, int MARGIN) => MZ == 1 ? BitmapRender(state, MX, MY, colors, pixelsize, MARGIN) : IsometricRender(state, MX, MY, MZ, colors, pixelsize, MARGIN);

    public static (int[], int, int) BitmapRender(byte[] state, int MX, int MY, int[] colors, int pixelsize, int MARGIN)
    {
        int WIDTH = MARGIN + MX * pixelsize, HEIGHT = MY * pixelsize;
        int TOTALWIDTH = WIDTH, TOTALHEIGHT = HEIGHT;
        //int TOTALWIDTH = 189 + MARGIN, TOTALHEIGHT = 189;
        int[] bitmap = new int[TOTALWIDTH * TOTALHEIGHT];
        for (int i = 0; i < bitmap.Length; i++) bitmap[i] = GUI.BACKGROUND;
        //for (int i = 0; i < bitmap.Length; i++) bitmap[i] = 255 << 24;

        int DX = (TOTALWIDTH - WIDTH) / 2;
        int DY = (TOTALHEIGHT - HEIGHT) / 2;

        for (int y = 0; y < MY; y++) for (int x = 0; x < MX; x++)
            {
                int c = colors[state[x + y * MX]];
                for (int dy = 0; dy < pixelsize; dy++) for (int dx = 0; dx < pixelsize; dx++)
                    {
                        int SX = DX + x * pixelsize + dx;
                        int SY = DY + y * pixelsize + dy;
                        if (SX < 0 || SX >= TOTALWIDTH - MARGIN || SY < 0 || SY >= TOTALHEIGHT) continue;
                        bitmap[MARGIN + SX + SY * TOTALWIDTH] = c;