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.

162 lines
3.7KB

  1. /*
  2. * .Y.U.V image format
  3. * Copyright (c) 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. #include "avformat.h"
  22. static int sizes[][2] = {
  23. { 640, 480 },
  24. { 720, 480 },
  25. { 720, 576 },
  26. { 352, 288 },
  27. { 352, 240 },
  28. { 160, 128 },
  29. { 512, 384 },
  30. { 640, 352 },
  31. { 640, 240 },
  32. };
  33. static int infer_size(int *width_ptr, int *height_ptr, int size)
  34. {
  35. int i;
  36. for(i=0;i<sizeof(sizes)/sizeof(sizes[0]);i++) {
  37. if ((sizes[i][0] * sizes[i][1]) == size) {
  38. *width_ptr = sizes[i][0];
  39. *height_ptr = sizes[i][1];
  40. return 0;
  41. }
  42. }
  43. return -1;
  44. }
  45. static int yuv_read(ByteIOContext *f,
  46. int (*alloc_cb)(void *opaque, AVImageInfo *info), void *opaque)
  47. {
  48. ByteIOContext pb1, *pb = &pb1;
  49. int img_size, ret;
  50. char fname[1024], *p;
  51. int size;
  52. URLContext *h;
  53. AVImageInfo info1, *info = &info1;
  54. img_size = url_fsize(f);
  55. /* XXX: hack hack */
  56. h = url_fileno(f);
  57. url_get_filename(h, fname, sizeof(fname));
  58. if (infer_size(&info->width, &info->height, img_size) < 0) {
  59. return AVERROR_IO;
  60. }
  61. info->pix_fmt = PIX_FMT_YUV420P;
  62. ret = alloc_cb(opaque, info);
  63. if (ret)
  64. return ret;
  65. size = info->width * info->height;
  66. p = strrchr(fname, '.');
  67. if (!p || p[1] != 'Y')
  68. return AVERROR_IO;
  69. get_buffer(f, info->pict.data[0], size);
  70. p[1] = 'U';
  71. if (url_fopen(pb, fname, URL_RDONLY) < 0)
  72. return AVERROR_IO;
  73. get_buffer(pb, info->pict.data[1], size / 4);
  74. url_fclose(pb);
  75. p[1] = 'V';
  76. if (url_fopen(pb, fname, URL_RDONLY) < 0)
  77. return AVERROR_IO;
  78. get_buffer(pb, info->pict.data[2], size / 4);
  79. url_fclose(pb);
  80. return 0;
  81. }
  82. static int yuv_write(ByteIOContext *pb2, AVImageInfo *info)
  83. {
  84. ByteIOContext pb1, *pb;
  85. char fname[1024], *p;
  86. int i, j, width, height;
  87. uint8_t *ptr;
  88. URLContext *h;
  89. static const char *ext = "YUV";
  90. /* XXX: hack hack */
  91. h = url_fileno(pb2);
  92. url_get_filename(h, fname, sizeof(fname));
  93. p = strrchr(fname, '.');
  94. if (!p || p[1] != 'Y')
  95. return AVERROR_IO;
  96. width = info->width;
  97. height = info->height;
  98. for(i=0;i<3;i++) {
  99. if (i == 1) {
  100. width >>= 1;
  101. height >>= 1;
  102. }
  103. if (i >= 1) {
  104. pb = &pb1;
  105. p[1] = ext[i];
  106. if (url_fopen(pb, fname, URL_WRONLY) < 0)
  107. return AVERROR_IO;
  108. } else {
  109. pb = pb2;
  110. }
  111. ptr = info->pict.data[i];
  112. for(j=0;j<height;j++) {
  113. put_buffer(pb, ptr, width);
  114. ptr += info->pict.linesize[i];
  115. }
  116. put_flush_packet(pb);
  117. if (i >= 1) {
  118. url_fclose(pb);
  119. }
  120. }
  121. return 0;
  122. }
  123. static int yuv_probe(AVProbeData *pd)
  124. {
  125. if (match_ext(pd->filename, "Y"))
  126. return AVPROBE_SCORE_MAX;
  127. else
  128. return 0;
  129. }
  130. AVImageFormat yuv_image_format = {
  131. "yuv",
  132. "Y",
  133. yuv_probe,
  134. yuv_read,
  135. (1 << PIX_FMT_YUV420P),
  136. yuv_write,
  137. };