vfs: check userland buffers before reading them.
[haiku.git] / src / add-ons / media / plugins / ape_reader / MAClib / MACLib.cpp
blobbe80a31cb00c0f4cea30fff136ddea7d74232110
1 #include "All.h"
2 #include "MACLib.h"
4 //#include "APECompress.h"
5 //#include "APECompressCreate.h"
6 //#include "APECompressCore.h"
7 #include "APECompress.h"
8 #include "APEDecompress.h"
9 #include "APEInfo.h"
10 #include "APELink.h"
12 #undef BACKWARDS_COMPATIBILITY
14 #ifdef BACKWARDS_COMPATIBILITY
15 #include "Old/APEDecompressOld.h"
16 #endif
18 IAPEDecompress * CreateIAPEDecompressCore(CAPEInfo * pAPEInfo, int nStartBlock, int nFinishBlock, int * pErrorCode)
20 IAPEDecompress * pAPEDecompress = NULL;
21 if (pAPEInfo != NULL && *pErrorCode == ERROR_SUCCESS)
23 try
25 if (pAPEInfo->GetInfo(APE_INFO_FILE_VERSION) >= 3930)
26 pAPEDecompress = new CAPEDecompress(pErrorCode, pAPEInfo, nStartBlock, nFinishBlock);
27 #ifdef BACKWARDS_COMPATIBILITY
28 else
29 pAPEDecompress = new CAPEDecompressOld(pErrorCode, pAPEInfo, nStartBlock, nFinishBlock);
30 #endif
32 if (pAPEDecompress == NULL || *pErrorCode != ERROR_SUCCESS)
34 SAFE_DELETE(pAPEDecompress)
37 catch(...)
39 SAFE_DELETE(pAPEDecompress)
40 *pErrorCode = ERROR_UNDEFINED;
44 return pAPEDecompress;
47 IAPEDecompress * __stdcall CreateIAPEDecompress(const str_utf16 * pFilename, int * pErrorCode)
49 // error check the parameters
50 if ((pFilename == NULL) || (wcslen(pFilename) == 0))
52 if (pErrorCode) *pErrorCode = ERROR_BAD_PARAMETER;
53 return NULL;
56 // variables
57 int nErrorCode = ERROR_UNDEFINED;
58 CAPEInfo * pAPEInfo = NULL;
59 int nStartBlock = -1; int nFinishBlock = -1;
61 // get the extension
62 const str_utf16 * pExtension = &pFilename[wcslen(pFilename)];
63 while ((pExtension > pFilename) && (*pExtension != '.'))
64 pExtension--;
66 // take the appropriate action (based on the extension)
67 if (wcsicmp(pExtension, ".apl") == 0)
69 // "link" file (.apl linked large APE file)
70 CAPELink APELink(pFilename);
71 if (APELink.GetIsLinkFile())
73 pAPEInfo = new CAPEInfo(&nErrorCode, APELink.GetImageFilename(), new CAPETag(pFilename, TRUE));
74 nStartBlock = APELink.GetStartBlock(); nFinishBlock = APELink.GetFinishBlock();
77 else /*if ((wcsicmp(pExtension, L".mac") == 0) || (wcsicmp(pExtension, L".ape") == 0))*/ // SHINTA: To play regardless of the extension.
79 // plain .ape file
80 pAPEInfo = new CAPEInfo(&nErrorCode, pFilename);
83 // fail if we couldn't get the file information
84 if (pAPEInfo == NULL)
86 if (pErrorCode) *pErrorCode = ERROR_INVALID_INPUT_FILE;
87 return NULL;
90 // create and return
91 IAPEDecompress * pAPEDecompress = CreateIAPEDecompressCore(pAPEInfo, nStartBlock, nFinishBlock, &nErrorCode);
92 if (pErrorCode) *pErrorCode = nErrorCode;
93 return pAPEDecompress;
96 IAPEDecompress * __stdcall CreateIAPEDecompressEx(CIO * pIO, int * pErrorCode)
98 int nErrorCode = ERROR_UNDEFINED;
99 CAPEInfo * pAPEInfo = new CAPEInfo(&nErrorCode, pIO);
100 IAPEDecompress * pAPEDecompress = CreateIAPEDecompressCore(pAPEInfo, -1, -1, &nErrorCode);
101 if (pErrorCode) *pErrorCode = nErrorCode;
102 return pAPEDecompress;
106 IAPEDecompress * __stdcall CreateIAPEDecompressEx2(CAPEInfo * pAPEInfo, int nStartBlock, int nFinishBlock, int * pErrorCode)
108 int nErrorCode = ERROR_SUCCESS;
109 IAPEDecompress * pAPEDecompress = CreateIAPEDecompressCore(pAPEInfo, nStartBlock, nFinishBlock, &nErrorCode);
110 if (pErrorCode) *pErrorCode = nErrorCode;
111 return pAPEDecompress;
114 IAPECompress * __stdcall CreateIAPECompress(int * pErrorCode)
116 if (pErrorCode)
117 *pErrorCode = ERROR_SUCCESS;
119 return new CAPECompress();
122 int __stdcall FillWaveFormatEx(WAVEFORMATEX * pWaveFormatEx, int nSampleRate, int nBitsPerSample, int nChannels)
124 pWaveFormatEx->cbSize = 0;
125 pWaveFormatEx->nSamplesPerSec = nSampleRate;
126 pWaveFormatEx->wBitsPerSample = nBitsPerSample;
127 pWaveFormatEx->nChannels = nChannels;
128 pWaveFormatEx->wFormatTag = 1;
130 pWaveFormatEx->nBlockAlign = (pWaveFormatEx->wBitsPerSample / 8) * pWaveFormatEx->nChannels;
131 pWaveFormatEx->nAvgBytesPerSec = pWaveFormatEx->nBlockAlign * pWaveFormatEx->nSamplesPerSec;
133 return ERROR_SUCCESS;
136 int __stdcall FillWaveHeader(WAVE_HEADER * pWAVHeader, int nAudioBytes, WAVEFORMATEX * pWaveFormatEx, int nTerminatingBytes)
140 // RIFF header
141 memcpy(pWAVHeader->cRIFFHeader, "RIFF", 4);
142 pWAVHeader->nRIFFBytes = (nAudioBytes + 44) - 8 + nTerminatingBytes;
144 // format header
145 memcpy(pWAVHeader->cDataTypeID, "WAVE", 4);
146 memcpy(pWAVHeader->cFormatHeader, "fmt ", 4);
148 // the format chunk is the first 16 bytes of a waveformatex
149 pWAVHeader->nFormatBytes = 16;
150 memcpy(&pWAVHeader->nFormatTag, pWaveFormatEx, 16);
152 // the data header
153 memcpy(pWAVHeader->cDataHeader, "data", 4);
154 pWAVHeader->nDataBytes = nAudioBytes;
156 return ERROR_SUCCESS;
158 catch(...) { return ERROR_UNDEFINED; }