A simple problem


#1

I have a simple problem, but I can’t figure it out.

I want to change this image

0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0

into

0 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0 0 0 1 1 1

So the output flips back and forth between 1 and 0 everytime the input encounters a ‘1’

I’ve tried using ‘fill’ but I’m having no luck.

Help! :slight_smile:


#2

I think a xor should do that (may need to change “init” to “begin” on latest gmic):

f. "init(X=0);X=xor(X,i)"


#3

Thanks!

That does the trick.


(G'MIC staff) #4

I’l suggest adding a > at the beginning of the expression:

f. ">begin(X=0);X = xor(X,i)"

because if your image becomes quite large, there is a risk the command fill decides to enable multi-threaded evaluation, and in this case, you cannot be sure the evaluation follows a scanline order.

For instance, this simple example exhibit a difference on my machine :

$ gmic 400,400,1,1,"begin(off=0);off++" 400,400,1,1,">begin(off=0);off++"

which results in

(the first image has been filled using 4 cores simultaneously, so not in a scanline order).
The second image is correct, using > ensures you evaluate in a scanline order.


#5

Thanks David.

For my purposes I want each line to be evaluated separately. So I was using ‘split y’, because it is what I know.

Of course, solving this problem has only revealed more problems! :wink:


#6

Now I’m really curious about what you’re making :thinking:
Perhaps best kept a secret, lest I be drawn in!


(G'MIC staff) #7

I wouldn’t suggest using split y, as line by line evaluation can be done also in the fill command :wink:

  f ">!x?(X = i):(X = xor(X,i))"

#8

I’m working on a pre-processor/lossy PNG optimiser.

Dithering is not very good for PNG compression but does really help with visual quality, so I am producing dither that is only horizontal lines. It’s a compromise between compression and visual quality.

The issue I am having is that there are discontinuities in the dither pattern cased when the error between the quantised image and the original jumps from a big positive value to a big negative value.

What you get is effectively a change from white lines on black to black lines on white. Detecting the change is easy enough (there a big step in the error) and then it just a matter of switching he dither pattern so all the lines are lined up.

That works great horizontally, but it introduces problems vertically because in some places you have you get two dither lines of the same colour on top of each other creating 2 pixel lines instead of 1 pixel lines. Oh well.

So that’s the story.


#9

That’s interesting enough to me that I’ll have to deliberately avoid thinking about it :slight_smile:
Hope you get it working, good luck!


#10

Well I’ve managed to get ‘better’ results by manipulating the error signal. Unfortunately, while it looks better on smooth areas, it makes the compression slightly worse :frowning:


#11

Nevermind. The solution was dead simple and it works a treat.

  1. Create an indexed image with accompanying palette
  2. find the absolute error between the original and the indexed image
  3. Create two new images one with the absolute error added to the original and one with is subtract from the original
  4. Use the original palette to index the two new images. This essentially makes one image errors are rounded down and one where they are rounded up
  5. Use a mask to interlace the images.

Solved