2
* GRUB -- GRand Unified Bootloader
3
* Copyright (C) 2006,2007,2008 Free Software Foundation, Inc.
5
* GRUB is free software: you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation, either version 3 of the License, or
8
* (at your option) any later version.
10
* GRUB is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
21
Please note following when reading the code below:
23
- In this driver we assume that every memory can be accessed by same memory
24
bus. If there are different address spaces do not use this code as a base
27
- Every function in this code assumes that bounds checking has been done in
28
previous phase and they are opted out in here. */
30
#include <grub/video_fb.h>
31
#include <grub/fbblit.h>
32
#include <grub/fbutil.h>
33
#include <grub/misc.h>
34
#include <grub/types.h>
35
#include <grub/video.h>
37
/* Generic replacing blitter (slow). Works for every supported format. */
39
grub_video_fbblit_replace (struct grub_video_fbblit_info *dst,
40
struct grub_video_fbblit_info *src,
41
int x, int y, int width, int height,
42
int offset_x, int offset_y)
47
grub_uint8_t src_green;
48
grub_uint8_t src_blue;
49
grub_uint8_t src_alpha;
50
grub_video_color_t src_color;
51
grub_video_color_t dst_color;
53
for (j = 0; j < height; j++)
55
for (i = 0; i < width; i++)
57
src_color = get_pixel (src, i + offset_x, j + offset_y);
59
grub_video_fb_unmap_color_int (src, src_color, &src_red, &src_green,
60
&src_blue, &src_alpha);
62
dst_color = grub_video_fb_map_rgba (src_red, src_green,
65
set_pixel (dst, x + i, y + j, dst_color);
70
/* Block copy replacing blitter. Works with modes multiple of 8 bits. */
72
grub_video_fbblit_replace_directN (struct grub_video_fbblit_info *dst,
73
struct grub_video_fbblit_info *src,
74
int x, int y, int width, int height,
75
int offset_x, int offset_y)
78
grub_uint32_t *srcptr;
79
grub_uint32_t *dstptr;
82
bpp = src->mode_info->bytes_per_pixel;
84
for (j = 0; j < height; j++)
86
srcptr = (grub_uint32_t *)grub_video_fb_get_video_ptr (src, offset_x, j + offset_y);
87
dstptr = (grub_uint32_t *)grub_video_fb_get_video_ptr (dst, x, y + j);
89
grub_memmove (dstptr, srcptr, width * bpp);
93
/* Optimized replacing blitter for 1-bit to 32bit. */
95
grub_video_fbblit_replace_32bit_1bit (struct grub_video_fbblit_info *dst,
96
struct grub_video_fbblit_info *src,
98
int width, int height,
99
int offset_x, int offset_y)
103
grub_uint8_t *srcptr;
104
grub_uint8_t *dstptr;
105
grub_uint8_t srcmask;
106
unsigned int dstrowskip;
107
unsigned int srcrowskipbyte, srcrowskipbit;
108
grub_uint32_t fgcolor, bgcolor;
111
/* Calculate the number of bytes to advance from the end of one line
112
to the beginning of the next line. */
113
dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
114
srcrowskipbyte = (src->mode_info->width - width) >> 3;
115
srcrowskipbit = (src->mode_info->width - width) & 7;
117
bit_index = offset_y * src->mode_info->width + offset_x;
118
srcptr = (grub_uint8_t *) src->data + (bit_index >> 3);
119
srcmask = 1 << (~bit_index & 7);
120
dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
122
fgcolor = grub_video_fb_map_rgba (src->mode_info->fg_red,
123
src->mode_info->fg_green,
124
src->mode_info->fg_blue,
125
src->mode_info->fg_alpha);
127
bgcolor = grub_video_fb_map_rgba (src->mode_info->bg_red,
128
src->mode_info->bg_green,
129
src->mode_info->bg_blue,
130
src->mode_info->bg_alpha);
132
for (j = 0; j < height; j++)
134
for (i = 0; i < width; i++)
136
if (*srcptr & srcmask)
137
*(grub_uint32_t *) dstptr = fgcolor;
139
*(grub_uint32_t *) dstptr = bgcolor;
150
srcptr += srcrowskipbyte;
151
if (srcmask >> srcrowskipbit)
152
srcmask >>= srcrowskipbit;
156
srcmask <<= 8 - srcrowskipbit;
158
dstptr += dstrowskip;
163
/* Optimized replacing blitter for 1-bit to 24-bit. */
165
grub_video_fbblit_replace_24bit_1bit (struct grub_video_fbblit_info *dst,
166
struct grub_video_fbblit_info *src,
168
int width, int height,
169
int offset_x, int offset_y)
173
grub_uint8_t *srcptr;
174
grub_uint8_t *dstptr;
175
grub_uint8_t srcmask;
176
unsigned int dstrowskip;
177
unsigned int srcrowskipbyte, srcrowskipbit;
178
grub_uint32_t fgcolor, bgcolor;
181
/* Calculate the number of bytes to advance from the end of one line
182
to the beginning of the next line. */
183
dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
184
srcrowskipbyte = (src->mode_info->width - width) >> 3;
185
srcrowskipbit = (src->mode_info->width - width) & 7;
187
bit_index = offset_y * src->mode_info->width + offset_x;
188
srcptr = (grub_uint8_t *) src->data + (bit_index >> 3);
189
srcmask = 1 << (~bit_index & 7);
190
dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
192
fgcolor = grub_video_fb_map_rgba (src->mode_info->fg_red,
193
src->mode_info->fg_green,
194
src->mode_info->fg_blue,
195
src->mode_info->fg_alpha);
197
bgcolor = grub_video_fb_map_rgba (src->mode_info->bg_red,
198
src->mode_info->bg_green,
199
src->mode_info->bg_blue,
200
src->mode_info->bg_alpha);
202
for (j = 0; j < height; j++)
204
for (i = 0; i < width - 1; i++)
206
if (*srcptr & srcmask)
207
*(grub_uint32_t *) dstptr = fgcolor;
209
*(grub_uint32_t *) dstptr = bgcolor;
220
if (*srcptr & srcmask)
222
*dstptr++ = fgcolor & 0xff;
223
*dstptr++ = (fgcolor & 0xff00) >> 8;
224
*dstptr++ = (fgcolor & 0xff0000) >> 16;
228
*dstptr++ = bgcolor & 0xff;
229
*dstptr++ = (bgcolor & 0xff00) >> 8;
230
*dstptr++ = (bgcolor & 0xff0000) >> 16;
239
srcptr += srcrowskipbyte;
240
if (srcmask >> srcrowskipbit)
241
srcmask >>= srcrowskipbit;
245
srcmask <<= 8 - srcrowskipbit;
247
dstptr += dstrowskip;
251
/* Optimized replacing blitter for 1-bit to 16-bit. */
253
grub_video_fbblit_replace_16bit_1bit (struct grub_video_fbblit_info *dst,
254
struct grub_video_fbblit_info *src,
256
int width, int height,
257
int offset_x, int offset_y)
261
grub_uint8_t *srcptr;
262
grub_uint8_t *dstptr;
263
grub_uint8_t srcmask;
264
unsigned int dstrowskip;
265
unsigned int srcrowskipbyte, srcrowskipbit;
266
grub_uint16_t fgcolor, bgcolor;
269
/* Calculate the number of bytes to advance from the end of one line
270
to the beginning of the next line. */
271
dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
272
srcrowskipbyte = (src->mode_info->width - width) >> 3;
273
srcrowskipbit = (src->mode_info->width - width) & 7;
275
bit_index = offset_y * src->mode_info->width + offset_x;
276
srcptr = (grub_uint8_t *) src->data + (bit_index >> 3);
277
srcmask = 1 << (~bit_index & 7);
278
dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
280
fgcolor = grub_video_fb_map_rgba (src->mode_info->fg_red,
281
src->mode_info->fg_green,
282
src->mode_info->fg_blue,
283
src->mode_info->fg_alpha);
285
bgcolor = grub_video_fb_map_rgba (src->mode_info->bg_red,
286
src->mode_info->bg_green,
287
src->mode_info->bg_blue,
288
src->mode_info->bg_alpha);
290
for (j = 0; j < height; j++)
292
for (i = 0; i < width; i++)
294
if (*srcptr & srcmask)
295
*(grub_uint16_t *) dstptr = fgcolor;
297
*(grub_uint16_t *) dstptr = bgcolor;
308
srcptr += srcrowskipbyte;
309
if (srcmask >> srcrowskipbit)
310
srcmask >>= srcrowskipbit;
314
srcmask <<= 8 - srcrowskipbit;
316
dstptr += dstrowskip;
320
/* Optimized replacing blitter for 1-bit to 8-bit. */
322
grub_video_fbblit_replace_8bit_1bit (struct grub_video_fbblit_info *dst,
323
struct grub_video_fbblit_info *src,
325
int width, int height,
326
int offset_x, int offset_y)
330
grub_uint8_t *srcptr;
331
grub_uint8_t *dstptr;
332
grub_uint8_t srcmask;
333
unsigned int dstrowskip;
334
unsigned int srcrowskipbyte, srcrowskipbit;
335
grub_uint8_t fgcolor, bgcolor;
338
/* Calculate the number of bytes to advance from the end of one line
339
to the beginning of the next line. */
340
dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
341
srcrowskipbyte = (src->mode_info->width - width) >> 3;
342
srcrowskipbit = (src->mode_info->width - width) & 7;
344
bit_index = offset_y * src->mode_info->width + offset_x;
345
srcptr = (grub_uint8_t *) src->data + (bit_index >> 3);
346
srcmask = 1 << (~bit_index & 7);
347
dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
349
fgcolor = grub_video_fb_map_rgba (src->mode_info->fg_red,
350
src->mode_info->fg_green,
351
src->mode_info->fg_blue,
352
src->mode_info->fg_alpha);
354
bgcolor = grub_video_fb_map_rgba (src->mode_info->bg_red,
355
src->mode_info->bg_green,
356
src->mode_info->bg_blue,
357
src->mode_info->bg_alpha);
359
for (j = 0; j < height; j++)
361
for (i = 0; i < width; i++)
363
if (*srcptr & srcmask)
364
*(grub_uint8_t *) dstptr = fgcolor;
366
*(grub_uint8_t *) dstptr = bgcolor;
377
srcptr += srcrowskipbyte;
378
if (srcmask >> srcrowskipbit)
379
srcmask >>= srcrowskipbit;
383
srcmask <<= 8 - srcrowskipbit;
385
dstptr += dstrowskip;
389
/* Optimized replacing blitter for RGBX8888 to BGRX8888. */
391
grub_video_fbblit_replace_BGRX8888_RGBX8888 (struct grub_video_fbblit_info *dst,
392
struct grub_video_fbblit_info *src,
394
int width, int height,
395
int offset_x, int offset_y)
399
grub_uint8_t *srcptr;
400
grub_uint8_t *dstptr;
401
unsigned int srcrowskip;
402
unsigned int dstrowskip;
404
/* Calculate the number of bytes to advance from the end of one line
405
to the beginning of the next line. */
406
srcrowskip = src->mode_info->pitch - src->mode_info->bytes_per_pixel * width;
407
dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
409
srcptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (src, offset_x, offset_y);
410
dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
412
for (j = 0; j < height; j++)
414
for (i = 0; i < width; i++)
416
grub_uint8_t r = *srcptr++;
417
grub_uint8_t g = *srcptr++;
418
grub_uint8_t b = *srcptr++;
419
grub_uint8_t a = *srcptr++;
427
srcptr += srcrowskip;
428
dstptr += dstrowskip;
432
/* Optimized replacing blitter for RGB888 to BGRX8888. */
434
grub_video_fbblit_replace_BGRX8888_RGB888 (struct grub_video_fbblit_info *dst,
435
struct grub_video_fbblit_info *src,
437
int width, int height,
438
int offset_x, int offset_y)
442
grub_uint8_t *srcptr;
443
grub_uint8_t *dstptr;
444
unsigned int srcrowskip;
445
unsigned int dstrowskip;
447
/* Calculate the number of bytes to advance from the end of one line
448
to the beginning of the next line. */
449
srcrowskip = src->mode_info->pitch - src->mode_info->bytes_per_pixel * width;
450
dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
452
srcptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (src, offset_x, offset_y);
453
dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
455
for (j = 0; j < height; j++)
457
for (i = 0; i < width; i++)
459
grub_uint8_t r = *srcptr++;
460
grub_uint8_t g = *srcptr++;
461
grub_uint8_t b = *srcptr++;
467
/* Set alpha component as opaque. */
471
srcptr += srcrowskip;
472
dstptr += dstrowskip;
476
/* Optimized replacing blitter for RGBX8888 to BGR888. */
478
grub_video_fbblit_replace_BGR888_RGBX8888 (struct grub_video_fbblit_info *dst,
479
struct grub_video_fbblit_info *src,
481
int width, int height,
482
int offset_x, int offset_y)
484
grub_uint32_t *srcptr;
485
grub_uint8_t *dstptr;
486
unsigned int srcrowskip;
487
unsigned int dstrowskip;
491
/* Calculate the number of bytes to advance from the end of one line
492
to the beginning of the next line. */
493
srcrowskip = src->mode_info->pitch - src->mode_info->bytes_per_pixel * width;
494
dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
496
srcptr = (grub_uint32_t *) grub_video_fb_get_video_ptr (src, offset_x, offset_y);
497
dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
499
for (j = 0; j < height; j++)
501
for (i = 0; i < width; i++)
510
sr = (color >> 0) & 0xFF;
511
sg = (color >> 8) & 0xFF;
512
sb = (color >> 16) & 0xFF;
519
srcptr = (grub_uint32_t *) (((grub_uint8_t *) srcptr) + srcrowskip);
520
dstptr += dstrowskip;
524
/* Optimized replacing blitter for RGB888 to BGR888. */
526
grub_video_fbblit_replace_BGR888_RGB888 (struct grub_video_fbblit_info *dst,
527
struct grub_video_fbblit_info *src,
529
int width, int height,
530
int offset_x, int offset_y)
534
grub_uint8_t *srcptr;
535
grub_uint8_t *dstptr;
536
unsigned int srcrowskip;
537
unsigned int dstrowskip;
539
/* Calculate the number of bytes to advance from the end of one line
540
to the beginning of the next line. */
541
srcrowskip = src->mode_info->pitch - src->mode_info->bytes_per_pixel * width;
542
dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
544
srcptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (src, offset_x, offset_y);
545
dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
547
for (j = 0; j < height; j++)
549
for (i = 0; i < width; i++)
551
grub_uint8_t r = *srcptr++;
552
grub_uint8_t g = *srcptr++;
553
grub_uint8_t b = *srcptr++;
560
srcptr += srcrowskip;
561
dstptr += dstrowskip;
565
/* Optimized replacing blitter for RGB888 to RGBX8888. */
567
grub_video_fbblit_replace_RGBX8888_RGB888 (struct grub_video_fbblit_info *dst,
568
struct grub_video_fbblit_info *src,
570
int width, int height,
571
int offset_x, int offset_y)
576
grub_uint8_t *srcptr;
577
grub_uint32_t *dstptr;
582
for (j = 0; j < height; j++)
584
srcptr = (grub_uint8_t *)grub_video_fb_get_video_ptr (src, offset_x, j + offset_y);
585
dstptr = (grub_uint32_t *)grub_video_fb_get_video_ptr (dst, x, y + j);
587
for (i = 0; i < width; i++)
593
/* Set alpha as opaque. */
594
color = 0xFF000000 | (sb << 16) | (sg << 8) | sr;
601
/* Optimized replacing blitter for RGBX8888 to RGB888. */
603
grub_video_fbblit_replace_RGB888_RGBX8888 (struct grub_video_fbblit_info *dst,
604
struct grub_video_fbblit_info *src,
606
int width, int height,
607
int offset_x, int offset_y)
612
grub_uint32_t *srcptr;
613
grub_uint8_t *dstptr;
618
for (j = 0; j < height; j++)
620
srcptr = (grub_uint32_t *)grub_video_fb_get_video_ptr (src, offset_x, j + offset_y);
621
dstptr = (grub_uint8_t *)grub_video_fb_get_video_ptr (dst, x, y + j);
623
for (i = 0; i < width; i++)
627
sr = (color >> 0) & 0xFF;
628
sg = (color >> 8) & 0xFF;
629
sb = (color >> 16) & 0xFF;
638
/* Optimized replacing blitter for RGBX8888 to indexed color. */
640
grub_video_fbblit_replace_index_RGBX8888 (struct grub_video_fbblit_info *dst,
641
struct grub_video_fbblit_info *src,
643
int width, int height,
644
int offset_x, int offset_y)
649
grub_uint32_t *srcptr;
650
grub_uint8_t *dstptr;
655
for (j = 0; j < height; j++)
657
srcptr = (grub_uint32_t *)grub_video_fb_get_video_ptr (src, offset_x, j + offset_y);
658
dstptr = (grub_uint8_t *)grub_video_fb_get_video_ptr (dst, x, y + j);
660
for (i = 0; i < width; i++)
664
sr = (color >> 0) & 0xFF;
665
sg = (color >> 8) & 0xFF;
666
sb = (color >> 16) & 0xFF;
668
color = grub_video_fb_map_rgb(sr, sg, sb);
669
*dstptr++ = color & 0xFF;
674
/* Optimized replacing blitter for RGB888 to indexed color. */
676
grub_video_fbblit_replace_index_RGB888 (struct grub_video_fbblit_info *dst,
677
struct grub_video_fbblit_info *src,
679
int width, int height,
680
int offset_x, int offset_y)
685
grub_uint8_t *srcptr;
686
grub_uint8_t *dstptr;
691
for (j = 0; j < height; j++)
693
srcptr = (grub_uint8_t *)grub_video_fb_get_video_ptr (src, offset_x, j + offset_y);
694
dstptr = (grub_uint8_t *)grub_video_fb_get_video_ptr (dst, x, y + j);
696
for (i = 0; i < width; i++)
702
color = grub_video_fb_map_rgb(sr, sg, sb);
704
*dstptr++ = color & 0xFF;
709
/* Generic blending blitter. Works for every supported format. */
711
grub_video_fbblit_blend (struct grub_video_fbblit_info *dst,
712
struct grub_video_fbblit_info *src,
713
int x, int y, int width, int height,
714
int offset_x, int offset_y)
719
for (j = 0; j < height; j++)
721
for (i = 0; i < width; i++)
723
grub_uint8_t src_red;
724
grub_uint8_t src_green;
725
grub_uint8_t src_blue;
726
grub_uint8_t src_alpha;
727
grub_uint8_t dst_red;
728
grub_uint8_t dst_green;
729
grub_uint8_t dst_blue;
730
grub_uint8_t dst_alpha;
731
grub_video_color_t src_color;
732
grub_video_color_t dst_color;
734
src_color = get_pixel (src, i + offset_x, j + offset_y);
735
grub_video_fb_unmap_color_int (src, src_color, &src_red, &src_green,
736
&src_blue, &src_alpha);
741
if (src_alpha == 255)
743
dst_color = grub_video_fb_map_rgba (src_red, src_green,
744
src_blue, src_alpha);
745
set_pixel (dst, x + i, y + j, dst_color);
749
dst_color = get_pixel (dst, x + i, y + j);
751
grub_video_fb_unmap_color_int (dst, dst_color, &dst_red,
752
&dst_green, &dst_blue, &dst_alpha);
754
dst_red = (((src_red * src_alpha)
755
+ (dst_red * (255 - src_alpha))) / 255);
756
dst_green = (((src_green * src_alpha)
757
+ (dst_green * (255 - src_alpha))) / 255);
758
dst_blue = (((src_blue * src_alpha)
759
+ (dst_blue * (255 - src_alpha))) / 255);
761
dst_alpha = src_alpha;
762
dst_color = grub_video_fb_map_rgba (dst_red, dst_green, dst_blue,
765
set_pixel (dst, x + i, y + j, dst_color);
770
/* Optimized blending blitter for RGBA8888 to BGRA8888. */
772
grub_video_fbblit_blend_BGRA8888_RGBA8888 (struct grub_video_fbblit_info *dst,
773
struct grub_video_fbblit_info *src,
775
int width, int height,
776
int offset_x, int offset_y)
778
grub_uint32_t *srcptr;
779
grub_uint32_t *dstptr;
780
unsigned int srcrowskip;
781
unsigned int dstrowskip;
785
/* Calculate the number of bytes to advance from the end of one line
786
to the beginning of the next line. */
787
srcrowskip = src->mode_info->pitch - src->mode_info->bytes_per_pixel * width;
788
dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
790
srcptr = (grub_uint32_t *) grub_video_fb_get_video_ptr (src, offset_x, offset_y);
791
dstptr = (grub_uint32_t *) grub_video_fb_get_video_ptr (dst, x, y);
793
for (j = 0; j < height; j++)
795
for (i = 0; i < width; i++)
812
/* Skip transparent source pixels. */
817
sr = (color >> 0) & 0xFF;
818
sg = (color >> 8) & 0xFF;
819
sb = (color >> 16) & 0xFF;
823
/* Opaque pixel shortcut. */
830
/* General pixel color blending. */
833
dr = (color >> 16) & 0xFF;
834
dr = (dr * (255 - a) + sr * a) / 255;
835
dg = (color >> 8) & 0xFF;
836
dg = (dg * (255 - a) + sg * a) / 255;
837
db = (color >> 0) & 0xFF;
838
db = (db * (255 - a) + sb * a) / 255;
841
color = (a << 24) | (dr << 16) | (dg << 8) | db;
846
srcptr = (grub_uint32_t *) (((grub_uint8_t *) srcptr) + srcrowskip);
847
dstptr = (grub_uint32_t *) (((grub_uint8_t *) dstptr) + dstrowskip);
851
/* Optimized blending blitter for RGBA8888 to BGR888. */
853
grub_video_fbblit_blend_BGR888_RGBA8888 (struct grub_video_fbblit_info *dst,
854
struct grub_video_fbblit_info *src,
856
int width, int height,
857
int offset_x, int offset_y)
859
grub_uint32_t *srcptr;
860
grub_uint8_t *dstptr;
861
unsigned int srcrowskip;
862
unsigned int dstrowskip;
866
/* Calculate the number of bytes to advance from the end of one line
867
to the beginning of the next line. */
868
srcrowskip = src->mode_info->pitch - src->mode_info->bytes_per_pixel * width;
869
dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
871
srcptr = (grub_uint32_t *) grub_video_fb_get_video_ptr (src, offset_x, offset_y);
872
dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
874
for (j = 0; j < height; j++)
876
for (i = 0; i < width; i++)
893
/* Skip transparent source pixels. */
898
sr = (color >> 0) & 0xFF;
899
sg = (color >> 8) & 0xFF;
900
sb = (color >> 16) & 0xFF;
904
/* Opaque pixel shortcut. */
911
/* General pixel color blending. */
915
db = (db * (255 - a) + sb * a) / 255;
917
dg = (dg * (255 - a) + sg * a) / 255;
919
dr = (dr * (255 - a) + sr * a) / 255;
927
srcptr = (grub_uint32_t *) (((grub_uint8_t *) srcptr) + srcrowskip);
928
dstptr += dstrowskip;
932
/* Optimized blending blitter for RGBA888 to RGBA8888. */
934
grub_video_fbblit_blend_RGBA8888_RGBA8888 (struct grub_video_fbblit_info *dst,
935
struct grub_video_fbblit_info *src,
937
int width, int height,
938
int offset_x, int offset_y)
943
grub_uint32_t *srcptr;
944
grub_uint32_t *dstptr;
953
for (j = 0; j < height; j++)
955
srcptr = (grub_uint32_t *)grub_video_fb_get_video_ptr (src, offset_x, j + offset_y);
956
dstptr = (grub_uint32_t *)grub_video_fb_get_video_ptr (dst, x, y + j);
958
for (i = 0; i < width; i++)
976
sr = (color >> 0) & 0xFF;
977
sg = (color >> 8) & 0xFF;
978
sb = (color >> 16) & 0xFF;
982
dr = (color >> 0) & 0xFF;
983
dg = (color >> 8) & 0xFF;
984
db = (color >> 16) & 0xFF;
986
dr = (dr * (255 - a) + sr * a) / 255;
987
dg = (dg * (255 - a) + sg * a) / 255;
988
db = (db * (255 - a) + sb * a) / 255;
990
color = (a << 24) | (db << 16) | (dg << 8) | dr;
997
/* Optimized blending blitter for RGBA8888 to RGB888. */
999
grub_video_fbblit_blend_RGB888_RGBA8888 (struct grub_video_fbblit_info *dst,
1000
struct grub_video_fbblit_info *src,
1002
int width, int height,
1003
int offset_x, int offset_y)
1005
grub_uint32_t color;
1008
grub_uint32_t *srcptr;
1009
grub_uint8_t *dstptr;
1018
for (j = 0; j < height; j++)
1020
srcptr = (grub_uint32_t *)grub_video_fb_get_video_ptr (src, offset_x, j + offset_y);
1021
dstptr = (grub_uint8_t *)grub_video_fb_get_video_ptr (dst, x, y + j);
1023
for (i = 0; i < width; i++)
1035
sr = (color >> 0) & 0xFF;
1036
sg = (color >> 8) & 0xFF;
1037
sb = (color >> 16) & 0xFF;
1052
dr = (dr * (255 - a) + sr * a) / 255;
1053
dg = (dg * (255 - a) + sg * a) / 255;
1054
db = (db * (255 - a) + sb * a) / 255;
1063
/* Optimized blending blitter for RGBA8888 to indexed color. */
1065
grub_video_fbblit_blend_index_RGBA8888 (struct grub_video_fbblit_info *dst,
1066
struct grub_video_fbblit_info *src,
1068
int width, int height,
1069
int offset_x, int offset_y)
1071
grub_uint32_t color;
1074
grub_uint32_t *srcptr;
1075
grub_uint8_t *dstptr;
1085
for (j = 0; j < height; j++)
1087
srcptr = (grub_uint32_t *)grub_video_fb_get_video_ptr (src, offset_x, j + offset_y);
1088
dstptr = (grub_uint8_t *)grub_video_fb_get_video_ptr (dst, x, y + j);
1090
for (i = 0; i < width; i++)
1102
sr = (color >> 0) & 0xFF;
1103
sg = (color >> 8) & 0xFF;
1104
sb = (color >> 16) & 0xFF;
1108
color = grub_video_fb_map_rgb(sr, sg, sb);
1109
*dstptr++ = color & 0xFF;
1113
grub_video_fb_unmap_color_int (dst, *dstptr, &dr, &dg, &db, &da);
1115
dr = (dr * (255 - a) + sr * a) / 255;
1116
dg = (dg * (255 - a) + sg * a) / 255;
1117
db = (db * (255 - a) + sb * a) / 255;
1119
color = grub_video_fb_map_rgb(dr, dg, db);
1121
*dstptr++ = color & 0xFF;
1126
/* Optimized blending blitter for 1-bit to XXXA8888. */
1128
grub_video_fbblit_blend_XXXA8888_1bit (struct grub_video_fbblit_info *dst,
1129
struct grub_video_fbblit_info *src,
1131
int width, int height,
1132
int offset_x, int offset_y)
1136
grub_uint8_t *srcptr;
1137
grub_uint8_t *dstptr;
1138
grub_uint8_t srcmask;
1139
unsigned int dstrowskip;
1140
unsigned int srcrowskipbyte, srcrowskipbit;
1141
grub_uint32_t fgcolor, bgcolor;
1144
/* Calculate the number of bytes to advance from the end of one line
1145
to the beginning of the next line. */
1146
dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
1147
srcrowskipbyte = (src->mode_info->width - width) >> 3;
1148
srcrowskipbit = (src->mode_info->width - width) & 7;
1150
bit_index = offset_y * src->mode_info->width + offset_x;
1151
srcptr = (grub_uint8_t *) src->data + (bit_index >> 3);
1152
srcmask = 1 << (~bit_index & 7);
1153
dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
1155
fgcolor = grub_video_fb_map_rgba (src->mode_info->fg_red,
1156
src->mode_info->fg_green,
1157
src->mode_info->fg_blue,
1158
src->mode_info->fg_alpha);
1160
bgcolor = grub_video_fb_map_rgba (src->mode_info->bg_red,
1161
src->mode_info->bg_green,
1162
src->mode_info->bg_blue,
1163
src->mode_info->bg_alpha);
1165
for (j = 0; j < height; j++)
1167
for (i = 0; i < width; i++)
1169
grub_uint32_t color;
1172
if (*srcptr & srcmask)
1175
a = src->mode_info->fg_alpha;
1180
a = src->mode_info->bg_alpha;
1184
*(grub_uint32_t *) dstptr = color;
1187
grub_uint8_t s1 = (color >> 0) & 0xFF;
1188
grub_uint8_t s2 = (color >> 8) & 0xFF;
1189
grub_uint8_t s3 = (color >> 16) & 0xFF;
1191
grub_uint8_t d1 = (*(grub_uint32_t *) dstptr >> 0) & 0xFF;
1192
grub_uint8_t d2 = (*(grub_uint32_t *) dstptr >> 8) & 0xFF;
1193
grub_uint8_t d3 = (*(grub_uint32_t *) dstptr >> 16) & 0xFF;
1195
d1 = (d1 * (255 - a) + s1 * a) / 255;
1196
d2 = (d2 * (255 - a) + s2 * a) / 255;
1197
d3 = (d3 * (255 - a) + s3 * a) / 255;
1199
*(grub_uint32_t *) dstptr = (a << 24) | (d3 << 16) | (d2 << 8)
1213
srcptr += srcrowskipbyte;
1214
if (srcmask >> srcrowskipbit)
1215
srcmask >>= srcrowskipbit;
1219
srcmask <<= 8 - srcrowskipbit;
1221
dstptr += dstrowskip;
1225
/* Optimized blending blitter for 1-bit to XXX888. */
1227
grub_video_fbblit_blend_XXX888_1bit (struct grub_video_fbblit_info *dst,
1228
struct grub_video_fbblit_info *src,
1230
int width, int height,
1231
int offset_x, int offset_y)
1235
grub_uint8_t *srcptr;
1236
grub_uint8_t *dstptr;
1237
grub_uint8_t srcmask;
1238
unsigned int dstrowskip;
1239
unsigned int srcrowskipbyte, srcrowskipbit;
1240
grub_uint32_t fgcolor, bgcolor;
1243
/* Calculate the number of bytes to advance from the end of one line
1244
to the beginning of the next line. */
1245
dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
1246
srcrowskipbyte = (src->mode_info->width - width) >> 3;
1247
srcrowskipbit = (src->mode_info->width - width) & 7;
1249
bit_index = offset_y * src->mode_info->width + offset_x;
1250
srcptr = (grub_uint8_t *) src->data + (bit_index >> 3);
1251
srcmask = 1 << (~bit_index & 7);
1252
dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
1254
fgcolor = grub_video_fb_map_rgba (src->mode_info->fg_red,
1255
src->mode_info->fg_green,
1256
src->mode_info->fg_blue,
1257
src->mode_info->fg_alpha);
1259
bgcolor = grub_video_fb_map_rgba (src->mode_info->bg_red,
1260
src->mode_info->bg_green,
1261
src->mode_info->bg_blue,
1262
src->mode_info->bg_alpha);
1264
for (j = 0; j < height; j++)
1266
for (i = 0; i < width; i++)
1268
grub_uint32_t color;
1270
if (*srcptr & srcmask)
1273
a = src->mode_info->fg_alpha;
1278
a = src->mode_info->bg_alpha;
1283
((grub_uint8_t *) dstptr)[0] = color & 0xff;
1284
((grub_uint8_t *) dstptr)[1] = (color & 0xff00) >> 8;
1285
((grub_uint8_t *) dstptr)[2] = (color & 0xff0000) >> 16;
1289
grub_uint8_t s1 = (color >> 0) & 0xFF;
1290
grub_uint8_t s2 = (color >> 8) & 0xFF;
1291
grub_uint8_t s3 = (color >> 16) & 0xFF;
1293
grub_uint8_t d1 = (*(grub_uint32_t *) dstptr >> 0) & 0xFF;
1294
grub_uint8_t d2 = (*(grub_uint32_t *) dstptr >> 8) & 0xFF;
1295
grub_uint8_t d3 = (*(grub_uint32_t *) dstptr >> 16) & 0xFF;
1297
((grub_uint8_t *) dstptr)[0] = (d1 * (255 - a) + s1 * a) / 255;
1298
((grub_uint8_t *) dstptr)[1] = (d2 * (255 - a) + s2 * a) / 255;
1299
((grub_uint8_t *) dstptr)[2] = (d3 * (255 - a) + s3 * a) / 255;
1312
srcptr += srcrowskipbyte;
1313
if (srcmask >> srcrowskipbit)
1314
srcmask >>= srcrowskipbit;
1318
srcmask <<= 8 - srcrowskipbit;
1320
dstptr += dstrowskip;
1324
/* Optimized blending blitter for 1-bit to XXX888. */
1326
grub_video_fbblit_blend_XXX565_1bit (struct grub_video_fbblit_info *dst,
1327
struct grub_video_fbblit_info *src,
1329
int width, int height,
1330
int offset_x, int offset_y)
1334
grub_uint8_t *srcptr;
1335
grub_uint8_t *dstptr;
1336
grub_uint8_t srcmask;
1337
unsigned int dstrowskip;
1338
unsigned int srcrowskipbyte, srcrowskipbit;
1339
grub_uint16_t fgcolor, bgcolor;
1342
/* Calculate the number of bytes to advance from the end of one line
1343
to the beginning of the next line. */
1344
dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
1345
srcrowskipbyte = (src->mode_info->width - width) >> 3;
1346
srcrowskipbit = (src->mode_info->width - width) & 7;
1348
bit_index = offset_y * src->mode_info->width + offset_x;
1349
srcptr = (grub_uint8_t *) src->data + (bit_index >> 3);
1350
srcmask = 1 << (~bit_index & 7);
1351
dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
1353
fgcolor = grub_video_fb_map_rgba (src->mode_info->fg_red,
1354
src->mode_info->fg_green,
1355
src->mode_info->fg_blue,
1356
src->mode_info->fg_alpha);
1358
bgcolor = grub_video_fb_map_rgba (src->mode_info->bg_red,
1359
src->mode_info->bg_green,
1360
src->mode_info->bg_blue,
1361
src->mode_info->bg_alpha);
1363
for (j = 0; j < height; j++)
1365
for (i = 0; i < width; i++)
1367
grub_uint32_t color;
1369
if (*srcptr & srcmask)
1372
a = src->mode_info->fg_alpha;
1377
a = src->mode_info->bg_alpha;
1381
*(grub_uint16_t *) dstptr = color;
1384
grub_uint8_t s1 = (color >> 0) & 0x1F;
1385
grub_uint8_t s2 = (color >> 5) & 0x3F;
1386
grub_uint8_t s3 = (color >> 11) & 0x1F;
1388
grub_uint8_t d1 = (*(grub_uint16_t *) dstptr >> 0) & 0x1F;
1389
grub_uint8_t d2 = (*(grub_uint16_t *) dstptr >> 5) & 0x3F;
1390
grub_uint8_t d3 = (*(grub_uint16_t *) dstptr >> 11) & 0x1F;
1392
d1 = (d1 * (255 - a) + s1 * a) / 255;
1393
d2 = (d2 * (255 - a) + s2 * a) / 255;
1394
d3 = (d3 * (255 - a) + s3 * a) / 255;
1396
*(grub_uint16_t *) dstptr = (d1 & 0x1f) | ((d2 & 0x3f) << 5)
1397
| ((d3 & 0x1f) << 11);
1410
srcptr += srcrowskipbyte;
1411
if (srcmask >> srcrowskipbit)
1412
srcmask >>= srcrowskipbit;
1416
srcmask <<= 8 - srcrowskipbit;
1418
dstptr += dstrowskip;