• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 #include <kms++/kms++.h>
3 #include <kms++util/kms++util.h>
4 
5 using namespace std;
6 
7 namespace kms
8 {
draw_rgb_pixel(IFramebuffer & buf,unsigned x,unsigned y,RGB color)9 void draw_rgb_pixel(IFramebuffer& buf, unsigned x, unsigned y, RGB color)
10 {
11 	if (x >= buf.width() || y >= buf.height())
12 		throw runtime_error("attempt to draw outside the buffer");
13 
14 	switch (buf.format()) {
15 	case PixelFormat::XRGB8888:
16 	case PixelFormat::ARGB8888:
17 	{
18 		uint32_t *p = (uint32_t*)(buf.map(0) + buf.stride(0) * y + x * 4);
19 		*p = color.argb8888();
20 		break;
21 	}
22 	case PixelFormat::XBGR8888:
23 	case PixelFormat::ABGR8888:
24 	{
25 		uint32_t *p = (uint32_t*)(buf.map(0) + buf.stride(0) * y + x * 4);
26 		*p = color.abgr8888();
27 		break;
28 	}
29 	case PixelFormat::RGB888:
30 	{
31 		uint8_t *p = buf.map(0) + buf.stride(0) * y + x * 3;
32 		p[0] = color.b;
33 		p[1] = color.g;
34 		p[2] = color.r;
35 		break;
36 	}
37 	case PixelFormat::BGR888:
38 	{
39 		uint8_t *p = buf.map(0) + buf.stride(0) * y + x * 3;
40 		p[0] = color.r;
41 		p[1] = color.g;
42 		p[2] = color.b;
43 		break;
44 	}
45 	case PixelFormat::RGB565:
46 	{
47 		uint16_t *p = (uint16_t*)(buf.map(0) + buf.stride(0) * y + x * 2);
48 		*p = color.rgb565();
49 		break;
50 	}
51 	case PixelFormat::BGR565:
52 	{
53 		uint16_t *p = (uint16_t*)(buf.map(0) + buf.stride(0) * y + x * 2);
54 		*p = color.bgr565();
55 		break;
56 	}
57 	default:
58 		throw std::invalid_argument("invalid pixelformat");
59 	}
60 }
61 
draw_yuv422_macropixel(IFramebuffer & buf,unsigned x,unsigned y,YUV yuv1,YUV yuv2)62 void draw_yuv422_macropixel(IFramebuffer& buf, unsigned x, unsigned y, YUV yuv1, YUV yuv2)
63 {
64 	if ((x + 1) >= buf.width() || y >= buf.height())
65 		throw runtime_error("attempt to draw outside the buffer");
66 
67 	ASSERT((x & 1) == 0);
68 
69 	uint8_t *p = (uint8_t*)(buf.map(0) + buf.stride(0) * y + x * 2);
70 
71 	uint8_t y0 = yuv1.y;
72 	uint8_t y1 = yuv2.y;
73 	uint8_t u = (yuv1.u + yuv2.u) / 2;
74 	uint8_t v = (yuv1.v + yuv2.v) / 2;
75 
76 	switch (buf.format()) {
77 	case PixelFormat::UYVY:
78 		p[0] = u;
79 		p[1] = y0;
80 		p[2] = v;
81 		p[3] = y1;
82 		break;
83 
84 	case PixelFormat::YUYV:
85 		p[0] = y0;
86 		p[1] = u;
87 		p[2] = y1;
88 		p[3] = v;
89 		break;
90 
91 	case PixelFormat::YVYU:
92 		p[0] = y0;
93 		p[1] = v;
94 		p[2] = y1;
95 		p[3] = u;
96 		break;
97 
98 	case PixelFormat::VYUY:
99 		p[0] = v;
100 		p[1] = y0;
101 		p[2] = u;
102 		p[3] = y1;
103 		break;
104 
105 	default:
106 		throw std::invalid_argument("invalid pixelformat");
107 	}
108 }
109 
draw_yuv420_macropixel(IFramebuffer & buf,unsigned x,unsigned y,YUV yuv1,YUV yuv2,YUV yuv3,YUV yuv4)110 void draw_yuv420_macropixel(IFramebuffer& buf, unsigned x, unsigned y,
111 			    YUV yuv1, YUV yuv2, YUV yuv3, YUV yuv4)
112 {
113 	if ((x + 1) >= buf.width() || (y + 1) >= buf.height())
114 		throw runtime_error("attempt to draw outside the buffer");
115 
116 	ASSERT((x & 1) == 0);
117 	ASSERT((y & 1) == 0);
118 
119 	uint8_t *py1 = (uint8_t*)(buf.map(0) + buf.stride(0) * (y + 0) + x);
120 	uint8_t *py2 = (uint8_t*)(buf.map(0) + buf.stride(0) * (y + 1) + x);
121 
122 	uint8_t *puv = (uint8_t*)(buf.map(1) + buf.stride(1) * (y / 2) + x);
123 
124 	uint8_t y0 = yuv1.y;
125 	uint8_t y1 = yuv2.y;
126 	uint8_t y2 = yuv3.y;
127 	uint8_t y3 = yuv4.y;
128 	uint8_t u = (yuv1.u + yuv2.u + yuv3.u + yuv4.u) / 4;
129 	uint8_t v = (yuv1.v + yuv2.v + yuv3.v + yuv4.v) / 4;
130 
131 	switch (buf.format()) {
132 	case PixelFormat::NV12:
133 		py1[0] = y0;
134 		py1[1] = y1;
135 		py2[0] = y2;
136 		py2[1] = y3;
137 		puv[0] = u;
138 		puv[1] = v;
139 		break;
140 
141 	case PixelFormat::NV21:
142 		py1[0] = y0;
143 		py1[1] = y1;
144 		py2[0] = y2;
145 		py2[1] = y3;
146 		puv[0] = v;
147 		puv[1] = u;
148 		break;
149 
150 	default:
151 		throw std::invalid_argument("invalid pixelformat");
152 	}
153 }
154 
draw_rect(IFramebuffer & fb,uint32_t x,uint32_t y,uint32_t w,uint32_t h,RGB color)155 void draw_rect(IFramebuffer &fb, uint32_t x, uint32_t y, uint32_t w, uint32_t h, RGB color)
156 {
157 	unsigned i, j;
158 	YUV yuvcolor = color.yuv();
159 
160 	switch (fb.format()) {
161 	case PixelFormat::XRGB8888:
162 	case PixelFormat::XBGR8888:
163 	case PixelFormat::ARGB8888:
164 	case PixelFormat::ABGR8888:
165 	case PixelFormat::RGB888:
166 	case PixelFormat::BGR888:
167 	case PixelFormat::RGB565:
168 	case PixelFormat::BGR565:
169 		for (j = 0; j < h; j++) {
170 			for (i = 0; i < w; i++) {
171 				draw_rgb_pixel(fb, x + i, y + j, color);
172 			}
173 		}
174 		break;
175 
176 	case PixelFormat::UYVY:
177 	case PixelFormat::YUYV:
178 	case PixelFormat::YVYU:
179 	case PixelFormat::VYUY:
180 		for (j = 0; j < h; j++) {
181 			for (i = 0; i < w; i += 2) {
182 				draw_yuv422_macropixel(fb, x + i, y + j, yuvcolor, yuvcolor);
183 			}
184 		}
185 		break;
186 
187 	case PixelFormat::NV12:
188 	case PixelFormat::NV21:
189 		for (j = 0; j < h; j += 2) {
190 			for (i = 0; i < w; i += 2) {
191 				draw_yuv420_macropixel(fb, x + i, y + j,
192 						       yuvcolor, yuvcolor, yuvcolor, yuvcolor);
193 			}
194 		}
195 		break;
196 	default:
197 		throw std::invalid_argument("unknown pixelformat");
198 	}
199 }
200 
get_char_pixel(char c,uint32_t x,uint32_t y)201 static bool get_char_pixel(char c, uint32_t x, uint32_t y)
202 {
203 #include "font_8x8.h"
204 
205 	uint8_t bits = fontdata_8x8[8 * c + y];
206 	bool bit = (bits >> (7 - x)) & 1;
207 
208 	return bit;
209 }
210 
draw_char(IFramebuffer & buf,uint32_t xpos,uint32_t ypos,char c,RGB color)211 static void draw_char(IFramebuffer& buf, uint32_t xpos, uint32_t ypos, char c, RGB color)
212 {
213 	unsigned x, y;
214 	YUV yuvcolor = color.yuv();
215 
216 	switch (buf.format()) {
217 	case PixelFormat::XRGB8888:
218 	case PixelFormat::XBGR8888:
219 	case PixelFormat::ARGB8888:
220 	case PixelFormat::ABGR8888:
221 	case PixelFormat::RGB888:
222 	case PixelFormat::BGR888:
223 	case PixelFormat::RGB565:
224 	case PixelFormat::BGR565:
225 		for (y = 0; y < 8; y++) {
226 			for (x = 0; x < 8; x++) {
227 				bool b = get_char_pixel(c, x, y);
228 
229 				draw_rgb_pixel(buf, xpos + x, ypos + y, b ? color : RGB());
230 			}
231 		}
232 		break;
233 
234 	case PixelFormat::UYVY:
235 	case PixelFormat::YUYV:
236 	case PixelFormat::YVYU:
237 	case PixelFormat::VYUY:
238 		for (y = 0; y < 8; y++) {
239 			for (x = 0; x < 8; x += 2) {
240 				bool b0 = get_char_pixel(c, x, y);
241 				bool b1 = get_char_pixel(c, x + 1, y);
242 
243 				draw_yuv422_macropixel(buf, xpos + x, ypos + y,
244 						       b0 ? yuvcolor : YUV(RGB()), b1 ? yuvcolor : YUV(RGB()));
245 			}
246 		}
247 		break;
248 
249 	case PixelFormat::NV12:
250 	case PixelFormat::NV21:
251 		for (y = 0; y < 8; y += 2) {
252 			for (x = 0; x < 8; x += 2) {
253 				bool b00 = get_char_pixel(c, x, y);
254 				bool b10 = get_char_pixel(c, x + 1, y);
255 				bool b01 = get_char_pixel(c, x, y + 1);
256 				bool b11 = get_char_pixel(c, x + 1, y + 1);
257 
258 				draw_yuv420_macropixel(buf, xpos + x, ypos + y,
259 						       b00 ? yuvcolor : YUV(RGB()), b10 ? yuvcolor : YUV(RGB()),
260 						       b01 ? yuvcolor : YUV(RGB()), b11 ? yuvcolor : YUV(RGB()));
261 			}
262 		}
263 		break;
264 	default:
265 		throw std::invalid_argument("unknown pixelformat");
266 	}
267 }
268 
draw_text(IFramebuffer & buf,uint32_t x,uint32_t y,const string & str,RGB color)269 void draw_text(IFramebuffer& buf, uint32_t x, uint32_t y, const string& str, RGB color)
270 {
271 	for(unsigned i = 0; i < str.size(); i++)
272 		draw_char(buf, (x + 8 * i), y, str[i], color);
273 }
274 
275 }
276