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.

1466 lines
48 KiB

  1. /*
  2. * Microsoft YUV Codec UyVy -> rgb conversion functions
  3. *
  4. * Copyright (c) Microsoft Corporation 1993
  5. * All Rights Reserved
  6. *
  7. */
  8. #include <windows.h>
  9. #include <windowsx.h>
  10. #include <mmsystem.h>
  11. #include "msyuv.h"
  12. #include "rgb8lut.h" // can only be included once
  13. /*
  14. * This module provides translation from YUV into RGB. It translates
  15. * from 8-bit YUV 4:2:2 (as provided by the Spigot video capture driver)
  16. * or 7-bit YUV 4:1:1 (as provided by the Bravado driver) into 16-bit RGB555
  17. * or RGB565. All versions use a look-up table built using YUVToRGB555
  18. * or YUVToRGB565
  19. */
  20. #define RANGE(x, lo, hi) max(lo, min(hi, x))
  21. /*
  22. * Convert a YUV colour into a 15-bit RGB colour.
  23. *
  24. * The input Y is in the range 16..235; the input U and V components
  25. * are in the range -128..+127. The conversion equations for this are
  26. * (according to CCIR 601):
  27. *
  28. * R = Y + 1.371 V
  29. * G = Y - 0.698 V - 0.336 U
  30. * B = Y + 1.732 U
  31. *
  32. * To avoid floating point, we scale all values by 1024.
  33. *
  34. * The resulting RGB values are in the range 16..235: we truncate these to
  35. * 5 bits each. and return a WORD containing 5-bits each for R, G and B
  36. * with bit 15 set to 0.
  37. */
  38. WORD
  39. YUVToRGB555(int y, int u, int v)
  40. {
  41. int ScaledY = RANGE(y, 16, 235) * 1024;
  42. int red, green, blue;
  43. red = RANGE((ScaledY + (1404 * v)) / 1024, 0, 255);
  44. green = RANGE((ScaledY - ( 715 * v) - (344 * u)) / 1024, 0, 255);
  45. blue = RANGE((ScaledY + (1774 * u)) / 1024, 0, 255);
  46. return (WORD) (((red & 0xf8) << 7) | ((green & 0xf8) << 2) | ((blue & 0xf8) >>3) );
  47. }
  48. // same as above but converts to RGB565 instead
  49. WORD
  50. YUVToRGB565(int y, int u, int v)
  51. {
  52. int ScaledY = RANGE(y, 16, 235) * 1024;
  53. int red, green, blue;
  54. red = RANGE((ScaledY + (1404 * v)) / 1024, 0, 255);
  55. green = RANGE((ScaledY - ( 715 * v) - (344 * u)) / 1024, 0, 255);
  56. blue = RANGE((ScaledY + (1774 * u)) / 1024, 0, 255);
  57. return (WORD) (((red & 0xf8) << 8) | ((green & 0xfc) << 3) | ((blue & 0xf8) >>3) );
  58. }
  59. /* YUV 4:2:2 support ------------------------------------------ */
  60. /*
  61. * The captured data is in YUV 4:2:2, 8-bits per sample.
  62. * The data is laid out in alternating Y-U-Y-V-Y-U-Y-V format. Thus
  63. * every DWORD contains two complete pixels, in the
  64. * form (msb..lsb) V..Y1..U..Y0
  65. * All 3 components (y, u and v) are all unsigned 8-bit values in the range
  66. * 16..235.
  67. *
  68. * We have to double scan lines for >= 480 line formats since
  69. * the hardware only captured one field maximum.
  70. *
  71. */
  72. LPVOID BuildUYVYToRGB32( PINSTINFO pinst )
  73. {
  74. LPVOID pXlate;
  75. long y, u, v;
  76. // need 5 lookup tables to do the conversions, each is 256 entries long,
  77. // and each contains short words.
  78. //
  79. short * yip; // Y impact
  80. short * vrip; // red's V impact
  81. short * vgip; // green's V impact
  82. short * ugip; // green's U impact
  83. short * ubip; // blue's U impact
  84. dprintf2((TEXT("In BuildUYVYToRGB32\n")));
  85. if (pinst->pXlate != NULL) {
  86. return(pinst->pXlate);
  87. }
  88. dprintf1((TEXT("Allocate memory and building table for BuildUYVYToRGB32\n")));
  89. /*
  90. * allocate a table big enough for 5 256-byte arrays
  91. */
  92. pXlate = VirtualAlloc (NULL, 5 * 256 * sizeof( short ), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
  93. if(!pXlate)
  94. return pXlate;
  95. // set the table offsets
  96. //
  97. yip = pXlate;
  98. vrip = yip + 256;
  99. vgip = vrip + 256;
  100. ugip = vgip + 256;
  101. ubip = ugip + 256;
  102. // setup Y impact, etc
  103. //
  104. for( y = 0 ; y < 256 ; y++ )
  105. {
  106. yip[y] = (short)( ( 1.164 * ( y - 16L ) / 1.0 ) + 0 );
  107. }
  108. for( v = 0 ; v < 256 ; v++ )
  109. {
  110. vrip[v] = (short)( 1.596 * ( v - 128L ) / 1.0 );
  111. vgip[v] = (short)( -0.813 * ( v - 128L ) / 1.0 );
  112. }
  113. for( u = 0 ; u < 256 ; u++ )
  114. {
  115. ugip[u] = (short)( -0.391 * ( u - 128L ) / 1.0 );
  116. ubip[u] = (short)( 2.018 * ( u - 128L ) / 1.0 );
  117. }
  118. return(pXlate);
  119. }
  120. /*
  121. * build a translation table to translate between YUV and RGB555.
  122. *
  123. * This builds a lookup table with 32k 1-word entries: truncate the YUV
  124. * to 15bits (5-5-5) and look-up in this xlate table to produce the
  125. * 15-bit rgb value.
  126. */
  127. LPVOID BuildUYVYToRGB555(PINSTINFO pinst)
  128. {
  129. LPVOID pXlate;
  130. LPWORD pRGB555;
  131. WORD w;
  132. dprintf2((TEXT("In BuildUYVYToRGB555\n")));
  133. if (pinst->pXlate != NULL) {
  134. return(pinst->pXlate);
  135. }
  136. dprintf2((TEXT("Allocate memory and building table for BuildUYVYToRGB555\n")));
  137. /*
  138. * allocate a table big enough for 32k 2-byte entries
  139. */
  140. pXlate = VirtualAlloc (NULL, 2 * 32 * 1024, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
  141. if(!pXlate)
  142. return pXlate;
  143. pRGB555 = (LPWORD)pXlate;
  144. /*
  145. * build a 15-bit yuv lookup table by stepping through each entry,
  146. * converting the yuv index to rgb and storing at that index. The index
  147. * to this table is a 15-bit value with the y component in bits 14..10,
  148. * u in bits 9..5 and v in bits 4..0. Note that the y component is unsigned,
  149. * whereas the u and v components are signed.
  150. */
  151. for (w = 0; w < 32*1024; w++) {
  152. /*
  153. * the YUVtoRGB55 conversion function takes values 0..255 for y,
  154. * and -128..+127 for u and v. Pick out the relevant bits of the
  155. * index for this cell, and shift to get values in this range.
  156. * Subtract 128 from u and v to shift from 0..255 to -128..+127
  157. */
  158. *pRGB555++ = YUVToRGB555(
  159. (w & 0x7c00) >> 7,
  160. ((w & 0x3e0) >> 2) - 128,
  161. ((w & 0x1f) << 3) - 128
  162. );
  163. }
  164. return(pXlate);
  165. }
  166. /*
  167. * build a translation table to translate between YUV and RGB 5-6-5
  168. *
  169. * This builds a lookup table with 32k 1-word entries: truncate the YUV
  170. * to 15bits (5-5-5) and look-up in this xlate table to produce the
  171. * 16-bit rgb value.
  172. */
  173. LPVOID BuildUYVYToRGB565(PINSTINFO pinst)
  174. {
  175. LPVOID pXlate;
  176. LPWORD pRGB;
  177. WORD w;
  178. dprintf2((TEXT("In BuildUYVYToRGB565\n")));
  179. if (pinst->pXlate != NULL) {
  180. return(pinst->pXlate);
  181. }
  182. dprintf2((TEXT("Allocate memory and building table for BuildUYVYToRGB565\n")));
  183. /*
  184. * allocate a table big enough for 32k 2-byte entries
  185. */
  186. pXlate = VirtualAlloc (NULL, 2 * 32 * 1024, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
  187. if(!pXlate)
  188. return pXlate;
  189. pRGB = (LPWORD)pXlate;
  190. /*
  191. * build a 15-bit yuv lookup table by stepping through each entry,
  192. * converting the yuv index to rgb and storing at that index. The index
  193. * to this table is a 15-bit value with the y component in bits 14..10,
  194. * u in bits 9..5 and v in bits 4..0. Note that the y component is unsigned,
  195. * whereas the u and v components are signed.
  196. */
  197. for (w = 0; w < 32*1024; w++) {
  198. /*
  199. * the YUVtoRGB conversion function takes values 0..255 for y,
  200. * and -128..+127 for u and v. Pick out the relevant bits of the
  201. * index for this cell, and shift to get values in this range.
  202. * Subtract 128 from u and v to shift from 0..255 to -128..+127
  203. */
  204. *pRGB++ = YUVToRGB565(
  205. (w & 0x7c00) >> 7,
  206. ((w & 0x3e0) >> 2) - 128,
  207. ((w & 0x1f) << 3) - 128
  208. );
  209. }
  210. return(pXlate);
  211. }
  212. /*
  213. * build a translation table to translate between YUV and RGB8
  214. *
  215. */
  216. LPVOID BuildUYVYToRGB8(PINSTINFO pinst)
  217. {
  218. dprintf2((TEXT("In BuildUYVYToRGB8: no dynamically built table. Return NULL;\n")));
  219. return(0);
  220. }
  221. /*
  222. * translate YUV 4:2:2 into 16-bit RGB using a lookup table. Flip vertically
  223. * into DIB format during processing. Double scanlines for formats of
  224. * 480 lines or greater. Produces 565 or 555 format RGB depending on the
  225. * xlate table.
  226. */
  227. VOID
  228. UYVYToRGB16(
  229. PINSTINFO pinst,
  230. LPBITMAPINFOHEADER lpbiInput,
  231. LPVOID lpInput,
  232. LPBITMAPINFOHEADER lpbiOutput,
  233. LPVOID lpOutput
  234. )
  235. {
  236. int RowInc;
  237. int i, j;
  238. DWORD uv55, dwPixel;
  239. int WidthBytes; // width of one line in BYTES
  240. BOOL bDuplicate = FALSE;
  241. PDWORD pSrc, pDst;
  242. int Height, Width;
  243. PWORD pXlate;
  244. int InputHeight;
  245. Height = abs(lpbiInput->biHeight);
  246. InputHeight = Height;
  247. Width = lpbiInput->biWidth;
  248. WidthBytes = Width * 2 ;
  249. ASSERT(lpbiInput->biBitCount / 8 == 2);
  250. pXlate = pinst->pXlate;
  251. pSrc = (PDWORD) lpInput;
  252. dprintf3(("UYVYToRGB: %s %dx%d; %s %dx%dx%d=%d; %s %dx%dx%d=%d\n",
  253. pinst->bRGB565?"RGB565" : "RGB555",
  254. Width, Height,
  255. (PCHAR) &lpbiInput->biCompression,
  256. lpbiInput->biWidth, lpbiInput->biHeight, lpbiInput->biBitCount, lpbiInput->biSizeImage,
  257. lpbiOutput->biCompression == 0 ? "RGB": lpbiOutput->biCompression == BI_BITFIELDS ? "BITF" : (PCHAR) &lpbiOutput->biCompression,
  258. lpbiOutput->biWidth, lpbiOutput->biHeight, lpbiOutput->biBitCount, lpbiOutput->biSizeImage));
  259. ASSERT((lpbiOutput->biWidth == lpbiInput->biWidth) && abs(lpbiOutput->biHeight) == abs(lpbiInput->biHeight));
  260. /*
  261. * calculate the amount to adjust pDst by at the end of one line
  262. * of copying. At this point we are at the end of line N. We need
  263. * to move to the start of line N-1.
  264. */
  265. RowInc = WidthBytes * 2; // two lines!!
  266. /* remember we are adding to a DWORD pointer */
  267. RowInc /= sizeof(DWORD);
  268. if(lpbiOutput->biCompression == FOURCC_UYVY ||
  269. lpbiOutput->biCompression == FOURCC_YUY2 ||
  270. lpbiOutput->biCompression == FOURCC_YVYU ) {
  271. pDst = (PDWORD) lpOutput;
  272. memcpy(pDst, pSrc, Width * Height * lpbiInput->biBitCount / 8); // Top down
  273. } else {
  274. // Output BI_RGB or BI_BITFIELD
  275. // UVYV->RGB; +RGB->Flip
  276. if(lpbiOutput->biHeight >= 0)
  277. pDst = (PDWORD) ( (LPBYTE)lpOutput + (Height - 1) * WidthBytes );
  278. else
  279. pDst = (PDWORD) lpOutput;
  280. //
  281. // UyVy
  282. //
  283. if(pinst->dwFormat == FOURCC_UYVY) {
  284. /* loop copying each scanline */
  285. for (i = InputHeight; i > 0; i--) {
  286. /* loop copying two pixels at a time */
  287. for (j = Width ; j > 0; j -= 2) {
  288. /*
  289. * get two pixels and convert to 15-bpp YUV
  290. */
  291. dwPixel = *pSrc++;
  292. /*
  293. * Convert UYVY (0x y1 V y0 U) to YUYV (0x V y1 U y0) in which the translation table is built for.
  294. */
  295. #if defined(_X86_)
  296. _asm {
  297. // FourCC
  298. // dwPixel 0x y1 V y0 U U0 Y0 V0 Y1
  299. mov eax, dwPixel // 0x y1 V y0 U U0 Y0 V0 Y1
  300. bswap eax // 0x U y0 V y1 Y1 V0 Y0 U0
  301. rol eax, 16 // 0x V y1 U y0 Y0 U0 Y1 V0
  302. mov dwPixel, eax
  303. }
  304. #else
  305. dwPixel = (((dwPixel & 0xff00ff00) >> 8) | ((dwPixel & 0x00ff00ff) << 8));
  306. #endif
  307. /*
  308. * dwPixel now has two pixels, in this layout (MSB..LSB):
  309. *
  310. * V Y1 U Y0
  311. *
  312. * convert to 2 yuv555 words and lookup in xlate table
  313. */
  314. /* get common u and v components to lower 10 bits */ // 9 8 7 6 5 4 3 2 1 0
  315. uv55 = ((dwPixel & 0xf8000000) >> 27) | ((dwPixel & 0x0000f800) >> 6); // U7U6:U5U4U3 V7:V6V5V4V3
  316. /* build each yuv-655 value by truncating
  317. * y to 5 bits and adding the common u and v bits,
  318. * look up to convert to rgb, and combine two pixels
  319. * into one dword
  320. */ // f e d c b a 9 8 7 6 5 4 3 2 1 0
  321. dwPixel = pXlate[((dwPixel & 0x000000f8) << 7) | uv55 ] | // 0Y7Y6Y5:Y4Y3 U7U6:U5U4U3 V7:V6V5V4V3
  322. (pXlate[((dwPixel & 0x00f80000) >> 9) | uv55 ] << 16); // 0Y7Y6Y5:Y4Y3 U7U6:U5U4U3 V7:V6V5V4V3
  323. /* write two pixels to destination */
  324. *pDst++ = dwPixel;
  325. } // loop per 2 pixels
  326. /*
  327. * bottom up need re-adjust its pointer by
  328. * moving dest pointer back to next line
  329. */
  330. if(lpbiOutput->biHeight >= 0) {
  331. pDst -= RowInc;
  332. }
  333. }
  334. //
  335. // yUyV
  336. //
  337. } else if(pinst->dwFormat == FOURCC_YUY2) {
  338. /* loop copying each scanline */
  339. for (i = InputHeight; i > 0; i--) {
  340. /* loop copying two pixels at a time */
  341. for (j = Width ; j > 0; j -= 2) {
  342. /*
  343. * get two pixels and convert to 15-bpp YUV
  344. */
  345. dwPixel = *pSrc++;
  346. // We are already in YUYV (0x V y1 U y0) format.
  347. /* get common u and v components to lower 10 bits */ // 9 8 7 6 5 4 3 2 1 0
  348. uv55 = ((dwPixel & 0xf8000000) >> 27) | ((dwPixel & 0x0000f800) >> 6); // U7U6:U5U4U3 V7:V6V5V4V3
  349. /* build each yuv-655 value by truncating
  350. * y to 5 bits and adding the common u and v bits,
  351. * look up to convert to rgb, and combine two pixels
  352. * into one dword
  353. */ // f e d c b a 9 8 7 6 5 4 3 2 1 0
  354. dwPixel = pXlate[((dwPixel & 0x000000f8) << 7) | uv55 ] | // 0Y7Y6Y5:Y4Y3 U7U6:U5U4U3 V7:V6V5V4V3
  355. (pXlate[((dwPixel & 0x00f80000) >> 9) | uv55 ] << 16); // 0Y7Y6Y5:Y4Y3 U7U6:U5U4U3 V7:V6V5V4V3
  356. /* write two pixels to destination */
  357. *pDst++ = dwPixel;
  358. } // loop per 2 pixels
  359. /*
  360. * bottom up need re-adjust its pointer by
  361. * moving dest pointer back to next line
  362. */
  363. if(lpbiOutput->biHeight >= 0) {
  364. pDst -= RowInc;
  365. }
  366. }
  367. //
  368. // yVyU
  369. //
  370. } else if(pinst->dwFormat == FOURCC_YVYU) {
  371. /* loop copying each scanline */
  372. for (i = InputHeight; i > 0; i--) {
  373. /* loop copying two pixels at a time */
  374. for (j = Width ; j > 0; j -= 2) {
  375. /*
  376. * get two pixels and convert to 15-bpp YUV
  377. */
  378. dwPixel = *pSrc++;
  379. /*
  380. * Convert yVyU (0x U y1 V y0) to YUYV (0x V y1 U y0) in which the translation table is built for.
  381. */
  382. #if defined(_X86_)
  383. _asm {
  384. // FourCC
  385. // dwPixel 0x U y1 V y0
  386. mov eax, dwPixel // 0x U y1 V y0
  387. bswap eax // 0x y0 V y1 U
  388. rol eax, 8 // 0x V y1 U y0
  389. mov dwPixel, eax
  390. }
  391. #else
  392. // y0 and y1 stay and swap U and V
  393. dwPixel = (dwPixel & 0x00ff00ff) | ((dwPixel & 0x0000ff00) << 16) | ((dwPixel & 0xff000000) >> 16);
  394. #endif
  395. /* get common u and v components to lower 10 bits */ // 9 8 7 6 5 4 3 2 1 0
  396. uv55 = ((dwPixel & 0xf8000000) >> 27) | ((dwPixel & 0x0000f800) >> 6); // U7U6:U5U4U3 V7:V6V5V4V3
  397. /* build each yuv-655 value by truncating
  398. * y to 5 bits and adding the common u and v bits,
  399. * look up to convert to rgb, and combine two pixels
  400. * into one dword
  401. */ // f e d c b a 9 8 7 6 5 4 3 2 1 0
  402. dwPixel = pXlate[((dwPixel & 0x000000f8) << 7) | uv55 ] | // 0Y7Y6Y5:Y4Y3 U7U6:U5U4U3 V7:V6V5V4V3
  403. (pXlate[((dwPixel & 0x00f80000) >> 9) | uv55 ] << 16); // 0Y7Y6Y5:Y4Y3 U7U6:U5U4U3 V7:V6V5V4V3
  404. /* write two pixels to destination */
  405. *pDst++ = dwPixel;
  406. } // loop per 2 pixels
  407. /*
  408. * bottom up need re-adjust its pointer by
  409. * moving dest pointer back to next line
  410. */
  411. if(lpbiOutput->biHeight >= 0) {
  412. pDst -= RowInc;
  413. }
  414. }
  415. }
  416. }
  417. }
  418. /*
  419. * translate YUV 4:2:2 into 8-bit RGB using a lookup table.
  420. * i.e. 0x Y1:V:Y0:U -> ox index1;index0
  421. */
  422. VOID
  423. UYVYToRGB8(
  424. PINSTINFO pinst,
  425. LPBITMAPINFOHEADER lpbiInput,
  426. LPVOID lpInput,
  427. LPBITMAPINFOHEADER lpbiOutput,
  428. LPVOID lpOutput
  429. )
  430. {
  431. register dwPixel;
  432. int i, j;
  433. int SrcRawInc, DstRawInc, Dst3RawInc;
  434. PDWORD pSrc, pSrc1; // Every 32bit UYVY
  435. PWORD pDst, pDst1; // Convert to two 8bit RGB8
  436. int Height, Width;
  437. int InputHeight;
  438. unsigned char y0, y1, y2, y3,
  439. u0, u1,
  440. v0, v1;
  441. unsigned long yuv0, yuv1;
  442. Height = abs(lpbiInput->biHeight);
  443. InputHeight = Height;
  444. Width = lpbiInput->biWidth;
  445. dprintf3(("UYVYToRGB8: %dx%d; %s %dx%dx%d=%d; %s %dx%dx%d=%d\n",
  446. Width, Height,
  447. (PCHAR) &lpbiInput->biCompression,
  448. lpbiInput->biWidth, lpbiInput->biHeight, lpbiInput->biBitCount, lpbiInput->biSizeImage,
  449. lpbiOutput->biCompression == 0 ? "RGB": lpbiOutput->biCompression == BI_BITFIELDS ? "BITF" : (PCHAR) &lpbiOutput->biCompression,
  450. lpbiOutput->biWidth, lpbiOutput->biHeight, lpbiOutput->biBitCount, lpbiOutput->biSizeImage));
  451. ASSERT(lpbiInput->biBitCount == 16 && lpbiOutput->biBitCount == 8);
  452. ASSERT((lpbiOutput->biWidth == lpbiInput->biWidth) && abs(lpbiOutput->biHeight) == abs(lpbiInput->biHeight));
  453. ASSERT(( lpbiOutput->biWidth % 8 == 0 )); // Align with pairs of UYVY:UYVY
  454. ASSERT(( lpbiOutput->biHeight % 2 == 0 )); // Even number of lines
  455. /*
  456. * calculate the amount to adjust pDst by at the end of one line of copying.
  457. */
  458. // 2bytes per pixel; pSrc is PDWORD
  459. SrcRawInc = Width * 2 / sizeof(DWORD);
  460. // 1 byte per pixel; pDst is PWORD
  461. DstRawInc = Width * 1 / sizeof(WORD);
  462. Dst3RawInc = 3 * DstRawInc;
  463. pSrc = (PDWORD) lpInput;
  464. pSrc1 = pSrc + SrcRawInc;
  465. // UVYV->RGB8; same sign:flip.
  466. if(lpbiOutput->biHeight >= 0) {
  467. pDst = (PWORD) ( (LPBYTE)lpOutput + (Height - 1) * Width/sizeof(BYTE) );
  468. pDst1 = (PWORD) ( (LPBYTE)lpOutput + (Height - 2) * Width/sizeof(BYTE) );
  469. } else {
  470. pDst = (PWORD) lpOutput;
  471. pDst1 = (PWORD) ((LPBYTE)lpOutput+Width/sizeof(BYTE));
  472. }
  473. if(pinst->dwFormat == FOURCC_UYVY) {
  474. // loop copying two scanline
  475. for (i = InputHeight; i > 0; i -= 2) {
  476. // loop copying four (% 8) pixels at a time
  477. for (j = Width ; j > 0; j -= 4) {
  478. //
  479. // Translate TopLeft, TopRight
  480. //
  481. dwPixel = *pSrc++;
  482. // Pixel is in this format: Y1:V:Y0:U
  483. y0 = (dwPixel & 0x0000ff00) >> 8;
  484. y1 = (dwPixel & 0xff000000) >> 24;
  485. u0 = (dwPixel & 0x000000ff);
  486. v0 = (dwPixel & 0x00ff0000) >> 16;
  487. dwPixel = *pSrc++;
  488. y2 = (dwPixel & 0x0000ff00) >> 8;
  489. y3 = (dwPixel & 0xff000000) >> 24;
  490. u1 = (dwPixel & 0x000000ff);
  491. v1 = (dwPixel & 0x00ff0000) >> 16;
  492. yuv0 = yLUT_1[y1+2] | yLUT_0[y0+10] | cLUT_B0[u0] | cLUT_R0[v0];
  493. yuv1 = yLUT_1[y3+0] | yLUT_0[y2+8] | cLUT_B0[u1+4] | cLUT_R0[v1+4];
  494. *pDst++ = (WORD) yuv0;
  495. *pDst++ = (WORD) yuv1;
  496. //
  497. // Translate BottomLeft, BottomRight
  498. //
  499. dwPixel = *pSrc1++;
  500. // Pixel is in this format: Y1:V:Y0:U
  501. y0 = (dwPixel & 0x0000ff00) >> 8;
  502. y1 = (dwPixel & 0xff000000) >> 24;
  503. u0 = (dwPixel & 0x000000ff);
  504. v0 = (dwPixel & 0x00ff0000) >> 16;
  505. dwPixel = *pSrc1++;
  506. y2 = (dwPixel & 0x0000ff00) >> 8;
  507. y3 = (dwPixel & 0xff000000) >> 24;
  508. u1 = (dwPixel & 0x000000ff);
  509. v1 = (dwPixel & 0x00ff0000) >> 16;
  510. yuv0 = yLUT_1[y1+0] | yLUT_0[y0+8] | cLUT_B0[u0+4] | cLUT_R0[v0+4];
  511. yuv1 = yLUT_1[y3+2] | yLUT_0[y2+10] | cLUT_B0[u1+0] | cLUT_R0[v1+0];
  512. *pDst1++ = (WORD) yuv0;
  513. *pDst1++ = (WORD) yuv1;
  514. } // 2 * 4 pixel per loops
  515. /*
  516. * bottom up need re-adjust its pointer by
  517. * moving dest pointer back to next line
  518. */
  519. if (lpbiOutput->biHeight >= 0) {
  520. pDst -= Dst3RawInc;
  521. pDst1 -= Dst3RawInc;
  522. } else {
  523. pDst += DstRawInc;
  524. pDst1 += DstRawInc;
  525. }
  526. pSrc += SrcRawInc;
  527. pSrc1 += SrcRawInc;
  528. } // 2 lines per loop
  529. } else if(pinst->dwFormat == FOURCC_YUY2) { // YUY2
  530. // loop copying two scanline
  531. for (i = InputHeight; i > 0; i -= 2) {
  532. // loop copying four (% 8) pixels at a time
  533. for (j = Width ; j > 0; j -= 4) {
  534. //
  535. // Translate TopLeft, TopRight
  536. //
  537. dwPixel = *pSrc++;
  538. // Pixel is in this format: V:Y1:U:Y0
  539. u0 = (dwPixel & 0x0000ff00) >> 8;
  540. v0 = (dwPixel & 0xff000000) >> 24;
  541. y0 = (dwPixel & 0x000000ff);
  542. y1 = (dwPixel & 0x00ff0000) >> 16;
  543. dwPixel = *pSrc++;
  544. u1 = (dwPixel & 0x0000ff00) >> 8;
  545. v1 = (dwPixel & 0xff000000) >> 24;
  546. y2 = (dwPixel & 0x000000ff);
  547. y3 = (dwPixel & 0x00ff0000) >> 16;
  548. yuv0 = yLUT_1[y1+2] | yLUT_0[y0+10] | cLUT_B0[u0] | cLUT_R0[v0];
  549. yuv1 = yLUT_1[y3+0] | yLUT_0[y2+8] | cLUT_B0[u1+4] | cLUT_R0[v1+4];
  550. *pDst++ = (WORD) yuv0;
  551. *pDst++ = (WORD) yuv1;
  552. //
  553. // Translate BottomLeft, BottomRight
  554. //
  555. dwPixel = *pSrc1++;
  556. // Pixel is in this format: V:Y1:U:Y0
  557. u0 = (dwPixel & 0x0000ff00) >> 8;
  558. v0 = (dwPixel & 0xff000000) >> 24;
  559. y0 = (dwPixel & 0x000000ff);
  560. y1 = (dwPixel & 0x00ff0000) >> 16;
  561. dwPixel = *pSrc1++;
  562. u1 = (dwPixel & 0x0000ff00) >> 8;
  563. v1 = (dwPixel & 0xff000000) >> 24;
  564. y2 = (dwPixel & 0x000000ff);
  565. y3 = (dwPixel & 0x00ff0000) >> 16;
  566. yuv0 = yLUT_1[y1+0] | yLUT_0[y0+8] | cLUT_B0[u0+4] | cLUT_R0[v0+4];
  567. yuv1 = yLUT_1[y3+2] | yLUT_0[y2+10] | cLUT_B0[u1+0] | cLUT_R0[v1+0];
  568. *pDst1++ = (WORD) yuv0;
  569. *pDst1++ = (WORD) yuv1;
  570. } // 2 * 4 pixel per loops
  571. /*
  572. * bottom up need re-adjust its pointer by
  573. * moving dest pointer back to next line
  574. */
  575. if (lpbiOutput->biHeight >= 0) {
  576. pDst -= Dst3RawInc;
  577. pDst1 -= Dst3RawInc;
  578. } else {
  579. pDst += DstRawInc;
  580. pDst1 += DstRawInc;
  581. }
  582. pSrc += SrcRawInc;
  583. pSrc1 += SrcRawInc;
  584. } // 2 lines per loop
  585. } else if(pinst->dwFormat == FOURCC_YVYU) {
  586. // loop copying two scanline
  587. for (i = InputHeight; i > 0; i -= 2) {
  588. // loop copying four (% 8) pixels at a time
  589. for (j = Width ; j > 0; j -= 4) {
  590. //
  591. // Translate TopLeft, TopRight
  592. //
  593. dwPixel = *pSrc++;
  594. // Pixel is in this format: U:Y1:V:Y0
  595. v0 = (dwPixel & 0x0000ff00) >> 8;
  596. u0 = (dwPixel & 0xff000000) >> 24;
  597. y0 = (dwPixel & 0x000000ff);
  598. y1 = (dwPixel & 0x00ff0000) >> 16;
  599. dwPixel = *pSrc++;
  600. v1 = (dwPixel & 0x0000ff00) >> 8;
  601. u1 = (dwPixel & 0xff000000) >> 24;
  602. y2 = (dwPixel & 0x000000ff);
  603. y3 = (dwPixel & 0x00ff0000) >> 16;
  604. yuv0 = yLUT_1[y1+2] | yLUT_0[y0+10] | cLUT_B0[u0] | cLUT_R0[v0];
  605. yuv1 = yLUT_1[y3+0] | yLUT_0[y2+8] | cLUT_B0[u1+4] | cLUT_R0[v1+4];
  606. *pDst++ = (WORD) yuv0;
  607. *pDst++ = (WORD) yuv1;
  608. //
  609. // Translate BottomLeft, BottomRight
  610. //
  611. dwPixel = *pSrc1++;
  612. // Pixel is in this format: U:Y1:V:Y0
  613. v0 = (dwPixel & 0x0000ff00) >> 8;
  614. u0 = (dwPixel & 0xff000000) >> 24;
  615. y0 = (dwPixel & 0x000000ff);
  616. y1 = (dwPixel & 0x00ff0000) >> 16;
  617. dwPixel = *pSrc1++;
  618. v1 = (dwPixel & 0x0000ff00) >> 8;
  619. u1 = (dwPixel & 0xff000000) >> 24;
  620. y2 = (dwPixel & 0x000000ff);
  621. y3 = (dwPixel & 0x00ff0000) >> 16;
  622. yuv0 = yLUT_1[y1+0] | yLUT_0[y0+8] | cLUT_B0[u0+4] | cLUT_R0[v0+4];
  623. yuv1 = yLUT_1[y3+2] | yLUT_0[y2+10] | cLUT_B0[u1+0] | cLUT_R0[v1+0];
  624. *pDst1++ = (WORD) yuv0;
  625. *pDst1++ = (WORD) yuv1;
  626. } // 2 * 4 pixel per loops
  627. /*
  628. * bottom up need re-adjust its pointer by
  629. * moving dest pointer back to next line
  630. */
  631. if (lpbiOutput->biHeight >= 0) {
  632. pDst -= Dst3RawInc;
  633. pDst1 -= Dst3RawInc;
  634. } else {
  635. pDst += DstRawInc;
  636. pDst1 += DstRawInc;
  637. }
  638. pSrc += SrcRawInc;
  639. pSrc1 += SrcRawInc;
  640. } // 2 lines per loop
  641. }
  642. }
  643. VOID
  644. UYVYToRGB32(
  645. PINSTINFO pinst,
  646. LPBITMAPINFOHEADER lpbiInput,
  647. LPVOID lpInput,
  648. LPBITMAPINFOHEADER lpbiOutput,
  649. LPVOID lpOutput
  650. )
  651. {
  652. int Height = abs( lpbiInput->biHeight );
  653. int Width = lpbiInput->biWidth;
  654. short U;
  655. short V;
  656. short y0, y1;
  657. short d;
  658. DWORD * pSrc = lpInput;
  659. BYTE * pDst = lpOutput;
  660. long WidthBytes = Width * 4; // ARGB = 4 bytes
  661. int i, j;
  662. DWORD dwYUV;
  663. long l;
  664. // set up the lookup table arrays
  665. //
  666. short * yip = pinst->pXlate;
  667. short * vrip = yip + 256;
  668. short * vgip = vrip + 256;
  669. short * ugip = vgip + 256;
  670. short * ubip = ugip + 256;
  671. // if just a straight copy
  672. //
  673. if(lpbiOutput->biCompression == FOURCC_UYVY ||
  674. lpbiOutput->biCompression == FOURCC_YUY2 ||
  675. lpbiOutput->biCompression == FOURCC_YVYU )
  676. {
  677. memcpy( pDst, pSrc, WidthBytes * Height ); // Top down
  678. return;
  679. }
  680. // flip around if necessary
  681. //
  682. if(lpbiOutput->biHeight >= 0)
  683. {
  684. pDst += (Height - 1) * WidthBytes;
  685. }
  686. if( pinst->dwFormat == FOURCC_UYVY ) // U0 Y0 V0 Y1 U2 Y2 V2 Y3
  687. {
  688. for (i = Height; i > 0; i--)
  689. {
  690. /* loop copying two pixels at a time */
  691. for (j = Width ; j > 0; j -= 2)
  692. {
  693. // get two YUV pixels at a time
  694. //
  695. dwYUV = *pSrc++; // U0 Y0 V0 Y1
  696. U = (short) ( dwYUV & 0xFF );
  697. dwYUV = dwYUV >> 8;
  698. y0 = yip[( dwYUV & 0xFF )];
  699. dwYUV = dwYUV >> 8;
  700. V = (short) ( dwYUV & 0xFF );
  701. dwYUV = dwYUV >> 8;
  702. y1 = yip[( dwYUV & 0xFF )];
  703. d = y0 + ubip[U]; // blue
  704. if( d < 0 ) d = 0;
  705. if( d > 255 ) d = 255;
  706. *pDst++ = (BYTE) d;
  707. d = y0 + ugip[U] + vgip[V]; // green
  708. if( d < 0 ) d = 0;
  709. if( d > 255 ) d = 255;
  710. *pDst++ = (BYTE) d;
  711. d = y0 + vrip[V]; // red
  712. if( d < 0 ) d = 0;
  713. if( d > 255 ) d = 255;
  714. *pDst++ = (BYTE) d;
  715. pDst++;
  716. d = y1 + ubip[U]; // blue
  717. if( d < 0 ) d = 0;
  718. if( d > 255 ) d = 255;
  719. *pDst++ = (BYTE) d;
  720. d = y1 + ugip[U] + vgip[V]; // green
  721. if( d < 0 ) d = 0;
  722. if( d > 255 ) d = 255;
  723. *pDst++ = (BYTE) d;
  724. d = y1 + vrip[V]; // red
  725. if( d < 0 ) d = 0;
  726. if( d > 255 ) d = 255;
  727. *pDst++ = (BYTE) d;
  728. pDst++;
  729. } // for j
  730. // back up two rows to get to the next scanline
  731. //
  732. if(lpbiOutput->biHeight >= 0)
  733. {
  734. pDst -= WidthBytes * 2;
  735. }
  736. } // for i
  737. } // UYVY
  738. else if( pinst->dwFormat == FOURCC_YUY2 ) // Y0 U0 Y1 V0...
  739. {
  740. for (i = Height; i > 0; i--)
  741. {
  742. /* loop copying two pixels at a time */
  743. for (j = Width ; j > 0; j -= 2)
  744. {
  745. // We are already in YUYV (0x V y1 U y0) format.
  746. #if 0 // straight computation
  747. // get two YUV pixels at a time
  748. //
  749. dwYUV = *pSrc++; // Y0 U0 Y1 V0
  750. y0 = (short) ( dwYUV & 0xFF ) - 16;
  751. dwYUV = dwYUV >> 8;
  752. U = (short) ( dwYUV & 0xFF ) - 128;
  753. dwYUV = dwYUV >> 8;
  754. y1 = (short) ( dwYUV & 0xFF ) - 16;
  755. dwYUV = dwYUV >> 8;
  756. V = (short) ( dwYUV & 0xFF ) - 128;
  757. l = ( ( y0 * 298L ) + ( 517L * U ) ) / 256; // blue
  758. if( l < 0 ) l = 0;
  759. if( l > 255 ) l = 255;
  760. *pDst++ = (BYTE) l; // blue
  761. l = ( ( y0 * 298L ) - ( 100L * U ) - ( 208L * V ) ) / 256; // green
  762. if( l < 0 ) l = 0;
  763. if( l > 255 ) l = 255;
  764. *pDst++ = (BYTE) l; // green
  765. l = ( ( y0 * 298L ) + ( 409L * V ) ) / 256; // red
  766. if( l < 0 ) l = 0;
  767. if( l > 255 ) l = 255;
  768. *pDst++ = (BYTE) l; // red
  769. pDst++;
  770. l = ( ( y1 * 298L ) + ( 517L * U ) ) / 256; // blue
  771. if( l < 0 ) l = 0;
  772. if( l > 255 ) l = 255;
  773. *pDst++ = (BYTE) l; // blue
  774. l = ( ( y1 * 298L ) - ( 100L * U ) - ( 208L * V ) ) / 256; // green
  775. if( l < 0 ) l = 0;
  776. if( l > 255 ) l = 255;
  777. *pDst++ = (BYTE) l; // green
  778. l = ( ( y1 * 298L ) + ( 409L * V ) ) / 256; // red
  779. if( l < 0 ) l = 0;
  780. if( l > 255 ) l = 255;
  781. *pDst++ = (BYTE) l; // red
  782. pDst++;
  783. #else // table lookup
  784. // get two YUV pixels at a time
  785. //
  786. dwYUV = *pSrc++; // Y0 U0 Y1 V0
  787. y0 = yip[( dwYUV & 0xFF )];
  788. dwYUV = dwYUV >> 8;
  789. U = (short) ( dwYUV & 0xFF );
  790. dwYUV = dwYUV >> 8;
  791. y1 = yip[( dwYUV & 0xFF )];
  792. dwYUV = dwYUV >> 8;
  793. V = (short) ( dwYUV & 0xFF );
  794. d = y0 + ubip[U]; // blue
  795. if( d < 0 ) d = 0;
  796. if( d > 255 ) d = 255;
  797. *pDst++ = (BYTE) d;
  798. d = y0 + ugip[U] + vgip[V]; // green
  799. if( d < 0 ) d = 0;
  800. if( d > 255 ) d = 255;
  801. *pDst++ = (BYTE) d;
  802. d = y0 + vrip[V]; // red
  803. if( d < 0 ) d = 0;
  804. if( d > 255 ) d = 255;
  805. *pDst++ = (BYTE) d;
  806. pDst++;
  807. d = y1 + ubip[U]; // blue
  808. if( d < 0 ) d = 0;
  809. if( d > 255 ) d = 255;
  810. *pDst++ = (BYTE) d;
  811. d = y1 + ugip[U] + vgip[V]; // green
  812. if( d < 0 ) d = 0;
  813. if( d > 255 ) d = 255;
  814. *pDst++ = (BYTE) d;
  815. d = y1 + vrip[V]; // red
  816. if( d < 0 ) d = 0;
  817. if( d > 255 ) d = 255;
  818. *pDst++ = (BYTE) d;
  819. pDst++;
  820. #endif
  821. } // for j
  822. // back up two rows to get to the next scanline
  823. //
  824. if(lpbiOutput->biHeight >= 0)
  825. {
  826. pDst -= WidthBytes * 2;
  827. }
  828. } // for i
  829. }
  830. else if( pinst->dwFormat == FOURCC_YVYU ) // Y0 V0 Y1 U0...
  831. {
  832. for (i = Height; i > 0; i--)
  833. {
  834. /* loop copying two pixels at a time */
  835. for (j = Width ; j > 0; j -= 2)
  836. {
  837. // get two YUV pixels at a time
  838. //
  839. dwYUV = *pSrc++; // Y0 U0 Y1 V0
  840. y0 = yip[( dwYUV & 0xFF )];
  841. dwYUV = dwYUV >> 8;
  842. V = (short) ( dwYUV & 0xFF );
  843. dwYUV = dwYUV >> 8;
  844. y1 = yip[( dwYUV & 0xFF )];
  845. dwYUV = dwYUV >> 8;
  846. U = (short) ( dwYUV & 0xFF );
  847. d = y0 + ubip[U]; // blue
  848. if( d < 0 ) d = 0;
  849. if( d > 255 ) d = 255;
  850. *pDst++ = (BYTE) d;
  851. d = y0 + ugip[U] + vgip[V]; // green
  852. if( d < 0 ) d = 0;
  853. if( d > 255 ) d = 255;
  854. *pDst++ = (BYTE) d;
  855. d = y0 + vrip[V]; // red
  856. if( d < 0 ) d = 0;
  857. if( d > 255 ) d = 255;
  858. *pDst++ = (BYTE) d;
  859. pDst++;
  860. d = y1 + ubip[U]; // blue
  861. if( d < 0 ) d = 0;
  862. if( d > 255 ) d = 255;
  863. *pDst++ = (BYTE) d;
  864. d = y1 + ugip[U] + vgip[V]; // green
  865. if( d < 0 ) d = 0;
  866. if( d > 255 ) d = 255;
  867. *pDst++ = (BYTE) d;
  868. d = y1 + vrip[V]; // red
  869. if( d < 0 ) d = 0;
  870. if( d > 255 ) d = 255;
  871. *pDst++ = (BYTE) d;
  872. pDst++;
  873. } // for j
  874. // back up two rows to get to the next scanline
  875. //
  876. if(lpbiOutput->biHeight >= 0)
  877. {
  878. pDst -= WidthBytes * 2;
  879. }
  880. } // for i
  881. }
  882. }
  883. VOID
  884. UYVYToRGB24(
  885. PINSTINFO pinst,
  886. LPBITMAPINFOHEADER lpbiInput,
  887. LPVOID lpInput,
  888. LPBITMAPINFOHEADER lpbiOutput,
  889. LPVOID lpOutput
  890. )
  891. {
  892. int Height = abs( lpbiInput->biHeight );
  893. int Width = lpbiInput->biWidth;
  894. short U;
  895. short V;
  896. short y0, y1;
  897. short d;
  898. DWORD * pSrc = lpInput;
  899. BYTE * pDst = lpOutput;
  900. long WidthBytes = Width * 3; // RGB = 3 bytes
  901. int i, j;
  902. DWORD dwYUV;
  903. long l;
  904. short maxd = 0;
  905. short mind = 255;
  906. // set up the lookup table arrays
  907. //
  908. short * yip = pinst->pXlate;
  909. short * vrip = yip + 256;
  910. short * vgip = vrip + 256;
  911. short * ugip = vgip + 256;
  912. short * ubip = ugip + 256;
  913. // if just a straight copy
  914. //
  915. if(lpbiOutput->biCompression == FOURCC_UYVY ||
  916. lpbiOutput->biCompression == FOURCC_YUY2 ||
  917. lpbiOutput->biCompression == FOURCC_YVYU )
  918. {
  919. memcpy( pDst, pSrc, WidthBytes * Height ); // Top down
  920. return;
  921. }
  922. // flip around if necessary
  923. //
  924. if(lpbiOutput->biHeight >= 0)
  925. {
  926. pDst += (Height - 1) * WidthBytes;
  927. }
  928. if( pinst->dwFormat == FOURCC_UYVY ) // U0 Y0 V0 Y1 U2 Y2 V2 Y3
  929. {
  930. for (i = Height; i > 0; i--)
  931. {
  932. /* loop copying two pixels at a time */
  933. for (j = Width ; j > 0; j -= 2)
  934. {
  935. // get two YUV pixels at a time
  936. //
  937. dwYUV = *pSrc++; // U0 Y0 V0 Y1
  938. U = (short) ( dwYUV & 0xFF );
  939. dwYUV = dwYUV >> 8;
  940. y0 = yip[( dwYUV & 0xFF )];
  941. dwYUV = dwYUV >> 8;
  942. V = (short) ( dwYUV & 0xFF );
  943. dwYUV = dwYUV >> 8;
  944. y1 = yip[( dwYUV & 0xFF )];
  945. d = y0 + ubip[U]; // blue
  946. if( d < 0 ) d = 0;
  947. if( d > 255 ) d = 255;
  948. *pDst++ = (BYTE) d;
  949. d = y0 + ugip[U] + vgip[V]; // green
  950. if( d < 0 ) d = 0;
  951. if( d > 255 ) d = 255;
  952. *pDst++ = (BYTE) d;
  953. d = y0 + vrip[V]; // red
  954. if( d < 0 ) d = 0;
  955. if( d > 255 ) d = 255;
  956. *pDst++ = (BYTE) d;
  957. d = y1 + ubip[U]; // blue
  958. if( d < 0 ) d = 0;
  959. if( d > 255 ) d = 255;
  960. *pDst++ = (BYTE) d;
  961. d = y1 + ugip[U] + vgip[V]; // green
  962. if( d < 0 ) d = 0;
  963. if( d > 255 ) d = 255;
  964. *pDst++ = (BYTE) d;
  965. d = y1 + vrip[V]; // red
  966. if( d < 0 ) d = 0;
  967. if( d > 255 ) d = 255;
  968. *pDst++ = (BYTE) d;
  969. } // for j
  970. // back up two rows to get to the next scanline
  971. //
  972. if(lpbiOutput->biHeight >= 0)
  973. {
  974. pDst -= WidthBytes * 2;
  975. }
  976. } // for i
  977. } // UYVY
  978. else if( pinst->dwFormat == FOURCC_YUY2 ) // Y0 U0 Y1 V0...
  979. {
  980. for (i = Height; i > 0; i--)
  981. {
  982. /* loop copying two pixels at a time */
  983. for (j = Width ; j > 0; j -= 2)
  984. {
  985. // We are already in YUYV (0x V y1 U y0) format.
  986. #if 0 // straight computation
  987. // get two YUV pixels at a time
  988. //
  989. dwYUV = *pSrc++; // Y0 U0 Y1 V0
  990. y0 = (short) ( dwYUV & 0xFF ) - 16;
  991. dwYUV = dwYUV >> 8;
  992. U = (short) ( dwYUV & 0xFF ) - 128;
  993. dwYUV = dwYUV >> 8;
  994. y1 = (short) ( dwYUV & 0xFF ) - 16;
  995. dwYUV = dwYUV >> 8;
  996. V = (short) ( dwYUV & 0xFF ) - 128;
  997. l = ( ( y0 * 298L ) + ( 517L * U ) ) / 256; // blue
  998. if( l < 0 ) l = 0;
  999. if( l > 255 ) l = 255;
  1000. *pDst++ = (BYTE) l; // blue
  1001. l = ( ( y0 * 298L ) - ( 100L * U ) - ( 208L * V ) ) / 256; // green
  1002. if( l < 0 ) l = 0;
  1003. if( l > 255 ) l = 255;
  1004. *pDst++ = (BYTE) l; // green
  1005. l = ( ( y0 * 298L ) + ( 409L * V ) ) / 256; // red
  1006. if( l < 0 ) l = 0;
  1007. if( l > 255 ) l = 255;
  1008. *pDst++ = (BYTE) l; // red
  1009. l = ( ( y1 * 298L ) + ( 517L * U ) ) / 256; // blue
  1010. if( l < 0 ) l = 0;
  1011. if( l > 255 ) l = 255;
  1012. *pDst++ = (BYTE) l; // blue
  1013. l = ( ( y1 * 298L ) - ( 100L * U ) - ( 208L * V ) ) / 256; // green
  1014. if( l < 0 ) l = 0;
  1015. if( l > 255 ) l = 255;
  1016. *pDst++ = (BYTE) l; // green
  1017. l = ( ( y1 * 298L ) + ( 409L * V ) ) / 256; // red
  1018. if( l < 0 ) l = 0;
  1019. if( l > 255 ) l = 255;
  1020. *pDst++ = (BYTE) l; // red
  1021. #else // table lookup
  1022. // get two YUV pixels at a time
  1023. //
  1024. dwYUV = *pSrc++; // Y0 U0 Y1 V0
  1025. y0 = yip[( dwYUV & 0xFF )];
  1026. dwYUV = dwYUV >> 8;
  1027. U = (short) ( dwYUV & 0xFF );
  1028. dwYUV = dwYUV >> 8;
  1029. y1 = yip[( dwYUV & 0xFF )];
  1030. dwYUV = dwYUV >> 8;
  1031. V = (short) ( dwYUV & 0xFF );
  1032. d = y0 + ubip[U]; // blue
  1033. if( d < 0 ) d = 0;
  1034. if( d > 255 ) d = 255;
  1035. *pDst++ = (BYTE) d;
  1036. d = y0 + ugip[U] + vgip[V]; // green
  1037. if( d < 0 ) d = 0;
  1038. if( d > 255 ) d = 255;
  1039. *pDst++ = (BYTE) d;
  1040. d = y0 + vrip[V]; // red
  1041. if( d < 0 ) d = 0;
  1042. if( d > 255 ) d = 255;
  1043. *pDst++ = (BYTE) d;
  1044. d = y1 + ubip[U]; // blue
  1045. if( d < 0 ) d = 0;
  1046. if( d > 255 ) d = 255;
  1047. *pDst++ = (BYTE) d;
  1048. d = y1 + ugip[U] + vgip[V]; // green
  1049. if( d < 0 ) d = 0;
  1050. if( d > 255 ) d = 255;
  1051. *pDst++ = (BYTE) d;
  1052. d = y1 + vrip[V]; // red
  1053. if( d < 0 ) d = 0;
  1054. if( d > 255 ) d = 255;
  1055. *pDst++ = (BYTE) d;
  1056. #endif
  1057. } // for j
  1058. // back up two rows to get to the next scanline
  1059. //
  1060. if(lpbiOutput->biHeight >= 0)
  1061. {
  1062. pDst -= WidthBytes * 2;
  1063. }
  1064. } // for i
  1065. }
  1066. else if( pinst->dwFormat == FOURCC_YVYU ) // Y0 V0 Y1 U0...
  1067. {
  1068. for (i = Height; i > 0; i--)
  1069. {
  1070. /* loop copying two pixels at a time */
  1071. for (j = Width ; j > 0; j -= 2)
  1072. {
  1073. // get two YUV pixels at a time
  1074. //
  1075. dwYUV = *pSrc++; // Y0 U0 Y1 V0
  1076. y0 = yip[( dwYUV & 0xFF )];
  1077. dwYUV = dwYUV >> 8;
  1078. V = (short) ( dwYUV & 0xFF );
  1079. dwYUV = dwYUV >> 8;
  1080. y1 = yip[( dwYUV & 0xFF )];
  1081. dwYUV = dwYUV >> 8;
  1082. U = (short) ( dwYUV & 0xFF );
  1083. d = y0 + ubip[U]; // blue
  1084. if( d < 0 ) d = 0;
  1085. if( d > 255 ) d = 255;
  1086. *pDst++ = (BYTE) d;
  1087. d = y0 + ugip[U] + vgip[V]; // green
  1088. if( d < 0 ) d = 0;
  1089. if( d > 255 ) d = 255;
  1090. *pDst++ = (BYTE) d;
  1091. d = y0 + vrip[V]; // red
  1092. if( d < 0 ) d = 0;
  1093. if( d > 255 ) d = 255;
  1094. *pDst++ = (BYTE) d;
  1095. d = y1 + ubip[U]; // blue
  1096. if( d < 0 ) d = 0;
  1097. if( d > 255 ) d = 255;
  1098. *pDst++ = (BYTE) d;
  1099. d = y1 + ugip[U] + vgip[V]; // green
  1100. if( d < 0 ) d = 0;
  1101. if( d > 255 ) d = 255;
  1102. *pDst++ = (BYTE) d;
  1103. d = y1 + vrip[V]; // red
  1104. if( d < 0 ) d = 0;
  1105. if( d > 255 ) d = 255;
  1106. *pDst++ = (BYTE) d;
  1107. } // for j
  1108. // back up two rows to get to the next scanline
  1109. //
  1110. if(lpbiOutput->biHeight >= 0)
  1111. {
  1112. pDst -= WidthBytes * 2;
  1113. }
  1114. } // for i
  1115. }
  1116. }
  1117. #define OFFSET 10
  1118. #define STDPALCOLOURS 256
  1119. /*****************************************************************************
  1120. *
  1121. * DecompressGetPalette() implements ICM_GET_PALETTE
  1122. *
  1123. * This function has no Compress...() equivalent
  1124. *
  1125. * It is used to pull the palette from a frame in order to possibly do
  1126. * a palette change.
  1127. *
  1128. ****************************************************************************/
  1129. DWORD NEAR PASCAL DecompressGetPalette(INSTINFO * pinst, LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut)
  1130. {
  1131. DWORD dw;
  1132. unsigned char * lpPalArea;
  1133. long Index, cntEntries;
  1134. HDC hDC;
  1135. PALETTEENTRY apeSystem[STDPALCOLOURS]; // OFFSET];
  1136. dprintf2((TEXT("DecompressGetPalette()\n")));
  1137. if (dw = DecompressQuery(pinst, lpbiIn, NULL))
  1138. return dw;
  1139. if (lpbiOut->biBitCount != 8) { /* 8-bit only for palettes */
  1140. dprintf1(("DecompressGetPalette: Unsupported lpbiOut->biBitCount=%d\n", lpbiOut->biBitCount));
  1141. return (DWORD)ICERR_ERROR;
  1142. }
  1143. // Initialise the palette entries in the header
  1144. dprintf1(("DecompressGetPalette(): in->biSize=%d, out->biSize=%d\n", lpbiIn->biSize, lpbiOut->biSize));
  1145. // Get the standard system colours
  1146. if ( hDC = GetDC(GetDesktopWindow()) )
  1147. {
  1148. cntEntries = GetSystemPaletteEntries(hDC,0,STDPALCOLOURS,apeSystem);
  1149. ReleaseDC(GetDesktopWindow(),hDC);
  1150. }
  1151. if (cntEntries == 0) {
  1152. dprintf2(("DecompressGetPalette:cntEntries is 0; GetSystemPaletteEntries failed.\n"));
  1153. lpbiOut->biClrUsed = 0;
  1154. lpbiOut->biClrImportant = 0;
  1155. return (DWORD) ICERR_OK;
  1156. }
  1157. lpbiOut->biClrUsed = STDPALCOLOURS;
  1158. lpbiOut->biClrImportant = 0;
  1159. // Adding system device colours to be dithered
  1160. lpPalArea = (unsigned char *)lpbiOut + (int)lpbiOut->biSize;
  1161. // Copy the first ten VGA system colours
  1162. for (Index = 0;Index < OFFSET;Index++) {
  1163. lpPalArea[Index*4+0] = apeSystem[Index].peRed;
  1164. lpPalArea[Index*4+1] = apeSystem[Index].peGreen;
  1165. lpPalArea[Index*4+2] = apeSystem[Index].peBlue;
  1166. lpPalArea[Index*4+3] = 0;
  1167. }
  1168. // Copy the palette we dither to one colour at a time
  1169. for (Index = OFFSET;Index < STDPALCOLOURS-OFFSET;Index++) {
  1170. lpPalArea[Index*4+0] = PalTable[Index*4+2];
  1171. lpPalArea[Index*4+1] = PalTable[Index*4+1];
  1172. lpPalArea[Index*4+2] = PalTable[Index*4+0];
  1173. lpPalArea[Index*4+3] = 0;
  1174. }
  1175. // Copy the last ten VGA system colours
  1176. for (Index = STDPALCOLOURS-OFFSET;Index < STDPALCOLOURS;Index++) {
  1177. lpPalArea[Index*4+0] = apeSystem[Index].peRed;
  1178. lpPalArea[Index*4+1] = apeSystem[Index].peGreen;
  1179. lpPalArea[Index*4+2] = apeSystem[Index].peBlue;
  1180. lpPalArea[Index*4+3] = 0;
  1181. }
  1182. return (DWORD)ICERR_OK;
  1183. }
  1184. VOID FreeXlate(PINSTINFO pinst)
  1185. {
  1186. ASSERT(pinst != NULL);
  1187. if (pinst && pinst->pXlate != NULL) {
  1188. VirtualFree(pinst->pXlate, 0, MEM_RELEASE);
  1189. pinst->pXlate = NULL;
  1190. }
  1191. }