Re: [PATCH] A lost patch for bug 306029



On Friday 05 May 2006 15:56, Matthias Clasen wrote:
> On 5/5/06, Denis Vlasenko <vda ilport com ua> wrote:
> > Hello gtk'ers,
> >
> > I was looking through my old bookmarks
> > and found this one:
> >
> > http://bugzilla.gnome.org/show_bug.cgi?id=306029
> >
> > I filed that one. Seems like it was not noticed yet,
> > after one year.
> >
> > gtk-2.8.13's  pixops/pixops.c::process_pixel is still
> > the same and can still be optimized.
> >
> > Please apply attached.
> 
> process_pixel is simply the wrong function to optimize. It is
> used only for the edge cases.

I use gqview a lot, and it uses gdk_pixbuf_scale_simple
(indirectly, via gdk_pixbuf_new_from_file_at_size)
for image scaling.

This eventually leads to call to pixops_process(), see below.
Optimizing it noticeably affects performance
when gqview renders 11477x7965 px sized images. ;)

Hey, and BTW, thanks for fixing the
http://bugzilla.gnome.org/show_bug.cgi?id=305894 !

Please apply the pixops_process patch.
--
vda

GdkPixbuf *
gdk_pixbuf_scale_simple (...)
{
  GdkPixbuf *dest;

  g_return_val_if_fail (src != NULL, NULL);
  g_return_val_if_fail (dest_width > 0, NULL);
  g_return_val_if_fail (dest_height > 0, NULL);

  dest = gdk_pixbuf_new (GDK_COLORSPACE_RGB, src->has_alpha, 8, dest_width, dest_height);
  if (!dest)
    return NULL;

  gdk_pixbuf_scale (src, dest,  0, 0, dest_width, dest_height, 0, 0,
                    (double) dest_width / src->width,
                    (double) dest_height / src->height,
                    interp_type);

  return dest;
}

void
gdk_pixbuf_scale (...)
{
  g_return_if_fail (src != NULL);
  g_return_if_fail (dest != NULL);
  g_return_if_fail (dest_x >= 0 && dest_x + dest_width <= dest->width);
  g_return_if_fail (dest_y >= 0 && dest_y + dest_height <= dest->height);

  offset_x = floor (offset_x + 0.5);
  offset_y = floor (offset_y + 0.5);

  _pixops_scale (dest->pixels + dest_y * dest->rowstride + dest_x * dest->n_channels,
                 dest_x - offset_x, dest_y - offset_y,
                 dest_x + dest_width - offset_x, dest_y + dest_height - offset_y,
                 dest->rowstride, dest->n_channels, dest->has_alpha,
                 src->pixels, src->width, src->height,
                 src->rowstride, src->n_channels, src->has_alpha,
                 scale_x, scale_y, (PixopsInterpType)interp_type);
}

void
_pixops_scale (guchar        *dest_buf,
               int            render_x0,
               int            render_y0,
               int            render_x1,
               int            render_y1,
               int            dest_rowstride,
               int            dest_channels,
               gboolean       dest_has_alpha,
               const guchar  *src_buf,
               int            src_width,
               int            src_height,
               int            src_rowstride,
               int            src_channels,
               gboolean       src_has_alpha,
               double         scale_x,
               double         scale_y,
               PixopsInterpType  interp_type)
{
  if (interp_type == PIXOPS_INTERP_NEAREST)
    {
      pixops_scale_nearest (...)
      return;
    }

  filter.overall_alpha = 1.0;
  make_weights (&filter, interp_type, scale_x, scale_y);

  if (filter.x.n == 2 && filter.y.n == 2 && dest_channels == 3 && src_channels == 3)
    {
#ifdef USE_MMX
      if (found_mmx)
        line_func = scale_line_22_33_mmx_stub;
      else
#endif
        line_func = scale_line_22_33;
    }
  else
    line_func = scale_line;

  pixops_process (dest_buf, render_x0, render_y0, render_x1, render_y1,
                  dest_rowstride, dest_channels, dest_has_alpha,
                  src_buf, src_width, src_height, src_rowstride, src_channels,
                  src_has_alpha, scale_x, scale_y, 0, 0, 0, 0, 0,
                  &filter, line_func, scale_pixel);

  g_free (filter.x.weights);
  g_free (filter.y.weights);
}



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]