All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Vladimir 'φ-coder/phcoder' Serbinenko" <phcoder@gmail.com>
To: The development of GNU GRUB <grub-devel@gnu.org>
Subject: Re: Image scaling performance
Date: Wed, 25 Feb 2015 21:39:37 +0100	[thread overview]
Message-ID: <54EE3309.4010605@gmail.com> (raw)
In-Reply-To: <CAN9vWDJ=zVD9nTcqa7Ce+G+kHXm0bcAEchaCOLT9Sx40WzwcHQ@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 127 bytes --]

On 25.02.2015 20:28, Michael Zimmermann wrote:
> your patch still has graphical glitches: http://puu.sh/gcpco/da369f26c7.png



[-- Attachment #2: scale.diff --]
[-- Type: text/x-diff, Size: 6115 bytes --]

diff --git a/grub-core/video/bitmap_scale.c b/grub-core/video/bitmap_scale.c
index 0b93d02..70c32f0 100644
--- a/grub-core/video/bitmap_scale.c
+++ b/grub-core/video/bitmap_scale.c
@@ -361,35 +361,46 @@ scale_nn (struct grub_video_bitmap *dst, struct grub_video_bitmap *src)
   unsigned dh = dst->mode_info.height;
   unsigned sw = src->mode_info.width;
   unsigned sh = src->mode_info.height;
-  unsigned dstride = dst->mode_info.pitch;
-  unsigned sstride = src->mode_info.pitch;
+  int dstride = dst->mode_info.pitch;
+  int sstride = src->mode_info.pitch;
   /* bytes_per_pixel is the same for both src and dst. */
-  unsigned bytes_per_pixel = dst->mode_info.bytes_per_pixel;
+  int bytes_per_pixel = dst->mode_info.bytes_per_pixel;
+  unsigned dy, sy, ystep, yfrac, yover;
+  unsigned sx, xstep, xfrac, xover;
+  grub_uint8_t *dptr, *dline_end, *sline;
 
-  unsigned dy;
-  for (dy = 0; dy < dh; dy++)
+  xstep = sw / dw;
+  xover = sw % dw;
+  ystep = sh / dh;
+  yover = sh % dh;
+
+  for (dy = 0, sy = 0, yfrac = 0; dy < dh; dy++, sy += ystep, yfrac += yover)
     {
-      unsigned dx;
-      for (dx = 0; dx < dw; dx++)
+      if (yfrac >= dh)
+	{
+	  yfrac -= dh;
+	  sy++;
+	}
+      dptr = ddata + dy * dstride;
+      dline_end = dptr + dw * bytes_per_pixel;
+      sline = sdata + sy * sstride;
+      for (sx = 0, xfrac = 0; dptr < dline_end; sx += xstep, xfrac += xover, dptr += bytes_per_pixel)
         {
-          grub_uint8_t *dptr;
           grub_uint8_t *sptr;
-          unsigned sx;
-          unsigned sy;
-          unsigned comp;
+          int comp;
 
-          /* Compute the source coordinate that the destination coordinate
-             maps to.  Note: sx/sw = dx/dw  =>  sx = sw*dx/dw. */
-          sx = sw * dx / dw;
-          sy = sh * dy / dh;
+	  if (xfrac >= dw)
+	    {
+	      xfrac -= dw;
+	      sx++;
+	    }
 
           /* Get the address of the pixels in src and dst. */
-          dptr = ddata + dy * dstride + dx * bytes_per_pixel;
-          sptr = sdata + sy * sstride + sx * bytes_per_pixel;
+	  sptr = sline + sx * bytes_per_pixel;
 
-          /* Copy the pixel color value. */
-          for (comp = 0; comp < bytes_per_pixel; comp++)
-            dptr[comp] = sptr[comp];
+	  /* Copy the pixel color value. */
+	  for (comp = 0; comp < bytes_per_pixel; comp++)
+	    dptr[comp] = sptr[comp];
         }
     }
   return GRUB_ERR_NONE;
@@ -422,27 +433,40 @@ scale_bilinear (struct grub_video_bitmap *dst, struct grub_video_bitmap *src)
   int sstride = src->mode_info.pitch;
   /* bytes_per_pixel is the same for both src and dst. */
   int bytes_per_pixel = dst->mode_info.bytes_per_pixel;
+  unsigned dy, syf, sy, ystep, yfrac, yover;
+  unsigned sxf, sx, xstep, xfrac, xover;
+  grub_uint8_t *dptr, *dline_end, *sline;
+
+  xstep = (sw << 8) / dw;
+  xover = (sw << 8) % dw;
+  ystep = (sh << 8) / dh;
+  yover = (sh << 8) % dh;
 
-  unsigned dy;
-  for (dy = 0; dy < dh; dy++)
+  for (dy = 0, syf = 0, yfrac = 0; dy < dh; dy++, syf += ystep, yfrac += yover)
     {
-      unsigned dx;
-      for (dx = 0; dx < dw; dx++)
+      if (yfrac >= dh)
+	{
+	  yfrac -= dh;
+	  syf++;
+	}
+      sy = syf >> 8;
+      dptr = ddata + dy * dstride;
+      dline_end = dptr + dw * bytes_per_pixel;
+      sline = sdata + sy * sstride;
+      for (sxf = 0, xfrac = 0; dptr < dline_end; sxf += xstep, xfrac += xover, dptr += bytes_per_pixel)
         {
-          grub_uint8_t *dptr;
           grub_uint8_t *sptr;
-          unsigned sx;
-          unsigned sy;
           int comp;
 
-          /* Compute the source coordinate that the destination coordinate
-             maps to.  Note: sx/sw = dx/dw  =>  sx = sw*dx/dw. */
-          sx = sw * dx / dw;
-          sy = sh * dy / dh;
+	  if (xfrac >= dw)
+	    {
+	      xfrac -= dw;
+	      sxf++;
+	    }
 
           /* Get the address of the pixels in src and dst. */
-          dptr = ddata + dy * dstride + dx * bytes_per_pixel;
-          sptr = sdata + sy * sstride + sx * bytes_per_pixel;
+	  sx = sxf >> 8;
+	  sptr = sline + sx * bytes_per_pixel;
 
           /* If we have enough space to do so, use bilinear interpolation.
              Otherwise, fall back to nearest neighbor for this pixel. */
@@ -453,27 +477,27 @@ scale_bilinear (struct grub_video_bitmap *dst, struct grub_video_bitmap *src)
               /* Fixed-point .8 numbers representing the fraction of the
                  distance in the x (u) and y (v) direction within the
                  box of 4 pixels in the source. */
-              int u = (256 * sw * dx / dw) - (sx * 256);
-              int v = (256 * sh * dy / dh) - (sy * 256);
+              unsigned u = sxf & 0xff;
+              unsigned v = syf & 0xff;
 
               for (comp = 0; comp < bytes_per_pixel; comp++)
                 {
                   /* Get the component's values for the
                      four source corner pixels. */
-                  int f00 = sptr[comp];
-                  int f10 = sptr[comp + bytes_per_pixel];
-                  int f01 = sptr[comp + sstride];
-                  int f11 = sptr[comp + sstride + bytes_per_pixel];
+                  unsigned f00 = sptr[comp];
+                  unsigned f10 = sptr[comp + bytes_per_pixel];
+                  unsigned f01 = sptr[comp + sstride];
+                  unsigned f11 = sptr[comp + sstride + bytes_per_pixel];
 
                   /* Count coeffecients. */
-                  int c00 = (256 - u) * (256 - v);
-                  int c10 = u * (256 - v);
-                  int c01 = (256 - u) * v;
-                  int c11 = u * v;
+                  unsigned c00 = (256 - u) * (256 - v);
+                  unsigned c10 = u * (256 - v);
+                  unsigned c01 = (256 - u) * v;
+                  unsigned c11 = u * v;
 
                   /* Interpolate. */
-                  int fxy = c00 * f00 + c01 * f01 + c10 * f10 + c11 * f11;
-                  fxy = fxy / (256 * 256);
+                  unsigned fxy = c00 * f00 + c01 * f01 + c10 * f10 + c11 * f11;
+                  fxy = fxy >> 16;
 
                   dptr[comp] = fxy;
                 }

  reply	other threads:[~2015-02-25 20:39 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-02-24  9:39 Image scaling performance Michael Zimmermann
2015-02-24  9:51 ` Vladimir 'phcoder' Serbinenko
2015-02-24 10:00   ` Michael Zimmermann
2015-02-24 11:27     ` Vladimir 'phcoder' Serbinenko
2015-02-24 11:47       ` Michael Zimmermann
2015-02-24 12:39         ` Vladimir 'phcoder' Serbinenko
2015-02-24 18:01           ` Michael Zimmermann
2015-02-24 18:22             ` Andrei Borzenkov
2015-02-25 16:20           ` Leif Lindholm
2015-02-25 15:45     ` Leif Lindholm
2015-02-25 16:23       ` Leif Lindholm
2015-02-25 18:38         ` Michael Zimmermann
2015-02-25 18:41           ` Vladimir 'phcoder' Serbinenko
2015-02-25 18:46             ` Michael Zimmermann
2015-02-25 18:56               ` Vladimir 'φ-coder/phcoder' Serbinenko
2015-02-25 19:28                 ` Michael Zimmermann
2015-02-25 20:39                   ` Vladimir 'φ-coder/phcoder' Serbinenko [this message]
2015-02-25 20:48               ` Vladimir 'φ-coder/phcoder' Serbinenko
2015-02-25 20:54                 ` Michael Zimmermann
2015-02-26 16:44               ` Vladimir 'φ-coder/phcoder' Serbinenko
2015-02-26 17:10                 ` Michael Zimmermann
2015-02-26 17:16                   ` Vladimir 'φ-coder/phcoder' Serbinenko
2015-02-26 20:27                     ` Michael Zimmermann
2015-02-26 20:35                       ` Vladimir 'φ-coder/phcoder' Serbinenko

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=54EE3309.4010605@gmail.com \
    --to=phcoder@gmail.com \
    --cc=grub-devel@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.