123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175 |
- #include "avi_rgb_decoder.h"
- #include "../Winamp/wa_ipc.h"
- #include <bfc/error.h>
- #include <limits.h>
- #include <intsafe.h>
- int BMP_GetMallocSize(int32_t height, int32_t width, int32_t bits_per_pixel, size_t *out_frame_bytes)
- {
- if (height < 0 || width < 0)
- {
- return NErr_Error;
- }
- uint64_t frame_size = (uint64_t)height * (uint64_t)width;
- if (frame_size > SIZE_MAX)
- return NErr_IntegerOverflow;
- uint64_t frame_bytes = frame_size * (uint64_t)bits_per_pixel;
- if (frame_bytes > SIZE_MAX || frame_bytes < frame_size)
- return NErr_IntegerOverflow;
- *out_frame_bytes = (size_t)(frame_bytes / 8);
- return NErr_Success;
- }
- AVIRGB *AVIRGB::CreateDecoder(nsavi::video_format *stream_format)
- {
- AVIRGB *decoder = new AVIRGB(stream_format);
- if (!decoder)
- {
- return 0;
- }
- if (decoder->Initialize() != NErr_Success)
- {
- delete decoder;
- return 0;
- }
-
- return decoder;
- }
- AVIRGB::AVIRGB(nsavi::video_format *stream_format) : stream_format(stream_format)
- {
- palette_retrieved=false;
- video_frame=0;
- video_frame_size_bytes=0;
-
-
- if (stream_format->size_bytes == 1064)
- {
- memset(palette, 0, sizeof(palette));
- memcpy(palette, (uint8_t *)stream_format + 44, 1024);
- }
- o=false;
- }
- AVIRGB::~AVIRGB()
- {
- free(video_frame);
- }
- int AVIRGB::Initialize()
- {
- size_t frame_bytes;
- int ret = BMP_GetMallocSize(stream_format->height, stream_format->width, stream_format->bits_per_pixel, &frame_bytes);
- if (ret != NErr_Success)
- return ret;
- video_frame=malloc(frame_bytes);
- if (!video_frame)
- return NErr_OutOfMemory;
- video_frame_size_bytes = frame_bytes;
- return NErr_Success;
- }
- int AVIRGB::GetPalette(RGB32 **palette)
- {
- if (!palette_retrieved)
- {
- *palette = (RGB32 *)(this->palette);
- palette_retrieved=true;
- return AVI_SUCCESS;
- }
- else
- {
- return AVI_FAILURE;
- }
- }
- int AVIRGB::GetOutputProperties(int *x, int *y, int *color_format, double *aspect_ratio, int *flip)
- {
- if (stream_format)
- {
- *x = stream_format->width;
- *y = stream_format->height;
- *flip = 1;
- switch(stream_format->bits_per_pixel)
- {
- case 8:
- *color_format = '8BGR';
- break;
- // TODO:
- //case 16:
- //*color_format = '8GBR';
- case 24:
- *color_format = '42GR';
- break;
- case 32:
- *color_format = '23GR';
- break;
- default:
- return AVI_FAILURE;
- }
- return AVI_SUCCESS;
- }
-
- return AVI_FAILURE;
- }
- int AVIRGB::DecodeChunk(uint16_t type, const void *inputBuffer, size_t inputBufferBytes)
- {
- if (stream_format)
- {
- if (video_frame_size_bytes < inputBufferBytes)
- return AVI_FAILURE;
- memcpy(video_frame, inputBuffer, inputBufferBytes);
- //video_frame = inputBuffer; // heh
- o=true;
- return AVI_SUCCESS;
- }
- return AVI_FAILURE;
- }
- void AVIRGB::Flush()
- {
- }
- int AVIRGB::GetPicture(void **data, void **decoder_data)
- {
- if (o && video_frame)
- {
- *data =(void *) video_frame;
- *decoder_data=0;
- //video_frame=0;
- o=false;
- //video_outputted=true;
- return AVI_SUCCESS;
- }
-
- return AVI_FAILURE;
- }
- void AVIRGB::Close()
- {
- delete this;
- }
- #define CBCLASS AVIRGB
- START_DISPATCH;
- CB(GET_OUTPUT_PROPERTIES, GetOutputProperties)
- CB(DECODE_CHUNK, DecodeChunk)
- VCB(FLUSH, Flush)
- VCB(CLOSE, Close)
- CB(GET_PICTURE, GetPicture)
- CB(GET_PALETTE, GetPalette)
- END_DISPATCH;
- #undef CBCLASS
|