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.

638 lines
17 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. #ifdef HAVE_CONFIG_H
  5. #include <config.h>
  6. #endif
  7. #include <cstdint>
  8. #include <limits.h>
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #ifdef HAVE_INTTYPES_H
  13. #include <inttypes.h>
  14. #endif
  15. #include "bitmap.h"
  16. #include "curve.h"
  17. #include "decompose.h"
  18. #include "lists.h"
  19. #include "potracelib.h"
  20. #include "progress.h"
  21. /* ---------------------------------------------------------------------- */
  22. /* deterministically and efficiently hash (x,y) into a pseudo-random bit */
  23. static inline int detrand( int x, int y )
  24. {
  25. unsigned int z;
  26. static const unsigned char t[256] =
  27. {
  28. /* non-linear sequence: constant term of inverse in GF(8),
  29. * mod x^8+x^4+x^3+x+1 */
  30. 0,
  31. 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0,
  32. 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1,
  33. 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0,
  34. 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1,
  35. 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0,
  36. 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0,
  37. 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1,
  38. 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1,
  39. 0, 1, 0, 1, 0, 1, 0,
  40. };
  41. /* 0x04b3e375 and 0x05a8ef93 are chosen to contain every possible
  42. * 5-bit sequence */
  43. z = ( ( 0x04b3e375 * x ) ^ y ) * 0x05a8ef93;
  44. z = t[z & 0xff] ^ t[( z >> 8 ) & 0xff] ^ t[( z >> 16 ) & 0xff] ^ t[( z >> 24 ) & 0xff];
  45. return z;
  46. }
  47. /* ---------------------------------------------------------------------- */
  48. /* auxiliary bitmap manipulations */
  49. /* set the excess padding to 0 */
  50. static void bm_clearexcess( potrace_bitmap_t* bm )
  51. {
  52. potrace_word mask;
  53. int y;
  54. if( bm->w % BM_WORDBITS != 0 )
  55. {
  56. mask = BM_ALLBITS << ( BM_WORDBITS - ( bm->w % BM_WORDBITS ) );
  57. for( y = 0; y < bm->h; y++ )
  58. {
  59. *bm_index( bm, bm->w, y ) &= mask;
  60. }
  61. }
  62. }
  63. struct bbox_s
  64. {
  65. int x0, x1, y0, y1; /* bounding box */
  66. };
  67. typedef struct bbox_s bbox_t;
  68. /* clear the bm, assuming the bounding box is set correctly (faster
  69. * than clearing the whole bitmap) */
  70. static void clear_bm_with_bbox( potrace_bitmap_t* bm, bbox_t* bbox )
  71. {
  72. int imin = ( bbox->x0 / BM_WORDBITS );
  73. int imax = ( ( bbox->x1 + BM_WORDBITS - 1 ) / BM_WORDBITS );
  74. int i, y;
  75. for( y = bbox->y0; y < bbox->y1; y++ )
  76. {
  77. for( i = imin; i < imax; i++ )
  78. {
  79. bm_scanline( bm, y )[i] = 0;
  80. }
  81. }
  82. }
  83. /* ---------------------------------------------------------------------- */
  84. /* auxiliary functions */
  85. /* return the "majority" value of bitmap bm at intersection (x,y). We
  86. * assume that the bitmap is balanced at "radius" 1. */
  87. static int majority( potrace_bitmap_t* bm, int x, int y )
  88. {
  89. int i, a, ct;
  90. for( i = 2; i < 5; i++ )
  91. {
  92. /* check at "radius" i */
  93. ct = 0;
  94. for( a = -i + 1; a <= i - 1; a++ )
  95. {
  96. ct += BM_GET( bm, x + a, y + i - 1 ) ? 1 : -1;
  97. ct += BM_GET( bm, x + i - 1, y + a - 1 ) ? 1 : -1;
  98. ct += BM_GET( bm, x + a - 1, y - i ) ? 1 : -1;
  99. ct += BM_GET( bm, x - i, y + a ) ? 1 : -1;
  100. }
  101. if( ct > 0 )
  102. {
  103. return 1;
  104. }
  105. else if( ct < 0 )
  106. {
  107. return 0;
  108. }
  109. }
  110. return 0;
  111. }
  112. /* ---------------------------------------------------------------------- */
  113. /* decompose image into paths */
  114. /* efficiently invert bits [x,infty) and [xa,infty) in line y. Here xa
  115. * must be a multiple of BM_WORDBITS. */
  116. static void xor_to_ref( potrace_bitmap_t* bm, int x, int y, int xa )
  117. {
  118. int xhi = x & - BM_WORDBITS;
  119. int xlo = x & ( BM_WORDBITS - 1 ); /* = x % BM_WORDBITS */
  120. int i;
  121. if( xhi < xa )
  122. {
  123. for( i = xhi; i < xa; i += BM_WORDBITS )
  124. {
  125. *bm_index( bm, i, y ) ^= BM_ALLBITS;
  126. }
  127. }
  128. else
  129. {
  130. for( i = xa; i < xhi; i += BM_WORDBITS )
  131. {
  132. *bm_index( bm, i, y ) ^= BM_ALLBITS;
  133. }
  134. }
  135. /* note: the following "if" is needed because x86 treats a<<b as
  136. * a<<(b&31). I spent hours looking for this bug. */
  137. if( xlo )
  138. {
  139. *bm_index( bm, xhi, y ) ^= ( BM_ALLBITS << ( BM_WORDBITS - xlo ) );
  140. }
  141. }
  142. /* a path is represented as an array of points, which are thought to
  143. * lie on the corners of pixels (not on their centers). The path point
  144. * (x,y) is the lower left corner of the pixel (x,y). Paths are
  145. * represented by the len/pt components of a path_t object (which
  146. * also stores other information about the path) */
  147. /* xor the given pixmap with the interior of the given path. Note: the
  148. * path must be within the dimensions of the pixmap. */
  149. static void xor_path( potrace_bitmap_t* bm, path_t* p )
  150. {
  151. int xa, x, y, k, y1;
  152. if( p->priv->len <= 0 )
  153. {
  154. /* a path of length 0 is silly, but legal */
  155. return;
  156. }
  157. y1 = p->priv->pt[p->priv->len - 1].y;
  158. xa = p->priv->pt[0].x & - BM_WORDBITS;
  159. for( k = 0; k < p->priv->len; k++ )
  160. {
  161. x = p->priv->pt[k].x;
  162. y = p->priv->pt[k].y;
  163. if( y != y1 )
  164. {
  165. /* efficiently invert the rectangle [x,xa] x [y,y1] */
  166. xor_to_ref( bm, x, min( y, y1 ), xa );
  167. y1 = y;
  168. }
  169. }
  170. }
  171. /* Find the bounding box of a given path. Path is assumed to be of
  172. * non-zero length. */
  173. static void setbbox_path( bbox_t* bbox, path_t* p )
  174. {
  175. int x, y;
  176. int k;
  177. bbox->y0 = INT_MAX;
  178. bbox->y1 = 0;
  179. bbox->x0 = INT_MAX;
  180. bbox->x1 = 0;
  181. for( k = 0; k < p->priv->len; k++ )
  182. {
  183. x = p->priv->pt[k].x;
  184. y = p->priv->pt[k].y;
  185. if( x < bbox->x0 )
  186. {
  187. bbox->x0 = x;
  188. }
  189. if( x > bbox->x1 )
  190. {
  191. bbox->x1 = x;
  192. }
  193. if( y < bbox->y0 )
  194. {
  195. bbox->y0 = y;
  196. }
  197. if( y > bbox->y1 )
  198. {
  199. bbox->y1 = y;
  200. }
  201. }
  202. }
  203. /* compute a path in the given pixmap, separating black from white.
  204. * Start path at the point (x0,x1), which must be an upper left corner
  205. * of the path. Also compute the area enclosed by the path. Return a
  206. * new path_t object, or NULL on error (note that a legitimate path
  207. * cannot have length 0). Sign is required for correct interpretation
  208. * of turnpolicies. */
  209. static path_t* findpath( potrace_bitmap_t* bm, int x0, int y0, int sign, int turnpolicy )
  210. {
  211. int x, y, dirx, diry, len, size;
  212. uint64_t area;
  213. int c, d, tmp;
  214. point_t* pt, * pt1;
  215. path_t* p = NULL;
  216. x = x0;
  217. y = y0;
  218. dirx = 0;
  219. diry = -1;
  220. len = size = 0;
  221. pt = NULL;
  222. area = 0;
  223. while( 1 )
  224. {
  225. /* add point to path */
  226. if( len >= size )
  227. {
  228. size += 100;
  229. size = (int) ( 1.3 * size );
  230. pt1 = (point_t*) realloc( pt, size * sizeof( point_t ) );
  231. if( !pt1 )
  232. {
  233. goto error;
  234. }
  235. pt = pt1;
  236. }
  237. pt[len].x = x;
  238. pt[len].y = y;
  239. len++;
  240. /* move to next point */
  241. x += dirx;
  242. y += diry;
  243. area += x * diry;
  244. /* path complete? */
  245. if( x == x0 && y == y0 )
  246. {
  247. break;
  248. }
  249. /* determine next direction */
  250. c = BM_GET( bm, x + ( dirx + diry - 1 ) / 2, y + ( diry - dirx - 1 ) / 2 );
  251. d = BM_GET( bm, x + ( dirx - diry - 1 ) / 2, y + ( diry + dirx - 1 ) / 2 );
  252. if( c && !d )
  253. {
  254. /* ambiguous turn */
  255. if( turnpolicy == POTRACE_TURNPOLICY_RIGHT
  256. || ( turnpolicy == POTRACE_TURNPOLICY_BLACK && sign == '+' )
  257. || ( turnpolicy == POTRACE_TURNPOLICY_WHITE && sign == '-' )
  258. || ( turnpolicy == POTRACE_TURNPOLICY_RANDOM && detrand( x, y ) )
  259. || ( turnpolicy == POTRACE_TURNPOLICY_MAJORITY && majority( bm, x, y ) )
  260. || ( turnpolicy == POTRACE_TURNPOLICY_MINORITY && !majority( bm, x, y ) ) )
  261. {
  262. tmp = dirx; /* right turn */
  263. dirx = diry;
  264. diry = -tmp;
  265. }
  266. else
  267. {
  268. tmp = dirx; /* left turn */
  269. dirx = -diry;
  270. diry = tmp;
  271. }
  272. }
  273. else if( c )
  274. {
  275. /* right turn */
  276. tmp = dirx;
  277. dirx = diry;
  278. diry = -tmp;
  279. }
  280. else if( !d )
  281. {
  282. /* left turn */
  283. tmp = dirx;
  284. dirx = -diry;
  285. diry = tmp;
  286. }
  287. } /* while this path */
  288. /* allocate new path object */
  289. p = path_new();
  290. if( !p )
  291. {
  292. goto error;
  293. }
  294. p->priv->pt = pt;
  295. p->priv->len = len;
  296. p->area = area <= INT_MAX ? area : INT_MAX; /* avoid overflow */
  297. p->sign = sign;
  298. return p;
  299. error:
  300. free( pt );
  301. return NULL;
  302. }
  303. /* Give a tree structure to the given path list, based on "insideness"
  304. * testing. I.e., path A is considered "below" path B if it is inside
  305. * path B. The input pathlist is assumed to be ordered so that "outer"
  306. * paths occur before "inner" paths. The tree structure is stored in
  307. * the "childlist" and "sibling" components of the path_t
  308. * structure. The linked list structure is also changed so that
  309. * negative path components are listed immediately after their
  310. * positive parent. Note: some backends may ignore the tree
  311. * structure, others may use it e.g. to group path components. We
  312. * assume that in the input, point 0 of each path is an "upper left"
  313. * corner of the path, as returned by bm_to_pathlist. This makes it
  314. * easy to find an "interior" point. The bm argument should be a
  315. * bitmap of the correct size (large enough to hold all the paths),
  316. * and will be used as scratch space. Return 0 on success or -1 on
  317. * error with errno set. */
  318. static void pathlist_to_tree( path_t* plist, potrace_bitmap_t* bm )
  319. {
  320. path_t* p, * p1;
  321. path_t* heap, * heap1;
  322. path_t* cur;
  323. path_t* head;
  324. path_t** plist_hook; /* for fast appending to linked list */
  325. path_t** hook_in, ** hook_out; /* for fast appending to linked list */
  326. bbox_t bbox;
  327. bm_clear( bm, 0 );
  328. /* save original "next" pointers */
  329. list_forall( p, plist ) {
  330. p->sibling = p->next;
  331. p->childlist = NULL;
  332. }
  333. heap = plist;
  334. /* the heap holds a list of lists of paths. Use "childlist" field
  335. * for outer list, "next" field for inner list. Each of the sublists
  336. * is to be turned into a tree. This code is messy, but it is
  337. * actually fast. Each path is rendered exactly once. We use the
  338. * heap to get a tail recursive algorithm: the heap holds a list of
  339. * pathlists which still need to be transformed. */
  340. while( heap )
  341. {
  342. /* unlink first sublist */
  343. cur = heap;
  344. heap = heap->childlist;
  345. cur->childlist = NULL;
  346. /* unlink first path */
  347. head = cur;
  348. cur = cur->next;
  349. head->next = NULL;
  350. /* render path */
  351. xor_path( bm, head );
  352. setbbox_path( &bbox, head );
  353. /* now do insideness test for each element of cur; append it to
  354. * head->childlist if it's inside head, else append it to
  355. * head->next. */
  356. hook_in = &head->childlist;
  357. hook_out = &head->next;
  358. list_forall_unlink( p, cur ) {
  359. if( p->priv->pt[0].y <= bbox.y0 )
  360. {
  361. list_insert_beforehook( p, hook_out );
  362. /* append the remainder of the list to hook_out */
  363. *hook_out = cur;
  364. break;
  365. }
  366. if( BM_GET( bm, p->priv->pt[0].x, p->priv->pt[0].y - 1 ) )
  367. {
  368. list_insert_beforehook( p, hook_in );
  369. }
  370. else
  371. {
  372. list_insert_beforehook( p, hook_out );
  373. }
  374. }
  375. /* clear bm */
  376. clear_bm_with_bbox( bm, &bbox );
  377. /* now schedule head->childlist and head->next for further
  378. * processing */
  379. if( head->next )
  380. {
  381. head->next->childlist = heap;
  382. heap = head->next;
  383. }
  384. if( head->childlist )
  385. {
  386. head->childlist->childlist = heap;
  387. heap = head->childlist;
  388. }
  389. }
  390. /* copy sibling structure from "next" to "sibling" component */
  391. p = plist;
  392. while( p )
  393. {
  394. p1 = p->sibling;
  395. p->sibling = p->next;
  396. p = p1;
  397. }
  398. /* reconstruct a new linked list ("next") structure from tree
  399. * ("childlist", "sibling") structure. This code is slightly messy,
  400. * because we use a heap to make it tail recursive: the heap
  401. * contains a list of childlists which still need to be
  402. * processed. */
  403. heap = plist;
  404. if( heap )
  405. {
  406. heap->next = NULL; /* heap is a linked list of childlists */
  407. }
  408. plist = NULL;
  409. plist_hook = &plist;
  410. while( heap )
  411. {
  412. heap1 = heap->next;
  413. for( p = heap; p; p = p->sibling )
  414. {
  415. /* p is a positive path */
  416. /* append to linked list */
  417. list_insert_beforehook( p, plist_hook );
  418. /* go through its children */
  419. for( p1 = p->childlist; p1; p1 = p1->sibling )
  420. {
  421. /* append to linked list */
  422. list_insert_beforehook( p1, plist_hook );
  423. /* append its childlist to heap, if non-empty */
  424. if( p1->childlist )
  425. {
  426. list_append( path_t, heap1, p1->childlist );
  427. }
  428. }
  429. }
  430. heap = heap1;
  431. }
  432. }
  433. /* find the next set pixel in a row <= y. Pixels are searched first
  434. * left-to-right, then top-down. In other words, (x,y)<(x',y') if y>y'
  435. * or y=y' and x<x'. If found, return 0 and store pixel in
  436. * (*xp,*yp). Else return 1. Note that this function assumes that
  437. * excess bytes have been cleared with bm_clearexcess. */
  438. static int findnext( potrace_bitmap_t* bm, int* xp, int* yp )
  439. {
  440. int x;
  441. int y;
  442. int x0;
  443. x0 = ( *xp ) & ~( BM_WORDBITS - 1 );
  444. for( y = *yp; y >= 0; y-- )
  445. {
  446. for( x = x0; x < bm->w && x >= 0; x += (unsigned) BM_WORDBITS )
  447. {
  448. if( *bm_index( bm, x, y ) )
  449. {
  450. while( !BM_GET( bm, x, y ) )
  451. {
  452. x++;
  453. }
  454. /* found */
  455. *xp = x;
  456. *yp = y;
  457. return 0;
  458. }
  459. }
  460. x0 = 0;
  461. }
  462. /* not found */
  463. return 1;
  464. }
  465. /* Decompose the given bitmap into paths. Returns a linked list of
  466. * path_t objects with the fields len, pt, area, sign filled
  467. * in. Returns 0 on success with plistp set, or -1 on error with errno
  468. * set. */
  469. int bm_to_pathlist( const potrace_bitmap_t* bm, path_t** plistp, const potrace_param_t* param,
  470. progress_t* progress )
  471. {
  472. int x;
  473. int y;
  474. path_t* p;
  475. path_t* plist = NULL; /* linked list of path objects */
  476. path_t** plist_hook = &plist; /* used to speed up appending to linked list */
  477. potrace_bitmap_t* bm1 = NULL;
  478. int sign;
  479. bm1 = bm_dup( bm );
  480. if( !bm1 )
  481. {
  482. goto error;
  483. }
  484. /* be sure the byte padding on the right is set to 0, as the fast
  485. * pixel search below relies on it */
  486. bm_clearexcess( bm1 );
  487. /* iterate through components */
  488. x = 0;
  489. y = bm1->h - 1;
  490. while( findnext( bm1, &x, &y ) == 0 )
  491. {
  492. /* calculate the sign by looking at the original */
  493. sign = BM_GET( bm, x, y ) ? '+' : '-';
  494. /* calculate the path */
  495. p = findpath( bm1, x, y + 1, sign, param->turnpolicy );
  496. if( p == NULL )
  497. {
  498. goto error;
  499. }
  500. /* update buffered image */
  501. xor_path( bm1, p );
  502. /* if it's a turd, eliminate it, else append it to the list */
  503. if( p->area <= param->turdsize )
  504. {
  505. path_free( p );
  506. }
  507. else
  508. {
  509. list_insert_beforehook( p, plist_hook );
  510. }
  511. if( bm1->h > 0 )
  512. {
  513. /* to be sure */
  514. progress_update( 1 - y / (double) bm1->h, progress );
  515. }
  516. }
  517. pathlist_to_tree( plist, bm1 );
  518. bm_free( bm1 );
  519. *plistp = plist;
  520. progress_update( 1.0, progress );
  521. return 0;
  522. error:
  523. bm_free( bm1 );
  524. list_forall_unlink( p, plist ) {
  525. path_free( p );
  526. }
  527. return -1;
  528. }