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.

215 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. /* XXX: totally non optimized */
  24. static void yuv422_to_yuv420p(UINT8 *lum, UINT8 *cb, UINT8 *cr,
  25. UINT8 *src, int width, int height)
  26. {
  27. int x, y;
  28. UINT8 *p = src;
  29. for(y=0;y<height;y+=2) {
  30. for(x=0;x<width;x+=2) {
  31. lum[0] = p[0];
  32. cb[0] = p[1];
  33. lum[1] = p[2];
  34. cr[0] = p[3];
  35. p += 4;
  36. lum += 2;
  37. cb++;
  38. cr++;
  39. }
  40. for(x=0;x<width;x+=2) {
  41. lum[0] = p[0];
  42. lum[1] = p[2];
  43. p += 4;
  44. lum += 2;
  45. }
  46. }
  47. }
  48. #define SCALEBITS 8
  49. #define ONE_HALF (1 << (SCALEBITS - 1))
  50. #define FIX(x) ((int) ((x) * (1L<<SCALEBITS) + 0.5))
  51. static void rgb24_to_yuv420p(UINT8 *lum, UINT8 *cb, UINT8 *cr,
  52. UINT8 *src, int width, int height)
  53. {
  54. int wrap, wrap3, x, y;
  55. int r, g, b, r1, g1, b1;
  56. UINT8 *p;
  57. wrap = width;
  58. wrap3 = width * 3;
  59. p = src;
  60. for(y=0;y<height;y+=2) {
  61. for(x=0;x<width;x+=2) {
  62. r = p[0];
  63. g = p[1];
  64. b = p[2];
  65. r1 = r;
  66. g1 = g;
  67. b1 = b;
  68. lum[0] = (FIX(0.29900) * r + FIX(0.58700) * g +
  69. FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
  70. r = p[3];
  71. g = p[4];
  72. b = p[5];
  73. r1 += r;
  74. g1 += g;
  75. b1 += b;
  76. lum[1] = (FIX(0.29900) * r + FIX(0.58700) * g +
  77. FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
  78. p += wrap3;
  79. lum += wrap;
  80. r = p[0];
  81. g = p[1];
  82. b = p[2];
  83. r1 += r;
  84. g1 += g;
  85. b1 += b;
  86. lum[0] = (FIX(0.29900) * r + FIX(0.58700) * g +
  87. FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
  88. r = p[3];
  89. g = p[4];
  90. b = p[5];
  91. r1 += r;
  92. g1 += g;
  93. b1 += b;
  94. lum[1] = (FIX(0.29900) * r + FIX(0.58700) * g +
  95. FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
  96. cb[0] = ((- FIX(0.16874) * r1 - FIX(0.33126) * g1 +
  97. FIX(0.50000) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128;
  98. cr[0] = ((FIX(0.50000) * r1 - FIX(0.41869) * g1 -
  99. FIX(0.08131) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128;
  100. cb++;
  101. cr++;
  102. p += -wrap3 + 2 * 3;
  103. lum += -wrap + 2;
  104. }
  105. p += wrap3;
  106. lum += wrap;
  107. }
  108. }
  109. static void bgr24_to_yuv420p(UINT8 *lum, UINT8 *cb, UINT8 *cr,
  110. UINT8 *src, int width, int height)
  111. {
  112. int wrap, wrap3, x, y;
  113. int r, g, b, r1, g1, b1;
  114. UINT8 *p;
  115. wrap = width;
  116. wrap3 = width * 3;
  117. p = src;
  118. for(y=0;y<height;y+=2) {
  119. for(x=0;x<width;x+=2) {
  120. b = p[0];
  121. g = p[1];
  122. r = p[2];
  123. r1 = r;
  124. g1 = g;
  125. b1 = b;
  126. lum[0] = (FIX(0.29900) * r + FIX(0.58700) * g +
  127. FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
  128. b = p[3];
  129. g = p[4];
  130. r = p[5];
  131. r1 += r;
  132. g1 += g;
  133. b1 += b;
  134. lum[1] = (FIX(0.29900) * r + FIX(0.58700) * g +
  135. FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
  136. p += wrap3;
  137. lum += wrap;
  138. b = p[0];
  139. g = p[1];
  140. r = p[2];
  141. r1 += r;
  142. g1 += g;
  143. b1 += b;
  144. lum[0] = (FIX(0.29900) * r + FIX(0.58700) * g +
  145. FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
  146. b = p[3];
  147. g = p[4];
  148. r = p[5];
  149. r1 += r;
  150. g1 += g;
  151. b1 += b;
  152. lum[1] = (FIX(0.29900) * r + FIX(0.58700) * g +
  153. FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
  154. cb[0] = ((- FIX(0.16874) * r1 - FIX(0.33126) * g1 +
  155. FIX(0.50000) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128;
  156. cr[0] = ((FIX(0.50000) * r1 - FIX(0.41869) * g1 -
  157. FIX(0.08131) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128;
  158. cb++;
  159. cr++;
  160. p += -wrap3 + 2 * 3;
  161. lum += -wrap + 2;
  162. }
  163. p += wrap3;
  164. lum += wrap;
  165. }
  166. }
  167. int img_convert_to_yuv420(UINT8 *img_out, UINT8 *img,
  168. int pix_fmt, int width, int height)
  169. {
  170. UINT8 *pict;
  171. int size, size_out;
  172. UINT8 *picture[3];
  173. pict = img_out;
  174. size = width * height;
  175. size_out = (size * 3) / 2;
  176. picture[0] = pict;
  177. picture[1] = pict + size;
  178. picture[2] = picture[1] + (size / 4);
  179. switch(pix_fmt) {
  180. case PIX_FMT_YUV420P:
  181. memcpy(pict, img, size_out);
  182. break;
  183. case PIX_FMT_YUV422:
  184. yuv422_to_yuv420p(picture[0], picture[1], picture[2],
  185. img, width, height);
  186. break;
  187. case PIX_FMT_RGB24:
  188. rgb24_to_yuv420p(picture[0], picture[1], picture[2],
  189. img, width, height);
  190. break;
  191. case PIX_FMT_BGR24:
  192. bgr24_to_yuv420p(picture[0], picture[1], picture[2],
  193. img, width, height);
  194. break;
  195. }
  196. return size_out;
  197. }