home *** CD-ROM | disk | FTP | other *** search
/ BCI NET / BCI NET Dec 94.iso / archives / programming / source / fbm12s.lha / flcmps.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-07-18  |  9.3 KB  |  302 lines

  1. /*****************************************************************
  2.  * flcmps.c: FBM Release 1.2 06-May-93 Michael Mauldin
  3.  *
  4.  * Copyright (C) 1993 by Michael Mauldin.  Permission is granted
  5.  * to use this file in whole or in part for any purpose, educational,
  6.  * recreational or commercial, provided that this copyright notice
  7.  * is retained unchanged.  This software is available to all free of
  8.  * charge by anonymous FTP and in the UUNET archives.
  9.  *
  10.  * flcmps.c: 
  11.  *
  12.  * CONTENTS
  13.  *    write_simple_ps (image, wfile)
  14.  *
  15.  * EDITLOG
  16.  *    LastEditDate = Wed May 26 14:04:52 1993 - Mike Mauldin
  17.  *    LastFileName = /usr/mlm/fbm/flcmps.c
  18.  *
  19.  * HISTORY
  20.  * 26-May-93  Michael Mauldin (mlm) at Carnegie-Mellon University
  21.  *    Created.
  22.  *****************************************************************/
  23.  
  24. # include <stdio.h>
  25. # include <ctype.h>
  26. # include "fbm.h"
  27.  
  28. #ifndef lint
  29. static char *fbmid =
  30. "$FBM flcmps.c <1.2> 26-May-93  (C) 1993 by Michael Mauldin, source \
  31. code available free from MLM@CS.CMU.EDU and from UUNET archives$";
  32. #endif
  33.  
  34. /* map 3, 4, 17, 19, and 20 to nearest valid grayscale */
  35. int ps_gray_char[256] = {
  36.   0,  1,  2,  2,  5,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
  37.  16, 16, 18, 18, 21, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
  38.  32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
  39.  48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
  40.  64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
  41.  80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
  42.  96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111,
  43. 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
  44. 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
  45. 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
  46. 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
  47. 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
  48. 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
  49. 208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
  50. 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
  51. 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255 };
  52.  
  53. /* map 3, 4, 17, 19, and 20 to nearest valid grayscale */
  54. int ps_1bit_char[256] = {
  55.   0,  1,  2,  5,  2,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
  56.  16,  9, 18, 35, 36, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
  57.  32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
  58.  48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
  59.  64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
  60.  80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
  61.  96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111,
  62. 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
  63. 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
  64. 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
  65. 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
  66. 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
  67. 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
  68. 208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
  69. 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
  70. 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255 };
  71.  
  72. /****************************************************************
  73.  * analyze_image: Determine color/grayscale and bits
  74.  ****************************************************************/
  75.  
  76. analyze_image (image, iscolor, bits, padlen)
  77. FBM *image;
  78. int *iscolor, *bits, *padlen;
  79. { register int i, j, w, h, rowlen, plnlen, pad;
  80.   register unsigned char *ibm, *s, *tail, *rd, *gr, *bl;
  81.   int nclrs, onebit, fourbit, mapped;
  82.  
  83.   mapped = (image->hdr.clrlen > 0);
  84.  
  85.   w = image->hdr.cols;
  86.   h = image->hdr.rows;
  87.   rowlen = image->hdr.rowlen;
  88.   plnlen = image->hdr.plnlen;
  89.  
  90.   /*================ Detect color vs grayscale ================*/
  91.   if (image->hdr.planes > 1)
  92.   { *iscolor = 1; }
  93.   else if (!mapped)
  94.   { *iscolor = 0; }
  95.   else
  96.   {
  97.     /* Check for color or grayscale image */
  98.     nclrs = image->hdr.clrlen / 3;
  99.     rd = image->cm;
  100.     gr = rd + nclrs;
  101.     bl = gr + nclrs;
  102.  
  103.     for (*iscolor=0, i=0; i<nclrs; i++)
  104.  
  105.     { if (rd[i] != gr[i] || rd[i] != bl[i])
  106.       { *iscolor=1; break; }
  107.     }
  108.   }
  109.  
  110.   /*================ Detect 1, 4 or 8 bits ================*/  
  111.   if (mapped)
  112.   { onebit = fourbit = 1;
  113.   
  114.     ibm = image->bm;
  115.     rd = image->cm;
  116.  
  117.     for (s=ibm, tail = s + image->hdr.plnlen; s<tail; s++)
  118.     { if (rd[*s] != 0 && rd[*s] != 255 ||
  119.       gr[*s] != 0 && gr[*s] != 255 ||
  120.       bl[*s] != 0 && bl[*s] != 255)
  121.       { onebit = 0; break; }
  122.     }
  123.     
  124.     for (s=ibm, tail = s + image->hdr.plnlen; s<tail; s++)
  125.     { if ((rd[*s] & 0x0f) && rd[*s] != 255 ||
  126.       (gr[*s] & 0x0f) && gr[*s] != 255 ||
  127.       (bl[*s] & 0x0f) && bl[*s] != 255 )
  128.       { fourbit = 0; break; }
  129.     }
  130.     
  131.     *bits = onebit ? 1 : fourbit ? 4 : 8;
  132.   }
  133.   else
  134.   { onebit = fourbit = 1;
  135.  
  136.     for (s=image->bm, tail = s + image->hdr.plnlen * image->hdr.planes;
  137.      s<tail;
  138.      s++)
  139.     { if (*s != 0 && *s != 255)
  140.       { onebit = 0; break; }
  141.     }
  142.     
  143.  
  144.     for (s=image->bm, tail = s + image->hdr.plnlen * image->hdr.planes;
  145.      s<tail;
  146.      s++)
  147.     { if (*s & 0x0f)
  148.       { fourbit = 0; break; }
  149.     }
  150.     
  151.     if (*iscolor && onebit)
  152.     { onebit = 0; fourbit = 1; }
  153.  
  154.     *bits = onebit ? 1 : fourbit ? 4 : 8;
  155.   }
  156.   
  157.   /*=======================================================*/
  158.   
  159.   fprintf (stderr, "flcmps: type of file: %d bit %s %s\n", *bits,
  160.        mapped ? "mapped" : "unmapped", *iscolor ? "color" : "grayscale");
  161.   
  162.   pad = (*bits == 1) ? 8 : (*bits == 4) ? 2 : 1;
  163.   *padlen = pad * ((w + pad - 1) / pad);
  164.   if (*padlen < rowlen)
  165.   { fprintf (stderr, "Error: rowlen %d, padlen smaller at %d\n",
  166.          rowlen, *padlen);
  167.     abort ();
  168.   }
  169.   
  170. }
  171.  
  172.  
  173.  
  174. /****************************************************************
  175.  * write a simple postscript data stream without ^C, ^D, ^Q, ^S or ^T
  176.  ****************************************************************/
  177.  
  178. write_simple_ps (image, wfile, iscolor, bits, padlen)
  179. FBM *image;
  180. FILE *wfile;
  181. int iscolor, bits, padlen;
  182. { register int i, j, w, h, rowlen, plnlen;
  183.   register unsigned char *ibm, *s, *tail, *rd, *gr, *bl;
  184.   int nclrs, onebit, fourbit, mapped;
  185.  
  186.   mapped = (image->hdr.clrlen > 0);
  187.   
  188.   w = image->hdr.cols;
  189.   h = image->hdr.rows;
  190.   rowlen = image->hdr.rowlen;
  191.   plnlen = image->hdr.plnlen;
  192.  
  193.   if (mapped)
  194.   { /* Check for color or grayscale image */
  195.     nclrs = image->hdr.clrlen / 3;
  196.     rd = image->cm;
  197.     gr = rd + nclrs;
  198.     bl = gr + nclrs;
  199.   }
  200.  
  201.   write_simple_decoder (padlen, h, bits, iscolor);
  202.  
  203.   if (iscolor && mapped)
  204.   { for (j=0; j<h; j++)
  205.     { write_simple_scanline (rowlen, padlen, bits, &image->bm[j * rowlen], rd);
  206.       write_simple_scanline (rowlen, padlen, bits, &image->bm[j * rowlen], gr);
  207.       write_simple_scanline (rowlen, padlen, bits, &image->bm[j * rowlen], bl);
  208.     }
  209.   }
  210.   else if (iscolor)
  211.   { for (j=0; j<h; j++)
  212.     { write_simple_scanline (rowlen, padlen, bits,
  213.                  &image->bm[j * rowlen], NULL);
  214.       write_simple_scanline (rowlen, padlen, bits,
  215.                  &image->bm[j * rowlen + plnlen], NULL);
  216.       write_simple_scanline (rowlen, padlen, bits,
  217.                  &image->bm[j * rowlen + 2 * plnlen], NULL);
  218.       
  219.     }
  220.   }
  221.   else
  222.   { for (j=0; j<h; j++)
  223.     { write_simple_scanline (rowlen, padlen, bits,
  224.                  &image->bm[j * rowlen], image->cm);
  225.     }
  226.   }
  227.  
  228.   printf ("\n");
  229.  
  230.   return (1);
  231. }
  232.  
  233. /****************************************************************
  234.  * write_simple_scanline
  235.  ****************************************************************/
  236.  
  237. # define PIXEL(C) (cmap ? cmap[ibm[C]] : ibm[C])
  238.  
  239. write_simple_scanline (rowlen, padlen, bits, ibm, cmap)
  240. register int rowlen, padlen;
  241. int bits;
  242. register unsigned char *ibm, *cmap;
  243. { register int i, ch;
  244.  
  245.   switch (bits)
  246.   { case 1:    for (i=0; i<padlen; i++)
  247.         { ch = (i<rowlen && PIXEL(i)) ? 1 : 0; ch <<= 1;
  248.           ch |= (++i<rowlen && PIXEL(i)) ? 1 : 0; ch <<= 1;
  249.           ch |= (++i<rowlen && PIXEL(i)) ? 1 : 0; ch <<= 1;
  250.           ch |= (++i<rowlen && PIXEL(i)) ? 1 : 0; ch <<= 1;
  251.           ch |= (++i<rowlen && PIXEL(i)) ? 1 : 0; ch <<= 1;
  252.           ch |= (++i<rowlen && PIXEL(i)) ? 1 : 0; ch <<= 1;
  253.           ch |= (++i<rowlen && PIXEL(i)) ? 1 : 0; ch <<= 1;
  254.           ch |= (++i<rowlen && PIXEL(i)) ? 1 : 0;
  255.           putchar (ps_1bit_char[ch]);
  256.         }
  257.         break;
  258.  
  259.  
  260.     case 4:    for (i=0; i<padlen; i++)
  261.         { ch = (i<rowlen) ? (PIXEL(i) >> 4) : 0; ch <<= 4;
  262.           ch |= (++i<rowlen) ? (PIXEL(i) >> 4) : 0;
  263.           putchar (ps_gray_char[ch]);
  264.         }
  265.         break;
  266.  
  267.     default:    for (i=0; i<padlen; i++)
  268.         { ch = (i<rowlen) ? PIXEL(i) : 0;
  269.           putchar (ps_gray_char[ch]);
  270.         }
  271.   }
  272. }
  273.  
  274.  
  275. /****************************************************************
  276.  * write_simple_decoder: Write a postscript header for the image
  277.  ****************************************************************/
  278.  
  279. write_simple_decoder (w, h, bits, iscolor)
  280. int w, h, bits, iscolor;
  281. {
  282.  
  283.   if (iscolor)
  284.   { printf ("/redScanLine %d string def\n", w);
  285.     printf ("/greenScanLine %d string def\n", w);
  286.     printf ("/blueScanLine %d string def\n", w);
  287.     printf ("%d %d %d [%d 0 0 -%d 0 %d]\n", w, h, bits, w, h, h);
  288.     printf ("{currentfile redScanLine readstring pop}\n");
  289.     printf ("{currentfile greenScanLine readstring pop}\n");
  290.     printf ("{currentfile blueScanLine readstring pop}\n");
  291.     printf ("true 3 colorimage\n");
  292.   }
  293.   else
  294.   { 
  295.     printf ("/scanline %d string def\n", w);
  296.     printf ("%d %d %d\n", w, h, bits);
  297.     printf ("[ %d 0 0 -%d 0 %d ]\n", w, h, h);
  298.     printf ("{ currentfile scanline readstring pop } bind\n");
  299.     printf ("image\n");
  300.   }
  301. }
  302.