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.

218 lines
6.1KB

  1. /*
  2. * Misc image convertion routines
  3. * Copyright (c) 2001 Gerard Lantau.
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program 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
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, write to the Free Software
  17. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18. */
  19. #include <stdlib.h>
  20. #include <stdio.h>
  21. #include <string.h>
  22. #include "avcodec.h"
  23. #ifdef USE_FASTMEMCPY
  24. #include "fastmemcpy.h"
  25. #endif
  26. /* XXX: totally non optimized */
  27. static void yuv422_to_yuv420p(UINT8 *lum, UINT8 *cb, UINT8 *cr,
  28. UINT8 *src, int width, int height)
  29. {
  30. int x, y;
  31. UINT8 *p = src;
  32. for(y=0;y<height;y+=2) {
  33. for(x=0;x<width;x+=2) {
  34. lum[0] = p[0];
  35. cb[0] = p[1];
  36. lum[1] = p[2];
  37. cr[0] = p[3];
  38. p += 4;
  39. lum += 2;
  40. cb++;
  41. cr++;
  42. }
  43. for(x=0;x<width;x+=2) {
  44. lum[0] = p[0];
  45. lum[1] = p[2];
  46. p += 4;
  47. lum += 2;
  48. }
  49. }
  50. }
  51. #define SCALEBITS 8
  52. #define ONE_HALF (1 << (SCALEBITS - 1))
  53. #define FIX(x) ((int) ((x) * (1L<<SCALEBITS) + 0.5))
  54. static void rgb24_to_yuv420p(UINT8 *lum, UINT8 *cb, UINT8 *cr,
  55. UINT8 *src, int width, int height)
  56. {
  57. int wrap, wrap3, x, y;
  58. int r, g, b, r1, g1, b1;
  59. UINT8 *p;
  60. wrap = width;
  61. wrap3 = width * 3;
  62. p = src;
  63. for(y=0;y<height;y+=2) {
  64. for(x=0;x<width;x+=2) {
  65. r = p[0];
  66. g = p[1];
  67. b = p[2];
  68. r1 = r;
  69. g1 = g;
  70. b1 = b;
  71. lum[0] = (FIX(0.29900) * r + FIX(0.58700) * g +
  72. FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
  73. r = p[3];
  74. g = p[4];
  75. b = p[5];
  76. r1 += r;
  77. g1 += g;
  78. b1 += b;
  79. lum[1] = (FIX(0.29900) * r + FIX(0.58700) * g +
  80. FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
  81. p += wrap3;
  82. lum += wrap;
  83. r = p[0];
  84. g = p[1];
  85. b = p[2];
  86. r1 += r;
  87. g1 += g;
  88. b1 += b;
  89. lum[0] = (FIX(0.29900) * r + FIX(0.58700) * g +
  90. FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
  91. r = p[3];
  92. g = p[4];
  93. b = p[5];
  94. r1 += r;
  95. g1 += g;
  96. b1 += b;
  97. lum[1] = (FIX(0.29900) * r + FIX(0.58700) * g +
  98. FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
  99. cb[0] = ((- FIX(0.16874) * r1 - FIX(0.33126) * g1 +
  100. FIX(0.50000) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128;
  101. cr[0] = ((FIX(0.50000) * r1 - FIX(0.41869) * g1 -
  102. FIX(0.08131) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128;
  103. cb++;
  104. cr++;
  105. p += -wrap3 + 2 * 3;
  106. lum += -wrap + 2;
  107. }
  108. p += wrap3;
  109. lum += wrap;
  110. }
  111. }
  112. static void bgr24_to_yuv420p(UINT8 *lum, UINT8 *cb, UINT8 *cr,
  113. UINT8 *src, int width, int height)
  114. {
  115. int wrap, wrap3, x, y;
  116. int r, g, b, r1, g1, b1;
  117. UINT8 *p;
  118. wrap = width;
  119. wrap3 = width * 3;
  120. p = src;
  121. for(y=0;y<height;y+=2) {
  122. for(x=0;x<width;x+=2) {
  123. b = p[0];
  124. g = p[1];
  125. r = p[2];
  126. r1 = r;
  127. g1 = g;
  128. b1 = b;
  129. lum[0] = (FIX(0.29900) * r + FIX(0.58700) * g +
  130. FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
  131. b = p[3];
  132. g = p[4];
  133. r = p[5];
  134. r1 += r;
  135. g1 += g;
  136. b1 += b;
  137. lum[1] = (FIX(0.29900) * r + FIX(0.58700) * g +
  138. FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
  139. p += wrap3;
  140. lum += wrap;
  141. b = p[0];
  142. g = p[1];
  143. r = p[2];
  144. r1 += r;
  145. g1 += g;
  146. b1 += b;
  147. lum[0] = (FIX(0.29900) * r + FIX(0.58700) * g +
  148. FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
  149. b = p[3];
  150. g = p[4];
  151. r = p[5];
  152. r1 += r;
  153. g1 += g;
  154. b1 += b;
  155. lum[1] = (FIX(0.29900) * r + FIX(0.58700) * g +
  156. FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
  157. cb[0] = ((- FIX(0.16874) * r1 - FIX(0.33126) * g1 +
  158. FIX(0.50000) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128;
  159. cr[0] = ((FIX(0.50000) * r1 - FIX(0.41869) * g1 -
  160. FIX(0.08131) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128;
  161. cb++;
  162. cr++;
  163. p += -wrap3 + 2 * 3;
  164. lum += -wrap + 2;
  165. }
  166. p += wrap3;
  167. lum += wrap;
  168. }
  169. }
  170. int img_convert_to_yuv420(UINT8 *img_out, UINT8 *img,
  171. int pix_fmt, int width, int height)
  172. {
  173. UINT8 *pict;
  174. int size, size_out;
  175. UINT8 *picture[3];
  176. pict = img_out;
  177. size = width * height;
  178. size_out = (size * 3) / 2;
  179. picture[0] = pict;
  180. picture[1] = pict + size;
  181. picture[2] = picture[1] + (size / 4);
  182. switch(pix_fmt) {
  183. case PIX_FMT_YUV420P:
  184. memcpy(pict, img, size_out);
  185. break;
  186. case PIX_FMT_YUV422:
  187. yuv422_to_yuv420p(picture[0], picture[1], picture[2],
  188. img, width, height);
  189. break;
  190. case PIX_FMT_RGB24:
  191. rgb24_to_yuv420p(picture[0], picture[1], picture[2],
  192. img, width, height);
  193. break;
  194. case PIX_FMT_BGR24:
  195. bgr24_to_yuv420p(picture[0], picture[1], picture[2],
  196. img, width, height);
  197. break;
  198. }
  199. return size_out;
  200. }