From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with archive (Exim 4.43) id 1KZic5-0003vv-0d for mharc-grub-devel@gnu.org; Sun, 31 Aug 2008 04:48:49 -0400 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1KZic3-0003v4-5V for grub-devel@gnu.org; Sun, 31 Aug 2008 04:48:47 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1KZic2-0003uL-8D for grub-devel@gnu.org; Sun, 31 Aug 2008 04:48:46 -0400 Received: from [199.232.76.173] (port=39296 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1KZic1-0003uC-Pd for grub-devel@gnu.org; Sun, 31 Aug 2008 04:48:46 -0400 Received: from gateway16.websitewelcome.com ([69.56.180.14]:48974) by monty-python.gnu.org with smtp (Exim 4.60) (envelope-from ) id 1KZic1-0003Yg-0a for grub-devel@gnu.org; Sun, 31 Aug 2008 04:48:45 -0400 Received: (qmail 16964 invoked from network); 31 Aug 2008 07:10:18 -0000 Received: from gator297.hostgator.com (74.53.228.114) by gateway16.websitewelcome.com with SMTP; 31 Aug 2008 07:10:18 -0000 Received: from c-67-185-142-228.hsd1.wa.comcast.net ([67.185.142.228]:38816 helo=gamma.lan) by gator297.hostgator.com with esmtpsa (TLSv1:AES128-SHA:128) (Exim 4.68) (envelope-from ) id 1KZgwg-00061a-Gj for grub-devel@gnu.org; Sun, 31 Aug 2008 02:01:58 -0500 Date: Sun, 31 Aug 2008 00:01:57 -0700 From: Colin D Bennett To: grub-devel@gnu.org Message-ID: <20080831000157.0c548199@gamma.lan> X-Mailer: Claws Mail 3.5.0 (GTK+ 2.12.11; i686-pc-linux-gnu) Mime-Version: 1.0 Content-Type: multipart/signed; boundary="Sig_/ZKPoUjLialH7A92CmPf1e9_"; protocol="application/pgp-signature"; micalg=PGP-SHA1 X-AntiAbuse: This header was added to track abuse, please include it with any abuse report X-AntiAbuse: Primary Hostname - gator297.hostgator.com X-AntiAbuse: Original Domain - gnu.org X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] X-AntiAbuse: Sender Address Domain - gibibit.com X-detected-kernel: by monty-python.gnu.org: Linux 2.6 (newer, 3) Subject: [PATCH] GSoC #09 Bitmap scaling X-BeenThere: grub-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: The development of GRUB 2 List-Id: The development of GRUB 2 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 31 Aug 2008 08:48:47 -0000 --Sig_/ZKPoUjLialH7A92CmPf1e9_ Content-Type: multipart/mixed; boundary="MP_/ZvDtLknb4qF8.EqTG2IrVHc" --MP_/ZvDtLknb4qF8.EqTG2IrVHc Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: quoted-printable Content-Disposition: inline This patch adds image scaling support. Nearest neighbor and bilinear interpolation algorithms are supported. The gfxterm background_image command scales the background image to fit the screen. This can be controlled with the new --mode/-m option. Regards, Colin --MP_/ZvDtLknb4qF8.EqTG2IrVHc Content-Type: text/x-patch; name=09_bitmap-scaling.patch Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename=09_bitmap-scaling.patch =3D=3D=3D modified file 'conf/i386-pc.rmk' --- conf/i386-pc.rmk 2008-08-30 19:20:13 +0000 +++ conf/i386-pc.rmk 2008-08-31 03:00:53 +0000 @@ -271,7 +271,10 @@ videotest_mod_LDFLAGS =3D $(COMMON_LDFLAGS) =20 # For bitmap.mod -bitmap_mod_SOURCES =3D video/bitmap.c +bitmap_mod_SOURCES =3D video/bitmap.c \ + video/bitmap_scale_nn.c \ + video/bitmap_scale_bilinear.c \ + video/bitmap_scale.c bitmap_mod_CFLAGS =3D $(COMMON_CFLAGS) bitmap_mod_LDFLAGS =3D $(COMMON_LDFLAGS) =20 =3D=3D=3D added file 'include/grub/bitmap_scale.h' --- include/grub/bitmap_scale.h 1970-01-01 00:00:00 +0000 +++ include/grub/bitmap_scale.h 2008-08-31 03:00:53 +0000 @@ -0,0 +1,54 @@ +/* bitmap_scale.h - Bitmap scaling functions. */ +/* + * 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 . + */ + +#ifndef GRUB_BITMAP_SCALE_HEADER +#define GRUB_BITMAP_SCALE_HEADER 1 + +#include +#include +#include + +enum grub_video_bitmap_scale_method +{ + /* Choose the fastest interpolation algorithm. */ + GRUB_VIDEO_BITMAP_SCALE_METHOD_FASTEST, + /* Choose the highest quality interpolation algorithm. */ + GRUB_VIDEO_BITMAP_SCALE_METHOD_BEST, + /* Nearest neighbor interpolation algorithm. */ + GRUB_VIDEO_BITMAP_SCALE_METHOD_NEAREST, + /* Bilinear interpolation algorithm. */ + GRUB_VIDEO_BITMAP_SCALE_METHOD_BILINEAR +}; + +grub_err_t +grub_video_bitmap_scale_nn (struct grub_video_bitmap *dst, + struct grub_video_bitmap *src); + +grub_err_t +grub_video_bitmap_scale_bilinear (struct grub_video_bitmap *dst, + struct grub_video_bitmap *src); + +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_meth= od); + +#endif /* ! GRUB_BITMAP_SCALE_HEADER */ =3D=3D=3D modified file 'term/gfxterm.c' --- term/gfxterm.c 2008-08-19 18:20:33 +0000 +++ term/gfxterm.c 2008-08-31 03:08:13 +0000 @@ -29,6 +29,7 @@ #include #include #include +#include =20 #define DEFAULT_VIDEO_WIDTH 640 #define DEFAULT_VIDEO_HEIGHT 480 @@ -1010,8 +1011,18 @@ dirty_region_redraw (); } =20 + +/* Option array indices. */ +#define BACKGROUND_CMD_ARGINDEX_MODE 0 + +static const struct grub_arg_option background_image_cmd_options[] =3D { + {"mode", 'm', 0, "Background image mode (`stretch', `normal').", 0,=20 + ARG_TYPE_STRING}, + {0, 0, 0, 0, 0, 0} +}; + static grub_err_t -grub_gfxterm_background_image_cmd (struct grub_arg_list *state __attribute= __ ((unused)), +grub_gfxterm_background_image_cmd (struct grub_arg_list *state, int argc, char **args) { @@ -1038,12 +1049,36 @@ if (grub_errno !=3D GRUB_ERR_NONE) return grub_errno; =20 + /* Determine if the bitmap should be scaled to fit the screen. */ + if (!state[BACKGROUND_CMD_ARGINDEX_MODE].set + || grub_strcmp (state[BACKGROUND_CMD_ARGINDEX_MODE].arg, + "stretch") =3D=3D 0) + { + if (mode_info.width !=3D grub_video_bitmap_get_width (bitmap) + || mode_info.height !=3D grub_video_bitmap_get_height (bitma= p))=20 + { + struct grub_video_bitmap *scaled_bitmap; + grub_video_bitmap_create_scaled (&scaled_bitmap, + mode_info.width,=20 + mode_info.height, + bitmap, + GRUB_VIDEO_BITMAP_SCALE_METH= OD_BEST); + if (grub_errno =3D=3D GRUB_ERR_NONE) + { + /* Replace the original bitmap with the scaled one. */ + grub_video_bitmap_destroy (bitmap); + bitmap =3D scaled_bitmap; + } + } + } + + /* If bitmap was loaded correctly, display it. */ if (bitmap) { /* Determine bitmap dimensions. */ bitmap_width =3D grub_video_bitmap_get_width (bitmap); - bitmap_height =3D grub_video_bitmap_get_width (bitmap); + bitmap_height =3D grub_video_bitmap_get_height (bitmap); =20 /* Mark whole screen as dirty. */ dirty_region_reset (); @@ -1088,7 +1123,7 @@ GRUB_COMMAND_FLAG_BOTH, "background_image", "Load background image for active terminal", - 0); + background_image_cmd_options); } =20 GRUB_MOD_FINI(term_gfxterm) =3D=3D=3D added file 'video/bitmap_scale.c' --- video/bitmap_scale.c 1970-01-01 00:00:00 +0000 +++ video/bitmap_scale.c 2008-08-31 03:00:53 +0000 @@ -0,0 +1,101 @@ +/* bitmap_scale.c - Bitmap scaling interface. */ +/* + * 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 . + */ + +#include +#include +#include +#include +#include +#include + +/*=20 + * 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, o= r=20 + * 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).=20 + * 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 =3D 0; + + /* Verify the simplifying assumptions. */ + if (src =3D=3D 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 !=3D 0 + || src->mode_info.green_field_pos % 8 !=3D 0 + || src->mode_info.blue_field_pos % 8 !=3D 0 + || src->mode_info.reserved_field_pos % 8 !=3D 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "src format not supported for scale"); + if (src->mode_info.width =3D=3D 0 || src->mode_info.height =3D=3D 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "bitmap has a zero dimension= "); + if (dst_width <=3D 0 || dst_height <=3D 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 !=3D 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 =3D grub_video_bitmap_create (dst, dst_width, dst_height, + src->mode_info.blit_format); + if (ret !=3D GRUB_ERR_NONE) + return ret; /* Error. */ + + switch (scale_method) + { + case GRUB_VIDEO_BITMAP_SCALE_METHOD_FASTEST: + case GRUB_VIDEO_BITMAP_SCALE_METHOD_NEAREST: + ret =3D grub_video_bitmap_scale_nn (*dst, src); + break; + case GRUB_VIDEO_BITMAP_SCALE_METHOD_BEST: + case GRUB_VIDEO_BITMAP_SCALE_METHOD_BILINEAR: + ret =3D grub_video_bitmap_scale_bilinear (*dst, src); + break; + default: + ret =3D grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid scale_method val= ue"); + break; + } + + if (ret =3D=3D 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 =3D 0; + return ret; + } +} =3D=3D=3D added file 'video/bitmap_scale_bilinear.c' --- video/bitmap_scale_bilinear.c 1970-01-01 00:00:00 +0000 +++ video/bitmap_scale_bilinear.c 2008-08-31 03:00:53 +0000 @@ -0,0 +1,145 @@ +/* bitmap_scale_bilinear.c - Bilinear image scaling algorithm. */ +/* + * 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 . + */ + +#include +#include +#include +#include +#include +#include + +/*=20 + * Copy the bitmap SRC to the bitmap DST, scaling the bitmap to fit the=20 + * dimensions of DST. This function uses the bilinear interpolation algor= ithm + * to interpolate the pixels. + * + * 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).=20 + * But because of this simplifying assumption, the implementation is + * greatly simplified. + */ +grub_err_t +grub_video_bitmap_scale_bilinear (struct grub_video_bitmap *dst, + struct grub_video_bitmap *src) +{ + /* Verify the simplifying assumptions. */ + if (dst =3D=3D 0 || src =3D=3D 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "null bitmap in scale func"); + if (dst->mode_info.red_field_pos % 8 !=3D 0 + || dst->mode_info.green_field_pos % 8 !=3D 0 + || dst->mode_info.blue_field_pos % 8 !=3D 0 + || dst->mode_info.reserved_field_pos % 8 !=3D 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "dst format not supported"); + if (src->mode_info.red_field_pos % 8 !=3D 0 + || src->mode_info.green_field_pos % 8 !=3D 0 + || src->mode_info.blue_field_pos % 8 !=3D 0 + || src->mode_info.reserved_field_pos % 8 !=3D 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "src format not supported"); + if (dst->mode_info.red_field_pos !=3D src->mode_info.red_field_pos + || dst->mode_info.red_mask_size !=3D src->mode_info.red_mask_size + || dst->mode_info.green_field_pos !=3D src->mode_info.green_field_pos + || dst->mode_info.green_mask_size !=3D src->mode_info.green_mask_size + || dst->mode_info.blue_field_pos !=3D src->mode_info.blue_field_pos + || dst->mode_info.blue_mask_size !=3D src->mode_info.blue_mask_size + || dst->mode_info.reserved_field_pos !=3D + src->mode_info.reserved_field_pos + || dst->mode_info.reserved_mask_size !=3D + src->mode_info.reserved_mask_size) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "dst and src not compatible"= ); + if (dst->mode_info.bytes_per_pixel !=3D src->mode_info.bytes_per_pixel) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "dst and src not compatible"= ); + if (dst->mode_info.width =3D=3D 0 || dst->mode_info.height =3D=3D 0 + || src->mode_info.width =3D=3D 0 || src->mode_info.height =3D=3D 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "bitmap has a zero dimension= "); + + grub_uint8_t *ddata =3D dst->data; + grub_uint8_t *sdata =3D src->data; + int dw =3D dst->mode_info.width; + int dh =3D dst->mode_info.height; + int sw =3D src->mode_info.width; + int sh =3D src->mode_info.height; + int dstride =3D dst->mode_info.pitch; + int sstride =3D src->mode_info.pitch; + /* bytes_per_pixel is the same for both src and dst. */ + int bytes_per_pixel =3D dst->mode_info.bytes_per_pixel; + + int dy; + for (dy =3D 0; dy < dh; dy++) + { + int dx; + for (dx =3D 0; dx < dw; dx++) + { + grub_uint8_t *dptr; + grub_uint8_t *sptr; + int sx; + int sy; + int comp; + + /* Compute the source coordinate that the destination coordinate + * maps to. Note: sx/sw =3D dx/dw =3D> sx =3D sw*dx/dw. */ + sx =3D sw * dx / dw; + sy =3D sh * dy / dh; + + /* Get the address of the pixels in src and dst. */ + dptr =3D ddata + dy * dstride + dx * bytes_per_pixel; + sptr =3D sdata + sy * sstride + sx * bytes_per_pixel; + + /* If we have enough space to do so, use bilinear interpolation. + * Otherwise, fall back to nearest neighbor for this pixel. */ + if (sx < sw - 1 && sy < sh - 1) + { + /* Do bilinear interpolation. */ + + /* Fixed-point .8 numbers representing the fraction of the + * distance in the x (u) and y (v) direction within the=20 + * box of 4 pixels in the source. */ + int u =3D (256 * sw * dx / dw) - (sx * 256); + int v =3D (256 * sh * dy / dh) - (sy * 256); + + for (comp =3D 0; comp < bytes_per_pixel; comp++) + { + /* Get the component's values for the=20 + * 4 source corner pixels. */ + grub_uint8_t f00 =3D sptr[comp]; + grub_uint8_t f10 =3D sptr[comp + bytes_per_pixel]; + grub_uint8_t f01 =3D sptr[comp + sstride]; + grub_uint8_t f11 =3D sptr[comp + sstride + bytes_per_pix= el]; + + /* Do linear interpolations along the top and bottom + * rows of the box. */ + grub_uint8_t f0y =3D (256 - v) * f00 / 256 + v * f01 / 2= 56; + grub_uint8_t f1y =3D (256 - v) * f10 / 256 + v * f11 / 2= 56; + + /* Interpolate vertically. */ + grub_uint8_t fxy =3D (256 - u) * f0y / 256 + u * f1y / 2= 56; + + dptr[comp] =3D fxy; + } + } + else + { + /* Fall back to nearest neighbor interpolation. */ + /* Copy the pixel color value. */ + for (comp =3D 0; comp < bytes_per_pixel; comp++) + dptr[comp] =3D sptr[comp]; + } + } + } + return GRUB_ERR_NONE; +} =3D=3D=3D added file 'video/bitmap_scale_nn.c' --- video/bitmap_scale_nn.c 1970-01-01 00:00:00 +0000 +++ video/bitmap_scale_nn.c 2008-08-31 03:00:53 +0000 @@ -0,0 +1,109 @@ +/* bitmap_scale_nn.c - Nearest neighbor image scaling algorithm. */ +/* + * 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 . + */ + +#include +#include +#include +#include +#include +#include + +/*=20 + * Copy the bitmap SRC to the bitmap DST, scaling the bitmap to fit the=20 + * dimensions of DST. This function uses the nearest neighbor algorithm to + * interpolate the pixels. + * + * 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).=20 + * But because of this simplifying assumption, the implementation is + * greatly simplified. + */ +grub_err_t +grub_video_bitmap_scale_nn (struct grub_video_bitmap *dst, + struct grub_video_bitmap *src) +{ + /* Verify the simplifying assumptions. */ + if (dst =3D=3D 0 || src =3D=3D 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "null bitmap in scale_nn"); + if (dst->mode_info.red_field_pos % 8 !=3D 0 + || dst->mode_info.green_field_pos % 8 !=3D 0 + || dst->mode_info.blue_field_pos % 8 !=3D 0 + || dst->mode_info.reserved_field_pos % 8 !=3D 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "dst format not supported"); + if (src->mode_info.red_field_pos % 8 !=3D 0 + || src->mode_info.green_field_pos % 8 !=3D 0 + || src->mode_info.blue_field_pos % 8 !=3D 0 + || src->mode_info.reserved_field_pos % 8 !=3D 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "src format not supported"); + if (dst->mode_info.red_field_pos !=3D src->mode_info.red_field_pos + || dst->mode_info.red_mask_size !=3D src->mode_info.red_mask_size + || dst->mode_info.green_field_pos !=3D src->mode_info.green_field_pos + || dst->mode_info.green_mask_size !=3D src->mode_info.green_mask_size + || dst->mode_info.blue_field_pos !=3D src->mode_info.blue_field_pos + || dst->mode_info.blue_mask_size !=3D src->mode_info.blue_mask_size + || dst->mode_info.reserved_field_pos !=3D + src->mode_info.reserved_field_pos + || dst->mode_info.reserved_mask_size !=3D + src->mode_info.reserved_mask_size) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "dst and src not compatible"= ); + if (dst->mode_info.bytes_per_pixel !=3D src->mode_info.bytes_per_pixel) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "dst and src not compatible"= ); + if (dst->mode_info.width =3D=3D 0 || dst->mode_info.height =3D=3D 0 + || src->mode_info.width =3D=3D 0 || src->mode_info.height =3D=3D 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "bitmap has a zero dimension= "); + + grub_uint8_t *ddata =3D dst->data; + grub_uint8_t *sdata =3D src->data; + int dw =3D dst->mode_info.width; + int dh =3D dst->mode_info.height; + int sw =3D src->mode_info.width; + int sh =3D src->mode_info.height; + int dstride =3D dst->mode_info.pitch; + int sstride =3D src->mode_info.pitch; + /* bytes_per_pixel is the same for both src and dst. */ + int bytes_per_pixel =3D dst->mode_info.bytes_per_pixel; + + int dy; + for (dy =3D 0; dy < dh; dy++) + { + int dx; + for (dx =3D 0; dx < dw; dx++) + { + grub_uint8_t *dptr; + grub_uint8_t *sptr; + int sx; + int sy; + int comp; + + /* Compute the source coordinate that the destination coordinate + * maps to. Note: sx/sw =3D dx/dw =3D> sx =3D sw*dx/dw. */ + sx =3D sw * dx / dw; + sy =3D sh * dy / dh; + + /* Get the address of the pixels in src and dst. */ + dptr =3D ddata + dy * dstride + dx * bytes_per_pixel; + sptr =3D sdata + sy * sstride + sx * bytes_per_pixel; + + /* Copy the pixel color value. */ + for (comp =3D 0; comp < bytes_per_pixel; comp++) + dptr[comp] =3D sptr[comp]; + } + } + return GRUB_ERR_NONE; +} --MP_/ZvDtLknb4qF8.EqTG2IrVHc Content-Type: text/plain; name=09_ChangeLog.txt Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename=09_ChangeLog.txt 2008-08-30 Colin D Bennett =09 Image scaling support. Also, gfxterm's background_image command can scale the image to fit the screen (--mode/-m option). * conf/i386-pc.rmk (bitmap_mod_SOURCES): Added new source files. * include/grub/bitmap_scale.h: New file. * video/bitmap_scale.c: New file. * video/bitmap_scale_bilinear.c: New file. * video/bitmap_scale_nn.c: New file. * term/gfxterm.c (BACKGROUND_CMD_ARGINDEX_MODE): New macro. (background_image_cmd_options): New static variable. (grub_gfxterm_background_image_cmd): Handle --mode/-m option and scale the bitmap to the screen size if requested. Also includes a "drive-by" fix to an erroneous assignment of the bitmap width to 'bitmap_height'. (GRUB_MOD_INIT): Pass background_image_cmd_options to grub_register_command. --MP_/ZvDtLknb4qF8.EqTG2IrVHc-- --Sig_/ZKPoUjLialH7A92CmPf1e9_ Content-Type: application/pgp-signature; name=signature.asc Content-Disposition: attachment; filename=signature.asc -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.9 (GNU/Linux) iEYEARECAAYFAki6QegACgkQokx8fzcGbYfGagCglYtSFKl6xrddtsdSkhkZGl0N 7IsAn2oDRvt2qvcmVHW6ZhDjxsCu749m =vABL -----END PGP SIGNATURE----- --Sig_/ZKPoUjLialH7A92CmPf1e9_--