about summary refs log tree commit diff
path: root/converter/pbm/pbmtomacp.c
diff options
context:
space:
mode:
Diffstat (limited to 'converter/pbm/pbmtomacp.c')
-rw-r--r--converter/pbm/pbmtomacp.c301
1 files changed, 301 insertions, 0 deletions
diff --git a/converter/pbm/pbmtomacp.c b/converter/pbm/pbmtomacp.c
new file mode 100644
index 00000000..82b55904
--- /dev/null
+++ b/converter/pbm/pbmtomacp.c
@@ -0,0 +1,301 @@
+/* pbmtomacp.c - read a portable bitmap and produce a MacPaint bitmap file
+**
+** Copyright (C) 1988 by Douwe vand der Schaaf.
+**
+** Permission to use, copy, modify, and distribute this software and its
+** documentation for any purpose and without fee is hereby granted, provided
+** that the above copyright notice appear in all copies and that both that
+** copyright notice and this permission notice appear in supporting
+** documentation.  This software is provided "as is" without express or
+** implied warranty.
+*/
+
+#include <string.h>
+
+#include "pbm.h"
+#include "macp.h"
+
+#define TRUE		1
+#define FALSE		0
+#define EQUAL		1
+#define UNEQUAL		0
+
+static void fillbits ARGS(( bit **bits, bit **bitsr, int top, int left, int bottom, int right ));
+static void writemacp ARGS(( bit **bits ));
+static int packit ARGS(( bit *pb, bit *bits ));
+static void filltemp ARGS(( bit *dest, bit *src ));
+static void sendbytes ARGS(( bit *pb, register int npb ));
+static void header ARGS(( void ));
+
+static FILE *fdout;
+
+int
+main(argc, argv)
+int argc;
+char *argv[];
+{ FILE *ifp;
+  register bit **bits, **bitsr;
+  int argn, rows, cols;
+  int left,bottom,right,top;
+  int lflg, rflg, tflg, bflg;
+  char name[100];
+  const char * const usage = "[-l left] [-r right] [-b bottom] [-t top] [pbmfile]";
+
+
+  pbm_init( &argc, argv );
+
+  argn = 1;
+  fdout = stdout;
+  lflg = rflg = tflg = bflg = 0;
+  left = right = top = bottom = 0;  /* To quiet compiler warning */
+
+  while ( argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0' )
+  { switch ( argv[argn][1] )
+    { case 'l':
+      lflg++;
+      argn++;
+      left = atoi( argv[argn] );
+      break;
+
+      case 'r':
+      rflg++;
+      argn++;
+      right = atoi( argv[argn] );
+      break;
+
+      case 't':
+      tflg++;
+      argn++;
+      top = atoi( argv[argn] );
+      break;
+
+      case 'b':
+      bflg++;
+      argn++;
+      bottom = atoi( argv[argn] );
+      break;
+
+      case '?':
+      default:
+      pm_usage( usage );
+    }
+    ++argn;
+  }
+
+  if ( argn == argc )
+  { ifp = stdin;
+    strcpy( name, "noname" );
+  }
+  else
+  { ifp = pm_openr( argv[argn] );
+    strcpy( name, argv[argn] );
+    ++argn;
+  }
+
+  if ( argn != argc )
+    pm_usage( usage );
+
+  bitsr = pbm_readpbm( ifp, &cols, &rows );
+
+  pm_close( ifp );
+
+  bits = pbm_allocarray( MAX_COLS, MAX_LINES );
+
+  if( !lflg )
+    left = 0;
+
+  if( rflg )
+  { if( right - left >= MAX_COLS )
+      right = left + MAX_COLS - 1;
+  }
+  else
+    right = ( left + MAX_COLS > cols ) ? ( cols - 1 ) : ( left + MAX_COLS - 1 );
+
+  if( !tflg )
+    top = 0;
+
+  if( bflg )
+  { if( bottom - top >= MAX_LINES )
+      bottom = top + MAX_LINES - 1;
+  }
+  else
+    bottom = ( top + MAX_LINES > rows ) ?
+		   ( rows - 1 ) : ( top + MAX_LINES - 1 );
+  
+    if( right <= left || left < 0 || right - left + 1 > MAX_COLS )
+      pm_error("error in right (= %d) and/or left (=%d)",right,left );
+    if( bottom <= top || top < 0 || bottom - top + 1 > MAX_LINES )
+      pm_error("error in bottom (= %d) and/or top (=%d)",bottom,top );
+
+  fillbits( bits, bitsr, top, left, bottom, right );
+
+  writemacp( bits );
+
+  exit( 0 );
+
+}
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+/* centreer het over te zenden plaatje in het MacPaint document
+ *
+ * Het plaatje wordt vanaf al of niet opgegeven (left, bottom)
+ * in een pbm bitmap van de juist macpaint afmetingen gezet,
+ * en eventueel afgekapt.
+ */
+static void
+fillbits( bits, bitsr, top, left, bottom, right )
+bit **bits, **bitsr;
+int top, left, bottom, right;
+{ register bit *bi, *bir;
+  register int i, j;
+  register int bottomr, leftr, topr, rightr;
+  int width, height;
+
+  width = right - left + 1;
+  leftr = (MAX_COLS - width) / 2;
+  rightr = leftr + width - 1;
+
+  height = bottom - top + 1;
+  topr = ( MAX_LINES - height ) / 2;
+  bottomr = topr + height - 1;
+
+  for( i = 0; i < topr; i++ )
+  { bi = bits[i];
+    for( j = 0; j < MAX_COLS; j++ )
+      *bi++ = 0;
+  }
+
+  for( i = topr; i <= bottomr; i++ )
+  { bi = bits[i];
+    { for( j = 0; j < leftr; j++ )
+	*bi++ = 0;
+      bir = bitsr[ i - topr + top ];
+      for( j = leftr; j <= rightr; j++ )
+	*bi++ = bir[j - leftr + left];
+      for( j = rightr + 1; j < MAX_COLS; j++ )
+	*bi++ = 0;
+  } }
+
+  for( i = bottomr + 1; i < MAX_LINES; i++ )
+  { bi = bits[i];
+    for( j = 0; j < MAX_COLS; j++ )
+      *bi++ = 0;
+  }
+} /* fillbits */
+      
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+static void
+writemacp( bits )
+bit **bits;
+{ register int i;
+  bit pb[MAX_COLS * 2];
+  int npb;
+
+  header();
+  for( i=0; i < MAX_LINES; i++ )
+  { npb = packit( pb, bits[i] );
+    sendbytes( pb, npb );
+  }
+} /* writemacp */
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+/* pack regel van MacPaint doc in Apple's format
+ * return value = # of bytes in pb 
+ */
+static int
+packit( pb, bits )
+     bit *pb, *bits;
+{ register int charcount, npb, newcount, flg;
+  bit temp[72];
+  bit *count, *srcb, *destb, save;
+
+  srcb = bits; destb = temp;
+  filltemp( destb, srcb );
+  srcb = temp;
+  destb = pb;
+  npb = 0;
+  charcount = BYTES_WIDE;
+  flg = EQUAL;
+  while( charcount ) { 
+      save = *srcb++;
+      charcount--;
+      newcount = 1;
+      while( (*srcb == save) && charcount ) { 
+          srcb++;
+          newcount++;
+          charcount--;
+      }
+      if( newcount > 2 ) { 
+          count = destb++;
+          *count = 257 - newcount;
+          *destb++ = save;
+          npb += 2;
+          flg = EQUAL;
+      } else { 
+          if( flg == EQUAL ) { 
+              count = destb++;
+              *count = newcount - 1;
+              npb++;
+          } else
+            *count += newcount;
+          while( newcount-- ) { 
+              *destb++ = save;
+              npb++;
+          }
+          flg = UNEQUAL;
+      } 
+  }
+  return npb;
+} /* packit */
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+static void
+filltemp( dest, src )
+bit *dest, *src;
+{ register unsigned char ch, zero, acht;
+  register int i, j;
+
+  zero = '\0';
+  acht = 8;
+  i = BYTES_WIDE;
+  while( i-- )
+  { ch = zero; 
+    j = acht;
+    while( j-- )
+    { ch <<= 1;
+      if( *src++ )
+	ch++;
+    }
+    *dest++ = ch;
+  }
+} /* filltemp */
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+static void
+sendbytes( pb, npb )
+bit *pb;
+register int npb;
+{ register bit *b;
+
+  b = pb;
+  while( npb-- )
+    (void) putc( *b++, fdout );
+} /* sendbytes */
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+static void
+header()
+{ register int i;
+  register char ch;
+
+  /* header contains nothing ... */
+  ch = '\0';
+  for(i = 0; i < HEADER_LENGTH; i++ )
+    (void) putc( ch, fdout );
+} /* header */