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

📄 yuv2yuv.c

📁 著名的 helix realplayer 基于手机 symbian 系统的 播放器全套源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* ***** BEGIN LICENSE BLOCK ***** 
 * Version: RCSL 1.0/RPSL 1.0 
 *  
 * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. 
 *      
 * The contents of this file, and the files included with this file, are 
 * subject to the current version of the RealNetworks Public Source License 
 * Version 1.0 (the "RPSL") available at 
 * http://www.helixcommunity.org/content/rpsl unless you have licensed 
 * the file under the RealNetworks Community Source License Version 1.0 
 * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, 
 * in which case the RCSL will apply. You may also obtain the license terms 
 * directly from RealNetworks.  You may not use this file except in 
 * compliance with the RPSL or, if you have a valid RCSL with RealNetworks 
 * applicable to this file, the RCSL.  Please see the applicable RPSL or 
 * RCSL for the rights, obligations and limitations governing use of the 
 * contents of the file.  
 *  
 * This file is part of the Helix DNA Technology. RealNetworks is the 
 * developer of the Original Code and owns the copyrights in the portions 
 * it created. 
 *  
 * This file, and the files included with this file, is distributed and made 
 * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
 * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 
 * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
 * 
 * Technology Compatibility Kit Test Suite(s) Location: 
 *    http://www.helixcommunity.org/content/tck 
 * 
 * Contributor(s): 
 *  
 * ***** END LICENSE BLOCK ***** */ 

/*** #includes: ********************************************/

#include "hxassert.h"

#include "env.h"
#include "yuv.h"    /* YUV-to-RGB conversion tables & macros */
#include "clip.h"   /* macros for clipping & dithering */

#include "hxassert.h"
#include "colorlib.h"


int PackedYUVMemcpyWithPitch( unsigned char *dest_ptr,
                              int dest_width, int dest_height,
                              int dest_pitch,
                              int dest_x, int dest_y, int dest_dx, int dest_dy,
                              unsigned char *src_ptr,
                              int src_width, int src_height, int src_pitch,
                              int src_x, int src_y, int src_dx, int src_dy);

/*** YUV to YUV color converters: **************************/

/*
 * These functions were borrowed from our "old" color conversion library,
 * and they do not support things like stretching or color adjustments.
 * Given some more time this module should be completely rewritten.
 *
 ***************/

static int YUY2toPlanarYUV(unsigned char *dY, unsigned char *dU, unsigned char *dV,
                           int dest_width, int dest_height,
                           int dyPitch, int duPitch, int dvPitch,
                           int dest_x, int dest_y, int dest_dx, int dest_dy,
                           unsigned char *src_ptr, int src_width, int src_height, int src_pitch,
                           int src_x, int src_y, int src_dx, int src_dy);

static int UYVYtoPlanarYUV(unsigned char *dY, unsigned char *dU, unsigned char *dV,
                           int dest_width, int dest_height,
                           int dyPitch, int duPitch, int dvPitch,
                           int dest_x, int dest_y, int dest_dx, int dest_dy,
                           unsigned char *src_ptr, int src_width, int src_height, int src_pitch,
                           int src_x, int src_y, int src_dx, int src_dy);
/*
 * Checks format conversion parameters.
 * Use:
 *  int chk_args (unsigned char *dest_ptr, int dest_width, int dest_height,
 *      int dest_pitch, int dest_x, int dest_y, int dest_dx, int dest_dy,
 *      unsigned char *src_ptr, int src_width, int src_height,
 *      int src_pitch, int src_x, int src_y, int src_dx, int src_dy,
 *      int *p_scale_x, int *p_scale_y);
 * Input:
 *  dest_ptr - pointer to a destination buffer
 *  dest_width, dest_height - width/height of the destination image (pixels)
 *  dest_pitch - pitch of the dest. buffer (in bytes; <0 - if bottom up image)
 *  dest_x, dest_y, dest_dx, dest_dy - destination rectangle (pixels)
 *  src_ptr - pointer to an input image
 *  src_width, src_height - width/height of the input image (pixels)
 *  src_pitch - pitch of the source buffer (in bytes; <0 - if bottom up image)
 *  src_x, src_y, src_dx, src_dy - source rectangle (pixels)
 * Output:
 *  p_scale_x, p_scale_y - scale factors for x,y axes
 *      (currently only 1:1, and 2:1 scale factors are allowed)
 * Returns:
 *  0 - if success; -1 if failure.
 */
static int
chk_args (unsigned char *dest_ptr, int dest_width, int dest_height,
    int dest_pitch, int dest_x, int dest_y, int dest_dx, int dest_dy,
    unsigned char *src_ptr, int src_width, int src_height,
    int src_pitch, int src_x, int src_y, int src_dx, int src_dy,
    int *p_scale_x, int *p_scale_y)
{
    /* alignments: */
    if (((unsigned)dest_ptr & 3) || (dest_pitch & 3) ||
        ((unsigned)src_ptr  & 3) || (src_pitch  & 3) ||
    /* image sizes: */
        dest_width <= 0 || dest_height <= 0 ||
        src_width  <= 0 || src_height  <= 0 ||
    /* rectangles: */
        dest_x < 0 || dest_y < 0 || dest_dx <= 0 || dest_dy <= 0 ||
        src_x  < 0 || src_y  < 0 || src_dx  <= 0 || src_dy  <= 0 ||
    /* overlaps: */
        dest_width < dest_x + dest_dx || dest_height < dest_y + dest_dy ||
        src_width  < src_x  + src_dx  || src_height  < src_y  + src_dy)
        goto fail;

    /* scale factors: */
    if (dest_dx == src_dx)          *p_scale_x = 1;
    else if (dest_dx == 2 * src_dx) *p_scale_x = 2;
    else goto fail;
    if (dest_dy == src_dy)          *p_scale_y = 1;
    else if (dest_dy == 2 * src_dy) *p_scale_y = 2;
    else goto fail;

    /* success: */
    return 1;

    /* failure: */
fail:
    return 0;
}

static int adjust_range (int *z1, int *dz1, int *z2, int *dz2, int inc2)
{
    /* skip odd start pixel: */
    if (*z1 & 1) {
        *z1 += 1;
        *dz1 -= 1;
        *z2 += inc2;
        *dz2 -= inc2;
    }
    /* clip the range: */
    if (*dz1 & 1) {
        *dz1 -= 1;
        *dz2 -= inc2;
    }
    return (*dz1 > 0 && *dz2 > 0);
}


/*** "from I420" converters: *******************************/

/*
 * I420toI420x() converter:
 */
int I420toI420x (unsigned char *dest_ptr, int dest_width, int dest_height,
                 int dest_pitch, int dest_x, int dest_y, int dest_dx, int dest_dy,
                 unsigned char *pY, unsigned char *pU, unsigned char *pV,
                 int src_width, int src_height, int yPitch, int uPitch, int vPitch,
                 int src_x, int src_y, int src_dx, int src_dy)
{
    /* scale factors: */
    int scale_x, scale_y;
	/* Chroma Shifting Allowed */
	int OddPattern;

    /* check arguments: */
    if (!chk_args (dest_ptr, dest_width, dest_height, dest_pitch,
        dest_x, dest_y, dest_dx, dest_dy, pY, src_width, src_height,
        yPitch, src_x, src_y, src_dx, src_dy, &scale_x, &scale_y))
        return -1;

    /* remove odd destination pixels: */
    if (!adjust_range (&dest_x, &dest_dx, &src_x, &src_dx, scale_x) ||
        !adjust_range (&dest_y, &dest_dy, &src_y, &src_dy, scale_y))
        return 0;

    /* check if we have matching chroma components: */
    //if ((src_x & 1) || (src_y & 1))
    //   OddCrop= true;                          /* can't shift chromas */
	//else
	//	OddCrop = false;

    /* check if bottop-up images: */
    if (dest_pitch <= 0 || yPitch <= 0)
        return -1;                          /* not supported for this format */

    /* check if 1:1 scale: */
    if (scale_x == 1 && scale_y == 1) {

        /* check if no color adjustmenst: */
        if (!(is_alpha | is_beta | is_gamma | is_kappa)) {

            /* no color adjustments: */
            unsigned char *s, *d, *v, *s2, *v2;
            int dest_uv_offs;
            register int i,j;

            /* copy Y plane: */
            s = pY + src_x + src_y * yPitch;
            d = dest_ptr + dest_x + dest_y * dest_pitch;
            for (i = 0; i < dest_dy; i ++) {
                memcpy (d, s, dest_dx); /* Flawfinder: ignore */
                s += yPitch;
                d += dest_pitch;
            }

            /* get Cr/Cb offsets: */
            dest_uv_offs = dest_height * dest_pitch / 4;

            /* copy Cr/Cb planes: */
            s = pU + src_x/2 + src_y/2 * uPitch;
            v = pV + src_x/2 + src_y/2 * vPitch;
            d = (dest_ptr + dest_height * dest_pitch) + dest_x/2 + dest_y/2 * dest_pitch/2;
			// extremely cheap way to handle 1 pel cropping
			OddPattern = ((src_y & 1) << 1) | (src_x & 1);
            for (i = 0; i < dest_dy/2; i++) 
			{						
				if((i+1) < dest_dy/2) {
					s2 = s+uPitch;
					v2 = v+vPitch;
				} else {
					s2 = s;
					v2 = v;
				}
				/* convert pixels: */
				switch(OddPattern)
				{
				case(0):
					memcpy (d, s, dest_dx/2); /* Flawfinder: ignore */
					memcpy (d + dest_uv_offs, v, dest_dx/2); /* Flawfinder: ignore */
					//memcpy (d + dest_uv_offs, s + src_uv_offs, dest_dx/2);
					break;
				case(1):					
					for (j = 0; j < dest_dx/2 -1; j ++) {
						d[j] = ((unsigned int)s[j] + (unsigned int)s[j+1] + 1)>>1;
						d[j + dest_uv_offs] = ((unsigned int)v[j] + (unsigned int)v[j+1] + 1)>>1;
					}
					d[j] = s[j];
					d[j + dest_uv_offs] = v[j];
					break;
				case(2):						
					for (j = 0; j < dest_dx/2; j ++) {
						d[j] = (s[j] + s2[j] + 1)>>1;
						d[j + dest_uv_offs] = ((unsigned int)v[j] + (unsigned int)v2[j] + 1)>>1;
					}					
					break;
				case(3):
					for (j = 0; j < dest_dx/2 -1; j ++) {
						d[j] = ((unsigned int)s[j] + (unsigned int)s[j+1] + (unsigned int)s2[j] + (unsigned int)s2[j+1] + 2)>>2;
						d[j + dest_uv_offs] = ((unsigned int)v[j] + (unsigned int)v[j+1] + (unsigned int)v2[j] + (unsigned int)v2[j+1] + 2)>>2;
					}
					d[j] = ((unsigned int)s[j]+ (unsigned int)s2[j] + 1)>>1;
					d[j + dest_uv_offs] = ((unsigned int)v[j] + (unsigned int)v2[j] + 1) >> 1;
					break;
				}
                s += uPitch;
                v += vPitch;
                d += (dest_pitch/2);				
            }

        } else {

            /* adjust colors: */
            unsigned char *s, *d, *v, *s2, *v2;
            int dest_uv_offs;
            register int i, j;

            /* convert Y plane: */
            s = pY + src_x + src_y * yPitch;
            d = dest_ptr + dest_x + dest_y * dest_pitch;
            for (i = 0; i < dest_dy; i ++) {

                /* convert pixels: */
                for (j = 0; j < dest_dx; j ++)
                    d[j] = _yytab[s[j]];

                s += yPitch;
                d += dest_pitch;
            }

            /* get Cr/Cb offsets: */
            dest_uv_offs = dest_height * dest_pitch / 4;

            /* get chroma pointers: */
            s = pU + src_x/2 + src_y/2 * uPitch;
            v = pV + src_x/2 + src_y/2 * vPitch;
            d = (dest_ptr + dest_height * dest_pitch) + dest_x/2 + dest_y/2 * dest_pitch/2;
			OddPattern = ((src_y & 1) << 1) | (src_x & 1);
            /* check if no hue adjustment: */
            if (!is_alpha) {				
                /* no chroma rotation: */
                for (i = 0; i < dest_dy/2; i ++) {
                    if((i+1) < dest_dy/2) {
						s2 = s+uPitch;
						v2 = v+vPitch;
					} else {
						s2 = s;
						v2 = v;
					}
					/* convert pixels: */									
					switch(OddPattern)
					{
					case(0):
						for (j = 0; j < dest_dx/2; j ++) {
							d[j] = _vvtab[s[j]];
							d[j + dest_uv_offs] = _uutab[v[j]];
						}
						break;
					case(1):					
						for (j = 0; j < dest_dx/2 -1; j ++) {
							register unsigned int s1 = ((unsigned int)s[j] + (unsigned int)s[j+1] + 1)>>1;
							register unsigned int v1 = ((unsigned int)v[j] + (unsigned int)v[j+1] + 1)>>1;
							d[j] = _vvtab[s1];							
							d[j + dest_uv_offs] = _uutab[v1];
						}
						d[j] = _vvtab[s[j]];
						d[j + dest_uv_offs] = _uutab[v[j]];
						break;
					case(2):						
						for (j = 0; j < dest_dx/2; j ++) {
							register unsigned int s1 = ((unsigned int)s[j] + (unsigned int)s2[j] + 1)>>1;							
							register unsigned int v1 = ((unsigned int)v[j] + (unsigned int)v2[j] + 1)>>1;
							d[j] = _vvtab[s1];							
							d[j + dest_uv_offs] = _uutab[v1];
						}					
						break;
					case(3):
						{
						register unsigned int s1, v1;
						for (j = 0; j < dest_dx/2 -1; j ++) {

⌨️ 快捷键说明

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