home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume14 / ataritoppm / part01 / ppmtopi1.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-07-15  |  3.9 KB  |  284 lines

  1. #include <stdio.h>
  2.  
  3. /*
  4.  *  ppmtppi1.c - Reads a portable pixmap (ppm) file on stdin and
  5.  *  writes a Degas PI1 file on stdout.
  6.  *
  7.  *  Copyright (C) 1990, Steve Belczyk
  8.  */
  9.  
  10. char *progname;
  11.  
  12. int pal[16][3];        /* Degas palette */
  13.  
  14. /* This is the ST's video RAM */
  15. short screen[16000];
  16.  
  17. /* RAWBITS flag */
  18. int rawbits;
  19.  
  20. /* Picture resolution */
  21. int xres, yres;
  22.  
  23. main (argc, argv)
  24. int argc;
  25. char *argv[];
  26. {
  27.     char magic[10];
  28.     int i, maxpix;
  29.     
  30.     progname = argv[0];
  31.     
  32.     /* Check for bogus arguments */
  33.     if (argc != 1)
  34.     {
  35.         fprintf (stderr, "usage: %s <ppmfile >pi1file\n",
  36.              progname);
  37.         exit (-1);
  38.     }
  39.  
  40.     /* Read ppm header, validate fields */
  41.     GetPPMHeader (magic, &xres, &yres, &maxpix);
  42.  
  43.     if ( (magic[0] != 'P') && (magic[0] != 'p') )
  44.     {
  45.         fprintf (stderr, "Not a ppm file.\n");
  46.         exit (-1);
  47.     }
  48.     if (magic[1] == '3')
  49.     {
  50.         rawbits = 0;
  51.     }
  52.     else if (magic[1] == '6')
  53.     {
  54.         rawbits = 1;
  55.     }
  56.     else
  57.     {
  58.         fprintf (stderr, "%s: Not a ppm file.\n", progname);
  59.         exit (-1);
  60.     }
  61.  
  62.     if ( (xres > 320) || (yres > 200) )
  63.     {
  64.         fprintf (stderr,
  65.             "%s: Resolution greater than 320x200. Sorry.\n",
  66.             progname);
  67.         exit (-1);
  68.     }
  69.  
  70.     /* Clear the bitmap */
  71.     for (i=0; i<16000; screen[i++]=0);
  72.  
  73.     /* Read the PPM data */
  74.     ReadPPM();
  75.  
  76.     /* Write the PI1 file */
  77.     WritePI1();
  78. }
  79.  
  80. WritePI1 ()
  81. {
  82.     int i, w;
  83.  
  84.     PutWord (0);    /* Low resolution */
  85.  
  86.     /* Write palette */
  87.     for (i=0; i<16; i++)
  88.     {
  89.         w  = (0xe0 & pal[i][0]) << 3;
  90.         w |= (0xe0 & pal[i][1]) >> 1;
  91.         w |= (0xe0 & pal[i][2]) >> 5;
  92.         PutWord (w);
  93.     }
  94.  
  95.     /* Write video RAM */
  96.     WriteScreen();
  97. }
  98.  
  99. SetPixel (x, y, c)
  100. int x, y, c;
  101. {
  102.     int index, bit, plane;
  103.  
  104.     /* In the next few statements, the bit operations are a little
  105.        quicker, but the arithmetic versions are easier to read and
  106.        maybe more portable.  Please try swapping them if you have
  107.        trouble on your machine. */
  108.  
  109. /*    index = (80 * y) + 4 * (x / 16);    */
  110.     index = (y << 6) + (y << 4) + ((x >> 4) << 2);
  111.  
  112. /*    bit = 0x8000 >> (x % 16);    */
  113.     bit = 0x8000 >> (x & 0x0f);
  114.  
  115.     for (plane=0; plane<4; plane++)
  116.     {
  117.         if (c & (1 << plane))
  118.         {
  119.             screen[index+plane] |= bit;
  120.         }
  121.     }
  122. }
  123.  
  124. WriteScreen ()
  125. {
  126.     int i;
  127.  
  128.     for (i=0; i<16000; i++)
  129.     {
  130.         PutWord (screen[i]);
  131.     }
  132. }
  133.  
  134. GetString (s)
  135. char *s;
  136. {
  137.     int i;
  138.     char c;
  139.  
  140.     /* Skip leading white space */
  141.     do
  142.     {
  143.         c = GetChar();
  144.     } while ( (c == ' ') || (c == '\t') || (c == '\n') );
  145.  
  146.     /* Build string */
  147.     i = 0;
  148.     do
  149.     {
  150.         s[i++] = c;
  151.         if (i > 8) break;
  152.         c = GetChar();
  153.     } while ( (c != ' ') && (c != '\t') && (c != '\n') );
  154.  
  155.     s[i] = 0;
  156.     return;
  157. }
  158.  
  159. int GetChar()
  160. {
  161.     int c;
  162.  
  163.     c = getchar();
  164.  
  165.     if (c == EOF)
  166.     {
  167.         fprintf (stderr, "%s: Premature EOF.\n", progname);
  168.         exit (-1);
  169.     }
  170.  
  171.     do
  172.     {
  173.         if (c == '#')    /* Comment character */
  174.         {
  175.             do    /* Skip to end-of-line */
  176.             {
  177.                 c = getchar();
  178.                 if (c == EOF)
  179.                 {
  180.                     fprintf (stderr,
  181.                       "%s: Premature EOF.\n",
  182.                       progname);
  183.                     exit (-1);
  184.                 }
  185.             } while (c != '\n');
  186.  
  187.             c = getchar();
  188.         }
  189.     } while (c == '#');    /* In case there's another comment */
  190.  
  191.     return (c);
  192. }
  193.  
  194. GetPPMHeader (magic, xres, yres, maxpix)
  195. char *magic;
  196. int *xres, *yres, *maxpix;
  197. {
  198.     char s[10];
  199.  
  200.     GetString (magic);
  201.  
  202.     GetString (s);
  203.     *xres = atoi(s);
  204.  
  205.     GetString (s);
  206.     *yres = atoi(s);
  207.  
  208.     GetString (s);
  209.     *maxpix = atoi(s);
  210. }
  211.  
  212. ReadPPM ()
  213. {
  214.     int x, y, n, r, g, b, i;
  215.     
  216.     n = 0;    /* counts colors */
  217.     
  218.     for (y=0; y<yres; y++)
  219.     {
  220.         for (x=0; x<xres; x++)
  221.         {
  222.             if (rawbits)
  223.             {
  224.                 r = 0xff & getchar();
  225.                 g = 0xff & getchar();
  226.                 b = 0xff & getchar();
  227.             }
  228.             else
  229.             {
  230.                 scanf ("%d %d %d", &r, &g, &b);
  231.             }
  232.             i = FindColor (&n, r, g, b);
  233.             SetPixel (x, y, i);
  234.         }
  235.     }
  236. }
  237.  
  238. int FindColor (n, r, g, b)
  239. int *n, r, g, b;
  240. {
  241.     int i;
  242.     
  243.     r = 0xe0 & r;
  244.     g = 0xe0 & g;
  245.     b = 0xe0 & b;
  246.     
  247.     for (i=0; i<(*n); i++)
  248.     {
  249.         if ( (r == pal[i][0]) &&
  250.              (g == pal[i][1]) &&
  251.              (b == pal[i][2]) )
  252.         {
  253.             return (i);
  254.         }
  255.     }
  256.     
  257.     if ((*n) > 15)
  258.     {
  259.         fprintf (stderr, "%s: More than 16 colors.\n", progname);
  260.         exit (-1);
  261.     }
  262.  
  263.     pal[*n][0] = r;
  264.     pal[*n][1] = g;
  265.     pal[*n][2] = b;
  266.     
  267.     i = (*n);
  268.     (*n)++;
  269.  
  270.     return (i);
  271. }
  272.  
  273. PutWord (w)
  274. int w;
  275. {
  276.     char c0, c1;
  277.     
  278.     c0 = 0xff & (w >> 8);
  279.     c1 = 0xff & w;
  280.     
  281.     putchar (c0);
  282.     putchar (c1);
  283. }
  284.