1 /*
2  ** Based on xwdtopnm.c - read and write an X11 or X10 window dump file
3  **
4  ** Modified heavily by Markus Baur (mbaur@ira.uka.de) for use as a part
5  ** of xv-2.21, 12/30/92
6  **
7  ** Hacked up again to support xv-3.00 and XWDs from 64bit machines
8  ** (e.g. DEC Alphas), 04/10/94
9  **
10  ** Copyright (C) 1989, 1991 by Jef Poskanzer.
11  **
12  ** Permission to use, copy, modify, and distribute this software and its
13  ** documentation for any purpose and without fee is hereby granted, provided
14  ** that the above copyright notice appear in all copies and that both that
15  ** copyright notice and this permission notice appear in supporting
16  ** documentation.  This software is provided "as is" without express or
17  ** implied warranty.
18  **
19  */
20 
21 #include "xv.h"
22 #include <limits.h>             /* for CHAR_BIT */
23 
24 /* SJT: just in case ... */
25 #ifndef CHAR_BIT
26 #  define CHAR_BIT 8
27 #endif
28 
29 
30 /***************************** x11wd.h *****************************/
31 #define X11WD_FILE_VERSION 7
32 typedef struct {
33   CARD32 header_size;         /* Size of the entire file header (bytes). */
34   CARD32 file_version;        /* X11WD_FILE_VERSION */
35   CARD32 pixmap_format;       /* Pixmap format */
36   CARD32 pixmap_depth;        /* Pixmap depth */
37   CARD32 pixmap_width;        /* Pixmap width */
38   CARD32 pixmap_height;       /* Pixmap height */
39   CARD32 xoffset;             /* Bitmap x offset */
40   CARD32 byte_order;          /* MSBFirst, LSBFirst */
41   CARD32 bitmap_unit;         /* Bitmap unit */
42   CARD32 bitmap_bit_order;    /* MSBFirst, LSBFirst */
43   CARD32 bitmap_pad;          /* Bitmap scanline pad */
44   CARD32 bits_per_pixel;      /* Bits per pixel */
45   CARD32 bytes_per_line;      /* Bytes per scanline */
46   CARD32 visual_class;        /* Class of colormap */
47   CARD32 red_mask;            /* Z red mask */
48   CARD32 grn_mask;            /* Z green mask */
49   CARD32 blu_mask;            /* Z blue mask */
50   CARD32 bits_per_rgb;        /* Log base 2 of distinct color values */
51   CARD32 colormap_entries;    /* Number of entries in colormap */
52   CARD32 ncolors;             /* Number of Color structures */
53   CARD32 window_width;        /* Window width */
54   CARD32 window_height;       /* Window height */
55   CARD32 window_x;            /* Window upper left X coordinate */
56   CARD32 window_y;            /* Window upper left Y coordinate */
57   CARD32 window_bdrwidth;     /* Window border width */
58 #ifdef WORD64
59   CARD32 header_pad;
60 #endif
61 } X11WDFileHeader;
62 
63 typedef struct {
64   CARD32 num;
65   CARD16 red, green, blue;
66   CARD8  flags;               /* do_red, do_green, do_blue */
67   CARD8  pad;
68 } X11XColor;
69 
70 
71 /*-------------------------------------------------------------------------*/
72 
73 typedef byte pixel;
74 
75 /* local functions */
76 static int    getinit         PARM((FILE *, int*, int*, int*, CARD32 *,
77 			                          CARD32, PICINFO *));
78 static CARD32 getpixnum       PARM((FILE *));
79 static int    xwdError        PARM((const char *));
80 static void   xwdWarning      PARM((const char *));
81 static int    bs_short        PARM((int));
82 static CARD32 bs_long         PARM((CARD32));
83 static int    readbigshort    PARM((FILE *, CARD16 *));
84 static int    readbiglong     PARM((FILE *, CARD32 *));
85 static int    readlittleshort PARM((FILE *, CARD16 *));
86 static int    readlittlelong  PARM((FILE *, CARD32 *));
87 #if 0 /* NOTUSED */
88 static int    writebigshort   PARM((FILE *, int));
89 static int    writebiglong    PARM((FILE *, CARD32));
90 #endif
91 
92 static void   getcolorshift   PARM((CARD32, int *, int *)); /* SJT */
93 
94 /* SJT: for 16bpp and 24bpp shifts */
95 static int    red_shift_right, red_justify_left,
96               grn_shift_right, grn_justify_left,
97               blu_shift_right, blu_justify_left;
98 static byte  *pic8, *pic24;
99 static CARD32 red_mask, grn_mask, blu_mask;
100 static int    bits_per_item, bits_used, bit_shift,
101               bits_per_pixel, bits_per_rgb;
102 static char   buf[4];
103 static char   *byteP;
104 static CARD16 *shortP;
105 static CARD32 *longP;
106 static CARD32 pixel_mask;
107 static int    byte_swap, byte_order, bit_order, filesize;
108 
109 static const char  *bname;
110 
111 
112 
113 /*************************************/
LoadXWD(fname,pinfo)114 int LoadXWD(fname, pinfo)
115      char *fname;
116      PICINFO *pinfo;
117 {
118   /* returns '1' on success */
119 
120   pixel *xP;
121   int    col;
122   int    rows=0, cols=0, padright=0, row, npixels, bufsize;
123   CARD32 maxval=0, visualclass=0;
124   FILE  *ifp;
125 
126   bname          = BaseName(fname);
127   pinfo->pic     = (byte *) NULL;
128   pinfo->comment = (char *) NULL;
129 
130   ifp = xv_fopen(fname, "r");
131   if (!ifp) return (xwdError("can't open file"));
132 
133   /* figure out the file size (used to check colormap size) */
134   fseek(ifp, 0L, 2);
135   filesize = ftell(ifp);
136   fseek(ifp, 0L, 0);
137 
138 
139   if (getinit(ifp, &cols, &rows, &padright, &visualclass, maxval, pinfo))
140     return 0;
141 
142   npixels = cols * rows;
143   if (cols <= 0 || rows <= 0 || npixels/cols != rows) {
144     xwdError("Image dimensions out of range");
145     return 0;
146   }
147 
148 
149   switch (visualclass) {
150   case StaticGray:
151   case GrayScale:
152     pinfo->colType = F_GREYSCALE;
153     pic8 = (byte *) calloc((size_t) npixels, (size_t) 1);
154     if (!pic8) {
155       xwdError("couldn't malloc 'pic'");
156       return 0;
157     }
158 
159     for (row=0; row<rows; row++) {
160       for (col=0, xP=pic8+(row*cols); col<cols; col++, xP++)
161 	*xP = getpixnum(ifp);
162 
163       for (col=0; col<padright; col++) getpixnum(ifp);
164     }
165 
166     pinfo->type = PIC8;
167     pinfo->pic  = pic8;
168     break;
169 
170   case StaticColor:
171   case PseudoColor:
172     pinfo->colType = F_FULLCOLOR;
173     pic8 = (byte *) calloc((size_t) npixels, (size_t) 1);
174     if (!pic8) {
175       xwdError("couldn't malloc 'pic'");
176       return 0;
177     }
178 
179     for (row=0; row<rows; row++) {
180       for (col=0, xP=pic8+(row*cols); col<cols; col++, xP++)
181 	*xP = getpixnum(ifp);
182       for (col=0; col<padright; col++) getpixnum(ifp);
183     }
184 
185     pinfo->type = PIC8;
186     pinfo->pic  = pic8;
187     break;
188 
189   case TrueColor:
190   case DirectColor:
191     pinfo->colType = F_FULLCOLOR;
192     bufsize = 3*npixels;
193     if (bufsize/3 != npixels) {
194       xwdError("Image dimensions out of range");
195       return 0;
196     }
197     pic24 = (byte *) calloc((size_t) bufsize, (size_t) 1);
198     if (!pic24) {
199       xwdError("couldn't malloc 'pic24'");
200       return 0;
201     }
202 
203     for (row=0; row<rows; row++) {
204       for (col=0, xP=pic24+(row*cols*3); col<cols; col++) {
205 	CARD32 ul;
206 
207 	ul = getpixnum(ifp);
208 	switch (bits_per_pixel) {
209         case 16:
210         case 24:
211         case 32:
212           /* SJT: shift all the way to the right and then shift left. The
213              pairs of shifts could be combined. There will be two right and
214              one left shift, but it's unknown which will be which. It seems
215              easier to do the shifts (which might be 0) separately than to
216              have a complex set of tests. I believe this is independent of
217              byte order but I have no way to test.
218            */
219           *xP++ = ((ul & red_mask) >> red_shift_right) << red_justify_left;
220           *xP++ = ((ul & grn_mask) >> grn_shift_right) << grn_justify_left;
221           *xP++ = ((ul & blu_mask) >> blu_shift_right) << blu_justify_left;
222           break;
223 
224 	default:
225 	  xwdError("True/Direct supports only 16, 24, and 32 bits");
226 	  return 0;
227 	}
228       }
229 
230       for (col=0; col<padright; col++) getpixnum(ifp);
231     }
232 
233     pinfo->type = PIC24;
234     pinfo->pic  = pic24;
235     break;
236 
237   default:
238     xwdError("unknown visual class");
239     return 0;
240   }
241 
242   sprintf(pinfo->fullInfo, "XWD, %d-bit %s.  (%d bytes)",
243 	  bits_per_pixel,
244 	  ((visualclass == StaticGray ) ? "StaticGray"  :
245 	   (visualclass == GrayScale  ) ? "GrayScale"   :
246 	   (visualclass == StaticColor) ? "StaticColor" :
247 	   (visualclass == PseudoColor) ? "PseudoColor" :
248 	   (visualclass == TrueColor  ) ? "TrueColor"   :
249 	   (visualclass == DirectColor) ? "DirectColor" : "<unknown>"),
250 	  filesize);
251 
252   sprintf(pinfo->shrtInfo, "%dx%d XWD.", cols, rows);
253 
254   pinfo->normw = pinfo->w = cols;
255   pinfo->normh = pinfo->h = rows;
256 
257   fclose(ifp);
258   return 1;
259 }
260 
261 
262 /*********************/
getinit(file,colsP,rowsP,padrightP,visualclassP,maxv,pinfo)263 static int getinit(file, colsP, rowsP, padrightP, visualclassP, maxv, pinfo)
264      FILE* file;
265      int* colsP;
266      int* rowsP;
267      int* padrightP;
268      CARD32 * visualclassP;
269      CARD32   maxv;
270      PICINFO *pinfo;
271 {
272   int              i;
273   int              grayscale;
274   char             errstr[200];
275   byte             header[sizeof(X11WDFileHeader)];
276   X11WDFileHeader *h11P;
277   X11XColor       *x11colors;
278   CARD32           pad;
279   int              word64 = 0;
280 
281   x11colors = (X11XColor *) NULL;
282 
283   byte_swap = 0;
284   maxv = 255L;
285 
286   h11P = (X11WDFileHeader*) header;
287 
288   if (fread(&header[0], sizeof(*h11P), (size_t) 1, file) != 1)
289     return(xwdError("couldn't read X11 XWD file header"));
290 
291   if (h11P->file_version != X11WD_FILE_VERSION) {
292     byte_swap = 1;
293     h11P->header_size      = bs_long(h11P->header_size);
294     h11P->file_version     = bs_long(h11P->file_version);
295     h11P->pixmap_format    = bs_long(h11P->pixmap_format);
296     h11P->pixmap_depth     = bs_long(h11P->pixmap_depth);
297     h11P->pixmap_width     = bs_long(h11P->pixmap_width);
298     h11P->pixmap_height    = bs_long(h11P->pixmap_height);
299     h11P->xoffset          = bs_long(h11P->xoffset);
300     h11P->byte_order       = bs_long(h11P->byte_order);
301     h11P->bitmap_unit      = bs_long(h11P->bitmap_unit);
302     h11P->bitmap_bit_order = bs_long(h11P->bitmap_bit_order);
303     h11P->bitmap_pad       = bs_long(h11P->bitmap_pad);
304     h11P->bits_per_pixel   = bs_long(h11P->bits_per_pixel);
305     h11P->bytes_per_line   = bs_long(h11P->bytes_per_line);
306     h11P->visual_class     = bs_long(h11P->visual_class);
307     h11P->red_mask         = bs_long(h11P->red_mask);
308     h11P->grn_mask         = bs_long(h11P->grn_mask);
309     h11P->blu_mask         = bs_long(h11P->blu_mask);
310     h11P->bits_per_rgb     = bs_long(h11P->bits_per_rgb);
311     h11P->colormap_entries = bs_long(h11P->colormap_entries);
312     h11P->ncolors          = bs_long(h11P->ncolors);
313     h11P->window_width     = bs_long(h11P->window_width);
314     h11P->window_height    = bs_long(h11P->window_height);
315     h11P->window_x         = bs_long(h11P->window_x);
316     h11P->window_y         = bs_long(h11P->window_y);
317     h11P->window_bdrwidth  = bs_long(h11P->window_bdrwidth);
318   }
319 
320   for (i=0; i<h11P->header_size - sizeof(*h11P); i++)
321     if (getc(file) == EOF)
322       return(xwdError("couldn't read rest of X11 XWD file header"));
323 
324   /* Check whether we can handle this dump. */
325   if (h11P->pixmap_depth > 24)
326     return(xwdError("can't handle X11 pixmap_depth > 24"));
327 
328   if (h11P->bits_per_rgb > 24)
329     return(xwdError("can't handle X11 bits_per_rgb > 24"));
330 
331   if (h11P->pixmap_format != ZPixmap && h11P->pixmap_depth != 1)  {
332     sprintf(errstr, "can't handle X11 pixmap_format %ld with depth != 1",
333 	    (long)h11P->pixmap_format);
334     return(xwdError(errstr));
335   }
336 
337   if (h11P->bitmap_unit != 8 && h11P->bitmap_unit != 16 &&
338       h11P->bitmap_unit != 32)  {
339     sprintf(errstr, "X11 bitmap_unit (%ld) is non-standard - can't handle",
340 	    (long)h11P->bitmap_unit);
341     return(xwdError(errstr));
342   }
343 
344   grayscale = 1;
345   if (h11P->ncolors > 0) {      /* Read X11 colormap. */
346     int bufsize = h11P->ncolors * sizeof(X11XColor);
347 
348     if (bufsize/sizeof(X11XColor) != h11P->ncolors)
349       return(xwdError("too many colors"));
350     x11colors = (X11XColor*) malloc(bufsize);
351     if (!x11colors) return(xwdError("out of memory"));
352 
353     if (h11P->header_size + bufsize
354 	+ h11P->pixmap_height * h11P->bytes_per_line + h11P->ncolors * 4
355 	== filesize ) word64 = 1;
356 
357     if (word64) {
358       for (i = 0; i < h11P->ncolors; ++i) {
359 	if (fread(&pad, sizeof(pad), (size_t) 1, file ) != 1)
360 	  return(xwdError("couldn't read X11 XWD colormap"));
361 
362 	if (fread( &x11colors[i], sizeof(X11XColor), (size_t) 1, file) != 1)
363 	  return(xwdError("couldn't read X11 XWD colormap"));
364       }
365     }
366     else {
367       if (fread(x11colors, sizeof(X11XColor), (size_t) h11P->ncolors, file)
368 	  != h11P->ncolors)
369 	return(xwdError("couldn't read X11 XWD colormap"));
370     }
371 
372     for (i = 0; i < h11P->ncolors; ++i) {
373       if (byte_swap) {
374 	x11colors[i].red   = (CARD16) bs_short(x11colors[i].red);
375 	x11colors[i].green = (CARD16) bs_short(x11colors[i].green);
376 	x11colors[i].blue  = (CARD16) bs_short(x11colors[i].blue);
377       }
378 
379       if (maxv != 65535L) {
380 	x11colors[i].red   = (u_short) ((x11colors[i].red   * maxv) / 65535);
381 	x11colors[i].green = (u_short) ((x11colors[i].green * maxv) / 65535);
382 	x11colors[i].blue  = (u_short) ((x11colors[i].blue  * maxv) / 65535);
383       }
384       if (x11colors[i].red != x11colors[i].green ||
385 	  x11colors[i].green != x11colors[i].blue)
386 	grayscale = 0;
387     }
388   }
389 
390   *visualclassP = h11P->visual_class;
391   /* SJT: FIXME. If bits_per_pixel == 16, maxv could be either 31 or 63.
392      It doesn't matter, though, because maxv is never used beyond here.
393    */
394   if (*visualclassP == TrueColor || *visualclassP == DirectColor) {
395     if (h11P->bits_per_pixel == 16) maxv = 31;
396     else maxv = 255;
397   }
398 
399   else if (*visualclassP == StaticGray && h11P->bits_per_pixel == 1) {
400     maxv = 1;
401     /* B/W bitmaps have a two entry colormap */
402     pinfo->r[0] = pinfo->g[0] = pinfo->b[0] = 255;   /* 0 = white */
403     pinfo->r[1] = pinfo->g[1] = pinfo->b[1] = 0;     /* 1 = black */
404   }
405 
406   else if (*visualclassP == StaticGray) {
407     maxv = (1 << h11P->bits_per_pixel) - 1;
408     for (i=0; i<=maxv; i++)
409       pinfo->r[i] = pinfo->g[i] = pinfo->b[i] = x11colors[i].red;
410   }
411 
412   else {
413     if (grayscale) {
414       for (i=0; i<=h11P->ncolors; i++)
415 	pinfo->r[i] = pinfo->g[i] = pinfo->b[i] = x11colors[i].red;
416     }
417     else {
418       for (i = 0; i < h11P->ncolors; ++i) {
419 	pinfo->r[i] = x11colors[i].red;
420 	pinfo->g[i] = x11colors[i].green;
421 	pinfo->b[i] = x11colors[i].blue;
422       }
423     }
424   }
425 
426   *colsP = h11P->pixmap_width;
427   *rowsP = h11P->pixmap_height;
428   *padrightP = h11P->bytes_per_line * 8 / h11P->bits_per_pixel -
429     h11P->pixmap_width;
430 
431   bits_per_item  = h11P->bitmap_unit;
432   bits_per_pixel = h11P->bits_per_pixel;
433   byte_order     = h11P->byte_order;
434   bit_order      = h11P->bitmap_bit_order;
435   bits_per_rgb   = h11P->bits_per_rgb;
436 
437 
438   /* add sanity-code for freako 'exceed' server, where bitmapunit = 8
439      and bitsperpix = 32 (and depth=24)... */
440 
441   if (bits_per_item < bits_per_pixel) {
442     bits_per_item = bits_per_pixel;
443 
444     /* round bits_per_item up to next legal value, if necc */
445     if      (bits_per_item <  8) bits_per_item = 8;
446     else if (bits_per_item < 16) bits_per_item = 16;
447     else                         bits_per_item = 32;
448   }
449 
450 
451   /* which raises the question:  how (can?) you ever have a 24 bits per pix,
452      (i.e., 3 bytes, no alpha/padding) */
453 
454 
455   bits_used  = bits_per_item;
456 
457   if (bits_per_pixel == sizeof(pixel_mask) * 8)  pixel_mask = (CARD32) -1;
458   else pixel_mask = (1 << bits_per_pixel) - 1;
459 
460   red_mask = h11P->red_mask;
461   grn_mask = h11P->grn_mask;
462   blu_mask = h11P->blu_mask;
463 
464   getcolorshift(red_mask, &red_shift_right, &red_justify_left);
465   getcolorshift(grn_mask, &grn_shift_right, &grn_justify_left);
466   getcolorshift(blu_mask, &blu_shift_right, &blu_justify_left);
467 
468   byteP  = (char   *) buf;
469   shortP = (CARD16 *) buf;
470   longP  = (CARD32 *) buf;
471 
472   return 0;
473 }
474 
475 
476 /* SJT: figure out the proper shifts */
getcolorshift(CARD32 mask,int * rightshift,int * leftshift)477 static void getcolorshift (CARD32 mask, int *rightshift, int *leftshift)
478 {
479   int lshift, rshift;
480   unsigned int uu;
481 
482   if (mask == 0)
483   {
484     *rightshift = *leftshift = 0;
485     return;
486   }
487 
488   uu = mask;
489   lshift = rshift = 0;
490   while ((uu & 0xf) == 0)
491   {
492       rshift += 4;
493       uu >>= 4;
494   }
495   while ((uu & 1) == 0)
496   {
497       rshift++;
498       uu >>= 1;
499   }
500 
501   while (uu != 0)
502   {
503       if (uu & 1)
504       {
505           lshift++;
506           uu >>= 1;
507       }
508   }
509   *rightshift = rshift;
510   *leftshift = CHAR_BIT * sizeof(pixel) - lshift;
511   return;
512 }
513 
514 
515 /******************************/
getpixnum(file)516 static CARD32 getpixnum(file)
517      FILE* file;
518 {
519   int n;
520 
521   if (bits_used == bits_per_item) {
522     switch (bits_per_item) {
523     case 8:
524       *byteP = getc(file);
525       break;
526 
527     case 16:
528       if (byte_order == MSBFirst) {
529 	if (readbigshort(file, shortP) == -1)
530 	  xwdWarning("unexpected EOF");
531       }
532       else {
533 	if (readlittleshort(file, shortP) == -1)
534 	  xwdWarning("unexpected EOF");
535       }
536       break;
537 
538     case 32:
539       if (byte_order == MSBFirst) {
540 	if (readbiglong(file, longP) == -1)
541 	  xwdWarning("unexpected EOF");
542       }
543       else {
544 	if (readlittlelong(file, longP) == -1)
545 	  xwdWarning("unexpected EOF");
546       }
547       break;
548 
549     default:
550       xwdWarning("can't happen");
551     }
552     bits_used = 0;
553 
554     if (bit_order == MSBFirst)
555       bit_shift = bits_per_item - bits_per_pixel;
556     else
557       bit_shift = 0;
558   }
559 
560   switch (bits_per_item) {
561   case 8:
562     n = (*byteP >> bit_shift) & pixel_mask;
563     break;
564 
565   case 16:
566     n = (*shortP >> bit_shift) & pixel_mask;
567     break;
568 
569   case 32:
570     n = (*longP >> bit_shift) & pixel_mask;
571     break;
572 
573   default:
574     n = 0;
575     xwdWarning("can't happen");
576   }
577 
578   if (bit_order == MSBFirst) bit_shift -= bits_per_pixel;
579                         else bit_shift += bits_per_pixel;
580 
581   bits_used += bits_per_pixel;
582 
583   return n;
584 }
585 
586 
587 /***************************/
xwdError(st)588 static int xwdError(st)
589      const char *st;
590 {
591   if (pic8  != NULL) free(pic8);
592   if (pic24 != NULL) free(pic24);
593 
594   SetISTR(ISTR_WARNING,"%s:  %s", bname, st);
595   return 0;
596 }
597 
598 
599 /***************************/
xwdWarning(st)600 static void xwdWarning(st)
601      const char *st;
602 {
603   SetISTR(ISTR_WARNING,"%s:  %s", bname, st);
604 }
605 
606 
607 
608 
609 
610 /*
611  * Byte-swapping junk.
612  */
613 
614 union cheat {
615   CARD32 l;
616   CARD16 s;
617   CARD8  c[sizeof(CARD32)];
618 };
619 
bs_short(s)620 static int bs_short(s)
621      int s;
622 {
623   union cheat u;
624   unsigned char t;
625 
626   u.s = (CARD16) s;
627   t = u.c[0];  u.c[0] = u.c[1];  u.c[1] = t;
628   return (int) u.s;
629 }
630 
bs_long(l)631 static CARD32 bs_long(l)
632      CARD32 l;
633 {
634   union cheat u;
635   unsigned char t;
636 
637   u.l = l;
638   t = u.c[0];  u.c[0] = u.c[3];  u.c[3] = t;
639   t = u.c[1];  u.c[1] = u.c[2];  u.c[2] = t;
640   return u.l;
641 }
642 
643 
644 
645 
646 
647 
648 /*
649  * Endian I/O.
650  */
651 
readbigshort(in,sP)652 static int readbigshort(in, sP)
653      FILE  *in;
654      CARD16 *sP;
655 {
656   *sP = (getc(in) & 0xff) << 8;
657   *sP |= getc(in) & 0xff;
658 
659   if (ferror(in)) return -1;
660   return 0;
661 }
662 
readbiglong(in,lP)663 static int readbiglong(in, lP)
664      FILE *in;
665      CARD32 *lP;
666 {
667   *lP  = (getc(in) & 0xff) << 24;
668   *lP |= (getc(in) & 0xff) << 16;
669   *lP |= (getc(in) & 0xff) << 8;
670   *lP |=  getc(in) & 0xff;
671 
672   if (ferror(in)) return -1;
673   return 0;
674 }
675 
676 
readlittleshort(in,sP)677 static int readlittleshort(in, sP)
678      FILE  *in;
679      CARD16 *sP;
680 {
681   *sP  =  getc(in) & 0xff;
682   *sP |= (getc(in) & 0xff) << 8;
683 
684   if (ferror(in)) return -1;
685   return 0;
686 }
687 
688 
readlittlelong(in,lP)689 static int readlittlelong(in, lP)
690      FILE *in;
691      CARD32 *lP;
692 {
693   *lP  =  getc(in) & 0xff;
694   *lP |= (getc(in) & 0xff) << 8;
695   *lP |= (getc(in) & 0xff) << 16;
696   *lP |= (getc(in) & 0xff) << 24;
697 
698   if (ferror(in)) return -1;
699   return 0;
700 }
701 
702 
703 #if 0 /* NOTUSED */
704 static int writebiglong(out, l)
705      FILE* out;
706      CARD32 l;
707 {
708   putc((l>>24) & 0xff, out);
709   putc((l>>16) & 0xff, out);
710   putc((l>> 8) & 0xff, out);
711   putc( l      & 0xff, out);
712   return 0;
713 }
714 
715 
716 static int writebigshort(out, s)
717      FILE* out;
718      int   s;
719 {
720   putc((s>>8)&0xff, out);
721   putc(s&0xff, out);
722   return 0;
723 }
724 #endif /* 0 (NOTUSED) */
725