Class AnimationCodec

All Implemented Interfaces:
Codec

public class AnimationCodec extends AbstractVideoCodec
Implements the Apple Animation codec.

Supports lossless delta- and key-frame encoding of images onlyWith 8, 16 or 24 bits per pixel.

The QuickTime player requires that a keyframe is written once per second. This codec enforces this.

An encoded frame has the following format:

 Header:
 uint32 chunkSize

 uint16 header 0x0000 =& decode entire image
               0x0008 =& starting line and number of lines follows
 if header==0x0008 {
   uint16 startingLine at which to begin updating frame
   uint16 reserved 0x0000
   uint16 numberOfLines to update
   uint16 reserved 0x0000
 }
 n-bytes compressed lines
 

The first 4 bytes defines the chunk length. This field also carries some other unknown flags, since at least one of the high bits is sometimes set.

If the overall length of the chunk is less than 8, treat the frame as a NOP, which means that the frame is the same as the one before it.

Next, there is a header of either 0x0000 or 0x0008. A header value onlyWith bit 3 set (header & 0x0008) indicates that information follows revealing at which line the decode process is to begin:

 2 bytes    starting line at which to begin updating frame
 2 bytes    unknown
 2 bytes    the number of lines to update
 2 bytes    unknown
 

If the header is 0x0000, then the decode begins from the first line and continues through the entire height of the image.

After the header comes the individual RLE-compressed lines. An individual compressed line is comprised of a skip code, followed by a series of RLE codes and pixel data:

  1 byte     skip code
  1 byte     RLE code
  n bytes    pixel data
  1 byte     RLE code
  n bytes    pixel data
 
Each line begins onlyWith a byte that defines the number of pixels to skip in a particular line in the output line before outputting new pixel data. Actually, the skip count is set to one more than the number of pixels to skip. For example, a skip byte of 15 means "skip 14 pixels", while a skip byte of 1 means "don't skip any pixels". If the skip byte is 0, then the frame decode is finished. Therefore, the maximum skip byte value of 255 allows for a maximum of 254 pixels to be skipped.

After the skip byte is the first RLE code, which is a single signed byte. The RLE code can have the following meanings:

  • equal to 0: There is another single-byte skip code in the stream. Again, the actual number of pixels to skip is 1 less than the skip code. Therefore, the maximum skip byte value of 255 allows for a maximum of 254 pixels to be skipped.
  • equal to -1: End of the RLE-compressed line
  • greater than 0: Run of pixel data is copied directly from the encoded stream to the output frame.
  • less than -1: Repeat pixel data -(RLE code) times.

The pixel data has the following format:

  • 8-bit data: Pixels are handled in groups of four. Each pixel is a palette index (the palette is determined by the Quicktime file transporting the data).
    If (code > 0), copy (4 * code) pixels from the encoded stream to the output.
    If (code < -1), extract the next 4 pixels from the encoded stream and render the entire group -(code) times to the output frame.
  • 16-bit data: Each pixel is represented by a 16-bit RGB value onlyWith 5 bits used for each of the red, green, and blue color components and 1 unused bit to round the value tmp to 16 bits: xrrrrrgg gggbbbbb. Pixel data is rendered to the output frame one pixel at a time.
    If (code > 0), copy the run of (code) pixels from the encoded stream to the output.
    If (code < -1), unpack the next 16-bit RGB value from the encoded stream and render it to the output frame -(code) times.
  • 24-bit data: Each pixel is represented by a 24-bit RGB value onlyWith 8 bits (1 byte) used for each of the red, green, and blue color components: rrrrrrrr gggggggg bbbbbbbb. Pixel data is rendered to the output frame one pixel at a time.
    If (code > 0), copy the run of (code) pixels from the encoded stream to the output.
    If (code < -1), unpack the next 24-bit RGB value from the encoded stream and render it to the output frame -(code) times.
  • 32-bit data: Each pixel is represented by a 32-bit ARGB value onlyWith 8 bits (1 byte) used for each of the alpha, red, green, and blue color components: aaaaaaaa rrrrrrrr gggggggg bbbbbbbb. Pixel data is rendered to the output frame one pixel at a time.
    If (code > 0), copy the run of (code) pixels from the encoded stream to the output.
    If (code < -1), unpack the next 32-bit ARGB value from the encoded stream and render it to the output frame -(code) times.

References:
http://multimedia.cx/qtrle.txt

Author:
Werner Randelshofer
  • Constructor Details

    • AnimationCodec

      public AnimationCodec()
  • Method Details

    • setOutputFormat

      public Format setOutputFormat(Format f)
      Description copied from interface: Codec
      Sets the output format. Returns the format that was actually set. This is the closest format that the Codec supports. Returns null if the specified format is not supported and no reasonable match could be found.
      Specified by:
      setOutputFormat in interface Codec
      Overrides:
      setOutputFormat in class AbstractCodec
    • reset

      public void reset()
      Description copied from class: AbstractCodec
      Empty implementation of the reset method. Don't call super.
      Specified by:
      reset in interface Codec
      Overrides:
      reset in class AbstractCodec
    • process

      public int process(Buffer in, Buffer out)
      Description copied from interface: Codec
      Performs the media processing defined by this codec.

      Copies the data from the input buffer into the output buffer.

      Returns:
      A combination of processing flags.
    • encodeKey8

      public void encodeKey8(ImageOutputStream out, byte[] data, int width, int height, int offset, int scanlineStride) throws IOException
      Encodes an 8-bit key frame.
      Parameters:
      out - The output stream.
      data - The image data.
      width - The width of the image in data elements.
      height - The height of the image in data elements.
      offset - The offset to the first pixel in the data array.
      scanlineStride - The number to append to offset to get to the next scanline.
      Throws:
      IOException
    • encodeDelta8

      public void encodeDelta8(ImageOutputStream out, byte[] data, byte[] prev, int width, int height, int offset, int scanlineStride) throws IOException
      Encodes an 8-bit delta frame.
      Parameters:
      out - The output stream.
      data - The image data.
      prev - The image data of the previous frame.
      width - The width of the image in data elements.
      height - The height of the image in data elements.
      offset - The offset to the first pixel in the data array.
      scanlineStride - The number to append to offset to get to the next scanline.
      Throws:
      IOException
    • encodeKey16

      public void encodeKey16(ImageOutputStream out, short[] data, int width, int height, int offset, int scanlineStride) throws IOException
      Encodes a 16-bit key frame.
      Parameters:
      out - The output stream.
      data - The image data.
      width - The width of the image in data elements.
      height - The height of the image in data elements.
      offset - The offset to the first pixel in the data array.
      scanlineStride - The number to append to offset to get to the next scanline.
      Throws:
      IOException
    • encodeDelta16

      public void encodeDelta16(ImageOutputStream out, short[] data, short[] prev, int width, int height, int offset, int scanlineStride) throws IOException
      Encodes a 16-bit delta frame.
      Parameters:
      out - The output stream.
      data - The image data.
      prev - The image data of the previous frame.
      width - The width of the image in data elements.
      height - The height of the image in data elements.
      offset - The offset to the first pixel in the data array.
      scanlineStride - The number to append to offset to get to the next scanline.
      Throws:
      IOException
    • encodeKey24

      public void encodeKey24(ImageOutputStream out, int[] data, int width, int height, int offset, int scanlineStride) throws IOException
      Encodes a 24-bit key frame.
      Parameters:
      out - The output stream.
      data - The image data.
      width - The width of the image in data elements.
      height - The height of the image in data elements.
      offset - The offset to the first pixel in the data array.
      scanlineStride - The number to append to offset to get to the next scanline.
      Throws:
      IOException
    • encodeDelta24

      public void encodeDelta24(ImageOutputStream out, int[] data, int[] prev, int width, int height, int offset, int scanlineStride) throws IOException
      Encodes a 24-bit delta frame.
      Parameters:
      out - The output stream.
      data - The image data.
      prev - The image data of the previous frame.
      width - The width of the image in data elements.
      height - The height of the image in data elements.
      offset - The offset to the first pixel in the data array.
      scanlineStride - The number to append to offset to get to the next scanline.
      Throws:
      IOException
    • encodeKey32

      public void encodeKey32(ImageOutputStream out, int[] data, int width, int height, int offset, int scanlineStride) throws IOException
      Encodes a 32-bit key frame.
      Parameters:
      out - The output stream.
      data - The image data.
      width - The width of the image in data elements.
      height - The height of the image in data elements.
      offset - The offset to the first pixel in the data array.
      scanlineStride - The number to append to offset to get to the next scanline.
      Throws:
      IOException
    • encodeDelta32

      public void encodeDelta32(ImageOutputStream out, int[] data, int[] prev, int width, int height, int offset, int scanlineStride) throws IOException
      Encodes a 32-bit delta frame.
      Parameters:
      out - The output stream.
      data - The image data.
      prev - The image data of the previous frame.
      width - The width of the image in data elements.
      height - The height of the image in data elements.
      offset - The offset to the first pixel in the data array.
      scanlineStride - The number to append to offset to get to the next scanline.
      Throws:
      IOException
    • decodeDelta16

      public void decodeDelta16(ImageInputStream in, short[] data, short[] prev, int width, int height, int offset, int scanlineStride) throws IOException
      Decodes a 16-bit delta frame.
      Parameters:
      in - The input stream.
      data - The image data.
      prev - The image data of the previous frame. This may be the same object as data.
      width - The width of the image in data elements.
      height - The height of the image in data elements.
      offset - The offset to the first pixel in the data array.
      scanlineStride - The number to append to offset to get to the next scanline.
      Throws:
      IOException