Initial community commit

This commit is contained in:
Jef
2024-09-24 14:54:57 +02:00
parent 537bcbc862
commit 20d28e80a5
16810 changed files with 4640254 additions and 2 deletions

113
Src/bmp/BMPLoader.cpp Normal file
View File

@ -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

23
Src/bmp/BMPLoader.h Normal file
View File

@ -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

88
Src/bmp/BMPWriter.cpp Normal file
View File

@ -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

21
Src/bmp/BMPWriter.h Normal file
View File

@ -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

39
Src/bmp/MyFactory.h Normal file
View File

@ -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

10
Src/bmp/api__bmp.h Normal file
View File

@ -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

54
Src/bmp/avi_decoder.cpp Normal file
View File

@ -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

18
Src/bmp/avi_decoder.h Normal file
View File

@ -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;
};

175
Src/bmp/avi_rgb_decoder.cpp Normal file
View File

@ -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

27
Src/bmp/avi_rgb_decoder.h Normal file
View File

@ -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;
};

225
Src/bmp/avi_rle_decoder.cpp Normal file
View File

@ -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

25
Src/bmp/avi_rle_decoder.h Normal file
View File

@ -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;
};

View File

@ -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

View File

@ -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;
};

117
Src/bmp/avi_yuv_decoder.cpp Normal file
View File

@ -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

24
Src/bmp/avi_yuv_decoder.h Normal file
View File

@ -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;
};

76
Src/bmp/bmp.rc Normal file
View File

@ -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

43
Src/bmp/bmp.sln Normal file
View File

@ -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

286
Src/bmp/bmp.vcxproj Normal file
View File

@ -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>

View File

@ -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>

14
Src/bmp/resource.h Normal file
View File

@ -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

141
Src/bmp/rle.cpp Normal file
View File

@ -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++;
}
}
}
}

12
Src/bmp/rle.h Normal file
View File

@ -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

39
Src/bmp/version.rc2 Normal file
View File

@ -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 <20> 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

68
Src/bmp/wa5_bmp.cpp Normal file
View File

@ -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

15
Src/bmp/wa5_bmp.h Normal file
View File

@ -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