*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!

**References**:**gdk_pixbuf scaling - variable interplation tables***From:*Brian Cameron

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