⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 readpic.c

📁 avi2mpg1_src 中包含了mpeg1编码的源程序
💻 C
📖 第 1 页 / 共 3 页
字号:
/* 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 + -