View Javadoc

1   package de.desy.video.sw;
2   
3   /**
4    * <code>CHuffmanDecompression</code> is a wrapper class around HuffYUV open source
5    * video codec v1.2.3 huffman-based video data decompression.<br>
6    * <br>
7    * It basically is a pure Java rewrite of simple C++ source code of HuffYUV 1.2.3.
8    * The HuffYUV site where the original C++ code was taken from in 2002 was situated at 
9    * Berkeley University, but is no longer available. A archived version of it can be 
10   * found at http://neuron2.net/www.math.berkeley.edu/benrg/huffyuv.html 
11   * (last checked July 19, 2008). The original author of the C++ source is 
12   * Ben Rudiak-Gould.<br>
13   * <br>
14   *  This so-called HuffYUV compression is lossless and was adapted and used at 
15   *  Video System v2 in order to compress/uncompress grayscale data before/after 
16   *  transferring it over the network.<br>
17   *  <br>
18   *  Speed of pure Java implementation was (after optimization) much better than thought. 
19   *  I could not believe how fast Java code can get. Only necessary method to call is 
20   *  ({@link DecompressHuffYUV( byte[], int, byte [], int, int)}).
21   *  
22   * @author <a href="mailto:stefan.weisse@desy.de">Stefan Weisse</a>
23   * @version $Id: Templates.xml,v 1.10 2008/06/19 17:40:13 sweisse Exp $
24   *
25   */
26  
27  public final class CHuffmanDecompression {
28  
29  	/** HuffYUV table taken from C++ source */
30  	/* 2 512 */ 
31  	private static final int[][] decode_luma9 = {
32  			 { 0,  0},{ 0,  0},{ 0,  0},{ 0,  0},{ 0,  0},{ 0,  0},{ 0,  0},{ 0,  0},{ 0,  0},{ 0,  0},{ 0,  0},{ 0,  0},{ 0,  0},{ 0,  0},{ 0,  0},{ 0,  0},
33  			 { 0,  0},{ 0,  0},{ 0,  0},{ 0,  0},{ 0,  0},{ 0,  0},{ 0,  0},{ 0,  0},{ 0,  0},{ 0,  0},{ 0,  0},{ 0,  0},{ 0,  0},{ 0,  0},{ 0,  0},{ 0,  0},
34  			 { 0,  0},{ 0,  0},{ 0,  0},{ 9,213},{ 9, 31},{ 9,214},{ 9, 30},{ 9,215},{ 9,216},{ 9, 29},{ 9,217},{ 9,218},{ 9, 28},{ 9,219},{ 9, 27},{ 9,220},
35  			 { 9,221},{ 9, 26},{ 9, 25},{ 9,222},{ 9,223},{ 9, 24},{ 9,224},{ 9,225},{ 9, 23},{ 9,226},{ 9, 22},{ 9,227},{ 9,228},{ 9, 21},{ 9,229},{ 9,230},
36  			 { 9, 20},{ 9, 19},{ 9,231},{ 9,232},{ 9, 18},{ 9,233},{ 9, 17},{ 9,234},{ 9,235},{ 9, 16},{ 8, 15},{ 8, 15},{ 8,236},{ 8,236},{ 8, 14},{ 8, 14},
37  			 { 8,237},{ 8,237},{ 8, 13},{ 8, 13},{ 8,238},{ 8,238},{ 8,239},{ 8,239},{ 8, 12},{ 8, 12},{ 8, 11},{ 8, 11},{ 8,240},{ 8,240},{ 8,241},{ 8,241},
38  			 { 8, 10},{ 8, 10},{ 8,242},{ 8,242},{ 8,  9},{ 8,  9},{ 8,243},{ 8,243},{ 7,244},{ 7,244},{ 7,244},{ 7,244},{ 7,  8},{ 7,  8},{ 7,  8},{ 7,  8},
39  			 { 7,245},{ 7,245},{ 7,245},{ 7,245},{ 7,  7},{ 7,  7},{ 7,  7},{ 7,  7},{ 7,246},{ 7,246},{ 7,246},{ 7,246},{ 7,247},{ 7,247},{ 7,247},{ 7,247},
40  			 { 7,  6},{ 7,  6},{ 7,  6},{ 7,  6},{ 7,248},{ 7,248},{ 7,248},{ 7,248},{ 7,249},{ 7,249},{ 7,249},{ 7,249},{ 7,  5},{ 7,  5},{ 7,  5},{ 7,  5},
41  			 { 6,250},{ 6,250},{ 6,250},{ 6,250},{ 6,250},{ 6,250},{ 6,250},{ 6,250},{ 6,251},{ 6,251},{ 6,251},{ 6,251},{ 6,251},{ 6,251},{ 6,251},{ 6,251},
42  			 { 5,  4},{ 5,  4},{ 5,  4},{ 5,  4},{ 5,  4},{ 5,  4},{ 5,  4},{ 5,  4},{ 5,  4},{ 5,  4},{ 5,  4},{ 5,  4},{ 5,  4},{ 5,  4},{ 5,  4},{ 5,  4},
43  			 { 5,252},{ 5,252},{ 5,252},{ 5,252},{ 5,252},{ 5,252},{ 5,252},{ 5,252},{ 5,252},{ 5,252},{ 5,252},{ 5,252},{ 5,252},{ 5,252},{ 5,252},{ 5,252},
44  			 { 5,  3},{ 5,  3},{ 5,  3},{ 5,  3},{ 5,  3},{ 5,  3},{ 5,  3},{ 5,  3},{ 5,  3},{ 5,  3},{ 5,  3},{ 5,  3},{ 5,  3},{ 5,  3},{ 5,  3},{ 5,  3},
45  			 { 5,253},{ 5,253},{ 5,253},{ 5,253},{ 5,253},{ 5,253},{ 5,253},{ 5,253},{ 5,253},{ 5,253},{ 5,253},{ 5,253},{ 5,253},{ 5,253},{ 5,253},{ 5,253},
46  			 { 4,254},{ 4,254},{ 4,254},{ 4,254},{ 4,254},{ 4,254},{ 4,254},{ 4,254},{ 4,254},{ 4,254},{ 4,254},{ 4,254},{ 4,254},{ 4,254},{ 4,254},{ 4,254},
47  			 { 4,254},{ 4,254},{ 4,254},{ 4,254},{ 4,254},{ 4,254},{ 4,254},{ 4,254},{ 4,254},{ 4,254},{ 4,254},{ 4,254},{ 4,254},{ 4,254},{ 4,254},{ 4,254},
48  			 { 4,255},{ 4,255},{ 4,255},{ 4,255},{ 4,255},{ 4,255},{ 4,255},{ 4,255},{ 4,255},{ 4,255},{ 4,255},{ 4,255},{ 4,255},{ 4,255},{ 4,255},{ 4,255},
49  			 { 4,255},{ 4,255},{ 4,255},{ 4,255},{ 4,255},{ 4,255},{ 4,255},{ 4,255},{ 4,255},{ 4,255},{ 4,255},{ 4,255},{ 4,255},{ 4,255},{ 4,255},{ 4,255},
50  			 { 4,  1},{ 4,  1},{ 4,  1},{ 4,  1},{ 4,  1},{ 4,  1},{ 4,  1},{ 4,  1},{ 4,  1},{ 4,  1},{ 4,  1},{ 4,  1},{ 4,  1},{ 4,  1},{ 4,  1},{ 4,  1},
51  			 { 4,  1},{ 4,  1},{ 4,  1},{ 4,  1},{ 4,  1},{ 4,  1},{ 4,  1},{ 4,  1},{ 4,  1},{ 4,  1},{ 4,  1},{ 4,  1},{ 4,  1},{ 4,  1},{ 4,  1},{ 4,  1},
52  			 { 3,  2},{ 3,  2},{ 3,  2},{ 3,  2},{ 3,  2},{ 3,  2},{ 3,  2},{ 3,  2},{ 3,  2},{ 3,  2},{ 3,  2},{ 3,  2},{ 3,  2},{ 3,  2},{ 3,  2},{ 3,  2},
53  			 { 3,  2},{ 3,  2},{ 3,  2},{ 3,  2},{ 3,  2},{ 3,  2},{ 3,  2},{ 3,  2},{ 3,  2},{ 3,  2},{ 3,  2},{ 3,  2},{ 3,  2},{ 3,  2},{ 3,  2},{ 3,  2},
54  			 { 3,  2},{ 3,  2},{ 3,  2},{ 3,  2},{ 3,  2},{ 3,  2},{ 3,  2},{ 3,  2},{ 3,  2},{ 3,  2},{ 3,  2},{ 3,  2},{ 3,  2},{ 3,  2},{ 3,  2},{ 3,  2},
55  			 { 3,  2},{ 3,  2},{ 3,  2},{ 3,  2},{ 3,  2},{ 3,  2},{ 3,  2},{ 3,  2},{ 3,  2},{ 3,  2},{ 3,  2},{ 3,  2},{ 3,  2},{ 3,  2},{ 3,  2},{ 3,  2},
56  			 { 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},
57  			 { 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},
58  			 { 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},
59  			 { 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},
60  			 { 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},
61  			 { 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},
62  			 { 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},
63  			 { 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0},{ 2,  0}
64  			};
65  
66  	/** HuffYUV table taken from C++ source */
67  	/* 2 512 */
68  	private static final int[][] decode_luma12 = {
69  			 { 0,  0},{ 0,  0},{ 0,  0},{ 0,  0},{ 0,  0},{ 0,  0},{ 0,  0},{ 0,  0},{ 0,  0},{ 0,  0},{ 0,  0},{ 0,  0},{ 0,  0},{ 0,  0},{ 0,  0},{12, 94},
70  			 {12,177},{12, 93},{12, 92},{12,178},{12, 91},{12, 90},{12,179},{12, 89},{12, 88},{12,180},{12, 87},{12, 86},{12,181},{12, 85},{12, 84},{12, 83},
71  			 {12,182},{12, 82},{12, 81},{12, 80},{12,183},{12, 79},{11, 78},{11, 78},{11, 77},{11, 77},{11,184},{11,184},{11, 76},{11, 76},{11, 75},{11, 75},
72  			 {11, 74},{11, 74},{11,185},{11,185},{11, 73},{11, 73},{11, 72},{11, 72},{11, 71},{11, 71},{11,186},{11,186},{11, 70},{11, 70},{11, 69},{11, 69},
73  			 {11, 68},{11, 68},{11,187},{11,187},{11, 67},{11, 67},{11, 66},{11, 66},{11, 65},{11, 65},{11, 64},{11, 64},{11,188},{11,188},{11, 63},{11, 63},
74  			 {11, 62},{11, 62},{11, 61},{11, 61},{11,189},{11,189},{11, 60},{11, 60},{11, 59},{11, 59},{11,190},{11,190},{11, 58},{11, 58},{11, 57},{11, 57},
75  			 {11, 56},{11, 56},{11,191},{11,191},{10, 55},{10, 55},{10, 55},{10, 55},{10, 54},{10, 54},{10, 54},{10, 54},{10, 53},{10, 53},{10, 53},{10, 53},
76  			 {10,192},{10,192},{10,192},{10,192},{10, 52},{10, 52},{10, 52},{10, 52},{10, 51},{10, 51},{10, 51},{10, 51},{10,193},{10,193},{10,193},{10,193},
77  			 {10, 50},{10, 50},{10, 50},{10, 50},{10, 49},{10, 49},{10, 49},{10, 49},{10,194},{10,194},{10,194},{10,194},{10, 48},{10, 48},{10, 48},{10, 48},
78  			 {10, 47},{10, 47},{10, 47},{10, 47},{10,195},{10,195},{10,195},{10,195},{10, 46},{10, 46},{10, 46},{10, 46},{10, 45},{10, 45},{10, 45},{10, 45},
79  			 {10,196},{10,196},{10,196},{10,196},{10, 44},{10, 44},{10, 44},{10, 44},{10,197},{10,197},{10,197},{10,197},{10, 43},{10, 43},{10, 43},{10, 43},
80  			 {10,198},{10,198},{10,198},{10,198},{10, 42},{10, 42},{10, 42},{10, 42},{10, 41},{10, 41},{10, 41},{10, 41},{10,199},{10,199},{10,199},{10,199},
81  			 {10, 40},{10, 40},{10, 40},{10, 40},{10,200},{10,200},{10,200},{10,200},{10,201},{10,201},{10,201},{10,201},{10, 39},{10, 39},{10, 39},{10, 39},
82  			 {10,202},{10,202},{10,202},{10,202},{10, 38},{10, 38},{10, 38},{10, 38},{10,203},{10,203},{10,203},{10,203},{10, 37},{10, 37},{10, 37},{10, 37},
83  			 {10,204},{10,204},{10,204},{10,204},{10,205},{10,205},{10,205},{10,205},{10, 36},{10, 36},{10, 36},{10, 36},{10,206},{10,206},{10,206},{10,206},
84  			 {10,207},{10,207},{10,207},{10,207},{10, 35},{10, 35},{10, 35},{10, 35},{10,208},{10,208},{10,208},{10,208},{10, 34},{10, 34},{10, 34},{10, 34},
85  			 {10,209},{10,209},{10,209},{10,209},{10, 33},{10, 33},{10, 33},{10, 33},{10,210},{10,210},{10,210},{10,210},{10,211},{10,211},{10,211},{10,211},
86  			 {10, 32},{10, 32},{10, 32},{10, 32},{10,212},{10,212},{10,212},{10,212},{ 9,213},{ 9,213},{ 9,213},{ 9,213},{ 9,213},{ 9,213},{ 9,213},{ 9,213},
87  			 { 9, 31},{ 9, 31},{ 9, 31},{ 9, 31},{ 9, 31},{ 9, 31},{ 9, 31},{ 9, 31},{ 9,214},{ 9,214},{ 9,214},{ 9,214},{ 9,214},{ 9,214},{ 9,214},{ 9,214},
88  			 { 9, 30},{ 9, 30},{ 9, 30},{ 9, 30},{ 9, 30},{ 9, 30},{ 9, 30},{ 9, 30},{ 9,215},{ 9,215},{ 9,215},{ 9,215},{ 9,215},{ 9,215},{ 9,215},{ 9,215},
89  			 { 9,216},{ 9,216},{ 9,216},{ 9,216},{ 9,216},{ 9,216},{ 9,216},{ 9,216},{ 9, 29},{ 9, 29},{ 9, 29},{ 9, 29},{ 9, 29},{ 9, 29},{ 9, 29},{ 9, 29},
90  			 { 9,217},{ 9,217},{ 9,217},{ 9,217},{ 9,217},{ 9,217},{ 9,217},{ 9,217},{ 9,218},{ 9,218},{ 9,218},{ 9,218},{ 9,218},{ 9,218},{ 9,218},{ 9,218},
91  			 { 9, 28},{ 9, 28},{ 9, 28},{ 9, 28},{ 9, 28},{ 9, 28},{ 9, 28},{ 9, 28},{ 9,219},{ 9,219},{ 9,219},{ 9,219},{ 9,219},{ 9,219},{ 9,219},{ 9,219},
92  			 { 9, 27},{ 9, 27},{ 9, 27},{ 9, 27},{ 9, 27},{ 9, 27},{ 9, 27},{ 9, 27},{ 9,220},{ 9,220},{ 9,220},{ 9,220},{ 9,220},{ 9,220},{ 9,220},{ 9,220},
93  			 { 9,221},{ 9,221},{ 9,221},{ 9,221},{ 9,221},{ 9,221},{ 9,221},{ 9,221},{ 9, 26},{ 9, 26},{ 9, 26},{ 9, 26},{ 9, 26},{ 9, 26},{ 9, 26},{ 9, 26},
94  			 { 9, 25},{ 9, 25},{ 9, 25},{ 9, 25},{ 9, 25},{ 9, 25},{ 9, 25},{ 9, 25},{ 9,222},{ 9,222},{ 9,222},{ 9,222},{ 9,222},{ 9,222},{ 9,222},{ 9,222},
95  			 { 9,223},{ 9,223},{ 9,223},{ 9,223},{ 9,223},{ 9,223},{ 9,223},{ 9,223},{ 9, 24},{ 9, 24},{ 9, 24},{ 9, 24},{ 9, 24},{ 9, 24},{ 9, 24},{ 9, 24},
96  			 { 9,224},{ 9,224},{ 9,224},{ 9,224},{ 9,224},{ 9,224},{ 9,224},{ 9,224},{ 9,225},{ 9,225},{ 9,225},{ 9,225},{ 9,225},{ 9,225},{ 9,225},{ 9,225},
97  			 { 9, 23},{ 9, 23},{ 9, 23},{ 9, 23},{ 9, 23},{ 9, 23},{ 9, 23},{ 9, 23},{ 9,226},{ 9,226},{ 9,226},{ 9,226},{ 9,226},{ 9,226},{ 9,226},{ 9,226},
98  			 { 9, 22},{ 9, 22},{ 9, 22},{ 9, 22},{ 9, 22},{ 9, 22},{ 9, 22},{ 9, 22},{ 9,227},{ 9,227},{ 9,227},{ 9,227},{ 9,227},{ 9,227},{ 9,227},{ 9,227},
99  			 { 9,228},{ 9,228},{ 9,228},{ 9,228},{ 9,228},{ 9,228},{ 9,228},{ 9,228},{ 9, 21},{ 9, 21},{ 9, 21},{ 9, 21},{ 9, 21},{ 9, 21},{ 9, 21},{ 9, 21},
100 			 { 9,229},{ 9,229},{ 9,229},{ 9,229},{ 9,229},{ 9,229},{ 9,229},{ 9,229},{ 9,230},{ 9,230},{ 9,230},{ 9,230},{ 9,230},{ 9,230},{ 9,230},{ 9,230}
101 			};
102 
103 	/** HuffYUV table taken from C++ source */
104 	/* 2 512 */	
105 	private static final int[][] decode_luma17 = {
106 			 {17,139},{17,136},{17,134},{17,141},{17,132},{17,146},{17,143},{17,137},{17,138},{17,133},{17,145},{17,135},{17,144},{17,131},{17,142},{17,147},
107 			 {17,140},{17,129},{17,148},{17,130},{16,150},{16,150},{16,149},{16,149},{16,128},{16,128},{16,151},{16,151},{16,127},{16,127},{16,152},{16,152},
108 			 {16,153},{16,153},{16,126},{16,126},{16,125},{16,125},{16,154},{16,154},{16,155},{16,155},{16,124},{16,124},{16,156},{16,156},{16,123},{16,123},
109 			 {16,157},{16,157},{16,122},{16,122},{16,121},{16,121},{16,158},{16,158},{15,120},{15,120},{15,120},{15,120},{15,159},{15,159},{15,159},{15,159},
110 			 {15,119},{15,119},{15,119},{15,119},{15,118},{15,118},{15,118},{15,118},{15,160},{15,160},{15,160},{15,160},{15,117},{15,117},{15,117},{15,117},
111 			 {15,161},{15,161},{15,161},{15,161},{15,116},{15,116},{15,116},{15,116},{15,162},{15,162},{15,162},{15,162},{15,115},{15,115},{15,115},{15,115},
112 			 {15,163},{15,163},{15,163},{15,163},{15,114},{15,114},{15,114},{15,114},{15,164},{15,164},{15,164},{15,164},{15,113},{15,113},{15,113},{15,113},
113 			 {14,165},{14,165},{14,165},{14,165},{14,165},{14,165},{14,165},{14,165},{14,112},{14,112},{14,112},{14,112},{14,112},{14,112},{14,112},{14,112},
114 			 {14,111},{14,111},{14,111},{14,111},{14,111},{14,111},{14,111},{14,111},{14,166},{14,166},{14,166},{14,166},{14,166},{14,166},{14,166},{14,166},
115 			 {14,110},{14,110},{14,110},{14,110},{14,110},{14,110},{14,110},{14,110},{14,109},{14,109},{14,109},{14,109},{14,109},{14,109},{14,109},{14,109},
116 			 {14,167},{14,167},{14,167},{14,167},{14,167},{14,167},{14,167},{14,167},{14,108},{14,108},{14,108},{14,108},{14,108},{14,108},{14,108},{14,108},
117 			 {14,168},{14,168},{14,168},{14,168},{14,168},{14,168},{14,168},{14,168},{14,107},{14,107},{14,107},{14,107},{14,107},{14,107},{14,107},{14,107},
118 			 {14,169},{14,169},{14,169},{14,169},{14,169},{14,169},{14,169},{14,169},{14,106},{14,106},{14,106},{14,106},{14,106},{14,106},{14,106},{14,106},
119 			 {14,105},{14,105},{14,105},{14,105},{14,105},{14,105},{14,105},{14,105},{14,170},{14,170},{14,170},{14,170},{14,170},{14,170},{14,170},{14,170},
120 			 {13,104},{13,104},{13,104},{13,104},{13,104},{13,104},{13,104},{13,104},{13,104},{13,104},{13,104},{13,104},{13,104},{13,104},{13,104},{13,104},
121 			 {13,171},{13,171},{13,171},{13,171},{13,171},{13,171},{13,171},{13,171},{13,171},{13,171},{13,171},{13,171},{13,171},{13,171},{13,171},{13,171},
122 			 {13,103},{13,103},{13,103},{13,103},{13,103},{13,103},{13,103},{13,103},{13,103},{13,103},{13,103},{13,103},{13,103},{13,103},{13,103},{13,103},
123 			 {13,102},{13,102},{13,102},{13,102},{13,102},{13,102},{13,102},{13,102},{13,102},{13,102},{13,102},{13,102},{13,102},{13,102},{13,102},{13,102},
124 			 {13,172},{13,172},{13,172},{13,172},{13,172},{13,172},{13,172},{13,172},{13,172},{13,172},{13,172},{13,172},{13,172},{13,172},{13,172},{13,172},
125 			 {13,101},{13,101},{13,101},{13,101},{13,101},{13,101},{13,101},{13,101},{13,101},{13,101},{13,101},{13,101},{13,101},{13,101},{13,101},{13,101},
126 			 {13,173},{13,173},{13,173},{13,173},{13,173},{13,173},{13,173},{13,173},{13,173},{13,173},{13,173},{13,173},{13,173},{13,173},{13,173},{13,173},
127 			 {13,100},{13,100},{13,100},{13,100},{13,100},{13,100},{13,100},{13,100},{13,100},{13,100},{13,100},{13,100},{13,100},{13,100},{13,100},{13,100},
128 			 {13, 99},{13, 99},{13, 99},{13, 99},{13, 99},{13, 99},{13, 99},{13, 99},{13, 99},{13, 99},{13, 99},{13, 99},{13, 99},{13, 99},{13, 99},{13, 99},
129 			 {13,174},{13,174},{13,174},{13,174},{13,174},{13,174},{13,174},{13,174},{13,174},{13,174},{13,174},{13,174},{13,174},{13,174},{13,174},{13,174},
130 			 {13, 98},{13, 98},{13, 98},{13, 98},{13, 98},{13, 98},{13, 98},{13, 98},{13, 98},{13, 98},{13, 98},{13, 98},{13, 98},{13, 98},{13, 98},{13, 98},
131 			 {13,175},{13,175},{13,175},{13,175},{13,175},{13,175},{13,175},{13,175},{13,175},{13,175},{13,175},{13,175},{13,175},{13,175},{13,175},{13,175},
132 			 {13, 97},{13, 97},{13, 97},{13, 97},{13, 97},{13, 97},{13, 97},{13, 97},{13, 97},{13, 97},{13, 97},{13, 97},{13, 97},{13, 97},{13, 97},{13, 97},
133 			 {13, 96},{13, 96},{13, 96},{13, 96},{13, 96},{13, 96},{13, 96},{13, 96},{13, 96},{13, 96},{13, 96},{13, 96},{13, 96},{13, 96},{13, 96},{13, 96},
134 			 {13,176},{13,176},{13,176},{13,176},{13,176},{13,176},{13,176},{13,176},{13,176},{13,176},{13,176},{13,176},{13,176},{13,176},{13,176},{13,176},
135 			 {13, 95},{13, 95},{13, 95},{13, 95},{13, 95},{13, 95},{13, 95},{13, 95},{13, 95},{13, 95},{13, 95},{13, 95},{13, 95},{13, 95},{13, 95},{13, 95},
136 			 {12, 94},{12, 94},{12, 94},{12, 94},{12, 94},{12, 94},{12, 94},{12, 94},{12, 94},{12, 94},{12, 94},{12, 94},{12, 94},{12, 94},{12, 94},{12, 94},
137 			 {12, 94},{12, 94},{12, 94},{12, 94},{12, 94},{12, 94},{12, 94},{12, 94},{12, 94},{12, 94},{12, 94},{12, 94},{12, 94},{12, 94},{12, 94},{12, 94}
138 			};
139 
140 	/**
141 	 * Decompresses HuffYUV compressed data.
142 	 * 
143 	 * @param aCompressedBuffer byte array containing the compressed bits, see Remark
144 	 * @param aCompressedOffset offset of first byte where compressed bits start
145 	 * @param aUncompressedBuffer see Remark, byte array of exact size to hold uncompressed frame bits
146 	 * @param aUncompressedOffset offset in uncompressed buffer where uncompressed bytes should start
147 	 * @param aSizeImage size of uncompressed frame bits (usually pxwidth*pxheight*bytes_per_px)
148 	 * <br>
149 	 * <br>
150 	 * <b>Remarks:</b> 
151 	 * <ul>
152 	 * <li>aCompressedBuffer must be at least [aConmpressedOffset+size_compressed_bits+4] 
153 	 * bytes big because it is read 32-bit wise so under rare occassions the loop needs 
154 	 * up to four extra bytes at end of buffer.
155 	 * <li>
156 	 * aUncompressedBuffer must be exactly [aUncompressedOffset+aSizeImage] bytes big! 
157 	 * This is due to optimisation. As a side-effect of this, aSizeImage is not used at the moment.
158 	 * </ul> 
159 	 */
160 	 public static final void DecompressHuffYUV( final byte[] aCompressedBuffer, int aCompressedOffset, byte [] aUncompressedBuffer, int aUncompressedOffset, int aSizeImage)
161 	 {
162 		 // TODO: return boolean and check properly for good decompression, account aSizeImage
163 		 
164 		 // comments further down usually refer to debug output that was necessary during 
165 		 // development
166 		 
167 		 // some comments refer to commented out things because of code speed optimisation
168 		 
169 		 int bitpos;
170 		 int outpos=aUncompressedOffset;
171 		 int inpos=aCompressedOffset;
172 		 
173 		 bitpos = 32+(aCompressedOffset*8);
174 
175 		 long fc =	(((long)(aCompressedBuffer[inpos+3]&0xFF)<<16))|
176 		 			(((long)(aCompressedBuffer[inpos+2]&0xFF)<<8))|
177 		 			(aCompressedBuffer[inpos+1]&0xFF); 
178 		 
179 		 //int fco = aCompressedBuffer[inpos] >>> 8;
180 		 
181 		 aUncompressedBuffer[outpos+3] = (byte) ((fc >> 24));
182 		 aUncompressedBuffer[outpos+2] = (byte) ((fc >> 16));
183 		 aUncompressedBuffer[outpos+1] = (byte) ((fc >> 8));
184 		 aUncompressedBuffer[outpos] = (byte) (fc);
185 		 
186 		 outpos += 3;
187 		 
188 		 try {
189 			 // while( outpos < (aSizeImage+aUncompressedOffset) )
190 			 for(;;outpos++)
191 			 {
192 				 // SW! signed, unsigned
193 				 //System.out.println("bitpos="+bitpos[0]);
194 
195 				//int wordt4o = (bitpos >>> 5)<<2;
196 				int wordt4 = ((bitpos>>>3)&0xFFFFFFFC);
197 				int bit = bitpos & 31;
198 				int retval;
199 				
200 				//System.out.println("wordt4o="+wordt4o+" wordt4="+wordt4);
201 						
202 				long val = 	(((long)(aCompressedBuffer[wordt4+3]&0xFF))<<24)|
203 							(((long)(aCompressedBuffer[wordt4+2]&0xFF))<<16)|
204 							(((long)(aCompressedBuffer[wordt4+1]&0xFF))<<8)|
205 							( (long)(aCompressedBuffer[wordt4])&0xFF);
206 						
207 				if (bit != 0) 
208 				{
209 					wordt4+=4;
210 					long val1 = (((long)(aCompressedBuffer[wordt4+3]&0xFF))<<24)|
211 								(((long)(aCompressedBuffer[wordt4+2]&0xFF))<<16)|
212 								(((long)(aCompressedBuffer[wordt4+1]&0xFF))<<8)|
213 								( (long)(aCompressedBuffer[wordt4])&0xFF);
214 							
215 					//val = (val << bit) | (in[word+1] >> (32-bit));
216 							
217 					val = ((val << bit)) | ((val1 >> (32-bit)));
218 					val &= 0xFFFFFFFFL;
219 				}
220 						
221 				if (val >= (35 << 23))
222 				{
223 					final int pos23 = (int) (val >> 23);
224 					
225 					bitpos += decode_luma9[pos23][0];
226 					retval = decode_luma9[pos23][1];
227 				}
228 				else if (val >= (15 << 20))
229 				{
230 					final int pos20 = (int) (val >> 20);
231 						
232 					bitpos += decode_luma12[pos20][0];
233 					retval = decode_luma12[pos20][1];
234 				}
235 				else
236 				{
237 					final int pos15 = (int) (val >> 15);
238 						
239 					bitpos += decode_luma17[pos15][0];
240 					retval = decode_luma17[pos15][1];
241 				}
242 				 
243 				aUncompressedBuffer[outpos] = (byte) (aUncompressedBuffer[outpos-3] + retval );
244 
245 				//aUncompressedBuffer[outpos] = (byte) 
246 				//( ((((int)aUncompressedBuffer[outpos-3])&0xFF)) + retval );
247 			
248 				 //System.out.println("bitpos="+bitpos[0]);
249 				//outpos++;
250 			 }
251 		 }
252 		 catch( java.lang.ArrayIndexOutOfBoundsException ex ) {}
253 			 
254 	 }
255 
256 	 /*
257 		static final int UnhuffLuma(final byte[] aCompressedBuffer, long[] pos)
258 		{
259 			int word = (int) (pos[0] >>> 5);
260 			int bit = (int) (pos[0] & 31);
261 			
262 			long val = 	(((long)(aCompressedBuffer[4*word+3]&0xFF))<<24)|
263 						(((long)(aCompressedBuffer[4*word+2]&0xFF))<<16)|
264 						(((long)(aCompressedBuffer[4*word+1]&0xFF))<<8)|
265 						( (long)(aCompressedBuffer[4*word])&0xFF);
266 			
267 			if (bit != 0) 
268 			{
269 				long val1 = (((long)(aCompressedBuffer[4*(word+1)+3]&0xFF))<<24)|
270 							(((long)(aCompressedBuffer[4*(word+1)+2]&0xFF))<<16)|
271 							(((long)(aCompressedBuffer[4*(word+1)+1]&0xFF))<<8)|
272 							( (long)(aCompressedBuffer[4*(word+1)])&0xFF);
273 				
274 				//val = (val << bit) | (in[word+1] >> (32-bit));
275 				
276 				val = ((val << bit)&0xFFFFFFFFL) | ((val1 >>> (32-bit))&0xFFFFFFFFL);
277 			}
278 			
279 			if (val >= (35L << 23))
280 			{
281 				final int pos23 = (int) (val >> 23);
282 			
283 				pos[0] += decode_luma9[pos23][0];
284 				return decode_luma9[pos23][1];
285 			}
286 			
287 			if (val >= (15L << 20))
288 			{
289 				final int pos20 = (int) (val >> 20);
290 				
291 				pos[0] += decode_luma12[pos20][0];
292 				return decode_luma12[pos20][1];
293 			}
294 
295 			final int pos15 = (int) (val >> 15);
296 			
297 			pos[0] += decode_luma17[pos15][0];
298 			return decode_luma17[pos15][1];
299 		}
300 		*/
301 		/*	C code
302 		 * static inline unsigned char UnhuffLuma(const DWORD* in, unsigned& pos) {
303 			  unsigned word = pos >> 5;
304 			  unsigned bit = pos & 31;
305 			  unsigned val = in[word];
306 			  if (bit)    // the conditional is necessary because shifting by 32 doesn't work correctly on x86 processors
307 			    val = (val << bit) | (in[word+1] >> (32-bit));
308 //			  // figure out the appropriate lookup table based on the number of leading zeros
309 			  if (val >= (35 << 23)) {
310 			    pos += decode_luma9[val >> 23].shift;
311 			    return decode_luma9[val >> 23].add;
312 			  }
313 			  if (val >= (15 << 20)) {
314 			    pos += decode_luma12[val >> 20].shift;
315 			    return decode_luma12[val >> 20].add;
316 			  }
317 			  pos += decode_luma17[val >> 15].shift;
318 			  return decode_luma17[val >> 15].add;
319 			}
320 		 */
321 	 
322 	 
323 	 
324 // old:
325 	 /*
326 	static final int UnhuffLuma(final byte[] aCompressedBuffer, int[] pos)
327 	{
328 		int word = pos[0] >>> 5;
329 		int bit = pos[0] & 31;
330 		
331 		long val = 	(((long)(aCompressedBuffer[4*word+3]&0xFF))<<24)|
332 					(((long)(aCompressedBuffer[4*word+2]&0xFF))<<16)|
333 					(((long)(aCompressedBuffer[4*word+1]&0xFF))<<8)|
334 					( (long)(aCompressedBuffer[4*word])&0xFF);
335 		
336 		if (bit != 0) 
337 		{
338 			long val1 = (((long)(aCompressedBuffer[4*(word+1)+3]&0xFF))<<24)|
339 						(((long)(aCompressedBuffer[4*(word+1)+2]&0xFF))<<16)|
340 						(((long)(aCompressedBuffer[4*(word+1)+1]&0xFF))<<8)|
341 						( (long)(aCompressedBuffer[4*(word+1)])&0xFF);
342 			
343 			//val = (val << bit) | (in[word+1] >> (32-bit));
344 			
345 			val = ((val << bit)&0xFFFFFFFFL) | ((val1 >>> (32-bit))&0xFFFFFFFFL);
346 		}
347 		
348 		if (val >= (35 << 23))
349 		{
350 			final int pos23 = (int) (val >> 23);
351 		
352 			pos[0] += decode_luma9[pos23][0];
353 			return decode_luma9[pos23][1];
354 		}
355 		
356 		if (val >= (15 << 20))
357 		{
358 			final int pos20 = (int) (val >> 20);
359 			
360 			pos[0] += decode_luma12[pos20][0];
361 			return decode_luma12[pos20][1];
362 		}
363 
364 		final int pos15 = (int) (val >> 15);
365 		
366 		pos[0] += decode_luma17[pos15][0];
367 		return decode_luma17[pos15][1];
368 	}
369 	*/
370 	/*
371 	 // aCompressedBuffer needs 4 bytes more than the compressed bytes contained inside
372 	 static final void DecompressHuffYUV( final byte[] aCompressedBuffer, int aCompressedOffset, byte [] aUncompressedBuffer, int aUncompressedOffset, int aSizeImage)
373 	 {
374 		 long[] bitpos = new long[1];
375 		 int outpos=aUncompressedOffset;
376 		 int inpos=aCompressedOffset;
377 		 
378 		 bitpos[0] = 32+(aCompressedOffset*8);
379 
380 		 long fc =	(((long)(aCompressedBuffer[inpos+3]&0xFF)<<24))|
381 		 			(((long)(aCompressedBuffer[inpos+2]&0xFF)<<16))|
382 		 			(((long)(aCompressedBuffer[inpos+1]&0xFF)<<8))|
383 		 			((long)(aCompressedBuffer[inpos]&0xFF)); 
384 		 
385 		 fc >>>= 8;
386 		                            
387 		 //int fc = aCompressedBuffer[inpos] >>> 8;
388 		 
389 		 // SW! might be reverse order
390 		 aUncompressedBuffer[outpos+3] = (byte) ((fc >> 24) & 0xFF);
391 		 aUncompressedBuffer[outpos+2] = (byte) ((fc >> 16) & 0xFF);
392 		 aUncompressedBuffer[outpos+1] = (byte) ((fc >> 8) & 0xFF);
393 		 aUncompressedBuffer[outpos+0] = (byte) (fc & 0xFF);
394 		 
395 		 outpos += 3;
396 		 
397 		 //try {
398 			 while( outpos < aSizeImage )
399 			 {
400 				 // SW! signed, unsigned
401 				 //System.out.println("bitpos="+bitpos[0]);
402 				 
403 				 				 
404 				 aUncompressedBuffer[outpos] = (byte) (((((int)aUncompressedBuffer[outpos-3])&0xFF)) + UnhuffLuma(aCompressedBuffer, bitpos));
405 				 //System.out.println("bitpos="+bitpos[0]);
406 				 outpos++;
407 			 }
408 		  //}
409 		 //catch( java.lang.ArrayIndexOutOfBoundsException ex )
410 		 //{
411 			 //int dbgbrkpt = 1;
412 			 //System.out.println("AIOOBex outpos="+outpos);
413 		// }
414 			 
415 			 
416 		 }
417 	 
418 	 */
419 	 
420 	 
421 	 /*	
422 //		 This function decompresses the raw image bits. It is directly taken out of the HufYUV v1.2.3 source
423 		void CCompression::DecompressRGB( void *compressed, void *uncompressed, DWORD dwSize, int sizeimage) 
424 		{
425 		  int size = sizeimage;
426 		  
427 		  const DWORD* const in = (DWORD*) compressed;
428 		  unsigned char* const end = (unsigned char*)uncompressed + size;
429 		  unsigned char* out = (unsigned char*)uncompressed;
430 
431 		  *(DWORD*)out = in[0] >> 8;
432 		  unsigned pos = 32;
433 
434 		  // RGB 24-bit
435 		  out += 3;
436 		  while (out < end) // main decompression loop
437 		  {
438 		    out[0] = out[-3] + UnhuffLuma(in, pos);
439 		    ++out;
440 		  }
441 
442 		}
443 	
444 	*/
445 
446 	 // goal is to read compressed image blob 
447 	// write out imm file at the end
448 
449 /*	public static void main(String[] args) {
450 		
451 		final int width = 768;
452 		final int height = 574;
453 		final double scale = 1.2345;
454 		int sizeImage = width*height;
455 		
456 		byte[] uncompressedBuffer = new byte[sizeImage];
457 		byte[] compressedBuffer;
458 		
459 		java.io.FileInputStream fis = null;
460 		java.io.FileOutputStream fos = null;
461 		
462 		try {
463 		
464 			fis = new java.io.FileInputStream(new java.io.File("input.huffyuv.blob"));
465 
466 			long fsize = fis.getChannel().size();
467 		
468 			compressedBuffer = new byte[(int) fsize+4];
469 			compressedBuffer[(int) fsize-1] = 0;
470 			compressedBuffer[(int)fsize-2] = 0;
471 			compressedBuffer[(int)fsize-3] = 0;
472 			compressedBuffer[(int)fsize-4] = 0;
473 		
474 			int ret = fis.read(compressedBuffer, 0, (int) fsize);
475 
476 			if (ret == fsize)
477 			{
478 				
479 				long start = System.currentTimeMillis();
480 				
481 				System.out.println("successfully read file, size read "+ret+" bytes.");
482 				for (int i=0;i<1000;i++)
483 				{
484 					DecompressHuffYUV(compressedBuffer, uncompressedBuffer, sizeImage);
485 				}
486 				
487 				long stop = System.currentTimeMillis();
488 				
489 				System.out.println("time for 1000 runs="+(stop-start)+" msec tpr="+((stop-start)/1000.0)+" msec.");
490 				
491 				
492 				try {
493 					fos = new java.io.FileOutputStream("outfile.imm", false);
494 					
495 					java.nio.ByteBuffer bb = java.nio.ByteBuffer.allocate(sizeImage+16);
496 					bb.order(java.nio.ByteOrder.LITTLE_ENDIAN);
497 					
498 					bb.putInt(width);
499 					bb.putInt(height);
500 					bb.put(uncompressedBuffer);
501 					bb.putDouble(scale);
502 					
503 					bb.flip();
504 
505 					//buf.flip();
506 		            //
507 		            //// Write the bytes to the channel
508 		            //int numWritten = channel.write(buf);
509 
510 					
511 					//java.nio.channels.WritableByteChannel wbc(fos.getChannel()); 
512 					
513 				    int ret1 = fos.getChannel().write( bb );
514 				    
515 				    System.out.println("successfully wrote "+ret1+" bytes to outfile.");
516 					fos.close();
517 				}
518 				catch( java.io.IOException e )
519 				{
520 					System.out.println("IOEx: "+e.getMessage()+"\n");
521 				}
522 				finally
523 				{
524 					try { if (fos != null) fos.close(); } catch(java.io.IOException e ){}
525 				}
526 
527 				
528 			}
529 			else System.out.println("Error reading full input file.");
530 		}
531 		catch( java.io.FileNotFoundException e )
532 		{
533 			System.out.println("FNFex: "+e.getMessage()+"\n");
534 		}
535 		catch( java.io.IOException e )
536 		{
537 			System.out.println("IOEx: "+e.getMessage()+"\n");
538 		}
539 		finally
540 		{
541 			try { if (fis != null) fis.close(); } catch(java.io.IOException e ){}
542 		}
543 		
544 		// read blob, write imm
545 	}
546 */
547 }