semmixcolor and perception

Comments ($FE)

The comment block holds text that does not appear in the image: the author, the program, copyright or anything else. It is the simplest extension: no fixed block, just text sub-blocks.

Structure

21 FE extension, comment label n ...n bytes of text sub-block (1..255 bytes) ... more sub-blocks for longer text 00 terminator

Example from the file

21 FE 09 73 65 6D 6D 69 78 2E 70 6C 00 s e m m i x . p l 09 = 9 bytes of text: "semmix.pl"

A comment longer than 255 bytes is split into several sub-blocks. The boundaries do not matter to the content: the decoder joins them into one text.

Character encoding

The specification assumes 7-bit ASCII. Accented letters in a comment therefore have no defined encoding. Modern software usually writes UTF-8 and usually reads it back correctly, but there is no guarantee. It is safer to stick to ASCII, or to store metadata as XMP through an application extension.

Where it can go

A comment can appear anywhere between blocks, including between animation frames. The only rule: it must not come between a graphic control block and the image that block applies to (see block order). In the example file the comment sits before the $F9 block, which is correct.

What comments can reveal

Graphics programs may write their name and version into a comment, and some also a user name or a file path. Before publishing a graphic, check what its comments contain and remove them if needed. GIF optimizers usually do this by default, since comments do not affect how the image looks.

// read a comment; pos points at byte 21 of a 21 FE block
function readComment(b, pos) {
  pos += 2;
  let text = '';
  for (let n = b[pos++]; n !== 0; n = b[pos++]) {
    text += new TextDecoder().decode(b.subarray(pos, pos + n));
    pos += n;
  }
  return { text, next: pos };
}