[comp.graphics] QRT 1.5 problems?

valdis@alchemy.mcs.clarkson.edu (& Kletnieks) (03/29/89)

I just got QRT 1.5 off the net, and had the following two things
happen to me:

1) The 'sphere' type seems to have problems, it leaves droppings that look
kind of like streamers waving in the breeze floating across the picture.
I have a stripped-down 'Mirrors.qrt' (with just the ground pattern and
one light and one sphere) that demonstrates this...

2) the 'qrt2gif' pulls down a 'segmentation fault' in clr_quantize when
dealing with a VERY large pixmap (1600x1280).

Both are under SunOS 4.0.1.  I have used the Sun 'cc' and gnu cc 1.30 AND
1.34, all to no avail.

Anybody seen these before, got any ideas how to fix them?

				Valdis Kletnieks
				Sr. Systems Programmer
				Clarkson University

valdis@alchemy.mcs.clarkson.edu (& Kletnieks) (03/31/89)

I tracked down one problem - in qrt2gif.c, near line 263, there was a
hard-coded 'unsigned char r_vals[1024], g_vals[1024], b_vals[1024];'

This of course choked up pretty good when you attacked a file more
than 1024 wide.  Increasing the value cured the qrt2gif problem.

Also, it looks like the 'sphere' object isn't the offender, as the
'Piano.QRT' file has some problems as well..  I just wasn't able
to see it clearly at the small testing sized I was using...

The really interesting part is that the third (?) stripe back seems 
to wrap up off the floor, come forward, make a big blob right over
the left leg of the piano, cross along just under the keyboard to
the RIGHT leg, make a blob there, and send a arm up the post holding up
the tap of the piano.  The first stripe goes across where it should, except
that the width is nonconstant, and sometimes zero.  The 'closer' edge is
a straight line, but the far edge meanders in and out.  It seems to hit its
widest where the stripe goes closest to the two legs of the piano.

Anybody have any ideas?  It seems almost like some objects act like
'blotters', atracting patterns...

				Valdis Kletnieks

koren@hpfelg.HP.COM (Steve Koren) (04/01/89)

> The really interesting part is that the third (?) stripe back seems 
> to wrap up off the floor, come forward, make a big blob right over
> the left leg of the piano, cross along just under the keyboard to
> the RIGHT leg, make a blob there, and send a arm up the post holding up
> the tap of the piano.  The first stripe goes across where it should, except

    I dunno, this sounds pretty bizarre!  Needless to say I've never
seen this behavior.  You might try running some really simple images to
isolate the cause of the problem.  For example, run just a simple sphere
with no other objects.  Do you still get your "blobs"?  If so, something
is seriously fubar.  Might the problem be your post processor or image
display program?  I've compiled and run QRT under 3 different UNIXs
(or is that UNIXI) with no problems.

        - steve

nl0s+@andrew.cmu.edu (Nathan James Loofbourrow) (04/05/89)

valdis@alchemy.mcs.clarkson.edu (& Kletnieks) writes:
>1) The 'sphere' type seems to have problems, it leaves droppings that look
>kind of like streamers waving in the breeze floating across the picture.

Your problem comes in having changed CNUM to 256 in qrt.h. Change it to 255.
(The comment describing it as "shades/color" is not entirely correct.)
This should apply to Erik's problem as well.

When in doubt, go back to your unmodified version!


------------------------------------------------------------
Nathan Loofbourrow
ARPA: nl0s+@andrew.cmu.edu
BITNET: nl0s%andrew@CMCCVB
UUCP: ...!{psuvax1,harvard}!andrew.cmu.edu!nl0s+
------------------------------------------------------------
"Sometimes, the truth hurts...
 Other times it causes a slight tingling sensation."
                                     - Chris Devlin
------------------------------------------------------------

valdis@alchemy.mcs.clarkson.edu (& Kletnieks) (04/06/89)

After much jumping up and down, I finally found something that
*seems* to fix my problems with qrt 1.5.

Something to note here is that I was using 'qrt2gif' to dither the 24-bit
color down to black&white.  I suspect that people dithering down to 256
or even 16 colors probably would not notice this, as they would be
getting 1/16 or 1/256 the dither error on each pixel and not get bit
by this...

In the qrt2gif program, there is kept a pair of 'error arrays' (cerr and lerr).
Now, I must admit that I speak out of ignorance as to EXACTLY how the
Floyd-Steinberg code works, but it seemed "morally wrong" that the
arrays keep getting added into and never cleared.  What would happen is
it would descend down the image, totalling (for instance) all the errors
from a 'green' ball to the 'gray' it was outputting.  Then, having passed
over that area, it would hit (for instance) a yellow area, and try to
re-compensate for the totalled up errors.

The reason it seemed to act like 'blotter paper' was simply that it would
tend to exhibit this backlash when moving from one object to another (or
actually when moving from one color area to another).  The 'streamer'
effect was because once ONE pixel got warped, the i+1 and i+2 terms would
tend to propagate it left and right on suceeding raster lines.  Eventually,
the error would have been 'expended' and it would fade out at some  pixel,
and then the correct value would be propagated left and right.

The basic fix was to apply an exponential decay, so that it would tend to
'forget' the error values more than a few pixels away (It only looks one
or two pixels left or right, having memory of 300 pixels above sounds
fishy to me).

Now, having discussed this, here's how I fixed it:

Original code (near line 826 of qrt2gif.c):

 Bitmap_Plot( bit, i, j, idx );
                }


                if( floyd ) {
                        /* Swap error vectors */
                        terr = lerr; lerr = cerr; cerr = terr;
                }

                }
                if( feof( fp ) )

New code:

 Bitmap_Plot( bit, i, j, idx );
                }


                if( floyd ) {
                        int jello;
                        /* Swap error vectors */
                        for (jello=0;jello<xres+2;jello++) {
                                cerr[RD][jello] >>= 1;
                                cerr[GR][jello] >>= 1;
                                cerr[BL][jello] >>= 1;
                        }
                        terr = lerr; lerr = cerr; cerr = terr;
                }

                }
                if( feof( fp ) )


Hope this helps, feel free to flame me if I totally mis-understood what
was going on...

				Valdis Kletnieks