aboutsummaryrefslogtreecommitdiff
path: root/Src/bmp/avi_rgb_decoder.cpp
diff options
context:
space:
mode:
authorJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
committerJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
commit20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch)
tree12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/bmp/avi_rgb_decoder.cpp
parent537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff)
downloadwinamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz
Initial community commit
Diffstat (limited to 'Src/bmp/avi_rgb_decoder.cpp')
-rw-r--r--Src/bmp/avi_rgb_decoder.cpp175
1 files changed, 175 insertions, 0 deletions
diff --git a/Src/bmp/avi_rgb_decoder.cpp b/Src/bmp/avi_rgb_decoder.cpp
new file mode 100644
index 00000000..e93b9ff1
--- /dev/null
+++ b/Src/bmp/avi_rgb_decoder.cpp
@@ -0,0 +1,175 @@
+#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