summaryrefslogtreecommitdiff
path: root/protocols/WhatsApp/src/avatars.cpp
blob: 43016048eea51f5ef59d4b08f39f71b7e66c8f41 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#include "common.h"

INT_PTR WhatsAppProto::GetAvatarInfo(WPARAM wParam, LPARAM lParam)
{
	PROTO_AVATAR_INFORMATION *pai = (PROTO_AVATAR_INFORMATION*)lParam;

	ptrA id(getStringA(pai->hContact, isChatRoom(pai->hContact) ? "ChatRoomID" : WHATSAPP_KEY_ID));
	if (id == NULL)
		return GAIR_NOAVATAR;

	std::tstring tszFileName = GetAvatarFileName(pai->hContact);
	_tcsncpy_s(pai->filename, tszFileName.c_str(), _TRUNCATE);
	pai->format = PA_FORMAT_JPEG;

	ptrA szAvatarId(getStringA(pai->hContact, WHATSAPP_KEY_AVATAR_ID));
	if (szAvatarId == NULL || (wParam & GAIF_FORCE) != 0)
		if (pai->hContact != NULL && m_pConnection != NULL) {
			m_pConnection->sendGetPicture(id, "image");
			return GAIR_WAITFOR;
		}

	debugLogA("No avatar");
	return GAIR_NOAVATAR;
}

INT_PTR WhatsAppProto::GetAvatarCaps(WPARAM wParam, LPARAM lParam)
{
	switch (wParam) {
	case AF_PROPORTION:
		return PIP_SQUARE;

	case AF_FORMATSUPPORTED: // Jabber supports avatars of virtually all formats
		return PA_FORMAT_JPEG;

	case AF_ENABLED:
		return TRUE;

	case AF_MAXSIZE:
		POINT *size = (POINT*)lParam;
		if (size)
			size->x = size->y = 640;
		return 0;
	}
	return -1;
}

std::tstring WhatsAppProto::GetAvatarFileName(MCONTACT hContact)
{
	std::tstring result = m_tszAvatarFolder + _T("\\");

	std::string jid;
	if (hContact != NULL) {
		ptrA szId(getStringA(hContact, isChatRoom(hContact) ? "ChatRoomID" : WHATSAPP_KEY_ID));
		if (szId == NULL)
			return _T("");

		jid = szId;
	}
	else jid = m_szJid;

	return result + std::tstring(_A2T(jid.c_str())) + _T(".jpg");
}

INT_PTR WhatsAppProto::GetMyAvatar(WPARAM wParam, LPARAM lParam)
{
	std::tstring tszOwnAvatar(m_tszAvatarFolder + _T("\\myavatar.jpg"));
	_tcsncpy_s((TCHAR*)wParam, lParam, tszOwnAvatar.c_str(), _TRUNCATE);
	return 0;
}

static std::vector<unsigned char>* sttFileToMem(const TCHAR *ptszFileName)
{
	HANDLE hFile = CreateFile(ptszFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
	if (hFile == INVALID_HANDLE_VALUE)
		return NULL;

	DWORD upperSize, lowerSize = GetFileSize(hFile, &upperSize);
	std::vector<unsigned char> *result = new std::vector<unsigned char>(lowerSize);
	ReadFile(hFile, (void*)result->data(), lowerSize, &upperSize, NULL);
	CloseHandle(hFile);
	return result;
}

int WhatsAppProto::InternalSetAvatar(MCONTACT hContact, const char *szJid, const TCHAR *ptszFileName)
{
	if (!isOnline() || ptszFileName == NULL)
		return 1;

	if (_taccess(ptszFileName, 4) != 0)
		return errno;

	ResizeBitmap resize = { 0 };
	if ((resize.hBmp = Bitmap_Load(ptszFileName)) == NULL)
		return 2;
	resize.size = sizeof(resize);
	resize.fit = RESIZEBITMAP_KEEP_PROPORTIONS;
	resize.max_height = resize.max_width = 96;

	HBITMAP hbmpPreview = (HBITMAP)CallService(MS_IMG_RESIZE, (LPARAM)&resize, 0);
	if (hbmpPreview == NULL)
		return 3;

	TCHAR tszTempFile[MAX_PATH], tszMyFile[MAX_PATH];
	if (hContact == NULL) {
		mir_sntprintf(tszMyFile, _countof(tszMyFile), _T("%s\\myavatar.jpg"), m_tszAvatarFolder.c_str());
		mir_sntprintf(tszTempFile, _countof(tszTempFile), _T("%s\\myavatar.preview.jpg"), m_tszAvatarFolder.c_str());
	}
	else {
		std::tstring tszContactAva = GetAvatarFileName(hContact);
		_tcsncpy_s(tszMyFile, tszContactAva.c_str(), _TRUNCATE);
		_tcsncpy_s(tszTempFile, (tszContactAva + _T(".preview")).c_str(), _TRUNCATE);
	}

	IMGSRVC_INFO saveInfo = { sizeof(saveInfo), 0 };
	saveInfo.hbm = hbmpPreview;
	saveInfo.tszName = tszTempFile;
	saveInfo.dwMask = IMGI_HBITMAP;
	saveInfo.fif = FIF_JPEG;
	CallService(MS_IMG_SAVE, (WPARAM)&saveInfo, IMGL_TCHAR);

	if (hbmpPreview != resize.hBmp)
		DeleteObject(hbmpPreview);
	DeleteObject(resize.hBmp);

	CopyFile(ptszFileName, tszMyFile, FALSE);

	m_pConnection->sendSetPicture(szJid, sttFileToMem(ptszFileName), sttFileToMem(tszTempFile));
	return 0;
}

INT_PTR WhatsAppProto::SetMyAvatar(WPARAM wParam, LPARAM lParam)
{
	return InternalSetAvatar(NULL, m_szJid.c_str(), (const TCHAR*)lParam);
}