Description of the LCL codecs (MSZH and ZLIB) by Roberto Togni (rtogni at bresciaonline dot it) v0.3: March 24, 2003 ======================================================================= NOTE: The information in this document is now maintained in Wiki format at: http://wiki.multimedia.cx/index.php?title=Lossless_Codec_Libraries ======================================================================= Copyright (c) 2002-2003 Roberto Togni Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled "GNU Free Documentation License". These are random notes i wrote while building a decoder for LCL compressed files. It works, i can assume that this description is mostly right! But since the original codec is available only in binary format, something could be missing or plainly wrong. If you find any errors in this document, or have a sample that doesn't follow this structure, please let me know. Introduction ============ This description is based on LCL Ver 2.23 dated 2000.09.20. The original win32 LCL is written by Kenji Oshima . LCL stands for Lossless Codec Library. LCL is made of avimszh.dll and avilib.dll These codec were created to compress digital animation. LCL codec are made for avi files. Quick description ================= Fourcc used by codec are MSZH and ZLIB. The codec converts original rgb24 image to target colorspace and compresses it with a chosen algorithm. The codec can also remove unchanged frames and replace them with null frames, and can filter image data before compression. The only difference between avimszh and avizlib is in the stream compressor. Png flitering is available only in avizlib. Except for null frames, there is no temporal compression, and all frames can be decodec independently from the others. Each avi chunk contains one frame, in case of multithread mode the two sections are stored into the same chunk. File header =========== Codec information are stored at the end of BITMAPINFOHEADER structure into avi header. This structure is 8 byte longer than the standard structure. struct { standard BITMAPINFOHEADER fields unsigned char unknown[4]; unsigned char imagetype; unsigned char compression; unsigned char flags; unsigned char codec; } BITMAPINFOHEADER_extended unknown: always [4, 0, 0, 0] codec: 1 mszh 3 zlib imagetype: 0 yuv111 1 yuv422 2 rgb24 3 yuv411 4 yuv211 5 yuv420 compression: 0 mszh: compression 1 mszh: no compression, zlib: hispeed compression 9 zlib: high compression -1 zlib: normal compression (zlib standard level) flags: bit 0: multithread used bit 1: nullframe insertion used bit 3: png fileter used (zlib only) Imagetype ========= RGB24 ----- Is standard BGR, 3 bytes per pixel. YUV --- yuv formats can be converted to RGB using the following equations: R = Y + 1.403V' G = Y - 0.344U' - 0.714V' B = Y + 1.770U' or, in a programmer-friendly form (integer math) b = ((y << 20) + u * 1858076 + 0x80000) >> 20; g = ((y << 20) - u * 360857 - v * 748830 + 0x80000) >> 20; r = ((y << 20) + v * 1470103 + 0x80000) >> 20; Values are then clamped to 0-255 range. Please note that these equations don't have the 128 offset value into U and V components. yuv structure: packed format with various subsampling factors [add byte order and description for every yuv format] Please note that byte order is different form standard yuv formats with the same name! Compression =========== As the codec name suggests, all compressors are lossless. Zlib compression ---------------- Uses standard zlib deflate method. For algorithm description look at zlib docs. Compressor is resetted every frame (decode every frame independently). Compression codes (1, 9, -1) have the same meaning as zlib compression flags. Zlib doesn't require compression level at decompressor, so the value is there only for information. Mszh ---- No compression: just does what it says, image is not compressed at all. Mszh compression: works by copying blocks from already decoded data. [add mszh decompression algorithm] Flags ===== Multithread ----------- The encodec image is split in two independent blocks; you have to decode them separately and concatenate the resulting images. [add length and offset fields] Nullframe --------- If two or more frames are equal, coder replaces them with a null frame. Can be ignored by the decoder (demuxer will take care). Png filter (zlib only) ---------------------- I don't know why it's called png filter since it has nothing to do with filters used in pnglib. All filters share the same structure, but the implementation depends on the colorspace. Pngfilters are line based, first pixel is stored unchanged, then other values are stored as difference from the previous ones. The filter (if any) is applied between decompression and colorspace conversion. Pngfilter for RGB24 format doesn't work ok in my implementation. [add structure for each pngfilter] Notes ===== Compressed RGB24 have fourcc DIB instead of MSZH References ========== HomePage (in Japanese) LCL(Loss-Less Codec Library) Ver2.23 By Kenji Oshima 2000.09.20 http://www.geocities.co.jp/Playtown-Denei/2837/ ChangeLog ========= v0.3: March 24, 2003 - licensed under GNU Free Documentation License v0.2: October 17, 2002 - fixed wrong assumptions from pre-release - start adding some content, missing parts commented in [] v0.1: July 09, 2002 - initial pre-release GNU Free Documentation License ============================== see http://www.gnu.org/licenses/fdl.html EOF