Mercurial > mplayer.hg
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 |