You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

945 lines
22KB

  1. /*
  2. * yuv2rgb.c, Software YUV to RGB coverter
  3. *
  4. * Copyright (C) 1999, Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
  5. * All Rights Reserved.
  6. *
  7. * Functions broken out from display_x11.c and several new modes
  8. * added by HÃ¥kan Hjort <d95hjort@dtek.chalmers.se>
  9. *
  10. * 15 & 16 bpp support by Franck Sicard <Franck.Sicard@solsoft.fr>
  11. *
  12. * This file is part of mpeg2dec, a free MPEG-2 video decoder
  13. *
  14. * mpeg2dec is free software; you can redistribute it and/or modify
  15. * it under the terms of the GNU General Public License as published by
  16. * the Free Software Foundation; either version 2, or (at your option)
  17. * any later version.
  18. *
  19. * mpeg2dec is distributed in the hope that it will be useful,
  20. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  21. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  22. * GNU General Public License for more details.
  23. *
  24. * You should have received a copy of the GNU General Public License
  25. * along with GNU Make; see the file COPYING. If not, write to
  26. * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  27. *
  28. * MMX/MMX2 Template stuff from Michael Niedermayer (michaelni@gmx.at) (needed for fast movntq support)
  29. * 1,4,8bpp support by Michael Niedermayer (michaelni@gmx.at)
  30. */
  31. #include <stdio.h>
  32. #include <stdlib.h>
  33. #include <inttypes.h>
  34. #include "config.h"
  35. //#include "video_out.h"
  36. #include "rgb2rgb.h"
  37. #include "../cpudetect.h"
  38. #include "../mangle.h"
  39. #include "../mp_msg.h"
  40. #ifdef HAVE_MLIB
  41. #include "yuv2rgb_mlib.c"
  42. #endif
  43. #define DITHER1XBPP // only for mmx
  44. #ifdef ARCH_X86
  45. #define CAN_COMPILE_X86_ASM
  46. #endif
  47. const uint8_t __attribute__((aligned(8))) dither_2x2_4[2][8]={
  48. { 1, 3, 1, 3, 1, 3, 1, 3, },
  49. { 2, 0, 2, 0, 2, 0, 2, 0, },
  50. };
  51. const uint8_t __attribute__((aligned(8))) dither_2x2_8[2][8]={
  52. { 6, 2, 6, 2, 6, 2, 6, 2, },
  53. { 0, 4, 0, 4, 0, 4, 0, 4, },
  54. };
  55. const uint8_t __attribute__((aligned(8))) dither_8x8_32[8][8]={
  56. { 17, 9, 23, 15, 16, 8, 22, 14, },
  57. { 5, 29, 3, 27, 4, 28, 2, 26, },
  58. { 21, 13, 19, 11, 20, 12, 18, 10, },
  59. { 0, 24, 6, 30, 1, 25, 7, 31, },
  60. { 16, 8, 22, 14, 17, 9, 23, 15, },
  61. { 4, 28, 2, 26, 5, 29, 3, 27, },
  62. { 20, 12, 18, 10, 21, 13, 19, 11, },
  63. { 1, 25, 7, 31, 0, 24, 6, 30, },
  64. };
  65. #if 0
  66. const uint8_t __attribute__((aligned(8))) dither_8x8_64[8][8]={
  67. { 0, 48, 12, 60, 3, 51, 15, 63, },
  68. { 32, 16, 44, 28, 35, 19, 47, 31, },
  69. { 8, 56, 4, 52, 11, 59, 7, 55, },
  70. { 40, 24, 36, 20, 43, 27, 39, 23, },
  71. { 2, 50, 14, 62, 1, 49, 13, 61, },
  72. { 34, 18, 46, 30, 33, 17, 45, 29, },
  73. { 10, 58, 6, 54, 9, 57, 5, 53, },
  74. { 42, 26, 38, 22, 41, 25, 37, 21, },
  75. };
  76. #endif
  77. const uint8_t __attribute__((aligned(8))) dither_8x8_73[8][8]={
  78. { 0, 55, 14, 68, 3, 58, 17, 72, },
  79. { 37, 18, 50, 32, 40, 22, 54, 35, },
  80. { 9, 64, 5, 59, 13, 67, 8, 63, },
  81. { 46, 27, 41, 23, 49, 31, 44, 26, },
  82. { 2, 57, 16, 71, 1, 56, 15, 70, },
  83. { 39, 21, 52, 34, 38, 19, 51, 33, },
  84. { 11, 66, 7, 62, 10, 65, 6, 60, },
  85. { 48, 30, 43, 25, 47, 29, 42, 24, },
  86. };
  87. #if 0
  88. const uint8_t __attribute__((aligned(8))) dither_8x8_128[8][8]={
  89. { 68, 36, 92, 60, 66, 34, 90, 58, },
  90. { 20, 116, 12, 108, 18, 114, 10, 106, },
  91. { 84, 52, 76, 44, 82, 50, 74, 42, },
  92. { 0, 96, 24, 120, 6, 102, 30, 126, },
  93. { 64, 32, 88, 56, 70, 38, 94, 62, },
  94. { 16, 112, 8, 104, 22, 118, 14, 110, },
  95. { 80, 48, 72, 40, 86, 54, 78, 46, },
  96. { 4, 100, 28, 124, 2, 98, 26, 122, },
  97. };
  98. #endif
  99. #if 1
  100. const uint8_t __attribute__((aligned(8))) dither_8x8_220[8][8]={
  101. {117, 62, 158, 103, 113, 58, 155, 100, },
  102. { 34, 199, 21, 186, 31, 196, 17, 182, },
  103. {144, 89, 131, 76, 141, 86, 127, 72, },
  104. { 0, 165, 41, 206, 10, 175, 52, 217, },
  105. {110, 55, 151, 96, 120, 65, 162, 107, },
  106. { 28, 193, 14, 179, 38, 203, 24, 189, },
  107. {138, 83, 124, 69, 148, 93, 134, 79, },
  108. { 7, 172, 48, 213, 3, 168, 45, 210, },
  109. };
  110. #elif 1
  111. // tries to correct a gamma of 1.5
  112. const uint8_t __attribute__((aligned(8))) dither_8x8_220[8][8]={
  113. { 0, 143, 18, 200, 2, 156, 25, 215, },
  114. { 78, 28, 125, 64, 89, 36, 138, 74, },
  115. { 10, 180, 3, 161, 16, 195, 8, 175, },
  116. {109, 51, 93, 38, 121, 60, 105, 47, },
  117. { 1, 152, 23, 210, 0, 147, 20, 205, },
  118. { 85, 33, 134, 71, 81, 30, 130, 67, },
  119. { 14, 190, 6, 171, 12, 185, 5, 166, },
  120. {117, 57, 101, 44, 113, 54, 97, 41, },
  121. };
  122. #elif 1
  123. // tries to correct a gamma of 2.0
  124. const uint8_t __attribute__((aligned(8))) dither_8x8_220[8][8]={
  125. { 0, 124, 8, 193, 0, 140, 12, 213, },
  126. { 55, 14, 104, 42, 66, 19, 119, 52, },
  127. { 3, 168, 1, 145, 6, 187, 3, 162, },
  128. { 86, 31, 70, 21, 99, 39, 82, 28, },
  129. { 0, 134, 11, 206, 0, 129, 9, 200, },
  130. { 62, 17, 114, 48, 58, 16, 109, 45, },
  131. { 5, 181, 2, 157, 4, 175, 1, 151, },
  132. { 95, 36, 78, 26, 90, 34, 74, 24, },
  133. };
  134. #else
  135. // tries to correct a gamma of 2.5
  136. const uint8_t __attribute__((aligned(8))) dither_8x8_220[8][8]={
  137. { 0, 107, 3, 187, 0, 125, 6, 212, },
  138. { 39, 7, 86, 28, 49, 11, 102, 36, },
  139. { 1, 158, 0, 131, 3, 180, 1, 151, },
  140. { 68, 19, 52, 12, 81, 25, 64, 17, },
  141. { 0, 119, 5, 203, 0, 113, 4, 195, },
  142. { 45, 9, 96, 33, 42, 8, 91, 30, },
  143. { 2, 172, 1, 144, 2, 165, 0, 137, },
  144. { 77, 23, 60, 15, 72, 21, 56, 14, },
  145. };
  146. #endif
  147. #ifdef CAN_COMPILE_X86_ASM
  148. /* hope these constant values are cache line aligned */
  149. uint64_t __attribute__((aligned(8))) mmx_80w = 0x0080008000800080;
  150. uint64_t __attribute__((aligned(8))) mmx_10w = 0x1010101010101010;
  151. uint64_t __attribute__((aligned(8))) mmx_00ffw = 0x00ff00ff00ff00ff;
  152. uint64_t __attribute__((aligned(8))) mmx_Y_coeff = 0x253f253f253f253f;
  153. /* hope these constant values are cache line aligned */
  154. uint64_t __attribute__((aligned(8))) mmx_U_green = 0xf37df37df37df37d;
  155. uint64_t __attribute__((aligned(8))) mmx_U_blue = 0x4093409340934093;
  156. uint64_t __attribute__((aligned(8))) mmx_V_red = 0x3312331233123312;
  157. uint64_t __attribute__((aligned(8))) mmx_V_green = 0xe5fce5fce5fce5fc;
  158. /* hope these constant values are cache line aligned */
  159. uint64_t __attribute__((aligned(8))) mmx_redmask = 0xf8f8f8f8f8f8f8f8;
  160. uint64_t __attribute__((aligned(8))) mmx_grnmask = 0xfcfcfcfcfcfcfcfc;
  161. uint64_t __attribute__((aligned(8))) M24A= 0x00FF0000FF0000FFLL;
  162. uint64_t __attribute__((aligned(8))) M24B= 0xFF0000FF0000FF00LL;
  163. uint64_t __attribute__((aligned(8))) M24C= 0x0000FF0000FF0000LL;
  164. // the volatile is required because gcc otherwise optimizes some writes away not knowing that these
  165. // are read in the asm block
  166. volatile uint64_t __attribute__((aligned(8))) b5Dither;
  167. volatile uint64_t __attribute__((aligned(8))) g5Dither;
  168. volatile uint64_t __attribute__((aligned(8))) g6Dither;
  169. volatile uint64_t __attribute__((aligned(8))) r5Dither;
  170. uint64_t __attribute__((aligned(8))) dither4[2]={
  171. 0x0103010301030103LL,
  172. 0x0200020002000200LL,};
  173. uint64_t __attribute__((aligned(8))) dither8[2]={
  174. 0x0602060206020602LL,
  175. 0x0004000400040004LL,};
  176. #undef HAVE_MMX
  177. #undef ARCH_X86
  178. //MMX versions
  179. #undef RENAME
  180. #define HAVE_MMX
  181. #undef HAVE_MMX2
  182. #undef HAVE_3DNOW
  183. #define ARCH_X86
  184. #define RENAME(a) a ## _MMX
  185. #include "yuv2rgb_template.c"
  186. //MMX2 versions
  187. #undef RENAME
  188. #define HAVE_MMX
  189. #define HAVE_MMX2
  190. #undef HAVE_3DNOW
  191. #define ARCH_X86
  192. #define RENAME(a) a ## _MMX2
  193. #include "yuv2rgb_template.c"
  194. #endif // CAN_COMPILE_X86_ASM
  195. uint32_t matrix_coefficients = 6;
  196. const int32_t Inverse_Table_6_9[8][4] = {
  197. {117504, 138453, 13954, 34903}, /* no sequence_display_extension */
  198. {117504, 138453, 13954, 34903}, /* ITU-R Rec. 709 (1990) */
  199. {104597, 132201, 25675, 53279}, /* unspecified */
  200. {104597, 132201, 25675, 53279}, /* reserved */
  201. {104448, 132798, 24759, 53109}, /* FCC */
  202. {104597, 132201, 25675, 53279}, /* ITU-R Rec. 624-4 System B, G */
  203. {104597, 132201, 25675, 53279}, /* SMPTE 170M */
  204. {117579, 136230, 16907, 35559} /* SMPTE 240M (1987) */
  205. };
  206. void *yuv2rgb_c_init (unsigned bpp, int mode, void *table_rV[256], void *table_gU[256], int table_gV[256], void *table_bU[256]);
  207. yuv2rgb_fun yuv2rgb= NULL;
  208. static void (* yuv2rgb_c_internal) (uint8_t *, uint8_t *,
  209. uint8_t *, uint8_t *,
  210. void *, void *, int, int);
  211. static void yuv2rgb_c (void * dst, uint8_t * py,
  212. uint8_t * pu, uint8_t * pv,
  213. unsigned h_size, unsigned v_size,
  214. unsigned rgb_stride, unsigned y_stride, unsigned uv_stride)
  215. {
  216. v_size >>= 1;
  217. while (v_size--) {
  218. yuv2rgb_c_internal (py, py + y_stride, pu, pv, dst, dst + rgb_stride,
  219. h_size, v_size<<1);
  220. py += 2 * y_stride;
  221. pu += uv_stride;
  222. pv += uv_stride;
  223. dst += 2 * rgb_stride;
  224. }
  225. }
  226. void * table_rV[256];
  227. void * table_gU[256];
  228. int table_gV[256];
  229. void * table_bU[256];
  230. void yuv2rgb_init (unsigned bpp, int mode)
  231. {
  232. if(yuv2rgb) return;
  233. #ifdef CAN_COMPILE_X86_ASM
  234. if(gCpuCaps.hasMMX2)
  235. {
  236. if (yuv2rgb == NULL /*&& (config.flags & VO_MMX_ENABLE)*/) {
  237. yuv2rgb = yuv2rgb_init_MMX2 (bpp, mode);
  238. if (yuv2rgb != NULL)
  239. mp_msg(MSGT_SWS,MSGL_INFO,"Using MMX2 for colorspace transform\n");
  240. else
  241. mp_msg(MSGT_SWS,MSGL_WARN,"Cannot init MMX2 colorspace transform\n");
  242. }
  243. }
  244. else if(gCpuCaps.hasMMX)
  245. {
  246. if (yuv2rgb == NULL /*&& (config.flags & VO_MMX_ENABLE)*/) {
  247. yuv2rgb = yuv2rgb_init_MMX (bpp, mode);
  248. if (yuv2rgb != NULL)
  249. mp_msg(MSGT_SWS,MSGL_INFO,"Using MMX for colorspace transform\n");
  250. else
  251. mp_msg(MSGT_SWS,MSGL_WARN,"Cannot init MMX colorspace transform\n");
  252. }
  253. }
  254. #endif
  255. #ifdef HAVE_MLIB
  256. if (yuv2rgb == NULL /*&& (config.flags & VO_MLIB_ENABLE)*/) {
  257. yuv2rgb = yuv2rgb_init_mlib (bpp, mode);
  258. if (yuv2rgb != NULL)
  259. mp_msg(MSGT_SWS,MSGL_INFO,"Using mlib for colorspace transform\n");
  260. }
  261. #endif
  262. if (yuv2rgb == NULL) {
  263. mp_msg(MSGT_SWS,MSGL_INFO,"No accelerated colorspace conversion found\n");
  264. yuv2rgb_c_init (bpp, mode, table_rV, table_gU, table_gV, table_bU);
  265. yuv2rgb = (yuv2rgb_fun)yuv2rgb_c;
  266. }
  267. }
  268. #define RGB(i) \
  269. U = pu[i]; \
  270. V = pv[i]; \
  271. r = table_rV[V]; \
  272. g = table_gU[U] + table_gV[V]; \
  273. b = table_bU[U];
  274. #define DST1(i) \
  275. Y = py_1[2*i]; \
  276. dst_1[2*i] = r[Y] + g[Y] + b[Y]; \
  277. Y = py_1[2*i+1]; \
  278. dst_1[2*i+1] = r[Y] + g[Y] + b[Y];
  279. #define DST2(i) \
  280. Y = py_2[2*i]; \
  281. dst_2[2*i] = r[Y] + g[Y] + b[Y]; \
  282. Y = py_2[2*i+1]; \
  283. dst_2[2*i+1] = r[Y] + g[Y] + b[Y];
  284. #define DST1RGB(i) \
  285. Y = py_1[2*i]; \
  286. dst_1[6*i] = r[Y]; dst_1[6*i+1] = g[Y]; dst_1[6*i+2] = b[Y]; \
  287. Y = py_1[2*i+1]; \
  288. dst_1[6*i+3] = r[Y]; dst_1[6*i+4] = g[Y]; dst_1[6*i+5] = b[Y];
  289. #define DST2RGB(i) \
  290. Y = py_2[2*i]; \
  291. dst_2[6*i] = r[Y]; dst_2[6*i+1] = g[Y]; dst_2[6*i+2] = b[Y]; \
  292. Y = py_2[2*i+1]; \
  293. dst_2[6*i+3] = r[Y]; dst_2[6*i+4] = g[Y]; dst_2[6*i+5] = b[Y];
  294. #define DST1BGR(i) \
  295. Y = py_1[2*i]; \
  296. dst_1[6*i] = b[Y]; dst_1[6*i+1] = g[Y]; dst_1[6*i+2] = r[Y]; \
  297. Y = py_1[2*i+1]; \
  298. dst_1[6*i+3] = b[Y]; dst_1[6*i+4] = g[Y]; dst_1[6*i+5] = r[Y];
  299. #define DST2BGR(i) \
  300. Y = py_2[2*i]; \
  301. dst_2[6*i] = b[Y]; dst_2[6*i+1] = g[Y]; dst_2[6*i+2] = r[Y]; \
  302. Y = py_2[2*i+1]; \
  303. dst_2[6*i+3] = b[Y]; dst_2[6*i+4] = g[Y]; dst_2[6*i+5] = r[Y];
  304. static void yuv2rgb_c_32 (uint8_t * py_1, uint8_t * py_2,
  305. uint8_t * pu, uint8_t * pv,
  306. void * _dst_1, void * _dst_2, int h_size, int v_pos)
  307. {
  308. int U, V, Y;
  309. uint32_t * r, * g, * b;
  310. uint32_t * dst_1, * dst_2;
  311. h_size >>= 3;
  312. dst_1 = _dst_1;
  313. dst_2 = _dst_2;
  314. while (h_size--) {
  315. RGB(0);
  316. DST1(0);
  317. DST2(0);
  318. RGB(1);
  319. DST2(1);
  320. DST1(1);
  321. RGB(2);
  322. DST1(2);
  323. DST2(2);
  324. RGB(3);
  325. DST2(3);
  326. DST1(3);
  327. pu += 4;
  328. pv += 4;
  329. py_1 += 8;
  330. py_2 += 8;
  331. dst_1 += 8;
  332. dst_2 += 8;
  333. }
  334. }
  335. // This is very near from the yuv2rgb_c_32 code
  336. static void yuv2rgb_c_24_rgb (uint8_t * py_1, uint8_t * py_2,
  337. uint8_t * pu, uint8_t * pv,
  338. void * _dst_1, void * _dst_2, int h_size, int v_pos)
  339. {
  340. int U, V, Y;
  341. uint8_t * r, * g, * b;
  342. uint8_t * dst_1, * dst_2;
  343. h_size >>= 3;
  344. dst_1 = _dst_1;
  345. dst_2 = _dst_2;
  346. while (h_size--) {
  347. RGB(0);
  348. DST1RGB(0);
  349. DST2RGB(0);
  350. RGB(1);
  351. DST2RGB(1);
  352. DST1RGB(1);
  353. RGB(2);
  354. DST1RGB(2);
  355. DST2RGB(2);
  356. RGB(3);
  357. DST2RGB(3);
  358. DST1RGB(3);
  359. pu += 4;
  360. pv += 4;
  361. py_1 += 8;
  362. py_2 += 8;
  363. dst_1 += 24;
  364. dst_2 += 24;
  365. }
  366. }
  367. // only trivial mods from yuv2rgb_c_24_rgb
  368. static void yuv2rgb_c_24_bgr (uint8_t * py_1, uint8_t * py_2,
  369. uint8_t * pu, uint8_t * pv,
  370. void * _dst_1, void * _dst_2, int h_size, int v_pos)
  371. {
  372. int U, V, Y;
  373. uint8_t * r, * g, * b;
  374. uint8_t * dst_1, * dst_2;
  375. h_size >>= 3;
  376. dst_1 = _dst_1;
  377. dst_2 = _dst_2;
  378. while (h_size--) {
  379. RGB(0);
  380. DST1BGR(0);
  381. DST2BGR(0);
  382. RGB(1);
  383. DST2BGR(1);
  384. DST1BGR(1);
  385. RGB(2);
  386. DST1BGR(2);
  387. DST2BGR(2);
  388. RGB(3);
  389. DST2BGR(3);
  390. DST1BGR(3);
  391. pu += 4;
  392. pv += 4;
  393. py_1 += 8;
  394. py_2 += 8;
  395. dst_1 += 24;
  396. dst_2 += 24;
  397. }
  398. }
  399. // This is exactly the same code as yuv2rgb_c_32 except for the types of
  400. // r, g, b, dst_1, dst_2
  401. static void yuv2rgb_c_16 (uint8_t * py_1, uint8_t * py_2,
  402. uint8_t * pu, uint8_t * pv,
  403. void * _dst_1, void * _dst_2, int h_size, int v_pos)
  404. {
  405. int U, V, Y;
  406. uint16_t * r, * g, * b;
  407. uint16_t * dst_1, * dst_2;
  408. h_size >>= 3;
  409. dst_1 = _dst_1;
  410. dst_2 = _dst_2;
  411. while (h_size--) {
  412. RGB(0);
  413. DST1(0);
  414. DST2(0);
  415. RGB(1);
  416. DST2(1);
  417. DST1(1);
  418. RGB(2);
  419. DST1(2);
  420. DST2(2);
  421. RGB(3);
  422. DST2(3);
  423. DST1(3);
  424. pu += 4;
  425. pv += 4;
  426. py_1 += 8;
  427. py_2 += 8;
  428. dst_1 += 8;
  429. dst_2 += 8;
  430. }
  431. }
  432. // This is exactly the same code as yuv2rgb_c_32 except for the types of
  433. // r, g, b, dst_1, dst_2
  434. static void yuv2rgb_c_8 (uint8_t * py_1, uint8_t * py_2,
  435. uint8_t * pu, uint8_t * pv,
  436. void * _dst_1, void * _dst_2, int h_size, int v_pos)
  437. {
  438. int U, V, Y;
  439. uint8_t * r, * g, * b;
  440. uint8_t * dst_1, * dst_2;
  441. h_size >>= 3;
  442. dst_1 = _dst_1;
  443. dst_2 = _dst_2;
  444. while (h_size--) {
  445. RGB(0);
  446. DST1(0);
  447. DST2(0);
  448. RGB(1);
  449. DST2(1);
  450. DST1(1);
  451. RGB(2);
  452. DST1(2);
  453. DST2(2);
  454. RGB(3);
  455. DST2(3);
  456. DST1(3);
  457. pu += 4;
  458. pv += 4;
  459. py_1 += 8;
  460. py_2 += 8;
  461. dst_1 += 8;
  462. dst_2 += 8;
  463. }
  464. }
  465. // r, g, b, dst_1, dst_2
  466. static void yuv2rgb_c_8_ordered_dither (uint8_t * py_1, uint8_t * py_2,
  467. uint8_t * pu, uint8_t * pv,
  468. void * _dst_1, void * _dst_2, int h_size, int v_pos)
  469. {
  470. int U, V, Y;
  471. uint8_t * r, * g, * b;
  472. uint8_t * dst_1, * dst_2;
  473. h_size >>= 3;
  474. dst_1 = _dst_1;
  475. dst_2 = _dst_2;
  476. while (h_size--) {
  477. const uint8_t *d32= dither_8x8_32[v_pos&7];
  478. const uint8_t *d64= dither_8x8_73[v_pos&7];
  479. #define DST1bpp8(i,o) \
  480. Y = py_1[2*i]; \
  481. dst_1[2*i] = r[Y+d32[0+o]] + g[Y+d32[0+o]] + b[Y+d64[0+o]]; \
  482. Y = py_1[2*i+1]; \
  483. dst_1[2*i+1] = r[Y+d32[1+o]] + g[Y+d32[1+o]] + b[Y+d64[1+o]];
  484. #define DST2bpp8(i,o) \
  485. Y = py_2[2*i]; \
  486. dst_2[2*i] = r[Y+d32[8+o]] + g[Y+d32[8+o]] + b[Y+d64[8+o]]; \
  487. Y = py_2[2*i+1]; \
  488. dst_2[2*i+1] = r[Y+d32[9+o]] + g[Y+d32[9+o]] + b[Y+d64[9+o]];
  489. RGB(0);
  490. DST1bpp8(0,0);
  491. DST2bpp8(0,0);
  492. RGB(1);
  493. DST2bpp8(1,2);
  494. DST1bpp8(1,2);
  495. RGB(2);
  496. DST1bpp8(2,4);
  497. DST2bpp8(2,4);
  498. RGB(3);
  499. DST2bpp8(3,6);
  500. DST1bpp8(3,6);
  501. pu += 4;
  502. pv += 4;
  503. py_1 += 8;
  504. py_2 += 8;
  505. dst_1 += 8;
  506. dst_2 += 8;
  507. }
  508. }
  509. // This is exactly the same code as yuv2rgb_c_32 except for the types of
  510. // r, g, b, dst_1, dst_2
  511. static void yuv2rgb_c_4 (uint8_t * py_1, uint8_t * py_2,
  512. uint8_t * pu, uint8_t * pv,
  513. void * _dst_1, void * _dst_2, int h_size, int v_pos)
  514. {
  515. int U, V, Y;
  516. uint8_t * r, * g, * b;
  517. uint8_t * dst_1, * dst_2;
  518. h_size >>= 3;
  519. dst_1 = _dst_1;
  520. dst_2 = _dst_2;
  521. while (h_size--) {
  522. RGB(0);
  523. DST1(0);
  524. DST2(0);
  525. RGB(1);
  526. DST2(1);
  527. DST1(1);
  528. RGB(2);
  529. DST1(2);
  530. DST2(2);
  531. RGB(3);
  532. DST2(3);
  533. DST1(3);
  534. pu += 4;
  535. pv += 4;
  536. py_1 += 8;
  537. py_2 += 8;
  538. dst_1 += 8;
  539. dst_2 += 8;
  540. }
  541. }
  542. static void yuv2rgb_c_4_ordered_dither (uint8_t * py_1, uint8_t * py_2,
  543. uint8_t * pu, uint8_t * pv,
  544. void * _dst_1, void * _dst_2, int h_size, int v_pos)
  545. {
  546. int U, V, Y;
  547. uint8_t * r, * g, * b;
  548. uint8_t * dst_1, * dst_2;
  549. h_size >>= 3;
  550. dst_1 = _dst_1;
  551. dst_2 = _dst_2;
  552. while (h_size--) {
  553. const uint8_t *d64= dither_8x8_73[v_pos&7];
  554. const uint8_t *d128=dither_8x8_220[v_pos&7];
  555. #define DST1bpp4(i,o) \
  556. Y = py_1[2*i]; \
  557. dst_1[2*i] = r[Y+d128[0+o]] + g[Y+d64[0+o]] + b[Y+d128[0+o]]; \
  558. Y = py_1[2*i+1]; \
  559. dst_1[2*i+1] = r[Y+d128[1+o]] + g[Y+d64[1+o]] + b[Y+d128[1+o]];
  560. #define DST2bpp4(i,o) \
  561. Y = py_2[2*i]; \
  562. dst_2[2*i] = r[Y+d128[8+o]] + g[Y+d64[8+o]] + b[Y+d128[8+o]]; \
  563. Y = py_2[2*i+1]; \
  564. dst_2[2*i+1] = r[Y+d128[9+o]] + g[Y+d64[9+o]] + b[Y+d128[9+o]];
  565. RGB(0);
  566. DST1bpp4(0,0);
  567. DST2bpp4(0,0);
  568. RGB(1);
  569. DST2bpp4(1,2);
  570. DST1bpp4(1,2);
  571. RGB(2);
  572. DST1bpp4(2,4);
  573. DST2bpp4(2,4);
  574. RGB(3);
  575. DST2bpp4(3,6);
  576. DST1bpp4(3,6);
  577. pu += 4;
  578. pv += 4;
  579. py_1 += 8;
  580. py_2 += 8;
  581. dst_1 += 8;
  582. dst_2 += 8;
  583. }
  584. }
  585. static void yuv2rgb_c_1_ordered_dither (uint8_t * py_1, uint8_t * py_2,
  586. uint8_t * pu, uint8_t * pv,
  587. void * _dst_1, void * _dst_2, int h_size, int v_pos)
  588. {
  589. int Y;
  590. uint8_t * g;
  591. uint8_t * dst_1, * dst_2;
  592. h_size >>= 3;
  593. dst_1 = _dst_1;
  594. dst_2 = _dst_2;
  595. g= table_gU[128] + table_gV[128];
  596. while (h_size--) {
  597. const uint8_t *d128=dither_8x8_220[v_pos&7];
  598. char out_1=0, out_2=0;
  599. #define DST1bpp1(i,o) \
  600. Y = py_1[2*i]; \
  601. out_1+= out_1 + g[Y+d128[0+o]]; \
  602. Y = py_1[2*i+1]; \
  603. out_1+= out_1 + g[Y+d128[1+o]];
  604. #define DST2bpp1(i,o) \
  605. Y = py_2[2*i]; \
  606. out_2+= out_2 + g[Y+d128[8+o]]; \
  607. Y = py_2[2*i+1]; \
  608. out_2+= out_2 + g[Y+d128[9+o]];
  609. DST1bpp1(0,0);
  610. DST2bpp1(0,0);
  611. DST2bpp1(1,2);
  612. DST1bpp1(1,2);
  613. DST1bpp1(2,4);
  614. DST2bpp1(2,4);
  615. DST2bpp1(3,6);
  616. DST1bpp1(3,6);
  617. dst_1[0]= out_1;
  618. dst_2[0]= out_2;
  619. pu += 4;
  620. pv += 4;
  621. py_1 += 8;
  622. py_2 += 8;
  623. dst_1 ++;
  624. dst_2 ++;
  625. }
  626. }
  627. static int div_round (int dividend, int divisor)
  628. {
  629. if (dividend > 0)
  630. return (dividend + (divisor>>1)) / divisor;
  631. else
  632. return -((-dividend + (divisor>>1)) / divisor);
  633. }
  634. void *yuv2rgb_c_init (unsigned bpp, int mode, void *table_rV[256], void *table_gU[256], int table_gV[256], void *table_bU[256])
  635. {
  636. int i;
  637. uint8_t table_Y[1024];
  638. uint32_t *table_32 = 0;
  639. uint16_t *table_16 = 0;
  640. uint8_t *table_8 = 0;
  641. uint8_t *table_332 = 0;
  642. uint8_t *table_121 = 0;
  643. uint8_t *table_1 = 0;
  644. int entry_size = 0;
  645. void *table_r = 0, *table_g = 0, *table_b = 0;
  646. void *table_start;
  647. int crv = Inverse_Table_6_9[matrix_coefficients][0];
  648. int cbu = Inverse_Table_6_9[matrix_coefficients][1];
  649. int cgu = -Inverse_Table_6_9[matrix_coefficients][2];
  650. int cgv = -Inverse_Table_6_9[matrix_coefficients][3];
  651. for (i = 0; i < 1024; i++) {
  652. int j;
  653. j = (76309 * (i - 384 - 16) + 32768) >> 16;
  654. j = (j < 0) ? 0 : ((j > 255) ? 255 : j);
  655. table_Y[i] = j;
  656. }
  657. switch (bpp) {
  658. case 32:
  659. yuv2rgb_c_internal = yuv2rgb_c_32;
  660. table_start= table_32 = malloc ((197 + 2*682 + 256 + 132) * sizeof (uint32_t));
  661. entry_size = sizeof (uint32_t);
  662. table_r = table_32 + 197;
  663. table_b = table_32 + 197 + 685;
  664. table_g = table_32 + 197 + 2*682;
  665. for (i = -197; i < 256+197; i++)
  666. ((uint32_t *)table_r)[i] = table_Y[i+384] << ((mode==MODE_RGB) ? 16 : 0);
  667. for (i = -132; i < 256+132; i++)
  668. ((uint32_t *)table_g)[i] = table_Y[i+384] << 8;
  669. for (i = -232; i < 256+232; i++)
  670. ((uint32_t *)table_b)[i] = table_Y[i+384] << ((mode==MODE_RGB) ? 0 : 16);
  671. break;
  672. case 24:
  673. // yuv2rgb_c_internal = (mode==MODE_RGB) ? yuv2rgb_c_24_rgb : yuv2rgb_c_24_bgr;
  674. yuv2rgb_c_internal = (mode!=MODE_RGB) ? yuv2rgb_c_24_rgb : yuv2rgb_c_24_bgr;
  675. table_start= table_8 = malloc ((256 + 2*232) * sizeof (uint8_t));
  676. entry_size = sizeof (uint8_t);
  677. table_r = table_g = table_b = table_8 + 232;
  678. for (i = -232; i < 256+232; i++)
  679. ((uint8_t * )table_b)[i] = table_Y[i+384];
  680. break;
  681. case 15:
  682. case 16:
  683. yuv2rgb_c_internal = yuv2rgb_c_16;
  684. table_start= table_16 = malloc ((197 + 2*682 + 256 + 132) * sizeof (uint16_t));
  685. entry_size = sizeof (uint16_t);
  686. table_r = table_16 + 197;
  687. table_b = table_16 + 197 + 685;
  688. table_g = table_16 + 197 + 2*682;
  689. for (i = -197; i < 256+197; i++) {
  690. int j = table_Y[i+384] >> 3;
  691. if (mode == MODE_RGB)
  692. j <<= ((bpp==16) ? 11 : 10);
  693. ((uint16_t *)table_r)[i] = j;
  694. }
  695. for (i = -132; i < 256+132; i++) {
  696. int j = table_Y[i+384] >> ((bpp==16) ? 2 : 3);
  697. ((uint16_t *)table_g)[i] = j << 5;
  698. }
  699. for (i = -232; i < 256+232; i++) {
  700. int j = table_Y[i+384] >> 3;
  701. if (mode == MODE_BGR)
  702. j <<= ((bpp==16) ? 11 : 10);
  703. ((uint16_t *)table_b)[i] = j;
  704. }
  705. break;
  706. case 8:
  707. yuv2rgb_c_internal = yuv2rgb_c_8_ordered_dither; //yuv2rgb_c_8;
  708. table_start= table_332 = malloc ((197 + 2*682 + 256 + 132) * sizeof (uint8_t));
  709. entry_size = sizeof (uint8_t);
  710. table_r = table_332 + 197;
  711. table_b = table_332 + 197 + 685;
  712. table_g = table_332 + 197 + 2*682;
  713. for (i = -197; i < 256+197; i++) {
  714. int j = (table_Y[i+384 - 16] + 18)/36;
  715. if (mode == MODE_RGB)
  716. j <<= 5;
  717. ((uint8_t *)table_r)[i] = j;
  718. }
  719. for (i = -132; i < 256+132; i++) {
  720. int j = (table_Y[i+384 - 16] + 18)/36;
  721. if (mode == MODE_BGR)
  722. j <<= 1;
  723. ((uint8_t *)table_g)[i] = j << 2;
  724. }
  725. for (i = -232; i < 256+232; i++) {
  726. int j = (table_Y[i+384 - 37] + 43)/85;
  727. if (mode == MODE_BGR)
  728. j <<= 6;
  729. ((uint8_t *)table_b)[i] = j;
  730. }
  731. break;
  732. case 4:
  733. yuv2rgb_c_internal = yuv2rgb_c_4_ordered_dither; //yuv2rgb_c_4;
  734. table_start= table_121 = malloc ((197 + 2*682 + 256 + 132) * sizeof (uint8_t));
  735. entry_size = sizeof (uint8_t);
  736. table_r = table_121 + 197;
  737. table_b = table_121 + 197 + 685;
  738. table_g = table_121 + 197 + 2*682;
  739. for (i = -197; i < 256+197; i++) {
  740. int j = table_Y[i+384 - 110] >> 7;
  741. if (mode == MODE_RGB)
  742. j <<= 3;
  743. ((uint8_t *)table_r)[i] = j;
  744. }
  745. for (i = -132; i < 256+132; i++) {
  746. int j = (table_Y[i+384 - 37]+ 43)/85;
  747. ((uint8_t *)table_g)[i] = j << 1;
  748. }
  749. for (i = -232; i < 256+232; i++) {
  750. int j =table_Y[i+384 - 110] >> 7;
  751. if (mode == MODE_BGR)
  752. j <<= 3;
  753. ((uint8_t *)table_b)[i] = j;
  754. }
  755. break;
  756. case 1:
  757. yuv2rgb_c_internal = yuv2rgb_c_1_ordered_dither;
  758. table_start= table_1 = malloc (256*2 * sizeof (uint8_t));
  759. entry_size = sizeof (uint8_t);
  760. table_g = table_1;
  761. table_r = table_b = NULL;
  762. for (i = 0; i < 256+256; i++) {
  763. int j = table_Y[i + 384 - 110]>>7;
  764. ((uint8_t *)table_g)[i] = j;
  765. }
  766. break;
  767. default:
  768. table_start= NULL;
  769. mp_msg(MSGT_SWS,MSGL_ERR,"%ibpp not supported by yuv2rgb\n", bpp);
  770. //exit (1);
  771. }
  772. for (i = 0; i < 256; i++) {
  773. table_rV[i] = table_r + entry_size * div_round (crv * (i-128), 76309);
  774. table_gU[i] = table_g + entry_size * div_round (cgu * (i-128), 76309);
  775. table_gV[i] = entry_size * div_round (cgv * (i-128), 76309);
  776. table_bU[i] = table_b + entry_size * div_round (cbu * (i-128), 76309);
  777. }
  778. return table_start;
  779. }