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.

870 lines
25KB

  1. /*
  2. * Misc image convertion routines
  3. * Copyright (c) 2001, 2002 Fabrice Bellard.
  4. *
  5. * This library is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU Lesser General Public
  7. * License as published by the Free Software Foundation; either
  8. * version 2 of the License, or (at your option) any later version.
  9. *
  10. * This library is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. * Lesser General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Lesser General Public
  16. * License along with this library; if not, write to the Free Software
  17. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  18. */
  19. #include "avcodec.h"
  20. #include "dsputil.h"
  21. #ifdef USE_FASTMEMCPY
  22. #include "fastmemcpy.h"
  23. #endif
  24. /* XXX: totally non optimized */
  25. static void yuv422_to_yuv420p(UINT8 *lum, UINT8 *cb, UINT8 *cr,
  26. UINT8 *src, int width, int height)
  27. {
  28. int x, y;
  29. UINT8 *p = src;
  30. for(y=0;y<height;y+=2) {
  31. for(x=0;x<width;x+=2) {
  32. lum[0] = p[0];
  33. cb[0] = p[1];
  34. lum[1] = p[2];
  35. cr[0] = p[3];
  36. p += 4;
  37. lum += 2;
  38. cb++;
  39. cr++;
  40. }
  41. for(x=0;x<width;x+=2) {
  42. lum[0] = p[0];
  43. lum[1] = p[2];
  44. p += 4;
  45. lum += 2;
  46. }
  47. }
  48. }
  49. #define SCALEBITS 8
  50. #define ONE_HALF (1 << (SCALEBITS - 1))
  51. #define FIX(x) ((int) ((x) * (1L<<SCALEBITS) + 0.5))
  52. static void rgb24_to_yuv420p(UINT8 *lum, UINT8 *cb, UINT8 *cr,
  53. UINT8 *src, int width, int height)
  54. {
  55. int wrap, wrap3, x, y;
  56. int r, g, b, r1, g1, b1;
  57. UINT8 *p;
  58. wrap = width;
  59. wrap3 = width * 3;
  60. p = src;
  61. for(y=0;y<height;y+=2) {
  62. for(x=0;x<width;x+=2) {
  63. r = p[0];
  64. g = p[1];
  65. b = p[2];
  66. r1 = r;
  67. g1 = g;
  68. b1 = b;
  69. lum[0] = (FIX(0.29900) * r + FIX(0.58700) * g +
  70. FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
  71. r = p[3];
  72. g = p[4];
  73. b = p[5];
  74. r1 += r;
  75. g1 += g;
  76. b1 += b;
  77. lum[1] = (FIX(0.29900) * r + FIX(0.58700) * g +
  78. FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
  79. p += wrap3;
  80. lum += wrap;
  81. r = p[0];
  82. g = p[1];
  83. b = p[2];
  84. r1 += r;
  85. g1 += g;
  86. b1 += b;
  87. lum[0] = (FIX(0.29900) * r + FIX(0.58700) * g +
  88. FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
  89. r = p[3];
  90. g = p[4];
  91. b = p[5];
  92. r1 += r;
  93. g1 += g;
  94. b1 += b;
  95. lum[1] = (FIX(0.29900) * r + FIX(0.58700) * g +
  96. FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
  97. cb[0] = ((- FIX(0.16874) * r1 - FIX(0.33126) * g1 +
  98. FIX(0.50000) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128;
  99. cr[0] = ((FIX(0.50000) * r1 - FIX(0.41869) * g1 -
  100. FIX(0.08131) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128;
  101. cb++;
  102. cr++;
  103. p += -wrap3 + 2 * 3;
  104. lum += -wrap + 2;
  105. }
  106. p += wrap3;
  107. lum += wrap;
  108. }
  109. }
  110. static void rgba32_to_yuv420p(UINT8 *lum, UINT8 *cb, UINT8 *cr,
  111. UINT8 *src, int width, int height)
  112. {
  113. int wrap, wrap4, x, y;
  114. int r, g, b, r1, g1, b1;
  115. UINT8 *p;
  116. wrap = width;
  117. wrap4 = width * 4;
  118. p = src;
  119. for(y=0;y<height;y+=2) {
  120. for(x=0;x<width;x+=2) {
  121. r = p[0];
  122. g = p[1];
  123. b = p[2];
  124. r1 = r;
  125. g1 = g;
  126. b1 = b;
  127. lum[0] = (FIX(0.29900) * r + FIX(0.58700) * g +
  128. FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
  129. r = p[4];
  130. g = p[5];
  131. b = p[6];
  132. r1 += r;
  133. g1 += g;
  134. b1 += b;
  135. lum[1] = (FIX(0.29900) * r + FIX(0.58700) * g +
  136. FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
  137. p += wrap4;
  138. lum += wrap;
  139. r = p[0];
  140. g = p[1];
  141. b = p[2];
  142. r1 += r;
  143. g1 += g;
  144. b1 += b;
  145. lum[0] = (FIX(0.29900) * r + FIX(0.58700) * g +
  146. FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
  147. r = p[4];
  148. g = p[5];
  149. b = p[6];
  150. r1 += r;
  151. g1 += g;
  152. b1 += b;
  153. lum[1] = (FIX(0.29900) * r + FIX(0.58700) * g +
  154. FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
  155. cb[0] = ((- FIX(0.16874) * r1 - FIX(0.33126) * g1 +
  156. FIX(0.50000) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128;
  157. cr[0] = ((FIX(0.50000) * r1 - FIX(0.41869) * g1 -
  158. FIX(0.08131) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128;
  159. cb++;
  160. cr++;
  161. p += -wrap4 + 2 * 4;
  162. lum += -wrap + 2;
  163. }
  164. p += wrap4;
  165. lum += wrap;
  166. }
  167. }
  168. static void bgr24_to_yuv420p(UINT8 *lum, UINT8 *cb, UINT8 *cr,
  169. UINT8 *src, int width, int height)
  170. {
  171. int wrap, wrap3, x, y;
  172. int r, g, b, r1, g1, b1;
  173. UINT8 *p;
  174. wrap = width;
  175. wrap3 = width * 3;
  176. p = src;
  177. for(y=0;y<height;y+=2) {
  178. for(x=0;x<width;x+=2) {
  179. b = p[0];
  180. g = p[1];
  181. r = p[2];
  182. r1 = r;
  183. g1 = g;
  184. b1 = b;
  185. lum[0] = (FIX(0.29900) * r + FIX(0.58700) * g +
  186. FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
  187. b = p[3];
  188. g = p[4];
  189. r = p[5];
  190. r1 += r;
  191. g1 += g;
  192. b1 += b;
  193. lum[1] = (FIX(0.29900) * r + FIX(0.58700) * g +
  194. FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
  195. p += wrap3;
  196. lum += wrap;
  197. b = p[0];
  198. g = p[1];
  199. r = p[2];
  200. r1 += r;
  201. g1 += g;
  202. b1 += b;
  203. lum[0] = (FIX(0.29900) * r + FIX(0.58700) * g +
  204. FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
  205. b = p[3];
  206. g = p[4];
  207. r = p[5];
  208. r1 += r;
  209. g1 += g;
  210. b1 += b;
  211. lum[1] = (FIX(0.29900) * r + FIX(0.58700) * g +
  212. FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
  213. cb[0] = ((- FIX(0.16874) * r1 - FIX(0.33126) * g1 +
  214. FIX(0.50000) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128;
  215. cr[0] = ((FIX(0.50000) * r1 - FIX(0.41869) * g1 -
  216. FIX(0.08131) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128;
  217. cb++;
  218. cr++;
  219. p += -wrap3 + 2 * 3;
  220. lum += -wrap + 2;
  221. }
  222. p += wrap3;
  223. lum += wrap;
  224. }
  225. }
  226. static void bgra32_to_yuv420p(UINT8 *lum, UINT8 *cb, UINT8 *cr,
  227. UINT8 *src, int width, int height)
  228. {
  229. int wrap, wrap4, x, y;
  230. int r, g, b, r1, g1, b1;
  231. UINT8 *p;
  232. wrap = width;
  233. wrap4 = width * 4;
  234. p = src;
  235. for(y=0;y<height;y+=2) {
  236. for(x=0;x<width;x+=2) {
  237. b = p[0];
  238. g = p[1];
  239. r = p[2];
  240. r1 = r;
  241. g1 = g;
  242. b1 = b;
  243. lum[0] = (FIX(0.29900) * r + FIX(0.58700) * g +
  244. FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
  245. b = p[4];
  246. g = p[5];
  247. r = p[6];
  248. r1 += r;
  249. g1 += g;
  250. b1 += b;
  251. lum[1] = (FIX(0.29900) * r + FIX(0.58700) * g +
  252. FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
  253. p += wrap4;
  254. lum += wrap;
  255. b = p[0];
  256. g = p[1];
  257. r = p[2];
  258. r1 += r;
  259. g1 += g;
  260. b1 += b;
  261. lum[0] = (FIX(0.29900) * r + FIX(0.58700) * g +
  262. FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
  263. b = p[4];
  264. g = p[5];
  265. r = p[6];
  266. r1 += r;
  267. g1 += g;
  268. b1 += b;
  269. lum[1] = (FIX(0.29900) * r + FIX(0.58700) * g +
  270. FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
  271. cb[0] = ((- FIX(0.16874) * r1 - FIX(0.33126) * g1 +
  272. FIX(0.50000) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128;
  273. cr[0] = ((FIX(0.50000) * r1 - FIX(0.41869) * g1 -
  274. FIX(0.08131) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128;
  275. cb++;
  276. cr++;
  277. p += -wrap4 + 2 * 4;
  278. lum += -wrap + 2;
  279. }
  280. p += wrap4;
  281. lum += wrap;
  282. }
  283. }
  284. /* XXX: use generic filter ? */
  285. /* 1x2 -> 1x1 */
  286. static void shrink2(UINT8 *dst, int dst_wrap,
  287. UINT8 *src, int src_wrap,
  288. int width, int height)
  289. {
  290. int w;
  291. UINT8 *s1, *s2, *d;
  292. for(;height > 0; height--) {
  293. s1 = src;
  294. s2 = s1 + src_wrap;
  295. d = dst;
  296. for(w = width;w >= 4; w-=4) {
  297. d[0] = (s1[0] + s2[0]) >> 1;
  298. d[1] = (s1[1] + s2[1]) >> 1;
  299. d[2] = (s1[2] + s2[2]) >> 1;
  300. d[3] = (s1[3] + s2[3]) >> 1;
  301. s1 += 4;
  302. s2 += 4;
  303. d += 4;
  304. }
  305. for(;w > 0; w--) {
  306. d[0] = (s1[0] + s2[0]) >> 1;
  307. s1++;
  308. s2++;
  309. d++;
  310. }
  311. src += 2 * src_wrap;
  312. dst += dst_wrap;
  313. }
  314. }
  315. /* 2x2 -> 1x1 */
  316. static void shrink22(UINT8 *dst, int dst_wrap,
  317. UINT8 *src, int src_wrap,
  318. int width, int height)
  319. {
  320. int w;
  321. UINT8 *s1, *s2, *d;
  322. for(;height > 0; height--) {
  323. s1 = src;
  324. s2 = s1 + src_wrap;
  325. d = dst;
  326. for(w = width;w >= 4; w-=4) {
  327. d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 1;
  328. d[1] = (s1[2] + s1[3] + s2[2] + s2[3] + 2) >> 1;
  329. d[2] = (s1[4] + s1[5] + s2[4] + s2[5] + 2) >> 1;
  330. d[3] = (s1[6] + s1[7] + s2[6] + s2[7] + 2) >> 1;
  331. s1 += 8;
  332. s2 += 8;
  333. d += 4;
  334. }
  335. for(;w > 0; w--) {
  336. d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 1;
  337. s1 += 2;
  338. s2 += 2;
  339. d++;
  340. }
  341. src += 2 * src_wrap;
  342. dst += dst_wrap;
  343. }
  344. }
  345. /* 1x1 -> 2x2 */
  346. static void grow22(UINT8 *dst, int dst_wrap,
  347. UINT8 *src, int src_wrap,
  348. int width, int height)
  349. {
  350. int w;
  351. UINT8 *s1, *d;
  352. for(;height > 0; height--) {
  353. s1 = src;
  354. d = dst;
  355. for(w = width;w >= 4; w-=4) {
  356. d[1] = d[0] = s1[0];
  357. d[3] = d[2] = s1[1];
  358. s1 += 2;
  359. d += 4;
  360. }
  361. for(;w > 0; w--) {
  362. d[0] = s1[0];
  363. s1 ++;
  364. d++;
  365. }
  366. if (height%2)
  367. src += src_wrap;
  368. dst += dst_wrap;
  369. }
  370. }
  371. /* 1x2 -> 2x1. width and height are given for the source picture */
  372. static void conv411(UINT8 *dst, int dst_wrap,
  373. UINT8 *src, int src_wrap,
  374. int width, int height)
  375. {
  376. int w, c;
  377. UINT8 *s1, *s2, *d;
  378. for(;height > 0; height -= 2) {
  379. s1 = src;
  380. s2 = src + src_wrap;
  381. d = dst;
  382. for(w = width;w > 0; w--) {
  383. c = (s1[0] + s2[0]) >> 1;
  384. d[0] = c;
  385. d[1] = c;
  386. s1++;
  387. s2++;
  388. d += 2;
  389. }
  390. src += src_wrap * 2;
  391. dst += dst_wrap;
  392. }
  393. }
  394. static void img_copy(UINT8 *dst, int dst_wrap,
  395. UINT8 *src, int src_wrap,
  396. int width, int height)
  397. {
  398. for(;height > 0; height--) {
  399. memcpy(dst, src, width);
  400. dst += dst_wrap;
  401. src += src_wrap;
  402. }
  403. }
  404. #define SCALE_BITS 10
  405. #define C_Y (76309 >> (16 - SCALE_BITS))
  406. #define C_RV (117504 >> (16 - SCALE_BITS))
  407. #define C_BU (138453 >> (16 - SCALE_BITS))
  408. #define C_GU (13954 >> (16 - SCALE_BITS))
  409. #define C_GV (34903 >> (16 - SCALE_BITS))
  410. #define RGBOUT(r, g, b, y1)\
  411. {\
  412. y = (y1 - 16) * C_Y;\
  413. r = cm[(y + r_add) >> SCALE_BITS];\
  414. g = cm[(y + g_add) >> SCALE_BITS];\
  415. b = cm[(y + b_add) >> SCALE_BITS];\
  416. }
  417. /* XXX: no chroma interpolating is done */
  418. static void yuv420p_to_bgra32(AVPicture *dst, AVPicture *src,
  419. int width, int height)
  420. {
  421. UINT8 *y1_ptr, *y2_ptr, *cb_ptr, *cr_ptr, *d, *d1, *d2;
  422. int w, y, cb, cr, r_add, g_add, b_add, width2;
  423. UINT8 *cm = cropTbl + MAX_NEG_CROP;
  424. d = dst->data[0];
  425. y1_ptr = src->data[0];
  426. cb_ptr = src->data[1];
  427. cr_ptr = src->data[2];
  428. width2 = width >> 1;
  429. for(;height > 0; height -= 2) {
  430. d1 = d;
  431. d2 = d + dst->linesize[0];
  432. y2_ptr = y1_ptr + src->linesize[0];
  433. for(w = width2; w > 0; w --) {
  434. cb = cb_ptr[0] - 128;
  435. cr = cr_ptr[0] - 128;
  436. r_add = C_RV * cr + (1 << (SCALE_BITS - 1));
  437. g_add = - C_GU * cb - C_GV * cr + (1 << (SCALE_BITS - 1));
  438. b_add = C_BU * cb + (1 << (SCALE_BITS - 1));
  439. /* output 4 pixels */
  440. RGBOUT(d1[2], d1[1], d1[0], y1_ptr[0]);
  441. RGBOUT(d1[6], d1[5], d1[4], y1_ptr[1]);
  442. RGBOUT(d2[2], d2[1], d2[0], y2_ptr[0]);
  443. RGBOUT(d2[6], d2[5], d2[4], y2_ptr[1]);
  444. d1[3] = d1[7] = d2[3] = d2[7] = 255;
  445. d1 += 8;
  446. d2 += 8;
  447. y1_ptr += 2;
  448. y2_ptr += 2;
  449. cb_ptr++;
  450. cr_ptr++;
  451. }
  452. d += 2 * dst->linesize[0];
  453. y1_ptr += 2 * src->linesize[0] - width;
  454. cb_ptr += src->linesize[1] - width2;
  455. cr_ptr += src->linesize[2] - width2;
  456. }
  457. }
  458. /* XXX: no chroma interpolating is done */
  459. static void yuv420p_to_rgba32(AVPicture *dst, AVPicture *src,
  460. int width, int height)
  461. {
  462. UINT8 *y1_ptr, *y2_ptr, *cb_ptr, *cr_ptr, *d, *d1, *d2;
  463. int w, y, cb, cr, r_add, g_add, b_add, width2;
  464. UINT8 *cm = cropTbl + MAX_NEG_CROP;
  465. d = dst->data[0];
  466. y1_ptr = src->data[0];
  467. cb_ptr = src->data[1];
  468. cr_ptr = src->data[2];
  469. width2 = width >> 1;
  470. for(;height > 0; height -= 2) {
  471. d1 = d;
  472. d2 = d + dst->linesize[0];
  473. y2_ptr = y1_ptr + src->linesize[0];
  474. for(w = width2; w > 0; w --) {
  475. cb = cb_ptr[0] - 128;
  476. cr = cr_ptr[0] - 128;
  477. r_add = C_RV * cr + (1 << (SCALE_BITS - 1));
  478. g_add = - C_GU * cb - C_GV * cr + (1 << (SCALE_BITS - 1));
  479. b_add = C_BU * cb + (1 << (SCALE_BITS - 1));
  480. /* output 4 pixels */
  481. RGBOUT(d1[0], d1[1], d1[2], y1_ptr[0]);
  482. RGBOUT(d1[4], d1[5], d1[6], y1_ptr[1]);
  483. RGBOUT(d2[0], d2[1], d2[2], y2_ptr[0]);
  484. RGBOUT(d2[4], d2[5], d2[6], y2_ptr[1]);
  485. d1[3] = d1[7] = d2[3] = d2[7] = 255;
  486. d1 += 8;
  487. d2 += 8;
  488. y1_ptr += 2;
  489. y2_ptr += 2;
  490. cb_ptr++;
  491. cr_ptr++;
  492. }
  493. d += 2 * dst->linesize[0];
  494. y1_ptr += 2 * src->linesize[0] - width;
  495. cb_ptr += src->linesize[1] - width2;
  496. cr_ptr += src->linesize[2] - width2;
  497. }
  498. }
  499. /* XXX: no chroma interpolating is done */
  500. static void yuv420p_to_rgb24(AVPicture *dst, AVPicture *src,
  501. int width, int height)
  502. {
  503. UINT8 *y1_ptr, *y2_ptr, *cb_ptr, *cr_ptr, *d, *d1, *d2;
  504. int w, y, cb, cr, r_add, g_add, b_add, width2;
  505. UINT8 *cm = cropTbl + MAX_NEG_CROP;
  506. d = dst->data[0];
  507. y1_ptr = src->data[0];
  508. cb_ptr = src->data[1];
  509. cr_ptr = src->data[2];
  510. width2 = width >> 1;
  511. for(;height > 0; height -= 2) {
  512. d1 = d;
  513. d2 = d + dst->linesize[0];
  514. y2_ptr = y1_ptr + src->linesize[0];
  515. for(w = width2; w > 0; w --) {
  516. cb = cb_ptr[0] - 128;
  517. cr = cr_ptr[0] - 128;
  518. r_add = C_RV * cr + (1 << (SCALE_BITS - 1));
  519. g_add = - C_GU * cb - C_GV * cr + (1 << (SCALE_BITS - 1));
  520. b_add = C_BU * cb + (1 << (SCALE_BITS - 1));
  521. /* output 4 pixels */
  522. RGBOUT(d1[0], d1[1], d1[2], y1_ptr[0]);
  523. RGBOUT(d1[3], d1[4], d1[5], y1_ptr[1]);
  524. RGBOUT(d2[0], d2[1], d2[2], y2_ptr[0]);
  525. RGBOUT(d2[3], d2[4], d2[5], y2_ptr[1]);
  526. d1 += 6;
  527. d2 += 6;
  528. y1_ptr += 2;
  529. y2_ptr += 2;
  530. cb_ptr++;
  531. cr_ptr++;
  532. }
  533. d += 2 * dst->linesize[0];
  534. y1_ptr += 2 * src->linesize[0] - width;
  535. cb_ptr += src->linesize[1] - width2;
  536. cr_ptr += src->linesize[2] - width2;
  537. }
  538. }
  539. /* XXX: no chroma interpolating is done */
  540. static void yuv422p_to_rgb24(AVPicture *dst, AVPicture *src,
  541. int width, int height)
  542. {
  543. UINT8 *y1_ptr, *cb_ptr, *cr_ptr, *d, *d1;
  544. int w, y, cb, cr, r_add, g_add, b_add, width2;
  545. UINT8 *cm = cropTbl + MAX_NEG_CROP;
  546. d = dst->data[0];
  547. y1_ptr = src->data[0];
  548. cb_ptr = src->data[1];
  549. cr_ptr = src->data[2];
  550. width2 = width >> 1;
  551. for(;height > 0; height --) {
  552. d1 = d;
  553. for(w = width2; w > 0; w --) {
  554. cb = cb_ptr[0] - 128;
  555. cr = cr_ptr[0] - 128;
  556. r_add = C_RV * cr + (1 << (SCALE_BITS - 1));
  557. g_add = - C_GU * cb - C_GV * cr + (1 << (SCALE_BITS - 1));
  558. b_add = C_BU * cb + (1 << (SCALE_BITS - 1));
  559. /* output 2 pixels */
  560. RGBOUT(d1[0], d1[1], d1[2], y1_ptr[0]);
  561. RGBOUT(d1[3], d1[4], d1[5], y1_ptr[1]);
  562. d1 += 6;
  563. y1_ptr += 2;
  564. cb_ptr++;
  565. cr_ptr++;
  566. }
  567. d += dst->linesize[0];
  568. y1_ptr += src->linesize[0] - width;
  569. cb_ptr += src->linesize[1] - width2;
  570. cr_ptr += src->linesize[2] - width2;
  571. }
  572. }
  573. /* XXX: always use linesize. Return -1 if not supported */
  574. int img_convert(AVPicture *dst, int dst_pix_fmt,
  575. AVPicture *src, int pix_fmt,
  576. int width, int height)
  577. {
  578. int i;
  579. assert(pix_fmt != PIX_FMT_ANY && dst_pix_fmt != PIX_FMT_ANY);
  580. if (dst_pix_fmt == pix_fmt) {
  581. switch(pix_fmt) {
  582. case PIX_FMT_YUV420P:
  583. for(i=0;i<3;i++) {
  584. if (i == 1) {
  585. width >>= 1;
  586. height >>= 1;
  587. }
  588. img_copy(dst->data[i], dst->linesize[i],
  589. src->data[i], src->linesize[i],
  590. width, height);
  591. }
  592. break;
  593. default:
  594. return -1;
  595. }
  596. } else if (dst_pix_fmt == PIX_FMT_YUV420P) {
  597. switch(pix_fmt) {
  598. case PIX_FMT_YUV411P:
  599. img_copy(dst->data[0], dst->linesize[0],
  600. src->data[0], src->linesize[0],
  601. width, height);
  602. conv411(dst->data[1], dst->linesize[1],
  603. src->data[1], src->linesize[1],
  604. width / 4, height);
  605. conv411(dst->data[2], dst->linesize[2],
  606. src->data[2], src->linesize[2],
  607. width / 4, height);
  608. break;
  609. case PIX_FMT_YUV410P:
  610. img_copy(dst->data[0], dst->linesize[0],
  611. src->data[0], src->linesize[0],
  612. width, height);
  613. grow22(dst->data[1], dst->linesize[1],
  614. src->data[1], src->linesize[1],
  615. width/2, height/2);
  616. grow22(dst->data[2], dst->linesize[2],
  617. src->data[2], src->linesize[2],
  618. width/2, height/2);
  619. break;
  620. case PIX_FMT_YUV420P:
  621. for(i=0;i<3;i++) {
  622. img_copy(dst->data[i], dst->linesize[i],
  623. src->data[i], src->linesize[i],
  624. width, height);
  625. }
  626. break;
  627. case PIX_FMT_YUV422P:
  628. img_copy(dst->data[0], dst->linesize[0],
  629. src->data[0], src->linesize[0],
  630. width, height);
  631. width >>= 1;
  632. height >>= 1;
  633. for(i=1;i<3;i++) {
  634. shrink2(dst->data[i], dst->linesize[i],
  635. src->data[i], src->linesize[i],
  636. width, height);
  637. }
  638. break;
  639. case PIX_FMT_YUV444P:
  640. img_copy(dst->data[0], dst->linesize[0],
  641. src->data[0], src->linesize[0],
  642. width, height);
  643. width >>= 1;
  644. height >>= 1;
  645. for(i=1;i<3;i++) {
  646. shrink22(dst->data[i], dst->linesize[i],
  647. src->data[i], src->linesize[i],
  648. width, height);
  649. }
  650. break;
  651. case PIX_FMT_YUV422:
  652. yuv422_to_yuv420p(dst->data[0], dst->data[1], dst->data[2],
  653. src->data[0], width, height);
  654. break;
  655. case PIX_FMT_RGB24:
  656. rgb24_to_yuv420p(dst->data[0], dst->data[1], dst->data[2],
  657. src->data[0], width, height);
  658. break;
  659. case PIX_FMT_RGBA32:
  660. rgba32_to_yuv420p(dst->data[0], dst->data[1], dst->data[2],
  661. src->data[0], width, height);
  662. break;
  663. case PIX_FMT_BGR24:
  664. bgr24_to_yuv420p(dst->data[0], dst->data[1], dst->data[2],
  665. src->data[0], width, height);
  666. break;
  667. case PIX_FMT_BGRA32:
  668. bgra32_to_yuv420p(dst->data[0], dst->data[1], dst->data[2],
  669. src->data[0], width, height);
  670. break;
  671. default:
  672. return -1;
  673. }
  674. } else if (dst_pix_fmt == PIX_FMT_RGB24) {
  675. switch(pix_fmt) {
  676. case PIX_FMT_YUV420P:
  677. yuv420p_to_rgb24(dst, src, width, height);
  678. break;
  679. case PIX_FMT_YUV422P:
  680. yuv422p_to_rgb24(dst, src, width, height);
  681. break;
  682. default:
  683. return -1;
  684. }
  685. } else if (dst_pix_fmt == PIX_FMT_RGBA32) {
  686. switch(pix_fmt) {
  687. case PIX_FMT_YUV420P:
  688. yuv420p_to_rgba32(dst, src, width, height);
  689. break;
  690. default:
  691. return -1;
  692. }
  693. } else if (dst_pix_fmt == PIX_FMT_BGRA32) {
  694. switch(pix_fmt) {
  695. case PIX_FMT_YUV420P:
  696. yuv420p_to_bgra32(dst, src, width, height);
  697. break;
  698. default:
  699. return -1;
  700. }
  701. } else {
  702. return -1;
  703. }
  704. return 0;
  705. }
  706. /* filter parameters: [-1 4 2 4 -1] // 8 */
  707. static void deinterlace_line(UINT8 *dst, UINT8 *src, int src_wrap,
  708. int size)
  709. {
  710. UINT8 *cm = cropTbl + MAX_NEG_CROP;
  711. int sum;
  712. UINT8 *s;
  713. for(;size > 0;size--) {
  714. s = src;
  715. sum = -s[0];
  716. s += src_wrap;
  717. sum += s[0] << 2;
  718. s += src_wrap;
  719. sum += s[0] << 1;
  720. s += src_wrap;
  721. sum += s[0] << 2;
  722. s += src_wrap;
  723. sum += -s[0];
  724. dst[0] = cm[(sum + 4) >> 3];
  725. dst++;
  726. src++;
  727. }
  728. }
  729. /* deinterlacing : 2 temporal taps, 3 spatial taps linear filter. The
  730. top field is copied as is, but the bottom field is deinterlaced
  731. against the top field. */
  732. static void deinterlace_bottom_field(UINT8 *dst, int dst_wrap,
  733. UINT8 *src1, int src_wrap,
  734. int width, int height)
  735. {
  736. UINT8 *src, *ptr;
  737. int y, y1, i;
  738. UINT8 *buf;
  739. buf = (UINT8*)av_malloc(5 * width);
  740. src = src1;
  741. for(y=0;y<height;y+=2) {
  742. /* copy top field line */
  743. memcpy(dst, src, width);
  744. dst += dst_wrap;
  745. src += (1 - 2) * src_wrap;
  746. y1 = y - 2;
  747. if (y1 >= 0 && (y1 + 4) < height) {
  748. /* fast case : no edges */
  749. deinterlace_line(dst, src, src_wrap, width);
  750. } else {
  751. /* in order to use the same function, we use an intermediate buffer */
  752. ptr = buf;
  753. for(i=0;i<5;i++) {
  754. if (y1 < 0)
  755. memcpy(ptr, src1, width);
  756. else if (y1 >= height)
  757. memcpy(ptr, src1 + (height - 1) * src_wrap, width);
  758. else
  759. memcpy(ptr, src1 + y1 * src_wrap, width);
  760. y1++;
  761. ptr += width;
  762. }
  763. deinterlace_line(dst, buf, width, width);
  764. }
  765. dst += dst_wrap;
  766. src += (2 + 1) * src_wrap;
  767. }
  768. av_free(buf);
  769. }
  770. /* deinterlace, return -1 if format not handled */
  771. int avpicture_deinterlace(AVPicture *dst, AVPicture *src,
  772. int pix_fmt, int width, int height)
  773. {
  774. int i;
  775. if (pix_fmt != PIX_FMT_YUV420P &&
  776. pix_fmt != PIX_FMT_YUV422P &&
  777. pix_fmt != PIX_FMT_YUV444P)
  778. return -1;
  779. if ((width & 1) != 0 || (height & 3) != 0)
  780. return -1;
  781. for(i=0;i<3;i++) {
  782. if (i == 1) {
  783. switch(pix_fmt) {
  784. case PIX_FMT_YUV420P:
  785. width >>= 1;
  786. height >>= 1;
  787. break;
  788. case PIX_FMT_YUV422P:
  789. width >>= 1;
  790. break;
  791. default:
  792. break;
  793. }
  794. }
  795. deinterlace_bottom_field(dst->data[i], dst->linesize[i],
  796. src->data[i], src->linesize[i],
  797. width, height);
  798. }
  799. return 0;
  800. }
  801. #undef FIX