1188
|
1 The following is some discussion of just what's going on in viewgif, so that
|
|
2 future code maintainers and modifiers can have an easier time of it.
|
|
3
|
|
4 Viewgif's main purpose is to decode GIF files and turn them into images that
|
|
5 can be displayed on the CoCo. The obstacles to such display are:
|
|
6
|
|
7 1. GIF images can contain up to 256 colors, which are specified in RGB-888
|
|
8 form (i.e. eight bits of resolution along each axis of RGB space, a 3-D
|
|
9 space for colors whose basis consists of {red, green, blue}). The CoCo
|
|
10 can display at most 16 colors out of the 64 colors that live in RGB-222.
|
|
11
|
|
12 2. GIF images are compressed, using Lempel-Ziv compression (up to 12-bit
|
|
13 code length).
|
|
14
|
|
15 The second part is no big deal; in fact, the method used in viewgif is that
|
|
16 used in the early LZ compress program ported to OS-9/6809 a few years ago.
|
|
17 The first part is the one of major interest here.
|
|
18
|
|
19 Viewgif uses two methods to overcome the GIME's limitations:
|
|
20
|
|
21 1. Representing each color c[i] in the GIF image with a sum of two colors
|
|
22 c1[i] and c2[i], where c1[i] + c2[i] is approximately equal to c[i].
|
|
23 The c1[i] are displayed on one window and the c2[i] on another, and
|
|
24 viewgif alternates rapidly between the two windows. This gives us
|
|
25 additional resolution in RGB space.
|
|
26
|
|
27 2. Dithering, adding random noise to the displayed image. It may seem odd
|
|
28 that adding noise to an image should improve it, but in fact it does,
|
|
29 because it spreads out quantization error, and quantization error,
|
|
30 the error induced by going from a continuous quantity to a discrete
|
|
31 representation or, in our case, cutting down the resolution available,
|
|
32 is the big problem here. The easiest way to see it is to use a non-
|
|
33 dithering CoCo GIF viewer on an image with lots of shading--portraits
|
|
34 are best, because you know what color people are. (Starships could be
|
|
35 any color. :-) It will look like someone painted the person brick red
|
|
36 or yellow, or like whoever does the *USA Today* weather maps body painted
|
|
37 the person. Or maybe both!
|
|
38
|
|
39 The real guts of viewgif is that portion which determines what "dithering
|
|
40 factor" is the best for a given image. (You get to specify whether you
|
|
41 want one or two windows.) This is done in the function newwind(), in the
|
|
42 file viewgif.c, and the functions it calls (setmap() and approx1() and
|
|
43 approx2() in setmap.c). newwind() uses a binary search to find the largest
|
|
44 dithering factor less than or equal to the one given on the command line
|
|
45 (or the default, if you don't specify one) for which all the colors can
|
|
46 successfully be mapped to those available on the one or two windows available.
|
|
47 The dithering factor is "extended" in the negative direction by interpreting
|
|
48 a negative dithering factor as increased sloppiness about what is considered
|
|
49 "successful" mapping, so that this search always "succeeds." Viewgif will
|
|
50 show a positive "color tolerance" in this case.
|
|
51
|
|
52 (If you look at the function approx2(), the function that approximates the
|
|
53 the colors in the GIF CLUT (Color Look-Up Table) for the two-screen case,
|
|
54 you'll note that not all pairs of colors are considered as possible sums;
|
|
55 instead, only those pairs that are "near" one another are tried. I can only
|
|
56 guess at the reason behind this, but I think that it is done to prevent the
|
|
57 change between windows from being excessively noticeable. If you know
|
|
58 of a reference that describes the algorithms used here, it would be nice
|
|
59 to add that in the program comments.)
|
|
60
|
|
61 Scattered throughout the original code were some numbers like 85, 42, and
|
|
62 21. These have to do with the conversion from RGB888 to RGB222. The
|
|
63 maximum value for a color component in RGB888 is 255, and in RGB222 is 3,
|
|
64 so...to convert, one scales by a factor of 255 / 3 = 85. (For two screens,
|
|
65 this program uses 85 / 2, or 42.) toler() and toler2(), the functions that
|
|
66 determine how "close" two colors are, do their comparison in RGB888 space,
|
|
67 but consider all colors that would map to the goal color in the CoCo display
|
|
68 space equally close. (The upper bound on the dithering factor is the
|
|
69 "radius" of that neighborhood in RGB888 space.)
|
|
70
|
|
71 For those who saw the original viewgif, here are the changes I've made:
|
|
72
|
|
73 1. A header file, viewgif.h, has been added, with #defines that I hope will
|
|
74 give some idea where the magic values come from. We've also anticipated
|
|
75 attempts to port to OS-9/68000, though of course the low-level routines
|
|
76 are quite CoCo-specific.
|
|
77
|
|
78 2. The data have been restructured. Most notably, the rgbcolor and
|
|
79 cocoscreen types are attempts to collect related data in an intelligible
|
|
80 fashion, to allow iteration over screens or color components, to let
|
|
81 the common outer loop in setmap() be actual common code, and to avoid
|
|
82 needless replication of code in the loop that tries to extend just
|
|
83 one CLUT in approx2(). We hope we are anticipating generalization to
|
|
84 three or more windows, though that way lies madness, more memory usage,
|
|
85 and a combinatorial explosion in the approx3() function that one would
|
|
86 have to add.
|
|
87
|
|
88 3. Scalar global variables have been explicitly put on the direct page
|
|
89 for speed. (This has been made conditional for possible porting.)
|
|
90 The assembly-language functions have been changed to reflect this
|
|
91 placement as well, since Vaughn Cato tried to pick time-critical
|
|
92 functions for conversion to assembly language. Speaking of which,
|
|
93 we added comments showing addpixel() in C--not that it's tough to
|
|
94 figure out, but every little bit helps.
|
|
95
|
|
96 4. Some judiciously-placed register declarations have been added, again
|
|
97 for speed.
|
|
98
|
|
99 5. Subscripting has been turned into pointer arithmetic in various places.
|
|
100
|
|
101 6. Some functions have been moved into what seems to me to be more
|
|
102 appropriate files, considering who calls them and the general purpose
|
|
103 of the functions in the file. (Some more of this should be done; in
|
|
104 particular, functions not related to window manipulation should be
|
|
105 moved out of gifwin.c.)
|
|
106
|
|
107 7. A bug in what was setmap2() but is now approx2() was corrected. The
|
|
108 original was not toggling the "mode" variable, so that it would never
|
|
109 look at possible sums extending the larger CLUT.
|
|
110
|
|
111 8. approx2() (formerly setmap2()) has added an array in which we recall
|
|
112 the results of the nearcolor() function, rather than calling it lots
|
|
113 of times. (I think this is the big win for speeding up the analysis
|
|
114 phase.)
|
|
115
|
|
116 9. We added a -? option.
|
|
117
|
|
118 10. We added a -z option, that overwrites the global color map after
|
|
119 replacing unused colors with some color that is used. CAUTION:
|
|
120 this overwrites the whole global color map, and said color map is
|
|
121 manipulated in other ways via the -g, -g2, and -b options. You
|
|
122 can lose information if you combine -z with those options, and
|
|
123 perhaps we should prevent them from being used together.
|
|
124
|
|
125 There is still more that can be done to speed things up.
|
|
126
|
|
127 1. It should be possible to speed up the decompression. Alas, the obvious
|
|
128 way, i.e. going with a hash table rather than a tree, may eat more memory
|
|
129 than we can afford; nevertheless, it is worth investigating.
|
|
130
|
|
131 2. It may be worth trying putting two scan lines at a time instead of one,
|
|
132 to cut system call overhead. One would have to allocate get/put buffers
|
|
133 for each window to do this. It's not clear whether it would be a win
|
|
134 for interleaved images.
|
|
135
|
|
136 3. This version of viewgif shares the problems of the program it is based
|
|
137 on. (Indeed, it would be surprising if it didn't!) Aside from smarter
|
|
138 mapping of colors, which I fear would require two passes over the GIF
|
|
139 file, the main one concerns smarter handling of aspect ratios. Most
|
|
140 likely, since the current GIF specification doesn't say beans about
|
|
141 aspect ratio, one will have to let the user tweak the aspect ratio
|
|
142 on the command line.
|
|
143
|
|
144 4. The VEF files generated may not be quite correct; vefprt seems to emit
|
|
145 a few lines of junk before putting out the rest of the image properly.
|
|
146 This behavior seems to be the same for the old and the new versions of
|
|
147 the program.
|
|
148
|
|
149 5. The code that waits for the user to type a character could be changed
|
|
150 to use the SS_SSIG setstat along with an intercept() routine, to cut
|
|
151 system overhead.
|