Re: [Pixman] [patch] Gradient dithering into pixman

2018-03-27 Thread Marc Jeanmougin


On 03/27/2018 07:45 PM, Bill Spitzak wrote:
> Quick look at the patch and it seems like this will work, though it is a
> random dither. You might get much better compression of .png with a
> patterned dither. I've also had good luck with pseudo-error-diffusion.
> You keep in static memory an accumulated error (per color, but not
> really depending on the location of the pixel) and that is the threshold
> for the random number. This produces a bit more patterning than a
> straight random generator. You might also try it with no random number
> generator at all, but you have to preserve the accumulated error so that
> solid areas that are an integer don't reset it so each adjacent line
> gets the same pattern.

I implemented the accumulated error dithering (attached file, can be
applied over the previous 0001 patch). It greatly improves PNG
compression ratio for purely horizontal gradients (approximately +15%
instead of +1%, in filesize), but produces small artifacts (it's
still way better than no dithering of course, they are almost invisible)
without a random accumulated error at the start of lines (which
increases a lot the filesize).


> May want to call the "on" setting PIXMAN_DITHERING_GOOD. On the
> assumption that anybody who wants it on is happy with "good" dithering,
> and that they may not want to pay for the slowness of "best" dithering.

Considering the prng used, the slowness is almost negligible ("good
except for the small stripes" dithering may in fact be slower)

-- 
Marc
From 85aa2a84e74f3079796ec4686c4fa2acf6c2e93f Mon Sep 17 00:00:00 2001
From: Marc Jeanmougin 
Date: Tue, 27 Mar 2018 21:36:10 +0200
Subject: [PATCH 2/2] Adds PIXMAN_DITHERING_GOOD with diffusion of accumulated
 error

Signed-off-by: Marc Jeanmougin 
---
 pixman/pixman-gradient-walker.c | 21 -
 pixman/pixman-image.c   |  2 +-
 pixman/pixman.h |  1 +
 3 files changed, 22 insertions(+), 2 deletions(-)

diff --git a/pixman/pixman-gradient-walker.c b/pixman/pixman-gradient-walker.c
index dbd7a92..1311fa4 100644
--- a/pixman/pixman-gradient-walker.c
+++ b/pixman/pixman-gradient-walker.c
@@ -52,7 +52,7 @@ _pixman_gradient_walker_init (pixman_gradient_walker_t *walker,
 
 walker->need_reset = TRUE;
 walker->dithering = gradient->dithering;
-walker->prng_state = rand();
+walker->prng_state = (gradient->dithering == PIXMAN_DITHERING_BEST) ? rand() : 0;
 }
 
 static void
@@ -179,6 +179,7 @@ _pixman_dither (pixman_gradient_walker_t *walker, float *in)
 {
 float f_rem = (*in-(float)((int)(*in)));
 uint32_t i_rem = f_rem * 4294967296.;
+uint32_t color_state;
 
 switch (walker->dithering)
 {
@@ -190,6 +191,24 @@ _pixman_dither (pixman_gradient_walker_t *walker, float *in)
 return *in +1;
 else
 return *in;
+
+case PIXMAN_DITHERING_GOOD:
+/* we use prng_state to keep four 8-bit values of errors to propagate */
+color_state = walker->prng_state & 0xff;
+i_rem >>= 24; /*keep 8 most significant bits*/
+color_state+=i_rem;
+if (color_state >= 256){
+color_state -= 256;
+/*rotate*/
+walker->prng_state = (walker->prng_state >> 8) | (color_state<<24);
+return *in+1;
+}
+else {
+/*rotate*/
+walker->prng_state = (walker->prng_state >> 8) | (color_state<<24);
+return *in;
+}
+
 case PIXMAN_DITHERING_NONE:
 default:
 /* round */
diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c
index 75f168e..61e6988 100644
--- a/pixman/pixman-image.c
+++ b/pixman/pixman-image.c
@@ -102,7 +102,7 @@ _pixman_init_gradient (gradient_t *  gradient,
 gradient->n_stops = n_stops;
 
 gradient->common.property_changed = gradient_property_changed;
-gradient->dithering = PIXMAN_DITHERING_NONE;
+gradient->dithering = PIXMAN_DITHERING_GOOD;
 
 return TRUE;
 }
diff --git a/pixman/pixman.h b/pixman/pixman.h
index 5ac0db6..2422eb8 100644
--- a/pixman/pixman.h
+++ b/pixman/pixman.h
@@ -319,6 +319,7 @@ typedef enum
 typedef enum
 {
 PIXMAN_DITHERING_NONE,
+PIXMAN_DITHERING_GOOD,
 PIXMAN_DITHERING_BEST
 } pixman_dithering_t;
 
-- 
2.16.2



signature.asc
Description: OpenPGP digital signature
___
Pixman mailing list
Pixman@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pixman


Re: [Pixman] [patch] Gradient dithering into pixman

2018-03-27 Thread Bill Spitzak
I get it, the dithering is turned on/off with a Cairo control. I thought
you were suggesting that it is turned off if the destination is an image.

Quick look at the patch and it seems like this will work, though it is a
random dither. You might get much better compression of .png with a
patterned dither. I've also had good luck with pseudo-error-diffusion. You
keep in static memory an accumulated error (per color, but not really
depending on the location of the pixel) and that is the threshold for the
random number. This produces a bit more patterning than a straight random
generator. You might also try it with no random number generator at all,
but you have to preserve the accumulated error so that solid areas that are
an integer don't reset it so each adjacent line gets the same pattern.

May want to call the "on" setting PIXMAN_DITHERING_GOOD. On the assumption
that anybody who wants it on is happy with "good" dithering, and that they
may not want to pay for the slowness of "best" dithering.


On Tue, Mar 27, 2018 at 2:20 AM, Marc Jeanmougin  wrote:

> Hi,
>
> Le 27/03/2018 à 02:04, Søren Sandmann a écrit :
> > A long time ago I wrote this:
> >
> > https://lists.freedesktop.org/archives/pixman/2012-July/002175.html
> >
> > about how dithering could be added to pixman. The basic idea is that
> > "dithering" is a property of the destination image, not of the
> > gradient.  I still think this is the right way to do it.
>
> Thank you for your input. Would it be possible to use your preferred way
> of doing it to my patch ?
>
> Le 27/03/2018 à 03:47, Bill Spitzak a écrit :
> > I don't understand why you would want to disable it when writing .png
> > files. There will be banding in the .png file, which I would think is
> > worse than the increased size.
> Depends. In many cases there is no visible banding, and some people may
> not want a x100 filesize increase for it (for files that are entirely
> made of gradients).
>
> > Also kind of fools the user if they did not look at the .png file and
> > only at InkScape's display.
> We already have such differences for filter quality, and of course it
> would be possible to switch it in the display windows for previewing.
>
> --
> Marc
>
>
___
Pixman mailing list
Pixman@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pixman


Re: [Pixman] [patch] Gradient dithering into pixman

2018-03-27 Thread Marc Jeanmougin
Hi,

Le 27/03/2018 à 02:04, Søren Sandmann a écrit :
> A long time ago I wrote this:
>
>     https://lists.freedesktop.org/archives/pixman/2012-July/002175.html
>
> about how dithering could be added to pixman. The basic idea is that
> "dithering" is a property of the destination image, not of the
> gradient.  I still think this is the right way to do it.

Thank you for your input. Would it be possible to use your preferred way
of doing it to my patch ?

Le 27/03/2018 à 03:47, Bill Spitzak a écrit :
> I don't understand why you would want to disable it when writing .png
> files. There will be banding in the .png file, which I would think is
> worse than the increased size.
Depends. In many cases there is no visible banding, and some people may
not want a x100 filesize increase for it (for files that are entirely
made of gradients).

> Also kind of fools the user if they did not look at the .png file and
> only at InkScape's display.
We already have such differences for filter quality, and of course it
would be possible to switch it in the display windows for previewing.

-- 
Marc

___
Pixman mailing list
Pixman@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pixman