comparison postproc/swscale_template.c @ 3215:3083616ba4d6

sliced scaleing bugfix
author michael
date Thu, 29 Nov 2001 22:19:21 +0000
parents 0b172eb639f1
children 7e4399d1eb65
comparison
equal deleted inserted replaced
3214:6d3c84c8b2f6 3215:3083616ba4d6
1153 } 1153 }
1154 #endif 1154 #endif
1155 } 1155 }
1156 1156
1157 1157
1158 static inline void RENAME(hyscale)(uint16_t *dst, int dstWidth, uint8_t *src, int srcWidth, int xInc) 1158 static inline void RENAME(hyscale)(uint16_t *dst, int dstWidth, uint8_t *src, int srcW, int xInc)
1159 { 1159 {
1160 // *** horizontal scale Y line to temp buffer 1160 // *** horizontal scale Y line to temp buffer
1161 #ifdef ARCH_X86 1161 #ifdef ARCH_X86
1162 #ifdef HAVE_MMX2 1162 #ifdef HAVE_MMX2
1163 int i; 1163 int i;
1206 1206
1207 :: "m" (src), "m" (dst), "m" (dstWidth), "m" ((xInc*4)>>16), 1207 :: "m" (src), "m" (dst), "m" (dstWidth), "m" ((xInc*4)>>16),
1208 "m" ((xInc*4)&0xFFFF), "m" (xInc&0xFFFF) 1208 "m" ((xInc*4)&0xFFFF), "m" (xInc&0xFFFF)
1209 : "%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi" 1209 : "%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi"
1210 ); 1210 );
1211 for(i=dstWidth-1; (i*xInc)>>16 >=srcWidth-1; i--) dst[i] = src[srcWidth-1]*128; 1211 for(i=dstWidth-1; (i*xInc)>>16 >=srcW-1; i--) dst[i] = src[srcW-1]*128;
1212 } 1212 }
1213 else 1213 else
1214 { 1214 {
1215 #endif 1215 #endif
1216 //NO MMX just normal asm ... 1216 //NO MMX just normal asm ...
1268 } 1268 }
1269 #endif 1269 #endif
1270 } 1270 }
1271 1271
1272 inline static void RENAME(hcscale)(uint16_t *dst, int dstWidth, 1272 inline static void RENAME(hcscale)(uint16_t *dst, int dstWidth,
1273 uint8_t *src1, uint8_t *src2, int srcWidth, int xInc) 1273 uint8_t *src1, uint8_t *src2, int srcW, int xInc)
1274 { 1274 {
1275 #ifdef ARCH_X86 1275 #ifdef ARCH_X86
1276 #ifdef HAVE_MMX2 1276 #ifdef HAVE_MMX2
1277 int i; 1277 int i;
1278 if(canMMX2BeUsed) 1278 if(canMMX2BeUsed)
1335 1335
1336 :: "m" (src1), "m" (dst), "m" (dstWidth), "m" ((xInc*4)>>16), 1336 :: "m" (src1), "m" (dst), "m" (dstWidth), "m" ((xInc*4)>>16),
1337 "m" ((xInc*4)&0xFFFF), "m" (xInc&0xFFFF), "m" (src2) 1337 "m" ((xInc*4)&0xFFFF), "m" (xInc&0xFFFF), "m" (src2)
1338 : "%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi" 1338 : "%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi"
1339 ); 1339 );
1340 for(i=dstWidth-1; (i*xInc)>>16 >=srcWidth/2-1; i--) 1340 for(i=dstWidth-1; (i*xInc)>>16 >=srcW/2-1; i--)
1341 { 1341 {
1342 dst[i] = src1[srcWidth/2-1]*128; 1342 dst[i] = src1[srcW/2-1]*128;
1343 dst[i+2048] = src2[srcWidth/2-1]*128; 1343 dst[i+2048] = src2[srcW/2-1]*128;
1344 } 1344 }
1345 } 1345 }
1346 else 1346 else
1347 { 1347 {
1348 #endif 1348 #endif
1411 1411
1412 unsigned int s_xinc2; 1412 unsigned int s_xinc2;
1413 //FIXME do we need th +-2 stuff? 1413 //FIXME do we need th +-2 stuff?
1414 unsigned int s_xinc= (srcW << 16) / dstW - 2; 1414 unsigned int s_xinc= (srcW << 16) / dstW - 2;
1415 unsigned int s_yinc= (srcH << 16) / dstH + 2; 1415 unsigned int s_yinc= (srcH << 16) / dstH + 2;
1416 1416
1417 static int lumDstYInSrc; // points to the dst Pixels center in the source (0 is the center of pixel 0,0 in src) 1417 static int lumDstYInSrc; // points to the dst Pixels center in the source (0 is the center of pixel 0,0 in src)
1418 static int dstY; 1418 static int dstY;
1419 1419
1420 // last horzontally interpolated lines, used to avoid unnecessary calculations 1420 // last horzontally interpolated lines, used to avoid unnecessary calculations
1421 static int lastLumSrcY; 1421 static int lastLumSrcY;
1425 // used to detect a horizontal size change 1425 // used to detect a horizontal size change
1426 static int old_dstW= -1; 1426 static int old_dstW= -1;
1427 static int old_s_xinc= -1; 1427 static int old_s_xinc= -1;
1428 #endif 1428 #endif
1429 1429
1430 int srcWidth;
1431 int dstUVw; 1430 int dstUVw;
1432 int i; 1431 int i;
1433 1432
1434 if(((dstW + 7)&(~7)) >= dststride) dstW&= ~7; 1433 if(((dstW + 7)&(~7)) >= dststride) dstW&= ~7;
1435 1434
1436 srcWidth= (dstW*s_xinc + 0x8000)>>16;
1437 dstUVw= fullUVIpol ? dstW : dstW/2; 1435 dstUVw= fullUVIpol ? dstW : dstW/2;
1438 1436
1437 //printf("%d %d %d %d\n", srcW, srcH, dstW, dstH);
1438 //printf("%d %d %d %d\n", s_xinc, s_yinc, srcSliceY, srcSliceH);
1439
1439 #ifdef HAVE_MMX2 1440 #ifdef HAVE_MMX2
1440 canMMX2BeUsed= (s_xinc <= 0x10000 && (dstW&31)==0 && (srcWidth&15)==0) ? 1 : 0; 1441 canMMX2BeUsed= (s_xinc <= 0x10000 && (dstW&31)==0 && (srcW&15)==0) ? 1 : 0;
1441 #endif 1442 #endif
1442 1443
1443 // match pixel 0 of the src to pixel 0 of dst and match pixel n-2 of src to pixel n-2 of dst 1444 // match pixel 0 of the src to pixel 0 of dst and match pixel n-2 of src to pixel n-2 of dst
1444 // n-2 is the last chrominance sample available 1445 // n-2 is the last chrominance sample available
1445 // FIXME this is not perfect, but noone shuld notice the difference, the more correct variant 1446 // FIXME this is not perfect, but noone shuld notice the difference, the more correct variant
1446 // would be like the vertical one, but that would require some special code for the 1447 // would be like the vertical one, but that would require some special code for the
1447 // first and last pixel 1448 // first and last pixel
1448 if(canMMX2BeUsed) s_xinc+= 20; 1449 if(canMMX2BeUsed) s_xinc+= 20;
1449 else s_xinc = ((srcWidth-2)<<16)/(dstW-2) - 20; 1450 else s_xinc = ((srcW-2)<<16)/(dstW-2) - 20;
1450 1451
1451 if(fullUVIpol && !(dstbpp==12)) s_xinc2= s_xinc>>1; 1452 if(fullUVIpol && !(dstbpp==12)) s_xinc2= s_xinc>>1;
1452 else s_xinc2= s_xinc; 1453 else s_xinc2= s_xinc;
1453 // force calculation of the horizontal interpolation of the first line 1454 // force calculation of the horizontal interpolation of the first line
1454 1455
1455 if(srcSliceY ==0){ 1456 if(srcSliceY ==0){
1456 // printf("dstW %d, srcw %d, mmx2 %d\n", dstW, srcWidth, canMMX2BeUsed); 1457 // printf("dstW %d, srcw %d, mmx2 %d\n", dstW, srcW, canMMX2BeUsed);
1457 lastLumSrcY=-99; 1458 lastLumSrcY=-99;
1458 lastChrSrcY=-99; 1459 lastChrSrcY=-99;
1459 lumDstYInSrc= s_yinc/2 - 0x8000; 1460 lumDstYInSrc= s_yinc/2 - 0x8000;
1460 dstY=0; 1461 dstY=0;
1461 1462
1618 uint16_t *buf0=pix_buf_y[ lumSrcY &1]; // top line of the interpolated slice 1619 uint16_t *buf0=pix_buf_y[ lumSrcY &1]; // top line of the interpolated slice
1619 uint16_t *buf1=pix_buf_y[(lumSrcY+1)&1]; // bottom line of the interpolated slice 1620 uint16_t *buf1=pix_buf_y[(lumSrcY+1)&1]; // bottom line of the interpolated slice
1620 uint16_t *uvbuf0=pix_buf_uv[ chrSrcY &1]; // top line of the interpolated slice 1621 uint16_t *uvbuf0=pix_buf_uv[ chrSrcY &1]; // top line of the interpolated slice
1621 uint16_t *uvbuf1=pix_buf_uv[(chrSrcY+1)&1]; // bottom line of the interpolated slice 1622 uint16_t *uvbuf1=pix_buf_uv[(chrSrcY+1)&1]; // bottom line of the interpolated slice
1622 1623
1623 // if(lumSrcY>=srcSliceY + srcSliceH) break; // wrong, skips last lines, but they are dupliactes anyway 1624 if(lumSrcY>=srcSliceY + srcSliceH && srcSliceY + srcSliceH < srcH) break;
1624 if(dstY >= dstH) break; 1625 if(dstY >= dstH) break;
1625 1626
1626 // printf("lumSrcY:%d, dstY:%d, yalpha:%d\n", lumSrcY, dstY, yalpha*100/0x1000); 1627 // printf("lumSrcY:%d, dstY:%d, yalpha:%d\n", lumSrcY, dstY, yalpha*100/0x1000);
1627 1628
1628 if((dstY&1) && dstbpp==12) uvalpha=-1; 1629 if((dstY&1) && dstbpp==12) uvalpha=-1;
1629 1630
1630 dstY++; lumDstYInSrc+=s_yinc; 1631 dstY++; lumDstYInSrc+=s_yinc;
1631 1632
1632 //only interpolate the src line horizontally if we didnt do it allready 1633 //only interpolate the src line horizontally if we didnt do it allready
1633 if(lastLumSrcY!=lumSrcY) 1634 if(lastLumSrcY!=lumSrcY)
1634 { 1635 {
1635 unsigned char *src; 1636 unsigned char *src;
1637
1636 // skip if first line has been horiz scaled alleady 1638 // skip if first line has been horiz scaled alleady
1637 if(lastLumSrcY != lumSrcY-1) 1639 if(lastLumSrcY != lumSrcY-1)
1638 { 1640 {
1639 // check if first line is before any available src lines 1641 // check if first line is before any available src lines
1640 if(lumSrcY-1 < srcSliceY ) src=srcptr[0]+(0 )*stride[0]; 1642 if(lumSrcY-1 < srcSliceY ) src=srcptr[0]+(0 )*stride[0];
1641 else src=srcptr[0]+(lumSrcY-srcSliceY -1)*stride[0]; 1643 else src=srcptr[0]+(lumSrcY-srcSliceY -1)*stride[0];
1642 1644
1643 RENAME(hyscale)(buf0, dstW, src, srcWidth, s_xinc); 1645 RENAME(hyscale)(buf0, dstW, src, srcW, s_xinc);
1644 } 1646 }
1645 // check if second line is after any available src lines 1647 // check if second line is after any available src lines
1646 if(lumSrcY-srcSliceY >= srcSliceH) src=srcptr[0]+(srcSliceH-1 )*stride[0]; 1648 if(lumSrcY-srcSliceY >= srcSliceH) src=srcptr[0]+(srcSliceH-1 )*stride[0];
1647 else src=srcptr[0]+(lumSrcY-srcSliceY )*stride[0]; 1649 else src=srcptr[0]+(lumSrcY-srcSliceY )*stride[0];
1648 1650
1649 // the min() is required to avoid reuseing lines which where not available 1651 // the min() is required to avoid reuseing lines which where not available
1650 lastLumSrcY= MIN(lumSrcY, srcSliceY +srcSliceH-1); 1652 lastLumSrcY= MIN(lumSrcY, srcSliceY +srcSliceH-1);
1651 RENAME(hyscale)(buf1, dstW, src, srcWidth, s_xinc); 1653 RENAME(hyscale)(buf1, dstW, src, srcW, s_xinc);
1652 } 1654 }
1653 // printf("%d %d %d %d\n", y, chrSrcY, lastChrSrcY, h); 1655 // printf("%d %d %d %d\n", y, chrSrcY, lastChrSrcY, h);
1654 // *** horizontal scale U and V lines to temp buffer 1656 // *** horizontal scale U and V lines to temp buffer
1655 if(lastChrSrcY!=chrSrcY) 1657 if(lastChrSrcY!=chrSrcY)
1656 { 1658 {
1665 src2= srcptr[2]+(0)*stride[2]; 1667 src2= srcptr[2]+(0)*stride[2];
1666 }else{ 1668 }else{
1667 src1= srcptr[1]+(chrSrcY-srcSliceY /2-1)*stride[1]; 1669 src1= srcptr[1]+(chrSrcY-srcSliceY /2-1)*stride[1];
1668 src2= srcptr[2]+(chrSrcY-srcSliceY /2-1)*stride[2]; 1670 src2= srcptr[2]+(chrSrcY-srcSliceY /2-1)*stride[2];
1669 } 1671 }
1670 RENAME(hcscale)(uvbuf0, dstUVw, src1, src2, srcWidth, s_xinc2); 1672 RENAME(hcscale)(uvbuf0, dstUVw, src1, src2, srcW, s_xinc2);
1671 } 1673 }
1672 1674
1673 // check if second line is after any available src lines 1675 // check if second line is after any available src lines
1674 if(chrSrcY - srcSliceY /2 >= srcSliceH/2) 1676 if(chrSrcY - srcSliceY /2 >= srcSliceH/2)
1675 { 1677 {
1677 src2= srcptr[2]+(srcSliceH/2-1)*stride[2]; 1679 src2= srcptr[2]+(srcSliceH/2-1)*stride[2];
1678 }else{ 1680 }else{
1679 src1= srcptr[1]+(chrSrcY-srcSliceY /2)*stride[1]; 1681 src1= srcptr[1]+(chrSrcY-srcSliceY /2)*stride[1];
1680 src2= srcptr[2]+(chrSrcY-srcSliceY /2)*stride[2]; 1682 src2= srcptr[2]+(chrSrcY-srcSliceY /2)*stride[2];
1681 } 1683 }
1682 RENAME(hcscale)(uvbuf1, dstUVw, src1, src2, srcWidth, s_xinc2); 1684 RENAME(hcscale)(uvbuf1, dstUVw, src1, src2, srcW, s_xinc2);
1683 1685
1684 // the min() is required to avoid reuseing lines which where not available 1686 // the min() is required to avoid reuseing lines which where not available
1685 lastChrSrcY= MIN(chrSrcY, srcSliceY /2+srcSliceH/2-1); 1687 lastChrSrcY= MIN(chrSrcY, srcSliceY /2+srcSliceH/2-1);
1686 } 1688 }
1687 #ifdef HAVE_MMX 1689 #ifdef HAVE_MMX