KiCad PCB EDA Suite
bitmap_io.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2001-2015 Peter Selinger.
2  * This file is part of Potrace. It is free software and it is covered
3  * by the GNU General Public License. See the file COPYING for details. */
4 
5 
6 /* Routines for manipulating bitmaps, including reading pbm files. */
7 
8 #ifdef HAVE_CONFIG_H
9 #include <config.h>
10 #endif
11 
12 #include <stdio.h>
13 
14 #include "bitmap.h"
15 #include "bitops.h"
16 
17 #define INTBITS ( 8 * sizeof(int) )
18 
19 static int bm_readbody_bmp( FILE* f, double threshold, potrace_bitmap_t** bmp );
20 static int bm_readbody_pnm( FILE* f, double threshold, potrace_bitmap_t** bmp, int magic );
21 
22 /* ---------------------------------------------------------------------- */
23 /* routines for reading pnm streams */
24 
25 /* read next character after whitespace and comments. Return EOF on
26  * end of file or error. */
27 static int fgetc_ws( FILE* f )
28 {
29  int c;
30 
31  while( 1 )
32  {
33  c = fgetc( f );
34 
35  if( c=='#' )
36  {
37  while( 1 )
38  {
39  c = fgetc( f );
40 
41  if( c=='\n' || c==EOF )
42  {
43  break;
44  }
45  }
46  }
47 
48  /* space, tab, line feed, carriage return, form-feed */
49  if( c!=' ' && c!='\t' && c!='\r' && c!='\n' && c!=12 )
50  {
51  return c;
52  }
53  }
54 }
55 
56 
57 /* skip whitespace and comments, then read a non-negative decimal
58  * number from a stream. Return -1 on EOF. Tolerate other errors (skip
59  * bad characters). Do not the read any characters following the
60  * number (put next character back into the stream) */
61 
62 static int readnum( FILE* f )
63 {
64  int c;
65  int acc;
66 
67  /* skip whitespace and comments */
68  while( 1 )
69  {
70  c = fgetc_ws( f );
71 
72  if( c==EOF )
73  {
74  return -1;
75  }
76 
77  if( c>='0' && c<='9' )
78  {
79  break;
80  }
81  }
82 
83  /* first digit is already in c */
84  acc = c - '0';
85 
86  while( 1 )
87  {
88  c = fgetc( f );
89 
90  if( c==EOF )
91  {
92  break;
93  }
94 
95  if( c<'0' || c>'9' )
96  {
97  ungetc( c, f );
98  break;
99  }
100 
101  acc *= 10;
102  acc += c - '0';
103  }
104 
105  return acc;
106 }
107 
108 
109 /* similar to readnum, but read only a single 0 or 1, and do not read
110  * any characters after it. */
111 
112 static int readbit( FILE* f )
113 {
114  int c;
115 
116  /* skip whitespace and comments */
117  while( 1 )
118  {
119  c = fgetc_ws( f );
120 
121  if( c==EOF )
122  {
123  return -1;
124  }
125 
126  if( c>='0' && c<='1' )
127  {
128  break;
129  }
130  }
131 
132  return c - '0';
133 }
134 
135 
136 /* ---------------------------------------------------------------------- */
137 
138 /* read a PNM stream: P1-P6 format (see pnm(5)), or a BMP stream, and
139  * convert the output to a bitmap. Return bitmap in *bmp. Return 0 on
140  * success, -1 on error with errno set, -2 on bad file format (with
141  * error message in bm_read_error), and 1 on premature end of file, -3
142  * on empty file (including files which contain only whitespace and
143  * comments), -4 if wrong magic number. If the return value is >=0,
144  * bmp is valid. */
145 
146 const char* bm_read_error = NULL;
147 
148 int bm_read( FILE* f, double threshold, potrace_bitmap_t** bmp )
149 {
150  int magic[2];
151 
152  /* read magic number. We ignore whitespace and comments before the
153  * magic, for the benefit of concatenated files in P1-P3 format.
154  * Multiple P1-P3 images in a single file are not formally allowed
155  * by the PNM standard, but there is no harm in being lenient. */
156 
157  magic[0] = fgetc_ws( f );
158 
159  if( magic[0] == EOF )
160  {
161  return -3;
162  }
163 
164  magic[1] = fgetc( f );
165 
166  if( magic[0] == 'P' && magic[1] >= '1' && magic[1] <= '6' )
167  {
168  return bm_readbody_pnm( f, threshold, bmp, magic[1] );
169  }
170 
171  if( magic[0] == 'B' && magic[1] == 'M' )
172  {
173  return bm_readbody_bmp( f, threshold, bmp );
174  }
175 
176  return -4;
177 }
178 
179 
180 /* ---------------------------------------------------------------------- */
181 /* read PNM format */
182 
183 /* read PNM stream after magic number. Return values as for bm_read */
184 static int bm_readbody_pnm( FILE* f, double threshold, potrace_bitmap_t** bmp, int magic )
185 {
186  potrace_bitmap_t* bm;
187  int x, y, i, b, b1, sum;
188  int bpr; /* bytes per row (as opposed to 4*bm->c) */
189  int w, h, max;
190 
191  bm = NULL;
192 
193  w = readnum( f );
194 
195  if( w<0 )
196  {
197  goto format_error;
198  }
199 
200  h = readnum( f );
201 
202  if( h<0 )
203  {
204  goto format_error;
205  }
206 
207  /* allocate bitmap */
208  bm = bm_new( w, h );
209 
210  if( !bm )
211  {
212  return -1;
213  }
214 
215  /* zero it out */
216  bm_clear( bm, 0 );
217 
218  switch( magic )
219  {
220  default:
221  /* not reached */
222  goto format_error;
223 
224  case '1':
225  /* read P1 format: PBM ascii */
226 
227  for( y = h - 1; y>=0; y-- )
228  {
229  for( x = 0; x<w; x++ )
230  {
231  b = readbit( f );
232 
233  if( b<0 )
234  {
235  goto eof;
236  }
237 
238  BM_UPUT( bm, x, y, b );
239  }
240  }
241 
242  break;
243 
244  case '2':
245  /* read P2 format: PGM ascii */
246 
247  max = readnum( f );
248 
249  if( max<1 )
250  {
251  goto format_error;
252  }
253 
254  for( y = h - 1; y>=0; y-- )
255  {
256  for( x = 0; x<w; x++ )
257  {
258  b = readnum( f );
259 
260  if( b<0 )
261  {
262  goto eof;
263  }
264 
265  BM_UPUT( bm, x, y, b > threshold * max ? 0 : 1 );
266  }
267  }
268 
269  break;
270 
271  case '3':
272  /* read P3 format: PPM ascii */
273 
274  max = readnum( f );
275 
276  if( max<1 )
277  {
278  goto format_error;
279  }
280 
281  for( y = h - 1; y>=0; y-- )
282  {
283  for( x = 0; x<w; x++ )
284  {
285  sum = 0;
286 
287  for( i = 0; i<3; i++ )
288  {
289  b = readnum( f );
290 
291  if( b<0 )
292  {
293  goto eof;
294  }
295 
296  sum += b;
297  }
298 
299  BM_UPUT( bm, x, y, sum > 3 * threshold * max ? 0 : 1 );
300  }
301  }
302 
303  break;
304 
305  case '4':
306  /* read P4 format: PBM raw */
307 
308  b = fgetc( f ); /* read single white-space character after height */
309 
310  if( b==EOF )
311  {
312  goto format_error;
313  }
314 
315  bpr = (w + 7) / 8;
316 
317  for( y = h - 1; y>=0; y-- )
318  {
319  for( i = 0; i<bpr; i++ )
320  {
321  b = fgetc( f );
322 
323  if( b==EOF )
324  {
325  goto eof;
326  }
327 
328  *bm_index( bm, i * 8,
329  y ) |= ( (potrace_word) b ) <<
330  ( 8 * ( BM_WORDSIZE - 1 - (i % BM_WORDSIZE) ) );
331  }
332  }
333 
334  break;
335 
336  case '5':
337  /* read P5 format: PGM raw */
338 
339  max = readnum( f );
340 
341  if( max<1 )
342  {
343  goto format_error;
344  }
345 
346  b = fgetc( f ); /* read single white-space character after max */
347 
348  if( b==EOF )
349  {
350  goto format_error;
351  }
352 
353  for( y = h - 1; y>=0; y-- )
354  {
355  for( x = 0; x<w; x++ )
356  {
357  b = fgetc( f );
358 
359  if( b==EOF )
360  goto eof;
361 
362  if( max>=256 )
363  {
364  b <<= 8;
365  b1 = fgetc( f );
366 
367  if( b1==EOF )
368  goto eof;
369 
370  b |= b1;
371  }
372 
373  BM_UPUT( bm, x, y, b > threshold * max ? 0 : 1 );
374  }
375  }
376 
377  break;
378 
379  case '6':
380  /* read P6 format: PPM raw */
381 
382  max = readnum( f );
383 
384  if( max<1 )
385  {
386  goto format_error;
387  }
388 
389  b = fgetc( f ); /* read single white-space character after max */
390 
391  if( b==EOF )
392  {
393  goto format_error;
394  }
395 
396  for( y = h - 1; y>=0; y-- )
397  {
398  for( x = 0; x<w; x++ )
399  {
400  sum = 0;
401 
402  for( i = 0; i<3; i++ )
403  {
404  b = fgetc( f );
405 
406  if( b==EOF )
407  {
408  goto eof;
409  }
410 
411  if( max>=256 )
412  {
413  b <<= 8;
414  b1 = fgetc( f );
415 
416  if( b1==EOF )
417  goto eof;
418 
419  b |= b1;
420  }
421 
422  sum += b;
423  }
424 
425  BM_UPUT( bm, x, y, sum > 3 * threshold * max ? 0 : 1 );
426  }
427  }
428 
429  break;
430  }
431 
432  *bmp = bm;
433  return 0;
434 
435 eof:
436  *bmp = bm;
437  return 1;
438 
439 format_error:
440  bm_free( bm );
441 
442  if( magic == '1' || magic == '4' )
443  {
444  bm_read_error = "invalid pbm file";
445  }
446  else if( magic == '2' || magic == '5' )
447  {
448  bm_read_error = "invalid pgm file";
449  }
450  else
451  {
452  bm_read_error = "invalid ppm file";
453  }
454 
455  return -2;
456 }
457 
458 
459 /* ---------------------------------------------------------------------- */
460 /* read BMP format */
461 
463 {
464  unsigned int FileSize;
465  unsigned int reserved;
466  unsigned int DataOffset;
467  unsigned int InfoSize;
468  unsigned int w; /* width */
469  unsigned int h; /* height */
470  unsigned int Planes;
471  unsigned int bits; /* bits per sample */
472  unsigned int comp; /* compression mode */
473  unsigned int ImageSize;
474  unsigned int XpixelsPerM;
475  unsigned int YpixelsPerM;
476  unsigned int ncolors; /* number of colors in palette */
477  unsigned int ColorsImportant;
478  unsigned int RedMask;
479  unsigned int GreenMask;
480  unsigned int BlueMask;
481  unsigned int AlphaMask;
482  unsigned int ctbits; /* sample size for color table */
483  int topdown; /* top-down mode? */
484 };
485 typedef struct bmp_info_s bmp_info_t;
486 
487 /* auxiliary */
488 
489 static int bmp_count = 0; /* counter for byte padding */
490 static int bmp_pos = 0; /* counter from start of BMP data */
491 
492 /* read n-byte little-endian integer. Return 1 on EOF or error, else
493  * 0. Assume n<=4. */
494 static int bmp_readint( FILE* f, int n, unsigned int* p )
495 {
496  int i;
497  unsigned int sum = 0;
498  int b;
499 
500  for( i = 0; i<n; i++ )
501  {
502  b = fgetc( f );
503 
504  if( b==EOF )
505  {
506  return 1;
507  }
508 
509  sum += b << (8 * i);
510  }
511 
512  bmp_count += n;
513  bmp_pos += n;
514  *p = sum;
515  return 0;
516 }
517 
518 
519 /* reset padding boundary */
520 static void bmp_pad_reset( void )
521 {
522  bmp_count = 0;
523 }
524 
525 
526 /* read padding bytes to 4-byte boundary. Return 1 on EOF or error,
527  * else 0. */
528 static int bmp_pad( FILE* f )
529 {
530  int c, i, b;
531 
532  c = (-bmp_count) & 3;
533 
534  for( i = 0; i<c; i++ )
535  {
536  b = fgetc( f );
537 
538  if( b==EOF )
539  {
540  return 1;
541  }
542  }
543 
544  bmp_pos += c;
545  bmp_count = 0;
546  return 0;
547 }
548 
549 
550 /* forward to the new file position. Return 1 on EOF or error, else 0 */
551 static int bmp_forward( FILE* f, int pos )
552 {
553  int b;
554 
555  while( bmp_pos < pos )
556  {
557  b = fgetc( f );
558 
559  if( b==EOF )
560  {
561  return 1;
562  }
563 
564  bmp_pos++;
565  bmp_count++;
566  }
567 
568  return 0;
569 }
570 
571 
572 #define TRY( x ) if( x ) \
573  goto try_error
574 #define TRY_EOF( x ) if( x ) \
575  goto eof
576 
577 /* correct y-coordinate for top-down format */
578 #define ycorr( y ) (bmpinfo.topdown ? bmpinfo.h - 1 - y : y)
579 
580 /* safe colortable access */
581 #define COLTABLE( c ) ( (c) < bmpinfo.ncolors ? coltable[(c)] : 0 )
582 
583 /* read BMP stream after magic number. Return values as for bm_read.
584  * We choose to be as permissive as possible, since there are many
585  * programs out there which produce BMP. For instance, ppmtobmp can
586  * produce codings with anywhere from 1-8 or 24 bits per sample,
587  * although most specifications only allow 1,4,8,24,32. We can also
588  * read both the old and new OS/2 BMP formats in addition to the
589  * Windows BMP format. */
590 static int bm_readbody_bmp( FILE* f, double threshold, potrace_bitmap_t** bmp )
591 {
592  bmp_info_t bmpinfo;
593  int* coltable;
594  unsigned int b, c;
595  unsigned int i;
596  potrace_bitmap_t* bm;
597  int mask;
598  unsigned int x, y;
599  int col[2];
600  unsigned int bitbuf;
601  unsigned int n;
602  unsigned int redshift, greenshift, blueshift;
603  int col1[2];
604 
605  bm_read_error = NULL;
606  bm = NULL;
607  coltable = NULL;
608 
609  bmp_pos = 2; /* set file position */
610 
611  /* file header (minus magic number) */
612  TRY( bmp_readint( f, 4, &bmpinfo.FileSize ) );
613  TRY( bmp_readint( f, 4, &bmpinfo.reserved ) );
614  TRY( bmp_readint( f, 4, &bmpinfo.DataOffset ) );
615 
616  /* info header */
617  TRY( bmp_readint( f, 4, &bmpinfo.InfoSize ) );
618 
619  if( bmpinfo.InfoSize == 40 || bmpinfo.InfoSize == 64
620  || bmpinfo.InfoSize == 108 || bmpinfo.InfoSize == 124 )
621  {
622  /* Windows or new OS/2 format */
623  bmpinfo.ctbits = 32; /* sample size in color table */
624  TRY( bmp_readint( f, 4, &bmpinfo.w ) );
625  TRY( bmp_readint( f, 4, &bmpinfo.h ) );
626  TRY( bmp_readint( f, 2, &bmpinfo.Planes ) );
627  TRY( bmp_readint( f, 2, &bmpinfo.bits ) );
628  TRY( bmp_readint( f, 4, &bmpinfo.comp ) );
629  TRY( bmp_readint( f, 4, &bmpinfo.ImageSize ) );
630  TRY( bmp_readint( f, 4, &bmpinfo.XpixelsPerM ) );
631  TRY( bmp_readint( f, 4, &bmpinfo.YpixelsPerM ) );
632  TRY( bmp_readint( f, 4, &bmpinfo.ncolors ) );
633  TRY( bmp_readint( f, 4, &bmpinfo.ColorsImportant ) );
634 
635  if( bmpinfo.InfoSize >= 108 ) /* V4 and V5 bitmaps */
636  {
637  TRY( bmp_readint( f, 4, &bmpinfo.RedMask ) );
638  TRY( bmp_readint( f, 4, &bmpinfo.GreenMask ) );
639  TRY( bmp_readint( f, 4, &bmpinfo.BlueMask ) );
640  TRY( bmp_readint( f, 4, &bmpinfo.AlphaMask ) );
641  }
642 
643  if( bmpinfo.w > 0x7fffffff )
644  {
645  goto format_error;
646  }
647 
648  if( bmpinfo.h > 0x7fffffff )
649  {
650  bmpinfo.h = (-bmpinfo.h) & 0xffffffff;
651  bmpinfo.topdown = 1;
652  }
653  else
654  {
655  bmpinfo.topdown = 0;
656  }
657 
658  if( bmpinfo.h > 0x7fffffff )
659  {
660  goto format_error;
661  }
662  }
663  else if( bmpinfo.InfoSize == 12 )
664  {
665  /* old OS/2 format */
666  bmpinfo.ctbits = 24; /* sample size in color table */
667  TRY( bmp_readint( f, 2, &bmpinfo.w ) );
668  TRY( bmp_readint( f, 2, &bmpinfo.h ) );
669  TRY( bmp_readint( f, 2, &bmpinfo.Planes ) );
670  TRY( bmp_readint( f, 2, &bmpinfo.bits ) );
671  bmpinfo.comp = 0;
672  bmpinfo.ncolors = 0;
673  bmpinfo.topdown = 0;
674  }
675  else
676  {
677  goto format_error;
678  }
679 
680  if( bmpinfo.comp == 3 && bmpinfo.InfoSize < 108 )
681  {
682  /* bitfield feature is only understood with V4 and V5 format */
683  goto format_error;
684  }
685 
686  if( bmpinfo.comp > 3 || bmpinfo.bits > 32 )
687  {
688  goto format_error;
689  }
690 
691  /* forward to color table (e.g., if bmpinfo.InfoSize == 64) */
692  TRY( bmp_forward( f, 14 + bmpinfo.InfoSize ) );
693 
694  if( bmpinfo.Planes != 1 )
695  {
696  bm_read_error = "cannot handle bmp planes";
697  goto format_error; /* can't handle planes */
698  }
699 
700  if( bmpinfo.ncolors == 0 )
701  {
702  bmpinfo.ncolors = 1 << bmpinfo.bits;
703  }
704 
705  /* color table, present only if bmpinfo.bits <= 8. */
706  if( bmpinfo.bits <= 8 )
707  {
708  coltable = (int*) calloc( bmpinfo.ncolors, sizeof(int) );
709 
710  if( !coltable )
711  {
712  goto std_error;
713  }
714 
715  /* NOTE: since we are reading a bitmap, we can immediately convert
716  * the color table entries to bits. */
717  for( i = 0; i<bmpinfo.ncolors; i++ )
718  {
719  TRY( bmp_readint( f, bmpinfo.ctbits / 8, &c ) );
720  c = ( (c >> 16) & 0xff ) + ( (c >> 8) & 0xff ) + (c & 0xff);
721  coltable[i] = (c > 3 * threshold * 255 ? 0 : 1);
722 
723  if( i<2 )
724  {
725  col1[i] = c;
726  }
727  }
728  }
729 
730  /* forward to data */
731  if( bmpinfo.InfoSize != 12 ) /* not old OS/2 format */
732  {
733  TRY( bmp_forward( f, bmpinfo.DataOffset ) );
734  }
735 
736  /* allocate bitmap */
737  bm = bm_new( bmpinfo.w, bmpinfo.h );
738 
739  if( !bm )
740  {
741  goto std_error;
742  }
743 
744  /* zero it out */
745  bm_clear( bm, 0 );
746 
747  switch( bmpinfo.bits + 0x100 * bmpinfo.comp )
748  {
749  default:
750  goto format_error;
751  break;
752 
753  case 0x001: /* monochrome palette */
754 
755  if( col1[0] < col1[1] ) /* make the darker color black */
756  {
757  mask = 0xff;
758  }
759  else
760  {
761  mask = 0;
762  }
763 
764  /* raster data */
765  for( y = 0; y<bmpinfo.h; y++ )
766  {
767  bmp_pad_reset();
768 
769  for( i = 0; 8 * i<bmpinfo.w; i++ )
770  {
771  TRY_EOF( bmp_readint( f, 1, &b ) );
772  b ^= mask;
773  *bm_index( bm, i * 8,
774  ycorr( y ) ) |= ( (potrace_word) b ) <<
775  ( 8 * ( BM_WORDSIZE - 1 - (i % BM_WORDSIZE) ) );
776  }
777 
778  TRY( bmp_pad( f ) );
779  }
780 
781  break;
782 
783  case 0x002: /* 2-bit to 8-bit palettes */
784  case 0x003:
785  case 0x004:
786  case 0x005:
787  case 0x006:
788  case 0x007:
789  case 0x008:
790 
791  for( y = 0; y<bmpinfo.h; y++ )
792  {
793  bmp_pad_reset();
794  bitbuf = 0; /* bit buffer: bits in buffer are high-aligned */
795  n = 0; /* number of bits currently in bitbuffer */
796 
797  for( x = 0; x<bmpinfo.w; x++ )
798  {
799  if( n < bmpinfo.bits )
800  {
801  TRY_EOF( bmp_readint( f, 1, &b ) );
802  bitbuf |= b << (INTBITS - 8 - n);
803  n += 8;
804  }
805 
806  b = bitbuf >> (INTBITS - bmpinfo.bits);
807  bitbuf <<= bmpinfo.bits;
808  n -= bmpinfo.bits;
809  BM_UPUT( bm, x, ycorr( y ), COLTABLE( b ) );
810  }
811 
812  TRY( bmp_pad( f ) );
813  }
814 
815  break;
816 
817  case 0x010: /* 16-bit encoding */
818  /* can't do this format because it is not well-documented and I
819  * don't have any samples */
820  bm_read_error = "cannot handle bmp 16-bit coding";
821  goto format_error;
822  break;
823 
824  case 0x018: /* 24-bit encoding */
825  case 0x020: /* 32-bit encoding */
826 
827  for( y = 0; y<bmpinfo.h; y++ )
828  {
829  bmp_pad_reset();
830 
831  for( x = 0; x<bmpinfo.w; x++ )
832  {
833  TRY_EOF( bmp_readint( f, bmpinfo.bits / 8, &c ) );
834  c = ( (c >> 16) & 0xff ) + ( (c >> 8) & 0xff ) + (c & 0xff);
835  BM_UPUT( bm, x, ycorr( y ), c > 3 * threshold * 255 ? 0 : 1 );
836  }
837 
838  TRY( bmp_pad( f ) );
839  }
840 
841  break;
842 
843  case 0x320: /* 32-bit encoding with bitfields */
844  redshift = lobit( bmpinfo.RedMask );
845  greenshift = lobit( bmpinfo.GreenMask );
846  blueshift = lobit( bmpinfo.BlueMask );
847 
848  for( y = 0; y<bmpinfo.h; y++ )
849  {
850  bmp_pad_reset();
851 
852  for( x = 0; x<bmpinfo.w; x++ )
853  {
854  TRY_EOF( bmp_readint( f, bmpinfo.bits / 8, &c ) );
855  c = ( (c & bmpinfo.RedMask) >> redshift ) +
856  ( (c & bmpinfo.GreenMask) >> greenshift ) +
857  ( (c & bmpinfo.BlueMask) >> blueshift );
858  BM_UPUT( bm, x, ycorr( y ), c > 3 * threshold * 255 ? 0 : 1 );
859  }
860 
861  TRY( bmp_pad( f ) );
862  }
863 
864  break;
865 
866  case 0x204: /* 4-bit runlength compressed encoding (RLE4) */
867  x = 0;
868  y = 0;
869 
870  while( 1 )
871  {
872  TRY_EOF( bmp_readint( f, 1, &b ) ); /* opcode */
873  TRY_EOF( bmp_readint( f, 1, &c ) ); /* argument */
874 
875  if( b>0 )
876  {
877  /* repeat count */
878  col[0] = COLTABLE( (c >> 4) & 0xf );
879  col[1] = COLTABLE( c & 0xf );
880 
881  for( i = 0; i<b && x<bmpinfo.w; i++ )
882  {
883  if( x>=bmpinfo.w )
884  {
885  x = 0;
886  y++;
887  }
888 
889  if( y>=bmpinfo.h )
890  {
891  break;
892  }
893 
894  BM_UPUT( bm, x, ycorr( y ), col[i & 1] );
895  x++;
896  }
897  }
898  else if( c == 0 )
899  {
900  /* end of line */
901  y++;
902  x = 0;
903  }
904  else if( c == 1 )
905  {
906  /* end of bitmap */
907  break;
908  }
909  else if( c == 2 )
910  {
911  /* "delta": skip pixels in x and y directions */
912  TRY_EOF( bmp_readint( f, 1, &b ) ); /* x offset */
913  TRY_EOF( bmp_readint( f, 1, &c ) ); /* y offset */
914  x += b;
915  y += c;
916  }
917  else
918  {
919  /* verbatim segment */
920  for( i = 0; i<c; i++ )
921  {
922  if( (i & 1)==0 )
923  {
924  TRY_EOF( bmp_readint( f, 1, &b ) );
925  }
926 
927  if( x>=bmpinfo.w )
928  {
929  x = 0;
930  y++;
931  }
932 
933  if( y>=bmpinfo.h )
934  {
935  break;
936  }
937 
938  BM_PUT( bm, x, ycorr( y ), COLTABLE( ( b >> ( 4 - 4 * (i & 1) ) ) & 0xf ) );
939  x++;
940  }
941 
942  if( (c + 1) & 2 )
943  {
944  /* pad to 16-bit boundary */
945  TRY_EOF( bmp_readint( f, 1, &b ) );
946  }
947  }
948  }
949 
950  break;
951 
952  case 0x108: /* 8-bit runlength compressed encoding (RLE8) */
953  x = 0;
954  y = 0;
955 
956  while( 1 )
957  {
958  TRY_EOF( bmp_readint( f, 1, &b ) ); /* opcode */
959  TRY_EOF( bmp_readint( f, 1, &c ) ); /* argument */
960 
961  if( b>0 )
962  {
963  /* repeat count */
964  for( i = 0; i<b; i++ )
965  {
966  if( x>=bmpinfo.w )
967  {
968  x = 0;
969  y++;
970  }
971 
972  if( y>=bmpinfo.h )
973  {
974  break;
975  }
976 
977  BM_UPUT( bm, x, ycorr( y ), COLTABLE( c ) );
978  x++;
979  }
980  }
981  else if( c == 0 )
982  {
983  /* end of line */
984  y++;
985  x = 0;
986  }
987  else if( c == 1 )
988  {
989  /* end of bitmap */
990  break;
991  }
992  else if( c == 2 )
993  {
994  /* "delta": skip pixels in x and y directions */
995  TRY_EOF( bmp_readint( f, 1, &b ) ); /* x offset */
996  TRY_EOF( bmp_readint( f, 1, &c ) ); /* y offset */
997  x += b;
998  y += c;
999  }
1000  else
1001  {
1002  /* verbatim segment */
1003  for( i = 0; i<c; i++ )
1004  {
1005  TRY_EOF( bmp_readint( f, 1, &b ) );
1006 
1007  if( x>=bmpinfo.w )
1008  {
1009  x = 0;
1010  y++;
1011  }
1012 
1013  if( y>=bmpinfo.h )
1014  {
1015  break;
1016  }
1017 
1018  BM_PUT( bm, x, ycorr( y ), COLTABLE( b ) );
1019  x++;
1020  }
1021 
1022  if( c & 1 )
1023  {
1024  /* pad input to 16-bit boundary */
1025  TRY_EOF( bmp_readint( f, 1, &b ) );
1026  }
1027  }
1028  }
1029 
1030  break;
1031  } /* switch */
1032 
1033  /* skip any potential junk after the data section, but don't
1034  * complain in case EOF is encountered */
1035  bmp_forward( f, bmpinfo.FileSize );
1036 
1037  free( coltable );
1038  *bmp = bm;
1039  return 0;
1040 
1041 eof:
1042  free( coltable );
1043  *bmp = bm;
1044  return 1;
1045 
1046 format_error:
1047 try_error:
1048  free( coltable );
1049  bm_free( bm );
1050 
1051  if( !bm_read_error )
1052  {
1053  bm_read_error = "invalid bmp file";
1054  }
1055 
1056  return -2;
1057 
1058 std_error:
1059  free( coltable );
1060  bm_free( bm );
1061  return -1;
1062 }
1063 
1064 
1065 /* ---------------------------------------------------------------------- */
1066 /* output pbm format */
1067 
1068 void bm_writepbm( FILE* f, potrace_bitmap_t* bm )
1069 {
1070  int w, h, bpr, y, i, c;
1071 
1072  w = bm->w;
1073  h = bm->h;
1074 
1075  bpr = (w + 7) / 8;
1076 
1077  fprintf( f, "P4\n%d %d\n", w, h );
1078 
1079  for( y = h - 1; y>=0; y-- )
1080  {
1081  for( i = 0; i<bpr; i++ )
1082  {
1083  c =
1084  ( *bm_index( bm, i * 8,
1085  y ) >> ( 8 * ( BM_WORDSIZE - 1 - (i % BM_WORDSIZE) ) ) ) & 0xff;
1086  fputc( c, f );
1087  }
1088  }
1089 }
1090 
1091 
1092 /* ---------------------------------------------------------------------- */
1093 /* output - for primitive debugging purposes only! */
1094 
1095 /* print bitmap to screen */
1096 int bm_print( FILE* f, potrace_bitmap_t* bm )
1097 {
1098  int x, y;
1099  int xx, yy;
1100  int d;
1101  int sw, sh;
1102 
1103  sw = bm->w < 79 ? bm->w : 79;
1104  sh = bm->w < 79 ? bm->h : bm->h * sw * 44 / (79 * bm->w);
1105 
1106  for( yy = sh - 1; yy>=0; yy-- )
1107  {
1108  for( xx = 0; xx<sw; xx++ )
1109  {
1110  d = 0;
1111 
1112  for( x = xx * bm->w / sw; x<(xx + 1) * bm->w / sw; x++ )
1113  {
1114  for( y = yy * bm->h / sh; y<(yy + 1) * bm->h / sh; y++ )
1115  {
1116  if( BM_GET( bm, x, y ) )
1117  {
1118  d++;
1119  }
1120  }
1121  }
1122 
1123  fputc( d ? '*' : ' ', f );
1124  }
1125 
1126  fputc( '\n', f );
1127  }
1128 
1129  return 0;
1130 }
unsigned int Planes
Definition: bitmap_io.cpp:470
static int bmp_forward(FILE *f, int pos)
Definition: bitmap_io.cpp:551
#define TRY_EOF(x)
Definition: bitmap_io.cpp:574
unsigned int DataOffset
Definition: bitmap_io.cpp:466
static void bm_free(potrace_bitmap_t *bm)
Definition: bitmap.h:49
static int bmp_pos
Definition: bitmap_io.cpp:490
unsigned int FileSize
Definition: bitmap_io.cpp:464
#define bm_index(bm, x, y)
Definition: bitmap.h:33
#define BM_WORDSIZE
Definition: bitmap.h:24
#define BM_UPUT(bm, x, y, b)
Definition: bitmap.h:41
static int bmp_pad(FILE *f)
Definition: bitmap_io.cpp:528
void bm_writepbm(FILE *f, potrace_bitmap_t *bm)
Definition: bitmap_io.cpp:1068
static int bm_readbody_bmp(FILE *f, double threshold, potrace_bitmap_t **bmp)
Definition: bitmap_io.cpp:590
unsigned int YpixelsPerM
Definition: bitmap_io.cpp:475
unsigned int reserved
Definition: bitmap_io.cpp:465
#define ycorr(y)
Definition: bitmap_io.cpp:578
unsigned long potrace_word
Definition: potracelib.h:53
unsigned int ctbits
Definition: bitmap_io.cpp:482
unsigned int ColorsImportant
Definition: bitmap_io.cpp:477
#define INTBITS
Definition: bitmap_io.cpp:17
unsigned int comp
Definition: bitmap_io.cpp:472
#define BM_GET(bm, x, y)
Definition: bitmap.h:42
int bm_read(FILE *f, double threshold, potrace_bitmap_t **bmp)
Definition: bitmap_io.cpp:148
static int bmp_readint(FILE *f, int n, unsigned int *p)
Definition: bitmap_io.cpp:494
static unsigned int lobit(unsigned int x)
Definition: bitops.h:60
static int readbit(FILE *f)
Definition: bitmap_io.cpp:112
const char * bm_read_error
Definition: bitmap_io.cpp:146
unsigned int InfoSize
Definition: bitmap_io.cpp:467
static int bmp_count
Definition: bitmap_io.cpp:489
static potrace_bitmap_t * bm_new(int w, int h)
Definition: bitmap.h:62
#define TRY(x)
Definition: bitmap_io.cpp:572
unsigned int BlueMask
Definition: bitmap_io.cpp:480
static int bm_readbody_pnm(FILE *f, double threshold, potrace_bitmap_t **bmp, int magic)
Definition: bitmap_io.cpp:184
static void bm_clear(potrace_bitmap_t *bm, int c)
Definition: bitmap.h:98
unsigned int h
Definition: bitmap_io.cpp:469
unsigned int AlphaMask
Definition: bitmap_io.cpp:481
unsigned int GreenMask
Definition: bitmap_io.cpp:479
#define max(a, b)
Definition: auxiliary.h:86
unsigned int RedMask
Definition: bitmap_io.cpp:478
#define COLTABLE(c)
Definition: bitmap_io.cpp:581
unsigned int ncolors
Definition: bitmap_io.cpp:476
static int fgetc_ws(FILE *f)
Definition: bitmap_io.cpp:27
unsigned int w
Definition: bitmap_io.cpp:468
unsigned int ImageSize
Definition: bitmap_io.cpp:473
unsigned int XpixelsPerM
Definition: bitmap_io.cpp:474
#define BM_PUT(bm, x, y, b)
Definition: bitmap.h:46
int bm_print(FILE *f, potrace_bitmap_t *bm)
Definition: bitmap_io.cpp:1096
unsigned int bits
Definition: bitmap_io.cpp:471
static void bmp_pad_reset(void)
Definition: bitmap_io.cpp:520
static int readnum(FILE *f)
Definition: bitmap_io.cpp:62