Source code of Windows XP (NT5)
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.

532 lines
12 KiB

  1. /***********************************************************************
  2. *
  3. * BitMap Openration modules
  4. *
  5. * Copyright (c) 1997-1999 Microsoft Corporation.
  6. *
  7. ***********************************************************************
  8. * BitMap Specifications
  9. *
  10. * Coordinate
  11. * (0,0) X (255,0)
  12. * +--------------*
  13. * |
  14. * Y |
  15. * |
  16. * |
  17. * |
  18. * *
  19. * (0,255)
  20. * Memory Boundary : Word Boundary
  21. *
  22. * Entry List
  23. * BMPDefine,
  24. * BMPZoomUp,
  25. * BMPOutline
  26. ***********************************************************************/
  27. #include "stdafx.h"
  28. #include "vdata.h"
  29. #include "extfunc.h"
  30. #define BMPWIDMAX 256
  31. #define BMPDEPMAX 256
  32. #define BMPMAX 8
  33. struct BMPDef {
  34. int width, depth;
  35. unsigned char *buf;
  36. int bWid;
  37. };
  38. void BMPInit(void);
  39. int BMPDefine(unsigned char *buf,int xWid,int yWid);
  40. int BMPFreDef(int bmpno);
  41. int BMPMkCont(int BMPNo,int wkBMP,int refBMP,int lsthdl);
  42. static int SearchON(int BMPNo,int x,int y);
  43. static int outline(int BMPNo,int x,int y,int lsthdl,int wkBMP,int refBMP);
  44. static int ContributeOutside(int BMPNo,int wkBMP,struct vecdata *org,int lsthdl);
  45. static int ContributeInside(int BMPNo,int wkBMP,struct vecdata *org,int lsthdl);
  46. int rdot(int BMP,int x,int y);
  47. void wdot(int BMP,int x,int y,int onoff);
  48. int ReverseRight(int BMPNo,int x,int y);
  49. static void cpybuf(int src,int dst);
  50. int BMPReverse(int bmpNo);
  51. int BMPClear(int bmpNo);
  52. struct BMPDef BMPTbl[BMPMAX]={0};
  53. /* On Bit Most left position */
  54. static unsigned char bitptbl[256] = {
  55. 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
  56. 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
  57. 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
  58. 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
  59. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  60. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  61. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  62. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  63. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  64. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  65. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  66. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  67. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  68. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  69. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  70. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  71. };
  72. static unsigned char wmaskB[8]={
  73. 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01
  74. };
  75. static unsigned char rightmask[8] = {
  76. 0xff, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01
  77. };
  78. /***********************************************************************
  79. * BMP Initialize
  80. */
  81. /* */ void
  82. /* */ BMPInit()
  83. /*
  84. * returns; none
  85. ***********************************************************************/
  86. {
  87. int i;
  88. for ( i = 0; i < BMPMAX; i++)
  89. BMPTbl[i].buf=(unsigned char *)0;
  90. return;
  91. }
  92. /***********************************************************************
  93. * Define BitMap
  94. */
  95. /* */ int
  96. /* */ BMPDefine(
  97. /* */ unsigned char *buf,
  98. /* */ int xWid,
  99. /* */ int yWid)
  100. /*
  101. * returns : 0-(BMPMAX-1), -1
  102. ***********************************************************************/
  103. {
  104. int i;
  105. /* Check Size */
  106. if ( xWid > BMPWIDMAX || xWid < 0
  107. || yWid > BMPWIDMAX || yWid < 0)
  108. goto ERET;
  109. /* Set Define */
  110. for ( i = 0; i < BMPMAX; i++) {
  111. if (BMPTbl[i].buf==(unsigned char *)0) {
  112. BMPTbl[i].bWid = (xWid + 15)/16*2;
  113. BMPTbl[i].width = xWid;
  114. BMPTbl[i].depth = yWid;
  115. BMPTbl[i].buf = buf;
  116. return(i);
  117. }
  118. }
  119. ERET:
  120. return( -1);
  121. }
  122. /***********************************************************************
  123. * Free BMP define
  124. */
  125. /* */ int
  126. /* */ BMPFreDef( int bmpno)
  127. /*
  128. * returns : 0, -1
  129. ***********************************************************************/
  130. {
  131. if ( bmpno < 0 || bmpno >= BMPMAX)
  132. return -1;
  133. else {
  134. BMPTbl[bmpno].buf = 0;
  135. return 0;
  136. }
  137. }
  138. /***********************************************************************
  139. * Get Outline
  140. */
  141. /* */ int
  142. /* */ BMPMkCont( int BMPNo, int wkBMP, int refBMP, int lsthdl)
  143. /*
  144. * returns : Number of Contour, -1
  145. * REMARKS : Used BMP be destroyed
  146. ***********************************************************************/
  147. {
  148. int x, y;
  149. int ncont;
  150. int sts;
  151. VDNew( lsthdl);
  152. sts = 0;
  153. ncont = 0;
  154. cpybuf( BMPNo, wkBMP);
  155. cpybuf( BMPNo, refBMP);
  156. for ( y = 0; y < BMPTbl[BMPNo].depth; y++) {
  157. x = 0;
  158. while ( (x = SearchON( wkBMP, x, y)) <BMPTbl[BMPNo].width) {
  159. if ((sts = outline( BMPNo, x, y,lsthdl, wkBMP, refBMP))<0)
  160. goto RET;
  161. ncont++;
  162. x++;
  163. }
  164. }
  165. sts = ncont;
  166. cpybuf(refBMP,BMPNo);
  167. RET:
  168. return( sts);
  169. }
  170. /***********************************************************************
  171. * Search ON dot
  172. */
  173. /* */ static int
  174. /* */ SearchON( int BMPNo, int x, int y)
  175. /*
  176. * returns : found position, Width(Not Found case)
  177. ***********************************************************************/
  178. {
  179. int bpos; /* byte position */
  180. int sbitpos; /* Start Byte Bit position */
  181. unsigned char *p;
  182. bpos = x/8;
  183. sbitpos = x % 8;
  184. p = BMPTbl[BMPNo].buf + BMPTbl[BMPNo].bWid*y + bpos;
  185. /* First Byte */
  186. if ( *p & rightmask[sbitpos])
  187. x = bpos*8 + bitptbl[(int)(*p& rightmask[sbitpos])];
  188. else {
  189. bpos++;
  190. x = bpos*8;
  191. for ( ; bpos < BMPTbl[BMPNo].bWid; bpos++, x+=8) {
  192. p++;
  193. if (*p) {
  194. x += bitptbl[(int)*p];
  195. break;
  196. }
  197. }
  198. }
  199. return( x);
  200. }
  201. /***********************************************************************
  202. * make outline data
  203. */
  204. /* */ static int
  205. /* */ outline(
  206. /* */ int BMPNo,
  207. /* */ int x,
  208. /* */ int y,
  209. /* */ int lsthdl,
  210. /* */ int wkBMP,
  211. /* */ int refBMP)
  212. /*
  213. * returns : 0, -1
  214. **********************************************************************/
  215. {
  216. int inout;
  217. struct vecdata vd;
  218. int sts;
  219. /* Check Inside/Outside */
  220. if ( rdot( refBMP, x, y) ==rdot( wkBMP, x, y)) /* OUTSIDE */
  221. inout = 0;
  222. else /* INSIDE */
  223. inout = 1;
  224. /* copy buffer */
  225. cpybuf( wkBMP, BMPNo);
  226. /* contribute */
  227. vd.x = (short)x;
  228. vd.y = (short)y;
  229. vd.atr = 0;
  230. if ( inout==0)
  231. sts = ContributeOutside( BMPNo, wkBMP, &vd, lsthdl);
  232. else
  233. sts = ContributeInside( BMPNo, wkBMP, &vd, lsthdl);
  234. return( sts);
  235. }
  236. /***********************************************************************
  237. * Contribute Outside Contour
  238. */
  239. /* */ static int
  240. /* */ ContributeOutside(int BMPNo, int wkBMP, struct vecdata *org, int lsthdl)
  241. /*
  242. * returns : 0, -1
  243. * Direction 2
  244. * |
  245. * |
  246. * 3-------+-------1
  247. * |
  248. * |
  249. * 0
  250. ***********************************************************************/
  251. {
  252. int orgx, orgy;
  253. struct vecdata vd;
  254. int dir;
  255. orgx = org->x;
  256. orgy = org->y;
  257. vd = *org;
  258. dir = 0;
  259. /*
  260. if (ReverseRight( wkBMP, vd.x, vd.y))
  261. return( -1);
  262. */
  263. do {
  264. if (VDSetData( lsthdl, &vd))
  265. return(-1);
  266. switch( dir) {
  267. case 0:
  268. if (ReverseRight( wkBMP, vd.x, vd.y))
  269. return( -1);
  270. vd.y++;
  271. if ( rdot( BMPNo, vd.x-1, vd.y))
  272. dir = 3;
  273. else if ( rdot( BMPNo, vd.x, vd.y))
  274. dir = 0;
  275. else dir = 1;
  276. break;
  277. case 1:
  278. vd.x++;
  279. if ( rdot( BMPNo, vd.x, vd.y))
  280. dir = 0;
  281. else if ( rdot( BMPNo, vd.x, vd.y-1))
  282. dir = 1;
  283. else dir = 2;
  284. break;
  285. case 2:
  286. vd.y--;
  287. if (ReverseRight( wkBMP, vd.x, vd.y))
  288. return( -1);
  289. if ( rdot( BMPNo, vd.x, vd.y-1))
  290. dir = 1;
  291. else if ( rdot( BMPNo, vd.x-1, vd.y-1))
  292. dir = 2;
  293. else dir = 3;
  294. break;
  295. case 3:
  296. vd.x--;
  297. if ( rdot( BMPNo, vd.x-1, vd.y-1))
  298. dir = 2;
  299. else if ( rdot( BMPNo, vd.x-1, vd.y))
  300. dir = 3;
  301. else dir = 0;
  302. break;
  303. }
  304. } while( vd.x!=orgx || vd.y != orgy);
  305. VDClose(lsthdl);
  306. return( 0);
  307. }
  308. /***********************************************************************
  309. * Contribute Outside Contour
  310. */
  311. /* */ static int
  312. /* */ ContributeInside( int BMPNo, int wkBMP, struct vecdata *org, int lsthdl)
  313. /*
  314. * returns : 0, -1
  315. ***********************************************************************/
  316. {
  317. int orgx, orgy;
  318. struct vecdata vd;
  319. int dir;
  320. orgx = org->x;
  321. orgy = org->y;
  322. vd = *org;
  323. dir = 1;
  324. do {
  325. if (VDSetData( lsthdl, &vd))
  326. return(-1);
  327. switch( dir) {
  328. case 0:
  329. if (ReverseRight( wkBMP, vd.x, vd.y))
  330. return( -1);
  331. vd.y++;
  332. if ( rdot( BMPNo, vd.x-1, vd.y)==0) /* right */
  333. dir = 3;
  334. else if ( rdot( BMPNo, vd.x, vd.y)==0) /* left */
  335. dir = 0;
  336. else dir = 1;
  337. break;
  338. case 1:
  339. vd.x++;
  340. if ( rdot( BMPNo, vd.x, vd.y)==0) /* right */
  341. dir = 0;
  342. else if ( rdot( BMPNo, vd.x, vd.y-1)==0) /* left */
  343. dir = 1;
  344. else dir = 2;
  345. break;
  346. case 2:
  347. vd.y--;
  348. if (ReverseRight( wkBMP, vd.x, vd.y))
  349. return( -1);
  350. if ( rdot( BMPNo, vd.x, vd.y-1)==0)
  351. dir = 1;
  352. else if ( rdot( BMPNo, vd.x-1, vd.y-1)==0)
  353. dir = 2;
  354. else dir = 3;
  355. break;
  356. case 3:
  357. vd.x--;
  358. if ( rdot( BMPNo, vd.x-1, vd.y-1)==0)
  359. dir = 2;
  360. else if ( rdot( BMPNo, vd.x-1, vd.y)==0)
  361. dir = 3;
  362. else dir = 0;
  363. break;
  364. }
  365. } while( vd.x!=orgx || vd.y != orgy);
  366. VDClose(lsthdl);
  367. return( 0);
  368. }
  369. /***********************************************************************
  370. * Read Dot
  371. */
  372. /* */ int
  373. /* */ rdot( int BMP, int x, int y)
  374. /*
  375. * returns : 0, nonzero
  376. ***********************************************************************/
  377. {
  378. unsigned char *radd;
  379. int rbit;
  380. int onoff;
  381. if ( x < 0 || y < 0 || x>=BMPTbl[BMP].width ||y>=BMPTbl[BMP].depth)
  382. return( 0);
  383. radd = BMPTbl[BMP].buf + BMPTbl[BMP].bWid*y + x/8;
  384. rbit = x % 8;
  385. onoff = (int)(wmaskB[rbit] & *radd);
  386. return onoff;
  387. }
  388. /***********************************************************************
  389. * Write Dot
  390. */
  391. /* */ void
  392. /* */ wdot( int BMP, int x, int y, int onoff)
  393. /*
  394. * returns : none
  395. ***********************************************************************/
  396. {
  397. unsigned char *radd;
  398. int rbit;
  399. if ( x < 0 || y < 0 || x>=BMPTbl[BMP].width ||y>=BMPTbl[BMP].depth)
  400. return;
  401. radd = BMPTbl[BMP].buf + BMPTbl[BMP].bWid*y + x/8;
  402. rbit = x % 8;
  403. if ( onoff) *radd |= wmaskB[rbit];
  404. else *radd &= ~wmaskB[rbit];
  405. return;
  406. }
  407. /***********************************************************************
  408. * Reverse right side ( Edge fill method)
  409. */
  410. /* */ int
  411. /* */ ReverseRight( int BMPNo, int x, int y)
  412. /*
  413. * returns : 0, -1
  414. ***********************************************************************/
  415. {
  416. int rb;
  417. int bitp;
  418. unsigned char *wp;
  419. if ( BMPNo < 0 || BMPNo >= BMPMAX)
  420. return 0;
  421. if ( x < 0 || x >= BMPTbl[BMPNo].width
  422. || y < 0 || y >= BMPTbl[BMPNo].depth)
  423. return 0;
  424. rb = BMPTbl[BMPNo].bWid - x/8 -1;
  425. bitp = x%8;
  426. wp = BMPTbl[BMPNo].buf + y*BMPTbl[BMPNo].bWid + x/8;
  427. /* First Byte */
  428. *wp ^= rightmask[bitp];
  429. /* to right limit */
  430. while( rb-->0) {
  431. wp++;
  432. *wp = (unsigned char)~(*wp);
  433. }
  434. return ( 0);
  435. }
  436. /***********************************************************************
  437. * Copy Buffer
  438. */
  439. /* */ static void
  440. /* */ cpybuf( int src, int dst)
  441. /*
  442. * returns : none
  443. ***********************************************************************/
  444. {
  445. int siz;
  446. if ( src < 0 || src >= BMPMAX)
  447. return;
  448. if ( dst < 0 || dst >= BMPMAX)
  449. return;
  450. siz = BMPTbl[src].bWid * BMPTbl[src].depth;
  451. memcpy( BMPTbl[dst].buf, BMPTbl[src].buf, siz);
  452. }
  453. /***********************************************************************
  454. * Reverse bitmap
  455. */
  456. /* */ int
  457. /* */ BMPReverse( int bmpNo)
  458. /*
  459. * returns : none
  460. ***********************************************************************/
  461. {
  462. int siz;
  463. char *buf;
  464. if ( bmpNo < 0 || bmpNo >= BMPMAX)
  465. return -1;
  466. else if (BMPTbl[bmpNo].buf==(unsigned char *)0)
  467. return -1;
  468. else {
  469. siz = BMPTbl[bmpNo].bWid * BMPTbl[bmpNo].depth;
  470. buf = (char *)BMPTbl[bmpNo].buf;
  471. while ( siz-->0) {
  472. *buf = (char)~*buf;
  473. buf++;
  474. }
  475. }
  476. return 0;
  477. }
  478. /***********************************************************************
  479. * Clear BMP
  480. */
  481. /* */ int
  482. /* */ BMPClear( int bmpNo)
  483. /*
  484. * returns : 0,-1
  485. ***********************************************************************/
  486. {
  487. int siz;
  488. if ( bmpNo < 0 || bmpNo >= BMPMAX)
  489. return -1;
  490. else if (BMPTbl[bmpNo].buf==(unsigned char *)0)
  491. return -1;
  492. siz = BMPTbl[bmpNo].bWid * BMPTbl[bmpNo].depth;
  493. memset( BMPTbl[bmpNo].buf, 0, siz);
  494. return 0;
  495. }
  496. /* EOF */