summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRafaël Carré <rafael.carre@gmail.com>2011-12-03 21:39:33 +0000
committerRafaël Carré <rafael.carre@gmail.com>2011-12-03 21:39:33 +0000
commitd7802133fd9d5bf2fddfcc26cf10cd17285b4efd (patch)
treee4e6de0a8babb5bb6543a5ccef7d6b88997767af
parent1d81683e0896e8b82d133fb0e577b6c79263ff39 (diff)
downloadrockbox-d7802133fd9d5bf2fddfcc26cf10cd17285b4efd.tar.gz
rockbox-d7802133fd9d5bf2fddfcc26cf10cd17285b4efd.zip
lcd_blit_yuv: move from sdl driver to lcd16bit-common
Declare as weak, so it can be overridden by targets git-svn-id: svn://svn.rockbox.org/rockbox/trunk@31127 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/drivers/lcd-16bit.c205
-rw-r--r--firmware/target/hosted/sdl/lcd-bitmap.c205
2 files changed, 204 insertions, 206 deletions
diff --git a/firmware/drivers/lcd-16bit.c b/firmware/drivers/lcd-16bit.c
index 28c3285a9c..300dbba9ac 100644
--- a/firmware/drivers/lcd-16bit.c
+++ b/firmware/drivers/lcd-16bit.c
@@ -913,10 +913,213 @@ void lcd_bitmap_transparent(const fb_data *src, int x, int y,
913 lcd_bitmap_transparent_part(src, 0, 0, width, x, y, width, height); 913 lcd_bitmap_transparent_part(src, 0, 0, width, x, y, width, height);
914} 914}
915 915
916/**
917 * |R| |1.000000 -0.000001 1.402000| |Y'|
918 * |G| = |1.000000 -0.334136 -0.714136| |Pb|
919 * |B| |1.000000 1.772000 0.000000| |Pr|
920 * Scaled, normalized, rounded and tweaked to yield RGB 565:
921 * |R| |74 0 101| |Y' - 16| >> 9
922 * |G| = |74 -24 -51| |Cb - 128| >> 8
923 * |B| |74 128 0| |Cr - 128| >> 9
924 */
925#define YFAC (74)
926#define RVFAC (101)
927#define GUFAC (-24)
928#define GVFAC (-51)
929#define BUFAC (128)
930
931static inline int clamp(int val, int min, int max)
932{
933 if (val < min)
934 val = min;
935 else if (val > max)
936 val = max;
937 return val;
938}
939
940__attribute__((weak)) void lcd_yuv_set_options(unsigned options)
941{
942 (void)options;
943}
944
945/* Draw a partial YUV colour bitmap - similiar behavior to lcd_blit_yuv
946 in the core */
947
948__attribute__((weak)) void lcd_blit_yuv(unsigned char * const src[3],
949 int src_x, int src_y, int stride,
950 int x, int y, int width, int height)
951{
952 const unsigned char *ysrc, *usrc, *vsrc;
953 int linecounter;
954 fb_data *dst, *row_end;
955 long z;
956
957 /* width and height must be >= 2 and an even number */
958 width &= ~1;
959 linecounter = height >> 1;
960
961#if LCD_WIDTH >= LCD_HEIGHT
962 dst = &lcd_framebuffer[y][x];
963 row_end = dst + width;
964#else
965 dst = &lcd_framebuffer[x][LCD_WIDTH - y - 1];
966 row_end = dst + LCD_WIDTH * width;
967#endif
968
969 z = stride * src_y;
970 ysrc = src[0] + z + src_x;
971 usrc = src[1] + (z >> 2) + (src_x >> 1);
972 vsrc = src[2] + (usrc - src[1]);
973
974 /* stride => amount to jump from end of last row to start of next */
975 stride -= width;
976
977 /* upsampling, YUV->RGB conversion and reduction to RGB565 in one go */
978
979 do
980 {
981 do
982 {
983 int y, cb, cr, rv, guv, bu, r, g, b;
984
985 y = YFAC*(*ysrc++ - 16);
986 cb = *usrc++ - 128;
987 cr = *vsrc++ - 128;
988
989 rv = RVFAC*cr;
990 guv = GUFAC*cb + GVFAC*cr;
991 bu = BUFAC*cb;
992
993 r = y + rv;
994 g = y + guv;
995 b = y + bu;
996
997 if ((unsigned)(r | g | b) > 64*256-1)
998 {
999 r = clamp(r, 0, 64*256-1);
1000 g = clamp(g, 0, 64*256-1);
1001 b = clamp(b, 0, 64*256-1);
1002 }
1003
1004 *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9);
1005
1006#if LCD_WIDTH >= LCD_HEIGHT
1007 dst++;
1008#else
1009 dst += LCD_WIDTH;
1010#endif
1011
1012 y = YFAC*(*ysrc++ - 16);
1013 r = y + rv;
1014 g = y + guv;
1015 b = y + bu;
1016
1017 if ((unsigned)(r | g | b) > 64*256-1)
1018 {
1019 r = clamp(r, 0, 64*256-1);
1020 g = clamp(g, 0, 64*256-1);
1021 b = clamp(b, 0, 64*256-1);
1022 }
1023
1024 *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9);
1025
1026#if LCD_WIDTH >= LCD_HEIGHT
1027 dst++;
1028#else
1029 dst += LCD_WIDTH;
1030#endif
1031 }
1032 while (dst < row_end);
1033
1034 ysrc += stride;
1035 usrc -= width >> 1;
1036 vsrc -= width >> 1;
1037
1038#if LCD_WIDTH >= LCD_HEIGHT
1039 row_end += LCD_WIDTH;
1040 dst += LCD_WIDTH - width;
1041#else
1042 row_end -= 1;
1043 dst -= LCD_WIDTH*width + 1;
1044#endif
1045
1046 do
1047 {
1048 int y, cb, cr, rv, guv, bu, r, g, b;
1049
1050 y = YFAC*(*ysrc++ - 16);
1051 cb = *usrc++ - 128;
1052 cr = *vsrc++ - 128;
1053
1054 rv = RVFAC*cr;
1055 guv = GUFAC*cb + GVFAC*cr;
1056 bu = BUFAC*cb;
1057
1058 r = y + rv;
1059 g = y + guv;
1060 b = y + bu;
1061
1062 if ((unsigned)(r | g | b) > 64*256-1)
1063 {
1064 r = clamp(r, 0, 64*256-1);
1065 g = clamp(g, 0, 64*256-1);
1066 b = clamp(b, 0, 64*256-1);
1067 }
1068
1069 *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9);
1070
1071#if LCD_WIDTH >= LCD_HEIGHT
1072 dst++;
1073#else
1074 dst += LCD_WIDTH;
1075#endif
1076
1077 y = YFAC*(*ysrc++ - 16);
1078 r = y + rv;
1079 g = y + guv;
1080 b = y + bu;
1081
1082 if ((unsigned)(r | g | b) > 64*256-1)
1083 {
1084 r = clamp(r, 0, 64*256-1);
1085 g = clamp(g, 0, 64*256-1);
1086 b = clamp(b, 0, 64*256-1);
1087 }
1088
1089 *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9);
1090
1091#if LCD_WIDTH >= LCD_HEIGHT
1092 dst++;
1093#else
1094 dst += LCD_WIDTH;
1095#endif
1096 }
1097 while (dst < row_end);
1098
1099 ysrc += stride;
1100 usrc += stride >> 1;
1101 vsrc += stride >> 1;
1102
1103#if LCD_WIDTH >= LCD_HEIGHT
1104 row_end += LCD_WIDTH;
1105 dst += LCD_WIDTH - width;
1106#else
1107 row_end -= 1;
1108 dst -= LCD_WIDTH*width + 1;
1109#endif
1110 }
1111 while (--linecounter > 0);
1112
1113#if LCD_WIDTH >= LCD_HEIGHT
1114 lcd_update_rect(x, y, width, height);
1115#else
1116 lcd_update_rect(LCD_WIDTH - y - height, x, height, width);
1117#endif
1118}
1119
916#define ROW_INC LCD_WIDTH 1120#define ROW_INC LCD_WIDTH
917#define COL_INC 1 1121#define COL_INC 1
918 1122
919#include "lcd-16bit-common.c" 1123#include "lcd-16bit-common.c"
920 1124
921#include "lcd-bitmap-common.c" 1125#include "lcd-bitmap-common.c"
922
diff --git a/firmware/target/hosted/sdl/lcd-bitmap.c b/firmware/target/hosted/sdl/lcd-bitmap.c
index 4c296924af..4ee0bbef5c 100644
--- a/firmware/target/hosted/sdl/lcd-bitmap.c
+++ b/firmware/target/hosted/sdl/lcd-bitmap.c
@@ -223,208 +223,3 @@ void sim_lcd_ex_update_rect(int x_start, int y_start, int width, int height)
223 } 223 }
224} 224}
225#endif 225#endif
226
227#ifdef HAVE_LCD_COLOR
228/**
229 * |R| |1.000000 -0.000001 1.402000| |Y'|
230 * |G| = |1.000000 -0.334136 -0.714136| |Pb|
231 * |B| |1.000000 1.772000 0.000000| |Pr|
232 * Scaled, normalized, rounded and tweaked to yield RGB 565:
233 * |R| |74 0 101| |Y' - 16| >> 9
234 * |G| = |74 -24 -51| |Cb - 128| >> 8
235 * |B| |74 128 0| |Cr - 128| >> 9
236 */
237#define YFAC (74)
238#define RVFAC (101)
239#define GUFAC (-24)
240#define GVFAC (-51)
241#define BUFAC (128)
242
243static inline int clamp(int val, int min, int max)
244{
245 if (val < min)
246 val = min;
247 else if (val > max)
248 val = max;
249 return val;
250}
251
252void lcd_yuv_set_options(unsigned options)
253{
254 (void)options;
255}
256
257/* Draw a partial YUV colour bitmap - similiar behavior to lcd_blit_yuv
258 in the core */
259void lcd_blit_yuv(unsigned char * const src[3],
260 int src_x, int src_y, int stride,
261 int x, int y, int width, int height)
262{
263 const unsigned char *ysrc, *usrc, *vsrc;
264 int linecounter;
265 fb_data *dst, *row_end;
266 long z;
267
268 /* width and height must be >= 2 and an even number */
269 width &= ~1;
270 linecounter = height >> 1;
271
272#if LCD_WIDTH >= LCD_HEIGHT
273 dst = &lcd_framebuffer[y][x];
274 row_end = dst + width;
275#else
276 dst = &lcd_framebuffer[x][LCD_WIDTH - y - 1];
277 row_end = dst + LCD_WIDTH * width;
278#endif
279
280 z = stride * src_y;
281 ysrc = src[0] + z + src_x;
282 usrc = src[1] + (z >> 2) + (src_x >> 1);
283 vsrc = src[2] + (usrc - src[1]);
284
285 /* stride => amount to jump from end of last row to start of next */
286 stride -= width;
287
288 /* upsampling, YUV->RGB conversion and reduction to RGB565 in one go */
289
290 do
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 -= width >> 1;
347 vsrc -= width >> 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 do
358 {
359 int y, cb, cr, rv, guv, bu, r, g, b;
360
361 y = YFAC*(*ysrc++ - 16);
362 cb = *usrc++ - 128;
363 cr = *vsrc++ - 128;
364
365 rv = RVFAC*cr;
366 guv = GUFAC*cb + GVFAC*cr;
367 bu = BUFAC*cb;
368
369 r = y + rv;
370 g = y + guv;
371 b = y + bu;
372
373 if ((unsigned)(r | g | b) > 64*256-1)
374 {
375 r = clamp(r, 0, 64*256-1);
376 g = clamp(g, 0, 64*256-1);
377 b = clamp(b, 0, 64*256-1);
378 }
379
380 *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9);
381
382#if LCD_WIDTH >= LCD_HEIGHT
383 dst++;
384#else
385 dst += LCD_WIDTH;
386#endif
387
388 y = YFAC*(*ysrc++ - 16);
389 r = y + rv;
390 g = y + guv;
391 b = y + bu;
392
393 if ((unsigned)(r | g | b) > 64*256-1)
394 {
395 r = clamp(r, 0, 64*256-1);
396 g = clamp(g, 0, 64*256-1);
397 b = clamp(b, 0, 64*256-1);
398 }
399
400 *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9);
401
402#if LCD_WIDTH >= LCD_HEIGHT
403 dst++;
404#else
405 dst += LCD_WIDTH;
406#endif
407 }
408 while (dst < row_end);
409
410 ysrc += stride;
411 usrc += stride >> 1;
412 vsrc += stride >> 1;
413
414#if LCD_WIDTH >= LCD_HEIGHT
415 row_end += LCD_WIDTH;
416 dst += LCD_WIDTH - width;
417#else
418 row_end -= 1;
419 dst -= LCD_WIDTH*width + 1;
420#endif
421 }
422 while (--linecounter > 0);
423
424#if LCD_WIDTH >= LCD_HEIGHT
425 lcd_update_rect(x, y, width, height);
426#else
427 lcd_update_rect(LCD_WIDTH - y - height, x, height, width);
428#endif
429}
430#endif /* HAVE_LCD_COLOR */