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

📄 image.c

📁 这是一个压缩解压包,用C语言进行编程的,里面有详细的源代码.
💻 C
📖 第 1 页 / 共 2 页
字号:
/************************************************************************** * *  XVID MPEG-4 VIDEO CODEC *  - Image management functions - * *  Copyright(C) 2001-2004 Peter Ross <pross@xvid.org> * *  This program is free software ; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation ; either version 2 of the License, or *  (at your option) any later version. * *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY ; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. * *  You should have received a copy of the GNU General Public License *  along with this program ; if not, write to the Free Software *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA * * $Id: image.c,v 1.32 2005/09/09 12:18:10 suxen_drol Exp $ * ****************************************************************************/#include <stdlib.h>#include <string.h>				/* memcpy, memset */#include <math.h>#include "../portab.h"#include "../global.h"			/* XVID_CSP_XXX's */#include "../xvid.h"			/* XVID_CSP_XXX's */#include "image.h"#include "colorspace.h"#include "interpolate8x8.h"#include "../utils/mem_align.h"#include "../motion/sad.h"#include "font.h"		/* XXX: remove later */#define SAFETY	64#define EDGE_SIZE2  (EDGE_SIZE/2)int32_timage_create(IMAGE * image,			 uint32_t edged_width,			 uint32_t edged_height){	const uint32_t edged_width2 = edged_width / 2;	const uint32_t edged_height2 = edged_height / 2;	image->y =		xvid_malloc(edged_width * (edged_height + 1) + SAFETY, CACHE_LINE);	if (image->y == NULL) {		return -1;	}	memset(image->y, 0, edged_width * (edged_height + 1) + SAFETY);	image->u = xvid_malloc(edged_width2 * edged_height2 + SAFETY, CACHE_LINE);	if (image->u == NULL) {		xvid_free(image->y);		image->y = NULL;		return -1;	}	memset(image->u, 0, edged_width2 * edged_height2 + SAFETY);	image->v = xvid_malloc(edged_width2 * edged_height2 + SAFETY, CACHE_LINE);	if (image->v == NULL) {		xvid_free(image->u);		image->u = NULL;		xvid_free(image->y);		image->y = NULL;		return -1;	}	memset(image->v, 0, edged_width2 * edged_height2 + SAFETY);	image->y += EDGE_SIZE * edged_width + EDGE_SIZE;	image->u += EDGE_SIZE2 * edged_width2 + EDGE_SIZE2;	image->v += EDGE_SIZE2 * edged_width2 + EDGE_SIZE2;	return 0;}voidimage_destroy(IMAGE * image,			  uint32_t edged_width,			  uint32_t edged_height){	const uint32_t edged_width2 = edged_width / 2;	if (image->y) {		xvid_free(image->y - (EDGE_SIZE * edged_width + EDGE_SIZE));		image->y = NULL;	}	if (image->u) {		xvid_free(image->u - (EDGE_SIZE2 * edged_width2 + EDGE_SIZE2));		image->u = NULL;	}	if (image->v) {		xvid_free(image->v - (EDGE_SIZE2 * edged_width2 + EDGE_SIZE2));		image->v = NULL;	}}voidimage_swap(IMAGE * image1,		   IMAGE * image2){    SWAP(uint8_t*, image1->y, image2->y);    SWAP(uint8_t*, image1->u, image2->u);    SWAP(uint8_t*, image1->v, image2->v);}voidimage_copy(IMAGE * image1,		   IMAGE * image2,		   uint32_t edged_width,		   uint32_t height){	memcpy(image1->y, image2->y, edged_width * height);	memcpy(image1->u, image2->u, edged_width * height / 4);	memcpy(image1->v, image2->v, edged_width * height / 4);}/* setedges bug was fixed in this BS version */#define SETEDGES_BUG_BEFORE		18voidimage_setedges(IMAGE * image,			   uint32_t edged_width,			   uint32_t edged_height,			   uint32_t width,			   uint32_t height,			   int bs_version){	const uint32_t edged_width2 = edged_width / 2;	uint32_t width2;	uint32_t i;	uint8_t *dst;	uint8_t *src;	dst = image->y - (EDGE_SIZE + EDGE_SIZE * edged_width);	src = image->y;	/* According to the Standard Clause 7.6.4, padding is done starting at 16	 * pixel width and height multiples. This was not respected in old xvids */	if (bs_version == 0 || bs_version >= SETEDGES_BUG_BEFORE) {		width  = (width+15)&~15;		height = (height+15)&~15;	}	width2 = width/2;	for (i = 0; i < EDGE_SIZE; i++) {		memset(dst, *src, EDGE_SIZE);		memcpy(dst + EDGE_SIZE, src, width);		memset(dst + edged_width - EDGE_SIZE, *(src + width - 1),			   EDGE_SIZE);		dst += edged_width;	}	for (i = 0; i < height; i++) {		memset(dst, *src, EDGE_SIZE);		memset(dst + edged_width - EDGE_SIZE, src[width - 1], EDGE_SIZE);		dst += edged_width;		src += edged_width;	}	src -= edged_width;	for (i = 0; i < EDGE_SIZE; i++) {		memset(dst, *src, EDGE_SIZE);		memcpy(dst + EDGE_SIZE, src, width);		memset(dst + edged_width - EDGE_SIZE, *(src + width - 1),				   EDGE_SIZE);		dst += edged_width;	}	/* U */	dst = image->u - (EDGE_SIZE2 + EDGE_SIZE2 * edged_width2);	src = image->u;	for (i = 0; i < EDGE_SIZE2; i++) {		memset(dst, *src, EDGE_SIZE2);		memcpy(dst + EDGE_SIZE2, src, width2);		memset(dst + edged_width2 - EDGE_SIZE2, *(src + width2 - 1),			   EDGE_SIZE2);		dst += edged_width2;	}	for (i = 0; i < height / 2; i++) {		memset(dst, *src, EDGE_SIZE2);		memset(dst + edged_width2 - EDGE_SIZE2, src[width2 - 1], EDGE_SIZE2);		dst += edged_width2;		src += edged_width2;	}	src -= edged_width2;	for (i = 0; i < EDGE_SIZE2; i++) {		memset(dst, *src, EDGE_SIZE2);		memcpy(dst + EDGE_SIZE2, src, width2);		memset(dst + edged_width2 - EDGE_SIZE2, *(src + width2 - 1),			   EDGE_SIZE2);		dst += edged_width2;	}	/* V */	dst = image->v - (EDGE_SIZE2 + EDGE_SIZE2 * edged_width2);	src = image->v;	for (i = 0; i < EDGE_SIZE2; i++) {		memset(dst, *src, EDGE_SIZE2);		memcpy(dst + EDGE_SIZE2, src, width2);		memset(dst + edged_width2 - EDGE_SIZE2, *(src + width2 - 1),			   EDGE_SIZE2);		dst += edged_width2;	}	for (i = 0; i < height / 2; i++) {		memset(dst, *src, EDGE_SIZE2);		memset(dst + edged_width2 - EDGE_SIZE2, src[width2 - 1], EDGE_SIZE2);		dst += edged_width2;		src += edged_width2;	}	src -= edged_width2;	for (i = 0; i < EDGE_SIZE2; i++) {		memset(dst, *src, EDGE_SIZE2);		memcpy(dst + EDGE_SIZE2, src, width2);		memset(dst + edged_width2 - EDGE_SIZE2, *(src + width2 - 1),			   EDGE_SIZE2);		dst += edged_width2;	}}/* bframe encoding requires image-based u,v interpolation */voidimage_interpolate(const IMAGE * refn,				  IMAGE * refh,				  IMAGE * refv,				  IMAGE * refhv,				  uint32_t edged_width,				  uint32_t edged_height,				  uint32_t quarterpel,				  uint32_t rounding){	const uint32_t offset = EDGE_SIZE2 * (edged_width + 1); /* we only interpolate half of the edge area */	const uint32_t stride_add = 7 * edged_width;#if 0	const uint32_t edged_width2 = edged_width / 2;	const uint32_t edged_height2 = edged_height / 2;	const uint32_t offset2 = EDGE_SIZE2 * (edged_width2 + 1);	const uint32_t stride_add2 = 7 * edged_width2;#endif	uint8_t *n_ptr, *h_ptr, *v_ptr, *hv_ptr;	uint32_t x, y;	n_ptr = refn->y;	h_ptr = refh->y;	v_ptr = refv->y;	n_ptr -= offset;	h_ptr -= offset;	v_ptr -= offset;	/* Note we initialize the hv pointer later, as we can optimize code a bit	 * doing it down to up in quarterpel and up to down in halfpel */	if(quarterpel) {		for (y = 0; y < (edged_height - EDGE_SIZE); y += 8) {			for (x = 0; x < (edged_width - EDGE_SIZE); x += 8) {				interpolate8x8_6tap_lowpass_h(h_ptr, n_ptr, edged_width, rounding);				interpolate8x8_6tap_lowpass_v(v_ptr, n_ptr, edged_width, rounding);				n_ptr += 8;				h_ptr += 8;				v_ptr += 8;			}			n_ptr += EDGE_SIZE;			h_ptr += EDGE_SIZE;			v_ptr += EDGE_SIZE;			h_ptr += stride_add;			v_ptr += stride_add;			n_ptr += stride_add;		}		h_ptr = refh->y + (edged_height - EDGE_SIZE - EDGE_SIZE2)*edged_width - EDGE_SIZE2;		hv_ptr = refhv->y + (edged_height - EDGE_SIZE - EDGE_SIZE2)*edged_width - EDGE_SIZE2;		for (y = 0; y < (edged_height - EDGE_SIZE); y = y + 8) {			hv_ptr -= stride_add;			h_ptr -= stride_add;			hv_ptr -= EDGE_SIZE;			h_ptr -= EDGE_SIZE;			for (x = 0; x < (edged_width - EDGE_SIZE); x = x + 8) {				hv_ptr -= 8;				h_ptr -= 8;				interpolate8x8_6tap_lowpass_v(hv_ptr, h_ptr, edged_width, rounding);			}		}	} else {		hv_ptr = refhv->y;		hv_ptr -= offset;		for (y = 0; y < (edged_height - EDGE_SIZE); y += 8) {			for (x = 0; x < (edged_width - EDGE_SIZE); x += 8) {				interpolate8x8_halfpel_h(h_ptr, n_ptr, edged_width, rounding);				interpolate8x8_halfpel_v(v_ptr, n_ptr, edged_width, rounding);				interpolate8x8_halfpel_hv(hv_ptr, n_ptr, edged_width, rounding);				n_ptr += 8;				h_ptr += 8;				v_ptr += 8;				hv_ptr += 8;			}			h_ptr += EDGE_SIZE;			v_ptr += EDGE_SIZE;			hv_ptr += EDGE_SIZE;			n_ptr += EDGE_SIZE;			h_ptr += stride_add;			v_ptr += stride_add;			hv_ptr += stride_add;			n_ptr += stride_add;		}	}/*#ifdef BFRAMES	n_ptr = refn->u;	h_ptr = refh->u;	v_ptr = refv->u;	hv_ptr = refhv->u;	n_ptr -= offset2;	h_ptr -= offset2;	v_ptr -= offset2;	hv_ptr -= offset2;	for (y = 0; y < edged_height2; y += 8) {		for (x = 0; x < edged_width2; x += 8) {			interpolate8x8_halfpel_h(h_ptr, n_ptr, edged_width2, rounding);			interpolate8x8_halfpel_v(v_ptr, n_ptr, edged_width2, rounding);			interpolate8x8_halfpel_hv(hv_ptr, n_ptr, edged_width2, rounding);			n_ptr += 8;			h_ptr += 8;			v_ptr += 8;			hv_ptr += 8;		}		h_ptr += stride_add2;		v_ptr += stride_add2;		hv_ptr += stride_add2;		n_ptr += stride_add2;	}	n_ptr = refn->v;	h_ptr = refh->v;	v_ptr = refv->v;	hv_ptr = refhv->v;	n_ptr -= offset2;	h_ptr -= offset2;	v_ptr -= offset2;	hv_ptr -= offset2;	for (y = 0; y < edged_height2; y = y + 8) {		for (x = 0; x < edged_width2; x = x + 8) {			interpolate8x8_halfpel_h(h_ptr, n_ptr, edged_width2, rounding);			interpolate8x8_halfpel_v(v_ptr, n_ptr, edged_width2, rounding);			interpolate8x8_halfpel_hv(hv_ptr, n_ptr, edged_width2, rounding);			n_ptr += 8;			h_ptr += 8;			v_ptr += 8;			hv_ptr += 8;		}		h_ptr += stride_add2;		v_ptr += stride_add2;		hv_ptr += stride_add2;		n_ptr += stride_add2;	}#endif*/	/*	   interpolate_halfpel_h(	   refh->y - offset,	   refn->y - offset,	   edged_width, edged_height,	   rounding);	   interpolate_halfpel_v(	   refv->y - offset,	   refn->y - offset,	   edged_width, edged_height,	   rounding);	   interpolate_halfpel_hv(	   refhv->y - offset,	   refn->y - offset,	   edged_width, edged_height,	   rounding);	 */	/* uv-image-based compensation	   offset = EDGE_SIZE2 * (edged_width / 2 + 1);	   interpolate_halfpel_h(	   refh->u - offset,	   refn->u - offset,	   edged_width / 2, edged_height / 2,	   rounding);	   interpolate_halfpel_v(	   refv->u - offset,	   refn->u - offset,	   edged_width / 2, edged_height / 2,	   rounding);	   interpolate_halfpel_hv(	   refhv->u - offset,	   refn->u - offset,	   edged_width / 2, edged_height / 2,	   rounding);	   interpolate_halfpel_h(	   refh->v - offset,	   refn->v - offset,	   edged_width / 2, edged_height / 2,	   rounding);	   interpolate_halfpel_v(	   refv->v - offset,	   refn->v - offset,	   edged_width / 2, edged_height / 2,	   rounding);	   interpolate_halfpel_hv(	   refhv->v - offset,	   refn->v - offset,	   edged_width / 2, edged_height / 2,	   rounding);	 */}/*chroma optimize filter, invented by mfa chroma pixel is average from the surrounding pixels, when thecorrepsonding luma pixels are pure black or white.*/voidimage_chroma_optimize(IMAGE * img, int width, int height, int edged_width){	int x,y;	int pixels = 0;	for (y = 1; y < height/2 - 1; y++)	for (x = 1; x < width/2 - 1; x++)	{#define IS_PURE(a)  ((a)<=16||(a)>=235)#define IMG_Y(Y,X)	img->y[(Y)*edged_width + (X)]#define IMG_U(Y,X)	img->u[(Y)*edged_width/2 + (X)]#define IMG_V(Y,X)	img->v[(Y)*edged_width/2 + (X)]		if (IS_PURE(IMG_Y(y*2  ,x*2  )) &&			IS_PURE(IMG_Y(y*2  ,x*2+1)) &&			IS_PURE(IMG_Y(y*2+1,x*2  )) &&			IS_PURE(IMG_Y(y*2+1,x*2+1)))		{			IMG_U(y,x) = (IMG_U(y,x-1) + IMG_U(y-1, x) + IMG_U(y, x+1) + IMG_U(y+1, x)) / 4;			IMG_V(y,x) = (IMG_V(y,x-1) + IMG_V(y-1, x) + IMG_V(y, x+1) + IMG_V(y+1, x)) / 4;			pixels++;		}#undef IS_PURE#undef IMG_Y#undef IMG_U#undef IMG_V	}	DPRINTF(XVID_DEBUG_DEBUG,"chroma_optimized_pixels = %i/%i\n", pixels, width*height/4);}/*  perform safe packed colorspace conversion, by splitting  the image up into an optimized area (pixel width divisible by 16),  and two unoptimized/plain-c areas (pixel width divisible by 2)*/static voidsafe_packed_conv(uint8_t * x_ptr, int x_stride,				 uint8_t * y_ptr, uint8_t * u_ptr, uint8_t * v_ptr,				 int y_stride, int uv_stride,				 int width, int height, int vflip,				 packedFunc * func_opt, packedFunc func_c, int size){	int width_opt, width_c;	if (func_opt != func_c && x_stride < size*((width+15)/16)*16)	{		width_opt = width & (~15);		width_c = width - width_opt;	}	else	{		width_opt = width;		width_c = 0;	}	func_opt(x_ptr, x_stride,			y_ptr, u_ptr, v_ptr, y_stride, uv_stride,			width_opt, height, vflip);	if (width_c)	{		func_c(x_ptr + size*width_opt, x_stride,			y_ptr + width_opt, u_ptr + width_opt/2, v_ptr + width_opt/2,			y_stride, uv_stride, width_c, height, vflip);	}}intimage_input(IMAGE * image,			uint32_t width,			int height,			uint32_t edged_width,			uint8_t * src[4],			int src_stride[4],			int csp,			int interlacing){	const int edged_width2 = edged_width/2;	const int width2 = width/2;	const int height2 = height/2;#if 0	const int height_signed = (csp & XVID_CSP_VFLIP) ? -height : height;#endif	switch (csp & ~XVID_CSP_VFLIP) {	case XVID_CSP_RGB555:		safe_packed_conv(			src[0], src_stride[0], image->y, image->u, image->v,			edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP),			interlacing?rgb555i_to_yv12  :rgb555_to_yv12,			interlacing?rgb555i_to_yv12_c:rgb555_to_yv12_c, 2);		break;	case XVID_CSP_RGB565:		safe_packed_conv(			src[0], src_stride[0], image->y, image->u, image->v,			edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP),			interlacing?rgb565i_to_yv12  :rgb565_to_yv12,			interlacing?rgb565i_to_yv12_c:rgb565_to_yv12_c, 2);

⌨️ 快捷键说明

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