avi_rgb_decoder.cpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. #include "avi_rgb_decoder.h"
  2. #include "../Winamp/wa_ipc.h"
  3. #include <bfc/error.h>
  4. #include <limits.h>
  5. #include <intsafe.h>
  6. int BMP_GetMallocSize(int32_t height, int32_t width, int32_t bits_per_pixel, size_t *out_frame_bytes)
  7. {
  8. if (height < 0 || width < 0)
  9. {
  10. return NErr_Error;
  11. }
  12. uint64_t frame_size = (uint64_t)height * (uint64_t)width;
  13. if (frame_size > SIZE_MAX)
  14. return NErr_IntegerOverflow;
  15. uint64_t frame_bytes = frame_size * (uint64_t)bits_per_pixel;
  16. if (frame_bytes > SIZE_MAX || frame_bytes < frame_size)
  17. return NErr_IntegerOverflow;
  18. *out_frame_bytes = (size_t)(frame_bytes / 8);
  19. return NErr_Success;
  20. }
  21. AVIRGB *AVIRGB::CreateDecoder(nsavi::video_format *stream_format)
  22. {
  23. AVIRGB *decoder = new AVIRGB(stream_format);
  24. if (!decoder)
  25. {
  26. return 0;
  27. }
  28. if (decoder->Initialize() != NErr_Success)
  29. {
  30. delete decoder;
  31. return 0;
  32. }
  33. return decoder;
  34. }
  35. AVIRGB::AVIRGB(nsavi::video_format *stream_format) : stream_format(stream_format)
  36. {
  37. palette_retrieved=false;
  38. video_frame=0;
  39. video_frame_size_bytes=0;
  40. if (stream_format->size_bytes == 1064)
  41. {
  42. memset(palette, 0, sizeof(palette));
  43. memcpy(palette, (uint8_t *)stream_format + 44, 1024);
  44. }
  45. o=false;
  46. }
  47. AVIRGB::~AVIRGB()
  48. {
  49. free(video_frame);
  50. }
  51. int AVIRGB::Initialize()
  52. {
  53. size_t frame_bytes;
  54. int ret = BMP_GetMallocSize(stream_format->height, stream_format->width, stream_format->bits_per_pixel, &frame_bytes);
  55. if (ret != NErr_Success)
  56. return ret;
  57. video_frame=malloc(frame_bytes);
  58. if (!video_frame)
  59. return NErr_OutOfMemory;
  60. video_frame_size_bytes = frame_bytes;
  61. return NErr_Success;
  62. }
  63. int AVIRGB::GetPalette(RGB32 **palette)
  64. {
  65. if (!palette_retrieved)
  66. {
  67. *palette = (RGB32 *)(this->palette);
  68. palette_retrieved=true;
  69. return AVI_SUCCESS;
  70. }
  71. else
  72. {
  73. return AVI_FAILURE;
  74. }
  75. }
  76. int AVIRGB::GetOutputProperties(int *x, int *y, int *color_format, double *aspect_ratio, int *flip)
  77. {
  78. if (stream_format)
  79. {
  80. *x = stream_format->width;
  81. *y = stream_format->height;
  82. *flip = 1;
  83. switch(stream_format->bits_per_pixel)
  84. {
  85. case 8:
  86. *color_format = '8BGR';
  87. break;
  88. // TODO:
  89. //case 16:
  90. //*color_format = '8GBR';
  91. case 24:
  92. *color_format = '42GR';
  93. break;
  94. case 32:
  95. *color_format = '23GR';
  96. break;
  97. default:
  98. return AVI_FAILURE;
  99. }
  100. return AVI_SUCCESS;
  101. }
  102. return AVI_FAILURE;
  103. }
  104. int AVIRGB::DecodeChunk(uint16_t type, const void *inputBuffer, size_t inputBufferBytes)
  105. {
  106. if (stream_format)
  107. {
  108. if (video_frame_size_bytes < inputBufferBytes)
  109. return AVI_FAILURE;
  110. memcpy(video_frame, inputBuffer, inputBufferBytes);
  111. //video_frame = inputBuffer; // heh
  112. o=true;
  113. return AVI_SUCCESS;
  114. }
  115. return AVI_FAILURE;
  116. }
  117. void AVIRGB::Flush()
  118. {
  119. }
  120. int AVIRGB::GetPicture(void **data, void **decoder_data)
  121. {
  122. if (o && video_frame)
  123. {
  124. *data =(void *) video_frame;
  125. *decoder_data=0;
  126. //video_frame=0;
  127. o=false;
  128. //video_outputted=true;
  129. return AVI_SUCCESS;
  130. }
  131. return AVI_FAILURE;
  132. }
  133. void AVIRGB::Close()
  134. {
  135. delete this;
  136. }
  137. #define CBCLASS AVIRGB
  138. START_DISPATCH;
  139. CB(GET_OUTPUT_PROPERTIES, GetOutputProperties)
  140. CB(DECODE_CHUNK, DecodeChunk)
  141. VCB(FLUSH, Flush)
  142. VCB(CLOSE, Close)
  143. CB(GET_PICTURE, GetPicture)
  144. CB(GET_PALETTE, GetPalette)
  145. END_DISPATCH;
  146. #undef CBCLASS