source: abuse/trunk/src/imlib/readxwd.cpp @ 56

Last change on this file since 56 was 56, checked in by Sam Hocevar, 15 years ago
  • Add licensing terms to most C / C++ files (Ref #5).
File size: 18.2 KB
Line 
1/*
2 *  Abuse - dark 2D side-scrolling platform game
3 *  Copyright (c) 1995 Crack dot Com
4 *
5 *  This software was released into the Public Domain. As with most public
6 *  domain software, no warranty is made or implied by Crack dot Com or
7 *  Jonathan Clark.
8 */
9
10#include "config.h"
11
12#include "image.hpp"
13#include "palette.hpp"
14#define MAXCOLORS 256
15//#define MC(x) (((x)<3)==0)
16#define MC(x) (x!=0)
17
18// the following table converts rgb to cym.
19int ca[8]={1,1,1,1,0,0,0,0},
20    ma[8]={1,0,1,0,1,0,1,0},
21    ya[8]={1,1,0,0,1,1,0,0};
22// the following defines make a color threshold
23#define RGB2C(r,g,b) (char)(ca[MC(b)|MC(g)<<1|MC(r)<<2])
24#define RGB2Y(r,g,b) (char)(ya[MC(b)|MC(g)<<1|MC(r)<<2])
25#define RGB2M(r,g,b) (char)(ma[MC(b)|MC(g)<<1|MC(r)<<2])
26
27#define LSBFirst        0
28#define MSBFirst        1
29
30#define XYBitmap        0
31#define XYPixmap        1
32#define ZPixmap         2
33
34#define StaticGray      0
35#define GrayScale       1
36#define StaticColor     2
37#define PseudoColor     3
38#define TrueColor       4
39#define DirectColor     5
40
41typedef unsigned long xwdval;
42#define X11WD_FILE_VERSION 7
43typedef struct {
44    xwdval header_size;         /* Size of the entire file header (bytes). */
45    xwdval file_version;        /* X11WD_FILE_VERSION */
46    xwdval pixmap_format;       /* Pixmap format */
47    xwdval pixmap_depth;        /* Pixmap depth */
48    xwdval pixmap_width;        /* Pixmap width */
49    xwdval pixmap_height;       /* Pixmap height */
50    xwdval xoffset;             /* Bitmap x offset */
51    xwdval byte_order;          /* MSBFirst, LSBFirst */
52    xwdval bitmap_unit;         /* Bitmap unit */
53    xwdval bitmap_bit_order;    /* MSBFirst, LSBFirst */
54    xwdval bitmap_pad;          /* Bitmap scanline pad */
55    xwdval bits_per_pixel;      /* Bits per pixel */
56    xwdval bytes_per_line;      /* Bytes per scanline */
57    xwdval visual_class;        /* Class of colormap */
58    xwdval red_mask;            /* Z red mask */
59    xwdval green_mask;          /* Z green mask */
60    xwdval blue_mask;           /* Z blue mask */
61    xwdval bits_per_rgb;        /* Log base 2 of distinct color values */
62    xwdval colormap_entries;    /* Number of entries in colormap */
63    xwdval ncolors;             /* Number of Color structures */
64    xwdval window_width;        /* Window width */
65    xwdval window_height;       /* Window height */
66    long window_x;              /* Window upper left X coordinate */
67    long window_y;              /* Window upper left Y coordinate */
68    xwdval window_bdrwidth;     /* Window border width */
69    } X11WDFileHeader;
70
71typedef struct {
72    unsigned long pixel;
73    unsigned short red, green, blue;
74    char flags;                 /* do_red, do_green, do_blue */
75    char pad;
76    } X11XColor;
77
78image *getinit(FILE *file, palette *&pal, int *padrightP);
79void getimage(FILE *file,image *image, int pad);
80int getpixnum(FILE *file);
81
82
83HBITMAP readxwd(char *input_file,palette *&pal)
84//char *hdfpal,int *palsize,int *cols,int *rows)
85{
86  FILE *ifd;
87  char *imageP;
88  unsigned int nspace;
89  int padright;
90  HBITMAP im;
91
92  /* open input file */
93  if (strcmp(input_file,"-") == 0)
94    ifd = stdin;d)
95  { printf("Unable to open %s\n"
96           "Get your story right and try again.\n",input_file);
97    exit(0);
98  }
99  printf("Reading image\n");
100  im=getinit( ifd, pal, &padright, int &xres, int &yres);
101//cols, rows, &padright, palsize, hdfpal);
102
103  /* alloc image array */
104
105  /* fill image array */
106  getimage(ifd, im, padright);
107
108  return(im);
109}
110
111int bits_per_item, bits_used, bit_shift, bits_per_pixel, pixel_mask;
112int bit_order, byte_swap;
113char buf[4];
114char *byteP;
115short *shortP;
116long *longP;
117
118
119int32_t bs_int32(int32_t s);
120int16_t bs_int16(int16_t s );
121
122
123HBITMAP getinit(FILE *file, palette *&pal, int *padrightP, int &xres, int &yres);)
124{
125  /* Assume X11 headers are larger than X10 ones. */
126  unsigned char header[sizeof(X11WDFileHeader)];
127  image *im;
128  X11WDFileHeader *h11P;
129  char junk[800];
130  int i, np, dummy1, dummy2, dummy3;
131  unsigned  short minred, maxred;
132  X11XColor x11col;
133
134  h11P = (X11WDFileHeader *) header;
135
136  if (fread(header,sizeof(*h11P),1,file) != 1 )
137    {
138      fprintf(stderr,"couldn't read X11 XWD file header");
139      exit(-1);
140    }
141  if ( h11P->file_version != X11WD_FILE_VERSION )
142    {
143      byte_swap = 1;
144      h11P->header_size = bltl(h11P->header_size);
145      h11P->file_version = bltl(h11P->file_version);
146      h11P->pixmap_format = bltl(h11P->pixmap_format);
147      h11P->pixmap_depth = bltl(h11P->pixmap_depth);
148      h11P->pixmap_width = bltl(h11P->pixmap_width);
149      h11P->pixmap_height = bltl(h11P->pixmap_height);
150      h11P->xoffset =  bltl(h11P->xoffset);
151      h11P->byte_order =  bltl(h11P->byte_order);
152      h11P->bitmap_unit = bltl(h11P->bitmap_unit);
153      h11P->bitmap_bit_order = bltl(h11P->bitmap_bit_order);
154      h11P->bitmap_pad = bltl(h11P->bitmap_pad);
155      h11P->bits_per_pixel = bltl(h11P->bits_per_pixel);
156      h11P->bytes_per_line = bltl(h11P->bytes_per_line);
157      h11P->visual_class = bltl(h11P->visual_class);
158      h11P->red_mask = bltl(h11P->red_mask);
159      h11P->green_mask = bltl(h11P->green_mask);
160      h11P->blue_mask = bltl(h11P->blue_mask);
161      h11P->bits_per_rgb = bltl(h11P->bits_per_rgb);
162      h11P->colormap_entries = bltl(h11P->colormap_entries);
163      h11P->ncolors = bltl(h11P->ncolors);
164      h11P->window_width = bltl(h11P->window_width);
165      h11P->window_height = bltl(h11P->window_height);
166      h11P->window_x = bltl(h11P->window_x);
167      h11P->window_y = bltl(h11P->window_y);
168      h11P->window_bdrwidth = bltl(h11P->window_bdrwidth);
169    }
170
171  if ( fread( junk, 1, h11P->header_size - sizeof(*h11P), file ) !=
172      h11P->header_size - sizeof(*h11P) )
173    {
174      fprintf(stderr,"couldn't read rest of X11 XWD file header");
175      exit(-1);
176    }
177
178  /* Check whether we can handle this dump. */
179  if ( h11P->pixmap_depth > 8 )
180    {
181      fprintf(stderr,"can't handle X11 pixmap_depth > 8");
182      exit(-1);
183    }
184  if ( h11P->bits_per_rgb > 8 )
185    {
186      fprintf(stderr,"can't handle X11 bits_per_rgb > 8");
187      exit(-1);
188    }
189  if ( h11P->ncolors > MAXCOLORS )
190    {
191      fprintf(stderr,"can't handle X11 ncolors > %d");
192      exit(-1);
193    }
194  if ( h11P->pixmap_format != ZPixmap )
195    {
196      fprintf(stderr,"can't handle X11 pixmap_format %d", h11P->pixmap_format,
197              0,0,0,0 );
198      exit(-1);
199    }
200  if ( h11P->bitmap_unit != 8 && h11P->bitmap_unit != 16 &&
201      h11P->bitmap_unit != 32 )
202    {
203      fprintf(stderr,"X11 bitmap_unit (%d) is non-standard - can't handle");
204      exit(-1);
205    }
206  xres=h11P->pixmap_width;
207  yres=h11P->pixmap_height;
208  im=new image(h11P->pixmap_width,h11P->pixmap_height);
209  pal=new palette(h11P->colormap_entries);
210  *padrightP = h11P->bytes_per_line * 8 / h11P->bits_per_pixel - im->width();
211
212/*****************************************************************************/
213  /* Read X11 colormap. */
214minred = 65535;
215maxred = 0;
216  for ( i = 0; i < h11P->colormap_entries; i++ )
217    {
218      if ( fread( &x11col, sizeof(X11XColor), 1, file ) != 1 )
219        {
220          fprintf(stderr,"couldn't read X11 XWD colormap");
221          exit(-1);
222        }
223        else
224        {
225          x11col.pixel=bltl(x11col.pixel);
226          x11col.red=bstl(x11col.red);
227          x11col.green=bstl(x11col.green);
228          x11col.blue=bstl(x11col.blue);
229        }
230      if (x11col.pixel < 256)
231        {
232          if (minred > x11col.red) minred = x11col.red;
233          if (maxred < x11col.red) maxred = x11col.red;
234          dummy1 = (unsigned) x11col.red / 256 ;
235          dummy2 = (unsigned) x11col.green / 256 ;
236          dummy3 = (unsigned) x11col.blue / 256 ;
237          pal->set(i,dummy1,dummy2,dummy3);
238        }
239      else
240        {
241          fprintf(stderr,"pixel value outside of valid HDF palette\n");
242          exit(-1);
243        }
244    }
245  /* rest of stuff for getpixnum */
246  bits_per_item = h11P->bitmap_unit;
247  bits_used = bits_per_item;
248  bits_per_pixel = h11P->bits_per_pixel;
249  bit_order = h11P->bitmap_bit_order;
250  pixel_mask = ( 1 << bits_per_pixel ) - 1;
251
252  byteP = (char *) buf;
253  shortP = (short *) buf;
254  longP = (long *) buf;
255  return im;
256}
257
258void getimage(FILE *file,HBITMAP &im.int pad)
259{
260  int i,j;
261  unsigned char *sl;
262  for (i=0; i<im->height(); i++)
263    {
264      if (i%50==0)
265        printf("Line %d of %d\n",i+1,im->height());
266      sl=im->scan_line(i);
267      for (j=0; j<im->width(); j++)
268        sl[j]= getpixnum(file);
269
270      for ( j = 0; j < pad; j++ )
271        getpixnum( file );
272    }
273}
274
275
276int getpixnum(FILE *file)
277{
278  int p;
279
280  if ( bits_used == bits_per_item )
281    {
282      if ( fread( buf, bits_per_item / 8, 1, file ) != 1 )
283        fprintf(stderr, "couldn't read bits" );
284      if ( byte_swap )
285        switch ( bits_per_item )
286          {
287          case 8:
288            break;
289
290          case 16:
291            *shortP = bstl(*shortP) ;
292            break;
293
294          case 32:
295            *longP = bltl(*longP) ;
296            break;
297
298          default:
299            fprintf(stderr, "can't happen" );
300          }
301      bits_used = 0;
302
303//      if ( bit_order == MSBFirst )
304        bit_shift = bits_per_item - bits_per_pixel;
305//      else
306//      bit_shift = 0;
307    }
308
309  switch ( bits_per_item )
310    {
311    case 8:
312      p = ( *byteP >> bit_shift) & pixel_mask;
313      break;
314
315    case 16:
316      p = ( *shortP >> bit_shift) & pixel_mask;
317      break;
318
319    case 32:
320      p = ( *longP >> bit_shift) & pixel_mask;
321      break;
322
323    default:
324      fprintf(stderr, "can't happen" );
325    }
326
327//  if ( bit_order == MSBFirst )
328    bit_shift -= bits_per_pixel;
329//  else
330//    bit_shift += bits_per_pixel;
331  bits_used += bits_per_pixel;
332
333  return p;
334}
335
336
337short bs_int16(short s )
338{
339  short ss;
340  unsigned char *bp, t;
341
342  ss = s;
343  bp = (unsigned char *) &ss;
344  t = bp[0];
345  bp[0] = bp[1];
346  bp[1] = t;
347  return ss;
348}
349
350int32_t bs_int32(int32_t l )
351{
352  int32_t ii;
353  uint8_t *bp, t;
354
355  ii = i;
356  bp = (uint8_t *) &ii;
357  t = bp[0];
358  bp[0] = bp[3];
359  bp[3] = t;
360  t = bp[1];
361  bp[1] = bp[2];
362  bp[2] = t;
363  return ii;
364}
365
366struct BMP_header
367{
368  char id[2];
369  long filesize;
370  int reserved[2];
371  long headersize,infosize,width,height;
372  int biplanes,bits;
373  long bicompression, bisizeimage, bixpelspermeter, biypelspermeter,
374       biclrused,biclrimportant;
375} bmp;
376
377void write_bmp(image *im, palette *pal, char *filename)
378{
379  FILE *fp;
380  int i,bytes;
381  uint8_t pal_quad[4];
382//  fp=fopen("d:\\windows\\256color.bmp","rb");
383//  fread(&bmp,1,sizeof(bmp),fp);
384//  fclose(fp);
385  fp=fopen(filename,"wb");
386  if (!fp)
387  { printf("Error : unable to open %s for writing!\n");
388    exit(0);
389  }
390  bytes=(im->width()+3)/4;
391  memset((char *)&bmp,0,sizeof(bmp));
392  memcpy(bmp.id,"BM",2);
393  bmp.width=im->width();
394  bmp.height=im->height();
395  bmp.bits=8;
396  bmp.infosize=0x28L;
397  bmp.biplanes=1;
398  bmp.headersize=1078;
399  bmp.filesize=bmp.headersize+bytes*im->height()*4;
400  bmp.bisizeimage=im->width()*im->height();
401  bmp.biclrused=256;
402  bmp.biclrimportant=256;
403  fwrite(&bmp,1,sizeof(bmp),fp);
404  pal_quad[3]=0;
405  for (i=0;i<256;i++)
406  {
407    pal->get(i,pal_quad[2],pal_quad[1],pal_quad[0]);
408    fwrite(pal_quad,1,4,fp);
409  }
410  for (i=im->height();i;i--)
411    fwrite(im->scan_line(i-1),1,bytes*4,fp);
412  fclose(fp);
413}
414
415image *image24(image *im, palette *pal, int rev)
416{
417  image *ni;
418  uint8_t *sl1,*sl2;
419  int i,x;
420  uint8_t r,g,b;
421  printf("Creating image size (%d, %d)\n",im->width()*3,im->height());
422  ni=new image(im->width()*3,im->height());
423  printf("Image created\n");
424  for (i=0;i<im->height();i++)
425  {
426    if (i%50==0)
427      printf("Line %d of %d\n",i+1,im->height());
428
429    sl1=   sl2[x*3]=r; sl2[x*3+1]=g; sl2[x*3+2]=b;
430    }
431    im->set_page_swapable();
432  }
433  return ni;
434}
435
436uint8_t addb(int n1, int n2)
437{ int n3;
438  n3=n1+n2;
439  return n3>255 ? 255 : (n3<0 ? 0 : n3);
440}
441
442// this function takes an image min 8 bit format, converts it to 24 bit
443// color and dithers it so that it can be printed on an deskjet
444/// (i.e it reduces it down to 8 colors)
445image *color_dither(image *im, palette *pal, int rev)
446{
447  image *i24;
448  uint8_t min[3],max[3],mid[3],*ad,*sl,*sl2,crimp;
449  int i,j,x,y,delta;
450  (void *)ad=pal->addr();
451
452  // find the minimum and maximum  red green and blue in the image
453  memset(min,0xff,3); memset(max,0,3);
454  for (j=0;j<3;j++,ad++)
455    for (y=0;y<im->height();y++)
456    { sl2=im->scan_line(y);
457      for (x=0;x<im->width();x++)
458      {
459        if (ad[sl2[x]*3]<min[j]) min[j]=ad[i*3];
460        if (ad[sl2[x]*3]>max[j]) max[j]=ad[i*3];
461      }
462    }
463  // find the middle color used for red green and blue
464  for (i=0;i<3;i++)
465    mid[i]=(int)((int)max[i]+(int)min[i])/2;
466  // convert the image to 24 bit color.
467  printf("Converting to 24 bit color...\n");
468  i24=image24(im,pal,rev);
469  printf("Dithering using flyod stienberg algorithm\n");
470  for (y=0;y<im->height();y++)
471  { if (y%20==0)
472      printf("Line %d of %d\n",y+1,im->height());
473    sl=i24->scan_line(y);
474    i24->set_page_unswapable();
475
476    if (y+1<im->height())
477      sl2=i24->scan_line(y+1);  // get the scan line below this one
478    for (x=0;x<im->width();x++)
479    {
480      // diffuse the colors using flyod stienburg dithering algorithm
481      for (j=0;j<3;j++)
482      {
483        crimp = sl[x*3+j]>mid[j] ? 255 : 0;
484        delta=sl[x*3+j]-crimp;
485        sl[x*3+j]=crimp;
486        if (x+1<im->width())
487        { sl[(x+1)*3+j]=addb(sl[(x+1)*3+j],delta*7/16);
488          if (y+1<im->height())
489            sl2[(x+1)*3+j]=addb(sl2[(x+1)*3+j],delta*1/16);
490        }
491        if (y+1<im->height())
492        { if (x>0)
493            sl2[(x-1)*3+j]=addb(sl2[(x-1)*3+j],delta*3/16);
494          sl2[(x)*3+j]=addb(sl2[(x)*3+j],delta*5/16);
495        }
496      }
497    }
498    sl=i24->scan_line(y);
499    i24->set_page_swapable();
500
501  }
502  return i24;
503}
504
505image *rotate90(image *im)
506{
507  image *i;
508  int x,y,w,h;
509  w=im->width();
510  h=im->height();
511  printf("Rotating image 90 deg\n");
512  i=new image(im->height(),im->width());
513  for (x=0;x<w;x++)
514  {
515    if (x%20==0)
516      printf("Row %d of %d\n",x,im->width());
517    for (y=0;y<h;y++)
518      i->putpixel(y,w-x-1,im->pixel(x,y));
519  }
520  return i;
521}
522
523void deskjet_print(int argc, char **argv)
524{
525  int i,dpi=100;
526  int y,x,byteo,bito,outc,outy,outm,outcv, outyv,outmv, w,rev,inten,val,
527      display=0,bad=0,bmp=0,land=0,ch,xo=0,yo=0;
528  image *im,*i24;
529  palette *pal;
530  uint8_t *sl;
531  FILE *fp;
532  char def_name[10],*dev_name,*fname=NULL;
533  uint8_t cp[500],mp[500],yp[500],kp[500];
534  strcpy(def_name,"\\dev\\lp");  // set the default output device to /dev/lp
535                // since we are in vpix, however we will use the backslash
536  dev_name=def_name; rev=0;
537  for (i=1;i<argc;i++)
538    if (!strcmp(argv[i],"-dpi"))
539    { i++; dpi=atoi(argv[i]);
540      if (dpi!=75 && dpi!=100 && dpi!=150 && dpi!=300) bad=1; }
541    else if (!strcmp(argv[i],"-dev"))
542    { i++; dev_name=argv[i]; }
543    else if (!strcmp(argv[i],"-rev"))
544    { rev=1; }
545    else if (!strcmp(argv[i],"-land"))
546    { land=1; }
547    else if (!strcmp(argv[i],"-2bmp"))
548    { bmp=1; }
549    else if (!strcmp(argv[i],"-display"))
550    { display=1; }
551    else fname=argv[i];
552
553  if (!fname || bad)
554  { printf("usage : %s [-dev device] [-dpi 75,100,150,300]\n"
555           "     [-rev] [-display] [-2bmp] [-land] filename\n\n"
556           "  default dpi is 100 (possible are 75/100/150/300)\n"
557           "  default printer is /dev/lp\n"
558           "  -rev, reverse black and white on the print out\n"
559           "  -display only displays the image to the screen and does not print it\n"
560           "    all ither options will be ignored\n"
561           "  -2bmp converts the image X window dump to a MicroSoft Windows bitmap (BMP)\n"
562           "    the file written to must be specified by -dev [filename]\n"
563           "    all other options will be ignored\n"
564           "  -land prints the image in landscape mode (sideways)\n"
565           "  filename is the name of the dump created by xwd\n"
566           "  Using Dos, the command [%s -dev lpt1] should be used\n",argv[0],argv[0]);
567    exit(0);
568  }
569  im=readxwd(fname,pal);
570  if (!im || !pal)
571  { printf("failed to read the image or the palette!\n");
572    exit(0);
573  }
574  if (display)
575  {
576    set_mode(19,argc,argv);
577    pal->load();                         // set the palette for the image we are going to print
578    im->put_image(screen,0,0);          // put the image on thge söööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööö<0) yo+=10; break;
579      }
580    } while (ch!=' ' && ch!='q' && ch!=13);
581    close_graphics();
582  }
583  else if (bmp)
584    write_bmp(im,pal,dev_name);
585  else
586  {
587    fp=fopen(dev_name,"wb");  // open the output device for printing
588    if (!fp)
589    { printf("Unable to open %s for writing, make sure the path exsist and you\n"
590             "have write permission to the file\n",dev_name);
591      exit(0);
592    }
593    if (land)
594      im=rotate90(im);
595
596    w=im->width()+7; w/=8; w*=8;
597    fprintf(fp,"E"           // reset the printer
598               "&l%dO"      // portrait/landscape mode
599               "*rbC"        // reset graphics
600               "*t%dR"        // set the resolution
601               "*r%dS"       // set the image width
602               "*r1A"        // start raster graphics at left edge
603               "*r-4U"         // set to CYM mode
604               ,land,dpi,w);
605  // now loop through all the scan lines of the image and pcik out the planes
606  // we need
607    i24=color_dither(im,pal,rev);
608    rev=0;  // turn off the revser option because the conversion to 24 bit takes care of it
609    printf("Printing...");
610    for (y=0;y<im->height();y++)
611    {
612      if (y%20==0)
613        printf(".");
614
615      sl=i24->scan_line(y);
616  //initally set all the planes to clear, this should leave the paper white
617      memset(cp,0,500);  memset(mp,0,500);  memset(yp,0,500); memset(kp,0,500);
618  // now scan through the cyan plane of this scan line and pick out the bits
619      for (x=0,bito=7;x<im->width();x++)
620      {
621        outcv=RGB2C(sl[x*3],sl[x*3+1],sl[x*3+2]);
622        outyv=RGB2Y(sl[x*3],sl[x*3+1],sl[x*3+2]);
623        outmv=RGB2M(sl[x*3],sl[x*3+1],sl[x*3+2]);
624        if (outcv==outyv && outyv==outmv)
625        {
626          if ((rev && !outcv) || (!rev && outcv))
627            kp[x/8]^=(1<<bito);
628        } else
629        {
630          cp[x/8]^=(outcv<<bito);
631          yp[x/8]^=(outyv<<bito);
632          mp[x/8]^=(outmv<<bito);
633        }
634        if ((bito--)==0)
635          bito=7;
636      }
637      fprintf(fp,"%c*b%dV",27,w/8);  // print out the black plane first
638      fwrite(kp,1,w/8,fp);
639      fprintf(fp,"%c*b%dV",27,w/8);  // now the cyan plane
640      fwrite(cp,1,w/8,fp);
641      fprintf(fp,"%c*b%dV",27,w/8);  // now the yellow plane
642      fwrite(yp,1,w/8,fp);
643      fprintf(fp,"%c*b%dW",27,w/8);  // now the magenta plane
644      fwrite(mp,1,w/8,fp);
645    }
646    fprintf(fp,"%c*rbC%c",27,12);  // end graphics, switch everthing back to defaults
647                                   // and print a form feed to eject the paper.
648    fclose(fp); // flush out anything in the buffers and close the file
649    delete i24;  // clean up the memory that we allocated to the image and the palette
650  }
651  printf("\n");
652  delete im;
653  delete pal;
654}
655
656main(int argc, char **argv)
657{
658  setcbrk(1);  // set the control break on, so that printing can be interrupted
659  deskjet_print(argc,argv);
Note: See TracBrowser for help on using the repository browser.