PageRenderTime 68ms CodeModel.GetById 33ms RepoModel.GetById 1ms app.codeStats 0ms

/lib/ffmpeg/libswscale/rgb2rgb_template.c

https://bitbucket.org/bgiorgini/xbmc
C | 921 lines | 772 code | 81 blank | 68 comment | 59 complexity | 7cef19e02ef33462b351620e7a5bc131 MD5 | raw file
Possible License(s): GPL-3.0, CC-BY-SA-3.0, BSD-3-Clause, GPL-2.0, LGPL-3.0, 0BSD, LGPL-2.0, AGPL-1.0, LGPL-2.1
  1. /*
  2. * software RGB to RGB converter
  3. * pluralize by software PAL8 to RGB converter
  4. * software YUV to YUV converter
  5. * software YUV to RGB converter
  6. * Written by Nick Kurshev.
  7. * palette & YUV & runtime CPU stuff by Michael (michaelni@gmx.at)
  8. * lot of big-endian byte order fixes by Alex Beregszaszi
  9. *
  10. * This file is part of FFmpeg.
  11. *
  12. * FFmpeg is free software; you can redistribute it and/or
  13. * modify it under the terms of the GNU Lesser General Public
  14. * License as published by the Free Software Foundation; either
  15. * version 2.1 of the License, or (at your option) any later version.
  16. *
  17. * FFmpeg is distributed in the hope that it will be useful,
  18. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  20. * Lesser General Public License for more details.
  21. *
  22. * You should have received a copy of the GNU Lesser General Public
  23. * License along with FFmpeg; if not, write to the Free Software
  24. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  25. */
  26. #include <stddef.h>
  27. static inline void rgb24tobgr32_c(const uint8_t *src, uint8_t *dst, int src_size)
  28. {
  29. uint8_t *dest = dst;
  30. const uint8_t *s = src;
  31. const uint8_t *end;
  32. end = s + src_size;
  33. while (s < end) {
  34. #if HAVE_BIGENDIAN
  35. /* RGB24 (= R,G,B) -> RGB32 (= A,B,G,R) */
  36. *dest++ = 255;
  37. *dest++ = s[2];
  38. *dest++ = s[1];
  39. *dest++ = s[0];
  40. s+=3;
  41. #else
  42. *dest++ = *s++;
  43. *dest++ = *s++;
  44. *dest++ = *s++;
  45. *dest++ = 255;
  46. #endif
  47. }
  48. }
  49. static inline void rgb32tobgr24_c(const uint8_t *src, uint8_t *dst, int src_size)
  50. {
  51. uint8_t *dest = dst;
  52. const uint8_t *s = src;
  53. const uint8_t *end;
  54. end = s + src_size;
  55. while (s < end) {
  56. #if HAVE_BIGENDIAN
  57. /* RGB32 (= A,B,G,R) -> RGB24 (= R,G,B) */
  58. s++;
  59. dest[2] = *s++;
  60. dest[1] = *s++;
  61. dest[0] = *s++;
  62. dest += 3;
  63. #else
  64. *dest++ = *s++;
  65. *dest++ = *s++;
  66. *dest++ = *s++;
  67. s++;
  68. #endif
  69. }
  70. }
  71. /*
  72. original by Strepto/Astral
  73. ported to gcc & bugfixed: A'rpi
  74. MMX2, 3DNOW optimization by Nick Kurshev
  75. 32-bit C version, and and&add trick by Michael Niedermayer
  76. */
  77. static inline void rgb15to16_c(const uint8_t *src, uint8_t *dst, int src_size)
  78. {
  79. register const uint8_t* s=src;
  80. register uint8_t* d=dst;
  81. register const uint8_t *end;
  82. const uint8_t *mm_end;
  83. end = s + src_size;
  84. mm_end = end - 3;
  85. while (s < mm_end) {
  86. register unsigned x= *((const uint32_t *)s);
  87. *((uint32_t *)d) = (x&0x7FFF7FFF) + (x&0x7FE07FE0);
  88. d+=4;
  89. s+=4;
  90. }
  91. if (s < end) {
  92. register unsigned short x= *((const uint16_t *)s);
  93. *((uint16_t *)d) = (x&0x7FFF) + (x&0x7FE0);
  94. }
  95. }
  96. static inline void rgb16to15_c(const uint8_t *src, uint8_t *dst, int src_size)
  97. {
  98. register const uint8_t* s=src;
  99. register uint8_t* d=dst;
  100. register const uint8_t *end;
  101. const uint8_t *mm_end;
  102. end = s + src_size;
  103. mm_end = end - 3;
  104. while (s < mm_end) {
  105. register uint32_t x= *((const uint32_t*)s);
  106. *((uint32_t *)d) = ((x>>1)&0x7FE07FE0) | (x&0x001F001F);
  107. s+=4;
  108. d+=4;
  109. }
  110. if (s < end) {
  111. register uint16_t x= *((const uint16_t*)s);
  112. *((uint16_t *)d) = ((x>>1)&0x7FE0) | (x&0x001F);
  113. }
  114. }
  115. static inline void rgb32to16_c(const uint8_t *src, uint8_t *dst, int src_size)
  116. {
  117. const uint8_t *s = src;
  118. const uint8_t *end;
  119. uint16_t *d = (uint16_t *)dst;
  120. end = s + src_size;
  121. while (s < end) {
  122. register int rgb = *(const uint32_t*)s; s += 4;
  123. *d++ = ((rgb&0xFF)>>3) + ((rgb&0xFC00)>>5) + ((rgb&0xF80000)>>8);
  124. }
  125. }
  126. static inline void rgb32tobgr16_c(const uint8_t *src, uint8_t *dst, int src_size)
  127. {
  128. const uint8_t *s = src;
  129. const uint8_t *end;
  130. uint16_t *d = (uint16_t *)dst;
  131. end = s + src_size;
  132. while (s < end) {
  133. register int rgb = *(const uint32_t*)s; s += 4;
  134. *d++ = ((rgb&0xF8)<<8) + ((rgb&0xFC00)>>5) + ((rgb&0xF80000)>>19);
  135. }
  136. }
  137. static inline void rgb32to15_c(const uint8_t *src, uint8_t *dst, int src_size)
  138. {
  139. const uint8_t *s = src;
  140. const uint8_t *end;
  141. uint16_t *d = (uint16_t *)dst;
  142. end = s + src_size;
  143. while (s < end) {
  144. register int rgb = *(const uint32_t*)s; s += 4;
  145. *d++ = ((rgb&0xFF)>>3) + ((rgb&0xF800)>>6) + ((rgb&0xF80000)>>9);
  146. }
  147. }
  148. static inline void rgb32tobgr15_c(const uint8_t *src, uint8_t *dst, int src_size)
  149. {
  150. const uint8_t *s = src;
  151. const uint8_t *end;
  152. uint16_t *d = (uint16_t *)dst;
  153. end = s + src_size;
  154. while (s < end) {
  155. register int rgb = *(const uint32_t*)s; s += 4;
  156. *d++ = ((rgb&0xF8)<<7) + ((rgb&0xF800)>>6) + ((rgb&0xF80000)>>19);
  157. }
  158. }
  159. static inline void rgb24tobgr16_c(const uint8_t *src, uint8_t *dst, int src_size)
  160. {
  161. const uint8_t *s = src;
  162. const uint8_t *end;
  163. uint16_t *d = (uint16_t *)dst;
  164. end = s + src_size;
  165. while (s < end) {
  166. const int b = *s++;
  167. const int g = *s++;
  168. const int r = *s++;
  169. *d++ = (b>>3) | ((g&0xFC)<<3) | ((r&0xF8)<<8);
  170. }
  171. }
  172. static inline void rgb24to16_c(const uint8_t *src, uint8_t *dst, int src_size)
  173. {
  174. const uint8_t *s = src;
  175. const uint8_t *end;
  176. uint16_t *d = (uint16_t *)dst;
  177. end = s + src_size;
  178. while (s < end) {
  179. const int r = *s++;
  180. const int g = *s++;
  181. const int b = *s++;
  182. *d++ = (b>>3) | ((g&0xFC)<<3) | ((r&0xF8)<<8);
  183. }
  184. }
  185. static inline void rgb24tobgr15_c(const uint8_t *src, uint8_t *dst, int src_size)
  186. {
  187. const uint8_t *s = src;
  188. const uint8_t *end;
  189. uint16_t *d = (uint16_t *)dst;
  190. end = s + src_size;
  191. while (s < end) {
  192. const int b = *s++;
  193. const int g = *s++;
  194. const int r = *s++;
  195. *d++ = (b>>3) | ((g&0xF8)<<2) | ((r&0xF8)<<7);
  196. }
  197. }
  198. static inline void rgb24to15_c(const uint8_t *src, uint8_t *dst, int src_size)
  199. {
  200. const uint8_t *s = src;
  201. const uint8_t *end;
  202. uint16_t *d = (uint16_t *)dst;
  203. end = s + src_size;
  204. while (s < end) {
  205. const int r = *s++;
  206. const int g = *s++;
  207. const int b = *s++;
  208. *d++ = (b>>3) | ((g&0xF8)<<2) | ((r&0xF8)<<7);
  209. }
  210. }
  211. static inline void rgb15tobgr24_c(const uint8_t *src, uint8_t *dst, int src_size)
  212. {
  213. const uint16_t *end;
  214. uint8_t *d = dst;
  215. const uint16_t *s = (const uint16_t*)src;
  216. end = s + src_size/2;
  217. while (s < end) {
  218. register uint16_t bgr;
  219. bgr = *s++;
  220. *d++ = ((bgr&0x1F)<<3) | ((bgr&0x1F)>>2);
  221. *d++ = ((bgr&0x3E0)>>2) | ((bgr&0x3E0)>>7);
  222. *d++ = ((bgr&0x7C00)>>7) | ((bgr&0x7C00)>>12);
  223. }
  224. }
  225. static inline void rgb16tobgr24_c(const uint8_t *src, uint8_t *dst, int src_size)
  226. {
  227. const uint16_t *end;
  228. uint8_t *d = (uint8_t *)dst;
  229. const uint16_t *s = (const uint16_t *)src;
  230. end = s + src_size/2;
  231. while (s < end) {
  232. register uint16_t bgr;
  233. bgr = *s++;
  234. *d++ = ((bgr&0x1F)<<3) | ((bgr&0x1F)>>2);
  235. *d++ = ((bgr&0x7E0)>>3) | ((bgr&0x7E0)>>9);
  236. *d++ = ((bgr&0xF800)>>8) | ((bgr&0xF800)>>13);
  237. }
  238. }
  239. static inline void rgb15to32_c(const uint8_t *src, uint8_t *dst, int src_size)
  240. {
  241. const uint16_t *end;
  242. uint8_t *d = dst;
  243. const uint16_t *s = (const uint16_t *)src;
  244. end = s + src_size/2;
  245. while (s < end) {
  246. register uint16_t bgr;
  247. bgr = *s++;
  248. #if HAVE_BIGENDIAN
  249. *d++ = 255;
  250. *d++ = ((bgr&0x7C00)>>7) | ((bgr&0x7C00)>>12);
  251. *d++ = ((bgr&0x3E0)>>2) | ((bgr&0x3E0)>>7);
  252. *d++ = ((bgr&0x1F)<<3) | ((bgr&0x1F)>>2);
  253. #else
  254. *d++ = ((bgr&0x1F)<<3) | ((bgr&0x1F)>>2);
  255. *d++ = ((bgr&0x3E0)>>2) | ((bgr&0x3E0)>>7);
  256. *d++ = ((bgr&0x7C00)>>7) | ((bgr&0x7C00)>>12);
  257. *d++ = 255;
  258. #endif
  259. }
  260. }
  261. static inline void rgb16to32_c(const uint8_t *src, uint8_t *dst, int src_size)
  262. {
  263. const uint16_t *end;
  264. uint8_t *d = dst;
  265. const uint16_t *s = (const uint16_t*)src;
  266. end = s + src_size/2;
  267. while (s < end) {
  268. register uint16_t bgr;
  269. bgr = *s++;
  270. #if HAVE_BIGENDIAN
  271. *d++ = 255;
  272. *d++ = ((bgr&0xF800)>>8) | ((bgr&0xF800)>>13);
  273. *d++ = ((bgr&0x7E0)>>3) | ((bgr&0x7E0)>>9);
  274. *d++ = ((bgr&0x1F)<<3) | ((bgr&0x1F)>>2);
  275. #else
  276. *d++ = ((bgr&0x1F)<<3) | ((bgr&0x1F)>>2);
  277. *d++ = ((bgr&0x7E0)>>3) | ((bgr&0x7E0)>>9);
  278. *d++ = ((bgr&0xF800)>>8) | ((bgr&0xF800)>>13);
  279. *d++ = 255;
  280. #endif
  281. }
  282. }
  283. static inline void shuffle_bytes_2103_c(const uint8_t *src, uint8_t *dst, int src_size)
  284. {
  285. int idx = 15 - src_size;
  286. const uint8_t *s = src-idx;
  287. uint8_t *d = dst-idx;
  288. for (; idx<15; idx+=4) {
  289. register int v = *(const uint32_t *)&s[idx], g = v & 0xff00ff00;
  290. v &= 0xff00ff;
  291. *(uint32_t *)&d[idx] = (v>>16) + g + (v<<16);
  292. }
  293. }
  294. static inline void rgb24tobgr24_c(const uint8_t *src, uint8_t *dst, int src_size)
  295. {
  296. unsigned i;
  297. for (i=0; i<src_size; i+=3) {
  298. register uint8_t x;
  299. x = src[i + 2];
  300. dst[i + 1] = src[i + 1];
  301. dst[i + 2] = src[i + 0];
  302. dst[i + 0] = x;
  303. }
  304. }
  305. static inline void yuvPlanartoyuy2_c(const uint8_t *ysrc, const uint8_t *usrc,
  306. const uint8_t *vsrc, uint8_t *dst,
  307. int width, int height,
  308. int lumStride, int chromStride,
  309. int dstStride, int vertLumPerChroma)
  310. {
  311. int y;
  312. const int chromWidth = width >> 1;
  313. for (y=0; y<height; y++) {
  314. #if HAVE_FAST_64BIT
  315. int i;
  316. uint64_t *ldst = (uint64_t *) dst;
  317. const uint8_t *yc = ysrc, *uc = usrc, *vc = vsrc;
  318. for (i = 0; i < chromWidth; i += 2) {
  319. uint64_t k, l;
  320. k = yc[0] + (uc[0] << 8) +
  321. (yc[1] << 16) + (vc[0] << 24);
  322. l = yc[2] + (uc[1] << 8) +
  323. (yc[3] << 16) + (vc[1] << 24);
  324. *ldst++ = k + (l << 32);
  325. yc += 4;
  326. uc += 2;
  327. vc += 2;
  328. }
  329. #else
  330. int i, *idst = (int32_t *) dst;
  331. const uint8_t *yc = ysrc, *uc = usrc, *vc = vsrc;
  332. for (i = 0; i < chromWidth; i++) {
  333. #if HAVE_BIGENDIAN
  334. *idst++ = (yc[0] << 24)+ (uc[0] << 16) +
  335. (yc[1] << 8) + (vc[0] << 0);
  336. #else
  337. *idst++ = yc[0] + (uc[0] << 8) +
  338. (yc[1] << 16) + (vc[0] << 24);
  339. #endif
  340. yc += 2;
  341. uc++;
  342. vc++;
  343. }
  344. #endif
  345. if ((y&(vertLumPerChroma-1)) == vertLumPerChroma-1) {
  346. usrc += chromStride;
  347. vsrc += chromStride;
  348. }
  349. ysrc += lumStride;
  350. dst += dstStride;
  351. }
  352. }
  353. /**
  354. * Height should be a multiple of 2 and width should be a multiple of 16.
  355. * (If this is a problem for anyone then tell me, and I will fix it.)
  356. */
  357. static inline void yv12toyuy2_c(const uint8_t *ysrc, const uint8_t *usrc,
  358. const uint8_t *vsrc, uint8_t *dst,
  359. int width, int height,
  360. int lumStride, int chromStride,
  361. int dstStride)
  362. {
  363. //FIXME interpolate chroma
  364. yuvPlanartoyuy2_c(ysrc, usrc, vsrc, dst, width, height, lumStride,
  365. chromStride, dstStride, 2);
  366. }
  367. static inline void yuvPlanartouyvy_c(const uint8_t *ysrc, const uint8_t *usrc,
  368. const uint8_t *vsrc, uint8_t *dst,
  369. int width, int height,
  370. int lumStride, int chromStride,
  371. int dstStride, int vertLumPerChroma)
  372. {
  373. int y;
  374. const int chromWidth = width >> 1;
  375. for (y=0; y<height; y++) {
  376. #if HAVE_FAST_64BIT
  377. int i;
  378. uint64_t *ldst = (uint64_t *) dst;
  379. const uint8_t *yc = ysrc, *uc = usrc, *vc = vsrc;
  380. for (i = 0; i < chromWidth; i += 2) {
  381. uint64_t k, l;
  382. k = uc[0] + (yc[0] << 8) +
  383. (vc[0] << 16) + (yc[1] << 24);
  384. l = uc[1] + (yc[2] << 8) +
  385. (vc[1] << 16) + (yc[3] << 24);
  386. *ldst++ = k + (l << 32);
  387. yc += 4;
  388. uc += 2;
  389. vc += 2;
  390. }
  391. #else
  392. int i, *idst = (int32_t *) dst;
  393. const uint8_t *yc = ysrc, *uc = usrc, *vc = vsrc;
  394. for (i = 0; i < chromWidth; i++) {
  395. #if HAVE_BIGENDIAN
  396. *idst++ = (uc[0] << 24)+ (yc[0] << 16) +
  397. (vc[0] << 8) + (yc[1] << 0);
  398. #else
  399. *idst++ = uc[0] + (yc[0] << 8) +
  400. (vc[0] << 16) + (yc[1] << 24);
  401. #endif
  402. yc += 2;
  403. uc++;
  404. vc++;
  405. }
  406. #endif
  407. if ((y&(vertLumPerChroma-1)) == vertLumPerChroma-1) {
  408. usrc += chromStride;
  409. vsrc += chromStride;
  410. }
  411. ysrc += lumStride;
  412. dst += dstStride;
  413. }
  414. }
  415. /**
  416. * Height should be a multiple of 2 and width should be a multiple of 16
  417. * (If this is a problem for anyone then tell me, and I will fix it.)
  418. */
  419. static inline void yv12touyvy_c(const uint8_t *ysrc, const uint8_t *usrc,
  420. const uint8_t *vsrc, uint8_t *dst,
  421. int width, int height,
  422. int lumStride, int chromStride,
  423. int dstStride)
  424. {
  425. //FIXME interpolate chroma
  426. yuvPlanartouyvy_c(ysrc, usrc, vsrc, dst, width, height, lumStride,
  427. chromStride, dstStride, 2);
  428. }
  429. /**
  430. * Width should be a multiple of 16.
  431. */
  432. static inline void yuv422ptouyvy_c(const uint8_t *ysrc, const uint8_t *usrc,
  433. const uint8_t *vsrc, uint8_t *dst,
  434. int width, int height,
  435. int lumStride, int chromStride,
  436. int dstStride)
  437. {
  438. yuvPlanartouyvy_c(ysrc, usrc, vsrc, dst, width, height, lumStride,
  439. chromStride, dstStride, 1);
  440. }
  441. /**
  442. * Width should be a multiple of 16.
  443. */
  444. static inline void yuv422ptoyuy2_c(const uint8_t *ysrc, const uint8_t *usrc,
  445. const uint8_t *vsrc, uint8_t *dst,
  446. int width, int height,
  447. int lumStride, int chromStride,
  448. int dstStride)
  449. {
  450. yuvPlanartoyuy2_c(ysrc, usrc, vsrc, dst, width, height, lumStride,
  451. chromStride, dstStride, 1);
  452. }
  453. /**
  454. * Height should be a multiple of 2 and width should be a multiple of 16.
  455. * (If this is a problem for anyone then tell me, and I will fix it.)
  456. */
  457. static inline void yuy2toyv12_c(const uint8_t *src, uint8_t *ydst,
  458. uint8_t *udst, uint8_t *vdst,
  459. int width, int height,
  460. int lumStride, int chromStride,
  461. int srcStride)
  462. {
  463. int y;
  464. const int chromWidth = width >> 1;
  465. for (y=0; y<height; y+=2) {
  466. int i;
  467. for (i=0; i<chromWidth; i++) {
  468. ydst[2*i+0] = src[4*i+0];
  469. udst[i] = src[4*i+1];
  470. ydst[2*i+1] = src[4*i+2];
  471. vdst[i] = src[4*i+3];
  472. }
  473. ydst += lumStride;
  474. src += srcStride;
  475. for (i=0; i<chromWidth; i++) {
  476. ydst[2*i+0] = src[4*i+0];
  477. ydst[2*i+1] = src[4*i+2];
  478. }
  479. udst += chromStride;
  480. vdst += chromStride;
  481. ydst += lumStride;
  482. src += srcStride;
  483. }
  484. }
  485. static inline void planar2x_c(const uint8_t *src, uint8_t *dst, int srcWidth,
  486. int srcHeight, int srcStride, int dstStride)
  487. {
  488. int x,y;
  489. dst[0]= src[0];
  490. // first line
  491. for (x=0; x<srcWidth-1; x++) {
  492. dst[2*x+1]= (3*src[x] + src[x+1])>>2;
  493. dst[2*x+2]= ( src[x] + 3*src[x+1])>>2;
  494. }
  495. dst[2*srcWidth-1]= src[srcWidth-1];
  496. dst+= dstStride;
  497. for (y=1; y<srcHeight; y++) {
  498. const int mmxSize = 1;
  499. dst[0 ]= (3*src[0] + src[srcStride])>>2;
  500. dst[dstStride]= ( src[0] + 3*src[srcStride])>>2;
  501. for (x=mmxSize-1; x<srcWidth-1; x++) {
  502. dst[2*x +1]= (3*src[x+0] + src[x+srcStride+1])>>2;
  503. dst[2*x+dstStride+2]= ( src[x+0] + 3*src[x+srcStride+1])>>2;
  504. dst[2*x+dstStride+1]= ( src[x+1] + 3*src[x+srcStride ])>>2;
  505. dst[2*x +2]= (3*src[x+1] + src[x+srcStride ])>>2;
  506. }
  507. dst[srcWidth*2 -1 ]= (3*src[srcWidth-1] + src[srcWidth-1 + srcStride])>>2;
  508. dst[srcWidth*2 -1 + dstStride]= ( src[srcWidth-1] + 3*src[srcWidth-1 + srcStride])>>2;
  509. dst+=dstStride*2;
  510. src+=srcStride;
  511. }
  512. // last line
  513. dst[0]= src[0];
  514. for (x=0; x<srcWidth-1; x++) {
  515. dst[2*x+1]= (3*src[x] + src[x+1])>>2;
  516. dst[2*x+2]= ( src[x] + 3*src[x+1])>>2;
  517. }
  518. dst[2*srcWidth-1]= src[srcWidth-1];
  519. }
  520. /**
  521. * Height should be a multiple of 2 and width should be a multiple of 16.
  522. * (If this is a problem for anyone then tell me, and I will fix it.)
  523. * Chrominance data is only taken from every second line, others are ignored.
  524. * FIXME: Write HQ version.
  525. */
  526. static inline void uyvytoyv12_c(const uint8_t *src, uint8_t *ydst,
  527. uint8_t *udst, uint8_t *vdst,
  528. int width, int height,
  529. int lumStride, int chromStride,
  530. int srcStride)
  531. {
  532. int y;
  533. const int chromWidth = width >> 1;
  534. for (y=0; y<height; y+=2) {
  535. int i;
  536. for (i=0; i<chromWidth; i++) {
  537. udst[i] = src[4*i+0];
  538. ydst[2*i+0] = src[4*i+1];
  539. vdst[i] = src[4*i+2];
  540. ydst[2*i+1] = src[4*i+3];
  541. }
  542. ydst += lumStride;
  543. src += srcStride;
  544. for (i=0; i<chromWidth; i++) {
  545. ydst[2*i+0] = src[4*i+1];
  546. ydst[2*i+1] = src[4*i+3];
  547. }
  548. udst += chromStride;
  549. vdst += chromStride;
  550. ydst += lumStride;
  551. src += srcStride;
  552. }
  553. }
  554. /**
  555. * Height should be a multiple of 2 and width should be a multiple of 2.
  556. * (If this is a problem for anyone then tell me, and I will fix it.)
  557. * Chrominance data is only taken from every second line,
  558. * others are ignored in the C version.
  559. * FIXME: Write HQ version.
  560. */
  561. void rgb24toyv12_c(const uint8_t *src, uint8_t *ydst, uint8_t *udst,
  562. uint8_t *vdst, int width, int height, int lumStride,
  563. int chromStride, int srcStride)
  564. {
  565. int y;
  566. const int chromWidth = width >> 1;
  567. y=0;
  568. for (; y<height; y+=2) {
  569. int i;
  570. for (i=0; i<chromWidth; i++) {
  571. unsigned int b = src[6*i+0];
  572. unsigned int g = src[6*i+1];
  573. unsigned int r = src[6*i+2];
  574. unsigned int Y = ((RY*r + GY*g + BY*b)>>RGB2YUV_SHIFT) + 16;
  575. unsigned int V = ((RV*r + GV*g + BV*b)>>RGB2YUV_SHIFT) + 128;
  576. unsigned int U = ((RU*r + GU*g + BU*b)>>RGB2YUV_SHIFT) + 128;
  577. udst[i] = U;
  578. vdst[i] = V;
  579. ydst[2*i] = Y;
  580. b = src[6*i+3];
  581. g = src[6*i+4];
  582. r = src[6*i+5];
  583. Y = ((RY*r + GY*g + BY*b)>>RGB2YUV_SHIFT) + 16;
  584. ydst[2*i+1] = Y;
  585. }
  586. ydst += lumStride;
  587. src += srcStride;
  588. if(y+1 == height)
  589. break;
  590. for (i=0; i<chromWidth; i++) {
  591. unsigned int b = src[6*i+0];
  592. unsigned int g = src[6*i+1];
  593. unsigned int r = src[6*i+2];
  594. unsigned int Y = ((RY*r + GY*g + BY*b)>>RGB2YUV_SHIFT) + 16;
  595. ydst[2*i] = Y;
  596. b = src[6*i+3];
  597. g = src[6*i+4];
  598. r = src[6*i+5];
  599. Y = ((RY*r + GY*g + BY*b)>>RGB2YUV_SHIFT) + 16;
  600. ydst[2*i+1] = Y;
  601. }
  602. udst += chromStride;
  603. vdst += chromStride;
  604. ydst += lumStride;
  605. src += srcStride;
  606. }
  607. }
  608. static void interleaveBytes_c(const uint8_t *src1, const uint8_t *src2,
  609. uint8_t *dest, int width,
  610. int height, int src1Stride,
  611. int src2Stride, int dstStride)
  612. {
  613. int h;
  614. for (h=0; h < height; h++) {
  615. int w;
  616. for (w=0; w < width; w++) {
  617. dest[2*w+0] = src1[w];
  618. dest[2*w+1] = src2[w];
  619. }
  620. dest += dstStride;
  621. src1 += src1Stride;
  622. src2 += src2Stride;
  623. }
  624. }
  625. static inline void vu9_to_vu12_c(const uint8_t *src1, const uint8_t *src2,
  626. uint8_t *dst1, uint8_t *dst2,
  627. int width, int height,
  628. int srcStride1, int srcStride2,
  629. int dstStride1, int dstStride2)
  630. {
  631. int y;
  632. int x,w,h;
  633. w=width/2; h=height/2;
  634. for (y=0;y<h;y++) {
  635. const uint8_t* s1=src1+srcStride1*(y>>1);
  636. uint8_t* d=dst1+dstStride1*y;
  637. x=0;
  638. for (;x<w;x++) d[2*x]=d[2*x+1]=s1[x];
  639. }
  640. for (y=0;y<h;y++) {
  641. const uint8_t* s2=src2+srcStride2*(y>>1);
  642. uint8_t* d=dst2+dstStride2*y;
  643. x=0;
  644. for (;x<w;x++) d[2*x]=d[2*x+1]=s2[x];
  645. }
  646. }
  647. static inline void yvu9_to_yuy2_c(const uint8_t *src1, const uint8_t *src2,
  648. const uint8_t *src3, uint8_t *dst,
  649. int width, int height,
  650. int srcStride1, int srcStride2,
  651. int srcStride3, int dstStride)
  652. {
  653. int x;
  654. int y,w,h;
  655. w=width/2; h=height;
  656. for (y=0;y<h;y++) {
  657. const uint8_t* yp=src1+srcStride1*y;
  658. const uint8_t* up=src2+srcStride2*(y>>2);
  659. const uint8_t* vp=src3+srcStride3*(y>>2);
  660. uint8_t* d=dst+dstStride*y;
  661. x=0;
  662. for (; x<w; x++) {
  663. const int x2 = x<<2;
  664. d[8*x+0] = yp[x2];
  665. d[8*x+1] = up[x];
  666. d[8*x+2] = yp[x2+1];
  667. d[8*x+3] = vp[x];
  668. d[8*x+4] = yp[x2+2];
  669. d[8*x+5] = up[x];
  670. d[8*x+6] = yp[x2+3];
  671. d[8*x+7] = vp[x];
  672. }
  673. }
  674. }
  675. static void extract_even_c(const uint8_t *src, uint8_t *dst, int count)
  676. {
  677. dst += count;
  678. src += 2*count;
  679. count= - count;
  680. while(count<0) {
  681. dst[count]= src[2*count];
  682. count++;
  683. }
  684. }
  685. static void extract_even2_c(const uint8_t *src, uint8_t *dst0, uint8_t *dst1,
  686. int count)
  687. {
  688. dst0+= count;
  689. dst1+= count;
  690. src += 4*count;
  691. count= - count;
  692. while(count<0) {
  693. dst0[count]= src[4*count+0];
  694. dst1[count]= src[4*count+2];
  695. count++;
  696. }
  697. }
  698. static void extract_even2avg_c(const uint8_t *src0, const uint8_t *src1,
  699. uint8_t *dst0, uint8_t *dst1, int count)
  700. {
  701. dst0 += count;
  702. dst1 += count;
  703. src0 += 4*count;
  704. src1 += 4*count;
  705. count= - count;
  706. while(count<0) {
  707. dst0[count]= (src0[4*count+0]+src1[4*count+0])>>1;
  708. dst1[count]= (src0[4*count+2]+src1[4*count+2])>>1;
  709. count++;
  710. }
  711. }
  712. static void extract_odd2_c(const uint8_t *src, uint8_t *dst0, uint8_t *dst1,
  713. int count)
  714. {
  715. dst0+= count;
  716. dst1+= count;
  717. src += 4*count;
  718. count= - count;
  719. src++;
  720. while(count<0) {
  721. dst0[count]= src[4*count+0];
  722. dst1[count]= src[4*count+2];
  723. count++;
  724. }
  725. }
  726. static void extract_odd2avg_c(const uint8_t *src0, const uint8_t *src1,
  727. uint8_t *dst0, uint8_t *dst1, int count)
  728. {
  729. dst0 += count;
  730. dst1 += count;
  731. src0 += 4*count;
  732. src1 += 4*count;
  733. count= - count;
  734. src0++;
  735. src1++;
  736. while(count<0) {
  737. dst0[count]= (src0[4*count+0]+src1[4*count+0])>>1;
  738. dst1[count]= (src0[4*count+2]+src1[4*count+2])>>1;
  739. count++;
  740. }
  741. }
  742. static void yuyvtoyuv420_c(uint8_t *ydst, uint8_t *udst, uint8_t *vdst,
  743. const uint8_t *src, int width, int height,
  744. int lumStride, int chromStride, int srcStride)
  745. {
  746. int y;
  747. const int chromWidth= -((-width)>>1);
  748. for (y=0; y<height; y++) {
  749. extract_even_c(src, ydst, width);
  750. if(y&1) {
  751. extract_odd2avg_c(src - srcStride, src, udst, vdst, chromWidth);
  752. udst+= chromStride;
  753. vdst+= chromStride;
  754. }
  755. src += srcStride;
  756. ydst+= lumStride;
  757. }
  758. }
  759. static void yuyvtoyuv422_c(uint8_t *ydst, uint8_t *udst, uint8_t *vdst,
  760. const uint8_t *src, int width, int height,
  761. int lumStride, int chromStride, int srcStride)
  762. {
  763. int y;
  764. const int chromWidth= -((-width)>>1);
  765. for (y=0; y<height; y++) {
  766. extract_even_c(src, ydst, width);
  767. extract_odd2_c(src, udst, vdst, chromWidth);
  768. src += srcStride;
  769. ydst+= lumStride;
  770. udst+= chromStride;
  771. vdst+= chromStride;
  772. }
  773. }
  774. static void uyvytoyuv420_c(uint8_t *ydst, uint8_t *udst, uint8_t *vdst,
  775. const uint8_t *src, int width, int height,
  776. int lumStride, int chromStride, int srcStride)
  777. {
  778. int y;
  779. const int chromWidth= -((-width)>>1);
  780. for (y=0; y<height; y++) {
  781. extract_even_c(src + 1, ydst, width);
  782. if(y&1) {
  783. extract_even2avg_c(src - srcStride, src, udst, vdst, chromWidth);
  784. udst+= chromStride;
  785. vdst+= chromStride;
  786. }
  787. src += srcStride;
  788. ydst+= lumStride;
  789. }
  790. }
  791. static void uyvytoyuv422_c(uint8_t *ydst, uint8_t *udst, uint8_t *vdst,
  792. const uint8_t *src, int width, int height,
  793. int lumStride, int chromStride, int srcStride)
  794. {
  795. int y;
  796. const int chromWidth= -((-width)>>1);
  797. for (y=0; y<height; y++) {
  798. extract_even_c(src + 1, ydst, width);
  799. extract_even2_c(src, udst, vdst, chromWidth);
  800. src += srcStride;
  801. ydst+= lumStride;
  802. udst+= chromStride;
  803. vdst+= chromStride;
  804. }
  805. }
  806. static inline void rgb2rgb_init_c(void)
  807. {
  808. rgb15to16 = rgb15to16_c;
  809. rgb15tobgr24 = rgb15tobgr24_c;
  810. rgb15to32 = rgb15to32_c;
  811. rgb16tobgr24 = rgb16tobgr24_c;
  812. rgb16to32 = rgb16to32_c;
  813. rgb16to15 = rgb16to15_c;
  814. rgb24tobgr16 = rgb24tobgr16_c;
  815. rgb24tobgr15 = rgb24tobgr15_c;
  816. rgb24tobgr32 = rgb24tobgr32_c;
  817. rgb32to16 = rgb32to16_c;
  818. rgb32to15 = rgb32to15_c;
  819. rgb32tobgr24 = rgb32tobgr24_c;
  820. rgb24to15 = rgb24to15_c;
  821. rgb24to16 = rgb24to16_c;
  822. rgb24tobgr24 = rgb24tobgr24_c;
  823. shuffle_bytes_2103 = shuffle_bytes_2103_c;
  824. rgb32tobgr16 = rgb32tobgr16_c;
  825. rgb32tobgr15 = rgb32tobgr15_c;
  826. yv12toyuy2 = yv12toyuy2_c;
  827. yv12touyvy = yv12touyvy_c;
  828. yuv422ptoyuy2 = yuv422ptoyuy2_c;
  829. yuv422ptouyvy = yuv422ptouyvy_c;
  830. yuy2toyv12 = yuy2toyv12_c;
  831. planar2x = planar2x_c;
  832. rgb24toyv12 = rgb24toyv12_c;
  833. interleaveBytes = interleaveBytes_c;
  834. vu9_to_vu12 = vu9_to_vu12_c;
  835. yvu9_to_yuy2 = yvu9_to_yuy2_c;
  836. uyvytoyuv420 = uyvytoyuv420_c;
  837. uyvytoyuv422 = uyvytoyuv422_c;
  838. yuyvtoyuv420 = yuyvtoyuv420_c;
  839. yuyvtoyuv422 = yuyvtoyuv422_c;
  840. }