public static List <PhotonFileLayer> ReadLayers(PhotonFileHeader photonFileHeader, byte[] fileContent, int margin, Action <string> reportProgress)
        {
            var photonLayer = new PhotonLayer(photonFileHeader.GetResolutionX(), photonFileHeader.GetResolutionY());

            var layers = new List <PhotonFileLayer>();

            int antiAliasLevel = 1;

            if (photonFileHeader.GetVersion() > 1)
            {
                antiAliasLevel = photonFileHeader.GetAntiAliasingLevel();
            }

            int layerCount = photonFileHeader.GetNumberOfLayers();

            var start = photonFileHeader.GetLayersDefinitionOffsetAddress();
            var ds    = new BinaryReader(new MemoryStream(fileContent, start, fileContent.Length - start));

            {
                var layerMap = new Dictionary <int, PhotonFileLayer>();
                for (int i = 0; i < layerCount; i++)
                {
                    reportProgress?.Invoke("Reading photon file layer " + (i + 1) + "/" + photonFileHeader.GetNumberOfLayers());

                    var layer = new PhotonFileLayer(ds)
                    {
                        photonFileHeader = photonFileHeader
                    };
                    layer.imageData = ArraysEmulation.CopyOfRange(fileContent, layer.dataAddress, layer.dataAddress + layer.dataSize);
                    layers.Add(layer);
                    layerMap[i] = layer;
                }

                if (antiAliasLevel > 1)
                {
                    for (int a = 0; a < (antiAliasLevel - 1); a++)
                    {
                        for (int i = 0; i < layerCount; i++)
                        {
                            reportProgress?.Invoke("Reading photon file AA " + (2 + a) + "/" + antiAliasLevel + " layer " + (i + 1) + "/" + photonFileHeader.GetNumberOfLayers());

                            var layer = new PhotonFileLayer(ds)
                            {
                                photonFileHeader = photonFileHeader
                            };
                            layer.imageData = ArraysEmulation.CopyOfRange(fileContent, layer.dataAddress, layer.dataAddress + layer.dataSize);

                            layerMap[i].AddAntiAliasLayer(layer);
                        }
                    }
                }
            }

            photonLayer.UnLink();

            return(layers);
        }
        public static void CalculateLayers(PhotonFileHeader photonFileHeader, List <PhotonFileLayer> layers, int margin, Action <string> reportProgress)
        {
            var             photonLayer           = new PhotonLayer(photonFileHeader.GetResolutionX(), photonFileHeader.GetResolutionY());
            List <BitArray> previousUnpackedImage = null;

            for (int i = 0; i < layers.Count; i++)
            {
                var layer = layers[i];

                List <BitArray> unpackedImage = layer.UnpackImage(photonFileHeader.GetResolutionX(), photonFileHeader.GetResolutionY());

                reportProgress?.Invoke("Calculating photon file layer " + i + "/" + photonFileHeader.GetNumberOfLayers());

                if (margin > 0)
                {
                    layer.extendsMargin = layer.CheckMargin(unpackedImage, margin);
                }

                layer.UnknownPixels(unpackedImage, photonLayer);

                layer.Calculate(unpackedImage, previousUnpackedImage, photonLayer);

                if (previousUnpackedImage != null)
                {
                    previousUnpackedImage.Clear();
                }
                previousUnpackedImage = unpackedImage;

                layer.packedLayerImage = photonLayer.PackLayerImage();
                layer.isCalculated     = true;

                if (photonFileHeader.GetVersion() > 1)
                {
                    foreach (var aaFileLayer in layer.antiAliasLayers)
                    {
                        List <BitArray> aaUnpackedImage = aaFileLayer.UnpackImage(photonFileHeader.GetResolutionX(), photonFileHeader.GetResolutionY());
                        var             aaPhotonLayer   = new PhotonLayer(photonFileHeader.GetResolutionX(), photonFileHeader.GetResolutionY());
                        aaFileLayer.UnknownPixels(aaUnpackedImage, aaPhotonLayer);
                        aaFileLayer.packedLayerImage = aaPhotonLayer.PackLayerImage();
                        aaFileLayer.isCalculated     = false;
                    }
                }
            }
            photonLayer.UnLink();
        }
        public static void CalculateAALayers(PhotonFileHeader photonFileHeader, List <PhotonFileLayer> layers, PhotonAaMatrix photonAaMatrix, Action <string> reportProgress)
        {
            var photonLayer = new PhotonLayer(photonFileHeader.GetResolutionX(), photonFileHeader.GetResolutionY());

            int[,] source = new int[photonFileHeader.GetResolutionY(), photonFileHeader.GetResolutionX()];

            int i = 0;

            foreach (var layer in layers)
            {
                List <BitArray> unpackedImage = layer.UnpackImage(photonFileHeader.GetResolutionX(), photonFileHeader.GetResolutionY());

                reportProgress?.Invoke("Calculating AA for photon file layer " + i + "/" + photonFileHeader.GetNumberOfLayers());

                for (int y = 0; y < photonFileHeader.GetResolutionY(); y++)
                {
                    for (int x = 0; x < photonFileHeader.GetResolutionX(); x++)
                    {
                        source[y, x] = 0;
                    }
                }

                for (int y = 0; y < unpackedImage.Count; y++)
                {
                    BitArray currentRow = unpackedImage[y];
                    if (currentRow != null)
                    {
                        for (int x = 0; x < currentRow.Length; x++)
                        {
                            if (currentRow[x])
                            {
                                source[y, x] = 255;
                            }
                        }
                    }
                }

                // Calc
                int[,] target = photonAaMatrix.Calc(source);

                int aaTresholdDiff = 255 / photonFileHeader.GetAntiAliasingLevel();
                int aaTreshold     = 0;
                foreach (var aaFileLayer in layer.antiAliasLayers)
                {
                    photonLayer.Clear();
                    aaTreshold += aaTresholdDiff;

                    for (int y = 0; y < photonFileHeader.GetResolutionY(); y++)
                    {
                        for (int x = 0; x < photonFileHeader.GetResolutionX(); x++)
                        {
                            if (target[y, x] >= aaTreshold)
                            {
                                photonLayer.Supported(x, y);
                            }
                        }
                    }

                    aaFileLayer.SaveLayer(photonLayer);
                }

                i++;
            }
            photonLayer.UnLink();
        }