[comp.graphics] Sun Rasterfile utilities

mike@relgyro.stanford.edu (Mike Macgirvin) (11/18/89)

	Sorry for the source posting to this group, but it is
	really the only approriate newsgroup for this...

	Routines for reading and writing Sun rasterfiles without
	the Sun libraries. Byte order independant.

	Released into the public domain with no restrictions,
	and no guarantees as to correctness or suitability for
	any specific purpose.

	mike@relgyro.stanford.edu
	
-------------------Cut Here -----------------------
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	PixRect.c
#	rasfile.h
#	colormap.h
# This archive created: Fri Nov 17 16:57:17 1989
export PATH; PATH=/bin:$PATH
echo shar: extracting "'PixRect.c'" '(7052 characters)'
if test -f 'PixRect.c'
then
	echo shar: will not over-write existing file "'PixRect.c'"
else
sed 's/^	X//' << \SHAR_EOF > 'PixRect.c'
	X/* pixrect.c */
	X
	X#include <stdio.h>
	X#include "rasfile.h"
	X#include "colormap.h"
	X
	X#ifndef MAX_MAPLENGTH
	X#define MAX_MAPLENGTH     768
	X#endif /* ! MAX_MAPLENGTH */
	X
	X#ifndef MAX_X_SIZE
	X#define MAX_X_SIZE 2048
	X#endif /* MAX_X_SIZE */
	X
	X#ifdef __STDC__
	X
	Xchar * memcpy(char *,char *,int);
	Xint Endian(void);
	Xvoid SwapWords(char *,int);
	Xint pr_load_header(FILE *,struct rasterfile *);
	Xint pr_dump_header(FILE *,struct rasterfile *,colormap_t *);
	Xint pr_load_colormap(FILE *,struct rasterfile *,colormap_t *);
	Xint readbyte(FILE *);
	Xint readbit(FILE *);
	Xint encode(FILE *,unsigned char *,int,int);
	Xint endofrun(unsigned char *,int,int);
	Xint writerepeat(int,int,FILE *);
	X
	X#else /* ! __STDC__ */
	X
	Xchar * memcpy();
	Xint Endian();
	Xvoid SwapWords();
	Xint pr_load_header();
	Xint pr_dump_header();
	Xint pr_load_colormap();
	Xint readbyte();
	Xint readbit();
	Xint encode();
	Xint endofrun();
	Xint writerepeat();
	X
	X#endif /* __STDC__ */
	X
	Xunsigned char      PR_ColorMap[MAX_MAPLENGTH];
	Xstruct rasterfile  PR_Ras;
	Xunsigned char linebuff[MAX_X_SIZE];
	Xlong image_bytes = 0L;
	Xint FileMode = 0;
	Xint repeat_flag = 0;
	Xint repeat_count = 0;
	Xint bitcount = 256;
	Xint filebyte = 0;
	X
	Xint Endian()
	X{ 
	X  char  * test = "\001\000";
	X  short * c    = (short *) test;
	X  if (* c == 1)
	X    return (1);
	X  return(0);
	X}
	X
	Xvoid SwapWords(s1,n)
	X     char *s1;
	X     int n;
	X{
	X  unsigned char s2[4];
	X  register int cnt;
	X  for(cnt = 0;cnt < n; cnt += 4) {
	X    s2[cnt + 0] = s1[cnt + 3];
	X    s2[cnt + 1] = s1[cnt + 2];
	X    s2[cnt + 2] = s1[cnt + 1];
	X    s2[cnt + 3] = s1[cnt + 0];
	X    s1[cnt + 0] = s2[cnt + 0];
	X    s1[cnt + 1] = s2[cnt + 1];
	X    s1[cnt + 2] = s2[cnt + 2];
	X    s1[cnt + 3] = s2[cnt + 3];
	X  }
	X  return;
	X}
	X
	Xint pr_load_header(fp,ras)
	X     FILE * fp;
	X     struct rasterfile * ras;
	X{
	X  if(fread(ras,sizeof(struct rasterfile),1,fp) != 1) 
	X    return(EOF);
	X  if(Endian())
	X    SwapWords((char *)ras,sizeof(struct rasterfile));
	X  if(ras->ras_magic != RAS_MAGIC)
	X    return(EOF);
	X  FileMode = ras->ras_type;
	X  repeat_flag = 0;
	X  repeat_count = 0;
	X  bitcount = 256;
	X  filebyte = 0;
	X  return(0);
	X}
	X
	Xint pr_dump_header(fp,ras,colormap)
	X     FILE * fp;
	X     struct rasterfile * ras;
	X     colormap_t * colormap;
	X{
	X  register int x;
	X  if(colormap)
	X    ras->ras_maplength = colormap->length * 3;
	X  (void)memcpy((char *)&PR_Ras,(char *)ras,sizeof(struct rasterfile));
	X  if(Endian())
	X    SwapWords((char *)&PR_Ras,sizeof(struct rasterfile));
	X  if(fwrite(&PR_Ras,sizeof(struct rasterfile),1,fp) != 1)
	X    return(EOF);
	X  if(colormap == (colormap_t *) NULL) 
	X    return(0);
	X  if(((fwrite(colormap->map[0],colormap->length,1,fp)) != 1)
	X  || ((fwrite(colormap->map[1],colormap->length,1,fp)) != 1)
	X  || ((fwrite(colormap->map[2],colormap->length,1,fp)) != 1))
	X    return(EOF);
	X  return(0);
	X}
	X
	Xint pr_load_colormap(fp,ras,colormap)
	X     FILE *fp;
	X     struct rasterfile * ras;
	X     colormap_t * colormap;
	X{
	X  register int x;
	X  if(colormap == (colormap_t *) NULL) {
	X    if(ras->ras_maplength) 
	X      for(x = 0; x < ras->ras_maplength; x ++)
	X	if((fgetc(fp)) == EOF)
	X	  return(EOF);
	X    return(0);
	X  }
	X  colormap->type = ras->ras_maptype;
	X  colormap->length = ras->ras_maplength / 3;
	X  if(ras->ras_maplength > MAX_MAPLENGTH) 
	X    return(EOF);
	X  if(fread(PR_ColorMap,ras->ras_maplength,1,fp) != 1)
	X    return(EOF);
	X  colormap->map[0] = PR_ColorMap;
	X  colormap->map[1] = PR_ColorMap + colormap->length;
	X  colormap->map[2] = colormap->map[1] + colormap->length;
	X  return(0);
	X}               
	X
	X/* 
	X  Routines to obtain an image from a rasterfile.
	X  first call pr_load_header and pr_load_colormap (if appropriate)
	X  if ras->ras_depth == 1, then get bits with readbit().
	X  otherwise, use readbyte. You must also account for the fact that
	X  image lines are rounded to a multiple of 16 bits.
	X
	X  Might be used like this:
	X     
	X  pr_load_header(fp,ras);
	X  pr_load_colormap(fp,ras,colormap);
	X        ... do whatever you need to set your colormap      
	X  if((ras->ras.depth == 1) && (ras->ras_width & 15))
	X       ras->ras_width = (ras->ras_width + (16 - (ras->ras_width & 15)));
	X  if((ras->ras_.depth == 8) && (ras->ras_width & 1))
	X       ras->ras_width ++;
	X
	X  for(y = 0; y < ras->ras_height; y ++)
	X	for(x = 0; x < ras->ras_width; x ++) {
	X	     if(ras->ras_depth == 1)
	X	        c = readbit(fp);
	X             else
	X	        c = readbyte(fp);
	X	     setpixel(x,y,c);
	X	}
	X
	X*/
	X
	Xint readbyte(fp)
	X     FILE *fp;
	X{
	X  register int c;
	X  if(FileMode != RT_BYTE_ENCODED)
	X    return(fgetc(fp));
	X  if(repeat_count) {
	X    repeat_count --;
	X    return(repeat_flag);
	X  }
	X  if((c = fgetc(fp)) == EOF)
	X    return(c);
	X  if(c != 128)
	X    return(c);
	X  if((repeat_count = fgetc(fp)) == EOF)
	X    return(repeat_count);
	X  if(!repeat_count)
	X    return(128);
	X  if((repeat_flag = fgetc(fp)) == EOF)
	X    return(repeat_flag);
	X  return(repeat_flag);
	X}
	X
	Xint readbit(fp)
	X     FILE *fp;
	X{
	X  register int x;
	X  if(bitcount == 256) {
	X    if((filebyte = readbyte(fp)) == EOF) {
	X      bitcount = 256;
	X      return(EOF);
	X    }
	X  }
	X  bitcount = bitcount >> 1;
	X  x = (filebyte & bitcount) ? 1 : 0;
	X  if(bitcount == 1)
	X    bitcount = 256;
	X  return(x);
	X}
	X
	X/*
	X   sample byte_encoding routine. image points to image buffer.
	X   First set up the rasterfile header with everything but the size.
	X   Dump the header and colormap.
	X   Call this routine.
	X   set ras->ras_length = image_bytes
	X   rewind the file and dump the header once more to give it the
	X   correct size.
	X   If you don't want encoding on the output, just dump the image out
	X   row by row.
	X*/
	X
	Xint encode(fp,image,xsiz,ysiz)
	X     FILE * fp;
	X     unsigned char * image;
	X     int xsiz,ysiz;
	X{
	X  register int x;
	X  register int y;
	X  int cnt;
	X  int z;
	X  image_bytes = 0L;
	X  for(y = 0; y < ysiz; y ++) {
	X    cnt = 0;
	X    for(x = 0; x < xsiz; x ++)
	X      linebuff[x] = *(image + ((y * xsiz) + x));
	X    while((z = endofrun(linebuff,cnt,xsiz)) <= xsiz) {
	X      if((writerepeat(z - cnt,linebuff[cnt],fp)) == EOF)
	X	return(EOF);
	X      cnt = z;
	X    }
	X  }
	X  return(0);
	X}
	X
	Xint endofrun(s1,a,b)
	X     unsigned char * s1;
	X     int a,b;
	X{
	X  register int x;
	X  do {
	X    x = s1[a];
	X    a ++;
	X  }
	X  while((x == s1[a]) && (a < b));
	X  return(a);
	X}
	X
	Xint writerepeat(repeat,c,fp)
	X     int c;
	X     int repeat;
	X     FILE * fp;
	X{
	X  while(repeat >= 256) {
	X    if(((fputc(128,fp)) == EOF) 
	X       || ((fputc(255,fp)) == EOF) 
	X       || ((fputc(c,fp)) == EOF))
	X      return(EOF);
	X    repeat -= 256; 
	X    image_bytes += 3L;
	X  }
	X  if(repeat > 2) {
	X    if(((fputc(128,fp)) == EOF) 
	X       || ((fputc(repeat - 1,fp)) == EOF) 
	X       || ((fputc(c,fp)) == EOF))
	X      return(EOF);
	X    image_bytes += 3L;
	X  }
	X  if(repeat == 2) {
	X    if(c == 128) {
	X      if(((fputc(128,fp)) == EOF) 
	X	 || ((fputc(1,fp)) == EOF)
	X	 || ((fputc(128,fp)) == EOF))
	X	return(EOF);
	X      image_bytes += 3L;
	X    }
	X    else {
	X      if(((fputc(c,fp)) == EOF) 
	X	 || ((fputc(c,fp)) == EOF)) 
	X	return(EOF);
	X      image_bytes += 2L;
	X    }
	X  }
	X  if(repeat == 1) {
	X    if(c == 128) {
	X      if(((fputc(c,fp)) == EOF) 
	X	 || ((fputc(0,fp)) == EOF))
	X	return(EOF);
	X      image_bytes += 2L;
	X    }
	X    else {
	X      if((fputc(c,fp)) == EOF)
	X	return(EOF);
	X      image_bytes += 1L;
	X    }
	X  }
	X  return(0);
	X}
	X
	X
	X
	X
	X
	X
	X
	X
	X
SHAR_EOF
if test 7052 -ne "`wc -c < 'PixRect.c'`"
then
	echo shar: error transmitting "'PixRect.c'" '(should have been 7052 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'rasfile.h'" '(527 characters)'
if test -f 'rasfile.h'
then
	echo shar: will not over-write existing file "'rasfile.h'"
else
sed 's/^	X//' << \SHAR_EOF > 'rasfile.h'
	X/* rasfile.h */
	X
	X#ifndef RASTERFILE_H
	X#define RASTERFILE_H
	X
	Xstruct rasterfile {
	X     long ras_magic;
	X     long ras_width;
	X     long ras_height;
	X     long ras_depth;
	X     long ras_length;
	X     long ras_type;
	X     long ras_maptype;
	X     long ras_maplength;
	X};
	X
	X#define RAS_MAGIC        0x59a66a95
	X
	X#define RT_OLD           0
	X#define RT_STANDARD      1
	X#define RT_BYTE_ENCODED  2
	X#define RT_EXPERIMENTAL  0xffff
	X
	X#define RMT_NONE         0
	X#define RMT_EQUAL_RGB    1
	X#define RMT_RAW          2
	X
	X#endif /* ! RASTERFILE_H */
	X
	X
	X
	X
	X
	X
	X
SHAR_EOF
if test 527 -ne "`wc -c < 'rasfile.h'`"
then
	echo shar: error transmitting "'rasfile.h'" '(should have been 527 characters)'
fi
chmod +x 'rasfile.h'
fi # end of overwriting check
echo shar: extracting "'colormap.h'" '(176 characters)'
if test -f 'colormap.h'
then
	echo shar: will not over-write existing file "'colormap.h'"
else
sed 's/^	X//' << \SHAR_EOF > 'colormap.h'
	X/* colormap.h */
	X
	X#ifndef COLORMAP_H
	X#define COLORMAP_H
	Xtypedef struct {
	X     long type;
	X     long length;
	X     unsigned char * map[3];
	X} colormap_t;
	X#endif /* ! COLORMAP_H */
SHAR_EOF
if test 176 -ne "`wc -c < 'colormap.h'`"
then
	echo shar: error transmitting "'colormap.h'" '(should have been 176 characters)'
fi
fi # end of overwriting check
#	End of shell archive
exit 0
--------------------------------Cut Here -------------------
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+  Mike Macgirvin              Relativity Gyroscope Experiment (GP-B)    +
+  mike@relgyro.stanford.edu   (36.64.0.50)                              +
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++