home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 309.lha / PBM_PLUS / pbm / gemtopbm.c < prev    next >
C/C++ Source or Header  |  1980-12-04  |  5KB  |  213 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.  */
  27.  
  28. #include <stdio.h>
  29. #ifdef    SYSV
  30. #include <string.h>
  31. #else    SYSV
  32. #include <strings.h>
  33. #endif    SYSV
  34. #include <assert.h>
  35. #include "pbm.h"
  36. #include "libpbm.h"
  37.  
  38. /*
  39.  * Handle systems that do CR-LF translation on reading / writing and
  40.  * little endians (some guesswork is involved).
  41.  */
  42. #ifdef MSDOS
  43. #define LITTLE_ENDIAN
  44. #endif
  45. #ifdef xenix
  46. #define LITTLE_ENDIAN
  47. #endif
  48. #ifdef sun386
  49. #define LITTLE_ENDIAN
  50. #endif
  51.  
  52.  
  53. /* Seek from current position */
  54. #ifndef SEEK_CUR
  55. #define SEEK_CUR 1
  56. #endif
  57.  
  58. /*
  59.  * File header structure
  60.  */
  61. struct header {
  62.     short           version;/* Image file version */
  63.     unsigned short  hlen;    /* Header length in bytes */
  64.     unsigned short  planes;    /* Number of planes */
  65.     unsigned short  patlen;    /* Pattern definition length (bytes) */
  66.     unsigned short  pxlen;    /* Pixel height (microns) */
  67.     unsigned short  pxht;    /* Pixel height (microns) */
  68.     unsigned short  linewid;/* Scan line width (bytes) */
  69.     unsigned short  nitems;    /* Number of scan line items */
  70. };
  71.  
  72. /*
  73.  * Scan item header
  74.  */
  75. struct line {
  76.     char            d1, d2;    /* Should be 0 */
  77.     char            d3;    /* Should be 0xff */
  78.     char            count;    /* Repetition count */
  79. };
  80.  
  81. char            pattern[256];
  82.  
  83.  
  84. static void byteswap();
  85. static void pbmout();
  86. extern int      errno;
  87. extern char    *sys_errlist[];
  88. #define strerror(x) (sys_errlist[x])
  89.  
  90. void
  91. main(argc, argv)
  92.     int             argc;
  93.     char           *argv[];
  94. {
  95.     int             debug = 0;
  96.     FILE           *f;
  97.     struct header   hd;
  98.     int             x;
  99.     int             i, j, k, l;
  100.     int             c, cc;
  101.     int        rows, cols;
  102.     bit        *bitrow;
  103.  
  104.     pm_progname = argv[0];
  105.  
  106.     /* Check if the compiler alligns structures the way we want */
  107.     assert( sizeof( struct header ) == 16 ) ;
  108.  
  109.     if (argc > 1 && !strcmp(argv[1], "-d")) {
  110.         argc--;
  111.         argv[1] = argv[0];
  112.         argv++;
  113.         debug++;
  114.     }
  115.  
  116.     if (argc != 2)
  117.         pm_usage("[-d] <gemfile>");
  118.  
  119.     f = pm_openr( argv[1] );
  120.  
  121.     if (fread(&hd, sizeof hd, 1, f) != 1)
  122.         pm_error( "read %s", strerror(errno), 0,0,0,0 );
  123.  
  124. #ifdef LITTLE_ENDIAN
  125.     byteswap((unsigned short *) &hd, sizeof hd / 2);
  126. #endif
  127.  
  128.     if( fseek(f, (long) hd.hlen * 2 - sizeof(struct header), SEEK_CUR) == -1 )
  129.         pm_error( "fseek %s", strerror(errno), 0,0,0,0 );
  130.  
  131.     if (debug)
  132.         fprintf(stderr,
  133.             " version\t\t%d\n hlen\t\t%d\n planes\t\t%d\n patlen\t\t%d\n pxlen\t\t%d\n pxht\t\t%d\n linewid\t\t%d\n nitems\t\t%d\n",
  134.                 hd.version, hd.hlen, hd.planes, hd.patlen, hd.pxlen,
  135.                 hd.pxht, hd.linewid, hd.nitems);
  136.  
  137.     cols = hd.linewid % 8 == 0 ? hd.linewid : hd.linewid + 8 - hd.linewid % 8;
  138.     rows = hd.nitems;
  139.     pbm_writepbminit( stdout, cols, rows );
  140.     bitrow = pbm_allocrow( cols );
  141.  
  142.     for (i = 0; i < hd.nitems; i++) {
  143.         x = 0;
  144.         while (x < hd.linewid) {
  145.             switch (c = getc(f)) {
  146.             case 0x80:    /* Bit String */
  147.                 c = getc(f);    /* Byte count */
  148.                 if (debug)
  149.                     fprintf(stderr,
  150.                         "Bit string of %d bytes\n", c);
  151.                 for (j = 0; j < c; j++) {
  152.                     cc = getc(f);
  153.                     for (k = 0x80; k; k >>= 1) {
  154.                         bitrow[x] = (k & cc) ? PBM_BLACK : PBM_WHITE;
  155.                         x++;
  156.                 }
  157.                 }
  158.                 break;
  159.             case 0:        /* Pattern run */
  160.                 c = getc(f);    /* Repeat count */
  161.                 if (debug)
  162.                     fprintf(stderr,
  163.                         "Pattern run of %d repetitions\n",
  164.                         c);
  165.                 fread(pattern, 1, hd.patlen, f);
  166.                 for (j = 0; j < c; j++)
  167.                     for (l = 0; l < hd.patlen; l++)
  168.                         for (k = 0x80; k; k >>= 1) {
  169.                             bitrow[x] = (k & pattern[l]) ? PBM_BLACK : PBM_WHITE;
  170.                             x++;
  171.                         }
  172.                 break;
  173.  
  174.             default:    /* Solid run */
  175.                 if (debug)
  176.                     fprintf(stderr,
  177.                         "Solid run of %d bytes %s\n",
  178.                         c & 0x7f,
  179.                         c & 0x80 ? "on" : "off");
  180.                 for (i = 0; i < c & 0x7f; i++) {
  181.                     bitrow[x] = (c & 0x80) ? PBM_BLACK : PBM_WHITE;
  182.                     x++;
  183.                 }
  184.                 break;
  185.  
  186.             case EOF:    /* End of file */
  187.                 pm_error( "end of file reached", 0,0,0,0,0 );
  188.  
  189.             }
  190.         }
  191.         pbm_writepbmrow( stdout, bitrow, cols );
  192.     }
  193.     pm_close( f );
  194.     exit(0);
  195. }
  196.  
  197. #ifdef LITTLE_ENDIAN
  198. static void
  199. byteswap(data, n)
  200.     unsigned short *data;
  201.     int             n;
  202. {
  203.     register        i;
  204.     char           *p, c;
  205.  
  206.     for (i = 0, p = (char *) data; i < n; i++, p++) {
  207.         c = *p;
  208.         *p = *(p + 1);
  209.         *++p = c;
  210.     }
  211. }
  212. #endif
  213.