Copyright 2012-04-26 Werner Randelshofer

org.monte.media.avi
Class TechSmithCodecCore

java.lang.Object
  extended by org.monte.media.AbstractVideoCodecCore
      extended by org.monte.media.avi.TechSmithCodecCore

public class TechSmithCodecCore
extends AbstractVideoCodecCore

TechSmithCodec (tscc) encodes a BufferedImage as a byte[] array.

This codec does not encode the color palette of an image. This must be done separately.

Supported input formats:

Supported output formats: The codec supports lossless delta- and key-frame encoding of images with 8, 16 or 24 bits per pixel.

Compression of a frame is performed in two steps: In the first, step a frame is compressed line by line from bottom to top. In the second step the resulting data is compressed again using zlib compression.

Apart from the second compression step and the support for 16- and 24-bit data, this encoder is identical to the RunLengthCodec.

Each line of a frame is compressed individually. A line consists of two-byte op-codes optionally followed by data. The end of the line is marked with the EOL op-code.

The following op-codes are supported:

Example:
 Compressed data         Expanded data

 03 04                   04 04 04
 05 06                   06 06 06 06 06
 00 03 45 56 67 00       45 56 67
 02 78                   78 78
 00 02 05 01             Move 5 right and 1 down
 02 78                   78 78
 00 00                   End of line
 09 1E                   1E 1E 1E 1E 1E 1E 1E 1E 1E
 00 01                   End of RLE bitmap
 
References:
http://wiki.multimedia.cx/index.php?title=TechSmith_Screen_Capture_Codec

Palette colors

In an AVI file, palette changes are stored in chunks with id's with the suffix "pc". "pc" chunks contain an AVIPALCHANGE struct as shown below.

 /* ------------------
  * AVI Palette Change
  * ------------------
  * /
 
 // Values for this enum have been taken from:
 // http://biodi.sdsc.edu/Doc/GARP/garp-1.1/define.h
 enum {
     PC_EXPLICIT = 0x02,
     // Specifies that the low-order word of the logical palette entry 
     // designates a hardware palette index. This flag allows the application to 
     // show the contents of the display device palette.
     PC_NOCOLLAPSE = 0x04,
     // Specifies that the color be placed in an unused entry in the system 
     // palette instead of being matched to an existing color in the system 
     // palette. If there are no unused entries in the system palette, the color 
     // is matched normally. Once this color is in the system palette, colors in
     // other logical palettes can be matched to this color.
     PC_RESERVED = 0x01
     // Specifies that the logical palette entry be used for palette animation. 
     // This flag prevents other windows from matching colors to the palette 
     // entry since the color frequently changes. If an unused system-palette
     // entry is available, the color is placed in that entry. Otherwise, the 
     // color is not available for animation.
 } peFlagsEnum;
 /* 
  * The PALETTEENTRY structure specifies the color and usage of an entry in a
  * logical palette. A logical palette is defined by a LOGPALETTE structure.
  * /
 typedef struct { 
   BYTE peRed; // Specifies a red intensity value for the palette entry.
   BYTE peGreen; // Specifies a green intensity value for the palette entry.
   BYTE peBlue; // Specifies a blue intensity value for the palette entry.
   BYTE enum peFlagsEnum peFlags; // Specifies how the palette entry is to be used.
 } PALETTEENTRY;
 
 typedef struct {
   AVIPALCHANGE avipalchange;
 } AVIPALCHANGE0;
 
 typedef struct {
     PALETTEENTRY  p[256];
 } PALETTEENTRY_ALLENTRIES;
 
 typedef struct {
     BYTE          firstEntry;
         // Specifies the index of the first palette entry to change.
     BYTE          numEntries;
         // Specifies the number of palette entries to change, or zero to change 
         // all 256 palette entries.
     WORD          flags;
         // Reserved.
     PALETTEENTRY  peNew[numEntries];
         // Specifies an array of PALETTEENTRY structures, of size "numEntries".
     PALETTEENTRY_ALLENTRIES  all[numEntries==0];
 } AVIPALCHANGE;
 

Version:
$Id: TechSmithCodecCore.java 136 2011-12-26 10:10:26Z werner $
Author:
Werner Randelshofer

Constructor Summary
TechSmithCodecCore()
           
 
Method Summary
 boolean decode16(byte[] inDat, int off, int length, int[] outDat, int[] prevDat, int width, int height, boolean onlyDecodeIfKeyframe)
          Decodes from 16-bit to 24-bit RGB.
 boolean decode24(byte[] inDat, int off, int length, int[] outDat, int[] prevDat, int width, int height, boolean onlyDecodeIfKeyframe)
          Decodes to 24-bit RGB.
 boolean decode8(byte[] inDat, int off, int length, byte[] outDat, byte[] prevDat, int width, int height, boolean onlyDecodeIfKeyframe)
          Decodes to 8-bit palettised.
 boolean decode8(byte[] inDat, int off, int length, int[] outDat, int[] prevDat, int width, int height, boolean onlyDecodeIfKeyframe)
          Decodes to 24-bit direct color.
 void decodePalette(byte[] inDat, int off, int len)
          Decodes an AVI palette change chunk.
 void encodeDelta16(java.io.OutputStream out, short[] data, short[] prev, int width, int height, int offset, int scanlineStride)
          Encodes a 16-bit delta frame.
 void encodeDelta24(java.io.OutputStream out, int[] data, int[] prev, int width, int height, int offset, int scanlineStride)
          Encodes a 24-bit delta frame.
 void encodeDelta8(java.io.OutputStream out, byte[] data, byte[] prev, int width, int height, int offset, int scanlineStride)
          Encodes an 8-bit delta frame with indexed colors.
 void encodeDelta8to24(java.io.OutputStream out, byte[] data, byte[] prev, int width, int height, int offset, int scanlineStride)
          Encodes an 8-bit delta frame with indexed colors to 24-bit.
 void encodeKey16(java.io.OutputStream out, short[] data, int width, int height, int offset, int scanlineStride)
          Encodes a 16-bit key frame.
 void encodeKey24(java.io.OutputStream out, int[] data, int width, int height, int offset, int scanlineStride)
          Encodes a 24-bit key frame.
 void encodeKey8(java.io.OutputStream out, byte[] data, int width, int height, int offset, int scanlineStride)
          Encodes a 8-bit key frame with indexed colors.
 void encodeKey8to24(java.io.OutputStream out, byte[] data, int width, int height, int offset, int scanlineStride)
          Encodes a 8-bit key frame with indexed colors to 24-bit.
 void encodeSameDelta16(java.io.OutputStream out, short[] data, short[] prev, int width, int height, int offset, int scanlineStride)
          Encodes a delta frame which is known to have the same content than the previous frame.
 void encodeSameDelta24(java.io.OutputStream out, int[] data, int[] prev, int width, int height, int offset, int scanlineStride)
          Encodes a delta frame which is known to have the same content than the previous frame.
 void encodeSameDelta8(java.io.OutputStream out, byte[] data, byte[] prev, int width, int height, int offset, int scanlineStride)
          Encodes a delta frame which is known to have the same content than the previous frame.
 int[] getPalette()
           
 void reset()
           
 void setPalette(byte[] redValues, byte[] greenValues, byte[] blueValues)
           
 
Methods inherited from class org.monte.media.AbstractVideoCodecCore
readInt24LE, readInts24LE, readRGB555to24, readRGB555to24LE, readRGB565to24, readRGBs555to24, readRGBs555to24LE, readRGBs565to24, writeInt24, writeInt24LE, writeInts24, writeInts24LE
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

TechSmithCodecCore

public TechSmithCodecCore()
Method Detail

reset

public void reset()

getPalette

public int[] getPalette()

decodePalette

public void decodePalette(byte[] inDat,
                          int off,
                          int len)
                   throws java.io.IOException
Decodes an AVI palette change chunk. FIXME - This could be moved out into a separate class.

Throws:
java.io.IOException

decode8

public boolean decode8(byte[] inDat,
                       int off,
                       int length,
                       byte[] outDat,
                       byte[] prevDat,
                       int width,
                       int height,
                       boolean onlyDecodeIfKeyframe)
                throws java.io.IOException
Decodes to 8-bit palettised. Returns true if a key-frame was decoded.

Parameters:
inDat -
off -
length -
outDat -
prevDat - The pixels decoded in the previous frame. Since no double buffering is used, this can be the same array than outDat.
width -
height -
onlyDecodeIfKeyframe -
Returns:
True if a key-frame was decoded.
Throws:
java.io.IOException

decode8

public boolean decode8(byte[] inDat,
                       int off,
                       int length,
                       int[] outDat,
                       int[] prevDat,
                       int width,
                       int height,
                       boolean onlyDecodeIfKeyframe)
                throws java.io.IOException
Decodes to 24-bit direct color. Returns true if a key-frame was decoded.

Parameters:
inDat -
off -
length -
outDat -
prevDat - The pixels decoded in the previous frame. Since no double buffering is used, this can be the same array than outDat.
width -
height -
onlyDecodeIfKeyframe -
Returns:
True if a key-frame was decoded.
Throws:
java.io.IOException

decode24

public boolean decode24(byte[] inDat,
                        int off,
                        int length,
                        int[] outDat,
                        int[] prevDat,
                        int width,
                        int height,
                        boolean onlyDecodeIfKeyframe)
                 throws java.io.IOException
Decodes to 24-bit RGB. Returns true if a key-frame was decoded.

Throws:
java.io.IOException

decode16

public boolean decode16(byte[] inDat,
                        int off,
                        int length,
                        int[] outDat,
                        int[] prevDat,
                        int width,
                        int height,
                        boolean onlyDecodeIfKeyframe)
                 throws java.io.IOException
Decodes from 16-bit to 24-bit RGB. Returns true if a key-frame was decoded.

Throws:
java.io.IOException

encodeDelta8

public void encodeDelta8(java.io.OutputStream out,
                         byte[] data,
                         byte[] prev,
                         int width,
                         int height,
                         int offset,
                         int scanlineStride)
                  throws java.io.IOException
Encodes an 8-bit delta frame with indexed colors.

Parameters:
out - The output stream.
data - The image data.
prev - The image data of the previous frame.
offset - The offset to the first pixel in the data array.
width - The width of the image in data elements.
scanlineStride - The number to add to offset to get to the next scanline.
Throws:
java.io.IOException

encodeDelta8to24

public void encodeDelta8to24(java.io.OutputStream out,
                             byte[] data,
                             byte[] prev,
                             int width,
                             int height,
                             int offset,
                             int scanlineStride)
                      throws java.io.IOException
Encodes an 8-bit delta frame with indexed colors to 24-bit.

Parameters:
out - The output stream.
data - The image data.
prev - The image data of the previous frame.
offset - The offset to the first pixel in the data array.
width - The width of the image in data elements.
scanlineStride - The number to add to offset to get to the next scanline.
Throws:
java.io.IOException

encodeSameDelta8

public void encodeSameDelta8(java.io.OutputStream out,
                             byte[] data,
                             byte[] prev,
                             int width,
                             int height,
                             int offset,
                             int scanlineStride)
                      throws java.io.IOException
Encodes a delta frame which is known to have the same content than the previous frame.

Parameters:
out -
data -
prev -
width -
height -
offset -
scanlineStride -
Throws:
java.io.IOException

encodeSameDelta24

public void encodeSameDelta24(java.io.OutputStream out,
                              int[] data,
                              int[] prev,
                              int width,
                              int height,
                              int offset,
                              int scanlineStride)
                       throws java.io.IOException
Encodes a delta frame which is known to have the same content than the previous frame.

Parameters:
out -
data -
prev -
width -
height -
offset -
scanlineStride -
Throws:
java.io.IOException

encodeSameDelta16

public void encodeSameDelta16(java.io.OutputStream out,
                              short[] data,
                              short[] prev,
                              int width,
                              int height,
                              int offset,
                              int scanlineStride)
                       throws java.io.IOException
Encodes a delta frame which is known to have the same content than the previous frame.

Parameters:
out -
data -
prev -
width -
height -
offset -
scanlineStride -
Throws:
java.io.IOException

encodeKey8

public void encodeKey8(java.io.OutputStream out,
                       byte[] data,
                       int width,
                       int height,
                       int offset,
                       int scanlineStride)
                throws java.io.IOException
Encodes a 8-bit key frame with indexed colors.

Parameters:
out - The output stream.
data - The image data.
offset - The offset to the first pixel in the data array.
width - The width of the image in data elements.
scanlineStride - The number to add to offset to get to the next scanline.
Throws:
java.io.IOException

encodeKey8to24

public void encodeKey8to24(java.io.OutputStream out,
                           byte[] data,
                           int width,
                           int height,
                           int offset,
                           int scanlineStride)
                    throws java.io.IOException
Encodes a 8-bit key frame with indexed colors to 24-bit.

Parameters:
out - The output stream.
data - The image data.
offset - The offset to the first pixel in the data array.
width - The width of the image in data elements.
scanlineStride - The number to add to offset to get to the next scanline.
Throws:
java.io.IOException

encodeDelta16

public void encodeDelta16(java.io.OutputStream out,
                          short[] data,
                          short[] prev,
                          int width,
                          int height,
                          int offset,
                          int scanlineStride)
                   throws java.io.IOException
Encodes a 16-bit delta frame.

Parameters:
out - The output stream.
data - The image data.
prev - The image data of the previous frame.
offset - The offset to the first pixel in the data array.
width - The width of the image in data elements.
scanlineStride - The number to add to offset to get to the next scanline.
Throws:
java.io.IOException

encodeKey24

public void encodeKey24(java.io.OutputStream out,
                        int[] data,
                        int width,
                        int height,
                        int offset,
                        int scanlineStride)
                 throws java.io.IOException
Encodes a 24-bit key frame.

Parameters:
out - The output stream.
data - The image data.
offset - The offset to the first pixel in the data array.
width - The width of the image in data elements.
scanlineStride - The number to add to offset to get to the next scanline.
Throws:
java.io.IOException

encodeDelta24

public void encodeDelta24(java.io.OutputStream out,
                          int[] data,
                          int[] prev,
                          int width,
                          int height,
                          int offset,
                          int scanlineStride)
                   throws java.io.IOException
Encodes a 24-bit delta frame.

Parameters:
out - The output stream.
data - The image data.
prev - The image data of the previous frame.
offset - The offset to the first pixel in the data array.
width - The width of the image in data elements.
scanlineStride - The number to add to offset to get to the next scanline.
Throws:
java.io.IOException

encodeKey16

public void encodeKey16(java.io.OutputStream out,
                        short[] data,
                        int width,
                        int height,
                        int offset,
                        int scanlineStride)
                 throws java.io.IOException
Encodes a 16-bit key frame.

Parameters:
out - The output stream.
data - The image data.
offset - The offset to the first pixel in the data array.
width - The width of the image in data elements.
scanlineStride - The number to add to offset to get to the next scanline.
Throws:
java.io.IOException

setPalette

public void setPalette(byte[] redValues,
                       byte[] greenValues,
                       byte[] blueValues)

Copyright 2012-04-26 Werner Randelshofer