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

📄 image.cpp

📁 H.263的编码程序,加了CPU指令优化,VC版.
💻 CPP
字号:
#include "HEnc.h"
#include <math.h>
#include <stdio.h>


void Hfilter(unsigned char *rec, int width, int height, int lx, int chr,
			 int coded_tab[MBR+1][MBC+1], int quant_tab[MBR+1][MBC+1])
{
	int i, j, k;
	int delta, d1, d2;
	int mbc, mbr, do_filter;
	int QP;
	int bquant[] = {5, 6, 7, 8};
	int mbr_above;
	int STRENGTH[] = {1,1,2,2,3,3,4,4,4,5,5,6,6,7,7,7,8,8,8,9,9,9,10,10,10,11,11,11,12,12,12};
	/* horizontal edges */
	for (j = 8; j < height; j += 8)
	{
		for (i = 0; i < width; i += 8)
		{
			if (!chr)
			{
				mbr = j >> 4;
				mbc = i >> 4;
				mbr_above = (j - 8) >> 4;
			} else
			{
				mbr = j >> 3;
				mbc = i >> 3;
				mbr_above = mbr - 1;
			}
			
			do_filter = coded_tab[mbr + 1][mbc + 1] || coded_tab[mbr_above + 1][mbc + 1];
			
			if (do_filter)
			{
				QP = coded_tab[mbr + 1][mbc + 1] ? quant_tab[mbr + 1][mbc + 1] : quant_tab[mbr_above + 1][mbc + 1];
			    for (k = i; k < i+8; k ++)
				{
					delta = (int) (((int) (*(rec + k + (j - 2) * lx)) +
						(int) (*(rec + k + (j - 1) * lx) * (-4)) +
						(int) (*(rec + k + (j) * lx) * (4)) +
						(int) (*(rec + k + (j + 1) * lx) * (-1))) / 8.0);
					d1 = sign (delta) * mmax (0, abs (delta) - mmax (0, 2 * (abs (delta) - STRENGTH[QP - 1])));
					d2 = mmin (abs (d1 / 2), mmax (-abs (d1 / 2), (int) (((*(rec + k + (j - 2) * lx) -
						*(rec + k + (j + 1) * lx))) / 4)));
					*(rec + k + (j + 1) * lx) = (int) (*(rec + k + (j + 1) * lx)) + d2;
					*(rec + k + (j) * lx) =
						mmin (255, mmax (0, (int) (*(rec + k + (j) * lx)) - d1));
					*(rec + k + (j - 1) * lx) =
						mmin (255, mmax (0, (int) (*(rec + k + (j - 1) * lx)) + d1));
					*(rec + k + (j - 2) * lx) = (int) (*(rec + k + (j - 2) * lx)) - d2;
				}
			}
		}
	}
}

void Vfilter(unsigned char *rec, int width, int height, int lx, int chr, 
			 int coded_tab[MBR+1][MBC+1], int quant_tab[MBR+1][MBC+1])
{
	int i, j, k;
	int delta, d1, d2;
	int mbc, mbr;
	int do_filter;
	int bquant[] = {5, 6, 7, 8};
	int QP;
	int mbc_left;
	int STRENGTH[] = {1,1,2,2,3,3,4,4,4,5,5,6,6,7,7,7,8,8,8,9,9,9,10,10,10,11,11,11,12,12,12};
	
	/* vertical edges */
	for (i = 8; i < width; i += 8)
	{
		for (j = 0; j < height; j += 8)
		{
			if (!chr)
			{
				mbr = j >> 4;
				mbc = i >> 4;
				mbc_left = (i - 8) >> 4;
			} else
			{
				mbr = j >> 3;
				mbc = i >> 3;
				mbc_left = mbc - 1;
			}
			do_filter = coded_tab[mbr + 1][mbc + 1] || coded_tab[mbr + 1][mbc_left + 1];
			
			if (do_filter)
			{
				QP = coded_tab[mbr + 1][mbc + 1] ? quant_tab[mbr + 1][mbc + 1] : quant_tab[mbr + 1][mbc_left + 1];
				for (k = j; k < j+8; k++)
				{
					delta = (int) (((int) (*(rec + i - 2 + k * lx)) +
						(int) (*(rec + i - 1 + k * lx) * (-4)) +
						(int) (*(rec + i + k * lx) * (4)) +
						(int) (*(rec + i + 1 + k * lx) * (-1))) / 8.0);
					
					d1 = sign (delta) * mmax (0, abs (delta) - mmax (0, 2 * (abs (delta) - STRENGTH[QP - 1])));
					d2 = mmin (abs (d1 / 2), mmax (-abs (d1 / 2), (int) ((*(rec + i - 2 + k * lx) -
						*(rec + i + 1 + k * lx)) / 4)));
					
					*(rec + i + 1 + k * lx) = (int) (*(rec + i + 1 + k * lx)) + d2;
					*(rec + i + k * lx) =
						mmin (255, mmax (0, (int) (*(rec + i + k * lx)) - d1));
					*(rec + i - 1 + k * lx) =
						mmin (255, mmax (0, (int) (*(rec + i - 1 + k * lx)) + d1));
					*(rec + i - 2 + k * lx) = (int) (*(rec + i - 2 + k * lx)) - d2;
				}
			}
		}
	}
}

/*!
    EdgeFilter:   Edge filter for reducing blocking artifact
    optimization: NO
*/
void EdgeFilter(H263VencStatus *encoder)
{
	int lx = encoder->mv_outside_frame ? (encoder->pels + 32) : encoder->pels;
	
	
	/* Lum */
	Hfilter(encoder->frame_buf[encoder->zero_index].pLum, encoder->pels, encoder->lines, lx, 0, encoder->coded_tab, encoder->quant_tab);
	Vfilter(encoder->frame_buf[encoder->zero_index].pLum, encoder->pels, encoder->lines, lx, 0, encoder->coded_tab, encoder->quant_tab);
	/* Chrom */
	Hfilter(encoder->frame_buf[encoder->zero_index].pCb, encoder->pels/2, encoder->lines/2, lx/2, 1, encoder->coded_tab, encoder->quant_tab);
	Vfilter(encoder->frame_buf[encoder->zero_index].pCb, encoder->pels/2, encoder->lines/2, lx/2, 1, encoder->coded_tab, encoder->quant_tab);
	Hfilter(encoder->frame_buf[encoder->zero_index].pCr, encoder->pels/2, encoder->lines/2, lx/2, 1, encoder->coded_tab, encoder->quant_tab);
	Vfilter(encoder->frame_buf[encoder->zero_index].pCr, encoder->pels/2, encoder->lines/2, lx/2, 1, encoder->coded_tab, encoder->quant_tab);
	
	return;
}

/*!
    MakeEdge:     for expansion of reference picture though making edge
    optimization: NO
*/
void MakeEdge(unsigned char *pic, int width, int height, int edge)
{
	int i,j;
	unsigned char *p1,*p2,*p3,*p4;
	unsigned char *o1,*o2,*o3,*o4;
	
	/* left and right edges */
	p1 = pic - 1;
	o1 = pic;
	for (j = 0; j < height;j++) 
	{
		for (i = 0; i < edge; i++) 
		{
			*(p1 - i) = *o1;
			*(p1 + width + i + 1) = *(o1 + width - 1);
		}
		p1 += width + (edge<<1);
		o1 += width + (edge<<1);
	}    
    
	/* top and bottom edges */
	p1 = pic;
	p2 = pic + (width + (edge<<1))*(height-1);
	o1 = pic;
	o2 = pic + (width + (edge<<1))*(height-1);
	for (j = 0; j < edge;j++) 
	{
		p1 = p1 - (width + (edge<<1));
		p2 = p2 + (width + (edge<<1));
		for (i = 0; i < width; i++) 
		{
			*(p1 + i) = *(o1 + i);
			*(p2 + i) = *(o2 + i);
		}
	}    
	
	/* corners */
	p1 = pic - (width+(edge<<1)) - 1;
	p2 = p1 + width + 1;
	p3 = pic + (width+(edge<<1))*(height)-1;
	p4 = p3 + width + 1;
	
	o1 = pic;
	o2 = o1 + width - 1;
	o3 = pic + (width+(edge<<1))*(height-1);
	o4 = o3 + width - 1;
	for (j = 0; j < edge; j++) 
	{
		for (i = 0; i < edge; i++) 
		{
			*(p1 - i) = *o1;
			*(p2 + i) = *o2;
			*(p3 - i) = *o3;
			*(p4 + i) = *o4; 
		}
		p1 = p1 - (width + (edge<<1));
		p2 = p2 - (width + (edge<<1));
		p3 = p3 + width + (edge<<1);
		p4 = p4 + width + (edge<<1);
	}
}
/*!
  MakeEdgeImage, for use with motion vector outside picture
*/
void MakeEdgeImage(H263VencStatus *encoder)
{
	
	/* Lum */
	MakeEdge(encoder->frame_buf[encoder->zero_index].pLum, encoder->pels, encoder->lines, 16);
	/* Chrom */
	MakeEdge(encoder->frame_buf[encoder->zero_index].pCb, encoder->pels/2, encoder->lines/2, 8);
	MakeEdge(encoder->frame_buf[encoder->zero_index].pCr, encoder->pels/2, encoder->lines/2, 8);
	
	
	return;
}

/* 
   WriteRec : Write Reconstructed Image, for test
*/
void WriteRec(H263VencStatus *encoder, FILE *fp)
{
	int j;
	int lx = encoder->mv_outside_frame ? (encoder->pels+32) : encoder->pels;
	unsigned char *pTmp;

	pTmp = encoder->frame_buf[encoder->zero_index].pLum;
	for (j = 0; j < encoder->lines; j++)
	{
		fwrite(pTmp, sizeof(unsigned char)*encoder->pels, 1, fp);
		pTmp += lx;
	}
	pTmp = encoder->frame_buf[encoder->zero_index].pCb;
	for (j = 0; j < encoder->lines/2; j++)
	{
		fwrite(pTmp, sizeof(unsigned char)*encoder->pels/2, 1, fp);
		pTmp += lx/2;
	}
	pTmp = encoder->frame_buf[encoder->zero_index].pCr;
	for (j = 0; j < encoder->lines/2; j++)
	{
		fwrite(pTmp, sizeof(unsigned char)*encoder->pels/2, 1, fp);
		pTmp += lx/2;
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -