Re: gdk_pixbuf scaling - variable interplation tables



> 
> gdk_pixbuf gurus:
> 
> Please cc: me on any response since I'm not on this alias.
> 
> I am currently working to make gdk-pixbuf work faster on Solaris.
> We are making use of the mediaLib library which is a front-end to
> the VIS multimedia acceleration UltraSparc chipset.
> 
> I notice that the various scaling functions use variable size
> interpolation tables when the interpolation type is PIXOPS_INTERP_TILES,
> PIXOPS_INTERP_BILINEAR, or PIXOPS_INTERP_HYPER.  Using PIXOPS_INTERP_HYPER
> as an example, it calls bilinear_make_weights.  In this function the
> table size is calculated by the following lines
> 
>   int n_x = ceil(1/x_scale + 2.0);
>   int n_y = ceil(1/y_scale + 2.0);
> 
> So, when scaling down, the table gets larger.  It obviously makes sense
> for the interpolation tables to get larger when the scaling factors get
> smaller.  This makes sure that all source pixels contribute to the
> resulting image when the scaling factor is <= 1.

Here is a bug tracking the issue that these tables get huge with small
scaling factors:
http://bugzilla.gnome.org/show_bug.cgi?id=80925

> 
> The mediaLib functions also support the ability to use variable sized
> interpolation tables.  However, there is a difference.  The mediaLib
> functions use 2 1-dimentional tables where the gdk_pixbuf functions
> use a single 2-dimensional table.
> 
> In tile_make_weights and bilinear_make_fast_weights, the 2-dimensional
> tables used by gdk_pixbuf are simply two 1-dimensional tables multiplied
> together and are trivial to separate for use with mediaLib.
> 
> However, things are not so easy for bilinear_make_weights used by
> PIXOPS_INTERP_HYPER.  This function seems a bit of a puzzle to me.
> 
> It contains the following for loop:
> 
> --code example start--
> 
>   for (i_offset=0; i_offset<SUBSAMPLE; i_offset++)
>     for (j_offset=0; j_offset<SUBSAMPLE; j_offset++)
>       {
>         int *pixel_weights = filter->weights + ((i_offset*SUBSAMPLE) +
> j_offset)
>  * n_x * n_y;
>         double x = (double)j_offset / SUBSAMPLE;
>         double y = (double)i_offset / SUBSAMPLE;
>         int i,j;
>         int total = 0;
> 
>         for (i = 0; i < n_y; i++)
>           for (j = 0; j < n_x; j++)
>             {
>               double w;
>               int weight;
> 
>               w = bilinear_quadrant  (0.5 + j - (x + 1 / x_scale), 0.5 + j
> - x,
> 0.5 + i - (y + 1 / y_scale), 0.5 + i - y);
>               w += bilinear_quadrant (1.5 + x - j, 1.5 + (x + 1 / x_scale)
> - j,
> 0.5 + i - (y + 1 / y_scale), 0.5 + i - y);
>               w += bilinear_quadrant (0.5 + j - (x + 1 / x_scale), 0.5 + j
> - x,
> 1.5 + y - i, 1.5 + (y + 1 / y_scale) - i);
>               w += bilinear_quadrant (1.5 + x - j, 1.5 + (x + 1 / x_scale)
> - j,
> 1.5 + y - i, 1.5 + (y + 1 / y_scale) - i);
>               weight = 65536 * w * x_scale * y_scale * overall_alpha +
> 0.5;
>               *(pixel_weights + n_x * i + j) = weight;
>               total += weight;
>             }
> 
>         correct_total (pixel_weights, n_x, n_y, total, overall_alpha);
>       }
> 
> 
> --code example end--
> 
> It might not be possible to make 2 1-d tables that exactly correspond to
> the table as built above.  The correct_total function is confusing to
> me, and the fact that i/j/x/y are all used to compute the value "w"
> (which in turn is used to compute weight and then  pixel_weights)
> makes me suspect that this interpolation table is not simply two 1-d
> tables multiplied together. 

correct_total was introduced to fix rounding errors. It is discussed in the
thread starting here:
http://mail.gnome.org/archives/gtk-devel-list/2002-February/msg00238.html

> 
> If I'm wrong in that assumption, and it really can be broken down into
> two 1-d tables, I'd appreciate it if anyone could clarify what I am 
> missing.  Otherwise, I would appreciate it if someone could explain to me
> exactly what the interpolation table is trying to accomplish and whether
> a reasonable approximation can be accomplished via two 1-d tables.
> 
> Lastly, I suppose it might be possible that this function is generating
> a more complicated interpolation table than is really needed.  If it is
> possible to replace this table with a simpler table that is similarly 
> effective, uses less processing time, and fits better with the
> two 1-d table approach required by mediaLib, then everyone gains.
> 
> I suggest this last idea because it obviously saves time to use two
> 1-d tables rather than building a 2-d table.  If gdk moved to this 
> model as well, then it would not be necessary to spend time building
> the full 2-d table.  pixops_process could just multiply the two 1-d
> tables together when it has calculate "run_weights" anyway.
> 
> I would be happy to do the work to make pixops.c use 1-d tables 
> that are multiplied together rather than building the current 2-d
> tables, if someone can help me unravel bilinear_make_weights (or
> help me to come up with a reasonable approximation that fits in 
> the 2 1-d table approach).
> 
> Thanks!
> 
> Brian
> 
> _______________________________________________
> gtk-devel-list mailing list
> gtk-devel-list gnome org
> http://mail.gnome.org/mailman/listinfo/gtk-devel-list
> 

-- 
+++ GMX - Mail, Messaging & more  http://www.gmx.net +++
NEU: Mit GMX ins Internet. Rund um die Uhr für 1 ct/ Min. surfen!




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