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

📄 colorspace.c

📁 网络MPEG4IP流媒体开发源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/************************************************************************** * *	XVID MPEG-4 VIDEO CODEC *	colorspace conversions * *	This program is an implementation of a part of one or more MPEG-4 *	Video tools as specified in ISO/IEC 14496-2 standard.  Those intending *	to use this software module in hardware or software products are *	advised that its use may infringe existing patents or copyrights, and *	any such use would be at such party's own risk.  The original *	developer of this software module and his/her company, and subsequent *	editors and their companies, will have no liability for use of this *	software or modifications or derivatives thereof. * *	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., 675 Mass Ave, Cambridge, MA 02139, USA. * *************************************************************************//************************************************************************** * *	History: * *	30.02.2002	out_yuv dst_stride2 fix *	26.02.2002	rgb555, rgb565 *	24.11.2001	accuracy improvement to yuyv/vyuy conversion *	28.10.2001	total rewrite <pross@cs.rmit.edu.au> * **************************************************************************/#include <string.h>		// memcpy#include "colorspace.h"// function pointers/* input */color_inputFuncPtr rgb555_to_yv12;color_inputFuncPtr rgb565_to_yv12;color_inputFuncPtr rgb24_to_yv12;color_inputFuncPtr rgb32_to_yv12;color_inputFuncPtr yuv_to_yv12;color_inputFuncPtr yuyv_to_yv12;color_inputFuncPtr uyvy_to_yv12;/* output */color_outputFuncPtr yv12_to_rgb555;color_outputFuncPtr yv12_to_rgb565;color_outputFuncPtr yv12_to_rgb24;color_outputFuncPtr yv12_to_rgb32;color_outputFuncPtr yv12_to_yuv;color_outputFuncPtr yv12_to_yuyv;color_outputFuncPtr yv12_to_uyvy;#ifndef MIN#define MIN(A,B)	((A)<(B)?(A):(B))#define MAX(A,B)	((A)>(B)?(A):(B))#endif/*	rgb -> yuv def's	this following constants are "official spec"	Video Demystified" (ISBN 1-878707-09-4)	rgb<->yuv _is_ lossy, since most programs do the conversion differently			SCALEBITS/FIX taken from  ffmpeg*/#define Y_R_IN			0.257#define Y_G_IN			0.504#define Y_B_IN			0.098#define Y_ADD_IN		16#define U_R_IN			0.148#define U_G_IN			0.291#define U_B_IN			0.439#define U_ADD_IN		128#define V_R_IN			0.439#define V_G_IN			0.368#define V_B_IN			0.071#define V_ADD_IN		128#define SCALEBITS_IN	8#define FIX_IN(x)		((uint16_t) ((x) * (1L<<SCALEBITS_IN) + 0.5))int32_t RGB_Y_tab[256];int32_t B_U_tab[256];int32_t G_U_tab[256];int32_t G_V_tab[256];int32_t R_V_tab[256];/* rgb555 -> yuv 4:2:0 planar */void rgb555_to_yv12_c(uint8_t *y_out, uint8_t *u_out, uint8_t *v_out,					uint8_t *src, int width, int height, int y_stride){	int32_t src_stride = width * 2;	uint32_t y_dif = y_stride - width;	uint32_t uv_dif = (y_stride - width) / 2;	uint32_t x, y;	if (height < 0)	{		height = -height;		src += (height - 1) * src_stride;		src_stride = -src_stride;	}		for (y = height / 2; y; y--) 	{		// process one 2x2 block per iteration		for (x = 0; x < (uint32_t)width; x += 2)		{			int rgb, r, g, b, r4, g4, b4;			rgb = *(uint16_t*)(src+x*2);			b4 = b = (rgb << 3) & 0xf8;			g4 = g = (rgb >> 2) & 0xf8;			r4 = r = (rgb >> 7) & 0xf8;            y_out[0] =(uint8_t)((						  FIX_IN(Y_R_IN) * r 						+ FIX_IN(Y_G_IN) * g 						+ FIX_IN(Y_B_IN) * b) >> SCALEBITS_IN) + Y_ADD_IN;			rgb = *(uint16_t*)(src+x*2+src_stride);			b4 += b = (rgb << 3) & 0xf8;			g4 += g = (rgb >> 2) & 0xf8;			r4 += r = (rgb >> 7) & 0xf8;            y_out[y_stride] =(uint8_t)((						  FIX_IN(Y_R_IN) * r 						+ FIX_IN(Y_G_IN) * g 						+ FIX_IN(Y_B_IN) * b) >> SCALEBITS_IN) + Y_ADD_IN;			rgb = *(uint16_t*)(src+x*2+2);			b4 += b = (rgb << 3) & 0xf8;			g4 += g = (rgb >> 2) & 0xf8;			r4 += r = (rgb >> 7) & 0xf8;            y_out[1] =(uint8_t)((						  FIX_IN(Y_R_IN) * r 						+ FIX_IN(Y_G_IN) * g 						+ FIX_IN(Y_B_IN) * b) >> SCALEBITS_IN) + Y_ADD_IN;			rgb = *(uint16_t*)(src+x*2+src_stride+2);			b4 += b = (rgb << 3) & 0xf8;			g4 += g = (rgb >> 2) & 0xf8;			r4 += r = (rgb >> 7) & 0xf8;            y_out[y_stride + 1] =(uint8_t)((						  FIX_IN(Y_R_IN) * r 						+ FIX_IN(Y_G_IN) * g 						+ FIX_IN(Y_B_IN) * b) >> SCALEBITS_IN) + Y_ADD_IN;			*u_out++ = (uint8_t)((						- FIX_IN(U_R_IN) * r4 						- FIX_IN(U_G_IN) * g4						+ FIX_IN(U_B_IN) * b4) >> (SCALEBITS_IN + 2)) + U_ADD_IN;						            *v_out++ = (uint8_t)((						  FIX_IN(V_R_IN) * r4						- FIX_IN(V_G_IN) * g4						- FIX_IN(V_B_IN) * b4) >> (SCALEBITS_IN + 2)) + V_ADD_IN; 			y_out += 2;		}		src += src_stride * 2;		y_out += y_dif + y_stride;		u_out += uv_dif;		v_out += uv_dif;	}}/* rgb565_to_yuv_c	NOTE:	identical to rgb555 except for shift/mask 			not tested */void rgb565_to_yv12_c(uint8_t *y_out, uint8_t *u_out, uint8_t *v_out,					uint8_t *src, int width, int height, int y_stride){	int32_t src_stride = width * 2;	uint32_t y_dif = y_stride - width;	uint32_t uv_dif = (y_stride - width) / 2;	uint32_t x, y;	if (height < 0)	{		height = -height;		src += (height - 1) * src_stride;		src_stride = -src_stride;	}		for (y = height / 2; y; y--) 	{		// process one 2x2 block per iteration		for (x = 0; x < (uint32_t)width; x += 2)		{			int rgb, r, g, b, r4, g4, b4;			rgb = *(uint16_t*)(src+x*2);			b4 = b = (rgb << 3) & 0xf8;			g4 = g = (rgb >> 3) & 0xfc;			r4 = r = (rgb >> 8) & 0xf8;            y_out[0] =(uint8_t)((						  FIX_IN(Y_R_IN) * r 						+ FIX_IN(Y_G_IN) * g 						+ FIX_IN(Y_B_IN) * b) >> SCALEBITS_IN) + Y_ADD_IN;			rgb = *(uint16_t*)(src+x*2+src_stride);			b4 += b = (rgb << 3) & 0xf8;			g4 += g = (rgb >> 3) & 0xfc;			r4 += r = (rgb >> 8) & 0xf8;            y_out[y_stride] =(uint8_t)((						  FIX_IN(Y_R_IN) * r 						+ FIX_IN(Y_G_IN) * g 						+ FIX_IN(Y_B_IN) * b) >> SCALEBITS_IN) + Y_ADD_IN;			rgb = *(uint16_t*)(src+x*2+2);			b4 += b = (rgb << 3) & 0xf8;			g4 += g = (rgb >> 3) & 0xfc;			r4 += r = (rgb >> 8) & 0xf8;            y_out[1] =(uint8_t)((						  FIX_IN(Y_R_IN) * r 						+ FIX_IN(Y_G_IN) * g 						+ FIX_IN(Y_B_IN) * b) >> SCALEBITS_IN) + Y_ADD_IN;			rgb = *(uint16_t*)(src+x*2+src_stride+2);			b4 += b = (rgb << 3) & 0xf8;			g4 += g = (rgb >> 3) & 0xfc;			r4 += r = (rgb >> 8) & 0xf8;            y_out[y_stride + 1] =(uint8_t)((						  FIX_IN(Y_R_IN) * r 						+ FIX_IN(Y_G_IN) * g 						+ FIX_IN(Y_B_IN) * b) >> SCALEBITS_IN) + Y_ADD_IN;			*u_out++ = (uint8_t)((						- FIX_IN(U_R_IN) * r4 						- FIX_IN(U_G_IN) * g4						+ FIX_IN(U_B_IN) * b4) >> (SCALEBITS_IN + 2)) + U_ADD_IN;						            *v_out++ = (uint8_t)((						  FIX_IN(V_R_IN) * r4						- FIX_IN(V_G_IN) * g4						- FIX_IN(V_B_IN) * b4) >> (SCALEBITS_IN + 2)) + V_ADD_IN; 			y_out += 2;		}		src += src_stride * 2;		y_out += y_dif + y_stride;		u_out += uv_dif;		v_out += uv_dif;	}}/*	rgb24 -> yuv 4:2:0 planar 	NOTE: always flips.*/void rgb24_to_yv12_c(uint8_t *y_out, uint8_t *u_out, uint8_t *v_out,					uint8_t *src, int width, int height, int stride){    uint32_t width3 = (width << 1) + width;		/* width * 3 */	uint32_t src_dif = (width << 3) + width;		/* width3 * 3 */	uint32_t y_dif = (stride << 1) - width;	uint32_t uv_dif = (stride - width) >> 1;    uint32_t x, y;	src += (height - 2) * width3;		    for(y = height >> 1; y; y--) {		for(x = width >> 1; x; x--) {			uint32_t r, g, b, r4, g4, b4;            b4 = b = src[0];            g4 = g = src[1];            r4 = r = src[2];            y_out[stride + 0] =(uint8_t)((						  FIX_IN(Y_R_IN) * r 						+ FIX_IN(Y_G_IN) * g 						+ FIX_IN(Y_B_IN) * b) >> SCALEBITS_IN) + Y_ADD_IN;             b4 += (b = src[3]);            g4 += (g = src[4]);            r4 += (r = src[5]);            y_out[stride + 1] = (uint8_t)((						  FIX_IN(Y_R_IN) * r 						+ FIX_IN(Y_G_IN) * g 						+ FIX_IN(Y_B_IN) * b) >> SCALEBITS_IN) + Y_ADD_IN;            b4 += (b = src[width3 + 0]);            g4 += (g = src[width3 + 1]);            r4 += (r = src[width3 + 2]);            y_out[0] = (uint8_t)((						FIX_IN(Y_R_IN) * r + 						FIX_IN(Y_G_IN) * g + 						FIX_IN(Y_B_IN) * b) >> SCALEBITS_IN) + Y_ADD_IN;            b4 += (b = src[width3 + 3]);            g4 += (g = src[width3 + 4]);            r4 += (r = src[width3 + 5]);            y_out[1] = (uint8_t)((						  FIX_IN(Y_R_IN) * r						+ FIX_IN(Y_G_IN) * g						+ FIX_IN(Y_B_IN) * b) >> SCALEBITS_IN) + Y_ADD_IN;            			*u_out++ = (uint8_t)((						- FIX_IN(U_R_IN) * r4 						- FIX_IN(U_G_IN) * g4						+ FIX_IN(U_B_IN) * b4) >> (SCALEBITS_IN + 2)) + U_ADD_IN;						            *v_out++ = (uint8_t)((						  FIX_IN(V_R_IN) * r4						- FIX_IN(V_G_IN) * g4						- FIX_IN(V_B_IN) * b4) >> (SCALEBITS_IN + 2)) + V_ADD_IN; 											src += 6;			y_out += 2;		}		src -= src_dif;		y_out += y_dif;		u_out += uv_dif;		v_out += uv_dif;    }}/*	rgb32 -> yuv 4:2:0 planar 	NOTE: always flips*/void rgb32_to_yv12_c(uint8_t *y_out, uint8_t *u_out, uint8_t *v_out,					uint8_t *src, int width, int height, int stride){    uint32_t width4 = (width << 2);		/* width * 4 */	uint32_t src_dif = 3 * width4;	uint32_t y_dif = (stride << 1) - width;	uint32_t uv_dif = (stride - width) >> 1;    uint32_t x, y;		src += (height - 2) * width4;    for(y = height >> 1; y; y--) {		for(x = width >> 1; x; x--) {			uint32_t r, g, b, r4, g4, b4;            b4 = b = src[0];            g4 = g = src[1];            r4 = r = src[2];            y_out[stride + 0] =(uint8_t)((						  FIX_IN(Y_R_IN) * r 						+ FIX_IN(Y_G_IN) * g 						+ FIX_IN(Y_B_IN) * b) >> SCALEBITS_IN) + Y_ADD_IN;            b4 += (b = src[4]);            g4 += (g = src[5]);            r4 += (r = src[6]);            y_out[stride + 1] =(uint8_t)((						  FIX_IN(Y_R_IN) * r 						+ FIX_IN(Y_G_IN) * g 						+ FIX_IN(Y_B_IN) * b) >> SCALEBITS_IN) + Y_ADD_IN;            b4 += (b = src[width4 + 0]);            g4 += (g = src[width4 + 1]);            r4 += (r = src[width4 + 2]);            y_out[0] =(uint8_t)((						  FIX_IN(Y_R_IN) * r 						+ FIX_IN(Y_G_IN) * g 						+ FIX_IN(Y_B_IN) * b) >> SCALEBITS_IN) + Y_ADD_IN;                        b4 += (b = src[width4 + 4]);            g4 += (g = src[width4 + 5]);            r4 += (r = src[width4 + 6]);            y_out[1] =(uint8_t)((						  FIX_IN(Y_R_IN) * r 						+ FIX_IN(Y_G_IN) * g 						+ FIX_IN(Y_B_IN) * b) >> SCALEBITS_IN) + Y_ADD_IN;            			*u_out++ = (uint8_t)((						- FIX_IN(U_R_IN) * r4 						- FIX_IN(U_G_IN) * g4						+ FIX_IN(U_B_IN) * b4) >> (SCALEBITS_IN + 2)) + U_ADD_IN;            *v_out++ = (uint8_t)((						  FIX_IN(V_R_IN) * r4						- FIX_IN(V_G_IN) * g4						- FIX_IN(V_B_IN) * b4) >> (SCALEBITS_IN + 2)) + V_ADD_IN;						src += 8;			y_out += 2;		}		src -= src_dif;		y_out += y_dif;		u_out += uv_dif;		v_out += uv_dif;    }}/*	yuv planar -> yuv 4:2:0 planar   	NOTE: does not flip */void yuv_to_yv12_c(uint8_t *y_out, uint8_t *u_out, uint8_t *v_out,				uint8_t *src, int width, int height, int stride){	uint32_t stride2 = stride >> 1;	uint32_t width2 = width >> 1;    uint32_t y;	for (y = height; y; y--)	{	    memcpy(y_out, src, width);	    src += width;		y_out += stride;	}	for (y = height >> 1; y; y--) {	    memcpy(u_out, src, width2);		src += width2;		u_out += stride2;	}	for (y = height >> 1; y; y--) {	    memcpy(v_out, src, width2);		src += width2;		v_out+= stride2;	}}#ifdef MPEG4IPvoid yuv_to_yv12_clip_c(uint8_t *y_out, uint8_t *u_out, uint8_t *v_out,				uint8_t *src, int width, int height, int raw_height, int stride){	uint32_t stride2 = stride >> 1;	uint32_t width2 = width >> 1;    uint32_t y;	uint32_t yoffset = ((raw_height - height) / 2) * width;	src += yoffset;	for (y = height; y; y--)	{	    memcpy(y_out, src, width);	    src += width;		y_out += stride;	}	src += yoffset + (yoffset / 4);	for (y = height >> 1; y; y--) {	    memcpy(u_out, src, width2);		src += width2;		u_out += stride2;	}	src += yoffset / 2;	for (y = height >> 1; y; y--) {	    memcpy(v_out, src, width2);		src += width2;		v_out+= stride2;	}}#endif/* yuyv (yuv2) packed -> yuv 4:2:0 planar      NOTE: does not flip */void yuyv_to_yv12_c(uint8_t *y_out, uint8_t *u_out, uint8_t *v_out,					uint8_t *src, int width, int height, int stride){	uint32_t width2 = width + width;	uint32_t y_dif = stride - width;	uint32_t uv_dif = y_dif >> 1;	uint32_t x, y;	for (y = height >> 1; y; y--) {        		for (x = width >> 1; x; x--) {            *y_out++ = *src++;			//*u_out++ = *src++;			*u_out++ = (*(src+width2) + *src) >> 1;	src++;			*y_out++ = *src++;			//*v_out++ = *src++;			*v_out++ = (*(src+width2) + *src) >> 1; src++;					}		y_out += y_dif;		u_out += uv_dif;		v_out += uv_dif; 		for (x = width >> 1; x; x--) {			*y_out++ = *src++;			src++;			*y_out++ = *src++;			src++;		}		y_out += y_dif;    }}/* uyvy packed -> yuv 4:2:0 planar      NOTE: does not flip */void uyvy_to_yv12_c(uint8_t *y_out, uint8_t *u_out, uint8_t *v_out,					uint8_t *src, int width, int height, int stride){	uint32_t width2 = width + width;	uint32_t y_dif = stride - width;	uint32_t uv_dif = y_dif >> 1;    uint32_t x, y;	for (y = height >> 1; y; y--) {        		for (x = width >> 1; x; x--) {			*u_out++ = *src++;            // *u_out++ = (*(src+width2) + *src++) >> 1;			*y_out++ = *src++;			//*v_out++ = *src++;			*v_out++ = (*(src+width2) + *src) >> 1; src++;

⌨️ 快捷键说明

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