blit.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373
  1. /*
  2. * Change Logs:
  3. * Date Author Notes
  4. * 2012-01-24 onelife add one more blit table which exchanges the
  5. * positions of R and B color components in output
  6. */
  7. #include <rtgui/rtgui.h>
  8. #include <rtgui/blit.h>
  9. /* 2 bpp to 1 bpp */
  10. static void rtgui_blit_line_2_1(rt_uint8_t* dst_ptr, rt_uint8_t* src_ptr, int line)
  11. {
  12. return;
  13. }
  14. /* 3 bpp to 1 bpp */
  15. static void rtgui_blit_line_3_1(rt_uint8_t* dst_ptr, rt_uint8_t* src_ptr, int line)
  16. {
  17. line = line / 3;
  18. while (line)
  19. {
  20. *dst_ptr = (rt_uint8_t)(((*src_ptr & 0x00E00000)>>16)|
  21. ((*(src_ptr + 1) & 0x0000E000)>>11) |
  22. ((*(src_ptr + 2) & 0x000000C0)>>6));
  23. src_ptr += 3;
  24. dst_ptr ++;
  25. line --;
  26. }
  27. return;
  28. }
  29. /* 4 bpp to 1 bpp */
  30. static void rtgui_blit_line_4_1(rt_uint8_t* dst_ptr, rt_uint8_t* src_ptr, int line)
  31. {
  32. struct _color {rt_uint8_t r, g, b, a;} *c;
  33. c = (struct _color*)src_ptr;
  34. while (line-- > 0)
  35. {
  36. *dst_ptr = (c->r & 0xe0) | (c->g & 0xc0) >> 3 | (c->b & 0xe0) >> 5 ;
  37. c ++;
  38. dst_ptr ++;
  39. }
  40. }
  41. /* 1 bpp to 2 bpp */
  42. static void rtgui_blit_line_1_2(rt_uint8_t* dst_ptr, rt_uint8_t* src_ptr, int line)
  43. {
  44. return;
  45. }
  46. /* 3 bpp to 2 bpp */
  47. static void rtgui_blit_line_3_2(rt_uint8_t* dst_ptr, rt_uint8_t* src_ptr, int line)
  48. {
  49. rt_uint16_t* dst;
  50. dst = (rt_uint16_t*)dst_ptr;
  51. line = line / 3;
  52. while (line)
  53. {
  54. *dst = (((*(src_ptr + 2) << 8) & 0x0000F800) |
  55. ((*(src_ptr + 1) << 3) & 0x000007E0) |
  56. ((*src_ptr >> 3) & 0x0000001F));
  57. src_ptr += 3;
  58. dst ++;
  59. line --;
  60. }
  61. return;
  62. }
  63. /* 4 bpp to 2 bpp */
  64. static void rtgui_blit_line_4_2(rt_uint8_t* dst_ptr, rt_uint8_t* src_ptr, int line)
  65. {
  66. struct _color {rt_uint8_t r, g, b, a;} *c;
  67. rt_uint16_t* ptr;
  68. c = (struct _color*)src_ptr;
  69. ptr = (rt_uint16_t*)dst_ptr;
  70. line = line / 4;
  71. while (line-- > 0)
  72. {
  73. *ptr = ((c->r & 0xf8) << 8) | ((c->g & 0xfc) << 3) | (c->b >> 3);
  74. c ++;
  75. ptr ++;
  76. }
  77. }
  78. static void rtgui_blit_line_1_3(rt_uint8_t* dst_ptr, rt_uint8_t* src_ptr, int line)
  79. {
  80. return;
  81. }
  82. #define HI 1
  83. #define LO 0
  84. /* Special optimized blit for RGB 5-6-5 --> RGBA 8-8-8-8 */
  85. static const rt_uint32_t RGB565_RGBA8888_LUT[512] =
  86. {
  87. 0x000000ff, 0x00000000, 0x000008ff, 0x00200000,
  88. 0x000010ff, 0x00400000, 0x000018ff, 0x00610000,
  89. 0x000020ff, 0x00810000, 0x000029ff, 0x00a10000,
  90. 0x000031ff, 0x00c20000, 0x000039ff, 0x00e20000,
  91. 0x000041ff, 0x08000000, 0x00004aff, 0x08200000,
  92. 0x000052ff, 0x08400000, 0x00005aff, 0x08610000,
  93. 0x000062ff, 0x08810000, 0x00006aff, 0x08a10000,
  94. 0x000073ff, 0x08c20000, 0x00007bff, 0x08e20000,
  95. 0x000083ff, 0x10000000, 0x00008bff, 0x10200000,
  96. 0x000094ff, 0x10400000, 0x00009cff, 0x10610000,
  97. 0x0000a4ff, 0x10810000, 0x0000acff, 0x10a10000,
  98. 0x0000b4ff, 0x10c20000, 0x0000bdff, 0x10e20000,
  99. 0x0000c5ff, 0x18000000, 0x0000cdff, 0x18200000,
  100. 0x0000d5ff, 0x18400000, 0x0000deff, 0x18610000,
  101. 0x0000e6ff, 0x18810000, 0x0000eeff, 0x18a10000,
  102. 0x0000f6ff, 0x18c20000, 0x0000ffff, 0x18e20000,
  103. 0x000400ff, 0x20000000, 0x000408ff, 0x20200000,
  104. 0x000410ff, 0x20400000, 0x000418ff, 0x20610000,
  105. 0x000420ff, 0x20810000, 0x000429ff, 0x20a10000,
  106. 0x000431ff, 0x20c20000, 0x000439ff, 0x20e20000,
  107. 0x000441ff, 0x29000000, 0x00044aff, 0x29200000,
  108. 0x000452ff, 0x29400000, 0x00045aff, 0x29610000,
  109. 0x000462ff, 0x29810000, 0x00046aff, 0x29a10000,
  110. 0x000473ff, 0x29c20000, 0x00047bff, 0x29e20000,
  111. 0x000483ff, 0x31000000, 0x00048bff, 0x31200000,
  112. 0x000494ff, 0x31400000, 0x00049cff, 0x31610000,
  113. 0x0004a4ff, 0x31810000, 0x0004acff, 0x31a10000,
  114. 0x0004b4ff, 0x31c20000, 0x0004bdff, 0x31e20000,
  115. 0x0004c5ff, 0x39000000, 0x0004cdff, 0x39200000,
  116. 0x0004d5ff, 0x39400000, 0x0004deff, 0x39610000,
  117. 0x0004e6ff, 0x39810000, 0x0004eeff, 0x39a10000,
  118. 0x0004f6ff, 0x39c20000, 0x0004ffff, 0x39e20000,
  119. 0x000800ff, 0x41000000, 0x000808ff, 0x41200000,
  120. 0x000810ff, 0x41400000, 0x000818ff, 0x41610000,
  121. 0x000820ff, 0x41810000, 0x000829ff, 0x41a10000,
  122. 0x000831ff, 0x41c20000, 0x000839ff, 0x41e20000,
  123. 0x000841ff, 0x4a000000, 0x00084aff, 0x4a200000,
  124. 0x000852ff, 0x4a400000, 0x00085aff, 0x4a610000,
  125. 0x000862ff, 0x4a810000, 0x00086aff, 0x4aa10000,
  126. 0x000873ff, 0x4ac20000, 0x00087bff, 0x4ae20000,
  127. 0x000883ff, 0x52000000, 0x00088bff, 0x52200000,
  128. 0x000894ff, 0x52400000, 0x00089cff, 0x52610000,
  129. 0x0008a4ff, 0x52810000, 0x0008acff, 0x52a10000,
  130. 0x0008b4ff, 0x52c20000, 0x0008bdff, 0x52e20000,
  131. 0x0008c5ff, 0x5a000000, 0x0008cdff, 0x5a200000,
  132. 0x0008d5ff, 0x5a400000, 0x0008deff, 0x5a610000,
  133. 0x0008e6ff, 0x5a810000, 0x0008eeff, 0x5aa10000,
  134. 0x0008f6ff, 0x5ac20000, 0x0008ffff, 0x5ae20000,
  135. 0x000c00ff, 0x62000000, 0x000c08ff, 0x62200000,
  136. 0x000c10ff, 0x62400000, 0x000c18ff, 0x62610000,
  137. 0x000c20ff, 0x62810000, 0x000c29ff, 0x62a10000,
  138. 0x000c31ff, 0x62c20000, 0x000c39ff, 0x62e20000,
  139. 0x000c41ff, 0x6a000000, 0x000c4aff, 0x6a200000,
  140. 0x000c52ff, 0x6a400000, 0x000c5aff, 0x6a610000,
  141. 0x000c62ff, 0x6a810000, 0x000c6aff, 0x6aa10000,
  142. 0x000c73ff, 0x6ac20000, 0x000c7bff, 0x6ae20000,
  143. 0x000c83ff, 0x73000000, 0x000c8bff, 0x73200000,
  144. 0x000c94ff, 0x73400000, 0x000c9cff, 0x73610000,
  145. 0x000ca4ff, 0x73810000, 0x000cacff, 0x73a10000,
  146. 0x000cb4ff, 0x73c20000, 0x000cbdff, 0x73e20000,
  147. 0x000cc5ff, 0x7b000000, 0x000ccdff, 0x7b200000,
  148. 0x000cd5ff, 0x7b400000, 0x000cdeff, 0x7b610000,
  149. 0x000ce6ff, 0x7b810000, 0x000ceeff, 0x7ba10000,
  150. 0x000cf6ff, 0x7bc20000, 0x000cffff, 0x7be20000,
  151. 0x001000ff, 0x83000000, 0x001008ff, 0x83200000,
  152. 0x001010ff, 0x83400000, 0x001018ff, 0x83610000,
  153. 0x001020ff, 0x83810000, 0x001029ff, 0x83a10000,
  154. 0x001031ff, 0x83c20000, 0x001039ff, 0x83e20000,
  155. 0x001041ff, 0x8b000000, 0x00104aff, 0x8b200000,
  156. 0x001052ff, 0x8b400000, 0x00105aff, 0x8b610000,
  157. 0x001062ff, 0x8b810000, 0x00106aff, 0x8ba10000,
  158. 0x001073ff, 0x8bc20000, 0x00107bff, 0x8be20000,
  159. 0x001083ff, 0x94000000, 0x00108bff, 0x94200000,
  160. 0x001094ff, 0x94400000, 0x00109cff, 0x94610000,
  161. 0x0010a4ff, 0x94810000, 0x0010acff, 0x94a10000,
  162. 0x0010b4ff, 0x94c20000, 0x0010bdff, 0x94e20000,
  163. 0x0010c5ff, 0x9c000000, 0x0010cdff, 0x9c200000,
  164. 0x0010d5ff, 0x9c400000, 0x0010deff, 0x9c610000,
  165. 0x0010e6ff, 0x9c810000, 0x0010eeff, 0x9ca10000,
  166. 0x0010f6ff, 0x9cc20000, 0x0010ffff, 0x9ce20000,
  167. 0x001400ff, 0xa4000000, 0x001408ff, 0xa4200000,
  168. 0x001410ff, 0xa4400000, 0x001418ff, 0xa4610000,
  169. 0x001420ff, 0xa4810000, 0x001429ff, 0xa4a10000,
  170. 0x001431ff, 0xa4c20000, 0x001439ff, 0xa4e20000,
  171. 0x001441ff, 0xac000000, 0x00144aff, 0xac200000,
  172. 0x001452ff, 0xac400000, 0x00145aff, 0xac610000,
  173. 0x001462ff, 0xac810000, 0x00146aff, 0xaca10000,
  174. 0x001473ff, 0xacc20000, 0x00147bff, 0xace20000,
  175. 0x001483ff, 0xb4000000, 0x00148bff, 0xb4200000,
  176. 0x001494ff, 0xb4400000, 0x00149cff, 0xb4610000,
  177. 0x0014a4ff, 0xb4810000, 0x0014acff, 0xb4a10000,
  178. 0x0014b4ff, 0xb4c20000, 0x0014bdff, 0xb4e20000,
  179. 0x0014c5ff, 0xbd000000, 0x0014cdff, 0xbd200000,
  180. 0x0014d5ff, 0xbd400000, 0x0014deff, 0xbd610000,
  181. 0x0014e6ff, 0xbd810000, 0x0014eeff, 0xbda10000,
  182. 0x0014f6ff, 0xbdc20000, 0x0014ffff, 0xbde20000,
  183. 0x001800ff, 0xc5000000, 0x001808ff, 0xc5200000,
  184. 0x001810ff, 0xc5400000, 0x001818ff, 0xc5610000,
  185. 0x001820ff, 0xc5810000, 0x001829ff, 0xc5a10000,
  186. 0x001831ff, 0xc5c20000, 0x001839ff, 0xc5e20000,
  187. 0x001841ff, 0xcd000000, 0x00184aff, 0xcd200000,
  188. 0x001852ff, 0xcd400000, 0x00185aff, 0xcd610000,
  189. 0x001862ff, 0xcd810000, 0x00186aff, 0xcda10000,
  190. 0x001873ff, 0xcdc20000, 0x00187bff, 0xcde20000,
  191. 0x001883ff, 0xd5000000, 0x00188bff, 0xd5200000,
  192. 0x001894ff, 0xd5400000, 0x00189cff, 0xd5610000,
  193. 0x0018a4ff, 0xd5810000, 0x0018acff, 0xd5a10000,
  194. 0x0018b4ff, 0xd5c20000, 0x0018bdff, 0xd5e20000,
  195. 0x0018c5ff, 0xde000000, 0x0018cdff, 0xde200000,
  196. 0x0018d5ff, 0xde400000, 0x0018deff, 0xde610000,
  197. 0x0018e6ff, 0xde810000, 0x0018eeff, 0xdea10000,
  198. 0x0018f6ff, 0xdec20000, 0x0018ffff, 0xdee20000,
  199. 0x001c00ff, 0xe6000000, 0x001c08ff, 0xe6200000,
  200. 0x001c10ff, 0xe6400000, 0x001c18ff, 0xe6610000,
  201. 0x001c20ff, 0xe6810000, 0x001c29ff, 0xe6a10000,
  202. 0x001c31ff, 0xe6c20000, 0x001c39ff, 0xe6e20000,
  203. 0x001c41ff, 0xee000000, 0x001c4aff, 0xee200000,
  204. 0x001c52ff, 0xee400000, 0x001c5aff, 0xee610000,
  205. 0x001c62ff, 0xee810000, 0x001c6aff, 0xeea10000,
  206. 0x001c73ff, 0xeec20000, 0x001c7bff, 0xeee20000,
  207. 0x001c83ff, 0xf6000000, 0x001c8bff, 0xf6200000,
  208. 0x001c94ff, 0xf6400000, 0x001c9cff, 0xf6610000,
  209. 0x001ca4ff, 0xf6810000, 0x001cacff, 0xf6a10000,
  210. 0x001cb4ff, 0xf6c20000, 0x001cbdff, 0xf6e20000,
  211. 0x001cc5ff, 0xff000000, 0x001ccdff, 0xff200000,
  212. 0x001cd5ff, 0xff400000, 0x001cdeff, 0xff610000,
  213. 0x001ce6ff, 0xff810000, 0x001ceeff, 0xffa10000,
  214. 0x001cf6ff, 0xffc20000, 0x001cffff, 0xffe20000,
  215. };
  216. static void rtgui_blit_line_2_3(rt_uint8_t* dst_ptr, rt_uint8_t* src_ptr, int line)
  217. {
  218. rt_uint16_t *src;
  219. rt_uint32_t *dst;
  220. src = (rt_uint16_t*)src_ptr;
  221. dst = (rt_uint32_t*)dst_ptr;
  222. line = line / 2;
  223. while (line)
  224. {
  225. *dst++ = RGB565_RGBA8888_LUT[src[LO]*2] + RGB565_RGBA8888_LUT[src[HI]*2+1];
  226. line--;
  227. src ++;
  228. }
  229. }
  230. void rtgui_blit_line_direct(rt_uint8_t* dst_ptr, rt_uint8_t* src_ptr, int line)
  231. {
  232. rt_memcpy(dst_ptr, src_ptr, line);
  233. }
  234. /* convert 4bpp to 3bpp */
  235. static void rtgui_blit_line_4_3(rt_uint8_t* dst_ptr, rt_uint8_t* src_ptr, int line)
  236. {
  237. line = line / 4;
  238. while (line)
  239. {
  240. *dst_ptr++ = *src_ptr++;
  241. *dst_ptr++ = *src_ptr++;
  242. *dst_ptr++ = *src_ptr++;
  243. src_ptr ++;
  244. line --;
  245. }
  246. }
  247. static void rtgui_blit_line_1_4(rt_uint8_t* dst_ptr, rt_uint8_t* src_ptr, int line)
  248. {
  249. }
  250. static void rtgui_blit_line_2_4(rt_uint8_t* dst_ptr, rt_uint8_t* src_ptr, int line)
  251. {
  252. }
  253. /* convert 3bpp to 4bpp */
  254. static void rtgui_blit_line_3_4(rt_uint8_t* dst_ptr, rt_uint8_t* src_ptr, int line)
  255. {
  256. line = line / 4;
  257. while (line)
  258. {
  259. *dst_ptr++ = *src_ptr++;
  260. *dst_ptr++ = *src_ptr++;
  261. *dst_ptr++ = *src_ptr++;
  262. *dst_ptr++ = 0;
  263. line --;
  264. }
  265. }
  266. static const rtgui_blit_line_func _blit_table[5][5] =
  267. {
  268. /* 0_0, 1_0, 2_0, 3_0, 4_0 */
  269. {RT_NULL, RT_NULL, RT_NULL, RT_NULL, RT_NULL },
  270. /* 0_1, 1_1, 2_1, 3_1, 4_1 */
  271. {RT_NULL, rtgui_blit_line_direct, rtgui_blit_line_2_1, rtgui_blit_line_3_1, rtgui_blit_line_4_1 },
  272. /* 0_2, 1_2, 2_2, 3_2, 4_2 */
  273. {RT_NULL, rtgui_blit_line_1_2, rtgui_blit_line_direct, rtgui_blit_line_3_2, rtgui_blit_line_4_2 },
  274. /* 0_3, 1_3, 2_3, 3_3, 4_3 */
  275. {RT_NULL, rtgui_blit_line_1_3, rtgui_blit_line_2_3, rtgui_blit_line_direct, rtgui_blit_line_4_3 },
  276. /* 0_4, 1_4, 2_4, 3_4, 4_4 */
  277. {RT_NULL, rtgui_blit_line_1_4, rtgui_blit_line_2_4, rtgui_blit_line_3_4, rtgui_blit_line_direct },
  278. };
  279. rtgui_blit_line_func rtgui_blit_line_get(int dst_bpp, int src_bpp)
  280. {
  281. RT_ASSERT(dst_bpp>0 && dst_bpp < 5);
  282. RT_ASSERT(src_bpp>0 && src_bpp < 5);
  283. return _blit_table[dst_bpp][src_bpp];
  284. }
  285. static void rtgui_blit_line_3_2_inv(rt_uint8_t* dst_ptr, rt_uint8_t* src_ptr, int line)
  286. {
  287. rt_uint16_t* dst;
  288. dst = (rt_uint16_t*)dst_ptr;
  289. line = line / 3;
  290. while (line)
  291. {
  292. *dst = (((*src_ptr << 8) & 0x0000F800) |
  293. ((*(src_ptr + 1) << 3) & 0x000007E0) |
  294. ((*(src_ptr + 2) >> 3) & 0x0000001F));
  295. src_ptr += 3;
  296. dst ++;
  297. line --;
  298. }
  299. return;
  300. }
  301. void rtgui_blit_line_2_2_inv(rt_uint8_t* dst_ptr, rt_uint8_t* src_ptr, int line)
  302. {
  303. rt_uint16_t *dst, *src;
  304. dst = (rt_uint16_t *)dst_ptr;
  305. src = (rt_uint16_t *)src_ptr;
  306. line = line / 2;
  307. while (line)
  308. {
  309. *dst = ((*src << 11) & 0xF800) | (*src & 0x07E0) | ((*src >> 11) & 0x001F);
  310. src ++;
  311. dst ++;
  312. line --;
  313. }
  314. }
  315. static const rtgui_blit_line_func _blit_table_inv[5][5] =
  316. {
  317. /* 0_0, 1_0, 2_0, 3_0, 4_0 */
  318. {RT_NULL, RT_NULL, RT_NULL, RT_NULL, RT_NULL },
  319. /* 0_1, 1_1, 2_1, 3_1, 4_1 */
  320. {RT_NULL, rtgui_blit_line_direct, rtgui_blit_line_2_1, rtgui_blit_line_3_1, rtgui_blit_line_4_1 },
  321. /* 0_2, 1_2, 2_2, 3_2, 4_2 */
  322. {RT_NULL, rtgui_blit_line_1_2, rtgui_blit_line_2_2_inv, rtgui_blit_line_3_2_inv, rtgui_blit_line_4_2 },
  323. /* 0_3, 1_3, 2_3, 3_3, 4_3 */
  324. {RT_NULL, rtgui_blit_line_1_3, rtgui_blit_line_2_3, rtgui_blit_line_direct, rtgui_blit_line_4_3 },
  325. /* 0_4, 1_4, 2_4, 3_4, 4_4 */
  326. {RT_NULL, rtgui_blit_line_1_4, rtgui_blit_line_2_4, rtgui_blit_line_3_4, rtgui_blit_line_direct },
  327. };
  328. rtgui_blit_line_func rtgui_blit_line_get_inv(int dst_bpp, int src_bpp)
  329. {
  330. RT_ASSERT(dst_bpp>0 && dst_bpp < 5);
  331. RT_ASSERT(src_bpp>0 && src_bpp < 5);
  332. return _blit_table_inv[dst_bpp][src_bpp];
  333. }