[comp.sys.next] bitmap data imaging

bz08+@andrew.cmu.edu (Brian Allan Zimmerman) (04/28/91)

I have been doing some work resently with the NXBitmapImageRep object
and have had some problems.  I have tried to load bitmap images using
standard data which is not in TIFF format.  It is in hexadecimal
notation similar to what is used by XCreateBitmapFromData in Xwindows. 
Perhaps this format is not allowable.  I cannot find information which
specifies what type of data is recognizable from the methods
initData:pixelsWide:pixelsHigh:bitsPerSample. . . etc.
 
Maybe this format does work but I am unfamiliar with the specifications
necessary to implement this initialization.  I am not sure what is meant
by bitsPerSample, samplePerPixel, bytesPerRow, bitsPerPixel?  Perhaps
someone can shed some inlightenment on this subject since the
documentation that I have seems a little unclear.
 
Thanks in advance
Brian Zimmerman
bz08@andrew.cmu.edu

aozer@next.com (Ali Ozer) (04/29/91)

In article <gc6bLUC00WBLI3T40J@andrew.cmu.edu> Brian Allan Zimmerman writes:
>I have been doing some work resently with the NXBitmapImageRep object
>and have had some problems.  I have tried to load bitmap images using
>standard data which is not in TIFF format.  It is in hexadecimal
>notation similar to what is used by XCreateBitmapFromData in Xwindows.
>Perhaps this format is not allowable.  I cannot find information which
>specifies what type of data is recognizable from the methods
>initData:pixelsWide:pixelsHigh:bitsPerSample. . . etc.

- initData:(unsigned char *)data
  pixelsWide:(int)width 
  pixelsHigh:(int)height
  bitsPerSample:(int)bps
  samplesPerPixel:(int)spp
  hasAlpha:(BOOL)alpha
  isPlanar:(BOOL)isPlanar
  colorSpace:(NXColorSpace)colorSpace
  bytesPerRow:(int)rBytes
  bitsPerPixel:(int)pBits;

This method takes a pointer to a chunk of memory containing the data;
the data is in binary format, packed, with the byte at the end of the
scanline filled.

For example, if you had a 4 x 4 monochrome image, with each pixel
represented by a single byte, then the data pointer would point to an
array of 16 bytes. The pixelsWide and pixelsHigh arguments would be
set to 4, and bits per sample would be set to 8 (to indicate that each
sample is one byte long).  We only have one sample per pixel
(monochrome images have 1 sample per pixel; RGB color images have 3,
CMYK images have 4, and so on...), thus samplesPerPixel would be set
to 1.  hasAlpha indicates whether the image has a transparency
channel; if so, then the image would have an extra sample per pixel.
In this case there is no alpha, so hasAlpha is NO. isPlanar is only
meaningful when the data contains more than one sample per pixel; it
indicates whether the different samples that make up a pixel are
together or separate, in "planes" following each other. In our case we
can set it to NO; doesn't matter with 1 sample.  The colorSpace
argument specifies how the data should be interpreted; the various
colorSpace values are described in graphics.h. In our case this could
be NX_OneIsWhiteColorSpace or NX_OneIsBlackColorSpace; the former
indicates that 0 = black and full value (255) = white (as in
PostScript); the latter indicates that 0 is white.

The last two arguments are unused in NeXTstep 2.0; passing in 0 will cause the
default values to be used. If these arguments worked, then bytesPerRow would
indicate how many bytes made up a scanline (this argument could be called
"rowBytes" as well), and bitsPerPixel indicates how many bits made up a pixel
(instead of the default, bitsPerSample x samplesPerPixel).

Another example is a 3 pixel x 3 pixel, 12-bit color image. Assume that the
image is NOT planar (ie, the R, G, and B values are together). Each pixel
will thus occupy 1.5 bytes, and pixels in a scanline will be packed:

Byte number: 0  1  2  3  4 
Contents:    RG BR GB RG Bx

Thus each scanline occupies 5 bytes, with the last half byte unused. The whole
image will require 5 x 3 bytes. Thus data should point to an array of 15
chars. Set pixelsWide and pixelsHigh to 3, bitsPerSample to 4, samplesPerPixel
to 3, isPlanar to NO, hasAlpha to NO, and colorSpace to NX_RGBColorSpace.

In the same example, if the image also had transparency, then one scanline
would occupy 6 bytes:

Byte number: 0  1  2  3  4  5
Contents:    RG BA RG BA RG BA

samplesPerPixel would be set to 4 and hasAlpha would be YES. The data array 
would need to contain 6 x 3 = 18 bytes.

Finally, let's assume there's no transparency but the data is planar. Then
the format for the whole image would be:

Byte number: 0  1  2  3  4  5  6  7  8  9  10 11 12 13 14 15 16 17
Contents:    RR Rx RR Rx RR Rx BB Bx BB Bx BB Bx GG Gx GG Gx GG Gx

As you can see, the red samples are all together, with each scanline 
byte-filled. Then come the blue samples, and then come the green ones.

Under NeXTstep, you'll find that monochrome images (with alpha) are usually
planar, and color images are meshed (== not planar). But of course any format
works.

Note that the NXBitmapImageRep does not copy your data; it simply points to
it. The data will not be freed when the object is freed. However, if you
call the initData:pixelsWide:... method with data set to NULL, then the object
will allocate its own memory and will free this memory when it's freed.

Ali, Ali Ozer@NeXT.com