summaryrefslogtreecommitdiff
path: root/mjpeg/colorspaces.c (plain)
blob: 723505c49e3d9c4544701973c21e97a3a8609ea3
1/*******************************************************************************#
2# guvcview http://guvcview.sourceforge.net #
3# #
4# Paulo Assis <pj.assis@gmail.com> #
5# Nobuhiro Iwamatsu <iwamatsu@nigauri.org> #
6# #
7# This program is free software; you can redistribute it and/or modify #
8# it under the terms of the GNU General Public License as published by #
9# the Free Software Foundation; either version 2 of the License, or #
10# (at your option) any later version. #
11# #
12# This program is distributed in the hope that it will be useful, #
13# but WITHOUT ANY WARRANTY; without even the implied warranty of #
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
15# GNU General Public License for more details. #
16# #
17# You should have received a copy of the GNU General Public License #
18# along with this program; if not, write to the Free Software #
19# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #
20# #
21********************************************************************************/
22
23#include <stdlib.h>
24#include <stdio.h>
25#include <string.h>
26#include "colorspaces.h"
27#include <stdbool.h>
28#define TRUE 1
29#define FALSE 0
30/*------------------------------- Color space conversions --------------------*/
31/* regular yuv (YUYV) to rgb24*/
32void
33yuyv2rgb (BYTE *pyuv, BYTE *prgb, int width, int height)
34{
35 int l=0;
36 int SizeYUV=height * width * 2; /* 2 bytes per pixel*/
37 for(l=0;l<SizeYUV;l=l+4)
38 { /*iterate every 4 bytes*/
39 /* standart: r = y0 + 1.402 (v-128) */
40 /* logitech: r = y0 + 1.370705 (v-128) */
41 *prgb++=CLIP(pyuv[l] + 1.402 * (pyuv[l+3]-128));
42 /* standart: g = y0 - 0.34414 (u-128) - 0.71414 (v-128)*/
43 /* logitech: g = y0 - 0.337633 (u-128)- 0.698001 (v-128)*/
44 *prgb++=CLIP(pyuv[l] - 0.34414 * (pyuv[l+1]-128) -0.71414*(pyuv[l+3]-128));
45 /* standart: b = y0 + 1.772 (u-128) */
46 /* logitech: b = y0 + 1.732446 (u-128) */
47 *prgb++=CLIP(pyuv[l] + 1.772 *( pyuv[l+1]-128));
48 /* standart: r1 =y1 + 1.402 (v-128) */
49 /* logitech: r1 = y1 + 1.370705 (v-128) */
50 *prgb++=CLIP(pyuv[l+2] + 1.402 * (pyuv[l+3]-128));
51 /* standart: g1 = y1 - 0.34414 (u-128) - 0.71414 (v-128)*/
52 /* logitech: g1 = y1 - 0.337633 (u-128)- 0.698001 (v-128)*/
53 *prgb++=CLIP(pyuv[l+2] - 0.34414 * (pyuv[l+1]-128) -0.71414 * (pyuv[l+3]-128));
54 /* standart: b1 = y1 + 1.772 (u-128) */
55 /* logitech: b1 = y1 + 1.732446 (u-128) */
56 *prgb++=CLIP(pyuv[l+2] + 1.772*(pyuv[l+1]-128));
57 }
58}
59
60/* used for rgb video (fourcc="RGB ") */
61/* lines are on correct order */
62void
63yuyv2bgr1 (BYTE *pyuv, BYTE *pbgr, int width, int height)
64{
65
66 int l=0;
67 int SizeYUV=height * width * 2; /* 2 bytes per pixel*/
68 for(l=0;l<SizeYUV;l=l+4)
69 { /*iterate every 4 bytes*/
70 /* standart: b = y0 + 1.772 (u-128) */
71 /* logitech: b = y0 + 1.732446 (u-128) */
72 *pbgr++=CLIP(pyuv[l] + 1.772 *( pyuv[l+1]-128));
73 /* standart: g = y0 - 0.34414 (u-128) - 0.71414 (v-128)*/
74 /* logitech: g = y0 - 0.337633 (u-128)- 0.698001 (v-128)*/
75 *pbgr++=CLIP(pyuv[l] - 0.34414 * (pyuv[l+1]-128) -0.71414*(pyuv[l+3]-128));
76 /* standart: r = y0 + 1.402 (v-128) */
77 /* logitech: r = y0 + 1.370705 (v-128) */
78 *pbgr++=CLIP(pyuv[l] + 1.402 * (pyuv[l+3]-128));
79 /* standart: b1 = y1 + 1.772 (u-128) */
80 /* logitech: b1 = y1 + 1.732446 (u-128) */
81 *pbgr++=CLIP(pyuv[l+2] + 1.772*(pyuv[l+1]-128));
82 /* standart: g1 = y1 - 0.34414 (u-128) - 0.71414 (v-128)*/
83 /* logitech: g1 = y1 - 0.337633 (u-128)- 0.698001 (v-128)*/
84 *pbgr++=CLIP(pyuv[l+2] - 0.34414 * (pyuv[l+1]-128) -0.71414 * (pyuv[l+3]-128));
85 /* standart: r1 =y1 + 1.402 (v-128) */
86 /* logitech: r1 = y1 + 1.370705 (v-128) */
87 *pbgr++=CLIP(pyuv[l+2] + 1.402 * (pyuv[l+3]-128));
88 }
89}
90
91/* yuv (YUYV) to bgr with lines upsidedown */
92/* used for bitmap files (DIB24) */
93void
94yuyv2bgr (BYTE *pyuv, BYTE *pbgr, int width, int height)
95{
96
97 int l=0;
98 int k=0;
99 BYTE *preverse;
100 int bytesUsed;
101 int SizeBGR=height * width * 3; /* 3 bytes per pixel*/
102 /* BMP byte order is bgr and the lines start from last to first*/
103 preverse=pbgr+SizeBGR;/*start at the end and decrement*/
104 for(l=0;l<height;l++)
105 { /*iterate every 1 line*/
106 preverse-=width*3;/*put pointer at begin of unprocessed line*/
107 bytesUsed=l*width*2;
108 for (k=0;k<(width*2);k=k+4)/*iterate every 4 bytes in the line*/
109 {
110 /* standart: b = y0 + 1.772 (u-128) */
111 /* logitech: b = y0 + 1.732446 (u-128) */
112 *preverse++=CLIP(pyuv[k+bytesUsed] + 1.772 *( pyuv[k+1+bytesUsed]-128));
113 /* standart: g = y0 - 0.34414 (u-128) - 0.71414 (v-128)*/
114 /* logitech: g = y0 - 0.337633 (u-128)- 0.698001 (v-128)*/
115 *preverse++=CLIP(pyuv[k+bytesUsed] - 0.34414 * (pyuv[k+1+bytesUsed]-128)
116 -0.71414*(pyuv[k+3+bytesUsed]-128));
117 /* standart: r = y0 + 1.402 (v-128) */
118 /* logitech: r = y0 + 1.370705 (v-128) */
119 *preverse++=CLIP(pyuv[k+bytesUsed] + 1.402 * (pyuv[k+3+bytesUsed]-128));
120 /* standart: b1 = y1 + 1.772 (u-128) */
121 /* logitech: b1 = y1 + 1.732446 (u-128) */
122 *preverse++=CLIP(pyuv[k+2+bytesUsed] + 1.772*(pyuv[k+1+bytesUsed]-128));
123 /* standart: g1 = y1 - 0.34414 (u-128) - 0.71414 (v-128)*/
124 /* logitech: g1 = y1 - 0.337633 (u-128)- 0.698001 (v-128)*/
125 *preverse++=CLIP(pyuv[k+2+bytesUsed] - 0.34414 * (pyuv[k+1+bytesUsed]-128)
126 -0.71414 * (pyuv[k+3+bytesUsed]-128));
127 /* standart: r1 =y1 + 1.402 (v-128) */
128 /* logitech: r1 = y1 + 1.370705 (v-128) */
129 *preverse++=CLIP(pyuv[k+2+bytesUsed] + 1.402 * (pyuv[k+3+bytesUsed]-128));
130 }
131 preverse-=width*3;/*get it back at the begin of processed line*/
132 }
133 preverse=NULL;
134}
135
136/* Unpack buffer of (vw bit) data into padded 16bit buffer. */
137static inline void convert_packed_to_16bit(uint8_t *raw, uint16_t *unpacked, int vw, int unpacked_len)
138{
139 int mask = (1 << vw) - 1;
140 uint32_t buffer = 0;
141 int bitsIn = 0;
142 while (unpacked_len--) {
143 while (bitsIn < vw) {
144 buffer = (buffer << 8) | *(raw++);
145 bitsIn += 8;
146 }
147 bitsIn -= vw;
148 *(unpacked++) = (buffer >> bitsIn) & mask;
149 }
150}
151
152/*convert y10b (bit-packed array greyscale format) to yuyv (packed)
153* args:
154* framebuffer: pointer to frame buffer (yuyv)
155* tmpbuffer: pointer to temp buffer containing y10b (bit-packed array) data frame
156* width: picture width
157* height: picture height
158*/
159void y10b_to_yuyv (BYTE *framebuffer, BYTE *tmpbuffer, int width, int height)
160{
161 UINT16 *unpacked_buffer = NULL;
162 UINT16 *ptmp;
163 int h = 0;
164 int w = 0;
165
166 unpacked_buffer = malloc(width * height * sizeof(UINT16));
167 convert_packed_to_16bit(tmpbuffer, unpacked_buffer, 10, width * height);
168
169 ptmp = unpacked_buffer;
170
171 for (h = 0; h < height; h++)
172 {
173 for (w = 0; w < width; w += 2)
174 {
175 /* Y0 */
176 *framebuffer++ = (BYTE) ((ptmp[0] & 0x3FF) >> 2);
177 /* U */
178 *framebuffer++ = 0x80;
179 /* Y1 */
180 *framebuffer++ = (BYTE) ((ptmp[1] & 0x3FF) >> 2);
181 /* V */
182 *framebuffer++ = 0x80;
183
184 ptmp += 2;
185 }
186 }
187
188 free(unpacked_buffer);
189}
190
191/*convert y16 (grey) to yuyv (packed)
192* args:
193* framebuffer: pointer to frame buffer (yuyv)
194* tmpbuffer: pointer to temp buffer containing y16 (grey) data frame
195* width: picture width
196* height: picture height
197*/
198void y16_to_yuyv (BYTE *framebuffer, BYTE *tmpbuffer, int width, int height)
199{
200 UINT16 *ptmp= (UINT16 *) tmpbuffer;
201
202 int h=0;
203 int w=0;
204
205 for(h=0;h<height;h++)
206 {
207 for(w=0;w<width;w+=2)
208 {
209 /* Y0 */
210 *framebuffer++ = (BYTE) ((ptmp[0] & 0xFF00) >> 8);
211 /* U */
212 *framebuffer++ = 0x80;
213 /* Y1 */
214 *framebuffer++ = (BYTE) ((ptmp[1] & 0xFF00) >> 8);
215 /* V */
216 *framebuffer++ = 0x80;
217
218 ptmp += 2;
219 }
220 }
221}
222
223/*convert yyuv (packed) to yuyv (packed)
224* args:
225* framebuffer: pointer to frame buffer (yuyv)
226* tmpbuffer: pointer to temp buffer containing yyuv packed data frame
227* width: picture width
228* height: picture height
229*/
230void yyuv_to_yuyv (BYTE *framebuffer, BYTE *tmpbuffer, int width, int height)
231{
232 BYTE *ptmp=NULL;
233 BYTE *pfmb=NULL;
234 ptmp = tmpbuffer;
235 pfmb = framebuffer;
236
237 int h=0;
238 int w=0;
239
240 for(h=0;h<height;h++)
241 {
242 for(w=0;w<(width*2);w+=4)
243 {
244 /* Y0 */
245 pfmb[0] = ptmp[0];
246 /* U */
247 pfmb[1] = ptmp[2];
248 /* Y1 */
249 pfmb[2] = ptmp[1];
250 /* V */
251 pfmb[3] = ptmp[3];
252
253 ptmp += 4;
254 pfmb += 4;
255 }
256 }
257}
258
259
260/*convert uyvy (packed) to yuyv (packed)
261* args:
262* framebuffer: pointer to frame buffer (yuyv)
263* tmpbuffer: pointer to temp buffer containing uyvy packed data frame
264* width: picture width
265* height: picture height
266*/
267void uyvy_to_yuyv (BYTE *framebuffer, BYTE *tmpbuffer, int width, int height)
268{
269 BYTE *ptmp = tmpbuffer;
270 BYTE *pfmb = framebuffer;
271 int h=0;
272 int w=0;
273
274 for(h=0;h<height;h++)
275 {
276 for(w=0;w<(width*2);w+=4)
277 {
278 /* Y0 */
279 pfmb[0] = ptmp[1];
280 /* U */
281 pfmb[1] = ptmp[0];
282 /* Y1 */
283 pfmb[2] = ptmp[3];
284 /* V */
285 pfmb[3] = ptmp[2];
286
287 ptmp += 4;
288 pfmb += 4;
289 }
290 }
291}
292
293
294/*convert yvyu (packed) to yuyv (packed)
295* args:
296* framebuffer: pointer to frame buffer (yuyv)
297* tmpbuffer: pointer to temp buffer containing yvyu packed data frame
298* width: picture width
299* height: picture height
300*/
301void yvyu_to_yuyv (BYTE *framebuffer, BYTE *tmpbuffer, int width, int height)
302{
303 BYTE *ptmp=NULL;
304 BYTE *pfmb=NULL;
305 ptmp = tmpbuffer;
306 pfmb = framebuffer;
307
308 int h=0;
309 int w=0;
310
311 for(h=0;h<height;h++)
312 {
313 for(w=0;w<(width*2);w+=4)
314 {
315 /* Y0 */
316 pfmb[0] = ptmp[0];
317 /* U */
318 pfmb[1] = ptmp[3];
319 /* Y1 */
320 pfmb[2] = ptmp[2];
321 /* V */
322 pfmb[3] = ptmp[1];
323
324 ptmp += 4;
325 pfmb += 4;
326 }
327 }
328}
329
330/*convert yuv 420 planar (yu12) to yuv 422
331* args:
332* framebuffer: pointer to frame buffer (yuyv)
333* tmpbuffer: pointer to temp buffer containing yuv420 planar data frame
334* width: picture width
335* height: picture height
336*/
337void yuv420_to_yuyv (BYTE *framebuffer, BYTE *tmpbuffer, int width, int height)
338{
339 BYTE *py;
340 BYTE *pu;
341 BYTE *pv;
342
343 int linesize = width * 2;
344 int uvlinesize = width / 2;
345 int offset=0;
346 int offset1=0;
347 int offsety=0;
348 int offsety1=0;
349 int offsetuv=0;
350
351 py=tmpbuffer;
352 pu=py+(width*height);
353 pv=pu+(width*height/4);
354
355 int h=0;
356 int w=0;
357
358 int wy=0;
359 int huv=0;
360 int wuv=0;
361
362 for(h=0;h<height;h+=2)
363 {
364 wy=0;
365 wuv=0;
366 offset = h * linesize;
367 offset1 = (h + 1) * linesize;
368 offsety = h * width;
369 offsety1 = (h + 1) * width;
370 offsetuv = huv * uvlinesize;
371
372 for(w=0;w<linesize;w+=4)
373 {
374 /*y00*/
375 framebuffer[w + offset] = py[wy + offsety];
376 /*u0*/
377 framebuffer[(w + 1) + offset] = pu[wuv + offsetuv];
378 /*y01*/
379 framebuffer[(w + 2) + offset] = py[(wy + 1) + offsety];
380 /*v0*/
381 framebuffer[(w + 3) + offset] = pv[wuv + offsetuv];
382
383 /*y10*/
384 framebuffer[w + offset1] = py[wy + offsety1];
385 /*u0*/
386 framebuffer[(w + 1) + offset1] = pu[wuv + offsetuv];
387 /*y11*/
388 framebuffer[(w + 2) + offset1] = py[(wy + 1) + offsety1];
389 /*v0*/
390 framebuffer[(w + 3) + offset1] = pv[wuv + offsetuv];
391
392 wuv++;
393 wy+=2;
394 }
395 huv++;
396 }
397}
398
399/*convert yvu 420 planar (yv12) to yuv 422
400* args:
401* framebuffer: pointer to frame buffer (yuyv)
402* tmpbuffer: pointer to temp buffer containing yuv420 planar data frame
403* width: picture width
404* height: picture height
405*/
406void yvu420_to_yuyv (BYTE *framebuffer, BYTE *tmpbuffer, int width, int height)
407{
408 BYTE *py;
409 BYTE *pv;
410 BYTE *pu;
411
412 int linesize = width * 2;
413 int uvlinesize = width / 2;
414 int offset=0;
415 int offset1=0;
416 int offsety=0;
417 int offsety1=0;
418 int offsetuv=0;
419
420 py=tmpbuffer;
421 pv=py+(width*height);
422 pu=pv+((width*height)/4);
423
424 int h=0;
425 int w=0;
426
427 int wy=0;
428 int huv=0;
429 int wuv=0;
430
431 for(h=0;h<height;h+=2)
432 {
433 wy=0;
434 wuv=0;
435 offset = h * linesize;
436 offset1 = (h + 1) * linesize;
437 offsety = h * width;
438 offsety1 = (h + 1) * width;
439 offsetuv = huv * uvlinesize;
440
441 for(w=0;w<linesize;w+=4)
442 {
443 /*y00*/
444 framebuffer[w + offset] = py[wy + offsety];
445 /*u0*/
446 framebuffer[(w + 1) + offset] = pu[wuv + offsetuv];
447 /*y01*/
448 framebuffer[(w + 2) + offset] = py[(wy + 1) + offsety];
449 /*v0*/
450 framebuffer[(w + 3) + offset] = pv[wuv + offsetuv];
451
452 /*y10*/
453 framebuffer[w + offset1] = py[wy + offsety1];
454 /*u0*/
455 framebuffer[(w + 1) + offset1] = pu[wuv + offsetuv];
456 /*y11*/
457 framebuffer[(w + 2) + offset1] = py[(wy + 1) + offsety1];
458 /*v0*/
459 framebuffer[(w + 3) + offset1] = pv[wuv + offsetuv];
460
461 wuv++;
462 wy+=2;
463 }
464 huv++;
465 }
466}
467
468/*convert yuv 420 planar (uv interleaved) (nv12) to yuv 422
469* args:
470* framebuffer: pointer to frame buffer (yuyv)
471* tmpbuffer: pointer to temp buffer containing yuv420 (nv12) planar data frame
472* width: picture width
473* height: picture height
474*/
475void nv12_to_yuyv (BYTE *framebuffer, BYTE *tmpbuffer, int width, int height)
476{
477 BYTE *py;
478 BYTE *puv;
479
480 int linesize = width * 2;
481 int offset=0;
482 int offset1=0;
483 int offsety=0;
484 int offsety1=0;
485 int offsetuv=0;
486
487 py=tmpbuffer;
488 puv=py+(width*height);
489
490 int h=0;
491 int w=0;
492
493 int wy=0;
494 int huv=0;
495 int wuv=0;
496
497 for(h=0;h<height;h+=2)
498 {
499 wy=0;
500 wuv=0;
501 offset = h * linesize;
502 offset1 = (h+1) * linesize;
503 offsety = h * width;
504 offsety1 = (h+1) * width;
505 offsetuv = huv * width;
506 for(w=0;w<linesize;w+=4)
507 {
508 /*y00*/
509 framebuffer[w + offset] = py[wy + offsety];
510 /*u0*/
511 framebuffer[(w + 1) + offset] = puv[wuv + offsetuv];
512 /*y01*/
513 framebuffer[(w + 2) + offset] = py[(wy + 1) + offsety];
514 /*v0*/
515 framebuffer[(w + 3) + offset] = puv[(wuv + 1) + offsetuv];
516
517 /*y10*/
518 framebuffer[w + offset1] = py[wy + offsety1];
519 /*u0*/
520 framebuffer[(w + 1) + offset1] = puv[wuv + offsetuv];
521 /*y11*/
522 framebuffer[(w + 2) + offset1] = py[(wy + 1) + offsety1];
523 /*v0*/
524 framebuffer[(w + 3) + offset1] = puv[(wuv + 1) + offsetuv];
525
526 wuv+=2;
527 wy+=2;
528 }
529 huv++;
530 }
531}
532
533/*convert yuv 420 planar (vu interleaved) (nv21) to yuv 422
534* args:
535* framebuffer: pointer to frame buffer (yuyv)
536* tmpbuffer: pointer to temp buffer containing yuv420 (nv21) planar data frame
537* width: picture width
538* height: picture height
539*/
540void nv21_to_yuyv (BYTE *framebuffer, BYTE *tmpbuffer, int width, int height)
541{
542 BYTE *py;
543 BYTE *puv;
544
545 int linesize = width * 2;
546 int offset=0;
547 int offset1=0;
548 int offsety=0;
549 int offsety1=0;
550 int offsetuv=0;
551
552 py=tmpbuffer;
553 puv=py+(width*height);
554
555 int h=0;
556 int w=0;
557
558 int wy=0;
559 int huv=0;
560 int wuv=0;
561
562 for(h=0;h<height;h+=2)
563 {
564 wy=0;
565 wuv=0;
566 offset = h * linesize;
567 offset1 = (h+1) * linesize;
568 offsety = h * width;
569 offsety1 = (h+1) * width;
570 offsetuv = huv * width;
571 for(w=0;w<linesize;w+=4)
572 {
573 /*y00*/
574 framebuffer[w + offset] = py[wy + offsety];
575 /*u0*/
576 framebuffer[(w + 1) + offset] = puv[(wuv + 1) + offsetuv];
577 /*y01*/
578 framebuffer[(w + 2) + offset] = py[(wy + 1) + offsety];
579 /*v0*/
580 framebuffer[(w + 3) + offset] = puv[wuv + offsetuv];
581
582 /*y10*/
583 framebuffer[w + offset1] = py[wy + offsety1];
584 /*u0*/
585 framebuffer[(w + 1) + offset1] = puv[(wuv + 1) + offsetuv];
586 /*y11*/
587 framebuffer[(w + 2) + offset1] = py[(wy + 1) + offsety1];
588 /*v0*/
589 framebuffer[(w + 3) + offset1] = puv[wuv + offsetuv];
590
591 wuv+=2;
592 wy+=2;
593 }
594 huv++;
595 }
596}
597
598/*convert yuv 422 planar (uv interleaved) (nv16) to yuv 422
599* args:
600* framebuffer: pointer to frame buffer (yuyv)
601* tmpbuffer: pointer to temp buffer containing yuv422 (nv16) planar data frame
602* width: picture width
603* height: picture height
604*/
605void nv16_to_yuyv (BYTE *framebuffer, BYTE *tmpbuffer, int width, int height)
606{
607 BYTE *py;
608 BYTE *puv;
609
610 int linesize = width * 2;
611 int offset=0;
612 int offsety=0;
613 int offsetuv=0;
614
615 py=tmpbuffer;
616 puv=py+(width*height);
617
618 int h=0;
619 int w=0;
620
621 int wy=0;
622 int huv=0;
623 int wuv=0;
624
625 for(h=0;h<height;h++)
626 {
627 wy=0;
628 wuv=0;
629 offset = h * linesize;
630 offsety = h * width;
631 offsetuv = huv * width;
632 for(w=0;w<linesize;w+=4)
633 {
634 /*y00*/
635 framebuffer[w + offset] = py[wy + offsety];
636 /*u0*/
637 framebuffer[(w + 1) + offset] = puv[wuv + offsetuv];
638 /*y01*/
639 framebuffer[(w + 2) + offset] = py[(wy + 1) + offsety];
640 /*v0*/
641 framebuffer[(w + 3) + offset] = puv[(wuv + 1) + offsetuv];
642
643 wuv+=2;
644 wy+=2;
645 }
646 huv++;
647 }
648}
649
650/*convert yuv 422 planar (vu interleaved) (nv61) to yuv 422
651* args:
652* framebuffer: pointer to frame buffer (yuyv)
653* tmpbuffer: pointer to temp buffer containing yuv422 (nv61) planar data frame
654* width: picture width
655* height: picture height
656*/
657void nv61_to_yuyv (BYTE *framebuffer, BYTE *tmpbuffer, int width, int height)
658{
659 BYTE *py;
660 BYTE *puv;
661
662 int linesize = width * 2;
663 int offset=0;
664 int offsety=0;
665 int offsetuv=0;
666
667 py=tmpbuffer;
668 puv=py+(width*height);
669
670 int h=0;
671 int w=0;
672
673 int wy=0;
674 int huv=0;
675 int wuv=0;
676
677 for(h=0;h<height;h++)
678 {
679 wy=0;
680 wuv=0;
681 offset = h * linesize;
682 offsety = h * width;
683 offsetuv = huv * width;
684 for(w=0;w<linesize;w+=4)
685 {
686 /*y00*/
687 framebuffer[w + offset] = py[wy + offsety];
688 /*u0*/
689 framebuffer[(w + 1) + offset] = puv[(wuv + 1) + offsetuv];
690 /*y01*/
691 framebuffer[(w + 2) + offset] = py[(wy + 1) + offsety];
692 /*v0*/
693 framebuffer[(w + 3) + offset] = puv[wuv + offsetuv];
694
695 wuv+=2;
696 wy+=2;
697 }
698 huv++;
699 }
700}
701
702/*convert yuv 411 packed (y41p) to yuv 422
703* args:
704* framebuffer: pointer to frame buffer (yuyv)
705* tmpbuffer: pointer to temp buffer containing y41p data frame
706* width: picture width
707* height: picture height
708*/
709void y41p_to_yuyv (BYTE *framebuffer, BYTE *tmpbuffer, int width, int height)
710{
711 int h=0;
712 int w=0;
713 int linesize = width * 3 /2;
714 int offset = 0;
715
716 for(h=0;h<height;h++)
717 {
718 offset = linesize * h;
719 for(w=0;w<linesize;w+=12)
720 {
721 *framebuffer++=tmpbuffer[w+1 + offset]; //Y0
722 *framebuffer++=tmpbuffer[w + offset]; //U0
723 *framebuffer++=tmpbuffer[w+3 + offset]; //Y1
724 *framebuffer++=tmpbuffer[w+2 + offset]; //V0
725 *framebuffer++=tmpbuffer[w+5 + offset]; //Y2
726 *framebuffer++=tmpbuffer[w + offset]; //U0
727 *framebuffer++=tmpbuffer[w+7 + offset]; //Y3
728 *framebuffer++=tmpbuffer[w+2 + offset]; //V0
729 *framebuffer++=tmpbuffer[w+8 + offset]; //Y4
730 *framebuffer++=tmpbuffer[w+4 + offset]; //U4
731 *framebuffer++=tmpbuffer[w+9 + offset]; //Y5
732 *framebuffer++=tmpbuffer[w+6 + offset]; //V4
733 *framebuffer++=tmpbuffer[w+10+ offset]; //Y6
734 *framebuffer++=tmpbuffer[w+4 + offset]; //U4
735 *framebuffer++=tmpbuffer[w+11+ offset]; //Y7
736 *framebuffer++=tmpbuffer[w+6 + offset]; //V4
737 }
738 }
739}
740
741/*convert yuv mono (grey) to yuv 422
742* args:
743* framebuffer: pointer to frame buffer (yuyv)
744* tmpbuffer: pointer to temp buffer containing grey (y only) data frame
745* width: picture width
746* height: picture height
747*/
748void grey_to_yuyv (BYTE *framebuffer, BYTE *tmpbuffer, int width, int height)
749{
750 int h=0;
751 int w=0;
752 int offset = 0;
753
754 for(h=0;h<height;h++)
755 {
756 offset = width * h;
757 for(w=0;w<width;w++)
758 {
759 *framebuffer++=tmpbuffer[w + offset]; //Y
760 *framebuffer++=0x80; //U or V
761 }
762 }
763}
764
765/*convert SPCA501 (s501) to yuv 422
766* s501 |Y0..width..Y0|U..width/2..U|Y1..width..Y1|V..width/2..V|
767* signed values (-128;+127) must be converted to unsigned (0; 255)
768* args:
769* framebuffer: pointer to frame buffer (yuyv)
770* tmpbuffer: pointer to temp buffer containing s501 data frame
771* width: picture width
772* height: picture height
773*/
774void s501_to_yuyv(BYTE *framebuffer, BYTE *tmpbuffer, int width, int height)
775{
776 BYTE *U, *V, *Y0, *Y1;
777 BYTE *line2;
778 int h, w;
779
780 Y0 = tmpbuffer; /*fisrt line*/
781 for (h = 0; h < height/2; h++ )
782 {
783 line2 = framebuffer + width * 2; /* next line */
784 U = Y0 + width;
785 Y1 = U + width / 2;
786 V = Y1 + width;
787 for (w = width / 2; --w >= 0; )
788 {
789 *framebuffer++ = 0x80 + *Y0++;
790 *framebuffer++ = 0x80 + *U;
791 *framebuffer++ = 0x80 + *Y0++;
792 *framebuffer++ = 0x80 + *V;
793
794 *line2++ = 0x80 + *Y1++;
795 *line2++ = 0x80 + *U++;
796 *line2++ = 0x80 + *Y1++;
797 *line2++ = 0x80 + *V++;
798 }
799 Y0 += width * 2; /* next block of lines */
800 framebuffer = line2;
801 }
802}
803
804/*convert SPCA505 (s505) to yuv 422
805* s505 |Y0..width..Y0|Y1..width..Y1|U..width/2..U|V..width/2..V|
806* signed values (-128;+127) must be converted to unsigned (0; 255)
807* args:
808* framebuffer: pointer to frame buffer (yuyv)
809* tmpbuffer: pointer to temp buffer containing s501 data frame
810* width: picture width
811* height: picture height
812*/
813void s505_to_yuyv(BYTE *framebuffer, BYTE *tmpbuffer, int width, int height)
814{
815 BYTE *U, *V, *Y0, *Y1;
816 BYTE *line2;
817 int h, w;
818
819 Y0 = tmpbuffer; /*fisrt line*/
820 for (h = 0; h < height/2; h++ )
821 {
822 line2 = framebuffer + width * 2; /* next line */
823 Y1 = Y0 + width;
824 U = Y1 + width;
825 V = U + width/2;
826 for (w = width / 2; --w >= 0; )
827 {
828 *framebuffer++ = 0x80 + *Y0++;
829 *framebuffer++ = 0x80 + *U;
830 *framebuffer++ = 0x80 + *Y0++;
831 *framebuffer++ = 0x80 + *V;
832
833 *line2++ = 0x80 + *Y1++;
834 *line2++ = 0x80 + *U++;
835 *line2++ = 0x80 + *Y1++;
836 *line2++ = 0x80 + *V++;
837 }
838 Y0 += width * 2; /* next block of lines */
839 framebuffer = line2;
840 }
841}
842
843/*convert SPCA508 (s508) to yuv 422
844* s508 |Y0..width..Y0|U..width/2..U|V..width/2..V|Y1..width..Y1|
845* signed values (-128;+127) must be converted to unsigned (0; 255)
846* args:
847* framebuffer: pointer to frame buffer (yuyv)
848* tmpbuffer: pointer to temp buffer containing s501 data frame
849* width: picture width
850* height: picture height
851*/
852void s508_to_yuyv(BYTE *framebuffer, BYTE *tmpbuffer, int width, int height)
853{
854 BYTE *U, *V, *Y0, *Y1;
855 BYTE *line2;
856 int h, w;
857
858 Y0 = tmpbuffer; /*fisrt line*/
859 for (h = 0; h < height/2; h++ )
860 {
861 line2 = framebuffer + width * 2; /* next line */
862 U = Y0 + width;
863 V = U + width/2;
864 Y1= V + width/2;
865 for (w = width / 2; --w >= 0; )
866 {
867 *framebuffer++ = 0x80 + *Y0++;
868 *framebuffer++ = 0x80 + *U;
869 *framebuffer++ = 0x80 + *Y0++;
870 *framebuffer++ = 0x80 + *V;
871
872 *line2++ = 0x80 + *Y1++;
873 *line2++ = 0x80 + *U++;
874 *line2++ = 0x80 + *Y1++;
875 *line2++ = 0x80 + *V++;
876 }
877 Y0 += width * 2; /* next block of lines */
878 framebuffer = line2;
879 }
880}
881
882// raw bayer functions
883// from libv4l bayer.c, (C) 2008 Hans de Goede <j.w.r.degoede@hhs.nl>
884//Note: original bayer_to_bgr24 code from :
885// 1394-Based Digital Camera Control Library
886//
887// Bayer pattern decoding functions
888//
889// Written by Damien Douxchamps and Frederic Devernay
890static void convert_border_bayer_line_to_bgr24( BYTE* bayer, BYTE* adjacent_bayer,
891 BYTE *bgr, int width, bool start_with_green, bool blue_line)
892{
893 int t0, t1;
894
895 if (start_with_green)
896 {
897 /* First pixel */
898 if (blue_line)
899 {
900 *bgr++ = bayer[1];
901 *bgr++ = bayer[0];
902 *bgr++ = adjacent_bayer[0];
903 }
904 else
905 {
906 *bgr++ = adjacent_bayer[0];
907 *bgr++ = bayer[0];
908 *bgr++ = bayer[1];
909 }
910 /* Second pixel */
911 t0 = (bayer[0] + bayer[2] + adjacent_bayer[1] + 1) / 3;
912 t1 = (adjacent_bayer[0] + adjacent_bayer[2] + 1) >> 1;
913 if (blue_line)
914 {
915 *bgr++ = bayer[1];
916 *bgr++ = t0;
917 *bgr++ = t1;
918 }
919 else
920 {
921 *bgr++ = t1;
922 *bgr++ = t0;
923 *bgr++ = bayer[1];
924 }
925 bayer++;
926 adjacent_bayer++;
927 width -= 2;
928 }
929 else
930 {
931 /* First pixel */
932 t0 = (bayer[1] + adjacent_bayer[0] + 1) >> 1;
933 if (blue_line)
934 {
935 *bgr++ = bayer[0];
936 *bgr++ = t0;
937 *bgr++ = adjacent_bayer[1];
938 }
939 else
940 {
941 *bgr++ = adjacent_bayer[1];
942 *bgr++ = t0;
943 *bgr++ = bayer[0];
944 }
945 width--;
946 }
947
948 if (blue_line)
949 {
950 for ( ; width > 2; width -= 2)
951 {
952 t0 = (bayer[0] + bayer[2] + 1) >> 1;
953 *bgr++ = t0;
954 *bgr++ = bayer[1];
955 *bgr++ = adjacent_bayer[1];
956 bayer++;
957 adjacent_bayer++;
958
959 t0 = (bayer[0] + bayer[2] + adjacent_bayer[1] + 1) / 3;
960 t1 = (adjacent_bayer[0] + adjacent_bayer[2] + 1) >> 1;
961 *bgr++ = bayer[1];
962 *bgr++ = t0;
963 *bgr++ = t1;
964 bayer++;
965 adjacent_bayer++;
966 }
967 }
968 else
969 {
970 for ( ; width > 2; width -= 2)
971 {
972 t0 = (bayer[0] + bayer[2] + 1) >> 1;
973 *bgr++ = adjacent_bayer[1];
974 *bgr++ = bayer[1];
975 *bgr++ = t0;
976 bayer++;
977 adjacent_bayer++;
978
979 t0 = (bayer[0] + bayer[2] + adjacent_bayer[1] + 1) / 3;
980 t1 = (adjacent_bayer[0] + adjacent_bayer[2] + 1) >> 1;
981 *bgr++ = t1;
982 *bgr++ = t0;
983 *bgr++ = bayer[1];
984 bayer++;
985 adjacent_bayer++;
986 }
987 }
988
989 if (width == 2)
990 {
991 /* Second to last pixel */
992 t0 = (bayer[0] + bayer[2] + 1) >> 1;
993 if (blue_line)
994 {
995 *bgr++ = t0;
996 *bgr++ = bayer[1];
997 *bgr++ = adjacent_bayer[1];
998 }
999 else
1000 {
1001 *bgr++ = adjacent_bayer[1];
1002 *bgr++ = bayer[1];
1003 *bgr++ = t0;
1004 }
1005 /* Last pixel */
1006 t0 = (bayer[1] + adjacent_bayer[2] + 1) >> 1;
1007 if (blue_line)
1008 {
1009 *bgr++ = bayer[2];
1010 *bgr++ = t0;
1011 *bgr++ = adjacent_bayer[1];
1012 }
1013 else
1014 {
1015 *bgr++ = adjacent_bayer[1];
1016 *bgr++ = t0;
1017 *bgr++ = bayer[2];
1018 }
1019 }
1020 else
1021 {
1022 /* Last pixel */
1023 if (blue_line)
1024 {
1025 *bgr++ = bayer[0];
1026 *bgr++ = bayer[1];
1027 *bgr++ = adjacent_bayer[1];
1028 }
1029 else
1030 {
1031 *bgr++ = adjacent_bayer[1];
1032 *bgr++ = bayer[1];
1033 *bgr++ = bayer[0];
1034 }
1035 }
1036}
1037
1038/* From libdc1394, which on turn was based on OpenCV's Bayer decoding */
1039static void bayer_to_rgbbgr24(BYTE *bayer,
1040 BYTE *bgr, int width, int height,
1041 bool start_with_green, bool blue_line)
1042{
1043 /* render the first line */
1044 convert_border_bayer_line_to_bgr24(bayer, bayer + width, bgr, width,
1045 start_with_green, blue_line);
1046 bgr += width * 3;
1047
1048 /* reduce height by 2 because of the special case top/bottom line */
1049 for (height -= 2; height; height--)
1050 {
1051 int t0, t1;
1052 /* (width - 2) because of the border */
1053 BYTE *bayerEnd = bayer + (width - 2);
1054
1055 if (start_with_green)
1056 {
1057 /* OpenCV has a bug in the next line, which was
1058 t0 = (bayer[0] + bayer[width * 2] + 1) >> 1; */
1059 t0 = (bayer[1] + bayer[width * 2 + 1] + 1) >> 1;
1060 /* Write first pixel */
1061 t1 = (bayer[0] + bayer[width * 2] + bayer[width + 1] + 1) / 3;
1062 if (blue_line)
1063 {
1064 *bgr++ = t0;
1065 *bgr++ = t1;
1066 *bgr++ = bayer[width];
1067 }
1068 else
1069 {
1070 *bgr++ = bayer[width];
1071 *bgr++ = t1;
1072 *bgr++ = t0;
1073 }
1074
1075 /* Write second pixel */
1076 t1 = (bayer[width] + bayer[width + 2] + 1) >> 1;
1077 if (blue_line)
1078 {
1079 *bgr++ = t0;
1080 *bgr++ = bayer[width + 1];
1081 *bgr++ = t1;
1082 }
1083 else
1084 {
1085 *bgr++ = t1;
1086 *bgr++ = bayer[width + 1];
1087 *bgr++ = t0;
1088 }
1089 bayer++;
1090 }
1091 else
1092 {
1093 /* Write first pixel */
1094 t0 = (bayer[0] + bayer[width * 2] + 1) >> 1;
1095 if (blue_line)
1096 {
1097 *bgr++ = t0;
1098 *bgr++ = bayer[width];
1099 *bgr++ = bayer[width + 1];
1100 }
1101 else
1102 {
1103 *bgr++ = bayer[width + 1];
1104 *bgr++ = bayer[width];
1105 *bgr++ = t0;
1106 }
1107 }
1108
1109 if (blue_line)
1110 {
1111 for (; bayer <= bayerEnd - 2; bayer += 2)
1112 {
1113 t0 = (bayer[0] + bayer[2] + bayer[width * 2] +
1114 bayer[width * 2 + 2] + 2) >> 2;
1115 t1 = (bayer[1] + bayer[width] +
1116 bayer[width + 2] + bayer[width * 2 + 1] +
1117 2) >> 2;
1118 *bgr++ = t0;
1119 *bgr++ = t1;
1120 *bgr++ = bayer[width + 1];
1121
1122 t0 = (bayer[2] + bayer[width * 2 + 2] + 1) >> 1;
1123 t1 = (bayer[width + 1] + bayer[width + 3] +
1124 1) >> 1;
1125 *bgr++ = t0;
1126 *bgr++ = bayer[width + 2];
1127 *bgr++ = t1;
1128 }
1129 }
1130 else
1131 {
1132 for (; bayer <= bayerEnd - 2; bayer += 2)
1133 {
1134 t0 = (bayer[0] + bayer[2] + bayer[width * 2] +
1135 bayer[width * 2 + 2] + 2) >> 2;
1136 t1 = (bayer[1] + bayer[width] +
1137 bayer[width + 2] + bayer[width * 2 + 1] +
1138 2) >> 2;
1139 *bgr++ = bayer[width + 1];
1140 *bgr++ = t1;
1141 *bgr++ = t0;
1142
1143 t0 = (bayer[2] + bayer[width * 2 + 2] + 1) >> 1;
1144 t1 = (bayer[width + 1] + bayer[width + 3] +
1145 1) >> 1;
1146 *bgr++ = t1;
1147 *bgr++ = bayer[width + 2];
1148 *bgr++ = t0;
1149 }
1150 }
1151
1152 if (bayer < bayerEnd)
1153 {
1154 /* write second to last pixel */
1155 t0 = (bayer[0] + bayer[2] + bayer[width * 2] +
1156 bayer[width * 2 + 2] + 2) >> 2;
1157 t1 = (bayer[1] + bayer[width] +
1158 bayer[width + 2] + bayer[width * 2 + 1] +
1159 2) >> 2;
1160 if (blue_line)
1161 {
1162 *bgr++ = t0;
1163 *bgr++ = t1;
1164 *bgr++ = bayer[width + 1];
1165 }
1166 else
1167 {
1168 *bgr++ = bayer[width + 1];
1169 *bgr++ = t1;
1170 *bgr++ = t0;
1171 }
1172 /* write last pixel */
1173 t0 = (bayer[2] + bayer[width * 2 + 2] + 1) >> 1;
1174 if (blue_line)
1175 {
1176 *bgr++ = t0;
1177 *bgr++ = bayer[width + 2];
1178 *bgr++ = bayer[width + 1];
1179 }
1180 else
1181 {
1182 *bgr++ = bayer[width + 1];
1183 *bgr++ = bayer[width + 2];
1184 *bgr++ = t0;
1185 }
1186 bayer++;
1187 }
1188 else
1189 {
1190 /* write last pixel */
1191 t0 = (bayer[0] + bayer[width * 2] + 1) >> 1;
1192 t1 = (bayer[1] + bayer[width * 2 + 1] + bayer[width] + 1) / 3;
1193 if (blue_line)
1194 {
1195 *bgr++ = t0;
1196 *bgr++ = t1;
1197 *bgr++ = bayer[width + 1];
1198 }
1199 else
1200 {
1201 *bgr++ = bayer[width + 1];
1202 *bgr++ = t1;
1203 *bgr++ = t0;
1204 }
1205 }
1206
1207 /* skip 2 border pixels */
1208 bayer += 2;
1209
1210 blue_line = !blue_line;
1211 start_with_green = !start_with_green;
1212 }
1213
1214 /* render the last line */
1215 convert_border_bayer_line_to_bgr24(bayer + width, bayer, bgr, width,
1216 !start_with_green, !blue_line);
1217}
1218
1219/*convert bayer raw data to rgb24
1220* args:
1221* pBay: pointer to buffer containing Raw bayer data data
1222* pRGB24: pointer to buffer containing rgb24 data
1223* width: picture width
1224* height: picture height
1225* pix_order: bayer pixel order (0=gb/rg 1=gr/bg 2=bg/gr 3=rg/bg)
1226*/
1227void
1228bayer_to_rgb24(BYTE *pBay, BYTE *pRGB24, int width, int height, int pix_order)
1229{
1230 switch (pix_order)
1231 {
1232 //conversion functions are build for bgr, by switching b and r lines we get rgb
1233 case 0: /* gbgbgb... | rgrgrg... (V4L2_PIX_FMT_SGBRG8)*/
1234 bayer_to_rgbbgr24(pBay, pRGB24, width, height, TRUE, FALSE);
1235 break;
1236
1237 case 1: /* grgrgr... | bgbgbg... (V4L2_PIX_FMT_SGRBG8)*/
1238 bayer_to_rgbbgr24(pBay, pRGB24, width, height, TRUE, TRUE);
1239 break;
1240
1241 case 2: /* bgbgbg... | grgrgr... (V4L2_PIX_FMT_SBGGR8)*/
1242 bayer_to_rgbbgr24(pBay, pRGB24, width, height, FALSE, FALSE);
1243 break;
1244
1245 case 3: /* rgrgrg... ! gbgbgb... (V4L2_PIX_FMT_SRGGB8)*/
1246 bayer_to_rgbbgr24(pBay, pRGB24, width, height, FALSE, TRUE);
1247 break;
1248
1249 default: /* default is 0*/
1250 bayer_to_rgbbgr24(pBay, pRGB24, width, height, TRUE, FALSE);
1251 break;
1252 }
1253}
1254
1255
1256void
1257rgb2yuyv(BYTE *prgb, BYTE *pyuv, int width, int height)
1258{
1259
1260 int i=0;
1261 for(i=0;i<(width*height*3);i=i+6)
1262 {
1263 /* y */
1264 *pyuv++ =CLIP(0.299 * (prgb[i] - 128) + 0.587 * (prgb[i+1] - 128) + 0.114 * (prgb[i+2] - 128) + 128);
1265 /* u */
1266 *pyuv++ =CLIP(((- 0.147 * (prgb[i] - 128) - 0.289 * (prgb[i+1] - 128) + 0.436 * (prgb[i+2] - 128) + 128) +
1267 (- 0.147 * (prgb[i+3] - 128) - 0.289 * (prgb[i+4] - 128) + 0.436 * (prgb[i+5] - 128) + 128))/2);
1268 /* y1 */
1269 *pyuv++ =CLIP(0.299 * (prgb[i+3] - 128) + 0.587 * (prgb[i+4] - 128) + 0.114 * (prgb[i+5] - 128) + 128);
1270 /* v*/
1271 *pyuv++ =CLIP(((0.615 * (prgb[i] - 128) - 0.515 * (prgb[i+1] - 128) - 0.100 * (prgb[i+2] - 128) + 128) +
1272 (0.615 * (prgb[i+3] - 128) - 0.515 * (prgb[i+4] - 128) - 0.100 * (prgb[i+5] - 128) + 128))/2);
1273 }
1274}
1275
1276void
1277bgr2yuyv(BYTE *pbgr, BYTE *pyuv, int width, int height)
1278{
1279
1280 int i=0;
1281 for(i=0;i<(width*height*3);i=i+6)
1282 {
1283 /* y */
1284 *pyuv++ =CLIP(0.299 * (pbgr[i+2] - 128) + 0.587 * (pbgr[i+1] - 128) + 0.114 * (pbgr[i] - 128) + 128);
1285 /* u */
1286 *pyuv++ =CLIP(((- 0.147 * (pbgr[i+2] - 128) - 0.289 * (pbgr[i+1] - 128) + 0.436 * (pbgr[i] - 128) + 128) +
1287 (- 0.147 * (pbgr[i+5] - 128) - 0.289 * (pbgr[i+4] - 128) + 0.436 * (pbgr[i+3] - 128) + 128))/2);
1288 /* y1 */
1289 *pyuv++ =CLIP(0.299 * (pbgr[i+5] - 128) + 0.587 * (pbgr[i+4] - 128) + 0.114 * (pbgr[i+3] - 128) + 128);
1290 /* v*/
1291 *pyuv++ =CLIP(((0.615 * (pbgr[i+2] - 128) - 0.515 * (pbgr[i+1] - 128) - 0.100 * (pbgr[i] - 128) + 128) +
1292 (0.615 * (pbgr[i+5] - 128) - 0.515 * (pbgr[i+4] - 128) - 0.100 * (pbgr[i+3] - 128) + 128))/2);
1293 }
1294}
1295
1296/*use in utils.c for jpeg decoding 420 planar to 422
1297* args:
1298* out: pointer to data output of idct (macroblocks yyyy u v)
1299* pic: pointer to picture buffer (yuyv)
1300* width: picture width
1301*/
1302void yuv420pto422(int * out,unsigned char *pic,int width)
1303{
1304 int j, k;
1305 unsigned char *pic0, *pic1;
1306 int *outy, *outu, *outv;
1307 int outy1 = 0;
1308 int outy2 = 8;
1309
1310 //yyyyuv
1311 pic0 = pic;
1312 pic1 = pic + width;
1313 outy = out;
1314 outu = out + 64 * 4;
1315 outv = out + 64 * 5;
1316 for (j = 0; j < 8; j++)
1317 {
1318 for (k = 0; k < 8; k++)
1319 {
1320 if( k == 4)
1321 {
1322 outy1 += 56;
1323 outy2 += 56;
1324 }
1325 *pic0++ = CLIP(outy[outy1]); //y1 line 1
1326 *pic0++ = CLIP(128 + *outu); //u line 1-2
1327 *pic0++ = CLIP(outy[outy1+1]); //y2 line 1
1328 *pic0++ = CLIP(128 + *outv); //v line 1-2
1329 *pic1++ = CLIP(outy[outy2]); //y1 line 2
1330 *pic1++ = CLIP(128 + *outu); //u line 1-2
1331 *pic1++ = CLIP(outy[outy2+1]); //y2 line 2
1332 *pic1++ = CLIP(128 + *outv); //v line 1-2
1333 outy1 +=2; outy2 += 2; outu++; outv++;
1334 }
1335 if(j==3)
1336 {
1337 outy = out + 128;
1338 }
1339 else
1340 {
1341 outy += 16;
1342 }
1343 outy1 = 0;
1344 outy2 = 8;
1345 pic0 += 2 * (width -16);
1346 pic1 += 2 * (width -16);
1347 }
1348}
1349
1350/*use in utils.c for jpeg decoding 422 planar to 422
1351* args:
1352* out: pointer to data output of idct (macroblocks yyyy u v)
1353* pic: pointer to picture buffer (yuyv)
1354* width: picture width
1355*/
1356void yuv422pto422(int * out,unsigned char *pic,int width)
1357{
1358 int j, k;
1359 unsigned char *pic0, *pic1;
1360 int *outy, *outu, *outv;
1361 int outy1 = 0;
1362 int outy2 = 8;
1363 int outu1 = 0;
1364 int outv1 = 0;
1365
1366 //yyyyuv
1367 pic0 = pic;
1368 pic1 = pic + width;
1369 outy = out;
1370 outu = out + 64 * 4;
1371 outv = out + 64 * 5;
1372 for (j = 0; j < 4; j++)
1373 {
1374 for (k = 0; k < 8; k++)
1375 {
1376 if( k == 4)
1377 {
1378 outy1 += 56;
1379 outy2 += 56;
1380 }
1381 *pic0++ = CLIP(outy[outy1]); //y1 line 1
1382 *pic0++ = CLIP(128 + outu[outu1]); //u line 1
1383 *pic0++ = CLIP(outy[outy1+1]); //y2 line 1
1384 *pic0++ = CLIP(128 + outv[outv1]); //v line 1
1385 *pic1++ = CLIP(outy[outy2]); //y1 line 2
1386 *pic1++ = CLIP(128 + outu[outu1+8]);//u line 2
1387 *pic1++ = CLIP(outy[outy2+1]); //y2 line 2
1388 *pic1++ = CLIP(128 + outv[outv1+8]);//v line 2
1389 outv1 += 1; outu1 += 1;
1390 outy1 +=2; outy2 +=2;
1391 }
1392 outy += 16;outu +=8; outv +=8;
1393 outv1 = 0; outu1=0;
1394 outy1 = 0;
1395 outy2 = 8;
1396 pic0 += 2 * (width -16);
1397 pic1 += 2 * (width -16);
1398 }
1399}
1400
1401void yuv420pto420sp(int * out, addr *pic, int width)
1402{
1403 int j, k;
1404 unsigned char *pic0, *pic1, *uv;
1405 int *outy, *outu, *outv;
1406 int *outy1 ;
1407 int *outy2 ;
1408 int *outu1 ;
1409 int *outv1 ;
1410
1411 pic0 = pic->y;
1412 pic1 = pic->y + width;
1413 uv = pic->v;
1414 outy = out;
1415 outu = out + 64 * 4;
1416 outv = out + 64 * 5;
1417
1418 for (j = 0; j < 8; j++)
1419 {
1420 outy1 = outy;
1421 outy2 = outy+8;
1422 outv1 = outv;
1423 outu1 = outu;
1424
1425 {
1426 asm volatile(
1427 "mov r0,#0 \n\t"
1428 "vdup.u32 d30, r0 \n\t"
1429 "mov r0,#255 \n\t"
1430 "vdup.u32 d31, r0 \n\t"
1431
1432 /*** line1 ***/
1433 "mov r0, #256 @256=64*4\n\t"
1434 "vld4.32 {d26,d27,d28,d29}, [%[outy1]], r0 \n\t"
1435 "vmax.s32 d26, d26, d30 \n\t"
1436 "vmin.s32 d26, d26, d31 \n\t"
1437 "vmax.s32 d27, d27, d30 \n\t"
1438 "vmin.s32 d27, d27, d31 \n\t"
1439 "vmax.s32 d28, d28, d30 \n\t"
1440 "vmin.s32 d28, d28, d31 \n\t"
1441 "vmax.s32 d29, d29, d30 \n\t"
1442 "vmin.s32 d29, d29, d31 \n\t"
1443 "vst4.8 {d26[0],d27[0],d28[0],d29[0]}, [%[pic0]]! \n\t"
1444 "vst4.8 {d26[4],d27[4],d28[4],d29[4]}, [%[pic0]]! \n\t"
1445
1446 /*** mb 2 ***/
1447 "vld4.32 {d26,d27,d28,d29}, [%[outy1]] \n\t"
1448 "vmax.s32 d26, d26, d30 \n\t"
1449 "vmin.s32 d26, d26, d31 \n\t"
1450 "vmax.s32 d27, d27, d30 \n\t"
1451 "vmin.s32 d27, d27, d31 \n\t"
1452 "vmax.s32 d28, d28, d30 \n\t"
1453 "vmin.s32 d28, d28, d31 \n\t"
1454 "vmax.s32 d29, d29, d30 \n\t"
1455 "vmin.s32 d29, d29, d31 \n\t"
1456 "vst4.8 {d26[0],d27[0],d28[0],d29[0]}, [%[pic0]]! \n\t"
1457 "vst4.8 {d26[4],d27[4],d28[4],d29[4]}, [%[pic0]]! \n\t"
1458
1459 /*** line2 ***/
1460 "vld4.32 {d26,d27,d28,d29}, [%[outy2]],r0 \n\t"
1461 "vmax.s32 d26, d26, d30 \n\t"
1462 "vmin.s32 d26, d26, d31 \n\t"
1463 "vmax.s32 d27, d27, d30 \n\t"
1464 "vmin.s32 d27, d27, d31 \n\t"
1465 "vmax.s32 d28, d28, d30 \n\t"
1466 "vmin.s32 d28, d28, d31 \n\t"
1467 "vmax.s32 d29, d29, d30 \n\t"
1468 "vmin.s32 d29, d29, d31 \n\t"
1469 "vst4.8 {d26[0],d27[0],d28[0],d29[0]}, [%[pic1]]! \n\t"
1470 "vst4.8 {d26[4],d27[4],d28[4],d29[4]}, [%[pic1]]! \n\t"
1471
1472 /*** mb2 ***/
1473 "vld4.32 {d26,d27,d28,d29}, [%[outy2]] \n\t"
1474 "vmax.s32 d26, d26, d30 \n\t"
1475 "vmin.s32 d26, d26, d31 \n\t"
1476 "vmax.s32 d27, d27, d30 \n\t"
1477 "vmin.s32 d27, d27, d31 \n\t"
1478 "vmax.s32 d28, d28, d30 \n\t"
1479 "vmin.s32 d28, d28, d31 \n\t"
1480 "vmax.s32 d29, d29, d30 \n\t"
1481 "vmin.s32 d29, d29, d31 \n\t"
1482 "vst4.8 {d26[0],d27[0],d28[0],d29[0]}, [%[pic1]]! \n\t"
1483 "vst4.8 {d26[4],d27[4],d28[4],d29[4]}, [%[pic1]]! \n\t"
1484
1485 /*** uv ***/
1486 "mov r0, #16 @16=4*4 \n\t"
1487 "vld4.32 {d22,d24,d26,d28}, [%[outv1]], r0 \n\t"
1488 "vld4.32 {d23,d25,d27,d29}, [%[outu1]], r0 \n\t"
1489
1490 "mov r0, #128 \n\t"
1491 "vdup.u32 d30, r0 \n\t"
1492 "vqadd.s32 d22, d22, d30 \n\t"
1493 "vqadd.s32 d23, d23, d30 \n\t"
1494 "vqadd.s32 d24, d24, d30 \n\t"
1495 "vqadd.s32 d25, d25, d30 \n\t"
1496 "vqadd.s32 d26, d26, d30 \n\t"
1497 "vqadd.s32 d27, d27, d30 \n\t"
1498 "vqadd.s32 d28, d28, d30 \n\t"
1499 "vqadd.s32 d29, d29, d30 \n\t"
1500
1501 "mov r0, #0 \n\t"
1502 "vdup.u32 d30, r0 \n\t"
1503
1504 "vmax.s32 d22, d22, d30 \n\t"
1505 "vmin.s32 d22, d22, d31 \n\t"
1506 "vmax.s32 d24, d24, d30 \n\t"
1507 "vmin.s32 d24, d24, d31 \n\t"
1508 "vmax.s32 d26, d26, d30 \n\t"
1509 "vmin.s32 d26, d26, d31 \n\t"
1510 "vmax.s32 d28, d28, d30 \n\t"
1511 "vmin.s32 d28, d28, d31 \n\t"
1512
1513 "vmax.s32 d23, d23, d30 \n\t"
1514 "vmin.s32 d23, d23, d31 \n\t"
1515 "vmax.s32 d25, d25, d30 \n\t"
1516 "vmin.s32 d25, d25, d31 \n\t"
1517 "vmax.s32 d27, d27, d30 \n\t"
1518 "vmin.s32 d27, d27, d31 \n\t"
1519 "vmax.s32 d29, d29, d30 \n\t"
1520 "vmin.s32 d29, d29, d31 \n\t"
1521
1522 "vst4.8 {d22[0],d23[0],d24[0],d25[0]}, [%[uv]]! \n\t"
1523 "vst4.8 {d26[0],d27[0],d28[0],d29[0]}, [%[uv]]! \n\t"
1524 "vst4.8 {d22[4],d23[4],d24[4],d25[4]}, [%[uv]]! \n\t"
1525 "vst4.8 {d26[4],d27[4],d28[4],d29[4]}, [%[uv]]! \n\t"
1526 //////////////////////////////
1527
1528 "4:@end \n\t"
1529 : [outy1] "+r" (outy1), [outy2] "+r" (outy2),
1530 [pic0] "+r" (pic0), [pic1] "+r" (pic1),
1531 [outu1] "+r" (outu1), [outv1] "+r" (outv1),
1532 [uv] "+r" (uv)
1533 : [width] "r" (width)
1534 : "cc", "memory", "r0","q11", "q12", "q13","q14","q15"
1535 );
1536 }
1537 if(j == 3)
1538 outy += 80;
1539 else
1540 outy += 16;
1541 outu +=8; outv +=8;
1542 pic0 += 2 * (width - 8);
1543 pic1 += 2 * (width - 8);
1544 uv += width - 16;
1545 }
1546}
1547
1548void yuv420pto420p(int * out, addr *pic, int width)
1549{
1550 int j, k;
1551 unsigned char *pic0, *pic1, *u, *v;
1552 int *outy, *outu, *outv;
1553 int *outy1 ;
1554 int *outy2 ;
1555 int *outu1 ;
1556 int *outv1 ;
1557
1558 pic0 = pic->y;
1559 pic1 = pic->y + width;
1560 v = pic->v;
1561 u = pic->u;
1562 outy = out;
1563 outu = out + 64 * 4;
1564 outv = out + 64 * 5;
1565
1566 for (j = 0; j < 8; j++)
1567 {
1568 outy1 = outy;
1569 outy2 = outy+8;
1570 outv1 = outv;
1571 outu1 = outu;
1572
1573 {
1574 asm volatile(
1575 "mov r0,#0 \n\t"
1576 "vdup.u32 d30, r0 \n\t"
1577 "mov r0,#255 \n\t"
1578 "vdup.u32 d31, r0 \n\t"
1579
1580 /*** line1 ***/
1581 "mov r0, #256 @256=64*4\n\t"
1582 "vld4.32 {d26,d27,d28,d29}, [%[outy1]], r0 \n\t"
1583 "vmax.s32 d26, d26, d30 \n\t"
1584 "vmin.s32 d26, d26, d31 \n\t"
1585 "vmax.s32 d27, d27, d30 \n\t"
1586 "vmin.s32 d27, d27, d31 \n\t"
1587 "vmax.s32 d28, d28, d30 \n\t"
1588 "vmin.s32 d28, d28, d31 \n\t"
1589 "vmax.s32 d29, d29, d30 \n\t"
1590 "vmin.s32 d29, d29, d31 \n\t"
1591 "vst4.8 {d26[0],d27[0],d28[0],d29[0]}, [%[pic0]]! \n\t"
1592 "vst4.8 {d26[4],d27[4],d28[4],d29[4]}, [%[pic0]]! \n\t"
1593
1594 /*** mb 2 ***/
1595 "vld4.32 {d26,d27,d28,d29}, [%[outy1]] \n\t"
1596 "vmax.s32 d26, d26, d30 \n\t"
1597 "vmin.s32 d26, d26, d31 \n\t"
1598 "vmax.s32 d27, d27, d30 \n\t"
1599 "vmin.s32 d27, d27, d31 \n\t"
1600 "vmax.s32 d28, d28, d30 \n\t"
1601 "vmin.s32 d28, d28, d31 \n\t"
1602 "vmax.s32 d29, d29, d30 \n\t"
1603 "vmin.s32 d29, d29, d31 \n\t"
1604 "vst4.8 {d26[0],d27[0],d28[0],d29[0]}, [%[pic0]]! \n\t"
1605 "vst4.8 {d26[4],d27[4],d28[4],d29[4]}, [%[pic0]]! \n\t"
1606
1607 /*** line2 ***/
1608 "vld4.32 {d26,d27,d28,d29}, [%[outy2]],r0 \n\t"
1609 "vmax.s32 d26, d26, d30 \n\t"
1610 "vmin.s32 d26, d26, d31 \n\t"
1611 "vmax.s32 d27, d27, d30 \n\t"
1612 "vmin.s32 d27, d27, d31 \n\t"
1613 "vmax.s32 d28, d28, d30 \n\t"
1614 "vmin.s32 d28, d28, d31 \n\t"
1615 "vmax.s32 d29, d29, d30 \n\t"
1616 "vmin.s32 d29, d29, d31 \n\t"
1617 "vst4.8 {d26[0],d27[0],d28[0],d29[0]}, [%[pic1]]! \n\t"
1618 "vst4.8 {d26[4],d27[4],d28[4],d29[4]}, [%[pic1]]! \n\t"
1619
1620 /*** mb2 ***/
1621 "vld4.32 {d26,d27,d28,d29}, [%[outy2]] \n\t"
1622 "vmax.s32 d26, d26, d30 \n\t"
1623 "vmin.s32 d26, d26, d31 \n\t"
1624 "vmax.s32 d27, d27, d30 \n\t"
1625 "vmin.s32 d27, d27, d31 \n\t"
1626 "vmax.s32 d28, d28, d30 \n\t"
1627 "vmin.s32 d28, d28, d31 \n\t"
1628 "vmax.s32 d29, d29, d30 \n\t"
1629 "vmin.s32 d29, d29, d31 \n\t"
1630 "vst4.8 {d26[0],d27[0],d28[0],d29[0]}, [%[pic1]]! \n\t"
1631 "vst4.8 {d26[4],d27[4],d28[4],d29[4]}, [%[pic1]]! \n\t"
1632
1633 /*** uv ***/
1634 "mov r0, #16 @16=4*4 \n\t"
1635 "vld4.32 {d22,d23,d24,d25}, [%[outv1]], r0 \n\t"
1636 "vld4.32 {d26,d27,d28,d29}, [%[outu1]], r0 \n\t"
1637
1638 "mov r0, #128 \n\t"
1639 "vdup.u32 d30, r0 \n\t"
1640 "vqadd.s32 d22, d22, d30 \n\t"
1641 "vqadd.s32 d23, d23, d30 \n\t"
1642 "vqadd.s32 d24, d24, d30 \n\t"
1643 "vqadd.s32 d25, d25, d30 \n\t"
1644 "vqadd.s32 d26, d26, d30 \n\t"
1645 "vqadd.s32 d27, d27, d30 \n\t"
1646 "vqadd.s32 d28, d28, d30 \n\t"
1647 "vqadd.s32 d29, d29, d30 \n\t"
1648
1649 "mov r0, #0 \n\t"
1650 "vdup.u32 d30, r0 \n\t"
1651
1652 "vmax.s32 d22, d22, d30 \n\t"
1653 "vmin.s32 d22, d22, d31 \n\t"
1654 "vmax.s32 d23, d23, d30 \n\t"
1655 "vmin.s32 d23, d23, d31 \n\t"
1656 "vmax.s32 d24, d24, d30 \n\t"
1657 "vmin.s32 d24, d24, d31 \n\t"
1658 "vmax.s32 d25, d25, d30 \n\t"
1659 "vmin.s32 d25, d25, d31 \n\t"
1660
1661 "vmax.s32 d26, d26, d30 \n\t"
1662 "vmin.s32 d26, d26, d31 \n\t"
1663 "vmax.s32 d27, d27, d30 \n\t"
1664 "vmin.s32 d27, d27, d31 \n\t"
1665 "vmax.s32 d28, d28, d30 \n\t"
1666 "vmin.s32 d28, d28, d31 \n\t"
1667 "vmax.s32 d29, d29, d30 \n\t"
1668 "vmin.s32 d29, d29, d31 \n\t"
1669
1670 "vst4.8 {d22[0],d23[0],d24[0],d25[0]}, [%[v]]! \n\t"
1671 "vst4.8 {d22[4],d23[4],d24[4],d25[4]}, [%[v]]! \n\t"
1672 "vst4.8 {d26[0],d27[0],d28[0],d29[0]}, [%[u]]! \n\t"
1673 "vst4.8 {d26[4],d27[4],d28[4],d29[4]}, [%[u]]! \n\t"
1674 //////////////////////////////
1675
1676 "4:@end \n\t"
1677 : [outy1] "+r" (outy1), [outy2] "+r" (outy2),
1678 [pic0] "+r" (pic0), [pic1] "+r" (pic1),
1679 [outu1] "+r" (outu1), [outv1] "+r" (outv1),
1680 [u] "+r" (u), [v] "+r" (v)
1681 : [width] "r" (width)
1682 : "cc", "memory", "r0","q11","q12","q13","q14","q15"
1683 );
1684 }
1685 if(j == 3)
1686 outy += 80;
1687 else
1688 outy += 16;
1689 outu += 8; outv += 8;
1690 pic0 += 2 * (width - 8);
1691 pic1 += 2 * (width - 8);
1692 u += width / 2 - 8;
1693 v += width / 2 - 8;
1694 }
1695}
1696
1697void yuv422pto420sp(int * out, addr *pic, int width)
1698{
1699 int j, k;
1700 unsigned char *pic0, *pic1,*uv;
1701 int *outy, *outu, *outv;
1702 int *outy1 ;
1703 int *outy2 ;
1704 int *outu1 ;
1705 int *outv1 ;
1706
1707 //yyyyuv
1708 pic0 = pic->y;
1709 pic1 = pic->y + width;
1710 uv = pic->v;
1711 outy = out;
1712 outu = out + 64 * 4;
1713 outv = out + 64 * 5;
1714
1715 for (j = 0; j < 4; j++)
1716 {
1717 outy1 = outy;
1718 outy2 = outy+8;
1719 outv1 = outv;
1720 outu1 = outu;
1721
1722 for (k = 0; k < 2; k++)
1723 {
1724 asm volatile(
1725 "mov r0,#0 \n\t"
1726 "vdup.u32 d30, r0 \n\t"
1727 "mov r0,#255 \n\t"
1728 "vdup.u32 d31, r0 \n\t"
1729
1730 /////////////////////////////line1
1731 "mov r0, #256 @256=64*4\n\t"
1732 "vld4.32 {d26,d27,d28,d29}, [%[outy1]], r0 \n\t"
1733 "vmax.s32 d26, d26, d30 \n\t"
1734 "vmin.s32 d26, d26, d31 \n\t"
1735 "vmax.s32 d27, d27, d30 \n\t"
1736 "vmin.s32 d27, d27, d31 \n\t"
1737 "vmax.s32 d28, d28, d30 \n\t"
1738 "vmin.s32 d28, d28, d31 \n\t"
1739 "vmax.s32 d29, d29, d30 \n\t"
1740 "vmin.s32 d29, d29, d31 \n\t"
1741 "vst4.8 {d26[0],d27[0],d28[0],d29[0]}, [%[pic0]]! \n\t"
1742 "vst4.8 {d26[4],d27[4],d28[4],d29[4]}, [%[pic0]]! \n\t"
1743
1744 /////////////////////////////line2
1745 "vld4.32 {d26,d27,d28,d29}, [%[outy2]],r0 \n\t"
1746 "vmax.s32 d26, d26, d30 \n\t"
1747 "vmin.s32 d26, d26, d31 \n\t"
1748 "vmax.s32 d27, d27, d30 \n\t"
1749 "vmin.s32 d27, d27, d31 \n\t"
1750 "vmax.s32 d28, d28, d30 \n\t"
1751 "vmin.s32 d28, d28, d31 \n\t"
1752 "vmax.s32 d29, d29, d30 \n\t"
1753 "vmin.s32 d29, d29, d31 \n\t"
1754 "vst4.8 {d26[0],d27[0],d28[0],d29[0]}, [%[pic1]]! \n\t"
1755 "vst4.8 {d26[4],d27[4],d28[4],d29[4]}, [%[pic1]]! \n\t"
1756
1757 //////////////////////////////uv
1758 "mov r0, #16 @16=4*4 \n\t"
1759 "vld4.32 {d22,d24,d26,d28}, [%[outv1]], r0 \n\t"
1760 "vld4.32 {d23,d25,d27,d29}, [%[outu1]], r0 \n\t"
1761
1762 "mov r0, #128 \n\t"
1763 "vdup.u32 d30, r0 \n\t"
1764 "vqadd.s32 d22, d22, d30 \n\t"
1765 "vqadd.s32 d23, d23, d30 \n\t"
1766 "vqadd.s32 d24, d24, d30 \n\t"
1767 "vqadd.s32 d25, d25, d30 \n\t"
1768 "vqadd.s32 d26, d26, d30 \n\t"
1769 "vqadd.s32 d27, d27, d30 \n\t"
1770 "vqadd.s32 d28, d28, d30 \n\t"
1771 "vqadd.s32 d29, d29, d30 \n\t"
1772
1773 "mov r0, #0 \n\t"
1774 "vdup.u32 d30, r0 \n\t"
1775
1776 "vmax.s32 d22, d22, d30 \n\t"
1777 "vmin.s32 d22, d22, d31 \n\t"
1778 "vmax.s32 d24, d24, d30 \n\t"
1779 "vmin.s32 d24, d24, d31 \n\t"
1780 "vmax.s32 d26, d26, d30 \n\t"
1781 "vmin.s32 d26, d26, d31 \n\t"
1782 "vmax.s32 d28, d28, d30 \n\t"
1783 "vmin.s32 d28, d28, d31 \n\t"
1784
1785 "vmax.s32 d23, d23, d30 \n\t"
1786 "vmin.s32 d23, d23, d31 \n\t"
1787 "vmax.s32 d25, d25, d30 \n\t"
1788 "vmin.s32 d25, d25, d31 \n\t"
1789 "vmax.s32 d27, d27, d30 \n\t"
1790 "vmin.s32 d27, d27, d31 \n\t"
1791 "vmax.s32 d29, d29, d30 \n\t"
1792 "vmin.s32 d29, d29, d31 \n\t"
1793
1794 "vst4.8 {d22[0],d23[0],d24[0],d25[0]}, [%[uv]]! \n\t"
1795 "vst4.8 {d26[0],d27[0],d28[0],d29[0]}, [%[uv]]! \n\t"
1796 //////////////////////////////
1797
1798 "4:@end \n\t"
1799 : [outy1] "+r" (outy1), [outy2] "+r" (outy2),
1800 [pic0] "+r" (pic0), [pic1] "+r" (pic1),
1801 [outu1] "+r" (outu1), [outv1] "+r" (outv1),
1802 [uv] "+r" (uv)
1803 : [width] "r" (width)
1804 : "cc", "memory", "r0","q11","q12","q13","q14","q15"
1805 );
1806 }
1807 outy += 16;outu +=8; outv +=8;
1808 pic0 += 2 * (width - 8);
1809 pic1 += 2 * (width - 8);
1810 uv += width - 16;
1811 }
1812}
1813
1814void yuv422pto420p(int * out, addr *pic, int width)
1815{
1816 int j, k;
1817 unsigned char *pic0, *pic1,*v,*u;
1818 int *outy, *outu, *outv;
1819 int *outy1 ;
1820 int *outy2 ;
1821 int *outu1 ;
1822 int *outv1 ;
1823
1824 //yyyyuv
1825 pic0 = pic->y;
1826 pic1 = pic->y + width;
1827 v = pic->v;
1828 u = pic->u;
1829 outy = out;
1830 outu = out + 64 * 4;
1831 outv = out + 64 * 5;
1832 for (j = 0; j < 4; j++)
1833 {
1834 outy1 = outy;
1835 outy2 = outy+8;
1836 outv1 = outv;
1837 outu1 = outu;
1838
1839 for (k = 0; k < 2; k++)
1840 {
1841 asm volatile(
1842 "mov r0,#0 \n\t"
1843 "vdup.u32 d30, r0 \n\t"
1844 "mov r0,#255 \n\t"
1845 "vdup.u32 d31, r0 \n\t"
1846
1847 /////////////////////////////line1
1848 "mov r0, #256 @256=64*4\n\t"
1849 "vld4.32 {d26,d27,d28,d29}, [%[outy1]], r0 \n\t"
1850 "vmax.s32 d26, d26, d30 \n\t"
1851 "vmin.s32 d26, d26, d31 \n\t"
1852 "vmax.s32 d27, d27, d30 \n\t"
1853 "vmin.s32 d27, d27, d31 \n\t"
1854 "vmax.s32 d28, d28, d30 \n\t"
1855 "vmin.s32 d28, d28, d31 \n\t"
1856 "vmax.s32 d29, d29, d30 \n\t"
1857 "vmin.s32 d29, d29, d31 \n\t"
1858 "vst4.8 {d26[0],d27[0],d28[0],d29[0]}, [%[pic0]]! \n\t"
1859 "vst4.8 {d26[4],d27[4],d28[4],d29[4]}, [%[pic0]]! \n\t"
1860
1861 /////////////////////////////line2
1862 "vld4.32 {d26,d27,d28,d29}, [%[outy2]],r0 \n\t"
1863 "vmax.s32 d26, d26, d30 \n\t"
1864 "vmin.s32 d26, d26, d31 \n\t"
1865 "vmax.s32 d27, d27, d30 \n\t"
1866 "vmin.s32 d27, d27, d31 \n\t"
1867 "vmax.s32 d28, d28, d30 \n\t"
1868 "vmin.s32 d28, d28, d31 \n\t"
1869 "vmax.s32 d29, d29, d30 \n\t"
1870 "vmin.s32 d29, d29, d31 \n\t"
1871 "vst4.8 {d26[0],d27[0],d28[0],d29[0]}, [%[pic1]]! \n\t"
1872 "vst4.8 {d26[4],d27[4],d28[4],d29[4]}, [%[pic1]]! \n\t"
1873
1874 //////////////////////////////uv
1875 "mov r0, #16 @16=4*4 \n\t"
1876 "vld4.32 {d22,d23,d24,d25}, [%[outv1]], r0 \n\t"
1877 "vld4.32 {d26,d27,d28,d29}, [%[outu1]], r0 \n\t"
1878
1879 "mov r0, #128 \n\t"
1880 "vdup.u32 d30, r0 \n\t"
1881 "vqadd.s32 d22, d22, d30 \n\t"
1882 "vqadd.s32 d23, d23, d30 \n\t"
1883 "vqadd.s32 d24, d24, d30 \n\t"
1884 "vqadd.s32 d25, d25, d30 \n\t"
1885 "vqadd.s32 d26, d26, d30 \n\t"
1886 "vqadd.s32 d27, d27, d30 \n\t"
1887 "vqadd.s32 d28, d28, d30 \n\t"
1888 "vqadd.s32 d29, d29, d30 \n\t"
1889
1890 "mov r0, #0 \n\t"
1891 "vdup.u32 d30, r0 \n\t"
1892
1893 "vmax.s32 d22, d22, d30 \n\t"
1894 "vmin.s32 d22, d22, d31 \n\t"
1895 "vmax.s32 d24, d24, d30 \n\t"
1896 "vmin.s32 d24, d24, d31 \n\t"
1897 "vmax.s32 d26, d26, d30 \n\t"
1898 "vmin.s32 d26, d26, d31 \n\t"
1899 "vmax.s32 d28, d28, d30 \n\t"
1900 "vmin.s32 d28, d28, d31 \n\t"
1901
1902 "vmax.s32 d23, d23, d30 \n\t"
1903 "vmin.s32 d23, d23, d31 \n\t"
1904 "vmax.s32 d25, d25, d30 \n\t"
1905 "vmin.s32 d25, d25, d31 \n\t"
1906 "vmax.s32 d27, d27, d30 \n\t"
1907 "vmin.s32 d27, d27, d31 \n\t"
1908 "vmax.s32 d29, d29, d30 \n\t"
1909 "vmin.s32 d29, d29, d31 \n\t"
1910
1911 "vst4.8 {d22[0],d23[0],d24[0],d25[0]}, [%[v]]! \n\t"
1912 "vst4.8 {d26[0],d27[0],d28[0],d29[0]}, [%[u]]! \n\t"
1913 //////////////////////////////
1914 "4:@end \n\t"
1915 : [outy1] "+r" (outy1), [outy2] "+r" (outy2),
1916 [pic0] "+r" (pic0), [pic1] "+r" (pic1),
1917 [outu1] "+r" (outu1), [outv1] "+r" (outv1),
1918 [v] "+r" (v),[u] "+r" (u)
1919 : [width] "r" (width)
1920 : "cc", "memory", "r0","q11", "q12", "q13","q14","q15"
1921 );
1922 }
1923 outy += 16;outu +=8; outv +=8;
1924 pic0 += 2 * (width - 8);
1925 pic1 += 2 * (width - 8);
1926 v += width/2 - 8;
1927 u += width/2 - 8;
1928 }
1929}
1930
1931/*use in utils.c for jpeg decoding 444 planar to 422
1932* args:
1933* out: pointer to data output of idct (macroblocks yyyy u v)
1934* pic: pointer to picture buffer (yuyv)
1935* width: picture width
1936*/
1937void yuv444pto422(int * out,unsigned char *pic,int width)
1938{
1939 int j, k;
1940 unsigned char *pic0, *pic1;
1941 int *outy, *outu, *outv;
1942 int outy1 = 0;
1943 int outy2 = 8;
1944 int outu1 = 0;
1945 int outv1 = 0;
1946
1947 //yyyyuv
1948 pic0 = pic;
1949 pic1 = pic + width;
1950 outy = out;
1951 outu = out + 64 * 4; // Ooops where did i invert ??
1952 outv = out + 64 * 5;
1953 for (j = 0; j < 4; j++)
1954 {
1955 for (k = 0; k < 4; k++)
1956 {
1957 *pic0++ =CLIP( outy[outy1]); //y1 line 1
1958 *pic0++ =CLIP( 128 + outu[outu1]); //u line 1
1959 *pic0++ =CLIP( outy[outy1+1]); //y2 line 1
1960 *pic0++ =CLIP( 128 + outv[outv1]); //v line 1
1961 *pic1++ =CLIP( outy[outy2]); //y1 line 2
1962 *pic1++ =CLIP( 128 + outu[outu1+8]);//u line 2
1963 *pic1++ =CLIP( outy[outy2+1]); //y2 line 2
1964 *pic1++ =CLIP( 128 + outv[outv1+8]);//v line 2
1965 outv1 += 2; outu1 += 2;
1966 outy1 +=2; outy2 +=2;
1967 }
1968 outy += 16;outu +=16; outv +=16;
1969 outv1 = 0; outu1=0;
1970 outy1 = 0;
1971 outy2 = 8;
1972 pic0 += 2 * (width -8);
1973 pic1 += 2 * (width -8);
1974 }
1975}
1976
1977/*use in utils.c for jpeg decoding 400 planar to 422
1978* args:
1979* out: pointer to data output of idct (macroblocks yyyy )
1980* pic: pointer to picture buffer (yuyv)
1981* width: picture width
1982*/
1983void yuv400pto422(int * out,unsigned char *pic,int width)
1984{
1985 int j, k;
1986 unsigned char *pic0, *pic1;
1987 int *outy ;
1988 int outy1 = 0;
1989 int outy2 = 8;
1990 pic0 = pic;
1991 pic1 = pic + width;
1992 outy = out;
1993
1994 //yyyy
1995 for (j = 0; j < 4; j++)
1996 {
1997 for (k = 0; k < 4; k++)
1998 {
1999 *pic0++ = CLIP(outy[outy1]); //y1 line 1
2000 *pic0++ = 128 ; //u
2001 *pic0++ = CLIP(outy[outy1+1]);//y2 line 1
2002 *pic0++ = 128 ; //v
2003 *pic1++ = CLIP(outy[outy2]); //y1 line 2
2004 *pic1++ = 128 ; //u
2005 *pic1++ = CLIP(outy[outy2+1]);//y2 line 2
2006 *pic1++ = 128 ; //v
2007 outy1 +=2; outy2 +=2;
2008 }
2009 outy += 16;
2010 outy1 = 0;
2011 outy2 = 8;
2012 pic0 += 2 * (width -8);
2013 pic1 += 2 * (width -8);
2014 }
2015}
2016
2017