<commit_before>/*
 *			GPAC - Multimedia Framework C SDK
 *
 *			Authors: <NAME>
 *			Copyright (c) Telecom ParisTech 2019
 *					All rights reserved
 *
 *  This file is part of GPAC / software 2D rasterizer module
 *
 *  GPAC is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as published by
 *  the Free Software Foundation; either version 2, or (at your option)
 *  any later version.
 *
 *  GPAC is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; see the file COPYING.  If not, write to
 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 *
 *
 */

#include "rast_soft.h"

//TODO: support for color spaces, support for more than 10 bits and BigEndian format ?

#if 1

#define mul255(_a, _b)  ( (((u32)(_a) + 1) * (u32)(_b) ) >> 8)

#else
static s32
mul255(s32 a, s32 b)
{
	return ((a + 1) * b) >> 8;
}
#endif

static s32
mul255_zero(s32 a, s32 b)
{
	if (!a) return 0;
	return ((a + 1) * b) >> 8;
}

void evg_rgb_to_yuv(GF_EVGSurface *surf, GF_Color col, u8*y, u8*cb, u8*cr)
{
	u32 r = GF_COL_R(col);
	u32 g = GF_COL_G(col);
	u32 b = GF_COL_B(col);

	*y = (u8) (0.299*r + 0.587 * g + 0.114 * b);
	*cb = (u8) (-0.169*(s32)r - 0.331*(s32)g + 0.499*b + 128);
	*cr = (u8) (0.499 * r - 0.418*(s32)g - 0.0813*(s32)b + 128);
}
GF_Color evg_argb_to_ayuv(GF_EVGSurface *surf, GF_Color col)
{
	u8 a, y, cb, cr;
	a = GF_COL_A(col);
	u32 r = GF_COL_R(col);
	u32 g = GF_COL_G(col);
	u32 b = GF_COL_B(col);

	y = (u8) (0.299*r + 0.587 * g + 0.114 * b);
	cb = (u8) (-0.169*(s32)r - 0.331*(s32)g + 0.499*b + 128);
	cr = (u8) (0.499 * r - 0.418*(s32)g - 0.0813*(s32)b + 128);
	return GF_COL_ARGB(a, y, cb, cr);
}

GF_Color evg_ayuv_to_argb(GF_EVGSurface *surf, GF_Color col)
{
	u32 a;
	s32 y, cb, cr;
	s32 r, g, b;
	a = GF_COL_A(col);
	y = GF_COL_R(col);
	cb = GF_COL_G(col);
	cr = GF_COL_B(col);

	r = (s32) (y + 1.402 * (cr - 128));
	g = (s32) (y - 0.344136 * (cb - 128) - 0.714136*(cr-128) );
	b = (s32) (y + 1.772 * (cb - 128) );
#define TRUNC_8BIT(_a) if (_a<0) {_a = 0;} else if (_a>255) {_a=255;}
	TRUNC_8BIT(r)
	TRUNC_8BIT(g)
	TRUNC_8BIT(b)
	return GF_COL_ARGB(a, r, g, b);
}

u64 evg_argb_to_ayuv_wide(GF_EVGSurface *surf, u64 col)
{
	u16 a, y, cb, cr;
	u32 r, g, b;
	a = (col>>48)&0xFFFF;
	r = (col>>32)&0xFFFF;
	g = (col>>16)&0xFFFF;
	b = (col)&0xFFFF;

	y = (u16) (0.299*r + 0.587 * g + 0.114 * b);
	cb = (u16) (-0.169*(s32)r - 0.331*(s32)g + 0.499*b + 32768);
	cr = (u16) (0.499 * r - 0.418*(s32)g - 0.0813*(s32)b + 32768);

	return evg_make_col_wide(a, y, cb, cr);
}
u64 evg_ayuv_to_argb_wide(GF_EVGSurface *surf, u64 col)
{
	u32 a;
	s64 y, cb, cr;
	s32 r, g, b;
	a = (col>>48)&0xFFFF;
	y = (col>>32)&0xFFFF;
	cb = (col>>16)&0xFFFF;
	cr = (col)&0xFFFF;

	r = (s32) (y + 1.402 * (cr - 32768));
	g = (s32) (y - 0.344136 * (cb - 32768) - 0.714136*(cr-32768) );
	b = (s32) (y + 1.772 * (cb - 32768) );
#define TRUNC_16BIT(_a) if (_a<0) {_a = 0;} else if (_a>32768) {_a=32768;}
	TRUNC_16BIT(r)
	TRUNC_16BIT(g)
	TRUNC_16BIT(b)

	return evg_make_col_wide(a, r, g, b);
}

void evg_make_ayuv_color_mx(GF_ColorMatrix *cmat, GF_ColorMatrix *yuv_cmat)
{
	GF_ColorMatrix cmx_y2r, cmx_r2y;
	gf_cmx_init(&cmx_r2y);
	gf_cmx_init(&cmx_y2r);
	cmx_r2y.identity = cmx_y2r.identity = GF_FALSE;

	//r = (s32) (y + 1.402 * (cr - 128));
	cmx_y2r.m[0] = FIX_ONE; //y
	cmx_y2r.m[2] = FLT2FIX(1.402); //cr
	cmx_y2r.m[4] = FLT2FIX(-1.402 * 0.504); //tr

	//g = (s32) (y - 0.344136 * (cb - 128) - 0.714136*(cr-128) );
	cmx_y2r.m[5] = FIX_ONE; //y
	cmx_y2r.m[6] = FLT2FIX(- 0.344136); //cb<commit_msg>move yuv-rgb conversions to int in evg<commit_after>/*
 *			GPAC - Multimedia Framework C SDK
 *
 *			Authors: <NAME>
 *			Copyright (c) Telecom ParisTech 2019
 *					All rights reserved
 *
 *  This file is part of GPAC / software 2D rasterizer module
 *
 *  GPAC is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as published by
 *  the Free Software Foundation; either version 2, or (at your option)
 *  any later version.
 *
 *  GPAC is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; see the file COPYING.  If not, write to
 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 *
 *
 */

#include "rast_soft.h"

//TODO: support for color spaces, support for more than 10 bits and BigEndian format ?

#if 1

#define mul255(_a, _b)  ( (((u32)(_a) + 1) * (u32)(_b) ) >> 8)

#else
static s32
mul255(s32 a, s32 b)
{
	return ((a + 1) * b) >> 8;
}
#endif

static s32
mul255_zero(s32 a, s32 b)
{
	if (!a) return 0;
	return ((a + 1) * b) >> 8;
}

//RGB <-> YUV full range conversion, using integer (1024 factor)
#define YUV_USE_INT

void evg_rgb_to_yuv(GF_EVGSurface *surf, GF_Color col, u8*y, u8*cb, u8*cr)
{
	u32 r = GF_COL_R(col);
	u32 g = GF_COL_G(col);
	u32 b = GF_COL_B(col);

#ifndef YUV_USE_INT
	*y = (u8) (0.299*r + 0.587 * g + 0.114 * b);
	*cb = (u8) (-0.169*(s32)r - 0.331*(s32)g + 0.499*b + 128);
	*cr = (u8) (0.499 * r - 0.418*(s32)g - 0.0813*(s32)b + 128);
#else
	u32 _v = 306*r + 601 * g + 117 * b;
	*y = (u8) (_v >> 10);
	_v = (-173*(s32)r - 339*(s32)g + 511*b + 131072);
	*cb = (u8) (_v >> 10);
	_v = (511 * r - 428*(s32)g - 83*(s32)b + 131072);
	*cr = (u8) (_v >> 10);
#endif

}
GF_Color evg_argb_to_ayuv(GF_EVGSurface *surf, GF_Color col)
{
	u8 a, y, cb, cr;
	a = GF_COL_A(col);
	u32 r = GF_COL_R(col);
	u32 g = GF_COL_G(col);
	u32 b = GF_COL_B(col);

#ifndef YUV_USE_INT
	y = (u8) (0.299*r + 0.587 * g + 0.114 * b);
	cb = (u8) (-0.169*(s32)r - 0.331*(s32)g + 0.499*b + 128);
	cr = (u8) (0.499 * r - 0.418*(s32)g - 0.0813*(s32)b + 128);
#else
	u32 _v = 306*r + 601 * g + 117 * b;
	y = (u8) (_v >> 10);
	_v = (-173*(s32)r - 339*(s32)g + 511*b + 131072);
	cb = (u8) (_v >> 10);
	_v = (511 * r - 428*(s32)g - 83*(s32)b + 131072);
	cr = (u8) (_v >> 10);
#endif
	return GF_COL_ARGB(a, y, cb, cr);
}

GF_Color evg_ayuv_to_argb(GF_EVGSurface *surf, GF_Color col)
{
	u32 a;
	s32 y, cb, cr;
	s32 r, g, b;
	a = GF_COL_A(col);
	y = GF_COL_R(col);
	cb = GF_COL_G(col);
	cr = GF_COL_B(col);

#ifndef YUV_USE_INT
	r = (s32) (y + 1.402 * (cr - 128));
	g = (s32) (y - 0.344136 * (cb - 128) - 0.714136*(cr-128) );
	b = (s32) (y + 1.772 * (cb - 128) );

#define TRUNC_8BIT(_a) if (_a<0) {_a = 0;} else if (_a>255) {_a=255;}
	TRUNC_8BIT(r)
	TRUNC_8BIT(g)
	TRUNC_8BIT(b)

#else
	y *= 1024;
	r = (s32) (y + 1436 * (cr - 128));
	g = (s32) (y - 352 * (cb - 128) - 731*(cr-128) );
	b = (s32) (y + 1814 * (cb - 128) );

#define TRUNC_8BIT(_a) if (_a<0) {_a = 0;} else { u32 __a = (u32) _a; __a>>=10; if (__a>255) {__a=255;} _a = __a; }
	TRUNC_8BIT(r)
	TRUNC_8BIT(g)
	TRUNC_8BIT(b)

#endif


	return GF_COL_ARGB(a, r, g, b);
}

u64 evg_argb_to_ayuv_wide(GF_EVGSurface *surf, u64 col)
{
	u16 a, y, cb, cr;
	u32 r, g, b;

	a = (col>>48)&0xFFFF;
	r = (col>>32)&0xFFFF;
	g = (col>>16)&0xFFFF;
	b = (col)&0xFFFF;

#ifndef YUV_USE_INT
	y = (u16) (0.299*r + 0.587 * g + 0.114 * b);
	cb = (u16) (-0.169*(s32)r - 0.331*(s32)g + 0.499*b + 32768);
	cr = (u16) (0.499 * r - 0.418*(s32)g - 0.0813*(s32)b + 32768);
#else
	u32 _v = 306*r + 601 * g + 117 * b;
	y = (u16) (_v >> 10);
	_v = (-173*(s32)r - 339*(s32)g + 511*b + 33554432);
	cb = (u16) (_v >> 10);
	_v = (511 * r - 428*(s32)g - 83*(s32)b + 33554432);
	cr = (u16) (_v >> 10);
#endif


	return evg_make_col_wide(a, y, cb, cr);
}
u64 evg_ayuv_to_argb_wide(GF_EVGSurface *surf, u64 col)
{
	u32 a;
	s64 y, cb, cr;
	s32 r, g, b;
	a = (col>>48)&0xFFFF;
	y = (col>>32)&0xFFFF;
	cb = (col>>16)&0xFFFF;
	cr = (col)&0xFFFF;

#ifndef YUV_USE_INT
	r = (s32) (y + 1.402 * (cr - 32768));
	g = (s32) (y - 0.344136 * (cb - 32768) - 0.714136*(cr-32768) );
	b = (s32) (y + 1.772 * (cb - 32768) );
#define TRUNC_16BIT(_a) if (_a<0) {_a = 0;} else if (_a>32768) {_a=32768;}
	TRUNC_16BIT(r)
	TRUNC_16BIT(g)
	TRUNC_16BIT(b)

#else
	y *= 1024;
	r = (s32) (y + 1436 * (cr - 32768));
	g = (s32) (y - 352 * (cb - 32768) - 731*(cr-32768) );
	b = (s32) (y + 1814 * (cb - 32768) );

#define TRUNC_16BIT(_a) if (_a<0) {_a = 0;} else { u32 __a = (u32) _a; __a>>=10; if (__a>32768) {__a=32768;} _a = __a; }
	TRUNC_16BIT(r)
	TRUNC_16BIT(g)
	TRUNC_16BIT(b)

#endif

	return evg_make_col_wide(a, r, g, b);
}

void evg_make_ayuv_color_mx(GF_ColorMatrix *cmat, GF_ColorMatrix *yuv_cmat)
{
	GF_ColorMatrix cmx_y2r, cmx_r2y;
	gf_cmx_init(&cmx_r2y);
	gf_cmx_init(&cmx_y2r);
	cmx_r2y.identity = cmx_y2r.identity = GF_FALSE;

	//r = (s32) (y + 1.402 * (cr - 128));
	cmx_y2r.m[0] = FIX_ONE; //y
	cmx_y2r.m[2] = FLT2FIX(1.402); //cr
	cmx_y2r.m[4] = FLT2FIX(-1.402 * 0.504); //tr

	//g = (s32) (y - 0.344136 * (cb - 128) - 0.714136*(cr-128) );
	cmx_y2r.m[5] = FIX_ONE; //y
	cmx_y2r.m[6] = FLT2FIX(- 0.344136); //cb
{'fraction_non_alphanumeric': 0.18986931634085755, 'fraction_numerical': 0.13392374986499622, 'mean_word_length': 3.2712177121771218, 'pattern_counts': {'":': 0, '<': 12, '<?xml version=': 0, '>': 70, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2808408', 'n_tokens_mistral': 5410, 'n_tokens_neox': 4556, 'n_words': 1176}