diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 10:54:16 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 10:54:16 +0000 |
commit | 485f6ecd453d8a2fd8b9b9fadea03159d8b50797 (patch) | |
tree | 32451fa3cdd9321fb2591fada9891b2cb70a9cd1 /grub-core/video/bitmap.c | |
parent | Initial commit. (diff) | |
download | grub2-upstream.tar.xz grub2-upstream.zip |
Adding upstream version 2.06.upstream/2.06upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'grub-core/video/bitmap.c')
-rw-r--r-- | grub-core/video/bitmap.c | 238 |
1 files changed, 238 insertions, 0 deletions
diff --git a/grub-core/video/bitmap.c b/grub-core/video/bitmap.c new file mode 100644 index 0000000..6256e20 --- /dev/null +++ b/grub-core/video/bitmap.c @@ -0,0 +1,238 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2006,2007 Free Software Foundation, Inc. + * + * GRUB 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 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <grub/video.h> +#include <grub/bitmap.h> +#include <grub/types.h> +#include <grub/dl.h> +#include <grub/mm.h> +#include <grub/misc.h> +#include <grub/i18n.h> +#include <grub/safemath.h> + +GRUB_MOD_LICENSE ("GPLv3+"); + +/* 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; + grub_size_t size; + + if (!bitmap) + return grub_error (GRUB_ERR_BUG, "invalid argument"); + + *bitmap = 0; + + if (width == 0 || height == 0) + return grub_error (GRUB_ERR_BUG, "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_RGBA_8888: + 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_RGB_888: + 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_NOT_IMPLEMENTED_YET, + "unsupported bitmap format"); + } + + mode_info->pitch = width * mode_info->bytes_per_pixel; + + /* Calculate size needed for the data. */ + if (grub_mul (width, mode_info->bytes_per_pixel, &size) || + grub_mul (size, height, &size)) + { + grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); + goto fail; + } + + (*bitmap)->data = grub_zalloc (size); + if (! (*bitmap)->data) + goto fail; + + return GRUB_ERR_NONE; + + fail: + grub_free (*bitmap); + *bitmap = NULL; + + return grub_errno; +} + +/* 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_strcasecmp (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_BUG, "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, + /* TRANSLATORS: We're speaking about bitmap images like + JPEG or PNG. */ + N_("bitmap file `%s' is of" + " unsupported format"), filename); +} + +/* 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; +} + |