From a8905e8ae83edc438214af553671efec7b787191 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 2 May 2013 22:30:20 +0200 Subject: [PATCH] Several fixes to ieee1275 and big-endian video. --- ChangeLog | 4 + grub-core/tests/checksums.c | 3 + grub-core/tests/video_checksum.c | 82 +++++++- grub-core/tests/videotest_checksum.c | 38 +++- grub-core/video/bochs.c | 1 + grub-core/video/cirrus.c | 6 +- grub-core/video/efi_uga.c | 2 +- grub-core/video/emu/sdl.c | 12 +- grub-core/video/fb/fbblit.c | 78 +++++++- grub-core/video/fb/fbfill.c | 20 +- grub-core/video/fb/fbutil.c | 8 + grub-core/video/fb/video_fb.c | 280 ++++++++++++++++++++++++--- grub-core/video/i386/pc/vbe.c | 5 +- grub-core/video/ieee1275.c | 106 ++++++++-- grub-core/video/readers/jpeg.c | 13 ++ grub-core/video/readers/png.c | 61 +++++- grub-core/video/sis315pro.c | 4 +- include/grub/video_fb.h | 4 +- 18 files changed, 655 insertions(+), 72 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8525dd9be..3ff4a050a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2013-05-02 Vladimir Serbinenko + + Several fixes to ieee1275 and big-endian video. + 2013-05-02 Vladimir Serbinenko Add missing exports on mips. diff --git a/grub-core/tests/checksums.c b/grub-core/tests/checksums.c index 93d100fee..583c696d6 100644 --- a/grub-core/tests/checksums.c +++ b/grub-core/tests/checksums.c @@ -1,6 +1,9 @@ { "videotest", 640, 480, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 640x480xi16 */, (grub_uint32_t []) { 0x7f1853ba, 0x7f1853ba, 0x7f1853ba, 0x7f1853ba, 0x7f1853ba, }, 5 }, { "videotest", 800, 600, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 800x600xi16 */, (grub_uint32_t []) { 0xff1957f0, 0xff1957f0, 0xff1957f0, 0xff1957f0, 0xff1957f0, }, 5 }, { "videotest", 1024, 768, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 1024x768xi16 */, (grub_uint32_t []) { 0xcb45d8c5, 0xcb45d8c5, 0xcb45d8c5, 0xcb45d8c5, 0xcb45d8c5, }, 5 }, + { "videotest", 640, 480, 0x2, 256, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 640x480xi256 */, (grub_uint32_t []) { 0x2d1b122b, 0x2d1b122b, 0x2d1b122b, 0x2d1b122b, 0x2d1b122b, }, 5 }, + { "videotest", 800, 600, 0x2, 256, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 800x600xi256 */, (grub_uint32_t []) { 0x327d1082, 0x327d1082, 0x327d1082, 0x327d1082, 0x327d1082, }, 5 }, + { "videotest", 1024, 768, 0x2, 256, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 1024x768xi256 */, (grub_uint32_t []) { 0xadd0f186, 0xadd0f186, 0xadd0f186, 0xadd0f186, 0xadd0f186, }, 5 }, { "videotest", 640, 480, 0x1, 256, 15, 2, 10, 5, 5, 5, 0, 5, 0, 0 /* 640x480xrgb555 */, (grub_uint32_t []) { 0x2c97569c, 0x2c97569c, 0x2c97569c, 0x2c97569c, 0x2c97569c, }, 5 }, { "videotest", 800, 600, 0x1, 256, 15, 2, 10, 5, 5, 5, 0, 5, 0, 0 /* 800x600xrgb555 */, (grub_uint32_t []) { 0x9bd7a3ac, 0x9bd7a3ac, 0x9bd7a3ac, 0x9bd7a3ac, 0x9bd7a3ac, }, 5 }, { "videotest", 1024, 768, 0x1, 256, 15, 2, 10, 5, 5, 5, 0, 5, 0, 0 /* 1024x768xrgb555 */, (grub_uint32_t []) { 0xedbceb9c, 0xedbceb9c, 0xedbceb9c, 0xedbceb9c, 0xedbceb9c, }, 5 }, diff --git a/grub-core/tests/video_checksum.c b/grub-core/tests/video_checksum.c index b2aab7929..cf47fa245 100644 --- a/grub-core/tests/video_checksum.c +++ b/grub-core/tests/video_checksum.c @@ -249,14 +249,16 @@ get_modename (void) } if (capt_mode_info.red_field_pos == 0) { - grub_snprintf (buf, sizeof (buf), "bgr%d%d%d", capt_mode_info.blue_mask_size, + grub_snprintf (buf, sizeof (buf), "bgra%d%d%d%d", capt_mode_info.blue_mask_size, capt_mode_info.green_mask_size, - capt_mode_info.red_mask_size); + capt_mode_info.red_mask_size, + capt_mode_info.reserved_mask_size); return buf; } - grub_snprintf (buf, sizeof (buf), "rgb%d%d%d", capt_mode_info.red_mask_size, + grub_snprintf (buf, sizeof (buf), "rgba%d%d%d%d", capt_mode_info.red_mask_size, capt_mode_info.green_mask_size, - capt_mode_info.blue_mask_size); + capt_mode_info.blue_mask_size, + capt_mode_info.reserved_mask_size); return buf; } @@ -270,11 +272,81 @@ static void checksum (void) { void *ptr; - grub_uint32_t crc; + grub_uint32_t crc = 0; ptr = grub_video_capture_get_framebuffer (); +#ifdef GRUB_CPU_WORDS_BIGENDIAN + switch (capt_mode_info.bytes_per_pixel) + { + case 1: + crc = grub_getcrc32c (0, ptr, capt_mode_info.pitch + * capt_mode_info.height); + break; + case 2: + { + unsigned x, y, rowskip; + grub_uint8_t *iptr = ptr; + crc = 0; + rowskip = capt_mode_info.pitch - capt_mode_info.width * 2; + for (y = 0; y < capt_mode_info.height; y++) + { + for (x = 0; x < capt_mode_info.width; x++) + { + crc = grub_getcrc32c (crc, iptr + 1, 1); + crc = grub_getcrc32c (crc, iptr, 1); + iptr += 2; + } + crc = grub_getcrc32c (crc, iptr, rowskip); + iptr += rowskip; + } + break; + } + case 3: + { + unsigned x, y, rowskip; + grub_uint8_t *iptr = ptr; + crc = 0; + rowskip = capt_mode_info.pitch - capt_mode_info.width * 3; + for (y = 0; y < capt_mode_info.height; y++) + { + for (x = 0; x < capt_mode_info.width; x++) + { + crc = grub_getcrc32c (crc, iptr + 2, 1); + crc = grub_getcrc32c (crc, iptr + 1, 1); + crc = grub_getcrc32c (crc, iptr, 1); + iptr += 3; + } + crc = grub_getcrc32c (crc, iptr, rowskip); + iptr += rowskip; + } + break; + } + case 4: + { + unsigned x, y, rowskip; + grub_uint8_t *iptr = ptr; + crc = 0; + rowskip = capt_mode_info.pitch - capt_mode_info.width * 4; + for (y = 0; y < capt_mode_info.height; y++) + { + for (x = 0; x < capt_mode_info.width; x++) + { + crc = grub_getcrc32c (crc, iptr + 3, 1); + crc = grub_getcrc32c (crc, iptr + 2, 1); + crc = grub_getcrc32c (crc, iptr + 1, 1); + crc = grub_getcrc32c (crc, iptr, 1); + iptr += 4; + } + crc = grub_getcrc32c (crc, iptr, rowskip); + iptr += rowskip; + } + break; + } + } +#else crc = grub_getcrc32c (0, ptr, capt_mode_info.pitch * capt_mode_info.height); +#endif if (!checksums || ctr >= nchk) { grub_test_assert (0, "Unexpected checksum %s_%dx%dx%s:%d: 0x%x", diff --git a/grub-core/tests/videotest_checksum.c b/grub-core/tests/videotest_checksum.c index 3c70f8c47..7833d04f4 100644 --- a/grub-core/tests/videotest_checksum.c +++ b/grub-core/tests/videotest_checksum.c @@ -63,6 +63,42 @@ struct .number_of_colors = GRUB_VIDEO_FBSTD_NUMCOLORS }, }, + + + { + .mode_info = { + .width = 640, + .height = 480, + .pitch = 640, + .mode_type = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR, + .bpp = 8, + .bytes_per_pixel = 1, + .number_of_colors = GRUB_VIDEO_FBSTD_EXT_NUMCOLORS + }, + }, + { + .mode_info = { + .width = 800, + .height = 600, + .pitch = 800, + .mode_type = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR, + .bpp = 8, + .bytes_per_pixel = 1, + .number_of_colors = GRUB_VIDEO_FBSTD_EXT_NUMCOLORS + }, + }, + { + .mode_info = { + .width = 1024, + .height = 768, + .pitch = 1024, + .mode_type = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR, + .bpp = 8, + .bytes_per_pixel = 1, + .number_of_colors = GRUB_VIDEO_FBSTD_EXT_NUMCOLORS + }, + }, + { .mode_info = { .width = 640, @@ -275,7 +311,7 @@ videotest_checksum (void) { grub_video_capture_start (&tests[i].mode_info, grub_video_fbstd_colors, - GRUB_VIDEO_FBSTD_NUMCOLORS); + tests[i].mode_info.number_of_colors); grub_terminal_input_fake_sequence ((int []) { '\n' }, 1); grub_video_checksum ("videotest"); diff --git a/grub-core/video/bochs.c b/grub-core/video/bochs.c index aea486c22..287ae0ff3 100644 --- a/grub-core/video/bochs.c +++ b/grub-core/video/bochs.c @@ -331,6 +331,7 @@ grub_video_bochs_setup (unsigned int width, unsigned int height, case 4: case 8: framebuffer.mode_info.mode_type = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR; + framebuffer.mode_info.number_of_colors = 16; break; case 16: framebuffer.mode_info.red_mask_size = 5; diff --git a/grub-core/video/cirrus.c b/grub-core/video/cirrus.c index 073c54e41..00e6516ac 100644 --- a/grub-core/video/cirrus.c +++ b/grub-core/video/cirrus.c @@ -295,15 +295,14 @@ grub_video_cirrus_setup (unsigned int width, unsigned int height, && !grub_video_check_mode_flag (mode_type, mode_mask, GRUB_VIDEO_MODE_TYPE_INDEX_COLOR, 0)) depth = 24; - - if (depth == 0) + else if (depth == 0) depth = 8; if (depth != 32 && depth != 24 && depth != 16 && depth != 15 && depth != 8) return grub_error (GRUB_ERR_IO, "only 32, 24, 16, 15 and 8-bit bpp are" " supported by cirrus video"); - bytes_per_pixel = (depth + 7) / 8; + bytes_per_pixel = (depth + GRUB_CHAR_BIT - 1) / GRUB_CHAR_BIT; pitch = width * bytes_per_pixel; if (pitch > CIRRUS_MAX_PITCH) @@ -411,6 +410,7 @@ grub_video_cirrus_setup (unsigned int width, unsigned int height, { case 8: framebuffer.mode_info.mode_type = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR; + framebuffer.mode_info.number_of_colors = 16; break; case 16: framebuffer.mode_info.red_mask_size = 5; diff --git a/grub-core/video/efi_uga.c b/grub-core/video/efi_uga.c index 695f01578..159df8e61 100644 --- a/grub-core/video/efi_uga.c +++ b/grub-core/video/efi_uga.c @@ -247,7 +247,7 @@ grub_video_uga_setup (unsigned int width, unsigned int height, framebuffer.mode_info.mode_type = GRUB_VIDEO_MODE_TYPE_RGB; framebuffer.mode_info.bpp = 32; framebuffer.mode_info.bytes_per_pixel = 4; - framebuffer.mode_info.number_of_colors = 256; /* TODO: fix me. */ + framebuffer.mode_info.number_of_colors = 256; framebuffer.mode_info.red_mask_size = 8; framebuffer.mode_info.red_field_pos = 16; framebuffer.mode_info.green_mask_size = 8; diff --git a/grub-core/video/emu/sdl.c b/grub-core/video/emu/sdl.c index f4c1a6ab6..6fd01be39 100644 --- a/grub-core/video/emu/sdl.c +++ b/grub-core/video/emu/sdl.c @@ -151,8 +151,7 @@ grub_video_sdl_setup (unsigned int width, unsigned int height, return err; /* Copy default palette to initialize emulated palette. */ - grub_video_sdl_set_palette (0, (sizeof (grub_video_fbstd_colors) - / sizeof (grub_video_fbstd_colors[0])), + grub_video_sdl_set_palette (0, GRUB_VIDEO_FBSTD_NUMCOLORS, grub_video_fbstd_colors); /* Reset render target to SDL one. */ @@ -166,7 +165,14 @@ grub_video_sdl_set_palette (unsigned int start, unsigned int count, unsigned i; if (window->format->palette) { - SDL_Color *tmp = grub_malloc (count * sizeof (tmp[0])); + SDL_Color *tmp; + if (start >= mode_info.number_of_colors) + return GRUB_ERR_NONE; + + if (start + count > mode_info.number_of_colors) + count = mode_info.number_of_colors - start; + + tmp = grub_malloc (count * sizeof (tmp[0])); for (i = 0; i < count; i++) { tmp[i].r = palette_data[i].r; diff --git a/grub-core/video/fb/fbblit.c b/grub-core/video/fb/fbblit.c index 4d262d710..13e2926bf 100644 --- a/grub-core/video/fb/fbblit.c +++ b/grub-core/video/fb/fbblit.c @@ -416,15 +416,25 @@ grub_video_fbblit_replace_BGRX8888_RGBX8888 (struct grub_video_fbblit_info *dst, { for (i = 0; i < width; i++) { +#ifdef GRUB_CPU_WORDS_BIGENDIAN + grub_uint8_t a = *srcptr++; +#endif grub_uint8_t r = *srcptr++; grub_uint8_t g = *srcptr++; grub_uint8_t b = *srcptr++; +#ifndef GRUB_CPU_WORDS_BIGENDIAN grub_uint8_t a = *srcptr++; +#endif +#ifdef GRUB_CPU_WORDS_BIGENDIAN + *dstptr++ = a; +#endif *dstptr++ = b; *dstptr++ = g; *dstptr++ = r; +#ifndef GRUB_CPU_WORDS_BIGENDIAN *dstptr++ = a; +#endif } srcptr += srcrowskip; @@ -463,12 +473,19 @@ grub_video_fbblit_replace_BGRX8888_RGB888 (struct grub_video_fbblit_info *dst, grub_uint8_t g = *srcptr++; grub_uint8_t b = *srcptr++; +#ifdef GRUB_CPU_WORDS_BIGENDIAN + /* Set alpha component as opaque. */ + *dstptr++ = 255; +#endif + *dstptr++ = b; *dstptr++ = g; *dstptr++ = r; +#ifndef GRUB_CPU_WORDS_BIGENDIAN /* Set alpha component as opaque. */ *dstptr++ = 255; +#endif } srcptr += srcrowskip; @@ -514,9 +531,15 @@ grub_video_fbblit_replace_BGR888_RGBX8888 (struct grub_video_fbblit_info *dst, sg = (color >> 8) & 0xFF; sb = (color >> 16) & 0xFF; +#ifdef GRUB_CPU_WORDS_BIGENDIAN + *dstptr++ = sr; + *dstptr++ = sg; + *dstptr++ = sb; +#else *dstptr++ = sb; *dstptr++ = sg; *dstptr++ = sr; +#endif } GRUB_VIDEO_FB_ADVANCE_POINTER (srcptr, srcrowskip); @@ -593,10 +616,15 @@ grub_video_fbblit_replace_RGBX8888_RGB888 (struct grub_video_fbblit_info *dst, { for (i = 0; i < width; i++) { +#ifdef GRUB_CPU_WORDS_BIGENDIAN + sb = *srcptr++; + sg = *srcptr++; + sr = *srcptr++; +#else sr = *srcptr++; sg = *srcptr++; sb = *srcptr++; - +#endif /* Set alpha as opaque. */ color = 0xFF000000 | (sb << 16) | (sg << 8) | sr; @@ -641,9 +669,15 @@ grub_video_fbblit_replace_RGB888_RGBX8888 (struct grub_video_fbblit_info *dst, sg = (color >> 8) & 0xFF; sb = (color >> 16) & 0xFF; +#ifndef GRUB_CPU_WORDS_BIGENDIAN *dstptr++ = sr; *dstptr++ = sg; *dstptr++ = sb; +#else + *dstptr++ = sb; + *dstptr++ = sg; + *dstptr++ = sr; +#endif } GRUB_VIDEO_FB_ADVANCE_POINTER (srcptr, srcrowskip); GRUB_VIDEO_FB_ADVANCE_POINTER (dstptr, dstrowskip); @@ -681,9 +715,15 @@ grub_video_fbblit_replace_index_RGBX8888 (struct grub_video_fbblit_info *dst, { color = *srcptr++; +#ifdef GRUB_CPU_WORDS_BIGENDIAN + sb = (color >> 0) & 0xFF; + sg = (color >> 8) & 0xFF; + sr = (color >> 16) & 0xFF; +#else sr = (color >> 0) & 0xFF; sg = (color >> 8) & 0xFF; sb = (color >> 16) & 0xFF; +#endif color = grub_video_fb_map_rgb(sr, sg, sb); *dstptr++ = color & 0xFF; @@ -722,9 +762,15 @@ grub_video_fbblit_replace_index_RGB888 (struct grub_video_fbblit_info *dst, { for (i = 0; i < width; i++) { +#ifndef GRUB_CPU_WORDS_BIGENDIAN sr = *srcptr++; sg = *srcptr++; sb = *srcptr++; +#else + sb = *srcptr++; + sg = *srcptr++; + sr = *srcptr++; +#endif color = grub_video_fb_map_rgb(sr, sg, sb); @@ -948,9 +994,15 @@ grub_video_fbblit_blend_BGR888_RGBA8888 (struct grub_video_fbblit_info *dst, dr = (dr * (255 - a) + sr * a) / 255; } +#ifndef GRUB_CPU_WORDS_BIGENDIAN *dstptr++ = db; *dstptr++ = dg; *dstptr++ = dr; +#else + *dstptr++ = dr; + *dstptr++ = dg; + *dstptr++ = db; +#endif } GRUB_VIDEO_FB_ADVANCE_POINTER (srcptr, srcrowskip); @@ -1079,24 +1131,42 @@ grub_video_fbblit_blend_RGB888_RGBA8888 (struct grub_video_fbblit_info *dst, if (a == 255) { +#ifndef GRUB_CPU_WORDS_BIGENDIAN *dstptr++ = sr; *dstptr++ = sg; *dstptr++ = sb; +#else + *dstptr++ = sb; + *dstptr++ = sg; + *dstptr++ = sr; +#endif continue; } +#ifndef GRUB_CPU_WORDS_BIGENDIAN + db = dstptr[0]; + dg = dstptr[1]; + dr = dstptr[2]; +#else dr = dstptr[0]; dg = dstptr[1]; db = dstptr[2]; +#endif dr = (dr * (255 - a) + sr * a) / 255; dg = (dg * (255 - a) + sg * a) / 255; db = (db * (255 - a) + sb * a) / 255; +#ifndef GRUB_CPU_WORDS_BIGENDIAN *dstptr++ = dr; *dstptr++ = dg; *dstptr++ = db; +#else + *dstptr++ = db; + *dstptr++ = dg; + *dstptr++ = dr; +#endif } GRUB_VIDEO_FB_ADVANCE_POINTER (srcptr, srcrowskip); GRUB_VIDEO_FB_ADVANCE_POINTER (dstptr, dstrowskip); @@ -1330,9 +1400,15 @@ grub_video_fbblit_blend_XXX888_1bit (struct grub_video_fbblit_info *dst, if (a == 255) { +#ifndef GRUB_CPU_WORDS_BIGENDIAN ((grub_uint8_t *) dstptr)[0] = color & 0xff; ((grub_uint8_t *) dstptr)[1] = (color & 0xff00) >> 8; ((grub_uint8_t *) dstptr)[2] = (color & 0xff0000) >> 16; +#else + ((grub_uint8_t *) dstptr)[2] = color & 0xff; + ((grub_uint8_t *) dstptr)[1] = (color & 0xff00) >> 8; + ((grub_uint8_t *) dstptr)[0] = (color & 0xff0000) >> 16; +#endif } else if (a != 0) { diff --git a/grub-core/video/fb/fbfill.c b/grub-core/video/fb/fbfill.c index 5f3e55fae..74b157bea 100644 --- a/grub-core/video/fb/fbfill.c +++ b/grub-core/video/fb/fbfill.c @@ -87,10 +87,15 @@ grub_video_fbfill_direct24 (struct grub_video_fbblit_info *dst, int j; grub_size_t rowskip; grub_uint8_t *dstptr; +#ifndef GRUB_CPU_WORDS_BIGENDIAN grub_uint8_t fill0 = (grub_uint8_t)((color >> 0) & 0xFF); grub_uint8_t fill1 = (grub_uint8_t)((color >> 8) & 0xFF); grub_uint8_t fill2 = (grub_uint8_t)((color >> 16) & 0xFF); - +#else + grub_uint8_t fill2 = (grub_uint8_t)((color >> 0) & 0xFF); + grub_uint8_t fill1 = (grub_uint8_t)((color >> 8) & 0xFF); + grub_uint8_t fill0 = (grub_uint8_t)((color >> 16) & 0xFF); +#endif /* Calculate the number of bytes to advance from the end of one line to the beginning of the next line. */ rowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width; @@ -122,13 +127,11 @@ grub_video_fbfill_direct16 (struct grub_video_fbblit_info *dst, int i; int j; grub_size_t rowskip; - grub_uint8_t *dstptr; - grub_uint8_t fill0 = (grub_uint8_t)((color >> 0) & 0xFF); - grub_uint8_t fill1 = (grub_uint8_t)((color >> 8) & 0xFF); + grub_uint16_t *dstptr; /* Calculate the number of bytes to advance from the end of one line to the beginning of the next line. */ - rowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width; + rowskip = (dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width); /* Get the start address. */ dstptr = grub_video_fb_get_video_ptr (dst, x, y); @@ -136,13 +139,10 @@ grub_video_fbfill_direct16 (struct grub_video_fbblit_info *dst, for (j = 0; j < height; j++) { for (i = 0; i < width; i++) - { - *dstptr++ = fill0; - *dstptr++ = fill1; - } + *dstptr++ = color; /* Advance the dest pointer to the right location on the next line. */ - dstptr += rowskip; + GRUB_VIDEO_FB_ADVANCE_POINTER (dstptr, rowskip); } } diff --git a/grub-core/video/fb/fbutil.c b/grub-core/video/fb/fbutil.c index c7fb08702..81b3860ac 100644 --- a/grub-core/video/fb/fbutil.c +++ b/grub-core/video/fb/fbutil.c @@ -82,7 +82,11 @@ get_pixel (struct grub_video_fbblit_info *source, { grub_uint8_t *ptr; ptr = grub_video_fb_get_video_ptr (source, x, y); +#ifdef GRUB_CPU_WORDS_BIGENDIAN + color = ptr[2] | (ptr[1] << 8) | (ptr[0] << 16); +#else color = ptr[0] | (ptr[1] << 8) | (ptr[2] << 16); +#endif } break; @@ -131,7 +135,11 @@ set_pixel (struct grub_video_fbblit_info *source, case 24: { grub_uint8_t *ptr; +#ifdef GRUB_CPU_WORDS_BIGENDIAN + grub_uint8_t *colorptr = ((grub_uint8_t *)&color) + 1; +#else grub_uint8_t *colorptr = (grub_uint8_t *)&color; +#endif ptr = grub_video_fb_get_video_ptr (source, x, y); diff --git a/grub-core/video/fb/video_fb.c b/grub-core/video/fb/video_fb.c index cfe441f42..836842e15 100644 --- a/grub-core/video/fb/video_fb.c +++ b/grub-core/video/fb/video_fb.c @@ -59,8 +59,10 @@ static struct /* Specify "standard" VGA palette, some video cards may need this and this will also be used when using RGB modes. */ -struct grub_video_palette_data grub_video_fbstd_colors[GRUB_VIDEO_FBSTD_NUMCOLORS] = +struct grub_video_palette_data grub_video_fbstd_colors[GRUB_VIDEO_FBSTD_EXT_NUMCOLORS] = { + /* Standard (3-bit) colors. */ + // {R, G, B, A} {0x00, 0x00, 0x00, 0xFF}, // 0 = black {0x00, 0x00, 0xA8, 0xFF}, // 1 = blue @@ -71,6 +73,7 @@ struct grub_video_palette_data grub_video_fbstd_colors[GRUB_VIDEO_FBSTD_NUMCOLOR {0xA8, 0x54, 0x00, 0xFF}, // 6 = brown {0xA8, 0xA8, 0xA8, 0xFF}, // 7 = light gray + /* Bright (4-bit) colors. */ {0x54, 0x54, 0x54, 0xFF}, // 8 = dark gray {0x54, 0x54, 0xFE, 0xFF}, // 9 = bright blue {0x54, 0xFE, 0x54, 0xFF}, // 10 = bright green @@ -78,7 +81,249 @@ struct grub_video_palette_data grub_video_fbstd_colors[GRUB_VIDEO_FBSTD_NUMCOLOR {0xFE, 0x54, 0x54, 0xFF}, // 12 = bright red {0xFE, 0x54, 0xFE, 0xFF}, // 13 = bright magenta {0xFE, 0xFE, 0x54, 0xFF}, // 14 = yellow - {0xFE, 0xFE, 0xFE, 0xFF} // 15 = white + {0xFE, 0xFE, 0xFE, 0xFF}, // 15 = white + + /* Extended (8-bit) colors. Completes preceding colors to full RGB332. */ + {0x00, 0x00, 0x55, 0xFF}, // RGB332 = (0, 0, 1) + {0x00, 0x00, 0xFF, 0xFF}, // RGB332 = (0, 0, 3) + {0x00, 0x24, 0x00, 0xFF}, // RGB332 = (0, 1, 0) + {0x00, 0x24, 0x55, 0xFF}, // RGB332 = (0, 1, 1) + {0x00, 0x24, 0xAA, 0xFF}, // RGB332 = (0, 1, 2) + {0x00, 0x24, 0xFF, 0xFF}, // RGB332 = (0, 1, 3) + {0x00, 0x48, 0x00, 0xFF}, // RGB332 = (0, 2, 0) + {0x00, 0x48, 0x55, 0xFF}, // RGB332 = (0, 2, 1) + {0x00, 0x48, 0xAA, 0xFF}, // RGB332 = (0, 2, 2) + {0x00, 0x48, 0xFF, 0xFF}, // RGB332 = (0, 2, 3) + {0x00, 0x6C, 0x00, 0xFF}, // RGB332 = (0, 3, 0) + {0x00, 0x6C, 0x55, 0xFF}, // RGB332 = (0, 3, 1) + {0x00, 0x6C, 0xAA, 0xFF}, // RGB332 = (0, 3, 2) + {0x00, 0x6C, 0xFF, 0xFF}, // RGB332 = (0, 3, 3) + {0x00, 0x90, 0x00, 0xFF}, // RGB332 = (0, 4, 0) + {0x00, 0x90, 0x55, 0xFF}, // RGB332 = (0, 4, 1) + {0x00, 0x90, 0xAA, 0xFF}, // RGB332 = (0, 4, 2) + {0x00, 0x90, 0xFF, 0xFF}, // RGB332 = (0, 4, 3) + {0x00, 0xB4, 0x55, 0xFF}, // RGB332 = (0, 5, 1) + {0x00, 0xB4, 0xFF, 0xFF}, // RGB332 = (0, 5, 3) + {0x00, 0xD8, 0x00, 0xFF}, // RGB332 = (0, 6, 0) + {0x00, 0xD8, 0x55, 0xFF}, // RGB332 = (0, 6, 1) + {0x00, 0xD8, 0xAA, 0xFF}, // RGB332 = (0, 6, 2) + {0x00, 0xD8, 0xFF, 0xFF}, // RGB332 = (0, 6, 3) + {0x00, 0xFC, 0x00, 0xFF}, // RGB332 = (0, 7, 0) + {0x00, 0xFC, 0x55, 0xFF}, // RGB332 = (0, 7, 1) + {0x00, 0xFC, 0xAA, 0xFF}, // RGB332 = (0, 7, 2) + {0x00, 0xFC, 0xFF, 0xFF}, // RGB332 = (0, 7, 3) + {0x24, 0x00, 0x00, 0xFF}, // RGB332 = (1, 0, 0) + {0x24, 0x00, 0x55, 0xFF}, // RGB332 = (1, 0, 1) + {0x24, 0x00, 0xAA, 0xFF}, // RGB332 = (1, 0, 2) + {0x24, 0x00, 0xFF, 0xFF}, // RGB332 = (1, 0, 3) + {0x24, 0x24, 0x00, 0xFF}, // RGB332 = (1, 1, 0) + {0x24, 0x24, 0x55, 0xFF}, // RGB332 = (1, 1, 1) + {0x24, 0x24, 0xAA, 0xFF}, // RGB332 = (1, 1, 2) + {0x24, 0x24, 0xFF, 0xFF}, // RGB332 = (1, 1, 3) + {0x24, 0x48, 0x00, 0xFF}, // RGB332 = (1, 2, 0) + {0x24, 0x48, 0x55, 0xFF}, // RGB332 = (1, 2, 1) + {0x24, 0x48, 0xAA, 0xFF}, // RGB332 = (1, 2, 2) + {0x24, 0x48, 0xFF, 0xFF}, // RGB332 = (1, 2, 3) + {0x24, 0x6C, 0x00, 0xFF}, // RGB332 = (1, 3, 0) + {0x24, 0x6C, 0x55, 0xFF}, // RGB332 = (1, 3, 1) + {0x24, 0x6C, 0xAA, 0xFF}, // RGB332 = (1, 3, 2) + {0x24, 0x6C, 0xFF, 0xFF}, // RGB332 = (1, 3, 3) + {0x24, 0x90, 0x00, 0xFF}, // RGB332 = (1, 4, 0) + {0x24, 0x90, 0x55, 0xFF}, // RGB332 = (1, 4, 1) + {0x24, 0x90, 0xAA, 0xFF}, // RGB332 = (1, 4, 2) + {0x24, 0x90, 0xFF, 0xFF}, // RGB332 = (1, 4, 3) + {0x24, 0xB4, 0x00, 0xFF}, // RGB332 = (1, 5, 0) + {0x24, 0xB4, 0x55, 0xFF}, // RGB332 = (1, 5, 1) + {0x24, 0xB4, 0xAA, 0xFF}, // RGB332 = (1, 5, 2) + {0x24, 0xB4, 0xFF, 0xFF}, // RGB332 = (1, 5, 3) + {0x24, 0xD8, 0x00, 0xFF}, // RGB332 = (1, 6, 0) + {0x24, 0xD8, 0x55, 0xFF}, // RGB332 = (1, 6, 1) + {0x24, 0xD8, 0xAA, 0xFF}, // RGB332 = (1, 6, 2) + {0x24, 0xD8, 0xFF, 0xFF}, // RGB332 = (1, 6, 3) + {0x24, 0xFC, 0x00, 0xFF}, // RGB332 = (1, 7, 0) + {0x24, 0xFC, 0x55, 0xFF}, // RGB332 = (1, 7, 1) + {0x24, 0xFC, 0xAA, 0xFF}, // RGB332 = (1, 7, 2) + {0x24, 0xFC, 0xFF, 0xFF}, // RGB332 = (1, 7, 3) + {0x48, 0x00, 0x00, 0xFF}, // RGB332 = (2, 0, 0) + {0x48, 0x00, 0x55, 0xFF}, // RGB332 = (2, 0, 1) + {0x48, 0x00, 0xAA, 0xFF}, // RGB332 = (2, 0, 2) + {0x48, 0x00, 0xFF, 0xFF}, // RGB332 = (2, 0, 3) + {0x48, 0x24, 0x00, 0xFF}, // RGB332 = (2, 1, 0) + {0x48, 0x24, 0x55, 0xFF}, // RGB332 = (2, 1, 1) + {0x48, 0x24, 0xAA, 0xFF}, // RGB332 = (2, 1, 2) + {0x48, 0x24, 0xFF, 0xFF}, // RGB332 = (2, 1, 3) + {0x48, 0x48, 0x00, 0xFF}, // RGB332 = (2, 2, 0) + {0x48, 0x48, 0xAA, 0xFF}, // RGB332 = (2, 2, 2) + {0x48, 0x6C, 0x00, 0xFF}, // RGB332 = (2, 3, 0) + {0x48, 0x6C, 0x55, 0xFF}, // RGB332 = (2, 3, 1) + {0x48, 0x6C, 0xAA, 0xFF}, // RGB332 = (2, 3, 2) + {0x48, 0x6C, 0xFF, 0xFF}, // RGB332 = (2, 3, 3) + {0x48, 0x90, 0x00, 0xFF}, // RGB332 = (2, 4, 0) + {0x48, 0x90, 0x55, 0xFF}, // RGB332 = (2, 4, 1) + {0x48, 0x90, 0xAA, 0xFF}, // RGB332 = (2, 4, 2) + {0x48, 0x90, 0xFF, 0xFF}, // RGB332 = (2, 4, 3) + {0x48, 0xB4, 0x00, 0xFF}, // RGB332 = (2, 5, 0) + {0x48, 0xB4, 0x55, 0xFF}, // RGB332 = (2, 5, 1) + {0x48, 0xB4, 0xAA, 0xFF}, // RGB332 = (2, 5, 2) + {0x48, 0xB4, 0xFF, 0xFF}, // RGB332 = (2, 5, 3) + {0x48, 0xD8, 0x00, 0xFF}, // RGB332 = (2, 6, 0) + {0x48, 0xD8, 0x55, 0xFF}, // RGB332 = (2, 6, 1) + {0x48, 0xD8, 0xAA, 0xFF}, // RGB332 = (2, 6, 2) + {0x48, 0xD8, 0xFF, 0xFF}, // RGB332 = (2, 6, 3) + {0x48, 0xFC, 0x00, 0xFF}, // RGB332 = (2, 7, 0) + {0x48, 0xFC, 0xAA, 0xFF}, // RGB332 = (2, 7, 2) + {0x6C, 0x00, 0x00, 0xFF}, // RGB332 = (3, 0, 0) + {0x6C, 0x00, 0x55, 0xFF}, // RGB332 = (3, 0, 1) + {0x6C, 0x00, 0xAA, 0xFF}, // RGB332 = (3, 0, 2) + {0x6C, 0x00, 0xFF, 0xFF}, // RGB332 = (3, 0, 3) + {0x6C, 0x24, 0x00, 0xFF}, // RGB332 = (3, 1, 0) + {0x6C, 0x24, 0x55, 0xFF}, // RGB332 = (3, 1, 1) + {0x6C, 0x24, 0xAA, 0xFF}, // RGB332 = (3, 1, 2) + {0x6C, 0x24, 0xFF, 0xFF}, // RGB332 = (3, 1, 3) + {0x6C, 0x48, 0x00, 0xFF}, // RGB332 = (3, 2, 0) + {0x6C, 0x48, 0x55, 0xFF}, // RGB332 = (3, 2, 1) + {0x6C, 0x48, 0xAA, 0xFF}, // RGB332 = (3, 2, 2) + {0x6C, 0x48, 0xFF, 0xFF}, // RGB332 = (3, 2, 3) + {0x6C, 0x6C, 0x00, 0xFF}, // RGB332 = (3, 3, 0) + {0x6C, 0x6C, 0x55, 0xFF}, // RGB332 = (3, 3, 1) + {0x6C, 0x6C, 0xAA, 0xFF}, // RGB332 = (3, 3, 2) + {0x6C, 0x6C, 0xFF, 0xFF}, // RGB332 = (3, 3, 3) + {0x6C, 0x90, 0x00, 0xFF}, // RGB332 = (3, 4, 0) + {0x6C, 0x90, 0x55, 0xFF}, // RGB332 = (3, 4, 1) + {0x6C, 0x90, 0xAA, 0xFF}, // RGB332 = (3, 4, 2) + {0x6C, 0x90, 0xFF, 0xFF}, // RGB332 = (3, 4, 3) + {0x6C, 0xB4, 0x00, 0xFF}, // RGB332 = (3, 5, 0) + {0x6C, 0xB4, 0x55, 0xFF}, // RGB332 = (3, 5, 1) + {0x6C, 0xB4, 0xAA, 0xFF}, // RGB332 = (3, 5, 2) + {0x6C, 0xB4, 0xFF, 0xFF}, // RGB332 = (3, 5, 3) + {0x6C, 0xD8, 0x00, 0xFF}, // RGB332 = (3, 6, 0) + {0x6C, 0xD8, 0x55, 0xFF}, // RGB332 = (3, 6, 1) + {0x6C, 0xD8, 0xAA, 0xFF}, // RGB332 = (3, 6, 2) + {0x6C, 0xD8, 0xFF, 0xFF}, // RGB332 = (3, 6, 3) + {0x6C, 0xFC, 0x00, 0xFF}, // RGB332 = (3, 7, 0) + {0x6C, 0xFC, 0x55, 0xFF}, // RGB332 = (3, 7, 1) + {0x6C, 0xFC, 0xAA, 0xFF}, // RGB332 = (3, 7, 2) + {0x6C, 0xFC, 0xFF, 0xFF}, // RGB332 = (3, 7, 3) + {0x90, 0x00, 0x00, 0xFF}, // RGB332 = (4, 0, 0) + {0x90, 0x00, 0x55, 0xFF}, // RGB332 = (4, 0, 1) + {0x90, 0x00, 0xAA, 0xFF}, // RGB332 = (4, 0, 2) + {0x90, 0x00, 0xFF, 0xFF}, // RGB332 = (4, 0, 3) + {0x90, 0x24, 0x00, 0xFF}, // RGB332 = (4, 1, 0) + {0x90, 0x24, 0x55, 0xFF}, // RGB332 = (4, 1, 1) + {0x90, 0x24, 0xAA, 0xFF}, // RGB332 = (4, 1, 2) + {0x90, 0x24, 0xFF, 0xFF}, // RGB332 = (4, 1, 3) + {0x90, 0x48, 0x00, 0xFF}, // RGB332 = (4, 2, 0) + {0x90, 0x48, 0x55, 0xFF}, // RGB332 = (4, 2, 1) + {0x90, 0x48, 0xAA, 0xFF}, // RGB332 = (4, 2, 2) + {0x90, 0x48, 0xFF, 0xFF}, // RGB332 = (4, 2, 3) + {0x90, 0x6C, 0x00, 0xFF}, // RGB332 = (4, 3, 0) + {0x90, 0x6C, 0x55, 0xFF}, // RGB332 = (4, 3, 1) + {0x90, 0x6C, 0xAA, 0xFF}, // RGB332 = (4, 3, 2) + {0x90, 0x6C, 0xFF, 0xFF}, // RGB332 = (4, 3, 3) + {0x90, 0x90, 0x00, 0xFF}, // RGB332 = (4, 4, 0) + {0x90, 0x90, 0x55, 0xFF}, // RGB332 = (4, 4, 1) + {0x90, 0x90, 0xAA, 0xFF}, // RGB332 = (4, 4, 2) + {0x90, 0x90, 0xFF, 0xFF}, // RGB332 = (4, 4, 3) + {0x90, 0xB4, 0x00, 0xFF}, // RGB332 = (4, 5, 0) + {0x90, 0xB4, 0x55, 0xFF}, // RGB332 = (4, 5, 1) + {0x90, 0xB4, 0xAA, 0xFF}, // RGB332 = (4, 5, 2) + {0x90, 0xB4, 0xFF, 0xFF}, // RGB332 = (4, 5, 3) + {0x90, 0xD8, 0x00, 0xFF}, // RGB332 = (4, 6, 0) + {0x90, 0xD8, 0x55, 0xFF}, // RGB332 = (4, 6, 1) + {0x90, 0xD8, 0xAA, 0xFF}, // RGB332 = (4, 6, 2) + {0x90, 0xD8, 0xFF, 0xFF}, // RGB332 = (4, 6, 3) + {0x90, 0xFC, 0x00, 0xFF}, // RGB332 = (4, 7, 0) + {0x90, 0xFC, 0x55, 0xFF}, // RGB332 = (4, 7, 1) + {0x90, 0xFC, 0xAA, 0xFF}, // RGB332 = (4, 7, 2) + {0x90, 0xFC, 0xFF, 0xFF}, // RGB332 = (4, 7, 3) + {0xB4, 0x00, 0x55, 0xFF}, // RGB332 = (5, 0, 1) + {0xB4, 0x00, 0xFF, 0xFF}, // RGB332 = (5, 0, 3) + {0xB4, 0x24, 0x00, 0xFF}, // RGB332 = (5, 1, 0) + {0xB4, 0x24, 0x55, 0xFF}, // RGB332 = (5, 1, 1) + {0xB4, 0x24, 0xAA, 0xFF}, // RGB332 = (5, 1, 2) + {0xB4, 0x24, 0xFF, 0xFF}, // RGB332 = (5, 1, 3) + {0xB4, 0x48, 0x55, 0xFF}, // RGB332 = (5, 2, 1) + {0xB4, 0x48, 0xAA, 0xFF}, // RGB332 = (5, 2, 2) + {0xB4, 0x48, 0xFF, 0xFF}, // RGB332 = (5, 2, 3) + {0xB4, 0x6C, 0x00, 0xFF}, // RGB332 = (5, 3, 0) + {0xB4, 0x6C, 0x55, 0xFF}, // RGB332 = (5, 3, 1) + {0xB4, 0x6C, 0xAA, 0xFF}, // RGB332 = (5, 3, 2) + {0xB4, 0x6C, 0xFF, 0xFF}, // RGB332 = (5, 3, 3) + {0xB4, 0x90, 0x00, 0xFF}, // RGB332 = (5, 4, 0) + {0xB4, 0x90, 0x55, 0xFF}, // RGB332 = (5, 4, 1) + {0xB4, 0x90, 0xAA, 0xFF}, // RGB332 = (5, 4, 2) + {0xB4, 0x90, 0xFF, 0xFF}, // RGB332 = (5, 4, 3) + {0xB4, 0xB4, 0x00, 0xFF}, // RGB332 = (5, 5, 0) + {0xB4, 0xB4, 0x55, 0xFF}, // RGB332 = (5, 5, 1) + {0xB4, 0xB4, 0xFF, 0xFF}, // RGB332 = (5, 5, 3) + {0xB4, 0xD8, 0x00, 0xFF}, // RGB332 = (5, 6, 0) + {0xB4, 0xD8, 0x55, 0xFF}, // RGB332 = (5, 6, 1) + {0xB4, 0xD8, 0xAA, 0xFF}, // RGB332 = (5, 6, 2) + {0xB4, 0xD8, 0xFF, 0xFF}, // RGB332 = (5, 6, 3) + {0xB4, 0xFC, 0x00, 0xFF}, // RGB332 = (5, 7, 0) + {0xB4, 0xFC, 0x55, 0xFF}, // RGB332 = (5, 7, 1) + {0xB4, 0xFC, 0xAA, 0xFF}, // RGB332 = (5, 7, 2) + {0xB4, 0xFC, 0xFF, 0xFF}, // RGB332 = (5, 7, 3) + {0xD8, 0x00, 0x00, 0xFF}, // RGB332 = (6, 0, 0) + {0xD8, 0x00, 0x55, 0xFF}, // RGB332 = (6, 0, 1) + {0xD8, 0x00, 0xAA, 0xFF}, // RGB332 = (6, 0, 2) + {0xD8, 0x00, 0xFF, 0xFF}, // RGB332 = (6, 0, 3) + {0xD8, 0x24, 0x00, 0xFF}, // RGB332 = (6, 1, 0) + {0xD8, 0x24, 0x55, 0xFF}, // RGB332 = (6, 1, 1) + {0xD8, 0x24, 0xAA, 0xFF}, // RGB332 = (6, 1, 2) + {0xD8, 0x24, 0xFF, 0xFF}, // RGB332 = (6, 1, 3) + {0xD8, 0x48, 0x00, 0xFF}, // RGB332 = (6, 2, 0) + {0xD8, 0x48, 0x55, 0xFF}, // RGB332 = (6, 2, 1) + {0xD8, 0x48, 0xAA, 0xFF}, // RGB332 = (6, 2, 2) + {0xD8, 0x48, 0xFF, 0xFF}, // RGB332 = (6, 2, 3) + {0xD8, 0x6C, 0x00, 0xFF}, // RGB332 = (6, 3, 0) + {0xD8, 0x6C, 0x55, 0xFF}, // RGB332 = (6, 3, 1) + {0xD8, 0x6C, 0xAA, 0xFF}, // RGB332 = (6, 3, 2) + {0xD8, 0x6C, 0xFF, 0xFF}, // RGB332 = (6, 3, 3) + {0xD8, 0x90, 0x00, 0xFF}, // RGB332 = (6, 4, 0) + {0xD8, 0x90, 0x55, 0xFF}, // RGB332 = (6, 4, 1) + {0xD8, 0x90, 0xAA, 0xFF}, // RGB332 = (6, 4, 2) + {0xD8, 0x90, 0xFF, 0xFF}, // RGB332 = (6, 4, 3) + {0xD8, 0xB4, 0x00, 0xFF}, // RGB332 = (6, 5, 0) + {0xD8, 0xB4, 0x55, 0xFF}, // RGB332 = (6, 5, 1) + {0xD8, 0xB4, 0xAA, 0xFF}, // RGB332 = (6, 5, 2) + {0xD8, 0xB4, 0xFF, 0xFF}, // RGB332 = (6, 5, 3) + {0xD8, 0xD8, 0x00, 0xFF}, // RGB332 = (6, 6, 0) + {0xD8, 0xD8, 0x55, 0xFF}, // RGB332 = (6, 6, 1) + {0xD8, 0xD8, 0xAA, 0xFF}, // RGB332 = (6, 6, 2) + {0xD8, 0xD8, 0xFF, 0xFF}, // RGB332 = (6, 6, 3) + {0xD8, 0xFC, 0x00, 0xFF}, // RGB332 = (6, 7, 0) + {0xD8, 0xFC, 0x55, 0xFF}, // RGB332 = (6, 7, 1) + {0xD8, 0xFC, 0xAA, 0xFF}, // RGB332 = (6, 7, 2) + {0xD8, 0xFC, 0xFF, 0xFF}, // RGB332 = (6, 7, 3) + {0xFC, 0x00, 0x00, 0xFF}, // RGB332 = (7, 0, 0) + {0xFC, 0x00, 0x55, 0xFF}, // RGB332 = (7, 0, 1) + {0xFC, 0x00, 0xAA, 0xFF}, // RGB332 = (7, 0, 2) + {0xFC, 0x00, 0xFF, 0xFF}, // RGB332 = (7, 0, 3) + {0xFC, 0x24, 0x00, 0xFF}, // RGB332 = (7, 1, 0) + {0xFC, 0x24, 0x55, 0xFF}, // RGB332 = (7, 1, 1) + {0xFC, 0x24, 0xAA, 0xFF}, // RGB332 = (7, 1, 2) + {0xFC, 0x24, 0xFF, 0xFF}, // RGB332 = (7, 1, 3) + {0xFC, 0x48, 0x00, 0xFF}, // RGB332 = (7, 2, 0) + {0xFC, 0x48, 0xAA, 0xFF}, // RGB332 = (7, 2, 2) + {0xFC, 0x6C, 0x00, 0xFF}, // RGB332 = (7, 3, 0) + {0xFC, 0x6C, 0x55, 0xFF}, // RGB332 = (7, 3, 1) + {0xFC, 0x6C, 0xAA, 0xFF}, // RGB332 = (7, 3, 2) + {0xFC, 0x6C, 0xFF, 0xFF}, // RGB332 = (7, 3, 3) + {0xFC, 0x90, 0x00, 0xFF}, // RGB332 = (7, 4, 0) + {0xFC, 0x90, 0x55, 0xFF}, // RGB332 = (7, 4, 1) + {0xFC, 0x90, 0xAA, 0xFF}, // RGB332 = (7, 4, 2) + {0xFC, 0x90, 0xFF, 0xFF}, // RGB332 = (7, 4, 3) + {0xFC, 0xB4, 0x00, 0xFF}, // RGB332 = (7, 5, 0) + {0xFC, 0xB4, 0x55, 0xFF}, // RGB332 = (7, 5, 1) + {0xFC, 0xB4, 0xAA, 0xFF}, // RGB332 = (7, 5, 2) + {0xFC, 0xB4, 0xFF, 0xFF}, // RGB332 = (7, 5, 3) + {0xFC, 0xD8, 0x00, 0xFF}, // RGB332 = (7, 6, 0) + {0xFC, 0xD8, 0x55, 0xFF}, // RGB332 = (7, 6, 1) + {0xFC, 0xD8, 0xAA, 0xFF}, // RGB332 = (7, 6, 2) + {0xFC, 0xD8, 0xFF, 0xFF}, // RGB332 = (7, 6, 3) + {0xFC, 0xFC, 0x00, 0xFF}, // RGB332 = (7, 7, 0) + {0xFC, 0xFC, 0xAA, 0xFF}, // RGB332 = (7, 7, 2) }; grub_err_t @@ -487,38 +732,21 @@ grub_video_fb_fill_rect (grub_video_color_t color, int x, int y, /* Try to figure out more optimized version. Note that color is already mapped to target format so we can make assumptions based on that. */ - if (target.mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGRA_8888) + switch (target.mode_info->bytes_per_pixel) { + case 4: grub_video_fbfill_direct32 (&target, color, x, y, - width, height); + width, height); return GRUB_ERR_NONE; - } - else if (target.mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGBA_8888) - { - grub_video_fbfill_direct32 (&target, color, x, y, - width, height); - return GRUB_ERR_NONE; - } - else if (target.mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_888) - { + case 3: grub_video_fbfill_direct24 (&target, color, x, y, - width, height); + width, height); return GRUB_ERR_NONE; - } - else if (target.mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_565) - { + case 2: grub_video_fbfill_direct16 (&target, color, x, y, width, height); return GRUB_ERR_NONE; - } - else if (target.mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGR_565) - { - grub_video_fbfill_direct16 (&target, color, x, y, - width, height); - return GRUB_ERR_NONE; - } - else if (target.mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR) - { + case 1: grub_video_fbfill_direct8 (&target, color, x, y, width, height); return GRUB_ERR_NONE; diff --git a/grub-core/video/i386/pc/vbe.c b/grub-core/video/i386/pc/vbe.c index f112f1567..6f7ede1fc 100644 --- a/grub-core/video/i386/pc/vbe.c +++ b/grub-core/video/i386/pc/vbe.c @@ -938,7 +938,10 @@ vbe2videoinfo (grub_uint32_t mode, else mode_info->pitch = vbeinfo->bytes_per_scan_line; - mode_info->number_of_colors = 256; /* TODO: fix me. */ + if (mode_info->mode_type & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR) + mode_info->number_of_colors = 16; + else + mode_info->number_of_colors = 256; mode_info->red_mask_size = vbeinfo->red_mask_size; mode_info->red_field_pos = vbeinfo->red_field_position; mode_info->green_mask_size = vbeinfo->green_mask_size; diff --git a/grub-core/video/ieee1275.c b/grub-core/video/ieee1275.c index 5830b68f8..5c5870278 100644 --- a/grub-core/video/ieee1275.c +++ b/grub-core/video/ieee1275.c @@ -43,6 +43,20 @@ static struct grub_uint8_t *ptr; } framebuffer; +static struct grub_video_palette_data serial_colors[] = + { + // {R, G, B} + {0x00, 0x00, 0x00, 0xFF}, // 0 = black + {0xA8, 0x00, 0x00, 0xFF}, // 1 = red + {0x00, 0xA8, 0x00, 0xFF}, // 2 = green + {0xFE, 0xFE, 0x54, 0xFF}, // 3 = yellow + {0x00, 0x00, 0xA8, 0xFF}, // 4 = blue + {0xA8, 0x00, 0xA8, 0xFF}, // 5 = magenta + {0x00, 0xA8, 0xA8, 0xFF}, // 6 = cyan + {0xFE, 0xFE, 0xFE, 0xFF} // 7 = white + }; + + static grub_err_t grub_video_ieee1275_set_palette (unsigned int start, unsigned int count, struct grub_video_palette_data *palette_data); @@ -123,11 +137,63 @@ grub_video_ieee1275_fill_mode_info (grub_ieee1275_phandle_t dev, return grub_error (GRUB_ERR_IO, "Couldn't retrieve display pitch."); out->pitch = tmp; - out->mode_type = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR; - out->bpp = 8; - out->bytes_per_pixel = 1; + if (grub_ieee1275_get_integer_property (dev, "depth", &tmp, + sizeof (tmp), 0)) + tmp = 4; + + out->mode_type = GRUB_VIDEO_MODE_TYPE_RGB; + out->bpp = tmp; + out->bytes_per_pixel = (out->bpp + GRUB_CHAR_BIT - 1) / GRUB_CHAR_BIT; out->number_of_colors = 256; + switch (tmp) + { + case 4: + case 8: + out->mode_type = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR; + out->bpp = 8; + if (have_setcolors) + out->number_of_colors = 1 << tmp; + else + out->number_of_colors = 8; + break; + + /* FIXME: we may need byteswapping for the following. Currently it + was seen only on qemu and no byteswap was needed. */ + case 15: + out->red_mask_size = 5; + out->red_field_pos = 10; + out->green_mask_size = 5; + out->green_field_pos = 5; + out->blue_mask_size = 5; + out->blue_field_pos = 0; + break; + + case 16: + out->red_mask_size = 5; + out->red_field_pos = 11; + out->green_mask_size = 6; + out->green_field_pos = 5; + out->blue_mask_size = 5; + out->blue_field_pos = 0; + break; + + case 32: + out->reserved_mask_size = 8; + out->reserved_field_pos = 24; + + case 24: + out->red_mask_size = 8; + out->red_field_pos = 16; + out->green_mask_size = 8; + out->green_field_pos = 8; + out->blue_mask_size = 8; + out->blue_field_pos = 0; + break; + default: + return grub_error (GRUB_ERR_IO, "unsupported video depth %d", tmp); + } + out->blit_format = grub_video_get_blit_format (out); return GRUB_ERR_NONE; } @@ -192,7 +258,7 @@ grub_video_ieee1275_setup (unsigned int width, unsigned int height, if (err) return err; - grub_video_ieee1275_set_palette (0, GRUB_VIDEO_FBSTD_NUMCOLORS, + grub_video_ieee1275_set_palette (0, framebuffer.mode_info.number_of_colors, grub_video_fbstd_colors); return err; @@ -214,25 +280,35 @@ static grub_err_t grub_video_ieee1275_set_palette (unsigned int start, unsigned int count, struct grub_video_palette_data *palette_data) { - grub_err_t err; + unsigned col; struct grub_video_palette_data fb_palette_data[256]; + grub_err_t err; + + if (!(framebuffer.mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR)) + return grub_video_fb_set_palette (start, count, palette_data); + + if (!have_setcolors) + return grub_video_fb_set_palette (0, ARRAY_SIZE (serial_colors), + serial_colors); + + if (start >= framebuffer.mode_info.number_of_colors) + return GRUB_ERR_NONE; + + if (start + count > framebuffer.mode_info.number_of_colors) + count = framebuffer.mode_info.number_of_colors - start; err = grub_video_fb_set_palette (start, count, palette_data); if (err) return err; - grub_video_fb_get_palette (0, ARRAY_SIZE (fb_palette_data), fb_palette_data); - /* Set colors. */ - if (have_setcolors) - { - unsigned col; - for (col = 0; col < ARRAY_SIZE (fb_palette_data); col++) - grub_ieee1275_set_color (stdout_ihandle, col, fb_palette_data[col].r, - fb_palette_data[col].g, - fb_palette_data[col].b); - } + grub_video_fb_get_palette (0, ARRAY_SIZE (fb_palette_data), + fb_palette_data); + for (col = 0; col < ARRAY_SIZE (fb_palette_data); col++) + grub_ieee1275_set_color (stdout_ihandle, col, fb_palette_data[col].r, + fb_palette_data[col].g, + fb_palette_data[col].b); return GRUB_ERR_NONE; } diff --git a/grub-core/video/readers/jpeg.c b/grub-core/video/readers/jpeg.c index f5e63aee2..33f28c32b 100644 --- a/grub-core/video/readers/jpeg.c +++ b/grub-core/video/readers/jpeg.c @@ -528,7 +528,11 @@ grub_jpeg_ycrcb_to_rgb (int yy, int cr, int cb, grub_uint8_t * rgb) dd = 0; if (dd > 255) dd = 255; +#ifdef GRUB_CPU_WORDS_BIGENDIAN + rgb[2] = dd; +#else *(rgb++) = dd; +#endif /* Green */ dd = yy - ((cb * CONST (0.34414) + cr * CONST (0.71414)) >> SHIFT_BITS); @@ -536,7 +540,11 @@ grub_jpeg_ycrcb_to_rgb (int yy, int cr, int cb, grub_uint8_t * rgb) dd = 0; if (dd > 255) dd = 255; +#ifdef GRUB_CPU_WORDS_BIGENDIAN + rgb[1] = dd; +#else *(rgb++) = dd; +#endif /* Blue */ dd = yy + ((cb * CONST (1.772)) >> SHIFT_BITS); @@ -544,7 +552,12 @@ grub_jpeg_ycrcb_to_rgb (int yy, int cr, int cb, grub_uint8_t * rgb) dd = 0; if (dd > 255) dd = 255; +#ifdef GRUB_CPU_WORDS_BIGENDIAN + rgb[0] = dd; + rgb += 3; +#else *(rgb++) = dd; +#endif } static grub_err_t diff --git a/grub-core/video/readers/png.c b/grub-core/video/readers/png.c index 7ef7e3b4c..6cae8965c 100644 --- a/grub-core/video/readers/png.c +++ b/grub-core/video/readers/png.c @@ -253,9 +253,12 @@ grub_png_decode_image_header (struct grub_png_data *data) "png: color type not supported"); if (data->is_16bit) - { data->bpp <<= 1; +#ifndef GRUB_CPU_WORDS_BIGENDIAN + if (data->is_16bit) +#endif + { data->image_data = grub_malloc (data->image_height * data->image_width * data->bpp); if (grub_errno) @@ -263,11 +266,13 @@ grub_png_decode_image_header (struct grub_png_data *data) data->cur_rgb = data->image_data; } +#ifndef GRUB_CPU_WORDS_BIGENDIAN else { data->image_data = 0; data->cur_rgb = (*data->bitmap)->data; } +#endif data->raw_bytes = data->image_height * (data->image_width + 1) * data->bpp; @@ -536,7 +541,7 @@ grub_png_output_byte (struct grub_png_data *data, grub_uint8_t n) data->cur_filter = n; } else - *(data->cur_rgb++) = n; + *data->cur_rgb++ = n; data->cur_column++; row_bytes = data->image_width * data->bpp; @@ -772,12 +777,60 @@ grub_png_convert_image (struct grub_png_data *data) grub_uint8_t *d1, *d2; d1 = (*data->bitmap)->data; - d2 = data->image_data + 1; + d2 = data->image_data + data->is_16bit; /* Only copy the upper 8 bit. */ +#ifndef GRUB_CPU_WORDS_BIGENDIAN for (i = 0; i < (data->image_width * data->image_height * data->bpp >> 1); i++, d1++, d2+=2) *d1 = *d2; +#else + switch (data->bpp) + { + /* 16-bit with alpha. */ + case 8: + for (i = 0; i < (data->image_width * data->image_height); + i++, d1 += 4, d2+=8) + { + d1[0] = d2[7]; + d1[1] = d2[5]; + d1[2] = d2[3]; + d1[3] = d2[1]; + } + break; + /* 16-bit without alpha. */ + case 6: + for (i = 0; i < (data->image_width * data->image_height); + i++, d1 += 3, d2+=6) + { + d1[0] = d2[5]; + d1[1] = d2[3]; + d1[2] = d2[1]; + } + break; + /* 8-bit with alpha. */ + case 4: + for (i = 0; i < (data->image_width * data->image_height); + i++, d1 += 4, d2 += 4) + { + d1[0] = d2[3]; + d1[1] = d2[2]; + d1[2] = d2[1]; + d1[3] = d2[0]; + } + break; + /* 8-bit without alpha. */ + case 3: + for (i = 0; i < (data->image_width * data->image_height); + i++, d1 += 3, d2 += 3) + { + d1[0] = d2[2]; + d1[1] = d2[1]; + d1[2] = d2[0]; + } + break; + } +#endif } static grub_err_t @@ -816,7 +869,9 @@ grub_png_decode_png (struct grub_png_data *data) break; case PNG_CHUNK_IEND: +#ifndef GRUB_CPU_WORDS_BIGENDIAN if (data->is_16bit) +#endif grub_png_convert_image (data); return grub_errno; diff --git a/grub-core/video/sis315pro.c b/grub-core/video/sis315pro.c index a98666944..cf45493a6 100644 --- a/grub-core/video/sis315pro.c +++ b/grub-core/video/sis315pro.c @@ -152,7 +152,7 @@ grub_video_sis315pro_setup (unsigned int width, unsigned int height, framebuffer.mode_info.bpp = 8; framebuffer.mode_info.bytes_per_pixel = 1; framebuffer.mode_info.pitch = 640 * 1; - framebuffer.mode_info.number_of_colors = 256; + framebuffer.mode_info.number_of_colors = 16; framebuffer.mode_info.red_mask_size = 0; framebuffer.mode_info.red_field_pos = 0; framebuffer.mode_info.green_mask_size = 0; @@ -372,7 +372,7 @@ grub_video_sis315pro_setup (unsigned int width, unsigned int height, return err; /* Copy default palette to initialize emulated palette. */ - err = grub_video_fb_set_palette (0, GRUB_VIDEO_FBSTD_NUMCOLORS, + err = grub_video_fb_set_palette (0, GRUB_VIDEO_FBSTD_EXT_NUMCOLORS, grub_video_fbstd_colors); #endif return err; diff --git a/include/grub/video_fb.h b/include/grub/video_fb.h index 0628467e7..ffe16c3ac 100644 --- a/include/grub/video_fb.h +++ b/include/grub/video_fb.h @@ -31,7 +31,9 @@ struct grub_video_fbblit_info; struct grub_video_fbrender_target; #define GRUB_VIDEO_FBSTD_NUMCOLORS 16 -extern struct grub_video_palette_data EXPORT_VAR(grub_video_fbstd_colors)[GRUB_VIDEO_FBSTD_NUMCOLORS]; +#define GRUB_VIDEO_FBSTD_EXT_NUMCOLORS 256 + +extern struct grub_video_palette_data EXPORT_VAR(grub_video_fbstd_colors)[GRUB_VIDEO_FBSTD_EXT_NUMCOLORS]; grub_err_t EXPORT_FUNC(grub_video_fb_init) (void);