diff options
Diffstat (limited to 'Src/bmp')
-rw-r--r-- | Src/bmp/BMPLoader.cpp | 113 | ||||
-rw-r--r-- | Src/bmp/BMPLoader.h | 23 | ||||
-rw-r--r-- | Src/bmp/BMPWriter.cpp | 88 | ||||
-rw-r--r-- | Src/bmp/BMPWriter.h | 21 | ||||
-rw-r--r-- | Src/bmp/MyFactory.h | 39 | ||||
-rw-r--r-- | Src/bmp/api__bmp.h | 10 | ||||
-rw-r--r-- | Src/bmp/avi_decoder.cpp | 54 | ||||
-rw-r--r-- | Src/bmp/avi_decoder.h | 18 | ||||
-rw-r--r-- | Src/bmp/avi_rgb_decoder.cpp | 175 | ||||
-rw-r--r-- | Src/bmp/avi_rgb_decoder.h | 27 | ||||
-rw-r--r-- | Src/bmp/avi_rle_decoder.cpp | 225 | ||||
-rw-r--r-- | Src/bmp/avi_rle_decoder.h | 25 | ||||
-rw-r--r-- | Src/bmp/avi_tscc_decoder.cpp | 257 | ||||
-rw-r--r-- | Src/bmp/avi_tscc_decoder.h | 27 | ||||
-rw-r--r-- | Src/bmp/avi_yuv_decoder.cpp | 117 | ||||
-rw-r--r-- | Src/bmp/avi_yuv_decoder.h | 24 | ||||
-rw-r--r-- | Src/bmp/bmp.rc | 76 | ||||
-rw-r--r-- | Src/bmp/bmp.sln | 43 | ||||
-rw-r--r-- | Src/bmp/bmp.vcxproj | 286 | ||||
-rw-r--r-- | Src/bmp/bmp.vcxproj.filters | 92 | ||||
-rw-r--r-- | Src/bmp/resource.h | 14 | ||||
-rw-r--r-- | Src/bmp/rle.cpp | 141 | ||||
-rw-r--r-- | Src/bmp/rle.h | 12 | ||||
-rw-r--r-- | Src/bmp/version.rc2 | 39 | ||||
-rw-r--r-- | Src/bmp/wa5_bmp.cpp | 68 | ||||
-rw-r--r-- | Src/bmp/wa5_bmp.h | 15 |
26 files changed, 2029 insertions, 0 deletions
diff --git a/Src/bmp/BMPLoader.cpp b/Src/bmp/BMPLoader.cpp new file mode 100644 index 00000000..38c85130 --- /dev/null +++ b/Src/bmp/BMPLoader.cpp @@ -0,0 +1,113 @@ +#include "BMPLoader.h" +#include "api__bmp.h" +#include <wchar.h> +#include <bfc/platform/strcmp.h> + +static bool StringEnds(const wchar_t *a, const wchar_t *b) +{ + size_t aLen = wcslen(a); + size_t bLen = wcslen(b); + if (aLen < bLen) return false; // too short + return !_wcsicmp(a + aLen- bLen, b); +} + +int BMPLoader::isMine(const wchar_t *filename) +{ + return (filename && StringEnds(filename, L".BMP")); +} + +const wchar_t *BMPLoader::mimeType() +{ + return L"image/bmp"; +} + +int BMPLoader::getHeaderSize() +{ + return 2; +} + +int BMPLoader::testData(const void *data, int datalen) +{ + if(datalen < 2) return 0; + return *((WORD*)data) == (WORD)'MB'; +} + +static void writeFile(const wchar_t *file, const void * data, int length) { + FILE *f = _wfopen(file,L"wb"); + if(!f) return; + fwrite(data,length,1,f); + fclose(f); +} + +ARGB32 *BMPLoader::loadImage(const void *data, int datalen, int *w, int *h, ifc_xmlreaderparams *params) +{ + int w0=0,h0=0; + if(!w) w = &w0; + if(!h) h = &h0; + + wchar_t file[MAX_PATH] = {0}; + GetTempPath(MAX_PATH, file); + GetTempFileName(file,L"wa5bmp",0,file); + writeFile(file,data,datalen); + + HBITMAP hbmp = (HBITMAP)LoadImage(0, file, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION); + + _wunlink(file); + if(!hbmp) return 0; + BITMAP bm; + HDC hMemDC, hMemDC2; + HBITMAP hsrcdib; + void *srcdib; + BITMAPINFO srcbmi = {0, }; + if(GetObject(hbmp, sizeof(BITMAP), &bm) == 0) { DeleteObject(hbmp); return 0; } + + *w = bm.bmWidth; + *h = abs(bm.bmHeight); + + ARGB32 *newbits=NULL; + srcbmi.bmiHeader.biSize = sizeof(srcbmi.bmiHeader); + srcbmi.bmiHeader.biWidth = *w; + srcbmi.bmiHeader.biHeight = -*h; + srcbmi.bmiHeader.biPlanes = 1; + srcbmi.bmiHeader.biBitCount = 32; + srcbmi.bmiHeader.biCompression = BI_RGB; + + hMemDC = CreateCompatibleDC(NULL); + hMemDC2 = CreateCompatibleDC(NULL); + hsrcdib = CreateDIBSection(hMemDC, &srcbmi, DIB_RGB_COLORS, &srcdib, NULL, 0); + if(hsrcdib) { + HBITMAP hprev = (HBITMAP) SelectObject(hMemDC, hsrcdib); + HBITMAP hprev2 = (HBITMAP) SelectObject(hMemDC2, hbmp); + BitBlt(hMemDC, 0, 0, *w, *h, hMemDC2, 0, 0, SRCCOPY); + newbits = (ARGB32*)WASABI_API_MEMMGR->sysMalloc((*w) * (*h) * sizeof(ARGB32)); + memcpy(newbits, srcdib, (*w)*(*h)*sizeof(ARGB32)); + { + // put the alpha channel to 255 + unsigned char *b = (unsigned char *)newbits; + int l = (*w) * (*h); + for (int i = 0;i < l;i++) + b[(i*4) + 3] = 0xff; + } + SelectObject(hMemDC, hprev); + SelectObject(hMemDC2, hprev2); + DeleteObject(hsrcdib); + } + DeleteDC(hMemDC2); + DeleteDC(hMemDC); + + DeleteObject(hbmp); + + return newbits; +} + +#define CBCLASS BMPLoader +START_DISPATCH; + CB(ISMINE, isMine); + CB(MIMETYPE, mimeType); + CB(TESTDATA, testData); + CB(GETHEADERSIZE, getHeaderSize); + CB(GETDIMENSIONS, getDimensions); + CB(LOADIMAGE, loadImage); + CB(LOADIMAGEDATA, loadImageData); +END_DISPATCH; +#undef CBCLASS
\ No newline at end of file diff --git a/Src/bmp/BMPLoader.h b/Src/bmp/BMPLoader.h new file mode 100644 index 00000000..60046eb2 --- /dev/null +++ b/Src/bmp/BMPLoader.h @@ -0,0 +1,23 @@ +#ifndef NULLSOFT_PNG_PNGLOADER_H +#define NULLSOFT_PNG_PNGLOADER_H + +#include <api/service/svcs/svc_imgload.h> + +class ifc_xmlreaderparams; + +class BMPLoader : public svc_imageLoader +{ +public: + // service + static const char *getServiceName() { return "BMP loader"; } + + virtual int isMine(const wchar_t *filename); + virtual const wchar_t *mimeType(); + virtual int getHeaderSize(); + virtual int testData(const void *data, int datalen); + virtual ARGB32 *loadImage(const void *data, int datalen, int *w, int *h, ifc_xmlreaderparams *params=NULL); + +protected: + RECVS_DISPATCH; +}; +#endif diff --git a/Src/bmp/BMPWriter.cpp b/Src/bmp/BMPWriter.cpp new file mode 100644 index 00000000..3a00fba6 --- /dev/null +++ b/Src/bmp/BMPWriter.cpp @@ -0,0 +1,88 @@ +#include "BMPWriter.h" +#include "api__bmp.h" +#include <wchar.h> +#include <bfc/platform/strcmp.h> + +// valid items include "quality" for jpeg files with value "0" to "100" +// return value is 1 if the config item is supported, 0 if it is not. +int BMPWriter::setConfig(const wchar_t * item, const wchar_t * value) { + return 0; // no config yet +} + +// valid items include "quality" for jpeg files with value "0" to "100", "lossless" returns "1" if it is "0" otherwise +// return value is 1 if the config item is supported, 0 if it is not. +int BMPWriter::getConfig(const wchar_t * item, wchar_t * value, int valuelen) { + if(!_wcsicmp(item,L"lossless")) lstrcpynW(value,L"1",valuelen); + else return 0; + return 1; +} + +// returns 1 if the bit depth is supported (eg 32 for ARGB32, 24 for RGB24) +// ARGB32 MUST be supported +int BMPWriter::bitDepthSupported(int depth) { + if(depth == 32 || depth == 24) return 1; + return 0; +} + +// returns the image in our format, free the returned buffer with api_memmgr::sysFree() +void * BMPWriter::convert(const void *pixels, int bitDepth, int w, int h, int *length) { + if(bitDepth != 32 && bitDepth != 24) return 0; + + int pixDataSize = (w * h * (bitDepth/8)); + int headersSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); + *length = pixDataSize + headersSize; + + BITMAPFILEHEADER fileHeader={0}; + fileHeader.bfType = 'MB'; + fileHeader.bfSize = *length; + fileHeader.bfOffBits = headersSize; + + BITMAPINFOHEADER infoHeader={0}; + infoHeader.biSize = sizeof(BITMAPINFOHEADER); + infoHeader.biWidth = w; + infoHeader.biHeight = h; + infoHeader.biPlanes = 1; + infoHeader.biBitCount = bitDepth; + infoHeader.biCompression = BI_RGB; + infoHeader.biSizeImage = pixDataSize; + infoHeader.biXPelsPerMeter = 2834; //72ppi + infoHeader.biYPelsPerMeter = 2834; //72ppi + infoHeader.biClrUsed = 0; + infoHeader.biClrImportant = 0; + + /* + The structure of bitmap files is like this: + fileheader + infoheader + palette (optional) + data + */ + BYTE * bmp = (BYTE *)WASABI_API_MEMMGR->sysMalloc(*length); + if(!bmp) return 0; + memcpy(bmp,&fileHeader,sizeof(BITMAPFILEHEADER)); + memcpy(bmp + sizeof(BITMAPFILEHEADER),&infoHeader,sizeof(BITMAPINFOHEADER)); + + //memcpy(bmp + headersSize,pixels,pixDataSize); + { + BYTE *pOut = bmp + headersSize; + BYTE *pIn = ((BYTE*)pixels) + w*h*(bitDepth/8); + int d = w*(bitDepth/8); + for(int i=0; i<h; i++) { + pIn-=d; + memcpy(pOut,pIn,d); + pOut+=d; + } + } + return bmp; +} + +#define CBCLASS BMPWriter +START_DISPATCH; + CB(GETIMAGETYPENAME, getImageTypeName); + CB(GETEXTENSIONS, getExtensions); + CB(SETCONFIG, setConfig); + CB(GETCONFIG, getConfig); + CB(BITDEPTHSUPPORTED, bitDepthSupported); + CB(CONVERT, convert); +END_DISPATCH; +#undef CBCLASS
\ No newline at end of file diff --git a/Src/bmp/BMPWriter.h b/Src/bmp/BMPWriter.h new file mode 100644 index 00000000..f034c022 --- /dev/null +++ b/Src/bmp/BMPWriter.h @@ -0,0 +1,21 @@ +#ifndef NULLSOFT_BMP_BMPWRITER_H +#define NULLSOFT_BMP_BMPWRITER_H + +#include <api/service/svcs/svc_imgwrite.h> + +class ifc_xmlreaderparams; + +class BMPWriter : public svc_imageWriter +{ +public: + static const char *getServiceName() { return "BMP loader"; } + const wchar_t * getImageTypeName() { return L"BMP"; } + const wchar_t * getExtensions() { return L"bmp;dib"; } + int setConfig(const wchar_t * item, const wchar_t * value); + int getConfig(const wchar_t * item, wchar_t * value, int valuelen); + int bitDepthSupported(int depth); + void * convert(const void *pixels, int bitDepth, int w, int h, int *length); +protected: + RECVS_DISPATCH; +}; +#endif diff --git a/Src/bmp/MyFactory.h b/Src/bmp/MyFactory.h new file mode 100644 index 00000000..5e9db1d6 --- /dev/null +++ b/Src/bmp/MyFactory.h @@ -0,0 +1,39 @@ +#ifndef _MYFACTORY_H_ +#define _MYFACTORY_H_ + +#include "api__bmp.h" +#include <api/service/waservicefactory.h> +#include <api/service/services.h> + +template <class T, class Base> +class MyFactory : public waServiceFactory +{ +public: + MyFactory(GUID guid) : guid(guid) {} + FOURCC GetServiceType() { return T::getServiceType(); } + const char *GetServiceName() { return T::getServiceName(); } + GUID GetGUID() { return guid; } + void *GetInterface(int global_lock) { return (Base*)new T; } + int SupportNonLockingInterface() {return 1;} + int ReleaseInterface(void *ifc) { delete static_cast<T *>(static_cast<Base *>(ifc)); return 1; } + const char *GetTestString() {return 0;} + int ServiceNotify(int msg, int param1, int param2) {return 1;} +private: + GUID guid; +protected: + #define CBCLASS MyFactory + START_DISPATCH_INLINE; + CB(WASERVICEFACTORY_GETSERVICETYPE, GetServiceType) + CB(WASERVICEFACTORY_GETSERVICENAME, GetServiceName) + CB(WASERVICEFACTORY_GETGUID, GetGUID) + CB(WASERVICEFACTORY_GETINTERFACE, GetInterface) + CB(WASERVICEFACTORY_SUPPORTNONLOCKINGGETINTERFACE, SupportNonLockingInterface) + CB(WASERVICEFACTORY_RELEASEINTERFACE, ReleaseInterface) + CB(WASERVICEFACTORY_GETTESTSTRING, GetTestString) + CB(WASERVICEFACTORY_SERVICENOTIFY, ServiceNotify) + END_DISPATCH; + #undef CBCLASS + //RECVS_DISPATCH; +}; + +#endif
\ No newline at end of file diff --git a/Src/bmp/api__bmp.h b/Src/bmp/api__bmp.h new file mode 100644 index 00000000..9a2d3dcb --- /dev/null +++ b/Src/bmp/api__bmp.h @@ -0,0 +1,10 @@ +#ifndef NULLSOFT_BMP_API_H +#define NULLSOFT_BMP_API_H + +#include <api/service/api_service.h> + +#include <api/memmgr/api_memmgr.h> +extern api_memmgr *memoryManager; +#define WASABI_API_MEMMGR memoryManager + +#endif // !NULLSOFT_BMP_API_H
\ No newline at end of file diff --git a/Src/bmp/avi_decoder.cpp b/Src/bmp/avi_decoder.cpp new file mode 100644 index 00000000..b133d8fd --- /dev/null +++ b/Src/bmp/avi_decoder.cpp @@ -0,0 +1,54 @@ +#include "avi_decoder.h" +#include "avi_tscc_decoder.h" +#include "avi_rle_decoder.h" +#include "avi_yuv_decoder.h" +#include "avi_rgb_decoder.h" + +int AVIDecoderCreator::CreateVideoDecoder(const nsavi::AVIH *avi_header, const nsavi::STRH *stream_header, const nsavi::STRF *stream_format, const nsavi::STRD *stream_data, ifc_avivideodecoder **decoder) +{ + nsavi::video_format *format = (nsavi::video_format *)stream_format; + if (format) + { + if (format->compression == 'ccst') // tscc + { + *decoder = AVITSCC::CreateDecoder(format); + if (*decoder) + return CREATEDECODER_SUCCESS; + else + return CREATEDECODER_FAILURE; + } + else if (format->compression == nsavi::video_format_rle8) // 8bit RLE + { + *decoder = AVIRLE::CreateDecoder(format); + if (*decoder) + return CREATEDECODER_SUCCESS; + else + return CREATEDECODER_FAILURE; + } + else if (format->compression == 'YVYU') // YUV + { + *decoder = AVIYUV::CreateDecoder(format); + if (*decoder) + return CREATEDECODER_SUCCESS; + else + return CREATEDECODER_FAILURE; + } + else if (format->compression == nsavi::video_format_rgb) + { + *decoder = AVIRGB::CreateDecoder(format); + if (*decoder) + return CREATEDECODER_SUCCESS; + else + return CREATEDECODER_FAILURE; + } + } + + return CREATEDECODER_NOT_MINE; +} + + +#define CBCLASS AVIDecoderCreator +START_DISPATCH; +CB(CREATE_VIDEO_DECODER, CreateVideoDecoder) +END_DISPATCH; +#undef CBCLASS diff --git a/Src/bmp/avi_decoder.h b/Src/bmp/avi_decoder.h new file mode 100644 index 00000000..818327fa --- /dev/null +++ b/Src/bmp/avi_decoder.h @@ -0,0 +1,18 @@ +#pragma once +#include "../Plugins/Input/in_avi/ifc_avivideodecoder.h" +#include "../Plugins/Input/in_avi/svc_avidecoder.h" + + +// {C5EC74D7-BE87-457c-BADA-0AA403F53822} +static const GUID avi_bitmap_guid = +{ 0xc5ec74d7, 0xbe87, 0x457c, { 0xba, 0xda, 0xa, 0xa4, 0x3, 0xf5, 0x38, 0x22 } }; + +class AVIDecoderCreator : public svc_avidecoder +{ +public: + static const char *getServiceName() { return "Bitmap AVI Decoder"; } + static GUID getServiceGuid() { return avi_bitmap_guid; } + int CreateVideoDecoder(const nsavi::AVIH *avi_header, const nsavi::STRH *stream_header, const nsavi::STRF *stream_format, const nsavi::STRD *stream_data, ifc_avivideodecoder **decoder); +protected: + RECVS_DISPATCH; +}; 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 diff --git a/Src/bmp/avi_rgb_decoder.h b/Src/bmp/avi_rgb_decoder.h new file mode 100644 index 00000000..08294462 --- /dev/null +++ b/Src/bmp/avi_rgb_decoder.h @@ -0,0 +1,27 @@ +#pragma once +#include "../Plugins/Input/in_avi/ifc_avivideodecoder.h" +#include "../nsavi/avi_header.h" + +class AVIRGB : public ifc_avivideodecoder +{ +public: + AVIRGB(nsavi::video_format *stream_format); + ~AVIRGB(); + int Initialize(); + static AVIRGB *CreateDecoder(nsavi::video_format *stream_format); + int GetOutputProperties(int *x, int *y, int *color_format, double *aspect_ratio, int *flip); + int DecodeChunk(uint16_t type, const void *inputBuffer, size_t inputBufferBytes); + void Flush(); + void Close(); + int GetPicture(void **data, void **decoder_data); + int GetPalette(RGB32 **palette); +private: + nsavi::video_format *stream_format; + void *video_frame; + size_t video_frame_size_bytes; + bool o; + RGBQUAD palette[256]; + bool palette_retrieved; +protected: + RECVS_DISPATCH; +};
\ No newline at end of file diff --git a/Src/bmp/avi_rle_decoder.cpp b/Src/bmp/avi_rle_decoder.cpp new file mode 100644 index 00000000..20d682f2 --- /dev/null +++ b/Src/bmp/avi_rle_decoder.cpp @@ -0,0 +1,225 @@ +#include "avi_rle_decoder.h" +#include "../Winamp/wa_ipc.h" +#include <limits.h> +#include "rle.h" +#include <intsafe.h> + +AVIRLE *AVIRLE::CreateDecoder(nsavi::video_format *stream_format) +{ + if (stream_format->bits_per_pixel == 4) + return 0; + + size_t bytes_per_pixel = stream_format->bits_per_pixel / 8U; + if (bytes_per_pixel > 4) + return 0; + + size_t image_size=0; + if (SizeTMult(stream_format->width, stream_format->height, &image_size) != S_OK || SizeTMult(image_size, bytes_per_pixel, &image_size) != S_OK) + return 0; + + void *video_frame = (uint8_t *)malloc(image_size); + if (!video_frame) + return 0; + + AVIRLE *decoder = new AVIRLE(video_frame, stream_format, image_size); + if (!decoder) + { + free(video_frame); + return 0; + } + + return decoder; +} + + +AVIRLE::AVIRLE(void *video_frame, nsavi::video_format *stream_format, size_t video_frame_size) : stream_format(stream_format), video_frame((uint8_t *)video_frame), video_frame_size(video_frame_size) +{ + memset(palette, 0, sizeof(palette)); + memcpy(palette, (uint8_t *)stream_format + 44, 1024); + video_outputted=false; + palette_retrieved=false; +} + +int AVIRLE::GetPalette(RGB32 **palette) +{ + if (!palette_retrieved) + { + *palette = (RGB32 *)(this->palette); + palette_retrieved=true; + return AVI_SUCCESS; + } + else + { + return AVI_FAILURE; + } + +} + +int AVIRLE::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 4: + *color_format = '8BGR'; + break; + case 8: + *color_format = '8BGR'; + break; + case 16: + *color_format = '555R'; + break; + case 24: + *color_format = '42GR'; + break; + case 32: + *color_format = '23GR'; + break; + default: + return AVI_FAILURE; + } + return AVI_SUCCESS; + } + + return AVI_FAILURE; +} + +static bool CheckOverflow(size_t total_size, int current_position, int read_size) +{ + if (read_size > (int)total_size) // check separate to avoid overflow + return true; + if (((int)total_size - read_size) < current_position) + return true; + return false; +} + +int AVIRLE::DecodeChunk(uint16_t type, const void *inputBuffer, size_t inputBufferBytes) +{ + if (stream_format) + { + uint32_t bytes_per_pixel = stream_format->bits_per_pixel / 8; + const uint8_t * const rle = (const uint8_t *)inputBuffer; + if (bytes_per_pixel == 2) + { + RLE16(rle, inputBufferBytes, (uint16_t *)video_frame, video_frame_size, stream_format->width); + } + else if (bytes_per_pixel == 1) + { + RLE8(rle, inputBufferBytes, (uint8_t *)video_frame, video_frame_size, stream_format->width); + } + else + { + + int input = 0; + int output = 0; + + int next_line = output + bytes_per_pixel*stream_format->width; + while (input < (int)inputBufferBytes && output < (int)video_frame_size) + { + if (CheckOverflow(inputBufferBytes, input, 2)) // we always read at least two bytes + break; + + uint8_t b0 = rle[input++]; + if (b0) + { + if (CheckOverflow(inputBufferBytes, input, bytes_per_pixel)) + break; + + if (CheckOverflow(video_frame_size, output, b0*bytes_per_pixel)) + break; + + uint8_t pixel[4]; + memcpy(pixel, &rle[input], bytes_per_pixel); + input += bytes_per_pixel; + while (b0--) + { + memcpy(&video_frame[output], &pixel, bytes_per_pixel); + output+=bytes_per_pixel; + } + } + else + { + uint8_t b1 = rle[input++]; + if (b1 == 0) + { + output = next_line; + next_line = output + bytes_per_pixel*stream_format->width; + } + else if (b1 == 1) + { + break; + } + else if (b1 == 2) + { + if (CheckOverflow(inputBufferBytes, input, 2)) + break; + + uint8_t p1 = rle[input++]; + uint8_t p2 = rle[input++]; + output += bytes_per_pixel*p1; + output += bytes_per_pixel*p2*stream_format->width; + next_line += bytes_per_pixel*p2*stream_format->width; + } + else + { + if (CheckOverflow(inputBufferBytes, input, b1*bytes_per_pixel)) + break; + + if (CheckOverflow(video_frame_size, output, b1*bytes_per_pixel)) + break; + + memcpy(&video_frame[output], &rle[input], b1*bytes_per_pixel); + input += b1*bytes_per_pixel; + output += b1*bytes_per_pixel; + if (bytes_per_pixel == 1 && (b1 & 1)) + input++; + } + } + } + + } + video_outputted=false; + return AVI_SUCCESS; + } + + return AVI_FAILURE; +} + +void AVIRLE::Flush() +{ + +} + +int AVIRLE::GetPicture(void **data, void **decoder_data) +{ + if (!video_outputted && video_frame) + { + *data = video_frame; + *decoder_data=0; + video_outputted=true; + return AVI_SUCCESS; + } + + return AVI_FAILURE; +} + +void AVIRLE::Close() +{ + free(video_frame); + delete this; +} + +#define CBCLASS AVIRLE +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 diff --git a/Src/bmp/avi_rle_decoder.h b/Src/bmp/avi_rle_decoder.h new file mode 100644 index 00000000..19bb5a86 --- /dev/null +++ b/Src/bmp/avi_rle_decoder.h @@ -0,0 +1,25 @@ +#pragma once +#include "../Plugins/Input/in_avi/ifc_avivideodecoder.h" +#include "../nsavi/avi_header.h" + +class AVIRLE : public ifc_avivideodecoder +{ +public: + AVIRLE(void *video_frame, nsavi::video_format *stream_format, size_t video_frame_size); + static AVIRLE *CreateDecoder(nsavi::video_format *stream_format); + int GetOutputProperties(int *x, int *y, int *color_format, double *aspect_ratio, int *flip); + int DecodeChunk(uint16_t type, const void *inputBuffer, size_t inputBufferBytes); + void Flush(); + void Close(); + int GetPicture(void **data, void **decoder_data); + int GetPalette(RGB32 **palette); +private: + nsavi::video_format *stream_format; + size_t video_frame_size; + uint8_t *video_frame; + bool video_outputted; + RGBQUAD palette[256]; + bool palette_retrieved; +protected: + RECVS_DISPATCH; +};
\ No newline at end of file diff --git a/Src/bmp/avi_tscc_decoder.cpp b/Src/bmp/avi_tscc_decoder.cpp new file mode 100644 index 00000000..5649cf2c --- /dev/null +++ b/Src/bmp/avi_tscc_decoder.cpp @@ -0,0 +1,257 @@ +#include "avi_tscc_decoder.h" +#include "avi_rle_decoder.h" +#include "avi_yuv_decoder.h" +#include "../Winamp/wa_ipc.h" +#include "rle.h" +#include <limits.h> +#include <intsafe.h> + +AVITSCC *AVITSCC::CreateDecoder(nsavi::video_format *stream_format) +{ + size_t bytes_per_pixel = stream_format->bits_per_pixel / 8U; + if (bytes_per_pixel > 4) + return 0; + + size_t image_size=0; + size_t pixel_size=0; + size_t data_len=0; + + /* set an upper bound on width so we don't overflow when we multiply uint8_t * 4 * width */ + if (stream_format->width > (1 << 20)) + return 0; + + if (SizeTMult(stream_format->width, stream_format->height, &pixel_size) != S_OK || SizeTMult(pixel_size, bytes_per_pixel, &image_size) != S_OK) + return 0; + + // calculate worst-case data length (3 * pixel_size / 255 + image_size) + if (SizeTMult(pixel_size, 3, &data_len) != S_OK) + return 0; + pixel_size /= 255; + if (SizeTAdd(pixel_size, data_len, &data_len) != S_OK) + return 0; + + void *video_frame = (uint8_t *)malloc(image_size); + if (!video_frame) + return 0; + + // upper bound for decompressed data size + + void *data = malloc(data_len); + if (!data) + { + free(video_frame); + return 0; + } + + AVITSCC *decoder = new AVITSCC(video_frame, image_size, data, data_len, stream_format); + if (!decoder) + { + free(video_frame); + free(data); + return 0; + } + + return decoder; +} + +AVITSCC::AVITSCC(void *video_frame, size_t video_frame_size, void *data, size_t data_len, nsavi::video_format *stream_format) : stream_format(stream_format), video_frame_size(video_frame_size), video_frame((uint8_t *)video_frame), data((uint8_t *)data), data_len(data_len) +{ + video_outputted=false; + + zlib_stream.next_in = Z_NULL; + zlib_stream.avail_in = Z_NULL; + zlib_stream.next_out = Z_NULL; + zlib_stream.avail_out = Z_NULL; + zlib_stream.zalloc = (alloc_func)0; + zlib_stream.zfree = (free_func)0; + zlib_stream.opaque = 0; + inflateInit(&zlib_stream); +} + +int AVITSCC::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; + case 16: + *color_format = '555R'; + break; + case 24: + *color_format = '42GR'; + break; + case 32: + *color_format = '23GR'; + break; + default: + return AVI_FAILURE; + } + return AVI_SUCCESS; + } + + return AVI_FAILURE; +} + + +static bool BoundsCheckX(uint8_t delta_x, size_t bytes_per_pixel, size_t video_frame_size, size_t output_pointer) +{ + if ((size_t)delta_x*bytes_per_pixel >= (video_frame_size - output_pointer)) + return false; + return true; +} + +static bool BoundsCheckY(uint8_t delta_y, size_t bytes_per_pixel, size_t width, size_t video_frame_size, size_t output_pointer) +{ + if ((size_t)delta_y*bytes_per_pixel*width >= (video_frame_size - output_pointer)) + return false; + return true; +} + +int AVITSCC::DecodeChunk(uint16_t type, const void *inputBuffer, size_t inputBufferBytes) +{ + if (stream_format) + { + if (inflateReset(&zlib_stream) != Z_OK) + return AVI_FAILURE; + + size_t bytes_per_pixel = stream_format->bits_per_pixel / 8U; + + zlib_stream.next_in = (Bytef *)inputBuffer; + zlib_stream.avail_in = (uInt)inputBufferBytes; + zlib_stream.next_out = data; + zlib_stream.avail_out = (uInt)data_len; + + int ret = inflate(&zlib_stream, Z_FINISH); + + if (ret == Z_OK || ret == Z_STREAM_END) + { + if (bytes_per_pixel == 2) + { + RLE16(data, data_len, (uint16_t *)video_frame, video_frame_size, stream_format->width); + } + else if (bytes_per_pixel == 1) + { + RLE8(data, data_len, (uint8_t *)video_frame, video_frame_size, stream_format->width); + } + else + { + const uint8_t * const rle = data; + int input = 0; + size_t output = 0; + int next_line = (int)output + (int)bytes_per_pixel*stream_format->width; + for (;;) + { + uint8_t b0 = rle[input++]; + if (b0) + { + uint8_t pixel[4] = {0}; + memcpy(pixel, &rle[input], bytes_per_pixel); + input += (int)bytes_per_pixel; + + if (!BoundsCheckX(b0, bytes_per_pixel, video_frame_size, output)) + return AVI_FAILURE; + + while (b0--) + { + memcpy(&video_frame[output], &pixel, bytes_per_pixel); + output+=bytes_per_pixel; + } + } + else + { + uint8_t b1 = rle[input++]; + if (b1 == 0) + { + if (next_line > (int)video_frame_size) + return AVI_FAILURE; + + output = next_line; + next_line = (int)output + (int)bytes_per_pixel*stream_format->width; + } + else if (b1 == 1) + { + break; + } + else if (b1 == 2) + { + uint8_t p1 = rle[input++]; + uint8_t p2 = rle[input++]; + if (!BoundsCheckX(p1, bytes_per_pixel, video_frame_size, output)) + return AVI_FAILURE; + + output += bytes_per_pixel*p1; + + if (!BoundsCheckY(p2, bytes_per_pixel, stream_format->width, video_frame_size, output)) + return AVI_FAILURE; + + output += bytes_per_pixel*p2*stream_format->width; + next_line += (int)bytes_per_pixel*p2*stream_format->width; + } + else + { + if (!BoundsCheckX(b1, bytes_per_pixel, video_frame_size, output)) + return AVI_FAILURE; + + memcpy(&video_frame[output], &rle[input], b1*bytes_per_pixel); + input += b1* (int)bytes_per_pixel; + output += b1*bytes_per_pixel; + if (bytes_per_pixel == 1 && (b1 & 1)) + input++; + } + } + } + } + } + else if (ret != Z_DATA_ERROR) + { + return AVI_FAILURE; + } + + video_outputted=false; + return AVI_SUCCESS; + } + + return AVI_FAILURE; +} + +void AVITSCC::Flush() +{ + +} + +int AVITSCC::GetPicture(void **data, void **decoder_data) +{ + if (!video_outputted && video_frame) + { + *data = video_frame; + *decoder_data=0; + video_outputted=true; + return AVI_SUCCESS; + } + + return AVI_FAILURE; +} + +void AVITSCC::Close() +{ + free(video_frame); + free(data); + inflateEnd(&zlib_stream); + delete this; +} + +#define CBCLASS AVITSCC +START_DISPATCH; +CB(GET_OUTPUT_PROPERTIES, GetOutputProperties) +CB(DECODE_CHUNK, DecodeChunk) +VCB(FLUSH, Flush) +VCB(CLOSE, Close) +CB(GET_PICTURE, GetPicture) +END_DISPATCH; +#undef CBCLASS diff --git a/Src/bmp/avi_tscc_decoder.h b/Src/bmp/avi_tscc_decoder.h new file mode 100644 index 00000000..7181340c --- /dev/null +++ b/Src/bmp/avi_tscc_decoder.h @@ -0,0 +1,27 @@ +#pragma once +#include "../Plugins/Input/in_avi/ifc_avivideodecoder.h" +#include "../nsavi/avi_header.h" +#include "zlib.h" + + +class AVITSCC : public ifc_avivideodecoder +{ +public: + AVITSCC(void *video_frame, size_t video_frame_size, void *data, size_t data_len, nsavi::video_format *stream_format); + static AVITSCC *CreateDecoder(nsavi::video_format *stream_format); + int GetOutputProperties(int *x, int *y, int *color_format, double *aspect_ratio, int *flip); + int DecodeChunk(uint16_t type, const void *inputBuffer, size_t inputBufferBytes); + void Flush(); + void Close(); + int GetPicture(void **data, void **decoder_data); +private: + nsavi::video_format *stream_format; + uint8_t *video_frame; + bool video_outputted; + z_stream zlib_stream; + uint8_t *data; + size_t data_len; + size_t video_frame_size; +protected: + RECVS_DISPATCH; +};
\ No newline at end of file diff --git a/Src/bmp/avi_yuv_decoder.cpp b/Src/bmp/avi_yuv_decoder.cpp new file mode 100644 index 00000000..441790d2 --- /dev/null +++ b/Src/bmp/avi_yuv_decoder.cpp @@ -0,0 +1,117 @@ +#include "avi_yuv_decoder.h" +#include "../Winamp/wa_ipc.h" +#include <limits.h> +#include <bfc/error.h> +#include <intsafe.h> + +int BMP_GetMallocSize(int32_t height, int32_t width, int32_t bits_per_pixel, size_t *out_frame_bytes); + +AVIYUV *AVIYUV::CreateDecoder(nsavi::video_format *stream_format) +{ + AVIYUV *decoder = new AVIYUV( stream_format); + if (!decoder) + { + return 0; + } + + if (decoder->Initialize() != NErr_Success) + { + delete decoder; + return 0; + } + return decoder; +} + + +AVIYUV::AVIYUV(nsavi::video_format *stream_format) : stream_format(stream_format) +{ + video_frame=0; + video_frame_size_bytes=0; + o=false; +} + +AVIYUV::~AVIYUV() +{ + free(video_frame); +} + + +int AVIYUV::Initialize() +{ + size_t frame_bytes; + int ret = BMP_GetMallocSize(stream_format->height, stream_format->width, 16, &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 AVIYUV::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; + *color_format = stream_format->compression; + return AVI_SUCCESS; + } + + return AVI_FAILURE; +} + +int AVIYUV::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 AVIYUV::Flush() +{ + +} + +int AVIYUV::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 AVIYUV::Close() +{ + delete this; +} + + +#define CBCLASS AVIYUV +START_DISPATCH; +CB(GET_OUTPUT_PROPERTIES, GetOutputProperties) +CB(DECODE_CHUNK, DecodeChunk) +VCB(FLUSH, Flush) +VCB(CLOSE, Close) +CB(GET_PICTURE, GetPicture) +END_DISPATCH; +#undef CBCLASS diff --git a/Src/bmp/avi_yuv_decoder.h b/Src/bmp/avi_yuv_decoder.h new file mode 100644 index 00000000..773c6582 --- /dev/null +++ b/Src/bmp/avi_yuv_decoder.h @@ -0,0 +1,24 @@ +#pragma once +#include "../Plugins/Input/in_avi/ifc_avivideodecoder.h" +#include "../nsavi/avi_header.h" + +class AVIYUV : public ifc_avivideodecoder +{ +public: + AVIYUV(nsavi::video_format *stream_format); + ~AVIYUV(); + static AVIYUV *CreateDecoder(nsavi::video_format *stream_format); + int Initialize(); + int GetOutputProperties(int *x, int *y, int *color_format, double *aspect_ratio, int *flip); + int DecodeChunk(uint16_t type, const void *inputBuffer, size_t inputBufferBytes); + void Flush(); + void Close(); + int GetPicture(void **data, void **decoder_data); +private: + nsavi::video_format *stream_format; + void *video_frame; + size_t video_frame_size_bytes; + bool o; +protected: + RECVS_DISPATCH; +};
\ No newline at end of file diff --git a/Src/bmp/bmp.rc b/Src/bmp/bmp.rc new file mode 100644 index 00000000..fcff7711 --- /dev/null +++ b/Src/bmp/bmp.rc @@ -0,0 +1,76 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////// +// English (U.K.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "#include ""version.rc2""\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + +#endif // English (U.K.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// +#include "version.rc2" + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/Src/bmp/bmp.sln b/Src/bmp/bmp.sln new file mode 100644 index 00000000..0d75cb1f --- /dev/null +++ b/Src/bmp/bmp.sln @@ -0,0 +1,43 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.29424.173 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bmp", "bmp.vcxproj", "{3E4C3F3B-5D94-4691-AF6D-13C1E6F54501}" + ProjectSection(ProjectDependencies) = postProject + {0F9730E4-45DA-4BD2-A50A-403A4BC9751A} = {0F9730E4-45DA-4BD2-A50A-403A4BC9751A} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib", "..\replicant\zlib\zlib.vcxproj", "{0F9730E4-45DA-4BD2-A50A-403A4BC9751A}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {3E4C3F3B-5D94-4691-AF6D-13C1E6F54501}.Debug|Win32.ActiveCfg = Debug|Win32 + {3E4C3F3B-5D94-4691-AF6D-13C1E6F54501}.Debug|Win32.Build.0 = Debug|Win32 + {3E4C3F3B-5D94-4691-AF6D-13C1E6F54501}.Debug|x64.ActiveCfg = Debug|x64 + {3E4C3F3B-5D94-4691-AF6D-13C1E6F54501}.Debug|x64.Build.0 = Debug|x64 + {3E4C3F3B-5D94-4691-AF6D-13C1E6F54501}.Release|Win32.ActiveCfg = Release|Win32 + {3E4C3F3B-5D94-4691-AF6D-13C1E6F54501}.Release|Win32.Build.0 = Release|Win32 + {3E4C3F3B-5D94-4691-AF6D-13C1E6F54501}.Release|x64.ActiveCfg = Release|x64 + {3E4C3F3B-5D94-4691-AF6D-13C1E6F54501}.Release|x64.Build.0 = Release|x64 + {0F9730E4-45DA-4BD2-A50A-403A4BC9751A}.Debug|Win32.ActiveCfg = Debug|Win32 + {0F9730E4-45DA-4BD2-A50A-403A4BC9751A}.Debug|Win32.Build.0 = Debug|Win32 + {0F9730E4-45DA-4BD2-A50A-403A4BC9751A}.Debug|x64.ActiveCfg = Debug|x64 + {0F9730E4-45DA-4BD2-A50A-403A4BC9751A}.Debug|x64.Build.0 = Debug|x64 + {0F9730E4-45DA-4BD2-A50A-403A4BC9751A}.Release|Win32.ActiveCfg = Release|Win32 + {0F9730E4-45DA-4BD2-A50A-403A4BC9751A}.Release|Win32.Build.0 = Release|Win32 + {0F9730E4-45DA-4BD2-A50A-403A4BC9751A}.Release|x64.ActiveCfg = Release|x64 + {0F9730E4-45DA-4BD2-A50A-403A4BC9751A}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {F13D0B81-5602-44F5-B7BC-1CB5054C7BE0} + EndGlobalSection +EndGlobal diff --git a/Src/bmp/bmp.vcxproj b/Src/bmp/bmp.vcxproj new file mode 100644 index 00000000..24b23dbf --- /dev/null +++ b/Src/bmp/bmp.vcxproj @@ -0,0 +1,286 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{3E4C3F3B-5D94-4691-AF6D-13C1E6F54501}</ProjectGuid> + <RootNamespace>bmp</RootNamespace> + <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <PlatformToolset>v142</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <PlatformToolset>v142</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <PlatformToolset>v142</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <PlatformToolset>v142</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir> + <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir> + <TargetExt>.w5s</TargetExt> + <IncludePath>$(IncludePath)</IncludePath> + <LibraryPath>$(LibraryPath)</LibraryPath> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir> + <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir> + <TargetExt>.w5s</TargetExt> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir> + <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir> + <TargetExt>.w5s</TargetExt> + <IncludePath>$(IncludePath)</IncludePath> + <LibraryPath>$(LibraryPath)</LibraryPath> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir> + <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir> + <TargetExt>.w5s</TargetExt> + </PropertyGroup> + <PropertyGroup Label="Vcpkg"> + <VcpkgEnableManifest>false</VcpkgEnableManifest> + </PropertyGroup> + <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <VcpkgInstalledDir> + </VcpkgInstalledDir> + <VcpkgUseStatic>false</VcpkgUseStatic> + <VcpkgConfiguration>Debug</VcpkgConfiguration> + <VcpkgTriplet>x86-windows-static-md</VcpkgTriplet> + </PropertyGroup> + <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <VcpkgInstalledDir> + </VcpkgInstalledDir> + <VcpkgUseStatic>false</VcpkgUseStatic> + <VcpkgTriplet>x86-windows-static-md</VcpkgTriplet> + </PropertyGroup> + <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <VcpkgInstalledDir> + </VcpkgInstalledDir> + <VcpkgUseStatic>false</VcpkgUseStatic> + <VcpkgTriplet>x86-windows-static-md</VcpkgTriplet> + <VcpkgConfiguration>Debug</VcpkgConfiguration> + </PropertyGroup> + <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <VcpkgInstalledDir> + </VcpkgInstalledDir> + <VcpkgUseStatic>false</VcpkgUseStatic> + <VcpkgTriplet>x86-windows-static-md</VcpkgTriplet> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <Optimization>Disabled</Optimization> + <AdditionalIncludeDirectories>../Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;BMP_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MinimalRebuild>false</MinimalRebuild> + <MultiProcessorCompilation>true</MultiProcessorCompilation> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName> + </ClCompile> + <Link> + <AdditionalDependencies>shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies> + <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> + <GenerateDebugInformation>true</GenerateDebugInformation> + <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile> + <SubSystem>Windows</SubSystem> + <RandomizedBaseAddress>false</RandomizedBaseAddress> + <ImportLibrary>$(ProjectDir)x86_Debug\$(ProjectName).lib</ImportLibrary> + <TargetMachine>MachineX86</TargetMachine> + <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers> + <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + </Link> + <PostBuildEvent> + <Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\ +xcopy /Y /D $(IntDir)$(TargetName).pdb ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\</Command> + <Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\'</Message> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <Optimization>Disabled</Optimization> + <AdditionalIncludeDirectories>../Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN64;_DEBUG;_WINDOWS;_USRDLL;BMP_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MinimalRebuild>false</MinimalRebuild> + <MultiProcessorCompilation>true</MultiProcessorCompilation> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName> + </ClCompile> + <Link> + <AdditionalDependencies>shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies> + <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> + <GenerateDebugInformation>true</GenerateDebugInformation> + <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile> + <SubSystem>Windows</SubSystem> + <RandomizedBaseAddress>false</RandomizedBaseAddress> + <ImportLibrary>$(ProjectDir)x64_Debug\$(ProjectName).lib</ImportLibrary> + <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers> + <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + </Link> + <PostBuildEvent> + <Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\ +xcopy /Y /D $(IntDir)$(TargetName).pdb ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\</Command> + <Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\'</Message> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <Optimization>MinSpace</Optimization> + <FavorSizeOrSpeed>Size</FavorSizeOrSpeed> + <AdditionalIncludeDirectories>../Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;BMP_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <StringPooling>true</StringPooling> + <MultiProcessorCompilation>true</MultiProcessorCompilation> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <BufferSecurityCheck>true</BufferSecurityCheck> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>None</DebugInformationFormat> + <DisableSpecificWarnings>4018;%(DisableSpecificWarnings)</DisableSpecificWarnings> + <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName> + </ClCompile> + <Link> + <AdditionalDependencies>shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies> + <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> + <GenerateDebugInformation>false</GenerateDebugInformation> + <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile> + <SubSystem>Windows</SubSystem> + <OptimizeReferences>true</OptimizeReferences> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <RandomizedBaseAddress>false</RandomizedBaseAddress> + <ImportLibrary>$(ProjectDir)x86_Release\$(ProjectName).lib</ImportLibrary> + <TargetMachine>MachineX86</TargetMachine> + <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers> + <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + </Link> + <PostBuildEvent> + <Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\</Command> + <Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\'</Message> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <Optimization>MinSpace</Optimization> + <FavorSizeOrSpeed>Size</FavorSizeOrSpeed> + <AdditionalIncludeDirectories>../Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN64;NDEBUG;_WINDOWS;_USRDLL;BMP_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <StringPooling>true</StringPooling> + <MultiProcessorCompilation>true</MultiProcessorCompilation> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <BufferSecurityCheck>true</BufferSecurityCheck> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>None</DebugInformationFormat> + <DisableSpecificWarnings>4018;%(DisableSpecificWarnings)</DisableSpecificWarnings> + <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName> + </ClCompile> + <Link> + <AdditionalDependencies>shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies> + <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> + <GenerateDebugInformation>false</GenerateDebugInformation> + <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile> + <SubSystem>Windows</SubSystem> + <OptimizeReferences>true</OptimizeReferences> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <RandomizedBaseAddress>false</RandomizedBaseAddress> + <ImportLibrary>$(ProjectDir)x64_Release\$(ProjectName).lib</ImportLibrary> + <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers> + <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + </Link> + <PostBuildEvent> + <Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\</Command> + <Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\'</Message> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemGroup> + <ProjectReference Include="..\Wasabi\Wasabi.vcxproj"> + <Project>{3e0bfa8a-b86a-42e9-a33f-ec294f823f7f}</Project> + </ProjectReference> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\Wasabi\api\service\svcs\svc_imgload.h" /> + <ClInclude Include="..\Wasabi\api\service\svcs\svc_imgwrite.h" /> + <ClInclude Include="api__bmp.h" /> + <ClInclude Include="avi_decoder.h" /> + <ClInclude Include="avi_rgb_decoder.h" /> + <ClInclude Include="avi_rle_decoder.h" /> + <ClInclude Include="avi_tscc_decoder.h" /> + <ClInclude Include="avi_yuv_decoder.h" /> + <ClInclude Include="BMPLoader.h" /> + <ClInclude Include="BMPWriter.h" /> + <ClInclude Include="MyFactory.h" /> + <ClInclude Include="resource.h" /> + <ClInclude Include="rle.h" /> + <ClInclude Include="wa5_bmp.h" /> + </ItemGroup> + <ItemGroup> + <ClCompile Include="avi_decoder.cpp" /> + <ClCompile Include="avi_rgb_decoder.cpp" /> + <ClCompile Include="avi_rle_decoder.cpp" /> + <ClCompile Include="avi_tscc_decoder.cpp" /> + <ClCompile Include="avi_yuv_decoder.cpp" /> + <ClCompile Include="BMPLoader.cpp" /> + <ClCompile Include="BMPWriter.cpp" /> + <ClCompile Include="rle.cpp" /> + <ClCompile Include="wa5_bmp.cpp" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="bmp.rc" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/Src/bmp/bmp.vcxproj.filters b/Src/bmp/bmp.vcxproj.filters new file mode 100644 index 00000000..8e9dc4dd --- /dev/null +++ b/Src/bmp/bmp.vcxproj.filters @@ -0,0 +1,92 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <ClCompile Include="avi_decoder.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="avi_rgb_decoder.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="avi_rle_decoder.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="avi_tscc_decoder.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="avi_yuv_decoder.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="BMPLoader.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="BMPWriter.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="rle.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="wa5_bmp.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="api__bmp.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="avi_decoder.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="avi_rgb_decoder.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="avi_rle_decoder.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="avi_tscc_decoder.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="avi_yuv_decoder.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="BMPLoader.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="BMPWriter.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="MyFactory.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="resource.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="rle.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\Wasabi\api\service\svcs\svc_imgload.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\Wasabi\api\service\svcs\svc_imgwrite.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="wa5_bmp.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> + <ItemGroup> + <Filter Include="Header Files"> + <UniqueIdentifier>{bbd61610-3e42-43fa-8623-41bd3ffadc24}</UniqueIdentifier> + </Filter> + <Filter Include="Ressource Files"> + <UniqueIdentifier>{c1764b77-d638-4b25-b887-4ca18f4fd333}</UniqueIdentifier> + </Filter> + <Filter Include="Source Files"> + <UniqueIdentifier>{94e2e597-651c-4cb2-9e7a-ff62872f3b30}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="bmp.rc"> + <Filter>Ressource Files</Filter> + </ResourceCompile> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/Src/bmp/resource.h b/Src/bmp/resource.h new file mode 100644 index 00000000..59c7ed62 --- /dev/null +++ b/Src/bmp/resource.h @@ -0,0 +1,14 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by bmp.rc + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 101 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/Src/bmp/rle.cpp b/Src/bmp/rle.cpp new file mode 100644 index 00000000..657ff411 --- /dev/null +++ b/Src/bmp/rle.cpp @@ -0,0 +1,141 @@ +#include "rle.h" +static bool CheckOverflow(size_t total_size, int current_position, int read_size) +{ + if (read_size > (int)total_size) // check separate to avoid overflow + return true; + if (((int)total_size - read_size) < current_position) + return true; + return false; +} + + +void RLE16(const uint8_t *rle, size_t rle_size_bytes, uint16_t *video_frame, size_t video_frame_size, int stride) +{ + int input = 0; + int output = 0; + video_frame_size >>= 1; // divide by 2 since we're indexing as uint16_t + int next_line = output + stride; + while (input < (int)rle_size_bytes && output < (int)video_frame_size) + { + if (CheckOverflow(rle_size_bytes, input, 2)) // we always read at least two bytes + break; + + uint8_t b0 = rle[input++]; + if (b0) + { + if (CheckOverflow(rle_size_bytes, input, 2)) + break; + + if (CheckOverflow(video_frame_size, output, b0)) + { + b0 = (uint8_t)(video_frame_size - output); + } + + uint16_t pixel = *(uint16_t *)(&rle[input]); + input += 2; + while (b0--) + { + memcpy(&video_frame[output], &pixel, 2); + output++; + } + } + else + { + uint8_t b1 = rle[input++]; + if (b1 == 0) + { + output = next_line; + next_line = output + stride; + } + else if (b1 == 1) + { + return; + } + else if (b1 == 2) + { + if (CheckOverflow(rle_size_bytes, input, 2)) + break; + + uint8_t p1 = rle[input++]; + uint8_t p2 = rle[input++]; + output += p1; + output += p2*stride; + next_line += p2*stride; + } + else + { + if (CheckOverflow(rle_size_bytes, input, b1*2)) + break; + + if (CheckOverflow(video_frame_size, output, b1)) + break; + for (uint8_t i=0;i!=b1;i++) + { + video_frame[output++] = *(uint16_t *)(&rle[input]); + input+=2; + } + } + } + } +} + +void RLE8(const uint8_t *rle, size_t rle_size_bytes, uint8_t *video_frame, size_t video_frame_size, int stride) +{ + int input = 0; + int output = 0; + int next_line = output + stride; + while (input < (int)rle_size_bytes && output < (int)video_frame_size) + { + if (CheckOverflow(rle_size_bytes, input, 2)) // we always read at least two bytes + break; + uint8_t b0 = rle[input++]; + if (b0) + { + if (CheckOverflow(video_frame_size, output, b0)) + { + b0 = (uint8_t)(video_frame_size - output); + } + + uint8_t pixel = rle[input++]; + memset(&video_frame[output], pixel, b0); + output+=b0; + } + else + { + uint8_t b1 = rle[input++]; + if (b1 == 0) + { + output = next_line; + next_line = output + stride; + } + else if (b1 == 1) + { + break; + } + else if (b1 == 2) + { + if (CheckOverflow(rle_size_bytes, input, 2)) + break; + + uint8_t p1 = rle[input++]; + uint8_t p2 = rle[input++]; + output += p1; + output += p2*stride; + next_line += p2*stride; + } + else + { + if (CheckOverflow(rle_size_bytes, input, b1)) + break; + + if (CheckOverflow(video_frame_size, output, b1)) + break; + memcpy(&video_frame[output], &rle[input], b1); + input += b1; + output += b1; + if (b1 & 1) + input++; + } + } + } +}
\ No newline at end of file diff --git a/Src/bmp/rle.h b/Src/bmp/rle.h new file mode 100644 index 00000000..e7c73381 --- /dev/null +++ b/Src/bmp/rle.h @@ -0,0 +1,12 @@ +#pragma once +#include <bfc/platform/types.h> +#ifdef __cplusplus +extern "C" { +#endif + +void RLE8(const uint8_t *rle, size_t rle_size_bytes, uint8_t *video_frame, size_t video_frame_size, int stride); +void RLE16(const uint8_t *rle, size_t rle_size_bytes, uint16_t *video_frame, size_t video_frame_size, int stride); + +#ifdef __cplusplus +} +#endif
\ No newline at end of file diff --git a/Src/bmp/version.rc2 b/Src/bmp/version.rc2 new file mode 100644 index 00000000..baa00806 --- /dev/null +++ b/Src/bmp/version.rc2 @@ -0,0 +1,39 @@ + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// +#include "../Winamp/buildType.h" +VS_VERSION_INFO VERSIONINFO + FILEVERSION WINAMP_PRODUCTVER + PRODUCTVERSION WINAMP_PRODUCTVER + FILEFLAGSMASK 0x17L +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", "Winamp SA" + VALUE "FileDescription", "Winamp 5.x System Component" + VALUE "FileVersion", STR_WINAMP_PRODUCTVER + VALUE "InternalName", "bmp.w5s" + VALUE "LegalCopyright", "Copyright © 2005-2019 Winamp SA" + VALUE "LegalTrademarks", "Nullsoft and Winamp are trademarks of Winamp SA" + VALUE "OriginalFilename", "bmp.w5s" + VALUE "ProductName", "Winamp BMP Image Service" + VALUE "ProductVersion", STR_WINAMP_PRODUCTVER + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END diff --git a/Src/bmp/wa5_bmp.cpp b/Src/bmp/wa5_bmp.cpp new file mode 100644 index 00000000..adb3417e --- /dev/null +++ b/Src/bmp/wa5_bmp.cpp @@ -0,0 +1,68 @@ +#include "api__bmp.h" +#include "wa5_bmp.h" +#include <bfc/platform/export.h> +#include "MyFactory.h" +#include "../nu/Singleton.h" +#include "BMPLoader.h" +#include "BMPWriter.h" +#include "avi_decoder.h" + +WA5_BMP wa5_bmp; + +// {BE7F448F-9107-489a-B3B0-7B1563C92BFE} +static const GUID bmpWriterGUID = +{ 0xbe7f448f, 0x9107, 0x489a, { 0xb3, 0xb0, 0x7b, 0x15, 0x63, 0xc9, 0x2b, 0xfe } }; + +// {D984CD4A-9D1E-4060-A624-5BFD0BF37050} +static const GUID bmpLoaderGUID = +{ 0xd984cd4a, 0x9d1e, 0x4060, { 0xa6, 0x24, 0x5b, 0xfd, 0xb, 0xf3, 0x70, 0x50 } }; + +MyFactory<BMPWriter, svc_imageWriter> bmpWriteFactory(bmpWriterGUID); +MyFactory<BMPLoader, svc_imageLoader> bmpLoadFactory(bmpLoaderGUID); + +api_service *WASABI_API_SVC = 0; +api_memmgr *WASABI_API_MEMMGR = 0; + +static AVIDecoderCreator aviCreator; +static SingletonServiceFactory<svc_avidecoder, AVIDecoderCreator> aviFactory; + +void WA5_BMP::RegisterServices(api_service *service) +{ + WASABI_API_SVC = service; + + // get memory manager + waServiceFactory *sf = WASABI_API_SVC->service_getServiceByGuid(memMgrApiServiceGuid); + if (sf) memoryManager = reinterpret_cast<api_memmgr *>(sf->getInterface()); + + WASABI_API_SVC->service_register(&bmpLoadFactory); + WASABI_API_SVC->service_register(&bmpWriteFactory); + aviFactory.Register(WASABI_API_SVC, &aviCreator); +} + +int WA5_BMP::RegisterServicesSafeModeOk() +{ + return 1; +} + +void WA5_BMP::DeregisterServices(api_service *service) +{ + service->service_deregister(&bmpWriteFactory); + service->service_deregister(&bmpLoadFactory); + aviFactory.Deregister(WASABI_API_SVC); + + waServiceFactory *sf = WASABI_API_SVC->service_getServiceByGuid(memMgrApiServiceGuid); + if (sf) sf->releaseInterface(memoryManager); +} + +extern "C" DLLEXPORT ifc_wa5component *GetWinamp5SystemComponent() +{ + return &wa5_bmp; +} + +#define CBCLASS WA5_BMP +START_DISPATCH; +VCB(API_WA5COMPONENT_REGISTERSERVICES, RegisterServices) +CB(15, RegisterServicesSafeModeOk) +VCB(API_WA5COMPONENT_DEREEGISTERSERVICES, DeregisterServices) +END_DISPATCH; +#undef CBCLASS
\ No newline at end of file diff --git a/Src/bmp/wa5_bmp.h b/Src/bmp/wa5_bmp.h new file mode 100644 index 00000000..75a0ee19 --- /dev/null +++ b/Src/bmp/wa5_bmp.h @@ -0,0 +1,15 @@ +#ifndef __WASABI_WA5_BMP_H +#define __WASABI_WA5_BMP_H + +#include "../Agave/Component/ifc_wa5component.h" + +class WA5_BMP : public ifc_wa5component +{ +public: + void RegisterServices(api_service *service); + int RegisterServicesSafeModeOk(); + void DeregisterServices(api_service *service); +protected: + RECVS_DISPATCH; +}; +#endif
\ No newline at end of file |