comparison postproc/swscale.c @ 6578:3727eb94a783

use unified yuv2rgb init {RGB,BGR}{1,4,8,15,16,24,32} output supported
author michael
date Thu, 27 Jun 2002 18:00:47 +0000
parents 5aa2dbf4d300
children 5059143aa020
comparison
equal deleted inserted replaced
6577:aad616b63bed 6578:3727eb94a783
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */ 17 */
18 18
19 /* 19 /*
20 supported Input formats: YV12, I420/IYUV, YUY2, BGR32, BGR24, BGR16, BGR15, RGB32, RGB24, Y8/Y800, YVU9/IF09 20 supported Input formats: YV12, I420/IYUV, YUY2, BGR32, BGR24, BGR16, BGR15, RGB32, RGB24, Y8/Y800, YVU9/IF09
21 supported output formats: YV12, I420/IYUV, BGR15, BGR16, BGR24, BGR32, Y8/Y800, YVU9/IF09 21 supported output formats: YV12, I420/IYUV, {BGR,RGB}{1,4,8,15,16,24,32}, Y8/Y800, YVU9/IF09
22 BGR15/16 support dithering 22 BGR15/16 support dithering
23 23
24 unscaled special converters 24 unscaled special converters
25 YV12/I420/IYUV -> BGR15/BGR16/BGR24/BGR32 25 YV12/I420/IYUV -> BGR15/BGR16/BGR24/BGR32
26 YV12/I420/IYUV -> YV12/I420/IYUV 26 YV12/I420/IYUV -> YV12/I420/IYUV
101 101
102 //FIXME replace this with something faster 102 //FIXME replace this with something faster
103 #define isPlanarYUV(x) ((x)==IMGFMT_YV12 || (x)==IMGFMT_I420 || (x)==IMGFMT_YVU9) 103 #define isPlanarYUV(x) ((x)==IMGFMT_YV12 || (x)==IMGFMT_I420 || (x)==IMGFMT_YVU9)
104 #define isYUV(x) ((x)==IMGFMT_YUY2 || isPlanarYUV(x)) 104 #define isYUV(x) ((x)==IMGFMT_YUY2 || isPlanarYUV(x))
105 #define isGray(x) ((x)==IMGFMT_Y800) 105 #define isGray(x) ((x)==IMGFMT_Y800)
106 #define isRGB(x) (((x)&IMGFMT_RGB_MASK)==IMGFMT_RGB)
107 #define isBGR(x) (((x)&IMGFMT_BGR_MASK)==IMGFMT_BGR)
106 #define isSupportedIn(x) ((x)==IMGFMT_YV12 || (x)==IMGFMT_I420 || (x)==IMGFMT_YUY2 \ 108 #define isSupportedIn(x) ((x)==IMGFMT_YV12 || (x)==IMGFMT_I420 || (x)==IMGFMT_YUY2 \
107 || (x)==IMGFMT_BGR32|| (x)==IMGFMT_BGR24|| (x)==IMGFMT_BGR16|| (x)==IMGFMT_BGR15\ 109 || (x)==IMGFMT_BGR32|| (x)==IMGFMT_BGR24|| (x)==IMGFMT_BGR16|| (x)==IMGFMT_BGR15\
108 || (x)==IMGFMT_RGB32|| (x)==IMGFMT_RGB24\ 110 || (x)==IMGFMT_RGB32|| (x)==IMGFMT_RGB24\
109 || (x)==IMGFMT_Y800 || (x)==IMGFMT_YVU9) 111 || (x)==IMGFMT_Y800 || (x)==IMGFMT_YVU9)
110 #define isSupportedOut(x) ((x)==IMGFMT_YV12 || (x)==IMGFMT_I420 \ 112 #define isSupportedOut(x) ((x)==IMGFMT_YV12 || (x)==IMGFMT_I420 \
111 || (x)==IMGFMT_BGR32|| (x)==IMGFMT_BGR24|| (x)==IMGFMT_BGR16|| (x)==IMGFMT_BGR15\ 113 || isRGB(x) || isBGR(x)\
112 || (x)==IMGFMT_Y800 || (x)==IMGFMT_YVU9) 114 || (x)==IMGFMT_Y800 || (x)==IMGFMT_YVU9)
113 #define isRGB(x) (((x)&IMGFMT_RGB_MASK)==IMGFMT_RGB)
114 #define isBGR(x) (((x)&IMGFMT_BGR_MASK)==IMGFMT_BGR)
115 #define isPacked(x) ((x)==IMGFMT_YUY2 || isRGB(x) || isBGR(x)) 115 #define isPacked(x) ((x)==IMGFMT_YUY2 || isRGB(x) || isBGR(x))
116 116
117 #define RGB2YUV_SHIFT 16 117 #define RGB2YUV_SHIFT 16
118 #define BY ((int)( 0.098*(1<<RGB2YUV_SHIFT)+0.5)) 118 #define BY ((int)( 0.098*(1<<RGB2YUV_SHIFT)+0.5))
119 #define BV ((int)(-0.071*(1<<RGB2YUV_SHIFT)+0.5)) 119 #define BV ((int)(-0.071*(1<<RGB2YUV_SHIFT)+0.5))
206 #endif 206 #endif
207 207
208 // clipping helper table for C implementations: 208 // clipping helper table for C implementations:
209 static unsigned char clip_table[768]; 209 static unsigned char clip_table[768];
210 210
211 static unsigned short clip_table16b[768];
212 static unsigned short clip_table16g[768];
213 static unsigned short clip_table16r[768];
214 static unsigned short clip_table15b[768];
215 static unsigned short clip_table15g[768];
216 static unsigned short clip_table15r[768];
217
218 // yuv->rgb conversion tables:
219 static int yuvtab_2568[256];
220 static int yuvtab_3343[256];
221 static int yuvtab_0c92[256];
222 static int yuvtab_1a1e[256];
223 static int yuvtab_40cf[256];
224 // Needed for cubic scaler to catch overflows
225 static int clip_yuvtab_2568[768];
226 static int clip_yuvtab_3343[768];
227 static int clip_yuvtab_0c92[768];
228 static int clip_yuvtab_1a1e[768];
229 static int clip_yuvtab_40cf[768];
230
231 //global sws_flags from the command line 211 //global sws_flags from the command line
232 int sws_flags=2; 212 int sws_flags=2;
233 213
234 //global srcFilter 214 //global srcFilter
235 SwsFilter src_filter= {NULL, NULL, NULL, NULL}; 215 SwsFilter src_filter= {NULL, NULL, NULL, NULL};
248 void (*swScale)(SwsContext *context, uint8_t* src[], int srcStride[], int srcSliceY, 228 void (*swScale)(SwsContext *context, uint8_t* src[], int srcStride[], int srcSliceY,
249 int srcSliceH, uint8_t* dst[], int dstStride[])=NULL; 229 int srcSliceH, uint8_t* dst[], int dstStride[])=NULL;
250 230
251 static SwsVector *getConvVec(SwsVector *a, SwsVector *b); 231 static SwsVector *getConvVec(SwsVector *a, SwsVector *b);
252 static inline void orderYUV(int format, uint8_t * sortedP[], int sortedStride[], uint8_t * p[], int stride[]); 232 static inline void orderYUV(int format, uint8_t * sortedP[], int sortedStride[], uint8_t * p[], int stride[]);
253 233 void *yuv2rgb_c_init (unsigned bpp, int mode, void *table_rV[256], void *table_gU[256], int table_gV[256], void *table_bU[256]);
234
235 extern const uint8_t dither_2x2_4[2][8];
236 extern const uint8_t dither_2x2_8[2][8];
237 extern const uint8_t dither_8x8_32[8][8];
238 extern const uint8_t dither_8x8_73[8][8];
239 extern const uint8_t dither_8x8_220[8][8];
254 240
255 #ifdef CAN_COMPILE_X86_ASM 241 #ifdef CAN_COMPILE_X86_ASM
256 void in_asm_used_var_warning_killer() 242 void in_asm_used_var_warning_killer()
257 { 243 {
258 volatile int i= yCoeff+vrCoeff+ubCoeff+vgCoeff+ugCoeff+bF8+bFC+w400+w80+w10+ 244 volatile int i= yCoeff+vrCoeff+ubCoeff+vgCoeff+ugCoeff+bF8+bFC+w400+w80+w10+
412 uDest[i]= MIN(MAX(u>>19, 0), 255); 398 uDest[i]= MIN(MAX(u>>19, 0), 255);
413 vDest[i]= MIN(MAX(v>>19, 0), 255); 399 vDest[i]= MIN(MAX(v>>19, 0), 255);
414 } 400 }
415 } 401 }
416 402
417 static inline void yuv2rgbXinC(int16_t *lumFilter, int16_t **lumSrc, int lumFilterSize, 403 #define YSCALE_YUV_2_RGBX_C(type) \
404 for(i=0; i<(dstW>>1); i++){\
405 int j;\
406 int Y1=0;\
407 int Y2=0;\
408 int U=0;\
409 int V=0;\
410 type *r, *b, *g;\
411 const int i2= 2*i;\
412 \
413 for(j=0; j<lumFilterSize; j++)\
414 {\
415 Y1 += lumSrc[j][i2] * lumFilter[j];\
416 Y2 += lumSrc[j][i2+1] * lumFilter[j];\
417 }\
418 for(j=0; j<chrFilterSize; j++)\
419 {\
420 U += chrSrc[j][i] * chrFilter[j];\
421 V += chrSrc[j][i+2048] * chrFilter[j];\
422 }\
423 Y1>>=19;\
424 Y2>>=19;\
425 U >>=19;\
426 V >>=19;\
427 if((Y1|Y2|U|V)&256)\
428 {\
429 if(Y1>255) Y1=255;\
430 else if(Y1<0)Y1=0;\
431 if(Y2>255) Y2=255;\
432 else if(Y2<0)Y2=0;\
433 if(U>255) U=255;\
434 else if(U<0) U=0;\
435 if(V>255) V=255;\
436 else if(V<0) V=0;\
437 }\
438 r = c->table_rV[V];\
439 g = c->table_gU[U] + c->table_gV[V];\
440 b = c->table_bU[U];\
441
442 #define YSCALE_YUV_2_RGB2_C(type) \
443 for(i=0; i<(dstW>>1); i++){\
444 const int i2= 2*i;\
445 int Y1= (buf0[i2 ]*yalpha1+buf1[i2 ]*yalpha)>>19;\
446 int Y2= (buf0[i2+1]*yalpha1+buf1[i2+1]*yalpha)>>19;\
447 int U= (uvbuf0[i ]*uvalpha1+uvbuf1[i ]*uvalpha)>>19;\
448 int V= (uvbuf0[i+2048]*uvalpha1+uvbuf1[i+2048]*uvalpha)>>19;\
449 type *r, *b, *g;\
450 r = c->table_rV[V];\
451 g = c->table_gU[U] + c->table_gV[V];\
452 b = c->table_bU[U];\
453
454 #define YSCALE_YUV_2_RGB1_C(type) \
455 for(i=0; i<(dstW>>1); i++){\
456 const int i2= 2*i;\
457 int Y1= buf0[i2 ]>>7;\
458 int Y2= buf0[i2+1]>>7;\
459 int U= (uvbuf1[i ])>>7;\
460 int V= (uvbuf1[i+2048])>>7;\
461 type *r, *b, *g;\
462 r = c->table_rV[V];\
463 g = c->table_gU[U] + c->table_gV[V];\
464 b = c->table_bU[U];\
465
466 #define YSCALE_YUV_2_RGB1B_C(type) \
467 for(i=0; i<(dstW>>1); i++){\
468 const int i2= 2*i;\
469 int Y1= buf0[i2 ]>>7;\
470 int Y2= buf0[i2+1]>>7;\
471 int U= (uvbuf0[i ] + uvbuf1[i ])>>8;\
472 int V= (uvbuf0[i+2048] + uvbuf1[i+2048])>>8;\
473 type *r, *b, *g;\
474 r = c->table_rV[V];\
475 g = c->table_gU[U] + c->table_gV[V];\
476 b = c->table_bU[U];\
477
478 #define YSCALE_YUV_2_ANYRGB_C(func)\
479 switch(c->dstFormat)\
480 {\
481 case IMGFMT_BGR32:\
482 case IMGFMT_RGB32:\
483 func(uint32_t)\
484 ((uint32_t*)dest)[i2+0]= r[Y1] + g[Y1] + b[Y1];\
485 ((uint32_t*)dest)[i2+1]= r[Y2] + g[Y2] + b[Y2];\
486 } \
487 break;\
488 case IMGFMT_RGB24:\
489 func(uint8_t)\
490 ((uint8_t*)dest)[0]= r[Y1];\
491 ((uint8_t*)dest)[1]= g[Y1];\
492 ((uint8_t*)dest)[2]= b[Y1];\
493 ((uint8_t*)dest)[3]= r[Y2];\
494 ((uint8_t*)dest)[4]= g[Y2];\
495 ((uint8_t*)dest)[5]= b[Y2];\
496 ((uint8_t*)dest)+=6;\
497 }\
498 break;\
499 case IMGFMT_BGR24:\
500 func(uint8_t)\
501 ((uint8_t*)dest)[0]= b[Y1];\
502 ((uint8_t*)dest)[1]= g[Y1];\
503 ((uint8_t*)dest)[2]= r[Y1];\
504 ((uint8_t*)dest)[3]= b[Y2];\
505 ((uint8_t*)dest)[4]= g[Y2];\
506 ((uint8_t*)dest)[5]= r[Y2];\
507 ((uint8_t*)dest)+=6;\
508 }\
509 break;\
510 case IMGFMT_RGB16:\
511 case IMGFMT_BGR16:\
512 {\
513 const int dr1= dither_2x2_8[y&1 ][0];\
514 const int dg1= dither_2x2_4[y&1 ][0];\
515 const int db1= dither_2x2_8[(y&1)^1][0];\
516 const int dr2= dither_2x2_8[y&1 ][1];\
517 const int dg2= dither_2x2_4[y&1 ][1];\
518 const int db2= dither_2x2_8[(y&1)^1][1];\
519 func(uint16_t)\
520 ((uint16_t*)dest)[i2+0]= r[Y1+dr1] + g[Y1+dg1] + b[Y1+db1];\
521 ((uint16_t*)dest)[i2+1]= r[Y2+dr2] + g[Y2+dg2] + b[Y2+db2];\
522 }\
523 }\
524 break;\
525 case IMGFMT_RGB15:\
526 case IMGFMT_BGR15:\
527 {\
528 const int dr1= dither_2x2_8[y&1 ][0];\
529 const int dg1= dither_2x2_8[y&1 ][1];\
530 const int db1= dither_2x2_8[(y&1)^1][0];\
531 const int dr2= dither_2x2_8[y&1 ][1];\
532 const int dg2= dither_2x2_8[y&1 ][0];\
533 const int db2= dither_2x2_8[(y&1)^1][1];\
534 func(uint16_t)\
535 ((uint16_t*)dest)[i2+0]= r[Y1+dr1] + g[Y1+dg1] + b[Y1+db1];\
536 ((uint16_t*)dest)[i2+1]= r[Y2+dr2] + g[Y2+dg2] + b[Y2+db2];\
537 }\
538 }\
539 break;\
540 case IMGFMT_RGB8:\
541 case IMGFMT_BGR8:\
542 {\
543 const uint8_t * const d64= dither_8x8_73[y&7];\
544 const uint8_t * const d32= dither_8x8_32[y&7];\
545 func(uint8_t)\
546 ((uint8_t*)dest)[i2+0]= r[Y1+d32[(i2+0)&7]] + g[Y1+d32[(i2+0)&7]] + b[Y1+d64[(i2+0)&7]];\
547 ((uint8_t*)dest)[i2+1]= r[Y2+d32[(i2+1)&7]] + g[Y2+d32[(i2+1)&7]] + b[Y2+d64[(i2+1)&7]];\
548 }\
549 }\
550 break;\
551 case IMGFMT_RGB4:\
552 case IMGFMT_BGR4:\
553 {\
554 const uint8_t * const d64= dither_8x8_73 [y&7];\
555 const uint8_t * const d128=dither_8x8_220[y&7];\
556 func(uint8_t)\
557 ((uint8_t*)dest)[i2+0]= r[Y1+d128[(i2+0)&7]] + g[Y1+d64[(i2+0)&7]] + b[Y1+d128[(i2+0)&7]];\
558 ((uint8_t*)dest)[i2+1]= r[Y2+d128[(i2+1)&7]] + g[Y2+d64[(i2+1)&7]] + b[Y2+d128[(i2+1)&7]];\
559 }\
560 }\
561 break;\
562 case IMGFMT_RGB1:\
563 case IMGFMT_BGR1:\
564 {\
565 const uint8_t * const d128=dither_8x8_220[y&7];\
566 uint8_t *g= c->table_gU[128] + c->table_gV[128];\
567 for(i=0; i<dstW-7; i+=8){\
568 int acc;\
569 acc = g[((buf0[i ]*yalpha1+buf1[i ]*yalpha)>>19) + d128[0]];\
570 acc+= acc + g[((buf0[i+1]*yalpha1+buf1[i+1]*yalpha)>>19) + d128[1]];\
571 acc+= acc + g[((buf0[i+2]*yalpha1+buf1[i+2]*yalpha)>>19) + d128[2]];\
572 acc+= acc + g[((buf0[i+3]*yalpha1+buf1[i+3]*yalpha)>>19) + d128[3]];\
573 acc+= acc + g[((buf0[i+4]*yalpha1+buf1[i+4]*yalpha)>>19) + d128[4]];\
574 acc+= acc + g[((buf0[i+5]*yalpha1+buf1[i+5]*yalpha)>>19) + d128[5]];\
575 acc+= acc + g[((buf0[i+6]*yalpha1+buf1[i+6]*yalpha)>>19) + d128[6]];\
576 acc+= acc + g[((buf0[i+7]*yalpha1+buf1[i+7]*yalpha)>>19) + d128[7]];\
577 ((uint8_t*)dest)[0]= acc;\
578 ((uint8_t*)dest)++;\
579 }\
580 \
581 /*\
582 ((uint8_t*)dest)-= dstW>>4;\
583 {\
584 int acc=0;\
585 int left=0;\
586 static int top[1024];\
587 static int last_new[1024][1024];\
588 static int last_in3[1024][1024];\
589 static int drift[1024][1024];\
590 int topLeft=0;\
591 int shift=0;\
592 int count=0;\
593 const uint8_t * const d128=dither_8x8_220[y&7];\
594 int error_new=0;\
595 int error_in3=0;\
596 int f=0;\
597 \
598 for(i=dstW>>1; i<dstW; i++){\
599 int in= ((buf0[i ]*yalpha1+buf1[i ]*yalpha)>>19);\
600 int in2 = (76309 * (in - 16) + 32768) >> 16;\
601 int in3 = (in2 < 0) ? 0 : ((in2 > 255) ? 255 : in2);\
602 int old= (left*7 + topLeft + top[i]*5 + top[i+1]*3)/20 + in3\
603 + (last_new[y][i] - in3)*f/256;\
604 int new= old> 128 ? 255 : 0;\
605 \
606 error_new+= ABS(last_new[y][i] - new);\
607 error_in3+= ABS(last_in3[y][i] - in3);\
608 f= error_new - error_in3*4;\
609 if(f<0) f=0;\
610 if(f>256) f=256;\
611 \
612 topLeft= top[i];\
613 left= top[i]= old - new;\
614 last_new[y][i]= new;\
615 last_in3[y][i]= in3;\
616 \
617 acc+= acc + (new&1);\
618 if((i&7)==6){\
619 ((uint8_t*)dest)[0]= acc;\
620 ((uint8_t*)dest)++;\
621 }\
622 }\
623 }\
624 */\
625 }\
626 break;\
627 }\
628
629
630 static inline void yuv2rgbXinC(SwsContext *c, int16_t *lumFilter, int16_t **lumSrc, int lumFilterSize,
418 int16_t *chrFilter, int16_t **chrSrc, int chrFilterSize, 631 int16_t *chrFilter, int16_t **chrSrc, int chrFilterSize,
419 uint8_t *dest, int dstW, int dstFormat) 632 uint8_t *dest, int dstW, int y)
420 { 633 {
421 if(dstFormat==IMGFMT_BGR32) 634 int i;
422 { 635 switch(c->dstFormat)
423 int i; 636 {
424 #ifdef WORDS_BIGENDIAN 637 case IMGFMT_RGB32:
425 dest++; 638 case IMGFMT_BGR32:
426 #endif 639 YSCALE_YUV_2_RGBX_C(uint32_t)
427 for(i=0; i<(dstW>>1); i++){ 640 ((uint32_t*)dest)[i2+0]= r[Y1] + g[Y1] + b[Y1];
428 int j; 641 ((uint32_t*)dest)[i2+1]= r[Y2] + g[Y2] + b[Y2];
429 int Y1=0; 642 }
430 int Y2=0; 643 break;
431 int U=0; 644 case IMGFMT_RGB24:
432 int V=0; 645 YSCALE_YUV_2_RGBX_C(uint8_t)
433 int Cb, Cr, Cg; 646 ((uint8_t*)dest)[0]= r[Y1];
434 for(j=0; j<lumFilterSize; j++) 647 ((uint8_t*)dest)[1]= g[Y1];
435 { 648 ((uint8_t*)dest)[2]= b[Y1];
436 Y1 += lumSrc[j][2*i] * lumFilter[j]; 649 ((uint8_t*)dest)[3]= r[Y2];
437 Y2 += lumSrc[j][2*i+1] * lumFilter[j]; 650 ((uint8_t*)dest)[4]= g[Y2];
651 ((uint8_t*)dest)[5]= b[Y2];
652 ((uint8_t*)dest)+=6;
653 }
654 break;
655 case IMGFMT_BGR24:
656 YSCALE_YUV_2_RGBX_C(uint8_t)
657 ((uint8_t*)dest)[0]= b[Y1];
658 ((uint8_t*)dest)[1]= g[Y1];
659 ((uint8_t*)dest)[2]= r[Y1];
660 ((uint8_t*)dest)[3]= b[Y2];
661 ((uint8_t*)dest)[4]= g[Y2];
662 ((uint8_t*)dest)[5]= r[Y2];
663 ((uint8_t*)dest)+=6;
664 }
665 break;
666 case IMGFMT_RGB16:
667 case IMGFMT_BGR16:
668 {
669 const int dr1= dither_2x2_8[y&1 ][0];
670 const int dg1= dither_2x2_4[y&1 ][0];
671 const int db1= dither_2x2_8[(y&1)^1][0];
672 const int dr2= dither_2x2_8[y&1 ][1];
673 const int dg2= dither_2x2_4[y&1 ][1];
674 const int db2= dither_2x2_8[(y&1)^1][1];
675 YSCALE_YUV_2_RGBX_C(uint16_t)
676 ((uint16_t*)dest)[i2+0]= r[Y1+dr1] + g[Y1+dg1] + b[Y1+db1];
677 ((uint16_t*)dest)[i2+1]= r[Y2+dr2] + g[Y2+dg2] + b[Y2+db2];
438 } 678 }
439 for(j=0; j<chrFilterSize; j++) 679 }
440 { 680 break;
441 U += chrSrc[j][i] * chrFilter[j]; 681 case IMGFMT_RGB15:
442 V += chrSrc[j][i+2048] * chrFilter[j]; 682 case IMGFMT_BGR15:
683 {
684 const int dr1= dither_2x2_8[y&1 ][0];
685 const int dg1= dither_2x2_8[y&1 ][1];
686 const int db1= dither_2x2_8[(y&1)^1][0];
687 const int dr2= dither_2x2_8[y&1 ][1];
688 const int dg2= dither_2x2_8[y&1 ][0];
689 const int db2= dither_2x2_8[(y&1)^1][1];
690 YSCALE_YUV_2_RGBX_C(uint16_t)
691 ((uint16_t*)dest)[i2+0]= r[Y1+dr1] + g[Y1+dg1] + b[Y1+db1];
692 ((uint16_t*)dest)[i2+1]= r[Y2+dr2] + g[Y2+dg2] + b[Y2+db2];
443 } 693 }
444 Y1= clip_yuvtab_2568[ (Y1>>19) + 256 ]; 694 }
445 Y2= clip_yuvtab_2568[ (Y2>>19) + 256 ]; 695 break;
446 U >>= 19; 696 case IMGFMT_RGB8:
447 V >>= 19; 697 case IMGFMT_BGR8:
448 698 {
449 Cb= clip_yuvtab_40cf[U+ 256]; 699 const uint8_t * const d64= dither_8x8_73[y&7];
450 Cg= clip_yuvtab_1a1e[V+ 256] + yuvtab_0c92[U+ 256]; 700 const uint8_t * const d32= dither_8x8_32[y&7];
451 Cr= clip_yuvtab_3343[V+ 256]; 701 YSCALE_YUV_2_RGBX_C(uint8_t)
452 702 ((uint8_t*)dest)[i2+0]= r[Y1+d32[(i2+0)&7]] + g[Y1+d32[(i2+0)&7]] + b[Y1+d64[(i2+0)&7]];
453 dest[8*i+0]=clip_table[((Y1 + Cb) >>13)]; 703 ((uint8_t*)dest)[i2+1]= r[Y2+d32[(i2+1)&7]] + g[Y2+d32[(i2+1)&7]] + b[Y2+d64[(i2+1)&7]];
454 dest[8*i+1]=clip_table[((Y1 + Cg) >>13)];
455 dest[8*i+2]=clip_table[((Y1 + Cr) >>13)];
456
457 dest[8*i+4]=clip_table[((Y2 + Cb) >>13)];
458 dest[8*i+5]=clip_table[((Y2 + Cg) >>13)];
459 dest[8*i+6]=clip_table[((Y2 + Cr) >>13)];
460 }
461 }
462 else if(dstFormat==IMGFMT_BGR24)
463 {
464 int i;
465 for(i=0; i<(dstW>>1); i++){
466 int j;
467 int Y1=0;
468 int Y2=0;
469 int U=0;
470 int V=0;
471 int Cb, Cr, Cg;
472 for(j=0; j<lumFilterSize; j++)
473 {
474 Y1 += lumSrc[j][2*i] * lumFilter[j];
475 Y2 += lumSrc[j][2*i+1] * lumFilter[j];
476 } 704 }
477 for(j=0; j<chrFilterSize; j++) 705 }
478 { 706 break;
479 U += chrSrc[j][i] * chrFilter[j]; 707 case IMGFMT_RGB4:
480 V += chrSrc[j][i+2048] * chrFilter[j]; 708 case IMGFMT_BGR4:
709 {
710 const uint8_t * const d64= dither_8x8_73 [y&7];
711 const uint8_t * const d128=dither_8x8_220[y&7];
712 YSCALE_YUV_2_RGBX_C(uint8_t)
713 ((uint8_t*)dest)[i2+0]= r[Y1+d128[(i2+0)&7]] + g[Y1+d64[(i2+0)&7]] + b[Y1+d128[(i2+0)&7]];
714 ((uint8_t*)dest)[i2+1]= r[Y2+d128[(i2+1)&7]] + g[Y2+d64[(i2+1)&7]] + b[Y2+d128[(i2+1)&7]];
481 } 715 }
482 Y1= clip_yuvtab_2568[ (Y1>>19) + 256 ]; 716 }
483 Y2= clip_yuvtab_2568[ (Y2>>19) + 256 ]; 717 break;
484 U >>= 19; 718 case IMGFMT_RGB1:
485 V >>= 19; 719 case IMGFMT_BGR1:
486 720 {
487 Cb= clip_yuvtab_40cf[U+ 256]; 721 const uint8_t * const d128=dither_8x8_220[y&7];
488 Cg= clip_yuvtab_1a1e[V+ 256] + yuvtab_0c92[U+ 256]; 722 uint8_t *g= c->table_gU[128] + c->table_gV[128];
489 Cr= clip_yuvtab_3343[V+ 256]; 723 int acc=0;
490 724 for(i=0; i<dstW-1; i+=2){
491 dest[0]=clip_table[((Y1 + Cb) >>13)]; 725 int j;
492 dest[1]=clip_table[((Y1 + Cg) >>13)]; 726 int Y1=0;
493 dest[2]=clip_table[((Y1 + Cr) >>13)]; 727 int Y2=0;
494 728
495 dest[3]=clip_table[((Y2 + Cb) >>13)]; 729 for(j=0; j<lumFilterSize; j++)
496 dest[4]=clip_table[((Y2 + Cg) >>13)]; 730 {
497 dest[5]=clip_table[((Y2 + Cr) >>13)]; 731 Y1 += lumSrc[j][i] * lumFilter[j];
498 dest+=6; 732 Y2 += lumSrc[j][i+1] * lumFilter[j];
499 } 733 }
500 } 734 Y1>>=19;
501 else if(dstFormat==IMGFMT_BGR16) 735 Y2>>=19;
502 { 736 if((Y1|Y2)&256)
503 int i; 737 {
504 #ifdef DITHER1XBPP 738 if(Y1>255) Y1=255;
505 static int ditherb1=1<<14; 739 else if(Y1<0)Y1=0;
506 static int ditherg1=1<<13; 740 if(Y2>255) Y2=255;
507 static int ditherr1=2<<14; 741 else if(Y2<0)Y2=0;
508 static int ditherb2=3<<14; 742 }
509 static int ditherg2=3<<13; 743 acc+= acc + g[Y1+d128[(i+0)&7]];
510 static int ditherr2=0<<14; 744 acc+= acc + g[Y2+d128[(i+1)&7]];
511 745 if((i&7)==6){
512 ditherb1 ^= (1^2)<<14; 746 ((uint8_t*)dest)[0]= acc;
513 ditherg1 ^= (1^2)<<13; 747 ((uint8_t*)dest)++;
514 ditherr1 ^= (1^2)<<14; 748 }
515 ditherb2 ^= (3^0)<<14;
516 ditherg2 ^= (3^0)<<13;
517 ditherr2 ^= (3^0)<<14;
518 #else
519 const int ditherb1=0;
520 const int ditherg1=0;
521 const int ditherr1=0;
522 const int ditherb2=0;
523 const int ditherg2=0;
524 const int ditherr2=0;
525 #endif
526 for(i=0; i<(dstW>>1); i++){
527 int j;
528 int Y1=0;
529 int Y2=0;
530 int U=0;
531 int V=0;
532 int Cb, Cr, Cg;
533 for(j=0; j<lumFilterSize; j++)
534 {
535 Y1 += lumSrc[j][2*i] * lumFilter[j];
536 Y2 += lumSrc[j][2*i+1] * lumFilter[j];
537 } 749 }
538 for(j=0; j<chrFilterSize; j++) 750 }
539 { 751 break;
540 U += chrSrc[j][i] * chrFilter[j];
541 V += chrSrc[j][i+2048] * chrFilter[j];
542 }
543 Y1= clip_yuvtab_2568[ (Y1>>19) + 256 ];
544 Y2= clip_yuvtab_2568[ (Y2>>19) + 256 ];
545 U >>= 19;
546 V >>= 19;
547
548 Cb= clip_yuvtab_40cf[U+ 256];
549 Cg= clip_yuvtab_1a1e[V+ 256] + yuvtab_0c92[U+ 256];
550 Cr= clip_yuvtab_3343[V+ 256];
551
552 ((uint16_t*)dest)[2*i] =
553 clip_table16b[(Y1 + Cb + ditherb1) >>13] |
554 clip_table16g[(Y1 + Cg + ditherg1) >>13] |
555 clip_table16r[(Y1 + Cr + ditherr1) >>13];
556
557 ((uint16_t*)dest)[2*i+1] =
558 clip_table16b[(Y2 + Cb + ditherb2) >>13] |
559 clip_table16g[(Y2 + Cg + ditherg2) >>13] |
560 clip_table16r[(Y2 + Cr + ditherr2) >>13];
561 }
562 }
563 else if(dstFormat==IMGFMT_BGR15)
564 {
565 int i;
566 #ifdef DITHER1XBPP
567 static int ditherb1=1<<14;
568 static int ditherg1=1<<14;
569 static int ditherr1=2<<14;
570 static int ditherb2=3<<14;
571 static int ditherg2=3<<14;
572 static int ditherr2=0<<14;
573
574 ditherb1 ^= (1^2)<<14;
575 ditherg1 ^= (1^2)<<14;
576 ditherr1 ^= (1^2)<<14;
577 ditherb2 ^= (3^0)<<14;
578 ditherg2 ^= (3^0)<<14;
579 ditherr2 ^= (3^0)<<14;
580 #else
581 const int ditherb1=0;
582 const int ditherg1=0;
583 const int ditherr1=0;
584 const int ditherb2=0;
585 const int ditherg2=0;
586 const int ditherr2=0;
587 #endif
588 for(i=0; i<(dstW>>1); i++){
589 int j;
590 int Y1=0;
591 int Y2=0;
592 int U=0;
593 int V=0;
594 int Cb, Cr, Cg;
595 for(j=0; j<lumFilterSize; j++)
596 {
597 Y1 += lumSrc[j][2*i] * lumFilter[j];
598 Y2 += lumSrc[j][2*i+1] * lumFilter[j];
599 }
600 for(j=0; j<chrFilterSize; j++)
601 {
602 U += chrSrc[j][i] * chrFilter[j];
603 V += chrSrc[j][i+2048] * chrFilter[j];
604 }
605 Y1= clip_yuvtab_2568[ (Y1>>19) + 256 ];
606 Y2= clip_yuvtab_2568[ (Y2>>19) + 256 ];
607 U >>= 19;
608 V >>= 19;
609
610 Cb= clip_yuvtab_40cf[U+ 256];
611 Cg= clip_yuvtab_1a1e[V+ 256] + yuvtab_0c92[U+ 256];
612 Cr= clip_yuvtab_3343[V+ 256];
613
614 ((uint16_t*)dest)[2*i] =
615 clip_table15b[(Y1 + Cb + ditherb1) >>13] |
616 clip_table15g[(Y1 + Cg + ditherg1) >>13] |
617 clip_table15r[(Y1 + Cr + ditherr1) >>13];
618
619 ((uint16_t*)dest)[2*i+1] =
620 clip_table15b[(Y2 + Cb + ditherb2) >>13] |
621 clip_table15g[(Y2 + Cg + ditherg2) >>13] |
622 clip_table15r[(Y2 + Cr + ditherr2) >>13];
623 }
624 } 752 }
625 } 753 }
626 754
627 755
628 //Note: we have C, X86, MMX, MMX2, 3DNOW version therse no 3DNOW+MMX2 one 756 //Note: we have C, X86, MMX, MMX2, 3DNOW version therse no 3DNOW+MMX2 one
1328 // generating tables: 1456 // generating tables:
1329 int i; 1457 int i;
1330 for(i=0; i<768; i++){ 1458 for(i=0; i<768; i++){
1331 int c= MIN(MAX(i-256, 0), 255); 1459 int c= MIN(MAX(i-256, 0), 255);
1332 clip_table[i]=c; 1460 clip_table[i]=c;
1333 yuvtab_2568[c]= clip_yuvtab_2568[i]=(0x2568*(c-16))+(256<<13);
1334 yuvtab_3343[c]= clip_yuvtab_3343[i]=0x3343*(c-128);
1335 yuvtab_0c92[c]= clip_yuvtab_0c92[i]=-0x0c92*(c-128);
1336 yuvtab_1a1e[c]= clip_yuvtab_1a1e[i]=-0x1a1e*(c-128);
1337 yuvtab_40cf[c]= clip_yuvtab_40cf[i]=0x40cf*(c-128);
1338 }
1339
1340 for(i=0; i<768; i++)
1341 {
1342 int v= clip_table[i];
1343 clip_table16b[i]= v>>3;
1344 clip_table16g[i]= (v<<3)&0x07E0;
1345 clip_table16r[i]= (v<<8)&0xF800;
1346 clip_table15b[i]= v>>3;
1347 clip_table15g[i]= (v<<2)&0x03E0;
1348 clip_table15r[i]= (v<<7)&0x7C00;
1349 } 1461 }
1350 1462
1351 cpuCaps= gCpuCaps; 1463 cpuCaps= gCpuCaps;
1352 1464
1353 #ifdef RUNTIME_CPUDETECT 1465 #ifdef RUNTIME_CPUDETECT
1885 // note the -((-x)>>y) is so that we allways round toward +inf 1997 // note the -((-x)>>y) is so that we allways round toward +inf
1886 c->chrSrcW= -((-srcW) >> c->chrSrcHSubSample); 1998 c->chrSrcW= -((-srcW) >> c->chrSrcHSubSample);
1887 c->chrSrcH= -((-srcH) >> c->chrSrcVSubSample); 1999 c->chrSrcH= -((-srcH) >> c->chrSrcVSubSample);
1888 c->chrDstW= -((-dstW) >> c->chrDstHSubSample); 2000 c->chrDstW= -((-dstW) >> c->chrDstHSubSample);
1889 c->chrDstH= -((-dstH) >> c->chrDstVSubSample); 2001 c->chrDstH= -((-dstH) >> c->chrDstVSubSample);
1890 /* printf("%d %d %d %d / %d %d %d %d //\n",
1891 c->chrSrcW,
1892 c->chrSrcH,
1893 c->chrDstW,
1894 c->chrDstH,
1895 srcW,
1896 srcH,
1897 dstW,
1898 dstH);*/
1899 2002
2003 if(isBGR(dstFormat))
2004 c->yuvTable= yuv2rgb_c_init(dstFormat & 0xFF, MODE_RGB, c->table_rV, c->table_gU, c->table_gV, c->table_bU);
2005 if(isRGB(dstFormat))
2006 c->yuvTable= yuv2rgb_c_init(dstFormat & 0xFF, MODE_BGR, c->table_rV, c->table_gU, c->table_gV, c->table_bU);
2007
1900 /* unscaled special Cases */ 2008 /* unscaled special Cases */
1901 if(unscaled && !usesFilter) 2009 if(unscaled && !usesFilter)
1902 { 2010 {
1903 /* yv12_to_nv12 */ 2011 /* yv12_to_nv12 */
1904 if((srcFormat == IMGFMT_YV12||srcFormat==IMGFMT_I420)&&dstFormat == IMGFMT_NV12) 2012 if((srcFormat == IMGFMT_YV12||srcFormat==IMGFMT_I420)&&dstFormat == IMGFMT_NV12)
1922 } 2030 }
1923 /* yuv2bgr */ 2031 /* yuv2bgr */
1924 if((srcFormat==IMGFMT_YV12 || srcFormat==IMGFMT_I420) && isBGR(dstFormat)) 2032 if((srcFormat==IMGFMT_YV12 || srcFormat==IMGFMT_I420) && isBGR(dstFormat))
1925 { 2033 {
1926 // FIXME multiple yuv2rgb converters wont work that way cuz that thing is full of globals&statics 2034 // FIXME multiple yuv2rgb converters wont work that way cuz that thing is full of globals&statics
2035 //FIXME rgb vs. bgr ?
1927 #ifdef WORDS_BIGENDIAN 2036 #ifdef WORDS_BIGENDIAN
1928 if(dstFormat==IMGFMT_BGR32) 2037 if(dstFormat==IMGFMT_BGR32)
1929 yuv2rgb_init( dstFormat&0xFF /* =bpp */, MODE_BGR); 2038 yuv2rgb_init( dstFormat&0xFF /* =bpp */, MODE_BGR);
1930 else 2039 else
1931 yuv2rgb_init( dstFormat&0xFF /* =bpp */, MODE_RGB); 2040 yuv2rgb_init( dstFormat&0xFF /* =bpp */, MODE_RGB);
2611 c->chrMmx2Filter=NULL; 2720 c->chrMmx2Filter=NULL;
2612 if(c->lumMmx2FilterPos) free(c->lumMmx2FilterPos); 2721 if(c->lumMmx2FilterPos) free(c->lumMmx2FilterPos);
2613 c->lumMmx2FilterPos=NULL; 2722 c->lumMmx2FilterPos=NULL;
2614 if(c->chrMmx2FilterPos) free(c->chrMmx2FilterPos); 2723 if(c->chrMmx2FilterPos) free(c->chrMmx2FilterPos);
2615 c->chrMmx2FilterPos=NULL; 2724 c->chrMmx2FilterPos=NULL;
2725 if(c->yuvTable) free(c->yuvTable);
2726 c->yuvTable=NULL;
2616 2727
2617 free(c); 2728 free(c);
2618 } 2729 }
2619 2730
2620 2731