Advertisement
Guest User

2xbr.c adds bigendian 8888

a guest
Apr 18th, 2014
52
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 22.57 KB | None | 0 0
  1. /* RetroArch - A frontend for libretro.
  2. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen
  3. *
  4. * RetroArch is free software: you can redistribute it and/or modify it under the terms
  5. * of the GNU General Public License as published by the Free Software Found-
  6. * ation, either version 3 of the License, or (at your option) any later version.
  7. *
  8. * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
  9. * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  10. * PURPOSE. See the GNU General Public License for more details.
  11. *
  12. * You should have received a copy of the GNU General Public License along with RetroArch.
  13. * If not, see <http://www.gnu.org/licenses/>.
  14. */
  15.  
  16. /*
  17. Hyllian's 2xBR v3.3a
  18.  
  19. Copyright (C) 2011, 2014 Hyllian/Jararaca - sergiogdb@gmail.com
  20.  
  21. This program is free software; you can redistribute it and/or
  22. modify it under the terms of the GNU General Public License
  23. as published by the Free Software Foundation; either version 2
  24. of the License, or (at your option) any later version.
  25.  
  26. This program is distributed in the hope that it will be useful,
  27. but WITHOUT ANY WARRANTY; without even the implied warranty of
  28. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  29. GNU General Public License for more details.
  30.  
  31. You should have received a copy of the GNU General Public License
  32. along with this program; if not, write to the Free Software
  33. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  34.  
  35. */
  36.  
  37. // Compile: gcc -o twoxbr.so -shared twoxbr.c -std=c99 -O3 -Wall -pedantic -fPIC
  38.  
  39. #include "softfilter.h"
  40. #include <stdlib.h>
  41.  
  42. #ifdef RARCH_INTERNAL
  43. #define softfilter_get_implementation twoxbr_get_implementation
  44. #endif
  45.  
  46. #define TWOXBR_SCALE 2
  47.  
  48. static unsigned twoxbr_generic_input_fmts(void)
  49. {
  50. return SOFTFILTER_FMT_RGB565 | SOFTFILTER_FMT_XRGB8888;
  51. }
  52.  
  53. static unsigned twoxbr_generic_output_fmts(unsigned input_fmts)
  54. {
  55. return input_fmts;
  56. }
  57.  
  58. static unsigned twoxbr_generic_threads(void *data)
  59. {
  60. struct filter_data *filt = (struct filter_data*)data;
  61. return filt->threads;
  62. }
  63.  
  64. static void *twoxbr_generic_create(unsigned in_fmt, unsigned out_fmt,
  65. unsigned max_width, unsigned max_height,
  66. unsigned threads, softfilter_simd_mask_t simd)
  67. {
  68. (void)simd;
  69.  
  70. struct filter_data *filt = (struct filter_data*)calloc(1, sizeof(*filt));
  71. if (!filt)
  72. return NULL;
  73. filt->workers = (struct softfilter_thread_data*)calloc(threads, sizeof(struct softfilter_thread_data));
  74. filt->threads = threads;
  75. filt->in_fmt = in_fmt;
  76. if (!filt->workers)
  77. {
  78. free(filt);
  79. return NULL;
  80. }
  81. return filt;
  82. }
  83.  
  84. static void twoxbr_generic_output(void *data, unsigned *out_width, unsigned *out_height,
  85. unsigned width, unsigned height)
  86. {
  87. *out_width = width * TWOXBR_SCALE;
  88. *out_height = height * TWOXBR_SCALE;
  89. }
  90.  
  91. static void twoxbr_generic_destroy(void *data)
  92. {
  93. struct filter_data *filt = (struct filter_data*)data;
  94. free(filt->workers);
  95. free(filt);
  96. }
  97.  
  98. static uint8_t initialized = 0;
  99. uint16_t RGBtoYUV[65536];
  100. const static uint16_t tbl_5_to_8[32]={0, 8, 16, 25, 33, 41, 49, 58, 66, 74, 82, 90, 99, 107, 115, 123, 132, 140, 148, 156, 165, 173, 181, 189, 197, 206, 214, 222, 230, 239, 247, 255};
  101. const static uint16_t tbl_6_to_8[64]={0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 45, 49, 53, 57, 61, 65, 69, 73, 77, 81, 85, 89, 93, 97, 101, 105, 109, 113, 117, 121, 125, 130, 134, 138, 142, 146, 150, 154, 158, 162, 166, 170, 174, 178, 182, 186, 190, 194, 198, 202, 206, 210, 215, 219, 223, 227, 231, 235, 239, 243, 247, 251, 255};
  102.  
  103. //---------------------------------------------------------------------------------------------------------------------------
  104.  
  105.  
  106. #define RED_MASK565 0xF800
  107. #define GREEN_MASK565 0x07E0
  108. #define BLUE_MASK565 0x001F
  109. #define PG_LBMASK565 0xF7DE
  110.  
  111. #ifdef MSB_FIRST
  112. #define RED_MASK8888 0x000000FF
  113. #define GREEN_MASK8888 0x0000FF00
  114. #define BLUE_MASK8888 0x00FF0000
  115. #define PG_LBMASK8888 0xFEFEFEFE
  116. #define ALPHA_MASK8888 0xFF000000
  117. #else
  118. #define RED_MASK8888 0xFF000000
  119. #define GREEN_MASK8888 0x00FF0000
  120. #define BLUE_MASK8888 0x0000FF00
  121. #define PG_LBMASK8888 0xFEFEFEFE
  122. #define ALPHA_MASK8888 0x000000FF
  123. #endif
  124.  
  125.  
  126. #define ALPHA_BLEND_128_W(dst, src) dst = ((src & pg_lbmask) >> 1) + ((dst & pg_lbmask) >> 1)
  127.  
  128. #define ALPHA_BLEND_32_W(dst, src) \
  129. dst = ( \
  130. (pg_red_mask & ((dst & pg_red_mask) + \
  131. ((((src & pg_red_mask) - \
  132. (dst & pg_red_mask))) >>3))) | \
  133. (pg_green_mask & ((dst & pg_green_mask) + \
  134. ((((src & pg_green_mask) - \
  135. (dst & pg_green_mask))) >>3))) | \
  136. (pg_blue_mask & ((dst & pg_blue_mask) + \
  137. ((((src & pg_blue_mask) - \
  138. (dst & pg_blue_mask))) >>3))) )
  139.  
  140.  
  141. #define ALPHA_BLEND_8888_32_W(dst, src) \
  142. dst = ( \
  143. (pg_red_mask & ((dst & pg_red_mask) + \
  144. ((((src & pg_red_mask) - \
  145. (dst & pg_red_mask))) >>3))) | \
  146. (pg_green_mask & ((dst & pg_green_mask) + \
  147. ((((src & pg_green_mask) - \
  148. (dst & pg_green_mask))) >>3))) | \
  149. (pg_blue_mask & ((dst & pg_blue_mask) + \
  150. ((((src & pg_blue_mask) - \
  151. (dst & pg_blue_mask))) >>3))) ) +\
  152. pg_alpha_mask
  153.  
  154.  
  155. #define ALPHA_BLEND_64_W(dst, src) \
  156. dst = ( \
  157. (pg_red_mask & ((dst & pg_red_mask) + \
  158. ((((src & pg_red_mask) - \
  159. (dst & pg_red_mask))) >>2))) | \
  160. (pg_green_mask & ((dst & pg_green_mask) + \
  161. ((((src & pg_green_mask) - \
  162. (dst & pg_green_mask))) >>2))) | \
  163. (pg_blue_mask & ((dst & pg_blue_mask) + \
  164. ((((src & pg_blue_mask) - \
  165. (dst & pg_blue_mask))) >>2))) )
  166.  
  167. #define ALPHA_BLEND_8888_64_W(dst, src) \
  168. dst = ( \
  169. (pg_red_mask & ((dst & pg_red_mask) + \
  170. ((((src & pg_red_mask) - \
  171. (dst & pg_red_mask))) >>2))) | \
  172. (pg_green_mask & ((dst & pg_green_mask) + \
  173. ((((src & pg_green_mask) - \
  174. (dst & pg_green_mask))) >>2))) | \
  175. (pg_blue_mask & ((dst & pg_blue_mask) + \
  176. ((((src & pg_blue_mask) - \
  177. (dst & pg_blue_mask))) >>2))) ) +\
  178. pg_alpha_mask
  179.  
  180.  
  181. #define ALPHA_BLEND_192_W(dst, src) \
  182. dst = ( \
  183. (pg_red_mask & ((dst & pg_red_mask) + \
  184. ((((src & pg_red_mask) - \
  185. (dst & pg_red_mask)) * 192) >>8))) | \
  186. (pg_green_mask & ((dst & pg_green_mask) + \
  187. ((((src & pg_green_mask) - \
  188. (dst & pg_green_mask)) * 192) >>8))) | \
  189. (pg_blue_mask & ((dst & pg_blue_mask) + \
  190. ((((src & pg_blue_mask) - \
  191. (dst & pg_blue_mask)) * 192) >>8))) )
  192.  
  193.  
  194. #define ALPHA_BLEND_8888_192_W(dst, src) \
  195. dst = ( \
  196. (pg_red_mask & ((dst & pg_red_mask) + \
  197. ((((src & pg_red_mask) - \
  198. (dst & pg_red_mask)) * 192) >>8))) | \
  199. (pg_green_mask & ((dst & pg_green_mask) + \
  200. ((((src & pg_green_mask) - \
  201. (dst & pg_green_mask)) * 192) >>8))) | \
  202. (pg_blue_mask & ((dst & pg_blue_mask) + \
  203. ((((src & pg_blue_mask) - \
  204. (dst & pg_blue_mask)) * 192) >>8))) ) +\
  205. pg_alpha_mask
  206.  
  207. #define ALPHA_BLEND_224_W(dst, src) \
  208. dst = ( \
  209. (pg_red_mask & ((dst & pg_red_mask) + \
  210. ((((src & pg_red_mask) - \
  211. (dst & pg_red_mask)) * 224) >>8))) | \
  212. (pg_green_mask & ((dst & pg_green_mask) + \
  213. ((((src & pg_green_mask) - \
  214. (dst & pg_green_mask)) * 224) >>8))) | \
  215. (pg_blue_mask & ((dst & pg_blue_mask) + \
  216. ((((src & pg_blue_mask) - \
  217. (dst & pg_blue_mask)) * 224) >>8))) );
  218.  
  219. #define ALPHA_BLEND_8888_224_W(dst, src) \
  220. dst = ( \
  221. (pg_red_mask & ((dst & pg_red_mask) + \
  222. ((((src & pg_red_mask) - \
  223. (dst & pg_red_mask)) * 224) >>8))) | \
  224. (pg_green_mask & ((dst & pg_green_mask) + \
  225. ((((src & pg_green_mask) - \
  226. (dst & pg_green_mask)) * 224) >>8))) | \
  227. (pg_blue_mask & ((dst & pg_blue_mask) + \
  228. ((((src & pg_blue_mask) - \
  229. (dst & pg_blue_mask)) * 224) >>8))) ) +\
  230. pg_alpha_mask
  231.  
  232.  
  233. #define LEFT_UP_2_2X(N3, N2, N1, PIXEL)\
  234. ALPHA_BLEND_224_W(E[N3], PIXEL); \
  235. ALPHA_BLEND_64_W( E[N2], PIXEL); \
  236. E[N1] = E[N2]; \
  237.  
  238.  
  239. #define LEFT_2_2X(N3, N2, PIXEL)\
  240. ALPHA_BLEND_192_W(E[N3], PIXEL); \
  241. ALPHA_BLEND_64_W( E[N2], PIXEL); \
  242.  
  243. #define UP_2_2X(N3, N1, PIXEL)\
  244. ALPHA_BLEND_192_W(E[N3], PIXEL); \
  245. ALPHA_BLEND_64_W( E[N1], PIXEL); \
  246.  
  247. #define DIA_2X(N3, PIXEL)\
  248. ALPHA_BLEND_128_W(E[N3], PIXEL); \
  249.  
  250.  
  251. #define LEFT_UP_2_8888_2X(N3, N2, N1, PIXEL)\
  252. ALPHA_BLEND_8888_224_W(E[N3], PIXEL); \
  253. ALPHA_BLEND_8888_64_W( E[N2], PIXEL); \
  254. E[N1] = E[N2]; \
  255.  
  256.  
  257. #define LEFT_2_8888_2X(N3, N2, PIXEL)\
  258. ALPHA_BLEND_8888_192_W(E[N3], PIXEL); \
  259. ALPHA_BLEND_8888_64_W( E[N2], PIXEL); \
  260.  
  261. #define UP_2_8888_2X(N3, N1, PIXEL)\
  262. ALPHA_BLEND_8888_192_W(E[N3], PIXEL); \
  263. ALPHA_BLEND_8888_64_W( E[N1], PIXEL); \
  264.  
  265. #define DIA_8888_2X(N3, PIXEL)\
  266. ALPHA_BLEND_128_W(E[N3], PIXEL); \
  267.  
  268.  
  269. #define df(A, B)\
  270. abs(RGBtoYUV[A] - RGBtoYUV[B])\
  271.  
  272. #define eq(A, B)\
  273. (df(A, B) < 155)\
  274.  
  275.  
  276.  
  277. float df8(uint32_t A, uint32_t B, uint32_t pg_red_mask, uint32_t pg_green_mask, uint32_t pg_blue_mask)
  278. {
  279. uint32_t r, g, b;
  280. uint32_t y, u, v;
  281.  
  282. #ifdef MSB_FIRST
  283. b = abs((int)(((A & pg_blue_mask )>>16) - ((B & pg_blue_mask )>> 16)));
  284. g = abs((int)(((A & pg_green_mask)>>8 ) - ((B & pg_green_mask )>> 8)));
  285. r = abs((int)(((A & pg_red_mask ) - (B & pg_red_mask ))));
  286. #else
  287. r = abs((int)(((A & pg_red_mask )>>24) - ((B & pg_red_mask )>> 24)));
  288. g = abs((int)(((A & pg_green_mask )>>16) - ((B & pg_green_mask )>> 16)));
  289. b = abs((int)(((A & pg_blue_mask )>>8 ) - ((B & pg_blue_mask )>> 8 )));
  290. #endif
  291. y = abs(0.299*r + 0.587*g + 0.114*b);
  292. u = abs(-0.169*r - 0.331*g + 0.500*b);
  293. v = abs(0.500*r - 0.419*g - 0.081*b);
  294.  
  295. return 48*y + 7*u + 6*v;
  296. }
  297.  
  298. int eq8(uint32_t A, uint32_t B, uint32_t pg_red_mask, uint32_t pg_green_mask, uint32_t pg_blue_mask)
  299. {
  300. uint32_t r, g, b;
  301. uint32_t y, u, v;
  302.  
  303. #ifdef MSB_FIRST
  304. b = abs((int)(((A & pg_blue_mask )>>16) - ((B & pg_blue_mask )>> 16)));
  305. g = abs((int)(((A & pg_green_mask)>>8 ) - ((B & pg_green_mask )>> 8)));
  306. r = abs((int)(((A & pg_red_mask ) - (B & pg_red_mask ))));
  307. #else
  308. r = abs((int)(((A & pg_red_mask )>>24) - ((B & pg_red_mask )>> 24)));
  309. g = abs((int)(((A & pg_green_mask )>>16) - ((B & pg_green_mask )>> 16)));
  310. b = abs((int)(((A & pg_blue_mask )>>8 ) - ((B & pg_blue_mask )>> 8 )));
  311. #endif
  312.  
  313. y = abs(0.299*r + 0.587*g + 0.114*b);
  314. u = abs(-0.169*r - 0.331*g + 0.500*b);
  315. v = abs(0.500*r - 0.419*g - 0.081*b);
  316.  
  317. return ((48 >= y) && (7 >= u) && (6 >= v)) ? 1 : 0;
  318. }
  319.  
  320.  
  321. #define FILTRO_RGB565(PE, PI, PH, PF, PG, PC, PD, PB, PA, G5, C4, G0, D0, C1, B1, F4, I4, H5, I5, A0, A1, N0, N1, N2, N3, pg_red_mask, pg_green_mask, pg_blue_mask) \
  322. ex = (PE!=PH && PE!=PF); \
  323. if ( ex )\
  324. {\
  325. e = (df(PE,PC)+df(PE,PG)+df(PI,H5)+df(PI,F4))+(df(PH,PF)<<2); \
  326. i = (df(PH,PD)+df(PH,I5)+df(PF,I4)+df(PF,PB))+(df(PE,PI)<<2); \
  327. if ((e<i) && ( (!eq(PF,PB) && !eq(PF,PC)) || (!eq(PH,PD) && !eq(PH,PG)) || (eq(PE,PI) && ((!eq(PF,F4) && !eq(PF,I4)) || (!eq(PH,H5) && !eq(PH,I5)))) || eq(PE,PG) || eq(PE,PC)) )\
  328. {\
  329. ke=df(PF,PG); ki=df(PH,PC); \
  330. ex2 = (PE!=PC && PB!=PC); ex3 = (PE!=PG && PD!=PG); px = (df(PE,PF) <= df(PE,PH)) ? PF : PH; \
  331. if ( ((ke<<1)<=ki) && ex3 && (ke>=(ki<<1)) && ex2 ) \
  332. {\
  333. LEFT_UP_2_2X(N3, N2, N1, px)\
  334. }\
  335. else if ( ((ke<<1)<=ki) && ex3 ) \
  336. {\
  337. LEFT_2_2X(N3, N2, px);\
  338. }\
  339. else if ( (ke>=(ki<<1)) && ex2 ) \
  340. {\
  341. UP_2_2X(N3, N1, px);\
  342. }\
  343. else \
  344. {\
  345. DIA_2X(N3, px);\
  346. }\
  347. }\
  348. else if (e<=i)\
  349. {\
  350. ALPHA_BLEND_128_W( E[N3], ((df(PE,PF) <= df(PE,PH)) ? PF : PH)); \
  351. }\
  352. }\
  353.  
  354. #define FILTRO_RGB8888(PE, PI, PH, PF, PG, PC, PD, PB, PA, G5, C4, G0, D0, C1, B1, F4, I4, H5, I5, A0, A1, N0, N1, N2, N3, pg_red_mask, pg_green_mask, pg_blue_mask) \
  355. ex = (PE!=PH && PE!=PF); \
  356. if ( ex )\
  357. {\
  358. e = (df8(PE,PC, pg_red_mask, pg_green_mask, pg_blue_mask ) + df8(PE,PG, pg_red_mask, pg_green_mask, pg_blue_mask) + \
  359. df8(PI,H5, pg_red_mask, pg_green_mask, pg_blue_mask ) + df8(PI,F4, pg_red_mask, pg_green_mask, pg_blue_mask))+(4 * (df8(PH,PF, pg_red_mask, pg_green_mask, pg_blue_mask))); \
  360. i = (df8(PH,PD, pg_red_mask, pg_green_mask, pg_blue_mask) + df8(PH,I5, pg_red_mask, pg_green_mask, pg_blue_mask) + \
  361. df8(PF,I4, pg_red_mask, pg_green_mask, pg_blue_mask) + df8(PF,PB, pg_red_mask, pg_green_mask, pg_blue_mask))+(4 * (df8(PE,PI, pg_red_mask, pg_green_mask, pg_blue_mask))); \
  362. if ((e<i) && ( (!eq8(PF,PB, pg_red_mask, pg_green_mask, pg_blue_mask) && !eq8(PF,PC, pg_red_mask, pg_green_mask, pg_blue_mask)) || (!eq8(PH,PD, pg_red_mask, pg_green_mask, pg_blue_mask) && !eq8(PH,PG, pg_red_mask, pg_green_mask, pg_blue_mask)) || (eq8(PE,PI, pg_red_mask, pg_green_mask, pg_blue_mask) && ((!eq8(PF,F4, pg_red_mask, pg_green_mask, pg_blue_mask) && !eq8(PF,I4, pg_red_mask, pg_green_mask, pg_blue_mask)) || (!eq8(PH,H5, pg_red_mask, pg_green_mask,pg_blue_mask) && !eq8(PH,I5, pg_red_mask, pg_green_mask, pg_blue_mask)))) || eq8(PE,PG, pg_red_mask, pg_green_mask, pg_blue_mask) || eq8(PE,PC, pg_red_mask, pg_green_mask, pg_blue_mask)) )\
  363. {\
  364. ke=df8(PF,PG, pg_red_mask, pg_green_mask, pg_blue_mask); ki=df8(PH,PC, pg_red_mask, pg_green_mask, pg_blue_mask); \
  365. ex2 = (PE!=PC && PB!=PC); ex3 = (PE!=PG && PD!=PG); px = (df8(PE,PF, pg_red_mask, pg_green_mask, pg_blue_mask) <= df8(PE,PH, pg_red_mask, pg_green_mask, pg_blue_mask)) ? PF : PH; \
  366. if ( ((ke<<1)<=ki) && ex3 && (ke>=(ki<<1)) && ex2 ) \
  367. {\
  368. LEFT_UP_2_8888_2X(N3, N2, N1, px)\
  369. }\
  370. else if ( ((ke<<1)<=ki) && ex3 ) \
  371. {\
  372. LEFT_2_8888_2X(N3, N2, px);\
  373. }\
  374. else if ( (ke>=(ki<<1)) && ex2 ) \
  375. {\
  376. UP_2_8888_2X(N3, N1, px);\
  377. }\
  378. else \
  379. {\
  380. DIA_8888_2X(N3, px);\
  381. }\
  382. }\
  383. else if (e<=i)\
  384. {\
  385. ALPHA_BLEND_128_W( E[N3], ((df8(PE,PF, pg_red_mask, pg_green_mask, pg_blue_mask) <= df8(PE,PH, pg_red_mask, pg_green_mask, pg_blue_mask)) ? PF : PH)); \
  386. }\
  387. }\
  388.  
  389.  
  390.  
  391. #define twoxbr_declare_variables(typename_t, in, nextline) \
  392. typename_t E[4]; \
  393. typename_t ex, e, i, ke, ki, ex2, ex3, px; \
  394. typename_t A1 = *(in - nextline - nextline - 1); \
  395. typename_t B1 = *(in - nextline - nextline); \
  396. typename_t C1 = *(in - nextline - nextline + 1); \
  397. typename_t A0 = *(in - nextline - 2); \
  398. typename_t PA = *(in - nextline - 1); \
  399. typename_t PB = *(in - nextline); \
  400. typename_t PC = *(in - nextline + 1); \
  401. typename_t C4 = *(in - nextline + 2); \
  402. typename_t D0 = *(in - 2); \
  403. typename_t PD = *(in - 1); \
  404. typename_t PE = *(in); \
  405. typename_t PF = *(in + 1); \
  406. typename_t F4 = *(in + 2); \
  407. typename_t G0 = *(in + nextline - 2); \
  408. typename_t PG = *(in + nextline - 1); \
  409. typename_t PH = *(in + nextline); \
  410. typename_t PI = *(in + nextline + 1); \
  411. typename_t I4 = *(in + nextline + 2); \
  412. typename_t G5 = *(in + nextline + nextline - 1); \
  413. typename_t H5 = *(in + nextline + nextline); \
  414. typename_t I5 = *(in + nextline + nextline + 1); \
  415.  
  416. #ifndef twoxbr_function
  417. #define twoxbr_function(FILTRO) \
  418. E[0] = E[1] = E[2] = E[3] = PE;\
  419. FILTRO(PE, PI, PH, PF, PG, PC, PD, PB, PA, G5, C4, G0, D0, C1, B1, F4, I4, H5, I5, A0, A1, 0, 1, 2, 3, pg_red_mask, pg_green_mask, pg_blue_mask);\
  420. FILTRO(PE, PC, PF, PB, PI, PA, PH, PD, PG, I4, A1, I5, H5, A0, D0, B1, C1, F4, C4, G5, G0, 2, 0, 3, 1, pg_red_mask, pg_green_mask, pg_blue_mask);\
  421. FILTRO(PE, PA, PB, PD, PC, PG, PF, PH, PI, C1, G0, C4, F4, G5, H5, D0, A0, B1, A1, I4, I5, 3, 2, 1, 0, pg_red_mask, pg_green_mask, pg_blue_mask);\
  422. FILTRO(PE, PG, PD, PH, PA, PI, PB, PF, PC, A0, I5, A1, B1, I4, F4, H5, G5, D0, G0, C1, C4, 1, 3, 0, 2, pg_red_mask, pg_green_mask, pg_blue_mask);\
  423. out[0] = E[0]; \
  424. out[1] = E[1]; \
  425. out[dst_stride] = E[2]; \
  426. out[dst_stride + 1] = E[3]; \
  427. ++in; \
  428. out += 2
  429. #endif
  430.  
  431. static void SetupFormat(void)
  432. {
  433. uint16_t r, g, b, y, u, v;
  434. uint32_t c;
  435.  
  436. for (c = 0; c < 65536; c++)
  437. {
  438. r = tbl_5_to_8[(c & RED_MASK565) >> 11];
  439. g = tbl_6_to_8[(c & GREEN_MASK565) >> 5];
  440. b = tbl_5_to_8[(c & BLUE_MASK565) ];
  441. y = ((r<<4) + (g<<5) + (b<<2));
  442. u = ( -r - (g<<1) + (b<<2));
  443. v = ((r<<1) - (g<<1) - (b>>1));
  444. RGBtoYUV[c] = y + u + v;
  445. }
  446. }
  447.  
  448.  
  449. static void twoxbr_generic_xrgb8888(unsigned width, unsigned height,
  450. int first, int last, uint32_t *src,
  451. unsigned src_stride, uint32_t *dst, unsigned dst_stride)
  452. {
  453. uint32_t pg_red_mask = RED_MASK8888;
  454. uint32_t pg_green_mask = GREEN_MASK8888;
  455. uint32_t pg_blue_mask = BLUE_MASK8888;
  456. uint32_t pg_lbmask = PG_LBMASK8888;
  457. uint32_t pg_alpha_mask = ALPHA_MASK8888;
  458. unsigned nextline, finish;
  459. nextline = (last) ? 0 : src_stride;
  460.  
  461. if (!initialized)
  462. {
  463. initialized = 1;
  464. }
  465.  
  466.  
  467. for (; height; height--)
  468. {
  469. uint32_t *in = (uint32_t*)src;
  470. uint32_t *out = (uint32_t*)dst;
  471.  
  472. for (finish = width; finish; finish -= 1)
  473. {
  474. twoxbr_declare_variables(uint32_t, in, nextline);
  475.  
  476. //---------------------------------------
  477. // Map of the pixels: A1 B1 C1
  478. // A0 PA PB PC C4
  479. // D0 PD PE PF F4
  480. // G0 PG PH PI I4
  481. // G5 H5 I5
  482.  
  483. twoxbr_function(FILTRO_RGB8888);
  484. }
  485.  
  486. src += src_stride;
  487. dst += 2 * dst_stride;
  488. }
  489. }
  490.  
  491. static void twoxbr_generic_rgb565(unsigned width, unsigned height,
  492. int first, int last, uint16_t *src,
  493. unsigned src_stride, uint16_t *dst, unsigned dst_stride)
  494. {
  495. uint16_t pg_red_mask, pg_green_mask, pg_blue_mask, pg_lbmask;
  496. unsigned nextline, finish;
  497.  
  498. pg_red_mask = RED_MASK565;
  499. pg_green_mask = GREEN_MASK565;
  500. pg_blue_mask = BLUE_MASK565;
  501. pg_lbmask = PG_LBMASK565;
  502. nextline = (last) ? 0 : src_stride;
  503.  
  504. if (!initialized)
  505. {
  506. SetupFormat();
  507. initialized = 1;
  508. }
  509.  
  510. for (; height; height--)
  511. {
  512. uint16_t *in = (uint16_t*)src;
  513. uint16_t *out = (uint16_t*)dst;
  514.  
  515. for (finish = width; finish; finish -= 1)
  516. {
  517. twoxbr_declare_variables(uint16_t, in, nextline);
  518.  
  519. //---------------------------------------
  520. // Map of the pixels: A1 B1 C1
  521. // A0 PA PB PC C4
  522. // D0 PD PE PF F4
  523. // G0 PG PH PI I4
  524. // G5 H5 I5
  525.  
  526. twoxbr_function(FILTRO_RGB565);
  527. }
  528.  
  529. src += src_stride;
  530. dst += 2 * dst_stride;
  531. }
  532. }
  533.  
  534. static void twoxbr_work_cb_rgb565(void *data, void *thread_data)
  535. {
  536. struct softfilter_thread_data *thr = (struct softfilter_thread_data*)thread_data;
  537. uint16_t *input = (uint16_t*)thr->in_data;
  538. uint16_t *output = (uint16_t*)thr->out_data;
  539. unsigned width = thr->width;
  540. unsigned height = thr->height;
  541.  
  542. twoxbr_generic_rgb565(width, height,
  543. thr->first, thr->last, input, thr->in_pitch / SOFTFILTER_BPP_RGB565, output, thr->out_pitch / SOFTFILTER_BPP_RGB565);
  544. }
  545.  
  546. static void twoxbr_work_cb_xrgb8888(void *data, void *thread_data)
  547. {
  548. struct softfilter_thread_data *thr = (struct softfilter_thread_data*)thread_data;
  549. uint32_t *input = (uint32_t*)thr->in_data;
  550. uint32_t *output = (uint32_t*)thr->out_data;
  551. unsigned width = thr->width;
  552. unsigned height = thr->height;
  553.  
  554. twoxbr_generic_xrgb8888(width, height,
  555. thr->first, thr->last, input, thr->in_pitch / SOFTFILTER_BPP_XRGB8888, output, thr->out_pitch / SOFTFILTER_BPP_XRGB8888);
  556. }
  557.  
  558. static void twoxbr_generic_packets(void *data,
  559. struct softfilter_work_packet *packets,
  560. void *output, size_t output_stride,
  561. const void *input, unsigned width, unsigned height, size_t input_stride)
  562. {
  563. struct filter_data *filt = (struct filter_data*)data;
  564. unsigned i;
  565. for (i = 0; i < filt->threads; i++)
  566. {
  567. struct softfilter_thread_data *thr = (struct softfilter_thread_data*)&filt->workers[i];
  568.  
  569. unsigned y_start = (height * i) / filt->threads;
  570. unsigned y_end = (height * (i + 1)) / filt->threads;
  571. thr->out_data = (uint8_t*)output + y_start * TWOXBR_SCALE * output_stride;
  572. thr->in_data = (const uint8_t*)input + y_start * input_stride;
  573. thr->out_pitch = output_stride;
  574. thr->in_pitch = input_stride;
  575. thr->width = width;
  576. thr->height = y_end - y_start;
  577.  
  578. // Workers need to know if they can access pixels outside their given buffer.
  579. thr->first = y_start;
  580. thr->last = y_end == height;
  581.  
  582. if (filt->in_fmt == SOFTFILTER_FMT_RGB565)
  583. packets[i].work = twoxbr_work_cb_rgb565;
  584. //else if (filt->in_fmt == SOFTFILTER_FMT_RGB4444)
  585. //packets[i].work = twoxbr_work_cb_rgb4444;
  586. else if (filt->in_fmt == SOFTFILTER_FMT_XRGB8888)
  587. packets[i].work = twoxbr_work_cb_xrgb8888;
  588. packets[i].thread_data = thr;
  589. }
  590. }
  591.  
  592. static const struct softfilter_implementation twoxbr_generic = {
  593. twoxbr_generic_input_fmts,
  594. twoxbr_generic_output_fmts,
  595.  
  596. twoxbr_generic_create,
  597. twoxbr_generic_destroy,
  598.  
  599. twoxbr_generic_threads,
  600. twoxbr_generic_output,
  601. twoxbr_generic_packets,
  602. "2xBR",
  603. SOFTFILTER_API_VERSION,
  604. };
  605.  
  606. const struct softfilter_implementation *softfilter_get_implementation(softfilter_simd_mask_t simd)
  607. {
  608. (void)simd;
  609. return &twoxbr_generic;
  610. }
  611.  
  612. #ifdef RARCH_INTERNAL
  613. #undef softfilter_get_implementation
  614. #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement