home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 4 / DATAFILE_PDCD4.iso / utilities / utilsm / netpbmsca / pbm / c / pbmtog3 < prev    next >
Encoding:
Text File  |  1993-10-04  |  3.8 KB  |  225 lines

  1. /* pbmtog3.c - read a portable bitmap and produce a Group 3 FAX file
  2. **
  3. ** Copyright (C) 1989 by Paul Haeberli <paul@manray.sgi.com>.
  4. **
  5. ** Permission to use, copy, modify, and distribute this software and its
  6. ** documentation for any purpose and without fee is hereby granted, provided
  7. ** that the above copyright notice appear in all copies and that both that
  8. ** copyright notice and this permission notice appear in supporting
  9. ** documentation.  This software is provided "as is" without express or
  10. ** implied warranty.
  11. */
  12.  
  13. #include "pbm.h"
  14. #include "g3.h"
  15.  
  16. static void tofax ARGS(( bit* bitrow, int n ));
  17. static void putwhitespan ARGS(( int c ));
  18. static void putblackspan ARGS(( int c ));
  19. static void putcode ARGS(( tableentry* te ));
  20. static void puteol ARGS(( void ));
  21. static void putinit ARGS(( void ));
  22. static void putbit ARGS(( int d ));
  23. static void flushbits ARGS(( void ));
  24.  
  25. static int reversebits;
  26.  
  27. int
  28. main( argc, argv )
  29.     int argc;
  30.     char* argv[];
  31.     {
  32.     FILE* ifp;
  33.     bit* bitrow;
  34.     int argn, rows, cols, bigcols, format, row, col, i;
  35.     char* usage = " [-reversebits] [pbmfile]";
  36.  
  37.  
  38.     pbm_init( &argc, argv );
  39.  
  40.     argn = 1;
  41.     reversebits = 0;
  42.  
  43.     if ( argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0' )
  44.     {
  45.     if ( pm_keymatch( argv[argn], "-reversebits", 2 ) )
  46.         reversebits = 1;
  47.     else
  48.         pm_usage( usage );
  49.     ++argn;
  50.     }
  51.     
  52.     if ( argn == argc )
  53.     ifp = stdin;
  54.     else
  55.     {
  56.     ifp = pm_openr( argv[argn] );
  57.     ++argn;
  58.     }
  59.     
  60.     if ( argn != argc )
  61.     pm_usage( usage );
  62.  
  63.     pbm_readpbminit( ifp, &cols, &rows, &format );
  64.     bigcols = max( 1728, cols );
  65.     bitrow = pbm_allocrow( bigcols );
  66.  
  67.     /* Write out four extra rows to get things stabilized. */
  68.     putinit();
  69.     for ( col = 0; col < bigcols; ++col )
  70.     bitrow[col] = PBM_WHITE;
  71.     tofax( bitrow, bigcols );
  72.     tofax( bitrow, bigcols );
  73.     tofax( bitrow, bigcols );
  74.     tofax( bitrow, bigcols );
  75.  
  76.     /* Write out bitmap. */
  77.     for ( row = 0; row < rows; ++row )
  78.     {
  79.     pbm_readpbmrow( ifp, bitrow, cols, format );
  80.     for ( col = cols; col < bigcols; ++col )
  81.         bitrow[col] = PBM_WHITE;
  82.     tofax( bitrow, cols );
  83.     }
  84.  
  85.     /* And finish off. */
  86.     for( i = 0; i < 6; ++i )
  87.     puteol( );
  88.     flushbits( );
  89.  
  90.     pm_close( ifp );
  91.  
  92.     exit( 0 );
  93.     }
  94.  
  95. static void
  96. tofax(bitrow,n)
  97.     bit* bitrow;
  98.     int n;
  99. {
  100.     int c;
  101.  
  102.     while(n>0) {
  103.     c = 0;
  104.     while(*bitrow == PBM_WHITE && n>0) {
  105.         ++bitrow;
  106.         ++c;
  107.         --n;
  108.     }
  109.     putwhitespan(c);
  110.     c = 0;
  111.     if(n==0)
  112.         break;
  113.     while(*bitrow == PBM_BLACK && n>0) {
  114.         ++bitrow;
  115.         ++c;
  116.         --n;
  117.     }
  118.     putblackspan(c);
  119.     }
  120.     puteol();
  121. }
  122.  
  123. static void
  124. putwhitespan(c)
  125.     int c;
  126. {
  127.     int tpos;
  128.     tableentry* te;
  129.  
  130.     if(c>=64) {
  131.     tpos = (c/64)-1;
  132.     te = mwtable+tpos;
  133.     c -= te->count;
  134.     putcode(te);
  135.     }
  136.     tpos = c;
  137.     te = twtable+tpos;
  138.     putcode(te);
  139. }
  140.  
  141. static void
  142. putblackspan(c)
  143.     int c;
  144. {
  145.     int tpos;
  146.     tableentry* te;
  147.  
  148.     if(c>=64) {
  149.     tpos = (c/64)-1;
  150.     te = mbtable+tpos;
  151.     c -= te->count;
  152.     putcode(te);
  153.     }
  154.     tpos = c;
  155.     te = tbtable+tpos;
  156.     putcode(te);
  157. }
  158.  
  159. static void
  160. putcode(te)
  161.     tableentry* te;
  162. {
  163.     unsigned int mask;
  164.     int code;
  165.  
  166.     mask = 1<<(te->length-1);
  167.     code = te->code;
  168.     while(mask) {
  169.      if(code&mask)
  170.         putbit(1);
  171.     else
  172.         putbit(0);
  173.     mask >>= 1;
  174.     }
  175.  
  176. }
  177.  
  178. static void
  179. puteol()
  180. {
  181.     int i;
  182.  
  183.     for(i=0; i<11; ++i)
  184.     putbit(0);
  185.     putbit(1);
  186. }
  187.  
  188. static int shdata;
  189. static int shbit;
  190.  
  191. static void
  192. putinit()
  193. {
  194.     shdata = 0;
  195.     shbit = reversebits ? 0x01 : 0x80;
  196. }
  197.  
  198. static void
  199. putbit(d)
  200. int d;
  201. {
  202.     if(d) 
  203.     shdata = shdata|shbit;
  204.     if ( reversebits )
  205.     shbit = shbit<<1;
  206.     else
  207.     shbit = shbit>>1;
  208.     if((shbit&0xff) == 0) {
  209.     putchar(shdata);
  210.     shdata = 0;
  211.     shbit = reversebits ? 0x01 : 0x80;
  212.     }
  213. }
  214.  
  215. static void
  216. flushbits( )
  217. {
  218.     if ( ( reversebits && shbit != 0x01 ) ||
  219.      ( ! reversebits && shbit != 0x80 ) ) {
  220.     putchar(shdata);
  221.     shdata = 0;
  222.     shbit = reversebits ? 0x01 : 0x80;
  223.     }
  224. }
  225.