Reformat Utilities (Resharper)
This commit is contained in:
parent
68c88a6b7c
commit
c0aabf20a1
97 changed files with 25869 additions and 23038 deletions
|
@ -14,9 +14,11 @@ ArchiveReader::~ArchiveReader()
|
|||
|
||||
bool ArchiveReader::GetStream(string filename, std::stringstream& stream)
|
||||
{
|
||||
if(_initialized) {
|
||||
if (_initialized)
|
||||
{
|
||||
vector<uint8_t> fileData;
|
||||
if(ExtractFile(filename, fileData)) {
|
||||
if (ExtractFile(filename, fileData))
|
||||
{
|
||||
stream.write((char*)fileData.data(), fileData.size());
|
||||
return true;
|
||||
}
|
||||
|
@ -26,17 +28,22 @@ bool ArchiveReader::GetStream(string filename, std::stringstream &stream)
|
|||
|
||||
vector<string> ArchiveReader::GetFileList(std::initializer_list<string> extensions)
|
||||
{
|
||||
if(extensions.size() == 0) {
|
||||
if (extensions.size() == 0)
|
||||
{
|
||||
return InternalGetFileList();
|
||||
}
|
||||
|
||||
vector<string> filenames;
|
||||
for(string filename : InternalGetFileList()) {
|
||||
for (string filename : InternalGetFileList())
|
||||
{
|
||||
string lcFilename = filename;
|
||||
std::transform(lcFilename.begin(), lcFilename.end(), lcFilename.begin(), ::tolower);
|
||||
for(string ext : extensions) {
|
||||
if(lcFilename.size() >= ext.size()) {
|
||||
if(lcFilename.substr(lcFilename.length() - ext.size(), ext.size()).compare(ext) == 0) {
|
||||
for (string ext : extensions)
|
||||
{
|
||||
if (lcFilename.size() >= ext.size())
|
||||
{
|
||||
if (lcFilename.substr(lcFilename.length() - ext.size(), ext.size()).compare(ext) == 0)
|
||||
{
|
||||
filenames.push_back(filename);
|
||||
}
|
||||
}
|
||||
|
@ -73,7 +80,8 @@ bool ArchiveReader::LoadArchive(vector<uint8_t> &data)
|
|||
|
||||
bool ArchiveReader::LoadArchive(void* buffer, size_t size)
|
||||
{
|
||||
if(InternalLoadArchive(buffer, size)) {
|
||||
if (InternalLoadArchive(buffer, size))
|
||||
{
|
||||
_initialized = true;
|
||||
return true;
|
||||
}
|
||||
|
@ -83,7 +91,8 @@ bool ArchiveReader::LoadArchive(void* buffer, size_t size)
|
|||
bool ArchiveReader::LoadArchive(string filename)
|
||||
{
|
||||
ifstream in(filename, std::ios::binary | std::ios::in);
|
||||
if(in.good()) {
|
||||
if (in.good())
|
||||
{
|
||||
LoadArchive(in);
|
||||
in.close();
|
||||
}
|
||||
|
@ -96,13 +105,17 @@ shared_ptr<ArchiveReader> ArchiveReader::GetReader(std::istream &in)
|
|||
in.read((char*)header, 2);
|
||||
|
||||
shared_ptr<ArchiveReader> reader;
|
||||
if(memcmp(header, "PK", 2) == 0) {
|
||||
if (memcmp(header, "PK", 2) == 0)
|
||||
{
|
||||
reader.reset(new ZipReader());
|
||||
} else if(memcmp(header, "7z", 2) == 0) {
|
||||
}
|
||||
else if (memcmp(header, "7z", 2) == 0)
|
||||
{
|
||||
reader.reset(new SZReader());
|
||||
}
|
||||
|
||||
if(reader) {
|
||||
if (reader)
|
||||
{
|
||||
reader->LoadArchive(in);
|
||||
}
|
||||
return reader;
|
||||
|
@ -111,7 +124,8 @@ shared_ptr<ArchiveReader> ArchiveReader::GetReader(std::istream &in)
|
|||
shared_ptr<ArchiveReader> ArchiveReader::GetReader(string filepath)
|
||||
{
|
||||
ifstream in(filepath, std::ios::in | std::ios::binary);
|
||||
if(in) {
|
||||
if (in)
|
||||
{
|
||||
return GetReader(in);
|
||||
}
|
||||
return nullptr;
|
||||
|
|
|
@ -15,10 +15,13 @@ AutoResetEvent::~AutoResetEvent()
|
|||
void AutoResetEvent::Wait(int timeoutDelay)
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(_mutex);
|
||||
if(timeoutDelay == 0) {
|
||||
if (timeoutDelay == 0)
|
||||
{
|
||||
//Wait until signaled
|
||||
_signal.wait(lock, [this] { return _signaled; });
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
//Wait until signaled or timeout
|
||||
auto timeoutTime = std::chrono::system_clock::now() + std::chrono::duration<int, std::milli>(timeoutDelay);
|
||||
_signal.wait_until(lock, timeoutTime, [this] { return _signaled; });
|
||||
|
|
|
@ -14,19 +14,23 @@ AviRecorder::AviRecorder(VideoCodec codec, uint32_t compressionLevel)
|
|||
|
||||
AviRecorder::~AviRecorder()
|
||||
{
|
||||
if(_recording) {
|
||||
if (_recording)
|
||||
{
|
||||
StopRecording();
|
||||
}
|
||||
|
||||
if(_frameBuffer) {
|
||||
if (_frameBuffer)
|
||||
{
|
||||
delete[] _frameBuffer;
|
||||
_frameBuffer = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool AviRecorder::StartRecording(string filename, uint32_t width, uint32_t height, uint32_t bpp, uint32_t audioSampleRate, double fps)
|
||||
bool AviRecorder::StartRecording(string filename, uint32_t width, uint32_t height, uint32_t bpp,
|
||||
uint32_t audioSampleRate, double fps)
|
||||
{
|
||||
if (!_recording)
|
||||
{
|
||||
if(!_recording) {
|
||||
_outputFile = filename;
|
||||
_sampleRate = audioSampleRate;
|
||||
_width = width;
|
||||
|
@ -36,15 +40,20 @@ bool AviRecorder::StartRecording(string filename, uint32_t width, uint32_t heigh
|
|||
_frameBuffer = new uint8_t[_frameBufferLength];
|
||||
|
||||
_aviWriter.reset(new AviWriter());
|
||||
if(!_aviWriter->StartWrite(filename, _codec, width, height, bpp, (uint32_t)(_fps * 1000000), audioSampleRate, _compressionLevel)) {
|
||||
if (!_aviWriter->StartWrite(filename, _codec, width, height, bpp, (uint32_t)(_fps * 1000000), audioSampleRate,
|
||||
_compressionLevel))
|
||||
{
|
||||
_aviWriter.reset();
|
||||
return false;
|
||||
}
|
||||
|
||||
_aviWriterThread = std::thread([=]() {
|
||||
while(!_stopFlag) {
|
||||
_aviWriterThread = std::thread([=]()
|
||||
{
|
||||
while (!_stopFlag)
|
||||
{
|
||||
_waitFrame.Wait();
|
||||
if(_stopFlag) {
|
||||
if (_stopFlag)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -60,7 +69,8 @@ bool AviRecorder::StartRecording(string filename, uint32_t width, uint32_t heigh
|
|||
|
||||
void AviRecorder::StopRecording()
|
||||
{
|
||||
if(_recording) {
|
||||
if (_recording)
|
||||
{
|
||||
_recording = false;
|
||||
|
||||
_stopFlag = true;
|
||||
|
@ -74,10 +84,14 @@ void AviRecorder::StopRecording()
|
|||
|
||||
void AviRecorder::AddFrame(void* frameBuffer, uint32_t width, uint32_t height, double fps)
|
||||
{
|
||||
if(_recording) {
|
||||
if(_width != width || _height != height || _fps != fps) {
|
||||
if (_recording)
|
||||
{
|
||||
if (_width != width || _height != height || _fps != fps)
|
||||
{
|
||||
StopRecording();
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
auto lock = _lock.AcquireSafe();
|
||||
memcpy(_frameBuffer, frameBuffer, _frameBufferLength);
|
||||
_waitFrame.Signal();
|
||||
|
@ -87,11 +101,15 @@ void AviRecorder::AddFrame(void* frameBuffer, uint32_t width, uint32_t height, d
|
|||
|
||||
void AviRecorder::AddSound(int16_t* soundBuffer, uint32_t sampleCount, uint32_t sampleRate)
|
||||
{
|
||||
if(_recording) {
|
||||
if(_sampleRate != sampleRate) {
|
||||
if (_recording)
|
||||
{
|
||||
if (_sampleRate != sampleRate)
|
||||
{
|
||||
auto lock = _lock.AcquireSafe();
|
||||
StopRecording();
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
_aviWriter->AddSound(soundBuffer, sampleCount);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,7 +36,8 @@ public:
|
|||
AviRecorder(VideoCodec codec, uint32_t compressionLevel);
|
||||
virtual ~AviRecorder();
|
||||
|
||||
bool StartRecording(string filename, uint32_t width, uint32_t height, uint32_t bpp, uint32_t audioSampleRate, double fps) override;
|
||||
bool StartRecording(string filename, uint32_t width, uint32_t height, uint32_t bpp, uint32_t audioSampleRate,
|
||||
double fps) override;
|
||||
void StopRecording() override;
|
||||
|
||||
void AddFrame(void* frameBuffer, uint32_t width, uint32_t height, double fps) override;
|
||||
|
|
|
@ -64,22 +64,29 @@ void AviWriter::host_writed(uint8_t* buffer, uint32_t value)
|
|||
buffer[3] = value >> 24;
|
||||
}
|
||||
|
||||
bool AviWriter::StartWrite(string filename, VideoCodec codec, uint32_t width, uint32_t height, uint32_t bpp, uint32_t fps, uint32_t audioSampleRate, uint32_t compressionLevel)
|
||||
bool AviWriter::StartWrite(string filename, VideoCodec codec, uint32_t width, uint32_t height, uint32_t bpp,
|
||||
uint32_t fps, uint32_t audioSampleRate, uint32_t compressionLevel)
|
||||
{
|
||||
_codecType = codec;
|
||||
_file.open(filename, std::ios::out | std::ios::binary);
|
||||
if(!_file) {
|
||||
if (!_file)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
switch(_codecType) {
|
||||
switch (_codecType)
|
||||
{
|
||||
default:
|
||||
case VideoCodec::None: _codec.reset(new RawCodec()); break;
|
||||
case VideoCodec::ZMBV: _codec.reset(new ZmbvCodec()); break;
|
||||
case VideoCodec::CSCD: _codec.reset(new CamstudioCodec()); break;
|
||||
case VideoCodec::None: _codec.reset(new RawCodec());
|
||||
break;
|
||||
case VideoCodec::ZMBV: _codec.reset(new ZmbvCodec());
|
||||
break;
|
||||
case VideoCodec::CSCD: _codec.reset(new CamstudioCodec());
|
||||
break;
|
||||
}
|
||||
|
||||
if(!_codec->SetupCompress(width, height, compressionLevel)) {
|
||||
if (!_codec->SetupCompress(width, height, compressionLevel))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -95,7 +102,8 @@ bool AviWriter::StartWrite(string filename, VideoCodec codec, uint32_t width, ui
|
|||
|
||||
_audiorate = audioSampleRate;
|
||||
|
||||
for(int i = 0; i < AviWriter::AviHeaderSize; i++) {
|
||||
for (int i = 0; i < AviWriter::AviHeaderSize; i++)
|
||||
{
|
||||
_file.put(0);
|
||||
}
|
||||
_frames = 0;
|
||||
|
@ -235,7 +243,8 @@ void AviWriter::EndWrite()
|
|||
|
||||
void AviWriter::AddFrame(uint8_t* frameData)
|
||||
{
|
||||
if(!_file) {
|
||||
if (!_file)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -243,17 +252,20 @@ void AviWriter::AddFrame(uint8_t *frameData)
|
|||
|
||||
uint8_t* compressedData = nullptr;
|
||||
int written = _codec->CompressFrame(isKeyFrame, frameData, &compressedData);
|
||||
if(written < 0) {
|
||||
if (written < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(_codecType == VideoCodec::None) {
|
||||
if (_codecType == VideoCodec::None)
|
||||
{
|
||||
isKeyFrame = true;
|
||||
}
|
||||
WriteAviChunk(_codecType == VideoCodec::None ? "00db" : "00dc", written, compressedData, isKeyFrame ? 0x10 : 0);
|
||||
_frames++;
|
||||
|
||||
if(_audioPos) {
|
||||
if (_audioPos)
|
||||
{
|
||||
auto lock = _audioLock.AcquireSafe();
|
||||
WriteAviChunk("01wb", _audioPos, _audiobuf, 0);
|
||||
_audiowritten += _audioPos;
|
||||
|
@ -263,7 +275,8 @@ void AviWriter::AddFrame(uint8_t *frameData)
|
|||
|
||||
void AviWriter::AddSound(int16_t* data, uint32_t sampleCount)
|
||||
{
|
||||
if(!_file) {
|
||||
if (!_file)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -52,6 +52,7 @@ public:
|
|||
void AddFrame(uint8_t* frameData);
|
||||
void AddSound(int16_t* data, uint32_t sampleCount);
|
||||
|
||||
bool StartWrite(string filename, VideoCodec codec, uint32_t width, uint32_t height, uint32_t bpp, uint32_t fps, uint32_t audioSampleRate, uint32_t compressionLevel);
|
||||
bool StartWrite(string filename, VideoCodec codec, uint32_t width, uint32_t height, uint32_t bpp, uint32_t fps,
|
||||
uint32_t audioSampleRate, uint32_t compressionLevel);
|
||||
void EndWrite();
|
||||
};
|
|
@ -9,15 +9,18 @@ public:
|
|||
std::string out;
|
||||
|
||||
int val = 0, valb = -6;
|
||||
for(uint8_t c : data) {
|
||||
for (uint8_t c : data)
|
||||
{
|
||||
val = (val << 8) + c;
|
||||
valb += 8;
|
||||
while(valb >= 0) {
|
||||
while (valb >= 0)
|
||||
{
|
||||
out.push_back("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[(val >> valb) & 0x3F]);
|
||||
valb -= 6;
|
||||
}
|
||||
}
|
||||
if(valb>-6) out.push_back("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[((val << 8) >> (valb + 8)) & 0x3F]);
|
||||
if (valb > -6) out.push_back(
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[((val << 8) >> (valb + 8)) & 0x3F]);
|
||||
while (out.size() % 4) out.push_back('=');
|
||||
return out;
|
||||
}
|
||||
|
@ -30,11 +33,13 @@ public:
|
|||
for (int i = 0; i < 64; i++) T["ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[i]] = i;
|
||||
|
||||
int val = 0, valb = -8;
|
||||
for(uint8_t c : in) {
|
||||
for (uint8_t c : in)
|
||||
{
|
||||
if (T[c] == -1) break;
|
||||
val = (val << 6) + T[c];
|
||||
valb += 6;
|
||||
if(valb >= 0) {
|
||||
if (valb >= 0)
|
||||
{
|
||||
out.push_back(val >> valb);
|
||||
valb -= 8;
|
||||
}
|
||||
|
|
|
@ -8,5 +8,7 @@ public:
|
|||
virtual int CompressFrame(bool isKeyFrame, uint8_t* frameData, uint8_t** compressedData) = 0;
|
||||
virtual const char* GetFourCC() = 0;
|
||||
|
||||
virtual ~BaseCodec() { }
|
||||
virtual ~BaseCodec()
|
||||
{
|
||||
}
|
||||
};
|
|
@ -9,14 +9,17 @@ int64_t BpsPatcher::ReadBase128Number(std::istream &file)
|
|||
int64_t result = 0;
|
||||
int shift = 0;
|
||||
uint8_t buffer;
|
||||
while(true) {
|
||||
while (true)
|
||||
{
|
||||
file.read((char*)&buffer, 1);
|
||||
if(file.eof()) {
|
||||
if (file.eof())
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
result += (buffer & 0x7F) << shift;
|
||||
shift += 7;
|
||||
if(buffer & 0x80) {
|
||||
if (buffer & 0x80)
|
||||
{
|
||||
break;
|
||||
}
|
||||
result += (int64_t)1 << shift;
|
||||
|
@ -28,7 +31,8 @@ int64_t BpsPatcher::ReadBase128Number(std::istream &file)
|
|||
bool BpsPatcher::PatchBuffer(string bpsFilepath, vector<uint8_t>& input, vector<uint8_t>& output)
|
||||
{
|
||||
ifstream bpsFile(bpsFilepath, std::ios::in | std::ios::binary);
|
||||
if(bpsFile) {
|
||||
if (bpsFile)
|
||||
{
|
||||
return PatchBuffer(bpsFile, input, output);
|
||||
}
|
||||
return false;
|
||||
|
@ -42,14 +46,16 @@ bool BpsPatcher::PatchBuffer(std::istream &bpsFile, vector<uint8_t> &input, vect
|
|||
|
||||
char header[4];
|
||||
bpsFile.read((char*)&header, 4);
|
||||
if(memcmp((char*)&header, "BPS1", 4) != 0) {
|
||||
if (memcmp((char*)&header, "BPS1", 4) != 0)
|
||||
{
|
||||
//Invalid BPS file
|
||||
return false;
|
||||
}
|
||||
|
||||
int64_t inputFileSize = ReadBase128Number(bpsFile);
|
||||
int64_t outputFileSize = ReadBase128Number(bpsFile);
|
||||
if(inputFileSize == -1 || outputFileSize == -1) {
|
||||
if (inputFileSize == -1 || outputFileSize == -1)
|
||||
{
|
||||
//Invalid file
|
||||
return false;
|
||||
}
|
||||
|
@ -62,19 +68,23 @@ bool BpsPatcher::PatchBuffer(std::istream &bpsFile, vector<uint8_t> &input, vect
|
|||
uint32_t outputOffset = 0;
|
||||
uint32_t inputRelativeOffset = 0;
|
||||
uint32_t outputRelativeOffset = 0;
|
||||
while((size_t)bpsFile.tellg() < fileSize - 12) {
|
||||
while ((size_t)bpsFile.tellg() < fileSize - 12)
|
||||
{
|
||||
int64_t data = ReadBase128Number(bpsFile);
|
||||
if(data == -1) {
|
||||
if (data == -1)
|
||||
{
|
||||
//Invalid file
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t command = data & 0x03;
|
||||
uint64_t length = (data >> 2) + 1;
|
||||
switch(command) {
|
||||
switch (command)
|
||||
{
|
||||
case 0:
|
||||
//SourceRead
|
||||
while(length--) {
|
||||
while (length--)
|
||||
{
|
||||
output[outputOffset] = input[outputOffset];
|
||||
outputOffset++;
|
||||
}
|
||||
|
@ -82,7 +92,8 @@ bool BpsPatcher::PatchBuffer(std::istream &bpsFile, vector<uint8_t> &input, vect
|
|||
|
||||
case 1:
|
||||
//TargetRead
|
||||
while(length--) {
|
||||
while (length--)
|
||||
{
|
||||
uint8_t value = 0;
|
||||
bpsFile.read((char*)&value, 1);
|
||||
|
||||
|
@ -90,21 +101,25 @@ bool BpsPatcher::PatchBuffer(std::istream &bpsFile, vector<uint8_t> &input, vect
|
|||
}
|
||||
break;
|
||||
|
||||
case 2: {
|
||||
case 2:
|
||||
{
|
||||
//SourceCopy
|
||||
int32_t data = (int32_t)ReadBase128Number(bpsFile);
|
||||
inputRelativeOffset += (data & 1 ? -1 : +1) * (data >> 1);
|
||||
while(length--) {
|
||||
while (length--)
|
||||
{
|
||||
output[outputOffset++] = input[inputRelativeOffset++];
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 3: {
|
||||
case 3:
|
||||
{
|
||||
//TargetCopy
|
||||
int32_t data = (int32_t)ReadBase128Number(bpsFile);
|
||||
outputRelativeOffset += (data & 1 ? -1 : +1) * (data >> 1);
|
||||
while(length--) {
|
||||
while (length--)
|
||||
{
|
||||
output[outputOffset++] = output[outputRelativeOffset++];
|
||||
}
|
||||
break;
|
||||
|
@ -116,12 +131,15 @@ bool BpsPatcher::PatchBuffer(std::istream &bpsFile, vector<uint8_t> &input, vect
|
|||
uint8_t outputChecksum[4];
|
||||
bpsFile.read((char*)inputChecksum, 4);
|
||||
bpsFile.read((char*)outputChecksum, 4);
|
||||
uint32_t patchInputCrc = inputChecksum[0] | (inputChecksum[1] << 8) | (inputChecksum[2] << 16) | (inputChecksum[3] << 24);
|
||||
uint32_t patchOutputCrc = outputChecksum[0] | (outputChecksum[1] << 8) | (outputChecksum[2] << 16) | (outputChecksum[3] << 24);
|
||||
uint32_t patchInputCrc = inputChecksum[0] | (inputChecksum[1] << 8) | (inputChecksum[2] << 16) | (inputChecksum[3] <<
|
||||
24);
|
||||
uint32_t patchOutputCrc = outputChecksum[0] | (outputChecksum[1] << 8) | (outputChecksum[2] << 16) | (outputChecksum[
|
||||
3] << 24);
|
||||
uint32_t inputCrc = CRC32::GetCRC(input.data(), input.size());
|
||||
uint32_t outputCrc = CRC32::GetCRC(output.data(), output.size());
|
||||
|
||||
if(patchInputCrc != inputCrc || patchOutputCrc != outputCrc) {
|
||||
if (patchInputCrc != inputCrc || patchOutputCrc != outputCrc)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
|
|
@ -46,7 +46,8 @@ uint32_t CRC32::GetCRC(string filename)
|
|||
|
||||
ifstream file(filename, std::ios::in | std::ios::binary);
|
||||
|
||||
if(file) {
|
||||
if (file)
|
||||
{
|
||||
file.seekg(0, std::ios::end);
|
||||
std::streamoff fileSize = file.tellg();
|
||||
file.seekg(0, std::ios::beg);
|
||||
|
@ -71,8 +72,10 @@ uint32_t CRC32::crc32_16bytes(const void* data, size_t length, uint32_t previous
|
|||
const size_t Unroll = 4;
|
||||
const size_t BytesAtOnce = 16 * Unroll;
|
||||
|
||||
while(length >= BytesAtOnce) {
|
||||
for(size_t unrolling = 0; unrolling < Unroll; unrolling++) {
|
||||
while (length >= BytesAtOnce)
|
||||
{
|
||||
for (size_t unrolling = 0; unrolling < Unroll; unrolling++)
|
||||
{
|
||||
#if __BYTE_ORDER == __BIG_ENDIAN
|
||||
uint32_t one = *current++ ^ swap(crc);
|
||||
uint32_t two = *current++;
|
||||
|
@ -164,8 +167,8 @@ const uint32_t Crc32Lookup[MaxSlice][256] =
|
|||
0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
|
||||
0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
|
||||
0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D,
|
||||
}
|
||||
,{
|
||||
},
|
||||
{
|
||||
0x00000000, 0x191B3141, 0x32366282, 0x2B2D53C3, 0x646CC504, 0x7D77F445, 0x565AA786, 0x4F4196C7,
|
||||
0xC8D98A08, 0xD1C2BB49, 0xFAEFE88A, 0xE3F4D9CB, 0xACB54F0C, 0xB5AE7E4D, 0x9E832D8E, 0x87981CCF,
|
||||
0x4AC21251, 0x53D92310, 0x78F470D3, 0x61EF4192, 0x2EAED755, 0x37B5E614, 0x1C98B5D7, 0x05838496,
|
||||
|
@ -268,8 +271,8 @@ const uint32_t Crc32Lookup[MaxSlice][256] =
|
|||
0x13CB69D7, 0xAB770EB2, 0xB9C2A15C, 0x017EC639, 0x9CA9FE80, 0x241599E5, 0x36A0360B, 0x8E1C516E,
|
||||
0x866616A7, 0x3EDA71C2, 0x2C6FDE2C, 0x94D3B949, 0x090481F0, 0xB1B8E695, 0xA30D497B, 0x1BB12E1E,
|
||||
0x43D23E48, 0xFB6E592D, 0xE9DBF6C3, 0x516791A6, 0xCCB0A91F, 0x740CCE7A, 0x66B96194, 0xDE0506F1,
|
||||
}
|
||||
,{
|
||||
},
|
||||
{
|
||||
0x00000000, 0x3D6029B0, 0x7AC05360, 0x47A07AD0, 0xF580A6C0, 0xC8E08F70, 0x8F40F5A0, 0xB220DC10,
|
||||
0x30704BC1, 0x0D106271, 0x4AB018A1, 0x77D03111, 0xC5F0ED01, 0xF890C4B1, 0xBF30BE61, 0x825097D1,
|
||||
0x60E09782, 0x5D80BE32, 0x1A20C4E2, 0x2740ED52, 0x95603142, 0xA80018F2, 0xEFA06222, 0xD2C04B92,
|
||||
|
@ -407,8 +410,8 @@ const uint32_t Crc32Lookup[MaxSlice][256] =
|
|||
0x50353ED4, 0x9C9F3E4A, 0x121039A9, 0xDEBA3937, 0xD47F302E, 0x18D530B0, 0x965A3753, 0x5AF037CD,
|
||||
0xFF6B144A, 0x33C114D4, 0xBD4E1337, 0x71E413A9, 0x7B211AB0, 0xB78B1A2E, 0x39041DCD, 0xF5AE1D53,
|
||||
0x2C8E0FFF, 0xE0240F61, 0x6EAB0882, 0xA201081C, 0xA8C40105, 0x646E019B, 0xEAE10678, 0x264B06E6,
|
||||
}
|
||||
,{
|
||||
},
|
||||
{
|
||||
0x00000000, 0x177B1443, 0x2EF62886, 0x398D3CC5, 0x5DEC510C, 0x4A97454F, 0x731A798A, 0x64616DC9,
|
||||
0xBBD8A218, 0xACA3B65B, 0x952E8A9E, 0x82559EDD, 0xE634F314, 0xF14FE757, 0xC8C2DB92, 0xDFB9CFD1,
|
||||
0xACC04271, 0xBBBB5632, 0x82366AF7, 0x954D7EB4, 0xF12C137D, 0xE657073E, 0xDFDA3BFB, 0xC8A12FB8,
|
||||
|
|
|
@ -19,9 +19,12 @@ bool CamstudioCodec::SetupCompress(int width, int height, uint32_t compressionLe
|
|||
_compressionLevel = compressionLevel;
|
||||
_orgWidth = width;
|
||||
|
||||
if(width % 4 != 0) {
|
||||
if (width % 4 != 0)
|
||||
{
|
||||
_rowStride = ((int)((width * 24 + 31) / 32 * 4));
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
_rowStride = width * 3;
|
||||
}
|
||||
_height = height;
|
||||
|
@ -45,7 +48,8 @@ bool CamstudioCodec::SetupCompress(int width, int height, uint32_t compressionLe
|
|||
|
||||
void CamstudioCodec::LoadRow(uint8_t* inPointer, uint8_t* outPointer)
|
||||
{
|
||||
for(int x = 0; x < _orgWidth; x++) {
|
||||
for (int x = 0; x < _orgWidth; x++)
|
||||
{
|
||||
outPointer[0] = inPointer[0];
|
||||
outPointer[1] = inPointer[1];
|
||||
outPointer[2] = inPointer[2];
|
||||
|
@ -65,15 +69,20 @@ int CamstudioCodec::CompressFrame(bool isKeyFrame, uint8_t *frameData, uint8_t**
|
|||
_compressBuffer[1] = 8; //8-bit per color
|
||||
|
||||
uint8_t* rowBuffer = _currentFrame;
|
||||
for(int y = 0; y < _height; y++) {
|
||||
for (int y = 0; y < _height; y++)
|
||||
{
|
||||
LoadRow(frameData + (_height - y - 1) * _orgWidth * 4, rowBuffer);
|
||||
rowBuffer += _rowStride;
|
||||
}
|
||||
|
||||
if(isKeyFrame) {
|
||||
if (isKeyFrame)
|
||||
{
|
||||
_compressor.next_in = _currentFrame;
|
||||
} else {
|
||||
for(int i = 0, len = _rowStride * _height; i < len; i++) {
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0, len = _rowStride * _height; i < len; i++)
|
||||
{
|
||||
_buffer[i] = _currentFrame[i] - _prevFrame[i];
|
||||
}
|
||||
_compressor.next_in = _buffer;
|
||||
|
|
|
@ -5,7 +5,8 @@
|
|||
void Equalizer::ApplyEqualizer(uint32_t sampleCount, int16_t* samples)
|
||||
{
|
||||
double outL, outR;
|
||||
for(uint32_t i = 0; i < sampleCount; i++) {
|
||||
for (uint32_t i = 0; i < sampleCount; i++)
|
||||
{
|
||||
double inL = samples[i * 2];
|
||||
double inR = samples[i * 2 + 1];
|
||||
|
||||
|
@ -19,13 +20,18 @@ void Equalizer::ApplyEqualizer(uint32_t sampleCount, int16_t *samples)
|
|||
|
||||
void Equalizer::UpdateEqualizers(vector<double> bandGains, uint32_t sampleRate)
|
||||
{
|
||||
if(_prevSampleRate != sampleRate || memcmp(bandGains.data(), _prevEqualizerGains.data(), bandGains.size() * sizeof(double)) != 0) {
|
||||
vector<double> bands = { 40, 56, 80, 113, 160, 225, 320, 450, 600, 750, 1000, 2000, 3000, 4000, 5000, 6000, 7000, 10000, 12500, 13000 };
|
||||
if (_prevSampleRate != sampleRate || memcmp(bandGains.data(), _prevEqualizerGains.data(),
|
||||
bandGains.size() * sizeof(double)) != 0)
|
||||
{
|
||||
vector<double> bands = {
|
||||
40, 56, 80, 113, 160, 225, 320, 450, 600, 750, 1000, 2000, 3000, 4000, 5000, 6000, 7000, 10000, 12500, 13000
|
||||
};
|
||||
bands.insert(bands.begin(), bands[0] - (bands[1] - bands[0]));
|
||||
bands.insert(bands.end(), bands[bands.size() - 1] + (bands[bands.size() - 1] - bands[bands.size() - 2]));
|
||||
|
||||
_eqFrequencyGrid.reset(new orfanidis_eq::freq_grid());
|
||||
for(size_t i = 1; i < bands.size() - 1; i++) {
|
||||
for (size_t i = 1; i < bands.size() - 1; i++)
|
||||
{
|
||||
_eqFrequencyGrid->add_band((bands[i] + bands[i - 1]) / 2, bands[i], (bands[i + 1] + bands[i]) / 2);
|
||||
}
|
||||
|
||||
|
@ -34,7 +40,8 @@ void Equalizer::UpdateEqualizers(vector<double> bandGains, uint32_t sampleRate)
|
|||
_equalizerLeft->set_sample_rate(sampleRate);
|
||||
_equalizerRight->set_sample_rate(sampleRate);
|
||||
|
||||
for(unsigned int i = 0; i < _eqFrequencyGrid->get_number_of_bands(); i++) {
|
||||
for (unsigned int i = 0; i < _eqFrequencyGrid->get_number_of_bands(); i++)
|
||||
{
|
||||
_equalizerLeft->change_band_gain_db(i, bandGains[i]);
|
||||
_equalizerRight->change_band_gain_db(i, bandGains[i]);
|
||||
}
|
||||
|
|
|
@ -8,7 +8,9 @@ private:
|
|||
uint16_t _pos = 0;
|
||||
bool _lowerCase = false;
|
||||
|
||||
void WriteAll() {}
|
||||
void WriteAll()
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
FastString(bool lowerCase = false) { _lowerCase = lowerCase; }
|
||||
|
@ -17,20 +19,27 @@ public:
|
|||
|
||||
void Write(char c)
|
||||
{
|
||||
if(_lowerCase) {
|
||||
if (_lowerCase)
|
||||
{
|
||||
_buffer[_pos++] = ::tolower(c);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
_buffer[_pos++] = c;
|
||||
}
|
||||
}
|
||||
|
||||
void Write(const char* str, int size)
|
||||
{
|
||||
if(_lowerCase) {
|
||||
for(int i = 0; i < size; i++) {
|
||||
if (_lowerCase)
|
||||
{
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
_buffer[_pos + i] = ::tolower(str[i]);
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(_buffer + _pos, str, size);
|
||||
}
|
||||
_pos += size;
|
||||
|
@ -38,7 +47,8 @@ public:
|
|||
|
||||
void Delimiter(const char* str)
|
||||
{
|
||||
if(_pos > 0) {
|
||||
if (_pos > 0)
|
||||
{
|
||||
Write(str, (uint16_t)strlen(str));
|
||||
}
|
||||
}
|
||||
|
@ -50,11 +60,15 @@ public:
|
|||
|
||||
void Write(string& str, bool preserveCase = false)
|
||||
{
|
||||
if(_lowerCase && !preserveCase) {
|
||||
for(size_t i = 0; i < str.size(); i++) {
|
||||
if (_lowerCase && !preserveCase)
|
||||
{
|
||||
for (size_t i = 0; i < str.size(); i++)
|
||||
{
|
||||
_buffer[_pos + i] = ::tolower(str[i]);
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(_buffer + _pos, str.c_str(), str.size());
|
||||
}
|
||||
_pos += (uint16_t)str.size();
|
||||
|
|
|
@ -30,7 +30,8 @@ void FolderUtilities::SetHomeFolder(string homeFolder)
|
|||
|
||||
string FolderUtilities::GetHomeFolder()
|
||||
{
|
||||
if(_homeFolder.size() == 0) {
|
||||
if (_homeFolder.size() == 0)
|
||||
{
|
||||
throw std::runtime_error("Home folder not specified");
|
||||
}
|
||||
return _homeFolder;
|
||||
|
@ -42,15 +43,18 @@ void FolderUtilities::AddKnownGameFolder(string gameFolder)
|
|||
string lowerCaseFolder = gameFolder;
|
||||
std::transform(lowerCaseFolder.begin(), lowerCaseFolder.end(), lowerCaseFolder.begin(), ::tolower);
|
||||
|
||||
for(string folder : _gameFolders) {
|
||||
for (string folder : _gameFolders)
|
||||
{
|
||||
std::transform(folder.begin(), folder.end(), folder.begin(), ::tolower);
|
||||
if(folder.compare(lowerCaseFolder) == 0) {
|
||||
if (folder.compare(lowerCaseFolder) == 0)
|
||||
{
|
||||
alreadyExists = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!alreadyExists) {
|
||||
if (!alreadyExists)
|
||||
{
|
||||
_gameFolders.push_back(gameFolder);
|
||||
}
|
||||
}
|
||||
|
@ -60,7 +64,8 @@ vector<string> FolderUtilities::GetKnownGameFolders()
|
|||
return _gameFolders;
|
||||
}
|
||||
|
||||
void FolderUtilities::SetFolderOverrides(string saveFolder, string saveStateFolder, string screenshotFolder, string firmwareFolder)
|
||||
void FolderUtilities::SetFolderOverrides(string saveFolder, string saveStateFolder, string screenshotFolder,
|
||||
string firmwareFolder)
|
||||
{
|
||||
_saveFolderOverride = saveFolder;
|
||||
_saveStateFolderOverride = saveStateFolder;
|
||||
|
@ -71,9 +76,12 @@ void FolderUtilities::SetFolderOverrides(string saveFolder, string saveStateFold
|
|||
string FolderUtilities::GetSaveFolder()
|
||||
{
|
||||
string folder;
|
||||
if(_saveFolderOverride.empty()) {
|
||||
if (_saveFolderOverride.empty())
|
||||
{
|
||||
folder = CombinePath(GetHomeFolder(), "Saves");
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
folder = _saveFolderOverride;
|
||||
}
|
||||
CreateFolder(folder);
|
||||
|
@ -83,9 +91,12 @@ string FolderUtilities::GetSaveFolder()
|
|||
string FolderUtilities::GetFirmwareFolder()
|
||||
{
|
||||
string folder;
|
||||
if(_firmwareFolderOverride.empty()) {
|
||||
if (_firmwareFolderOverride.empty())
|
||||
{
|
||||
folder = CombinePath(GetHomeFolder(), "Firmware");
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
folder = _firmwareFolderOverride;
|
||||
}
|
||||
CreateFolder(folder);
|
||||
|
@ -109,9 +120,12 @@ string FolderUtilities::GetDebuggerFolder()
|
|||
string FolderUtilities::GetSaveStateFolder()
|
||||
{
|
||||
string folder;
|
||||
if(_saveStateFolderOverride.empty()) {
|
||||
if (_saveStateFolderOverride.empty())
|
||||
{
|
||||
folder = CombinePath(GetHomeFolder(), "SaveStates");
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
folder = _saveStateFolderOverride;
|
||||
}
|
||||
CreateFolder(folder);
|
||||
|
@ -121,9 +135,12 @@ string FolderUtilities::GetSaveStateFolder()
|
|||
string FolderUtilities::GetScreenshotFolder()
|
||||
{
|
||||
string folder;
|
||||
if(_screenshotFolderOverride.empty()) {
|
||||
if (_screenshotFolderOverride.empty())
|
||||
{
|
||||
folder = CombinePath(GetHomeFolder(), "Screenshots");
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
folder = _screenshotFolderOverride;
|
||||
}
|
||||
CreateFolder(folder);
|
||||
|
@ -140,7 +157,8 @@ string FolderUtilities::GetRecentGamesFolder()
|
|||
string FolderUtilities::GetExtension(string filename)
|
||||
{
|
||||
size_t position = filename.find_last_of('.');
|
||||
if(position != string::npos) {
|
||||
if (position != string::npos)
|
||||
{
|
||||
string ext = filename.substr(position, filename.size() - position);
|
||||
std::transform(ext.begin(), ext.end(), ext.begin(), ::tolower);
|
||||
return ext;
|
||||
|
@ -160,16 +178,22 @@ vector<string> FolderUtilities::GetFolders(string rootFolder)
|
|||
vector<string> folders;
|
||||
|
||||
std::error_code errorCode;
|
||||
if(!fs::is_directory(fs::u8path(rootFolder), errorCode)) {
|
||||
if (!fs::is_directory(fs::u8path(rootFolder), errorCode))
|
||||
{
|
||||
return folders;
|
||||
}
|
||||
|
||||
for(fs::recursive_directory_iterator i(fs::u8path(rootFolder)), end; i != end; i++) {
|
||||
if(i.depth() > 1) {
|
||||
for (fs::recursive_directory_iterator i(fs::u8path(rootFolder)), end; i != end; i++)
|
||||
{
|
||||
if (i.depth() > 1)
|
||||
{
|
||||
//Prevent excessive recursion
|
||||
i.disable_recursion_pending();
|
||||
} else {
|
||||
if(fs::is_directory(i->path(), errorCode)) {
|
||||
}
|
||||
else
|
||||
{
|
||||
if (fs::is_directory(i->path(), errorCode))
|
||||
{
|
||||
folders.push_back(i->path().u8string());
|
||||
}
|
||||
}
|
||||
|
@ -178,34 +202,46 @@ vector<string> FolderUtilities::GetFolders(string rootFolder)
|
|||
return folders;
|
||||
}
|
||||
|
||||
vector<string> FolderUtilities::GetFilesInFolder(string rootFolder, std::unordered_set<string> extensions, bool recursive)
|
||||
vector<string> FolderUtilities::GetFilesInFolder(string rootFolder, std::unordered_set<string> extensions,
|
||||
bool recursive)
|
||||
{
|
||||
vector<string> files;
|
||||
vector<string> folders = {{rootFolder}};
|
||||
|
||||
std::error_code errorCode;
|
||||
if(!fs::is_directory(fs::u8path(rootFolder), errorCode)) {
|
||||
if (!fs::is_directory(fs::u8path(rootFolder), errorCode))
|
||||
{
|
||||
return files;
|
||||
}
|
||||
|
||||
if(recursive) {
|
||||
for(fs::recursive_directory_iterator i(fs::u8path(rootFolder)), end; i != end; i++) {
|
||||
if(i.depth() > 1) {
|
||||
if (recursive)
|
||||
{
|
||||
for (fs::recursive_directory_iterator i(fs::u8path(rootFolder)), end; i != end; i++)
|
||||
{
|
||||
if (i.depth() > 1)
|
||||
{
|
||||
//Prevent excessive recursion
|
||||
i.disable_recursion_pending();
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
string extension = i->path().extension().u8string();
|
||||
std::transform(extension.begin(), extension.end(), extension.begin(), ::tolower);
|
||||
if(extensions.empty() || extensions.find(extension) != extensions.end()) {
|
||||
if (extensions.empty() || extensions.find(extension) != extensions.end())
|
||||
{
|
||||
files.push_back(i->path().u8string());
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for(fs::directory_iterator i(fs::u8path(rootFolder)), end; i != end; i++) {
|
||||
}
|
||||
else
|
||||
{
|
||||
for (fs::directory_iterator i(fs::u8path(rootFolder)), end; i != end; i++)
|
||||
{
|
||||
string extension = i->path().extension().u8string();
|
||||
std::transform(extension.begin(), extension.end(), extension.begin(), ::tolower);
|
||||
if(extensions.empty() || extensions.find(extension) != extensions.end()) {
|
||||
if (extensions.empty() || extensions.find(extension) != extensions.end())
|
||||
{
|
||||
files.push_back(i->path().u8string());
|
||||
}
|
||||
}
|
||||
|
@ -217,7 +253,8 @@ vector<string> FolderUtilities::GetFilesInFolder(string rootFolder, std::unorder
|
|||
string FolderUtilities::GetFilename(string filepath, bool includeExtension)
|
||||
{
|
||||
fs::path filename = fs::u8path(filepath).filename();
|
||||
if(!includeExtension) {
|
||||
if (!includeExtension)
|
||||
{
|
||||
filename.replace_extension("");
|
||||
}
|
||||
return filename.u8string();
|
||||
|
@ -231,9 +268,12 @@ string FolderUtilities::GetFolderName(string filepath)
|
|||
string FolderUtilities::CombinePath(string folder, string filename)
|
||||
{
|
||||
//Windows supports forward slashes for paths, too. And fs::u8path is abnormally slow.
|
||||
if(folder[folder.length() - 1] != '/') {
|
||||
if (folder[folder.length() - 1] != '/')
|
||||
{
|
||||
return folder + "/" + filename;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
return folder + filename;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,8 @@ public:
|
|||
static void SetHomeFolder(string homeFolder);
|
||||
static string GetHomeFolder();
|
||||
|
||||
static void SetFolderOverrides(string saveFolder, string saveStateFolder, string screenshotFolder, string firmwareFolder);
|
||||
static void SetFolderOverrides(string saveFolder, string saveStateFolder, string screenshotFolder,
|
||||
string firmwareFolder);
|
||||
|
||||
static void AddKnownGameFolder(string gameFolder);
|
||||
static vector<string> GetKnownGameFolders();
|
||||
|
|
|
@ -12,7 +12,8 @@ GifRecorder::~GifRecorder()
|
|||
StopRecording();
|
||||
}
|
||||
|
||||
bool GifRecorder::StartRecording(string filename, uint32_t width, uint32_t height, uint32_t bpp, uint32_t audioSampleRate, double fps)
|
||||
bool GifRecorder::StartRecording(string filename, uint32_t width, uint32_t height, uint32_t bpp,
|
||||
uint32_t audioSampleRate, double fps)
|
||||
{
|
||||
_outputFile = filename;
|
||||
_recording = GifBegin(_gif.get(), filename.c_str(), width, height, 2, 8, false);
|
||||
|
@ -22,7 +23,8 @@ bool GifRecorder::StartRecording(string filename, uint32_t width, uint32_t heigh
|
|||
|
||||
void GifRecorder::StopRecording()
|
||||
{
|
||||
if(_recording) {
|
||||
if (_recording)
|
||||
{
|
||||
GifEnd(_gif.get());
|
||||
}
|
||||
}
|
||||
|
@ -31,7 +33,8 @@ void GifRecorder::AddFrame(void* frameBuffer, uint32_t width, uint32_t height, d
|
|||
{
|
||||
_frameCounter++;
|
||||
|
||||
if(fps < 55 || (_frameCounter % 6) != 0) {
|
||||
if (fps < 55 || (_frameCounter % 6) != 0)
|
||||
{
|
||||
//At 60 FPS, skip 1 of every 6 frames (max FPS for GIFs is 50fps)
|
||||
GifWriteFrame(_gif.get(), (uint8_t*)frameBuffer, width, height, 2, 8, false);
|
||||
}
|
||||
|
|
|
@ -16,7 +16,8 @@ public:
|
|||
GifRecorder();
|
||||
virtual ~GifRecorder();
|
||||
|
||||
bool StartRecording(string filename, uint32_t width, uint32_t height, uint32_t bpp, uint32_t audioSampleRate, double fps) override;
|
||||
bool StartRecording(string filename, uint32_t width, uint32_t height, uint32_t bpp, uint32_t audioSampleRate,
|
||||
double fps) override;
|
||||
void StopRecording() override;
|
||||
void AddFrame(void* frameBuffer, uint32_t width, uint32_t height, double fps) override;
|
||||
void AddSound(int16_t* soundBuffer, uint32_t sampleCount, uint32_t sampleRate) override;
|
||||
|
|
|
@ -48,7 +48,8 @@ static inline uint32_t rgb_to_yuv(uint32_t c)
|
|||
}
|
||||
|
||||
/* Test if there is difference in color */
|
||||
static inline int yuv_diff(uint32_t yuv1, uint32_t yuv2) {
|
||||
static inline int yuv_diff(uint32_t yuv1, uint32_t yuv2)
|
||||
{
|
||||
return ((std::abs((int)((yuv1 & Ymask) - (yuv2 & Ymask))) > trY) ||
|
||||
(std::abs((int)((yuv1 & Umask) - (yuv2 & Umask))) > trU) ||
|
||||
(std::abs((int)((yuv1 & Vmask) - (yuv2 & Vmask))) > trV));
|
||||
|
@ -62,7 +63,8 @@ static inline int Diff(uint32_t c1, uint32_t c2)
|
|||
/* Interpolate functions */
|
||||
static inline uint32_t Interpolate_2(uint32_t c1, int w1, uint32_t c2, int w2, int s)
|
||||
{
|
||||
if (c1 == c2) {
|
||||
if (c1 == c2)
|
||||
{
|
||||
return c1;
|
||||
}
|
||||
return
|
||||
|
@ -74,7 +76,8 @@ static inline uint32_t Interpolate_2(uint32_t c1, int w1, uint32_t c2, int w2, i
|
|||
static inline uint32_t Interpolate_3(uint32_t c1, int w1, uint32_t c2, int w2, uint32_t c3, int w3, int s)
|
||||
{
|
||||
return
|
||||
(((((c1 & MASK_ALPHA) >> 24) * w1 + ((c2 & MASK_ALPHA) >> 24) * w2 + ((c3 & MASK_ALPHA) >> 24) * w3) << (24-s)) & MASK_ALPHA) +
|
||||
(((((c1 & MASK_ALPHA) >> 24) * w1 + ((c2 & MASK_ALPHA) >> 24) * w2 + ((c3 & MASK_ALPHA) >> 24) * w3) << (24 - s))
|
||||
& MASK_ALPHA) +
|
||||
((((c1 & MASK_2) * w1 + (c2 & MASK_2) * w2 + (c3 & MASK_2) * w3) >> s) & MASK_2) +
|
||||
((((c1 & MASK_13) * w1 + (c2 & MASK_13) * w2 + (c3 & MASK_13) * w3) >> s) & MASK_13);
|
||||
}
|
||||
|
|
|
@ -96,8 +96,10 @@ void HQX_CALLCONV hq2x_32_rb( uint32_t * sp, uint32_t srb, uint32_t * dp, uint32
|
|||
|
||||
for (j = 0; j < Yres; j++)
|
||||
{
|
||||
if (j>0) prevline = -spL; else prevline = 0;
|
||||
if (j<Yres-1) nextline = spL; else nextline = 0;
|
||||
if (j > 0) prevline = -spL;
|
||||
else prevline = 0;
|
||||
if (j < Yres - 1) nextline = spL;
|
||||
else nextline = 0;
|
||||
|
||||
for (i = 0; i < Xres; i++)
|
||||
{
|
||||
|
|
|
@ -101,8 +101,10 @@ void HQX_CALLCONV hq3x_32_rb( uint32_t * sp, uint32_t srb, uint32_t * dp, uint32
|
|||
|
||||
for (j = 0; j < Yres; j++)
|
||||
{
|
||||
if (j>0) prevline = -spL; else prevline = 0;
|
||||
if (j<Yres-1) nextline = spL; else nextline = 0;
|
||||
if (j > 0) prevline = -spL;
|
||||
else prevline = 0;
|
||||
if (j < Yres - 1) nextline = spL;
|
||||
else nextline = 0;
|
||||
|
||||
for (i = 0; i < Xres; i++)
|
||||
{
|
||||
|
|
|
@ -188,8 +188,10 @@ void HQX_CALLCONV hq4x_32_rb( uint32_t * sp, uint32_t srb, uint32_t * dp, uint32
|
|||
|
||||
for (j = 0; j < Yres; j++)
|
||||
{
|
||||
if (j>0) prevline = -spL; else prevline = 0;
|
||||
if (j<Yres-1) nextline = spL; else nextline = 0;
|
||||
if (j > 0) prevline = -spL;
|
||||
else prevline = 0;
|
||||
if (j < Yres - 1) nextline = spL;
|
||||
else nextline = 0;
|
||||
|
||||
for (i = 0; i < Xres; i++)
|
||||
{
|
||||
|
|
|
@ -50,8 +50,11 @@ void HQX_CALLCONV hq2x_32( uint32_t * src, uint32_t * dest, int width, int heigh
|
|||
void HQX_CALLCONV hq3x_32(uint32_t* src, uint32_t* dest, int width, int height);
|
||||
void HQX_CALLCONV hq4x_32(uint32_t* src, uint32_t* dest, int width, int height);
|
||||
|
||||
void HQX_CALLCONV hq2x_32_rb( uint32_t * src, uint32_t src_rowBytes, uint32_t * dest, uint32_t dest_rowBytes, int width, int height );
|
||||
void HQX_CALLCONV hq3x_32_rb( uint32_t * src, uint32_t src_rowBytes, uint32_t * dest, uint32_t dest_rowBytes, int width, int height );
|
||||
void HQX_CALLCONV hq4x_32_rb( uint32_t * src, uint32_t src_rowBytes, uint32_t * dest, uint32_t dest_rowBytes, int width, int height );
|
||||
void HQX_CALLCONV hq2x_32_rb(uint32_t* src, uint32_t src_rowBytes, uint32_t* dest, uint32_t dest_rowBytes, int width,
|
||||
int height);
|
||||
void HQX_CALLCONV hq3x_32_rb(uint32_t* src, uint32_t src_rowBytes, uint32_t* dest, uint32_t dest_rowBytes, int width,
|
||||
int height);
|
||||
void HQX_CALLCONV hq4x_32_rb(uint32_t* src, uint32_t src_rowBytes, uint32_t* dest, uint32_t dest_rowBytes, int width,
|
||||
int height);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -27,7 +27,8 @@ void HQX_CALLCONV hqxInit(void)
|
|||
{
|
||||
/* Initalize RGB to YUV lookup table */
|
||||
uint32_t c, r, g, b, y, u, v;
|
||||
for (c = 0; c < 16777215; c++) {
|
||||
for (c = 0; c < 16777215; c++)
|
||||
{
|
||||
r = (c & 0xFF0000) >> 16;
|
||||
g = (c & 0x00FF00) >> 8;
|
||||
b = c & 0x0000FF;
|
||||
|
@ -40,9 +41,13 @@ void HQX_CALLCONV hqxInit(void)
|
|||
|
||||
void HQX_CALLCONV hqx(uint32_t scale, uint32_t* src, uint32_t* dest, int width, int height)
|
||||
{
|
||||
switch(scale) {
|
||||
case 2: hq2x_32(src, dest, width, height); break;
|
||||
case 3: hq3x_32(src, dest, width, height); break;
|
||||
case 4: hq4x_32(src, dest, width, height); break;
|
||||
switch (scale)
|
||||
{
|
||||
case 2: hq2x_32(src, dest, width, height);
|
||||
break;
|
||||
case 3: hq3x_32(src, dest, width, height);
|
||||
break;
|
||||
case 4: hq4x_32(src, dest, width, height);
|
||||
break;
|
||||
}
|
||||
}
|
|
@ -36,7 +36,8 @@ void HermiteResampler::PushSample(double prevValues[4], int16_t sample)
|
|||
|
||||
void HermiteResampler::Reset()
|
||||
{
|
||||
for(int i = 0; i < 4; i++) {
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
_prevLeft[i] = 0.0;
|
||||
_prevRight[i] = 0.0;
|
||||
}
|
||||
|
@ -50,15 +51,18 @@ void HermiteResampler::SetSampleRates(double srcRate, double dstRate)
|
|||
|
||||
uint32_t HermiteResampler::Resample(int16_t* in, uint32_t inSampleCount, int16_t* out)
|
||||
{
|
||||
if(_rateRatio == 1.0) {
|
||||
if (_rateRatio == 1.0)
|
||||
{
|
||||
memcpy(out, in, inSampleCount * 2 * sizeof(int16_t));
|
||||
return inSampleCount;
|
||||
}
|
||||
|
||||
uint32_t outPos = 0;
|
||||
|
||||
for(uint32_t i = 0; i < inSampleCount * 2; i += 2) {
|
||||
while(_fraction <= 1.0) {
|
||||
for (uint32_t i = 0; i < inSampleCount * 2; i += 2)
|
||||
{
|
||||
while (_fraction <= 1.0)
|
||||
{
|
||||
//Generate interpolated samples until we have enough samples for the current source sample
|
||||
out[outPos] = HermiteInterpolate(_prevLeft, _fraction);
|
||||
out[outPos + 1] = HermiteInterpolate(_prevRight, _fraction);
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
#include "stdafx.h"
|
||||
#include "HexUtilities.h"
|
||||
|
||||
const vector<string> HexUtilities::_hexCache = { {
|
||||
const vector<string> HexUtilities::_hexCache = {
|
||||
{
|
||||
"00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "0A", "0B", "0C", "0D", "0E", "0F",
|
||||
"10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "1A", "1B", "1C", "1D", "1E", "1F",
|
||||
"20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "2A", "2B", "2C", "2D", "2E", "2F",
|
||||
|
@ -18,7 +19,8 @@ const vector<string> HexUtilities::_hexCache = { {
|
|||
"D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7", "D8", "D9", "DA", "DB", "DC", "DD", "DE", "DF",
|
||||
"E0", "E1", "E2", "E3", "E4", "E5", "E6", "E7", "E8", "E9", "EA", "EB", "EC", "ED", "EE", "EF",
|
||||
"F0", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "FA", "FB", "FC", "FD", "FE", "FF"
|
||||
} };
|
||||
}
|
||||
};
|
||||
|
||||
constexpr const char* _hexCharCache[256] = {
|
||||
"00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "0A", "0B", "0C", "0D", "0E", "0F",
|
||||
|
@ -43,13 +45,19 @@ constexpr const char* _hexCharCache[256] = {
|
|||
int HexUtilities::FromHex(string hex)
|
||||
{
|
||||
int value = 0;
|
||||
for(size_t i = 0, len = hex.size(); i < len; i++) {
|
||||
for (size_t i = 0, len = hex.size(); i < len; i++)
|
||||
{
|
||||
value <<= 4;
|
||||
if(hex[i] >= '0' && hex[i] <= '9') {
|
||||
if (hex[i] >= '0' && hex[i] <= '9')
|
||||
{
|
||||
value |= hex[i] - '0';
|
||||
} else if(hex[i] >= 'A' && hex[i] <= 'F') {
|
||||
}
|
||||
else if (hex[i] >= 'A' && hex[i] <= 'F')
|
||||
{
|
||||
value |= hex[i] - 'A' + 10;
|
||||
} else if(hex[i] >= 'a' && hex[i] <= 'f') {
|
||||
}
|
||||
else if (hex[i] >= 'a' && hex[i] <= 'f')
|
||||
{
|
||||
value |= hex[i] - 'a' + 10;
|
||||
}
|
||||
}
|
||||
|
@ -83,13 +91,21 @@ string HexUtilities::ToHex24(int32_t value)
|
|||
|
||||
string HexUtilities::ToHex(uint32_t value, bool fullSize)
|
||||
{
|
||||
if(fullSize || value > 0xFFFFFF) {
|
||||
return _hexCache[value >> 24] + _hexCache[(value >> 16) & 0xFF] + _hexCache[(value >> 8) & 0xFF] + _hexCache[value & 0xFF];
|
||||
} else if(value <= 0xFF) {
|
||||
if (fullSize || value > 0xFFFFFF)
|
||||
{
|
||||
return _hexCache[value >> 24] + _hexCache[(value >> 16) & 0xFF] + _hexCache[(value >> 8) & 0xFF] + _hexCache[value
|
||||
& 0xFF];
|
||||
}
|
||||
else if (value <= 0xFF)
|
||||
{
|
||||
return ToHex((uint8_t)value);
|
||||
} else if(value <= 0xFFFF) {
|
||||
}
|
||||
else if (value <= 0xFFFF)
|
||||
{
|
||||
return ToHex((uint16_t)value);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
return _hexCache[(value >> 16) & 0xFF] + _hexCache[(value >> 8) & 0xFF] + _hexCache[value & 0xFF];
|
||||
}
|
||||
}
|
||||
|
@ -98,7 +114,8 @@ string HexUtilities::ToHex(vector<uint8_t> &data)
|
|||
{
|
||||
string result;
|
||||
result.reserve(data.size() * 2);
|
||||
for(uint8_t value : data) {
|
||||
for (uint8_t value : data)
|
||||
{
|
||||
result += HexUtilities::ToHex(value);
|
||||
}
|
||||
return result;
|
||||
|
|
|
@ -7,4 +7,3 @@ class ISerializable
|
|||
public:
|
||||
virtual void Serialize(Serializer& s) = 0;
|
||||
};
|
||||
|
||||
|
|
|
@ -4,7 +4,8 @@
|
|||
class IVideoRecorder
|
||||
{
|
||||
public:
|
||||
virtual bool StartRecording(string filename, uint32_t width, uint32_t height, uint32_t bpp, uint32_t audioSampleRate, double fps) = 0;
|
||||
virtual bool StartRecording(string filename, uint32_t width, uint32_t height, uint32_t bpp, uint32_t audioSampleRate,
|
||||
double fps) = 0;
|
||||
virtual void StopRecording() = 0;
|
||||
|
||||
virtual void AddFrame(void* frameBuffer, uint32_t width, uint32_t height, double fps) = 0;
|
||||
|
|
|
@ -20,21 +20,27 @@ public:
|
|||
uint8_t buffer[3];
|
||||
|
||||
ipsFile.read((char*)buffer, 3);
|
||||
if(memcmp(buffer, "EOF", 3) == 0) {
|
||||
if (memcmp(buffer, "EOF", 3) == 0)
|
||||
{
|
||||
//EOF reached
|
||||
return false;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
Address = buffer[2] | (buffer[1] << 8) | (buffer[0] << 16);
|
||||
|
||||
ipsFile.read((char*)buffer, 2);
|
||||
Length = buffer[1] | (buffer[0] << 8);
|
||||
|
||||
if(Length == 0) {
|
||||
if (Length == 0)
|
||||
{
|
||||
//RLE record
|
||||
ipsFile.read((char*)buffer, 3);
|
||||
RepeatCount = buffer[1] | (buffer[0] << 8);
|
||||
Value = buffer[2];
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
Replacement.resize(Length);
|
||||
ipsFile.read((char*)Replacement.data(), Length);
|
||||
}
|
||||
|
@ -51,11 +57,14 @@ public:
|
|||
output.push_back((Length >> 8) & 0xFF);
|
||||
output.push_back(Length & 0xFF);
|
||||
|
||||
if(Length == 0) {
|
||||
if (Length == 0)
|
||||
{
|
||||
output.push_back((RepeatCount >> 8) & 0xFF);
|
||||
output.push_back(RepeatCount & 0xFF);
|
||||
output.push_back(Value);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
output.insert(output.end(), Replacement.data(), Replacement.data() + Replacement.size());
|
||||
}
|
||||
}
|
||||
|
@ -64,7 +73,8 @@ public:
|
|||
bool IpsPatcher::PatchBuffer(string ipsFilepath, vector<uint8_t>& input, vector<uint8_t>& output)
|
||||
{
|
||||
ifstream ipsFile(ipsFilepath, std::ios::in | std::ios::binary);
|
||||
if(ipsFile) {
|
||||
if (ipsFile)
|
||||
{
|
||||
return PatchBuffer(ipsFile, input, output);
|
||||
}
|
||||
return false;
|
||||
|
@ -81,7 +91,8 @@ bool IpsPatcher::PatchBuffer(std::istream &ipsFile, vector<uint8_t> &input, vect
|
|||
{
|
||||
char header[5];
|
||||
ipsFile.read((char*)&header, 5);
|
||||
if(memcmp((char*)&header, "PATCH", 5) != 0) {
|
||||
if (memcmp((char*)&header, "PATCH", 5) != 0)
|
||||
{
|
||||
//Invalid ips file
|
||||
return false;
|
||||
}
|
||||
|
@ -89,18 +100,24 @@ bool IpsPatcher::PatchBuffer(std::istream &ipsFile, vector<uint8_t> &input, vect
|
|||
vector<IpsRecord> records;
|
||||
int32_t truncateOffset = -1;
|
||||
size_t maxOutputSize = input.size();
|
||||
while(!ipsFile.eof()) {
|
||||
while (!ipsFile.eof())
|
||||
{
|
||||
IpsRecord record;
|
||||
if(record.ReadRecord(ipsFile)) {
|
||||
if(record.Address + record.Length + record.RepeatCount > maxOutputSize) {
|
||||
if (record.ReadRecord(ipsFile))
|
||||
{
|
||||
if (record.Address + record.Length + record.RepeatCount > maxOutputSize)
|
||||
{
|
||||
maxOutputSize = record.Address + record.Length + record.RepeatCount;
|
||||
}
|
||||
records.push_back(record);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
//EOF, try to read truncate offset record if it exists
|
||||
uint8_t buffer[3];
|
||||
ipsFile.read((char*)buffer, 3);
|
||||
if(!ipsFile.eof()) {
|
||||
if (!ipsFile.eof())
|
||||
{
|
||||
truncateOffset = buffer[2] | (buffer[1] << 8) | (buffer[0] << 16);
|
||||
}
|
||||
break;
|
||||
|
@ -110,15 +127,20 @@ bool IpsPatcher::PatchBuffer(std::istream &ipsFile, vector<uint8_t> &input, vect
|
|||
output.resize(maxOutputSize);
|
||||
std::copy(input.begin(), input.end(), output.begin());
|
||||
|
||||
for(IpsRecord record : records) {
|
||||
if(record.Length == 0) {
|
||||
for (IpsRecord record : records)
|
||||
{
|
||||
if (record.Length == 0)
|
||||
{
|
||||
std::fill(&output[record.Address], &output[record.Address] + record.RepeatCount, record.Value);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
std::copy(record.Replacement.begin(), record.Replacement.end(), output.begin() + record.Address);
|
||||
}
|
||||
}
|
||||
|
||||
if(truncateOffset != -1 && (int32_t)output.size() > truncateOffset) {
|
||||
if (truncateOffset != -1 && (int32_t)output.size() > truncateOffset)
|
||||
{
|
||||
output.resize(truncateOffset);
|
||||
}
|
||||
|
||||
|
@ -128,7 +150,8 @@ bool IpsPatcher::PatchBuffer(std::istream &ipsFile, vector<uint8_t> &input, vect
|
|||
vector<uint8_t> IpsPatcher::CreatePatch(vector<uint8_t> originalData, vector<uint8_t> newData)
|
||||
{
|
||||
vector<uint8_t> patchFile;
|
||||
if(originalData.size() != newData.size()) {
|
||||
if (originalData.size() != newData.size())
|
||||
{
|
||||
return patchFile;
|
||||
}
|
||||
|
||||
|
@ -136,23 +159,32 @@ vector<uint8_t> IpsPatcher::CreatePatch(vector<uint8_t> originalData, vector<uin
|
|||
patchFile.insert(patchFile.end(), header, header + sizeof(header));
|
||||
|
||||
size_t i = 0, len = originalData.size();
|
||||
while(i < len) {
|
||||
while(i < len && originalData[i] == newData[i]) {
|
||||
while (i < len)
|
||||
{
|
||||
while (i < len && originalData[i] == newData[i])
|
||||
{
|
||||
i++;
|
||||
}
|
||||
if(i < len) {
|
||||
if (i < len)
|
||||
{
|
||||
IpsRecord patchRecord;
|
||||
uint8_t rleByte = newData[i];
|
||||
uint8_t rleCount = 0;
|
||||
bool createRleRecord = false;
|
||||
patchRecord.Address = (uint32_t)i;
|
||||
patchRecord.Length = 0;
|
||||
while(i < len && patchRecord.Length < 65535 && originalData[i] != newData[i]) {
|
||||
if(newData[i] == rleByte) {
|
||||
while (i < len && patchRecord.Length < 65535 && originalData[i] != newData[i])
|
||||
{
|
||||
if (newData[i] == rleByte)
|
||||
{
|
||||
rleCount++;
|
||||
} else if(createRleRecord) {
|
||||
}
|
||||
else if (createRleRecord)
|
||||
{
|
||||
break;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
rleByte = newData[i];
|
||||
rleCount = 1;
|
||||
}
|
||||
|
@ -160,24 +192,32 @@ vector<uint8_t> IpsPatcher::CreatePatch(vector<uint8_t> originalData, vector<uin
|
|||
patchRecord.Length++;
|
||||
i++;
|
||||
|
||||
if((patchRecord.Length == rleCount && rleCount > 3) || rleCount > 13) {
|
||||
if ((patchRecord.Length == rleCount && rleCount > 3) || rleCount > 13)
|
||||
{
|
||||
//Making a RLE entry would probably save space, so write the current entry and create a RLE entry after it
|
||||
if(patchRecord.Length == rleCount) {
|
||||
if (patchRecord.Length == rleCount)
|
||||
{
|
||||
//Same character since the start of this entry, make the RLE entry now
|
||||
createRleRecord = true;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
patchRecord.Length -= rleCount;
|
||||
i -= rleCount;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(createRleRecord) {
|
||||
if (createRleRecord)
|
||||
{
|
||||
patchRecord.Length = 0;
|
||||
patchRecord.RepeatCount = rleCount;
|
||||
patchRecord.Value = rleByte;
|
||||
} else {
|
||||
patchRecord.Replacement = vector<uint8_t>(&newData[patchRecord.Address], &newData[patchRecord.Address + patchRecord.Length]);
|
||||
}
|
||||
else
|
||||
{
|
||||
patchRecord.Replacement = vector<uint8_t>(&newData[patchRecord.Address],
|
||||
&newData[patchRecord.Address + patchRecord.Length]);
|
||||
}
|
||||
patchRecord.WriteRecord(patchFile);
|
||||
}
|
||||
|
|
|
@ -40,8 +40,7 @@
|
|||
typename_t colorL = *(in + nextline + nextcolumn2); \
|
||||
typename_t colorM = *(in + nextline2 - prevcolumn); \
|
||||
typename_t colorN = *(in + nextline2 + 0); \
|
||||
typename_t colorO = *(in + nextline2 + nextcolumn); \
|
||||
|
||||
typename_t colorO = *(in + nextline2 + nextcolumn);
|
||||
#ifndef twoxsai_function
|
||||
#define twoxsai_function(result_cb, interpolate_cb, interpolate2_cb) \
|
||||
if (colorA == colorD && colorB != colorC) \
|
||||
|
@ -130,12 +129,14 @@
|
|||
out += 2
|
||||
#endif
|
||||
|
||||
void twoxsai_generic_xrgb8888(unsigned width, unsigned height, uint32_t *src, unsigned src_stride, uint32_t *dst, unsigned dst_stride)
|
||||
void twoxsai_generic_xrgb8888(unsigned width, unsigned height, uint32_t* src, unsigned src_stride, uint32_t* dst,
|
||||
unsigned dst_stride)
|
||||
{
|
||||
unsigned finish;
|
||||
int y = 0;
|
||||
int x = 0;
|
||||
for(; height; height--) {
|
||||
for (; height; height--)
|
||||
{
|
||||
uint32_t* in = (uint32_t*)src;
|
||||
uint32_t* out = (uint32_t*)dst;
|
||||
|
||||
|
@ -143,7 +144,8 @@ void twoxsai_generic_xrgb8888(unsigned width, unsigned height, uint32_t *src, un
|
|||
int nextline = (height > 1 ? src_stride : 0);
|
||||
int nextline2 = (height > 2 ? src_stride * 2 : nextline);
|
||||
|
||||
for(finish = width; finish; finish -= 1) {
|
||||
for (finish = width; finish; finish -= 1)
|
||||
{
|
||||
int prevcolumn = (x > 0 ? 1 : 0);
|
||||
int nextcolumn = (finish > 1 ? 1 : 0);
|
||||
int nextcolumn2 = (finish > 2 ? 2 : nextcolumn);
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
#pragma once
|
||||
#include "../stdafx.h"
|
||||
|
||||
extern void supertwoxsai_generic_xrgb8888(unsigned width, unsigned height, uint32_t *src, unsigned src_stride, uint32_t *dst, unsigned dst_stride);
|
||||
extern void twoxsai_generic_xrgb8888(unsigned width, unsigned height, uint32_t *src, unsigned src_stride, uint32_t *dst, unsigned dst_stride);
|
||||
extern void supereagle_generic_xrgb8888(unsigned width, unsigned height, uint32_t *src, unsigned src_stride, uint32_t *dst, unsigned dst_stride);
|
||||
|
||||
extern void supertwoxsai_generic_xrgb8888(unsigned width, unsigned height, uint32_t* src, unsigned src_stride,
|
||||
uint32_t* dst, unsigned dst_stride);
|
||||
extern void twoxsai_generic_xrgb8888(unsigned width, unsigned height, uint32_t* src, unsigned src_stride, uint32_t* dst,
|
||||
unsigned dst_stride);
|
||||
extern void supereagle_generic_xrgb8888(unsigned width, unsigned height, uint32_t* src, unsigned src_stride,
|
||||
uint32_t* dst, unsigned dst_stride);
|
||||
|
|
|
@ -108,12 +108,14 @@
|
|||
out += 2
|
||||
#endif
|
||||
|
||||
void supertwoxsai_generic_xrgb8888(unsigned width, unsigned height, uint32_t *src, unsigned src_stride, uint32_t *dst, unsigned dst_stride)
|
||||
void supertwoxsai_generic_xrgb8888(unsigned width, unsigned height, uint32_t* src, unsigned src_stride, uint32_t* dst,
|
||||
unsigned dst_stride)
|
||||
{
|
||||
unsigned finish;
|
||||
int y = 0;
|
||||
int x = 0;
|
||||
for(; height; height--) {
|
||||
for (; height; height--)
|
||||
{
|
||||
uint32_t* in = (uint32_t*)src;
|
||||
uint32_t* out = (uint32_t*)dst;
|
||||
|
||||
|
@ -121,7 +123,8 @@ void supertwoxsai_generic_xrgb8888(unsigned width, unsigned height, uint32_t *sr
|
|||
int nextline = (height > 1 ? src_stride : 0);
|
||||
int nextline2 = (height > 2 ? src_stride * 2 : nextline);
|
||||
|
||||
for(finish = width; finish; finish -= 1) {
|
||||
for (finish = width; finish; finish -= 1)
|
||||
{
|
||||
int prevcolumn = (x > 0 ? 1 : 0);
|
||||
int nextcolumn = (finish > 1 ? 1 : 0);
|
||||
int nextcolumn2 = (finish > 2 ? 2 : nextcolumn);
|
||||
|
@ -133,7 +136,8 @@ void supertwoxsai_generic_xrgb8888(unsigned width, unsigned height, uint32_t *sr
|
|||
// A1 A2
|
||||
//--------------------------------------
|
||||
|
||||
supertwoxsai_function(supertwoxsai_result, supertwoxsai_interpolate_xrgb8888, supertwoxsai_interpolate2_xrgb8888);
|
||||
supertwoxsai_function(supertwoxsai_result, supertwoxsai_interpolate_xrgb8888,
|
||||
supertwoxsai_interpolate2_xrgb8888);
|
||||
x++;
|
||||
}
|
||||
|
||||
|
|
|
@ -125,12 +125,14 @@
|
|||
out += 2
|
||||
#endif
|
||||
|
||||
void supereagle_generic_xrgb8888(unsigned width, unsigned height, uint32_t *src, unsigned src_stride, uint32_t *dst, unsigned dst_stride)
|
||||
void supereagle_generic_xrgb8888(unsigned width, unsigned height, uint32_t* src, unsigned src_stride, uint32_t* dst,
|
||||
unsigned dst_stride)
|
||||
{
|
||||
unsigned finish;
|
||||
int y = 0;
|
||||
int x = 0;
|
||||
for(; height; height--) {
|
||||
for (; height; height--)
|
||||
{
|
||||
uint32_t* in = (uint32_t*)src;
|
||||
uint32_t* out = (uint32_t*)dst;
|
||||
|
||||
|
@ -138,7 +140,8 @@ void supereagle_generic_xrgb8888(unsigned width, unsigned height, uint32_t *src,
|
|||
int nextline = (height > 1 ? src_stride : 0);
|
||||
int nextline2 = (height > 2 ? src_stride * 2 : nextline);
|
||||
|
||||
for(finish = width; finish; finish -= 1) {
|
||||
for (finish = width; finish; finish -= 1)
|
||||
{
|
||||
int prevcolumn = (x > 0 ? 1 : 0);
|
||||
int nextcolumn = (finish > 1 ? 1 : 0);
|
||||
int nextcolumn2 = (finish > 2 ? 2 : nextcolumn);
|
||||
|
|
|
@ -12,11 +12,14 @@ private:
|
|||
|
||||
void UpdateSample(int16_t* buffer, size_t index, int strength, double volume, int16_t* _prevSamples)
|
||||
{
|
||||
if(strength > 0) {
|
||||
if (strength > 0)
|
||||
{
|
||||
int32_t sum = std::accumulate(_prevSamples, _prevSamples + strength, 0);
|
||||
buffer[index] = (int16_t)((sum + buffer[index]) / (strength + 1) * volume);
|
||||
_prevSamples[_prevSampleCounter] = buffer[index];
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer[index] = (int16_t)(buffer[index] * volume);
|
||||
}
|
||||
}
|
||||
|
@ -26,10 +29,12 @@ public:
|
|||
{
|
||||
assert(strength <= 10);
|
||||
|
||||
for(size_t i = 0; i < sampleCount*2; i+=2) {
|
||||
for (size_t i = 0; i < sampleCount * 2; i += 2)
|
||||
{
|
||||
UpdateSample(buffer, i, strength, volume, _prevSamplesLeft);
|
||||
UpdateSample(buffer, i + 1, strength, volume, _prevSamplesRight);
|
||||
if(strength > 0) {
|
||||
if (strength > 0)
|
||||
{
|
||||
_prevSampleCounter = (_prevSampleCounter + 1) % strength;
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -4,10 +4,12 @@
|
|||
class PNGHelper
|
||||
{
|
||||
private:
|
||||
static int DecodePNG(vector<unsigned char>& out_image, unsigned long& image_width, unsigned long& image_height, const unsigned char* in_png, size_t in_size, bool convert_to_rgba32 = true);
|
||||
static int DecodePNG(vector<unsigned char>& out_image, unsigned long& image_width, unsigned long& image_height,
|
||||
const unsigned char* in_png, size_t in_size, bool convert_to_rgba32 = true);
|
||||
|
||||
public:
|
||||
static bool WritePNG(std::stringstream &stream, uint32_t* buffer, uint32_t xSize, uint32_t ySize, uint32_t bitsPerPixel = 32);
|
||||
static bool WritePNG(std::stringstream& stream, uint32_t* buffer, uint32_t xSize, uint32_t ySize,
|
||||
uint32_t bitsPerPixel = 32);
|
||||
static bool WritePNG(string filename, uint32_t* buffer, uint32_t xSize, uint32_t ySize, uint32_t bitsPerPixel = 32);
|
||||
static bool ReadPNG(string filename, vector<uint8_t>& pngData, uint32_t& pngWidth, uint32_t& pngHeight);
|
||||
static bool ReadPNG(vector<uint8_t> input, vector<uint8_t>& output, uint32_t& pngWidth, uint32_t& pngHeight);
|
||||
|
|
|
@ -27,7 +27,8 @@ void PlatformUtilities::EnableHighResolutionTimer()
|
|||
{
|
||||
#if !defined(LIBRETRO) && defined(_WIN32)
|
||||
//Request a 1ms timer resolution on Windows while a game is running
|
||||
if(!_highResTimerEnabled) {
|
||||
if (!_highResTimerEnabled)
|
||||
{
|
||||
timeBeginPeriod(1);
|
||||
_highResTimerEnabled = true;
|
||||
}
|
||||
|
@ -37,7 +38,8 @@ void PlatformUtilities::EnableHighResolutionTimer()
|
|||
void PlatformUtilities::RestoreTimerResolution()
|
||||
{
|
||||
#if !defined(LIBRETRO) && defined(_WIN32)
|
||||
if(_highResTimerEnabled) {
|
||||
if (_highResTimerEnabled)
|
||||
{
|
||||
timeEndPeriod(1);
|
||||
_highResTimerEnabled = false;
|
||||
}
|
||||
|
|
|
@ -31,8 +31,10 @@ public:
|
|||
//Convert raw frame to BMP/DIB format (row order is reversed)
|
||||
uint8_t* buffer = _buffer;
|
||||
frameData += (_height - 1) * _width * 4;
|
||||
for(int y = 0; y < _height; y++) {
|
||||
for(int x = 0; x < _width; x++) {
|
||||
for (int y = 0; y < _height; y++)
|
||||
{
|
||||
for (int x = 0; x < _width; x++)
|
||||
{
|
||||
buffer[0] = frameData[0];
|
||||
buffer[1] = frameData[1];
|
||||
buffer[2] = frameData[2];
|
||||
|
|
|
@ -16,7 +16,8 @@ SZReader::~SZReader()
|
|||
|
||||
bool SZReader::InternalLoadArchive(void* buffer, size_t size)
|
||||
{
|
||||
if(_initialized) {
|
||||
if (_initialized)
|
||||
{
|
||||
SzArEx_Free(&_archive, &_allocImp);
|
||||
_initialized = false;
|
||||
}
|
||||
|
@ -34,26 +35,32 @@ bool SZReader::InternalLoadArchive(void* buffer, size_t size)
|
|||
bool SZReader::ExtractFile(string filename, vector<uint8_t>& output)
|
||||
{
|
||||
bool result = false;
|
||||
if(_initialized) {
|
||||
if (_initialized)
|
||||
{
|
||||
char16_t* utf16Filename = (char16_t*)SzAlloc(nullptr, 2000);
|
||||
|
||||
uint32_t blockIndex = 0xFFFFFFFF;
|
||||
uint8_t* outBuffer = 0;
|
||||
size_t outBufferSize = 0;
|
||||
|
||||
for(uint32_t i = 0; i < _archive.NumFiles; i++) {
|
||||
for (uint32_t i = 0; i < _archive.NumFiles; i++)
|
||||
{
|
||||
size_t offset = 0;
|
||||
size_t outSizeProcessed = 0;
|
||||
unsigned isDir = SzArEx_IsDir(&_archive, i);
|
||||
if(isDir) {
|
||||
if (isDir)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
SzArEx_GetFileNameUtf16(&_archive, i, (uint16_t*)utf16Filename);
|
||||
string entryName = utf8::utf8::encode(std::u16string(utf16Filename));
|
||||
if(filename == entryName) {
|
||||
WRes res = SzArEx_Extract(&_archive, &_lookStream.s, i, &blockIndex, &outBuffer, &outBufferSize, &offset, &outSizeProcessed, &_allocImp, &_allocTempImp);
|
||||
if(res == SZ_OK) {
|
||||
if (filename == entryName)
|
||||
{
|
||||
WRes res = SzArEx_Extract(&_archive, &_lookStream.s, i, &blockIndex, &outBuffer, &outBufferSize, &offset,
|
||||
&outSizeProcessed, &_allocImp, &_allocTempImp);
|
||||
if (res == SZ_OK)
|
||||
{
|
||||
output = vector<uint8_t>(outBuffer + offset, outBuffer + offset + outSizeProcessed);
|
||||
result = true;
|
||||
}
|
||||
|
@ -72,10 +79,13 @@ vector<string> SZReader::InternalGetFileList()
|
|||
vector<string> filenames;
|
||||
char16_t* utf16Filename = (char16_t*)SzAlloc(nullptr, 2000);
|
||||
|
||||
if(_initialized) {
|
||||
for(uint32_t i = 0; i < _archive.NumFiles; i++) {
|
||||
if (_initialized)
|
||||
{
|
||||
for (uint32_t i = 0; i < _archive.NumFiles; i++)
|
||||
{
|
||||
unsigned isDir = SzArEx_IsDir(&_archive, i);
|
||||
if(isDir) {
|
||||
if (isDir)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -44,15 +44,19 @@
|
|||
*/
|
||||
/* #define USE_SCALE_RANDOMWRITE */
|
||||
|
||||
static inline void scale2x_8_def_border(scale2x_uint8* dst, const scale2x_uint8* src0, const scale2x_uint8* src1, const scale2x_uint8* src2, unsigned count)
|
||||
static inline void scale2x_8_def_border(scale2x_uint8* dst, const scale2x_uint8* src0, const scale2x_uint8* src1,
|
||||
const scale2x_uint8* src2, unsigned count)
|
||||
{
|
||||
assert(count >= 2);
|
||||
|
||||
/* first pixel */
|
||||
if (src0[0] != src2[0] && src1[0] != src1[1]) {
|
||||
if (src0[0] != src2[0] && src1[0] != src1[1])
|
||||
{
|
||||
dst[0] = src1[0] == src0[0] ? src0[0] : src1[0];
|
||||
dst[1] = src1[1] == src0[0] ? src0[0] : src1[0];
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
dst[0] = src1[0];
|
||||
dst[1] = src1[0];
|
||||
}
|
||||
|
@ -63,11 +67,15 @@ static inline void scale2x_8_def_border(scale2x_uint8* dst, const scale2x_uint8*
|
|||
|
||||
/* central pixels */
|
||||
count -= 2;
|
||||
while (count) {
|
||||
if (src0[0] != src2[0] && src1[-1] != src1[1]) {
|
||||
while (count)
|
||||
{
|
||||
if (src0[0] != src2[0] && src1[-1] != src1[1])
|
||||
{
|
||||
dst[0] = src1[-1] == src0[0] ? src0[0] : src1[0];
|
||||
dst[1] = src1[1] == src0[0] ? src0[0] : src1[0];
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
dst[0] = src1[0];
|
||||
dst[1] = src1[0];
|
||||
}
|
||||
|
@ -80,24 +88,33 @@ static inline void scale2x_8_def_border(scale2x_uint8* dst, const scale2x_uint8*
|
|||
}
|
||||
|
||||
/* last pixel */
|
||||
if (src0[0] != src2[0] && src1[-1] != src1[0]) {
|
||||
if (src0[0] != src2[0] && src1[-1] != src1[0])
|
||||
{
|
||||
dst[0] = src1[-1] == src0[0] ? src0[0] : src1[0];
|
||||
dst[1] = src1[0] == src0[0] ? src0[0] : src1[0];
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
dst[0] = src1[0];
|
||||
dst[1] = src1[0];
|
||||
}
|
||||
}
|
||||
|
||||
static inline void scale2x_8_def_center(scale2x_uint8* dst, const scale2x_uint8* src0, const scale2x_uint8* src1, const scale2x_uint8* src2, unsigned count)
|
||||
static inline void scale2x_8_def_center(scale2x_uint8* dst, const scale2x_uint8* src0, const scale2x_uint8* src1,
|
||||
const scale2x_uint8* src2, unsigned count)
|
||||
{
|
||||
assert(count >= 2);
|
||||
|
||||
/* first pixel */
|
||||
if (src0[0] != src2[0] && src1[0] != src1[1]) {
|
||||
if (src0[0] != src2[0] && src1[0] != src1[1])
|
||||
{
|
||||
dst[0] = src1[0];
|
||||
dst[1] = (src1[1] == src0[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src0[1]) ? src1[1] : src1[0];
|
||||
} else {
|
||||
dst[1] = (src1[1] == src0[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src0[1])
|
||||
? src1[1]
|
||||
: src1[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
dst[0] = src1[0];
|
||||
dst[1] = src1[0];
|
||||
}
|
||||
|
@ -108,11 +125,19 @@ static inline void scale2x_8_def_center(scale2x_uint8* dst, const scale2x_uint8*
|
|||
|
||||
/* central pixels */
|
||||
count -= 2;
|
||||
while (count) {
|
||||
if (src0[0] != src2[0] && src1[-1] != src1[1]) {
|
||||
dst[0] = (src1[-1] == src0[0] && src1[0] != src2[-1]) || (src1[-1] == src2[0] && src1[0] != src0[-1]) ? src1[-1] : src1[0];
|
||||
dst[1] = (src1[1] == src0[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src0[1]) ? src1[1] : src1[0];
|
||||
} else {
|
||||
while (count)
|
||||
{
|
||||
if (src0[0] != src2[0] && src1[-1] != src1[1])
|
||||
{
|
||||
dst[0] = (src1[-1] == src0[0] && src1[0] != src2[-1]) || (src1[-1] == src2[0] && src1[0] != src0[-1])
|
||||
? src1[-1]
|
||||
: src1[0];
|
||||
dst[1] = (src1[1] == src0[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src0[1])
|
||||
? src1[1]
|
||||
: src1[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
dst[0] = src1[0];
|
||||
dst[1] = src1[0];
|
||||
}
|
||||
|
@ -125,24 +150,33 @@ static inline void scale2x_8_def_center(scale2x_uint8* dst, const scale2x_uint8*
|
|||
}
|
||||
|
||||
/* last pixel */
|
||||
if (src0[0] != src2[0] && src1[-1] != src1[0]) {
|
||||
dst[0] = (src1[-1] == src0[0] && src1[0] != src2[-1]) || (src1[-1] == src2[0] && src1[0] != src0[-1]) ? src1[-1] : src1[0];
|
||||
if (src0[0] != src2[0] && src1[-1] != src1[0])
|
||||
{
|
||||
dst[0] = (src1[-1] == src0[0] && src1[0] != src2[-1]) || (src1[-1] == src2[0] && src1[0] != src0[-1])
|
||||
? src1[-1]
|
||||
: src1[0];
|
||||
dst[1] = src1[0];
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
dst[0] = src1[0];
|
||||
dst[1] = src1[0];
|
||||
}
|
||||
}
|
||||
|
||||
static inline void scale2x_16_def_border(scale2x_uint16* dst, const scale2x_uint16* src0, const scale2x_uint16* src1, const scale2x_uint16* src2, unsigned count)
|
||||
static inline void scale2x_16_def_border(scale2x_uint16* dst, const scale2x_uint16* src0, const scale2x_uint16* src1,
|
||||
const scale2x_uint16* src2, unsigned count)
|
||||
{
|
||||
assert(count >= 2);
|
||||
|
||||
/* first pixel */
|
||||
if (src0[0] != src2[0] && src1[0] != src1[1]) {
|
||||
if (src0[0] != src2[0] && src1[0] != src1[1])
|
||||
{
|
||||
dst[0] = src1[0] == src0[0] ? src0[0] : src1[0];
|
||||
dst[1] = src1[1] == src0[0] ? src0[0] : src1[0];
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
dst[0] = src1[0];
|
||||
dst[1] = src1[0];
|
||||
}
|
||||
|
@ -153,11 +187,15 @@ static inline void scale2x_16_def_border(scale2x_uint16* dst, const scale2x_uint
|
|||
|
||||
/* central pixels */
|
||||
count -= 2;
|
||||
while (count) {
|
||||
if (src0[0] != src2[0] && src1[-1] != src1[1]) {
|
||||
while (count)
|
||||
{
|
||||
if (src0[0] != src2[0] && src1[-1] != src1[1])
|
||||
{
|
||||
dst[0] = src1[-1] == src0[0] ? src0[0] : src1[0];
|
||||
dst[1] = src1[1] == src0[0] ? src0[0] : src1[0];
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
dst[0] = src1[0];
|
||||
dst[1] = src1[0];
|
||||
}
|
||||
|
@ -170,24 +208,33 @@ static inline void scale2x_16_def_border(scale2x_uint16* dst, const scale2x_uint
|
|||
}
|
||||
|
||||
/* last pixel */
|
||||
if (src0[0] != src2[0] && src1[-1] != src1[0]) {
|
||||
if (src0[0] != src2[0] && src1[-1] != src1[0])
|
||||
{
|
||||
dst[0] = src1[-1] == src0[0] ? src0[0] : src1[0];
|
||||
dst[1] = src1[0] == src0[0] ? src0[0] : src1[0];
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
dst[0] = src1[0];
|
||||
dst[1] = src1[0];
|
||||
}
|
||||
}
|
||||
|
||||
static inline void scale2x_16_def_center(scale2x_uint16* dst, const scale2x_uint16* src0, const scale2x_uint16* src1, const scale2x_uint16* src2, unsigned count)
|
||||
static inline void scale2x_16_def_center(scale2x_uint16* dst, const scale2x_uint16* src0, const scale2x_uint16* src1,
|
||||
const scale2x_uint16* src2, unsigned count)
|
||||
{
|
||||
assert(count >= 2);
|
||||
|
||||
/* first pixel */
|
||||
if (src0[0] != src2[0] && src1[0] != src1[1]) {
|
||||
if (src0[0] != src2[0] && src1[0] != src1[1])
|
||||
{
|
||||
dst[0] = src1[0];
|
||||
dst[1] = (src1[1] == src0[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src0[1]) ? src1[1] : src1[0];
|
||||
} else {
|
||||
dst[1] = (src1[1] == src0[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src0[1])
|
||||
? src1[1]
|
||||
: src1[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
dst[0] = src1[0];
|
||||
dst[1] = src1[0];
|
||||
}
|
||||
|
@ -198,11 +245,19 @@ static inline void scale2x_16_def_center(scale2x_uint16* dst, const scale2x_uint
|
|||
|
||||
/* central pixels */
|
||||
count -= 2;
|
||||
while (count) {
|
||||
if (src0[0] != src2[0] && src1[-1] != src1[1]) {
|
||||
dst[0] = (src1[-1] == src0[0] && src1[0] != src2[-1]) || (src1[-1] == src2[0] && src1[0] != src0[-1]) ? src1[-1] : src1[0];
|
||||
dst[1] = (src1[1] == src0[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src0[1]) ? src1[1] : src1[0];
|
||||
} else {
|
||||
while (count)
|
||||
{
|
||||
if (src0[0] != src2[0] && src1[-1] != src1[1])
|
||||
{
|
||||
dst[0] = (src1[-1] == src0[0] && src1[0] != src2[-1]) || (src1[-1] == src2[0] && src1[0] != src0[-1])
|
||||
? src1[-1]
|
||||
: src1[0];
|
||||
dst[1] = (src1[1] == src0[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src0[1])
|
||||
? src1[1]
|
||||
: src1[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
dst[0] = src1[0];
|
||||
dst[1] = src1[0];
|
||||
}
|
||||
|
@ -215,24 +270,33 @@ static inline void scale2x_16_def_center(scale2x_uint16* dst, const scale2x_uint
|
|||
}
|
||||
|
||||
/* last pixel */
|
||||
if (src0[0] != src2[0] && src1[-1] != src1[0]) {
|
||||
dst[0] = (src1[-1] == src0[0] && src1[0] != src2[-1]) || (src1[-1] == src2[0] && src1[0] != src0[-1]) ? src1[-1] : src1[0];
|
||||
if (src0[0] != src2[0] && src1[-1] != src1[0])
|
||||
{
|
||||
dst[0] = (src1[-1] == src0[0] && src1[0] != src2[-1]) || (src1[-1] == src2[0] && src1[0] != src0[-1])
|
||||
? src1[-1]
|
||||
: src1[0];
|
||||
dst[1] = src1[0];
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
dst[0] = src1[0];
|
||||
dst[1] = src1[0];
|
||||
}
|
||||
}
|
||||
|
||||
static inline void scale2x_32_def_border(scale2x_uint32* dst, const scale2x_uint32* src0, const scale2x_uint32* src1, const scale2x_uint32* src2, unsigned count)
|
||||
static inline void scale2x_32_def_border(scale2x_uint32* dst, const scale2x_uint32* src0, const scale2x_uint32* src1,
|
||||
const scale2x_uint32* src2, unsigned count)
|
||||
{
|
||||
assert(count >= 2);
|
||||
|
||||
/* first pixel */
|
||||
if (src0[0] != src2[0] && src1[0] != src1[1]) {
|
||||
if (src0[0] != src2[0] && src1[0] != src1[1])
|
||||
{
|
||||
dst[0] = src1[0] == src0[0] ? src0[0] : src1[0];
|
||||
dst[1] = src1[1] == src0[0] ? src0[0] : src1[0];
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
dst[0] = src1[0];
|
||||
dst[1] = src1[0];
|
||||
}
|
||||
|
@ -243,11 +307,15 @@ static inline void scale2x_32_def_border(scale2x_uint32* dst, const scale2x_uint
|
|||
|
||||
/* central pixels */
|
||||
count -= 2;
|
||||
while (count) {
|
||||
if (src0[0] != src2[0] && src1[-1] != src1[1]) {
|
||||
while (count)
|
||||
{
|
||||
if (src0[0] != src2[0] && src1[-1] != src1[1])
|
||||
{
|
||||
dst[0] = src1[-1] == src0[0] ? src0[0] : src1[0];
|
||||
dst[1] = src1[1] == src0[0] ? src0[0] : src1[0];
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
dst[0] = src1[0];
|
||||
dst[1] = src1[0];
|
||||
}
|
||||
|
@ -260,24 +328,33 @@ static inline void scale2x_32_def_border(scale2x_uint32* dst, const scale2x_uint
|
|||
}
|
||||
|
||||
/* last pixel */
|
||||
if (src0[0] != src2[0] && src1[-1] != src1[0]) {
|
||||
if (src0[0] != src2[0] && src1[-1] != src1[0])
|
||||
{
|
||||
dst[0] = src1[-1] == src0[0] ? src0[0] : src1[0];
|
||||
dst[1] = src1[0] == src0[0] ? src0[0] : src1[0];
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
dst[0] = src1[0];
|
||||
dst[1] = src1[0];
|
||||
}
|
||||
}
|
||||
|
||||
static inline void scale2x_32_def_center(scale2x_uint32* dst, const scale2x_uint32* src0, const scale2x_uint32* src1, const scale2x_uint32* src2, unsigned count)
|
||||
static inline void scale2x_32_def_center(scale2x_uint32* dst, const scale2x_uint32* src0, const scale2x_uint32* src1,
|
||||
const scale2x_uint32* src2, unsigned count)
|
||||
{
|
||||
assert(count >= 2);
|
||||
|
||||
/* first pixel */
|
||||
if (src0[0] != src2[0] && src1[0] != src1[1]) {
|
||||
if (src0[0] != src2[0] && src1[0] != src1[1])
|
||||
{
|
||||
dst[0] = src1[0];
|
||||
dst[1] = (src1[1] == src0[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src0[1]) ? src1[1] : src1[0];
|
||||
} else {
|
||||
dst[1] = (src1[1] == src0[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src0[1])
|
||||
? src1[1]
|
||||
: src1[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
dst[0] = src1[0];
|
||||
dst[1] = src1[0];
|
||||
}
|
||||
|
@ -288,11 +365,19 @@ static inline void scale2x_32_def_center(scale2x_uint32* dst, const scale2x_uint
|
|||
|
||||
/* central pixels */
|
||||
count -= 2;
|
||||
while (count) {
|
||||
if (src0[0] != src2[0] && src1[-1] != src1[1]) {
|
||||
dst[0] = (src1[-1] == src0[0] && src1[0] != src2[-1]) || (src1[-1] == src2[0] && src1[0] != src0[-1]) ? src1[-1] : src1[0];
|
||||
dst[1] = (src1[1] == src0[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src0[1]) ? src1[1] : src1[0];
|
||||
} else {
|
||||
while (count)
|
||||
{
|
||||
if (src0[0] != src2[0] && src1[-1] != src1[1])
|
||||
{
|
||||
dst[0] = (src1[-1] == src0[0] && src1[0] != src2[-1]) || (src1[-1] == src2[0] && src1[0] != src0[-1])
|
||||
? src1[-1]
|
||||
: src1[0];
|
||||
dst[1] = (src1[1] == src0[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src0[1])
|
||||
? src1[1]
|
||||
: src1[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
dst[0] = src1[0];
|
||||
dst[1] = src1[0];
|
||||
}
|
||||
|
@ -305,10 +390,15 @@ static inline void scale2x_32_def_center(scale2x_uint32* dst, const scale2x_uint
|
|||
}
|
||||
|
||||
/* last pixel */
|
||||
if (src0[0] != src2[0] && src1[-1] != src1[0]) {
|
||||
dst[0] = (src1[-1] == src0[0] && src1[0] != src2[-1]) || (src1[-1] == src2[0] && src1[0] != src0[-1]) ? src1[-1] : src1[0];
|
||||
if (src0[0] != src2[0] && src1[-1] != src1[0])
|
||||
{
|
||||
dst[0] = (src1[-1] == src0[0] && src1[0] != src2[-1]) || (src1[-1] == src2[0] && src1[0] != src0[-1])
|
||||
? src1[-1]
|
||||
: src1[0];
|
||||
dst[1] = src1[0];
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
dst[0] = src1[0];
|
||||
dst[1] = src1[0];
|
||||
}
|
||||
|
@ -329,7 +419,8 @@ static inline void scale2x_32_def_center(scale2x_uint32* dst, const scale2x_uint
|
|||
* \param dst0 First destination row, double length in pixels.
|
||||
* \param dst1 Second destination row, double length in pixels.
|
||||
*/
|
||||
void scale2x_8_def(scale2x_uint8* dst0, scale2x_uint8* dst1, const scale2x_uint8* src0, const scale2x_uint8* src1, const scale2x_uint8* src2, unsigned count)
|
||||
void scale2x_8_def(scale2x_uint8* dst0, scale2x_uint8* dst1, const scale2x_uint8* src0, const scale2x_uint8* src1,
|
||||
const scale2x_uint8* src2, unsigned count)
|
||||
{
|
||||
#ifdef USE_SCALE_RANDOMWRITE
|
||||
scale2x_8_def_whole(dst0, dst1, src0, src1, src2, count);
|
||||
|
@ -350,7 +441,8 @@ void scale2x_8_def(scale2x_uint8* dst0, scale2x_uint8* dst1, const scale2x_uint8
|
|||
* \param dst0 First destination row, double length in pixels.
|
||||
* \param dst1 Second destination row, double length in pixels.
|
||||
*/
|
||||
void scale2x_16_def(scale2x_uint16* dst0, scale2x_uint16* dst1, const scale2x_uint16* src0, const scale2x_uint16* src1, const scale2x_uint16* src2, unsigned count)
|
||||
void scale2x_16_def(scale2x_uint16* dst0, scale2x_uint16* dst1, const scale2x_uint16* src0, const scale2x_uint16* src1,
|
||||
const scale2x_uint16* src2, unsigned count)
|
||||
{
|
||||
#ifdef USE_SCALE_RANDOMWRITE
|
||||
scale2x_16_def_whole(dst0, dst1, src0, src1, src2, count);
|
||||
|
@ -371,7 +463,8 @@ void scale2x_16_def(scale2x_uint16* dst0, scale2x_uint16* dst1, const scale2x_ui
|
|||
* \param dst0 First destination row, double length in pixels.
|
||||
* \param dst1 Second destination row, double length in pixels.
|
||||
*/
|
||||
void scale2x_32_def(scale2x_uint32* dst0, scale2x_uint32* dst1, const scale2x_uint32* src0, const scale2x_uint32* src1, const scale2x_uint32* src2, unsigned count)
|
||||
void scale2x_32_def(scale2x_uint32* dst0, scale2x_uint32* dst1, const scale2x_uint32* src0, const scale2x_uint32* src1,
|
||||
const scale2x_uint32* src2, unsigned count)
|
||||
{
|
||||
#ifdef USE_SCALE_RANDOMWRITE
|
||||
scale2x_32_def_whole(dst0, dst1, src0, src1, src2, count);
|
||||
|
@ -385,7 +478,8 @@ void scale2x_32_def(scale2x_uint32* dst0, scale2x_uint32* dst1, const scale2x_ui
|
|||
* Scale by a factor of 2x3 a row of pixels of 8 bits.
|
||||
* \note Like scale2x_8_def();
|
||||
*/
|
||||
void scale2x3_8_def(scale2x_uint8* dst0, scale2x_uint8* dst1, scale2x_uint8* dst2, const scale2x_uint8* src0, const scale2x_uint8* src1, const scale2x_uint8* src2, unsigned count)
|
||||
void scale2x3_8_def(scale2x_uint8* dst0, scale2x_uint8* dst1, scale2x_uint8* dst2, const scale2x_uint8* src0,
|
||||
const scale2x_uint8* src1, const scale2x_uint8* src2, unsigned count)
|
||||
{
|
||||
#ifdef USE_SCALE_RANDOMWRITE
|
||||
scale2x_8_def_whole(dst0, dst2, src0, src1, src2, count);
|
||||
|
@ -401,7 +495,8 @@ void scale2x3_8_def(scale2x_uint8* dst0, scale2x_uint8* dst1, scale2x_uint8* dst
|
|||
* Scale by a factor of 2x3 a row of pixels of 16 bits.
|
||||
* \note Like scale2x_16_def();
|
||||
*/
|
||||
void scale2x3_16_def(scale2x_uint16* dst0, scale2x_uint16* dst1, scale2x_uint16* dst2, const scale2x_uint16* src0, const scale2x_uint16* src1, const scale2x_uint16* src2, unsigned count)
|
||||
void scale2x3_16_def(scale2x_uint16* dst0, scale2x_uint16* dst1, scale2x_uint16* dst2, const scale2x_uint16* src0,
|
||||
const scale2x_uint16* src1, const scale2x_uint16* src2, unsigned count)
|
||||
{
|
||||
#ifdef USE_SCALE_RANDOMWRITE
|
||||
scale2x_16_def_whole(dst0, dst2, src0, src1, src2, count);
|
||||
|
@ -417,7 +512,8 @@ void scale2x3_16_def(scale2x_uint16* dst0, scale2x_uint16* dst1, scale2x_uint16*
|
|||
* Scale by a factor of 2x3 a row of pixels of 32 bits.
|
||||
* \note Like scale2x_32_def();
|
||||
*/
|
||||
void scale2x3_32_def(scale2x_uint32* dst0, scale2x_uint32* dst1, scale2x_uint32* dst2, const scale2x_uint32* src0, const scale2x_uint32* src1, const scale2x_uint32* src2, unsigned count)
|
||||
void scale2x3_32_def(scale2x_uint32* dst0, scale2x_uint32* dst1, scale2x_uint32* dst2, const scale2x_uint32* src0,
|
||||
const scale2x_uint32* src1, const scale2x_uint32* src2, unsigned count)
|
||||
{
|
||||
#ifdef USE_SCALE_RANDOMWRITE
|
||||
scale2x_32_def_whole(dst0, dst2, src0, src1, src2, count);
|
||||
|
@ -433,7 +529,8 @@ void scale2x3_32_def(scale2x_uint32* dst0, scale2x_uint32* dst1, scale2x_uint32*
|
|||
* Scale by a factor of 2x4 a row of pixels of 8 bits.
|
||||
* \note Like scale2x_8_def();
|
||||
*/
|
||||
void scale2x4_8_def(scale2x_uint8* dst0, scale2x_uint8* dst1, scale2x_uint8* dst2, scale2x_uint8* dst3, const scale2x_uint8* src0, const scale2x_uint8* src1, const scale2x_uint8* src2, unsigned count)
|
||||
void scale2x4_8_def(scale2x_uint8* dst0, scale2x_uint8* dst1, scale2x_uint8* dst2, scale2x_uint8* dst3,
|
||||
const scale2x_uint8* src0, const scale2x_uint8* src1, const scale2x_uint8* src2, unsigned count)
|
||||
{
|
||||
#ifdef USE_SCALE_RANDOMWRITE
|
||||
scale2x_8_def_whole(dst0, dst3, src0, src1, src2, count);
|
||||
|
@ -451,7 +548,8 @@ void scale2x4_8_def(scale2x_uint8* dst0, scale2x_uint8* dst1, scale2x_uint8* dst
|
|||
* Scale by a factor of 2x4 a row of pixels of 16 bits.
|
||||
* \note Like scale2x_16_def();
|
||||
*/
|
||||
void scale2x4_16_def(scale2x_uint16* dst0, scale2x_uint16* dst1, scale2x_uint16* dst2, scale2x_uint16* dst3, const scale2x_uint16* src0, const scale2x_uint16* src1, const scale2x_uint16* src2, unsigned count)
|
||||
void scale2x4_16_def(scale2x_uint16* dst0, scale2x_uint16* dst1, scale2x_uint16* dst2, scale2x_uint16* dst3,
|
||||
const scale2x_uint16* src0, const scale2x_uint16* src1, const scale2x_uint16* src2, unsigned count)
|
||||
{
|
||||
#ifdef USE_SCALE_RANDOMWRITE
|
||||
scale2x_16_def_whole(dst0, dst3, src0, src1, src2, count);
|
||||
|
@ -469,7 +567,8 @@ void scale2x4_16_def(scale2x_uint16* dst0, scale2x_uint16* dst1, scale2x_uint16*
|
|||
* Scale by a factor of 2x4 a row of pixels of 32 bits.
|
||||
* \note Like scale2x_32_def();
|
||||
*/
|
||||
void scale2x4_32_def(scale2x_uint32* dst0, scale2x_uint32* dst1, scale2x_uint32* dst2, scale2x_uint32* dst3, const scale2x_uint32* src0, const scale2x_uint32* src1, const scale2x_uint32* src2, unsigned count)
|
||||
void scale2x4_32_def(scale2x_uint32* dst0, scale2x_uint32* dst1, scale2x_uint32* dst2, scale2x_uint32* dst3,
|
||||
const scale2x_uint32* src0, const scale2x_uint32* src1, const scale2x_uint32* src2, unsigned count)
|
||||
{
|
||||
#ifdef USE_SCALE_RANDOMWRITE
|
||||
scale2x_32_def_whole(dst0, dst3, src0, src1, src2, count);
|
||||
|
|
|
@ -21,17 +21,27 @@ typedef unsigned char scale2x_uint8;
|
|||
typedef unsigned short scale2x_uint16;
|
||||
typedef unsigned scale2x_uint32;
|
||||
|
||||
void scale2x_8_def(scale2x_uint8* dst0, scale2x_uint8* dst1, const scale2x_uint8* src0, const scale2x_uint8* src1, const scale2x_uint8* src2, unsigned count);
|
||||
void scale2x_16_def(scale2x_uint16* dst0, scale2x_uint16* dst1, const scale2x_uint16* src0, const scale2x_uint16* src1, const scale2x_uint16* src2, unsigned count);
|
||||
void scale2x_32_def(scale2x_uint32* dst0, scale2x_uint32* dst1, const scale2x_uint32* src0, const scale2x_uint32* src1, const scale2x_uint32* src2, unsigned count);
|
||||
void scale2x_8_def(scale2x_uint8* dst0, scale2x_uint8* dst1, const scale2x_uint8* src0, const scale2x_uint8* src1,
|
||||
const scale2x_uint8* src2, unsigned count);
|
||||
void scale2x_16_def(scale2x_uint16* dst0, scale2x_uint16* dst1, const scale2x_uint16* src0, const scale2x_uint16* src1,
|
||||
const scale2x_uint16* src2, unsigned count);
|
||||
void scale2x_32_def(scale2x_uint32* dst0, scale2x_uint32* dst1, const scale2x_uint32* src0, const scale2x_uint32* src1,
|
||||
const scale2x_uint32* src2, unsigned count);
|
||||
|
||||
void scale2x3_8_def(scale2x_uint8* dst0, scale2x_uint8* dst1, scale2x_uint8* dst2, const scale2x_uint8* src0, const scale2x_uint8* src1, const scale2x_uint8* src2, unsigned count);
|
||||
void scale2x3_16_def(scale2x_uint16* dst0, scale2x_uint16* dst1, scale2x_uint16* dst2, const scale2x_uint16* src0, const scale2x_uint16* src1, const scale2x_uint16* src2, unsigned count);
|
||||
void scale2x3_32_def(scale2x_uint32* dst0, scale2x_uint32* dst1, scale2x_uint32* dst2, const scale2x_uint32* src0, const scale2x_uint32* src1, const scale2x_uint32* src2, unsigned count);
|
||||
void scale2x3_8_def(scale2x_uint8* dst0, scale2x_uint8* dst1, scale2x_uint8* dst2, const scale2x_uint8* src0,
|
||||
const scale2x_uint8* src1, const scale2x_uint8* src2, unsigned count);
|
||||
void scale2x3_16_def(scale2x_uint16* dst0, scale2x_uint16* dst1, scale2x_uint16* dst2, const scale2x_uint16* src0,
|
||||
const scale2x_uint16* src1, const scale2x_uint16* src2, unsigned count);
|
||||
void scale2x3_32_def(scale2x_uint32* dst0, scale2x_uint32* dst1, scale2x_uint32* dst2, const scale2x_uint32* src0,
|
||||
const scale2x_uint32* src1, const scale2x_uint32* src2, unsigned count);
|
||||
|
||||
void scale2x4_8_def(scale2x_uint8* dst0, scale2x_uint8* dst1, scale2x_uint8* dst2, scale2x_uint8* dst3, const scale2x_uint8* src0, const scale2x_uint8* src1, const scale2x_uint8* src2, unsigned count);
|
||||
void scale2x4_16_def(scale2x_uint16* dst0, scale2x_uint16* dst1, scale2x_uint16* dst2, scale2x_uint16* dst3, const scale2x_uint16* src0, const scale2x_uint16* src1, const scale2x_uint16* src2, unsigned count);
|
||||
void scale2x4_32_def(scale2x_uint32* dst0, scale2x_uint32* dst1, scale2x_uint32* dst2, scale2x_uint32* dst3, const scale2x_uint32* src0, const scale2x_uint32* src1, const scale2x_uint32* src2, unsigned count);
|
||||
void scale2x4_8_def(scale2x_uint8* dst0, scale2x_uint8* dst1, scale2x_uint8* dst2, scale2x_uint8* dst3,
|
||||
const scale2x_uint8* src0, const scale2x_uint8* src1, const scale2x_uint8* src2, unsigned count);
|
||||
void scale2x4_16_def(scale2x_uint16* dst0, scale2x_uint16* dst1, scale2x_uint16* dst2, scale2x_uint16* dst3,
|
||||
const scale2x_uint16* src0, const scale2x_uint16* src1, const scale2x_uint16* src2,
|
||||
unsigned count);
|
||||
void scale2x4_32_def(scale2x_uint32* dst0, scale2x_uint32* dst1, scale2x_uint32* dst2, scale2x_uint32* dst3,
|
||||
const scale2x_uint32* src0, const scale2x_uint32* src1, const scale2x_uint32* src2,
|
||||
unsigned count);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -44,16 +44,22 @@
|
|||
*/
|
||||
/* #define USE_SCALE_RANDOMWRITE */
|
||||
|
||||
static inline void scale3x_8_def_border(scale3x_uint8* dst, const scale3x_uint8* src0, const scale3x_uint8* src1, const scale3x_uint8* src2, unsigned count)
|
||||
static inline void scale3x_8_def_border(scale3x_uint8* dst, const scale3x_uint8* src0, const scale3x_uint8* src1,
|
||||
const scale3x_uint8* src2, unsigned count)
|
||||
{
|
||||
assert(count >= 2);
|
||||
|
||||
/* first pixel */
|
||||
if (src0[0] != src2[0] && src1[0] != src1[1]) {
|
||||
if (src0[0] != src2[0] && src1[0] != src1[1])
|
||||
{
|
||||
dst[0] = src1[0];
|
||||
dst[1] = (src1[0] == src0[0] && src1[0] != src0[1]) || (src1[1] == src0[0] && src1[0] != src0[0]) ? src0[0] : src1[0];
|
||||
dst[1] = (src1[0] == src0[0] && src1[0] != src0[1]) || (src1[1] == src0[0] && src1[0] != src0[0])
|
||||
? src0[0]
|
||||
: src1[0];
|
||||
dst[2] = src1[1] == src0[0] ? src1[1] : src1[0];
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
dst[0] = src1[0];
|
||||
dst[1] = src1[0];
|
||||
dst[2] = src1[0];
|
||||
|
@ -65,12 +71,18 @@ static inline void scale3x_8_def_border(scale3x_uint8* dst, const scale3x_uint8*
|
|||
|
||||
/* central pixels */
|
||||
count -= 2;
|
||||
while (count) {
|
||||
if (src0[0] != src2[0] && src1[-1] != src1[1]) {
|
||||
while (count)
|
||||
{
|
||||
if (src0[0] != src2[0] && src1[-1] != src1[1])
|
||||
{
|
||||
dst[0] = src1[-1] == src0[0] ? src1[-1] : src1[0];
|
||||
dst[1] = (src1[-1] == src0[0] && src1[0] != src0[1]) || (src1[1] == src0[0] && src1[0] != src0[-1]) ? src0[0] : src1[0];
|
||||
dst[1] = (src1[-1] == src0[0] && src1[0] != src0[1]) || (src1[1] == src0[0] && src1[0] != src0[-1])
|
||||
? src0[0]
|
||||
: src1[0];
|
||||
dst[2] = src1[1] == src0[0] ? src1[1] : src1[0];
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
dst[0] = src1[0];
|
||||
dst[1] = src1[0];
|
||||
dst[2] = src1[0];
|
||||
|
@ -84,27 +96,40 @@ static inline void scale3x_8_def_border(scale3x_uint8* dst, const scale3x_uint8*
|
|||
}
|
||||
|
||||
/* last pixel */
|
||||
if (src0[0] != src2[0] && src1[-1] != src1[0]) {
|
||||
if (src0[0] != src2[0] && src1[-1] != src1[0])
|
||||
{
|
||||
dst[0] = src1[-1] == src0[0] ? src1[-1] : src1[0];
|
||||
dst[1] = (src1[-1] == src0[0] && src1[0] != src0[0]) || (src1[0] == src0[0] && src1[0] != src0[-1]) ? src0[0] : src1[0];
|
||||
dst[1] = (src1[-1] == src0[0] && src1[0] != src0[0]) || (src1[0] == src0[0] && src1[0] != src0[-1])
|
||||
? src0[0]
|
||||
: src1[0];
|
||||
dst[2] = src1[0];
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
dst[0] = src1[0];
|
||||
dst[1] = src1[0];
|
||||
dst[2] = src1[0];
|
||||
}
|
||||
}
|
||||
|
||||
static inline void scale3x_8_def_center(scale3x_uint8* dst, const scale3x_uint8* src0, const scale3x_uint8* src1, const scale3x_uint8* src2, unsigned count)
|
||||
static inline void scale3x_8_def_center(scale3x_uint8* dst, const scale3x_uint8* src0, const scale3x_uint8* src1,
|
||||
const scale3x_uint8* src2, unsigned count)
|
||||
{
|
||||
assert(count >= 2);
|
||||
|
||||
/* first pixel */
|
||||
if (src0[0] != src2[0] && src1[0] != src1[1]) {
|
||||
dst[0] = (src1[0] == src0[0] && src1[0] != src2[0]) || (src1[0] == src2[0] && src1[0] != src0[0]) ? src1[0] : src1[0];
|
||||
if (src0[0] != src2[0] && src1[0] != src1[1])
|
||||
{
|
||||
dst[0] = (src1[0] == src0[0] && src1[0] != src2[0]) || (src1[0] == src2[0] && src1[0] != src0[0])
|
||||
? src1[0]
|
||||
: src1[0];
|
||||
dst[1] = src1[0];
|
||||
dst[2] = (src1[1] == src0[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src0[1]) ? src1[1] : src1[0];
|
||||
} else {
|
||||
dst[2] = (src1[1] == src0[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src0[1])
|
||||
? src1[1]
|
||||
: src1[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
dst[0] = src1[0];
|
||||
dst[1] = src1[0];
|
||||
dst[2] = src1[0];
|
||||
|
@ -116,12 +141,20 @@ static inline void scale3x_8_def_center(scale3x_uint8* dst, const scale3x_uint8*
|
|||
|
||||
/* central pixels */
|
||||
count -= 2;
|
||||
while (count) {
|
||||
if (src0[0] != src2[0] && src1[-1] != src1[1]) {
|
||||
dst[0] = (src1[-1] == src0[0] && src1[0] != src2[-1]) || (src1[-1] == src2[0] && src1[0] != src0[-1]) ? src1[-1] : src1[0];
|
||||
while (count)
|
||||
{
|
||||
if (src0[0] != src2[0] && src1[-1] != src1[1])
|
||||
{
|
||||
dst[0] = (src1[-1] == src0[0] && src1[0] != src2[-1]) || (src1[-1] == src2[0] && src1[0] != src0[-1])
|
||||
? src1[-1]
|
||||
: src1[0];
|
||||
dst[1] = src1[0];
|
||||
dst[2] = (src1[1] == src0[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src0[1]) ? src1[1] : src1[0];
|
||||
} else {
|
||||
dst[2] = (src1[1] == src0[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src0[1])
|
||||
? src1[1]
|
||||
: src1[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
dst[0] = src1[0];
|
||||
dst[1] = src1[0];
|
||||
dst[2] = src1[0];
|
||||
|
@ -135,27 +168,40 @@ static inline void scale3x_8_def_center(scale3x_uint8* dst, const scale3x_uint8*
|
|||
}
|
||||
|
||||
/* last pixel */
|
||||
if (src0[0] != src2[0] && src1[-1] != src1[0]) {
|
||||
dst[0] = (src1[-1] == src0[0] && src1[0] != src2[-1]) || (src1[-1] == src2[0] && src1[0] != src0[-1]) ? src1[-1] : src1[0];
|
||||
if (src0[0] != src2[0] && src1[-1] != src1[0])
|
||||
{
|
||||
dst[0] = (src1[-1] == src0[0] && src1[0] != src2[-1]) || (src1[-1] == src2[0] && src1[0] != src0[-1])
|
||||
? src1[-1]
|
||||
: src1[0];
|
||||
dst[1] = src1[0];
|
||||
dst[2] = (src1[0] == src0[0] && src1[0] != src2[0]) || (src1[0] == src2[0] && src1[0] != src0[0]) ? src1[0] : src1[0];
|
||||
} else {
|
||||
dst[2] = (src1[0] == src0[0] && src1[0] != src2[0]) || (src1[0] == src2[0] && src1[0] != src0[0])
|
||||
? src1[0]
|
||||
: src1[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
dst[0] = src1[0];
|
||||
dst[1] = src1[0];
|
||||
dst[2] = src1[0];
|
||||
}
|
||||
}
|
||||
|
||||
static inline void scale3x_16_def_border(scale3x_uint16* dst, const scale3x_uint16* src0, const scale3x_uint16* src1, const scale3x_uint16* src2, unsigned count)
|
||||
static inline void scale3x_16_def_border(scale3x_uint16* dst, const scale3x_uint16* src0, const scale3x_uint16* src1,
|
||||
const scale3x_uint16* src2, unsigned count)
|
||||
{
|
||||
assert(count >= 2);
|
||||
|
||||
/* first pixel */
|
||||
if (src0[0] != src2[0] && src1[0] != src1[1]) {
|
||||
if (src0[0] != src2[0] && src1[0] != src1[1])
|
||||
{
|
||||
dst[0] = src1[0];
|
||||
dst[1] = (src1[0] == src0[0] && src1[0] != src0[1]) || (src1[1] == src0[0] && src1[0] != src0[0]) ? src0[0] : src1[0];
|
||||
dst[1] = (src1[0] == src0[0] && src1[0] != src0[1]) || (src1[1] == src0[0] && src1[0] != src0[0])
|
||||
? src0[0]
|
||||
: src1[0];
|
||||
dst[2] = src1[1] == src0[0] ? src1[1] : src1[0];
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
dst[0] = src1[0];
|
||||
dst[1] = src1[0];
|
||||
dst[2] = src1[0];
|
||||
|
@ -167,12 +213,18 @@ static inline void scale3x_16_def_border(scale3x_uint16* dst, const scale3x_uint
|
|||
|
||||
/* central pixels */
|
||||
count -= 2;
|
||||
while (count) {
|
||||
if (src0[0] != src2[0] && src1[-1] != src1[1]) {
|
||||
while (count)
|
||||
{
|
||||
if (src0[0] != src2[0] && src1[-1] != src1[1])
|
||||
{
|
||||
dst[0] = src1[-1] == src0[0] ? src1[-1] : src1[0];
|
||||
dst[1] = (src1[-1] == src0[0] && src1[0] != src0[1]) || (src1[1] == src0[0] && src1[0] != src0[-1]) ? src0[0] : src1[0];
|
||||
dst[1] = (src1[-1] == src0[0] && src1[0] != src0[1]) || (src1[1] == src0[0] && src1[0] != src0[-1])
|
||||
? src0[0]
|
||||
: src1[0];
|
||||
dst[2] = src1[1] == src0[0] ? src1[1] : src1[0];
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
dst[0] = src1[0];
|
||||
dst[1] = src1[0];
|
||||
dst[2] = src1[0];
|
||||
|
@ -186,27 +238,40 @@ static inline void scale3x_16_def_border(scale3x_uint16* dst, const scale3x_uint
|
|||
}
|
||||
|
||||
/* last pixel */
|
||||
if (src0[0] != src2[0] && src1[-1] != src1[0]) {
|
||||
if (src0[0] != src2[0] && src1[-1] != src1[0])
|
||||
{
|
||||
dst[0] = src1[-1] == src0[0] ? src1[-1] : src1[0];
|
||||
dst[1] = (src1[-1] == src0[0] && src1[0] != src0[0]) || (src1[0] == src0[0] && src1[0] != src0[-1]) ? src0[0] : src1[0];
|
||||
dst[1] = (src1[-1] == src0[0] && src1[0] != src0[0]) || (src1[0] == src0[0] && src1[0] != src0[-1])
|
||||
? src0[0]
|
||||
: src1[0];
|
||||
dst[2] = src1[0];
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
dst[0] = src1[0];
|
||||
dst[1] = src1[0];
|
||||
dst[2] = src1[0];
|
||||
}
|
||||
}
|
||||
|
||||
static inline void scale3x_16_def_center(scale3x_uint16* dst, const scale3x_uint16* src0, const scale3x_uint16* src1, const scale3x_uint16* src2, unsigned count)
|
||||
static inline void scale3x_16_def_center(scale3x_uint16* dst, const scale3x_uint16* src0, const scale3x_uint16* src1,
|
||||
const scale3x_uint16* src2, unsigned count)
|
||||
{
|
||||
assert(count >= 2);
|
||||
|
||||
/* first pixel */
|
||||
if (src0[0] != src2[0] && src1[0] != src1[1]) {
|
||||
dst[0] = (src1[0] == src0[0] && src1[0] != src2[0]) || (src1[0] == src2[0] && src1[0] != src0[0]) ? src1[0] : src1[0];
|
||||
if (src0[0] != src2[0] && src1[0] != src1[1])
|
||||
{
|
||||
dst[0] = (src1[0] == src0[0] && src1[0] != src2[0]) || (src1[0] == src2[0] && src1[0] != src0[0])
|
||||
? src1[0]
|
||||
: src1[0];
|
||||
dst[1] = src1[0];
|
||||
dst[2] = (src1[1] == src0[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src0[1]) ? src1[1] : src1[0];
|
||||
} else {
|
||||
dst[2] = (src1[1] == src0[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src0[1])
|
||||
? src1[1]
|
||||
: src1[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
dst[0] = src1[0];
|
||||
dst[1] = src1[0];
|
||||
dst[2] = src1[0];
|
||||
|
@ -218,12 +283,20 @@ static inline void scale3x_16_def_center(scale3x_uint16* dst, const scale3x_uint
|
|||
|
||||
/* central pixels */
|
||||
count -= 2;
|
||||
while (count) {
|
||||
if (src0[0] != src2[0] && src1[-1] != src1[1]) {
|
||||
dst[0] = (src1[-1] == src0[0] && src1[0] != src2[-1]) || (src1[-1] == src2[0] && src1[0] != src0[-1]) ? src1[-1] : src1[0];
|
||||
while (count)
|
||||
{
|
||||
if (src0[0] != src2[0] && src1[-1] != src1[1])
|
||||
{
|
||||
dst[0] = (src1[-1] == src0[0] && src1[0] != src2[-1]) || (src1[-1] == src2[0] && src1[0] != src0[-1])
|
||||
? src1[-1]
|
||||
: src1[0];
|
||||
dst[1] = src1[0];
|
||||
dst[2] = (src1[1] == src0[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src0[1]) ? src1[1] : src1[0];
|
||||
} else {
|
||||
dst[2] = (src1[1] == src0[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src0[1])
|
||||
? src1[1]
|
||||
: src1[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
dst[0] = src1[0];
|
||||
dst[1] = src1[0];
|
||||
dst[2] = src1[0];
|
||||
|
@ -237,27 +310,40 @@ static inline void scale3x_16_def_center(scale3x_uint16* dst, const scale3x_uint
|
|||
}
|
||||
|
||||
/* last pixel */
|
||||
if (src0[0] != src2[0] && src1[-1] != src1[0]) {
|
||||
dst[0] = (src1[-1] == src0[0] && src1[0] != src2[-1]) || (src1[-1] == src2[0] && src1[0] != src0[-1]) ? src1[-1] : src1[0];
|
||||
if (src0[0] != src2[0] && src1[-1] != src1[0])
|
||||
{
|
||||
dst[0] = (src1[-1] == src0[0] && src1[0] != src2[-1]) || (src1[-1] == src2[0] && src1[0] != src0[-1])
|
||||
? src1[-1]
|
||||
: src1[0];
|
||||
dst[1] = src1[0];
|
||||
dst[2] = (src1[0] == src0[0] && src1[0] != src2[0]) || (src1[0] == src2[0] && src1[0] != src0[0]) ? src1[0] : src1[0];
|
||||
} else {
|
||||
dst[2] = (src1[0] == src0[0] && src1[0] != src2[0]) || (src1[0] == src2[0] && src1[0] != src0[0])
|
||||
? src1[0]
|
||||
: src1[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
dst[0] = src1[0];
|
||||
dst[1] = src1[0];
|
||||
dst[2] = src1[0];
|
||||
}
|
||||
}
|
||||
|
||||
static inline void scale3x_32_def_border(scale3x_uint32* dst, const scale3x_uint32* src0, const scale3x_uint32* src1, const scale3x_uint32* src2, unsigned count)
|
||||
static inline void scale3x_32_def_border(scale3x_uint32* dst, const scale3x_uint32* src0, const scale3x_uint32* src1,
|
||||
const scale3x_uint32* src2, unsigned count)
|
||||
{
|
||||
assert(count >= 2);
|
||||
|
||||
/* first pixel */
|
||||
if (src0[0] != src2[0] && src1[0] != src1[1]) {
|
||||
if (src0[0] != src2[0] && src1[0] != src1[1])
|
||||
{
|
||||
dst[0] = src1[0];
|
||||
dst[1] = (src1[0] == src0[0] && src1[0] != src0[1]) || (src1[1] == src0[0] && src1[0] != src0[0]) ? src0[0] : src1[0];
|
||||
dst[1] = (src1[0] == src0[0] && src1[0] != src0[1]) || (src1[1] == src0[0] && src1[0] != src0[0])
|
||||
? src0[0]
|
||||
: src1[0];
|
||||
dst[2] = src1[1] == src0[0] ? src1[1] : src1[0];
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
dst[0] = src1[0];
|
||||
dst[1] = src1[0];
|
||||
dst[2] = src1[0];
|
||||
|
@ -269,12 +355,18 @@ static inline void scale3x_32_def_border(scale3x_uint32* dst, const scale3x_uint
|
|||
|
||||
/* central pixels */
|
||||
count -= 2;
|
||||
while (count) {
|
||||
if (src0[0] != src2[0] && src1[-1] != src1[1]) {
|
||||
while (count)
|
||||
{
|
||||
if (src0[0] != src2[0] && src1[-1] != src1[1])
|
||||
{
|
||||
dst[0] = src1[-1] == src0[0] ? src1[-1] : src1[0];
|
||||
dst[1] = (src1[-1] == src0[0] && src1[0] != src0[1]) || (src1[1] == src0[0] && src1[0] != src0[-1]) ? src0[0] : src1[0];
|
||||
dst[1] = (src1[-1] == src0[0] && src1[0] != src0[1]) || (src1[1] == src0[0] && src1[0] != src0[-1])
|
||||
? src0[0]
|
||||
: src1[0];
|
||||
dst[2] = src1[1] == src0[0] ? src1[1] : src1[0];
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
dst[0] = src1[0];
|
||||
dst[1] = src1[0];
|
||||
dst[2] = src1[0];
|
||||
|
@ -288,27 +380,40 @@ static inline void scale3x_32_def_border(scale3x_uint32* dst, const scale3x_uint
|
|||
}
|
||||
|
||||
/* last pixel */
|
||||
if (src0[0] != src2[0] && src1[-1] != src1[0]) {
|
||||
if (src0[0] != src2[0] && src1[-1] != src1[0])
|
||||
{
|
||||
dst[0] = src1[-1] == src0[0] ? src1[-1] : src1[0];
|
||||
dst[1] = (src1[-1] == src0[0] && src1[0] != src0[0]) || (src1[0] == src0[0] && src1[0] != src0[-1]) ? src0[0] : src1[0];
|
||||
dst[1] = (src1[-1] == src0[0] && src1[0] != src0[0]) || (src1[0] == src0[0] && src1[0] != src0[-1])
|
||||
? src0[0]
|
||||
: src1[0];
|
||||
dst[2] = src1[0];
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
dst[0] = src1[0];
|
||||
dst[1] = src1[0];
|
||||
dst[2] = src1[0];
|
||||
}
|
||||
}
|
||||
|
||||
static inline void scale3x_32_def_center(scale3x_uint32* dst, const scale3x_uint32* src0, const scale3x_uint32* src1, const scale3x_uint32* src2, unsigned count)
|
||||
static inline void scale3x_32_def_center(scale3x_uint32* dst, const scale3x_uint32* src0, const scale3x_uint32* src1,
|
||||
const scale3x_uint32* src2, unsigned count)
|
||||
{
|
||||
assert(count >= 2);
|
||||
|
||||
/* first pixel */
|
||||
if (src0[0] != src2[0] && src1[0] != src1[1]) {
|
||||
dst[0] = (src1[0] == src0[0] && src1[0] != src2[0]) || (src1[0] == src2[0] && src1[0] != src0[0]) ? src1[0] : src1[0];
|
||||
if (src0[0] != src2[0] && src1[0] != src1[1])
|
||||
{
|
||||
dst[0] = (src1[0] == src0[0] && src1[0] != src2[0]) || (src1[0] == src2[0] && src1[0] != src0[0])
|
||||
? src1[0]
|
||||
: src1[0];
|
||||
dst[1] = src1[0];
|
||||
dst[2] = (src1[1] == src0[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src0[1]) ? src1[1] : src1[0];
|
||||
} else {
|
||||
dst[2] = (src1[1] == src0[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src0[1])
|
||||
? src1[1]
|
||||
: src1[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
dst[0] = src1[0];
|
||||
dst[1] = src1[0];
|
||||
dst[2] = src1[0];
|
||||
|
@ -320,12 +425,20 @@ static inline void scale3x_32_def_center(scale3x_uint32* dst, const scale3x_uint
|
|||
|
||||
/* central pixels */
|
||||
count -= 2;
|
||||
while (count) {
|
||||
if (src0[0] != src2[0] && src1[-1] != src1[1]) {
|
||||
dst[0] = (src1[-1] == src0[0] && src1[0] != src2[-1]) || (src1[-1] == src2[0] && src1[0] != src0[-1]) ? src1[-1] : src1[0];
|
||||
while (count)
|
||||
{
|
||||
if (src0[0] != src2[0] && src1[-1] != src1[1])
|
||||
{
|
||||
dst[0] = (src1[-1] == src0[0] && src1[0] != src2[-1]) || (src1[-1] == src2[0] && src1[0] != src0[-1])
|
||||
? src1[-1]
|
||||
: src1[0];
|
||||
dst[1] = src1[0];
|
||||
dst[2] = (src1[1] == src0[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src0[1]) ? src1[1] : src1[0];
|
||||
} else {
|
||||
dst[2] = (src1[1] == src0[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src0[1])
|
||||
? src1[1]
|
||||
: src1[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
dst[0] = src1[0];
|
||||
dst[1] = src1[0];
|
||||
dst[2] = src1[0];
|
||||
|
@ -339,11 +452,18 @@ static inline void scale3x_32_def_center(scale3x_uint32* dst, const scale3x_uint
|
|||
}
|
||||
|
||||
/* last pixel */
|
||||
if (src0[0] != src2[0] && src1[-1] != src1[0]) {
|
||||
dst[0] = (src1[-1] == src0[0] && src1[0] != src2[-1]) || (src1[-1] == src2[0] && src1[0] != src0[-1]) ? src1[-1] : src1[0];
|
||||
if (src0[0] != src2[0] && src1[-1] != src1[0])
|
||||
{
|
||||
dst[0] = (src1[-1] == src0[0] && src1[0] != src2[-1]) || (src1[-1] == src2[0] && src1[0] != src0[-1])
|
||||
? src1[-1]
|
||||
: src1[0];
|
||||
dst[1] = src1[0];
|
||||
dst[2] = (src1[0] == src0[0] && src1[0] != src2[0]) || (src1[0] == src2[0] && src1[0] != src0[0]) ? src1[0] : src1[0];
|
||||
} else {
|
||||
dst[2] = (src1[0] == src0[0] && src1[0] != src2[0]) || (src1[0] == src2[0] && src1[0] != src0[0])
|
||||
? src1[0]
|
||||
: src1[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
dst[0] = src1[0];
|
||||
dst[1] = src1[0];
|
||||
dst[2] = src1[0];
|
||||
|
@ -364,7 +484,8 @@ static inline void scale3x_32_def_center(scale3x_uint32* dst, const scale3x_uint
|
|||
* \param dst1 Second destination row, triple length in pixels.
|
||||
* \param dst2 Third destination row, triple length in pixels.
|
||||
*/
|
||||
void scale3x_8_def(scale3x_uint8* dst0, scale3x_uint8* dst1, scale3x_uint8* dst2, const scale3x_uint8* src0, const scale3x_uint8* src1, const scale3x_uint8* src2, unsigned count)
|
||||
void scale3x_8_def(scale3x_uint8* dst0, scale3x_uint8* dst1, scale3x_uint8* dst2, const scale3x_uint8* src0,
|
||||
const scale3x_uint8* src1, const scale3x_uint8* src2, unsigned count)
|
||||
{
|
||||
#ifdef USE_SCALE_RANDOMWRITE
|
||||
scale3x_8_def_whole(dst0, dst1, dst2, src0, src1, src2, count);
|
||||
|
@ -387,7 +508,8 @@ void scale3x_8_def(scale3x_uint8* dst0, scale3x_uint8* dst1, scale3x_uint8* dst2
|
|||
* \param dst1 Second destination row, triple length in pixels.
|
||||
* \param dst2 Third destination row, triple length in pixels.
|
||||
*/
|
||||
void scale3x_16_def(scale3x_uint16* dst0, scale3x_uint16* dst1, scale3x_uint16* dst2, const scale3x_uint16* src0, const scale3x_uint16* src1, const scale3x_uint16* src2, unsigned count)
|
||||
void scale3x_16_def(scale3x_uint16* dst0, scale3x_uint16* dst1, scale3x_uint16* dst2, const scale3x_uint16* src0,
|
||||
const scale3x_uint16* src1, const scale3x_uint16* src2, unsigned count)
|
||||
{
|
||||
#ifdef USE_SCALE_RANDOMWRITE
|
||||
scale3x_16_def_whole(dst0, dst1, dst2, src0, src1, src2, count);
|
||||
|
@ -410,7 +532,8 @@ void scale3x_16_def(scale3x_uint16* dst0, scale3x_uint16* dst1, scale3x_uint16*
|
|||
* \param dst1 Second destination row, triple length in pixels.
|
||||
* \param dst2 Third destination row, triple length in pixels.
|
||||
*/
|
||||
void scale3x_32_def(scale3x_uint32* dst0, scale3x_uint32* dst1, scale3x_uint32* dst2, const scale3x_uint32* src0, const scale3x_uint32* src1, const scale3x_uint32* src2, unsigned count)
|
||||
void scale3x_32_def(scale3x_uint32* dst0, scale3x_uint32* dst1, scale3x_uint32* dst2, const scale3x_uint32* src0,
|
||||
const scale3x_uint32* src1, const scale3x_uint32* src2, unsigned count)
|
||||
{
|
||||
#ifdef USE_SCALE_RANDOMWRITE
|
||||
scale3x_32_def_whole(dst0, dst1, dst2, src0, src1, src2, count);
|
||||
|
@ -420,4 +543,3 @@ void scale3x_32_def(scale3x_uint32* dst0, scale3x_uint32* dst1, scale3x_uint32*
|
|||
scale3x_32_def_border(dst2, src2, src1, src0, count);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -21,9 +21,11 @@ typedef unsigned char scale3x_uint8;
|
|||
typedef unsigned short scale3x_uint16;
|
||||
typedef unsigned scale3x_uint32;
|
||||
|
||||
void scale3x_8_def(scale3x_uint8* dst0, scale3x_uint8* dst1, scale3x_uint8* dst2, const scale3x_uint8* src0, const scale3x_uint8* src1, const scale3x_uint8* src2, unsigned count);
|
||||
void scale3x_16_def(scale3x_uint16* dst0, scale3x_uint16* dst1, scale3x_uint16* dst2, const scale3x_uint16* src0, const scale3x_uint16* src1, const scale3x_uint16* src2, unsigned count);
|
||||
void scale3x_32_def(scale3x_uint32* dst0, scale3x_uint32* dst1, scale3x_uint32* dst2, const scale3x_uint32* src0, const scale3x_uint32* src1, const scale3x_uint32* src2, unsigned count);
|
||||
void scale3x_8_def(scale3x_uint8* dst0, scale3x_uint8* dst1, scale3x_uint8* dst2, const scale3x_uint8* src0,
|
||||
const scale3x_uint8* src1, const scale3x_uint8* src2, unsigned count);
|
||||
void scale3x_16_def(scale3x_uint16* dst0, scale3x_uint16* dst1, scale3x_uint16* dst2, const scale3x_uint16* src0,
|
||||
const scale3x_uint16* src1, const scale3x_uint16* src2, unsigned count);
|
||||
void scale3x_32_def(scale3x_uint32* dst0, scale3x_uint32* dst1, scale3x_uint32* dst2, const scale3x_uint32* src0,
|
||||
const scale3x_uint32* src1, const scale3x_uint32* src2, unsigned count);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -49,55 +49,83 @@
|
|||
/**
|
||||
* Apply the Scale2x effect on a group of rows. Used internally.
|
||||
*/
|
||||
static inline void stage_scale2x(void* dst0, void* dst1, const void* src0, const void* src1, const void* src2, unsigned pixel, unsigned pixel_per_row)
|
||||
static inline void stage_scale2x(void* dst0, void* dst1, const void* src0, const void* src1, const void* src2,
|
||||
unsigned pixel, unsigned pixel_per_row)
|
||||
{
|
||||
switch (pixel) {
|
||||
case 1 : scale2x_8_def(SSDST(8,0), SSDST(8,1), SSSRC(8,0), SSSRC(8,1), SSSRC(8,2), pixel_per_row); break;
|
||||
case 2 : scale2x_16_def(SSDST(16,0), SSDST(16,1), SSSRC(16,0), SSSRC(16,1), SSSRC(16,2), pixel_per_row); break;
|
||||
case 4 : scale2x_32_def(SSDST(32,0), SSDST(32,1), SSSRC(32,0), SSSRC(32,1), SSSRC(32,2), pixel_per_row); break;
|
||||
switch (pixel)
|
||||
{
|
||||
case 1: scale2x_8_def(SSDST(8, 0), SSDST(8, 1), SSSRC(8, 0), SSSRC(8, 1), SSSRC(8, 2), pixel_per_row);
|
||||
break;
|
||||
case 2: scale2x_16_def(SSDST(16, 0), SSDST(16, 1), SSSRC(16, 0), SSSRC(16, 1), SSSRC(16, 2), pixel_per_row);
|
||||
break;
|
||||
case 4: scale2x_32_def(SSDST(32, 0), SSDST(32, 1), SSSRC(32, 0), SSSRC(32, 1), SSSRC(32, 2), pixel_per_row);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the Scale2x3 effect on a group of rows. Used internally.
|
||||
*/
|
||||
static inline void stage_scale2x3(void* dst0, void* dst1, void* dst2, const void* src0, const void* src1, const void* src2, unsigned pixel, unsigned pixel_per_row)
|
||||
static inline void stage_scale2x3(void* dst0, void* dst1, void* dst2, const void* src0, const void* src1,
|
||||
const void* src2, unsigned pixel, unsigned pixel_per_row)
|
||||
{
|
||||
switch (pixel) {
|
||||
case 1 : scale2x3_8_def(SSDST(8,0), SSDST(8,1), SSDST(8,2), SSSRC(8,0), SSSRC(8,1), SSSRC(8,2), pixel_per_row); break;
|
||||
case 2 : scale2x3_16_def(SSDST(16,0), SSDST(16,1), SSDST(16,2), SSSRC(16,0), SSSRC(16,1), SSSRC(16,2), pixel_per_row); break;
|
||||
case 4 : scale2x3_32_def(SSDST(32,0), SSDST(32,1), SSDST(32,2), SSSRC(32,0), SSSRC(32,1), SSSRC(32,2), pixel_per_row); break;
|
||||
switch (pixel)
|
||||
{
|
||||
case 1: scale2x3_8_def(SSDST(8, 0), SSDST(8, 1), SSDST(8, 2), SSSRC(8, 0), SSSRC(8, 1), SSSRC(8, 2), pixel_per_row);
|
||||
break;
|
||||
case 2: scale2x3_16_def(SSDST(16, 0), SSDST(16, 1), SSDST(16, 2), SSSRC(16, 0), SSSRC(16, 1), SSSRC(16, 2),
|
||||
pixel_per_row);
|
||||
break;
|
||||
case 4: scale2x3_32_def(SSDST(32, 0), SSDST(32, 1), SSDST(32, 2), SSSRC(32, 0), SSSRC(32, 1), SSSRC(32, 2),
|
||||
pixel_per_row);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the Scale2x4 effect on a group of rows. Used internally.
|
||||
*/
|
||||
static inline void stage_scale2x4(void* dst0, void* dst1, void* dst2, void* dst3, const void* src0, const void* src1, const void* src2, unsigned pixel, unsigned pixel_per_row)
|
||||
static inline void stage_scale2x4(void* dst0, void* dst1, void* dst2, void* dst3, const void* src0, const void* src1,
|
||||
const void* src2, unsigned pixel, unsigned pixel_per_row)
|
||||
{
|
||||
switch (pixel) {
|
||||
case 1 : scale2x4_8_def(SSDST(8,0), SSDST(8,1), SSDST(8,2), SSDST(8,3), SSSRC(8,0), SSSRC(8,1), SSSRC(8,2), pixel_per_row); break;
|
||||
case 2 : scale2x4_16_def(SSDST(16,0), SSDST(16,1), SSDST(16,2), SSDST(16,3), SSSRC(16,0), SSSRC(16,1), SSSRC(16,2), pixel_per_row); break;
|
||||
case 4 : scale2x4_32_def(SSDST(32,0), SSDST(32,1), SSDST(32,2), SSDST(32,3), SSSRC(32,0), SSSRC(32,1), SSSRC(32,2), pixel_per_row); break;
|
||||
switch (pixel)
|
||||
{
|
||||
case 1: scale2x4_8_def(SSDST(8, 0), SSDST(8, 1), SSDST(8, 2), SSDST(8, 3), SSSRC(8, 0), SSSRC(8, 1), SSSRC(8, 2),
|
||||
pixel_per_row);
|
||||
break;
|
||||
case 2: scale2x4_16_def(SSDST(16, 0), SSDST(16, 1), SSDST(16, 2), SSDST(16, 3), SSSRC(16, 0), SSSRC(16, 1),
|
||||
SSSRC(16, 2), pixel_per_row);
|
||||
break;
|
||||
case 4: scale2x4_32_def(SSDST(32, 0), SSDST(32, 1), SSDST(32, 2), SSDST(32, 3), SSSRC(32, 0), SSSRC(32, 1),
|
||||
SSSRC(32, 2), pixel_per_row);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the Scale3x effect on a group of rows. Used internally.
|
||||
*/
|
||||
static inline void stage_scale3x(void* dst0, void* dst1, void* dst2, const void* src0, const void* src1, const void* src2, unsigned pixel, unsigned pixel_per_row)
|
||||
static inline void stage_scale3x(void* dst0, void* dst1, void* dst2, const void* src0, const void* src1,
|
||||
const void* src2, unsigned pixel, unsigned pixel_per_row)
|
||||
{
|
||||
switch (pixel) {
|
||||
case 1 : scale3x_8_def(SSDST(8,0), SSDST(8,1), SSDST(8,2), SSSRC(8,0), SSSRC(8,1), SSSRC(8,2), pixel_per_row); break;
|
||||
case 2 : scale3x_16_def(SSDST(16,0), SSDST(16,1), SSDST(16,2), SSSRC(16,0), SSSRC(16,1), SSSRC(16,2), pixel_per_row); break;
|
||||
case 4 : scale3x_32_def(SSDST(32,0), SSDST(32,1), SSDST(32,2), SSSRC(32,0), SSSRC(32,1), SSSRC(32,2), pixel_per_row); break;
|
||||
switch (pixel)
|
||||
{
|
||||
case 1: scale3x_8_def(SSDST(8, 0), SSDST(8, 1), SSDST(8, 2), SSSRC(8, 0), SSSRC(8, 1), SSSRC(8, 2), pixel_per_row);
|
||||
break;
|
||||
case 2: scale3x_16_def(SSDST(16, 0), SSDST(16, 1), SSDST(16, 2), SSSRC(16, 0), SSSRC(16, 1), SSSRC(16, 2),
|
||||
pixel_per_row);
|
||||
break;
|
||||
case 4: scale3x_32_def(SSDST(32, 0), SSDST(32, 1), SSDST(32, 2), SSSRC(32, 0), SSSRC(32, 1), SSSRC(32, 2),
|
||||
pixel_per_row);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the Scale4x effect on a group of rows. Used internally.
|
||||
*/
|
||||
static inline void stage_scale4x(void* dst0, void* dst1, void* dst2, void* dst3, const void* src0, const void* src1, const void* src2, const void* src3, unsigned pixel, unsigned pixel_per_row)
|
||||
static inline void stage_scale4x(void* dst0, void* dst1, void* dst2, void* dst3, const void* src0, const void* src1,
|
||||
const void* src2, const void* src3, unsigned pixel, unsigned pixel_per_row)
|
||||
{
|
||||
stage_scale2x(dst0, dst1, src0, src1, src2, pixel, 2 * pixel_per_row);
|
||||
stage_scale2x(dst2, dst3, src1, src2, src3, pixel, 2 * pixel_per_row);
|
||||
|
@ -121,7 +149,8 @@ static inline void stage_scale4x(void* dst0, void* dst1, void* dst2, void* dst3,
|
|||
* \param width Horizontal size in pixels of the source bitmap.
|
||||
* \param height Vertical size in pixels of the source bitmap.
|
||||
*/
|
||||
static void scale2x(void* void_dst, unsigned dst_slice, const void* void_src, unsigned src_slice, unsigned pixel, unsigned width, unsigned height)
|
||||
static void scale2x(void* void_dst, unsigned dst_slice, const void* void_src, unsigned src_slice, unsigned pixel,
|
||||
unsigned width, unsigned height)
|
||||
{
|
||||
unsigned char* dst = (unsigned char*)void_dst;
|
||||
const unsigned char* src = (const unsigned char*)void_src;
|
||||
|
@ -136,7 +165,8 @@ static void scale2x(void* void_dst, unsigned dst_slice, const void* void_src, un
|
|||
dst = SCDST(2);
|
||||
|
||||
count -= 2;
|
||||
while (count) {
|
||||
while (count)
|
||||
{
|
||||
stage_scale2x(SCDST(0), SCDST(1), SCSRC(0), SCSRC(1), SCSRC(2), pixel, width);
|
||||
|
||||
dst = SCDST(2);
|
||||
|
@ -162,7 +192,8 @@ static void scale2x(void* void_dst, unsigned dst_slice, const void* void_src, un
|
|||
* \param width Horizontal size in pixels of the source bitmap.
|
||||
* \param height Vertical size in pixels of the source bitmap.
|
||||
*/
|
||||
static void scale2x3(void* void_dst, unsigned dst_slice, const void* void_src, unsigned src_slice, unsigned pixel, unsigned width, unsigned height)
|
||||
static void scale2x3(void* void_dst, unsigned dst_slice, const void* void_src, unsigned src_slice, unsigned pixel,
|
||||
unsigned width, unsigned height)
|
||||
{
|
||||
unsigned char* dst = (unsigned char*)void_dst;
|
||||
const unsigned char* src = (const unsigned char*)void_src;
|
||||
|
@ -177,7 +208,8 @@ static void scale2x3(void* void_dst, unsigned dst_slice, const void* void_src, u
|
|||
dst = SCDST(3);
|
||||
|
||||
count -= 2;
|
||||
while (count) {
|
||||
while (count)
|
||||
{
|
||||
stage_scale2x3(SCDST(0), SCDST(1), SCDST(2), SCSRC(0), SCSRC(1), SCSRC(2), pixel, width);
|
||||
|
||||
dst = SCDST(3);
|
||||
|
@ -203,7 +235,8 @@ static void scale2x3(void* void_dst, unsigned dst_slice, const void* void_src, u
|
|||
* \param width Horizontal size in pixels of the source bitmap.
|
||||
* \param height Vertical size in pixels of the source bitmap.
|
||||
*/
|
||||
static void scale2x4(void* void_dst, unsigned dst_slice, const void* void_src, unsigned src_slice, unsigned pixel, unsigned width, unsigned height)
|
||||
static void scale2x4(void* void_dst, unsigned dst_slice, const void* void_src, unsigned src_slice, unsigned pixel,
|
||||
unsigned width, unsigned height)
|
||||
{
|
||||
unsigned char* dst = (unsigned char*)void_dst;
|
||||
const unsigned char* src = (const unsigned char*)void_src;
|
||||
|
@ -218,7 +251,8 @@ static void scale2x4(void* void_dst, unsigned dst_slice, const void* void_src, u
|
|||
dst = SCDST(4);
|
||||
|
||||
count -= 2;
|
||||
while (count) {
|
||||
while (count)
|
||||
{
|
||||
stage_scale2x4(SCDST(0), SCDST(1), SCDST(2), SCDST(3), SCSRC(0), SCSRC(1), SCSRC(2), pixel, width);
|
||||
|
||||
dst = SCDST(4);
|
||||
|
@ -244,7 +278,8 @@ static void scale2x4(void* void_dst, unsigned dst_slice, const void* void_src, u
|
|||
* \param width Horizontal size in pixels of the source bitmap.
|
||||
* \param height Vertical size in pixels of the source bitmap.
|
||||
*/
|
||||
static void scale3x(void* void_dst, unsigned dst_slice, const void* void_src, unsigned src_slice, unsigned pixel, unsigned width, unsigned height)
|
||||
static void scale3x(void* void_dst, unsigned dst_slice, const void* void_src, unsigned src_slice, unsigned pixel,
|
||||
unsigned width, unsigned height)
|
||||
{
|
||||
unsigned char* dst = (unsigned char*)void_dst;
|
||||
const unsigned char* src = (const unsigned char*)void_src;
|
||||
|
@ -259,7 +294,8 @@ static void scale3x(void* void_dst, unsigned dst_slice, const void* void_src, un
|
|||
dst = SCDST(3);
|
||||
|
||||
count -= 2;
|
||||
while (count) {
|
||||
while (count)
|
||||
{
|
||||
stage_scale3x(SCDST(0), SCDST(1), SCDST(2), SCSRC(0), SCSRC(1), SCSRC(2), pixel, width);
|
||||
|
||||
dst = SCDST(3);
|
||||
|
@ -292,7 +328,8 @@ static void scale3x(void* void_dst, unsigned dst_slice, const void* void_src, un
|
|||
* \param width Horizontal size in pixels of the source bitmap.
|
||||
* \param height Vertical size in pixels of the source bitmap.
|
||||
*/
|
||||
static void scale4x_buf(void* void_dst, unsigned dst_slice, void* void_mid, unsigned mid_slice, const void* void_src, unsigned src_slice, unsigned pixel, unsigned width, unsigned height)
|
||||
static void scale4x_buf(void* void_dst, unsigned dst_slice, void* void_mid, unsigned mid_slice, const void* void_src,
|
||||
unsigned src_slice, unsigned pixel, unsigned width, unsigned height)
|
||||
{
|
||||
unsigned char* dst = (unsigned char*)void_dst;
|
||||
const unsigned char* src = (const unsigned char*)void_src;
|
||||
|
@ -323,7 +360,8 @@ static void scale4x_buf(void* void_dst, unsigned dst_slice, void* void_mid, unsi
|
|||
dst = SCDST(4);
|
||||
|
||||
count -= 4;
|
||||
while (count) {
|
||||
while (count)
|
||||
{
|
||||
unsigned char* tmp;
|
||||
|
||||
stage_scale2x(SCMID(4), SCMID(5), SCSRC(2), SCSRC(3), SCSRC(4), pixel, width);
|
||||
|
@ -368,7 +406,8 @@ static void scale4x_buf(void* void_dst, unsigned dst_slice, void* void_mid, unsi
|
|||
* \param width Horizontal size in pixels of the source bitmap.
|
||||
* \param height Vertical size in pixels of the source bitmap.
|
||||
*/
|
||||
static void scale4x(void* void_dst, unsigned dst_slice, const void* void_src, unsigned src_slice, unsigned pixel, unsigned width, unsigned height)
|
||||
static void scale4x(void* void_dst, unsigned dst_slice, const void* void_src, unsigned src_slice, unsigned pixel,
|
||||
unsigned width, unsigned height)
|
||||
{
|
||||
unsigned mid_slice;
|
||||
void* mid;
|
||||
|
@ -410,7 +449,8 @@ int scale_precondition(unsigned scale, unsigned pixel, unsigned width, unsigned
|
|||
if (pixel != 1 && pixel != 2 && pixel != 4)
|
||||
return -1;
|
||||
|
||||
switch (scale) {
|
||||
switch (scale)
|
||||
{
|
||||
case 202:
|
||||
case 203:
|
||||
case 204:
|
||||
|
@ -447,9 +487,11 @@ int scale_precondition(unsigned scale, unsigned pixel, unsigned width, unsigned
|
|||
* \param width Horizontal size in pixels of the source bitmap.
|
||||
* \param height Vertical size in pixels of the source bitmap.
|
||||
*/
|
||||
void scale(unsigned scale, void* void_dst, unsigned dst_slice, const void* void_src, unsigned src_slice, unsigned pixel, unsigned width, unsigned height)
|
||||
void scale(unsigned scale, void* void_dst, unsigned dst_slice, const void* void_src, unsigned src_slice, unsigned pixel,
|
||||
unsigned width, unsigned height)
|
||||
{
|
||||
switch (scale)
|
||||
{
|
||||
switch (scale) {
|
||||
case 202:
|
||||
case 2:
|
||||
scale2x(void_dst, dst_slice, void_src, src_slice, pixel, width, height);
|
||||
|
@ -470,4 +512,3 @@ void scale(unsigned scale, void* void_dst, unsigned dst_slice, const void* void_
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
#define __SCALEBIT_H
|
||||
|
||||
int scale_precondition(unsigned scale, unsigned pixel, unsigned width, unsigned height);
|
||||
void scale(unsigned scale, void* void_dst, unsigned dst_slice, const void* void_src, unsigned src_slice, unsigned pixel, unsigned width, unsigned height);
|
||||
void scale(unsigned scale, void* void_dst, unsigned dst_slice, const void* void_src, unsigned src_slice, unsigned pixel,
|
||||
unsigned width, unsigned height);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -22,7 +22,8 @@ Serializer::Serializer(istream &file, uint32_t version, bool compressed)
|
|||
_block->Position = 0;
|
||||
_saving = false;
|
||||
|
||||
if(compressed) {
|
||||
if (compressed)
|
||||
{
|
||||
uint32_t decompressedSize;
|
||||
file.read((char*)&decompressedSize, sizeof(decompressedSize));
|
||||
|
||||
|
@ -36,7 +37,9 @@ Serializer::Serializer(istream &file, uint32_t version, bool compressed)
|
|||
|
||||
unsigned long decompSize = decompressedSize;
|
||||
uncompress(_block->Data.data(), &decompSize, compressedData.data(), (unsigned long)compressedData.size());
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
file.seekg(0, std::ios::end);
|
||||
uint32_t size = (uint32_t)file.tellg();
|
||||
file.seekg(0, std::ios::beg);
|
||||
|
@ -50,14 +53,16 @@ void Serializer::EnsureCapacity(uint32_t typeSize)
|
|||
{
|
||||
//Make sure the current block/stream is large enough to fit the next write
|
||||
uint32_t oldSize = (uint32_t)_block->Data.size();
|
||||
if(oldSize == 0) {
|
||||
if (oldSize == 0)
|
||||
{
|
||||
oldSize = typeSize * 2;
|
||||
}
|
||||
|
||||
uint32_t sizeRequired = _block->Position + typeSize;
|
||||
|
||||
uint32_t newSize = oldSize;
|
||||
while(newSize < sizeRequired) {
|
||||
while (newSize < sizeRequired)
|
||||
{
|
||||
newSize *= 2;
|
||||
}
|
||||
|
||||
|
@ -73,10 +78,13 @@ void Serializer::StreamStartBlock()
|
|||
unique_ptr<BlockData> block(new BlockData());
|
||||
block->Position = 0;
|
||||
|
||||
if(!_saving) {
|
||||
if (!_saving)
|
||||
{
|
||||
VectorInfo<uint8_t> vectorInfo = {&block->Data};
|
||||
InternalStream(vectorInfo);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
block->Data = vector<uint8_t>(0x100);
|
||||
}
|
||||
|
||||
|
@ -86,7 +94,8 @@ void Serializer::StreamStartBlock()
|
|||
|
||||
void Serializer::StreamEndBlock()
|
||||
{
|
||||
if(_blocks.empty()) {
|
||||
if (_blocks.empty())
|
||||
{
|
||||
throw std::runtime_error("Invalid call to end block");
|
||||
}
|
||||
|
||||
|
@ -95,7 +104,8 @@ void Serializer::StreamEndBlock()
|
|||
_block = std::move(_blocks.back());
|
||||
_blocks.pop_back();
|
||||
|
||||
if(_saving) {
|
||||
if (_saving)
|
||||
{
|
||||
ArrayInfo<uint8_t> arrayInfo{block->Data.data(), block->Position};
|
||||
InternalStream(arrayInfo);
|
||||
}
|
||||
|
@ -103,12 +113,16 @@ void Serializer::StreamEndBlock()
|
|||
|
||||
void Serializer::Save(ostream& file, int compressionLevel)
|
||||
{
|
||||
if(compressionLevel == 0) {
|
||||
if (compressionLevel == 0)
|
||||
{
|
||||
file.write((char*)_block->Data.data(), _block->Position);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned long compressedSize = compressBound((unsigned long)_block->Position);
|
||||
uint8_t* compressedData = new uint8_t[compressedSize];
|
||||
compress2(compressedData, &compressedSize, (unsigned char*)_block->Data.data(), (unsigned long)_block->Position, compressionLevel);
|
||||
compress2(compressedData, &compressedSize, (unsigned char*)_block->Data.data(), (unsigned long)_block->Position,
|
||||
compressionLevel);
|
||||
|
||||
uint32_t size = (uint32_t)compressedSize;
|
||||
file.write((char*)&_block->Position, sizeof(uint32_t));
|
||||
|
@ -137,6 +151,7 @@ void Serializer::Stream(ISerializable &obj)
|
|||
obj.Serialize(*this);
|
||||
StreamEndBlock();
|
||||
}
|
||||
|
||||
void Serializer::Stream(ISerializable* obj)
|
||||
{
|
||||
StreamStartBlock();
|
||||
|
@ -146,12 +161,15 @@ void Serializer::Stream(ISerializable *obj)
|
|||
|
||||
void Serializer::InternalStream(string& str)
|
||||
{
|
||||
if(_saving) {
|
||||
if (_saving)
|
||||
{
|
||||
vector<uint8_t> stringData;
|
||||
stringData.resize(str.size());
|
||||
memcpy(stringData.data(), str.data(), str.size());
|
||||
StreamVector(stringData);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
vector<uint8_t> stringData;
|
||||
StreamVector(stringData);
|
||||
str = string(stringData.begin(), stringData.end());
|
||||
|
|
|
@ -43,16 +43,22 @@ private:
|
|||
private:
|
||||
void EnsureCapacity(uint32_t typeSize);
|
||||
|
||||
template<typename T> void StreamElement(T &value, T defaultValue = T());
|
||||
template <typename T>
|
||||
void StreamElement(T& value, T defaultValue = T());
|
||||
|
||||
template<typename T> void InternalStream(ArrayInfo<T> &info);
|
||||
template<typename T> void InternalStream(VectorInfo<T> &info);
|
||||
template<typename T> void InternalStream(ValueInfo<T> &info);
|
||||
template<typename T> void InternalStream(T &value);
|
||||
template <typename T>
|
||||
void InternalStream(ArrayInfo<T>& info);
|
||||
template <typename T>
|
||||
void InternalStream(VectorInfo<T>& info);
|
||||
template <typename T>
|
||||
void InternalStream(ValueInfo<T>& info);
|
||||
template <typename T>
|
||||
void InternalStream(T& value);
|
||||
void InternalStream(string& str);
|
||||
void RecursiveStream();
|
||||
|
||||
template<typename T, typename... T2> void RecursiveStream(T &value, T2&... args);
|
||||
template <typename T, typename... T2>
|
||||
void RecursiveStream(T& value, T2&... args);
|
||||
|
||||
void StreamStartBlock();
|
||||
void StreamEndBlock();
|
||||
|
@ -64,9 +70,12 @@ public:
|
|||
uint32_t GetVersion() { return _version; }
|
||||
bool IsSaving() { return _saving; }
|
||||
|
||||
template<typename... T> void Stream(T&... args);
|
||||
template<typename T> void StreamArray(T *array, uint32_t size);
|
||||
template<typename T> void StreamVector(vector<T> &list);
|
||||
template <typename... T>
|
||||
void Stream(T&... args);
|
||||
template <typename T>
|
||||
void StreamArray(T* array, uint32_t size);
|
||||
template <typename T>
|
||||
void StreamVector(vector<T>& list);
|
||||
|
||||
void Save(ostream& file, int compressionLevel = 1);
|
||||
|
||||
|
@ -80,19 +89,26 @@ public:
|
|||
template <typename T>
|
||||
void Serializer::StreamElement(T& value, T defaultValue)
|
||||
{
|
||||
if(_saving) {
|
||||
if (_saving)
|
||||
{
|
||||
uint8_t* bytes = (uint8_t*)&value;
|
||||
int typeSize = sizeof(T);
|
||||
|
||||
EnsureCapacity(typeSize);
|
||||
for(int i = 0; i < typeSize; i++) {
|
||||
for (int i = 0; i < typeSize; i++)
|
||||
{
|
||||
_block->Data[_block->Position++] = bytes[i];
|
||||
}
|
||||
} else {
|
||||
if(_block->Position + sizeof(T) <= _block->Data.size()) {
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_block->Position + sizeof(T) <= _block->Data.size())
|
||||
{
|
||||
memcpy(&value, _block->Data.data() + _block->Position, sizeof(T));
|
||||
_block->Position += sizeof(T);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
value = defaultValue;
|
||||
_block->Position = (uint32_t)_block->Data.size();
|
||||
}
|
||||
|
@ -105,7 +121,8 @@ void Serializer::InternalStream(ArrayInfo<T> &info)
|
|||
uint32_t count = info.ElementCount;
|
||||
StreamElement<uint32_t>(count);
|
||||
|
||||
if(!_saving) {
|
||||
if (!_saving)
|
||||
{
|
||||
//Reset array to 0 before loading from file
|
||||
memset(info.Array, 0, info.ElementCount * sizeof(T));
|
||||
}
|
||||
|
@ -113,9 +130,12 @@ void Serializer::InternalStream(ArrayInfo<T> &info)
|
|||
//Load the number of elements requested, or the maximum possible (based on what is present in the save state)
|
||||
EnsureCapacity(info.ElementCount * sizeof(T));
|
||||
|
||||
if(_saving) {
|
||||
if (_saving)
|
||||
{
|
||||
memcpy(_block->Data.data() + _block->Position, info.Array, info.ElementCount * sizeof(T));
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(info.Array, _block->Data.data() + _block->Position, info.ElementCount * sizeof(T));
|
||||
}
|
||||
_block->Position += info.ElementCount * sizeof(T);
|
||||
|
@ -129,8 +149,10 @@ void Serializer::InternalStream(VectorInfo<T> &info)
|
|||
uint32_t count = (uint32_t)vector->size();
|
||||
StreamElement<uint32_t>(count);
|
||||
|
||||
if(!_saving) {
|
||||
if(count > 0xFFFFFF) {
|
||||
if (!_saving)
|
||||
{
|
||||
if (count > 0xFFFFFF)
|
||||
{
|
||||
throw std::runtime_error("Invalid save state");
|
||||
}
|
||||
vector->resize(count);
|
||||
|
@ -139,7 +161,8 @@ void Serializer::InternalStream(VectorInfo<T> &info)
|
|||
|
||||
//Load the number of elements requested
|
||||
T* pointer = vector->data();
|
||||
for(uint32_t i = 0; i < count; i++) {
|
||||
for (uint32_t i = 0; i < count; i++)
|
||||
{
|
||||
StreamElement<T>(*pointer);
|
||||
pointer++;
|
||||
}
|
||||
|
|
|
@ -22,11 +22,14 @@ LockHandler SimpleLock::AcquireSafe()
|
|||
|
||||
void SimpleLock::Acquire()
|
||||
{
|
||||
if(_lockCount == 0 || _holderThreadID != _threadID) {
|
||||
if (_lockCount == 0 || _holderThreadID != _threadID)
|
||||
{
|
||||
while (_lock.test_and_set());
|
||||
_holderThreadID = _threadID;
|
||||
_lockCount = 1;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
//Same thread can acquire the same lock multiple times
|
||||
_lockCount++;
|
||||
}
|
||||
|
@ -46,13 +49,17 @@ void SimpleLock::WaitForRelease()
|
|||
|
||||
void SimpleLock::Release()
|
||||
{
|
||||
if(_lockCount > 0 && _holderThreadID == _threadID) {
|
||||
if (_lockCount > 0 && _holderThreadID == _threadID)
|
||||
{
|
||||
_lockCount--;
|
||||
if(_lockCount == 0) {
|
||||
if (_lockCount == 0)
|
||||
{
|
||||
_holderThreadID = std::thread::id();
|
||||
_lock.clear();
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,4 +33,3 @@ public:
|
|||
void WaitForRelease();
|
||||
void Release();
|
||||
};
|
||||
|
||||
|
|
|
@ -40,7 +40,8 @@ Socket::Socket()
|
|||
{
|
||||
#ifdef _WIN32
|
||||
WSADATA wsaDat;
|
||||
if(WSAStartup(MAKEWORD(2, 2), &wsaDat) != 0) {
|
||||
if (WSAStartup(MAKEWORD(2, 2), &wsaDat) != 0)
|
||||
{
|
||||
std::cout << "WSAStartup failed." << std::endl;
|
||||
SetConnectionErrorFlag();
|
||||
return;
|
||||
|
@ -49,10 +50,13 @@ Socket::Socket()
|
|||
#endif
|
||||
|
||||
_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
if(_socket == INVALID_SOCKET) {
|
||||
if (_socket == INVALID_SOCKET)
|
||||
{
|
||||
std::cout << "Socket creation failed." << std::endl;
|
||||
SetConnectionErrorFlag();
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
SetSocketOptions();
|
||||
}
|
||||
}
|
||||
|
@ -61,25 +65,31 @@ Socket::Socket(uintptr_t socket)
|
|||
{
|
||||
_socket = socket;
|
||||
|
||||
if(socket == INVALID_SOCKET) {
|
||||
if (socket == INVALID_SOCKET)
|
||||
{
|
||||
SetConnectionErrorFlag();
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
SetSocketOptions();
|
||||
}
|
||||
}
|
||||
|
||||
Socket::~Socket()
|
||||
{
|
||||
if(_UPnPPort != -1) {
|
||||
if (_UPnPPort != -1)
|
||||
{
|
||||
UPnPPortMapper::RemoveNATPortMapping(_UPnPPort, IPProtocol::TCP);
|
||||
}
|
||||
|
||||
if(_socket != INVALID_SOCKET) {
|
||||
if (_socket != INVALID_SOCKET)
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
if(_cleanupWSA) {
|
||||
if (_cleanupWSA)
|
||||
{
|
||||
WSACleanup();
|
||||
}
|
||||
#endif
|
||||
|
@ -126,11 +136,13 @@ void Socket::Bind(uint16_t port)
|
|||
serverInf.sin_addr.s_addr = INADDR_ANY;
|
||||
serverInf.sin_port = htons(port);
|
||||
|
||||
if(UPnPPortMapper::AddNATPortMapping(port, port, IPProtocol::TCP)) {
|
||||
if (UPnPPortMapper::AddNATPortMapping(port, port, IPProtocol::TCP))
|
||||
{
|
||||
_UPnPPort = port;
|
||||
}
|
||||
|
||||
if(::bind(_socket, (SOCKADDR*)(&serverInf), sizeof(serverInf)) == SOCKET_ERROR) {
|
||||
if (::bind(_socket, (SOCKADDR*)(&serverInf), sizeof(serverInf)) == SOCKET_ERROR)
|
||||
{
|
||||
std::cout << "Unable to bind socket." << std::endl;
|
||||
SetConnectionErrorFlag();
|
||||
}
|
||||
|
@ -147,10 +159,13 @@ bool Socket::Connect(const char* hostname, uint16_t port)
|
|||
hint.ai_socktype = SOCK_STREAM;
|
||||
addrinfo* addrInfo;
|
||||
|
||||
if(getaddrinfo(hostname, std::to_string(port).c_str(), &hint, &addrInfo) != 0) {
|
||||
if (getaddrinfo(hostname, std::to_string(port).c_str(), &hint, &addrInfo) != 0)
|
||||
{
|
||||
std::cout << "Failed to resolve hostname." << std::endl;
|
||||
SetConnectionErrorFlag();
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
//Set socket in non-blocking mode
|
||||
u_long iMode = 1;
|
||||
ioctlsocket(_socket, FIONBIO, &iMode);
|
||||
|
@ -174,11 +189,15 @@ bool Socket::Connect(const char* hostname, uint16_t port)
|
|||
|
||||
// check if the socket is ready
|
||||
int returnVal = select((int)_socket + 1, nullptr, &writeSockets, nullptr, &timeout);
|
||||
if(returnVal > 0) {
|
||||
if (returnVal > 0)
|
||||
{
|
||||
result = true;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
//Could not connect
|
||||
if(returnVal == SOCKET_ERROR) {
|
||||
if (returnVal == SOCKET_ERROR)
|
||||
{
|
||||
//int nError = WSAGetLastError();
|
||||
//std::cout << "select failed: nError " << std::to_string(nError) << " returnVal" << std::to_string(returnVal) << std::endl;
|
||||
}
|
||||
|
@ -193,7 +212,8 @@ bool Socket::Connect(const char* hostname, uint16_t port)
|
|||
|
||||
void Socket::Listen(int backlog)
|
||||
{
|
||||
if(listen(_socket, backlog) == SOCKET_ERROR) {
|
||||
if (listen(_socket, backlog) == SOCKET_ERROR)
|
||||
{
|
||||
std::cout << "listen failed." << std::endl;
|
||||
SetConnectionErrorFlag();
|
||||
}
|
||||
|
@ -215,22 +235,31 @@ int Socket::Send(char *buf, int len, int flags)
|
|||
int retryCount = 15;
|
||||
int nError = 0;
|
||||
int returnVal;
|
||||
do {
|
||||
do
|
||||
{
|
||||
//Loop until everything has been sent (shouldn't loop at all in the vast majority of cases)
|
||||
returnVal = send(_socket, buf, len, flags);
|
||||
|
||||
if(returnVal > 0) {
|
||||
if (returnVal > 0)
|
||||
{
|
||||
//Sent partial data, adjust pointer & length
|
||||
buf += returnVal;
|
||||
len -= returnVal;
|
||||
} else if(returnVal == SOCKET_ERROR) {
|
||||
}
|
||||
else if (returnVal == SOCKET_ERROR)
|
||||
{
|
||||
nError = WSAGetLastError();
|
||||
if(nError != 0) {
|
||||
if(!WouldBlock(nError)) {
|
||||
if (nError != 0)
|
||||
{
|
||||
if (!WouldBlock(nError))
|
||||
{
|
||||
SetConnectionErrorFlag();
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
retryCount--;
|
||||
if(retryCount == 0) {
|
||||
if (retryCount == 0)
|
||||
{
|
||||
//Connection seems dead, close it.
|
||||
std::cout << "Unable to send data, closing socket." << std::endl;
|
||||
Close();
|
||||
|
@ -241,7 +270,8 @@ int Socket::Send(char *buf, int len, int flags)
|
|||
}
|
||||
}
|
||||
}
|
||||
} while(WouldBlock(nError) && len > 0);
|
||||
}
|
||||
while (WouldBlock(nError) && len > 0);
|
||||
|
||||
return returnVal;
|
||||
}
|
||||
|
@ -250,13 +280,18 @@ int Socket::Recv(char *buf, int len, int flags)
|
|||
{
|
||||
int returnVal = recv(_socket, buf, len, flags);
|
||||
|
||||
if(returnVal == SOCKET_ERROR) {
|
||||
if (returnVal == SOCKET_ERROR)
|
||||
{
|
||||
int nError = WSAGetLastError();
|
||||
if(nError && !WouldBlock(nError)) {
|
||||
std::cout << "recv failed: nError " << std::to_string(nError) << " returnVal" << std::to_string(returnVal) << std::endl;
|
||||
if (nError && !WouldBlock(nError))
|
||||
{
|
||||
std::cout << "recv failed: nError " << std::to_string(nError) << " returnVal" << std::to_string(returnVal) <<
|
||||
std::endl;
|
||||
SetConnectionErrorFlag();
|
||||
}
|
||||
} else if(returnVal == 0) {
|
||||
}
|
||||
else if (returnVal == 0)
|
||||
{
|
||||
//Socket closed
|
||||
std::cout << "Socket closed by peer." << std::endl;
|
||||
Close();
|
||||
|
|
|
@ -9,7 +9,8 @@ public:
|
|||
vector<string> result;
|
||||
size_t index = 0;
|
||||
size_t lastIndex = 0;
|
||||
while((index = input.find(delimiter, index)) != string::npos) {
|
||||
while ((index = input.find(delimiter, index)) != string::npos)
|
||||
{
|
||||
result.push_back(input.substr(lastIndex, index - lastIndex));
|
||||
index++;
|
||||
lastIndex = index;
|
||||
|
|
|
@ -25,9 +25,11 @@ double Timer::GetElapsedMS()
|
|||
|
||||
void Timer::WaitUntil(double targetMillisecond)
|
||||
{
|
||||
if(targetMillisecond > 0) {
|
||||
if (targetMillisecond > 0)
|
||||
{
|
||||
double elapsedTime = GetElapsedMS();
|
||||
if(targetMillisecond - elapsedTime > 1) {
|
||||
if (targetMillisecond - elapsedTime > 1)
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::duration<int, std::milli>((int)(targetMillisecond - elapsedTime)));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,47 +17,61 @@ bool UPnPPortMapper::AddNATPortMapping(uint16_t internalPort, uint16_t externalP
|
|||
|
||||
BSTR proto = SysAllocString((protocol == IPProtocol::TCP) ? L"TCP" : L"UDP");
|
||||
|
||||
if(SUCCEEDED(hResult) && nat) {
|
||||
if (SUCCEEDED(hResult) && nat)
|
||||
{
|
||||
IStaticPortMappingCollection* spmc = nullptr;
|
||||
hResult = nat->get_StaticPortMappingCollection(&spmc);
|
||||
if(SUCCEEDED(hResult) && spmc) {
|
||||
if (SUCCEEDED(hResult) && spmc)
|
||||
{
|
||||
IStaticPortMapping* spm = nullptr;
|
||||
hResult = spmc->get_Item(externalPort, proto, &spm);
|
||||
if(spm != nullptr) {
|
||||
if (spm != nullptr)
|
||||
{
|
||||
//An identical mapping already exists, remove it
|
||||
if(RemoveNATPortMapping(externalPort, protocol)) {
|
||||
if (RemoveNATPortMapping(externalPort, protocol))
|
||||
{
|
||||
std::cout << "Removed existing UPnP mapping." << std::endl;
|
||||
spm->Release();
|
||||
spm = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if(!SUCCEEDED(hResult) || spm == nullptr) {
|
||||
if (!SUCCEEDED(hResult) || spm == nullptr)
|
||||
{
|
||||
std::cout << "Attempting to automatically forward port via UPnP..." << std::endl;
|
||||
|
||||
vector<wstring> localIPs = GetLocalIPs();
|
||||
BSTR desc = SysAllocString(L"Mesen NetPlay");
|
||||
spm = nullptr;
|
||||
|
||||
for(size_t i = 0, len = localIPs.size(); i < len; i++) {
|
||||
for (size_t i = 0, len = localIPs.size(); i < len; i++)
|
||||
{
|
||||
BSTR clientStr = SysAllocString(localIPs[i].c_str());
|
||||
hResult = spmc->Add(externalPort, proto, internalPort, clientStr, true, desc, &spm);
|
||||
SysFreeString(clientStr);
|
||||
SysFreeString(desc);
|
||||
|
||||
if(SUCCEEDED(hResult) && spm) {
|
||||
if (SUCCEEDED(hResult) && spm)
|
||||
{
|
||||
//Successfully added a new port mapping
|
||||
std::cout << std::dec << "Forwarded port " << externalPort << " to IP " << utf8::utf8::encode(localIPs[i]) << std::endl;
|
||||
std::cout << std::dec << "Forwarded port " << externalPort << " to IP " <<
|
||||
utf8::utf8::encode(localIPs[i]) << std::endl;
|
||||
result = true;
|
||||
} else {
|
||||
std::cout << "Unable to add UPnP port mapping. IP: " << utf8::utf8::encode(localIPs[i]) << " HRESULT: 0x" << std::hex << hResult << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Unable to add UPnP port mapping. IP: " << utf8::utf8::encode(localIPs[i]) <<
|
||||
" HRESULT: 0x" << std::hex << hResult << std::endl;
|
||||
}
|
||||
|
||||
if(spm) {
|
||||
if (spm)
|
||||
{
|
||||
spm->Release();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Unable to add UPnP port mapping." << std::endl;
|
||||
}
|
||||
spmc->Release();
|
||||
|
@ -84,9 +98,11 @@ bool UPnPPortMapper::RemoveNATPortMapping(uint16_t externalPort, IPProtocol prot
|
|||
|
||||
BSTR proto = SysAllocString((protocol == IPProtocol::TCP) ? L"TCP" : L"UDP");
|
||||
|
||||
if(SUCCEEDED(hResult) && nat) {
|
||||
if (SUCCEEDED(hResult) && nat)
|
||||
{
|
||||
hResult = nat->get_StaticPortMappingCollection(&spmc);
|
||||
if(SUCCEEDED(hResult) && spmc) {
|
||||
if (SUCCEEDED(hResult) && spmc)
|
||||
{
|
||||
spmc->Remove(externalPort, proto);
|
||||
spmc->Release();
|
||||
result = true;
|
||||
|
@ -117,14 +133,18 @@ vector<wstring> UPnPPortMapper::GetLocalIPs()
|
|||
DWORD hostSize = 255;
|
||||
GetComputerName(hostName, &hostSize);
|
||||
|
||||
if(GetAddrInfoW(hostName, nullptr, &hints, &result) == 0) {
|
||||
if (GetAddrInfoW(hostName, nullptr, &hints, &result) == 0)
|
||||
{
|
||||
current = result;
|
||||
while(current != nullptr) {
|
||||
while (current != nullptr)
|
||||
{
|
||||
wchar_t ipAddr[255];
|
||||
DWORD ipSize = 255;
|
||||
|
||||
if(WSAAddressToString(current->ai_addr, (DWORD)current->ai_addrlen, nullptr, ipAddr, &ipSize) == 0) {
|
||||
if(std::find(localIPs.begin(), localIPs.end(), ipAddr) == localIPs.end()) {
|
||||
if (WSAAddressToString(current->ai_addr, (DWORD)current->ai_addrlen, nullptr, ipAddr, &ipSize) == 0)
|
||||
{
|
||||
if (std::find(localIPs.begin(), localIPs.end(), ipAddr) == localIPs.end())
|
||||
{
|
||||
localIPs.push_back(ipAddr);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
|
||||
#include <fstream>
|
||||
|
||||
namespace utf8 {
|
||||
namespace utf8
|
||||
{
|
||||
class utf8
|
||||
{
|
||||
public:
|
||||
|
@ -15,17 +16,37 @@ namespace utf8 {
|
|||
class ifstream : public std::ifstream
|
||||
{
|
||||
public:
|
||||
ifstream(const std::string& _Str, ios_base::openmode _Mode = ios_base::in, int _Prot = (int)ios_base::_Openprot) : std::ifstream(utf8::decode(_Str), _Mode, _Prot) { }
|
||||
ifstream() : std::ifstream() { }
|
||||
void open(const std::string& _Str, ios_base::openmode _Mode = ios_base::in, int _Prot = (int)ios_base::_Openprot) { std::ifstream::open(utf8::decode(_Str), _Mode, _Prot); }
|
||||
ifstream(const std::string& _Str, ios_base::openmode _Mode = ios_base::in,
|
||||
int _Prot = (int)ios_base::_Openprot) : std::ifstream(utf8::decode(_Str), _Mode, _Prot)
|
||||
{
|
||||
}
|
||||
|
||||
ifstream() : std::ifstream()
|
||||
{
|
||||
}
|
||||
|
||||
void open(const std::string& _Str, ios_base::openmode _Mode = ios_base::in, int _Prot = (int)ios_base::_Openprot)
|
||||
{
|
||||
std::ifstream::open(utf8::decode(_Str), _Mode, _Prot);
|
||||
}
|
||||
};
|
||||
|
||||
class ofstream : public std::ofstream
|
||||
{
|
||||
public:
|
||||
ofstream(const std::string& _Str, ios_base::openmode _Mode = ios_base::in, int _Prot = (int)ios_base::_Openprot) : std::ofstream(utf8::decode(_Str), _Mode, _Prot) { }
|
||||
ofstream() : std::ofstream() { }
|
||||
void open(const std::string& _Str, ios_base::openmode _Mode = ios_base::in, int _Prot = (int)ios_base::_Openprot) { std::ofstream::open(utf8::decode(_Str), _Mode, _Prot); }
|
||||
ofstream(const std::string& _Str, ios_base::openmode _Mode = ios_base::in,
|
||||
int _Prot = (int)ios_base::_Openprot) : std::ofstream(utf8::decode(_Str), _Mode, _Prot)
|
||||
{
|
||||
}
|
||||
|
||||
ofstream() : std::ofstream()
|
||||
{
|
||||
}
|
||||
|
||||
void open(const std::string& _Str, ios_base::openmode _Mode = ios_base::in, int _Prot = (int)ios_base::_Openprot)
|
||||
{
|
||||
std::ofstream::open(utf8::decode(_Str), _Mode, _Prot);
|
||||
}
|
||||
};
|
||||
#else
|
||||
using std::ifstream;
|
||||
|
|
|
@ -9,14 +9,17 @@ int64_t UpsPatcher::ReadBase128Number(std::istream &file)
|
|||
int64_t result = 0;
|
||||
int shift = 0;
|
||||
uint8_t buffer;
|
||||
while(true) {
|
||||
while (true)
|
||||
{
|
||||
file.read((char*)&buffer, 1);
|
||||
if(file.eof()) {
|
||||
if (file.eof())
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
result += (buffer & 0x7F) << shift;
|
||||
shift += 7;
|
||||
if(buffer & 0x80) {
|
||||
if (buffer & 0x80)
|
||||
{
|
||||
break;
|
||||
}
|
||||
result += (int64_t)1 << shift;
|
||||
|
@ -28,7 +31,8 @@ int64_t UpsPatcher::ReadBase128Number(std::istream &file)
|
|||
bool UpsPatcher::PatchBuffer(string upsFilepath, vector<uint8_t>& input, vector<uint8_t>& output)
|
||||
{
|
||||
ifstream upsFile(upsFilepath, std::ios::in | std::ios::binary);
|
||||
if(upsFile) {
|
||||
if (upsFile)
|
||||
{
|
||||
return PatchBuffer(upsFile, input, output);
|
||||
}
|
||||
return false;
|
||||
|
@ -42,14 +46,16 @@ bool UpsPatcher::PatchBuffer(std::istream &upsFile, vector<uint8_t> &input, vect
|
|||
|
||||
char header[4];
|
||||
upsFile.read((char*)&header, 4);
|
||||
if(memcmp((char*)&header, "UPS1", 4) != 0) {
|
||||
if (memcmp((char*)&header, "UPS1", 4) != 0)
|
||||
{
|
||||
//Invalid UPS file
|
||||
return false;
|
||||
}
|
||||
|
||||
int64_t inputFileSize = ReadBase128Number(upsFile);
|
||||
int64_t outputFileSize = ReadBase128Number(upsFile);
|
||||
if(inputFileSize == -1 || outputFileSize == -1) {
|
||||
if (inputFileSize == -1 || outputFileSize == -1)
|
||||
{
|
||||
//Invalid file
|
||||
return false;
|
||||
}
|
||||
|
@ -58,19 +64,23 @@ bool UpsPatcher::PatchBuffer(std::istream &upsFile, vector<uint8_t> &input, vect
|
|||
std::copy(input.begin(), input.end(), output.begin());
|
||||
|
||||
uint32_t pos = 0;
|
||||
while((size_t)upsFile.tellg() < fileSize - 12) {
|
||||
while ((size_t)upsFile.tellg() < fileSize - 12)
|
||||
{
|
||||
int32_t offset = (int32_t)ReadBase128Number(upsFile);
|
||||
if(offset == -1) {
|
||||
if (offset == -1)
|
||||
{
|
||||
//Invalid file
|
||||
return false;
|
||||
}
|
||||
|
||||
pos += offset;
|
||||
|
||||
while(true) {
|
||||
while (true)
|
||||
{
|
||||
uint8_t xorValue = 0;
|
||||
upsFile.read((char*)&xorValue, 1);
|
||||
if((size_t)upsFile.tellg() > fileSize - 12) {
|
||||
if ((size_t)upsFile.tellg() > fileSize - 12)
|
||||
{
|
||||
//Invalid file
|
||||
return false;
|
||||
}
|
||||
|
@ -78,7 +88,8 @@ bool UpsPatcher::PatchBuffer(std::istream &upsFile, vector<uint8_t> &input, vect
|
|||
output[pos] ^= xorValue;
|
||||
pos++;
|
||||
|
||||
if(!xorValue) {
|
||||
if (!xorValue)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -88,12 +99,15 @@ bool UpsPatcher::PatchBuffer(std::istream &upsFile, vector<uint8_t> &input, vect
|
|||
uint8_t outputChecksum[4];
|
||||
upsFile.read((char*)inputChecksum, 4);
|
||||
upsFile.read((char*)outputChecksum, 4);
|
||||
uint32_t patchInputCrc = inputChecksum[0] | (inputChecksum[1] << 8) | (inputChecksum[2] << 16) | (inputChecksum[3] << 24);
|
||||
uint32_t patchOutputCrc = outputChecksum[0] | (outputChecksum[1] << 8) | (outputChecksum[2] << 16) | (outputChecksum[3] << 24);
|
||||
uint32_t patchInputCrc = inputChecksum[0] | (inputChecksum[1] << 8) | (inputChecksum[2] << 16) | (inputChecksum[3] <<
|
||||
24);
|
||||
uint32_t patchOutputCrc = outputChecksum[0] | (outputChecksum[1] << 8) | (outputChecksum[2] << 16) | (outputChecksum[
|
||||
3] << 24);
|
||||
uint32_t inputCrc = CRC32::GetCRC(input.data(), input.size());
|
||||
uint32_t outputCrc = CRC32::GetCRC(output.data(), output.size());
|
||||
|
||||
if(patchInputCrc != inputCrc || patchOutputCrc != outputCrc) {
|
||||
if (patchInputCrc != inputCrc || patchOutputCrc != outputCrc)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
|
|
@ -26,12 +26,18 @@ VirtualFile::VirtualFile(const string& file)
|
|||
{
|
||||
vector<string> tokens = StringUtilities::Split(file, '\x1');
|
||||
_path = tokens[0];
|
||||
if(tokens.size() > 1) {
|
||||
if (tokens.size() > 1)
|
||||
{
|
||||
_innerFile = tokens[1];
|
||||
if(tokens.size() > 2) {
|
||||
try {
|
||||
if (tokens.size() > 2)
|
||||
{
|
||||
try
|
||||
{
|
||||
_innerFileIndex = std::stoi(tokens[2]);
|
||||
} catch(std::exception&) {}
|
||||
}
|
||||
catch (std::exception&)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -52,14 +58,22 @@ VirtualFile::VirtualFile(std::istream& input, string filePath)
|
|||
|
||||
VirtualFile::operator std::string() const
|
||||
{
|
||||
if(_innerFile.empty()) {
|
||||
if (_innerFile.empty())
|
||||
{
|
||||
return _path;
|
||||
} else if(_path.empty()) {
|
||||
}
|
||||
else if (_path.empty())
|
||||
{
|
||||
throw std::runtime_error("Cannot convert to string");
|
||||
} else {
|
||||
if(_innerFileIndex >= 0) {
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_innerFileIndex >= 0)
|
||||
{
|
||||
return _path + "\x1" + _innerFile + "\x1" + std::to_string(_innerFileIndex);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
return _path + "\x1" + _innerFile;
|
||||
}
|
||||
}
|
||||
|
@ -77,22 +91,32 @@ void VirtualFile::FromStream(std::istream& input, vector<uint8_t>& output)
|
|||
|
||||
void VirtualFile::LoadFile()
|
||||
{
|
||||
if(_data.size() == 0) {
|
||||
if(!_innerFile.empty()) {
|
||||
if (_data.size() == 0)
|
||||
{
|
||||
if (!_innerFile.empty())
|
||||
{
|
||||
shared_ptr<ArchiveReader> reader = ArchiveReader::GetReader(_path);
|
||||
if(reader) {
|
||||
if(_innerFileIndex >= 0) {
|
||||
if (reader)
|
||||
{
|
||||
if (_innerFileIndex >= 0)
|
||||
{
|
||||
vector<string> filelist = reader->GetFileList(VirtualFile::RomExtensions);
|
||||
if((int32_t)filelist.size() > _innerFileIndex) {
|
||||
if ((int32_t)filelist.size() > _innerFileIndex)
|
||||
{
|
||||
reader->ExtractFile(filelist[_innerFileIndex], _data);
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
reader->ExtractFile(_innerFile, _data);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
ifstream input(_path, std::ios::in | std::ios::binary);
|
||||
if(input.good()) {
|
||||
if (input.good())
|
||||
{
|
||||
FromStream(input, _data);
|
||||
}
|
||||
}
|
||||
|
@ -101,25 +125,35 @@ void VirtualFile::LoadFile()
|
|||
|
||||
bool VirtualFile::IsValid()
|
||||
{
|
||||
if(_data.size() > 0) {
|
||||
if (_data.size() > 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if(!_innerFile.empty()) {
|
||||
if (!_innerFile.empty())
|
||||
{
|
||||
shared_ptr<ArchiveReader> reader = ArchiveReader::GetReader(_path);
|
||||
if(reader) {
|
||||
if (reader)
|
||||
{
|
||||
vector<string> filelist = reader->GetFileList();
|
||||
if(_innerFileIndex >= 0) {
|
||||
if((int32_t)filelist.size() > _innerFileIndex) {
|
||||
if (_innerFileIndex >= 0)
|
||||
{
|
||||
if ((int32_t)filelist.size() > _innerFileIndex)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
return std::find(filelist.begin(), filelist.end(), _innerFile) != filelist.end();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
ifstream input(_path, std::ios::in | std::ios::binary);
|
||||
if(input) {
|
||||
if (input)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -156,7 +190,8 @@ size_t VirtualFile::GetSize()
|
|||
bool VirtualFile::ReadFile(vector<uint8_t>& out)
|
||||
{
|
||||
LoadFile();
|
||||
if(_data.size() > 0) {
|
||||
if (_data.size() > 0)
|
||||
{
|
||||
out.resize(_data.size(), 0);
|
||||
std::copy(_data.begin(), _data.end(), out.begin());
|
||||
return true;
|
||||
|
@ -167,7 +202,8 @@ bool VirtualFile::ReadFile(vector<uint8_t>& out)
|
|||
bool VirtualFile::ReadFile(std::stringstream& out)
|
||||
{
|
||||
LoadFile();
|
||||
if(_data.size() > 0) {
|
||||
if (_data.size() > 0)
|
||||
{
|
||||
out.write((char*)_data.data(), _data.size());
|
||||
return true;
|
||||
}
|
||||
|
@ -177,7 +213,8 @@ bool VirtualFile::ReadFile(std::stringstream& out)
|
|||
bool VirtualFile::ReadFile(uint8_t* out, uint32_t expectedSize)
|
||||
{
|
||||
LoadFile();
|
||||
if(_data.size() == expectedSize) {
|
||||
if (_data.size() == expectedSize)
|
||||
{
|
||||
memcpy(out, _data.data(), _data.size());
|
||||
return true;
|
||||
}
|
||||
|
@ -188,22 +225,30 @@ bool VirtualFile::ApplyPatch(VirtualFile& patch)
|
|||
{
|
||||
//Apply patch file
|
||||
bool result = false;
|
||||
if(IsValid() && patch.IsValid()) {
|
||||
if (IsValid() && patch.IsValid())
|
||||
{
|
||||
patch.LoadFile();
|
||||
LoadFile();
|
||||
if(patch._data.size() >= 5) {
|
||||
if (patch._data.size() >= 5)
|
||||
{
|
||||
vector<uint8_t> patchedData;
|
||||
std::stringstream ss;
|
||||
patch.ReadFile(ss);
|
||||
|
||||
if(memcmp(patch._data.data(), "PATCH", 5) == 0) {
|
||||
if (memcmp(patch._data.data(), "PATCH", 5) == 0)
|
||||
{
|
||||
result = IpsPatcher::PatchBuffer(ss, _data, patchedData);
|
||||
} else if(memcmp(patch._data.data(), "UPS1", 4) == 0) {
|
||||
}
|
||||
else if (memcmp(patch._data.data(), "UPS1", 4) == 0)
|
||||
{
|
||||
result = UpsPatcher::PatchBuffer(ss, _data, patchedData);
|
||||
} else if(memcmp(patch._data.data(), "BPS1", 4) == 0) {
|
||||
}
|
||||
else if (memcmp(patch._data.data(), "BPS1", 4) == 0)
|
||||
{
|
||||
result = BpsPatcher::PatchBuffer(ss, _data, patchedData);
|
||||
}
|
||||
if(result) {
|
||||
if (result)
|
||||
{
|
||||
_data = patchedData;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,14 +10,16 @@ ZipReader::ZipReader()
|
|||
|
||||
ZipReader::~ZipReader()
|
||||
{
|
||||
if(_initialized) {
|
||||
if (_initialized)
|
||||
{
|
||||
mz_zip_reader_end(&_zipArchive);
|
||||
}
|
||||
}
|
||||
|
||||
bool ZipReader::InternalLoadArchive(void* buffer, size_t size)
|
||||
{
|
||||
if(_initialized) {
|
||||
if (_initialized)
|
||||
{
|
||||
mz_zip_reader_end(&_zipArchive);
|
||||
memset(&_zipArchive, 0, sizeof(mz_zip_archive));
|
||||
_initialized = false;
|
||||
|
@ -29,10 +31,13 @@ bool ZipReader::InternalLoadArchive(void* buffer, size_t size)
|
|||
vector<string> ZipReader::InternalGetFileList()
|
||||
{
|
||||
vector<string> fileList;
|
||||
if(_initialized) {
|
||||
for(int i = 0, len = (int)mz_zip_reader_get_num_files(&_zipArchive); i < len; i++) {
|
||||
if (_initialized)
|
||||
{
|
||||
for (int i = 0, len = (int)mz_zip_reader_get_num_files(&_zipArchive); i < len; i++)
|
||||
{
|
||||
mz_zip_archive_file_stat file_stat;
|
||||
if(!mz_zip_reader_file_stat(&_zipArchive, i, &file_stat)) {
|
||||
if (!mz_zip_reader_file_stat(&_zipArchive, i, &file_stat))
|
||||
{
|
||||
std::cout << "mz_zip_reader_file_stat() failed!" << std::endl;
|
||||
}
|
||||
|
||||
|
@ -44,10 +49,12 @@ vector<string> ZipReader::InternalGetFileList()
|
|||
|
||||
bool ZipReader::ExtractFile(string filename, vector<uint8_t>& output)
|
||||
{
|
||||
if(_initialized) {
|
||||
if (_initialized)
|
||||
{
|
||||
size_t uncompSize;
|
||||
void* p = mz_zip_reader_extract_file_to_heap(&_zipArchive, filename.c_str(), &uncompSize, 0);
|
||||
if(!p) {
|
||||
if (!p)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
std::cout << "mz_zip_reader_extract_file_to_heap() failed!" << std::endl;
|
||||
#endif
|
||||
|
|
|
@ -29,14 +29,16 @@ bool ZipWriter::Save()
|
|||
|
||||
void ZipWriter::AddFile(string filepath, string zipFilename)
|
||||
{
|
||||
if(!mz_zip_writer_add_file(&_zipArchive, zipFilename.c_str(), filepath.c_str(), "", 0, MZ_BEST_COMPRESSION)) {
|
||||
if (!mz_zip_writer_add_file(&_zipArchive, zipFilename.c_str(), filepath.c_str(), "", 0, MZ_BEST_COMPRESSION))
|
||||
{
|
||||
std::cout << "mz_zip_writer_add_file() failed!" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void ZipWriter::AddFile(vector<uint8_t>& fileData, string zipFilename)
|
||||
{
|
||||
if(!mz_zip_writer_add_mem(&_zipArchive, zipFilename.c_str(), fileData.data(), fileData.size(), MZ_BEST_COMPRESSION)) {
|
||||
if (!mz_zip_writer_add_mem(&_zipArchive, zipFilename.c_str(), fileData.data(), fileData.size(), MZ_BEST_COMPRESSION))
|
||||
{
|
||||
std::cout << "mz_zip_writer_add_file() failed!" << std::endl;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,13 +39,19 @@
|
|||
#define Mask_KeyFrame 0x01
|
||||
#define Mask_DeltaPalette 0x02
|
||||
|
||||
int ZmbvCodec::NeededSize( int _width, int _height, zmbv_format_t _format) {
|
||||
int ZmbvCodec::NeededSize(int _width, int _height, zmbv_format_t _format)
|
||||
{
|
||||
int f;
|
||||
switch (_format) {
|
||||
case ZMBV_FORMAT_8BPP:f = 1;break;
|
||||
case ZMBV_FORMAT_15BPP:f = 2;break;
|
||||
case ZMBV_FORMAT_16BPP:f = 2;break;
|
||||
case ZMBV_FORMAT_32BPP:f = 4;break;
|
||||
switch (_format)
|
||||
{
|
||||
case ZMBV_FORMAT_8BPP: f = 1;
|
||||
break;
|
||||
case ZMBV_FORMAT_15BPP: f = 2;
|
||||
break;
|
||||
case ZMBV_FORMAT_16BPP: f = 2;
|
||||
break;
|
||||
case ZMBV_FORMAT_32BPP: f = 4;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
@ -53,10 +59,12 @@ int ZmbvCodec::NeededSize( int _width, int _height, zmbv_format_t _format) {
|
|||
return f + f / 1000;
|
||||
}
|
||||
|
||||
bool ZmbvCodec::SetupBuffers(zmbv_format_t _format, int blockwidth, int blockheight) {
|
||||
bool ZmbvCodec::SetupBuffers(zmbv_format_t _format, int blockwidth, int blockheight)
|
||||
{
|
||||
FreeBuffers();
|
||||
palsize = 0;
|
||||
switch (_format) {
|
||||
switch (_format)
|
||||
{
|
||||
case ZMBV_FORMAT_8BPP:
|
||||
pixelsize = 1;
|
||||
palsize = 256;
|
||||
|
@ -88,24 +96,33 @@ bool ZmbvCodec::SetupBuffers(zmbv_format_t _format, int blockwidth, int blockhei
|
|||
blockcount = yblocks * xblocks;
|
||||
blocks = new FrameBlock[blockcount];
|
||||
|
||||
if (!buf1 || !buf2 || !work || !blocks) {
|
||||
if (!buf1 || !buf2 || !work || !blocks)
|
||||
{
|
||||
FreeBuffers();
|
||||
return false;
|
||||
}
|
||||
int y, x, i;
|
||||
i = 0;
|
||||
for (y=0;y<yblocks;y++) {
|
||||
for (x=0;x<xblocks;x++) {
|
||||
for (y = 0; y < yblocks; y++)
|
||||
{
|
||||
for (x = 0; x < xblocks; x++)
|
||||
{
|
||||
blocks[i].start = ((y * blockheight) + MAX_VECTOR) * pitch +
|
||||
(x * blockwidth) + MAX_VECTOR;
|
||||
if (xleft && x==(xblocks-1)) {
|
||||
if (xleft && x == (xblocks - 1))
|
||||
{
|
||||
blocks[i].dx = xleft;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
blocks[i].dx = blockwidth;
|
||||
}
|
||||
if (yleft && y==(yblocks-1)) {
|
||||
if (yleft && y == (yblocks - 1))
|
||||
{
|
||||
blocks[i].dy = yleft;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
blocks[i].dy = blockheight;
|
||||
}
|
||||
i++;
|
||||
|
@ -125,14 +142,19 @@ bool ZmbvCodec::SetupBuffers(zmbv_format_t _format, int blockwidth, int blockhei
|
|||
return true;
|
||||
}
|
||||
|
||||
void ZmbvCodec::CreateVectorTable(void) {
|
||||
void ZmbvCodec::CreateVectorTable(void)
|
||||
{
|
||||
int x, y, s;
|
||||
VectorCount = 1;
|
||||
|
||||
VectorTable[0].x = VectorTable[0].y = 0;
|
||||
for (s=1;s<=10;s++) {
|
||||
for (y=0-s;y<=0+s;y++) for (x=0-s;x<=0+s;x++) {
|
||||
if (abs(x)==s || abs(y)==s) {
|
||||
for (s = 1; s <= 10; s++)
|
||||
{
|
||||
for (y = 0 - s; y <= 0 + s; y++)
|
||||
for (x = 0 - s; x <= 0 + s; x++)
|
||||
{
|
||||
if (abs(x) == s || abs(y) == s)
|
||||
{
|
||||
VectorTable[VectorCount].x = x;
|
||||
VectorTable[VectorCount].y = y;
|
||||
VectorCount++;
|
||||
|
@ -142,12 +164,15 @@ void ZmbvCodec::CreateVectorTable(void) {
|
|||
}
|
||||
|
||||
template <class P>
|
||||
INLINE int ZmbvCodec::PossibleBlock(int vx,int vy,FrameBlock * block) {
|
||||
INLINE int ZmbvCodec::PossibleBlock(int vx, int vy, FrameBlock* block)
|
||||
{
|
||||
int ret = 0;
|
||||
P* pold = ((P*)oldframe) + block->start + (vy * pitch) + vx;
|
||||
P* pnew = ((P*)newframe) + block->start;;
|
||||
for (int y=0;y<block->dy;y+=4) {
|
||||
for (int x=0;x<block->dx;x+=4) {
|
||||
for (int y = 0; y < block->dy; y += 4)
|
||||
{
|
||||
for (int x = 0; x < block->dx; x += 4)
|
||||
{
|
||||
int test = 0 - ((pold[x] - pnew[x]) & 0x00ffffff);
|
||||
ret -= (test >> 31);
|
||||
}
|
||||
|
@ -158,12 +183,15 @@ INLINE int ZmbvCodec::PossibleBlock(int vx,int vy,FrameBlock * block) {
|
|||
}
|
||||
|
||||
template <class P>
|
||||
INLINE int ZmbvCodec::CompareBlock(int vx,int vy,FrameBlock * block) {
|
||||
INLINE int ZmbvCodec::CompareBlock(int vx, int vy, FrameBlock* block)
|
||||
{
|
||||
int ret = 0;
|
||||
P* pold = ((P*)oldframe) + block->start + (vy * pitch) + vx;
|
||||
P* pnew = ((P*)newframe) + block->start;;
|
||||
for (int y=0;y<block->dy;y++) {
|
||||
for (int x=0;x<block->dx;x++) {
|
||||
for (int y = 0; y < block->dy; y++)
|
||||
{
|
||||
for (int x = 0; x < block->dx; x++)
|
||||
{
|
||||
int test = 0 - ((pold[x] - pnew[x]) & 0x00ffffff);
|
||||
ret -= (test >> 31);
|
||||
}
|
||||
|
@ -174,11 +202,14 @@ INLINE int ZmbvCodec::CompareBlock(int vx,int vy,FrameBlock * block) {
|
|||
}
|
||||
|
||||
template <class P>
|
||||
INLINE void ZmbvCodec::AddXorBlock(int vx,int vy,FrameBlock * block) {
|
||||
INLINE void ZmbvCodec::AddXorBlock(int vx, int vy, FrameBlock* block)
|
||||
{
|
||||
P* pold = ((P*)oldframe) + block->start + (vy * pitch) + vx;
|
||||
P* pnew = ((P*)newframe) + block->start;
|
||||
for (int y=0;y<block->dy;y++) {
|
||||
for (int x=0;x<block->dx;x++) {
|
||||
for (int y = 0; y < block->dy; y++)
|
||||
{
|
||||
for (int x = 0; x < block->dx; x++)
|
||||
{
|
||||
*((P*)&work[workUsed]) = pnew[x] ^ pold[x];
|
||||
workUsed += sizeof(P);
|
||||
}
|
||||
|
@ -188,24 +219,29 @@ INLINE void ZmbvCodec::AddXorBlock(int vx,int vy,FrameBlock * block) {
|
|||
}
|
||||
|
||||
template <class P>
|
||||
void ZmbvCodec::AddXorFrame(void) {
|
||||
void ZmbvCodec::AddXorFrame(void)
|
||||
{
|
||||
signed char* vectors = (signed char*)&work[workUsed];
|
||||
/* Align the following xor data on 4 byte boundary*/
|
||||
workUsed = (workUsed + blockcount * 2 + 3) & ~3;
|
||||
for (int b=0;b<blockcount;b++) {
|
||||
for (int b = 0; b < blockcount; b++)
|
||||
{
|
||||
FrameBlock* block = &blocks[b];
|
||||
int bestvx = 0;
|
||||
int bestvy = 0;
|
||||
int bestchange = CompareBlock<P>(0, 0, block);
|
||||
int possibles = 64;
|
||||
for (int v=0;v<VectorCount && possibles;v++) {
|
||||
for (int v = 0; v < VectorCount && possibles; v++)
|
||||
{
|
||||
if (bestchange < 4) break;
|
||||
int vx = VectorTable[v].x;
|
||||
int vy = VectorTable[v].y;
|
||||
if (PossibleBlock<P>(vx, vy, block) < 4) {
|
||||
if (PossibleBlock<P>(vx, vy, block) < 4)
|
||||
{
|
||||
possibles--;
|
||||
int testchange = CompareBlock<P>(vx, vy, block);
|
||||
if (testchange<bestchange) {
|
||||
if (testchange < bestchange)
|
||||
{
|
||||
bestchange = testchange;
|
||||
bestvx = vx;
|
||||
bestvy = vy;
|
||||
|
@ -214,14 +250,16 @@ void ZmbvCodec::AddXorFrame(void) {
|
|||
}
|
||||
vectors[b * 2 + 0] = (bestvx << 1);
|
||||
vectors[b * 2 + 1] = (bestvy << 1);
|
||||
if (bestchange) {
|
||||
if (bestchange)
|
||||
{
|
||||
vectors[b * 2 + 0] |= 1;
|
||||
AddXorBlock<P>(bestvx, bestvy, block);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool ZmbvCodec::SetupCompress( int _width, int _height, uint32_t compressionLevel ) {
|
||||
bool ZmbvCodec::SetupCompress(int _width, int _height, uint32_t compressionLevel)
|
||||
{
|
||||
width = _width;
|
||||
height = _height;
|
||||
pitch = _width + 2 * MAX_VECTOR;
|
||||
|
@ -237,7 +275,8 @@ bool ZmbvCodec::PrepareCompressFrame(int flags, zmbv_format_t _format, char * pa
|
|||
int i;
|
||||
unsigned char* firstByte;
|
||||
|
||||
if (_format != format) {
|
||||
if (_format != format)
|
||||
{
|
||||
if (!SetupBuffers(_format, 16, 16))
|
||||
return false;
|
||||
flags |= 1; //Force a keyframe
|
||||
|
@ -255,8 +294,10 @@ bool ZmbvCodec::PrepareCompressFrame(int flags, zmbv_format_t _format, char * pa
|
|||
firstByte = compressInfo.writeBuf;
|
||||
*firstByte = 0;
|
||||
//Reset the work buffer
|
||||
workUsed = 0;workPos = 0;
|
||||
if (flags & 1) {
|
||||
workUsed = 0;
|
||||
workPos = 0;
|
||||
if (flags & 1)
|
||||
{
|
||||
/* Make a keyframe */
|
||||
*firstByte |= Mask_KeyFrame;
|
||||
KeyframeHeader* header = (KeyframeHeader*)(compressInfo.writeBuf + compressInfo.writeDone);
|
||||
|
@ -268,13 +309,15 @@ bool ZmbvCodec::PrepareCompressFrame(int flags, zmbv_format_t _format, char * pa
|
|||
header->blockheight = 16;
|
||||
compressInfo.writeDone += sizeof(KeyframeHeader);
|
||||
/* Copy the new frame directly over */
|
||||
if (palsize) {
|
||||
if (palsize)
|
||||
{
|
||||
if (pal)
|
||||
memcpy(&palette, pal, sizeof(palette));
|
||||
else
|
||||
memset(&palette, 0, sizeof(palette));
|
||||
/* keyframes get the full palette */
|
||||
for (i=0;i<palsize;i++) {
|
||||
for (i = 0; i < palsize; i++)
|
||||
{
|
||||
work[workUsed++] = palette[i * 4 + 0];
|
||||
work[workUsed++] = palette[i * 4 + 1];
|
||||
work[workUsed++] = palette[i * 4 + 2];
|
||||
|
@ -282,10 +325,14 @@ bool ZmbvCodec::PrepareCompressFrame(int flags, zmbv_format_t _format, char * pa
|
|||
}
|
||||
/* Restart deflate */
|
||||
deflateReset(&zstream);
|
||||
} else {
|
||||
if (palsize && pal && memcmp(pal, palette, palsize * 4)) {
|
||||
}
|
||||
else
|
||||
{
|
||||
if (palsize && pal && memcmp(pal, palette, palsize * 4))
|
||||
{
|
||||
*firstByte |= Mask_DeltaPalette;
|
||||
for(i=0;i<palsize;i++) {
|
||||
for (i = 0; i < palsize; i++)
|
||||
{
|
||||
work[workUsed++] = palette[i * 4 + 0] ^ pal[i * 4 + 0];
|
||||
work[workUsed++] = palette[i * 4 + 1] ^ pal[i * 4 + 1];
|
||||
work[workUsed++] = palette[i * 4 + 2] ^ pal[i * 4 + 2];
|
||||
|
@ -302,28 +349,35 @@ void ZmbvCodec::CompressLines(int lineCount, void *lineData[])
|
|||
int lineWidth = width * pixelsize;
|
||||
int i = 0;
|
||||
unsigned char* destStart = newframe + pixelsize * (MAX_VECTOR + (compressInfo.linesDone + MAX_VECTOR) * pitch);
|
||||
while ( i < lineCount && (compressInfo.linesDone < height)) {
|
||||
while (i < lineCount && (compressInfo.linesDone < height))
|
||||
{
|
||||
memcpy(destStart, lineData[i], lineWidth);
|
||||
destStart += linePitch;
|
||||
i++; compressInfo.linesDone++;
|
||||
i++;
|
||||
compressInfo.linesDone++;
|
||||
}
|
||||
}
|
||||
|
||||
int ZmbvCodec::FinishCompressFrame(uint8_t** compressedData)
|
||||
{
|
||||
unsigned char firstByte = *compressInfo.writeBuf;
|
||||
if (firstByte & Mask_KeyFrame) {
|
||||
if (firstByte & Mask_KeyFrame)
|
||||
{
|
||||
int i;
|
||||
/* Add the full frame data */
|
||||
unsigned char* readFrame = newframe + pixelsize * (MAX_VECTOR + MAX_VECTOR * pitch);
|
||||
for (i=0;i<height;i++) {
|
||||
for (i = 0; i < height; i++)
|
||||
{
|
||||
memcpy(&work[workUsed], readFrame, width * pixelsize);
|
||||
readFrame += pitch * pixelsize;
|
||||
workUsed += width * pixelsize;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Add the delta frame data */
|
||||
switch (format) {
|
||||
switch (format)
|
||||
{
|
||||
case ZMBV_FORMAT_8BPP:
|
||||
AddXorFrame<int8_t>();
|
||||
break;
|
||||
|
@ -380,11 +434,13 @@ ZmbvCodec::ZmbvCodec()
|
|||
|
||||
int ZmbvCodec::CompressFrame(bool isKeyFrame, uint8_t* frameData, uint8_t** compressedData)
|
||||
{
|
||||
if(!PrepareCompressFrame(isKeyFrame ? 1 : 0, ZMBV_FORMAT_32BPP, nullptr)) {
|
||||
if (!PrepareCompressFrame(isKeyFrame ? 1 : 0, ZMBV_FORMAT_32BPP, nullptr))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
for(int i = 0; i < height; i++) {
|
||||
for (int i = 0; i < height; i++)
|
||||
{
|
||||
void* rowPointer = frameData + i * width * 4;
|
||||
CompressLines(1, &rowPointer);
|
||||
}
|
||||
|
|
|
@ -30,7 +30,8 @@
|
|||
#define INLINE inline
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
typedef enum
|
||||
{
|
||||
ZMBV_FORMAT_NONE = 0x00,
|
||||
ZMBV_FORMAT_1BPP = 0x01,
|
||||
ZMBV_FORMAT_2BPP = 0x02,
|
||||
|
@ -45,15 +46,20 @@ typedef enum {
|
|||
class ZmbvCodec : public BaseCodec
|
||||
{
|
||||
private:
|
||||
struct FrameBlock {
|
||||
struct FrameBlock
|
||||
{
|
||||
int start = 0;
|
||||
int dx = 0, dy = 0;
|
||||
};
|
||||
struct CodecVector {
|
||||
|
||||
struct CodecVector
|
||||
{
|
||||
int x = 0, y = 0;
|
||||
int slot = 0;
|
||||
};
|
||||
struct KeyframeHeader {
|
||||
|
||||
struct KeyframeHeader
|
||||
{
|
||||
unsigned char high_version = 0;
|
||||
unsigned char low_version = 0;
|
||||
unsigned char compression = 0;
|
||||
|
@ -61,7 +67,8 @@ private:
|
|||
unsigned char blockwidth = 0, blockheight = 0;
|
||||
};
|
||||
|
||||
struct {
|
||||
struct
|
||||
{
|
||||
int linesDone = 0;
|
||||
int writeSize = 0;
|
||||
int writeDone = 0;
|
||||
|
@ -96,10 +103,14 @@ private:
|
|||
void CreateVectorTable(void);
|
||||
bool SetupBuffers(zmbv_format_t format, int blockwidth, int blockheight);
|
||||
|
||||
template<class P> void AddXorFrame(void);
|
||||
template<class P> INLINE int PossibleBlock(int vx,int vy,FrameBlock * block);
|
||||
template<class P> INLINE int CompareBlock(int vx,int vy,FrameBlock * block);
|
||||
template<class P> INLINE void AddXorBlock(int vx,int vy,FrameBlock * block);
|
||||
template <class P>
|
||||
void AddXorFrame(void);
|
||||
template <class P>
|
||||
INLINE int PossibleBlock(int vx, int vy, FrameBlock* block);
|
||||
template <class P>
|
||||
INLINE int CompareBlock(int vx, int vy, FrameBlock* block);
|
||||
template <class P>
|
||||
INLINE void AddXorBlock(int vx, int vy, FrameBlock* block);
|
||||
|
||||
int NeededSize(int _width, int _height, zmbv_format_t _format);
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@ Avoids constants that don't fit in 32 bits. */
|
|||
|
||||
#elif defined(ULLONG_MAX)
|
||||
typedef unsigned long long fixed_t;
|
||||
|
||||
enum { pre_shift = 32 };
|
||||
|
||||
#else
|
||||
|
@ -47,11 +48,17 @@ enum { bass_shift = 9 }; /* affects high-pass filter breakpoint frequency */
|
|||
enum { end_frame_extra = 2 }; /* allows deltas slightly after frame length */
|
||||
|
||||
enum { half_width = 8 };
|
||||
|
||||
enum { buf_extra = half_width * 2 + end_frame_extra };
|
||||
|
||||
enum { phase_bits = 5 };
|
||||
|
||||
enum { phase_count = 1 << phase_bits };
|
||||
|
||||
enum { delta_bits = 15 };
|
||||
|
||||
enum { delta_unit = 1 << delta_bits };
|
||||
|
||||
enum { frac_bits = time_bits - pre_shift };
|
||||
|
||||
/* We could eliminate avail and encode whole samples in offset, but that would
|
||||
|
@ -80,6 +87,7 @@ typedef int buf_t;
|
|||
((n) >> (shift))
|
||||
|
||||
enum { max_sample = +32767 };
|
||||
|
||||
enum { min_sample = -32768 };
|
||||
|
||||
#define CLAMP( n ) \
|
||||
|
|
|
@ -31,9 +31,12 @@ EXPORT blip_t* blip_new( int sample_count );
|
|||
clock_rate input clocks, approximately sample_rate samples are generated. */
|
||||
EXPORT void blip_set_rates(blip_t*, double clock_rate, double sample_rate);
|
||||
|
||||
enum { /** Maximum clock_rate/sample_rate ratio. For a given sample_rate,
|
||||
enum
|
||||
{
|
||||
/** Maximum clock_rate/sample_rate ratio. For a given sample_rate,
|
||||
clock_rate must not be greater than sample_rate*blip_max_ratio. */
|
||||
blip_max_ratio = 1 << 20 };
|
||||
blip_max_ratio = 1 << 20
|
||||
};
|
||||
|
||||
/** Clears entire buffer. Afterwards, blip_samples_avail() == 0. */
|
||||
EXPORT void blip_clear(blip_t*);
|
||||
|
@ -48,8 +51,11 @@ void blip_add_delta_fast( blip_t*, unsigned int clock_time, int delta );
|
|||
samples available. */
|
||||
int blip_clocks_needed(const blip_t*, int sample_count);
|
||||
|
||||
enum { /** Maximum number of samples that can be generated from one time frame. */
|
||||
blip_max_frame = 4000 };
|
||||
enum
|
||||
{
|
||||
/** Maximum number of samples that can be generated from one time frame. */
|
||||
blip_max_frame = 4000
|
||||
};
|
||||
|
||||
/** Makes input clocks before clock_duration available for reading as output
|
||||
samples. Also begins new time frame at clock_duration, so that clock time 0 in
|
||||
|
|
|
@ -109,7 +109,10 @@ void GifGetClosestPaletteColor(GifPalette* pPal, int r, int g, int b, int& bestI
|
|||
}
|
||||
|
||||
// take the appropriate color (r, g, or b) for this node of the k-d tree
|
||||
int comps[3]; comps[0] = r; comps[1] = g; comps[2] = b;
|
||||
int comps[3];
|
||||
comps[0] = r;
|
||||
comps[1] = g;
|
||||
comps[2] = b;
|
||||
int splitComp = comps[pPal->treeSplitElt[treeRoot]];
|
||||
|
||||
int splitPos = pPal->treeSplit[treeRoot];
|
||||
|
@ -204,7 +207,8 @@ void GifPartitionByMedian(uint8_t* image, int left, int right, int com, int need
|
|||
}
|
||||
|
||||
// Builds a palette by creating a balanced k-d tree of all pixels in the image
|
||||
void GifSplitPalette(uint8_t* image, int numPixels, int firstElt, int lastElt, int splitElt, int splitDist, int treeNode, bool buildForDither, GifPalette* pal)
|
||||
void GifSplitPalette(uint8_t* image, int numPixels, int firstElt, int lastElt, int splitElt, int splitDist,
|
||||
int treeNode, bool buildForDither, GifPalette* pal)
|
||||
{
|
||||
if (lastElt <= firstElt || numPixels == 0)
|
||||
return;
|
||||
|
@ -315,8 +319,10 @@ void GifSplitPalette(uint8_t* image, int numPixels, int firstElt, int lastElt, i
|
|||
pal->treeSplitElt[treeNode] = (uint8_t)splitCom;
|
||||
pal->treeSplit[treeNode] = image[subPixelsA * 4 + splitCom];
|
||||
|
||||
GifSplitPalette(image, subPixelsA, firstElt, splitElt, splitElt-splitDist, splitDist/2, treeNode*2, buildForDither, pal);
|
||||
GifSplitPalette(image+subPixelsA*4, subPixelsB, splitElt, lastElt, splitElt+splitDist, splitDist/2, treeNode*2+1, buildForDither, pal);
|
||||
GifSplitPalette(image, subPixelsA, firstElt, splitElt, splitElt - splitDist, splitDist / 2, treeNode * 2,
|
||||
buildForDither, pal);
|
||||
GifSplitPalette(image + subPixelsA * 4, subPixelsB, splitElt, lastElt, splitElt + splitDist, splitDist / 2,
|
||||
treeNode * 2 + 1, buildForDither, pal);
|
||||
}
|
||||
|
||||
// Finds all pixels that have changed from the previous image and
|
||||
|
@ -349,7 +355,8 @@ int GifPickChangedPixels( const uint8_t* lastFrame, uint8_t* frame, int numPixel
|
|||
|
||||
// Creates a palette by placing all the image pixels in a k-d tree and then averaging the blocks at the bottom.
|
||||
// This is known as the "modified median split" technique
|
||||
void GifMakePalette( const uint8_t* lastFrame, const uint8_t* nextFrame, uint32_t width, uint32_t height, int bitDepth, bool buildForDither, GifPalette* pPal )
|
||||
void GifMakePalette(const uint8_t* lastFrame, const uint8_t* nextFrame, uint32_t width, uint32_t height, int bitDepth,
|
||||
bool buildForDither, GifPalette* pPal)
|
||||
{
|
||||
pPal->bitDepth = bitDepth;
|
||||
|
||||
|
@ -380,7 +387,8 @@ void GifMakePalette( const uint8_t* lastFrame, const uint8_t* nextFrame, uint32_
|
|||
}
|
||||
|
||||
// Implements Floyd-Steinberg dithering, writes palette value to alpha
|
||||
void GifDitherImage( const uint8_t* lastFrame, const uint8_t* nextFrame, uint8_t* outFrame, uint32_t width, uint32_t height, GifPalette* pPal )
|
||||
void GifDitherImage(const uint8_t* lastFrame, const uint8_t* nextFrame, uint8_t* outFrame, uint32_t width,
|
||||
uint32_t height, GifPalette* pPal)
|
||||
{
|
||||
int numPixels = (int)(width * height);
|
||||
|
||||
|
@ -489,7 +497,8 @@ void GifDitherImage( const uint8_t* lastFrame, const uint8_t* nextFrame, uint8_t
|
|||
}
|
||||
|
||||
// Picks palette colors for the image using simple thresholding, no dithering
|
||||
void GifThresholdImage( const uint8_t* lastFrame, const uint8_t* nextFrame, uint8_t* outFrame, uint32_t width, uint32_t height, GifPalette* pPal )
|
||||
void GifThresholdImage(const uint8_t* lastFrame, const uint8_t* nextFrame, uint8_t* outFrame, uint32_t width,
|
||||
uint32_t height, GifPalette* pPal)
|
||||
{
|
||||
uint32_t numPixels = width * height;
|
||||
for (uint32_t ii = 0; ii < numPixels; ++ii)
|
||||
|
@ -607,7 +616,8 @@ void GifWritePalette( const GifPalette* pPal, FILE* f )
|
|||
}
|
||||
|
||||
// write the image header, LZW-compress and write out the image
|
||||
void GifWriteLzwImage(FILE* f, uint8_t* image, uint32_t left, uint32_t top, uint32_t width, uint32_t height, uint32_t delay, GifPalette* pPal)
|
||||
void GifWriteLzwImage(FILE* f, uint8_t* image, uint32_t left, uint32_t top, uint32_t width, uint32_t height,
|
||||
uint32_t delay, GifPalette* pPal)
|
||||
{
|
||||
// graphics control extension
|
||||
fputc(0x21, f);
|
||||
|
@ -735,9 +745,11 @@ struct GifWriter
|
|||
// Creates a gif file.
|
||||
// The input GIFWriter is assumed to be uninitialized.
|
||||
// The delay value is the time between frames in hundredths of a second - note that not all viewers pay much attention to this value.
|
||||
bool GifBegin( GifWriter* writer, const char* filename, uint32_t width, uint32_t height, uint32_t delay, int32_t bitDepth = 8, bool dither = false )
|
||||
bool GifBegin(GifWriter* writer, const char* filename, uint32_t width, uint32_t height, uint32_t delay,
|
||||
int32_t bitDepth = 8, bool dither = false)
|
||||
{
|
||||
(void)bitDepth; (void)dither; // Mute "Unused argument" warnings
|
||||
(void)bitDepth;
|
||||
(void)dither; // Mute "Unused argument" warnings
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
|
||||
writer->f = 0;
|
||||
fopen_s(&writer->f, filename, "wb");
|
||||
|
@ -796,7 +808,8 @@ bool GifBegin( GifWriter* writer, const char* filename, uint32_t width, uint32_t
|
|||
// The GIFWriter should have been created by GIFBegin.
|
||||
// AFAIK, it is legal to use different bit depths for different frames of an image -
|
||||
// this may be handy to save bits in animations that don't change much.
|
||||
bool GifWriteFrame( GifWriter* writer, const uint8_t* image, uint32_t width, uint32_t height, uint32_t delay, int bitDepth = 8, bool dither = false )
|
||||
bool GifWriteFrame(GifWriter* writer, const uint8_t* image, uint32_t width, uint32_t height, uint32_t delay,
|
||||
int bitDepth = 8, bool dither = false)
|
||||
{
|
||||
if (!writer->f) return false;
|
||||
|
||||
|
|
|
@ -103,7 +103,8 @@ static const void *body(MD5_CTX *ctx, const void *data, unsigned long size)
|
|||
c = ctx->c;
|
||||
d = ctx->d;
|
||||
|
||||
do {
|
||||
do
|
||||
{
|
||||
saved_a = a;
|
||||
saved_b = b;
|
||||
saved_c = c;
|
||||
|
@ -187,7 +188,8 @@ static const void *body(MD5_CTX *ctx, const void *data, unsigned long size)
|
|||
d += saved_d;
|
||||
|
||||
ptr += 64;
|
||||
} while (size -= 64);
|
||||
}
|
||||
while (size -= 64);
|
||||
|
||||
ctx->a = a;
|
||||
ctx->b = b;
|
||||
|
@ -220,10 +222,12 @@ void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size)
|
|||
|
||||
used = saved_lo & 0x3f;
|
||||
|
||||
if (used) {
|
||||
if (used)
|
||||
{
|
||||
available = 64 - used;
|
||||
|
||||
if (size < available) {
|
||||
if (size < available)
|
||||
{
|
||||
memcpy(&ctx->buffer[used], data, size);
|
||||
return;
|
||||
}
|
||||
|
@ -234,7 +238,8 @@ void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size)
|
|||
body(ctx, ctx->buffer, 64);
|
||||
}
|
||||
|
||||
if (size >= 64) {
|
||||
if (size >= 64)
|
||||
{
|
||||
data = body(ctx, data, size & ~(unsigned long)0x3f);
|
||||
size &= 0x3f;
|
||||
}
|
||||
|
@ -252,7 +257,8 @@ void MD5_Final(unsigned char *result, MD5_CTX *ctx)
|
|||
|
||||
available = 64 - used;
|
||||
|
||||
if (available < 8) {
|
||||
if (available < 8)
|
||||
{
|
||||
memset(&ctx->buffer[used], 0, available);
|
||||
body(ctx, ctx->buffer, 64);
|
||||
used = 0;
|
||||
|
@ -308,7 +314,8 @@ string GetMd5Sum(void* buffer, size_t size)
|
|||
|
||||
std::stringstream ss;
|
||||
ss << std::hex << std::uppercase << std::setfill('0');
|
||||
for(int i = 0; i < 16; i++) {
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
ss << std::setw(2) << (int)result[i];
|
||||
}
|
||||
return ss.str();
|
||||
|
|
|
@ -28,7 +28,8 @@
|
|||
/* Any 32-bit or wider unsigned integer data type will do */
|
||||
typedef unsigned int MD5_u32plus;
|
||||
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
MD5_u32plus lo, hi;
|
||||
MD5_u32plus a, b, c, d;
|
||||
unsigned char buffer[64];
|
||||
|
|
1721
Utilities/miniz.cpp
1721
Utilities/miniz.cpp
File diff suppressed because it is too large
Load diff
|
@ -267,10 +267,30 @@ typedef void *(*mz_realloc_func)(void *opaque, void *address, size_t items, size
|
|||
enum { MZ_NO_FLUSH = 0, MZ_PARTIAL_FLUSH = 1, MZ_SYNC_FLUSH = 2, MZ_FULL_FLUSH = 3, MZ_FINISH = 4, MZ_BLOCK = 5 };
|
||||
|
||||
// Return status codes. MZ_PARAM_ERROR is non-standard.
|
||||
enum { MZ_OK = 0, MZ_STREAM_END = 1, MZ_NEED_DICT = 2, MZ_ERRNO = -1, MZ_STREAM_ERROR = -2, MZ_DATA_ERROR = -3, MZ_MEM_ERROR = -4, MZ_BUF_ERROR = -5, MZ_VERSION_ERROR = -6, MZ_PARAM_ERROR = -10000 };
|
||||
enum
|
||||
{
|
||||
MZ_OK = 0,
|
||||
MZ_STREAM_END = 1,
|
||||
MZ_NEED_DICT = 2,
|
||||
MZ_ERRNO = -1,
|
||||
MZ_STREAM_ERROR = -2,
|
||||
MZ_DATA_ERROR = -3,
|
||||
MZ_MEM_ERROR = -4,
|
||||
MZ_BUF_ERROR = -5,
|
||||
MZ_VERSION_ERROR = -6,
|
||||
MZ_PARAM_ERROR = -10000
|
||||
};
|
||||
|
||||
// Compression levels: 0-9 are the standard zlib-style levels, 10 is best possible compression (not zlib compatible, and may be very slow), MZ_DEFAULT_COMPRESSION=MZ_DEFAULT_LEVEL.
|
||||
enum { MZ_NO_COMPRESSION = 0, MZ_BEST_SPEED = 1, MZ_BEST_COMPRESSION = 9, MZ_UBER_COMPRESSION = 10, MZ_DEFAULT_LEVEL = 6, MZ_DEFAULT_COMPRESSION = -1 };
|
||||
enum
|
||||
{
|
||||
MZ_NO_COMPRESSION = 0,
|
||||
MZ_BEST_SPEED = 1,
|
||||
MZ_BEST_COMPRESSION = 9,
|
||||
MZ_UBER_COMPRESSION = 10,
|
||||
MZ_DEFAULT_LEVEL = 6,
|
||||
MZ_DEFAULT_COMPRESSION = -1
|
||||
};
|
||||
|
||||
// Window bits
|
||||
#define MZ_DEFAULT_WINDOW_BITS 15
|
||||
|
@ -352,7 +372,8 @@ mz_ulong mz_deflateBound(mz_streamp pStream, mz_ulong source_len);
|
|||
// Single-call compression functions mz_compress() and mz_compress2():
|
||||
// Returns MZ_OK on success, or one of the error codes from mz_deflate() on failure.
|
||||
int mz_compress(unsigned char* pDest, mz_ulong* pDest_len, const unsigned char* pSource, mz_ulong source_len);
|
||||
int mz_compress2(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len, int level);
|
||||
int mz_compress2(unsigned char* pDest, mz_ulong* pDest_len, const unsigned char* pSource, mz_ulong source_len,
|
||||
int level);
|
||||
|
||||
// mz_compressBound() returns a (very) conservative upper bound on the amount of data that could be generated by calling mz_compress().
|
||||
mz_ulong mz_compressBound(mz_ulong source_len);
|
||||
|
@ -554,7 +575,6 @@ typedef struct mz_zip_archive_tag
|
|||
void* m_pIO_opaque;
|
||||
|
||||
mz_zip_internal_state* m_pState;
|
||||
|
||||
} mz_zip_archive;
|
||||
|
||||
typedef enum
|
||||
|
@ -588,7 +608,8 @@ mz_bool mz_zip_reader_is_file_encrypted(mz_zip_archive *pZip, mz_uint file_index
|
|||
|
||||
// Retrieves the filename of an archive file entry.
|
||||
// Returns the number of bytes written to pFilename, or if filename_buf_size is 0 this function returns the number of bytes needed to fully store the filename.
|
||||
mz_uint mz_zip_reader_get_filename(mz_zip_archive *pZip, mz_uint file_index, char *pFilename, mz_uint filename_buf_size);
|
||||
mz_uint mz_zip_reader_get_filename(mz_zip_archive* pZip, mz_uint file_index, char* pFilename,
|
||||
mz_uint filename_buf_size);
|
||||
|
||||
// Attempts to locates a file in the archive's central directory.
|
||||
// Valid flags: MZ_ZIP_FLAG_CASE_SENSITIVE, MZ_ZIP_FLAG_IGNORE_PATH
|
||||
|
@ -596,26 +617,35 @@ mz_uint mz_zip_reader_get_filename(mz_zip_archive *pZip, mz_uint file_index, cha
|
|||
int mz_zip_reader_locate_file(mz_zip_archive* pZip, const char* pName, const char* pComment, mz_uint flags);
|
||||
|
||||
// Extracts a archive file to a memory buffer using no memory allocation.
|
||||
mz_bool mz_zip_reader_extract_to_mem_no_alloc(mz_zip_archive *pZip, mz_uint file_index, void *pBuf, size_t buf_size, mz_uint flags, void *pUser_read_buf, size_t user_read_buf_size);
|
||||
mz_bool mz_zip_reader_extract_file_to_mem_no_alloc(mz_zip_archive *pZip, const char *pFilename, void *pBuf, size_t buf_size, mz_uint flags, void *pUser_read_buf, size_t user_read_buf_size);
|
||||
mz_bool mz_zip_reader_extract_to_mem_no_alloc(mz_zip_archive* pZip, mz_uint file_index, void* pBuf, size_t buf_size,
|
||||
mz_uint flags, void* pUser_read_buf, size_t user_read_buf_size);
|
||||
mz_bool mz_zip_reader_extract_file_to_mem_no_alloc(mz_zip_archive* pZip, const char* pFilename, void* pBuf,
|
||||
size_t buf_size, mz_uint flags, void* pUser_read_buf,
|
||||
size_t user_read_buf_size);
|
||||
|
||||
// Extracts a archive file to a memory buffer.
|
||||
mz_bool mz_zip_reader_extract_to_mem(mz_zip_archive *pZip, mz_uint file_index, void *pBuf, size_t buf_size, mz_uint flags);
|
||||
mz_bool mz_zip_reader_extract_file_to_mem(mz_zip_archive *pZip, const char *pFilename, void *pBuf, size_t buf_size, mz_uint flags);
|
||||
mz_bool mz_zip_reader_extract_to_mem(mz_zip_archive* pZip, mz_uint file_index, void* pBuf, size_t buf_size,
|
||||
mz_uint flags);
|
||||
mz_bool mz_zip_reader_extract_file_to_mem(mz_zip_archive* pZip, const char* pFilename, void* pBuf, size_t buf_size,
|
||||
mz_uint flags);
|
||||
|
||||
// Extracts a archive file to a dynamically allocated heap buffer.
|
||||
void* mz_zip_reader_extract_to_heap(mz_zip_archive* pZip, mz_uint file_index, size_t* pSize, mz_uint flags);
|
||||
void* mz_zip_reader_extract_file_to_heap(mz_zip_archive* pZip, const char* pFilename, size_t* pSize, mz_uint flags);
|
||||
|
||||
// Extracts a archive file using a callback function to output the file's data.
|
||||
mz_bool mz_zip_reader_extract_to_callback(mz_zip_archive *pZip, mz_uint file_index, mz_file_write_func pCallback, void *pOpaque, mz_uint flags);
|
||||
mz_bool mz_zip_reader_extract_file_to_callback(mz_zip_archive *pZip, const char *pFilename, mz_file_write_func pCallback, void *pOpaque, mz_uint flags);
|
||||
mz_bool mz_zip_reader_extract_to_callback(mz_zip_archive* pZip, mz_uint file_index, mz_file_write_func pCallback,
|
||||
void* pOpaque, mz_uint flags);
|
||||
mz_bool mz_zip_reader_extract_file_to_callback(mz_zip_archive* pZip, const char* pFilename,
|
||||
mz_file_write_func pCallback, void* pOpaque, mz_uint flags);
|
||||
|
||||
#ifndef MINIZ_NO_STDIO
|
||||
// Extracts a archive file to a disk file and sets its last accessed and modified times.
|
||||
// This function only extracts files, not archive directory records.
|
||||
mz_bool mz_zip_reader_extract_to_file(mz_zip_archive *pZip, mz_uint file_index, const char *pDst_filename, mz_uint flags);
|
||||
mz_bool mz_zip_reader_extract_file_to_file(mz_zip_archive *pZip, const char *pArchive_filename, const char *pDst_filename, mz_uint flags);
|
||||
mz_bool mz_zip_reader_extract_to_file(mz_zip_archive* pZip, mz_uint file_index, const char* pDst_filename,
|
||||
mz_uint flags);
|
||||
mz_bool mz_zip_reader_extract_file_to_file(mz_zip_archive* pZip, const char* pArchive_filename,
|
||||
const char* pDst_filename, mz_uint flags);
|
||||
#endif
|
||||
|
||||
// Ends archive reading, freeing all allocations, and closing the input archive file if mz_zip_reader_init_file() was used.
|
||||
|
@ -627,7 +657,8 @@ mz_bool mz_zip_reader_end(mz_zip_archive *pZip);
|
|||
|
||||
// Inits a ZIP archive writer.
|
||||
mz_bool mz_zip_writer_init(mz_zip_archive* pZip, mz_uint64 existing_size);
|
||||
mz_bool mz_zip_writer_init_heap(mz_zip_archive *pZip, size_t size_to_reserve_at_beginning, size_t initial_allocation_size);
|
||||
mz_bool mz_zip_writer_init_heap(mz_zip_archive* pZip, size_t size_to_reserve_at_beginning,
|
||||
size_t initial_allocation_size);
|
||||
|
||||
#ifndef MINIZ_NO_STDIO
|
||||
mz_bool mz_zip_writer_init_file(mz_zip_archive* pZip, const char* pFilename, mz_uint64 size_to_reserve_at_beginning);
|
||||
|
@ -644,13 +675,17 @@ mz_bool mz_zip_writer_init_from_reader(mz_zip_archive *pZip, const char *pFilena
|
|||
// Adds the contents of a memory buffer to an archive. These functions record the current local time into the archive.
|
||||
// To add a directory entry, call this method with an archive name ending in a forwardslash with empty buffer.
|
||||
// level_and_flags - compression level (0-10, see MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc.) logically OR'd with zero or more mz_zip_flags, or just set to MZ_DEFAULT_COMPRESSION.
|
||||
mz_bool mz_zip_writer_add_mem(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, mz_uint level_and_flags);
|
||||
mz_bool mz_zip_writer_add_mem_ex(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, mz_uint64 uncomp_size, mz_uint32 uncomp_crc32);
|
||||
mz_bool mz_zip_writer_add_mem(mz_zip_archive* pZip, const char* pArchive_name, const void* pBuf, size_t buf_size,
|
||||
mz_uint level_and_flags);
|
||||
mz_bool mz_zip_writer_add_mem_ex(mz_zip_archive* pZip, const char* pArchive_name, const void* pBuf, size_t buf_size,
|
||||
const void* pComment, mz_uint16 comment_size, mz_uint level_and_flags,
|
||||
mz_uint64 uncomp_size, mz_uint32 uncomp_crc32);
|
||||
|
||||
#ifndef MINIZ_NO_STDIO
|
||||
// Adds the contents of a disk file to an archive. This function also records the disk file's modified time into the archive.
|
||||
// level_and_flags - compression level (0-10, see MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc.) logically OR'd with zero or more mz_zip_flags, or just set to MZ_DEFAULT_COMPRESSION.
|
||||
mz_bool mz_zip_writer_add_file(mz_zip_archive *pZip, const char *pArchive_name, const char *pSrc_filename, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags);
|
||||
mz_bool mz_zip_writer_add_file(mz_zip_archive* pZip, const char* pArchive_name, const char* pSrc_filename,
|
||||
const void* pComment, mz_uint16 comment_size, mz_uint level_and_flags);
|
||||
#endif
|
||||
|
||||
// Adds a file to an archive by fully cloning the data from another archive.
|
||||
|
@ -671,11 +706,14 @@ mz_bool mz_zip_writer_end(mz_zip_archive *pZip);
|
|||
|
||||
// mz_zip_add_mem_to_archive_file_in_place() efficiently (but not atomically) appends a memory blob to a ZIP archive.
|
||||
// level_and_flags - compression level (0-10, see MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc.) logically OR'd with zero or more mz_zip_flags, or just set to MZ_DEFAULT_COMPRESSION.
|
||||
mz_bool mz_zip_add_mem_to_archive_file_in_place(const char *pZip_filename, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags);
|
||||
mz_bool mz_zip_add_mem_to_archive_file_in_place(const char* pZip_filename, const char* pArchive_name, const void* pBuf,
|
||||
size_t buf_size, const void* pComment, mz_uint16 comment_size,
|
||||
mz_uint level_and_flags);
|
||||
|
||||
// Reads a single file from an archive into a heap block.
|
||||
// Returns NULL on failure.
|
||||
void *mz_zip_extract_archive_file_to_heap(const char *pZip_filename, const char *pArchive_name, size_t *pSize, mz_uint zip_flags);
|
||||
void* mz_zip_extract_archive_file_to_heap(const char* pZip_filename, const char* pArchive_name, size_t* pSize,
|
||||
mz_uint zip_flags);
|
||||
|
||||
#endif // #ifndef MINIZ_NO_ARCHIVE_WRITING_APIS
|
||||
|
||||
|
@ -709,14 +747,17 @@ void *tinfl_decompress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, siz
|
|||
// tinfl_decompress_mem_to_mem() decompresses a block in memory to another block in memory.
|
||||
// Returns TINFL_DECOMPRESS_MEM_TO_MEM_FAILED on failure, or the number of bytes written on success.
|
||||
#define TINFL_DECOMPRESS_MEM_TO_MEM_FAILED ((size_t)(-1))
|
||||
size_t tinfl_decompress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void *pSrc_buf, size_t src_buf_len, int flags);
|
||||
size_t tinfl_decompress_mem_to_mem(void* pOut_buf, size_t out_buf_len, const void* pSrc_buf, size_t src_buf_len,
|
||||
int flags);
|
||||
|
||||
// tinfl_decompress_mem_to_callback() decompresses a block in memory to an internal 32KB buffer, and a user provided callback function will be called to flush the buffer.
|
||||
// Returns 1 on success or 0 on failure.
|
||||
typedef int (*tinfl_put_buf_func_ptr)(const void* pBuf, int len, void* pUser);
|
||||
int tinfl_decompress_mem_to_callback(const void *pIn_buf, size_t *pIn_buf_size, tinfl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags);
|
||||
int tinfl_decompress_mem_to_callback(const void* pIn_buf, size_t* pIn_buf_size, tinfl_put_buf_func_ptr pPut_buf_func,
|
||||
void* pPut_buf_user, int flags);
|
||||
|
||||
struct tinfl_decompressor_tag; typedef struct tinfl_decompressor_tag tinfl_decompressor;
|
||||
struct tinfl_decompressor_tag;
|
||||
typedef struct tinfl_decompressor_tag tinfl_decompressor;
|
||||
|
||||
// Max size of LZ dictionary.
|
||||
#define TINFL_LZ_DICT_SIZE 32768
|
||||
|
@ -738,13 +779,19 @@ typedef enum
|
|||
|
||||
// Main low-level decompressor coroutine function. This is the only function actually needed for decompression. All the other functions are just high-level helpers for improved usability.
|
||||
// This is a universal API, i.e. it can be used as a building block to build any desired higher level decompression API. In the limit case, it can be called once per every byte input or output.
|
||||
tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_next, size_t *pIn_buf_size, mz_uint8 *pOut_buf_start, mz_uint8 *pOut_buf_next, size_t *pOut_buf_size, const mz_uint32 decomp_flags);
|
||||
tinfl_status tinfl_decompress(tinfl_decompressor* r, const mz_uint8* pIn_buf_next, size_t* pIn_buf_size,
|
||||
mz_uint8* pOut_buf_start, mz_uint8* pOut_buf_next, size_t* pOut_buf_size,
|
||||
const mz_uint32 decomp_flags);
|
||||
|
||||
// Internal/private bits follow.
|
||||
enum
|
||||
{
|
||||
TINFL_MAX_HUFF_TABLES = 3, TINFL_MAX_HUFF_SYMBOLS_0 = 288, TINFL_MAX_HUFF_SYMBOLS_1 = 32, TINFL_MAX_HUFF_SYMBOLS_2 = 19,
|
||||
TINFL_FAST_LOOKUP_BITS = 10, TINFL_FAST_LOOKUP_SIZE = 1 << TINFL_FAST_LOOKUP_BITS
|
||||
TINFL_MAX_HUFF_TABLES = 3,
|
||||
TINFL_MAX_HUFF_SYMBOLS_0 = 288,
|
||||
TINFL_MAX_HUFF_SYMBOLS_1 = 32,
|
||||
TINFL_MAX_HUFF_SYMBOLS_2 = 19,
|
||||
TINFL_FAST_LOOKUP_BITS = 10,
|
||||
TINFL_FAST_LOOKUP_SIZE = 1 << TINFL_FAST_LOOKUP_BITS
|
||||
};
|
||||
|
||||
typedef struct
|
||||
|
@ -767,7 +814,8 @@ typedef struct
|
|||
|
||||
struct tinfl_decompressor_tag
|
||||
{
|
||||
mz_uint32 m_state, m_num_bits, m_zhdr0, m_zhdr1, m_z_adler32, m_final, m_type, m_check_adler32, m_dist, m_counter, m_num_extra, m_table_sizes[TINFL_MAX_HUFF_TABLES];
|
||||
mz_uint32 m_state, m_num_bits, m_zhdr0, m_zhdr1, m_z_adler32, m_final, m_type, m_check_adler32, m_dist, m_counter,
|
||||
m_num_extra, m_table_sizes[TINFL_MAX_HUFF_TABLES];
|
||||
tinfl_bit_buf_t m_bit_buf;
|
||||
size_t m_dist_from_out_buf_start;
|
||||
tinfl_huff_table m_tables[TINFL_MAX_HUFF_TABLES];
|
||||
|
@ -783,7 +831,9 @@ struct tinfl_decompressor_tag
|
|||
// TDEFL_DEFAULT_MAX_PROBES: The compressor defaults to 128 dictionary probes per dictionary search. 0=Huffman only, 1=Huffman+LZ (fastest/crap compression), 4095=Huffman+LZ (slowest/best compression).
|
||||
enum
|
||||
{
|
||||
TDEFL_HUFFMAN_ONLY = 0, TDEFL_DEFAULT_MAX_PROBES = 128, TDEFL_MAX_PROBES_MASK = 0xFFF
|
||||
TDEFL_HUFFMAN_ONLY = 0,
|
||||
TDEFL_DEFAULT_MAX_PROBES = 128,
|
||||
TDEFL_MAX_PROBES_MASK = 0xFFF
|
||||
};
|
||||
|
||||
// TDEFL_WRITE_ZLIB_HEADER: If set, the compressor outputs a zlib header before the deflate data, and the Adler-32 of the source data at the end. Otherwise, you'll get raw deflate data.
|
||||
|
@ -820,7 +870,8 @@ void *tdefl_compress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_
|
|||
|
||||
// tdefl_compress_mem_to_mem() compresses a block in memory to another block in memory.
|
||||
// Returns 0 on failure.
|
||||
size_t tdefl_compress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void *pSrc_buf, size_t src_buf_len, int flags);
|
||||
size_t tdefl_compress_mem_to_mem(void* pOut_buf, size_t out_buf_len, const void* pSrc_buf, size_t src_buf_len,
|
||||
int flags);
|
||||
|
||||
// Compresses an image to a compressed PNG file in memory.
|
||||
// On entry:
|
||||
|
@ -832,22 +883,43 @@ size_t tdefl_compress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void
|
|||
// Function returns a pointer to the compressed data, or NULL on failure.
|
||||
// *pLen_out will be set to the size of the PNG image file.
|
||||
// The caller must mz_free() the returned heap block (which will typically be larger than *pLen_out) when it's no longer needed.
|
||||
void *tdefl_write_image_to_png_file_in_memory_ex(const void *pImage, int w, int h, int num_chans, size_t *pLen_out, mz_uint level, mz_bool flip);
|
||||
void* tdefl_write_image_to_png_file_in_memory_ex(const void* pImage, int w, int h, int num_chans, size_t* pLen_out,
|
||||
mz_uint level, mz_bool flip);
|
||||
void* tdefl_write_image_to_png_file_in_memory(const void* pImage, int w, int h, int num_chans, size_t* pLen_out);
|
||||
|
||||
// Output stream interface. The compressor uses this interface to write compressed data. It'll typically be called TDEFL_OUT_BUF_SIZE at a time.
|
||||
typedef mz_bool (*tdefl_put_buf_func_ptr)(const void* pBuf, int len, void* pUser);
|
||||
|
||||
// tdefl_compress_mem_to_output() compresses a block to an output stream. The above helpers use this function internally.
|
||||
mz_bool tdefl_compress_mem_to_output(const void *pBuf, size_t buf_len, tdefl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags);
|
||||
mz_bool tdefl_compress_mem_to_output(const void* pBuf, size_t buf_len, tdefl_put_buf_func_ptr pPut_buf_func,
|
||||
void* pPut_buf_user, int flags);
|
||||
|
||||
enum { TDEFL_MAX_HUFF_TABLES = 3, TDEFL_MAX_HUFF_SYMBOLS_0 = 288, TDEFL_MAX_HUFF_SYMBOLS_1 = 32, TDEFL_MAX_HUFF_SYMBOLS_2 = 19, TDEFL_LZ_DICT_SIZE = 32768, TDEFL_LZ_DICT_SIZE_MASK = TDEFL_LZ_DICT_SIZE - 1, TDEFL_MIN_MATCH_LEN = 3, TDEFL_MAX_MATCH_LEN = 258 };
|
||||
enum
|
||||
{
|
||||
TDEFL_MAX_HUFF_TABLES = 3,
|
||||
TDEFL_MAX_HUFF_SYMBOLS_0 = 288,
|
||||
TDEFL_MAX_HUFF_SYMBOLS_1 = 32,
|
||||
TDEFL_MAX_HUFF_SYMBOLS_2 = 19,
|
||||
TDEFL_LZ_DICT_SIZE = 32768,
|
||||
TDEFL_LZ_DICT_SIZE_MASK = TDEFL_LZ_DICT_SIZE - 1,
|
||||
TDEFL_MIN_MATCH_LEN = 3,
|
||||
TDEFL_MAX_MATCH_LEN = 258
|
||||
};
|
||||
|
||||
// TDEFL_OUT_BUF_SIZE MUST be large enough to hold a single entire compressed output block (using static/fixed Huffman codes).
|
||||
#if TDEFL_LESS_MEMORY
|
||||
enum { TDEFL_LZ_CODE_BUF_SIZE = 24 * 1024, TDEFL_OUT_BUF_SIZE = (TDEFL_LZ_CODE_BUF_SIZE * 13 ) / 10, TDEFL_MAX_HUFF_SYMBOLS = 288, TDEFL_LZ_HASH_BITS = 12, TDEFL_LEVEL1_HASH_SIZE_MASK = 4095, TDEFL_LZ_HASH_SHIFT = (TDEFL_LZ_HASH_BITS + 2) / 3, TDEFL_LZ_HASH_SIZE = 1 << TDEFL_LZ_HASH_BITS };
|
||||
#else
|
||||
enum { TDEFL_LZ_CODE_BUF_SIZE = 64 * 1024, TDEFL_OUT_BUF_SIZE = (TDEFL_LZ_CODE_BUF_SIZE * 13 ) / 10, TDEFL_MAX_HUFF_SYMBOLS = 288, TDEFL_LZ_HASH_BITS = 15, TDEFL_LEVEL1_HASH_SIZE_MASK = 4095, TDEFL_LZ_HASH_SHIFT = (TDEFL_LZ_HASH_BITS + 2) / 3, TDEFL_LZ_HASH_SIZE = 1 << TDEFL_LZ_HASH_BITS };
|
||||
enum
|
||||
{
|
||||
TDEFL_LZ_CODE_BUF_SIZE = 64 * 1024,
|
||||
TDEFL_OUT_BUF_SIZE = (TDEFL_LZ_CODE_BUF_SIZE * 13) / 10,
|
||||
TDEFL_MAX_HUFF_SYMBOLS = 288,
|
||||
TDEFL_LZ_HASH_BITS = 15,
|
||||
TDEFL_LEVEL1_HASH_SIZE_MASK = 4095,
|
||||
TDEFL_LZ_HASH_SHIFT = (TDEFL_LZ_HASH_BITS + 2) / 3,
|
||||
TDEFL_LZ_HASH_SIZE = 1 << TDEFL_LZ_HASH_BITS
|
||||
};
|
||||
#endif
|
||||
|
||||
// The low-level tdefl functions below may be used directly if the above helper functions aren't flexible enough. The low-level functions don't make any heap allocations, unlike the above helper functions.
|
||||
|
@ -878,7 +950,8 @@ typedef struct
|
|||
mz_uint m_adler32, m_lookahead_pos, m_lookahead_size, m_dict_size;
|
||||
mz_uint8 *m_pLZ_code_buf, *m_pLZ_flags, *m_pOutput_buf, *m_pOutput_buf_end;
|
||||
mz_uint m_num_flags_left, m_total_lz_bytes, m_lz_code_buf_dict_pos, m_bits_in, m_bit_buffer;
|
||||
mz_uint m_saved_match_dist, m_saved_match_len, m_saved_lit, m_output_flush_ofs, m_output_flush_remaining, m_finished, m_block_index, m_wants_to_finish;
|
||||
mz_uint m_saved_match_dist, m_saved_match_len, m_saved_lit, m_output_flush_ofs, m_output_flush_remaining, m_finished,
|
||||
m_block_index, m_wants_to_finish;
|
||||
tdefl_status m_prev_return_status;
|
||||
const void* m_pIn_buf;
|
||||
void* m_pOut_buf;
|
||||
|
@ -904,7 +977,8 @@ typedef struct
|
|||
tdefl_status tdefl_init(tdefl_compressor* d, tdefl_put_buf_func_ptr pPut_buf_func, void* pPut_buf_user, int flags);
|
||||
|
||||
// Compresses a block of data, consuming as much of the specified input buffer as possible, and writing as much compressed data to the specified output buffer as possible.
|
||||
tdefl_status tdefl_compress(tdefl_compressor *d, const void *pIn_buf, size_t *pIn_buf_size, void *pOut_buf, size_t *pOut_buf_size, tdefl_flush flush);
|
||||
tdefl_status tdefl_compress(tdefl_compressor* d, const void* pIn_buf, size_t* pIn_buf_size, void* pOut_buf,
|
||||
size_t* pOut_buf_size, tdefl_flush flush);
|
||||
|
||||
// tdefl_compress_buffer() is only usable when the tdefl_init() is called with a non-NULL tdefl_put_buf_func_ptr.
|
||||
// tdefl_compress_buffer() always consumes the entire input buffer.
|
||||
|
@ -927,4 +1001,3 @@ mz_uint tdefl_create_comp_flags_from_zip_params(int level, int window_bits, int
|
|||
#endif
|
||||
|
||||
#endif // MINIZ_HEADER_INCLUDED
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -59,14 +59,16 @@ static uint32_t blk(const uint32_t block[BLOCK_INTS], const size_t i)
|
|||
* (R0+R1), R2, R3, R4 are the different operations used in SHA1
|
||||
*/
|
||||
|
||||
static void R0(const uint32_t block[BLOCK_INTS], const uint32_t v, uint32_t &w, const uint32_t x, const uint32_t y, uint32_t &z, const size_t i)
|
||||
static void R0(const uint32_t block[BLOCK_INTS], const uint32_t v, uint32_t& w, const uint32_t x, const uint32_t y,
|
||||
uint32_t& z, const size_t i)
|
||||
{
|
||||
z += ((w & (x ^ y)) ^ y) + block[i] + 0x5a827999 + rol(v, 5);
|
||||
w = rol(w, 30);
|
||||
}
|
||||
|
||||
|
||||
static void R1(uint32_t block[BLOCK_INTS], const uint32_t v, uint32_t &w, const uint32_t x, const uint32_t y, uint32_t &z, const size_t i)
|
||||
static void R1(uint32_t block[BLOCK_INTS], const uint32_t v, uint32_t& w, const uint32_t x, const uint32_t y,
|
||||
uint32_t& z, const size_t i)
|
||||
{
|
||||
block[i] = blk(block, i);
|
||||
z += ((w & (x ^ y)) ^ y) + block[i] + 0x5a827999 + rol(v, 5);
|
||||
|
@ -74,7 +76,8 @@ static void R1(uint32_t block[BLOCK_INTS], const uint32_t v, uint32_t &w, const
|
|||
}
|
||||
|
||||
|
||||
static void R2(uint32_t block[BLOCK_INTS], const uint32_t v, uint32_t &w, const uint32_t x, const uint32_t y, uint32_t &z, const size_t i)
|
||||
static void R2(uint32_t block[BLOCK_INTS], const uint32_t v, uint32_t& w, const uint32_t x, const uint32_t y,
|
||||
uint32_t& z, const size_t i)
|
||||
{
|
||||
block[i] = blk(block, i);
|
||||
z += (w ^ x ^ y) + block[i] + 0x6ed9eba1 + rol(v, 5);
|
||||
|
@ -82,7 +85,8 @@ static void R2(uint32_t block[BLOCK_INTS], const uint32_t v, uint32_t &w, const
|
|||
}
|
||||
|
||||
|
||||
static void R3(uint32_t block[BLOCK_INTS], const uint32_t v, uint32_t &w, const uint32_t x, const uint32_t y, uint32_t &z, const size_t i)
|
||||
static void R3(uint32_t block[BLOCK_INTS], const uint32_t v, uint32_t& w, const uint32_t x, const uint32_t y,
|
||||
uint32_t& z, const size_t i)
|
||||
{
|
||||
block[i] = blk(block, i);
|
||||
z += (((w | x) & y) | (w & x)) + block[i] + 0x8f1bbcdc + rol(v, 5);
|
||||
|
@ -90,7 +94,8 @@ static void R3(uint32_t block[BLOCK_INTS], const uint32_t v, uint32_t &w, const
|
|||
}
|
||||
|
||||
|
||||
static void R4(uint32_t block[BLOCK_INTS], const uint32_t v, uint32_t &w, const uint32_t x, const uint32_t y, uint32_t &z, const size_t i)
|
||||
static void R4(uint32_t block[BLOCK_INTS], const uint32_t v, uint32_t& w, const uint32_t x, const uint32_t y,
|
||||
uint32_t& z, const size_t i)
|
||||
{
|
||||
block[i] = blk(block, i);
|
||||
z += (w ^ x ^ y) + block[i] + 0xca62c1d6 + rol(v, 5);
|
||||
|
@ -208,7 +213,8 @@ static void transform(uint32_t digest[], uint32_t block[BLOCK_INTS], uint64_t &t
|
|||
static void buffer_to_block(const std::string& buffer, uint32_t block[BLOCK_INTS])
|
||||
{
|
||||
/* Convert the std::string (byte buffer) to a uint32_t array (MSB) */
|
||||
for(size_t i = 0; i < BLOCK_INTS; i++) {
|
||||
for (size_t i = 0; i < BLOCK_INTS; i++)
|
||||
{
|
||||
block[i] = (buffer[4 * i + 3] & 0xff)
|
||||
| (buffer[4 * i + 2] & 0xff) << 8
|
||||
| (buffer[4 * i + 1] & 0xff) << 16
|
||||
|
@ -235,10 +241,12 @@ void SHA1::update(std::istream &is)
|
|||
char sbuf[BLOCK_BYTES];
|
||||
uint32_t block[BLOCK_INTS];
|
||||
|
||||
while(true) {
|
||||
while (true)
|
||||
{
|
||||
is.read(sbuf, BLOCK_BYTES - buffer.size());
|
||||
buffer.append(sbuf, (size_t)is.gcount());
|
||||
if(buffer.size() != BLOCK_BYTES) {
|
||||
if (buffer.size() != BLOCK_BYTES)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -261,16 +269,19 @@ std::string SHA1::final()
|
|||
/* Padding */
|
||||
buffer += (char)0x80;
|
||||
size_t orig_size = buffer.size();
|
||||
while(buffer.size() < BLOCK_BYTES) {
|
||||
while (buffer.size() < BLOCK_BYTES)
|
||||
{
|
||||
buffer += (char)0x00;
|
||||
}
|
||||
|
||||
uint32_t block[BLOCK_INTS];
|
||||
buffer_to_block(buffer, block);
|
||||
|
||||
if(orig_size > BLOCK_BYTES - 8) {
|
||||
if (orig_size > BLOCK_BYTES - 8)
|
||||
{
|
||||
transform(digest, block, transforms);
|
||||
for(size_t i = 0; i < BLOCK_INTS - 2; i++) {
|
||||
for (size_t i = 0; i < BLOCK_INTS - 2; i++)
|
||||
{
|
||||
block[i] = 0;
|
||||
}
|
||||
}
|
||||
|
@ -282,7 +293,8 @@ std::string SHA1::final()
|
|||
|
||||
/* Hex std::string */
|
||||
std::ostringstream result;
|
||||
for(size_t i = 0; i < sizeof(digest) / sizeof(digest[0]); i++) {
|
||||
for (size_t i = 0; i < sizeof(digest) / sizeof(digest[0]); i++)
|
||||
{
|
||||
result << std::uppercase << std::hex << std::setfill('0') << std::setw(8);
|
||||
result << digest[i];
|
||||
}
|
||||
|
|
|
@ -132,11 +132,16 @@ statement in a block (unless you're using C++). */
|
|||
|
||||
/* private */
|
||||
enum { snes_ntsc_entry_size = 128 };
|
||||
|
||||
enum { snes_ntsc_palette_size = 0x2000 };
|
||||
|
||||
typedef unsigned long snes_ntsc_rgb_t;
|
||||
struct snes_ntsc_t {
|
||||
|
||||
struct snes_ntsc_t
|
||||
{
|
||||
snes_ntsc_rgb_t table[snes_ntsc_palette_size][snes_ntsc_entry_size];
|
||||
};
|
||||
|
||||
enum { snes_ntsc_burst_size = snes_ntsc_entry_size / snes_ntsc_burst_count };
|
||||
|
||||
#define SNES_NTSC_RGB16( ktable, n ) \
|
||||
|
|
|
@ -45,7 +45,9 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
|
|||
#define rgb_offset (rgb_unit * 2 + 0.5f)
|
||||
|
||||
enum { burst_size = snes_ntsc_entry_size / burst_count };
|
||||
|
||||
enum { kernel_half = 16 };
|
||||
|
||||
enum { kernel_size = kernel_half * 2 + 1 };
|
||||
|
||||
typedef struct init_t
|
||||
|
@ -285,6 +287,7 @@ static void init( init_t* impl, snes_ntsc_setup_t const* setup )
|
|||
#define PACK_RGB( r, g, b ) ((r) << 21 | (g) << 11 | (b) << 1)
|
||||
|
||||
enum { rgb_kernel_size = burst_size / alignment_count };
|
||||
|
||||
enum { rgb_bias = rgb_unit * 2 * snes_ntsc_rgb_builder };
|
||||
|
||||
typedef struct pixel_info_t
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -290,17 +290,26 @@ extern "C" {
|
|||
{
|
||||
VORBIS__no_error,
|
||||
|
||||
VORBIS_need_more_data = 1, // not a real error
|
||||
VORBIS_need_more_data = 1,
|
||||
// not a real error
|
||||
|
||||
VORBIS_invalid_api_mixing, // can't mix API modes
|
||||
VORBIS_outofmem, // not enough memory
|
||||
VORBIS_feature_not_supported, // uses floor 0
|
||||
VORBIS_too_many_channels, // STB_VORBIS_MAX_CHANNELS is too small
|
||||
VORBIS_file_open_failure, // fopen() failed
|
||||
VORBIS_seek_without_length, // can't seek in unknown-length file
|
||||
VORBIS_invalid_api_mixing,
|
||||
// can't mix API modes
|
||||
VORBIS_outofmem,
|
||||
// not enough memory
|
||||
VORBIS_feature_not_supported,
|
||||
// uses floor 0
|
||||
VORBIS_too_many_channels,
|
||||
// STB_VORBIS_MAX_CHANNELS is too small
|
||||
VORBIS_file_open_failure,
|
||||
// fopen() failed
|
||||
VORBIS_seek_without_length,
|
||||
// can't seek in unknown-length file
|
||||
|
||||
VORBIS_unexpected_eof = 10, // file is truncated?
|
||||
VORBIS_seek_invalid, // seek past EOF
|
||||
VORBIS_unexpected_eof = 10,
|
||||
// file is truncated?
|
||||
VORBIS_seek_invalid,
|
||||
// seek past EOF
|
||||
|
||||
// decoding errors (corrupt/invalid stream) -- you probably
|
||||
// don't care about the exact details of these
|
||||
|
@ -330,4 +339,3 @@ extern "C" {
|
|||
// HEADER ENDS HERE
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
|
@ -22,7 +22,8 @@
|
|||
|
||||
namespace
|
||||
{
|
||||
template <uint32_t N> inline
|
||||
template <uint32_t N>
|
||||
inline
|
||||
unsigned char getByte(uint32_t val) { return static_cast<unsigned char>((val >> (8 * N)) & 0xff); }
|
||||
|
||||
inline unsigned char getAlpha(uint32_t pix) { return getByte<3>(pix); }
|
||||
|
@ -31,15 +32,24 @@ inline unsigned char getGreen(uint32_t pix) { return getByte<1>(pix); }
|
|||
inline unsigned char getBlue(uint32_t pix) { return getByte<0>(pix); }
|
||||
|
||||
inline uint32_t makePixel(unsigned char r, unsigned char g, unsigned char b) { return (r << 16) | (g << 8) | b; }
|
||||
inline uint32_t makePixel(unsigned char a, unsigned char r, unsigned char g, unsigned char b) { return (a << 24) | (r << 16) | (g << 8) | b; }
|
||||
|
||||
inline uint32_t makePixel(unsigned char a, unsigned char r, unsigned char g, unsigned char b)
|
||||
{
|
||||
return (a << 24) | (r << 16) | (g << 8) | b;
|
||||
}
|
||||
|
||||
|
||||
template <unsigned int M, unsigned int N> inline
|
||||
uint32_t gradientRGB(uint32_t pixFront, uint32_t pixBack) //blend front color with opacity M / N over opaque background: http://en.wikipedia.org/wiki/Alpha_compositing#Alpha_blending
|
||||
template <unsigned int M, unsigned int N>
|
||||
inline
|
||||
uint32_t gradientRGB(uint32_t pixFront, uint32_t pixBack)
|
||||
//blend front color with opacity M / N over opaque background: http://en.wikipedia.org/wiki/Alpha_compositing#Alpha_blending
|
||||
{
|
||||
static_assert(0 < M && M < N && N <= 1000, "");
|
||||
|
||||
auto calcColor = [](unsigned char colFront, unsigned char colBack) -> unsigned char { return (colFront * M + colBack * (N - M)) / N; };
|
||||
auto calcColor = [](unsigned char colFront, unsigned char colBack) -> unsigned char
|
||||
{
|
||||
return (colFront * M + colBack * (N - M)) / N;
|
||||
};
|
||||
|
||||
return makePixel(calcColor(getRed(pixFront), getRed(pixBack)),
|
||||
calcColor(getGreen(pixFront), getGreen(pixBack)),
|
||||
|
@ -47,8 +57,10 @@ uint32_t gradientRGB(uint32_t pixFront, uint32_t pixBack) //blend front color wi
|
|||
}
|
||||
|
||||
|
||||
template <unsigned int M, unsigned int N> inline
|
||||
uint32_t gradientARGB(uint32_t pixFront, uint32_t pixBack) //find intermediate color between two colors with alpha channels (=> NO alpha blending!!!)
|
||||
template <unsigned int M, unsigned int N>
|
||||
inline
|
||||
uint32_t gradientARGB(uint32_t pixFront, uint32_t pixBack)
|
||||
//find intermediate color between two colors with alpha channels (=> NO alpha blending!!!)
|
||||
{
|
||||
static_assert(0 < M && M < N && N <= 1000, "");
|
||||
|
||||
|
@ -82,8 +94,15 @@ uint32_t gradientARGB(uint32_t pixFront, uint32_t pixBack) //find intermediate c
|
|||
//
|
||||
|
||||
|
||||
uint32_t* byteAdvance( uint32_t* ptr, int bytes) { return reinterpret_cast< uint32_t*>(reinterpret_cast< char*>(ptr) + bytes); }
|
||||
const uint32_t* byteAdvance(const uint32_t* ptr, int bytes) { return reinterpret_cast<const uint32_t*>(reinterpret_cast<const char*>(ptr) + bytes); }
|
||||
uint32_t* byteAdvance(uint32_t* ptr, int bytes)
|
||||
{
|
||||
return reinterpret_cast<uint32_t*>(reinterpret_cast<char*>(ptr) + bytes);
|
||||
}
|
||||
|
||||
const uint32_t* byteAdvance(const uint32_t* ptr, int bytes)
|
||||
{
|
||||
return reinterpret_cast<const uint32_t*>(reinterpret_cast<const char*>(ptr) + bytes);
|
||||
}
|
||||
|
||||
|
||||
//fill block with the given color
|
||||
|
@ -130,10 +149,12 @@ struct MatrixRotation<ROT_0, I, J, N>
|
|||
static const size_t J_old = J;
|
||||
};
|
||||
|
||||
template <RotationDegree rotDeg, size_t I, size_t J, size_t N> //(i, j) = (row, col) indices, N = size of (square) matrix
|
||||
template <RotationDegree rotDeg, size_t I, size_t J, size_t N>
|
||||
//(i, j) = (row, col) indices, N = size of (square) matrix
|
||||
struct MatrixRotation
|
||||
{
|
||||
static const size_t I_old = N - 1 - MatrixRotation<static_cast<RotationDegree>(rotDeg - 1), I, J, N>::J_old; //old coordinates before rotation!
|
||||
static const size_t I_old = N - 1 - MatrixRotation<static_cast<RotationDegree>(rotDeg - 1), I, J, N>::J_old;
|
||||
//old coordinates before rotation!
|
||||
static const size_t J_old = MatrixRotation<static_cast<RotationDegree>(rotDeg - 1), I, J, N>::I_old; //
|
||||
};
|
||||
|
||||
|
@ -142,9 +163,12 @@ template <size_t N, RotationDegree rotDeg>
|
|||
class OutputMatrix
|
||||
{
|
||||
public:
|
||||
OutputMatrix(uint32_t* out, int outWidth) : //access matrix area, top-left at position "out" for image with given width
|
||||
OutputMatrix(uint32_t* out, int outWidth) :
|
||||
//access matrix area, top-left at position "out" for image with given width
|
||||
out_(out),
|
||||
outWidth_(outWidth) {}
|
||||
outWidth_(outWidth)
|
||||
{
|
||||
}
|
||||
|
||||
template <size_t I, size_t J>
|
||||
uint32_t& ref() const
|
||||
|
@ -160,7 +184,8 @@ private:
|
|||
};
|
||||
|
||||
|
||||
template <class T> inline
|
||||
template <class T>
|
||||
inline
|
||||
T square(T value) { return value * value; }
|
||||
|
||||
struct DistYCbCrBuffer //30% perf boost compared to distYCbCr()!
|
||||
|
@ -210,7 +235,8 @@ private:
|
|||
const int g_diff = static_cast<int>(getGreen(pix1)) - getGreen(pix2);
|
||||
const int b_diff = static_cast<int>(getBlue(pix1)) - getBlue(pix2);
|
||||
|
||||
return buffer[(((r_diff + 255) / 2) << 16) | //slightly reduce precision (division by 2) to squeeze value into single byte
|
||||
return buffer[(((r_diff + 255) / 2) << 16) |
|
||||
//slightly reduce precision (division by 2) to squeeze value into single byte
|
||||
(((g_diff + 255) / 2) << 8) |
|
||||
((b_diff + 255) / 2)];
|
||||
}
|
||||
|
@ -222,8 +248,10 @@ private:
|
|||
enum BlendType
|
||||
{
|
||||
BLEND_NONE = 0,
|
||||
BLEND_NORMAL, //a normal indication to blend
|
||||
BLEND_DOMINANT, //a strong indication to blend
|
||||
BLEND_NORMAL,
|
||||
//a normal indication to blend
|
||||
BLEND_DOMINANT,
|
||||
//a strong indication to blend
|
||||
//attention: BlendType must fit into the value range of 2 bit!!!
|
||||
};
|
||||
|
||||
|
@ -258,7 +286,8 @@ input kernel area naming convention:
|
|||
*/
|
||||
template <class ColorDistance>
|
||||
FORCE_INLINE //detect blend direction
|
||||
BlendResult preProcessCorners(const Kernel_4x4& ker, const xbrz::ScalerCfg& cfg) //result: F, G, J, K corners of "GradientType"
|
||||
BlendResult preProcessCorners(const Kernel_4x4& ker, const xbrz::ScalerCfg& cfg)
|
||||
//result: F, G, J, K corners of "GradientType"
|
||||
{
|
||||
BlendResult result = {};
|
||||
|
||||
|
@ -271,8 +300,10 @@ BlendResult preProcessCorners(const Kernel_4x4& ker, const xbrz::ScalerCfg& cfg)
|
|||
auto dist = [&](uint32_t pix1, uint32_t pix2) { return ColorDistance::dist(pix1, pix2, cfg.luminanceWeight); };
|
||||
|
||||
const int weight = 4;
|
||||
double jg = dist(ker.i, ker.f) + dist(ker.f, ker.c) + dist(ker.n, ker.k) + dist(ker.k, ker.h) + weight * dist(ker.j, ker.g);
|
||||
double fk = dist(ker.e, ker.j) + dist(ker.j, ker.o) + dist(ker.b, ker.g) + dist(ker.g, ker.l) + weight * dist(ker.f, ker.k);
|
||||
double jg = dist(ker.i, ker.f) + dist(ker.f, ker.c) + dist(ker.n, ker.k) + dist(ker.k, ker.h) + weight *
|
||||
dist(ker.j, ker.g);
|
||||
double fk = dist(ker.e, ker.j) + dist(ker.j, ker.o) + dist(ker.b, ker.g) + dist(ker.g, ker.l) + weight *
|
||||
dist(ker.f, ker.k);
|
||||
|
||||
if (jg < fk) //test sample: 70% of values max(jg, fk) / min(jg, fk) are between 1.1 and 3.7 with median being 1.8
|
||||
{
|
||||
|
@ -305,27 +336,48 @@ struct Kernel_3x3
|
|||
|
||||
#define DEF_GETTER(x) template <RotationDegree rotDeg> uint32_t inline get_##x(const Kernel_3x3& ker) { return ker.x; }
|
||||
//we cannot and NEED NOT write "ker.##x" since ## concatenates preprocessor tokens but "." is not a token
|
||||
DEF_GETTER(a) DEF_GETTER(b) DEF_GETTER(c)
|
||||
DEF_GETTER(d) DEF_GETTER(e) DEF_GETTER(f)
|
||||
DEF_GETTER(g) DEF_GETTER(h) DEF_GETTER(i)
|
||||
DEF_GETTER(a)
|
||||
DEF_GETTER(b)
|
||||
DEF_GETTER(c)
|
||||
DEF_GETTER(d)
|
||||
DEF_GETTER(e)
|
||||
DEF_GETTER(f)
|
||||
DEF_GETTER(g)
|
||||
DEF_GETTER(h)
|
||||
DEF_GETTER(i)
|
||||
#undef DEF_GETTER
|
||||
|
||||
#define DEF_GETTER(x, y) template <> inline uint32_t get_##x<ROT_90>(const Kernel_3x3& ker) { return ker.y; }
|
||||
DEF_GETTER(b, d) DEF_GETTER(c, a)
|
||||
DEF_GETTER(d, h) DEF_GETTER(e, e) DEF_GETTER(f, b)
|
||||
DEF_GETTER(g, i) DEF_GETTER(h, f) DEF_GETTER(i, c)
|
||||
DEF_GETTER(b, d)
|
||||
DEF_GETTER(c, a)
|
||||
DEF_GETTER(d, h)
|
||||
DEF_GETTER(e, e)
|
||||
DEF_GETTER(f, b)
|
||||
DEF_GETTER(g, i)
|
||||
DEF_GETTER(h, f)
|
||||
DEF_GETTER(i, c)
|
||||
#undef DEF_GETTER
|
||||
|
||||
#define DEF_GETTER(x, y) template <> inline uint32_t get_##x<ROT_180>(const Kernel_3x3& ker) { return ker.y; }
|
||||
DEF_GETTER(b, h) DEF_GETTER(c, g)
|
||||
DEF_GETTER(d, f) DEF_GETTER(e, e) DEF_GETTER(f, d)
|
||||
DEF_GETTER(g, c) DEF_GETTER(h, b) DEF_GETTER(i, a)
|
||||
DEF_GETTER(b, h)
|
||||
DEF_GETTER(c, g)
|
||||
DEF_GETTER(d, f)
|
||||
DEF_GETTER(e, e)
|
||||
DEF_GETTER(f, d)
|
||||
DEF_GETTER(g, c)
|
||||
DEF_GETTER(h, b)
|
||||
DEF_GETTER(i, a)
|
||||
#undef DEF_GETTER
|
||||
|
||||
#define DEF_GETTER(x, y) template <> inline uint32_t get_##x<ROT_270>(const Kernel_3x3& ker) { return ker.y; }
|
||||
DEF_GETTER(b, f) DEF_GETTER(c, i)
|
||||
DEF_GETTER(d, b) DEF_GETTER(e, e) DEF_GETTER(f, h)
|
||||
DEF_GETTER(g, a) DEF_GETTER(h, d) DEF_GETTER(i, g)
|
||||
DEF_GETTER(b, f)
|
||||
DEF_GETTER(c, i)
|
||||
DEF_GETTER(d, b)
|
||||
DEF_GETTER(e, e)
|
||||
DEF_GETTER(f, h)
|
||||
DEF_GETTER(g, a)
|
||||
DEF_GETTER(h, d)
|
||||
DEF_GETTER(i, g)
|
||||
#undef DEF_GETTER
|
||||
|
||||
|
||||
|
@ -334,18 +386,26 @@ inline BlendType getTopR (unsigned char b) { return static_cast<BlendType>(0x3
|
|||
inline BlendType getBottomR(unsigned char b) { return static_cast<BlendType>(0x3 & (b >> 4)); }
|
||||
inline BlendType getBottomL(unsigned char b) { return static_cast<BlendType>(0x3 & (b >> 6)); }
|
||||
|
||||
inline void setTopL (unsigned char& b, BlendType bt) { b |= bt; } //buffer is assumed to be initialized before preprocessing!
|
||||
inline void setTopL(unsigned char& b, BlendType bt) { b |= bt; }
|
||||
//buffer is assumed to be initialized before preprocessing!
|
||||
inline void setTopR(unsigned char& b, BlendType bt) { b |= (bt << 2); }
|
||||
inline void setBottomR(unsigned char& b, BlendType bt) { b |= (bt << 4); }
|
||||
inline void setBottomL(unsigned char& b, BlendType bt) { b |= (bt << 6); }
|
||||
|
||||
inline bool blendingNeeded(unsigned char b) { return b != 0; }
|
||||
|
||||
template <RotationDegree rotDeg> inline
|
||||
template <RotationDegree rotDeg>
|
||||
inline
|
||||
unsigned char rotateBlendInfo(unsigned char b) { return b; }
|
||||
template <> inline unsigned char rotateBlendInfo<ROT_90 >(unsigned char b) { return ((b << 2) | (b >> 6)) & 0xff; }
|
||||
template <> inline unsigned char rotateBlendInfo<ROT_180>(unsigned char b) { return ((b << 4) | (b >> 4)) & 0xff; }
|
||||
template <> inline unsigned char rotateBlendInfo<ROT_270>(unsigned char b) { return ((b << 6) | (b >> 2)) & 0xff; }
|
||||
|
||||
template <>
|
||||
inline unsigned char rotateBlendInfo<ROT_90>(unsigned char b) { return ((b << 2) | (b >> 6)) & 0xff; }
|
||||
|
||||
template <>
|
||||
inline unsigned char rotateBlendInfo<ROT_180>(unsigned char b) { return ((b << 4) | (b >> 4)) & 0xff; }
|
||||
|
||||
template <>
|
||||
inline unsigned char rotateBlendInfo<ROT_270>(unsigned char b) { return ((b << 6) | (b >> 2)) & 0xff; }
|
||||
|
||||
|
||||
/*
|
||||
|
@ -380,7 +440,10 @@ void blendPixel(const Kernel_3x3& ker,
|
|||
|
||||
if (getBottomR(blend) >= BLEND_NORMAL)
|
||||
{
|
||||
auto eq = [&](uint32_t pix1, uint32_t pix2) { return ColorDistance::dist(pix1, pix2, cfg.luminanceWeight) < cfg.equalColorTolerance; };
|
||||
auto eq = [&](uint32_t pix1, uint32_t pix2)
|
||||
{
|
||||
return ColorDistance::dist(pix1, pix2, cfg.luminanceWeight) < cfg.equalColorTolerance;
|
||||
};
|
||||
auto dist = [&](uint32_t pix1, uint32_t pix2) { return ColorDistance::dist(pix1, pix2, cfg.luminanceWeight); };
|
||||
|
||||
const bool doLineBlend = [&]() -> bool
|
||||
|
@ -407,7 +470,8 @@ void blendPixel(const Kernel_3x3& ker,
|
|||
|
||||
if (doLineBlend)
|
||||
{
|
||||
const double fg = dist(f, g); //test sample: 70% of values max(fg, hc) / min(fg, hc) are between 1.1 and 3.7 with median being 1.9
|
||||
const double fg = dist(f, g);
|
||||
//test sample: 70% of values max(fg, hc) / min(fg, hc) are between 1.1 and 3.7 with median being 1.9
|
||||
const double hc = dist(h, c); //
|
||||
|
||||
const bool haveShallowLine = cfg.steepDirectionThreshold * fg <= hc && e != g && d != g;
|
||||
|
@ -445,7 +509,8 @@ void blendPixel(const Kernel_3x3& ker,
|
|||
|
||||
|
||||
template <class Scaler, class ColorDistance> //scaler policy: see "Scaler2x" reference implementation
|
||||
void scaleImage(const uint32_t* src, uint32_t* trg, int srcWidth, int srcHeight, const xbrz::ScalerCfg& cfg, int yFirst, int yLast)
|
||||
void scaleImage(const uint32_t* src, uint32_t* trg, int srcWidth, int srcHeight, const xbrz::ScalerCfg& cfg,
|
||||
int yFirst, int yLast)
|
||||
{
|
||||
yFirst = std::max(yFirst, 0);
|
||||
yLast = std::min(yLast, srcHeight);
|
||||
|
@ -457,7 +522,8 @@ void scaleImage(const uint32_t* src, uint32_t* trg, int srcWidth, int srcHeight,
|
|||
//"use" space at the end of the image as temporary buffer for "on the fly preprocessing": we even could use larger area of
|
||||
//"sizeof(uint32_t) * srcWidth * (yLast - yFirst)" bytes without risk of accidental overwriting before accessing
|
||||
const int bufferSize = srcWidth;
|
||||
unsigned char* preProcBuffer = reinterpret_cast<unsigned char*>(trg + yLast * Scaler::scale * trgWidth) - bufferSize;
|
||||
unsigned char* preProcBuffer = reinterpret_cast<unsigned char*>(trg + yLast * Scaler::scale * trgWidth) -
|
||||
bufferSize;
|
||||
std::fill(preProcBuffer, preProcBuffer + bufferSize, 0);
|
||||
static_assert(BLEND_NONE == 0, "");
|
||||
|
||||
|
@ -569,20 +635,23 @@ void scaleImage(const uint32_t* src, uint32_t* trg, int srcWidth, int srcHeight,
|
|||
---------
|
||||
*/
|
||||
blend_xy = preProcBuffer[x];
|
||||
setBottomR(blend_xy, res.blend_f); //all four corners of (x, y) have been determined at this point due to processing sequence!
|
||||
setBottomR(blend_xy, res.blend_f);
|
||||
//all four corners of (x, y) have been determined at this point due to processing sequence!
|
||||
|
||||
setTopR(blend_xy1, res.blend_j); //set 2nd known corner for (x, y + 1)
|
||||
preProcBuffer[x] = blend_xy1; //store on current buffer position for use on next row
|
||||
|
||||
blend_xy1 = 0;
|
||||
setTopL(blend_xy1, res.blend_k); //set 1st known corner for (x + 1, y + 1) and buffer for use on next column
|
||||
setTopL(blend_xy1, res.blend_k);
|
||||
//set 1st known corner for (x + 1, y + 1) and buffer for use on next column
|
||||
|
||||
if (x + 1 < bufferSize) //set 3rd known corner for (x + 1, y)
|
||||
setBottomL(preProcBuffer[x + 1], res.blend_g);
|
||||
}
|
||||
|
||||
//fill block of size scale * scale with the given color
|
||||
fillBlock(out, trgWidth * sizeof(uint32_t), ker4.f, Scaler::scale); //place *after* preprocessing step, to not overwrite the results while processing the the last pixel!
|
||||
fillBlock(out, trgWidth * sizeof(uint32_t), ker4.f, Scaler::scale);
|
||||
//place *after* preprocessing step, to not overwrite the results while processing the the last pixel!
|
||||
|
||||
//blend four corners of current pixel
|
||||
if (blendingNeeded(blend_xy)) //good 5% perf-improvement
|
||||
|
@ -618,7 +687,10 @@ struct Scaler2x : public ColorGradient
|
|||
static const int scale = 2;
|
||||
|
||||
template <unsigned int M, unsigned int N> //bring template function into scope for GCC
|
||||
static void alphaGrad(uint32_t& pixBack, uint32_t pixFront) { ColorGradient::template alphaGrad<M, N>(pixBack, pixFront); }
|
||||
static void alphaGrad(uint32_t& pixBack, uint32_t pixFront)
|
||||
{
|
||||
ColorGradient::template alphaGrad<M, N>(pixBack, pixFront);
|
||||
}
|
||||
|
||||
|
||||
template <class OutputMatrix>
|
||||
|
@ -664,7 +736,10 @@ struct Scaler3x : public ColorGradient
|
|||
static const int scale = 3;
|
||||
|
||||
template <unsigned int M, unsigned int N> //bring template function into scope for GCC
|
||||
static void alphaGrad(uint32_t& pixBack, uint32_t pixFront) { ColorGradient::template alphaGrad<M, N>(pixBack, pixFront); }
|
||||
static void alphaGrad(uint32_t& pixBack, uint32_t pixFront)
|
||||
{
|
||||
ColorGradient::template alphaGrad<M, N>(pixBack, pixFront);
|
||||
}
|
||||
|
||||
|
||||
template <class OutputMatrix>
|
||||
|
@ -722,7 +797,10 @@ struct Scaler4x : public ColorGradient
|
|||
static const int scale = 4;
|
||||
|
||||
template <unsigned int M, unsigned int N> //bring template function into scope for GCC
|
||||
static void alphaGrad(uint32_t& pixBack, uint32_t pixFront) { ColorGradient::template alphaGrad<M, N>(pixBack, pixFront); }
|
||||
static void alphaGrad(uint32_t& pixBack, uint32_t pixFront)
|
||||
{
|
||||
ColorGradient::template alphaGrad<M, N>(pixBack, pixFront);
|
||||
}
|
||||
|
||||
|
||||
template <class OutputMatrix>
|
||||
|
@ -791,7 +869,10 @@ struct Scaler5x : public ColorGradient
|
|||
static const int scale = 5;
|
||||
|
||||
template <unsigned int M, unsigned int N> //bring template function into scope for GCC
|
||||
static void alphaGrad(uint32_t& pixBack, uint32_t pixFront) { ColorGradient::template alphaGrad<M, N>(pixBack, pixFront); }
|
||||
static void alphaGrad(uint32_t& pixBack, uint32_t pixFront)
|
||||
{
|
||||
ColorGradient::template alphaGrad<M, N>(pixBack, pixFront);
|
||||
}
|
||||
|
||||
|
||||
template <class OutputMatrix>
|
||||
|
@ -850,7 +931,8 @@ struct Scaler5x : public ColorGradient
|
|||
template <class OutputMatrix>
|
||||
static void blendLineDiagonal(uint32_t col, OutputMatrix& out)
|
||||
{
|
||||
alphaGrad<1, 8>(out.template ref<scale - 1, scale / 2 >(), col); //conflict with other rotations for this odd scale
|
||||
alphaGrad<1, 8>(out.template ref<scale - 1, scale / 2>(), col);
|
||||
//conflict with other rotations for this odd scale
|
||||
alphaGrad<1, 8>(out.template ref<scale - 2, scale / 2 + 1>(), col);
|
||||
alphaGrad<1, 8>(out.template ref<scale - 3, scale / 2 + 2>(), col); //
|
||||
|
||||
|
@ -879,7 +961,10 @@ struct Scaler6x : public ColorGradient
|
|||
static const int scale = 6;
|
||||
|
||||
template <unsigned int M, unsigned int N> //bring template function into scope for GCC
|
||||
static void alphaGrad(uint32_t& pixBack, uint32_t pixFront) { ColorGradient::template alphaGrad<M, N>(pixBack, pixFront); }
|
||||
static void alphaGrad(uint32_t& pixBack, uint32_t pixFront)
|
||||
{
|
||||
ColorGradient::template alphaGrad<M, N>(pixBack, pixFront);
|
||||
}
|
||||
|
||||
|
||||
template <class OutputMatrix>
|
||||
|
@ -1032,7 +1117,8 @@ struct ColorGradientARGB
|
|||
}
|
||||
|
||||
|
||||
void xbrz::scale(size_t factor, const uint32_t* src, uint32_t* trg, int srcWidth, int srcHeight, ColorFormat colFmt, const xbrz::ScalerCfg& cfg, int yFirst, int yLast)
|
||||
void xbrz::scale(size_t factor, const uint32_t* src, uint32_t* trg, int srcWidth, int srcHeight, ColorFormat colFmt,
|
||||
const xbrz::ScalerCfg& cfg, int yFirst, int yLast)
|
||||
{
|
||||
switch (colFmt)
|
||||
{
|
||||
|
@ -1040,15 +1126,20 @@ void xbrz::scale(size_t factor, const uint32_t* src, uint32_t* trg, int srcWidth
|
|||
switch (factor)
|
||||
{
|
||||
case 2:
|
||||
return scaleImage<Scaler2x<ColorGradientARGB>, ColorDistanceARGB>(src, trg, srcWidth, srcHeight, cfg, yFirst, yLast);
|
||||
return scaleImage<Scaler2x<ColorGradientARGB>, ColorDistanceARGB>(
|
||||
src, trg, srcWidth, srcHeight, cfg, yFirst, yLast);
|
||||
case 3:
|
||||
return scaleImage<Scaler3x<ColorGradientARGB>, ColorDistanceARGB>(src, trg, srcWidth, srcHeight, cfg, yFirst, yLast);
|
||||
return scaleImage<Scaler3x<ColorGradientARGB>, ColorDistanceARGB>(
|
||||
src, trg, srcWidth, srcHeight, cfg, yFirst, yLast);
|
||||
case 4:
|
||||
return scaleImage<Scaler4x<ColorGradientARGB>, ColorDistanceARGB>(src, trg, srcWidth, srcHeight, cfg, yFirst, yLast);
|
||||
return scaleImage<Scaler4x<ColorGradientARGB>, ColorDistanceARGB>(
|
||||
src, trg, srcWidth, srcHeight, cfg, yFirst, yLast);
|
||||
case 5:
|
||||
return scaleImage<Scaler5x<ColorGradientARGB>, ColorDistanceARGB>(src, trg, srcWidth, srcHeight, cfg, yFirst, yLast);
|
||||
return scaleImage<Scaler5x<ColorGradientARGB>, ColorDistanceARGB>(
|
||||
src, trg, srcWidth, srcHeight, cfg, yFirst, yLast);
|
||||
case 6:
|
||||
return scaleImage<Scaler6x<ColorGradientARGB>, ColorDistanceARGB>(src, trg, srcWidth, srcHeight, cfg, yFirst, yLast);
|
||||
return scaleImage<Scaler6x<ColorGradientARGB>, ColorDistanceARGB>(
|
||||
src, trg, srcWidth, srcHeight, cfg, yFirst, yLast);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -1056,15 +1147,20 @@ void xbrz::scale(size_t factor, const uint32_t* src, uint32_t* trg, int srcWidth
|
|||
switch (factor)
|
||||
{
|
||||
case 2:
|
||||
return scaleImage<Scaler2x<ColorGradientRGB>, ColorDistanceRGB>(src, trg, srcWidth, srcHeight, cfg, yFirst, yLast);
|
||||
return scaleImage<Scaler2x<ColorGradientRGB>, ColorDistanceRGB>(
|
||||
src, trg, srcWidth, srcHeight, cfg, yFirst, yLast);
|
||||
case 3:
|
||||
return scaleImage<Scaler3x<ColorGradientRGB>, ColorDistanceRGB>(src, trg, srcWidth, srcHeight, cfg, yFirst, yLast);
|
||||
return scaleImage<Scaler3x<ColorGradientRGB>, ColorDistanceRGB>(
|
||||
src, trg, srcWidth, srcHeight, cfg, yFirst, yLast);
|
||||
case 4:
|
||||
return scaleImage<Scaler4x<ColorGradientRGB>, ColorDistanceRGB>(src, trg, srcWidth, srcHeight, cfg, yFirst, yLast);
|
||||
return scaleImage<Scaler4x<ColorGradientRGB>, ColorDistanceRGB>(
|
||||
src, trg, srcWidth, srcHeight, cfg, yFirst, yLast);
|
||||
case 5:
|
||||
return scaleImage<Scaler5x<ColorGradientRGB>, ColorDistanceRGB>(src, trg, srcWidth, srcHeight, cfg, yFirst, yLast);
|
||||
return scaleImage<Scaler5x<ColorGradientRGB>, ColorDistanceRGB>(
|
||||
src, trg, srcWidth, srcHeight, cfg, yFirst, yLast);
|
||||
case 6:
|
||||
return scaleImage<Scaler6x<ColorGradientRGB>, ColorDistanceRGB>(src, trg, srcWidth, srcHeight, cfg, yFirst, yLast);
|
||||
return scaleImage<Scaler6x<ColorGradientRGB>, ColorDistanceRGB>(
|
||||
src, trg, srcWidth, srcHeight, cfg, yFirst, yLast);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1072,7 +1168,8 @@ void xbrz::scale(size_t factor, const uint32_t* src, uint32_t* trg, int srcWidth
|
|||
}
|
||||
|
||||
|
||||
bool xbrz::equalColorTest(uint32_t col1, uint32_t col2, ColorFormat colFmt, double luminanceWeight, double equalColorTolerance)
|
||||
bool xbrz::equalColorTest(uint32_t col1, uint32_t col2, ColorFormat colFmt, double luminanceWeight,
|
||||
double equalColorTolerance)
|
||||
{
|
||||
switch (colFmt)
|
||||
{
|
||||
|
@ -1113,7 +1210,8 @@ void xbrz::nearestNeighborScale(const uint32_t* src, int srcWidth, int srcHeight
|
|||
|
||||
//keep within for loop to support MT input slices!
|
||||
const int yTrg_first = (y * trgHeight + srcHeight - 1) / srcHeight; //=ceil(y * trgHeight / srcHeight)
|
||||
const int yTrg_last = ((y + 1) * trgHeight + srcHeight - 1) / srcHeight; //=ceil(((y + 1) * trgHeight) / srcHeight)
|
||||
const int yTrg_last = ((y + 1) * trgHeight + srcHeight - 1) / srcHeight;
|
||||
//=ceil(((y + 1) * trgHeight) / srcHeight)
|
||||
const int blockHeight = yTrg_last - yTrg_first;
|
||||
|
||||
if (blockHeight > 0)
|
||||
|
|
|
@ -40,8 +40,10 @@ http://board.byuu.org/viewtopic.php?f=10&t=2248
|
|||
|
||||
enum class ColorFormat //from high bits -> low bits, 8 bit per channel
|
||||
{
|
||||
RGB, //8 bit for each red, green, blue, upper 8 bits unused
|
||||
ARGB, //including alpha channel, BGRA byte order on little-endian machines
|
||||
RGB,
|
||||
//8 bit for each red, green, blue, upper 8 bits unused
|
||||
ARGB,
|
||||
//including alpha channel, BGRA byte order on little-endian machines
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -69,15 +71,14 @@ enum SliceType
|
|||
NN_SCALE_SLICE_SOURCE,
|
||||
NN_SCALE_SLICE_TARGET,
|
||||
};
|
||||
|
||||
void nearestNeighborScale(const uint32_t* src, int srcWidth, int srcHeight, int srcPitch, //pitch in bytes!
|
||||
uint32_t* trg, int trgWidth, int trgHeight, int trgPitch,
|
||||
SliceType st, int yFirst, int yLast);
|
||||
|
||||
//parameter tuning
|
||||
bool equalColorTest(uint32_t col1, uint32_t col2, ColorFormat colFmt, double luminanceWeight, double equalColorTolerance);
|
||||
|
||||
|
||||
|
||||
bool equalColorTest(uint32_t col1, uint32_t col2, ColorFormat colFmt, double luminanceWeight,
|
||||
double equalColorTolerance);
|
||||
|
||||
|
||||
//########################### implementation ###########################
|
||||
|
|
Loading…
Add table
Reference in a new issue