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.

2110 lines
58 KiB

  1. /*
  2. * Microsoft YUV Codec -yuv411 -> rgb conversion functions
  3. *
  4. * Copyright (c) Microsoft Corporation 1993
  5. * All Rights Reserved
  6. *
  7. */
  8. /*
  9. * for TOSHIBA Pistachio yuv12 -> rgb conversion functions
  10. *
  11. * Programed by Y.Kasai 05/27/97
  12. *
  13. * supported type:
  14. * YUV411 (for Bravado)
  15. * YUV422 (for Spigot)
  16. * YUV12 (for Pistachio)
  17. * YUV9 (for Pistachio)
  18. */
  19. #include <windows.h>
  20. #include <windowsx.h>
  21. #include "msyuv.h"
  22. /*
  23. * This module provides translation from YUV into RGB. It translates
  24. * from 8-bit YUV 4:2:2 (as provided by the Spigot video capture driver)
  25. * or 7-bit YUV 4:1:1 (as provided by the Bravado driver) into 16-bit RGB555
  26. * or RGB565. All versions use a look-up table built using YUVToRGB555
  27. * or YUVToRGB565
  28. */
  29. #define RANGE(x, lo, hi) max(lo, min(hi, x))
  30. /*
  31. * Convert a YUV colour into a 15-bit RGB colour.
  32. *
  33. * The input Y is in the range 16..235; the input U and V components
  34. * are in the range -128..+127. The conversion equations for this are
  35. * (according to CCIR 601):
  36. *
  37. * R = Y + 1.371 V
  38. * G = Y - 0.698 V - 0.336 U
  39. * B = Y + 1.732 U
  40. *
  41. * To avoid floating point, we scale all values by 1024.
  42. *
  43. * The resulting RGB values are in the range 16..235: we truncate these to
  44. * 5 bits each. and return a WORD containing 5-bits each for R, G and B
  45. * with bit 15 set to 0.
  46. */
  47. WORD
  48. YUVToRGB555(int y, int u, int v)
  49. {
  50. int ScaledY = RANGE(y, 16, 235) * 1024;
  51. int red, green, blue;
  52. red = RANGE((ScaledY + (1404 * v)) / 1024, 0, 255);
  53. green = RANGE( (ScaledY - (715 * v) - (344 * u)) / 1024, 0, 255);
  54. blue = RANGE( (ScaledY + (1774 * u)) / 1024, 0, 255);
  55. return (WORD) (((red & 0xf8) << 7) | ((green & 0xf8) << 2) | ((blue & 0xf8) >>3) );
  56. }
  57. // same as above but converts to RGB565 instead
  58. WORD
  59. YUVToRGB565(int y, int u, int v)
  60. {
  61. int ScaledY = RANGE(y, 16, 235) * 1024;
  62. int red, green, blue;
  63. red = RANGE((ScaledY + (1404 * v)) / 1024, 0, 255);
  64. green = RANGE( (ScaledY - (715 * v) - (344 * u)) / 1024, 0, 255);
  65. blue = RANGE( (ScaledY + (1774 * u)) / 1024, 0, 255);
  66. return (WORD) (((red & 0xf8) << 8) | ((green & 0xfc) << 3) | ((blue & 0xf8) >>3) );
  67. }
  68. #ifdef TOSHIBA
  69. #ifdef COLOR_MODIFY
  70. /*
  71. * TOSHIBA Y.Kasai
  72. * for Pistachio.
  73. *
  74. * Convert a YUV colour into a 15-bit RGB colour.
  75. *
  76. * The input Y is in the range 0..255; the input U and V components
  77. * are in the same range 0..255. The conversion equations for this are
  78. * (according to CCIR 601):
  79. *
  80. * R = 1.1644Y + 1.5976 V - 223.0089
  81. * G = 1.1644Y - 0.8133 V - 0.3921 U + 135.6523
  82. * B = 1.1644Y + 2.0184 U - 276.9814
  83. *
  84. * To avoid floating point, we scale all values by 1024.
  85. *
  86. * 1024R = 1192Y + 1635V - 228361
  87. * 1024G = 1192Y - 833V - 402U + 138908
  88. * 1024B = 1192Y + 2067U - 283629
  89. *
  90. */
  91. BYTE
  92. TosYVToR(int y, int v)
  93. {
  94. int ScaledY = y * 1192;
  95. int red;
  96. red = RANGE((ScaledY + (1635 * v) - 228361) / 1024, 0, 255);
  97. return (BYTE) (red);
  98. }
  99. BYTE
  100. TosYUToB(int y, int u)
  101. {
  102. int ScaledY = y * 1192;
  103. int blue;
  104. blue = RANGE( (ScaledY + (2067 * u) - 283629) / 1024, 0, 255);
  105. return (BYTE) (blue);
  106. }
  107. #else //COLOR_MODIFY
  108. /*
  109. * TOSHIBA Y.Kasai
  110. * for Pistachio.
  111. *
  112. * Convert a YUV colour into a 15-bit RGB colour.
  113. *
  114. * The input Y is in the range 0..255; the input U and V components
  115. * are in the same range 0..255. The conversion equations for this are
  116. * (according to CCIR 601):
  117. *
  118. * R = 1.1644Y + 1.5976 V - 223.0089
  119. * G = 1.1644Y - 0.8133 V - 0.3921 U + 135.6523
  120. * B = 1.1644Y + 2.0184 U - 276.9814
  121. *
  122. * To avoid floating point, we scale all values by 1024.
  123. *
  124. * 1024R = 1192Y + 1635V - 228361
  125. * 1024G = 1192Y - 833V - 402U + 138908
  126. * 1024B = 1192Y + 2067U - 283629
  127. *
  128. * The resulting RGB values are in the range 0..255: we truncate these to
  129. * 5 bits each. and return a WORD containing 5-bits each for R, G and B
  130. * with bit 15 set to 0.
  131. */
  132. WORD
  133. TosYUVToRGB555(int y, int u, int v)
  134. {
  135. int ScaledY = y * 1192;
  136. int red, green, blue;
  137. red = RANGE((ScaledY + (1635 * v) - 228361) / 1024, 0, 255);
  138. green = RANGE( (ScaledY - (833 * v) - (402 * u) + 138908) / 1024, 0, 255);
  139. blue = RANGE( (ScaledY + (2067 * u) - 283629) / 1024, 0, 255);
  140. return (WORD) (((red & 0xf8) << 7) | ((green & 0xf8) << 2) | ((blue & 0xf8) >>3) );
  141. }
  142. // same as above but converts to RGB565 instead
  143. WORD
  144. TosYUVToRGB565(int y, int u, int v)
  145. {
  146. int ScaledY = y * 1192;
  147. int red, green, blue;
  148. red = RANGE((ScaledY + (1635 * v) - 228361) / 1024, 0, 255);
  149. green = RANGE( (ScaledY - (833 * v) - (402 * u) + 138908) / 1024, 0, 255);
  150. blue = RANGE( (ScaledY + (2067 * u) - 283629) / 1024, 0, 255);
  151. return (WORD) (((red & 0xf8) << 8) | ((green & 0xfc) << 3) | ((blue & 0xf8) >>3) );
  152. }
  153. #endif//COLOR_MODIFY
  154. #endif//TOSHIBA
  155. /* --- YUV 4:1:1 support ------------------------------------------ */
  156. /*
  157. * the input data is in YUV411 format. There is one 7 bit Luma sample
  158. * per pixel, and 1 each 7-bit U and V sample averaged over 4 pixels,
  159. * in the following layout:
  160. *
  161. * 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
  162. * Word 0 u6 u5 v6 v5 y6 y5 y4 y3 y2 y1 y0
  163. *
  164. * Word 1 u4 u3 v4 v3 y6 y5 y4 y3 y2 y1 y0
  165. *
  166. * Word 2 u2 u1 v2 v1 y6 y5 y4 y3 y2 y1 y0
  167. *
  168. * Word 3 u0 v0 y6 y5 y4 y3 y2 y1 y0
  169. *
  170. * The 7-bit y values are unsigned (0..127), whereas the 7-bit
  171. * u and V values are signed (-64..+63).
  172. *
  173. *
  174. * For RGB: we truncate the YUV into a 15-bit format and use a prepared
  175. * lookup table to convert the 15-bit YUV into a 15- or 16-bit RGB value.
  176. *
  177. * The (64 kbyte) rgb555 lookup table is built by BuildYUVToRGB555.
  178. *
  179. */
  180. /*
  181. * the YUV xlate tables use 5-bits per component with y in the ms bits, and
  182. * v in the ls bits. To convert from the above layout, look up the nibbles
  183. * containing the chroma bits in these tables and or together the result to
  184. * get a word with a 5-bit V component in bits 0..4, and a 5-bit
  185. * U component in bits 5..9. Note you only need three lookups since
  186. * we discard chroma bits 0 and 1.
  187. */
  188. WORD ChromaBits65[] = {
  189. 0x000, 0x008, 0x010, 0x018,
  190. 0x100, 0x108, 0x110, 0x118,
  191. 0x200, 0x208, 0x210, 0x218,
  192. 0x300, 0x308, 0x310, 0x318
  193. };
  194. WORD ChromaBits43[] = {
  195. 0x000, 0x002, 0x004, 0x006,
  196. 0x040, 0x042, 0x044, 0x046,
  197. 0x080, 0x082, 0x084, 0x086,
  198. 0x0c0, 0x0c2, 0x0c4, 0x0c6
  199. };
  200. WORD ChromaBits2[] = {
  201. 0x000, 0x000, 0x001, 0x001,
  202. 0x000, 0x000, 0x001, 0x001,
  203. 0x020, 0x020, 0x021, 0x021,
  204. 0x020, 0x020, 0x021, 0x021
  205. };
  206. /*
  207. * build yuv411->RGB555 xlate table
  208. */
  209. LPVOID BuildYUVToRGB555(PINSTINFO pinst)
  210. {
  211. HGLOBAL hMem = NULL;
  212. LPVOID pXlate = NULL;
  213. if (pinst->pXlate != NULL) {
  214. return(pinst->pXlate);
  215. }
  216. /*
  217. * allocate a table big enough for 32k 2-byte entries
  218. */
  219. if ( ( hMem = GlobalAlloc(GPTR, 2 * 32 * 1024))
  220. && ( pXlate = GlobalLock( hMem ) ) )
  221. {
  222. WORD w;
  223. LPWORD pRGB555 = (LPWORD)pXlate;
  224. /*
  225. * build a 15-bit yuv lookup table by stepping through each entry,
  226. * converting the yuv index to rgb and storing at that index. The index
  227. * to this table is a 15-bit value with the y component in bits 14..10,
  228. * u in bits 9..5 and v in bits 4..0. Note that the y component is unsigned,
  229. * whereas the u and v components are signed.
  230. */
  231. for (w = 0; w < 32*1024; w++) {
  232. /*
  233. * the YUVtoRGB55 conversion function takes values 0..255 for y,
  234. * and -128..+127 for u and v. Pick out the relevant bits of the
  235. * index for this cell, and shift to get values in this range.
  236. * Remember the cast to ensure sign-extension of these (8-bit) values -
  237. * and don't assume that chars are signed (they're not on MIPS).
  238. */
  239. *pRGB555++ = YUVToRGB555(
  240. (w & 0x7c00) >> 7,
  241. (signed char) ((w & 0x3e0) >> 2),
  242. (signed char) ((w & 0x1f) << 3)
  243. );
  244. }
  245. }
  246. return(pXlate);
  247. }
  248. /*
  249. * build yuv411->RGB565 xlate table
  250. */
  251. LPVOID BuildYUVToRGB565(PINSTINFO pinst)
  252. {
  253. HGLOBAL hMem = 0;
  254. LPVOID pXlate = NULL;
  255. if (pinst->pXlate != NULL) {
  256. return(pinst->pXlate);
  257. }
  258. /*
  259. * allocate a table big enough for 32k 2-byte entries
  260. */
  261. if ( ( hMem = GlobalAlloc(GPTR, 2 * 32 * 1024))
  262. && ( pXlate = GlobalLock( hMem ) ) )
  263. {
  264. WORD w;
  265. LPWORD pRGB = (LPWORD)pXlate;
  266. /*
  267. * build a 15-bit yuv lookup table by stepping through each entry,
  268. * converting the yuv index to rgb and storing at that index. The index
  269. * to this table is a 15-bit value with the y component in bits 14..10,
  270. * u in bits 9..5 and v in bits 4..0. Note that the y component is unsigned,
  271. * whereas the u and v components are signed.
  272. */
  273. for (w = 0; w < 32*1024; w++) {
  274. /*
  275. * the YUVtoRGB conversion function takes values 0..255 for y,
  276. * and -128..+127 for u and v. Pick out the relevant bits of the
  277. * index for this cell, and shift to get values in this range.
  278. * Remember the cast to ensure sign-extension of these (8-bit) values -
  279. * and don't assume that chars are signed (they're not on MIPS).
  280. */
  281. *pRGB++ = YUVToRGB565(
  282. (w & 0x7c00) >> 7,
  283. (signed char) ((w & 0x3e0) >> 2),
  284. (signed char) ((w & 0x1f) << 3)
  285. );
  286. }
  287. }
  288. return(pXlate);
  289. }
  290. /*
  291. * translate one frame from yuv411 to 15/16 bit rgb.
  292. *
  293. * The YUV data is spread over 4 16-bit pixels in the format described
  294. * above. Pick out 4 pixels at a time, truncate them to 15-bit yuv,
  295. * lookup to translate to 15 or 16-bit rgb (depending on the lookup table
  296. * and write out.
  297. *
  298. * Flip vertically into correct dib format during conversion.
  299. */
  300. VOID
  301. YUV411ToRGB(
  302. PINSTINFO pinst,
  303. LPBITMAPINFOHEADER lpbiInput,
  304. LPVOID lpInput,
  305. LPBITMAPINFOHEADER lpbiOutput,
  306. LPVOID lpOutput
  307. )
  308. {
  309. int RowInc;
  310. int i, j;
  311. DWORD Luma01, Luma23;
  312. DWORD Chroma;
  313. int Height, Width;
  314. int WidthBytes;
  315. PWORD pXlate;
  316. PWORD pDst;
  317. PDWORD pSrc;
  318. Height = lpbiInput->biHeight;
  319. Width = lpbiInput->biWidth;
  320. WidthBytes = Width*2; // size of (input and output) line
  321. pXlate = pinst->pXlate;
  322. /*
  323. * adjust the source to point to the start of the last line,
  324. * and work upwards (to flip vertically into DIB format)
  325. */
  326. pSrc = (PDWORD) ( (PUCHAR) lpInput + ((Height - 1) * WidthBytes));
  327. pDst = (PWORD) lpOutput;
  328. /*
  329. * calculate the amount to adjust source by at the end of one line
  330. * of copying. At this point we are at the end of line N. We need
  331. * to move to the start of line N-1.
  332. */
  333. RowInc = (WidthBytes * 2) / sizeof(DWORD);
  334. /* loop copying each scanline */
  335. for (i = 0; i < Height; i++) {
  336. /* loop copying four pixels at a time */
  337. for (j = 0; j < Width; j += 4) {
  338. /*
  339. * get four pixels and convert to 15-bpp YUV
  340. */
  341. /* get luma for first 2 pixels + higher chroma bits */
  342. Luma01 = *pSrc++;
  343. /* pick out u,v components using lookup table.
  344. * u and v will be the bottom 10 bits of each pixel, so
  345. * convert to this layout
  346. */
  347. Chroma = ChromaBits65[(Luma01 >> 12) & 0xf] |
  348. ChromaBits43[ (Luma01 >> 28) & 0xf ];
  349. /* next two pixels + lower chroma bits */
  350. Luma23 = *pSrc++;
  351. /* pickup u and v bits 2 - ignore bits 1, 0 since
  352. * we only use 5-bits per component for conversion
  353. */
  354. Chroma |= ChromaBits2[ ( Luma23 >> 12) & 0xf];
  355. /*
  356. * combine luma for pix 0 with common chroma bits to
  357. * get 15-bit yuv, then lookup to convert to
  358. * rgb and store.
  359. */
  360. *pDst++ = pXlate[ ((Luma01 & 0xf8) << 7) | Chroma];
  361. *pDst++ = pXlate[ ((Luma01 & 0xf80000) >> 9) | Chroma];
  362. *pDst++ = pXlate[ ((Luma23 & 0xf8) << 7) | Chroma];
  363. *pDst++ = pXlate[ ((Luma23 & 0xf80000) >> 9) | Chroma];
  364. } // loop per 4 pixels
  365. /* move source pointer back to next line */
  366. pSrc -= RowInc;
  367. } // loop per row
  368. }
  369. /* YUV 4:2:2 support ------------------------------------------ */
  370. /*
  371. * The captured data is in YUV 4:2:2, 8-bits per sample.
  372. * The data is laid out in alternating Y-U-Y-V-Y-U-Y-V format. Thus
  373. * every DWORD contains two complete pixels, in the
  374. * form (msb..lsb) V..Y1..U..Y0
  375. * All 3 components (y, u and v) are all unsigned 8-bit values in the range
  376. * 16..235.
  377. *
  378. * We have to double scan lines for >= 480 line formats since
  379. * the hardware only captured one field maximum.
  380. *
  381. */
  382. /*
  383. * build a translation table to translate between YUV and RGB555.
  384. *
  385. * This builds a lookup table with 32k 1-word entries: truncate the YUV
  386. * to 15bits (5-5-5) and look-up in this xlate table to produce the
  387. * 15-bit rgb value.
  388. */
  389. LPVOID BuildYUV422ToRGB555(PINSTINFO pinst)
  390. {
  391. HGLOBAL hMem = 0;
  392. LPVOID pXlate = NULL;
  393. if (pinst->pXlate != NULL) {
  394. return(pinst->pXlate);
  395. }
  396. /*
  397. * allocate a table big enough for 32k 2-byte entries
  398. */
  399. if ( ( hMem = GlobalAlloc(GPTR, 2 * 32 * 1024))
  400. && ( pXlate = GlobalLock( hMem ) ) )
  401. {
  402. WORD w;
  403. LPWORD pRGB555 = (LPWORD)pXlate;
  404. /*
  405. * build a 15-bit yuv lookup table by stepping through each entry,
  406. * converting the yuv index to rgb and storing at that index. The index
  407. * to this table is a 15-bit value with the y component in bits 14..10,
  408. * u in bits 9..5 and v in bits 4..0. Note that the y component is unsigned,
  409. * whereas the u and v components are signed.
  410. */
  411. for (w = 0; w < 32*1024; w++) {
  412. /*
  413. * the YUVtoRGB55 conversion function takes values 0..255 for y,
  414. * and -128..+127 for u and v. Pick out the relevant bits of the
  415. * index for this cell, and shift to get values in this range.
  416. * Subtract 128 from u and v to shift from 0..255 to -128..+127
  417. */
  418. *pRGB555++ = YUVToRGB555(
  419. (w & 0x7c00) >> 7,
  420. ((w & 0x3e0) >> 2) - 128,
  421. ((w & 0x1f) << 3) - 128
  422. );
  423. }
  424. }
  425. return(pXlate);
  426. }
  427. /*
  428. * build a translation table to translate between YUV and RGB 5-6-5
  429. *
  430. * This builds a lookup table with 32k 1-word entries: truncate the YUV
  431. * to 15bits (5-5-5) and look-up in this xlate table to produce the
  432. * 16-bit rgb value.
  433. */
  434. LPVOID BuildYUV422ToRGB565(PINSTINFO pinst)
  435. {
  436. HGLOBAL hMem = 0;
  437. LPVOID pXlate = NULL;
  438. if (pinst->pXlate != NULL) {
  439. return(pinst->pXlate);
  440. }
  441. /*
  442. * allocate a table big enough for 32k 2-byte entries
  443. */
  444. if ( ( hMem = GlobalAlloc(GPTR, 2 * 32 * 1024))
  445. && ( pXlate = GlobalLock( hMem ) ) )
  446. {
  447. WORD w;
  448. LPWORD pRGB = (LPWORD)pXlate;
  449. /*
  450. * build a 15-bit yuv lookup table by stepping through each entry,
  451. * converting the yuv index to rgb and storing at that index. The index
  452. * to this table is a 15-bit value with the y component in bits 14..10,
  453. * u in bits 9..5 and v in bits 4..0. Note that the y component is unsigned,
  454. * whereas the u and v components are signed.
  455. */
  456. for (w = 0; w < 32*1024; w++) {
  457. /*
  458. * the YUVtoRGB conversion function takes values 0..255 for y,
  459. * and -128..+127 for u and v. Pick out the relevant bits of the
  460. * index for this cell, and shift to get values in this range.
  461. * Subtract 128 from u and v to shift from 0..255 to -128..+127
  462. */
  463. *pRGB++ = YUVToRGB565(
  464. (w & 0x7c00) >> 7,
  465. ((w & 0x3e0) >> 2) - 128,
  466. ((w & 0x1f) << 3) - 128
  467. );
  468. }
  469. }
  470. return(pXlate);
  471. }
  472. /*
  473. * translate YUV 4:2:2 into 16-bit RGB using a lookup table. Flip vertically
  474. * into DIB format during processing. Double scanlines for formats of
  475. * 480 lines or greater. Produces 565 or 555 format RGB depending on the
  476. * xlate table.
  477. */
  478. VOID
  479. YUV422ToRGB(
  480. PINSTINFO pinst,
  481. LPBITMAPINFOHEADER lpbiInput,
  482. LPVOID lpInput,
  483. LPBITMAPINFOHEADER lpbiOutput,
  484. LPVOID lpOutput
  485. )
  486. {
  487. int RowInc;
  488. int i, j;
  489. DWORD uv55, dwPixel;
  490. int WidthBytes; // width of one line in BYTES
  491. BOOL bDuplicate = FALSE;
  492. PDWORD pSrc, pDst;
  493. int Height, Width;
  494. PWORD pXlate;
  495. int InputHeight;
  496. Height = lpbiInput->biHeight;
  497. InputHeight = Height;
  498. Width = lpbiInput->biWidth;
  499. WidthBytes = Width*2; // size of (input and output) line
  500. pXlate = pinst->pXlate;
  501. /*
  502. * adjust the destination to point to the start of the last line,
  503. * and work upwards (to flip vertically into DIB format)
  504. */
  505. pDst = (PDWORD) ( (LPBYTE)lpOutput + (Height - 1) * WidthBytes );
  506. pSrc = (PDWORD) lpInput;
  507. /*
  508. * do we need to duplicate scans to fill the destination ?
  509. */
  510. if (Height >= 480) {
  511. bDuplicate = TRUE;
  512. /*
  513. * we need to skip one line each time we copy a line
  514. */
  515. RowInc = WidthBytes * 2 + (Width * 2);
  516. InputHeight = Height/2;
  517. } else {
  518. /*
  519. * calculate the amount to adjust pDst by at the end of one line
  520. * of copying. At this point we are at the end of line N. We need
  521. * to move to the start of line N-1.
  522. */
  523. RowInc = WidthBytes + (Width * 2);
  524. }
  525. /* remember we are adding to a DWORD pointer */
  526. RowInc /= sizeof(DWORD);
  527. /* loop copying each scanline */
  528. for (i = InputHeight; i > 0; i--) {
  529. /* loop copying two pixels at a time */
  530. for (j = Width ; j > 0; j -= 2) {
  531. /*
  532. * get two pixels and convert to 15-bpp YUV
  533. */
  534. dwPixel = *pSrc++;
  535. /*
  536. * dwPixel now has two pixels, in this layout (MSB..LSB):
  537. *
  538. * V Y1 U Y0
  539. *
  540. * convert to 2 yuv555 words and lookup in xlate table
  541. */
  542. /* get common u and v components to lower 10 bits */
  543. uv55 = ((dwPixel & 0xf8000000) >> 27) |
  544. ((dwPixel & 0x0000f800) >> 6);
  545. /* build each yuv-655 value by truncating
  546. * y to 5 bits and adding the common u and v bits,
  547. * look up to convert to rgb, and combine two pixels
  548. * into one dword
  549. */
  550. dwPixel = pXlate[ ((dwPixel & 0xf8) << 7) | uv55 ] |
  551. (pXlate[((dwPixel & 0xf80000) >> 9) | uv55 ] << 16);
  552. /* write two pixels to destination */
  553. *pDst++ = dwPixel;
  554. } // loop per 2 pixels
  555. /* move dest pointer back to next line */
  556. pDst -= RowInc;
  557. } // loop per row
  558. if (bDuplicate) {
  559. PBYTE pbDst;
  560. /*
  561. * Note that since we started at the last line, and didn't duplicate,
  562. * we placed data in lines 1, 3, 5 etc that needs to be copied
  563. * to lines 0, 2, 4 etc.
  564. */
  565. for (i = 0, pbDst = lpOutput; i < (int) Height; i+= 2) {
  566. /*
  567. * duplicate the scan line. We point at the first of the
  568. * two lines - the data is in the second of the
  569. * two lines.
  570. */
  571. RtlCopyMemory(pbDst, pbDst + WidthBytes, WidthBytes);
  572. /* skip this pair to get to the next line to be converted */
  573. pbDst += WidthBytes * 2;
  574. }
  575. }
  576. }
  577. #ifdef TOSHIBA
  578. #ifdef COLOR_MODIFY
  579. /* YUV12 support ------------------------------------------ */
  580. /*
  581. * TOSHIBA Y.Kasai
  582. * for Pistachio
  583. *
  584. * The captured data is in YUV12 , 8-bits per.
  585. * The data is separated each Y,U,V segment.
  586. * Data format is folow sequence:
  587. * Y0,Y1,Y2.......Yn,U0,U1,U2.....U(n/4),V0,V1,V2....V(n/4)
  588. *
  589. */
  590. /*
  591. * build a translation table to translate between YUV and RGB555.
  592. *
  593. * This builds a lookup table with 32k 1-word entries: truncate the YUV
  594. * to 15bits (5-5-5) and look-up in this xlate table to produce the
  595. * 15-bit rgb value.
  596. */
  597. LPVOID BuildYUVToRB(PINSTINFO pinst)
  598. {
  599. HGLOBAL hMem = 0;
  600. LPVOID pXlate = NULL;
  601. if (pinst->pXlate != NULL) {
  602. return(pinst->pXlate);
  603. }
  604. /*
  605. * allocate a table big enough for 64k 2-coloer (R, B) entries
  606. */
  607. if ( ( hMem = GlobalAlloc(GPTR, 2 * 64 * 1024) )
  608. && ( pXlate = GlobalLock( hMem ) ) )
  609. {
  610. LPBYTE pRB = (LPBYTE)pXlate;
  611. ULONG w;
  612. for (w = 0; w < 64*1024; w++) {
  613. *pRB++ = TosYVToR( (w & 0xff00) >> 8, ((w & 0xff)) );
  614. }
  615. for (w = 0; w < 64*1024; w++) {
  616. *pRB++ = TosYUToB( (w & 0xff00) >> 8, ((w & 0xff)) );
  617. }
  618. }
  619. return(pXlate);
  620. }
  621. #else //COLOR_MODIFY
  622. /* YUV12 support ------------------------------------------ */
  623. /*
  624. * TOSHIBA Y.Kasai
  625. * for Pistachio
  626. *
  627. * The captured data is in YUV12 , 8-bits per.
  628. * The data is separated each Y,U,V segment.
  629. * Data format is folow sequence:
  630. * Y0,Y1,Y2.......Yn,U0,U1,U2.....U(n/4),V0,V1,V2....V(n/4)
  631. *
  632. */
  633. /*
  634. * build a translation table to translate between YUV and RGB555.
  635. *
  636. * This builds a lookup table with 32k 1-word entries: truncate the YUV
  637. * to 15bits (5-5-5) and look-up in this xlate table to produce the
  638. * 15-bit rgb value.
  639. */
  640. LPVOID BuildYUV12ToRGB555(PINSTINFO pinst)
  641. {
  642. HGLOBAL hMem = 0;
  643. LPVOID pXlate = NULL;
  644. // LPWORD pRGB555;
  645. if (pinst->pXlate != NULL) {
  646. return(pinst->pXlate);
  647. }
  648. /*
  649. * allocate a table big enough for 32k 2-byte entries
  650. */
  651. if ( ( hMem = GlobalAlloc(GPTR, 2 * 32 * 1024) )
  652. && ( pXlate = GlobalLock( hMem ) ) )
  653. {
  654. WORD w;
  655. LPWORD pRGB555 = (LPWORD)pXlate;
  656. /*
  657. * build a 15-bit yuv lookup table by stepping through each entry,
  658. * converting the yuv index to rgb and storing at that index. The index
  659. * to this table is a 15-bit value with the y component in bits 14..10,
  660. * u in bits 9..5 and v in bits 4..0. Note that the y component is unsigned,
  661. * whereas the u and v components are signed.
  662. */
  663. for (w = 0; w < 32*1024; w++) {
  664. /*
  665. * the YUVtoRGB55 conversion function takes values 0..255 for y,
  666. * and 0..255 for u and v. Pick out the relevant bits of the
  667. * index for this cell, and shift to get values in this range.
  668. */
  669. *pRGB555++ = TosYUVToRGB555(
  670. (w & 0x7c00) >> 7,
  671. ((w & 0x3e0) >> 2),
  672. ((w & 0x1f) << 3)
  673. );
  674. }
  675. }
  676. return(pXlate);
  677. }
  678. /*
  679. * build a translation table to translate between YUV and RGB 5-6-5
  680. *
  681. * This builds a lookup table with 32k 1-word entries: truncate the YUV
  682. * to 15bits (5-5-5) and look-up in this xlate table to produce the
  683. * 16-bit rgb value.
  684. */
  685. LPVOID BuildYUV12ToRGB565(PINSTINFO pinst)
  686. {
  687. HGLOBAL hMem = 0;
  688. LPVOID pXlate = NULL;
  689. if (pinst->pXlate != NULL) {
  690. return(pinst->pXlate);
  691. }
  692. /*
  693. * allocate a table big enough for 32k 2-byte entries
  694. */
  695. if ( ( hMem = GlobalAlloc(GPTR, 2 * 32 * 1024) )
  696. && ( pXlate = GlobalLock( hMem ) ) )
  697. {
  698. WORD w;
  699. LPWORD pRGB = (LPWORD)pXlate;
  700. /*
  701. * build a 15-bit yuv lookup table by stepping through each entry,
  702. * converting the yuv index to rgb and storing at that index. The index
  703. * to this table is a 15-bit value with the y component in bits 14..10,
  704. * u in bits 9..5 and v in bits 4..0. Note that the y component is unsigned,
  705. * whereas the u and v components are signed.
  706. */
  707. for (w = 0; w < 32*1024; w++) {
  708. /*
  709. * the YUVtoRGB conversion function takes values 0..255 for y,
  710. * and 0.255 for u and v. Pick out the relevant bits of the
  711. * index for this cell, and shift to get values in this range.
  712. */
  713. *pRGB++ = TosYUVToRGB565(
  714. (w & 0x7c00) >> 7,
  715. ((w & 0x3e0) >> 2),
  716. ((w & 0x1f) << 3)
  717. );
  718. }
  719. }
  720. return(pXlate);
  721. }
  722. #endif//COLOR_MODIFY
  723. /*
  724. * translate YUV12 into 16-bit RGB using a lookup table. Flip vertically
  725. * into DIB format during processing. Double scanlines for formats of
  726. * 240 lines or greater. Produces 565 or 555 format RGB depending on the
  727. * xlate table.
  728. */
  729. #ifdef COLOR_MODIFY
  730. VOID
  731. YUV12ToRGB24(
  732. PINSTINFO pinst,
  733. LPBITMAPINFOHEADER lpbiInput,
  734. LPVOID lpInput,
  735. LPBITMAPINFOHEADER lpbiOutput,
  736. LPVOID lpOutput
  737. )
  738. {
  739. int RowInc;
  740. int UVRowInc;
  741. int i, j;
  742. DWORD dwYPixel;
  743. int dwParam, dwTemp;
  744. int WidthBytes; // width of one line in BYTES
  745. BOOL bDuplicate = FALSE;
  746. PDWORD pYSrc;
  747. volatile PBYTE pDst; // '98-12-08 Add volatile attr. for Rep.253570
  748. PWORD pUSrc, pVSrc;
  749. WORD wUPixel, wVPixel;
  750. WORD wUPTemp, wVPTemp;
  751. int Height, Width;
  752. PBYTE pXlate;
  753. int InputHeight;
  754. BYTE ubR, ubG, ubB;
  755. Height = lpbiInput->biHeight;
  756. InputHeight = Height;
  757. Width = lpbiInput->biWidth;
  758. WidthBytes = Width*3; // size of (input and output) line
  759. pXlate = (PBYTE)pinst->pXlate;
  760. /*
  761. * adjust the destination to point to the start of the last line,
  762. * and work upwards (to flip vertically into DIB format)
  763. */
  764. pDst = (PBYTE) ( (LPBYTE)lpOutput + (Height - 1) * WidthBytes );
  765. pYSrc = (PDWORD) lpInput;
  766. pUSrc = (PWORD) ( (LPBYTE)lpInput + Height * Width);
  767. pVSrc = (PWORD) ( (LPBYTE)lpInput + Height * Width + Height * Width / 4);
  768. RowInc = WidthBytes + (Width * 3);
  769. UVRowInc = Width / 2;
  770. UVRowInc /= sizeof(WORD);
  771. /* loop copying each scanline */
  772. for (i = 0; i < InputHeight; i++) {
  773. /* loop copying two pixels at a time */
  774. for (j = Width ; j > 0; j -= 4) {
  775. /*
  776. * get four pixels and convert to 15-bpp YUV
  777. */
  778. dwYPixel = *pYSrc++;
  779. wUPixel = *pUSrc++;
  780. wVPixel = *pVSrc++;
  781. wVPTemp = wVPixel & 0xff;
  782. wUPTemp = wUPixel & 0xff;
  783. dwParam = (833 * wVPTemp) + (402 * wUPTemp) - 138908;
  784. /*
  785. * dwY(U or V)Pixel now has two pixels, in this layout (MSB..LSB):
  786. *
  787. * Y3 Y2 Y1 Y0
  788. * V1 V0
  789. * U1 U0
  790. *
  791. * convert to 4 yuv555 words and lookup in xlate table
  792. */
  793. /* build each yuv-555 value by truncating
  794. * y to 8 bits and adding the common u and v bits,
  795. * look up to convert to rgb, and combine two pixels
  796. * into one dword
  797. */
  798. dwTemp = dwYPixel & 0xff;
  799. ubG = (BYTE)RANGE((dwTemp * 1192 - dwParam) / 1024, 0, 255);
  800. dwTemp <<= 8;
  801. ubR = pXlate[ dwTemp | wVPTemp];
  802. ubB = pXlate[(dwTemp | wUPTemp) + 65536];
  803. *pDst++ = ubB;
  804. *pDst++ = ubG;
  805. *pDst++ = ubR;
  806. // next pixel
  807. dwTemp = dwYPixel & 0xff00;
  808. ubR = pXlate[ dwTemp | wVPTemp];
  809. ubB = pXlate[(dwTemp | wUPTemp) + 65536];
  810. ubG = (BYTE)RANGE(((dwTemp >> 8) * 1192 - dwParam) / 1024, 0, 255);
  811. *pDst++ = ubB;
  812. *pDst++ = ubG;
  813. *pDst++ = ubR;
  814. wVPTemp = (wVPixel >> 8) & 0xff;
  815. wUPTemp = (wUPixel >> 8) & 0xff;
  816. dwParam = (833 * wVPTemp) + (402 * wUPTemp) - 138908;
  817. dwTemp = (dwYPixel & 0xff0000) >> 8;
  818. ubR = pXlate[ dwTemp | wVPTemp];
  819. ubB = pXlate[(dwTemp | wUPTemp) + 65536];
  820. ubG = (BYTE)RANGE(((dwTemp >> 8) * 1192 - dwParam) / 1024, 0, 255);
  821. *pDst++ = ubB;
  822. *pDst++ = ubG;
  823. *pDst++ = ubR;
  824. // next pixel
  825. dwTemp = (dwYPixel & 0xff000000) >> 16;
  826. ubR = pXlate[ dwTemp | wVPTemp];
  827. ubB = pXlate[(dwTemp | wUPTemp) + 65536];
  828. ubG = (BYTE)RANGE(((dwTemp >> 8) * 1192 - dwParam) / 1024, 0, 255);
  829. *pDst++ = ubB;
  830. *pDst++ = ubG;
  831. *pDst++ = ubR;
  832. } // loop per 4 pixels
  833. if (!(i & 1))
  834. {
  835. pUSrc -= UVRowInc;
  836. pVSrc -= UVRowInc;
  837. }
  838. /* move dest pointer back to next line */
  839. pDst -= RowInc;
  840. } // loop per row
  841. }
  842. VOID
  843. YUV12ToRGB565(
  844. PINSTINFO pinst,
  845. LPBITMAPINFOHEADER lpbiInput,
  846. LPVOID lpInput,
  847. LPBITMAPINFOHEADER lpbiOutput,
  848. LPVOID lpOutput
  849. )
  850. {
  851. int RowInc;
  852. int UVRowInc;
  853. int i, j;
  854. DWORD uv55, dwPixel, dwYPixel;
  855. int dwParam, dwTemp;
  856. int WidthBytes; // width of one line in BYTES
  857. BOOL bDuplicate = FALSE;
  858. PDWORD pYSrc;
  859. volatile PDWORD pDst; // '98-12-08 Add volatile attr. for Rep.253570
  860. PWORD pUSrc, pVSrc;
  861. WORD wUPixel, wVPixel;
  862. WORD wUPTemp, wVPTemp;
  863. int Height, Width;
  864. PBYTE pXlate;
  865. int InputHeight;
  866. BYTE ubR, ubG, ubB;
  867. Height = lpbiInput->biHeight;
  868. InputHeight = Height;
  869. Width = lpbiInput->biWidth;
  870. WidthBytes = Width*2; // size of (input and output) line
  871. pXlate = (PBYTE)pinst->pXlate;
  872. /*
  873. * adjust the destination to point to the start of the last line,
  874. * and work upwards (to flip vertically into DIB format)
  875. */
  876. pDst = (PDWORD) ( (LPBYTE)lpOutput + (Height - 1) * WidthBytes );
  877. pYSrc = (PDWORD) lpInput;
  878. pUSrc = (PWORD) ( (LPBYTE)lpInput + Height * Width);
  879. pVSrc = (PWORD) ( (LPBYTE)lpInput + Height * Width + Height * Width / 4);
  880. RowInc = WidthBytes + (Width * 2);
  881. /* remember we are adding to a DWORD pointer */
  882. RowInc /= sizeof(DWORD);
  883. UVRowInc = Width / 2;
  884. UVRowInc /= sizeof(WORD);
  885. /* loop copying each scanline */
  886. for (i = 0; i < InputHeight; i++) {
  887. /* loop copying two pixels at a time */
  888. for (j = Width ; j > 0; j -= 4) {
  889. /*
  890. * get four pixels and convert to 15-bpp YUV
  891. */
  892. dwYPixel = *pYSrc++;
  893. wUPixel = *pUSrc++;
  894. wVPixel = *pVSrc++;
  895. wVPTemp = wVPixel & 0xff;
  896. wUPTemp = wUPixel & 0xff;
  897. dwParam = (833 * wVPTemp) + (402 * wUPTemp) - 138908;
  898. /*
  899. * dwY(U or V)Pixel now has two pixels, in this layout (MSB..LSB):
  900. *
  901. * Y3 Y2 Y1 Y0
  902. * V1 V0
  903. * U1 U0
  904. *
  905. * convert to 4 yuv555 words and lookup in xlate table
  906. */
  907. /* build each yuv-555 value by truncating
  908. * y to 8 bits and adding the common u and v bits,
  909. * look up to convert to rgb, and combine two pixels
  910. * into one dword
  911. */
  912. dwTemp = dwYPixel & 0xff;
  913. ubG = (BYTE)RANGE((dwTemp * 1192 - dwParam) / 1024, 0, 255);
  914. dwTemp <<= 8;
  915. ubR = pXlate[ dwTemp | wVPTemp];
  916. ubB = pXlate[(dwTemp | wUPTemp) + 65536];
  917. dwPixel = (ubR & 0xf8) << 8 | (ubG & 0xfc) << 3 | (ubB & 0xf8) >> 3;
  918. // next pixel
  919. dwTemp = dwYPixel & 0xff00;
  920. ubR = pXlate[ dwTemp | wVPTemp];
  921. ubB = pXlate[(dwTemp | wUPTemp) + 65536];
  922. ubG = (BYTE)RANGE(((dwTemp >> 8) * 1192 - dwParam) / 1024, 0, 255);
  923. dwPixel |= (ubR & 0xf8) << 24 | (ubG & 0xfc) << 19 | (ubB & 0xf8) << 13;
  924. /* write two pixels to destination */
  925. *pDst++ = dwPixel;
  926. wVPTemp = (wVPixel >> 8) & 0xff;
  927. wUPTemp = (wUPixel >> 8) & 0xff;
  928. dwParam = (833 * wVPTemp) + (402 * wUPTemp) - 138908;
  929. dwTemp = (dwYPixel & 0xff0000) >> 8;
  930. ubR = pXlate[ dwTemp | wVPTemp];
  931. ubB = pXlate[(dwTemp | wUPTemp) + 65536];
  932. ubG = (BYTE)RANGE(((dwTemp >> 8) * 1192 - dwParam) / 1024, 0, 255);
  933. dwPixel = (ubR & 0xf8) << 8 | (ubG & 0xfc) << 3 | (ubB & 0xf8) >> 3;
  934. // next pixel
  935. dwTemp = (dwYPixel & 0xff000000) >> 16;
  936. ubR = pXlate[ dwTemp | wVPTemp];
  937. ubB = pXlate[(dwTemp | wUPTemp) + 65536];
  938. ubG = (BYTE)RANGE(((dwTemp >> 8) * 1192 - dwParam) / 1024, 0, 255);
  939. dwPixel |= (ubR & 0xf8) << 24 | (ubG & 0xfc) << 19 | (ubB & 0xf8) << 13;
  940. /* write two pixels to destination */
  941. *pDst++ = dwPixel;
  942. } // loop per 4 pixels
  943. if (!(i & 1))
  944. {
  945. pUSrc -= UVRowInc;
  946. pVSrc -= UVRowInc;
  947. }
  948. /* move dest pointer back to next line */
  949. pDst -= RowInc;
  950. } // loop per row
  951. }
  952. VOID
  953. YUV12ToRGB555(
  954. PINSTINFO pinst,
  955. LPBITMAPINFOHEADER lpbiInput,
  956. LPVOID lpInput,
  957. LPBITMAPINFOHEADER lpbiOutput,
  958. LPVOID lpOutput
  959. )
  960. {
  961. int RowInc;
  962. int UVRowInc;
  963. int i, j;
  964. DWORD uv55, dwPixel, dwYPixel;
  965. int dwParam, dwTemp;
  966. int WidthBytes; // width of one line in BYTES
  967. BOOL bDuplicate = FALSE;
  968. PDWORD pYSrc;
  969. volatile PDWORD pDst; // '98-12-08 Add volatile attr. for Rep.253570
  970. PWORD pUSrc, pVSrc;
  971. WORD wUPixel, wVPixel;
  972. WORD wUPTemp, wVPTemp;
  973. int Height, Width;
  974. PBYTE pXlate;
  975. int InputHeight;
  976. BYTE ubR, ubG, ubB;
  977. Height = lpbiInput->biHeight;
  978. InputHeight = Height;
  979. Width = lpbiInput->biWidth;
  980. WidthBytes = Width*2; // size of (input and output) line
  981. pXlate = (PBYTE)pinst->pXlate;
  982. /*
  983. * adjust the destination to point to the start of the last line,
  984. * and work upwards (to flip vertically into DIB format)
  985. */
  986. pDst = (PDWORD) ( (LPBYTE)lpOutput + (Height - 1) * WidthBytes );
  987. pYSrc = (PDWORD) lpInput;
  988. pUSrc = (PWORD) ( (LPBYTE)lpInput + Height * Width);
  989. pVSrc = (PWORD) ( (LPBYTE)lpInput + Height * Width + Height * Width / 4);
  990. RowInc = WidthBytes + (Width * 2);
  991. /* remember we are adding to a DWORD pointer */
  992. RowInc /= sizeof(DWORD);
  993. UVRowInc = Width / 2;
  994. UVRowInc /= sizeof(WORD);
  995. /* loop copying each scanline */
  996. for (i = 0; i < InputHeight; i++) {
  997. /* loop copying two pixels at a time */
  998. for (j = Width ; j > 0; j -= 4) {
  999. /*
  1000. * get four pixels and convert to 15-bpp YUV
  1001. */
  1002. dwYPixel = *pYSrc++;
  1003. wUPixel = *pUSrc++;
  1004. wVPixel = *pVSrc++;
  1005. wVPTemp = wVPixel & 0xff;
  1006. wUPTemp = wUPixel & 0xff;
  1007. dwParam = (833 * wVPTemp) + (402 * wUPTemp) - 138908;
  1008. /*
  1009. * dwY(U or V)Pixel now has two pixels, in this layout (MSB..LSB):
  1010. *
  1011. * Y3 Y2 Y1 Y0
  1012. * V1 V0
  1013. * U1 U0
  1014. *
  1015. * convert to 4 yuv555 words and lookup in xlate table
  1016. */
  1017. /* build each yuv-555 value by truncating
  1018. * y to 8 bits and adding the common u and v bits,
  1019. * look up to convert to rgb, and combine two pixels
  1020. * into one dword
  1021. */
  1022. dwTemp = dwYPixel & 0xff;
  1023. ubG = (BYTE)RANGE((dwTemp * 1192 - dwParam) / 1024, 0, 255);
  1024. dwTemp <<= 8;
  1025. ubR = pXlate[ dwTemp | wVPTemp];
  1026. ubB = pXlate[(dwTemp | wUPTemp) + 65536];
  1027. dwPixel = (ubR & 0xf8) << 7 | (ubG & 0xf8) << 2 | (ubB & 0xf8) >> 3;
  1028. // next pixel
  1029. dwTemp = dwYPixel & 0xff00;
  1030. ubR = pXlate[ dwTemp | wVPTemp];
  1031. ubB = pXlate[(dwTemp | wUPTemp) + 65536];
  1032. ubG = (BYTE)RANGE(((dwTemp >> 8) * 1192 - dwParam) / 1024, 0, 255);
  1033. dwPixel |= (ubR & 0xf8) << 23 | (ubG & 0xf8) << 18 | (ubB & 0xf8) << 13;
  1034. /* write two pixels to destination */
  1035. *pDst++ = dwPixel;
  1036. wVPTemp = (wVPixel >> 8) & 0xff;
  1037. wUPTemp = (wUPixel >> 8) & 0xff;
  1038. dwParam = (833 * wVPTemp) + (402 * wUPTemp) - 138908;
  1039. dwTemp = (dwYPixel & 0xff0000) >> 8;
  1040. ubR = pXlate[ dwTemp | wVPTemp];
  1041. ubB = pXlate[(dwTemp | wUPTemp) + 65536];
  1042. ubG = (BYTE)RANGE(((dwTemp >> 8) * 1192 - dwParam) / 1024, 0, 255);
  1043. dwPixel = (ubR & 0xf8) << 7 | (ubG & 0xf8) << 2 | (ubB & 0xf8) >> 3;
  1044. // next pixel
  1045. dwTemp = (dwYPixel & 0xff000000) >> 16;
  1046. ubR = pXlate[ dwTemp | wVPTemp];
  1047. ubB = pXlate[(dwTemp | wUPTemp) + 65536];
  1048. ubG = (BYTE)RANGE(((dwTemp >> 8) * 1192 - dwParam) / 1024, 0, 255);
  1049. dwPixel |= (ubR & 0xf8) << 23 | (ubG & 0xf8) << 18 | (ubB & 0xf8) << 13;
  1050. /* write two pixels to destination */
  1051. *pDst++ = dwPixel;
  1052. } // loop per 4 pixels
  1053. if (!(i & 1))
  1054. {
  1055. pUSrc -= UVRowInc;
  1056. pVSrc -= UVRowInc;
  1057. }
  1058. /* move dest pointer back to next line */
  1059. pDst -= RowInc;
  1060. } // loop per row
  1061. }
  1062. #else //COLOR_MODIFY
  1063. VOID
  1064. YUV12ToRGB(
  1065. PINSTINFO pinst,
  1066. LPBITMAPINFOHEADER lpbiInput,
  1067. LPVOID lpInput,
  1068. LPBITMAPINFOHEADER lpbiOutput,
  1069. LPVOID lpOutput
  1070. )
  1071. {
  1072. int RowInc;
  1073. int UVRowInc;
  1074. int i, j;
  1075. DWORD uv55, dwPixel, dwYPixel;
  1076. int WidthBytes; // width of one line in BYTES
  1077. BOOL bDuplicate = FALSE;
  1078. PDWORD pYSrc, pDst;
  1079. PWORD pUSrc, pVSrc;
  1080. WORD wUPixel, wVPixel;
  1081. int Height, Width;
  1082. PWORD pXlate;
  1083. int InputHeight;
  1084. Height = lpbiInput->biHeight;
  1085. InputHeight = Height;
  1086. Width = lpbiInput->biWidth;
  1087. WidthBytes = Width*2; // size of (input and output) line
  1088. pXlate = pinst->pXlate;
  1089. /*
  1090. * adjust the destination to point to the start of the last line,
  1091. * and work upwards (to flip vertically into DIB format)
  1092. */
  1093. pDst = (PDWORD) ( (LPBYTE)lpOutput + (Height - 1) * WidthBytes );
  1094. pYSrc = (PDWORD) lpInput;
  1095. #if 1
  1096. pUSrc = (PWORD) ( (LPBYTE)lpInput + Height * Width);
  1097. pVSrc = (PWORD) ( (LPBYTE)lpInput + Height * Width + Height * Width / 4);
  1098. #else
  1099. pUSrc = (PWORD) lpInput + Height * Width;
  1100. pVSrc = (PWORD) lpInput + Height * Width + Height * Width / 4;
  1101. #endif
  1102. #if 1
  1103. RowInc = WidthBytes + (Width * 2);
  1104. #else
  1105. /*
  1106. * do we need to duplicate scans to fill the destination ?
  1107. */
  1108. if (Height >= 240) {
  1109. bDuplicate = TRUE;
  1110. /*
  1111. * we need to skip one line each time we copy a line
  1112. */
  1113. RowInc = WidthBytes * 2 + (Width * 2);
  1114. InputHeight = Height/2;
  1115. } else {
  1116. /*
  1117. * calculate the amount to adjust pDst by at the end of one line
  1118. * of copying. At this point we are at the end of line N. We need
  1119. * to move to the start of line N-1.
  1120. */
  1121. RowInc = WidthBytes + (Width * 2);
  1122. }
  1123. #endif
  1124. /* remember we are adding to a DWORD pointer */
  1125. RowInc /= sizeof(DWORD);
  1126. UVRowInc = Width / 2;
  1127. UVRowInc /= sizeof(WORD);
  1128. /* loop copying each scanline */
  1129. for (i = 0; i < InputHeight; i++) {
  1130. /* loop copying two pixels at a time */
  1131. for (j = Width ; j > 0; j -= 4) {
  1132. /*
  1133. * get four pixels and convert to 15-bpp YUV
  1134. */
  1135. dwYPixel = *pYSrc++;
  1136. wUPixel = *pUSrc++;
  1137. wVPixel = *pVSrc++;
  1138. /*
  1139. * dwY(U or V)Pixel now has two pixels, in this layout (MSB..LSB):
  1140. *
  1141. * Y3 Y2 Y1 Y0
  1142. * V1 V0
  1143. * U1 U0
  1144. *
  1145. * convert to 4 yuv555 words and lookup in xlate table
  1146. */
  1147. /* get common u0 and v0 components to lower 10 bits */
  1148. uv55 = ((wUPixel & 0xf8) << 2) |
  1149. ((wVPixel & 0xf8) >> 3);
  1150. /* build each yuv-555 value by truncating
  1151. * y to 5 bits and adding the common u and v bits,
  1152. * look up to convert to rgb, and combine two pixels
  1153. * into one dword
  1154. */
  1155. dwPixel = pXlate[ ((dwYPixel & 0xf8) << 7) | uv55 ] |
  1156. (pXlate[((dwYPixel & 0xf800) >> 1) | uv55 ] << 16);
  1157. /* write two pixels to destination */
  1158. *pDst++ = dwPixel;
  1159. /* get common u1 and v1 components to lower 10 bits */
  1160. uv55 = ((wUPixel & 0xf800) >> 6) |
  1161. ((wVPixel & 0xf800) >> 11);
  1162. /* build each yuv-655 value by truncating
  1163. * y to 5 bits and adding the common u and v bits,
  1164. * look up to convert to rgb, and combine two pixels
  1165. * into one dword
  1166. */
  1167. dwPixel = pXlate[ ((dwYPixel & 0xf80000) >> 9) | uv55 ] |
  1168. (pXlate[((dwYPixel & 0xf8000000) >> 17) | uv55 ] << 16);
  1169. /* write two pixels to destination */
  1170. *pDst++ = dwPixel;
  1171. } // loop per 4 pixels
  1172. if (!(i & 1))
  1173. {
  1174. pUSrc -= UVRowInc;
  1175. pVSrc -= UVRowInc;
  1176. }
  1177. /* move dest pointer back to next line */
  1178. pDst -= RowInc;
  1179. } // loop per row
  1180. #if 0 // Pistachio is not support Interlace mode!!
  1181. if (bDuplicate) {
  1182. PBYTE pbDst;
  1183. /*
  1184. * Note that since we started at the last line, and didn't duplicate,
  1185. * we placed data in lines 1, 3, 5 etc that needs to be copied
  1186. * to lines 0, 2, 4 etc.
  1187. */
  1188. for (i = 0, pbDst = lpOutput; i < (int) Height; i+= 2) {
  1189. /*
  1190. * duplicate the scan line. We point at the first of the
  1191. * two lines - the data is in the second of the
  1192. * two lines.
  1193. */
  1194. RtlCopyMemory(pbDst, pbDst + WidthBytes, WidthBytes);
  1195. /* skip this pair to get to the next line to be converted */
  1196. pbDst += WidthBytes * 2;
  1197. }
  1198. }
  1199. #endif
  1200. }
  1201. #endif//COLOR_MODIFY
  1202. /* YUV9 Support ------------------------------------------ */
  1203. /*
  1204. * TOSHIBA Y.Kasai
  1205. * for Pistachio
  1206. *
  1207. * The captured data is in YUV9 .
  1208. * The data is separated each Y,U,V segment.
  1209. * Data format is folow sequence:
  1210. * Y0,Y1,Y2.......Yn,V0,V1,V2....V(n/16),U0,U1,U2.....U(n/16)
  1211. *
  1212. */
  1213. /*
  1214. * translate YUV9 into 16-bit RGB using a lookup table. Flip vertically
  1215. * into DIB format during processing.
  1216. * Produces 565 or 555 format RGB depending on the
  1217. * xlate table.
  1218. */
  1219. #ifdef COLOR_MODIFY
  1220. VOID
  1221. YUV9ToRGB24(
  1222. PINSTINFO pinst,
  1223. LPBITMAPINFOHEADER lpbiInput,
  1224. LPVOID lpInput,
  1225. LPBITMAPINFOHEADER lpbiOutput,
  1226. LPVOID lpOutput
  1227. )
  1228. {
  1229. int RowInc;
  1230. int UVRowInc;
  1231. int i, j;
  1232. DWORD dwYPixel;
  1233. int dwParam, dwTemp;
  1234. int WidthBytes; // width of one line in BYTES
  1235. BOOL bDuplicate = FALSE;
  1236. PDWORD pYSrc;
  1237. volatile PBYTE pDst; // '98-12-08 Add volatile attr. for Rep.253570
  1238. PBYTE pUSrc, pVSrc;
  1239. BYTE bUPixel, bVPixel;
  1240. int Height, Width;
  1241. PBYTE pXlate;
  1242. int InputHeight;
  1243. BYTE ubR, ubG, ubB;
  1244. Height = lpbiInput->biHeight;
  1245. InputHeight = Height;
  1246. Width = lpbiInput->biWidth;
  1247. WidthBytes = Width*3; // size of (input and output) line
  1248. pXlate = (PBYTE)pinst->pXlate;
  1249. /*
  1250. * adjust the destination to point to the start of the last line,
  1251. * and work upwards (to flip vertically into DIB format)
  1252. */
  1253. pDst = (PBYTE) ( (LPBYTE)lpOutput + (Height - 1) * WidthBytes );
  1254. pYSrc = (PDWORD) lpInput;
  1255. pVSrc = (PBYTE) ( (LPBYTE)lpInput + Height * Width);
  1256. pUSrc = (PBYTE) ( (LPBYTE)lpInput + Height * Width + Height * Width / 16);
  1257. /*
  1258. * calculate the amount to adjust pDst by at the end of one line
  1259. * of copying. At this point we are at the end of line N. We need
  1260. * to move to the start of line N-1.
  1261. */
  1262. RowInc = WidthBytes + (Width * 3);
  1263. UVRowInc = Width / 4;
  1264. UVRowInc /= sizeof(BYTE);
  1265. /* loop copying each scanline */
  1266. for (i = 0; i < InputHeight; i++) {
  1267. /* loop copying two pixels at a time */
  1268. for (j = Width ; j > 0; j -= 4) {
  1269. /*
  1270. * get four pixels and convert to 15-bpp YUV
  1271. */
  1272. dwYPixel = *pYSrc++;
  1273. bUPixel = *pUSrc++;
  1274. bVPixel = *pVSrc++;
  1275. dwParam = (833 * bVPixel) + (402 * bUPixel) - 138908;
  1276. /*
  1277. * dwY(U or V)Pixel now has four pixels, in this layout (MSB..LSB):
  1278. *
  1279. * Y3 Y2 Y1 Y0
  1280. * V0
  1281. * U0
  1282. *
  1283. * convert to 4 yuv555 words and lookup in xlate table
  1284. */
  1285. /* build each yuv-555 value by truncating
  1286. * y to 5 bits and adding the common u and v bits,
  1287. * look up to convert to rgb, and combine two pixels
  1288. * into one dword
  1289. */
  1290. dwTemp = dwYPixel & 0xff;
  1291. ubG = (BYTE)RANGE((dwTemp * 1192 - dwParam) / 1024, 0, 255);
  1292. dwTemp <<= 8;
  1293. ubR = pXlate[ dwTemp | bVPixel];
  1294. ubB = pXlate[(dwTemp | bUPixel) + 65536];
  1295. *pDst++ = ubB;
  1296. *pDst++ = ubG;
  1297. *pDst++ = ubR;
  1298. // next pixel
  1299. dwTemp = dwYPixel & 0xff00;
  1300. ubR = pXlate[ dwTemp | bVPixel];
  1301. ubB = pXlate[(dwTemp | bUPixel) + 65536];
  1302. ubG = (BYTE)RANGE(((dwTemp >> 8) * 1192 - dwParam) / 1024, 0, 255);
  1303. *pDst++ = ubB;
  1304. *pDst++ = ubG;
  1305. *pDst++ = ubR;
  1306. /* build each yuv-655 value by truncating
  1307. * y to 5 bits and adding the common u and v bits,
  1308. * look up to convert to rgb, and combine two pixels
  1309. * into one dword
  1310. */
  1311. dwTemp = (dwYPixel & 0xff0000) >> 8;
  1312. ubR = pXlate[ dwTemp | bVPixel];
  1313. ubB = pXlate[(dwTemp | bUPixel) + 65536];
  1314. ubG = (BYTE)RANGE(((dwTemp >> 8) * 1192 - dwParam) / 1024, 0, 255);
  1315. *pDst++ = ubB;
  1316. *pDst++ = ubG;
  1317. *pDst++ = ubR;
  1318. // next pixel
  1319. dwTemp = (dwYPixel & 0xff000000) >> 16;
  1320. ubR = pXlate[ dwTemp | bVPixel];
  1321. ubB = pXlate[(dwTemp | bUPixel) + 65536];
  1322. ubG = (BYTE)RANGE((((dwTemp >> 8) & 0xff) * 1192 - dwParam) / 1024, 0, 255);
  1323. *pDst++ = ubB;
  1324. *pDst++ = ubG;
  1325. *pDst++ = ubR;
  1326. } // loop per 4 pixels
  1327. if ((i & 0x3) != 0x03)
  1328. {
  1329. pUSrc -= UVRowInc;
  1330. pVSrc -= UVRowInc;
  1331. }
  1332. /* move dest pointer back to next line */
  1333. pDst -= RowInc;
  1334. } // loop per row
  1335. }
  1336. VOID
  1337. YUV9ToRGB565(
  1338. PINSTINFO pinst,
  1339. LPBITMAPINFOHEADER lpbiInput,
  1340. LPVOID lpInput,
  1341. LPBITMAPINFOHEADER lpbiOutput,
  1342. LPVOID lpOutput
  1343. )
  1344. {
  1345. int RowInc;
  1346. int UVRowInc;
  1347. int i, j;
  1348. DWORD uv55, dwPixel, dwYPixel;
  1349. int dwParam, dwTemp;
  1350. int WidthBytes; // width of one line in BYTES
  1351. BOOL bDuplicate = FALSE;
  1352. PDWORD pYSrc;
  1353. volatile PDWORD pDst; // '98-12-08 Add volatile attr. for Rep.253570
  1354. PBYTE pUSrc, pVSrc;
  1355. BYTE bUPixel, bVPixel;
  1356. int Height, Width;
  1357. PBYTE pXlate;
  1358. int InputHeight;
  1359. BYTE ubR, ubG, ubB;
  1360. Height = lpbiInput->biHeight;
  1361. InputHeight = Height;
  1362. Width = lpbiInput->biWidth;
  1363. WidthBytes = Width*2; // size of (input and output) line
  1364. pXlate = (PBYTE)pinst->pXlate;
  1365. /*
  1366. * adjust the destination to point to the start of the last line,
  1367. * and work upwards (to flip vertically into DIB format)
  1368. */
  1369. pDst = (PDWORD) ( (LPBYTE)lpOutput + (Height - 1) * WidthBytes );
  1370. pYSrc = (PDWORD) lpInput;
  1371. pVSrc = (PBYTE) ( (LPBYTE)lpInput + Height * Width);
  1372. pUSrc = (PBYTE) ( (LPBYTE)lpInput + Height * Width + Height * Width / 16);
  1373. /*
  1374. * calculate the amount to adjust pDst by at the end of one line
  1375. * of copying. At this point we are at the end of line N. We need
  1376. * to move to the start of line N-1.
  1377. */
  1378. RowInc = WidthBytes + (Width * 2);
  1379. /* remember we are adding to a DWORD pointer */
  1380. RowInc /= sizeof(DWORD);
  1381. UVRowInc = Width / 4;
  1382. UVRowInc /= sizeof(BYTE);
  1383. /* loop copying each scanline */
  1384. for (i = 0; i < InputHeight; i++) {
  1385. /* loop copying two pixels at a time */
  1386. for (j = Width ; j > 0; j -= 4) {
  1387. /*
  1388. * get four pixels and convert to 15-bpp YUV
  1389. */
  1390. dwYPixel = *pYSrc++;
  1391. bUPixel = *pUSrc++;
  1392. bVPixel = *pVSrc++;
  1393. dwParam = (833 * bVPixel) + (402 * bUPixel) - 138908;
  1394. /*
  1395. * dwY(U or V)Pixel now has four pixels, in this layout (MSB..LSB):
  1396. *
  1397. * Y3 Y2 Y1 Y0
  1398. * V0
  1399. * U0
  1400. *
  1401. * convert to 4 yuv555 words and lookup in xlate table
  1402. */
  1403. /* build each yuv-555 value by truncating
  1404. * y to 5 bits and adding the common u and v bits,
  1405. * look up to convert to rgb, and combine two pixels
  1406. * into one dword
  1407. */
  1408. dwTemp = dwYPixel & 0xff;
  1409. ubG = (BYTE)RANGE((dwTemp * 1192 - dwParam) / 1024, 0, 255);
  1410. dwTemp <<= 8;
  1411. ubR = pXlate[ dwTemp | bVPixel];
  1412. ubB = pXlate[(dwTemp | bUPixel) + 65536];
  1413. dwPixel = (ubR & 0xf8) << 8 | (ubG & 0xfc) << 3 | (ubB & 0xf8) >> 3;
  1414. // next pixel
  1415. dwTemp = dwYPixel & 0xff00;
  1416. ubR = pXlate[ dwTemp | bVPixel];
  1417. ubB = pXlate[(dwTemp | bUPixel) + 65536];
  1418. ubG = (BYTE)RANGE(((dwTemp >> 8) * 1192 - dwParam) / 1024, 0, 255);
  1419. dwPixel |= (ubR & 0xf8) << 24 | (ubG & 0xfc) << 19 | (ubB & 0xf8) << 13;
  1420. *pDst++ = dwPixel;
  1421. /* build each yuv-655 value by truncating
  1422. * y to 5 bits and adding the common u and v bits,
  1423. * look up to convert to rgb, and combine two pixels
  1424. * into one dword
  1425. */
  1426. dwTemp = (dwYPixel & 0xff0000) >> 8;
  1427. ubR = pXlate[ dwTemp | bVPixel];
  1428. ubB = pXlate[(dwTemp | bUPixel) + 65536];
  1429. ubG = (BYTE)RANGE(((dwTemp >> 8) * 1192 - dwParam) / 1024, 0, 255);
  1430. dwPixel = (ubR & 0xf8) << 8 | (ubG & 0xfc) << 3 | (ubB & 0xf8) >> 3;
  1431. // next pixel
  1432. dwTemp = (dwYPixel & 0xff000000) >> 16;
  1433. ubR = pXlate[ dwTemp | bVPixel];
  1434. ubB = pXlate[(dwTemp | bUPixel) + 65536];
  1435. ubG = (BYTE)RANGE((((dwTemp >> 8) & 0xff) * 1192 - dwParam) / 1024, 0, 255);
  1436. dwPixel |= (ubR & 0xf8) << 24 | (ubG & 0xfc) << 19 | (ubB & 0xf8) << 13;
  1437. /* write two pixels to destination */
  1438. *pDst++ = dwPixel;
  1439. } // loop per 4 pixels
  1440. if ((i & 0x3) != 0x03)
  1441. {
  1442. pUSrc -= UVRowInc;
  1443. pVSrc -= UVRowInc;
  1444. }
  1445. /* move dest pointer back to next line */
  1446. pDst -= RowInc;
  1447. } // loop per row
  1448. }
  1449. VOID
  1450. YUV9ToRGB555(
  1451. PINSTINFO pinst,
  1452. LPBITMAPINFOHEADER lpbiInput,
  1453. LPVOID lpInput,
  1454. LPBITMAPINFOHEADER lpbiOutput,
  1455. LPVOID lpOutput
  1456. )
  1457. {
  1458. int RowInc;
  1459. int UVRowInc;
  1460. int i, j;
  1461. DWORD uv55, dwPixel, dwYPixel;
  1462. int dwParam, dwTemp;
  1463. int WidthBytes; // width of one line in BYTES
  1464. BOOL bDuplicate = FALSE;
  1465. PDWORD pYSrc;
  1466. volatile PDWORD pDst; // '98-12-08 Add volatile attr. for Rep.253570
  1467. PBYTE pUSrc, pVSrc;
  1468. BYTE bUPixel, bVPixel;
  1469. int Height, Width;
  1470. PBYTE pXlate;
  1471. int InputHeight;
  1472. BYTE ubR, ubG, ubB;
  1473. Height = lpbiInput->biHeight;
  1474. InputHeight = Height;
  1475. Width = lpbiInput->biWidth;
  1476. WidthBytes = Width*2; // size of (input and output) line
  1477. pXlate = pinst->pXlate;
  1478. /*
  1479. * adjust the destination to point to the start of the last line,
  1480. * and work upwards (to flip vertically into DIB format)
  1481. */
  1482. pDst = (PDWORD) ( (LPBYTE)lpOutput + (Height - 1) * WidthBytes );
  1483. pYSrc = (PDWORD) lpInput;
  1484. pVSrc = (PBYTE) ( (LPBYTE)lpInput + Height * Width);
  1485. pUSrc = (PBYTE) ( (LPBYTE)lpInput + Height * Width + Height * Width / 16);
  1486. /*
  1487. * calculate the amount to adjust pDst by at the end of one line
  1488. * of copying. At this point we are at the end of line N. We need
  1489. * to move to the start of line N-1.
  1490. */
  1491. RowInc = WidthBytes + (Width * 2);
  1492. /* remember we are adding to a DWORD pointer */
  1493. RowInc /= sizeof(DWORD);
  1494. UVRowInc = Width / 4;
  1495. UVRowInc /= sizeof(BYTE);
  1496. /* loop copying each scanline */
  1497. for (i = 0; i < InputHeight; i++) {
  1498. /* loop copying two pixels at a time */
  1499. for (j = Width ; j > 0; j -= 4) {
  1500. /*
  1501. * get four pixels and convert to 15-bpp YUV
  1502. */
  1503. dwYPixel = *pYSrc++;
  1504. bUPixel = *pUSrc++;
  1505. bVPixel = *pVSrc++;
  1506. dwParam = (833 * bVPixel) + (402 * bUPixel) - 138908;
  1507. /*
  1508. * dwY(U or V)Pixel now has four pixels, in this layout (MSB..LSB):
  1509. *
  1510. * Y3 Y2 Y1 Y0
  1511. * V0
  1512. * U0
  1513. *
  1514. * convert to 4 yuv555 words and lookup in xlate table
  1515. */
  1516. /* build each yuv-555 value by truncating
  1517. * y to 5 bits and adding the common u and v bits,
  1518. * look up to convert to rgb, and combine two pixels
  1519. * into one dword
  1520. */
  1521. dwTemp = dwYPixel & 0xff;
  1522. ubG = (BYTE)RANGE((dwTemp * 1192 - dwParam) / 1024, 0, 255);
  1523. dwTemp <<= 8;
  1524. ubR = pXlate[ dwTemp | bVPixel];
  1525. ubB = pXlate[(dwTemp | bUPixel) + 65536];
  1526. dwPixel = (ubR & 0xf8) << 7 | (ubG & 0xf8) << 2 | (ubB & 0xf8) >> 3;
  1527. // next pixel
  1528. dwTemp = dwYPixel & 0xff00;
  1529. ubR = pXlate[ dwTemp | bVPixel];
  1530. ubB = pXlate[(dwTemp | bUPixel) + 65536];
  1531. ubG = (BYTE)RANGE(((dwTemp >> 8) * 1192 - dwParam) / 1024, 0, 255);
  1532. dwPixel |= (ubR & 0xf8) << 23 | (ubG & 0xf8) << 18 | (ubB & 0xf8) << 13;
  1533. /* write two pixels to destination */
  1534. *pDst++ = dwPixel;
  1535. /* build each yuv-655 value by truncating
  1536. * y to 5 bits and adding the common u and v bits,
  1537. * look up to convert to rgb, and combine two pixels
  1538. * into one dword
  1539. */
  1540. dwTemp = (dwYPixel & 0xff0000) >> 8;
  1541. ubR = pXlate[ dwTemp | bVPixel];
  1542. ubB = pXlate[(dwTemp | bUPixel) + 65536];
  1543. ubG = (BYTE)RANGE(((dwTemp >> 8) * 1192 - dwParam) / 1024, 0, 255);
  1544. dwPixel = (ubR & 0xf8) << 7 | (ubG & 0xf8) << 2 | (ubB & 0xf8) >> 3;
  1545. // next pixel
  1546. dwTemp = (dwYPixel & 0xff000000) >> 16;
  1547. ubR = pXlate[ dwTemp | bVPixel];
  1548. ubB = pXlate[(dwTemp | bUPixel) + 65536];
  1549. ubG = (BYTE)RANGE((((dwTemp >> 8) & 0xff) * 1192 - dwParam) / 1024, 0, 255);
  1550. dwPixel |= (ubR & 0xf8) << 23 | (ubG & 0xf8) << 18 | (ubB & 0xf8) << 13;
  1551. /* write two pixels to destination */
  1552. *pDst++ = dwPixel;
  1553. } // loop per 4 pixels
  1554. if ((i & 0x3) != 0x03)
  1555. {
  1556. pUSrc -= UVRowInc;
  1557. pVSrc -= UVRowInc;
  1558. }
  1559. /* move dest pointer back to next line */
  1560. pDst -= RowInc;
  1561. } // loop per row
  1562. }
  1563. #else //COLOR_MODIFY
  1564. VOID
  1565. YUV9ToRGB(
  1566. PINSTINFO pinst,
  1567. LPBITMAPINFOHEADER lpbiInput,
  1568. LPVOID lpInput,
  1569. LPBITMAPINFOHEADER lpbiOutput,
  1570. LPVOID lpOutput
  1571. )
  1572. {
  1573. int RowInc;
  1574. int UVRowInc;
  1575. int i, j;
  1576. DWORD uv55, dwPixel, dwYPixel;
  1577. int WidthBytes; // width of one line in BYTES
  1578. BOOL bDuplicate = FALSE;
  1579. PDWORD pYSrc, pDst;
  1580. PBYTE pUSrc, pVSrc;
  1581. BYTE bUPixel, bVPixel;
  1582. int Height, Width;
  1583. PWORD pXlate;
  1584. int InputHeight;
  1585. Height = lpbiInput->biHeight;
  1586. InputHeight = Height;
  1587. Width = lpbiInput->biWidth;
  1588. WidthBytes = Width*2; // size of (input and output) line
  1589. pXlate = pinst->pXlate;
  1590. /*
  1591. * adjust the destination to point to the start of the last line,
  1592. * and work upwards (to flip vertically into DIB format)
  1593. */
  1594. pDst = (PDWORD) ( (LPBYTE)lpOutput + (Height - 1) * WidthBytes );
  1595. pYSrc = (PDWORD) lpInput;
  1596. #if 1
  1597. pVSrc = (PBYTE) ( (LPBYTE)lpInput + Height * Width);
  1598. pUSrc = (PBYTE) ( (LPBYTE)lpInput + Height * Width + Height * Width / 16);
  1599. #else
  1600. pVSrc = (PBYTE) lpInput + Height * Width;
  1601. pUSrc = (PBYTE) lpInput + Height * Width + Height * Width / 16;
  1602. #endif
  1603. /*
  1604. * calculate the amount to adjust pDst by at the end of one line
  1605. * of copying. At this point we are at the end of line N. We need
  1606. * to move to the start of line N-1.
  1607. */
  1608. RowInc = WidthBytes + (Width * 2);
  1609. /* remember we are adding to a DWORD pointer */
  1610. RowInc /= sizeof(DWORD);
  1611. UVRowInc = Width / 4;
  1612. UVRowInc /= sizeof(BYTE);
  1613. /* loop copying each scanline */
  1614. for (i = 0; i < InputHeight; i++) {
  1615. /* loop copying two pixels at a time */
  1616. for (j = Width ; j > 0; j -= 4) {
  1617. /*
  1618. * get four pixels and convert to 15-bpp YUV
  1619. */
  1620. dwYPixel = *pYSrc++;
  1621. bUPixel = *pUSrc++;
  1622. bVPixel = *pVSrc++;
  1623. /*
  1624. * dwY(U or V)Pixel now has four pixels, in this layout (MSB..LSB):
  1625. *
  1626. * Y3 Y2 Y1 Y0
  1627. * V0
  1628. * U0
  1629. *
  1630. * convert to 4 yuv555 words and lookup in xlate table
  1631. */
  1632. /* get common u0 and v0 components to lower 10 bits */
  1633. uv55 = ((bUPixel & 0xf8) << 2) |
  1634. ((bVPixel & 0xf8) >> 3);
  1635. /* build each yuv-555 value by truncating
  1636. * y to 5 bits and adding the common u and v bits,
  1637. * look up to convert to rgb, and combine two pixels
  1638. * into one dword
  1639. */
  1640. dwPixel = pXlate[ ((dwYPixel & 0xf8) << 7) | uv55 ] |
  1641. (pXlate[((dwYPixel & 0xf800) >> 1) | uv55 ] << 16);
  1642. /* write two pixels to destination */
  1643. *pDst++ = dwPixel;
  1644. /* build each yuv-655 value by truncating
  1645. * y to 5 bits and adding the common u and v bits,
  1646. * look up to convert to rgb, and combine two pixels
  1647. * into one dword
  1648. */
  1649. dwPixel = pXlate[ ((dwYPixel & 0xf80000) >> 9) | uv55 ] |
  1650. (pXlate[((dwYPixel & 0xf8000000) >> 17) | uv55 ] << 16);
  1651. /* write two pixels to destination */
  1652. *pDst++ = dwPixel;
  1653. } // loop per 4 pixels
  1654. if ((i & 0x3) != 0x03)
  1655. {
  1656. pUSrc -= UVRowInc;
  1657. pVSrc -= UVRowInc;
  1658. }
  1659. /* move dest pointer back to next line */
  1660. pDst -= RowInc;
  1661. } // loop per row
  1662. }
  1663. #endif//COLOR_MODIFY
  1664. #endif//TOSHIBA
  1665. VOID FreeXlate(PINSTINFO pinst)
  1666. {
  1667. GlobalFree(GlobalHandle(pinst->pXlate));
  1668. pinst->pXlate = NULL;
  1669. }