~darkmuggle-deactivatedaccount/ubuntu/quantal/grub2/fix-872244

« back to all changes in this revision

Viewing changes to video/readers/tga.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  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
 
#include <grub/bitmap.h>
20
 
#include <grub/types.h>
21
 
#include <grub/normal.h>
22
 
#include <grub/dl.h>
23
 
#include <grub/mm.h>
24
 
#include <grub/misc.h>
25
 
#include <grub/bufio.h>
26
 
 
27
 
/* Uncomment following define to enable TGA debug.  */
28
 
//#define TGA_DEBUG
29
 
 
30
 
#if defined(TGA_DEBUG)
31
 
#define dump_int_field(x) grub_printf( #x " = %d (0x%04x)\n", x, x);
32
 
static grub_command_t cmd;
33
 
#endif
34
 
 
35
 
enum
36
 
{
37
 
  GRUB_TGA_IMAGE_TYPE_NONE = 0,
38
 
  GRUB_TGA_IMAGE_TYPE_UNCOMPRESSED_INDEXCOLOR = 1,
39
 
  GRUB_TGA_IMAGE_TYPE_UNCOMPRESSED_TRUECOLOR = 2,
40
 
  GRUB_TGA_IMAGE_TYPE_UNCOMPRESSED_BLACK_AND_WHITE = 3,
41
 
  GRUB_TGA_IMAGE_TYPE_RLE_INDEXCOLOR = 9,
42
 
  GRUB_TGA_IMAGE_TYPE_RLE_TRUECOLOR = 10,
43
 
  GRUB_TGA_IMAGE_TYPE_RLE_BLACK_AND_WHITE = 11,
44
 
};
45
 
 
46
 
enum
47
 
{
48
 
  GRUB_TGA_COLOR_MAP_TYPE_NONE = 0,
49
 
  GRUB_TGA_COLOR_MAP_TYPE_INCLUDED = 1
50
 
};
51
 
 
52
 
enum
53
 
{
54
 
  GRUB_TGA_IMAGE_ORIGIN_RIGHT = 0x10,
55
 
  GRUB_TGA_IMAGE_ORIGIN_TOP   = 0x20
56
 
};
57
 
 
58
 
struct grub_tga_header
59
 
{
60
 
  grub_uint8_t id_length;
61
 
  grub_uint8_t color_map_type;
62
 
  grub_uint8_t image_type;
63
 
 
64
 
  /* Color Map Specification.  */
65
 
  grub_uint16_t color_map_first_index;
66
 
  grub_uint16_t color_map_length;
67
 
  grub_uint8_t color_map_bpp;
68
 
 
69
 
  /* Image Specification.  */
70
 
  grub_uint16_t image_x_origin;
71
 
  grub_uint16_t image_y_origin;
72
 
  grub_uint16_t image_width;
73
 
  grub_uint16_t image_height;
74
 
  grub_uint8_t image_bpp;
75
 
  grub_uint8_t image_descriptor;
76
 
} __attribute__ ((packed));
77
 
 
78
 
static grub_err_t
79
 
tga_load_truecolor_rle_R8G8B8 (struct grub_video_bitmap *bitmap,
80
 
                               struct grub_tga_header *header,
81
 
                               grub_file_t file)
82
 
{
83
 
  unsigned int x;
84
 
  unsigned int y;
85
 
  grub_uint8_t type;
86
 
  grub_uint8_t *ptr;
87
 
  grub_uint8_t tmp[4]; /* Size should be max_bpp / 8.  */
88
 
  grub_uint8_t bytes_per_pixel;
89
 
 
90
 
  bytes_per_pixel = header->image_bpp / 8;
91
 
 
92
 
  for (y = 0; y < header->image_height; y++)
93
 
    {
94
 
      ptr = bitmap->data;
95
 
      if ((header->image_descriptor & GRUB_TGA_IMAGE_ORIGIN_TOP) != 0)
96
 
        ptr += y * bitmap->mode_info.pitch;
97
 
      else
98
 
        ptr += (header->image_height - 1 - y) * bitmap->mode_info.pitch;
99
 
 
100
 
      for (x = 0; x < header->image_width;)
101
 
        {
102
 
          if (grub_file_read (file, &type, sizeof (type)) != sizeof(type))
103
 
            return grub_errno;
104
 
 
105
 
          if (type & 0x80)
106
 
            {
107
 
              /* RLE-encoded packet.  */
108
 
              type &= 0x7f;
109
 
              type++;
110
 
 
111
 
              if (grub_file_read (file, &tmp[0], bytes_per_pixel)
112
 
                  != bytes_per_pixel)
113
 
                return grub_errno;
114
 
 
115
 
              while (type)
116
 
                {
117
 
                  if (x < header->image_width)
118
 
                    {
119
 
                      ptr[0] = tmp[2];
120
 
                      ptr[1] = tmp[1];
121
 
                      ptr[2] = tmp[0];
122
 
                      ptr += 3;
123
 
                    }
124
 
 
125
 
                  type--;
126
 
                  x++;
127
 
                }
128
 
            }
129
 
          else
130
 
            {
131
 
              /* RAW-encoded packet.  */
132
 
              type++;
133
 
 
134
 
              while (type)
135
 
                {
136
 
                  if (grub_file_read (file, &tmp[0], bytes_per_pixel)
137
 
                      != bytes_per_pixel)
138
 
                    return grub_errno;
139
 
 
140
 
                  if (x < header->image_width)
141
 
                    {
142
 
                      ptr[0] = tmp[2];
143
 
                      ptr[1] = tmp[1];
144
 
                      ptr[2] = tmp[0];
145
 
                      ptr += 3;
146
 
                    }
147
 
 
148
 
                  type--;
149
 
                  x++;
150
 
                }
151
 
            }
152
 
        }
153
 
    }
154
 
  return GRUB_ERR_NONE;
155
 
}
156
 
 
157
 
static grub_err_t
158
 
tga_load_truecolor_rle_R8G8B8A8 (struct grub_video_bitmap *bitmap,
159
 
                                 struct grub_tga_header *header,
160
 
                                 grub_file_t file)
161
 
{
162
 
  unsigned int x;
163
 
  unsigned int y;
164
 
  grub_uint8_t type;
165
 
  grub_uint8_t *ptr;
166
 
  grub_uint8_t tmp[4]; /* Size should be max_bpp / 8.  */
167
 
  grub_uint8_t bytes_per_pixel;
168
 
 
169
 
  bytes_per_pixel = header->image_bpp / 8;
170
 
 
171
 
  for (y = 0; y < header->image_height; y++)
172
 
    {
173
 
      ptr = bitmap->data;
174
 
      if ((header->image_descriptor & GRUB_TGA_IMAGE_ORIGIN_TOP) != 0)
175
 
        ptr += y * bitmap->mode_info.pitch;
176
 
      else
177
 
        ptr += (header->image_height - 1 - y) * bitmap->mode_info.pitch;
178
 
 
179
 
      for (x = 0; x < header->image_width;)
180
 
        {
181
 
          if (grub_file_read (file, &type, sizeof (type)) != sizeof(type))
182
 
            return grub_errno;
183
 
 
184
 
          if (type & 0x80)
185
 
            {
186
 
              /* RLE-encoded packet.  */
187
 
              type &= 0x7f;
188
 
              type++;
189
 
 
190
 
              if (grub_file_read (file, &tmp[0], bytes_per_pixel)
191
 
                  != bytes_per_pixel)
192
 
                return grub_errno;
193
 
 
194
 
              while (type)
195
 
                {
196
 
                  if (x < header->image_width)
197
 
                    {
198
 
                      ptr[0] = tmp[2];
199
 
                      ptr[1] = tmp[1];
200
 
                      ptr[2] = tmp[0];
201
 
                      ptr[3] = tmp[3];
202
 
                      ptr += 4;
203
 
                    }
204
 
 
205
 
                  type--;
206
 
                  x++;
207
 
                }
208
 
            }
209
 
          else
210
 
            {
211
 
              /* RAW-encoded packet.  */
212
 
              type++;
213
 
 
214
 
              while (type)
215
 
                {
216
 
                  if (grub_file_read (file, &tmp[0], bytes_per_pixel)
217
 
                      != bytes_per_pixel)
218
 
                    return grub_errno;
219
 
 
220
 
                  if (x < header->image_width)
221
 
                    {
222
 
                      ptr[0] = tmp[2];
223
 
                      ptr[1] = tmp[1];
224
 
                      ptr[2] = tmp[0];
225
 
                      ptr[3] = tmp[3];
226
 
                      ptr += 4;
227
 
                    }
228
 
 
229
 
                  type--;
230
 
                  x++;
231
 
                }
232
 
            }
233
 
        }
234
 
    }
235
 
  return GRUB_ERR_NONE;
236
 
}
237
 
 
238
 
static grub_err_t
239
 
tga_load_truecolor_R8G8B8 (struct grub_video_bitmap *bitmap,
240
 
                           struct grub_tga_header *header,
241
 
                           grub_file_t file)
242
 
{
243
 
  unsigned int x;
244
 
  unsigned int y;
245
 
  grub_uint8_t *ptr;
246
 
  grub_uint8_t tmp[4]; /* Size should be max_bpp / 8.  */
247
 
  grub_uint8_t bytes_per_pixel;
248
 
 
249
 
  bytes_per_pixel = header->image_bpp / 8;
250
 
 
251
 
  for (y = 0; y < header->image_height; y++)
252
 
    {
253
 
      ptr = bitmap->data;
254
 
      if ((header->image_descriptor & GRUB_TGA_IMAGE_ORIGIN_TOP) != 0)
255
 
        ptr += y * bitmap->mode_info.pitch;
256
 
      else
257
 
        ptr += (header->image_height - 1 - y) * bitmap->mode_info.pitch;
258
 
 
259
 
      for (x = 0; x < header->image_width; x++)
260
 
        {
261
 
          if (grub_file_read (file, &tmp[0], bytes_per_pixel)
262
 
              != bytes_per_pixel)
263
 
            return grub_errno;
264
 
 
265
 
          ptr[0] = tmp[2];
266
 
          ptr[1] = tmp[1];
267
 
          ptr[2] = tmp[0];
268
 
 
269
 
          ptr += 3;
270
 
        }
271
 
    }
272
 
  return GRUB_ERR_NONE;
273
 
}
274
 
 
275
 
static grub_err_t
276
 
tga_load_truecolor_R8G8B8A8 (struct grub_video_bitmap *bitmap,
277
 
                             struct grub_tga_header *header,
278
 
                             grub_file_t file)
279
 
{
280
 
  unsigned int x;
281
 
  unsigned int y;
282
 
  grub_uint8_t *ptr;
283
 
  grub_uint8_t tmp[4]; /* Size should be max_bpp / 8.  */
284
 
  grub_uint8_t bytes_per_pixel;
285
 
 
286
 
  bytes_per_pixel = header->image_bpp / 8;
287
 
 
288
 
  for (y = 0; y < header->image_height; y++)
289
 
    {
290
 
      ptr = bitmap->data;
291
 
      if ((header->image_descriptor & GRUB_TGA_IMAGE_ORIGIN_TOP) != 0)
292
 
        ptr += y * bitmap->mode_info.pitch;
293
 
      else
294
 
        ptr += (header->image_height - 1 - y) * bitmap->mode_info.pitch;
295
 
 
296
 
      for (x = 0; x < header->image_width; x++)
297
 
        {
298
 
          if (grub_file_read (file, &tmp[0], bytes_per_pixel)
299
 
              != bytes_per_pixel)
300
 
            return grub_errno;
301
 
 
302
 
          ptr[0] = tmp[2];
303
 
          ptr[1] = tmp[1];
304
 
          ptr[2] = tmp[0];
305
 
          ptr[3] = tmp[3];
306
 
 
307
 
          ptr += 4;
308
 
        }
309
 
    }
310
 
  return GRUB_ERR_NONE;
311
 
}
312
 
 
313
 
static grub_err_t
314
 
grub_video_reader_tga (struct grub_video_bitmap **bitmap,
315
 
                       const char *filename)
316
 
{
317
 
  grub_file_t file;
318
 
  grub_ssize_t pos;
319
 
  struct grub_tga_header header;
320
 
  int has_alpha;
321
 
 
322
 
  file = grub_buffile_open (filename, 0);
323
 
  if (! file)
324
 
    return grub_errno;
325
 
 
326
 
  /* TGA Specification states that we SHOULD start by reading
327
 
     ID from end of file, but we really don't care about that as we are
328
 
     not going to support developer area & extensions at this point.  */
329
 
 
330
 
  /* Read TGA header from beginning of file.  */
331
 
  if (grub_file_read (file, &header, sizeof (header))
332
 
      != sizeof (header))
333
 
    {
334
 
      grub_file_close (file);
335
 
      return grub_errno;
336
 
    }
337
 
 
338
 
  /* Skip ID field.  */
339
 
  pos = grub_file_tell (file);
340
 
  pos += header.id_length;
341
 
  grub_file_seek (file, pos);
342
 
  if (grub_errno != GRUB_ERR_NONE)
343
 
    {
344
 
      grub_file_close (file);
345
 
      return grub_errno;
346
 
    }
347
 
 
348
 
#if defined(TGA_DEBUG)
349
 
  grub_printf("tga: header\n");
350
 
  dump_int_field(header.id_length);
351
 
  dump_int_field(header.color_map_type);
352
 
  dump_int_field(header.image_type);
353
 
  dump_int_field(header.color_map_first_index);
354
 
  dump_int_field(header.color_map_length);
355
 
  dump_int_field(header.color_map_bpp);
356
 
  dump_int_field(header.image_x_origin);
357
 
  dump_int_field(header.image_y_origin);
358
 
  dump_int_field(header.image_width);
359
 
  dump_int_field(header.image_height);
360
 
  dump_int_field(header.image_bpp);
361
 
  dump_int_field(header.image_descriptor);
362
 
#endif
363
 
 
364
 
  /* Check that bitmap encoding is supported.  */
365
 
  switch (header.image_type)
366
 
    {
367
 
      case GRUB_TGA_IMAGE_TYPE_UNCOMPRESSED_TRUECOLOR:
368
 
      case GRUB_TGA_IMAGE_TYPE_RLE_TRUECOLOR:
369
 
        break;
370
 
 
371
 
      default:
372
 
        grub_file_close (file);
373
 
        return grub_error (GRUB_ERR_BAD_FILE_TYPE,
374
 
                           "unsupported bitmap format (unknown encoding)");
375
 
    }
376
 
 
377
 
  /* Check that bitmap depth is supported.  */
378
 
  switch (header.image_bpp)
379
 
    {
380
 
      case 24:
381
 
        has_alpha = 0;
382
 
        break;
383
 
 
384
 
      case 32:
385
 
        has_alpha = 1;
386
 
        break;
387
 
 
388
 
      default:
389
 
        grub_file_close (file);
390
 
        return grub_error (GRUB_ERR_BAD_FILE_TYPE,
391
 
                           "unsupported bitmap format (bpp=%d)",
392
 
                           header.image_bpp);
393
 
    }
394
 
 
395
 
  /* Allocate bitmap.  If there is alpha information store it too.  */
396
 
  if (has_alpha)
397
 
    {
398
 
      grub_video_bitmap_create (bitmap, header.image_width,
399
 
                                header.image_height,
400
 
                                GRUB_VIDEO_BLIT_FORMAT_RGBA_8888);
401
 
      if (grub_errno != GRUB_ERR_NONE)
402
 
        {
403
 
          grub_file_close (file);
404
 
          return grub_errno;
405
 
        }
406
 
 
407
 
      /* Load bitmap data.  */
408
 
      switch (header.image_type)
409
 
        {
410
 
          case GRUB_TGA_IMAGE_TYPE_UNCOMPRESSED_TRUECOLOR:
411
 
            tga_load_truecolor_R8G8B8A8 (*bitmap, &header, file);
412
 
            break;
413
 
 
414
 
          case GRUB_TGA_IMAGE_TYPE_RLE_TRUECOLOR:
415
 
            tga_load_truecolor_rle_R8G8B8A8 (*bitmap, &header, file);
416
 
            break;
417
 
        }
418
 
    }
419
 
  else
420
 
    {
421
 
      grub_video_bitmap_create (bitmap, header.image_width,
422
 
                                header.image_height,
423
 
                                GRUB_VIDEO_BLIT_FORMAT_RGB_888);
424
 
      if (grub_errno != GRUB_ERR_NONE)
425
 
        {
426
 
          grub_file_close (file);
427
 
          return grub_errno;
428
 
        }
429
 
 
430
 
      /* Load bitmap data.  */
431
 
      switch (header.image_type)
432
 
        {
433
 
          case GRUB_TGA_IMAGE_TYPE_UNCOMPRESSED_TRUECOLOR:
434
 
            tga_load_truecolor_R8G8B8 (*bitmap, &header, file);
435
 
            break;
436
 
 
437
 
          case GRUB_TGA_IMAGE_TYPE_RLE_TRUECOLOR:
438
 
            tga_load_truecolor_rle_R8G8B8 (*bitmap, &header, file);
439
 
            break;
440
 
        }
441
 
    }
442
 
 
443
 
  /* If there was a loading problem, destroy bitmap.  */
444
 
  if (grub_errno != GRUB_ERR_NONE)
445
 
    {
446
 
      grub_video_bitmap_destroy (*bitmap);
447
 
      *bitmap = 0;
448
 
    }
449
 
 
450
 
  grub_file_close (file);
451
 
  return grub_errno;
452
 
}
453
 
 
454
 
#if defined(TGA_DEBUG)
455
 
static grub_err_t
456
 
grub_cmd_tgatest (grub_command_t cmd __attribute__ ((unused)),
457
 
                  int argc, char **args)
458
 
{
459
 
  struct grub_video_bitmap *bitmap = 0;
460
 
 
461
 
  if (argc != 1)
462
 
    return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
463
 
 
464
 
  grub_video_reader_tga (&bitmap, args[0]);
465
 
  if (grub_errno != GRUB_ERR_NONE)
466
 
    return grub_errno;
467
 
 
468
 
  grub_video_bitmap_destroy (bitmap);
469
 
 
470
 
  return GRUB_ERR_NONE;
471
 
}
472
 
#endif
473
 
 
474
 
static struct grub_video_bitmap_reader tga_reader = {
475
 
  .extension = ".tga",
476
 
  .reader = grub_video_reader_tga,
477
 
  .next = 0
478
 
};
479
 
 
480
 
GRUB_MOD_INIT(tga)
481
 
{
482
 
  grub_video_bitmap_reader_register (&tga_reader);
483
 
#if defined(TGA_DEBUG)
484
 
  cmd = grub_register_command ("tgatest", grub_cmd_tgatest,
485
 
                               "FILE", "Tests loading of TGA bitmap.");
486
 
#endif
487
 
}
488
 
 
489
 
GRUB_MOD_FINI(tga)
490
 
{
491
 
#if defined(TGA_DEBUG)
492
 
  grub_unregister_command (cmd);
493
 
#endif
494
 
  grub_video_bitmap_reader_unregister (&tga_reader);
495
 
}