00001
00038 #ifdef _WINDOWS
00039 #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
00040 #include <windows.h>
00041 #else
00042 #include <stdio.h>
00043 #endif
00044
00045 #include <string.h>
00046 #include <stdlib.h>
00047 #include <math.h>
00048
00049 #include "PicScalerYUV420PImpl.h"
00050
00051
00052
00053
00054
00055
00064 int PicScalerYUV420PImpl::Scale(void* pOutImg, void* pInImg)
00065 {
00066 if( (pOutImg == NULL) || (pInImg == NULL) )
00067 return(0);
00068
00069 scaleType* pSrc = (scaleType*)pInImg;
00070 scaleType* pDst = (scaleType*)pOutImg;
00071
00072 double scalex = ((double)_widthIn)/((double)_widthOut);
00073 double scaley = ((double)_heightIn)/((double)_heightOut);
00074
00075 int x,y,posx,posy,i,j;
00076
00078 for(y = 0; y < _heightOut; y++)
00079 {
00080 posy = (int)((scaley * (double)y) + 0.5);
00081 if(posy < 0) posy = 0;
00082 else if(posy >= _heightIn) posy = _heightIn-1;
00083
00084 for(x = 0; x < _widthOut; x++)
00085 {
00086 posx = (int)((scalex * (double)x) + 0.5);
00087 if(posx < 0) posx = 0;
00088 else if(posx >= _widthIn) posx = _widthIn-1;
00089
00091 int ai = (posy*_widthIn) + posx;
00092 int lum = 7 * (int)(*(pSrc + ai));
00093 for(i = -1; i <= 1; i++)
00094 {
00095 int row = posy + i;
00096 if(row < 0) row = 0;
00097 else if(row >= _heightIn) row = _heightIn-1;
00098 for(j = -1; j <= 1; j++)
00099 {
00100 int col = posx + j;
00101 if(col < 0) col = 0;
00102 else if(col >= _widthIn) col = _widthIn-1;
00103
00104 int aii = (row*_widthIn) + col;
00105 lum += (int)(*(pSrc + aii));
00106
00107 }
00108 }
00109
00111 int ao = (y*_widthOut) + x;
00112 *(pDst + ao) = (scaleType)((lum + 8) >> 4);
00113
00114 }
00115
00116 }
00117
00119 int chrWidthIn = _widthIn/2;
00120 int chrHeightIn = _heightIn/2;
00121 int chrWidthOut = _widthOut/2;
00122 int chrHeightOut = _heightOut/2;
00123
00124 scaleType* pSrcU = (scaleType*)pInImg + (_widthIn * _heightIn);
00125 scaleType* pSrcV = (scaleType*)pInImg + (_widthIn * _heightIn) + (chrWidthIn * chrHeightIn);
00126 scaleType* pDstU = (scaleType*)pOutImg + (_widthOut * _heightOut);
00127 scaleType* pDstV = (scaleType*)pOutImg + (_widthOut * _heightOut) + (chrWidthOut * chrHeightOut);
00128
00129 for(y = 0; y < chrHeightOut; y++)
00130 {
00131 posy = (int)((scaley * (double)y) + 0.5);
00132 if(posy < 0) posy = 0;
00133 else if(posy >= chrHeightIn) posy = chrHeightIn-1;
00134
00135 for(x = 0; x < chrWidthOut; x++)
00136 {
00137 posx = (int)((scalex * (double)x) + 0.5);
00138 if(posx < 0) posx = 0;
00139 else if(posx >= chrWidthIn) posx = chrWidthIn-1;
00140
00142 int ai = (posy*chrWidthIn) + posx;
00143 int chrU = 7 * (int)(*(pSrcU + ai));
00144 int chrV = 7 * (int)(*(pSrcV + ai));
00145 for(i = -1; i <= 1; i++)
00146 {
00147 int row = posy + i;
00148 if(row < 0) row = 0;
00149 else if(row >= chrHeightIn) row = chrHeightIn-1;
00150 for(j = -1; j <= 1; j++)
00151 {
00152 int col = posx + j;
00153 if(col < 0) col = 0;
00154 else if(col >= chrWidthIn) col = chrWidthIn-1;
00155
00156 int aii = (row*chrWidthIn) + col;
00157 chrU += (int)(*(pSrcU + aii));
00158 chrV += (int)(*(pSrcV + aii));
00159
00160 }
00161 }
00162
00164 int ao = (y*chrWidthOut) + x;
00165 *(pDstU + ao) = (scaleType)((chrU + 8) >> 4);
00166 *(pDstV + ao) = (scaleType)((chrV + 8) >> 4);
00167
00168 }
00169
00170 }
00171 return(1);
00172 }
00173