Windows NT 4.0 source code leak
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.

471 lines
12 KiB

4 years ago
  1. /*----------------------------------------------------------------------+
  2. | msyuv.c - Microsoft YUV Codec |
  3. | |
  4. | Copyright (c) 1993 Microsoft Corporation. |
  5. | All Rights Reserved. |
  6. | |
  7. +----------------------------------------------------------------------*/
  8. #include <windows.h>
  9. #include <windowsx.h>
  10. #include <mmsystem.h>
  11. #include <compddk.h>
  12. #ifndef _WIN32
  13. #include "stdarg.h"
  14. #endif
  15. #ifdef _WIN32
  16. #include <memory.h> /* for memcpy */
  17. #endif
  18. #include "msyuv.h"
  19. TCHAR szDescription[] = TEXT("Microsoft YUV Codec");
  20. TCHAR szName[] = TEXT("MS-YUV411");
  21. TCHAR szAbout[] = TEXT("About");
  22. #define VERSION 0x00010000 // 1.0
  23. /*****************************************************************************
  24. ****************************************************************************/
  25. INSTINFO * NEAR PASCAL Open(ICOPEN FAR * icinfo)
  26. {
  27. INSTINFO * pinst;
  28. //
  29. // refuse to open if we are not being opened as a Video compressor
  30. //
  31. if (icinfo->fccType != ICTYPE_VIDEO)
  32. return NULL;
  33. pinst = (INSTINFO *)LocalAlloc(LPTR, sizeof(INSTINFO));
  34. if (!pinst) {
  35. icinfo->dwError = (DWORD)ICERR_MEMORY;
  36. return NULL;
  37. }
  38. //
  39. // init structure
  40. //
  41. pinst->dwFlags = icinfo->dwFlags;
  42. pinst->pXlate = NULL;
  43. //
  44. // return success.
  45. //
  46. icinfo->dwError = ICERR_OK;
  47. return pinst;
  48. }
  49. /*****************************************************************************
  50. ****************************************************************************/
  51. DWORD NEAR PASCAL Close(INSTINFO * pinst)
  52. {
  53. if (pinst->pXlate) {
  54. DecompressEnd(pinst);
  55. }
  56. if (pinst->vh) {
  57. DrawEnd(pinst);
  58. }
  59. LocalFree((HLOCAL)pinst);
  60. return 1;
  61. }
  62. /*****************************************************************************
  63. ****************************************************************************/
  64. BOOL NEAR PASCAL QueryAbout(INSTINFO * pinst)
  65. {
  66. return TRUE;
  67. }
  68. DWORD NEAR PASCAL About(INSTINFO * pinst, HWND hwnd)
  69. {
  70. MessageBox(hwnd,szDescription,szAbout,MB_OK|MB_ICONINFORMATION);
  71. return ICERR_OK;
  72. }
  73. /*****************************************************************************
  74. ****************************************************************************/
  75. BOOL NEAR PASCAL QueryConfigure(INSTINFO * pinst)
  76. {
  77. return FALSE;
  78. }
  79. DWORD NEAR PASCAL Configure(INSTINFO * pinst, HWND hwnd)
  80. {
  81. return (TRUE);
  82. }
  83. /*****************************************************************************
  84. ****************************************************************************/
  85. /*
  86. * lossless translation - hence no need for state adjustments
  87. */
  88. DWORD NEAR PASCAL GetState(INSTINFO * pinst, LPVOID pv, DWORD dwSize)
  89. {
  90. return 0;
  91. }
  92. /*****************************************************************************
  93. ****************************************************************************/
  94. DWORD NEAR PASCAL SetState(INSTINFO * pinst, LPVOID pv, DWORD dwSize)
  95. {
  96. return(0);
  97. }
  98. /*****************************************************************************
  99. ****************************************************************************/
  100. DWORD NEAR PASCAL GetInfo(INSTINFO * pinst, ICINFO FAR *icinfo, DWORD dwSize)
  101. {
  102. if (icinfo == NULL)
  103. return sizeof(ICINFO);
  104. if (dwSize < sizeof(ICINFO))
  105. return 0;
  106. icinfo->dwSize = sizeof(ICINFO);
  107. icinfo->fccType = ICTYPE_VIDEO;
  108. icinfo->fccHandler = FOURCC_YUV411;
  109. icinfo->dwFlags = 0;
  110. icinfo->dwVersion = VERSION;
  111. icinfo->dwVersionICM = ICVERSION;
  112. lstrcpy(icinfo->szDescription, szDescription);
  113. lstrcpy(icinfo->szName, szName);
  114. return sizeof(ICINFO);
  115. }
  116. /*****************************************************************************
  117. ****************************************************************************/
  118. DWORD FAR PASCAL CompressQuery(INSTINFO * pinst, LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut)
  119. {
  120. return ((DWORD) ICERR_BADFORMAT);
  121. }
  122. /*****************************************************************************
  123. ****************************************************************************/
  124. DWORD FAR PASCAL CompressGetFormat(INSTINFO * pinst, LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut)
  125. {
  126. return((DWORD) ICERR_BADFORMAT);
  127. }
  128. /*****************************************************************************
  129. ****************************************************************************/
  130. DWORD FAR PASCAL CompressBegin(INSTINFO * pinst, LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut)
  131. {
  132. return((DWORD) ICERR_ERROR);
  133. }
  134. /*****************************************************************************
  135. ****************************************************************************/
  136. DWORD FAR PASCAL CompressGetSize(INSTINFO * pinst, LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut)
  137. {
  138. return (0);
  139. }
  140. /*****************************************************************************
  141. ****************************************************************************/
  142. DWORD FAR PASCAL Compress(INSTINFO * pinst, ICCOMPRESS FAR *icinfo, DWORD dwSize)
  143. {
  144. return((DWORD) ICERR_ERROR);
  145. }
  146. /*****************************************************************************
  147. ****************************************************************************/
  148. DWORD FAR PASCAL CompressEnd(INSTINFO * pinst)
  149. {
  150. return (DWORD)ICERR_ERROR;
  151. }
  152. /*****************************************************************************
  153. ****************************************************************************/
  154. DWORD NEAR PASCAL DecompressQuery(INSTINFO * pinst, LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut)
  155. {
  156. //
  157. // determine if the input DIB data is in a format we like.
  158. //
  159. if (lpbiIn == NULL ||
  160. (lpbiIn->biBitCount != 16) ||
  161. ( (lpbiIn->biCompression != FOURCC_YUV411) &&
  162. (lpbiIn->biCompression != FOURCC_YUV422))) {
  163. dprintf(("bad input format"));
  164. return (DWORD)ICERR_BADFORMAT;
  165. }
  166. //
  167. // are we being asked to query just the input format?
  168. //
  169. if (lpbiOut == NULL) {
  170. return ICERR_OK;
  171. }
  172. // check output format to make sure we can convert to this
  173. // must be full dib
  174. if (lpbiOut->biCompression == BI_RGB) {
  175. pinst->bRGB565 = FALSE;
  176. } else if ((lpbiOut->biCompression == BI_BITFIELDS) &&
  177. (lpbiOut->biBitCount == 16) &&
  178. (((LPDWORD)(lpbiOut+1))[0] == 0x00f800) &&
  179. (((LPDWORD)(lpbiOut+1))[1] == 0x0007e0) &&
  180. (((LPDWORD)(lpbiOut+1))[2] == 0x00001f)) {
  181. dprintf1(("rgb565 output"));
  182. pinst->bRGB565 = TRUE;
  183. } else {
  184. dprintf1(("bad compression for output"));
  185. return (DWORD)ICERR_BADFORMAT;
  186. }
  187. /* must be 1:1 (no stretching) */
  188. if ((lpbiOut->biWidth != lpbiIn->biWidth) ||
  189. (lpbiOut->biHeight != lpbiIn->biHeight)) {
  190. dprintf1(("YUV can't stretch: %dx%d->%dx%d",
  191. lpbiIn->biWidth, lpbiIn->biHeight,
  192. lpbiOut->biWidth, lpbiOut->biHeight
  193. ));
  194. return((DWORD) ICERR_BADFORMAT);
  195. }
  196. /*
  197. * we translate to 16 bits
  198. */
  199. if (lpbiOut->biBitCount != 16) {
  200. dprintf1(("YUV 16:16 only"));
  201. return((DWORD) ICERR_BADFORMAT);
  202. }
  203. return ICERR_OK;
  204. }
  205. /*****************************************************************************
  206. ****************************************************************************/
  207. DWORD DecompressGetFormat(INSTINFO * pinst, LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut)
  208. {
  209. DWORD dw;
  210. int dx,dy;
  211. dw = DecompressQuery(pinst, lpbiIn, NULL);
  212. if (dw != ICERR_OK) {
  213. return dw;
  214. }
  215. //
  216. // if lpbiOut == NULL then, return the size required to hold a output
  217. // format
  218. //
  219. if (lpbiOut == NULL) {
  220. dprintf2(("get format size query"));
  221. return (int)lpbiIn->biSize + (int)lpbiIn->biClrUsed * sizeof(RGBQUAD);
  222. }
  223. memcpy(lpbiOut, lpbiIn,
  224. (int)lpbiIn->biSize + (int)lpbiIn->biClrUsed * sizeof(RGBQUAD));
  225. dx = (int)lpbiIn->biWidth & ~3;
  226. dy = (int)lpbiIn->biHeight & ~3;
  227. lpbiOut->biWidth = dx;
  228. lpbiOut->biHeight = dy;
  229. lpbiOut->biBitCount = lpbiIn->biBitCount; // convert 16->16
  230. lpbiOut->biCompression = BI_RGB;
  231. lpbiOut->biSizeImage = dx*dy*2;
  232. return ICERR_OK;
  233. }
  234. /*****************************************************************************
  235. ****************************************************************************/
  236. DWORD NEAR PASCAL DecompressBegin(INSTINFO * pinst, LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut)
  237. {
  238. DWORD dw;
  239. /* check that the conversion formats are valid */
  240. dw = DecompressQuery(pinst, lpbiIn, lpbiOut);
  241. if (dw != ICERR_OK) {
  242. return dw;
  243. }
  244. /* init the yuv-to-rgb55 xlate table if not already inited */
  245. /* free up the existing table if the formats differ */
  246. if (lpbiIn->biCompression != pinst->dwFormat) {
  247. if (pinst->pXlate != NULL) {
  248. DecompressEnd(pinst);
  249. }
  250. }
  251. if (pinst->pXlate == NULL) {
  252. switch(lpbiIn->biCompression) {
  253. case FOURCC_YUV411:
  254. if (pinst->bRGB565) {
  255. pinst->pXlate = BuildYUVToRGB565(pinst);
  256. } else {
  257. pinst->pXlate = BuildYUVToRGB555(pinst);
  258. }
  259. break;
  260. case FOURCC_YUV422:
  261. if (pinst->bRGB565) {
  262. pinst->pXlate = BuildYUV422ToRGB565(pinst);
  263. } else {
  264. pinst->pXlate = BuildYUV422ToRGB555(pinst);
  265. }
  266. break;
  267. default:
  268. return((DWORD) ICERR_BADFORMAT);
  269. }
  270. if (pinst->pXlate == NULL) {
  271. return((DWORD) ICERR_MEMORY);
  272. }
  273. pinst->dwFormat = lpbiIn->biCompression;
  274. }
  275. return(ICERR_OK);
  276. }
  277. /*****************************************************************************
  278. ****************************************************************************/
  279. DWORD NEAR PASCAL Decompress(INSTINFO * pinst, ICDECOMPRESS FAR *icinfo, DWORD dwSize)
  280. {
  281. /* must have been a DecompressBegin first */
  282. if (pinst->pXlate == NULL) {
  283. return((DWORD) ICERR_ERROR);
  284. }
  285. if (pinst->dwFormat == FOURCC_YUV411) {
  286. YUV411ToRGB(pinst,
  287. icinfo->lpbiInput,
  288. icinfo->lpInput,
  289. icinfo->lpbiOutput,
  290. icinfo->lpOutput
  291. );
  292. } else {
  293. /*
  294. * for compatibility with 16-bit Spigot driver,
  295. * check for Guard field at start of data
  296. */
  297. LPDWORD lpInput = icinfo->lpInput;
  298. if (*lpInput == FOURCC_YUV422) {
  299. lpInput++;
  300. }
  301. YUV422ToRGB(pinst,
  302. icinfo->lpbiInput,
  303. icinfo->lpInput,
  304. icinfo->lpbiOutput,
  305. icinfo->lpOutput
  306. );
  307. }
  308. return ICERR_OK;
  309. }
  310. /*****************************************************************************
  311. *
  312. * DecompressGetPalette() implements ICM_GET_PALETTE
  313. *
  314. * This function has no Compress...() equivalent
  315. *
  316. * It is used to pull the palette from a frame in order to possibly do
  317. * a palette change.
  318. *
  319. ****************************************************************************/
  320. DWORD NEAR PASCAL DecompressGetPalette(INSTINFO * pinst, LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut)
  321. {
  322. dprintf2(("DecompressGetPalette()"));
  323. /*
  324. * only applies to 8-bit output formats. We only decompress to 16 bits
  325. */
  326. return((DWORD) ICERR_BADFORMAT);
  327. }
  328. /*****************************************************************************
  329. ****************************************************************************/
  330. DWORD NEAR PASCAL DecompressEnd(INSTINFO * pinst)
  331. {
  332. if (pinst->pXlate == NULL) {
  333. return (DWORD)ICERR_ERROR;
  334. }
  335. FreeXlate(pinst);
  336. pinst->dwFormat = 0;
  337. return ICERR_OK;
  338. }
  339. /*****************************************************************************
  340. ****************************************************************************/
  341. #ifdef DEBUG
  342. void FAR CDECL dprintf(LPSTR szFormat, ...)
  343. {
  344. char ach[128];
  345. va_list va;
  346. static BOOL fDebug = -1;
  347. if (fDebug == -1)
  348. fDebug = GetProfileIntA("Debug", "MSYUV", FALSE);
  349. if (!fDebug)
  350. return;
  351. lstrcpyA(ach, "MSYUV: ");
  352. va_start(va, szFormat);
  353. wvsprintfA(ach+7,szFormat,(LPSTR)va);
  354. va_end(va);
  355. lstrcatA(ach, "\r\n");
  356. OutputDebugStringA(ach);
  357. }
  358. #endif