Merge branch 'ct' of git.pipapo.org:cinelerra-ct into ct
[cinelerra_cv/ct.git] / quicktime / cmodel_yuv422.c
blobf54b72d6d564e9e1e9ac570c3242594ef9901cb4
1 /*
2 * This library is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU Lesser General Public License as published
4 * by the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
6 *
7 * This library is distributed in the hope that it will be useful, but
8 * WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10 * Lesser General Public License for more details.
12 * You should have received a copy of the GNU Lesser General Public
13 * License along with this library; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
15 * USA
19 #include "cmodel_permutation.h"
23 static inline void transfer_YUV422_to_RGB8(unsigned char *(*output),
24 unsigned char *input,
25 int column)
27 int y, u, v;
28 int r, g, b;
30 // Even pixel
31 if(!(column & 1))
32 y = (int)(input[0]) << 16;
33 else
34 // Odd pixel
35 y = (int)(input[2]) << 16;
37 u = input[1];
38 v = input[3];
39 YUV_TO_RGB(y, u, v, r, g, b)
41 *(*output) = (unsigned char)((r & 0xc0) +
42 ((g & 0xe0) >> 2) +
43 ((b & 0xe0) >> 5));
44 (*output)++;
47 static inline void transfer_YUV422_to_BGR565(unsigned char *(*output),
48 unsigned char *input,
49 int column)
51 int y, u, v;
52 int r, g, b;
54 // Even pixel
55 if(!(column & 1))
56 y = (int)(input[0]) << 16;
57 else
58 // Odd pixel
59 y = (int)(input[2]) << 16;
60 u = input[1];
61 v = input[3];
62 YUV_TO_RGB(y, u, v, r, g, b)
64 *(uint16_t*)(*output) = ((b & 0xf8) << 8)
65 + ((g & 0xfc) << 3)
66 + ((r & 0xf8) >> 3);
67 (*output) += 2;
70 static inline void transfer_YUV422_to_RGB565(unsigned char *(*output),
71 unsigned char *input,
72 int column)
74 int y, u, v;
75 int r, g, b;
77 // Even pixel
78 if(!(column & 1))
79 y = (int)(input[0]) << 16;
80 else
81 // Odd pixel
82 y = (int)(input[2]) << 16;
83 u = input[1];
84 v = input[3];
85 YUV_TO_RGB(y, u, v, r, g, b)
87 *(uint16_t*)(*output) = ((r & 0xf8) << 8)
88 + ((g & 0xfc) << 3)
89 + ((b & 0xf8) >> 3);
90 (*output) += 2;
93 static inline void transfer_YUV422_to_BGR888(unsigned char *(*output),
94 unsigned char *input,
95 int column)
97 int y, u, v;
98 int r, g, b;
100 // Even pixel
101 if(!(column & 1))
102 y = (int)(input[0]) << 16;
103 else
104 // Odd pixel
105 y = (int)(input[2]) << 16;
106 u = input[1];
107 v = input[3];
108 YUV_TO_RGB(y, u, v, r, g, b)
110 (*output)[0] = b;
111 (*output)[1] = g;
112 (*output)[2] = r;
113 (*output) += 3;
116 static inline void transfer_YUV422_to_RGB888(unsigned char *(*output),
117 unsigned char *input,
118 int column)
120 int y, u, v;
121 int r, g, b;
123 // Even pixel
124 if(!(column & 1))
125 y = (input[0] << 16) | (input[0] << 8) | input[0];
126 else
127 // Odd pixel
128 y = (input[2] << 16) | (input[2] << 8) | input[2];
129 u = input[1];
130 v = input[3];
131 YUV_TO_RGB(y, u, v, r, g, b)
133 (*output)[0] = r;
134 (*output)[1] = g;
135 (*output)[2] = b;
136 (*output) += 3;
139 static inline void transfer_YUV422_to_RGBA8888(unsigned char *(*output),
140 unsigned char *input,
141 int column)
143 int y, u, v;
144 int r, g, b;
146 // Even pixel
147 if(!(column & 1))
148 y = (input[0] << 16) | (input[0] << 8) | input[0];
149 else
150 // Odd pixel
151 y = (input[2] << 16) | (input[2] << 8) | input[2];
152 u = input[1];
153 v = input[3];
154 YUV_TO_RGB(y, u, v, r, g, b)
156 (*output)[0] = r;
157 (*output)[1] = g;
158 (*output)[2] = b;
159 (*output)[3] = 0xff;
160 (*output) += 4;
163 static inline void transfer_YUV422_to_RGB161616(uint16_t *(*output),
164 unsigned char *input,
165 int column)
167 int y, u, v;
168 int r, g, b;
170 // Even pixel
171 if(!(column & 1))
172 y = (input[0] << 16) | (input[0] << 8) | input[0];
173 else
174 // Odd pixel
175 y = (input[2] << 16) | (input[2] << 8) | input[2];
176 u = (input[1] << 8) | input[1];
177 v = (input[3] << 8) | input[3];
178 YUV_TO_RGB16(y, u, v, r, g, b)
180 (*output)[0] = r;
181 (*output)[1] = g;
182 (*output)[2] = b;
183 (*output) += 3;
186 static inline void transfer_YUV422_to_RGBA16161616(uint16_t *(*output),
187 unsigned char *input,
188 int column)
190 int y, u, v;
191 int r, g, b;
193 // Even pixel
194 if(!(column & 1))
195 y = (input[0] << 16) | (input[0] << 8) | input[0];
196 else
197 // Odd pixel
198 y = (input[2] << 16) | (input[2] << 8) | input[2];
199 u = (input[1] << 8) | input[1];
200 v = (input[3] << 8) | input[3];
201 YUV_TO_RGB16(y, u, v, r, g, b)
203 (*output)[0] = r;
204 (*output)[1] = g;
205 (*output)[2] = b;
206 (*output)[3] = 0xffff;
207 (*output) += 4;
210 static inline void transfer_YUV422_to_RGB_FLOAT(float* *output,
211 unsigned char *input,
212 int column)
214 float y;
215 // Signedness is important
216 int u, v;
217 float r, g, b;
219 // Even pixel
220 if(!(column & 1))
221 y = (float)input[0] / 0xff;
222 else
223 // Odd pixel
224 y = (float)input[2] / 0xff;
225 u = input[1];
226 v = input[3];
227 YUV_TO_FLOAT(y, u, v, r, g, b)
229 *(*output)++ = r;
230 *(*output)++ = g;
231 *(*output)++ = b;
234 static inline void transfer_YUV422_to_RGBA_FLOAT(float* *output,
235 unsigned char *input,
236 int column)
238 float y;
239 // Signedness is important
240 int u, v;
241 float r, g, b;
243 // Even pixel
244 if(!(column & 1))
245 y = (float)input[0] / 0xff;
246 else
247 // Odd pixel
248 y = (float)input[2] / 0xff;
249 u = input[1];
250 v = input[3];
251 YUV_TO_FLOAT(y, u, v, r, g, b)
253 *(*output)++ = r;
254 *(*output)++ = g;
255 *(*output)++ = b;
256 *(*output)++ = 1.0;
259 static inline void transfer_YUV422_to_YUV888(unsigned char *(*output),
260 unsigned char *input,
261 int column)
263 // Even pixel
264 if(!(column & 1))
265 (*output)[0] = input[0];
266 else
267 // Odd pixel
268 (*output)[0] = input[2];
270 (*output)[1] = input[1];
271 (*output)[2] = input[3];
272 (*output) += 3;
275 static inline void transfer_YUV422_to_YUVA8888(unsigned char *(*output),
276 unsigned char *input,
277 int column)
279 // Even pixel
280 if(!(column & 1))
281 (*output)[0] = input[0];
282 else
283 // Odd pixel
284 (*output)[0] = input[2];
286 (*output)[1] = input[1];
287 (*output)[2] = input[3];
288 (*output)[3] = 255;
289 (*output) += 4;
292 static inline void transfer_YUV422_to_YUV161616(uint16_t *(*output),
293 unsigned char *input,
294 int column)
296 // Even pixel
297 if(!(column & 1))
298 (*output)[0] = (input[0] << 8) | input[0];
299 else
300 // Odd pixel
301 (*output)[0] = (input[2] << 8) | input[2];
303 (*output)[1] = (input[1] << 8) | input[1];
304 (*output)[2] = (input[3] << 8) | input[3];
305 (*output) += 3;
308 static inline void transfer_YUV422_to_YUVA16161616(uint16_t *(*output),
309 unsigned char *input,
310 int column)
312 // Even pixel
313 if(!(column & 1))
314 (*output)[0] = (input[0] << 8) | input[0];
315 else
316 // Odd pixel
317 (*output)[0] = (input[2] << 8) | input[2];
319 (*output)[1] = (input[1] << 8) | input[1];
320 (*output)[2] = (input[3] << 8) | input[3];
321 (*output)[3] = 0xffff;
322 (*output) += 4;
325 static inline void transfer_YUV422_to_BGR8888(unsigned char *(*output),
326 unsigned char *input,
327 int column)
329 int y, u, v;
330 int r, g, b;
332 // Even pixel
333 if(!(column & 1))
334 y = (int)(input[0]) << 16;
335 else
336 // Odd pixel
337 y = (int)(input[2]) << 16;
338 u = input[1];
339 v = input[3];
341 YUV_TO_RGB(y, u, v, r, g, b)
343 (*output)[0] = b;
344 (*output)[1] = g;
345 (*output)[2] = r;
346 (*output) += 4;
350 static inline void transfer_YUV422_to_YUV422P(unsigned char *output_y,
351 unsigned char *output_u,
352 unsigned char *output_v,
353 unsigned char *input,
354 int output_column)
356 // Store U and V for even pixels only
357 if(!(output_column & 1))
359 output_y[output_column] = input[0];
360 output_u[output_column / 2] = input[1];
361 output_v[output_column / 2] = input[3];
363 else
364 // Store Y and advance output for odd pixels only
366 output_y[output_column] = input[2];
370 static inline void transfer_YUV422_to_YUV420P(unsigned char *output_y,
371 unsigned char *output_u,
372 unsigned char *output_v,
373 unsigned char *input,
374 int output_column,
375 int output_row)
377 // Even column
378 if(!(output_column & 1))
380 output_y[output_column] = input[0];
381 // Store U and V for even columns and even rows only
382 if(!(output_row & 1))
384 output_u[output_column / 2] = input[1];
385 output_v[output_column / 2] = input[3];
388 else
389 // Odd column
391 output_y[output_column] = input[2];
395 static inline void transfer_YUV422_to_YUV422(unsigned char *(*output),
396 unsigned char *input,
397 int j)
399 // Store U and V for even pixels only
400 if(!(j & 1))
402 (*output)[0] = input[0];
403 (*output)[1] = input[1];
404 (*output)[3] = input[3];
406 else
407 // Store Y and advance output for odd pixels only
409 (*output)[2] = input[2];
410 (*output) += 4;
419 #define TRANSFER_FRAME_DEFAULT(output, \
420 input, \
421 y_in_offset, \
422 u_in_offset, \
423 v_in_offset, \
424 input_column) \
426 register int i, j; \
428 switch(out_colormodel) \
430 case BC_RGB8: \
431 TRANSFER_FRAME_HEAD \
432 transfer_YUV422_to_RGB8((output), (input), (input_column)); \
433 TRANSFER_FRAME_TAIL \
434 break; \
435 case BC_BGR565: \
436 case BC_RGB565: \
437 TRANSFER_FRAME_HEAD \
438 transfer_YUV422_to_RGB565((output), (input), (input_column)); \
439 TRANSFER_FRAME_TAIL \
440 break; \
441 case BC_RGB888: \
442 TRANSFER_FRAME_HEAD \
443 transfer_YUV422_to_RGB888((output), (input), (input_column)); \
444 TRANSFER_FRAME_TAIL \
445 break; \
446 case BC_RGBA8888: \
447 TRANSFER_FRAME_HEAD \
448 transfer_YUV422_to_RGBA8888((output), (input), (input_column)); \
449 TRANSFER_FRAME_TAIL \
450 break; \
451 case BC_YUV888: \
452 TRANSFER_FRAME_HEAD \
453 transfer_YUV422_to_YUV888((output), (input), (input_column)); \
454 TRANSFER_FRAME_TAIL \
455 break; \
456 case BC_YUVA8888: \
457 TRANSFER_FRAME_HEAD \
458 transfer_YUV422_to_YUVA8888((output), (input), (input_column)); \
459 TRANSFER_FRAME_TAIL \
460 break; \
461 case BC_RGB161616: \
462 TRANSFER_FRAME_HEAD \
463 transfer_YUV422_to_RGB161616((uint16_t**)(output), (input), (input_column)); \
464 TRANSFER_FRAME_TAIL \
465 break; \
466 case BC_RGBA16161616: \
467 TRANSFER_FRAME_HEAD \
468 transfer_YUV422_to_RGBA16161616((uint16_t**)(output), (input), (input_column)); \
469 TRANSFER_FRAME_TAIL \
470 break; \
471 case BC_RGB_FLOAT: \
472 TRANSFER_FRAME_HEAD \
473 transfer_YUV422_to_RGB_FLOAT((float**)(output), (input), (input_column)); \
474 TRANSFER_FRAME_TAIL \
475 break; \
476 case BC_RGBA_FLOAT: \
477 TRANSFER_FRAME_HEAD \
478 transfer_YUV422_to_RGBA_FLOAT((float**)(output), (input), (input_column)); \
479 TRANSFER_FRAME_TAIL \
480 break; \
481 case BC_YUV161616: \
482 TRANSFER_FRAME_HEAD \
483 transfer_YUV422_to_YUV161616((uint16_t**)(output), (input), (input_column)); \
484 TRANSFER_FRAME_TAIL \
485 break; \
486 case BC_YUVA16161616: \
487 TRANSFER_FRAME_HEAD \
488 transfer_YUV422_to_YUVA16161616((uint16_t**)(output), (input), (input_column)); \
489 TRANSFER_FRAME_TAIL \
490 break; \
491 case BC_BGR888: \
492 TRANSFER_FRAME_HEAD \
493 transfer_YUV422_to_BGR888((output), (input), (input_column)); \
494 TRANSFER_FRAME_TAIL \
495 break; \
496 case BC_BGR8888: \
497 TRANSFER_FRAME_HEAD \
498 transfer_YUV422_to_BGR8888((output), (input), (input_column)); \
499 TRANSFER_FRAME_TAIL \
500 break; \
501 case BC_YUV422P: \
502 TRANSFER_YUV422P_OUT_HEAD \
503 transfer_YUV422_to_YUV422P(output_y, \
504 output_u, \
505 output_v, \
506 (input), \
507 j); \
508 TRANSFER_FRAME_TAIL \
509 break; \
510 case BC_YUV422: \
511 TRANSFER_FRAME_HEAD \
512 transfer_YUV422_to_YUV422((output), \
513 (input), \
514 j); \
515 TRANSFER_FRAME_TAIL \
516 break; \
517 case BC_YUV420P: \
518 TRANSFER_YUV420P_OUT_HEAD \
519 transfer_YUV422_to_YUV420P(output_y, \
520 output_u, \
521 output_v, \
522 (input), \
523 j, \
524 i); \
525 TRANSFER_FRAME_TAIL \
526 break; \
530 void cmodel_yuv422(PERMUTATION_ARGS)
532 if(scale)
534 TRANSFER_FRAME_DEFAULT(&output_row,
535 input_row + ((column_table[j] * in_pixelsize) & 0xfffffffc),
539 column_table[j]);
541 else
543 TRANSFER_FRAME_DEFAULT(&output_row,
544 input_row + ((j * in_pixelsize) & 0xfffffffc),