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.

902 lines
28 KiB

  1. /*++
  2. Copyright (c) 1998 Philips B.V. CE - I&C
  3. Module Name:
  4. mcodec.c
  5. Abstract:
  6. this module converts the raw USB data to video data.
  7. Original Author:
  8. Ronald v.d.Meer
  9. Environment:
  10. Kernel mode only
  11. Revision History:
  12. Date Reason
  13. 14-04-1998 Initial version
  14. --*/
  15. #include "wdm.h"
  16. #include "mcamdrv.h"
  17. #include "mstreams.h"
  18. #include "mdecoder.h"
  19. #include "mcodec.h"
  20. /*******************************************************************************
  21. *
  22. * START DEFINES
  23. *
  24. ******************************************************************************/
  25. #define NO_BANDS_CIF (CIF_Y / 4) /* Number of YUV bands per frame */
  26. #define NO_BANDS_SIF (SIF_Y / 4) /* Number of YUV bands per frame */
  27. #define NO_BANDS_SSIF (SSIF_Y / 4) /* Number of YUV bands per frame */
  28. #define NO_BANDS_SCIF (SCIF_Y / 4) /* Number of YUV bands per frame */
  29. #define NO_LINES_IN_BAND 4
  30. /*
  31. * one line contains "Width * 3/2" bytes (12 bits per pixel)
  32. * one YYYYCC block is 6 bytes
  33. * NO_YYYYCC_PER_LINE = (Width * 3/2 / 6) = (Width / 4)
  34. */
  35. #define NO_YYYYCC_PER_LINE(width) (width >> 2)
  36. #define QQCIF_DY ((SQCIF_Y - QQCIF_Y) / 2)
  37. #define QQCIF_DX ((SQCIF_X - QQCIF_X) / 2)
  38. #define SQSIF_DY ((SQCIF_Y - SQSIF_Y) / 2)
  39. #define SQSIF_DX ((SQCIF_X - SQSIF_X) / 2)
  40. #define QSIF_DY (( QCIF_Y - QSIF_Y) / 2)
  41. #define QSIF_DX (( QCIF_X - QSIF_X) / 2)
  42. #define SSIF_DY (( CIF_Y - SSIF_Y) / 2)
  43. #define SSIF_DX (( CIF_X - SSIF_X) / 2)
  44. #define SIF_DY (( CIF_Y - SIF_Y) / 2)
  45. #define SIF_DX (( CIF_X - SIF_X) / 2)
  46. #define SCIF_DY (( CIF_Y - SCIF_Y) / 2)
  47. #define SCIF_DX (( CIF_X - SCIF_X) / 2)
  48. /*******************************************************************************
  49. *
  50. * START STATIC VARIABLES
  51. *
  52. ******************************************************************************/
  53. static WORD FixGreenbarArray[CIF_Y][4];
  54. /*******************************************************************************
  55. *
  56. * START STATIC METHODS DECLARATIONS
  57. *
  58. ******************************************************************************/
  59. static void TranslateP420ToI420 (PBYTE pInput, PBYTE pOutput, int w, int h,
  60. DWORD camVersion);
  61. extern void TranslatePCFxToI420 (PBYTE pInput, PBYTE pOutput, int width,
  62. int height, DWORD camVersion);
  63. #ifdef PIX12_FIX
  64. static void FixPix12InI420 (PBYTE p, BOOLEAN Compress, int w, int h,
  65. DWORD camVersion);
  66. #endif
  67. static void Fix16PixGreenbarInI420 (PBYTE pStart, int w);
  68. /*******************************************************************************
  69. *
  70. * START EXPORTED METHODS DEFINITIONS
  71. *
  72. ******************************************************************************/
  73. /*
  74. * This routine is called at selection of a new stream
  75. */
  76. extern NTSTATUS
  77. PHILIPSCAM_DecodeUsbData (PPHILIPSCAM_DEVICE_CONTEXT DeviceContext,
  78. PUCHAR FrameBuffer,
  79. ULONG FrameLength,
  80. PUCHAR RawFrameBuffer,
  81. ULONG RawFrameLength)
  82. {
  83. NTSTATUS ntStatus = STATUS_SUCCESS;
  84. int width;
  85. int height;
  86. switch (DeviceContext->CamStatus.PictureFormat)
  87. {
  88. case FORMATCIF :
  89. width = CIF_X;
  90. height = CIF_Y;
  91. break;
  92. case FORMATQCIF :
  93. width = QCIF_X;
  94. height = QCIF_Y;
  95. break;
  96. case FORMATSQCIF :
  97. width = SQCIF_X;
  98. height = SQCIF_Y;
  99. break;
  100. case FORMATSIF :
  101. width = SIF_X;
  102. height = SIF_Y;
  103. break;
  104. case FORMATQSIF :
  105. width = QSIF_X;
  106. height = QSIF_Y;
  107. break;
  108. case FORMATSQSIF :
  109. width = SQSIF_X;
  110. height = SQSIF_Y;
  111. break;
  112. case FORMATQQCIF :
  113. width = QQCIF_X;
  114. height = QQCIF_Y;
  115. break;
  116. case FORMATSSIF :
  117. width = SSIF_X;
  118. height = SSIF_Y;
  119. break;
  120. case FORMATSCIF :
  121. width = SCIF_X;
  122. height = SCIF_Y;
  123. break;
  124. default : // VGA
  125. width = VGA_X;
  126. height = VGA_Y;
  127. break;
  128. }
  129. if (DeviceContext->CamStatus.PictureCompressing == COMPRESSION0)
  130. {
  131. // convert Philips P420 format to Intel I420 format
  132. TranslateP420ToI420 ((PBYTE) RawFrameBuffer, (PBYTE) FrameBuffer,
  133. width, height,
  134. DeviceContext->CamStatus.ReleaseNumber);
  135. }
  136. else
  137. {
  138. // convert Philips PCFx format to Intel I420 format
  139. TranslatePCFxToI420 ((PBYTE) RawFrameBuffer, (PBYTE) FrameBuffer,
  140. width, height,
  141. DeviceContext->CamStatus.ReleaseNumber);
  142. }
  143. return (ntStatus);
  144. }
  145. //------------------------------------------------------------------------------
  146. /*
  147. * This routine is called at selection of a new stream
  148. */
  149. extern NTSTATUS
  150. PHILIPSCAM_StartCodec (PPHILIPSCAM_DEVICE_CONTEXT DeviceContext)
  151. {
  152. NTSTATUS ntStatus = STATUS_SUCCESS;
  153. InitDecoder ();
  154. if (DeviceContext->CamStatus.ReleaseNumber < SSI_8117_N3)
  155. {
  156. int line, pix;
  157. for (line = 0; line < CIF_Y; line++)
  158. {
  159. for (pix = 0; pix < 4; pix++)
  160. {
  161. FixGreenbarArray[line][pix] = (WORD) 0x8080;
  162. }
  163. }
  164. }
  165. return (ntStatus);
  166. }
  167. //------------------------------------------------------------------------------
  168. /*
  169. * This routine is called after stopping a stream.
  170. * Used resources have to be made free.
  171. */
  172. extern NTSTATUS
  173. PHILIPSCAM_StopCodec(PPHILIPSCAM_DEVICE_CONTEXT DeviceContext)
  174. {
  175. NTSTATUS ntStatus = STATUS_SUCCESS;
  176. return (ntStatus);
  177. }
  178. //------------------------------------------------------------------------------
  179. /*
  180. * This routine is called by mprpobj.c to announce a framerate selection
  181. * in CIF mode, eventually resulting in change from compressed <-> uncompressed.
  182. */
  183. extern NTSTATUS
  184. PHILIPSCAM_FrameRateChanged (PPHILIPSCAM_DEVICE_CONTEXT DeviceContext)
  185. {
  186. NTSTATUS ntStatus = STATUS_SUCCESS;
  187. return (ntStatus);
  188. }
  189. /*******************************************************************************
  190. *
  191. * START STATIC METHODS DEFINITIONS
  192. *
  193. ******************************************************************************/
  194. #ifdef PIX12_FIX
  195. static void
  196. FixPix12InI420 (PBYTE p, BOOLEAN Compress, int width, int height,
  197. DWORD camVersion)
  198. {
  199. int line;
  200. PBYTE pStart;
  201. if (width == SQCIF_X)
  202. {
  203. return;
  204. }
  205. // only QCIF and CIF have to be fixed
  206. pStart = p;
  207. if (Compress)
  208. {
  209. for (line = height; line > 0; line--)
  210. {
  211. *(p + 0) = *(p + 1);
  212. *(p + 2) = *(p + 3);
  213. p += width;
  214. }
  215. }
  216. else
  217. {
  218. for (line = height; line > 0; line--)
  219. {
  220. *(p + 0) = *(p + 1);
  221. *(p + 1) = *(p + 2);
  222. p += width;
  223. }
  224. p = pStart + I420_NO_Y (width, height);
  225. width >>= 1;
  226. if (camVersion >= SSI_PIX12_FIX)
  227. {
  228. for (line = height; line > 0; line--)
  229. {
  230. // First all U's then all V's
  231. *(p + 0) = *(p + 1);
  232. p += width;
  233. }
  234. }
  235. else
  236. {
  237. for (line = height; line > 0; line--)
  238. {
  239. // First all U's then all V's
  240. *(p + 0) = *(p + 2);
  241. *(p + 1) = *(p + 2);
  242. p += width;
  243. }
  244. }
  245. }
  246. }
  247. #endif // PIX12_FIX
  248. //------------------------------------------------------------------------------
  249. // In the 8117 silicum versions N2 and before, the CIF decompressed
  250. // picture contains little green bars at the end of the picture.
  251. // These greenbars are 16 pixels width and 4 pixels height.
  252. // This bug is fixed in the 3rd silicium version of the 8117 (N3)
  253. // UV components of last 16 pixels in line : YYYYUU YYYYUU YYYYUU YYYYUU
  254. // YYYYVV YYYYVV YYYYVV YYYYVV
  255. // This are 2 blocks
  256. // Greenbar bug : all V's do have the same value.
  257. // This value is less then 'VREF_VALUE'
  258. // pU points to 1st UUUU block, pU + 1 points to 1st VVVV block
  259. static void
  260. Fix16PixGreenbarInI420 (PBYTE pStart, int width)
  261. {
  262. int line;
  263. int band;
  264. PWORD pU;
  265. PWORD pV;
  266. #define VREF_VALUE 0x40
  267. #define C_INC (I420_NO_C_PER_LINE_CIF / sizeof (WORD))
  268. /* point to start of last 8 V's of first band V line */
  269. pU = (PWORD) ((PBYTE) pStart + I420_NO_Y_CIF + I420_NO_C_PER_LINE_CIF - 8);
  270. pV = (PWORD) ((PBYTE) pStart + I420_NO_Y_CIF + I420_NO_U_CIF + I420_NO_C_PER_LINE_CIF - 8);
  271. for (band = 0; band < NO_BANDS_CIF; band++)
  272. {
  273. line = band * 4;
  274. /*
  275. * band : UUUU UUUU ...
  276. * UUUU UUUU ...
  277. * VVVV VVVV ... --> check the last 8 V's for error condition
  278. * VVVV VVVV ...
  279. *
  280. * V1V2 V3V4 V5V6 V7V8 (last V's in first BLOCK_BAND V line)
  281. * all V's have to be the same value. This value is < VREF_VALUE
  282. * If so, a green bar will be visible --> correct with last correct
  283. * pixel information
  284. */
  285. if ( (*(pV + 0) == *(pV + 1)) &&
  286. (*(pV + 0) == *(pV + 2)) &&
  287. (*(pV + 0) == *(pV + 3)) &&
  288. ((*(pV + 0) & 0x00FF) == (((*pV + 0) & 0xFF00) >> 8)) &&
  289. ((*(pV + 0) & 0x00FF) < VREF_VALUE))
  290. {
  291. *(pU + (C_INC * 0) + 0) = FixGreenbarArray[line + 0][0];
  292. *(pU + (C_INC * 0) + 1) = FixGreenbarArray[line + 0][1];
  293. *(pU + (C_INC * 0) + 2) = FixGreenbarArray[line + 0][2];
  294. *(pU + (C_INC * 0) + 3) = FixGreenbarArray[line + 0][3];
  295. *(pV + (C_INC * 0) + 0) = FixGreenbarArray[line + 1][0];
  296. *(pV + (C_INC * 0) + 1) = FixGreenbarArray[line + 1][1];
  297. *(pV + (C_INC * 0) + 2) = FixGreenbarArray[line + 1][2];
  298. *(pV + (C_INC * 0) + 3) = FixGreenbarArray[line + 1][3];
  299. *(pU + (C_INC * 1) + 0) = FixGreenbarArray[line + 2][0];
  300. *(pU + (C_INC * 1) + 1) = FixGreenbarArray[line + 2][1];
  301. *(pU + (C_INC * 1) + 2) = FixGreenbarArray[line + 2][2];
  302. *(pU + (C_INC * 1) + 3) = FixGreenbarArray[line + 2][3];
  303. *(pV + (C_INC * 1) + 0) = FixGreenbarArray[line + 3][0];
  304. *(pV + (C_INC * 1) + 1) = FixGreenbarArray[line + 3][1];
  305. *(pV + (C_INC * 1) + 2) = FixGreenbarArray[line + 3][2];
  306. *(pV + (C_INC * 1) + 3) = FixGreenbarArray[line + 3][3];
  307. }
  308. else
  309. {
  310. FixGreenbarArray[line + 0][0] = *(pU + (C_INC * 0) + 0);
  311. FixGreenbarArray[line + 0][1] = *(pU + (C_INC * 0) + 1);
  312. FixGreenbarArray[line + 0][2] = *(pU + (C_INC * 0) + 2);
  313. FixGreenbarArray[line + 0][3] = *(pU + (C_INC * 0) + 3);
  314. FixGreenbarArray[line + 1][0] = *(pV + (C_INC * 0) + 0);
  315. FixGreenbarArray[line + 1][1] = *(pV + (C_INC * 0) + 1);
  316. FixGreenbarArray[line + 1][2] = *(pV + (C_INC * 0) + 2);
  317. FixGreenbarArray[line + 1][3] = *(pV + (C_INC * 0) + 3);
  318. FixGreenbarArray[line + 2][0] = *(pU + (C_INC * 1) + 0);
  319. FixGreenbarArray[line + 2][1] = *(pU + (C_INC * 1) + 1);
  320. FixGreenbarArray[line + 2][2] = *(pU + (C_INC * 1) + 2);
  321. FixGreenbarArray[line + 2][3] = *(pU + (C_INC * 1) + 3);
  322. FixGreenbarArray[line + 3][0] = *(pV + (C_INC * 1) + 0);
  323. FixGreenbarArray[line + 3][1] = *(pV + (C_INC * 1) + 1);
  324. FixGreenbarArray[line + 3][2] = *(pV + (C_INC * 1) + 2);
  325. FixGreenbarArray[line + 3][3] = *(pV + (C_INC * 1) + 3);
  326. }
  327. pU += (2 * C_INC);
  328. pV += (2 * C_INC);
  329. }
  330. }
  331. //------------------------------------------------------------------------------
  332. //------------------------------------------------------------------------------
  333. /*
  334. *
  335. */
  336. static void
  337. TranslateP420ToI420 (PBYTE pInput, PBYTE pOutput, int width, int height,
  338. DWORD camVersion)
  339. {
  340. int line;
  341. int byte;
  342. int dxSrc;
  343. PDWORD pdwSrc;
  344. PDWORD pdwY;
  345. PWORD pwU;
  346. PWORD pwV;
  347. PBYTE pbSrc;
  348. PBYTE pbY;
  349. if (camVersion == SSI_YGAIN_MUL2)
  350. {
  351. // SSI version 4 --> Ygain has to be doubled
  352. pbSrc = (PBYTE) pInput;
  353. pbY = (PBYTE) pOutput;
  354. pwU = (PWORD) ((PBYTE) pbY + (width * height));
  355. pwV = (PWORD) ((PBYTE) pwU + ((width * height) >> 2));
  356. switch (width)
  357. {
  358. case SQSIF_X :
  359. pbSrc += ((((SQSIF_DY * SQCIF_X) + SQSIF_DX) * 3) / 2);
  360. dxSrc = ((2 * SQSIF_DX) * 3) / 2;
  361. break;
  362. case QSIF_X :
  363. pbSrc += ((((QSIF_DY * QCIF_X) + QSIF_DX) * 3) / 2);
  364. dxSrc = ((2 * QSIF_DX) * 3) / 2;
  365. break;
  366. case SIF_X :
  367. pbSrc += ((((SIF_DY * CIF_X) + SIF_DX) * 3) / 2);
  368. dxSrc = ((2 * SIF_DX) * 3) / 2;
  369. break;
  370. case QQCIF_X :
  371. pbSrc += ((((QQCIF_DY * SQCIF_X) + QQCIF_DX) * 3) / 2);
  372. dxSrc = ((2 * QQCIF_DX) * 3) / 2;
  373. break;
  374. case SSIF_X : // SSIF || SCIF
  375. if (height == SSIF_Y) {
  376. pbSrc += ((((SSIF_DY * CIF_X) + SSIF_DX) * 3) / 2);
  377. dxSrc = ((2 * SSIF_DX) * 3) / 2;
  378. }else{
  379. pbSrc += ((((SCIF_DY * CIF_X) + SCIF_DX) * 3) / 2);
  380. dxSrc = ((2 * SCIF_DX) * 3) / 2;
  381. }
  382. break;
  383. default : // xxCIF
  384. dxSrc = 0;
  385. break;
  386. }
  387. for (line = height >> 1; line > 0; line--)
  388. {
  389. for (byte = NO_YYYYCC_PER_LINE(width); byte > 0; byte--)
  390. {
  391. *pbY++ = (*pbSrc < 0x7F) ? (*pbSrc << 1) : 0xFF;
  392. pbSrc++;
  393. *pbY++ = (*pbSrc < 0x7F) ? (*pbSrc << 1) : 0xFF;
  394. pbSrc++;
  395. *pbY++ = (*pbSrc < 0x7F) ? (*pbSrc << 1) : 0xFF;
  396. pbSrc++;
  397. *pbY++ = (*pbSrc < 0x7F) ? (*pbSrc << 1) : 0xFF;
  398. pbSrc++;
  399. *pwU++ = (WORD) (* (PWORD) pbSrc);
  400. pbSrc += 2;
  401. }
  402. pbSrc += dxSrc;
  403. for (byte = NO_YYYYCC_PER_LINE(width); byte > 0; byte--)
  404. {
  405. *pbY++ = (*pbSrc < 0x7F) ? (*pbSrc << 1) : 0xFF;
  406. pbSrc++;
  407. *pbY++ = (*pbSrc < 0x7F) ? (*pbSrc << 1) : 0xFF;
  408. pbSrc++;
  409. *pbY++ = (*pbSrc < 0x7F) ? (*pbSrc << 1) : 0xFF;
  410. pbSrc++;
  411. *pbY++ = (*pbSrc < 0x7F) ? (*pbSrc << 1) : 0xFF;
  412. pbSrc++;
  413. *pwV++ = (WORD) (* (PWORD) pbSrc);
  414. pbSrc += 2;
  415. }
  416. pbSrc += dxSrc;
  417. }
  418. }
  419. else // NO_YGAIN_MULTIPLY
  420. {
  421. pdwY = (PDWORD) pOutput;
  422. pwU = (PWORD) ((PBYTE) pdwY + (width * height));
  423. pwV = (PWORD) ((PBYTE) pwU + ((width * height) >> 2));
  424. if (width == QQCIF_X)
  425. {
  426. pbSrc = (PBYTE) (pInput + ((((QQCIF_DY * SQCIF_X) + QQCIF_DX) * 3) / 2));
  427. dxSrc = ((2 * QQCIF_DX) * 3) / 2;
  428. for (line = height >> 1; line > 0; line--)
  429. {
  430. for (byte = NO_YYYYCC_PER_LINE(width); byte > 0; byte--)
  431. {
  432. *pdwY++ = *((PDWORD) pbSrc)++;
  433. *pwU++ = (WORD) (* (PWORD) pbSrc);
  434. pbSrc += 2;
  435. }
  436. pbSrc += dxSrc;
  437. for (byte = NO_YYYYCC_PER_LINE(width); byte > 0; byte--)
  438. {
  439. *pdwY++ = *((PDWORD) pbSrc)++;
  440. *pwV++ = (WORD) (* (PWORD) pbSrc);
  441. pbSrc += 2;
  442. }
  443. pbSrc += dxSrc;
  444. }
  445. }
  446. else
  447. {
  448. pdwSrc = (PDWORD) pInput;
  449. switch (width)
  450. {
  451. case SQSIF_X :
  452. pdwSrc += (((((SQSIF_DY * SQCIF_X) + SQSIF_DX) * 3) / 2) / sizeof (DWORD));
  453. dxSrc = (((2 * SQSIF_DX) * 3) / 2) / sizeof (DWORD);
  454. break;
  455. case QSIF_X :
  456. pdwSrc += (((((QSIF_DY * QCIF_X) + QSIF_DX) * 3) / 2) / sizeof (DWORD));
  457. dxSrc = (((2 * QSIF_DX) * 3) / 2) / sizeof (DWORD);
  458. break;
  459. case SIF_X :
  460. pdwSrc += (((((SIF_DY * CIF_X) + SIF_DX) * 3) / 2) / sizeof (DWORD));
  461. dxSrc = (((2 * SIF_DX) * 3) / 2) / sizeof (DWORD);
  462. break;
  463. case SSIF_X : // SSIF || SCIF
  464. if (height == SSIF_Y) {
  465. pdwSrc += (((((SSIF_DY * CIF_X) + SSIF_DX) * 3) / 2) / sizeof (DWORD));
  466. dxSrc = (((2 * SSIF_DX) * 3) / 2) / sizeof (DWORD);
  467. }else{
  468. pdwSrc += (((((SCIF_DY * CIF_X) + SCIF_DX) * 3) / 2) / sizeof (DWORD));
  469. dxSrc = (((2 * SCIF_DX) * 3) / 2) / sizeof (DWORD);
  470. }
  471. break;
  472. default : // xxCIF
  473. dxSrc = 0;
  474. break;
  475. }
  476. for (line = height >> 1; line > 0; line--)
  477. {
  478. for (byte = NO_YYYYCC_PER_LINE(width); byte > 0; byte--)
  479. {
  480. *pdwY++ = *pdwSrc++;
  481. *pwU++ = (WORD) (* (PWORD) pdwSrc);
  482. pdwSrc = (PDWORD) ((PBYTE) pdwSrc + 2);
  483. }
  484. pdwSrc += dxSrc;
  485. for (byte = NO_YYYYCC_PER_LINE(width); byte > 0; byte--)
  486. {
  487. *pdwY++ = *pdwSrc++;
  488. *pwV++ = (WORD) (* (PWORD) pdwSrc);
  489. pdwSrc = (PDWORD) ((PBYTE) pdwSrc + 2);
  490. }
  491. pdwSrc += dxSrc;
  492. }
  493. }
  494. }
  495. #ifdef PIX12_FIX
  496. if (width == CIF_X || width == QCIF_X || width == SQCIF_X)
  497. {
  498. FixPix12InI420 (pOutput, FALSE, width, height, camVersion);
  499. }
  500. #endif
  501. }
  502. /*
  503. ===========================================================================
  504. */
  505. static void
  506. TranslatePCFxToI420 (PBYTE pInput, PBYTE pOutput, int width, int height,
  507. DWORD camVersion)
  508. {
  509. int band;
  510. int line;
  511. int byte;
  512. PBYTE pSrc;
  513. PDWORD pYDst;
  514. PDWORD pCDst;
  515. PDWORD pSIF_Y;
  516. PDWORD pSIF_C;
  517. /*
  518. * For formats != 352x288, cropping has to be done.
  519. * The formats 320x240 and 240x180 can be derived from the 352x288 format.
  520. * The compressed data consists of 72 bands. A band contains the data for
  521. * 4 uncompressed lines. For the not 352x240 formats, the first 6 bands or
  522. * first 13 bands (320x240 or 240x180) of compressed data can be skipped.
  523. * This will be the cropping in the Y-direction.
  524. * One band is 528 bytes big for 4x compressed mode and 704 bytes big for
  525. * 3x compressed mode. It's dependent of the camera version which
  526. * compression mode will be selected.
  527. * For the not 352x288 formats, the uncompressed data is temporary stored
  528. * in the first not used bands.
  529. * One uncompressed band consists of 4x352=1408 bytes of Y followed by
  530. * 2x176=352 bytes of U and followed by 2x176 bytes of V.
  531. * This is a total of 2112 uncompressed bytes. So there's enough place
  532. * for this temporary storage (6x528-2112=1056 bytes left worst case)
  533. * This temporary uncompressed data is then cropped in the X direction.
  534. * The result is written to the buffer pointed by 'pOutput'
  535. */
  536. if (width == CIF_X)
  537. {
  538. pSrc = pInput;
  539. pYDst = (PDWORD) pOutput;
  540. pCDst = (PDWORD) pOutput + (I420_NO_Y_CIF / sizeof (DWORD));
  541. band = NO_BANDS_CIF;
  542. }
  543. else
  544. {
  545. pSrc = pInput;
  546. pYDst = (PDWORD) pInput;
  547. pCDst = (PDWORD) pInput + (I420_NO_Y_PER_BAND_CIF / sizeof (DWORD));
  548. pSIF_Y = (PDWORD) pOutput;
  549. if (width == SIF_X)
  550. {
  551. pSIF_C = (PDWORD) pOutput + (I420_NO_Y_SIF / sizeof (DWORD));
  552. if (camVersion >= SSI_CIF3)
  553. {
  554. pSrc += ((SIF_DY / NO_LINES_IN_BAND) * BytesPerBandCIF3);
  555. }
  556. else
  557. {
  558. pSrc += ((SIF_DY / NO_LINES_IN_BAND) * BytesPerBandCIF4);
  559. }
  560. band = NO_BANDS_SIF;
  561. }
  562. else // width == SSIF_X || width == SCIF
  563. {
  564. if (height == SSIF_Y) {
  565. pSIF_C = (PDWORD) pOutput + (I420_NO_Y_SSIF / sizeof (DWORD));
  566. // 13,5 bands to skip in start en 13,5 bands to skip at end
  567. // To make it easier : 13 bands to skip in start and 14 bytes at end
  568. if (camVersion >= SSI_CIF3)
  569. {
  570. pSrc += (((SSIF_DY - 2) / NO_LINES_IN_BAND) * BytesPerBandCIF3);
  571. }
  572. else
  573. {
  574. pSrc += (((SSIF_DY - 2) / NO_LINES_IN_BAND) * BytesPerBandCIF4);
  575. }
  576. band = NO_BANDS_SSIF;
  577. }else{
  578. pSIF_C = (PDWORD) pOutput + (I420_NO_Y_SCIF / sizeof (DWORD));
  579. if (camVersion >= SSI_CIF3)
  580. {
  581. pSrc += (((SCIF_DY - 2) / NO_LINES_IN_BAND) * BytesPerBandCIF3);
  582. }
  583. else
  584. {
  585. pSrc += (((SCIF_DY - 2) / NO_LINES_IN_BAND) * BytesPerBandCIF4);
  586. }
  587. band = NO_BANDS_SCIF;
  588. }
  589. }
  590. }
  591. for (; band > 0; band--)
  592. {
  593. DcDecompressBandToI420 (pSrc, (PBYTE) pYDst, camVersion,
  594. Y_BLOCK_BAND, (BOOLEAN) (width != CIF_X));
  595. if (width == CIF_X)
  596. {
  597. pYDst += (I420_NO_Y_PER_BAND_CIF / sizeof (DWORD));
  598. }
  599. else
  600. {
  601. if (width == SIF_X)
  602. {
  603. pYDst += (SIF_DX / sizeof (DWORD));
  604. for (line = NO_LINES_IN_BAND; line > 0; line--)
  605. {
  606. for (byte = (SIF_X / sizeof (DWORD)); byte > 0; byte--)
  607. {
  608. *pSIF_Y++ = *pYDst++;
  609. }
  610. pYDst += (( 2 * SIF_DX) / sizeof (DWORD));
  611. }
  612. pYDst = (PDWORD) pInput;
  613. }
  614. else // width == SSIF_X || width == SCIF_X
  615. {
  616. if ( height == SSIF_Y ){
  617. pYDst += (SSIF_DX / sizeof (DWORD));
  618. for (line = NO_LINES_IN_BAND ; line > 0; line--)
  619. {
  620. for (byte = (SSIF_X / sizeof (DWORD)); byte > 0; byte--)
  621. {
  622. *pSIF_Y++ = *pYDst++;
  623. }
  624. pYDst += (( 2 * SSIF_DX) / sizeof (DWORD));
  625. }
  626. pYDst = (PDWORD) pInput;
  627. }else{
  628. pYDst += (SCIF_DX / sizeof (DWORD));
  629. for (line = NO_LINES_IN_BAND ; line > 0; line--)
  630. {
  631. for (byte = (SCIF_X / sizeof (DWORD)); byte > 0; byte--)
  632. {
  633. *pSIF_Y++ = *pYDst++;
  634. }
  635. pYDst += (( 2 * SCIF_DX) / sizeof (DWORD));
  636. }
  637. pYDst = (PDWORD) pInput;
  638. }
  639. }
  640. }
  641. DcDecompressBandToI420 (pSrc, (PBYTE) pCDst, camVersion,
  642. UV_BLOCK_BAND, (BOOLEAN) (width != CIF_X));
  643. if (width == CIF_X)
  644. {
  645. pCDst += (I420_NO_U_PER_BAND_CIF / sizeof (DWORD));
  646. }
  647. else
  648. {
  649. if (width == SIF_X)
  650. {
  651. pCDst += ((SIF_DX / 2) / sizeof (DWORD));
  652. for (line = (NO_LINES_IN_BAND / 2); line > 0; line--)
  653. {
  654. for (byte = ((SIF_X / 2) / sizeof (DWORD)); byte > 0; byte--)
  655. {
  656. *pSIF_C++ = *pCDst++;
  657. }
  658. pCDst += ((2 * (SIF_DX / 2)) / sizeof (DWORD));
  659. }
  660. pSIF_C += ((I420_NO_U_SIF - I420_NO_U_PER_BAND_SIF) / sizeof (DWORD));
  661. for (line = (NO_LINES_IN_BAND / 2); line > 0; line--)
  662. {
  663. for (byte = ((SIF_X / 2) / sizeof (DWORD)); byte > 0; byte--)
  664. {
  665. *pSIF_C++ = *pCDst++;
  666. }
  667. pCDst += ((2 * (SIF_DX / 2)) / sizeof (DWORD));
  668. }
  669. pCDst = (PDWORD) pInput + (I420_NO_Y_PER_BAND_CIF / sizeof (DWORD));
  670. pSIF_C -= (I420_NO_U_SIF / sizeof (DWORD));
  671. }
  672. else // width == SSIF_X || width == SCIF_X
  673. {
  674. if (height == SSIF_Y){
  675. pCDst += ((SSIF_DX / 2) / sizeof (DWORD));
  676. for (line = (NO_LINES_IN_BAND / 2); line > 0; line--)
  677. {
  678. for (byte = ((SSIF_X / 2) / sizeof (DWORD)); byte > 0; byte--)
  679. {
  680. *pSIF_C++ = *pCDst++;
  681. }
  682. pCDst += ((2 * (SSIF_DX / 2)) / sizeof (DWORD));
  683. }
  684. pSIF_C += ((I420_NO_U_SSIF - I420_NO_U_PER_BAND_SSIF) / sizeof (DWORD));
  685. for (line = (NO_LINES_IN_BAND / 2); line > 0; line--)
  686. {
  687. for (byte = ((SSIF_X / 2) / sizeof (DWORD)); byte > 0; byte--)
  688. {
  689. *pSIF_C++ = *pCDst++;
  690. }
  691. pCDst += ((2 * (SSIF_DX / 2)) / sizeof (DWORD));
  692. }
  693. pCDst = (PDWORD) pInput + (I420_NO_Y_PER_BAND_CIF / sizeof (DWORD));
  694. pSIF_C -= (I420_NO_U_SSIF / sizeof (DWORD));
  695. }else{
  696. pCDst += ((SCIF_DX / 2) / sizeof (DWORD));
  697. for (line = (NO_LINES_IN_BAND / 2); line > 0; line--)
  698. {
  699. for (byte = ((SCIF_X / 2) / sizeof (DWORD)); byte > 0; byte--)
  700. {
  701. *pSIF_C++ = *pCDst++;
  702. }
  703. pCDst += ((2 * (SCIF_DX / 2)) / sizeof (DWORD));
  704. }
  705. pSIF_C += ((I420_NO_U_SCIF - I420_NO_U_PER_BAND_SCIF) / sizeof (DWORD));
  706. for (line = (NO_LINES_IN_BAND / 2); line > 0; line--)
  707. {
  708. for (byte = ((SCIF_X / 2) / sizeof (DWORD)); byte > 0; byte--)
  709. {
  710. *pSIF_C++ = *pCDst++;
  711. }
  712. pCDst += ((2 * (SCIF_DX / 2)) / sizeof (DWORD));
  713. }
  714. pCDst = (PDWORD) pInput + (I420_NO_Y_PER_BAND_CIF / sizeof (DWORD));
  715. pSIF_C -= (I420_NO_U_SCIF / sizeof (DWORD));
  716. }
  717. }
  718. }
  719. pSrc += (camVersion >= SSI_CIF3) ? BytesPerBandCIF3 : BytesPerBandCIF4;
  720. }
  721. if (width == CIF_X)
  722. {
  723. if (camVersion < SSI_8117_N3)
  724. {
  725. Fix16PixGreenbarInI420 (pOutput, width);
  726. }
  727. #ifdef PIX12_FIX
  728. FixPix12InI420 (pOutput, TRUE, width, height, camVersion);
  729. #endif
  730. }
  731. }