View Javadoc

1   package de.desy.acop.video.displayer;
2   
3   /**
4    * <code>HuffmanDecompression</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 HuffmanDecompression {
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 		 	// performance & loop stop condition
254 		 }
255 			 
256 	 }
257 
258 	 /*
259 		static final int UnhuffLuma(final byte[] aCompressedBuffer, long[] pos)
260 		{
261 			int word = (int) (pos[0] >>> 5);
262 			int bit = (int) (pos[0] & 31);
263 			
264 			long val = 	(((long)(aCompressedBuffer[4*word+3]&0xFF))<<24)|
265 						(((long)(aCompressedBuffer[4*word+2]&0xFF))<<16)|
266 						(((long)(aCompressedBuffer[4*word+1]&0xFF))<<8)|
267 						( (long)(aCompressedBuffer[4*word])&0xFF);
268 			
269 			if (bit != 0) 
270 			{
271 				long val1 = (((long)(aCompressedBuffer[4*(word+1)+3]&0xFF))<<24)|
272 							(((long)(aCompressedBuffer[4*(word+1)+2]&0xFF))<<16)|
273 							(((long)(aCompressedBuffer[4*(word+1)+1]&0xFF))<<8)|
274 							( (long)(aCompressedBuffer[4*(word+1)])&0xFF);
275 				
276 				//val = (val << bit) | (in[word+1] >> (32-bit));
277 				
278 				val = ((val << bit)&0xFFFFFFFFL) | ((val1 >>> (32-bit))&0xFFFFFFFFL);
279 			}
280 			
281 			if (val >= (35L << 23))
282 			{
283 				final int pos23 = (int) (val >> 23);
284 			
285 				pos[0] += decode_luma9[pos23][0];
286 				return decode_luma9[pos23][1];
287 			}
288 			
289 			if (val >= (15L << 20))
290 			{
291 				final int pos20 = (int) (val >> 20);
292 				
293 				pos[0] += decode_luma12[pos20][0];
294 				return decode_luma12[pos20][1];
295 			}
296 
297 			final int pos15 = (int) (val >> 15);
298 			
299 			pos[0] += decode_luma17[pos15][0];
300 			return decode_luma17[pos15][1];
301 		}
302 		*/
303 		/*	C code
304 		 * static inline unsigned char UnhuffLuma(const DWORD* in, unsigned& pos) {
305 			  unsigned word = pos >> 5;
306 			  unsigned bit = pos & 31;
307 			  unsigned val = in[word];
308 			  if (bit)    // the conditional is necessary because shifting by 32 doesn't work correctly on x86 processors
309 			    val = (val << bit) | (in[word+1] >> (32-bit));
310 //			  // figure out the appropriate lookup table based on the number of leading zeros
311 			  if (val >= (35 << 23)) {
312 			    pos += decode_luma9[val >> 23].shift;
313 			    return decode_luma9[val >> 23].add;
314 			  }
315 			  if (val >= (15 << 20)) {
316 			    pos += decode_luma12[val >> 20].shift;
317 			    return decode_luma12[val >> 20].add;
318 			  }
319 			  pos += decode_luma17[val >> 15].shift;
320 			  return decode_luma17[val >> 15].add;
321 			}
322 		 */
323 	 
324 	 
325 	 
326 // old:
327 	 /*
328 	static final int UnhuffLuma(final byte[] aCompressedBuffer, int[] pos)
329 	{
330 		int word = pos[0] >>> 5;
331 		int bit = pos[0] & 31;
332 		
333 		long val = 	(((long)(aCompressedBuffer[4*word+3]&0xFF))<<24)|
334 					(((long)(aCompressedBuffer[4*word+2]&0xFF))<<16)|
335 					(((long)(aCompressedBuffer[4*word+1]&0xFF))<<8)|
336 					( (long)(aCompressedBuffer[4*word])&0xFF);
337 		
338 		if (bit != 0) 
339 		{
340 			long val1 = (((long)(aCompressedBuffer[4*(word+1)+3]&0xFF))<<24)|
341 						(((long)(aCompressedBuffer[4*(word+1)+2]&0xFF))<<16)|
342 						(((long)(aCompressedBuffer[4*(word+1)+1]&0xFF))<<8)|
343 						( (long)(aCompressedBuffer[4*(word+1)])&0xFF);
344 			
345 			//val = (val << bit) | (in[word+1] >> (32-bit));
346 			
347 			val = ((val << bit)&0xFFFFFFFFL) | ((val1 >>> (32-bit))&0xFFFFFFFFL);
348 		}
349 		
350 		if (val >= (35 << 23))
351 		{
352 			final int pos23 = (int) (val >> 23);
353 		
354 			pos[0] += decode_luma9[pos23][0];
355 			return decode_luma9[pos23][1];
356 		}
357 		
358 		if (val >= (15 << 20))
359 		{
360 			final int pos20 = (int) (val >> 20);
361 			
362 			pos[0] += decode_luma12[pos20][0];
363 			return decode_luma12[pos20][1];
364 		}
365 
366 		final int pos15 = (int) (val >> 15);
367 		
368 		pos[0] += decode_luma17[pos15][0];
369 		return decode_luma17[pos15][1];
370 	}
371 	*/
372 	/*
373 	 // aCompressedBuffer needs 4 bytes more than the compressed bytes contained inside
374 	 static final void DecompressHuffYUV( final byte[] aCompressedBuffer, int aCompressedOffset, byte [] aUncompressedBuffer, int aUncompressedOffset, int aSizeImage)
375 	 {
376 		 long[] bitpos = new long[1];
377 		 int outpos=aUncompressedOffset;
378 		 int inpos=aCompressedOffset;
379 		 
380 		 bitpos[0] = 32+(aCompressedOffset*8);
381 
382 		 long fc =	(((long)(aCompressedBuffer[inpos+3]&0xFF)<<24))|
383 		 			(((long)(aCompressedBuffer[inpos+2]&0xFF)<<16))|
384 		 			(((long)(aCompressedBuffer[inpos+1]&0xFF)<<8))|
385 		 			((long)(aCompressedBuffer[inpos]&0xFF)); 
386 		 
387 		 fc >>>= 8;
388 		                            
389 		 //int fc = aCompressedBuffer[inpos] >>> 8;
390 		 
391 		 // SW! might be reverse order
392 		 aUncompressedBuffer[outpos+3] = (byte) ((fc >> 24) & 0xFF);
393 		 aUncompressedBuffer[outpos+2] = (byte) ((fc >> 16) & 0xFF);
394 		 aUncompressedBuffer[outpos+1] = (byte) ((fc >> 8) & 0xFF);
395 		 aUncompressedBuffer[outpos+0] = (byte) (fc & 0xFF);
396 		 
397 		 outpos += 3;
398 		 
399 		 //try {
400 			 while( outpos < aSizeImage )
401 			 {
402 				 // SW! signed, unsigned
403 				 //System.out.println("bitpos="+bitpos[0]);
404 				 
405 				 				 
406 				 aUncompressedBuffer[outpos] = (byte) (((((int)aUncompressedBuffer[outpos-3])&0xFF)) + UnhuffLuma(aCompressedBuffer, bitpos));
407 				 //System.out.println("bitpos="+bitpos[0]);
408 				 outpos++;
409 			 }
410 		  //}
411 		 //catch( java.lang.ArrayIndexOutOfBoundsException ex )
412 		 //{
413 			 //int dbgbrkpt = 1;
414 			 //System.out.println("AIOOBex outpos="+outpos);
415 		// }
416 			 
417 			 
418 		 }
419 	 
420 	 */
421 	 
422 	 
423 	 /*	
424 //		 This function decompresses the raw image bits. It is directly taken out of the HufYUV v1.2.3 source
425 		void CCompression::DecompressRGB( void *compressed, void *uncompressed, DWORD dwSize, int sizeimage) 
426 		{
427 		  int size = sizeimage;
428 		  
429 		  const DWORD* const in = (DWORD*) compressed;
430 		  unsigned char* const end = (unsigned char*)uncompressed + size;
431 		  unsigned char* out = (unsigned char*)uncompressed;
432 
433 		  *(DWORD*)out = in[0] >> 8;
434 		  unsigned pos = 32;
435 
436 		  // RGB 24-bit
437 		  out += 3;
438 		  while (out < end) // main decompression loop
439 		  {
440 		    out[0] = out[-3] + UnhuffLuma(in, pos);
441 		    ++out;
442 		  }
443 
444 		}
445 	
446 	*/
447 
448 	 // goal is to read compressed image blob 
449 	// write out imm file at the end
450 
451 /*	public static void main(String[] args) {
452 		
453 		final int width = 768;
454 		final int height = 574;
455 		final double scale = 1.2345;
456 		int sizeImage = width*height;
457 		
458 		byte[] uncompressedBuffer = new byte[sizeImage];
459 		byte[] compressedBuffer;
460 		
461 		java.io.FileInputStream fis = null;
462 		java.io.FileOutputStream fos = null;
463 		
464 		try {
465 		
466 			fis = new java.io.FileInputStream(new java.io.File("input.huffyuv.blob"));
467 
468 			long fsize = fis.getChannel().size();
469 		
470 			compressedBuffer = new byte[(int) fsize+4];
471 			compressedBuffer[(int) fsize-1] = 0;
472 			compressedBuffer[(int)fsize-2] = 0;
473 			compressedBuffer[(int)fsize-3] = 0;
474 			compressedBuffer[(int)fsize-4] = 0;
475 		
476 			int ret = fis.read(compressedBuffer, 0, (int) fsize);
477 
478 			if (ret == fsize)
479 			{
480 				
481 				long start = System.currentTimeMillis();
482 				
483 				System.out.println("successfully read file, size read "+ret+" bytes.");
484 				for (int i=0;i<1000;i++)
485 				{
486 					DecompressHuffYUV(compressedBuffer, uncompressedBuffer, sizeImage);
487 				}
488 				
489 				long stop = System.currentTimeMillis();
490 				
491 				System.out.println("time for 1000 runs="+(stop-start)+" msec tpr="+((stop-start)/1000.0)+" msec.");
492 				
493 				
494 				try {
495 					fos = new java.io.FileOutputStream("outfile.imm", false);
496 					
497 					java.nio.ByteBuffer bb = java.nio.ByteBuffer.allocate(sizeImage+16);
498 					bb.order(java.nio.ByteOrder.LITTLE_ENDIAN);
499 					
500 					bb.putInt(width);
501 					bb.putInt(height);
502 					bb.put(uncompressedBuffer);
503 					bb.putDouble(scale);
504 					
505 					bb.flip();
506 
507 					//buf.flip();
508 		            //
509 		            //// Write the bytes to the channel
510 		            //int numWritten = channel.write(buf);
511 
512 					
513 					//java.nio.channels.WritableByteChannel wbc(fos.getChannel()); 
514 					
515 				    int ret1 = fos.getChannel().write( bb );
516 				    
517 				    System.out.println("successfully wrote "+ret1+" bytes to outfile.");
518 					fos.close();
519 				}
520 				catch( java.io.IOException e )
521 				{
522 					System.out.println("IOEx: "+e.getMessage()+"\n");
523 				}
524 				finally
525 				{
526 					try { if (fos != null) fos.close(); } catch(java.io.IOException e ){}
527 				}
528 
529 				
530 			}
531 			else System.out.println("Error reading full input file.");
532 		}
533 		catch( java.io.FileNotFoundException e )
534 		{
535 			System.out.println("FNFex: "+e.getMessage()+"\n");
536 		}
537 		catch( java.io.IOException e )
538 		{
539 			System.out.println("IOEx: "+e.getMessage()+"\n");
540 		}
541 		finally
542 		{
543 			try { if (fis != null) fis.close(); } catch(java.io.IOException e ){}
544 		}
545 		
546 		// read blob, write imm
547 	}
548 */
549 }