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

📄 y4mshift.c

📁 Motion JPEG编解码器源代码
💻 C
字号:
/* * $Id: y4mshift.c,v 1.13 2004/04/05 17:07:34 sms00 Exp $ * * written by Steven M. Schultz <sms@2BSD.COM> * * 2003/5/8 - added the ability to place a black border around the frame. *	The -b usage is the same as for yuvdenoise.   This is a useful  *	feature when yuvdenoise or other programs are not being used but a *	border is still desired. * * Simple program to shift the data an even number of pixels.   The shift count * is positive for shifting to the right and negative for a left shift.    * * Usage: y4mshift -n N [ -b xoffset,yoffset,xsize,ysize ] * * No file arguments are needed since this is a filter only program.*/#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <stdio.h>#include <sys/types.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#include "yuv4mpeg.h"extern  char    *__progname;#define HALFSHIFT (shiftnum / SS_H)	void	black_border(u_char **, char *, int, int, int, int);	void	vertical_shift(u_char **, int, int, int, int, int, int);static  void    usage(void);int main(int argc, char **argv)        {        int     i, c, width, height, frames, err, chroma_ss, ilace_factor;        int     shiftnum = 0, shiftY = 0, rightshiftY, rightshiftUV;        int     vshift = 0, vshiftY = 0, monochrome = 0;        int     verbose = 0, fdin;        int     SS_H = 2, SS_V = 2;        u_char  *yuv[3], *line;	char	*borderarg = NULL;        y4m_stream_info_t istream, ostream;        y4m_frame_info_t iframe;        fdin = fileno(stdin);	y4m_accept_extensions(1);        opterr = 0;        while   ((c = getopt(argc, argv, "hvn:N:b:My:Y:")) != EOF)                {                switch  (c)                        {			case	'M':				monochrome = 1;				break;			case	'b':				borderarg = strdup(optarg);				break;                        case    'n':                                shiftnum = atoi(optarg);                                break;                        case    'y':                                shiftY = atoi(optarg);                                break;                        case    'Y':                                vshiftY = atoi(optarg);                                break;			case	'N':				vshift = atoi(optarg);				break;                        case    'v':                                verbose++;                                break;                        case    '?':                        case    'h':                        default:                                usage();                        }                }	if      ( shiftnum + shiftY > 0 )		rightshiftY = 1;	else		rightshiftY = 0;	shiftY = abs(shiftnum + shiftY);  /* now shiftY is total Y shift */        if      (shiftnum > 0)                rightshiftUV = 1;        else                {                rightshiftUV = 0;                shiftnum = abs(shiftnum);                }        y4m_init_stream_info(&istream);        y4m_init_frame_info(&iframe);        err = y4m_read_stream_header(fdin, &istream);        if      (err != Y4M_OK)                mjpeg_error_exit1("Input stream error: %s\n", y4m_strerr(err));	if	(y4m_si_get_plane_count(&istream) != 3)		mjpeg_error_exit1("Only 3 plane formats supported");	chroma_ss = y4m_si_get_chroma(&istream);	SS_H = y4m_chroma_ss_x_ratio(chroma_ss).d;	SS_V = y4m_chroma_ss_y_ratio(chroma_ss).d;	if	(y4m_si_get_interlace(&istream) == Y4M_ILACE_NONE)		ilace_factor = 1;	else		ilace_factor = 2;        if      ((shiftnum % SS_H) != 0)                usage();        if      ((vshift % (ilace_factor * SS_V)) != 0)                usage();        width = y4m_si_get_width(&istream);        height = y4m_si_get_height(&istream);        if      (shiftnum > width / 2)                mjpeg_error_exit1("nonsense to shift %d out of %d",                        shiftnum, width);        if      (shiftY > width / 2)                mjpeg_error_exit1("nonsense to shift %d out of %d\n",                        shiftY, width);        y4m_init_stream_info(&ostream);        y4m_copy_stream_info(&ostream, &istream);        y4m_write_stream_header(fileno(stdout), &ostream);        yuv[0] = malloc(y4m_si_get_plane_length(&istream, 0));        if      (yuv[0] == NULL)                mjpeg_error_exit1("malloc() failed for plane 0");        yuv[1] = malloc(y4m_si_get_plane_length(&istream, 1));        if      (yuv[1] == NULL)                mjpeg_error_exit1("malloc() failed for plane 1");        yuv[2] = malloc(y4m_si_get_plane_length(&istream, 2));        if      (yuv[2] == NULL)                mjpeg_error_exit1("malloc() failed for plane 2");        if      (verbose)		y4m_log_stream_info(LOG_INFO, "", &istream);        frames = 0;        for     (;y4m_read_frame(fdin,&istream,&iframe,yuv) == Y4M_OK; frames++)                {                if      (shiftnum == 0 && shiftY == 0)                        goto outputframe;                for     (i = 0; i < height; i++)                        {/* * Y*/                        line = &yuv[0][i * width];                        if      (rightshiftY)                                {                                bcopy(line, line + shiftY, width - shiftY);                                memset(line, 16, shiftY); /* black */                                }                        else                                 {                                bcopy(line + shiftY, line, width - shiftY);                                memset(line + width - shiftY, 16, shiftY);                                }                        }/* * U*/                for     (i = 0; i < height / SS_V; i++)                        {                        line = &yuv[1][i * (width / SS_H)];                        if      (rightshiftUV)                                {                                bcopy(line, line+HALFSHIFT, (width-shiftnum)/SS_H);                                memset(line, 128, HALFSHIFT); /* black */                                }                        else                                {                                bcopy(line+HALFSHIFT, line, (width-shiftnum)/SS_H);                                memset(line+(width-shiftnum)/SS_H, 128, HALFSHIFT);                                }                        }/* * V*/                for     (i = 0; i < height / SS_V; i++)                        {                        line = &yuv[2][i  * (width / SS_H)];                        if      (rightshiftUV)                                {                                bcopy(line, line+HALFSHIFT, (width-shiftnum)/SS_H);                                memset(line, 128, HALFSHIFT); /* black */                                }                        else                                {                                bcopy(line+HALFSHIFT, line, (width-shiftnum)/SS_H);                                memset(line+(width-shiftnum)/SS_H, 128, HALFSHIFT);                                }                        }outputframe:		if	(vshift)			vertical_shift(yuv, vshift, vshiftY, width, height, SS_H, SS_V);		if	(borderarg)			black_border(yuv, borderarg, width, height, SS_H, SS_V);		if	(monochrome)			{			memset(&yuv[1][0], 128, (width / SS_H) * (height / SS_V));			memset(&yuv[2][0], 128, (width / SS_H) * (height / SS_V));			}                y4m_write_frame(fileno(stdout), &ostream, &iframe, yuv);                }        y4m_fini_frame_info(&iframe);        y4m_fini_stream_info(&istream);        y4m_fini_stream_info(&ostream);        exit(0);        }/* * -b Xoff,Yoff,Xsize,YSize*/void black_border (u_char *yuv[], char *borderstring, int W, int H, int SS_H, int SS_V)	{	static	int parsed = -1;	static	int BX0, BX1;	/* Left, Right border columns */	static	int BY0, BY1;	/* Top, Bottom border rows */	int	i1, i2, i, dy, W2, H2;  	if	(parsed == -1)		{		parsed = 0;		i = sscanf(borderstring, "%d,%d,%d,%d", &BX0, &BY0, &i1, &i2);		if	(i != 4 || (BX0 % SS_H) || (BY0 % (2*SS_V)) || i1 < 0 || i2 < 0 ||			 (BX0 + i1 > W) || (BY0 + i2 > H))			{			mjpeg_log(LOG_WARN, " border args invalid - ignored");			return;			}		BX1 = BX0 + i1;		BY1 = BY0 + i2;		parsed = 1;		}/* * If a borderstring was seen but declared invalid then it * is being ignored so just return.*/	if	(parsed == 0)		return;	W2 = W / SS_H;	H2 = H / SS_V;/* * Yoff Lines at the top.   If the vertical offset is 0 then no top border * is being requested and there is nothing to do.*/	if	(BY0 != 0)		{		memset(yuv[0], 16,  W  * BY0);		memset(yuv[1], 128, W2 * BY0/SS_V);		memset(yuv[2], 128, W2 * BY0/SS_V);		}/* * Height - (Ysize + Yoff) lines at bottom.   If the bottom coincides with * the frame size then there is nothing to do.*/	if	(H != BY1)		{		memset(&yuv[0][BY1 * W], 16, W  * (H - BY1));		memset(&yuv[1][(BY1 / SS_V) * W2], 128, W2 * (H - BY1)/SS_V);		memset(&yuv[2][(BY1 / SS_V) * W2], 128, W2 * (H - BY1)/SS_V);		}/* * Now the partial lines in the middle.   Go from rows BY0 thru BY1 because * the whole rows (0 thru BY0) and (BY1 thru H) have been done above.*/	for	(dy = BY0; dy < BY1; dy++)		{/* * First the columns on the left (x = 0 thru BX0).   If the X offset is 0 * then there is nothing to do.*/		if	(BX0 != 0)			{			memset(&yuv[0][dy * W], 16, BX0);			memset(&yuv[1][dy / SS_V * W2], 128, BX0 / SS_H);			memset(&yuv[2][dy / SS_V * W2], 128, BX0 / SS_H);			}/* * Then the columns on the right (x = BX1 thru W).   If the right border * start coincides with the frame size then there is nothing to do.*/		if	(W != BX1)			{			memset(&yuv[0][(dy * W) + BX1], 16, W - BX1);			memset(&yuv[1][(dy/SS_V * W2) + BX1/SS_H], 128, (W - BX1)/SS_H);			memset(&yuv[2][(dy/SS_V * W2) + BX1/SS_H], 128, (W - BX1)/SS_H);			}		}	}void vertical_shift(u_char **yuv, int vshift, int vshiftY, int width, int height, int SS_H, int SS_V)	{	int	downshiftY, downshiftUV, w2 = width / SS_H, v2;	if      ( vshift + vshiftY > 0 )		downshiftY = 1;	else		downshiftY = 0;	vshiftY = abs(vshift + vshiftY);  /* now shiftY is total Y shift */	if	(vshift > 0)		downshiftUV = 1;	else		{		downshiftUV = 0;		vshift = abs(vshift);		}	v2 = vshift / SS_V;	if	(downshiftY)		{		memmove(&yuv[0][vshiftY * width], &yuv[0][0],			(height - vshiftY) * width);		memset(&yuv[0][0], 16, vshiftY * width);		}	else		{		memmove(&yuv[0][0], &yuv[0][vshiftY * width],			(height - vshiftY) * width);		memset(&yuv[0][(height - vshiftY) * width], 16, vshiftY * width);		}	if      (downshiftUV)	        {		memmove( &yuv[1][v2 * w2], &yuv[1][0],			(height - vshift) / SS_V * w2);		memmove( &yuv[2][v2 * w2], &yuv[2][0],			(height - vshift) / SS_V * w2);		memset(&yuv[1][0], 128, v2 * w2);		memset(&yuv[2][0], 128, v2 * w2);		}	else		{		memmove(&yuv[1][0], &yuv[1][v2 * w2],			(height - vshift) / SS_V * w2);		memmove(&yuv[2][0], &yuv[2][v2 * w2],			(height - vshift) / SS_V * w2);		memset(&yuv[1][((height - vshift) / SS_V) * w2], 128, v2 * w2);		memset(&yuv[2][((height - vshift) / SS_V) * w2], 128, v2 * w2);		}	}static void usage(void)        {        fprintf(stderr, "%s: usage: [-v] [-h] [-M] [-b xoff,yoff,xsize,ysize] [-y num] [-Y num] [-N num] -n N\n", __progname);	fprintf(stderr, "%s:\t-M = monochrome output\n", __progname);        fprintf(stderr, "%s:\t-n N = horizontal shift count - must be multiple of 2 for 4:2:0, multiple of 4 for 4:1:1!\n", __progname);        fprintf(stderr, "%s:\t-y num = Y-only horizontal shift count - need not be even\n", __progname);        fprintf(stderr, "%s:\t\tpositive count shifts right\n",__progname);        fprintf(stderr, "%s:\t\t0 passes the data thru unchanged\n",__progname);        fprintf(stderr, "%s:\t\tnegative count shifts left\n", __progname);	fprintf(stderr, "%s:\t-N num = vertical shift count - must be multiple of 4 for 4:2:0, multiple of 2 for 4:1:1!\n", __progname);	fprintf(stderr, "%s:\t-Y num = Y-only vertical shift count - multiple of 2 for interlaced material\n", __progname);	fprintf(stderr, "%s:\t\tnegative count shifts up\n", __progname);	fprintf(stderr, "%s:\t\t0 does no vertical shift (is ignored)\n", __progname);	fprintf(stderr, "%s:\t\tpositive count shifts down\n", __progname);	fprintf(stderr, "%s:\t-b creates black border\n", __progname);	fprintf(stderr, "%s:\t\tusage is same as yuvdenoise.\n", __progname);	fprintf(stderr, "%s:\tShifting is done before border creation\n", __progname);        fprintf(stderr, "%s:\t-v print input stream info\n", __progname);        fprintf(stderr, "%s:\t-h print this usage summary\n", __progname);        exit(1);        }

⌨️ 快捷键说明

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