sminkin@bbn.com (Scott Minkin) (12/08/89)
Greetings, I've recently written a program to display GIF files on DEC VT340 terminals using color sixel. The 16 color GIF files come out beutifully, but I don't really have a scheme for converting 256 colors down to 16 (which is the limitation of the VT340). Is there a preferred algorithm for doing this? Averaging RGB values? Picking the 16 most commonly used colors and trying to map the remaining colors to them? I've seen the source code to some other GIF decoders which handle the stripping of color bits, but that seems to deal with devices with a limited resolution for each color, rather than a limited number of colors. Of course, the possibility that I'm misunderstanding this issue is also a distinct possibility. Any friendly advice would be greatly appreciated. Thanks. Scott sminkin@bbn.com
aceman@walt.cc.utexas.edu (acy james stapp) (12/08/89)
In article <49396@bbn.COM> sminkin@BBN.COM () writes: >I've recently written a program to display GIF files on DEC VT340 >terminals using color sixel. The 16 color GIF files come out beutifully, >but I don't really have a scheme for converting 256 colors down to >16 (which is the limitation of the VT340). Is there a preferred Try this algorithm: read row(0) convert row(0) to array[length+1] of signed int; (or less, this is what I use) until eof() do read row(1) from file convert row(1) to array of int for every element of row(0) do newrow(element)=newrow(element)+(red>>7)>>3 row(0)(element+1)(red)=(red+1)>>1 row(1)(element)(red)=red>>1 newrow(element)=newrow(element)+(green>>6)<<1 row(0)(element+1)(green)=(green+1)>>1 row(1)(element)(green)=green>>1 newrow(element)=newrow(element)+(blue>>7) row(0)(element+1)(blue)=(blue+1)>>1 row(1)(element)(blue)=blue>>1 enddo write row(0) to file row(0)=row(1) /* HaHaHa to all you C programmers! Try doing this with one statement! */ enddo >> means shift into nothingness, << means shift into overflowingness use the following color map to display your final thingythingy Val R G B 0 0 0 0 1 0 0 255 2 0 85 0 3 0 85 255 4 0 170 0 5 0 170 255 6 0 255 0 7 0 255 255 8-15 255 as above-8 email me for an explanation if you're too stupid to figure it out yourself. <*>*<*>*<*>*<*>*<*>*<*>*<*>*<*>*<*>*<*>*<*>*<*>*<*>*<*>*<*>*<*>*<*>*<*>*<*>*<*> <*>Acy Stapp email: aceman@walt.cc.utexas.edu `NO SMOKING IN CORRIDORS' <*> <*>"Learn to love your anger now, anger here is all you posess" Duran Duran <*> <*>Disclaimer: The opinions presented above are true and correct, and if *>*<*> <*>*<anyone disagrees with them, then that's their problem. <*>*<*>*<*>*<*>*<*> <*>*<*>*<*>*<*>*<*>*<*>*<*>*<*>*<*>*<*>*<*>*<*>*<*>*<*>*<*>*<*>*<*>*<*>*<*>*<*>
aceman@walt.cc.utexas.edu (acy james stapp) (12/09/89)
In article <22099@ut-emx.UUCP> I write: >In article <49396@bbn.COM> sminkin@BBN.COM () writes: >>I've recently written a program to display GIF files on DEC VT340 >>terminals using color sixel. The 16 color GIF files come out beutifully, >>but I don't really have a scheme for converting 256 colors down to >>16 (which is the limitation of the VT340). Is there a preferred > >Try this algorithm: > [ awesome but non-functional algorithm deleted ] I committed a gross stupidity. Forgive me, It was late at night and I probably cost USENET hundreds if not thousands of dollars. The correct algorithm follows: (if you're interested) row:[2][width+1][3] integer output:[width] char red:constant integer=0 green:contant integer=1 blue:constant integer=2 temp:integer colmap:[16][3] char=((0,0,0),(0,0,255),(0,85,0),(0,85,255),/ (0,170,0),(0,170,255),(0,255,0),(0,255,255),/ (255,0,0),(255,0,255),(255,85,0),(255,85,255),/ (255,170,0),(255,170,255),(255,255,0),(255,255,255)) x:range integer=(0,width-1,1) tempp:^[] fixem:[3][2] integer=((128,32),(192,64),(128,128)) read first row from file into row[0][0..width-1][R..B] /* 0..255 Intensity */ while not eof(), do { read next row from file into row[1][0..width-1][R..B] instance x, do { color:range integer=(r,b,1) instance color, do { temp=row[0][x][color] output[x]=(temp .and fixem[color][0])/fixem[color][1] temp=temp-colmap[output[x]][color] row[0][x+1][color] += (temp+1)/2 row[1][x][color] += temp/2 } } write output[0..length] to your output file tempp=&row[0] &row[0]=&row[1] &row[1]=&row[0] } /* this is in DRIZZLE, a language I am developing. It should be fairly self- explanatory and easy to read. I hope so. I just noticed that I forgot to put statement separators. Damn. I welcome any comments on the style of the language. I developed this algorithm myself, but I think it's already been done by someone else. Notes: .<boolean op> makes it bitwise, otherwise it's logical. range is a type (min,max,delta). instancing a range evaluates the do succesively with the variable evaluating as the range supertype. e.g. x:range(1,10,1); instance x, do write(_<x,2>_); would write 1 2 3 4 5 6 7 8 910. I hope it makes sense to you. I like it.*/ /* p.s. The color mapping table is now defined in the program. Values in each triplet are Red, Green, and Blue succesively, ranging from 0..255. This program attempts to keep the average color intensities correct by propogating the differences between displayed and actual value down and to the right. One possible Change is to change the percentage of propogation right, down, and down&right depending on the original color. This will give you different patterns for colors with the same brightness. I gave green two bits since it is about twice as bright as red, the delta(brightness) should be fairly consistent. */ <*>*<*>*<*>*<*>*<*>*<*>*<*>*<*>*<*>*<*>*<*>*<*>*<*>*<*>*<*>*<*>*<*>*<*>*<*>*<*> <*>Acy Stapp email: aceman@walt.cc.utexas.edu `NO SMOKING IN CORRIDORS' <*> <*>"Learn to love your anger now, anger here is all you posess" Duran Duran <*> <*>Disclaimer: The opinions presented above are true and correct, and if *>*<*> <*>*<anyone disagrees with them, then that's their problem. <*>*<*>*<*>*<*>*<*> <*>*<*>*<*>*<*>*<*>*<*>*<*>*<*>*<*>*<*>*<*>*<*>*<*>*<*>*<*>*<*>*<*>*<*>*<*>*<*>