[net.graphics] An Image Format Standard

ken@turtlevax.UUCP (Ken Turkowski) (07/29/85)

In article <182@ukc.UUCP> msp@eagle.UUCP (Mike Parsons. ) writes:
>In article <1130@vax135.UUCP> miles@vax135.UUCP (Miles Murdocca) writes:
>>How about this idea:  subscribers to the net informally create a standard 
>>that fills their needs as well as the needs of anyone else they can think 
>>of. For starters, I suggest this: every image will start with a fixed size 
>>header that gives information on the rest of the image(s).
>>Such information could be X dimension (in pixels), Y dimension, type
>>of data (graphic or raster), number of bits per pixel, number of images,
>>etc.  Color maps and data would then follow.  Ideas or comments, anyone?
>
>Good idea. I would love to trade images round the net. I think the header
>needs to be somewhat more flexible though: What about run-length, quadtree,
>octree and other 3-D data? To keep size to a minimum, every image could be
>put through compress. We'll need uuencode/decode too.

-----------------------------------------------------------------
Additionally, there is
byte ordering - If there are any data stored in quanta other than bytes,
	there is a problem transferring images generated on a big-endian
	machine to a little-endian one.
scanning direction: right-to-left then top-to-bottom, right-to-left then
	bottom-to-top, or any of the other 6 possible ways to scan a 2-
	dimensional signal to convert it into a 1-dimensional one.
	More possibilities are possible for 3-dimensional signals.
packing orientation: Several pixels can be packed into a "word".
	Are they packed left-to-right or right-to-left?
contiguity within words: If several pixels are packed into the same
	word, what is their geometric relationship (horizontal or
	vertical).  You may think that this is a weird concept,
	but a certain workstation manufacturer's graphics board
	seems to work fastest when 1-bit pixels are packed
	16-to-a-word horizontally-contiguous and then block-scanned
	vertically.
cursor hot spot: If an image is used as a cursor, where is the relative
	location of the point to which the cursor points?

Below I submit a format that we've used in-house, which seems to meet
nearly every criterion.  I offer it to the net for comment and
improvement.  The only things not specifically included are encoding
(run-length, quadtree, octtree, 3-D) which could be put into the
"ident" field of ImageSubHeader, and cursor hot-spot, which could
replace the "thisimage" field of ImageSubHeader.  The "thisimage"
pointer was originally proposed to allow locating all of the subheaders
at the beginning of the file, to accommodate an easily accessible index
for font files which contain an entire character set.

I'm not advocating that every institution accommodate every permutation
allowed by this header in every one of its application programs, but
some allowance should be made for an almighty conversion program
(albeit partially implemented) to convert between various popular
formats.

-----------------------------------------------------------------

# This is a shell archive.  Remove anything before this line, then
# unpack it by saving it in a file and typing "sh file".  (Files
# unpacked will be owned by you and have default permissions.)
#
# This archive contains:
# image.h

echo x - image.h
cat > "image.h" << '//E*O*F image.h//'
/* These are the headers to be used on all images.  A simple image, with
 * one component, is characterized by a 32-byte header, followed by the
 * image.  More complex images with multiple components, as well as (whole
 * or partial) color maps may be included in this file by using one
 * 20-byte header plus a 12-byte header for each separate image
 * component.  The general structure follows:
 *
 *	RasterImageHeader	(20 bytes)
 *	Colormap		(optional; flagged in RasterImageHeader)
 *	ImageSubHeader		(12 bytes)
 *	Image1
 *	ImageSubHeader		(12 bytes, optional)
 *	Image2			(optional)
 *	...		(Should be at least one ImageSubHeader and Image)
 * 
 * If a colormap is supplied with the image, it is denoted by a nonzero
 * cmapsize in the RasterImageHeader.  The colormap is located immediately
 * afterward, and should be 832 bytes long, as described in
 * <colormap.h>:  32 for the header, 32 for the indexmap, and 3*256 for
 * the main and alternate colormaps.  The colormap can easily be skipped
 * (regardless of its conformity to the colormap.h standard) by using the
 * cmapsize parameter.
 * 
 * The ImageSubHeader is used in front of every image.  This is useful for
 * images with different sized components (as with an alpha component to
 * specify transparency) or for images with R, G, and B generated
 * separately.
 */

# define STDIMAGE 'I','M','A','G',('3'<<24)|('2'<<16)|('1'<<8)|'0',0,16,\
	SCANRTDN|HCONTINUITY|BIGENDIAN|RIGHTJUSTIFIED,0

struct RasterImageHeader {		/* 20 byte introductory header */
	char	objecttype[4];	/* "IMAG" */
	long	byteorder;	/* ('3'<<24) | ('2'<<16) | ('1'<<8) | '0' */
	char	version;	/* 0 */
	char	wordsize;	/* Size (in bits) of the word */
	char	packingorientation;	/* Fields defined below */
	char	unused;		/* Should be zero */

	short	width;		/* Width of the raster image in pixels */
	short	height;		/* Height of the raster image in pixels */
	char	unused1[2];	/* Should be zero */

	short	cmapsize;     /* colormap size, or offset to ImageSubHeader */
};

struct ImageSubHeader {			/* 12-byte header for each image */
	char imagetype;		/* The type code of the image */
	char bitspercomp;	/* The number of bits per component */
	char fieldshift;	/* Bit number: 0 unless plane-scanned */
	char ident;		/* User's identification code (0 default) */
	long thisimage;		/* Should be 0; reserved for image offset */
	long nextimage;		/* Offset to next ImageSubHeader; 0 if none */
};

/* Below we have the bit definitions for the packingorientation field */
# define SCANRTUP	0x00	/* left-to-right, bottom-to-top */
# define SCANUPRT	0x01	/* bottom-to-top, left-to-right */
# define SCANUPLF	0x02	/* bottom-to-top, right-to-left */
# define SCANLFUP	0x03	/* right-to-left, bottom-to-top */
# define SCANLFDN	0x04	/* right-to-left, top-to-bottom */
# define SCANDNLF	0x05	/* top-to-bottom, right-to-left */
# define SCANDNRT	0x06	/* top-to-bottom, left-to-right */
# define SCANRTDN	0x07	/* left-to-right, top-to-bottom */

# define HCONTIGUITY	0x00	/* word has horizontally-contiguous pixels */
# define VCONTIGUITY	0x08	/* word has vertically-contiguous pixels */

# define LITTLEENDIAN	0x00	/* first pixel in least significant position */
# define BIGENDIAN 	0x10	/* first pixel in most significant position */

# define RIGHTJUSTIFIED	0x00	/* Right justification in field */
# define LEFTJUSTIFIED	0x20	/* Left justification in field */

/* Here is the encoding for the various image types */
# define IMAG_UNDEFINED	0

# define IMAG_VALUE	1
# define IMAG_AALINE	2
# define IMAG_INTENSITY	3
# define IMAG_ALPHA	4
# define IMAG_INVALPHA	5

# define IMAG_RGB	8
# define IMAG_RGBA	9
# define IMAG_RED	10
# define IMAG_GREEN	11
# define IMAG_BLUE	12

# define IMAG_DEPTH	16

/* #include <colormap.h>	/* To interpret the colormap, if included */
//E*O*F image.h//

exit 0
-- 

Ken Turkowski @ CADLINC, Menlo Park, CA
UUCP: {amd,decwrl,hplabs,nsc,seismo,spar}!turtlevax!ken
ARPA: turtlevax!ken@DECWRL.ARPA

julian@osu-eddie.UUCP (Julian Gomez) (08/07/85)

Lucasfilm has had an image format standard for a while now.  It has
even been used externally: images for the frame buffer show at
SIGGRAPH 85 were mailed on tapes using a simplified Lucasfilm
standard.

One problem with their format (and Ken's too) is the lack of stating
the aspect ratio for the pixels: square or 4:3.  Not all frame
buffers do them the same way.
-- 

	Julian "a tribble took it" Gomez
	The Ohio State University
	{ucbvax,decvax}!cbosg!osu-eddie!julian