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.

145 lines
4.1KB

  1. /*
  2. * This file is part of Libav.
  3. *
  4. * Libav is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU Lesser General Public
  6. * License as published by the Free Software Foundation; either
  7. * version 2.1 of the License, or (at your option) any later version.
  8. *
  9. * Libav is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. * Lesser General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU Lesser General Public
  15. * License along with Libav; if not, write to the Free Software
  16. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  17. */
  18. #include <stdio.h>
  19. #include <stdlib.h>
  20. #define SCALEBITS 8
  21. #define ONE_HALF (1 << (SCALEBITS - 1))
  22. #define FIX(x) ((int) ((x) * (1L << SCALEBITS) + 0.5))
  23. static void rgb24_to_yuv420p(unsigned char *lum, unsigned char *cb,
  24. unsigned char *cr, unsigned char *src,
  25. int width, int height)
  26. {
  27. int wrap, wrap3, x, y;
  28. int r, g, b, r1, g1, b1;
  29. unsigned char *p;
  30. wrap = width;
  31. wrap3 = width * 3;
  32. p = src;
  33. for (y = 0; y < height; y += 2) {
  34. for (x = 0; x < width; x += 2) {
  35. r = p[0];
  36. g = p[1];
  37. b = p[2];
  38. r1 = r;
  39. g1 = g;
  40. b1 = b;
  41. lum[0] = (FIX(0.29900) * r + FIX(0.58700) * g +
  42. FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
  43. r = p[3];
  44. g = p[4];
  45. b = p[5];
  46. r1 += r;
  47. g1 += g;
  48. b1 += b;
  49. lum[1] = (FIX(0.29900) * r + FIX(0.58700) * g +
  50. FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
  51. p += wrap3;
  52. lum += wrap;
  53. r = p[0];
  54. g = p[1];
  55. b = p[2];
  56. r1 += r;
  57. g1 += g;
  58. b1 += b;
  59. lum[0] = (FIX(0.29900) * r + FIX(0.58700) * g +
  60. FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
  61. r = p[3];
  62. g = p[4];
  63. b = p[5];
  64. r1 += r;
  65. g1 += g;
  66. b1 += b;
  67. lum[1] = (FIX(0.29900) * r + FIX(0.58700) * g +
  68. FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
  69. cb[0] = ((- FIX(0.16874) * r1 - FIX(0.33126) * g1 +
  70. FIX(0.50000) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128;
  71. cr[0] = ((FIX(0.50000) * r1 - FIX(0.41869) * g1 -
  72. FIX(0.08131) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128;
  73. cb++;
  74. cr++;
  75. p += -wrap3 + 2 * 3;
  76. lum += -wrap + 2;
  77. }
  78. p += wrap3;
  79. lum += wrap;
  80. }
  81. }
  82. /* cif format */
  83. #define DEFAULT_WIDTH 352
  84. #define DEFAULT_HEIGHT 288
  85. #define DEFAULT_NB_PICT 50
  86. static void pgmyuv_save(const char *filename, int w, int h,
  87. unsigned char *rgb_tab)
  88. {
  89. FILE *f;
  90. int i, h2, w2;
  91. unsigned char *cb, *cr;
  92. unsigned char *lum_tab, *cb_tab, *cr_tab;
  93. lum_tab = malloc(w * h);
  94. cb_tab = malloc(w * h / 4);
  95. cr_tab = malloc(w * h / 4);
  96. rgb24_to_yuv420p(lum_tab, cb_tab, cr_tab, rgb_tab, w, h);
  97. f = fopen(filename, "wb");
  98. fprintf(f, "P5\n%d %d\n%d\n", w, h * 3 / 2, 255);
  99. fwrite(lum_tab, 1, w * h, f);
  100. h2 = h / 2;
  101. w2 = w / 2;
  102. cb = cb_tab;
  103. cr = cr_tab;
  104. for (i = 0; i < h2; i++) {
  105. fwrite(cb, 1, w2, f);
  106. fwrite(cr, 1, w2, f);
  107. cb += w2;
  108. cr += w2;
  109. }
  110. fclose(f);
  111. free(lum_tab);
  112. free(cb_tab);
  113. free(cr_tab);
  114. }
  115. static unsigned char *rgb_tab;
  116. static int width, height, wrap;
  117. static void put_pixel(int x, int y, int r, int g, int b)
  118. {
  119. unsigned char *p;
  120. if (x < 0 || x >= width ||
  121. y < 0 || y >= height)
  122. return;
  123. p = rgb_tab + y * wrap + x * 3;
  124. p[0] = r;
  125. p[1] = g;
  126. p[2] = b;
  127. }