Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Chunks encoder decoder #14

Open
hannespreishuber opened this issue Aug 5, 2023 · 2 comments
Open

Chunks encoder decoder #14

hannespreishuber opened this issue Aug 5, 2023 · 2 comments

Comments

@hannespreishuber
Copy link

have any solution on read write chunk (eg itxt) like https://www.nayuki.io/page/png-file-chunk-inspector
would even pay for it

@EliotJones
Copy link
Owner

Depending on your needs you can hook into the parsing of individual chunks using the IChunkVisitor (here), you can implement the interface with any logic you need and pass it to Png.Open https://github.com/EliotJones/BigGustave/blob/master/src/BigGustave/Png.cs#L59

@stanac
Copy link

stanac commented Oct 10, 2023

For those who are trying to set and read data:

To set data:

class Program
{
    private const string Key = "testKey";
    private const string Value = "testValue123";

    private const string SourceFile = @"c:\temp\PNG_transparency_demonstration_1.png";
    private const string DestinationFile = @"c:\temp\PNG_transparency_demonstration_2.png";

    static void Main(string[] args)
    {
        byte[] pngBytes = File.ReadAllBytes(SourceFile);

        Png png = Png.Open(pngBytes);
        PngBuilder builder = PngBuilder.FromPng(png);

        builder.StoreText(Key, Value);
        byte[] newPng = builder.Save(new PngBuilder.SaveOptions {AttemptCompression = false, MaxDegreeOfParallelism = 1});

        if (File.Exists(DestinationFile))
        {
            File.Delete(DestinationFile);
        }

        File.WriteAllBytes(DestinationFile, newPng);
    }
}

To read data:

Png.Open(DestinationFile, new TextVisitor());

And TextVisitor:

public class TextVisitor : IChunkVisitor
{
    public void Visit(Stream stream, ImageHeader header, ChunkHeader chunkHeader, byte[] data, byte[] crc)
    {
        if (chunkHeader.Name == "iTXt")
        {
            string key = GetTextKey(data, out int keyLength);

            if (key == "testKey")
            {
                string value = GetTextValue(data, keyLength);

                Console.WriteLine(value);
            }
        }
    }

    private static string GetTextKey(byte[] data, out int keyLength)
    {
        const int MaxKeyLength = 79;
        keyLength = 0;
        
        for (int i = 0; i < MaxKeyLength - 3; i++)
        {
            if (data[i] == 0 && data[i + 1] == 0 && data[i + 2] == 0 && data[i + 3] == 0)
            {
                keyLength = i;
                break;
            }
        }

        return Encoding.UTF8.GetString(data, 0, keyLength);
    }

    private static string GetTextValue(byte[] data, int keyLength)
    {
        int count = data.Length - keyLength - 5;
        return Encoding.UTF8.GetString(data, keyLength + 5, count);
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants