SDL_blit_A.c
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:20k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. /*
  2.     SDL - Simple DirectMedia Layer
  3.     Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002  Sam Lantinga
  4.     This library is free software; you can redistribute it and/or
  5.     modify it under the terms of the GNU Library General Public
  6.     License as published by the Free Software Foundation; either
  7.     version 2 of the License, or (at your option) any later version.
  8.     This library is distributed in the hope that it will be useful,
  9.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  11.     Library General Public License for more details.
  12.     You should have received a copy of the GNU Library General Public
  13.     License along with this library; if not, write to the Free
  14.     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  15.     Sam Lantinga
  16.     slouken@libsdl.org
  17. */
  18. #ifdef SAVE_RCSID
  19. static char rcsid =
  20.  "@(#) $Id: SDL_blit_A.c,v 1.4 2002/04/22 21:38:03 wmay Exp $";
  21. #endif
  22. #include <stdio.h>
  23. #include "SDL_types.h"
  24. #include "SDL_video.h"
  25. #include "SDL_blit.h"
  26. /* Functions to perform alpha blended blitting */
  27. /* N->1 blending with per-surface alpha */
  28. static void BlitNto1SurfaceAlpha(SDL_BlitInfo *info)
  29. {
  30. int width = info->d_width;
  31. int height = info->d_height;
  32. Uint8 *src = info->s_pixels;
  33. int srcskip = info->s_skip;
  34. Uint8 *dst = info->d_pixels;
  35. int dstskip = info->d_skip;
  36. Uint8 *palmap = info->table;
  37. SDL_PixelFormat *srcfmt = info->src;
  38. SDL_PixelFormat *dstfmt = info->dst;
  39. int srcbpp = srcfmt->BytesPerPixel;
  40. const unsigned A = srcfmt->alpha;
  41. while ( height-- ) {
  42.     DUFFS_LOOP4(
  43.     {
  44. Uint32 pixel;
  45. unsigned sR;
  46. unsigned sG;
  47. unsigned sB;
  48. unsigned dR;
  49. unsigned dG;
  50. unsigned dB;
  51. DISEMBLE_RGB(src, srcbpp, srcfmt, pixel, sR, sG, sB);
  52. dR = dstfmt->palette->colors[*dst].r;
  53. dG = dstfmt->palette->colors[*dst].g;
  54. dB = dstfmt->palette->colors[*dst].b;
  55. ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB);
  56. dR &= 0xff;
  57. dG &= 0xff;
  58. dB &= 0xff;
  59. /* Pack RGB into 8bit pixel */
  60. if ( palmap == NULL ) {
  61.     *dst =((dR>>5)<<(3+2))|
  62.   ((dG>>5)<<(2))|
  63.   ((dB>>6)<<(0));
  64. } else {
  65.     *dst = palmap[((dR>>5)<<(3+2))|
  66.   ((dG>>5)<<(2))  |
  67.   ((dB>>6)<<(0))];
  68. }
  69. dst++;
  70. src += srcbpp;
  71.     },
  72.     width);
  73.     src += srcskip;
  74.     dst += dstskip;
  75. }
  76. }
  77. /* N->1 blending with pixel alpha */
  78. static void BlitNto1PixelAlpha(SDL_BlitInfo *info)
  79. {
  80. int width = info->d_width;
  81. int height = info->d_height;
  82. Uint8 *src = info->s_pixels;
  83. int srcskip = info->s_skip;
  84. Uint8 *dst = info->d_pixels;
  85. int dstskip = info->d_skip;
  86. Uint8 *palmap = info->table;
  87. SDL_PixelFormat *srcfmt = info->src;
  88. SDL_PixelFormat *dstfmt = info->dst;
  89. int srcbpp = srcfmt->BytesPerPixel;
  90. /* FIXME: fix alpha bit field expansion here too? */
  91. while ( height-- ) {
  92.     DUFFS_LOOP4(
  93.     {
  94. Uint32 pixel;
  95. unsigned sR;
  96. unsigned sG;
  97. unsigned sB;
  98. unsigned sA;
  99. unsigned dR;
  100. unsigned dG;
  101. unsigned dB;
  102. DISEMBLE_RGBA(src,srcbpp,srcfmt,pixel,sR,sG,sB,sA);
  103. dR = dstfmt->palette->colors[*dst].r;
  104. dG = dstfmt->palette->colors[*dst].g;
  105. dB = dstfmt->palette->colors[*dst].b;
  106. ALPHA_BLEND(sR, sG, sB, sA, dR, dG, dB);
  107. dR &= 0xff;
  108. dG &= 0xff;
  109. dB &= 0xff;
  110. /* Pack RGB into 8bit pixel */
  111. if ( palmap == NULL ) {
  112.     *dst =((dR>>5)<<(3+2))|
  113.   ((dG>>5)<<(2))|
  114.   ((dB>>6)<<(0));
  115. } else {
  116.     *dst = palmap[((dR>>5)<<(3+2))|
  117.   ((dG>>5)<<(2))  |
  118.   ((dB>>6)<<(0))  ];
  119. }
  120. dst++;
  121. src += srcbpp;
  122.     },
  123.     width);
  124.     src += srcskip;
  125.     dst += dstskip;
  126. }
  127. }
  128. /* colorkeyed N->1 blending with per-surface alpha */
  129. static void BlitNto1SurfaceAlphaKey(SDL_BlitInfo *info)
  130. {
  131. int width = info->d_width;
  132. int height = info->d_height;
  133. Uint8 *src = info->s_pixels;
  134. int srcskip = info->s_skip;
  135. Uint8 *dst = info->d_pixels;
  136. int dstskip = info->d_skip;
  137. Uint8 *palmap = info->table;
  138. SDL_PixelFormat *srcfmt = info->src;
  139. SDL_PixelFormat *dstfmt = info->dst;
  140. int srcbpp = srcfmt->BytesPerPixel;
  141. Uint32 ckey = srcfmt->colorkey;
  142. const int A = srcfmt->alpha;
  143. while ( height-- ) {
  144.     DUFFS_LOOP(
  145.     {
  146. Uint32 pixel;
  147. unsigned sR;
  148. unsigned sG;
  149. unsigned sB;
  150. unsigned dR;
  151. unsigned dG;
  152. unsigned dB;
  153. DISEMBLE_RGB(src, srcbpp, srcfmt, pixel, sR, sG, sB);
  154. if ( pixel != ckey ) {
  155.     dR = dstfmt->palette->colors[*dst].r;
  156.     dG = dstfmt->palette->colors[*dst].g;
  157.     dB = dstfmt->palette->colors[*dst].b;
  158.     ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB);
  159.     dR &= 0xff;
  160.     dG &= 0xff;
  161.     dB &= 0xff;
  162.     /* Pack RGB into 8bit pixel */
  163.     if ( palmap == NULL ) {
  164. *dst =((dR>>5)<<(3+2))|
  165.       ((dG>>5)<<(2)) |
  166.       ((dB>>6)<<(0));
  167.     } else {
  168. *dst = palmap[((dR>>5)<<(3+2))|
  169.       ((dG>>5)<<(2))  |
  170.       ((dB>>6)<<(0))  ];
  171.     }
  172. }
  173. dst++;
  174. src += srcbpp;
  175.     },
  176.     width);
  177.     src += srcskip;
  178.     dst += dstskip;
  179. }
  180. }
  181. /* fast RGB888->(A)RGB888 blending with surface alpha=128 special case */
  182. static void BlitRGBtoRGBSurfaceAlpha128(SDL_BlitInfo *info)
  183. {
  184. int width = info->d_width;
  185. int height = info->d_height;
  186. Uint32 *srcp = (Uint32 *)info->s_pixels;
  187. int srcskip = info->s_skip >> 2;
  188. Uint32 *dstp = (Uint32 *)info->d_pixels;
  189. int dstskip = info->d_skip >> 2;
  190. while(height--) {
  191.     DUFFS_LOOP4({
  192.     Uint32 s = *srcp++;
  193.     Uint32 d = *dstp;
  194.     *dstp++ = ((((s & 0x00fefefe) + (d & 0x00fefefe)) >> 1)
  195.        + (s & d & 0x00010101)) | 0xff000000;
  196.     }, width);
  197.     srcp += srcskip;
  198.     dstp += dstskip;
  199. }
  200. }
  201. /* fast RGB888->(A)RGB888 blending with surface alpha */
  202. static void BlitRGBtoRGBSurfaceAlpha(SDL_BlitInfo *info)
  203. {
  204. unsigned alpha = info->src->alpha;
  205. if(alpha == 128) {
  206. BlitRGBtoRGBSurfaceAlpha128(info);
  207. } else {
  208. int width = info->d_width;
  209. int height = info->d_height;
  210. Uint32 *srcp = (Uint32 *)info->s_pixels;
  211. int srcskip = info->s_skip >> 2;
  212. Uint32 *dstp = (Uint32 *)info->d_pixels;
  213. int dstskip = info->d_skip >> 2;
  214. while(height--) {
  215. DUFFS_LOOP4({
  216. Uint32 s;
  217. Uint32 d;
  218. Uint32 s1;
  219. Uint32 d1;
  220. s = *srcp;
  221. d = *dstp;
  222. s1 = s & 0xff00ff;
  223. d1 = d & 0xff00ff;
  224. d1 = (d1 + ((s1 - d1) * alpha >> 8))
  225.      & 0xff00ff;
  226. s &= 0xff00;
  227. d &= 0xff00;
  228. d = (d + ((s - d) * alpha >> 8)) & 0xff00;
  229. *dstp = d1 | d | 0xff000000;
  230. ++srcp;
  231. ++dstp;
  232. }, width);
  233. srcp += srcskip;
  234. dstp += dstskip;
  235. }
  236. }
  237. }
  238. /* fast ARGB888->(A)RGB888 blending with pixel alpha */
  239. static void BlitRGBtoRGBPixelAlpha(SDL_BlitInfo *info)
  240. {
  241. int width = info->d_width;
  242. int height = info->d_height;
  243. Uint32 *srcp = (Uint32 *)info->s_pixels;
  244. int srcskip = info->s_skip >> 2;
  245. Uint32 *dstp = (Uint32 *)info->d_pixels;
  246. int dstskip = info->d_skip >> 2;
  247. while(height--) {
  248.     DUFFS_LOOP4({
  249. Uint32 dalpha;
  250. Uint32 d;
  251. Uint32 s1;
  252. Uint32 d1;
  253. Uint32 s = *srcp;
  254. Uint32 alpha = s >> 24;
  255. /* FIXME: Here we special-case opaque alpha since the
  256.    compositioning used (>>8 instead of /255) doesn't handle
  257.    it correctly. Also special-case alpha=0 for speed?
  258.    Benchmark this! */
  259. if(alpha == SDL_ALPHA_OPAQUE) {
  260.     *dstp = (s & 0x00ffffff) | (*dstp & 0xff000000);
  261. } else {
  262.     /*
  263.      * take out the middle component (green), and process
  264.      * the other two in parallel. One multiply less.
  265.      */
  266.     d = *dstp;
  267.     dalpha = d & 0xff000000;
  268.     s1 = s & 0xff00ff;
  269.     d1 = d & 0xff00ff;
  270.     d1 = (d1 + ((s1 - d1) * alpha >> 8)) & 0xff00ff;
  271.     s &= 0xff00;
  272.     d &= 0xff00;
  273.     d = (d + ((s - d) * alpha >> 8)) & 0xff00;
  274.     *dstp = d1 | d | dalpha;
  275. }
  276. ++srcp;
  277. ++dstp;
  278.     }, width);
  279.     srcp += srcskip;
  280.     dstp += dstskip;
  281. }
  282. }
  283. /* 16bpp special case for per-surface alpha=50%: blend 2 pixels in parallel */
  284. /* blend a single 16 bit pixel at 50% */
  285. #define BLEND16_50(d, s, mask)
  286. ((((s & mask) + (d & mask)) >> 1) + (s & d & (~mask & 0xffff)))
  287. /* blend two 16 bit pixels at 50% */
  288. #define BLEND2x16_50(d, s, mask)      
  289. (((s & (mask | mask << 16)) >> 1) + ((d & (mask | mask << 16)) >> 1) 
  290.  + (s & d & (~(mask | mask << 16))))
  291. static void Blit16to16SurfaceAlpha128(SDL_BlitInfo *info, Uint16 mask)
  292. {
  293. int width = info->d_width;
  294. int height = info->d_height;
  295. Uint16 *srcp = (Uint16 *)info->s_pixels;
  296. int srcskip = info->s_skip >> 1;
  297. Uint16 *dstp = (Uint16 *)info->d_pixels;
  298. int dstskip = info->d_skip >> 1;
  299. while(height--) {
  300. if(((unsigned long)srcp ^ (unsigned long)dstp) & 2) {
  301. /*
  302.  * Source and destination not aligned, pipeline it.
  303.  * This is mostly a win for big blits but no loss for
  304.  * small ones
  305.  */
  306. Uint32 prev_sw;
  307. int w = width;
  308. /* handle odd destination */
  309. if((unsigned long)dstp & 2) {
  310. Uint16 d = *dstp, s = *srcp;
  311. *dstp = BLEND16_50(d, s, mask);
  312. dstp++;
  313. srcp++;
  314. w--;
  315. }
  316. srcp++; /* srcp is now 32-bit aligned */
  317. /* bootstrap pipeline with first halfword */
  318. prev_sw = ((Uint32 *)srcp)[-1];
  319. while(w > 1) {
  320. Uint32 sw, dw, s;
  321. sw = *(Uint32 *)srcp;
  322. dw = *(Uint32 *)dstp;
  323. if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
  324. s = (prev_sw << 16) + (sw >> 16);
  325. else
  326. s = (prev_sw >> 16) + (sw << 16);
  327. prev_sw = sw;
  328. *(Uint32 *)dstp = BLEND2x16_50(dw, s, mask);
  329. dstp += 2;
  330. srcp += 2;
  331. w -= 2;
  332. }
  333. /* final pixel if any */
  334. if(w) {
  335. Uint16 d = *dstp, s;
  336. if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
  337. s = prev_sw;
  338. else
  339. s = prev_sw >> 16;
  340. *dstp = BLEND16_50(d, s, mask);
  341. srcp++;
  342. dstp++;
  343. }
  344. srcp += srcskip - 1;
  345. dstp += dstskip;
  346. } else {
  347. /* source and destination are aligned */
  348. int w = width;
  349. /* first odd pixel? */
  350. if((unsigned long)srcp & 2) {
  351. Uint16 d = *dstp, s = *srcp;
  352. *dstp = BLEND16_50(d, s, mask);
  353. srcp++;
  354. dstp++;
  355. w--;
  356. }
  357. /* srcp and dstp are now 32-bit aligned */
  358. while(w > 1) {
  359. Uint32 sw = *(Uint32 *)srcp;
  360. Uint32 dw = *(Uint32 *)dstp;
  361. *(Uint32 *)dstp = BLEND2x16_50(dw, sw, mask);
  362. srcp += 2;
  363. dstp += 2;
  364. w -= 2;
  365. }
  366. /* last odd pixel? */
  367. if(w) {
  368. Uint16 d = *dstp, s = *srcp;
  369. *dstp = BLEND16_50(d, s, mask);
  370. srcp++;
  371. dstp++;
  372. }
  373. srcp += srcskip;
  374. dstp += dstskip;
  375. }
  376. }
  377. }
  378. /* fast RGB565->RGB565 blending with surface alpha */
  379. static void Blit565to565SurfaceAlpha(SDL_BlitInfo *info)
  380. {
  381. unsigned alpha = info->src->alpha;
  382. if(alpha == 128) {
  383. Blit16to16SurfaceAlpha128(info, 0xf7de);
  384. } else {
  385. int width = info->d_width;
  386. int height = info->d_height;
  387. Uint16 *srcp = (Uint16 *)info->s_pixels;
  388. int srcskip = info->s_skip >> 1;
  389. Uint16 *dstp = (Uint16 *)info->d_pixels;
  390. int dstskip = info->d_skip >> 1;
  391. alpha >>= 3; /* downscale alpha to 5 bits */
  392. while(height--) {
  393. DUFFS_LOOP4({
  394. Uint32 s = *srcp++;
  395. Uint32 d = *dstp;
  396. /*
  397.  * shift out the middle component (green) to
  398.  * the high 16 bits, and process all three RGB
  399.  * components at the same time.
  400.  */
  401. s = (s | s << 16) & 0x07e0f81f;
  402. d = (d | d << 16) & 0x07e0f81f;
  403. d += (s - d) * alpha >> 5;
  404. d &= 0x07e0f81f;
  405. *dstp++ = d | d >> 16;
  406. }, width);
  407. srcp += srcskip;
  408. dstp += dstskip;
  409. }
  410. }
  411. }
  412. /* fast RGB555->RGB555 blending with surface alpha */
  413. static void Blit555to555SurfaceAlpha(SDL_BlitInfo *info)
  414. {
  415. unsigned alpha = info->src->alpha; /* downscale alpha to 5 bits */
  416. if(alpha == 128) {
  417. Blit16to16SurfaceAlpha128(info, 0xfbde);
  418. } else {
  419. int width = info->d_width;
  420. int height = info->d_height;
  421. Uint16 *srcp = (Uint16 *)info->s_pixels;
  422. int srcskip = info->s_skip >> 1;
  423. Uint16 *dstp = (Uint16 *)info->d_pixels;
  424. int dstskip = info->d_skip >> 1;
  425. alpha >>= 3; /* downscale alpha to 5 bits */
  426. while(height--) {
  427. DUFFS_LOOP4({
  428. Uint32 s = *srcp++;
  429. Uint32 d = *dstp;
  430. /*
  431.  * shift out the middle component (green) to
  432.  * the high 16 bits, and process all three RGB
  433.  * components at the same time.
  434.  */
  435. s = (s | s << 16) & 0x03e07c1f;
  436. d = (d | d << 16) & 0x03e07c1f;
  437. d += (s - d) * alpha >> 5;
  438. d &= 0x03e07c1f;
  439. *dstp++ = d | d >> 16;
  440. }, width);
  441. srcp += srcskip;
  442. dstp += dstskip;
  443. }
  444. }
  445. }
  446. /* fast ARGB8888->RGB565 blending with pixel alpha */
  447. static void BlitARGBto565PixelAlpha(SDL_BlitInfo *info)
  448. {
  449. int width = info->d_width;
  450. int height = info->d_height;
  451. Uint32 *srcp = (Uint32 *)info->s_pixels;
  452. int srcskip = info->s_skip >> 2;
  453. Uint16 *dstp = (Uint16 *)info->d_pixels;
  454. int dstskip = info->d_skip >> 1;
  455. while(height--) {
  456.     DUFFS_LOOP4({
  457. Uint32 s = *srcp;
  458. unsigned alpha = s >> 27; /* downscale alpha to 5 bits */
  459. /* FIXME: Here we special-case opaque alpha since the
  460.    compositioning used (>>8 instead of /255) doesn't handle
  461.    it correctly. Also special-case alpha=0 for speed?
  462.    Benchmark this! */
  463. if(alpha == (SDL_ALPHA_OPAQUE >> 3)) {
  464.     *dstp = (s >> 8 & 0xf800) + (s >> 5 & 0x7e0)
  465.   + (s >> 3  & 0x1f);
  466. } else {
  467.     Uint32 d = *dstp;
  468.     /*
  469.      * convert source and destination to G0RAB65565
  470.      * and blend all components at the same time
  471.      */
  472.     s = ((s & 0xfc00) << 11) + (s >> 8 & 0xf800)
  473.       + (s >> 3 & 0x1f);
  474.     d = (d | d << 16) & 0x07e0f81f;
  475.     d += (s - d) * alpha >> 5;
  476.     d &= 0x07e0f81f;
  477.     *dstp = d | d >> 16;
  478. }
  479. srcp++;
  480. dstp++;
  481.     }, width);
  482.     srcp += srcskip;
  483.     dstp += dstskip;
  484. }
  485. }
  486. /* fast ARGB8888->RGB555 blending with pixel alpha */
  487. static void BlitARGBto555PixelAlpha(SDL_BlitInfo *info)
  488. {
  489. int width = info->d_width;
  490. int height = info->d_height;
  491. Uint32 *srcp = (Uint32 *)info->s_pixels;
  492. int srcskip = info->s_skip >> 2;
  493. Uint16 *dstp = (Uint16 *)info->d_pixels;
  494. int dstskip = info->d_skip >> 1;
  495. while(height--) {
  496.     DUFFS_LOOP4({
  497. unsigned alpha;
  498. Uint32 s = *srcp;
  499. alpha = s >> 27; /* downscale alpha to 5 bits */
  500. /* FIXME: Here we special-case opaque alpha since the
  501.    compositioning used (>>8 instead of /255) doesn't handle
  502.    it correctly. Also special-case alpha=0 for speed?
  503.    Benchmark this! */
  504. if(alpha == (SDL_ALPHA_OPAQUE >> 3)) {
  505.     *dstp = (s >> 9 & 0x7c00) + (s >> 6 & 0x3e0)
  506.   + (s >> 3  & 0x1f);
  507. } else {
  508.     Uint32 d = *dstp;
  509.     /*
  510.      * convert source and destination to G0RAB65565
  511.      * and blend all components at the same time
  512.      */
  513.     s = ((s & 0xf800) << 10) + (s >> 9 & 0x7c00)
  514.       + (s >> 3 & 0x1f);
  515.     d = (d | d << 16) & 0x03e07c1f;
  516.     d += (s - d) * alpha >> 5;
  517.     d &= 0x03e07c1f;
  518.     *dstp = d | d >> 16;
  519. }
  520. srcp++;
  521. dstp++;
  522.     }, width);
  523.     srcp += srcskip;
  524.     dstp += dstskip;
  525. }
  526. }
  527. /* General (slow) N->N blending with per-surface alpha */
  528. static void BlitNtoNSurfaceAlpha(SDL_BlitInfo *info)
  529. {
  530. int width = info->d_width;
  531. int height = info->d_height;
  532. Uint8 *src = info->s_pixels;
  533. int srcskip = info->s_skip;
  534. Uint8 *dst = info->d_pixels;
  535. int dstskip = info->d_skip;
  536. SDL_PixelFormat *srcfmt = info->src;
  537. SDL_PixelFormat *dstfmt = info->dst;
  538. int srcbpp = srcfmt->BytesPerPixel;
  539. int dstbpp = dstfmt->BytesPerPixel;
  540. unsigned sA = srcfmt->alpha;
  541. unsigned dA = dstfmt->Amask ? SDL_ALPHA_OPAQUE : 0;
  542. while ( height-- ) {
  543.     DUFFS_LOOP4(
  544.     {
  545. Uint32 pixel;
  546. unsigned sR;
  547. unsigned sG;
  548. unsigned sB;
  549. unsigned dR;
  550. unsigned dG;
  551. unsigned dB;
  552. DISEMBLE_RGB(src, srcbpp, srcfmt, pixel, sR, sG, sB);
  553. DISEMBLE_RGB(dst, dstbpp, dstfmt, pixel, dR, dG, dB);
  554. ALPHA_BLEND(sR, sG, sB, sA, dR, dG, dB);
  555. ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA);
  556. src += srcbpp;
  557. dst += dstbpp;
  558.     },
  559.     width);
  560.     src += srcskip;
  561.     dst += dstskip;
  562. }
  563. }
  564. /* General (slow) colorkeyed N->N blending with per-surface alpha */
  565. static void BlitNtoNSurfaceAlphaKey(SDL_BlitInfo *info)
  566. {
  567. int width = info->d_width;
  568. int height = info->d_height;
  569. Uint8 *src = info->s_pixels;
  570. int srcskip = info->s_skip;
  571. Uint8 *dst = info->d_pixels;
  572. int dstskip = info->d_skip;
  573. SDL_PixelFormat *srcfmt = info->src;
  574. SDL_PixelFormat *dstfmt = info->dst;
  575. Uint32 ckey = srcfmt->colorkey;
  576. int srcbpp = srcfmt->BytesPerPixel;
  577. int dstbpp = dstfmt->BytesPerPixel;
  578. unsigned sA = srcfmt->alpha;
  579. unsigned dA = dstfmt->Amask ? SDL_ALPHA_OPAQUE : 0;
  580. while ( height-- ) {
  581.     DUFFS_LOOP4(
  582.     {
  583. Uint32 pixel;
  584. unsigned sR;
  585. unsigned sG;
  586. unsigned sB;
  587. unsigned dR;
  588. unsigned dG;
  589. unsigned dB;
  590. RETRIEVE_RGB_PIXEL(src, srcbpp, pixel);
  591. if(pixel != ckey) {
  592.     RGB_FROM_PIXEL(pixel, srcfmt, sR, sG, sB);
  593.     DISEMBLE_RGB(dst, dstbpp, dstfmt, pixel, dR, dG, dB);
  594.     ALPHA_BLEND(sR, sG, sB, sA, dR, dG, dB);
  595.     ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA);
  596. }
  597. src += srcbpp;
  598. dst += dstbpp;
  599.     },
  600.     width);
  601.     src += srcskip;
  602.     dst += dstskip;
  603. }
  604. }
  605. /* General (slow) N->N blending with pixel alpha */
  606. static void BlitNtoNPixelAlpha(SDL_BlitInfo *info)
  607. {
  608. int width = info->d_width;
  609. int height = info->d_height;
  610. Uint8 *src = info->s_pixels;
  611. int srcskip = info->s_skip;
  612. Uint8 *dst = info->d_pixels;
  613. int dstskip = info->d_skip;
  614. SDL_PixelFormat *srcfmt = info->src;
  615. SDL_PixelFormat *dstfmt = info->dst;
  616. int  srcbpp;
  617. int  dstbpp;
  618. /* Set up some basic variables */
  619. srcbpp = srcfmt->BytesPerPixel;
  620. dstbpp = dstfmt->BytesPerPixel;
  621. /* FIXME: for 8bpp source alpha, this doesn't get opaque values
  622.    quite right. for <8bpp source alpha, it gets them very wrong
  623.    (check all macros!)
  624.    It is unclear whether there is a good general solution that doesn't
  625.    need a branch (or a divide). */
  626. while ( height-- ) {
  627.     DUFFS_LOOP4(
  628.     {
  629. Uint32 pixel;
  630. unsigned sR;
  631. unsigned sG;
  632. unsigned sB;
  633. unsigned dR;
  634. unsigned dG;
  635. unsigned dB;
  636. unsigned sA;
  637. unsigned dA;
  638. DISEMBLE_RGBA(src, srcbpp, srcfmt, pixel, sR, sG, sB, sA);
  639. DISEMBLE_RGBA(dst, dstbpp, dstfmt, pixel, dR, dG, dB, dA);
  640. ALPHA_BLEND(sR, sG, sB, sA, dR, dG, dB);
  641. ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA);
  642. src += srcbpp;
  643. dst += dstbpp;
  644.     },
  645.     width);
  646.     src += srcskip;
  647.     dst += dstskip;
  648. }
  649. }
  650. SDL_loblit SDL_CalculateAlphaBlit(SDL_Surface *surface, int blit_index)
  651. {
  652.     SDL_PixelFormat *sf = surface->format;
  653.     SDL_PixelFormat *df = surface->map->dst->format;
  654.     if(sf->Amask == 0) {
  655. if((surface->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY) {
  656.     if(df->BytesPerPixel == 1)
  657. return BlitNto1SurfaceAlphaKey;
  658.     else
  659. return BlitNtoNSurfaceAlphaKey;
  660. } else {
  661.     /* Per-surface alpha blits */
  662.     switch(df->BytesPerPixel) {
  663.     case 1:
  664. return BlitNto1SurfaceAlpha;
  665.     case 2:
  666. if(surface->map->identity) {
  667.     if(df->Gmask == 0x7e0)
  668. return Blit565to565SurfaceAlpha;
  669.     else if(df->Gmask == 0x3e0)
  670. return Blit555to555SurfaceAlpha;
  671. }
  672. return BlitNtoNSurfaceAlpha;
  673.     case 4:
  674. if(sf->Rmask == df->Rmask
  675.    && sf->Gmask == df->Gmask
  676.    && sf->Bmask == df->Bmask
  677.    && (sf->Rmask | sf->Gmask | sf->Bmask) == 0xffffff
  678.    && sf->BytesPerPixel == 4)
  679.     return BlitRGBtoRGBSurfaceAlpha;
  680. else
  681.     return BlitNtoNSurfaceAlpha;
  682.     case 3:
  683.     default:
  684. return BlitNtoNSurfaceAlpha;
  685.     }
  686. }
  687.     } else {
  688. /* Per-pixel alpha blits */
  689. switch(df->BytesPerPixel) {
  690. case 1:
  691.     return BlitNto1PixelAlpha;
  692. case 2:
  693.     if(sf->BytesPerPixel == 4 && sf->Amask == 0xff000000
  694.        && sf->Gmask == 0xff00
  695.        && ((sf->Rmask == 0xff && df->Rmask == 0x1f)
  696.    || (sf->Bmask == 0xff && df->Bmask == 0x1f))) {
  697. if(df->Gmask == 0x7e0)
  698.     return BlitARGBto565PixelAlpha;
  699. else if(df->Gmask == 0x3e0)
  700.     return BlitARGBto555PixelAlpha;
  701.     }
  702.     return BlitNtoNPixelAlpha;
  703. case 4:
  704.     if(sf->Amask == 0xff000000
  705.        && sf->Rmask == df->Rmask
  706.        && sf->Gmask == df->Gmask
  707.        && sf->Bmask == df->Bmask
  708.        && sf->BytesPerPixel == 4)
  709. return BlitRGBtoRGBPixelAlpha;
  710.     return BlitNtoNPixelAlpha;
  711. case 3:
  712. default:
  713.     return BlitNtoNPixelAlpha;
  714. }
  715.     }
  716. }