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.

915 lines
35 KiB

  1. /*
  2. * @DEC_COPYRIGHT@
  3. */
  4. /*
  5. * HISTORY
  6. * $Log: scon_yuv_to_rgb.c,v $
  7. * $EndLog$
  8. */
  9. /*****************************************************************************
  10. ** Copyright (c) Digital Equipment Corporation, 1997 **
  11. ** **
  12. ** All Rights Reserved. Unpublished rights reserved under the copyright **
  13. ** laws of the United States. **
  14. ** **
  15. ** The software contained on this media is proprietary to and embodies **
  16. ** the confidential technology of Digital Equipment Corporation. **
  17. ** Possession, use, duplication or dissemination of the software and **
  18. ** media is authorized only pursuant to a valid written license from **
  19. ** Digital Equipment Corporation. **
  20. ** **
  21. ** RESTRICTED RIGHTS LEGEND Use, duplication, or disclosure by the U.S. **
  22. ** Government is subject to restrictions as set forth in Subparagraph **
  23. ** (c)(1)(ii) of DFARS 252.227-7013, or in FAR 52.227-19, as applicable. **
  24. ******************************************************************************/
  25. /**********************************************************************/
  26. /**********************************************************************/
  27. /* */
  28. /* Function: YUV_To_RGB_422_Init */
  29. /* Author: Bill Hallahan */
  30. /* Date: July 29, 1994 */
  31. /* */
  32. /* Abstract: */
  33. /* */
  34. /* This function produces a table that is used by the */
  35. /* yuv_to_rgb_422 conversion routines. This table is required */
  36. /* by the following routines. */
  37. /* */
  38. /* YUV_To_RGB_422_24_Bit */
  39. /* YUV_To_RGB_422_555 */
  40. /* */
  41. /* */
  42. /* YUV to RGB conversion can be described by a 3x3 matrix */
  43. /* multiplication: */
  44. /* */
  45. /* R | 1 0 VR | Y */
  46. /* G = | 1 UG VG | U */
  47. /* B | 1 UB 0 | V */
  48. /* */
  49. /* where: */
  50. /* */
  51. /* 0 <= Y <= 255 */
  52. /* -128 <= U <= 127 UG = -0.3455 UB = 1.7790 */
  53. /* -128 <= V <= 127 VR = 1.4075 VG = -0.7169 */
  54. /* */
  55. /* The Red, Green, and Blue output values are obtained in */
  56. /* parallel by summing three 64 bit words as shown. Each of the */
  57. /* quadwords is obtained from either the Y_Table, the U_Table, */
  58. /* or the V_table using the corresponding 8 bit Y, U, or V value */
  59. /* as an index. Thus all multiplications are performed by table */
  60. /* lookup. Note that the matrix output is ordered as B, R, G */
  61. /* and then B again (starting at the LSB). */
  62. /* This is to allow an efficient conversion to the output format. */
  63. /* */
  64. /* For 32-bit RGB, the Red and Blue bits are already in the */
  65. /* correct position, the conversion routine only has to shift */
  66. /* the Green bits. For General BI-BITFIELDS however, the Red, */
  67. /* Green and Blue bits could be anywhere in a 16-bit or 32-bit */
  68. /* word (we only support 16-bit for now). To avoid a costly */
  69. /* decicion in the inner loop whether to shift the Blue bits left */
  70. /* or right, we maintain a copy of the Blue bits in position 48 */
  71. /* so a right shift will always work. Each conversion routine can */
  72. /* choose whichever set of Blue bits that are fastest to use, */
  73. /* they are identical. */
  74. /* */
  75. /* */
  76. /* MSW LSW */
  77. /* */
  78. /* 63 48 47 32 31 16 15 0 Index */
  79. /* ----------------------------------------------- */
  80. /* | Y| Y| Y| Y| Y */
  81. /* ----------------------------------------------- */
  82. /* */
  83. /* ----------------------------------------------- */
  84. /* | ub| ug| 0| ub| U */
  85. /* ----------------------------------------------- */
  86. /* */
  87. /* ----------------------------------------------- */
  88. /* + | 0| vg| vr| 0| V */
  89. /* ----------------------------------------------- */
  90. /* __________________________________________________________ */
  91. /* */
  92. /* ----------------------------------------------- */
  93. /* Total | 0| 0| x| G| x| R| x| B| */
  94. /* ----------------------------------------------- */
  95. /* */
  96. /* */
  97. /* where: */
  98. /* */
  99. /* ub = UB * U */
  100. /* ug = UG * U */
  101. /* vg = VG * V */
  102. /* vr = VR * V */
  103. /* */
  104. /* */
  105. /* The maximum absolute value for Y is 255 and the maximum */
  106. /* for U or V is 128, so 9 bits is the minimum size to represent */
  107. /* them together as two's complement values. The maximum */
  108. /* chrominance (U or V) magnitude is 128. This is 0.5 as a Q9 */
  109. /* two's complement fraction. 255 is 1 - 2^-8 in Q9 fraction form. */
  110. /* */
  111. /* The maximum possible bit growth is determined as follows. */
  112. /* */
  113. /* R_Max = 1 - 2^-8 + 0.5 * fabs(VR) = 1.6998 */
  114. /* G_Max = 1 - 2^-8 + 0.5 * fabs(UG) + 0.5 * fabs(VG) = 1.5273 */
  115. /* B_Max = 1 - 2^-8 + 0.5 * fabs(UB) = 1.8856 */
  116. /* */
  117. /* */
  118. /* Since B_Max = 1.8856 then the next highest integer */
  119. /* greater than or equal to log base 2 of 1.8856 is 1. So 1 bit */
  120. /* is required for bit growth. The minimum accumulator size */
  121. /* required is 9 + 1 = 10 bits. This code uses 12 bit accumulators */
  122. /* since there are bits to spare. */
  123. /* */
  124. /* The 11'th bit (starting at bit 0) of each accumulator */
  125. /* is the sign bit. This may be tested to determine if there is */
  126. /* a negative result. Accumulator overflows are discarded as is */
  127. /* normal for two's complement arithmetic. Each R, G, or B result */
  128. /* that is over 255 is set to 255. Each R, G, or B result that is */
  129. /* less than zero is set to zero. */
  130. /* */
  131. /* */
  132. /* Input: */
  133. /* */
  134. /* */
  135. /* bSign Contains a 32 bit boolean that if non-zero, changes */
  136. /* the interpretation of the chrominance (U and V) data */
  137. /* from an offset binary format, where the values range */
  138. /* from 0 to 255 with 128 representing 0 chrominance, */
  139. /* to a signed two's complement format, where the values */
  140. /* range from -128 to 127. */
  141. /* */
  142. /* */
  143. /* bBGR Contains a 32 bit boolean that if non-zero, changes */
  144. /* the order of the conversion from RGB to BGR. */
  145. /* */
  146. /* */
  147. /* pTable The address of the RGB (or BGR) conversion table */
  148. /* that is filled in by this function. The table */
  149. /* address must be quadword aligned. The table size */
  150. /* is 6244 bytes 3 * 256 quadwords. */
  151. /* */
  152. /* */
  153. /* Output: */
  154. /* */
  155. /* This function has no return value. */
  156. /* */
  157. /* */
  158. /**********************************************************************/
  159. /**********************************************************************/
  160. /*
  161. #define _SLIBDEBUG_
  162. */
  163. #include "scon_int.h"
  164. #include "SC_err.h"
  165. #include "SC_conv.h"
  166. #ifdef _SLIBDEBUG_
  167. #include "sc_debug.h"
  168. #define _DEBUG_ 1 /* detailed debuging statements */
  169. #define _VERBOSE_ 1 /* show progress */
  170. #define _VERIFY_ 1 /* verify correct operation */
  171. #define _WARN_ 1 /* warnings about strange behavior */
  172. #endif
  173. /*
  174. * Define NEW_YCBCR to use new YCbCr conversion values.
  175. */
  176. #define NEW_YCBCR
  177. #define GetRGB555(in16, r, g, b) b = (in16>>7)&0xF8; \
  178. g = (in16>>2)&0xF8; \
  179. r = (in16<<3)&0xF8
  180. #define AddRGB555(in16, r, g, b) b += (in16>>7)&0xF8; \
  181. g += (in16>>2)&0xF8; \
  182. r += (in16<<3)&0xF8
  183. #define PutRGB565(r, g, b, out16) out16 = ((r&0xf8)<<8)|((g&0xfC)<<3)|((b&0xf8)>>3)
  184. #define PutRGB555(r, g, b, out16) out16 = ((r&0xf8)<<7)|((g&0xf8)<<2)|((b&0xf8)>>3)
  185. #ifdef NEW_YCBCR
  186. /*
  187. ** y = 16.000 + 0.257 * r + 0.504 * g + 0.098 * b ;
  188. ** u = 16.055 + 0.148 * (255-r) + 0.291 * (255-g) + 0.439 * b ;
  189. ** v = 16.055 + 0.439 * r + 0.368 * (255-g) + 0.071 * (255-b) ;
  190. */
  191. #define YC 16.000
  192. #define UC 16.055
  193. #define VC 16.055
  194. #define YR 0.257
  195. #define UR 0.148
  196. #define VR 0.439
  197. #define YG 0.504
  198. #define UG 0.291
  199. #define VG 0.368
  200. #define YB 0.098
  201. #define UB 0.439
  202. #define VB 0.071
  203. #else /* !NEW_YCBCR */
  204. /*
  205. ** ( y = 0.0 0.299 * r + 0.587 * g + 0.1140 * b ; )
  206. ** ( u = 0.245 + 0.169 * (255-r) + 0.332 * (255-g) + 0.5000 * b ; )
  207. ** ( v = 0.4235 + 0.500 * r + 0.419 * (255-g) + 0.0813 * (255-b) ; )
  208. */
  209. #define YC 0.0
  210. #define UC 0.245
  211. #define VC 0.4235
  212. #define YR 0.299
  213. #define UR 0.169
  214. #define VR 0.500
  215. #define YG 0.587
  216. #define UG 0.332
  217. #define VG 0.419
  218. #define YB 0.1140
  219. #define UB 0.5000
  220. #define VB 0.0813
  221. #endif /* !NEW_YCBCR */
  222. /********************************** YUV to RGB ***********************************/
  223. /*
  224. * The YUV to RGB conversion routines
  225. * generates RGB values in a 64-bit
  226. * word thus:
  227. *
  228. * 63 56 55 48 47 40 39 32 31 24 23 16 15 8 7 0
  229. * +-------+-------+-------+-------+-------+-------+-------+-------+
  230. * | 0 | Blue | 0 | Green | 0 | Red | 0 | Blue |
  231. * +-------+-------+-------+-------+-------+-------+-------+-------+
  232. *
  233. * Figure out how many steps to the right are needed to
  234. * shift the red, green and blue into the correct position.
  235. */
  236. #define ArrangRGB565(inrgb, outrgb) \
  237. outrgb=((inrgb>>8)&0xf800)|((inrgb>>29)&0x07e0)|((inrgb>>51)&0x001f)
  238. #define ArrangRGB888(inrgb, outrgb) \
  239. outrgb=(inrgb&0xFF0000)|((inrgb>>24)&0x00FF00)|(inrgb&0x0000FF)
  240. SconStatus_t sconInitYUVtoRGB(SconInfo_t *Info)
  241. {
  242. qword i, qY, qUV, qSigned;
  243. SconBoolean_t bBGR=Info->Output.vinfo.Rmask&1; /* BGR vs RGB ordering */
  244. SconBoolean_t bSign=FALSE; /* U and V are signed values */
  245. unsigned qword qRed;
  246. unsigned qword qGreen;
  247. unsigned qword qBlue;
  248. unsigned qword qTemp;
  249. unsigned qword qAccMask = 0xFFF;
  250. unsigned qword *pTable, *pU_Table, *pV_Table;
  251. double Chrominance;
  252. #ifdef NEW_YCBCR
  253. double CF_UB = 2.018;
  254. double CF_UG = -0.391;
  255. double CF_VG = -0.813;
  256. double CF_VR = 1.596;
  257. #else /* !NEW_YCBCR */
  258. double CF_UB = 1.7790;
  259. double CF_UG = -0.3455;
  260. double CF_VG = -0.7169;
  261. double CF_VR = 1.4075;
  262. #endif /* !NEW_YCBCR */
  263. /* allocate memory to hold the lookup table */
  264. if (Info->Table && Info->TableSize<256*3*8)
  265. {
  266. ScPaFree(Info->Table);
  267. Info->Table=NULL;
  268. }
  269. if (Info->Table==NULL)
  270. {
  271. if ((Info->Table = ScPaMalloc(256*3*8)) == NULL)
  272. return(SconErrorMemory);
  273. Info->TableSize=256*3*8;
  274. }
  275. /*
  276. * Set constant that determines if the U and V chrominance values
  277. * are interpreted as signed or unsigned values.
  278. */
  279. if ( !bSign )
  280. qSigned = 0;
  281. else
  282. qSigned = 0xFFFFFFFFFFFFFF80;
  283. /* Get the U, and V table pointers. */
  284. pTable = (unsigned qword *)Info->Table;
  285. pU_Table = pTable + 256;
  286. pV_Table = pU_Table + 256;
  287. /* Initialize the Y_Table, the U_Table, and the V_Table. */
  288. for ( i = 0; i < 256; i++ )
  289. {
  290. /******************************************************************/
  291. /* Construct the Y array value for the current index value. */
  292. /* */
  293. /* 63 48 47 32 31 16 15 0 Index */
  294. /* ----------------------------------------------- */
  295. /* | Y| Y| Y| Y| Y = i */
  296. /* ----------------------------------------------- */
  297. /* */
  298. /******************************************************************/
  299. #ifdef NEW_YCBCR
  300. qY = (qword) ((i-16)*1.164) ;
  301. qY = (qY < 0) ? 0 : (qY > 255) ? 255 : qY ;
  302. #else /* !NEW_YCBCR */
  303. qY = i ;
  304. #endif /* !NEW_YCBCR */
  305. qY |= qY << 16 ;
  306. *pTable++ = qY | ( qY << 32 ) ;
  307. /******************************************************************/
  308. /* Construct the U array value for the current index value. */
  309. /* */
  310. /* 63 48 47 32 31 16 15 0 Index */
  311. /* ----------------------------------------------- */
  312. /* | ub| ug| 0| ub| U = i */
  313. /* ----------------------------------------------- */
  314. /* */
  315. /******************************************************************/
  316. #ifdef NEW_YCBCR
  317. qUV = (i< 16) ? 16
  318. : (i<240) ? i
  319. : 240 ;
  320. #else /* !NEW_YCBCR */
  321. qUV = i ;
  322. #endif /* !NEW_YCBCR */
  323. Chrominance = (double) (( qUV - 128 ) ^ qSigned );
  324. qBlue = ((qword)( CF_UB * Chrominance )) & qAccMask;
  325. qGreen = ((qword)( CF_UG * Chrominance )) & qAccMask;
  326. qRed = 0;
  327. if ( bBGR )
  328. {
  329. qTemp = qBlue;
  330. qBlue = qRed;
  331. qRed = qTemp;
  332. }
  333. *pU_Table++ = qBlue | ( qRed << 16 ) | ( qGreen << 32 ) | ( qBlue << 48 );
  334. /******************************************************************/
  335. /* Construct the V array value for the current index value. */
  336. /* */
  337. /* 63 48 47 32 31 16 15 0 Index */
  338. /* ----------------------------------------------- */
  339. /* | 0| vg| vr| 0| V = i */
  340. /* ----------------------------------------------- */
  341. /* */
  342. /******************************************************************/
  343. qBlue = 0;
  344. qGreen = ((qword)( CF_VG * Chrominance )) & qAccMask;
  345. qRed = ((qword)( CF_VR * Chrominance )) & qAccMask;
  346. if ( bBGR )
  347. {
  348. qTemp = qBlue;
  349. qBlue = qRed;
  350. qRed = qTemp;
  351. }
  352. *pV_Table++ = qBlue | ( qRed << 16 ) | ( qGreen << 32 );
  353. }
  354. return(SconErrorNone);
  355. }
  356. SconStatus_t scon422ToRGB565(unsigned char *inimage, unsigned char *outimage,
  357. unsigned dword width, unsigned dword height,
  358. dword stride, unsigned qword *pTable)
  359. {
  360. unsigned qword y, u, v, mask ;
  361. unsigned qword y0, y1, y2, y3 ;
  362. unsigned qword y4, y5, y6, y7 ;
  363. unsigned qword u01, v01, u23, v23 ;
  364. unsigned qword *yData=(unsigned qword *)inimage;
  365. unsigned int *uData=(unsigned int *)(inimage+width*height);
  366. unsigned int *vData=(unsigned int *)(inimage+(width*height*3)/2);
  367. unsigned qword *rgbData=(unsigned qword *)outimage;
  368. unsigned dword x, line;
  369. if (stride<0) /* flip */
  370. outimage=outimage+((height-1)*(-stride));
  371. for (line=height; line>0; line--, outimage+=stride)
  372. {
  373. rgbData=(unsigned qword *)outimage;
  374. for (x=width>>3; x>0; x--)
  375. {
  376. y = *yData++ ;
  377. y0 = y & 255 ; y >>= 8 ;
  378. y1 = y & 255 ; y >>= 8 ;
  379. y2 = y & 255 ; y >>= 8 ;
  380. y3 = y & 255 ; y >>= 8 ;
  381. y4 = y & 255 ; y >>= 8 ;
  382. y5 = y & 255 ; y >>= 8 ;
  383. y6 = y & 255 ; y >>= 8 ;
  384. y7 = y & 255 ; y >>= 8 ;
  385. u = *uData++ ;
  386. u01 = u & 255 ; u >>= 8 ;
  387. u23 = u & 255 ; u >>= 8 ;
  388. v = *vData++ ;
  389. v01 = v & 255 ; v >>= 8 ;
  390. v23 = v & 255 ; v >>= 8 ;
  391. y0 = pTable[y0] ;
  392. y1 = pTable[y1] ;
  393. y2 = pTable[y2] ;
  394. y3 = pTable[y3] ;
  395. y4 = pTable[y4] ;
  396. y5 = pTable[y5] ;
  397. y6 = pTable[y6] ;
  398. y7 = pTable[y7] ;
  399. u01 = pTable[u01+256] ;
  400. u23 = pTable[u23+256] ;
  401. v01 = pTable[v01+512] ;
  402. v23 = pTable[v23+512] ;
  403. /* Now, convert to RGB */
  404. y0 += u01 + v01 ;
  405. y1 += u01 + v01 ;
  406. y2 += u23 + v23 ;
  407. y3 += u23 + v23 ;
  408. /*
  409. * Same thing for more pixels.
  410. * Use u01 for u45 and u23 for u67
  411. */
  412. u01 = u & 255 ; u >>= 8 ;
  413. u23 = u & 255 ;
  414. v01 = v & 255 ; v >>= 8 ;
  415. v23 = v & 255 ;
  416. u01 = pTable[u01+256] ;
  417. u23 = pTable[u23+256] ;
  418. v01 = pTable[v01+512] ;
  419. v23 = pTable[v23+512] ;
  420. /* Convert to RGB. */
  421. y4 += u01 + v01 ;
  422. y5 += u01 + v01 ;
  423. y6 += u23 + v23 ;
  424. y7 += u23 + v23 ;
  425. /* See if any value is out of range. */
  426. mask = (unsigned qword)0x0F000F000F000F00L;
  427. if( (y0 | y1 | y2 | y3 | y4 | y5 | y6 | y7) & mask )
  428. {
  429. /* Zero values that are negative */
  430. mask = (unsigned qword)0x0800080008000800L ;
  431. y = y0 & mask ; y0 &= ~(y - (y>>11)) ;
  432. y = y1 & mask ; y1 &= ~(y - (y>>11)) ;
  433. y = y2 & mask ; y2 &= ~(y - (y>>11)) ;
  434. y = y3 & mask ; y3 &= ~(y - (y>>11)) ;
  435. y = y4 & mask ; y4 &= ~(y - (y>>11)) ;
  436. y = y5 & mask ; y5 &= ~(y - (y>>11)) ;
  437. y = y6 & mask ; y6 &= ~(y - (y>>11)) ;
  438. y = y7 & mask ; y7 &= ~(y - (y>>11)) ;
  439. /* Clamp values that are > 255 to 255. */
  440. mask = (unsigned qword)0x0100010001000100L ;
  441. y = y0 & mask ; y0 |= (y - (y >> 8)) ;
  442. y = y1 & mask ; y1 |= (y - (y >> 8)) ;
  443. y = y2 & mask ; y2 |= (y - (y >> 8)) ;
  444. y = y3 & mask ; y3 |= (y - (y >> 8)) ;
  445. y = y4 & mask ; y4 |= (y - (y >> 8)) ;
  446. y = y5 & mask ; y5 |= (y - (y >> 8)) ;
  447. y = y6 & mask ; y6 |= (y - (y >> 8)) ;
  448. y = y7 & mask ; y7 |= (y - (y >> 8)) ;
  449. /* Stray bits left over will be masked below */
  450. }
  451. ArrangRGB565(y0, y0);
  452. ArrangRGB565(y1, y1);
  453. ArrangRGB565(y2, y2);
  454. ArrangRGB565(y3, y3);
  455. ArrangRGB565(y4, y4);
  456. ArrangRGB565(y5, y5);
  457. ArrangRGB565(y6, y6);
  458. ArrangRGB565(y7, y7);
  459. *rgbData++ = y0 | (y1 << 16) | (y2 << 32) | (y3 << 48) ;
  460. *rgbData++ = y4 | (y5 << 16) | (y6 << 32) | (y7 << 48) ;
  461. }
  462. }
  463. return(SconErrorNone);
  464. }
  465. SconStatus_t scon422ToRGB888(unsigned char *inimage, unsigned char *outimage,
  466. unsigned dword width, unsigned dword height,
  467. dword stride, unsigned qword *pTable)
  468. {
  469. unsigned qword y, u, v, mask ;
  470. unsigned qword y0, y1, y2, y3 ;
  471. unsigned qword u01, v01, u23, v23 ;
  472. unsigned dword *yData=(unsigned dword *)inimage;
  473. unsigned word *uData=(unsigned word *)(inimage+width*height);
  474. unsigned word *vData=(unsigned word *)(inimage+(width*height*3)/2);
  475. unsigned dword *rgbData=(unsigned dword *)outimage;
  476. unsigned dword x, line;
  477. if (stride<0) /* flip */
  478. outimage=outimage+((height-1)*(-stride));
  479. for (line=height; line>0; line--, outimage+=stride)
  480. {
  481. rgbData=(unsigned dword *)outimage;
  482. for (x=width>>2; x>0; x--)
  483. {
  484. y = *yData++ ;
  485. y0 = y & 255 ; y >>= 8 ;
  486. y1 = y & 255 ; y >>= 8 ;
  487. y2 = y & 255 ; y >>= 8 ;
  488. y3 = y & 255 ;
  489. u = *uData++ ;
  490. u01 = u & 255 ; u >>= 8 ;
  491. u23 = u & 255 ;
  492. v = *vData++ ;
  493. v01 = v & 255 ; v >>= 8 ;
  494. v23 = v & 255 ;
  495. y0 = pTable[y0] ;
  496. y1 = pTable[y1] ;
  497. y2 = pTable[y2] ;
  498. y3 = pTable[y3] ;
  499. u01 = pTable[u01+256] ;
  500. u23 = pTable[u23+256] ;
  501. v01 = pTable[v01+512] ;
  502. v23 = pTable[v23+512] ;
  503. /* Now, convert to RGB */
  504. y0 += u01 + v01 ;
  505. y1 += u01 + v01 ;
  506. y2 += u23 + v23 ;
  507. y3 += u23 + v23 ;
  508. /* See if any value is out of range. */
  509. mask = (unsigned qword)0x0F000F000F000F00L;
  510. if( (y0 | y1 | y2 | y3) & mask )
  511. {
  512. /* Zero values that are negative */
  513. mask = (unsigned qword)0x0800080008000800L ;
  514. y = y0 & mask ; y0 &= ~(y - (y>>11)) ;
  515. y = y1 & mask ; y1 &= ~(y - (y>>11)) ;
  516. y = y2 & mask ; y2 &= ~(y - (y>>11)) ;
  517. y = y3 & mask ; y3 &= ~(y - (y>>11)) ;
  518. /* Clamp values that are > 255 to 255. */
  519. mask = (unsigned qword)0x0100010001000100L ;
  520. y = y0 & mask ; y0 |= (y - (y >> 8)) ;
  521. y = y1 & mask ; y1 |= (y - (y >> 8)) ;
  522. y = y2 & mask ; y2 |= (y - (y >> 8)) ;
  523. y = y3 & mask ; y3 |= (y - (y >> 8)) ;
  524. /* Stray bits left over will be masked below */
  525. }
  526. ArrangRGB888(y0, y0);
  527. ArrangRGB888(y1, y1);
  528. ArrangRGB888(y2, y2);
  529. ArrangRGB888(y3, y3);
  530. *rgbData++ = (unsigned dword)(y0 | (y1 << 24));
  531. *rgbData++ = (unsigned dword)((y1 & 0xFFFF) | (y2 << 16));
  532. *rgbData++ = (unsigned dword)((y2 & 0xFF) | (y3 << 8));
  533. }
  534. }
  535. return(SconErrorNone);
  536. }
  537. SconStatus_t scon420ToRGB565(unsigned char *inimage, unsigned char *outimage,
  538. unsigned dword width, unsigned dword height,
  539. dword stride, unsigned qword *pTable)
  540. {
  541. unsigned qword y, u, v, mask ;
  542. unsigned qword y0, y1, y2, y3 ;
  543. unsigned qword y4, y5, y6, y7 ;
  544. unsigned qword u01, v01, u23, v23;
  545. unsigned qword *yData=(unsigned qword *)inimage;
  546. unsigned int *uData=(unsigned int *)(inimage+width*height);
  547. unsigned int *vData=(unsigned int *)(inimage+(width*height*5)/4);
  548. unsigned int *puData, *pvData;
  549. unsigned qword *rgbData=(unsigned qword *)outimage;
  550. unsigned dword x, line;
  551. if (stride<0) /* flip */
  552. outimage=outimage+((height-1)*(-stride));
  553. puData=uData;
  554. pvData=vData;
  555. for (line=(height>>1)<<1; line>0; line--, outimage+=stride)
  556. {
  557. rgbData=(unsigned qword *)outimage;
  558. if (line&1) /* odd line, reuse U and V */
  559. {
  560. puData=uData;
  561. pvData=vData;
  562. }
  563. else
  564. {
  565. uData=puData;
  566. vData=pvData;
  567. }
  568. for (x=width>>3; x>0; x--)
  569. {
  570. y = *yData++ ;
  571. y0 = y & 255 ; y >>= 8 ;
  572. y1 = y & 255 ; y >>= 8 ;
  573. y2 = y & 255 ; y >>= 8 ;
  574. y3 = y & 255 ; y >>= 8 ;
  575. y4 = y & 255 ; y >>= 8 ;
  576. y5 = y & 255 ; y >>= 8 ;
  577. y6 = y & 255 ; y >>= 8 ;
  578. y7 = y & 255 ; y >>= 8 ;
  579. u = *puData++ ;
  580. u01 = u & 255 ; u >>= 8 ;
  581. u23 = u & 255 ; u >>= 8 ;
  582. v = *pvData++ ;
  583. v01 = v & 255 ; v >>= 8 ;
  584. v23 = v & 255 ; v >>= 8 ;
  585. y0 = pTable[y0] ;
  586. y1 = pTable[y1] ;
  587. y2 = pTable[y2] ;
  588. y3 = pTable[y3] ;
  589. y4 = pTable[y4] ;
  590. y5 = pTable[y5] ;
  591. y6 = pTable[y6] ;
  592. y7 = pTable[y7] ;
  593. u01 = pTable[u01+256] ;
  594. u23 = pTable[u23+256] ;
  595. v01 = pTable[v01+512] ;
  596. v23 = pTable[v23+512] ;
  597. /* Now, convert to RGB */
  598. y0 += u01 + v01 ;
  599. y1 += u01 + v01 ;
  600. y2 += u23 + v23 ;
  601. y3 += u23 + v23 ;
  602. /*
  603. * Same thing for more pixels.
  604. * Use u01 for u45 and u23 for u67
  605. */
  606. u01 = u & 255 ; u >>= 8 ;
  607. u23 = u & 255 ;
  608. v01 = v & 255 ; v >>= 8 ;
  609. v23 = v & 255 ;
  610. u01 = pTable[u01+256] ;
  611. u23 = pTable[u23+256] ;
  612. v01 = pTable[v01+512] ;
  613. v23 = pTable[v23+512] ;
  614. /* Convert to RGB. */
  615. y4 += u01 + v01 ;
  616. y5 += u01 + v01 ;
  617. y6 += u23 + v23 ;
  618. y7 += u23 + v23 ;
  619. /* See if any value is out of range. */
  620. mask = (unsigned qword)0x0F000F000F000F00L;
  621. if( (y0 | y1 | y2 | y3 | y4 | y5 | y6 | y7) & mask )
  622. {
  623. /* Zero values that are negative */
  624. mask = (unsigned qword)0x0800080008000800L ;
  625. y = y0 & mask ; y0 &= ~(y - (y>>11)) ;
  626. y = y1 & mask ; y1 &= ~(y - (y>>11)) ;
  627. y = y2 & mask ; y2 &= ~(y - (y>>11)) ;
  628. y = y3 & mask ; y3 &= ~(y - (y>>11)) ;
  629. y = y4 & mask ; y4 &= ~(y - (y>>11)) ;
  630. y = y5 & mask ; y5 &= ~(y - (y>>11)) ;
  631. y = y6 & mask ; y6 &= ~(y - (y>>11)) ;
  632. y = y7 & mask ; y7 &= ~(y - (y>>11)) ;
  633. /* Clamp values that are > 255 to 255. */
  634. mask = (unsigned qword)0x0100010001000100L ;
  635. y = y0 & mask ; y0 |= (y - (y >> 8)) ;
  636. y = y1 & mask ; y1 |= (y - (y >> 8)) ;
  637. y = y2 & mask ; y2 |= (y - (y >> 8)) ;
  638. y = y3 & mask ; y3 |= (y - (y >> 8)) ;
  639. y = y4 & mask ; y4 |= (y - (y >> 8)) ;
  640. y = y5 & mask ; y5 |= (y - (y >> 8)) ;
  641. y = y6 & mask ; y6 |= (y - (y >> 8)) ;
  642. y = y7 & mask ; y7 |= (y - (y >> 8)) ;
  643. /* Stray bits left over will be masked below */
  644. }
  645. ArrangRGB565(y0, y0);
  646. ArrangRGB565(y1, y1);
  647. ArrangRGB565(y2, y2);
  648. ArrangRGB565(y3, y3);
  649. ArrangRGB565(y4, y4);
  650. ArrangRGB565(y5, y5);
  651. ArrangRGB565(y6, y6);
  652. ArrangRGB565(y7, y7);
  653. *rgbData++ = y0 | (y1 << 16) | (y2 << 32) | (y3 << 48) ;
  654. *rgbData++ = y4 | (y5 << 16) | (y6 << 32) | (y7 << 48) ;
  655. }
  656. }
  657. return(SconErrorNone);
  658. }
  659. SconStatus_t scon420ToRGB888(unsigned char *inimage, unsigned char *outimage,
  660. unsigned dword width, unsigned dword height,
  661. dword stride, unsigned qword *pTable)
  662. {
  663. unsigned qword y, u, v, mask ;
  664. unsigned qword y0, y1, y2, y3 ;
  665. unsigned qword u01, v01, u23, v23;
  666. unsigned dword *yData=(unsigned dword *)inimage;
  667. unsigned word *uData=(unsigned word *)(inimage+width*height);
  668. unsigned word *vData=(unsigned word *)(inimage+(width*height*5)/4);
  669. unsigned word *puData, *pvData;
  670. unsigned dword *rgbData=(unsigned dword *)outimage;
  671. unsigned dword x, line;
  672. if (stride<0) /* flip */
  673. outimage=outimage+((height-1)*(-stride));
  674. puData=uData;
  675. pvData=vData;
  676. for (line=(height>>1)<<1; line>0; line--, outimage+=stride)
  677. {
  678. rgbData=(unsigned dword *)outimage;
  679. if (line&1) /* odd line, reuse U and V */
  680. {
  681. puData=uData;
  682. pvData=vData;
  683. }
  684. else
  685. {
  686. uData=puData;
  687. vData=pvData;
  688. }
  689. for (x=width>>2; x>0; x--)
  690. {
  691. y = *yData++ ;
  692. y0 = y & 255 ; y >>= 8 ;
  693. y1 = y & 255 ; y >>= 8 ;
  694. y2 = y & 255 ; y >>= 8 ;
  695. y3 = y & 255 ;
  696. u = *puData++ ;
  697. u01 = u & 255 ; u >>= 8 ;
  698. u23 = u & 255 ;
  699. v = *pvData++ ;
  700. v01 = v & 255 ; v >>= 8 ;
  701. v23 = v & 255 ;
  702. y0 = pTable[y0] ;
  703. y1 = pTable[y1] ;
  704. y2 = pTable[y2] ;
  705. y3 = pTable[y3] ;
  706. u01 = pTable[u01+256] ;
  707. u23 = pTable[u23+256] ;
  708. v01 = pTable[v01+512] ;
  709. v23 = pTable[v23+512] ;
  710. /* Now, convert to RGB */
  711. y0 += u01 + v01 ;
  712. y1 += u01 + v01 ;
  713. y2 += u23 + v23 ;
  714. y3 += u23 + v23 ;
  715. /* See if any value is out of range. */
  716. mask = (unsigned qword)0x0F000F000F000F00L;
  717. if( (y0 | y1 | y2 | y3) & mask )
  718. {
  719. /* Zero values that are negative */
  720. mask = (unsigned qword)0x0800080008000800L ;
  721. y = y0 & mask ; y0 &= ~(y - (y>>11)) ;
  722. y = y1 & mask ; y1 &= ~(y - (y>>11)) ;
  723. y = y2 & mask ; y2 &= ~(y - (y>>11)) ;
  724. y = y3 & mask ; y3 &= ~(y - (y>>11)) ;
  725. /* Clamp values that are > 255 to 255. */
  726. mask = (unsigned qword)0x0100010001000100L ;
  727. y = y0 & mask ; y0 |= (y - (y >> 8)) ;
  728. y = y1 & mask ; y1 |= (y - (y >> 8)) ;
  729. y = y2 & mask ; y2 |= (y - (y >> 8)) ;
  730. y = y3 & mask ; y3 |= (y - (y >> 8)) ;
  731. /* Stray bits left over will be masked below */
  732. }
  733. ArrangRGB888(y0, y0);
  734. ArrangRGB888(y1, y1);
  735. ArrangRGB888(y2, y2);
  736. ArrangRGB888(y3, y3);
  737. *rgbData++ = (unsigned dword)(y0 | (y1 << 24));
  738. *rgbData++ = (unsigned dword)((y1 >> 8) | (y2 << 16));
  739. *rgbData++ = (unsigned dword)((y2 >> 16) | (y3 << 8));
  740. }
  741. }
  742. return(SconErrorNone);
  743. }
  744. /********************************** YUV to RGB ***********************************/
  745. SconStatus_t sconInitRGBtoYUV(SconInfo_t *Info)
  746. {
  747. unsigned dword i, y, u, v ;
  748. qword *RedToYuyv, *GreenToYuyv, *BlueToYuyv;
  749. /* allocate memory to hold the lookup table */
  750. if (Info->Table && Info->TableSize<256*3*8)
  751. {
  752. ScPaFree(Info->Table);
  753. Info->Table=NULL;
  754. }
  755. if (Info->Table==NULL)
  756. {
  757. if ((Info->Table = ScPaMalloc(256*3*8)) == NULL)
  758. return(SconErrorMemory);
  759. Info->TableSize=256*3*8;
  760. }
  761. RedToYuyv=(unsigned qword *)Info->Table;
  762. GreenToYuyv=RedToYuyv+256;
  763. BlueToYuyv=RedToYuyv+512;
  764. for( i=0 ; i<256 ; i++ )
  765. {
  766. /*
  767. * Calculate contribution from red.
  768. * We will also add in the constant here.
  769. * Pack it into the tables thus: lsb->YUYV<-msb
  770. */
  771. y = (unsigned dword) ((float)YC + (float)YR * (float)i) ;
  772. u = (unsigned dword) ((float)UC + (float)UR * (float)(255-i)) ;
  773. v = (unsigned dword) ((float)VC + (float)VR * (float)i) ;
  774. RedToYuyv[i] = (y | (u<<8) | (y<<16) | (v<<24)) ;
  775. /*
  776. * Calculate contribution from green.
  777. */
  778. y = (unsigned dword) ((float)YG * (float)i) ;
  779. u = (unsigned dword) ((float)UG * (float)(255-i)) ;
  780. v = (unsigned dword) ((float)VG * (float)(255-i)) ;
  781. GreenToYuyv[i] = (y | (u<<8) | (y<<16) | (v<<24)) ;
  782. /*
  783. * Calculate contribution from blue.
  784. */
  785. y = (unsigned dword) ((float)YB * (float)i) ;
  786. u = (unsigned dword) ((float)UB * (float)i) ;
  787. v = (unsigned dword) ((float)VB * (float)(255-i)) ;
  788. BlueToYuyv[i] = (y | (u<<8) | (y<<16) | (v<<24)) ;
  789. }
  790. return(SconErrorNone);
  791. }
  792. /*
  793. ** Name: sconRGB888To420
  794. ** Purpose: convert 24-bit RGB (8:8:8 format) to 16-bit YCrCb (4:1:1 format)
  795. */
  796. SconStatus_t sconRGB888To420(unsigned char *inimage, unsigned char *outimage,
  797. unsigned dword width, unsigned dword height,
  798. dword stride, unsigned qword *pTable)
  799. {
  800. unsigned char *yData=(unsigned char *)outimage;
  801. unsigned char *uData=(unsigned char *)(outimage+width*height);
  802. unsigned char *vData=(unsigned char *)(outimage+(width*height*5)/4);
  803. register unsigned dword row, col;
  804. unsigned dword yuyv, r, g, b;
  805. unsigned char *tmp, *evl, *odl;
  806. if (stride<0)
  807. inimage=inimage+(-stride*(height-1));
  808. for (row=height; row>0; row--)
  809. {
  810. if (row&1)
  811. {
  812. tmp=inimage;
  813. for (col = 0; col < width; col++)
  814. {
  815. r = *tmp++;
  816. g = *tmp++;
  817. b = *tmp++;
  818. yuyv = (unsigned dword)(pTable[r] + pTable[g+256] + pTable[b+512]);
  819. *yData++ = (yuyv&0xff);
  820. }
  821. inimage+=stride;
  822. }
  823. else
  824. {
  825. tmp = evl = inimage;
  826. inimage+=stride;
  827. odl = inimage;
  828. for (col = 0; col < width; col++)
  829. {
  830. r = *tmp++;
  831. g = *tmp++;
  832. b = *tmp++;
  833. yuyv = (unsigned dword)(pTable[r] + pTable[g+256] + pTable[b+512]);
  834. *yData++ = (yuyv&0xff);
  835. /* We only store every fourth value of u and v components */
  836. if (col & 1)
  837. {
  838. /* Compute average r, g and b values */
  839. r = (unsigned dword)*evl++ + (unsigned dword)*odl++;
  840. g = (unsigned dword)*evl++ + (unsigned dword)*odl++;
  841. b = (unsigned dword)*evl++ + (unsigned dword)*odl++;
  842. r += (unsigned dword)*evl++ + (unsigned dword)*odl++;
  843. g += (unsigned dword)*evl++ + (unsigned dword)*odl++;
  844. b += (unsigned dword)*evl++ + (unsigned dword)*odl++;
  845. r = r >> 2;
  846. g = g >> 2;
  847. b = b >> 2;
  848. yuyv = (unsigned dword)(pTable[r] + pTable[g+256] + pTable[b+512]);
  849. *uData++ = (yuyv>>24)& 0xff; // V
  850. *vData++ = (yuyv>>8) & 0xff; // U
  851. }
  852. }
  853. }
  854. }
  855. return(SconErrorNone);
  856. }