diff options
Diffstat (limited to 'uisimulator/sdl/lcd-bitmap.c')
-rw-r--r-- | uisimulator/sdl/lcd-bitmap.c | 204 |
1 files changed, 204 insertions, 0 deletions
diff --git a/uisimulator/sdl/lcd-bitmap.c b/uisimulator/sdl/lcd-bitmap.c index da6acce1bc..12cc063288 100644 --- a/uisimulator/sdl/lcd-bitmap.c +++ b/uisimulator/sdl/lcd-bitmap.c | |||
@@ -159,3 +159,207 @@ void sim_lcd_ex_update_rect(int x_start, int y_start, int width, int height) | |||
159 | } | 159 | } |
160 | #endif | 160 | #endif |
161 | 161 | ||
162 | #ifdef HAVE_LCD_COLOR | ||
163 | /** | ||
164 | * |R| |1.000000 -0.000001 1.402000| |Y'| | ||
165 | * |G| = |1.000000 -0.334136 -0.714136| |Pb| | ||
166 | * |B| |1.000000 1.772000 0.000000| |Pr| | ||
167 | * Scaled, normalized, rounded and tweaked to yield RGB 565: | ||
168 | * |R| |74 0 101| |Y' - 16| >> 9 | ||
169 | * |G| = |74 -24 -51| |Cb - 128| >> 8 | ||
170 | * |B| |74 128 0| |Cr - 128| >> 9 | ||
171 | */ | ||
172 | #define YFAC (74) | ||
173 | #define RVFAC (101) | ||
174 | #define GUFAC (-24) | ||
175 | #define GVFAC (-51) | ||
176 | #define BUFAC (128) | ||
177 | |||
178 | static inline int clamp(int val, int min, int max) | ||
179 | { | ||
180 | if (val < min) | ||
181 | val = min; | ||
182 | else if (val > max) | ||
183 | val = max; | ||
184 | return val; | ||
185 | } | ||
186 | |||
187 | void lcd_yuv_set_options(unsigned options) | ||
188 | { | ||
189 | (void)options; | ||
190 | } | ||
191 | |||
192 | /* Draw a partial YUV colour bitmap - similiar behavior to lcd_yuv_blit | ||
193 | in the core */ | ||
194 | void lcd_yuv_blit(unsigned char * const src[3], | ||
195 | int src_x, int src_y, int stride, | ||
196 | int x, int y, int width, int height) | ||
197 | { | ||
198 | const unsigned char *ysrc, *usrc, *vsrc; | ||
199 | int linecounter; | ||
200 | fb_data *dst, *row_end; | ||
201 | long z; | ||
202 | |||
203 | /* width and height must be >= 2 and an even number */ | ||
204 | width &= ~1; | ||
205 | linecounter = height >> 1; | ||
206 | |||
207 | #if LCD_WIDTH >= LCD_HEIGHT | ||
208 | dst = &lcd_framebuffer[y][x]; | ||
209 | row_end = dst + width; | ||
210 | #else | ||
211 | dst = &lcd_framebuffer[x][LCD_WIDTH - y - 1]; | ||
212 | row_end = dst + LCD_WIDTH * width; | ||
213 | #endif | ||
214 | |||
215 | z = stride * src_y; | ||
216 | ysrc = src[0] + z + src_x; | ||
217 | usrc = src[1] + (z >> 2) + (src_x >> 1); | ||
218 | vsrc = src[2] + (usrc - src[1]); | ||
219 | |||
220 | /* stride => amount to jump from end of last row to start of next */ | ||
221 | stride -= width; | ||
222 | |||
223 | /* upsampling, YUV->RGB conversion and reduction to RGB565 in one go */ | ||
224 | |||
225 | do | ||
226 | { | ||
227 | do | ||
228 | { | ||
229 | int y, cb, cr, rv, guv, bu, r, g, b; | ||
230 | |||
231 | y = YFAC*(*ysrc++ - 16); | ||
232 | cb = *usrc++ - 128; | ||
233 | cr = *vsrc++ - 128; | ||
234 | |||
235 | rv = RVFAC*cr; | ||
236 | guv = GUFAC*cb + GVFAC*cr; | ||
237 | bu = BUFAC*cb; | ||
238 | |||
239 | r = y + rv; | ||
240 | g = y + guv; | ||
241 | b = y + bu; | ||
242 | |||
243 | if ((unsigned)(r | g | b) > 64*256-1) | ||
244 | { | ||
245 | r = clamp(r, 0, 64*256-1); | ||
246 | g = clamp(g, 0, 64*256-1); | ||
247 | b = clamp(b, 0, 64*256-1); | ||
248 | } | ||
249 | |||
250 | *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9); | ||
251 | |||
252 | #if LCD_WIDTH >= LCD_HEIGHT | ||
253 | dst++; | ||
254 | #else | ||
255 | dst += LCD_WIDTH; | ||
256 | #endif | ||
257 | |||
258 | y = YFAC*(*ysrc++ - 16); | ||
259 | r = y + rv; | ||
260 | g = y + guv; | ||
261 | b = y + bu; | ||
262 | |||
263 | if ((unsigned)(r | g | b) > 64*256-1) | ||
264 | { | ||
265 | r = clamp(r, 0, 64*256-1); | ||
266 | g = clamp(g, 0, 64*256-1); | ||
267 | b = clamp(b, 0, 64*256-1); | ||
268 | } | ||
269 | |||
270 | *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9); | ||
271 | |||
272 | #if LCD_WIDTH >= LCD_HEIGHT | ||
273 | dst++; | ||
274 | #else | ||
275 | dst += LCD_WIDTH; | ||
276 | #endif | ||
277 | } | ||
278 | while (dst < row_end); | ||
279 | |||
280 | ysrc += stride; | ||
281 | usrc -= width >> 1; | ||
282 | vsrc -= width >> 1; | ||
283 | |||
284 | #if LCD_WIDTH >= LCD_HEIGHT | ||
285 | row_end += LCD_WIDTH; | ||
286 | dst += LCD_WIDTH - width; | ||
287 | #else | ||
288 | row_end -= 1; | ||
289 | dst -= LCD_WIDTH*width + 1; | ||
290 | #endif | ||
291 | |||
292 | do | ||
293 | { | ||
294 | int y, cb, cr, rv, guv, bu, r, g, b; | ||
295 | |||
296 | y = YFAC*(*ysrc++ - 16); | ||
297 | cb = *usrc++ - 128; | ||
298 | cr = *vsrc++ - 128; | ||
299 | |||
300 | rv = RVFAC*cr; | ||
301 | guv = GUFAC*cb + GVFAC*cr; | ||
302 | bu = BUFAC*cb; | ||
303 | |||
304 | r = y + rv; | ||
305 | g = y + guv; | ||
306 | b = y + bu; | ||
307 | |||
308 | if ((unsigned)(r | g | b) > 64*256-1) | ||
309 | { | ||
310 | r = clamp(r, 0, 64*256-1); | ||
311 | g = clamp(g, 0, 64*256-1); | ||
312 | b = clamp(b, 0, 64*256-1); | ||
313 | } | ||
314 | |||
315 | *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9); | ||
316 | |||
317 | #if LCD_WIDTH >= LCD_HEIGHT | ||
318 | dst++; | ||
319 | #else | ||
320 | dst += LCD_WIDTH; | ||
321 | #endif | ||
322 | |||
323 | y = YFAC*(*ysrc++ - 16); | ||
324 | r = y + rv; | ||
325 | g = y + guv; | ||
326 | b = y + bu; | ||
327 | |||
328 | if ((unsigned)(r | g | b) > 64*256-1) | ||
329 | { | ||
330 | r = clamp(r, 0, 64*256-1); | ||
331 | g = clamp(g, 0, 64*256-1); | ||
332 | b = clamp(b, 0, 64*256-1); | ||
333 | } | ||
334 | |||
335 | *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9); | ||
336 | |||
337 | #if LCD_WIDTH >= LCD_HEIGHT | ||
338 | dst++; | ||
339 | #else | ||
340 | dst += LCD_WIDTH; | ||
341 | #endif | ||
342 | } | ||
343 | while (dst < row_end); | ||
344 | |||
345 | ysrc += stride; | ||
346 | usrc += stride >> 1; | ||
347 | vsrc += stride >> 1; | ||
348 | |||
349 | #if LCD_WIDTH >= LCD_HEIGHT | ||
350 | row_end += LCD_WIDTH; | ||
351 | dst += LCD_WIDTH - width; | ||
352 | #else | ||
353 | row_end -= 1; | ||
354 | dst -= LCD_WIDTH*width + 1; | ||
355 | #endif | ||
356 | } | ||
357 | while (--linecounter > 0); | ||
358 | |||
359 | #if LCD_WIDTH >= LCD_HEIGHT | ||
360 | lcd_update_rect(x, y, width, height); | ||
361 | #else | ||
362 | lcd_update_rect(y, x, height, width); | ||
363 | #endif | ||
364 | } | ||
365 | #endif /* HAVE_LCD_COLOR */ | ||