diff --git a/contrib/previewers/win/.gitignore b/contrib/previewers/win/.gitignore new file mode 100644 index 0000000..9fd3ebe --- /dev/null +++ b/contrib/previewers/win/.gitignore @@ -0,0 +1,12 @@ +# Windows intermediate files +bin/x86/ +bin/x64/ + +# VS project files +*.vcxproj.user +.vs/ +*.VC.db +*.VC.opendb +*.sdf +*.suo +*.opensdf diff --git a/contrib/previewers/win/README.md b/contrib/previewers/win/README.md new file mode 100644 index 0000000..cc4f087 --- /dev/null +++ b/contrib/previewers/win/README.md @@ -0,0 +1,7 @@ +# Windows Previewers for Basis Universal + +Build using Visual Studio from 2012 onwards. Enable from an Adminstrator console using `regsvr32 previewers.dll` (and remove using `regsvr32 /u previewers.dll`). + +![Icon and preview pane](preview.png) + +Work-in-progress. Prebuilt signed version and installer coming soon. Mac version to follow. diff --git a/contrib/previewers/win/basisthumbprovider.cpp b/contrib/previewers/win/basisthumbprovider.cpp new file mode 100644 index 0000000..a7022a7 --- /dev/null +++ b/contrib/previewers/win/basisthumbprovider.cpp @@ -0,0 +1,151 @@ +#include "basisthumbprovider.h" + +#include + +#include "basisu_transcoder.h" + +#include "helpers.h" + +#pragma comment(lib, "Shlwapi.lib") + +using namespace basist; + +static etc1_global_selector_codebook* globalCodebook = NULL; + +BasisThumbProvider::BasisThumbProvider() : count(1), stream(NULL) { + dprintf("BasisThumbProvider ctor"); + basisu_transcoder_init(); + if (!globalCodebook) { + globalCodebook = new etc1_global_selector_codebook(g_global_selector_cb_size, g_global_selector_cb); + } +} + +BasisThumbProvider::~BasisThumbProvider() { + dprintf("BasisThumbProvider **dtor**"); + if (stream) { + stream->Release(); + stream = NULL; + } +} + +IFACEMETHODIMP BasisThumbProvider::QueryInterface(REFIID riid, void **ppv) { + static const QITAB qit[] = { + QITABENT(BasisThumbProvider, IThumbnailProvider), + QITABENT(BasisThumbProvider, IInitializeWithStream), + {0}, + }; + return QISearch(this, qit, riid, ppv); +} + +IFACEMETHODIMP_(ULONG) BasisThumbProvider::AddRef() { + return InterlockedIncrement(&count); +} + +IFACEMETHODIMP_(ULONG) BasisThumbProvider::Release() { + LONG refs = InterlockedDecrement(&count); + if (refs == 0) { + delete this; + } + return refs; +} + +IFACEMETHODIMP BasisThumbProvider::Initialize(IStream *pStream, DWORD grfMode) { + dprintf("BasisThumbProvider::Initialize"); + HRESULT hr = HRESULT_FROM_WIN32(ERROR_ALREADY_INITIALIZED); + if (!stream) { + hr = pStream->QueryInterface(&stream); + } + return hr; +} + +// Note: thumbnails get written here: %LocalAppData%\Microsoft\Windows\Explorer +IFACEMETHODIMP BasisThumbProvider::GetThumbnail(UINT cx, HBITMAP *phbmp, WTS_ALPHATYPE *pdwAlpha) { + STATSTG stat; + if (stream && SUCCEEDED(stream->Stat(&stat, STATFLAG_NONAME))) { + if (void* data = malloc(static_cast(stat.cbSize.LowPart))) { + ULONG size = 0; + if (SUCCEEDED(stream->Read(data, static_cast(stat.cbSize.LowPart), &size))) { + if (size == stat.cbSize.LowPart) { + basisu_transcoder transcoder(globalCodebook); + if (transcoder.validate_header(data, size)) { + dprintf("Requested %d bytes for %dx%d image", size, cx, cx); + basisu_image_info info; + if (transcoder.get_image_info(data, size, info, 0)) { + uint32_t level = 0; + uint32_t descW = 0, descH = 0, blocks; + for (uint32_t n = 0; n < info.m_total_levels; n++) { + if (transcoder.get_image_level_desc(data, size, 0, n, descW, descH, blocks)) { + dprintf("mipmap level w: %d, h: %d (blocks: %d)", descW, descH, blocks); + if (cx >= std::max(descW, descH)) { + level = n; + break; + } + } + } + basisu_file_info fileInfo; + transcoder.get_file_info(data, size, fileInfo); + if (transcoder.start_transcoding(data, size)) { + if (void* dxtBuf = malloc(basis_get_bytes_per_block(cTFBC1) * blocks)) { + if (transcoder.transcode_image_level(data, size, 0, level, dxtBuf, blocks, cTFBC1)) { + dprintf("Decoded!!!!"); + *phbmp = dxtToBitmap(static_cast(dxtBuf), descW, descH, fileInfo.m_y_flipped); + } + delete dxtBuf; + } + } + } + } + } + } + free(data); + } + } + return (*phbmp) ? S_OK : S_FALSE; +} + +//********************************** Factory *********************************/ + +BasisThumbProviderFactory::BasisThumbProviderFactory() : count(1) {} + +BasisThumbProviderFactory::~BasisThumbProviderFactory() {} + +IFACEMETHODIMP BasisThumbProviderFactory::QueryInterface(REFIID riid, void **ppv) { + static const QITAB qit[] = { + QITABENT(BasisThumbProviderFactory, IClassFactory), + {0}, + }; + return QISearch(this, qit, riid, ppv); +} + +IFACEMETHODIMP_(ULONG) BasisThumbProviderFactory::AddRef() { + return InterlockedIncrement(&count); +} + +IFACEMETHODIMP_(ULONG) BasisThumbProviderFactory::Release() { + LONG refs = InterlockedDecrement(&count); + if (refs == 0) { + delete this; + } + return refs; +} + +IFACEMETHODIMP BasisThumbProviderFactory::CreateInstance(IUnknown *pUnkOuter, REFIID riid, void **ppv) { + HRESULT hr = CLASS_E_NOAGGREGATION; + if (pUnkOuter == NULL) { + hr = E_OUTOFMEMORY; + if (BasisThumbProvider* provider = new (std::nothrow) BasisThumbProvider()) { + hr = provider->QueryInterface(riid, ppv); + provider->Release(); + } + } + return hr; +} + +IFACEMETHODIMP BasisThumbProviderFactory::LockServer(BOOL fLock) { + if (fLock) { + InterlockedIncrement(&count); + } else { + InterlockedDecrement(&count); + } + return S_OK; +} diff --git a/contrib/previewers/win/basisthumbprovider.h b/contrib/previewers/win/basisthumbprovider.h new file mode 100644 index 0000000..e73747c --- /dev/null +++ b/contrib/previewers/win/basisthumbprovider.h @@ -0,0 +1,58 @@ +#pragma once + +#include +#include + +/** + * + */ +class BasisThumbProvider : public IInitializeWithStream, public IThumbnailProvider +{ +public: + BasisThumbProvider(); + // IUnknown::QueryInterface() + IFACEMETHODIMP QueryInterface(REFIID riid, void **ppv) override; + // IUnknown::AddRef() + IFACEMETHODIMP_(ULONG) AddRef() override; + // IUnknown::Release() + IFACEMETHODIMP_(ULONG) Release() override; + + // IInitializeWithStream::Initialize() + IFACEMETHODIMP Initialize(IStream *pStream, DWORD grfMode) override; + + // IThumbnailProvider::GetThumbnail() + IFACEMETHODIMP GetThumbnail(UINT cx, HBITMAP *phbmp, WTS_ALPHATYPE *pdwAlpha) override; + +protected: + virtual ~BasisThumbProvider(); + +private: + LONG count; + IStream* stream; +}; + +/** + * + */ +class BasisThumbProviderFactory : public IClassFactory +{ +public: + BasisThumbProviderFactory(); + // IUnknown::QueryInterface() + IFACEMETHODIMP QueryInterface(REFIID riid, void **ppv) override; + // IUnknown::AddRef() + IFACEMETHODIMP_(ULONG) AddRef() override; + // IUnknown::Release() + IFACEMETHODIMP_(ULONG) Release() override; + + // IClassFactory::CreateInstance() + IFACEMETHODIMP CreateInstance(IUnknown *pUnkOuter, REFIID riid, void **ppv) override; + // IClassFactory::LockServer() + IFACEMETHODIMP LockServer(BOOL fLock) override; + +protected: + virtual ~BasisThumbProviderFactory(); + +private: + LONG count; +}; diff --git a/contrib/previewers/win/helpers.cpp b/contrib/previewers/win/helpers.cpp new file mode 100644 index 0000000..d592ac4 --- /dev/null +++ b/contrib/previewers/win/helpers.cpp @@ -0,0 +1,173 @@ +#include "helpers.h" + +#include +#include + +//************************* See cubic/texture-dxt.cpp ************************/ + +/** + * Expands an RGB565 format colour into BGR888. + * + * \note Unlike the original code, which was RGB888, for a Windows bitmap we + * need this is as \e BGR. + * + * \param[in] color RGB565 format colour + * \return a \e bit \e expansion of the supplied colour as 8-bit per channel (with zero alpha) + */ +static uint32_t rgbFrom565(unsigned const color) { + unsigned r = (color >> 11) & 0x1F; + unsigned g = (color >> 5) & 0x3F; + unsigned b = (color >> 0) & 0x1F; + return (((r << 3) | (r >> 2)) << 16) + | (((g << 2) | (g >> 4)) << 8) + | (((b << 3) | (b >> 2)) << 0); +} + +/** + * Calculates the DXT decompressor's \e midpoint colour, where the weighting + * is \c 2:1 (the parameters can be exchanged to calculate both midpoints). + * Used by the DXT block decode. + * + * \param[in] color0 \c endpoint colour receiving a double weighting + * \param[in] color1 \c endpoint colour receiving a single weighting + * \return blended colour (excluding alpha) + */ +static uint32_t midpoint21(uint32_t const color0, uint32_t const color1) { + return (((2 * (color0 & 0x0000FF) + (color1 & 0x0000FF)) / 3) & 0x0000FF) + | (((2 * (color0 & 0x00FF00) + (color1 & 0x00FF00)) / 3) & 0x00FF00) + | (((2 * (color0 & 0xFF0000) + (color1 & 0xFF0000)) / 3) & 0xFF0000); +} + +/** + * Calculates the DXT decompressor's \e midpoint colour, where the weighting + * is \c 1:1. Used by the DXT block decode. + * + * \param[in] color0 \c endpoint colour (any of the endpoints) + * \param[in] color1 \c endpoint colour (any of the endpoints) + * \return blended colour (excluding alpha) + */ +static uint32_t midpoint11(uint32_t const color0, uint32_t const color1) { + return ((((color0 & 0x0000FF) + (color1 & 0x0000FF)) / 2) & 0x0000FF) + | ((((color0 & 0x00FF00) + (color1 & 0x00FF00)) / 2) & 0x00FF00) + | ((((color0 & 0xFF0000) + (color1 & 0xFF0000)) / 2) & 0xFF0000); +} + +/** + * Decodes a DXT1 block. + * + * \note Unlike the original code, which was RGB888, for a Windows bitmap we + * need this is as \e BGR. + * + * \param[in] src start of the encoded data (eight contiguous bytes) + * \param[in] dst destination of the block's top-left pixel + * \param[in] span number of pixels to advance to the next line (usually the texture width) + */ +static void decodeDxt1(const uint8_t* const src, uint32_t* dst, unsigned const span) { + assert(src && dst && span); + /* + * Extract the two 16-bit 'endpoints'. These are little Endian, regardless + * of the platform. Note that the midpoint choices are made against these + * (not the platform Endian RGB/BGR versions) and that (specifically in + * this implementation) DXT1 will always have solid alpha (which we bake + * into the colour table). The color 'codes' are collated here into a + * 32-bit value (which simplifies addressing the bits directly later). + */ +#if defined(__BYTE_ORDER) && (__BYTE_ORDER == __BIG_ENDIAN) + unsigned const color0((src[0] << 0) | (src[1] << 8)); + unsigned const color1((src[2] << 0) | (src[3] << 8)); + unsigned const ccodes((src[4] << 0) | (src[5] << 8) + | (src[6] << 16) | (src[7] << 24)); +#else + unsigned const color0(*reinterpret_cast(src + 0)); + unsigned const color1(*reinterpret_cast(src + 2)); + unsigned const ccodes(*reinterpret_cast(src + 4)); +#endif + uint32_t color[4]; + color[0] = 0xFF000000 | rgbFrom565(color0); + color[1] = 0xFF000000 | rgbFrom565(color1); + color[2] = 0xFF000000 | ((color0 > color1) + ? midpoint21(color[0], color[1]) + : midpoint11(color[0], color[1])); + color[3] = 0xFF000000 | ((color0 > color1) + ? midpoint21(color[1], color[0]) + : 0); + /* + * The 4x4 block is unrolled. For destinations smaller than 4x4 the pixel + * overwrites here are inefficient, but the overhead isn't enough to worry + * about (when compared with the GL texture upload). + */ + dst[0] = color[(ccodes >> 0) & 0x03]; + dst[1] = color[(ccodes >> 2) & 0x03]; + dst[2] = color[(ccodes >> 4) & 0x03]; + dst[3] = color[(ccodes >> 6) & 0x03]; + dst += span; + dst[0] = color[(ccodes >> 8) & 0x03]; + dst[1] = color[(ccodes >> 10) & 0x03]; + dst[2] = color[(ccodes >> 12) & 0x03]; + dst[3] = color[(ccodes >> 14) & 0x03]; + dst += span; + dst[0] = color[(ccodes >> 16) & 0x03]; + dst[1] = color[(ccodes >> 18) & 0x03]; + dst[2] = color[(ccodes >> 20) & 0x03]; + dst[3] = color[(ccodes >> 22) & 0x03]; + dst += span; + dst[0] = color[(ccodes >> 24) & 0x03]; + dst[1] = color[(ccodes >> 26) & 0x03]; + dst[2] = color[(ccodes >> 28) & 0x03]; + dst[3] = color[(ccodes >> 30) & 0x03]; +} + +//******************************** Public API ********************************/ + +void dprintf(char* const fmt, ...) { + va_list args; + char buf[256]; + va_start(args, fmt); + int len = vsnprintf_s(buf, sizeof buf, fmt, args); + va_end (args); + if (len > 0) { + buf[sizeof buf - 1] = 0; + OutputDebugStringA(buf); + } +} + +HBITMAP dxtToBitmap(const uint8_t* src, uint32_t const imgW, uint32_t const imgH, bool const flip) { + assert(src && imgW && imgH); + /* + * Creates a bitmap (a DIB) for the passed-in pixel size. Note that + * negation of the height means top-down, origin upper-left, which is the + * regular case. + * + * TODO: 16-bit variant instead? + * TODO: we're growing the nearest 4x4 but not cropping afterwards (what about shrinking and skipping the last blocks?) + */ + uint32_t nearW = (imgW + 3) & ~3; + uint32_t nearH = (imgH + 3) & ~3; + BITMAPINFO bmi = { + sizeof(bmi.bmiHeader) + }; + bmi.bmiHeader.biWidth = nearW; + bmi.bmiHeader.biHeight = (flip) ? nearH : -static_cast(nearH); + bmi.bmiHeader.biPlanes = 1; + bmi.bmiHeader.biBitCount = 32; + bmi.bmiHeader.biCompression = BI_RGB; + void* pixels = NULL; + HBITMAP hbmp = CreateDIBSection(NULL, &bmi, DIB_RGB_COLORS, &pixels, NULL, 0); + /* + * Decode the BC1 blocks. + */ + if (hbmp && pixels) { + uint32_t* dst = static_cast(pixels); + for (unsigned y = 0; y < nearH; y += 4) { + uint32_t* row = dst; + for (unsigned x = 0; x < nearW; x += 4) { + decodeDxt1(src, row, nearW); + src += 8; + row += 4; + } + dst += 4 * nearW; + } + GdiFlush(); + } + return hbmp; +} diff --git a/contrib/previewers/win/helpers.h b/contrib/previewers/win/helpers.h new file mode 100644 index 0000000..1a4a955 --- /dev/null +++ b/contrib/previewers/win/helpers.h @@ -0,0 +1,22 @@ +#pragma once + +#include + +#include + +/** + * Write a formatted string to the connected debugger (e.g. DebugView). + * + * \param[in] fmt content to write in \c printf format (followed by optional arguments) + */ +void dprintf(char* const fmt, ...); + +/** + * Software decodes BC1 format data. + * + * \param[in] src BC1 source blocks (the number of blocks being determined by the image dimensions) + * \param[in] imgW width of the decoded image + * \param[in] imgH height of the decoded image + * \return handle to a bitmap (ownership passed to the caller) + */ +HBITMAP dxtToBitmap(const uint8_t* src, uint32_t const imgW, uint32_t const imgH, bool const flip = false); diff --git a/contrib/previewers/win/preview.png b/contrib/previewers/win/preview.png new file mode 100644 index 0000000..19836cf Binary files /dev/null and b/contrib/previewers/win/preview.png differ diff --git a/contrib/previewers/win/previewers.cpp b/contrib/previewers/win/previewers.cpp new file mode 100644 index 0000000..8274bd9 --- /dev/null +++ b/contrib/previewers/win/previewers.cpp @@ -0,0 +1,118 @@ +#include +#include +#include + +#include + +#include "basisthumbprovider.h" + +#define SHELLEX_THUMBNAIL_CLSID _T("ShellEx\\{E357FCCD-A995-4576-B01F-234630154E96}") +#define SHELLEX_PREVIEWER_CLSID _T("ShellEx\\{8895B1C6-B41F-4C1C-A562-0D564250836F}") + +#define THUMBNAIL_HANDLER_TITLE _T("Basis Thumbnail Handler") +#define THUMBNAIL_HANDLER_CLSID _T("{CD1F0EA0-283C-4D90-A41D-DEBD9207D91F}") + +#define PREVIEWER_HANDLER_TITLE _T("Basis Previewer Handler") +#define PREVIEWER_HANDLER_CLSID _T("{7B5DA275-3BB6-45AE-B0EB-E50187A28F13}") + +#define FILE_EXTENSION _T(".basis") + +static const CLSID CLSID_ThumbnailHandler = {0xCD1F0EA0, 0x283C, 0x4D90, {0xA4, 0x1D, 0xDE, 0xBD, 0x92, 0x07, 0xD9, 0x1F}}; +static const CLSID CLSID_PreviewerHandler = {0x7B5DA275, 0x3BB6, 0x45AE, {0xB0, 0xEB, 0xE5, 0x01, 0x87, 0xA2, 0x8F, 0x13}}; + +static TCHAR dllPath[MAX_PATH] = {0}; + +static LONG dllRefs = 0; + +#ifndef BAIL_ON_FAIL +#define BAIL_ON_FAIL(code) if (FAILED((hr = (code)))) return hr +#endif + +static HRESULT setRegKey(HKEY root, LPTSTR key, LPTSTR val, LPTSTR data) { + HKEY hKey; + HRESULT hr = HRESULT_FROM_WIN32(RegCreateKeyEx(root, key, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL, &hKey, NULL)); + if (SUCCEEDED(hr)) { + hr = HRESULT_FROM_WIN32(RegSetValueEx(hKey, val, 0, REG_SZ, reinterpret_cast(data), static_cast(_tcslen(data) * sizeof TCHAR))); + RegCloseKey(hKey); + } + return hr; +} + +BOOL APIENTRY DllMain(HMODULE hInstDLL, DWORD reason, LPVOID /*reserved*/) { + if (reason == DLL_PROCESS_ATTACH) { + OutputDebugString(_T("DllMain")); + if (GetModuleFileName(hInstDLL, dllPath, sizeof dllPath) == 0) { + #ifdef _DEBUG + OutputDebugString(_T("Failed to obtain DLL path")); + #endif + } + DisableThreadLibraryCalls(hInstDLL); + } + return TRUE; +} + + +STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void **ppv) { + HRESULT hr = CLASS_E_CLASSNOTAVAILABLE; + if (IsEqualCLSID(CLSID_ThumbnailHandler, rclsid)) { + hr = E_OUTOFMEMORY; + if (IClassFactory* factory = new (std::nothrow) BasisThumbProviderFactory()) { + hr = factory->QueryInterface(riid, ppv); + factory->Release(); + } + } + return hr; +} + +void DllAddRef() { +#ifdef _DEBUG + OutputDebugString(_T("DllAddRef")); +#endif + InterlockedIncrement(&dllRefs); +} + +void DllRelease() { +#ifdef _DEBUG + OutputDebugString(_T("DllRelease")); +#endif + InterlockedDecrement(&dllRefs); +} + +STDAPI DllCanUnloadNow() { +#ifdef _DEBUG + OutputDebugString(_T("DllCanUnloadNow")); +#endif + return (dllRefs == 0) ? S_OK : S_FALSE; +} + +// regsvr32 /s previewers.dll +STDAPI DllRegisterServer() { + HRESULT hr = E_FAIL; + if (_tcslen(dllPath)) { + BAIL_ON_FAIL(setRegKey(HKEY_LOCAL_MACHINE, _T("Software\\Classes\\CLSID\\") THUMBNAIL_HANDLER_CLSID, NULL, THUMBNAIL_HANDLER_TITLE)); + BAIL_ON_FAIL(setRegKey(HKEY_LOCAL_MACHINE, _T("Software\\Classes\\CLSID\\") THUMBNAIL_HANDLER_CLSID _T("\\InProcServer32"), NULL, dllPath)); + BAIL_ON_FAIL(setRegKey(HKEY_LOCAL_MACHINE, _T("Software\\Classes\\CLSID\\") THUMBNAIL_HANDLER_CLSID _T("\\InProcServer32"), _T("ThreadingModel"), _T("Apartment"))); + BAIL_ON_FAIL(setRegKey(HKEY_LOCAL_MACHINE, _T("Software\\Classes\\") FILE_EXTENSION _T("\\") SHELLEX_THUMBNAIL_CLSID, NULL, THUMBNAIL_HANDLER_CLSID)); + SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL); + } +#ifdef _DEBUG + if (SUCCEEDED(hr)) { + OutputDebugString(_T("Previewer successfully registered")); + } +#endif + return hr; +} + +// regsvr32 /s /u previewers.dll +STDAPI DllUnregisterServer() { + HRESULT hr = HRESULT_FROM_WIN32(RegDeleteTree(HKEY_LOCAL_MACHINE, _T("Software\\Classes\\CLSID\\") THUMBNAIL_HANDLER_CLSID)); + if (SUCCEEDED(hr)) { + hr = HRESULT_FROM_WIN32(RegDeleteTree(HKEY_LOCAL_MACHINE, _T("Software\\Classes\\") FILE_EXTENSION _T("\\") SHELLEX_THUMBNAIL_CLSID)); + } +#ifdef _DEBUG + if (SUCCEEDED(hr)) { + OutputDebugString(_T("Previewer successfully unregistered")); + } +#endif + return hr; +} diff --git a/contrib/previewers/win/previewers.def b/contrib/previewers/win/previewers.def new file mode 100644 index 0000000..112ba88 --- /dev/null +++ b/contrib/previewers/win/previewers.def @@ -0,0 +1,6 @@ +EXPORTS + DllGetClassObject PRIVATE + DllCanUnloadNow PRIVATE + DllRegisterServer PRIVATE + DllUnregisterServer PRIVATE + diff --git a/contrib/previewers/win/previewers.sln b/contrib/previewers/win/previewers.sln new file mode 100644 index 0000000..ec39390 --- /dev/null +++ b/contrib/previewers/win/previewers.sln @@ -0,0 +1,26 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2012 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "previewers", "previewers.vcxproj", "{F3D4D2B1-20BF-44F2-B624-BE19C6911D4B}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F3D4D2B1-20BF-44F2-B624-BE19C6911D4B}.Debug|Win32.ActiveCfg = Debug|Win32 + {F3D4D2B1-20BF-44F2-B624-BE19C6911D4B}.Debug|Win32.Build.0 = Debug|Win32 + {F3D4D2B1-20BF-44F2-B624-BE19C6911D4B}.Debug|x64.ActiveCfg = Debug|x64 + {F3D4D2B1-20BF-44F2-B624-BE19C6911D4B}.Debug|x64.Build.0 = Debug|x64 + {F3D4D2B1-20BF-44F2-B624-BE19C6911D4B}.Release|Win32.ActiveCfg = Release|Win32 + {F3D4D2B1-20BF-44F2-B624-BE19C6911D4B}.Release|Win32.Build.0 = Release|Win32 + {F3D4D2B1-20BF-44F2-B624-BE19C6911D4B}.Release|x64.ActiveCfg = Release|x64 + {F3D4D2B1-20BF-44F2-B624-BE19C6911D4B}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/contrib/previewers/win/previewers.vcxproj b/contrib/previewers/win/previewers.vcxproj new file mode 100644 index 0000000..6f1d62b --- /dev/null +++ b/contrib/previewers/win/previewers.vcxproj @@ -0,0 +1,188 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {F3D4D2B1-20BF-44F2-B624-BE19C6911D4B} + Win32Proj + previewers + + + + DynamicLibrary + true + $(DefaultPlatformToolset) + Unicode + + + DynamicLibrary + true + $(DefaultPlatformToolset) + Unicode + + + DynamicLibrary + false + $(DefaultPlatformToolset) + true + Unicode + + + DynamicLibrary + false + $(DefaultPlatformToolset) + true + Unicode + + + + + + + + + + + + + + + + + + + true + $(SolutionDir)bin\$(PlatformShortName)\$(Configuration)\ + bin\$(PlatformShortName)\$(Configuration)\ + + + true + bin\$(PlatformShortName)\$(Configuration)\ + $(SolutionDir)bin\$(PlatformShortName)\$(Configuration)\ + + + false + $(SolutionDir)bin\$(PlatformShortName)\$(Configuration)\ + bin\$(PlatformShortName)\$(Configuration)\ + + + false + bin\$(PlatformShortName)\$(Configuration)\ + $(SolutionDir)bin\$(PlatformShortName)\$(Configuration)\ + + + + Level3 + Disabled + WIN32;_WIN32_WINNT=0x0601;_WINDOWS;_USRDLL;_ITERATOR_DEBUG_LEVEL=1;BASISD_SUPPORT_DXT5A=0;BASISD_SUPPORT_PVRTC1=0;BASISD_SUPPORT_BC7=0;BASISD_SUPPORT_ETC2_EAC_A8=0;_DEBUG;%(PreprocessorDefinitions) + true + false + $(ProjectDir)..\..\..\transcoder\;%(AdditionalIncludeDirectories) + false + false + + + Windows + true + previewers.def + + + + + Level3 + Disabled + WIN32;_WIN32_WINNT=0x0601;_WINDOWS;_USRDLL;_ITERATOR_DEBUG_LEVEL=1;BASISD_SUPPORT_DXT5A=0;BASISD_SUPPORT_PVRTC1=0;BASISD_SUPPORT_BC7=0;BASISD_SUPPORT_ETC2_EAC_A8=0;_DEBUG;%(PreprocessorDefinitions) + true + false + $(ProjectDir)..\..\..\transcoder\;%(AdditionalIncludeDirectories) + false + false + + + Windows + true + previewers.def + + + + + Level3 + Full + true + true + WIN32;_WIN32_WINNT=0x0601;_WINDOWS;_USRDLL;_ITERATOR_DEBUG_LEVEL=0;BASISD_SUPPORT_DXT5A=0;BASISD_SUPPORT_PVRTC1=0;BASISD_SUPPORT_BC7=0;BASISD_SUPPORT_ETC2_EAC_A8=0;NDEBUG;WIN32_LEAN_AND_MEAN;%(PreprocessorDefinitions) + false + $(ProjectDir)..\..\..\transcoder\;%(AdditionalIncludeDirectories) + false + + + Windows + true + true + true + previewers.def + + + + + Level3 + Full + true + true + WIN32;_WIN32_WINNT=0x0601;_WINDOWS;_USRDLL;_ITERATOR_DEBUG_LEVEL=0;BASISD_SUPPORT_DXT5A=0;BASISD_SUPPORT_PVRTC1=0;BASISD_SUPPORT_BC7=0;BASISD_SUPPORT_ETC2_EAC_A8=0;NDEBUG;WIN32_LEAN_AND_MEAN;%(PreprocessorDefinitions) + false + $(ProjectDir)..\..\..\transcoder\;%(AdditionalIncludeDirectories) + false + + + Windows + true + true + true + previewers.def + + + + + + + + + + + + + false + false + + + + + false + false + + + + + + + + + + \ No newline at end of file diff --git a/contrib/previewers/win/previewers.vcxproj.filters b/contrib/previewers/win/previewers.vcxproj.filters new file mode 100644 index 0000000..e2ac404 --- /dev/null +++ b/contrib/previewers/win/previewers.vcxproj.filters @@ -0,0 +1,44 @@ + + + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {2d6d195a-ebe1-467a-a713-8abb5d133ce6} + + + {724b1ae2-a9f5-4706-b406-26d4660d72e0} + + + + + inc + + + inc\transcoder + + + inc + + + + + src + + + src + + + src\transcoder + + + src + + + \ No newline at end of file