/* * GRUB -- GRand Unified Bootloader * Copyright (C) 2006 Free Software Foundation, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include #include #include #include /* List of bitmap readers registered to system. */ static grub_video_bitmap_reader_t bitmap_readers_list; /* Register bitmap reader. */ void grub_video_bitmap_reader_register (grub_video_bitmap_reader_t reader) { reader->next = bitmap_readers_list; bitmap_readers_list = reader; } /* Unregister bitmap reader. */ void grub_video_bitmap_reader_unregister (grub_video_bitmap_reader_t reader) { grub_video_bitmap_reader_t *p, q; for (p = &bitmap_readers_list, q = *p; q; p = &(q->next), q = q->next) if (q == reader) { *p = q->next; break; } } /* Creates new bitmap, saves created bitmap on success to *bitmap. */ grub_err_t grub_video_bitmap_create (struct grub_video_bitmap **bitmap, unsigned int width, unsigned int height, enum grub_video_blit_format blit_format) { struct grub_video_mode_info *mode_info; unsigned int size; if (!bitmap) return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid argument."); *bitmap = 0; if (width == 0 || height == 0) return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid argument."); *bitmap = (struct grub_video_bitmap *)grub_malloc (sizeof (struct grub_video_bitmap)); if (! *bitmap) return grub_errno; mode_info = &((*bitmap)->mode_info); /* Populate mode_info. */ mode_info->width = width; mode_info->height = height; mode_info->blit_format = blit_format; switch (blit_format) { case GRUB_VIDEO_BLIT_FORMAT_R8G8B8A8: mode_info->mode_type = GRUB_VIDEO_MODE_TYPE_RGB | GRUB_VIDEO_MODE_TYPE_ALPHA; mode_info->bpp = 32; mode_info->bytes_per_pixel = 4; mode_info->number_of_colors = 256; mode_info->red_mask_size = 8; mode_info->red_field_pos = 0; mode_info->green_mask_size = 8; mode_info->green_field_pos = 8; mode_info->blue_mask_size = 8; mode_info->blue_field_pos = 16; mode_info->reserved_mask_size = 8; mode_info->reserved_field_pos = 24; break; case GRUB_VIDEO_BLIT_FORMAT_R8G8B8: mode_info->mode_type = GRUB_VIDEO_MODE_TYPE_RGB; mode_info->bpp = 24; mode_info->bytes_per_pixel = 3; mode_info->number_of_colors = 256; mode_info->red_mask_size = 8; mode_info->red_field_pos = 0; mode_info->green_mask_size = 8; mode_info->green_field_pos = 8; mode_info->blue_mask_size = 8; mode_info->blue_field_pos = 16; mode_info->reserved_mask_size = 0; mode_info->reserved_field_pos = 0; break; case GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR: mode_info->mode_type = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR; mode_info->bpp = 8; mode_info->bytes_per_pixel = 1; mode_info->number_of_colors = 256; mode_info->red_mask_size = 0; mode_info->red_field_pos = 0; mode_info->green_mask_size = 0; mode_info->green_field_pos = 0; mode_info->blue_mask_size = 0; mode_info->blue_field_pos = 0; mode_info->reserved_mask_size = 0; mode_info->reserved_field_pos = 0; break; default: grub_free (*bitmap); *bitmap = 0; return grub_error (GRUB_ERR_BAD_ARGUMENT, "Unsupported bitmap format"); } mode_info->pitch = width * mode_info->bytes_per_pixel; /* Calculate size needed for the data. */ size = (width * mode_info->bytes_per_pixel) * height; (*bitmap)->data = grub_malloc (size); if (! (*bitmap)->data) { grub_free (*bitmap); *bitmap = 0; return grub_errno; } /* Clear bitmap. */ grub_memset ((*bitmap)->data, 0, size); return GRUB_ERR_NONE; } /* Frees all resources allocated by bitmap. */ grub_err_t grub_video_bitmap_destroy (struct grub_video_bitmap *bitmap) { if (! bitmap) return GRUB_ERR_NONE; grub_free (bitmap->data); grub_free (bitmap); return GRUB_ERR_NONE; } /* Match extension to filename. */ static int match_extension (const char *filename, const char *ext) { int pos; int ext_len; pos = grub_strlen (filename); ext_len = grub_strlen (ext); if (! pos || ! ext_len || ext_len > pos) return 0; pos -= ext_len; return grub_strcmp (filename + pos, ext) == 0; } /* Loads bitmap using registered bitmap readers. */ grub_err_t grub_video_bitmap_load (struct grub_video_bitmap **bitmap, const char *filename) { grub_video_bitmap_reader_t reader = bitmap_readers_list; if (!bitmap) return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid argument."); *bitmap = 0; while (reader) { if (match_extension (filename, reader->extension)) return reader->reader (bitmap, filename); reader = reader->next; } return grub_error(GRUB_ERR_BAD_FILE_TYPE, "unsupported bitmap format"); } /* Return bitmap width. */ unsigned int grub_video_bitmap_get_width (struct grub_video_bitmap *bitmap) { if (!bitmap) return 0; return bitmap->mode_info.width; } /* Return bitmap height. */ unsigned int grub_video_bitmap_get_height (struct grub_video_bitmap *bitmap) { if (!bitmap) return 0; return bitmap->mode_info.height; } /* Return mode info for bitmap. */ void grub_video_bitmap_get_mode_info (struct grub_video_bitmap *bitmap, struct grub_video_mode_info *mode_info) { if (!bitmap) return; *mode_info = bitmap->mode_info; } /* Return pointer to bitmap's raw data. */ void *grub_video_bitmap_get_data (struct grub_video_bitmap *bitmap) { if (!bitmap) return 0; return bitmap->data; } /* Initialize bitmap module. */ GRUB_MOD_INIT(video_bitmap) { } /* Finalize bitmap module. */ GRUB_MOD_FINI(video_bitmap) { }