diff options
Diffstat (limited to 'libswscale/swscale_template.c')
-rw-r--r-- | libswscale/swscale_template.c | 57 |
1 files changed, 51 insertions, 6 deletions
diff --git a/libswscale/swscale_template.c b/libswscale/swscale_template.c index 84daef5135..928bf97320 100644 --- a/libswscale/swscale_template.c +++ b/libswscale/swscale_template.c @@ -2279,6 +2279,38 @@ static inline void RENAME(rgb15ToUV)(uint8_t *dstU, uint8_t *dstV, uint8_t *src1 } } +static inline void RENAME(palToY)(uint8_t *dst, uint8_t *src, int width, uint32_t *pal) +{ + int i; + for(i=0; i<width; i++) + { + int d= src[i]; + int b= pal[d] &0xFF; + int g=(pal[d]>>8 )&0xFF; + int r= pal[d]>>16; + + dst[i]= ((RY*r + GY*g + BY*b)>>RGB2YUV_SHIFT) + 16; + } +} + +static inline void RENAME(palToUV)(uint8_t *dstU, uint8_t *dstV, uint8_t *src1, uint8_t *src2, int width, uint32_t *pal) +{ + int i; + assert(src1 == src2); + for(i=0; i<width; i++) + { + int d0= src1[2*i ]; + int d1= src1[2*i+1]; + int p = (pal[d0]&0xFF00FF) + (pal[d1]&0xFF00FF); + int g = (pal[d0]+pal[d1]-p)>>8; + int b= p&0x1FF; + int r= p>>16; + + dstU[i]= ((RU*r + GU*g + BU*b)>>(RGB2YUV_SHIFT+1)) + 128; + dstV[i]= ((RV*r + GV*g + BV*b)>>(RGB2YUV_SHIFT+1)) + 128; + } +} + // Bilinear / Bicubic scaling static inline void RENAME(hScale)(int16_t *dst, int dstW, uint8_t *src, int srcW, int xInc, int16_t *filter, int16_t *filterPos, long filterSize) @@ -2467,7 +2499,7 @@ static inline void RENAME(hyscale)(uint16_t *dst, long dstWidth, uint8_t *src, i int flags, int canMMX2BeUsed, int16_t *hLumFilter, int16_t *hLumFilterPos, int hLumFilterSize, void *funnyYCode, int srcFormat, uint8_t *formatConvBuffer, int16_t *mmx2Filter, - int32_t *mmx2FilterPos) + int32_t *mmx2FilterPos, uint8_t *pal) { if(srcFormat==PIX_FMT_YUYV422 || srcFormat==PIX_FMT_GRAY16BE) { @@ -2519,6 +2551,11 @@ static inline void RENAME(hyscale)(uint16_t *dst, long dstWidth, uint8_t *src, i RENAME(rgb15ToY)(formatConvBuffer, src, srcW); src= formatConvBuffer; } + else if(srcFormat==PIX_FMT_RGB8 || srcFormat==PIX_FMT_BGR8 || srcFormat==PIX_FMT_PAL8) + { + RENAME(palToY)(formatConvBuffer, src, srcW, pal); + src= formatConvBuffer; + } #ifdef HAVE_MMX // use the new MMX scaler if the mmx2 can't be used (its faster than the x86asm one) @@ -2664,7 +2701,7 @@ inline static void RENAME(hcscale)(uint16_t *dst, long dstWidth, uint8_t *src1, int srcW, int xInc, int flags, int canMMX2BeUsed, int16_t *hChrFilter, int16_t *hChrFilterPos, int hChrFilterSize, void *funnyUVCode, int srcFormat, uint8_t *formatConvBuffer, int16_t *mmx2Filter, - int32_t *mmx2FilterPos) + int32_t *mmx2FilterPos, uint8_t *pal) { if(srcFormat==PIX_FMT_YUYV422) { @@ -2730,6 +2767,12 @@ inline static void RENAME(hcscale)(uint16_t *dst, long dstWidth, uint8_t *src1, { return; } + else if(srcFormat==PIX_FMT_RGB8 || srcFormat==PIX_FMT_BGR8 || srcFormat==PIX_FMT_PAL8) + { + RENAME(palToUV)(formatConvBuffer, formatConvBuffer+2048, src1, src2, srcW, pal); + src1= formatConvBuffer; + src2= formatConvBuffer+2048; + } #ifdef HAVE_MMX // use the new MMX scaler if the mmx2 can't be used (its faster than the x86asm one) @@ -2932,6 +2975,7 @@ static int RENAME(swScale)(SwsContext *c, uint8_t* src[], int srcStride[], int s const int chrSrcSliceY= srcSliceY >> c->chrSrcVSubSample; const int chrSrcSliceH= -((-srcSliceH) >> c->chrSrcVSubSample); int lastDstY; + uint8_t *pal=NULL; /* vars whch will change and which we need to storw back in the context */ int dstY= c->dstY; @@ -2941,6 +2985,7 @@ static int RENAME(swScale)(SwsContext *c, uint8_t* src[], int srcStride[], int s int lastInChrBuf= c->lastInChrBuf; if(isPacked(c->srcFormat)){ + pal= src[1]; src[0]= src[1]= src[2]= src[0]; @@ -3026,7 +3071,7 @@ i--; RENAME(hyscale)(lumPixBuf[ lumBufIndex ], dstW, s, srcW, lumXInc, flags, canMMX2BeUsed, hLumFilter, hLumFilterPos, hLumFilterSize, funnyYCode, c->srcFormat, formatConvBuffer, - c->lumMmx2Filter, c->lumMmx2FilterPos); + c->lumMmx2Filter, c->lumMmx2FilterPos, pal); lastInLumBuf++; } while(lastInChrBuf < lastChrSrcY) @@ -3043,7 +3088,7 @@ i--; RENAME(hcscale)(chrPixBuf[ chrBufIndex ], chrDstW, src1, src2, chrSrcW, chrXInc, flags, canMMX2BeUsed, hChrFilter, hChrFilterPos, hChrFilterSize, funnyUVCode, c->srcFormat, formatConvBuffer, - c->chrMmx2Filter, c->chrMmx2FilterPos); + c->chrMmx2Filter, c->chrMmx2FilterPos, pal); lastInChrBuf++; } //wrap buf index around to stay inside the ring buffer @@ -3068,7 +3113,7 @@ i--; RENAME(hyscale)(lumPixBuf[ lumBufIndex ], dstW, s, srcW, lumXInc, flags, canMMX2BeUsed, hLumFilter, hLumFilterPos, hLumFilterSize, funnyYCode, c->srcFormat, formatConvBuffer, - c->lumMmx2Filter, c->lumMmx2FilterPos); + c->lumMmx2Filter, c->lumMmx2FilterPos, pal); lastInLumBuf++; } while(lastInChrBuf+1 < (chrSrcSliceY + chrSrcSliceH)) @@ -3084,7 +3129,7 @@ i--; RENAME(hcscale)(chrPixBuf[ chrBufIndex ], chrDstW, src1, src2, chrSrcW, chrXInc, flags, canMMX2BeUsed, hChrFilter, hChrFilterPos, hChrFilterSize, funnyUVCode, c->srcFormat, formatConvBuffer, - c->chrMmx2Filter, c->chrMmx2FilterPos); + c->chrMmx2Filter, c->chrMmx2FilterPos, pal); lastInChrBuf++; } //wrap buf index around to stay inside the ring buffer |