Utah Raster Toolkit  9999-git
URT Development version (post-3.1b)
dvirle2.c
Go to the documentation of this file.
1 #ifndef lint
2 static char rcsid[] = "$Id: dvirle2.c,v 3.0.1.1 1992/01/21 19:26:59 spencer Exp $";
3 #endif
4 
5 /*
6  * Dvirle2 -- Second half of DVI to RLE converter
7  *
8  * Reads pre-sorted pages as put out by dvirle1, and shovels bitmaps
9  * out to the RLE file as fast as possible. Warning: there is some
10  * inline assembly code used in inner loops, where the C compiler
11  * produced particuarly poor code.
12  *
13  * We use a technique known as a `band buffer', where we keep track
14  * of what has yet to be written to the RLE file in a buffer that
15  * represents a `band' across the current page, analagous to a magnifying
16  * bar across the page. Only the region in the band can be written,
17  * and the band moves only downward; this is why dvirle1 must sort
18  * each page, at least by y coordinate. This also implies that the
19  * `tallest' object we can write is the same height as the band. This
20  * is a problem for large characters. For these there is some (as yet
21  * unimplemented) code that will ask for a `part' of each character
22  * to be drawn into the band. The character would then be repeated
23  * with a request for the next part when the band has moved down to
24  * just below the bottom of the previous part. Rules are also broken
25  * up as appropriate (and that code *is* implemented).
26  *
27  * Another important point is that the band buffer is treated as a
28  * `cylinder' rather than a `strip': we write bits onto the cylinder,
29  * then roll it forward over the page, moving the bits off the cylinder
30  * and onto the paper, leaving that part of the cylinder clean, ready
31  * for more bits. The variable `CurRow' points at the current row
32  * in the buffer/on the cylinder, and `FirstRow' and `LastRow' bound
33  * the `dirty' part of the cylinder. Modular arithmetic suffices to
34  * change linear to cylindrical.
35  *
36  * Yet another point of note is that because the band always moves
37  * `down' on the page, we need only a positive offset from the current
38  * row to move to a new row. This means (among other things) that we
39  * can use negative offsets for special purposes.
40  */
41 
42 #include <errno.h>
43 #include <setjmp.h>
44 #include <stdio.h>
45 #include "types.h"
46 #include "conv.h"
47 #include "fio.h"
48 #include "font.h"
49 #include "dvirle.h"
50 #include "rle.h"
51 
52 /*#define SPEED_HACK*/
53 
54 void ReadFonts(), FormFeed(), ReadInput(), VWriteChar(), VWriteRule();
55 void DumpTopOfBand(), MoveDown(), WriteBuf(), WriteBlanks();
56 
57 char *ProgName;
58 extern char *optarg;
59 extern int optind;
60 
61 /* Global variables. */
62 struct font *Fonts[NFONTS]; /* the fonts */
63 
64 char TeXFontDesc[256]; /* getenv("TEXFONTDESC") from dvirle1 */
65 
66 int RasterOrientation; /* ROT_NORM or ROT_RIGHT, based on HFlag */
67 
68 int DFlag; /* -d => output discarded */
69 int HFlag; /* -h => horizontal (rotated bitmaps) */
70 int SFlag; /* -s => silent processing */
71 int TFlag; /* -t => output to tape */
72 int Debug; /* -D => debug flag */
73 
74 unsigned char VBuffer[ROWS][COLUMNS]; /* band buffer */
75 
76 int NewPage; /* New page indicator */
77 
78 int CurRow; /* current row in buffer */
79 int CurCol; /* current column in buffer */
80 int FirstRow; /* the first row used */
81 int LastRow; /* the last row used */
82 int NLines; /* counts lines; used for pagefeeds */
83 int PageHeight, PageWidth; /* Page size, from pass 1 */
84 
85 int filtw = 5, filth = 5; /* Filter dimensions */
86 int filtfact; /* multiplier for filter averaging */
87 int outwidth; /* width of output line */
88 
89 rle_hdr out_hdr;
90 
92  "Creator=DVIRLE",
93  "Note=Created from DVI file at 300 dots/inch",
94  0
95 };
96 
97 /*
98  * RowsBetween tells how many rows (in cylindrical arithmetic) there
99  * are between the first position and the second. If the second value
100  * is less than the first value, add ROWS to do the appropriate modular
101  * arithmetic. We cannot use `%' as C `%' is machine-dependent with
102  * respect to negative values.
103  */
104 #define RowsBetween(f, n) ((n) >= (f) ? (n) - (f) : (n) - (f) + ROWS)
105 
106 /*
107  * This is it... on your marks ... get set ... main!
108  */
109 void
111  int argc;
112  register char **argv;
113 {
114  register int c;
115  register char *s;
116  int dpi, usermag, num, denom, dvimag;
117 
118  ProgName = *argv;
119 
120  while ((c = getopt(argc, argv, "dstDx:y:")) != EOF) {
121  switch (c) {
122 
123  case 'd': /* output to /dev/null */
124  DFlag++;
125  break;
126 
127  case 's': /* silent processing except for errors */
128  SFlag++;
129  break;
130 
131  case 't': /* output to tape (not implemented) */
132  TFlag++;
133  error(0, 0, "tape option not yet implemented");
134  break;
135 
136  case 'D':
137  Debug++;
138  break;
139 
140  case 'x':
141  if ( optarg )
142  filtw = atoi( optarg );
143  break;
144  case 'y':
145  if ( optarg )
146  filth = atoi( optarg );
147  break;
148  case '?':
149  fprintf(stderr, "Usage: %s [-d] [-s] [-t] [file]\n",
150  ProgName);
151  exit(1);
152  }
153  }
154  if (optind < argc)
155  if (freopen(argv[optind], "r", stdin) == NULL)
156  error(1, 0, "can't open %s", argv[optind]);
157 
158  HFlag = getchar();
159  if ((HFlag >> 1) != VERSION)
160  error(1, 0, "input file is not version %d", VERSION);
161  HFlag &= 1;
162  RasterOrientation = HFlag ? ROT_RIGHT : ROT_NORM;
163 
164  s = TeXFontDesc;
165  c = GetLong(stdin);
166  while (--c >= 0)
167  *s++ = getchar();
168  if (feof(stdin))
169  (void) GetByte(stdin); /* let GetByte do error */
170  *s = 0;
171 
172  dpi = GetLong(stdin);
173  usermag = GetLong(stdin);
174  num = GetLong(stdin);
175  denom = GetLong(stdin);
176  dvimag = GetLong(stdin);
177  SetConversion(dpi, usermag, num, denom, dvimag);
178 
179  fontinit(*TeXFontDesc ? TeXFontDesc : (char *) NULL);
180  ReadFonts();
181 
182  PageHeight = GetLong(stdin);
183  PageWidth = GetLong(stdin);
184 
185  out_hdr = *rle_hdr_init( (rle_hdr *)NULL );
186  rle_names( &out_hdr, cmd_name( argv ), NULL, 0 );
187 
188  if (DFlag) {
189  (void) fprintf(stderr, "Output will be discarded\n");
190  (void) fflush(stderr);
191  out_hdr.rle_file = fopen("/dev/null", "w");
192  }
193 
194  /* Set up output file papameters */
195  out_hdr.xmin = 0;
196  out_hdr.xmax = outwidth = (PageWidth - 1) / filtw;
197  out_hdr.ymin = 0;
198  out_hdr.ymax = (PageHeight - 1) / filth;
199  out_hdr.ncolors = 1;
200  out_hdr.alpha = 1;
204 
205  filtfact = 255.0 / (filtw * filth);
206 
207  ReadInput();
208 
209  FormFeed(); /* Write last EOF */
210 
211  if (!SFlag)
212  (void) putc('\n', stderr);
213 
214  exit(0);
215  /* NOTREACHED */
216 }
217 
218 /*
219  * Read the font definitions.
220  *
221  * Anti-streak hack: get the rasters ahead of time, #ifdef SPEED_HACK.
222  */
223 void
224 ReadFonts()
225 {
226  register struct font *f, **fp;
227  register int c;
228  register char *s;
229 #ifdef SPEED_HACK
230  register struct glyph *g;
231 #endif
232  i32 mag, dsize;
233  char *fname;
234  char nm[512];
235 
236  if (!SFlag)
237  (void) fprintf(stderr, "[fonts:\n");
238  fp = Fonts;
239  while (GetByte(stdin) == 1) {
240  (void) GetLong(stdin); /* checksum */
241  mag = GetLong(stdin); /* magfactor */
242  dsize = GetLong(stdin); /* design size */
243  c = GetLong(stdin);
244  s = nm;
245  while (--c >= 0)
246  *s++ = getchar();
247  if (feof(stdin))
248  (void) GetByte(stdin); /* let GetByte do error */
249  *s = 0;
250  f = GetFont(nm, mag, dsize, "RLE", &fname);
251  if (f == NULL) {
252  GripeCannotGetFont(nm, mag, dsize, "RLE", fname);
253  exit(1);
254  /* NOTREACHED */
255  }
256  if (Debug) {
257  (void) fprintf(stderr, "[%s -> %s]\n",
258  Font_TeXName(f), fname);
259  (void) fflush(stderr);
260  }
261  if (!SFlag) {
262  register char *t = fname;
263 
264  s = fname;
265  while (*s)
266  if (*s++ == '/' && *s)
267  t = s;
268  (void) fprintf(stderr, " %s\n", t);
269  }
270 #ifdef SPEED_HACK
271  for (c = 0; c < 128; c++) {
272  g = GLYPH(f, c);
273  if (GVALID(g))
274  (void) RASTER(g, f, RasterOrientation);
275  }
276 #endif
277  *fp++ = f;
278  }
279  if (!SFlag)
280  (void) fprintf(stderr, "]\n");
281 }
282 
283 /*
284  * Read the input stream, decode it, and put character rasters or rules at
285  * the positions given.
286  */
287 void
288 ReadInput()
289 {
290  register int yx, fcp, height;
291 
292  /*
293  * Loop forever. I had a `for (;;)' but everything crept off the
294  * right side of the screen.
295  */
296 next:
297  fGetLong(stdin, yx); /* position */
298  fGetLong(stdin, fcp); /* character, most likely */
299  if ( Debug > 2 )
300  fprintf( stderr, "yx:%lx, fcp:%lx\n", yx, fcp );
301  if (feof(stdin))
302  return; /* done */
303 
304  /*
305  * A `position' of -1 indicates either a rule or an end of page.
306  * Anything else is a character.
307  */
308  if (yx != -1) { /* place character */
309  register struct glyph *g;
310  register struct font *f;
311  register int fnum;
312 
313  /*
314  * Any delta-y required is stored in the upper 16 bits of yx.
315  */
316  if ((height = yx >> 16) != 0)
317  MoveDown(height);
318  /*
319  * Extract the x, font, char, and part info into CurCol,
320  * fnum, yx, and fcp.
321  */
322  CurCol = yx & 0xffff;
323  fnum = fcp >> FONTSHIFT;
324  yx = (fcp >> CHARSHIFT) & CHARMASK;
325  fcp = fcp & PARTMASK;
326  f = Fonts[fnum]; /* trusting */
327  g = GLYPH(f, yx);
328  if ( Debug > 1 )
329  fprintf( stderr,
330  "Col:%d, Height:%d, fnum:%d, yx:%d, fcp:%d\n",
331  CurCol, height, fnum, yx, fcp );
332 
333  /*
334  * In case this character does not fit, write
335  * out the used part of the band. It had better
336  * fit afterward....
337  */
338  height = g->g_height;
339  if (height >= ROWS - RowsBetween(FirstRow, CurRow))
340  DumpTopOfBand();
341  if (fcp) /* cannot handle these yet */
342  error(0, 0, "\
343 part code not implemented; skipping char %d in %s",
344  yx, f->f_path);
345  else if (HASRASTER(g)) {
346 #ifdef SPEED_HACK
347  /* XXX, but saves time */
348  VWriteChar(g->g_raster, height, g->g_width);
349 #else
350  VWriteChar(RASTER(g, f, RasterOrientation),
351  height, g->g_width);
352 #endif
353  }
354  goto next; /* done with character */
355  }
356 
357  /*
358  * If the `character' is negative, we need to move down first,
359  * possibly because this is an end-of-page. If this is not the
360  * end of the page, it must be a rule.
361  */
362  if (fcp < 0) { /* move down */
363  yx = -fcp;
364  fGetLong(stdin, fcp); /* junk */
365  fGetLong(stdin, fcp);
366  if (fcp == 0) { /* end page */
367  if ( Debug > 1 )
368  fprintf( stderr, "End of Page\n" );
369  /* dump entire band */
370  WriteBuf(&VBuffer[0][0], FirstRow, LastRow, 1);
371  CurRow = LastRow = FirstRow;
372  if (!HFlag) {
373  WriteBlanks(yx - NLines);
374  FormFeed();
375  } else
376  FormFeed();
377  if (!SFlag)
378  (void) fprintf(stderr, ".");
379  NLines = 0;
380  goto next; /* all done */
381  }
382 
383  MoveDown(yx); /* must be a rule; move down by yx rows */
384  }
385 
386  /*
387  * At this point we have a rule to put at the current
388  * position, CurRow.
389  */
390  height = (fcp & 0xff00) >> 8;
391  /* make sure it fits */
392  if (height >= ROWS - RowsBetween(FirstRow, CurRow))
393  DumpTopOfBand();
394  VWriteRule(fcp);
395  goto next; /* done with rule */
396 }
397 
398 /*
399  * Write the given raster for the given character.
400  *
401  * Basically, the task is to move bits from the raster to the output
402  * buffer. However, because the character being plotted can be on an
403  * arbitrary bit boundary, things are not as simple as we might like.
404  * The solution used here is to shift each raster value right, OR it
405  * into the buffer, then (at the next location) OR in the bits that
406  * `fell off the right edge'.
407  */
408 void
409 VWriteChar(rastp, height, width)
410  unsigned char *rastp; /* raster pointer */
411  int height, width; /* height & width of char */
412 {
413  register unsigned char *bp; /* Output buffer pointer [r11] */
414  register unsigned char *rp; /* raster pointer [r10] */
415  register int rshift; /* right shift index [r9] */
416  register int lshift; /* left shift index [r8] */
417  register int j; /* width loop downcounter */
418  register int o; /* offset to next row in buffer */
419  int row; /* current row in buffer */
420  int col; /* column in buffer of left edge */
421  int i; /* height loop downcounter */
422  int w; /* raster width (bytes) */
423 
424  if ((rp = rastp) == NULL)
425  return; /* an all-white character */
426 
427  row = CurRow + height - 1;
428  if ( row >= ROWS )
429  row -= ROWS; /* assume height <= ROWS? */
430  col = CurCol >> 3;
431  i = height;
432  w = (width + 7) >> 3;
433  o = COLUMNS + w;
434 
435 #if defined(lint) || !defined(vax)
436  rshift = CurCol & 7;
437  lshift = 8 - rshift;
438 #else /* lint || !vax */
439  rshift = -(CurCol & 7); /* Vax does '>>' as negative '<<' */
440  lshift = 8 + rshift;
441 #endif /* lint || !vax */
442  bp = &VBuffer[row][col];
443 
444 #define avoiding_shifts_is_faster /* but is it??? */
446  /*
447  * One out of eight or so times, the shift values will be
448  * zero. This makes the code run faster.
449  */
450  if (rshift == 0) {
451  while (--i >= 0) {
452  j = w;
453  while (--j >= 0)
454  *bp++ |= *rp++;
455  if (--row < 0) {
456  row = ROWS - 1;
457  bp = &VBuffer[ROWS - 1][col];
458  } else
459  bp -= o;
460  }
461  } else
462 #endif
463  {
464  while (--i >= 0) {
465  j = w;
466  while (--j >= 0) {
467 #if defined(lint) || !defined(vax)
468  *bp++ |= (*rp & 255) >> rshift;
469  *bp |= (*rp++ & 255) << lshift;
470 #else /* lint || !vax */
471  /*
472  * THE FOLLOWING ASSEMBLY CODE IS INSERTED
473  * BECAUSE THE COMPILER CAN'T OPTIMIZE THE
474  * C CODE WORTH A DARN
475  */
476  asm(" movzbl (r10)+,r1 # *rp++ & 255");
477  asm(" ashl r9,r1,r0 # >> rshift");
478  asm(" bisb2 r0,(r11)+ # *bp++ |=");
479  asm(" ashl r8,r1,r0 # << lshift");
480  asm(" bisb2 r0,(r11) # *bp |=");
481 #endif /* lint || !vax */
482  }
483  if (--row < 0) {
484  row = ROWS - 1;
485  bp = &VBuffer[ROWS - 1][col];
486  } else
487  bp -= o;
488  }
489  }
490 
491  j = height + CurRow - 1;/* have now set bits this far */
492  if (j >= ROWS)
493  j -= ROWS; /* keep it modular */
494 
495  /*
496  * There are two cases. Either the buffer is not currently wrapped,
497  * in which case the regions past LastRow or before FirstRow extend
498  * it; or it is wrapped, in which case the region between LastRow
499  * and FirstRow extends it:
500  *
501  * case 1 case 2
502  * -------- --------
503  * | | last ->| XXXX |
504  * first ->| XXXX | | |
505  * | XXXX | | |
506  * last ->| XXXX | first ->| XXXX |
507  * | | | XXXX |
508  * -------- --------
509  *
510  * The `X's mark the region that is in use; the blank spaces
511  * mark the region that causes the `last' value to change.
512  */
513  if (FirstRow <= LastRow) {
514  /* first case: not wrapped */
515  if (j < FirstRow || j > LastRow)
516  LastRow = j;
517  } else {
518  /* second case: wrapped */
519  if (j > LastRow && j < FirstRow)
520  LastRow = j;
521  }
522 }
523 
524 /*
525  * Write a rule at the current row according to the (packed) information in
526  * 'info'. This includes the x position and the height and width of the
527  * rule.
528  */
529 void
530 VWriteRule(info)
531  int info;
532 {
533  register unsigned char *bp; /* buffer pointer */
534  register int j;
535  register int lbits; /* bits along left */
536  register int rbits; /* bits along right */
537  register int o; /* offset to next row */
538  register int i;
539  register int full; /* number of 8 bit words to set */
540  register int height; /* rule height */
541  register int width; /* rule width */
542  register int row;
543  register int col;
544 
545  i = info;
546  CurCol = (i & 0x7fff0000) >> 16;
547  height = ((i & 0xff00) >> 8);
548  width = (i & 0xff);
549  if ( Debug > 1 )
550  fprintf( stderr, "Rule: Row: %d, Col:%d, height:%d, width:%d\n",
551  CurRow, CurCol, height, width );
552  col = CurCol >> 3;
553  row = CurRow;
554  j = CurCol & 7; /* bit # of start position */
555  lbits = 0xff >> j; /* bits to set along left edge */
556  /* there are 8-j bits set in lbits */
557  o = 8 - j - width;
558  if (o > 0) { /* then lbits has o too many bits set */
559  lbits >>= o;
560  lbits <<= o; /* puts zeros into o righthand bits */
561  rbits = 0;
562  full = 0;
563  } else {
564  i = (CurCol + width) & 7; /* bit # of ending position */
565  rbits = 0xff00 >> i; /* bits to set along right edge */
566  /* there are i bits set in rbits (well, in the low byte) */
567  full = (width - i - (8 - j)) >> 3;
568  }
569  bp = &VBuffer[row][col];
570  i = height;
571 
572  /* Often "full" is zero, which makes things faster */
573  if (full) { /* oh well */
574  o = COLUMNS - full - 1;
575  while (--i >= 0) {
576  *bp++ |= lbits;
577  for (j = full; --j >= 0;)
578  *bp++ |= 0xff;
579  *bp |= rbits;
580  if (++row >= ROWS) {
581  row = 0;
582  bp = &VBuffer[0][col];
583  } else
584  bp += o;
585  }
586  } else {
587  o = COLUMNS - 1;
588  while (--i >= 0) {
589  *bp++ |= lbits;
590  *bp |= rbits;
591  if (++row >= ROWS) {
592  row = 0;
593  bp = &VBuffer[0][col];
594  } else
595  bp += o;
596  }
597  }
598  i = CurRow + height - 1;
599  if (i >= ROWS)
600  i -= ROWS;
601  /*
602  * This is another way of expressing both cases 1 and 2 in
603  * VWriteChar(). I think the other way is likely to be
604  * faster, and characters occur far more frequently; but this
605  * is the more readable by far.
606  */
608  LastRow = i;
609 }
610 
611 /*
612  * Dump out the top portion of the band (rows [Firstrow, CurRow)).
613  */
614 void
615 DumpTopOfBand()
616 {
617 
618  /*
619  * To exclude CurRow, subtract one, but modularly, modularly!
620  */
621  WriteBuf(&VBuffer[0][0], FirstRow, CurRow ? CurRow - 1 : ROWS - 1, 1);
622  FirstRow = CurRow;
623 }
624 
625 /*
626  * Move the current row in the band buffer down by delta rows, by,
627  * if necessary, writing out the currently-used portion of the buffer.
628  */
629 void
630 MoveDown(delta)
631  register int delta;
632 {
633 
634  if (delta >= ROWS - RowsBetween(FirstRow, CurRow)) {
635  /*
636  * Need to roll the cylinder forward. Write out the used
637  * part, and then write as many blank lines as necessary.
638  */
639  WriteBuf(&VBuffer[0][0], FirstRow, LastRow, 1);
640  WriteBlanks(delta - RowsBetween(CurRow, LastRow) - 1);
641  CurRow = LastRow = FirstRow; /* band is now empty */
642  } else {
643  /*
644  * Because RowsBetween returns nonnegative integers, we
645  * know delta <= ROWS, so can do mod more quickly thus:
646  */
647  CurRow += delta; /* result < 2*ROWS */
648  if (CurRow >= ROWS)
649  CurRow -= ROWS; /* now result < ROWS */
650  }
651 }
652 
653 /*
654  * Count the bits in a byte
655  */
656 static unsigned char nbits[256] = {
657  0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
658  1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
659  1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
660  2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
661  1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
662  2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
663  2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
664  3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
665  1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
666  2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
667  2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
668  3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
669  2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
670  3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
671  3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
672  4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
673 };
674 
675 /*
676  * Write the lines between the first and last inclusive from the given
677  * buffer. If 'cl', clear after writing.
678  * Filters pixels using a box filter (filth x filtw) in size.
679  *
680  * If buf is NULL, then just skips blank space.
681  */
682 void
683 WriteBuf(buf, first, last, cl)
684  unsigned char *buf;
685  register int first, last;
686  int cl;
687 {
688  static unsigned char bytebuf[COLUMNS*8];
689  static int filtrow = 0, sawbit = 0;
690  unsigned char mask;
691  unsigned char * scans[2];
692  int row;
693  register int bit, col;
694  register unsigned char * cp, * bufp;
695 
696  if ( Debug > 1 )
697  fprintf( stderr, "Writebuf( %lx, %d, %d, %d )\n",
698  buf, first, last, cl );
699 
700  /* Setup RLE file if beginning of page */
701  if ( NewPage )
702  {
704  NewPage = 0;
705  }
706 
707  scans[0] = scans[1] = bytebuf;
708 
709  if ( buf == NULL )
710  {
711  if ( filtrow > 0 && filtrow + last - first + 1 >= filth )
712  {
713  for ( col = 0; col < outwidth; col++ )
714  {
715  /* Why two lines? HP compiler bug! */
716  bit = bytebuf[col] * filtfact;
717  bytebuf[col] = bit;
718  }
719  rle_putrow( &scans[1], outwidth, &out_hdr );
720  for ( col = 0; col < outwidth; col++ )
721  bytebuf[col] = 0;
722  }
723  NLines += last - first + 1;
724  if ( last - first - filtrow + 1 >= filth )
726  (last - first - filtrow + 1) / filth );
727  filtrow = (filtrow + last - first + 1) % filth;
728  return;
729  }
730 
731  if (first > last) { /* recursively do wrapped part first */
732  WriteBuf(buf, first, ROWS - 1, cl);
733  first = 0;
734  }
735  buf = &buf[first * COLUMNS];
736 
737  mask = (0xff << (8 - filtw)) & 0xff;
738  for ( row = first, bufp = buf; row <= last; row++, bufp += COLUMNS )
739  {
740  for ( cp = bufp, col = 0, bit = 0; col < outwidth;
741  col++, bit += filtw, bit >= 8 ? cp++ : cp, bit %= 8 )
742  if ( (bytebuf[col] +=
743  nbits[(*cp & (mask >> bit))] +
744  nbits[((*(cp+1) & (mask << (8 - bit)))) & 0xff]) != 0 )
745  sawbit++;
746 
747  filtrow = (filtrow + 1) % filth;
748 
749  if ( filtrow == 0 )
750  {
751  if ( sawbit )
752  {
753  for ( col = 0; col < outwidth; col++ )
754  {
755  bit = bytebuf[col] * filtfact;
756  bytebuf[col] = bit;
757  }
758  rle_putrow( &scans[1], outwidth, &out_hdr );
759  for ( col = 0; col < outwidth; col++ )
760  bytebuf[col] = 0;
761  }
762  else
764  sawbit = 0;
765  }
766  }
767 
768  if (cl)
769  bzero(buf, (unsigned) (COLUMNS * (last - first + 1)));
770  NLines += last - first + 1;
771 }
772 
773 /*
774  * Write 'n' blank lines.
775  */
776 void
777 WriteBlanks(n)
778  int n;
779 {
780  WriteBuf((unsigned char *)0, 0, n - 1, 0);
781 }
782 
783 /*
784  * Perform a page feed.
785  */
786 void
787 FormFeed()
788 {
789  if ( !NewPage )
791  NewPage = 1; /* next output will setup RLE file */
792 }
793 
794 #ifdef hpux
795 void
796 bcopy( from, to, len )
797 {
798  return memcpy( to, from, len );
799 }
800 
801 bzero( to, len )
802 {
803  memset( to, 0, len );
804 }
805 
806 #endif
#define PARTMASK
Definition: dvirle.h:33
int TFlag
Definition: dvirle2.c:71
#define RLE_SET_BIT(glob, bit)
Definition: rle.h:122
int xmin
Definition: rle.h:100
const char ** comments
Definition: rle.h:113
void rle_names(rle_hdr *the_hdr, const char *pgmname, const char *fname, int img_num)
Definition: rle_hdr.c:48
static unsigned char nbits[256]
Definition: dvirle2.c:656
int LastRow
Definition: dvirle2.c:81
int filtfact
Definition: dvirle2.c:86
char * cmd_name(char **argv)
Definition: cmd_name.c:31
int FirstRow
Definition: dvirle2.c:80
int filth
Definition: dvirle2.c:85
unsigned char VBuffer[600][319]
Definition: dvirle2.c:74
void main(int argc, char **argv)
Definition: aliastorle.c:121
#define COLUMNS
Definition: dvirle.h:37
int HFlag
Definition: dvirle2.c:69
int RasterOrientation
Definition: dvirle2.c:66
#define CHARSHIFT
Definition: dvirle.h:31
char TeXFontDesc[256]
Definition: dvirle2.c:64
int PageWidth
Definition: dvirle2.c:83
int ymin
Definition: rle.h:100
int optind
Definition: getopt.c:30
struct font * Fonts[100]
Definition: dvirle2.c:62
char * ProgName
Definition: dvirle2.c:57
void rle_puteof(rle_hdr *the_hdr)
Definition: rle_putrow.c:474
#define CHARMASK
Definition: dvirle.h:32
void rle_putrow(rows, int rowlen, rle_hdr *the_hdr)
Definition: rle_putrow.c:96
int xmax
Definition: rle.h:100
rle_hdr out_hdr
Definition: unslice.c:34
int NewPage
Definition: dvirle2.c:76
int CurCol
Definition: dvirle2.c:79
int filtw
Definition: dvirle2.c:85
#define CONST_DECL
Definition: rle_config.h:42
#define FONTSHIFT
Definition: dvirle.h:30
int SFlag
Definition: dvirle2.c:70
#define VERSION
Definition: dvirle.h:26
const char * pic_comments[]
Definition: dvirle2.c:91
void rle_skiprow(rle_hdr *the_hdr, int nrow)
Definition: rle_putrow.c:393
int PageHeight
Definition: dvirle2.c:83
int NLines
Definition: dvirle2.c:82
int outwidth
Definition: dvirle2.c:87
int ymax
Definition: rle.h:100
#define NFONTS
Definition: dvirle.h:28
void rle_put_setup(rle_hdr *the_hdr)
Definition: rle_putrow.c:453
static char rcsid[]
Definition: dvirle2.c:2
#define RowsBetween(f, n)
Definition: dvirle2.c:104
int alpha
Definition: rle.h:100
#define RLE_ALPHA
Definition: rle.h:65
bool Debug
Definition: rleClock.c:116
#define avoiding_shifts_is_faster
char * optarg
Definition: getopt.c:29
int DFlag
Definition: dvirle2.c:68
#define ROWS
Definition: dvirle.h:36
rle_hdr * rle_hdr_init(rle_hdr *the_hdr)
Definition: rle_hdr.c:267
FILE * rle_file
Definition: rle.h:114
int ncolors
Definition: rle.h:100
int CurRow
Definition: dvirle2.c:78