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