예제 #1
0
파일: gui_image.c 프로젝트: JoliOS/grub2
static void
image_destroy (void *vself)
{
    grub_gui_image_t self = vself;

    /* Free the scaled bitmap, unless it's a reference to the raw bitmap.  */
    if (self->bitmap && (self->bitmap != self->raw_bitmap))
        grub_video_bitmap_destroy (self->bitmap);
    if (self->raw_bitmap)
        grub_video_bitmap_destroy (self->raw_bitmap);

    grub_free (self);
}
예제 #2
0
파일: icon_manager.c 프로젝트: Arvian/GRUB2
/* Get the icon for the specified class CLASS_NAME.  If an icon for
   CLASS_NAME already exists in the cache, then a reference to the cached
   bitmap is returned.  If it is not cached, then it is loaded and cached.
   If no icon could be could for CLASS_NAME, then 0 is returned.  */
static struct grub_video_bitmap *
get_icon_by_class (grub_gfxmenu_icon_manager_t mgr, const char *class_name)
{
  /* First check the icon cache.  */
  icon_entry_t entry;
  for (entry = mgr->cache.next; entry; entry = entry->next)
    {
      if (grub_strcmp (entry->class_name, class_name) == 0)
        return entry->bitmap;
    }

  if (! mgr->theme_path)
    return 0;

  /* Otherwise, we search for an icon to load.  */
  char *theme_dir = grub_get_dirname (mgr->theme_path);
  char *icons_dir;
  struct grub_video_bitmap *icon;
  icon = 0;
  /* First try the theme's own icons, from "grub/themes/NAME/icons/"  */
  icons_dir = grub_resolve_relative_path (theme_dir, "icons/");
  if (icons_dir)
    {
      icon = try_loading_icon (mgr, icons_dir, class_name);
      grub_free (icons_dir);
    }

  grub_free (theme_dir);
  if (! icon)
    {
      const char *icondir;

      icondir = grub_env_get ("icondir");
      if (icondir)
	icon = try_loading_icon (mgr, icondir, class_name);
    }

  /* No icon was found.  */
  /* This should probably be noted in the cache, so that a search is not
     performed each time an icon for CLASS_NAME is requested.  */
  if (! icon)
    return 0;

  /* Insert a new cache entry for this icon.  */
  entry = grub_malloc (sizeof (*entry));
  if (! entry)
    {
      grub_video_bitmap_destroy (icon);
      return 0;
    }
  entry->class_name = grub_strdup (class_name);
  entry->bitmap = icon;
  entry->next = mgr->cache.next;
  mgr->cache.next = entry;   /* Link it into the cache.  */
  return entry->bitmap;
}
예제 #3
0
static void
destroy (grub_gfxmenu_box_t self)
{
  unsigned i;
  for (i = 0; i < BOX_NUM_PIXMAPS; i++)
    {
      if (self->raw_pixmaps[i])
        grub_video_bitmap_destroy(self->raw_pixmaps[i]);
      self->raw_pixmaps[i] = 0;

      if (self->scaled_pixmaps[i])
        grub_video_bitmap_destroy(self->scaled_pixmaps[i]);
      self->scaled_pixmaps[i] = 0;
    }
  grub_free (self->raw_pixmaps);
  self->raw_pixmaps = 0;
  grub_free (self->scaled_pixmaps);
  self->scaled_pixmaps = 0;

  /* Free self:  must be the last step!  */
  grub_free (self);
}
예제 #4
0
파일: icon_manager.c 프로젝트: Arvian/GRUB2
/* Clear the icon cache.  */
void
grub_gfxmenu_icon_manager_clear_cache (grub_gfxmenu_icon_manager_t mgr)
{
  icon_entry_t cur;
  icon_entry_t next;
  for (cur = mgr->cache.next; cur; cur = next)
    {
      next = cur->next;
      grub_free (cur->class_name);
      grub_video_bitmap_destroy (cur->bitmap);
      grub_free (cur);
    }
  mgr->cache.next = 0;
}
예제 #5
0
파일: tga.c 프로젝트: Firef0x/burg-new
static grub_err_t
grub_cmd_tgatest (grub_command_t cmd __attribute__ ((unused)),
                  int argc, char **args)
{
  struct grub_video_bitmap *bitmap = 0;

  if (argc != 1)
    return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");

  grub_video_reader_tga (&bitmap, args[0]);
  if (grub_errno != GRUB_ERR_NONE)
    return grub_errno;

  grub_video_bitmap_destroy (bitmap);

  return GRUB_ERR_NONE;
}
예제 #6
0
/* This function creates a new scaled version of the bitmap SRC.  The new
   bitmap has dimensions DST_WIDTH by DST_HEIGHT.  The scaling algorithm
   is given by SCALE_METHOD.  If an error is encountered, the return code is
   not equal to GRUB_ERR_NONE, and the bitmap DST is either not created, or
   it is destroyed before this function returns.

   Supports only direct color modes which have components separated
   into bytes (e.g., RGBA 8:8:8:8 or BGR 8:8:8 true color).
   But because of this simplifying assumption, the implementation is
   greatly simplified.  */
static grub_err_t
grub_video_bitmap_create_scaled_internal (struct grub_video_bitmap **dst,
        int dst_width, int dst_height,
        struct grub_video_bitmap *src,
        int scale_method)
{
    /* Create the new bitmap. */
    grub_err_t ret;
    ret = grub_video_bitmap_create (dst, dst_width, dst_height,
                                    src->mode_info.blit_format);
    if (ret != GRUB_ERR_NONE)
        return ret;                 /* Error. */

    (*dst)->transparent = src->transparent;

    switch (scale_method)
    {
    case GRUB_VIDEO_BITMAP_SCALE_METHOD_FASTEST:
    case GRUB_VIDEO_BITMAP_SCALE_METHOD_NEAREST:
        ret = scale_nn (*dst, src);
        break;
    case GRUB_VIDEO_BITMAP_SCALE_METHOD_BEST:
    case GRUB_VIDEO_BITMAP_SCALE_METHOD_BILINEAR:
        ret = scale_bilinear (*dst, src);
        break;
    default:
        ret = grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid scale method value");
        break;
    }

    if (ret == GRUB_ERR_NONE)
    {
        /* Success:  *dst is now a pointer to the scaled bitmap. */
        return GRUB_ERR_NONE;
    }
    else
    {
        /* Destroy the bitmap and return the error code. */
        grub_video_bitmap_destroy (*dst);
        *dst = 0;
        return ret;
    }
}
예제 #7
0
파일: icon_manager.c 프로젝트: Arvian/GRUB2
/* Try to load an icon for the specified CLASS_NAME in the directory DIR.
   Returns 0 if the icon could not be loaded, or returns a pointer to a new
   bitmap if it was successful.  */
static struct grub_video_bitmap *
try_loading_icon (grub_gfxmenu_icon_manager_t mgr,
                  const char *dir, const char *class_name)
{
  char *path;
  int l;

  path = grub_malloc (grub_strlen (dir) + grub_strlen (class_name)
		      + grub_strlen (icon_extension) + 3);
  if (! path)
    return 0;

  grub_strcpy (path, dir);
  l = grub_strlen (path);
  if (path[l-1] != '/')
    {
      path[l] = '/';
      path[l+1] = 0;
    }
  grub_strcat (path, class_name);
  grub_strcat (path, icon_extension);

  struct grub_video_bitmap *raw_bitmap;
  grub_video_bitmap_load (&raw_bitmap, path);
  grub_free (path);
  grub_errno = GRUB_ERR_NONE;  /* Critical to clear the error!!  */
  if (! raw_bitmap)
    return 0;

  struct grub_video_bitmap *scaled_bitmap;
  grub_video_bitmap_create_scaled (&scaled_bitmap,
                                   mgr->icon_width, mgr->icon_height,
                                   raw_bitmap,
                                   GRUB_VIDEO_BITMAP_SCALE_METHOD_BEST);
  grub_video_bitmap_destroy (raw_bitmap);
  if (! scaled_bitmap)
    return 0;

  return scaled_bitmap;
}
예제 #8
0
static grub_err_t
scale_pixmap (grub_gfxmenu_box_t self, int i, int w, int h)
{
  struct grub_video_bitmap **scaled = &self->scaled_pixmaps[i];
  struct grub_video_bitmap *raw = self->raw_pixmaps[i];

  if (raw == 0)
    return grub_errno;

  if (w == -1)
    w = grub_video_bitmap_get_width (raw);
  if (h == -1)
    h = grub_video_bitmap_get_height (raw);

  if (*scaled == 0
      || ((int) grub_video_bitmap_get_width (*scaled) != w)
      || ((int) grub_video_bitmap_get_height (*scaled) != h))
    {
      if (*scaled)
        {
          grub_video_bitmap_destroy (*scaled);
          *scaled = 0;
        }

      /* Don't try to create a bitmap with a zero dimension.  */
      if (w != 0 && h != 0)
        grub_video_bitmap_create_scaled (scaled, w, h, raw,
                                         GRUB_VIDEO_BITMAP_SCALE_METHOD_BEST);
      if (grub_errno != GRUB_ERR_NONE)
        {
          grub_error_push ();
          grub_error (grub_errno,
                      "failed to scale bitmap for styled box pixmap #%d", i);
        }
    }

  return grub_errno;
}
예제 #9
0
/* This function creates a new scaled version of the bitmap SRC.  The new
   bitmap has dimensions DST_WIDTH by DST_HEIGHT.  The scaling algorithm
   is given by SCALE_METHOD.  If an error is encountered, the return code is
   not equal to GRUB_ERR_NONE, and the bitmap DST is either not created, or
   it is destroyed before this function returns.

   Supports only direct color modes which have components separated
   into bytes (e.g., RGBA 8:8:8:8 or BGR 8:8:8 true color).
   But because of this simplifying assumption, the implementation is
   greatly simplified.  */
grub_err_t
grub_video_bitmap_create_scaled (struct grub_video_bitmap **dst,
                                 int dst_width, int dst_height,
                                 struct grub_video_bitmap *src,
                                 enum grub_video_bitmap_scale_method
                                 scale_method)
{
  *dst = 0;

  grub_err_t err = verify_source_bitmap(src);
  if (err != GRUB_ERR_NONE)
    return err;
  if (dst_width <= 0 || dst_height <= 0)
    return grub_error (GRUB_ERR_BUG,
                       "requested to scale to a size w/ a zero dimension");

  /* Create the new bitmap. */
  grub_err_t ret;
  ret = grub_video_bitmap_create (dst, dst_width, dst_height,
                                  src->mode_info.blit_format);
  if (ret != GRUB_ERR_NONE)
    return ret;                 /* Error. */

  ret = grub_video_bitmap_scale (*dst, src, scale_method);

  if (ret == GRUB_ERR_NONE)
    {
      /* Success:  *dst is now a pointer to the scaled bitmap. */
      return GRUB_ERR_NONE;
    }
  else
    {
      /* Destroy the bitmap and return the error code. */
      grub_video_bitmap_destroy (*dst);
      *dst = 0;
      return ret;
    }
}
예제 #10
0
파일: theme_loader.c 프로젝트: flihp/grub2
/* Set the specified property NAME on the view to the given string VALUE.
   The caller is responsible for the lifetimes of NAME and VALUE.  */
static grub_err_t
theme_set_string (grub_gfxmenu_view_t view,
                  const char *name,
                  const char *value,
                  const char *theme_dir,
                  const char *filename,
                  int line_num,
                  int col_num)
{
  if (! grub_strcmp ("title-font", name))
    view->title_font = grub_font_get (value);
  else if (! grub_strcmp ("message-font", name))
    view->message_font = grub_font_get (value);
  else if (! grub_strcmp ("terminal-font", name))
    {
      grub_free (view->terminal_font_name);
      view->terminal_font_name = grub_strdup (value);
      if (! view->terminal_font_name)
        return grub_errno;
    }
  else if (! grub_strcmp ("title-color", name))
    grub_video_parse_color (value, &view->title_color);
  else if (! grub_strcmp ("message-color", name))
    grub_video_parse_color (value, &view->message_color);
  else if (! grub_strcmp ("message-bg-color", name))
    grub_video_parse_color (value, &view->message_bg_color);
  else if (! grub_strcmp ("desktop-image", name))
    {
      struct grub_video_bitmap *raw_bitmap;
      char *path;
      path = grub_resolve_relative_path (theme_dir, value);
      if (! path)
        return grub_errno;
      if (grub_video_bitmap_load (&raw_bitmap, path) != GRUB_ERR_NONE)
        {
          grub_free (path);
          return grub_errno;
        }
      grub_free(path);
      grub_video_bitmap_destroy (view->raw_desktop_image);
      view->raw_desktop_image = raw_bitmap;
    }
  else if (! grub_strcmp ("desktop-image-scale-method", name))
    {
      if (! value || ! grub_strcmp ("stretch", value))
        view->desktop_image_scale_method =
            GRUB_VIDEO_BITMAP_SELECTION_METHOD_STRETCH;
      else if (! grub_strcmp ("crop", value))
        view->desktop_image_scale_method =
            GRUB_VIDEO_BITMAP_SELECTION_METHOD_CROP;
      else if (! grub_strcmp ("padding", value))
        view->desktop_image_scale_method =
            GRUB_VIDEO_BITMAP_SELECTION_METHOD_PADDING;
      else if (! grub_strcmp ("fitwidth", value))
        view->desktop_image_scale_method =
            GRUB_VIDEO_BITMAP_SELECTION_METHOD_FITWIDTH;
      else if (! grub_strcmp ("fitheight", value))
        view->desktop_image_scale_method =
            GRUB_VIDEO_BITMAP_SELECTION_METHOD_FITHEIGHT;
      else
        return grub_error (GRUB_ERR_BAD_ARGUMENT,
                           "Unsupported scale method: %s",
                           value);
    }
  else if (! grub_strcmp ("desktop-image-h-align", name))
    {
      if (! grub_strcmp ("left", value))
        view->desktop_image_h_align = GRUB_VIDEO_BITMAP_H_ALIGN_LEFT;
      else if (! grub_strcmp ("center", value))
        view->desktop_image_h_align = GRUB_VIDEO_BITMAP_H_ALIGN_CENTER;
      else if (! grub_strcmp ("right", value))
        view->desktop_image_h_align = GRUB_VIDEO_BITMAP_H_ALIGN_RIGHT;
      else
        return grub_error (GRUB_ERR_BAD_ARGUMENT,
                           "Unsupported horizontal align method: %s",
                           value);
    }
  else if (! grub_strcmp ("desktop-image-v-align", name))
    {
      if (! grub_strcmp ("top", value))
        view->desktop_image_v_align = GRUB_VIDEO_BITMAP_V_ALIGN_TOP;
      else if (! grub_strcmp ("center", value))
        view->desktop_image_v_align = GRUB_VIDEO_BITMAP_V_ALIGN_CENTER;
      else if (! grub_strcmp ("bottom", value))
        view->desktop_image_v_align = GRUB_VIDEO_BITMAP_V_ALIGN_BOTTOM;
      else
        return grub_error (GRUB_ERR_BAD_ARGUMENT,
                           "Unsupported vertical align method: %s",
                           value);
    }
  else if (! grub_strcmp ("desktop-color", name))
     grub_video_parse_color (value, &view->desktop_color);
  else if (! grub_strcmp ("terminal-box", name))
    {
        grub_err_t err;
        err = grub_gui_recreate_box (&view->terminal_box, value, theme_dir);
        if (err != GRUB_ERR_NONE)
          return err;
    }
  else if (! grub_strcmp ("terminal-border", name))
    {
      view->terminal_border = grub_strtoul (value, 0, 10);
      if (grub_errno)
        return grub_errno;
    }
  else if (! grub_strcmp ("terminal-left", name))
    {
      unsigned int tmp;
      int err = theme_get_unsigned_int_from_proportional (value,
                                                          view->screen.width,
                                                          &tmp);
      if (err != GRUB_ERR_NONE)
        return err;
      view->terminal_rect.x = tmp;
    }
  else if (! grub_strcmp ("terminal-top", name))
    {
      unsigned int tmp;
      int err = theme_get_unsigned_int_from_proportional (value,
                                                          view->screen.height,
                                                          &tmp);
      if (err != GRUB_ERR_NONE)
        return err;
      view->terminal_rect.y = tmp;
    }
  else if (! grub_strcmp ("terminal-width", name))
    {
      unsigned int tmp;
      int err = theme_get_unsigned_int_from_proportional (value,
                                                          view->screen.width,
                                                          &tmp);
      if (err != GRUB_ERR_NONE)
        return err;
      view->terminal_rect.width = tmp;
    }
  else if (! grub_strcmp ("terminal-height", name))
    {
      unsigned int tmp;
      int err = theme_get_unsigned_int_from_proportional (value,
                                                          view->screen.height,
                                                          &tmp);
      if (err != GRUB_ERR_NONE)
        return err;
      view->terminal_rect.height = tmp;
    }
  else if (! grub_strcmp ("title-text", name))
    {
      grub_free (view->title_text);
      view->title_text = grub_strdup (value);
      if (! view->title_text)
        return grub_errno;
    }
  else
    {
      return grub_error (GRUB_ERR_BAD_ARGUMENT,
                         "%s:%d:%d unknown property `%s'",
                         filename, line_num, col_num, name);
    }
  return grub_errno;
}
예제 #11
0
grub_err_t
grub_video_bitmap_create_scaled (struct grub_video_bitmap **dst,
                                 int dst_width, int dst_height,
                                 struct grub_video_bitmap *src,
                                 int scale, grub_video_color_t color)
{
    int type, method;
    int src_width, src_height, width, height;
    struct grub_video_fbblit_info dst_info;
    struct grub_video_bitmap *tmp = 0;
    grub_err_t ret;

    *dst = 0;

    /* Verify the simplifying assumptions. */
    if (src == 0)
        return grub_error (GRUB_ERR_BAD_ARGUMENT,
                           "null src bitmap in grub_video_bitmap_create_scaled");
    if (src->mode_info.red_field_pos % 8 != 0
            || src->mode_info.green_field_pos % 8 != 0
            || src->mode_info.blue_field_pos % 8 != 0
            || src->mode_info.reserved_field_pos % 8 != 0)
        return grub_error (GRUB_ERR_BAD_ARGUMENT,
                           "src format not supported for scale");
    if (src->mode_info.width == 0 || src->mode_info.height == 0)
        return grub_error (GRUB_ERR_BAD_ARGUMENT,
                           "source bitmap has a zero dimension");
    if (dst_width <= 0 || dst_height <= 0)
        return grub_error (GRUB_ERR_BAD_ARGUMENT,
                           "requested to scale to a size w/ a zero dimension");
    if (src->mode_info.bytes_per_pixel * 8 != src->mode_info.bpp)
        return grub_error (GRUB_ERR_BAD_ARGUMENT,
                           "bitmap to scale has inconsistent Bpp and bpp");

    type = scale & GRUB_VIDEO_BITMAP_SCALE_TYPE_MASK;
    method = scale & GRUB_VIDEO_BITMAP_SCALE_METHOD_MASK;

    src_width = src->mode_info.width;
    src_height =  src->mode_info.height;
    if ((src_width == dst_width) &&  (src_height == dst_height))
        type = GRUB_VIDEO_BITMAP_SCALE_TYPE_CENTER;

    if ((type == GRUB_VIDEO_BITMAP_SCALE_TYPE_NORMAL) ||
            (((type == GRUB_VIDEO_BITMAP_SCALE_TYPE_MINFIT) ||
              (type == GRUB_VIDEO_BITMAP_SCALE_TYPE_MAXFIT)) &&
             (src_width * dst_height == src_height * dst_width)))
        return grub_video_bitmap_create_scaled_internal (dst, dst_width,
                dst_height, src, method);

    ret = grub_video_bitmap_create (dst, dst_width, dst_height,
                                    src->mode_info.blit_format);
    if (ret != GRUB_ERR_NONE)
        return ret;                 /* Error. */

    (*dst)->transparent = src->transparent;

    dst_info.mode_info = &(*dst)->mode_info;
    dst_info.data = (*dst)->data;
    color = map_color (dst_info.mode_info, color);

    switch (type)
    {
    case GRUB_VIDEO_BITMAP_SCALE_TYPE_MINFIT:
    case GRUB_VIDEO_BITMAP_SCALE_TYPE_MAXFIT:
    {
        if ((src_width * dst_height > src_height * dst_width) ==
                (type == GRUB_VIDEO_BITMAP_SCALE_TYPE_MAXFIT))
        {
            width = src_width * dst_height / src_height;
            height = dst_height;
        }
        else
        {
            width = dst_width;
            height = src_height * dst_width / src_width;
        }

        ret = grub_video_bitmap_create_scaled_internal (&tmp, width, height,
                src, method);
        if (ret)
            return ret;

        src = tmp;
        src_width = width;
        src_height = height;
    }

    case GRUB_VIDEO_BITMAP_SCALE_TYPE_CENTER:
    {
        int src_x, src_y, dst_x, dst_y;
        struct grub_video_fbblit_info src_info;

        width = (src_width > dst_width) ? dst_width : src_width;
        height = (src_height > dst_height) ? dst_height : src_height;

        src_x = (src_width - width) >> 1;
        src_y = (src_height - height) >> 1;
        dst_x = (dst_width - width) >> 1;
        dst_y = (dst_height - height) >> 1;

        if (dst_y)
        {
            grub_video_fbfill (&dst_info, color, 0, 0, dst_width, dst_y);
            grub_video_fbfill (&dst_info, color, 0, dst_y + height,
                               dst_width, dst_height - dst_y - height);
        }

        if (dst_x)
        {
            grub_video_fbfill (&dst_info, color, 0, dst_y, dst_x, height);
            grub_video_fbfill (&dst_info, color, dst_x + width, dst_y,
                               dst_width - dst_x - width, height);
        }

        src_info.mode_info = &src->mode_info;
        src_info.data = src->data;
        grub_video_fbblit (&dst_info, &src_info, GRUB_VIDEO_BLIT_REPLACE,
                           dst_x, dst_y, width, height, src_x, src_y);
        break;
    }

    case GRUB_VIDEO_BITMAP_SCALE_TYPE_TILING:
    {
        int x, y;
        struct grub_video_fbblit_info src_info;

        src_info.mode_info = &src->mode_info;
        src_info.data = src->data;
        for (y = 0; y < dst_height; y += src_height)
        {
            for (x = 0; x < dst_width; x += src_width)
            {

                int w, h;

                w = src_width;
                if (x + w > dst_width)
                    w = dst_width - x;
                h = src_height;
                if (y + h > dst_height)
                    h = dst_height - y;

                grub_video_fbblit (&dst_info, &src_info,
                                   GRUB_VIDEO_BLIT_REPLACE,
                                   x, y, w, h, 0, 0);
            }
        }
        break;
    }

    default:
        return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid scale type value");
    }

    if (tmp)
        grub_video_bitmap_destroy (tmp);

    return 0;
}
예제 #12
0
/* This function creates a new scaled version of the bitmap SRC.  The new
   bitmap has dimensions DST_WIDTH by DST_HEIGHT.  The scaling algorithm
   is given by SCALE_METHOD.  If an error is encountered, the return code is
   not equal to GRUB_ERR_NONE, and the bitmap DST is either not created, or
   it is destroyed before this function returns.

   Supports only direct color modes which have components separated
   into bytes (e.g., RGBA 8:8:8:8 or BGR 8:8:8 true color).
   But because of this simplifying assumption, the implementation is
   greatly simplified.  */
grub_err_t
grub_video_bitmap_create_scaled (struct grub_video_bitmap **dst,
                                 int dst_width, int dst_height,
                                 struct grub_video_bitmap *src,
                                 enum grub_video_bitmap_scale_method
                                 scale_method)
{
  *dst = 0;

  /* Verify the simplifying assumptions. */
  if (src == 0)
    return grub_error (GRUB_ERR_BAD_ARGUMENT,
                       "null src bitmap in grub_video_bitmap_create_scaled");
  if (src->mode_info.red_field_pos % 8 != 0
      || src->mode_info.green_field_pos % 8 != 0
      || src->mode_info.blue_field_pos % 8 != 0
      || src->mode_info.reserved_field_pos % 8 != 0)
    return grub_error (GRUB_ERR_BAD_ARGUMENT,
                       "src format not supported for scale");
  if (src->mode_info.width == 0 || src->mode_info.height == 0)
    return grub_error (GRUB_ERR_BAD_ARGUMENT,
                       "source bitmap has a zero dimension");
  if (dst_width <= 0 || dst_height <= 0)
    return grub_error (GRUB_ERR_BAD_ARGUMENT,
                       "requested to scale to a size w/ a zero dimension");
  if (src->mode_info.bytes_per_pixel * 8 != src->mode_info.bpp)
    return grub_error (GRUB_ERR_BAD_ARGUMENT,
                       "bitmap to scale has inconsistent Bpp and bpp");

  /* Create the new bitmap. */
  grub_err_t ret;
  ret = grub_video_bitmap_create (dst, dst_width, dst_height,
                                  src->mode_info.blit_format);
  if (ret != GRUB_ERR_NONE)
    return ret;                 /* Error. */

  switch (scale_method)
    {
    case GRUB_VIDEO_BITMAP_SCALE_METHOD_FASTEST:
    case GRUB_VIDEO_BITMAP_SCALE_METHOD_NEAREST:
      ret = scale_nn (*dst, src);
      break;
    case GRUB_VIDEO_BITMAP_SCALE_METHOD_BEST:
    case GRUB_VIDEO_BITMAP_SCALE_METHOD_BILINEAR:
      ret = scale_bilinear (*dst, src);
      break;
    default:
      ret = grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid scale_method value");
      break;
    }

  if (ret == GRUB_ERR_NONE)
    {
      /* Success:  *dst is now a pointer to the scaled bitmap. */
      return GRUB_ERR_NONE;
    }
  else
    {
      /* Destroy the bitmap and return the error code. */
      grub_video_bitmap_destroy (*dst);
      *dst = 0;
      return ret;
    }
}
예제 #13
0
grub_err_t
grub_video_bitmap_scale_proportional (struct grub_video_bitmap **dst,
                                      int dst_width, int dst_height,
                                      struct grub_video_bitmap *src,
                                      enum grub_video_bitmap_scale_method
                                      scale_method,
                                      grub_video_bitmap_selection_method_t
                                      selection_method,
                                      grub_video_bitmap_v_align_t v_align,
                                      grub_video_bitmap_h_align_t h_align)
{
  *dst = 0;
  grub_err_t ret = verify_source_bitmap(src);
  if (ret != GRUB_ERR_NONE)
    return ret;
  if (dst_width <= 0 || dst_height <= 0)
    return grub_error (GRUB_ERR_BUG,
                       "requested to scale to a size w/ a zero dimension");

  ret = grub_video_bitmap_create (dst, dst_width, dst_height,
                                  src->mode_info.blit_format);
  if (ret != GRUB_ERR_NONE)
    return ret;                 /* Error. */

  unsigned dx0 = 0;
  unsigned dy0 = 0;
  unsigned dw = dst_width;
  unsigned dh = dst_height;
  unsigned sx0 = 0;
  unsigned sy0 = 0;
  unsigned sw = src->mode_info.width;
  unsigned sh = src->mode_info.height;

  switch (selection_method)
    {
    case GRUB_VIDEO_BITMAP_SELECTION_METHOD_CROP:
      /* Comparing sw/sh VS dw/dh. */
      if (sw * dh < dw * sh)
        ret = make_v_align (&sy0, &sh, sw * dh / dw, v_align);
      else
        ret = make_h_align (&sx0, &sw, sh * dw / dh, h_align);
      break;
    case GRUB_VIDEO_BITMAP_SELECTION_METHOD_PADDING:
      if (sw * dh < dw * sh)
        ret = make_h_align (&dx0, &dw, sw * dh / sh, h_align);
      else
        ret = make_v_align (&dy0, &dh, sh * dw / sw, v_align);
      break;
    case GRUB_VIDEO_BITMAP_SELECTION_METHOD_FITWIDTH:
      if (sw * dh < dw * sh)
        ret = make_v_align (&sy0, &sh, sw * dh / dw, v_align);
      else
        ret = make_v_align (&dy0, &dh, sh * dw / sw, v_align);
      break;
    case GRUB_VIDEO_BITMAP_SELECTION_METHOD_FITHEIGHT:
      if (sw * dh < dw * sh)
        ret = make_h_align (&dx0, &dw, sw * dh / sh, h_align);
      else
        ret = make_h_align (&sx0, &sw, sh * dw / dh, h_align);
      break;
    default:
      ret = grub_error (GRUB_ERR_BUG, "Invalid selection_method value");
      break;
    }

  if (ret == GRUB_ERR_NONE)
    {
      /* Backup original data. */
      int src_width_orig = src->mode_info.width;
      int src_height_orig = src->mode_info.height;
      grub_uint8_t *src_data_orig = src->data;
      int dst_width_orig = (*dst)->mode_info.width;
      int dst_height_orig = (*dst)->mode_info.height;
      grub_uint8_t *dst_data_orig = (*dst)->data;

      int dstride = (*dst)->mode_info.pitch;
      int sstride = src->mode_info.pitch;
      /* bytes_per_pixel is the same for both src and dst. */
      int bytes_per_pixel = src->mode_info.bytes_per_pixel;

      /* Crop src and dst. */
      src->mode_info.width = sw;
      src->mode_info.height = sh;
      src->data = (grub_uint8_t *) src->data + sx0 * bytes_per_pixel
                  + sy0 * sstride;
      (*dst)->mode_info.width = dw;
      (*dst)->mode_info.height = dh;
      (*dst)->data = (grub_uint8_t *) (*dst)->data + dx0 * bytes_per_pixel
                     + dy0 * dstride;

      /* Scale our image. */
      ret = grub_video_bitmap_scale (*dst, src, scale_method);

      /* Restore original data. */
      src->mode_info.width = src_width_orig;
      src->mode_info.height = src_height_orig;
      src->data = src_data_orig;
      (*dst)->mode_info.width = dst_width_orig;
      (*dst)->mode_info.height = dst_height_orig;
      (*dst)->data = dst_data_orig;
    }

  if (ret == GRUB_ERR_NONE)
    {
      /* Success:  *dst is now a pointer to the scaled bitmap. */
      return GRUB_ERR_NONE;
    }
  else
    {
      /* Destroy the bitmap and return the error code. */
      grub_video_bitmap_destroy (*dst);
      *dst = 0;
      return ret;
    }
}
예제 #14
0
파일: tga.c 프로젝트: Firef0x/burg-new
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;
}
예제 #15
0
파일: tga.c 프로젝트: jnbek/grub2-fedora
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;
}