home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / netpbma.zip / pbm / gemtopbm.c < prev    next >
C/C++ Source or Header  |  1994-02-02  |  6KB  |  216 lines

  1. /*
  2.  * Convert a GEM .img file to a portable bitmap file.
  3.  *
  4.  * Author: Diomidis D. Spinellis
  5.  * (C) Copyright 1988 Diomidis D. Spinellis.
  6.  *
  7.  * Permission to use, copy, modify, and distribute this software and its
  8.  * documentation for any purpose and without fee is hereby granted,
  9.  * provided that the above copyright notice appear in all copies and that
  10.  * both that copyright notice and this permission notice appear in
  11.  * supporting documentation.
  12.  *
  13.  * This file is provided AS IS with no warranties of any kind.  The author
  14.  * shall have no liability with respect to the infringement of copyrights,
  15.  * trade secrets or any patents by this file or any part thereof.  In no
  16.  * event will the author be liable for any lost revenue or profits or
  17.  * other special, indirect and consequential damages.
  18.  *
  19.  * Comments and additions should be sent to the author:
  20.  *
  21.  *                     Diomidis D. Spinellis
  22.  *                     1 Myrsinis Str.
  23.  *                     GR-145 62 Kifissia
  24.  *                     GREECE
  25.  *
  26.  * 92/07/11 Johann Haider
  27.  * Changed to read from stdin if file is omitted
  28.  * Changed to handle line length not a multipe of 8
  29.  *
  30.  * 94/01/31 Andreas Schwab (schwab@ls5.informatik.uni-dortmund.de)
  31.  * Changed to remove architecture dependency and conform to
  32.  * PBM coding standard.
  33.  * Added more tests for garbage.
  34.  */
  35.  
  36. #include <assert.h>
  37. #include "pbm.h"
  38.  
  39. char pattern[8];
  40.  
  41. static void getinit ARGS ((FILE *file, int *colsP, int *rowsP, int *padrightP,
  42.                int *patlenP));
  43.  
  44. int
  45. main(argc, argv)
  46.     int             argc;
  47.     char           *argv[];
  48. {
  49.     int             debug = 0;
  50.     FILE           *f;
  51.     int             x;
  52.     int             i, j, k, l;
  53.     int             c, cc, linerep;
  54.     int        rows, cols;
  55.     bit        *bitrow;
  56.     int padright, patlen;
  57.     char *usage = "[-debug] [gemfile]";
  58.     int argn = 1;
  59.  
  60.     pbm_init( &argc, argv );
  61.  
  62.     while (argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0')
  63.       {
  64.         if (pm_keymatch(argv[1], "-debug", 2))
  65.           debug = 1;
  66.         else
  67.           pm_usage (usage);
  68.         ++argn;
  69.       }
  70.  
  71.     if (argc == argn)
  72.         f = stdin;
  73.     else {
  74.         f = pm_openr (argv[argn]);
  75.         ++argn;
  76.     }
  77.  
  78.     if (argn != argc)
  79.       pm_usage (usage);
  80.  
  81.     getinit (f, &cols, &rows, &padright, &patlen);
  82.  
  83.     pbm_writepbminit( stdout, cols, rows, 0 );
  84.     bitrow = pbm_allocrow (cols + padright);
  85.  
  86.     for (i = 0; i < rows; ) {
  87.         x = 0;
  88.         linerep = 1;
  89.         while (x < cols) {
  90.             switch (c = getc(f)) {
  91.             case 0x80:    /* Bit String */
  92.                 c = getc(f);    /* Byte count */
  93.                 if (debug)
  94.                     pm_message(
  95.                         "bit string of %d bytes",
  96.                         c );
  97.                 
  98.                 if (x + c * 8 > cols + padright)
  99.                   pm_error ("bad byte count");
  100.                 for (j = 0; j < c; ++j) {
  101.                     cc = getc(f);
  102.                     for (k = 0x80; k; k >>= 1) {
  103.                         bitrow[x] = (k & cc) ? PBM_BLACK : PBM_WHITE;
  104.                         ++x;
  105.                     }
  106.                 }
  107.                 break;
  108.             case 0:        /* Pattern run */
  109.                 c = getc(f);    /* Repeat count */
  110.                 if (debug)
  111.                     pm_message(
  112.                         "pattern run of %d repetitions",
  113.                         c );
  114.                                 /* line repeat */
  115.                                 if (c == 0) {
  116.                                         c = getc(f);
  117.                                         if (c != 0x00ff)
  118.                                                 pm_error( "badly formed line repeat" );
  119.                                         linerep = getc(f);
  120.                                         break;
  121.                                 }
  122.                 fread (pattern, 1, patlen, f);
  123.                 if (x + c * patlen * 8 > cols + padright)
  124.                   pm_error ("bad pattern repeat count");
  125.                 for (j = 0; j < c; ++j)
  126.                     for (l = 0; l < patlen; ++l)
  127.                         for (k = 0x80; k; k >>= 1) {
  128.                             bitrow[x] = (k & pattern[l]) ? PBM_BLACK : PBM_WHITE;
  129.                             ++x;
  130.                         }
  131.                 break;
  132.  
  133.             default:    /* Solid run */
  134.                 if (debug)
  135.                     pm_message(
  136.                         "solid run of %d bytes %s",
  137.                         c & 0x7f,
  138.                         c & 0x80 ? "on" : "off" );
  139.                                 /* each byte had eight bits DSB */
  140.                                 l = (c & 0x80) ? PBM_BLACK : PBM_WHITE;
  141.                                 c = (c & 0x7f) * 8;
  142.                                 if (x + c > cols + padright)
  143.                   pm_error ("bad solid run repeat count");
  144.                 for (j = 0; j < c; ++j) {
  145.                                         bitrow[x] = l;
  146.                     ++x;
  147.                                 }
  148.                 break;
  149.  
  150.             case EOF:    /* End of file */
  151.                 pm_error( "end of file reached" );
  152.  
  153.             }
  154.         }
  155.                 if ( debug )
  156.                         pm_message( "EOL row %d", i );
  157.                 if (x != cols + padright)
  158.                         pm_error( "EOL beyond edge" );
  159.         while (linerep--)
  160.           {
  161.             pbm_writepbmrow( stdout, bitrow, cols, 0 );
  162.             ++i;
  163.           }
  164.     }
  165.     pm_close( f );
  166.     pm_close( stdout );
  167.     exit(0);
  168. }
  169.  
  170. static void
  171. getinit (file, colsP, rowsP, padrightP, patlenP)
  172.      FILE *file;
  173.      int *colsP;
  174.      int *rowsP;
  175.      int *padrightP;
  176.      int *patlenP;
  177. {
  178.   short s;
  179.   short headlen;
  180.  
  181.   if (pm_readbigshort (file, &s) == -1) /* Image file version */
  182.     pm_error ("EOF / read error");
  183.   if (s != 1)
  184.     pm_error ("unknown version number (%d)", (int) s);
  185.   if (pm_readbigshort (file, &headlen) == -1) /* Header length in words */
  186.     pm_error ("EOF / read error");
  187.   if (headlen < 8)
  188.     pm_error ("short header (%d)", (int) headlen);
  189.   if (pm_readbigshort (file, &s) == -1) /* Number of planes */
  190.     pm_error ("EOF / read error");
  191.   if (s != 1)
  192.     pm_error ("color IMG not supported");
  193.   if (pm_readbigshort (file, &s) == -1) /* Pattern definition length (bytes) */
  194.     pm_error ("EOF / read error");
  195.   if (s < 1 || s > 8)
  196.     pm_error ("illegal pattern length (%d)", (int) s);
  197.   *patlenP = (int) s;
  198.   if (pm_readbigshort (file, &s) == -1 /* Pixel height (microns) */
  199.       || pm_readbigshort (file, &s) == -1 /* Pixel height (microns) */
  200.       || pm_readbigshort (file, &s) == -1) /* Scan line width */
  201.     pm_error ("EOF / read error");
  202.   *colsP = (int) s;
  203.   if (pm_readbigshort (file, &s) == -1) /* Number of scan line items */
  204.     pm_error ("EOF / read error");
  205.   *rowsP = (int) s;
  206.   *padrightP = 7 - ((*colsP + 7) & 7);
  207.  
  208.   headlen -= 8;
  209.   while (headlen-- > 0)
  210.     {
  211.       (void) getc (file);
  212.       (void) getc (file);
  213.     }
  214. }
  215.  
  216.