1/* OV518 Decompression Support Module (No-MMX version)
2 *
3 * Copyright (c) 2002-2003 Mark W. McClelland. All rights reserved.
4 * http://alpha.dyndns.org/ov511/
5 *
6 * Fast integer iDCT by Yuri van Oers <yvanoers AT xs4all.nl>
7 * Original OV511 decompression code Copyright 1998-2000 OmniVision Technologies
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; version 2 of the License.
12 */
13
14#include <linux/config.h>
15
16#if defined(OUTSIDE_KERNEL)
17	#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
18		#define MODVERSIONS
19	#endif
20
21	#include <linux/version.h>
22
23	#ifdef MODVERSIONS
24		#include <linux/modversions.h>
25	#endif
26#else
27	#include <linux/version.h>
28#endif
29
30#include <linux/module.h>
31#include <linux/init.h>
32
33#include "ov51x.h"
34
35/******************************************************************************
36 * Compile-time Options
37 ******************************************************************************/
38
39/* Defining APPROXIMATE_MUL_BY_SHIFT increases performance by approximation
40 * the multiplications by shifts. I think there's no change in the
41 * calculated picture, but I'm not sure, so the choice is still in here. */
42#undef APPROXIMATE_MUL_BY_SHIFT
43
44/* Allows printing the dynamic quantization tables (only if debug >= 5) */
45#define PRINT_QT
46
47/******************************************************************************
48 * Version Information
49 ******************************************************************************/
50
51#define DRIVER_VERSION "v1.3"
52#define DRIVER_AUTHOR "Mark McClelland <mark@alpha.dyndns.org>, \
53Yuri van Oers <yvanoers AT xs4all.nl>, OmniVision Technologies \
54<http://www.ovt.com/>"
55#define DRIVER_DESC "OV518 Decompression Module"
56
57/******************************************************************************
58 * Decompression Module Interface Constants
59 ******************************************************************************/
60
61static const int interface_ver = DECOMP_INTERFACE_VER;
62static const int ov518 = 1;
63static const int mmx = 0;
64
65/******************************************************************************
66 * Module Features
67 ******************************************************************************/
68
69static int debug = 0;
70
71/* Static quantization. This uses a fixed quantization table versus the one
72 * that is normally embedded in the data. Define this if you see very bad
73 * contrast or "blockiness" in the decompressed output. */
74static int staticquant = 0;
75
76MODULE_PARM(debug, "i");
77MODULE_PARM_DESC(debug,
78  "Debug level: 0=none, 1=inits, 2=warning, 3=config, 4=functions, 5=max");
79
80MODULE_AUTHOR(DRIVER_AUTHOR);
81MODULE_DESCRIPTION(DRIVER_DESC);
82#if defined(MODULE_LICENSE)	/* Introduced in ~2.4.10 */
83MODULE_LICENSE("GPL");
84#endif
85
86/******************************************************************************
87 * Prototypes
88 ******************************************************************************/
89
90extern int ov511_register_decomp_module(int ver, struct ov51x_decomp_ops *ops,
91					int ov518, int mmx);
92extern void ov511_deregister_decomp_module(int ov518, int mmx);
93
94/******************************************************************************
95 * Local Data Types
96 ******************************************************************************/
97
98/* Make sure this remains naturally aligned and 2^n bytes in size */
99struct tree_node {
100	short left;		/* Pointer to left child node */
101	short right;		/* Pointer to right child node */
102	signed char depth;	/* Depth (starting at 1) if leaf, else -1 */
103	signed char coeffbits;	/* Size of coefficient data, or zero if none */
104	signed char skip;	/* Number of zero coefficients. Unused w/ DC */
105	char padding;		/* Pad out to 8 bytes */
106};
107
108struct comp_info {
109	int bytes;		/* Number of processed input bytes */
110	int bits;		/* Number of unprocessed input bits */
111	int rawLen;		/* Total number of bytes in input buffer */
112	unsigned char *qt;	/* Current quantization table */
113};
114
115/******************************************************************************
116 * Constant Data Definitions
117 ******************************************************************************/
118
119/* Zig-Zag Table */
120static const unsigned char ZigZag518[] = {
121	0x00, 0x02, 0x03, 0x09,
122	0x01, 0x04, 0x08, 0x0a,
123	0x05, 0x07, 0x0b, 0x11,
124	0x06, 0x0c, 0x10, 0x12,
125	0x0d, 0x0f, 0x13, 0x19,
126	0x0e, 0x14, 0x18, 0x1a,
127	0x15, 0x17, 0x1b, 0x1e,
128	0x16, 0x1c, 0x1d, 0x1f
129};
130
131/* Huffman trees */
132
133static const struct tree_node treeYAC[] = {
134	{  1,   4, -1,  0, -1}, {  2,   3, -1,  0, -1},
135	{ -1,  -1,  2,  1,  0}, { -1,  -1,  2,  2,  0},
136	{  5,   9, -1,  0, -1}, {  6,   7, -1,  0, -1},
137	{ -1,  -1,  3,  3,  0}, {323,   8, -1,  0, -1},
138	{ -1,  -1,  4,  4,  0}, { 10,  13, -1,  0, -1},
139	{ 38,  11, -1,  0, -1}, { 12,  39, -1,  0, -1},
140	{ -1,  -1,  5,  5,  0}, { 59,  14, -1,  0, -1},
141	{ 15,  18, -1,  0, -1}, { 16, 113, -1,  0, -1},
142	{ 17,  40, -1,  0, -1}, { -1,  -1,  7,  6,  0},
143	{ 19,  22, -1,  0, -1}, { 20,  41, -1,  0, -1},
144	{ 21,  61, -1,  0, -1}, { -1,  -1,  8,  7,  0},
145	{ 23,  27, -1,  0, -1}, {169,  24, -1,  0, -1},
146	{208,  25, -1,  0, -1}, { 26,  62, -1,  0, -1},
147	{ -1,  -1, 10,  8,  0}, { 44,  28, -1,  0, -1},
148	{ 63,  29, -1,  0, -1}, { 30, 191, -1,  0, -1},
149	{ 31, 119, -1,  0, -1}, { 32,  82, -1,  0, -1},
150	{ 33,  55, -1,  0, -1}, { 34,  48, -1,  0, -1},
151	{171,  35, -1,  0, -1}, { 36,  37, -1,  0, -1},
152	{ -1,  -1, 16,  9,  0}, { -1,  -1, 16, 10,  0},
153	{ -1,  -1,  4,  1,  1}, { -1,  -1,  5,  2,  1},
154	{ -1,  -1,  7,  3,  1}, {151,  42, -1,  0, -1},
155	{ 43,  79, -1,  0, -1}, { -1,  -1,  9,  4,  1},
156	{ 96,  45, -1,  0, -1}, {246,  46, -1,  0, -1},
157	{ 47, 115, -1,  0, -1}, { -1,  -1, 11,  5,  1},
158	{ 49,  52, -1,  0, -1}, { 50,  51, -1,  0, -1},
159	{ -1,  -1, 16,  6,  1}, { -1,  -1, 16,  7,  1},
160	{ 53,  54, -1,  0, -1}, { -1,  -1, 16,  8,  1},
161	{ -1,  -1, 16,  9,  1}, { 56,  71, -1,  0, -1},
162	{ 57,  68, -1,  0, -1}, { 58,  67, -1,  0, -1},
163	{ -1,  -1, 16, 10,  1}, { 60,  77, -1,  0, -1},
164	{ -1,  -1,  5,  1,  2}, { -1,  -1,  8,  2,  2},
165	{ -1,  -1, 10,  3,  2}, {265,  64, -1,  0, -1},
166	{ 65, 134, -1,  0, -1}, { 66,  80, -1,  0, -1},
167	{ -1,  -1, 12,  4,  2}, { -1,  -1, 16,  5,  2},
168	{ 69,  70, -1,  0, -1}, { -1,  -1, 16,  6,  2},
169	{ -1,  -1, 16,  7,  2}, { 72,  75, -1,  0, -1},
170	{ 73,  74, -1,  0, -1}, { -1,  -1, 16,  8,  2},
171	{ -1,  -1, 16,  9,  2}, { 76,  81, -1,  0, -1},
172	{ -1,  -1, 16, 10,  2}, { 78,  95, -1,  0, -1},
173	{ -1,  -1,  6,  1,  3}, { -1,  -1,  9,  2,  3},
174	{ -1,  -1, 12,  3,  3}, { -1,  -1, 16,  4,  3},
175	{ 83, 101, -1,  0, -1}, { 84,  91, -1,  0, -1},
176	{ 85,  88, -1,  0, -1}, { 86,  87, -1,  0, -1},
177	{ -1,  -1, 16,  5,  3}, { -1,  -1, 16,  6,  3},
178	{ 89,  90, -1,  0, -1}, { -1,  -1, 16,  7,  3},
179	{ -1,  -1, 16,  8,  3}, { 92,  98, -1,  0, -1},
180	{ 93,  94, -1,  0, -1}, { -1,  -1, 16,  9,  3},
181	{ -1,  -1, 16, 10,  3}, { -1,  -1,  6,  1,  4},
182	{ 97, 225, -1,  0, -1}, { -1,  -1, 10,  2,  4},
183	{ 99, 100, -1,  0, -1}, { -1,  -1, 16,  3,  4},
184	{ -1,  -1, 16,  4,  4}, {102, 109, -1,  0, -1},
185	{103, 106, -1,  0, -1}, {104, 105, -1,  0, -1},
186	{ -1,  -1, 16,  5,  4}, { -1,  -1, 16,  6,  4},
187	{107, 108, -1,  0, -1}, { -1,  -1, 16,  7,  4},
188	{ -1,  -1, 16,  8,  4}, {110, 116, -1,  0, -1},
189	{111, 112, -1,  0, -1}, { -1,  -1, 16,  9,  4},
190	{ -1,  -1, 16, 10,  4}, {114, 133, -1,  0, -1},
191	{ -1,  -1,  7,  1,  5}, { -1,  -1, 11,  2,  5},
192	{117, 118, -1,  0, -1}, { -1,  -1, 16,  3,  5},
193	{ -1,  -1, 16,  4,  5}, {120, 156, -1,  0, -1},
194	{121, 139, -1,  0, -1}, {122, 129, -1,  0, -1},
195	{123, 126, -1,  0, -1}, {124, 125, -1,  0, -1},
196	{ -1,  -1, 16,  5,  5}, { -1,  -1, 16,  6,  5},
197	{127, 128, -1,  0, -1}, { -1,  -1, 16,  7,  5},
198	{ -1,  -1, 16,  8,  5}, {130, 136, -1,  0, -1},
199	{131, 132, -1,  0, -1}, { -1,  -1, 16,  9,  5},
200	{ -1,  -1, 16, 10,  5}, { -1,  -1,  7,  1,  6},
201	{135, 152, -1,  0, -1}, { -1,  -1, 12,  2,  6},
202	{137, 138, -1,  0, -1}, { -1,  -1, 16,  3,  6},
203	{ -1,  -1, 16,  4,  6}, {140, 147, -1,  0, -1},
204	{141, 144, -1,  0, -1}, {142, 143, -1,  0, -1},
205	{ -1,  -1, 16,  5,  6}, { -1,  -1, 16,  6,  6},
206	{145, 146, -1,  0, -1}, { -1,  -1, 16,  7,  6},
207	{ -1,  -1, 16,  8,  6}, {148, 153, -1,  0, -1},
208	{149, 150, -1,  0, -1}, { -1,  -1, 16,  9,  6},
209	{ -1,  -1, 16, 10,  6}, { -1,  -1,  8,  1,  7},
210	{ -1,  -1, 12,  2,  7}, {154, 155, -1,  0, -1},
211	{ -1,  -1, 16,  3,  7}, { -1,  -1, 16,  4,  7},
212	{157, 175, -1,  0, -1}, {158, 165, -1,  0, -1},
213	{159, 162, -1,  0, -1}, {160, 161, -1,  0, -1},
214	{ -1,  -1, 16,  5,  7}, { -1,  -1, 16,  6,  7},
215	{163, 164, -1,  0, -1}, { -1,  -1, 16,  7,  7},
216	{ -1,  -1, 16,  8,  7}, {166, 172, -1,  0, -1},
217	{167, 168, -1,  0, -1}, { -1,  -1, 16,  9,  7},
218	{ -1,  -1, 16, 10,  7}, {170, 187, -1,  0, -1},
219	{ -1,  -1,  9,  1,  8}, { -1,  -1, 15,  2,  8},
220	{173, 174, -1,  0, -1}, { -1,  -1, 16,  3,  8},
221	{ -1,  -1, 16,  4,  8}, {176, 183, -1,  0, -1},
222	{177, 180, -1,  0, -1}, {178, 179, -1,  0, -1},
223	{ -1,  -1, 16,  5,  8}, { -1,  -1, 16,  6,  8},
224	{181, 182, -1,  0, -1}, { -1,  -1, 16,  7,  8},
225	{ -1,  -1, 16,  8,  8}, {184, 188, -1,  0, -1},
226	{185, 186, -1,  0, -1}, { -1,  -1, 16,  9,  8},
227	{ -1,  -1, 16, 10,  8}, { -1,  -1,  9,  1,  9},
228	{189, 190, -1,  0, -1}, { -1,  -1, 16,  2,  9},
229	{ -1,  -1, 16,  3,  9}, {192, 258, -1,  0, -1},
230	{193, 226, -1,  0, -1}, {194, 210, -1,  0, -1},
231	{195, 202, -1,  0, -1}, {196, 199, -1,  0, -1},
232	{197, 198, -1,  0, -1}, { -1,  -1, 16,  4,  9},
233	{ -1,  -1, 16,  5,  9}, {200, 201, -1,  0, -1},
234	{ -1,  -1, 16,  6,  9}, { -1,  -1, 16,  7,  9},
235	{203, 206, -1,  0, -1}, {204, 205, -1,  0, -1},
236	{ -1,  -1, 16,  8,  9}, { -1,  -1, 16,  9,  9},
237	{207, 209, -1,  0, -1}, { -1,  -1, 16, 10,  9},
238	{ -1,  -1,  9,  1, 10}, { -1,  -1, 16,  2, 10},
239	{211, 218, -1,  0, -1}, {212, 215, -1,  0, -1},
240	{213, 214, -1,  0, -1}, { -1,  -1, 16,  3, 10},
241	{ -1,  -1, 16,  4, 10}, {216, 217, -1,  0, -1},
242	{ -1,  -1, 16,  5, 10}, { -1,  -1, 16,  6, 10},
243	{219, 222, -1,  0, -1}, {220, 221, -1,  0, -1},
244	{ -1,  -1, 16,  7, 10}, { -1,  -1, 16,  8, 10},
245	{223, 224, -1,  0, -1}, { -1,  -1, 16,  9, 10},
246	{ -1,  -1, 16, 10, 10}, { -1,  -1, 10,  1, 11},
247	{227, 242, -1,  0, -1}, {228, 235, -1,  0, -1},
248	{229, 232, -1,  0, -1}, {230, 231, -1,  0, -1},
249	{ -1,  -1, 16,  2, 11}, { -1,  -1, 16,  3, 11},
250	{233, 234, -1,  0, -1}, { -1,  -1, 16,  4, 11},
251	{ -1,  -1, 16,  5, 11}, {236, 239, -1,  0, -1},
252	{237, 238, -1,  0, -1}, { -1,  -1, 16,  6, 11},
253	{ -1,  -1, 16,  7, 11}, {240, 241, -1,  0, -1},
254	{ -1,  -1, 16,  8, 11}, { -1,  -1, 16,  9, 11},
255	{243, 251, -1,  0, -1}, {244, 248, -1,  0, -1},
256	{245, 247, -1,  0, -1}, { -1,  -1, 16, 10, 11},
257	{ -1,  -1, 10,  1, 12}, { -1,  -1, 16,  2, 12},
258	{249, 250, -1,  0, -1}, { -1,  -1, 16,  3, 12},
259	{ -1,  -1, 16,  4, 12}, {252, 255, -1,  0, -1},
260	{253, 254, -1,  0, -1}, { -1,  -1, 16,  5, 12},
261	{ -1,  -1, 16,  6, 12}, {256, 257, -1,  0, -1},
262	{ -1,  -1, 16,  7, 12}, { -1,  -1, 16,  8, 12},
263	{259, 292, -1,  0, -1}, {260, 277, -1,  0, -1},
264	{261, 270, -1,  0, -1}, {262, 267, -1,  0, -1},
265	{263, 264, -1,  0, -1}, { -1,  -1, 16,  9, 12},
266	{ -1,  -1, 16, 10, 12}, {266, 322, -1,  0, -1},
267	{ -1,  -1, 11,  1, 13}, {268, 269, -1,  0, -1},
268	{ -1,  -1, 16,  2, 13}, { -1,  -1, 16,  3, 13},
269	{271, 274, -1,  0, -1}, {272, 273, -1,  0, -1},
270	{ -1,  -1, 16,  4, 13}, { -1,  -1, 16,  5, 13},
271	{275, 276, -1,  0, -1}, { -1,  -1, 16,  6, 13},
272	{ -1,  -1, 16,  7, 13}, {278, 285, -1,  0, -1},
273	{279, 282, -1,  0, -1}, {280, 281, -1,  0, -1},
274	{ -1,  -1, 16,  8, 13}, { -1,  -1, 16,  9, 13},
275	{283, 284, -1,  0, -1}, { -1,  -1, 16, 10, 13},
276	{ -1,  -1, 16,  1, 14}, {286, 289, -1,  0, -1},
277	{287, 288, -1,  0, -1}, { -1,  -1, 16,  2, 14},
278	{ -1,  -1, 16,  3, 14}, {290, 291, -1,  0, -1},
279	{ -1,  -1, 16,  4, 14}, { -1,  -1, 16,  5, 14},
280	{293, 308, -1,  0, -1}, {294, 301, -1,  0, -1},
281	{295, 298, -1,  0, -1}, {296, 297, -1,  0, -1},
282	{ -1,  -1, 16,  6, 14}, { -1,  -1, 16,  7, 14},
283	{299, 300, -1,  0, -1}, { -1,  -1, 16,  8, 14},
284	{ -1,  -1, 16,  9, 14}, {302, 305, -1,  0, -1},
285	{303, 304, -1,  0, -1}, { -1,  -1, 16, 10, 14},
286	{ -1,  -1, 16,  1, 15}, {306, 307, -1,  0, -1},
287	{ -1,  -1, 16,  2, 15}, { -1,  -1, 16,  3, 15},
288	{309, 316, -1,  0, -1}, {310, 313, -1,  0, -1},
289	{311, 312, -1,  0, -1}, { -1,  -1, 16,  4, 15},
290	{ -1,  -1, 16,  5, 15}, {314, 315, -1,  0, -1},
291	{ -1,  -1, 16,  6, 15}, { -1,  -1, 16,  7, 15},
292	{317, 320, -1,  0, -1}, {318, 319, -1,  0, -1},
293	{ -1,  -1, 16,  8, 15}, { -1,  -1, 16,  9, 15},
294	{321,  -1, -1,  0, -1}, { -1,  -1, 16, 10, 15},
295	{ -1,  -1, 11,  0, 16}, { -1,  -1,  4,  0, -1},
296};
297
298static const struct tree_node treeUVAC[] = {
299	{  1,   3, -1,  0, -1}, {323,   2, -1,  0, -1},
300	{ -1,  -1,  2,  1,  0}, {  4,   8, -1,  0, -1},
301	{  5,   6, -1,  0, -1}, { -1,  -1,  3,  2,  0},
302	{  7,  37, -1,  0, -1}, { -1,  -1,  4,  3,  0},
303	{  9,  13, -1,  0, -1}, { 10,  60, -1,  0, -1},
304	{ 11,  12, -1,  0, -1}, { -1,  -1,  5,  4,  0},
305	{ -1,  -1,  5,  5,  0}, { 14,  17, -1,  0, -1},
306	{ 15,  97, -1,  0, -1}, { 16,  38, -1,  0, -1},
307	{ -1,  -1,  6,  6,  0}, { 18,  21, -1,  0, -1},
308	{ 19,  39, -1,  0, -1}, { 20, 135, -1,  0, -1},
309	{ -1,  -1,  7,  7,  0}, { 22,  26, -1,  0, -1},
310	{ 82,  23, -1,  0, -1}, { 24,  99, -1,  0, -1},
311	{ 25,  42, -1,  0, -1}, { -1,  -1,  9,  8,  0},
312	{ 27,  31, -1,  0, -1}, {211,  28, -1,  0, -1},
313	{248,  29, -1,  0, -1}, { 30,  63, -1,  0, -1},
314	{ -1,  -1, 10,  9,  0}, { 43,  32, -1,  0, -1},
315	{ 33,  48, -1,  0, -1}, {153,  34, -1,  0, -1},
316	{ 35,  64, -1,  0, -1}, { 36,  47, -1,  0, -1},
317	{ -1,  -1, 12, 10,  0}, { -1,  -1,  4,  1,  1},
318	{ -1,  -1,  6,  2,  1}, {152,  40, -1,  0, -1},
319	{ 41,  62, -1,  0, -1}, { -1,  -1,  8,  3,  1},
320	{ -1,  -1,  9,  4,  1}, { 84,  44, -1,  0, -1},
321	{322,  45, -1,  0, -1}, { 46, 136, -1,  0, -1},
322	{ -1,  -1, 11,  5,  1}, { -1,  -1, 12,  6,  1},
323	{ 49, 189, -1,  0, -1}, { 50, 119, -1,  0, -1},
324	{ 51,  76, -1,  0, -1}, { 66,  52, -1,  0, -1},
325	{ 53,  69, -1,  0, -1}, { 54,  57, -1,  0, -1},
326	{ 55,  56, -1,  0, -1}, { -1,  -1, 16,  7,  1},
327	{ -1,  -1, 16,  8,  1}, { 58,  59, -1,  0, -1},
328	{ -1,  -1, 16,  9,  1}, { -1,  -1, 16, 10,  1},
329	{ 61,  81, -1,  0, -1}, { -1,  -1,  5,  1,  2},
330	{ -1,  -1,  8,  2,  2}, { -1,  -1, 10,  3,  2},
331	{ 65,  86, -1,  0, -1}, { -1,  -1, 12,  4,  2},
332	{286,  67, -1,  0, -1}, { 68, 304, -1,  0, -1},
333	{ -1,  -1, 15,  5,  2}, { 70,  73, -1,  0, -1},
334	{ 71,  72, -1,  0, -1}, { -1,  -1, 16,  6,  2},
335	{ -1,  -1, 16,  7,  2}, { 74,  75, -1,  0, -1},
336	{ -1,  -1, 16,  8,  2}, { -1,  -1, 16,  9,  2},
337	{ 77, 102, -1,  0, -1}, { 78,  91, -1,  0, -1},
338	{ 79,  88, -1,  0, -1}, { 80,  87, -1,  0, -1},
339	{ -1,  -1, 16, 10,  2}, { -1,  -1,  5,  1,  3},
340	{ 83, 171, -1,  0, -1}, { -1,  -1,  8,  2,  3},
341	{ 85, 117, -1,  0, -1}, { -1,  -1, 10,  3,  3},
342	{ -1,  -1, 12,  4,  3}, { -1,  -1, 16,  5,  3},
343	{ 89,  90, -1,  0, -1}, { -1,  -1, 16,  6,  3},
344	{ -1,  -1, 16,  7,  3}, { 92,  95, -1,  0, -1},
345	{ 93,  94, -1,  0, -1}, { -1,  -1, 16,  8,  3},
346	{ -1,  -1, 16,  9,  3}, { 96, 101, -1,  0, -1},
347	{ -1,  -1, 16, 10,  3}, { 98, 116, -1,  0, -1},
348	{ -1,  -1,  6,  1,  4}, {100, 188, -1,  0, -1},
349	{ -1,  -1,  9,  2,  4}, { -1,  -1, 16,  3,  4},
350	{103, 110, -1,  0, -1}, {104, 107, -1,  0, -1},
351	{105, 106, -1,  0, -1}, { -1,  -1, 16,  4,  4},
352	{ -1,  -1, 16,  5,  4}, {108, 109, -1,  0, -1},
353	{ -1,  -1, 16,  6,  4}, { -1,  -1, 16,  7,  4},
354	{111, 114, -1,  0, -1}, {112, 113, -1,  0, -1},
355	{ -1,  -1, 16,  8,  4}, { -1,  -1, 16,  9,  4},
356	{115, 118, -1,  0, -1}, { -1,  -1, 16, 10,  4},
357	{ -1,  -1,  6,  1,  5}, { -1,  -1, 10,  2,  5},
358	{ -1,  -1, 16,  3,  5}, {120, 156, -1,  0, -1},
359	{121, 138, -1,  0, -1}, {122, 129, -1,  0, -1},
360	{123, 126, -1,  0, -1}, {124, 125, -1,  0, -1},
361	{ -1,  -1, 16,  4,  5}, { -1,  -1, 16,  5,  5},
362	{127, 128, -1,  0, -1}, { -1,  -1, 16,  6,  5},
363	{ -1,  -1, 16,  7,  5}, {130, 133, -1,  0, -1},
364	{131, 132, -1,  0, -1}, { -1,  -1, 16,  8,  5},
365	{ -1,  -1, 16,  9,  5}, {134, 137, -1,  0, -1},
366	{ -1,  -1, 16, 10,  5}, { -1,  -1,  7,  1,  6},
367	{ -1,  -1, 11,  2,  6}, { -1,  -1, 16,  3,  6},
368	{139, 146, -1,  0, -1}, {140, 143, -1,  0, -1},
369	{141, 142, -1,  0, -1}, { -1,  -1, 16,  4,  6},
370	{ -1,  -1, 16,  5,  6}, {144, 145, -1,  0, -1},
371	{ -1,  -1, 16,  6,  6}, { -1,  -1, 16,  7,  6},
372	{147, 150, -1,  0, -1}, {148, 149, -1,  0, -1},
373	{ -1,  -1, 16,  8,  6}, { -1,  -1, 16,  9,  6},
374	{151, 155, -1,  0, -1}, { -1,  -1, 16, 10,  6},
375	{ -1,  -1,  7,  1,  7}, {154, 267, -1,  0, -1},
376	{ -1,  -1, 11,  2,  7}, { -1,  -1, 16,  3,  7},
377	{157, 173, -1,  0, -1}, {158, 165, -1,  0, -1},
378	{159, 162, -1,  0, -1}, {160, 161, -1,  0, -1},
379	{ -1,  -1, 16,  4,  7}, { -1,  -1, 16,  5,  7},
380	{163, 164, -1,  0, -1}, { -1,  -1, 16,  6,  7},
381	{ -1,  -1, 16,  7,  7}, {166, 169, -1,  0, -1},
382	{167, 168, -1,  0, -1}, { -1,  -1, 16,  8,  7},
383	{ -1,  -1, 16,  9,  7}, {170, 172, -1,  0, -1},
384	{ -1,  -1, 16, 10,  7}, { -1,  -1,  8,  1,  8},
385	{ -1,  -1, 16,  2,  8}, {174, 181, -1,  0, -1},
386	{175, 178, -1,  0, -1}, {176, 177, -1,  0, -1},
387	{ -1,  -1, 16,  3,  8}, { -1,  -1, 16,  4,  8},
388	{179, 180, -1,  0, -1}, { -1,  -1, 16,  5,  8},
389	{ -1,  -1, 16,  6,  8}, {182, 185, -1,  0, -1},
390	{183, 184, -1,  0, -1}, { -1,  -1, 16,  7,  8},
391	{ -1,  -1, 16,  8,  8}, {186, 187, -1,  0, -1},
392	{ -1,  -1, 16,  9,  8}, { -1,  -1, 16, 10,  8},
393	{ -1,  -1,  9,  1,  9}, {190, 257, -1,  0, -1},
394	{191, 224, -1,  0, -1}, {192, 207, -1,  0, -1},
395	{193, 200, -1,  0, -1}, {194, 197, -1,  0, -1},
396	{195, 196, -1,  0, -1}, { -1,  -1, 16,  2,  9},
397	{ -1,  -1, 16,  3,  9}, {198, 199, -1,  0, -1},
398	{ -1,  -1, 16,  4,  9}, { -1,  -1, 16,  5,  9},
399	{201, 204, -1,  0, -1}, {202, 203, -1,  0, -1},
400	{ -1,  -1, 16,  6,  9}, { -1,  -1, 16,  7,  9},
401	{205, 206, -1,  0, -1}, { -1,  -1, 16,  8,  9},
402	{ -1,  -1, 16,  9,  9}, {208, 217, -1,  0, -1},
403	{209, 214, -1,  0, -1}, {210, 213, -1,  0, -1},
404	{ -1,  -1, 16, 10,  9}, {212, 230, -1,  0, -1},
405	{ -1,  -1,  9,  1, 10}, { -1,  -1, 16,  2, 10},
406	{215, 216, -1,  0, -1}, { -1,  -1, 16,  3, 10},
407	{ -1,  -1, 16,  4, 10}, {218, 221, -1,  0, -1},
408	{219, 220, -1,  0, -1}, { -1,  -1, 16,  5, 10},
409	{ -1,  -1, 16,  6, 10}, {222, 223, -1,  0, -1},
410	{ -1,  -1, 16,  7, 10}, { -1,  -1, 16,  8, 10},
411	{225, 241, -1,  0, -1}, {226, 234, -1,  0, -1},
412	{227, 231, -1,  0, -1}, {228, 229, -1,  0, -1},
413	{ -1,  -1, 16,  9, 10}, { -1,  -1, 16, 10, 10},
414	{ -1,  -1,  9,  1, 11}, {232, 233, -1,  0, -1},
415	{ -1,  -1, 16,  2, 11}, { -1,  -1, 16,  3, 11},
416	{235, 238, -1,  0, -1}, {236, 237, -1,  0, -1},
417	{ -1,  -1, 16,  4, 11}, { -1,  -1, 16,  5, 11},
418	{239, 240, -1,  0, -1}, { -1,  -1, 16,  6, 11},
419	{ -1,  -1, 16,  7, 11}, {242, 250, -1,  0, -1},
420	{243, 246, -1,  0, -1}, {244, 245, -1,  0, -1},
421	{ -1,  -1, 16,  8, 11}, { -1,  -1, 16,  9, 11},
422	{247, 249, -1,  0, -1}, { -1,  -1, 16, 10, 11},
423	{ -1,  -1,  9,  1, 12}, { -1,  -1, 16,  2, 12},
424	{251, 254, -1,  0, -1}, {252, 253, -1,  0, -1},
425	{ -1,  -1, 16,  3, 12}, { -1,  -1, 16,  4, 12},
426	{255, 256, -1,  0, -1}, { -1,  -1, 16,  5, 12},
427	{ -1,  -1, 16,  6, 12}, {258, 291, -1,  0, -1},
428	{259, 275, -1,  0, -1}, {260, 268, -1,  0, -1},
429	{261, 264, -1,  0, -1}, {262, 263, -1,  0, -1},
430	{ -1,  -1, 16,  7, 12}, { -1,  -1, 16,  8, 12},
431	{265, 266, -1,  0, -1}, { -1,  -1, 16,  9, 12},
432	{ -1,  -1, 16, 10, 12}, { -1,  -1, 11,  1, 13},
433	{269, 272, -1,  0, -1}, {270, 271, -1,  0, -1},
434	{ -1,  -1, 16,  2, 13}, { -1,  -1, 16,  3, 13},
435	{273, 274, -1,  0, -1}, { -1,  -1, 16,  4, 13},
436	{ -1,  -1, 16,  5, 13}, {276, 283, -1,  0, -1},
437	{277, 280, -1,  0, -1}, {278, 279, -1,  0, -1},
438	{ -1,  -1, 16,  6, 13}, { -1,  -1, 16,  7, 13},
439	{281, 282, -1,  0, -1}, { -1,  -1, 16,  8, 13},
440	{ -1,  -1, 16,  9, 13}, {284, 288, -1,  0, -1},
441	{285, 287, -1,  0, -1}, { -1,  -1, 16, 10, 13},
442	{ -1,  -1, 14,  1, 14}, { -1,  -1, 16,  2, 14},
443	{289, 290, -1,  0, -1}, { -1,  -1, 16,  3, 14},
444	{ -1,  -1, 16,  4, 14}, {292, 308, -1,  0, -1},
445	{293, 300, -1,  0, -1}, {294, 297, -1,  0, -1},
446	{295, 296, -1,  0, -1}, { -1,  -1, 16,  5, 14},
447	{ -1,  -1, 16,  6, 14}, {298, 299, -1,  0, -1},
448	{ -1,  -1, 16,  7, 14}, { -1,  -1, 16,  8, 14},
449	{301, 305, -1,  0, -1}, {302, 303, -1,  0, -1},
450	{ -1,  -1, 16,  9, 14}, { -1,  -1, 16, 10, 14},
451	{ -1,  -1, 15,  1, 15}, {306, 307, -1,  0, -1},
452	{ -1,  -1, 16,  2, 15}, { -1,  -1, 16,  3, 15},
453	{309, 316, -1,  0, -1}, {310, 313, -1,  0, -1},
454	{311, 312, -1,  0, -1}, { -1,  -1, 16,  4, 15},
455	{ -1,  -1, 16,  5, 15}, {314, 315, -1,  0, -1},
456	{ -1,  -1, 16,  6, 15}, { -1,  -1, 16,  7, 15},
457	{317, 320, -1,  0, -1}, {318, 319, -1,  0, -1},
458	{ -1,  -1, 16,  8, 15}, { -1,  -1, 16,  9, 15},
459	{321,  -1, -1,  0, -1}, { -1,  -1, 16, 10, 15},
460	{ -1,  -1, 10,  0, 16}, { -1,  -1,  2,  0, -1},
461};
462
463static const struct tree_node treeYDC[] = {
464	{  1,   6, -1,  0}, {  2,   3, -1,  0},
465	{ -1,  -1,  2,  0}, {  4,   5, -1,  0},
466	{ -1,  -1,  3,  1}, { -1,  -1,  3,  2},
467	{  7,  10, -1,  0}, {  8,   9, -1,  0},
468	{ -1,  -1,  3,  3}, { -1,  -1,  3,  4},
469	{ 11,  12, -1,  0}, { -1,  -1,  3,  5},
470	{ 13,  14, -1,  0}, { -1,  -1,  4,  6},
471	{ 15,  16, -1,  0}, { -1,  -1,  5,  7},
472	{ 17,  18, -1,  0}, { -1,  -1,  6,  8},
473	{ 19,  20, -1,  0}, { -1,  -1,  7,  9},
474	{ 21,  22, -1,  0}, { -1,  -1,  8, 10},
475	{ 23,  -1, -1,  0}, { -1,  -1,  9, 11},
476};
477
478static const struct tree_node treeUVDC[] = {
479	{  1,   4, -1,  0}, {  2,   3, -1,  0},
480	{ -1,  -1,  2,  0}, { -1,  -1,  2,  1},
481	{  5,   6, -1,  0}, { -1,  -1,  2,  2},
482	{  7,   8, -1,  0}, { -1,  -1,  3,  3},
483	{  9,  10, -1,  0}, { -1,  -1,  4,  4},
484	{ 11,  12, -1,  0}, { -1,  -1,  5,  5},
485	{ 13,  14, -1,  0}, { -1,  -1,  6,  6},
486	{ 15,  16, -1,  0}, { -1,  -1,  7,  7},
487	{ 17,  18, -1,  0}, { -1,  -1,  8,  8},
488	{ 19,  20, -1,  0}, { -1,  -1,  9,  9},
489	{ 21,  22, -1,  0}, { -1,  -1, 10, 10},
490	{ 23,  -1, -1,  0}, { -1,  -1, 11, 11},
491};
492
493/******************************************************************************
494 * Debugging
495 ******************************************************************************/
496
497#ifdef PRINT_QT
498#define PRN_QT_ROW(a, i) PDEBUG(5, "%02x %02x %02x %02x %02x %02x %02x %02x", \
499	(a)[(i)], (a)[(i)+1], (a)[(i)+2], (a)[(i)+3], (a)[(i)+4], (a)[(i)+5], \
500	(a)[(i)+6], (a)[(i)+7])
501
502static inline void
503print_qt(unsigned char *qt)
504{
505	PDEBUG(5, "Y Quantization table:");
506	PRN_QT_ROW(qt, 0);
507	PRN_QT_ROW(qt, 8);
508	PRN_QT_ROW(qt, 16);
509	PRN_QT_ROW(qt, 24);
510	PDEBUG(5, "UV Quantization table:");
511	PRN_QT_ROW(qt, 32);
512	PRN_QT_ROW(qt, 40);
513	PRN_QT_ROW(qt, 48);
514	PRN_QT_ROW(qt, 56);
515}
516#else
517static inline void
518print_qt(unsigned char *qt) {  }
519#endif	/* PRINT_QT */
520
521/******************************************************************************
522 * Huffman Decoder
523 ******************************************************************************/
524
525/* Note: There is no penalty for passing the tree as an argument, since dummy
526 * args are passed anyway (to maintain 16-byte stack alignment), and since the
527 * address is loaded into a register either way. */
528
529/* If no node is found, coeffbits and skip will not be modified */
530/* Return: Depth of node found, or -1 if invalid input code */
531static int
532getNodeAC(unsigned int in, signed char *coeffbits, signed char *skip,
533	  const struct tree_node *tree)
534{
535	int node = 0;
536	int i = 0;
537	int depth;
538
539	do {
540		if ((in & 0x80000000) == 0)
541			node = tree[node].left;
542		else
543			node = tree[node].right;
544
545		if (node == -1)
546			break;
547
548		depth = tree[node].depth;
549
550		/* Is it a leaf? If not, branch downward */
551		if (depth != -1) {
552			*coeffbits = tree[node].coeffbits;
553			*skip = tree[node].skip;
554			return depth;
555		}
556
557		in <<= 1;
558		++i;
559	} while (i <= 15);
560
561	return -1;
562}
563
564/* If no node is found, coeffbits will not be modified */
565/* Return: Depth of node found, or -1 if invalid input code */
566static int
567getNodeDC(unsigned int in, signed char *coeffbits, const struct tree_node *tree)
568{
569	int node = 0;
570	int i = 0;
571	int depth;
572
573	do {
574		if ((in & 0x80000000) == 0)
575			node = tree[node].left;
576		else
577			node = tree[node].right;
578
579		if (node == -1)
580			break;
581
582		depth = tree[node].depth;
583
584		/* Is it a leaf? If not, branch downward */
585		if (depth != -1) {
586			*coeffbits = tree[node].coeffbits;
587			return depth;
588		}
589
590		in <<= 1;
591		++i;
592	} while (i <= 15);
593
594	return -1;
595}
596
597static inline unsigned int
598getBytes(int *rawData, struct comp_info *cinfo)
599{
600	int bufLen = cinfo->rawLen;
601	int bits = cinfo->bits;
602	int bytes = cinfo->bytes;
603	unsigned char *in = bytes + (unsigned char *) rawData;
604	unsigned char b1, b2, b3, b4, b5;
605	unsigned int packedIn;
606
607	/* Pull 5 bytes out of raw data */
608	if (bytes < bufLen - 4) {
609		b1 = in[0];
610		b2 = in[1];
611		b3 = in[2];
612		b4 = in[3];
613		b5 = in[4];
614	} else {
615		if (bytes < bufLen - 3) {
616			b1 = in[0];
617			b2 = in[1];
618			b3 = in[2];
619			b4 = in[3];
620		} else {
621			if (bytes < bufLen - 2) {
622				b1 = in[0];
623				b2 = in[1];
624				b3 = in[2];
625			} else {
626				if (bytes < bufLen - 1) {
627					b1 = in[0];
628					b2 = in[1];
629				} else {
630					if (bytes <= bufLen) {
631						b1 = in[0];
632					} else {
633						b1 = 0;
634					}
635					b2 = 0;
636				}
637				b3 = 0;
638			}
639			b4 = 0;
640		}
641		b5 = 0;
642	}
643
644	/* Pack the bytes */
645	packedIn  = b1 << 24;
646	packedIn += b2 << 16;
647	packedIn += b3 << 8;
648	packedIn += b4;
649
650	if (bits != 0) {
651		packedIn = packedIn << bits;
652		packedIn += b5 >> (8 - bits);
653	}
654
655	return packedIn;
656}
657
658static int
659getACCoefficient(int *rawData, int *coeff, struct comp_info *cinfo,
660		 const struct tree_node *tree)
661{
662	int input, bits, bytes, tmp_c;
663	signed char coeffbits = 0;
664	signed char skip = 0;
665
666	input = getBytes(rawData, cinfo);
667	bits = getNodeAC(input, &coeffbits, &skip, tree);
668
669	if (coeffbits) {
670		input = input << (bits - 1);
671		input &= 0x7fffffff;
672		if (! (input & 0x40000000))
673			input |= 0x80000000;
674
675		tmp_c = input >> (31 - coeffbits);
676		if (tmp_c < 0)
677			tmp_c++;
678		*coeff = tmp_c;
679
680		bits += coeffbits;
681	}
682
683	bytes = (bits + cinfo->bits) >> 3;
684	cinfo->bytes += bytes;
685	cinfo->bits += bits - (bytes << 3);
686
687	return skip;
688}
689
690static void
691getDCCoefficient(int *rawData, int *coeff, struct comp_info *cinfo,
692		 const struct tree_node *tree)
693{
694	int input, bits, bytes, tmp_c;
695	signed char coeffbits = 0;
696
697	input = getBytes(rawData, cinfo);
698	bits = getNodeDC(input, &coeffbits, tree);
699
700	if (bits == -1) {
701		bits = 1;	/* Try to re-sync at the next bit */
702		*coeff = 0;	/* Indicates no change from last DC */
703	} else {
704
705		input = input << (bits - 1);
706		input &= 0x7fffffff;
707		if (! (input & 0x40000000))
708			input |= 0x80000000;
709
710		tmp_c = input >> (31 - coeffbits);
711		if (tmp_c < 0)
712			tmp_c++;
713		*coeff = tmp_c;
714
715		bits += coeffbits;
716	}
717
718	bytes = (bits + cinfo->bits) >> 3;
719	cinfo->bytes += bytes;
720	cinfo->bits += bits - (bytes << 3);
721}
722
723/* For AC coefficients, here is what the "skip" value means:
724 *   -1: Either the 8x4 block has ended, or the decoding failed.
725 *    0: Use the returned coeff. Don't skip anything.
726 * 1-15: The next <skip> coeffs are zero. The returned coeff is used.
727 *   16: The next 16 coeffs are zero. The returned coeff is ignored.
728 *
729 * You must ensure that the C[] array not be overrun, or stack corruption will
730 * result.
731 */
732static void
733huffmanDecoderY(int *C, int *pIn, struct comp_info *cinfo)
734{
735	int coeff = 0;
736	int i = 1;
737	int k, skip;
738
739	getDCCoefficient(pIn, C, cinfo, treeYDC);
740
741	i = 1;
742	do {
743		skip = getACCoefficient(pIn, &coeff, cinfo, treeYAC);
744
745		if (skip == -1) {
746			break;
747		} else if (skip == 0) {
748			C[i++] = coeff;
749		} else if (skip == 16) {
750			k = 16;
751			if (i > 16)
752				k = 32 - i;
753
754			while (k--)
755				C[i++] = 0;
756		} else {
757			k = skip;
758			if (skip > 31 - i)
759				k = 31 - i;
760
761			while (k--)
762				C[i++] = 0;
763
764			C[i++] = coeff;
765		}
766	} while (i <= 31);
767
768	if (skip == -1)
769		while (i <= 31)  C[i++] = 0;
770	else
771		getACCoefficient(pIn, &coeff, cinfo, treeYAC);
772}
773
774/* Same as huffmanDecoderY, except for the tables used */
775static void
776huffmanDecoderUV(int *C, int *pIn, struct comp_info *cinfo)
777{
778	int coeff = 0;
779	int i = 1;
780	int k, skip;
781
782	getDCCoefficient(pIn, C, cinfo, treeUVDC);
783
784	i = 1;
785	do {
786		skip = getACCoefficient(pIn, &coeff, cinfo, treeUVAC);
787
788		if (skip == -1) {
789			break;
790		} else if (skip == 0) {
791			C[i++] = coeff;
792		} else if (skip == 16) {
793			k = 16;
794			if (i > 16)
795				k = 32 - i;
796
797			while (k--)
798				C[i++] = 0;
799		} else {
800			k = skip;
801			if (skip > 31 - i)
802				k = 31 - i;
803
804			while (k--)
805				C[i++] = 0;
806
807			C[i++] = coeff;
808		}
809	} while (i <= 31);
810
811	if (skip == -1)
812		while (i <= 31)  C[i++] = 0;
813	else
814		getACCoefficient(pIn, &coeff, cinfo, treeUVAC);
815}
816
817/******************************************************************************
818 * iDCT Functions
819 ******************************************************************************/
820
821#ifndef APPROXIMATE_MUL_BY_SHIFT
822
823#define IDCT_MESSAGE "iDCT with multiply"
824
825#define TIMES_16382(u)	((u)? 16382 * (u):0)
826#define TIMES_23168(u)	((u)? 23168 * (u):0)
827#define TIMES_30270(u)	((u)? 30270 * (u):0)
828#define TIMES_41986(u)	((u)? 41986 * (u):0)
829#define TIMES_35594(u)	((u)? 35594 * (u):0)
830#define TIMES_23783(u)	((u)? 23783 * (u):0)
831#define TIMES_8351(u)	((u)? 8351  * (u):0)
832#define TIMES_17391(u)	((u)? 17391 * (u):0)
833#define TIMES_14743(u)	((u)? 14743 * (u):0)
834#define TIMES_9851(u)	((u)? 9851  * (u):0)
835#define TIMES_3459(u)	((u)? 3459  * (u):0)
836#define TIMES_32134(u)	((u)? 32134 * (u):0)
837#define TIMES_27242(u)	((u)? 27242 * (u):0)
838#define TIMES_18202(u)	((u)? 18202 * (u):0)
839#define TIMES_6392(u)	((u)? 6392  * (u):0)
840#define TIMES_39550(u)	((u)? 39550 * (u):0)
841#define TIMES_6785(u)	((u)? 6785  * (u):0)
842#define TIMES_12538(u)	((u)? 12538 * (u):0)
843
844#else
845
846#define IDCT_MESSAGE "iDCT with shift"
847
848#define TIMES_16382(u) ( (u)? x=(u) , (x<<14) - (x<<1) :0 )
849#define TIMES_23168(u) ( (u)? x=(u) , (x<<14) + (x<<12) + (x<<11) + (x<<9) :0 )
850#define TIMES_30270(u) ( (u)? x=(u) , (x<<15) - (x<<11) :0 )
851#define TIMES_41986(u) ( (u)? x=(u) , (x<<15) + (x<<13) + (x<<10) :0 )
852#define TIMES_35594(u) ( (u)? x=(u) , (x<<15) + (x<<11) + (x<<9) + (x<<8) :0 )
853#define TIMES_23783(u) ( (u)? x=(u) , (x<<14) + (x<<13) - (x<<9) - (x<<8) :0 )
854#define TIMES_8351(u)  ( (u)? x=(u) , (x<<13) :0 )
855#define TIMES_17391(u) ( (u)? x=(u) , (x<<14) + (x<<10) :0 )
856#define TIMES_14743(u) ( (u)? x=(u) , (x<<14) - (x<<10) - (x<<9) :0 )
857#define TIMES_9851(u)  ( (u)? x=(u) , (x<<13) + (x<<10) + (x<<9) :0 )
858#define TIMES_3459(u)  ( (u)? x=(u) , (x<<12) - (x<<9) :0 )
859#define TIMES_32134(u) ( (u)? x=(u) , (x<<15) - (x<<9) :0 )
860#define TIMES_27242(u) ( (u)? x=(u) , (x<<14) + (x<<13) + (x<<11) + (x<<9) :0 )
861#define TIMES_18202(u) ( (u)? x=(u) , (x<<14) + (x<<11) - (x<<8) :0 )
862#define TIMES_6392(u)  ( (u)? x=(u) , (x<<13) - (x<<11) + (x<<8) :0 )
863#define TIMES_39550(u) ( (u)? x=(u) , (x<<15) + (x<<12) + (x<<11) + (x<<9) :0 )
864#define TIMES_6785(u)  ( (u)? x=(u) , (x<<12) + (x<<11) + (x<<9) :0 )
865#define TIMES_12538(u) ( (u)? x=(u) , (x<<13) + (x<<12) + (x<<8) :0 )
866
867/*
868 * The variables C0, C4, C16 and C20 can also be removed from the algorithm
869 * if APPROXIMATE_MUL_BY_SHIFTS is defined. They store correction values
870 * and can be considered insignificant.
871 */
872
873#endif
874
875static void
876DCT_8x4(int *coeff, unsigned char *out)
877/* pre: coeff == coefficients
878   post: coeff != coefficients
879   ** DO NOT ASSUME coeff TO BE THE SAME BEFORE AND AFTER CALLING THIS FUNCTION!
880*/
881{
882	register int base,val1,val2,val3;
883	int tmp1,tmp2;
884	int C0,C4,C16,C20;
885	int C2_18,C6_22,C1_17,C3_19,C5_21,C7_23;
886	register int t;
887#ifdef APPROXIMATE_MUL_BY_SHIFT
888	register int x;
889#endif
890
891	C0=coeff[0];
892	C4=coeff[4];
893	C16=coeff[16];
894	C20=coeff[20];
895
896	coeff[0]=TIMES_23168(coeff[0]);
897	coeff[4]=TIMES_23168(coeff[4]);
898	coeff[16]=TIMES_23168(coeff[16]);
899	coeff[20]=TIMES_23168(coeff[20]);
900
901	C2_18 = coeff[2]+coeff[18];
902	C6_22 = coeff[6]+coeff[22];
903	C1_17 = coeff[1]+coeff[17];
904	C3_19 = coeff[3]+coeff[19];
905	C5_21 = coeff[5]+coeff[21];
906	C7_23 = coeff[7]+coeff[23];
907
908// 0,7,25,32
909
910	base = 0x1000000;
911	base += coeff[0]+coeff[4]+coeff[16]+coeff[20];
912	base += TIMES_30270(C2_18);
913	base += TIMES_12538(C6_22);
914
915	val1 = TIMES_41986(coeff[9]);
916	val1 += TIMES_35594(coeff[11]);
917	val1 += TIMES_23783(coeff[13]);
918	val1 += TIMES_8351(coeff[15]);
919	val1 += TIMES_17391(coeff[25]);
920	val1 += TIMES_14743(coeff[27]);
921	val1 += TIMES_9851(coeff[29]);
922	val1 += TIMES_3459(coeff[31]);
923
924	val2 = TIMES_32134(C1_17);
925	val2 += TIMES_27242(C3_19);
926	val2 += TIMES_18202(C5_21);
927	val2 += TIMES_6392(C7_23);
928
929	val3 = TIMES_39550(coeff[10]);
930	val3 += TIMES_16382(coeff[14]+coeff[26]);
931	val3 += TIMES_6785(coeff[30]);
932	val3 += TIMES_30270(coeff[8]+coeff[12]);
933	val3 += TIMES_12538(coeff[24]+coeff[28]);
934
935	t=(base + val1 + val2 + val3) >> 17;
936	out[0]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t;
937	t=(base - val1 - val2 + val3 - C4 - C20) >> 17;
938	out[7]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t;
939	t=(base - val1 + val2 - val3 - C16- C20) >> 17;
940	out[24]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t;
941	t=(base + val1 - val2 - val3 - C4 - C16 - C20) >> 17;
942	out[31]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t;
943
944//1,6,25,30
945
946	base = 0x1000000;
947	base += coeff[0]-coeff[4]+coeff[16]-coeff[20];
948	base += TIMES_12538(C2_18);
949	base -= TIMES_30270(C6_22);
950
951	val1 = TIMES_35594(coeff[9]);
952	val1 -= TIMES_8351(coeff[11]);
953	val1 -= TIMES_41986(coeff[13]);
954	val1 -= TIMES_23783(coeff[15]);
955	val1 -= TIMES_14743(coeff[25]);
956	val1 -= TIMES_3459(coeff[27]);
957	val1 -= TIMES_17391(coeff[29]);
958	val1 -= TIMES_9851(coeff[31]);
959
960	val2 = TIMES_27242(C1_17);
961	val2 -= TIMES_6392(C3_19);
962	val2 -= TIMES_32134(C5_21);
963	val2 -= TIMES_18202(C7_23);
964
965	val3 = TIMES_16382(coeff[10]-coeff[30]);
966	val3 -= TIMES_39550(coeff[14]);
967	val3 += TIMES_6785(coeff[26]);
968	val3 += TIMES_12538(coeff[24]-coeff[28]);
969	val3 += TIMES_30270(coeff[8]-coeff[12]);
970
971	t=(base + val1 + val2 + val3 + C4 + C20) >> 17;
972	out[1]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t;
973	t=(base - val1 - val2 + val3) >> 17;
974	out[6]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t;
975	t=(base - val1 + val2 - val3 + C4 - C16 + C20) >> 17;
976	out[25]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t;
977	t=(base + val1 - val2 - val3 + C20) >> 17;
978	out[30]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t;
979
980//2,5,26,29
981
982	base = 0x1000000;
983	base += coeff[0] - coeff[4] + coeff[16] - coeff[20];
984	base -= TIMES_12538(C2_18);
985	base += TIMES_30270(C6_22);
986
987	val1 = TIMES_23783(coeff[9]);
988	val1 -= TIMES_41986(coeff[11]);
989	val1 += TIMES_8351(coeff[13]);
990	val1 += TIMES_35594(coeff[15]);
991	val1 += TIMES_9851(coeff[25]);
992	val1 -= TIMES_17391(coeff[27]);
993	val1 += TIMES_3459(coeff[29]);
994	val1 += TIMES_14743(coeff[31]);
995
996	val2 = TIMES_18202(C1_17);
997	val2 -= TIMES_32134(C3_19);
998	val2 += TIMES_6392(C5_21);
999	val2 += TIMES_27242(C7_23);
1000
1001	val3 = -TIMES_16382(coeff[10] - coeff[30]);
1002	val3 += TIMES_39550(coeff[14]);
1003	val3 -= TIMES_6785(coeff[26]);
1004	val3 += TIMES_12538(coeff[24] - coeff[28]);
1005	val3 += TIMES_30270(coeff[8] - coeff[12]);
1006
1007	t=(base + val1 + val2 + val3) >> 17;
1008	out[2]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t;
1009	t=(base - val1 - val2 + val3) >> 17;
1010	out[5]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t;
1011	t=(base - val1 + val2 - val3 - C16) >> 17;
1012	out[26]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t;
1013	t=(base + val1 - val2 - val3 + C4 - C16 + C20) >> 17;
1014	out[29]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t;
1015
1016//3,4,27,28
1017
1018	base = 0x1000000;
1019	base += coeff[0] + coeff[4] + coeff[16] + coeff[20];
1020	base -= TIMES_30270(C2_18);
1021	base -= TIMES_12538(C6_22);
1022
1023	val1 = TIMES_8351(coeff[9]);
1024	val1 -= TIMES_23783(coeff[11]);
1025	val1 += TIMES_35594(coeff[13]);
1026	val1 += TIMES_3459(coeff[25]);
1027	val1 -= TIMES_9851(coeff[27]);
1028	val1 += TIMES_14743(coeff[29]);
1029
1030	val2 = TIMES_6392(C1_17);
1031	val2 -= TIMES_18202(C3_19);
1032	val2 += TIMES_27242(C5_21);
1033
1034	val3 = -TIMES_39550(coeff[10]);
1035	val3 += TIMES_16382(coeff[14] + coeff[26]);
1036	val3 -= TIMES_6785(coeff[30]);
1037	val3 += TIMES_30270(coeff[8] + coeff[12]);
1038	val3 += TIMES_12538(coeff[24] + coeff[28]);
1039
1040	tmp1 = TIMES_32134(C7_23);
1041	tmp2 = TIMES_41986(coeff[15]) + TIMES_17391(coeff[31]);
1042
1043	t=(base + val1 + val2 + val3 - tmp1 - tmp2 - C4 - C20) >> 17;
1044	out[3]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t;
1045	t=(base - val1 - val2 + val3) >> 17;
1046	out[4]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t;
1047	t=(base - val1 + val2 - val3 - tmp1 + tmp2) >> 17;
1048	out[27]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t;
1049	t=(base + val1 - val2 - val3 - C16 - C20) >> 17;
1050	out[28]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t;
1051
1052// Second half
1053	C2_18 = coeff[2] - coeff[18];
1054	C6_22 = coeff[6] - coeff[22];
1055	C1_17 = coeff[1] - coeff[17];
1056	C3_19 = coeff[3] - coeff[19];
1057	C5_21 = coeff[5] - coeff[21];
1058	C7_23 = coeff[7] - coeff[23];
1059
1060// 8,15,16,23
1061
1062	base = 0x1000000;
1063	base += coeff[0] + coeff[4] - coeff[16] - coeff[20];
1064	base +=TIMES_30270(C2_18);
1065	base +=TIMES_12538(C6_22);
1066
1067	val1 = TIMES_17391(coeff[9]);
1068	val1 += TIMES_14743(coeff[11]);
1069	val1 += TIMES_9851(coeff[13]);
1070	val1 += TIMES_3459(coeff[15]);
1071	val1 -= TIMES_41986(coeff[25]);
1072	val1 -= TIMES_35594(coeff[27]);
1073	val1 -= TIMES_23783(coeff[29]);
1074	val1 -= TIMES_8351(coeff[31]);
1075
1076	val2 = TIMES_32134(C1_17);
1077	val2 += TIMES_27242(C3_19);
1078	val2 += TIMES_18202(C5_21);
1079	val2 += TIMES_6392(C7_23);
1080
1081	val3 = TIMES_16382(coeff[10] - coeff[30]);
1082	val3 += TIMES_6785(coeff[14]);
1083	val3 -= TIMES_39550(coeff[26]);
1084	val3 -=TIMES_30270(coeff[24] + coeff[28]);
1085	val3 +=TIMES_12538(coeff[8] + coeff[12]);
1086
1087	t=(base + val1 + val2 + val3) >> 17;
1088	out[8]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t;
1089	t=(base - val1 - val2 + val3 - C4 + C16 + C20) >> 17;
1090	out[15]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t;
1091	t=(base - val1 + val2 - val3) >> 17;
1092	out[16]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t;
1093	t=(base + val1 - val2 - val3 - C4 + C20) >> 17;
1094	out[23]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t;
1095
1096//9,14,17,22
1097
1098	base = 0x1000000;
1099	base += coeff[0] - coeff[4] - coeff[16] + coeff[20];
1100	base += TIMES_12538(C2_18);
1101	base -= TIMES_30270(C6_22);
1102
1103	val1 = TIMES_14743(coeff[9]);
1104	val1 -= TIMES_3459(coeff[11]);
1105	val1 -= TIMES_17391(coeff[13]);
1106	val1 -= TIMES_9851(coeff[15]);
1107	val1 -= TIMES_35594(coeff[25]);
1108	val1 += TIMES_8351(coeff[27]);
1109	val1 += TIMES_41986(coeff[29]);
1110	val1 += TIMES_23783(coeff[31]);
1111
1112	val2 = TIMES_27242(C1_17);
1113	val2 -= TIMES_6392(C3_19);
1114	val2 -= TIMES_32134(C5_21);
1115	val2 -= TIMES_18202(C7_23);
1116
1117	val3 = TIMES_6785(coeff[10]);
1118	val3 -= TIMES_16382(coeff[14] + coeff[26]);
1119	val3 += TIMES_39550(coeff[30]);
1120	val3 += TIMES_12538(coeff[8] - coeff[12]);
1121	val3 -= TIMES_30270(coeff[24] - coeff[28]);
1122
1123	t=(base + val1 + val2 + val3 + C4 + C16 - C20) >> 17;
1124	out[9]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t;
1125	t=(base - val1 - val2 + val3 + C16) >> 17;
1126	out[14]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t;
1127	t=(base - val1 + val2 - val3 + C4) >> 17;
1128	out[17]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t;
1129	t=(base + val1 - val2 - val3) >> 17;
1130	out[22]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t;
1131
1132//10,13,18,21
1133
1134	base = 0x1000000;
1135	base += coeff[0] - coeff[4] - coeff[16] + coeff[20];
1136	base -= TIMES_12538(C2_18);
1137	base += TIMES_30270(C6_22);
1138
1139	val1 = TIMES_9851(coeff[9]);
1140	val1 -= TIMES_17391(coeff[11]);
1141	val1 += TIMES_3459(coeff[13]);
1142	val1 += TIMES_14743(coeff[15]);
1143	val1 -= TIMES_23783(coeff[25]);
1144	val1 += TIMES_41986(coeff[27]);
1145	val1 -= TIMES_8351(coeff[29]);
1146	val1 -= TIMES_35594(coeff[31]);
1147
1148	val2 = TIMES_18202(C1_17);
1149	val2 -= TIMES_32134(C3_19);
1150	val2 += TIMES_6392(C5_21);
1151	val2 += TIMES_27242(C7_23);
1152
1153	val3 = -TIMES_6785(coeff[10]);
1154	val3 += TIMES_16382(coeff[14]+coeff[26]);
1155	val3 -= TIMES_39550(coeff[30]);
1156	val3 += TIMES_12538(coeff[8]-coeff[12]);
1157	val3 -= TIMES_30270(coeff[24]-coeff[28]);
1158
1159	t=(base + val1 + val2 + val3) >> 17;
1160	out[10]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t;
1161	t=(base - val1 - val2 + val3 + C4 + C16 - C20) >> 17;
1162	out[13]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t;
1163	t=(base - val1 + val2 - val3) >> 17;
1164	out[18]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t;
1165	t=(base + val1 - val2 - val3 + C4) >> 17;
1166	out[21]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t;
1167
1168// 11,12,19,20
1169
1170	base = 0x1000000;
1171	base += coeff[0]+coeff[4]-coeff[16]-coeff[20];
1172	base -= TIMES_30270(C2_18);
1173	base -= TIMES_12538(C6_22);
1174
1175	val1 = TIMES_3459(coeff[9]);
1176	val1 -= TIMES_9851(coeff[11]);
1177	val1 += TIMES_14743(coeff[13]);
1178	val1 -= TIMES_8351(coeff[25]);
1179	val1 += TIMES_23783(coeff[27]);
1180	val1 -= TIMES_35594(coeff[29]);
1181
1182	val2 = TIMES_6392(C1_17);
1183	val2 -= TIMES_18202(C3_19);
1184	val2 += TIMES_27242(C5_21);
1185
1186	val3 = -TIMES_16382(coeff[10] - coeff[30]);
1187	val3 -= TIMES_6785(coeff[14]);
1188	val3 += TIMES_39550(coeff[26]);
1189	val3 -= TIMES_30270(coeff[24]+coeff[28]);
1190	val3 += TIMES_12538(coeff[8]+coeff[12]);
1191
1192	tmp1 = TIMES_32134(C7_23);
1193	tmp2 = -TIMES_17391(coeff[15]) + TIMES_41986(coeff[31]);
1194
1195	t=(base + val1 + val2 + val3 - tmp1 + tmp2 + C16 + C20) >> 17;
1196	out[11]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t;
1197	t=(base - val1 - val2 + val3 + C16 + C20) >> 17;
1198	out[12]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t;
1199	t=(base - val1 + val2 - val3 - tmp1 - tmp2 - C4 + C20) >> 17;
1200	out[19]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t;
1201	t=(base + val1 - val2 - val3) >> 17;
1202	out[20]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t;
1203}
1204
1205#undef TIMES_16382
1206#undef TIMES_23168
1207#undef TIMES_30270
1208#undef TIMES_41986
1209#undef TIMES_35594
1210#undef TIMES_23783
1211#undef TIMES_8351
1212#undef TIMES_17391
1213#undef TIMES_14743
1214#undef TIMES_9851
1215#undef TIMES_3459
1216#undef TIMES_32134
1217#undef TIMES_27242
1218#undef TIMES_18202
1219#undef TIMES_6392
1220#undef TIMES_39550
1221#undef TIMES_6785
1222#undef TIMES_12538
1223
1224/******************************************************************************
1225 * Main Decoder Functions
1226 ******************************************************************************/
1227
1228/* This function handles the decompression of a single 8x4 block. It is
1229 * independent of the palette (YUV422, YUV420, YUV400, GBR422...). cinfo->bytes
1230 * determines the positin in the input buffer.
1231 */
1232static int
1233decompress8x4(unsigned char	*pOut,
1234	      unsigned char	*pIn,
1235	      int		*lastDC,
1236	      int		uvFlag,
1237	      struct comp_info	*cinfo)
1238{
1239	int i, x, y, dc;
1240	int coeffs[32];
1241	int deZigZag[32];
1242	int *dest;
1243	int *src;
1244	unsigned char *qt = cinfo->qt;
1245
1246	if (! uvFlag) {
1247		huffmanDecoderY(coeffs, (int*) pIn, cinfo);
1248
1249		/* iDPCM and dequantize first coefficient */
1250		dc = (*lastDC) + coeffs[0];
1251		coeffs[0] = dc * (qt[0] + 1);
1252		*lastDC = dc;
1253
1254		/* ...and the second coefficient */
1255		coeffs[1] = ((qt[1] + 1) * coeffs[1]) >> 1;
1256
1257		/* Dequantize, starting at 3rd element */
1258		for (i = 2; i < 32; i++)
1259			coeffs[i] = (qt[i] + 1) * coeffs[i];
1260	} else {
1261		huffmanDecoderUV(coeffs, (int*) pIn, cinfo);
1262
1263		/* iDPCM */
1264		dc = (*lastDC) + coeffs[0];
1265		coeffs[0] = dc;
1266		*lastDC = dc;
1267
1268		/* Dequantize */
1269		for (i = 0; i < 32; i++)
1270			coeffs[i] = (qt[32 + i] + 1) * coeffs[i];
1271	}
1272
1273	/* Dezigzag */
1274	for (i = 0; i < 32; i++)
1275		deZigZag[i] = coeffs[ZigZag518[i]];
1276
1277	/* Transpose the dezigzagged coefficient matrix */
1278	src = deZigZag;
1279	dest = coeffs;
1280	for (y = 0; y <= 3; ++y) {
1281		for (x = 0; x <= 7; ++x) {
1282			dest[x] = src[x * 4];
1283		}
1284		src += 1;
1285		dest += 8;
1286	}
1287
1288	/* Do the inverse DCT transform */
1289	DCT_8x4(coeffs, pOut);
1290
1291	return 0;	/* Always returns 0 */
1292}
1293
1294static inline void
1295copyBlock(unsigned char *src, unsigned char *dest, int destInc)
1296{
1297	int i;
1298	unsigned int *pSrc, *pDest;
1299
1300	for (i = 0; i <= 3; i++) {
1301		pSrc = (unsigned int *) src;
1302		pDest = (unsigned int *) dest;
1303		pDest[0] = pSrc[0];
1304		pDest[1] = pSrc[1];
1305		src += 8;
1306		dest += destInc;
1307	}
1308}
1309
1310static inline int
1311decompress400NoMMXOV518(unsigned char	 *pIn,
1312			unsigned char	 *pOut,
1313			unsigned char	 *pTmp,
1314			const int	 w,
1315			const int	 h,
1316			const int	 numpix,
1317			struct comp_info *cinfo)
1318{
1319	int iOutY, x, y;
1320	int lastYDC = 0;
1321
1322	/* Start Y loop */
1323	y = 0;
1324	do {
1325		iOutY = w * y;
1326		x = 0;
1327		do {
1328			decompress8x4(pTmp, pIn, &lastYDC, 0, cinfo);
1329			copyBlock(pTmp, pOut + iOutY, w);
1330			iOutY += 8;
1331			x += 8;
1332		} while (x < w);
1333		y += 4;
1334	} while (y < h);
1335
1336	/* Did we decode too much? */
1337	if (cinfo->bytes > cinfo->rawLen + 897)
1338		return 1;
1339
1340	/* Did we decode enough? */
1341	if (cinfo->bytes >= cinfo->rawLen - 897)
1342		return 0;
1343	else
1344		return 1;
1345}
1346
1347static inline int
1348decompress420NoMMXOV518(unsigned char	 *pIn,
1349			unsigned char	 *pOut,
1350			unsigned char	 *pTmp,
1351			const int	 w,
1352			const int	 h,
1353			const int	 numpix,
1354			struct comp_info *cinfo)
1355{
1356	unsigned char *pOutU = pOut + numpix;
1357	unsigned char *pOutV = pOutU + numpix / 4;
1358	int iOutY, iOutU, iOutV, x, y;
1359	int lastYDC = 0;
1360	int lastUDC = 0;
1361	int lastVDC = 0;
1362
1363	/* Start Y loop */
1364	y = 0;
1365	do {
1366		iOutY = w * y;
1367		iOutV = iOutU = iOutY / 4;
1368
1369		x = 0;
1370		do {
1371			decompress8x4(pTmp, pIn, &lastYDC, 0, cinfo);
1372			copyBlock(pTmp, pOut + iOutY, w);
1373			iOutY += 8;
1374			x += 8;
1375		} while (x < w);
1376
1377
1378
1379		iOutY = w * (y + 4);
1380		x = 0;
1381		do {
1382			decompress8x4(pTmp, pIn, &lastUDC, 1, cinfo);
1383			copyBlock(pTmp, pOutU + iOutU, w/2);
1384			iOutU += 8;
1385
1386			decompress8x4(pTmp, pIn, &lastVDC, 1, cinfo);
1387			copyBlock(pTmp, pOutV + iOutV, w/2);
1388			iOutV += 8;
1389
1390			decompress8x4(pTmp, pIn, &lastYDC, 0, cinfo);
1391			copyBlock(pTmp, pOut + iOutY, w);
1392			iOutY += 8;
1393
1394			decompress8x4(pTmp, pIn, &lastYDC, 0, cinfo);
1395			copyBlock(pTmp, pOut + iOutY, w);
1396			iOutY += 8;
1397
1398			x += 16;
1399		} while (x < w);
1400
1401		y += 8;
1402	} while (y < h);
1403
1404	/* Did we decode too much? */
1405	if (cinfo->bytes > cinfo->rawLen + 897)
1406		return 1;
1407
1408	/* Did we decode enough? */
1409	if (cinfo->bytes >= cinfo->rawLen - 897)
1410		return 0;
1411	else
1412		return 1;
1413}
1414
1415/* Get quantization tables from static arrays
1416 * Returns: <0 if error, or >=0 otherwise */
1417static int
1418get_qt_static(struct comp_info *cinfo)
1419{
1420	unsigned char qtY[] = OV518_YQUANTABLE;
1421	unsigned char qtUV[] = OV518_UVQUANTABLE;
1422	unsigned char qt[64];
1423
1424	memcpy(qt, qtY, 32);
1425	memcpy(qt + 32, qtUV, 32);
1426	cinfo->qt = qt;
1427
1428	return 0;
1429}
1430
1431
1432/* Get quantization tables from input
1433 * Returns: <0 if error, or >=0 otherwise */
1434static int
1435get_qt_dynamic(unsigned char *pIn, struct comp_info *cinfo)
1436{
1437	int rawLen = cinfo->rawLen;
1438
1439	/* Make sure input is actually big enough to hold trailer */
1440	if (rawLen < 72) {
1441		PDEBUG(1, "Not enough input to decompress");
1442		return -EINVAL;
1443	}
1444
1445	cinfo->qt = pIn + rawLen - 64;
1446
1447	print_qt(cinfo->qt);
1448
1449	return 0;
1450}
1451
1452/* Input format is raw isoc. data (with intact SOF header, packet numbers
1453 * stripped, and all-zero blocks removed).
1454 * Output format is planar YUV400
1455 * Returns uncompressed data length if success, or zero if error
1456 */
1457static int
1458Decompress400(unsigned char *pIn,
1459	      unsigned char *pOut,
1460	      unsigned char *pTmp,
1461	      int	     w,
1462	      int	     h,
1463	      int	     inSize)
1464{
1465	struct comp_info cinfo;
1466	int numpix = w * h;
1467
1468	PDEBUG(4, "%dx%d pIn=%p pOut=%p pTmp=%p inSize=%d", w, h, pIn, pOut,
1469	       pTmp, inSize);
1470
1471	cinfo.bytes = 0;
1472	cinfo.bits = 0;
1473	cinfo.rawLen = inSize;
1474
1475	if (staticquant) {
1476		if (get_qt_static(&cinfo) < 0)
1477			return 0;
1478	} else {
1479		if (get_qt_dynamic(pIn, &cinfo) < 0)
1480			return 0;
1481	}
1482
1483	/* Decompress, skipping the 8-byte SOF header */
1484	if (decompress400NoMMXOV518(pIn + 8, pOut, pTmp, w, h, numpix, &cinfo))
1485//		return 0;
1486		; /* Don't return error yet */
1487
1488	return (numpix);
1489}
1490
1491/* Input format is raw isoc. data (with intact SOF header, packet numbers
1492 * stripped, and all-zero blocks removed).
1493 * Output format is planar YUV420
1494 * Returns uncompressed data length if success, or zero if error
1495 */
1496static int
1497Decompress420(unsigned char *pIn,
1498	      unsigned char *pOut,
1499	      unsigned char *pTmp,
1500	      int	     w,
1501	      int	     h,
1502	      int	     inSize)
1503{
1504	struct comp_info cinfo;
1505	int numpix = w * h;
1506
1507	PDEBUG(4, "%dx%d pIn=%p pOut=%p pTmp=%p inSize=%d", w, h, pIn, pOut,
1508	       pTmp, inSize);
1509
1510	cinfo.bytes = 0;
1511	cinfo.bits = 0;
1512	cinfo.rawLen = inSize;
1513
1514	if (staticquant) {
1515		if (get_qt_static(&cinfo) < 0)
1516			return 0;
1517	} else {
1518		if (get_qt_dynamic(pIn, &cinfo) < 0)
1519			return 0;
1520	}
1521
1522	/* Decompress, skipping the 8-byte SOF header */
1523	if (decompress420NoMMXOV518(pIn + 8, pOut, pTmp, w, h, numpix, &cinfo))
1524//		return 0;
1525		; /* Don't return error yet */
1526
1527	return (numpix * 3 / 2);
1528}
1529
1530/******************************************************************************
1531 * Module Functions
1532 ******************************************************************************/
1533
1534static struct ov51x_decomp_ops decomp_ops = {
1535	.decomp_400 =	Decompress400,
1536	.decomp_420 =	Decompress420,
1537	.owner =	THIS_MODULE,
1538};
1539
1540static int __init
1541decomp_init(void)
1542{
1543	int rc;
1544
1545	EXPORT_NO_SYMBOLS;
1546
1547	rc = ov511_register_decomp_module(DECOMP_INTERFACE_VER, &decomp_ops,
1548					  ov518, mmx);
1549	if (rc) {
1550		err("Could not register with ov511 (rc=%d)", rc);
1551		return -1;
1552	}
1553
1554	info(DRIVER_VERSION " : " DRIVER_DESC);
1555	PDEBUG(1, "Using %s, %s quantization", IDCT_MESSAGE,
1556	       staticquant ? "static" : "dynamic");
1557
1558	return 0;
1559}
1560
1561static void __exit
1562decomp_exit(void)
1563{
1564	ov511_deregister_decomp_module(ov518, mmx);
1565	info("deregistered");
1566}
1567
1568module_init(decomp_init);
1569module_exit(decomp_exit);
1570