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

流媒体/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_1.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. #include "SDL_sysvideo.h"
  27. #include "SDL_endian.h"
  28. /* Functions to blit from 8-bit surfaces to other surfaces */
  29. static void Blit1to1(SDL_BlitInfo *info)
  30. {
  31. #ifndef USE_DUFFS_LOOP
  32. int c;
  33. #endif
  34. int width, height;
  35. Uint8 *src, *map, *dst;
  36. int srcskip, dstskip;
  37. /* Set up some basic variables */
  38. width = info->d_width;
  39. height = info->d_height;
  40. src = info->s_pixels;
  41. srcskip = info->s_skip;
  42. dst = info->d_pixels;
  43. dstskip = info->d_skip;
  44. map = info->table;
  45. while ( height-- ) {
  46. #ifdef USE_DUFFS_LOOP
  47. DUFFS_LOOP(
  48. {
  49.   *dst = map[*src];
  50. }
  51. dst++;
  52. src++;
  53. , width);
  54. #else
  55. for ( c=width; c; --c ) {
  56.         *dst = map[*src];
  57. dst++;
  58. src++;
  59. }
  60. #endif
  61. src += srcskip;
  62. dst += dstskip;
  63. }
  64. }
  65. /* This is now endian dependent */
  66. #if ( SDL_BYTEORDER == SDL_LIL_ENDIAN )
  67. #define HI 1
  68. #define LO 0
  69. #else /* ( SDL_BYTEORDER == SDL_BIG_ENDIAN ) */
  70. #define HI 0
  71. #define LO 1
  72. #endif
  73. static void Blit1to2(SDL_BlitInfo *info)
  74. {
  75. #ifndef USE_DUFFS_LOOP
  76. int c;
  77. #endif
  78. int width, height;
  79. Uint8 *src, *dst;
  80. Uint16 *map;
  81. int srcskip, dstskip;
  82. /* Set up some basic variables */
  83. width = info->d_width;
  84. height = info->d_height;
  85. src = info->s_pixels;
  86. srcskip = info->s_skip;
  87. dst = info->d_pixels;
  88. dstskip = info->d_skip;
  89. map = (Uint16 *)info->table;
  90. #ifdef USE_DUFFS_LOOP
  91. while ( height-- ) {
  92. DUFFS_LOOP(
  93. {
  94. *(Uint16 *)dst = map[*src++];
  95. dst += 2;
  96. },
  97. width);
  98. src += srcskip;
  99. dst += dstskip;
  100. }
  101. #else
  102. /* Memory align at 4-byte boundary, if necessary */
  103. if ( (long)dst & 0x03 ) {
  104. /* Don't do anything if width is 0 */
  105. if ( width == 0 ) {
  106. return;
  107. }
  108. --width;
  109. while ( height-- ) {
  110. /* Perform copy alignment */
  111. *(Uint16 *)dst = map[*src++];
  112. dst += 2;
  113. /* Copy in 4 pixel chunks */
  114. for ( c=width/4; c; --c ) {
  115. *(Uint32 *)dst =
  116. (map[src[HI]]<<16)|(map[src[LO]]);
  117. src += 2;
  118. dst += 4;
  119. *(Uint32 *)dst =
  120. (map[src[HI]]<<16)|(map[src[LO]]);
  121. src += 2;
  122. dst += 4;
  123. }
  124. /* Get any leftovers */
  125. switch (width & 3) {
  126. case 3:
  127. *(Uint16 *)dst = map[*src++];
  128. dst += 2;
  129. case 2:
  130. *(Uint32 *)dst =
  131.   (map[src[HI]]<<16)|(map[src[LO]]);
  132. src += 2;
  133. dst += 4;
  134. break;
  135. case 1:
  136. *(Uint16 *)dst = map[*src++];
  137. dst += 2;
  138. break;
  139. }
  140. src += srcskip;
  141. dst += dstskip;
  142. }
  143. } else { 
  144. while ( height-- ) {
  145. /* Copy in 4 pixel chunks */
  146. for ( c=width/4; c; --c ) {
  147. *(Uint32 *)dst =
  148. (map[src[HI]]<<16)|(map[src[LO]]);
  149. src += 2;
  150. dst += 4;
  151. *(Uint32 *)dst =
  152. (map[src[HI]]<<16)|(map[src[LO]]);
  153. src += 2;
  154. dst += 4;
  155. }
  156. /* Get any leftovers */
  157. switch (width & 3) {
  158. case 3:
  159. *(Uint16 *)dst = map[*src++];
  160. dst += 2;
  161. case 2:
  162. *(Uint32 *)dst =
  163.   (map[src[HI]]<<16)|(map[src[LO]]);
  164. src += 2;
  165. dst += 4;
  166. break;
  167. case 1:
  168. *(Uint16 *)dst = map[*src++];
  169. dst += 2;
  170. break;
  171. }
  172. src += srcskip;
  173. dst += dstskip;
  174. }
  175. }
  176. #endif /* USE_DUFFS_LOOP */
  177. }
  178. static void Blit1to3(SDL_BlitInfo *info)
  179. {
  180. #ifndef USE_DUFFS_LOOP
  181. int c;
  182. #endif
  183. int o;
  184. int width, height;
  185. Uint8 *src, *map, *dst;
  186. int srcskip, dstskip;
  187. /* Set up some basic variables */
  188. width = info->d_width;
  189. height = info->d_height;
  190. src = info->s_pixels;
  191. srcskip = info->s_skip;
  192. dst = info->d_pixels;
  193. dstskip = info->d_skip;
  194. map = info->table;
  195. while ( height-- ) {
  196. #ifdef USE_DUFFS_LOOP
  197. DUFFS_LOOP(
  198. {
  199. o = *src * 4;
  200. dst[0] = map[o++];
  201. dst[1] = map[o++];
  202. dst[2] = map[o++];
  203. }
  204. src++;
  205. dst += 3;
  206. , width);
  207. #else
  208. for ( c=width; c; --c ) {
  209. o = *src * 4;
  210. dst[0] = map[o++];
  211. dst[1] = map[o++];
  212. dst[2] = map[o++];
  213. src++;
  214. dst += 3;
  215. }
  216. #endif /* USE_DUFFS_LOOP */
  217. src += srcskip;
  218. dst += dstskip;
  219. }
  220. }
  221. static void Blit1to4(SDL_BlitInfo *info)
  222. {
  223. #ifndef USE_DUFFS_LOOP
  224. int c;
  225. #endif
  226. int width, height;
  227. Uint8 *src;
  228. Uint32 *map, *dst;
  229. int srcskip, dstskip;
  230. /* Set up some basic variables */
  231. width = info->d_width;
  232. height = info->d_height;
  233. src = info->s_pixels;
  234. srcskip = info->s_skip;
  235. dst = (Uint32 *)info->d_pixels;
  236. dstskip = info->d_skip/4;
  237. map = (Uint32 *)info->table;
  238. while ( height-- ) {
  239. #ifdef USE_DUFFS_LOOP
  240. DUFFS_LOOP(
  241. *dst++ = map[*src++];
  242. , width);
  243. #else
  244. for ( c=width/4; c; --c ) {
  245. *dst++ = map[*src++];
  246. *dst++ = map[*src++];
  247. *dst++ = map[*src++];
  248. *dst++ = map[*src++];
  249. }
  250. switch ( width & 3 ) {
  251. case 3:
  252. *dst++ = map[*src++];
  253. case 2:
  254. *dst++ = map[*src++];
  255. case 1:
  256. *dst++ = map[*src++];
  257. }
  258. #endif /* USE_DUFFS_LOOP */
  259. src += srcskip;
  260. dst += dstskip;
  261. }
  262. }
  263. static void Blit1to1Key(SDL_BlitInfo *info)
  264. {
  265. int width = info->d_width;
  266. int height = info->d_height;
  267. Uint8 *src = info->s_pixels;
  268. int srcskip = info->s_skip;
  269. Uint8 *dst = info->d_pixels;
  270. int dstskip = info->d_skip;
  271. Uint8 *palmap = info->table;
  272. Uint32 ckey = info->src->colorkey;
  273.         
  274. if ( palmap ) {
  275. while ( height-- ) {
  276. DUFFS_LOOP(
  277. {
  278. if ( *src != ckey ) {
  279.   *dst = palmap[*src];
  280. }
  281. dst++;
  282. src++;
  283. },
  284. width);
  285. src += srcskip;
  286. dst += dstskip;
  287. }
  288. } else {
  289. while ( height-- ) {
  290. DUFFS_LOOP(
  291. {
  292. if ( *src != ckey ) {
  293.   *dst = *src;
  294. }
  295. dst++;
  296. src++;
  297. },
  298. width);
  299. src += srcskip;
  300. dst += dstskip;
  301. }
  302. }
  303. }
  304. static void Blit1to2Key(SDL_BlitInfo *info)
  305. {
  306. int width = info->d_width;
  307. int height = info->d_height;
  308. Uint8 *src = info->s_pixels;
  309. int srcskip = info->s_skip;
  310. Uint16 *dstp = (Uint16 *)info->d_pixels;
  311. int dstskip = info->d_skip;
  312. Uint16 *palmap = (Uint16 *)info->table;
  313. Uint32 ckey = info->src->colorkey;
  314. /* Set up some basic variables */
  315. dstskip /= 2;
  316. while ( height-- ) {
  317. DUFFS_LOOP(
  318. {
  319. if ( *src != ckey ) {
  320. *dstp=palmap[*src];
  321. }
  322. src++;
  323. dstp++;
  324. },
  325. width);
  326. src += srcskip;
  327. dstp += dstskip;
  328. }
  329. }
  330. static void Blit1to3Key(SDL_BlitInfo *info)
  331. {
  332. int width = info->d_width;
  333. int height = info->d_height;
  334. Uint8 *src = info->s_pixels;
  335. int srcskip = info->s_skip;
  336. Uint8 *dst = info->d_pixels;
  337. int dstskip = info->d_skip;
  338. Uint8 *palmap = info->table;
  339. Uint32 ckey = info->src->colorkey;
  340. int o;
  341. while ( height-- ) {
  342. DUFFS_LOOP(
  343. {
  344. if ( *src != ckey ) {
  345. o = *src * 4;
  346. dst[0] = palmap[o++];
  347. dst[1] = palmap[o++];
  348. dst[2] = palmap[o++];
  349. }
  350. src++;
  351. dst += 3;
  352. },
  353. width);
  354. src += srcskip;
  355. dst += dstskip;
  356. }
  357. }
  358. static void Blit1to4Key(SDL_BlitInfo *info)
  359. {
  360. int width = info->d_width;
  361. int height = info->d_height;
  362. Uint8 *src = info->s_pixels;
  363. int srcskip = info->s_skip;
  364. Uint32 *dstp = (Uint32 *)info->d_pixels;
  365. int dstskip = info->d_skip;
  366. Uint32 *palmap = (Uint32 *)info->table;
  367. Uint32 ckey = info->src->colorkey;
  368. /* Set up some basic variables */
  369. dstskip /= 4;
  370. while ( height-- ) {
  371. DUFFS_LOOP(
  372. {
  373. if ( *src != ckey ) {
  374. *dstp = palmap[*src];
  375. }
  376. src++;
  377. dstp++;
  378. },
  379. width);
  380. src += srcskip;
  381. dstp += dstskip;
  382. }
  383. }
  384. static void Blit1toNAlpha(SDL_BlitInfo *info)
  385. {
  386. int width = info->d_width;
  387. int height = info->d_height;
  388. Uint8 *src = info->s_pixels;
  389. int srcskip = info->s_skip;
  390. Uint8 *dst = info->d_pixels;
  391. int dstskip = info->d_skip;
  392. SDL_PixelFormat *dstfmt = info->dst;
  393. const SDL_Color *srcpal = info->src->palette->colors;
  394. int dstbpp;
  395. const int A = info->src->alpha;
  396. /* Set up some basic variables */
  397. dstbpp = dstfmt->BytesPerPixel;
  398. while ( height-- ) {
  399.         int sR, sG, sB;
  400. int dR, dG, dB;
  401.      DUFFS_LOOP4(
  402. {
  403.         Uint32 pixel;
  404. sR = srcpal[*src].r;
  405. sG = srcpal[*src].g;
  406. sB = srcpal[*src].b;
  407. DISEMBLE_RGB(dst, dstbpp, dstfmt,
  408.      pixel, dR, dG, dB);
  409. ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB);
  410.    ASSEMBLE_RGB(dst, dstbpp, dstfmt, dR, dG, dB);
  411. src++;
  412. dst += dstbpp;
  413. },
  414. width);
  415. src += srcskip;
  416. dst += dstskip;
  417. }
  418. }
  419. static void Blit1toNAlphaKey(SDL_BlitInfo *info)
  420. {
  421. int width = info->d_width;
  422. int height = info->d_height;
  423. Uint8 *src = info->s_pixels;
  424. int srcskip = info->s_skip;
  425. Uint8 *dst = info->d_pixels;
  426. int dstskip = info->d_skip;
  427. SDL_PixelFormat *srcfmt = info->src;
  428. SDL_PixelFormat *dstfmt = info->dst;
  429. const SDL_Color *srcpal = info->src->palette->colors;
  430. Uint32 ckey = srcfmt->colorkey;
  431. int dstbpp;
  432. const int A = srcfmt->alpha;
  433. /* Set up some basic variables */
  434. dstbpp = dstfmt->BytesPerPixel;
  435. while ( height-- ) {
  436.         int sR, sG, sB;
  437. int dR, dG, dB;
  438. DUFFS_LOOP(
  439. {
  440. if ( *src != ckey ) {
  441.         Uint32 pixel;
  442. sR = srcpal[*src].r;
  443. sG = srcpal[*src].g;
  444. sB = srcpal[*src].b;
  445. DISEMBLE_RGB(dst, dstbpp, dstfmt,
  446. pixel, dR, dG, dB);
  447. ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB);
  448.    ASSEMBLE_RGB(dst, dstbpp, dstfmt, dR, dG, dB);
  449. }
  450. src++;
  451. dst += dstbpp;
  452. },
  453. width);
  454. src += srcskip;
  455. dst += dstskip;
  456. }
  457. }
  458. static SDL_loblit one_blit[] = {
  459. NULL, Blit1to1, Blit1to2, Blit1to3, Blit1to4
  460. };
  461. static SDL_loblit one_blitkey[] = {
  462.         NULL, Blit1to1Key, Blit1to2Key, Blit1to3Key, Blit1to4Key
  463. };
  464. SDL_loblit SDL_CalculateBlit1(SDL_Surface *surface, int blit_index)
  465. {
  466. int which;
  467. SDL_PixelFormat *dstfmt;
  468. dstfmt = surface->map->dst->format;
  469. if ( dstfmt->BitsPerPixel < 8 ) {
  470. which = 0;
  471. } else {
  472. which = dstfmt->BytesPerPixel;
  473. }
  474. switch(blit_index) {
  475. case 0: /* copy */
  476.     return one_blit[which];
  477. case 1: /* colorkey */
  478.     return one_blitkey[which];
  479. case 2: /* alpha */
  480.     /* Supporting 8bpp->8bpp alpha is doable but requires lots of
  481.        tables which consume space and takes time to precompute,
  482.        so is better left to the user */
  483.     return which >= 2 ? Blit1toNAlpha : NULL;
  484. case 3: /* alpha + colorkey */
  485.     return which >= 2 ? Blit1toNAlphaKey : NULL;
  486. }
  487. return NULL;
  488. }