/*
 * writexwd - output xwd file.
 */

#include "x11wd.h"
#include <stdio.h>
/*****************************************************************************/

int
writexwd(outfile,image,xsize,ysize,pal,palsize)
     int palsize,xsize,ysize;
     char *outfile, image[], *pal;
{
  X11WDFileHeader header;
  int i, ix;
  X11XColor color;
  int nspace;
  int one,n,m;
  long Multi;
  FILE *of;

  if (strcmp(outfile,"stdout") == 0)
    of = stdout;
  else
    of = fopen(outfile,"w");
  nspace = xsize*ysize;
  
  m = colorstobpp(palsize);
  m = (m + 7) / 8 * 8;
  n = 1 << m;

  fprintf(stderr,"X dim = %d, Y dim = %d,\n",xsize,ysize);
  header.header_size = sizeof(header);
  header.file_version =  X11WD_FILE_VERSION;
  header.pixmap_format = ZPixmap;
  header.pixmap_depth =  m;
  header.pixmap_width =  xsize;
  header.pixmap_height =  ysize;
  header.xoffset =  0;
  header.byte_order =  LSBFirst;
  header.bitmap_unit =  8;
  header.bitmap_bit_order =  LSBFirst;
  header.bitmap_pad =  8;
  header.bits_per_pixel =  8;
  header.bytes_per_line =  xsize;
  header.visual_class =  PseudoColor;
  header.red_mask   =  0;
  header.green_mask =  0;
  header.blue_mask  =  0;
  header.bits_per_rgb =  header.pixmap_depth;
  header.colormap_entries =  n;
  header.ncolors = n;
  header.window_width  =  xsize;
  header.window_height =  ysize;
  header.window_x = 0;
  header.window_y = 0;
  header.window_bdrwidth = 0;

  one=1;
  if (fwrite(&header,header.header_size,one,of) != 1)
    {
      fprintf(stderr,"writexwd:  fwrite header failed\n");
      exit(1);
    }

  /* Write out the colormap. */
  color.flags = 7;
  color.pad = 0;
  Multi = 65535 / 255;
  for ( i = 0; i < palsize; i++ )
    {
      color.pixel = i;
      ix = i*3;
      color.red   = ((long) pal[ix])   * Multi;
      color.green = ((long) pal[ix+1]) * Multi;
      color.blue  = ((long) pal[ix+2]) * Multi;
      (void) fwrite( &color, sizeof(color),one,of );
    }
  /* padding */
  color.red   = 0;
  color.green = 0;
  color.blue  = 0;
  for (; i<n; i++)
    {
      color.pixel = i;
      (void) fwrite( &color, sizeof(color),one,of );
    }

  (void) fflush(of);
  (void) write(fileno(of), image, nspace);

}


int
colorstobpp( colors )
int colors;
    {
    int bpp;

    if ( colors <= 2 )
	bpp = 1;
    else if ( colors <= 4 )
	bpp = 2;
    else if ( colors <= 8 )
	bpp = 3;
    else if ( colors <= 16 )
	bpp = 4;
    else if ( colors <= 32 )
	bpp = 5;
    else if ( colors <= 64 )
	bpp = 6;
    else if ( colors <= 128 )
	bpp = 7;
    else if ( colors <= 256 )
	bpp = 8;
    else
	fprintf(stderr, "can't happen");

    return bpp;
    }
