yuv2yuv.c
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:145k
- /* ***** BEGIN LICENSE BLOCK *****
- * Source last modified: $Id: yuv2yuv.c,v 1.4.28.1 2004/07/09 02:00:19 hubbe Exp $
- *
- * Portions Copyright (c) 1995-2004 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 (the "RPSL") available at
- * http://www.helixcommunity.org/content/rpsl unless you have licensed
- * the file under the current version of the RealNetworks Community
- * Source License (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.
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL") in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your version of
- * this file only under the terms of the GPL, and not to allow others
- * to use your version of this file under the terms of either the RPSL
- * or RCSL, indicate your decision by deleting the provisions above
- * and replace them with the notice and other provisions required by
- * the GPL. If you do not delete the provisions above, a recipient may
- * use your version of this file under the terms of any one of the
- * RPSL, the RCSL or the GPL.
- *
- * 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 ++) {
- s1 = ((unsigned int)s[j] + (unsigned int)s[j+1] + (unsigned int)s2[j] + (unsigned int)s2[j+1] + 2)>>2;
- v1 = ((unsigned int)v[j] + (unsigned int)v[j+1] + (unsigned int)v2[j] + (unsigned int)v2[j+1] + 2)>>2;
- d[j] = _vvtab[s1];
- d[j + dest_uv_offs] = _uutab[v1];
- }
- s1 =((unsigned int)s[j]+ (unsigned int)s2[j] + 1) >> 1;
- v1 = ((unsigned int)v[j] + (unsigned int)v2[j] + 1) >> 1;
- d[j] = _vvtab[s1];
- d[j + dest_uv_offs] = _uutab[v1];
- }
- break;
- }
- s += uPitch;
- v += vPitch;
- d += dest_pitch/2;
- }
- } else {
- /* adjust hue: */
- 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 ++) {
- register unsigned v1 = v[j], u1 = s[j];
- d[j] = _CLIP(8,_vvtab[v1] + _vutab[u1]);
- d[j + dest_uv_offs] = _CLIP(8,_uutab[u1] + _uvtab[v1]);
- }
- break;
- case(1):
- {
- register unsigned s1, v1;
- for (j = 0; j < dest_dx/2 -1; j ++) {
- s1 = ((unsigned int)s[j] + (unsigned int)s[j+1] + 1)>>1;
- v1 = ((unsigned int)v[j] + (unsigned int)v[j+1] + 1)>>1;
- d[j] = _CLIP(8,_vvtab[v1] + _vutab[s1]);
- d[j + dest_uv_offs] = _CLIP(8,_uutab[s1] + _uvtab[v1]);
- }
- v1 = v[j];
- s1 = s[j];
- d[j] = _CLIP(8,_vvtab[v1] + _vutab[s1]);
- d[j + dest_uv_offs] = _CLIP(8,_uutab[s1] + _uvtab[v1]);
- }
- break;
- case(2):
- for (j = 0; j < dest_dx/2; j ++) {
- register unsigned s1 = ((unsigned int)s[j] + (unsigned int)s2[j] + 1)>>1;
- register unsigned v1 = ((unsigned int)v[j] + (unsigned int)v2[j] + 1)>>1;
- d[j] = _CLIP(8,_vvtab[v1] + _vutab[s1]);
- d[j + dest_uv_offs] = _CLIP(8,_uutab[s1] + _uvtab[v1]);
- }
- break;
- case(3):
- {
- register unsigned s1, v1;
- for (j = 0; j < dest_dx/2 -1; j ++) {
- s1 =((unsigned int)s[j] + (unsigned int)s[j+1] + (unsigned int)s2[j] + (unsigned int)s2[j+1] + 2)>>2;
- v1 =((unsigned int)v[j] + (unsigned int)v[j+1] + (unsigned int)v2[j] + (unsigned int)v2[j+1] + 2)>>2;
- d[j] = _CLIP(8,_vvtab[v1] + _vutab[s1]);
- d[j + dest_uv_offs] = _CLIP(8,_uutab[s1] + _uvtab[v1]);
- }
- s1 = ((unsigned int)s[j]+ (unsigned int)s2[j] + 1)>>1;
- v1 = ((unsigned int)v[j] + (unsigned int)v2[j] + 1) >> 1;
- d[j] = _CLIP(8,_vvtab[v1] + _vutab[s1]);
- d[j + dest_uv_offs] = _CLIP(8,_uutab[s1] + _uvtab[v1]);
- }
- break;
- }
- s += uPitch;
- v += vPitch;
- d += dest_pitch/2;
- }
- }
- }
- return 0;
- }
- /* conversion is not supported */
- return -1;
- }
- /*
- * I420toI420() converter:
- */
- int I420toI420 (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)
- {
- #if 1
- unsigned char *pU = src_ptr+src_height*src_pitch,
- *pV = pU + src_height*src_pitch/4;
- return I420toI420x(dest_ptr, dest_width, dest_height, dest_pitch, dest_x, dest_y, dest_dx, dest_dy,
- src_ptr, pU, pV,
- src_width, src_height, src_pitch, src_pitch/2, src_pitch/2,
- src_x, src_y, src_dx, src_dy);
-
- #else
- /* scale factors: */
- int scale_x, scale_y;
- /* check arguments: */
- if (!chk_args (dest_ptr, dest_width, dest_height, dest_pitch,
- dest_x, dest_y, dest_dx, dest_dy, src_ptr, src_width, src_height,
- src_pitch, 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))
- return -1; /* can't shift chromas */
- /* check if bottop-up images: */
- if (dest_pitch <= 0 || src_pitch <= 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;
- int src_uv_offs, dest_uv_offs;
- register int i;
- /* copy Y plane: */
- s = src_ptr + src_x + src_y * src_pitch;
- d = dest_ptr + dest_x + dest_y * dest_pitch;
- for (i = 0; i < dest_dy; i ++) {
- memcpy (d, s, dest_dx); /* Flawfinder: ignore */
- s += src_pitch;
- d += dest_pitch;
- }
- /* get Cr/Cb offsets: */
- src_uv_offs = src_height * src_pitch / 4;
- dest_uv_offs = dest_height * dest_pitch / 4;
- /* copy Cr/Cb planes: */
- s = (src_ptr + src_height * src_pitch) + src_x/2 + src_y/2 * src_pitch/2;
- d = (dest_ptr + dest_height * dest_pitch) + dest_x/2 + dest_y/2 * dest_pitch/2;
- for (i = 0; i < dest_dy/2; i ++) {
- memcpy (d, s, dest_dx/2); /* Flawfinder: ignore */
- memcpy (d + dest_uv_offs, s + src_uv_offs, dest_dx/2); /* Flawfinder: ignore */
- s += src_pitch/2;
- d += dest_pitch/2;
- }
- } else {
- /* adjust colors: */
- unsigned char *s, *d;
- int src_uv_offs, dest_uv_offs;
- register int i, j;
- /* convert Y plane: */
- s = src_ptr + src_x + src_y * src_pitch;
- 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 += src_pitch;
- d += dest_pitch;
- }
- /* get Cr/Cb offsets: */
- src_uv_offs = src_height * src_pitch / 4;
- dest_uv_offs = dest_height * dest_pitch / 4;
- /* get chroma pointers: */
- s = (src_ptr + src_height * src_pitch) + src_x/2 + src_y/2 * src_pitch/2;
- d = (dest_ptr + dest_height * dest_pitch) + dest_x/2 + dest_y/2 * dest_pitch/2;
- /* check if no hue adjustment: */
- if (!is_alpha) {
- /* no chroma rotation: */
- for (i = 0; i < dest_dy/2; i ++) {
- /* convert pixels: */
- for (j = 0; j < dest_dx/2; j ++) {
- d[j] = _vvtab[s[j]];
- d[j + dest_uv_offs] = _uutab[s[j + src_uv_offs]];
- }
- s += src_pitch/2;
- d += dest_pitch/2;
- }
- } else {
- /* adjust hue: */
- for (i = 0; i < dest_dy/2; i ++) {
- /* convert pixels: */
- for (j = 0; j < dest_dx/2; j ++) {
- register unsigned v = s[j], u = s[j + src_uv_offs];
- d[j] = _CLIP(8,_vvtab[v] + _vutab[u]);
- d[j + dest_uv_offs] = _CLIP(8,_uutab[u] + _uvtab[v]);
- }
- s += src_pitch/2;
- d += dest_pitch/2;
- }
- }
- }
- return 0;
- }
- /* conversion is not supported */
- return -1;
- #endif
- }
- int I420toYV12x (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;
- /* 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))
- return -1; /* can't shift chromas */
- /* 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 adjustments: */
- if (!(is_alpha | is_beta | is_gamma | is_kappa)) {
- /* no color adjustments: */
- unsigned char *sy, *su, *sv, *d;
- int dest_uv_offs;
- register int i;
- /* copy Y plane: */
- sy = pY + src_x + src_y * yPitch;
- d = dest_ptr + dest_x + dest_y * dest_pitch;
- for (i = 0; i < dest_dy; i ++) {
- memcpy (d, sy, dest_dx); /* Flawfinder: ignore */
- sy += yPitch;
- d += dest_pitch;
- }
- /* get Cr/Cb offsets: */
- dest_uv_offs = dest_height * dest_pitch / 4;
- /* copy Cr/Cb planes: */
- su = pU + src_x/2 + src_y/2 * uPitch;
- sv = pV + src_x/2 + src_y/2 * vPitch;
-
- d = (dest_ptr + dest_height * dest_pitch) + dest_x/2 + dest_y/2 * dest_pitch/2;
- for (i = 0; i < dest_dy/2; i ++) {
- memcpy (d, sv, dest_dx/2); /* Flawfinder: ignore */
- memcpy (d + dest_uv_offs, su, dest_dx/2); /* Flawfinder: ignore */
- su += uPitch;
- sv += vPitch;
- d += dest_pitch/2;
- }
- } else {
- /* adjust colors: */
- unsigned char *sy, *su, *sv, *d;
- int dest_uv_offs;
- register int i, j;
- /* convert Y plane: */
- sy = 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[sy[j]];
- sy += yPitch;
- d += dest_pitch;
- }
- /* get Cr/Cb offsets: */
- dest_uv_offs = dest_height * dest_pitch / 4;
- /* get chroma pointers: */
- su = pU + src_x/2 + src_y/2 * uPitch;
- sv = pV + src_x/2 + src_y/2 * vPitch;
- d = (dest_ptr + dest_height * dest_pitch) + dest_x/2 + dest_y/2 * dest_pitch/2;
- /* check if no hue adjustment: */
- if (!is_alpha) {
- /* no chroma rotation: */
- for (i = 0; i < dest_dy/2; i ++) {
- /* convert pixels: */
- for (j = 0; j < dest_dx/2; j ++) {
- d[j] = _vvtab[sv[j]];
- d[j + dest_uv_offs] = _uutab[su[j]];
- }
- su += uPitch;
- sv += vPitch;
- d += dest_pitch/2;
- }
- } else {
- /* adjust hue: */
- for (i = 0; i < dest_dy/2; i ++) {
- /* convert pixels: */
- for (j = 0; j < dest_dx/2; j ++) {
- register unsigned v = sv[j], u = su[j];
- d[j] = _CLIP(8,_vvtab[v] + _vutab[u]);
- d[j + dest_uv_offs] = _CLIP(8,_uutab[u] + _uvtab[v]);
- }
- su += uPitch;
- sv += vPitch;
- d += dest_pitch/2;
- }
- }
- }
- return 0;
- }
- /* conversion is not supported */
- return -1;
- }
- /*
- * I420toYV12() converter:
- */
- int I420toYV12 (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)
- {
- #if 1
- unsigned char *pU = src_ptr+src_height*src_pitch,
- *pV = pU + src_height*src_pitch/4;
- return I420toYV12x(dest_ptr, dest_width, dest_height, dest_pitch, dest_x, dest_y, dest_dx, dest_dy,
- src_ptr, pU, pV,
- src_width, src_height, src_pitch, src_pitch/2, src_pitch/2,
- src_x, src_y, src_dx, src_dy);
-
- #else
- /* scale factors: */
- int scale_x, scale_y;
- /* check arguments: */
- if (!chk_args (dest_ptr, dest_width, dest_height, dest_pitch,
- dest_x, dest_y, dest_dx, dest_dy, src_ptr, src_width, src_height,
- src_pitch, 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))
- return -1; /* can't shift chromas */
- /* check if bottop-up images: */
- if (dest_pitch <= 0 || src_pitch <= 0)
- return -1; /* not supported for this format */
- /* check if 1:1 scale: */
- if (scale_x == 1 && scale_y == 1) {
- /* check if no color adjustments: */
- if (!(is_alpha | is_beta | is_gamma | is_kappa)) {
- /* no color adjustments: */
- unsigned char *s, *d;
- int src_uv_offs, dest_uv_offs;
- register int i;
- /* copy Y plane: */
- s = src_ptr + src_x + src_y * src_pitch;
- d = dest_ptr + dest_x + dest_y * dest_pitch;
- for (i = 0; i < dest_dy; i ++) {
- memcpy (d, s, dest_dx); /* Flawfinder: ignore */
- s += src_pitch;
- d += dest_pitch;
- }
- /* get Cr/Cb offsets: */
- src_uv_offs = src_height * src_pitch / 4;
- dest_uv_offs = dest_height * dest_pitch / 4;
- /* copy Cr/Cb planes: */
- s = (src_ptr + src_height * src_pitch) + src_x/2 + src_y/2 * src_pitch/2;
- d = (dest_ptr + dest_height * dest_pitch) + dest_x/2 + dest_y/2 * dest_pitch/2;
- for (i = 0; i < dest_dy/2; i ++) {
- memcpy (d, s + src_uv_offs, dest_dx/2); /* Flawfinder: ignore */
- memcpy (d + dest_uv_offs, s, dest_dx/2); /* Flawfinder: ignore */
- s += src_pitch/2;
- d += dest_pitch/2;
- }
- } else {
- /* adjust colors: */
- unsigned char *s, *d;
- int src_uv_offs, dest_uv_offs;
- register int i, j;
- /* convert Y plane: */
- s = src_ptr + src_x + src_y * src_pitch;
- 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 += src_pitch;
- d += dest_pitch;
- }
- /* get Cr/Cb offsets: */
- src_uv_offs = src_height * src_pitch / 4;
- dest_uv_offs = dest_height * dest_pitch / 4;
- /* get chroma pointers: */
- s = (src_ptr + src_height * src_pitch) + src_x/2 + src_y/2 * src_pitch/2;
- d = (dest_ptr + dest_height * dest_pitch) + dest_x/2 + dest_y/2 * dest_pitch/2;
- /* check if no hue adjustment: */
- if (!is_alpha) {
- /* no chroma rotation: */
- for (i = 0; i < dest_dy/2; i ++) {
- /* convert pixels: */
- for (j = 0; j < dest_dx/2; j ++) {
- d[j] = _vvtab[s[j + src_uv_offs]];
- d[j + dest_uv_offs] = _uutab[s[j]];
- }
- s += src_pitch/2;
- d += dest_pitch/2;
- }
- } else {
- /* adjust hue: */
- for (i = 0; i < dest_dy/2; i ++) {
- /* convert pixels: */
- for (j = 0; j < dest_dx/2; j ++) {
- register unsigned v = s[j + src_uv_offs], u = s[j];
- d[j] = _CLIP(8,_vvtab[v] + _vutab[u]);
- d[j + dest_uv_offs] = _CLIP(8,_uutab[u] + _uvtab[v]);
- }
- s += src_pitch/2;
- d += dest_pitch/2;
- }
- }
- }
- return 0;
- }
- /* conversion is not supported */
- return -1;
- #endif
- }
- #if (defined(_M_IX86) || defined(_USE_MMX_BLENDERS)) && !defined(WINCE_EMULATOR)
- //Our MMX optimized YUY2 and UYVY to YUV converters.
- //No scaling supported yet.
- extern void YUY2ToPlanarYUV_MMX( unsigned char* d1,
- unsigned char* d2,
- unsigned char* du,
- unsigned char* dv,
- INT32 dyPitch,
- INT32 duPitch,
- INT32 dvPitch,
- INT32 dest_dx,
- INT32 dest_dy,
- unsigned char* s1,
- unsigned char* s2,
- INT32 src_pitch
- );
- extern void UYVYToPlanarYUV_MMX( unsigned char* d1,
- unsigned char* d2,
- unsigned char* du,
- unsigned char* dv,
- INT32 dyPitch,
- INT32 duPitch,
- INT32 dvPitch,
- INT32 dest_dx,
- INT32 dest_dy,
- unsigned char* s1,
- unsigned char* s2,
- INT32 src_pitch
- );
- extern YUY2toUYVY_MMX( unsigned char* src,
- unsigned char* dest,
- ULONG32 dx
- );
- /* MMX version of I420toYUY2 converter: */
- extern void _MMX_lineI420toYUY2( unsigned char *sy,
- unsigned char *su,
- unsigned char *sv,
- unsigned char *d,
- int count
- );
- /* MMX version of I420toUYVY converter */
- extern void _MMX_lineI420toUYVY( unsigned char *sy,
- unsigned char *su,
- unsigned char *sv,
- unsigned char *d,
- int count
- );
- #endif
- #ifdef _MACINTOSH
- #ifdef __cplusplus
- extern "C"
- #endif
- void
- AltiVec_lineI420toYUY2 (
- unsigned char *sy,
- unsigned char *su,
- unsigned char *sv,
- unsigned char *d,
- int dest_dx);
- #endif
- /*
- * Combine 4 bytes in a register for fast transfer to
- * the main memory:
- */
- #if BYTE_ORDER == LITTLE_ENDIAN
- #define COMBINE(b0,b1,b2,b3)
- ((unsigned int)(b0) | ((unsigned int)(b1) << 8) |
- ((unsigned int)(b2) << 16) | ((unsigned int)(b3) << 24))
- #else /* BYTE_ORDER != LITTLE_ENDIAN */
- #define COMBINE(b0,b1,b2,b3)
- ((unsigned int)(b3) | ((unsigned int)(b2) << 8) |
- ((unsigned int)(b1) << 16) | ((unsigned int)(b0) << 24))
- #endif
- int I420toYUY2x (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;
- /* 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 columns: */
- if (!adjust_range (&dest_x, &dest_dx, &src_x, &src_dx, scale_x))
- return 0;
- /* check if we have misaligned input: */
- if (src_x & 1)
- return -1; /* can't shift chromas */
- /* check if bottop-up images: */
- if (dest_pitch < 0) dest_ptr -= (dest_height-1) * dest_pitch;
- if (yPitch <= 0 ||
- uPitch <= 0 ||
- vPitch <= 0)
- return -1; /* not supported */
- /* check if 1:1 scale: */
- if (scale_x == 1 && scale_y == 1) {
- /* check if no color adjustments: */
- if (!(is_alpha | is_beta | is_gamma | is_kappa)) {
- /* no color adjustments: */
- unsigned char *sy, *sv, *su, *d;
- register int i, j;
- /* get pointers: */
- sy = pY + src_x + src_y * yPitch; /* luma offset */
- su = pU + (src_x/2 + src_y/2 * uPitch);
- sv = pV + (src_x/2 + src_y/2 * vPitch);
- d = dest_ptr + dest_x * 2 + dest_y * dest_pitch; /* 2 bytes/pixel */
- #if (defined(_M_IX86) || defined(_USE_MMX_BLENDERS)) && !defined(WINCE_EMULATOR)
- /* check if we can use MMX-optimized code here: */
- if (_x86_MMX_Available)
- {
- /* process top line (if chroma is not pairable): */
- if (dest_y & 1) {
- _MMX_lineI420toYUY2 (sy, su, sv, d, dest_dx);
- sy += yPitch;
- su += uPitch;
- sv += vPitch;
- d += dest_pitch;
- dest_dy --;
- }
- /* the main loop (processes two lines a time): */
- for (i = 0; i < dest_dy/2; i ++) {
- _MMX_lineI420toYUY2 (sy, su, sv, d, dest_dx);
- sy += yPitch;
- d += dest_pitch;
- _MMX_lineI420toYUY2 (sy, su, sv, d, dest_dx);
- sy += yPitch;
- su += uPitch;
- sv += vPitch;
- d += dest_pitch;
- }
- /* process the last line (if dy is odd): */
- if (dest_dy & 1) {
- _MMX_lineI420toYUY2 (sy, su, sv, d, dest_dx);
- }
- /* end of MMX code */
- #if defined(_M_IX86) && !defined(WINCE_EMULATOR)
- __asm emms
- #elif defined(_USE_MMX_BLENDERS) && !defined(WINCE_EMULATOR)
- __asm__ __volatile__ ( "emms" );
- #endif
- } else
- #endif
- #ifdef _MACINTOSH
- /* check if we can use MMX-optimized code here: */
- if (_AltiVec_Available)
- {
- /* process top line (if chroma is not pairable): */
- if (dest_y & 1) {
- AltiVec_lineI420toYUY2 (sy, su, sv, d, dest_dx);
- sy += yPitch;
- su += uPitch;
- sv += vPitch;
- d += dest_pitch;
- dest_dy --;
- }
- /* the main loop (processes two lines a time): */
- for (i = 0; i < dest_dy/2; i ++) {
- AltiVec_lineI420toYUY2 (sy, su, sv, d, dest_dx);
- sy += yPitch;
- d += dest_pitch;
- AltiVec_lineI420toYUY2 (sy, su, sv, d, dest_dx);
- sy += yPitch;
- su += uPitch;
- sv += vPitch;
- d += dest_pitch;
- }
- /* process the last line (if dy is odd): */
- if (dest_dy & 1) {
- AltiVec_lineI420toYUY2 (sy, su, sv, d, dest_dx);
- }
- /* end of MMX code */
- } else
- #endif
- /* a generic "C" version: */
- {
- /* process top line (if chroma is not pairable): */
- if (dest_y & 1) {
- for (j = 0; j < dest_dx/2; j ++)
- *(unsigned int *)(d + j*4) = COMBINE(sy[j*2], su[j], sy[j*2+1], sv[j]);
- sy += yPitch;
- su += uPitch;
- sv += vPitch;
- d += dest_pitch;
- dest_dy --;
- }
- /* the main loop (processes two lines a time): */
- for (i = 0; i < dest_dy/2; i ++) {
- for (j = 0; j < dest_dx/2; j ++)
- *(unsigned int *)(d + j*4) = COMBINE(sy[j*2], su[j], sy[j*2+1], sv[j]);
- sy += yPitch;
- d += dest_pitch;
- for (j = 0; j < dest_dx/2; j ++)
- *(unsigned int *)(d + j*4) = COMBINE(sy[j*2], su[j], sy[j*2+1], sv[j]);
- sy += yPitch;
- su += uPitch;
- sv += vPitch;
- d += dest_pitch;
- }
- /* process the last line (if dy is odd): */
- if (dest_dy & 1) {
- for (j = 0; j < dest_dx/2; j ++)
- *(unsigned int *)(d + j*4) = COMBINE(sy[j*2], su[j], sy[j*2+1], sv[j]);
- }
- }
- } else
- /* check if no hue adjustment: */
- if (!is_alpha) {
- /* no chroma rotation: */
- unsigned char *sy, *sv, *su, *d;
- register int i, j;
- /* get pointers: */
- sy = pY + src_x + src_y * yPitch; /* luma offset */
- su = pU + (src_x/2 + src_y/2 * uPitch);
- sv = pV + (src_x/2 + src_y/2 * vPitch);
- d = dest_ptr + dest_x * 2 + dest_y * dest_pitch; /* 2 bytes/pixel */
- /* process top line (if chroma is not pairable): */
- if (dest_y & 1) {
- for (j = 0; j < dest_dx/2; j ++)
- *(unsigned int *)(d + j*4) = COMBINE(_yytab[sy[j*2]], _uutab[su[j]], _yytab[sy[j*2+1]], _vvtab[sv[j]]);
- sy += yPitch;
- su += uPitch;
- sv += vPitch;
- d += dest_pitch;
- dest_dy --;
- }
- /* the main loop (processes two lines a time): */
- for (i = 0; i < dest_dy/2; i ++) {
- for (j = 0; j < dest_dx/2; j ++)
- *(unsigned int *)(d + j*4) = COMBINE(_yytab[sy[j*2]], _uutab[su[j]], _yytab[sy[j*2+1]], _vvtab[sv[j]]);
- sy += yPitch;
- d += dest_pitch;
- for (j = 0; j < dest_dx/2; j ++)
- *(unsigned int *)(d + j*4) = COMBINE(_yytab[sy[j*2]], _uutab[su[j]], _yytab[sy[j*2+1]], _vvtab[sv[j]]);
- sy += yPitch;
- su += uPitch;
- sv += vPitch;
- d += dest_pitch;
- }
- /* process the last line (if dy is odd): */
- if (dest_dy & 1) {
- for (j = 0; j < dest_dx/2; j ++)
- *(unsigned int *)(d + j*4) = COMBINE(_yytab[sy[j*2]], _uutab[su[j]], _yytab[sy[j*2+1]], _vvtab[sv[j]]);
- }
- } else {
- /* the most complex case (w. hue adjustment): */
- unsigned char *sy, *sv, *su, *d;
- register int i, j, u, v;
- /* get pointers: */
- sy = pY + src_x + src_y * yPitch; /* luma offset */
- su = pU + (src_x/2 + src_y/2 * uPitch);
- sv = pV + (src_x/2 + src_y/2 * vPitch);
- d = dest_ptr + dest_x * 2 + dest_y * dest_pitch; /* 2 bytes/pixel */
- /* process top line (if chroma is not pairable): */
- if (dest_y & 1) {
- for (j = 0; j < dest_dx/2; j ++) {
- v = _CLIP(8,_vvtab[sv[j]] + _vutab[su[j]]);
- u = _CLIP(8,_uutab[su[j]] + _uvtab[sv[j]]);
- *(unsigned int *)(d + j*4) = COMBINE(_yytab[sy[j*2]], u, _yytab[sy[j*2+1]], v);
- }
- sy += yPitch;
- su += uPitch;
- sv += vPitch;
- d += dest_pitch;
- dest_dy --;
- }
- /* the main loop (processes two lines a time): */
- for (i = 0; i < dest_dy/2; i ++) {
- for (j = 0; j < dest_dx/2; j ++) {
- v = _CLIP(8,_vvtab[sv[j]] + _vutab[su[j]]);
- u = _CLIP(8,_uutab[su[j]] + _uvtab[sv[j]]);
- *(unsigned int *)(d + j*4) = COMBINE(_yytab[sy[j*2]], u, _yytab[sy[j*2+1]], v);
- *(unsigned int *)(d + j*4 + dest_pitch) = COMBINE(_yytab[sy[j*2 + yPitch]], u, _yytab[sy[j*2+1+yPitch]], v);
- }
- sy += yPitch*2;
- su += uPitch;
- sv += vPitch;
- d += dest_pitch*2;
- }
- /* process the last line (if dy is odd): */
- if (dest_dy & 1) {
- for (j = 0; j < dest_dx/2; j ++) {
- v = _CLIP(8,_vvtab[sv[j]] + _vutab[su[j]]);
- u = _CLIP(8,_uutab[su[j]] + _uvtab[sv[j]]);
- *(unsigned int *)(d + j*4) = COMBINE(_yytab[sy[j*2]], u, _yytab[sy[j*2+1]], v);
- }
- }
- }
- return 0;
- }
- /* conversion is not supported */
- return -1;
- }
- /*
- * I420toYUY2() converter:
- */
- int I420toYUY2 (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)
- {
- #if 1
- unsigned char *pU = src_ptr+src_height*src_pitch,
- *pV = pU + src_height*src_pitch/4;
- return I420toYUY2x(dest_ptr, dest_width, dest_height, dest_pitch, dest_x, dest_y, dest_dx, dest_dy,
- src_ptr, pU, pV,
- src_width, src_height, src_pitch, src_pitch/2, src_pitch/2,
- src_x, src_y, src_dx, src_dy);
-
- #else
- /* scale factors: */
- int scale_x, scale_y;
- /* check arguments: */
- if (!chk_args (dest_ptr, dest_width, dest_height, dest_pitch,
- dest_x, dest_y, dest_dx, dest_dy, src_ptr, src_width, src_height,
- src_pitch, src_x, src_y, src_dx, src_dy, &scale_x, &scale_y))
- return -1;
- /* remove odd destination columns: */
- if (!adjust_range (&dest_x, &dest_dx, &src_x, &src_dx, scale_x))
- return 0;
- /* check if we have misaligned input: */
- if (src_x & 1)
- return -1; /* can't shift chromas */
- /* check if bottop-up images: */
- if (dest_pitch < 0) dest_ptr -= (dest_height-1) * dest_pitch;
- if (src_pitch <= 0) return -1; /* not supported */
- /* check if 1:1 scale: */
- if (scale_x == 1 && scale_y == 1) {
- /* check if no color adjustments: */
- if (!(is_alpha | is_beta | is_gamma | is_kappa)) {
- /* no color adjustments: */
- unsigned char *sy, *sv, *su, *d;
- register int i, j;
- /* get pointers: */
- sy = src_ptr + src_x + src_y * src_pitch; /* luma offset */
- su = src_ptr + src_height * src_pitch + (src_x/2 + src_y/2 * src_pitch);
- sv = su + src_height * src_pitch / 4;
- d = dest_ptr + dest_x * 2 + dest_y * dest_pitch; /* 2 bytes/pixel */
- #if (defined(_M_IX86) || defined(_USE_MMX_BLENDERS)) && !defined(WINCE_EMULATOR)
- /* check if we can use MMX-optimized code here: */
- if (_x86_MMX_Available)
- {
- /* process top line (if chroma is not pairable): */
- if (dest_y & 1) {
- _MMX_lineI420toYUY2 (sy, su, sv, d, dest_dx);
- sy += src_pitch;
- su += src_pitch/2;
- sv += src_pitch/2;
- d += dest_pitch;
- dest_dy --;
- }
- /* the main loop (processes two lines a time): */
- for (i = 0; i < dest_dy/2; i ++) {
- _MMX_lineI420toYUY2 (sy, su, sv, d, dest_dx);
- sy += src_pitch;
- d += dest_pitch;
- _MMX_lineI420toYUY2 (sy, su, sv, d, dest_dx);
- sy += src_pitch;
- su += src_pitch/2;
- sv += src_pitch/2;
- d += dest_pitch;
- }
- /* process the last line (if dy is odd): */
- if (dest_dy & 1) {
- _MMX_lineI420toYUY2 (sy, su, sv, d, dest_dx);
- }
- /* end of MMX code */
- #if defined(_M_IX86) && !defined(WINCE_EMULATOR)
- __asm emms
- #elif defined(_USE_MMX_BLENDERS) && !defined(WINCE_EMULATOR)
- __asm__ __volatile__ ( "emms" );
- #endif
- } else
- #endif
- /* a generic "C" version: */
- {
- /* process top line (if chroma is not pairable): */
- if (dest_y & 1) {
- for (j = 0; j < dest_dx/2; j ++)
- *(unsigned int *)(d + j*4) = COMBINE(sy[j*2], su[j], sy[j*2+1], sv[j]);
- sy += src_pitch;
- su += src_pitch/2;
- sv += src_pitch/2;
- d += dest_pitch;
- dest_dy --;
- }
- /* the main loop (processes two lines a time): */
- for (i = 0; i < dest_dy/2; i ++) {
- for (j = 0; j < dest_dx/2; j ++)
- *(unsigned int *)(d + j*4) = COMBINE(sy[j*2], su[j], sy[j*2+1], sv[j]);
- sy += src_pitch;
- d += dest_pitch;
- for (j = 0; j < dest_dx/2; j ++)
- *(unsigned int *)(d + j*4) = COMBINE(sy[j*2], su[j], sy[j*2+1], sv[j]);
- sy += src_pitch;
- su += src_pitch/2;
- sv += src_pitch/2;
- d += dest_pitch;
- }
- /* process the last line (if dy is odd): */
- if (dest_dy & 1) {
- for (j = 0; j < dest_dx/2; j ++)
- *(unsigned int *)(d + j*4) = COMBINE(sy[j*2], su[j], sy[j*2+1], sv[j]);
- }
- }
- } else
- /* check if no hue adjustment: */
- if (!is_alpha) {
- /* no chroma rotation: */
- unsigned char *sy, *sv, *su, *d;
- register int i, j;
- /* get pointers: */
- sy = src_ptr + src_x + src_y * src_pitch; /* luma offset */
- su = src_ptr + src_height * src_pitch + (src_x/2 + src_y/2 * src_pitch);
- sv = su + src_height * src_pitch / 4;
- d = dest_ptr + dest_x * 2 + dest_y * dest_pitch; /* 2 bytes/pixel */
- /* process top line (if chroma is not pairable): */
- if (dest_y & 1) {
- for (j = 0; j < dest_dx/2; j ++)
- *(unsigned int *)(d + j*4) = COMBINE(_yytab[sy[j*2]], _uutab[su[j]], _yytab[sy[j*2+1]], _vvtab[sv[j]]);
- sy += src_pitch;
- su += src_pitch/2;
- sv += src_pitch/2;
- d += dest_pitch;
- dest_dy --;
- }
- /* the main loop (processes two lines a time): */
- for (i = 0; i < dest_dy/2; i ++) {
- for (j = 0; j < dest_dx/2; j ++)
- *(unsigned int *)(d + j*4) = COMBINE(_yytab[sy[j*2]], _uutab[su[j]], _yytab[sy[j*2+1]], _vvtab[sv[j]]);
- sy += src_pitch;
- d += dest_pitch;
- for (j = 0; j < dest_dx/2; j ++)
- *(unsigned int *)(d + j*4) = COMBINE(_yytab[sy[j*2]], _uutab[su[j]], _yytab[sy[j*2+1]], _vvtab[sv[j]]);
- sy += src_pitch;
- su += src_pitch/2;
- sv += src_pitch/2;
- d += dest_pitch;
- }
- /* process the last line (if dy is odd): */
- if (dest_dy & 1) {
- for (j = 0; j < dest_dx/2; j ++)
- *(unsigned int *)(d + j*4) = COMBINE(_yytab[sy[j*2]], _uutab[su[j]], _yytab[sy[j*2+1]], _vvtab[sv[j]]);
- }
- } else {
- /* the most complex case (w. hue adjustment): */
- unsigned char *sy, *sv, *su, *d;
- register int i, j, u, v;
- /* get pointers: */
- sy = src_ptr + src_x + src_y * src_pitch; /* luma offset */
- su = src_ptr + src_height * src_pitch + (src_x/2 + src_y/2 * src_pitch/2);
- sv = su + src_height * src_pitch / 4;
- d = dest_ptr + dest_x * 2 + dest_y * dest_pitch; /* 2 bytes/pixel */
- /* process top line (if chroma is not pairable): */
- if (dest_y & 1) {
- for (j = 0; j < dest_dx/2; j ++) {
- v = _CLIP(8,_vvtab[sv[j]] + _vutab[su[j]]);
- u = _CLIP(8,_uutab[su[j]] + _uvtab[sv[j]]);
- *(unsigned int *)(d + j*4) = COMBINE(_yytab[sy[j*2]], u, _yytab[sy[j*2+1]], v);
- }
- sy += src_pitch;
- su += src_pitch/2;
- sv += src_pitch/2;
- d += dest_pitch;
- dest_dy --;
- }
- /* the main loop (processes two lines a time): */
- for (i = 0; i < dest_dy/2; i ++) {
- for (j = 0; j < dest_dx/2; j ++) {
- v = _CLIP(8,_vvtab[sv[j]] + _vutab[su[j]]);
- u = _CLIP(8,_uutab[su[j]] + _uvtab[sv[j]]);
- *(unsigned int *)(d + j*4) = COMBINE(_yytab[sy[j*2]], u, _yytab[sy[j*2+1]], v);
- *(unsigned int *)(d + j*4 + dest_pitch) = COMBINE(_yytab[sy[j*2 + src_pitch]], u, _yytab[sy[j*2+1+src_pitch]], v);
- }
- sy += src_pitch*2;
- su += src_pitch/2;
- sv += src_pitch/2;
- d += dest_pitch*2;
- }
- /* process the last line (if dy is odd): */
- if (dest_dy & 1) {
- for (j = 0; j < dest_dx/2; j ++) {
- v = _CLIP(8,_vvtab[sv[j]] + _vutab[su[j]]);
- u = _CLIP(8,_uutab[su[j]] + _uvtab[sv[j]]);
- *(unsigned int *)(d + j*4) = COMBINE(_yytab[sy[j*2]], u, _yytab[sy[j*2+1]], v);
- }
- }
- }
- return 0;
- }
- /* conversion is not supported */
- return -1;
- #endif //0
- }
- int I420toUYVYx (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;
- /* 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 columns: */
- if (!adjust_range (&dest_x, &dest_dx, &src_x, &src_dx, scale_x))
- return 0;
- /* check if we have misaligned input: */
- if (src_x & 1)
- return -1; /* can't shift chromas */
- /* check if bottop-up images: */
- if (dest_pitch < 0) dest_ptr -= (dest_height-1) * dest_pitch;
- if (yPitch <= 0 ||
- uPitch <= 0 ||
- vPitch <= 0)
- return -1; /* not supported */
- /* check if 1:1 scale: */
- if (scale_x == 1 && scale_y == 1) {
- /* check if no color adjustments: */
- if (!(is_alpha | is_beta | is_gamma | is_kappa)) {
- /* no color adjustments: */
- unsigned char *sy, *sv, *su, *d;
- register int i, j;
- /* get pointers: */
- sy = pY + src_x + src_y * yPitch; /* luma offset */
- su = pU + (src_x/2 + src_y/2 * uPitch);
- sv = pV + (src_x/2 + src_y/2 * vPitch);
- d = dest_ptr + dest_x * 2 + dest_y * dest_pitch; /* 2 bytes/pixel */
- #if (defined(_M_IX86) || defined(_USE_MMX_BLENDERS)) && !defined(WINCE_EMULATOR)
- /* check if we can use MMX-optimized code here: */
- if (_x86_MMX_Available)
- {
- /* process top line (if chroma is not pairable): */
- if (dest_y & 1) {
- _MMX_lineI420toUYVY (sy, su, sv, d, dest_dx);
- sy += yPitch;
- su += uPitch;
- sv += vPitch;
- d += dest_pitch;
- dest_dy --;
- }
- /* the main loop (processes two lines a time): */
- for (i = 0; i < dest_dy/2; i ++) {
- _MMX_lineI420toUYVY (sy, su, sv, d, dest_dx);
- sy += yPitch;
- d += dest_pitch;
- _MMX_lineI420toUYVY (sy, su, sv, d, dest_dx);
- sy += yPitch;
- su += uPitch;
- sv += vPitch;
- d += dest_pitch;
- }
- /* process the last line (if dy is odd): */
- if (dest_dy & 1) {
- _MMX_lineI420toUYVY (sy, su, sv, d, dest_dx);
- }
- /* end of MMX code */
- #if defined(_M_IX86) && !defined(WINCE_EMULATOR)
- __asm emms
- #elif defined(_USE_MMX_BLENDERS) && !defined(WINCE_EMULATOR)
- __asm__ __volatile__ ( "emms" );
- #endif
- } else
- #endif
- /* a generic "C" version: */
- {
- /* process top line (if chroma is not pairable): */
- if (dest_y & 1) {
- for (j = 0; j < dest_dx/2; j ++)
- *(unsigned int *)(d + j*4) = su[j] | (sy[j*2] << 8) | (sv[j] << 16) | (sy[j*2+1] << 24);
- sy += yPitch;
- su += uPitch;
- sv += vPitch;
- d += dest_pitch;
- dest_dy --;
- }
- /* the main loop (processes two lines a time): */
- for (i = 0; i < dest_dy/2; i ++) {
- for (j = 0; j < dest_dx/2; j ++)
- *(unsigned int *)(d + j*4) = su[j] | (sy[j*2] << 8) | (sv[j] << 16) | (sy[j*2+1] << 24);
- sy += yPitch;
- d += dest_pitch;
- for (j = 0; j < dest_dx/2; j ++)
- *(unsigned int *)(d + j*4) = su[j] | (sy[j*2] << 8) | (sv[j] << 16) | (sy[j*2+1] << 24);
- sy += yPitch;
- su += uPitch;
- sv += vPitch;
- d += dest_pitch;
- }
- /* process the last line (if dy is odd): */
- if (dest_dy & 1) {
- for (j = 0; j < dest_dx/2; j ++)
- *(unsigned int *)(d + j*4) = su[j] | (sy[j*2] << 8) | (sv[j] << 16) | (sy[j*2+1] << 24);
- }
- }
- } else
- /* check if no hue adjustment: */
- if (!is_alpha) {
- /* no chroma rotation: */
- unsigned char *sy, *sv, *su, *d;
- register int i, j;
- /* get pointers: */
- sy = pY + src_x + src_y * yPitch; /* luma offset */
- su = pU + (src_x/2 + src_y/2 * uPitch);
- sv = pV + (src_x/2 + src_y/2 * vPitch);
- d = dest_ptr + dest_x * 2 + dest_y * dest_pitch; /* 2 bytes/pixel */
- /* process top line (if chroma is not pairable): */
- if (dest_y & 1) {
- for (j = 0; j < dest_dx/2; j ++)
- *(unsigned int *)(d + j*4) = _uutab[su[j]] | (_yytab[sy[j*2]] << 8) | (_vvtab[sv[j]] << 16) | (_yytab[sy[j*2+1]] << 24);
- sy += yPitch;
- su += uPitch;
- sv += vPitch;
- d += dest_pitch;
- dest_dy --;
- }
- /* the main loop (processes two lines a time): */
- for (i = 0; i < dest_dy/2; i ++) {
- for (j = 0; j < dest_dx/2; j ++)
- *(unsigned int *)(d + j*4) = _uutab[su[j]] | (_yytab[sy[j*2]] << 8) | (_vvtab[sv[j]] << 16) | (_yytab[sy[j*2+1]] << 24);
- sy += yPitch;
- d += dest_pitch;
- for (j = 0; j < dest_dx/2; j ++)
- *(unsigned int *)(d + j*4) = _uutab[su[j]] | (_yytab[sy[j*2]] << 8) | (_vvtab[sv[j]] << 16) | (_yytab[sy[j*2+1]] << 24);
- sy += yPitch;
- su += uPitch;
- sv += vPitch;
- d += dest_pitch;
- }
- /* process the last line (if dy is odd): */
- if (dest_dy & 1) {
- for (j = 0; j < dest_dx/2; j ++)
- *(unsigned int *)(d + j*4) = _uutab[su[j]] | (_yytab[sy[j*2]] << 8) | (_vvtab[sv[j]] << 16) | (_yytab[sy[j*2+1]] << 24);
- }
- } else {
- /* the most complex case (w. hue adjustement): */
- unsigned char *sy, *sv, *su, *d;
- register int i, j, u, v;
- /* get pointers: */
- sy = pY + src_x + src_y * yPitch; /* luma offset */
- su = pU + (src_x/2 + src_y/2 * uPitch);
- sv = pV + (src_x/2 + src_y/2 * vPitch);
- d = dest_ptr + dest_x * 2 + dest_y * dest_pitch; /* 2 bytes/pixel */
- /* process top line (if chroma is not pairable): */
- if (dest_y & 1) {
- for (j = 0; j < dest_dx/2; j ++) {
- v = _CLIP(8,_vvtab[sv[j]] + _vutab[su[j]]);
- u = _CLIP(8,_uutab[su[j]] + _uvtab[sv[j]]);
- *(unsigned int *)(d + j*4) = u | (_yytab[sy[j*2]] << 8) | (v << 16) | (_yytab[sy[j*2+1]] << 24);
- }
- sy += yPitch;
- su += uPitch;
- sv += vPitch;
- d += dest_pitch;
- dest_dy --;
- }
- /* the main loop (processes two lines a time): */
- for (i = 0; i < dest_dy/2; i ++) {
- for (j = 0; j < dest_dx/2; j ++) {
- v = _CLIP(8,_vvtab[sv[j]] + _vutab[su[j]]);
- u = _CLIP(8,_uutab[su[j]] + _uvtab[sv[j]]);
- *(unsigned int *)(d + j*4) = u | (_yytab[sy[j*2]] << 8) | (v << 16) | (_yytab[sy[j*2+1]] << 24);
- *(unsigned int *)(d + j*4 + dest_pitch) = u | (_yytab[sy[j*2 + yPitch]] << 8) | (v << 16) | (_yytab[sy[j*2+1 + yPitch]] << 24);
- }
- sy += yPitch*2;
- su += uPitch;
- sv += vPitch;
- d += dest_pitch*2;
- }
- /* process the last line (if dy is odd): */
- if (dest_dy & 1) {
- for (j = 0; j < dest_dx/2; j ++) {
- v = _CLIP(8,_vvtab[sv[j]] + _vutab[su[j]]);
- u = _CLIP(8,_uutab[su[j]] + _uvtab[sv[j]]);
- *(unsigned int *)(d + j*4) = u | (_yytab[sy[j*2]] << 8) | (v << 16) | (_yytab[sy[j*2+1]] << 24);
- }
- }
- }
- return 0;
- }
- /* conversion is not supported */
- return -1;
- }
- /*
- * I420toUYVY() converter:
- */
- int I420toUYVY (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)
- {
- #if 1
- unsigned char *pU = src_ptr+src_height*src_pitch,
- *pV = pU + src_height*src_pitch/4;
- return I420toUYVYx(dest_ptr, dest_width, dest_height, dest_pitch, dest_x, dest_y, dest_dx, dest_dy,
- src_ptr, pU, pV,
- src_width, src_height, src_pitch, src_pitch/2, src_pitch/2,
- src_x, src_y, src_dx, src_dy);
-
- #else
- /* scale factors: */
- int scale_x, scale_y;
- /* check arguments: */
- if (!chk_args (dest_ptr, dest_width, dest_height, dest_pitch,
- dest_x, dest_y, dest_dx, dest_dy, src_ptr, src_width, src_height,
- src_pitch, src_x, src_y, src_dx, src_dy, &scale_x, &scale_y))
- return -1;
- /* remove odd destination columns: */
- if (!adjust_range (&dest_x, &dest_dx, &src_x, &src_dx, scale_x))
- return 0;
- /* check if we have misaligned input: */
- if (src_x & 1)
- return -1; /* can't shift chromas */
- /* check if bottop-up images: */
- if (dest_pitch < 0) dest_ptr -= (dest_height-1) * dest_pitch;
- if (src_pitch <= 0) return -1; /* not supported */
- /* check if 1:1 scale: */
- if (scale_x == 1 && scale_y == 1) {
- /* check if no color adjustments: */
- if (!(is_alpha | is_beta | is_gamma | is_kappa)) {
- /* no color adjustments: */
- unsigned char *sy, *sv, *su, *d;
- register int i, j;
- /* get pointers: */
- sy = src_ptr + src_x + src_y * src_pitch; /* luma offset */
- su = src_ptr + src_height * src_pitch + (src_x/2 + src_y/2 * src_pitch);
- sv = su + src_height * src_pitch / 4;
- d = dest_ptr + dest_x * 2 + dest_y * dest_pitch; /* 2 bytes/pixel */
- #if (defined(_M_IX86) || defined(_USE_MMX_BLENDERS)) && !defined(WINCE_EMULATOR)
- /* check if we can use MMX-optimized code here: */
- if (_x86_MMX_Available)
- {
- /* process top line (if chroma is not pairable): */
- if (dest_y & 1) {
- _MMX_lineI420toUYVY (sy, su, sv, d, dest_dx);
- sy += src_pitch;
- su += src_pitch/2;
- sv += src_pitch/2;
- d += dest_pitch;
- dest_dy --;
- }
- /* the main loop (processes two lines a time): */
- for (i = 0; i < dest_dy/2; i ++) {
- _MMX_lineI420toUYVY (sy, su, sv, d, dest_dx);
- sy += src_pitch;
- d += dest_pitch;
- _MMX_lineI420toUYVY (sy, su, sv, d, dest_dx);
- sy += src_pitch;
- su += src_pitch/2;
- sv += src_pitch/2;
- d += dest_pitch;
- }
- /* process the last line (if dy is odd): */
- if (dest_dy & 1) {
- _MMX_lineI420toUYVY (sy, su, sv, d, dest_dx);
- }
- /* end of MMX code */
- #if defined(_M_IX86) && !defined(WINCE_EMULATOR)
- __asm emms
- #elif defined(_USE_MMX_BLENDERS) && !defined(WINCE_EMULATOR)
- __asm__ __volatile__ ( "emms" );
- #endif
- } else
- #endif
- /* a generic "C" version: */
- {
- /* process top line (if chroma is not pairable): */
- if (dest_y & 1) {
- for (j = 0; j < dest_dx/2; j ++)
- *(unsigned int *)(d + j*4) = su[j] | (sy[j*2] << 8) | (sv[j] << 16) | (sy[j*2+1] << 24);
- sy += src_pitch;
- su += src_pitch/2;
- sv += src_pitch/2;
- d += dest_pitch;
- dest_dy --;
- }
- /* the main loop (processes two lines a time): */
- for (i = 0; i < dest_dy/2; i ++) {
- for (j = 0; j < dest_dx/2; j ++)
- *(unsigned int *)(d + j*4) = su[j] | (sy[j*2] << 8) | (sv[j] << 16) | (sy[j*2+1] << 24);
- sy += src_pitch;
- d += dest_pitch;
- for (j = 0; j < dest_dx/2; j ++)
- *(unsigned int *)(d + j*4) = su[j] | (sy[j*2] << 8) | (sv[j] << 16) | (sy[j*2+1] << 24);
- sy += src_pitch;
- su += src_pitch/2;
- sv += src_pitch/2;
- d += dest_pitch;
- }
- /* process the last line (if dy is odd): */
- if (dest_dy & 1) {
- for (j = 0; j < dest_dx/2; j ++)
- *(unsigned int *)(d + j*4) = su[j] | (sy[j*2] << 8) | (sv[j] << 16) | (sy[j*2+1] << 24);
- }
- }
- } else
- /* check if no hue adjustment: */
- if (!is_alpha) {
- /* no chroma rotation: */
- unsigned char *sy, *sv, *su, *d;
- register int i, j;
- /* get pointers: */
- sy = src_ptr + src_x + src_y * src_pitch; /* luma offset */
- su = src_ptr + src_height * src_pitch + (src_x/2 + src_y/2 * src_pitch);
- sv = su + src_height * src_pitch / 4;
- d = dest_ptr + dest_x * 2 + dest_y * dest_pitch; /* 2 bytes/pixel */
- /* process top line (if chroma is not pairable): */
- if (dest_y & 1) {
- for (j = 0; j < dest_dx/2; j ++)
- *(unsigned int *)(d + j*4) = _uutab[su[j]] | (_yytab[sy[j*2]] << 8) | (_vvtab[sv[j]] << 16) | (_yytab[sy[j*2+1]] << 24);
- sy += src_pitch;
- su += src_pitch/2;
- sv += src_pitch/2;
- d += dest_pitch;
- dest_dy --;
- }
- /* the main loop (processes two lines a time): */
- for (i = 0; i < dest_dy/2; i ++) {
- for (j = 0; j < dest_dx/2; j ++)
- *(unsigned int *)(d + j*4) = _uutab[su[j]] | (_yytab[sy[j*2]] << 8) | (_vvtab[sv[j]] << 16) | (_yytab[sy[j*2+1]] << 24);
- sy += src_pitch;
- d += dest_pitch;
- for (j = 0; j < dest_dx/2; j ++)
- *(unsigned int *)(d + j*4) = _uutab[su[j]] | (_yytab[sy[j*2]] << 8) | (_vvtab[sv[j]] << 16) | (_yytab[sy[j*2+1]] << 24);
- sy += src_pitch;
- su += src_pitch/2;
- sv += src_pitch/2;
- d += dest_pitch;
- }
- /* process the last line (if dy is odd): */
- if (dest_dy & 1) {
- for (j = 0; j < dest_dx/2; j ++)
- *(unsigned int *)(d + j*4) = _uutab[su[j]] | (_yytab[sy[j*2]] << 8) | (_vvtab[sv[j]] << 16) | (_yytab[sy[j*2+1]] << 24);
- }
- } else {
- /* the most complex case (w. hue adjustement): */
- unsigned char *sy, *sv, *su, *d;
- register int i, j, u, v;
- /* get pointers: */
- sy = src_ptr + src_x + src_y * src_pitch; /* luma offset */
- su = src_ptr + src_height * src_pitch + (src_x/2 + src_y/2 * src_pitch/2);
- sv = su + src_height * src_pitch / 4;
- d = dest_ptr + dest_x * 2 + dest_y * dest_pitch; /* 2 bytes/pixel */
- /* process top line (if chroma is not pairable): */
- if (dest_y & 1) {
- for (j = 0; j < dest_dx/2; j ++) {
- v = _CLIP(8,_vvtab[sv[j]] + _vutab[su[j]]);
- u = _CLIP(8,_uutab[su[j]] + _uvtab[sv[j]]);
- *(unsigned int *)(d + j*4) = u | (_yytab[sy[j*2]] << 8) | (v << 16) | (_yytab[sy[j*2+1]] << 24);
- }
- sy += src_pitch;
- su += src_pitch/2;
- sv += src_pitch/2;
- d += dest_pitch;
- dest_dy --;
- }
- /* the main loop (processes two lines a time): */
- for (i = 0; i < dest_dy/2; i ++) {
- for (j = 0; j < dest_dx/2; j ++) {
- v = _CLIP(8,_vvtab[sv[j]] + _vutab[su[j]]);
- u = _CLIP(8,_uutab[su[j]] + _uvtab[sv[j]]);
- *(unsigned int *)(d + j*4) = u | (_yytab[sy[j*2]] << 8) | (v << 16) | (_yytab[sy[j*2+1]] << 24);
- *(unsigned int *)(d + j*4 + dest_pitch) = u | (_yytab[sy[j*2 + src_pitch]] << 8) | (v << 16) | (_yytab[sy[j*2+1 + src_pitch]] << 24);
- }
- sy += src_pitch*2;
- su += src_pitch/2;
- sv += src_pitch/2;
- d += dest_pitch*2;
- }
- /* process the last line (if dy is odd): */
- if (dest_dy & 1) {
- for (j = 0; j < dest_dx/2; j ++) {
- v = _CLIP(8,_vvtab[sv[j]] + _vutab[su[j]]);
- u = _CLIP(8,_uutab[su[j]] + _uvtab[sv[j]]);
- *(unsigned int *)(d + j*4) = u | (_yytab[sy[j*2]] << 8) | (v << 16) | (_yytab[sy[j*2+1]] << 24);
- }
- }
- }
- return 0;
- }
- /* conversion is not supported */
- return -1;
- #endif //0
- }
- /*** "to I420" converters: *********************************/
- int YV12toI420x (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))
- // return -1; /* can't shift chromas */
- /* check if bottop-up images: */
- if (dest_pitch <= 0 || yPitch <= 0)
- return -1; /* not supported */
- /*
- * if (!is_dest_alpha && !is_dest_beta && !is_dest_gamma && !is_dest_kappa)
- */
- {
- /* just move data in, no color adjustments: */
- unsigned char *sy, *su, *sv, *d, *su2, *sv2;
- int dest_uv_offs;
- register int i,j;
- /* copy Y plane: */
- sy = pY + src_x + src_y * yPitch;
- d = dest_ptr + dest_x + dest_y * dest_pitch;
- for (i = 0; i < dest_dy; i ++) {
- memcpy (d, sy, dest_dx); /* Flawfinder: ignore */
- sy += yPitch;
- d += dest_pitch;
- }
- /* get Cr/Cb offsets: */
- dest_uv_offs = dest_height * dest_pitch / 4;
- /* copy & flip Cr/Cb planes: */
- su = pU + src_x/2 + src_y/2 * uPitch;
- sv = 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);
- // extremely cheap way to handle 1 pel cropping
- for (i = 0; i < dest_dy/2; i ++) {
- if((i+1) < dest_dy/2) {
- su2 = su+uPitch;
- sv2 = sv+vPitch;
- } else {
- su2 = su;
- sv2 = sv;
- }
- /* convert pixels: */
- switch(OddPattern)
- {
- case(0):
- memcpy (d, su, dest_dx/2); /* Flawfinder: ignore */
- memcpy (d + dest_uv_offs, sv, dest_dx/2); /* Flawfinder: ignore */
- break;
- case(1):
- for (j = 0; j < dest_dx/2 -1; j ++) {
- d[j] = ((unsigned int)su[j] + (unsigned int)su[j+1] + 1)>>1;
- d[j + dest_uv_offs] = ((unsigned int)sv[j] + (unsigned int)sv[j+1] + 1)>>1;
- }
- d[j] = su[j];
- d[j + dest_uv_offs] = sv[j];
- break;
- case(2):
- for (j = 0; j < dest_dx/2; j ++) {
- d[j] = ((unsigned int)su[j] + (unsigned int)su2[j] + 1)>>1;
- d[j + dest_uv_offs] = ((unsigned int)sv[j] + (unsigned int)sv2[j] + 1)>>1;
- }
- break;
- case(3):
- for (j = 0; j < dest_dx/2 -1; j ++) {
- d[j] = ((unsigned int)su[j] + (unsigned int)su[j+1] + (unsigned int)su2[j] + (unsigned int)su2[j+1] + 2)>>2;
- d[j + dest_uv_offs] = ((unsigned int)sv[j] + (unsigned int)sv[j+1] + (unsigned int)sv2[j] + (unsigned int)sv2[j+1] + 2)>>2;
- }
- d[j] = ((unsigned int)su[j]+ (unsigned int)su2[j] + 1)>>1;
- d[j + dest_uv_offs] = ((unsigned int)sv[j] + (unsigned int)sv2[j] + 1) >> 1;
- break;
- }
- su += uPitch;
- sv += vPitch;
- d += dest_pitch/2;
- }
- }
- /*
- * else {
- * put all the color-dependent stuff here ...
- * }
- */
- return 0;
- }
- int YV12toI420 (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)
- {
- #if 1
- unsigned char *pV = src_ptr+src_height*src_pitch,
- *pU = pV + src_height*src_pitch/4;
- return YV12toI420x(dest_ptr, dest_width, dest_height, dest_pitch, dest_x, dest_y, dest_dx, dest_dy,
- src_ptr, pU, pV,
- src_width, src_height, src_pitch, src_pitch/2, src_pitch/2,
- src_x, src_y, src_dx, src_dy);
- #else
- /* scale factors: */
- int scale_x, scale_y;
- /* check arguments: */
- if (!chk_args (dest_ptr, dest_width, dest_height, dest_pitch,
- dest_x, dest_y, dest_dx, dest_dy, src_ptr, src_width, src_height,
- src_pitch, 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))
- return -1; /* can't shift chromas */
- /* check if bottop-up images: */
- if (dest_pitch <= 0 || src_pitch <= 0)
- return -1; /* not supported */
- /*
- * if (!is_dest_alpha && !is_dest_beta && !is_dest_gamma && !is_dest_kappa)
- */
- {
- /* just move data in, no color adjustments: */
- unsigned char *s, *d;
- int src_uv_offs, dest_uv_offs;
- register int i;
- /* copy Y plane: */
- s = src_ptr + src_x + src_y * src_pitch;
- d = dest_ptr + dest_x + dest_y * dest_pitch;
- for (i = 0; i < dest_dy; i ++) {
- memcpy (d, s, dest_dx); /* Flawfinder: ignore */
- s += src_pitch;
- d += dest_pitch;
- }
- /* get Cr/Cb offsets: */
- src_uv_offs = src_height * src_pitch / 4;
- dest_uv_offs = dest_height * dest_pitch / 4;
- /* copy & flip Cr/Cb planes: */
- s = (src_ptr + src_height * src_pitch) + src_x/2 + src_y/2 * src_pitch/2;
- d = (dest_ptr + dest_height * dest_pitch) + dest_x/2 + dest_y/2 * dest_pitch/2;
- for (i = 0; i < dest_dy/2; i ++) {
- memcpy (d, s + src_uv_offs, dest_dx/2); /* Flawfinder: ignore */
- memcpy (d + dest_uv_offs, s, dest_dx/2); /* Flawfinder: ignore */
- s += src_pitch/2;
- d += dest_pitch/2;
- }
- }
- /*
- * else {
- * put all the color-dependent stuff here ...
- * }
- */
- return 0;
- #endif
- }
- int YV12toYV12x (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)
- {
- return I420toYV12x(dest_ptr, dest_width, dest_height, dest_pitch, dest_x, dest_y, dest_dx, dest_dy,
- pY, pU, pV,
- src_width, src_height, yPitch, uPitch, vPitch,
- src_x, src_y, src_dx, src_dy);
- }
- int YV12toYV12 (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)
- {
- unsigned char *pV = src_ptr+src_height*src_pitch,
- *pU = pV + src_height*src_pitch/4;
- return I420toYV12x(dest_ptr, dest_width, dest_height, dest_pitch, dest_x, dest_y, dest_dx, dest_dy,
- src_ptr, pU, pV,
- src_width, src_height, src_pitch, src_pitch/2, src_pitch/2,
- src_x, src_y, src_dx, src_dy);
- }
- int YV12toYUY2x (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)
- {
- return I420toYUY2x(dest_ptr, dest_width, dest_height, dest_pitch, dest_x, dest_y, dest_dx, dest_dy,
- pY, pU, pV,
- src_width, src_height, yPitch, uPitch, vPitch,
- src_x, src_y, src_dx, src_dy);
- }
- int YV12toYUY2 (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)
- {
- unsigned char *pV = src_ptr+src_height*src_pitch,
- *pU = pV + src_height*src_pitch/4;
- return I420toYUY2x(dest_ptr, dest_width, dest_height, dest_pitch, dest_x, dest_y, dest_dx, dest_dy,
- src_ptr, pU, pV,
- src_width, src_height, src_pitch, src_pitch/2, src_pitch/2,
- src_x, src_y, src_dx, src_dy);
- }
- int YV12toUYVYx (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)
- {
- return I420toUYVYx(dest_ptr, dest_width, dest_height, dest_pitch, dest_x, dest_y, dest_dx, dest_dy,
- pY, pU, pV,
- src_width, src_height, yPitch, uPitch, vPitch,
- src_x, src_y, src_dx, src_dy);
- }
- int YV12toUYVY (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)
- {
- unsigned char *pV = src_ptr+src_height*src_pitch,
- *pU = pV + src_height*src_pitch/4;
- return I420toUYVYx(dest_ptr, dest_width, dest_height, dest_pitch, dest_x, dest_y, dest_dx, dest_dy,
- src_ptr, pU, pV,
- src_width, src_height, src_pitch, src_pitch/2, src_pitch/2,
- src_x, src_y, src_dx, src_dy);
- }
- static void lineYVU9toI420 (unsigned char *d, unsigned char *s, int x, int dx)
- {
- register int i;
- /* first pixel: */
- // extremely cheap way to handle 1 pel cropping
- switch(x&3)
- {
- case(0):
- case(1):
- break;
- case(2):
- d[0] = s[0];
- s += 1;
- d += 1;
- dx -= 2;
- break;
- case(3):
- //d[0] = s[0];
- s += 1;
- //d += 1;
- //dx -= 2;
- break;
- }
- /* the main loop: */
- for (i = 0; i < dx/4; i ++) {
- d[i*2] = s[i];
- d[i*2+1] = s[i];
- }
- /* last pixel: */
- if (dx & 2)
- d[dx/2] = s[dx/4];
- }
- #if 1
- /*-----------------2/24/2002 2:01PM-----------------
- * fixes:
- * - switched u and v pointers
- * --------------------------------------------------*/
- int YVU9toI420 (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)
- {
- /* scale factors: */
- int scale_x, scale_y;
- /* check arguments: */
- if (!chk_args (dest_ptr, dest_width, dest_height, dest_pitch,
- dest_x, dest_y, dest_dx, dest_dy, src_ptr, src_width, src_height,
- src_pitch, 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))
- //return -1; /* can't shift chromas */
- /* check if bottop-up images: */
- if (dest_pitch <= 0 || src_pitch <= 0)
- return -1; /* not supported */
- /*
- * if (!is_dest_alpha && !is_dest_beta && !is_dest_gamma && !is_dest_kappa)
- */
- {
- /* no color adjustments: */
- unsigned char *s, *d;
- int src_uv_offs, dest_uv_offs;
- register int j;
- /* copy Y plane: */
- s = src_ptr + src_x + src_y * src_pitch;
- d = dest_ptr + dest_x + dest_y * dest_pitch;
- for (j = 0; j < dest_dy; j ++) {
- memcpy (d, s, dest_dx); /* Flawfinder: ignore */
- s += src_pitch;
- d += dest_pitch;
- }
- /* get Cr/Cb offsets: */
- src_uv_offs = src_height * src_pitch / 16;
- dest_uv_offs = dest_height * dest_pitch / 4;
- /* get pointers: */
- s = (src_ptr + src_height * src_pitch) + src_x/4 + src_y/4 * src_pitch/4;
- d = (dest_ptr + dest_height * dest_pitch) + dest_x/2 + dest_y/2 * dest_pitch/2;
- /* top lines: */
- // extremely cheap way to handle 1 pel cropping
- switch(src_y & 3)
- {
- case(2):
- case(3):
- lineYVU9toI420 (d, s + src_uv_offs, src_x, dest_dx); /* Cr */
- lineYVU9toI420 (d + dest_uv_offs, s, src_x, dest_dx); /* Cb */
- s += src_pitch/4;
- d += dest_pitch/2;
- dest_dy -= 2;
- break;
- case(0):
- case(1):
- break;
- }
- /* the main loop (processes two lines a time): */
- for (j = 0; j < dest_dy/4; j ++) {
- lineYVU9toI420 (d, s + src_uv_offs, src_x, dest_dx); /* Cr */
- memcpy (d + dest_pitch/2, d, dest_dx/2); /* Flawfinder: ignore */
- lineYVU9toI420 (d + dest_uv_offs, s, src_x, dest_dx); /* Cb */
- memcpy (d + dest_pitch/2 + dest_uv_offs, d + dest_uv_offs, dest_dx/2); /* Flawfinder: ignore */
- s += src_pitch/4;
- d += dest_pitch;
- }
- /* bottom lines: */
- if (dest_dy & 2) {
- lineYVU9toI420 (d, s + src_uv_offs, src_x, dest_dx); /* Cr */
- lineYVU9toI420 (d + dest_uv_offs, s, src_x, dest_dx); /* Cb */
- }
- }
- /*
- * else {
- * put all the color-dependent stuff here ...
- * }
- */
- return 0;
- }
- #else
- int YVU9toI420 (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)
- {
- /* scale factors: */
- int scale_x, scale_y;
- /* check arguments: */
- if (!chk_args (dest_ptr, dest_width, dest_height, dest_pitch,
- dest_x, dest_y, dest_dx, dest_dy, src_ptr, src_width, src_height,
- src_pitch, 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))
- return -1; /* can't shift chromas */
- /* check if bottop-up images: */
- if (dest_pitch <= 0 || src_pitch <= 0)
- return -1; /* not supported */
- /*
- * if (!is_dest_alpha && !is_dest_beta && !is_dest_gamma && !is_dest_kappa)
- */
- {
- /* no color adjustments: */
- unsigned char *s, *d;
- int src_uv_offs, dest_uv_offs;
- register int j;
- /* copy Y plane: */
- s = src_ptr + src_x + src_y * src_pitch;
- d = dest_ptr + dest_x + dest_y * dest_pitch;
- for (j = 0; j < dest_dy; j ++) {
- memcpy (d, s, dest_dx); /* Flawfinder: ignore */
- s += src_pitch;
- d += dest_pitch;
- }
- /* get Cr/Cb offsets: */
- src_uv_offs = src_height * src_pitch / 16;
- dest_uv_offs = dest_height * dest_pitch / 4;
- /* get pointers: */
- s = (src_ptr + src_height * src_pitch) + src_x/4 + src_y/4 * src_pitch/4;
- d = (dest_ptr + dest_height * dest_pitch) + dest_x/2 + dest_y/2 * dest_pitch/2;
- /* top lines: */
- if (src_y & 2) {
- lineYVU9toI420 (d, s, src_x, dest_dx); /* Cr */
- lineYVU9toI420 (d + dest_uv_offs, s + src_uv_offs, src_x, dest_dx); /* Cb */
- s += src_pitch/4;
- d += dest_pitch/2;
- dest_dy -= 2;
- }
- /* the main loop (processes two lines a time): */
- for (j = 0; j < dest_dy/4; j ++) {
- lineYVU9toI420 (d, s, src_x, dest_dx); /* Cr */
- memcpy (d + dest_pitch/2, d, dest_dx/2); /* Flawfinder: ignore */
- lineYVU9toI420 (d + dest_uv_offs, s + src_uv_offs, src_x, dest_dx); /* Cb */
- memcpy (d + dest_pitch/2 + dest_uv_offs, d + dest_uv_offs, dest_dx/2); /* Flawfinder: ignore */
- s += src_pitch/4;
- d += dest_pitch;
- }
- /* bottom lines: */
- if (dest_dy & 2) {
- lineYVU9toI420 (d, s, src_x, dest_dx); /* Cr */
- lineYVU9toI420 (d + dest_uv_offs, s + src_uv_offs, src_x, dest_dx); /* Cb */
- }
- }
- /*
- * else {
- * put all the color-dependent stuff here ...
- * }
- */
- return 0;
- }
- #endif /* YUV9 */
- 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)
- {
- /* scale factors: */
- int scale_x, scale_y;
- unsigned char *s1, *s2, *d1, *d2, *dv, *du;
- register int i, j;
- /* check arguments: */
- if (!chk_args (dY, dest_width, dest_height, dyPitch,
- dest_x, dest_y, dest_dx, dest_dy, src_ptr, src_width, src_height,
- src_pitch, 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 misaligned source: */
- if (src_x & 1)
- return -1; /* can't shift chromas */
- /* check if bottop-up images: */
- if (dyPitch <= 0)
- return -1; /* not supported */
- if (src_pitch < 0)
- src_ptr -= (src_height-1) * src_pitch;
- /* just move data in, no color adjustments: */
- /* get pointers: */
- s1 = src_ptr + src_x * 2 + src_y * src_pitch; /* 2 bytes/pixel */
- s2 = s1 + src_pitch;
- d1 = dY + dest_x + dest_y * dyPitch; /* luma offsets */
- d2 = d1 + dyPitch;
-
- du = dU + (dest_x/2 + dest_y/2 * duPitch);
- dv = dV + (dest_x/2 + dest_y/2 * dvPitch);
- #if (defined(_M_IX86) || defined(_USE_MMX_BLENDERS)) && !defined(WINCE_EMULATOR)
- if (_x86_MMX_Available )
- {
- //Use our MMX versions.....
- HX_ASSERT( src_dx==dest_dx && src_dy==dest_dy );
- YUY2ToPlanarYUV_MMX( d1, d2, du, dv,
- dyPitch, duPitch, dvPitch,
- dest_dx, dest_dy,
- s1, s2, src_pitch
- );
- }
- else
- #endif
- {
- /* the main loop (processes lines a time): */
- for (i = 0; i < dest_dy/2; i ++)
- {
- /* copy 2x2 pixels: */
- for (j = 0; j < dest_dx/2; j ++)
- {
- /* copy luma components: */
- d1[j*2] = s1[j*4];
- d1[j*2+1] = s1[j*4+2];
- d2[j*2] = s2[j*4];
- d2[j*2+1] = s2[j*4+2];
-
- /* average chromas: */
- du[j] = ((unsigned int) s1[j*4+1] + (unsigned int)s2[j*4+1]) >> 1;
- dv[j] = ((unsigned int) s1[j*4+3] + (unsigned int)s2[j*4+3]) >> 1;
- }
-
- s1 += src_pitch*2; s2 += src_pitch*2;
- d1 += dyPitch*2; d2 += dyPitch*2;
- du += duPitch; dv += dvPitch;
- }
- }
- return 0;
- }
- int YUY2toI420x (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)
- {
- // No need for seperate yuv pointers since yuy2 is packed
- return YUY2toI420(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);
- }
- /*
- * Mac YUVU/YVU2 formats:
- * 8-bit 4:2:2 Component Y扖bCr format.
- * Each 16 bit pixel is represented by an unsigned eight bit luminance
- * component and two two抯 complement signed eight bit chroma components.
- * Each pair of pixels shares a common set of chroma values.
- * The components are ordered in memory; Y0, Cb, Y1, Cr.
- * The luminance components have a range of [0, 255],
- * the chroma values have a range of [-127, +127].
- * This format is equivalent to the 憏uv2