GIF target

OK, I need some more eyes on this one… I’m looking at the GIF target renderer. I believe the conventional wisdom says that the lower the render quality, the better the render. And, in the GIF module,

if(get_quality()>5) lossy=true; else lossy=false;
would imply that a quality of 3, lossy=false, i.e. no loss of quality.
Yet rendering with quality = 6 gives better results than with Quality =3.
boxq6.gif
boxq3.gif
Dooglus did some investigation into this, and suggested a patch, but the patch didn’t work with dithering. And it looks to me like dithering is defined as true, and never changed, although I’d expect it to be initially false, and set only if we were attempting to render a picture with a pallette larger than 256 colours. What am I missing?

So it looks like the quick work around is to use a quality level greater than 5 (i.e. 6 or more).

I’m trying to understand what’s going on here more…

[code] // If the pixel is the same as the one that
// is already there, then we should make it
// transparent
if(build_off_previous)
{
if(lossy)
{

				// Lossy
				if(
					abs( ( iter->color-prev_palette[prev_frame[cur_scanline][i]-1].color ).get_y() ) > (1.0/16.0) ||

// abs((int)value-(int)prev_frame[cur_scanline][i])>2||
// (value<=2 && value!=prev_frame[cur_scanline][i]) ||
(imagecount%iframe_density)==0 || imagecount==desc.get_frame_end()-1 ) // lossy version
prev_frame[cur_scanline][i]=value;
else
{
prev_frame[cur_scanline][i]=value;
value=0;
}
}
else
{
// lossless version
if(value!=prev_frame[cur_scanline][i])
prev_frame[cur_scanline][i]=value;
else
value=0;
}
}
else
prev_frame[cur_scanline][i]=value;[/code]

So, obviously “build_off_previous” controls whether we can use transparency or not.
If it’s ‘lossy’ (i.e. quality is 6 or greater) then there’s a series of criteria that determine whether we can set the pixel transparent or not. The first term is interesting -

abs( ( iter->color-prev_palette[prev_frame[cur_scanline][i]-1].color ).get_y() ) > (1.0/16.0)

I don’t see why it’s measured against 1/16. I hope the compiler is not making us calculate that each time. It looks like it’s checking the color is non-zero. The next term not commented out,

(imagecount%iframe_density)==0 appears to be checking for iframes. We don’t want them to be transparent :slight_smile:
The last term,

imagecount==desc.get_frame_end()-1 ) seems to be checking for the last frame. If any of those conditions are met, then we keep the value. Else we make it transparent.
If, on the other hand, quality is 5 or less, we take the lossless route, and the pixel is only transparent if it’s identical to the previous frame pixel for that location.
And then to round it out, if we don’t build from the previous frame, we need to store the existing value as the previous value.