w32tex
About: TeX Live provides a comprehensive TeX system including all the major TeX-related programs, macro packages, and fonts that are free software. Windows sources.
  Fossies Dox: w32tex-src.tar.xz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

pbmtolj.c
Go to the documentation of this file.
1 /* pbmtolj.c - read a portable bitmap and produce a LaserJet bitmap file
2 **
3 ** based on pbmtops.c
4 **
5 ** Michael Haberler HP Vienna mah@hpuviea.uucp
6 ** mcvax!tuvie!mah
7 ** misfeatures:
8 ** no positioning
9 **
10 ** Bug fix Dec 12, 1988 :
11 ** lines in putbit() reshuffled
12 ** now runs OK on HP-UX 6.0 with X10R4 and HP Laserjet II
13 ** Bo Thide', Swedish Institute of Space Physics, Uppsala <bt@irfu.se>
14 **
15 ** Flags added December, 1993:
16 ** -noreset to suppress printer reset code
17 ** -float to suppress positioning code (such as it is)
18 ** Wim Lewis, Seattle <wiml@netcom.com>
19 **
20 ** Copyright (C) 1988 by Jef Poskanzer and Michael Haberler.
21 **
22 ** Permission to use, copy, modify, and distribute this software and its
23 ** documentation for any purpose and without fee is hereby granted, provided
24 ** that the above copyright notice appear in all copies and that both that
25 ** copyright notice and this permission notice appear in supporting
26 ** documentation. This software is provided "as is" without express or
27 ** implied warranty.
28 */
29 
30 #include "pbm.h"
31 #include <assert.h>
32 
33 static int dpi = 75;
34 static int floating = 0; /* suppress the ``ESC & l 0 E'' ? */
35 static int pack = 0; /* use TIFF packbits compression */
36 static int delta = 0; /* use row-delta compression */
37 static int resets = 3; /* bit mask for when to emit printer reset seq */
42 
43 static void putinit ARGS(( void ));
44 static void putbit ARGS(( bit b ));
45 static void putflush ARGS(( void ));
46 static void putrest ARGS(( void ));
47 static void putitem ARGS(( void ));
48 static void packbits ARGS(( void ));
49 static void deltarow ARGS(( void ));
50 
51 int
53  int argc;
54  char* argv[];
55  {
56  FILE* ifp;
57  bit* bitrow;
58  register bit* bP;
59  int argn, rows, cols, format, rucols, padright, row, mode, blankRows;
60  int prevRowBufferIndex;
61  int savedRowBufferIndex;
62  register int nzcol, col;
63  char* usage = "[-noreset|-float|-packbits|-delta|-compress -resolution N] [pbmfile]\n\tresolution = [75|100|150|300] (dpi)";
64 
65  pbm_init( &argc, argv );
66 
67  argn = 1;
68 
69  /* Check for flags. */
70  while ( argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0' )
71  {
72  if ( pm_keymatch( argv[argn], "-resolution", 2 ) )
73  {
74  ++argn;
75  if ( argn == argc || sscanf( argv[argn], "%d", &dpi ) != 1 )
76  pm_usage( usage );
77  }
78  else if ( pm_keymatch( argv[argn], "-float", 2 ) )
79  {
80  floating = 1;
81  }
82  else if ( pm_keymatch( argv[argn], "-noreset", 2 ) )
83  {
84  resets = 0;
85  }
86  else if ( pm_keymatch( argv[argn], "-packbits", 2 ) )
87  {
88  pack = 1;
89  }
90  else if ( pm_keymatch( argv[argn], "-delta", 2 ) )
91  {
92  delta = 1;
93  }
94  else if ( pm_keymatch( argv[argn], "-compress", 2 ) )
95  {
96  pack = 1;
97  delta = 1;
98  }
99  else
100  pm_usage( usage );
101  ++argn;
102  }
103 
104  if ( argn != argc )
105  {
106  ifp = pm_openr( argv[argn] );
107  ++argn;
108  }
109  else
110  ifp = stdin;
111 
112  if ( argn != argc )
113  pm_usage( usage );
114 
116  bitrow = pbm_allocrow( cols );
117 
118  rowBufferSize = (cols + 7) / 8;
119  packBufferSize = rowBufferSize + (rowBufferSize + 127) / 128 + 1;
121 
122  prevRowBuffer = (char *) malloc(rowBufferSize);
123  rowBuffer = (char *) malloc(rowBufferSize);
124  packBuffer = (char *) malloc(packBufferSize);
125  deltaBuffer = (char *) malloc(deltaBufferSize);
126 
127  if (!rowBuffer || !prevRowBuffer || !packBuffer || !deltaBuffer) {
128  fprintf(stderr, "Can't allocate row buffer\n");
129  return 1;
130  }
131 
132  putinit( );
133 
134  blankRows = 0;
135  prevRowBufferIndex = 0;
137 
138  mode = -1;
139 
140  for ( row = 0; row < rows; ++row )
141  {
142  pbm_readpbmrow( ifp, bitrow, cols, format );
143 
144  /* Find rightmost black pixel. */
145  for ( nzcol = cols - 1; nzcol >= 0 && bitrow[nzcol] == PBM_WHITE; --nzcol )
146  continue;
147 
148  if (nzcol < 0) {
149  blankRows ++;
150  continue;
151  }
152 
153  if (blankRows > 0) {
154  printf("\033*b%dY", blankRows);
155  blankRows = 0;
157  }
158 
160 
161  /* Round up to the nearest multiple of 8. */
162  rucols = ( nzcol + 8 ) / 8;
163  rucols = rucols * 8;
164  padright = rucols - (nzcol + 1);
165 
166  rowBufferIndex = 0;
167 
168  /*
169  Generate the unpacked data
170  */
171 
172  for ( col = 0, bP = bitrow; col <= nzcol; ++col, ++bP )
173  putbit( *bP );
174  for ( col = 0; col < padright; ++col )
175  putbit( 0 );
176  putflush( );
177 
178  /*
179  Try optional compression algorithms
180  */
181 
182  if (pack) {
183  packbits();
184  } else {
186  }
187 
188  if (delta) {
189 
190  /*
191  May need to temporarily bump the row buffer index up to
192  whatever the previous line's was - if this line is shorter
193  than the previous would otherwise leave dangling cruft.
194  */
195 
196  savedRowBufferIndex = rowBufferIndex;
197 
198  if (rowBufferIndex < prevRowBufferIndex) {
199  rowBufferIndex = prevRowBufferIndex;
200  }
201 
202  deltarow();
203 
204  rowBufferIndex = savedRowBufferIndex;
205 
206  } else {
208  }
209 
213  /*
214  It's smallest when delta'ed
215  */
216  if (mode != 3) {
217  printf("\033*b3M");
218  mode = 3;
219  }
220  printf("\033*b%dW", deltaBufferIndex);
222  } else if (rowBufferIndex <= packBufferIndex) {
224  /*
225  It didn't pack - send it unpacked
226  */
227  if (mode != 0) {
228  printf("\033*b0M");
229  mode = 0;
230  }
231  printf("\033*b%dW", rowBufferIndex);
233  } else {
235  /*
236  It's smaller when packed
237  */
238  if (mode != 2) {
239  printf("\033*b2M");
240  mode = 2;
241  }
242  printf("\033*b%dW", packBufferIndex);
244  }
246  prevRowBufferIndex = rowBufferIndex;
247  }
248 
249  pm_close( ifp );
250 
251  putrest( );
252 
253  exit( 0 );
254  }
255 
257 
258 static void
260  {
261  if(resets & 1)
262  {
263  /* Printer reset. */
264  printf("\033E");
265  }
266 
267  if(!floating)
268  {
269  /* Ensure top margin is zero */
270  printf("\033&l0E");
271  }
272 
273  /* Set raster graphics resolution */
274  printf("\033*t%dR",dpi);
275 
276  /* Start raster graphics, relative adressing */
277  printf("\033*r1A");
278 
279  itemsperline = 0;
280  bitsperitem = 1;
281  item = 0;
282  bitshift = 7;
283  firstitem = 1;
284  }
285 
286 #if __STDC__
287 static void
288 putbit( bit b )
289 #else /*__STDC__*/
290 static void
292 bit b;
293 #endif /*__STDC__*/
294  {
295  if ( b == PBM_BLACK )
296  item += 1 << bitshift;
297  bitshift--;
298  if ( bitsperitem == 8 ) {
299  putitem( );
300  bitshift = 7;
301  }
302  bitsperitem++;
303  }
304 
305 static void
307  {
308  if ( bitsperitem > 1 )
309  putitem( );
310  }
311 
312 static void
314  {
315  /* end raster graphics */
316  printf( "\033*rB" );
317 
318  if(resets & 2)
319  {
320  /* Printer reset. */
321  printf("\033E");
322  }
323  }
324 
325 static void
327  {
330  bitsperitem = 0;
331  item = 0;
332  }
333 
334 static void
336  {
337  int ptr, litStart, runStart, thisByte, startByte, chew, spit;
338  packBufferIndex = 0;
339  ptr = 0;
340  while (ptr < rowBufferIndex) {
341  litStart = ptr;
342  runStart = ptr;
343  startByte = rowBuffer[ptr];
344  ptr++;
345  while (ptr < rowBufferIndex) {
346  thisByte = rowBuffer[ptr];
347  if (thisByte != startByte) {
348  if (ptr - runStart > 3) { /* found literal after nontrivial run */
349  break;
350  }
351  startByte = thisByte;
352  runStart = ptr;
353  }
354  ptr ++;
355  }
356  /*
357  We drop out here after having found a [possibly empty]
358  literal, followed by a [possibly degenerate] run of repeated
359  bytes. Degenerate runs can occur at the end of the scan line...
360  there may be a "repeat" of 1 byte (which can't actually be
361  represented as a repeat) so we simply fold it into the previous
362  literal.
363  */
364  if (runStart == rowBufferIndex - 1) {
365  runStart = rowBufferIndex;
366  }
367  /*
368  Spit out the leading literal if it isn't empty
369  */
370  chew = runStart - litStart;
371  while (chew > 0) {
372  spit = (chew > 127) ? 127 : chew;
373  packBuffer[packBufferIndex++] = (char) (spit - 1);
374  memcpy(packBuffer+packBufferIndex, rowBuffer+litStart, spit);
375  packBufferIndex += spit;
376  litStart += spit;
377  chew -= spit;
378  }
379  /*
380  Spit out the repeat, if it isn't empty
381  */
382  chew = ptr - runStart;
383  while (chew > 0) {
384  spit = (chew > 128) ? 128 : chew;
385  if (chew == spit + 1) {
386  spit--; /* don't leave a degenerate run at the end */
387  }
388  if (spit == 1) {
389  fprintf(stderr, "packbits created a degenerate run!\n");
390  }
391  packBuffer[packBufferIndex++] = (char) -(spit - 1);
392  packBuffer[packBufferIndex++] = startByte;
393  chew -= spit;
394  }
395  }
396  }
397 
398 static void
400  {
401  int burstStart, burstEnd, burstCode, mustBurst, ptr, skip, skipped, code;
402  deltaBufferIndex = 0;
404  return; /* exact match, no deltas required */
405  }
406  ptr = 0;
407  skipped = 0;
408  burstStart = -1;
409  burstEnd = -1;
410  mustBurst = 0;
411  while (ptr < rowBufferIndex) {
412  skip = 0;
413  if (ptr == 0 || skipped == 30 || rowBuffer[ptr] != prevRowBuffer[ptr] ||
414  (burstStart != -1 && ptr == rowBufferIndex - 1)) {
415  /* we want to output this byte... */
416  if (burstStart == -1) {
417  burstStart = ptr;
418  }
419  if (ptr - burstStart == 7 || ptr == rowBufferIndex - 1) {
420  /* we have to output it now... */
421  burstEnd = ptr;
422  mustBurst = 1;
423  }
424  } else {
425  /* duplicate byte, we can skip it */
426  if (burstStart != -1) {
427  burstEnd = ptr - 1;
428  mustBurst = 1;
429  }
430  skip = 1;
431  }
432  if (mustBurst) {
433  burstCode = burstEnd - burstStart; /* 0-7, means 1-8 bytes follow */
434  code = (burstCode << 5) | skipped;
435  deltaBuffer[deltaBufferIndex++] = (char) code;
436  memcpy(deltaBuffer+deltaBufferIndex, rowBuffer+burstStart, burstCode + 1);
437  deltaBufferIndex += burstCode + 1;
438  burstStart = -1;
439  burstEnd = -1;
440  mustBurst = 0;
441  skipped = 0;
442  }
443  if (skip) {
444  skipped ++;
445  }
446  ptr ++;
447  }
448  }
449 
450 
int code
Definition: aftopl.c:52
#define mode
Definition: aptex-macros.h:510
#define b
Definition: jpegint.h:372
#define skip(p, c)
Definition: ptexmac.h:70
int sscanf()
int printf()
static char usage[]
Definition: giftopnm.c:59
#define memcmp(s1, s2, n)
Definition: gsftopk.c:66
#define memcpy(d, s, n)
Definition: gsftopk.c:64
int col
Definition: gsftopk.c:443
unsigned char * bP
Definition: hbf2gf.c:371
assert(pcxLoadImage24((char *)((void *) 0), fp, pinfo, hdr))
void exit()
#define fprintf
Definition: mendex.h:64
Code related to b fwrite(a, sizeof(char), b, stdout) @d C_printf(c
#define malloc
Definition: alloca.c:91
void pm_usage(char *usage)
Definition: libpbm1.c:343
void pbm_init(int *argcP, argv)
Definition: libpbm1.c:332
FILE * pm_openr(char *name)
Definition: libpbm1.c:600
void pbm_readpbminit(FILE *file, int *colsP, int *rowsP, int *formatP)
Definition: libpbm2.c:62
void pbm_readpbmrow(FILE *file, bit *bitrow, int cols, int format)
Definition: libpbm2.c:82
#define pbm_allocrow(cols)
Definition: pbm.h:36
unsigned char bit
Definition: pbm.h:9
#define PBM_BLACK
Definition: pbm.h:11
#define PBM_WHITE
Definition: pbm.h:10
static int rows
Definition: pbmclean.c:15
static int format
Definition: pbmclean.c:15
static int cols
Definition: pbmmask.c:21
#define ARGS(alist)
Definition: pbmplus.h:235
static int item
Definition: pbmtolj.c:256
static int resets
Definition: pbmtolj.c:37
static int delta
Definition: pbmtolj.c:36
static int rowBufferSize
Definition: pbmtolj.c:39
static char * rowBuffer
Definition: pbmtolj.c:38
static int pack
Definition: pbmtolj.c:35
static void deltarow()
Definition: pbmtolj.c:399
static int packBufferSize
Definition: pbmtolj.c:40
static int itemsperline
Definition: pbmtolj.c:256
static char * deltaBuffer
Definition: pbmtolj.c:38
static char * prevRowBuffer
Definition: pbmtolj.c:38
static void packbits()
Definition: pbmtolj.c:335
static int bitsperitem
Definition: pbmtolj.c:256
static int rowBufferIndex
Definition: pbmtolj.c:39
static char * packBuffer
Definition: pbmtolj.c:38
static int floating
Definition: pbmtolj.c:34
static void putflush()
Definition: pbmtolj.c:306
static void putitem()
Definition: pbmtolj.c:326
static int bitshift
Definition: pbmtolj.c:256
static int packBufferIndex
Definition: pbmtolj.c:40
static int deltaBufferIndex
Definition: pbmtolj.c:41
static void putbit()
static int firstitem
Definition: pbmtolj.c:256
static void putrest()
Definition: pbmtolj.c:313
static void putinit()
Definition: pbmtolj.c:259
static int dpi
Definition: pbmtolj.c:33
static int deltaBufferSize
Definition: pbmtolj.c:41
int main(int argc, argv)
Definition: pbmtolj.c:52
set set set set set set set set set set set set set set set set set set set set *set set set macro pixldst op &r &cond WK op &r &cond WK op &r &cond WK else op &m &cond &ia op &r &cond WK else op &m &cond &ia elseif elseif else error unsupported base if elseif elseif else error unsupported unaligned pixldst unaligned endm macro pixst base base else pixldst base endif endm macro PF ptr
#define pm_keymatch(stra, strb, _x)
Definition: png22pnm.c:121
#define pm_close(file)
Definition: png22pnm.c:120
bstring c int memset(void *s, int c, int length)
static int row
Definition: ps2pk.c:587
Definition: inftrees.h:24
#define FILE
Definition: t1stdio.h:34
FILE * ifp
Definition: t1asm.c:88
#define argv
Definition: xmain.c:270
#define argc
Definition: xmain.c:269
#define argn