repair flickering video encode, bug created last checkin
[goodguy/history.git] / cinelerra-5.0 / quicktime / cmodel_yuv422.c
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.
11  * 
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
16  */
17
18
19 #include "cmodel_permutation.h"
20
21
22
23 static inline void transfer_YUV422_to_RGB8(unsigned char *(*output), 
24         unsigned char *input, 
25         int column)
26 {
27         int y, u, v;
28         int r, g, b;
29
30 // Even pixel
31         if(!(column & 1))
32                 y = (int)(input[0]) << 16;
33         else
34 // Odd pixel
35                 y = (int)(input[2]) << 16;
36
37         u = input[1];
38         v = input[3];
39         YUV_TO_RGB(y, u, v, r, g, b)
40
41         *(*output) = (unsigned char)((r & 0xc0) +
42                                                  ((g & 0xe0) >> 2) +
43                                                  ((b & 0xe0) >> 5));
44         (*output)++;
45 }
46
47 static inline void transfer_YUV422_to_BGR565(unsigned char *(*output), 
48         unsigned char *input, 
49         int column)
50 {
51         int y, u, v;
52         int r, g, b;
53
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)
63
64         *(uint16_t*)(*output) = ((b & 0xf8) << 8)
65                          + ((g & 0xfc) << 3)
66                          + ((r & 0xf8) >> 3);
67         (*output) += 2;
68 }
69
70 static inline void transfer_YUV422_to_RGB565(unsigned char *(*output), 
71         unsigned char *input, 
72         int column)
73 {
74         int y, u, v;
75         int r, g, b;
76
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)
86
87         *(uint16_t*)(*output) = ((r & 0xf8) << 8)
88                          + ((g & 0xfc) << 3)
89                          + ((b & 0xf8) >> 3);
90         (*output) += 2;
91 }
92
93 static inline void transfer_YUV422_to_BGR888(unsigned char *(*output), 
94         unsigned char *input, 
95         int column)
96 {
97         int y, u, v;
98         int r, g, b;
99
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)
109
110         (*output)[0] = b;
111         (*output)[1] = g;
112         (*output)[2] = r;
113         (*output) += 3;
114 }
115
116 static inline void transfer_YUV422_to_RGB888(unsigned char *(*output), 
117         unsigned char *input, 
118         int column)
119 {
120         int y, u, v;
121         int r, g, b;
122
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)
132
133         (*output)[0] = r;
134         (*output)[1] = g;
135         (*output)[2] = b;
136         (*output) += 3;
137 }
138
139 static inline void transfer_YUV422_to_RGBA8888(unsigned char *(*output), 
140         unsigned char *input, 
141         int column)
142 {
143         int y, u, v;
144         int r, g, b;
145
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)
155
156         (*output)[0] = r;
157         (*output)[1] = g;
158         (*output)[2] = b;
159         (*output)[3] = 0xff;
160         (*output) += 4;
161 }
162
163 static inline void transfer_YUV422_to_RGB161616(uint16_t *(*output), 
164         unsigned char *input, 
165         int column)
166 {
167         int y, u, v;
168         int r, g, b;
169
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)
179
180         (*output)[0] = r;
181         (*output)[1] = g;
182         (*output)[2] = b;
183         (*output) += 3;
184 }
185
186 static inline void transfer_YUV422_to_RGBA16161616(uint16_t *(*output), 
187         unsigned char *input, 
188         int column)
189 {
190         int y, u, v;
191         int r, g, b;
192
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)
202
203         (*output)[0] = r;
204         (*output)[1] = g;
205         (*output)[2] = b;
206         (*output)[3] = 0xffff;
207         (*output) += 4;
208 }
209
210 static inline void transfer_YUV422_to_RGB_FLOAT(float* *output, 
211         unsigned char *input, 
212         int column)
213 {
214         float y;
215 // Signedness is important
216         int u, v;
217         float r, g, b;
218
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)
228
229         *(*output)++ = r;
230         *(*output)++ = g;
231         *(*output)++ = b;
232 }
233
234 static inline void transfer_YUV422_to_RGBA_FLOAT(float* *output, 
235         unsigned char *input, 
236         int column)
237 {
238         float y;
239 // Signedness is important
240         int u, v;
241         float r, g, b;
242
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)
252
253         *(*output)++ = r;
254         *(*output)++ = g;
255         *(*output)++ = b;
256         *(*output)++ = 1.0;
257 }
258
259 static inline void transfer_YUV422_to_YUV888(unsigned char *(*output), 
260         unsigned char *input, 
261         int column)
262 {
263 // Even pixel
264         if(!(column & 1))
265                 (*output)[0] = input[0];
266         else
267 // Odd pixel
268                 (*output)[0] = input[2];
269
270         (*output)[1] = input[1];
271         (*output)[2] = input[3];
272         (*output) += 3;
273 }
274
275 static inline void transfer_YUV422_to_YUVA8888(unsigned char *(*output), 
276         unsigned char *input, 
277         int column)
278 {
279 // Even pixel
280         if(!(column & 1))
281                 (*output)[0] = input[0];
282         else
283 // Odd pixel
284                 (*output)[0] = input[2];
285
286         (*output)[1] = input[1];
287         (*output)[2] = input[3];
288         (*output)[3] = 255;
289         (*output) += 4;
290 }
291
292 static inline void transfer_YUV422_to_YUV161616(uint16_t *(*output), 
293         unsigned char *input, 
294         int column)
295 {
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];
302
303         (*output)[1] = (input[1] << 8) | input[1];
304         (*output)[2] = (input[3] << 8) | input[3];
305         (*output) += 3;
306 }
307
308 static inline void transfer_YUV422_to_YUVA16161616(uint16_t *(*output), 
309         unsigned char *input, 
310         int column)
311 {
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];
318
319         (*output)[1] = (input[1] << 8) | input[1];
320         (*output)[2] = (input[3] << 8) | input[3];
321         (*output)[3] = 0xffff;
322         (*output) += 4;
323 }
324
325 static inline void transfer_YUV422_to_BGR8888(unsigned char *(*output), 
326         unsigned char *input, 
327         int column)
328 {
329         int y, u, v;
330         int r, g, b;
331
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];
340
341         YUV_TO_RGB(y, u, v, r, g, b)
342
343         (*output)[0] = b;
344         (*output)[1] = g;
345         (*output)[2] = r;
346         (*output) += 4;
347 }
348
349
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)
355 {
356 // Store U and V for even pixels only
357         if(!(output_column & 1))
358         {
359                 output_y[output_column] = input[0];
360                 output_u[output_column / 2] = input[1];
361                 output_v[output_column / 2] = input[3];
362         }
363         else
364 // Store Y and advance output for odd pixels only
365         {
366                 output_y[output_column] = input[2];
367         }
368 }
369
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)
376 {
377 // Even column
378         if(!(output_column & 1))
379         {
380                 output_y[output_column] = input[0];
381 // Store U and V for even columns and even rows only
382                 if(!(output_row & 1))
383                 {
384                         output_u[output_column / 2] = input[1];
385                         output_v[output_column / 2] = input[3];
386                 }
387         }
388         else
389 // Odd column
390         {
391                 output_y[output_column] = input[2];
392         }
393 }
394
395 static inline void transfer_YUV422_to_YUV422(unsigned char *(*output), 
396         unsigned char *input,
397         int j)
398 {
399 // Store U and V for even pixels only
400         if(!(j & 1))
401         {
402                 (*output)[0] = input[0];
403                 (*output)[1] = input[1];
404                 (*output)[3] = input[3];
405         }
406         else
407 // Store Y and advance output for odd pixels only
408         {
409                 (*output)[2] = input[2];
410                 (*output) += 4;
411         }
412 }
413
414
415
416
417
418
419 #define TRANSFER_FRAME_DEFAULT(output, \
420         input, \
421         y_in_offset, \
422         u_in_offset, \
423         v_in_offset, \
424         input_column) \
425 { \
426         register int i, j; \
427  \
428         switch(out_colormodel) \
429         { \
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                         TRANSFER_FRAME_HEAD \
437                         transfer_YUV422_to_BGR565((output), \
438                                 (input), \
439                                 j); \
440                         TRANSFER_FRAME_TAIL \
441                         break; \
442                 case BC_RGB565: \
443                         TRANSFER_FRAME_HEAD \
444                         transfer_YUV422_to_RGB565((output), (input), (input_column)); \
445                         TRANSFER_FRAME_TAIL \
446                         break; \
447                 case BC_RGB888:      \
448                         TRANSFER_FRAME_HEAD \
449                         transfer_YUV422_to_RGB888((output), (input), (input_column)); \
450                         TRANSFER_FRAME_TAIL \
451                         break; \
452                 case BC_RGBA8888:      \
453                         TRANSFER_FRAME_HEAD \
454                         transfer_YUV422_to_RGBA8888((output), (input), (input_column)); \
455                         TRANSFER_FRAME_TAIL \
456                         break; \
457                 case BC_YUV888:      \
458                         TRANSFER_FRAME_HEAD \
459                         transfer_YUV422_to_YUV888((output), (input), (input_column)); \
460                         TRANSFER_FRAME_TAIL \
461                         break; \
462                 case BC_YUVA8888:      \
463                         TRANSFER_FRAME_HEAD \
464                         transfer_YUV422_to_YUVA8888((output), (input), (input_column)); \
465                         TRANSFER_FRAME_TAIL \
466                         break; \
467                 case BC_RGB161616:      \
468                         TRANSFER_FRAME_HEAD \
469                         transfer_YUV422_to_RGB161616((uint16_t**)(output), (input), (input_column)); \
470                         TRANSFER_FRAME_TAIL \
471                         break; \
472                 case BC_RGBA16161616:      \
473                         TRANSFER_FRAME_HEAD \
474                         transfer_YUV422_to_RGBA16161616((uint16_t**)(output), (input), (input_column)); \
475                         TRANSFER_FRAME_TAIL \
476                         break; \
477                 case BC_RGB_FLOAT:      \
478                         TRANSFER_FRAME_HEAD \
479                         transfer_YUV422_to_RGB_FLOAT((float**)(output), (input), (input_column)); \
480                         TRANSFER_FRAME_TAIL \
481                         break; \
482                 case BC_RGBA_FLOAT:      \
483                         TRANSFER_FRAME_HEAD \
484                         transfer_YUV422_to_RGBA_FLOAT((float**)(output), (input), (input_column)); \
485                         TRANSFER_FRAME_TAIL \
486                         break; \
487                 case BC_YUV161616:      \
488                         TRANSFER_FRAME_HEAD \
489                         transfer_YUV422_to_YUV161616((uint16_t**)(output), (input), (input_column)); \
490                         TRANSFER_FRAME_TAIL \
491                         break; \
492                 case BC_YUVA16161616:      \
493                         TRANSFER_FRAME_HEAD \
494                         transfer_YUV422_to_YUVA16161616((uint16_t**)(output), (input), (input_column)); \
495                         TRANSFER_FRAME_TAIL \
496                         break; \
497                 case BC_BGR888:      \
498                         TRANSFER_FRAME_HEAD \
499                         transfer_YUV422_to_BGR888((output), (input), (input_column)); \
500                         TRANSFER_FRAME_TAIL \
501                         break; \
502                 case BC_BGR8888: \
503                         TRANSFER_FRAME_HEAD \
504                         transfer_YUV422_to_BGR8888((output), (input), (input_column)); \
505                         TRANSFER_FRAME_TAIL \
506                         break; \
507                 case BC_YUV422P: \
508                         TRANSFER_YUV422P_OUT_HEAD \
509                         transfer_YUV422_to_YUV422P(output_y, \
510                                 output_u, \
511                                 output_v, \
512                                 (input), \
513                                 j); \
514                         TRANSFER_FRAME_TAIL \
515                         break; \
516                 case BC_YUV422: \
517                         TRANSFER_FRAME_HEAD \
518                         transfer_YUV422_to_YUV422((output), \
519                                 (input), \
520                                 j); \
521                         TRANSFER_FRAME_TAIL \
522                         break; \
523                 case BC_YUV420P: \
524                         TRANSFER_YUV420P_OUT_HEAD \
525                         transfer_YUV422_to_YUV420P(output_y, \
526                                 output_u, \
527                                 output_v, \
528                                 (input), \
529                                 j, \
530                                 i); \
531                         TRANSFER_FRAME_TAIL \
532                         break; \
533         } \
534 }
535
536 void cmodel_yuv422(PERMUTATION_ARGS)
537 {
538         if(scale)
539         {
540                 TRANSFER_FRAME_DEFAULT(&output_row, 
541                         input_row + ((column_table[j] * in_pixelsize) & 0xfffffffc),
542                         0,
543                         0,
544                         0,
545                         column_table[j]);
546         }
547         else
548         {
549                 TRANSFER_FRAME_DEFAULT(&output_row, 
550                         input_row + ((j * in_pixelsize) & 0xfffffffc),
551                         0,
552                         0,
553                         0,
554                         j);
555         }
556 }