home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume5 / pbm3 / part3 / pbmtomacp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-02-03  |  6.4 KB  |  312 lines

  1. /* pbmtomacp.c - read a portable bitmap and produce a MacPaint bitmap file
  2. **
  3. ** Copyright (C) 1988 by Douwe vand der Schaaf.
  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 <stdio.h>
  14. #include "pbm.h"
  15. #include "macp.h"
  16.  
  17. #define TRUE        1
  18. #define FALSE        0
  19. #define EQUAL        1
  20. #define UNEQUAL        0
  21.  
  22. FILE *fdout;
  23. char *Program;
  24. char *usage =
  25.     "usage:  %s [-l left] [-r right] [-b bottom] [-t top] [pbmfile]\n";
  26.  
  27. extern int optind;
  28. extern char *optarg;
  29.  
  30. main(argc, argv)
  31. int argc;
  32. char *argv[];
  33. { int c;
  34.   FILE *ifd;
  35.   bit **bits, **bitsr;
  36.   int rows, cols;
  37.   int left,bottom,right,top;
  38.   int lflg, rflg, tflg, bflg, errflg;
  39.   char name[100];
  40. int i,j;
  41.  
  42.   fdout = stdout;
  43.   Program = argv[0];
  44.   errflg = lflg = rflg = tflg = bflg = 0;
  45.   if( argc > 1 )
  46.   { while( ( c = getopt( argc, argv, "l:r:t:b:" ) ) != EOF )
  47.     switch(c)
  48.     {
  49. case 'l':
  50.       lflg++;
  51.       left = atoi( optarg );
  52.       break;
  53.  
  54. case 'r':
  55.       rflg++;
  56.       right = atoi( optarg );
  57.       break;
  58.  
  59. case 't':
  60.       tflg++;
  61.       top = atoi( optarg );
  62.       break;
  63.  
  64. case 'b':
  65.       bflg++;
  66.       bottom = atoi( optarg );
  67.       break;
  68.  
  69. case '?':
  70. default:
  71.        errflg++;
  72.     }
  73.     if (errflg)
  74.     { fprintf( stderr, "%s: ERROR. incorrect flag\n", Program );
  75.       fprintf( stderr, usage, Program );
  76.       exit(1);
  77.   } }
  78.  
  79.   if ( argc - optind > 1 )
  80.   { fprintf( stderr, "%s: ERROR. more than 1 inputfile given.\n", Program );
  81.     fprintf( stderr, usage, Program );
  82.     exit( 2 );
  83.   }
  84.  
  85.   if ( optind == argc - 1 )
  86.   { ifd = fopen( argv[optind], "r" );
  87.     if ( ifd == NULL )
  88.     { fprintf( stderr, "%s: can't open.\n", argv[optind] );
  89.       exit( 3 );
  90.     }
  91.     strcpy( name, argv[optind] );
  92.   }
  93.   else
  94.   { ifd = stdin;
  95.     strcpy( name, "noname" );
  96.   }
  97.  
  98.   bitsr = pbm_readpbm( ifd, &cols, &rows );
  99.  
  100.   if ( ifd != stdin )
  101.     fclose( ifd );
  102.     
  103.   bits = pbm_allocarray( MAX_COLS, MAX_LINES );
  104.  
  105.   if( !lflg )
  106.     left = 0;
  107.  
  108.   if( rflg )
  109.   { if( right - left >= MAX_COLS )
  110.       right = left + MAX_COLS - 1;
  111.   }
  112.   else
  113.     right = ( left + MAX_COLS > cols ) ? ( cols - 1 ) : ( left + MAX_COLS - 1 );
  114.  
  115.   if( !tflg )
  116.     top = 0;
  117.  
  118.   if( bflg )
  119.   { if( bottom - top >= MAX_LINES )
  120.       bottom = top + MAX_LINES - 1;
  121.   }
  122.   else
  123.     bottom = ( top + MAX_LINES > rows ) ?
  124.            ( rows - 1 ) : ( top + MAX_LINES - 1 );
  125.   
  126.   if( !checkborders( top, left, bottom, right ) )
  127.     exit( 4 );
  128.  
  129.   fillbits( bits, bitsr, top, left, bottom, right );
  130.  
  131.   writemacp( bits );
  132.  
  133. } /* main */
  134.  
  135. /* - - - - - - - - - - - - - - - - - - - - - - - - - - */
  136.  
  137. checkborders( top, left, bottom, right )
  138. int top, left, bottom, right;
  139. { if( right <= left || left < 0 || right - left + 1 > MAX_COLS )
  140.   { fprintf(stderr,"%s: error in right (= %d) and/or left (=%d)\n",
  141.           Program,right,left );
  142.     return( FALSE );
  143.   }
  144.   if( bottom <= top || top < 0 || bottom - top + 1 > MAX_LINES )
  145.   { fprintf(stderr,"%s: error in bottom (= %d) and/or top (=%d)\n",
  146.           Program,bottom,top );
  147.     return( FALSE );
  148.   }
  149.   return( TRUE );
  150. } /* checkborders */
  151.  
  152. /* - - - - - - - - - - - - - - - - - - - - - - - - - - */
  153.  
  154. /* centreer het over te zenden plaatje in het MacPaint document
  155.  *
  156.  * Het plaatje wordt vanaf al of niet opgegeven (left, bottom)
  157.  * in een pbm bitmap van de juist macpaint afmetingen gezet,
  158.  * en eventueel afgekapt.
  159.  */
  160. fillbits( bits, bitsr, top, left, bottom, right )
  161. bit **bits, **bitsr;
  162. int top, left, bottom, right;
  163. { register bit *bi, *bir;
  164.   register int i, j;
  165.   register int bottomr, leftr, topr, rightr;
  166.   int width, height;
  167.  
  168.   width = right - left + 1;
  169.   leftr = (MAX_COLS - width) / 2;
  170.   rightr = leftr + width - 1;
  171.  
  172.   height = bottom - top + 1;
  173.   topr = ( MAX_LINES - height ) / 2;
  174.   bottomr = topr + height - 1;
  175.  
  176.   for( i = 0; i < topr; i++ )
  177.   { bi = bits[i];
  178.     for( j = 0; j < MAX_COLS; j++ )
  179.       *bi++ = 0;
  180.   }
  181.  
  182.   for( i = topr; i <= bottomr; i++ )
  183.   { bi = bits[i];
  184.     { for( j = 0; j < leftr; j++ )
  185.     *bi++ = 0;
  186.       bir = bitsr[ i - topr + top ];
  187.       for( j = leftr; j <= rightr; j++ )
  188.     *bi++ = bir[j - leftr + left];
  189.       for( j = rightr + 1; j < MAX_COLS; j++ )
  190.     *bi++ = 0;
  191.   } }
  192.  
  193.   for( i = bottomr + 1; i < MAX_LINES; i++ )
  194.   { bi = bits[i];
  195.     for( j = 0; j < MAX_COLS; j++ )
  196.       *bi++ = 0;
  197.   }
  198. } /* fillbits */
  199.       
  200. /* - - - - - - - - - - - - - - - - - - - - - - - - - - */
  201.  
  202. writemacp( bits )
  203. bit **bits;
  204. { register int i;
  205.   bit pb[MAX_COLS * 2];
  206.   int npb;
  207.  
  208.   header();
  209.   for( i=0; i < MAX_LINES; i++ )
  210.   { npb = packit( pb, bits[i] );
  211.     sendbytes( pb, npb );
  212.   }
  213. } /* writemacp */
  214.  
  215. /* - - - - - - - - - - - - - - - - - - - - - - - - - - */
  216.  
  217. /* pack regel van MacPaint doc in Apple's format
  218.  * return value = # of bytes in pb 
  219.  */
  220. int
  221. packit( pb, bits )
  222. bit *pb, *bits;
  223. { register int i, charcount, npb, newcount, flg;
  224.   bit temp[72];
  225.   bit *count, *srcb, *destb, save;
  226.  
  227.   srcb = bits; destb = temp;
  228.   filltemp( destb, srcb );
  229.   srcb = temp;
  230.   destb = pb;
  231.   npb = 0;
  232.   charcount = BYTES_WIDE;
  233.   flg = EQUAL;
  234.   while( charcount )
  235.   { save = *srcb++;
  236.     charcount--;
  237.     newcount = 1;
  238.     while( (*srcb == save) && charcount )
  239.     { srcb++;
  240.       newcount++;
  241.       charcount--;
  242.     }
  243.     if( newcount > 2 )
  244.     { count = destb++;
  245.       *count = 257 - newcount;
  246.       *destb++ = save;
  247.       npb += 2;
  248.       flg = EQUAL;
  249.     }
  250.     else
  251.     { if( flg == EQUAL )
  252.       { count = destb++;
  253.     *count = newcount - 1;
  254.     npb++;
  255.       }
  256.       else
  257.     *count += newcount;
  258.       while( newcount-- )
  259.       { *destb++ = save;
  260.         npb++;
  261.       }
  262.       flg = UNEQUAL;
  263.   } }
  264.   return npb;
  265. } /* packit */
  266.  
  267. /* - - - - - - - - - - - - - - - - - - - - - - - - - - */
  268.  
  269. filltemp( dest, src )
  270. bit *src, *dest;
  271. { register unsigned char ch, zero, acht;
  272.   register int i, j;
  273.  
  274.   zero = '\0';
  275.   acht = 8;
  276.   i = BYTES_WIDE;
  277.   while( i-- )
  278.   { ch = zero; 
  279.     j = acht;
  280.     while( j-- )
  281.     { ch <<= 1;
  282.       if( *src++ )
  283.     ch++;
  284.     }
  285.     *dest++ = ch;
  286.   }
  287. } /* filltemp */
  288.  
  289. /* - - - - - - - - - - - - - - - - - - - - - - - - - - */
  290.  
  291. sendbytes( pb, npb )
  292. bit *pb;
  293. register int npb;
  294. { register bit *b;
  295.  
  296.   b = pb;
  297.   while( npb-- )
  298.     putc( *b++, fdout );
  299. } /* sendbytes */
  300.  
  301. /* - - - - - - - - - - - - - - - - - - - - - - - - - - */
  302.  
  303. header()
  304. { register int i;
  305.   register char ch;
  306.  
  307.   /* header contains nothing ... */
  308.   ch = '\0';
  309.   for(i = 0; i < HEADER_LENGTH; i++ )
  310.     putc( ch, fdout );
  311. } /* header */
  312.