[comp.sys.mac.programmer] Utilities for RGB to 8-Bit

richr@ai.etl.army.mil (Richard Rosenthal) (05/19/88)

	I have a 24-bit color image on VAX with UNIX:
	    8-bit red
	    8-bit green
	    8-bit blue

	I want to display this on Mac II, 8-bit video.

	Any suggestions?

-- 
Richard Rosenthal                            | ARPANET:  richr@etl.arpa
US Army Engineer Topographic Laboratories    | UUCP:     (use ARPANET)
Ft. Belvoir, VA 22060-5546                   | PHONE:    +1 202 355 2830

wetter@tybalt.caltech.edu (Pierce T. Wetter) (05/20/88)

>
>	I have a 24-bit color image on VAX with UNIX:
>	    8-bit red
>	    8-bit green
>	    8-bit blue
>
>	I want to display this on Mac II, 8-bit video.
>
     Sure, get one pixel at a time from your unix file, then SetRGBColor to
  red*256, green*256, blue*256, then SetPixel(x,y). This saves programmer time
  at the expense of user time.

     You might also want to do dithering, best simple dither is 50% of one
  color + 50% of another color, but I don't know any dithering algorithms off 
the top of my head.

Pierce WEtter

----------------------------------------------------------------
wetter@tybalt.caltech.edu     Race For Space Grand Prize Winner.
-----------------------------------------------------------------
   Useless Advice #986: Never sit on a Tack.

kaufman@polya.STANFORD.EDU (Marc T. Kaufman) (05/20/88)

In article <6604@cit-vax.Caltech.Edu> wetter@tybalt.caltech.edu.UUCP (Pierce T. Wetter) writes:

->	I have a 24-bit color image on VAX with UNIX:
->	I want to display this on Mac II, 8-bit video.

>     Sure, get one pixel at a time from your unix file, then SetRGBColor to
>  red*256, green*256, blue*256, then SetPixel(x,y). This saves programmer time
>  at the expense of user time.

You might prefer SetCPixel, which does both operations at once.

lsr@Apple.COM (Larry Rosenstein) (05/21/88)

In article <6604@cit-vax.Caltech.Edu> wetter@tybalt.caltech.edu.UUCP (Pierce T. Wetter) writes:
>
>     You might also want to do dithering, best simple dither is 50% of one
>  color + 50% of another color, but I don't know any dithering algorithms off 
>the top of my head.

You might be able to achieve this effect by using the MakeRGBPat call which
will construct a dithered color pattern.  Then you can fill a 1 pixel
rectangle with that pattern.  This will be slower than calling SetCPixel,
but might yield better results in some cases.

Some things to note.  I don't think MakeRGBPattern recognizes when the RGB
color you input is actually in the color table.  I think this is because the
pattern you get back is not specific to any color table, but is computed
when used.  So you will want to call RealColor to see if the desired color
is in the color table, and only make a pattern if it isn't.

Also, you can save some time by reusing the pattern if the next pixel RGB is
the same as the previous one.  (You could even fill a larger rectangle of
pixels with 1 call.)

olson@endor.harvard.edu (Eric K. Olson) (05/25/88)

In a recent article Marc T. Kaufman writes:
>In article <6604@cit-vax.Caltech.Edu> wetter@tybalt.caltech.edu.UUCP (Pierce T. Wetter) writes:
>
>->	I have a 24-bit color image on VAX with UNIX:
>->	I want to display this on Mac II, 8-bit video.
>
>>     Sure, get one pixel at a time from your unix file, then SetRGBColor to
>>  red*256, green*256, blue*256, then SetPixel(x,y). This saves programmer time
>>  at the expense of user time.
>
>You might prefer SetCPixel, which does both operations at once.

Both these techniques use the current ITable (Inverse Color Mapping Table),
which is only 4 bits each of Red, Green, and Blue.  To get slightly better
results, you can use MakeITable() to get 5 bits each (for a total of 15 bits
of inverse mapping).  But you still don't get the best colors, and you don't
get a color table chosen to match the data.

If you are willing to settle for 5-bit ITable quality, you can create
3 off-screen PixMaps, with cluts set to Red, Green, or Blue ramps, fill
them with the raw 8-bit data, and CopyBits them into a fourth PixMap with
a transfer mode of AddPin.  This takes about 5 seconds for a 640 X 480
pixel image.  You can also then vary the color balance just by changing 
the cluts of the color planes.

The best technique is to histogram the input data, choose 256 popular colors
from the histogram, and match the 24-bit data into the color table exactly
(it helps in terms of speed if the color table is sorted, so you don't
have to compare to every entry).  You can also dither the 24 bits into
the color table.

Finally, SuperMac Software, the makers of PixelPaint, have a software
package that does all this for you quickly, and I believe it's free.
Their address is 295 North Bernardo Ave., Mountain View, CA 94043.
You'll probably have to adapt the raw 24-bit file before that package
will take it (I think its called "PixelScan").

-Eric

          Lexington Software Design:  Tomorrow's Software Yesterday

Eric K. Olson     olson@endor.harvard.edu     harvard!endor!olson     D0760
   (Name)                (ArpaNet)                 (UseNet)        (AppleLink)

olson@endor.harvard.edu (Eric K. Olson) (05/25/88)

In a recent article I write:
>In a recent article Marc T. Kaufman writes:
>>In article <6604@cit-vax.Caltech.Edu> wetter@tybalt.caltech.edu.UUCP (Pierce T. Wetter) writes:
>>
>>->	I have a 24-bit color image on VAX with UNIX:
>>->	I want to display this on Mac II, 8-bit video.
>>
>>>     Sure, get one pixel at a time from your unix file, then SetRGBColor to
>>>  red*256, green*256, blue*256, then SetPixel(x,y). This saves programmer time
>>>  at the expense of user time.
>>
>>You might prefer SetCPixel, which does both operations at once.
>
>Both these techniques use the current ITable (Inverse Color Mapping Table),
>which is only 4 bits each of Red, Green, and Blue.  To get slightly better
>results, you can use MakeITable() to get 5 bits each (for a total of 15 bits
>of inverse mapping).  But you still don't get the best colors, and you don't
>get a color table chosen to match the data.

Sorry, folks, I jumped the gun on this one.  To quote my brand new copy of
Inside Mac V (release version), page 138, 

"For Example, even if the color table were loaded with 256 levels of gray,
a 4-bit inverse table can only discriminate among 16 of the levels.  To
solve this problem without having to use special-case sets of colors with
hidden colors, inverse tables carry additional information about how to
find colors that differ only in the less significant bits.  As a result,
when the Color2Index routine is called, it can find the best match to the 
full 48-bit resolution available in a colorSpec.  Since examining the extra
information takes time, certain parts of Color Quickdraw, notably drawing
in the arithmetic tranfer modes, don't use this information, and hence won't
find the hidden colors."

I don't know what this extra information is or how it works.  Note that
if you use my technique of CopyBitsing in the three planes with the
(Arithmetic) tranfer mode AddPin, the problem with the inverse table
resolution being too low still holds.

Sorry if I led anyone astray.

-Eric

          Lexington Software Design:  Tomorrow's Software Yesterday

Eric K. Olson     olson@endor.harvard.edu     harvard!endor!olson     D0760
   (Name)                (ArpaNet)                 (UseNet)        (AppleLink)

peterson@peterson.applicon.UUCP (05/26/88)

	The problem here is that you have a true 24 bit image and you
want to display it as an 8 bit image.  This has been an ongoing problem
and there is no perfect solution.  The previous two responses would
work fine if you had only 256 pixels in your image, but that would be 
VERY small!  One way to do this would be to do a scan through the image
sampling it in 256 places (evenly).  Then assign these colors to the
Mac CLUT.  Now display the image using the Mac's ability to find the closest
color available for each pixel.  This gives you a unique color map for
each picture.
	Another way, as suggested, is dithering.  The idea is to try
to cover the entire 16 million colors with 256 by making a CLUT that
has a very large range of colors.  Doing this will make very large
steps between shades and will make your picture look "banded."
To reduce this banding, you have to alternate between the two nearest
colors depending on how close the real color is to the available ones.
There are many articles on dithering (also in "Fundamentals of Interactive
Computer Graphics" by Foley & Van Dam).
	I hope this helps.  I wish I could provide an algorithm, but
that would take up too much space here!

Joe Peterson
Schlumberger Technologies
Billerica, Ma

UUCP: ...mit-eddie!applicon!peterson