static int add_font (const char *filename) { grub_file_t file = 0; char magic[4]; grub_uint32_t num, i; struct font *font = 0; file = grub_buffile_open (filename, 0); if (! file) goto fail; if (grub_file_read (file, magic, 4) != 4) goto fail; if (grub_memcmp (magic, GRUB_FONT_MAGIC, 4) != 0) { grub_error (GRUB_ERR_BAD_FONT, "invalid font magic"); goto fail; } if (grub_file_read (file, (char *) &num, 4) != 4) goto fail; num = grub_le_to_cpu32 (num); font = (struct font *) grub_malloc (sizeof (struct font) + sizeof (struct entry) * num); if (! font) goto fail; font->file = file; font->num = num; for (i = 0; i < num; i++) { grub_uint32_t code, offset; if (grub_file_read (file, (char *) &code, 4) != 4) goto fail; if (grub_file_read (file, (char *) &offset, 4) != 4) goto fail; font->table[i].code = grub_le_to_cpu32 (code); font->table[i].offset = grub_le_to_cpu32 (offset); } font->next = font_list; font_list = font; return 1; fail: if (font) grub_free (font); if (file) grub_file_close (file); return 0; }
static grub_err_t grub_video_reader_tga (struct grub_video_bitmap **bitmap, const char *filename) { grub_file_t file; grub_ssize_t pos; struct grub_tga_header header; int has_alpha; file = grub_buffile_open (filename, 0); if (! file) return grub_errno; /* TGA Specification states that we SHOULD start by reading ID from end of file, but we really don't care about that as we are not going to support developer area & extensions at this point. */ /* Read TGA header from beginning of file. */ if (grub_file_read (file, &header, sizeof (header)) != sizeof (header)) { grub_file_close (file); return grub_errno; } /* Skip ID field. */ pos = grub_file_tell (file); pos += header.id_length; grub_file_seek (file, pos); if (grub_errno != GRUB_ERR_NONE) { grub_file_close (file); return grub_errno; } #if defined(TGA_DEBUG) grub_printf("tga: header\n"); dump_int_field(header.id_length); dump_int_field(header.color_map_type); dump_int_field(header.image_type); dump_int_field(header.color_map_first_index); dump_int_field(header.color_map_length); dump_int_field(header.color_map_bpp); dump_int_field(header.image_x_origin); dump_int_field(header.image_y_origin); dump_int_field(header.image_width); dump_int_field(header.image_height); dump_int_field(header.image_bpp); dump_int_field(header.image_descriptor); #endif /* Check that bitmap encoding is supported. */ switch (header.image_type) { case GRUB_TGA_IMAGE_TYPE_UNCOMPRESSED_TRUECOLOR: case GRUB_TGA_IMAGE_TYPE_RLE_TRUECOLOR: break; default: grub_file_close (file); return grub_error (GRUB_ERR_BAD_FILE_TYPE, "unsupported bitmap format (unknown encoding)"); } /* Check that bitmap depth is supported. */ switch (header.image_bpp) { case 24: has_alpha = 0; break; case 32: has_alpha = 1; break; default: grub_file_close (file); return grub_error (GRUB_ERR_BAD_FILE_TYPE, "unsupported bitmap format (bpp=%d)", header.image_bpp); } /* Allocate bitmap. If there is alpha information store it too. */ if (has_alpha) { grub_video_bitmap_create (bitmap, header.image_width, header.image_height, GRUB_VIDEO_BLIT_FORMAT_RGBA_8888); if (grub_errno != GRUB_ERR_NONE) { grub_file_close (file); return grub_errno; } /* Load bitmap data. */ switch (header.image_type) { case GRUB_TGA_IMAGE_TYPE_UNCOMPRESSED_TRUECOLOR: tga_load_truecolor_R8G8B8A8 (*bitmap, &header, file); break; case GRUB_TGA_IMAGE_TYPE_RLE_TRUECOLOR: tga_load_truecolor_rle_R8G8B8A8 (*bitmap, &header, file); break; } } else { grub_video_bitmap_create (bitmap, header.image_width, header.image_height, GRUB_VIDEO_BLIT_FORMAT_RGB_888); if (grub_errno != GRUB_ERR_NONE) { grub_file_close (file); return grub_errno; } /* Load bitmap data. */ switch (header.image_type) { case GRUB_TGA_IMAGE_TYPE_UNCOMPRESSED_TRUECOLOR: tga_load_truecolor_R8G8B8 (*bitmap, &header, file); break; case GRUB_TGA_IMAGE_TYPE_RLE_TRUECOLOR: tga_load_truecolor_rle_R8G8B8 (*bitmap, &header, file); break; } } /* If there was a loading problem, destroy bitmap. */ if (grub_errno != GRUB_ERR_NONE) { grub_video_bitmap_destroy (*bitmap); *bitmap = 0; } grub_file_close (file); return grub_errno; }
/* Load a font and add it to the beginning of the global font list. Returns 0 upon success, nonzero upon failure. */ grub_font_t grub_font_load (const char *filename) { grub_file_t file = 0; struct font_file_section section; char magic[4]; grub_font_t font = 0; #if FONT_DEBUG >= 1 grub_dprintf ("font", "add_font(%s)\n", filename); #endif if (filename[0] == '(' || filename[0] == '/' || filename[0] == '+') file = grub_buffile_open (filename, 1024); else { const char *prefix = grub_env_get ("prefix"); char *fullname, *ptr; if (!prefix) { grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("variable `%s' isn't set"), "prefix"); goto fail; } fullname = grub_malloc (grub_strlen (prefix) + grub_strlen (filename) + 1 + sizeof ("/fonts/") + sizeof (".pf2")); if (!fullname) goto fail; ptr = grub_stpcpy (fullname, prefix); ptr = grub_stpcpy (ptr, "/fonts/"); ptr = grub_stpcpy (ptr, filename); ptr = grub_stpcpy (ptr, ".pf2"); *ptr = 0; file = grub_buffile_open (fullname, 1024); grub_free (fullname); } if (!file) goto fail; #if FONT_DEBUG >= 3 grub_dprintf ("font", "file opened\n"); #endif /* Read the FILE section. It indicates the file format. */ if (open_section (file, §ion) != 0) goto fail; #if FONT_DEBUG >= 3 grub_dprintf ("font", "opened FILE section\n"); #endif if (grub_memcmp (section.name, FONT_FORMAT_SECTION_NAMES_FILE, sizeof (FONT_FORMAT_SECTION_NAMES_FILE) - 1) != 0) { grub_error (GRUB_ERR_BAD_FONT, "font file format error: 1st section must be FILE"); goto fail; } #if FONT_DEBUG >= 3 grub_dprintf ("font", "section name ok\n"); #endif if (section.length != 4) { grub_error (GRUB_ERR_BAD_FONT, "font file format error (file type ID length is %d " "but should be 4)", section.length); goto fail; } #if FONT_DEBUG >= 3 grub_dprintf ("font", "section length ok\n"); #endif /* Check the file format type code. */ if (grub_file_read (file, magic, 4) != 4) goto fail; #if FONT_DEBUG >= 3 grub_dprintf ("font", "read magic ok\n"); #endif if (grub_memcmp (magic, FONT_FORMAT_PFF2_MAGIC, 4) != 0) { grub_error (GRUB_ERR_BAD_FONT, "invalid font magic %x %x %x %x", magic[0], magic[1], magic[2], magic[3]); goto fail; } #if FONT_DEBUG >= 3 grub_dprintf ("font", "compare magic ok\n"); #endif /* Allocate the font object. */ font = (grub_font_t) grub_zalloc (sizeof (struct grub_font)); if (!font) goto fail; font_init (font); font->file = file; #if FONT_DEBUG >= 3 grub_dprintf ("font", "allocate font ok; loading font info\n"); #endif /* Load the font information. */ while (1) { if (open_section (file, §ion) != 0) { if (section.eof) break; /* Done reading the font file. */ else goto fail; } #if FONT_DEBUG >= 2 grub_dprintf ("font", "opened section %c%c%c%c ok\n", section.name[0], section.name[1], section.name[2], section.name[3]); #endif if (grub_memcmp (section.name, FONT_FORMAT_SECTION_NAMES_FONT_NAME, sizeof (FONT_FORMAT_SECTION_NAMES_FONT_NAME) - 1) == 0) { font->name = read_section_as_string (§ion); if (!font->name) goto fail; } else if (grub_memcmp (section.name, FONT_FORMAT_SECTION_NAMES_POINT_SIZE, sizeof (FONT_FORMAT_SECTION_NAMES_POINT_SIZE) - 1) == 0) { if (read_section_as_short (§ion, &font->point_size) != 0) goto fail; } else if (grub_memcmp (section.name, FONT_FORMAT_SECTION_NAMES_WEIGHT, sizeof (FONT_FORMAT_SECTION_NAMES_WEIGHT) - 1) == 0) { char *wt; wt = read_section_as_string (§ion); if (!wt) continue; /* Convert the weight string 'normal' or 'bold' into a number. */ if (grub_strcmp (wt, "normal") == 0) font->weight = FONT_WEIGHT_NORMAL; else if (grub_strcmp (wt, "bold") == 0) font->weight = FONT_WEIGHT_BOLD; grub_free (wt); } else if (grub_memcmp (section.name, FONT_FORMAT_SECTION_NAMES_MAX_CHAR_WIDTH, sizeof (FONT_FORMAT_SECTION_NAMES_MAX_CHAR_WIDTH) - 1) == 0) { if (read_section_as_short (§ion, &font->max_char_width) != 0) goto fail; } else if (grub_memcmp (section.name, FONT_FORMAT_SECTION_NAMES_MAX_CHAR_HEIGHT, sizeof (FONT_FORMAT_SECTION_NAMES_MAX_CHAR_HEIGHT) - 1) == 0) { if (read_section_as_short (§ion, &font->max_char_height) != 0) goto fail; } else if (grub_memcmp (section.name, FONT_FORMAT_SECTION_NAMES_ASCENT, sizeof (FONT_FORMAT_SECTION_NAMES_ASCENT) - 1) == 0) { if (read_section_as_short (§ion, &font->ascent) != 0) goto fail; } else if (grub_memcmp (section.name, FONT_FORMAT_SECTION_NAMES_DESCENT, sizeof (FONT_FORMAT_SECTION_NAMES_DESCENT) - 1) == 0) { if (read_section_as_short (§ion, &font->descent) != 0) goto fail; } else if (grub_memcmp (section.name, FONT_FORMAT_SECTION_NAMES_CHAR_INDEX, sizeof (FONT_FORMAT_SECTION_NAMES_CHAR_INDEX) - 1) == 0) { if (load_font_index (file, section.length, font) != 0) goto fail; } else if (grub_memcmp (section.name, FONT_FORMAT_SECTION_NAMES_DATA, sizeof (FONT_FORMAT_SECTION_NAMES_DATA) - 1) == 0) { /* When the DATA section marker is reached, we stop reading. */ break; } else { /* Unhandled section type, simply skip past it. */ #if FONT_DEBUG >= 3 grub_dprintf ("font", "Unhandled section type, skipping.\n"); #endif grub_off_t section_end = grub_file_tell (file) + section.length; if ((int) grub_file_seek (file, section_end) == -1) goto fail; } } if (!font->name) { grub_dprintf ("font", "Font has no name.\n"); font->name = grub_strdup ("Unknown"); } #if FONT_DEBUG >= 1 grub_dprintf ("font", "Loaded font `%s'.\n" "Ascent=%d Descent=%d MaxW=%d MaxH=%d Number of characters=%d.\n", font->name, font->ascent, font->descent, font->max_char_width, font->max_char_height, font->num_chars); #endif if (font->max_char_width == 0 || font->max_char_height == 0 || font->num_chars == 0 || font->char_index == 0 || font->ascent == 0 || font->descent == 0) { grub_error (GRUB_ERR_BAD_FONT, "invalid font file: missing some required data"); goto fail; } /* Add the font to the global font registry. */ if (register_font (font) != 0) goto fail; return font; fail: if (file) grub_file_close (file); if (font) font->file = 0; free_font (font); return 0; }
static grub_err_t grub_video_reader_tga (struct grub_video_bitmap **bitmap, const char *filename) { grub_ssize_t pos; struct tga_data data; grub_memset (&data, 0, sizeof (data)); data.file = grub_buffile_open (filename, 0); if (! data.file) return grub_errno; /* TGA Specification states that we SHOULD start by reading ID from end of file, but we really don't care about that as we are not going to support developer area & extensions at this point. */ /* Read TGA header from beginning of file. */ if (grub_file_read (data.file, &data.hdr, sizeof (data.hdr)) != sizeof (data.hdr)) { grub_file_close (data.file); return grub_errno; } /* Skip ID field. */ pos = grub_file_tell (data.file); pos += data.hdr.id_length; grub_file_seek (data.file, pos); if (grub_errno != GRUB_ERR_NONE) { grub_file_close (data.file); return grub_errno; } grub_dprintf("tga", "tga: header\n"); dump_int_field(data.hdr.id_length); dump_int_field(data.hdr.color_map_type); dump_int_field(data.hdr.image_type); dump_int_field(data.hdr.color_map_first_index); dump_int_field(data.hdr.color_map_length); dump_int_field(data.hdr.color_map_bpp); dump_int_field(data.hdr.image_x_origin); dump_int_field(data.hdr.image_y_origin); dump_int_field(data.hdr.image_width); dump_int_field(data.hdr.image_height); dump_int_field(data.hdr.image_bpp); dump_int_field(data.hdr.image_descriptor); data.image_width = grub_le_to_cpu16 (data.hdr.image_width); data.image_height = grub_le_to_cpu16 (data.hdr.image_height); /* Check that bitmap encoding is supported. */ switch (data.hdr.image_type) { case GRUB_TGA_IMAGE_TYPE_RLE_TRUECOLOR: case GRUB_TGA_IMAGE_TYPE_RLE_BLACK_AND_WHITE: case GRUB_TGA_IMAGE_TYPE_RLE_INDEXCOLOR: data.uses_rle = 1; break; case GRUB_TGA_IMAGE_TYPE_UNCOMPRESSED_TRUECOLOR: case GRUB_TGA_IMAGE_TYPE_UNCOMPRESSED_BLACK_AND_WHITE: case GRUB_TGA_IMAGE_TYPE_UNCOMPRESSED_INDEXCOLOR: data.uses_rle = 0; break; default: grub_file_close (data.file); return grub_error (GRUB_ERR_BAD_FILE_TYPE, "unsupported bitmap format (unknown encoding %d)", data.hdr.image_type); } data.bpp = data.hdr.image_bpp / 8; /* Check that bitmap depth is supported. */ switch (data.hdr.image_type) { case GRUB_TGA_IMAGE_TYPE_RLE_BLACK_AND_WHITE: case GRUB_TGA_IMAGE_TYPE_UNCOMPRESSED_BLACK_AND_WHITE: if (data.hdr.image_bpp != 8) { grub_file_close (data.file); return grub_error (GRUB_ERR_BAD_FILE_TYPE, "unsupported bitmap format (bpp=%d)", data.hdr.image_bpp); } grub_video_bitmap_create (bitmap, data.image_width, data.image_height, GRUB_VIDEO_BLIT_FORMAT_RGB_888); if (grub_errno != GRUB_ERR_NONE) { grub_file_close (data.file); return grub_errno; } data.bitmap = *bitmap; /* Load bitmap data. */ tga_load_grayscale (&data); break; case GRUB_TGA_IMAGE_TYPE_RLE_INDEXCOLOR: case GRUB_TGA_IMAGE_TYPE_UNCOMPRESSED_INDEXCOLOR: if (data.hdr.image_bpp != 8 || data.hdr.color_map_bpp != 24 || data.hdr.color_map_first_index != 0) { grub_file_close (data.file); return grub_error (GRUB_ERR_BAD_FILE_TYPE, "unsupported bitmap format (bpp=%d)", data.hdr.image_bpp); } grub_video_bitmap_create (bitmap, data.image_width, data.image_height, GRUB_VIDEO_BLIT_FORMAT_RGB_888); if (grub_errno != GRUB_ERR_NONE) { grub_file_close (data.file); return grub_errno; } data.bitmap = *bitmap; /* Load bitmap data. */ tga_load_palette (&data); tga_load_index_color (&data); break; case GRUB_TGA_IMAGE_TYPE_RLE_TRUECOLOR: case GRUB_TGA_IMAGE_TYPE_UNCOMPRESSED_TRUECOLOR: switch (data.hdr.image_bpp) { case 24: grub_video_bitmap_create (bitmap, data.image_width, data.image_height, GRUB_VIDEO_BLIT_FORMAT_RGB_888); if (grub_errno != GRUB_ERR_NONE) { grub_file_close (data.file); return grub_errno; } data.bitmap = *bitmap; /* Load bitmap data. */ tga_load_truecolor_R8G8B8 (&data); break; case 32: grub_video_bitmap_create (bitmap, data.image_width, data.image_height, GRUB_VIDEO_BLIT_FORMAT_RGBA_8888); if (grub_errno != GRUB_ERR_NONE) { grub_file_close (data.file); return grub_errno; } data.bitmap = *bitmap; /* Load bitmap data. */ tga_load_truecolor_R8G8B8A8 (&data); break; default: grub_file_close (data.file); return grub_error (GRUB_ERR_BAD_FILE_TYPE, "unsupported bitmap format (bpp=%d)", data.hdr.image_bpp); } } /* If there was a loading problem, destroy bitmap. */ if (grub_errno != GRUB_ERR_NONE) { grub_video_bitmap_destroy (*bitmap); *bitmap = 0; } grub_file_close (data.file); return grub_errno; }