EGG

From MultimediaWiki
Jump to navigation Jump to search

The format employs YUV frames coded per-plane and IMA ADPCM-encoded audio. Data is aligned to CD sector size (2048 bytes)

Egg does not have audio stream and has slightly different coding but the differences are minimal.

EGG header:

 4 bytes - "EGG\0"
 4 bytes - always 0x350?
 4 bytes - number of frames
 2036 bytes - padding

EGG frame header:

 4x2x3 bytes - offsets to each plane pixel and mode data

EGG frames are always 20kB long.

YQS header:

 2 bytes - number of frames
 4 bytes - audio sample rate
 2042 bytes - padding

YQS frame header:

 4 bytes - size
 4x2x3 bytes - offsets to each plane pixel and mode data
 4 bytes - audio data offset
 4 bytes - audio data size

Video coding employs quadtree coding and vector quantisation: before actual image data there's an array of possible 2x2 block values which may be used during luma decoding.

Luma plane is coded as 8x8 blocks with mode flags telling how to decode them (fill/skip/split). Chroma plane is coded in similar manner using 4x4 blocks.

Luma coding:

 if (get_bit() == 0) {
   raw block - read 64 pixels from pixel data to fill it
 } else {
   //split block
   for (blk_no = 0; blk_no < 4; blk_no++) {
     if (get_bit() == 1)
       decode_luma_4x4_block();
     // otherwise leave it unchanged
   }
 }

4x4 luma blocks are coded in the same manner, 2x2 blocks depend on the format.

EGG uses bit pattern (highest bit is the one read first) to determine coding mode:

  • 00 - skip
  • 01 - fill
  • 10 - raw
  • 11xx - VQ with possible transformation (00 - as is, 01 - flip horizontally, 10 - flip vertically, 11 - flip in both directions)

YQS simply uses 2-bit mode for that:

  • 0 - fill
  • 1 - raw
  • 2 - VQ (followed by index in the header table of 2x2 blocks)
  • 3 - VQ flipped vertically

Chroma coding:

 if (get_bit() == 1) { // otherwise skip
   if (get_bit() == 0) {
     fill 4x4 block with single colour
   } else {
     for (blk_no = 0; blk_no < 4; blk_no++) {
       if (get_bit() == 1) {
         // decode 2x2 chroma block
         if (get_bit() == 0)
           fill 2x2 block
         else
           raw 2x2 block
       }
       // otherwise leave it unchanged
     }
   }
 }