Search code examples
c#commentsgifspecifications

Gif File Specification - Comment property of frames


I'm looking forward for a way to store text in each frame of a gif file. Not printing the text in the image, but adding as a property. There is na old program made by Microsoft that is able to set text for each frame.

Comments

As you can see, there is a field "Comment" for each frame.

Now, my question is:

Is this field something that the GIF specification aproves? There is almost no documents out there, saying so. (Actually, there is)

if yes:

Where is located? In one of these methods?

     protected void WriteGraphicCtrlExt()
     {
    fs.WriteByte(0x21); // extension introducer
    fs.WriteByte(0xf9); // GCE label
        fs.WriteByte(4); // data block size

        int transp, disp;

    if (transparent == Color.Empty) 
    {
    transp = 0;
    disp = 0; // dispose = no action
    } 
    else 
    {
    transp = 1;
    disp = 2; // force clear if using transparent color
        }

        //If first frame, no transparency and no dispose.
        if (firstFrame)
        {
            disp = 0;
            transp = 0;
        }
        else
        {
            if (dispose >= 0)
            {
                disp = dispose & 7; // user override
            }
            disp <<= 2;
        }

        // packed fields
        fs.WriteByte( Convert.ToByte( 0 | // 1:3 reserved
            disp | // 4:6 disposal
            0 | // 7   user input - 0 = none
            transp )); // 8   transparency flag

        WriteShort(delay); // delay x 1/100 sec
        fs.WriteByte( Convert.ToByte( transIndex)); // transparent color index
        fs.WriteByte(0); // block terminator
    }


    protected void WriteImageDesc()
    {

        fs.WriteByte(0x2c); // image separator
        WriteShort(0); // image position x,y = 0,0
        WriteShort(0);
        WriteShort(width); // image size
        WriteShort(height);
        // packed fields
        if (firstFrame) 
        {
            // no LCT  - GCT is used for first (or only) frame
            fs.WriteByte(0);
        } 
        else 
        {
            // specify normal LCT
            fs.WriteByte( Convert.ToByte( 0x80 | // 1 local color table  1=yes
                0 | // 2 interlace - 0=no
                0 | // 3 sorted - 0=no
                0 | // 4-5 reserved
                palSize ) ); // 6-8 size of color table
        }
    }

EDIT:

I've found a way to do it, like the Hans Passand wrote:

protected void WriteComment(string comment)
{
        fs.WriteByte(0x21);
        fs.WriteByte(0xfe);

        byte[] lenght = StringToByteArray(comment.Length.ToString("X"));

        foreach (byte b in lenght)
        {
            fs.WriteByte(b);
        }

        WriteString(comment);
}

Solution

  • Well there's the GifLib project that may help you with this. Specifically, these files:

    http://giflib.codeplex.com/SourceControl/latest#GifEncoder.cs, line #87 Encode(), which specifies, in code, in what order to write things to the output gif stream

    and for the comments extensions, a few pointers:

    http://giflib.codeplex.com/SourceControl/latest#CommentEx.cs, line #57 GetBuffer():

            internal byte[] GetBuffer()
            {            
                List<byte> list = new List<byte>();
                list.Add(GifExtensions.ExtensionIntroducer); // 0x21
                list.Add(GifExtensions.CommentLabel); // 0xFE
                foreach (string coment in CommentDatas)
                {
                    char[] commentCharArray = coment.ToCharArray();
                    list.Add((byte)commentCharArray.Length);
                    foreach (char c in commentCharArray)
                    {
                        list.Add((byte)c);
                    }
                }
                list.Add(GifExtensions.Terminator); // 0
                return list.ToArray();
            }