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