<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.multimedia.cx/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Ultimotion</id>
	<title>MultimediaWiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.multimedia.cx/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Ultimotion"/>
	<link rel="alternate" type="text/html" href="https://wiki.multimedia.cx/index.php/Special:Contributions/Ultimotion"/>
	<updated>2026-06-19T08:09:43Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.39.5</generator>
	<entry>
		<id>https://wiki.multimedia.cx/index.php?title=IBM_UltiMotion&amp;diff=6246</id>
		<title>IBM UltiMotion</title>
		<link rel="alternate" type="text/html" href="https://wiki.multimedia.cx/index.php?title=IBM_UltiMotion&amp;diff=6246"/>
		<updated>2006-10-12T20:35:27Z</updated>

		<summary type="html">&lt;p&gt;Ultimotion: /* Decoding Algorithm */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* FourCC: ULTI&lt;br /&gt;
* Company: [[IBM]]&lt;br /&gt;
* Official Description: [http://multimedia.cx/UMSPEC.ZIP Ultimotion Digital Video Data Stream Specification]&lt;br /&gt;
* Additional Documentation: [http://multimedia.cx/ultimotion-format.txt 'Description of the IBM UltiMotion (ULTI) Video Codec' by Mike Melanson and Konstantin Shishkov ].''&lt;br /&gt;
* Samples: [http://samples.mplayerhq.hu/V-codecs/ULTI/ http://samples.mplayerhq.hu/V-codecs/ULTI/]&lt;br /&gt;
* Codec: [http://hobbes.nmsu.edu/cgi-bin/h-viewer?sh=1&amp;amp;fname=/pub/windows/ultimo.zip Win32 Ultimotion decoder]&lt;br /&gt;
&lt;br /&gt;
IBM Ultimotion is a video codec typically seen in [[AVI]] files, though there is no reason it could not be used in other container formats.  Full codecs were available for Windows 3.1 (VfW), OS/2 and AIX.  It is primarily a vector quantizing algorithm with simple inter-frame coding (unchanged block).  Ultimotion encoding is significantly more computationally intensive than decoding.&lt;br /&gt;
&lt;br /&gt;
== Decoding Algorithm ==&lt;br /&gt;
&lt;br /&gt;
The Ultimotion algorithm operates natively on a scaled-down [[Raw YUV|YUV]] 4:1:0 planar colorspace. This means that for each 4x4 block of pixels (quadrant), each of the 16 pixels has a luminance (Y) sample and the entire block shares one chrominance sample expressed as two color difference components : C&amp;lt;sub&amp;gt;b&amp;lt;/sub&amp;gt; (or U) and C&amp;lt;sub&amp;gt;r&amp;lt;/sub&amp;gt; (or V). The colorspace is actually non-linear quantized to fixed values from 2 tables. Indices into these tables (64 possible values for luminance and 16 for each chrominance component) are transmitted in the final bitstream.&lt;br /&gt;
&lt;br /&gt;
The Ultimotion algorithm codes a frame by dividing it into a series of 8x8 blocks. Each 8x8 block is subdivided and coded as 4 4x4 quadrants. The 4 quadrants, 0-3, are coded in the following arrangement:&lt;br /&gt;
&lt;br /&gt;
  0 3&lt;br /&gt;
  1 2&lt;br /&gt;
&lt;br /&gt;
Each block can be encoded using a single chrominance sample or unique chrominance sample for each quadrant. Each quadrant has 16 luminance samples that can be coded using a variety of methods.&lt;br /&gt;
&lt;br /&gt;
To decode a frame of Ultimotion data, follow this process:&lt;br /&gt;
&lt;br /&gt;
 initialize uniq and mode flags to 0&lt;br /&gt;
 &lt;br /&gt;
 for each 8x8 block in the frame, iterating from left -&amp;gt; right, top -&amp;gt; bottom:&lt;br /&gt;
 &lt;br /&gt;
  get the next byte in the stream (b0)&lt;br /&gt;
  if (b0 &amp;amp; 0xF8) == 0x70, handle escape code:&lt;br /&gt;
    if b0 is 0x70&lt;br /&gt;
      mode = next byte in stream&lt;br /&gt;
      note: only mode values of 0 or 1 are valid&lt;br /&gt;
    if b0 is 0x71&lt;br /&gt;
      uniq flag = -1 &lt;br /&gt;
    if b0 is 0x72&lt;br /&gt;
      toggle uniq flag (0/1)&lt;br /&gt;
    if b0 is 0x73&lt;br /&gt;
      end of frame, stop decoding&lt;br /&gt;
    if b0 is 0x74&lt;br /&gt;
      get the next byte in stream (b1)&lt;br /&gt;
      skip next (b1) blocks in the output frame (unchanged from previous frame)&lt;br /&gt;
 &lt;br /&gt;
  else&lt;br /&gt;
    if b0 is non-zero and uniq flag is 0&lt;br /&gt;
      chrominance byte = next byte from stream&lt;br /&gt;
 &lt;br /&gt;
    for each 4x4 quadrant in the block, arranged in the quadrant pattern:&lt;br /&gt;
 &lt;br /&gt;
      extract quadrant coding mode from b0:&lt;br /&gt;
        bits 7-6: quadrant 0 coding mode&lt;br /&gt;
        bits 5-4: quadrant 1 coding mode&lt;br /&gt;
        bits 3-2: quadrant 2 coding mode&lt;br /&gt;
        bits 1-0: quadrant 3 coding mode&lt;br /&gt;
 &lt;br /&gt;
      if coding mode is non-zero and uniq flag is non-zero&lt;br /&gt;
        chrominance byte = next byte from stream&lt;br /&gt;
 &lt;br /&gt;
      coding mode 0:&lt;br /&gt;
        skip quadrant (unchanged from the previous frame)&lt;br /&gt;
 &lt;br /&gt;
      coding mode 1:&lt;br /&gt;
        paint the luminance samples using a gradient pattern based on one &lt;br /&gt;
          sample coded in the stream&lt;br /&gt;
 &lt;br /&gt;
        get next byte from stream (b1)&lt;br /&gt;
        bits 7-6 of b1 indicate gradient fill pattern:&lt;br /&gt;
          0 = gradient fill pattern A&lt;br /&gt;
          1 = gradient fill pattern 2&lt;br /&gt;
          2 = gradient fill pattern 6&lt;br /&gt;
          3 = gradient fill pattern B&lt;br /&gt;
        bits 5-0 of b1 indicate luminance sample Y0&lt;br /&gt;
          Y1 = Y0, Y2 = Y0 + 1, Y3 = Y0 + 1&lt;br /&gt;
        fill luminance samples according to Y0..Y3 and the gradient fill &lt;br /&gt;
          pattern (see section Gradient Fill Patterns)&lt;br /&gt;
 &lt;br /&gt;
      coding mode 2:&lt;br /&gt;
        paint the luminance samples using a gradient pattern based on either &lt;br /&gt;
          four samples retrieved from a 4,096-entry codebook using an index&lt;br /&gt;
          coded in the stream or four samples coded in the stream &lt;br /&gt;
        if mode is 0&lt;br /&gt;
          get the next 2 bytes from the stream as a big endian 16-bit &lt;br /&gt;
            number:&lt;br /&gt;
          gradient fill pattern = bits 15-12&lt;br /&gt;
          luminance codebook index = bits 11-0&lt;br /&gt;
          Y0..Y3 are set according to the codebook entry (see section Luminance&lt;br /&gt;
            Codebook Enumeration)&lt;br /&gt;
          if bit 3 of the gradient fill pattern is set&lt;br /&gt;
            swap Y0 with Y3 and Y1 with Y2&lt;br /&gt;
            clear bit 3 of the gradient fill pattern&lt;br /&gt;
          fill luminance samples according to Y0..Y3 and the gradient fill &lt;br /&gt;
            pattern (see section Gradient Fill Patterns)&lt;br /&gt;
        else (mode is non-zero)&lt;br /&gt;
          get the next 3 bytes from the stream as a big endian 24-bit number:&lt;br /&gt;
            Y0 = bits 23-18&lt;br /&gt;
            Y1 = bits 17-12&lt;br /&gt;
            Y2 = bits 11-6&lt;br /&gt;
            Y3 = bits 5-0&lt;br /&gt;
          fill luminance samples according to Y0..Y3 and gradient fill &lt;br /&gt;
            pattern C (see section Gradient Fill Patterns)&lt;br /&gt;
 &lt;br /&gt;
      coding mode 3:&lt;br /&gt;
        flexible coding mode that can paint the luminance samples with an &lt;br /&gt;
          arbitrary pattern using two samples and a set of flags coded in the &lt;br /&gt;
          stream, or with a gradient fill pattern and four samples coded in the &lt;br /&gt;
          stream, or with 16 samples coded in the stream&lt;br /&gt;
        if mode is 0&lt;br /&gt;
          if bit 7 of b1 is 0&lt;br /&gt;
            flagsA = b1&lt;br /&gt;
            flagsB = next byte in the stream&lt;br /&gt;
            Y0 = next byte in stream &amp;amp; 0x3F&lt;br /&gt;
            Y1 = next byte in stream &amp;amp; 0x3F&lt;br /&gt;
            the 16 bits between flagsA and flagsB represent the pattern &lt;br /&gt;
              used to place either Y0 or Y1 into the luminance grid&lt;br /&gt;
 &lt;br /&gt;
              A7 A6 A5 A4&lt;br /&gt;
              A3 A2 A1 A0&lt;br /&gt;
              B7 B6 B5 B4&lt;br /&gt;
              B3 B2 B1 B0&lt;br /&gt;
 &lt;br /&gt;
              for example, if bit 3 of flagsB is 1, Y1 would be used in &lt;br /&gt;
              the lower left corner of the quadrant, else Y0&lt;br /&gt;
          else&lt;br /&gt;
            gradient fill pattern = bits 6-4 of b1&lt;br /&gt;
            get the next byte in the stream (b2)&lt;br /&gt;
            Y0 = ((b1 &amp;amp; 0x0F) &amp;lt;&amp;lt; 2) | (b2 &amp;gt;&amp;gt; 6)&lt;br /&gt;
            Y1 = bits 5-0 of b2&lt;br /&gt;
            Y2 = next byte in stream &amp;amp; 0x3F&lt;br /&gt;
            Y3 = next byte in stream &amp;amp; 0x3F&lt;br /&gt;
            fill luminance samples according to Y0..Y3 and the gradient &lt;br /&gt;
              fill pattern (see section Gradient Fill Patterns)&lt;br /&gt;
        else (mode is non-zero)&lt;br /&gt;
          get the next 12 bytes from the stream as 16 6-bit numbers as the 16 &lt;br /&gt;
            luminance samples (Y0..Y15) for the quadrant&lt;br /&gt;
          fill luminance samples according to Y0..Y15 and gradient fill &lt;br /&gt;
            pattern D (see section Gradient Fill Patterns)&lt;br /&gt;
 &lt;br /&gt;
      finally, output quadrant:&lt;br /&gt;
        bits 7-4 of the chrominance byte represent the Cr (or V) component&lt;br /&gt;
          while bits 3-0 represent the Cb (U) component&lt;br /&gt;
        convert the 16 luminance values and the 2 chrominance values to a &lt;br /&gt;
          proper YUV colorspace using the conversion tables in Appendix A&lt;br /&gt;
 &lt;br /&gt;
  if uniq flag is -1&lt;br /&gt;
    uniq flag = 0&lt;br /&gt;
&lt;br /&gt;
== Gradient Fill Patterns ==&lt;br /&gt;
&lt;br /&gt;
The ULTI codec has 12 gradient fill patterns for painting 4x4 sub blocks of luminance data using 4 (or 16) luminance samples.&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 0: (0 degrees)&lt;br /&gt;
  Y0 Y1 Y2 Y3&lt;br /&gt;
  Y0 Y1 Y2 Y3&lt;br /&gt;
  Y0 Y1 Y2 Y3&lt;br /&gt;
  Y0 Y1 Y2 Y3&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 1: (22.5 degrees)&lt;br /&gt;
  Y1 Y2 Y3 Y3&lt;br /&gt;
  Y0 Y1 Y2 Y3&lt;br /&gt;
  Y0 Y1 Y2 Y3&lt;br /&gt;
  Y0 Y0 Y1 Y2&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 2: (45 degrees)&lt;br /&gt;
  Y1 Y2 Y3 Y3&lt;br /&gt;
  Y1 Y2 Y2 Y3&lt;br /&gt;
  Y0 Y1 Y1 Y2&lt;br /&gt;
  Y0 Y0 Y1 Y2&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 3: (67.5 degrees)&lt;br /&gt;
  Y2 Y3 Y3 Y3&lt;br /&gt;
  Y1 Y2 Y2 Y3&lt;br /&gt;
  Y0 Y1 Y1 Y2&lt;br /&gt;
  Y0 Y0 Y0 Y1&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 4: (90 degrees)&lt;br /&gt;
  Y3 Y3 Y3 Y3&lt;br /&gt;
  Y2 Y2 Y2 Y2&lt;br /&gt;
  Y1 Y1 Y1 Y1&lt;br /&gt;
  Y0 Y0 Y0 Y0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 5: (112.5 degrees)&lt;br /&gt;
  Y3 Y3 Y3 Y2&lt;br /&gt;
  Y3 Y2 Y2 Y1&lt;br /&gt;
  Y2 Y1 Y1 Y0&lt;br /&gt;
  Y1 Y0 Y0 Y0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 6: (135 degrees)&lt;br /&gt;
  Y3 Y3 Y2 Y2&lt;br /&gt;
  Y3 Y2 Y1 Y1&lt;br /&gt;
  Y2 Y2 Y1 Y0&lt;br /&gt;
  Y1 Y1 Y0 Y0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 7: (157.5 degrees)&lt;br /&gt;
  Y3 Y3 Y2 Y1&lt;br /&gt;
  Y3 Y2 Y1 Y0&lt;br /&gt;
  Y3 Y2 Y1 Y0&lt;br /&gt;
  Y2 Y1 Y0 Y0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern A: (homogeneous)&lt;br /&gt;
  Y0 Y0 Y0 Y0&lt;br /&gt;
  Y0 Y0 Y0 Y0&lt;br /&gt;
  Y0 Y0 Y0 Y0&lt;br /&gt;
  Y0 Y0 Y0 Y0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern B: (270 degrees)&lt;br /&gt;
  Y0 Y0 Y0 Y0&lt;br /&gt;
  Y1 Y1 Y1 Y1&lt;br /&gt;
  Y2 Y2 Y2 Y2&lt;br /&gt;
  Y3 Y3 Y3 Y3&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern C: (subsampled)&lt;br /&gt;
  Y0 Y0 Y1 Y1&lt;br /&gt;
  Y0 Y0 Y1 Y1&lt;br /&gt;
  Y2 Y2 Y3 Y3&lt;br /&gt;
  Y2 Y2 Y3 Y3&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern D: (16 samples)&lt;br /&gt;
  Y0  Y1  Y2  Y3&lt;br /&gt;
  Y4  Y5  Y6  Y7&lt;br /&gt;
  Y8  Y9  Y10 Y11&lt;br /&gt;
  Y12 Y13 Y14 Y15&lt;br /&gt;
&lt;br /&gt;
== Luminance Codebook Enumeration ==&lt;br /&gt;
&lt;br /&gt;
The following pseudo-code creates the Ultimotion Luminance Transition Coding codebook&lt;br /&gt;
&lt;br /&gt;
 i = 0&lt;br /&gt;
 for Y0 = 0 to 61&lt;br /&gt;
   for Y3 = Y0 + 2 to 63&lt;br /&gt;
     Yd = Y3 - Y0&lt;br /&gt;
     if Yd in (2,3,5,6,7,8,11,14,17,20)&lt;br /&gt;
       LTC[i++] = (Y0, Y0 + Yd/3, Y3 - Yd/3, Y3)&lt;br /&gt;
     endif&lt;br /&gt;
     if Yd in (4,5,6,7,8,11,14,17,20,23,26,29,32,36)&lt;br /&gt;
       LTC[i++] = (Y0, Y0 + Yd/2, Y3 - Yd/4, Y3)&lt;br /&gt;
       LTC[i++] = (Y0, Y0 + Yd/4, Y3 - Yd/4, Y3)&lt;br /&gt;
       LTC[i++] = (Y0, Y0 + Yd/4, Y3 - Yd/2, Y3)&lt;br /&gt;
     endif&lt;br /&gt;
     if Yd in (6,8,11,14,17,20,23,26,29,32,35,40,46)&lt;br /&gt;
       LTC[i++] = (Y0, Y3, Y3, Y3)&lt;br /&gt;
       LTC[i++] = (Y0, Y0, Y3, Y3)&lt;br /&gt;
       LTC[i++] = (Y0, Y0, Y0, Y3)&lt;br /&gt;
     endif&lt;br /&gt;
   next Y3&lt;br /&gt;
 next Y0&lt;br /&gt;
&lt;br /&gt;
It should be noted there is an error in the &amp;quot;Ultimotion Digital Video Data Stream Specification&amp;quot; - the pre-determined linear transitions are for Y deltas of 2, 3, 5, 6, 7, 8, 11, 14, 17, 20 (not 4). (If 4 is included then there are 4156 transitions. The various transitions are handled by the low contrast edge transitions.) &lt;br /&gt;
&lt;br /&gt;
== Converting Ultimotion Scaled YUV To Correct YUV ==&lt;br /&gt;
&lt;br /&gt;
To convert Ultimotion 6-bit luminance values to proper luminance samples, use the following conversion table:&lt;br /&gt;
&lt;br /&gt;
 unsigned char ulti_lumas[64] =&lt;br /&gt;
    { 0x10, 0x13, 0x17, 0x1A, 0x1E, 0x21, 0x25, 0x28,&lt;br /&gt;
      0x2C, 0x2F, 0x33, 0x36, 0x3A, 0x3D, 0x41, 0x44,&lt;br /&gt;
      0x48, 0x4B, 0x4F, 0x52, 0x56, 0x59, 0x5C, 0x60,&lt;br /&gt;
      0x63, 0x67, 0x6A, 0x6E, 0x71, 0x75, 0x78, 0x7C,&lt;br /&gt;
      0x7F, 0x83, 0x86, 0x8A, 0x8D, 0x91, 0x94, 0x98,&lt;br /&gt;
      0x9B, 0x9F, 0xA2, 0xA5, 0xA9, 0xAC, 0xB0, 0xB3,&lt;br /&gt;
      0xB7, 0xBA, 0xBE, 0xC1, 0xC5, 0xC8, 0xCC, 0xCF,&lt;br /&gt;
      0xD3, 0xD6, 0xDA, 0xDD, 0xE1, 0xE4, 0xE8, 0xEB};&lt;br /&gt;
      &lt;br /&gt;
To convert Ultimotion 4-bit chrominance values to proper chrominance samples, use the following conversion table:&lt;br /&gt;
&lt;br /&gt;
 unsigned char ulti_chromas[16] =&lt;br /&gt;
    { 0x60, 0x67, 0x6D, 0x73, 0x7A, 0x80, 0x86, 0x8D,&lt;br /&gt;
      0x93, 0x99, 0xA0, 0xA6, 0xAC, 0xB3, 0xB9, 0xC0};&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* [http://xanim.polter.net/ XAnim]&lt;br /&gt;
&lt;br /&gt;
* [http://mplayerhq.hu/cgi-bin/cvsweb.cgi/~checkout~/ffmpeg/libavcodec/ulti_cb.h?content-type=text/x-cvsweb-markup&amp;amp;cvsroot=FFMpeg Ultimotion Luminance Codebook]&lt;br /&gt;
&lt;br /&gt;
[[Category:Video Codecs]]&lt;/div&gt;</summary>
		<author><name>Ultimotion</name></author>
	</entry>
	<entry>
		<id>https://wiki.multimedia.cx/index.php?title=IBM_UltiMotion&amp;diff=6245</id>
		<title>IBM UltiMotion</title>
		<link rel="alternate" type="text/html" href="https://wiki.multimedia.cx/index.php?title=IBM_UltiMotion&amp;diff=6245"/>
		<updated>2006-10-12T20:34:57Z</updated>

		<summary type="html">&lt;p&gt;Ultimotion: /* Decoding Algorithm */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* FourCC: ULTI&lt;br /&gt;
* Company: [[IBM]]&lt;br /&gt;
* Official Description: [http://multimedia.cx/UMSPEC.ZIP Ultimotion Digital Video Data Stream Specification]&lt;br /&gt;
* Additional Documentation: [http://multimedia.cx/ultimotion-format.txt 'Description of the IBM UltiMotion (ULTI) Video Codec' by Mike Melanson and Konstantin Shishkov ].''&lt;br /&gt;
* Samples: [http://samples.mplayerhq.hu/V-codecs/ULTI/ http://samples.mplayerhq.hu/V-codecs/ULTI/]&lt;br /&gt;
* Codec: [http://hobbes.nmsu.edu/cgi-bin/h-viewer?sh=1&amp;amp;fname=/pub/windows/ultimo.zip Win32 Ultimotion decoder]&lt;br /&gt;
&lt;br /&gt;
IBM Ultimotion is a video codec typically seen in [[AVI]] files, though there is no reason it could not be used in other container formats.  Full codecs were available for Windows 3.1 (VfW), OS/2 and AIX.  It is primarily a vector quantizing algorithm with simple inter-frame coding (unchanged block).  Ultimotion encoding is significantly more computationally intensive than decoding.&lt;br /&gt;
&lt;br /&gt;
== Decoding Algorithm ==&lt;br /&gt;
&lt;br /&gt;
The Ultimotion algorithm operates natively on a scaled-down [[Raw YUV|YUV]] 4:1:0 planar colorspace. This means that for each 4x4 block of pixels (quadrant), each of the 16 pixels has a luminance (Y) sample and the entire block shares one chrominance sample (expressed as two color difference components : C&amp;lt;sub&amp;gt;b&amp;lt;/sub&amp;gt; (or U) and C&amp;lt;sub&amp;gt;r&amp;lt;/sub&amp;gt; (or V). The colorspace is actually non-linear quantized to fixed values from 2 tables. Indices into these tables (64 possible values for luminance and 16 for each chrominance component) are transmitted in the final bitstream.&lt;br /&gt;
&lt;br /&gt;
The Ultimotion algorithm codes a frame by dividing it into a series of 8x8 blocks. Each 8x8 block is subdivided and coded as 4 4x4 quadrants. The 4 quadrants, 0-3, are coded in the following arrangement:&lt;br /&gt;
&lt;br /&gt;
  0 3&lt;br /&gt;
  1 2&lt;br /&gt;
&lt;br /&gt;
Each block can be encoded using a single chrominance sample or unique chrominance sample for each quadrant. Each quadrant has 16 luminance samples that can be coded using a variety of methods.&lt;br /&gt;
&lt;br /&gt;
To decode a frame of Ultimotion data, follow this process:&lt;br /&gt;
&lt;br /&gt;
 initialize uniq and mode flags to 0&lt;br /&gt;
 &lt;br /&gt;
 for each 8x8 block in the frame, iterating from left -&amp;gt; right, top -&amp;gt; bottom:&lt;br /&gt;
 &lt;br /&gt;
  get the next byte in the stream (b0)&lt;br /&gt;
  if (b0 &amp;amp; 0xF8) == 0x70, handle escape code:&lt;br /&gt;
    if b0 is 0x70&lt;br /&gt;
      mode = next byte in stream&lt;br /&gt;
      note: only mode values of 0 or 1 are valid&lt;br /&gt;
    if b0 is 0x71&lt;br /&gt;
      uniq flag = -1 &lt;br /&gt;
    if b0 is 0x72&lt;br /&gt;
      toggle uniq flag (0/1)&lt;br /&gt;
    if b0 is 0x73&lt;br /&gt;
      end of frame, stop decoding&lt;br /&gt;
    if b0 is 0x74&lt;br /&gt;
      get the next byte in stream (b1)&lt;br /&gt;
      skip next (b1) blocks in the output frame (unchanged from previous frame)&lt;br /&gt;
 &lt;br /&gt;
  else&lt;br /&gt;
    if b0 is non-zero and uniq flag is 0&lt;br /&gt;
      chrominance byte = next byte from stream&lt;br /&gt;
 &lt;br /&gt;
    for each 4x4 quadrant in the block, arranged in the quadrant pattern:&lt;br /&gt;
 &lt;br /&gt;
      extract quadrant coding mode from b0:&lt;br /&gt;
        bits 7-6: quadrant 0 coding mode&lt;br /&gt;
        bits 5-4: quadrant 1 coding mode&lt;br /&gt;
        bits 3-2: quadrant 2 coding mode&lt;br /&gt;
        bits 1-0: quadrant 3 coding mode&lt;br /&gt;
 &lt;br /&gt;
      if coding mode is non-zero and uniq flag is non-zero&lt;br /&gt;
        chrominance byte = next byte from stream&lt;br /&gt;
 &lt;br /&gt;
      coding mode 0:&lt;br /&gt;
        skip quadrant (unchanged from the previous frame)&lt;br /&gt;
 &lt;br /&gt;
      coding mode 1:&lt;br /&gt;
        paint the luminance samples using a gradient pattern based on one &lt;br /&gt;
          sample coded in the stream&lt;br /&gt;
 &lt;br /&gt;
        get next byte from stream (b1)&lt;br /&gt;
        bits 7-6 of b1 indicate gradient fill pattern:&lt;br /&gt;
          0 = gradient fill pattern A&lt;br /&gt;
          1 = gradient fill pattern 2&lt;br /&gt;
          2 = gradient fill pattern 6&lt;br /&gt;
          3 = gradient fill pattern B&lt;br /&gt;
        bits 5-0 of b1 indicate luminance sample Y0&lt;br /&gt;
          Y1 = Y0, Y2 = Y0 + 1, Y3 = Y0 + 1&lt;br /&gt;
        fill luminance samples according to Y0..Y3 and the gradient fill &lt;br /&gt;
          pattern (see section Gradient Fill Patterns)&lt;br /&gt;
 &lt;br /&gt;
      coding mode 2:&lt;br /&gt;
        paint the luminance samples using a gradient pattern based on either &lt;br /&gt;
          four samples retrieved from a 4,096-entry codebook using an index&lt;br /&gt;
          coded in the stream or four samples coded in the stream &lt;br /&gt;
        if mode is 0&lt;br /&gt;
          get the next 2 bytes from the stream as a big endian 16-bit &lt;br /&gt;
            number:&lt;br /&gt;
          gradient fill pattern = bits 15-12&lt;br /&gt;
          luminance codebook index = bits 11-0&lt;br /&gt;
          Y0..Y3 are set according to the codebook entry (see section Luminance&lt;br /&gt;
            Codebook Enumeration)&lt;br /&gt;
          if bit 3 of the gradient fill pattern is set&lt;br /&gt;
            swap Y0 with Y3 and Y1 with Y2&lt;br /&gt;
            clear bit 3 of the gradient fill pattern&lt;br /&gt;
          fill luminance samples according to Y0..Y3 and the gradient fill &lt;br /&gt;
            pattern (see section Gradient Fill Patterns)&lt;br /&gt;
        else (mode is non-zero)&lt;br /&gt;
          get the next 3 bytes from the stream as a big endian 24-bit number:&lt;br /&gt;
            Y0 = bits 23-18&lt;br /&gt;
            Y1 = bits 17-12&lt;br /&gt;
            Y2 = bits 11-6&lt;br /&gt;
            Y3 = bits 5-0&lt;br /&gt;
          fill luminance samples according to Y0..Y3 and gradient fill &lt;br /&gt;
            pattern C (see section Gradient Fill Patterns)&lt;br /&gt;
 &lt;br /&gt;
      coding mode 3:&lt;br /&gt;
        flexible coding mode that can paint the luminance samples with an &lt;br /&gt;
          arbitrary pattern using two samples and a set of flags coded in the &lt;br /&gt;
          stream, or with a gradient fill pattern and four samples coded in the &lt;br /&gt;
          stream, or with 16 samples coded in the stream&lt;br /&gt;
        if mode is 0&lt;br /&gt;
          if bit 7 of b1 is 0&lt;br /&gt;
            flagsA = b1&lt;br /&gt;
            flagsB = next byte in the stream&lt;br /&gt;
            Y0 = next byte in stream &amp;amp; 0x3F&lt;br /&gt;
            Y1 = next byte in stream &amp;amp; 0x3F&lt;br /&gt;
            the 16 bits between flagsA and flagsB represent the pattern &lt;br /&gt;
              used to place either Y0 or Y1 into the luminance grid&lt;br /&gt;
 &lt;br /&gt;
              A7 A6 A5 A4&lt;br /&gt;
              A3 A2 A1 A0&lt;br /&gt;
              B7 B6 B5 B4&lt;br /&gt;
              B3 B2 B1 B0&lt;br /&gt;
 &lt;br /&gt;
              for example, if bit 3 of flagsB is 1, Y1 would be used in &lt;br /&gt;
              the lower left corner of the quadrant, else Y0&lt;br /&gt;
          else&lt;br /&gt;
            gradient fill pattern = bits 6-4 of b1&lt;br /&gt;
            get the next byte in the stream (b2)&lt;br /&gt;
            Y0 = ((b1 &amp;amp; 0x0F) &amp;lt;&amp;lt; 2) | (b2 &amp;gt;&amp;gt; 6)&lt;br /&gt;
            Y1 = bits 5-0 of b2&lt;br /&gt;
            Y2 = next byte in stream &amp;amp; 0x3F&lt;br /&gt;
            Y3 = next byte in stream &amp;amp; 0x3F&lt;br /&gt;
            fill luminance samples according to Y0..Y3 and the gradient &lt;br /&gt;
              fill pattern (see section Gradient Fill Patterns)&lt;br /&gt;
        else (mode is non-zero)&lt;br /&gt;
          get the next 12 bytes from the stream as 16 6-bit numbers as the 16 &lt;br /&gt;
            luminance samples (Y0..Y15) for the quadrant&lt;br /&gt;
          fill luminance samples according to Y0..Y15 and gradient fill &lt;br /&gt;
            pattern D (see section Gradient Fill Patterns)&lt;br /&gt;
 &lt;br /&gt;
      finally, output quadrant:&lt;br /&gt;
        bits 7-4 of the chrominance byte represent the Cr (or V) component&lt;br /&gt;
          while bits 3-0 represent the Cb (U) component&lt;br /&gt;
        convert the 16 luminance values and the 2 chrominance values to a &lt;br /&gt;
          proper YUV colorspace using the conversion tables in Appendix A&lt;br /&gt;
 &lt;br /&gt;
  if uniq flag is -1&lt;br /&gt;
    uniq flag = 0&lt;br /&gt;
&lt;br /&gt;
== Gradient Fill Patterns ==&lt;br /&gt;
&lt;br /&gt;
The ULTI codec has 12 gradient fill patterns for painting 4x4 sub blocks of luminance data using 4 (or 16) luminance samples.&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 0: (0 degrees)&lt;br /&gt;
  Y0 Y1 Y2 Y3&lt;br /&gt;
  Y0 Y1 Y2 Y3&lt;br /&gt;
  Y0 Y1 Y2 Y3&lt;br /&gt;
  Y0 Y1 Y2 Y3&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 1: (22.5 degrees)&lt;br /&gt;
  Y1 Y2 Y3 Y3&lt;br /&gt;
  Y0 Y1 Y2 Y3&lt;br /&gt;
  Y0 Y1 Y2 Y3&lt;br /&gt;
  Y0 Y0 Y1 Y2&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 2: (45 degrees)&lt;br /&gt;
  Y1 Y2 Y3 Y3&lt;br /&gt;
  Y1 Y2 Y2 Y3&lt;br /&gt;
  Y0 Y1 Y1 Y2&lt;br /&gt;
  Y0 Y0 Y1 Y2&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 3: (67.5 degrees)&lt;br /&gt;
  Y2 Y3 Y3 Y3&lt;br /&gt;
  Y1 Y2 Y2 Y3&lt;br /&gt;
  Y0 Y1 Y1 Y2&lt;br /&gt;
  Y0 Y0 Y0 Y1&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 4: (90 degrees)&lt;br /&gt;
  Y3 Y3 Y3 Y3&lt;br /&gt;
  Y2 Y2 Y2 Y2&lt;br /&gt;
  Y1 Y1 Y1 Y1&lt;br /&gt;
  Y0 Y0 Y0 Y0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 5: (112.5 degrees)&lt;br /&gt;
  Y3 Y3 Y3 Y2&lt;br /&gt;
  Y3 Y2 Y2 Y1&lt;br /&gt;
  Y2 Y1 Y1 Y0&lt;br /&gt;
  Y1 Y0 Y0 Y0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 6: (135 degrees)&lt;br /&gt;
  Y3 Y3 Y2 Y2&lt;br /&gt;
  Y3 Y2 Y1 Y1&lt;br /&gt;
  Y2 Y2 Y1 Y0&lt;br /&gt;
  Y1 Y1 Y0 Y0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 7: (157.5 degrees)&lt;br /&gt;
  Y3 Y3 Y2 Y1&lt;br /&gt;
  Y3 Y2 Y1 Y0&lt;br /&gt;
  Y3 Y2 Y1 Y0&lt;br /&gt;
  Y2 Y1 Y0 Y0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern A: (homogeneous)&lt;br /&gt;
  Y0 Y0 Y0 Y0&lt;br /&gt;
  Y0 Y0 Y0 Y0&lt;br /&gt;
  Y0 Y0 Y0 Y0&lt;br /&gt;
  Y0 Y0 Y0 Y0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern B: (270 degrees)&lt;br /&gt;
  Y0 Y0 Y0 Y0&lt;br /&gt;
  Y1 Y1 Y1 Y1&lt;br /&gt;
  Y2 Y2 Y2 Y2&lt;br /&gt;
  Y3 Y3 Y3 Y3&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern C: (subsampled)&lt;br /&gt;
  Y0 Y0 Y1 Y1&lt;br /&gt;
  Y0 Y0 Y1 Y1&lt;br /&gt;
  Y2 Y2 Y3 Y3&lt;br /&gt;
  Y2 Y2 Y3 Y3&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern D: (16 samples)&lt;br /&gt;
  Y0  Y1  Y2  Y3&lt;br /&gt;
  Y4  Y5  Y6  Y7&lt;br /&gt;
  Y8  Y9  Y10 Y11&lt;br /&gt;
  Y12 Y13 Y14 Y15&lt;br /&gt;
&lt;br /&gt;
== Luminance Codebook Enumeration ==&lt;br /&gt;
&lt;br /&gt;
The following pseudo-code creates the Ultimotion Luminance Transition Coding codebook&lt;br /&gt;
&lt;br /&gt;
 i = 0&lt;br /&gt;
 for Y0 = 0 to 61&lt;br /&gt;
   for Y3 = Y0 + 2 to 63&lt;br /&gt;
     Yd = Y3 - Y0&lt;br /&gt;
     if Yd in (2,3,5,6,7,8,11,14,17,20)&lt;br /&gt;
       LTC[i++] = (Y0, Y0 + Yd/3, Y3 - Yd/3, Y3)&lt;br /&gt;
     endif&lt;br /&gt;
     if Yd in (4,5,6,7,8,11,14,17,20,23,26,29,32,36)&lt;br /&gt;
       LTC[i++] = (Y0, Y0 + Yd/2, Y3 - Yd/4, Y3)&lt;br /&gt;
       LTC[i++] = (Y0, Y0 + Yd/4, Y3 - Yd/4, Y3)&lt;br /&gt;
       LTC[i++] = (Y0, Y0 + Yd/4, Y3 - Yd/2, Y3)&lt;br /&gt;
     endif&lt;br /&gt;
     if Yd in (6,8,11,14,17,20,23,26,29,32,35,40,46)&lt;br /&gt;
       LTC[i++] = (Y0, Y3, Y3, Y3)&lt;br /&gt;
       LTC[i++] = (Y0, Y0, Y3, Y3)&lt;br /&gt;
       LTC[i++] = (Y0, Y0, Y0, Y3)&lt;br /&gt;
     endif&lt;br /&gt;
   next Y3&lt;br /&gt;
 next Y0&lt;br /&gt;
&lt;br /&gt;
It should be noted there is an error in the &amp;quot;Ultimotion Digital Video Data Stream Specification&amp;quot; - the pre-determined linear transitions are for Y deltas of 2, 3, 5, 6, 7, 8, 11, 14, 17, 20 (not 4). (If 4 is included then there are 4156 transitions. The various transitions are handled by the low contrast edge transitions.) &lt;br /&gt;
&lt;br /&gt;
== Converting Ultimotion Scaled YUV To Correct YUV ==&lt;br /&gt;
&lt;br /&gt;
To convert Ultimotion 6-bit luminance values to proper luminance samples, use the following conversion table:&lt;br /&gt;
&lt;br /&gt;
 unsigned char ulti_lumas[64] =&lt;br /&gt;
    { 0x10, 0x13, 0x17, 0x1A, 0x1E, 0x21, 0x25, 0x28,&lt;br /&gt;
      0x2C, 0x2F, 0x33, 0x36, 0x3A, 0x3D, 0x41, 0x44,&lt;br /&gt;
      0x48, 0x4B, 0x4F, 0x52, 0x56, 0x59, 0x5C, 0x60,&lt;br /&gt;
      0x63, 0x67, 0x6A, 0x6E, 0x71, 0x75, 0x78, 0x7C,&lt;br /&gt;
      0x7F, 0x83, 0x86, 0x8A, 0x8D, 0x91, 0x94, 0x98,&lt;br /&gt;
      0x9B, 0x9F, 0xA2, 0xA5, 0xA9, 0xAC, 0xB0, 0xB3,&lt;br /&gt;
      0xB7, 0xBA, 0xBE, 0xC1, 0xC5, 0xC8, 0xCC, 0xCF,&lt;br /&gt;
      0xD3, 0xD6, 0xDA, 0xDD, 0xE1, 0xE4, 0xE8, 0xEB};&lt;br /&gt;
      &lt;br /&gt;
To convert Ultimotion 4-bit chrominance values to proper chrominance samples, use the following conversion table:&lt;br /&gt;
&lt;br /&gt;
 unsigned char ulti_chromas[16] =&lt;br /&gt;
    { 0x60, 0x67, 0x6D, 0x73, 0x7A, 0x80, 0x86, 0x8D,&lt;br /&gt;
      0x93, 0x99, 0xA0, 0xA6, 0xAC, 0xB3, 0xB9, 0xC0};&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* [http://xanim.polter.net/ XAnim]&lt;br /&gt;
&lt;br /&gt;
* [http://mplayerhq.hu/cgi-bin/cvsweb.cgi/~checkout~/ffmpeg/libavcodec/ulti_cb.h?content-type=text/x-cvsweb-markup&amp;amp;cvsroot=FFMpeg Ultimotion Luminance Codebook]&lt;br /&gt;
&lt;br /&gt;
[[Category:Video Codecs]]&lt;/div&gt;</summary>
		<author><name>Ultimotion</name></author>
	</entry>
	<entry>
		<id>https://wiki.multimedia.cx/index.php?title=IBM_UltiMotion&amp;diff=6244</id>
		<title>IBM UltiMotion</title>
		<link rel="alternate" type="text/html" href="https://wiki.multimedia.cx/index.php?title=IBM_UltiMotion&amp;diff=6244"/>
		<updated>2006-10-12T20:33:36Z</updated>

		<summary type="html">&lt;p&gt;Ultimotion: /* Luminance Codebook Enumeration */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* FourCC: ULTI&lt;br /&gt;
* Company: [[IBM]]&lt;br /&gt;
* Official Description: [http://multimedia.cx/UMSPEC.ZIP Ultimotion Digital Video Data Stream Specification]&lt;br /&gt;
* Additional Documentation: [http://multimedia.cx/ultimotion-format.txt 'Description of the IBM UltiMotion (ULTI) Video Codec' by Mike Melanson and Konstantin Shishkov ].''&lt;br /&gt;
* Samples: [http://samples.mplayerhq.hu/V-codecs/ULTI/ http://samples.mplayerhq.hu/V-codecs/ULTI/]&lt;br /&gt;
* Codec: [http://hobbes.nmsu.edu/cgi-bin/h-viewer?sh=1&amp;amp;fname=/pub/windows/ultimo.zip Win32 Ultimotion decoder]&lt;br /&gt;
&lt;br /&gt;
IBM Ultimotion is a video codec typically seen in [[AVI]] files, though there is no reason it could not be used in other container formats.  Full codecs were available for Windows 3.1 (VfW), OS/2 and AIX.  It is primarily a vector quantizing algorithm with simple inter-frame coding (unchanged block).  Ultimotion encoding is significantly more computationally intensive than decoding.&lt;br /&gt;
&lt;br /&gt;
== Decoding Algorithm ==&lt;br /&gt;
&lt;br /&gt;
The Ultimotion algorithm operates natively on a scaled-down [[Raw YUV|YUV]] 4:1:0 planar colorspace. This means that for each 4x4 block of pixels (quadrant), each of the 16 pixels has a luminance (Y) sample and the entire block shares one chrominance sample (expressed as two color difference components : C&amp;lt;sub&amp;gt;b&amp;lt;/sub&amp;gt; (or U) and C&amp;lt;sub&amp;gt;r&amp;lt;/sub&amp;gt; (or V). The colorspace is actually non-linear quantized to fixed values from 2 tables. Indices into these tables (64 possible values for luminance and 16 for each chrominance component) are transmitted in the final bitstream.&lt;br /&gt;
&lt;br /&gt;
The Ultimotion algorithm codes a frame by dividing it into a series of 8x8 blocks. Each 8x8 block is subdivided and coded as 4 4x4 quadrants. The 4 quadrants, 0-3, are coded in the following arrangement:&lt;br /&gt;
&lt;br /&gt;
  0 3&lt;br /&gt;
  1 2&lt;br /&gt;
&lt;br /&gt;
Each block can be encoded using a single chrominance sample or unique chrominance sample for each quadrant. Each quadrant has 16 luminance samples that can be coded using a variety of methods.&lt;br /&gt;
&lt;br /&gt;
To decode a frame of Ultimotion data, follow this process:&lt;br /&gt;
&lt;br /&gt;
 initialize uniq and mode flags to 0&lt;br /&gt;
 &lt;br /&gt;
 for each 8x8 block in the frame, iterating from left -&amp;gt; right, top -&amp;gt; bottom:&lt;br /&gt;
 &lt;br /&gt;
  get the next byte in the stream (b0)&lt;br /&gt;
  if (b0 &amp;amp; 0xF8) == 0x70, handle escape code:&lt;br /&gt;
    if b0 is 0x70&lt;br /&gt;
      mode = next byte in stream&lt;br /&gt;
      note: only mode values of 0 or 1 are valid&lt;br /&gt;
    if b0 is 0x71&lt;br /&gt;
      uniq flag = -1 &lt;br /&gt;
    if b0 is 0x72&lt;br /&gt;
      toggle uniq flag (0/1)&lt;br /&gt;
    if b0 is 0x73&lt;br /&gt;
      end of frame, stop decoding&lt;br /&gt;
    if b0 is 0x74&lt;br /&gt;
      get the next byte in stream (b1)&lt;br /&gt;
      skip next (b1) blocks in the output frame (unchanged from previous frame)&lt;br /&gt;
 &lt;br /&gt;
  else&lt;br /&gt;
    if b0 is non-zero and uniq flag is 0&lt;br /&gt;
      chrominance byte = next byte from stream&lt;br /&gt;
 &lt;br /&gt;
    for each 4x4 quadrant in the block, arranged in the quadrant pattern:&lt;br /&gt;
 &lt;br /&gt;
      extract quadrant coding mode from b0:&lt;br /&gt;
        bits 7-6: quadrant 0 coding mode&lt;br /&gt;
        bits 5-4: quadrant 1 coding mode&lt;br /&gt;
        bits 3-2: quadrant 2 coding mode&lt;br /&gt;
        bits 1-0: quadrant 3 coding mode&lt;br /&gt;
 &lt;br /&gt;
      if coding mode is non-zero and uniq flag is non-zero&lt;br /&gt;
        chrominance byte = next byte from stream&lt;br /&gt;
 &lt;br /&gt;
      coding mode 0:&lt;br /&gt;
        skip quadrant (unchanged from the previous frame)&lt;br /&gt;
 &lt;br /&gt;
      coding mode 1:&lt;br /&gt;
        paint the luminance samples using a gradient pattern based on one &lt;br /&gt;
          sample coded in the stream&lt;br /&gt;
 &lt;br /&gt;
        get next byte from stream (b1)&lt;br /&gt;
        bits 7-6 of b1 indicate gradient fill pattern:&lt;br /&gt;
          0 = gradient fill pattern A&lt;br /&gt;
          1 = gradient fill pattern 2&lt;br /&gt;
          2 = gradient fill pattern 6&lt;br /&gt;
          3 = gradient fill pattern B&lt;br /&gt;
        bits 5-0 of b1 indicate luminance sample Y0&lt;br /&gt;
          Y1 = Y0, Y2 = Y0 + 1, Y3 = Y0 + 1&lt;br /&gt;
        fill luminance samples according to Y0..Y3 and the gradient fill &lt;br /&gt;
          pattern (see section Gradient Fill Patterns)&lt;br /&gt;
 &lt;br /&gt;
      coding mode 2:&lt;br /&gt;
        paint the luminance samples using a gradient pattern based on either &lt;br /&gt;
          four samples retrieved from a 4,096-entry codebook using an index&lt;br /&gt;
          coded in the stream or four samples coded in the stream &lt;br /&gt;
        if mode is 0&lt;br /&gt;
          get the next 2 bytes from the stream as a big endian 16-bit &lt;br /&gt;
            number:&lt;br /&gt;
          gradient fill pattern = bits 15-12&lt;br /&gt;
          luminance codebook index = bits 11-0&lt;br /&gt;
          Y0..Y3 are set according to the codebook entry (see References &lt;br /&gt;
            for Ultimotion luminance codebook)&lt;br /&gt;
          if bit 3 of the gradient fill pattern is set&lt;br /&gt;
            swap Y0 with Y3 and Y1 with Y2&lt;br /&gt;
            clear bit 3 of the gradient fill pattern&lt;br /&gt;
          fill luminance samples according to Y0..Y3 and the gradient fill &lt;br /&gt;
            pattern (see section Gradient Fill Patterns)&lt;br /&gt;
        else (mode is non-zero)&lt;br /&gt;
          get the next 3 bytes from the stream as a big endian 24-bit number:&lt;br /&gt;
            Y0 = bits 23-18&lt;br /&gt;
            Y1 = bits 17-12&lt;br /&gt;
            Y2 = bits 11-6&lt;br /&gt;
            Y3 = bits 5-0&lt;br /&gt;
          fill luminance samples according to Y0..Y3 and gradient fill &lt;br /&gt;
            pattern C (see section Gradient Fill Patterns)&lt;br /&gt;
 &lt;br /&gt;
      coding mode 3:&lt;br /&gt;
        flexible coding mode that can paint the luminance samples with an &lt;br /&gt;
          arbitrary pattern using two samples and a set of flags coded in the &lt;br /&gt;
          stream, or with a gradient fill pattern and four samples coded in the &lt;br /&gt;
          stream, or with 16 samples coded in the stream&lt;br /&gt;
        if mode is 0&lt;br /&gt;
          if bit 7 of b1 is 0&lt;br /&gt;
            flagsA = b1&lt;br /&gt;
            flagsB = next byte in the stream&lt;br /&gt;
            Y0 = next byte in stream &amp;amp; 0x3F&lt;br /&gt;
            Y1 = next byte in stream &amp;amp; 0x3F&lt;br /&gt;
            the 16 bits between flagsA and flagsB represent the pattern &lt;br /&gt;
              used to place either Y0 or Y1 into the luminance grid&lt;br /&gt;
 &lt;br /&gt;
              A7 A6 A5 A4&lt;br /&gt;
              A3 A2 A1 A0&lt;br /&gt;
              B7 B6 B5 B4&lt;br /&gt;
              B3 B2 B1 B0&lt;br /&gt;
 &lt;br /&gt;
              for example, if bit 3 of flagsB is 1, Y1 would be used in &lt;br /&gt;
              the lower left corner of the quadrant, else Y0&lt;br /&gt;
          else&lt;br /&gt;
            gradient fill pattern = bits 6-4 of b1&lt;br /&gt;
            get the next byte in the stream (b2)&lt;br /&gt;
            Y0 = ((b1 &amp;amp; 0x0F) &amp;lt;&amp;lt; 2) | (b2 &amp;gt;&amp;gt; 6)&lt;br /&gt;
            Y1 = bits 5-0 of b2&lt;br /&gt;
            Y2 = next byte in stream &amp;amp; 0x3F&lt;br /&gt;
            Y3 = next byte in stream &amp;amp; 0x3F&lt;br /&gt;
            fill luminance samples according to Y0..Y3 and the gradient &lt;br /&gt;
              fill pattern (see section Gradient Fill Patterns)&lt;br /&gt;
        else (mode is non-zero)&lt;br /&gt;
          get the next 12 bytes from the stream as 16 6-bit numbers as the 16 &lt;br /&gt;
            luminance samples (Y0..Y15) for the quadrant&lt;br /&gt;
          fill luminance samples according to Y0..Y15 and gradient fill &lt;br /&gt;
            pattern D (see section Gradient Fill Patterns)&lt;br /&gt;
 &lt;br /&gt;
      finally, output quadrant:&lt;br /&gt;
        bits 7-4 of the chrominance byte represent the Cr (or V) component&lt;br /&gt;
          while bits 3-0 represent the Cb (U) component&lt;br /&gt;
        convert the 16 luminance values and the 2 chrominance values to a &lt;br /&gt;
          proper YUV colorspace using the conversion tables in Appendix A&lt;br /&gt;
 &lt;br /&gt;
  if uniq flag is -1&lt;br /&gt;
    uniq flag = 0&lt;br /&gt;
&lt;br /&gt;
== Gradient Fill Patterns ==&lt;br /&gt;
&lt;br /&gt;
The ULTI codec has 12 gradient fill patterns for painting 4x4 sub blocks of luminance data using 4 (or 16) luminance samples.&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 0: (0 degrees)&lt;br /&gt;
  Y0 Y1 Y2 Y3&lt;br /&gt;
  Y0 Y1 Y2 Y3&lt;br /&gt;
  Y0 Y1 Y2 Y3&lt;br /&gt;
  Y0 Y1 Y2 Y3&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 1: (22.5 degrees)&lt;br /&gt;
  Y1 Y2 Y3 Y3&lt;br /&gt;
  Y0 Y1 Y2 Y3&lt;br /&gt;
  Y0 Y1 Y2 Y3&lt;br /&gt;
  Y0 Y0 Y1 Y2&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 2: (45 degrees)&lt;br /&gt;
  Y1 Y2 Y3 Y3&lt;br /&gt;
  Y1 Y2 Y2 Y3&lt;br /&gt;
  Y0 Y1 Y1 Y2&lt;br /&gt;
  Y0 Y0 Y1 Y2&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 3: (67.5 degrees)&lt;br /&gt;
  Y2 Y3 Y3 Y3&lt;br /&gt;
  Y1 Y2 Y2 Y3&lt;br /&gt;
  Y0 Y1 Y1 Y2&lt;br /&gt;
  Y0 Y0 Y0 Y1&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 4: (90 degrees)&lt;br /&gt;
  Y3 Y3 Y3 Y3&lt;br /&gt;
  Y2 Y2 Y2 Y2&lt;br /&gt;
  Y1 Y1 Y1 Y1&lt;br /&gt;
  Y0 Y0 Y0 Y0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 5: (112.5 degrees)&lt;br /&gt;
  Y3 Y3 Y3 Y2&lt;br /&gt;
  Y3 Y2 Y2 Y1&lt;br /&gt;
  Y2 Y1 Y1 Y0&lt;br /&gt;
  Y1 Y0 Y0 Y0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 6: (135 degrees)&lt;br /&gt;
  Y3 Y3 Y2 Y2&lt;br /&gt;
  Y3 Y2 Y1 Y1&lt;br /&gt;
  Y2 Y2 Y1 Y0&lt;br /&gt;
  Y1 Y1 Y0 Y0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 7: (157.5 degrees)&lt;br /&gt;
  Y3 Y3 Y2 Y1&lt;br /&gt;
  Y3 Y2 Y1 Y0&lt;br /&gt;
  Y3 Y2 Y1 Y0&lt;br /&gt;
  Y2 Y1 Y0 Y0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern A: (homogeneous)&lt;br /&gt;
  Y0 Y0 Y0 Y0&lt;br /&gt;
  Y0 Y0 Y0 Y0&lt;br /&gt;
  Y0 Y0 Y0 Y0&lt;br /&gt;
  Y0 Y0 Y0 Y0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern B: (270 degrees)&lt;br /&gt;
  Y0 Y0 Y0 Y0&lt;br /&gt;
  Y1 Y1 Y1 Y1&lt;br /&gt;
  Y2 Y2 Y2 Y2&lt;br /&gt;
  Y3 Y3 Y3 Y3&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern C: (subsampled)&lt;br /&gt;
  Y0 Y0 Y1 Y1&lt;br /&gt;
  Y0 Y0 Y1 Y1&lt;br /&gt;
  Y2 Y2 Y3 Y3&lt;br /&gt;
  Y2 Y2 Y3 Y3&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern D: (16 samples)&lt;br /&gt;
  Y0  Y1  Y2  Y3&lt;br /&gt;
  Y4  Y5  Y6  Y7&lt;br /&gt;
  Y8  Y9  Y10 Y11&lt;br /&gt;
  Y12 Y13 Y14 Y15&lt;br /&gt;
&lt;br /&gt;
== Luminance Codebook Enumeration ==&lt;br /&gt;
&lt;br /&gt;
The following pseudo-code creates the Ultimotion Luminance Transition Coding codebook&lt;br /&gt;
&lt;br /&gt;
 i = 0&lt;br /&gt;
 for Y0 = 0 to 61&lt;br /&gt;
   for Y3 = Y0 + 2 to 63&lt;br /&gt;
     Yd = Y3 - Y0&lt;br /&gt;
     if Yd in (2,3,5,6,7,8,11,14,17,20)&lt;br /&gt;
       LTC[i++] = (Y0, Y0 + Yd/3, Y3 - Yd/3, Y3)&lt;br /&gt;
     endif&lt;br /&gt;
     if Yd in (4,5,6,7,8,11,14,17,20,23,26,29,32,36)&lt;br /&gt;
       LTC[i++] = (Y0, Y0 + Yd/2, Y3 - Yd/4, Y3)&lt;br /&gt;
       LTC[i++] = (Y0, Y0 + Yd/4, Y3 - Yd/4, Y3)&lt;br /&gt;
       LTC[i++] = (Y0, Y0 + Yd/4, Y3 - Yd/2, Y3)&lt;br /&gt;
     endif&lt;br /&gt;
     if Yd in (6,8,11,14,17,20,23,26,29,32,35,40,46)&lt;br /&gt;
       LTC[i++] = (Y0, Y3, Y3, Y3)&lt;br /&gt;
       LTC[i++] = (Y0, Y0, Y3, Y3)&lt;br /&gt;
       LTC[i++] = (Y0, Y0, Y0, Y3)&lt;br /&gt;
     endif&lt;br /&gt;
   next Y3&lt;br /&gt;
 next Y0&lt;br /&gt;
&lt;br /&gt;
It should be noted there is an error in the &amp;quot;Ultimotion Digital Video Data Stream Specification&amp;quot; - the pre-determined linear transitions are for Y deltas of 2, 3, 5, 6, 7, 8, 11, 14, 17, 20 (not 4). (If 4 is included then there are 4156 transitions. The various transitions are handled by the low contrast edge transitions.) &lt;br /&gt;
&lt;br /&gt;
== Converting Ultimotion Scaled YUV To Correct YUV ==&lt;br /&gt;
&lt;br /&gt;
To convert Ultimotion 6-bit luminance values to proper luminance samples, use the following conversion table:&lt;br /&gt;
&lt;br /&gt;
 unsigned char ulti_lumas[64] =&lt;br /&gt;
    { 0x10, 0x13, 0x17, 0x1A, 0x1E, 0x21, 0x25, 0x28,&lt;br /&gt;
      0x2C, 0x2F, 0x33, 0x36, 0x3A, 0x3D, 0x41, 0x44,&lt;br /&gt;
      0x48, 0x4B, 0x4F, 0x52, 0x56, 0x59, 0x5C, 0x60,&lt;br /&gt;
      0x63, 0x67, 0x6A, 0x6E, 0x71, 0x75, 0x78, 0x7C,&lt;br /&gt;
      0x7F, 0x83, 0x86, 0x8A, 0x8D, 0x91, 0x94, 0x98,&lt;br /&gt;
      0x9B, 0x9F, 0xA2, 0xA5, 0xA9, 0xAC, 0xB0, 0xB3,&lt;br /&gt;
      0xB7, 0xBA, 0xBE, 0xC1, 0xC5, 0xC8, 0xCC, 0xCF,&lt;br /&gt;
      0xD3, 0xD6, 0xDA, 0xDD, 0xE1, 0xE4, 0xE8, 0xEB};&lt;br /&gt;
      &lt;br /&gt;
To convert Ultimotion 4-bit chrominance values to proper chrominance samples, use the following conversion table:&lt;br /&gt;
&lt;br /&gt;
 unsigned char ulti_chromas[16] =&lt;br /&gt;
    { 0x60, 0x67, 0x6D, 0x73, 0x7A, 0x80, 0x86, 0x8D,&lt;br /&gt;
      0x93, 0x99, 0xA0, 0xA6, 0xAC, 0xB3, 0xB9, 0xC0};&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* [http://xanim.polter.net/ XAnim]&lt;br /&gt;
&lt;br /&gt;
* [http://mplayerhq.hu/cgi-bin/cvsweb.cgi/~checkout~/ffmpeg/libavcodec/ulti_cb.h?content-type=text/x-cvsweb-markup&amp;amp;cvsroot=FFMpeg Ultimotion Luminance Codebook]&lt;br /&gt;
&lt;br /&gt;
[[Category:Video Codecs]]&lt;/div&gt;</summary>
		<author><name>Ultimotion</name></author>
	</entry>
	<entry>
		<id>https://wiki.multimedia.cx/index.php?title=IBM_UltiMotion&amp;diff=6243</id>
		<title>IBM UltiMotion</title>
		<link rel="alternate" type="text/html" href="https://wiki.multimedia.cx/index.php?title=IBM_UltiMotion&amp;diff=6243"/>
		<updated>2006-10-12T20:17:29Z</updated>

		<summary type="html">&lt;p&gt;Ultimotion: /* Decoding Algorithm */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* FourCC: ULTI&lt;br /&gt;
* Company: [[IBM]]&lt;br /&gt;
* Official Description: [http://multimedia.cx/UMSPEC.ZIP Ultimotion Digital Video Data Stream Specification]&lt;br /&gt;
* Additional Documentation: [http://multimedia.cx/ultimotion-format.txt 'Description of the IBM UltiMotion (ULTI) Video Codec' by Mike Melanson and Konstantin Shishkov ].''&lt;br /&gt;
* Samples: [http://samples.mplayerhq.hu/V-codecs/ULTI/ http://samples.mplayerhq.hu/V-codecs/ULTI/]&lt;br /&gt;
* Codec: [http://hobbes.nmsu.edu/cgi-bin/h-viewer?sh=1&amp;amp;fname=/pub/windows/ultimo.zip Win32 Ultimotion decoder]&lt;br /&gt;
&lt;br /&gt;
IBM Ultimotion is a video codec typically seen in [[AVI]] files, though there is no reason it could not be used in other container formats.  Full codecs were available for Windows 3.1 (VfW), OS/2 and AIX.  It is primarily a vector quantizing algorithm with simple inter-frame coding (unchanged block).  Ultimotion encoding is significantly more computationally intensive than decoding.&lt;br /&gt;
&lt;br /&gt;
== Decoding Algorithm ==&lt;br /&gt;
&lt;br /&gt;
The Ultimotion algorithm operates natively on a scaled-down [[Raw YUV|YUV]] 4:1:0 planar colorspace. This means that for each 4x4 block of pixels (quadrant), each of the 16 pixels has a luminance (Y) sample and the entire block shares one chrominance sample (expressed as two color difference components : C&amp;lt;sub&amp;gt;b&amp;lt;/sub&amp;gt; (or U) and C&amp;lt;sub&amp;gt;r&amp;lt;/sub&amp;gt; (or V). The colorspace is actually non-linear quantized to fixed values from 2 tables. Indices into these tables (64 possible values for luminance and 16 for each chrominance component) are transmitted in the final bitstream.&lt;br /&gt;
&lt;br /&gt;
The Ultimotion algorithm codes a frame by dividing it into a series of 8x8 blocks. Each 8x8 block is subdivided and coded as 4 4x4 quadrants. The 4 quadrants, 0-3, are coded in the following arrangement:&lt;br /&gt;
&lt;br /&gt;
  0 3&lt;br /&gt;
  1 2&lt;br /&gt;
&lt;br /&gt;
Each block can be encoded using a single chrominance sample or unique chrominance sample for each quadrant. Each quadrant has 16 luminance samples that can be coded using a variety of methods.&lt;br /&gt;
&lt;br /&gt;
To decode a frame of Ultimotion data, follow this process:&lt;br /&gt;
&lt;br /&gt;
 initialize uniq and mode flags to 0&lt;br /&gt;
 &lt;br /&gt;
 for each 8x8 block in the frame, iterating from left -&amp;gt; right, top -&amp;gt; bottom:&lt;br /&gt;
 &lt;br /&gt;
  get the next byte in the stream (b0)&lt;br /&gt;
  if (b0 &amp;amp; 0xF8) == 0x70, handle escape code:&lt;br /&gt;
    if b0 is 0x70&lt;br /&gt;
      mode = next byte in stream&lt;br /&gt;
      note: only mode values of 0 or 1 are valid&lt;br /&gt;
    if b0 is 0x71&lt;br /&gt;
      uniq flag = -1 &lt;br /&gt;
    if b0 is 0x72&lt;br /&gt;
      toggle uniq flag (0/1)&lt;br /&gt;
    if b0 is 0x73&lt;br /&gt;
      end of frame, stop decoding&lt;br /&gt;
    if b0 is 0x74&lt;br /&gt;
      get the next byte in stream (b1)&lt;br /&gt;
      skip next (b1) blocks in the output frame (unchanged from previous frame)&lt;br /&gt;
 &lt;br /&gt;
  else&lt;br /&gt;
    if b0 is non-zero and uniq flag is 0&lt;br /&gt;
      chrominance byte = next byte from stream&lt;br /&gt;
 &lt;br /&gt;
    for each 4x4 quadrant in the block, arranged in the quadrant pattern:&lt;br /&gt;
 &lt;br /&gt;
      extract quadrant coding mode from b0:&lt;br /&gt;
        bits 7-6: quadrant 0 coding mode&lt;br /&gt;
        bits 5-4: quadrant 1 coding mode&lt;br /&gt;
        bits 3-2: quadrant 2 coding mode&lt;br /&gt;
        bits 1-0: quadrant 3 coding mode&lt;br /&gt;
 &lt;br /&gt;
      if coding mode is non-zero and uniq flag is non-zero&lt;br /&gt;
        chrominance byte = next byte from stream&lt;br /&gt;
 &lt;br /&gt;
      coding mode 0:&lt;br /&gt;
        skip quadrant (unchanged from the previous frame)&lt;br /&gt;
 &lt;br /&gt;
      coding mode 1:&lt;br /&gt;
        paint the luminance samples using a gradient pattern based on one &lt;br /&gt;
          sample coded in the stream&lt;br /&gt;
 &lt;br /&gt;
        get next byte from stream (b1)&lt;br /&gt;
        bits 7-6 of b1 indicate gradient fill pattern:&lt;br /&gt;
          0 = gradient fill pattern A&lt;br /&gt;
          1 = gradient fill pattern 2&lt;br /&gt;
          2 = gradient fill pattern 6&lt;br /&gt;
          3 = gradient fill pattern B&lt;br /&gt;
        bits 5-0 of b1 indicate luminance sample Y0&lt;br /&gt;
          Y1 = Y0, Y2 = Y0 + 1, Y3 = Y0 + 1&lt;br /&gt;
        fill luminance samples according to Y0..Y3 and the gradient fill &lt;br /&gt;
          pattern (see section Gradient Fill Patterns)&lt;br /&gt;
 &lt;br /&gt;
      coding mode 2:&lt;br /&gt;
        paint the luminance samples using a gradient pattern based on either &lt;br /&gt;
          four samples retrieved from a 4,096-entry codebook using an index&lt;br /&gt;
          coded in the stream or four samples coded in the stream &lt;br /&gt;
        if mode is 0&lt;br /&gt;
          get the next 2 bytes from the stream as a big endian 16-bit &lt;br /&gt;
            number:&lt;br /&gt;
          gradient fill pattern = bits 15-12&lt;br /&gt;
          luminance codebook index = bits 11-0&lt;br /&gt;
          Y0..Y3 are set according to the codebook entry (see References &lt;br /&gt;
            for Ultimotion luminance codebook)&lt;br /&gt;
          if bit 3 of the gradient fill pattern is set&lt;br /&gt;
            swap Y0 with Y3 and Y1 with Y2&lt;br /&gt;
            clear bit 3 of the gradient fill pattern&lt;br /&gt;
          fill luminance samples according to Y0..Y3 and the gradient fill &lt;br /&gt;
            pattern (see section Gradient Fill Patterns)&lt;br /&gt;
        else (mode is non-zero)&lt;br /&gt;
          get the next 3 bytes from the stream as a big endian 24-bit number:&lt;br /&gt;
            Y0 = bits 23-18&lt;br /&gt;
            Y1 = bits 17-12&lt;br /&gt;
            Y2 = bits 11-6&lt;br /&gt;
            Y3 = bits 5-0&lt;br /&gt;
          fill luminance samples according to Y0..Y3 and gradient fill &lt;br /&gt;
            pattern C (see section Gradient Fill Patterns)&lt;br /&gt;
 &lt;br /&gt;
      coding mode 3:&lt;br /&gt;
        flexible coding mode that can paint the luminance samples with an &lt;br /&gt;
          arbitrary pattern using two samples and a set of flags coded in the &lt;br /&gt;
          stream, or with a gradient fill pattern and four samples coded in the &lt;br /&gt;
          stream, or with 16 samples coded in the stream&lt;br /&gt;
        if mode is 0&lt;br /&gt;
          if bit 7 of b1 is 0&lt;br /&gt;
            flagsA = b1&lt;br /&gt;
            flagsB = next byte in the stream&lt;br /&gt;
            Y0 = next byte in stream &amp;amp; 0x3F&lt;br /&gt;
            Y1 = next byte in stream &amp;amp; 0x3F&lt;br /&gt;
            the 16 bits between flagsA and flagsB represent the pattern &lt;br /&gt;
              used to place either Y0 or Y1 into the luminance grid&lt;br /&gt;
 &lt;br /&gt;
              A7 A6 A5 A4&lt;br /&gt;
              A3 A2 A1 A0&lt;br /&gt;
              B7 B6 B5 B4&lt;br /&gt;
              B3 B2 B1 B0&lt;br /&gt;
 &lt;br /&gt;
              for example, if bit 3 of flagsB is 1, Y1 would be used in &lt;br /&gt;
              the lower left corner of the quadrant, else Y0&lt;br /&gt;
          else&lt;br /&gt;
            gradient fill pattern = bits 6-4 of b1&lt;br /&gt;
            get the next byte in the stream (b2)&lt;br /&gt;
            Y0 = ((b1 &amp;amp; 0x0F) &amp;lt;&amp;lt; 2) | (b2 &amp;gt;&amp;gt; 6)&lt;br /&gt;
            Y1 = bits 5-0 of b2&lt;br /&gt;
            Y2 = next byte in stream &amp;amp; 0x3F&lt;br /&gt;
            Y3 = next byte in stream &amp;amp; 0x3F&lt;br /&gt;
            fill luminance samples according to Y0..Y3 and the gradient &lt;br /&gt;
              fill pattern (see section Gradient Fill Patterns)&lt;br /&gt;
        else (mode is non-zero)&lt;br /&gt;
          get the next 12 bytes from the stream as 16 6-bit numbers as the 16 &lt;br /&gt;
            luminance samples (Y0..Y15) for the quadrant&lt;br /&gt;
          fill luminance samples according to Y0..Y15 and gradient fill &lt;br /&gt;
            pattern D (see section Gradient Fill Patterns)&lt;br /&gt;
 &lt;br /&gt;
      finally, output quadrant:&lt;br /&gt;
        bits 7-4 of the chrominance byte represent the Cr (or V) component&lt;br /&gt;
          while bits 3-0 represent the Cb (U) component&lt;br /&gt;
        convert the 16 luminance values and the 2 chrominance values to a &lt;br /&gt;
          proper YUV colorspace using the conversion tables in Appendix A&lt;br /&gt;
 &lt;br /&gt;
  if uniq flag is -1&lt;br /&gt;
    uniq flag = 0&lt;br /&gt;
&lt;br /&gt;
== Gradient Fill Patterns ==&lt;br /&gt;
&lt;br /&gt;
The ULTI codec has 12 gradient fill patterns for painting 4x4 sub blocks of luminance data using 4 (or 16) luminance samples.&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 0: (0 degrees)&lt;br /&gt;
  Y0 Y1 Y2 Y3&lt;br /&gt;
  Y0 Y1 Y2 Y3&lt;br /&gt;
  Y0 Y1 Y2 Y3&lt;br /&gt;
  Y0 Y1 Y2 Y3&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 1: (22.5 degrees)&lt;br /&gt;
  Y1 Y2 Y3 Y3&lt;br /&gt;
  Y0 Y1 Y2 Y3&lt;br /&gt;
  Y0 Y1 Y2 Y3&lt;br /&gt;
  Y0 Y0 Y1 Y2&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 2: (45 degrees)&lt;br /&gt;
  Y1 Y2 Y3 Y3&lt;br /&gt;
  Y1 Y2 Y2 Y3&lt;br /&gt;
  Y0 Y1 Y1 Y2&lt;br /&gt;
  Y0 Y0 Y1 Y2&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 3: (67.5 degrees)&lt;br /&gt;
  Y2 Y3 Y3 Y3&lt;br /&gt;
  Y1 Y2 Y2 Y3&lt;br /&gt;
  Y0 Y1 Y1 Y2&lt;br /&gt;
  Y0 Y0 Y0 Y1&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 4: (90 degrees)&lt;br /&gt;
  Y3 Y3 Y3 Y3&lt;br /&gt;
  Y2 Y2 Y2 Y2&lt;br /&gt;
  Y1 Y1 Y1 Y1&lt;br /&gt;
  Y0 Y0 Y0 Y0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 5: (112.5 degrees)&lt;br /&gt;
  Y3 Y3 Y3 Y2&lt;br /&gt;
  Y3 Y2 Y2 Y1&lt;br /&gt;
  Y2 Y1 Y1 Y0&lt;br /&gt;
  Y1 Y0 Y0 Y0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 6: (135 degrees)&lt;br /&gt;
  Y3 Y3 Y2 Y2&lt;br /&gt;
  Y3 Y2 Y1 Y1&lt;br /&gt;
  Y2 Y2 Y1 Y0&lt;br /&gt;
  Y1 Y1 Y0 Y0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 7: (157.5 degrees)&lt;br /&gt;
  Y3 Y3 Y2 Y1&lt;br /&gt;
  Y3 Y2 Y1 Y0&lt;br /&gt;
  Y3 Y2 Y1 Y0&lt;br /&gt;
  Y2 Y1 Y0 Y0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern A: (homogeneous)&lt;br /&gt;
  Y0 Y0 Y0 Y0&lt;br /&gt;
  Y0 Y0 Y0 Y0&lt;br /&gt;
  Y0 Y0 Y0 Y0&lt;br /&gt;
  Y0 Y0 Y0 Y0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern B: (270 degrees)&lt;br /&gt;
  Y0 Y0 Y0 Y0&lt;br /&gt;
  Y1 Y1 Y1 Y1&lt;br /&gt;
  Y2 Y2 Y2 Y2&lt;br /&gt;
  Y3 Y3 Y3 Y3&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern C: (subsampled)&lt;br /&gt;
  Y0 Y0 Y1 Y1&lt;br /&gt;
  Y0 Y0 Y1 Y1&lt;br /&gt;
  Y2 Y2 Y3 Y3&lt;br /&gt;
  Y2 Y2 Y3 Y3&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern D: (16 samples)&lt;br /&gt;
  Y0  Y1  Y2  Y3&lt;br /&gt;
  Y4  Y5  Y6  Y7&lt;br /&gt;
  Y8  Y9  Y10 Y11&lt;br /&gt;
  Y12 Y13 Y14 Y15&lt;br /&gt;
&lt;br /&gt;
== Converting Ultimotion Scaled YUV To Correct YUV ==&lt;br /&gt;
&lt;br /&gt;
To convert Ultimotion 6-bit luminance values to proper luminance samples, use the following conversion table:&lt;br /&gt;
&lt;br /&gt;
 unsigned char ulti_lumas[64] =&lt;br /&gt;
    { 0x10, 0x13, 0x17, 0x1A, 0x1E, 0x21, 0x25, 0x28,&lt;br /&gt;
      0x2C, 0x2F, 0x33, 0x36, 0x3A, 0x3D, 0x41, 0x44,&lt;br /&gt;
      0x48, 0x4B, 0x4F, 0x52, 0x56, 0x59, 0x5C, 0x60,&lt;br /&gt;
      0x63, 0x67, 0x6A, 0x6E, 0x71, 0x75, 0x78, 0x7C,&lt;br /&gt;
      0x7F, 0x83, 0x86, 0x8A, 0x8D, 0x91, 0x94, 0x98,&lt;br /&gt;
      0x9B, 0x9F, 0xA2, 0xA5, 0xA9, 0xAC, 0xB0, 0xB3,&lt;br /&gt;
      0xB7, 0xBA, 0xBE, 0xC1, 0xC5, 0xC8, 0xCC, 0xCF,&lt;br /&gt;
      0xD3, 0xD6, 0xDA, 0xDD, 0xE1, 0xE4, 0xE8, 0xEB};&lt;br /&gt;
      &lt;br /&gt;
To convert Ultimotion 4-bit chrominance values to proper chrominance samples, use the following conversion table:&lt;br /&gt;
&lt;br /&gt;
 unsigned char ulti_chromas[16] =&lt;br /&gt;
    { 0x60, 0x67, 0x6D, 0x73, 0x7A, 0x80, 0x86, 0x8D,&lt;br /&gt;
      0x93, 0x99, 0xA0, 0xA6, 0xAC, 0xB3, 0xB9, 0xC0};&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* [http://xanim.polter.net/ XAnim]&lt;br /&gt;
&lt;br /&gt;
* [http://mplayerhq.hu/cgi-bin/cvsweb.cgi/~checkout~/ffmpeg/libavcodec/ulti_cb.h?content-type=text/x-cvsweb-markup&amp;amp;cvsroot=FFMpeg Ultimotion Luminance Codebook]&lt;br /&gt;
&lt;br /&gt;
[[Category:Video Codecs]]&lt;/div&gt;</summary>
		<author><name>Ultimotion</name></author>
	</entry>
	<entry>
		<id>https://wiki.multimedia.cx/index.php?title=IBM_UltiMotion&amp;diff=6242</id>
		<title>IBM UltiMotion</title>
		<link rel="alternate" type="text/html" href="https://wiki.multimedia.cx/index.php?title=IBM_UltiMotion&amp;diff=6242"/>
		<updated>2006-10-12T20:16:54Z</updated>

		<summary type="html">&lt;p&gt;Ultimotion: /* Gradient Fill Patterns */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* FourCC: ULTI&lt;br /&gt;
* Company: [[IBM]]&lt;br /&gt;
* Official Description: [http://multimedia.cx/UMSPEC.ZIP Ultimotion Digital Video Data Stream Specification]&lt;br /&gt;
* Additional Documentation: [http://multimedia.cx/ultimotion-format.txt 'Description of the IBM UltiMotion (ULTI) Video Codec' by Mike Melanson and Konstantin Shishkov ].''&lt;br /&gt;
* Samples: [http://samples.mplayerhq.hu/V-codecs/ULTI/ http://samples.mplayerhq.hu/V-codecs/ULTI/]&lt;br /&gt;
* Codec: [http://hobbes.nmsu.edu/cgi-bin/h-viewer?sh=1&amp;amp;fname=/pub/windows/ultimo.zip Win32 Ultimotion decoder]&lt;br /&gt;
&lt;br /&gt;
IBM Ultimotion is a video codec typically seen in [[AVI]] files, though there is no reason it could not be used in other container formats.  Full codecs were available for Windows 3.1 (VfW), OS/2 and AIX.  It is primarily a vector quantizing algorithm with simple inter-frame coding (unchanged block).  Ultimotion encoding is significantly more computationally intensive than decoding.&lt;br /&gt;
&lt;br /&gt;
== Decoding Algorithm ==&lt;br /&gt;
&lt;br /&gt;
The Ultimotion algorithm operates natively on a scaled-down [[Raw YUV|YUV]] 4:1:0 planar colorspace. This means that for each 4x4 block of pixels (quadrant), each of the 16 pixels has a luminance (Y) sample and the entire block shares one chrominance sample (expressed as two color difference components : C&amp;lt;sub&amp;gt;b&amp;lt;/sub&amp;gt; (or U) and C&amp;lt;sub&amp;gt;r&amp;lt;/sub&amp;gt; (or V). The colorspace is actually non-linear quantized to fixed values from 2 tables. Indices into these tables (64 possible values for luminance and 16 for each chrominance component) are transmitted in the final bitstream.&lt;br /&gt;
&lt;br /&gt;
The Ultimotion algorithm codes a frame by dividing it into a series of 8x8 blocks. Each 8x8 block is subdivided and coded as 4 4x4 quadrants. The 4 quadrants, 0-3, are coded in the following arrangement:&lt;br /&gt;
&lt;br /&gt;
  0 3&lt;br /&gt;
  1 2&lt;br /&gt;
&lt;br /&gt;
Each block can be encoded using a single chrominance sample or unique chrominance sample for each quadrant. Each quadrant has 16 luminance samples that can be coded using a variety of methods.&lt;br /&gt;
&lt;br /&gt;
To decode a frame of Ultimotion data, follow this process:&lt;br /&gt;
&lt;br /&gt;
 initialize uniq and mode flags to 0&lt;br /&gt;
 &lt;br /&gt;
 for each 8x8 block in the frame, iterating from left -&amp;gt; right, top -&amp;gt; bottom:&lt;br /&gt;
 &lt;br /&gt;
  get the next byte in the stream (b0)&lt;br /&gt;
  if (b0 &amp;amp; 0xF8) == 0x70, handle escape code:&lt;br /&gt;
    if b0 is 0x70&lt;br /&gt;
      mode = next byte in stream&lt;br /&gt;
      note: only mode values of 0 or 1 are valid&lt;br /&gt;
    if b0 is 0x71&lt;br /&gt;
      uniq flag = -1 &lt;br /&gt;
    if b0 is 0x72&lt;br /&gt;
      toggle uniq flag (0/1)&lt;br /&gt;
    if b0 is 0x73&lt;br /&gt;
      end of frame, stop decoding&lt;br /&gt;
    if b0 is 0x74&lt;br /&gt;
      get the next byte in stream (b1)&lt;br /&gt;
      skip next (b1) blocks in the output frame (unchanged from previous frame)&lt;br /&gt;
 &lt;br /&gt;
  else&lt;br /&gt;
    if b0 is non-zero and uniq flag is 0&lt;br /&gt;
      chrominance byte = next byte from stream&lt;br /&gt;
 &lt;br /&gt;
    for each 4x4 quadrant in the block, arranged in the quadrant pattern:&lt;br /&gt;
 &lt;br /&gt;
      extract quadrant coding mode from b0:&lt;br /&gt;
        bits 7-6: quadrant 0 coding mode&lt;br /&gt;
        bits 5-4: quadrant 1 coding mode&lt;br /&gt;
        bits 3-2: quadrant 2 coding mode&lt;br /&gt;
        bits 1-0: quadrant 3 coding mode&lt;br /&gt;
 &lt;br /&gt;
      if coding mode is non-zero and uniq flag is non-zero&lt;br /&gt;
        chrominance byte = next byte from stream&lt;br /&gt;
 &lt;br /&gt;
      coding mode 0:&lt;br /&gt;
        skip quadrant (unchanged from the previous frame)&lt;br /&gt;
 &lt;br /&gt;
      coding mode 1:&lt;br /&gt;
        paint the luminance samples using a gradient pattern based on one &lt;br /&gt;
          sample coded in the stream&lt;br /&gt;
 &lt;br /&gt;
        get next byte from stream (b1)&lt;br /&gt;
        bits 7-6 of b1 indicate gradient fill pattern:&lt;br /&gt;
          0 = gradient fill pattern A&lt;br /&gt;
          1 = gradient fill pattern 2&lt;br /&gt;
          2 = gradient fill pattern 6&lt;br /&gt;
          3 = gradient fill pattern B&lt;br /&gt;
        bits 5-0 of b1 indicate luminance sample Y0&lt;br /&gt;
          Y1 = Y0, Y2 = Y0 + 1, Y3 = Y0 + 1&lt;br /&gt;
        fill luminance samples according to Y0..Y3 and the gradient fill &lt;br /&gt;
          pattern (see section Gradient Fill Patterns)&lt;br /&gt;
 &lt;br /&gt;
      coding mode 2:&lt;br /&gt;
        paint the luminance samples using a gradient pattern based on either &lt;br /&gt;
          four samples retrieved from a 4,096-entry codebook using an index&lt;br /&gt;
          coded in the stream or four samples coded in the stream &lt;br /&gt;
        if mode is 0&lt;br /&gt;
          get the next 2 bytes from the stream as a big endian 16-bit &lt;br /&gt;
            number:&lt;br /&gt;
          gradient fill pattern = bits 15-12&lt;br /&gt;
          luminance codebook index = bits 11-0&lt;br /&gt;
          Y0..Y3 are set according to the codebook entry (see References &lt;br /&gt;
            for Ultimotion luminance codebook)&lt;br /&gt;
          if bit 3 of the gradient fill pattern is set&lt;br /&gt;
            swap Y0 with Y3 and Y1 with Y2&lt;br /&gt;
            clear bit 3 of the gradient fill pattern&lt;br /&gt;
          fill luminance samples according to Y0..Y3 and the gradient fill &lt;br /&gt;
            pattern (see section Gradient Fill Patterns)&lt;br /&gt;
        else (mode is non-zero)&lt;br /&gt;
          get the next 3 bytes from the stream as a big endian 24-bit number:&lt;br /&gt;
            Y0 = bits 23-18&lt;br /&gt;
            Y1 = bits 17-12&lt;br /&gt;
            Y2 = bits 11-6&lt;br /&gt;
            Y3 = bits 5-0&lt;br /&gt;
          fill luminance samples according to Y0..Y3 and gradient fill &lt;br /&gt;
            pattern C (see section Gradient Fill Patterns)&lt;br /&gt;
 &lt;br /&gt;
      coding mode 3:&lt;br /&gt;
        flexible coding mode that can paint the luminance samples with an &lt;br /&gt;
          arbitrary pattern using two samples and a set of flags coded in the &lt;br /&gt;
          stream, or with a gradient fill pattern and four samples coded in the &lt;br /&gt;
          stream, or with 16 samples coded in the stream&lt;br /&gt;
        if mode is 0&lt;br /&gt;
          if bit 7 of b1 is 0&lt;br /&gt;
            flagsA = b1&lt;br /&gt;
            flagsB = next byte in the stream&lt;br /&gt;
            Y0 = next byte in stream &amp;amp; 0x3F&lt;br /&gt;
            Y1 = next byte in stream &amp;amp; 0x3F&lt;br /&gt;
            the 16 bits between flagsA and flagsB represent the pattern &lt;br /&gt;
              used to place either Y0 or Y1 into the luminance grid&lt;br /&gt;
 &lt;br /&gt;
              A7 A6 A5 A4&lt;br /&gt;
              A3 A2 A1 A0&lt;br /&gt;
              B7 B6 B5 B4&lt;br /&gt;
              B3 B2 B1 B0&lt;br /&gt;
 &lt;br /&gt;
              for example, if bit 3 of flagsB is 1, Y1 would be used in &lt;br /&gt;
              the lower left corner of the quadrant, else Y0&lt;br /&gt;
          else&lt;br /&gt;
            gradient fill pattern = bits 6-4 of b1&lt;br /&gt;
            get the next byte in the stream (b2)&lt;br /&gt;
            Y0 = ((b1 &amp;amp; 0x0F) &amp;lt;&amp;lt; 2) | (b2 &amp;gt;&amp;gt; 6)&lt;br /&gt;
            Y1 = bits 5-0 of b2&lt;br /&gt;
            Y2 = next byte in stream &amp;amp; 0x3F&lt;br /&gt;
            Y3 = next byte in stream &amp;amp; 0x3F&lt;br /&gt;
            fill luminance samples according to Y0..Y3 and the gradient &lt;br /&gt;
              fill pattern (see section Gradient Fill Patterns)&lt;br /&gt;
        else (mode is non-zero)&lt;br /&gt;
          get the next 12 bytes from the stream as 16 6-bit numbers as the 16 &lt;br /&gt;
            luminance samples (Y0..Y16) for the quadrant&lt;br /&gt;
          fill luminance samples according to Y0..Y16 and gradient fill &lt;br /&gt;
            pattern D (see section Gradient Fill Patterns)&lt;br /&gt;
 &lt;br /&gt;
      finally, output quadrant:&lt;br /&gt;
        bits 7-4 of the chrominance byte represent the Cr (or V) component&lt;br /&gt;
          while bits 3-0 represent the Cb (U) component&lt;br /&gt;
        convert the 16 luminance values and the 2 chrominance values to a &lt;br /&gt;
          proper YUV colorspace using the conversion tables in Appendix A&lt;br /&gt;
 &lt;br /&gt;
  if uniq flag is -1&lt;br /&gt;
    uniq flag = 0&lt;br /&gt;
&lt;br /&gt;
== Gradient Fill Patterns ==&lt;br /&gt;
&lt;br /&gt;
The ULTI codec has 12 gradient fill patterns for painting 4x4 sub blocks of luminance data using 4 (or 16) luminance samples.&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 0: (0 degrees)&lt;br /&gt;
  Y0 Y1 Y2 Y3&lt;br /&gt;
  Y0 Y1 Y2 Y3&lt;br /&gt;
  Y0 Y1 Y2 Y3&lt;br /&gt;
  Y0 Y1 Y2 Y3&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 1: (22.5 degrees)&lt;br /&gt;
  Y1 Y2 Y3 Y3&lt;br /&gt;
  Y0 Y1 Y2 Y3&lt;br /&gt;
  Y0 Y1 Y2 Y3&lt;br /&gt;
  Y0 Y0 Y1 Y2&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 2: (45 degrees)&lt;br /&gt;
  Y1 Y2 Y3 Y3&lt;br /&gt;
  Y1 Y2 Y2 Y3&lt;br /&gt;
  Y0 Y1 Y1 Y2&lt;br /&gt;
  Y0 Y0 Y1 Y2&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 3: (67.5 degrees)&lt;br /&gt;
  Y2 Y3 Y3 Y3&lt;br /&gt;
  Y1 Y2 Y2 Y3&lt;br /&gt;
  Y0 Y1 Y1 Y2&lt;br /&gt;
  Y0 Y0 Y0 Y1&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 4: (90 degrees)&lt;br /&gt;
  Y3 Y3 Y3 Y3&lt;br /&gt;
  Y2 Y2 Y2 Y2&lt;br /&gt;
  Y1 Y1 Y1 Y1&lt;br /&gt;
  Y0 Y0 Y0 Y0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 5: (112.5 degrees)&lt;br /&gt;
  Y3 Y3 Y3 Y2&lt;br /&gt;
  Y3 Y2 Y2 Y1&lt;br /&gt;
  Y2 Y1 Y1 Y0&lt;br /&gt;
  Y1 Y0 Y0 Y0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 6: (135 degrees)&lt;br /&gt;
  Y3 Y3 Y2 Y2&lt;br /&gt;
  Y3 Y2 Y1 Y1&lt;br /&gt;
  Y2 Y2 Y1 Y0&lt;br /&gt;
  Y1 Y1 Y0 Y0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 7: (157.5 degrees)&lt;br /&gt;
  Y3 Y3 Y2 Y1&lt;br /&gt;
  Y3 Y2 Y1 Y0&lt;br /&gt;
  Y3 Y2 Y1 Y0&lt;br /&gt;
  Y2 Y1 Y0 Y0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern A: (homogeneous)&lt;br /&gt;
  Y0 Y0 Y0 Y0&lt;br /&gt;
  Y0 Y0 Y0 Y0&lt;br /&gt;
  Y0 Y0 Y0 Y0&lt;br /&gt;
  Y0 Y0 Y0 Y0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern B: (270 degrees)&lt;br /&gt;
  Y0 Y0 Y0 Y0&lt;br /&gt;
  Y1 Y1 Y1 Y1&lt;br /&gt;
  Y2 Y2 Y2 Y2&lt;br /&gt;
  Y3 Y3 Y3 Y3&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern C: (subsampled)&lt;br /&gt;
  Y0 Y0 Y1 Y1&lt;br /&gt;
  Y0 Y0 Y1 Y1&lt;br /&gt;
  Y2 Y2 Y3 Y3&lt;br /&gt;
  Y2 Y2 Y3 Y3&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern D: (16 samples)&lt;br /&gt;
  Y0  Y1  Y2  Y3&lt;br /&gt;
  Y4  Y5  Y6  Y7&lt;br /&gt;
  Y8  Y9  Y10 Y11&lt;br /&gt;
  Y12 Y13 Y14 Y15&lt;br /&gt;
&lt;br /&gt;
== Converting Ultimotion Scaled YUV To Correct YUV ==&lt;br /&gt;
&lt;br /&gt;
To convert Ultimotion 6-bit luminance values to proper luminance samples, use the following conversion table:&lt;br /&gt;
&lt;br /&gt;
 unsigned char ulti_lumas[64] =&lt;br /&gt;
    { 0x10, 0x13, 0x17, 0x1A, 0x1E, 0x21, 0x25, 0x28,&lt;br /&gt;
      0x2C, 0x2F, 0x33, 0x36, 0x3A, 0x3D, 0x41, 0x44,&lt;br /&gt;
      0x48, 0x4B, 0x4F, 0x52, 0x56, 0x59, 0x5C, 0x60,&lt;br /&gt;
      0x63, 0x67, 0x6A, 0x6E, 0x71, 0x75, 0x78, 0x7C,&lt;br /&gt;
      0x7F, 0x83, 0x86, 0x8A, 0x8D, 0x91, 0x94, 0x98,&lt;br /&gt;
      0x9B, 0x9F, 0xA2, 0xA5, 0xA9, 0xAC, 0xB0, 0xB3,&lt;br /&gt;
      0xB7, 0xBA, 0xBE, 0xC1, 0xC5, 0xC8, 0xCC, 0xCF,&lt;br /&gt;
      0xD3, 0xD6, 0xDA, 0xDD, 0xE1, 0xE4, 0xE8, 0xEB};&lt;br /&gt;
      &lt;br /&gt;
To convert Ultimotion 4-bit chrominance values to proper chrominance samples, use the following conversion table:&lt;br /&gt;
&lt;br /&gt;
 unsigned char ulti_chromas[16] =&lt;br /&gt;
    { 0x60, 0x67, 0x6D, 0x73, 0x7A, 0x80, 0x86, 0x8D,&lt;br /&gt;
      0x93, 0x99, 0xA0, 0xA6, 0xAC, 0xB3, 0xB9, 0xC0};&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* [http://xanim.polter.net/ XAnim]&lt;br /&gt;
&lt;br /&gt;
* [http://mplayerhq.hu/cgi-bin/cvsweb.cgi/~checkout~/ffmpeg/libavcodec/ulti_cb.h?content-type=text/x-cvsweb-markup&amp;amp;cvsroot=FFMpeg Ultimotion Luminance Codebook]&lt;br /&gt;
&lt;br /&gt;
[[Category:Video Codecs]]&lt;/div&gt;</summary>
		<author><name>Ultimotion</name></author>
	</entry>
	<entry>
		<id>https://wiki.multimedia.cx/index.php?title=IBM_UltiMotion&amp;diff=6241</id>
		<title>IBM UltiMotion</title>
		<link rel="alternate" type="text/html" href="https://wiki.multimedia.cx/index.php?title=IBM_UltiMotion&amp;diff=6241"/>
		<updated>2006-10-12T20:15:21Z</updated>

		<summary type="html">&lt;p&gt;Ultimotion: /* Decoding Algorithm */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* FourCC: ULTI&lt;br /&gt;
* Company: [[IBM]]&lt;br /&gt;
* Official Description: [http://multimedia.cx/UMSPEC.ZIP Ultimotion Digital Video Data Stream Specification]&lt;br /&gt;
* Additional Documentation: [http://multimedia.cx/ultimotion-format.txt 'Description of the IBM UltiMotion (ULTI) Video Codec' by Mike Melanson and Konstantin Shishkov ].''&lt;br /&gt;
* Samples: [http://samples.mplayerhq.hu/V-codecs/ULTI/ http://samples.mplayerhq.hu/V-codecs/ULTI/]&lt;br /&gt;
* Codec: [http://hobbes.nmsu.edu/cgi-bin/h-viewer?sh=1&amp;amp;fname=/pub/windows/ultimo.zip Win32 Ultimotion decoder]&lt;br /&gt;
&lt;br /&gt;
IBM Ultimotion is a video codec typically seen in [[AVI]] files, though there is no reason it could not be used in other container formats.  Full codecs were available for Windows 3.1 (VfW), OS/2 and AIX.  It is primarily a vector quantizing algorithm with simple inter-frame coding (unchanged block).  Ultimotion encoding is significantly more computationally intensive than decoding.&lt;br /&gt;
&lt;br /&gt;
== Decoding Algorithm ==&lt;br /&gt;
&lt;br /&gt;
The Ultimotion algorithm operates natively on a scaled-down [[Raw YUV|YUV]] 4:1:0 planar colorspace. This means that for each 4x4 block of pixels (quadrant), each of the 16 pixels has a luminance (Y) sample and the entire block shares one chrominance sample (expressed as two color difference components : C&amp;lt;sub&amp;gt;b&amp;lt;/sub&amp;gt; (or U) and C&amp;lt;sub&amp;gt;r&amp;lt;/sub&amp;gt; (or V). The colorspace is actually non-linear quantized to fixed values from 2 tables. Indices into these tables (64 possible values for luminance and 16 for each chrominance component) are transmitted in the final bitstream.&lt;br /&gt;
&lt;br /&gt;
The Ultimotion algorithm codes a frame by dividing it into a series of 8x8 blocks. Each 8x8 block is subdivided and coded as 4 4x4 quadrants. The 4 quadrants, 0-3, are coded in the following arrangement:&lt;br /&gt;
&lt;br /&gt;
  0 3&lt;br /&gt;
  1 2&lt;br /&gt;
&lt;br /&gt;
Each block can be encoded using a single chrominance sample or unique chrominance sample for each quadrant. Each quadrant has 16 luminance samples that can be coded using a variety of methods.&lt;br /&gt;
&lt;br /&gt;
To decode a frame of Ultimotion data, follow this process:&lt;br /&gt;
&lt;br /&gt;
 initialize uniq and mode flags to 0&lt;br /&gt;
 &lt;br /&gt;
 for each 8x8 block in the frame, iterating from left -&amp;gt; right, top -&amp;gt; bottom:&lt;br /&gt;
 &lt;br /&gt;
  get the next byte in the stream (b0)&lt;br /&gt;
  if (b0 &amp;amp; 0xF8) == 0x70, handle escape code:&lt;br /&gt;
    if b0 is 0x70&lt;br /&gt;
      mode = next byte in stream&lt;br /&gt;
      note: only mode values of 0 or 1 are valid&lt;br /&gt;
    if b0 is 0x71&lt;br /&gt;
      uniq flag = -1 &lt;br /&gt;
    if b0 is 0x72&lt;br /&gt;
      toggle uniq flag (0/1)&lt;br /&gt;
    if b0 is 0x73&lt;br /&gt;
      end of frame, stop decoding&lt;br /&gt;
    if b0 is 0x74&lt;br /&gt;
      get the next byte in stream (b1)&lt;br /&gt;
      skip next (b1) blocks in the output frame (unchanged from previous frame)&lt;br /&gt;
 &lt;br /&gt;
  else&lt;br /&gt;
    if b0 is non-zero and uniq flag is 0&lt;br /&gt;
      chrominance byte = next byte from stream&lt;br /&gt;
 &lt;br /&gt;
    for each 4x4 quadrant in the block, arranged in the quadrant pattern:&lt;br /&gt;
 &lt;br /&gt;
      extract quadrant coding mode from b0:&lt;br /&gt;
        bits 7-6: quadrant 0 coding mode&lt;br /&gt;
        bits 5-4: quadrant 1 coding mode&lt;br /&gt;
        bits 3-2: quadrant 2 coding mode&lt;br /&gt;
        bits 1-0: quadrant 3 coding mode&lt;br /&gt;
 &lt;br /&gt;
      if coding mode is non-zero and uniq flag is non-zero&lt;br /&gt;
        chrominance byte = next byte from stream&lt;br /&gt;
 &lt;br /&gt;
      coding mode 0:&lt;br /&gt;
        skip quadrant (unchanged from the previous frame)&lt;br /&gt;
 &lt;br /&gt;
      coding mode 1:&lt;br /&gt;
        paint the luminance samples using a gradient pattern based on one &lt;br /&gt;
          sample coded in the stream&lt;br /&gt;
 &lt;br /&gt;
        get next byte from stream (b1)&lt;br /&gt;
        bits 7-6 of b1 indicate gradient fill pattern:&lt;br /&gt;
          0 = gradient fill pattern A&lt;br /&gt;
          1 = gradient fill pattern 2&lt;br /&gt;
          2 = gradient fill pattern 6&lt;br /&gt;
          3 = gradient fill pattern B&lt;br /&gt;
        bits 5-0 of b1 indicate luminance sample Y0&lt;br /&gt;
          Y1 = Y0, Y2 = Y0 + 1, Y3 = Y0 + 1&lt;br /&gt;
        fill luminance samples according to Y0..Y3 and the gradient fill &lt;br /&gt;
          pattern (see section Gradient Fill Patterns)&lt;br /&gt;
 &lt;br /&gt;
      coding mode 2:&lt;br /&gt;
        paint the luminance samples using a gradient pattern based on either &lt;br /&gt;
          four samples retrieved from a 4,096-entry codebook using an index&lt;br /&gt;
          coded in the stream or four samples coded in the stream &lt;br /&gt;
        if mode is 0&lt;br /&gt;
          get the next 2 bytes from the stream as a big endian 16-bit &lt;br /&gt;
            number:&lt;br /&gt;
          gradient fill pattern = bits 15-12&lt;br /&gt;
          luminance codebook index = bits 11-0&lt;br /&gt;
          Y0..Y3 are set according to the codebook entry (see References &lt;br /&gt;
            for Ultimotion luminance codebook)&lt;br /&gt;
          if bit 3 of the gradient fill pattern is set&lt;br /&gt;
            swap Y0 with Y3 and Y1 with Y2&lt;br /&gt;
            clear bit 3 of the gradient fill pattern&lt;br /&gt;
          fill luminance samples according to Y0..Y3 and the gradient fill &lt;br /&gt;
            pattern (see section Gradient Fill Patterns)&lt;br /&gt;
        else (mode is non-zero)&lt;br /&gt;
          get the next 3 bytes from the stream as a big endian 24-bit number:&lt;br /&gt;
            Y0 = bits 23-18&lt;br /&gt;
            Y1 = bits 17-12&lt;br /&gt;
            Y2 = bits 11-6&lt;br /&gt;
            Y3 = bits 5-0&lt;br /&gt;
          fill luminance samples according to Y0..Y3 and gradient fill &lt;br /&gt;
            pattern C (see section Gradient Fill Patterns)&lt;br /&gt;
 &lt;br /&gt;
      coding mode 3:&lt;br /&gt;
        flexible coding mode that can paint the luminance samples with an &lt;br /&gt;
          arbitrary pattern using two samples and a set of flags coded in the &lt;br /&gt;
          stream, or with a gradient fill pattern and four samples coded in the &lt;br /&gt;
          stream, or with 16 samples coded in the stream&lt;br /&gt;
        if mode is 0&lt;br /&gt;
          if bit 7 of b1 is 0&lt;br /&gt;
            flagsA = b1&lt;br /&gt;
            flagsB = next byte in the stream&lt;br /&gt;
            Y0 = next byte in stream &amp;amp; 0x3F&lt;br /&gt;
            Y1 = next byte in stream &amp;amp; 0x3F&lt;br /&gt;
            the 16 bits between flagsA and flagsB represent the pattern &lt;br /&gt;
              used to place either Y0 or Y1 into the luminance grid&lt;br /&gt;
 &lt;br /&gt;
              A7 A6 A5 A4&lt;br /&gt;
              A3 A2 A1 A0&lt;br /&gt;
              B7 B6 B5 B4&lt;br /&gt;
              B3 B2 B1 B0&lt;br /&gt;
 &lt;br /&gt;
              for example, if bit 3 of flagsB is 1, Y1 would be used in &lt;br /&gt;
              the lower left corner of the quadrant, else Y0&lt;br /&gt;
          else&lt;br /&gt;
            gradient fill pattern = bits 6-4 of b1&lt;br /&gt;
            get the next byte in the stream (b2)&lt;br /&gt;
            Y0 = ((b1 &amp;amp; 0x0F) &amp;lt;&amp;lt; 2) | (b2 &amp;gt;&amp;gt; 6)&lt;br /&gt;
            Y1 = bits 5-0 of b2&lt;br /&gt;
            Y2 = next byte in stream &amp;amp; 0x3F&lt;br /&gt;
            Y3 = next byte in stream &amp;amp; 0x3F&lt;br /&gt;
            fill luminance samples according to Y0..Y3 and the gradient &lt;br /&gt;
              fill pattern (see section Gradient Fill Patterns)&lt;br /&gt;
        else (mode is non-zero)&lt;br /&gt;
          get the next 12 bytes from the stream as 16 6-bit numbers as the 16 &lt;br /&gt;
            luminance samples (Y0..Y16) for the quadrant&lt;br /&gt;
          fill luminance samples according to Y0..Y16 and gradient fill &lt;br /&gt;
            pattern D (see section Gradient Fill Patterns)&lt;br /&gt;
 &lt;br /&gt;
      finally, output quadrant:&lt;br /&gt;
        bits 7-4 of the chrominance byte represent the Cr (or V) component&lt;br /&gt;
          while bits 3-0 represent the Cb (U) component&lt;br /&gt;
        convert the 16 luminance values and the 2 chrominance values to a &lt;br /&gt;
          proper YUV colorspace using the conversion tables in Appendix A&lt;br /&gt;
 &lt;br /&gt;
  if uniq flag is -1&lt;br /&gt;
    uniq flag = 0&lt;br /&gt;
&lt;br /&gt;
== Gradient Fill Patterns ==&lt;br /&gt;
&lt;br /&gt;
The ULTI codec has 11 gradient fill patterns for painting 4x4 sub blocks of luminance data using 4 luminance samples.&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 0: (0 degrees)&lt;br /&gt;
  Y0 Y1 Y2 Y3&lt;br /&gt;
  Y0 Y1 Y2 Y3&lt;br /&gt;
  Y0 Y1 Y2 Y3&lt;br /&gt;
  Y0 Y1 Y2 Y3&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 1: (22.5 degrees)&lt;br /&gt;
  Y1 Y2 Y3 Y3&lt;br /&gt;
  Y0 Y1 Y2 Y3&lt;br /&gt;
  Y0 Y1 Y2 Y3&lt;br /&gt;
  Y0 Y0 Y1 Y2&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 2: (45 degrees)&lt;br /&gt;
  Y1 Y2 Y3 Y3&lt;br /&gt;
  Y1 Y2 Y2 Y3&lt;br /&gt;
  Y0 Y1 Y1 Y2&lt;br /&gt;
  Y0 Y0 Y1 Y2&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 3: (67.5 degrees)&lt;br /&gt;
  Y2 Y3 Y3 Y3&lt;br /&gt;
  Y1 Y2 Y2 Y3&lt;br /&gt;
  Y0 Y1 Y1 Y2&lt;br /&gt;
  Y0 Y0 Y0 Y1&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 4: (90 degrees)&lt;br /&gt;
  Y3 Y3 Y3 Y3&lt;br /&gt;
  Y2 Y2 Y2 Y2&lt;br /&gt;
  Y1 Y1 Y1 Y1&lt;br /&gt;
  Y0 Y0 Y0 Y0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 5: (112.5 degrees)&lt;br /&gt;
  Y3 Y3 Y3 Y2&lt;br /&gt;
  Y3 Y2 Y2 Y1&lt;br /&gt;
  Y2 Y1 Y1 Y0&lt;br /&gt;
  Y1 Y0 Y0 Y0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 6: (135 degrees)&lt;br /&gt;
  Y3 Y3 Y2 Y2&lt;br /&gt;
  Y3 Y2 Y1 Y1&lt;br /&gt;
  Y2 Y2 Y1 Y0&lt;br /&gt;
  Y1 Y1 Y0 Y0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 7: (157.5 degrees)&lt;br /&gt;
  Y3 Y3 Y2 Y1&lt;br /&gt;
  Y3 Y2 Y1 Y0&lt;br /&gt;
  Y3 Y2 Y1 Y0&lt;br /&gt;
  Y2 Y1 Y0 Y0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern A: (homogeneous)&lt;br /&gt;
  Y0 Y0 Y0 Y0&lt;br /&gt;
  Y0 Y0 Y0 Y0&lt;br /&gt;
  Y0 Y0 Y0 Y0&lt;br /&gt;
  Y0 Y0 Y0 Y0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern B: (270 degrees)&lt;br /&gt;
  Y0 Y0 Y0 Y0&lt;br /&gt;
  Y1 Y1 Y1 Y1&lt;br /&gt;
  Y2 Y2 Y2 Y2&lt;br /&gt;
  Y3 Y3 Y3 Y3&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern C: (subsampled)&lt;br /&gt;
  Y0 Y0 Y1 Y1&lt;br /&gt;
  Y0 Y0 Y1 Y1&lt;br /&gt;
  Y2 Y2 Y3 Y3&lt;br /&gt;
  Y2 Y2 Y3 Y3&lt;br /&gt;
&lt;br /&gt;
== Converting Ultimotion Scaled YUV To Correct YUV ==&lt;br /&gt;
&lt;br /&gt;
To convert Ultimotion 6-bit luminance values to proper luminance samples, use the following conversion table:&lt;br /&gt;
&lt;br /&gt;
 unsigned char ulti_lumas[64] =&lt;br /&gt;
    { 0x10, 0x13, 0x17, 0x1A, 0x1E, 0x21, 0x25, 0x28,&lt;br /&gt;
      0x2C, 0x2F, 0x33, 0x36, 0x3A, 0x3D, 0x41, 0x44,&lt;br /&gt;
      0x48, 0x4B, 0x4F, 0x52, 0x56, 0x59, 0x5C, 0x60,&lt;br /&gt;
      0x63, 0x67, 0x6A, 0x6E, 0x71, 0x75, 0x78, 0x7C,&lt;br /&gt;
      0x7F, 0x83, 0x86, 0x8A, 0x8D, 0x91, 0x94, 0x98,&lt;br /&gt;
      0x9B, 0x9F, 0xA2, 0xA5, 0xA9, 0xAC, 0xB0, 0xB3,&lt;br /&gt;
      0xB7, 0xBA, 0xBE, 0xC1, 0xC5, 0xC8, 0xCC, 0xCF,&lt;br /&gt;
      0xD3, 0xD6, 0xDA, 0xDD, 0xE1, 0xE4, 0xE8, 0xEB};&lt;br /&gt;
      &lt;br /&gt;
To convert Ultimotion 4-bit chrominance values to proper chrominance samples, use the following conversion table:&lt;br /&gt;
&lt;br /&gt;
 unsigned char ulti_chromas[16] =&lt;br /&gt;
    { 0x60, 0x67, 0x6D, 0x73, 0x7A, 0x80, 0x86, 0x8D,&lt;br /&gt;
      0x93, 0x99, 0xA0, 0xA6, 0xAC, 0xB3, 0xB9, 0xC0};&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* [http://xanim.polter.net/ XAnim]&lt;br /&gt;
&lt;br /&gt;
* [http://mplayerhq.hu/cgi-bin/cvsweb.cgi/~checkout~/ffmpeg/libavcodec/ulti_cb.h?content-type=text/x-cvsweb-markup&amp;amp;cvsroot=FFMpeg Ultimotion Luminance Codebook]&lt;br /&gt;
&lt;br /&gt;
[[Category:Video Codecs]]&lt;/div&gt;</summary>
		<author><name>Ultimotion</name></author>
	</entry>
	<entry>
		<id>https://wiki.multimedia.cx/index.php?title=IBM_UltiMotion&amp;diff=6240</id>
		<title>IBM UltiMotion</title>
		<link rel="alternate" type="text/html" href="https://wiki.multimedia.cx/index.php?title=IBM_UltiMotion&amp;diff=6240"/>
		<updated>2006-10-12T19:54:45Z</updated>

		<summary type="html">&lt;p&gt;Ultimotion: /* Decoding Algorithm */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* FourCC: ULTI&lt;br /&gt;
* Company: [[IBM]]&lt;br /&gt;
* Official Description: [http://multimedia.cx/UMSPEC.ZIP Ultimotion Digital Video Data Stream Specification]&lt;br /&gt;
* Additional Documentation: [http://multimedia.cx/ultimotion-format.txt 'Description of the IBM UltiMotion (ULTI) Video Codec' by Mike Melanson and Konstantin Shishkov ].''&lt;br /&gt;
* Samples: [http://samples.mplayerhq.hu/V-codecs/ULTI/ http://samples.mplayerhq.hu/V-codecs/ULTI/]&lt;br /&gt;
* Codec: [http://hobbes.nmsu.edu/cgi-bin/h-viewer?sh=1&amp;amp;fname=/pub/windows/ultimo.zip Win32 Ultimotion decoder]&lt;br /&gt;
&lt;br /&gt;
IBM Ultimotion is a video codec typically seen in [[AVI]] files, though there is no reason it could not be used in other container formats.  Full codecs were available for Windows 3.1 (VfW), OS/2 and AIX.  It is primarily a vector quantizing algorithm with simple inter-frame coding (unchanged block).  Ultimotion encoding is significantly more computationally intensive than decoding.&lt;br /&gt;
&lt;br /&gt;
== Decoding Algorithm ==&lt;br /&gt;
&lt;br /&gt;
The Ultimotion algorithm operates natively on a scaled-down [[Raw YUV|YUV]] 4:1:0 planar colorspace. This means that for each 4x4 block of pixels (quadrant), each of the 16 pixels has a luminance (Y) sample and the entire block shares one chrominance sample (expressed as two color difference components : C&amp;lt;sub&amp;gt;b&amp;lt;/sub&amp;gt; (or U) and C&amp;lt;sub&amp;gt;r&amp;lt;/sub&amp;gt; (or V). The colorspace is actually non-linear quantized to fixed values from 2 tables. Indices into these tables (64 possible values for luminance and 16 for each chrominance component) are transmitted in the final bitstream.&lt;br /&gt;
&lt;br /&gt;
The Ultimotion algorithm codes a frame by dividing it into a series of 8x8 blocks. Each 8x8 block is subdivided and coded as 4 4x4 quadrants. The 4 quadrants, 0-3, are coded in the following arrangement:&lt;br /&gt;
&lt;br /&gt;
  0 3&lt;br /&gt;
  1 2&lt;br /&gt;
&lt;br /&gt;
Each block can be encoded using a single chrominance sample or unique chrominance sample for each quadrant. Each quadrant has 16 luminance samples that can be coded using a variety of methods.&lt;br /&gt;
&lt;br /&gt;
To decode a frame of Ultimotion data, follow this process:&lt;br /&gt;
&lt;br /&gt;
 initialize uniq and mode flags to 0&lt;br /&gt;
 &lt;br /&gt;
 for each 8x8 block in the frame, iterating from left -&amp;gt; right, top -&amp;gt; bottom:&lt;br /&gt;
 &lt;br /&gt;
  get the next byte in the stream (b0)&lt;br /&gt;
  if (b0 &amp;amp; 0xF8) == 0x70, handle escape code:&lt;br /&gt;
    if b0 is 0x70&lt;br /&gt;
      mode = next byte in stream&lt;br /&gt;
      note: only mode values of 0 or 1 are valid&lt;br /&gt;
    if b0 is 0x71&lt;br /&gt;
      uniq flag = -1 &lt;br /&gt;
    if b0 is 0x72&lt;br /&gt;
      toggle uniq flag (0/1)&lt;br /&gt;
    if b0 is 0x73&lt;br /&gt;
      end of frame, stop decoding&lt;br /&gt;
    if b0 is 0x74&lt;br /&gt;
      get the next byte in stream (b1)&lt;br /&gt;
      skip next (b1) blocks in the output frame (unchanged from previous frame)&lt;br /&gt;
 &lt;br /&gt;
  else&lt;br /&gt;
    if b0 is non-zero and uniq flag is 0&lt;br /&gt;
      chrominance byte = next byte from stream&lt;br /&gt;
 &lt;br /&gt;
    for each 4x4 quadrant in the block, arranged in the quadrant pattern:&lt;br /&gt;
 &lt;br /&gt;
      extract quadrant coding mode from b0:&lt;br /&gt;
        bits 7-6: quadrant 0 coding mode&lt;br /&gt;
        bits 5-4: quadrant 1 coding mode&lt;br /&gt;
        bits 3-2: quadrant 2 coding mode&lt;br /&gt;
        bits 1-0: quadrant 3 coding mode&lt;br /&gt;
 &lt;br /&gt;
      if coding mode is non-zero and uniq flag is non-zero&lt;br /&gt;
        chrominance byte = next byte from stream&lt;br /&gt;
 &lt;br /&gt;
      coding mode 0:&lt;br /&gt;
        skip quadrant (unchanged from the previous frame)&lt;br /&gt;
 &lt;br /&gt;
      coding mode 1:&lt;br /&gt;
        paint the luminance samples using a gradient pattern based on one &lt;br /&gt;
          6-bit sample coded in the stream&lt;br /&gt;
 &lt;br /&gt;
        get next byte from stream (b1)&lt;br /&gt;
        bits 7-6 of b1 indicate gradient fill pattern:&lt;br /&gt;
          0 = gradient fill pattern A&lt;br /&gt;
          1 = gradient fill pattern 2&lt;br /&gt;
          2 = gradient fill pattern 6&lt;br /&gt;
          3 = gradient fill pattern B&lt;br /&gt;
        bits 5-0 of b1 indicate luminance sample Y0&lt;br /&gt;
          Y1 = Y0, Y2 = Y0 + 1, Y3 = Y0 + 1&lt;br /&gt;
        fill luminance samples according to Y0..Y3 and the gradient fill &lt;br /&gt;
          pattern (see section Gradient Fill Patterns)&lt;br /&gt;
 &lt;br /&gt;
      coding mode 2:&lt;br /&gt;
        paint the luminance samples using a gradient pattern based on &lt;br /&gt;
          either 4 6-bit samples coded in the stream or 4 6-bit samples &lt;br /&gt;
          retrieved from a 16,384-entry codebook using an index coded in &lt;br /&gt;
          the stream&lt;br /&gt;
        if mode is 0&lt;br /&gt;
          get the next 2 bytes from the stream as a big endian 16-bit &lt;br /&gt;
            number:&lt;br /&gt;
          gradient fill pattern = bits 15-12&lt;br /&gt;
          luminance codebook index = bits 11-0&lt;br /&gt;
          Y0..Y3 are set according to the codebook entry (see References &lt;br /&gt;
            for Ultimotion luminance codebook)&lt;br /&gt;
          if bit 3 of the gradient fill pattern is set, swap Y0 with Y3 &lt;br /&gt;
            and Y1 with Y2; clear bit 3 of the gradient fill pattern&lt;br /&gt;
          fill luminance samples according to Y0..Y3 and the gradient fill &lt;br /&gt;
            pattern (see section Gradient Fill Patterns)&lt;br /&gt;
        else (mode is non-zero)&lt;br /&gt;
          get the next 3 bytes from the stream as a big endian 24-bit &lt;br /&gt;
            number:&lt;br /&gt;
          Y0 = bits 23-18&lt;br /&gt;
          Y1 = bits 17-12&lt;br /&gt;
          Y2 = bits 11-6&lt;br /&gt;
          Y3 = bits 5-0&lt;br /&gt;
          fill luminance samples according to Y0..Y3 and gradient fill &lt;br /&gt;
            pattern 8 (see section Gradient Fill Patterns)&lt;br /&gt;
 &lt;br /&gt;
      coding mode 3:&lt;br /&gt;
        flexible coding mode that can paint the luminance samples with 16 &lt;br /&gt;
          6-bit samples coded in the stream, or with a gradient fill &lt;br /&gt;
          pattern and 4 6-bit luminance samples coded in the stream, or &lt;br /&gt;
          with an arbitrary pattern using 2 luminance samples and a set of &lt;br /&gt;
          flags coded in the stream&lt;br /&gt;
        if mode is 0&lt;br /&gt;
          get the next byte in the stream (b1)&lt;br /&gt;
          if bit 7 of b1 is set&lt;br /&gt;
            gradient fill pattern = bits 6-4 of b1&lt;br /&gt;
            get the next byte in the stream (b1)&lt;br /&gt;
            Y0 = ((b1 &amp;amp; 0x0F) &amp;lt;&amp;lt; 2) | (b1 &amp;gt;&amp;gt; 6)&lt;br /&gt;
            Y1 = bits 5-0 of b1&lt;br /&gt;
            Y2 = next byte in stream &amp;amp; 0x3F&lt;br /&gt;
            Y3 = next byte in stream &amp;amp; 0x3F&lt;br /&gt;
            fill luminance samples according to Y0..Y3 and the gradient &lt;br /&gt;
              fill pattern (see section Gradient Fill Patterns)&lt;br /&gt;
          else&lt;br /&gt;
            flagsA = b1&lt;br /&gt;
            flagsB = next byte in the stream&lt;br /&gt;
            Y0 = next byte in stream &amp;amp; 0x3F&lt;br /&gt;
            Y1 = next byte in stream &amp;amp; 0x3F&lt;br /&gt;
            the 16 bits between flagsA and flagsB represent the pattern &lt;br /&gt;
              used to place either Y0 or Y1 into the luminance grid&lt;br /&gt;
 &lt;br /&gt;
              A7 A6 A5 A4&lt;br /&gt;
              A3 A2 A1 A0&lt;br /&gt;
              B7 B6 B5 B4&lt;br /&gt;
              B3 B2 B1 B0&lt;br /&gt;
 &lt;br /&gt;
              for example, if bit 3 of flagsB is 1, Y1 would be used in &lt;br /&gt;
              the lower left corner of the quadrant, else Y0&lt;br /&gt;
        else (mode is non-zero)&lt;br /&gt;
          get the next 16 6-bit numbers from the stream as the 16 &lt;br /&gt;
            luminance samples for the quadrant, thus consuming 96 bits, &lt;br /&gt;
            or 12 bytes from the stream&lt;br /&gt;
 &lt;br /&gt;
      finally, output quadrant:&lt;br /&gt;
        bits 7-4 of the chrominance byte represent the Cr (or V) component&lt;br /&gt;
          while bits 3-0 represent the Cb (U) component&lt;br /&gt;
        convert the 16 luminance values and the 2 chrominance values to a &lt;br /&gt;
          proper YUV colorspace using the conversion tables in Appendix A&lt;br /&gt;
 &lt;br /&gt;
  if uniq flag is -1&lt;br /&gt;
    uniq flag = 0&lt;br /&gt;
&lt;br /&gt;
== Gradient Fill Patterns ==&lt;br /&gt;
&lt;br /&gt;
The ULTI codec has 11 gradient fill patterns for painting 4x4 sub blocks of luminance data using 4 luminance samples.&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 0: (0 degrees)&lt;br /&gt;
  Y0 Y1 Y2 Y3&lt;br /&gt;
  Y0 Y1 Y2 Y3&lt;br /&gt;
  Y0 Y1 Y2 Y3&lt;br /&gt;
  Y0 Y1 Y2 Y3&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 1: (22.5 degrees)&lt;br /&gt;
  Y1 Y2 Y3 Y3&lt;br /&gt;
  Y0 Y1 Y2 Y3&lt;br /&gt;
  Y0 Y1 Y2 Y3&lt;br /&gt;
  Y0 Y0 Y1 Y2&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 2: (45 degrees)&lt;br /&gt;
  Y1 Y2 Y3 Y3&lt;br /&gt;
  Y1 Y2 Y2 Y3&lt;br /&gt;
  Y0 Y1 Y1 Y2&lt;br /&gt;
  Y0 Y0 Y1 Y2&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 3: (67.5 degrees)&lt;br /&gt;
  Y2 Y3 Y3 Y3&lt;br /&gt;
  Y1 Y2 Y2 Y3&lt;br /&gt;
  Y0 Y1 Y1 Y2&lt;br /&gt;
  Y0 Y0 Y0 Y1&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 4: (90 degrees)&lt;br /&gt;
  Y3 Y3 Y3 Y3&lt;br /&gt;
  Y2 Y2 Y2 Y2&lt;br /&gt;
  Y1 Y1 Y1 Y1&lt;br /&gt;
  Y0 Y0 Y0 Y0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 5: (112.5 degrees)&lt;br /&gt;
  Y3 Y3 Y3 Y2&lt;br /&gt;
  Y3 Y2 Y2 Y1&lt;br /&gt;
  Y2 Y1 Y1 Y0&lt;br /&gt;
  Y1 Y0 Y0 Y0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 6: (135 degrees)&lt;br /&gt;
  Y3 Y3 Y2 Y2&lt;br /&gt;
  Y3 Y2 Y1 Y1&lt;br /&gt;
  Y2 Y2 Y1 Y0&lt;br /&gt;
  Y1 Y1 Y0 Y0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 7: (157.5 degrees)&lt;br /&gt;
  Y3 Y3 Y2 Y1&lt;br /&gt;
  Y3 Y2 Y1 Y0&lt;br /&gt;
  Y3 Y2 Y1 Y0&lt;br /&gt;
  Y2 Y1 Y0 Y0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern A: (homogeneous)&lt;br /&gt;
  Y0 Y0 Y0 Y0&lt;br /&gt;
  Y0 Y0 Y0 Y0&lt;br /&gt;
  Y0 Y0 Y0 Y0&lt;br /&gt;
  Y0 Y0 Y0 Y0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern B: (270 degrees)&lt;br /&gt;
  Y0 Y0 Y0 Y0&lt;br /&gt;
  Y1 Y1 Y1 Y1&lt;br /&gt;
  Y2 Y2 Y2 Y2&lt;br /&gt;
  Y3 Y3 Y3 Y3&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern C: (subsampled)&lt;br /&gt;
  Y0 Y0 Y1 Y1&lt;br /&gt;
  Y0 Y0 Y1 Y1&lt;br /&gt;
  Y2 Y2 Y3 Y3&lt;br /&gt;
  Y2 Y2 Y3 Y3&lt;br /&gt;
&lt;br /&gt;
== Converting Ultimotion Scaled YUV To Correct YUV ==&lt;br /&gt;
&lt;br /&gt;
To convert Ultimotion 6-bit luminance values to proper luminance samples, use the following conversion table:&lt;br /&gt;
&lt;br /&gt;
 unsigned char ulti_lumas[64] =&lt;br /&gt;
    { 0x10, 0x13, 0x17, 0x1A, 0x1E, 0x21, 0x25, 0x28,&lt;br /&gt;
      0x2C, 0x2F, 0x33, 0x36, 0x3A, 0x3D, 0x41, 0x44,&lt;br /&gt;
      0x48, 0x4B, 0x4F, 0x52, 0x56, 0x59, 0x5C, 0x60,&lt;br /&gt;
      0x63, 0x67, 0x6A, 0x6E, 0x71, 0x75, 0x78, 0x7C,&lt;br /&gt;
      0x7F, 0x83, 0x86, 0x8A, 0x8D, 0x91, 0x94, 0x98,&lt;br /&gt;
      0x9B, 0x9F, 0xA2, 0xA5, 0xA9, 0xAC, 0xB0, 0xB3,&lt;br /&gt;
      0xB7, 0xBA, 0xBE, 0xC1, 0xC5, 0xC8, 0xCC, 0xCF,&lt;br /&gt;
      0xD3, 0xD6, 0xDA, 0xDD, 0xE1, 0xE4, 0xE8, 0xEB};&lt;br /&gt;
      &lt;br /&gt;
To convert Ultimotion 4-bit chrominance values to proper chrominance samples, use the following conversion table:&lt;br /&gt;
&lt;br /&gt;
 unsigned char ulti_chromas[16] =&lt;br /&gt;
    { 0x60, 0x67, 0x6D, 0x73, 0x7A, 0x80, 0x86, 0x8D,&lt;br /&gt;
      0x93, 0x99, 0xA0, 0xA6, 0xAC, 0xB3, 0xB9, 0xC0};&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* [http://xanim.polter.net/ XAnim]&lt;br /&gt;
&lt;br /&gt;
* [http://mplayerhq.hu/cgi-bin/cvsweb.cgi/~checkout~/ffmpeg/libavcodec/ulti_cb.h?content-type=text/x-cvsweb-markup&amp;amp;cvsroot=FFMpeg Ultimotion Luminance Codebook]&lt;br /&gt;
&lt;br /&gt;
[[Category:Video Codecs]]&lt;/div&gt;</summary>
		<author><name>Ultimotion</name></author>
	</entry>
	<entry>
		<id>https://wiki.multimedia.cx/index.php?title=IBM_UltiMotion&amp;diff=6239</id>
		<title>IBM UltiMotion</title>
		<link rel="alternate" type="text/html" href="https://wiki.multimedia.cx/index.php?title=IBM_UltiMotion&amp;diff=6239"/>
		<updated>2006-10-12T19:48:46Z</updated>

		<summary type="html">&lt;p&gt;Ultimotion: /* Gradient Fill Patterns */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* FourCC: ULTI&lt;br /&gt;
* Company: [[IBM]]&lt;br /&gt;
* Official Description: [http://multimedia.cx/UMSPEC.ZIP Ultimotion Digital Video Data Stream Specification]&lt;br /&gt;
* Additional Documentation: [http://multimedia.cx/ultimotion-format.txt 'Description of the IBM UltiMotion (ULTI) Video Codec' by Mike Melanson and Konstantin Shishkov ].''&lt;br /&gt;
* Samples: [http://samples.mplayerhq.hu/V-codecs/ULTI/ http://samples.mplayerhq.hu/V-codecs/ULTI/]&lt;br /&gt;
* Codec: [http://hobbes.nmsu.edu/cgi-bin/h-viewer?sh=1&amp;amp;fname=/pub/windows/ultimo.zip Win32 Ultimotion decoder]&lt;br /&gt;
&lt;br /&gt;
IBM Ultimotion is a video codec typically seen in [[AVI]] files, though there is no reason it could not be used in other container formats.  Full codecs were available for Windows 3.1 (VfW), OS/2 and AIX.  It is primarily a vector quantizing algorithm with simple inter-frame coding (unchanged block).  Ultimotion encoding is significantly more computationally intensive than decoding.&lt;br /&gt;
&lt;br /&gt;
== Decoding Algorithm ==&lt;br /&gt;
&lt;br /&gt;
The Ultimotion algorithm operates natively on a scaled-down [[Raw YUV|YUV]] 4:1:0 planar colorspace. This means that for each 4x4 block of pixels (quadrant), each of the 16 pixels has a luminance (Y) sample and the entire block shares one chrominance sample (expressed as two color difference components : C&amp;lt;sub&amp;gt;b&amp;lt;/sub&amp;gt; (or U) and C&amp;lt;sub&amp;gt;r&amp;lt;/sub&amp;gt; (or V). The colorspace is actually non-linear quantized to fixed values from 2 tables. Indices into these tables (64 possible values for luminance and 16 for each chrominance component) are transmitted in the final bitstream.&lt;br /&gt;
&lt;br /&gt;
The Ultimotion algorithm codes a frame by dividing it into a series of 8x8 blocks. Each 8x8 block is subdivided and coded as 4 4x4 quadrants. The 4 quadrants, 0-3, are coded in the following arrangement:&lt;br /&gt;
&lt;br /&gt;
  0 3&lt;br /&gt;
  1 2&lt;br /&gt;
&lt;br /&gt;
Each block can be encoded using a single chrominance sample or unique chrominance sample for each quadrant. Each quadrant has 16 luminance samples that can be coded using a variety of methods.&lt;br /&gt;
&lt;br /&gt;
To decode a frame of Ultimotion data, follow this process:&lt;br /&gt;
&lt;br /&gt;
 initialize uniq and mode flags to 0&lt;br /&gt;
 &lt;br /&gt;
 for each 8x8 block in the frame, iterating from left -&amp;gt; right, top -&amp;gt; bottom:&lt;br /&gt;
 &lt;br /&gt;
  get the next byte in the stream (b0)&lt;br /&gt;
  if (b0 &amp;amp; 0xF8) == 0x70, handle escape code:&lt;br /&gt;
    if b0 is 0x70&lt;br /&gt;
      mode = next byte in stream&lt;br /&gt;
      note: only mode values of 0 or 1 are valid&lt;br /&gt;
    if b0 is 0x71&lt;br /&gt;
      uniq flag = -1 &lt;br /&gt;
    if b0 is 0x72&lt;br /&gt;
      toggle uniq flag (0/1)&lt;br /&gt;
    if b0 is 0x73&lt;br /&gt;
      end of frame, stop decoding&lt;br /&gt;
    if b0 is 0x74&lt;br /&gt;
      get the next byte in stream (b1)&lt;br /&gt;
      skip next (b1) blocks in the output frame (unchanged from previous frame)&lt;br /&gt;
 &lt;br /&gt;
  else&lt;br /&gt;
    if b0 is non-zero and uniq flag is 0&lt;br /&gt;
      chrominance byte = next byte from stream&lt;br /&gt;
 &lt;br /&gt;
    for each 4x4 quadrant in the block, arranged in the quadrant pattern:&lt;br /&gt;
 &lt;br /&gt;
      extract quadrant coding mode from b0:&lt;br /&gt;
        bits 7-6: quadrant 0 coding mode&lt;br /&gt;
        bits 5-4: quadrant 1 coding mode&lt;br /&gt;
        bits 3-2: quadrant 2 coding mode&lt;br /&gt;
        bits 1-0: quadrant 3 coding mode&lt;br /&gt;
 &lt;br /&gt;
      if coding mode is non-zero and uniq flag is non-zero&lt;br /&gt;
        chrominance byte = next byte from stream&lt;br /&gt;
 &lt;br /&gt;
      coding mode 0:&lt;br /&gt;
        skip quadrant (unchanged from the previous frame)&lt;br /&gt;
 &lt;br /&gt;
      coding mode 1:&lt;br /&gt;
        paint the luminance samples using a gradient pattern based on one &lt;br /&gt;
          6-bit sample coded in the stream&lt;br /&gt;
 &lt;br /&gt;
        get next byte from stream (b1)&lt;br /&gt;
        bits 7-6 of b1 indicate gradient fill pattern:&lt;br /&gt;
        bits 5-0 of b1 indicate luminance sample Y0&lt;br /&gt;
          0 = fill quadrant with Y0&lt;br /&gt;
          1 = gradient fill pattern 3&lt;br /&gt;
              Y1 = Y0, Y2 = Y0 + 1, Y3 = Y0 + 1&lt;br /&gt;
          2 = gradient fill pattern 5&lt;br /&gt;
              Y1 = Y0, Y2 = Y0 + 1, Y3 = Y0 + 1&lt;br /&gt;
          3 = gradient fill pattern 5&lt;br /&gt;
              Y3 = Y0, Y2 = Y0, Y1 = Y0 + 1, Y0 = Y0 + 1&lt;br /&gt;
        fill luminance samples according to Y0..Y3 and the gradient fill &lt;br /&gt;
          pattern (see section Gradient Fill Patterns)&lt;br /&gt;
 &lt;br /&gt;
      coding mode 2:&lt;br /&gt;
        paint the luminance samples using a gradient pattern based on &lt;br /&gt;
          either 4 6-bit samples coded in the stream or 4 6-bit samples &lt;br /&gt;
          retrieved from a 16,384-entry codebook using an index coded in &lt;br /&gt;
          the stream&lt;br /&gt;
        if mode is 0&lt;br /&gt;
          get the next 2 bytes from the stream as a big endian 16-bit &lt;br /&gt;
            number:&lt;br /&gt;
          gradient fill pattern = bits 15-12&lt;br /&gt;
          luminance codebook index = bits 11-0&lt;br /&gt;
          Y0..Y3 are set according to the codebook entry (see References &lt;br /&gt;
            for Ultimotion luminance codebook)&lt;br /&gt;
          if bit 3 of the gradient fill pattern is set, swap Y0 with Y3 &lt;br /&gt;
            and Y1 with Y2; clear bit 3 of the gradient fill pattern&lt;br /&gt;
          fill luminance samples according to Y0..Y3 and the gradient fill &lt;br /&gt;
            pattern (see section Gradient Fill Patterns)&lt;br /&gt;
        else (mode is non-zero)&lt;br /&gt;
          get the next 3 bytes from the stream as a big endian 24-bit &lt;br /&gt;
            number:&lt;br /&gt;
          Y0 = bits 23-18&lt;br /&gt;
          Y1 = bits 17-12&lt;br /&gt;
          Y2 = bits 11-6&lt;br /&gt;
          Y3 = bits 5-0&lt;br /&gt;
          fill luminance samples according to Y0..Y3 and gradient fill &lt;br /&gt;
            pattern 8 (see section Gradient Fill Patterns)&lt;br /&gt;
 &lt;br /&gt;
      coding mode 3:&lt;br /&gt;
        flexible coding mode that can paint the luminance samples with 16 &lt;br /&gt;
          6-bit samples coded in the stream, or with a gradient fill &lt;br /&gt;
          pattern and 4 6-bit luminance samples coded in the stream, or &lt;br /&gt;
          with an arbitrary pattern using 2 luminance samples and a set of &lt;br /&gt;
          flags coded in the stream&lt;br /&gt;
        if mode is 0&lt;br /&gt;
          get the next byte in the stream (b1)&lt;br /&gt;
          if bit 7 of b1 is set&lt;br /&gt;
            gradient fill pattern = bits 6-4 of b1&lt;br /&gt;
            get the next byte in the stream (b1)&lt;br /&gt;
            Y0 = ((b1 &amp;amp; 0x0F) &amp;lt;&amp;lt; 2) | (b1 &amp;gt;&amp;gt; 6)&lt;br /&gt;
            Y1 = bits 5-0 of b1&lt;br /&gt;
            Y2 = next byte in stream &amp;amp; 0x3F&lt;br /&gt;
            Y3 = next byte in stream &amp;amp; 0x3F&lt;br /&gt;
            fill luminance samples according to Y0..Y3 and the gradient &lt;br /&gt;
              fill pattern (see section Gradient Fill Patterns)&lt;br /&gt;
          else&lt;br /&gt;
            flagsA = b1&lt;br /&gt;
            flagsB = next byte in the stream&lt;br /&gt;
            Y0 = next byte in stream &amp;amp; 0x3F&lt;br /&gt;
            Y1 = next byte in stream &amp;amp; 0x3F&lt;br /&gt;
            the 16 bits between flagsA and flagsB represent the pattern &lt;br /&gt;
              used to place either Y0 or Y1 into the luminance grid&lt;br /&gt;
 &lt;br /&gt;
              A7 A6 A5 A4&lt;br /&gt;
              A3 A2 A1 A0&lt;br /&gt;
              B7 B6 B5 B4&lt;br /&gt;
              B3 B2 B1 B0&lt;br /&gt;
 &lt;br /&gt;
              for example, if bit 3 of flagsB is 1, Y1 would be used in &lt;br /&gt;
              the lower left corner of the quadrant, else Y0&lt;br /&gt;
        else (mode is non-zero)&lt;br /&gt;
          get the next 16 6-bit numbers from the stream as the 16 &lt;br /&gt;
            luminance samples for the quadrant, thus consuming 96 bits, &lt;br /&gt;
            or 12 bytes from the stream&lt;br /&gt;
 &lt;br /&gt;
      finally, output quadrant:&lt;br /&gt;
        bits 7-4 of the chrominance byte represent the Cr (or V) component&lt;br /&gt;
          while bits 3-0 represent the Cb (U) component&lt;br /&gt;
        convert the 16 luminance values and the 2 chrominance values to a &lt;br /&gt;
          proper YUV colorspace using the conversion tables in Appendix A&lt;br /&gt;
 &lt;br /&gt;
  if uniq flag is -1&lt;br /&gt;
    uniq flag = 0&lt;br /&gt;
&lt;br /&gt;
== Gradient Fill Patterns ==&lt;br /&gt;
&lt;br /&gt;
The ULTI codec has 11 gradient fill patterns for painting 4x4 sub blocks of luminance data using 4 luminance samples.&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 0: (0 degrees)&lt;br /&gt;
  Y0 Y1 Y2 Y3&lt;br /&gt;
  Y0 Y1 Y2 Y3&lt;br /&gt;
  Y0 Y1 Y2 Y3&lt;br /&gt;
  Y0 Y1 Y2 Y3&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 1: (22.5 degrees)&lt;br /&gt;
  Y1 Y2 Y3 Y3&lt;br /&gt;
  Y0 Y1 Y2 Y3&lt;br /&gt;
  Y0 Y1 Y2 Y3&lt;br /&gt;
  Y0 Y0 Y1 Y2&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 2: (45 degrees)&lt;br /&gt;
  Y1 Y2 Y3 Y3&lt;br /&gt;
  Y1 Y2 Y2 Y3&lt;br /&gt;
  Y0 Y1 Y1 Y2&lt;br /&gt;
  Y0 Y0 Y1 Y2&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 3: (67.5 degrees)&lt;br /&gt;
  Y2 Y3 Y3 Y3&lt;br /&gt;
  Y1 Y2 Y2 Y3&lt;br /&gt;
  Y0 Y1 Y1 Y2&lt;br /&gt;
  Y0 Y0 Y0 Y1&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 4: (90 degrees)&lt;br /&gt;
  Y3 Y3 Y3 Y3&lt;br /&gt;
  Y2 Y2 Y2 Y2&lt;br /&gt;
  Y1 Y1 Y1 Y1&lt;br /&gt;
  Y0 Y0 Y0 Y0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 5: (112.5 degrees)&lt;br /&gt;
  Y3 Y3 Y3 Y2&lt;br /&gt;
  Y3 Y2 Y2 Y1&lt;br /&gt;
  Y2 Y1 Y1 Y0&lt;br /&gt;
  Y1 Y0 Y0 Y0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 6: (135 degrees)&lt;br /&gt;
  Y3 Y3 Y2 Y2&lt;br /&gt;
  Y3 Y2 Y1 Y1&lt;br /&gt;
  Y2 Y2 Y1 Y0&lt;br /&gt;
  Y1 Y1 Y0 Y0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 7: (157.5 degrees)&lt;br /&gt;
  Y3 Y3 Y2 Y1&lt;br /&gt;
  Y3 Y2 Y1 Y0&lt;br /&gt;
  Y3 Y2 Y1 Y0&lt;br /&gt;
  Y2 Y1 Y0 Y0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern A: (homogeneous)&lt;br /&gt;
  Y0 Y0 Y0 Y0&lt;br /&gt;
  Y0 Y0 Y0 Y0&lt;br /&gt;
  Y0 Y0 Y0 Y0&lt;br /&gt;
  Y0 Y0 Y0 Y0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern B: (270 degrees)&lt;br /&gt;
  Y0 Y0 Y0 Y0&lt;br /&gt;
  Y1 Y1 Y1 Y1&lt;br /&gt;
  Y2 Y2 Y2 Y2&lt;br /&gt;
  Y3 Y3 Y3 Y3&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern C: (subsampled)&lt;br /&gt;
  Y0 Y0 Y1 Y1&lt;br /&gt;
  Y0 Y0 Y1 Y1&lt;br /&gt;
  Y2 Y2 Y3 Y3&lt;br /&gt;
  Y2 Y2 Y3 Y3&lt;br /&gt;
&lt;br /&gt;
== Converting Ultimotion Scaled YUV To Correct YUV ==&lt;br /&gt;
&lt;br /&gt;
To convert Ultimotion 6-bit luminance values to proper luminance samples, use the following conversion table:&lt;br /&gt;
&lt;br /&gt;
 unsigned char ulti_lumas[64] =&lt;br /&gt;
    { 0x10, 0x13, 0x17, 0x1A, 0x1E, 0x21, 0x25, 0x28,&lt;br /&gt;
      0x2C, 0x2F, 0x33, 0x36, 0x3A, 0x3D, 0x41, 0x44,&lt;br /&gt;
      0x48, 0x4B, 0x4F, 0x52, 0x56, 0x59, 0x5C, 0x60,&lt;br /&gt;
      0x63, 0x67, 0x6A, 0x6E, 0x71, 0x75, 0x78, 0x7C,&lt;br /&gt;
      0x7F, 0x83, 0x86, 0x8A, 0x8D, 0x91, 0x94, 0x98,&lt;br /&gt;
      0x9B, 0x9F, 0xA2, 0xA5, 0xA9, 0xAC, 0xB0, 0xB3,&lt;br /&gt;
      0xB7, 0xBA, 0xBE, 0xC1, 0xC5, 0xC8, 0xCC, 0xCF,&lt;br /&gt;
      0xD3, 0xD6, 0xDA, 0xDD, 0xE1, 0xE4, 0xE8, 0xEB};&lt;br /&gt;
      &lt;br /&gt;
To convert Ultimotion 4-bit chrominance values to proper chrominance samples, use the following conversion table:&lt;br /&gt;
&lt;br /&gt;
 unsigned char ulti_chromas[16] =&lt;br /&gt;
    { 0x60, 0x67, 0x6D, 0x73, 0x7A, 0x80, 0x86, 0x8D,&lt;br /&gt;
      0x93, 0x99, 0xA0, 0xA6, 0xAC, 0xB3, 0xB9, 0xC0};&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* [http://xanim.polter.net/ XAnim]&lt;br /&gt;
&lt;br /&gt;
* [http://mplayerhq.hu/cgi-bin/cvsweb.cgi/~checkout~/ffmpeg/libavcodec/ulti_cb.h?content-type=text/x-cvsweb-markup&amp;amp;cvsroot=FFMpeg Ultimotion Luminance Codebook]&lt;br /&gt;
&lt;br /&gt;
[[Category:Video Codecs]]&lt;/div&gt;</summary>
		<author><name>Ultimotion</name></author>
	</entry>
	<entry>
		<id>https://wiki.multimedia.cx/index.php?title=IBM_UltiMotion&amp;diff=6238</id>
		<title>IBM UltiMotion</title>
		<link rel="alternate" type="text/html" href="https://wiki.multimedia.cx/index.php?title=IBM_UltiMotion&amp;diff=6238"/>
		<updated>2006-10-12T19:41:54Z</updated>

		<summary type="html">&lt;p&gt;Ultimotion: /* Decoding Algorithm */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* FourCC: ULTI&lt;br /&gt;
* Company: [[IBM]]&lt;br /&gt;
* Official Description: [http://multimedia.cx/UMSPEC.ZIP Ultimotion Digital Video Data Stream Specification]&lt;br /&gt;
* Additional Documentation: [http://multimedia.cx/ultimotion-format.txt 'Description of the IBM UltiMotion (ULTI) Video Codec' by Mike Melanson and Konstantin Shishkov ].''&lt;br /&gt;
* Samples: [http://samples.mplayerhq.hu/V-codecs/ULTI/ http://samples.mplayerhq.hu/V-codecs/ULTI/]&lt;br /&gt;
* Codec: [http://hobbes.nmsu.edu/cgi-bin/h-viewer?sh=1&amp;amp;fname=/pub/windows/ultimo.zip Win32 Ultimotion decoder]&lt;br /&gt;
&lt;br /&gt;
IBM Ultimotion is a video codec typically seen in [[AVI]] files, though there is no reason it could not be used in other container formats.  Full codecs were available for Windows 3.1 (VfW), OS/2 and AIX.  It is primarily a vector quantizing algorithm with simple inter-frame coding (unchanged block).  Ultimotion encoding is significantly more computationally intensive than decoding.&lt;br /&gt;
&lt;br /&gt;
== Decoding Algorithm ==&lt;br /&gt;
&lt;br /&gt;
The Ultimotion algorithm operates natively on a scaled-down [[Raw YUV|YUV]] 4:1:0 planar colorspace. This means that for each 4x4 block of pixels (quadrant), each of the 16 pixels has a luminance (Y) sample and the entire block shares one chrominance sample (expressed as two color difference components : C&amp;lt;sub&amp;gt;b&amp;lt;/sub&amp;gt; (or U) and C&amp;lt;sub&amp;gt;r&amp;lt;/sub&amp;gt; (or V). The colorspace is actually non-linear quantized to fixed values from 2 tables. Indices into these tables (64 possible values for luminance and 16 for each chrominance component) are transmitted in the final bitstream.&lt;br /&gt;
&lt;br /&gt;
The Ultimotion algorithm codes a frame by dividing it into a series of 8x8 blocks. Each 8x8 block is subdivided and coded as 4 4x4 quadrants. The 4 quadrants, 0-3, are coded in the following arrangement:&lt;br /&gt;
&lt;br /&gt;
  0 3&lt;br /&gt;
  1 2&lt;br /&gt;
&lt;br /&gt;
Each block can be encoded using a single chrominance sample or unique chrominance sample for each quadrant. Each quadrant has 16 luminance samples that can be coded using a variety of methods.&lt;br /&gt;
&lt;br /&gt;
To decode a frame of Ultimotion data, follow this process:&lt;br /&gt;
&lt;br /&gt;
 initialize uniq and mode flags to 0&lt;br /&gt;
 &lt;br /&gt;
 for each 8x8 block in the frame, iterating from left -&amp;gt; right, top -&amp;gt; bottom:&lt;br /&gt;
 &lt;br /&gt;
  get the next byte in the stream (b0)&lt;br /&gt;
  if (b0 &amp;amp; 0xF8) == 0x70, handle escape code:&lt;br /&gt;
    if b0 is 0x70&lt;br /&gt;
      mode = next byte in stream&lt;br /&gt;
      note: only mode values of 0 or 1 are valid&lt;br /&gt;
    if b0 is 0x71&lt;br /&gt;
      uniq flag = -1 &lt;br /&gt;
    if b0 is 0x72&lt;br /&gt;
      toggle uniq flag (0/1)&lt;br /&gt;
    if b0 is 0x73&lt;br /&gt;
      end of frame, stop decoding&lt;br /&gt;
    if b0 is 0x74&lt;br /&gt;
      get the next byte in stream (b1)&lt;br /&gt;
      skip next (b1) blocks in the output frame (unchanged from previous frame)&lt;br /&gt;
 &lt;br /&gt;
  else&lt;br /&gt;
    if b0 is non-zero and uniq flag is 0&lt;br /&gt;
      chrominance byte = next byte from stream&lt;br /&gt;
 &lt;br /&gt;
    for each 4x4 quadrant in the block, arranged in the quadrant pattern:&lt;br /&gt;
 &lt;br /&gt;
      extract quadrant coding mode from b0:&lt;br /&gt;
        bits 7-6: quadrant 0 coding mode&lt;br /&gt;
        bits 5-4: quadrant 1 coding mode&lt;br /&gt;
        bits 3-2: quadrant 2 coding mode&lt;br /&gt;
        bits 1-0: quadrant 3 coding mode&lt;br /&gt;
 &lt;br /&gt;
      if coding mode is non-zero and uniq flag is non-zero&lt;br /&gt;
        chrominance byte = next byte from stream&lt;br /&gt;
 &lt;br /&gt;
      coding mode 0:&lt;br /&gt;
        skip quadrant (unchanged from the previous frame)&lt;br /&gt;
 &lt;br /&gt;
      coding mode 1:&lt;br /&gt;
        paint the luminance samples using a gradient pattern based on one &lt;br /&gt;
          6-bit sample coded in the stream&lt;br /&gt;
 &lt;br /&gt;
        get next byte from stream (b1)&lt;br /&gt;
        bits 7-6 of b1 indicate gradient fill pattern:&lt;br /&gt;
        bits 5-0 of b1 indicate luminance sample Y0&lt;br /&gt;
          0 = fill quadrant with Y0&lt;br /&gt;
          1 = gradient fill pattern 3&lt;br /&gt;
              Y1 = Y0, Y2 = Y0 + 1, Y3 = Y0 + 1&lt;br /&gt;
          2 = gradient fill pattern 5&lt;br /&gt;
              Y1 = Y0, Y2 = Y0 + 1, Y3 = Y0 + 1&lt;br /&gt;
          3 = gradient fill pattern 5&lt;br /&gt;
              Y3 = Y0, Y2 = Y0, Y1 = Y0 + 1, Y0 = Y0 + 1&lt;br /&gt;
        fill luminance samples according to Y0..Y3 and the gradient fill &lt;br /&gt;
          pattern (see section Gradient Fill Patterns)&lt;br /&gt;
 &lt;br /&gt;
      coding mode 2:&lt;br /&gt;
        paint the luminance samples using a gradient pattern based on &lt;br /&gt;
          either 4 6-bit samples coded in the stream or 4 6-bit samples &lt;br /&gt;
          retrieved from a 16,384-entry codebook using an index coded in &lt;br /&gt;
          the stream&lt;br /&gt;
        if mode is 0&lt;br /&gt;
          get the next 2 bytes from the stream as a big endian 16-bit &lt;br /&gt;
            number:&lt;br /&gt;
          gradient fill pattern = bits 15-12&lt;br /&gt;
          luminance codebook index = bits 11-0&lt;br /&gt;
          Y0..Y3 are set according to the codebook entry (see References &lt;br /&gt;
            for Ultimotion luminance codebook)&lt;br /&gt;
          if bit 3 of the gradient fill pattern is set, swap Y0 with Y3 &lt;br /&gt;
            and Y1 with Y2; clear bit 3 of the gradient fill pattern&lt;br /&gt;
          fill luminance samples according to Y0..Y3 and the gradient fill &lt;br /&gt;
            pattern (see section Gradient Fill Patterns)&lt;br /&gt;
        else (mode is non-zero)&lt;br /&gt;
          get the next 3 bytes from the stream as a big endian 24-bit &lt;br /&gt;
            number:&lt;br /&gt;
          Y0 = bits 23-18&lt;br /&gt;
          Y1 = bits 17-12&lt;br /&gt;
          Y2 = bits 11-6&lt;br /&gt;
          Y3 = bits 5-0&lt;br /&gt;
          fill luminance samples according to Y0..Y3 and gradient fill &lt;br /&gt;
            pattern 8 (see section Gradient Fill Patterns)&lt;br /&gt;
 &lt;br /&gt;
      coding mode 3:&lt;br /&gt;
        flexible coding mode that can paint the luminance samples with 16 &lt;br /&gt;
          6-bit samples coded in the stream, or with a gradient fill &lt;br /&gt;
          pattern and 4 6-bit luminance samples coded in the stream, or &lt;br /&gt;
          with an arbitrary pattern using 2 luminance samples and a set of &lt;br /&gt;
          flags coded in the stream&lt;br /&gt;
        if mode is 0&lt;br /&gt;
          get the next byte in the stream (b1)&lt;br /&gt;
          if bit 7 of b1 is set&lt;br /&gt;
            gradient fill pattern = bits 6-4 of b1&lt;br /&gt;
            get the next byte in the stream (b1)&lt;br /&gt;
            Y0 = ((b1 &amp;amp; 0x0F) &amp;lt;&amp;lt; 2) | (b1 &amp;gt;&amp;gt; 6)&lt;br /&gt;
            Y1 = bits 5-0 of b1&lt;br /&gt;
            Y2 = next byte in stream &amp;amp; 0x3F&lt;br /&gt;
            Y3 = next byte in stream &amp;amp; 0x3F&lt;br /&gt;
            fill luminance samples according to Y0..Y3 and the gradient &lt;br /&gt;
              fill pattern (see section Gradient Fill Patterns)&lt;br /&gt;
          else&lt;br /&gt;
            flagsA = b1&lt;br /&gt;
            flagsB = next byte in the stream&lt;br /&gt;
            Y0 = next byte in stream &amp;amp; 0x3F&lt;br /&gt;
            Y1 = next byte in stream &amp;amp; 0x3F&lt;br /&gt;
            the 16 bits between flagsA and flagsB represent the pattern &lt;br /&gt;
              used to place either Y0 or Y1 into the luminance grid&lt;br /&gt;
 &lt;br /&gt;
              A7 A6 A5 A4&lt;br /&gt;
              A3 A2 A1 A0&lt;br /&gt;
              B7 B6 B5 B4&lt;br /&gt;
              B3 B2 B1 B0&lt;br /&gt;
 &lt;br /&gt;
              for example, if bit 3 of flagsB is 1, Y1 would be used in &lt;br /&gt;
              the lower left corner of the quadrant, else Y0&lt;br /&gt;
        else (mode is non-zero)&lt;br /&gt;
          get the next 16 6-bit numbers from the stream as the 16 &lt;br /&gt;
            luminance samples for the quadrant, thus consuming 96 bits, &lt;br /&gt;
            or 12 bytes from the stream&lt;br /&gt;
 &lt;br /&gt;
      finally, output quadrant:&lt;br /&gt;
        bits 7-4 of the chrominance byte represent the Cr (or V) component&lt;br /&gt;
          while bits 3-0 represent the Cb (U) component&lt;br /&gt;
        convert the 16 luminance values and the 2 chrominance values to a &lt;br /&gt;
          proper YUV colorspace using the conversion tables in Appendix A&lt;br /&gt;
 &lt;br /&gt;
  if uniq flag is -1&lt;br /&gt;
    uniq flag = 0&lt;br /&gt;
&lt;br /&gt;
== Gradient Fill Patterns ==&lt;br /&gt;
&lt;br /&gt;
The ULTI codec has 9 gradient fill patterns for painting 4x4 sub blocks of luminance data using 4 luminance samples.&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 0:&lt;br /&gt;
  0 1 2 3&lt;br /&gt;
  0 1 2 3&lt;br /&gt;
  0 1 2 3&lt;br /&gt;
  0 1 2 3&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 1:&lt;br /&gt;
  1 2 3 3&lt;br /&gt;
  0 1 2 3&lt;br /&gt;
  0 1 2 3&lt;br /&gt;
  0 0 1 2&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 2:&lt;br /&gt;
  1 2 3 3&lt;br /&gt;
  1 2 2 3&lt;br /&gt;
  0 1 1 2&lt;br /&gt;
  0 0 1 2&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 3:&lt;br /&gt;
  2 3 3 3&lt;br /&gt;
  1 2 2 3&lt;br /&gt;
  0 1 1 2&lt;br /&gt;
  0 0 0 1&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 4:&lt;br /&gt;
  3 3 3 3&lt;br /&gt;
  2 2 2 2&lt;br /&gt;
  1 1 1 1&lt;br /&gt;
  0 0 0 0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 5:&lt;br /&gt;
  3 3 3 2&lt;br /&gt;
  3 2 2 1&lt;br /&gt;
  2 1 1 0&lt;br /&gt;
  1 0 0 0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 6:&lt;br /&gt;
  3 3 2 2&lt;br /&gt;
  3 2 1 1&lt;br /&gt;
  2 2 1 0&lt;br /&gt;
  1 1 0 0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 7:&lt;br /&gt;
  3 3 2 1&lt;br /&gt;
  3 2 1 0&lt;br /&gt;
  3 2 1 0&lt;br /&gt;
  2 1 0 0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 8:&lt;br /&gt;
  0 0 1 1&lt;br /&gt;
  0 0 1 1&lt;br /&gt;
  2 2 3 3&lt;br /&gt;
  2 2 3 3&lt;br /&gt;
&lt;br /&gt;
== Converting Ultimotion Scaled YUV To Correct YUV ==&lt;br /&gt;
&lt;br /&gt;
To convert Ultimotion 6-bit luminance values to proper luminance samples, use the following conversion table:&lt;br /&gt;
&lt;br /&gt;
 unsigned char ulti_lumas[64] =&lt;br /&gt;
    { 0x10, 0x13, 0x17, 0x1A, 0x1E, 0x21, 0x25, 0x28,&lt;br /&gt;
      0x2C, 0x2F, 0x33, 0x36, 0x3A, 0x3D, 0x41, 0x44,&lt;br /&gt;
      0x48, 0x4B, 0x4F, 0x52, 0x56, 0x59, 0x5C, 0x60,&lt;br /&gt;
      0x63, 0x67, 0x6A, 0x6E, 0x71, 0x75, 0x78, 0x7C,&lt;br /&gt;
      0x7F, 0x83, 0x86, 0x8A, 0x8D, 0x91, 0x94, 0x98,&lt;br /&gt;
      0x9B, 0x9F, 0xA2, 0xA5, 0xA9, 0xAC, 0xB0, 0xB3,&lt;br /&gt;
      0xB7, 0xBA, 0xBE, 0xC1, 0xC5, 0xC8, 0xCC, 0xCF,&lt;br /&gt;
      0xD3, 0xD6, 0xDA, 0xDD, 0xE1, 0xE4, 0xE8, 0xEB};&lt;br /&gt;
      &lt;br /&gt;
To convert Ultimotion 4-bit chrominance values to proper chrominance samples, use the following conversion table:&lt;br /&gt;
&lt;br /&gt;
 unsigned char ulti_chromas[16] =&lt;br /&gt;
    { 0x60, 0x67, 0x6D, 0x73, 0x7A, 0x80, 0x86, 0x8D,&lt;br /&gt;
      0x93, 0x99, 0xA0, 0xA6, 0xAC, 0xB3, 0xB9, 0xC0};&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* [http://xanim.polter.net/ XAnim]&lt;br /&gt;
&lt;br /&gt;
* [http://mplayerhq.hu/cgi-bin/cvsweb.cgi/~checkout~/ffmpeg/libavcodec/ulti_cb.h?content-type=text/x-cvsweb-markup&amp;amp;cvsroot=FFMpeg Ultimotion Luminance Codebook]&lt;br /&gt;
&lt;br /&gt;
[[Category:Video Codecs]]&lt;/div&gt;</summary>
		<author><name>Ultimotion</name></author>
	</entry>
	<entry>
		<id>https://wiki.multimedia.cx/index.php?title=IBM_UltiMotion&amp;diff=6237</id>
		<title>IBM UltiMotion</title>
		<link rel="alternate" type="text/html" href="https://wiki.multimedia.cx/index.php?title=IBM_UltiMotion&amp;diff=6237"/>
		<updated>2006-10-12T19:29:44Z</updated>

		<summary type="html">&lt;p&gt;Ultimotion: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* FourCC: ULTI&lt;br /&gt;
* Company: [[IBM]]&lt;br /&gt;
* Official Description: [http://multimedia.cx/UMSPEC.ZIP Ultimotion Digital Video Data Stream Specification]&lt;br /&gt;
* Additional Documentation: [http://multimedia.cx/ultimotion-format.txt 'Description of the IBM UltiMotion (ULTI) Video Codec' by Mike Melanson and Konstantin Shishkov ].''&lt;br /&gt;
* Samples: [http://samples.mplayerhq.hu/V-codecs/ULTI/ http://samples.mplayerhq.hu/V-codecs/ULTI/]&lt;br /&gt;
* Codec: [http://hobbes.nmsu.edu/cgi-bin/h-viewer?sh=1&amp;amp;fname=/pub/windows/ultimo.zip Win32 Ultimotion decoder]&lt;br /&gt;
&lt;br /&gt;
IBM Ultimotion is a video codec typically seen in [[AVI]] files, though there is no reason it could not be used in other container formats.  Full codecs were available for Windows 3.1 (VfW), OS/2 and AIX.  It is primarily a vector quantizing algorithm with simple inter-frame coding (unchanged block).  Ultimotion encoding is significantly more computationally intensive than decoding.&lt;br /&gt;
&lt;br /&gt;
== Decoding Algorithm ==&lt;br /&gt;
&lt;br /&gt;
The Ultimotion algorithm operates natively on a scaled-down [[Raw YUV|YUV]] 4:1:0 planar colorspace. This means that for each 4x4 block of pixels (quadrant), each of the 16 pixels has a luminance (Y) sample and the entire block shares one chrominance sample (expressed as two color difference components : C&amp;lt;sub&amp;gt;b&amp;lt;/sub&amp;gt; (or U) and C&amp;lt;sub&amp;gt;r&amp;lt;/sub&amp;gt; (or V). The colorspace is actually non-linear quantized to fixed values from 2 tables. Indices into these tables (64 possible values for luminance and 16 for each chrominance component) are transmitted in the final bitstream.&lt;br /&gt;
&lt;br /&gt;
The Ultimotion algorithm codes a frame by dividing it into a series of 8x8 blocks. Each 8x8 block is subdivided and coded as 4 4x4 quadrants. The 4 quadrants, 0-3, are coded in the following arrangement:&lt;br /&gt;
&lt;br /&gt;
  0 3&lt;br /&gt;
  1 2&lt;br /&gt;
&lt;br /&gt;
Each block can be encoded using a single chrominance sample or unique chrominance sample for each quadrant. Each quadrant has 16 luminance samples that can be coded using a variety of methods.&lt;br /&gt;
&lt;br /&gt;
To decode a frame of Ultimotion data, follow this process:&lt;br /&gt;
&lt;br /&gt;
 initialize uniq and mode flags to 0&lt;br /&gt;
 &lt;br /&gt;
 for each 8x8 block in the frame, iterating from left -&amp;gt; right, top -&amp;gt; bottom:&lt;br /&gt;
 &lt;br /&gt;
  get the next byte in the stream (b0)&lt;br /&gt;
  if (b0 &amp;amp; 0xF8) == 0x70, handle escape code:&lt;br /&gt;
    if b0 is 0x70&lt;br /&gt;
      mode = next byte in stream&lt;br /&gt;
      note: only mode values of 0 or 1 are valid&lt;br /&gt;
    if b0 is 0x71&lt;br /&gt;
      uniq flag = -1 &lt;br /&gt;
    if b0 is 0x72&lt;br /&gt;
      toggle uniq flag (0/1)&lt;br /&gt;
    if b0 is 0x73&lt;br /&gt;
      end of frame, stop decoding&lt;br /&gt;
    if b0 is 0x74&lt;br /&gt;
      get the next byte in stream (b1)&lt;br /&gt;
      skip next (b1) blocks in the output frame (unchanged from previous frame)&lt;br /&gt;
 &lt;br /&gt;
  else&lt;br /&gt;
    if b0 is non-zero and uniq flag is 0&lt;br /&gt;
      chrominance byte = next byte from stream&lt;br /&gt;
 &lt;br /&gt;
    for each 4x4 quadrant in the block, arranged in the quadrant pattern:&lt;br /&gt;
 &lt;br /&gt;
      extract quadrant coding mode from b0:&lt;br /&gt;
        bits 7-6: quadrant 0 coding mode&lt;br /&gt;
        bits 5-4: quadrant 1 coding mode&lt;br /&gt;
        bits 3-2: quadrant 2 coding mode&lt;br /&gt;
        bits 1-0: quadrant 3 coding mode&lt;br /&gt;
 &lt;br /&gt;
      if coding mode is non-zero and uniq flag is non-zero&lt;br /&gt;
        chrominance byte = next byte from stream&lt;br /&gt;
 &lt;br /&gt;
      coding mode 0:&lt;br /&gt;
        skip quadrant (unchanged from the previous frame)&lt;br /&gt;
 &lt;br /&gt;
      coding mode 1:&lt;br /&gt;
        paint the luminance samples using a gradient pattern based on one &lt;br /&gt;
          6-bit sample coded in the stream&lt;br /&gt;
 &lt;br /&gt;
        get next byte from stream (b1)&lt;br /&gt;
        bits 7-6 of b1 indicate gradient fill pattern:&lt;br /&gt;
          0 = gradient fill pattern 0&lt;br /&gt;
          1 = gradient fill pattern 2&lt;br /&gt;
          2 = gradient fill pattern 6&lt;br /&gt;
          3 = gradient fill pattern 4, swap Y0 with Y3 and Y1 with Y2 &lt;br /&gt;
              after unpacking Y samples&lt;br /&gt;
        bits 5-0 of b1 indicate luminance sample Y0&lt;br /&gt;
        Y1 = Y0&lt;br /&gt;
        if gradient fill pattern is pattern 0&lt;br /&gt;
          Y2 = Y0 + 1 (saturated to an upper limit of 0x3F)&lt;br /&gt;
          Y3 = Y2&lt;br /&gt;
        else&lt;br /&gt;
          Y2 = Y3 = Y0&lt;br /&gt;
        fill luminance samples according to Y0..Y3 and the gradient fill &lt;br /&gt;
          pattern (see section Gradient Fill Patterns)&lt;br /&gt;
 &lt;br /&gt;
      coding mode 2:&lt;br /&gt;
        paint the luminance samples using a gradient pattern based on &lt;br /&gt;
          either 4 6-bit samples coded in the stream or 4 6-bit samples &lt;br /&gt;
          retrieved from a 16,384-entry codebook using an index coded in &lt;br /&gt;
          the stream&lt;br /&gt;
        if mode is 0&lt;br /&gt;
          get the next 2 bytes from the stream as a big endian 16-bit &lt;br /&gt;
            number:&lt;br /&gt;
          gradient fill pattern = bits 15-12&lt;br /&gt;
          luminance codebook index = bits 11-0&lt;br /&gt;
          Y0..Y3 are set according to the codebook entry (see References &lt;br /&gt;
            for Ultimotion luminance codebook)&lt;br /&gt;
          if bit 3 of the gradient fill pattern is set, swap Y0 with Y3 &lt;br /&gt;
            and Y1 with Y2; clear bit 3 of the gradient fill pattern&lt;br /&gt;
          fill luminance samples according to Y0..Y3 and the gradient fill &lt;br /&gt;
            pattern (see section Gradient Fill Patterns)&lt;br /&gt;
        else (mode is non-zero)&lt;br /&gt;
          get the next 3 bytes from the stream as a big endian 24-bit &lt;br /&gt;
            number:&lt;br /&gt;
          Y0 = bits 23-18&lt;br /&gt;
          Y1 = bits 17-12&lt;br /&gt;
          Y2 = bits 11-6&lt;br /&gt;
          Y3 = bits 5-0&lt;br /&gt;
          fill luminance samples according to Y0..Y3 and gradient fill &lt;br /&gt;
            pattern 8 (see section Gradient Fill Patterns)&lt;br /&gt;
 &lt;br /&gt;
      coding mode 3:&lt;br /&gt;
        flexible coding mode that can paint the luminance samples with 16 &lt;br /&gt;
          6-bit samples coded in the stream, or with a gradient fill &lt;br /&gt;
          pattern and 4 6-bit luminance samples coded in the stream, or &lt;br /&gt;
          with an arbitrary pattern using 2 luminance samples and a set of &lt;br /&gt;
          flags coded in the stream&lt;br /&gt;
        if mode is 0&lt;br /&gt;
          get the next byte in the stream (b1)&lt;br /&gt;
          if bit 7 of b1 is set&lt;br /&gt;
            gradient fill pattern = bits 6-4 of b1&lt;br /&gt;
            get the next byte in the stream (b1)&lt;br /&gt;
            Y0 = ((b1 &amp;amp; 0x0F) &amp;lt;&amp;lt; 2) | (b1 &amp;gt;&amp;gt; 6)&lt;br /&gt;
            Y1 = bits 5-0 of b1&lt;br /&gt;
            Y2 = next byte in stream &amp;amp; 0x3F&lt;br /&gt;
            Y3 = next byte in stream &amp;amp; 0x3F&lt;br /&gt;
            fill luminance samples according to Y0..Y3 and the gradient &lt;br /&gt;
              fill pattern (see section Gradient Fill Patterns)&lt;br /&gt;
          else&lt;br /&gt;
            flagsA = b1&lt;br /&gt;
            flagsB = next byte in the stream&lt;br /&gt;
            Y0 = next byte in stream &amp;amp; 0x3F&lt;br /&gt;
            Y1 = next byte in stream &amp;amp; 0x3F&lt;br /&gt;
            the 16 bits between flagsA and flagsB represent the pattern &lt;br /&gt;
              used to place either Y0 or Y1 into the luminance grid&lt;br /&gt;
 &lt;br /&gt;
              A7 A6 A5 A4&lt;br /&gt;
              A3 A2 A1 A0&lt;br /&gt;
              B7 B6 B5 B4&lt;br /&gt;
              B3 B2 B1 B0&lt;br /&gt;
 &lt;br /&gt;
              for example, if bit 3 of flagsB is 1, Y1 would be used in &lt;br /&gt;
              the lower left corner of the quadrant, else Y0&lt;br /&gt;
        else (mode is non-zero)&lt;br /&gt;
          get the next 16 6-bit numbers from the stream as the 16 &lt;br /&gt;
            luminance samples for the quadrant, thus consuming 96 bits, &lt;br /&gt;
            or 12 bytes from the stream&lt;br /&gt;
 &lt;br /&gt;
      finally, output quadrant:&lt;br /&gt;
        bits 7-4 of the chrominance byte represent the Cr (or V) component&lt;br /&gt;
          while bits 3-0 represent the Cb (U) component&lt;br /&gt;
        convert the 16 luminance values and the 2 chrominance values to a &lt;br /&gt;
          proper YUV colorspace using the conversion tables in Appendix A&lt;br /&gt;
 &lt;br /&gt;
  if uniq flag is -1&lt;br /&gt;
    uniq flag = 0&lt;br /&gt;
&lt;br /&gt;
== Gradient Fill Patterns ==&lt;br /&gt;
&lt;br /&gt;
The ULTI codec has 9 gradient fill patterns for painting 4x4 sub blocks of luminance data using 4 luminance samples.&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 0:&lt;br /&gt;
  0 1 2 3&lt;br /&gt;
  0 1 2 3&lt;br /&gt;
  0 1 2 3&lt;br /&gt;
  0 1 2 3&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 1:&lt;br /&gt;
  1 2 3 3&lt;br /&gt;
  0 1 2 3&lt;br /&gt;
  0 1 2 3&lt;br /&gt;
  0 0 1 2&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 2:&lt;br /&gt;
  1 2 3 3&lt;br /&gt;
  1 2 2 3&lt;br /&gt;
  0 1 1 2&lt;br /&gt;
  0 0 1 2&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 3:&lt;br /&gt;
  2 3 3 3&lt;br /&gt;
  1 2 2 3&lt;br /&gt;
  0 1 1 2&lt;br /&gt;
  0 0 0 1&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 4:&lt;br /&gt;
  3 3 3 3&lt;br /&gt;
  2 2 2 2&lt;br /&gt;
  1 1 1 1&lt;br /&gt;
  0 0 0 0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 5:&lt;br /&gt;
  3 3 3 2&lt;br /&gt;
  3 2 2 1&lt;br /&gt;
  2 1 1 0&lt;br /&gt;
  1 0 0 0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 6:&lt;br /&gt;
  3 3 2 2&lt;br /&gt;
  3 2 1 1&lt;br /&gt;
  2 2 1 0&lt;br /&gt;
  1 1 0 0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 7:&lt;br /&gt;
  3 3 2 1&lt;br /&gt;
  3 2 1 0&lt;br /&gt;
  3 2 1 0&lt;br /&gt;
  2 1 0 0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 8:&lt;br /&gt;
  0 0 1 1&lt;br /&gt;
  0 0 1 1&lt;br /&gt;
  2 2 3 3&lt;br /&gt;
  2 2 3 3&lt;br /&gt;
&lt;br /&gt;
== Converting Ultimotion Scaled YUV To Correct YUV ==&lt;br /&gt;
&lt;br /&gt;
To convert Ultimotion 6-bit luminance values to proper luminance samples, use the following conversion table:&lt;br /&gt;
&lt;br /&gt;
 unsigned char ulti_lumas[64] =&lt;br /&gt;
    { 0x10, 0x13, 0x17, 0x1A, 0x1E, 0x21, 0x25, 0x28,&lt;br /&gt;
      0x2C, 0x2F, 0x33, 0x36, 0x3A, 0x3D, 0x41, 0x44,&lt;br /&gt;
      0x48, 0x4B, 0x4F, 0x52, 0x56, 0x59, 0x5C, 0x60,&lt;br /&gt;
      0x63, 0x67, 0x6A, 0x6E, 0x71, 0x75, 0x78, 0x7C,&lt;br /&gt;
      0x7F, 0x83, 0x86, 0x8A, 0x8D, 0x91, 0x94, 0x98,&lt;br /&gt;
      0x9B, 0x9F, 0xA2, 0xA5, 0xA9, 0xAC, 0xB0, 0xB3,&lt;br /&gt;
      0xB7, 0xBA, 0xBE, 0xC1, 0xC5, 0xC8, 0xCC, 0xCF,&lt;br /&gt;
      0xD3, 0xD6, 0xDA, 0xDD, 0xE1, 0xE4, 0xE8, 0xEB};&lt;br /&gt;
      &lt;br /&gt;
To convert Ultimotion 4-bit chrominance values to proper chrominance samples, use the following conversion table:&lt;br /&gt;
&lt;br /&gt;
 unsigned char ulti_chromas[16] =&lt;br /&gt;
    { 0x60, 0x67, 0x6D, 0x73, 0x7A, 0x80, 0x86, 0x8D,&lt;br /&gt;
      0x93, 0x99, 0xA0, 0xA6, 0xAC, 0xB3, 0xB9, 0xC0};&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* [http://xanim.polter.net/ XAnim]&lt;br /&gt;
&lt;br /&gt;
* [http://mplayerhq.hu/cgi-bin/cvsweb.cgi/~checkout~/ffmpeg/libavcodec/ulti_cb.h?content-type=text/x-cvsweb-markup&amp;amp;cvsroot=FFMpeg Ultimotion Luminance Codebook]&lt;br /&gt;
&lt;br /&gt;
[[Category:Video Codecs]]&lt;/div&gt;</summary>
		<author><name>Ultimotion</name></author>
	</entry>
	<entry>
		<id>https://wiki.multimedia.cx/index.php?title=IBM_UltiMotion&amp;diff=6220</id>
		<title>IBM UltiMotion</title>
		<link rel="alternate" type="text/html" href="https://wiki.multimedia.cx/index.php?title=IBM_UltiMotion&amp;diff=6220"/>
		<updated>2006-10-11T20:06:57Z</updated>

		<summary type="html">&lt;p&gt;Ultimotion: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;''This page is based on the document 'Description of the IBM UltiMotion (ULTI) Video Codec' by Mike Melanson and Konstantin Shishkov found at [http://multimedia.cx/ultimotion-format.txt http://multimedia.cx/ultimotion-format.txt].''&lt;br /&gt;
&lt;br /&gt;
* FourCC: ULTI&lt;br /&gt;
* Company: [[IBM]]&lt;br /&gt;
* Official Description: [http://multimedia.cx/UMSPEC.ZIP http://multimedia.cx/UMSPEC.ZIP]&lt;br /&gt;
* Samples: [http://samples.mplayerhq.hu/V-codecs/ULTI/ http://samples.mplayerhq.hu/V-codecs/ULTI/]&lt;br /&gt;
* Codec: [http://hobbes.nmsu.edu/cgi-bin/h-viewer?sh=1&amp;amp;fname=/pub/windows/ultimo.zip Win32 Ultimotion decoder]&lt;br /&gt;
&lt;br /&gt;
IBM UltiMotion (henceforth ULTI) is a video codec typically seen in [[AVI]] files, though there is no reason it could not be used in other container formats. &lt;br /&gt;
&lt;br /&gt;
== Decoding Algorithm ==&lt;br /&gt;
&lt;br /&gt;
The ULTI algorithm operates natively on a scaled-down [[Raw YUV|YUV]] 4:1:0 planar colorspace. This means that for each 4x4 block of pixels (quadrant), each of the 16 pixels has a luminance (Y) sample and the entire block shares one chrominance sample (expressed as two color difference components : C&amp;lt;sub&amp;gt;b&amp;lt;/sub&amp;gt; (or U) and C&amp;lt;sub&amp;gt;r&amp;lt;/sub&amp;gt; (or V). The colorspace is actually non-linear quantized to fixed values from 2 tables. Indices into these tables (64 possible values for luminance and 16 for each chrominance component) are transmitted in the final bitstream.&lt;br /&gt;
&lt;br /&gt;
The ULTI algorithm codes a frame by dividing it into a series of 8x8 blocks. Each 8x8 block is subdivided and coded as 4 4x4 quadrants. The 4 quadrants, 0-3, are coded in the following arrangement:&lt;br /&gt;
&lt;br /&gt;
  0 3&lt;br /&gt;
  1 2&lt;br /&gt;
&lt;br /&gt;
Each block can be encoded using a single chrominance sample or unique chrominance sample for each quadrant. Each quadrant has 16 luminance samples that can be coded using a variety of methods.&lt;br /&gt;
&lt;br /&gt;
To decode a frame of UltiMotion data, follow this process:&lt;br /&gt;
&lt;br /&gt;
 initialize uniq and mode flags to 0&lt;br /&gt;
 &lt;br /&gt;
 for each 8x8 block in the frame, iterating from left -&amp;gt; right, top -&amp;gt; bottom:&lt;br /&gt;
 &lt;br /&gt;
  get the next byte in the stream (b0)&lt;br /&gt;
  if (b0 &amp;amp; 0xF8) == 0x70, handle escape code:&lt;br /&gt;
    if b0 is 0x70&lt;br /&gt;
      mode = next byte in stream&lt;br /&gt;
      note: only mode values of 0 or 1 are valid&lt;br /&gt;
    if b0 is 0x71&lt;br /&gt;
      uniq flag = -1 &lt;br /&gt;
    if b0 is 0x72&lt;br /&gt;
      toggle uniq flag (0/1)&lt;br /&gt;
    if b0 is 0x73&lt;br /&gt;
      end of frame, stop decoding&lt;br /&gt;
    if b0 is 0x74&lt;br /&gt;
      get the next byte in stream (b1)&lt;br /&gt;
      skip next (b1) blocks in the output frame (unchanged from previous frame)&lt;br /&gt;
 &lt;br /&gt;
  else&lt;br /&gt;
    if b0 is non-zero and uniq flag is 0&lt;br /&gt;
      chrominance byte = next byte from stream&lt;br /&gt;
 &lt;br /&gt;
    for each 4x4 quadrant in the block, arranged in the quadrant pattern:&lt;br /&gt;
 &lt;br /&gt;
      extract quadrant coding mode from b0:&lt;br /&gt;
        bits 7-6: quadrant 0 coding mode&lt;br /&gt;
        bits 5-4: quadrant 1 coding mode&lt;br /&gt;
        bits 3-2: quadrant 2 coding mode&lt;br /&gt;
        bits 1-0: quadrant 3 coding mode&lt;br /&gt;
 &lt;br /&gt;
      if coding mode is non-zero and uniq flag is non-zero&lt;br /&gt;
        chrominance byte = next byte from stream&lt;br /&gt;
 &lt;br /&gt;
      coding mode 0:&lt;br /&gt;
        skip quadrant (unchanged from the previous frame)&lt;br /&gt;
 &lt;br /&gt;
      coding mode 1:&lt;br /&gt;
        paint the luminance samples using a gradient pattern based on one &lt;br /&gt;
          6-bit sample coded in the stream&lt;br /&gt;
 &lt;br /&gt;
        get next byte from stream (b1)&lt;br /&gt;
        bits 7-6 of b1 indicate gradient fill pattern:&lt;br /&gt;
          0 = gradient fill pattern 0&lt;br /&gt;
          1 = gradient fill pattern 2&lt;br /&gt;
          2 = gradient fill pattern 6&lt;br /&gt;
          3 = gradient fill pattern 4, swap Y0 with Y3 and Y1 with Y2 &lt;br /&gt;
              after unpacking Y samples&lt;br /&gt;
        bits 5-0 of b1 indicate luminance sample Y0&lt;br /&gt;
        Y1 = Y0&lt;br /&gt;
        if gradient fill pattern is pattern 0&lt;br /&gt;
          Y2 = Y0 + 1 (saturated to an upper limit of 0x3F)&lt;br /&gt;
          Y3 = Y2&lt;br /&gt;
        else&lt;br /&gt;
          Y2 = Y3 = Y0&lt;br /&gt;
        fill luminance samples according to Y0..Y3 and the gradient fill &lt;br /&gt;
          pattern (see section Gradient Fill Patterns)&lt;br /&gt;
 &lt;br /&gt;
      coding mode 2:&lt;br /&gt;
        paint the luminance samples using a gradient pattern based on &lt;br /&gt;
          either 4 6-bit samples coded in the stream or 4 6-bit samples &lt;br /&gt;
          retrieved from a 16,384-entry codebook using an index coded in &lt;br /&gt;
          the stream&lt;br /&gt;
        if mode is 0&lt;br /&gt;
          get the next 2 bytes from the stream as a big endian 16-bit &lt;br /&gt;
            number:&lt;br /&gt;
          gradient fill pattern = bits 15-12&lt;br /&gt;
          luminance codebook index = bits 11-0&lt;br /&gt;
          Y0..Y3 are set according to the codebook entry (see References &lt;br /&gt;
            for UltiMotion luminance codebook)&lt;br /&gt;
          if bit 3 of the gradient fill pattern is set, swap Y0 with Y3 &lt;br /&gt;
            and Y1 with Y2; clear bit 3 of the gradient fill pattern&lt;br /&gt;
          fill luminance samples according to Y0..Y3 and the gradient fill &lt;br /&gt;
            pattern (see section Gradient Fill Patterns)&lt;br /&gt;
        else (mode is non-zero)&lt;br /&gt;
          get the next 3 bytes from the stream as a big endian 24-bit &lt;br /&gt;
            number:&lt;br /&gt;
          Y0 = bits 23-18&lt;br /&gt;
          Y1 = bits 17-12&lt;br /&gt;
          Y2 = bits 11-6&lt;br /&gt;
          Y3 = bits 5-0&lt;br /&gt;
          fill luminance samples according to Y0..Y3 and gradient fill &lt;br /&gt;
            pattern 8 (see section Gradient Fill Patterns)&lt;br /&gt;
 &lt;br /&gt;
      coding mode 3:&lt;br /&gt;
        flexible coding mode that can paint the luminance samples with 16 &lt;br /&gt;
          6-bit samples coded in the stream, or with a gradient fill &lt;br /&gt;
          pattern and 4 6-bit luminance samples coded in the stream, or &lt;br /&gt;
          with an arbitrary pattern using 2 luminance samples and a set of &lt;br /&gt;
          flags coded in the stream&lt;br /&gt;
        if mode is 0&lt;br /&gt;
          get the next byte in the stream (b1)&lt;br /&gt;
          if bit 7 of b1 is set&lt;br /&gt;
            gradient fill pattern = bits 6-4 of b1&lt;br /&gt;
            get the next byte in the stream (b1)&lt;br /&gt;
            Y0 = ((b1 &amp;amp; 0x0F) &amp;lt;&amp;lt; 2) | (b1 &amp;gt;&amp;gt; 6)&lt;br /&gt;
            Y1 = bits 5-0 of b1&lt;br /&gt;
            Y2 = next byte in stream &amp;amp; 0x3F&lt;br /&gt;
            Y3 = next byte in stream &amp;amp; 0x3F&lt;br /&gt;
            fill luminance samples according to Y0..Y3 and the gradient &lt;br /&gt;
              fill pattern (see section Gradient Fill Patterns)&lt;br /&gt;
          else&lt;br /&gt;
            flagsA = b1&lt;br /&gt;
            flagsB = next byte in the stream&lt;br /&gt;
            Y0 = next byte in stream &amp;amp; 0x3F&lt;br /&gt;
            Y1 = next byte in stream &amp;amp; 0x3F&lt;br /&gt;
            the 16 bits between flagsA and flagsB represent the pattern &lt;br /&gt;
              used to place either Y0 or Y1 into the luminance grid&lt;br /&gt;
 &lt;br /&gt;
              A7 A6 A5 A4&lt;br /&gt;
              A3 A2 A1 A0&lt;br /&gt;
              B7 B6 B5 B4&lt;br /&gt;
              B3 B2 B1 B0&lt;br /&gt;
 &lt;br /&gt;
              for example, if bit 3 of flagsB is 1, Y1 would be used in &lt;br /&gt;
              the lower left corner of the quadrant, else Y0&lt;br /&gt;
        else (mode is non-zero)&lt;br /&gt;
          get the next 16 6-bit numbers from the stream as the 16 &lt;br /&gt;
            luminance samples for the quadrant, thus consuming 96 bits, &lt;br /&gt;
            or 12 bytes from the stream&lt;br /&gt;
 &lt;br /&gt;
      finally, output quadrant:&lt;br /&gt;
        bits 7-4 of the chrominance byte represent the Cr (or V) component&lt;br /&gt;
          while bits 3-0 represent the Cb (U) component&lt;br /&gt;
        convert the 16 luminance values and the 2 chrominance values to a &lt;br /&gt;
          proper YUV colorspace using the conversion tables in Appendix A&lt;br /&gt;
 &lt;br /&gt;
  if uniq flag is -1&lt;br /&gt;
    uniq flag = 0&lt;br /&gt;
&lt;br /&gt;
== Gradient Fill Patterns ==&lt;br /&gt;
&lt;br /&gt;
The ULTI codec has 9 gradient fill patterns for painting 4x4 sub blocks of luminance data using 4 luminance samples.&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 0:&lt;br /&gt;
  0 1 2 3&lt;br /&gt;
  0 1 2 3&lt;br /&gt;
  0 1 2 3&lt;br /&gt;
  0 1 2 3&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 1:&lt;br /&gt;
  1 2 3 3&lt;br /&gt;
  0 1 2 3&lt;br /&gt;
  0 1 2 3&lt;br /&gt;
  0 0 1 2&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 2:&lt;br /&gt;
  1 2 3 3&lt;br /&gt;
  1 2 2 3&lt;br /&gt;
  0 1 1 2&lt;br /&gt;
  0 0 1 2&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 3:&lt;br /&gt;
  2 3 3 3&lt;br /&gt;
  1 2 2 3&lt;br /&gt;
  0 1 1 2&lt;br /&gt;
  0 0 0 1&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 4:&lt;br /&gt;
  3 3 3 3&lt;br /&gt;
  2 2 2 2&lt;br /&gt;
  1 1 1 1&lt;br /&gt;
  0 0 0 0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 5:&lt;br /&gt;
  3 3 3 2&lt;br /&gt;
  3 2 2 1&lt;br /&gt;
  2 1 1 0&lt;br /&gt;
  1 0 0 0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 6:&lt;br /&gt;
  3 3 2 2&lt;br /&gt;
  3 2 1 1&lt;br /&gt;
  2 2 1 0&lt;br /&gt;
  1 1 0 0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 7:&lt;br /&gt;
  3 3 2 1&lt;br /&gt;
  3 2 1 0&lt;br /&gt;
  3 2 1 0&lt;br /&gt;
  2 1 0 0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 8:&lt;br /&gt;
  0 0 1 1&lt;br /&gt;
  0 0 1 1&lt;br /&gt;
  2 2 3 3&lt;br /&gt;
  2 2 3 3&lt;br /&gt;
&lt;br /&gt;
== Converting UltiMotion Scaled YUV To Correct YUV ==&lt;br /&gt;
&lt;br /&gt;
To convert UltiMotion 6-bit luminance values to proper luminance samples, use the following conversion table:&lt;br /&gt;
&lt;br /&gt;
 unsigned char ulti_lumas[64] =&lt;br /&gt;
    { 0x10, 0x13, 0x17, 0x1A, 0x1E, 0x21, 0x25, 0x28,&lt;br /&gt;
      0x2C, 0x2F, 0x33, 0x36, 0x3A, 0x3D, 0x41, 0x44,&lt;br /&gt;
      0x48, 0x4B, 0x4F, 0x52, 0x56, 0x59, 0x5C, 0x60,&lt;br /&gt;
      0x63, 0x67, 0x6A, 0x6E, 0x71, 0x75, 0x78, 0x7C,&lt;br /&gt;
      0x7F, 0x83, 0x86, 0x8A, 0x8D, 0x91, 0x94, 0x98,&lt;br /&gt;
      0x9B, 0x9F, 0xA2, 0xA5, 0xA9, 0xAC, 0xB0, 0xB3,&lt;br /&gt;
      0xB7, 0xBA, 0xBE, 0xC1, 0xC5, 0xC8, 0xCC, 0xCF,&lt;br /&gt;
      0xD3, 0xD6, 0xDA, 0xDD, 0xE1, 0xE4, 0xE8, 0xEB};&lt;br /&gt;
      &lt;br /&gt;
To convert UltiMotion 4-bit chrominance values to proper chrominance samples, use the following conversion table:&lt;br /&gt;
&lt;br /&gt;
 unsigned char ulti_chromas[16] =&lt;br /&gt;
    { 0x60, 0x67, 0x6D, 0x73, 0x7A, 0x80, 0x86, 0x8D,&lt;br /&gt;
      0x93, 0x99, 0xA0, 0xA6, 0xAC, 0xB3, 0xB9, 0xC0};&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* [http://xanim.polter.net/ XAnim]&lt;br /&gt;
&lt;br /&gt;
* [http://mplayerhq.hu/cgi-bin/cvsweb.cgi/~checkout~/ffmpeg/libavcodec/ulti_cb.h?content-type=text/x-cvsweb-markup&amp;amp;cvsroot=FFMpeg UltiMotion Luminance Codebook]&lt;br /&gt;
&lt;br /&gt;
[[Category:Video Codecs]]&lt;/div&gt;</summary>
		<author><name>Ultimotion</name></author>
	</entry>
	<entry>
		<id>https://wiki.multimedia.cx/index.php?title=IBM_UltiMotion&amp;diff=6219</id>
		<title>IBM UltiMotion</title>
		<link rel="alternate" type="text/html" href="https://wiki.multimedia.cx/index.php?title=IBM_UltiMotion&amp;diff=6219"/>
		<updated>2006-10-11T19:59:33Z</updated>

		<summary type="html">&lt;p&gt;Ultimotion: /* Decoding Algorithm */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;''This page is based on the document 'Description of the IBM UltiMotion (ULTI) Video Codec' by Mike Melanson and Konstantin Shishkov found at [http://multimedia.cx/ultimotion-format.txt http://multimedia.cx/ultimotion-format.txt].''&lt;br /&gt;
&lt;br /&gt;
* FourCC: ULTI&lt;br /&gt;
* Company: [[IBM]]&lt;br /&gt;
* Official Description: [http://multimedia.cx/UMSPEC.ZIP http://multimedia.cx/UMSPEC.ZIP]&lt;br /&gt;
* Samples: [http://samples.mplayerhq.hu/V-codecs/ULTI/ http://samples.mplayerhq.hu/V-codecs/ULTI/]&lt;br /&gt;
&lt;br /&gt;
IBM UltiMotion (henceforth ULTI) is a video codec typically seen in [[AVI]] files, though there is no reason it could not be used in other container formats. &lt;br /&gt;
&lt;br /&gt;
== Decoding Algorithm ==&lt;br /&gt;
&lt;br /&gt;
The ULTI algorithm operates natively on a scaled-down [[Raw YUV|YUV]] 4:1:0 planar colorspace. This means that for each 4x4 block of pixels (quadrant), each of the 16 pixels has a luminance (Y) sample and the entire block shares one chrominance sample (expressed as two color difference components : C&amp;lt;sub&amp;gt;b&amp;lt;/sub&amp;gt; (or U) and C&amp;lt;sub&amp;gt;r&amp;lt;/sub&amp;gt; (or V). The colorspace is actually non-linear quantized to fixed values from 2 tables. Indices into these tables (64 possible values for luminance and 16 for each chrominance component) are transmitted in the final bitstream.&lt;br /&gt;
&lt;br /&gt;
The ULTI algorithm codes a frame by dividing it into a series of 8x8 blocks. Each 8x8 block is subdivided and coded as 4 4x4 quadrants. The 4 quadrants, 0-3, are coded in the following arrangement:&lt;br /&gt;
&lt;br /&gt;
  0 3&lt;br /&gt;
  1 2&lt;br /&gt;
&lt;br /&gt;
Each block can be encoded using a single chrominance sample or unique chrominance sample for each quadrant. Each quadrant has 16 luminance samples that can be coded using a variety of methods.&lt;br /&gt;
&lt;br /&gt;
To decode a frame of UltiMotion data, follow this process:&lt;br /&gt;
&lt;br /&gt;
 initialize uniq and mode flags to 0&lt;br /&gt;
 &lt;br /&gt;
 for each 8x8 block in the frame, iterating from left -&amp;gt; right, top -&amp;gt; bottom:&lt;br /&gt;
 &lt;br /&gt;
  get the next byte in the stream (b0)&lt;br /&gt;
  if (b0 &amp;amp; 0xF8) == 0x70, handle escape code:&lt;br /&gt;
    if b0 is 0x70&lt;br /&gt;
      mode = next byte in stream&lt;br /&gt;
      note: only mode values of 0 or 1 are valid&lt;br /&gt;
    if b0 is 0x71&lt;br /&gt;
      uniq flag = -1 &lt;br /&gt;
    if b0 is 0x72&lt;br /&gt;
      toggle uniq flag (0/1)&lt;br /&gt;
    if b0 is 0x73&lt;br /&gt;
      end of frame, stop decoding&lt;br /&gt;
    if b0 is 0x74&lt;br /&gt;
      get the next byte in stream (b1)&lt;br /&gt;
      skip next (b1) blocks in the output frame (unchanged from previous frame)&lt;br /&gt;
 &lt;br /&gt;
  else&lt;br /&gt;
    if b0 is non-zero and uniq flag is 0&lt;br /&gt;
      chrominance byte = next byte from stream&lt;br /&gt;
 &lt;br /&gt;
    for each 4x4 quadrant in the block, arranged in the quadrant pattern:&lt;br /&gt;
 &lt;br /&gt;
      extract quadrant coding mode from b0:&lt;br /&gt;
        bits 7-6: quadrant 0 coding mode&lt;br /&gt;
        bits 5-4: quadrant 1 coding mode&lt;br /&gt;
        bits 3-2: quadrant 2 coding mode&lt;br /&gt;
        bits 1-0: quadrant 3 coding mode&lt;br /&gt;
 &lt;br /&gt;
      if coding mode is non-zero and uniq flag is non-zero&lt;br /&gt;
        chrominance byte = next byte from stream&lt;br /&gt;
 &lt;br /&gt;
      coding mode 0:&lt;br /&gt;
        skip quadrant (unchanged from the previous frame)&lt;br /&gt;
 &lt;br /&gt;
      coding mode 1:&lt;br /&gt;
        paint the luminance samples using a gradient pattern based on one &lt;br /&gt;
          6-bit sample coded in the stream&lt;br /&gt;
 &lt;br /&gt;
        get next byte from stream (b1)&lt;br /&gt;
        bits 7-6 of b1 indicate gradient fill pattern:&lt;br /&gt;
          0 = gradient fill pattern 0&lt;br /&gt;
          1 = gradient fill pattern 2&lt;br /&gt;
          2 = gradient fill pattern 6&lt;br /&gt;
          3 = gradient fill pattern 4, swap Y0 with Y3 and Y1 with Y2 &lt;br /&gt;
              after unpacking Y samples&lt;br /&gt;
        bits 5-0 of b1 indicate luminance sample Y0&lt;br /&gt;
        Y1 = Y0&lt;br /&gt;
        if gradient fill pattern is pattern 0&lt;br /&gt;
          Y2 = Y0 + 1 (saturated to an upper limit of 0x3F)&lt;br /&gt;
          Y3 = Y2&lt;br /&gt;
        else&lt;br /&gt;
          Y2 = Y3 = Y0&lt;br /&gt;
        fill luminance samples according to Y0..Y3 and the gradient fill &lt;br /&gt;
          pattern (see section Gradient Fill Patterns)&lt;br /&gt;
 &lt;br /&gt;
      coding mode 2:&lt;br /&gt;
        paint the luminance samples using a gradient pattern based on &lt;br /&gt;
          either 4 6-bit samples coded in the stream or 4 6-bit samples &lt;br /&gt;
          retrieved from a 16,384-entry codebook using an index coded in &lt;br /&gt;
          the stream&lt;br /&gt;
        if mode is 0&lt;br /&gt;
          get the next 2 bytes from the stream as a big endian 16-bit &lt;br /&gt;
            number:&lt;br /&gt;
          gradient fill pattern = bits 15-12&lt;br /&gt;
          luminance codebook index = bits 11-0&lt;br /&gt;
          Y0..Y3 are set according to the codebook entry (see References &lt;br /&gt;
            for UltiMotion luminance codebook)&lt;br /&gt;
          if bit 3 of the gradient fill pattern is set, swap Y0 with Y3 &lt;br /&gt;
            and Y1 with Y2; clear bit 3 of the gradient fill pattern&lt;br /&gt;
          fill luminance samples according to Y0..Y3 and the gradient fill &lt;br /&gt;
            pattern (see section Gradient Fill Patterns)&lt;br /&gt;
        else (mode is non-zero)&lt;br /&gt;
          get the next 3 bytes from the stream as a big endian 24-bit &lt;br /&gt;
            number:&lt;br /&gt;
          Y0 = bits 23-18&lt;br /&gt;
          Y1 = bits 17-12&lt;br /&gt;
          Y2 = bits 11-6&lt;br /&gt;
          Y3 = bits 5-0&lt;br /&gt;
          fill luminance samples according to Y0..Y3 and gradient fill &lt;br /&gt;
            pattern 8 (see section Gradient Fill Patterns)&lt;br /&gt;
 &lt;br /&gt;
      coding mode 3:&lt;br /&gt;
        flexible coding mode that can paint the luminance samples with 16 &lt;br /&gt;
          6-bit samples coded in the stream, or with a gradient fill &lt;br /&gt;
          pattern and 4 6-bit luminance samples coded in the stream, or &lt;br /&gt;
          with an arbitrary pattern using 2 luminance samples and a set of &lt;br /&gt;
          flags coded in the stream&lt;br /&gt;
        if mode is 0&lt;br /&gt;
          get the next byte in the stream (b1)&lt;br /&gt;
          if bit 7 of b1 is set&lt;br /&gt;
            gradient fill pattern = bits 6-4 of b1&lt;br /&gt;
            get the next byte in the stream (b1)&lt;br /&gt;
            Y0 = ((b1 &amp;amp; 0x0F) &amp;lt;&amp;lt; 2) | (b1 &amp;gt;&amp;gt; 6)&lt;br /&gt;
            Y1 = bits 5-0 of b1&lt;br /&gt;
            Y2 = next byte in stream &amp;amp; 0x3F&lt;br /&gt;
            Y3 = next byte in stream &amp;amp; 0x3F&lt;br /&gt;
            fill luminance samples according to Y0..Y3 and the gradient &lt;br /&gt;
              fill pattern (see section Gradient Fill Patterns)&lt;br /&gt;
          else&lt;br /&gt;
            flagsA = b1&lt;br /&gt;
            flagsB = next byte in the stream&lt;br /&gt;
            Y0 = next byte in stream &amp;amp; 0x3F&lt;br /&gt;
            Y1 = next byte in stream &amp;amp; 0x3F&lt;br /&gt;
            the 16 bits between flagsA and flagsB represent the pattern &lt;br /&gt;
              used to place either Y0 or Y1 into the luminance grid&lt;br /&gt;
 &lt;br /&gt;
              A7 A6 A5 A4&lt;br /&gt;
              A3 A2 A1 A0&lt;br /&gt;
              B7 B6 B5 B4&lt;br /&gt;
              B3 B2 B1 B0&lt;br /&gt;
 &lt;br /&gt;
              for example, if bit 3 of flagsB is 1, Y1 would be used in &lt;br /&gt;
              the lower left corner of the quadrant, else Y0&lt;br /&gt;
        else (mode is non-zero)&lt;br /&gt;
          get the next 16 6-bit numbers from the stream as the 16 &lt;br /&gt;
            luminance samples for the quadrant, thus consuming 96 bits, &lt;br /&gt;
            or 12 bytes from the stream&lt;br /&gt;
 &lt;br /&gt;
      finally, output quadrant:&lt;br /&gt;
        bits 7-4 of the chrominance byte represent the Cr (or V) component&lt;br /&gt;
          while bits 3-0 represent the Cb (U) component&lt;br /&gt;
        convert the 16 luminance values and the 2 chrominance values to a &lt;br /&gt;
          proper YUV colorspace using the conversion tables in Appendix A&lt;br /&gt;
 &lt;br /&gt;
  if uniq flag is -1&lt;br /&gt;
    uniq flag = 0&lt;br /&gt;
&lt;br /&gt;
== Gradient Fill Patterns ==&lt;br /&gt;
&lt;br /&gt;
The ULTI codec has 9 gradient fill patterns for painting 4x4 sub blocks of luminance data using 4 luminance samples.&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 0:&lt;br /&gt;
  0 1 2 3&lt;br /&gt;
  0 1 2 3&lt;br /&gt;
  0 1 2 3&lt;br /&gt;
  0 1 2 3&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 1:&lt;br /&gt;
  1 2 3 3&lt;br /&gt;
  0 1 2 3&lt;br /&gt;
  0 1 2 3&lt;br /&gt;
  0 0 1 2&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 2:&lt;br /&gt;
  1 2 3 3&lt;br /&gt;
  1 2 2 3&lt;br /&gt;
  0 1 1 2&lt;br /&gt;
  0 0 1 2&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 3:&lt;br /&gt;
  2 3 3 3&lt;br /&gt;
  1 2 2 3&lt;br /&gt;
  0 1 1 2&lt;br /&gt;
  0 0 0 1&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 4:&lt;br /&gt;
  3 3 3 3&lt;br /&gt;
  2 2 2 2&lt;br /&gt;
  1 1 1 1&lt;br /&gt;
  0 0 0 0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 5:&lt;br /&gt;
  3 3 3 2&lt;br /&gt;
  3 2 2 1&lt;br /&gt;
  2 1 1 0&lt;br /&gt;
  1 0 0 0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 6:&lt;br /&gt;
  3 3 2 2&lt;br /&gt;
  3 2 1 1&lt;br /&gt;
  2 2 1 0&lt;br /&gt;
  1 1 0 0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 7:&lt;br /&gt;
  3 3 2 1&lt;br /&gt;
  3 2 1 0&lt;br /&gt;
  3 2 1 0&lt;br /&gt;
  2 1 0 0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 8:&lt;br /&gt;
  0 0 1 1&lt;br /&gt;
  0 0 1 1&lt;br /&gt;
  2 2 3 3&lt;br /&gt;
  2 2 3 3&lt;br /&gt;
&lt;br /&gt;
== Converting UltiMotion Scaled YUV To Correct YUV ==&lt;br /&gt;
&lt;br /&gt;
To convert UltiMotion 6-bit luminance values to proper luminance samples, use the following conversion table:&lt;br /&gt;
&lt;br /&gt;
 unsigned char ulti_lumas[64] =&lt;br /&gt;
    { 0x10, 0x13, 0x17, 0x1A, 0x1E, 0x21, 0x25, 0x28,&lt;br /&gt;
      0x2C, 0x2F, 0x33, 0x36, 0x3A, 0x3D, 0x41, 0x44,&lt;br /&gt;
      0x48, 0x4B, 0x4F, 0x52, 0x56, 0x59, 0x5C, 0x60,&lt;br /&gt;
      0x63, 0x67, 0x6A, 0x6E, 0x71, 0x75, 0x78, 0x7C,&lt;br /&gt;
      0x7F, 0x83, 0x86, 0x8A, 0x8D, 0x91, 0x94, 0x98,&lt;br /&gt;
      0x9B, 0x9F, 0xA2, 0xA5, 0xA9, 0xAC, 0xB0, 0xB3,&lt;br /&gt;
      0xB7, 0xBA, 0xBE, 0xC1, 0xC5, 0xC8, 0xCC, 0xCF,&lt;br /&gt;
      0xD3, 0xD6, 0xDA, 0xDD, 0xE1, 0xE4, 0xE8, 0xEB};&lt;br /&gt;
      &lt;br /&gt;
To convert UltiMotion 4-bit chrominance values to proper chrominance samples, use the following conversion table:&lt;br /&gt;
&lt;br /&gt;
 unsigned char ulti_chromas[16] =&lt;br /&gt;
    { 0x60, 0x67, 0x6D, 0x73, 0x7A, 0x80, 0x86, 0x8D,&lt;br /&gt;
      0x93, 0x99, 0xA0, 0xA6, 0xAC, 0xB3, 0xB9, 0xC0};&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* [http://xanim.polter.net/ XAnim]&lt;br /&gt;
&lt;br /&gt;
* [http://mplayerhq.hu/cgi-bin/cvsweb.cgi/~checkout~/ffmpeg/libavcodec/ulti_cb.h?content-type=text/x-cvsweb-markup&amp;amp;cvsroot=FFMpeg UltiMotion Luminance Codebook]&lt;br /&gt;
&lt;br /&gt;
[[Category:Video Codecs]]&lt;/div&gt;</summary>
		<author><name>Ultimotion</name></author>
	</entry>
	<entry>
		<id>https://wiki.multimedia.cx/index.php?title=IBM_UltiMotion&amp;diff=6218</id>
		<title>IBM UltiMotion</title>
		<link rel="alternate" type="text/html" href="https://wiki.multimedia.cx/index.php?title=IBM_UltiMotion&amp;diff=6218"/>
		<updated>2006-10-11T19:57:22Z</updated>

		<summary type="html">&lt;p&gt;Ultimotion: /* Decoding Algorithm */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;''This page is based on the document 'Description of the IBM UltiMotion (ULTI) Video Codec' by Mike Melanson and Konstantin Shishkov found at [http://multimedia.cx/ultimotion-format.txt http://multimedia.cx/ultimotion-format.txt].''&lt;br /&gt;
&lt;br /&gt;
* FourCC: ULTI&lt;br /&gt;
* Company: [[IBM]]&lt;br /&gt;
* Official Description: [http://multimedia.cx/UMSPEC.ZIP http://multimedia.cx/UMSPEC.ZIP]&lt;br /&gt;
* Samples: [http://samples.mplayerhq.hu/V-codecs/ULTI/ http://samples.mplayerhq.hu/V-codecs/ULTI/]&lt;br /&gt;
&lt;br /&gt;
IBM UltiMotion (henceforth ULTI) is a video codec typically seen in [[AVI]] files, though there is no reason it could not be used in other container formats. &lt;br /&gt;
&lt;br /&gt;
== Decoding Algorithm ==&lt;br /&gt;
&lt;br /&gt;
The ULTI algorithm operates natively on a scaled-down [[Raw YUV|YUV]] 4:1:0 planar colorspace. This means that for each 4x4 block of pixels (quadrant), each of the 16 pixels has a luminance (Y) sample and the entire block shares one chrominance sample (expressed as two color difference components : C&amp;lt;sub&amp;gt;b&amp;lt;/sub&amp;gt; (or U) and C&amp;lt;sub&amp;gt;r&amp;lt;/sub&amp;gt; (or V). The colorspace is actually non-linear quantized to fixed values from 2 tables. Indices into these tables (64 possible values for luminance and 16 for each chrominance component) are transmitted in the final bitstream.&lt;br /&gt;
&lt;br /&gt;
The ULTI algorithm codes a frame by dividing it into a series of 8x8 blocks. Each 8x8 block is subdivided and coded as 4 4x4 quadrants. The 4 quadrants, 0-3, are coded in the following arrangement:&lt;br /&gt;
&lt;br /&gt;
  0 3&lt;br /&gt;
  1 2&lt;br /&gt;
&lt;br /&gt;
Each block can be encoded using a single chrominance sample or unique chrominance sample for each quadrant. Each quadrant has 16 luminance samples that can be coded using a variety of methods.&lt;br /&gt;
&lt;br /&gt;
To decode a frame of UltiMotion data, follow this process:&lt;br /&gt;
&lt;br /&gt;
 initialize uniq and mode flags to 0&lt;br /&gt;
 &lt;br /&gt;
 for each 8x8 block in the frame, iterating from left -&amp;gt; right, top -&amp;gt; bottom:&lt;br /&gt;
 &lt;br /&gt;
  get the next byte in the stream (b0)&lt;br /&gt;
  if (b0 &amp;amp; 0xF8) == 0x70, handle escape code:&lt;br /&gt;
    if b0 is 0x70&lt;br /&gt;
      mode = next byte in stream&lt;br /&gt;
      note: only mode values of 0 or 1 are valid&lt;br /&gt;
    if b0 is 0x71&lt;br /&gt;
      uniq flag = -1 &lt;br /&gt;
    if b0 is 0x72&lt;br /&gt;
      toggle uniq flag (0/1)&lt;br /&gt;
    if b0 is 0x73&lt;br /&gt;
      end of frame, stop decoding&lt;br /&gt;
    if b0 is 0x74&lt;br /&gt;
      get the next byte in stream (b1)&lt;br /&gt;
      skip next (b1) blocks in the output frame (unchanged from previous frame)&lt;br /&gt;
 &lt;br /&gt;
  else&lt;br /&gt;
    if b0 is non-zero and uniq flag is 0&lt;br /&gt;
      chrominance byte = next byte from stream&lt;br /&gt;
 &lt;br /&gt;
    for each 4x4 quadrant in the block, arranged in the quadrant pattern:&lt;br /&gt;
 &lt;br /&gt;
      extract quadrant coding mode from b0:&lt;br /&gt;
        bits 7-6: quadrant 0 coding mode&lt;br /&gt;
        bits 5-4: quadrant 1 coding mode&lt;br /&gt;
        bits 3-2: quadrant 2 coding mode&lt;br /&gt;
        bits 1-0: quadrant 3 coding mode&lt;br /&gt;
 &lt;br /&gt;
      if coding mode is non-zero and uniq flag is non-zero&lt;br /&gt;
        chrominance byte = next byte from stream&lt;br /&gt;
 &lt;br /&gt;
      coding mode 0:&lt;br /&gt;
        skip quadrant (unchanged from the previous frame)&lt;br /&gt;
 &lt;br /&gt;
      coding mode 1:&lt;br /&gt;
        paint the luminance samples using a gradient pattern based on one &lt;br /&gt;
          6-bit sample coded in the stream&lt;br /&gt;
 &lt;br /&gt;
        get next byte from stream (b1)&lt;br /&gt;
        bits 7-6 of b1 indicate gradient fill pattern:&lt;br /&gt;
          0 = gradient fill pattern 0&lt;br /&gt;
          1 = gradient fill pattern 2&lt;br /&gt;
          2 = gradient fill pattern 6&lt;br /&gt;
          3 = gradient fill pattern 4, swap Y0 with Y3 and Y1 with Y2 &lt;br /&gt;
              after unpacking Y samples&lt;br /&gt;
        bits 5-0 of b1 indicate luminance sample Y0&lt;br /&gt;
        Y1 = Y0&lt;br /&gt;
        if gradient fill pattern is pattern 0&lt;br /&gt;
          Y2 = Y0 + 1 (saturated to an upper limit of 0x3F)&lt;br /&gt;
          Y3 = Y2&lt;br /&gt;
        else&lt;br /&gt;
          Y2 = Y3 = Y0&lt;br /&gt;
        fill luminance samples according to Y0..Y3 and the gradient fill &lt;br /&gt;
          pattern (see section Gradient Fill Patterns)&lt;br /&gt;
 &lt;br /&gt;
      coding mode 2:&lt;br /&gt;
        paint the luminance samples using a gradient pattern based on &lt;br /&gt;
          either 4 6-bit samples coded in the stream or 4 6-bit samples &lt;br /&gt;
          retrieved from a 16,384-entry codebook using an index coded in &lt;br /&gt;
          the stream&lt;br /&gt;
        if mode is 0&lt;br /&gt;
          get the next 2 bytes from the stream as a big endian 16-bit &lt;br /&gt;
            number:&lt;br /&gt;
          gradient fill pattern = bits 15-12&lt;br /&gt;
          luminance codebook index = bits 11-0&lt;br /&gt;
          Y0..Y3 are set according to the codebook entry (see References &lt;br /&gt;
            for UltiMotion luminance codebook)&lt;br /&gt;
          if bit 3 of the gradient fill pattern is set, swap Y0 with Y3 &lt;br /&gt;
            and Y1 with Y2; clear bit 3 of the gradient fill pattern&lt;br /&gt;
          fill luminance samples according to Y0..Y3 and the gradient fill &lt;br /&gt;
            pattern (see section Gradient Fill Patterns)&lt;br /&gt;
        else (mode is non-zero)&lt;br /&gt;
          get the next 3 bytes from the stream as a big endian 24-bit &lt;br /&gt;
            number:&lt;br /&gt;
          Y0 = bits 23-18&lt;br /&gt;
          Y1 = bits 17-12&lt;br /&gt;
          Y2 = bits 11-6&lt;br /&gt;
          Y3 = bits 5-0&lt;br /&gt;
          fill luminance samples according to Y0..Y3 and gradient fill &lt;br /&gt;
            pattern 8 (see section Gradient Fill Patterns)&lt;br /&gt;
 &lt;br /&gt;
      coding mode 3:&lt;br /&gt;
        flexible coding mode that can paint the luminance samples with 16 &lt;br /&gt;
          6-bit samples coded in the stream, or with a gradient fill &lt;br /&gt;
          pattern and 4 6-bit luminance samples coded in the stream, or &lt;br /&gt;
          with an arbitrary pattern using 2 luminance samples and a set of &lt;br /&gt;
          flags coded in the stream&lt;br /&gt;
        if mode is 0&lt;br /&gt;
          get the next byte in the stream (b1)&lt;br /&gt;
          if bit 7 of b1 is set&lt;br /&gt;
            gradient fill pattern = bits 6-4 of b1&lt;br /&gt;
            get the next byte in the stream (b1)&lt;br /&gt;
            Y0 = ((b1 &amp;amp; 0x0F) &amp;lt;&amp;lt; 2) | (b1 &amp;gt;&amp;gt; 6)&lt;br /&gt;
            Y1 = bits 5-0 of b1&lt;br /&gt;
            Y2 = next byte in stream &amp;amp; 0x3F&lt;br /&gt;
            Y3 = next byte in stream &amp;amp; 0x3F&lt;br /&gt;
            fill luminance samples according to Y0..Y3 and the gradient &lt;br /&gt;
              fill pattern (see section Gradient Fill Patterns)&lt;br /&gt;
          else&lt;br /&gt;
            flagsA = b1&lt;br /&gt;
            flagsB = next byte in the stream&lt;br /&gt;
            Y0 = next byte in stream &amp;amp; 0x3F&lt;br /&gt;
            Y1 = next byte in stream &amp;amp; 0x3F&lt;br /&gt;
            the 16 bits between flagsA and flagsB represent the pattern &lt;br /&gt;
              used to place either Y0 or Y1 into the luminance grid&lt;br /&gt;
 &lt;br /&gt;
              A7 A6 A5 A4&lt;br /&gt;
              A3 A2 A1 A0&lt;br /&gt;
              B7 B6 B5 B4&lt;br /&gt;
              B3 B2 B1 B0&lt;br /&gt;
 &lt;br /&gt;
              for example, if bit 3 of flagsB is 1, Y1 would be used in &lt;br /&gt;
              the lower left corner of the quadrant, else Y0&lt;br /&gt;
        else (mode is non-zero)&lt;br /&gt;
          get the next 16 6-bit numbers from the stream as the 16 &lt;br /&gt;
            luminance samples for the quadrant, thus consuming 96 bits, &lt;br /&gt;
            or 12 bytes from the stream&lt;br /&gt;
 &lt;br /&gt;
      finally, output quadrant:&lt;br /&gt;
        bits 7-4 of the chrominance byte represent the Cr (or V) component&lt;br /&gt;
          while bits 3-0 represent the Cb (U) component&lt;br /&gt;
        convert the 16 luminance values and the 2 chrominance values to a &lt;br /&gt;
          proper YUV colorspace using the conversion tables in Appendix A&lt;br /&gt;
&lt;br /&gt;
  if uniq flag is -1&lt;br /&gt;
    uniq flag = 0&lt;br /&gt;
&lt;br /&gt;
== Gradient Fill Patterns ==&lt;br /&gt;
&lt;br /&gt;
The ULTI codec has 9 gradient fill patterns for painting 4x4 sub blocks of luminance data using 4 luminance samples.&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 0:&lt;br /&gt;
  0 1 2 3&lt;br /&gt;
  0 1 2 3&lt;br /&gt;
  0 1 2 3&lt;br /&gt;
  0 1 2 3&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 1:&lt;br /&gt;
  1 2 3 3&lt;br /&gt;
  0 1 2 3&lt;br /&gt;
  0 1 2 3&lt;br /&gt;
  0 0 1 2&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 2:&lt;br /&gt;
  1 2 3 3&lt;br /&gt;
  1 2 2 3&lt;br /&gt;
  0 1 1 2&lt;br /&gt;
  0 0 1 2&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 3:&lt;br /&gt;
  2 3 3 3&lt;br /&gt;
  1 2 2 3&lt;br /&gt;
  0 1 1 2&lt;br /&gt;
  0 0 0 1&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 4:&lt;br /&gt;
  3 3 3 3&lt;br /&gt;
  2 2 2 2&lt;br /&gt;
  1 1 1 1&lt;br /&gt;
  0 0 0 0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 5:&lt;br /&gt;
  3 3 3 2&lt;br /&gt;
  3 2 2 1&lt;br /&gt;
  2 1 1 0&lt;br /&gt;
  1 0 0 0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 6:&lt;br /&gt;
  3 3 2 2&lt;br /&gt;
  3 2 1 1&lt;br /&gt;
  2 2 1 0&lt;br /&gt;
  1 1 0 0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 7:&lt;br /&gt;
  3 3 2 1&lt;br /&gt;
  3 2 1 0&lt;br /&gt;
  3 2 1 0&lt;br /&gt;
  2 1 0 0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 8:&lt;br /&gt;
  0 0 1 1&lt;br /&gt;
  0 0 1 1&lt;br /&gt;
  2 2 3 3&lt;br /&gt;
  2 2 3 3&lt;br /&gt;
&lt;br /&gt;
== Converting UltiMotion Scaled YUV To Correct YUV ==&lt;br /&gt;
&lt;br /&gt;
To convert UltiMotion 6-bit luminance values to proper luminance samples, use the following conversion table:&lt;br /&gt;
&lt;br /&gt;
 unsigned char ulti_lumas[64] =&lt;br /&gt;
    { 0x10, 0x13, 0x17, 0x1A, 0x1E, 0x21, 0x25, 0x28,&lt;br /&gt;
      0x2C, 0x2F, 0x33, 0x36, 0x3A, 0x3D, 0x41, 0x44,&lt;br /&gt;
      0x48, 0x4B, 0x4F, 0x52, 0x56, 0x59, 0x5C, 0x60,&lt;br /&gt;
      0x63, 0x67, 0x6A, 0x6E, 0x71, 0x75, 0x78, 0x7C,&lt;br /&gt;
      0x7F, 0x83, 0x86, 0x8A, 0x8D, 0x91, 0x94, 0x98,&lt;br /&gt;
      0x9B, 0x9F, 0xA2, 0xA5, 0xA9, 0xAC, 0xB0, 0xB3,&lt;br /&gt;
      0xB7, 0xBA, 0xBE, 0xC1, 0xC5, 0xC8, 0xCC, 0xCF,&lt;br /&gt;
      0xD3, 0xD6, 0xDA, 0xDD, 0xE1, 0xE4, 0xE8, 0xEB};&lt;br /&gt;
      &lt;br /&gt;
To convert UltiMotion 4-bit chrominance values to proper chrominance samples, use the following conversion table:&lt;br /&gt;
&lt;br /&gt;
 unsigned char ulti_chromas[16] =&lt;br /&gt;
    { 0x60, 0x67, 0x6D, 0x73, 0x7A, 0x80, 0x86, 0x8D,&lt;br /&gt;
      0x93, 0x99, 0xA0, 0xA6, 0xAC, 0xB3, 0xB9, 0xC0};&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* [http://xanim.polter.net/ XAnim]&lt;br /&gt;
&lt;br /&gt;
* [http://mplayerhq.hu/cgi-bin/cvsweb.cgi/~checkout~/ffmpeg/libavcodec/ulti_cb.h?content-type=text/x-cvsweb-markup&amp;amp;cvsroot=FFMpeg UltiMotion Luminance Codebook]&lt;br /&gt;
&lt;br /&gt;
[[Category:Video Codecs]]&lt;/div&gt;</summary>
		<author><name>Ultimotion</name></author>
	</entry>
	<entry>
		<id>https://wiki.multimedia.cx/index.php?title=IBM_UltiMotion&amp;diff=6217</id>
		<title>IBM UltiMotion</title>
		<link rel="alternate" type="text/html" href="https://wiki.multimedia.cx/index.php?title=IBM_UltiMotion&amp;diff=6217"/>
		<updated>2006-10-11T19:41:12Z</updated>

		<summary type="html">&lt;p&gt;Ultimotion: /* Decoding Algorithm */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;''This page is based on the document 'Description of the IBM UltiMotion (ULTI) Video Codec' by Mike Melanson and Konstantin Shishkov found at [http://multimedia.cx/ultimotion-format.txt http://multimedia.cx/ultimotion-format.txt].''&lt;br /&gt;
&lt;br /&gt;
* FourCC: ULTI&lt;br /&gt;
* Company: [[IBM]]&lt;br /&gt;
* Official Description: [http://multimedia.cx/UMSPEC.ZIP http://multimedia.cx/UMSPEC.ZIP]&lt;br /&gt;
* Samples: [http://samples.mplayerhq.hu/V-codecs/ULTI/ http://samples.mplayerhq.hu/V-codecs/ULTI/]&lt;br /&gt;
&lt;br /&gt;
IBM UltiMotion (henceforth ULTI) is a video codec typically seen in [[AVI]] files, though there is no reason it could not be used in other container formats. &lt;br /&gt;
&lt;br /&gt;
== Decoding Algorithm ==&lt;br /&gt;
&lt;br /&gt;
The ULTI algorithm operates natively on a scaled-down [[Raw YUV|YUV]] 4:1:0 planar colorspace. This means that for each 4x4 block of pixels (quadrant), each of the 16 pixels has a luminance (Y) sample and the entire block shares one chrominance sample (expressed as two color difference components : C&amp;lt;sub&amp;gt;b&amp;lt;/sub&amp;gt; (or U) and C&amp;lt;sub&amp;gt;r&amp;lt;/sub&amp;gt; (or V). The colorspace is actually non-linear quantized to fixed values from 2 tables. Indices into these tables (64 possible values for luminance and 16 for each chrominance component) are transmitted in the final bitstream.&lt;br /&gt;
&lt;br /&gt;
The ULTI algorithm codes a frame by dividing it into a series of 8x8 blocks. Each 8x8 block is subdivided and coded as 4 4x4 quadrants. The 4 quadrants, 0-3, are coded in the following arrangement:&lt;br /&gt;
&lt;br /&gt;
  0 3&lt;br /&gt;
  1 2&lt;br /&gt;
&lt;br /&gt;
Each block can be encoded using a single chrominance sample or each quadrant can be coded with its own pair of chrominance samples. Each sub block has 16 luminance samples that can be coded using a variety of methods.&lt;br /&gt;
&lt;br /&gt;
To decode a frame of UltiMotion data, follow this process:&lt;br /&gt;
&lt;br /&gt;
 initialize uniq and mode flags to 0&lt;br /&gt;
 &lt;br /&gt;
 for each 8x8 block in the frame, iterating from left -&amp;gt; right, top -&amp;gt; bottom:&lt;br /&gt;
 &lt;br /&gt;
  get the next byte in the stream (b0)&lt;br /&gt;
  if (b0 &amp;amp; 0xF8) == 0x70, handle escape code:&lt;br /&gt;
    if b0 is 0x70&lt;br /&gt;
      mode = next byte in stream&lt;br /&gt;
      note: only mode values of 0 or 1 are valid&lt;br /&gt;
    if b0 is 0x71&lt;br /&gt;
      uniq flag = -1 &lt;br /&gt;
    if b0 is 0x72&lt;br /&gt;
      toggle mode flag (0/1)&lt;br /&gt;
    if b0 is 0x73&lt;br /&gt;
      end of frame, stop decoding&lt;br /&gt;
    if b0 is 0x74&lt;br /&gt;
      get the next byte in stream (b1)&lt;br /&gt;
      skip next (b1) blocks in the output frame (unchanged from previous &lt;br /&gt;
        frame)&lt;br /&gt;
 &lt;br /&gt;
  else&lt;br /&gt;
    if b0 is non-zero and uniq flag is 0&lt;br /&gt;
      chrominance byte = next byte from stream&lt;br /&gt;
 &lt;br /&gt;
    for each 4x4 sub block in the block, arranged in the sub block pattern:&lt;br /&gt;
 &lt;br /&gt;
      extract sub block coding mode from b0:&lt;br /&gt;
        bits 7-6: sub block 0 coding mode&lt;br /&gt;
        bits 5-4: sub block 1 coding mode&lt;br /&gt;
        bits 3-2: sub block 2 coding mode&lt;br /&gt;
        bits 1-0: sub block 3 coding mode&lt;br /&gt;
 &lt;br /&gt;
      if coding mode is non-zero and uniq flag is non-zero&lt;br /&gt;
        chrominance byte = next byte from stream&lt;br /&gt;
 &lt;br /&gt;
      coding mode 0:&lt;br /&gt;
        skip sub block (unchanged from the previous frame)&lt;br /&gt;
 &lt;br /&gt;
      coding mode 1:&lt;br /&gt;
        paint the luminance samples using a gradient pattern based on one &lt;br /&gt;
          6-bit sample coded in the stream&lt;br /&gt;
 &lt;br /&gt;
        get next byte from stream (b1)&lt;br /&gt;
        bits 7-6 of b1 indicate gradient fill pattern:&lt;br /&gt;
          0 = gradient fill pattern 0&lt;br /&gt;
          1 = gradient fill pattern 2&lt;br /&gt;
          2 = gradient fill pattern 6&lt;br /&gt;
          3 = gradient fill pattern 4, swap Y0 with Y3 and Y1 with Y2 &lt;br /&gt;
              after unpacking Y samples&lt;br /&gt;
        bits 5-0 of b1 indicate luminance sample Y0&lt;br /&gt;
        Y1 = Y0&lt;br /&gt;
        if gradient fill pattern is pattern 0&lt;br /&gt;
          Y2 = Y0 + 1 (saturated to an upper limit of 0x3F)&lt;br /&gt;
          Y3 = Y2&lt;br /&gt;
        else&lt;br /&gt;
          Y2 = Y3 = Y0&lt;br /&gt;
        fill luminance samples according to Y0..Y3 and the gradient fill &lt;br /&gt;
          pattern (see section Gradient Fill Patterns)&lt;br /&gt;
 &lt;br /&gt;
      coding mode 2:&lt;br /&gt;
        paint the luminance samples using a gradient pattern based on &lt;br /&gt;
          either 4 6-bit samples coded in the stream or 4 6-bit samples &lt;br /&gt;
          retrieved from a 16,384-entry codebook using an index coded in &lt;br /&gt;
          the stream&lt;br /&gt;
        if mode is 0&lt;br /&gt;
          get the next 2 bytes from the stream as a big endian 16-bit &lt;br /&gt;
            number:&lt;br /&gt;
          gradient fill pattern = bits 15-12&lt;br /&gt;
          luminance codebook index = bits 11-0&lt;br /&gt;
          Y0..Y3 are set according to the codebook entry (see References &lt;br /&gt;
            for UltiMotion luminance codebook)&lt;br /&gt;
          if bit 3 of the gradient fill pattern is set, swap Y0 with Y3 &lt;br /&gt;
            and Y1 with Y2; clear bit 3 of the gradient fill pattern&lt;br /&gt;
          fill luminance samples according to Y0..Y3 and the gradient fill &lt;br /&gt;
            pattern (see section Gradient Fill Patterns)&lt;br /&gt;
        else (mode is non-zero)&lt;br /&gt;
          get the next 3 bytes from the stream as a big endian 24-bit &lt;br /&gt;
            number:&lt;br /&gt;
          Y0 = bits 23-18&lt;br /&gt;
          Y1 = bits 17-12&lt;br /&gt;
          Y2 = bits 11-6&lt;br /&gt;
          Y3 = bits 5-0&lt;br /&gt;
          fill luminance samples according to Y0..Y3 and gradient fill &lt;br /&gt;
            pattern 8 (see section Gradient Fill Patterns)&lt;br /&gt;
 &lt;br /&gt;
      coding mode 3:&lt;br /&gt;
        flexible coding mode that can paint the luminance samples with 16 &lt;br /&gt;
          6-bit samples coded in the stream, or with a gradient fill &lt;br /&gt;
          pattern and 4 6-bit luminance samples coded in the stream, or &lt;br /&gt;
          with an arbitrary pattern using 2 luminance samples and a set of &lt;br /&gt;
          flags coded in the stream&lt;br /&gt;
        if mode is 0&lt;br /&gt;
          get the next byte in the stream (b1)&lt;br /&gt;
          if bit 7 of b1 is set&lt;br /&gt;
            gradient fill pattern = bits 6-4 of b1&lt;br /&gt;
            get the next byte in the stream (b1)&lt;br /&gt;
            Y0 = ((b1 &amp;amp; 0x0F) &amp;lt;&amp;lt; 2) | (b1 &amp;gt;&amp;gt; 6)&lt;br /&gt;
            Y1 = bits 5-0 of b1&lt;br /&gt;
            Y2 = next byte in stream &amp;amp; 0x3F&lt;br /&gt;
            Y3 = next byte in stream &amp;amp; 0x3F&lt;br /&gt;
            fill luminance samples according to Y0..Y3 and the gradient &lt;br /&gt;
              fill pattern (see section Gradient Fill Patterns)&lt;br /&gt;
          else&lt;br /&gt;
            flagsA = b1&lt;br /&gt;
            flagsB = next byte in the stream&lt;br /&gt;
            Y0 = next byte in stream &amp;amp; 0x3F&lt;br /&gt;
            Y1 = next byte in stream &amp;amp; 0x3F&lt;br /&gt;
            the 16 bits between flagsA and flagsB represent the pattern &lt;br /&gt;
              used to place either Y0 or Y1 into the luminance grid&lt;br /&gt;
 &lt;br /&gt;
              A7 A6 A5 A4&lt;br /&gt;
              A3 A2 A1 A0&lt;br /&gt;
              B7 B6 B5 B4&lt;br /&gt;
              B3 B2 B1 B0&lt;br /&gt;
 &lt;br /&gt;
              for example, if bit 3 of flagsB is 1, Y1 would be used in &lt;br /&gt;
              the lower left corner of the sub block, else Y0&lt;br /&gt;
        else (mode is non-zero)&lt;br /&gt;
          get the next 16 6-bit numbers from the stream as the 16 &lt;br /&gt;
            luminance samples for the sub block, thus consuming 96 bits, &lt;br /&gt;
            or 12 bytes from the stream&lt;br /&gt;
 &lt;br /&gt;
      finally, output sub block:&lt;br /&gt;
        bits 7-4 of the chrominance byte represent the red chrominance &lt;br /&gt;
          value for the sub block while bits 3-0 represent the blue value&lt;br /&gt;
        convert the 16 luminance values and the 2 chrominance values to a &lt;br /&gt;
          proper YUV colorspace using the conversion tables in Appendix A&lt;br /&gt;
      if uniq flag is -1&lt;br /&gt;
        uniq flag = 0&lt;br /&gt;
&lt;br /&gt;
== Gradient Fill Patterns ==&lt;br /&gt;
&lt;br /&gt;
The ULTI codec has 9 gradient fill patterns for painting 4x4 sub blocks of luminance data using 4 luminance samples.&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 0:&lt;br /&gt;
  0 1 2 3&lt;br /&gt;
  0 1 2 3&lt;br /&gt;
  0 1 2 3&lt;br /&gt;
  0 1 2 3&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 1:&lt;br /&gt;
  1 2 3 3&lt;br /&gt;
  0 1 2 3&lt;br /&gt;
  0 1 2 3&lt;br /&gt;
  0 0 1 2&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 2:&lt;br /&gt;
  1 2 3 3&lt;br /&gt;
  1 2 2 3&lt;br /&gt;
  0 1 1 2&lt;br /&gt;
  0 0 1 2&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 3:&lt;br /&gt;
  2 3 3 3&lt;br /&gt;
  1 2 2 3&lt;br /&gt;
  0 1 1 2&lt;br /&gt;
  0 0 0 1&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 4:&lt;br /&gt;
  3 3 3 3&lt;br /&gt;
  2 2 2 2&lt;br /&gt;
  1 1 1 1&lt;br /&gt;
  0 0 0 0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 5:&lt;br /&gt;
  3 3 3 2&lt;br /&gt;
  3 2 2 1&lt;br /&gt;
  2 1 1 0&lt;br /&gt;
  1 0 0 0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 6:&lt;br /&gt;
  3 3 2 2&lt;br /&gt;
  3 2 1 1&lt;br /&gt;
  2 2 1 0&lt;br /&gt;
  1 1 0 0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 7:&lt;br /&gt;
  3 3 2 1&lt;br /&gt;
  3 2 1 0&lt;br /&gt;
  3 2 1 0&lt;br /&gt;
  2 1 0 0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 8:&lt;br /&gt;
  0 0 1 1&lt;br /&gt;
  0 0 1 1&lt;br /&gt;
  2 2 3 3&lt;br /&gt;
  2 2 3 3&lt;br /&gt;
&lt;br /&gt;
== Converting UltiMotion Scaled YUV To Correct YUV ==&lt;br /&gt;
&lt;br /&gt;
To convert UltiMotion 6-bit luminance values to proper luminance samples, use the following conversion table:&lt;br /&gt;
&lt;br /&gt;
 unsigned char ulti_lumas[64] =&lt;br /&gt;
    { 0x10, 0x13, 0x17, 0x1A, 0x1E, 0x21, 0x25, 0x28,&lt;br /&gt;
      0x2C, 0x2F, 0x33, 0x36, 0x3A, 0x3D, 0x41, 0x44,&lt;br /&gt;
      0x48, 0x4B, 0x4F, 0x52, 0x56, 0x59, 0x5C, 0x60,&lt;br /&gt;
      0x63, 0x67, 0x6A, 0x6E, 0x71, 0x75, 0x78, 0x7C,&lt;br /&gt;
      0x7F, 0x83, 0x86, 0x8A, 0x8D, 0x91, 0x94, 0x98,&lt;br /&gt;
      0x9B, 0x9F, 0xA2, 0xA5, 0xA9, 0xAC, 0xB0, 0xB3,&lt;br /&gt;
      0xB7, 0xBA, 0xBE, 0xC1, 0xC5, 0xC8, 0xCC, 0xCF,&lt;br /&gt;
      0xD3, 0xD6, 0xDA, 0xDD, 0xE1, 0xE4, 0xE8, 0xEB};&lt;br /&gt;
      &lt;br /&gt;
To convert UltiMotion 4-bit chrominance values to proper chrominance samples, use the following conversion table:&lt;br /&gt;
&lt;br /&gt;
 unsigned char ulti_chromas[16] =&lt;br /&gt;
    { 0x60, 0x67, 0x6D, 0x73, 0x7A, 0x80, 0x86, 0x8D,&lt;br /&gt;
      0x93, 0x99, 0xA0, 0xA6, 0xAC, 0xB3, 0xB9, 0xC0};&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* [http://xanim.polter.net/ XAnim]&lt;br /&gt;
&lt;br /&gt;
* [http://mplayerhq.hu/cgi-bin/cvsweb.cgi/~checkout~/ffmpeg/libavcodec/ulti_cb.h?content-type=text/x-cvsweb-markup&amp;amp;cvsroot=FFMpeg UltiMotion Luminance Codebook]&lt;br /&gt;
&lt;br /&gt;
[[Category:Video Codecs]]&lt;/div&gt;</summary>
		<author><name>Ultimotion</name></author>
	</entry>
	<entry>
		<id>https://wiki.multimedia.cx/index.php?title=IBM_UltiMotion&amp;diff=6216</id>
		<title>IBM UltiMotion</title>
		<link rel="alternate" type="text/html" href="https://wiki.multimedia.cx/index.php?title=IBM_UltiMotion&amp;diff=6216"/>
		<updated>2006-10-11T17:46:47Z</updated>

		<summary type="html">&lt;p&gt;Ultimotion: /* Decoding Algorithm */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;''This page is based on the document 'Description of the IBM UltiMotion (ULTI) Video Codec' by Mike Melanson and Konstantin Shishkov found at [http://multimedia.cx/ultimotion-format.txt http://multimedia.cx/ultimotion-format.txt].''&lt;br /&gt;
&lt;br /&gt;
* FourCC: ULTI&lt;br /&gt;
* Company: [[IBM]]&lt;br /&gt;
* Official Description: [http://multimedia.cx/UMSPEC.ZIP http://multimedia.cx/UMSPEC.ZIP]&lt;br /&gt;
* Samples: [http://samples.mplayerhq.hu/V-codecs/ULTI/ http://samples.mplayerhq.hu/V-codecs/ULTI/]&lt;br /&gt;
&lt;br /&gt;
IBM UltiMotion (henceforth ULTI) is a video codec typically seen in [[AVI]] files, though there is no reason it could not be used in other container formats. &lt;br /&gt;
&lt;br /&gt;
== Decoding Algorithm ==&lt;br /&gt;
&lt;br /&gt;
The ULTI algorithm operates natively on a scaled-down [[Raw YUV|YUV]] 4:1:0 planar colorspace. This means that for each 4x4 block of pixels, each of the 16 pixels has a luminance (Y) sample and the entire block shares one blue&lt;br /&gt;
chrominance sample (C&amp;lt;sub&amp;gt;b&amp;lt;/sub&amp;gt; or U) and one red chrominance sample (C&amp;lt;sub&amp;gt;r&amp;lt;/sub&amp;gt; or V). The colorspace is actually non-linear quantized to fixed values from 2 tables. Indices into these tables (64 possible values for luminance and 16 for chrominance) are transmitted in the final bitstream.&lt;br /&gt;
&lt;br /&gt;
The ULTI algorithm codes a frame by dividing it into a series of 8x8 blocks. Each 8x8 block is subdivided and coded as 4 4x4 blocks. The 4 sub blocks, 0-3, are coded in the following arrangement:&lt;br /&gt;
&lt;br /&gt;
  0 3&lt;br /&gt;
  1 2&lt;br /&gt;
&lt;br /&gt;
Each block can be coded using the same chrominance samples, or each sub block can be coded with its own pair of chrominance samples. Each sub block has 16 luminance samples that can be coded using a variety of methods.&lt;br /&gt;
&lt;br /&gt;
To decode a frame of UltiMotion data, follow this process:&lt;br /&gt;
&lt;br /&gt;
 initialize uniq and mode flags to 0&lt;br /&gt;
 &lt;br /&gt;
 for each 8x8 block in the frame, iterating from left -&amp;gt; right, top -&amp;gt; bottom:&lt;br /&gt;
 &lt;br /&gt;
  get the next byte in the stream (b0)&lt;br /&gt;
  if (b0 &amp;amp; 0xF8) == 0x70, handle escape code:&lt;br /&gt;
    if b0 is 0x70&lt;br /&gt;
      mode = next byte in stream&lt;br /&gt;
      note: only mode values of 0 or 1 are valid&lt;br /&gt;
    if b0 is 0x71&lt;br /&gt;
      uniq flag = -1 &lt;br /&gt;
    if b0 is 0x72&lt;br /&gt;
      toggle mode flag (0/1)&lt;br /&gt;
    if b0 is 0x73&lt;br /&gt;
      end of frame, stop decoding&lt;br /&gt;
    if b0 is 0x74&lt;br /&gt;
      get the next byte in stream (b1)&lt;br /&gt;
      skip next (b1) blocks in the output frame (unchanged from previous &lt;br /&gt;
        frame)&lt;br /&gt;
 &lt;br /&gt;
  else&lt;br /&gt;
    if b0 is non-zero and uniq flag is 0&lt;br /&gt;
      chrominance byte = next byte from stream&lt;br /&gt;
 &lt;br /&gt;
    for each 4x4 sub block in the block, arranged in the sub block pattern:&lt;br /&gt;
 &lt;br /&gt;
      extract sub block coding mode from b0:&lt;br /&gt;
        bits 7-6: sub block 0 coding mode&lt;br /&gt;
        bits 5-4: sub block 1 coding mode&lt;br /&gt;
        bits 3-2: sub block 2 coding mode&lt;br /&gt;
        bits 1-0: sub block 3 coding mode&lt;br /&gt;
 &lt;br /&gt;
      if coding mode is non-zero and uniq flag is non-zero&lt;br /&gt;
        chrominance byte = next byte from stream&lt;br /&gt;
 &lt;br /&gt;
      coding mode 0:&lt;br /&gt;
        skip sub block (unchanged from the previous frame)&lt;br /&gt;
 &lt;br /&gt;
      coding mode 1:&lt;br /&gt;
        paint the luminance samples using a gradient pattern based on one &lt;br /&gt;
          6-bit sample coded in the stream&lt;br /&gt;
 &lt;br /&gt;
        get next byte from stream (b1)&lt;br /&gt;
        bits 7-6 of b1 indicate gradient fill pattern:&lt;br /&gt;
          0 = gradient fill pattern 0&lt;br /&gt;
          1 = gradient fill pattern 2&lt;br /&gt;
          2 = gradient fill pattern 6&lt;br /&gt;
          3 = gradient fill pattern 4, swap Y0 with Y3 and Y1 with Y2 &lt;br /&gt;
              after unpacking Y samples&lt;br /&gt;
        bits 5-0 of b1 indicate luminance sample Y0&lt;br /&gt;
        Y1 = Y0&lt;br /&gt;
        if gradient fill pattern is pattern 0&lt;br /&gt;
          Y2 = Y0 + 1 (saturated to an upper limit of 0x3F)&lt;br /&gt;
          Y3 = Y2&lt;br /&gt;
        else&lt;br /&gt;
          Y2 = Y3 = Y0&lt;br /&gt;
        fill luminance samples according to Y0..Y3 and the gradient fill &lt;br /&gt;
          pattern (see section Gradient Fill Patterns)&lt;br /&gt;
 &lt;br /&gt;
      coding mode 2:&lt;br /&gt;
        paint the luminance samples using a gradient pattern based on &lt;br /&gt;
          either 4 6-bit samples coded in the stream or 4 6-bit samples &lt;br /&gt;
          retrieved from a 16,384-entry codebook using an index coded in &lt;br /&gt;
          the stream&lt;br /&gt;
        if mode is 0&lt;br /&gt;
          get the next 2 bytes from the stream as a big endian 16-bit &lt;br /&gt;
            number:&lt;br /&gt;
          gradient fill pattern = bits 15-12&lt;br /&gt;
          luminance codebook index = bits 11-0&lt;br /&gt;
          Y0..Y3 are set according to the codebook entry (see References &lt;br /&gt;
            for UltiMotion luminance codebook)&lt;br /&gt;
          if bit 3 of the gradient fill pattern is set, swap Y0 with Y3 &lt;br /&gt;
            and Y1 with Y2; clear bit 3 of the gradient fill pattern&lt;br /&gt;
          fill luminance samples according to Y0..Y3 and the gradient fill &lt;br /&gt;
            pattern (see section Gradient Fill Patterns)&lt;br /&gt;
        else (mode is non-zero)&lt;br /&gt;
          get the next 3 bytes from the stream as a big endian 24-bit &lt;br /&gt;
            number:&lt;br /&gt;
          Y0 = bits 23-18&lt;br /&gt;
          Y1 = bits 17-12&lt;br /&gt;
          Y2 = bits 11-6&lt;br /&gt;
          Y3 = bits 5-0&lt;br /&gt;
          fill luminance samples according to Y0..Y3 and gradient fill &lt;br /&gt;
            pattern 8 (see section Gradient Fill Patterns)&lt;br /&gt;
 &lt;br /&gt;
      coding mode 3:&lt;br /&gt;
        flexible coding mode that can paint the luminance samples with 16 &lt;br /&gt;
          6-bit samples coded in the stream, or with a gradient fill &lt;br /&gt;
          pattern and 4 6-bit luminance samples coded in the stream, or &lt;br /&gt;
          with an arbitrary pattern using 2 luminance samples and a set of &lt;br /&gt;
          flags coded in the stream&lt;br /&gt;
        if mode is 0&lt;br /&gt;
          get the next byte in the stream (b1)&lt;br /&gt;
          if bit 7 of b1 is set&lt;br /&gt;
            gradient fill pattern = bits 6-4 of b1&lt;br /&gt;
            get the next byte in the stream (b1)&lt;br /&gt;
            Y0 = ((b1 &amp;amp; 0x0F) &amp;lt;&amp;lt; 2) | (b1 &amp;gt;&amp;gt; 6)&lt;br /&gt;
            Y1 = bits 5-0 of b1&lt;br /&gt;
            Y2 = next byte in stream &amp;amp; 0x3F&lt;br /&gt;
            Y3 = next byte in stream &amp;amp; 0x3F&lt;br /&gt;
            fill luminance samples according to Y0..Y3 and the gradient &lt;br /&gt;
              fill pattern (see section Gradient Fill Patterns)&lt;br /&gt;
          else&lt;br /&gt;
            flagsA = b1&lt;br /&gt;
            flagsB = next byte in the stream&lt;br /&gt;
            Y0 = next byte in stream &amp;amp; 0x3F&lt;br /&gt;
            Y1 = next byte in stream &amp;amp; 0x3F&lt;br /&gt;
            the 16 bits between flagsA and flagsB represent the pattern &lt;br /&gt;
              used to place either Y0 or Y1 into the luminance grid&lt;br /&gt;
 &lt;br /&gt;
              A7 A6 A5 A4&lt;br /&gt;
              A3 A2 A1 A0&lt;br /&gt;
              B7 B6 B5 B4&lt;br /&gt;
              B3 B2 B1 B0&lt;br /&gt;
 &lt;br /&gt;
              for example, if bit 3 of flagsB is 1, Y1 would be used in &lt;br /&gt;
              the lower left corner of the sub block, else Y0&lt;br /&gt;
        else (mode is non-zero)&lt;br /&gt;
          get the next 16 6-bit numbers from the stream as the 16 &lt;br /&gt;
            luminance samples for the sub block, thus consuming 96 bits, &lt;br /&gt;
            or 12 bytes from the stream&lt;br /&gt;
 &lt;br /&gt;
      finally, output sub block:&lt;br /&gt;
        bits 7-4 of the chrominance byte represent the red chrominance &lt;br /&gt;
          value for the sub block while bits 3-0 represent the blue value&lt;br /&gt;
        convert the 16 luminance values and the 2 chrominance values to a &lt;br /&gt;
          proper YUV colorspace using the conversion tables in Appendix A&lt;br /&gt;
      if uniq flag is -1&lt;br /&gt;
        uniq flag = 0&lt;br /&gt;
&lt;br /&gt;
== Gradient Fill Patterns ==&lt;br /&gt;
&lt;br /&gt;
The ULTI codec has 9 gradient fill patterns for painting 4x4 sub blocks of luminance data using 4 luminance samples.&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 0:&lt;br /&gt;
  0 1 2 3&lt;br /&gt;
  0 1 2 3&lt;br /&gt;
  0 1 2 3&lt;br /&gt;
  0 1 2 3&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 1:&lt;br /&gt;
  1 2 3 3&lt;br /&gt;
  0 1 2 3&lt;br /&gt;
  0 1 2 3&lt;br /&gt;
  0 0 1 2&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 2:&lt;br /&gt;
  1 2 3 3&lt;br /&gt;
  1 2 2 3&lt;br /&gt;
  0 1 1 2&lt;br /&gt;
  0 0 1 2&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 3:&lt;br /&gt;
  2 3 3 3&lt;br /&gt;
  1 2 2 3&lt;br /&gt;
  0 1 1 2&lt;br /&gt;
  0 0 0 1&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 4:&lt;br /&gt;
  3 3 3 3&lt;br /&gt;
  2 2 2 2&lt;br /&gt;
  1 1 1 1&lt;br /&gt;
  0 0 0 0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 5:&lt;br /&gt;
  3 3 3 2&lt;br /&gt;
  3 2 2 1&lt;br /&gt;
  2 1 1 0&lt;br /&gt;
  1 0 0 0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 6:&lt;br /&gt;
  3 3 2 2&lt;br /&gt;
  3 2 1 1&lt;br /&gt;
  2 2 1 0&lt;br /&gt;
  1 1 0 0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 7:&lt;br /&gt;
  3 3 2 1&lt;br /&gt;
  3 2 1 0&lt;br /&gt;
  3 2 1 0&lt;br /&gt;
  2 1 0 0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 8:&lt;br /&gt;
  0 0 1 1&lt;br /&gt;
  0 0 1 1&lt;br /&gt;
  2 2 3 3&lt;br /&gt;
  2 2 3 3&lt;br /&gt;
&lt;br /&gt;
== Converting UltiMotion Scaled YUV To Correct YUV ==&lt;br /&gt;
&lt;br /&gt;
To convert UltiMotion 6-bit luminance values to proper luminance samples, use the following conversion table:&lt;br /&gt;
&lt;br /&gt;
 unsigned char ulti_lumas[64] =&lt;br /&gt;
    { 0x10, 0x13, 0x17, 0x1A, 0x1E, 0x21, 0x25, 0x28,&lt;br /&gt;
      0x2C, 0x2F, 0x33, 0x36, 0x3A, 0x3D, 0x41, 0x44,&lt;br /&gt;
      0x48, 0x4B, 0x4F, 0x52, 0x56, 0x59, 0x5C, 0x60,&lt;br /&gt;
      0x63, 0x67, 0x6A, 0x6E, 0x71, 0x75, 0x78, 0x7C,&lt;br /&gt;
      0x7F, 0x83, 0x86, 0x8A, 0x8D, 0x91, 0x94, 0x98,&lt;br /&gt;
      0x9B, 0x9F, 0xA2, 0xA5, 0xA9, 0xAC, 0xB0, 0xB3,&lt;br /&gt;
      0xB7, 0xBA, 0xBE, 0xC1, 0xC5, 0xC8, 0xCC, 0xCF,&lt;br /&gt;
      0xD3, 0xD6, 0xDA, 0xDD, 0xE1, 0xE4, 0xE8, 0xEB};&lt;br /&gt;
      &lt;br /&gt;
To convert UltiMotion 4-bit chrominance values to proper chrominance samples, use the following conversion table:&lt;br /&gt;
&lt;br /&gt;
 unsigned char ulti_chromas[16] =&lt;br /&gt;
    { 0x60, 0x67, 0x6D, 0x73, 0x7A, 0x80, 0x86, 0x8D,&lt;br /&gt;
      0x93, 0x99, 0xA0, 0xA6, 0xAC, 0xB3, 0xB9, 0xC0};&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* [http://xanim.polter.net/ XAnim]&lt;br /&gt;
&lt;br /&gt;
* [http://mplayerhq.hu/cgi-bin/cvsweb.cgi/~checkout~/ffmpeg/libavcodec/ulti_cb.h?content-type=text/x-cvsweb-markup&amp;amp;cvsroot=FFMpeg UltiMotion Luminance Codebook]&lt;br /&gt;
&lt;br /&gt;
[[Category:Video Codecs]]&lt;/div&gt;</summary>
		<author><name>Ultimotion</name></author>
	</entry>
	<entry>
		<id>https://wiki.multimedia.cx/index.php?title=IBM_UltiMotion&amp;diff=6215</id>
		<title>IBM UltiMotion</title>
		<link rel="alternate" type="text/html" href="https://wiki.multimedia.cx/index.php?title=IBM_UltiMotion&amp;diff=6215"/>
		<updated>2006-10-11T17:40:15Z</updated>

		<summary type="html">&lt;p&gt;Ultimotion: /* Decoding Algorithm */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;''This page is based on the document 'Description of the IBM UltiMotion (ULTI) Video Codec' by Mike Melanson and Konstantin Shishkov found at [http://multimedia.cx/ultimotion-format.txt http://multimedia.cx/ultimotion-format.txt].''&lt;br /&gt;
&lt;br /&gt;
* FourCC: ULTI&lt;br /&gt;
* Company: [[IBM]]&lt;br /&gt;
* Official Description: [http://multimedia.cx/UMSPEC.ZIP http://multimedia.cx/UMSPEC.ZIP]&lt;br /&gt;
* Samples: [http://samples.mplayerhq.hu/V-codecs/ULTI/ http://samples.mplayerhq.hu/V-codecs/ULTI/]&lt;br /&gt;
&lt;br /&gt;
IBM UltiMotion (henceforth ULTI) is a video codec typically seen in [[AVI]] files, though there is no reason it could not be used in other container formats. &lt;br /&gt;
&lt;br /&gt;
== Decoding Algorithm ==&lt;br /&gt;
&lt;br /&gt;
The ULTI algorithm operates natively on a scaled-down [[Raw YUV|YUV]] 4:1:0 planar colorspace. This means that for each 4x4 block of pixels, each of the 16 pixels has a luminance (Y) sample and the entire block shares one blue&lt;br /&gt;
chrominance sample (C&amp;lt;sub&amp;gt;b&amp;lt;/sub&amp;gt; or U) and one red chrominance sample (C&amp;lt;sub&amp;gt;r&amp;lt;/sub&amp;gt; or V). The colorspace is actually non-linear quantized to fixed values from 2 tables. Indices into these tables (64 possible values for luminance and 16 for chrominance) are transmitted in the final bitstream.&lt;br /&gt;
&lt;br /&gt;
The ULTI algorithm codes a frame by dividing it into a series of 8x8 blocks. Each 8x8 block is subdivided and coded as 4 4x4 blocks. The 4 sub blocks, 0-3, are coded in the following arrangement:&lt;br /&gt;
&lt;br /&gt;
  0 3&lt;br /&gt;
  1 2&lt;br /&gt;
&lt;br /&gt;
Each block can be coded using the same chrominance samples, or each sub block can be coded with its own pair of chrominance samples. Each sub block has 16 luminance samples that can be coded using a variety of methods.&lt;br /&gt;
&lt;br /&gt;
To decode a frame of UltiMotion data, follow this process:&lt;br /&gt;
&lt;br /&gt;
 initialize uniq and mode flags to 0&lt;br /&gt;
 &lt;br /&gt;
 for each 8x8 block in the frame, iterating from left -&amp;gt; right, top -&amp;gt; bottom:&lt;br /&gt;
 &lt;br /&gt;
  get the next byte in the stream (b0)&lt;br /&gt;
  if (b0 &amp;amp; 0xF8) == 0x70, handle escape code:&lt;br /&gt;
    if b0 is 0x70&lt;br /&gt;
      mode = next byte in stream&lt;br /&gt;
      note: only mode values of 0 or 1 are valid&lt;br /&gt;
    if b0 is 0x71&lt;br /&gt;
      uniq flag = -1 &lt;br /&gt;
    if b0 is 0x72&lt;br /&gt;
      toggle mode flag (0/1)&lt;br /&gt;
    if b0 is 0x73&lt;br /&gt;
      end of frame, stop decoding&lt;br /&gt;
    if b0 is 0x74&lt;br /&gt;
      get the next byte in stream (b1)&lt;br /&gt;
      skip next (b1) blocks in the output frame (unchanged from previous &lt;br /&gt;
        frame)&lt;br /&gt;
 &lt;br /&gt;
  else&lt;br /&gt;
    if b0 is non-zero and uniq flag is 0&lt;br /&gt;
      chrominance byte = next byte from stream&lt;br /&gt;
 &lt;br /&gt;
    for each 4x4 sub block in the block, arranged in the sub block pattern:&lt;br /&gt;
 &lt;br /&gt;
      extract sub block coding mode from b0:&lt;br /&gt;
        bits 7-6: sub block 0 coding mode&lt;br /&gt;
        bits 5-4: sub block 1 coding mode&lt;br /&gt;
        bits 3-2: sub block 2 coding mode&lt;br /&gt;
        bits 1-0: sub block 3 coding mode&lt;br /&gt;
 &lt;br /&gt;
      if coding mode is non-zero and uniq flag is non-zero&lt;br /&gt;
        chrominance byte = next byte from stream&lt;br /&gt;
 &lt;br /&gt;
      coding mode 0:&lt;br /&gt;
        skip sub block (unchanged from the previous frame)&lt;br /&gt;
 &lt;br /&gt;
      coding mode 1:&lt;br /&gt;
        paint the luminance samples using a gradient pattern based on one &lt;br /&gt;
          6-bit sample coded in the stream&lt;br /&gt;
 &lt;br /&gt;
        get next byte from stream (b0)&lt;br /&gt;
        bits 7-6 of b0 indicate gradient fill pattern:&lt;br /&gt;
          0 = gradient fill pattern 0&lt;br /&gt;
          1 = gradient fill pattern 2&lt;br /&gt;
          2 = gradient fill pattern 6&lt;br /&gt;
          3 = gradient fill pattern 4, swap Y0 with Y3 and Y1 with Y2 &lt;br /&gt;
              after unpacking Y samples&lt;br /&gt;
        bits 5-0 of b1 indicate luminance sample Y0&lt;br /&gt;
        Y1 = Y0&lt;br /&gt;
        if gradient fill pattern is pattern 0&lt;br /&gt;
          Y2 = Y0 + 1 (saturated to an upper limit of 0x3F)&lt;br /&gt;
          Y3 = Y2&lt;br /&gt;
        else&lt;br /&gt;
          Y2 = Y3 = Y0&lt;br /&gt;
        fill luminance samples according to Y0..Y3 and the gradient fill &lt;br /&gt;
          pattern (see section Gradient Fill Patterns)&lt;br /&gt;
 &lt;br /&gt;
      coding mode 2:&lt;br /&gt;
        paint the luminance samples using a gradient pattern based on &lt;br /&gt;
          either 4 6-bit samples coded in the stream or 4 6-bit samples &lt;br /&gt;
          retrieved from a 16,384-entry codebook using an index coded in &lt;br /&gt;
          the stream&lt;br /&gt;
        if mode is non-zero&lt;br /&gt;
          get the next 3 bytes from the stream as a big endian 24-bit &lt;br /&gt;
            number:&lt;br /&gt;
          Y0 = bits 23-18&lt;br /&gt;
          Y1 = bits 17-12&lt;br /&gt;
          Y2 = bits 11-6&lt;br /&gt;
          Y3 = bits 5-0&lt;br /&gt;
          fill luminance samples according to Y0..Y3 and gradient fill &lt;br /&gt;
            pattern 8 (see section Gradient Fill Patterns)&lt;br /&gt;
 &lt;br /&gt;
        else (mode is 0)&lt;br /&gt;
          get the next 2 bytes from the stream as a big endian 16-bit &lt;br /&gt;
            number:&lt;br /&gt;
          gradient fill pattern = bits 15-12&lt;br /&gt;
          luminance codebook index = bits 11-0&lt;br /&gt;
          Y0..Y3 are set according to the codebook entry (see References &lt;br /&gt;
            for UltiMotion luminance codebook)&lt;br /&gt;
          if bit 3 of the gradient fill pattern is set, swap Y0 with Y3 &lt;br /&gt;
            and Y1 with Y2; clear bit 3 of the gradient fill pattern&lt;br /&gt;
          fill luminance samples according to Y0..Y3 and the gradient fill &lt;br /&gt;
            pattern (see section Gradient Fill Patterns)&lt;br /&gt;
 &lt;br /&gt;
      coding mode 3:&lt;br /&gt;
        flexible coding mode that can paint the luminance samples with 16 &lt;br /&gt;
          6-bit samples coded in the stream, or with a gradient fill &lt;br /&gt;
          pattern and 4 6-bit luminance samples coded in the stream, or &lt;br /&gt;
          with an arbitrary pattern using 2 luminance samples and a set of &lt;br /&gt;
          flags coded in the stream&lt;br /&gt;
        if mode is non-zero&lt;br /&gt;
          get the next 16 6-bit numbers from the stream as the 16 &lt;br /&gt;
            luminance samples for the sub block, thus consuming 96 bits, &lt;br /&gt;
            or 12 bytes from the stream&lt;br /&gt;
        if mode is 0&lt;br /&gt;
          get the next byte in the stream (b0)&lt;br /&gt;
          if bit 7 of b0 is set&lt;br /&gt;
            gradient fill pattern = bits 6-4 of b0&lt;br /&gt;
            get the next byte in the stream (b1)&lt;br /&gt;
            Y0 = ((b0 &amp;amp; 0x0F) &amp;lt;&amp;lt; 2) | (b1 &amp;gt;&amp;gt; 6)&lt;br /&gt;
            Y1 = bits 5-0 of b1&lt;br /&gt;
            Y2 = next byte in stream &amp;amp; 0x3F&lt;br /&gt;
            Y3 = next byte in stream &amp;amp; 0x3F&lt;br /&gt;
            fill luminance samples according to Y0..Y3 and the gradient &lt;br /&gt;
              fill pattern (see section Gradient Fill Patterns)&lt;br /&gt;
          else&lt;br /&gt;
            flagsA = b0&lt;br /&gt;
            flagsB = next byte in the stream&lt;br /&gt;
            Y0 = next byte in stream &amp;amp; 0x3F&lt;br /&gt;
            Y1 = next byte in stream &amp;amp; 0x3F&lt;br /&gt;
            the 16 bits between flagsA and flagsB represent the pattern &lt;br /&gt;
              used to place either Y0 or Y1 into the luminance grid&lt;br /&gt;
 &lt;br /&gt;
              A7 A6 A5 A4&lt;br /&gt;
              A3 A2 A1 A0&lt;br /&gt;
              B7 B6 B5 B4&lt;br /&gt;
              B3 B2 B1 B0&lt;br /&gt;
 &lt;br /&gt;
              for example, if bit 3 of flagsB is 1, Y1 would be used in &lt;br /&gt;
              the lower left corner of the sub block, else Y0&lt;br /&gt;
 &lt;br /&gt;
      finally, output sub block:&lt;br /&gt;
        bits 7-4 of the chrominance byte represent the red chrominance &lt;br /&gt;
          value for the sub block while bits 3-0 represent the blue value&lt;br /&gt;
        convert the 16 luminance values and the 2 chrominance values to a &lt;br /&gt;
          proper YUV colorspace using the conversion tables in Appendix A&lt;br /&gt;
      if uniq flag is -1&lt;br /&gt;
        uniq flag = 0&lt;br /&gt;
&lt;br /&gt;
== Gradient Fill Patterns ==&lt;br /&gt;
&lt;br /&gt;
The ULTI codec has 9 gradient fill patterns for painting 4x4 sub blocks of luminance data using 4 luminance samples.&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 0:&lt;br /&gt;
  0 1 2 3&lt;br /&gt;
  0 1 2 3&lt;br /&gt;
  0 1 2 3&lt;br /&gt;
  0 1 2 3&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 1:&lt;br /&gt;
  1 2 3 3&lt;br /&gt;
  0 1 2 3&lt;br /&gt;
  0 1 2 3&lt;br /&gt;
  0 0 1 2&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 2:&lt;br /&gt;
  1 2 3 3&lt;br /&gt;
  1 2 2 3&lt;br /&gt;
  0 1 1 2&lt;br /&gt;
  0 0 1 2&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 3:&lt;br /&gt;
  2 3 3 3&lt;br /&gt;
  1 2 2 3&lt;br /&gt;
  0 1 1 2&lt;br /&gt;
  0 0 0 1&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 4:&lt;br /&gt;
  3 3 3 3&lt;br /&gt;
  2 2 2 2&lt;br /&gt;
  1 1 1 1&lt;br /&gt;
  0 0 0 0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 5:&lt;br /&gt;
  3 3 3 2&lt;br /&gt;
  3 2 2 1&lt;br /&gt;
  2 1 1 0&lt;br /&gt;
  1 0 0 0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 6:&lt;br /&gt;
  3 3 2 2&lt;br /&gt;
  3 2 1 1&lt;br /&gt;
  2 2 1 0&lt;br /&gt;
  1 1 0 0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 7:&lt;br /&gt;
  3 3 2 1&lt;br /&gt;
  3 2 1 0&lt;br /&gt;
  3 2 1 0&lt;br /&gt;
  2 1 0 0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 8:&lt;br /&gt;
  0 0 1 1&lt;br /&gt;
  0 0 1 1&lt;br /&gt;
  2 2 3 3&lt;br /&gt;
  2 2 3 3&lt;br /&gt;
&lt;br /&gt;
== Converting UltiMotion Scaled YUV To Correct YUV ==&lt;br /&gt;
&lt;br /&gt;
To convert UltiMotion 6-bit luminance values to proper luminance samples, use the following conversion table:&lt;br /&gt;
&lt;br /&gt;
 unsigned char ulti_lumas[64] =&lt;br /&gt;
    { 0x10, 0x13, 0x17, 0x1A, 0x1E, 0x21, 0x25, 0x28,&lt;br /&gt;
      0x2C, 0x2F, 0x33, 0x36, 0x3A, 0x3D, 0x41, 0x44,&lt;br /&gt;
      0x48, 0x4B, 0x4F, 0x52, 0x56, 0x59, 0x5C, 0x60,&lt;br /&gt;
      0x63, 0x67, 0x6A, 0x6E, 0x71, 0x75, 0x78, 0x7C,&lt;br /&gt;
      0x7F, 0x83, 0x86, 0x8A, 0x8D, 0x91, 0x94, 0x98,&lt;br /&gt;
      0x9B, 0x9F, 0xA2, 0xA5, 0xA9, 0xAC, 0xB0, 0xB3,&lt;br /&gt;
      0xB7, 0xBA, 0xBE, 0xC1, 0xC5, 0xC8, 0xCC, 0xCF,&lt;br /&gt;
      0xD3, 0xD6, 0xDA, 0xDD, 0xE1, 0xE4, 0xE8, 0xEB};&lt;br /&gt;
      &lt;br /&gt;
To convert UltiMotion 4-bit chrominance values to proper chrominance samples, use the following conversion table:&lt;br /&gt;
&lt;br /&gt;
 unsigned char ulti_chromas[16] =&lt;br /&gt;
    { 0x60, 0x67, 0x6D, 0x73, 0x7A, 0x80, 0x86, 0x8D,&lt;br /&gt;
      0x93, 0x99, 0xA0, 0xA6, 0xAC, 0xB3, 0xB9, 0xC0};&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* [http://xanim.polter.net/ XAnim]&lt;br /&gt;
&lt;br /&gt;
* [http://mplayerhq.hu/cgi-bin/cvsweb.cgi/~checkout~/ffmpeg/libavcodec/ulti_cb.h?content-type=text/x-cvsweb-markup&amp;amp;cvsroot=FFMpeg UltiMotion Luminance Codebook]&lt;br /&gt;
&lt;br /&gt;
[[Category:Video Codecs]]&lt;/div&gt;</summary>
		<author><name>Ultimotion</name></author>
	</entry>
	<entry>
		<id>https://wiki.multimedia.cx/index.php?title=IBM_UltiMotion&amp;diff=6214</id>
		<title>IBM UltiMotion</title>
		<link rel="alternate" type="text/html" href="https://wiki.multimedia.cx/index.php?title=IBM_UltiMotion&amp;diff=6214"/>
		<updated>2006-10-11T16:57:45Z</updated>

		<summary type="html">&lt;p&gt;Ultimotion: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;''This page is based on the document 'Description of the IBM UltiMotion (ULTI) Video Codec' by Mike Melanson and Konstantin Shishkov found at [http://multimedia.cx/ultimotion-format.txt http://multimedia.cx/ultimotion-format.txt].''&lt;br /&gt;
&lt;br /&gt;
* FourCC: ULTI&lt;br /&gt;
* Company: [[IBM]]&lt;br /&gt;
* Official Description: [http://multimedia.cx/UMSPEC.ZIP http://multimedia.cx/UMSPEC.ZIP]&lt;br /&gt;
* Samples: [http://samples.mplayerhq.hu/V-codecs/ULTI/ http://samples.mplayerhq.hu/V-codecs/ULTI/]&lt;br /&gt;
&lt;br /&gt;
IBM UltiMotion (henceforth ULTI) is a video codec typically seen in [[AVI]] files, though there is no reason it could not be used in other container formats. &lt;br /&gt;
&lt;br /&gt;
== Decoding Algorithm ==&lt;br /&gt;
&lt;br /&gt;
The ULTI algorithm operates natively on a scaled-down [[Raw YUV|YUV]] 4:1:0 planar colorspace. This means that for each 4x4 block of pixels, each of the 16 pixels has a luminance (Y) sample and the entire block shares one blue&lt;br /&gt;
chrominance sample (C&amp;lt;sub&amp;gt;b&amp;lt;/sub&amp;gt; or U) and one red chrominance sample (C&amp;lt;sub&amp;gt;r&amp;lt;/sub&amp;gt; or V). The colorspace is actually non-linear quantized to fixed values from 2 tables. Indices into these tables (64 possible values for luminance and 16 for chrominance) are transmitted in the final bitstream.&lt;br /&gt;
&lt;br /&gt;
The ULTI algorithm codes a frame by dividing it into a series of 8x8 blocks. Each 8x8 block is subdivided and coded as 4 4x4 blocks. The 4 sub blocks, 0-3, are coded in the following arrangement:&lt;br /&gt;
&lt;br /&gt;
  0 3&lt;br /&gt;
  1 2&lt;br /&gt;
&lt;br /&gt;
Each block can be coded using the same chrominance samples, or each sub block can be coded with its own pair of chrominance samples. Each sub block has 16 luminance samples that can be coded using a variety of methods.&lt;br /&gt;
&lt;br /&gt;
To decode a frame of UltiMotion data, follow this process:&lt;br /&gt;
&lt;br /&gt;
 initialize uniq and mode flags to 0&lt;br /&gt;
 &lt;br /&gt;
 for each 8x8 block in the frame, iterating from left -&amp;gt; right, top -&amp;gt; bottom:&lt;br /&gt;
 &lt;br /&gt;
  get the next byte in the stream (b0)&lt;br /&gt;
  if (b0 &amp;amp; 0xF8) == 0x70, handle escape code:&lt;br /&gt;
    if b0 is 0x70&lt;br /&gt;
      mode = next byte in stream&lt;br /&gt;
      note: only mode values of 0 or 1 are valid&lt;br /&gt;
    if b0 is 0x71&lt;br /&gt;
      uniq flag = -1 &lt;br /&gt;
    if b0 is 0x72&lt;br /&gt;
      toggle mode flag (0/1)&lt;br /&gt;
    if b0 is 0x73&lt;br /&gt;
      end of frame, stop decoding&lt;br /&gt;
    if b0 is 0x74&lt;br /&gt;
      get the next byte in stream (b1)&lt;br /&gt;
      skip next (b1) blocks in the output frame (unchanged from previous &lt;br /&gt;
        frame)&lt;br /&gt;
 &lt;br /&gt;
  else&lt;br /&gt;
    if b0 is non-zero and uniq flag is 0&lt;br /&gt;
      chrominance byte = next byte from stream&lt;br /&gt;
&lt;br /&gt;
    for each 4x4 sub block in the block, arranged in the sub block pattern:&lt;br /&gt;
 &lt;br /&gt;
      extract sub block coding mode from b0:&lt;br /&gt;
        bits 7-6: sub block 0 coding mode&lt;br /&gt;
        bits 5-4: sub block 1 coding mode&lt;br /&gt;
        bits 3-2: sub block 2 coding mode&lt;br /&gt;
        bits 1-0: sub block 3 coding mode&lt;br /&gt;
 &lt;br /&gt;
      if coding mode is non-zero and uniq flag is non-zero&lt;br /&gt;
        chrominance byte = next byte from stream&lt;br /&gt;
 &lt;br /&gt;
      coding mode 0:&lt;br /&gt;
        skip sub block (unchanged from the previous frame)&lt;br /&gt;
 &lt;br /&gt;
      coding mode 1:&lt;br /&gt;
        paint the luminance samples using a gradient pattern based on one &lt;br /&gt;
          6-bit sample coded in the stream&lt;br /&gt;
 &lt;br /&gt;
        get next byte from stream (b0)&lt;br /&gt;
        bits 7-6 of b0 indicate gradient fill pattern:&lt;br /&gt;
          0 = gradient fill pattern 0&lt;br /&gt;
          1 = gradient fill pattern 2&lt;br /&gt;
          2 = gradient fill pattern 6&lt;br /&gt;
          3 = gradient fill pattern 4, swap Y0 with Y3 and Y1 with Y2 &lt;br /&gt;
              after unpacking Y samples&lt;br /&gt;
        bits 5-0 of b1 indicate luminance sample Y0&lt;br /&gt;
        Y1 = Y0&lt;br /&gt;
        if gradient fill pattern is pattern 0&lt;br /&gt;
          Y2 = Y0 + 1 (saturated to an upper limit of 0x3F)&lt;br /&gt;
          Y3 = Y2&lt;br /&gt;
        else&lt;br /&gt;
          Y2 = Y3 = Y0&lt;br /&gt;
        fill luminance samples according to Y0..Y3 and the gradient fill &lt;br /&gt;
          pattern (see section Gradient Fill Patterns)&lt;br /&gt;
 &lt;br /&gt;
      coding mode 2:&lt;br /&gt;
        paint the luminance samples using a gradient pattern based on &lt;br /&gt;
          either 4 6-bit samples coded in the stream or 4 6-bit samples &lt;br /&gt;
          retrieved from a 16,384-entry codebook using an index coded in &lt;br /&gt;
          the stream&lt;br /&gt;
        if mode is non-zero&lt;br /&gt;
          get the next 3 bytes from the stream as a big endian 24-bit &lt;br /&gt;
            number:&lt;br /&gt;
          Y0 = bits 23-18&lt;br /&gt;
          Y1 = bits 17-12&lt;br /&gt;
          Y2 = bits 11-6&lt;br /&gt;
          Y3 = bits 5-0&lt;br /&gt;
          fill luminance samples according to Y0..Y3 and gradient fill &lt;br /&gt;
            pattern 8 (see section Gradient Fill Patterns)&lt;br /&gt;
 &lt;br /&gt;
        else (mode is 0)&lt;br /&gt;
          get the next 2 bytes from the stream as a big endian 16-bit &lt;br /&gt;
            number:&lt;br /&gt;
          gradient fill pattern = bits 15-12&lt;br /&gt;
          luminance codebook index = bits 11-0&lt;br /&gt;
          Y0..Y3 are set according to the codebook entry (see References &lt;br /&gt;
            for UltiMotion luminance codebook)&lt;br /&gt;
          if bit 3 of the gradient fill pattern is set, swap Y0 with Y3 &lt;br /&gt;
            and Y1 with Y2; clear bit 3 of the gradient fill pattern&lt;br /&gt;
          fill luminance samples according to Y0..Y3 and the gradient fill &lt;br /&gt;
            pattern (see section Gradient Fill Patterns)&lt;br /&gt;
 &lt;br /&gt;
      coding mode 3:&lt;br /&gt;
        flexible coding mode that can paint the luminance samples with 16 &lt;br /&gt;
          6-bit samples coded in the stream, or with a gradient fill &lt;br /&gt;
          pattern and 4 6-bit luminance samples coded in the stream, or &lt;br /&gt;
          with an arbitrary pattern using 2 luminance samples and a set of &lt;br /&gt;
          flags coded in the stream&lt;br /&gt;
        if mode is non-zero&lt;br /&gt;
          get the next 16 6-bit numbers from the stream as the 16 &lt;br /&gt;
            luminance samples for the sub block, thus consuming 96 bits, &lt;br /&gt;
            or 12 bytes from the stream&lt;br /&gt;
        if mode is 0&lt;br /&gt;
          get the next byte in the stream (b0)&lt;br /&gt;
          if bit 7 of b0 is set&lt;br /&gt;
            gradient fill pattern = bits 6-4 of b0&lt;br /&gt;
            get the next byte in the stream (b1)&lt;br /&gt;
            Y0 = ((b0 &amp;amp; 0x0F) &amp;lt;&amp;lt; 2) | (b1 &amp;gt;&amp;gt; 6)&lt;br /&gt;
            Y1 = bits 5-0 of b1&lt;br /&gt;
            Y2 = next byte in stream &amp;amp; 0x3F&lt;br /&gt;
            Y3 = next byte in stream &amp;amp; 0x3F&lt;br /&gt;
            fill luminance samples according to Y0..Y3 and the gradient &lt;br /&gt;
              fill pattern (see section Gradient Fill Patterns)&lt;br /&gt;
          else&lt;br /&gt;
            flagsA = b0&lt;br /&gt;
            flagsB = next byte in the stream&lt;br /&gt;
            Y0 = next byte in stream &amp;amp; 0x3F&lt;br /&gt;
            Y1 = next byte in stream &amp;amp; 0x3F&lt;br /&gt;
            the 16 bits between flagsA and flagsB represent the pattern &lt;br /&gt;
              used to place either Y0 or Y1 into the luminance grid&lt;br /&gt;
 &lt;br /&gt;
              A7 A6 A5 A4&lt;br /&gt;
              A3 A2 A1 A0&lt;br /&gt;
              B7 B6 B5 B4&lt;br /&gt;
              B3 B2 B1 B0&lt;br /&gt;
 &lt;br /&gt;
              for example, if bit 3 of flagsB is 1, Y1 would be used in &lt;br /&gt;
              the lower left corner of the sub block, else Y0&lt;br /&gt;
 &lt;br /&gt;
      finally, output sub block:&lt;br /&gt;
        bits 7-4 of the chrominance byte represent the red chrominance &lt;br /&gt;
          value for the sub block while bits 3-0 represent the blue value&lt;br /&gt;
        convert the 16 luminance values and the 2 chrominance values to a &lt;br /&gt;
          proper YUV colorspace using the conversion tables in Appendix A&lt;br /&gt;
      if uniq flag is -1&lt;br /&gt;
        uniq flag = 0&lt;br /&gt;
&lt;br /&gt;
== Gradient Fill Patterns ==&lt;br /&gt;
&lt;br /&gt;
The ULTI codec has 9 gradient fill patterns for painting 4x4 sub blocks of luminance data using 4 luminance samples.&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 0:&lt;br /&gt;
  0 1 2 3&lt;br /&gt;
  0 1 2 3&lt;br /&gt;
  0 1 2 3&lt;br /&gt;
  0 1 2 3&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 1:&lt;br /&gt;
  1 2 3 3&lt;br /&gt;
  0 1 2 3&lt;br /&gt;
  0 1 2 3&lt;br /&gt;
  0 0 1 2&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 2:&lt;br /&gt;
  1 2 3 3&lt;br /&gt;
  1 2 2 3&lt;br /&gt;
  0 1 1 2&lt;br /&gt;
  0 0 1 2&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 3:&lt;br /&gt;
  2 3 3 3&lt;br /&gt;
  1 2 2 3&lt;br /&gt;
  0 1 1 2&lt;br /&gt;
  0 0 0 1&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 4:&lt;br /&gt;
  3 3 3 3&lt;br /&gt;
  2 2 2 2&lt;br /&gt;
  1 1 1 1&lt;br /&gt;
  0 0 0 0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 5:&lt;br /&gt;
  3 3 3 2&lt;br /&gt;
  3 2 2 1&lt;br /&gt;
  2 1 1 0&lt;br /&gt;
  1 0 0 0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 6:&lt;br /&gt;
  3 3 2 2&lt;br /&gt;
  3 2 1 1&lt;br /&gt;
  2 2 1 0&lt;br /&gt;
  1 1 0 0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 7:&lt;br /&gt;
  3 3 2 1&lt;br /&gt;
  3 2 1 0&lt;br /&gt;
  3 2 1 0&lt;br /&gt;
  2 1 0 0&lt;br /&gt;
&lt;br /&gt;
* Gradient Pattern 8:&lt;br /&gt;
  0 0 1 1&lt;br /&gt;
  0 0 1 1&lt;br /&gt;
  2 2 3 3&lt;br /&gt;
  2 2 3 3&lt;br /&gt;
&lt;br /&gt;
== Converting UltiMotion Scaled YUV To Correct YUV ==&lt;br /&gt;
&lt;br /&gt;
To convert UltiMotion 6-bit luminance values to proper luminance samples, use the following conversion table:&lt;br /&gt;
&lt;br /&gt;
 unsigned char ulti_lumas[64] =&lt;br /&gt;
    { 0x10, 0x13, 0x17, 0x1A, 0x1E, 0x21, 0x25, 0x28,&lt;br /&gt;
      0x2C, 0x2F, 0x33, 0x36, 0x3A, 0x3D, 0x41, 0x44,&lt;br /&gt;
      0x48, 0x4B, 0x4F, 0x52, 0x56, 0x59, 0x5C, 0x60,&lt;br /&gt;
      0x63, 0x67, 0x6A, 0x6E, 0x71, 0x75, 0x78, 0x7C,&lt;br /&gt;
      0x7F, 0x83, 0x86, 0x8A, 0x8D, 0x91, 0x94, 0x98,&lt;br /&gt;
      0x9B, 0x9F, 0xA2, 0xA5, 0xA9, 0xAC, 0xB0, 0xB3,&lt;br /&gt;
      0xB7, 0xBA, 0xBE, 0xC1, 0xC5, 0xC8, 0xCC, 0xCF,&lt;br /&gt;
      0xD3, 0xD6, 0xDA, 0xDD, 0xE1, 0xE4, 0xE8, 0xEB};&lt;br /&gt;
      &lt;br /&gt;
To convert UltiMotion 4-bit chrominance values to proper chrominance samples, use the following conversion table:&lt;br /&gt;
&lt;br /&gt;
 unsigned char ulti_chromas[16] =&lt;br /&gt;
    { 0x60, 0x67, 0x6D, 0x73, 0x7A, 0x80, 0x86, 0x8D,&lt;br /&gt;
      0x93, 0x99, 0xA0, 0xA6, 0xAC, 0xB3, 0xB9, 0xC0};&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* [http://xanim.polter.net/ XAnim]&lt;br /&gt;
&lt;br /&gt;
* [http://mplayerhq.hu/cgi-bin/cvsweb.cgi/~checkout~/ffmpeg/libavcodec/ulti_cb.h?content-type=text/x-cvsweb-markup&amp;amp;cvsroot=FFMpeg UltiMotion Luminance Codebook]&lt;br /&gt;
&lt;br /&gt;
[[Category:Video Codecs]]&lt;/div&gt;</summary>
		<author><name>Ultimotion</name></author>
	</entry>
</feed>