You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1180 lines
27 KiB

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