2N/A/*
2N/A * GRUB -- GRand Unified Bootloader
2N/A * Copyright (C) 2006,2007 Free Software Foundation, Inc.
2N/A *
2N/A * GRUB is free software: you can redistribute it and/or modify
2N/A * it under the terms of the GNU General Public License as published by
2N/A * the Free Software Foundation, either version 3 of the License, or
2N/A * (at your option) any later version.
2N/A *
2N/A * GRUB is distributed in the hope that it will be useful,
2N/A * but WITHOUT ANY WARRANTY; without even the implied warranty of
2N/A * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2N/A * GNU General Public License for more details.
2N/A *
2N/A * You should have received a copy of the GNU General Public License
2N/A * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
2N/A */
2N/A
2N/A#include <grub/video.h>
2N/A#include <grub/bitmap.h>
2N/A#include <grub/types.h>
2N/A#include <grub/dl.h>
2N/A#include <grub/mm.h>
2N/A#include <grub/misc.h>
2N/A
2N/AGRUB_MOD_LICENSE ("GPLv3+");
2N/A
2N/A/* List of bitmap readers registered to system. */
2N/Astatic grub_video_bitmap_reader_t bitmap_readers_list;
2N/A
2N/A/* Register bitmap reader. */
2N/Avoid
2N/Agrub_video_bitmap_reader_register (grub_video_bitmap_reader_t reader)
2N/A{
2N/A reader->next = bitmap_readers_list;
2N/A bitmap_readers_list = reader;
2N/A}
2N/A
2N/A/* Unregister bitmap reader. */
2N/Avoid
2N/Agrub_video_bitmap_reader_unregister (grub_video_bitmap_reader_t reader)
2N/A{
2N/A grub_video_bitmap_reader_t *p, q;
2N/A
2N/A for (p = &bitmap_readers_list, q = *p; q; p = &(q->next), q = q->next)
2N/A if (q == reader)
2N/A {
2N/A *p = q->next;
2N/A break;
2N/A }
2N/A}
2N/A
2N/A/* Creates new bitmap, saves created bitmap on success to *bitmap. */
2N/Agrub_err_t
2N/Agrub_video_bitmap_create (struct grub_video_bitmap **bitmap,
2N/A unsigned int width, unsigned int height,
2N/A enum grub_video_blit_format blit_format)
2N/A{
2N/A struct grub_video_mode_info *mode_info;
2N/A unsigned int size;
2N/A
2N/A if (!bitmap)
2N/A return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid argument");
2N/A
2N/A *bitmap = 0;
2N/A
2N/A if (width == 0 || height == 0)
2N/A return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid argument");
2N/A
2N/A *bitmap = (struct grub_video_bitmap *)grub_malloc (sizeof (struct grub_video_bitmap));
2N/A if (! *bitmap)
2N/A return grub_errno;
2N/A
2N/A mode_info = &((*bitmap)->mode_info);
2N/A
2N/A /* Populate mode_info. */
2N/A mode_info->width = width;
2N/A mode_info->height = height;
2N/A mode_info->blit_format = blit_format;
2N/A
2N/A switch (blit_format)
2N/A {
2N/A case GRUB_VIDEO_BLIT_FORMAT_RGBA_8888:
2N/A mode_info->mode_type = GRUB_VIDEO_MODE_TYPE_RGB
2N/A | GRUB_VIDEO_MODE_TYPE_ALPHA;
2N/A mode_info->bpp = 32;
2N/A mode_info->bytes_per_pixel = 4;
2N/A mode_info->number_of_colors = 256;
2N/A mode_info->red_mask_size = 8;
2N/A mode_info->red_field_pos = 0;
2N/A mode_info->green_mask_size = 8;
2N/A mode_info->green_field_pos = 8;
2N/A mode_info->blue_mask_size = 8;
2N/A mode_info->blue_field_pos = 16;
2N/A mode_info->reserved_mask_size = 8;
2N/A mode_info->reserved_field_pos = 24;
2N/A break;
2N/A
2N/A case GRUB_VIDEO_BLIT_FORMAT_RGB_888:
2N/A mode_info->mode_type = GRUB_VIDEO_MODE_TYPE_RGB;
2N/A mode_info->bpp = 24;
2N/A mode_info->bytes_per_pixel = 3;
2N/A mode_info->number_of_colors = 256;
2N/A mode_info->red_mask_size = 8;
2N/A mode_info->red_field_pos = 0;
2N/A mode_info->green_mask_size = 8;
2N/A mode_info->green_field_pos = 8;
2N/A mode_info->blue_mask_size = 8;
2N/A mode_info->blue_field_pos = 16;
2N/A mode_info->reserved_mask_size = 0;
2N/A mode_info->reserved_field_pos = 0;
2N/A break;
2N/A
2N/A case GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR:
2N/A mode_info->mode_type = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR;
2N/A mode_info->bpp = 8;
2N/A mode_info->bytes_per_pixel = 1;
2N/A mode_info->number_of_colors = 256;
2N/A mode_info->red_mask_size = 0;
2N/A mode_info->red_field_pos = 0;
2N/A mode_info->green_mask_size = 0;
2N/A mode_info->green_field_pos = 0;
2N/A mode_info->blue_mask_size = 0;
2N/A mode_info->blue_field_pos = 0;
2N/A mode_info->reserved_mask_size = 0;
2N/A mode_info->reserved_field_pos = 0;
2N/A break;
2N/A
2N/A default:
2N/A grub_free (*bitmap);
2N/A *bitmap = 0;
2N/A
2N/A return grub_error (GRUB_ERR_BAD_ARGUMENT,
2N/A "unsupported bitmap format");
2N/A }
2N/A
2N/A mode_info->pitch = width * mode_info->bytes_per_pixel;
2N/A
2N/A /* Calculate size needed for the data. */
2N/A size = (width * mode_info->bytes_per_pixel) * height;
2N/A
2N/A (*bitmap)->data = grub_zalloc (size);
2N/A if (! (*bitmap)->data)
2N/A {
2N/A grub_free (*bitmap);
2N/A *bitmap = 0;
2N/A
2N/A return grub_errno;
2N/A }
2N/A
2N/A return GRUB_ERR_NONE;
2N/A}
2N/A
2N/A/* Frees all resources allocated by bitmap. */
2N/Agrub_err_t
2N/Agrub_video_bitmap_destroy (struct grub_video_bitmap *bitmap)
2N/A{
2N/A if (! bitmap)
2N/A return GRUB_ERR_NONE;
2N/A
2N/A grub_free (bitmap->data);
2N/A grub_free (bitmap);
2N/A
2N/A return GRUB_ERR_NONE;
2N/A}
2N/A
2N/A/* Match extension to filename. */
2N/Astatic int
2N/Amatch_extension (const char *filename, const char *ext)
2N/A{
2N/A int pos;
2N/A int ext_len;
2N/A
2N/A pos = grub_strlen (filename);
2N/A ext_len = grub_strlen (ext);
2N/A
2N/A if (! pos || ! ext_len || ext_len > pos)
2N/A return 0;
2N/A
2N/A pos -= ext_len;
2N/A
2N/A return grub_strcasecmp (filename + pos, ext) == 0;
2N/A}
2N/A
2N/A/* Loads bitmap using registered bitmap readers. */
2N/Agrub_err_t
2N/Agrub_video_bitmap_load (struct grub_video_bitmap **bitmap,
2N/A const char *filename)
2N/A{
2N/A grub_video_bitmap_reader_t reader = bitmap_readers_list;
2N/A
2N/A if (!bitmap)
2N/A return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid argument");
2N/A
2N/A *bitmap = 0;
2N/A
2N/A while (reader)
2N/A {
2N/A if (match_extension (filename, reader->extension))
2N/A return reader->reader (bitmap, filename);
2N/A
2N/A reader = reader->next;
2N/A }
2N/A
2N/A return grub_error(GRUB_ERR_BAD_FILE_TYPE, "unsupported bitmap format");
2N/A}
2N/A
2N/A/* Return bitmap width. */
2N/Aunsigned int
2N/Agrub_video_bitmap_get_width (struct grub_video_bitmap *bitmap)
2N/A{
2N/A if (!bitmap)
2N/A return 0;
2N/A
2N/A return bitmap->mode_info.width;
2N/A}
2N/A
2N/A/* Return bitmap height. */
2N/Aunsigned int
2N/Agrub_video_bitmap_get_height (struct grub_video_bitmap *bitmap)
2N/A{
2N/A if (!bitmap)
2N/A return 0;
2N/A
2N/A return bitmap->mode_info.height;
2N/A}
2N/A
2N/A/* Return mode info for bitmap. */
2N/Avoid grub_video_bitmap_get_mode_info (struct grub_video_bitmap *bitmap,
2N/A struct grub_video_mode_info *mode_info)
2N/A{
2N/A if (!bitmap)
2N/A return;
2N/A
2N/A *mode_info = bitmap->mode_info;
2N/A}
2N/A
2N/A/* Return pointer to bitmap's raw data. */
2N/Avoid *grub_video_bitmap_get_data (struct grub_video_bitmap *bitmap)
2N/A{
2N/A if (!bitmap)
2N/A return 0;
2N/A
2N/A return bitmap->data;
2N/A}
2N/A
2N/A/* Initialize bitmap module. */
2N/AGRUB_MOD_INIT(bitmap)
2N/A{
2N/A}
2N/A
2N/A/* Finalize bitmap module. */
2N/AGRUB_MOD_FINI(bitmap)
2N/A{
2N/A}