On Mon, Feb 8, 2016 at 10:06 AM, <spit...@gmail.com> wrote: > From: Bill Spitzak <spit...@gmail.com> > > The intention here is to produce approximately the same number of samples for > each filter size (ie width*samples is the same). This means the caller can > pass a constant rather than a different value for each size. To avoid conflict > with existing code, negative numbers are used to indicate that -n samples are > needed at size==1. > > For larger size the width of a BOX.BOX filter is used (the number of samples > is scaled by 2/(size+1)). This may be more than are needed for other filters > which increase in width faster. > > For smaller filters it seems 1/size would be needed to keep the same number > of samples on the high-frequency portions. But it appears to be acceptable to > reduce them, I used 2/((size+1)*size) which makes about 1/2 as many samples > as size approaches zero. > > These functions were arrived at experimentally by testing for visible > artifacts in the scaling of the zone plate image. > > The computed value is then rounded up to the next power of 2 to get the > subsample_bits. > > The scale demo is modified to allow these negative numbers, and initially > uses -12. > > v11: Put subsample calculation in it's own function > Minor changes to comments > v12: More info in the commit message > > Signed-off-by: Bill Spitzak <spit...@gmail.com> > --- > demos/scale.ui | 5 +++-- > pixman/pixman-filter.c | 33 +++++++++++++++++++++++++++++++++ > 2 files changed, 36 insertions(+), 2 deletions(-) > > diff --git a/demos/scale.ui b/demos/scale.ui > index b62cbfb..1e77f56 100644 > --- a/demos/scale.ui > +++ b/demos/scale.ui > @@ -24,12 +24,12 @@ > <property name="page_size">10</property> > </object> > <object class="GtkAdjustment" id="subsample_adjustment"> > - <property name="lower">0</property> > + <property name="lower">-256</property> > <property name="upper">12</property> > <property name="step_increment">1</property> > <property name="page_increment">1</property> > <property name="page_size">0</property> > - <property name="value">4</property> > + <property name="value">-12</property> > </object> > <object class="GtkWindow" id="main"> > <child> > @@ -321,6 +321,7 @@ > <object class="GtkSpinButton" > id="subsample_spin_button"> > <property name="visible">True</property> > <property > name="adjustment">subsample_adjustment</property> > + <property name="value">-12</property> > </object> > <packing> > <property name="left_attach">1</property> > diff --git a/pixman/pixman-filter.c b/pixman/pixman-filter.c > index 56e25b1..e57b154 100644 > --- a/pixman/pixman-filter.c > +++ b/pixman/pixman-filter.c > @@ -346,6 +346,37 @@ filter_width (pixman_kernel_t reconstruct, > pixman_kernel_t sample, double size) > return ceil (filters[reconstruct].width + size * filters[sample].width); > } > > +/* Turn negative number into approximately ceil(ln2(-n / size)) > + * Actual function is somewhat non-linear. For size > 1 it uses > + * the width/2 of BOX.BOX instead of size. For size < 1 it reduces > + * the samples by 1/2 as size approaches zero. > + */ > +static int > +subsample_bits (int subsample_bits, pixman_kernel_t sample, double size) > +{ > + if (subsample_bits < 0) > + { > + /* The intention was to do -n / size rounded up to the next power of > 2, > + but this non-linear function seems to work better. For large size > + it is the width of the BOX.BOX filter. For small size it reduces > + samples by 2 at maximum. */ > + double desired_samples = -subsample_bits; > + if (sample == PIXMAN_KERNEL_IMPULSE) > + ; /* For x.IMPULSE no scaling is done */ > + else if (size >= 1.0) > + desired_samples *= 2.0 / (size + 1.0); > + else > + desired_samples *= 2.0 / ((size + 1.0) * size); > + if (desired_samples <= 1.0) > + subsample_bits = 0; > + else if (desired_samples >= 256.0) > + subsample_bits = 8; > + else > + subsample_bits = (int) ceil (log2(desired_samples) - .01); > + } > + return subsample_bits; > +} > + > /* Create the parameter list for a SEPARABLE_CONVOLUTION filter > * with the given kernels and size parameters > */ > @@ -367,9 +398,11 @@ pixman_filter_create_separable_convolution (int > *n_values, > int width, height; > > width = filter_width (reconstruct_x, sample_x, sx); > + subsample_bits_x = subsample_bits (subsample_bits_x, sample_x, sx); > subsample_x = (1 << subsample_bits_x); > > height = filter_width (reconstruct_y, sample_y, sy); > + subsample_bits_y = subsample_bits (subsample_bits_y, sample_y, sy); > subsample_y = (1 << subsample_bits_y); > > *n_values = 4 + width * subsample_x + height * subsample_y; > -- > 1.9.1 > > _______________________________________________ > Pixman mailing list > Pixman@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/pixman
This patch is: Acked-by: Oded Gabbay <oded.gab...@gmail.com> _______________________________________________ Pixman mailing list Pixman@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/pixman