?? readpic.c
字號:
/* readpic.c, 從avi文件中讀取源圖像數據*/
#include <windows.h>
#include <vfw.h>
#include <stdio.h>
#include <stdlib.h>
#include "global.h"#include "video.h"
static void conv444to422(unsigned char[], unsigned char[]);
static void conv422to420(unsigned char[], unsigned char[]);
unsigned int u, v, bpscanl, dib_offset, j, hblank, vblank, hcrop, vcrop, topblank;
int x, y;
float R, G, B;
// RGB->YUV 轉換常數
const float RY = (77.0/256.0), GY = (150.0/256.0), BY = (29.0/256.0);
const float RU = (-44.0/256.0), GU = (-87.0/256.0), BU = (131.0/256.0);
const float RV = (131.0/256.0), GV = (-110.0/256.0), BV = (-21.0/256.0);
static short PACKED_Y[4] = { 29, 150, 77, 0 };
static short PACKED_U[4] = { 131, -87, -44, 0 };
static short PACKED_V[4] = { -21, -110, 131, 0 };
static short PACKED_RY[4] = { 77, 77, 77, 77 };
static short PACKED_GY[4] = { 150, 150, 150, 150 };
static short PACKED_BY[4] = { 29, 29, 29, 29 };
static short PACKED_RU[4] = { -44, -44, -44, -44 };
static short PACKED_GU[4] = { -87, -87, -87, -87 };
static short PACKED_BU[4] = { 131, 131, 131, 131 };
static short PACKED_RV[4] = { 131, 131, 131, 131 };
static short PACKED_GV[4] = { -110, -110, -110, -110 };
static short PACKED_BV[4] = { -21, -21, -21, -21 };
static short PACKED_128[4] = { 128, 128, 128, 128 };
static short PACKED_0[4] = { 0, 0, 0, 0 };
static unsigned char PACKED_128B[8] = { 128, 128, 128, 128, 128, 128, 128, 128 };
static long PACKED_128L[2] = { 128, 128 };
static short PACKED_0x07[4] = { 0x07, 0x07, 0x07, 0x07 };
static short PACKED_0xf8[4] = { 0xf8, 0xf8, 0xf8, 0xf8 };
// conv444to422 and conv522to420 constants
static short PACKED_228[4] = { 228, 228, 228, 228 };
static short PACKED_70[4] = { 70, 70, 70, 70 };
static short PACKED_MINUS37[4] = { -37, -37, -37, -37 };
static short PACKED_MINUS21[4] = { -21, -21, -21, -21 };
static short PACKED_11[4] = { 11, 11, 11, 11 };
static short PACKED_5[4] = { 5, 5, 5, 5 };
static long PACKED_256[2] = { 256, 256 };
static short PACKED_255[4] = { 255, 255, 255, 255 };
/
const int Tolerance = 10;
const int Filtersize = 6;
#define MAX(a, b) ((a)>(b)?(a):(b))
#define MIN(a, b) ((a)<(b)?(a):(b))
/*
下面的程序是一個軟濾波器,它用像素周圍與之最接近的值進行替代
*/
void softfilter(unsigned char* dest, unsigned char* src, int width, int height)
{
int refval, aktval, upperval, lowerval, numvalues, sum, rowindex;
int x, y, fx, fy, fy1, fy2, fx1, fx2;
for(y = 0; y < height; y++)
{
for(x = 0; x < width; x++)
{
refval = src[x+y*width];
upperval = refval + Tolerance;
lowerval = refval - Tolerance;
numvalues = 1;
sum = refval;
fy1 = MAX(y-Filtersize, 0);
fy2 = MIN(y+Filtersize+1, height);
for (fy = fy1; fy<fy2; fy++)
{
rowindex = fy*width;
fx1 = MAX(x-Filtersize, 0) + rowindex;
fx2 = MIN(x+Filtersize+1, width) + rowindex;
for (fx = fx1; fx<fx2; fx++)
{
aktval = src[fx];
if ((lowerval-aktval)*(upperval-aktval)<0)
{
numvalues ++;
sum += aktval;
}
} //for fx
} //for fy
dest[x+y*width] = sum/numvalues;
}
}
}
void readframe(lCurFrame,frame)unsigned char *frame[];
unsigned long lCurFrame;{
int h, w;
int lblank, rblank; unsigned char *lpframeY, *lpframeU, *lpframeV;
unsigned int pixsz;
unsigned char *lpColor;
unsigned int palletized;
int file;
for(file=0;file<numAviFiles;file++)
if ((lCurFrame/frame_repl) < nextFileFrames[file])
break;
lpbi = AVIStreamGetFrame(pget[file], lCurFrame/frame_repl-((file==0)?0:nextFileFrames[file-1]));
if(!lpbi && !fake_bad_frames)
{
fprintf(stderr, "\ncould not retrieve video frame %i!\n", lCurFrame);
fprintf(stderr, "\npossibly corrupt avi file, try -e option.");
exit(25);
}
else if(!lpbi && fake_bad_frames)
{
for(file=0;file<numAviFiles;file++)
if ((last_good_video_frame) < nextFileFrames[file])
break;
lpbi = AVIStreamGetFrame(pget[file], last_good_video_frame);
bad_frame_count++;
}
else if(lpbi)
{
last_good_video_frame = lCurFrame/frame_repl;
}
pixsz = lpbi->biBitCount;
if((pixsz!=8)&&(pixsz!=16)&&(pixsz!=24)&&(pixsz!=32))
{
fprintf(stderr, "\ncan only handle 8 bit palettized, or 16, 24, or 32 bit RGB video!");
exit(26);
}
if(pixsz==8)
palletized=1;
else
palletized=0;
if (lpbi->biCompression != BI_RGB) // does not support BI_BITFIELDS
{
fprintf(stderr, "\ncan not handle compressed DIBs from codec!");
exit(27);
}
lpColor = (unsigned char *)lpbi + lpbi->biSize;
if(palletized)
dib_offset = sizeof(BITMAPINFOHEADER) + lpbi->biClrUsed * 4;
else
dib_offset = sizeof(BITMAPINFOHEADER); // offset past bitmap header
lpbitmp = (unsigned char *)lpbi + dib_offset; // pointer to actual bitmap
switch(pixsz)
{
case 8:
bpscanl = (unsigned int)(((lpbi->biWidth + 3)>>2)<<2);
break;
case 16:
bpscanl = (unsigned int)(lpbi->biWidth * 2);
break;
case 24:
bpscanl = ((((unsigned int)lpbi->biWidth * 3 + 3)>>2)<<2);
break;
case 32:
bpscanl = (unsigned int)(lpbi->biWidth * 4);
break;
default:
fprintf(stderr, "\ninternal error: illegal pixsz value\n");
exit(28);
}
if(width>lpbi->biWidth)
hblank = width - lpbi->biWidth;
else
hblank=0;
if(height>lpbi->biHeight)
vblank = height - lpbi->biHeight;
else
vblank=0;
if(width<lpbi->biWidth)
hcrop = lpbi->biWidth - width;
else
hcrop=0;
if(height<lpbi->biHeight)
vcrop = lpbi->biHeight - height;
else
vcrop=0;
if(vertical_size>lpbi->biHeight)
topblank = (vertical_size - lpbi->biHeight)/2;
else
topblank = 0;
// 將RGB DIB 轉化成 YUV (4:2:0)
lpframeY = (unsigned char *)frame[0];
lpframeU = (unsigned char *)frame[1];
lpframeV = (unsigned char *)frame[2];
j = topblank;
while(j > 0)
{
for(x = 0; x < width; x++)
{
*lpframeY++ = 0;
Ubuffer[x + (j - 1)*width] = 128;
Vbuffer[x + (j - 1)*width] = 128;
}
j--;
}
switch(pixsz)
{
case 8:
lpcurscanl = (unsigned char *)(lpbitmp + ((lpbi->biHeight - 1 - (vcrop/2)) * bpscanl) + ((hcrop/2)));
lpframeU = Ubuffer+(hblank/2)+topblank*width;
lpframeV = Vbuffer+(hblank/2)+topblank*width;
h = lpbi->biHeight - (int) vcrop;
lblank = hblank/2;
rblank = hblank - lblank;
do
{
if(lblank > 0)
{
memset(lpframeY, 0, lblank);
memset(lpframeU, 128, lblank);
memset(lpframeV, 128, lblank);
lpframeY += lblank;
lpframeU += lblank;
lpframeV += lblank;
}
w = lpbi->biWidth - (int) hcrop;
lpcurpix = lpcurscanl;
do
{
R = (float) lpColor[*lpcurpix * 4 + 2];
G = (float) lpColor[*lpcurpix * 4 + 1];
B = (float) lpColor[*lpcurpix * 4 + 0];
lpcurpix++;
*lpframeY++ = (int)(RY*R + GY*G + BY*B);
*lpframeU++ = (int)(RU*R + GU*G + BU*B + 128);
*lpframeV++ = (int)(RV*R + GV*G + BV*B + 128);
} while(--w);
if(rblank > 0)
{
memset(lpframeY, 0, rblank);
memset(lpframeU, 128, rblank);
memset(lpframeV, 128, rblank);
lpframeY += rblank;
lpframeU += rblank;
lpframeV += rblank;
}
lpcurscanl -= bpscanl;
} while(--h);
break;
case 16:
lpcurscanl = (unsigned char *)(lpbitmp + ((lpbi->biHeight - 1 - (vcrop/2)) * bpscanl) + ((hcrop/2) * 2));
lpframeU = Ubuffer+(hblank/2)+topblank*width;
lpframeV = Vbuffer+(hblank/2)+topblank*width;
h = lpbi->biHeight - (int) vcrop;
lblank = hblank/2;
rblank = hblank - lblank;
do
{
if(lblank > 0)
{
memset(lpframeY, 0, lblank);
memset(lpframeU, 128, lblank);
memset(lpframeV, 128, lblank);
lpframeY += lblank;
lpframeU += lblank;
lpframeV += lblank;
}
if(cpu_MMX)
{
w = (lpbi->biWidth-(int)hcrop) >> 2;
_asm
{
mov esi, lpcurscanl ;// esi = lpcurscanl
mov ecx, lpframeY ;// ecx = lpframeY
mov edx, lpframeU ;// edx = lpframeU
mov edi, lpframeV ;// edi = lpframeV
movq mm6, PACKED_128 ;// mm6 = (128, 128, 128, 128)
readframe__l1:
movq mm0, [esi] ;// mm0 = 4 words into esi[0..7]
movq mm3, mm0
movq mm6, mm0
psrlw mm0, 7
psrlw mm3, 2
psllw mm6, 3
pand mm0, PACKED_0xf8
pand mm3, PACKED_0xf8
pand mm6, PACKED_0xf8
por mm0, PACKED_0x07 ;// red is in mm0
por mm3, PACKED_0x07 ;// green is in mm3
por mm6, PACKED_0x07 ;// blue is in mm6
movq mm1, mm0
movq mm2, mm0
movq mm4, mm3
movq mm5, mm3
pmullw mm0, PACKED_RY ;// mm0 *= (RY, RY, RY, RY)
pmullw mm1, PACKED_RU ;// mm1 *= (RU, RU, RU, RU)
pmullw mm2, PACKED_RV ;// mm2 *= (RV, RV, RV, RV)
pmullw mm3, PACKED_GY ;// mm3 *= (GY, GY, GY, GY)
pmullw mm4, PACKED_GU ;// mm4 *= (GU, GU, GU, GU)
pmullw mm5, PACKED_GV ;// mm5 *= (GV, GV, GV, GV)
paddw mm0, mm3 ;// mm0 += mm3
paddw mm1, mm4 ;// mm1 += mm4
paddw mm2, mm5 ;// mm2 += mm5
movq mm7, mm6
movq mm3, mm6
pmullw mm6, PACKED_BY ;// mm6 *= (RY, RY, RY, RY)
pmullw mm7, PACKED_BU ;// mm7 *= (RY, RY, RY, RY)
pmullw mm3, PACKED_BV ;// mm3 *= (RY, RY, RY, RY)
paddw mm0, mm6 ;// mm0 += mm6
paddw mm1, mm7 ;// mm1 += mm7
paddw mm2, mm3 ;// mm2 += mm3
paddusw mm0, PACKED_128 ;// mm0 += (128, 128, 128, 128)
paddusw mm1, PACKED_128 ;// mm1 += (128, 128, 128, 128)
paddusw mm2, PACKED_128 ;// mm2 += (128, 128, 128, 128)
psrlw mm0, 8 ;// shift mm0 and round to lower
psrlw mm1, 8 ;// shift mm1 and round to lower
psrlw mm2, 8 ;// shift mm2 and round to lower
packuswb mm0, mm0 ;// pack 4 words into the lower 4 bytes of mm0
packuswb mm1, mm1 ;// pack 4 words into the lower 4 bytes of mm1
packuswb mm2, mm2 ;// pack 4 words into the lower 4 bytes of mm2
paddb mm1, PACKED_128B ;// mm1 += (128, 128, 128, 128, 128, 128, 128, 128)
paddb mm2, PACKED_128B ;// mm2 += (128, 128, 128, 128, 128, 128, 128, 128)
movd [ecx], mm0 ;// store mm0 into ecx[0..7]
movd [edx], mm1 ;// store mm1 into edx[0..7]
movd [edi], mm2 ;// store mm2 into edi[0..7]
add esi, 8 ;// esi += 8
add ecx, 4 ;// edx += 4
add edx, 4 ;// edx += 4
add edi, 4 ;// edi += 4;
dec dword ptr w ;// decrement w
jnz readframe__l1 ;// loop while not zero
mov lpframeY, ecx ;// update lpframeY
mov lpframeU, edx ;// update lpframeU
mov lpframeV, edi ;// update lpframeV
emms ;// empty MMX state
}
}
else
{
w = lpbi->biWidth - (int) hcrop;
lpcurpixw = (unsigned short *) lpcurscanl;
do
{
R = (float)(((*lpcurpixw >> 7) & 0xf8)|0x07);
G = (float)(((*lpcurpixw >> 2) & 0xf8)|0x07);
B = (float)(((*lpcurpixw << 3) & 0xf8)|0x07);
lpcurpixw++;
*lpframeY++ = (int)(RY*R + GY*G + BY*B);
*lpframeU++ = (int)(RU*R + GU*G + BU*B + 128);
*lpframeV++ = (int)(RV*R + GV*G + BV*B + 128);
} while(--w);
}
// take care of any blank pixels on the right
if(rblank > 0)
{
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -