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.

880 lines
22KB

  1. /*
  2. * templates for image conversion routines
  3. * Copyright (c) 2001, 2002, 2003 Fabrice Bellard.
  4. *
  5. * This file is part of FFmpeg.
  6. *
  7. * FFmpeg is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Lesser General Public
  9. * License as published by the Free Software Foundation; either
  10. * version 2.1 of the License, or (at your option) any later version.
  11. *
  12. * FFmpeg is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with FFmpeg; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20. */
  21. /* This header intentionally has no multiple inclusion guards. It is meant to
  22. * be included multiple times and generates different code depending on the
  23. * value of certain #defines. */
  24. #ifndef RGB_OUT
  25. #define RGB_OUT(d, r, g, b) RGBA_OUT(d, r, g, b, 0xff)
  26. #endif
  27. static void glue(yuv420p_to_, RGB_NAME)(AVPicture *dst, const AVPicture *src,
  28. int width, int height)
  29. {
  30. const uint8_t *y1_ptr, *y2_ptr, *cb_ptr, *cr_ptr;
  31. uint8_t *d, *d1, *d2;
  32. int w, y, cb, cr, r_add, g_add, b_add, width2;
  33. uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
  34. unsigned int r, g, b;
  35. d = dst->data[0];
  36. y1_ptr = src->data[0];
  37. cb_ptr = src->data[1];
  38. cr_ptr = src->data[2];
  39. width2 = (width + 1) >> 1;
  40. for(;height >= 2; height -= 2) {
  41. d1 = d;
  42. d2 = d + dst->linesize[0];
  43. y2_ptr = y1_ptr + src->linesize[0];
  44. for(w = width; w >= 2; w -= 2) {
  45. YUV_TO_RGB1_CCIR(cb_ptr[0], cr_ptr[0]);
  46. /* output 4 pixels */
  47. YUV_TO_RGB2_CCIR(r, g, b, y1_ptr[0]);
  48. RGB_OUT(d1, r, g, b);
  49. YUV_TO_RGB2_CCIR(r, g, b, y1_ptr[1]);
  50. RGB_OUT(d1 + BPP, r, g, b);
  51. YUV_TO_RGB2_CCIR(r, g, b, y2_ptr[0]);
  52. RGB_OUT(d2, r, g, b);
  53. YUV_TO_RGB2_CCIR(r, g, b, y2_ptr[1]);
  54. RGB_OUT(d2 + BPP, r, g, b);
  55. d1 += 2 * BPP;
  56. d2 += 2 * BPP;
  57. y1_ptr += 2;
  58. y2_ptr += 2;
  59. cb_ptr++;
  60. cr_ptr++;
  61. }
  62. /* handle odd width */
  63. if (w) {
  64. YUV_TO_RGB1_CCIR(cb_ptr[0], cr_ptr[0]);
  65. YUV_TO_RGB2_CCIR(r, g, b, y1_ptr[0]);
  66. RGB_OUT(d1, r, g, b);
  67. YUV_TO_RGB2_CCIR(r, g, b, y2_ptr[0]);
  68. RGB_OUT(d2, r, g, b);
  69. d1 += BPP;
  70. d2 += BPP;
  71. y1_ptr++;
  72. y2_ptr++;
  73. cb_ptr++;
  74. cr_ptr++;
  75. }
  76. d += 2 * dst->linesize[0];
  77. y1_ptr += 2 * src->linesize[0] - width;
  78. cb_ptr += src->linesize[1] - width2;
  79. cr_ptr += src->linesize[2] - width2;
  80. }
  81. /* handle odd height */
  82. if (height) {
  83. d1 = d;
  84. for(w = width; w >= 2; w -= 2) {
  85. YUV_TO_RGB1_CCIR(cb_ptr[0], cr_ptr[0]);
  86. /* output 2 pixels */
  87. YUV_TO_RGB2_CCIR(r, g, b, y1_ptr[0]);
  88. RGB_OUT(d1, r, g, b);
  89. YUV_TO_RGB2_CCIR(r, g, b, y1_ptr[1]);
  90. RGB_OUT(d1 + BPP, r, g, b);
  91. d1 += 2 * BPP;
  92. y1_ptr += 2;
  93. cb_ptr++;
  94. cr_ptr++;
  95. }
  96. /* handle width */
  97. if (w) {
  98. YUV_TO_RGB1_CCIR(cb_ptr[0], cr_ptr[0]);
  99. /* output 2 pixels */
  100. YUV_TO_RGB2_CCIR(r, g, b, y1_ptr[0]);
  101. RGB_OUT(d1, r, g, b);
  102. d1 += BPP;
  103. y1_ptr++;
  104. cb_ptr++;
  105. cr_ptr++;
  106. }
  107. }
  108. }
  109. static void glue(yuvj420p_to_, RGB_NAME)(AVPicture *dst, const AVPicture *src,
  110. int width, int height)
  111. {
  112. const uint8_t *y1_ptr, *y2_ptr, *cb_ptr, *cr_ptr;
  113. uint8_t *d, *d1, *d2;
  114. int w, y, cb, cr, r_add, g_add, b_add, width2;
  115. uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
  116. unsigned int r, g, b;
  117. d = dst->data[0];
  118. y1_ptr = src->data[0];
  119. cb_ptr = src->data[1];
  120. cr_ptr = src->data[2];
  121. width2 = (width + 1) >> 1;
  122. for(;height >= 2; height -= 2) {
  123. d1 = d;
  124. d2 = d + dst->linesize[0];
  125. y2_ptr = y1_ptr + src->linesize[0];
  126. for(w = width; w >= 2; w -= 2) {
  127. YUV_TO_RGB1(cb_ptr[0], cr_ptr[0]);
  128. /* output 4 pixels */
  129. YUV_TO_RGB2(r, g, b, y1_ptr[0]);
  130. RGB_OUT(d1, r, g, b);
  131. YUV_TO_RGB2(r, g, b, y1_ptr[1]);
  132. RGB_OUT(d1 + BPP, r, g, b);
  133. YUV_TO_RGB2(r, g, b, y2_ptr[0]);
  134. RGB_OUT(d2, r, g, b);
  135. YUV_TO_RGB2(r, g, b, y2_ptr[1]);
  136. RGB_OUT(d2 + BPP, r, g, b);
  137. d1 += 2 * BPP;
  138. d2 += 2 * BPP;
  139. y1_ptr += 2;
  140. y2_ptr += 2;
  141. cb_ptr++;
  142. cr_ptr++;
  143. }
  144. /* handle odd width */
  145. if (w) {
  146. YUV_TO_RGB1(cb_ptr[0], cr_ptr[0]);
  147. YUV_TO_RGB2(r, g, b, y1_ptr[0]);
  148. RGB_OUT(d1, r, g, b);
  149. YUV_TO_RGB2(r, g, b, y2_ptr[0]);
  150. RGB_OUT(d2, r, g, b);
  151. d1 += BPP;
  152. d2 += BPP;
  153. y1_ptr++;
  154. y2_ptr++;
  155. cb_ptr++;
  156. cr_ptr++;
  157. }
  158. d += 2 * dst->linesize[0];
  159. y1_ptr += 2 * src->linesize[0] - width;
  160. cb_ptr += src->linesize[1] - width2;
  161. cr_ptr += src->linesize[2] - width2;
  162. }
  163. /* handle odd height */
  164. if (height) {
  165. d1 = d;
  166. for(w = width; w >= 2; w -= 2) {
  167. YUV_TO_RGB1(cb_ptr[0], cr_ptr[0]);
  168. /* output 2 pixels */
  169. YUV_TO_RGB2(r, g, b, y1_ptr[0]);
  170. RGB_OUT(d1, r, g, b);
  171. YUV_TO_RGB2(r, g, b, y1_ptr[1]);
  172. RGB_OUT(d1 + BPP, r, g, b);
  173. d1 += 2 * BPP;
  174. y1_ptr += 2;
  175. cb_ptr++;
  176. cr_ptr++;
  177. }
  178. /* handle width */
  179. if (w) {
  180. YUV_TO_RGB1(cb_ptr[0], cr_ptr[0]);
  181. /* output 2 pixels */
  182. YUV_TO_RGB2(r, g, b, y1_ptr[0]);
  183. RGB_OUT(d1, r, g, b);
  184. d1 += BPP;
  185. y1_ptr++;
  186. cb_ptr++;
  187. cr_ptr++;
  188. }
  189. }
  190. }
  191. static void glue(RGB_NAME, _to_yuv420p)(AVPicture *dst, const AVPicture *src,
  192. int width, int height)
  193. {
  194. int wrap, wrap3, width2;
  195. int r, g, b, r1, g1, b1, w;
  196. uint8_t *lum, *cb, *cr;
  197. const uint8_t *p;
  198. lum = dst->data[0];
  199. cb = dst->data[1];
  200. cr = dst->data[2];
  201. width2 = (width + 1) >> 1;
  202. wrap = dst->linesize[0];
  203. wrap3 = src->linesize[0];
  204. p = src->data[0];
  205. for(;height>=2;height -= 2) {
  206. for(w = width; w >= 2; w -= 2) {
  207. RGB_IN(r, g, b, p);
  208. r1 = r;
  209. g1 = g;
  210. b1 = b;
  211. lum[0] = RGB_TO_Y_CCIR(r, g, b);
  212. RGB_IN(r, g, b, p + BPP);
  213. r1 += r;
  214. g1 += g;
  215. b1 += b;
  216. lum[1] = RGB_TO_Y_CCIR(r, g, b);
  217. p += wrap3;
  218. lum += wrap;
  219. RGB_IN(r, g, b, p);
  220. r1 += r;
  221. g1 += g;
  222. b1 += b;
  223. lum[0] = RGB_TO_Y_CCIR(r, g, b);
  224. RGB_IN(r, g, b, p + BPP);
  225. r1 += r;
  226. g1 += g;
  227. b1 += b;
  228. lum[1] = RGB_TO_Y_CCIR(r, g, b);
  229. cb[0] = RGB_TO_U_CCIR(r1, g1, b1, 2);
  230. cr[0] = RGB_TO_V_CCIR(r1, g1, b1, 2);
  231. cb++;
  232. cr++;
  233. p += -wrap3 + 2 * BPP;
  234. lum += -wrap + 2;
  235. }
  236. if (w) {
  237. RGB_IN(r, g, b, p);
  238. r1 = r;
  239. g1 = g;
  240. b1 = b;
  241. lum[0] = RGB_TO_Y_CCIR(r, g, b);
  242. p += wrap3;
  243. lum += wrap;
  244. RGB_IN(r, g, b, p);
  245. r1 += r;
  246. g1 += g;
  247. b1 += b;
  248. lum[0] = RGB_TO_Y_CCIR(r, g, b);
  249. cb[0] = RGB_TO_U_CCIR(r1, g1, b1, 1);
  250. cr[0] = RGB_TO_V_CCIR(r1, g1, b1, 1);
  251. cb++;
  252. cr++;
  253. p += -wrap3 + BPP;
  254. lum += -wrap + 1;
  255. }
  256. p += wrap3 + (wrap3 - width * BPP);
  257. lum += wrap + (wrap - width);
  258. cb += dst->linesize[1] - width2;
  259. cr += dst->linesize[2] - width2;
  260. }
  261. /* handle odd height */
  262. if (height) {
  263. for(w = width; w >= 2; w -= 2) {
  264. RGB_IN(r, g, b, p);
  265. r1 = r;
  266. g1 = g;
  267. b1 = b;
  268. lum[0] = RGB_TO_Y_CCIR(r, g, b);
  269. RGB_IN(r, g, b, p + BPP);
  270. r1 += r;
  271. g1 += g;
  272. b1 += b;
  273. lum[1] = RGB_TO_Y_CCIR(r, g, b);
  274. cb[0] = RGB_TO_U_CCIR(r1, g1, b1, 1);
  275. cr[0] = RGB_TO_V_CCIR(r1, g1, b1, 1);
  276. cb++;
  277. cr++;
  278. p += 2 * BPP;
  279. lum += 2;
  280. }
  281. if (w) {
  282. RGB_IN(r, g, b, p);
  283. lum[0] = RGB_TO_Y_CCIR(r, g, b);
  284. cb[0] = RGB_TO_U_CCIR(r, g, b, 0);
  285. cr[0] = RGB_TO_V_CCIR(r, g, b, 0);
  286. }
  287. }
  288. }
  289. static void glue(RGB_NAME, _to_gray)(AVPicture *dst, const AVPicture *src,
  290. int width, int height)
  291. {
  292. const unsigned char *p;
  293. unsigned char *q;
  294. int r, g, b, dst_wrap, src_wrap;
  295. int x, y;
  296. p = src->data[0];
  297. src_wrap = src->linesize[0] - BPP * width;
  298. q = dst->data[0];
  299. dst_wrap = dst->linesize[0] - width;
  300. for(y=0;y<height;y++) {
  301. for(x=0;x<width;x++) {
  302. RGB_IN(r, g, b, p);
  303. q[0] = RGB_TO_Y(r, g, b);
  304. q++;
  305. p += BPP;
  306. }
  307. p += src_wrap;
  308. q += dst_wrap;
  309. }
  310. }
  311. static void glue(gray_to_, RGB_NAME)(AVPicture *dst, const AVPicture *src,
  312. int width, int height)
  313. {
  314. const unsigned char *p;
  315. unsigned char *q;
  316. int r, dst_wrap, src_wrap;
  317. int x, y;
  318. p = src->data[0];
  319. src_wrap = src->linesize[0] - width;
  320. q = dst->data[0];
  321. dst_wrap = dst->linesize[0] - BPP * width;
  322. for(y=0;y<height;y++) {
  323. for(x=0;x<width;x++) {
  324. r = p[0];
  325. RGB_OUT(q, r, r, r);
  326. q += BPP;
  327. p ++;
  328. }
  329. p += src_wrap;
  330. q += dst_wrap;
  331. }
  332. }
  333. static void glue(pal8_to_, RGB_NAME)(AVPicture *dst, const AVPicture *src,
  334. int width, int height)
  335. {
  336. const unsigned char *p;
  337. unsigned char *q;
  338. int r, g, b, dst_wrap, src_wrap;
  339. int x, y;
  340. uint32_t v;
  341. const uint32_t *palette;
  342. p = src->data[0];
  343. src_wrap = src->linesize[0] - width;
  344. palette = (uint32_t *)src->data[1];
  345. q = dst->data[0];
  346. dst_wrap = dst->linesize[0] - BPP * width;
  347. for(y=0;y<height;y++) {
  348. for(x=0;x<width;x++) {
  349. v = palette[p[0]];
  350. r = (v >> 16) & 0xff;
  351. g = (v >> 8) & 0xff;
  352. b = (v) & 0xff;
  353. #ifdef RGBA_OUT
  354. {
  355. int a;
  356. a = (v >> 24) & 0xff;
  357. RGBA_OUT(q, r, g, b, a);
  358. }
  359. #else
  360. RGB_OUT(q, r, g, b);
  361. #endif
  362. q += BPP;
  363. p ++;
  364. }
  365. p += src_wrap;
  366. q += dst_wrap;
  367. }
  368. }
  369. // RGB24 has optimized routines
  370. #if !defined(FMT_RGB32) && !defined(FMT_RGB24)
  371. /* alpha support */
  372. static void glue(rgb32_to_, RGB_NAME)(AVPicture *dst, const AVPicture *src,
  373. int width, int height)
  374. {
  375. const uint8_t *s;
  376. uint8_t *d;
  377. int src_wrap, dst_wrap, j, y;
  378. unsigned int v, r, g, b;
  379. #ifdef RGBA_OUT
  380. unsigned int a;
  381. #endif
  382. s = src->data[0];
  383. src_wrap = src->linesize[0] - width * 4;
  384. d = dst->data[0];
  385. dst_wrap = dst->linesize[0] - width * BPP;
  386. for(y=0;y<height;y++) {
  387. for(j = 0;j < width; j++) {
  388. v = ((const uint32_t *)(s))[0];
  389. r = (v >> 16) & 0xff;
  390. g = (v >> 8) & 0xff;
  391. b = v & 0xff;
  392. #ifdef RGBA_OUT
  393. a = (v >> 24) & 0xff;
  394. RGBA_OUT(d, r, g, b, a);
  395. #else
  396. RGB_OUT(d, r, g, b);
  397. #endif
  398. s += 4;
  399. d += BPP;
  400. }
  401. s += src_wrap;
  402. d += dst_wrap;
  403. }
  404. }
  405. static void glue(RGB_NAME, _to_rgb32)(AVPicture *dst, const AVPicture *src,
  406. int width, int height)
  407. {
  408. const uint8_t *s;
  409. uint8_t *d;
  410. int src_wrap, dst_wrap, j, y;
  411. unsigned int r, g, b;
  412. #ifdef RGBA_IN
  413. unsigned int a;
  414. #endif
  415. s = src->data[0];
  416. src_wrap = src->linesize[0] - width * BPP;
  417. d = dst->data[0];
  418. dst_wrap = dst->linesize[0] - width * 4;
  419. for(y=0;y<height;y++) {
  420. for(j = 0;j < width; j++) {
  421. #ifdef RGBA_IN
  422. RGBA_IN(r, g, b, a, s);
  423. ((uint32_t *)(d))[0] = (a << 24) | (r << 16) | (g << 8) | b;
  424. #else
  425. RGB_IN(r, g, b, s);
  426. ((uint32_t *)(d))[0] = (0xff << 24) | (r << 16) | (g << 8) | b;
  427. #endif
  428. d += 4;
  429. s += BPP;
  430. }
  431. s += src_wrap;
  432. d += dst_wrap;
  433. }
  434. }
  435. #endif /* !defined(FMT_RGB32) */
  436. #ifndef FMT_RGB24
  437. static void glue(rgb24_to_, RGB_NAME)(AVPicture *dst, const AVPicture *src,
  438. int width, int height)
  439. {
  440. const uint8_t *s;
  441. uint8_t *d;
  442. int src_wrap, dst_wrap, j, y;
  443. unsigned int r, g, b;
  444. s = src->data[0];
  445. src_wrap = src->linesize[0] - width * 3;
  446. d = dst->data[0];
  447. dst_wrap = dst->linesize[0] - width * BPP;
  448. for(y=0;y<height;y++) {
  449. for(j = 0;j < width; j++) {
  450. r = s[0];
  451. g = s[1];
  452. b = s[2];
  453. RGB_OUT(d, r, g, b);
  454. s += 3;
  455. d += BPP;
  456. }
  457. s += src_wrap;
  458. d += dst_wrap;
  459. }
  460. }
  461. static void glue(RGB_NAME, _to_rgb24)(AVPicture *dst, const AVPicture *src,
  462. int width, int height)
  463. {
  464. const uint8_t *s;
  465. uint8_t *d;
  466. int src_wrap, dst_wrap, j, y;
  467. unsigned int r, g , b;
  468. s = src->data[0];
  469. src_wrap = src->linesize[0] - width * BPP;
  470. d = dst->data[0];
  471. dst_wrap = dst->linesize[0] - width * 3;
  472. for(y=0;y<height;y++) {
  473. for(j = 0;j < width; j++) {
  474. RGB_IN(r, g, b, s)
  475. d[0] = r;
  476. d[1] = g;
  477. d[2] = b;
  478. d += 3;
  479. s += BPP;
  480. }
  481. s += src_wrap;
  482. d += dst_wrap;
  483. }
  484. }
  485. #endif /* !FMT_RGB24 */
  486. #ifdef FMT_RGB24
  487. static void yuv444p_to_rgb24(AVPicture *dst, const AVPicture *src,
  488. int width, int height)
  489. {
  490. const uint8_t *y1_ptr, *cb_ptr, *cr_ptr;
  491. uint8_t *d, *d1;
  492. int w, y, cb, cr, r_add, g_add, b_add;
  493. uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
  494. unsigned int r, g, b;
  495. d = dst->data[0];
  496. y1_ptr = src->data[0];
  497. cb_ptr = src->data[1];
  498. cr_ptr = src->data[2];
  499. for(;height > 0; height --) {
  500. d1 = d;
  501. for(w = width; w > 0; w--) {
  502. YUV_TO_RGB1_CCIR(cb_ptr[0], cr_ptr[0]);
  503. YUV_TO_RGB2_CCIR(r, g, b, y1_ptr[0]);
  504. RGB_OUT(d1, r, g, b);
  505. d1 += BPP;
  506. y1_ptr++;
  507. cb_ptr++;
  508. cr_ptr++;
  509. }
  510. d += dst->linesize[0];
  511. y1_ptr += src->linesize[0] - width;
  512. cb_ptr += src->linesize[1] - width;
  513. cr_ptr += src->linesize[2] - width;
  514. }
  515. }
  516. static void yuvj444p_to_rgb24(AVPicture *dst, const AVPicture *src,
  517. int width, int height)
  518. {
  519. const uint8_t *y1_ptr, *cb_ptr, *cr_ptr;
  520. uint8_t *d, *d1;
  521. int w, y, cb, cr, r_add, g_add, b_add;
  522. uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
  523. unsigned int r, g, b;
  524. d = dst->data[0];
  525. y1_ptr = src->data[0];
  526. cb_ptr = src->data[1];
  527. cr_ptr = src->data[2];
  528. for(;height > 0; height --) {
  529. d1 = d;
  530. for(w = width; w > 0; w--) {
  531. YUV_TO_RGB1(cb_ptr[0], cr_ptr[0]);
  532. YUV_TO_RGB2(r, g, b, y1_ptr[0]);
  533. RGB_OUT(d1, r, g, b);
  534. d1 += BPP;
  535. y1_ptr++;
  536. cb_ptr++;
  537. cr_ptr++;
  538. }
  539. d += dst->linesize[0];
  540. y1_ptr += src->linesize[0] - width;
  541. cb_ptr += src->linesize[1] - width;
  542. cr_ptr += src->linesize[2] - width;
  543. }
  544. }
  545. static void rgb24_to_yuv444p(AVPicture *dst, const AVPicture *src,
  546. int width, int height)
  547. {
  548. int src_wrap, x, y;
  549. int r, g, b;
  550. uint8_t *lum, *cb, *cr;
  551. const uint8_t *p;
  552. lum = dst->data[0];
  553. cb = dst->data[1];
  554. cr = dst->data[2];
  555. src_wrap = src->linesize[0] - width * BPP;
  556. p = src->data[0];
  557. for(y=0;y<height;y++) {
  558. for(x=0;x<width;x++) {
  559. RGB_IN(r, g, b, p);
  560. lum[0] = RGB_TO_Y_CCIR(r, g, b);
  561. cb[0] = RGB_TO_U_CCIR(r, g, b, 0);
  562. cr[0] = RGB_TO_V_CCIR(r, g, b, 0);
  563. p += BPP;
  564. cb++;
  565. cr++;
  566. lum++;
  567. }
  568. p += src_wrap;
  569. lum += dst->linesize[0] - width;
  570. cb += dst->linesize[1] - width;
  571. cr += dst->linesize[2] - width;
  572. }
  573. }
  574. static void rgb24_to_yuvj420p(AVPicture *dst, const AVPicture *src,
  575. int width, int height)
  576. {
  577. int wrap, wrap3, width2;
  578. int r, g, b, r1, g1, b1, w;
  579. uint8_t *lum, *cb, *cr;
  580. const uint8_t *p;
  581. lum = dst->data[0];
  582. cb = dst->data[1];
  583. cr = dst->data[2];
  584. width2 = (width + 1) >> 1;
  585. wrap = dst->linesize[0];
  586. wrap3 = src->linesize[0];
  587. p = src->data[0];
  588. for(;height>=2;height -= 2) {
  589. for(w = width; w >= 2; w -= 2) {
  590. RGB_IN(r, g, b, p);
  591. r1 = r;
  592. g1 = g;
  593. b1 = b;
  594. lum[0] = RGB_TO_Y(r, g, b);
  595. RGB_IN(r, g, b, p + BPP);
  596. r1 += r;
  597. g1 += g;
  598. b1 += b;
  599. lum[1] = RGB_TO_Y(r, g, b);
  600. p += wrap3;
  601. lum += wrap;
  602. RGB_IN(r, g, b, p);
  603. r1 += r;
  604. g1 += g;
  605. b1 += b;
  606. lum[0] = RGB_TO_Y(r, g, b);
  607. RGB_IN(r, g, b, p + BPP);
  608. r1 += r;
  609. g1 += g;
  610. b1 += b;
  611. lum[1] = RGB_TO_Y(r, g, b);
  612. cb[0] = RGB_TO_U(r1, g1, b1, 2);
  613. cr[0] = RGB_TO_V(r1, g1, b1, 2);
  614. cb++;
  615. cr++;
  616. p += -wrap3 + 2 * BPP;
  617. lum += -wrap + 2;
  618. }
  619. if (w) {
  620. RGB_IN(r, g, b, p);
  621. r1 = r;
  622. g1 = g;
  623. b1 = b;
  624. lum[0] = RGB_TO_Y(r, g, b);
  625. p += wrap3;
  626. lum += wrap;
  627. RGB_IN(r, g, b, p);
  628. r1 += r;
  629. g1 += g;
  630. b1 += b;
  631. lum[0] = RGB_TO_Y(r, g, b);
  632. cb[0] = RGB_TO_U(r1, g1, b1, 1);
  633. cr[0] = RGB_TO_V(r1, g1, b1, 1);
  634. cb++;
  635. cr++;
  636. p += -wrap3 + BPP;
  637. lum += -wrap + 1;
  638. }
  639. p += wrap3 + (wrap3 - width * BPP);
  640. lum += wrap + (wrap - width);
  641. cb += dst->linesize[1] - width2;
  642. cr += dst->linesize[2] - width2;
  643. }
  644. /* handle odd height */
  645. if (height) {
  646. for(w = width; w >= 2; w -= 2) {
  647. RGB_IN(r, g, b, p);
  648. r1 = r;
  649. g1 = g;
  650. b1 = b;
  651. lum[0] = RGB_TO_Y(r, g, b);
  652. RGB_IN(r, g, b, p + BPP);
  653. r1 += r;
  654. g1 += g;
  655. b1 += b;
  656. lum[1] = RGB_TO_Y(r, g, b);
  657. cb[0] = RGB_TO_U(r1, g1, b1, 1);
  658. cr[0] = RGB_TO_V(r1, g1, b1, 1);
  659. cb++;
  660. cr++;
  661. p += 2 * BPP;
  662. lum += 2;
  663. }
  664. if (w) {
  665. RGB_IN(r, g, b, p);
  666. lum[0] = RGB_TO_Y(r, g, b);
  667. cb[0] = RGB_TO_U(r, g, b, 0);
  668. cr[0] = RGB_TO_V(r, g, b, 0);
  669. }
  670. }
  671. }
  672. static void rgb24_to_yuvj444p(AVPicture *dst, const AVPicture *src,
  673. int width, int height)
  674. {
  675. int src_wrap, x, y;
  676. int r, g, b;
  677. uint8_t *lum, *cb, *cr;
  678. const uint8_t *p;
  679. lum = dst->data[0];
  680. cb = dst->data[1];
  681. cr = dst->data[2];
  682. src_wrap = src->linesize[0] - width * BPP;
  683. p = src->data[0];
  684. for(y=0;y<height;y++) {
  685. for(x=0;x<width;x++) {
  686. RGB_IN(r, g, b, p);
  687. lum[0] = RGB_TO_Y(r, g, b);
  688. cb[0] = RGB_TO_U(r, g, b, 0);
  689. cr[0] = RGB_TO_V(r, g, b, 0);
  690. p += BPP;
  691. cb++;
  692. cr++;
  693. lum++;
  694. }
  695. p += src_wrap;
  696. lum += dst->linesize[0] - width;
  697. cb += dst->linesize[1] - width;
  698. cr += dst->linesize[2] - width;
  699. }
  700. }
  701. #endif /* FMT_RGB24 */
  702. #if defined(FMT_RGB24) || defined(FMT_RGB32)
  703. static void glue(RGB_NAME, _to_pal8)(AVPicture *dst, const AVPicture *src,
  704. int width, int height)
  705. {
  706. const unsigned char *p;
  707. unsigned char *q;
  708. int dst_wrap, src_wrap;
  709. int x, y, has_alpha;
  710. unsigned int r, g, b;
  711. p = src->data[0];
  712. src_wrap = src->linesize[0] - BPP * width;
  713. q = dst->data[0];
  714. dst_wrap = dst->linesize[0] - width;
  715. has_alpha = 0;
  716. for(y=0;y<height;y++) {
  717. for(x=0;x<width;x++) {
  718. #ifdef RGBA_IN
  719. {
  720. unsigned int a;
  721. RGBA_IN(r, g, b, a, p);
  722. /* crude approximation for alpha ! */
  723. if (a < 0x80) {
  724. has_alpha = 1;
  725. q[0] = TRANSP_INDEX;
  726. } else {
  727. q[0] = gif_clut_index(r, g, b);
  728. }
  729. }
  730. #else
  731. RGB_IN(r, g, b, p);
  732. q[0] = gif_clut_index(r, g, b);
  733. #endif
  734. q++;
  735. p += BPP;
  736. }
  737. p += src_wrap;
  738. q += dst_wrap;
  739. }
  740. build_rgb_palette(dst->data[1], has_alpha);
  741. }
  742. #endif /* defined(FMT_RGB24) || defined(FMT_RGB32) */
  743. #ifdef RGBA_IN
  744. static int glue(get_alpha_info_, RGB_NAME)(const AVPicture *src,
  745. int width, int height)
  746. {
  747. const unsigned char *p;
  748. int src_wrap, ret, x, y;
  749. unsigned int r, g, b, a;
  750. p = src->data[0];
  751. src_wrap = src->linesize[0] - BPP * width;
  752. ret = 0;
  753. for(y=0;y<height;y++) {
  754. for(x=0;x<width;x++) {
  755. RGBA_IN(r, g, b, a, p);
  756. if (a == 0x00) {
  757. ret |= FF_ALPHA_TRANSP;
  758. } else if (a != 0xff) {
  759. ret |= FF_ALPHA_SEMI_TRANSP;
  760. }
  761. p += BPP;
  762. }
  763. p += src_wrap;
  764. }
  765. return ret;
  766. }
  767. #endif /* RGBA_IN */
  768. #undef RGB_IN
  769. #undef RGBA_IN
  770. #undef RGB_OUT
  771. #undef RGBA_OUT
  772. #undef BPP
  773. #undef RGB_NAME
  774. #undef FMT_RGB24
  775. #undef FMT_RGB32