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.

160 lines
3.7KB

  1. /*
  2. * .Y.U.V image format
  3. * Copyright (c) 2003 Fabrice Bellard.
  4. *
  5. * This library is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU Lesser General Public
  7. * License as published by the Free Software Foundation; either
  8. * version 2 of the License, or (at your option) any later version.
  9. *
  10. * This library 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 GNU
  13. * Lesser General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Lesser General Public
  16. * License along with this library; if not, write to the Free Software
  17. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  18. */
  19. #include "avformat.h"
  20. static int sizes[][2] = {
  21. { 640, 480 },
  22. { 720, 480 },
  23. { 720, 576 },
  24. { 352, 288 },
  25. { 352, 240 },
  26. { 160, 128 },
  27. { 512, 384 },
  28. { 640, 352 },
  29. { 640, 240 },
  30. };
  31. static int infer_size(int *width_ptr, int *height_ptr, int size)
  32. {
  33. int i;
  34. for(i=0;i<sizeof(sizes)/sizeof(sizes[0]);i++) {
  35. if ((sizes[i][0] * sizes[i][1]) == size) {
  36. *width_ptr = sizes[i][0];
  37. *height_ptr = sizes[i][1];
  38. return 0;
  39. }
  40. }
  41. return -1;
  42. }
  43. static int yuv_read(ByteIOContext *f,
  44. int (*alloc_cb)(void *opaque, AVImageInfo *info), void *opaque)
  45. {
  46. ByteIOContext pb1, *pb = &pb1;
  47. int img_size, ret;
  48. char fname[1024], *p;
  49. int size;
  50. URLContext *h;
  51. AVImageInfo info1, *info = &info1;
  52. img_size = url_fsize(f);
  53. /* XXX: hack hack */
  54. h = url_fileno(f);
  55. url_get_filename(h, fname, sizeof(fname));
  56. if (infer_size(&info->width, &info->height, img_size) < 0) {
  57. return AVERROR_IO;
  58. }
  59. info->pix_fmt = PIX_FMT_YUV420P;
  60. ret = alloc_cb(opaque, info);
  61. if (ret)
  62. return ret;
  63. size = info->width * info->height;
  64. p = strrchr(fname, '.');
  65. if (!p || p[1] != 'Y')
  66. return AVERROR_IO;
  67. get_buffer(f, info->pict.data[0], size);
  68. p[1] = 'U';
  69. if (url_fopen(pb, fname, URL_RDONLY) < 0)
  70. return AVERROR_IO;
  71. get_buffer(pb, info->pict.data[1], size / 4);
  72. url_fclose(pb);
  73. p[1] = 'V';
  74. if (url_fopen(pb, fname, URL_RDONLY) < 0)
  75. return AVERROR_IO;
  76. get_buffer(pb, info->pict.data[2], size / 4);
  77. url_fclose(pb);
  78. return 0;
  79. }
  80. static int yuv_write(ByteIOContext *pb2, AVImageInfo *info)
  81. {
  82. ByteIOContext pb1, *pb;
  83. char fname[1024], *p;
  84. int i, j, width, height;
  85. uint8_t *ptr;
  86. URLContext *h;
  87. static const char *ext = "YUV";
  88. /* XXX: hack hack */
  89. h = url_fileno(pb2);
  90. url_get_filename(h, fname, sizeof(fname));
  91. p = strrchr(fname, '.');
  92. if (!p || p[1] != 'Y')
  93. return AVERROR_IO;
  94. width = info->width;
  95. height = info->height;
  96. for(i=0;i<3;i++) {
  97. if (i == 1) {
  98. width >>= 1;
  99. height >>= 1;
  100. }
  101. if (i >= 1) {
  102. pb = &pb1;
  103. p[1] = ext[i];
  104. if (url_fopen(pb, fname, URL_WRONLY) < 0)
  105. return AVERROR_IO;
  106. } else {
  107. pb = pb2;
  108. }
  109. ptr = info->pict.data[i];
  110. for(j=0;j<height;j++) {
  111. put_buffer(pb, ptr, width);
  112. ptr += info->pict.linesize[i];
  113. }
  114. put_flush_packet(pb);
  115. if (i >= 1) {
  116. url_fclose(pb);
  117. }
  118. }
  119. return 0;
  120. }
  121. static int yuv_probe(AVProbeData *pd)
  122. {
  123. if (match_ext(pd->filename, "Y"))
  124. return AVPROBE_SCORE_MAX;
  125. else
  126. return 0;
  127. }
  128. AVImageFormat yuv_image_format = {
  129. "yuv",
  130. "Y",
  131. yuv_probe,
  132. yuv_read,
  133. (1 << PIX_FMT_YUV420P),
  134. yuv_write,
  135. };