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.

2534 lines
79 KiB

  1. /*
  2. * @DEC_COPYRIGHT@
  3. */
  4. /*
  5. * HISTORY
  6. * $Log: sc_convert.c,v $
  7. * Revision 1.1.8.6 1996/10/28 17:32:17 Hans_Graves
  8. * Add use IsYUV422Sep() macro in ScConvertSepYUVToOther().
  9. * [1996/10/28 16:51:30 Hans_Graves]
  10. *
  11. * Revision 1.1.8.5 1996/10/02 18:42:50 Hans_Graves
  12. * Fix RGB 24-bit conversion in ScYuv411ToRgb().
  13. * [1996/10/02 18:32:51 Hans_Graves]
  14. *
  15. * Revision 1.1.8.4 1996/09/29 22:19:32 Hans_Graves
  16. * Added stride support to ScYuv411ToRgb()
  17. * [1996/09/29 21:27:17 Hans_Graves]
  18. *
  19. * Revision 1.1.8.3 1996/09/18 23:45:34 Hans_Graves
  20. * Added ScConvert1611PlanarTo411_C, ScConvert411sTo422s_C, and ScRgbToYuv411
  21. * [1996/09/18 21:52:27 Hans_Graves]
  22. *
  23. * Revision 1.1.8.2 1996/05/07 19:55:42 Hans_Graves
  24. * Added YUV 4:1:1 to RGB 32-bit conversion - C code
  25. * [1996/05/07 19:44:38 Hans_Graves]
  26. *
  27. * Revision 1.1.6.4 1996/04/11 20:21:57 Hans_Graves
  28. * Moved ScIsUpsideDown() from sc_convert_yuv.c
  29. * [1996/04/11 20:03:44 Hans_Graves]
  30. *
  31. * Revision 1.1.6.3 1996/04/09 16:04:24 Hans_Graves
  32. * Added ValidateBI_BITFIELDS(). Fixed BI_RGB 16 bit conversion in ScYuv411ToRgb()
  33. * [1996/04/09 14:46:27 Hans_Graves]
  34. *
  35. * Revision 1.1.6.2 1996/04/03 21:41:07 Hans_Graves
  36. * Change include path for <mmsystems.h>
  37. * [1996/04/03 21:37:55 Hans_Graves]
  38. *
  39. * Revision 1.1.4.4 1996/02/22 17:35:17 Bjorn_Engberg
  40. * Added support for BI_BITFIELDS 16 and BI_RGB 32 rendering.
  41. * [1996/02/22 17:31:35 Bjorn_Engberg]
  42. *
  43. * Revision 1.1.4.3 1996/01/02 18:30:33 Bjorn_Engberg
  44. * Got rid of compiler warnings: Added Casts
  45. * [1996/01/02 15:21:27 Bjorn_Engberg]
  46. *
  47. * Revision 1.1.4.2 1995/12/07 19:31:15 Hans_Graves
  48. * Added ScConvert422PlanarTo411_C()
  49. * [1995/12/07 17:44:00 Hans_Graves]
  50. *
  51. * Revision 1.1.2.21 1995/11/30 20:17:02 Hans_Graves
  52. * Cleaned up ScYuv422toRgb() routine
  53. * [1995/11/30 20:13:26 Hans_Graves]
  54. *
  55. * Revision 1.1.2.20 1995/11/28 22:47:28 Hans_Graves
  56. * Make XIMAGE 24 identical to BI_BITFIELDS pBGR
  57. * [1995/11/28 22:26:11 Hans_Graves]
  58. *
  59. * Added ScYuv1611ToRgb() routine for use by Indeo
  60. * [1995/11/28 21:34:28 Hans_Graves]
  61. *
  62. * Revision 1.1.2.19 1995/11/17 21:31:21 Hans_Graves
  63. * Add ScYuv411ToRgb() conversion routine.
  64. * [1995/11/17 20:50:51 Hans_Graves]
  65. *
  66. * Revision 1.1.2.18 1995/10/25 18:19:18 Bjorn_Engberg
  67. * Support Upside Down in ScRgbInterlToYuvInterl().
  68. * [1995/10/25 18:05:18 Bjorn_Engberg]
  69. *
  70. * Revision 1.1.2.17 1995/10/10 21:43:02 Bjorn_Engberg
  71. * Speeded up RgbToYuv code and made it table driven.
  72. * [1995/10/10 21:21:48 Bjorn_Engberg]
  73. *
  74. * Revision 1.1.2.16 1995/10/09 19:44:31 Bjorn_Engberg
  75. * Removed ValidateBI_BITFIELDS(), it's now in sc_convert_yuv.c
  76. * [1995/10/09 19:44:14 Bjorn_Engberg]
  77. *
  78. * Revision 1.1.2.15 1995/10/06 20:43:23 Farokh_Morshed
  79. * Enhance ScRgbInterlToYuvInterl to handle BI_BITFIELDS
  80. * [1995/10/06 20:42:43 Farokh_Morshed]
  81. *
  82. * Revision 1.1.2.14 1995/10/02 19:30:26 Bjorn_Engberg
  83. * Added support for Assebler YUV to RGB routines.
  84. * [1995/10/02 18:39:05 Bjorn_Engberg]
  85. *
  86. * Revision 1.1.2.13 1995/09/28 20:37:53 Farokh_Morshed
  87. * Handle negative Height
  88. * [1995/09/28 20:37:39 Farokh_Morshed]
  89. *
  90. * Revision 1.1.2.12 1995/09/26 15:58:47 Paul_Gauthier
  91. * Fix mono JPEG to interlaced 422 YUV conversion
  92. * [1995/09/26 15:58:09 Paul_Gauthier]
  93. *
  94. * Revision 1.1.2.11 1995/09/22 18:56:35 Paul_Gauthier
  95. * {** Merge Information **}
  96. * {** Command used: bsubmit **}
  97. * {** Ancestor revision: 1.1.2.7 **}
  98. * {** Merge revision: 1.1.2.10 **}
  99. * {** End **}
  100. * Use faster method for 16bit YUV output for TGA2
  101. * [1995/09/22 18:39:55 Paul_Gauthier]
  102. *
  103. * Revision 1.1.2.10 1995/09/21 18:26:45 Farokh_Morshed
  104. * When BI_RGB or BI_BITFIELDS, invert the image while translating from
  105. * YUV to RGB. Also fix the coefficient for the YUV colors.
  106. * This work was actually done by Bjorn
  107. * [1995/09/21 18:26:19 Farokh_Morshed]
  108. *
  109. * Revision 1.1.2.9 1995/09/20 17:39:18 Karen_Dintino
  110. * Add RGB support to JPEG
  111. * [1995/09/20 17:37:22 Karen_Dintino]
  112. *
  113. * Revision 1.1.2.8 1995/09/20 14:59:31 Bjorn_Engberg
  114. * Port to NT
  115. * [1995/09/20 14:41:10 Bjorn_Engberg]
  116. *
  117. * Revision 1.1.2.7 1995/09/18 19:47:47 Paul_Gauthier
  118. * Added conversion of MPEG planar 4:1:1 to interleaved 4:2:2
  119. * [1995/09/18 19:46:13 Paul_Gauthier]
  120. *
  121. * Revision 1.1.2.6 1995/09/14 14:40:34 Karen_Dintino
  122. * Move RgbToYuv out of rendition
  123. * [1995/09/14 14:26:13 Karen_Dintino]
  124. *
  125. * Revision 1.1.2.5 1995/09/11 18:47:25 Farokh_Morshed
  126. * {** Merge Information **}
  127. * {** Command used: bsubmit **}
  128. * {** Ancestor revision: 1.1.2.3 **}
  129. * {** Merge revision: 1.1.2.4 **}
  130. * {** End **}
  131. * Support BI_BITFIELDS format
  132. * [1995/09/11 18:43:39 Farokh_Morshed]
  133. *
  134. * Revision 1.1.2.4 1995/09/05 17:17:34 Paul_Gauthier
  135. * Fix for softjpeg decompression JPEG -> BICOMP_DECYUVDIB
  136. * [1995/09/05 17:17:09 Paul_Gauthier]
  137. *
  138. * Revision 1.1.2.3 1995/08/03 15:01:06 Hans_Graves
  139. * Moved ScConvert422ToYUV_char_C() from h261.
  140. * [1995/08/03 14:46:23 Hans_Graves]
  141. *
  142. * Revision 1.1.2.2 1995/05/31 18:07:27 Hans_Graves
  143. * Inclusion in new SLIB location.
  144. * [1995/05/31 16:06:30 Hans_Graves]
  145. *
  146. * $EndLog$
  147. */
  148. /*****************************************************************************
  149. ** Copyright (c) Digital Equipment Corporation, 1993 **
  150. ** **
  151. ** All Rights Reserved. Unpublished rights reserved under the copyright **
  152. ** laws of the United States. **
  153. ** **
  154. ** The software contained on this media is proprietary to and embodies **
  155. ** the confidential technology of Digital Equipment Corporation. **
  156. ** Possession, use, duplication or dissemination of the software and **
  157. ** media is authorized only pursuant to a valid written license from **
  158. ** Digital Equipment Corporation. **
  159. ** **
  160. ** RESTRICTED RIGHTS LEGEND Use, duplication, or disclosure by the U.S. **
  161. ** Government is subject to restrictions as set forth in Subparagraph **
  162. ** (c)(1)(ii) of DFARS 252.227-7013, or in FAR 52.227-19, as applicable. **
  163. ******************************************************************************/
  164. /*
  165. **
  166. ** Miscellaneous conversion utility subroutines
  167. **
  168. ** Author(s): Victor Bahl
  169. ** Date: May 27, 1993
  170. **
  171. */
  172. #include <stdio.h> /* NULL */
  173. #include <sys/types.h>
  174. #ifdef WIN32
  175. #include <windows.h>
  176. #include <mmsystem.h>
  177. #else /* !WIN32 */
  178. #include <mmsystem.h>
  179. #endif /* !WIN32 */
  180. #include "SC_conv.h"
  181. #include "SC_err.h"
  182. #ifndef BI_DECSEPRGBDIB
  183. #define BI_DECSEPRGBDIB mmioFOURCC('D','S','R','G')
  184. #endif
  185. #define NEW_YCBCR /* Use new YUV to RGB coefficients */
  186. /*
  187. ** Name: ScCreateBMHeader
  188. ** Purpose: Allocate memory for a (Microsoft specified) bitmap header and
  189. ** fill in the appropriate fields
  190. **
  191. */
  192. BITMAPINFOHEADER *ScCreateBMHeader(int width, int height, int bpp,
  193. int format, int ncolors)
  194. {
  195. BITMAPINFOHEADER *pHead;
  196. int struct_size = sizeof(BITMAPINFOHEADER) + ncolors*sizeof(RGBQUAD);
  197. if ((pHead = (BITMAPINFOHEADER *)ScAlloc(struct_size)) == NULL) {
  198. puts("Can't Allocate memory for image headers");
  199. return NULL;
  200. }
  201. pHead->biSize = sizeof(BITMAPINFOHEADER);
  202. pHead->biWidth = width;
  203. pHead->biHeight = height;
  204. pHead->biPlanes = 1;
  205. pHead->biBitCount = (WORD)bpp;
  206. pHead->biCompression = format;
  207. pHead->biSizeImage = 0;
  208. pHead->biXPelsPerMeter = 0;
  209. pHead->biYPelsPerMeter = 0;
  210. pHead->biClrUsed = ncolors;
  211. pHead->biClrImportant = 0;
  212. return pHead;
  213. }
  214. /*
  215. ** Function: ScIsUpsideDown
  216. ** Descript: Return TRUE if the current combination
  217. ** of input and output formats and image
  218. ** heights means that the image should be
  219. ** flipped during the render stage.
  220. */
  221. int ScIsUpsideDown( BITMAPINFOHEADER *lpbiIn,
  222. BITMAPINFOHEADER *lpbiOut )
  223. {
  224. int ups = 0 ;
  225. if( lpbiIn )
  226. ups = (((lpbiIn->biCompression == BI_RGB) ||
  227. (lpbiIn->biCompression == BI_BITFIELDS)) ^
  228. ((int) lpbiIn->biHeight < 0)) ;
  229. if( lpbiOut )
  230. ups ^= (((lpbiOut->biCompression == BI_RGB) ||
  231. (lpbiOut->biCompression == BI_BITFIELDS)) ^
  232. ((int) lpbiOut->biHeight < 0)) ;
  233. return ups ;
  234. }
  235. /*
  236. **++
  237. ** FUNCTIONAL_DESCRIPTION:
  238. ** Return an enum value that validates a BI_BITFIELDS bitmapinfoheader
  239. ** with BI_BITFIELDS format.
  240. **
  241. ** FORMAL PARAMETERS:
  242. ** Pointer to bitmapinfoheader
  243. ** RETURN VALUE:
  244. ** A value from enum type ValidBI_BITFIELDSKinds.
  245. **/
  246. enum ValidBI_BITFIELDSKinds ValidateBI_BITFIELDS(
  247. LPBITMAPINFOHEADER lpbi)
  248. {
  249. DWORD *MaskPtr;
  250. if (lpbi == NULL || lpbi->biCompression != BI_BITFIELDS)
  251. return InvalidBI_BITFIELDS;
  252. MaskPtr = (DWORD *)&lpbi[1];
  253. /*
  254. * For 32-bit BI_BITFIELDS, we support
  255. * only the special cases 00RRGGBB and 00BBGGRR.
  256. */
  257. if( lpbi->biBitCount == 32 ) {
  258. if (MaskPtr[1] != 0x0000FF00U)
  259. return InvalidBI_BITFIELDS;
  260. else if (MaskPtr[0] == 0x00FF0000U && MaskPtr[2] == 0x000000FFU)
  261. return pRGB;
  262. else if (MaskPtr[0] == 0x000000FFU && MaskPtr[2] == 0x00FF0000U)
  263. return pBGR;
  264. else
  265. return InvalidBI_BITFIELDS;
  266. }
  267. #ifdef WIN32
  268. /*
  269. * For 16-bit BI_BITFIELDS, we support any legal
  270. * color arrangement, but RGB565 and RGB555 are
  271. * recognized as special since we have extra
  272. * fast assembler code for those cases.
  273. */
  274. else if( lpbi->biBitCount == 16 ) {
  275. int i ;
  276. if( MaskPtr[2] == 0x001f ) {
  277. if( MaskPtr[0] == 0xf800 && MaskPtr[1] == 0x07e0 )
  278. return pRGB565 ;
  279. else if( MaskPtr[0] == 0x7c00 && MaskPtr[1] == 0x03e00 )
  280. return pRGB555 ;
  281. }
  282. /*
  283. * Generic case: First make sure that each mask is
  284. * a 16-bit mask.
  285. */
  286. if( (MaskPtr[0] | MaskPtr[1] | MaskPtr[2]) & ~0x0000ffff )
  287. return InvalidBI_BITFIELDS ;
  288. /*
  289. * Masks must not overlap.
  290. */
  291. if( (MaskPtr[0] & MaskPtr[1]) ||
  292. (MaskPtr[0] & MaskPtr[2]) ||
  293. (MaskPtr[1] & MaskPtr[2]) )
  294. return InvalidBI_BITFIELDS ;
  295. /*
  296. * Make sure each mask contains a contiguous
  297. * sequence of 1's (or is 0).
  298. */
  299. for( i=0 ; i<3 ; i++ ) {
  300. DWORD v = MaskPtr[i] ;
  301. if( (((v-1)|v)+1)&v )
  302. return InvalidBI_BITFIELDS ;
  303. }
  304. /*
  305. * If we pass all these tests, we have
  306. * a valid generic 16-bit BI_BITFIELDS case.
  307. */
  308. return pRGBnnn ;
  309. }
  310. #endif /* WIN32 */
  311. /*
  312. * No other biBitCounts are supported.
  313. */
  314. return InvalidBI_BITFIELDS ;
  315. }
  316. /*********************** Conversion Routines ***************************/
  317. static void sc_ExtractBlockNonInt(u_char *InData, float **OutData,
  318. int ByteWidth, int x, int y)
  319. {
  320. register int i,j;
  321. u_char *Inp, *IStart = InData + 8*y*ByteWidth + 8*x;
  322. for (i = 0 , Inp = IStart ; i < 8 ; i++ , Inp += ByteWidth)
  323. for (j = 0 ; j < 8 ; j++)
  324. *((*OutData)++) = (float)((int)(*Inp++) - 128);
  325. }
  326. /*
  327. ** Name: ScConvertSepYUVToOther
  328. ** Purpose: Convert Seperated YUV 422 to another format
  329. **
  330. */
  331. ScStatus_t ScConvertSepYUVToOther(BITMAPINFOHEADER *InBmh,
  332. BITMAPINFOHEADER *OutBmh,
  333. u_char *OutImage,
  334. u_char *YData, u_char *CbData, u_char *CrData)
  335. {
  336. /*
  337. ** no need to do extensive checking, DecompressBegin and CompressBegin
  338. ** should take care of static checking (eg. valid output colorspace
  339. */
  340. /*
  341. ** Are we converting from SepYUV to RGB ?
  342. */
  343. if ((OutBmh->biCompression == BI_RGB) ||
  344. (OutBmh->biCompression == BI_BITFIELDS) ||
  345. (OutBmh->biCompression == BI_DECXIMAGEDIB) ||
  346. (OutBmh->biCompression == BI_DECSEPRGBDIB)) {
  347. /*
  348. ** It is assumed that YUV is subsampled 4:2:2, we will need to
  349. ** generalize the code below to handle other cases as well -- VB
  350. */
  351. if (InBmh->biBitCount == 8)
  352. ScYuv422ToRgb (OutBmh, YData, NULL, NULL, OutImage);
  353. else
  354. ScYuv422ToRgb (OutBmh, YData, CbData, CrData, OutImage);
  355. }
  356. /*
  357. ** Are we converting from SepYUV to Interlaced YUV ?
  358. */
  359. else if (IsYUV422Sep(OutBmh->biCompression))
  360. {
  361. /*
  362. ** It is assumed that YUV is subsampled 4:2:2, we will need to
  363. ** generalize the code below to handle other cases as well
  364. ** XXX - Bad idea to do this here, should be done as part of
  365. ** decompression (VB)
  366. ** XXX - While we can move the Sep YUV to 422 interleaved
  367. ** to decompression, we also need a copy here so we
  368. ** can use this as a general purpose dither'ing
  369. ** device. (JPL)
  370. */
  371. int i, j;
  372. /*
  373. ** If the input format is Mono JPEG and the output format is
  374. ** packed YUV422, we must reset the U and V values to neutral (Gray).
  375. */
  376. if (InBmh->biBitCount == 8) {
  377. #ifdef __alpha
  378. /*
  379. * If we're an Alpha, and the buffer is quadword
  380. * aligned, we can use 64-bit transfers.
  381. */
  382. if( ((INT_PTR) OutImage & 0x7) == 0 )
  383. {
  384. _int64 val = 0x7f007f007f007f00L ;
  385. _int64 *iptr = (_int64 *) OutImage ;
  386. for( i=(OutBmh->biWidth*abs(OutBmh->biHeight)>>2) ; i>0 ; i-- )
  387. *iptr++ = val ;
  388. }
  389. else
  390. #endif /* __alpha */
  391. {
  392. int val = 0x7f007f00 ;
  393. int *iptr = (int *) OutImage ;
  394. for( i=(OutBmh->biWidth*abs(OutBmh->biHeight)>>1) ; i>0 ; i-- )
  395. *iptr++ = val ;
  396. }
  397. /*
  398. ** Plug in the luminance samples
  399. */
  400. for( i=(OutBmh->biWidth * abs(OutBmh->biHeight)) ; i>0 ; i-- ) {
  401. *OutImage = *YData++;
  402. OutImage +=2;
  403. }
  404. }
  405. /*
  406. ** Color input
  407. */
  408. else {
  409. /* If this is quad padded in both X and Y and quad aligned,
  410. ** we can call the assembly routine
  411. */
  412. if ( (abs(OutBmh->biHeight) & 0x7) == 0 &&
  413. (OutBmh->biWidth & 0x7) == 0 &&
  414. ((ULONG_PTR)OutImage & 0xf) == 0 )
  415. {
  416. ScConvert422PlanarTo422i(YData, CbData, CrData, OutImage,
  417. OutBmh->biWidth, abs(OutBmh->biHeight));
  418. }
  419. else {
  420. for (i=0; i<abs(OutBmh->biHeight); i++)
  421. /* Remember, pixels are 16 bit in interleaved YUV. That
  422. ** means the 4 bytes below represent two pixels so our
  423. ** loop should be for half the width.
  424. */
  425. for (j=0; j<OutBmh->biWidth>>1; j++) { /* Note: was j+=2 */
  426. *OutImage++ = *YData++;
  427. *OutImage++ = *CbData++;
  428. *OutImage++ = *YData++;
  429. *OutImage++ = *CrData++;
  430. }
  431. }
  432. }
  433. }
  434. else return(ScErrorUnrecognizedFormat);
  435. return(ScErrorNone);
  436. }
  437. /*
  438. ** Name: ScYuv411ToRgb
  439. ** Purpose: convert 16-bit YCrCb 4:1:1 to an 16/24/32-bit RGB
  440. **
  441. ** Note: The code below is pixel based and is inefficient, we
  442. ** plan to replace faster assembly code
  443. */
  444. ScStatus_t ScYuv411ToRgb (BITMAPINFOHEADER *Bmh, u_char *Y, u_char *Cb,
  445. u_char *Cr, u_char *ImageOut, int Width, int Height, long stride)
  446. {
  447. const int pixels = Width;
  448. int lines = Height;
  449. register int row, col;
  450. register int Luma, U, V;
  451. /* Variables to hold R, G and B values for a 2x2 matrix of pixels */
  452. int R1,R2,R3,R4;
  453. int G1,G2,G3,G4;
  454. int B1,B2,B3,B4;
  455. int Ups = 0, tmp; /* Flip image upside down */
  456. u_char *Y1=Y, *Y2=Y+pixels;
  457. #define _LoadRGBfrom411() \
  458. R1 = R2 = R3 = R4 = (int) ( + (1.596 * V)); \
  459. G1 = G2 = G3 = G4 = (int) (- (0.391 * U) - (0.813 * V)); \
  460. B1 = B2 = B3 = B4 = (int) (+ (2.018 * U) ); \
  461. Luma = (int) (((int) *(Y1++) - 16) * 1.164); \
  462. R1 += Luma; G1 +=Luma; B1 += Luma; \
  463. Luma = (int) (((int) *(Y1++) - 16) * 1.164); \
  464. R2 += Luma; G2 +=Luma; B2 += Luma; \
  465. if ((R1 | G1 | B1 | R2 | G2 | B2) & 0xffffff00) { \
  466. if (R1<0) R1=0; else if (R1>255) R1=255; \
  467. if (G1<0) G1=0; else if (G1>255) G1=255; \
  468. if (B1<0) B1=0; else if (B1>255) B1=255; \
  469. if (R2<0) R2=0; else if (R2>255) R2=255; \
  470. if (G2<0) G2=0; else if (G2>255) G2=255; \
  471. if (B2<0) B2=0; else if (B2>255) B2=255; \
  472. } \
  473. Luma = (int) (((int) *(Y2++) - 16) * 1.164); \
  474. R3 += Luma; G3 +=Luma; B3 += Luma; \
  475. Luma = (int) (((int) *(Y2++) - 16) * 1.164); \
  476. R4 += Luma; G4 +=Luma; B4 += Luma; \
  477. if ((R3 | G3 | B3 | R4 | G4 | B4) & 0xffffff00) { \
  478. if (R3<0) R3=0; else if (R3>255) R3=255; \
  479. if (G3<0) G3=0; else if (G3>255) G3=255; \
  480. if (B3<0) B3=0; else if (B3>255) B3=255; \
  481. if (R4<0) R4=0; else if (R4>255) R4=255; \
  482. if (G4<0) G4=0; else if (G4>255) G4=255; \
  483. if (B4<0) B4=0; else if (B4>255) B4=255; \
  484. }
  485. /*
  486. * Normally, images are stored right side up, that is with the
  487. * first pixel in the buffer corresponding to the top left pixel
  488. * in the image.
  489. *
  490. * The Microsoft standard Device Independent bitmap formats BI_RGB and
  491. * BI_BITFIELD are stored with the lower left pixel first. We view that
  492. * as upside down.
  493. *
  494. * Each format can also have a negative height, which also signifes
  495. * upside down.
  496. *
  497. * Since two negatives makes a positive, that means that BI_ formats with
  498. * negative height are right side up.
  499. */
  500. if( Bmh->biCompression == BI_RGB ||
  501. Bmh->biCompression == BI_BITFIELDS )
  502. Ups = 1 ;
  503. if( lines < 0 ) {
  504. Ups = 1-Ups ;
  505. lines = -lines ;
  506. }
  507. /*
  508. ** The assumption is that YCrCb are subsampled 4:1:1
  509. ** YSize = lines * pixels
  510. ** CbSize = CrSize = (lines*pixels)/4
  511. */
  512. switch (Bmh->biCompression)
  513. {
  514. case BI_RGB:
  515. switch (Bmh->biBitCount)
  516. {
  517. case 15:
  518. {
  519. u_short *Sout1 = (u_short *)ImageOut, *Sout2=Sout1+pixels;
  520. for (row = 0; row < lines; row+=2)
  521. {
  522. if (Ups)
  523. {
  524. tmp = stride * (lines-row-1) ;
  525. Sout1 = (u_short *)ImageOut+tmp; /* For 16-bit */
  526. Sout2=Sout1-stride;
  527. }
  528. else
  529. {
  530. tmp = stride * row;
  531. Sout1 = (u_short *)ImageOut+tmp; /* For 16-bit */
  532. Sout2=Sout1+stride;
  533. }
  534. Y2=Y1+pixels;
  535. for (col = 0; col < pixels; col += 2)
  536. {
  537. U = *Cb++ - 128;
  538. V = *Cr++ - 128;
  539. _LoadRGBfrom411();
  540. *(Sout1++) = ((R1&0xf8)<<7)|((G1&0xf8)<<2)|((B1&0xf8)>>3);
  541. *(Sout1++) = ((R2&0xf8)<<7)|((G2&0xf8)<<2)|((B2&0xf8)>>3);
  542. *(Sout2++) = ((R3&0xf8)<<7)|((G3&0xf8)<<2)|((B3&0xf8)>>3);
  543. *(Sout2++) = ((R4&0xf8)<<7)|((G4&0xf8)<<2)|((B4&0xf8)>>3);
  544. }
  545. Y1=Y2;
  546. }
  547. }
  548. break;
  549. case 16:
  550. {
  551. u_short *Sout1 = (u_short *)ImageOut, *Sout2=Sout1+pixels;
  552. for (row = 0; row < lines; row+=2)
  553. {
  554. if (Ups)
  555. {
  556. tmp = stride * (lines-row-1) ;
  557. Sout1 = (u_short *)ImageOut+tmp; /* For 16-bit */
  558. Sout2=Sout1-stride;
  559. }
  560. else
  561. {
  562. tmp = stride * row;
  563. Sout1 = (u_short *)ImageOut+tmp; /* For 16-bit */
  564. Sout2=Sout1+stride;
  565. }
  566. Y2=Y1+pixels;
  567. for (col = 0; col < pixels; col += 2)
  568. {
  569. U = *Cb++ - 128;
  570. V = *Cr++ - 128;
  571. _LoadRGBfrom411();
  572. #ifdef WIN95 /* RGB 565 - 16 bit */
  573. *(Sout1++) = ((R1&0xf8)<<8)|((G1&0xfC)<<3)|((B1&0xf8)>>3);
  574. *(Sout1++) = ((R2&0xf8)<<8)|((G2&0xfC)<<3)|((B2&0xf8)>>3);
  575. *(Sout2++) = ((R3&0xf8)<<8)|((G3&0xfC)<<3)|((B3&0xf8)>>3);
  576. *(Sout2++) = ((R4&0xf8)<<8)|((G4&0xfC)<<3)|((B4&0xf8)>>3);
  577. #else /* RGB 555 - 15 bit */
  578. *(Sout1++) = ((R1&0xf8)<<7)|((G1&0xf8)<<2)|((B1&0xf8)>>3);
  579. *(Sout1++) = ((R2&0xf8)<<7)|((G2&0xf8)<<2)|((B2&0xf8)>>3);
  580. *(Sout2++) = ((R3&0xf8)<<7)|((G3&0xf8)<<2)|((B3&0xf8)>>3);
  581. *(Sout2++) = ((R4&0xf8)<<7)|((G4&0xf8)<<2)|((B4&0xf8)>>3);
  582. #endif
  583. }
  584. Y1=Y2;
  585. }
  586. }
  587. break;
  588. case 24:
  589. {
  590. u_char *Cout1, *Cout2;
  591. stride*=3;
  592. for (row = 0; row < lines; row+=2)
  593. {
  594. if (Ups)
  595. {
  596. tmp = stride * (lines-row-1) ;
  597. Cout1 = (u_char *)(ImageOut + tmp); /* For 24-bit */
  598. Cout2=Cout1-stride;
  599. }
  600. else
  601. {
  602. tmp = stride * row;
  603. Cout1 = (u_char *)(ImageOut + tmp); /* For 24-bit */
  604. Cout2=Cout1+stride;
  605. }
  606. Y2=Y1+pixels;
  607. for (col = 0; col < pixels; col += 2)
  608. {
  609. U = *Cb++ - 128;
  610. V = *Cr++ - 128;
  611. _LoadRGBfrom411();
  612. *(Cout1++) = (u_char)B1; *(Cout1++) = (u_char)G1; *(Cout1++) = (u_char)R1;
  613. *(Cout1++) = (u_char)B2; *(Cout1++) = (u_char)G2; *(Cout1++) = (u_char)R2;
  614. *(Cout2++) = (u_char)B3; *(Cout2++) = (u_char)G3; *(Cout2++) = (u_char)R3;
  615. *(Cout2++) = (u_char)B4; *(Cout2++) = (u_char)G4; *(Cout2++) = (u_char)R4;
  616. }
  617. Y1=Y2;
  618. }
  619. }
  620. break;
  621. case 32:
  622. {
  623. unsigned dword *Wout1 = (unsigned dword *)ImageOut,
  624. *Wout2=Wout1+pixels;
  625. for (row = 0; row < lines; row+=2)
  626. {
  627. if (Ups)
  628. {
  629. tmp = stride * (lines-row-1);
  630. Wout1 = (unsigned dword *)ImageOut + tmp;
  631. Wout2=Wout1-stride;
  632. }
  633. else
  634. {
  635. tmp = stride * row;
  636. Wout1 = (unsigned dword *)ImageOut + tmp;
  637. Wout2=Wout1+stride;
  638. }
  639. Y2=Y1+pixels;
  640. for (col = 0; col < pixels; col += 2)
  641. {
  642. U = *Cb++ - 128;
  643. V = *Cr++ - 128;
  644. _LoadRGBfrom411();
  645. *(Wout1++) = (R1<<16) | (G1<<8) | B1;
  646. *(Wout1++) = (R2<<16) | (G2<<8) | B2;
  647. *(Wout2++) = (R3<<16) | (G3<<8) | B3;
  648. *(Wout2++) = (R4<<16) | (G4<<8) | B4;
  649. }
  650. Y1=Y2;
  651. }
  652. }
  653. break;
  654. }
  655. break;
  656. case BI_DECSEPRGBDIB: /* 24-bit separate RGB */
  657. {
  658. u_char *RData1, *GData1, *BData1;
  659. u_char *RData2, *GData2, *BData2;
  660. RData1 = ImageOut;
  661. GData1 = RData1 + (pixels * lines);
  662. BData1 = GData1 + (pixels * lines);
  663. RData2 = RData1 + pixels;
  664. GData2 = GData1 + pixels;
  665. BData2 = BData1 + pixels;
  666. for (row = 0; row < lines; row+=2)
  667. {
  668. Y2=Y1+pixels;
  669. for (col = 0; col < pixels; col += 2)
  670. {
  671. U = *Cb++ - 128;
  672. V = *Cr++ - 128;
  673. _LoadRGBfrom411();
  674. *(RData1++) = (u_char)R1; *(RData1++) = (u_char)R2;
  675. *(RData2++) = (u_char)R3; *(RData2++) = (u_char)R4;
  676. *(GData1++) = (u_char)G1; *(GData1++) = (u_char)G2;
  677. *(GData2++) = (u_char)G3; *(GData2++) = (u_char)G4;
  678. *(BData1++) = (u_char)B1; *(BData1++) = (u_char)B2;
  679. *(BData2++) = (u_char)B3; *(BData2++) = (u_char)B4;
  680. }
  681. RData1=RData2;
  682. RData2=RData1+pixels;
  683. Y1=Y2;
  684. }
  685. }
  686. break;
  687. case BI_DECXIMAGEDIB: /* XIMAGE 24 == pBGR */
  688. case BI_BITFIELDS: /* 32-bit RGB */
  689. {
  690. unsigned dword *Iout1 = (unsigned dword *)ImageOut,
  691. *Iout2=Iout1+pixels;
  692. if (ValidateBI_BITFIELDS(Bmh) == pRGB)
  693. for (row = 0; row < lines; row+=2)
  694. {
  695. if (Ups)
  696. {
  697. tmp = stride * (lines-row-1);
  698. Iout1 = (unsigned dword *)ImageOut+tmp; /* For 32-bit */
  699. Iout2=Iout1-stride;
  700. }
  701. else
  702. {
  703. tmp = stride * row;
  704. Iout1 = (unsigned dword *)ImageOut+tmp; /* For 32-bit */
  705. Iout2=Iout1+stride;
  706. }
  707. Y2=Y1+pixels;
  708. for (col = 0; col < pixels; col += 2)
  709. {
  710. U = *Cb++ - 128;
  711. V = *Cr++ - 128;
  712. _LoadRGBfrom411();
  713. *(Iout1++) = (R1<<16) | (G1<<8) | B1;
  714. *(Iout1++) = (R2<<16) | (G2<<8) | B2;
  715. *(Iout2++) = (R3<<16) | (G3<<8) | B3;
  716. *(Iout2++) = (R4<<16) | (G4<<8) | B4;
  717. }
  718. Y1=Y2;
  719. }
  720. else /* pBGR and XIMAGE 24-bit */
  721. for (row = 0; row < lines; row+=2)
  722. {
  723. if (Ups)
  724. {
  725. tmp = stride * (lines-row-1);
  726. Iout1 = (unsigned dword *)ImageOut+tmp; /* For 32-bit */
  727. Iout2=Iout1-stride;
  728. }
  729. else
  730. {
  731. tmp = stride * row;
  732. Iout1 = (unsigned dword *)ImageOut+tmp; /* For 32-bit */
  733. Iout2=Iout1+stride;
  734. }
  735. Y2=Y1+pixels;
  736. for (col = 0; col < pixels; col += 2)
  737. {
  738. U = *Cb++ - 128;
  739. V = *Cr++ - 128;
  740. _LoadRGBfrom411();
  741. *(Iout1++) = (B1<<16) | (G1<<8) | R1;
  742. *(Iout1++) = (B2<<16) | (G2<<8) | R2;
  743. *(Iout2++) = (B3<<16) | (G3<<8) | R3;
  744. *(Iout2++) = (B4<<16) | (G4<<8) | R4;
  745. }
  746. Y1=Y2;
  747. }
  748. }
  749. break;
  750. default:
  751. return(ScErrorUnrecognizedFormat);
  752. }
  753. return (NoErrors);
  754. }
  755. /*
  756. ** Name: ScYuv1611ToRgb
  757. ** Purpose: convert 16-bit YCrCb 16:1:1 (YUV9/YVU9) to 16/24/32-bit RGB
  758. **
  759. ** Note: The code below is pixel based and is inefficient, we
  760. ** plan to replace faster assembly code
  761. ** This routine is used by Indeo, which actually only has 7-bits for
  762. ** Y, U and V components. The 8th bits are ignored.
  763. */
  764. ScStatus_t ScYuv1611ToRgb (BITMAPINFOHEADER *Bmh, u_char *Y, u_char *Cb,
  765. u_char *Cr, u_char *ImageOut)
  766. {
  767. const int pixels = Bmh->biWidth;
  768. int lines = Bmh->biHeight;
  769. register int row, col, i;
  770. register int Luma, U, V;
  771. /* Variables to hold R, G and B values for a 4x4 matrix of pixels */
  772. int R[16], G[16], B[16], tmpR, tmpG, tmpB, cR, cG, cB;
  773. int Ups = 0, tmp; /* Flip image upside down */
  774. u_char *Y0=Y, *Y1, *Y2, *Y3;
  775. #define _LoadRGBfrom1611() \
  776. cR=(int) ( + (1.596 * V));\
  777. cG=(int) (-(0.391 * U) - (0.813 * V));\
  778. cB=(int) (+(2.018 * U) );\
  779. for (i=0; i<4; i++) { \
  780. Luma = (int) ((((int)(*Y0++)<<1) - 16) * 1.164); \
  781. tmpR=cR + Luma; tmpG=cG + Luma; tmpB=cB + Luma; \
  782. if ((tmpR | tmpG | tmpB) & 0xffffff00) { \
  783. if (tmpR<0) R[i]=0; else if (tmpR>255) R[i]=255; else R[i]=tmpR; \
  784. if (tmpG<0) G[i]=0; else if (tmpG>255) G[i]=255; else G[i]=tmpG; \
  785. if (tmpB<0) B[i]=0; else if (tmpB>255) B[i]=255; else B[i]=tmpB; \
  786. } else { R[i]=tmpR; G[i]=tmpG; B[i]=tmpB; } \
  787. } \
  788. for (; i<8; i++) { \
  789. Luma = (int) ((((int)(*Y1++)<<1) - 16) * 1.164); \
  790. tmpR=cR + Luma; tmpG=cG + Luma; tmpB=cB + Luma; \
  791. if ((tmpR | tmpG | tmpB) & 0xffffff00) { \
  792. if (tmpR<0) R[i]=0; else if (tmpR>255) R[i]=255; else R[i]=tmpR; \
  793. if (tmpG<0) G[i]=0; else if (tmpG>255) G[i]=255; else G[i]=tmpG; \
  794. if (tmpB<0) B[i]=0; else if (tmpB>255) B[i]=255; else B[i]=tmpB; \
  795. } else { R[i]=tmpR; G[i]=tmpG; B[i]=tmpB; } \
  796. } \
  797. for (; i<12; i++) { \
  798. Luma = (int) ((((int)(*Y2++)<<1) - 16) * 1.164); \
  799. tmpR=cR + Luma; tmpG=cG + Luma; tmpB=cB + Luma; \
  800. if ((tmpR | tmpG | tmpB) & 0xffffff00) { \
  801. if (tmpR<0) R[i]=0; else if (tmpR>255) R[i]=255; else R[i]=tmpR; \
  802. if (tmpG<0) G[i]=0; else if (tmpG>255) G[i]=255; else G[i]=tmpG; \
  803. if (tmpB<0) B[i]=0; else if (tmpB>255) B[i]=255; else B[i]=tmpB; \
  804. } else { R[i]=tmpR; G[i]=tmpG; B[i]=tmpB; } \
  805. } \
  806. for (; i<16; i++) { \
  807. Luma = (int) ((((int)(*Y3++)<<1) - 16) * 1.164); \
  808. tmpR=cR + Luma; tmpG=cG + Luma; tmpB=cB + Luma; \
  809. if ((tmpR | tmpG | tmpB) & 0xffffff00) { \
  810. if (tmpR<0) R[i]=0; else if (tmpR>255) R[i]=255; else R[i]=tmpR; \
  811. if (tmpG<0) G[i]=0; else if (tmpG>255) G[i]=255; else G[i]=tmpG; \
  812. if (tmpB<0) B[i]=0; else if (tmpB>255) B[i]=255; else B[i]=tmpB; \
  813. } else { R[i]=tmpR; G[i]=tmpG; B[i]=tmpB; } \
  814. }
  815. /*
  816. * Normally, images are stored right side up, that is with the
  817. * first pixel in the buffer corresponding to the top left pixel
  818. * in the image.
  819. *
  820. * The Microsoft standard Device Independent bitmap formats BI_RGB and
  821. * BI_BITFIELD are stored with the lower left pixel first. We view that
  822. * as upside down.
  823. *
  824. * Each format can also have a negative height, which also signifes
  825. * upside down.
  826. *
  827. * Since two negatives makes a positive, that means that BI_ formats with
  828. * negative height are right side up.
  829. */
  830. if( Bmh->biCompression == BI_RGB ||
  831. Bmh->biCompression == BI_BITFIELDS )
  832. Ups = 1 ;
  833. if( lines < 0 ) {
  834. Ups = 1-Ups ;
  835. lines = -lines ;
  836. }
  837. /*
  838. ** The assumption is that YCrCb are subsampled 4:1:1
  839. ** YSize = lines * pixels
  840. ** CbSize = CrSize = (lines*pixels)/4
  841. */
  842. switch (Bmh->biCompression)
  843. {
  844. case BI_DECXIMAGEDIB: /* XIMAGE 24 == pBGR */
  845. case BI_BITFIELDS: /* 32-bit RGB */
  846. {
  847. unsigned dword *Iout0 = (unsigned dword *)ImageOut,
  848. *Iout1, *Iout2, *Iout3;
  849. if (ValidateBI_BITFIELDS(Bmh) == pRGB)
  850. for (row = 0; row < lines; row+=4)
  851. {
  852. if (Ups) {
  853. tmp = pixels * (lines-row-1) ;
  854. Iout0 = (unsigned dword *)ImageOut+tmp;
  855. Iout1=Iout0-pixels; Iout2=Iout1-pixels; Iout3=Iout2-pixels;
  856. }
  857. else {
  858. Iout1=Iout0+pixels; Iout2=Iout1+pixels; Iout3=Iout2+pixels;
  859. }
  860. Y1=Y0+pixels; Y2=Y1+pixels; Y3=Y2+pixels;
  861. for (col = 0; col < pixels; col += 4)
  862. {
  863. if (*Cb & 0x80) /* if 8th bit is set, ignore */
  864. {
  865. for (i=0; i<4; i++) {
  866. *(Iout0++) = 0;
  867. *(Iout1++) = 0;
  868. *(Iout2++) = 0;
  869. *(Iout3++) = 0;
  870. }
  871. Cb++; Cr++;
  872. }
  873. else
  874. {
  875. U = ((*Cb++)<<1) - 128;
  876. V = ((*Cr++)<<1) - 128;
  877. _LoadRGBfrom1611();
  878. for (i=0; i<4; i++)
  879. *(Iout0++) = (R[i]<<16) | (G[i]<<8) | B[i];
  880. for (; i<8; i++)
  881. *(Iout1++) = (R[i]<<16) | (G[i]<<8) | B[i];
  882. for (; i<12; i++)
  883. *(Iout2++) = (R[i]<<16) | (G[i]<<8) | B[i];
  884. for (; i<16; i++)
  885. *(Iout3++) = (R[i]<<16) | (G[i]<<8) | B[i];
  886. }
  887. }
  888. Iout0=Iout3;
  889. Y0=Y3;
  890. }
  891. else /* pBGR and XIMAGE 24-bit */
  892. for (row = 0; row < lines; row+=4)
  893. {
  894. if (Ups) {
  895. tmp = pixels * (lines-row-1) ;
  896. Iout0 = (unsigned dword *)ImageOut+tmp;
  897. Iout1=Iout0-pixels; Iout2=Iout1-pixels; Iout3=Iout2-pixels;
  898. }
  899. else {
  900. Iout1=Iout0+pixels; Iout2=Iout1+pixels; Iout3=Iout2+pixels;
  901. }
  902. Y1=Y0+pixels; Y2=Y1+pixels; Y3=Y2+pixels;
  903. for (col = 0; col < pixels; col += 4)
  904. {
  905. if (*Cb & 0x80) /* if 8th bit is set, ignore */
  906. {
  907. for (i=0; i<4; i++) {
  908. *(Iout0++) = 0;
  909. *(Iout1++) = 0;
  910. *(Iout2++) = 0;
  911. *(Iout3++) = 0;
  912. }
  913. Cb++; Cr++;
  914. }
  915. else
  916. {
  917. U = ((*Cb++)<<1) - 128;
  918. V = ((*Cr++)<<1) - 128;
  919. _LoadRGBfrom1611();
  920. for (i=0; i<4; i++)
  921. *(Iout0++) = (B[i]<<16) | (G[i]<<8) | R[i];
  922. for (; i<8; i++)
  923. *(Iout1++) = (B[i]<<16) | (G[i]<<8) | R[i];
  924. for (; i<12; i++)
  925. *(Iout2++) = (B[i]<<16) | (G[i]<<8) | R[i];
  926. for (; i<16; i++)
  927. *(Iout3++) = (B[i]<<16) | (G[i]<<8) | R[i];
  928. }
  929. }
  930. Iout0=Iout3;
  931. Y0=Y3;
  932. }
  933. }
  934. break;
  935. case BI_RGB:
  936. switch (Bmh->biBitCount)
  937. {
  938. case 15:
  939. case 16:
  940. {
  941. u_short *Sout0 = (u_short *)ImageOut, *Sout1, *Sout2, *Sout3;
  942. for (row = 0; row < lines; row+=4)
  943. {
  944. if (Ups) {
  945. tmp = pixels * (lines-row-1) ;
  946. Sout0 = &((u_short *)ImageOut)[tmp]; /* For 32-bit */
  947. Sout1=Sout0-pixels; Sout2=Sout1-pixels; Sout3=Sout2-pixels;
  948. }
  949. else {
  950. Sout1=Sout0+pixels; Sout2=Sout1+pixels; Sout3=Sout2+pixels;
  951. }
  952. Y1=Y0+pixels; Y2=Y1+pixels; Y3=Y2+pixels;
  953. for (col = 0; col < pixels; col += 4)
  954. {
  955. if (*Cb & 0x80) /* if 8th bit is set, ignore */
  956. {
  957. for (i=0; i<4; i++) {
  958. *(Sout0++) = 0;
  959. *(Sout1++) = 0;
  960. *(Sout2++) = 0;
  961. *(Sout3++) = 0;
  962. }
  963. Cb++; Cr++;
  964. }
  965. else
  966. {
  967. U = ((*Cb++)<<1) - 128;
  968. V = ((*Cr++)<<1) - 128;
  969. _LoadRGBfrom1611();
  970. for (i=0; i<4; i++)
  971. *(Sout0++)=
  972. ((R[i]&0xf8)<<7)|((G[i]&0xf8)<<2)|((B[i]&0xf8)>>3);
  973. for (; i<8; i++)
  974. *(Sout1++)=
  975. ((R[i]&0xf8)<<7)|((G[i]&0xf8)<<2)|((B[i]&0xf8)>>3);
  976. for (; i<12; i++)
  977. *(Sout2++)=
  978. ((R[i]&0xf8)<<7)|((G[i]&0xf8)<<2)|((B[i]&0xf8)>>3);
  979. for (; i<16; i++)
  980. *(Sout3++)=
  981. ((R[i]&0xf8)<<7)|((G[i]&0xf8)<<2)|((B[i]&0xf8)>>3);
  982. }
  983. }
  984. Sout0=Sout3;
  985. Y0=Y3;
  986. }
  987. }
  988. break;
  989. case 24:
  990. {
  991. u_char *Cout0 = (u_char *)ImageOut, *Cout1, *Cout2, *Cout3;
  992. for (row = 0; row < lines; row+=4)
  993. {
  994. if (Ups) {
  995. tmp = pixels * (lines-row-1) ;
  996. Cout0 = &((u_char *)ImageOut)[tmp*3]; /* For 32-bit */
  997. Cout1=Cout0-pixels; Cout2=Cout1-pixels; Cout3=Cout2-pixels;
  998. }
  999. else {
  1000. Cout1=Cout0+pixels; Cout2=Cout1+pixels; Cout3=Cout2+pixels;
  1001. }
  1002. Y1=Y0+pixels; Y2=Y1+pixels; Y3=Y2+pixels;
  1003. for (col = 0; col < pixels; col += 4)
  1004. {
  1005. if (*Cb & 0x80) /* if 8th bit is set, ignore */
  1006. {
  1007. for (i=0; i<4*3; i++) {
  1008. *(Cout0++) = 0;
  1009. *(Cout1++) = 0;
  1010. *(Cout2++) = 0;
  1011. *(Cout3++) = 0;
  1012. }
  1013. Cb++; Cr++;
  1014. }
  1015. else
  1016. {
  1017. U = ((*Cb++)<<1) - 128;
  1018. V = ((*Cr++)<<1) - 128;
  1019. _LoadRGBfrom1611();
  1020. for (i=0; i<4; i++)
  1021. { *(Cout0++)=(u_char)B[i]; *(Cout0++)=(u_char)G[i]; *(Cout0++)=(u_char)R[i]; }
  1022. for (; i<8; i++)
  1023. { *(Cout1++)=(u_char)B[i]; *(Cout1++)=(u_char)G[i]; *(Cout1++)=(u_char)R[i]; }
  1024. for (; i<12; i++)
  1025. { *(Cout2++)=(u_char)B[i]; *(Cout2++)=(u_char)G[i]; *(Cout2++)=(u_char)R[i]; }
  1026. for (; i<16; i++)
  1027. { *(Cout3++)=(u_char)B[i]; *(Cout3++)=(u_char)G[i]; *(Cout3++)=(u_char)R[i]; }
  1028. }
  1029. }
  1030. Cout0=Cout3;
  1031. Y0=Y3;
  1032. }
  1033. }
  1034. break;
  1035. }
  1036. break;
  1037. default:
  1038. return(ScErrorUnrecognizedFormat);
  1039. }
  1040. return (NoErrors);
  1041. }
  1042. /*
  1043. ** Name: ScYuv422ToRgb
  1044. ** Purpose: convert 16-bit YCrCb 4:2:2 to an 24-bit/16-bit/32-bit RGB
  1045. **
  1046. ** Note: The code below is pixel based and is *extremely* inefficient, we
  1047. ** plan to replace the dumb code below with some fast code
  1048. ** If Cb==NULL and Cr==NULL then assume BI_DECGRAYDIB (use only Y component).
  1049. */
  1050. ScStatus_t ScYuv422ToRgb (BITMAPINFOHEADER *Bmh, u_char *Y, u_char *Cb,
  1051. u_char *Cr, u_char *ImageOut)
  1052. {
  1053. register int row, col;
  1054. register int Luma,U=0,V=0;
  1055. int R1,R2, G1,G2, B1,B2;
  1056. int Ups = 0, tmp; /* Flip image upside down */
  1057. u_char *RData, *GData, *BData; /* pointers for non-interlaced mode */
  1058. u_char *Cout = (u_char *)ImageOut;
  1059. u_short *Sout = (u_short *)ImageOut;
  1060. u_int *Iout = (u_int *)ImageOut;
  1061. int pixels = Bmh->biWidth;
  1062. int lines = Bmh->biHeight;
  1063. #ifdef NEW_YCBCR
  1064. #define _LoadRGBfrom422() \
  1065. if (U || V) { \
  1066. R1 = R2 = (int) ( + (1.596 * V)); \
  1067. G1 = G2 = (int) (- (0.391 * U) - (0.813 * V)); \
  1068. B1 = B2 = (int) (+ (2.018 * U) ); \
  1069. } else { R1=R2=G1=G2=B1=B2=0; } \
  1070. Luma = (int) (((int) *(Y++) - 16) * 1.164); \
  1071. R1 += Luma; G1 += Luma; B1 += Luma; \
  1072. Luma = (int) (((int) *(Y++) - 16) * 1.164); \
  1073. R2 += Luma; G2 += Luma; B2 += Luma; \
  1074. if ((R1 | G1 | B1 | R2 | G2 | B2) & 0xffffff00) { \
  1075. if (R1<0) R1=0; else if (R1>255) R1=255; \
  1076. if (G1<0) G1=0; else if (G1>255) G1=255; \
  1077. if (B1<0) B1=0; else if (B1>255) B1=255; \
  1078. if (R2<0) R2=0; else if (R2>255) R2=255; \
  1079. if (G2<0) G2=0; else if (G2>255) G2=255; \
  1080. if (B2<0) B2=0; else if (B2>255) B2=255; \
  1081. }
  1082. #else
  1083. #define _LoadRGBfrom422() \
  1084. Luma = *(Y++); \
  1085. R1 = Luma + (1.4075 * V); \
  1086. G1 = Luma - (0.3455 * U) - (0.7169 * V); \
  1087. B1 = Luma + (1.7790 * U); \
  1088. Luma = *(Y++); \
  1089. R2 = Luma + (1.4075 * V); \
  1090. G2 = Luma - (0.3455 * U) - (0.7169 * V); \
  1091. B2 = Luma + (1.7790 * U); \
  1092. if ((R1 | G1 | B1 | R2 | G2 | B2) & 0xffffff00) { \
  1093. if (R1<0) R1=0; else if (R1>255) R1=255; \
  1094. if (G1<0) G1=0; else if (G1>255) G1=255; \
  1095. if (B1<0) B1=0; else if (B1>255) B1=255; \
  1096. if (R2<0) R2=0; else if (R2>255) R2=255; \
  1097. if (G2<0) G2=0; else if (G2>255) G2=255; \
  1098. if (B2<0) B2=0; else if (B2>255) B2=255; \
  1099. }
  1100. #endif /* NEW_YCBCR */
  1101. /*
  1102. * Normally, images are stored right side up,
  1103. * that is with the first pixel in the buffer
  1104. * corresponding to the top left pixel in the image.
  1105. *
  1106. * The Microsoft standard Device Independent bitmap
  1107. * formats BI_RGB and BI_BITFIELD are stored with
  1108. * the lower left pixel first.
  1109. * We view that as upside down.
  1110. *
  1111. * Each format can also have a negative height,
  1112. * which also signifes upside down.
  1113. *
  1114. * Since two negatives makes a positive, that means
  1115. * that BI_ formats with a negative height are right side up.
  1116. */
  1117. if( Bmh->biCompression == BI_RGB ||
  1118. Bmh->biCompression == BI_BITFIELDS)
  1119. Ups = 1 ;
  1120. if( lines < 0 ) {
  1121. Ups = 1-Ups ;
  1122. lines = -lines ;
  1123. }
  1124. /*
  1125. ** needed if the three components are to be provided in a
  1126. ** non-interlaced mode:
  1127. */
  1128. if (Bmh->biCompression == BI_DECSEPRGBDIB) {
  1129. RData = ImageOut;
  1130. GData = RData + (pixels * lines);
  1131. BData = GData + (pixels * lines);
  1132. }
  1133. /*
  1134. ** The assumption is that YCrCb are subsampled 4:2:2
  1135. ** YSize = lines * pixels
  1136. ** CbSize = CrSize = (lines*pixels)/2
  1137. */
  1138. switch (Bmh->biCompression)
  1139. {
  1140. case BI_RGB:
  1141. switch (Bmh->biBitCount)
  1142. {
  1143. case 15:
  1144. case 16:
  1145. {
  1146. u_short *Sout = (u_short *)ImageOut;
  1147. for (row = 0; row < lines; row++)
  1148. {
  1149. if (Ups)
  1150. {
  1151. tmp = pixels * (lines-row-1) ;
  1152. Sout = &((u_short *)ImageOut)[tmp]; /* For 16-bit */
  1153. }
  1154. for (col = 0; col < pixels; col += 2)
  1155. {
  1156. if (Cb) {
  1157. U = *Cb++ - 128;
  1158. V = *Cr++ - 128;
  1159. }
  1160. _LoadRGBfrom422();
  1161. *(Sout++) = ((R1&0xf8)<<7)|((G1&0xf8)<<2)|((B1&0xf8)>>3);
  1162. *(Sout++) = ((R2&0xf8)<<7)|((G2&0xf8)<<2)|((B2&0xf8)>>3);
  1163. }
  1164. }
  1165. }
  1166. break;
  1167. case 24:
  1168. {
  1169. u_char *Cout = (u_char *)ImageOut;
  1170. for (row = 0; row < lines; row++)
  1171. {
  1172. if (Ups)
  1173. {
  1174. tmp = pixels * (lines-row-1) ;
  1175. Cout = &((u_char *)ImageOut)[3*tmp]; /* For 24-bit */
  1176. }
  1177. for (col = 0; col < pixels; col += 2)
  1178. {
  1179. if (Cb) {
  1180. U = *Cb++ - 128;
  1181. V = *Cr++ - 128;
  1182. }
  1183. _LoadRGBfrom422();
  1184. *(Cout++) = (u_char)B1; *(Cout++) = (u_char)G1; *(Cout++) = (u_char)R1;
  1185. *(Cout++) = (u_char)B2; *(Cout++) = (u_char)G2; *(Cout++) = (u_char)R2;
  1186. }
  1187. }
  1188. }
  1189. break;
  1190. case 32:
  1191. {
  1192. u_int *Iout = (u_int *)ImageOut;
  1193. for (row = 0; row < lines; row++)
  1194. {
  1195. if (Ups)
  1196. {
  1197. tmp = pixels * (lines-row-1) ;
  1198. Iout = &((u_int *)ImageOut)[tmp]; /* For 32-bit */
  1199. }
  1200. for (col = 0; col < pixels; col += 2)
  1201. {
  1202. if (Cb) {
  1203. U = *Cb++ - 128;
  1204. V = *Cr++ - 128;
  1205. }
  1206. _LoadRGBfrom422();
  1207. *(Iout++) = (R1<<16) | (G1<<8) | B1 ;
  1208. *(Iout++) = (R2<<16) | (G2<<8) | B2 ;
  1209. }
  1210. }
  1211. }
  1212. break;
  1213. }
  1214. break;
  1215. case BI_DECSEPRGBDIB: /* 24-bit separate RGB */
  1216. {
  1217. u_char *RData, *GData, *BData;
  1218. RData = ImageOut;
  1219. GData = RData + (pixels * lines);
  1220. BData = GData + (pixels * lines);
  1221. for (row = 0; row < lines; row++)
  1222. {
  1223. for (col = 0; col < pixels; col += 2)
  1224. {
  1225. if (Cb) {
  1226. U = *Cb++ - 128;
  1227. V = *Cr++ - 128;
  1228. }
  1229. _LoadRGBfrom422();
  1230. *(RData++) = (u_char)R1; *(RData++) = (u_char)R2;
  1231. *(GData++) = (u_char)G1; *(GData++) = (u_char)G2;
  1232. *(BData++) = (u_char)B1; *(BData++) = (u_char)B2;
  1233. }
  1234. }
  1235. }
  1236. break;
  1237. case BI_DECXIMAGEDIB: /* XIMAGE 24 == pBGR */
  1238. case BI_BITFIELDS: /* 16 or 32-bit RGB */
  1239. switch (Bmh->biBitCount)
  1240. {
  1241. case 16:
  1242. { /* 16-bit BI_BITFIELDS, hardcoded to RGB565 */
  1243. u_short *Sout = (u_short *)ImageOut;
  1244. for (row = 0; row < lines; row++)
  1245. {
  1246. if (Ups)
  1247. {
  1248. tmp = pixels * (lines-row-1) ;
  1249. Sout = &((u_short *)ImageOut)[tmp]; /* For 16-bit */
  1250. }
  1251. for (col = 0; col < pixels; col += 2)
  1252. {
  1253. if (Cb) {
  1254. U = *Cb++ - 128;
  1255. V = *Cr++ - 128;
  1256. }
  1257. _LoadRGBfrom422();
  1258. *(Sout++) = ((R1<<8) & 0xf800) | ((G1<<3) & 0x07e0) | ((B1>>3) & 0x01f);
  1259. *(Sout++) = ((R2<<8) & 0xf800) | ((G2<<3) & 0x07e0) | ((B2>>3) & 0x01f);
  1260. }
  1261. }
  1262. }
  1263. break ;
  1264. case 24:
  1265. case 32:
  1266. { /* 32-bit RGB */
  1267. u_int *Iout = (u_int *)ImageOut;
  1268. if (ValidateBI_BITFIELDS(Bmh) == pRGB)
  1269. {
  1270. for (row = 0; row < lines; row++)
  1271. {
  1272. if (Ups)
  1273. {
  1274. tmp = pixels * (lines-row-1) ;
  1275. Iout = &((u_int *)ImageOut)[tmp]; /* For 32-bit */
  1276. }
  1277. for (col = 0; col < pixels; col += 2)
  1278. {
  1279. if (Cb) {
  1280. U = *Cb++ - 128;
  1281. V = *Cr++ - 128;
  1282. }
  1283. _LoadRGBfrom422();
  1284. *(Iout++) = (R1<<16) | (G1<<8) | B1;
  1285. *(Iout++) = (R2<<16) | (G2<<8) | B2;
  1286. }
  1287. }
  1288. }
  1289. else /* pBGR and XIMAGE 24-bit */
  1290. {
  1291. for (row = 0; row < lines; row++)
  1292. {
  1293. if (Ups)
  1294. {
  1295. tmp = pixels * (lines-row-1) ;
  1296. Iout = &((u_int *)ImageOut)[tmp]; /* For 32-bit */
  1297. }
  1298. for (col = 0; col < pixels; col += 2)
  1299. {
  1300. if (Cb) {
  1301. U = *Cb++ - 128;
  1302. V = *Cr++ - 128;
  1303. }
  1304. _LoadRGBfrom422();
  1305. *(Iout++) = (B1<<16) | (G1<<8) | R1;
  1306. *(Iout++) = (B2<<16) | (G2<<8) | R2;
  1307. }
  1308. }
  1309. }
  1310. }
  1311. break;
  1312. }
  1313. break;
  1314. default:
  1315. return(ScErrorUnrecognizedFormat);
  1316. }
  1317. return (NoErrors);
  1318. }
  1319. /*
  1320. ** Name: ScInitRgbToYuv
  1321. ** Purpose: Initializes tables for RGB to YUV conversion.
  1322. **
  1323. ** Notes:
  1324. **
  1325. ** The tables are allocated and filled in once the first
  1326. ** time they are needed. They will remin for the lifetime
  1327. ** of the server.
  1328. **
  1329. ** The following formula is used:
  1330. **
  1331. ** y = 0.257 * r + 0.504 * g + 0.098 * b + 16 ; /+ 16 - 235 +/
  1332. ** u = -0.148 * r - 0.291 * g + 0.439 * b + 128 ; /+ 16 - 239 +/
  1333. ** v = 0.439 * r - 0.368 * g - 0.071 * b + 128 ; /+ 16 - 239 +/
  1334. **
  1335. ** But we rewrite it thus:
  1336. **
  1337. ** y = 16.000 + 0.257 * r + 0.504 * g + 0.098 * b ;
  1338. ** u = 16.055 + 0.148 * (255-r) + 0.291 * (255-g) + 0.439 * b ;
  1339. ** v = 16.055 + 0.439 * r + 0.368 * (255-g) + 0.071 * (255-b) ;
  1340. **
  1341. ** ( By the way, the old constants are: )
  1342. ** ( y = r * 0.299 + g * 0.587 + b * 0.114 ; )
  1343. ** ( u = r * -0.169 + g * -0.332 + b * 0.500 + 128 ; )
  1344. ** ( v = r * 0.500 + g * -0.419 + b * -0.0813 + 128 ; )
  1345. ** ( or )
  1346. ** ( y = 0.0 + 0.299 * r + 0.587 * g + 0.1140 * b ; )
  1347. ** ( u = 0.245 + 0.169 * (255-r) + 0.332 * (255-g) + 0.5000 * b ; )
  1348. ** ( v = 0.4235 + 0.500 * r + 0.419 * (255-g) + 0.0813 * (255-b) ; )
  1349. **
  1350. ** This particular arrangement of the formula allows Y, U and V values
  1351. ** to be calculated in paralell by simple table lookup.
  1352. ** The paralellism comes from the fact that Y,U and V values
  1353. ** are stored in the same word, but in different bytes.
  1354. ** The tables are such that the contribution from red, green
  1355. ** and blue can simply be added together, without any carry
  1356. ** between bytes. Since the YUV space is larger than the RGB
  1357. ** cube, and the RGB cube fits entirely within YUV space,
  1358. ** there is no overflow and no range checking is needed.
  1359. **
  1360. */
  1361. #ifdef NEW_YCBCR
  1362. /*
  1363. ** y = 16.000 + 0.257 * r + 0.504 * g + 0.098 * b ;
  1364. ** u = 16.055 + 0.148 * (255-r) + 0.291 * (255-g) + 0.439 * b ;
  1365. ** v = 16.055 + 0.439 * r + 0.368 * (255-g) + 0.071 * (255-b) ;
  1366. */
  1367. #define YC 16.000
  1368. #define UC 16.055
  1369. #define VC 16.055
  1370. #define YR 0.257
  1371. #define UR 0.148
  1372. #define VR 0.439
  1373. #define YG 0.504
  1374. #define UG 0.291
  1375. #define VG 0.368
  1376. #define YB 0.098
  1377. #define UB 0.439
  1378. #define VB 0.071
  1379. #else /* !NEW_YCBCR */
  1380. /*
  1381. ** ( y = 0.0 0.299 * r + 0.587 * g + 0.1140 * b ; )
  1382. ** ( u = 0.245 + 0.169 * (255-r) + 0.332 * (255-g) + 0.5000 * b ; )
  1383. ** ( v = 0.4235 + 0.500 * r + 0.419 * (255-g) + 0.0813 * (255-b) ; )
  1384. */
  1385. #define YC 0.0
  1386. #define UC 0.245
  1387. #define VC 0.4235
  1388. #define YR 0.299
  1389. #define UR 0.169
  1390. #define VR 0.500
  1391. #define YG 0.587
  1392. #define UG 0.332
  1393. #define VG 0.419
  1394. #define YB 0.1140
  1395. #define UB 0.5000
  1396. #define VB 0.0813
  1397. #endif /* !NEW_YCBCR */
  1398. /*
  1399. * We only need an int (32 bits) per table entry but
  1400. * 64-bit aligned access is faster on alpha.
  1401. */
  1402. #ifdef __alpha
  1403. _int64 *RedToYuyv, *GreenToYuyv, *BlueToYuyv ;
  1404. #else /* !__alpha */
  1405. unsigned int *RedToYuyv, *GreenToYuyv, *BlueToYuyv ;
  1406. #endif /* !__alpha */
  1407. int ScInitRgbToYuv()
  1408. {
  1409. int i, y, u, v ;
  1410. if( RedToYuyv == NULL ) {
  1411. #ifdef __alpha
  1412. RedToYuyv = (_int64 *) ScAlloc( 256 * sizeof( _int64 ) ) ;
  1413. GreenToYuyv = (_int64 *) ScAlloc( 256 * sizeof( _int64 ) ) ;
  1414. BlueToYuyv = (_int64 *) ScAlloc( 256 * sizeof( _int64 ) ) ;
  1415. #else /* !__alpha */
  1416. RedToYuyv = (unsigned int *) ScAlloc( 256 * sizeof( unsigned int ) ) ;
  1417. GreenToYuyv = (unsigned int *) ScAlloc( 256 * sizeof( unsigned int ) ) ;
  1418. BlueToYuyv = (unsigned int *) ScAlloc( 256 * sizeof( unsigned int ) ) ;
  1419. #endif /* !__alpha */
  1420. if( !RedToYuyv || !GreenToYuyv || !BlueToYuyv )
  1421. return 0 ;
  1422. for( i=0 ; i<256 ; i++ ) {
  1423. /*
  1424. * Calculate contribution from red.
  1425. * We will also add in the constant here.
  1426. * Pack it into the tables thus: lsb->YUYV<-msb
  1427. */
  1428. y = (int) (YC + YR * i) ;
  1429. u = (int) (UC + UR * (255-i)) ;
  1430. v = (int) (VC + VR * i) ;
  1431. RedToYuyv[i] = (y | (u<<8) | (y<<16) | (v<<24)) ;
  1432. /*
  1433. * Calculate contribution from green.
  1434. */
  1435. y = (int) (YG * i) ;
  1436. u = (int) (UG * (255-i)) ;
  1437. v = (int) (VG * (255-i)) ;
  1438. GreenToYuyv[i] = (y | (u<<8) | (y<<16) | (v<<24)) ;
  1439. /*
  1440. * Calculate contribution from blue.
  1441. */
  1442. y = (int) (YB * i) ;
  1443. u = (int) (UB * i) ;
  1444. v = (int) (VB * (255-i)) ;
  1445. BlueToYuyv[i] = (y | (u<<8) | (y<<16) | (v<<24)) ;
  1446. }
  1447. }
  1448. return 1 ;
  1449. }
  1450. /*
  1451. ** Name: ScConvertRGB24sTo422i_C
  1452. ** Purpose: convert 24-bit RGB (8:8:8 format) to 16-bit YCrCb (4:2:2 format)
  1453. */
  1454. ScStatus_t ScConvertRGB24sTo422i_C(BITMAPINFOHEADER *Bmh, u_char *R, u_char *G,
  1455. u_char *B, u_short *ImageOut)
  1456. {
  1457. register int row, col;
  1458. int yuyv,r,g,b;
  1459. int pixels = Bmh->biWidth;
  1460. int lines = abs(Bmh->biHeight);
  1461. if( !RedToYuyv && !ScInitRgbToYuv() )
  1462. return ScErrorMemory ;
  1463. for (row = 0; row < lines; row++) {
  1464. for (col = 0; col < pixels; col++) {
  1465. r = *(R++); g = *(G++); b = *(B++);
  1466. /*
  1467. * Quick convert to YUV.
  1468. */
  1469. yuyv = (int) (RedToYuyv[r] + GreenToYuyv[g] + BlueToYuyv[b]) ;
  1470. /*
  1471. * Pack 4:2:2 = YUYV YUYV ...
  1472. * We'll pack YU or YV depending on whether col is odd or not.
  1473. * Shift yuyv 0 for even, 16 for odd columns.
  1474. */
  1475. *(ImageOut++) = yuyv >> ((col & 1) << 4) ;
  1476. }
  1477. }
  1478. return (NoErrors);
  1479. }
  1480. #define M_RND(f) ((int) ((f) + .5))
  1481. /*
  1482. ** Name: ScConvertRGB24To411s_C
  1483. ** Purpose: convert 24-bit RGB (8:8:8 format) to 16-bit YCrCb (4:1:1 format)
  1484. */
  1485. ScStatus_t ScConvertRGB24To411s_C(u_char *inimage,
  1486. u_char *Y, u_char *U, u_char *V,
  1487. int width, int height)
  1488. {
  1489. register int row, col;
  1490. int yuyv, r, g, b;
  1491. u_char *tmp, *evl, *odl;
  1492. if( !RedToYuyv && !ScInitRgbToYuv() )
  1493. return(ScErrorMemory);
  1494. if (height<0) /* flip image */
  1495. {
  1496. height = -height;
  1497. for (row = height-1; row; row--)
  1498. {
  1499. tmp = inimage+(width*row*3);
  1500. if (row & 1)
  1501. {
  1502. odl = tmp;
  1503. evl = tmp-(width*3);
  1504. }
  1505. else
  1506. {
  1507. evl = tmp;
  1508. odl = tmp-(width*3);
  1509. }
  1510. for (col = 0; col < width; col++)
  1511. {
  1512. r = *tmp++;
  1513. g = *tmp++;
  1514. b = *tmp++;
  1515. yuyv = (int) (RedToYuyv[r] + GreenToYuyv[g] + BlueToYuyv[b]);
  1516. *Y++ = (yuyv&0xff);
  1517. /* We only store every fourth value of u and v components */
  1518. if ((col & 1) && (row & 1))
  1519. {
  1520. /* Compute average r, g and b values */
  1521. r = *evl++ + *odl++;
  1522. g = *evl++ + *odl++;
  1523. b = *evl++ + *odl++;
  1524. r += (*evl++ + *odl++);
  1525. g += (*evl++ + *odl++);
  1526. b += (*evl++ + *odl++);
  1527. r = r >> 2;
  1528. g = g >> 2;
  1529. b = b >> 2;
  1530. yuyv = (int) (RedToYuyv[r] + GreenToYuyv[g] + BlueToYuyv[b]);
  1531. *U++ = ((yuyv&0xff000000) >> 24); // V
  1532. *V++ = ((yuyv&0xff00) >> 8); // U
  1533. }
  1534. }
  1535. }
  1536. }
  1537. else
  1538. {
  1539. tmp = inimage;
  1540. for (row = 0; row < height; row++)
  1541. {
  1542. if (row & 1)
  1543. odl = tmp;
  1544. else
  1545. evl = tmp;
  1546. for (col = 0; col < width; col++)
  1547. {
  1548. r = *tmp++;
  1549. g = *tmp++;
  1550. b = *tmp++;
  1551. yuyv = (int) (RedToYuyv[r] + GreenToYuyv[g] + BlueToYuyv[b]);
  1552. *Y++ = (yuyv&0xff);
  1553. /* We only store every fourth value of u and v components */
  1554. if ((col & 1) && (row & 1))
  1555. {
  1556. /* Compute average r, g and b values */
  1557. r = *evl++ + *odl++;
  1558. g = *evl++ + *odl++;
  1559. b = *evl++ + *odl++;
  1560. r += (*evl++ + *odl++);
  1561. g += (*evl++ + *odl++);
  1562. b += (*evl++ + *odl++);
  1563. r = r >> 2;
  1564. g = g >> 2;
  1565. b = b >> 2;
  1566. yuyv = (int) (RedToYuyv[r] + GreenToYuyv[g] + BlueToYuyv[b]);
  1567. *U++ = ((yuyv&0xff000000) >> 24); // V
  1568. *V++ = ((yuyv&0xff00) >> 8); // U
  1569. }
  1570. }
  1571. }
  1572. }
  1573. return (NoErrors);
  1574. }
  1575. /*
  1576. ** Name: ScConvertRGB555To411s_C
  1577. ** Purpose: convert 16-bit RGB (5:5:5 format) to 16-bit YCrCb (4:1:1 format)
  1578. */
  1579. ScStatus_t ScConvertRGB555To411s_C(u_char *inimage, u_char *outimage,
  1580. int width, int height)
  1581. {
  1582. u_char *Y=outimage, *U, *V;
  1583. register int row, col, inpixel;
  1584. int yuyv, r, g, b;
  1585. unsigned word *tmp, *evl, *odl;
  1586. #define GetRGB555(in16, r, g, b) b = (inpixel>>7)&0xF8; \
  1587. g = (inpixel>>2)&0xF8; \
  1588. r = (inpixel<<3)&0xF8
  1589. #define AddRGB555(in16, r, g, b) b += (inpixel>>7)&0xF8; \
  1590. g += (inpixel>>2)&0xF8; \
  1591. r += (inpixel<<3)&0xF8
  1592. if( !RedToYuyv && !ScInitRgbToYuv() )
  1593. return(ScErrorMemory);
  1594. if (height<0) /* flip image */
  1595. {
  1596. height = -height;
  1597. U=Y+(width*height);
  1598. V=U+(width*height*1)/4;
  1599. for (row = height-1; row; row--)
  1600. {
  1601. tmp = ((unsigned word *)inimage)+(width*row);
  1602. if (row & 1)
  1603. {
  1604. odl = tmp;
  1605. evl = tmp-width;
  1606. }
  1607. else
  1608. {
  1609. evl = tmp;
  1610. odl = tmp-width;
  1611. }
  1612. for (col = 0; col < width; col++)
  1613. {
  1614. inpixel=*tmp++;
  1615. GetRGB555(inpixel, r, g, b);
  1616. yuyv = (int) (RedToYuyv[r] + GreenToYuyv[g] + BlueToYuyv[b]);
  1617. *Y++ = (yuyv&0xff);
  1618. /* We only store every fourth value of u and v components */
  1619. if ((col & 1) && (row & 1))
  1620. {
  1621. /* Compute average r, g and b values */
  1622. inpixel=*evl++;
  1623. GetRGB555(inpixel, r, g, b);
  1624. inpixel=*evl++;
  1625. AddRGB555(inpixel, r, g, b);
  1626. inpixel=*odl++;
  1627. AddRGB555(inpixel, r, g, b);
  1628. inpixel=*odl++;
  1629. AddRGB555(inpixel, r, g, b);
  1630. r = r >> 2;
  1631. g = g >> 2;
  1632. b = b >> 2;
  1633. yuyv = (int) (RedToYuyv[r] + GreenToYuyv[g] + BlueToYuyv[b]);
  1634. *U++ = ((yuyv&0xff000000) >> 24); // V
  1635. *V++ = ((yuyv&0xff00) >> 8); // U
  1636. }
  1637. }
  1638. }
  1639. }
  1640. else
  1641. {
  1642. U=Y+(width*height);
  1643. V=U+(width*height*1)/4;
  1644. tmp = (unsigned word *)inimage;
  1645. for (row = 0; row < height; row++)
  1646. {
  1647. if (row & 1)
  1648. odl = tmp;
  1649. else
  1650. evl = tmp;
  1651. for (col = 0; col < width; col++)
  1652. {
  1653. inpixel=*tmp++;
  1654. GetRGB555(inpixel, r, g, b);
  1655. yuyv = (int) (RedToYuyv[r] + GreenToYuyv[g] + BlueToYuyv[b]);
  1656. *Y++ = (yuyv&0xff);
  1657. /* We only store every fourth value of u and v components */
  1658. if ((col & 1) && (row & 1))
  1659. {
  1660. /* Compute average r, g and b values */
  1661. inpixel=*evl++;
  1662. GetRGB555(inpixel, r, g, b);
  1663. inpixel=*evl++;
  1664. AddRGB555(inpixel, r, g, b);
  1665. inpixel=*odl++;
  1666. AddRGB555(inpixel, r, g, b);
  1667. inpixel=*odl++;
  1668. AddRGB555(inpixel, r, g, b);
  1669. r = r >> 2;
  1670. g = g >> 2;
  1671. b = b >> 2;
  1672. yuyv = (int) (RedToYuyv[r] + GreenToYuyv[g] + BlueToYuyv[b]);
  1673. *U++ = ((yuyv&0xff000000) >> 24); // V
  1674. *V++ = ((yuyv&0xff00) >> 8); // U
  1675. }
  1676. }
  1677. }
  1678. }
  1679. return (NoErrors);
  1680. }
  1681. /*
  1682. ** Name: ScConvertRGB565To411s_C
  1683. ** Purpose: convert 16-bit RGB (5:6:5 format) to 16-bit YCrCb (4:1:1 format)
  1684. */
  1685. ScStatus_t ScConvertRGB565To411s_C(u_char *inimage, u_char *outimage,
  1686. int width, int height)
  1687. {
  1688. u_char *Y=outimage, *U, *V;
  1689. register int row, col, inpixel;
  1690. int yuyv, r, g, b;
  1691. unsigned word *tmp, *evl, *odl;
  1692. #define GetRGB565(in16, r, g, b) b = (inpixel>>8)&0xF8; \
  1693. g = (inpixel>>3)&0xFC; \
  1694. r = (inpixel<<3)&0xF8
  1695. #define AddRGB565(in16, r, g, b) b += (inpixel>>8)&0xF8; \
  1696. g += (inpixel>>3)&0xFC; \
  1697. r += (inpixel<<3)&0xF8
  1698. if( !RedToYuyv && !ScInitRgbToYuv() )
  1699. return(ScErrorMemory);
  1700. if (height<0) /* flip image */
  1701. {
  1702. height = -height;
  1703. U=Y+(width*height);
  1704. V=U+(width*height*1)/4;
  1705. for (row = height-1; row; row--)
  1706. {
  1707. tmp = ((unsigned word *)inimage)+(width*row);
  1708. if (row & 1)
  1709. {
  1710. odl = tmp;
  1711. evl = tmp-width;
  1712. }
  1713. else
  1714. {
  1715. evl = tmp;
  1716. odl = tmp-width;
  1717. }
  1718. for (col = 0; col < width; col++)
  1719. {
  1720. inpixel=*tmp++;
  1721. GetRGB565(inpixel, r, g, b);
  1722. yuyv = (int) (RedToYuyv[r] + GreenToYuyv[g] + BlueToYuyv[b]);
  1723. *Y++ = (yuyv&0xff);
  1724. /* We only store every fourth value of u and v components */
  1725. if ((col & 1) && (row & 1))
  1726. {
  1727. /* Compute average r, g and b values */
  1728. inpixel=*evl++;
  1729. GetRGB565(inpixel, r, g, b);
  1730. inpixel=*evl++;
  1731. AddRGB565(inpixel, r, g, b);
  1732. inpixel=*odl++;
  1733. AddRGB565(inpixel, r, g, b);
  1734. inpixel=*odl++;
  1735. AddRGB565(inpixel, r, g, b);
  1736. r = r >> 2;
  1737. g = g >> 2;
  1738. b = b >> 2;
  1739. yuyv = (int) (RedToYuyv[r] + GreenToYuyv[g] + BlueToYuyv[b]);
  1740. *U++ = ((yuyv&0xff000000) >> 24); // V
  1741. *V++ = ((yuyv&0xff00) >> 8); // U
  1742. }
  1743. }
  1744. }
  1745. }
  1746. else
  1747. {
  1748. U=Y+(width*height);
  1749. V=U+(width*height*1)/4;
  1750. tmp = (unsigned word *)inimage;
  1751. for (row = 0; row < height; row++)
  1752. {
  1753. if (row & 1)
  1754. odl = tmp;
  1755. else
  1756. evl = tmp;
  1757. for (col = 0; col < width; col++)
  1758. {
  1759. inpixel=*tmp++;
  1760. GetRGB565(inpixel, r, g, b);
  1761. yuyv = (int) (RedToYuyv[r] + GreenToYuyv[g] + BlueToYuyv[b]);
  1762. *Y++ = (yuyv&0xff);
  1763. /* We only store every fourth value of u and v components */
  1764. if ((col & 1) && (row & 1))
  1765. {
  1766. /* Compute average r, g and b values */
  1767. inpixel=*evl++;
  1768. GetRGB565(inpixel, r, g, b);
  1769. inpixel=*evl++;
  1770. AddRGB565(inpixel, r, g, b);
  1771. inpixel=*odl++;
  1772. AddRGB565(inpixel, r, g, b);
  1773. inpixel=*odl++;
  1774. AddRGB565(inpixel, r, g, b);
  1775. r = r >> 2;
  1776. g = g >> 2;
  1777. b = b >> 2;
  1778. yuyv = (int) (RedToYuyv[r] + GreenToYuyv[g] + BlueToYuyv[b]);
  1779. *U++ = ((yuyv&0xff000000) >> 24); // V
  1780. *V++ = ((yuyv&0xff00) >> 8); // U
  1781. }
  1782. }
  1783. }
  1784. }
  1785. return (NoErrors);
  1786. }
  1787. /*
  1788. ** Name: ScRgbInterlToYuvInterl
  1789. ** Purpose: convert many RGB formats to 16-bit YCrCb (4:2:2 format)
  1790. */
  1791. ScStatus_t ScRgbInterlToYuvInterl (
  1792. LPBITMAPINFOHEADER Bmh,
  1793. int Width,
  1794. int Height,
  1795. u_char *ImageIn,
  1796. u_short *ImageOut)
  1797. {
  1798. register int row, col;
  1799. int yuyv,r,g,b,mask=0x00ff;
  1800. int pixels = Width;
  1801. int lines = abs(Height);
  1802. int IspBGR = (ValidateBI_BITFIELDS(Bmh) == pBGR) ||
  1803. (Bmh->biCompression==BI_DECXIMAGEDIB && Bmh->biBitCount==24);
  1804. int IspRGB_BI_RGB_24 = (Bmh->biCompression==BI_RGB && Bmh->biBitCount==24);
  1805. int linestep = 0 ;
  1806. if( !RedToYuyv && !ScInitRgbToYuv() )
  1807. return ScErrorMemory ;
  1808. /*
  1809. * Check the input format and decide
  1810. * whether the image is to be turned
  1811. * upside down or not.
  1812. */
  1813. if( (Bmh->biCompression == BI_RGB ||
  1814. Bmh->biCompression == BI_BITFIELDS) ^
  1815. ((int) Bmh->biHeight < 0) ) {
  1816. ImageOut = &ImageOut[ pixels * (lines - 1) ] ;
  1817. linestep = -(pixels << 1) ;
  1818. }
  1819. /*
  1820. * To avoid if-then-else statements inside
  1821. * the inner loop, we have 3 loops.
  1822. */
  1823. /*
  1824. * 24 bits per pixel RGB.
  1825. */
  1826. if (IspRGB_BI_RGB_24) {
  1827. for (row = 0; row < lines; row++) {
  1828. for (col = 0; col < pixels; col++) {
  1829. b = *(ImageIn++);
  1830. g = *(ImageIn++);
  1831. r = *(ImageIn++);
  1832. /*
  1833. * Quick convert from RGB to YUV. Just add together
  1834. * the contributions from each of Red, Green and Blue.
  1835. */
  1836. yuyv = (int) (RedToYuyv[r] + GreenToYuyv[g] + BlueToYuyv[b]) ;
  1837. /*
  1838. * Pack 4:2:2 = YUYV YUYV ...
  1839. * We'll pack YU or YV depending on whether col is odd or not.
  1840. * Shift yuyv 0 for even, 16 for odd columns.
  1841. */
  1842. *(ImageOut++) = yuyv >> ((col & 1) << 4) ;
  1843. }
  1844. /*
  1845. * In case we're turning the image upside down.
  1846. * This will do nothing if it's right side up.
  1847. */
  1848. ImageOut = &ImageOut[linestep] ;
  1849. }
  1850. }
  1851. /*
  1852. * 32 bits per pixels 0BGR.
  1853. */
  1854. else if (IspBGR) {
  1855. for (row = 0; row < lines; row++) {
  1856. for (col = 0; col < pixels; col++) {
  1857. r = *((int *) ImageIn)++ ;
  1858. b = (r>>16) & mask ;
  1859. g = (r>> 8) & mask ;
  1860. r &= mask ;
  1861. yuyv = (int) (RedToYuyv[r] + GreenToYuyv[g] + BlueToYuyv[b]) ;
  1862. *(ImageOut++) = yuyv >> ((col & 1) << 4) ;
  1863. }
  1864. ImageOut = &ImageOut[linestep] ;
  1865. }
  1866. }
  1867. /*
  1868. * 32 bits per pixels 0RGB.
  1869. */
  1870. else {
  1871. for (row = 0; row < lines; row++) {
  1872. for (col = 0; col < pixels; col++) {
  1873. b = *((int *) ImageIn)++ ;
  1874. r = (b>>16) & mask ;
  1875. g = (b>> 8) & mask ;
  1876. b &= mask ;
  1877. yuyv = (int) (RedToYuyv[r] + GreenToYuyv[g] + BlueToYuyv[b]) ;
  1878. *(ImageOut++) = yuyv >> ((col & 1) << 4) ;
  1879. }
  1880. ImageOut = &ImageOut[linestep] ;
  1881. }
  1882. }
  1883. return (NoErrors);
  1884. }
  1885. /*
  1886. ** Function: ScConvert422ToYUV_char_C
  1887. ** Purpose: Extract the Y, U and V components into separate planes.
  1888. ** The interleaved format is YUYV, 4:2:2, we want 4:1:1 so,
  1889. ** only copy every other line of the chrominance
  1890. */
  1891. ScStatus_t ScConvert422ToYUV_char_C (u_char *RawImage,
  1892. u_char *Y, u_char *U, u_char *V,
  1893. int Width, int Height)
  1894. {
  1895. register int x, y;
  1896. Width/=2;
  1897. Height=abs(Height)/2;
  1898. for (y = 0; y < Height; y++)
  1899. {
  1900. for (x = 0 ; x < Width; x++)
  1901. {
  1902. *Y++ = *RawImage++;
  1903. *U++ = *RawImage++;
  1904. *Y++ = *RawImage++;
  1905. *V++ = *RawImage++;
  1906. }
  1907. for (x = 0; x < Width; x++)
  1908. {
  1909. *Y++ = *RawImage;
  1910. RawImage+=2;
  1911. *Y++ = *RawImage;
  1912. RawImage+=2;
  1913. }
  1914. }
  1915. return (NoErrors);
  1916. }
  1917. /*
  1918. ** Function: ScConvert422PlanarTo411_C
  1919. ** Purpose: Extract the Y, U and V components from (4:2:2)
  1920. ** planes and convert to 4:1:1 so,
  1921. ** only copy every other line of the chrominance
  1922. */
  1923. ScStatus_t ScConvert422PlanarTo411_C (u_char *RawImage,
  1924. u_char *Y, u_char *U, u_char *V,
  1925. int Width, int Height)
  1926. {
  1927. register int y;
  1928. const int HalfWidth=Width/2;
  1929. unsigned char *RY, *RU, *RV;
  1930. RY=RawImage;
  1931. RU=RY+(Width*Height);
  1932. RV=RU+(Width*Height/2);
  1933. Height=abs(Height);
  1934. memcpy(Y, RawImage, Width*Height);
  1935. for (y = Height/2; y > 0; y--)
  1936. {
  1937. memcpy(U, RU, HalfWidth);
  1938. memcpy(V, RV, HalfWidth);
  1939. U+=HalfWidth;
  1940. V+=HalfWidth;
  1941. RU+=Width; /* skip odd U and V lines */
  1942. RV+=Width;
  1943. }
  1944. return (NoErrors);
  1945. }
  1946. /*
  1947. ** C versions of block-extraction routines. To be replaced by ASM
  1948. */
  1949. void ScConvertSep422ToBlockYUV (u_char *RawImage, int bpp,
  1950. float *Comp1, float *Comp2, float *Comp3,
  1951. int Width, int Height)
  1952. {
  1953. int x,y;
  1954. int VertBlocks = abs(Height)/8;
  1955. int YBlocks = Width/8;
  1956. int UBlocks = Width/16;
  1957. int VBlocks = Width/16;
  1958. int ByteWidth = Width*2;
  1959. u_char *I1 = RawImage;
  1960. u_char *I2 = I1 + Width*abs(Height);
  1961. u_char *I3 = I2 + Width*abs(Height)/2;
  1962. float *C1 = Comp1, *C2 = Comp2, *C3 = Comp3;
  1963. for (y = 0 ; y < VertBlocks ; y++) {
  1964. for (x = 0 ; x < YBlocks ; x++)
  1965. sc_ExtractBlockNonInt(I1, &C1, ByteWidth, x, y);
  1966. for (x = 0 ; x < UBlocks ; x++)
  1967. sc_ExtractBlockNonInt(I2, &C2, ByteWidth, x, y);
  1968. for (x = 0 ; x < VBlocks ; x++)
  1969. sc_ExtractBlockNonInt(I3, &C3, ByteWidth, x, y);
  1970. }
  1971. }
  1972. void ScConvertGrayToBlock (u_char *RawImage, int bpp,
  1973. float *Comp1, int Width, int Height)
  1974. {
  1975. int x,y;
  1976. int VertBlocks = abs(Height)/8;
  1977. int YBlocks = Width/8;
  1978. int ByteWidth = Width;
  1979. u_char *I1 = RawImage;
  1980. float *C1 = Comp1;
  1981. for (y = 0 ; y < VertBlocks ; y++)
  1982. for (x = 0 ; x < YBlocks ; x++)
  1983. sc_ExtractBlockNonInt(I1, &C1, ByteWidth, x, y);
  1984. }
  1985. /*
  1986. ** Function: ScSepYUVto422i_C
  1987. ** Purpose: Convert a 4:1:1 YUV image in separate-component form to its
  1988. ** equivalent interleaved 4:2:2 form.
  1989. */
  1990. extern int ScSepYUVto422i_C(u_char *Y, u_char *U,
  1991. u_char *V, u_char *ImageOut,
  1992. u_int width, u_int height)
  1993. {
  1994. /* need C code for this */
  1995. return(0);
  1996. }
  1997. /*
  1998. ** Function: ScConvert422PlanarTo422i_C
  1999. ** Purpose: Convert a 4:2:2 YUV image in separate-component form to its
  2000. ** equivalent interleaved 4:2:2 form.
  2001. */
  2002. extern void ScConvert422PlanarTo422i_C(u_char *Y, u_char *Cb,
  2003. u_char *Cr, u_char *OutImage,
  2004. long width, long height)
  2005. {
  2006. int i, j;
  2007. height=abs(height);
  2008. width=width>>1;
  2009. for (i=0; i<height; i++)
  2010. {
  2011. /* Remember, pixels are 16 bit in interleaved YUV. That
  2012. ** means the 4 bytes below represent two pixels so our
  2013. ** loop should be for half the width.
  2014. */
  2015. for (j=0; j<width; j++)
  2016. {
  2017. *OutImage++ = *Y++;
  2018. *OutImage++ = *Cb++;
  2019. *OutImage++ = *Y++;
  2020. *OutImage++ = *Cr++;
  2021. }
  2022. }
  2023. }
  2024. /*
  2025. ** Function: ScConvert422iTo422s_C
  2026. ** Purpose: Convert a 4:2:2 YUV interleaved to 4:2:2 planar.
  2027. */
  2028. extern void ScConvert422iTo422s_C(u_char *InImage,
  2029. u_char *Y, u_char *U, u_char *V,
  2030. long width, long height)
  2031. {
  2032. int i, j;
  2033. height=abs(height);
  2034. width=width>>1;
  2035. for (i=0; i<height; i++)
  2036. {
  2037. /* Remember, pixels are 16 bit in interleaved YUV. That
  2038. ** means the 4 bytes below represent two pixels so our
  2039. ** loop should be for half the width.
  2040. */
  2041. for (j=0; j<width; j++)
  2042. {
  2043. *Y++ = *InImage++;
  2044. *U++ = *InImage++;
  2045. *Y++ = *InImage++;
  2046. *V++ = *InImage++;
  2047. }
  2048. }
  2049. }
  2050. /*
  2051. ** Function: ScConvert422iTo422sf_C
  2052. ** Purpose: Convert a 4:2:2 YUV interleaved to 4:2:2 planar.
  2053. */
  2054. extern void ScConvert422iTo422sf_C(u_char *InImage, int bpp,
  2055. float *Y, float *U, float *V,
  2056. long width, long height)
  2057. {
  2058. int i, j;
  2059. height=abs(height);
  2060. width=width>>1;
  2061. for (i=0; i<height; i++)
  2062. {
  2063. /* Remember, pixels are 16 bit in interleaved YUV. That
  2064. ** means the 4 bytes below represent two pixels so our
  2065. ** loop should be for half the width.
  2066. */
  2067. for (j=0; j<width; j++)
  2068. {
  2069. *Y++ = (float)*InImage++;
  2070. *U++ = (float)*InImage++;
  2071. *Y++ = (float)*InImage++;
  2072. *V++ = (float)*InImage++;
  2073. }
  2074. }
  2075. }
  2076. /*
  2077. ** Function: ScConvert411sTo422i_C
  2078. ** Purpose: Convert a 4:1:1 YUV image in separate-component form to its
  2079. ** equivalent interleaved 4:2:2 form.
  2080. */
  2081. extern void ScConvert411sTo422i_C(u_char *Y, u_char *Cb,
  2082. u_char *Cr, u_char *OutImage,
  2083. long width, long height)
  2084. {
  2085. u_char *p422e, *p422o, *Yo=Y+width;
  2086. int i, j;
  2087. height=abs(height)/2;
  2088. p422e=OutImage;
  2089. p422o=OutImage+width*2;
  2090. for (i=0; i<height; i++)
  2091. {
  2092. for (j=0; j<width; j+=2)
  2093. {
  2094. *p422e++ = *Y++;
  2095. *p422e++ = *Cb;
  2096. *p422e++ = *Y++;
  2097. *p422e++ = *Cr;
  2098. *p422o++ = *Yo++;
  2099. *p422o++ = *Cb++;
  2100. *p422o++ = *Yo++;
  2101. *p422o++ = *Cr++;
  2102. }
  2103. p422e=p422o;
  2104. p422o=p422e+width*2;
  2105. Y=Yo;
  2106. Yo=Y+width;
  2107. }
  2108. }
  2109. /*
  2110. ** Function: ScConvert411sTo422s_C
  2111. ** Purpose: Convert a 4:1:1 YUV image in separate-component form to its
  2112. ** equivalent interleaved 4:2:2 form.
  2113. */
  2114. extern void ScConvert411sTo422s_C(u_char *Y, u_char *Cb,
  2115. u_char *Cr, u_char *OutImage,
  2116. long width, long height)
  2117. {
  2118. u_char *p411, *p422e, *p422o;
  2119. int i, j;
  2120. height=abs(height);
  2121. if (OutImage!=Y)
  2122. memcpy(OutImage, Y, width*height); /* copy Y components */
  2123. p411=Cb+((height/2)-1)*(width/2);
  2124. p422e=OutImage+((height*width*3)/2)-width; /* U component */
  2125. p422o=p422e+(width/2);
  2126. for (i=0; i<height; i+=2)
  2127. {
  2128. for (j=0; j<width; j+=2, p411++, p422e++, p422o++)
  2129. *p422e=*p422o=*p411;
  2130. p411-=width;
  2131. p422o=p422e-width;
  2132. p422e=p422o-(width/2);
  2133. }
  2134. p411=Cr+((height/2)-1)*(width/2);
  2135. p422e=OutImage+(height*width*2)-width; /* V component */
  2136. p422o=p422e+(width/2);
  2137. for (i=0; i<height; i+=2)
  2138. {
  2139. for (j=0; j<width; j+=2, p411++, p422e++, p422o++)
  2140. *p422e=*p422o=*p411;
  2141. p411-=width;
  2142. p422o=p422e-width;
  2143. p422e=p422o-(width/2);
  2144. }
  2145. }
  2146. /*
  2147. ** Name: ScConvert1611sTo411s_C
  2148. ** Purpose: convert a YCrCb 16:1:1 (YUV9/YVU9) to YCrCb 4:1:1
  2149. */
  2150. ScStatus_t ScConvert1611sTo411s_C (u_char *inimage,
  2151. u_char *Y, u_char *U, u_char *V,
  2152. int Width, int Height)
  2153. {
  2154. register int y;
  2155. const int HalfWidth=Width/2;
  2156. unsigned char *RU, *RV;
  2157. int pixels = Width * abs(Height), tmp;
  2158. tmp = pixels / 16;
  2159. RU=inimage+pixels;
  2160. RV=RU+tmp;
  2161. memcpy(Y, inimage, pixels);
  2162. for (y = 0; y < tmp; y++)
  2163. {
  2164. *U++ = *RU;
  2165. *U++ = *RU;
  2166. *U++ = *RU;
  2167. *U++ = *RU++;
  2168. *V++ = *RV;
  2169. *V++ = *RV;
  2170. *V++ = *RV;
  2171. *V++ = *RV++;
  2172. }
  2173. return (NoErrors);
  2174. }
  2175. /*
  2176. ** Name: ScConvert1611sTo422s_C
  2177. ** Purpose: convert a YCrCb 16:1:1 (YUV9/YVU9) to YCrCb 4:2:2
  2178. */
  2179. ScStatus_t ScConvert1611sTo422s_C(u_char *inimage,
  2180. u_char *Y, u_char *U, u_char *V,
  2181. int Width, int Height)
  2182. {
  2183. register int x, y;
  2184. const int HalfWidth=Width/2;
  2185. unsigned char *RU, *RV;
  2186. unsigned char *Uo, *Vo;
  2187. int pixels = Width * abs(Height), tmp;
  2188. tmp = pixels / 16;
  2189. RU=inimage+pixels;
  2190. RV=RU+tmp;
  2191. memcpy(Y, inimage, pixels);
  2192. for (y = Height/32; y>0; y--)
  2193. {
  2194. Vo=V+Width;
  2195. Uo=U+Width;
  2196. for (x = Width/4; x > 0; x--)
  2197. {
  2198. *U++ = *Uo++ = *RU;
  2199. *U++ = *Uo++ = *RU;
  2200. *U++ = *Uo++ = *RU;
  2201. *U++ = *Uo++ = *RU++;
  2202. *V++ = *Vo++ = *RV;
  2203. *V++ = *Vo++ = *RV;
  2204. *V++ = *Vo++ = *RV;
  2205. *V++ = *Vo++ = *RV++;
  2206. }
  2207. V=Vo; U=Uo;
  2208. }
  2209. return (NoErrors);
  2210. }
  2211. /*
  2212. ** Name: ScConvert1611sTo422i_C
  2213. ** Purpose: convert a YCrCb 16:1:1 (YUV9/YVU9) to 4:2:2 interleaved
  2214. */
  2215. ScStatus_t ScConvert1611sTo422i_C(u_char *inimage, u_char *outimage,
  2216. int Width, int Height)
  2217. {
  2218. register int x, y;
  2219. const int HalfWidth=Width/2;
  2220. unsigned char *Ye, *Yo, *Ye2, *Yo2, *RU, *RV;
  2221. unsigned char *o1, *e1, *o2, *e2;
  2222. unsigned char U, V;
  2223. RU=inimage+Width*abs(Height);
  2224. RV=RU+(Width*abs(Height))/16;
  2225. e1=outimage;
  2226. Ye=inimage;
  2227. for (y = abs(Height)/4; y>0; y--)
  2228. {
  2229. Yo=Ye+Width;
  2230. Ye2=Yo+Width;
  2231. Yo2=Ye2+Width;
  2232. o1=e1+Width*2;
  2233. e2=o1+Width*2;
  2234. o2=e2+Width*2;
  2235. for (x = Width/4; x > 0; x--)
  2236. {
  2237. U = *RU++;
  2238. V = *RV++;
  2239. /* even line */
  2240. *e1++ = *Ye++;
  2241. *e1++ = U;
  2242. *e1++ = *Ye++;
  2243. *e1++ = V;
  2244. *e1++ = *Ye++;
  2245. *e1++ = U;
  2246. *e1++ = *Ye++;
  2247. *e1++ = V;
  2248. /* odd line */
  2249. *o1++ = *Yo++;
  2250. *o1++ = U;
  2251. *o1++ = *Yo++;
  2252. *o1++ = V;
  2253. *o1++ = *Yo++;
  2254. *o1++ = U;
  2255. *o1++ = *Yo++;
  2256. *o1++ = V;
  2257. /* even line */
  2258. *e2++ = *Ye2++;
  2259. *e2++ = U;
  2260. *e2++ = *Ye2++;
  2261. *e2++ = V;
  2262. *e2++ = *Ye2++;
  2263. *e2++ = U;
  2264. *e2++ = *Ye2++;
  2265. *e2++ = V;
  2266. /* odd line */
  2267. *o2++ = *Yo2++;
  2268. *o2++ = U;
  2269. *o2++ = *Yo2++;
  2270. *o2++ = V;
  2271. *o2++ = *Yo2++;
  2272. *o2++ = U;
  2273. *o2++ = *Yo2++;
  2274. *o2++ = V;
  2275. }
  2276. e1=o2;
  2277. Ye=Yo2;
  2278. }
  2279. return (NoErrors);
  2280. }
  2281. /*
  2282. ** Name: ScConvert411sTo1611s_C
  2283. ** Purpose: convert a YCrCb 4:1:1 to YCrCb 16:1:1 (YUV9/YVU9)
  2284. */
  2285. ScStatus_t ScConvert411sTo1611s_C (u_char *inimage,
  2286. u_char *Y, u_char *U, u_char *V,
  2287. int Width, int Height)
  2288. {
  2289. register int x, y, c0, c1, c2, c3;
  2290. unsigned char *Ue, *Uo, *Ve, *Vo;
  2291. int pixels = Width * abs(Height), tmp;
  2292. Width/=2;
  2293. tmp = pixels / 4;
  2294. Ue=inimage+pixels;
  2295. Uo=Ue+Width;
  2296. Ve=Ue+tmp;
  2297. Vo=Ve+Width;
  2298. memcpy(Y, inimage, pixels);
  2299. for (y = 0; y < tmp; y+=2)
  2300. {
  2301. for (x=0; x<Width; x+=2)
  2302. {
  2303. c0=*Ue++;
  2304. c1=*Ue++;
  2305. c2=*Uo++;
  2306. c3=*Uo++;
  2307. *U++ = (c0+c1+c2+c3)/4;
  2308. }
  2309. Ue=Uo;
  2310. Uo+=Width;
  2311. }
  2312. for (y = 0; y < tmp; y+=2)
  2313. {
  2314. for (x=0; x<Width; x+=2)
  2315. {
  2316. c0=*Ve++;
  2317. c1=*Ve++;
  2318. c2=*Vo++;
  2319. c3=*Vo++;
  2320. *V++ = (c0+c1+c2+c3)/4;
  2321. }
  2322. Ve=Vo;
  2323. Vo+=Width;
  2324. }
  2325. return (NoErrors);
  2326. }
  2327. /*
  2328. ** Function: ScConvertNTSCtoCIF422()
  2329. ** Purpose: Convert a Q/CIF frame from a 4:2:2 NTSC input. We dup every 10th
  2330. ** pixel horizontally and every 4th line vertically. We also
  2331. ** discard the chroma on every other line, since CIF wants 4:1:1.
  2332. */
  2333. ScStatus_t ScConvertNTSC422toCIF411_C(u_char *framein,
  2334. u_char *yp, u_char *up, u_char *vp,
  2335. int stride)
  2336. {
  2337. int h, w;
  2338. int vdup = 5;
  2339. for (h = 0; h < 240; ++h)
  2340. {
  2341. int hdup = 10/2;
  2342. for (w = 320; w > 0; w -= 2)
  2343. {
  2344. yp[0] = framein[0];
  2345. yp[1] = framein[2];
  2346. yp += 2;
  2347. if ((h & 1) == 0)
  2348. {
  2349. *up++ = framein[1];
  2350. *vp++ = framein[3];
  2351. }
  2352. framein += 4;
  2353. if (--hdup <= 0)
  2354. {
  2355. hdup = 10/2;
  2356. yp[0] = yp[-1];
  2357. yp += 1;
  2358. if ((h & 1) == 0)
  2359. {
  2360. if ((w & 2) == 0)
  2361. {
  2362. up[0] = up[-1];
  2363. ++up;
  2364. vp[0] = vp[-1];
  2365. ++vp;
  2366. }
  2367. }
  2368. }
  2369. }
  2370. if (--vdup <= 0)
  2371. {
  2372. vdup = 5;
  2373. /* copy previous line */
  2374. memcpy((char*)yp, (char*)yp - stride, stride);
  2375. yp += stride;
  2376. if ((h & 1) == 0)
  2377. {
  2378. int s = stride >> 1;
  2379. memcpy((char*)up, (char*)up - s, s);
  2380. memcpy((char*)vp, (char*)vp - s, s);
  2381. up += s;
  2382. vp += s;
  2383. }
  2384. }
  2385. }
  2386. return (NoErrors);
  2387. }
  2388.