~hamo/ubuntu/precise/grub2/grub2.hi_res

« back to all changes in this revision

Viewing changes to video/fb/fbblit.c

  • Committer: Bazaar Package Importer
  • Author(s): Colin Watson, Colin Watson, Evan Broder, Mario Limonciello
  • Date: 2010-11-24 13:59:55 UTC
  • mfrom: (1.17.6 upstream) (17.6.15 experimental)
  • Revision ID: james.westby@ubuntu.com-20101124135955-r6ii5sepayr7jt53
Tags: 1.99~20101124-1ubuntu1
[ Colin Watson ]
* Resynchronise with Debian experimental.  Remaining changes:
  - Adjust for default Ubuntu boot options ("quiet splash").
  - Default to hiding the menu; holding down Shift at boot will show it.
  - Set a monochromatic theme for Ubuntu.
  - Apply Ubuntu GRUB Legacy changes to legacy update-grub script: title,
    recovery mode, quiet option, tweak how memtest86+ is displayed, and
    use UUIDs where appropriate.
  - Fix backslash-escaping in merge_debconf_into_conf.
  - Remove "GNU/Linux" from default distributor string.
  - Add crashkernel= options if kdump and makedumpfile are available.
  - If other operating systems are installed, then automatically unhide
    the menu.  Otherwise, if GRUB_HIDDEN_TIMEOUT is 0, then use keystatus
    if available to check whether Shift is pressed.  If it is, show the
    menu, otherwise boot immediately.  If keystatus is not available, then
    fall back to a short delay interruptible with Escape.
  - Allow Shift to interrupt 'sleep --interruptible'.
  - Don't display introductory message about line editing unless we're
    actually offering a shell prompt.  Don't clear the screen just before
    booting if we never drew the menu in the first place.
  - Remove some verbose messages printed before reading the configuration
    file.
  - Suppress progress messages as the kernel and initrd load for
    non-recovery kernel menu entries.
  - Change prepare_grub_to_access_device to handle filesystems
    loop-mounted on file images.
  - Ignore devices loop-mounted from files in 10_linux.
  - Show the boot menu if the previous boot failed, that is if it failed
    to get to the end of one of the normal runlevels.
  - Don't generate /boot/grub/device.map during grub-install or
    grub-mkconfig by default.
  - Adjust upgrade version checks for Ubuntu.
  - Don't display "GRUB loading" unless Shift is held down.
  - Adjust versions of grub-doc and grub-legacy-doc conflicts to tolerate
    our backport of the grub-doc split.
  - Fix LVM/RAID probing in the absence of /boot/grub/device.map.
  - Look for .mo files in /usr/share/locale-langpack as well, in
    preference.
  - Make sure GRUB_TIMEOUT isn't quoted unnecessarily.
  - Probe all devices in 'grub-probe --target=drive' if
    /boot/grub/device.map is missing.
  - Build-depend on qemu-kvm rather than qemu-system for grub-pc tests.
  - Use qemu rather than qemu-system-i386.
  - Program vesafb on BIOS systems rather than efifb.
  - Add a grub-rescue-efi-amd64 package containing a rescue CD-ROM image
    for EFI-AMD64.
  - On Wubi, don't ask for an install device, but just update wubildr
    using the diverted grub-install.
  - When embedding the core image in a post-MBR gap, check for and avoid
    sectors matching any of a list of known signatures.
  - Disable video_bochs and video_cirrus on PC BIOS systems, as probing
    PCI space seems to break on some systems.
* Downgrade "ACPI shutdown failed" error to a debug message, since it can
  cause spurious test failures.

[ Evan Broder ]
* Enable lua from grub-extras.
* Incorporate the bitop library into lua.
* Add enum_pci function to grub module in lua.
* Switch back to gfxpayload=keep by default, unless the video hardware
  is known to not support it.

[ Mario Limonciello ]
* Built part_msdos and vfat into bootx64.efi (LP: #677758)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 *  GRUB  --  GRand Unified Bootloader
3
 
 *  Copyright (C) 2006,2007,2008  Free Software Foundation, Inc.
4
 
 *
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.
9
 
 *
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.
14
 
 *
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/>.
17
 
 */
18
 
 
19
 
/* SPECIAL NOTES!
20
 
 
21
 
   Please note following when reading the code below:
22
 
 
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
25
 
   code for other archs.
26
 
 
27
 
   - Every function in this code assumes that bounds checking has been done in
28
 
   previous phase and they are opted out in here.  */
29
 
 
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>
36
 
 
37
 
/* Generic replacing blitter (slow).  Works for every supported format.  */
38
 
void
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)
43
 
{
44
 
  int i;
45
 
  int j;
46
 
  grub_uint8_t src_red;
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;
52
 
 
53
 
  for (j = 0; j < height; j++)
54
 
    {
55
 
      for (i = 0; i < width; i++)
56
 
        {
57
 
          src_color = get_pixel (src, i + offset_x, j + offset_y);
58
 
 
59
 
          grub_video_fb_unmap_color_int (src, src_color, &src_red, &src_green,
60
 
                                         &src_blue, &src_alpha);
61
 
 
62
 
          dst_color = grub_video_fb_map_rgba (src_red, src_green,
63
 
                                              src_blue, src_alpha);
64
 
 
65
 
          set_pixel (dst, x + i, y + j, dst_color);
66
 
        }
67
 
    }
68
 
}
69
 
 
70
 
/* Block copy replacing blitter.  Works with modes multiple of 8 bits.  */
71
 
void
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)
76
 
{
77
 
  int j;
78
 
  grub_uint32_t *srcptr;
79
 
  grub_uint32_t *dstptr;
80
 
  int bpp;
81
 
 
82
 
  bpp = src->mode_info->bytes_per_pixel;
83
 
 
84
 
  for (j = 0; j < height; j++)
85
 
    {
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);
88
 
 
89
 
      grub_memmove (dstptr, srcptr, width * bpp);
90
 
    }
91
 
}
92
 
 
93
 
/* Optimized replacing blitter for 1-bit to 32bit.  */
94
 
void
95
 
grub_video_fbblit_replace_32bit_1bit (struct grub_video_fbblit_info *dst,
96
 
                                      struct grub_video_fbblit_info *src,
97
 
                                      int x, int y,
98
 
                                      int width, int height,
99
 
                                      int offset_x, int offset_y)
100
 
{
101
 
  int i;
102
 
  int j;
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;
109
 
  int bit_index;
110
 
 
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;
116
 
 
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);
121
 
 
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);
126
 
 
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);
131
 
 
132
 
  for (j = 0; j < height; j++)
133
 
    {
134
 
      for (i = 0; i < width; i++)
135
 
        {
136
 
          if (*srcptr & srcmask)
137
 
            *(grub_uint32_t *) dstptr = fgcolor;
138
 
          else
139
 
            *(grub_uint32_t *) dstptr = bgcolor;
140
 
          srcmask >>= 1;
141
 
          if (!srcmask)
142
 
            {
143
 
              srcptr++;
144
 
              srcmask = 0x80;
145
 
            }
146
 
 
147
 
          dstptr += 4;
148
 
        }
149
 
 
150
 
      srcptr += srcrowskipbyte;
151
 
      if (srcmask >> srcrowskipbit)
152
 
        srcmask >>= srcrowskipbit;
153
 
      else
154
 
        {
155
 
          srcptr++;
156
 
          srcmask <<= 8 - srcrowskipbit;
157
 
        }
158
 
      dstptr += dstrowskip;
159
 
    }
160
 
}
161
 
 
162
 
 
163
 
/* Optimized replacing blitter for 1-bit to 24-bit.  */
164
 
void
165
 
grub_video_fbblit_replace_24bit_1bit (struct grub_video_fbblit_info *dst,
166
 
                                      struct grub_video_fbblit_info *src,
167
 
                                      int x, int y,
168
 
                                      int width, int height,
169
 
                                      int offset_x, int offset_y)
170
 
{
171
 
  int i;
172
 
  int j;
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;
179
 
  int bit_index;
180
 
 
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;
186
 
 
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);
191
 
 
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);
196
 
 
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);
201
 
 
202
 
  for (j = 0; j < height; j++)
203
 
    {
204
 
      for (i = 0; i < width - 1; i++)
205
 
        {
206
 
          if (*srcptr & srcmask)
207
 
            *(grub_uint32_t *) dstptr = fgcolor;
208
 
          else
209
 
            *(grub_uint32_t *) dstptr = bgcolor;
210
 
          srcmask >>= 1;
211
 
          if (!srcmask)
212
 
            {
213
 
              srcptr++;
214
 
              srcmask = 0x80;
215
 
            }
216
 
 
217
 
          dstptr += 3;
218
 
        }
219
 
 
220
 
      if (*srcptr & srcmask)
221
 
        {
222
 
          *dstptr++ = fgcolor & 0xff;
223
 
          *dstptr++ = (fgcolor & 0xff00) >> 8;
224
 
          *dstptr++ = (fgcolor & 0xff0000) >> 16;
225
 
        }
226
 
      else
227
 
        {
228
 
          *dstptr++ = bgcolor & 0xff;
229
 
          *dstptr++ = (bgcolor & 0xff00) >> 8;
230
 
          *dstptr++ = (bgcolor & 0xff0000) >> 16;
231
 
        }
232
 
      srcmask >>= 1;
233
 
      if (!srcmask)
234
 
        {
235
 
          srcptr++;
236
 
          srcmask = 0x80;
237
 
        }
238
 
 
239
 
      srcptr += srcrowskipbyte;
240
 
      if (srcmask >> srcrowskipbit)
241
 
        srcmask >>= srcrowskipbit;
242
 
      else
243
 
        {
244
 
          srcptr++;
245
 
          srcmask <<= 8 - srcrowskipbit;
246
 
        }
247
 
      dstptr += dstrowskip;
248
 
    }
249
 
}
250
 
 
251
 
/* Optimized replacing blitter for 1-bit to 16-bit.  */
252
 
void
253
 
grub_video_fbblit_replace_16bit_1bit (struct grub_video_fbblit_info *dst,
254
 
                                      struct grub_video_fbblit_info *src,
255
 
                                      int x, int y,
256
 
                                      int width, int height,
257
 
                                      int offset_x, int offset_y)
258
 
{
259
 
  int i;
260
 
  int j;
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;
267
 
  int bit_index;
268
 
 
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;
274
 
 
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);
279
 
 
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);
284
 
 
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);
289
 
 
290
 
  for (j = 0; j < height; j++)
291
 
    {
292
 
      for (i = 0; i < width; i++)
293
 
        {
294
 
          if (*srcptr & srcmask)
295
 
            *(grub_uint16_t *) dstptr = fgcolor;
296
 
          else
297
 
            *(grub_uint16_t *) dstptr = bgcolor;
298
 
          srcmask >>= 1;
299
 
          if (!srcmask)
300
 
            {
301
 
              srcptr++;
302
 
              srcmask = 0x80;
303
 
            }
304
 
 
305
 
          dstptr += 2;
306
 
        }
307
 
 
308
 
      srcptr += srcrowskipbyte;
309
 
      if (srcmask >> srcrowskipbit)
310
 
        srcmask >>= srcrowskipbit;
311
 
      else
312
 
        {
313
 
          srcptr++;
314
 
          srcmask <<= 8 - srcrowskipbit;
315
 
        }
316
 
      dstptr += dstrowskip;
317
 
    }
318
 
}
319
 
 
320
 
/* Optimized replacing blitter for 1-bit to 8-bit.  */
321
 
void
322
 
grub_video_fbblit_replace_8bit_1bit (struct grub_video_fbblit_info *dst,
323
 
                                      struct grub_video_fbblit_info *src,
324
 
                                      int x, int y,
325
 
                                      int width, int height,
326
 
                                      int offset_x, int offset_y)
327
 
{
328
 
  int i;
329
 
  int j;
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;
336
 
  int bit_index;
337
 
 
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;
343
 
 
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);
348
 
 
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);
353
 
 
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);
358
 
 
359
 
  for (j = 0; j < height; j++)
360
 
    {
361
 
      for (i = 0; i < width; i++)
362
 
        {
363
 
          if (*srcptr & srcmask)
364
 
            *(grub_uint8_t *) dstptr = fgcolor;
365
 
          else
366
 
            *(grub_uint8_t *) dstptr = bgcolor;
367
 
          srcmask >>= 1;
368
 
          if (!srcmask)
369
 
            {
370
 
              srcptr++;
371
 
              srcmask = 0x80;
372
 
            }
373
 
 
374
 
          dstptr++;
375
 
        }
376
 
 
377
 
      srcptr += srcrowskipbyte;
378
 
      if (srcmask >> srcrowskipbit)
379
 
        srcmask >>= srcrowskipbit;
380
 
      else
381
 
        {
382
 
          srcptr++;
383
 
          srcmask <<= 8 - srcrowskipbit;
384
 
        }
385
 
      dstptr += dstrowskip;
386
 
    }
387
 
}
388
 
 
389
 
/* Optimized replacing blitter for RGBX8888 to BGRX8888.  */
390
 
void
391
 
grub_video_fbblit_replace_BGRX8888_RGBX8888 (struct grub_video_fbblit_info *dst,
392
 
                                             struct grub_video_fbblit_info *src,
393
 
                                             int x, int y,
394
 
                                             int width, int height,
395
 
                                             int offset_x, int offset_y)
396
 
{
397
 
  int i;
398
 
  int j;
399
 
  grub_uint8_t *srcptr;
400
 
  grub_uint8_t *dstptr;
401
 
  unsigned int srcrowskip;
402
 
  unsigned int dstrowskip;
403
 
 
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;
408
 
 
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);
411
 
 
412
 
  for (j = 0; j < height; j++)
413
 
    {
414
 
      for (i = 0; i < width; i++)
415
 
        {
416
 
          grub_uint8_t r = *srcptr++;
417
 
          grub_uint8_t g = *srcptr++;
418
 
          grub_uint8_t b = *srcptr++;
419
 
          grub_uint8_t a = *srcptr++;
420
 
 
421
 
          *dstptr++ = b;
422
 
          *dstptr++ = g;
423
 
          *dstptr++ = r;
424
 
          *dstptr++ = a;
425
 
        }
426
 
 
427
 
      srcptr += srcrowskip;
428
 
      dstptr += dstrowskip;
429
 
    }
430
 
}
431
 
 
432
 
/* Optimized replacing blitter for RGB888 to BGRX8888.  */
433
 
void
434
 
grub_video_fbblit_replace_BGRX8888_RGB888 (struct grub_video_fbblit_info *dst,
435
 
                                           struct grub_video_fbblit_info *src,
436
 
                                           int x, int y,
437
 
                                           int width, int height,
438
 
                                           int offset_x, int offset_y)
439
 
{
440
 
  int i;
441
 
  int j;
442
 
  grub_uint8_t *srcptr;
443
 
  grub_uint8_t *dstptr;
444
 
  unsigned int srcrowskip;
445
 
  unsigned int dstrowskip;
446
 
 
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;
451
 
 
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);
454
 
 
455
 
  for (j = 0; j < height; j++)
456
 
    {
457
 
      for (i = 0; i < width; i++)
458
 
        {
459
 
          grub_uint8_t r = *srcptr++;
460
 
          grub_uint8_t g = *srcptr++;
461
 
          grub_uint8_t b = *srcptr++;
462
 
 
463
 
          *dstptr++ = b;
464
 
          *dstptr++ = g;
465
 
          *dstptr++ = r;
466
 
 
467
 
          /* Set alpha component as opaque.  */
468
 
          *dstptr++ = 255;
469
 
        }
470
 
 
471
 
      srcptr += srcrowskip;
472
 
      dstptr += dstrowskip;
473
 
    }
474
 
}
475
 
 
476
 
/* Optimized replacing blitter for RGBX8888 to BGR888.  */
477
 
void
478
 
grub_video_fbblit_replace_BGR888_RGBX8888 (struct grub_video_fbblit_info *dst,
479
 
                                           struct grub_video_fbblit_info *src,
480
 
                                           int x, int y,
481
 
                                           int width, int height,
482
 
                                           int offset_x, int offset_y)
483
 
{
484
 
  grub_uint32_t *srcptr;
485
 
  grub_uint8_t *dstptr;
486
 
  unsigned int srcrowskip;
487
 
  unsigned int dstrowskip;
488
 
  int i;
489
 
  int j;
490
 
 
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;
495
 
 
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);
498
 
 
499
 
  for (j = 0; j < height; j++)
500
 
    {
501
 
      for (i = 0; i < width; i++)
502
 
        {
503
 
          grub_uint32_t color;
504
 
          grub_uint8_t sr;
505
 
          grub_uint8_t sg;
506
 
          grub_uint8_t sb;
507
 
 
508
 
          color = *srcptr++;
509
 
 
510
 
          sr = (color >> 0) & 0xFF;
511
 
          sg = (color >> 8) & 0xFF;
512
 
          sb = (color >> 16) & 0xFF;
513
 
 
514
 
          *dstptr++ = sb;
515
 
          *dstptr++ = sg;
516
 
          *dstptr++ = sr;
517
 
        }
518
 
 
519
 
      srcptr = (grub_uint32_t *) (((grub_uint8_t *) srcptr) + srcrowskip);
520
 
      dstptr += dstrowskip;
521
 
    }
522
 
}
523
 
 
524
 
/* Optimized replacing blitter for RGB888 to BGR888.  */
525
 
void
526
 
grub_video_fbblit_replace_BGR888_RGB888 (struct grub_video_fbblit_info *dst,
527
 
                                         struct grub_video_fbblit_info *src,
528
 
                                         int x, int y,
529
 
                                         int width, int height,
530
 
                                         int offset_x, int offset_y)
531
 
{
532
 
  int i;
533
 
  int j;
534
 
  grub_uint8_t *srcptr;
535
 
  grub_uint8_t *dstptr;
536
 
  unsigned int srcrowskip;
537
 
  unsigned int dstrowskip;
538
 
 
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;
543
 
 
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);
546
 
 
547
 
  for (j = 0; j < height; j++)
548
 
    {
549
 
      for (i = 0; i < width; i++)
550
 
        {
551
 
          grub_uint8_t r = *srcptr++;
552
 
          grub_uint8_t g = *srcptr++;
553
 
          grub_uint8_t b = *srcptr++;
554
 
 
555
 
          *dstptr++ = b;
556
 
          *dstptr++ = g;
557
 
          *dstptr++ = r;
558
 
        }
559
 
 
560
 
      srcptr += srcrowskip;
561
 
      dstptr += dstrowskip;
562
 
    }
563
 
}
564
 
 
565
 
/* Optimized replacing blitter for RGB888 to RGBX8888.  */
566
 
void
567
 
grub_video_fbblit_replace_RGBX8888_RGB888 (struct grub_video_fbblit_info *dst,
568
 
                                           struct grub_video_fbblit_info *src,
569
 
                                           int x, int y,
570
 
                                           int width, int height,
571
 
                                           int offset_x, int offset_y)
572
 
{
573
 
  grub_uint32_t color;
574
 
  int i;
575
 
  int j;
576
 
  grub_uint8_t *srcptr;
577
 
  grub_uint32_t *dstptr;
578
 
  unsigned int sr;
579
 
  unsigned int sg;
580
 
  unsigned int sb;
581
 
 
582
 
  for (j = 0; j < height; j++)
583
 
    {
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);
586
 
 
587
 
      for (i = 0; i < width; i++)
588
 
        {
589
 
          sr = *srcptr++;
590
 
          sg = *srcptr++;
591
 
          sb = *srcptr++;
592
 
 
593
 
          /* Set alpha as opaque.  */
594
 
          color = 0xFF000000 | (sb << 16) | (sg << 8) | sr;
595
 
 
596
 
          *dstptr++ = color;
597
 
        }
598
 
    }
599
 
}
600
 
 
601
 
/* Optimized replacing blitter for RGBX8888 to RGB888.  */
602
 
void
603
 
grub_video_fbblit_replace_RGB888_RGBX8888 (struct grub_video_fbblit_info *dst,
604
 
                                           struct grub_video_fbblit_info *src,
605
 
                                           int x, int y,
606
 
                                           int width, int height,
607
 
                                           int offset_x, int offset_y)
608
 
{
609
 
  grub_uint32_t color;
610
 
  int i;
611
 
  int j;
612
 
  grub_uint32_t *srcptr;
613
 
  grub_uint8_t *dstptr;
614
 
  unsigned int sr;
615
 
  unsigned int sg;
616
 
  unsigned int sb;
617
 
 
618
 
  for (j = 0; j < height; j++)
619
 
    {
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);
622
 
 
623
 
      for (i = 0; i < width; i++)
624
 
        {
625
 
          color = *srcptr++;
626
 
 
627
 
          sr = (color >> 0) & 0xFF;
628
 
          sg = (color >> 8) & 0xFF;
629
 
          sb = (color >> 16) & 0xFF;
630
 
 
631
 
          *dstptr++ = sr;
632
 
          *dstptr++ = sg;
633
 
          *dstptr++ = sb;
634
 
        }
635
 
    }
636
 
}
637
 
 
638
 
/* Optimized replacing blitter for RGBX8888 to indexed color.  */
639
 
void
640
 
grub_video_fbblit_replace_index_RGBX8888 (struct grub_video_fbblit_info *dst,
641
 
                                          struct grub_video_fbblit_info *src,
642
 
                                          int x, int y,
643
 
                                          int width, int height,
644
 
                                          int offset_x, int offset_y)
645
 
{
646
 
  grub_uint32_t color;
647
 
  int i;
648
 
  int j;
649
 
  grub_uint32_t *srcptr;
650
 
  grub_uint8_t *dstptr;
651
 
  unsigned int sr;
652
 
  unsigned int sg;
653
 
  unsigned int sb;
654
 
 
655
 
  for (j = 0; j < height; j++)
656
 
    {
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);
659
 
 
660
 
      for (i = 0; i < width; i++)
661
 
        {
662
 
          color = *srcptr++;
663
 
 
664
 
          sr = (color >> 0) & 0xFF;
665
 
          sg = (color >> 8) & 0xFF;
666
 
          sb = (color >> 16) & 0xFF;
667
 
 
668
 
          color = grub_video_fb_map_rgb(sr, sg, sb);
669
 
          *dstptr++ = color & 0xFF;
670
 
        }
671
 
    }
672
 
}
673
 
 
674
 
/* Optimized replacing blitter for RGB888 to indexed color.  */
675
 
void
676
 
grub_video_fbblit_replace_index_RGB888 (struct grub_video_fbblit_info *dst,
677
 
                                        struct grub_video_fbblit_info *src,
678
 
                                        int x, int y,
679
 
                                        int width, int height,
680
 
                                        int offset_x, int offset_y)
681
 
{
682
 
  grub_uint32_t color;
683
 
  int i;
684
 
  int j;
685
 
  grub_uint8_t *srcptr;
686
 
  grub_uint8_t *dstptr;
687
 
  unsigned int sr;
688
 
  unsigned int sg;
689
 
  unsigned int sb;
690
 
 
691
 
  for (j = 0; j < height; j++)
692
 
    {
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);
695
 
 
696
 
      for (i = 0; i < width; i++)
697
 
        {
698
 
          sr = *srcptr++;
699
 
          sg = *srcptr++;
700
 
          sb = *srcptr++;
701
 
 
702
 
          color = grub_video_fb_map_rgb(sr, sg, sb);
703
 
 
704
 
          *dstptr++ = color & 0xFF;
705
 
        }
706
 
    }
707
 
}
708
 
 
709
 
/* Generic blending blitter.  Works for every supported format.  */
710
 
void
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)
715
 
{
716
 
  int i;
717
 
  int j;
718
 
 
719
 
  for (j = 0; j < height; j++)
720
 
    {
721
 
      for (i = 0; i < width; i++)
722
 
        {
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;
733
 
 
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);
737
 
 
738
 
          if (src_alpha == 0)
739
 
            continue;
740
 
 
741
 
          if (src_alpha == 255)
742
 
            {
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);
746
 
              continue;
747
 
            }
748
 
 
749
 
          dst_color = get_pixel (dst, x + i, y + j);
750
 
 
751
 
          grub_video_fb_unmap_color_int (dst, dst_color, &dst_red,
752
 
                                         &dst_green, &dst_blue, &dst_alpha);
753
 
 
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);
760
 
 
761
 
          dst_alpha = src_alpha;
762
 
          dst_color = grub_video_fb_map_rgba (dst_red, dst_green, dst_blue,
763
 
                                              dst_alpha);
764
 
 
765
 
          set_pixel (dst, x + i, y + j, dst_color);
766
 
        }
767
 
    }
768
 
}
769
 
 
770
 
/* Optimized blending blitter for RGBA8888 to BGRA8888.  */
771
 
void
772
 
grub_video_fbblit_blend_BGRA8888_RGBA8888 (struct grub_video_fbblit_info *dst,
773
 
                                           struct grub_video_fbblit_info *src,
774
 
                                           int x, int y,
775
 
                                           int width, int height,
776
 
                                           int offset_x, int offset_y)
777
 
{
778
 
  grub_uint32_t *srcptr;
779
 
  grub_uint32_t *dstptr;
780
 
  unsigned int srcrowskip;
781
 
  unsigned int dstrowskip;
782
 
  int i;
783
 
  int j;
784
 
 
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;
789
 
 
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);
792
 
 
793
 
  for (j = 0; j < height; j++)
794
 
    {
795
 
      for (i = 0; i < width; i++)
796
 
        {
797
 
          grub_uint32_t color;
798
 
          unsigned int sr;
799
 
          unsigned int sg;
800
 
          unsigned int sb;
801
 
          unsigned int a;
802
 
          unsigned int dr;
803
 
          unsigned int dg;
804
 
          unsigned int db;
805
 
 
806
 
          color = *srcptr++;
807
 
 
808
 
          a = color >> 24;
809
 
 
810
 
          if (a == 0)
811
 
            {
812
 
              /* Skip transparent source pixels.  */
813
 
              dstptr++;
814
 
              continue;
815
 
            }
816
 
 
817
 
          sr = (color >> 0) & 0xFF;
818
 
          sg = (color >> 8) & 0xFF;
819
 
          sb = (color >> 16) & 0xFF;
820
 
 
821
 
          if (a == 255)
822
 
            {
823
 
              /* Opaque pixel shortcut.  */
824
 
              dr = sr;
825
 
              dg = sg;
826
 
              db = sb;
827
 
            }
828
 
          else
829
 
            {
830
 
              /* General pixel color blending.  */
831
 
              color = *dstptr;
832
 
 
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;
839
 
            }
840
 
 
841
 
          color = (a << 24) | (dr << 16) | (dg << 8) | db;
842
 
 
843
 
          *dstptr++ = color;
844
 
        }
845
 
 
846
 
      srcptr = (grub_uint32_t *) (((grub_uint8_t *) srcptr) + srcrowskip);
847
 
      dstptr = (grub_uint32_t *) (((grub_uint8_t *) dstptr) + dstrowskip);
848
 
    }
849
 
}
850
 
 
851
 
/* Optimized blending blitter for RGBA8888 to BGR888.  */
852
 
void
853
 
grub_video_fbblit_blend_BGR888_RGBA8888 (struct grub_video_fbblit_info *dst,
854
 
                                         struct grub_video_fbblit_info *src,
855
 
                                         int x, int y,
856
 
                                         int width, int height,
857
 
                                         int offset_x, int offset_y)
858
 
{
859
 
  grub_uint32_t *srcptr;
860
 
  grub_uint8_t *dstptr;
861
 
  unsigned int srcrowskip;
862
 
  unsigned int dstrowskip;
863
 
  int i;
864
 
  int j;
865
 
 
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;
870
 
 
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);
873
 
 
874
 
  for (j = 0; j < height; j++)
875
 
    {
876
 
      for (i = 0; i < width; i++)
877
 
        {
878
 
          grub_uint32_t color;
879
 
          unsigned int sr;
880
 
          unsigned int sg;
881
 
          unsigned int sb;
882
 
          unsigned int a;
883
 
          unsigned int dr;
884
 
          unsigned int dg;
885
 
          unsigned int db;
886
 
 
887
 
          color = *srcptr++;
888
 
 
889
 
          a = color >> 24;
890
 
 
891
 
          if (a == 0)
892
 
            {
893
 
              /* Skip transparent source pixels.  */
894
 
              dstptr += 3;
895
 
              continue;
896
 
            }
897
 
 
898
 
          sr = (color >> 0) & 0xFF;
899
 
          sg = (color >> 8) & 0xFF;
900
 
          sb = (color >> 16) & 0xFF;
901
 
 
902
 
          if (a == 255)
903
 
            {
904
 
              /* Opaque pixel shortcut.  */
905
 
              dr = sr;
906
 
              dg = sg;
907
 
              db = sb;
908
 
            }
909
 
          else
910
 
            {
911
 
              /* General pixel color blending.  */
912
 
              color = *dstptr;
913
 
 
914
 
              db = dstptr[0];
915
 
              db = (db * (255 - a) + sb * a) / 255;
916
 
              dg = dstptr[1];
917
 
              dg = (dg * (255 - a) + sg * a) / 255;
918
 
              dr = dstptr[2];
919
 
              dr = (dr * (255 - a) + sr * a) / 255;
920
 
            }
921
 
 
922
 
          *dstptr++ = db;
923
 
          *dstptr++ = dg;
924
 
          *dstptr++ = dr;
925
 
        }
926
 
 
927
 
      srcptr = (grub_uint32_t *) (((grub_uint8_t *) srcptr) + srcrowskip);
928
 
      dstptr += dstrowskip;
929
 
    }
930
 
}
931
 
 
932
 
/* Optimized blending blitter for RGBA888 to RGBA8888.  */
933
 
void
934
 
grub_video_fbblit_blend_RGBA8888_RGBA8888 (struct grub_video_fbblit_info *dst,
935
 
                                           struct grub_video_fbblit_info *src,
936
 
                                           int x, int y,
937
 
                                           int width, int height,
938
 
                                           int offset_x, int offset_y)
939
 
{
940
 
  grub_uint32_t color;
941
 
  int i;
942
 
  int j;
943
 
  grub_uint32_t *srcptr;
944
 
  grub_uint32_t *dstptr;
945
 
  unsigned int sr;
946
 
  unsigned int sg;
947
 
  unsigned int sb;
948
 
  unsigned int a;
949
 
  unsigned int dr;
950
 
  unsigned int dg;
951
 
  unsigned int db;
952
 
 
953
 
  for (j = 0; j < height; j++)
954
 
    {
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);
957
 
 
958
 
      for (i = 0; i < width; i++)
959
 
        {
960
 
          color = *srcptr++;
961
 
 
962
 
          a = color >> 24;
963
 
 
964
 
          if (a == 0)
965
 
            {
966
 
              dstptr++;
967
 
              continue;
968
 
            }
969
 
 
970
 
          if (a == 255)
971
 
            {
972
 
              *dstptr++ = color;
973
 
              continue;
974
 
            }
975
 
 
976
 
          sr = (color >> 0) & 0xFF;
977
 
          sg = (color >> 8) & 0xFF;
978
 
          sb = (color >> 16) & 0xFF;
979
 
 
980
 
          color = *dstptr;
981
 
 
982
 
          dr = (color >> 0) & 0xFF;
983
 
          dg = (color >> 8) & 0xFF;
984
 
          db = (color >> 16) & 0xFF;
985
 
 
986
 
          dr = (dr * (255 - a) + sr * a) / 255;
987
 
          dg = (dg * (255 - a) + sg * a) / 255;
988
 
          db = (db * (255 - a) + sb * a) / 255;
989
 
 
990
 
          color = (a << 24) | (db << 16) | (dg << 8) | dr;
991
 
 
992
 
          *dstptr++ = color;
993
 
        }
994
 
    }
995
 
}
996
 
 
997
 
/* Optimized blending blitter for RGBA8888 to RGB888.  */
998
 
void
999
 
grub_video_fbblit_blend_RGB888_RGBA8888 (struct grub_video_fbblit_info *dst,
1000
 
                                         struct grub_video_fbblit_info *src,
1001
 
                                         int x, int y,
1002
 
                                         int width, int height,
1003
 
                                         int offset_x, int offset_y)
1004
 
{
1005
 
  grub_uint32_t color;
1006
 
  int i;
1007
 
  int j;
1008
 
  grub_uint32_t *srcptr;
1009
 
  grub_uint8_t *dstptr;
1010
 
  unsigned int sr;
1011
 
  unsigned int sg;
1012
 
  unsigned int sb;
1013
 
  unsigned int a;
1014
 
  unsigned int dr;
1015
 
  unsigned int dg;
1016
 
  unsigned int db;
1017
 
 
1018
 
  for (j = 0; j < height; j++)
1019
 
    {
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);
1022
 
 
1023
 
      for (i = 0; i < width; i++)
1024
 
        {
1025
 
          color = *srcptr++;
1026
 
 
1027
 
          a = color >> 24;
1028
 
 
1029
 
          if (a == 0)
1030
 
            {
1031
 
              dstptr += 3;
1032
 
              continue;
1033
 
            }
1034
 
 
1035
 
          sr = (color >> 0) & 0xFF;
1036
 
          sg = (color >> 8) & 0xFF;
1037
 
          sb = (color >> 16) & 0xFF;
1038
 
 
1039
 
          if (a == 255)
1040
 
            {
1041
 
              *dstptr++ = sr;
1042
 
              *dstptr++ = sg;
1043
 
              *dstptr++ = sb;
1044
 
 
1045
 
              continue;
1046
 
            }
1047
 
 
1048
 
          dr = dstptr[0];
1049
 
          dg = dstptr[1];
1050
 
          db = dstptr[2];
1051
 
 
1052
 
          dr = (dr * (255 - a) + sr * a) / 255;
1053
 
          dg = (dg * (255 - a) + sg * a) / 255;
1054
 
          db = (db * (255 - a) + sb * a) / 255;
1055
 
 
1056
 
          *dstptr++ = dr;
1057
 
          *dstptr++ = dg;
1058
 
          *dstptr++ = db;
1059
 
        }
1060
 
    }
1061
 
}
1062
 
 
1063
 
/* Optimized blending blitter for RGBA8888 to indexed color.  */
1064
 
void
1065
 
grub_video_fbblit_blend_index_RGBA8888 (struct grub_video_fbblit_info *dst,
1066
 
                                        struct grub_video_fbblit_info *src,
1067
 
                                        int x, int y,
1068
 
                                        int width, int height,
1069
 
                                        int offset_x, int offset_y)
1070
 
{
1071
 
  grub_uint32_t color;
1072
 
  int i;
1073
 
  int j;
1074
 
  grub_uint32_t *srcptr;
1075
 
  grub_uint8_t *dstptr;
1076
 
  unsigned int sr;
1077
 
  unsigned int sg;
1078
 
  unsigned int sb;
1079
 
  unsigned int a;
1080
 
  unsigned char dr;
1081
 
  unsigned char dg;
1082
 
  unsigned char db;
1083
 
  unsigned char da;
1084
 
 
1085
 
  for (j = 0; j < height; j++)
1086
 
    {
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);
1089
 
 
1090
 
      for (i = 0; i < width; i++)
1091
 
        {
1092
 
          color = *srcptr++;
1093
 
 
1094
 
          a = color >> 24;
1095
 
 
1096
 
          if (a == 0)
1097
 
            {
1098
 
              dstptr++;
1099
 
              continue;
1100
 
            }
1101
 
 
1102
 
          sr = (color >> 0) & 0xFF;
1103
 
          sg = (color >> 8) & 0xFF;
1104
 
          sb = (color >> 16) & 0xFF;
1105
 
 
1106
 
          if (a == 255)
1107
 
            {
1108
 
              color = grub_video_fb_map_rgb(sr, sg, sb);
1109
 
              *dstptr++ = color & 0xFF;
1110
 
              continue;
1111
 
            }
1112
 
 
1113
 
          grub_video_fb_unmap_color_int (dst, *dstptr, &dr, &dg, &db, &da);
1114
 
 
1115
 
          dr = (dr * (255 - a) + sr * a) / 255;
1116
 
          dg = (dg * (255 - a) + sg * a) / 255;
1117
 
          db = (db * (255 - a) + sb * a) / 255;
1118
 
 
1119
 
          color = grub_video_fb_map_rgb(dr, dg, db);
1120
 
 
1121
 
          *dstptr++ = color & 0xFF;
1122
 
        }
1123
 
    }
1124
 
}
1125
 
 
1126
 
/* Optimized blending blitter for 1-bit to XXXA8888.  */
1127
 
void
1128
 
grub_video_fbblit_blend_XXXA8888_1bit (struct grub_video_fbblit_info *dst,
1129
 
                                       struct grub_video_fbblit_info *src,
1130
 
                                       int x, int y,
1131
 
                                       int width, int height,
1132
 
                                       int offset_x, int offset_y)
1133
 
{
1134
 
  int i;
1135
 
  int j;
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;
1142
 
  int bit_index;
1143
 
 
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;
1149
 
 
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);
1154
 
 
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);
1159
 
 
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);
1164
 
 
1165
 
  for (j = 0; j < height; j++)
1166
 
    {
1167
 
      for (i = 0; i < width; i++)
1168
 
        {
1169
 
          grub_uint32_t color;
1170
 
          grub_uint8_t a;
1171
 
 
1172
 
          if (*srcptr & srcmask)
1173
 
            {
1174
 
              color = fgcolor;
1175
 
              a = src->mode_info->fg_alpha;
1176
 
            }
1177
 
          else
1178
 
            {
1179
 
              color = bgcolor;
1180
 
              a = src->mode_info->bg_alpha;
1181
 
            }
1182
 
 
1183
 
          if (a == 255)
1184
 
            *(grub_uint32_t *) dstptr = color;
1185
 
          else if (a != 0)
1186
 
            {
1187
 
              grub_uint8_t s1 = (color >> 0) & 0xFF;
1188
 
              grub_uint8_t s2 = (color >> 8) & 0xFF;
1189
 
              grub_uint8_t s3 = (color >> 16) & 0xFF;
1190
 
 
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;
1194
 
 
1195
 
              d1 = (d1 * (255 - a) + s1 * a) / 255;
1196
 
              d2 = (d2 * (255 - a) + s2 * a) / 255;
1197
 
              d3 = (d3 * (255 - a) + s3 * a) / 255;
1198
 
 
1199
 
              *(grub_uint32_t *) dstptr = (a << 24) | (d3 << 16) | (d2 << 8)
1200
 
                | d1;
1201
 
            }
1202
 
 
1203
 
          srcmask >>= 1;
1204
 
          if (!srcmask)
1205
 
            {
1206
 
              srcptr++;
1207
 
              srcmask = 0x80;
1208
 
            }
1209
 
 
1210
 
          dstptr += 4;
1211
 
        }
1212
 
 
1213
 
      srcptr += srcrowskipbyte;
1214
 
      if (srcmask >> srcrowskipbit)
1215
 
        srcmask >>= srcrowskipbit;
1216
 
      else
1217
 
        {
1218
 
          srcptr++;
1219
 
          srcmask <<= 8 - srcrowskipbit;
1220
 
        }
1221
 
      dstptr += dstrowskip;
1222
 
    }
1223
 
}
1224
 
 
1225
 
/* Optimized blending blitter for 1-bit to XXX888.  */
1226
 
void
1227
 
grub_video_fbblit_blend_XXX888_1bit (struct grub_video_fbblit_info *dst,
1228
 
                                     struct grub_video_fbblit_info *src,
1229
 
                                     int x, int y,
1230
 
                                     int width, int height,
1231
 
                                     int offset_x, int offset_y)
1232
 
{
1233
 
  int i;
1234
 
  int j;
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;
1241
 
  int bit_index;
1242
 
 
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;
1248
 
 
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);
1253
 
 
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);
1258
 
 
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);
1263
 
 
1264
 
  for (j = 0; j < height; j++)
1265
 
    {
1266
 
      for (i = 0; i < width; i++)
1267
 
        {
1268
 
          grub_uint32_t color;
1269
 
          grub_uint8_t a;
1270
 
          if (*srcptr & srcmask)
1271
 
            {
1272
 
              color = fgcolor;
1273
 
              a = src->mode_info->fg_alpha;
1274
 
            }
1275
 
          else
1276
 
            {
1277
 
              color = bgcolor;
1278
 
              a = src->mode_info->bg_alpha;
1279
 
            }
1280
 
 
1281
 
          if (a == 255)
1282
 
            {
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;
1286
 
            }
1287
 
          else if (a != 0)
1288
 
            {
1289
 
              grub_uint8_t s1 = (color >> 0) & 0xFF;
1290
 
              grub_uint8_t s2 = (color >> 8) & 0xFF;
1291
 
              grub_uint8_t s3 = (color >> 16) & 0xFF;
1292
 
 
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;
1296
 
 
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;
1300
 
            }
1301
 
 
1302
 
          srcmask >>= 1;
1303
 
          if (!srcmask)
1304
 
            {
1305
 
              srcptr++;
1306
 
              srcmask = 0x80;
1307
 
            }
1308
 
 
1309
 
          dstptr += 3;
1310
 
        }
1311
 
 
1312
 
      srcptr += srcrowskipbyte;
1313
 
      if (srcmask >> srcrowskipbit)
1314
 
        srcmask >>= srcrowskipbit;
1315
 
      else
1316
 
        {
1317
 
          srcptr++;
1318
 
          srcmask <<= 8 - srcrowskipbit;
1319
 
        }
1320
 
      dstptr += dstrowskip;
1321
 
    }
1322
 
}
1323
 
 
1324
 
/* Optimized blending blitter for 1-bit to XXX888.  */
1325
 
void
1326
 
grub_video_fbblit_blend_XXX565_1bit (struct grub_video_fbblit_info *dst,
1327
 
                                     struct grub_video_fbblit_info *src,
1328
 
                                     int x, int y,
1329
 
                                     int width, int height,
1330
 
                                     int offset_x, int offset_y)
1331
 
{
1332
 
  int i;
1333
 
  int j;
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;
1340
 
  int bit_index;
1341
 
 
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;
1347
 
 
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);
1352
 
 
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);
1357
 
 
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);
1362
 
 
1363
 
  for (j = 0; j < height; j++)
1364
 
    {
1365
 
      for (i = 0; i < width; i++)
1366
 
        {
1367
 
          grub_uint32_t color;
1368
 
          grub_uint8_t a;
1369
 
          if (*srcptr & srcmask)
1370
 
            {
1371
 
              color = fgcolor;
1372
 
              a = src->mode_info->fg_alpha;
1373
 
            }
1374
 
          else
1375
 
            {
1376
 
              color = bgcolor;
1377
 
              a = src->mode_info->bg_alpha;
1378
 
            }
1379
 
 
1380
 
          if (a == 255)
1381
 
            *(grub_uint16_t *) dstptr = color;
1382
 
          else if (a != 0)
1383
 
            {
1384
 
              grub_uint8_t s1 = (color >> 0) & 0x1F;
1385
 
              grub_uint8_t s2 = (color >> 5) & 0x3F;
1386
 
              grub_uint8_t s3 = (color >> 11) & 0x1F;
1387
 
 
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;
1391
 
 
1392
 
              d1 = (d1 * (255 - a) + s1 * a) / 255;
1393
 
              d2 = (d2 * (255 - a) + s2 * a) / 255;
1394
 
              d3 = (d3 * (255 - a) + s3 * a) / 255;
1395
 
 
1396
 
              *(grub_uint16_t *) dstptr = (d1 & 0x1f) | ((d2 & 0x3f) << 5)
1397
 
                | ((d3 & 0x1f) << 11);
1398
 
            }
1399
 
 
1400
 
          srcmask >>= 1;
1401
 
          if (!srcmask)
1402
 
            {
1403
 
              srcptr++;
1404
 
              srcmask = 0x80;
1405
 
            }
1406
 
 
1407
 
          dstptr += 2;
1408
 
        }
1409
 
 
1410
 
      srcptr += srcrowskipbyte;
1411
 
      if (srcmask >> srcrowskipbit)
1412
 
        srcmask >>= srcrowskipbit;
1413
 
      else
1414
 
        {
1415
 
          srcptr++;
1416
 
          srcmask <<= 8 - srcrowskipbit;
1417
 
        }
1418
 
      dstptr += dstrowskip;
1419
 
    }
1420
 
}