summaryrefslogtreecommitdiffstatshomepage
path: root/src/osd/modules/render/copyutil.h
blob: 715fcba0dca3413a822294a9a1796f774be87640 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
// license:BSD-3-Clause
// copyright-holders:Ryan Holtz
//============================================================
//
//  copyutil.h - bitmap-conversion functions
//
//============================================================

#pragma once

#ifndef __RENDER_COPYUTIL__
#define __RENDER_COPYUTIL__


class copy_util
{
public:
	static inline void copyline_palette16(uint32_t *dst, const uint16_t *src, int width, const rgb_t *palette)
	{
		for (int x = 0; x < width; x++)
		{
			rgb_t srcpixel = palette[*src++];
			*dst++ = 0xff000000 | (srcpixel.b() << 16) | (srcpixel.g() << 8) | srcpixel.r();
		}
	}

	static inline void copyline_rgb32(uint32_t *dst, const uint32_t *src, int width, const rgb_t *palette)
	{
		int x;

		// palette (really RGB map) case
		if (palette != nullptr)
		{
			for (x = 0; x < width; x++)
			{
				rgb_t srcpix = *src++;
				*dst++ = 0xff000000 | palette[0x200 + srcpix.b()] | palette[0x100 + srcpix.g()] | palette[srcpix.r()];
			}
		}

		// direct case
		else
		{
			for (x = 0; x < width; x++)
			{
				rgb_t srcpix = *src++;
				*dst++ = 0xff000000 | (srcpix.b() << 16) | (srcpix.g() << 8) | srcpix.r();
			}
		}
	}

	static inline void copyline_argb32(uint32_t *dst, const uint32_t *src, int width, const rgb_t *palette)
	{
		int x;
		// palette (really RGB map) case
		if (palette != nullptr)
		{
			for (x = 0; x < width; x++)
			{
				rgb_t srcpix = *src++;
				*dst++ = (srcpix & 0xff000000) | palette[0x200 + srcpix.b()] | palette[0x100 + srcpix.g()] | palette[srcpix.r()];
			}
		}

		// direct case
		else
		{
			for (x = 0; x < width; x++)
			{
				rgb_t srcpix = *src++;
				*dst++ = (srcpix.a() << 24) | (srcpix.b() << 16) | (srcpix.g() << 8) | srcpix.r();
			}
		}
	}

	static inline uint32_t ycc_to_rgb(uint8_t y, uint8_t cb, uint8_t cr)
	{
		/* original equations:

		C = Y - 16
		D = Cb - 128
		E = Cr - 128

		R = clip(( 298 * C           + 409 * E + 128) >> 8)
		G = clip(( 298 * C - 100 * D - 208 * E + 128) >> 8)
		B = clip(( 298 * C + 516 * D           + 128) >> 8)

		R = clip(( 298 * (Y - 16)                    + 409 * (Cr - 128) + 128) >> 8)
		G = clip(( 298 * (Y - 16) - 100 * (Cb - 128) - 208 * (Cr - 128) + 128) >> 8)
		B = clip(( 298 * (Y - 16) + 516 * (Cb - 128)                    + 128) >> 8)

		R = clip(( 298 * Y - 298 * 16                        + 409 * Cr - 409 * 128 + 128) >> 8)
		G = clip(( 298 * Y - 298 * 16 - 100 * Cb + 100 * 128 - 208 * Cr + 208 * 128 + 128) >> 8)
		B = clip(( 298 * Y - 298 * 16 + 516 * Cb - 516 * 128                        + 128) >> 8)

		R = clip(( 298 * Y - 298 * 16                        + 409 * Cr - 409 * 128 + 128) >> 8)
		G = clip(( 298 * Y - 298 * 16 - 100 * Cb + 100 * 128 - 208 * Cr + 208 * 128 + 128) >> 8)
		B = clip(( 298 * Y - 298 * 16 + 516 * Cb - 516 * 128                        + 128) >> 8)
		*/
		int r, g, b, common;

		common = 298 * y - 298 * 16;
		r = (common + 409 * cr - 409 * 128 + 128) >> 8;
		g = (common - 100 * cb + 100 * 128 - 208 * cr + 208 * 128 + 128) >> 8;
		b = (common + 516 * cb - 516 * 128 + 128) >> 8;

		if (r < 0) r = 0;
		else if (r > 255) r = 255;
		if (g < 0) g = 0;
		else if (g > 255) g = 255;
		if (b < 0) b = 0;
		else if (b > 255) b = 255;

		return 0xff000000 | (b << 16) | (g << 8) | r;
	}

	static inline void copyline_yuy16_to_argb(uint32_t *dst, const uint16_t *src, int width, const rgb_t *palette, int xprescale)
	{
		int x;

		assert(width % 2 == 0);

		// palette (really RGB map) case
		if (palette != nullptr)
		{
			for (x = 0; x < width / 2; x++)
			{
				uint16_t srcpix0 = *src++;
				uint16_t srcpix1 = *src++;
				uint8_t cb = srcpix0 & 0xff;
				uint8_t cr = srcpix1 & 0xff;
				for (int x2 = 0; x2 < xprescale; x2++)
					*dst++ = ycc_to_rgb(palette[0x000 + (srcpix0 >> 8)], cb, cr);
				for (int x2 = 0; x2 < xprescale; x2++)
					*dst++ = ycc_to_rgb(palette[0x000 + (srcpix1 >> 8)], cb, cr);
			}
		}

		// direct case
		else
		{
			for (x = 0; x < width; x += 2)
			{
				uint16_t srcpix0 = *src++;
				uint16_t srcpix1 = *src++;
				uint8_t cb = srcpix0 & 0xff;
				uint8_t cr = srcpix1 & 0xff;
				for (int x2 = 0; x2 < xprescale; x2++)
					*dst++ = ycc_to_rgb(srcpix0 >> 8, cb, cr);
				for (int x2 = 0; x2 < xprescale; x2++)
					*dst++ = ycc_to_rgb(srcpix1 >> 8, cb, cr);
			}
		}
	}
};

#endif // __RENDER_COPYUTIL__