bitmap.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  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. #include <grub/video.h>
  19. #include <grub/bitmap.h>
  20. #include <grub/types.h>
  21. #include <grub/dl.h>
  22. #include <grub/mm.h>
  23. #include <grub/misc.h>
  24. GRUB_EXPORT(grub_video_bitmap_create);
  25. GRUB_EXPORT(grub_video_bitmap_destroy);
  26. GRUB_EXPORT(grub_video_bitmap_get_width);
  27. GRUB_EXPORT(grub_video_bitmap_get_height);
  28. GRUB_EXPORT(grub_video_bitmap_load);
  29. GRUB_EXPORT(grub_video_bitmap_reader_register);
  30. GRUB_EXPORT(grub_video_bitmap_reader_unregister);
  31. GRUB_EXPORT(grub_video_bitmap_get_data);
  32. /* List of bitmap readers registered to system. */
  33. static grub_video_bitmap_reader_t bitmap_readers_list;
  34. /* Register bitmap reader. */
  35. void
  36. grub_video_bitmap_reader_register (grub_video_bitmap_reader_t reader)
  37. {
  38. reader->next = bitmap_readers_list;
  39. bitmap_readers_list = reader;
  40. }
  41. /* Unregister bitmap reader. */
  42. void
  43. grub_video_bitmap_reader_unregister (grub_video_bitmap_reader_t reader)
  44. {
  45. grub_video_bitmap_reader_t *p, q;
  46. for (p = &bitmap_readers_list, q = *p; q; p = &(q->next), q = q->next)
  47. if (q == reader)
  48. {
  49. *p = q->next;
  50. break;
  51. }
  52. }
  53. /* Creates new bitmap, saves created bitmap on success to *bitmap. */
  54. grub_err_t
  55. grub_video_bitmap_create (struct grub_video_bitmap **bitmap,
  56. unsigned int width, unsigned int height,
  57. enum grub_video_blit_format blit_format)
  58. {
  59. struct grub_video_mode_info *mode_info;
  60. unsigned int size;
  61. if (!bitmap)
  62. return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid argument");
  63. *bitmap = 0;
  64. if (width == 0 || height == 0)
  65. return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid argument");
  66. *bitmap = (struct grub_video_bitmap *)grub_malloc (sizeof (struct grub_video_bitmap));
  67. if (! *bitmap)
  68. return grub_errno;
  69. mode_info = &((*bitmap)->mode_info);
  70. /* Populate mode_info. */
  71. mode_info->width = width;
  72. mode_info->height = height;
  73. mode_info->blit_format = blit_format;
  74. switch (blit_format)
  75. {
  76. case GRUB_VIDEO_BLIT_FORMAT_RGBA_8888:
  77. mode_info->mode_type = GRUB_VIDEO_MODE_TYPE_RGB
  78. | GRUB_VIDEO_MODE_TYPE_ALPHA;
  79. mode_info->bpp = 32;
  80. mode_info->bytes_per_pixel = 4;
  81. mode_info->number_of_colors = 256;
  82. mode_info->red_mask_size = 8;
  83. mode_info->red_field_pos = 0;
  84. mode_info->green_mask_size = 8;
  85. mode_info->green_field_pos = 8;
  86. mode_info->blue_mask_size = 8;
  87. mode_info->blue_field_pos = 16;
  88. mode_info->reserved_mask_size = 8;
  89. mode_info->reserved_field_pos = 24;
  90. break;
  91. case GRUB_VIDEO_BLIT_FORMAT_RGB_888:
  92. mode_info->mode_type = GRUB_VIDEO_MODE_TYPE_RGB;
  93. mode_info->bpp = 24;
  94. mode_info->bytes_per_pixel = 3;
  95. mode_info->number_of_colors = 256;
  96. mode_info->red_mask_size = 8;
  97. mode_info->red_field_pos = 0;
  98. mode_info->green_mask_size = 8;
  99. mode_info->green_field_pos = 8;
  100. mode_info->blue_mask_size = 8;
  101. mode_info->blue_field_pos = 16;
  102. mode_info->reserved_mask_size = 0;
  103. mode_info->reserved_field_pos = 0;
  104. break;
  105. case GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR:
  106. mode_info->mode_type = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR;
  107. mode_info->bpp = 8;
  108. mode_info->bytes_per_pixel = 1;
  109. mode_info->number_of_colors = 256;
  110. mode_info->red_mask_size = 0;
  111. mode_info->red_field_pos = 0;
  112. mode_info->green_mask_size = 0;
  113. mode_info->green_field_pos = 0;
  114. mode_info->blue_mask_size = 0;
  115. mode_info->blue_field_pos = 0;
  116. mode_info->reserved_mask_size = 0;
  117. mode_info->reserved_field_pos = 0;
  118. break;
  119. default:
  120. grub_free (*bitmap);
  121. *bitmap = 0;
  122. return grub_error (GRUB_ERR_BAD_ARGUMENT,
  123. "unsupported bitmap format");
  124. }
  125. mode_info->pitch = width * mode_info->bytes_per_pixel;
  126. /* Calculate size needed for the data. */
  127. size = (width * mode_info->bytes_per_pixel) * height;
  128. (*bitmap)->data = grub_zalloc (size);
  129. if (! (*bitmap)->data)
  130. {
  131. grub_free (*bitmap);
  132. *bitmap = 0;
  133. return grub_errno;
  134. }
  135. (*bitmap)->transparent = 0;
  136. return GRUB_ERR_NONE;
  137. }
  138. /* Frees all resources allocated by bitmap. */
  139. grub_err_t
  140. grub_video_bitmap_destroy (struct grub_video_bitmap *bitmap)
  141. {
  142. if (! bitmap)
  143. return GRUB_ERR_NONE;
  144. grub_free (bitmap->data);
  145. grub_free (bitmap);
  146. return GRUB_ERR_NONE;
  147. }
  148. /* Match extension to filename. */
  149. static int
  150. match_extension (const char *filename, const char *ext)
  151. {
  152. int pos;
  153. int ext_len;
  154. pos = grub_strlen (filename);
  155. ext_len = grub_strlen (ext);
  156. if (! pos || ! ext_len || ext_len > pos)
  157. return 0;
  158. pos -= ext_len;
  159. return grub_strcmp (filename + pos, ext) == 0;
  160. }
  161. /* Loads bitmap using registered bitmap readers. */
  162. grub_err_t
  163. grub_video_bitmap_load (struct grub_video_bitmap **bitmap,
  164. const char *filename)
  165. {
  166. grub_video_bitmap_reader_t reader = bitmap_readers_list;
  167. if (!bitmap)
  168. return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid argument");
  169. *bitmap = 0;
  170. while (reader)
  171. {
  172. if (match_extension (filename, reader->extension))
  173. return reader->reader (bitmap, filename);
  174. reader = reader->next;
  175. }
  176. return grub_error(GRUB_ERR_BAD_FILE_TYPE, "unsupported bitmap format");
  177. }
  178. /* Return bitmap width. */
  179. unsigned int
  180. grub_video_bitmap_get_width (struct grub_video_bitmap *bitmap)
  181. {
  182. if (!bitmap)
  183. return 0;
  184. return bitmap->mode_info.width;
  185. }
  186. /* Return bitmap height. */
  187. unsigned int
  188. grub_video_bitmap_get_height (struct grub_video_bitmap *bitmap)
  189. {
  190. if (!bitmap)
  191. return 0;
  192. return bitmap->mode_info.height;
  193. }
  194. /* Return mode info for bitmap. */
  195. void grub_video_bitmap_get_mode_info (struct grub_video_bitmap *bitmap,
  196. struct grub_video_mode_info *mode_info)
  197. {
  198. if (!bitmap)
  199. return;
  200. *mode_info = bitmap->mode_info;
  201. }
  202. /* Return pointer to bitmap's raw data. */
  203. void *grub_video_bitmap_get_data (struct grub_video_bitmap *bitmap)
  204. {
  205. if (!bitmap)
  206. return 0;
  207. return bitmap->data;
  208. }
  209. /* Initialize bitmap module. */
  210. GRUB_MOD_INIT(bitmap)
  211. {
  212. }
  213. /* Finalize bitmap module. */
  214. GRUB_MOD_FINI(bitmap)
  215. {
  216. }