Merge pull request #32 from cwoffenden/previewers

Generates Windows thumbnails and preview
This commit is contained in:
Rich Geldreich
2019-06-11 11:02:47 -07:00
committed by GitHub
12 changed files with 805 additions and 0 deletions

12
contrib/previewers/win/.gitignore vendored Normal file
View File

@@ -0,0 +1,12 @@
# Windows intermediate files
bin/x86/
bin/x64/
# VS project files
*.vcxproj.user
.vs/
*.VC.db
*.VC.opendb
*.sdf
*.suo
*.opensdf

View File

@@ -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.

View File

@@ -0,0 +1,151 @@
#include "basisthumbprovider.h"
#include <Shlwapi.h>
#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<size_t>(stat.cbSize.LowPart))) {
ULONG size = 0;
if (SUCCEEDED(stream->Read(data, static_cast<ULONG>(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<uint8_t*>(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;
}

View File

@@ -0,0 +1,58 @@
#pragma once
#include <Windows.h>
#include <thumbcache.h>
/**
*
*/
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;
};

View File

@@ -0,0 +1,173 @@
#include "helpers.h"
#include <cassert>
#include <cstdio>
//************************* 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<const uint16_t*>(src + 0));
unsigned const color1(*reinterpret_cast<const uint16_t*>(src + 2));
unsigned const ccodes(*reinterpret_cast<const uint32_t*>(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<int32_t>(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<uint32_t*>(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;
}

View File

@@ -0,0 +1,22 @@
#pragma once
#include <Windows.h>
#include <cstdint>
/**
* 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);

Binary file not shown.

After

Width:  |  Height:  |  Size: 709 KiB

View File

@@ -0,0 +1,118 @@
#include <Windows.h>
#include <ShlObj.h>
#include <tchar.h>
#include <new>
#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<LPBYTE>(data), static_cast<DWORD>(_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;
}

View File

@@ -0,0 +1,6 @@
EXPORTS
DllGetClassObject PRIVATE
DllCanUnloadNow PRIVATE
DllRegisterServer PRIVATE
DllUnregisterServer PRIVATE

View File

@@ -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

View File

@@ -0,0 +1,188 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{F3D4D2B1-20BF-44F2-B624-BE19C6911D4B}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>previewers</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)bin\$(PlatformShortName)\$(Configuration)\</OutDir>
<IntDir>bin\$(PlatformShortName)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<IntDir>bin\$(PlatformShortName)\$(Configuration)\</IntDir>
<OutDir>$(SolutionDir)bin\$(PlatformShortName)\$(Configuration)\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)bin\$(PlatformShortName)\$(Configuration)\</OutDir>
<IntDir>bin\$(PlatformShortName)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<IntDir>bin\$(PlatformShortName)\$(Configuration)\</IntDir>
<OutDir>$(SolutionDir)bin\$(PlatformShortName)\$(Configuration)\</OutDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>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)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<ExceptionHandling>false</ExceptionHandling>
<AdditionalIncludeDirectories>$(ProjectDir)..\..\..\transcoder\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<MinimalRebuild>false</MinimalRebuild>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ModuleDefinitionFile>previewers.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>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)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<ExceptionHandling>false</ExceptionHandling>
<AdditionalIncludeDirectories>$(ProjectDir)..\..\..\transcoder\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<MinimalRebuild>false</MinimalRebuild>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ModuleDefinitionFile>previewers.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Full</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>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)</PreprocessorDefinitions>
<ExceptionHandling>false</ExceptionHandling>
<AdditionalIncludeDirectories>$(ProjectDir)..\..\..\transcoder\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<ModuleDefinitionFile>previewers.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Full</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>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)</PreprocessorDefinitions>
<ExceptionHandling>false</ExceptionHandling>
<AdditionalIncludeDirectories>$(ProjectDir)..\..\..\transcoder\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<ModuleDefinitionFile>previewers.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="..\..\..\transcoder\basisu_transcoder.h" />
<ClInclude Include="basisthumbprovider.h" />
<ClInclude Include="helpers.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\..\transcoder\basisu_transcoder.cpp" />
<ClCompile Include="basisthumbprovider.cpp" />
<ClCompile Include="helpers.cpp" />
<ClCompile Include="previewers.cpp">
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsManaged>
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</CompileAsManaged>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
</PrecompiledHeader>
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsManaged>
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</CompileAsManaged>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
</PrecompiledHeader>
</ClCompile>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="inc">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="src">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="src\transcoder">
<UniqueIdentifier>{2d6d195a-ebe1-467a-a713-8abb5d133ce6}</UniqueIdentifier>
</Filter>
<Filter Include="inc\transcoder">
<UniqueIdentifier>{724b1ae2-a9f5-4706-b406-26d4660d72e0}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="basisthumbprovider.h">
<Filter>inc</Filter>
</ClInclude>
<ClInclude Include="..\..\..\transcoder\basisu_transcoder.h">
<Filter>inc\transcoder</Filter>
</ClInclude>
<ClInclude Include="helpers.h">
<Filter>inc</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="basisthumbprovider.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="previewers.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="..\..\..\transcoder\basisu_transcoder.cpp">
<Filter>src\transcoder</Filter>
</ClCompile>
<ClCompile Include="helpers.cpp">
<Filter>src</Filter>
</ClCompile>
</ItemGroup>
</Project>