yuvalpha.c
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:29k
源码类别:

Symbian

开发平台:

Visual C++

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Source last modified: $Id: yuvalpha.c,v 1.2.36.1 2004/07/09 02:00:19 hubbe Exp $
  3.  * 
  4.  * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.
  5.  * 
  6.  * The contents of this file, and the files included with this file,
  7.  * are subject to the current version of the RealNetworks Public
  8.  * Source License (the "RPSL") available at
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed
  10.  * the file under the current version of the RealNetworks Community
  11.  * Source License (the "RCSL") available at
  12.  * http://www.helixcommunity.org/content/rcsl, in which case the RCSL
  13.  * will apply. You may also obtain the license terms directly from
  14.  * RealNetworks.  You may not use this file except in compliance with
  15.  * the RPSL or, if you have a valid RCSL with RealNetworks applicable
  16.  * to this file, the RCSL.  Please see the applicable RPSL or RCSL for
  17.  * the rights, obligations and limitations governing use of the
  18.  * contents of the file.
  19.  * 
  20.  * Alternatively, the contents of this file may be used under the
  21.  * terms of the GNU General Public License Version 2 or later (the
  22.  * "GPL") in which case the provisions of the GPL are applicable
  23.  * instead of those above. If you wish to allow use of your version of
  24.  * this file only under the terms of the GPL, and not to allow others
  25.  * to use your version of this file under the terms of either the RPSL
  26.  * or RCSL, indicate your decision by deleting the provisions above
  27.  * and replace them with the notice and other provisions required by
  28.  * the GPL. If you do not delete the provisions above, a recipient may
  29.  * use your version of this file under the terms of any one of the
  30.  * RPSL, the RCSL or the GPL.
  31.  * 
  32.  * This file is part of the Helix DNA Technology. RealNetworks is the
  33.  * developer of the Original Code and owns the copyrights in the
  34.  * portions it created.
  35.  * 
  36.  * This file, and the files included with this file, is distributed
  37.  * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
  38.  * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
  39.  * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
  40.  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
  41.  * ENJOYMENT OR NON-INFRINGEMENT.
  42.  * 
  43.  * Technology Compatibility Kit Test Suite(s) Location:
  44.  *    http://www.helixcommunity.org/content/tck
  45.  * 
  46.  * Contributor(s):
  47.  * 
  48.  * ***** END LICENSE BLOCK ***** */
  49. #include "hxtypes.h"
  50. #include "hxcom.h"
  51. #include "env.h"
  52. #include "yuvalpha.h"
  53. #ifdef _USE_MMX_BLENDERS
  54. //MMX alphablending only available on linux and windows right now.
  55. //Should work just fine on any IA plaform though (intel solaris for example)
  56. #include "mmx_util.h" //for checkMmxAvailablity()
  57. BOOL z_bMMXAvailable = FALSE;
  58. BOOL z_bCheckedForMMX = FALSE;
  59. #endif
  60. /////////////////////////////////////////////////////////////
  61. // Note:  Output buffer can be the same as one of the input
  62. //        buffers for I420 and YV12 output only.  Common 
  63. //        input/output buffer must have same pitch and lines
  64. //        width and height.
  65. /////////////////////////////////////////////////////////////
  66. /////////////////////////////////////////////////////////////
  67. //
  68. // Define the bit offsets for components in both
  69. // YUY2 and UYVU color formats.
  70. //
  71. /////////////////////////////////////////////////////////////
  72. #if BYTE_ORDER == LITTLE_ENDIAN
  73. // YUY2
  74. #define YUY2_Y0_SHIFT 0
  75. #define YUY2_U_SHIFT  8
  76. #define YUY2_Y1_SHIFT 16
  77. #define YUY2_V_SHIFT  24
  78. // UYVY
  79. #define UYVY_U_SHIFT  0
  80. #define UYVY_Y0_SHIFT 8
  81. #define UYVY_V_SHIFT  16
  82. #define UYVY_Y1_SHIFT 24
  83. #else /* BYTE_ORDER != LITTLE_ENDIAN */
  84. // YUY2
  85. #define YUY2_Y0_SHIFT 24
  86. #define YUY2_U_SHIFT  16
  87. #define YUY2_Y1_SHIFT 8
  88. #define YUY2_V_SHIFT  0
  89. // UYVY
  90. #define UYVY_U_SHIFT  24
  91. #define UYVY_Y0_SHIFT 16
  92. #define UYVY_V_SHIFT  8
  93. #define UYVY_Y1_SHIFT 0
  94. #endif
  95. /////////////////////////////////////////////////////////////
  96. //
  97. // I420andYUVAtoI420orYV12
  98. //
  99. // This function alpha-blends two I420 buffers into a third
  100. // I420 or YV12 buffer using the alpha info tacked to the 
  101. // end of the second I420 buffer
  102. //
  103. // The alpha used for chroma is merely one (lower-right) of
  104. // the alpha used in the corresponding 2x2 luma pels.
  105. //
  106. /////////////////////////////////////////////////////////////
  107. int I420andYUVAtoI420orYV12 (
  108. unsigned char *src1_ptr, int src1_pels,   int src1_lines,  int src1_pitch,
  109.                          int src1_startx, int src1_starty,
  110. unsigned char *src2_ptr, int src2_pels,   int src2_lines,  int src2_pitch,
  111.                          int src2_startx, int src2_starty,
  112. unsigned char *dest_ptr, int dest_pels,   int dest_lines,  int dest_pitch,
  113.                          int dest_startx, int dest_starty,
  114. int width,  int height,  int output_format)
  115. {
  116. int i, j;
  117. unsigned char *sy1, *su1, *sv1;
  118. unsigned char *sy2, *su2, *sv2, *sa2;
  119. unsigned char *dy, *du, *dv;
  120. // Initialize color plane pointers to beginning of image
  121. sy1 = src1_ptr;
  122. su1 = src1_ptr + src1_lines * src1_pitch;
  123. sv1 = su1 + src1_lines * src1_pitch / 4;
  124. sy2 = src2_ptr;
  125. su2 = src2_ptr + src2_lines * src2_pitch;
  126. sv2 = su2 + src2_lines * src2_pitch / 4;
  127. sa2 = sv2 + src2_lines * src2_pitch / 4;
  128. dy  = dest_ptr;
  129. if (output_format == CID_I420)
  130. {
  131. du  = dest_ptr + dest_lines * dest_pitch;
  132. dv  = du + dest_lines * dest_pitch / 4;
  133. }
  134. else if (output_format == CID_YV12)
  135. {
  136. dv  = dest_ptr + dest_lines * dest_pitch;
  137. du  = dv + dest_lines * dest_pitch / 4;
  138. }
  139. else
  140. {
  141. return -1;
  142. }
  143. // Move color plane pointers to start points
  144. sy1 += src1_starty * src1_pitch + src1_startx;
  145. su1 += (src1_starty * src1_pitch / 4) + src1_startx / 2;
  146. sv1 += (src1_starty * src1_pitch / 4) + src1_startx / 2;
  147. sy2 += src2_starty * src2_pitch + src2_startx;
  148. su2 += (src2_starty * src2_pitch / 4) + src2_startx / 2;
  149. sv2 += (src2_starty * src2_pitch / 4) + src2_startx / 2;
  150. sa2 += src2_starty * src2_pitch + src2_startx;
  151. dy += dest_starty * dest_pitch + dest_startx;
  152. du += (dest_starty * dest_pitch / 4) + dest_startx / 2;
  153. dv += (dest_starty * dest_pitch / 4) + dest_startx / 2;
  154. for (i = 0; i < height; i += 2)
  155. {
  156. // First line
  157. for (j = 0; j < width - 3; j += 4)
  158. {
  159. int x1, x2;
  160. // Y
  161. x1 = *(sy1 + 0);
  162. x2 = *(sy2 + 0);
  163. x1 -= x2;
  164. x1 *= *(sa2 + 0);
  165. x1 >>= 8;
  166. x1 += x2;
  167. *(dy + 0) = x1;
  168. x1 = *(sy1 + 1);
  169. x2 = *(sy2 + 1);
  170. x1 -= x2;
  171. x1 *= *(sa2 + 1);
  172. x1 >>= 8;
  173. x1 += x2;
  174. *(dy + 1) = x1;
  175. x1 = *(sy1 + 2);
  176. x2 = *(sy2 + 2);
  177. x1 -= x2;
  178. x1 *= *(sa2 + 2);
  179. x1 >>= 8;
  180. x1 += x2;
  181. *(dy + 2) = x1;
  182. x1 = *(sy1 + 3);
  183. x2 = *(sy2 + 3);
  184. x1 -= x2;
  185. x1 *= *(sa2 + 3);
  186. x1 >>= 8;
  187. x1 += x2;
  188. *(dy + 3) = x1;
  189. sy1 += 4;
  190. sy2 += 4;
  191. sa2 += 4;
  192. dy  += 4;
  193. }
  194. while (j < width)
  195. {
  196. int x1, x2;
  197. // Y
  198. x1 = *sy1++;
  199. x2 = *sy2++;
  200. x1 -= x2;
  201. x1 *= *sa2++;
  202. x1 >>= 8;
  203. x1 += x2;
  204. *dy++ = x1; 
  205. j++;
  206. }
  207. // move to next line
  208. sy1 += src1_pitch - width;
  209. sy2 += src2_pitch - width;
  210. sa2 += src2_pitch - width;
  211. dy  += dest_pitch - width;
  212. // Second line
  213. for (j = 0; j < width; j += 2)
  214. {
  215. int x1, x2, x1b, a;
  216. // Y
  217. x1 = *(sy1 + 0);
  218. x2 = *(sy2 + 0);
  219. x1 -= x2;
  220. x1 *= *(sa2 + 0);
  221. x1 >>= 8;
  222. x1 += x2;
  223. *(dy + 0) = x1;
  224. // Y
  225. x1 = *(sy1 + 1);
  226. x2 = *(sy2 + 1);
  227. x1 -= x2;
  228. a  = *(sa2 + 1);
  229. x1 *= a;
  230. x1 >>= 8;
  231. x1 += x2;
  232. *(dy + 1) = x1; 
  233. //We need to do something with the four alpha values
  234. //and this chroma value. We can average/mean/max/min?????
  235. //Avaerage alpha values....
  236. a += *(sa2+0);
  237. a += *((sa2-src2_pitch)+0);
  238. a += *((sa2-src2_pitch)+1);
  239. a >>= 2;
  240. //Max/Min?
  241. //a = max( *(sa2+0), *(sa2+1));
  242. sy1 += 2;
  243. sy2 += 2;
  244. sa2 += 2;
  245. dy  += 2;
  246. // U
  247. x1 = *su1++;
  248. x2 = *su2++;
  249. x1 -= x2;
  250. x1 *= a;
  251. x1 >>= 8;
  252. x1 += x2;
  253. // V
  254. x1b = *sv1++;
  255. x2  = *sv2++;
  256. x1b -= x2;
  257. x1b *= a;
  258. x1b >>= 8;
  259. x1b += x2;
  260. *du++ = x1;     // postpone store to allow inplace YV12
  261. *dv++ = x1b;
  262. }
  263. // move to next line
  264. sy1 += src1_pitch - width;
  265. su1 += (src1_pitch - width) / 2;
  266. sv1 += (src1_pitch - width) / 2;
  267. sy2 += src2_pitch - width;
  268. su2 += (src2_pitch - width) / 2;
  269. sv2 += (src2_pitch - width) / 2;
  270. sa2 += src2_pitch - width;
  271. dy  += dest_pitch - width;
  272. du  += (dest_pitch - width) / 2;
  273. dv  += (dest_pitch - width) / 2;
  274.                 
  275. /*                  sy1 = src1_ptr; */
  276. /*                  su1 = src1_ptr + src1_lines * src1_pitch; */
  277. /*                  sv1 = su1 + src1_lines * src1_pitch / 4; */
  278.                 
  279. /*                  sy2 = src2_ptr; */
  280. /*                  su2 = src2_ptr + src2_lines * src2_pitch; */
  281. /*                  sv2 = su2 + src2_lines * src2_pitch / 4; */
  282. /*                  sa2 = sv2 + src2_lines * src2_pitch / 4; */
  283. /*                  dy  = dest_ptr; */
  284.                 
  285. /*                  if (output_format == CID_I420) */
  286. /*                  { */
  287. /*                      du  = dest_ptr + dest_lines * dest_pitch; */
  288. /*                      dv  = du + dest_lines * dest_pitch / 4; */
  289. /*                  } */
  290. /*                  else if (output_format == CID_YV12) */
  291. /*                  { */
  292. /*                      dv  = dest_ptr + dest_lines * dest_pitch; */
  293. /*                      du  = dv + dest_lines * dest_pitch / 4; */
  294. /*                  } */
  295.         
  296. /*                  sy1 +=  (src1_starty+i) * src1_pitch + src1_startx; */
  297. /*                  su1 += ((src1_starty+i) * src1_pitch / 4) + src1_startx / 2; */
  298. /*                  sv1 += ((src1_starty+i) * src1_pitch / 4) + src1_startx / 2; */
  299.                 
  300. /*                  sy2 +=  (src2_starty+i) * src2_pitch + src2_startx; */
  301. /*                  su2 += ((src2_starty+i) * src2_pitch / 4) + src2_startx / 2; */
  302. /*                  sv2 += ((src2_starty+i) * src2_pitch / 4) + src2_startx / 2; */
  303. /*                  sa2 +=  (src2_starty+i) * src2_pitch + src2_startx; */
  304.                 
  305. /*                  dy +=  (dest_starty+i) * dest_pitch + dest_startx; */
  306. /*                  du += ((dest_starty+i) * dest_pitch / 4) + dest_startx / 2; */
  307. /*                  dv += ((dest_starty+i) * dest_pitch / 4) + dest_startx / 2; */
  308. }
  309. return 0;
  310. }
  311. /////////////////////////////////////////////////////////////
  312. //
  313. // I420andYUVAtoYUY2
  314. //
  315. // This function alpha-blends two I420 buffers into a third
  316. // YUY2 buffer using the alpha info tacked to the 
  317. // end of the second I420 buffer
  318. //
  319. /////////////////////////////////////////////////////////////
  320. int I420andYUVAtoYUY2 (
  321. unsigned char *src1_ptr, int src1_pels,   int src1_lines,  int src1_pitch,
  322.                          int src1_startx, int src1_starty,
  323. unsigned char *src2_ptr, int src2_pels,   int src2_lines,  int src2_pitch,
  324.                          int src2_startx, int src2_starty,
  325. unsigned char *dest_ptr, int dest_pels,   int dest_lines,  int dest_pitch,
  326.                          int dest_startx, int dest_starty,
  327. int width,  int height)
  328. {
  329. int i, j;
  330. unsigned char *sy11, *sy12, *su1, *sv1;
  331. unsigned char *sy21, *sy22, *su2, *sv2, *sa21, *sa22;
  332. unsigned int  *dst1, *dst2;
  333. sy11 = src1_ptr;
  334. su1  = src1_ptr + src1_lines * src1_pitch;
  335. sv1  = su1 + src1_lines * src1_pitch / 4;
  336. sy21 = src2_ptr;
  337. su2  = src2_ptr + src2_lines * src2_pitch;
  338. sv2  = su2 + src2_lines * src2_pitch / 4;
  339. sa21 = sv2 + src2_lines * src2_pitch / 4;
  340. dst1 = (unsigned int *)(dest_ptr);
  341. // Move color planes to start point
  342. sy11 += src1_starty * src1_pitch + src1_startx;
  343. sy12  = sy11 + src1_pitch;
  344. su1  += src1_starty * src1_pitch / 4 + src1_startx / 2;
  345. sv1  += src1_starty * src1_pitch / 4 + src1_startx / 2;
  346. sy21 += src2_starty * src2_pitch + src2_startx;
  347. sy22  = sy21 + src2_pitch;
  348. su2  += src2_starty * src2_pitch / 4 + src2_startx / 2;
  349. sv2  += src2_starty * src2_pitch / 4 + src2_startx / 2;
  350. sa21 += src2_starty * src2_pitch + src2_startx;
  351. sa22  = sa21 + src2_pitch;
  352. dst1 += dest_starty * dest_pitch / 4 + dest_startx / 2;
  353. dst2  = dst1 + dest_pitch / 4;
  354. for (i = 0; i < height / 2; i++)
  355. {
  356. for (j = 0; j < width / 2; j++)
  357. {
  358. int x1, x2, a1, a2, d;
  359. int u1, u2, v1, v2;
  360. // First line
  361. // Y0
  362. x1 = *(sy11 + 0);
  363. x2 = *(sy21 + 0);
  364. x1 -= x2;
  365. a1 = *(sa21 + 0);
  366. x1 *= a1;
  367. x1 >>= 8;
  368. x1 += x2;
  369. d = (x1 << YUY2_Y0_SHIFT);
  370. // Y1
  371. x1 = *(sy11 + 1);
  372. x2 = *(sy21 + 1);
  373. x1 -= x2;
  374. a2 = *(sa21 + 1);
  375. x1 *= a2;
  376. x1 >>= 8;
  377. x1 += x2;
  378. d |= (x1 << YUY2_Y1_SHIFT);
  379. sy11 += 2;
  380. sy21 += 2;
  381. sa21 += 2;
  382. // Average Alphas
  383. a1 += a2;
  384. a1 >>= 1;
  385. // U
  386. x1 = u1 = *su1;
  387. x2 = u2 = *su2;
  388. x1 -= x2;
  389. x1 *= a1;
  390. x1 >>= 8;
  391. x1 += x2;
  392. d |= (x1 << YUY2_U_SHIFT);
  393. // V
  394. x1 = v1 = *sv1;
  395. x2 = v2 = *sv2;
  396. x1 -= x2;
  397. x1 *= a1;
  398. x1 >>= 8;
  399. x1 += x2;
  400. d |= (x1 << YUY2_V_SHIFT);
  401. su1++;
  402. su2++;
  403. sv1++;
  404. sv2++;
  405. // Store YUY2 pel
  406. *dst1++ = d;
  407. // Second line
  408. // Y0
  409. x1 = *(sy12 + 0);
  410. x2 = *(sy22 + 0);
  411. x1 -= x2;
  412. a1 = *(sa22 + 0);
  413. x1 *= a1;
  414. x1 >>= 8;
  415. x1 += x2;
  416. d = (x1 << YUY2_Y0_SHIFT);
  417. // Y1
  418. x1 = *(sy12 + 1);
  419. x2 = *(sy22 + 1);
  420. x1 -= x2;
  421. a2 = *(sa22 + 1);
  422. x1 *= a2;
  423. x1 >>= 8;
  424. x1 += x2;
  425. d |= (x1 << YUY2_Y1_SHIFT);
  426. sy12 += 2;
  427. sy22 += 2;
  428. sa22 += 2;
  429. // Average Alphas
  430. a1 += a2;
  431. a1 >>= 1;
  432. // U
  433. u1 -= u2;
  434. u1 *= a1;
  435. u1 >>= 8;
  436. u1 += u2;
  437. d |= (u1 << YUY2_U_SHIFT);
  438. // V
  439. v1 -= v2;
  440. v1 *= a1;
  441. v1 >>= 8;
  442. v1 += v2;
  443. d |= (v1 << YUY2_V_SHIFT);
  444. // Store YUY2 pel
  445. *dst2++ = d;
  446. }
  447. // move down two lines
  448. sy11 += 2 * src1_pitch - width;
  449. sy12 += 2 * src1_pitch - width;
  450. su1 += (src1_pitch - width) / 2;
  451. sv1 += (src1_pitch - width) / 2;
  452. sy21 += 2 * src2_pitch - width;
  453. sy22 += 2 * src2_pitch - width;
  454. su2 += (src2_pitch - width) / 2;
  455. sv2 += (src2_pitch - width) / 2;
  456. sa21 += 2 * src2_pitch - width;
  457. sa22 += 2 * src2_pitch - width;
  458. dst1 += (dest_pitch / 2) - (width / 2);
  459. dst2 += (dest_pitch / 2) - (width / 2);
  460. }
  461. return 0;
  462. }
  463. /////////////////////////////////////////////////////////////
  464. //
  465. // I420andYUVAtoUYVY
  466. //
  467. // This function alpha-blends two I420 buffers into a third
  468. // UYVY buffer using the alpha info tacked to the 
  469. // end of the second I420 buffer
  470. //
  471. /////////////////////////////////////////////////////////////
  472. int I420andYUVAtoUYVY (
  473. unsigned char *src1_ptr, int src1_pels,   int src1_lines,  int src1_pitch,
  474.                          int src1_startx, int src1_starty,
  475. unsigned char *src2_ptr, int src2_pels,   int src2_lines,  int src2_pitch,
  476.                          int src2_startx, int src2_starty,
  477. unsigned char *dest_ptr, int dest_pels,   int dest_lines,  int dest_pitch,
  478.                          int dest_startx, int dest_starty,
  479. int width,  int height)
  480. {
  481. int i, j;
  482. unsigned char *sy11, *sy12, *su1, *sv1;
  483. unsigned char *sy21, *sy22, *su2, *sv2, *sa21, *sa22;
  484. unsigned int  *dst1, *dst2;
  485. // Initialize color plane pointers
  486. sy11 = src1_ptr;
  487. su1  = src1_ptr + src1_lines * src1_pitch;
  488. sv1  = su1 + src1_lines * src1_pitch / 4;
  489. sy21 = src2_ptr;
  490. su2  = src2_ptr + src2_lines * src2_pitch;
  491. sv2  = su2 + src2_lines * src2_pitch / 4;
  492. sa21 = sv2 + src2_lines * src2_pitch / 4;
  493. dst1 = (unsigned int *)(dest_ptr);
  494. // Move color planes to start point
  495. sy11 += src1_starty * src1_pitch + src1_startx;
  496. sy12  = sy11 + src1_pitch;
  497. su1  += src1_starty * src1_pitch / 4 + src1_startx / 2;
  498. sv1  += src1_starty * src1_pitch / 4 + src1_startx / 2;
  499. sy21 += src2_starty * src2_pitch + src2_startx;
  500. sy22  = sy21 + src2_pitch;
  501. su2  += src2_starty * src2_pitch / 4 + src2_startx / 2;
  502. sv2  += src2_starty * src2_pitch / 4 + src2_startx / 2;
  503. sa21 += src2_starty * src2_pitch + src2_startx;
  504. sa22  = sa21 + src2_pitch;
  505. dst1 += dest_starty * dest_pitch / 4 + dest_startx / 2;
  506. dst2  = dst1 + dest_pitch / 4;
  507. for (i = 0; i < height / 2; i++)
  508. {
  509. for (j = 0; j < width / 2; j++)
  510. {
  511. int x1, x2, a1, a2, d;
  512. int u1, u2, v1, v2;
  513. // First line
  514. // Y0
  515. x1 = *(sy11 + 0);
  516. x2 = *(sy21 + 0);
  517. x1 -= x2;
  518. a1 = *(sa21 + 0);
  519. x1 *= a1;
  520. x1 >>= 8;
  521. x1 += x2;
  522. d = (x1 << UYVY_Y0_SHIFT);
  523. // Y1
  524. x1 = *(sy11 + 1);
  525. x2 = *(sy21 + 1);
  526. x1 -= x2;
  527. a2 = *(sa21 + 1);
  528. x1 *= a2; 
  529. x1 >>= 8;
  530. x1 += x2;
  531. d |= (x1 << UYVY_Y1_SHIFT);
  532. sy11 += 2;
  533. sy21 += 2;
  534. sa21 += 2;
  535. // Average Alphas
  536. a1 += a2;
  537. a1 >>= 1;
  538. // U
  539. x1 = u1 = *su1;
  540. x2 = u2 = *su2;
  541. x1 -= x2;
  542. x1 *= a1;
  543. x1 >>= 8;
  544. x1 += x2;
  545. d |= (x1 << UYVY_U_SHIFT);
  546. // V
  547. x1 = v1 = *sv1;
  548. x2 = v2 = *sv2;
  549. x1 -= x2;
  550. x1 *= a1;
  551. x1 >>= 8;
  552. x1 += x2;
  553. d |= (x1 << UYVY_V_SHIFT);
  554. su1++;
  555. su2++;
  556. sv1++;
  557. sv2++;
  558. // Store YUY2 pel
  559. *dst1++ = d;
  560. // Second line
  561. // Y0
  562. x1 = *(sy12 + 0);
  563. x2 = *(sy22 + 0);
  564. x1 -= x2;
  565. a1 = *(sa22 + 0);
  566. x1 *= a1;
  567. x1 >>= 8;
  568. x1 += x2;
  569. d = (x1 << UYVY_Y0_SHIFT);
  570. // Y1
  571. x1 = *(sy12 + 1);
  572. x2 = *(sy22 + 1);
  573. x1 -= x2;
  574. a2 = *(sa22 + 1);
  575. x1 *= a2;
  576. x1 >>= 8;
  577. x1 += x2;
  578. d |= (x1 << UYVY_Y1_SHIFT);
  579. sy12 += 2;
  580. sy22 += 2;
  581. sa22 += 2;
  582. // Average Alphas
  583. a1 += a2;
  584. a1 >>= 1;
  585. // U
  586. u1 -= u2;
  587. u1 *= a1;
  588. u1 >>= 8;
  589. u1 += u2;
  590. d |= (u1 << UYVY_U_SHIFT);
  591. // V
  592. v1 -= v2;
  593. v1 *= a1;
  594. v1 >>= 8;
  595. v1 += v2;
  596. d |= (v1 << UYVY_V_SHIFT);
  597. // Store YUY2 pel
  598. *dst2++ = d;
  599. }
  600. // move down two lines
  601. sy11 += 2 * src1_pitch - width;
  602. sy12 += 2 * src1_pitch - width;
  603. su1 += (src1_pitch - width) / 2;
  604. sv1 += (src1_pitch - width) / 2;
  605. sy21 += 2 * src2_pitch - width;
  606. sy22 += 2 * src2_pitch - width;
  607. su2 += (src2_pitch - width) / 2;
  608. sv2 += (src2_pitch - width) / 2;
  609. sa21 += 2 * src2_pitch - width;
  610. sa22 += 2 * src2_pitch - width;
  611. dst1 += (dest_pitch / 2) - (width / 2);
  612. dst2 += (dest_pitch / 2) - (width / 2);
  613. }
  614. return 0;
  615. }
  616. /////////////////////////////////////////////////////////////
  617. //
  618. // I420andYUVAtoI420
  619. //
  620. // This function alpha-blends two I420 buffers into a third
  621. // I420 buffer using the alpha info tacked to the 
  622. // end of the second I420 buffer
  623. //
  624. /////////////////////////////////////////////////////////////
  625. int I420andYUVAtoI420 (
  626. unsigned char *src1_ptr, int src1_pels,   int src1_lines,  int src1_pitch,
  627.                          int src1_startx, int src1_starty,
  628. unsigned char *src2_ptr, int src2_pels,   int src2_lines,  int src2_pitch,
  629.                          int src2_startx, int src2_starty,
  630. unsigned char *dest_ptr, int dest_pels,   int dest_lines,  int dest_pitch,
  631.                          int dest_startx, int dest_starty,
  632. int width,  int height)
  633. {
  634. return I420andYUVAtoI420orYV12 (
  635. src1_ptr, src1_pels, src1_lines, src1_pitch, src1_startx, src1_starty,
  636. src2_ptr, src2_pels, src2_lines, src2_pitch, src2_startx, src2_starty,
  637. dest_ptr, dest_pels, dest_lines, dest_pitch, dest_startx, dest_starty,
  638. width, height, CID_I420);
  639. }
  640. /////////////////////////////////////////////////////////////
  641. //
  642. // I420andYUVAtoYV12
  643. //
  644. // This function alpha-blends two I420 buffers into a third
  645. // YV12 buffer using the alpha info tacked to the 
  646. // end of the second I420 buffer
  647. //
  648. /////////////////////////////////////////////////////////////
  649. int I420andYUVAtoYV12 (
  650. unsigned char *src1_ptr, int src1_pels,   int src1_lines,  int src1_pitch,
  651.                          int src1_startx, int src1_starty,
  652. unsigned char *src2_ptr, int src2_pels,   int src2_lines,  int src2_pitch,
  653.                          int src2_startx, int src2_starty,
  654. unsigned char *dest_ptr, int dest_pels,   int dest_lines,  int dest_pitch,
  655.                          int dest_startx, int dest_starty,
  656. int width,  int height)
  657. {
  658. return I420andYUVAtoI420orYV12 (
  659. src1_ptr, src1_pels, src1_lines, src1_pitch, src1_startx, src1_starty,
  660. src2_ptr, src2_pels, src2_lines, src2_pitch, src2_startx, src2_starty,
  661. dest_ptr, dest_pels, dest_lines, dest_pitch, dest_startx, dest_starty,
  662. width, height, CID_YV12);
  663. }
  664. /////////////////////////////////////////////////////////////
  665. //
  666. // I420andYUVA
  667. //
  668. // This function alpha-blends two I420 buffers into a third
  669. // YV12 buffer using the alpha info tacked to the 
  670. // end of the second I420 buffer
  671. //
  672. /////////////////////////////////////////////////////////////
  673. int HXEXPORT ENTRYPOINT(I420andYUVA) (
  674. unsigned char *src1_ptr, int src1_pels,   int src1_lines,  int src1_pitch,
  675.                          int src1_startx, int src1_starty,
  676. unsigned char *src2_ptr, int src2_pels,   int src2_lines,  int src2_pitch,
  677.                          int src2_startx, int src2_starty,
  678. unsigned char *dest_ptr, int dest_pels,   int dest_lines,  int dest_pitch,
  679.                          int dest_startx, int dest_starty,
  680. int width,  int height,  int color_format)
  681. {
  682. #ifdef _USE_MMX_BLENDERS
  683.     if( !z_bCheckedForMMX )
  684.     {
  685.         z_bMMXAvailable = (checkMmxAvailablity()&CPU_HAS_MMX)?1:0;
  686.         z_bCheckedForMMX = TRUE;
  687.     }
  688.     
  689.     if( z_bMMXAvailable )
  690.     {
  691.         switch (color_format)
  692.         {
  693.            case CID_I420:
  694.                return I420andYUVAtoI420_MMX (
  695.                    src1_ptr, src1_pels, src1_lines, src1_pitch, src1_startx, src1_starty,
  696.                    src2_ptr, src2_pels, src2_lines, src2_pitch, src2_startx, src2_starty,
  697.                    dest_ptr, dest_pels, dest_lines, dest_pitch, dest_startx, dest_starty,
  698.                    width, height);
  699.            case CID_YV12:
  700.                return I420andYUVAtoYV12_MMX (
  701.                    src1_ptr, src1_pels, src1_lines, src1_pitch, src1_startx, src1_starty,
  702.                    src2_ptr, src2_pels, src2_lines, src2_pitch, src2_startx, src2_starty,
  703.                    dest_ptr, dest_pels, dest_lines, dest_pitch, dest_startx, dest_starty,
  704.                    width, height);
  705.            case CID_YUY2:
  706.                return I420andYUVAtoYUY2_MMX (
  707.                    src1_ptr, src1_pels, src1_lines, src1_pitch, src1_startx, src1_starty,
  708.                    src2_ptr, src2_pels, src2_lines, src2_pitch, src2_startx, src2_starty,
  709.                    dest_ptr, dest_pels, dest_lines, dest_pitch, dest_startx, dest_starty,
  710.                    width, height);
  711.            case CID_UYVY:
  712.                return I420andYUVAtoUYVY_MMX (
  713.                    src1_ptr, src1_pels, src1_lines, src1_pitch, src1_startx, src1_starty,
  714.                    src2_ptr, src2_pels, src2_lines, src2_pitch, src2_startx, src2_starty,
  715.                    dest_ptr, dest_pels, dest_lines, dest_pitch, dest_startx, dest_starty,
  716.                    width, height);
  717.            default:
  718.                return -1;
  719.         }
  720.     }
  721. #endif
  722.     switch (color_format)
  723.     {
  724.        case CID_I420:
  725.        case CID_YV12:
  726.            return I420andYUVAtoI420orYV12 (
  727.                src1_ptr, src1_pels, src1_lines, src1_pitch, src1_startx, src1_starty,
  728.                src2_ptr, src2_pels, src2_lines, src2_pitch, src2_startx, src2_starty,
  729.                dest_ptr, dest_pels, dest_lines, dest_pitch, dest_startx, dest_starty,
  730.                width, height, color_format);
  731.        case CID_YUY2:
  732.            return I420andYUVAtoYUY2 (
  733.                src1_ptr, src1_pels, src1_lines, src1_pitch, src1_startx, src1_starty,
  734.                src2_ptr, src2_pels, src2_lines, src2_pitch, src2_startx, src2_starty,
  735.                dest_ptr, dest_pels, dest_lines, dest_pitch, dest_startx, dest_starty,
  736.                width, height);
  737.        case CID_UYVY:
  738.            return I420andYUVAtoUYVY (
  739.                src1_ptr, src1_pels, src1_lines, src1_pitch, src1_startx, src1_starty,
  740.                src2_ptr, src2_pels, src2_lines, src2_pitch, src2_startx, src2_starty,
  741.                dest_ptr, dest_pels, dest_lines, dest_pitch, dest_startx, dest_starty,
  742.                width, height);
  743.        default:
  744.            return -1;
  745.     }
  746.     
  747. }
  748. /////////////////////////////////////////////////////////////
  749. //
  750. // I420andI420toI420
  751. //
  752. // This function alpha-blends two I420 buffers into a third
  753. // I420 buffer using the constant alpha given in the params.
  754. //
  755. /////////////////////////////////////////////////////////////
  756. int HXEXPORT ENTRYPOINT(I420andI420toI420) (
  757.     unsigned char *src1_ptr, int src1_pels,   int src1_lines,  int src1_pitch,
  758.     int src1_startx, int src1_starty,
  759.     unsigned char *src2_ptr, int src2_pels,   int src2_lines,  int src2_pitch,
  760.     int src2_startx, int src2_starty,
  761.     unsigned char *dest_ptr, int dest_pels,   int dest_lines,  int dest_pitch,
  762.     int dest_startx, int dest_starty,
  763.     int width,  int height,  int alpha )
  764. {
  765.     int ALPHA_tab[511];
  766.     
  767.     int i, j, c;
  768.     unsigned char *s1, *s2, *d;
  769.     int s1_lineskip, s2_lineskip, d_lineskip;
  770. #ifdef _USE_MMX_BLENDERS
  771.     if( !z_bCheckedForMMX )
  772.     {
  773.         z_bMMXAvailable = (checkMmxAvailablity()&CPU_HAS_MMX)?1:0;
  774.         z_bCheckedForMMX = TRUE;
  775.     }
  776.     if( z_bMMXAvailable )
  777.     {
  778.         return I420andI420toI420_MMX_sub (
  779.             src1_ptr, src1_pels,   src1_lines,  src1_pitch,
  780.             src1_startx, src1_starty,
  781.             src2_ptr, src2_pels,   src2_lines,  src2_pitch,
  782.             src2_startx, src2_starty,
  783.             dest_ptr, dest_pels,   dest_lines,  dest_pitch,
  784.             dest_startx, dest_starty,
  785.             width,  height,  alpha );
  786.     }
  787. #endif
  788.     for (i = 0; i < 511; i++)
  789.     {
  790.         ALPHA_tab[i] = (i - 255) * alpha;
  791.     }
  792.     
  793.     for (c = 0; c < 3; c++)
  794.     {
  795.         switch (c)
  796.         {
  797.            case 0:
  798.                // Y
  799.                s1 = src1_ptr + src1_starty * src1_pitch + src1_startx;
  800.                s2 = src2_ptr + src2_starty * src2_pitch + src2_startx;
  801.                d  = dest_ptr + dest_starty * dest_pitch + dest_startx;
  802.                s1_lineskip = src1_pitch - width;
  803.                s2_lineskip = src2_pitch - width;
  804.                d_lineskip  = dest_pitch - width; 
  805.                break;
  806.            case 1:
  807.                // U
  808.                s1  = src1_ptr + src1_pitch * src1_lines;
  809.                s1 += (src1_starty * src1_pitch / 4) + src1_startx / 2;
  810.                s2  = src2_ptr + src2_pitch * src2_lines;
  811.                s2 += (src2_starty * src2_pitch / 4) + src2_startx / 2;
  812.                d   = dest_ptr + dest_pitch * dest_lines;
  813.                d  += (dest_starty * dest_pitch / 4) + dest_startx / 2;
  814.                s1_lineskip = (src1_pitch - width) / 2;
  815.                s2_lineskip = (src2_pitch - width) / 2;
  816.                d_lineskip  = (dest_pitch - width) / 2;
  817.                width >>= 1;
  818.                height >>= 1;
  819.                break;
  820.            case 2:
  821.                // V
  822.                s1  = src1_ptr + 5 * src1_pitch * src1_lines / 4;
  823.                s1 += (src1_starty * src1_pitch / 4) + src1_startx / 2;
  824.                s2  = src2_ptr + 5 * src2_pitch * src2_lines / 4;
  825.                s2 += (src2_starty * src2_pitch / 4) + src2_startx / 2;
  826.                d   = dest_ptr + 5 * dest_pitch * dest_lines / 4;
  827.                d  += (dest_starty * dest_pitch / 4) + dest_startx / 2;
  828.                break;
  829.         }
  830.         for (i = 0; i < height; i++)
  831.         {
  832.             for (j = 0; j < (width-3); j += 4)
  833.             {
  834.                 int x1, x2;
  835.                 x1 = *(s1 + 0);
  836.                 x2 = *(s2 + 0);
  837.                 x1 -= x2;
  838.                 x1 = *(ALPHA_tab + x1 + 255);
  839.                 x1 >>= 8;
  840.                 x1 += x2;
  841.                 *(d + 0) = (unsigned char)x1;
  842.                 x1 = *(s1 + 1);
  843.                 x2 = *(s2 + 1);
  844.                 x1 -= x2;
  845.                 x1 = *(ALPHA_tab + x1 + 255);
  846.                 x1 >>= 8;
  847.                 x1 += x2;
  848.                 *(d + 1) = (unsigned char)x1;
  849.                 x1 = *(s1 + 2);
  850.                 x2 = *(s2 + 2);
  851.                 x1 -= x2;
  852.                 x1 = *(ALPHA_tab + x1 + 255);
  853.                 x1 >>= 8;
  854.                 x1 += x2;
  855.                 *(d + 2) = (unsigned char)x1;
  856.                 x1 = *(s1 + 3);
  857.                 x2 = *(s2 + 3);
  858.                 x1 -= x2;
  859.                 x1 = *(ALPHA_tab + x1 + 255);
  860.                 x1 >>= 8;
  861.                 x1 += x2;
  862.                 *(d + 3) = (unsigned char)x1;
  863.                 s1 += 4;
  864.                 s2 += 4;
  865.                 d  += 4;
  866.             }
  867.             while (j < width)
  868.             {
  869.                 int x1, x2;
  870.                 x1 = *s1;
  871.                 x2 = *s2;
  872.                 x1 -= x2;
  873.                 x1 = *(ALPHA_tab + x1 + 255);
  874.                 x1 >>= 8;
  875.                 x1 += x2;
  876.                 *d++ = (unsigned char)x1;
  877.                 s1++;
  878.                 s2++;
  879.                 j++;
  880.             }
  881.             s1 += s1_lineskip;
  882.             s2 += s2_lineskip;
  883.             d  += d_lineskip;
  884.         }
  885.     }
  886.     return 0;
  887. }
  888. #if 0
  889. void main (void)
  890. {
  891. unsigned char *s1, *s2, *dst;
  892. int pels = 64;
  893. int lines = 32;
  894. int pitch = 64;
  895. s1  = malloc (lines*pitch*3/2);
  896. s2  = malloc (lines*pitch*5/2);
  897. dst = malloc (lines*pitch*3/2);
  898. memset (s1, 64, lines*pitch*3/2);
  899. memset (s2, 192, lines*pitch*3/2);
  900. memset (s2 + lines*pitch*3/2, 64, lines*pitch);
  901. I420andYUVAtoI420orYV12 (
  902. s1, pels, lines, pitch, pels, lines,
  903. s2, pels, lines, pitch, pels, lines,
  904. dst, pels, lines, pitch, pels, lines,
  905. pels, lines, CID_I420);
  906. free (s1);
  907. free (s2);
  908. free (dst);
  909. }
  910. #endif