Leaked source code of windows server 2003
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.

747 lines
21 KiB

  1. /*----------------------------------------------------------------------+
  2. | invcmap.c - Microsoft Video 1 Compressor - Inverse Color Map. |
  3. | |
  4. | Copyright (c) 1990-1994 Microsoft Corporation. |
  5. | Portions Copyright Media Vision Inc. |
  6. | All Rights Reserved. |
  7. | |
  8. | You have a non-exclusive, worldwide, royalty-free, and perpetual |
  9. | license to use this source code in developing hardware, software |
  10. | (limited to drivers and other software required for hardware |
  11. | functionality), and firmware for video display and/or processing |
  12. | boards. Microsoft makes no warranties, express or implied, with |
  13. | respect to the Video 1 codec, including without limitation warranties |
  14. | of merchantability or fitness for a particular purpose. Microsoft |
  15. | shall not be liable for any damages whatsoever, including without |
  16. | limitation consequential damages arising from your use of the Video 1 |
  17. | codec. |
  18. | |
  19. | |
  20. +----------------------------------------------------------------------*/
  21. #include <math.h>
  22. #include <windows.h>
  23. #include <windowsx.h>
  24. #include <win32.h>
  25. //#pragma optimize("", off)
  26. int redloop(void);
  27. int greenloop( int restart );
  28. int blueloop( int restart );
  29. #ifdef _WIN32
  30. #define maxfill(pbuffer, side) \
  31. memset(pbuffer, -1, colormax*colormax*colormax*sizeof(LONG))
  32. #else
  33. void maxfill( DWORD _huge *buffer, long side);
  34. #endif
  35. void inv_cmap_2( int colors, BYTE colormap[3][256], int bits,
  36. DWORD _huge *dist_buf, LPBYTE rgbmap );
  37. void inv_cmap_1( int colors, BYTE colormap[3][256], int bits,
  38. DWORD _huge *dist_buf, LPBYTE rgbmap );
  39. /* Track minimum and maximum in inv_cmap_2. */
  40. #define MINMAX_TRACK
  41. BYTE NewMap[3][256];
  42. LPVOID FAR PASCAL MakeITable(LPRGBQUAD lprgbq, int nColors)
  43. {
  44. LPVOID lpDistBuf;
  45. LPBYTE lpITable;
  46. int i;
  47. lpITable = GlobalAllocPtr(GHND|GMEM_SHARE,32768l);
  48. if (lpITable == NULL)
  49. return NULL; // error no memory
  50. lpDistBuf = (LPVOID)GlobalAllocPtr(GHND,32768l * sizeof(DWORD));
  51. if (lpDistBuf == NULL) {
  52. GlobalFreePtr(lpITable);
  53. return NULL; // error no memory
  54. }
  55. for (i = 0; i < nColors; i++) {
  56. NewMap[0][i] = lprgbq[i].rgbRed;
  57. NewMap[1][i] = lprgbq[i].rgbGreen;
  58. NewMap[2][i] = lprgbq[i].rgbBlue;
  59. }
  60. inv_cmap_2(nColors,NewMap,5,lpDistBuf,lpITable);
  61. GlobalFreePtr(lpDistBuf);
  62. return lpITable;
  63. }
  64. static int bcenter, gcenter, rcenter;
  65. static long gdist, rdist, cdist;
  66. static long cbinc, cginc, crinc;
  67. static DWORD _huge *gdp;
  68. static DWORD _huge *rdp;
  69. static DWORD _huge *cdp;
  70. static LPBYTE grgbp;
  71. static LPBYTE rrgbp;
  72. static LPBYTE crgbp;
  73. static int gstride, rstride;
  74. static long x, xsqr, colormax;
  75. static int cindex;
  76. /*****************************************************************
  77. * TAG( inv_cmap_2 )
  78. *
  79. * Compute an inverse colormap efficiently.
  80. * Inputs:
  81. * colors: Number of colors in the forward colormap.
  82. * colormap: The forward colormap.
  83. * bits: Number of quantization bits. The inverse
  84. * colormap will have (2^bits)^3 entries.
  85. * dist_buf: An array of (2^bits)^3 long integers to be
  86. * used as scratch space.
  87. * Outputs:
  88. * rgbmap: The output inverse colormap. The entry
  89. * rgbmap[(r<<(2*bits)) + (g<<bits) + b]
  90. * is the colormap entry that is closest to the
  91. * (quantized) color (r,g,b).
  92. * Assumptions:
  93. * Quantization is performed by right shift (low order bits are
  94. * truncated). Thus, the distance to a quantized color is
  95. * actually measured to the color at the center of the cell
  96. * (i.e., to r+.5, g+.5, b+.5, if (r,g,b) is a quantized color).
  97. * Algorithm:
  98. * Uses a "distance buffer" algorithm:
  99. * The distance from each representative in the forward color map
  100. * to each point in the rgb space is computed. If it is less
  101. * than the distance currently stored in dist_buf, then the
  102. * corresponding entry in rgbmap is replaced with the current
  103. * representative (and the dist_buf entry is replaced with the
  104. * new distance).
  105. *
  106. * The distance computation uses an efficient incremental formulation.
  107. *
  108. * Distances are computed "outward" from each color. If the
  109. * colors are evenly distributed in color space, the expected
  110. * number of cells visited for color I is N^3/I.
  111. * Thus, the complexity of the algorithm is O(log(K) N^3),
  112. * where K = colors, and N = 2^bits.
  113. */
  114. /*
  115. * Here's the idea: scan from the "center" of each cell "out"
  116. * until we hit the "edge" of the cell -- that is, the point
  117. * at which some other color is closer -- and stop. In 1-D,
  118. * this is simple:
  119. * for i := here to max do
  120. * if closer then buffer[i] = this color
  121. * else break
  122. * repeat above loop with i := here-1 to min by -1
  123. *
  124. * In 2-D, it's trickier, because along a "scan-line", the
  125. * region might start "after" the "center" point. A picture
  126. * might clarify:
  127. * | ...
  128. * | ... .
  129. * ... .
  130. * ... | .
  131. * . + .
  132. * . .
  133. * . .
  134. * .........
  135. *
  136. * The + marks the "center" of the above region. On the top 2
  137. * lines, the region "begins" to the right of the "center".
  138. *
  139. * Thus, we need a loop like this:
  140. * detect := false
  141. * for i := here to max do
  142. * if closer then
  143. * buffer[..., i] := this color
  144. * if !detect then
  145. * here = i
  146. * detect = true
  147. * else
  148. * if detect then
  149. * break
  150. *
  151. * Repeat the above loop with i := here-1 to min by -1. Note that
  152. * the "detect" value should not be reinitialized. If it was
  153. * "true", and center is not inside the cell, then none of the
  154. * cell lies to the left and this loop should exit
  155. * immediately.
  156. *
  157. * The outer loops are similar, except that the "closer" test
  158. * is replaced by a call to the "next in" loop; its "detect"
  159. * value serves as the test. (No assignment to the buffer is
  160. * done, either.)
  161. *
  162. * Each time an outer loop starts, the "here", "min", and
  163. * "max" values of the next inner loop should be
  164. * re-initialized to the center of the cell, 0, and cube size,
  165. * respectively. Otherwise, these values will carry over from
  166. * one "call" to the inner loop to the next. This tracks the
  167. * edges of the cell and minimizes the number of
  168. * "unproductive" comparisons that must be made.
  169. *
  170. * Finally, the inner-most loop can have the "if !detect"
  171. * optimized out of it by splitting it into two loops: one
  172. * that finds the first color value on the scan line that is
  173. * in this cell, and a second that fills the cell until
  174. * another one is closer:
  175. * if !detect then {needed for "down" loop}
  176. * for i := here to max do
  177. * if closer then
  178. * buffer[..., i] := this color
  179. * detect := true
  180. * break
  181. * for i := i+1 to max do
  182. * if closer then
  183. * buffer[..., i] := this color
  184. * else
  185. * break
  186. *
  187. * In this implementation, each level will require the
  188. * following variables. Variables labelled (l) are local to each
  189. * procedure. The ? should be replaced with r, g, or b:
  190. * cdist: The distance at the starting point.
  191. * ?center: The value of this component of the color
  192. * c?inc: The initial increment at the ?center position.
  193. * ?stride: The amount to add to the buffer
  194. * pointers (dp and rgbp) to get to the
  195. * "next row".
  196. * min(l): The "low edge" of the cell, init to 0
  197. * max(l): The "high edge" of the cell, init to
  198. * colormax-1
  199. * detect(l): True if this row has changed some
  200. * buffer entries.
  201. * i(l): The index for this row.
  202. * ?xx: The accumulated increment value.
  203. *
  204. * here(l): The starting index for this color. The
  205. * following variables are associated with here,
  206. * in the sense that they must be updated if here
  207. * is changed.
  208. * ?dist: The current distance for this level. The
  209. * value of dist from the previous level (g or r,
  210. * for level b or g) initializes dist on this
  211. * level. Thus gdist is associated with here(b)).
  212. * ?inc: The initial increment for the row.
  213. * ?dp: Pointer into the distance buffer. The value
  214. * from the previous level initializes this level.
  215. * ?rgbp: Pointer into the rgb buffer. The value
  216. * from the previous level initializes this level.
  217. *
  218. * The blue and green levels modify 'here-associated' variables (dp,
  219. * rgbp, dist) on the green and red levels, respectively, when here is
  220. * changed.
  221. */
  222. void
  223. inv_cmap_2( int colors, BYTE colormap[3][256], int bits,
  224. DWORD _huge *dist_buf, LPBYTE rgbmap )
  225. {
  226. int nbits = 8 - bits;
  227. colormax = 1 << bits;
  228. x = 1 << nbits;
  229. xsqr = 1 << (2 * nbits);
  230. /* Compute "strides" for accessing the arrays. */
  231. gstride = (int) colormax;
  232. rstride = (int) (colormax * colormax);
  233. maxfill( dist_buf, colormax );
  234. for ( cindex = 0; cindex < colors; cindex++ )
  235. {
  236. /*
  237. * Distance formula is
  238. * (red - map[0])^2 + (green - map[1])^2 + (blue - map[2])^2
  239. *
  240. * Because of quantization, we will measure from the center of
  241. * each quantized "cube", so blue distance is
  242. * (blue + x/2 - map[2])^2,
  243. * where x = 2^(8 - bits).
  244. * The step size is x, so the blue increment is
  245. * 2*x*blue - 2*x*map[2] + 2*x^2
  246. *
  247. * Now, b in the code below is actually blue/x, so our
  248. * increment will be 2*(b*x^2 + x^2 - x*map[2]). For
  249. * efficiency, we will maintain this quantity in a separate variable
  250. * that will be updated incrementally by adding 2*x^2 each time.
  251. */
  252. /* The initial position is the cell containing the colormap
  253. * entry. We get this by quantizing the colormap values.
  254. */
  255. rcenter = colormap[0][cindex] >> nbits;
  256. gcenter = colormap[1][cindex] >> nbits;
  257. bcenter = colormap[2][cindex] >> nbits;
  258. rdist = colormap[0][cindex] - (rcenter * x + x/2);
  259. gdist = colormap[1][cindex] - (gcenter * x + x/2);
  260. cdist = colormap[2][cindex] - (bcenter * x + x/2);
  261. cdist = rdist*rdist + gdist*gdist + cdist*cdist;
  262. crinc = 2 * ((rcenter + 1) * xsqr - (colormap[0][cindex] * x));
  263. cginc = 2 * ((gcenter + 1) * xsqr - (colormap[1][cindex] * x));
  264. cbinc = 2 * ((bcenter + 1) * xsqr - (colormap[2][cindex] * x));
  265. /* Array starting points. */
  266. cdp = dist_buf + rcenter * rstride + gcenter * gstride + bcenter;
  267. crgbp = rgbmap + rcenter * rstride + gcenter * gstride + bcenter;
  268. (void)redloop();
  269. }
  270. }
  271. /* redloop -- loop up and down from red center. */
  272. int
  273. redloop()
  274. {
  275. int detect;
  276. int r, i = cindex;
  277. int first;
  278. long txsqr = xsqr + xsqr;
  279. static long rxx;
  280. detect = 0;
  281. /* Basic loop up. */
  282. for ( r = rcenter, rdist = cdist, rxx = crinc,
  283. rdp = cdp, rrgbp = crgbp, first = 1;
  284. r < (int) colormax;
  285. r++, rdp += rstride, rrgbp += rstride,
  286. rdist += rxx, rxx += txsqr, first = 0 )
  287. {
  288. if ( greenloop( first ) )
  289. detect = 1;
  290. else if ( detect )
  291. break;
  292. }
  293. /* Basic loop down. */
  294. for ( r = rcenter - 1, rxx = crinc - txsqr, rdist = cdist - rxx,
  295. rdp = cdp - rstride, rrgbp = crgbp - rstride, first = 1;
  296. r >= 0;
  297. r--, rdp -= rstride, rrgbp -= rstride,
  298. rxx -= txsqr, rdist -= rxx, first = 0 )
  299. {
  300. if ( greenloop( first ) )
  301. detect = 1;
  302. else if ( detect )
  303. break;
  304. }
  305. return detect;
  306. }
  307. /* greenloop -- loop up and down from green center. */
  308. int
  309. greenloop( int restart )
  310. {
  311. int detect;
  312. int g, i = cindex;
  313. int first;
  314. long txsqr = xsqr + xsqr;
  315. static int here, min, max;
  316. #ifdef MINMAX_TRACK
  317. static int prevmax, prevmin;
  318. int thismax, thismin;
  319. #endif
  320. static long ginc, gxx, gcdist; /* "gc" variables maintain correct */
  321. static DWORD _huge *gcdp; /* values for bcenter position, */
  322. static LPBYTE gcrgbp; /* despite modifications by blueloop */
  323. /* to gdist, gdp, grgbp. */
  324. if ( restart )
  325. {
  326. here = gcenter;
  327. min = 0;
  328. max = (int) colormax - 1;
  329. ginc = cginc;
  330. #ifdef MINMAX_TRACK
  331. prevmax = 0;
  332. prevmin = (int) colormax;
  333. #endif
  334. }
  335. #ifdef MINMAX_TRACK
  336. thismin = min;
  337. thismax = max;
  338. #endif
  339. detect = 0;
  340. /* Basic loop up. */
  341. for ( g = here, gcdist = gdist = rdist, gxx = ginc,
  342. gcdp = gdp = rdp, gcrgbp = grgbp = rrgbp, first = 1;
  343. g <= max;
  344. g++, gdp += gstride, gcdp += gstride, grgbp += gstride, gcrgbp += gstride,
  345. gdist += gxx, gcdist += gxx, gxx += txsqr, first = 0 )
  346. {
  347. if ( blueloop( first ) )
  348. {
  349. if ( !detect )
  350. {
  351. /* Remember here and associated data! */
  352. if ( g > here )
  353. {
  354. here = g;
  355. rdp = gcdp;
  356. rrgbp = gcrgbp;
  357. rdist = gcdist;
  358. ginc = gxx;
  359. #ifdef MINMAX_TRACK
  360. thismin = here;
  361. #endif
  362. }
  363. detect = 1;
  364. }
  365. }
  366. else if ( detect )
  367. {
  368. #ifdef MINMAX_TRACK
  369. thismax = g - 1;
  370. #endif
  371. break;
  372. }
  373. }
  374. /* Basic loop down. */
  375. for ( g = here - 1, gxx = ginc - txsqr, gcdist = gdist = rdist - gxx,
  376. gcdp = gdp = rdp - gstride, gcrgbp = grgbp = rrgbp - gstride,
  377. first = 1;
  378. g >= min;
  379. g--, gdp -= gstride, gcdp -= gstride, grgbp -= gstride, gcrgbp -= gstride,
  380. gxx -= txsqr, gdist -= gxx, gcdist -= gxx, first = 0 )
  381. {
  382. if ( blueloop( first ) )
  383. {
  384. if ( !detect )
  385. {
  386. /* Remember here! */
  387. here = g;
  388. rdp = gcdp;
  389. rrgbp = gcrgbp;
  390. rdist = gcdist;
  391. ginc = gxx;
  392. #ifdef MINMAX_TRACK
  393. thismax = here;
  394. #endif
  395. detect = 1;
  396. }
  397. }
  398. else if ( detect )
  399. {
  400. #ifdef MINMAX_TRACK
  401. thismin = g + 1;
  402. #endif
  403. break;
  404. }
  405. }
  406. #ifdef MINMAX_TRACK
  407. /* If we saw something, update the edge trackers. For now, only
  408. * tracks edges that are "shrinking" (min increasing, max
  409. * decreasing.
  410. */
  411. if ( detect )
  412. {
  413. if ( thismax < prevmax )
  414. max = thismax;
  415. prevmax = thismax;
  416. if ( thismin > prevmin )
  417. min = thismin;
  418. prevmin = thismin;
  419. }
  420. #endif
  421. return detect;
  422. }
  423. /* blueloop -- loop up and down from blue center. */
  424. int
  425. blueloop( int restart )
  426. {
  427. int detect;
  428. register DWORD _huge *dp;
  429. register LPBYTE rgbp;
  430. register long bdist, bxx;
  431. register int b, i = cindex;
  432. register long txsqr = xsqr + xsqr;
  433. register int lim;
  434. static int here, min, max;
  435. #ifdef MINMAX_TRACK
  436. static int prevmin, prevmax;
  437. int thismin, thismax;
  438. #endif /* MINMAX_TRACK */
  439. static long binc;
  440. if ( restart )
  441. {
  442. here = bcenter;
  443. min = 0;
  444. max = (int) colormax - 1;
  445. binc = cbinc;
  446. #ifdef MINMAX_TRACK
  447. prevmin = (int) colormax;
  448. prevmax = 0;
  449. #endif /* MINMAX_TRACK */
  450. }
  451. detect = 0;
  452. #ifdef MINMAX_TRACK
  453. thismin = min;
  454. thismax = max;
  455. #endif
  456. /* Basic loop up. */
  457. /* First loop just finds first applicable cell. */
  458. for ( b = here, bdist = gdist, bxx = binc, dp = gdp, rgbp = grgbp, lim = max;
  459. b <= lim;
  460. b++, dp++, rgbp++,
  461. bdist += bxx, bxx += txsqr )
  462. {
  463. if ( *dp > (DWORD)bdist )
  464. {
  465. /* Remember new 'here' and associated data! */
  466. if ( b > here )
  467. {
  468. here = b;
  469. gdp = dp;
  470. grgbp = rgbp;
  471. gdist = bdist;
  472. binc = bxx;
  473. #ifdef MINMAX_TRACK
  474. thismin = here;
  475. #endif
  476. }
  477. detect = 1;
  478. break;
  479. }
  480. }
  481. /* Second loop fills in a run of closer cells. */
  482. for ( ;
  483. b <= lim;
  484. b++, dp++, rgbp++,
  485. bdist += bxx, bxx += txsqr )
  486. {
  487. if ( *dp > (DWORD)bdist )
  488. {
  489. *dp = bdist;
  490. *rgbp = (BYTE) i;
  491. }
  492. else
  493. {
  494. #ifdef MINMAX_TRACK
  495. thismax = b - 1;
  496. #endif
  497. break;
  498. }
  499. }
  500. /* Basic loop down. */
  501. /* Do initializations here, since the 'find' loop might not get
  502. * executed.
  503. */
  504. lim = min;
  505. b = here - 1;
  506. bxx = binc - txsqr;
  507. bdist = gdist - bxx;
  508. dp = gdp - 1;
  509. rgbp = grgbp - 1;
  510. /* The 'find' loop is executed only if we didn't already find
  511. * something.
  512. */
  513. if ( !detect )
  514. for ( ;
  515. b >= lim;
  516. b--, dp--, rgbp--,
  517. bxx -= txsqr, bdist -= bxx )
  518. {
  519. if ( *dp > (DWORD)bdist )
  520. {
  521. /* Remember here! */
  522. /* No test for b against here necessary because b <
  523. * here by definition.
  524. */
  525. here = b;
  526. gdp = dp;
  527. grgbp = rgbp;
  528. gdist = bdist;
  529. binc = bxx;
  530. #ifdef MINMAX_TRACK
  531. thismax = here;
  532. #endif
  533. detect = 1;
  534. break;
  535. }
  536. }
  537. /* The 'update' loop. */
  538. for ( ;
  539. b >= lim;
  540. b--, dp--, rgbp--,
  541. bxx -= txsqr, bdist -= bxx )
  542. {
  543. if ( *dp > (DWORD)bdist )
  544. {
  545. *dp = bdist;
  546. *rgbp = (BYTE) i;
  547. }
  548. else
  549. {
  550. #ifdef MINMAX_TRACK
  551. thismin = b + 1;
  552. #endif
  553. break;
  554. }
  555. }
  556. /* If we saw something, update the edge trackers. */
  557. #ifdef MINMAX_TRACK
  558. if ( detect )
  559. {
  560. /* Only tracks edges that are "shrinking" (min increasing, max
  561. * decreasing.
  562. */
  563. if ( thismax < prevmax )
  564. max = thismax;
  565. if ( thismin > prevmin )
  566. min = thismin;
  567. /* Remember the min and max values. */
  568. prevmax = thismax;
  569. prevmin = thismin;
  570. }
  571. #endif /* MINMAX_TRACK */
  572. return detect;
  573. }
  574. #ifndef _WIN32
  575. void maxfill( DWORD _huge *buffer, long side)
  576. {
  577. register unsigned long maxv = ~0uL;
  578. register long i;
  579. register DWORD _huge *bp;
  580. for ( i = colormax * colormax * colormax, bp = buffer;
  581. i > 0;
  582. i--, bp++ )
  583. *bp = maxv;
  584. }
  585. #endif
  586. #ifdef CMAP1
  587. /*****************************************************************
  588. * TAG( inv_cmap_1 )
  589. *
  590. * Compute an inverse colormap efficiently.
  591. * Inputs:
  592. * colors: Number of colors in the forward colormap.
  593. * colormap: The forward colormap.
  594. * bits: Number of quantization bits. The inverse
  595. * colormap will have (2^bits)^3 entries.
  596. * dist_buf: An array of (2^bits)^3 long integers to be
  597. * used as scratch space.
  598. * Outputs:
  599. * rgbmap: The output inverse colormap. The entry
  600. * rgbmap[(r<<(2*bits)) + (g<<bits) + b]
  601. * is the colormap entry that is closest to the
  602. * (quantized) color (r,g,b).
  603. * Assumptions:
  604. * Quantization is performed by right shift (low order bits are
  605. * truncated). Thus, the distance to a quantized color is
  606. * actually measured to the color at the center of the cell
  607. * (i.e., to r+.5, g+.5, b+.5, if (r,g,b) is a quantized color).
  608. * Algorithm:
  609. * Uses a "distance buffer" algorithm:
  610. * The distance from each representative in the forward color map
  611. * to each point in the rgb space is computed. If it is less
  612. * than the distance currently stored in dist_buf, then the
  613. * corresponding entry in rgbmap is replaced with the current
  614. * representative (and the dist_buf entry is replaced with the
  615. * new distance).
  616. *
  617. * The distance computation uses an efficient incremental formulation.
  618. *
  619. * Right now, distances are computed for all entries in the rgb
  620. * space. Thus, the complexity of the algorithm is O(K N^3),
  621. * where K = colors, and N = 2^bits.
  622. */
  623. void
  624. inv_cmap_1( int colors, BYTE colormap[3][256], int bits,
  625. DWORD _huge *dist_buf, LPBYTE rgbmap )
  626. {
  627. register DWORD _huge *dp;
  628. register LPBYTE rgbp;
  629. register long bdist, bxx;
  630. register int b, i;
  631. int nbits = 8 - bits;
  632. register int colormax = 1 << bits;
  633. register long xsqr = 1 << (2 * nbits);
  634. int x = 1 << nbits;
  635. int rinc, ginc, binc, r, g;
  636. long rdist, gdist, rxx, gxx;
  637. for ( i = 0; i < colors; i++ )
  638. {
  639. /*
  640. * Distance formula is
  641. * (red - map[0])^2 + (green - map[1])^2 + (blue - map[2])^2
  642. *
  643. * Because of quantization, we will measure from the center of
  644. * each quantized "cube", so blue distance is
  645. * (blue + x/2 - map[2])^2,
  646. * where x = 2^(8 - bits).
  647. * The step size is x, so the blue increment is
  648. * 2*x*blue - 2*x*map[2] + 2*x^2
  649. *
  650. * Now, b in the code below is actually blue/x, so our
  651. * increment will be 2*x*x*b + (2*x^2 - 2*x*map[2]). For
  652. * efficiency, we will maintain this quantity in a separate variable
  653. * that will be updated incrementally by adding 2*x^2 each time.
  654. */
  655. rdist = colormap[0][i] - x/2;
  656. gdist = colormap[1][i] - x/2;
  657. bdist = colormap[2][i] - x/2;
  658. rdist = rdist*rdist + gdist*gdist + bdist*bdist;
  659. rinc = 2 * (xsqr - (colormap[0][i] << nbits));
  660. ginc = 2 * (xsqr - (colormap[1][i] << nbits));
  661. binc = 2 * (xsqr - (colormap[2][i] << nbits));
  662. dp = dist_buf;
  663. rgbp = rgbmap;
  664. for ( r = 0, rxx = rinc;
  665. r < colormax;
  666. rdist += rxx, r++, rxx += xsqr + xsqr )
  667. for ( g = 0, gdist = rdist, gxx = ginc;
  668. g < colormax;
  669. gdist += gxx, g++, gxx += xsqr + xsqr )
  670. for ( b = 0, bdist = gdist, bxx = binc;
  671. b < colormax;
  672. bdist += bxx, b++, dp++, rgbp++,
  673. bxx += xsqr + xsqr )
  674. {
  675. if ( i == 0 || *dp > bdist )
  676. {
  677. *dp = bdist;
  678. *rgbp = i;
  679. }
  680. }
  681. }
  682. }
  683. #endif
  684.