Main Page   Class Hierarchy   Data Structures   File List   Data Fields   Globals  

make_header.C

Go to the documentation of this file.
00001 
00002 #include "stdinc.h"
00003 
00004 // Description of header for files containing SUN raster images:
00005 // (Nothing special about this format -- it just happens to be simple.)
00006 
00007 struct rasterfile {
00008         int     ras_magic;              // magic number
00009         int     ras_width;              // width (pixels) of image
00010         int     ras_height;             // height (pixels) of image
00011         int     ras_depth;              // depth (1, 8, or 24 bits) of pixel
00012         int     ras_length;             // length (bytes) of image
00013         int     ras_type;               // type of file; see RT_* below
00014         int     ras_maptype;            // type of colormap; see RMT_* below
00015         int     ras_maplength;          // length (bytes) of following map
00016 
00017         // color map follows for ras_maplength bytes, followed by image
00018 };
00019 
00020 // Note: colormap and image are in bytes, so no compatibility problems
00021 // between machines.  However, the byte ordering in the header file is
00022 // important, and has to be right...  Ordering must be such that the
00023 // four bytes of the magic number RAS_MAGIC are stored in the order:
00024 //
00025 //      a6 59 95 6a
00026 //
00027 // On a Sun system, bytes 0, 1, 2, and 3, as defined in check_bytes and
00028 // write_word below, are a6, 59, 95, and 6a, respectively.  On an Intel
00029 // box, they are 95, 6a, a6, and 59, and so must be reordered.
00030 //
00031 // Maybe standard routines exist to figure this out.  My functions below
00032 // at least work...
00033 
00034 #define RAS_MAGIC       0x59a66a95
00035 
00036 static int byte_order = 0;      // 0 == Sun, 1 = non-Sun ordering
00037 
00038 void check_byte()
00039 {
00040     int i = RAS_MAGIC;
00041     unsigned char *c;
00042 
00043     c = (unsigned char*) &i;
00044 
00045     if (*c == 0x59 && *(c+1) == 0xa6)
00046         byte_order = 0;
00047     else
00048         byte_order = 1;
00049 }
00050 
00051 void write_word(unsigned char * x, int n, FILE* out_file)
00052 {
00053     int i1, i2, inc;
00054 
00055     if (byte_order == 0) {
00056         i1 = 0;
00057         i2 = n;
00058         inc = 1;
00059     } else {
00060         i1 = n-1;
00061         i2 = -1;
00062         inc = -1;
00063     }
00064     for (int i = i1; i != i2; i += inc) {
00065         fwrite(x+i, sizeof(*x), 1, out_file);
00066         // fprintf(stderr, "wrote %d %x %c\n", i, *(x+i), *(x+i));
00067     }
00068 }
00069 
00070 #define RT_OLD          0       // Raw pixrect image in 68000 byte order
00071 #define RT_STANDARD     1       // Raw pixrect image in 68000 byte order
00072 #define RT_BYTE_ENCODED 2       // Run-length compression of bytes
00073 #define RT_FORMAT_RGB   3       // XRGB or RGB instead of XBGR or BGR
00074 #define RT_FORMAT_TIFF  4       // tiff <-> standard rasterfile
00075 #define RT_FORMAT_IFF   5       // iff (TAAC format) <-> standard rasterfile
00076 #define RT_EXPERIMENTAL 0xffff  // Reserved for testing
00077 
00078 #define RMT_RAW         2
00079 
00080 #define RMT_NONE        0       // ras_maplength is expected to be 0
00081 #define RMT_EQUAL_RGB   1       // red[ras_maplength/3],green[],blue[]
00082 
00083 // NOTES:
00084 //      Each line of the image is rounded out to a multiple of 16 bits.
00085 //   This corresponds to the rounding convention used by the memory pixrect
00086 //   package (/usr/include/pixrect/memvar.h) of the SunWindows system.
00087 //      The ras_encoding field (always set to 0 by Sun's supported software)
00088 //   was renamed to ras_length in release 2.0.  As a result, rasterfiles
00089 //   of type 0 generated by the old software claim to have 0 length; for
00090 //   compatibility, code reading rasterfiles must be prepared to compute the
00091 //   true length from the width, height, and depth fields.
00092 
00093 static void make_colormap(unsigned char* red,
00094                    unsigned char* green,
00095                    unsigned char* blue)
00096 {
00097     // Make a simple standard colormap.
00098 
00099     int i;
00100 
00101     for (i = 0; i < 32; i++) {
00102         red[i] = 0;
00103         green[i] = 0;
00104         blue[i] = 8*i;
00105     }
00106     for (i = 32; i < 96; i++) {
00107         red[i] = 0;
00108         green[i] = 4*(i-32);
00109         blue[i] = 255;
00110     }
00111     for (i = 96; i < 160; i++) {
00112         red[i] = 4*(i-96);
00113         green[i] = 255;
00114         blue[i] = 255 - red[i];
00115     }
00116     for (i = 160; i < 224; i++) {
00117         red[i] = 255;
00118         green[i] = 255 - 4*(i-160);
00119         blue[i] = 0;
00120     }
00121     for (i = 224; i < 256; i++) {
00122         red[i] = 255;
00123         blue[i] = green[i] = 8*(i-224);
00124     }
00125 }
00126 
00127 void make_header(int m, int n, FILE* out_file, char* colormap_file)
00128 {
00129     // Construct a SUN rasterfile header.
00130 
00131     int i;
00132     unsigned char red[256], green[256], blue[256];
00133 
00134     struct rasterfile r;
00135     FILE* mapfile;
00136 
00137     // Attempt to read a color map.
00138 
00139     if (colormap_file) {
00140         if ((mapfile = fopen(colormap_file, "r")) == NULL) {
00141             fprintf(stderr, "Can't open color map file %s: using default\n",
00142                     colormap_file);
00143             colormap_file = NULL;
00144         } else {
00145             if (fread(red, 1, 256, mapfile) != 256) {
00146                 fprintf(stderr, "Error reading color map: using default\n");
00147                 colormap_file = NULL;
00148             } else {
00149                 if (fread(green, 1, 256, mapfile) != 256) {
00150                     fprintf(stderr, "Error reading color map: using default\n");
00151                     colormap_file = NULL;
00152                 } else {
00153                     if (fread(blue, 1, 256, mapfile) != 256) {
00154                         fprintf(stderr,
00155                                 "Error reading color map: using default\n");
00156                         colormap_file = NULL;
00157                     }
00158                 }
00159             }
00160         }
00161     }
00162 
00163     r.ras_magic = RAS_MAGIC;
00164     r.ras_width = m;
00165     r.ras_height = n;
00166     r.ras_depth = 8;
00167     r.ras_length = m*n;
00168     r.ras_type = RT_STANDARD;
00169     r.ras_maptype = RMT_EQUAL_RGB;
00170     r.ras_maplength = 768;
00171 
00172     // fwrite(&r, sizeof(r), 1, out_file);
00173 
00174     // Horrible kludge to get the byte ordering right in the header...
00175 
00176     check_byte();
00177 
00178     write_word((unsigned char*)&r.ras_magic, sizeof(r.ras_magic), out_file);
00179     write_word((unsigned char*)&r.ras_width, sizeof(r.ras_width), out_file);
00180     write_word((unsigned char*)&r.ras_height, sizeof(r.ras_height), out_file);
00181     write_word((unsigned char*)&r.ras_depth, sizeof(r.ras_depth), out_file);
00182     write_word((unsigned char*)&r.ras_length, sizeof(r.ras_length), out_file);
00183     write_word((unsigned char*)&r.ras_type, sizeof(r.ras_type), out_file);
00184     write_word((unsigned char*)&r.ras_maptype, sizeof(r.ras_maptype), out_file);
00185     write_word((unsigned char*)&r.ras_maplength, sizeof(r.ras_maplength),
00186                out_file);
00187 
00188     // Remaining elements are all bytes, so no special treatment needed.
00189 
00190     if (!colormap_file) make_colormap(red, green, blue);
00191 
00192     fwrite(red, 1, 256, out_file);
00193     fwrite(green, 1, 256, out_file);
00194     fwrite(blue, 1, 256, out_file);
00195 }

Generated at Sun Feb 24 09:57:08 2002 for STARLAB by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001