public PhysicalPixelDimensionsDataChunkRepresentation(PNG parent) : base(parent)
 {
 }
 public BackgroundColorDataChunkRepresentation(PNG parent) : base(parent)
 {
 }
 public TransparentColorDataChunkRepresentation(PNG parent) : base(parent)
 {
 }
 public SuggestedPaletteDataChunkRepresentation(PNG parent) : base(parent)
 {
 }
 public VirtualPageDataChunkRepresentation(PNG parent) : base(parent)
 {
 }
 public HeaderChunkRepresentation(PNG parent) : base(parent)
 {
 }
 public TimestampDataChunkRepresentation(PNG parent) : base(parent)
 {
 }
 public ZippedTextDataChunkRepresentation(PNG parent) : base(parent)
 {
 }
 public InternationalTextDataChunkRepresentation(PNG parent) : base(parent)
 {
 }
 public SignificantBitsDataChunkRepresentation(PNG parent) : base(parent)
 {
 }
 public EmbeddedICCProfileDataChunkRepresentation(PNG parent) : base(parent)
 {
 }
                //The sRGB chunk contains:
                //Rendering intent
                //1 byte
                //The following values are defined for rendering intent:
                //0 Perceptual: for images preferring good adaptation to the output device gamut at the expense of colorimetric accuracy, such as photographs.
                //1 Relative colorimetric: for images requiring colour appearance matching(relative to the output device white point), such as logos.
                //2 Saturation: for images preferring preservation of saturation at the expense of hue and lightness, such as charts and graphs.
                //3 Absolute colorimetric: for images requiring preservation of absolute colorimetry, such as previews of images destined for a different output device(proofs).
                //It is recommended that a PNG encoder that writes the sRGB chunk also write a gAMA chunk(and optionally a cHRM chunk) for compatibility with decoders that do not use the sRGB chunk.Only the following values shall be used.
                //gAMA
                //Gamma 45455
                //cHRM
                //White point x 31270
                //White point y 32900
                //Red x 64000
                //Red y 33000
                //Green x 30000
                //Green y 60000
                //Blue x 15000
                //Blue y 6000
                //When the sRGB chunk is present, it is recommended that decoders that recognize it and are capable of colour management[ICC] ignore the gAMA and cHRM chunks and use the sRGB chunk instead.Decoders that recognize the sRGB chunk but are not capable of colour management [ICC] are recommended to ignore the gAMA and cHRM chunks, and use the values given above as if they had appeared in gAMA and cHRM chunks.

                public StandardRGBDataChunkRepresentation(PNG parent) : base(parent)
                {
                }
 public PrimaryChromaticitiesAndWhitePoint(PNG parent) : base(parent)
 {
 }
 public GammaDataChunkRepresentation(PNG parent) : base(parent)
 {
 }
 public ImageDataChunkRepresentation(PNG parent) : base(parent)
 {
 }
 public HistogramDataChunkRepresentation(PNG parent) : base(parent)
 {
 }
            public DataChunk(BinaryReader reader, PNG parent)
            {
                byte[] lengthBytes = reader.ReadBytes(4);
                Length = (uint)lengthBytes.GetULongBE(0);

                byte[] typeBytes = reader.ReadBytes(4);
                ChunkTypeBytes = typeBytes;
                ChunkType      = Encoding.Default.GetString(typeBytes);

                Data = reader.ReadBytes((int)Length);

                byte[] crcBytes = reader.ReadBytes(4);
                CRC = (uint)crcBytes.GetULongBE(0);

                byte[] checkBytes = new byte[Data.Length + typeBytes.Length];
                Array.Copy(typeBytes, 0, checkBytes, 0, typeBytes.Length);
                int dst = typeBytes.Length;

                Array.Copy(Data, 0, checkBytes, dst, Data.Length);

                CRC   crc        = new CRC();
                ulong crc_result = crc.crc(checkBytes, checkBytes.Length);

                if (CRC == crc_result)
                {
                    CRCPassed = true;
                }
                else
                {
                    CRCPassed = false;
                }

                switch (ChunkType.ToLower())
                {
                case "bkgd": DataChunkRepresentation = new BackgroundColorDataChunkRepresentation(parent); break;

                case "chrm": DataChunkRepresentation = new PrimaryChromaticitiesAndWhitePoint(parent); break;

                case "gama": DataChunkRepresentation = new GammaDataChunkRepresentation(parent); break;

                case "hist": DataChunkRepresentation = new HistogramDataChunkRepresentation(parent); break;

                case "iccp": DataChunkRepresentation = new EmbeddedICCProfileDataChunkRepresentation(parent); break;

                case "idat": DataChunkRepresentation = new ImageDataChunkRepresentation(parent); break;

                case "ihdr": DataChunkRepresentation = new HeaderChunkRepresentation(parent); break;

                case "itxt": DataChunkRepresentation = new InternationalTextDataChunkRepresentation(parent); break;

                case "phys": DataChunkRepresentation = new PhysicalPixelDimensionsDataChunkRepresentation(parent); break;

                case "plte": DataChunkRepresentation = new PaletteDataChunkRepresentation(parent); break;

                case "sbit": DataChunkRepresentation = new SignificantBitsDataChunkRepresentation(parent); break;

                case "splt": DataChunkRepresentation = new SuggestedPaletteDataChunkRepresentation(parent); break;

                case "srgb": DataChunkRepresentation = new StandardRGBDataChunkRepresentation(parent); break;

                case "text": DataChunkRepresentation = new TextDataChunkRepresentation(parent); break;

                case "time": DataChunkRepresentation = new TimestampDataChunkRepresentation(parent); break;

                case "vpag": DataChunkRepresentation = new VirtualPageDataChunkRepresentation(parent); break;

                case "ztxt": DataChunkRepresentation = new ZippedTextDataChunkRepresentation(parent); break;

                default: break;
                }

                if (DataChunkRepresentation != null)
                {
                    StringBuilder sb     = new StringBuilder();
                    var           values = DataChunkRepresentation.ToProperties(Data);
                    foreach (var val in values)
                    {
                        sb.AppendLine(val.Key + " = " + val.Value.ToString());
                    }
                    PropertyString = sb.ToString();
                }

                if (!CRCPassed)
                {
                    throw new InvalidDataException($@"CRC Failure reading data chunk of type {ChunkType} - Expected CRC {CRC}, Actual Checksum Result {crc_result}");
                }
            }
 public DataChunkRepresentationBase(PNG parent)
 {
     this.Parent = parent;
 }