1 From durham.ac.uk!A.J.Scholl Wed Jan  4 14:05:37 1995
2 Return-Path: <A.J.Scholl@durham.ac.uk>
3 Received: by greenie.muc.de (/\==/\ Smail3.1.24.1 #24.2)
4 	id <m0rPVPA-00015dC@greenie.muc.de>; Wed, 4 Jan 95 14:05 MET
5 Received: from ben.britain.eu.net ([192.91.199.254]) by colin.muc.de with SMTP id <25577-1>; Wed, 4 Jan 1995 14:05:27 +0100
6 Received: from durham.ac.uk by ben.britain.eu.net via JANET with NIFTP (PP)
7           id <sg.08575-0@ben.britain.eu.net>; Wed, 4 Jan 1995 13:04:32 +0000
8 Received: from gauss.dur.ac.uk by durham.ac.uk; Wed, 4 Jan 95 13:03:52 GMT
9 From: Tony Scholl <A.J.Scholl@durham.ac.uk>
10 Date: Wed, 4 Jan 1995 14:03:50 +0100
11 Message-Id: <AA03302.9501041303.gauss@uk.ac.durham>
12 Received: from germain.durham.ac.uk (germain.dur) by uk.ac.durham.gauss;
13           Wed, 4 Jan 95 13:03:50 GMT
14 Received: by germain.durham.ac.uk (4.1/SMI-4.1) id AA14688;
15           Wed, 4 Jan 95 13:03:35 GMT
16 To: gert@greenie.muc.de
17 Subject: pbmsplit
18 Status: RO
19 
20 Hi,
21 
22 A promised, here's a late Christmas present (and a pretty crummy one, too ---
23 _my_ Christmas present was a ZyXEL...) but I've found it useful at times.
24 
25 Tony
26 
27 ---------------------------------cut here------------------------------------
28 /* pbmsplit.c: split a pbm file into pieces of specified size, with
29    overlapping/breaking on blank rows.
30 
31    Usage: pbmsplit [-w rows|-o rows] [-n rows] {-|infile} [outfile]
32 
33    Optional argument -n is number of rows for each output file (default 2400).
34 
35    Optional argument -w is number of rows by which it is permissible to shorten
36    an output file to search for a whitespace-only row to break (default 0).
37 
38    Optional argument -o is number of rows to overlap (default 0). You cannot
39    specify both -o and -w.
40 
41    Argument - means read from stdin (in which case outfile MUST be given)
42    Output is written to outfile.001, etc; outfile defaults to infile.
43 
44    This was put together by Tony Scholl (a.j.scholl@durham.ac.uk). I've
45    tested it a little, and it seems to work. But the code is far from
46    brilliant, so if you can write a better/working one please do.....
47 */
48 
49 #define MAXROWS 2400
50 #include <stdio.h>
51 #include <string.h>
52 #include <sys/types.h>
53 #include <sys/stat.h>
54 #include <fcntl.h>
55 
56 int row_len;
57 
usage()58 void usage ()
59 {
60   fprintf (stderr, "Usage: pbmsplit [-w rows|-o rows] [-n rows] {-|infile} [outfile]\n");
61   exit (-1);
62 }
63 
fatal(char * s)64 void fatal (char *s)
65 {
66   fprintf (stderr, s);
67   fprintf (stderr, "\n");
68   exit (-1);
69 }
70 
copy_rows(FILE * inf,FILE * outf,int r)71 void copy_rows (FILE *inf, FILE *outf, int r)
72 {
73   int c, n;
74   n = r * row_len;
75   while ((n-- > 0) && ((c = getc(inf)) != EOF))
76     putc(c, outf);
77   if (n > 0)
78     {
79       fclose (inf);
80       fclose (outf);
81       fatal ("Unexpected EOF");
82     }
83 }
84 
copy_saved_rows(FILE * outf,char * buf,int r)85 void copy_saved_rows (FILE *outf, char *buf, int r)
86 {
87   int n;
88   n = r * row_len;
89   while (n-- > 0)
90     putc (*(buf++), outf);
91 }
92 
copy_and_save_rows(FILE * inf,FILE * outf,char * buf,int r)93 void copy_and_save_rows (FILE *inf, FILE *outf, char *buf, int r)
94 {
95   int c, n;
96   n = r * row_len;
97   while ((n-- > 0) && ((c = getc (inf)) != EOF))
98     {
99       putc (c, outf);
100       *(buf++) = c;
101     }
102   if (n > 0)
103     {
104       fclose (inf);
105       fclose (outf);
106       fatal ("Unexpected EOF");
107     }
108 }
109 
110 
111 /* function to copy characters and return the OR of them */
copy_row2(FILE * inf,FILE * outf)112 int copy_row2 (FILE *inf, FILE *outf)
113 {
114   int c, n;
115   int d = 0;
116   n = row_len;
117   while ((n-- > 0) && ((c = getc (inf)) != EOF))
118     {
119       putc (c, outf);
120       d |= c;
121     }
122   if (n > 0)
123     {
124       fclose (inf);
125       fclose (outf);
126       fatal ("Unexpected EOF");
127     }
128   return (d);
129 }
130 
put_white(FILE * outf,int r)131 int put_white (FILE *outf, int r)
132 {
133   int n;
134   n = r * row_len;
135   while (n-- > 0)
136     putc ('\0', outf);
137 }
138 
main(int argc,char * argv[])139 main (int argc, char *argv[])
140 {
141   int count = 0;
142   int over_rows = 0;
143   int max_rows = MAXROWS;
144   int min_rows = 0;
145   int frows, fcols;
146   int rows_remaining;
147   char header[64];
148   FILE *in_f;
149   FILE *out_f;
150   char *in_fname;
151   char *out_fbasename;
152   char out_fname[256];
153   char *over_buf;
154 
155 /* parse arguments */
156   if (argc == 1)
157     usage ();
158   while ((**++argv == '-') && (*++*argv != '\0') && (argc-- > 3))
159     {
160       switch (**(argv++))
161 	{
162 	case 'o':
163 	  over_rows = atoi (*argv); break;
164 	case 'w':
165 	  min_rows = - atoi (*argv); break;
166 	case 'n':
167 	  max_rows = atoi (*argv); break;
168 	default:
169 	  fprintf (stderr, "Invalid option \"-%s\"\n", *(--argv));
170 	  usage ();
171 	}
172       argc--;
173     }
174   min_rows += max_rows;
175   in_fname = *argv;
176   switch (argc)
177     {
178     case 3: argv++;
179     case 2: out_fbasename = *argv; break;
180     default: usage ();
181     }
182   if ( out_fbasename[0] == '\0' )
183     usage ();
184 
185   if ((over_rows > 0) && (min_rows != max_rows))
186       fprintf (stderr, "Warning: you cannot use both -o and -w! I'm ignoring -w.\n");
187   if (over_rows > max_rows/2)
188     fatal ("You have specified an excessive overlap!");
189 
190   if (*in_fname != '\0')
191     in_f = fopen (in_fname, "r");
192   else
193     in_f = stdin;
194   if (in_f == NULL)
195     {
196       fprintf (stderr, "Cannot open %s for reading\n", in_fname);
197       exit (-1);
198     }
199   fgets (header, 62, in_f);
200     if (strcmp (header, "P4\n") != 0)
201       fatal ("Wrong magic number");
202   fgets (header, 63, in_f);
203   fcols = atoi (strtok (header, " "));
204   frows = rows_remaining = atoi (strtok (NULL, " "));
205 
206   row_len = (fcols + 7) / 8;
207 
208   if (over_rows == 0) /* no overlapping */
209     {
210       while (rows_remaining > 0)
211 	{
212 	  sprintf (out_fname, "%s.%03d", out_fbasename, ++count);
213 	  if ((out_f = fopen (out_fname, "w")) == (FILE *)NULL)
214 	    {
215 	      close (in_f);
216 	      fatal ("Cannot open output file");
217 	    }
218 	  if (rows_remaining < max_rows)
219 	    /* put the lot */
220 	    {
221 	      fprintf (out_f, "P4\n%d %d\n", fcols, rows_remaining);
222 	      copy_rows (in_f, out_f, rows_remaining);
223 	      rows_remaining = 0;
224 	    }
225 	  else
226 	    /* first put min_rows */
227 	    {
228 	      int j = min_rows;
229 	      fprintf (out_f, "P4\n%d %d\n", fcols, max_rows);
230 	      copy_rows (in_f, out_f, min_rows);
231 	      /* now look for white rows */
232 	      while ((j < max_rows) && (j++) && copy_row2 (in_f, out_f))
233 		;
234 	      rows_remaining -= j;
235 	      put_white (out_f, max_rows-j);
236 	    }
237 	  /* now close outfile */
238 	  fclose (out_f);
239 	}
240     }
241   else /* do overlapping */
242     {
243       if ((over_buf = (char *)malloc (over_rows * row_len + 1)) == NULL)
244 	  fatal ("Cannot allocate memory");
245       while (rows_remaining > 0)
246 	{
247 	  sprintf (out_fname, "%s.%03d", out_fbasename, ++count);
248 	  if ((out_f = fopen (out_fname, "w")) == (FILE *)NULL)
249 	    {
250 	      close (in_f);
251 	      fatal ("Cannot open output file");
252 	    }
253 	  if (count == 1)
254 	    {
255 	      if (rows_remaining <= max_rows)
256 		/* put the lot */
257 		{
258 		  fprintf (out_f, "P4\n%d %d\n", fcols, rows_remaining);
259 		  copy_rows (in_f, out_f, rows_remaining);
260 		  rows_remaining = 0;
261 		}
262 	      else
263 		/* put a page, saving overlap */
264 		{
265 		  fprintf (out_f, "P4\n%d %d\n", fcols, max_rows);
266 		  copy_rows (in_f, out_f, max_rows - over_rows);
267 		  copy_and_save_rows (in_f, out_f, over_buf, over_rows);
268 		  rows_remaining -= max_rows;
269 		}
270 	    }
271 	  else /* count > 1 */
272 	    {
273 	      if (rows_remaining <= max_rows - over_rows)
274 		/* put the lot */
275 		{
276 		  fprintf (out_f, "P4\n%d %d\n", fcols, rows_remaining + over_rows);
277 		  copy_saved_rows (out_f, over_buf, over_rows);
278 		  copy_rows (in_f, out_f, rows_remaining);
279 		  rows_remaining = 0;
280 		}
281 	      else
282 		{
283 		  fprintf (out_f, "P4\n%d %d\n", fcols, max_rows);
284 		  copy_saved_rows (out_f, over_buf, over_rows);
285 		  copy_rows (in_f, out_f, max_rows - 2 * over_rows);
286 		  copy_and_save_rows (in_f, out_f, over_buf, over_rows);
287 		  rows_remaining -= max_rows - over_rows;
288 		}
289 	    }
290 	  /* now close outfile */
291 	  fclose (out_f);
292 	}
293     }
294   fclose (in_f);
295 }
296 
297 /******************************* end ****************************************/
298 
299