Re: gdk_pixbuf scaling - variable interplation tables
- From: Matthias Clasen <maclas gmx de>
- To: Brian Cameron <Brian Cameron sun com>
- Cc: gtk-devel-list gnome org, brian cameron sun com
- Subject: Re: gdk_pixbuf scaling - variable interplation tables
- Date: Wed, 8 Jan 2003 14:10:49 +0100 (MET)
>
> 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]