<commit_before>/*
The ttaplugin-winamp project.
Copyright (C) 2005-2013 Yamagata Fumihiro

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
*/

#include <stdio.h>
#include <Wasabi/api/service/api_service.h>
#include <Agave/Config/api_config.h>
#include <Wasabi/api/memmgr/api_memmgr.h>
#include <Winamp/in2.h>
#include <Winamp/wa_ipc.h>
#include <Wasabi/api/service/waservicefactory.h>
#include <Agave/AlbumArt/svc_albumArtProvider.h>
#include "AlbumArt.h"
#include <taglib/trueaudiofile.h>
#include <taglib/id3v2tag.h>
#include <taglib/attachedpictureframe.h>
#include <taglib/tag.h>

#include "MediaLibrary.h"

static const int MIME_LENGTH = 64;

class AlbumArtFactory : public waServiceFactory
{
public:
	FOURCC GetServiceType();
	const char *GetServiceName();
	GUID GetGUID();
	void *GetInterface(int global_lock);
	int SupportNonLockingInterface();
	int ReleaseInterface(void *ifc);
	const char *GetTestString();
	int ServiceNotify(int msg, int param1, int param2);

protected:
	RECVS_DISPATCH;
};

extern In_Module mod; // TODO: change if you called yours something else
extern CMediaLibrary m_ReadTag;
extern CMediaLibrary m_WriteTag;

#define WASABI_API_MEMMGR memmgr

static api_config *AGAVE_API_CONFIG = 0;
static api_service *WASABI_API_SVC = 0;
static api_memmgr *WASABI_API_MEMMGR=0;

static AlbumArtFactory albumArtFactory;

void Wasabi_Init()
{
	WASABI_API_SVC = (api_service *)SendMessage(mod.hMainWindow, WM_WA_IPC, 0, IPC_GET_API_SERVICE);

	if (WASABI_API_SVC == 0 || WASABI_API_SVC == (api_service *) 1) {
		WASABI_API_SVC = 0;
		return;
	}

	WASABI_API_SVC->service_register(&albumArtFactory);

	waServiceFactory *sf = (waServiceFactory *)WASABI_API_SVC->service_getServiceByGuid(AgaveConfigGUID);
	if (sf)
		AGAVE_API_CONFIG= (api_config *)sf->getInterface();
	sf = (waServiceFactory *)WASABI_API_SVC->service_getServiceByGuid(memMgrApiServiceGuid);
	if (sf)
		WASABI_API_MEMMGR= (api_memmgr *)sf->getInterface();
}

void Wasabi_Quit()
{
	if (WASABI_API_SVC) {
		waServiceFactory *sf = (waServiceFactory *)WASABI_API_SVC->service_getServiceByGuid(AgaveConfigGUID);
		if (sf)
			sf->releaseInterface(AGAVE_API_CONFIG);
		sf = (waServiceFactory *)WASABI_API_SVC->service_getServiceByGuid(memMgrApiServiceGuid);
		if (sf)
			sf->releaseInterface(WASABI_API_MEMMGR);

		WASABI_API_SVC->service_deregister(&albumArtFactory);
	}
}

void *Wasabi_Malloc(size_t size_in_bytes)
{
	return WASABI_API_MEMMGR->sysMalloc(size_in_bytes);
}

void Wasabi_Free(void *memory_block)
{
	WASABI_API_MEMMGR->sysFree(memory_block);
}

class TTA_AlbumArtProvider : public svc_albumArtProvider
{
public:
	TTA_AlbumArtProvider();
	virtual ~TTA_AlbumArtProvider();
	bool IsMine(const wchar_t *filename);
	int ProviderType();
	// implementation note: use WASABI_API_MEMMGR to alloc bits and mimetype, so that the recipient can free through that
	int GetAlbumArtData(const wchar_t *filename, const wchar_t *type, void **bits, size_t *len, wchar_t **mimeType);
	int SetAlbumArtData(const wchar_t *filename, const wchar_t *type, void *bits, size_t len, const wchar_t *mimeType);
	int DeleteAlbumArt(const wchar_t *filename, const wchar_t *type);
protected:
	RECVS_DISPATCH;
	CRITICAL_SECTION	CriticalSection;
	std::wstring			FileName;
	bool					isSucceed;
	TagLib::ByteVector		AlbumArt;
	TagLib::String			extension;
};

TTA_AlbumArtProvider::TTA_AlbumArtProvider() : svc_albumArtProvider()
{
	::InitializeCriticalSection(&CriticalSection);
	isSucceed = false;
}

TTA_AlbumArtProvider::~TTA_AlbumArtProvider()
{
	::DeleteCriticalSection(&CriticalSection);
	isSucceed = false;
}

static const wchar_t *GetLastCharactercW(const wchar_t *string)
{
	if (!string || !*string)
		return string;

	return CharPrevW(string, string+lstrlenW(string));
}

static const wchar_t *scanstr_backW(const wchar_t *str, const wchar_t *toscan, const wchar_t *defval)
{
	const wchar_t *s = GetLastCharactercW(str);
	if (!str[0]) return defval;
	if (!toscan || !toscan[0]) return defval;
	while (1)
	{
		const wchar_t *t = toscan;
		while (*t)
		{
			if (*t == *s) return s;
			t = CharNextW(t);
		}
		t = CharPrevW(str, s);
		if (t == s)
			return defval;
		s = t;
	}
}

static const wchar_t *extensionW(const wchar_t *fn)
{
	const wchar_t *end = scanstr_backW(fn, L"./\\", 0);
	if (!end)
		return (fn+lstrlenW(fn));

	if (*end == L'.')
		return end+1;

	return (fn+lstrlenW(fn));
}

bool TTA_AlbumArtProvider::IsMine(const wchar_t *filename)
{
	const wchar_t *extension = extensionW(filename);
	if (extension && *extension)
	{
		return (_wcsicmp (extension, L"tta") == 0) ? true : false;
	}
	else
	{
		// Do nothing
	}
	return false;
}

int TTA_AlbumArtProvider::ProviderType()
{
	return ALBUMARTPROVIDER_TYPE_EMBEDDED;
}

int TTA_AlbumArtProvider::GetAlbumArtData(const wchar_t *filename, const wchar_t *type, void **bits, size_t *len, wchar_t **mime_type)
{

	size_t tag_size = 0;
    int retval = ALBUMARTPROVIDER_FAILURE;
	size_t string_len = 0;
	TagLib::String mimeType;

	::EnterCriticalSection(&CriticalSection);

	if(_wcsicmp (type, L"cover")) {
		::LeaveCriticalSection(&CriticalSection);
        return retval;
	} else {
		// do nothing
	}

	if(!bits || !len || !mime_type) {
		::LeaveCriticalSection(&CriticalSection);
		return retval;
	} else {
		// do nothing
	}

	if (!isSucceed || _wcsicmp(FileName.c_str(), filename))
	{
		if (m_ReadTag.isValid() && m_ReadTag.GetCurrentFileName() == filename)
		{
			FileName = filename;
			// read Album Art
			AlbumArt =
				m_ReadTag.GetAlbumArt(TagLib::ID3v2::AttachedPictureFrame::FrontCover, mimeType);
			extension = mimeType.substr(mimeType.find("/") + 1);
			isSucceed = true;
		}
		else if (m_WriteTag.isValid() && m_WriteTag.GetCurrentFileName() == filename)
		{
			FileName = filename;
			// read Album Art
			AlbumArt =
				m_WriteTag.GetAlbumArt(TagLib::ID3v2::AttachedPictureFrame::FrontCover, mimeType);
			extension = mimeType.substr(mimeType.find("/") + 1);
			isSucceed = true;

		}
		else
		{
			FileName = filename;

			TagLib::TrueAudio::File TagFile(FileName.c_str());

			if (!TagFile.isValid())
			{
				isSucceed = false;
				::LeaveCriticalSection(&CriticalSection);
				return retval;
			}
			else {
				isSucceed = true;
			}

			// read Album Art
			AlbumArt =
				TagFile.ID3v2Tag()->albumArt(TagLib::ID3v2::AttachedPictureFrame::FrontCover, mimeType);

			extension = mimeType.substr(mimeType.find("/") + 1);
		}

	}
	else
	{
		// Do nothing
	}

	if (AlbumArt != TagLib::ByteVector::null) {
		*len = AlbumArt.size();
		*bits = (char *)Wasabi_Malloc(*len);
		if (NULL == *bits) {
			::LeaveCriticalSection(&CriticalSection);
			return retval;
		}
		else {
			// do nothing
		}

		errno_t err = memcpy_s(*bits, AlbumArt.size(), AlbumArt.data(), AlbumArt.size());
		if (err) {
			::LeaveCriticalSection(&CriticalSection);
			return retval;
		}
		else {
			// do nothing
		}

		*mime_type = (wchar_t *)Wasabi_Malloc(extension.size() * 2 + 2);
		if (NULL == *mime_type) {
			if (NULL != *bits) {
				Wasabi_Free(*bits);
			}
			else {
				// do nothing
			}
			::LeaveCriticalSection(&CriticalSection);
			return retval;
		}
		else {
			mbstowcs_s(&string_len, *mime_type, extension.size() + 1, extension.toCString(), _TRUNCATE);
			retval = ALBUMARTPROVIDER_SUCCESS;
		}

		if (retval) {
			if (NULL != *bits) {
				Wasabi_Free(*bits);
			} else {
				// do nothing
			}
			if (NULL != *mime_type) {
				Wasabi_Free(*bits);
			} else {
				// do nothing
			}
		}
	} else {
		// do nothing
	}

	::LeaveCriticalSection(&CriticalSection);
    return retval;
}

int TTA_AlbumArtProvider::SetAlbumArtData(const wchar_t *filename, const wchar_t *type, void *bits, size_t len, const wchar_t *mime_type)
{

    int retval = ALBUMARTPROVIDER_FAILURE;
	TagLib::String mimeType(L"");
	int size = 0;
	TagLib::ID3v2::AttachedPictureFrame::Type artType = TagLib::ID3v2::AttachedPictureFrame::Other;
	size_t string_len = 0;

	::EnterCriticalSection(&CriticalSection);

	if(std::wstring(filename) == L"") {
		::LeaveCriticalSection(&CriticalSection);
        return retval;
	}

	size_t convertedChars = 0;

	TagLib::ByteVector AlbumArt;

	if (!bits) {
		//delete AlbumArt
		AlbumArt.setData(NULL, 0);

	} else if(len == 0 || wcscmp(mime_type, L"")==0) {
		::LeaveCriticalSection(&CriticalSection);
		return retval;
	} else {
		mimeType = L"image/";
		mimeType += mime_type;
		size = len;
		artType = TagLib::ID3v2::AttachedPictureFrame::FrontCover;
		AlbumArt.setData((const char *)bits, (TagLib::uint)size);
	}

	TagLib::TrueAudio::File TTAFile(filename);

	if (TTAFile.isValid())
	{
		TTAFile.ID3v2Tag()->setAlbumArt(AlbumArt, artType, mimeType);
		TTAFile.save();
		isSucceed = false;
		retval = ALBUMARTPROVIDER_SUCCESS;
	}
	else
	{
		// Do nothing
	}
	::LeaveCriticalSection(&CriticalSection);

	return retval;
}

int TTA_AlbumArtProvider::DeleteAlbumArt(const wchar_t *filename, const wchar_t *type)
{
	return SetAlbumArtData(filename, type, NULL, 0, L"image/jpeg");
}

#define CBCLASS TTA_AlbumArtProvider
START_DISPATCH;
CB(SVC_ALBUMARTPROVIDER_PROVIDERTYPE, ProviderType);
CB(SVC_ALBUMARTPROVIDER_GETALBUMARTDATA, GetAlbumArtData);
CB(SVC_ALBUMARTPROVIDER_ISMINE, IsMine);
CB(SVC_ALBUMARTPROVIDER_SETALBUMARTDATA, SetAlbumArtData);
CB(SVC_ALBUMARTPROVIDER_DELETEALBUMART, DeleteAlbumArt);
END_DISPATCH;
#undef CBCLASS

static TTA_AlbumArtProvider albumArtProvider;

// {bb653840-6dab-4867-9f42-A772E4068C81}
static const GUID TTA_albumartproviderGUID =
{ 0xbb653840, 0x6dab, 0x4867, { 0x9f, 0x42, 0xa7, 0x72, 0xe4, 0x05, 0x8c, 0x81 } };

FOURCC AlbumArtFactory::GetServiceType()
{
	return svc_albumArtProvider::SERVICETYPE;
}

const char *AlbumArtFactory::GetServiceName()
{
	return "TTA Album Art Provider";
}

GUID AlbumArtFactory::GetGUID()
{
	return TTA_albumartproviderGUID;
}

void *AlbumArtFactory::GetInterface(int global_lock)
{
	return &albumArtProvider;
}

int AlbumArtFactory::SupportNonLockingInterface()
{
	return 0;
}

int AlbumArtFactory::ReleaseInterface(void *ifc)
{
	return 1;
}

const char *AlbumArtFactory::GetTestString()
{
	return 0;
}

int AlbumArtFactory::ServiceNotify(int msg, int param1, int param2)
{
	return 1;
}

#define CBCLASS AlbumArtFactory
START_DISPATCH;
CB(WASERVICEFACTORY_GETSERVICETYPE, GetServiceType)
CB(WASERVICEFACTORY_GETSERVICENAME, GetServiceName)
CB(WASERVICEFACTORY_GETGUID, GetGUID)
CB(WASERVICEFACTORY_GETINTERFACE, GetInterface)
CB(WASERVICEFACTORY_SUPPORTNONLOCKINGGETINTERFACE, SupportNonLockingInterface)
CB(WASERVICEFACTORY_RELEASEINTERFACE, ReleaseInterface)
CB(WASERVICEFACTORY_GETTESTSTRING, GetTestString)
CB(WASERVICEFACTORY_SERVICENOTIFY, ServiceNotify)
END_DISPATCH;
#undef CBCLASS
<commit_msg>Fix parameter calilng for removing AlbumArt.<commit_after>/*
The ttaplugin-winamp project.
Copyright (C) 2005-2013 Yamagata Fumihiro

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
*/

#include <stdio.h>
#include <Wasabi/api/service/api_service.h>
#include <Agave/Config/api_config.h>
#include <Wasabi/api/memmgr/api_memmgr.h>
#include <Winamp/in2.h>
#include <Winamp/wa_ipc.h>
#include <Wasabi/api/service/waservicefactory.h>
#include <Agave/AlbumArt/svc_albumArtProvider.h>
#include "AlbumArt.h"
#include <taglib/trueaudiofile.h>
#include <taglib/id3v2tag.h>
#include <taglib/attachedpictureframe.h>
#include <taglib/tag.h>

#include "MediaLibrary.h"

static const int MIME_LENGTH = 64;

class AlbumArtFactory : public waServiceFactory
{
public:
	FOURCC GetServiceType();
	const char *GetServiceName();
	GUID GetGUID();
	void *GetInterface(int global_lock);
	int SupportNonLockingInterface();
	int ReleaseInterface(void *ifc);
	const char *GetTestString();
	int ServiceNotify(int msg, int param1, int param2);

protected:
	RECVS_DISPATCH;
};

extern In_Module mod; // TODO: change if you called yours something else
extern CMediaLibrary m_ReadTag;
extern CMediaLibrary m_WriteTag;

#define WASABI_API_MEMMGR memmgr

static api_config *AGAVE_API_CONFIG = 0;
static api_service *WASABI_API_SVC = 0;
static api_memmgr *WASABI_API_MEMMGR=0;

static AlbumArtFactory albumArtFactory;

void Wasabi_Init()
{
	WASABI_API_SVC = (api_service *)SendMessage(mod.hMainWindow, WM_WA_IPC, 0, IPC_GET_API_SERVICE);

	if (WASABI_API_SVC == 0 || WASABI_API_SVC == (api_service *) 1) {
		WASABI_API_SVC = 0;
		return;
	}

	WASABI_API_SVC->service_register(&albumArtFactory);

	waServiceFactory *sf = (waServiceFactory *)WASABI_API_SVC->service_getServiceByGuid(AgaveConfigGUID);
	if (sf)
		AGAVE_API_CONFIG= (api_config *)sf->getInterface();
	sf = (waServiceFactory *)WASABI_API_SVC->service_getServiceByGuid(memMgrApiServiceGuid);
	if (sf)
		WASABI_API_MEMMGR= (api_memmgr *)sf->getInterface();
}

void Wasabi_Quit()
{
	if (WASABI_API_SVC) {
		waServiceFactory *sf = (waServiceFactory *)WASABI_API_SVC->service_getServiceByGuid(AgaveConfigGUID);
		if (sf)
			sf->releaseInterface(AGAVE_API_CONFIG);
		sf = (waServiceFactory *)WASABI_API_SVC->service_getServiceByGuid(memMgrApiServiceGuid);
		if (sf)
			sf->releaseInterface(WASABI_API_MEMMGR);

		WASABI_API_SVC->service_deregister(&albumArtFactory);
	}
}

void *Wasabi_Malloc(size_t size_in_bytes)
{
	return WASABI_API_MEMMGR->sysMalloc(size_in_bytes);
}

void Wasabi_Free(void *memory_block)
{
	WASABI_API_MEMMGR->sysFree(memory_block);
}

class TTA_AlbumArtProvider : public svc_albumArtProvider
{
public:
	TTA_AlbumArtProvider();
	virtual ~TTA_AlbumArtProvider();
	bool IsMine(const wchar_t *filename);
	int ProviderType();
	// implementation note: use WASABI_API_MEMMGR to alloc bits and mimetype, so that the recipient can free through that
	int GetAlbumArtData(const wchar_t *filename, const wchar_t *type, void **bits, size_t *len, wchar_t **mimeType);
	int SetAlbumArtData(const wchar_t *filename, const wchar_t *type, void *bits, size_t len, const wchar_t *mimeType);
	int DeleteAlbumArt(const wchar_t *filename, const wchar_t *type);
protected:
	RECVS_DISPATCH;
	CRITICAL_SECTION	CriticalSection;
	std::wstring			FileName;
	bool					isSucceed;
	TagLib::ByteVector		AlbumArt;
	TagLib::String			extension;
};

TTA_AlbumArtProvider::TTA_AlbumArtProvider() : svc_albumArtProvider()
{
	::InitializeCriticalSection(&CriticalSection);
	isSucceed = false;
}

TTA_AlbumArtProvider::~TTA_AlbumArtProvider()
{
	::DeleteCriticalSection(&CriticalSection);
	isSucceed = false;
}

static const wchar_t *GetLastCharactercW(const wchar_t *string)
{
	if (!string || !*string)
		return string;

	return CharPrevW(string, string+lstrlenW(string));
}

static const wchar_t *scanstr_backW(const wchar_t *str, const wchar_t *toscan, const wchar_t *defval)
{
	const wchar_t *s = GetLastCharactercW(str);
	if (!str[0]) return defval;
	if (!toscan || !toscan[0]) return defval;
	while (1)
	{
		const wchar_t *t = toscan;
		while (*t)
		{
			if (*t == *s) return s;
			t = CharNextW(t);
		}
		t = CharPrevW(str, s);
		if (t == s)
			return defval;
		s = t;
	}
}

static const wchar_t *extensionW(const wchar_t *fn)
{
	const wchar_t *end = scanstr_backW(fn, L"./\\", 0);
	if (!end)
		return (fn+lstrlenW(fn));

	if (*end == L'.')
		return end+1;

	return (fn+lstrlenW(fn));
}

bool TTA_AlbumArtProvider::IsMine(const wchar_t *filename)
{
	const wchar_t *extension = extensionW(filename);
	if (extension && *extension)
	{
		return (_wcsicmp (extension, L"tta") == 0) ? true : false;
	}
	else
	{
		// Do nothing
	}
	return false;
}

int TTA_AlbumArtProvider::ProviderType()
{
	return ALBUMARTPROVIDER_TYPE_EMBEDDED;
}

int TTA_AlbumArtProvider::GetAlbumArtData(const wchar_t *filename, const wchar_t *type, void **bits, size_t *len, wchar_t **mime_type)
{

	size_t tag_size = 0;
    int retval = ALBUMARTPROVIDER_FAILURE;
	size_t string_len = 0;
	TagLib::String mimeType;

	::EnterCriticalSection(&CriticalSection);

	if(_wcsicmp (type, L"cover")) {
		::LeaveCriticalSection(&CriticalSection);
        return retval;
	} else {
		// do nothing
	}

	if(!bits || !len || !mime_type) {
		::LeaveCriticalSection(&CriticalSection);
		return retval;
	} else {
		// do nothing
	}

	if (!isSucceed || _wcsicmp(FileName.c_str(), filename))
	{
		if (m_ReadTag.isValid() && m_ReadTag.GetCurrentFileName() == filename)
		{
			FileName = filename;
			// read Album Art
			AlbumArt =
				m_ReadTag.GetAlbumArt(TagLib::ID3v2::AttachedPictureFrame::FrontCover, mimeType);
			extension = mimeType.substr(mimeType.find("/") + 1);
			isSucceed = true;
		}
		else if (m_WriteTag.isValid() && m_WriteTag.GetCurrentFileName() == filename)
		{
			FileName = filename;
			// read Album Art
			AlbumArt =
				m_WriteTag.GetAlbumArt(TagLib::ID3v2::AttachedPictureFrame::FrontCover, mimeType);
			extension = mimeType.substr(mimeType.find("/") + 1);
			isSucceed = true;

		}
		else
		{
			FileName = filename;

			TagLib::TrueAudio::File TagFile(FileName.c_str());

			if (!TagFile.isValid())
			{
				isSucceed = false;
				::LeaveCriticalSection(&CriticalSection);
				return retval;
			}
			else {
				isSucceed = true;
			}

			// read Album Art
			AlbumArt =
				TagFile.ID3v2Tag()->albumArt(TagLib::ID3v2::AttachedPictureFrame::FrontCover, mimeType);

			extension = mimeType.substr(mimeType.find("/") + 1);
		}

	}
	else
	{
		// Do nothing
	}

	if (AlbumArt != TagLib::ByteVector::null) {
		*len = AlbumArt.size();
		*bits = (char *)Wasabi_Malloc(*len);
		if (NULL == *bits) {
			::LeaveCriticalSection(&CriticalSection);
			return retval;
		}
		else {
			// do nothing
		}

		errno_t err = memcpy_s(*bits, AlbumArt.size(), AlbumArt.data(), AlbumArt.size());
		if (err) {
			::LeaveCriticalSection(&CriticalSection);
			return retval;
		}
		else {
			// do nothing
		}

		*mime_type = (wchar_t *)Wasabi_Malloc(extension.size() * 2 + 2);
		if (NULL == *mime_type) {
			if (NULL != *bits) {
				Wasabi_Free(*bits);
			}
			else {
				// do nothing
			}
			::LeaveCriticalSection(&CriticalSection);
			return retval;
		}
		else {
			mbstowcs_s(&string_len, *mime_type, extension.size() + 1, extension.toCString(), _TRUNCATE);
			retval = ALBUMARTPROVIDER_SUCCESS;
		}

		if (retval) {
			if (NULL != *bits) {
				Wasabi_Free(*bits);
			} else {
				// do nothing
			}
			if (NULL != *mime_type) {
				Wasabi_Free(*bits);
			} else {
				// do nothing
			}
		}
	} else {
		// do nothing
	}

	::LeaveCriticalSection(&CriticalSection);
    return retval;
}

int TTA_AlbumArtProvider::SetAlbumArtData(const wchar_t *filename, const wchar_t *type, void *bits, size_t len, const wchar_t *mime_type)
{

    int retval = ALBUMARTPROVIDER_FAILURE;
	TagLib::String mimeType(L"");
	int size = 0;
	TagLib::ID3v2::AttachedPictureFrame::Type artType = TagLib::ID3v2::AttachedPictureFrame::Other;
	size_t string_len = 0;

	::EnterCriticalSection(&CriticalSection);

	if(std::wstring(filename) == L"") {
		::LeaveCriticalSection(&CriticalSection);
        return retval;
	}

	size_t convertedChars = 0;

	TagLib::ByteVector AlbumArt;

	if (!bits) {
		//delete AlbumArt
		AlbumArt.setData(NULL, 0);

	} else if(len == 0 || wcscmp(mime_type, L"")==0) {
		::LeaveCriticalSection(&CriticalSection);
		return retval;
	} else {
		mimeType = L"image/";
		mimeType += mime_type;
		size = len;
		artType = TagLib::ID3v2::AttachedPictureFrame::FrontCover;
		AlbumArt.setData((const char *)bits, (TagLib::uint)size);
	}

	TagLib::TrueAudio::File TTAFile(filename);

	if (TTAFile.isValid())
	{
		TTAFile.ID3v2Tag()->setAlbumArt(AlbumArt, artType, mimeType);
		TTAFile.save();
		isSucceed = false;
		retval = ALBUMARTPROVIDER_SUCCESS;
	}
	else
	{
		// Do nothing
	}
	::LeaveCriticalSection(&CriticalSection);

	return retval;
}

int TTA_AlbumArtProvider::DeleteAlbumArt(const wchar_t *filename, const wchar_t *type)
{
	return SetAlbumArtData(filename, type, NULL, 0, L"jpeg");
}

#define CBCLASS TTA_AlbumArtProvider
START_DISPATCH;
CB(SVC_ALBUMARTPROVIDER_PROVIDERTYPE, ProviderType);
CB(SVC_ALBUMARTPROVIDER_GETALBUMARTDATA, GetAlbumArtData);
CB(SVC_ALBUMARTPROVIDER_ISMINE, IsMine);
CB(SVC_ALBUMARTPROVIDER_SETALBUMARTDATA, SetAlbumArtData);
CB(SVC_ALBUMARTPROVIDER_DELETEALBUMART, DeleteAlbumArt);
END_DISPATCH;
#undef CBCLASS

static TTA_AlbumArtProvider albumArtProvider;

// {bb653840-6dab-4867-9f42-A772E4068C81}
static const GUID TTA_albumartproviderGUID =
{ 0xbb653840, 0x6dab, 0x4867, { 0x9f, 0x42, 0xa7, 0x72, 0xe4, 0x05, 0x8c, 0x81 } };

FOURCC AlbumArtFactory::GetServiceType()
{
	return svc_albumArtProvider::SERVICETYPE;
}

const char *AlbumArtFactory::GetServiceName()
{
	return "TTA Album Art Provider";
}

GUID AlbumArtFactory::GetGUID()
{
	return TTA_albumartproviderGUID;
}

void *AlbumArtFactory::GetInterface(int global_lock)
{
	return &albumArtProvider;
}

int AlbumArtFactory::SupportNonLockingInterface()
{
	return 0;
}

int AlbumArtFactory::ReleaseInterface(void *ifc)
{
	return 1;
}

const char *AlbumArtFactory::GetTestString()
{
	return 0;
}

int AlbumArtFactory::ServiceNotify(int msg, int param1, int param2)
{
	return 1;
}

#define CBCLASS AlbumArtFactory
START_DISPATCH;
CB(WASERVICEFACTORY_GETSERVICETYPE, GetServiceType)
CB(WASERVICEFACTORY_GETSERVICENAME, GetServiceName)
CB(WASERVICEFACTORY_GETGUID, GetGUID)
CB(WASERVICEFACTORY_GETINTERFACE, GetInterface)
CB(WASERVICEFACTORY_SUPPORTNONLOCKINGGETINTERFACE, SupportNonLockingInterface)
CB(WASERVICEFACTORY_RELEASEINTERFACE, ReleaseInterface)
CB(WASERVICEFACTORY_GETTESTSTRING, GetTestString)
CB(WASERVICEFACTORY_SERVICENOTIFY, ServiceNotify)
END_DISPATCH;
#undef CBCLASS
<|endoftext|>


<commit_before>#ifndef _SNARKFRONT_ALG_UINT_HPP_
#define _SNARKFRONT_ALG_UINT_HPP_

#include <algorithm>
#include <cassert>

#include <snarkfront/Alg.hpp>
#include <snarkfront/Alg_internal.hpp>

namespace snarkfront {

////////////////////////////////////////////////////////////////////////////////
// Alg_uint8
// Alg_uint32
// Alg_uint64
//

template <typename ALG>
void evalStackOp_Bitwise(std::stack<ALG>& S, const BitwiseOps op)
{
    typedef typename ALG::ValueType Value;
    typedef typename ALG::FrType Fr;
    typedef typename ALG::R1T R1T;
    auto& RS = TL<R1C<Fr>>::singleton();

    typedef cryptl::BitwiseINT<Value> BitOps;

    // y is right argument
    const auto R = S.top();
    S.pop();
    const Value yvalue = R.value();
    const Fr ywitness = R.witness();

    // modulo addition
    if (BitwiseOps::ADDMOD == op) {
        // x is left argument
        const auto L = S.top();
        S.pop();
        const Value xvalue = L.value();
        const Fr xwitness = L.witness();

        // left argument
        R1T x;
        Fr x_witness;
        Value xhigh, xlow;
        std::size_t xhighCnt;
        if (L.splitBits().size() < 2 * sizeBits(xvalue)) {
            x_witness = xwitness;
            x = RS->argScalar(L);

            const std::vector<int> xrem = bitsValue(xlow, L.splitBits());
            bitsValue(xhigh, xrem);
            xhighCnt = xrem.size();

#ifdef USE_ASSERT
            assert(xlow == xvalue);
            assert(xhighCnt < sizeBits(xvalue));
#endif

        } else {
            x_witness = ALG::valueToString(xvalue);
            const std::vector<R1T> xbits = RS->argBits(L);
            const std::vector<R1T> xfit = rank1_xword(xbits, sizeBits(xvalue));
            x = RS->bitsToWitness(xfit, x_witness);

            xlow = xvalue;
            xhigh = 0;
            xhighCnt = 0;
        }

        // right argument
        R1T y;
        Fr y_witness;
        Value yhigh, ylow;
        std::size_t yhighCnt;
        if (R.splitBits().size() < 2 * sizeBits(yvalue)) {
            y_witness = ywitness;
            y = RS->argScalar(R);

            const std::vector<int> yrem = bitsValue(ylow, R.splitBits());
            bitsValue(yhigh, yrem);
            yhighCnt = yrem.size();

#ifdef USE_ASSERT
            assert(ylow == yvalue);
            assert(yhighCnt < sizeBits(yvalue));
#endif

        } else {
            y_witness = ALG::valueToString(yvalue);
            const std::vector<R1T> ybits = RS->argBits(R);
            const std::vector<R1T> yfit = rank1_xword(ybits, sizeBits(yvalue));
            y = RS->bitsToWitness(yfit, y_witness);

            ylow = yvalue;
            yhigh = 0;
            yhighCnt = 0;
        }

        // overflow addition
        Value high = xhigh + yhigh, low = xlow;
        addover(high, low, ylow);

        const Value zvalue = BitOps::ADDMOD(xvalue, yvalue);
#ifdef USE_ASSERT
        assert(zvalue == low);
#endif

        std::vector<int> zbits = valueBits(low);
        for (std::size_t i = 0; i < xhighCnt + yhighCnt + 1; ++i) {
            zbits.push_back(high & 0x1);
            high >>= 1;
        }
#ifdef USE_ASSERT
        assert(0 == high);
#endif

        const Fr zwitness = x_witness + y_witness;
        const R1T z = RS->createResult(op, x, y, zwitness);

        S.push(
            ALG(zvalue, zwitness, zbits, {z}));

    } else if (BitwiseOps::CMPLMNT == op) {
        // y is only argument
        const std::vector<R1T> y = RS->argBits(R);
#ifdef USE_ASSERT
        assert(y.size() >= sizeBits(yvalue));
        assert(y.size() == R.splitBits().size());
#endif

        // z is result
        const Value zvalue = BitOps::CMPLMNT(yvalue);

        std::vector<int> zbits;
        std::vector<R1T> z;
        zbits.reserve(sizeBits(zvalue));
        z.reserve(sizeBits(zvalue));
        for (std::size_t i = 0; i < sizeBits(zvalue); ++i) {
            const bool b = ! R.splitBits()[i];
            zbits.push_back(b);
            z.emplace_back(
                RS->createResult(op, y[i], y[i], boolTo<Fr>(b)));
        }
#ifdef USE_ASSERT
        assert(zbits == valueBits(zvalue));
#endif

        S.push(
            ALG(zvalue, ALG::valueToString(zvalue), zbits, z));

    } else {
        // x is left argument
        const auto L = S.top();
        S.pop();
        const Value xvalue = L.value();
        const Fr xwitness = L.witness();

        const std::vector<R1T> x = RS->argBits(L);
#ifdef USE_ASSERT
        assert(x.size() >= sizeBits(xvalue));
#endif

        // z is result
        const Value zvalue = evalOp(op, xvalue, yvalue);

        std::vector<R1T> z;
        z.reserve(sizeBits(zvalue));

        if (isPermute(op)) {
            const std::vector<R1T> xfit = rank1_xword(x, sizeBits(xvalue));
            z = RS->permuteBits(op, xfit, yvalue);

        } else {
            const std::vector<R1T> y = RS->argBits(R);
#ifdef USE_ASSERT
            assert(y.size() >= sizeBits(yvalue));
#endif

            Value mask = 0x1;
            for (std::size_t i = 0; i < sizeBits(zvalue); ++i) {
                z.emplace_back(
                    RS->createResult(op, x[i], y[i], boolTo<Fr>(zvalue & mask)));

                mask <<= 1;
            }
        }

        S.push(
            ALG(zvalue, ALG::valueToString(zvalue), valueBits(zvalue), z));
    }
}

template <typename FR>
void evalStackOp(std::stack<Alg_uint8<FR>>& S, const BitwiseOps op) {
    evalStackOp_Bitwise<Alg_uint8<FR>>(S, op);
}

template <typename FR>
void evalStackOp(std::stack<Alg_uint32<FR>>& S, const BitwiseOps op) {
    evalStackOp_Bitwise<Alg_uint32<FR>>(S, op);
}

template <typename FR>
void evalStackOp(std::stack<Alg_uint64<FR>>& S, const BitwiseOps op) {
    evalStackOp_Bitwise<Alg_uint64<FR>>(S, op);
}

template <typename FR>
void evalStackCmp(std::stack<Alg_uint8<FR>>& S, const EqualityCmp op) {
    evalStackCmp_Equality(S, op);
}

template <typename FR>
void evalStackCmp(std::stack<Alg_uint32<FR>>& S, const EqualityCmp op) {
    evalStackCmp_Equality(S, op);
}

template <typename FR>
void evalStackCmp(std::stack<Alg_uint64<FR>>& S, const EqualityCmp op) {
    evalStackCmp_Equality(S, op);
}

} // namespace snarkfront

#endif
<commit_msg>MULMOD for ED25519<commit_after>#ifndef _SNARKFRONT_ALG_UINT_HPP_
#define _SNARKFRONT_ALG_UINT_HPP_

#include <algorithm>
#include <cassert>

#include <snarkfront/Alg.hpp>
#include <snarkfront/Alg_internal.hpp>

namespace snarkfront {

////////////////////////////////////////////////////////////////////////////////
// Alg_uint8
// Alg_uint32
// Alg_uint64
//

template <typename ALG>
void evalStackOp_Bitwise(std::stack<ALG>& S, const BitwiseOps op)
{
    typedef typename ALG::ValueType Value;
    typedef typename ALG::FrType Fr;
    typedef typename ALG::R1T R1T;
    auto& RS = TL<R1C<Fr>>::singleton();

    typedef cryptl::BitwiseINT<Value> BitOps;

    // y is right argument
    const auto R = S.top();
    S.pop();
    const Value yvalue = R.value();
    const Fr ywitness = R.witness();

    // modulo addition
    if (BitwiseOps::ADDMOD == op) {
        // x is left argument
        const auto L = S.top();
        S.pop();
        const Value xvalue = L.value();
        const Fr xwitness = L.witness();

        // left argument
        R1T x;
        Fr x_witness;
        Value xhigh, xlow;
        std::size_t xhighCnt;
        if (L.splitBits().size() < 2 * sizeBits(xvalue)) {
            x_witness = xwitness;
            x = RS->argScalar(L);

            const std::vector<int> xrem = bitsValue(xlow, L.splitBits());
            bitsValue(xhigh, xrem);
            xhighCnt = xrem.size();

#ifdef USE_ASSERT
            assert(xlow == xvalue);
            assert(xhighCnt < sizeBits(xvalue));
#endif

        } else {
            x_witness = ALG::valueToString(xvalue);
            const std::vector<R1T> xbits = RS->argBits(L);
            const std::vector<R1T> xfit = rank1_xword(xbits, sizeBits(xvalue));
            x = RS->bitsToWitness(xfit, x_witness);

            xlow = xvalue;
            xhigh = 0;
            xhighCnt = 0;
        }

        // right argument
        R1T y;
        Fr y_witness;
        Value yhigh, ylow;
        std::size_t yhighCnt;
        if (R.splitBits().size() < 2 * sizeBits(yvalue)) {
            y_witness = ywitness;
            y = RS->argScalar(R);

            const std::vector<int> yrem = bitsValue(ylow, R.splitBits());
            bitsValue(yhigh, yrem);
            yhighCnt = yrem.size();

#ifdef USE_ASSERT
            assert(ylow == yvalue);
            assert(yhighCnt < sizeBits(yvalue));
#endif

        } else {
            y_witness = ALG::valueToString(yvalue);
            const std::vector<R1T> ybits = RS->argBits(R);
            const std::vector<R1T> yfit = rank1_xword(ybits, sizeBits(yvalue));
            y = RS->bitsToWitness(yfit, y_witness);

            ylow = yvalue;
            yhigh = 0;
            yhighCnt = 0;
        }

        // overflow addition
        Value high = xhigh + yhigh, low = xlow;
        addover(high, low, ylow);

        const Value zvalue = BitOps::ADDMOD(xvalue, yvalue);
#ifdef USE_ASSERT
        assert(zvalue == low);
#endif

        std::vector<int> zbits = valueBits(low);
        for (std::size_t i = 0; i < xhighCnt + yhighCnt + 1; ++i) {
            zbits.push_back(high & 0x1);
            high >>= 1;
        }
#ifdef USE_ASSERT
        assert(0 == high);
#endif

        const Fr zwitness = x_witness + y_witness;
        const R1T z = RS->createResult(op, x, y, zwitness);

        S.push(
            ALG(zvalue, zwitness, zbits, {z}));

    } else if (BitwiseOps::MULMOD == op) {
        // x is left argument
        const auto L = S.top();
        S.pop();
        const Value xvalue = L.value();
        const Fr x_witness = ALG::valueToString(xvalue);
        const std::vector<R1T> xbits = RS->argBits(L);
        const std::vector<R1T> xfit = rank1_xword(xbits, sizeBits(xvalue));
        const R1T x = RS->bitsToWitness(xfit, x_witness);

        // right argument
        const Fr y_witness = ALG::valueToString(yvalue);
        const std::vector<R1T> ybits = RS->argBits(R);
        const std::vector<R1T> yfit = rank1_xword(ybits, sizeBits(yvalue));
        const R1T y = RS->bitsToWitness(yfit, y_witness);

        // overflow multiplication
        Value high, low;
        mulover(high, low, xvalue, yvalue);

        const Value zvalue = BitOps::MULMOD(xvalue, yvalue);
#ifdef USE_ASSERT
        assert(zvalue == low);
#endif

        std::vector<int> zbits = valueBits(low);
        for (std::size_t i = 0; i < sizeBits(high); ++i) {
            zbits.push_back(high & 0x1);
            high >>= 1;
        }
#ifdef USE_ASSERT
        assert(0 == high);
#endif

        const Fr zwitness = x_witness * y_witness;
        const R1T z = RS->createResult(op, x, y, zwitness);

        S.push(
            ALG(zvalue, zwitness, zbits, {z}));

    } else if (BitwiseOps::CMPLMNT == op) {
        // y is only argument
        const std::vector<R1T> y = RS->argBits(R);
#ifdef USE_ASSERT
        assert(y.size() >= sizeBits(yvalue));
        assert(y.size() == R.splitBits().size());
#endif

        // z is result
        const Value zvalue = BitOps::CMPLMNT(yvalue);

        std::vector<int> zbits;
        std::vector<R1T> z;
        zbits.reserve(sizeBits(zvalue));
        z.reserve(sizeBits(zvalue));
        for (std::size_t i = 0; i < sizeBits(zvalue); ++i) {
            const bool b = ! R.splitBits()[i];
            zbits.push_back(b);
            z.emplace_back(
                RS->createResult(op, y[i], y[i], boolTo<Fr>(b)));
        }
#ifdef USE_ASSERT
        assert(zbits == valueBits(zvalue));
#endif

        S.push(
            ALG(zvalue, ALG::valueToString(zvalue), zbits, z));

    } else {
        // x is left argument
        const auto L = S.top();
        S.pop();
        const Value xvalue = L.value();
        const Fr xwitness = L.witness();

        const std::vector<R1T> x = RS->argBits(L);
#ifdef USE_ASSERT
        assert(x.size() >= sizeBits(xvalue));
#endif

        // z is result
        const Value zvalue = evalOp(op, xvalue, yvalue);

        std::vector<R1T> z;
        z.reserve(sizeBits(zvalue));

        if (isPermute(op)) {
            const std::vector<R1T> xfit = rank1_xword(x, sizeBits(xvalue));
            z = RS->permuteBits(op, xfit, yvalue);

        } else {
            const std::vector<R1T> y = RS->argBits(R);
#ifdef USE_ASSERT
            assert(y.size() >= sizeBits(yvalue));
#endif

            Value mask = 0x1;
            for (std::size_t i = 0; i < sizeBits(zvalue); ++i) {
                z.emplace_back(
                    RS->createResult(op, x[i], y[i], boolTo<Fr>(zvalue & mask)));

                mask <<= 1;
            }
        }

        S.push(
            ALG(zvalue, ALG::valueToString(zvalue), valueBits(zvalue), z));
    }
}

template <typename FR>
void evalStackOp(std::stack<Alg_uint8<FR>>& S, const BitwiseOps op) {
    evalStackOp_Bitwise<Alg_uint8<FR>>(S, op);
}

template <typename FR>
void evalStackOp(std::stack<Alg_uint32<FR>>& S, const BitwiseOps op) {
    evalStackOp_Bitwise<Alg_uint32<FR>>(S, op);
}

template <typename FR>
void evalStackOp(std::stack<Alg_uint64<FR>>& S, const BitwiseOps op) {
    evalStackOp_Bitwise<Alg_uint64<FR>>(S, op);
}

template <typename FR>
void evalStackCmp(std::stack<Alg_uint8<FR>>& S, const EqualityCmp op) {
    evalStackCmp_Equality(S, op);
}

template <typename FR>
void evalStackCmp(std::stack<Alg_uint32<FR>>& S, const EqualityCmp op) {
    evalStackCmp_Equality(S, op);
}

template <typename FR>
void evalStackCmp(std::stack<Alg_uint64<FR>>& S, const EqualityCmp op) {
    evalStackCmp_Equality(S, op);
}

} // namespace snarkfront

#endif
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#include "itkExceptionObject.h"

#include "otbWindowedSincInterpolateImageFunction.h"
#include "itkConstantBoundaryCondition.h"
#include "otbImage.h"
#include "otbImageFileReader.h"

#include "otbStreamingImageFileWriter.h"
#include "itkTranslationTransform.h"
#include "otbStreamingResampleImageFilter.h"

int otbWindowedSincInterpolateImageFunction(int argc, char * argv[])
{
  const char * infname = argv[1];
  const char * outfname = argv[2];

  typedef otb::Image<double,2>                                                ImageType;
  // Gaussian
  typedef otb::Function::GaussianWindowFunction<double, double>               GaussType;
  typedef otb::WindowedSincInterpolateImageFunction<ImageType, GaussType>     GaussInterpolatorType;
  typedef GaussInterpolatorType::ContinuousIndexType                          GaussContinuousIndexType;
  // Cosine
  typedef otb::Function::CosineWindowFunction<double, double>                 CosType;
  typedef otb::WindowedSincInterpolateImageFunction<ImageType, CosType>       CosInterpolatorType;
  typedef CosInterpolatorType::ContinuousIndexType                            CosContinuousIndexType;
  // Hamming
  typedef otb::Function::HammingWindowFunction<double, double>                HammingType;
  typedef otb::WindowedSincInterpolateImageFunction<ImageType, HammingType>   HammingInterpolatorType;
  typedef HammingInterpolatorType::ContinuousIndexType                        HammingContinuousIndexType;
  // Welch
  typedef otb::Function::WelchWindowFunction<double, double>                  WelchType;
  typedef otb::WindowedSincInterpolateImageFunction<ImageType,WelchType>      WelchInterpolatorType;
  typedef WelchInterpolatorType::ContinuousIndexType                          WelchContinuousIndexType;
  // Lanczos
  typedef otb::Function::LanczosWindowFunction<double, double>                LanczosType;
  typedef otb::WindowedSincInterpolateImageFunction<ImageType, LanczosType>   LanczosInterpolatorType;
  typedef LanczosInterpolatorType::ContinuousIndexType                        LanczosContinuousIndexType;
  // Blackman
  typedef otb::Function::BlackmanWindowFunction<double, double>               BlackmanType;
  typedef otb::WindowedSincInterpolateImageFunction<ImageType, BlackmanType>  BlackmanInterpolatorType;
  typedef BlackmanInterpolatorType::ContinuousIndexType                       BlackmanContinuousIndexType;

  typedef otb::ImageFileReader<ImageType>                                     ReaderType;

  // Instantiating objects
  GaussInterpolatorType::Pointer    gauss    = GaussInterpolatorType::New();
  CosInterpolatorType::Pointer      cos      = CosInterpolatorType::New();
  HammingInterpolatorType::Pointer  hamming  = HammingInterpolatorType::New();
  WelchInterpolatorType::Pointer    welch    = WelchInterpolatorType::New();
  LanczosInterpolatorType::Pointer  lanczos  = LanczosInterpolatorType::New();
  BlackmanInterpolatorType::Pointer blackman = BlackmanInterpolatorType::New();

  unsigned int i = 4;

  std::vector<GaussContinuousIndexType>    gaussindicesList;
  std::vector<CosContinuousIndexType>      cosindicesList;
  std::vector<HammingContinuousIndexType>  hammingindicesList;
  std::vector<WelchContinuousIndexType>    welchindicesList;
  std::vector<LanczosContinuousIndexType>  lanczosindicesList;
  std::vector<BlackmanContinuousIndexType> blackmanindicesList;
  while(i<static_cast<unsigned int>(argc) && (i+1)<static_cast<unsigned int>(argc))
    {
      GaussContinuousIndexType idx1;
      idx1[0]=atof(argv[i]);
      idx1[1]=atof(argv[i+1]);
      gaussindicesList.push_back(idx1);
      CosContinuousIndexType idx2;
      idx2[0]=atof(argv[i]);
      idx2[1]=atof(argv[i+1]);
      cosindicesList.push_back(idx2);
      HammingContinuousIndexType idx3;
      idx3[0]=atof(argv[i]);
      idx3[1]=atof(argv[i+1]);
      hammingindicesList.push_back(idx3);
      WelchContinuousIndexType idx4;
      idx4[0]=atof(argv[i]);
      idx4[1]=atof(argv[i+1]);
      welchindicesList.push_back(idx4);
      LanczosContinuousIndexType idx5;
      idx5[0]=atof(argv[i]);
      idx5[1]=atof(argv[i+1]);
      lanczosindicesList.push_back(idx5);
      BlackmanContinuousIndexType idx6;
      idx6[0]=atof(argv[i]);
      idx6[1]=atof(argv[i+1]);
      blackmanindicesList.push_back(idx6);
      i+=2;
    }

  ReaderType::Pointer reader = ReaderType::New();
  reader->SetFileName(infname);
  reader->Update();
  gauss->SetInputImage(reader->GetOutput());
  gauss->SetRadius(atoi(argv[3]));
  cos->SetInputImage(reader->GetOutput());
  cos->SetRadius(atoi(argv[3]));
  hamming->SetInputImage(reader->GetOutput());
  hamming->SetRadius(atoi(argv[3]));
  welch->SetInputImage(reader->GetOutput());
  welch->SetRadius(atoi(argv[3]));
  lanczos->SetInputImage(reader->GetOutput());
  lanczos->SetRadius(atoi(argv[3]));
  blackman->SetInputImage(reader->GetOutput());
  blackman->SetRadius(atoi(argv[3]));

  std::ofstream file;
  file.open(outfname);

  file << "Gauss Window Function"<<std::endl;
  for(std::vector<GaussContinuousIndexType>::iterator it = gaussindicesList.begin();it!=gaussindicesList.end();++it)
    {
      file<<(*it)<<" -> "<<gauss->EvaluateAtContinuousIndex((*it))<<std::endl;
    }
  file << std::endl;

  file << "Cosine Window Function"<<std::endl;
  for(std::vector<CosContinuousIndexType>::iterator it = cosindicesList.begin();it!=cosindicesList.end();++it)
    {
      file<<(*it)<<" -> "<<cos->EvaluateAtContinuousIndex((*it))<<std::endl;
    }
  file << std::endl;

  file << "Hamming Window Function"<<std::endl;
  for(std::vector<HammingContinuousIndexType>::iterator it = hammingindicesList.begin();it!=hammingindicesList.end();++it)
    {
      file<<(*it)<<" -> "<<hamming->EvaluateAtContinuousIndex((*it))<<std::endl;
    }
  file << std::endl;

  file << "Welch Window Function"<<std::endl;
  for(std::vector<WelchContinuousIndexType>::iterator it = welchindicesList.begin();it!=welchindicesList.end();++it)
    {
      file<<(*it)<<" -> "<<welch->EvaluateAtContinuousIndex((*it))<<std::endl;
    }
  file << std::endl;

  file << "Lanczos Window Function"<<std::endl;
  for(std::vector<LanczosContinuousIndexType>::iterator it = lanczosindicesList.begin();it!=lanczosindicesList.end();++it)
    {
      file<<(*it)<<" -> "<<lanczos->EvaluateAtContinuousIndex((*it))<<std::endl;
    }
  file << std::endl;

  file << "Blackman Window Function"<<std::endl;
  for(std::vector<BlackmanContinuousIndexType>::iterator it = blackmanindicesList.begin();it!=blackmanindicesList.end();++it)
    {
      file<<(*it)<<" -> "<<blackman->EvaluateAtContinuousIndex((*it))<<std::endl;
    }

  file.close();

  /**********************************************/
  typedef otb::StreamingImageFileWriter<ImageType> WriterType;
  typedef itk::TranslationTransform<double,2> TransformType;
  typedef otb::StreamingResampleImageFilter<ImageType,ImageType,double> StreamingResampleImageFilterType;

  // Instantiating object
  WriterType::Pointer writer = WriterType::New();
  StreamingResampleImageFilterType::Pointer resampler = StreamingResampleImageFilterType::New();
  TransformType::Pointer transform = TransformType::New();

  // Resampler connected to input image
  resampler->SetInput(reader->GetOutput());

  // Size of output resampler result
  StreamingResampleImageFilterType::SizeType size;
  size[0]=600;
  size[1]=600;
  resampler->SetSize(size);

  resampler->SetInterpolatorNeighborhoodRadius(atoi(argv[3]));
  resampler->SetInterpolator(gauss);

  // Transformation creation
  TransformType::OutputVectorType translation;
  translation[0] = 100;
  translation[1] = 200;
  transform->SetOffset(translation);

  // Resampler is updated with new transformation (default is identity)
  resampler->SetTransform(transform);

  // Result of resampler is written
  writer->SetInput(resampler->GetOutput());
  writer->SetNumberOfStreamDivisions(1);
  writer->SetFileName("tutu.tif");

  writer->Update();

  return EXIT_SUCCESS;
}
<commit_msg>oups... oubli d'un bout de commit.<commit_after>/*=========================================================================

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#include "itkExceptionObject.h"

#include "otbWindowedSincInterpolateImageFunction.h"
#include "itkConstantBoundaryCondition.h"
#include "otbImage.h"
#include "otbImageFileReader.h"

#include "otbStreamingImageFileWriter.h"
#include "itkTranslationTransform.h"
#include "otbStreamingResampleImageFilter.h"

int otbWindowedSincInterpolateImageFunction(int argc, char * argv[])
{
  const char * infname = argv[1];
  const char * outfname = argv[2];

  typedef otb::Image<double,2>                                                ImageType;
  // Gaussian
  typedef otb::Function::GaussianWindowFunction<double, double>               GaussType;
  typedef otb::WindowedSincInterpolateImageFunction<ImageType, GaussType>     GaussInterpolatorType;
  typedef GaussInterpolatorType::ContinuousIndexType                          GaussContinuousIndexType;
  // Cosine
  typedef otb::Function::CosineWindowFunction<double, double>                 CosType;
  typedef otb::WindowedSincInterpolateImageFunction<ImageType, CosType>       CosInterpolatorType;
  typedef CosInterpolatorType::ContinuousIndexType                            CosContinuousIndexType;
  // Hamming
  typedef otb::Function::HammingWindowFunction<double, double>                HammingType;
  typedef otb::WindowedSincInterpolateImageFunction<ImageType, HammingType>   HammingInterpolatorType;
  typedef HammingInterpolatorType::ContinuousIndexType                        HammingContinuousIndexType;
  // Welch
  typedef otb::Function::WelchWindowFunction<double, double>                  WelchType;
  typedef otb::WindowedSincInterpolateImageFunction<ImageType,WelchType>      WelchInterpolatorType;
  typedef WelchInterpolatorType::ContinuousIndexType                          WelchContinuousIndexType;
  // Lanczos
  typedef otb::Function::LanczosWindowFunction<double, double>                LanczosType;
  typedef otb::WindowedSincInterpolateImageFunction<ImageType, LanczosType>   LanczosInterpolatorType;
  typedef LanczosInterpolatorType::ContinuousIndexType                        LanczosContinuousIndexType;
  // Blackman
  typedef otb::Function::BlackmanWindowFunction<double, double>               BlackmanType;
  typedef otb::WindowedSincInterpolateImageFunction<ImageType, BlackmanType>  BlackmanInterpolatorType;
  typedef BlackmanInterpolatorType::ContinuousIndexType                       BlackmanContinuousIndexType;

  typedef otb::ImageFileReader<ImageType>                                     ReaderType;

  // Instantiating objects
  GaussInterpolatorType::Pointer    gauss    = GaussInterpolatorType::New();
  CosInterpolatorType::Pointer      cos      = CosInterpolatorType::New();
  HammingInterpolatorType::Pointer  hamming  = HammingInterpolatorType::New();
  WelchInterpolatorType::Pointer    welch    = WelchInterpolatorType::New();
  LanczosInterpolatorType::Pointer  lanczos  = LanczosInterpolatorType::New();
  BlackmanInterpolatorType::Pointer blackman = BlackmanInterpolatorType::New();

  unsigned int i = 4;

  std::vector<GaussContinuousIndexType>    gaussindicesList;
  std::vector<CosContinuousIndexType>      cosindicesList;
  std::vector<HammingContinuousIndexType>  hammingindicesList;
  std::vector<WelchContinuousIndexType>    welchindicesList;
  std::vector<LanczosContinuousIndexType>  lanczosindicesList;
  std::vector<BlackmanContinuousIndexType> blackmanindicesList;
  while(i<static_cast<unsigned int>(argc) && (i+1)<static_cast<unsigned int>(argc))
    {
      GaussContinuousIndexType idx1;
      idx1[0]=atof(argv[i]);
      idx1[1]=atof(argv[i+1]);
      gaussindicesList.push_back(idx1);
      CosContinuousIndexType idx2;
      idx2[0]=atof(argv[i]);
      idx2[1]=atof(argv[i+1]);
      cosindicesList.push_back(idx2);
      HammingContinuousIndexType idx3;
      idx3[0]=atof(argv[i]);
      idx3[1]=atof(argv[i+1]);
      hammingindicesList.push_back(idx3);
      WelchContinuousIndexType idx4;
      idx4[0]=atof(argv[i]);
      idx4[1]=atof(argv[i+1]);
      welchindicesList.push_back(idx4);
      LanczosContinuousIndexType idx5;
      idx5[0]=atof(argv[i]);
      idx5[1]=atof(argv[i+1]);
      lanczosindicesList.push_back(idx5);
      BlackmanContinuousIndexType idx6;
      idx6[0]=atof(argv[i]);
      idx6[1]=atof(argv[i+1]);
      blackmanindicesList.push_back(idx6);
      i+=2;
    }

  ReaderType::Pointer reader = ReaderType::New();
  reader->SetFileName(infname);
  reader->Update();
  gauss->SetInputImage(reader->GetOutput());
  gauss->SetRadius(atoi(argv[3]));
  cos->SetInputImage(reader->GetOutput());
  cos->SetRadius(atoi(argv[3]));
  hamming->SetInputImage(reader->GetOutput());
  hamming->SetRadius(atoi(argv[3]));
  welch->SetInputImage(reader->GetOutput());
  welch->SetRadius(atoi(argv[3]));
  lanczos->SetInputImage(reader->GetOutput());
  lanczos->SetRadius(atoi(argv[3]));
  blackman->SetInputImage(reader->GetOutput());
  blackman->SetRadius(atoi(argv[3]));

  std::ofstream file;
  file.open(outfname);

  file << "Gauss Window Function"<<std::endl;
  for(std::vector<GaussContinuousIndexType>::iterator it = gaussindicesList.begin();it!=gaussindicesList.end();++it)
    {
      file<<(*it)<<" -> "<<gauss->EvaluateAtContinuousIndex((*it))<<std::endl;
    }
  file << std::endl;

  file << "Cosine Window Function"<<std::endl;
  for(std::vector<CosContinuousIndexType>::iterator it = cosindicesList.begin();it!=cosindicesList.end();++it)
    {
      file<<(*it)<<" -> "<<cos->EvaluateAtContinuousIndex((*it))<<std::endl;
    }
  file << std::endl;

  file << "Hamming Window Function"<<std::endl;
  for(std::vector<HammingContinuousIndexType>::iterator it = hammingindicesList.begin();it!=hammingindicesList.end();++it)
    {
      file<<(*it)<<" -> "<<hamming->EvaluateAtContinuousIndex((*it))<<std::endl;
    }
  file << std::endl;

  file << "Welch Window Function"<<std::endl;
  for(std::vector<WelchContinuousIndexType>::iterator it = welchindicesList.begin();it!=welchindicesList.end();++it)
    {
      file<<(*it)<<" -> "<<welch->EvaluateAtContinuousIndex((*it))<<std::endl;
    }
  file << std::endl;

  file << "Lanczos Window Function"<<std::endl;
  for(std::vector<LanczosContinuousIndexType>::iterator it = lanczosindicesList.begin();it!=lanczosindicesList.end();++it)
    {
      file<<(*it)<<" -> "<<lanczos->EvaluateAtContinuousIndex((*it))<<std::endl;
    }
  file << std::endl;

  file << "Blackman Window Function"<<std::endl;
  for(std::vector<BlackmanContinuousIndexType>::iterator it = blackmanindicesList.begin();it!=blackmanindicesList.end();++it)
    {
      file<<(*it)<<" -> "<<blackman->EvaluateAtContinuousIndex((*it))<<std::endl;
    }

  file.close();

  return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>/*
 *  Copyright (c) 2014, Facebook, Inc.
 *  All rights reserved.
 *
 *  This source code is licensed under the BSD-style license found in the
 *  LICENSE file in the root directory of this source tree. An additional grant
 *  of patent rights can be found in the PATENTS file in the same directory.
 *
 */

#include <chrono>
#include <random>

#include <syslog.h>
#include <stdio.h>
#include <time.h>
#include <unistd.h>

#include <boost/algorithm/string/trim.hpp>
#include <boost/filesystem.hpp>

#include <osquery/config.h>
#include <osquery/core.h>
#include <osquery/events.h>
#include <osquery/extensions.h>
#include <osquery/flags.h>
#include <osquery/filesystem.h>
#include <osquery/logger.h>
#include <osquery/registry.h>

#include "osquery/core/watcher.h"
#include "osquery/database/db_handle.h"

#ifdef __linux__
#include <sys/resource.h>
#include <sys/syscall.h>

/*
 * These are the io priority groups as implemented by CFQ. RT is the realtime
 * class, it always gets premium service. BE is the best-effort scheduling
 * class, the default for any process. IDLE is the idle scheduling class, it
 * is only served when no one else is using the disk.
 */
enum {
  IOPRIO_CLASS_NONE,
  IOPRIO_CLASS_RT,
  IOPRIO_CLASS_BE,
  IOPRIO_CLASS_IDLE,
};

/*
 * 8 best effort priority levels are supported
 */
#define IOPRIO_BE_NR  (8)

enum {
  IOPRIO_WHO_PROCESS = 1,
  IOPRIO_WHO_PGRP,
  IOPRIO_WHO_USER,
};
#endif

namespace fs = boost::filesystem;

namespace osquery {

#define DESCRIPTION \
  "osquery %s, your OS as a high-performance relational database\n"
#define EPILOG "\nosquery project page <https://osquery.io>.\n"
#define OPTIONS \
  "\nosquery configuration options (set by config or CLI flags):\n\n"
#define OPTIONS_SHELL "\nosquery shell-only CLI flags:\n\n"
#define OPTIONS_CLI "osquery%s command line flags:\n\n"
#define USAGE "Usage: %s [OPTION]... %s\n\n"
#define CONFIG_ERROR                                                          \
  "You are using default configurations for osqueryd for one or more of the " \
  "following\n"                                                               \
  "flags: pidfile, db_path.\n\n"                                              \
  "These options create files in /var/osquery but it looks like that path "   \
  "has not\n"                                                                 \
  "been created. Please consider explicitly defining those "                  \
  "options as a different \n"                                                 \
  "path. Additionally, review the \"using osqueryd\" wiki page:\n"            \
  " - https://osquery.readthedocs.org/en/latest/introduction/using-osqueryd/" \
  "\n\n";

typedef std::chrono::high_resolution_clock chrono_clock;

CLI_FLAG(bool,
         config_check,
         false,
         "Check the format of an osquery config and exit");

#ifndef __APPLE__
CLI_FLAG(bool, daemonize, false, "Run as daemon (osqueryd only)");
#endif

void printUsage(const std::string& binary, int tool) {
  // Parse help options before gflags. Only display osquery-related options.
  fprintf(stdout, DESCRIPTION, OSQUERY_VERSION);
  if (tool == OSQUERY_TOOL_SHELL) {
    // The shell allows a caller to run a single SQL statement and exit.
    fprintf(stdout, USAGE, binary.c_str(), "[SQL STATEMENT]");
  } else {
    fprintf(stdout, USAGE, binary.c_str(), "");
  }

  if (tool == OSQUERY_EXTENSION) {
    fprintf(stdout, OPTIONS_CLI, " extension");
    Flag::printFlags(false, true);
  } else {
    fprintf(stdout, OPTIONS_CLI, "");
    Flag::printFlags(false, false, true);
    fprintf(stdout, OPTIONS);
    Flag::printFlags();
  }

  if (tool == OSQUERY_TOOL_SHELL) {
    // Print shell flags.
    fprintf(stdout, OPTIONS_SHELL);
    Flag::printFlags(true);
  }

  fprintf(stdout, EPILOG);
}

Initializer::Initializer(int& argc, char**& argv, ToolType tool)
    : argc_(&argc),
      argv_(&argv),
      tool_(tool),
      binary_(fs::path(std::string(argv[0])).filename().string()) {
  std::srand(chrono_clock::now().time_since_epoch().count());

  // osquery implements a custom help/usage output.
  for (int i = 1; i < *argc_; i++) {
    auto help = std::string((*argv_)[i]);
    if ((help == "--help" || help == "-help" || help == "--h" ||
         help == "-h") &&
        tool != OSQUERY_TOOL_TEST) {
      printUsage(binary_, tool_);
      ::exit(0);
    }
  }

// To change the default config plugin, compile osquery with
// -DOSQUERY_DEFAULT_CONFIG_PLUGIN=<new_default_plugin>
#ifdef OSQUERY_DEFAULT_CONFIG_PLUGIN
  FLAGS_config_plugin = STR(OSQUERY_DEFAULT_CONFIG_PLUGIN);
#endif

// To change the default logger plugin, compile osquery with
// -DOSQUERY_DEFAULT_LOGGER_PLUGIN=<new_default_plugin>
#ifdef OSQUERY_DEFAULT_LOGGER_PLUGIN
  FLAGS_logger_plugin = STR(OSQUERY_DEFAULT_LOGGER_PLUGIN);
#endif

  // Set version string from CMake build
  GFLAGS_NAMESPACE::SetVersionString(OSQUERY_VERSION);

  // Let gflags parse the non-help options/flags.
  GFLAGS_NAMESPACE::ParseCommandLineFlags(
      argc_, argv_, (tool == OSQUERY_TOOL_SHELL));

  if (tool == OSQUERY_TOOL_SHELL) {
    // The shell is transient, rewrite config-loaded paths.
    FLAGS_disable_logging = true;
    // Get the caller's home dir for temporary storage/state management.
    auto homedir = osqueryHomeDirectory();
    if (osquery::pathExists(homedir).ok() ||
        boost::filesystem::create_directory(homedir)) {
      // Only apply user/shell-specific paths if not overridden by CLI flag.
      if (Flag::isDefault("database_path")) {
        osquery::FLAGS_database_path = homedir + "/shell.db";
      }
      if (Flag::isDefault("extension_socket")) {
        osquery::FLAGS_extensions_socket = homedir + "/shell.em";
      }
    }
  }

  // If the caller is checking configuration, disable the watchdog/worker.
  if (FLAGS_config_check) {
    FLAGS_disable_watchdog = true;
  }

  // Initialize the status and results logger.
  initStatusLogger(binary_);
  if (tool != OSQUERY_EXTENSION) {
    if (isWorker()) {
      VLOG(1) << "osquery worker initialized [watcher="
              << getenv("OSQUERY_WORKER") << "]";
    } else {
      VLOG(1) << "osquery initialized [version=" << OSQUERY_VERSION << "]";
    }
  } else {
    VLOG(1) << "osquery extension initialized [sdk=" << OSQUERY_SDK_VERSION
            << "]";
  }
}

void Initializer::initDaemon() {
  if (FLAGS_config_check) {
    // No need to daemonize, emit log lines, or create process mutexes.
    return;
  }

#ifndef __APPLE__
  // OSX uses launchd to daemonize.
  if (osquery::FLAGS_daemonize) {
    if (daemon(0, 0) == -1) {
      ::exit(EXIT_FAILURE);
    }
  }
#endif

  // Print the version to SYSLOG.
  syslog(
      LOG_NOTICE, "%s started [version=%s]", binary_.c_str(), OSQUERY_VERSION);

  // Check if /var/osquery exists
  if ((Flag::isDefault("pidfile") || Flag::isDefault("database_path")) &&
      !isDirectory("/var/osquery")) {
    std::cerr << CONFIG_ERROR
  }

  // Create a process mutex around the daemon.
  auto pid_status = createPidFile();
  if (!pid_status.ok()) {
    LOG(ERROR) << binary_ << " initialize failed: " << pid_status.toString();
    ::exit(EXIT_FAILURE);
  }

  // Nice ourselves if using a watchdog and the level is not too permissive.
  if (!FLAGS_disable_watchdog &&
      FLAGS_watchdog_level >= WATCHDOG_LEVEL_DEFAULT &&
      FLAGS_watchdog_level != WATCHDOG_LEVEL_DEBUG) {
    // Set CPU scheduling IO limits.
    setpriority(PRIO_PGRP, 0, 10);
#ifdef __linux__
    // Using: ioprio_set(IOPRIO_WHO_PGRP, 0, IOPRIO_CLASS_IDLE);
    syscall(SYS_ioprio_set, IOPRIO_WHO_PGRP, 0, IOPRIO_CLASS_IDLE);
#elif defined(__APPLE__) || defined(__FreeBSD__)
    setiopolicy_np(IOPOL_TYPE_DISK, IOPOL_SCOPE_PROCESS, IOPOL_THROTTLE);
#endif
  }
}

void Initializer::initWatcher() {
  // The watcher takes a list of paths to autoload extensions from.
  osquery::loadExtensions();

  // Add a watcher service thread to start/watch an optional worker and set
  // of optional extensions in the autoload paths.
  if (Watcher::hasManagedExtensions() || !FLAGS_disable_watchdog) {
    Dispatcher::addService(std::make_shared<WatcherRunner>(
        *argc_, *argv_, !FLAGS_disable_watchdog));
  }

  // If there are no autoloaded extensions, the watcher service will end,
  // otherwise it will continue as a background thread and respawn them.
  // If the watcher is also a worker watchdog it will do nothing but monitor
  // the extensions and worker process.
  if (!FLAGS_disable_watchdog) {
    Dispatcher::joinServices();
    // Execution should never reach this point.
    ::exit(EXIT_FAILURE);
  }
}

void Initializer::initWorker(const std::string& name) {
  // Clear worker's arguments.
  size_t name_size = strlen((*argv_)[0]);
  for (int i = 0; i < *argc_; i++) {
    if ((*argv_)[i] != nullptr) {
      memset((*argv_)[i], 0, strlen((*argv_)[i]));
    }
  }

  // Set the worker's process name.
  if (name.size() <= name_size) {
    std::copy(name.begin(), name.end(), (*argv_)[0]);
  }

  // Start a watcher watcher thread to exit the process if the watcher exits.
  Dispatcher::addService(std::make_shared<WatcherWatcherRunner>(getppid()));
}

void Initializer::initWorkerWatcher(const std::string& name) {
  if (isWorker()) {
    initWorker(name);
  } else {
    // The watcher will forever monitor and spawn additional workers.
    initWatcher();
  }
}

bool Initializer::isWorker() { return (getenv("OSQUERY_WORKER") != nullptr); }

void Initializer::initActivePlugin(const std::string& type,
                                   const std::string& name) {
  // Use a delay, meaning the amount of milliseconds waited for extensions.
  size_t delay = 0;
  // The timeout is the maximum time in seconds to wait for extensions.
  size_t timeout = atoi(FLAGS_extensions_timeout.c_str());
  while (!Registry::setActive(type, name)) {
    if (!Watcher::hasManagedExtensions() || delay > timeout * 1000) {
      LOG(ERROR) << "Active " << type << " plugin not found: " << name;
      ::exit(EXIT_CATASTROPHIC);
    }
    ::usleep(kExtensionInitializeMLatency * 1000);
    delay += kExtensionInitializeMLatency;
  }
}

void Initializer::start() {
  // Load registry/extension modules before extensions.
  osquery::loadModules();

  // Pre-extension manager initialization options checking.
  if (FLAGS_config_check && !Watcher::hasManagedExtensions()) {
    FLAGS_disable_extensions = true;
  }

  // Check the backing store by allocating and exiting on error.
  if (!DBHandle::checkDB()) {
    LOG(ERROR) << binary_ << " initialize failed: Could not open RocksDB";
    if (isWorker()) {
      ::exit(EXIT_CATASTROPHIC);
    } else {
      ::exit(EXIT_FAILURE);
    }
  }

  // Bind to an extensions socket and wait for registry additions.
  osquery::startExtensionManager();

  // Then set the config plugin, which uses a single/active plugin.
  initActivePlugin("config", FLAGS_config_plugin);

  // Run the setup for all lazy registries (tables, SQL).
  Registry::setUp();

  if (FLAGS_config_check) {
    // The initiator requested an initialization and config check.
    auto s = Config::checkConfig();
    if (!s.ok()) {
      std::cerr << "Error reading config: " << s.toString() << "\n";
    }
    // A configuration check exits the application.
    ::exit(s.getCode());
  }

  // Load the osquery config using the default/active config plugin.
  Config::load();

  // Initialize the status and result plugin logger.
  initActivePlugin("logger", FLAGS_logger_plugin);
  initLogger(binary_);

  // Start event threads.
  osquery::attachEvents();
  EventFactory::delay();
}

void Initializer::shutdown() {
  // End any event type run loops.
  EventFactory::end();

  // Hopefully release memory used by global string constructors in gflags.
  GFLAGS_NAMESPACE::ShutDownCommandLineFlags();
}
}
<commit_msg>[Fix #1202] Replace argv[*] with spaces, fallback to path in [0]<commit_after>/*
 *  Copyright (c) 2014, Facebook, Inc.
 *  All rights reserved.
 *
 *  This source code is licensed under the BSD-style license found in the
 *  LICENSE file in the root directory of this source tree. An additional grant
 *  of patent rights can be found in the PATENTS file in the same directory.
 *
 */

#include <chrono>
#include <random>

#include <syslog.h>
#include <stdio.h>
#include <time.h>
#include <unistd.h>

#include <boost/algorithm/string/trim.hpp>
#include <boost/filesystem.hpp>

#include <osquery/config.h>
#include <osquery/core.h>
#include <osquery/events.h>
#include <osquery/extensions.h>
#include <osquery/flags.h>
#include <osquery/filesystem.h>
#include <osquery/logger.h>
#include <osquery/registry.h>

#include "osquery/core/watcher.h"
#include "osquery/database/db_handle.h"

#ifdef __linux__
#include <sys/resource.h>
#include <sys/syscall.h>

/*
 * These are the io priority groups as implemented by CFQ. RT is the realtime
 * class, it always gets premium service. BE is the best-effort scheduling
 * class, the default for any process. IDLE is the idle scheduling class, it
 * is only served when no one else is using the disk.
 */
enum {
  IOPRIO_CLASS_NONE,
  IOPRIO_CLASS_RT,
  IOPRIO_CLASS_BE,
  IOPRIO_CLASS_IDLE,
};

/*
 * 8 best effort priority levels are supported
 */
#define IOPRIO_BE_NR  (8)

enum {
  IOPRIO_WHO_PROCESS = 1,
  IOPRIO_WHO_PGRP,
  IOPRIO_WHO_USER,
};
#endif

namespace fs = boost::filesystem;

namespace osquery {

#define DESCRIPTION \
  "osquery %s, your OS as a high-performance relational database\n"
#define EPILOG "\nosquery project page <https://osquery.io>.\n"
#define OPTIONS \
  "\nosquery configuration options (set by config or CLI flags):\n\n"
#define OPTIONS_SHELL "\nosquery shell-only CLI flags:\n\n"
#define OPTIONS_CLI "osquery%s command line flags:\n\n"
#define USAGE "Usage: %s [OPTION]... %s\n\n"
#define CONFIG_ERROR                                                          \
  "You are using default configurations for osqueryd for one or more of the " \
  "following\n"                                                               \
  "flags: pidfile, db_path.\n\n"                                              \
  "These options create files in /var/osquery but it looks like that path "   \
  "has not\n"                                                                 \
  "been created. Please consider explicitly defining those "                  \
  "options as a different \n"                                                 \
  "path. Additionally, review the \"using osqueryd\" wiki page:\n"            \
  " - https://osquery.readthedocs.org/en/latest/introduction/using-osqueryd/" \
  "\n\n";

typedef std::chrono::high_resolution_clock chrono_clock;

CLI_FLAG(bool,
         config_check,
         false,
         "Check the format of an osquery config and exit");

#ifndef __APPLE__
CLI_FLAG(bool, daemonize, false, "Run as daemon (osqueryd only)");
#endif

void printUsage(const std::string& binary, int tool) {
  // Parse help options before gflags. Only display osquery-related options.
  fprintf(stdout, DESCRIPTION, OSQUERY_VERSION);
  if (tool == OSQUERY_TOOL_SHELL) {
    // The shell allows a caller to run a single SQL statement and exit.
    fprintf(stdout, USAGE, binary.c_str(), "[SQL STATEMENT]");
  } else {
    fprintf(stdout, USAGE, binary.c_str(), "");
  }

  if (tool == OSQUERY_EXTENSION) {
    fprintf(stdout, OPTIONS_CLI, " extension");
    Flag::printFlags(false, true);
  } else {
    fprintf(stdout, OPTIONS_CLI, "");
    Flag::printFlags(false, false, true);
    fprintf(stdout, OPTIONS);
    Flag::printFlags();
  }

  if (tool == OSQUERY_TOOL_SHELL) {
    // Print shell flags.
    fprintf(stdout, OPTIONS_SHELL);
    Flag::printFlags(true);
  }

  fprintf(stdout, EPILOG);
}

Initializer::Initializer(int& argc, char**& argv, ToolType tool)
    : argc_(&argc),
      argv_(&argv),
      tool_(tool),
      binary_(fs::path(std::string(argv[0])).filename().string()) {
  std::srand(chrono_clock::now().time_since_epoch().count());

  // osquery implements a custom help/usage output.
  for (int i = 1; i < *argc_; i++) {
    auto help = std::string((*argv_)[i]);
    if ((help == "--help" || help == "-help" || help == "--h" ||
         help == "-h") &&
        tool != OSQUERY_TOOL_TEST) {
      printUsage(binary_, tool_);
      ::exit(0);
    }
  }

// To change the default config plugin, compile osquery with
// -DOSQUERY_DEFAULT_CONFIG_PLUGIN=<new_default_plugin>
#ifdef OSQUERY_DEFAULT_CONFIG_PLUGIN
  FLAGS_config_plugin = STR(OSQUERY_DEFAULT_CONFIG_PLUGIN);
#endif

// To change the default logger plugin, compile osquery with
// -DOSQUERY_DEFAULT_LOGGER_PLUGIN=<new_default_plugin>
#ifdef OSQUERY_DEFAULT_LOGGER_PLUGIN
  FLAGS_logger_plugin = STR(OSQUERY_DEFAULT_LOGGER_PLUGIN);
#endif

  // Set version string from CMake build
  GFLAGS_NAMESPACE::SetVersionString(OSQUERY_VERSION);

  // Let gflags parse the non-help options/flags.
  GFLAGS_NAMESPACE::ParseCommandLineFlags(
      argc_, argv_, (tool == OSQUERY_TOOL_SHELL));

  if (tool == OSQUERY_TOOL_SHELL) {
    // The shell is transient, rewrite config-loaded paths.
    FLAGS_disable_logging = true;
    // Get the caller's home dir for temporary storage/state management.
    auto homedir = osqueryHomeDirectory();
    if (osquery::pathExists(homedir).ok() ||
        boost::filesystem::create_directory(homedir)) {
      // Only apply user/shell-specific paths if not overridden by CLI flag.
      if (Flag::isDefault("database_path")) {
        osquery::FLAGS_database_path = homedir + "/shell.db";
      }
      if (Flag::isDefault("extension_socket")) {
        osquery::FLAGS_extensions_socket = homedir + "/shell.em";
      }
    }
  }

  // If the caller is checking configuration, disable the watchdog/worker.
  if (FLAGS_config_check) {
    FLAGS_disable_watchdog = true;
  }

  // Initialize the status and results logger.
  initStatusLogger(binary_);
  if (tool != OSQUERY_EXTENSION) {
    if (isWorker()) {
      VLOG(1) << "osquery worker initialized [watcher="
              << getenv("OSQUERY_WORKER") << "]";
    } else {
      VLOG(1) << "osquery initialized [version=" << OSQUERY_VERSION << "]";
    }
  } else {
    VLOG(1) << "osquery extension initialized [sdk=" << OSQUERY_SDK_VERSION
            << "]";
  }
}

void Initializer::initDaemon() {
  if (FLAGS_config_check) {
    // No need to daemonize, emit log lines, or create process mutexes.
    return;
  }

#ifndef __APPLE__
  // OSX uses launchd to daemonize.
  if (osquery::FLAGS_daemonize) {
    if (daemon(0, 0) == -1) {
      ::exit(EXIT_FAILURE);
    }
  }
#endif

  // Print the version to SYSLOG.
  syslog(
      LOG_NOTICE, "%s started [version=%s]", binary_.c_str(), OSQUERY_VERSION);

  // Check if /var/osquery exists
  if ((Flag::isDefault("pidfile") || Flag::isDefault("database_path")) &&
      !isDirectory("/var/osquery")) {
    std::cerr << CONFIG_ERROR
  }

  // Create a process mutex around the daemon.
  auto pid_status = createPidFile();
  if (!pid_status.ok()) {
    LOG(ERROR) << binary_ << " initialize failed: " << pid_status.toString();
    ::exit(EXIT_FAILURE);
  }

  // Nice ourselves if using a watchdog and the level is not too permissive.
  if (!FLAGS_disable_watchdog &&
      FLAGS_watchdog_level >= WATCHDOG_LEVEL_DEFAULT &&
      FLAGS_watchdog_level != WATCHDOG_LEVEL_DEBUG) {
    // Set CPU scheduling IO limits.
    setpriority(PRIO_PGRP, 0, 10);
#ifdef __linux__
    // Using: ioprio_set(IOPRIO_WHO_PGRP, 0, IOPRIO_CLASS_IDLE);
    syscall(SYS_ioprio_set, IOPRIO_WHO_PGRP, 0, IOPRIO_CLASS_IDLE);
#elif defined(__APPLE__) || defined(__FreeBSD__)
    setiopolicy_np(IOPOL_TYPE_DISK, IOPOL_SCOPE_PROCESS, IOPOL_THROTTLE);
#endif
  }
}

void Initializer::initWatcher() {
  // The watcher takes a list of paths to autoload extensions from.
  osquery::loadExtensions();

  // Add a watcher service thread to start/watch an optional worker and set
  // of optional extensions in the autoload paths.
  if (Watcher::hasManagedExtensions() || !FLAGS_disable_watchdog) {
    Dispatcher::addService(std::make_shared<WatcherRunner>(
        *argc_, *argv_, !FLAGS_disable_watchdog));
  }

  // If there are no autoloaded extensions, the watcher service will end,
  // otherwise it will continue as a background thread and respawn them.
  // If the watcher is also a worker watchdog it will do nothing but monitor
  // the extensions and worker process.
  if (!FLAGS_disable_watchdog) {
    Dispatcher::joinServices();
    // Execution should never reach this point.
    ::exit(EXIT_FAILURE);
  }
}

void Initializer::initWorker(const std::string& name) {
  // Clear worker's arguments.
  size_t name_size = strlen((*argv_)[0]);
  auto original_name = std::string((*argv_)[0]);
  for (int i = 0; i < *argc_; i++) {
    if ((*argv_)[i] != nullptr) {
      memset((*argv_)[i], ' ', strlen((*argv_)[i]));
    }
  }

  // Set the worker's process name.
  if (name.size() < name_size) {
    std::copy(name.begin(), name.end(), (*argv_)[0]);
    (*argv_)[0][name.size()] = '\0';
  } else {
    std::copy(original_name.begin(), original_name.end(), (*argv_)[0]);
    (*argv_)[0][original_name.size()] = '\0';
  }

  // Start a watcher watcher thread to exit the process if the watcher exits.
  Dispatcher::addService(std::make_shared<WatcherWatcherRunner>(getppid()));
}

void Initializer::initWorkerWatcher(const std::string& name) {
  if (isWorker()) {
    initWorker(name);
  } else {
    // The watcher will forever monitor and spawn additional workers.
    initWatcher();
  }
}

bool Initializer::isWorker() { return (getenv("OSQUERY_WORKER") != nullptr); }

void Initializer::initActivePlugin(const std::string& type,
                                   const std::string& name) {
  // Use a delay, meaning the amount of milliseconds waited for extensions.
  size_t delay = 0;
  // The timeout is the maximum time in seconds to wait for extensions.
  size_t timeout = atoi(FLAGS_extensions_timeout.c_str());
  while (!Registry::setActive(type, name)) {
    if (!Watcher::hasManagedExtensions() || delay > timeout * 1000) {
      LOG(ERROR) << "Active " << type << " plugin not found: " << name;
      ::exit(EXIT_CATASTROPHIC);
    }
    ::usleep(kExtensionInitializeMLatency * 1000);
    delay += kExtensionInitializeMLatency;
  }
}

void Initializer::start() {
  // Load registry/extension modules before extensions.
  osquery::loadModules();

  // Pre-extension manager initialization options checking.
  if (FLAGS_config_check && !Watcher::hasManagedExtensions()) {
    FLAGS_disable_extensions = true;
  }

  // Check the backing store by allocating and exiting on error.
  if (!DBHandle::checkDB()) {
    LOG(ERROR) << binary_ << " initialize failed: Could not open RocksDB";
    if (isWorker()) {
      ::exit(EXIT_CATASTROPHIC);
    } else {
      ::exit(EXIT_FAILURE);
    }
  }

  // Bind to an extensions socket and wait for registry additions.
  osquery::startExtensionManager();

  // Then set the config plugin, which uses a single/active plugin.
  initActivePlugin("config", FLAGS_config_plugin);

  // Run the setup for all lazy registries (tables, SQL).
  Registry::setUp();

  if (FLAGS_config_check) {
    // The initiator requested an initialization and config check.
    auto s = Config::checkConfig();
    if (!s.ok()) {
      std::cerr << "Error reading config: " << s.toString() << "\n";
    }
    // A configuration check exits the application.
    ::exit(s.getCode());
  }

  // Load the osquery config using the default/active config plugin.
  Config::load();

  // Initialize the status and result plugin logger.
  initActivePlugin("logger", FLAGS_logger_plugin);
  initLogger(binary_);

  // Start event threads.
  osquery::attachEvents();
  EventFactory::delay();
}

void Initializer::shutdown() {
  // End any event type run loops.
  EventFactory::end();

  // Hopefully release memory used by global string constructors in gflags.
  GFLAGS_NAMESPACE::ShutDownCommandLineFlags();
}
}
<|endoftext|>


<commit_before>#include "BgraFrame.h"
#include "../common/File.h"

bool CBgraFrame::OpenFile(const std::wstring& strFileName)
{
	NSFile::CFileBinary oFile;
	if (!oFile.OpenFile(strFileName))
		return false;

	CxImage img;

	if( !img.Decode( oFile.GetFileNative(), 0 ) )
		return false;

	CxImageToMediaFrame( img );
	return true;
}

bool CBgraFrame::SaveFile(const std::wstring& strFileName, uint32_t nFileType)
{
	NSFile::CFileBinary oFile;
	if (!oFile.CreateFile(strFileName))
		return false;

	CxImage img;
	if (!img.CreateFromArray(m_pData, m_lWidth, m_lHeight, 32, 4 * m_lWidth, (m_lStride >= 0) ? true : false))
		return false;

	if (!img.Encode( oFile.GetFileNative(), nFileType ))
		return false;

	oFile.CloseFile();
	return true;
}

void CBgraFrame::CxImageToMediaFrame( CxImage& img )
{
	if( !img.IsValid() )
		return;

	int nWidth  = img.GetWidth();
	int nHeight = img.GetHeight();

	m_pData = new BYTE[4 * nWidth * nHeight];

	if (!m_pData)
		return;

	m_lWidth = nWidth;
	m_lHeight = nHeight;
	m_lStride = -4 * nWidth;

	BYTE* pPixels = m_pData;

	int nBitsPerPixel = img.GetBpp();
	int nStride = img.GetEffWidth();
	BYTE* pBuffer = img.GetBits();
	RGBQUAD* pPalette = img.GetPalette();
	bool bIsAlphaPalettePresent = false;//img.GetPaletteAlphaEnabled();
	bool bIsAlphaApplied = false;

	if( 1 == nBitsPerPixel )
	{
		RGBQUAD pal[2];

		if( !pPalette )
		{
			for( int i = 0; i < 2; i++ )
			{
				int c = i * 255;
				pal[i].rgbBlue  = c;
				pal[i].rgbGreen = c;
				pal[i].rgbRed   = c;
			}
			pPalette = pal;
		}

		BYTE* src = pBuffer;
		BYTE* dst = pPixels;

		for( int nRow = 0; nRow < nHeight; ++nRow, src += nStride )
		{
			for( int nPos = 0; nPos < nWidth; ++nPos, dst += 4 )
			{
				int index = (src[nPos >> 3] >> (7 - (nPos & 7)) * 1) & 1;
				dst[0] = pPalette[index].rgbBlue;
				dst[1] = pPalette[index].rgbGreen;
				dst[2] = pPalette[index].rgbRed;
			}
		}
	}
	else
	if( 2 == nBitsPerPixel )
	{
		RGBQUAD pal[4];

		if( !pPalette )
		{
			for( int i = 0; i < 4; i++ )
			{
				int c = (i * 255 + 2) / 3;
				pal[i].rgbBlue  = c;
				pal[i].rgbGreen = c;
				pal[i].rgbRed   = c;
			}
			pPalette = pal;
		}

		BYTE* src = pBuffer;
		BYTE* dst = pPixels;

		for( int nRow = 0; nRow < nHeight; ++nRow, src += nStride )
		{
			for( int nPos = 0; nPos < nWidth; ++nPos, dst += 4 )
			{
				int index = (src[nPos >> 2] >> (3 - (nPos & 3)) * 2) & 3;
				dst[0] = pPalette[index].rgbBlue;
				dst[1] = pPalette[index].rgbGreen;
				dst[2] = pPalette[index].rgbRed;
			}
		}
	}
	else
	if( 4 == nBitsPerPixel )
	{
		RGBQUAD pal[16];

		if( !pPalette )
		{
			for( int i = 0; i < 16; i++ )
			{
				int c = (i * 255 + 8) / 15;
				pal[i].rgbBlue  = c;
				pal[i].rgbGreen = c;
				pal[i].rgbRed   = c;
			}
			pPalette = pal;
		}

		BYTE* src = pBuffer;
		BYTE* dst = pPixels;

		for( int nRow = 0; nRow < nHeight; ++nRow, src += nStride )
		{
			for( int nPos = 0; nPos < nWidth; ++nPos, dst += 4 )
			{
				int index = (src[nPos >> 1] >> (1 - (nPos & 1)) * 4) & 15;
				dst[0] = pPalette[index].rgbBlue;
				dst[1] = pPalette[index].rgbGreen;
				dst[2] = pPalette[index].rgbRed;
			}
		}
	}
	else
	if( 8 == nBitsPerPixel )
	{
		BYTE* src = pBuffer;
		BYTE* dst = pPixels;

		nStride -= nWidth;

		if( pPalette )
		{
			if (bIsAlphaPalettePresent)
			{
				for( int nRow = 0; nRow < nHeight; ++nRow, src += nStride )
				{
					for( int nPos = 0; nPos < nWidth; ++nPos, src += 1, dst += 4 )
					{
						int index = src[0];
						dst[0] = pPalette[index].rgbBlue;
						dst[1] = pPalette[index].rgbGreen;
						dst[2] = pPalette[index].rgbRed;
						dst[3] = pPalette[index].rgbReserved;
					}
				}
				bIsAlphaApplied = true;
			}
			else
			{
				for( int nRow = 0; nRow < nHeight; ++nRow, src += nStride )
				{
					for( int nPos = 0; nPos < nWidth; ++nPos, src += 1, dst += 4 )
					{
						int index = src[0];
						dst[0] = pPalette[index].rgbBlue;
						dst[1] = pPalette[index].rgbGreen;
						dst[2] = pPalette[index].rgbRed;
					}
				}
			}
		}
		else
		{
			for( int nRow = 0; nRow < nHeight; ++nRow, src += nStride )
			{
				for( int nPos = 0; nPos < nWidth; ++nPos, src += 1, dst += 4 )
				{
					int index = src[0];
					dst[0] = index;
					dst[1] = index;
					dst[2] = index;
				}
			}
		}
	}
	else if( 24 == nBitsPerPixel )
	{
		BYTE* src = pBuffer;
		BYTE* dst = pPixels;

		nStride -= nWidth * 3;

		for( int nRow = 0; nRow < nHeight; ++nRow, src += nStride )
		{
			for( int nPos = 0; nPos < nWidth; ++nPos, src += 3, dst += 4 )
			{
				dst[0] = src[0];
				dst[1] = src[1];
				dst[2] = src[2];
			}
		}
	}
	else if( 32 == nBitsPerPixel )
	{
		BYTE* src = pBuffer;
		BYTE* dst = pPixels;

		nStride -= nWidth * 4;

		for( int nRow = 0; nRow < nHeight; ++nRow, src += nStride )
		{
			for( int nPos = 0; nPos < nWidth; ++nPos, src += 4, dst += 4 )
			{
				dst[0] = src[0];
				dst[1] = src[1];
				dst[2] = src[2];
			}
		}
	}
	else
	{
		Destroy();
		return;
	}

	if( img.AlphaIsValid() )
	{
		BYTE* pAlpha  = img.AlphaGetPointer();
		DWORD nMaxAlpha = img.AlphaGetMax();

		if( 255 == nMaxAlpha )
		{
			BYTE* src = pAlpha;
			BYTE* dst = pPixels;
			int nSize = nWidth * nHeight;

			for( int i = 0; i < nSize; ++i, ++src, dst += 4 )
			{
				dst[3] = src[0];
			}
		}
		else
		{
			BYTE table[256];
			for( DWORD i = 0; i < 256; ++i )
			{
				DWORD a = (i * 255 + nMaxAlpha / 2) / nMaxAlpha;
				table[i] = (BYTE)min(a, 255);
			}

			BYTE* src = pAlpha;
			BYTE* dst = pPixels;
			int nSize = nWidth * nHeight;

			for( int i = 0; i < nSize; ++i, ++src, dst += 4 )
			{
				dst[3] = table[src[0]];
			}
		}
	}
	else if (!bIsAlphaApplied)
	{
		BYTE* dst = pPixels;
		int nSize = nWidth * nHeight;

		for( int i = 0; i < nSize; ++i, dst += 4 )
		{
			dst[3] = 255;
		}
	}
}
<commit_msg>git-svn-id: svn://fileserver/activex/AVS/Sources/TeamlabOffice/trunk/ServerComponents@54857 954022d7-b5bf-4e40-9824-e11837661b57<commit_after>#include "BgraFrame.h"
#include "../common/File.h"

bool CBgraFrame::OpenFile(const std::wstring& strFileName)
{
	NSFile::CFileBinary oFile;
	if (!oFile.OpenFile(strFileName))
		return false;

	CxImage img;

	if( !img.Decode( oFile.GetFileNative(), 0 ) )
		return false;

	CxImageToMediaFrame( img );
	return true;
}

bool CBgraFrame::SaveFile(const std::wstring& strFileName, uint32_t nFileType)
{
	NSFile::CFileBinary oFile;
	if (!oFile.CreateFileW(strFileName))
		return false;

	CxImage img;
	if (!img.CreateFromArray(m_pData, m_lWidth, m_lHeight, 32, 4 * m_lWidth, (m_lStride >= 0) ? true : false))
		return false;

	if (!img.Encode( oFile.GetFileNative(), nFileType ))
		return false;

	oFile.CloseFile();
	return true;
}

void CBgraFrame::CxImageToMediaFrame( CxImage& img )
{
	if( !img.IsValid() )
		return;

	int nWidth  = img.GetWidth();
	int nHeight = img.GetHeight();

	m_pData = new BYTE[4 * nWidth * nHeight];

	if (!m_pData)
		return;

	m_lWidth = nWidth;
	m_lHeight = nHeight;
	m_lStride = -4 * nWidth;

	BYTE* pPixels = m_pData;

	int nBitsPerPixel = img.GetBpp();
	int nStride = img.GetEffWidth();
	BYTE* pBuffer = img.GetBits();
	RGBQUAD* pPalette = img.GetPalette();
	bool bIsAlphaPalettePresent = false;//img.GetPaletteAlphaEnabled();
	bool bIsAlphaApplied = false;

	if( 1 == nBitsPerPixel )
	{
		RGBQUAD pal[2];

		if( !pPalette )
		{
			for( int i = 0; i < 2; i++ )
			{
				int c = i * 255;
				pal[i].rgbBlue  = c;
				pal[i].rgbGreen = c;
				pal[i].rgbRed   = c;
			}
			pPalette = pal;
		}

		BYTE* src = pBuffer;
		BYTE* dst = pPixels;

		for( int nRow = 0; nRow < nHeight; ++nRow, src += nStride )
		{
			for( int nPos = 0; nPos < nWidth; ++nPos, dst += 4 )
			{
				int index = (src[nPos >> 3] >> (7 - (nPos & 7)) * 1) & 1;
				dst[0] = pPalette[index].rgbBlue;
				dst[1] = pPalette[index].rgbGreen;
				dst[2] = pPalette[index].rgbRed;
			}
		}
	}
	else
	if( 2 == nBitsPerPixel )
	{
		RGBQUAD pal[4];

		if( !pPalette )
		{
			for( int i = 0; i < 4; i++ )
			{
				int c = (i * 255 + 2) / 3;
				pal[i].rgbBlue  = c;
				pal[i].rgbGreen = c;
				pal[i].rgbRed   = c;
			}
			pPalette = pal;
		}

		BYTE* src = pBuffer;
		BYTE* dst = pPixels;

		for( int nRow = 0; nRow < nHeight; ++nRow, src += nStride )
		{
			for( int nPos = 0; nPos < nWidth; ++nPos, dst += 4 )
			{
				int index = (src[nPos >> 2] >> (3 - (nPos & 3)) * 2) & 3;
				dst[0] = pPalette[index].rgbBlue;
				dst[1] = pPalette[index].rgbGreen;
				dst[2] = pPalette[index].rgbRed;
			}
		}
	}
	else
	if( 4 == nBitsPerPixel )
	{
		RGBQUAD pal[16];

		if( !pPalette )
		{
			for( int i = 0; i < 16; i++ )
			{
				int c = (i * 255 + 8) / 15;
				pal[i].rgbBlue  = c;
				pal[i].rgbGreen = c;
				pal[i].rgbRed   = c;
			}
			pPalette = pal;
		}

		BYTE* src = pBuffer;
		BYTE* dst = pPixels;

		for( int nRow = 0; nRow < nHeight; ++nRow, src += nStride )
		{
			for( int nPos = 0; nPos < nWidth; ++nPos, dst += 4 )
			{
				int index = (src[nPos >> 1] >> (1 - (nPos & 1)) * 4) & 15;
				dst[0] = pPalette[index].rgbBlue;
				dst[1] = pPalette[index].rgbGreen;
				dst[2] = pPalette[index].rgbRed;
			}
		}
	}
	else
	if( 8 == nBitsPerPixel )
	{
		BYTE* src = pBuffer;
		BYTE* dst = pPixels;

		nStride -= nWidth;

		if( pPalette )
		{
			if (bIsAlphaPalettePresent)
			{
				for( int nRow = 0; nRow < nHeight; ++nRow, src += nStride )
				{
					for( int nPos = 0; nPos < nWidth; ++nPos, src += 1, dst += 4 )
					{
						int index = src[0];
						dst[0] = pPalette[index].rgbBlue;
						dst[1] = pPalette[index].rgbGreen;
						dst[2] = pPalette[index].rgbRed;
						dst[3] = pPalette[index].rgbReserved;
					}
				}
				bIsAlphaApplied = true;
			}
			else
			{
				for( int nRow = 0; nRow < nHeight; ++nRow, src += nStride )
				{
					for( int nPos = 0; nPos < nWidth; ++nPos, src += 1, dst += 4 )
					{
						int index = src[0];
						dst[0] = pPalette[index].rgbBlue;
						dst[1] = pPalette[index].rgbGreen;
						dst[2] = pPalette[index].rgbRed;
					}
				}
			}
		}
		else
		{
			for( int nRow = 0; nRow < nHeight; ++nRow, src += nStride )
			{
				for( int nPos = 0; nPos < nWidth; ++nPos, src += 1, dst += 4 )
				{
					int index = src[0];
					dst[0] = index;
					dst[1] = index;
					dst[2] = index;
				}
			}
		}
	}
	else if( 24 == nBitsPerPixel )
	{
		BYTE* src = pBuffer;
		BYTE* dst = pPixels;

		nStride -= nWidth * 3;

		for( int nRow = 0; nRow < nHeight; ++nRow, src += nStride )
		{
			for( int nPos = 0; nPos < nWidth; ++nPos, src += 3, dst += 4 )
			{
				dst[0] = src[0];
				dst[1] = src[1];
				dst[2] = src[2];
			}
		}
	}
	else if( 32 == nBitsPerPixel )
	{
		BYTE* src = pBuffer;
		BYTE* dst = pPixels;

		nStride -= nWidth * 4;

		for( int nRow = 0; nRow < nHeight; ++nRow, src += nStride )
		{
			for( int nPos = 0; nPos < nWidth; ++nPos, src += 4, dst += 4 )
			{
				dst[0] = src[0];
				dst[1] = src[1];
				dst[2] = src[2];
			}
		}
	}
	else
	{
		Destroy();
		return;
	}

	if( img.AlphaIsValid() )
	{
		BYTE* pAlpha  = img.AlphaGetPointer();
		DWORD nMaxAlpha = img.AlphaGetMax();

		if( 255 == nMaxAlpha )
		{
			BYTE* src = pAlpha;
			BYTE* dst = pPixels;
			int nSize = nWidth * nHeight;

			for( int i = 0; i < nSize; ++i, ++src, dst += 4 )
			{
				dst[3] = src[0];
			}
		}
		else
		{
			BYTE table[256];
			for( DWORD i = 0; i < 256; ++i )
			{
				DWORD a = (i * 255 + nMaxAlpha / 2) / nMaxAlpha;
				table[i] = (BYTE)min(a, 255);
			}

			BYTE* src = pAlpha;
			BYTE* dst = pPixels;
			int nSize = nWidth * nHeight;

			for( int i = 0; i < nSize; ++i, ++src, dst += 4 )
			{
				dst[3] = table[src[0]];
			}
		}
	}
	else if (!bIsAlphaApplied)
	{
		BYTE* dst = pPixels;
		int nSize = nWidth * nHeight;

		for( int i = 0; i < nSize; ++i, dst += 4 )
		{
			dst[3] = 255;
		}
	}
}
<|endoftext|>