Repository: GameTechDev/Intel-Texture-Works-Plugin Branch: master Commit: e5a30421a82c Files: 146 Total size: 4.0 MB Directory structure: gitextract_5vvclg95/ ├── .gitignore ├── 3rdParty/ │ ├── DirectXTex/ │ │ ├── .gitignore │ │ ├── DDSTextureLoader/ │ │ │ ├── DDSTextureLoader.cpp │ │ │ └── DDSTextureLoader.h │ │ ├── DDSView/ │ │ │ ├── DDSView.rc │ │ │ ├── DDSView_Desktop_2012.sln │ │ │ ├── DDSView_Desktop_2012.vcxproj │ │ │ ├── DDSView_Desktop_2012.vcxproj.filters │ │ │ ├── DDSView_Desktop_2013.sln │ │ │ ├── DDSView_Desktop_2013.vcxproj │ │ │ ├── DDSView_Desktop_2013.vcxproj.filters │ │ │ ├── DDSView_Desktop_2015.sln │ │ │ ├── DDSView_Desktop_2015.vcxproj │ │ │ ├── DDSView_Desktop_2015.vcxproj.filters │ │ │ ├── ddsview.cpp │ │ │ ├── ddsview.fx │ │ │ ├── hlsl.cmd │ │ │ └── shaders/ │ │ │ ├── ps1D.h │ │ │ ├── ps1Darray.h │ │ │ ├── ps2D.h │ │ │ ├── ps2Darray.h │ │ │ ├── ps3D.h │ │ │ ├── psCube.h │ │ │ └── vs.h │ │ ├── DirectXTex/ │ │ │ ├── BC.cpp │ │ │ ├── BC.h │ │ │ ├── BC4BC5.cpp │ │ │ ├── BC6HBC7.cpp │ │ │ ├── BCDirectCompute.cpp │ │ │ ├── BCDirectCompute.h │ │ │ ├── DDS.h │ │ │ ├── DirectXTex.h │ │ │ ├── DirectXTex.inl │ │ │ ├── DirectXTexCompress.cpp │ │ │ ├── DirectXTexCompressGPU.cpp │ │ │ ├── DirectXTexConvert.cpp │ │ │ ├── DirectXTexD3D11.cpp │ │ │ ├── DirectXTexDDS.cpp │ │ │ ├── DirectXTexFlipRotate.cpp │ │ │ ├── DirectXTexImage.cpp │ │ │ ├── DirectXTexMipmaps.cpp │ │ │ ├── DirectXTexMisc.cpp │ │ │ ├── DirectXTexNormalMaps.cpp │ │ │ ├── DirectXTexP.h │ │ │ ├── DirectXTexPMAlpha.cpp │ │ │ ├── DirectXTexResize.cpp │ │ │ ├── DirectXTexTGA.cpp │ │ │ ├── DirectXTexUtil.cpp │ │ │ ├── DirectXTexWIC.cpp │ │ │ ├── DirectXTex_Desktop_2012.sln │ │ │ ├── DirectXTex_Desktop_2012.vcxproj │ │ │ ├── DirectXTex_Desktop_2012.vcxproj.filters │ │ │ ├── DirectXTex_Desktop_2013.sln │ │ │ ├── DirectXTex_Desktop_2013.vcxproj │ │ │ ├── DirectXTex_Desktop_2013.vcxproj.filters │ │ │ ├── DirectXTex_Desktop_2015.sln │ │ │ ├── DirectXTex_Desktop_2015.vcxproj │ │ │ ├── DirectXTex_Desktop_2015.vcxproj.filters │ │ │ ├── DirectXTex_Windows10.sln │ │ │ ├── DirectXTex_Windows10.vcxproj │ │ │ ├── DirectXTex_Windows10.vcxproj.filters │ │ │ ├── DirectXTex_Windows81.sln │ │ │ ├── DirectXTex_Windows81.vcxproj │ │ │ ├── DirectXTex_Windows81.vcxproj.filters │ │ │ ├── DirectXTex_WindowsPhone81.sln │ │ │ ├── DirectXTex_WindowsPhone81.vcxproj │ │ │ ├── DirectXTex_WindowsPhone81.vcxproj.filters │ │ │ ├── DirectXTex_XboxOneADK.sln │ │ │ ├── DirectXTex_XboxOneADK.vcxproj │ │ │ ├── DirectXTex_XboxOneADK.vcxproj.filters │ │ │ ├── DirectXTex_XboxOneXDK.sln │ │ │ ├── DirectXTex_XboxOneXDK.vcxproj │ │ │ ├── DirectXTex_XboxOneXDK.vcxproj.filters │ │ │ ├── Filters.h │ │ │ ├── Shaders/ │ │ │ │ ├── BC6HEncode.hlsl │ │ │ │ ├── BC7Encode.hlsl │ │ │ │ ├── CompileShaders.cmd │ │ │ │ └── Compiled/ │ │ │ │ ├── BC6HEncode_EncodeBlockCS.inc │ │ │ │ ├── BC6HEncode_TryModeG10CS.inc │ │ │ │ ├── BC6HEncode_TryModeLE10CS.inc │ │ │ │ ├── BC7Encode_EncodeBlockCS.inc │ │ │ │ ├── BC7Encode_TryMode02CS.inc │ │ │ │ ├── BC7Encode_TryMode137CS.inc │ │ │ │ └── BC7Encode_TryMode456CS.inc │ │ │ └── scoped.h │ │ ├── MIT.txt │ │ ├── ReadMe.txt │ │ ├── ScreenGrab/ │ │ │ ├── ScreenGrab.cpp │ │ │ └── ScreenGrab.h │ │ ├── Texassemble/ │ │ │ ├── Texassemble_Desktop_2012.sln │ │ │ ├── Texassemble_Desktop_2012.vcxproj │ │ │ ├── Texassemble_Desktop_2012.vcxproj.filters │ │ │ ├── Texassemble_Desktop_2013.sln │ │ │ ├── Texassemble_Desktop_2013.vcxproj │ │ │ ├── Texassemble_Desktop_2013.vcxproj.filters │ │ │ ├── Texassemble_Desktop_2015.sln │ │ │ ├── Texassemble_Desktop_2015.vcxproj │ │ │ ├── Texassemble_Desktop_2015.vcxproj.filters │ │ │ ├── texassemble.cpp │ │ │ └── texassemble.rc │ │ ├── Texconv/ │ │ │ ├── Texconv.rc │ │ │ ├── Texconv_Desktop_2012.sln │ │ │ ├── Texconv_Desktop_2012.vcxproj │ │ │ ├── Texconv_Desktop_2012.vcxproj.filters │ │ │ ├── Texconv_Desktop_2013.sln │ │ │ ├── Texconv_Desktop_2013.vcxproj │ │ │ ├── Texconv_Desktop_2013.vcxproj.filters │ │ │ ├── Texconv_Desktop_2015.sln │ │ │ ├── Texconv_Desktop_2015.vcxproj │ │ │ ├── Texconv_Desktop_2015.vcxproj.filters │ │ │ └── texconv.cpp │ │ └── WICTextureLoader/ │ │ ├── WICTextureLoader.cpp │ │ └── WICTextureLoader.h │ └── Intel/ │ └── Source/ │ ├── StopWatch.cpp │ ├── StopWatch.h │ ├── ispc_texcomp.cpp │ ├── ispc_texcomp.h │ ├── win32Threads.cpp │ └── win32Threads.h ├── IntelCompressionPlugin/ │ ├── IntelPlugin.cpp │ ├── IntelPlugin.h │ ├── IntelPlugin.r │ ├── IntelPlugin.rc │ ├── IntelPluginName.h │ ├── IntelPluginUIWin.cpp │ ├── IntelPluginUIWin.h │ ├── IntelTextureWorks.vcxproj │ ├── IntelTextureWorks.vcxproj.filters │ ├── PreviewDialog.cpp │ ├── PreviewDialog.h │ ├── SaveOptionsDialog.cpp │ ├── SaveOptionsDialog.h │ ├── kernel.ispc │ └── resource.h ├── IntelTextureWorks.sln ├── PhotoshopScripts/ │ ├── IntelTextureWorks-ConvertCubeMap.jsx │ └── IntelTextureWorks-CubeMapGaussianBlur.jsx ├── README.md ├── Sample Images/ │ ├── CubeMapByLayerTestImage.psd │ ├── HDR.hdr │ ├── baboon-MipMapAsLayers.psd │ ├── mandrill-MipMapAsLayers.psd │ ├── monkey-32bit.hdr │ ├── monkey-MipMapAsLayers.psd │ └── monkey.tif └── license.txt ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ # ignore these types *.cache *.log *.suo *.sdf *.opensdf *.pdb *.user *.tmp_proj *.bsc *.ilk # intel compiler generated *_ispc*.h #ignore these folders Debug/ Release/ bin/ obj/ ipch/ *.DS_Store *.pipl Plugins/ *.dds *.aps *.zip *.tmp ================================================ FILE: 3rdParty/DirectXTex/.gitignore ================================================ *.psess *.vsp *.log *.err *.wrn *.suo *.sdf *.user *.i *.vspscc *.opensdf *.ipch *.cache *.tlog *.lastbuildstate *.ilk Bin /ipch Debug Profile Release x64 /Tests /wiki ================================================ FILE: 3rdParty/DirectXTex/DDSTextureLoader/DDSTextureLoader.cpp ================================================ //-------------------------------------------------------------------------------------- // File: DDSTextureLoader.cpp // // Functions for loading a DDS texture and creating a Direct3D 11 runtime resource for it // // Note these functions are useful as a light-weight runtime loader for DDS files. For // a full-featured DDS file reader, writer, and texture processing pipeline see // the 'Texconv' sample and the 'DirectXTex' library. // // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A // PARTICULAR PURPOSE. // // Copyright (c) Microsoft Corporation. All rights reserved. // // http://go.microsoft.com/fwlink/?LinkId=248926 // http://go.microsoft.com/fwlink/?LinkId=248929 //-------------------------------------------------------------------------------------- #include #include #include #include "DDSTextureLoader.h" #if !defined(NO_D3D11_DEBUG_NAME) && ( defined(_DEBUG) || defined(PROFILE) ) #pragma comment(lib,"dxguid.lib") #endif using namespace DirectX; //-------------------------------------------------------------------------------------- // Macros //-------------------------------------------------------------------------------------- #ifndef MAKEFOURCC #define MAKEFOURCC(ch0, ch1, ch2, ch3) \ ((uint32_t)(uint8_t)(ch0) | ((uint32_t)(uint8_t)(ch1) << 8) | \ ((uint32_t)(uint8_t)(ch2) << 16) | ((uint32_t)(uint8_t)(ch3) << 24 )) #endif /* defined(MAKEFOURCC) */ //-------------------------------------------------------------------------------------- // DDS file structure definitions // // See DDS.h in the 'Texconv' sample and the 'DirectXTex' library //-------------------------------------------------------------------------------------- #pragma pack(push,1) const uint32_t DDS_MAGIC = 0x20534444; // "DDS " struct DDS_PIXELFORMAT { uint32_t size; uint32_t flags; uint32_t fourCC; uint32_t RGBBitCount; uint32_t RBitMask; uint32_t GBitMask; uint32_t BBitMask; uint32_t ABitMask; }; #define DDS_FOURCC 0x00000004 // DDPF_FOURCC #define DDS_RGB 0x00000040 // DDPF_RGB #define DDS_LUMINANCE 0x00020000 // DDPF_LUMINANCE #define DDS_ALPHA 0x00000002 // DDPF_ALPHA #define DDS_HEADER_FLAGS_VOLUME 0x00800000 // DDSD_DEPTH #define DDS_HEIGHT 0x00000002 // DDSD_HEIGHT #define DDS_WIDTH 0x00000004 // DDSD_WIDTH #define DDS_CUBEMAP_POSITIVEX 0x00000600 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEX #define DDS_CUBEMAP_NEGATIVEX 0x00000a00 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEX #define DDS_CUBEMAP_POSITIVEY 0x00001200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEY #define DDS_CUBEMAP_NEGATIVEY 0x00002200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEY #define DDS_CUBEMAP_POSITIVEZ 0x00004200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEZ #define DDS_CUBEMAP_NEGATIVEZ 0x00008200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEZ #define DDS_CUBEMAP_ALLFACES ( DDS_CUBEMAP_POSITIVEX | DDS_CUBEMAP_NEGATIVEX |\ DDS_CUBEMAP_POSITIVEY | DDS_CUBEMAP_NEGATIVEY |\ DDS_CUBEMAP_POSITIVEZ | DDS_CUBEMAP_NEGATIVEZ ) #define DDS_CUBEMAP 0x00000200 // DDSCAPS2_CUBEMAP enum DDS_MISC_FLAGS2 { DDS_MISC_FLAGS2_ALPHA_MODE_MASK = 0x7L, }; struct DDS_HEADER { uint32_t size; uint32_t flags; uint32_t height; uint32_t width; uint32_t pitchOrLinearSize; uint32_t depth; // only if DDS_HEADER_FLAGS_VOLUME is set in flags uint32_t mipMapCount; uint32_t reserved1[11]; DDS_PIXELFORMAT ddspf; uint32_t caps; uint32_t caps2; uint32_t caps3; uint32_t caps4; uint32_t reserved2; }; struct DDS_HEADER_DXT10 { DXGI_FORMAT dxgiFormat; uint32_t resourceDimension; uint32_t miscFlag; // see D3D11_RESOURCE_MISC_FLAG uint32_t arraySize; uint32_t miscFlags2; }; #pragma pack(pop) //-------------------------------------------------------------------------------------- namespace { struct handle_closer { void operator()(HANDLE h) { if (h) CloseHandle(h); } }; typedef public std::unique_ptr ScopedHandle; inline HANDLE safe_handle( HANDLE h ) { return (h == INVALID_HANDLE_VALUE) ? 0 : h; } template inline void SetDebugObjectName(_In_ ID3D11DeviceChild* resource, _In_ const char (&name)[TNameLength]) { #if defined(_DEBUG) || defined(PROFILE) resource->SetPrivateData(WKPDID_D3DDebugObjectName, TNameLength - 1, name); #else UNREFERENCED_PARAMETER(resource); UNREFERENCED_PARAMETER(name); #endif } }; //-------------------------------------------------------------------------------------- static HRESULT LoadTextureDataFromFile( _In_z_ const wchar_t* fileName, std::unique_ptr& ddsData, DDS_HEADER** header, uint8_t** bitData, size_t* bitSize ) { if (!header || !bitData || !bitSize) { return E_POINTER; } // open the file #if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) ScopedHandle hFile( safe_handle( CreateFile2( fileName, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, nullptr ) ) ); #else ScopedHandle hFile( safe_handle( CreateFileW( fileName, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr ) ) ); #endif if ( !hFile ) { return HRESULT_FROM_WIN32( GetLastError() ); } // Get the file size LARGE_INTEGER FileSize = { 0 }; #if (_WIN32_WINNT >= _WIN32_WINNT_VISTA) FILE_STANDARD_INFO fileInfo; if ( !GetFileInformationByHandleEx( hFile.get(), FileStandardInfo, &fileInfo, sizeof(fileInfo) ) ) { return HRESULT_FROM_WIN32( GetLastError() ); } FileSize = fileInfo.EndOfFile; #else GetFileSizeEx( hFile.get(), &FileSize ); #endif // File is too big for 32-bit allocation, so reject read if (FileSize.HighPart > 0) { return E_FAIL; } // Need at least enough data to fill the header and magic number to be a valid DDS if (FileSize.LowPart < ( sizeof(DDS_HEADER) + sizeof(uint32_t) ) ) { return E_FAIL; } // create enough space for the file data ddsData.reset( new (std::nothrow) uint8_t[ FileSize.LowPart ] ); if (!ddsData) { return E_OUTOFMEMORY; } // read the data in DWORD BytesRead = 0; if (!ReadFile( hFile.get(), ddsData.get(), FileSize.LowPart, &BytesRead, nullptr )) { return HRESULT_FROM_WIN32( GetLastError() ); } if (BytesRead < FileSize.LowPart) { return E_FAIL; } // DDS files always start with the same magic number ("DDS ") uint32_t dwMagicNumber = *( const uint32_t* )( ddsData.get() ); if (dwMagicNumber != DDS_MAGIC) { return E_FAIL; } auto hdr = reinterpret_cast( ddsData.get() + sizeof( uint32_t ) ); // Verify header to validate DDS file if (hdr->size != sizeof(DDS_HEADER) || hdr->ddspf.size != sizeof(DDS_PIXELFORMAT)) { return E_FAIL; } // Check for DX10 extension bool bDXT10Header = false; if ((hdr->ddspf.flags & DDS_FOURCC) && (MAKEFOURCC( 'D', 'X', '1', '0' ) == hdr->ddspf.fourCC)) { // Must be long enough for both headers and magic value if (FileSize.LowPart < ( sizeof(DDS_HEADER) + sizeof(uint32_t) + sizeof(DDS_HEADER_DXT10) ) ) { return E_FAIL; } bDXT10Header = true; } // setup the pointers in the process request *header = hdr; ptrdiff_t offset = sizeof( uint32_t ) + sizeof( DDS_HEADER ) + (bDXT10Header ? sizeof( DDS_HEADER_DXT10 ) : 0); *bitData = ddsData.get() + offset; *bitSize = FileSize.LowPart - offset; return S_OK; } //-------------------------------------------------------------------------------------- // Return the BPP for a particular format //-------------------------------------------------------------------------------------- static size_t BitsPerPixel( _In_ DXGI_FORMAT fmt ) { switch( fmt ) { case DXGI_FORMAT_R32G32B32A32_TYPELESS: case DXGI_FORMAT_R32G32B32A32_FLOAT: case DXGI_FORMAT_R32G32B32A32_UINT: case DXGI_FORMAT_R32G32B32A32_SINT: return 128; case DXGI_FORMAT_R32G32B32_TYPELESS: case DXGI_FORMAT_R32G32B32_FLOAT: case DXGI_FORMAT_R32G32B32_UINT: case DXGI_FORMAT_R32G32B32_SINT: return 96; case DXGI_FORMAT_R16G16B16A16_TYPELESS: case DXGI_FORMAT_R16G16B16A16_FLOAT: case DXGI_FORMAT_R16G16B16A16_UNORM: case DXGI_FORMAT_R16G16B16A16_UINT: case DXGI_FORMAT_R16G16B16A16_SNORM: case DXGI_FORMAT_R16G16B16A16_SINT: case DXGI_FORMAT_R32G32_TYPELESS: case DXGI_FORMAT_R32G32_FLOAT: case DXGI_FORMAT_R32G32_UINT: case DXGI_FORMAT_R32G32_SINT: case DXGI_FORMAT_R32G8X24_TYPELESS: case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: case DXGI_FORMAT_Y416: case DXGI_FORMAT_Y210: case DXGI_FORMAT_Y216: return 64; case DXGI_FORMAT_R10G10B10A2_TYPELESS: case DXGI_FORMAT_R10G10B10A2_UNORM: case DXGI_FORMAT_R10G10B10A2_UINT: case DXGI_FORMAT_R11G11B10_FLOAT: case DXGI_FORMAT_R8G8B8A8_TYPELESS: case DXGI_FORMAT_R8G8B8A8_UNORM: case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: case DXGI_FORMAT_R8G8B8A8_UINT: case DXGI_FORMAT_R8G8B8A8_SNORM: case DXGI_FORMAT_R8G8B8A8_SINT: case DXGI_FORMAT_R16G16_TYPELESS: case DXGI_FORMAT_R16G16_FLOAT: case DXGI_FORMAT_R16G16_UNORM: case DXGI_FORMAT_R16G16_UINT: case DXGI_FORMAT_R16G16_SNORM: case DXGI_FORMAT_R16G16_SINT: case DXGI_FORMAT_R32_TYPELESS: case DXGI_FORMAT_D32_FLOAT: case DXGI_FORMAT_R32_FLOAT: case DXGI_FORMAT_R32_UINT: case DXGI_FORMAT_R32_SINT: case DXGI_FORMAT_R24G8_TYPELESS: case DXGI_FORMAT_D24_UNORM_S8_UINT: case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: case DXGI_FORMAT_X24_TYPELESS_G8_UINT: case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: case DXGI_FORMAT_R8G8_B8G8_UNORM: case DXGI_FORMAT_G8R8_G8B8_UNORM: case DXGI_FORMAT_B8G8R8A8_UNORM: case DXGI_FORMAT_B8G8R8X8_UNORM: case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM: case DXGI_FORMAT_B8G8R8A8_TYPELESS: case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: case DXGI_FORMAT_B8G8R8X8_TYPELESS: case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: case DXGI_FORMAT_AYUV: case DXGI_FORMAT_Y410: case DXGI_FORMAT_YUY2: return 32; case DXGI_FORMAT_P010: case DXGI_FORMAT_P016: return 24; case DXGI_FORMAT_R8G8_TYPELESS: case DXGI_FORMAT_R8G8_UNORM: case DXGI_FORMAT_R8G8_UINT: case DXGI_FORMAT_R8G8_SNORM: case DXGI_FORMAT_R8G8_SINT: case DXGI_FORMAT_R16_TYPELESS: case DXGI_FORMAT_R16_FLOAT: case DXGI_FORMAT_D16_UNORM: case DXGI_FORMAT_R16_UNORM: case DXGI_FORMAT_R16_UINT: case DXGI_FORMAT_R16_SNORM: case DXGI_FORMAT_R16_SINT: case DXGI_FORMAT_B5G6R5_UNORM: case DXGI_FORMAT_B5G5R5A1_UNORM: case DXGI_FORMAT_A8P8: case DXGI_FORMAT_B4G4R4A4_UNORM: return 16; case DXGI_FORMAT_NV12: case DXGI_FORMAT_420_OPAQUE: case DXGI_FORMAT_NV11: return 12; case DXGI_FORMAT_R8_TYPELESS: case DXGI_FORMAT_R8_UNORM: case DXGI_FORMAT_R8_UINT: case DXGI_FORMAT_R8_SNORM: case DXGI_FORMAT_R8_SINT: case DXGI_FORMAT_A8_UNORM: case DXGI_FORMAT_AI44: case DXGI_FORMAT_IA44: case DXGI_FORMAT_P8: return 8; case DXGI_FORMAT_R1_UNORM: return 1; case DXGI_FORMAT_BC1_TYPELESS: case DXGI_FORMAT_BC1_UNORM: case DXGI_FORMAT_BC1_UNORM_SRGB: case DXGI_FORMAT_BC4_TYPELESS: case DXGI_FORMAT_BC4_UNORM: case DXGI_FORMAT_BC4_SNORM: return 4; case DXGI_FORMAT_BC2_TYPELESS: case DXGI_FORMAT_BC2_UNORM: case DXGI_FORMAT_BC2_UNORM_SRGB: case DXGI_FORMAT_BC3_TYPELESS: case DXGI_FORMAT_BC3_UNORM: case DXGI_FORMAT_BC3_UNORM_SRGB: case DXGI_FORMAT_BC5_TYPELESS: case DXGI_FORMAT_BC5_UNORM: case DXGI_FORMAT_BC5_SNORM: case DXGI_FORMAT_BC6H_TYPELESS: case DXGI_FORMAT_BC6H_UF16: case DXGI_FORMAT_BC6H_SF16: case DXGI_FORMAT_BC7_TYPELESS: case DXGI_FORMAT_BC7_UNORM: case DXGI_FORMAT_BC7_UNORM_SRGB: return 8; default: return 0; } } //-------------------------------------------------------------------------------------- // Get surface information for a particular format //-------------------------------------------------------------------------------------- static void GetSurfaceInfo( _In_ size_t width, _In_ size_t height, _In_ DXGI_FORMAT fmt, _Out_opt_ size_t* outNumBytes, _Out_opt_ size_t* outRowBytes, _Out_opt_ size_t* outNumRows ) { size_t numBytes = 0; size_t rowBytes = 0; size_t numRows = 0; bool bc = false; bool packed = false; bool planar = false; size_t bpe = 0; switch (fmt) { case DXGI_FORMAT_BC1_TYPELESS: case DXGI_FORMAT_BC1_UNORM: case DXGI_FORMAT_BC1_UNORM_SRGB: case DXGI_FORMAT_BC4_TYPELESS: case DXGI_FORMAT_BC4_UNORM: case DXGI_FORMAT_BC4_SNORM: bc=true; bpe = 8; break; case DXGI_FORMAT_BC2_TYPELESS: case DXGI_FORMAT_BC2_UNORM: case DXGI_FORMAT_BC2_UNORM_SRGB: case DXGI_FORMAT_BC3_TYPELESS: case DXGI_FORMAT_BC3_UNORM: case DXGI_FORMAT_BC3_UNORM_SRGB: case DXGI_FORMAT_BC5_TYPELESS: case DXGI_FORMAT_BC5_UNORM: case DXGI_FORMAT_BC5_SNORM: case DXGI_FORMAT_BC6H_TYPELESS: case DXGI_FORMAT_BC6H_UF16: case DXGI_FORMAT_BC6H_SF16: case DXGI_FORMAT_BC7_TYPELESS: case DXGI_FORMAT_BC7_UNORM: case DXGI_FORMAT_BC7_UNORM_SRGB: bc = true; bpe = 16; break; case DXGI_FORMAT_R8G8_B8G8_UNORM: case DXGI_FORMAT_G8R8_G8B8_UNORM: case DXGI_FORMAT_YUY2: packed = true; bpe = 4; break; case DXGI_FORMAT_Y210: case DXGI_FORMAT_Y216: packed = true; bpe = 8; break; case DXGI_FORMAT_NV12: case DXGI_FORMAT_420_OPAQUE: planar = true; bpe = 2; break; case DXGI_FORMAT_P010: case DXGI_FORMAT_P016: planar = true; bpe = 4; break; } if (bc) { size_t numBlocksWide = 0; if (width > 0) { numBlocksWide = std::max( 1, (width + 3) / 4 ); } size_t numBlocksHigh = 0; if (height > 0) { numBlocksHigh = std::max( 1, (height + 3) / 4 ); } rowBytes = numBlocksWide * bpe; numRows = numBlocksHigh; numBytes = rowBytes * numBlocksHigh; } else if (packed) { rowBytes = ( ( width + 1 ) >> 1 ) * bpe; numRows = height; numBytes = rowBytes * height; } else if ( fmt == DXGI_FORMAT_NV11 ) { rowBytes = ( ( width + 3 ) >> 2 ) * 4; numRows = height * 2; // Direct3D makes this simplifying assumption, although it is larger than the 4:1:1 data numBytes = rowBytes * numRows; } else if (planar) { rowBytes = ( ( width + 1 ) >> 1 ) * bpe; numBytes = ( rowBytes * height ) + ( ( rowBytes * height + 1 ) >> 1 ); numRows = height + ( ( height + 1 ) >> 1 ); } else { size_t bpp = BitsPerPixel( fmt ); rowBytes = ( width * bpp + 7 ) / 8; // round up to nearest byte numRows = height; numBytes = rowBytes * height; } if (outNumBytes) { *outNumBytes = numBytes; } if (outRowBytes) { *outRowBytes = rowBytes; } if (outNumRows) { *outNumRows = numRows; } } //-------------------------------------------------------------------------------------- #define ISBITMASK( r,g,b,a ) ( ddpf.RBitMask == r && ddpf.GBitMask == g && ddpf.BBitMask == b && ddpf.ABitMask == a ) static DXGI_FORMAT GetDXGIFormat( const DDS_PIXELFORMAT& ddpf ) { if (ddpf.flags & DDS_RGB) { // Note that sRGB formats are written using the "DX10" extended header switch (ddpf.RGBBitCount) { case 32: if (ISBITMASK(0x000000ff,0x0000ff00,0x00ff0000,0xff000000)) { return DXGI_FORMAT_R8G8B8A8_UNORM; } if (ISBITMASK(0x00ff0000,0x0000ff00,0x000000ff,0xff000000)) { return DXGI_FORMAT_B8G8R8A8_UNORM; } if (ISBITMASK(0x00ff0000,0x0000ff00,0x000000ff,0x00000000)) { return DXGI_FORMAT_B8G8R8X8_UNORM; } // No DXGI format maps to ISBITMASK(0x000000ff,0x0000ff00,0x00ff0000,0x00000000) aka D3DFMT_X8B8G8R8 // Note that many common DDS reader/writers (including D3DX) swap the // the RED/BLUE masks for 10:10:10:2 formats. We assume // below that the 'backwards' header mask is being used since it is most // likely written by D3DX. The more robust solution is to use the 'DX10' // header extension and specify the DXGI_FORMAT_R10G10B10A2_UNORM format directly // For 'correct' writers, this should be 0x000003ff,0x000ffc00,0x3ff00000 for RGB data if (ISBITMASK(0x3ff00000,0x000ffc00,0x000003ff,0xc0000000)) { return DXGI_FORMAT_R10G10B10A2_UNORM; } // No DXGI format maps to ISBITMASK(0x000003ff,0x000ffc00,0x3ff00000,0xc0000000) aka D3DFMT_A2R10G10B10 if (ISBITMASK(0x0000ffff,0xffff0000,0x00000000,0x00000000)) { return DXGI_FORMAT_R16G16_UNORM; } if (ISBITMASK(0xffffffff,0x00000000,0x00000000,0x00000000)) { // Only 32-bit color channel format in D3D9 was R32F return DXGI_FORMAT_R32_FLOAT; // D3DX writes this out as a FourCC of 114 } break; case 24: // No 24bpp DXGI formats aka D3DFMT_R8G8B8 break; case 16: if (ISBITMASK(0x7c00,0x03e0,0x001f,0x8000)) { return DXGI_FORMAT_B5G5R5A1_UNORM; } if (ISBITMASK(0xf800,0x07e0,0x001f,0x0000)) { return DXGI_FORMAT_B5G6R5_UNORM; } // No DXGI format maps to ISBITMASK(0x7c00,0x03e0,0x001f,0x0000) aka D3DFMT_X1R5G5B5 if (ISBITMASK(0x0f00,0x00f0,0x000f,0xf000)) { return DXGI_FORMAT_B4G4R4A4_UNORM; } // No DXGI format maps to ISBITMASK(0x0f00,0x00f0,0x000f,0x0000) aka D3DFMT_X4R4G4B4 // No 3:3:2, 3:3:2:8, or paletted DXGI formats aka D3DFMT_A8R3G3B2, D3DFMT_R3G3B2, D3DFMT_P8, D3DFMT_A8P8, etc. break; } } else if (ddpf.flags & DDS_LUMINANCE) { if (8 == ddpf.RGBBitCount) { if (ISBITMASK(0x000000ff,0x00000000,0x00000000,0x00000000)) { return DXGI_FORMAT_R8_UNORM; // D3DX10/11 writes this out as DX10 extension } // No DXGI format maps to ISBITMASK(0x0f,0x00,0x00,0xf0) aka D3DFMT_A4L4 } if (16 == ddpf.RGBBitCount) { if (ISBITMASK(0x0000ffff,0x00000000,0x00000000,0x00000000)) { return DXGI_FORMAT_R16_UNORM; // D3DX10/11 writes this out as DX10 extension } if (ISBITMASK(0x000000ff,0x00000000,0x00000000,0x0000ff00)) { return DXGI_FORMAT_R8G8_UNORM; // D3DX10/11 writes this out as DX10 extension } } } else if (ddpf.flags & DDS_ALPHA) { if (8 == ddpf.RGBBitCount) { return DXGI_FORMAT_A8_UNORM; } } else if (ddpf.flags & DDS_FOURCC) { if (MAKEFOURCC( 'D', 'X', 'T', '1' ) == ddpf.fourCC) { return DXGI_FORMAT_BC1_UNORM; } if (MAKEFOURCC( 'D', 'X', 'T', '3' ) == ddpf.fourCC) { return DXGI_FORMAT_BC2_UNORM; } if (MAKEFOURCC( 'D', 'X', 'T', '5' ) == ddpf.fourCC) { return DXGI_FORMAT_BC3_UNORM; } // While pre-multiplied alpha isn't directly supported by the DXGI formats, // they are basically the same as these BC formats so they can be mapped if (MAKEFOURCC( 'D', 'X', 'T', '2' ) == ddpf.fourCC) { return DXGI_FORMAT_BC2_UNORM; } if (MAKEFOURCC( 'D', 'X', 'T', '4' ) == ddpf.fourCC) { return DXGI_FORMAT_BC3_UNORM; } if (MAKEFOURCC( 'A', 'T', 'I', '1' ) == ddpf.fourCC) { return DXGI_FORMAT_BC4_UNORM; } if (MAKEFOURCC( 'B', 'C', '4', 'U' ) == ddpf.fourCC) { return DXGI_FORMAT_BC4_UNORM; } if (MAKEFOURCC( 'B', 'C', '4', 'S' ) == ddpf.fourCC) { return DXGI_FORMAT_BC4_SNORM; } if (MAKEFOURCC( 'A', 'T', 'I', '2' ) == ddpf.fourCC) { return DXGI_FORMAT_BC5_UNORM; } if (MAKEFOURCC( 'B', 'C', '5', 'U' ) == ddpf.fourCC) { return DXGI_FORMAT_BC5_UNORM; } if (MAKEFOURCC( 'B', 'C', '5', 'S' ) == ddpf.fourCC) { return DXGI_FORMAT_BC5_SNORM; } // BC6H and BC7 are written using the "DX10" extended header if (MAKEFOURCC( 'R', 'G', 'B', 'G' ) == ddpf.fourCC) { return DXGI_FORMAT_R8G8_B8G8_UNORM; } if (MAKEFOURCC( 'G', 'R', 'G', 'B' ) == ddpf.fourCC) { return DXGI_FORMAT_G8R8_G8B8_UNORM; } if (MAKEFOURCC('Y','U','Y','2') == ddpf.fourCC) { return DXGI_FORMAT_YUY2; } // Check for D3DFORMAT enums being set here switch( ddpf.fourCC ) { case 36: // D3DFMT_A16B16G16R16 return DXGI_FORMAT_R16G16B16A16_UNORM; case 110: // D3DFMT_Q16W16V16U16 return DXGI_FORMAT_R16G16B16A16_SNORM; case 111: // D3DFMT_R16F return DXGI_FORMAT_R16_FLOAT; case 112: // D3DFMT_G16R16F return DXGI_FORMAT_R16G16_FLOAT; case 113: // D3DFMT_A16B16G16R16F return DXGI_FORMAT_R16G16B16A16_FLOAT; case 114: // D3DFMT_R32F return DXGI_FORMAT_R32_FLOAT; case 115: // D3DFMT_G32R32F return DXGI_FORMAT_R32G32_FLOAT; case 116: // D3DFMT_A32B32G32R32F return DXGI_FORMAT_R32G32B32A32_FLOAT; } } return DXGI_FORMAT_UNKNOWN; } //-------------------------------------------------------------------------------------- static DXGI_FORMAT MakeSRGB( _In_ DXGI_FORMAT format ) { switch( format ) { case DXGI_FORMAT_R8G8B8A8_UNORM: return DXGI_FORMAT_R8G8B8A8_UNORM_SRGB; case DXGI_FORMAT_BC1_UNORM: return DXGI_FORMAT_BC1_UNORM_SRGB; case DXGI_FORMAT_BC2_UNORM: return DXGI_FORMAT_BC2_UNORM_SRGB; case DXGI_FORMAT_BC3_UNORM: return DXGI_FORMAT_BC3_UNORM_SRGB; case DXGI_FORMAT_B8G8R8A8_UNORM: return DXGI_FORMAT_B8G8R8A8_UNORM_SRGB; case DXGI_FORMAT_B8G8R8X8_UNORM: return DXGI_FORMAT_B8G8R8X8_UNORM_SRGB; case DXGI_FORMAT_BC7_UNORM: return DXGI_FORMAT_BC7_UNORM_SRGB; default: return format; } } //-------------------------------------------------------------------------------------- static HRESULT FillInitData( _In_ size_t width, _In_ size_t height, _In_ size_t depth, _In_ size_t mipCount, _In_ size_t arraySize, _In_ DXGI_FORMAT format, _In_ size_t maxsize, _In_ size_t bitSize, _In_reads_bytes_(bitSize) const uint8_t* bitData, _Out_ size_t& twidth, _Out_ size_t& theight, _Out_ size_t& tdepth, _Out_ size_t& skipMip, _Out_writes_(mipCount*arraySize) D3D11_SUBRESOURCE_DATA* initData ) { if ( !bitData || !initData ) { return E_POINTER; } skipMip = 0; twidth = 0; theight = 0; tdepth = 0; size_t NumBytes = 0; size_t RowBytes = 0; const uint8_t* pSrcBits = bitData; const uint8_t* pEndBits = bitData + bitSize; size_t index = 0; for( size_t j = 0; j < arraySize; j++ ) { size_t w = width; size_t h = height; size_t d = depth; for( size_t i = 0; i < mipCount; i++ ) { GetSurfaceInfo( w, h, format, &NumBytes, &RowBytes, nullptr ); if ( (mipCount <= 1) || !maxsize || (w <= maxsize && h <= maxsize && d <= maxsize) ) { if ( !twidth ) { twidth = w; theight = h; tdepth = d; } assert(index < mipCount * arraySize); _Analysis_assume_(index < mipCount * arraySize); initData[index].pSysMem = ( const void* )pSrcBits; initData[index].SysMemPitch = static_cast( RowBytes ); initData[index].SysMemSlicePitch = static_cast( NumBytes ); ++index; } else if ( !j ) { // Count number of skipped mipmaps (first item only) ++skipMip; } if (pSrcBits + (NumBytes*d) > pEndBits) { return HRESULT_FROM_WIN32( ERROR_HANDLE_EOF ); } pSrcBits += NumBytes * d; w = w >> 1; h = h >> 1; d = d >> 1; if (w == 0) { w = 1; } if (h == 0) { h = 1; } if (d == 0) { d = 1; } } } return (index > 0) ? S_OK : E_FAIL; } //-------------------------------------------------------------------------------------- static HRESULT CreateD3DResources( _In_ ID3D11Device* d3dDevice, _In_ uint32_t resDim, _In_ size_t width, _In_ size_t height, _In_ size_t depth, _In_ size_t mipCount, _In_ size_t arraySize, _In_ DXGI_FORMAT format, _In_ D3D11_USAGE usage, _In_ unsigned int bindFlags, _In_ unsigned int cpuAccessFlags, _In_ unsigned int miscFlags, _In_ bool forceSRGB, _In_ bool isCubeMap, _In_reads_opt_(mipCount*arraySize) D3D11_SUBRESOURCE_DATA* initData, _Outptr_opt_ ID3D11Resource** texture, _Outptr_opt_ ID3D11ShaderResourceView** textureView ) { if ( !d3dDevice ) return E_POINTER; HRESULT hr = E_FAIL; if ( forceSRGB ) { format = MakeSRGB( format ); } switch ( resDim ) { case D3D11_RESOURCE_DIMENSION_TEXTURE1D: { D3D11_TEXTURE1D_DESC desc; desc.Width = static_cast( width ); desc.MipLevels = static_cast( mipCount ); desc.ArraySize = static_cast( arraySize ); desc.Format = format; desc.Usage = usage; desc.BindFlags = bindFlags; desc.CPUAccessFlags = cpuAccessFlags; desc.MiscFlags = miscFlags & ~D3D11_RESOURCE_MISC_TEXTURECUBE; ID3D11Texture1D* tex = nullptr; hr = d3dDevice->CreateTexture1D( &desc, initData, &tex ); if (SUCCEEDED( hr ) && tex != 0) { if (textureView != 0) { D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc; memset( &SRVDesc, 0, sizeof( SRVDesc ) ); SRVDesc.Format = format; if (arraySize > 1) { SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1DARRAY; SRVDesc.Texture1DArray.MipLevels = (!mipCount) ? -1 : desc.MipLevels; SRVDesc.Texture1DArray.ArraySize = static_cast( arraySize ); } else { SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1D; SRVDesc.Texture1D.MipLevels = (!mipCount) ? -1 : desc.MipLevels; } hr = d3dDevice->CreateShaderResourceView( tex, &SRVDesc, textureView ); if ( FAILED(hr) ) { tex->Release(); return hr; } } if (texture != 0) { *texture = tex; } else { SetDebugObjectName(tex, "DDSTextureLoader"); tex->Release(); } } } break; case D3D11_RESOURCE_DIMENSION_TEXTURE2D: { D3D11_TEXTURE2D_DESC desc; desc.Width = static_cast( width ); desc.Height = static_cast( height ); desc.MipLevels = static_cast( mipCount ); desc.ArraySize = static_cast( arraySize ); desc.Format = format; desc.SampleDesc.Count = 1; desc.SampleDesc.Quality = 0; desc.Usage = usage; desc.BindFlags = bindFlags; desc.CPUAccessFlags = cpuAccessFlags; if ( isCubeMap ) { desc.MiscFlags = miscFlags | D3D11_RESOURCE_MISC_TEXTURECUBE; } else { desc.MiscFlags = miscFlags & ~D3D11_RESOURCE_MISC_TEXTURECUBE; } ID3D11Texture2D* tex = nullptr; hr = d3dDevice->CreateTexture2D( &desc, initData, &tex ); if (SUCCEEDED( hr ) && tex != 0) { if (textureView != 0) { D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc; memset( &SRVDesc, 0, sizeof( SRVDesc ) ); SRVDesc.Format = format; if ( isCubeMap ) { if (arraySize > 6) { SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBEARRAY; SRVDesc.TextureCubeArray.MipLevels = (!mipCount) ? -1 : desc.MipLevels; // Earlier we set arraySize to (NumCubes * 6) SRVDesc.TextureCubeArray.NumCubes = static_cast( arraySize / 6 ); } else { SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE; SRVDesc.TextureCube.MipLevels = (!mipCount) ? -1 : desc.MipLevels; } } else if (arraySize > 1) { SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; SRVDesc.Texture2DArray.MipLevels = (!mipCount) ? -1 : desc.MipLevels; SRVDesc.Texture2DArray.ArraySize = static_cast( arraySize ); } else { SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; SRVDesc.Texture2D.MipLevels = (!mipCount) ? -1 : desc.MipLevels; } hr = d3dDevice->CreateShaderResourceView( tex, &SRVDesc, textureView ); if ( FAILED(hr) ) { tex->Release(); return hr; } } if (texture != 0) { *texture = tex; } else { SetDebugObjectName(tex, "DDSTextureLoader"); tex->Release(); } } } break; case D3D11_RESOURCE_DIMENSION_TEXTURE3D: { D3D11_TEXTURE3D_DESC desc; desc.Width = static_cast( width ); desc.Height = static_cast( height ); desc.Depth = static_cast( depth ); desc.MipLevels = static_cast( mipCount ); desc.Format = format; desc.Usage = usage; desc.BindFlags = bindFlags; desc.CPUAccessFlags = cpuAccessFlags; desc.MiscFlags = miscFlags & ~D3D11_RESOURCE_MISC_TEXTURECUBE; ID3D11Texture3D* tex = nullptr; hr = d3dDevice->CreateTexture3D( &desc, initData, &tex ); if (SUCCEEDED( hr ) && tex != 0) { if (textureView != 0) { D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc; memset( &SRVDesc, 0, sizeof( SRVDesc ) ); SRVDesc.Format = format; SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D; SRVDesc.Texture3D.MipLevels = (!mipCount) ? -1 : desc.MipLevels; hr = d3dDevice->CreateShaderResourceView( tex, &SRVDesc, textureView ); if ( FAILED(hr) ) { tex->Release(); return hr; } } if (texture != 0) { *texture = tex; } else { SetDebugObjectName(tex, "DDSTextureLoader"); tex->Release(); } } } break; } return hr; } //-------------------------------------------------------------------------------------- static HRESULT CreateTextureFromDDS( _In_ ID3D11Device* d3dDevice, _In_opt_ ID3D11DeviceContext* d3dContext, _In_ const DDS_HEADER* header, _In_reads_bytes_(bitSize) const uint8_t* bitData, _In_ size_t bitSize, _In_ size_t maxsize, _In_ D3D11_USAGE usage, _In_ unsigned int bindFlags, _In_ unsigned int cpuAccessFlags, _In_ unsigned int miscFlags, _In_ bool forceSRGB, _Outptr_opt_ ID3D11Resource** texture, _Outptr_opt_ ID3D11ShaderResourceView** textureView ) { HRESULT hr = S_OK; UINT width = header->width; UINT height = header->height; UINT depth = header->depth; uint32_t resDim = D3D11_RESOURCE_DIMENSION_UNKNOWN; UINT arraySize = 1; DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN; bool isCubeMap = false; size_t mipCount = header->mipMapCount; if (0 == mipCount) { mipCount = 1; } if ((header->ddspf.flags & DDS_FOURCC) && (MAKEFOURCC( 'D', 'X', '1', '0' ) == header->ddspf.fourCC )) { auto d3d10ext = reinterpret_cast( (const char*)header + sizeof(DDS_HEADER) ); arraySize = d3d10ext->arraySize; if (arraySize == 0) { return HRESULT_FROM_WIN32( ERROR_INVALID_DATA ); } switch( d3d10ext->dxgiFormat ) { case DXGI_FORMAT_AI44: case DXGI_FORMAT_IA44: case DXGI_FORMAT_P8: case DXGI_FORMAT_A8P8: return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); default: if ( BitsPerPixel( d3d10ext->dxgiFormat ) == 0 ) { return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); } } format = d3d10ext->dxgiFormat; switch ( d3d10ext->resourceDimension ) { case D3D11_RESOURCE_DIMENSION_TEXTURE1D: // D3DX writes 1D textures with a fixed Height of 1 if ((header->flags & DDS_HEIGHT) && height != 1) { return HRESULT_FROM_WIN32( ERROR_INVALID_DATA ); } height = depth = 1; break; case D3D11_RESOURCE_DIMENSION_TEXTURE2D: if (d3d10ext->miscFlag & D3D11_RESOURCE_MISC_TEXTURECUBE) { arraySize *= 6; isCubeMap = true; } depth = 1; break; case D3D11_RESOURCE_DIMENSION_TEXTURE3D: if (!(header->flags & DDS_HEADER_FLAGS_VOLUME)) { return HRESULT_FROM_WIN32( ERROR_INVALID_DATA ); } if (arraySize > 1) { return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); } break; default: return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); } resDim = d3d10ext->resourceDimension; } else { format = GetDXGIFormat( header->ddspf ); if (format == DXGI_FORMAT_UNKNOWN) { return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); } if (header->flags & DDS_HEADER_FLAGS_VOLUME) { resDim = D3D11_RESOURCE_DIMENSION_TEXTURE3D; } else { if (header->caps2 & DDS_CUBEMAP) { // We require all six faces to be defined if ((header->caps2 & DDS_CUBEMAP_ALLFACES ) != DDS_CUBEMAP_ALLFACES) { return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); } arraySize = 6; isCubeMap = true; } depth = 1; resDim = D3D11_RESOURCE_DIMENSION_TEXTURE2D; // Note there's no way for a legacy Direct3D 9 DDS to express a '1D' texture } assert( BitsPerPixel( format ) != 0 ); } // Bound sizes (for security purposes we don't trust DDS file metadata larger than the D3D 11.x hardware requirements) if (mipCount > D3D11_REQ_MIP_LEVELS) { return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); } switch ( resDim ) { case D3D11_RESOURCE_DIMENSION_TEXTURE1D: if ((arraySize > D3D11_REQ_TEXTURE1D_ARRAY_AXIS_DIMENSION) || (width > D3D11_REQ_TEXTURE1D_U_DIMENSION) ) { return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); } break; case D3D11_RESOURCE_DIMENSION_TEXTURE2D: if ( isCubeMap ) { // This is the right bound because we set arraySize to (NumCubes*6) above if ((arraySize > D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION) || (width > D3D11_REQ_TEXTURECUBE_DIMENSION) || (height > D3D11_REQ_TEXTURECUBE_DIMENSION)) { return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); } } else if ((arraySize > D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION) || (width > D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION) || (height > D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION)) { return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); } break; case D3D11_RESOURCE_DIMENSION_TEXTURE3D: if ((arraySize > 1) || (width > D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION) || (height > D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION) || (depth > D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION) ) { return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); } break; default: return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); } bool autogen = false; if ( mipCount == 1 && d3dContext != 0 && textureView != 0 ) // Must have context and shader-view to auto generate mipmaps { // See if format is supported for auto-gen mipmaps (varies by feature level) UINT fmtSupport = 0; hr = d3dDevice->CheckFormatSupport( format, &fmtSupport ); if ( SUCCEEDED(hr) && ( fmtSupport & D3D11_FORMAT_SUPPORT_MIP_AUTOGEN ) ) { // 10level9 feature levels do not support auto-gen mipgen for volume textures if ( ( resDim != D3D11_RESOURCE_DIMENSION_TEXTURE3D ) || ( d3dDevice->GetFeatureLevel() >= D3D_FEATURE_LEVEL_10_0 ) ) { autogen = true; } } } if ( autogen ) { // Create texture with auto-generated mipmaps ID3D11Resource* tex = nullptr; hr = CreateD3DResources( d3dDevice, resDim, width, height, depth, 0, arraySize, format, usage, bindFlags | D3D11_BIND_RENDER_TARGET, cpuAccessFlags, miscFlags | D3D11_RESOURCE_MISC_GENERATE_MIPS, forceSRGB, isCubeMap, nullptr, &tex, textureView ); if ( SUCCEEDED(hr) ) { size_t numBytes = 0; size_t rowBytes = 0; GetSurfaceInfo( width, height, format, &numBytes, &rowBytes, nullptr ); if ( numBytes > bitSize ) { (*textureView)->Release(); *textureView = nullptr; tex->Release(); return HRESULT_FROM_WIN32( ERROR_HANDLE_EOF ); } D3D11_SHADER_RESOURCE_VIEW_DESC desc; (*textureView)->GetDesc( &desc ); UINT mipLevels = 1; switch( desc.ViewDimension ) { case D3D_SRV_DIMENSION_TEXTURE1D: mipLevels = desc.Texture1D.MipLevels; break; case D3D_SRV_DIMENSION_TEXTURE1DARRAY: mipLevels = desc.Texture1DArray.MipLevels; break; case D3D_SRV_DIMENSION_TEXTURE2D: mipLevels = desc.Texture2D.MipLevels; break; case D3D_SRV_DIMENSION_TEXTURE2DARRAY: mipLevels = desc.Texture2DArray.MipLevels; break; case D3D_SRV_DIMENSION_TEXTURECUBE: mipLevels = desc.TextureCube.MipLevels; break; case D3D_SRV_DIMENSION_TEXTURECUBEARRAY:mipLevels = desc.TextureCubeArray.MipLevels; break; case D3D_SRV_DIMENSION_TEXTURE3D: mipLevels = desc.Texture3D.MipLevels; break; default: (*textureView)->Release(); *textureView = nullptr; tex->Release(); return E_UNEXPECTED; } if ( arraySize > 1 ) { const uint8_t* pSrcBits = bitData; const uint8_t* pEndBits = bitData + bitSize; for( UINT item = 0; item < arraySize; ++item ) { if ( (pSrcBits + numBytes) > pEndBits ) { (*textureView)->Release(); *textureView = nullptr; tex->Release(); return HRESULT_FROM_WIN32( ERROR_HANDLE_EOF ); } UINT res = D3D11CalcSubresource( 0, item, mipLevels ); d3dContext->UpdateSubresource( tex, res, nullptr, pSrcBits, static_cast(rowBytes), static_cast(numBytes) ); pSrcBits += numBytes; } } else { d3dContext->UpdateSubresource( tex, 0, nullptr, bitData, static_cast(rowBytes), static_cast(numBytes) ); } d3dContext->GenerateMips( *textureView ); if ( texture ) { *texture = tex; } else { tex->Release(); } } } else { // Create the texture std::unique_ptr initData( new (std::nothrow) D3D11_SUBRESOURCE_DATA[ mipCount * arraySize ] ); if ( !initData ) { return E_OUTOFMEMORY; } size_t skipMip = 0; size_t twidth = 0; size_t theight = 0; size_t tdepth = 0; hr = FillInitData( width, height, depth, mipCount, arraySize, format, maxsize, bitSize, bitData, twidth, theight, tdepth, skipMip, initData.get() ); if ( SUCCEEDED(hr) ) { hr = CreateD3DResources( d3dDevice, resDim, twidth, theight, tdepth, mipCount - skipMip, arraySize, format, usage, bindFlags, cpuAccessFlags, miscFlags, forceSRGB, isCubeMap, initData.get(), texture, textureView ); if ( FAILED(hr) && !maxsize && (mipCount > 1) ) { // Retry with a maxsize determined by feature level switch( d3dDevice->GetFeatureLevel() ) { case D3D_FEATURE_LEVEL_9_1: case D3D_FEATURE_LEVEL_9_2: if ( isCubeMap ) { maxsize = 512 /*D3D_FL9_1_REQ_TEXTURECUBE_DIMENSION*/; } else { maxsize = (resDim == D3D11_RESOURCE_DIMENSION_TEXTURE3D) ? 256 /*D3D_FL9_1_REQ_TEXTURE3D_U_V_OR_W_DIMENSION*/ : 2048 /*D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION*/; } break; case D3D_FEATURE_LEVEL_9_3: maxsize = (resDim == D3D11_RESOURCE_DIMENSION_TEXTURE3D) ? 256 /*D3D_FL9_1_REQ_TEXTURE3D_U_V_OR_W_DIMENSION*/ : 4096 /*D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION*/; break; default: // D3D_FEATURE_LEVEL_10_0 & D3D_FEATURE_LEVEL_10_1 maxsize = (resDim == D3D11_RESOURCE_DIMENSION_TEXTURE3D) ? 2048 /*D3D10_REQ_TEXTURE3D_U_V_OR_W_DIMENSION*/ : 8192 /*D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION*/; break; } hr = FillInitData( width, height, depth, mipCount, arraySize, format, maxsize, bitSize, bitData, twidth, theight, tdepth, skipMip, initData.get() ); if ( SUCCEEDED(hr) ) { hr = CreateD3DResources( d3dDevice, resDim, twidth, theight, tdepth, mipCount - skipMip, arraySize, format, usage, bindFlags, cpuAccessFlags, miscFlags, forceSRGB, isCubeMap, initData.get(), texture, textureView ); } } } } return hr; } //-------------------------------------------------------------------------------------- static DDS_ALPHA_MODE GetAlphaMode( _In_ const DDS_HEADER* header ) { if ( header->ddspf.flags & DDS_FOURCC ) { if ( MAKEFOURCC( 'D', 'X', '1', '0' ) == header->ddspf.fourCC ) { auto d3d10ext = reinterpret_cast( (const char*)header + sizeof(DDS_HEADER) ); auto mode = static_cast( d3d10ext->miscFlags2 & DDS_MISC_FLAGS2_ALPHA_MODE_MASK ); switch( mode ) { case DDS_ALPHA_MODE_STRAIGHT: case DDS_ALPHA_MODE_PREMULTIPLIED: case DDS_ALPHA_MODE_OPAQUE: case DDS_ALPHA_MODE_CUSTOM: return mode; } } else if ( ( MAKEFOURCC( 'D', 'X', 'T', '2' ) == header->ddspf.fourCC ) || ( MAKEFOURCC( 'D', 'X', 'T', '4' ) == header->ddspf.fourCC ) ) { return DDS_ALPHA_MODE_PREMULTIPLIED; } } return DDS_ALPHA_MODE_UNKNOWN; } //-------------------------------------------------------------------------------------- _Use_decl_annotations_ HRESULT DirectX::CreateDDSTextureFromMemory( ID3D11Device* d3dDevice, const uint8_t* ddsData, size_t ddsDataSize, ID3D11Resource** texture, ID3D11ShaderResourceView** textureView, size_t maxsize, DDS_ALPHA_MODE* alphaMode ) { return CreateDDSTextureFromMemoryEx( d3dDevice, nullptr, ddsData, ddsDataSize, maxsize, D3D11_USAGE_DEFAULT, D3D11_BIND_SHADER_RESOURCE, 0, 0, false, texture, textureView, alphaMode ); } _Use_decl_annotations_ HRESULT DirectX::CreateDDSTextureFromMemory( ID3D11Device* d3dDevice, ID3D11DeviceContext* d3dContext, const uint8_t* ddsData, size_t ddsDataSize, ID3D11Resource** texture, ID3D11ShaderResourceView** textureView, size_t maxsize, DDS_ALPHA_MODE* alphaMode ) { return CreateDDSTextureFromMemoryEx( d3dDevice, d3dContext, ddsData, ddsDataSize, maxsize, D3D11_USAGE_DEFAULT, D3D11_BIND_SHADER_RESOURCE, 0, 0, false, texture, textureView, alphaMode ); } _Use_decl_annotations_ HRESULT DirectX::CreateDDSTextureFromMemoryEx( ID3D11Device* d3dDevice, const uint8_t* ddsData, size_t ddsDataSize, size_t maxsize, D3D11_USAGE usage, unsigned int bindFlags, unsigned int cpuAccessFlags, unsigned int miscFlags, bool forceSRGB, ID3D11Resource** texture, ID3D11ShaderResourceView** textureView, DDS_ALPHA_MODE* alphaMode ) { return CreateDDSTextureFromMemoryEx( d3dDevice, nullptr, ddsData, ddsDataSize, maxsize, usage, bindFlags, cpuAccessFlags, miscFlags, forceSRGB, texture, textureView, alphaMode ); } _Use_decl_annotations_ HRESULT DirectX::CreateDDSTextureFromMemoryEx( ID3D11Device* d3dDevice, ID3D11DeviceContext* d3dContext, const uint8_t* ddsData, size_t ddsDataSize, size_t maxsize, D3D11_USAGE usage, unsigned int bindFlags, unsigned int cpuAccessFlags, unsigned int miscFlags, bool forceSRGB, ID3D11Resource** texture, ID3D11ShaderResourceView** textureView, DDS_ALPHA_MODE* alphaMode ) { if ( texture ) { *texture = nullptr; } if ( textureView ) { *textureView = nullptr; } if ( alphaMode ) { *alphaMode = DDS_ALPHA_MODE_UNKNOWN; } if (!d3dDevice || !ddsData || (!texture && !textureView)) { return E_INVALIDARG; } // Validate DDS file in memory if (ddsDataSize < (sizeof(uint32_t) + sizeof(DDS_HEADER))) { return E_FAIL; } uint32_t dwMagicNumber = *( const uint32_t* )( ddsData ); if (dwMagicNumber != DDS_MAGIC) { return E_FAIL; } auto header = reinterpret_cast( ddsData + sizeof( uint32_t ) ); // Verify header to validate DDS file if (header->size != sizeof(DDS_HEADER) || header->ddspf.size != sizeof(DDS_PIXELFORMAT)) { return E_FAIL; } // Check for DX10 extension bool bDXT10Header = false; if ((header->ddspf.flags & DDS_FOURCC) && (MAKEFOURCC( 'D', 'X', '1', '0' ) == header->ddspf.fourCC) ) { // Must be long enough for both headers and magic value if (ddsDataSize < (sizeof(DDS_HEADER) + sizeof(uint32_t) + sizeof(DDS_HEADER_DXT10))) { return E_FAIL; } bDXT10Header = true; } ptrdiff_t offset = sizeof( uint32_t ) + sizeof( DDS_HEADER ) + (bDXT10Header ? sizeof( DDS_HEADER_DXT10 ) : 0); HRESULT hr = CreateTextureFromDDS( d3dDevice, d3dContext, header, ddsData + offset, ddsDataSize - offset, maxsize, usage, bindFlags, cpuAccessFlags, miscFlags, forceSRGB, texture, textureView ); if ( SUCCEEDED(hr) ) { if (texture != 0 && *texture != 0) { SetDebugObjectName(*texture, "DDSTextureLoader"); } if (textureView != 0 && *textureView != 0) { SetDebugObjectName(*textureView, "DDSTextureLoader"); } if ( alphaMode ) *alphaMode = GetAlphaMode( header ); } return hr; } //-------------------------------------------------------------------------------------- _Use_decl_annotations_ HRESULT DirectX::CreateDDSTextureFromFile( ID3D11Device* d3dDevice, const wchar_t* fileName, ID3D11Resource** texture, ID3D11ShaderResourceView** textureView, size_t maxsize, DDS_ALPHA_MODE* alphaMode ) { return CreateDDSTextureFromFileEx( d3dDevice, nullptr, fileName, maxsize, D3D11_USAGE_DEFAULT, D3D11_BIND_SHADER_RESOURCE, 0, 0, false, texture, textureView, alphaMode ); } _Use_decl_annotations_ HRESULT DirectX::CreateDDSTextureFromFile( ID3D11Device* d3dDevice, ID3D11DeviceContext* d3dContext, const wchar_t* fileName, ID3D11Resource** texture, ID3D11ShaderResourceView** textureView, size_t maxsize, DDS_ALPHA_MODE* alphaMode ) { return CreateDDSTextureFromFileEx( d3dDevice, d3dContext, fileName, maxsize, D3D11_USAGE_DEFAULT, D3D11_BIND_SHADER_RESOURCE, 0, 0, false, texture, textureView, alphaMode ); } _Use_decl_annotations_ HRESULT DirectX::CreateDDSTextureFromFileEx( ID3D11Device* d3dDevice, const wchar_t* fileName, size_t maxsize, D3D11_USAGE usage, unsigned int bindFlags, unsigned int cpuAccessFlags, unsigned int miscFlags, bool forceSRGB, ID3D11Resource** texture, ID3D11ShaderResourceView** textureView, DDS_ALPHA_MODE* alphaMode ) { return CreateDDSTextureFromFileEx( d3dDevice, nullptr, fileName, maxsize, usage, bindFlags, cpuAccessFlags, miscFlags, forceSRGB, texture, textureView, alphaMode ); } _Use_decl_annotations_ HRESULT DirectX::CreateDDSTextureFromFileEx( ID3D11Device* d3dDevice, ID3D11DeviceContext* d3dContext, const wchar_t* fileName, size_t maxsize, D3D11_USAGE usage, unsigned int bindFlags, unsigned int cpuAccessFlags, unsigned int miscFlags, bool forceSRGB, ID3D11Resource** texture, ID3D11ShaderResourceView** textureView, DDS_ALPHA_MODE* alphaMode ) { if ( texture ) { *texture = nullptr; } if ( textureView ) { *textureView = nullptr; } if ( alphaMode ) { *alphaMode = DDS_ALPHA_MODE_UNKNOWN; } if (!d3dDevice || !fileName || (!texture && !textureView)) { return E_INVALIDARG; } DDS_HEADER* header = nullptr; uint8_t* bitData = nullptr; size_t bitSize = 0; std::unique_ptr ddsData; HRESULT hr = LoadTextureDataFromFile( fileName, ddsData, &header, &bitData, &bitSize ); if (FAILED(hr)) { return hr; } hr = CreateTextureFromDDS( d3dDevice, d3dContext, header, bitData, bitSize, maxsize, usage, bindFlags, cpuAccessFlags, miscFlags, forceSRGB, texture, textureView ); if ( SUCCEEDED(hr) ) { #if !defined(NO_D3D11_DEBUG_NAME) && ( defined(_DEBUG) || defined(PROFILE) ) if (texture != 0 || textureView != 0) { CHAR strFileA[MAX_PATH]; int result = WideCharToMultiByte( CP_ACP, WC_NO_BEST_FIT_CHARS, fileName, -1, strFileA, MAX_PATH, nullptr, FALSE ); if ( result > 0 ) { const CHAR* pstrName = strrchr( strFileA, '\\' ); if (!pstrName) { pstrName = strFileA; } else { pstrName++; } if (texture != 0 && *texture != 0) { (*texture)->SetPrivateData( WKPDID_D3DDebugObjectName, static_cast( strnlen_s(pstrName, MAX_PATH) ), pstrName ); } if (textureView != 0 && *textureView != 0 ) { (*textureView)->SetPrivateData( WKPDID_D3DDebugObjectName, static_cast( strnlen_s(pstrName, MAX_PATH) ), pstrName ); } } } #endif if ( alphaMode ) *alphaMode = GetAlphaMode( header ); } return hr; } ================================================ FILE: 3rdParty/DirectXTex/DDSTextureLoader/DDSTextureLoader.h ================================================ //-------------------------------------------------------------------------------------- // File: DDSTextureLoader.h // // Functions for loading a DDS texture and creating a Direct3D 11 runtime resource for it // // Note these functions are useful as a light-weight runtime loader for DDS files. For // a full-featured DDS file reader, writer, and texture processing pipeline see // the 'Texconv' sample and the 'DirectXTex' library. // // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A // PARTICULAR PURPOSE. // // Copyright (c) Microsoft Corporation. All rights reserved. // // http://go.microsoft.com/fwlink/?LinkId=248926 // http://go.microsoft.com/fwlink/?LinkId=248929 //-------------------------------------------------------------------------------------- #ifdef _MSC_VER #pragma once #endif #include #pragma warning(push) #pragma warning(disable : 4005) #include #pragma warning(pop) #if defined(_MSC_VER) && (_MSC_VER<1610) && !defined(_In_reads_) #define _In_reads_(exp) #define _Out_writes_(exp) #define _In_reads_bytes_(exp) #define _In_reads_opt_(exp) #define _Outptr_opt_ #endif #ifndef _Use_decl_annotations_ #define _Use_decl_annotations_ #endif namespace DirectX { enum DDS_ALPHA_MODE { DDS_ALPHA_MODE_UNKNOWN = 0, DDS_ALPHA_MODE_STRAIGHT = 1, DDS_ALPHA_MODE_PREMULTIPLIED = 2, DDS_ALPHA_MODE_OPAQUE = 3, DDS_ALPHA_MODE_CUSTOM = 4, }; // Standard version HRESULT CreateDDSTextureFromMemory( _In_ ID3D11Device* d3dDevice, _In_reads_bytes_(ddsDataSize) const uint8_t* ddsData, _In_ size_t ddsDataSize, _Outptr_opt_ ID3D11Resource** texture, _Outptr_opt_ ID3D11ShaderResourceView** textureView, _In_ size_t maxsize = 0, _Out_opt_ DDS_ALPHA_MODE* alphaMode = nullptr ); HRESULT CreateDDSTextureFromFile( _In_ ID3D11Device* d3dDevice, _In_z_ const wchar_t* szFileName, _Outptr_opt_ ID3D11Resource** texture, _Outptr_opt_ ID3D11ShaderResourceView** textureView, _In_ size_t maxsize = 0, _Out_opt_ DDS_ALPHA_MODE* alphaMode = nullptr ); // Standard version with optional auto-gen mipmap support HRESULT CreateDDSTextureFromMemory( _In_ ID3D11Device* d3dDevice, _In_opt_ ID3D11DeviceContext* d3dContext, _In_reads_bytes_(ddsDataSize) const uint8_t* ddsData, _In_ size_t ddsDataSize, _Outptr_opt_ ID3D11Resource** texture, _Outptr_opt_ ID3D11ShaderResourceView** textureView, _In_ size_t maxsize = 0, _Out_opt_ DDS_ALPHA_MODE* alphaMode = nullptr ); HRESULT CreateDDSTextureFromFile( _In_ ID3D11Device* d3dDevice, _In_opt_ ID3D11DeviceContext* d3dContext, _In_z_ const wchar_t* szFileName, _Outptr_opt_ ID3D11Resource** texture, _Outptr_opt_ ID3D11ShaderResourceView** textureView, _In_ size_t maxsize = 0, _Out_opt_ DDS_ALPHA_MODE* alphaMode = nullptr ); // Extended version HRESULT CreateDDSTextureFromMemoryEx( _In_ ID3D11Device* d3dDevice, _In_reads_bytes_(ddsDataSize) const uint8_t* ddsData, _In_ size_t ddsDataSize, _In_ size_t maxsize, _In_ D3D11_USAGE usage, _In_ unsigned int bindFlags, _In_ unsigned int cpuAccessFlags, _In_ unsigned int miscFlags, _In_ bool forceSRGB, _Outptr_opt_ ID3D11Resource** texture, _Outptr_opt_ ID3D11ShaderResourceView** textureView, _Out_opt_ DDS_ALPHA_MODE* alphaMode = nullptr ); HRESULT CreateDDSTextureFromFileEx( _In_ ID3D11Device* d3dDevice, _In_z_ const wchar_t* szFileName, _In_ size_t maxsize, _In_ D3D11_USAGE usage, _In_ unsigned int bindFlags, _In_ unsigned int cpuAccessFlags, _In_ unsigned int miscFlags, _In_ bool forceSRGB, _Outptr_opt_ ID3D11Resource** texture, _Outptr_opt_ ID3D11ShaderResourceView** textureView, _Out_opt_ DDS_ALPHA_MODE* alphaMode = nullptr ); // Extended version with optional auto-gen mipmap support HRESULT CreateDDSTextureFromMemoryEx( _In_ ID3D11Device* d3dDevice, _In_opt_ ID3D11DeviceContext* d3dContext, _In_reads_bytes_(ddsDataSize) const uint8_t* ddsData, _In_ size_t ddsDataSize, _In_ size_t maxsize, _In_ D3D11_USAGE usage, _In_ unsigned int bindFlags, _In_ unsigned int cpuAccessFlags, _In_ unsigned int miscFlags, _In_ bool forceSRGB, _Outptr_opt_ ID3D11Resource** texture, _Outptr_opt_ ID3D11ShaderResourceView** textureView, _Out_opt_ DDS_ALPHA_MODE* alphaMode = nullptr ); HRESULT CreateDDSTextureFromFileEx( _In_ ID3D11Device* d3dDevice, _In_opt_ ID3D11DeviceContext* d3dContext, _In_z_ const wchar_t* szFileName, _In_ size_t maxsize, _In_ D3D11_USAGE usage, _In_ unsigned int bindFlags, _In_ unsigned int cpuAccessFlags, _In_ unsigned int miscFlags, _In_ bool forceSRGB, _Outptr_opt_ ID3D11Resource** texture, _Outptr_opt_ ID3D11ShaderResourceView** textureView, _Out_opt_ DDS_ALPHA_MODE* alphaMode = nullptr ); } ================================================ FILE: 3rdParty/DirectXTex/DDSView/DDSView.rc ================================================ // Microsoft Visual C++ generated resource script. // #define APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 2 resource. // #define IDC_STATIC -1 #define IDI_MAIN_ICON 100 #include ///////////////////////////////////////////////////////////////////////////// #undef APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // English (U.S.) resources #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) #ifdef _WIN32 LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US #pragma code_page(1252) #endif //_WIN32 ///////////////////////////////////////////////////////////////////////////// // // Icon // // Icon with lowest ID value placed first to ensure application icon // remains consistent on all systems. IDI_MAIN_ICON ICON "directx.ico" #ifdef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // TEXTINCLUDE // 1 TEXTINCLUDE BEGIN "resource.h\0" END 2 TEXTINCLUDE BEGIN "#define IDC_STATIC -1\r\n" "#include \r\n" "\r\n" "\r\n" "\0" END 3 TEXTINCLUDE BEGIN "\r\n" "\0" END #endif // APSTUDIO_INVOKED #endif // English (U.S.) resources ///////////////////////////////////////////////////////////////////////////// #ifndef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 3 resource. // ///////////////////////////////////////////////////////////////////////////// #endif // not APSTUDIO_INVOKED ================================================ FILE: 3rdParty/DirectXTex/DDSView/DDSView_Desktop_2012.sln ================================================ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 2012 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DDSView", "DDSView_Desktop_2012.vcxproj", "{9D3EDCAD-A800-43F0-B77F-FE6E4DFA3D84}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DirectXTex", "..\DirectXTex\DirectXTex_Desktop_2012.vcxproj", "{371B9FA9-4C90-4AC6-A123-ACED756D6C77}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Debug|x64 = Debug|x64 Profile|Win32 = Profile|Win32 Profile|x64 = Profile|x64 Release|Win32 = Release|Win32 Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {9D3EDCAD-A800-43F0-B77F-FE6E4DFA3D84}.Debug|Win32.ActiveCfg = Debug|Win32 {9D3EDCAD-A800-43F0-B77F-FE6E4DFA3D84}.Debug|Win32.Build.0 = Debug|Win32 {9D3EDCAD-A800-43F0-B77F-FE6E4DFA3D84}.Debug|x64.ActiveCfg = Debug|x64 {9D3EDCAD-A800-43F0-B77F-FE6E4DFA3D84}.Debug|x64.Build.0 = Debug|x64 {9D3EDCAD-A800-43F0-B77F-FE6E4DFA3D84}.Profile|Win32.ActiveCfg = Profile|Win32 {9D3EDCAD-A800-43F0-B77F-FE6E4DFA3D84}.Profile|Win32.Build.0 = Profile|Win32 {9D3EDCAD-A800-43F0-B77F-FE6E4DFA3D84}.Profile|x64.ActiveCfg = Profile|x64 {9D3EDCAD-A800-43F0-B77F-FE6E4DFA3D84}.Profile|x64.Build.0 = Profile|x64 {9D3EDCAD-A800-43F0-B77F-FE6E4DFA3D84}.Release|Win32.ActiveCfg = Release|Win32 {9D3EDCAD-A800-43F0-B77F-FE6E4DFA3D84}.Release|Win32.Build.0 = Release|Win32 {9D3EDCAD-A800-43F0-B77F-FE6E4DFA3D84}.Release|x64.ActiveCfg = Release|x64 {9D3EDCAD-A800-43F0-B77F-FE6E4DFA3D84}.Release|x64.Build.0 = Release|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Debug|Win32.ActiveCfg = Debug|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Debug|Win32.Build.0 = Debug|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Debug|x64.ActiveCfg = Debug|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Debug|x64.Build.0 = Debug|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Profile|Win32.ActiveCfg = Profile|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Profile|Win32.Build.0 = Profile|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Profile|x64.ActiveCfg = Profile|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Profile|x64.Build.0 = Profile|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Release|Win32.ActiveCfg = Release|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Release|Win32.Build.0 = Release|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Release|x64.ActiveCfg = Release|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal ================================================ FILE: 3rdParty/DirectXTex/DDSView/DDSView_Desktop_2012.vcxproj ================================================  Debug Win32 Debug x64 Profile Win32 Profile x64 Release Win32 Release x64 DDSView {9D3EDCAD-A800-43F0-B77F-FE6E4DFA3D84} DDSView Win32Proj $(VCTargetsPath11) Application Unicode v110 Application Unicode v110 Application true Unicode v110 Application true Unicode v110 Application true Unicode v110 Application true Unicode v110 true true $(ExecutablePath) $(IncludePath) $(LibraryPath) true true $(ExecutablePath) $(IncludePath) $(LibraryPath) false true $(ExecutablePath) $(IncludePath) $(LibraryPath) false true $(ExecutablePath) $(IncludePath) $(LibraryPath) false true $(ExecutablePath) $(IncludePath) $(LibraryPath) false true $(ExecutablePath) $(IncludePath) $(LibraryPath) Level4 Disabled MultiThreadedDebugDLL false true Fast StreamingSIMDExtensions2 Sync ..\DirectXTex;%(AdditionalIncludeDirectories) %(AdditionalOptions) WIN32;_DEBUG;DEBUG;PROFILE;_WINDOWS;D3DXFX_LARGEADDRESS_HANDLE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions) EditAndContinue EnableFastChecks %(AdditionalOptions) d3d11.lib;ole32.lib;windowscodecs.lib;uuid.lib;%(AdditionalDependencies) Windows true true true true MachineX86 AsInvoker %(DelayLoadDLLs) false Level4 Disabled MultiThreadedDebugDLL false true Fast Sync ..\DirectXTex;%(AdditionalIncludeDirectories) %(AdditionalOptions) WIN32;_DEBUG;DEBUG;PROFILE;_WINDOWS;D3DXFX_LARGEADDRESS_HANDLE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions) EnableFastChecks %(AdditionalOptions) d3d11.lib;ole32.lib;windowscodecs.lib;uuid.lib;%(AdditionalDependencies) Windows true true true true MachineX64 AsInvoker %(DelayLoadDLLs) false Level4 MaxSpeed MultiThreadedDLL false true true Fast StreamingSIMDExtensions2 Sync ..\DirectXTex;%(AdditionalIncludeDirectories) %(AdditionalOptions) WIN32;NDEBUG;_WINDOWS;D3DXFX_LARGEADDRESS_HANDLE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions) %(AdditionalOptions) d3d11.lib;ole32.lib;windowscodecs.lib;uuid.lib;%(AdditionalDependencies) true Windows true true true true true MachineX86 AsInvoker %(DelayLoadDLLs) false Level4 MaxSpeed MultiThreadedDLL false true true Fast Sync ..\DirectXTex;%(AdditionalIncludeDirectories) %(AdditionalOptions) WIN32;NDEBUG;_WINDOWS;D3DXFX_LARGEADDRESS_HANDLE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions) %(AdditionalOptions) d3d11.lib;ole32.lib;windowscodecs.lib;uuid.lib;%(AdditionalDependencies) true Windows true true true true true MachineX64 AsInvoker %(DelayLoadDLLs) false Level4 MaxSpeed MultiThreadedDLL false true true Fast StreamingSIMDExtensions2 Sync ..\DirectXTex;%(AdditionalIncludeDirectories) %(AdditionalOptions) WIN32;NDEBUG;PROFILE;_WINDOWS;D3DXFX_LARGEADDRESS_HANDLE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions) %(AdditionalOptions) d3d11.lib;ole32.lib;windowscodecs.lib;uuid.lib;%(AdditionalDependencies) true Windows true true true true true MachineX86 AsInvoker %(DelayLoadDLLs) false Level4 MaxSpeed MultiThreadedDLL false true true Fast Sync ..\DirectXTex;%(AdditionalIncludeDirectories) %(AdditionalOptions) WIN32;NDEBUG;PROFILE;_WINDOWS;D3DXFX_LARGEADDRESS_HANDLE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions) %(AdditionalOptions) d3d11.lib;ole32.lib;windowscodecs.lib;uuid.lib;%(AdditionalDependencies) true Windows true true true true true MachineX64 AsInvoker %(DelayLoadDLLs) false {371b9fa9-4c90-4ac6-a123-aced756d6c77} ================================================ FILE: 3rdParty/DirectXTex/DDSView/DDSView_Desktop_2012.vcxproj.filters ================================================  {8e114980-c1a3-4ada-ad7c-83caadf5daeb} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe Resource Files ================================================ FILE: 3rdParty/DirectXTex/DDSView/DDSView_Desktop_2013.sln ================================================ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 2013 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DDSView", "DDSView_Desktop_2013.vcxproj", "{9D3EDCAD-A800-43F0-B77F-FE6E4DFA3D84}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DirectXTex", "..\DirectXTex\DirectXTex_Desktop_2013.vcxproj", "{371B9FA9-4C90-4AC6-A123-ACED756D6C77}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Debug|x64 = Debug|x64 Profile|Win32 = Profile|Win32 Profile|x64 = Profile|x64 Release|Win32 = Release|Win32 Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {9D3EDCAD-A800-43F0-B77F-FE6E4DFA3D84}.Debug|Win32.ActiveCfg = Debug|Win32 {9D3EDCAD-A800-43F0-B77F-FE6E4DFA3D84}.Debug|Win32.Build.0 = Debug|Win32 {9D3EDCAD-A800-43F0-B77F-FE6E4DFA3D84}.Debug|x64.ActiveCfg = Debug|x64 {9D3EDCAD-A800-43F0-B77F-FE6E4DFA3D84}.Debug|x64.Build.0 = Debug|x64 {9D3EDCAD-A800-43F0-B77F-FE6E4DFA3D84}.Profile|Win32.ActiveCfg = Profile|Win32 {9D3EDCAD-A800-43F0-B77F-FE6E4DFA3D84}.Profile|Win32.Build.0 = Profile|Win32 {9D3EDCAD-A800-43F0-B77F-FE6E4DFA3D84}.Profile|x64.ActiveCfg = Profile|x64 {9D3EDCAD-A800-43F0-B77F-FE6E4DFA3D84}.Profile|x64.Build.0 = Profile|x64 {9D3EDCAD-A800-43F0-B77F-FE6E4DFA3D84}.Release|Win32.ActiveCfg = Release|Win32 {9D3EDCAD-A800-43F0-B77F-FE6E4DFA3D84}.Release|Win32.Build.0 = Release|Win32 {9D3EDCAD-A800-43F0-B77F-FE6E4DFA3D84}.Release|x64.ActiveCfg = Release|x64 {9D3EDCAD-A800-43F0-B77F-FE6E4DFA3D84}.Release|x64.Build.0 = Release|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Debug|Win32.ActiveCfg = Debug|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Debug|Win32.Build.0 = Debug|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Debug|x64.ActiveCfg = Debug|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Debug|x64.Build.0 = Debug|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Profile|Win32.ActiveCfg = Profile|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Profile|Win32.Build.0 = Profile|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Profile|x64.ActiveCfg = Profile|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Profile|x64.Build.0 = Profile|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Release|Win32.ActiveCfg = Release|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Release|Win32.Build.0 = Release|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Release|x64.ActiveCfg = Release|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal ================================================ FILE: 3rdParty/DirectXTex/DDSView/DDSView_Desktop_2013.vcxproj ================================================  Debug Win32 Debug x64 Profile Win32 Profile x64 Release Win32 Release x64 DDSView {9D3EDCAD-A800-43F0-B77F-FE6E4DFA3D84} DDSView Win32Proj $(VCTargetsPath11) Application Unicode v120 Application Unicode v120 Application true Unicode v120 Application true Unicode v120 Application true Unicode v120 Application true Unicode v120 true true $(ExecutablePath) $(IncludePath) $(LibraryPath) true true $(ExecutablePath) $(IncludePath) $(LibraryPath) false true $(ExecutablePath) $(IncludePath) $(LibraryPath) false true $(ExecutablePath) $(IncludePath) $(LibraryPath) false true $(ExecutablePath) $(IncludePath) $(LibraryPath) false true $(ExecutablePath) $(IncludePath) $(LibraryPath) Level4 Disabled MultiThreadedDebugDLL false true Fast StreamingSIMDExtensions2 Sync ..\DirectXTex;%(AdditionalIncludeDirectories) %(AdditionalOptions) WIN32;_DEBUG;DEBUG;PROFILE;_WINDOWS;D3DXFX_LARGEADDRESS_HANDLE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions) EditAndContinue EnableFastChecks %(AdditionalOptions) d3d11.lib;ole32.lib;windowscodecs.lib;uuid.lib;%(AdditionalDependencies) Windows true true true true MachineX86 AsInvoker %(DelayLoadDLLs) false Level4 Disabled MultiThreadedDebugDLL false true Fast Sync ..\DirectXTex;%(AdditionalIncludeDirectories) %(AdditionalOptions) WIN32;_DEBUG;DEBUG;PROFILE;_WINDOWS;D3DXFX_LARGEADDRESS_HANDLE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions) EnableFastChecks %(AdditionalOptions) d3d11.lib;ole32.lib;windowscodecs.lib;uuid.lib;%(AdditionalDependencies) Windows true true true true MachineX64 AsInvoker %(DelayLoadDLLs) false Level4 MaxSpeed MultiThreadedDLL false true true Fast StreamingSIMDExtensions2 Sync ..\DirectXTex;%(AdditionalIncludeDirectories) %(AdditionalOptions) WIN32;NDEBUG;_WINDOWS;D3DXFX_LARGEADDRESS_HANDLE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions) %(AdditionalOptions) d3d11.lib;ole32.lib;windowscodecs.lib;uuid.lib;%(AdditionalDependencies) true Windows true true true true true MachineX86 AsInvoker %(DelayLoadDLLs) false Level4 MaxSpeed MultiThreadedDLL false true true Fast Sync ..\DirectXTex;%(AdditionalIncludeDirectories) %(AdditionalOptions) WIN32;NDEBUG;_WINDOWS;D3DXFX_LARGEADDRESS_HANDLE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions) %(AdditionalOptions) d3d11.lib;ole32.lib;windowscodecs.lib;uuid.lib;%(AdditionalDependencies) true Windows true true true true true MachineX64 AsInvoker %(DelayLoadDLLs) false Level4 MaxSpeed MultiThreadedDLL false true true Fast StreamingSIMDExtensions2 Sync ..\DirectXTex;%(AdditionalIncludeDirectories) %(AdditionalOptions) WIN32;NDEBUG;PROFILE;_WINDOWS;D3DXFX_LARGEADDRESS_HANDLE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions) %(AdditionalOptions) d3d11.lib;ole32.lib;windowscodecs.lib;uuid.lib;%(AdditionalDependencies) true Windows true true true true true MachineX86 AsInvoker %(DelayLoadDLLs) false Level4 MaxSpeed MultiThreadedDLL false true true Fast Sync ..\DirectXTex;%(AdditionalIncludeDirectories) %(AdditionalOptions) WIN32;NDEBUG;PROFILE;_WINDOWS;D3DXFX_LARGEADDRESS_HANDLE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions) %(AdditionalOptions) d3d11.lib;ole32.lib;windowscodecs.lib;uuid.lib;%(AdditionalDependencies) true Windows true true true true true MachineX64 AsInvoker %(DelayLoadDLLs) false {371b9fa9-4c90-4ac6-a123-aced756d6c77} ================================================ FILE: 3rdParty/DirectXTex/DDSView/DDSView_Desktop_2013.vcxproj.filters ================================================  {8e114980-c1a3-4ada-ad7c-83caadf5daeb} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe Resource Files ================================================ FILE: 3rdParty/DirectXTex/DDSView/DDSView_Desktop_2015.sln ================================================ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 2015 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DDSView", "DDSView_Desktop_2015.vcxproj", "{9D3EDCAD-A800-43F0-B77F-FE6E4DFA3D84}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DirectXTex", "..\DirectXTex\DirectXTex_Desktop_2015.vcxproj", "{371B9FA9-4C90-4AC6-A123-ACED756D6C77}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Debug|x64 = Debug|x64 Profile|Win32 = Profile|Win32 Profile|x64 = Profile|x64 Release|Win32 = Release|Win32 Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {9D3EDCAD-A800-43F0-B77F-FE6E4DFA3D84}.Debug|Win32.ActiveCfg = Debug|Win32 {9D3EDCAD-A800-43F0-B77F-FE6E4DFA3D84}.Debug|Win32.Build.0 = Debug|Win32 {9D3EDCAD-A800-43F0-B77F-FE6E4DFA3D84}.Debug|x64.ActiveCfg = Debug|x64 {9D3EDCAD-A800-43F0-B77F-FE6E4DFA3D84}.Debug|x64.Build.0 = Debug|x64 {9D3EDCAD-A800-43F0-B77F-FE6E4DFA3D84}.Profile|Win32.ActiveCfg = Profile|Win32 {9D3EDCAD-A800-43F0-B77F-FE6E4DFA3D84}.Profile|Win32.Build.0 = Profile|Win32 {9D3EDCAD-A800-43F0-B77F-FE6E4DFA3D84}.Profile|x64.ActiveCfg = Profile|x64 {9D3EDCAD-A800-43F0-B77F-FE6E4DFA3D84}.Profile|x64.Build.0 = Profile|x64 {9D3EDCAD-A800-43F0-B77F-FE6E4DFA3D84}.Release|Win32.ActiveCfg = Release|Win32 {9D3EDCAD-A800-43F0-B77F-FE6E4DFA3D84}.Release|Win32.Build.0 = Release|Win32 {9D3EDCAD-A800-43F0-B77F-FE6E4DFA3D84}.Release|x64.ActiveCfg = Release|x64 {9D3EDCAD-A800-43F0-B77F-FE6E4DFA3D84}.Release|x64.Build.0 = Release|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Debug|Win32.ActiveCfg = Debug|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Debug|Win32.Build.0 = Debug|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Debug|x64.ActiveCfg = Debug|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Debug|x64.Build.0 = Debug|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Profile|Win32.ActiveCfg = Profile|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Profile|Win32.Build.0 = Profile|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Profile|x64.ActiveCfg = Profile|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Profile|x64.Build.0 = Profile|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Release|Win32.ActiveCfg = Release|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Release|Win32.Build.0 = Release|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Release|x64.ActiveCfg = Release|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal ================================================ FILE: 3rdParty/DirectXTex/DDSView/DDSView_Desktop_2015.vcxproj ================================================  Debug Win32 Debug x64 Profile Win32 Profile x64 Release Win32 Release x64 DDSView {9D3EDCAD-A800-43F0-B77F-FE6E4DFA3D84} DDSView Win32Proj Application Unicode v140 Application Unicode v140 Application true Unicode v140 Application true Unicode v140 Application true Unicode v140 Application true Unicode v140 true true $(ExecutablePath) $(IncludePath) $(LibraryPath) true true $(ExecutablePath) $(IncludePath) $(LibraryPath) false true $(ExecutablePath) $(IncludePath) $(LibraryPath) false true $(ExecutablePath) $(IncludePath) $(LibraryPath) false true $(ExecutablePath) $(IncludePath) $(LibraryPath) false true $(ExecutablePath) $(IncludePath) $(LibraryPath) Level4 Disabled MultiThreadedDebugDLL false true Fast StreamingSIMDExtensions2 Sync ..\DirectXTex;%(AdditionalIncludeDirectories) %(AdditionalOptions) WIN32;_DEBUG;DEBUG;PROFILE;_WINDOWS;D3DXFX_LARGEADDRESS_HANDLE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions) EditAndContinue EnableFastChecks %(AdditionalOptions) d3d11.lib;ole32.lib;windowscodecs.lib;uuid.lib;%(AdditionalDependencies) Windows true true true true MachineX86 AsInvoker %(DelayLoadDLLs) false Level4 Disabled MultiThreadedDebugDLL false true Fast Sync ..\DirectXTex;%(AdditionalIncludeDirectories) %(AdditionalOptions) WIN32;_DEBUG;DEBUG;PROFILE;_WINDOWS;D3DXFX_LARGEADDRESS_HANDLE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions) EnableFastChecks %(AdditionalOptions) d3d11.lib;ole32.lib;windowscodecs.lib;uuid.lib;%(AdditionalDependencies) Windows true true true true MachineX64 AsInvoker %(DelayLoadDLLs) false Level4 MaxSpeed MultiThreadedDLL false true true Fast StreamingSIMDExtensions2 Sync ..\DirectXTex;%(AdditionalIncludeDirectories) %(AdditionalOptions) WIN32;NDEBUG;_WINDOWS;D3DXFX_LARGEADDRESS_HANDLE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions) %(AdditionalOptions) d3d11.lib;ole32.lib;windowscodecs.lib;uuid.lib;%(AdditionalDependencies) true Windows true true true true true MachineX86 AsInvoker %(DelayLoadDLLs) false Level4 MaxSpeed MultiThreadedDLL false true true Fast Sync ..\DirectXTex;%(AdditionalIncludeDirectories) %(AdditionalOptions) WIN32;NDEBUG;_WINDOWS;D3DXFX_LARGEADDRESS_HANDLE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions) %(AdditionalOptions) d3d11.lib;ole32.lib;windowscodecs.lib;uuid.lib;%(AdditionalDependencies) true Windows true true true true true MachineX64 AsInvoker %(DelayLoadDLLs) false Level4 MaxSpeed MultiThreadedDLL false true true Fast StreamingSIMDExtensions2 Sync ..\DirectXTex;%(AdditionalIncludeDirectories) %(AdditionalOptions) WIN32;NDEBUG;PROFILE;_WINDOWS;D3DXFX_LARGEADDRESS_HANDLE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions) %(AdditionalOptions) d3d11.lib;ole32.lib;windowscodecs.lib;uuid.lib;%(AdditionalDependencies) true Windows true true true true true MachineX86 AsInvoker %(DelayLoadDLLs) false Level4 MaxSpeed MultiThreadedDLL false true true Fast Sync ..\DirectXTex;%(AdditionalIncludeDirectories) %(AdditionalOptions) WIN32;NDEBUG;PROFILE;_WINDOWS;D3DXFX_LARGEADDRESS_HANDLE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions) %(AdditionalOptions) d3d11.lib;ole32.lib;windowscodecs.lib;uuid.lib;%(AdditionalDependencies) true Windows true true true true true MachineX64 AsInvoker %(DelayLoadDLLs) false {371b9fa9-4c90-4ac6-a123-aced756d6c77} ================================================ FILE: 3rdParty/DirectXTex/DDSView/DDSView_Desktop_2015.vcxproj.filters ================================================  {8e114980-c1a3-4ada-ad7c-83caadf5daeb} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe Resource Files ================================================ FILE: 3rdParty/DirectXTex/DDSView/ddsview.cpp ================================================ //-------------------------------------------------------------------------------------- // File: DDSView.cpp // // DirectX 11 DDS File Viewer // // Copyright (c) Microsoft Corporation. All rights reserved. //-------------------------------------------------------------------------------------- #include #include #include #include #include #include #include "DirectXTex.h" using namespace DirectX; //-------------------------------------------------------------------------------------- #define IDI_MAIN_ICON 100 //-------------------------------------------------------------------------------------- #pragma pack(push,1) struct SimpleVertex { XMFLOAT4 Pos; XMFLOAT4 Tex; }; struct CBArrayControl { float Index; float pad[3]; }; #pragma pack(pop) //-------------------------------------------------------------------------------------- // fxc ddsview.fx /nologo /EVS /Tvs_4_1 /Fhshaders\vs.h #include "shaders\vs.h" // fxc ddsview.fx /nologo /EPS_1D /Tps_4_1 /Fhshaders\ps1D.h #include "shaders\ps1D.h" // fxc ddsview.fx /nologo /EPS_1DArray /Tps_4_1 /Fhshaders\ps1Darray.h #include "shaders\\ps1Darray.h" // fxc ddsview.fx /nologo /EPS_2D /Tps_4_1 /Fhshaders\ps2D.h #include "shaders\\ps2D.h" // fxc ddsview.fx /nologo /EPS_2DArray /Tps_4_1 /Fhshaders\ps2Darray.h #include "shaders\ps2Darray.h" // fxc ddsview.fx /nologo /EPS_3D /Tps_4_1 /Fhshaders\ps3D.h #include "shaders\ps3D.h" // fxc ddsview.fx /nologo /EPS_Cube /Tps_4_1 /Fhshaders\psCube.h #include "shaders\psCube.h" //-------------------------------------------------------------------------------------- HINSTANCE g_hInst = NULL; HWND g_hWnd = NULL; D3D_DRIVER_TYPE g_driverType = D3D_DRIVER_TYPE_NULL; D3D_FEATURE_LEVEL g_featureLevel = D3D_FEATURE_LEVEL_11_0; ID3D11Device* g_pd3dDevice = NULL; ID3D11DeviceContext* g_pImmediateContext = NULL; IDXGISwapChain* g_pSwapChain = NULL; ID3D11RenderTargetView* g_pRenderTargetView = NULL; ID3D11Texture2D* g_pDepthStencil = NULL; ID3D11DepthStencilView* g_pDepthStencilView = NULL; ID3D11VertexShader* g_pVertexShader = NULL; ID3D11PixelShader* g_pPixelShader = NULL; ID3D11InputLayout* g_pVertexLayout = NULL; ID3D11Buffer* g_pVertexBuffer = NULL; ID3D11Buffer* g_pIndexBuffer = NULL; ID3D11Buffer* g_pCBArrayControl = NULL; ID3D11ShaderResourceView* g_pSRV = NULL; ID3D11BlendState* g_AlphaBlendState = NULL; ID3D11SamplerState* g_pSamplerLinear = NULL; UINT g_iCurrentIndex = 0; UINT g_iMaxIndex = 1; UINT g_iIndices = 0; //-------------------------------------------------------------------------------------- HRESULT InitWindow( HINSTANCE hInstance, int nCmdShow, const TexMetadata& mdata ); HRESULT InitDevice( const TexMetadata& mdata ); void CleanupDevice(); LRESULT CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM ); void Render(); //-------------------------------------------------------------------------------------- #pragma warning( suppress : 6262 ) int WINAPI wWinMain( _In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow ) { UNREFERENCED_PARAMETER( hPrevInstance ); UNREFERENCED_PARAMETER( lpCmdLine ); if ( !*lpCmdLine ) { MessageBox( NULL, L"Usage: ddsview ", L"DDSView", MB_OK | MB_ICONEXCLAMATION ); return 0; } TexMetadata mdata; HRESULT hr = GetMetadataFromDDSFile( lpCmdLine, DDS_FLAGS_NONE, mdata ); if ( FAILED(hr) ) { WCHAR buff[2048]; swprintf_s( buff, L"Failed to open texture file\n\nFilename = %ls\nHRESULT %08X", lpCmdLine, hr ); MessageBox( NULL, buff, L"DDSView", MB_OK | MB_ICONEXCLAMATION ); return 0; } if( FAILED( InitWindow( hInstance, nCmdShow, mdata ) ) ) return 0; SetWindowTextW( g_hWnd, lpCmdLine ); if( FAILED( InitDevice( mdata ) ) ) { CleanupDevice(); return 0; } if (mdata.dimension == TEX_DIMENSION_TEXTURE3D) { if ( mdata.arraySize > 1 ) { WCHAR buff[2048]; swprintf_s( buff, L"Arrays of volume textures are not supported\n\nFilename = %ls\nArray size %Iu", lpCmdLine, mdata.arraySize ); MessageBox( NULL, buff, L"DDSView", MB_OK | MB_ICONEXCLAMATION ); return 0; } g_iMaxIndex = static_cast( mdata.depth ); } else { g_iMaxIndex = static_cast( mdata.arraySize ); } switch( mdata.format ) { case DXGI_FORMAT_BC6H_TYPELESS: case DXGI_FORMAT_BC6H_UF16: case DXGI_FORMAT_BC6H_SF16: case DXGI_FORMAT_BC7_TYPELESS: case DXGI_FORMAT_BC7_UNORM: case DXGI_FORMAT_BC7_UNORM_SRGB: if ( g_featureLevel < D3D_FEATURE_LEVEL_11_0 ) { WCHAR buff[2048]; swprintf_s( buff, L"BC6H/BC7 requires DirectX 11 hardware\n\nFilename = %ls\nDXGI Format %d\nFeature Level %d", lpCmdLine, mdata.format, g_featureLevel ); MessageBox( NULL, buff, L"DDSView", MB_OK | MB_ICONEXCLAMATION ); return 0; } break; default: { UINT flags = 0; hr = g_pd3dDevice->CheckFormatSupport ( mdata.format, &flags ); if ( FAILED(hr) || !(flags & (D3D11_FORMAT_SUPPORT_TEXTURE1D|D3D11_FORMAT_SUPPORT_TEXTURE2D|D3D11_FORMAT_SUPPORT_TEXTURE3D)) ) { WCHAR buff[2048]; swprintf_s( buff, L"Format not supported by DirectX hardware\n\nFilename = %ls\nDXGI Format %d\nFeature Level %d\nHRESULT = %08X", lpCmdLine, mdata.format, g_featureLevel, hr ); MessageBox( NULL, buff, L"DDSView", MB_OK | MB_ICONEXCLAMATION ); return 0; } } break; } ScratchImage image; hr = LoadFromDDSFile( lpCmdLine, DDS_FLAGS_NONE, &mdata, image ); if ( FAILED(hr) ) { WCHAR buff[2048]; swprintf_s( buff, L"Failed to load texture file\n\nFilename = %ls\nHRESULT %08X", lpCmdLine, hr ); MessageBox( NULL, buff, L"DDSView", MB_OK | MB_ICONEXCLAMATION ); return 0; } // Special case to make sure Texture cubes remain arrays mdata.miscFlags &= ~TEX_MISC_TEXTURECUBE; hr = CreateShaderResourceView( g_pd3dDevice, image.GetImages(), image.GetImageCount(), mdata, &g_pSRV ); if ( FAILED(hr) ) { WCHAR buff[2048]; swprintf_s( buff, L"Failed creating texture from file\n\nFilename = %ls\nHRESULT = %08X", lpCmdLine, hr ); MessageBox( NULL, buff, L"DDSView", MB_OK | MB_ICONEXCLAMATION ); return 0; } // Main message loop MSG msg = {0}; while( WM_QUIT != msg.message ) { if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ) { TranslateMessage( &msg ); DispatchMessage( &msg ); } else { Render(); } } CleanupDevice(); return ( int )msg.wParam; } //-------------------------------------------------------------------------------------- HRESULT InitWindow( HINSTANCE hInstance, int nCmdShow, const TexMetadata& mdata ) { // Register class WNDCLASSEX wcex; wcex.cbSize = sizeof( WNDCLASSEX ); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = LoadIcon( hInstance, ( LPCTSTR )IDI_MAIN_ICON ); wcex.hCursor = LoadCursor( NULL, IDC_ARROW ); wcex.hbrBackground = ( HBRUSH )( COLOR_WINDOW + 1 ); wcex.lpszMenuName = NULL; wcex.lpszClassName = L"DDSViewWindowClass"; wcex.hIconSm = LoadIcon( wcex.hInstance, ( LPCTSTR )IDI_MAIN_ICON ); if( !RegisterClassEx( &wcex ) ) return E_FAIL; // Create window g_hInst = hInstance; RECT rc = { 0, 0, 640, 480 }; int cxborder = GetSystemMetrics( SM_CXBORDER ); int cxedge = GetSystemMetrics( SM_CXEDGE ); int screenX = GetSystemMetrics( SM_CXSCREEN ) - max( cxborder, cxedge ); if( rc.right < (LONG)mdata.width ) rc.right = (LONG)mdata.height; if ( rc.right > screenX ) rc.right = screenX; int cyborder = GetSystemMetrics( SM_CYBORDER ); int cyedge = GetSystemMetrics( SM_CYEDGE ); int screenY = GetSystemMetrics( SM_CYSCREEN ) - max( cyborder, cyedge ); if ( rc.bottom < (LONG)mdata.height ) rc.bottom = (LONG)mdata.height; if ( rc.bottom > screenY ) rc.bottom = screenY; AdjustWindowRect( &rc, WS_OVERLAPPEDWINDOW, FALSE ); g_hWnd = CreateWindow( L"DDSViewWindowClass", L"DDS View", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, rc.right - rc.left, rc.bottom - rc.top, NULL, NULL, hInstance, NULL ); if( !g_hWnd ) return E_FAIL; ShowWindow( g_hWnd, nCmdShow ); return S_OK; } //-------------------------------------------------------------------------------------- LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam ) { PAINTSTRUCT ps; HDC hdc; switch( message ) { case WM_PAINT: hdc = BeginPaint( hWnd, &ps ); EndPaint( hWnd, &ps ); break; case WM_DESTROY: PostQuitMessage( 0 ); break; case WM_KEYDOWN: if ( wParam == VK_RIGHT ) { if ( g_iCurrentIndex < g_iMaxIndex-1 ) ++g_iCurrentIndex; } else if ( wParam == VK_LEFT ) { if ( g_iCurrentIndex > 0 ) { --g_iCurrentIndex; } } else if ( wParam >= '0' && wParam <= '9' ) { UINT index = (wParam == '0') ? 10 : ((UINT) (wParam - '1')); if ( index < g_iMaxIndex ) g_iCurrentIndex = index; } InvalidateRect( hWnd, NULL, FALSE ); break; default: return DefWindowProc( hWnd, message, wParam, lParam ); } return 0; } //-------------------------------------------------------------------------------------- HRESULT InitDevice( const TexMetadata& mdata ) { HRESULT hr = S_OK; RECT rc; GetClientRect( g_hWnd, &rc ); UINT width = rc.right - rc.left; UINT height = rc.bottom - rc.top; UINT createDeviceFlags = 0; #if defined( DEBUG ) || defined( _DEBUG ) createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG; #endif D3D_DRIVER_TYPE driverTypes[] = { D3D_DRIVER_TYPE_HARDWARE, D3D_DRIVER_TYPE_WARP, D3D_DRIVER_TYPE_REFERENCE, }; UINT numDriverTypes = ARRAYSIZE( driverTypes ); D3D_FEATURE_LEVEL featureLevels[] = { D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0, }; UINT numFeatureLevels = ARRAYSIZE( featureLevels ); DXGI_SWAP_CHAIN_DESC sd; ZeroMemory( &sd, sizeof( sd ) ); sd.BufferCount = 1; sd.BufferDesc.Width = width; sd.BufferDesc.Height = height; sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; sd.BufferDesc.RefreshRate.Numerator = 60; sd.BufferDesc.RefreshRate.Denominator = 1; sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; sd.OutputWindow = g_hWnd; sd.SampleDesc.Count = 1; sd.SampleDesc.Quality = 0; sd.Windowed = TRUE; for( UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++ ) { g_driverType = driverTypes[driverTypeIndex]; hr = D3D11CreateDeviceAndSwapChain( NULL, g_driverType, NULL, createDeviceFlags, featureLevels, numFeatureLevels, D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, &g_featureLevel, &g_pImmediateContext ); if( SUCCEEDED( hr ) ) break; } if( FAILED( hr ) ) return hr; // Create a render target view ID3D11Texture2D* pBackBuffer = NULL; hr = g_pSwapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D ), ( LPVOID* )&pBackBuffer ); if( FAILED( hr ) ) return hr; hr = g_pd3dDevice->CreateRenderTargetView( pBackBuffer, NULL, &g_pRenderTargetView ); pBackBuffer->Release(); if( FAILED( hr ) ) return hr; // Create depth stencil texture D3D11_TEXTURE2D_DESC descDepth; ZeroMemory( &descDepth, sizeof(descDepth) ); descDepth.Width = width; descDepth.Height = height; descDepth.MipLevels = 1; descDepth.ArraySize = 1; descDepth.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; descDepth.SampleDesc.Count = 1; descDepth.SampleDesc.Quality = 0; descDepth.Usage = D3D11_USAGE_DEFAULT; descDepth.BindFlags = D3D11_BIND_DEPTH_STENCIL; descDepth.CPUAccessFlags = 0; descDepth.MiscFlags = 0; hr = g_pd3dDevice->CreateTexture2D( &descDepth, NULL, &g_pDepthStencil ); if( FAILED( hr ) ) return hr; // Create the depth stencil view D3D11_DEPTH_STENCIL_VIEW_DESC descDSV; ZeroMemory( &descDSV, sizeof(descDSV) ); descDSV.Format = descDepth.Format; descDSV.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; descDSV.Texture2D.MipSlice = 0; hr = g_pd3dDevice->CreateDepthStencilView( g_pDepthStencil, &descDSV, &g_pDepthStencilView ); if( FAILED( hr ) ) return hr; g_pImmediateContext->OMSetRenderTargets( 1, &g_pRenderTargetView, g_pDepthStencilView ); // Setup the viewport D3D11_VIEWPORT vp; vp.Width = (FLOAT)width; vp.Height = (FLOAT)height; vp.MinDepth = 0.0f; vp.MaxDepth = 1.0f; vp.TopLeftX = 0; vp.TopLeftY = 0; g_pImmediateContext->RSSetViewports( 1, &vp ); // Create the vertex shader hr = g_pd3dDevice->CreateVertexShader( g_VS, sizeof(g_VS), NULL, &g_pVertexShader ); if( FAILED( hr ) ) return hr; // Define the input layout D3D11_INPUT_ELEMENT_DESC layout[] = { { "POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "TEXCOORD", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, sizeof(XMFLOAT4), D3D11_INPUT_PER_VERTEX_DATA, 0 }, }; UINT numElements = ARRAYSIZE( layout ); // Create the input layout hr = g_pd3dDevice->CreateInputLayout( layout, numElements, g_VS, sizeof(g_VS), &g_pVertexLayout ); if( FAILED( hr ) ) return hr; // Set the input layout g_pImmediateContext->IASetInputLayout( g_pVertexLayout ); // Select the pixel shader bool isCubeMap = false; bool is1D = false; const BYTE* pshader = NULL; size_t pshader_size = 0; switch ( mdata.dimension ) { case TEX_DIMENSION_TEXTURE1D: if ( mdata.arraySize > 1) { pshader = g_PS_1DArray; pshader_size = sizeof(g_PS_1DArray); } else { pshader = g_PS_1D; pshader_size = sizeof(g_PS_1D); } is1D = true; break; case TEX_DIMENSION_TEXTURE2D: if ( mdata.miscFlags & TEX_MISC_TEXTURECUBE ) { pshader = g_PS_Cube; pshader_size = sizeof(g_PS_Cube); isCubeMap = true; } else if ( mdata.arraySize > 1 ) { pshader = g_PS_2DArray; pshader_size = sizeof(g_PS_2DArray); } else { pshader = g_PS_2D; pshader_size = sizeof(g_PS_2D); } break; case TEX_DIMENSION_TEXTURE3D: pshader = g_PS_3D; pshader_size = sizeof(g_PS_3D); break; default: return E_FAIL; } assert( pshader && pshader_size > 0 ); // Create the pixel shader hr = g_pd3dDevice->CreatePixelShader( pshader, pshader_size, NULL, &g_pPixelShader ); if( FAILED( hr ) ) return hr; // Create vertex buffer UINT nverts; D3D11_SUBRESOURCE_DATA InitData; ZeroMemory( &InitData, sizeof(InitData) ); static const SimpleVertex verticesCube[] = { // Render cubemaps as horizontal cross // XPOS { XMFLOAT4( .5f, .25f, 0.f, 1.f ), XMFLOAT4( 0.f, 0.f, 0.f, 0.f ) }, { XMFLOAT4( 1.f, .25f, 0.f, 1.f ), XMFLOAT4( 1.f, 0.f, 0.f, 0.f ) }, { XMFLOAT4( .5f, -.25f, 0.f, 1.f ), XMFLOAT4( 0.f, 1.f, 0.f, 0.f ) }, { XMFLOAT4( 1.f, -.25f, 0.f, 1.f ), XMFLOAT4( 1.f, 1.f, 0.f, 0.f ) }, // XNEG { XMFLOAT4( -.5f, .25f, 0.f, 1.f ), XMFLOAT4( 0.f, 0.f, 1.f, 0.f ) }, { XMFLOAT4( 0.f, .25f, 0.f, 1.f ), XMFLOAT4( 1.f, 0.f, 1.f, 0.f ) }, { XMFLOAT4( -.5f, -.25f, 0.f, 1.f ), XMFLOAT4( 0.f, 1.f, 1.f, 0.f ) }, { XMFLOAT4( 0.f, -.25f, 0.f, 1.f ), XMFLOAT4( 1.f, 1.f, 1.f, 0.f ) }, // YPOS { XMFLOAT4( -.5f, .75f, 0.f, 1.f ), XMFLOAT4( 0.f, 0.f, 2.f, 0.f ) }, { XMFLOAT4( 0.f, .75f, 0.f, 1.f ), XMFLOAT4( 1.f, 0.f, 2.f, 0.f ) }, { XMFLOAT4( -.5f, .25f, 0.f, 1.f ), XMFLOAT4( 0.f, 1.f, 2.f, 0.f ) }, { XMFLOAT4( 0.f, .25f, 0.f, 1.f ), XMFLOAT4( 1.f, 1.f, 2.f, 0.f ) }, // YNEG { XMFLOAT4( -.5f, -.25f, 0.f, 1.f ), XMFLOAT4( 0.f, 0.f, 3.f, 0.f ) }, { XMFLOAT4( 0.f, -.25f, 0.f, 1.f ), XMFLOAT4( 1.f, 0.f, 3.f, 0.f ) }, { XMFLOAT4( -.5f, -.75f, 0.f, 1.f ), XMFLOAT4( 0.f, 1.f, 3.f, 0.f ) }, { XMFLOAT4( 0.f, -.75f, 0.f, 1.f ), XMFLOAT4( 1.f, 1.f, 3.f, 0.f ) }, // ZPOS { XMFLOAT4( 0.f, .25f, 0.f, 1.f ), XMFLOAT4( 0.f, 0.f, 4.f, 0.f ) }, { XMFLOAT4( .5f, .25f, 0.f, 1.f ), XMFLOAT4( 1.f, 0.f, 4.f, 0.f ) }, { XMFLOAT4( 0.f, -.25f, 0.f, 1.f ), XMFLOAT4( 0.f, 1.f, 4.f, 0.f ) }, { XMFLOAT4( .5f, -.25f, 0.f, 1.f ), XMFLOAT4( 1.f, 1.f, 4.f, 0.f ) }, // ZNEG { XMFLOAT4( -1.f, .25f, 0.f, 1.f ), XMFLOAT4( 0.f, 0.f, 5.f, 0.f ) }, { XMFLOAT4( -.5f, .25f, 0.f, 1.f ), XMFLOAT4( 1.f, 0.f, 5.f, 0.f ) }, { XMFLOAT4( -1.f, -.25f, 0.f, 1.f ), XMFLOAT4( 0.f, 1.f, 5.f, 0.f ) }, { XMFLOAT4( -.5f, -.25f, 0.f, 1.f ), XMFLOAT4( 1.f, 1.f, 5.f, 0.f ) }, }; static const SimpleVertex vertices[] = { { XMFLOAT4( -1.f, 1.f, 0.f, 1.f ), XMFLOAT4( 0.f, 0.f, 0.f, 0.f ) }, { XMFLOAT4( 1.f, 1.f, 0.f, 1.f ), XMFLOAT4( 1.f, 0.f, 0.f, 0.f ) }, { XMFLOAT4( -1.f, -1.f, 0.f, 1.f ), XMFLOAT4( 0.f, 1.f, 0.f, 0.f ) }, { XMFLOAT4( 1.f, -1.f, 0.f, 1.f ), XMFLOAT4( 1.f, 1.f, 0.f, 0.f ) }, }; static const SimpleVertex vertices1D[] = { { XMFLOAT4( -1.f, .05f, 0.f, 1.f ), XMFLOAT4( 0.f, 0.f, 0.f, 0.f ) }, { XMFLOAT4( 1.f, .05f, 0.f, 1.f ), XMFLOAT4( 1.f, 0.f, 0.f, 0.f ) }, { XMFLOAT4( -1.f, -.05f, 0.f, 1.f ), XMFLOAT4( 0.f, 0.f, 0.f, 0.f ) }, { XMFLOAT4( 1.f, -.05f, 0.f, 1.f ), XMFLOAT4( 1.f, 0.f, 0.f, 0.f ) }, }; if ( isCubeMap ) { nverts = _countof(verticesCube); InitData.pSysMem = verticesCube; } else if ( is1D ) { nverts = _countof(vertices1D); InitData.pSysMem = vertices1D; } else { nverts = _countof(vertices); InitData.pSysMem = vertices; } D3D11_BUFFER_DESC bd; ZeroMemory( &bd, sizeof(bd) ); bd.Usage = D3D11_USAGE_DEFAULT; bd.ByteWidth = sizeof( SimpleVertex ) * nverts; bd.BindFlags = D3D11_BIND_VERTEX_BUFFER; bd.CPUAccessFlags = 0; hr = g_pd3dDevice->CreateBuffer( &bd, &InitData, &g_pVertexBuffer ); if( FAILED( hr ) ) return hr; // Set vertex buffer UINT stride = sizeof( SimpleVertex ); UINT offset = 0; g_pImmediateContext->IASetVertexBuffers( 0, 1, &g_pVertexBuffer, &stride, &offset ); // Create index buffer static const WORD indicesCube[] = { 0, 1, 2, 2, 1, 3, 4, 5, 6, 6, 5, 7, 8, 9, 10, 10, 9, 11, 12, 13, 14, 14, 13, 15, 16, 17, 18, 18, 17, 19, 20, 21, 22, 22, 21, 23 }; static const WORD indices[] = { 0, 1, 2, 2, 1, 3 }; if ( isCubeMap ) { g_iIndices = _countof(indicesCube); InitData.pSysMem = indicesCube; } else { g_iIndices = _countof(indices); InitData.pSysMem = indices; } bd.Usage = D3D11_USAGE_DEFAULT; bd.ByteWidth = g_iIndices * sizeof(WORD); bd.BindFlags = D3D11_BIND_INDEX_BUFFER; bd.CPUAccessFlags = 0; hr = g_pd3dDevice->CreateBuffer( &bd, &InitData, &g_pIndexBuffer ); if( FAILED( hr ) ) return hr; // Set index buffer g_pImmediateContext->IASetIndexBuffer( g_pIndexBuffer, DXGI_FORMAT_R16_UINT, 0 ); // Set primitive topology g_pImmediateContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST ); // Create the constant buffers bd.Usage = D3D11_USAGE_DEFAULT; bd.ByteWidth = sizeof(CBArrayControl); bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER; bd.CPUAccessFlags = 0; hr = g_pd3dDevice->CreateBuffer( &bd, NULL, &g_pCBArrayControl ); if( FAILED( hr ) ) return hr; // Create the state objects D3D11_SAMPLER_DESC sampDesc; ZeroMemory( &sampDesc, sizeof(sampDesc) ); sampDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT; sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP; sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP; sampDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; sampDesc.ComparisonFunc = D3D11_COMPARISON_NEVER; sampDesc.MinLOD = 0; sampDesc.MaxLOD = D3D11_FLOAT32_MAX; hr = g_pd3dDevice->CreateSamplerState( &sampDesc, &g_pSamplerLinear ); if( FAILED( hr ) ) return hr; D3D11_BLEND_DESC dsc = { false, false, { true, D3D11_BLEND_SRC_ALPHA, D3D11_BLEND_INV_SRC_ALPHA, D3D11_BLEND_OP_ADD, D3D11_BLEND_ZERO, D3D11_BLEND_ZERO, D3D11_BLEND_OP_ADD, D3D11_COLOR_WRITE_ENABLE_ALL } }; hr = g_pd3dDevice->CreateBlendState(&dsc, &g_AlphaBlendState ); if( FAILED(hr) ) return hr; return S_OK; } //-------------------------------------------------------------------------------------- void Render() { float ClearColor[4] = { 0.f, 1.f, 1.f, 1.0f }; //red,green,blue,alpha g_pImmediateContext->ClearRenderTargetView( g_pRenderTargetView, ClearColor ); g_pImmediateContext->ClearDepthStencilView( g_pDepthStencilView, D3D11_CLEAR_DEPTH, 1.0f, 0 ); float bf [4] = {1.0f, 1.0f, 1.0f, 1.0f}; g_pImmediateContext->OMSetBlendState( g_AlphaBlendState, bf, 0xffffffff ); CBArrayControl cb; cb.Index = (float)g_iCurrentIndex; g_pImmediateContext->UpdateSubresource( g_pCBArrayControl, 0, NULL, &cb, 0, 0 ); g_pImmediateContext->VSSetShader( g_pVertexShader, NULL, 0 ); g_pImmediateContext->PSSetShader( g_pPixelShader, NULL, 0 ); g_pImmediateContext->PSSetConstantBuffers( 0, 1, &g_pCBArrayControl ); g_pImmediateContext->PSSetShaderResources( 0, 1, &g_pSRV ); g_pImmediateContext->PSSetSamplers( 0, 1, &g_pSamplerLinear ); g_pImmediateContext->DrawIndexed( g_iIndices, 0, 0 ); g_pSwapChain->Present( 0, 0 ); } //-------------------------------------------------------------------------------------- void CleanupDevice() { if( g_pImmediateContext ) g_pImmediateContext->ClearState(); if( g_pSamplerLinear ) g_pSamplerLinear->Release(); if( g_AlphaBlendState ) g_AlphaBlendState->Release(); if( g_pSRV ) g_pSRV->Release(); if( g_pVertexBuffer ) g_pVertexBuffer->Release(); if( g_pIndexBuffer ) g_pIndexBuffer->Release(); if( g_pCBArrayControl ) g_pCBArrayControl->Release(); if( g_pVertexLayout ) g_pVertexLayout->Release(); if( g_pVertexShader ) g_pVertexShader->Release(); if( g_pPixelShader ) g_pPixelShader->Release(); if( g_pDepthStencil ) g_pDepthStencil->Release(); if( g_pDepthStencilView ) g_pDepthStencilView->Release(); if( g_pRenderTargetView ) g_pRenderTargetView->Release(); if( g_pSwapChain ) g_pSwapChain->Release(); if( g_pImmediateContext ) g_pImmediateContext->Release(); if( g_pd3dDevice ) g_pd3dDevice->Release(); } ================================================ FILE: 3rdParty/DirectXTex/DDSView/ddsview.fx ================================================ //-------------------------------------------------------------------------------------- // File: ddsview.fx // // Copyright (c) Microsoft Corporation. All rights reserved. //-------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------- // Constant Buffer Variables //-------------------------------------------------------------------------------------- Texture1D tx1D : register( t0 ); Texture1DArray tx1DArray : register( t0 ); Texture2D tx2D : register( t0 ); Texture2DArray tx2DArray : register( t0 ); Texture3D tx3D : register( t0 ); SamplerState samLinear : register( s0 ); cbuffer cbArrayControl : register( b0 ) { float Index; }; //-------------------------------------------------------------------------------------- struct VS_INPUT { float4 Pos : POSITION; float4 Tex : TEXCOORD0; }; struct PS_INPUT { float4 Pos : SV_POSITION; float4 Tex : TEXCOORD0; }; //-------------------------------------------------------------------------------------- // Vertex Shader //-------------------------------------------------------------------------------------- PS_INPUT VS( VS_INPUT input ) { PS_INPUT output = (PS_INPUT)0; output.Pos = input.Pos; output.Tex = input.Tex; return output; } //-------------------------------------------------------------------------------------- // Pixel Shader //-------------------------------------------------------------------------------------- float4 PS_1D( PS_INPUT input) : SV_Target { return tx1D.Sample( samLinear, input.Tex.x ); } float4 PS_1DArray( PS_INPUT input) : SV_Target { return tx1DArray.Sample( samLinear, float2(input.Tex.x, Index) ); } float4 PS_2D( PS_INPUT input) : SV_Target { return tx2D.Sample( samLinear, input.Tex.xy ); } float4 PS_2DArray( PS_INPUT input) : SV_Target { return tx2DArray.Sample( samLinear, float3(input.Tex.xy, Index) ); } float4 PS_3D( PS_INPUT input) : SV_Target { int Width, Height, Depth; tx3D.GetDimensions( Width, Height, Depth); return tx3D.Sample( samLinear, float3(input.Tex.xy, Index / Depth) ); } float4 PS_Cube( PS_INPUT input) : SV_Target { return tx2DArray.Sample( samLinear, float3(input.Tex.xy, input.Tex.z + (6*Index)) ); } ================================================ FILE: 3rdParty/DirectXTex/DDSView/hlsl.cmd ================================================ fxc ddsview.fx /nologo /EVS /Tvs_4_1 /Fhshaders\vs.h fxc ddsview.fx /nologo /EPS_1D /Tps_4_1 /Fhshaders\ps1D.h fxc ddsview.fx /nologo /EPS_1DArray /Tps_4_1 /Fhshaders\ps1Darray.h fxc ddsview.fx /nologo /EPS_2D /Tps_4_1 /Fhshaders\ps2D.h fxc ddsview.fx /nologo /EPS_2DArray /Tps_4_1 /Fhshaders\ps2Darray.h fxc ddsview.fx /nologo /EPS_3D /Tps_4_1 /Fhshaders\ps3D.h fxc ddsview.fx /nologo /EPS_Cube /Tps_4_1 /Fhshaders\psCube.h ================================================ FILE: 3rdParty/DirectXTex/DDSView/shaders/ps1D.h ================================================ #if 0 // // Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111 // // // fxc ddsview.fx /nologo /EPS_1D /Tps_4_1 /Fhshaders\ps1D.h // // // Buffer Definitions: // // cbuffer cbArrayControl // { // // float Index; // Offset: 0 Size: 4 [unused] // // } // // // Resource Bindings: // // Name Type Format Dim Slot Elements // ------------------------------ ---------- ------- ----------- ---- -------- // samLinear sampler NA NA 0 1 // tx1D texture float4 1d 0 1 // cbArrayControl cbuffer NA NA 0 1 // // // // Input signature: // // Name Index Mask Register SysValue Format Used // -------------------- ----- ------ -------- -------- ------ ------ // SV_POSITION 0 xyzw 0 POS float // TEXCOORD 0 xyzw 1 NONE float x // // // Output signature: // // Name Index Mask Register SysValue Format Used // -------------------- ----- ------ -------- -------- ------ ------ // SV_Target 0 xyzw 0 TARGET float xyzw // ps_4_1 dcl_globalFlags refactoringAllowed dcl_constantbuffer cb0[1], immediateIndexed dcl_sampler s0, mode_default dcl_resource_texture1d (float,float,float,float) t0 dcl_input_ps linear v1.x dcl_output o0.xyzw sample o0.xyzw, v1.xxxx, t0.xyzw, s0 ret // Approximately 2 instruction slots used #endif const BYTE g_PS_1D[] = { 68, 88, 66, 67, 71, 33, 105, 235, 206, 215, 61, 110, 190, 73, 39, 172, 36, 251, 31, 148, 1, 0, 0, 0, 220, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 84, 1, 0, 0, 172, 1, 0, 0, 224, 1, 0, 0, 96, 2, 0, 0, 82, 68, 69, 70, 24, 1, 0, 0, 1, 0, 0, 0, 156, 0, 0, 0, 3, 0, 0, 0, 28, 0, 0, 0, 1, 4, 255, 255, 0, 1, 0, 0, 228, 0, 0, 0, 124, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 134, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, 139, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 115, 97, 109, 76, 105, 110, 101, 97, 114, 0, 116, 120, 49, 68, 0, 99, 98, 65, 114, 114, 97, 121, 67, 111, 110, 116, 114, 111, 108, 0, 171, 171, 139, 0, 0, 0, 1, 0, 0, 0, 180, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 204, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 212, 0, 0, 0, 0, 0, 0, 0, 73, 110, 100, 101, 120, 0, 171, 171, 0, 0, 3, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 57, 46, 50, 57, 46, 57, 53, 50, 46, 51, 49, 49, 49, 0, 171, 171, 171, 73, 83, 71, 78, 80, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 1, 0, 0, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 171, 171, 171, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 171, 171, 83, 72, 68, 82, 120, 0, 0, 0, 65, 0, 0, 0, 30, 0, 0, 0, 106, 8, 0, 1, 89, 0, 0, 4, 70, 142, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 16, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 18, 16, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 69, 0, 0, 9, 242, 32, 16, 0, 0, 0, 0, 0, 6, 16, 16, 0, 1, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; ================================================ FILE: 3rdParty/DirectXTex/DDSView/shaders/ps1Darray.h ================================================ #if 0 // // Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111 // // // fxc ddsview.fx /nologo /EPS_1DArray /Tps_4_1 /Fhshaders\ps1Darray.h // // // Buffer Definitions: // // cbuffer cbArrayControl // { // // float Index; // Offset: 0 Size: 4 // // } // // // Resource Bindings: // // Name Type Format Dim Slot Elements // ------------------------------ ---------- ------- ----------- ---- -------- // samLinear sampler NA NA 0 1 // tx1DArray texture float4 1darray 0 1 // cbArrayControl cbuffer NA NA 0 1 // // // // Input signature: // // Name Index Mask Register SysValue Format Used // -------------------- ----- ------ -------- -------- ------ ------ // SV_POSITION 0 xyzw 0 POS float // TEXCOORD 0 xyzw 1 NONE float x // // // Output signature: // // Name Index Mask Register SysValue Format Used // -------------------- ----- ------ -------- -------- ------ ------ // SV_Target 0 xyzw 0 TARGET float xyzw // ps_4_1 dcl_globalFlags refactoringAllowed dcl_constantbuffer cb0[1], immediateIndexed dcl_sampler s0, mode_default dcl_resource_texture1darray (float,float,float,float) t0 dcl_input_ps linear v1.x dcl_output o0.xyzw dcl_temps 1 mov r0.x, v1.x mov r0.y, cb0[0].x sample o0.xyzw, r0.xyxx, t0.xyzw, s0 ret // Approximately 4 instruction slots used #endif const BYTE g_PS_1DArray[] = { 68, 88, 66, 67, 210, 249, 153, 123, 172, 65, 50, 100, 250, 1, 76, 219, 67, 149, 143, 209, 1, 0, 0, 0, 20, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 88, 1, 0, 0, 176, 1, 0, 0, 228, 1, 0, 0, 152, 2, 0, 0, 82, 68, 69, 70, 28, 1, 0, 0, 1, 0, 0, 0, 160, 0, 0, 0, 3, 0, 0, 0, 28, 0, 0, 0, 1, 4, 255, 255, 0, 1, 0, 0, 232, 0, 0, 0, 124, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 134, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, 144, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 115, 97, 109, 76, 105, 110, 101, 97, 114, 0, 116, 120, 49, 68, 65, 114, 114, 97, 121, 0, 99, 98, 65, 114, 114, 97, 121, 67, 111, 110, 116, 114, 111, 108, 0, 171, 144, 0, 0, 0, 1, 0, 0, 0, 184, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 208, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 216, 0, 0, 0, 0, 0, 0, 0, 73, 110, 100, 101, 120, 0, 171, 171, 0, 0, 3, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 57, 46, 50, 57, 46, 57, 53, 50, 46, 51, 49, 49, 49, 0, 171, 171, 171, 73, 83, 71, 78, 80, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 1, 0, 0, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 171, 171, 171, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 171, 171, 83, 72, 68, 82, 172, 0, 0, 0, 65, 0, 0, 0, 43, 0, 0, 0, 106, 8, 0, 1, 89, 0, 0, 4, 70, 142, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 56, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 18, 16, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 0, 0, 0, 0, 10, 16, 16, 0, 1, 0, 0, 0, 54, 0, 0, 6, 34, 0, 16, 0, 0, 0, 0, 0, 10, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 9, 242, 32, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; ================================================ FILE: 3rdParty/DirectXTex/DDSView/shaders/ps2D.h ================================================ #if 0 // // Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111 // // // fxc ddsview.fx /nologo /EPS_2D /Tps_4_1 /Fhshaders\ps2D.h // // // Resource Bindings: // // Name Type Format Dim Slot Elements // ------------------------------ ---------- ------- ----------- ---- -------- // samLinear sampler NA NA 0 1 // tx2D texture float4 2d 0 1 // // // // Input signature: // // Name Index Mask Register SysValue Format Used // -------------------- ----- ------ -------- -------- ------ ------ // SV_POSITION 0 xyzw 0 POS float // TEXCOORD 0 xyzw 1 NONE float xy // // // Output signature: // // Name Index Mask Register SysValue Format Used // -------------------- ----- ------ -------- -------- ------ ------ // SV_Target 0 xyzw 0 TARGET float xyzw // ps_4_1 dcl_globalFlags refactoringAllowed dcl_sampler s0, mode_default dcl_resource_texture2d (float,float,float,float) t0 dcl_input_ps linear v1.xy dcl_output o0.xyzw sample o0.xyzw, v1.xyxx, t0.xyzw, s0 ret // Approximately 2 instruction slots used #endif const BYTE g_PS_2D[] = { 68, 88, 66, 67, 45, 73, 251, 77, 247, 44, 253, 34, 100, 41, 211, 74, 100, 236, 72, 69, 1, 0, 0, 0, 80, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 216, 0, 0, 0, 48, 1, 0, 0, 100, 1, 0, 0, 212, 1, 0, 0, 82, 68, 69, 70, 156, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, 1, 4, 255, 255, 0, 1, 0, 0, 107, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 102, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, 115, 97, 109, 76, 105, 110, 101, 97, 114, 0, 116, 120, 50, 68, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 57, 46, 50, 57, 46, 57, 53, 50, 46, 51, 49, 49, 49, 0, 73, 83, 71, 78, 80, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 3, 0, 0, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 171, 171, 171, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 171, 171, 83, 72, 68, 82, 104, 0, 0, 0, 65, 0, 0, 0, 26, 0, 0, 0, 106, 8, 0, 1, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 24, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 69, 0, 0, 9, 242, 32, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 1, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; ================================================ FILE: 3rdParty/DirectXTex/DDSView/shaders/ps2Darray.h ================================================ #if 0 // // Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111 // // // fxc ddsview.fx /nologo /EPS_2DArray /Tps_4_1 /Fhshaders\ps2Darray.h // // // Buffer Definitions: // // cbuffer cbArrayControl // { // // float Index; // Offset: 0 Size: 4 // // } // // // Resource Bindings: // // Name Type Format Dim Slot Elements // ------------------------------ ---------- ------- ----------- ---- -------- // samLinear sampler NA NA 0 1 // tx2DArray texture float4 2darray 0 1 // cbArrayControl cbuffer NA NA 0 1 // // // // Input signature: // // Name Index Mask Register SysValue Format Used // -------------------- ----- ------ -------- -------- ------ ------ // SV_POSITION 0 xyzw 0 POS float // TEXCOORD 0 xyzw 1 NONE float xy // // // Output signature: // // Name Index Mask Register SysValue Format Used // -------------------- ----- ------ -------- -------- ------ ------ // SV_Target 0 xyzw 0 TARGET float xyzw // ps_4_1 dcl_globalFlags refactoringAllowed dcl_constantbuffer cb0[1], immediateIndexed dcl_sampler s0, mode_default dcl_resource_texture2darray (float,float,float,float) t0 dcl_input_ps linear v1.xy dcl_output o0.xyzw dcl_temps 1 mov r0.xy, v1.xyxx mov r0.z, cb0[0].x sample o0.xyzw, r0.xyzx, t0.xyzw, s0 ret // Approximately 4 instruction slots used #endif const BYTE g_PS_2DArray[] = { 68, 88, 66, 67, 55, 138, 65, 43, 181, 212, 29, 116, 142, 112, 89, 51, 193, 95, 148, 33, 1, 0, 0, 0, 20, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 88, 1, 0, 0, 176, 1, 0, 0, 228, 1, 0, 0, 152, 2, 0, 0, 82, 68, 69, 70, 28, 1, 0, 0, 1, 0, 0, 0, 160, 0, 0, 0, 3, 0, 0, 0, 28, 0, 0, 0, 1, 4, 255, 255, 0, 1, 0, 0, 232, 0, 0, 0, 124, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 134, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, 144, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 115, 97, 109, 76, 105, 110, 101, 97, 114, 0, 116, 120, 50, 68, 65, 114, 114, 97, 121, 0, 99, 98, 65, 114, 114, 97, 121, 67, 111, 110, 116, 114, 111, 108, 0, 171, 144, 0, 0, 0, 1, 0, 0, 0, 184, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 208, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 216, 0, 0, 0, 0, 0, 0, 0, 73, 110, 100, 101, 120, 0, 171, 171, 0, 0, 3, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 57, 46, 50, 57, 46, 57, 53, 50, 46, 51, 49, 49, 49, 0, 171, 171, 171, 73, 83, 71, 78, 80, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 3, 0, 0, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 171, 171, 171, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 171, 171, 83, 72, 68, 82, 172, 0, 0, 0, 65, 0, 0, 0, 43, 0, 0, 0, 106, 8, 0, 1, 89, 0, 0, 4, 70, 142, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 64, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 1, 0, 0, 0, 54, 0, 0, 6, 66, 0, 16, 0, 0, 0, 0, 0, 10, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 9, 242, 32, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; ================================================ FILE: 3rdParty/DirectXTex/DDSView/shaders/ps3D.h ================================================ #if 0 // // Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111 // // // fxc ddsview.fx /nologo /EPS_3D /Tps_4_1 /Fhshaders\ps3D.h // // // Buffer Definitions: // // cbuffer cbArrayControl // { // // float Index; // Offset: 0 Size: 4 // // } // // // Resource Bindings: // // Name Type Format Dim Slot Elements // ------------------------------ ---------- ------- ----------- ---- -------- // samLinear sampler NA NA 0 1 // tx3D texture float4 3d 0 1 // cbArrayControl cbuffer NA NA 0 1 // // // // Input signature: // // Name Index Mask Register SysValue Format Used // -------------------- ----- ------ -------- -------- ------ ------ // SV_POSITION 0 xyzw 0 POS float // TEXCOORD 0 xyzw 1 NONE float xy // // // Output signature: // // Name Index Mask Register SysValue Format Used // -------------------- ----- ------ -------- -------- ------ ------ // SV_Target 0 xyzw 0 TARGET float xyzw // ps_4_1 dcl_globalFlags refactoringAllowed dcl_constantbuffer cb0[1], immediateIndexed dcl_sampler s0, mode_default dcl_resource_texture3d (float,float,float,float) t0 dcl_input_ps linear v1.xy dcl_output o0.xyzw dcl_temps 1 resinfo r0.x, l(0), t0.zxyw div r0.z, cb0[0].x, r0.x mov r0.xy, v1.xyxx sample o0.xyzw, r0.xyzx, t0.xyzw, s0 ret // Approximately 5 instruction slots used #endif const BYTE g_PS_3D[] = { 68, 88, 66, 67, 119, 18, 113, 52, 66, 105, 65, 45, 139, 58, 175, 102, 69, 213, 121, 186, 1, 0, 0, 0, 52, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 84, 1, 0, 0, 172, 1, 0, 0, 224, 1, 0, 0, 184, 2, 0, 0, 82, 68, 69, 70, 24, 1, 0, 0, 1, 0, 0, 0, 156, 0, 0, 0, 3, 0, 0, 0, 28, 0, 0, 0, 1, 4, 255, 255, 0, 1, 0, 0, 228, 0, 0, 0, 124, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 134, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 8, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, 139, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 115, 97, 109, 76, 105, 110, 101, 97, 114, 0, 116, 120, 51, 68, 0, 99, 98, 65, 114, 114, 97, 121, 67, 111, 110, 116, 114, 111, 108, 0, 171, 171, 139, 0, 0, 0, 1, 0, 0, 0, 180, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 204, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 212, 0, 0, 0, 0, 0, 0, 0, 73, 110, 100, 101, 120, 0, 171, 171, 0, 0, 3, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 57, 46, 50, 57, 46, 57, 53, 50, 46, 51, 49, 49, 49, 0, 171, 171, 171, 73, 83, 71, 78, 80, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 3, 0, 0, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 171, 171, 171, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 171, 171, 83, 72, 68, 82, 208, 0, 0, 0, 65, 0, 0, 0, 52, 0, 0, 0, 106, 8, 0, 1, 89, 0, 0, 4, 70, 142, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 40, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, 0, 61, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 38, 125, 16, 0, 0, 0, 0, 0, 14, 0, 0, 8, 66, 0, 16, 0, 0, 0, 0, 0, 10, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 1, 0, 0, 0, 69, 0, 0, 9, 242, 32, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; ================================================ FILE: 3rdParty/DirectXTex/DDSView/shaders/psCube.h ================================================ #if 0 // // Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111 // // // fxc ddsview.fx /nologo /EPS_Cube /Tps_4_1 /Fhshaders\psCube.h // // // Buffer Definitions: // // cbuffer cbArrayControl // { // // float Index; // Offset: 0 Size: 4 // // } // // // Resource Bindings: // // Name Type Format Dim Slot Elements // ------------------------------ ---------- ------- ----------- ---- -------- // samLinear sampler NA NA 0 1 // tx2DArray texture float4 2darray 0 1 // cbArrayControl cbuffer NA NA 0 1 // // // // Input signature: // // Name Index Mask Register SysValue Format Used // -------------------- ----- ------ -------- -------- ------ ------ // SV_POSITION 0 xyzw 0 POS float // TEXCOORD 0 xyzw 1 NONE float xyz // // // Output signature: // // Name Index Mask Register SysValue Format Used // -------------------- ----- ------ -------- -------- ------ ------ // SV_Target 0 xyzw 0 TARGET float xyzw // ps_4_1 dcl_globalFlags refactoringAllowed dcl_constantbuffer cb0[1], immediateIndexed dcl_sampler s0, mode_default dcl_resource_texture2darray (float,float,float,float) t0 dcl_input_ps linear v1.xyz dcl_output o0.xyzw dcl_temps 1 mad r0.z, cb0[0].x, l(6.000000), v1.z mov r0.xy, v1.xyxx sample o0.xyzw, r0.xyzx, t0.xyzw, s0 ret // Approximately 4 instruction slots used #endif const BYTE g_PS_Cube[] = { 68, 88, 66, 67, 255, 88, 222, 202, 51, 233, 113, 192, 119, 52, 43, 119, 92, 83, 243, 127, 1, 0, 0, 0, 36, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 88, 1, 0, 0, 176, 1, 0, 0, 228, 1, 0, 0, 168, 2, 0, 0, 82, 68, 69, 70, 28, 1, 0, 0, 1, 0, 0, 0, 160, 0, 0, 0, 3, 0, 0, 0, 28, 0, 0, 0, 1, 4, 255, 255, 0, 1, 0, 0, 232, 0, 0, 0, 124, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 134, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, 144, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 115, 97, 109, 76, 105, 110, 101, 97, 114, 0, 116, 120, 50, 68, 65, 114, 114, 97, 121, 0, 99, 98, 65, 114, 114, 97, 121, 67, 111, 110, 116, 114, 111, 108, 0, 171, 144, 0, 0, 0, 1, 0, 0, 0, 184, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 208, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 216, 0, 0, 0, 0, 0, 0, 0, 73, 110, 100, 101, 120, 0, 171, 171, 0, 0, 3, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 57, 46, 50, 57, 46, 57, 53, 50, 46, 51, 49, 49, 49, 0, 171, 171, 171, 73, 83, 71, 78, 80, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 7, 0, 0, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 171, 171, 171, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 171, 171, 83, 72, 68, 82, 188, 0, 0, 0, 65, 0, 0, 0, 47, 0, 0, 0, 106, 8, 0, 1, 89, 0, 0, 4, 70, 142, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 64, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, 0, 50, 0, 0, 10, 66, 0, 16, 0, 0, 0, 0, 0, 10, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 192, 64, 42, 16, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 1, 0, 0, 0, 69, 0, 0, 9, 242, 32, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; ================================================ FILE: 3rdParty/DirectXTex/DDSView/shaders/vs.h ================================================ #if 0 // // Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111 // // // fxc ddsview.fx /nologo /EVS /Tvs_4_1 /Fhshaders\vs.h // // // // Input signature: // // Name Index Mask Register SysValue Format Used // -------------------- ----- ------ -------- -------- ------ ------ // POSITION 0 xyzw 0 NONE float xyzw // TEXCOORD 0 xyzw 1 NONE float xyzw // // // Output signature: // // Name Index Mask Register SysValue Format Used // -------------------- ----- ------ -------- -------- ------ ------ // SV_POSITION 0 xyzw 0 POS float xyzw // TEXCOORD 0 xyzw 1 NONE float xyzw // vs_4_1 dcl_globalFlags refactoringAllowed dcl_input v0.xyzw dcl_input v1.xyzw dcl_output_siv o0.xyzw, position dcl_output o1.xyzw mov o0.xyzw, v0.xyzw mov o1.xyzw, v1.xyzw ret // Approximately 3 instruction slots used #endif const BYTE g_VS[] = { 68, 88, 66, 67, 243, 4, 207, 4, 72, 185, 125, 253, 86, 236, 11, 103, 199, 128, 83, 243, 1, 0, 0, 0, 40, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 140, 0, 0, 0, 224, 0, 0, 0, 56, 1, 0, 0, 172, 1, 0, 0, 82, 68, 69, 70, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 1, 4, 254, 255, 0, 1, 0, 0, 28, 0, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 57, 46, 50, 57, 46, 57, 53, 50, 46, 51, 49, 49, 49, 0, 171, 171, 171, 73, 83, 71, 78, 76, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 171, 171, 79, 83, 71, 78, 80, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 171, 171, 171, 83, 72, 68, 82, 108, 0, 0, 0, 65, 0, 1, 0, 27, 0, 0, 0, 106, 8, 0, 1, 95, 0, 0, 3, 242, 16, 16, 0, 0, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 1, 0, 0, 0, 103, 0, 0, 4, 242, 32, 16, 0, 0, 0, 0, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 242, 32, 16, 0, 0, 0, 0, 0, 70, 30, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 242, 32, 16, 0, 1, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; ================================================ FILE: 3rdParty/DirectXTex/DirectXTex/BC.cpp ================================================ //------------------------------------------------------------------------------------- // BC.cpp // // Block-compression (BC) functionality for BC1, BC2, BC3 (orginal DXTn formats) // // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A // PARTICULAR PURPOSE. // // Copyright (c) Microsoft Corporation. All rights reserved. // // http://go.microsoft.com/fwlink/?LinkId=248926 //------------------------------------------------------------------------------------- #include "directxtexp.h" // Experiemental encoding variants, not enabled by default //#define COLOR_WEIGHTS //#define COLOR_AVG_0WEIGHTS #include "BC.h" using namespace DirectX::PackedVector; namespace DirectX { //------------------------------------------------------------------------------------- // Constants //------------------------------------------------------------------------------------- // Perceptual weightings for the importance of each channel. static const HDRColorA g_Luminance (0.2125f / 0.7154f, 1.0f, 0.0721f / 0.7154f, 1.0f); static const HDRColorA g_LuminanceInv(0.7154f / 0.2125f, 1.0f, 0.7154f / 0.0721f, 1.0f); //------------------------------------------------------------------------------------- // Decode/Encode RGB 5/6/5 colors //------------------------------------------------------------------------------------- inline static void Decode565(_Out_ HDRColorA *pColor, _In_ const uint16_t w565) { pColor->r = (float) ((w565 >> 11) & 31) * (1.0f / 31.0f); pColor->g = (float) ((w565 >> 5) & 63) * (1.0f / 63.0f); pColor->b = (float) ((w565 >> 0) & 31) * (1.0f / 31.0f); pColor->a = 1.0f; } inline static uint16_t Encode565(_In_ const HDRColorA *pColor) { HDRColorA Color; Color.r = (pColor->r < 0.0f) ? 0.0f : (pColor->r > 1.0f) ? 1.0f : pColor->r; Color.g = (pColor->g < 0.0f) ? 0.0f : (pColor->g > 1.0f) ? 1.0f : pColor->g; Color.b = (pColor->b < 0.0f) ? 0.0f : (pColor->b > 1.0f) ? 1.0f : pColor->b; uint16_t w; w = (uint16_t) ((static_cast(Color.r * 31.0f + 0.5f) << 11) | (static_cast(Color.g * 63.0f + 0.5f) << 5) | (static_cast(Color.b * 31.0f + 0.5f) << 0)); return w; } //------------------------------------------------------------------------------------- static void OptimizeRGB(_Out_ HDRColorA *pX, _Out_ HDRColorA *pY, _In_reads_(NUM_PIXELS_PER_BLOCK) const HDRColorA *pPoints, _In_ size_t cSteps, _In_ DWORD flags) { static const float fEpsilon = (0.25f / 64.0f) * (0.25f / 64.0f); static const float pC3[] = { 2.0f/2.0f, 1.0f/2.0f, 0.0f/2.0f }; static const float pD3[] = { 0.0f/2.0f, 1.0f/2.0f, 2.0f/2.0f }; static const float pC4[] = { 3.0f/3.0f, 2.0f/3.0f, 1.0f/3.0f, 0.0f/3.0f }; static const float pD4[] = { 0.0f/3.0f, 1.0f/3.0f, 2.0f/3.0f, 3.0f/3.0f }; const float *pC = (3 == cSteps) ? pC3 : pC4; const float *pD = (3 == cSteps) ? pD3 : pD4; // Find Min and Max points, as starting point HDRColorA X = (flags & BC_FLAGS_UNIFORM) ? HDRColorA(1.f, 1.f, 1.f, 1.f) : g_Luminance; HDRColorA Y = HDRColorA(0.0f, 0.0f, 0.0f, 1.0f); for(size_t iPoint = 0; iPoint < NUM_PIXELS_PER_BLOCK; iPoint++) { #ifdef COLOR_WEIGHTS if(pPoints[iPoint].a > 0.0f) #endif // COLOR_WEIGHTS { if(pPoints[iPoint].r < X.r) X.r = pPoints[iPoint].r; if(pPoints[iPoint].g < X.g) X.g = pPoints[iPoint].g; if(pPoints[iPoint].b < X.b) X.b = pPoints[iPoint].b; if(pPoints[iPoint].r > Y.r) Y.r = pPoints[iPoint].r; if(pPoints[iPoint].g > Y.g) Y.g = pPoints[iPoint].g; if(pPoints[iPoint].b > Y.b) Y.b = pPoints[iPoint].b; } } // Diagonal axis HDRColorA AB; AB.r = Y.r - X.r; AB.g = Y.g - X.g; AB.b = Y.b - X.b; float fAB = AB.r * AB.r + AB.g * AB.g + AB.b * AB.b; // Single color block.. no need to root-find if(fAB < FLT_MIN) { pX->r = X.r; pX->g = X.g; pX->b = X.b; pY->r = Y.r; pY->g = Y.g; pY->b = Y.b; return; } // Try all four axis directions, to determine which diagonal best fits data float fABInv = 1.0f / fAB; HDRColorA Dir; Dir.r = AB.r * fABInv; Dir.g = AB.g * fABInv; Dir.b = AB.b * fABInv; HDRColorA Mid; Mid.r = (X.r + Y.r) * 0.5f; Mid.g = (X.g + Y.g) * 0.5f; Mid.b = (X.b + Y.b) * 0.5f; float fDir[4]; fDir[0] = fDir[1] = fDir[2] = fDir[3] = 0.0f; for(size_t iPoint = 0; iPoint < NUM_PIXELS_PER_BLOCK; iPoint++) { HDRColorA Pt; Pt.r = (pPoints[iPoint].r - Mid.r) * Dir.r; Pt.g = (pPoints[iPoint].g - Mid.g) * Dir.g; Pt.b = (pPoints[iPoint].b - Mid.b) * Dir.b; float f; #ifdef COLOR_WEIGHTS f = Pt.r + Pt.g + Pt.b; fDir[0] += pPoints[iPoint].a * f * f; f = Pt.r + Pt.g - Pt.b; fDir[1] += pPoints[iPoint].a * f * f; f = Pt.r - Pt.g + Pt.b; fDir[2] += pPoints[iPoint].a * f * f; f = Pt.r - Pt.g - Pt.b; fDir[3] += pPoints[iPoint].a * f * f; #else f = Pt.r + Pt.g + Pt.b; fDir[0] += f * f; f = Pt.r + Pt.g - Pt.b; fDir[1] += f * f; f = Pt.r - Pt.g + Pt.b; fDir[2] += f * f; f = Pt.r - Pt.g - Pt.b; fDir[3] += f * f; #endif // COLOR_WEIGHTS } float fDirMax = fDir[0]; size_t iDirMax = 0; for(size_t iDir = 1; iDir < 4; iDir++) { if(fDir[iDir] > fDirMax) { fDirMax = fDir[iDir]; iDirMax = iDir; } } if(iDirMax & 2) { float f = X.g; X.g = Y.g; Y.g = f; } if(iDirMax & 1) { float f = X.b; X.b = Y.b; Y.b = f; } // Two color block.. no need to root-find if(fAB < 1.0f / 4096.0f) { pX->r = X.r; pX->g = X.g; pX->b = X.b; pY->r = Y.r; pY->g = Y.g; pY->b = Y.b; return; } // Use Newton's Method to find local minima of sum-of-squares error. float fSteps = (float) (cSteps - 1); for(size_t iIteration = 0; iIteration < 8; iIteration++) { // Calculate new steps HDRColorA pSteps[4]; for(size_t iStep = 0; iStep < cSteps; iStep++) { pSteps[iStep].r = X.r * pC[iStep] + Y.r * pD[iStep]; pSteps[iStep].g = X.g * pC[iStep] + Y.g * pD[iStep]; pSteps[iStep].b = X.b * pC[iStep] + Y.b * pD[iStep]; } // Calculate color direction Dir.r = Y.r - X.r; Dir.g = Y.g - X.g; Dir.b = Y.b - X.b; float fLen = (Dir.r * Dir.r + Dir.g * Dir.g + Dir.b * Dir.b); if(fLen < (1.0f / 4096.0f)) break; float fScale = fSteps / fLen; Dir.r *= fScale; Dir.g *= fScale; Dir.b *= fScale; // Evaluate function, and derivatives float d2X, d2Y; HDRColorA dX, dY; d2X = d2Y = dX.r = dX.g = dX.b = dY.r = dY.g = dY.b = 0.0f; for(size_t iPoint = 0; iPoint < NUM_PIXELS_PER_BLOCK; iPoint++) { float fDot = (pPoints[iPoint].r - X.r) * Dir.r + (pPoints[iPoint].g - X.g) * Dir.g + (pPoints[iPoint].b - X.b) * Dir.b; size_t iStep; if(fDot <= 0.0f) iStep = 0; else if(fDot >= fSteps) iStep = cSteps - 1; else iStep = static_cast(fDot + 0.5f); HDRColorA Diff; Diff.r = pSteps[iStep].r - pPoints[iPoint].r; Diff.g = pSteps[iStep].g - pPoints[iPoint].g; Diff.b = pSteps[iStep].b - pPoints[iPoint].b; #ifdef COLOR_WEIGHTS float fC = pC[iStep] * pPoints[iPoint].a * (1.0f / 8.0f); float fD = pD[iStep] * pPoints[iPoint].a * (1.0f / 8.0f); #else float fC = pC[iStep] * (1.0f / 8.0f); float fD = pD[iStep] * (1.0f / 8.0f); #endif // COLOR_WEIGHTS d2X += fC * pC[iStep]; dX.r += fC * Diff.r; dX.g += fC * Diff.g; dX.b += fC * Diff.b; d2Y += fD * pD[iStep]; dY.r += fD * Diff.r; dY.g += fD * Diff.g; dY.b += fD * Diff.b; } // Move endpoints if(d2X > 0.0f) { float f = -1.0f / d2X; X.r += dX.r * f; X.g += dX.g * f; X.b += dX.b * f; } if(d2Y > 0.0f) { float f = -1.0f / d2Y; Y.r += dY.r * f; Y.g += dY.g * f; Y.b += dY.b * f; } if((dX.r * dX.r < fEpsilon) && (dX.g * dX.g < fEpsilon) && (dX.b * dX.b < fEpsilon) && (dY.r * dY.r < fEpsilon) && (dY.g * dY.g < fEpsilon) && (dY.b * dY.b < fEpsilon)) { break; } } pX->r = X.r; pX->g = X.g; pX->b = X.b; pY->r = Y.r; pY->g = Y.g; pY->b = Y.b; } //------------------------------------------------------------------------------------- inline static void DecodeBC1( _Out_writes_(NUM_PIXELS_PER_BLOCK) XMVECTOR *pColor, _In_ const D3DX_BC1 *pBC, _In_ bool isbc1 ) { assert( pColor && pBC ); static_assert( sizeof(D3DX_BC1) == 8, "D3DX_BC1 should be 8 bytes" ); static XMVECTORF32 s_Scale = { 1.f/31.f, 1.f/63.f, 1.f/31.f, 1.f }; XMVECTOR clr0 = XMLoadU565( reinterpret_cast(&pBC->rgb[0]) ); XMVECTOR clr1 = XMLoadU565( reinterpret_cast(&pBC->rgb[1]) ); clr0 = XMVectorMultiply( clr0, s_Scale ); clr1 = XMVectorMultiply( clr1, s_Scale ); clr0 = XMVectorSwizzle<2, 1, 0, 3>( clr0 ); clr1 = XMVectorSwizzle<2, 1, 0, 3>( clr1 ); clr0 = XMVectorSelect( g_XMIdentityR3, clr0, g_XMSelect1110 ); clr1 = XMVectorSelect( g_XMIdentityR3, clr1, g_XMSelect1110 ); XMVECTOR clr2, clr3; if ( isbc1 && (pBC->rgb[0] <= pBC->rgb[1]) ) { clr2 = XMVectorLerp( clr0, clr1, 0.5f ); clr3 = XMVectorZero(); // Alpha of 0 } else { clr2 = XMVectorLerp( clr0, clr1, 1.f/3.f ); clr3 = XMVectorLerp( clr0, clr1, 2.f/3.f ); } uint32_t dw = pBC->bitmap; for(size_t i = 0; i < NUM_PIXELS_PER_BLOCK; ++i, dw >>= 2) { switch(dw & 3) { case 0: pColor[i] = clr0; break; case 1: pColor[i] = clr1; break; case 2: pColor[i] = clr2; break; case 3: default: pColor[i] = clr3; break; } } } //------------------------------------------------------------------------------------- static void EncodeBC1(_Out_ D3DX_BC1 *pBC, _In_reads_(NUM_PIXELS_PER_BLOCK) const HDRColorA *pColor, _In_ bool bColorKey, _In_ float alphaRef, _In_ DWORD flags) { assert( pBC && pColor ); static_assert( sizeof(D3DX_BC1) == 8, "D3DX_BC1 should be 8 bytes" ); // Determine if we need to colorkey this block size_t uSteps; if (bColorKey) { size_t uColorKey = 0; for(size_t i = 0; i < NUM_PIXELS_PER_BLOCK; ++i) { if(pColor[i].a < alphaRef) uColorKey++; } if(NUM_PIXELS_PER_BLOCK == uColorKey) { pBC->rgb[0] = 0x0000; pBC->rgb[1] = 0xffff; pBC->bitmap = 0xffffffff; return; } uSteps = (uColorKey > 0) ? 3 : 4; } else { uSteps = 4; } // Quantize block to R56B5, using Floyd Stienberg error diffusion. This // increases the chance that colors will map directly to the quantized // axis endpoints. HDRColorA Color[NUM_PIXELS_PER_BLOCK]; HDRColorA Error[NUM_PIXELS_PER_BLOCK]; if (flags & BC_FLAGS_DITHER_RGB) memset(Error, 0x00, NUM_PIXELS_PER_BLOCK * sizeof(HDRColorA)); size_t i; for(i = 0; i < NUM_PIXELS_PER_BLOCK; ++i) { HDRColorA Clr; Clr.r = pColor[i].r; Clr.g = pColor[i].g; Clr.b = pColor[i].b; if (flags & BC_FLAGS_DITHER_RGB) { Clr.r += Error[i].r; Clr.g += Error[i].g; Clr.b += Error[i].b; } Color[i].r = (float) static_cast(Clr.r * 31.0f + 0.5f) * (1.0f / 31.0f); Color[i].g = (float) static_cast(Clr.g * 63.0f + 0.5f) * (1.0f / 63.0f); Color[i].b = (float) static_cast(Clr.b * 31.0f + 0.5f) * (1.0f / 31.0f); #ifdef COLOR_WEIGHTS Color[i].a = pColor[i].a; #else Color[i].a = 1.0f; #endif // COLOR_WEIGHTS if (flags & BC_FLAGS_DITHER_RGB) { HDRColorA Diff; Diff.r = Color[i].a * (Clr.r - Color[i].r); Diff.g = Color[i].a * (Clr.g - Color[i].g); Diff.b = Color[i].a * (Clr.b - Color[i].b); if(3 != (i & 3)) { assert( i < 15 ); _Analysis_assume_( i < 15 ); Error[i + 1].r += Diff.r * (7.0f / 16.0f); Error[i + 1].g += Diff.g * (7.0f / 16.0f); Error[i + 1].b += Diff.b * (7.0f / 16.0f); } if(i < 12) { if(i & 3) { Error[i + 3].r += Diff.r * (3.0f / 16.0f); Error[i + 3].g += Diff.g * (3.0f / 16.0f); Error[i + 3].b += Diff.b * (3.0f / 16.0f); } Error[i + 4].r += Diff.r * (5.0f / 16.0f); Error[i + 4].g += Diff.g * (5.0f / 16.0f); Error[i + 4].b += Diff.b * (5.0f / 16.0f); if(3 != (i & 3)) { assert( i < 11 ); _Analysis_assume_( i < 11 ); Error[i + 5].r += Diff.r * (1.0f / 16.0f); Error[i + 5].g += Diff.g * (1.0f / 16.0f); Error[i + 5].b += Diff.b * (1.0f / 16.0f); } } } if ( !( flags & BC_FLAGS_UNIFORM ) ) { Color[i].r *= g_Luminance.r; Color[i].g *= g_Luminance.g; Color[i].b *= g_Luminance.b; } } // Perform 6D root finding function to find two endpoints of color axis. // Then quantize and sort the endpoints depending on mode. HDRColorA ColorA, ColorB, ColorC, ColorD; OptimizeRGB(&ColorA, &ColorB, Color, uSteps, flags); if ( flags & BC_FLAGS_UNIFORM ) { ColorC = ColorA; ColorD = ColorB; } else { ColorC.r = ColorA.r * g_LuminanceInv.r; ColorC.g = ColorA.g * g_LuminanceInv.g; ColorC.b = ColorA.b * g_LuminanceInv.b; ColorD.r = ColorB.r * g_LuminanceInv.r; ColorD.g = ColorB.g * g_LuminanceInv.g; ColorD.b = ColorB.b * g_LuminanceInv.b; } uint16_t wColorA = Encode565(&ColorC); uint16_t wColorB = Encode565(&ColorD); if((uSteps == 4) && (wColorA == wColorB)) { pBC->rgb[0] = wColorA; pBC->rgb[1] = wColorB; pBC->bitmap = 0x00000000; return; } Decode565(&ColorC, wColorA); Decode565(&ColorD, wColorB); if ( flags & BC_FLAGS_UNIFORM ) { ColorA = ColorC; ColorB = ColorD; } else { ColorA.r = ColorC.r * g_Luminance.r; ColorA.g = ColorC.g * g_Luminance.g; ColorA.b = ColorC.b * g_Luminance.b; ColorB.r = ColorD.r * g_Luminance.r; ColorB.g = ColorD.g * g_Luminance.g; ColorB.b = ColorD.b * g_Luminance.b; } // Calculate color steps HDRColorA Step[4]; if((3 == uSteps) == (wColorA <= wColorB)) { pBC->rgb[0] = wColorA; pBC->rgb[1] = wColorB; Step[0] = ColorA; Step[1] = ColorB; } else { pBC->rgb[0] = wColorB; pBC->rgb[1] = wColorA; Step[0] = ColorB; Step[1] = ColorA; } static const size_t pSteps3[] = { 0, 2, 1 }; static const size_t pSteps4[] = { 0, 2, 3, 1 }; const size_t *pSteps; if(3 == uSteps) { pSteps = pSteps3; HDRColorALerp(&Step[2], &Step[0], &Step[1], 0.5f); } else { pSteps = pSteps4; HDRColorALerp(&Step[2], &Step[0], &Step[1], 1.0f / 3.0f); HDRColorALerp(&Step[3], &Step[0], &Step[1], 2.0f / 3.0f); } // Calculate color direction HDRColorA Dir; Dir.r = Step[1].r - Step[0].r; Dir.g = Step[1].g - Step[0].g; Dir.b = Step[1].b - Step[0].b; float fSteps = (float) (uSteps - 1); float fScale = (wColorA != wColorB) ? (fSteps / (Dir.r * Dir.r + Dir.g * Dir.g + Dir.b * Dir.b)) : 0.0f; Dir.r *= fScale; Dir.g *= fScale; Dir.b *= fScale; // Encode colors uint32_t dw = 0; if (flags & BC_FLAGS_DITHER_RGB) memset(Error, 0x00, NUM_PIXELS_PER_BLOCK * sizeof(HDRColorA)); for(i = 0; i < NUM_PIXELS_PER_BLOCK; ++i) { if((3 == uSteps) && (pColor[i].a < alphaRef)) { dw = (3 << 30) | (dw >> 2); } else { HDRColorA Clr; if ( flags & BC_FLAGS_UNIFORM ) { Clr.r = pColor[i].r; Clr.g = pColor[i].g; Clr.b = pColor[i].b; } else { Clr.r = pColor[i].r * g_Luminance.r; Clr.g = pColor[i].g * g_Luminance.g; Clr.b = pColor[i].b * g_Luminance.b; } if (flags & BC_FLAGS_DITHER_RGB) { Clr.r += Error[i].r; Clr.g += Error[i].g; Clr.b += Error[i].b; } float fDot = (Clr.r - Step[0].r) * Dir.r + (Clr.g - Step[0].g) * Dir.g + (Clr.b - Step[0].b) * Dir.b; uint32_t iStep; if(fDot <= 0.0f) iStep = 0; else if(fDot >= fSteps) iStep = 1; else iStep = static_cast( pSteps[static_cast(fDot + 0.5f)] ); dw = (iStep << 30) | (dw >> 2); if (flags & BC_FLAGS_DITHER_RGB) { HDRColorA Diff; Diff.r = Color[i].a * (Clr.r - Step[iStep].r); Diff.g = Color[i].a * (Clr.g - Step[iStep].g); Diff.b = Color[i].a * (Clr.b - Step[iStep].b); if(3 != (i & 3)) { Error[i + 1].r += Diff.r * (7.0f / 16.0f); Error[i + 1].g += Diff.g * (7.0f / 16.0f); Error[i + 1].b += Diff.b * (7.0f / 16.0f); } if(i < 12) { if(i & 3) { Error[i + 3].r += Diff.r * (3.0f / 16.0f); Error[i + 3].g += Diff.g * (3.0f / 16.0f); Error[i + 3].b += Diff.b * (3.0f / 16.0f); } Error[i + 4].r += Diff.r * (5.0f / 16.0f); Error[i + 4].g += Diff.g * (5.0f / 16.0f); Error[i + 4].b += Diff.b * (5.0f / 16.0f); if(3 != (i & 3)) { Error[i + 5].r += Diff.r * (1.0f / 16.0f); Error[i + 5].g += Diff.g * (1.0f / 16.0f); Error[i + 5].b += Diff.b * (1.0f / 16.0f); } } } } } pBC->bitmap = dw; } //------------------------------------------------------------------------------------- #ifdef COLOR_WEIGHTS static void EncodeSolidBC1(_Out_ D3DX_BC1 *pBC, _In_reads_(NUM_PIXELS_PER_BLOCK) const HDRColorA *pColor) { #ifdef COLOR_AVG_0WEIGHTS // Compute avg color HDRColorA Color; Color.r = pColor[0].r; Color.g = pColor[0].g; Color.b = pColor[0].b; for(size_t i = 1; i < NUM_PIXELS_PER_BLOCK; ++i) { Color.r += pColor[i].r; Color.g += pColor[i].g; Color.b += pColor[i].b; } Color.r *= 1.0f / 16.0f; Color.g *= 1.0f / 16.0f; Color.b *= 1.0f / 16.0f; uint16_t wColor = Encode565(&Color); #else uint16_t wColor = 0x0000; #endif // COLOR_AVG_0WEIGHTS // Encode solid block pBC->rgb[0] = wColor; pBC->rgb[1] = wColor; pBC->bitmap = 0x00000000; } #endif // COLOR_WEIGHTS //===================================================================================== // Entry points //===================================================================================== //------------------------------------------------------------------------------------- // BC1 Compression //------------------------------------------------------------------------------------- _Use_decl_annotations_ void D3DXDecodeBC1(XMVECTOR *pColor, const uint8_t *pBC) { auto pBC1 = reinterpret_cast(pBC); DecodeBC1( pColor, pBC1, true ); } _Use_decl_annotations_ void D3DXEncodeBC1(uint8_t *pBC, const XMVECTOR *pColor, float alphaRef, DWORD flags) { assert( pBC && pColor ); HDRColorA Color[NUM_PIXELS_PER_BLOCK]; if (flags & BC_FLAGS_DITHER_A) { float fError[NUM_PIXELS_PER_BLOCK]; memset(fError, 0x00, NUM_PIXELS_PER_BLOCK * sizeof(float)); for(size_t i = 0; i < NUM_PIXELS_PER_BLOCK; ++i) { HDRColorA clr; XMStoreFloat4( reinterpret_cast( &clr ), pColor[i] ); float fAlph = clr.a + fError[i]; Color[i].r = clr.r; Color[i].g = clr.g; Color[i].b = clr.b; Color[i].a = (float) static_cast(clr.a + fError[i] + 0.5f); float fDiff = fAlph - Color[i].a; if(3 != (i & 3)) { assert( i < 15 ); _Analysis_assume_( i < 15 ); fError[i + 1] += fDiff * (7.0f / 16.0f); } if(i < 12) { if(i & 3) fError[i + 3] += fDiff * (3.0f / 16.0f); fError[i + 4] += fDiff * (5.0f / 16.0f); if(3 != (i & 3)) { assert( i < 11 ); _Analysis_assume_( i < 11 ); fError[i + 5] += fDiff * (1.0f / 16.0f); } } } } else { for(size_t i = 0; i < NUM_PIXELS_PER_BLOCK; ++i) { XMStoreFloat4( reinterpret_cast( &Color[i] ), pColor[i] ); } } auto pBC1 = reinterpret_cast(pBC); EncodeBC1(pBC1, Color, true, alphaRef, flags); } //------------------------------------------------------------------------------------- // BC2 Compression //------------------------------------------------------------------------------------- _Use_decl_annotations_ void D3DXDecodeBC2(XMVECTOR *pColor, const uint8_t *pBC) { assert( pColor && pBC ); static_assert( sizeof(D3DX_BC2) == 16, "D3DX_BC2 should be 16 bytes" ); auto pBC2 = reinterpret_cast(pBC); // RGB part DecodeBC1(pColor, &pBC2->bc1, false); // 4-bit alpha part DWORD dw = pBC2->bitmap[0]; for(size_t i = 0; i < 8; ++i, dw >>= 4) { #pragma prefast(suppress:22103, "writing blocks in two halves confuses tool") pColor[i] = XMVectorSetW( pColor[i], (float) (dw & 0xf) * (1.0f / 15.0f) ); } dw = pBC2->bitmap[1]; for(size_t i = 8; i < NUM_PIXELS_PER_BLOCK; ++i, dw >>= 4) pColor[i] = XMVectorSetW( pColor[i], (float) (dw & 0xf) * (1.0f / 15.0f) ); } _Use_decl_annotations_ void D3DXEncodeBC2(uint8_t *pBC, const XMVECTOR *pColor, DWORD flags) { assert( pBC && pColor ); static_assert( sizeof(D3DX_BC2) == 16, "D3DX_BC2 should be 16 bytes" ); HDRColorA Color[NUM_PIXELS_PER_BLOCK]; for(size_t i = 0; i < NUM_PIXELS_PER_BLOCK; ++i) { XMStoreFloat4( reinterpret_cast( &Color[i] ), pColor[i] ); } auto pBC2 = reinterpret_cast(pBC); // 4-bit alpha part. Dithered using Floyd Stienberg error diffusion. pBC2->bitmap[0] = 0; pBC2->bitmap[1] = 0; float fError[NUM_PIXELS_PER_BLOCK]; if (flags & BC_FLAGS_DITHER_A) memset(fError, 0x00, NUM_PIXELS_PER_BLOCK * sizeof(float)); for(size_t i = 0; i < NUM_PIXELS_PER_BLOCK; ++i) { float fAlph = Color[i].a; if (flags & BC_FLAGS_DITHER_A) fAlph += fError[i]; uint32_t u = (uint32_t) static_cast(fAlph * 15.0f + 0.5f); pBC2->bitmap[i >> 3] >>= 4; pBC2->bitmap[i >> 3] |= (u << 28); if (flags & BC_FLAGS_DITHER_A) { float fDiff = fAlph - (float) u * (1.0f / 15.0f); if(3 != (i & 3)) { assert( i < 15 ); _Analysis_assume_( i < 15 ); fError[i + 1] += fDiff * (7.0f / 16.0f); } if(i < 12) { if(i & 3) fError[i + 3] += fDiff * (3.0f / 16.0f); fError[i + 4] += fDiff * (5.0f / 16.0f); if(3 != (i & 3)) { assert( i < 11 ); _Analysis_assume_( i < 11 ); fError[i + 5] += fDiff * (1.0f / 16.0f); } } } } // RGB part #ifdef COLOR_WEIGHTS if(!pBC2->bitmap[0] && !pBC2->bitmap[1]) { EncodeSolidBC1(pBC2->dxt1, Color); return; } #endif // COLOR_WEIGHTS EncodeBC1(&pBC2->bc1, Color, false, 0.f, flags); } //------------------------------------------------------------------------------------- // BC3 Compression //------------------------------------------------------------------------------------- _Use_decl_annotations_ void D3DXDecodeBC3(XMVECTOR *pColor, const uint8_t *pBC) { assert( pColor && pBC ); static_assert( sizeof(D3DX_BC3) == 16, "D3DX_BC3 should be 16 bytes" ); auto pBC3 = reinterpret_cast(pBC); // RGB part DecodeBC1(pColor, &pBC3->bc1, false); // Adaptive 3-bit alpha part float fAlpha[8]; fAlpha[0] = ((float) pBC3->alpha[0]) * (1.0f / 255.0f); fAlpha[1] = ((float) pBC3->alpha[1]) * (1.0f / 255.0f); if(pBC3->alpha[0] > pBC3->alpha[1]) { for(size_t i = 1; i < 7; ++i) fAlpha[i + 1] = (fAlpha[0] * (7 - i) + fAlpha[1] * i) * (1.0f / 7.0f); } else { for(size_t i = 1; i < 5; ++i) fAlpha[i + 1] = (fAlpha[0] * (5 - i) + fAlpha[1] * i) * (1.0f / 5.0f); fAlpha[6] = 0.0f; fAlpha[7] = 1.0f; } DWORD dw = pBC3->bitmap[0] | (pBC3->bitmap[1] << 8) | (pBC3->bitmap[2] << 16); for(size_t i = 0; i < 8; ++i, dw >>= 3) pColor[i] = XMVectorSetW( pColor[i], fAlpha[dw & 0x7] ); dw = pBC3->bitmap[3] | (pBC3->bitmap[4] << 8) | (pBC3->bitmap[5] << 16); for(size_t i = 8; i < NUM_PIXELS_PER_BLOCK; ++i, dw >>= 3) pColor[i] = XMVectorSetW( pColor[i], fAlpha[dw & 0x7] ); } _Use_decl_annotations_ void D3DXEncodeBC3(uint8_t *pBC, const XMVECTOR *pColor, DWORD flags) { assert( pBC && pColor ); static_assert( sizeof(D3DX_BC3) == 16, "D3DX_BC3 should be 16 bytes" ); HDRColorA Color[NUM_PIXELS_PER_BLOCK]; for(size_t i = 0; i < NUM_PIXELS_PER_BLOCK; ++i) { XMStoreFloat4( reinterpret_cast( &Color[i] ), pColor[i] ); } auto pBC3 = reinterpret_cast(pBC); // Quantize block to A8, using Floyd Stienberg error diffusion. This // increases the chance that colors will map directly to the quantized // axis endpoints. float fAlpha[NUM_PIXELS_PER_BLOCK]; float fError[NUM_PIXELS_PER_BLOCK]; float fMinAlpha = Color[0].a; float fMaxAlpha = Color[0].a; if (flags & BC_FLAGS_DITHER_A) memset(fError, 0x00, NUM_PIXELS_PER_BLOCK * sizeof(float)); for(size_t i = 0; i < NUM_PIXELS_PER_BLOCK; ++i) { float fAlph = Color[i].a; if (flags & BC_FLAGS_DITHER_A) fAlph += fError[i]; fAlpha[i] = static_cast(fAlph * 255.0f + 0.5f) * (1.0f / 255.0f); if(fAlpha[i] < fMinAlpha) fMinAlpha = fAlpha[i]; else if(fAlpha[i] > fMaxAlpha) fMaxAlpha = fAlpha[i]; if (flags & BC_FLAGS_DITHER_A) { float fDiff = fAlph - fAlpha[i]; if(3 != (i & 3)) { assert( i < 15 ); _Analysis_assume_( i < 15 ); fError[i + 1] += fDiff * (7.0f / 16.0f); } if(i < 12) { if(i & 3) fError[i + 3] += fDiff * (3.0f / 16.0f); fError[i + 4] += fDiff * (5.0f / 16.0f); if(3 != (i & 3)) { assert( i < 11 ); _Analysis_assume_( i < 11 ); fError[i + 5] += fDiff * (1.0f / 16.0f); } } } } #ifdef COLOR_WEIGHTS if(0.0f == fMaxAlpha) { EncodeSolidBC1(&pBC3->dxt1, Color); pBC3->alpha[0] = 0x00; pBC3->alpha[1] = 0x00; memset(pBC3->bitmap, 0x00, 6); } #endif // RGB part EncodeBC1(&pBC3->bc1, Color, false, 0.f, flags); // Alpha part if(1.0f == fMinAlpha) { pBC3->alpha[0] = 0xff; pBC3->alpha[1] = 0xff; memset(pBC3->bitmap, 0x00, 6); return; } // Optimize and Quantize Min and Max values size_t uSteps = ((0.0f == fMinAlpha) || (1.0f == fMaxAlpha)) ? 6 : 8; float fAlphaA, fAlphaB; OptimizeAlpha(&fAlphaA, &fAlphaB, fAlpha, uSteps); uint8_t bAlphaA = (uint8_t) static_cast(fAlphaA * 255.0f + 0.5f); uint8_t bAlphaB = (uint8_t) static_cast(fAlphaB * 255.0f + 0.5f); fAlphaA = (float) bAlphaA * (1.0f / 255.0f); fAlphaB = (float) bAlphaB * (1.0f / 255.0f); // Setup block if((8 == uSteps) && (bAlphaA == bAlphaB)) { pBC3->alpha[0] = bAlphaA; pBC3->alpha[1] = bAlphaB; memset(pBC3->bitmap, 0x00, 6); return; } static const size_t pSteps6[] = { 0, 2, 3, 4, 5, 1 }; static const size_t pSteps8[] = { 0, 2, 3, 4, 5, 6, 7, 1 }; const size_t *pSteps; float fStep[8]; if(6 == uSteps) { pBC3->alpha[0] = bAlphaA; pBC3->alpha[1] = bAlphaB; fStep[0] = fAlphaA; fStep[1] = fAlphaB; for(size_t i = 1; i < 5; ++i) fStep[i + 1] = (fStep[0] * (5 - i) + fStep[1] * i) * (1.0f / 5.0f); fStep[6] = 0.0f; fStep[7] = 1.0f; pSteps = pSteps6; } else { pBC3->alpha[0] = bAlphaB; pBC3->alpha[1] = bAlphaA; fStep[0] = fAlphaB; fStep[1] = fAlphaA; for(size_t i = 1; i < 7; ++i) fStep[i + 1] = (fStep[0] * (7 - i) + fStep[1] * i) * (1.0f / 7.0f); pSteps = pSteps8; } // Encode alpha bitmap float fSteps = (float) (uSteps - 1); float fScale = (fStep[0] != fStep[1]) ? (fSteps / (fStep[1] - fStep[0])) : 0.0f; if (flags & BC_FLAGS_DITHER_A) memset(fError, 0x00, NUM_PIXELS_PER_BLOCK * sizeof(float)); for(size_t iSet = 0; iSet < 2; iSet++) { uint32_t dw = 0; size_t iMin = iSet * 8; size_t iLim = iMin + 8; for(size_t i = iMin; i < iLim; ++i) { float fAlph = Color[i].a; if (flags & BC_FLAGS_DITHER_A) fAlph += fError[i]; float fDot = (fAlph - fStep[0]) * fScale; uint32_t iStep; if(fDot <= 0.0f) iStep = ((6 == uSteps) && (fAlph <= fStep[0] * 0.5f)) ? 6 : 0; else if(fDot >= fSteps) iStep = ((6 == uSteps) && (fAlph >= (fStep[1] + 1.0f) * 0.5f)) ? 7 : 1; else iStep = static_cast( pSteps[static_cast(fDot + 0.5f)] ); dw = (iStep << 21) | (dw >> 3); if (flags & BC_FLAGS_DITHER_A) { float fDiff = (fAlph - fStep[iStep]); if(3 != (i & 3)) fError[i + 1] += fDiff * (7.0f / 16.0f); if(i < 12) { if(i & 3) fError[i + 3] += fDiff * (3.0f / 16.0f); fError[i + 4] += fDiff * (5.0f / 16.0f); if(3 != (i & 3)) fError[i + 5] += fDiff * (1.0f / 16.0f); } } } pBC3->bitmap[0 + iSet * 3] = ((uint8_t *) &dw)[0]; pBC3->bitmap[1 + iSet * 3] = ((uint8_t *) &dw)[1]; pBC3->bitmap[2 + iSet * 3] = ((uint8_t *) &dw)[2]; } } } // namespace ================================================ FILE: 3rdParty/DirectXTex/DirectXTex/BC.h ================================================ //------------------------------------------------------------------------------------- // BC.h // // Block-compression (BC) functionality // // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A // PARTICULAR PURPOSE. // // Copyright (c) Microsoft Corporation. All rights reserved. // // http://go.microsoft.com/fwlink/?LinkId=248926 //------------------------------------------------------------------------------------- #pragma once #include #include #include namespace DirectX { //------------------------------------------------------------------------------------- // Constants //------------------------------------------------------------------------------------- const uint16_t F16S_MASK = 0x8000; // f16 sign mask const uint16_t F16EM_MASK = 0x7fff; // f16 exp & mantissa mask const uint16_t F16MAX = 0x7bff; // MAXFLT bit pattern for XMHALF #define SIGN_EXTEND(x,nb) ((((x)&(1<<((nb)-1)))?((~0)<<(nb)):0)|(x)) // Because these are used in SAL annotations, they need to remain macros rather than const values #define NUM_PIXELS_PER_BLOCK 16 #define BC6H_MAX_REGIONS 2 #define BC6H_MAX_INDICES 16 #define BC7_MAX_REGIONS 3 #define BC7_MAX_INDICES 16 const size_t BC6H_NUM_CHANNELS = 3; const size_t BC6H_MAX_SHAPES = 32; const size_t BC7_NUM_CHANNELS = 4; const size_t BC7_MAX_SHAPES = 64; const int32_t BC67_WEIGHT_MAX = 64; const uint32_t BC67_WEIGHT_SHIFT = 6; const int32_t BC67_WEIGHT_ROUND = 32; extern const int g_aWeights2[4]; extern const int g_aWeights3[8]; extern const int g_aWeights4[16]; enum BC_FLAGS { BC_FLAGS_NONE = 0x0, BC_FLAGS_DITHER_RGB = 0x10000, // Enables dithering for RGB colors for BC1-3 BC_FLAGS_DITHER_A = 0x20000, // Enables dithering for Alpha channel for BC1-3 BC_FLAGS_UNIFORM = 0x40000, // By default, uses perceptual weighting for BC1-3; this flag makes it a uniform weighting BC_FLAGS_USE_3SUBSETS = 0x80000,// By default, BC7 skips mode 0 & 2; this flag adds those modes back }; //------------------------------------------------------------------------------------- // Structures //------------------------------------------------------------------------------------- class HDRColorA; class LDRColorA { public: uint8_t r, g, b, a; LDRColorA() DIRECTX_CTOR_DEFAULT LDRColorA(uint8_t _r, uint8_t _g, uint8_t _b, uint8_t _a) : r(_r), g(_g), b(_b), a(_a) {} const uint8_t& operator [] (_In_range_(0,3) size_t uElement) const { switch(uElement) { case 0: return r; case 1: return g; case 2: return b; case 3: return a; default: assert(false); return r; } } uint8_t& operator [] (_In_range_(0,3) size_t uElement) { switch(uElement) { case 0: return r; case 1: return g; case 2: return b; case 3: return a; default: assert(false); return r; } } LDRColorA operator = (_In_ const HDRColorA& c); static void InterpolateRGB(_In_ const LDRColorA& c0, _In_ const LDRColorA& c1, _In_ size_t wc, _In_ _In_range_(2, 4) size_t wcprec, _Out_ LDRColorA& out) { const int* aWeights = nullptr; switch(wcprec) { case 2: aWeights = g_aWeights2; assert( wc < 4 ); _Analysis_assume_( wc < 4 ); break; case 3: aWeights = g_aWeights3; assert( wc < 8 ); _Analysis_assume_( wc < 8 ); break; case 4: aWeights = g_aWeights4; assert( wc < 16 ); _Analysis_assume_( wc < 16 ); break; default: assert(false); out.r = out.g = out.b = 0; return; } out.r = uint8_t((uint32_t(c0.r) * uint32_t(BC67_WEIGHT_MAX - aWeights[wc]) + uint32_t(c1.r) * uint32_t(aWeights[wc]) + BC67_WEIGHT_ROUND) >> BC67_WEIGHT_SHIFT); out.g = uint8_t((uint32_t(c0.g) * uint32_t(BC67_WEIGHT_MAX - aWeights[wc]) + uint32_t(c1.g) * uint32_t(aWeights[wc]) + BC67_WEIGHT_ROUND) >> BC67_WEIGHT_SHIFT); out.b = uint8_t((uint32_t(c0.b) * uint32_t(BC67_WEIGHT_MAX - aWeights[wc]) + uint32_t(c1.b) * uint32_t(aWeights[wc]) + BC67_WEIGHT_ROUND) >> BC67_WEIGHT_SHIFT); } static void InterpolateA(_In_ const LDRColorA& c0, _In_ const LDRColorA& c1, _In_ size_t wa, _In_range_(2, 4) _In_ size_t waprec, _Out_ LDRColorA& out) { const int* aWeights = nullptr; switch(waprec) { case 2: aWeights = g_aWeights2; assert( wa < 4 ); _Analysis_assume_( wa < 4 ); break; case 3: aWeights = g_aWeights3; assert( wa < 8 ); _Analysis_assume_( wa < 8 ); break; case 4: aWeights = g_aWeights4; assert( wa < 16 ); _Analysis_assume_( wa < 16 ); break; default: assert(false); out.a = 0; return; } out.a = uint8_t((uint32_t(c0.a) * uint32_t(BC67_WEIGHT_MAX - aWeights[wa]) + uint32_t(c1.a) * uint32_t(aWeights[wa]) + BC67_WEIGHT_ROUND) >> BC67_WEIGHT_SHIFT); } static void Interpolate(_In_ const LDRColorA& c0, _In_ const LDRColorA& c1, _In_ size_t wc, _In_ size_t wa, _In_ _In_range_(2, 4) size_t wcprec, _In_ _In_range_(2, 4) size_t waprec, _Out_ LDRColorA& out) { InterpolateRGB(c0, c1, wc, wcprec, out); InterpolateA(c0, c1, wa, waprec, out); } }; static_assert( sizeof(LDRColorA) == 4, "Unexpected packing"); class HDRColorA { public: float r, g, b, a; public: HDRColorA() DIRECTX_CTOR_DEFAULT HDRColorA(float _r, float _g, float _b, float _a) : r(_r), g(_g), b(_b), a(_a) {} HDRColorA(const HDRColorA& c) : r(c.r), g(c.g), b(c.b), a(c.a) {} HDRColorA(const LDRColorA& c) { r = float(c.r) * (1.0f/255.0f); g = float(c.g) * (1.0f/255.0f); b = float(c.b) * (1.0f/255.0f); a = float(c.a) * (1.0f/255.0f); } // binary operators HDRColorA operator + ( _In_ const HDRColorA& c ) const { return HDRColorA(r + c.r, g + c.g, b + c.b, a + c.a); } HDRColorA operator - ( _In_ const HDRColorA& c ) const { return HDRColorA(r - c.r, g - c.g, b - c.b, a - c.a); } HDRColorA operator * ( _In_ float f ) const { return HDRColorA(r * f, g * f, b * f, a * f); } HDRColorA operator / ( _In_ float f ) const { float fInv = 1.0f / f; return HDRColorA(r * fInv, g * fInv, b * fInv, a * fInv); } float operator * ( _In_ const HDRColorA& c ) const { return r * c.r + g * c.g + b * c.b + a * c.a; } // assignment operators HDRColorA& operator += ( _In_ const HDRColorA& c ) { r += c.r; g += c.g; b += c.b; a += c.a; return *this; } HDRColorA& operator -= ( _In_ const HDRColorA& c ) { r -= c.r; g -= c.g; b -= c.b; a -= c.a; return *this; } HDRColorA& operator *= ( _In_ float f ) { r *= f; g *= f; b *= f; a *= f; return *this; } HDRColorA& operator /= ( _In_ float f ) { float fInv = 1.0f / f; r *= fInv; g *= fInv; b *= fInv; a *= fInv; return *this; } HDRColorA& operator = (_In_ const LDRColorA& c) { r = (float) c.r; g = (float) c.g; b = (float) c.b; a = (float) c.a; return *this; } HDRColorA& Clamp(_In_ float fMin, _In_ float fMax) { r = std::min(fMax, std::max(fMin, r)); g = std::min(fMax, std::max(fMin, g)); b = std::min(fMax, std::max(fMin, b)); a = std::min(fMax, std::max(fMin, a)); return *this; } LDRColorA ToLDRColorA() const { return LDRColorA((uint8_t) (r + 0.01f), (uint8_t) (g + 0.01f), (uint8_t) (b + 0.01f), (uint8_t) (a + 0.01f)); } }; inline LDRColorA LDRColorA::operator = (_In_ const HDRColorA& c) { LDRColorA ret; HDRColorA tmp(c); tmp = tmp.Clamp(0.0f, 1.0f) * 255.0f; ret.r = uint8_t(tmp.r + 0.001f); ret.g = uint8_t(tmp.g + 0.001f); ret.b = uint8_t(tmp.b + 0.001f); ret.a = uint8_t(tmp.a + 0.001f); return ret; } struct LDREndPntPair { LDRColorA A; LDRColorA B; }; struct HDREndPntPair { HDRColorA A; HDRColorA B; }; inline HDRColorA* HDRColorALerp(_Out_ HDRColorA *pOut, _In_ const HDRColorA *pC1, _In_ const HDRColorA *pC2, _In_ float s) { pOut->r = pC1->r + s * (pC2->r - pC1->r); pOut->g = pC1->g + s * (pC2->g - pC1->g); pOut->b = pC1->b + s * (pC2->b - pC1->b); pOut->a = pC1->a + s * (pC2->a - pC1->a); return pOut; } #pragma pack(push,1) // BC1/DXT1 compression (4 bits per texel) struct D3DX_BC1 { uint16_t rgb[2]; // 565 colors uint32_t bitmap; // 2bpp rgb bitmap }; // BC2/DXT2/3 compression (8 bits per texel) struct D3DX_BC2 { uint32_t bitmap[2]; // 4bpp alpha bitmap D3DX_BC1 bc1; // BC1 rgb data }; // BC3/DXT4/5 compression (8 bits per texel) struct D3DX_BC3 { uint8_t alpha[2]; // alpha values uint8_t bitmap[6]; // 3bpp alpha bitmap D3DX_BC1 bc1; // BC1 rgb data }; #pragma pack(pop) class INTColor { public: int r, g, b; int pad; public: INTColor() DIRECTX_CTOR_DEFAULT INTColor(int nr, int ng, int nb) {r = nr; g = ng; b = nb;} INTColor(const INTColor& c) {r = c.r; g = c.g; b = c.b;} INTColor operator - ( _In_ const INTColor& c ) const { return INTColor(r - c.r, g - c.g, b - c.b); } INTColor& operator += ( _In_ const INTColor& c ) { r += c.r; g += c.g; b += c.b; return *this; } INTColor& operator -= ( _In_ const INTColor& c ) { r -= c.r; g -= c.g; b -= c.b; return *this; } INTColor& operator &= ( _In_ const INTColor& c ) { r &= c.r; g &= c.g; b &= c.b; return *this; } int& operator [] ( _In_ uint8_t i ) { assert(i < sizeof(INTColor) / sizeof(int)); _Analysis_assume_(i < sizeof(INTColor) / sizeof(int)); return ((int*) this)[i]; } void Set(_In_ const HDRColorA& c, _In_ bool bSigned) { PackedVector::XMHALF4 aF16; XMVECTOR v = XMLoadFloat4( (const XMFLOAT4*)& c ); XMStoreHalf4( &aF16, v ); r = F16ToINT(aF16.x, bSigned); g = F16ToINT(aF16.y, bSigned); b = F16ToINT(aF16.z, bSigned); } INTColor& Clamp(_In_ int iMin, _In_ int iMax) { r = std::min(iMax, std::max(iMin, r)); g = std::min(iMax, std::max(iMin, g)); b = std::min(iMax, std::max(iMin, b)); return *this; } INTColor& SignExtend(_In_ const LDRColorA& Prec) { r = SIGN_EXTEND(r, Prec.r); g = SIGN_EXTEND(g, Prec.g); b = SIGN_EXTEND(b, Prec.b); return *this; } void ToF16(_Out_writes_(3) PackedVector::HALF aF16[3], _In_ bool bSigned) const { aF16[0] = INT2F16(r, bSigned); aF16[1] = INT2F16(g, bSigned); aF16[2] = INT2F16(b, bSigned); } private: static int F16ToINT(_In_ const PackedVector::HALF& f, _In_ bool bSigned) { uint16_t input = *((const uint16_t*) &f); int out, s; if(bSigned) { s = input & F16S_MASK; input &= F16EM_MASK; if(input > F16MAX) out = F16MAX; else out = input; out = s ? -out : out; } else { if(input & F16S_MASK) out = 0; else out = input; } return out; } static PackedVector::HALF INT2F16(_In_ int input, _In_ bool bSigned) { PackedVector::HALF h; uint16_t out; if(bSigned) { int s = 0; if(input < 0) { s = F16S_MASK; input = -input; } out = uint16_t(s | input); } else { assert(input >= 0 && input <= F16MAX); out = (uint16_t) input; } *((uint16_t*) &h) = out; return h; } }; static_assert( sizeof(INTColor) == 16, "Unexpected packing"); struct INTEndPntPair { INTColor A; INTColor B; }; template< size_t SizeInBytes > class CBits { public: uint8_t GetBit(_Inout_ size_t& uStartBit) const { assert(uStartBit < 128); _Analysis_assume_(uStartBit < 128); size_t uIndex = uStartBit >> 3; uint8_t ret = (m_uBits[uIndex] >> (uStartBit - (uIndex << 3))) & 0x01; uStartBit++; return ret; } uint8_t GetBits(_Inout_ size_t& uStartBit, _In_ size_t uNumBits) const { if(uNumBits == 0) return 0; assert(uStartBit + uNumBits <= 128 && uNumBits <= 8); _Analysis_assume_(uStartBit + uNumBits <= 128 && uNumBits <= 8); uint8_t ret; size_t uIndex = uStartBit >> 3; size_t uBase = uStartBit - (uIndex << 3); if(uBase + uNumBits > 8) { size_t uFirstIndexBits = 8 - uBase; size_t uNextIndexBits = uNumBits - uFirstIndexBits; ret = (m_uBits[uIndex] >> uBase) | ((m_uBits[uIndex+1] & ((1 << uNextIndexBits) - 1)) << uFirstIndexBits); } else { ret = (m_uBits[uIndex] >> uBase) & ((1 << uNumBits) - 1); } assert(ret < (1 << uNumBits)); uStartBit += uNumBits; return ret; } void SetBit(_Inout_ size_t& uStartBit, _In_ uint8_t uValue) { assert(uStartBit < 128 && uValue < 2); _Analysis_assume_(uStartBit < 128 && uValue < 2); size_t uIndex = uStartBit >> 3; size_t uBase = uStartBit - (uIndex << 3); m_uBits[uIndex] &= ~(1 << uBase); m_uBits[uIndex] |= uValue << uBase; uStartBit++; } void SetBits(_Inout_ size_t& uStartBit, _In_ size_t uNumBits, _In_ uint8_t uValue) { if(uNumBits == 0) return; assert(uStartBit + uNumBits <= 128 && uNumBits <= 8); _Analysis_assume_(uStartBit + uNumBits <= 128 && uNumBits <= 8); assert(uValue < (1 << uNumBits)); size_t uIndex = uStartBit >> 3; size_t uBase = uStartBit - (uIndex << 3); if(uBase + uNumBits > 8) { size_t uFirstIndexBits = 8 - uBase; size_t uNextIndexBits = uNumBits - uFirstIndexBits; m_uBits[uIndex] &= ~(((1 << uFirstIndexBits) - 1) << uBase); m_uBits[uIndex] |= uValue << uBase; m_uBits[uIndex+1] &= ~((1 << uNextIndexBits) - 1); m_uBits[uIndex+1] |= uValue >> uFirstIndexBits; } else { m_uBits[uIndex] &= ~(((1 << uNumBits) - 1) << uBase); m_uBits[uIndex] |= uValue << uBase; } uStartBit += uNumBits; } private: uint8_t m_uBits[ SizeInBytes ]; }; // BC6H compression (16 bits per texel) class D3DX_BC6H : private CBits< 16 > { public: void Decode(_In_ bool bSigned, _Out_writes_(NUM_PIXELS_PER_BLOCK) HDRColorA* pOut) const; void Encode(_In_ bool bSigned, _In_reads_(NUM_PIXELS_PER_BLOCK) const HDRColorA* const pIn); private: #pragma warning(push) #pragma warning(disable : 4480) enum EField : uint8_t { NA, // N/A M, // Mode D, // Shape RW, RX, RY, RZ, GW, GX, GY, GZ, BW, BX, BY, BZ, }; #pragma warning(pop) struct ModeDescriptor { EField m_eField; uint8_t m_uBit; }; struct ModeInfo { uint8_t uMode; uint8_t uPartitions; bool bTransformed; uint8_t uIndexPrec; LDRColorA RGBAPrec[BC6H_MAX_REGIONS][2]; }; #pragma warning(push) #pragma warning(disable : 4512) struct EncodeParams { float fBestErr; const bool bSigned; uint8_t uMode; uint8_t uShape; const HDRColorA* const aHDRPixels; INTEndPntPair aUnqEndPts[BC6H_MAX_SHAPES][BC6H_MAX_REGIONS]; INTColor aIPixels[NUM_PIXELS_PER_BLOCK]; EncodeParams(const HDRColorA* const aOriginal, bool bSignedFormat) : aHDRPixels(aOriginal), fBestErr(FLT_MAX), bSigned(bSignedFormat) { for(size_t i = 0; i < NUM_PIXELS_PER_BLOCK; ++i) { aIPixels[i].Set(aOriginal[i], bSigned); } } }; #pragma warning(pop) static int Quantize(_In_ int iValue, _In_ int prec, _In_ bool bSigned); static int Unquantize(_In_ int comp, _In_ uint8_t uBitsPerComp, _In_ bool bSigned); static int FinishUnquantize(_In_ int comp, _In_ bool bSigned); static bool EndPointsFit(_In_ const EncodeParams* pEP, _In_reads_(BC6H_MAX_REGIONS) const INTEndPntPair aEndPts[]); void GeneratePaletteQuantized(_In_ const EncodeParams* pEP, _In_ const INTEndPntPair& endPts, _Out_writes_(BC6H_MAX_INDICES) INTColor aPalette[]) const; float MapColorsQuantized(_In_ const EncodeParams* pEP, _In_reads_(np) const INTColor aColors[], _In_ size_t np, _In_ const INTEndPntPair &endPts) const; float PerturbOne(_In_ const EncodeParams* pEP, _In_reads_(np) const INTColor aColors[], _In_ size_t np, _In_ uint8_t ch, _In_ const INTEndPntPair& oldEndPts, _Out_ INTEndPntPair& newEndPts, _In_ float fOldErr, _In_ int do_b) const; void OptimizeOne(_In_ const EncodeParams* pEP, _In_reads_(np) const INTColor aColors[], _In_ size_t np, _In_ float aOrgErr, _In_ const INTEndPntPair &aOrgEndPts, _Out_ INTEndPntPair &aOptEndPts) const; void OptimizeEndPoints(_In_ const EncodeParams* pEP, _In_reads_(BC6H_MAX_REGIONS) const float aOrgErr[], _In_reads_(BC6H_MAX_REGIONS) const INTEndPntPair aOrgEndPts[], _Out_writes_all_(BC6H_MAX_REGIONS) INTEndPntPair aOptEndPts[]) const; static void SwapIndices(_In_ const EncodeParams* pEP, _Inout_updates_all_(BC6H_MAX_REGIONS) INTEndPntPair aEndPts[], _In_reads_(NUM_PIXELS_PER_BLOCK) size_t aIndices[]); void AssignIndices(_In_ const EncodeParams* pEP, _In_reads_(BC6H_MAX_REGIONS) const INTEndPntPair aEndPts[], _Out_writes_(NUM_PIXELS_PER_BLOCK) size_t aIndices[], _Out_writes_(BC6H_MAX_REGIONS) float aTotErr[]) const; void QuantizeEndPts(_In_ const EncodeParams* pEP, _Out_writes_(BC6H_MAX_REGIONS) INTEndPntPair* qQntEndPts) const; void EmitBlock(_In_ const EncodeParams* pEP, _In_reads_(BC6H_MAX_REGIONS) const INTEndPntPair aEndPts[], _In_reads_(NUM_PIXELS_PER_BLOCK) const size_t aIndices[]); void Refine(_Inout_ EncodeParams* pEP); static void GeneratePaletteUnquantized(_In_ const EncodeParams* pEP, _In_ size_t uRegion, _Out_writes_(BC6H_MAX_INDICES) INTColor aPalette[]); float MapColors(_In_ const EncodeParams* pEP, _In_ size_t uRegion, _In_ size_t np, _In_reads_(np) const size_t* auIndex) const; float RoughMSE(_Inout_ EncodeParams* pEP) const; private: const static ModeDescriptor ms_aDesc[][82]; const static ModeInfo ms_aInfo[]; const static int ms_aModeToInfo[]; }; // BC67 compression (16b bits per texel) class D3DX_BC7 : private CBits< 16 > { public: void Decode(_Out_writes_(NUM_PIXELS_PER_BLOCK) HDRColorA* pOut) const; void Encode(bool skip3subsets, _In_reads_(NUM_PIXELS_PER_BLOCK) const HDRColorA* const pIn); private: struct ModeInfo { uint8_t uPartitions; uint8_t uPartitionBits; uint8_t uPBits; uint8_t uRotationBits; uint8_t uIndexModeBits; uint8_t uIndexPrec; uint8_t uIndexPrec2; LDRColorA RGBAPrec; LDRColorA RGBAPrecWithP; }; #pragma warning(push) #pragma warning(disable : 4512) struct EncodeParams { uint8_t uMode; LDREndPntPair aEndPts[BC7_MAX_SHAPES][BC7_MAX_REGIONS]; LDRColorA aLDRPixels[NUM_PIXELS_PER_BLOCK]; const HDRColorA* const aHDRPixels; EncodeParams(const HDRColorA* const aOriginal) : aHDRPixels(aOriginal) {} }; #pragma warning(pop) static uint8_t Quantize(_In_ uint8_t comp, _In_ uint8_t uPrec) { assert(0 < uPrec && uPrec <= 8); uint8_t rnd = (uint8_t) std::min(255, uint16_t(comp) + (1 << (7 - uPrec))); return rnd >> (8 - uPrec); } static LDRColorA Quantize(_In_ const LDRColorA& c, _In_ const LDRColorA& RGBAPrec) { LDRColorA q; q.r = Quantize(c.r, RGBAPrec.r); q.g = Quantize(c.g, RGBAPrec.g); q.b = Quantize(c.b, RGBAPrec.b); if(RGBAPrec.a) q.a = Quantize(c.a, RGBAPrec.a); else q.a = 255; return q; } static uint8_t Unquantize(_In_ uint8_t comp, _In_ size_t uPrec) { assert(0 < uPrec && uPrec <= 8); comp = comp << (8 - uPrec); return comp | (comp >> uPrec); } static LDRColorA Unquantize(_In_ const LDRColorA& c, _In_ const LDRColorA& RGBAPrec) { LDRColorA q; q.r = Unquantize(c.r, RGBAPrec.r); q.g = Unquantize(c.g, RGBAPrec.g); q.b = Unquantize(c.b, RGBAPrec.b); q.a = RGBAPrec.a > 0 ? Unquantize(c.a, RGBAPrec.a) : 255; return q; } void GeneratePaletteQuantized(_In_ const EncodeParams* pEP, _In_ size_t uIndexMode, _In_ const LDREndPntPair& endpts, _Out_writes_(BC7_MAX_INDICES) LDRColorA aPalette[]) const; float PerturbOne(_In_ const EncodeParams* pEP, _In_reads_(np) const LDRColorA colors[], _In_ size_t np, _In_ size_t uIndexMode, _In_ size_t ch, _In_ const LDREndPntPair &old_endpts, _Out_ LDREndPntPair &new_endpts, _In_ float old_err, _In_ uint8_t do_b) const; void Exhaustive(_In_ const EncodeParams* pEP, _In_reads_(np) const LDRColorA aColors[], _In_ size_t np, _In_ size_t uIndexMode, _In_ size_t ch, _Inout_ float& fOrgErr, _Inout_ LDREndPntPair& optEndPt) const; void OptimizeOne(_In_ const EncodeParams* pEP, _In_reads_(np) const LDRColorA colors[], _In_ size_t np, _In_ size_t uIndexMode, _In_ float orig_err, _In_ const LDREndPntPair &orig_endpts, _Out_ LDREndPntPair &opt_endpts) const; void OptimizeEndPoints(_In_ const EncodeParams* pEP, _In_ size_t uShape, _In_ size_t uIndexMode, _In_reads_(BC7_MAX_REGIONS) const float orig_err[], _In_reads_(BC7_MAX_REGIONS) const LDREndPntPair orig_endpts[], _Out_writes_(BC7_MAX_REGIONS) LDREndPntPair opt_endpts[]) const; void AssignIndices(_In_ const EncodeParams* pEP, _In_ size_t uShape, _In_ size_t uIndexMode, _In_reads_(BC7_MAX_REGIONS) LDREndPntPair endpts[], _Out_writes_(NUM_PIXELS_PER_BLOCK) size_t aIndices[], _Out_writes_(NUM_PIXELS_PER_BLOCK) size_t aIndices2[], _Out_writes_(BC7_MAX_REGIONS) float afTotErr[]) const; void EmitBlock(_In_ const EncodeParams* pEP, _In_ size_t uShape, _In_ size_t uRotation, _In_ size_t uIndexMode, _In_reads_(BC7_MAX_REGIONS) const LDREndPntPair aEndPts[], _In_reads_(NUM_PIXELS_PER_BLOCK) const size_t aIndex[], _In_reads_(NUM_PIXELS_PER_BLOCK) const size_t aIndex2[]); float Refine(_In_ const EncodeParams* pEP, _In_ size_t uShape, _In_ size_t uRotation, _In_ size_t uIndexMode); float MapColors(_In_ const EncodeParams* pEP, _In_reads_(np) const LDRColorA aColors[], _In_ size_t np, _In_ size_t uIndexMode, _In_ const LDREndPntPair& endPts, _In_ float fMinErr) const; static float RoughMSE(_Inout_ EncodeParams* pEP, _In_ size_t uShape, _In_ size_t uIndexMode); private: const static ModeInfo ms_aInfo[]; }; //------------------------------------------------------------------------------------- #pragma warning(push) #pragma warning(disable : 4127) template void OptimizeAlpha(float *pX, float *pY, const float *pPoints, size_t cSteps) { static const float pC6[] = { 5.0f/5.0f, 4.0f/5.0f, 3.0f/5.0f, 2.0f/5.0f, 1.0f/5.0f, 0.0f/5.0f }; static const float pD6[] = { 0.0f/5.0f, 1.0f/5.0f, 2.0f/5.0f, 3.0f/5.0f, 4.0f/5.0f, 5.0f/5.0f }; static const float pC8[] = { 7.0f/7.0f, 6.0f/7.0f, 5.0f/7.0f, 4.0f/7.0f, 3.0f/7.0f, 2.0f/7.0f, 1.0f/7.0f, 0.0f/7.0f }; static const float pD8[] = { 0.0f/7.0f, 1.0f/7.0f, 2.0f/7.0f, 3.0f/7.0f, 4.0f/7.0f, 5.0f/7.0f, 6.0f/7.0f, 7.0f/7.0f }; const float *pC = (6 == cSteps) ? pC6 : pC8; const float *pD = (6 == cSteps) ? pD6 : pD8; float MAX_VALUE = 1.0f; float MIN_VALUE; if (bRange) { MIN_VALUE = -1.0f; } else { MIN_VALUE = 0.0f; } // Find Min and Max points, as starting point float fX = MAX_VALUE; float fY = MIN_VALUE; if(8 == cSteps) { for(size_t iPoint = 0; iPoint < NUM_PIXELS_PER_BLOCK; iPoint++) { if(pPoints[iPoint] < fX) fX = pPoints[iPoint]; if(pPoints[iPoint] > fY) fY = pPoints[iPoint]; } } else { for(size_t iPoint = 0; iPoint < NUM_PIXELS_PER_BLOCK; iPoint++) { if(pPoints[iPoint] < fX && pPoints[iPoint] > MIN_VALUE) fX = pPoints[iPoint]; if(pPoints[iPoint] > fY && pPoints[iPoint] < MAX_VALUE) fY = pPoints[iPoint]; } if (fX == fY) { fY = MAX_VALUE; } } // Use Newton's Method to find local minima of sum-of-squares error. float fSteps = (float) (cSteps - 1); for(size_t iIteration = 0; iIteration < 8; iIteration++) { float fScale; if((fY - fX) < (1.0f / 256.0f)) break; fScale = fSteps / (fY - fX); // Calculate new steps float pSteps[8]; for(size_t iStep = 0; iStep < cSteps; iStep++) pSteps[iStep] = pC[iStep] * fX + pD[iStep] * fY; if(6 == cSteps) { pSteps[6] = MIN_VALUE; pSteps[7] = MAX_VALUE; } // Evaluate function, and derivatives float dX = 0.0f; float dY = 0.0f; float d2X = 0.0f; float d2Y = 0.0f; for(size_t iPoint = 0; iPoint < NUM_PIXELS_PER_BLOCK; iPoint++) { float fDot = (pPoints[iPoint] - fX) * fScale; size_t iStep; if(fDot <= 0.0f) iStep = ((6 == cSteps) && (pPoints[iPoint] <= fX * 0.5f)) ? 6 : 0; else if(fDot >= fSteps) iStep = ((6 == cSteps) && (pPoints[iPoint] >= (fY + 1.0f) * 0.5f)) ? 7 : (cSteps - 1); else iStep = static_cast(fDot + 0.5f); if(iStep < cSteps) { // D3DX had this computation backwards (pPoints[iPoint] - pSteps[iStep]) // this fix improves RMS of the alpha component float fDiff = pSteps[iStep] - pPoints[iPoint]; dX += pC[iStep] * fDiff; d2X += pC[iStep] * pC[iStep]; dY += pD[iStep] * fDiff; d2Y += pD[iStep] * pD[iStep]; } } // Move endpoints if(d2X > 0.0f) fX -= dX / d2X; if(d2Y > 0.0f) fY -= dY / d2Y; if(fX > fY) { float f = fX; fX = fY; fY = f; } if((dX * dX < (1.0f / 64.0f)) && (dY * dY < (1.0f / 64.0f))) break; } *pX = (fX < MIN_VALUE) ? MIN_VALUE : (fX > MAX_VALUE) ? MAX_VALUE : fX; *pY = (fY < MIN_VALUE) ? MIN_VALUE : (fY > MAX_VALUE) ? MAX_VALUE : fY; } #pragma warning(pop) //------------------------------------------------------------------------------------- // Functions //------------------------------------------------------------------------------------- typedef void (*BC_DECODE)(XMVECTOR *pColor, const uint8_t *pBC); typedef void (*BC_ENCODE)(uint8_t *pDXT, const XMVECTOR *pColor, DWORD flags); void D3DXDecodeBC1(_Out_writes_(NUM_PIXELS_PER_BLOCK) XMVECTOR *pColor, _In_reads_(8) const uint8_t *pBC); void D3DXDecodeBC2(_Out_writes_(NUM_PIXELS_PER_BLOCK) XMVECTOR *pColor, _In_reads_(16) const uint8_t *pBC); void D3DXDecodeBC3(_Out_writes_(NUM_PIXELS_PER_BLOCK) XMVECTOR *pColor, _In_reads_(16) const uint8_t *pBC); void D3DXDecodeBC4U(_Out_writes_(NUM_PIXELS_PER_BLOCK) XMVECTOR *pColor, _In_reads_(8) const uint8_t *pBC); void D3DXDecodeBC4S(_Out_writes_(NUM_PIXELS_PER_BLOCK) XMVECTOR *pColor, _In_reads_(8) const uint8_t *pBC); void D3DXDecodeBC5U(_Out_writes_(NUM_PIXELS_PER_BLOCK) XMVECTOR *pColor, _In_reads_(16) const uint8_t *pBC); void D3DXDecodeBC5S(_Out_writes_(NUM_PIXELS_PER_BLOCK) XMVECTOR *pColor, _In_reads_(16) const uint8_t *pBC); void D3DXDecodeBC6HU(_Out_writes_(NUM_PIXELS_PER_BLOCK) XMVECTOR *pColor, _In_reads_(16) const uint8_t *pBC); void D3DXDecodeBC6HS(_Out_writes_(NUM_PIXELS_PER_BLOCK) XMVECTOR *pColor, _In_reads_(16) const uint8_t *pBC); void D3DXDecodeBC7(_Out_writes_(NUM_PIXELS_PER_BLOCK) XMVECTOR *pColor, _In_reads_(16) const uint8_t *pBC); void D3DXEncodeBC1(_Out_writes_(8) uint8_t *pBC, _In_reads_(NUM_PIXELS_PER_BLOCK) const XMVECTOR *pColor, _In_ float alphaRef, _In_ DWORD flags); // BC1 requires one additional parameter, so it doesn't match signature of BC_ENCODE above void D3DXEncodeBC2(_Out_writes_(16) uint8_t *pBC, _In_reads_(NUM_PIXELS_PER_BLOCK) const XMVECTOR *pColor, _In_ DWORD flags); void D3DXEncodeBC3(_Out_writes_(16) uint8_t *pBC, _In_reads_(NUM_PIXELS_PER_BLOCK) const XMVECTOR *pColor, _In_ DWORD flags); void D3DXEncodeBC4U(_Out_writes_(8) uint8_t *pBC, _In_reads_(NUM_PIXELS_PER_BLOCK) const XMVECTOR *pColor, _In_ DWORD flags); void D3DXEncodeBC4S(_Out_writes_(8) uint8_t *pBC, _In_reads_(NUM_PIXELS_PER_BLOCK) const XMVECTOR *pColor, _In_ DWORD flags); void D3DXEncodeBC5U(_Out_writes_(16) uint8_t *pBC, _In_reads_(NUM_PIXELS_PER_BLOCK) const XMVECTOR *pColor, _In_ DWORD flags); void D3DXEncodeBC5S(_Out_writes_(16) uint8_t *pBC, _In_reads_(NUM_PIXELS_PER_BLOCK) const XMVECTOR *pColor, _In_ DWORD flags); void D3DXEncodeBC6HU(_Out_writes_(16) uint8_t *pBC, _In_reads_(NUM_PIXELS_PER_BLOCK) const XMVECTOR *pColor, _In_ DWORD flags); void D3DXEncodeBC6HS(_Out_writes_(16) uint8_t *pBC, _In_reads_(NUM_PIXELS_PER_BLOCK) const XMVECTOR *pColor, _In_ DWORD flags); void D3DXEncodeBC7(_Out_writes_(16) uint8_t *pBC, _In_reads_(NUM_PIXELS_PER_BLOCK) const XMVECTOR *pColor, _In_ DWORD flags); }; // namespace ================================================ FILE: 3rdParty/DirectXTex/DirectXTex/BC4BC5.cpp ================================================ //------------------------------------------------------------------------------------- // BC4BC5.cpp // // Block-compression (BC) functionality for BC4 and BC5 (DirectX 10 texture compression) // // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A // PARTICULAR PURPOSE. // // Copyright (c) Microsoft Corporation. All rights reserved. // // http://go.microsoft.com/fwlink/?LinkId=248926 //------------------------------------------------------------------------------------- #include "directxtexp.h" #include "BC.h" namespace DirectX { //------------------------------------------------------------------------------------ // Constants //------------------------------------------------------------------------------------ // Because these are used in SAL annotations, they need to remain macros rather than const values #define BLOCK_LEN 4 // length of each block in texel #define BLOCK_SIZE (BLOCK_LEN * BLOCK_LEN) // total texels in a 4x4 block. //------------------------------------------------------------------------------------ // Structures //------------------------------------------------------------------------------------- #pragma warning(push) #pragma warning(disable : 4201) // BC4U/BC5U struct BC4_UNORM { float R(size_t uOffset) const { size_t uIndex = GetIndex(uOffset); return DecodeFromIndex(uIndex); } float DecodeFromIndex(size_t uIndex) const { if (uIndex == 0) return red_0 / 255.0f; if (uIndex == 1) return red_1 / 255.0f; float fred_0 = red_0 / 255.0f; float fred_1 = red_1 / 255.0f; if (red_0 > red_1) { uIndex -= 1; return (fred_0 * (7-uIndex) + fred_1 * uIndex) / 7.0f; } else { if (uIndex == 6) return 0.0f; if (uIndex == 7) return 1.0f; uIndex -= 1; return (fred_0 * (5-uIndex) + fred_1 * uIndex) / 5.0f; } } size_t GetIndex(size_t uOffset) const { return (size_t) ((data >> (3*uOffset + 16)) & 0x07); } void SetIndex(size_t uOffset, size_t uIndex) { data &= ~((uint64_t) 0x07 << (3*uOffset + 16)); data |= ((uint64_t) uIndex << (3*uOffset + 16)); } union { struct { uint8_t red_0; uint8_t red_1; uint8_t indices[6]; }; uint64_t data; }; }; // BC4S/BC5S struct BC4_SNORM { float R(size_t uOffset) const { size_t uIndex = GetIndex(uOffset); return DecodeFromIndex(uIndex); } float DecodeFromIndex(size_t uIndex) const { int8_t sred_0 = (red_0 == -128)? -127 : red_0; int8_t sred_1 = (red_1 == -128)? -127 : red_1; if (uIndex == 0) return sred_0 / 127.0f; if (uIndex == 1) return sred_1 / 127.0f; float fred_0 = sred_0 / 127.0f; float fred_1 = sred_1 / 127.0f; if (red_0 > red_1) { uIndex -= 1; return (fred_0 * (7-uIndex) + fred_1 * uIndex) / 7.0f; } else { if (uIndex == 6) return -1.0f; if (uIndex == 7) return 1.0f; uIndex -= 1; return (fred_0 * (5-uIndex) + fred_1 * uIndex) / 5.0f; } } size_t GetIndex(size_t uOffset) const { return (size_t) ((data >> (3*uOffset + 16)) & 0x07); } void SetIndex(size_t uOffset, size_t uIndex) { data &= ~((uint64_t) 0x07 << (3*uOffset + 16)); data |= ((uint64_t) uIndex << (3*uOffset + 16)); } union { struct { int8_t red_0; int8_t red_1; uint8_t indices[6]; }; uint64_t data; }; }; #pragma warning(pop) //------------------------------------------------------------------------------------- // Convert a floating point value to an 8-bit SNORM //------------------------------------------------------------------------------------- static void inline FloatToSNorm( _In_ float fVal, _Out_ int8_t *piSNorm ) { const uint32_t dwMostNeg = ( 1 << ( 8 * sizeof( int8_t ) - 1 ) ); if( _isnan( fVal ) ) fVal = 0; else if( fVal > 1 ) fVal = 1; // Clamp to 1 else if( fVal < -1 ) fVal = -1; // Clamp to -1 fVal = fVal * (int8_t) ( dwMostNeg - 1 ); if( fVal >= 0 ) fVal += .5f; else fVal -= .5f; *piSNorm = (int8_t) (fVal); } //------------------------------------------------------------------------------ static void FindEndPointsBC4U( _In_reads_(BLOCK_SIZE) const float theTexelsU[], _Out_ uint8_t &endpointU_0, _Out_ uint8_t &endpointU_1) { // The boundary of codec for signed/unsigned format float MIN_NORM; float MAX_NORM = 1.0f; int8_t iStart, iEnd; size_t i; MIN_NORM = 0.0f; // Find max/min of input texels float fBlockMax = theTexelsU[0]; float fBlockMin = theTexelsU[0]; for (i = 0; i < BLOCK_SIZE; ++i) { if (theTexelsU[i]fBlockMax) { fBlockMax = theTexelsU[i]; } } // If there are boundary values in input texels, Should use 4 block-codec to guarantee // the exact code of the boundary values. bool bUsing4BlockCodec = ( MIN_NORM == fBlockMin || MAX_NORM == fBlockMax ); // Using Optimize float fStart, fEnd; if (!bUsing4BlockCodec) { OptimizeAlpha(&fStart, &fEnd, theTexelsU, 8); iStart = (uint8_t) (fStart * 255.0f); iEnd = (uint8_t) (fEnd * 255.0f); endpointU_0 = iEnd; endpointU_1 = iStart; } else { OptimizeAlpha(&fStart, &fEnd, theTexelsU, 6); iStart = (uint8_t) (fStart * 255.0f); iEnd = (uint8_t) (fEnd * 255.0f); endpointU_1 = iEnd; endpointU_0 = iStart; } } static void FindEndPointsBC4S(_In_reads_(BLOCK_SIZE) const float theTexelsU[], _Out_ int8_t &endpointU_0, _Out_ int8_t &endpointU_1) { // The boundary of codec for signed/unsigned format float MIN_NORM; float MAX_NORM = 1.0f; int8_t iStart, iEnd; size_t i; MIN_NORM = -1.0f; // Find max/min of input texels float fBlockMax = theTexelsU[0]; float fBlockMin = theTexelsU[0]; for (i = 0; i < BLOCK_SIZE; ++i) { if (theTexelsU[i]fBlockMax) { fBlockMax = theTexelsU[i]; } } // If there are boundary values in input texels, Should use 4 block-codec to guarantee // the exact code of the boundary values. bool bUsing4BlockCodec = ( MIN_NORM == fBlockMin || MAX_NORM == fBlockMax ); // Using Optimize float fStart, fEnd; if (!bUsing4BlockCodec) { OptimizeAlpha(&fStart, &fEnd, theTexelsU, 8); FloatToSNorm(fStart, &iStart); FloatToSNorm(fEnd, &iEnd); endpointU_0 = iEnd; endpointU_1 = iStart; } else { OptimizeAlpha(&fStart, &fEnd, theTexelsU, 6); FloatToSNorm(fStart, &iStart); FloatToSNorm(fEnd, &iEnd); endpointU_1 = iEnd; endpointU_0 = iStart; } } //------------------------------------------------------------------------------ static inline void FindEndPointsBC5U( _In_reads_(BLOCK_SIZE) const float theTexelsU[], _In_reads_(BLOCK_SIZE) const float theTexelsV[], _Out_ uint8_t &endpointU_0, _Out_ uint8_t &endpointU_1, _Out_ uint8_t &endpointV_0, _Out_ uint8_t &endpointV_1) { //Encoding the U and V channel by BC4 codec separately. FindEndPointsBC4U( theTexelsU, endpointU_0, endpointU_1); FindEndPointsBC4U( theTexelsV, endpointV_0, endpointV_1); } static inline void FindEndPointsBC5S( _In_reads_(BLOCK_SIZE) const float theTexelsU[], _In_reads_(BLOCK_SIZE) const float theTexelsV[], _Out_ int8_t &endpointU_0, _Out_ int8_t &endpointU_1, _Out_ int8_t &endpointV_0, _Out_ int8_t &endpointV_1) { //Encoding the U and V channel by BC4 codec separately. FindEndPointsBC4S( theTexelsU, endpointU_0, endpointU_1); FindEndPointsBC4S( theTexelsV, endpointV_0, endpointV_1); } //------------------------------------------------------------------------------ static void FindClosestUNORM(_Inout_ BC4_UNORM* pBC, _In_reads_(NUM_PIXELS_PER_BLOCK) const float theTexelsU[]) { float rGradient[8]; int i; for (i = 0; i < 8; ++i) { rGradient[i] = pBC->DecodeFromIndex(i); } for (i = 0; i < NUM_PIXELS_PER_BLOCK; ++i) { size_t uBestIndex = 0; float fBestDelta = 100000; for (size_t uIndex = 0; uIndex < 8; uIndex++) { float fCurrentDelta = fabsf(rGradient[uIndex]-theTexelsU[i]); if (fCurrentDelta < fBestDelta) { uBestIndex = uIndex; fBestDelta = fCurrentDelta; } } pBC->SetIndex(i, uBestIndex); } } static void FindClosestSNORM(_Inout_ BC4_SNORM* pBC, _In_reads_(NUM_PIXELS_PER_BLOCK) const float theTexelsU[]) { float rGradient[8]; int i; for (i = 0; i < 8; ++i) { rGradient[i] = pBC->DecodeFromIndex(i); } for (i = 0; i < NUM_PIXELS_PER_BLOCK; ++i) { size_t uBestIndex = 0; float fBestDelta = 100000; for (size_t uIndex = 0; uIndex < 8; uIndex++) { float fCurrentDelta = fabsf(rGradient[uIndex]-theTexelsU[i]); if (fCurrentDelta < fBestDelta) { uBestIndex = uIndex; fBestDelta = fCurrentDelta; } } pBC->SetIndex(i, uBestIndex); } } //===================================================================================== // Entry points //===================================================================================== //------------------------------------------------------------------------------------- // BC4 Compression //------------------------------------------------------------------------------------- _Use_decl_annotations_ void D3DXDecodeBC4U( XMVECTOR *pColor, const uint8_t *pBC ) { assert( pColor && pBC ); static_assert( sizeof(BC4_UNORM) == 8, "BC4_UNORM should be 8 bytes" ); auto pBC4 = reinterpret_cast(pBC); for (size_t i = 0; i < NUM_PIXELS_PER_BLOCK; ++i) { #pragma prefast(suppress:22103, "writing blocks in two halves confuses tool") pColor[i] = XMVectorSet( pBC4->R(i), 0, 0, 1.0f); } } _Use_decl_annotations_ void D3DXDecodeBC4S(XMVECTOR *pColor, const uint8_t *pBC) { assert( pColor && pBC ); static_assert( sizeof(BC4_SNORM) == 8, "BC4_SNORM should be 8 bytes" ); auto pBC4 = reinterpret_cast(pBC); for (size_t i = 0; i < NUM_PIXELS_PER_BLOCK; ++i) { #pragma prefast(suppress:22103, "writing blocks in two halves confuses tool") pColor[i] = XMVectorSet( pBC4->R(i), 0, 0, 1.0f); } } _Use_decl_annotations_ void D3DXEncodeBC4U( uint8_t *pBC, const XMVECTOR *pColor, DWORD flags ) { UNREFERENCED_PARAMETER( flags ); assert( pBC && pColor ); static_assert( sizeof(BC4_UNORM) == 8, "BC4_UNORM should be 8 bytes" ); memset(pBC, 0, sizeof(BC4_UNORM)); auto pBC4 = reinterpret_cast(pBC); float theTexelsU[NUM_PIXELS_PER_BLOCK]; for (size_t i = 0; i < NUM_PIXELS_PER_BLOCK; ++i) { theTexelsU[i] = XMVectorGetX( pColor[i] ); } FindEndPointsBC4U(theTexelsU, pBC4->red_0, pBC4->red_1); FindClosestUNORM(pBC4, theTexelsU); } _Use_decl_annotations_ void D3DXEncodeBC4S( uint8_t *pBC, const XMVECTOR *pColor, DWORD flags ) { UNREFERENCED_PARAMETER( flags ); assert( pBC && pColor ); static_assert( sizeof(BC4_SNORM) == 8, "BC4_SNORM should be 8 bytes" ); memset(pBC, 0, sizeof(BC4_UNORM)); auto pBC4 = reinterpret_cast(pBC); float theTexelsU[NUM_PIXELS_PER_BLOCK]; for (size_t i = 0; i < NUM_PIXELS_PER_BLOCK; ++i) { theTexelsU[i] = XMVectorGetX( pColor[i] ); } FindEndPointsBC4S(theTexelsU, pBC4->red_0, pBC4->red_1); FindClosestSNORM(pBC4, theTexelsU); } //------------------------------------------------------------------------------------- // BC5 Compression //------------------------------------------------------------------------------------- _Use_decl_annotations_ void D3DXDecodeBC5U(XMVECTOR *pColor, const uint8_t *pBC) { assert( pColor && pBC ); static_assert( sizeof(BC4_UNORM) == 8, "BC4_UNORM should be 8 bytes" ); auto pBCR = reinterpret_cast(pBC); auto pBCG = reinterpret_cast(pBC+sizeof(BC4_UNORM)); for (size_t i = 0; i < NUM_PIXELS_PER_BLOCK; ++i) { #pragma prefast(suppress:22103, "writing blocks in two halves confuses tool") pColor[i] = XMVectorSet(pBCR->R(i), pBCG->R(i), 0, 1.0f); } } _Use_decl_annotations_ void D3DXDecodeBC5S(XMVECTOR *pColor, const uint8_t *pBC) { assert( pColor && pBC ); static_assert( sizeof(BC4_SNORM) == 8, "BC4_SNORM should be 8 bytes" ); auto pBCR = reinterpret_cast(pBC); auto pBCG = reinterpret_cast(pBC+sizeof(BC4_SNORM)); for (size_t i = 0; i < NUM_PIXELS_PER_BLOCK; ++i) { #pragma prefast(suppress:22103, "writing blocks in two halves confuses tool") pColor[i] = XMVectorSet(pBCR->R(i), pBCG->R(i), 0, 1.0f); } } _Use_decl_annotations_ void D3DXEncodeBC5U( uint8_t *pBC, const XMVECTOR *pColor, DWORD flags ) { UNREFERENCED_PARAMETER( flags ); assert( pBC && pColor ); static_assert( sizeof(BC4_UNORM) == 8, "BC4_UNORM should be 8 bytes" ); memset(pBC, 0, sizeof(BC4_UNORM)*2); auto pBCR = reinterpret_cast(pBC); auto pBCG = reinterpret_cast(pBC+sizeof(BC4_UNORM)); float theTexelsU[NUM_PIXELS_PER_BLOCK]; float theTexelsV[NUM_PIXELS_PER_BLOCK]; for (size_t i = 0; i < NUM_PIXELS_PER_BLOCK; ++i) { XMFLOAT4A clr; XMStoreFloat4A( &clr, pColor[i] ); theTexelsU[i] = clr.x; theTexelsV[i] = clr.y; } FindEndPointsBC5U( theTexelsU, theTexelsV, pBCR->red_0, pBCR->red_1, pBCG->red_0, pBCG->red_1); FindClosestUNORM(pBCR, theTexelsU); FindClosestUNORM(pBCG, theTexelsV); } _Use_decl_annotations_ void D3DXEncodeBC5S( uint8_t *pBC, const XMVECTOR *pColor, DWORD flags ) { UNREFERENCED_PARAMETER( flags ); assert( pBC && pColor ); static_assert( sizeof(BC4_SNORM) == 8, "BC4_SNORM should be 8 bytes" ); memset(pBC, 0, sizeof(BC4_UNORM)*2); auto pBCR = reinterpret_cast(pBC); auto pBCG = reinterpret_cast(pBC+sizeof(BC4_SNORM)); float theTexelsU[NUM_PIXELS_PER_BLOCK]; float theTexelsV[NUM_PIXELS_PER_BLOCK]; for (size_t i = 0; i < NUM_PIXELS_PER_BLOCK; ++i) { XMFLOAT4A clr; XMStoreFloat4A( &clr, pColor[i] ); theTexelsU[i] = clr.x; theTexelsV[i] = clr.y; } FindEndPointsBC5S( theTexelsU, theTexelsV, pBCR->red_0, pBCR->red_1, pBCG->red_0, pBCG->red_1); FindClosestSNORM(pBCR, theTexelsU); FindClosestSNORM(pBCG, theTexelsV); } } // namespace ================================================ FILE: 3rdParty/DirectXTex/DirectXTex/BC6HBC7.cpp ================================================ //------------------------------------------------------------------------------------- // BC6HBC7.cpp // // Block-compression (BC) functionality for BC6H and BC7 (DirectX 11 texture compression) // // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A // PARTICULAR PURPOSE. // // Copyright (c) Microsoft Corporation. All rights reserved. // // http://go.microsoft.com/fwlink/?LinkId=248926 //------------------------------------------------------------------------------------- #include "directxtexp.h" #include "BC.h" using namespace DirectX::PackedVector; namespace DirectX { //------------------------------------------------------------------------------------- // Constants //------------------------------------------------------------------------------------- static const float fEpsilon = (0.25f / 64.0f) * (0.25f / 64.0f); static const float pC3[] = { 2.0f/2.0f, 1.0f/2.0f, 0.0f/2.0f }; static const float pD3[] = { 0.0f/2.0f, 1.0f/2.0f, 2.0f/2.0f }; static const float pC4[] = { 3.0f/3.0f, 2.0f/3.0f, 1.0f/3.0f, 0.0f/3.0f }; static const float pD4[] = { 0.0f/3.0f, 1.0f/3.0f, 2.0f/3.0f, 3.0f/3.0f }; const int g_aWeights2[] = {0, 21, 43, 64}; const int g_aWeights3[] = {0, 9, 18, 27, 37, 46, 55, 64}; const int g_aWeights4[] = {0, 4, 9, 13, 17, 21, 26, 30, 34, 38, 43, 47, 51, 55, 60, 64}; // Partition, Shape, Pixel (index into 4x4 block) static const uint8_t g_aPartitionTable[3][64][16] = { { // 1 Region case has no subsets (all 0) { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, { // BC6H/BC7 Partition Set for 2 Subsets { 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1 }, // Shape 0 { 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1 }, // Shape 1 { 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1 }, // Shape 2 { 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1 }, // Shape 3 { 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1 }, // Shape 4 { 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1 }, // Shape 5 { 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1 }, // Shape 6 { 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1 }, // Shape 7 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1 }, // Shape 8 { 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, // Shape 9 { 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1 }, // Shape 10 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1 }, // Shape 11 { 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, // Shape 12 { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1 }, // Shape 13 { 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, // Shape 14 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1 }, // Shape 15 { 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1 }, // Shape 16 { 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 }, // Shape 17 { 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0 }, // Shape 18 { 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0 }, // Shape 19 { 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 }, // Shape 20 { 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0 }, // Shape 21 { 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0 }, // Shape 22 { 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1 }, // Shape 23 { 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0 }, // Shape 24 { 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0 }, // Shape 25 { 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0 }, // Shape 26 { 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0 }, // Shape 27 { 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0 }, // Shape 28 { 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0 }, // Shape 29 { 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0 }, // Shape 30 { 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0 }, // Shape 31 // BC7 Partition Set for 2 Subsets (second-half) { 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 }, // Shape 32 { 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1 }, // Shape 33 { 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0 }, // Shape 34 { 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0 }, // Shape 35 { 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0 }, // Shape 36 { 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0 }, // Shape 37 { 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1 }, // Shape 38 { 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1 }, // Shape 39 { 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0 }, // Shape 40 { 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0 }, // Shape 41 { 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0 }, // Shape 42 { 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0 }, // Shape 43 { 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 }, // Shape 44 { 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1 }, // Shape 45 { 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1 }, // Shape 46 { 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0 }, // Shape 47 { 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, // Shape 48 { 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, // Shape 49 { 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0 }, // Shape 50 { 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0 }, // Shape 51 { 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1 }, // Shape 52 { 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1 }, // Shape 53 { 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0 }, // Shape 54 { 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0 }, // Shape 55 { 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1 }, // Shape 56 { 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1 }, // Shape 57 { 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1 }, // Shape 58 { 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1 }, // Shape 59 { 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1 }, // Shape 60 { 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0 }, // Shape 61 { 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0 }, // Shape 62 { 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1 } // Shape 63 }, { // BC7 Partition Set for 3 Subsets { 0, 0, 1, 1, 0, 0, 1, 1, 0, 2, 2, 1, 2, 2, 2, 2 }, // Shape 0 { 0, 0, 0, 1, 0, 0, 1, 1, 2, 2, 1, 1, 2, 2, 2, 1 }, // Shape 1 { 0, 0, 0, 0, 2, 0, 0, 1, 2, 2, 1, 1, 2, 2, 1, 1 }, // Shape 2 { 0, 2, 2, 2, 0, 0, 2, 2, 0, 0, 1, 1, 0, 1, 1, 1 }, // Shape 3 { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 1, 1, 2, 2 }, // Shape 4 { 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 2, 2, 0, 0, 2, 2 }, // Shape 5 { 0, 0, 2, 2, 0, 0, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1 }, // Shape 6 { 0, 0, 1, 1, 0, 0, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1 }, // Shape 7 { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2 }, // Shape 8 { 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2 }, // Shape 9 { 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2 }, // Shape 10 { 0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2 }, // Shape 11 { 0, 1, 1, 2, 0, 1, 1, 2, 0, 1, 1, 2, 0, 1, 1, 2 }, // Shape 12 { 0, 1, 2, 2, 0, 1, 2, 2, 0, 1, 2, 2, 0, 1, 2, 2 }, // Shape 13 { 0, 0, 1, 1, 0, 1, 1, 2, 1, 1, 2, 2, 1, 2, 2, 2 }, // Shape 14 { 0, 0, 1, 1, 2, 0, 0, 1, 2, 2, 0, 0, 2, 2, 2, 0 }, // Shape 15 { 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 2, 1, 1, 2, 2 }, // Shape 16 { 0, 1, 1, 1, 0, 0, 1, 1, 2, 0, 0, 1, 2, 2, 0, 0 }, // Shape 17 { 0, 0, 0, 0, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2 }, // Shape 18 { 0, 0, 2, 2, 0, 0, 2, 2, 0, 0, 2, 2, 1, 1, 1, 1 }, // Shape 19 { 0, 1, 1, 1, 0, 1, 1, 1, 0, 2, 2, 2, 0, 2, 2, 2 }, // Shape 20 { 0, 0, 0, 1, 0, 0, 0, 1, 2, 2, 2, 1, 2, 2, 2, 1 }, // Shape 21 { 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 2, 2, 0, 1, 2, 2 }, // Shape 22 { 0, 0, 0, 0, 1, 1, 0, 0, 2, 2, 1, 0, 2, 2, 1, 0 }, // Shape 23 { 0, 1, 2, 2, 0, 1, 2, 2, 0, 0, 1, 1, 0, 0, 0, 0 }, // Shape 24 { 0, 0, 1, 2, 0, 0, 1, 2, 1, 1, 2, 2, 2, 2, 2, 2 }, // Shape 25 { 0, 1, 1, 0, 1, 2, 2, 1, 1, 2, 2, 1, 0, 1, 1, 0 }, // Shape 26 { 0, 0, 0, 0, 0, 1, 1, 0, 1, 2, 2, 1, 1, 2, 2, 1 }, // Shape 27 { 0, 0, 2, 2, 1, 1, 0, 2, 1, 1, 0, 2, 0, 0, 2, 2 }, // Shape 28 { 0, 1, 1, 0, 0, 1, 1, 0, 2, 0, 0, 2, 2, 2, 2, 2 }, // Shape 29 { 0, 0, 1, 1, 0, 1, 2, 2, 0, 1, 2, 2, 0, 0, 1, 1 }, // Shape 30 { 0, 0, 0, 0, 2, 0, 0, 0, 2, 2, 1, 1, 2, 2, 2, 1 }, // Shape 31 { 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 2, 2, 1, 2, 2, 2 }, // Shape 32 { 0, 2, 2, 2, 0, 0, 2, 2, 0, 0, 1, 2, 0, 0, 1, 1 }, // Shape 33 { 0, 0, 1, 1, 0, 0, 1, 2, 0, 0, 2, 2, 0, 2, 2, 2 }, // Shape 34 { 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2, 0 }, // Shape 35 { 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 0, 0, 0, 0 }, // Shape 36 { 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0 }, // Shape 37 { 0, 1, 2, 0, 2, 0, 1, 2, 1, 2, 0, 1, 0, 1, 2, 0 }, // Shape 38 { 0, 0, 1, 1, 2, 2, 0, 0, 1, 1, 2, 2, 0, 0, 1, 1 }, // Shape 39 { 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 0, 0, 0, 0, 1, 1 }, // Shape 40 { 0, 1, 0, 1, 0, 1, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2 }, // Shape 41 { 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 2, 1, 2, 1, 2, 1 }, // Shape 42 { 0, 0, 2, 2, 1, 1, 2, 2, 0, 0, 2, 2, 1, 1, 2, 2 }, // Shape 43 { 0, 0, 2, 2, 0, 0, 1, 1, 0, 0, 2, 2, 0, 0, 1, 1 }, // Shape 44 { 0, 2, 2, 0, 1, 2, 2, 1, 0, 2, 2, 0, 1, 2, 2, 1 }, // Shape 45 { 0, 1, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 0, 1 }, // Shape 46 { 0, 0, 0, 0, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1 }, // Shape 47 { 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 2, 2, 2, 2 }, // Shape 48 { 0, 2, 2, 2, 0, 1, 1, 1, 0, 2, 2, 2, 0, 1, 1, 1 }, // Shape 49 { 0, 0, 0, 2, 1, 1, 1, 2, 0, 0, 0, 2, 1, 1, 1, 2 }, // Shape 50 { 0, 0, 0, 0, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2 }, // Shape 51 { 0, 2, 2, 2, 0, 1, 1, 1, 0, 1, 1, 1, 0, 2, 2, 2 }, // Shape 52 { 0, 0, 0, 2, 1, 1, 1, 2, 1, 1, 1, 2, 0, 0, 0, 2 }, // Shape 53 { 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 2, 2, 2, 2 }, // Shape 54 { 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 2, 2, 1, 1, 2 }, // Shape 55 { 0, 1, 1, 0, 0, 1, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2 }, // Shape 56 { 0, 0, 2, 2, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 2, 2 }, // Shape 57 { 0, 0, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 0, 0, 2, 2 }, // Shape 58 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 2 }, // Shape 59 { 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1 }, // Shape 60 { 0, 2, 2, 2, 1, 2, 2, 2, 0, 2, 2, 2, 1, 2, 2, 2 }, // Shape 61 { 0, 1, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 }, // Shape 62 { 0, 1, 1, 1, 2, 0, 1, 1, 2, 2, 0, 1, 2, 2, 2, 0 } // Shape 63 } }; // Partition, Shape, Fixup static const uint8_t g_aFixUp[3][64][3] = { { // No fix-ups for 1st subset for BC6H or BC7 { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0} }, { // BC6H/BC7 Partition Set Fixups for 2 Subsets { 0,15, 0}, { 0,15, 0}, { 0,15, 0}, { 0,15, 0}, { 0,15, 0}, { 0,15, 0}, { 0,15, 0}, { 0,15, 0}, { 0,15, 0}, { 0,15, 0}, { 0,15, 0}, { 0,15, 0}, { 0,15, 0}, { 0,15, 0}, { 0,15, 0}, { 0,15, 0}, { 0,15, 0}, { 0, 2, 0}, { 0, 8, 0}, { 0, 2, 0}, { 0, 2, 0}, { 0, 8, 0}, { 0, 8, 0}, { 0,15, 0}, { 0, 2, 0}, { 0, 8, 0}, { 0, 2, 0}, { 0, 2, 0}, { 0, 8, 0}, { 0, 8, 0}, { 0, 2, 0}, { 0, 2, 0}, // BC7 Partition Set Fixups for 2 Subsets (second-half) { 0,15, 0}, { 0,15, 0}, { 0, 6, 0}, { 0, 8, 0}, { 0, 2, 0}, { 0, 8, 0}, { 0,15, 0}, { 0,15, 0}, { 0, 2, 0}, { 0, 8, 0}, { 0, 2, 0}, { 0, 2, 0}, { 0, 2, 0}, { 0,15, 0}, { 0,15, 0}, { 0, 6, 0}, { 0, 6, 0}, { 0, 2, 0}, { 0, 6, 0}, { 0, 8, 0}, { 0,15, 0}, { 0,15, 0}, { 0, 2, 0}, { 0, 2, 0}, { 0,15, 0}, { 0,15, 0}, { 0,15, 0}, { 0,15, 0}, { 0,15, 0}, { 0, 2, 0}, { 0, 2, 0}, { 0,15, 0} }, { // BC7 Partition Set Fixups for 3 Subsets { 0, 3,15}, { 0, 3, 8}, { 0,15, 8}, { 0,15, 3}, { 0, 8,15}, { 0, 3,15}, { 0,15, 3}, { 0,15, 8}, { 0, 8,15}, { 0, 8,15}, { 0, 6,15}, { 0, 6,15}, { 0, 6,15}, { 0, 5,15}, { 0, 3,15}, { 0, 3, 8}, { 0, 3,15}, { 0, 3, 8}, { 0, 8,15}, { 0,15, 3}, { 0, 3,15}, { 0, 3, 8}, { 0, 6,15}, { 0,10, 8}, { 0, 5, 3}, { 0, 8,15}, { 0, 8, 6}, { 0, 6,10}, { 0, 8,15}, { 0, 5,15}, { 0,15,10}, { 0,15, 8}, { 0, 8,15}, { 0,15, 3}, { 0, 3,15}, { 0, 5,10}, { 0, 6,10}, { 0,10, 8}, { 0, 8, 9}, { 0,15,10}, { 0,15, 6}, { 0, 3,15}, { 0,15, 8}, { 0, 5,15}, { 0,15, 3}, { 0,15, 6}, { 0,15, 6}, { 0,15, 8}, { 0, 3,15}, { 0,15, 3}, { 0, 5,15}, { 0, 5,15}, { 0, 5,15}, { 0, 8,15}, { 0, 5,15}, { 0,10,15}, { 0, 5,15}, { 0,10,15}, { 0, 8,15}, { 0,13,15}, { 0,15, 3}, { 0,12,15}, { 0, 3,15}, { 0, 3, 8} } }; // BC6H Compression const D3DX_BC6H::ModeDescriptor D3DX_BC6H::ms_aDesc[14][82] = { { // Mode 1 (0x00) - 10 5 5 5 { M, 0}, { M, 1}, {GY, 4}, {BY, 4}, {BZ, 4}, {RW, 0}, {RW, 1}, {RW, 2}, {RW, 3}, {RW, 4}, {RW, 5}, {RW, 6}, {RW, 7}, {RW, 8}, {RW, 9}, {GW, 0}, {GW, 1}, {GW, 2}, {GW, 3}, {GW, 4}, {GW, 5}, {GW, 6}, {GW, 7}, {GW, 8}, {GW, 9}, {BW, 0}, {BW, 1}, {BW, 2}, {BW, 3}, {BW, 4}, {BW, 5}, {BW, 6}, {BW, 7}, {BW, 8}, {BW, 9}, {RX, 0}, {RX, 1}, {RX, 2}, {RX, 3}, {RX, 4}, {GZ, 4}, {GY, 0}, {GY, 1}, {GY, 2}, {GY, 3}, {GX, 0}, {GX, 1}, {GX, 2}, {GX, 3}, {GX, 4}, {BZ, 0}, {GZ, 0}, {GZ, 1}, {GZ, 2}, {GZ, 3}, {BX, 0}, {BX, 1}, {BX, 2}, {BX, 3}, {BX, 4}, {BZ, 1}, {BY, 0}, {BY, 1}, {BY, 2}, {BY, 3}, {RY, 0}, {RY, 1}, {RY, 2}, {RY, 3}, {RY, 4}, {BZ, 2}, {RZ, 0}, {RZ, 1}, {RZ, 2}, {RZ, 3}, {RZ, 4}, {BZ, 3}, { D, 0}, { D, 1}, { D, 2}, { D, 3}, { D, 4}, }, { // Mode 2 (0x01) - 7 6 6 6 { M, 0}, { M, 1}, {GY, 5}, {GZ, 4}, {GZ, 5}, {RW, 0}, {RW, 1}, {RW, 2}, {RW, 3}, {RW, 4}, {RW, 5}, {RW, 6}, {BZ, 0}, {BZ, 1}, {BY, 4}, {GW, 0}, {GW, 1}, {GW, 2}, {GW, 3}, {GW, 4}, {GW, 5}, {GW, 6}, {BY, 5}, {BZ, 2}, {GY, 4}, {BW, 0}, {BW, 1}, {BW, 2}, {BW, 3}, {BW, 4}, {BW, 5}, {BW, 6}, {BZ, 3}, {BZ, 5}, {BZ, 4}, {RX, 0}, {RX, 1}, {RX, 2}, {RX, 3}, {RX, 4}, {RX, 5}, {GY, 0}, {GY, 1}, {GY, 2}, {GY, 3}, {GX, 0}, {GX, 1}, {GX, 2}, {GX, 3}, {GX, 4}, {GX, 5}, {GZ, 0}, {GZ, 1}, {GZ, 2}, {GZ, 3}, {BX, 0}, {BX, 1}, {BX, 2}, {BX, 3}, {BX, 4}, {BX, 5}, {BY, 0}, {BY, 1}, {BY, 2}, {BY, 3}, {RY, 0}, {RY, 1}, {RY, 2}, {RY, 3}, {RY, 4}, {RY, 5}, {RZ, 0}, {RZ, 1}, {RZ, 2}, {RZ, 3}, {RZ, 4}, {RZ, 5}, { D, 0}, { D, 1}, { D, 2}, { D, 3}, { D, 4}, }, { // Mode 3 (0x02) - 11 5 4 4 { M, 0}, { M, 1}, { M, 2}, { M, 3}, { M, 4}, {RW, 0}, {RW, 1}, {RW, 2}, {RW, 3}, {RW, 4}, {RW, 5}, {RW, 6}, {RW, 7}, {RW, 8}, {RW, 9}, {GW, 0}, {GW, 1}, {GW, 2}, {GW, 3}, {GW, 4}, {GW, 5}, {GW, 6}, {GW, 7}, {GW, 8}, {GW, 9}, {BW, 0}, {BW, 1}, {BW, 2}, {BW, 3}, {BW, 4}, {BW, 5}, {BW, 6}, {BW, 7}, {BW, 8}, {BW, 9}, {RX, 0}, {RX, 1}, {RX, 2}, {RX, 3}, {RX, 4}, {RW,10}, {GY, 0}, {GY, 1}, {GY, 2}, {GY, 3}, {GX, 0}, {GX, 1}, {GX, 2}, {GX, 3}, {GW,10}, {BZ, 0}, {GZ, 0}, {GZ, 1}, {GZ, 2}, {GZ, 3}, {BX, 0}, {BX, 1}, {BX, 2}, {BX, 3}, {BW,10}, {BZ, 1}, {BY, 0}, {BY, 1}, {BY, 2}, {BY, 3}, {RY, 0}, {RY, 1}, {RY, 2}, {RY, 3}, {RY, 4}, {BZ, 2}, {RZ, 0}, {RZ, 1}, {RZ, 2}, {RZ, 3}, {RZ, 4}, {BZ, 3}, { D, 0}, { D, 1}, { D, 2}, { D, 3}, { D, 4}, }, { // Mode 4 (0x06) - 11 4 5 4 { M, 0}, { M, 1}, { M, 2}, { M, 3}, { M, 4}, {RW, 0}, {RW, 1}, {RW, 2}, {RW, 3}, {RW, 4}, {RW, 5}, {RW, 6}, {RW, 7}, {RW, 8}, {RW, 9}, {GW, 0}, {GW, 1}, {GW, 2}, {GW, 3}, {GW, 4}, {GW, 5}, {GW, 6}, {GW, 7}, {GW, 8}, {GW, 9}, {BW, 0}, {BW, 1}, {BW, 2}, {BW, 3}, {BW, 4}, {BW, 5}, {BW, 6}, {BW, 7}, {BW, 8}, {BW, 9}, {RX, 0}, {RX, 1}, {RX, 2}, {RX, 3}, {RW,10}, {GZ, 4}, {GY, 0}, {GY, 1}, {GY, 2}, {GY, 3}, {GX, 0}, {GX, 1}, {GX, 2}, {GX, 3}, {GX, 4}, {GW,10}, {GZ, 0}, {GZ, 1}, {GZ, 2}, {GZ, 3}, {BX, 0}, {BX, 1}, {BX, 2}, {BX, 3}, {BW,10}, {BZ, 1}, {BY, 0}, {BY, 1}, {BY, 2}, {BY, 3}, {RY, 0}, {RY, 1}, {RY, 2}, {RY, 3}, {BZ, 0}, {BZ, 2}, {RZ, 0}, {RZ, 1}, {RZ, 2}, {RZ, 3}, {GY, 4}, {BZ, 3}, { D, 0}, { D, 1}, { D, 2}, { D, 3}, { D, 4}, }, { // Mode 5 (0x0a) - 11 4 4 5 { M, 0}, { M, 1}, { M, 2}, { M, 3}, { M, 4}, {RW, 0}, {RW, 1}, {RW, 2}, {RW, 3}, {RW, 4}, {RW, 5}, {RW, 6}, {RW, 7}, {RW, 8}, {RW, 9}, {GW, 0}, {GW, 1}, {GW, 2}, {GW, 3}, {GW, 4}, {GW, 5}, {GW, 6}, {GW, 7}, {GW, 8}, {GW, 9}, {BW, 0}, {BW, 1}, {BW, 2}, {BW, 3}, {BW, 4}, {BW, 5}, {BW, 6}, {BW, 7}, {BW, 8}, {BW, 9}, {RX, 0}, {RX, 1}, {RX, 2}, {RX, 3}, {RW,10}, {BY, 4}, {GY, 0}, {GY, 1}, {GY, 2}, {GY, 3}, {GX, 0}, {GX, 1}, {GX, 2}, {GX, 3}, {GW,10}, {BZ, 0}, {GZ, 0}, {GZ, 1}, {GZ, 2}, {GZ, 3}, {BX, 0}, {BX, 1}, {BX, 2}, {BX, 3}, {BX, 4}, {BW,10}, {BY, 0}, {BY, 1}, {BY, 2}, {BY, 3}, {RY, 0}, {RY, 1}, {RY, 2}, {RY, 3}, {BZ, 1}, {BZ, 2}, {RZ, 0}, {RZ, 1}, {RZ, 2}, {RZ, 3}, {BZ, 4}, {BZ, 3}, { D, 0}, { D, 1}, { D, 2}, { D, 3}, { D, 4}, }, { // Mode 6 (0x0e) - 9 5 5 5 { M, 0}, { M, 1}, { M, 2}, { M, 3}, { M, 4}, {RW, 0}, {RW, 1}, {RW, 2}, {RW, 3}, {RW, 4}, {RW, 5}, {RW, 6}, {RW, 7}, {RW, 8}, {BY, 4}, {GW, 0}, {GW, 1}, {GW, 2}, {GW, 3}, {GW, 4}, {GW, 5}, {GW, 6}, {GW, 7}, {GW, 8}, {GY, 4}, {BW, 0}, {BW, 1}, {BW, 2}, {BW, 3}, {BW, 4}, {BW, 5}, {BW, 6}, {BW, 7}, {BW, 8}, {BZ, 4}, {RX, 0}, {RX, 1}, {RX, 2}, {RX, 3}, {RX, 4}, {GZ, 4}, {GY, 0}, {GY, 1}, {GY, 2}, {GY, 3}, {GX, 0}, {GX, 1}, {GX, 2}, {GX, 3}, {GX, 4}, {BZ, 0}, {GZ, 0}, {GZ, 1}, {GZ, 2}, {GZ, 3}, {BX, 0}, {BX, 1}, {BX, 2}, {BX, 3}, {BX, 4}, {BZ, 1}, {BY, 0}, {BY, 1}, {BY, 2}, {BY, 3}, {RY, 0}, {RY, 1}, {RY, 2}, {RY, 3}, {RY, 4}, {BZ, 2}, {RZ, 0}, {RZ, 1}, {RZ, 2}, {RZ, 3}, {RZ, 4}, {BZ, 3}, { D, 0}, { D, 1}, { D, 2}, { D, 3}, { D, 4}, }, { // Mode 7 (0x12) - 8 6 5 5 { M, 0}, { M, 1}, { M, 2}, { M, 3}, { M, 4}, {RW, 0}, {RW, 1}, {RW, 2}, {RW, 3}, {RW, 4}, {RW, 5}, {RW, 6}, {RW, 7}, {GZ, 4}, {BY, 4}, {GW, 0}, {GW, 1}, {GW, 2}, {GW, 3}, {GW, 4}, {GW, 5}, {GW, 6}, {GW, 7}, {BZ, 2}, {GY, 4}, {BW, 0}, {BW, 1}, {BW, 2}, {BW, 3}, {BW, 4}, {BW, 5}, {BW, 6}, {BW, 7}, {BZ, 3}, {BZ, 4}, {RX, 0}, {RX, 1}, {RX, 2}, {RX, 3}, {RX, 4}, {RX, 5}, {GY, 0}, {GY, 1}, {GY, 2}, {GY, 3}, {GX, 0}, {GX, 1}, {GX, 2}, {GX, 3}, {GX, 4}, {BZ, 0}, {GZ, 0}, {GZ, 1}, {GZ, 2}, {GZ, 3}, {BX, 0}, {BX, 1}, {BX, 2}, {BX, 3}, {BX, 4}, {BZ, 1}, {BY, 0}, {BY, 1}, {BY, 2}, {BY, 3}, {RY, 0}, {RY, 1}, {RY, 2}, {RY, 3}, {RY, 4}, {RY, 5}, {RZ, 0}, {RZ, 1}, {RZ, 2}, {RZ, 3}, {RZ, 4}, {RZ, 5}, { D, 0}, { D, 1}, { D, 2}, { D, 3}, { D, 4}, }, { // Mode 8 (0x16) - 8 5 6 5 { M, 0}, { M, 1}, { M, 2}, { M, 3}, { M, 4}, {RW, 0}, {RW, 1}, {RW, 2}, {RW, 3}, {RW, 4}, {RW, 5}, {RW, 6}, {RW, 7}, {BZ, 0}, {BY, 4}, {GW, 0}, {GW, 1}, {GW, 2}, {GW, 3}, {GW, 4}, {GW, 5}, {GW, 6}, {GW, 7}, {GY, 5}, {GY, 4}, {BW, 0}, {BW, 1}, {BW, 2}, {BW, 3}, {BW, 4}, {BW, 5}, {BW, 6}, {BW, 7}, {GZ, 5}, {BZ, 4}, {RX, 0}, {RX, 1}, {RX, 2}, {RX, 3}, {RX, 4}, {GZ, 4}, {GY, 0}, {GY, 1}, {GY, 2}, {GY, 3}, {GX, 0}, {GX, 1}, {GX, 2}, {GX, 3}, {GX, 4}, {GX, 5}, {GZ, 0}, {GZ, 1}, {GZ, 2}, {GZ, 3}, {BX, 0}, {BX, 1}, {BX, 2}, {BX, 3}, {BX, 4}, {BZ, 1}, {BY, 0}, {BY, 1}, {BY, 2}, {BY, 3}, {RY, 0}, {RY, 1}, {RY, 2}, {RY, 3}, {RY, 4}, {BZ, 2}, {RZ, 0}, {RZ, 1}, {RZ, 2}, {RZ, 3}, {RZ, 4}, {BZ, 3}, { D, 0}, { D, 1}, { D, 2}, { D, 3}, { D, 4}, }, { // Mode 9 (0x1a) - 8 5 5 6 { M, 0}, { M, 1}, { M, 2}, { M, 3}, { M, 4}, {RW, 0}, {RW, 1}, {RW, 2}, {RW, 3}, {RW, 4}, {RW, 5}, {RW, 6}, {RW, 7}, {BZ, 1}, {BY, 4}, {GW, 0}, {GW, 1}, {GW, 2}, {GW, 3}, {GW, 4}, {GW, 5}, {GW, 6}, {GW, 7}, {BY, 5}, {GY, 4}, {BW, 0}, {BW, 1}, {BW, 2}, {BW, 3}, {BW, 4}, {BW, 5}, {BW, 6}, {BW, 7}, {BZ, 5}, {BZ, 4}, {RX, 0}, {RX, 1}, {RX, 2}, {RX, 3}, {RX, 4}, {GZ, 4}, {GY, 0}, {GY, 1}, {GY, 2}, {GY, 3}, {GX, 0}, {GX, 1}, {GX, 2}, {GX, 3}, {GX, 4}, {BZ, 0}, {GZ, 0}, {GZ, 1}, {GZ, 2}, {GZ, 3}, {BX, 0}, {BX, 1}, {BX, 2}, {BX, 3}, {BX, 4}, {BX, 5}, {BY, 0}, {BY, 1}, {BY, 2}, {BY, 3}, {RY, 0}, {RY, 1}, {RY, 2}, {RY, 3}, {RY, 4}, {BZ, 2}, {RZ, 0}, {RZ, 1}, {RZ, 2}, {RZ, 3}, {RZ, 4}, {BZ, 3}, { D, 0}, { D, 1}, { D, 2}, { D, 3}, { D, 4}, }, { // Mode 10 (0x1e) - 6 6 6 6 { M, 0}, { M, 1}, { M, 2}, { M, 3}, { M, 4}, {RW, 0}, {RW, 1}, {RW, 2}, {RW, 3}, {RW, 4}, {RW, 5}, {GZ, 4}, {BZ, 0}, {BZ, 1}, {BY, 4}, {GW, 0}, {GW, 1}, {GW, 2}, {GW, 3}, {GW, 4}, {GW, 5}, {GY, 5}, {BY, 5}, {BZ, 2}, {GY, 4}, {BW, 0}, {BW, 1}, {BW, 2}, {BW, 3}, {BW, 4}, {BW, 5}, {GZ, 5}, {BZ, 3}, {BZ, 5}, {BZ, 4}, {RX, 0}, {RX, 1}, {RX, 2}, {RX, 3}, {RX, 4}, {RX, 5}, {GY, 0}, {GY, 1}, {GY, 2}, {GY, 3}, {GX, 0}, {GX, 1}, {GX, 2}, {GX, 3}, {GX, 4}, {GX, 5}, {GZ, 0}, {GZ, 1}, {GZ, 2}, {GZ, 3}, {BX, 0}, {BX, 1}, {BX, 2}, {BX, 3}, {BX, 4}, {BX, 5}, {BY, 0}, {BY, 1}, {BY, 2}, {BY, 3}, {RY, 0}, {RY, 1}, {RY, 2}, {RY, 3}, {RY, 4}, {RY, 5}, {RZ, 0}, {RZ, 1}, {RZ, 2}, {RZ, 3}, {RZ, 4}, {RZ, 5}, { D, 0}, { D, 1}, { D, 2}, { D, 3}, { D, 4}, }, { // Mode 11 (0x03) - 10 10 { M, 0}, { M, 1}, { M, 2}, { M, 3}, { M, 4}, {RW, 0}, {RW, 1}, {RW, 2}, {RW, 3}, {RW, 4}, {RW, 5}, {RW, 6}, {RW, 7}, {RW, 8}, {RW, 9}, {GW, 0}, {GW, 1}, {GW, 2}, {GW, 3}, {GW, 4}, {GW, 5}, {GW, 6}, {GW, 7}, {GW, 8}, {GW, 9}, {BW, 0}, {BW, 1}, {BW, 2}, {BW, 3}, {BW, 4}, {BW, 5}, {BW, 6}, {BW, 7}, {BW, 8}, {BW, 9}, {RX, 0}, {RX, 1}, {RX, 2}, {RX, 3}, {RX, 4}, {RX, 5}, {RX, 6}, {RX, 7}, {RX, 8}, {RX, 9}, {GX, 0}, {GX, 1}, {GX, 2}, {GX, 3}, {GX, 4}, {GX, 5}, {GX, 6}, {GX, 7}, {GX, 8}, {GX, 9}, {BX, 0}, {BX, 1}, {BX, 2}, {BX, 3}, {BX, 4}, {BX, 5}, {BX, 6}, {BX, 7}, {BX, 8}, {BX, 9}, {NA, 0}, {NA, 0}, {NA, 0}, {NA, 0}, {NA, 0}, {NA, 0}, {NA, 0}, {NA, 0}, {NA, 0}, {NA, 0}, {NA, 0}, {NA, 0}, {NA, 0}, {NA, 0}, {NA, 0}, {NA, 0}, {NA, 0}, }, { // Mode 12 (0x07) - 11 9 { M, 0}, { M, 1}, { M, 2}, { M, 3}, { M, 4}, {RW, 0}, {RW, 1}, {RW, 2}, {RW, 3}, {RW, 4}, {RW, 5}, {RW, 6}, {RW, 7}, {RW, 8}, {RW, 9}, {GW, 0}, {GW, 1}, {GW, 2}, {GW, 3}, {GW, 4}, {GW, 5}, {GW, 6}, {GW, 7}, {GW, 8}, {GW, 9}, {BW, 0}, {BW, 1}, {BW, 2}, {BW, 3}, {BW, 4}, {BW, 5}, {BW, 6}, {BW, 7}, {BW, 8}, {BW, 9}, {RX, 0}, {RX, 1}, {RX, 2}, {RX, 3}, {RX, 4}, {RX, 5}, {RX, 6}, {RX, 7}, {RX, 8}, {RW,10}, {GX, 0}, {GX, 1}, {GX, 2}, {GX, 3}, {GX, 4}, {GX, 5}, {GX, 6}, {GX, 7}, {GX, 8}, {GW,10}, {BX, 0}, {BX, 1}, {BX, 2}, {BX, 3}, {BX, 4}, {BX, 5}, {BX, 6}, {BX, 7}, {BX, 8}, {BW,10}, {NA, 0}, {NA, 0}, {NA, 0}, {NA, 0}, {NA, 0}, {NA, 0}, {NA, 0}, {NA, 0}, {NA, 0}, {NA, 0}, {NA, 0}, {NA, 0}, {NA, 0}, {NA, 0}, {NA, 0}, {NA, 0}, {NA, 0}, }, { // Mode 13 (0x0b) - 12 8 { M, 0}, { M, 1}, { M, 2}, { M, 3}, { M, 4}, {RW, 0}, {RW, 1}, {RW, 2}, {RW, 3}, {RW, 4}, {RW, 5}, {RW, 6}, {RW, 7}, {RW, 8}, {RW, 9}, {GW, 0}, {GW, 1}, {GW, 2}, {GW, 3}, {GW, 4}, {GW, 5}, {GW, 6}, {GW, 7}, {GW, 8}, {GW, 9}, {BW, 0}, {BW, 1}, {BW, 2}, {BW, 3}, {BW, 4}, {BW, 5}, {BW, 6}, {BW, 7}, {BW, 8}, {BW, 9}, {RX, 0}, {RX, 1}, {RX, 2}, {RX, 3}, {RX, 4}, {RX, 5}, {RX, 6}, {RX, 7}, {RW,11}, {RW,10}, {GX, 0}, {GX, 1}, {GX, 2}, {GX, 3}, {GX, 4}, {GX, 5}, {GX, 6}, {GX, 7}, {GW,11}, {GW,10}, {BX, 0}, {BX, 1}, {BX, 2}, {BX, 3}, {BX, 4}, {BX, 5}, {BX, 6}, {BX, 7}, {BW,11}, {BW,10}, {NA, 0}, {NA, 0}, {NA, 0}, {NA, 0}, {NA, 0}, {NA, 0}, {NA, 0}, {NA, 0}, {NA, 0}, {NA, 0}, {NA, 0}, {NA, 0}, {NA, 0}, {NA, 0}, {NA, 0}, {NA, 0}, {NA, 0}, }, { // Mode 14 (0x0f) - 16 4 { M, 0}, { M, 1}, { M, 2}, { M, 3}, { M, 4}, {RW, 0}, {RW, 1}, {RW, 2}, {RW, 3}, {RW, 4}, {RW, 5}, {RW, 6}, {RW, 7}, {RW, 8}, {RW, 9}, {GW, 0}, {GW, 1}, {GW, 2}, {GW, 3}, {GW, 4}, {GW, 5}, {GW, 6}, {GW, 7}, {GW, 8}, {GW, 9}, {BW, 0}, {BW, 1}, {BW, 2}, {BW, 3}, {BW, 4}, {BW, 5}, {BW, 6}, {BW, 7}, {BW, 8}, {BW, 9}, {RX, 0}, {RX, 1}, {RX, 2}, {RX, 3}, {RW,15}, {RW,14}, {RW,13}, {RW,12}, {RW,11}, {RW,10}, {GX, 0}, {GX, 1}, {GX, 2}, {GX, 3}, {GW,15}, {GW,14}, {GW,13}, {GW,12}, {GW,11}, {GW,10}, {BX, 0}, {BX, 1}, {BX, 2}, {BX, 3}, {BW,15}, {BW,14}, {BW,13}, {BW,12}, {BW,11}, {BW,10}, {NA, 0}, {NA, 0}, {NA, 0}, {NA, 0}, {NA, 0}, {NA, 0}, {NA, 0}, {NA, 0}, {NA, 0}, {NA, 0}, {NA, 0}, {NA, 0}, {NA, 0}, {NA, 0}, {NA, 0}, {NA, 0}, {NA, 0}, }, }; // Mode, Partitions, Transformed, IndexPrec, RGBAPrec const D3DX_BC6H::ModeInfo D3DX_BC6H::ms_aInfo[] = { {0x00, 1, true, 3, LDRColorA(10,10,10,0), LDRColorA( 5, 5, 5,0), LDRColorA(5,5,5,0), LDRColorA(5,5,5,0)}, // Mode 1 {0x01, 1, true, 3, LDRColorA( 7, 7, 7,0), LDRColorA( 6, 6, 6,0), LDRColorA(6,6,6,0), LDRColorA(6,6,6,0)}, // Mode 2 {0x02, 1, true, 3, LDRColorA(11,11,11,0), LDRColorA( 5, 4, 4,0), LDRColorA(5,4,4,0), LDRColorA(5,4,4,0)}, // Mode 3 {0x06, 1, true, 3, LDRColorA(11,11,11,0), LDRColorA( 4, 5, 4,0), LDRColorA(4,5,4,0), LDRColorA(4,5,4,0)}, // Mode 4 {0x0a, 1, true, 3, LDRColorA(11,11,11,0), LDRColorA( 4, 4, 5,0), LDRColorA(4,4,5,0), LDRColorA(4,4,5,0)}, // Mode 5 {0x0e, 1, true, 3, LDRColorA( 9, 9, 9,0), LDRColorA( 5, 5, 5,0), LDRColorA(5,5,5,0), LDRColorA(5,5,5,0)}, // Mode 6 {0x12, 1, true, 3, LDRColorA( 8, 8, 8,0), LDRColorA( 6, 5, 5,0), LDRColorA(6,5,5,0), LDRColorA(6,5,5,0)}, // Mode 7 {0x16, 1, true, 3, LDRColorA( 8, 8, 8,0), LDRColorA( 5, 6, 5,0), LDRColorA(5,6,5,0), LDRColorA(5,6,5,0)}, // Mode 8 {0x1a, 1, true, 3, LDRColorA( 8, 8, 8,0), LDRColorA( 5, 5, 6,0), LDRColorA(5,5,6,0), LDRColorA(5,5,6,0)}, // Mode 9 {0x1e, 1, false, 3, LDRColorA( 6, 6, 6,0), LDRColorA( 6, 6, 6,0), LDRColorA(6,6,6,0), LDRColorA(6,6,6,0)}, // Mode 10 {0x03, 0, false, 4, LDRColorA(10,10,10,0), LDRColorA(10,10,10,0), LDRColorA(0,0,0,0), LDRColorA(0,0,0,0)}, // Mode 11 {0x07, 0, true, 4, LDRColorA(11,11,11,0), LDRColorA( 9, 9, 9,0), LDRColorA(0,0,0,0), LDRColorA(0,0,0,0)}, // Mode 12 {0x0b, 0, true, 4, LDRColorA(12,12,12,0), LDRColorA( 8, 8, 8,0), LDRColorA(0,0,0,0), LDRColorA(0,0,0,0)}, // Mode 13 {0x0f, 0, true, 4, LDRColorA(16,16,16,0), LDRColorA( 4, 4, 4,0), LDRColorA(0,0,0,0), LDRColorA(0,0,0,0)}, // Mode 14 }; const int D3DX_BC6H::ms_aModeToInfo[] = { 0, // Mode 1 - 0x00 1, // Mode 2 - 0x01 2, // Mode 3 - 0x02 10, // Mode 11 - 0x03 -1, // Invalid - 0x04 -1, // Invalid - 0x05 3, // Mode 4 - 0x06 11, // Mode 12 - 0x07 -1, // Invalid - 0x08 -1, // Invalid - 0x09 4, // Mode 5 - 0x0a 12, // Mode 13 - 0x0b -1, // Invalid - 0x0c -1, // Invalid - 0x0d 5, // Mode 6 - 0x0e 13, // Mode 14 - 0x0f -1, // Invalid - 0x10 -1, // Invalid - 0x11 6, // Mode 7 - 0x12 -1, // Reserved - 0x13 -1, // Invalid - 0x14 -1, // Invalid - 0x15 7, // Mode 8 - 0x16 -1, // Reserved - 0x17 -1, // Invalid - 0x18 -1, // Invalid - 0x19 8, // Mode 9 - 0x1a -1, // Reserved - 0x1b -1, // Invalid - 0x1c -1, // Invalid - 0x1d 9, // Mode 10 - 0x1e -1, // Resreved - 0x1f }; // BC7 compression: uPartitions, uPartitionBits, uPBits, uRotationBits, uIndexModeBits, uIndexPrec, uIndexPrec2, RGBAPrec, RGBAPrecWithP const D3DX_BC7::ModeInfo D3DX_BC7::ms_aInfo[] = { {2, 4, 6, 0, 0, 3, 0, LDRColorA(4,4,4,0), LDRColorA(5,5,5,0)}, // Mode 0: Color only, 3 Subsets, RGBP 4441 (unique P-bit), 3-bit indecies, 16 partitions {1, 6, 2, 0, 0, 3, 0, LDRColorA(6,6,6,0), LDRColorA(7,7,7,0)}, // Mode 1: Color only, 2 Subsets, RGBP 6661 (shared P-bit), 3-bit indecies, 64 partitions {2, 6, 0, 0, 0, 2, 0, LDRColorA(5,5,5,0), LDRColorA(5,5,5,0)}, // Mode 2: Color only, 3 Subsets, RGB 555, 2-bit indecies, 64 partitions {1, 6, 4, 0, 0, 2, 0, LDRColorA(7,7,7,0), LDRColorA(8,8,8,0)}, // Mode 3: Color only, 2 Subsets, RGBP 7771 (unique P-bit), 2-bits indecies, 64 partitions {0, 0, 0, 2, 1, 2, 3, LDRColorA(5,5,5,6), LDRColorA(5,5,5,6)}, // Mode 4: Color w/ Separate Alpha, 1 Subset, RGB 555, A6, 16x2/16x3-bit indices, 2-bit rotation, 1-bit index selector {0, 0, 0, 2, 0, 2, 2, LDRColorA(7,7,7,8), LDRColorA(7,7,7,8)}, // Mode 5: Color w/ Separate Alpha, 1 Subset, RGB 777, A8, 16x2/16x2-bit indices, 2-bit rotation {0, 0, 2, 0, 0, 4, 0, LDRColorA(7,7,7,7), LDRColorA(8,8,8,8)}, // Mode 6: Color+Alpha, 1 Subset, RGBAP 77771 (unique P-bit), 16x4-bit indecies {1, 6, 4, 0, 0, 2, 0, LDRColorA(5,5,5,5), LDRColorA(6,6,6,6)} // Mode 7: Color+Alpha, 2 Subsets, RGBAP 55551 (unique P-bit), 2-bit indices, 64 partitions }; //------------------------------------------------------------------------------------- // Helper functions //------------------------------------------------------------------------------------- inline static bool IsFixUpOffset(_In_range_(0,2) size_t uPartitions, _In_range_(0,63) size_t uShape, _In_range_(0,15) size_t uOffset) { assert(uPartitions < 3 && uShape < 64 && uOffset < 16); _Analysis_assume_(uPartitions < 3 && uShape < 64 && uOffset < 16); for(size_t p = 0; p <= uPartitions; p++) { if(uOffset == g_aFixUp[uPartitions][uShape][p]) { return true; } } return false; } inline static void TransformForward(_Inout_updates_all_(BC6H_MAX_REGIONS) INTEndPntPair aEndPts[]) { aEndPts[0].B -= aEndPts[0].A; aEndPts[1].A -= aEndPts[0].A; aEndPts[1].B -= aEndPts[0].A; } inline static void TransformInverse(_Inout_updates_all_(BC6H_MAX_REGIONS) INTEndPntPair aEndPts[], _In_ const LDRColorA& Prec, _In_ bool bSigned) { INTColor WrapMask((1 << Prec.r) - 1, (1 << Prec.g) - 1, (1 << Prec.b) - 1); aEndPts[0].B += aEndPts[0].A; aEndPts[0].B &= WrapMask; aEndPts[1].A += aEndPts[0].A; aEndPts[1].A &= WrapMask; aEndPts[1].B += aEndPts[0].A; aEndPts[1].B &= WrapMask; if(bSigned) { aEndPts[0].B.SignExtend(Prec); aEndPts[1].A.SignExtend(Prec); aEndPts[1].B.SignExtend(Prec); } } inline static float Norm(_In_ const INTColor& a, _In_ const INTColor& b) { float dr = float(a.r) - float(b.r); float dg = float(a.g) - float(b.g); float db = float(a.b) - float(b.b); return dr * dr + dg * dg + db * db; } // return # of bits needed to store n. handle signed or unsigned cases properly inline static int NBits(_In_ int n, _In_ bool bIsSigned) { int nb; if(n == 0) { return 0; // no bits needed for 0, signed or not } else if(n > 0) { for(nb = 0; n; ++nb, n >>= 1); return nb + (bIsSigned ? 1 : 0); } else { assert(bIsSigned); for(nb = 0; n < -1; ++nb, n >>= 1) ; return nb + 1; } } //------------------------------------------------------------------------------------- static float OptimizeRGB(_In_reads_(NUM_PIXELS_PER_BLOCK) const HDRColorA* const pPoints, _Out_ HDRColorA* pX, _Out_ HDRColorA* pY, _In_ size_t cSteps, _In_ size_t cPixels, _In_reads_(cPixels) const size_t* pIndex) { float fError = FLT_MAX; const float *pC = (3 == cSteps) ? pC3 : pC4; const float *pD = (3 == cSteps) ? pD3 : pD4; // Find Min and Max points, as starting point HDRColorA X(1.0f, 1.0f, 1.0f, 0.0f); HDRColorA Y(0.0f, 0.0f, 0.0f, 0.0f); for(size_t iPoint = 0; iPoint < cPixels; iPoint++) { if(pPoints[pIndex[iPoint]].r < X.r) X.r = pPoints[pIndex[iPoint]].r; if(pPoints[pIndex[iPoint]].g < X.g) X.g = pPoints[pIndex[iPoint]].g; if(pPoints[pIndex[iPoint]].b < X.b) X.b = pPoints[pIndex[iPoint]].b; if(pPoints[pIndex[iPoint]].r > Y.r) Y.r = pPoints[pIndex[iPoint]].r; if(pPoints[pIndex[iPoint]].g > Y.g) Y.g = pPoints[pIndex[iPoint]].g; if(pPoints[pIndex[iPoint]].b > Y.b) Y.b = pPoints[pIndex[iPoint]].b; } // Diagonal axis HDRColorA AB; AB.r = Y.r - X.r; AB.g = Y.g - X.g; AB.b = Y.b - X.b; float fAB = AB.r * AB.r + AB.g * AB.g + AB.b * AB.b; // Single color block.. no need to root-find if(fAB < FLT_MIN) { pX->r = X.r; pX->g = X.g; pX->b = X.b; pY->r = Y.r; pY->g = Y.g; pY->b = Y.b; return 0.0f; } // Try all four axis directions, to determine which diagonal best fits data float fABInv = 1.0f / fAB; HDRColorA Dir; Dir.r = AB.r * fABInv; Dir.g = AB.g * fABInv; Dir.b = AB.b * fABInv; HDRColorA Mid; Mid.r = (X.r + Y.r) * 0.5f; Mid.g = (X.g + Y.g) * 0.5f; Mid.b = (X.b + Y.b) * 0.5f; float fDir[4]; fDir[0] = fDir[1] = fDir[2] = fDir[3] = 0.0f; for(size_t iPoint = 0; iPoint < cPixels; iPoint++) { HDRColorA Pt; Pt.r = (pPoints[pIndex[iPoint]].r - Mid.r) * Dir.r; Pt.g = (pPoints[pIndex[iPoint]].g - Mid.g) * Dir.g; Pt.b = (pPoints[pIndex[iPoint]].b - Mid.b) * Dir.b; float f; f = Pt.r + Pt.g + Pt.b; fDir[0] += f * f; f = Pt.r + Pt.g - Pt.b; fDir[1] += f * f; f = Pt.r - Pt.g + Pt.b; fDir[2] += f * f; f = Pt.r - Pt.g - Pt.b; fDir[3] += f * f; } float fDirMax = fDir[0]; size_t iDirMax = 0; for(size_t iDir = 1; iDir < 4; iDir++) { if(fDir[iDir] > fDirMax) { fDirMax = fDir[iDir]; iDirMax = iDir; } } if(iDirMax & 2) std::swap( X.g, Y.g ); if(iDirMax & 1) std::swap( X.b, Y.b ); // Two color block.. no need to root-find if(fAB < 1.0f / 4096.0f) { pX->r = X.r; pX->g = X.g; pX->b = X.b; pY->r = Y.r; pY->g = Y.g; pY->b = Y.b; return 0.0f; } // Use Newton's Method to find local minima of sum-of-squares error. float fSteps = (float) (cSteps - 1); for(size_t iIteration = 0; iIteration < 8; iIteration++) { // Calculate new steps HDRColorA pSteps[4] = {}; for(size_t iStep = 0; iStep < cSteps; iStep++) { pSteps[iStep].r = X.r * pC[iStep] + Y.r * pD[iStep]; pSteps[iStep].g = X.g * pC[iStep] + Y.g * pD[iStep]; pSteps[iStep].b = X.b * pC[iStep] + Y.b * pD[iStep]; } // Calculate color direction Dir.r = Y.r - X.r; Dir.g = Y.g - X.g; Dir.b = Y.b - X.b; float fLen = (Dir.r * Dir.r + Dir.g * Dir.g + Dir.b * Dir.b); if(fLen < (1.0f / 4096.0f)) break; float fScale = fSteps / fLen; Dir.r *= fScale; Dir.g *= fScale; Dir.b *= fScale; // Evaluate function, and derivatives float d2X = 0.0f, d2Y = 0.0f; HDRColorA dX(0.0f, 0.0f, 0.0f, 0.0f), dY(0.0f, 0.0f, 0.0f, 0.0f); for(size_t iPoint = 0; iPoint < cPixels; iPoint++) { float fDot = (pPoints[pIndex[iPoint]].r - X.r) * Dir.r + (pPoints[pIndex[iPoint]].g - X.g) * Dir.g + (pPoints[pIndex[iPoint]].b - X.b) * Dir.b; size_t iStep; if(fDot <= 0.0f) iStep = 0; if(fDot >= fSteps) iStep = cSteps - 1; else iStep = size_t(fDot + 0.5f); HDRColorA Diff; Diff.r = pSteps[iStep].r - pPoints[pIndex[iPoint]].r; Diff.g = pSteps[iStep].g - pPoints[pIndex[iPoint]].g; Diff.b = pSteps[iStep].b - pPoints[pIndex[iPoint]].b; float fC = pC[iStep] * (1.0f / 8.0f); float fD = pD[iStep] * (1.0f / 8.0f); d2X += fC * pC[iStep]; dX.r += fC * Diff.r; dX.g += fC * Diff.g; dX.b += fC * Diff.b; d2Y += fD * pD[iStep]; dY.r += fD * Diff.r; dY.g += fD * Diff.g; dY.b += fD * Diff.b; } // Move endpoints if(d2X > 0.0f) { float f = -1.0f / d2X; X.r += dX.r * f; X.g += dX.g * f; X.b += dX.b * f; } if(d2Y > 0.0f) { float f = -1.0f / d2Y; Y.r += dY.r * f; Y.g += dY.g * f; Y.b += dY.b * f; } if((dX.r * dX.r < fEpsilon) && (dX.g * dX.g < fEpsilon) && (dX.b * dX.b < fEpsilon) && (dY.r * dY.r < fEpsilon) && (dY.g * dY.g < fEpsilon) && (dY.b * dY.b < fEpsilon)) { break; } } pX->r = X.r; pX->g = X.g; pX->b = X.b; pY->r = Y.r; pY->g = Y.g; pY->b = Y.b; return fError; } //------------------------------------------------------------------------------------- static float OptimizeRGBA(_In_reads_(NUM_PIXELS_PER_BLOCK) const HDRColorA* const pPoints, _Out_ HDRColorA* pX, _Out_ HDRColorA* pY, _In_ size_t cSteps, _In_ size_t cPixels, _In_reads_(cPixels) const size_t* pIndex) { float fError = FLT_MAX; const float *pC = (3 == cSteps) ? pC3 : pC4; const float *pD = (3 == cSteps) ? pD3 : pD4; // Find Min and Max points, as starting point HDRColorA X(1.0f, 1.0f, 1.0f, 1.0f); HDRColorA Y(0.0f, 0.0f, 0.0f, 0.0f); for(size_t iPoint = 0; iPoint < cPixels; iPoint++) { if(pPoints[pIndex[iPoint]].r < X.r) X.r = pPoints[pIndex[iPoint]].r; if(pPoints[pIndex[iPoint]].g < X.g) X.g = pPoints[pIndex[iPoint]].g; if(pPoints[pIndex[iPoint]].b < X.b) X.b = pPoints[pIndex[iPoint]].b; if(pPoints[pIndex[iPoint]].a < X.a) X.a = pPoints[pIndex[iPoint]].a; if(pPoints[pIndex[iPoint]].r > Y.r) Y.r = pPoints[pIndex[iPoint]].r; if(pPoints[pIndex[iPoint]].g > Y.g) Y.g = pPoints[pIndex[iPoint]].g; if(pPoints[pIndex[iPoint]].b > Y.b) Y.b = pPoints[pIndex[iPoint]].b; if(pPoints[pIndex[iPoint]].a > Y.a) Y.a = pPoints[pIndex[iPoint]].a; } // Diagonal axis HDRColorA AB = Y - X; float fAB = AB * AB; // Single color block.. no need to root-find if(fAB < FLT_MIN) { *pX = X; *pY = Y; return 0.0f; } // Try all four axis directions, to determine which diagonal best fits data float fABInv = 1.0f / fAB; HDRColorA Dir = AB * fABInv; HDRColorA Mid = (X + Y) * 0.5f; float fDir[8]; fDir[0] = fDir[1] = fDir[2] = fDir[3] = fDir[4] = fDir[5] = fDir[6] = fDir[7] = 0.0f; for(size_t iPoint = 0; iPoint < cPixels; iPoint++) { HDRColorA Pt; Pt.r = (pPoints[pIndex[iPoint]].r - Mid.r) * Dir.r; Pt.g = (pPoints[pIndex[iPoint]].g - Mid.g) * Dir.g; Pt.b = (pPoints[pIndex[iPoint]].b - Mid.b) * Dir.b; Pt.a = (pPoints[pIndex[iPoint]].a - Mid.a) * Dir.a; float f; f = Pt.r + Pt.g + Pt.b + Pt.a; fDir[0] += f * f; f = Pt.r + Pt.g + Pt.b - Pt.a; fDir[1] += f * f; f = Pt.r + Pt.g - Pt.b + Pt.a; fDir[2] += f * f; f = Pt.r + Pt.g - Pt.b - Pt.a; fDir[3] += f * f; f = Pt.r - Pt.g + Pt.b + Pt.a; fDir[4] += f * f; f = Pt.r - Pt.g + Pt.b - Pt.a; fDir[5] += f * f; f = Pt.r - Pt.g - Pt.b + Pt.a; fDir[6] += f * f; f = Pt.r - Pt.g - Pt.b - Pt.a; fDir[7] += f * f; } float fDirMax = fDir[0]; size_t iDirMax = 0; for(size_t iDir = 1; iDir < 8; iDir++) { if(fDir[iDir] > fDirMax) { fDirMax = fDir[iDir]; iDirMax = iDir; } } if(iDirMax & 4) std::swap(X.g, Y.g); if(iDirMax & 2) std::swap(X.b, Y.b); if(iDirMax & 1) std::swap(X.a, Y.a); // Two color block.. no need to root-find if(fAB < 1.0f / 4096.0f) { *pX = X; *pY = Y; return 0.0f; } // Use Newton's Method to find local minima of sum-of-squares error. float fSteps = (float) (cSteps - 1); for(size_t iIteration = 0; iIteration < 8 && fError > 0.0f; iIteration++) { // Calculate new steps HDRColorA pSteps[BC7_MAX_INDICES]; LDRColorA lX, lY; lX = (X * 255.0f).ToLDRColorA(); lY = (Y * 255.0f).ToLDRColorA(); for(size_t iStep = 0; iStep < cSteps; iStep++) { pSteps[iStep] = X * pC[iStep] + Y * pD[iStep]; //LDRColorA::Interpolate(lX, lY, i, i, wcprec, waprec, aSteps[i]); } // Calculate color direction Dir = Y - X; float fLen = Dir * Dir; if(fLen < (1.0f / 4096.0f)) break; float fScale = fSteps / fLen; Dir *= fScale; // Evaluate function, and derivatives float d2X = 0.0f, d2Y = 0.0f; HDRColorA dX(0.0f, 0.0f, 0.0f, 0.0f), dY(0.0f, 0.0f, 0.0f, 0.0f); for(size_t iPoint = 0; iPoint < cPixels; ++iPoint) { float fDot = (pPoints[pIndex[iPoint]] - X) * Dir; size_t iStep; if(fDot <= 0.0f) iStep = 0; if(fDot >= fSteps) iStep = cSteps - 1; else iStep = size_t(fDot + 0.5f); HDRColorA Diff = pSteps[iStep] - pPoints[pIndex[iPoint]]; float fC = pC[iStep] * (1.0f / 8.0f); float fD = pD[iStep] * (1.0f / 8.0f); d2X += fC * pC[iStep]; dX += Diff * fC; d2Y += fD * pD[iStep]; dY += Diff * fD; } // Move endpoints if(d2X > 0.0f) { float f = -1.0f / d2X; X += dX * f; } if(d2Y > 0.0f) { float f = -1.0f / d2Y; Y += dY * f; } if((dX * dX < fEpsilon) && (dY * dY < fEpsilon)) break; } *pX = X; *pY = Y; return fError; } //------------------------------------------------------------------------------------- static float ComputeError(_Inout_ const LDRColorA& pixel, _In_reads_(1 << uIndexPrec) const LDRColorA aPalette[], _In_ uint8_t uIndexPrec, _In_ uint8_t uIndexPrec2, _Out_opt_ size_t* pBestIndex = nullptr, _Out_opt_ size_t* pBestIndex2 = nullptr) { const size_t uNumIndices = size_t(1) << uIndexPrec; const size_t uNumIndices2 = size_t(1) << uIndexPrec2; float fTotalErr = 0; float fBestErr = FLT_MAX; if(pBestIndex) *pBestIndex = 0; if(pBestIndex2) *pBestIndex2 = 0; XMVECTOR vpixel = XMLoadUByte4( reinterpret_cast( &pixel ) ); if(uIndexPrec2 == 0) { for(register size_t i = 0; i < uNumIndices && fBestErr > 0; i++) { XMVECTOR tpixel = XMLoadUByte4( reinterpret_cast( &aPalette[i] ) ); // Compute ErrorMetric tpixel = XMVectorSubtract( vpixel, tpixel ); float fErr = XMVectorGetX( XMVector4Dot( tpixel, tpixel ) ); if(fErr > fBestErr) // error increased, so we're done searching break; if(fErr < fBestErr) { fBestErr = fErr; if(pBestIndex) *pBestIndex = i; } } fTotalErr += fBestErr; } else { for(register size_t i = 0; i < uNumIndices && fBestErr > 0; i++) { XMVECTOR tpixel = XMLoadUByte4( reinterpret_cast( &aPalette[i] ) ); // Compute ErrorMetricRGB tpixel = XMVectorSubtract( vpixel, tpixel ); float fErr = XMVectorGetX( XMVector3Dot( tpixel, tpixel ) ); if(fErr > fBestErr) // error increased, so we're done searching break; if(fErr < fBestErr) { fBestErr = fErr; if(pBestIndex) *pBestIndex = i; } } fTotalErr += fBestErr; fBestErr = FLT_MAX; for(register size_t i = 0; i < uNumIndices2 && fBestErr > 0; i++) { // Compute ErrorMetricAlpha float ea = float(pixel.a) - float(aPalette[i].a); float fErr = ea*ea; if(fErr > fBestErr) // error increased, so we're done searching break; if(fErr < fBestErr) { fBestErr = fErr; if(pBestIndex2) *pBestIndex2 = i; } } fTotalErr += fBestErr; } return fTotalErr; } inline static void FillWithErrorColors( _Out_writes_(NUM_PIXELS_PER_BLOCK) HDRColorA* pOut ) { for(size_t i = 0; i < NUM_PIXELS_PER_BLOCK; ++i) { #ifdef _DEBUG // Use Magenta in debug as a highly-visible error color pOut[i] = HDRColorA(1.0f, 0.0f, 1.0f, 1.0f); #else // In production use, default to black pOut[i] = HDRColorA(0.0f, 0.0f, 0.0f, 1.0f); #endif } } //------------------------------------------------------------------------------------- // BC6H Compression //------------------------------------------------------------------------------------- _Use_decl_annotations_ void D3DX_BC6H::Decode(bool bSigned, HDRColorA* pOut) const { assert(pOut ); size_t uStartBit = 0; uint8_t uMode = GetBits(uStartBit, 2); if(uMode != 0x00 && uMode != 0x01) { uMode = (GetBits(uStartBit, 3) << 2) | uMode; } assert( uMode < 32 ); _Analysis_assume_( uMode < 32 ); if ( ms_aModeToInfo[uMode] >= 0 ) { assert(ms_aModeToInfo[uMode] < ARRAYSIZE(ms_aInfo)); _Analysis_assume_(ms_aModeToInfo[uMode] < ARRAYSIZE(ms_aInfo)); const ModeDescriptor* desc = ms_aDesc[ms_aModeToInfo[uMode]]; assert(ms_aModeToInfo[uMode] < ARRAYSIZE(ms_aDesc)); _Analysis_assume_(ms_aModeToInfo[uMode] < ARRAYSIZE(ms_aDesc)); const ModeInfo& info = ms_aInfo[ms_aModeToInfo[uMode]]; INTEndPntPair aEndPts[BC6H_MAX_REGIONS]; memset(aEndPts, 0, BC6H_MAX_REGIONS * 2 * sizeof(INTColor)); uint32_t uShape = 0; // Read header const size_t uHeaderBits = info.uPartitions > 0 ? 82 : 65; while(uStartBit < uHeaderBits) { size_t uCurBit = uStartBit; if(GetBit(uStartBit)) { switch(desc[uCurBit].m_eField) { case D: uShape |= 1 << uint32_t(desc[uCurBit].m_uBit); break; case RW: aEndPts[0].A.r |= 1 << uint32_t(desc[uCurBit].m_uBit); break; case RX: aEndPts[0].B.r |= 1 << uint32_t(desc[uCurBit].m_uBit); break; case RY: aEndPts[1].A.r |= 1 << uint32_t(desc[uCurBit].m_uBit); break; case RZ: aEndPts[1].B.r |= 1 << uint32_t(desc[uCurBit].m_uBit); break; case GW: aEndPts[0].A.g |= 1 << uint32_t(desc[uCurBit].m_uBit); break; case GX: aEndPts[0].B.g |= 1 << uint32_t(desc[uCurBit].m_uBit); break; case GY: aEndPts[1].A.g |= 1 << uint32_t(desc[uCurBit].m_uBit); break; case GZ: aEndPts[1].B.g |= 1 << uint32_t(desc[uCurBit].m_uBit); break; case BW: aEndPts[0].A.b |= 1 << uint32_t(desc[uCurBit].m_uBit); break; case BX: aEndPts[0].B.b |= 1 << uint32_t(desc[uCurBit].m_uBit); break; case BY: aEndPts[1].A.b |= 1 << uint32_t(desc[uCurBit].m_uBit); break; case BZ: aEndPts[1].B.b |= 1 << uint32_t(desc[uCurBit].m_uBit); break; default: { #ifdef _DEBUG OutputDebugStringA( "BC6H: Invalid header bits encountered during decoding\n" ); #endif FillWithErrorColors( pOut ); return; } } } } assert( uShape < 64 ); _Analysis_assume_( uShape < 64 ); // Sign extend necessary end points if(bSigned) { aEndPts[0].A.SignExtend(info.RGBAPrec[0][0]); } if(bSigned || info.bTransformed) { assert( info.uPartitions < BC6H_MAX_REGIONS ); _Analysis_assume_( info.uPartitions < BC6H_MAX_REGIONS ); for(size_t p = 0; p <= info.uPartitions; ++p) { if(p != 0) { aEndPts[p].A.SignExtend(info.RGBAPrec[p][0]); } aEndPts[p].B.SignExtend(info.RGBAPrec[p][1]); } } // Inverse transform the end points if(info.bTransformed) { TransformInverse(aEndPts, info.RGBAPrec[0][0], bSigned); } // Read indices for(size_t i = 0; i < NUM_PIXELS_PER_BLOCK; ++i) { size_t uNumBits = IsFixUpOffset(info.uPartitions, uShape, i) ? info.uIndexPrec-1 : info.uIndexPrec; if ( uStartBit + uNumBits > 128 ) { #ifdef _DEBUG OutputDebugStringA( "BC6H: Invalid block encountered during decoding\n" ); #endif FillWithErrorColors( pOut ); return; } uint8_t uIndex = GetBits(uStartBit, uNumBits); if ( uIndex >= ((info.uPartitions > 0) ? 8 : 16) ) { #ifdef _DEBUG OutputDebugStringA( "BC6H: Invalid index encountered during decoding\n" ); #endif FillWithErrorColors( pOut ); return; } size_t uRegion = g_aPartitionTable[info.uPartitions][uShape][i]; assert( uRegion < BC6H_MAX_REGIONS ); _Analysis_assume_( uRegion < BC6H_MAX_REGIONS ); // Unquantize endpoints and interpolate int r1 = Unquantize(aEndPts[uRegion].A.r, info.RGBAPrec[0][0].r, bSigned); int g1 = Unquantize(aEndPts[uRegion].A.g, info.RGBAPrec[0][0].g, bSigned); int b1 = Unquantize(aEndPts[uRegion].A.b, info.RGBAPrec[0][0].b, bSigned); int r2 = Unquantize(aEndPts[uRegion].B.r, info.RGBAPrec[0][0].r, bSigned); int g2 = Unquantize(aEndPts[uRegion].B.g, info.RGBAPrec[0][0].g, bSigned); int b2 = Unquantize(aEndPts[uRegion].B.b, info.RGBAPrec[0][0].b, bSigned); const int* aWeights = info.uPartitions > 0 ? g_aWeights3 : g_aWeights4; INTColor fc; fc.r = FinishUnquantize((r1 * (BC67_WEIGHT_MAX - aWeights[uIndex]) + r2 * aWeights[uIndex] + BC67_WEIGHT_ROUND) >> BC67_WEIGHT_SHIFT, bSigned); fc.g = FinishUnquantize((g1 * (BC67_WEIGHT_MAX - aWeights[uIndex]) + g2 * aWeights[uIndex] + BC67_WEIGHT_ROUND) >> BC67_WEIGHT_SHIFT, bSigned); fc.b = FinishUnquantize((b1 * (BC67_WEIGHT_MAX - aWeights[uIndex]) + b2 * aWeights[uIndex] + BC67_WEIGHT_ROUND) >> BC67_WEIGHT_SHIFT, bSigned); HALF rgb[3]; fc.ToF16(rgb, bSigned); pOut[i].r = XMConvertHalfToFloat( rgb[0] ); pOut[i].g = XMConvertHalfToFloat( rgb[1] ); pOut[i].b = XMConvertHalfToFloat( rgb[2] ); pOut[i].a = 1.0f; } } else { #ifdef _DEBUG const char* warnstr = "BC6H: Invalid mode encountered during decoding\n"; switch( uMode ) { case 0x13: warnstr = "BC6H: Reserved mode 10011 encountered during decoding\n"; break; case 0x17: warnstr = "BC6H: Reserved mode 10111 encountered during decoding\n"; break; case 0x1B: warnstr = "BC6H: Reserved mode 11011 encountered during decoding\n"; break; case 0x1F: warnstr = "BC6H: Reserved mode 11111 encountered during decoding\n"; break; } OutputDebugStringA( warnstr ); #endif // Per the BC6H format spec, we must return opaque black for(size_t i = 0; i < NUM_PIXELS_PER_BLOCK; ++i) { pOut[i] = HDRColorA(0.0f, 0.0f, 0.0f, 1.0f); } } } _Use_decl_annotations_ void D3DX_BC6H::Encode(bool bSigned, const HDRColorA* const pIn) { assert( pIn ); EncodeParams EP(pIn, bSigned); for(EP.uMode = 0; EP.uMode < ARRAYSIZE(ms_aInfo) && EP.fBestErr > 0; ++EP.uMode) { const uint8_t uShapes = ms_aInfo[EP.uMode].uPartitions ? 32 : 1; // Number of rough cases to look at. reasonable values of this are 1, uShapes/4, and uShapes // uShapes/4 gets nearly all the cases; you can increase that a bit (say by 3 or 4) if you really want to squeeze the last bit out const size_t uItems = std::max(1, uShapes >> 2); float afRoughMSE[BC6H_MAX_SHAPES]; uint8_t auShape[BC6H_MAX_SHAPES]; // pick the best uItems shapes and refine these. for(EP.uShape = 0; EP.uShape < uShapes; ++EP.uShape) { size_t uShape = EP.uShape; afRoughMSE[uShape] = RoughMSE(&EP); auShape[uShape] = static_cast(uShape); } // Bubble up the first uItems items for(register size_t i = 0; i < uItems; i++) { for(register size_t j = i + 1; j < uShapes; j++) { if(afRoughMSE[i] > afRoughMSE[j]) { std::swap(afRoughMSE[i], afRoughMSE[j]); std::swap(auShape[i], auShape[j]); } } } for(size_t i = 0; i < uItems && EP.fBestErr > 0; i++) { EP.uShape = auShape[i]; Refine(&EP); } } } //------------------------------------------------------------------------------------- _Use_decl_annotations_ int D3DX_BC6H::Quantize(int iValue, int prec, bool bSigned) { assert(prec > 1); // didn't bother to make it work for 1 int q, s = 0; if(bSigned) { assert(iValue >= -F16MAX && iValue <= F16MAX); if(iValue < 0) { s = 1; iValue = -iValue; } q = (prec >= 16) ? iValue : (iValue << (prec-1)) / (F16MAX+1); if(s) q = -q; assert (q > -(1 << (prec-1)) && q < (1 << (prec-1))); } else { assert(iValue >= 0 && iValue <= F16MAX); q = (prec >= 15) ? iValue : (iValue << prec) / (F16MAX+1); assert (q >= 0 && q < (1 << prec)); } return q; } _Use_decl_annotations_ int D3DX_BC6H::Unquantize(int comp, uint8_t uBitsPerComp, bool bSigned) { int unq = 0, s = 0; if(bSigned) { if(uBitsPerComp >= 16) { unq = comp; } else { if(comp < 0) { s = 1; comp = -comp; } if(comp == 0) unq = 0; else if(comp >= ((1 << (uBitsPerComp - 1)) - 1)) unq = 0x7FFF; else unq = ((comp << 15) + 0x4000) >> (uBitsPerComp-1); if(s) unq = -unq; } } else { if(uBitsPerComp >= 15) unq = comp; else if(comp == 0) unq = 0; else if(comp == ((1 << uBitsPerComp) - 1)) unq = 0xFFFF; else unq = ((comp << 16) + 0x8000) >> uBitsPerComp; } return unq; } _Use_decl_annotations_ int D3DX_BC6H::FinishUnquantize(int comp, bool bSigned) { if(bSigned) { return (comp < 0) ? -(((-comp) * 31) >> 5) : (comp * 31) >> 5; // scale the magnitude by 31/32 } else { return (comp * 31) >> 6; // scale the magnitude by 31/64 } } //------------------------------------------------------------------------------------- _Use_decl_annotations_ bool D3DX_BC6H::EndPointsFit(const EncodeParams* pEP, const INTEndPntPair aEndPts[]) { assert( pEP ); const bool bTransformed = ms_aInfo[pEP->uMode].bTransformed; const bool bIsSigned = pEP->bSigned; const LDRColorA& Prec0 = ms_aInfo[pEP->uMode].RGBAPrec[0][0]; const LDRColorA& Prec1 = ms_aInfo[pEP->uMode].RGBAPrec[0][1]; const LDRColorA& Prec2 = ms_aInfo[pEP->uMode].RGBAPrec[1][0]; const LDRColorA& Prec3 = ms_aInfo[pEP->uMode].RGBAPrec[1][1]; INTColor aBits[4]; aBits[0].r = NBits(aEndPts[0].A.r, bIsSigned); aBits[0].g = NBits(aEndPts[0].A.g, bIsSigned); aBits[0].b = NBits(aEndPts[0].A.b, bIsSigned); aBits[1].r = NBits(aEndPts[0].B.r, bTransformed || bIsSigned); aBits[1].g = NBits(aEndPts[0].B.g, bTransformed || bIsSigned); aBits[1].b = NBits(aEndPts[0].B.b, bTransformed || bIsSigned); if(aBits[0].r > Prec0.r || aBits[1].r > Prec1.r || aBits[0].g > Prec0.g || aBits[1].g > Prec1.g || aBits[0].b > Prec0.b || aBits[1].b > Prec1.b) return false; if(ms_aInfo[pEP->uMode].uPartitions) { aBits[2].r = NBits(aEndPts[1].A.r, bTransformed || bIsSigned); aBits[2].g = NBits(aEndPts[1].A.g, bTransformed || bIsSigned); aBits[2].b = NBits(aEndPts[1].A.b, bTransformed || bIsSigned); aBits[3].r = NBits(aEndPts[1].B.r, bTransformed || bIsSigned); aBits[3].g = NBits(aEndPts[1].B.g, bTransformed || bIsSigned); aBits[3].b = NBits(aEndPts[1].B.b, bTransformed || bIsSigned); if(aBits[2].r > Prec2.r || aBits[3].r > Prec3.r || aBits[2].g > Prec2.g || aBits[3].g > Prec3.g || aBits[2].b > Prec2.b || aBits[3].b > Prec3.b) return false; } return true; } _Use_decl_annotations_ void D3DX_BC6H::GeneratePaletteQuantized(const EncodeParams* pEP, const INTEndPntPair& endPts, INTColor aPalette[]) const { assert( pEP ); const size_t uIndexPrec = ms_aInfo[pEP->uMode].uIndexPrec; const size_t uNumIndices = size_t(1) << uIndexPrec; assert( uNumIndices > 0 ); _Analysis_assume_( uNumIndices > 0 ); const LDRColorA& Prec = ms_aInfo[pEP->uMode].RGBAPrec[0][0]; // scale endpoints INTEndPntPair unqEndPts; unqEndPts.A.r = Unquantize(endPts.A.r, Prec.r, pEP->bSigned); unqEndPts.A.g = Unquantize(endPts.A.g, Prec.g, pEP->bSigned); unqEndPts.A.b = Unquantize(endPts.A.b, Prec.b, pEP->bSigned); unqEndPts.B.r = Unquantize(endPts.B.r, Prec.r, pEP->bSigned); unqEndPts.B.g = Unquantize(endPts.B.g, Prec.g, pEP->bSigned); unqEndPts.B.b = Unquantize(endPts.B.b, Prec.b, pEP->bSigned); // interpolate const int* aWeights = nullptr; switch(uIndexPrec) { case 3: aWeights = g_aWeights3; assert(uNumIndices <= 8); _Analysis_assume_(uNumIndices <= 8); break; case 4: aWeights = g_aWeights4; assert(uNumIndices <= 16); _Analysis_assume_(uNumIndices <= 16); break; default: assert(false); for(size_t i = 0; i < uNumIndices; ++i) { #pragma prefast(suppress:22102 22103, "writing blocks in two halves confuses tool") aPalette[i] = INTColor(0,0,0); } return; } for (size_t i = 0; i < uNumIndices; ++i) { aPalette[i].r = FinishUnquantize( (unqEndPts.A.r * (BC67_WEIGHT_MAX - aWeights[i]) + unqEndPts.B.r * aWeights[i] + BC67_WEIGHT_ROUND) >> BC67_WEIGHT_SHIFT, pEP->bSigned); aPalette[i].g = FinishUnquantize( (unqEndPts.A.g * (BC67_WEIGHT_MAX - aWeights[i]) + unqEndPts.B.g * aWeights[i] + BC67_WEIGHT_ROUND) >> BC67_WEIGHT_SHIFT, pEP->bSigned); aPalette[i].b = FinishUnquantize( (unqEndPts.A.b * (BC67_WEIGHT_MAX - aWeights[i]) + unqEndPts.B.b * aWeights[i] + BC67_WEIGHT_ROUND) >> BC67_WEIGHT_SHIFT, pEP->bSigned); } } // given a collection of colors and quantized endpoints, generate a palette, choose best entries, and return a single toterr _Use_decl_annotations_ float D3DX_BC6H::MapColorsQuantized(const EncodeParams* pEP, const INTColor aColors[], size_t np, const INTEndPntPair &endPts) const { assert( pEP ); const uint8_t uIndexPrec = ms_aInfo[pEP->uMode].uIndexPrec; const uint8_t uNumIndices = 1 << uIndexPrec; INTColor aPalette[BC6H_MAX_INDICES]; GeneratePaletteQuantized(pEP, endPts, aPalette); float fTotErr = 0; for(size_t i = 0; i < np; ++i) { XMVECTOR vcolors = XMLoadSInt4( reinterpret_cast( &aColors[i] ) ); // Compute ErrorMetricRGB XMVECTOR tpal = XMLoadSInt4( reinterpret_cast( &aPalette[0] ) ); tpal = XMVectorSubtract( vcolors, tpal ); float fBestErr = XMVectorGetX( XMVector3Dot( tpal, tpal ) ); for(int j = 1; j < uNumIndices && fBestErr > 0; ++j) { // Compute ErrorMetricRGB tpal = XMLoadSInt4( reinterpret_cast( &aPalette[j] ) ); tpal = XMVectorSubtract( vcolors, tpal ); float fErr = XMVectorGetX( XMVector3Dot( tpal, tpal ) ); if(fErr > fBestErr) break; // error increased, so we're done searching if(fErr < fBestErr) fBestErr = fErr; } fTotErr += fBestErr; } return fTotErr; } _Use_decl_annotations_ float D3DX_BC6H::PerturbOne(const EncodeParams* pEP, const INTColor aColors[], size_t np, uint8_t ch, const INTEndPntPair& oldEndPts, INTEndPntPair& newEndPts, float fOldErr, int do_b) const { assert( pEP ); uint8_t uPrec; switch(ch) { case 0: uPrec = ms_aInfo[pEP->uMode].RGBAPrec[0][0].r; break; case 1: uPrec = ms_aInfo[pEP->uMode].RGBAPrec[0][0].g; break; case 2: uPrec = ms_aInfo[pEP->uMode].RGBAPrec[0][0].b; break; default: assert(false); newEndPts = oldEndPts; return FLT_MAX; } INTEndPntPair tmpEndPts; float fMinErr = fOldErr; int beststep = 0; // copy real endpoints so we can perturb them tmpEndPts = newEndPts = oldEndPts; // do a logarithmic search for the best error for this endpoint (which) for(int step = 1 << (uPrec-1); step; step >>= 1) { bool bImproved = false; for(int sign = -1; sign <= 1; sign += 2) { if(do_b == 0) { tmpEndPts.A[ch] = newEndPts.A[ch] + sign * step; if(tmpEndPts.A[ch] < 0 || tmpEndPts.A[ch] >= (1 << uPrec)) continue; } else { tmpEndPts.B[ch] = newEndPts.B[ch] + sign * step; if(tmpEndPts.B[ch] < 0 || tmpEndPts.B[ch] >= (1 << uPrec)) continue; } float fErr = MapColorsQuantized(pEP, aColors, np, tmpEndPts); if(fErr < fMinErr) { bImproved = true; fMinErr = fErr; beststep = sign * step; } } // if this was an improvement, move the endpoint and continue search from there if(bImproved) { if(do_b == 0) newEndPts.A[ch] += beststep; else newEndPts.B[ch] += beststep; } } return fMinErr; } _Use_decl_annotations_ void D3DX_BC6H::OptimizeOne(const EncodeParams* pEP, const INTColor aColors[], size_t np, float aOrgErr, const INTEndPntPair &aOrgEndPts, INTEndPntPair &aOptEndPts) const { assert( pEP ); float aOptErr = aOrgErr; aOptEndPts.A = aOrgEndPts.A; aOptEndPts.B = aOrgEndPts.B; INTEndPntPair new_a, new_b; INTEndPntPair newEndPts; int do_b; // now optimize each channel separately for(uint8_t ch = 0; ch < 3; ++ch) { // figure out which endpoint when perturbed gives the most improvement and start there // if we just alternate, we can easily end up in a local minima float fErr0 = PerturbOne(pEP, aColors, np, ch, aOptEndPts, new_a, aOptErr, 0); // perturb endpt A float fErr1 = PerturbOne(pEP, aColors, np, ch, aOptEndPts, new_b, aOptErr, 1); // perturb endpt B if(fErr0 < fErr1) { if(fErr0 >= aOptErr) continue; aOptEndPts.A[ch] = new_a.A[ch]; aOptErr = fErr0; do_b = 1; // do B next } else { if(fErr1 >= aOptErr) continue; aOptEndPts.B[ch] = new_b.B[ch]; aOptErr = fErr1; do_b = 0; // do A next } // now alternate endpoints and keep trying until there is no improvement for(;;) { float fErr = PerturbOne(pEP, aColors, np, ch, aOptEndPts, newEndPts, aOptErr, do_b); if(fErr >= aOptErr) break; if(do_b == 0) aOptEndPts.A[ch] = newEndPts.A[ch]; else aOptEndPts.B[ch] = newEndPts.B[ch]; aOptErr = fErr; do_b = 1 - do_b; // now move the other endpoint } } } _Use_decl_annotations_ void D3DX_BC6H::OptimizeEndPoints(const EncodeParams* pEP, const float aOrgErr[], const INTEndPntPair aOrgEndPts[], INTEndPntPair aOptEndPts[]) const { assert( pEP ); const uint8_t uPartitions = ms_aInfo[pEP->uMode].uPartitions; assert( uPartitions < BC6H_MAX_REGIONS ); _Analysis_assume_( uPartitions < BC6H_MAX_REGIONS ); INTColor aPixels[NUM_PIXELS_PER_BLOCK]; for(size_t p = 0; p <= uPartitions; ++p) { // collect the pixels in the region size_t np = 0; for(size_t i = 0; i < NUM_PIXELS_PER_BLOCK; ++i) { if(g_aPartitionTable[p][pEP->uShape][i] == p) { aPixels[np++] = pEP->aIPixels[i]; } } OptimizeOne(pEP, aPixels, np, aOrgErr[p], aOrgEndPts[p], aOptEndPts[p]); } } // Swap endpoints as needed to ensure that the indices at fix up have a 0 high-order bit _Use_decl_annotations_ void D3DX_BC6H::SwapIndices(const EncodeParams* pEP, INTEndPntPair aEndPts[], size_t aIndices[]) { assert( pEP ); const size_t uPartitions = ms_aInfo[pEP->uMode].uPartitions; const size_t uNumIndices = size_t(1) << ms_aInfo[pEP->uMode].uIndexPrec; const size_t uHighIndexBit = uNumIndices >> 1; assert( uPartitions < BC6H_MAX_REGIONS && pEP->uShape < BC6H_MAX_SHAPES ); _Analysis_assume_( uPartitions < BC6H_MAX_REGIONS && pEP->uShape < BC6H_MAX_SHAPES ); for(size_t p = 0; p <= uPartitions; ++p) { size_t i = g_aFixUp[uPartitions][pEP->uShape][p]; assert(g_aPartitionTable[uPartitions][pEP->uShape][i] == p); if(aIndices[i] & uHighIndexBit) { // high bit is set, swap the aEndPts and indices for this region std::swap(aEndPts[p].A, aEndPts[p].B); for(size_t j = 0; j < NUM_PIXELS_PER_BLOCK; ++j) if(g_aPartitionTable[uPartitions][pEP->uShape][j] == p) aIndices[j] = uNumIndices - 1 - aIndices[j]; } } } // assign indices given a tile, shape, and quantized endpoints, return toterr for each region _Use_decl_annotations_ void D3DX_BC6H::AssignIndices(const EncodeParams* pEP, const INTEndPntPair aEndPts[], size_t aIndices[], float aTotErr[]) const { assert( pEP ); const uint8_t uPartitions = ms_aInfo[pEP->uMode].uPartitions; const uint8_t uNumIndices = 1 << ms_aInfo[pEP->uMode].uIndexPrec; assert( uPartitions < BC6H_MAX_REGIONS && pEP->uShape < BC6H_MAX_SHAPES ); _Analysis_assume_( uPartitions < BC6H_MAX_REGIONS && pEP->uShape < BC6H_MAX_SHAPES ); // build list of possibles INTColor aPalette[BC6H_MAX_REGIONS][BC6H_MAX_INDICES]; for(size_t p = 0; p <= uPartitions; ++p) { GeneratePaletteQuantized(pEP, aEndPts[p], aPalette[p]); aTotErr[p] = 0; } for(size_t i = 0; i < NUM_PIXELS_PER_BLOCK; ++i) { const uint8_t uRegion = g_aPartitionTable[uPartitions][pEP->uShape][i]; assert( uRegion < BC6H_MAX_REGIONS ); _Analysis_assume_( uRegion < BC6H_MAX_REGIONS ); float fBestErr = Norm(pEP->aIPixels[i], aPalette[uRegion][0]); aIndices[i] = 0; for(uint8_t j = 1; j < uNumIndices && fBestErr > 0; ++j) { float fErr = Norm(pEP->aIPixels[i], aPalette[uRegion][j]); if(fErr > fBestErr) break; // error increased, so we're done searching if(fErr < fBestErr) { fBestErr = fErr; aIndices[i] = j; } } aTotErr[uRegion] += fBestErr; } } _Use_decl_annotations_ void D3DX_BC6H::QuantizeEndPts(const EncodeParams* pEP, INTEndPntPair* aQntEndPts) const { assert( pEP && aQntEndPts ); const INTEndPntPair* aUnqEndPts = pEP->aUnqEndPts[pEP->uShape]; const LDRColorA& Prec = ms_aInfo[pEP->uMode].RGBAPrec[0][0]; const uint8_t uPartitions = ms_aInfo[pEP->uMode].uPartitions; assert( uPartitions < BC6H_MAX_REGIONS ); _Analysis_assume_( uPartitions < BC6H_MAX_REGIONS ); for(size_t p = 0; p <= uPartitions; ++p) { aQntEndPts[p].A.r = Quantize(aUnqEndPts[p].A.r, Prec.r, pEP->bSigned); aQntEndPts[p].A.g = Quantize(aUnqEndPts[p].A.g, Prec.g, pEP->bSigned); aQntEndPts[p].A.b = Quantize(aUnqEndPts[p].A.b, Prec.b, pEP->bSigned); aQntEndPts[p].B.r = Quantize(aUnqEndPts[p].B.r, Prec.r, pEP->bSigned); aQntEndPts[p].B.g = Quantize(aUnqEndPts[p].B.g, Prec.g, pEP->bSigned); aQntEndPts[p].B.b = Quantize(aUnqEndPts[p].B.b, Prec.b, pEP->bSigned); } } _Use_decl_annotations_ void D3DX_BC6H::EmitBlock(const EncodeParams* pEP, const INTEndPntPair aEndPts[], const size_t aIndices[]) { assert( pEP ); const uint8_t uRealMode = ms_aInfo[pEP->uMode].uMode; const uint8_t uPartitions = ms_aInfo[pEP->uMode].uPartitions; const uint8_t uIndexPrec = ms_aInfo[pEP->uMode].uIndexPrec; const size_t uHeaderBits = uPartitions > 0 ? 82 : 65; const ModeDescriptor* desc = ms_aDesc[pEP->uMode]; size_t uStartBit = 0; while(uStartBit < uHeaderBits) { switch(desc[uStartBit].m_eField) { case M: SetBit(uStartBit, uint8_t(uRealMode >> desc[uStartBit].m_uBit) & 0x01); break; case D: SetBit(uStartBit, uint8_t(pEP->uShape >> desc[uStartBit].m_uBit) & 0x01); break; case RW: SetBit(uStartBit, uint8_t(aEndPts[0].A.r >> desc[uStartBit].m_uBit) & 0x01); break; case RX: SetBit(uStartBit, uint8_t(aEndPts[0].B.r >> desc[uStartBit].m_uBit) & 0x01); break; case RY: SetBit(uStartBit, uint8_t(aEndPts[1].A.r >> desc[uStartBit].m_uBit) & 0x01); break; case RZ: SetBit(uStartBit, uint8_t(aEndPts[1].B.r >> desc[uStartBit].m_uBit) & 0x01); break; case GW: SetBit(uStartBit, uint8_t(aEndPts[0].A.g >> desc[uStartBit].m_uBit) & 0x01); break; case GX: SetBit(uStartBit, uint8_t(aEndPts[0].B.g >> desc[uStartBit].m_uBit) & 0x01); break; case GY: SetBit(uStartBit, uint8_t(aEndPts[1].A.g >> desc[uStartBit].m_uBit) & 0x01); break; case GZ: SetBit(uStartBit, uint8_t(aEndPts[1].B.g >> desc[uStartBit].m_uBit) & 0x01); break; case BW: SetBit(uStartBit, uint8_t(aEndPts[0].A.b >> desc[uStartBit].m_uBit) & 0x01); break; case BX: SetBit(uStartBit, uint8_t(aEndPts[0].B.b >> desc[uStartBit].m_uBit) & 0x01); break; case BY: SetBit(uStartBit, uint8_t(aEndPts[1].A.b >> desc[uStartBit].m_uBit) & 0x01); break; case BZ: SetBit(uStartBit, uint8_t(aEndPts[1].B.b >> desc[uStartBit].m_uBit) & 0x01); break; default: assert(false); } } for(size_t i = 0; i < NUM_PIXELS_PER_BLOCK; ++i) { if(IsFixUpOffset(ms_aInfo[pEP->uMode].uPartitions, pEP->uShape, i)) SetBits(uStartBit, uIndexPrec - 1, static_cast( aIndices[i] )); else SetBits(uStartBit, uIndexPrec, static_cast( aIndices[i] )); } assert(uStartBit == 128); } _Use_decl_annotations_ void D3DX_BC6H::Refine(EncodeParams* pEP) { assert( pEP ); const uint8_t uPartitions = ms_aInfo[pEP->uMode].uPartitions; assert( uPartitions < BC6H_MAX_REGIONS ); _Analysis_assume_( uPartitions < BC6H_MAX_REGIONS ); const bool bTransformed = ms_aInfo[pEP->uMode].bTransformed; float aOrgErr[BC6H_MAX_REGIONS], aOptErr[BC6H_MAX_REGIONS]; INTEndPntPair aOrgEndPts[BC6H_MAX_REGIONS], aOptEndPts[BC6H_MAX_REGIONS]; size_t aOrgIdx[NUM_PIXELS_PER_BLOCK], aOptIdx[NUM_PIXELS_PER_BLOCK]; QuantizeEndPts(pEP, aOrgEndPts); AssignIndices(pEP, aOrgEndPts, aOrgIdx, aOrgErr); SwapIndices(pEP, aOrgEndPts, aOrgIdx); if(bTransformed) TransformForward(aOrgEndPts); if(EndPointsFit(pEP, aOrgEndPts)) { if(bTransformed) TransformInverse(aOrgEndPts, ms_aInfo[pEP->uMode].RGBAPrec[0][0], pEP->bSigned); OptimizeEndPoints(pEP, aOrgErr, aOrgEndPts, aOptEndPts); AssignIndices(pEP, aOptEndPts, aOptIdx, aOptErr); SwapIndices(pEP, aOptEndPts, aOptIdx); float fOrgTotErr = 0.0f, fOptTotErr = 0.0f; for(size_t p = 0; p <= uPartitions; ++p) { fOrgTotErr += aOrgErr[p]; fOptTotErr += aOptErr[p]; } if(bTransformed) TransformForward(aOptEndPts); if(EndPointsFit(pEP, aOptEndPts) && fOptTotErr < fOrgTotErr && fOptTotErr < pEP->fBestErr) { pEP->fBestErr = fOptTotErr; EmitBlock(pEP, aOptEndPts, aOptIdx); } else if(fOrgTotErr < pEP->fBestErr) { // either it stopped fitting when we optimized it, or there was no improvement // so go back to the unoptimized endpoints which we know will fit if(bTransformed) TransformForward(aOrgEndPts); pEP->fBestErr = fOrgTotErr; EmitBlock(pEP, aOrgEndPts, aOrgIdx); } } } _Use_decl_annotations_ void D3DX_BC6H::GeneratePaletteUnquantized(const EncodeParams* pEP, size_t uRegion, INTColor aPalette[]) { assert( pEP ); assert( uRegion < BC6H_MAX_REGIONS && pEP->uShape < BC6H_MAX_SHAPES ); _Analysis_assume_( uRegion < BC6H_MAX_REGIONS && pEP->uShape < BC6H_MAX_SHAPES ); const INTEndPntPair& endPts = pEP->aUnqEndPts[pEP->uShape][uRegion]; const uint8_t uIndexPrec = ms_aInfo[pEP->uMode].uIndexPrec; const uint8_t uNumIndices = 1 << uIndexPrec; assert(uNumIndices > 0); _Analysis_assume_(uNumIndices > 0); const int* aWeights = nullptr; switch(uIndexPrec) { case 3: aWeights = g_aWeights3; assert(uNumIndices <= 8); _Analysis_assume_(uNumIndices <= 8); break; case 4: aWeights = g_aWeights4; assert(uNumIndices <= 16); _Analysis_assume_(uNumIndices <= 16); break; default: assert(false); for(size_t i = 0; i < uNumIndices; ++i) { #pragma prefast(suppress:22102 22103, "writing blocks in two halves confuses tool") aPalette[i] = INTColor(0,0,0); } return; } for(register size_t i = 0; i < uNumIndices; ++i) { aPalette[i].r = (endPts.A.r * (BC67_WEIGHT_MAX - aWeights[i]) + endPts.B.r * aWeights[i] + BC67_WEIGHT_ROUND) >> BC67_WEIGHT_SHIFT; aPalette[i].g = (endPts.A.g * (BC67_WEIGHT_MAX - aWeights[i]) + endPts.B.g * aWeights[i] + BC67_WEIGHT_ROUND) >> BC67_WEIGHT_SHIFT; aPalette[i].b = (endPts.A.b * (BC67_WEIGHT_MAX - aWeights[i]) + endPts.B.b * aWeights[i] + BC67_WEIGHT_ROUND) >> BC67_WEIGHT_SHIFT; } } _Use_decl_annotations_ float D3DX_BC6H::MapColors(const EncodeParams* pEP, size_t uRegion, size_t np, const size_t* auIndex) const { assert( pEP ); const uint8_t uIndexPrec = ms_aInfo[pEP->uMode].uIndexPrec; const uint8_t uNumIndices = 1 << uIndexPrec; INTColor aPalette[BC6H_MAX_INDICES]; GeneratePaletteUnquantized(pEP, uRegion, aPalette); float fTotalErr = 0.0f; for(size_t i = 0; i < np; ++i) { float fBestErr = Norm(pEP->aIPixels[auIndex[i]], aPalette[0]); for(uint8_t j = 1; j < uNumIndices && fBestErr > 0.0f; ++j) { float fErr = Norm(pEP->aIPixels[auIndex[i]], aPalette[j]); if(fErr > fBestErr) break; // error increased, so we're done searching if(fErr < fBestErr) fBestErr = fErr; } fTotalErr += fBestErr; } return fTotalErr; } _Use_decl_annotations_ float D3DX_BC6H::RoughMSE(EncodeParams* pEP) const { assert( pEP ); assert( pEP->uShape < BC6H_MAX_SHAPES); _Analysis_assume_( pEP->uShape < BC6H_MAX_SHAPES); INTEndPntPair* aEndPts = pEP->aUnqEndPts[pEP->uShape]; const uint8_t uPartitions = ms_aInfo[pEP->uMode].uPartitions; assert( uPartitions < BC6H_MAX_REGIONS ); _Analysis_assume_( uPartitions < BC6H_MAX_REGIONS ); size_t auPixIdx[NUM_PIXELS_PER_BLOCK]; float fError = 0.0f; for(size_t p = 0; p <= uPartitions; ++p) { size_t np = 0; for(register size_t i = 0; i < NUM_PIXELS_PER_BLOCK; ++i) { if(g_aPartitionTable[uPartitions][pEP->uShape][i] == p) { auPixIdx[np++] = i; } } // handle simple cases assert(np > 0); if(np == 1) { aEndPts[p].A = pEP->aIPixels[auPixIdx[0]]; aEndPts[p].B = pEP->aIPixels[auPixIdx[0]]; continue; } else if(np == 2) { aEndPts[p].A = pEP->aIPixels[auPixIdx[0]]; aEndPts[p].B = pEP->aIPixels[auPixIdx[1]]; continue; } HDRColorA epA, epB; OptimizeRGB(pEP->aHDRPixels, &epA, &epB, 4, np, auPixIdx); aEndPts[p].A.Set(epA, pEP->bSigned); aEndPts[p].B.Set(epB, pEP->bSigned); if(pEP->bSigned) { aEndPts[p].A.Clamp(-F16MAX, F16MAX); aEndPts[p].B.Clamp(-F16MAX, F16MAX); } else { aEndPts[p].A.Clamp(0, F16MAX); aEndPts[p].B.Clamp(0, F16MAX); } fError += MapColors(pEP, p, np, auPixIdx); } return fError; } //------------------------------------------------------------------------------------- // BC7 Compression //------------------------------------------------------------------------------------- _Use_decl_annotations_ void D3DX_BC7::Decode(HDRColorA* pOut) const { assert( pOut ); size_t uFirst = 0; while(uFirst < 128 && !GetBit(uFirst)) {} uint8_t uMode = uint8_t(uFirst - 1); if(uMode < 8) { const uint8_t uPartitions = ms_aInfo[uMode].uPartitions; assert( uPartitions < BC7_MAX_REGIONS ); _Analysis_assume_( uPartitions < BC7_MAX_REGIONS ); const uint8_t uNumEndPts = (uPartitions + 1) << 1; const uint8_t uIndexPrec = ms_aInfo[uMode].uIndexPrec; const uint8_t uIndexPrec2 = ms_aInfo[uMode].uIndexPrec2; register size_t i; size_t uStartBit = uMode + 1; uint8_t P[6]; uint8_t uShape = GetBits(uStartBit, ms_aInfo[uMode].uPartitionBits); assert( uShape < BC7_MAX_SHAPES ); _Analysis_assume_( uShape < BC7_MAX_SHAPES ); uint8_t uRotation = GetBits(uStartBit, ms_aInfo[uMode].uRotationBits); assert( uRotation < 4 ); uint8_t uIndexMode = GetBits(uStartBit, ms_aInfo[uMode].uIndexModeBits); assert( uIndexMode < 2 ); LDRColorA c[BC7_MAX_REGIONS << 1]; const LDRColorA RGBAPrec = ms_aInfo[uMode].RGBAPrec; const LDRColorA RGBAPrecWithP = ms_aInfo[uMode].RGBAPrecWithP; assert( uNumEndPts <= (BC7_MAX_REGIONS << 1) ); // Red channel for(i = 0; i < uNumEndPts; i++) { if ( uStartBit + RGBAPrec.r > 128 ) { #ifdef _DEBUG OutputDebugStringA( "BC7: Invalid block encountered during decoding\n" ); #endif FillWithErrorColors( pOut ); return; } c[i].r = GetBits(uStartBit, RGBAPrec.r); } // Green channel for(i = 0; i < uNumEndPts; i++) { if ( uStartBit + RGBAPrec.g > 128 ) { #ifdef _DEBUG OutputDebugStringA( "BC7: Invalid block encountered during decoding\n" ); #endif FillWithErrorColors( pOut ); return; } c[i].g = GetBits(uStartBit, RGBAPrec.g); } // Blue channel for(i = 0; i < uNumEndPts; i++) { if ( uStartBit + RGBAPrec.b > 128 ) { #ifdef _DEBUG OutputDebugStringA( "BC7: Invalid block encountered during decoding\n" ); #endif FillWithErrorColors( pOut ); return; } c[i].b = GetBits(uStartBit, RGBAPrec.b); } // Alpha channel for(i = 0; i < uNumEndPts; i++) { if ( uStartBit + RGBAPrec.a > 128 ) { #ifdef _DEBUG OutputDebugStringA( "BC7: Invalid block encountered during decoding\n" ); #endif FillWithErrorColors( pOut ); return; } c[i].a = RGBAPrec.a ? GetBits(uStartBit, RGBAPrec.a) : 255; } // P-bits assert( ms_aInfo[uMode].uPBits <= 6 ); _Analysis_assume_( ms_aInfo[uMode].uPBits <= 6 ); for(i = 0; i < ms_aInfo[uMode].uPBits; i++) { if ( uStartBit > 127 ) { #ifdef _DEBUG OutputDebugStringA( "BC7: Invalid block encountered during decoding\n" ); #endif FillWithErrorColors( pOut ); return; } P[i] = GetBit(uStartBit); } if(ms_aInfo[uMode].uPBits) { for(i = 0; i < uNumEndPts; i++) { size_t pi = i * ms_aInfo[uMode].uPBits / uNumEndPts; for(register uint8_t ch = 0; ch < BC7_NUM_CHANNELS; ch++) { if(RGBAPrec[ch] != RGBAPrecWithP[ch]) { c[i][ch] = (c[i][ch] << 1) | P[pi]; } } } } for(i = 0; i < uNumEndPts; i++) { c[i] = Unquantize(c[i], RGBAPrecWithP); } uint8_t w1[NUM_PIXELS_PER_BLOCK], w2[NUM_PIXELS_PER_BLOCK]; // read color indices for(i = 0; i < NUM_PIXELS_PER_BLOCK; i++) { size_t uNumBits = IsFixUpOffset(ms_aInfo[uMode].uPartitions, uShape, i) ? uIndexPrec - 1 : uIndexPrec; if ( uStartBit + uNumBits > 128 ) { #ifdef _DEBUG OutputDebugStringA( "BC7: Invalid block encountered during decoding\n" ); #endif FillWithErrorColors( pOut ); return; } w1[i] = GetBits(uStartBit, uNumBits); } // read alpha indices if(uIndexPrec2) { for(i = 0; i < NUM_PIXELS_PER_BLOCK; i++) { size_t uNumBits = i ? uIndexPrec2 : uIndexPrec2 - 1; if ( uStartBit + uNumBits > 128 ) { #ifdef _DEBUG OutputDebugStringA( "BC7: Invalid block encountered during decoding\n" ); #endif FillWithErrorColors( pOut ); return; } w2[i] = GetBits(uStartBit, uNumBits ); } } for(i = 0; i < NUM_PIXELS_PER_BLOCK; ++i) { uint8_t uRegion = g_aPartitionTable[uPartitions][uShape][i]; LDRColorA outPixel; if(uIndexPrec2 == 0) { LDRColorA::Interpolate(c[uRegion << 1], c[(uRegion << 1) + 1], w1[i], w1[i], uIndexPrec, uIndexPrec, outPixel); } else { if(uIndexMode == 0) { LDRColorA::Interpolate(c[uRegion << 1], c[(uRegion << 1) + 1], w1[i], w2[i], uIndexPrec, uIndexPrec2, outPixel); } else { LDRColorA::Interpolate(c[uRegion << 1], c[(uRegion << 1) + 1], w2[i], w1[i], uIndexPrec2, uIndexPrec, outPixel); } } switch(uRotation) { case 1: std::swap(outPixel.r, outPixel.a); break; case 2: std::swap(outPixel.g, outPixel.a); break; case 3: std::swap(outPixel.b, outPixel.a); break; } pOut[i] = HDRColorA(outPixel); } } else { #ifdef _DEBUG OutputDebugStringA( "BC7: Reserved mode 8 encountered during decoding\n" ); #endif // Per the BC7 format spec, we must return transparent black memset( pOut, 0, sizeof(HDRColorA) * NUM_PIXELS_PER_BLOCK ); } } _Use_decl_annotations_ void D3DX_BC7::Encode(bool skip3subsets, const HDRColorA* const pIn) { assert( pIn ); D3DX_BC7 final = *this; EncodeParams EP(pIn); float fMSEBest = FLT_MAX; for(size_t i = 0; i < NUM_PIXELS_PER_BLOCK; ++i) { EP.aLDRPixels[i].r = uint8_t( std::max( 0.0f, std::min( 255.0f, pIn[i].r * 255.0f + 0.01f ) ) ); EP.aLDRPixels[i].g = uint8_t( std::max( 0.0f, std::min( 255.0f, pIn[i].g * 255.0f + 0.01f ) ) ); EP.aLDRPixels[i].b = uint8_t( std::max( 0.0f, std::min( 255.0f, pIn[i].b * 255.0f + 0.01f ) ) ); EP.aLDRPixels[i].a = uint8_t( std::max( 0.0f, std::min( 255.0f, pIn[i].a * 255.0f + 0.01f ) ) ); } for(EP.uMode = 0; EP.uMode < 8 && fMSEBest > 0; ++EP.uMode) { if ( skip3subsets && (EP.uMode == 0 || EP.uMode == 2) ) { // 3 subset modes tend to be used rarely and add significant compression time continue; } const size_t uShapes = size_t(1) << ms_aInfo[EP.uMode].uPartitionBits; assert( uShapes <= BC7_MAX_SHAPES ); _Analysis_assume_( uShapes <= BC7_MAX_SHAPES ); const size_t uNumRots = size_t(1) << ms_aInfo[EP.uMode].uRotationBits; const size_t uNumIdxMode = size_t(1) << ms_aInfo[EP.uMode].uIndexModeBits; // Number of rough cases to look at. reasonable values of this are 1, uShapes/4, and uShapes // uShapes/4 gets nearly all the cases; you can increase that a bit (say by 3 or 4) if you really want to squeeze the last bit out const size_t uItems = std::max(1, uShapes >> 2); float afRoughMSE[BC7_MAX_SHAPES]; size_t auShape[BC7_MAX_SHAPES]; for(size_t r = 0; r < uNumRots && fMSEBest > 0; ++r) { switch(r) { case 1: for(register size_t i = 0; i < NUM_PIXELS_PER_BLOCK; i++) std::swap(EP.aLDRPixels[i].r, EP.aLDRPixels[i].a); break; case 2: for(register size_t i = 0; i < NUM_PIXELS_PER_BLOCK; i++) std::swap(EP.aLDRPixels[i].g, EP.aLDRPixels[i].a); break; case 3: for(register size_t i = 0; i < NUM_PIXELS_PER_BLOCK; i++) std::swap(EP.aLDRPixels[i].b, EP.aLDRPixels[i].a); break; } for(size_t im = 0; im < uNumIdxMode && fMSEBest > 0; ++im) { // pick the best uItems shapes and refine these. for(size_t s = 0; s < uShapes; s++) { afRoughMSE[s] = RoughMSE(&EP, s, im); auShape[s] = s; } // Bubble up the first uItems items for(size_t i = 0; i < uItems; i++) { for(size_t j = i + 1; j < uShapes; j++) { if(afRoughMSE[i] > afRoughMSE[j]) { std::swap(afRoughMSE[i], afRoughMSE[j]); std::swap(auShape[i], auShape[j]); } } } for(size_t i = 0; i < uItems && fMSEBest > 0; i++) { float fMSE = Refine(&EP, auShape[i], r, im); if(fMSE < fMSEBest) { final = *this; fMSEBest = fMSE; } } } switch(r) { case 1: for(register size_t i = 0; i < NUM_PIXELS_PER_BLOCK; i++) std::swap(EP.aLDRPixels[i].r, EP.aLDRPixels[i].a); break; case 2: for(register size_t i = 0; i < NUM_PIXELS_PER_BLOCK; i++) std::swap(EP.aLDRPixels[i].g, EP.aLDRPixels[i].a); break; case 3: for(register size_t i = 0; i < NUM_PIXELS_PER_BLOCK; i++) std::swap(EP.aLDRPixels[i].b, EP.aLDRPixels[i].a); break; } } } *this = final; } //------------------------------------------------------------------------------------- _Use_decl_annotations_ void D3DX_BC7::GeneratePaletteQuantized(const EncodeParams* pEP, size_t uIndexMode, const LDREndPntPair& endPts, LDRColorA aPalette[]) const { assert( pEP ); const size_t uIndexPrec = uIndexMode ? ms_aInfo[pEP->uMode].uIndexPrec2 : ms_aInfo[pEP->uMode].uIndexPrec; const size_t uIndexPrec2 = uIndexMode ? ms_aInfo[pEP->uMode].uIndexPrec : ms_aInfo[pEP->uMode].uIndexPrec2; const size_t uNumIndices = size_t(1) << uIndexPrec; const size_t uNumIndices2 = size_t(1) << uIndexPrec2; assert( uNumIndices > 0 && uNumIndices2 > 0 ); _Analysis_assume_( uNumIndices > 0 && uNumIndices2 > 0 ); assert( (uNumIndices <= BC7_MAX_INDICES) && (uNumIndices2 <= BC7_MAX_INDICES) ); _Analysis_assume_( (uNumIndices <= BC7_MAX_INDICES) && (uNumIndices2 <= BC7_MAX_INDICES) ); LDRColorA a = Unquantize(endPts.A, ms_aInfo[pEP->uMode].RGBAPrecWithP); LDRColorA b = Unquantize(endPts.B, ms_aInfo[pEP->uMode].RGBAPrecWithP); if(uIndexPrec2 == 0) { for(register size_t i = 0; i < uNumIndices; i++) LDRColorA::Interpolate(a, b, i, i, uIndexPrec, uIndexPrec, aPalette[i]); } else { for(register size_t i = 0; i < uNumIndices; i++) LDRColorA::InterpolateRGB(a, b, i, uIndexPrec, aPalette[i]); for(register size_t i = 0; i < uNumIndices2; i++) LDRColorA::InterpolateA(a, b, i, uIndexPrec2, aPalette[i]); } } _Use_decl_annotations_ float D3DX_BC7::PerturbOne(const EncodeParams* pEP, const LDRColorA aColors[], size_t np, size_t uIndexMode, size_t ch, const LDREndPntPair &oldEndPts, LDREndPntPair &newEndPts, float fOldErr, uint8_t do_b) const { assert( pEP ); const int prec = ms_aInfo[pEP->uMode].RGBAPrecWithP[ch]; LDREndPntPair tmp_endPts = newEndPts = oldEndPts; float fMinErr = fOldErr; uint8_t* pnew_c = (do_b ? &newEndPts.B[ch] : &newEndPts.A[ch]); uint8_t* ptmp_c = (do_b ? &tmp_endPts.B[ch] : &tmp_endPts.A[ch]); // do a logarithmic search for the best error for this endpoint (which) for(int step = 1 << (prec-1); step; step >>= 1) { bool bImproved = false; int beststep = 0; for(int sign = -1; sign <= 1; sign += 2) { int tmp = int(*pnew_c) + sign * step; if(tmp < 0 || tmp >= (1 << prec)) continue; else *ptmp_c = (uint8_t) tmp; float fTotalErr = MapColors(pEP, aColors, np, uIndexMode, tmp_endPts, fMinErr); if(fTotalErr < fMinErr) { bImproved = true; fMinErr = fTotalErr; beststep = sign * step; } } // if this was an improvement, move the endpoint and continue search from there if(bImproved) *pnew_c = uint8_t(int(*pnew_c) + beststep); } return fMinErr; } // perturb the endpoints at least -3 to 3. // always ensure endpoint ordering is preserved (no need to overlap the scan) _Use_decl_annotations_ void D3DX_BC7::Exhaustive(const EncodeParams* pEP, const LDRColorA aColors[], size_t np, size_t uIndexMode, size_t ch, float& fOrgErr, LDREndPntPair& optEndPt) const { assert( pEP ); const uint8_t uPrec = ms_aInfo[pEP->uMode].RGBAPrecWithP[ch]; LDREndPntPair tmpEndPt; if(fOrgErr == 0) return; int delta = 5; // ok figure out the range of A and B tmpEndPt = optEndPt; int alow = std::max(0, int(optEndPt.A[ch]) - delta); int ahigh = std::min((1 << uPrec) - 1, int(optEndPt.A[ch]) + delta); int blow = std::max(0, int(optEndPt.B[ch]) - delta); int bhigh = std::min((1 << uPrec) - 1, int(optEndPt.B[ch]) + delta); int amin = 0; int bmin = 0; float fBestErr = fOrgErr; if(optEndPt.A[ch] <= optEndPt.B[ch]) { // keep a <= b for(int a = alow; a <= ahigh; ++a) { for(int b = std::max(a, blow); b < bhigh; ++b) { tmpEndPt.A[ch] = (uint8_t) a; tmpEndPt.B[ch] = (uint8_t) b; float fErr = MapColors(pEP, aColors, np, uIndexMode, tmpEndPt, fBestErr); if(fErr < fBestErr) { amin = a; bmin = b; fBestErr = fErr; } } } } else { // keep b <= a for(int b = blow; b < bhigh; ++b) { for(int a = std::max(b, alow); a <= ahigh; ++a) { tmpEndPt.A[ch] = (uint8_t) a; tmpEndPt.B[ch] = (uint8_t) b; float fErr = MapColors(pEP, aColors, np, uIndexMode, tmpEndPt, fBestErr); if(fErr < fBestErr) { amin = a; bmin = b; fBestErr = fErr; } } } } if(fBestErr < fOrgErr) { optEndPt.A[ch] = (uint8_t) amin; optEndPt.B[ch] = (uint8_t) bmin; fOrgErr = fBestErr; } } _Use_decl_annotations_ void D3DX_BC7::OptimizeOne(const EncodeParams* pEP, const LDRColorA aColors[], size_t np, size_t uIndexMode, float fOrgErr, const LDREndPntPair& org, LDREndPntPair& opt) const { assert( pEP ); float fOptErr = fOrgErr; opt = org; LDREndPntPair new_a, new_b; LDREndPntPair newEndPts; uint8_t do_b; // now optimize each channel separately for(size_t ch = 0; ch < BC7_NUM_CHANNELS; ++ch) { if(ms_aInfo[pEP->uMode].RGBAPrecWithP[ch] == 0) continue; // figure out which endpoint when perturbed gives the most improvement and start there // if we just alternate, we can easily end up in a local minima float fErr0 = PerturbOne(pEP, aColors, np, uIndexMode, ch, opt, new_a, fOptErr, 0); // perturb endpt A float fErr1 = PerturbOne(pEP, aColors, np, uIndexMode, ch, opt, new_b, fOptErr, 1); // perturb endpt B uint8_t& copt_a = opt.A[ch]; uint8_t& copt_b = opt.B[ch]; uint8_t& cnew_a = new_a.A[ch]; uint8_t& cnew_b = new_a.B[ch]; if(fErr0 < fErr1) { if(fErr0 >= fOptErr) continue; copt_a = cnew_a; fOptErr = fErr0; do_b = 1; // do B next } else { if(fErr1 >= fOptErr) continue; copt_b = cnew_b; fOptErr = fErr1; do_b = 0; // do A next } // now alternate endpoints and keep trying until there is no improvement for( ; ; ) { float fErr = PerturbOne(pEP, aColors, np, uIndexMode, ch, opt, newEndPts, fOptErr, do_b); if(fErr >= fOptErr) break; if(do_b == 0) copt_a = cnew_a; else copt_b = cnew_b; fOptErr = fErr; do_b = 1 - do_b; // now move the other endpoint } } // finally, do a small exhaustive search around what we think is the global minima to be sure for(size_t ch = 0; ch < BC7_NUM_CHANNELS; ch++) Exhaustive(pEP, aColors, np, uIndexMode, ch, fOptErr, opt); } _Use_decl_annotations_ void D3DX_BC7::OptimizeEndPoints(const EncodeParams* pEP, size_t uShape, size_t uIndexMode, const float afOrgErr[], const LDREndPntPair aOrgEndPts[], LDREndPntPair aOptEndPts[]) const { assert( pEP ); const uint8_t uPartitions = ms_aInfo[pEP->uMode].uPartitions; assert( uPartitions < BC7_MAX_REGIONS && uShape < BC7_MAX_SHAPES ); _Analysis_assume_( uPartitions < BC7_MAX_REGIONS && uShape < BC7_MAX_SHAPES ); LDRColorA aPixels[NUM_PIXELS_PER_BLOCK]; for(size_t p = 0; p <= uPartitions; ++p) { // collect the pixels in the region size_t np = 0; for(register size_t i = 0; i < NUM_PIXELS_PER_BLOCK; ++i) if(g_aPartitionTable[uPartitions][uShape][i] == p) aPixels[np++] = pEP->aLDRPixels[i]; OptimizeOne(pEP, aPixels, np, uIndexMode, afOrgErr[p], aOrgEndPts[p], aOptEndPts[p]); } } _Use_decl_annotations_ void D3DX_BC7::AssignIndices(const EncodeParams* pEP, size_t uShape, size_t uIndexMode, LDREndPntPair endPts[], size_t aIndices[], size_t aIndices2[], float afTotErr[]) const { assert( pEP ); assert( uShape < BC7_MAX_SHAPES ); _Analysis_assume_( uShape < BC7_MAX_SHAPES ); const uint8_t uPartitions = ms_aInfo[pEP->uMode].uPartitions; assert( uPartitions < BC7_MAX_REGIONS ); _Analysis_assume_( uPartitions < BC7_MAX_REGIONS ); const uint8_t uIndexPrec = uIndexMode ? ms_aInfo[pEP->uMode].uIndexPrec2 : ms_aInfo[pEP->uMode].uIndexPrec; const uint8_t uIndexPrec2 = uIndexMode ? ms_aInfo[pEP->uMode].uIndexPrec : ms_aInfo[pEP->uMode].uIndexPrec2; const uint8_t uNumIndices = 1 << uIndexPrec; const uint8_t uNumIndices2 = 1 << uIndexPrec2; assert( (uNumIndices <= BC7_MAX_INDICES) && (uNumIndices2 <= BC7_MAX_INDICES) ); _Analysis_assume_( (uNumIndices <= BC7_MAX_INDICES) && (uNumIndices2 <= BC7_MAX_INDICES) ); const uint8_t uHighestIndexBit = uNumIndices >> 1; const uint8_t uHighestIndexBit2 = uNumIndices2 >> 1; LDRColorA aPalette[BC7_MAX_REGIONS][BC7_MAX_INDICES]; // build list of possibles for(size_t p = 0; p <= uPartitions; p++) { GeneratePaletteQuantized(pEP, uIndexMode, endPts[p], aPalette[p]); afTotErr[p] = 0; } for(register size_t i = 0; i < NUM_PIXELS_PER_BLOCK; i++) { uint8_t uRegion = g_aPartitionTable[uPartitions][uShape][i]; assert( uRegion < BC7_MAX_REGIONS ); _Analysis_assume_( uRegion < BC7_MAX_REGIONS ); afTotErr[uRegion] += ComputeError(pEP->aLDRPixels[i], aPalette[uRegion], uIndexPrec, uIndexPrec2, &(aIndices[i]), &(aIndices2[i])); } // swap endpoints as needed to ensure that the indices at index_positions have a 0 high-order bit if(uIndexPrec2 == 0) { for(register size_t p = 0; p <= uPartitions; p++) { if(aIndices[g_aFixUp[uPartitions][uShape][p]] & uHighestIndexBit) { std::swap(endPts[p].A, endPts[p].B); for(register size_t i = 0; i < NUM_PIXELS_PER_BLOCK; i++) if(g_aPartitionTable[uPartitions][uShape][i] == p) aIndices[i] = uNumIndices - 1 - aIndices[i]; } assert((aIndices[g_aFixUp[uPartitions][uShape][p]] & uHighestIndexBit) == 0); } } else { for(register size_t p = 0; p <= uPartitions; p++) { if(aIndices[g_aFixUp[uPartitions][uShape][p]] & uHighestIndexBit) { std::swap(endPts[p].A.r, endPts[p].B.r); std::swap(endPts[p].A.g, endPts[p].B.g); std::swap(endPts[p].A.b, endPts[p].B.b); for(register size_t i = 0; i < NUM_PIXELS_PER_BLOCK; i++) if(g_aPartitionTable[uPartitions][uShape][i] == p) aIndices[i] = uNumIndices - 1 - aIndices[i]; } assert((aIndices[g_aFixUp[uPartitions][uShape][p]] & uHighestIndexBit) == 0); if(aIndices2[0] & uHighestIndexBit2) { std::swap(endPts[p].A.a, endPts[p].B.a); for(register size_t i = 0; i < NUM_PIXELS_PER_BLOCK; i++) aIndices2[i] = uNumIndices2 - 1 - aIndices2[i]; } assert((aIndices2[0] & uHighestIndexBit2) == 0); } } } _Use_decl_annotations_ void D3DX_BC7::EmitBlock(const EncodeParams* pEP, size_t uShape, size_t uRotation, size_t uIndexMode, const LDREndPntPair aEndPts[], const size_t aIndex[], const size_t aIndex2[]) { assert( pEP ); const uint8_t uPartitions = ms_aInfo[pEP->uMode].uPartitions; assert( uPartitions < BC7_MAX_REGIONS ); _Analysis_assume_( uPartitions < BC7_MAX_REGIONS ); const size_t uPBits = ms_aInfo[pEP->uMode].uPBits; const size_t uIndexPrec = ms_aInfo[pEP->uMode].uIndexPrec; const size_t uIndexPrec2 = ms_aInfo[pEP->uMode].uIndexPrec2; const LDRColorA RGBAPrec = ms_aInfo[pEP->uMode].RGBAPrec; const LDRColorA RGBAPrecWithP = ms_aInfo[pEP->uMode].RGBAPrecWithP; register size_t i; size_t uStartBit = 0; SetBits(uStartBit, pEP->uMode, 0); SetBits(uStartBit, 1, 1); SetBits(uStartBit, ms_aInfo[pEP->uMode].uRotationBits, static_cast( uRotation )); SetBits(uStartBit, ms_aInfo[pEP->uMode].uIndexModeBits, static_cast( uIndexMode )); SetBits(uStartBit, ms_aInfo[pEP->uMode].uPartitionBits, static_cast( uShape )); if(uPBits) { const size_t uNumEP = size_t(1 + uPartitions) << 1; uint8_t aPVote[BC7_MAX_REGIONS << 1] = {0,0,0,0,0,0}; uint8_t aCount[BC7_MAX_REGIONS << 1] = {0,0,0,0,0,0}; for(uint8_t ch = 0; ch < BC7_NUM_CHANNELS; ch++) { uint8_t ep = 0; for(i = 0; i <= uPartitions; i++) { if(RGBAPrec[ch] == RGBAPrecWithP[ch]) { SetBits(uStartBit, RGBAPrec[ch], aEndPts[i].A[ch]); SetBits(uStartBit, RGBAPrec[ch], aEndPts[i].B[ch]); } else { SetBits(uStartBit, RGBAPrec[ch], aEndPts[i].A[ch] >> 1); SetBits(uStartBit, RGBAPrec[ch], aEndPts[i].B[ch] >> 1); size_t idx = ep++ * uPBits / uNumEP; assert(idx < (BC7_MAX_REGIONS << 1)); _Analysis_assume_(idx < (BC7_MAX_REGIONS << 1)); aPVote[idx] += aEndPts[i].A[ch] & 0x01; aCount[idx]++; idx = ep++ * uPBits / uNumEP; assert(idx < (BC7_MAX_REGIONS << 1)); _Analysis_assume_(idx < (BC7_MAX_REGIONS << 1)); aPVote[idx] += aEndPts[i].B[ch] & 0x01; aCount[idx]++; } } } for(i = 0; i < uPBits; i++) { SetBits(uStartBit, 1, aPVote[i] > (aCount[i] >> 1) ? 1 : 0); } } else { for(size_t ch = 0; ch < BC7_NUM_CHANNELS; ch++) { for(i = 0; i <= uPartitions; i++) { SetBits(uStartBit, RGBAPrec[ch], aEndPts[i].A[ch] ); SetBits(uStartBit, RGBAPrec[ch], aEndPts[i].B[ch] ); } } } const size_t* aI1 = uIndexMode ? aIndex2 : aIndex; const size_t* aI2 = uIndexMode ? aIndex : aIndex2; for(i = 0; i < NUM_PIXELS_PER_BLOCK; i++) { if(IsFixUpOffset(ms_aInfo[pEP->uMode].uPartitions, uShape, i)) SetBits(uStartBit, uIndexPrec - 1, static_cast( aI1[i] )); else SetBits(uStartBit, uIndexPrec, static_cast( aI1[i] )); } if(uIndexPrec2) for(i = 0; i < NUM_PIXELS_PER_BLOCK; i++) SetBits(uStartBit, i ? uIndexPrec2 : uIndexPrec2 - 1, static_cast( aI2[i] )); assert(uStartBit == 128); } _Use_decl_annotations_ float D3DX_BC7::Refine(const EncodeParams* pEP, size_t uShape, size_t uRotation, size_t uIndexMode) { assert( pEP ); assert( uShape < BC7_MAX_SHAPES ); _Analysis_assume_( uShape < BC7_MAX_SHAPES ); const LDREndPntPair* aEndPts = pEP->aEndPts[uShape]; const size_t uPartitions = ms_aInfo[pEP->uMode].uPartitions; assert( uPartitions < BC7_MAX_REGIONS ); _Analysis_assume_( uPartitions < BC7_MAX_REGIONS ); LDREndPntPair aOrgEndPts[BC7_MAX_REGIONS]; LDREndPntPair aOptEndPts[BC7_MAX_REGIONS]; size_t aOrgIdx[NUM_PIXELS_PER_BLOCK]; size_t aOrgIdx2[NUM_PIXELS_PER_BLOCK]; size_t aOptIdx[NUM_PIXELS_PER_BLOCK]; size_t aOptIdx2[NUM_PIXELS_PER_BLOCK]; float aOrgErr[BC7_MAX_REGIONS]; float aOptErr[BC7_MAX_REGIONS]; for(register size_t p = 0; p <= uPartitions; p++) { aOrgEndPts[p].A = Quantize(aEndPts[p].A, ms_aInfo[pEP->uMode].RGBAPrecWithP); aOrgEndPts[p].B = Quantize(aEndPts[p].B, ms_aInfo[pEP->uMode].RGBAPrecWithP); } AssignIndices(pEP, uShape, uIndexMode, aOrgEndPts, aOrgIdx, aOrgIdx2, aOrgErr); OptimizeEndPoints(pEP, uShape, uIndexMode, aOrgErr, aOrgEndPts, aOptEndPts); AssignIndices(pEP, uShape, uIndexMode, aOptEndPts, aOptIdx, aOptIdx2, aOptErr); float fOrgTotErr = 0, fOptTotErr = 0; for(register size_t p = 0; p <= uPartitions; p++) { fOrgTotErr += aOrgErr[p]; fOptTotErr += aOptErr[p]; } if(fOptTotErr < fOrgTotErr) { EmitBlock(pEP, uShape, uRotation, uIndexMode, aOptEndPts, aOptIdx, aOptIdx2); return fOptTotErr; } else { EmitBlock(pEP, uShape, uRotation, uIndexMode, aOrgEndPts, aOrgIdx, aOrgIdx2); return fOrgTotErr; } } _Use_decl_annotations_ float D3DX_BC7::MapColors(const EncodeParams* pEP, const LDRColorA aColors[], size_t np, size_t uIndexMode, const LDREndPntPair& endPts, float fMinErr) const { assert( pEP ); const uint8_t uIndexPrec = uIndexMode ? ms_aInfo[pEP->uMode].uIndexPrec2 : ms_aInfo[pEP->uMode].uIndexPrec; const uint8_t uIndexPrec2 = uIndexMode ? ms_aInfo[pEP->uMode].uIndexPrec : ms_aInfo[pEP->uMode].uIndexPrec2; LDRColorA aPalette[BC7_MAX_INDICES]; float fTotalErr = 0; GeneratePaletteQuantized(pEP, uIndexMode, endPts, aPalette); for(register size_t i = 0; i < np; ++i) { fTotalErr += ComputeError(aColors[i], aPalette, uIndexPrec, uIndexPrec2); if(fTotalErr > fMinErr) // check for early exit { fTotalErr = FLT_MAX; break; } } return fTotalErr; } _Use_decl_annotations_ float D3DX_BC7::RoughMSE(EncodeParams* pEP, size_t uShape, size_t uIndexMode) { assert( pEP ); assert( uShape < BC7_MAX_SHAPES ); _Analysis_assume_( uShape < BC7_MAX_SHAPES ); LDREndPntPair* aEndPts = pEP->aEndPts[uShape]; const uint8_t uPartitions = ms_aInfo[pEP->uMode].uPartitions; assert( uPartitions < BC7_MAX_REGIONS ); _Analysis_assume_( uPartitions < BC7_MAX_REGIONS ); const uint8_t uIndexPrec = uIndexMode ? ms_aInfo[pEP->uMode].uIndexPrec2 : ms_aInfo[pEP->uMode].uIndexPrec; const uint8_t uIndexPrec2 = uIndexMode ? ms_aInfo[pEP->uMode].uIndexPrec : ms_aInfo[pEP->uMode].uIndexPrec2; const uint8_t uNumIndices = 1 << uIndexPrec; const uint8_t uNumIndices2 = 1 << uIndexPrec2; size_t auPixIdx[NUM_PIXELS_PER_BLOCK]; LDRColorA aPalette[BC7_MAX_REGIONS][BC7_MAX_INDICES]; for(size_t p = 0; p <= uPartitions; p++) { size_t np = 0; for(register size_t i = 0; i < NUM_PIXELS_PER_BLOCK; i++) { if (g_aPartitionTable[uPartitions][uShape][i] == p) { auPixIdx[np++] = i; } } // handle simple cases assert(np > 0); if(np == 1) { aEndPts[p].A = pEP->aLDRPixels[auPixIdx[0]]; aEndPts[p].B = pEP->aLDRPixels[auPixIdx[0]]; continue; } else if(np == 2) { aEndPts[p].A = pEP->aLDRPixels[auPixIdx[0]]; aEndPts[p].B = pEP->aLDRPixels[auPixIdx[1]]; continue; } if(uIndexPrec2 == 0) { HDRColorA epA, epB; OptimizeRGBA(pEP->aHDRPixels, &epA, &epB, 4, np, auPixIdx); epA.Clamp(0.0f, 1.0f); epB.Clamp(0.0f, 1.0f); epA *= 255.0f; epB *= 255.0f; aEndPts[p].A = epA.ToLDRColorA(); aEndPts[p].B = epB.ToLDRColorA(); } else { uint8_t uMinAlpha = 255, uMaxAlpha = 0; for(register size_t i = 0; i < NUM_PIXELS_PER_BLOCK; ++i) { uMinAlpha = std::min(uMinAlpha, pEP->aLDRPixels[auPixIdx[i]].a); uMaxAlpha = std::max(uMaxAlpha, pEP->aLDRPixels[auPixIdx[i]].a); } HDRColorA epA, epB; OptimizeRGB(pEP->aHDRPixels, &epA, &epB, 4, np, auPixIdx); epA.Clamp(0.0f, 1.0f); epB.Clamp(0.0f, 1.0f); epA *= 255.0f; epB *= 255.0f; aEndPts[p].A = epA.ToLDRColorA(); aEndPts[p].B = epB.ToLDRColorA(); aEndPts[p].A.a = uMinAlpha; aEndPts[p].B.a = uMaxAlpha; } } if(uIndexPrec2 == 0) { for(size_t p = 0; p <= uPartitions; p++) for(register size_t i = 0; i < uNumIndices; i++) LDRColorA::Interpolate(aEndPts[p].A, aEndPts[p].B, i, i, uIndexPrec, uIndexPrec, aPalette[p][i]); } else { for(size_t p = 0; p <= uPartitions; p++) { for(register size_t i = 0; i < uNumIndices; i++) LDRColorA::InterpolateRGB(aEndPts[p].A, aEndPts[p].B, i, uIndexPrec, aPalette[p][i]); for(register size_t i = 0; i < uNumIndices2; i++) LDRColorA::InterpolateA(aEndPts[p].A, aEndPts[p].B, i, uIndexPrec2, aPalette[p][i]); } } float fTotalErr = 0; for(register size_t i = 0; i < NUM_PIXELS_PER_BLOCK; i++) { uint8_t uRegion = g_aPartitionTable[uPartitions][uShape][i]; fTotalErr += ComputeError(pEP->aLDRPixels[i], aPalette[uRegion], uIndexPrec, uIndexPrec2); } return fTotalErr; } //===================================================================================== // Entry points //===================================================================================== //------------------------------------------------------------------------------------- // BC6H Compression //------------------------------------------------------------------------------------- _Use_decl_annotations_ void D3DXDecodeBC6HU(XMVECTOR *pColor, const uint8_t *pBC) { assert( pColor && pBC ); static_assert( sizeof(D3DX_BC6H) == 16, "D3DX_BC6H should be 16 bytes" ); reinterpret_cast< const D3DX_BC6H* >( pBC )->Decode(false, reinterpret_cast(pColor)); } _Use_decl_annotations_ void D3DXDecodeBC6HS(XMVECTOR *pColor, const uint8_t *pBC) { assert( pColor && pBC ); static_assert( sizeof(D3DX_BC6H) == 16, "D3DX_BC6H should be 16 bytes" ); reinterpret_cast< const D3DX_BC6H* >( pBC )->Decode(true, reinterpret_cast(pColor)); } _Use_decl_annotations_ void D3DXEncodeBC6HU(uint8_t *pBC, const XMVECTOR *pColor, DWORD flags) { UNREFERENCED_PARAMETER(flags); assert( pBC && pColor ); static_assert( sizeof(D3DX_BC6H) == 16, "D3DX_BC6H should be 16 bytes" ); reinterpret_cast< D3DX_BC6H* >( pBC )->Encode(false, reinterpret_cast(pColor)); } _Use_decl_annotations_ void D3DXEncodeBC6HS(uint8_t *pBC, const XMVECTOR *pColor, DWORD flags) { UNREFERENCED_PARAMETER(flags); assert( pBC && pColor ); static_assert( sizeof(D3DX_BC6H) == 16, "D3DX_BC6H should be 16 bytes" ); reinterpret_cast< D3DX_BC6H* >( pBC )->Encode(true, reinterpret_cast(pColor)); } //------------------------------------------------------------------------------------- // BC7 Compression //------------------------------------------------------------------------------------- _Use_decl_annotations_ void D3DXDecodeBC7(XMVECTOR *pColor, const uint8_t *pBC) { assert( pColor && pBC ); static_assert( sizeof(D3DX_BC7) == 16, "D3DX_BC7 should be 16 bytes" ); reinterpret_cast< const D3DX_BC7* >( pBC )->Decode(reinterpret_cast(pColor)); } _Use_decl_annotations_ void D3DXEncodeBC7(uint8_t *pBC, const XMVECTOR *pColor, DWORD flags) { assert( pBC && pColor ); static_assert( sizeof(D3DX_BC7) == 16, "D3DX_BC7 should be 16 bytes" ); reinterpret_cast< D3DX_BC7* >( pBC )->Encode( !(flags& BC_FLAGS_USE_3SUBSETS), reinterpret_cast(pColor)); } } // namespace ================================================ FILE: 3rdParty/DirectXTex/DirectXTex/BCDirectCompute.cpp ================================================ //------------------------------------------------------------------------------------- // BCDirectCompute.cpp // // Direct3D 11 Compute Shader BC Compressor // // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A // PARTICULAR PURPOSE. // // Copyright (c) Microsoft Corporation. All rights reserved. //------------------------------------------------------------------------------------- #include "directxtexp.h" #include "BCDirectCompute.h" #if defined(_DEBUG) || defined(PROFILE) #pragma comment(lib,"dxguid.lib") #endif using Microsoft::WRL::ComPtr; namespace { #include "Shaders\Compiled\BC7Encode_EncodeBlockCS.inc" #include "Shaders\Compiled\BC7Encode_TryMode02CS.inc" #include "Shaders\Compiled\BC7Encode_TryMode137CS.inc" #include "Shaders\Compiled\BC7Encode_TryMode456CS.inc" #include "Shaders\Compiled\BC6HEncode_EncodeBlockCS.inc" #include "Shaders\Compiled\BC6HEncode_TryModeG10CS.inc" #include "Shaders\Compiled\BC6HEncode_TryModeLE10CS.inc" struct BufferBC6HBC7 { UINT color[4]; }; struct ConstantsBC6HBC7 { UINT tex_width; UINT num_block_x; UINT format; UINT mode_id; UINT start_block_id; UINT num_total_blocks; float alpha_weight; UINT reserved; }; static_assert( sizeof(ConstantsBC6HBC7) == sizeof(UINT)*8, "Constant buffer size mismatch" ); inline void RunComputeShader( ID3D11DeviceContext* pContext, ID3D11ComputeShader* shader, ID3D11ShaderResourceView** pSRVs, UINT srvCount, ID3D11Buffer* pCB, ID3D11UnorderedAccessView* pUAV, UINT X ) { // Force UAV to nullptr before setting SRV since we are swapping buffers ID3D11UnorderedAccessView* nullUAV = nullptr; pContext->CSSetUnorderedAccessViews( 0, 1, &nullUAV, nullptr ); pContext->CSSetShader( shader, nullptr, 0 ); pContext->CSSetShaderResources( 0, srvCount, pSRVs ); pContext->CSSetUnorderedAccessViews( 0, 1, &pUAV, nullptr ); pContext->CSSetConstantBuffers( 0, 1, &pCB ); pContext->Dispatch( X, 1, 1 ); } inline void ResetContext( ID3D11DeviceContext* pContext ) { ID3D11UnorderedAccessView* nullUAV = nullptr; pContext->CSSetUnorderedAccessViews( 0, 1, &nullUAV, nullptr ); ID3D11ShaderResourceView* nullSRV[3] = { nullptr, nullptr, nullptr }; pContext->CSSetShaderResources( 0, 3, nullSRV ); ID3D11Buffer* nullBuffer[1] = { nullptr }; pContext->CSSetConstantBuffers( 0, 1, nullBuffer ); } }; namespace DirectX { GPUCompressBC::GPUCompressBC() : m_bcformat(DXGI_FORMAT_UNKNOWN), m_srcformat(DXGI_FORMAT_UNKNOWN), m_alphaWeight(1.f), m_width(0), m_height(0) { } //------------------------------------------------------------------------------------- _Use_decl_annotations_ HRESULT GPUCompressBC::Initialize( ID3D11Device* pDevice ) { if ( !pDevice ) return E_INVALIDARG; // Check for DirectCompute support D3D_FEATURE_LEVEL fl = pDevice->GetFeatureLevel(); if ( fl < D3D_FEATURE_LEVEL_10_0 ) { // DirectCompute not supported on Feature Level 9.x hardware return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); } if ( fl < D3D_FEATURE_LEVEL_11_0 ) { // DirectCompute support on Feature Level 10.x hardware is optional, and this function needs it D3D11_FEATURE_DATA_D3D10_X_HARDWARE_OPTIONS hwopts; HRESULT hr = pDevice->CheckFeatureSupport( D3D11_FEATURE_D3D10_X_HARDWARE_OPTIONS, &hwopts, sizeof(hwopts) ); if ( FAILED(hr) ) { memset( &hwopts, 0, sizeof(hwopts) ); } if ( !hwopts.ComputeShaders_Plus_RawAndStructuredBuffers_Via_Shader_4_x ) { return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); } } // Save a device reference and obtain immediate context m_device = pDevice; pDevice->GetImmediateContext( m_context.ReleaseAndGetAddressOf() ); assert( m_context ); //--- Create compute shader library: BC6H ----------------------------------------- // Modes 11-14 HRESULT hr = pDevice->CreateComputeShader( BC6HEncode_TryModeG10CS, sizeof(BC6HEncode_TryModeG10CS), nullptr, m_BC6H_tryModeG10CS.ReleaseAndGetAddressOf() ); if ( FAILED(hr) ) return hr; // Modes 1-10 hr = pDevice->CreateComputeShader( BC6HEncode_TryModeLE10CS, sizeof(BC6HEncode_TryModeLE10CS), nullptr, m_BC6H_tryModeLE10CS.ReleaseAndGetAddressOf() ); if ( FAILED(hr) ) return hr; // Encode hr = pDevice->CreateComputeShader( BC6HEncode_EncodeBlockCS, sizeof(BC6HEncode_EncodeBlockCS), nullptr, m_BC6H_encodeBlockCS.ReleaseAndGetAddressOf() ); if ( FAILED(hr) ) return hr; //--- Create compute shader library: BC7 ------------------------------------------ // Modes 4, 5, 6 hr = pDevice->CreateComputeShader( BC7Encode_TryMode456CS, sizeof(BC7Encode_TryMode456CS), nullptr, m_BC7_tryMode456CS.ReleaseAndGetAddressOf() ); if ( FAILED(hr) ) return hr; // Modes 1, 3, 7 hr = pDevice->CreateComputeShader( BC7Encode_TryMode137CS, sizeof(BC7Encode_TryMode137CS), nullptr, m_BC7_tryMode137CS.ReleaseAndGetAddressOf() ); if ( FAILED(hr) ) return hr; // Modes 0, 2 hr = pDevice->CreateComputeShader( BC7Encode_TryMode02CS, sizeof(BC7Encode_TryMode02CS), nullptr, m_BC7_tryMode02CS.ReleaseAndGetAddressOf() ); if ( FAILED(hr) ) return hr; // Encode hr = pDevice->CreateComputeShader( BC7Encode_EncodeBlockCS, sizeof(BC7Encode_EncodeBlockCS), nullptr, m_BC7_encodeBlockCS.ReleaseAndGetAddressOf() ); if ( FAILED(hr) ) return hr; return S_OK; } //------------------------------------------------------------------------------------- _Use_decl_annotations_ HRESULT GPUCompressBC::Prepare( size_t width, size_t height, DXGI_FORMAT format, float alphaWeight, bool skip3subsets ) { if ( !width || !height || alphaWeight < 0.f ) return E_INVALIDARG; #ifdef _M_X64 if ( (width > 0xFFFFFFFF) || (height > 0xFFFFFFFF) ) return E_INVALIDARG; #endif m_width = width; m_height = height; m_alphaWeight = alphaWeight; m_skip3Subsets = skip3subsets; size_t xblocks = std::max( 1, (width + 3) >> 2 ); size_t yblocks = std::max( 1, (height + 3) >> 2 ); size_t num_blocks = xblocks * yblocks; switch( format ) { // BC6H GPU compressor takes RGBAF32 as input case DXGI_FORMAT_BC6H_TYPELESS: case DXGI_FORMAT_BC6H_UF16: case DXGI_FORMAT_BC6H_SF16: m_srcformat = DXGI_FORMAT_R32G32B32A32_FLOAT; break; // BC7 GPU compressor takes RGBA32 as input case DXGI_FORMAT_BC7_TYPELESS: case DXGI_FORMAT_BC7_UNORM: m_srcformat = DXGI_FORMAT_R8G8B8A8_UNORM; break; case DXGI_FORMAT_BC7_UNORM_SRGB: m_srcformat = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB; break; default: m_bcformat = m_srcformat = DXGI_FORMAT_UNKNOWN; return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); } m_bcformat = format; auto pDevice = m_device.Get(); if ( !pDevice ) return E_POINTER; // Create structured buffers size_t bufferSize = num_blocks * sizeof( BufferBC6HBC7 ); { D3D11_BUFFER_DESC desc; memset( &desc, 0, sizeof(desc) ); desc.BindFlags = D3D11_BIND_UNORDERED_ACCESS | D3D11_BIND_SHADER_RESOURCE; desc.Usage = D3D11_USAGE_DEFAULT; desc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED; desc.StructureByteStride = sizeof( BufferBC6HBC7 ); desc.ByteWidth = static_cast( bufferSize ); HRESULT hr = pDevice->CreateBuffer( &desc, nullptr, m_output.ReleaseAndGetAddressOf() ); if ( FAILED(hr) ) { return hr; } hr = pDevice->CreateBuffer( &desc, nullptr, m_err1.ReleaseAndGetAddressOf() ); if ( FAILED(hr) ) { return hr; } hr = pDevice->CreateBuffer( &desc, nullptr, m_err2.ReleaseAndGetAddressOf() ); if ( FAILED(hr) ) { return hr; } } // Create staging output buffer { D3D11_BUFFER_DESC desc; memset( &desc, 0, sizeof(desc) ); desc.Usage = D3D11_USAGE_STAGING; desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; desc.ByteWidth = static_cast( bufferSize ); HRESULT hr = pDevice->CreateBuffer( &desc, nullptr, m_outputCPU.ReleaseAndGetAddressOf() ); if ( FAILED(hr) ) { return hr; } } // Create constant buffer { D3D11_BUFFER_DESC desc; memset( &desc, 0, sizeof(desc) ); desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; desc.Usage = D3D11_USAGE_DYNAMIC; desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; desc.ByteWidth = sizeof( ConstantsBC6HBC7 ); HRESULT hr = pDevice->CreateBuffer( &desc, nullptr, m_constBuffer.ReleaseAndGetAddressOf() ); if ( FAILED(hr) ) { return hr; } } // Create shader resource views { D3D11_SHADER_RESOURCE_VIEW_DESC desc; memset( &desc, 0, sizeof(desc) ); desc.Buffer.NumElements = static_cast( num_blocks ); desc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER; HRESULT hr = pDevice->CreateShaderResourceView( m_err1.Get(), &desc, m_err1SRV.ReleaseAndGetAddressOf() ); if ( FAILED(hr) ) { return hr; } hr = pDevice->CreateShaderResourceView( m_err2.Get(), &desc, m_err2SRV.ReleaseAndGetAddressOf() ); if ( FAILED(hr) ) { return hr; } } // Create unordered access views { D3D11_UNORDERED_ACCESS_VIEW_DESC desc; memset( &desc, 0, sizeof(desc) ); desc.Buffer.NumElements = static_cast( num_blocks ); desc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER; HRESULT hr = pDevice->CreateUnorderedAccessView( m_output.Get(), &desc, m_outputUAV.ReleaseAndGetAddressOf() ); if ( FAILED(hr) ) { return hr; } hr = pDevice->CreateUnorderedAccessView( m_err1.Get(), &desc, m_err1UAV.ReleaseAndGetAddressOf() ); if ( FAILED(hr) ) { return hr; } hr = pDevice->CreateUnorderedAccessView( m_err2.Get(), &desc, m_err2UAV.ReleaseAndGetAddressOf() ); if ( FAILED(hr) ) { return hr; } } return S_OK; } //------------------------------------------------------------------------------------- _Use_decl_annotations_ HRESULT GPUCompressBC::Compress( const Image& srcImage, const Image& destImage ) { if ( !srcImage.pixels || !destImage.pixels ) return E_INVALIDARG; if ( srcImage.width != destImage.width || srcImage.height != destImage.height || srcImage.width != m_width || srcImage.height != m_height || srcImage.format != m_srcformat || destImage.format != m_bcformat ) { return E_UNEXPECTED; } //--- Create input texture -------------------------------------------------------- auto pDevice = m_device.Get(); if ( !pDevice ) return E_POINTER; // We need to avoid the hardware doing additional colorspace conversion DXGI_FORMAT inputFormat = ( m_srcformat == DXGI_FORMAT_R8G8B8A8_UNORM_SRGB ) ? DXGI_FORMAT_R8G8B8A8_UNORM : m_srcformat; ComPtr sourceTex; { D3D11_TEXTURE2D_DESC desc; memset( &desc, 0, sizeof(desc) ); desc.Width = static_cast( srcImage.width ); desc.Height = static_cast( srcImage.height ); desc.MipLevels = 1; desc.ArraySize = 1; desc.Format = inputFormat; desc.SampleDesc.Count = 1; desc.Usage = D3D11_USAGE_DEFAULT; desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; D3D11_SUBRESOURCE_DATA initData; initData.pSysMem = srcImage.pixels; initData.SysMemPitch = static_cast( srcImage.rowPitch ); initData.SysMemSlicePitch = static_cast( srcImage.slicePitch ); HRESULT hr = pDevice->CreateTexture2D( &desc, &initData, sourceTex.GetAddressOf() ); if ( FAILED(hr) ) { return hr; } } ComPtr sourceSRV; { D3D11_SHADER_RESOURCE_VIEW_DESC desc; memset( &desc, 0, sizeof(desc) ); desc.Texture2D.MipLevels = 1; desc.Format = inputFormat; desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; HRESULT hr = pDevice->CreateShaderResourceView( sourceTex.Get(), &desc, sourceSRV.GetAddressOf() ); if ( FAILED(hr) ) { return hr; } } //--- Compress using DirectCompute ------------------------------------------------ bool isbc7 = false; switch( m_bcformat ) { case DXGI_FORMAT_BC6H_TYPELESS: case DXGI_FORMAT_BC6H_UF16: case DXGI_FORMAT_BC6H_SF16: break; case DXGI_FORMAT_BC7_TYPELESS: case DXGI_FORMAT_BC7_UNORM: case DXGI_FORMAT_BC7_UNORM_SRGB: isbc7 = true; break; default: return E_UNEXPECTED; } const UINT MAX_BLOCK_BATCH = 64; auto pContext = m_context.Get(); if ( !pContext ) return E_UNEXPECTED; size_t xblocks = std::max( 1, (m_width + 3) >> 2 ); size_t yblocks = std::max( 1, (m_height + 3) >> 2 ); UINT num_total_blocks = static_cast( xblocks * yblocks ); UINT num_blocks = num_total_blocks; int start_block_id = 0; while (num_blocks > 0) { UINT n = std::min( num_blocks, MAX_BLOCK_BATCH ); UINT uThreadGroupCount = n; { D3D11_MAPPED_SUBRESOURCE mapped; HRESULT hr = pContext->Map( m_constBuffer.Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped ); if ( FAILED(hr) ) return hr; ConstantsBC6HBC7 param; param.tex_width = static_cast( srcImage.width ); param.num_block_x = static_cast( xblocks ); param.format = m_bcformat; param.mode_id = 0; param.start_block_id = start_block_id; param.num_total_blocks = num_total_blocks; param.alpha_weight = m_alphaWeight; memcpy( mapped.pData, ¶m, sizeof( param ) ); pContext->Unmap( m_constBuffer.Get(), 0 ); } if ( isbc7 ) { //--- BC7 ----------------------------------------------------------------- ID3D11ShaderResourceView* pSRVs[] = { sourceSRV.Get(), nullptr }; RunComputeShader( pContext, m_BC7_tryMode456CS.Get(), pSRVs, 2, m_constBuffer.Get(), m_err1UAV.Get(), std::max( (uThreadGroupCount + 3) / 4, 1) ); for ( UINT i = 0; i < 3; ++i ) { static const UINT modes[] = { 1, 3, 7 }; // Mode 1: err1 -> err2 // Mode 3: err2 -> err1 // Mode 7: err1 -> err2 { D3D11_MAPPED_SUBRESOURCE mapped; HRESULT hr = pContext->Map( m_constBuffer.Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped ); if ( FAILED(hr) ) { ResetContext( pContext ); return hr; } ConstantsBC6HBC7 param; param.tex_width = static_cast( srcImage.width ); param.num_block_x = static_cast( xblocks ); param.format = m_bcformat; param.mode_id = modes[i]; param.start_block_id = start_block_id; param.num_total_blocks = num_total_blocks; param.alpha_weight = m_alphaWeight; memcpy( mapped.pData, ¶m, sizeof( param ) ); pContext->Unmap( m_constBuffer.Get(), 0 ); } pSRVs[1] = (i & 1) ? m_err2SRV.Get() : m_err1SRV.Get(); RunComputeShader( pContext, m_BC7_tryMode137CS.Get(), pSRVs, 2, m_constBuffer.Get(), (i & 1) ? m_err1UAV.Get() : m_err2UAV.Get(), uThreadGroupCount ); } if ( !m_skip3Subsets ) { // 3 subset modes tend to be used rarely and add significant compression time for ( UINT i = 0; i < 2; ++i ) { static const UINT modes[] = { 0, 2 }; // Mode 0: err2 -> err1 // Mode 2: err1 -> err2 { D3D11_MAPPED_SUBRESOURCE mapped; HRESULT hr = pContext->Map( m_constBuffer.Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped ); if ( FAILED(hr) ) { ResetContext( pContext ); return hr; } ConstantsBC6HBC7 param; param.tex_width = static_cast( srcImage.width ); param.num_block_x = static_cast( xblocks ); param.format = m_bcformat; param.mode_id = modes[i]; param.start_block_id = start_block_id; param.num_total_blocks = num_total_blocks; param.alpha_weight = m_alphaWeight; memcpy( mapped.pData, ¶m, sizeof( param ) ); pContext->Unmap( m_constBuffer.Get(), 0 ); } pSRVs[1] = (i & 1) ? m_err1SRV.Get() : m_err2SRV.Get(); RunComputeShader( pContext, m_BC7_tryMode02CS.Get(), pSRVs, 2, m_constBuffer.Get(), (i & 1) ? m_err2UAV.Get() : m_err1UAV.Get(), uThreadGroupCount ); } } pSRVs[1] = m_err2SRV.Get(); RunComputeShader( pContext, m_BC7_encodeBlockCS.Get(), pSRVs, 2, m_constBuffer.Get(), m_outputUAV.Get(), std::max( (uThreadGroupCount + 3) / 4, 1) ); } else { //--- BC6H ---------------------------------------------------------------- ID3D11ShaderResourceView* pSRVs[] = { sourceSRV.Get(), nullptr }; RunComputeShader( pContext, m_BC6H_tryModeG10CS.Get(), pSRVs, 2, m_constBuffer.Get(), m_err1UAV.Get(), std::max( (uThreadGroupCount + 3) / 4, 1) ); for ( UINT i = 0; i < 10; ++i ) { { D3D11_MAPPED_SUBRESOURCE mapped; HRESULT hr = pContext->Map( m_constBuffer.Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped ); if ( FAILED(hr) ) { ResetContext( pContext ); return hr; } ConstantsBC6HBC7 param; param.tex_width = static_cast( srcImage.width ); param.num_block_x = static_cast( xblocks ); param.format = m_bcformat; param.mode_id = i; param.start_block_id = start_block_id; param.num_total_blocks = num_total_blocks; memcpy( mapped.pData, ¶m, sizeof( param ) ); pContext->Unmap( m_constBuffer.Get(), 0 ); } pSRVs[1] = (i & 1) ? m_err2SRV.Get() : m_err1SRV.Get(); RunComputeShader( pContext, m_BC6H_tryModeLE10CS.Get(), pSRVs, 2, m_constBuffer.Get(), (i & 1) ? m_err1UAV.Get() : m_err2UAV.Get(), std::max( (uThreadGroupCount + 1) / 2, 1) ); } pSRVs[1] = m_err1SRV.Get(); RunComputeShader( pContext, m_BC6H_encodeBlockCS.Get(), pSRVs, 2, m_constBuffer.Get(), m_outputUAV.Get(), std::max( (uThreadGroupCount + 1) / 2, 1) ); } start_block_id += n; num_blocks -= n; } ResetContext( pContext ); //--- Copy output texture back to CPU --------------------------------------------- pContext->CopyResource( m_outputCPU.Get(), m_output.Get() ); D3D11_MAPPED_SUBRESOURCE mapped; HRESULT hr = pContext->Map( m_outputCPU.Get(), 0, D3D11_MAP_READ, 0, &mapped ); if ( SUCCEEDED(hr) ) { const uint8_t *pSrc = reinterpret_cast( mapped.pData ); uint8_t *pDest = destImage.pixels; size_t pitch = xblocks * sizeof( BufferBC6HBC7 ); size_t rows = std::max( 1, ( destImage.height + 3 ) >> 2 ); for( size_t h = 0; h < rows; ++h ) { memcpy( pDest, pSrc, destImage.rowPitch ); pSrc += pitch; pDest += destImage.rowPitch; } pContext->Unmap( m_outputCPU.Get(), 0 ); } return hr; } }; // namespace ================================================ FILE: 3rdParty/DirectXTex/DirectXTex/BCDirectCompute.h ================================================ //------------------------------------------------------------------------------------- // BCDirectCompute.h // // Direct3D 11 Compute Shader BC Compressor // // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A // PARTICULAR PURPOSE. // // Copyright (c) Microsoft Corporation. All rights reserved. //------------------------------------------------------------------------------------- #pragma once namespace DirectX { class GPUCompressBC { public: GPUCompressBC(); HRESULT Initialize( _In_ ID3D11Device* pDevice ); HRESULT Prepare( _In_ size_t width, _In_ size_t height, _In_ DXGI_FORMAT format, _In_ float alphaWeight = 1.f, _In_ bool skip3subsets = true ); HRESULT Compress( _In_ const Image& srcImage, _In_ const Image& destImage ); DXGI_FORMAT GetSourceFormat() const { return m_srcformat; } private: DXGI_FORMAT m_bcformat; DXGI_FORMAT m_srcformat; float m_alphaWeight; bool m_skip3Subsets; size_t m_width; size_t m_height; Microsoft::WRL::ComPtr m_device; Microsoft::WRL::ComPtr m_context; Microsoft::WRL::ComPtr m_err1; Microsoft::WRL::ComPtr m_err1UAV; Microsoft::WRL::ComPtr m_err1SRV; Microsoft::WRL::ComPtr m_err2; Microsoft::WRL::ComPtr m_err2UAV; Microsoft::WRL::ComPtr m_err2SRV; Microsoft::WRL::ComPtr m_output; Microsoft::WRL::ComPtr m_outputCPU; Microsoft::WRL::ComPtr m_outputUAV; Microsoft::WRL::ComPtr m_constBuffer; // Compute shader library Microsoft::WRL::ComPtr m_BC6H_tryModeG10CS; Microsoft::WRL::ComPtr m_BC6H_tryModeLE10CS; Microsoft::WRL::ComPtr m_BC6H_encodeBlockCS; Microsoft::WRL::ComPtr m_BC7_tryMode456CS; Microsoft::WRL::ComPtr m_BC7_tryMode137CS; Microsoft::WRL::ComPtr m_BC7_tryMode02CS; Microsoft::WRL::ComPtr m_BC7_encodeBlockCS; }; }; // namespace ================================================ FILE: 3rdParty/DirectXTex/DirectXTex/DDS.h ================================================ //-------------------------------------------------------------------------------------- // dds.h // // This header defines constants and structures that are useful when parsing // DDS files. DDS files were originally designed to use several structures // and constants that are native to DirectDraw and are defined in ddraw.h, // such as DDSURFACEDESC2 and DDSCAPS2. This file defines similar // (compatible) constants and structures so that one can use DDS files // without needing to include ddraw.h. // // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A // PARTICULAR PURPOSE. // // Copyright (c) Microsoft Corporation. All rights reserved. // // http://go.microsoft.com/fwlink/?LinkId=248926 //-------------------------------------------------------------------------------------- #pragma once #if defined(_XBOX_ONE) && defined(_TITLE) #include #else #include #endif // VS 2010's stdint.h conflicts with intsafe.h #pragma warning(push) #pragma warning(disable : 4005) #include #pragma warning(pop) namespace DirectX { #pragma pack(push,1) const uint32_t DDS_MAGIC = 0x20534444; // "DDS " struct DDS_PIXELFORMAT { uint32_t dwSize; uint32_t dwFlags; uint32_t dwFourCC; uint32_t dwRGBBitCount; uint32_t dwRBitMask; uint32_t dwGBitMask; uint32_t dwBBitMask; uint32_t dwABitMask; }; #define DDS_FOURCC 0x00000004 // DDPF_FOURCC #define DDS_RGB 0x00000040 // DDPF_RGB #define DDS_RGBA 0x00000041 // DDPF_RGB | DDPF_ALPHAPIXELS #define DDS_LUMINANCE 0x00020000 // DDPF_LUMINANCE #define DDS_LUMINANCEA 0x00020001 // DDPF_LUMINANCE | DDPF_ALPHAPIXELS #define DDS_ALPHA 0x00000002 // DDPF_ALPHA #define DDS_PAL8 0x00000020 // DDPF_PALETTEINDEXED8 #ifndef MAKEFOURCC #define MAKEFOURCC(ch0, ch1, ch2, ch3) \ ((uint32_t)(uint8_t)(ch0) | ((uint32_t)(uint8_t)(ch1) << 8) | \ ((uint32_t)(uint8_t)(ch2) << 16) | ((uint32_t)(uint8_t)(ch3) << 24 )) #endif /* defined(MAKEFOURCC) */ extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_DXT1 = { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D','X','T','1'), 0, 0, 0, 0, 0 }; extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_DXT2 = { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D','X','T','2'), 0, 0, 0, 0, 0 }; extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_DXT3 = { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D','X','T','3'), 0, 0, 0, 0, 0 }; extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_DXT4 = { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D','X','T','4'), 0, 0, 0, 0, 0 }; extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_DXT5 = { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D','X','T','5'), 0, 0, 0, 0, 0 }; extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_BC4_UNORM = { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('B','C','4','U'), 0, 0, 0, 0, 0 }; extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_BC4_SNORM = { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('B','C','4','S'), 0, 0, 0, 0, 0 }; extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_BC5_UNORM = { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('B','C','5','U'), 0, 0, 0, 0, 0 }; extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_BC5_SNORM = { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('B','C','5','S'), 0, 0, 0, 0, 0 }; extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_R8G8_B8G8 = { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('R','G','B','G'), 0, 0, 0, 0, 0 }; extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_G8R8_G8B8 = { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('G','R','G','B'), 0, 0, 0, 0, 0 }; extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_YUY2 = { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('Y','U','Y','2'), 0, 0, 0, 0, 0 }; extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_A8R8G8B8 = { sizeof(DDS_PIXELFORMAT), DDS_RGBA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }; extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_X8R8G8B8 = { sizeof(DDS_PIXELFORMAT), DDS_RGB, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000 }; extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_A8B8G8R8 = { sizeof(DDS_PIXELFORMAT), DDS_RGBA, 0, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 }; extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_X8B8G8R8 = { sizeof(DDS_PIXELFORMAT), DDS_RGB, 0, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0x00000000 }; extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_G16R16 = { sizeof(DDS_PIXELFORMAT), DDS_RGB, 0, 32, 0x0000ffff, 0xffff0000, 0x00000000, 0x00000000 }; extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_R5G6B5 = { sizeof(DDS_PIXELFORMAT), DDS_RGB, 0, 16, 0x0000f800, 0x000007e0, 0x0000001f, 0x00000000 }; extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_A1R5G5B5 = { sizeof(DDS_PIXELFORMAT), DDS_RGBA, 0, 16, 0x00007c00, 0x000003e0, 0x0000001f, 0x00008000 }; extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_A4R4G4B4 = { sizeof(DDS_PIXELFORMAT), DDS_RGBA, 0, 16, 0x00000f00, 0x000000f0, 0x0000000f, 0x0000f000 }; extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_R8G8B8 = { sizeof(DDS_PIXELFORMAT), DDS_RGB, 0, 24, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000 }; extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_L8 = { sizeof(DDS_PIXELFORMAT), DDS_LUMINANCE, 0, 8, 0xff, 0x00, 0x00, 0x00 }; extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_L16 = { sizeof(DDS_PIXELFORMAT), DDS_LUMINANCE, 0, 16, 0xffff, 0x0000, 0x0000, 0x0000 }; extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_A8L8 = { sizeof(DDS_PIXELFORMAT), DDS_LUMINANCEA, 0, 16, 0x00ff, 0x0000, 0x0000, 0xff00 }; extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_A8 = { sizeof(DDS_PIXELFORMAT), DDS_ALPHA, 0, 8, 0x00, 0x00, 0x00, 0xff }; // D3DFMT_A2R10G10B10/D3DFMT_A2B10G10R10 should be written using DX10 extension to avoid D3DX 10:10:10:2 reversal issue // This indicates the DDS_HEADER_DXT10 extension is present (the format is in dxgiFormat) extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_DX10 = { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D','X','1','0'), 0, 0, 0, 0, 0 }; #define DDS_HEADER_FLAGS_TEXTURE 0x00001007 // DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT #define DDS_HEADER_FLAGS_MIPMAP 0x00020000 // DDSD_MIPMAPCOUNT #define DDS_HEADER_FLAGS_VOLUME 0x00800000 // DDSD_DEPTH #define DDS_HEADER_FLAGS_PITCH 0x00000008 // DDSD_PITCH #define DDS_HEADER_FLAGS_LINEARSIZE 0x00080000 // DDSD_LINEARSIZE #define DDS_HEIGHT 0x00000002 // DDSD_HEIGHT #define DDS_WIDTH 0x00000004 // DDSD_WIDTH #define DDS_SURFACE_FLAGS_TEXTURE 0x00001000 // DDSCAPS_TEXTURE #define DDS_SURFACE_FLAGS_MIPMAP 0x00400008 // DDSCAPS_COMPLEX | DDSCAPS_MIPMAP #define DDS_SURFACE_FLAGS_CUBEMAP 0x00000008 // DDSCAPS_COMPLEX #define DDS_CUBEMAP_POSITIVEX 0x00000600 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEX #define DDS_CUBEMAP_NEGATIVEX 0x00000a00 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEX #define DDS_CUBEMAP_POSITIVEY 0x00001200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEY #define DDS_CUBEMAP_NEGATIVEY 0x00002200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEY #define DDS_CUBEMAP_POSITIVEZ 0x00004200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEZ #define DDS_CUBEMAP_NEGATIVEZ 0x00008200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEZ #define DDS_CUBEMAP_ALLFACES ( DDS_CUBEMAP_POSITIVEX | DDS_CUBEMAP_NEGATIVEX |\ DDS_CUBEMAP_POSITIVEY | DDS_CUBEMAP_NEGATIVEY |\ DDS_CUBEMAP_POSITIVEZ | DDS_CUBEMAP_NEGATIVEZ ) #define DDS_CUBEMAP 0x00000200 // DDSCAPS2_CUBEMAP #define DDS_FLAGS_VOLUME 0x00200000 // DDSCAPS2_VOLUME // Subset here matches D3D10_RESOURCE_DIMENSION and D3D11_RESOURCE_DIMENSION enum DDS_RESOURCE_DIMENSION { DDS_DIMENSION_TEXTURE1D = 2, DDS_DIMENSION_TEXTURE2D = 3, DDS_DIMENSION_TEXTURE3D = 4, }; // Subset here matches D3D10_RESOURCE_MISC_FLAG and D3D11_RESOURCE_MISC_FLAG enum DDS_RESOURCE_MISC_FLAG { DDS_RESOURCE_MISC_TEXTURECUBE = 0x4L, }; enum DDS_MISC_FLAGS2 { DDS_MISC_FLAGS2_ALPHA_MODE_MASK = 0x7L, }; enum DDS_ALPHA_MODE { DDS_ALPHA_MODE_UNKNOWN = 0, DDS_ALPHA_MODE_STRAIGHT = 1, DDS_ALPHA_MODE_PREMULTIPLIED = 2, DDS_ALPHA_MODE_OPAQUE = 3, DDS_ALPHA_MODE_CUSTOM = 4, }; struct DDS_HEADER { uint32_t dwSize; uint32_t dwFlags; uint32_t dwHeight; uint32_t dwWidth; uint32_t dwPitchOrLinearSize; uint32_t dwDepth; // only if DDS_HEADER_FLAGS_VOLUME is set in dwFlags uint32_t dwMipMapCount; uint32_t dwReserved1[11]; DDS_PIXELFORMAT ddspf; uint32_t dwCaps; uint32_t dwCaps2; uint32_t dwCaps3; uint32_t dwCaps4; uint32_t dwReserved2; }; struct DDS_HEADER_DXT10 { DXGI_FORMAT dxgiFormat; uint32_t resourceDimension; uint32_t miscFlag; // see DDS_RESOURCE_MISC_FLAG uint32_t arraySize; uint32_t miscFlags2; // see DDS_MISC_FLAGS2 }; #pragma pack(pop) static_assert( sizeof(DDS_HEADER) == 124, "DDS Header size mismatch" ); static_assert( sizeof(DDS_HEADER_DXT10) == 20, "DDS DX10 Extended Header size mismatch"); }; // namespace ================================================ FILE: 3rdParty/DirectXTex/DirectXTex/DirectXTex.h ================================================ //------------------------------------------------------------------------------------- // DirectXTex.h // // DirectX Texture Library // // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A // PARTICULAR PURPOSE. // // Copyright (c) Microsoft Corporation. All rights reserved. // // http://go.microsoft.com/fwlink/?LinkId=248926 //------------------------------------------------------------------------------------- #pragma once #if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) && (_WIN32_WINNT <= _WIN32_WINNT_WIN8) #error WIC is not supported on Windows Phone 8.0 #endif // VS 2010's stdint.h conflicts with intsafe.h #pragma warning(push) #pragma warning(disable : 4005) #include #pragma warning(pop) #include #include #if defined(_XBOX_ONE) && defined(_TITLE) #include #define DCOMMON_H_INCLUDED #else #include #endif #include // VS 2010 doesn't support explicit calling convention for std::function #ifndef DIRECTX_STD_CALLCONV #if defined(_MSC_VER) && (_MSC_VER < 1700) #define DIRECTX_STD_CALLCONV #else #define DIRECTX_STD_CALLCONV __cdecl #endif #endif // VS 2010/2012 do not support =default =delete #ifndef DIRECTX_CTOR_DEFAULT #if defined(_MSC_VER) && (_MSC_VER < 1800) #define DIRECTX_CTOR_DEFAULT {} #define DIRECTX_CTOR_DELETE ; #else #define DIRECTX_CTOR_DEFAULT =default; #define DIRECTX_CTOR_DELETE =delete; #endif #endif #define DIRECTX_TEX_VERSION 132 namespace DirectX { //--------------------------------------------------------------------------------- // DXGI Format Utilities bool __cdecl IsValid( _In_ DXGI_FORMAT fmt ); bool __cdecl IsCompressed( _In_ DXGI_FORMAT fmt ); bool __cdecl IsPacked( _In_ DXGI_FORMAT fmt ); bool __cdecl IsVideo( _In_ DXGI_FORMAT fmt ); bool __cdecl IsPlanar( _In_ DXGI_FORMAT fmt ); bool __cdecl IsPalettized( _In_ DXGI_FORMAT fmt ); bool __cdecl IsDepthStencil(_In_ DXGI_FORMAT fmt ); bool __cdecl IsSRGB( _In_ DXGI_FORMAT fmt ); bool __cdecl IsTypeless( _In_ DXGI_FORMAT fmt, _In_ bool partialTypeless = true ); bool __cdecl HasAlpha( _In_ DXGI_FORMAT fmt ); size_t __cdecl BitsPerPixel( _In_ DXGI_FORMAT fmt ); size_t __cdecl BitsPerColor( _In_ DXGI_FORMAT fmt ); enum CP_FLAGS { CP_FLAGS_NONE = 0x0, // Normal operation CP_FLAGS_LEGACY_DWORD = 0x1, // Assume pitch is DWORD aligned instead of BYTE aligned CP_FLAGS_PARAGRAPH = 0x2, // Assume pitch is 16-byte aligned instead of BYTE aligned CP_FLAGS_YMM = 0x4, // Assume pitch is 32-byte aligned instead of BYTE aligned CP_FLAGS_ZMM = 0x8, // Assume pitch is 64-byte aligned instead of BYTE aligned CP_FLAGS_PAGE4K = 0x200, // Assume pitch is 4096-byte aligned instead of BYTE aligned CP_FLAGS_24BPP = 0x10000, // Override with a legacy 24 bits-per-pixel format size CP_FLAGS_16BPP = 0x20000, // Override with a legacy 16 bits-per-pixel format size CP_FLAGS_8BPP = 0x40000, // Override with a legacy 8 bits-per-pixel format size }; void __cdecl ComputePitch( _In_ DXGI_FORMAT fmt, _In_ size_t width, _In_ size_t height, _Out_ size_t& rowPitch, _Out_ size_t& slicePitch, _In_ DWORD flags = CP_FLAGS_NONE ); size_t __cdecl ComputeScanlines( _In_ DXGI_FORMAT fmt, _In_ size_t height ); DXGI_FORMAT __cdecl MakeSRGB( _In_ DXGI_FORMAT fmt ); DXGI_FORMAT __cdecl MakeTypeless( _In_ DXGI_FORMAT fmt ); DXGI_FORMAT __cdecl MakeTypelessUNORM( _In_ DXGI_FORMAT fmt ); DXGI_FORMAT __cdecl MakeTypelessFLOAT( _In_ DXGI_FORMAT fmt ); //--------------------------------------------------------------------------------- // Texture metadata enum TEX_DIMENSION // Subset here matches D3D10_RESOURCE_DIMENSION and D3D11_RESOURCE_DIMENSION { TEX_DIMENSION_TEXTURE1D = 2, TEX_DIMENSION_TEXTURE2D = 3, TEX_DIMENSION_TEXTURE3D = 4, }; enum TEX_MISC_FLAG // Subset here matches D3D10_RESOURCE_MISC_FLAG and D3D11_RESOURCE_MISC_FLAG { TEX_MISC_TEXTURECUBE = 0x4L, }; enum TEX_MISC_FLAG2 { TEX_MISC2_ALPHA_MODE_MASK = 0x7L, }; enum TEX_ALPHA_MODE // Matches DDS_ALPHA_MODE, encoded in MISC_FLAGS2 { TEX_ALPHA_MODE_UNKNOWN = 0, TEX_ALPHA_MODE_STRAIGHT = 1, TEX_ALPHA_MODE_PREMULTIPLIED = 2, TEX_ALPHA_MODE_OPAQUE = 3, TEX_ALPHA_MODE_CUSTOM = 4, }; struct TexMetadata { size_t width; size_t height; // Should be 1 for 1D textures size_t depth; // Should be 1 for 1D or 2D textures size_t arraySize; // For cubemap, this is a multiple of 6 size_t mipLevels; uint32_t miscFlags; uint32_t miscFlags2; DXGI_FORMAT format; TEX_DIMENSION dimension; size_t __cdecl ComputeIndex( _In_ size_t mip, _In_ size_t item, _In_ size_t slice ) const; // Returns size_t(-1) to indicate an out-of-range error bool __cdecl IsCubemap() const { return (miscFlags & TEX_MISC_TEXTURECUBE) != 0; } // Helper for miscFlags bool __cdecl IsPMAlpha() const { return ((miscFlags2 & TEX_MISC2_ALPHA_MODE_MASK) == TEX_ALPHA_MODE_PREMULTIPLIED) != 0; } void __cdecl SetAlphaMode( TEX_ALPHA_MODE mode ) { miscFlags2 = (miscFlags2 & ~TEX_MISC2_ALPHA_MODE_MASK) | static_cast(mode); } // Helpers for miscFlags2 bool __cdecl IsVolumemap() const { return (dimension == TEX_DIMENSION_TEXTURE3D); } // Helper for dimension }; enum DDS_FLAGS { DDS_FLAGS_NONE = 0x0, DDS_FLAGS_LEGACY_DWORD = 0x1, // Assume pitch is DWORD aligned instead of BYTE aligned (used by some legacy DDS files) DDS_FLAGS_NO_LEGACY_EXPANSION = 0x2, // Do not implicitly convert legacy formats that result in larger pixel sizes (24 bpp, 3:3:2, A8L8, A4L4, P8, A8P8) DDS_FLAGS_NO_R10B10G10A2_FIXUP = 0x4, // Do not use work-around for long-standing D3DX DDS file format issue which reversed the 10:10:10:2 color order masks DDS_FLAGS_FORCE_RGB = 0x8, // Convert DXGI 1.1 BGR formats to DXGI_FORMAT_R8G8B8A8_UNORM to avoid use of optional WDDM 1.1 formats DDS_FLAGS_NO_16BPP = 0x10, // Conversions avoid use of 565, 5551, and 4444 formats and instead expand to 8888 to avoid use of optional WDDM 1.2 formats DDS_FLAGS_EXPAND_LUMINANCE = 0x20, // When loading legacy luminance formats expand replicating the color channels rather than leaving them packed (L8, L16, A8L8) DDS_FLAGS_FORCE_DX10_EXT = 0x10000, // Always use the 'DX10' header extension for DDS writer (i.e. don't try to write DX9 compatible DDS files) DDS_FLAGS_FORCE_DX10_EXT_MISC2 = 0x20000, // DDS_FLAGS_FORCE_DX10_EXT including miscFlags2 information (result may not be compatible with D3DX10 or D3DX11) }; enum WIC_FLAGS { WIC_FLAGS_NONE = 0x0, WIC_FLAGS_FORCE_RGB = 0x1, // Loads DXGI 1.1 BGR formats as DXGI_FORMAT_R8G8B8A8_UNORM to avoid use of optional WDDM 1.1 formats WIC_FLAGS_NO_X2_BIAS = 0x2, // Loads DXGI 1.1 X2 10:10:10:2 format as DXGI_FORMAT_R10G10B10A2_UNORM WIC_FLAGS_NO_16BPP = 0x4, // Loads 565, 5551, and 4444 formats as 8888 to avoid use of optional WDDM 1.2 formats WIC_FLAGS_ALLOW_MONO = 0x8, // Loads 1-bit monochrome (black & white) as R1_UNORM rather than 8-bit grayscale WIC_FLAGS_ALL_FRAMES = 0x10, // Loads all images in a multi-frame file, converting/resizing to match the first frame as needed, defaults to 0th frame otherwise WIC_FLAGS_IGNORE_SRGB = 0x20, // Ignores sRGB metadata if present in the file WIC_FLAGS_DITHER = 0x10000, // Use ordered 4x4 dithering for any required conversions WIC_FLAGS_DITHER_DIFFUSION = 0x20000, // Use error-diffusion dithering for any required conversions WIC_FLAGS_FILTER_POINT = 0x100000, WIC_FLAGS_FILTER_LINEAR = 0x200000, WIC_FLAGS_FILTER_CUBIC = 0x300000, WIC_FLAGS_FILTER_FANT = 0x400000, // Combination of Linear and Box filter // Filtering mode to use for any required image resizing (only needed when loading arrays of differently sized images; defaults to Fant) }; HRESULT __cdecl GetMetadataFromDDSMemory( _In_reads_bytes_(size) LPCVOID pSource, _In_ size_t size, _In_ DWORD flags, _Out_ TexMetadata& metadata ); HRESULT __cdecl GetMetadataFromDDSFile( _In_z_ LPCWSTR szFile, _In_ DWORD flags, _Out_ TexMetadata& metadata ); HRESULT __cdecl GetMetadataFromTGAMemory( _In_reads_bytes_(size) LPCVOID pSource, _In_ size_t size, _Out_ TexMetadata& metadata ); HRESULT __cdecl GetMetadataFromTGAFile( _In_z_ LPCWSTR szFile, _Out_ TexMetadata& metadata ); HRESULT __cdecl GetMetadataFromWICMemory( _In_reads_bytes_(size) LPCVOID pSource, _In_ size_t size, _In_ DWORD flags, _Out_ TexMetadata& metadata ); HRESULT __cdecl GetMetadataFromWICFile( _In_z_ LPCWSTR szFile, _In_ DWORD flags, _Out_ TexMetadata& metadata ); //--------------------------------------------------------------------------------- // Bitmap image container struct Image { size_t width; size_t height; DXGI_FORMAT format; size_t rowPitch; size_t slicePitch; uint8_t* pixels; }; class ScratchImage { public: ScratchImage() : _nimages(0), _size(0), _image(nullptr), _memory(nullptr) {} ScratchImage(ScratchImage&& moveFrom) : _nimages(0), _size(0), _image(nullptr), _memory(nullptr) { *this = std::move(moveFrom); } ~ScratchImage() { Release(); } ScratchImage& __cdecl operator= (ScratchImage&& moveFrom); HRESULT __cdecl Initialize( _In_ const TexMetadata& mdata, _In_ DWORD flags = CP_FLAGS_NONE ); HRESULT __cdecl Initialize1D( _In_ DXGI_FORMAT fmt, _In_ size_t length, _In_ size_t arraySize, _In_ size_t mipLevels, _In_ DWORD flags = CP_FLAGS_NONE ); HRESULT __cdecl Initialize2D( _In_ DXGI_FORMAT fmt, _In_ size_t width, _In_ size_t height, _In_ size_t arraySize, _In_ size_t mipLevels, _In_ DWORD flags = CP_FLAGS_NONE ); HRESULT __cdecl Initialize3D( _In_ DXGI_FORMAT fmt, _In_ size_t width, _In_ size_t height, _In_ size_t depth, _In_ size_t mipLevels, _In_ DWORD flags = CP_FLAGS_NONE ); HRESULT __cdecl InitializeCube( _In_ DXGI_FORMAT fmt, _In_ size_t width, _In_ size_t height, _In_ size_t nCubes, _In_ size_t mipLevels, _In_ DWORD flags = CP_FLAGS_NONE ); HRESULT __cdecl InitializeFromImage( _In_ const Image& srcImage, _In_ bool allow1D = false, _In_ DWORD flags = CP_FLAGS_NONE ); HRESULT __cdecl InitializeArrayFromImages( _In_reads_(nImages) const Image* images, _In_ size_t nImages, _In_ bool allow1D = false, _In_ DWORD flags = CP_FLAGS_NONE ); HRESULT __cdecl InitializeCubeFromImages( _In_reads_(nImages) const Image* images, _In_ size_t nImages, _In_ DWORD flags = CP_FLAGS_NONE ); HRESULT __cdecl Initialize3DFromImages( _In_reads_(depth) const Image* images, _In_ size_t depth, _In_ DWORD flags = CP_FLAGS_NONE ); void __cdecl Release(); bool __cdecl OverrideFormat( _In_ DXGI_FORMAT f ); const TexMetadata& __cdecl GetMetadata() const { return _metadata; } const Image* __cdecl GetImage(_In_ size_t mip, _In_ size_t item, _In_ size_t slice) const; const Image* __cdecl GetImages() const { return _image; } size_t __cdecl GetImageCount() const { return _nimages; } uint8_t* __cdecl GetPixels() const { return _memory; } size_t __cdecl GetPixelsSize() const { return _size; } bool __cdecl IsAlphaAllOpaque() const; private: size_t _nimages; size_t _size; TexMetadata _metadata; Image* _image; uint8_t* _memory; // Hide copy constructor and assignment operator ScratchImage( const ScratchImage& ); ScratchImage& operator=( const ScratchImage& ); }; //--------------------------------------------------------------------------------- // Memory blob (allocated buffer pointer is always 16-byte aligned) class Blob { public: Blob() : _buffer(nullptr), _size(0) {} Blob(Blob&& moveFrom) : _buffer(nullptr), _size(0) { *this = std::move(moveFrom); } ~Blob() { Release(); } Blob& __cdecl operator= (Blob&& moveFrom); HRESULT __cdecl Initialize( _In_ size_t size ); void __cdecl Release(); void *__cdecl GetBufferPointer() const { return _buffer; } size_t __cdecl GetBufferSize() const { return _size; } private: void* _buffer; size_t _size; // Hide copy constructor and assignment operator Blob( const Blob& ); Blob& operator=( const Blob& ); }; //--------------------------------------------------------------------------------- // Image I/O // DDS operations HRESULT __cdecl LoadFromDDSMemory( _In_reads_bytes_(size) LPCVOID pSource, _In_ size_t size, _In_ DWORD flags, _Out_opt_ TexMetadata* metadata, _Out_ ScratchImage& image ); HRESULT __cdecl LoadFromDDSFile( _In_z_ LPCWSTR szFile, _In_ DWORD flags, _Out_opt_ TexMetadata* metadata, _Out_ ScratchImage& image ); HRESULT __cdecl SaveToDDSMemory( _In_ const Image& image, _In_ DWORD flags, _Out_ Blob& blob ); HRESULT __cdecl SaveToDDSMemory( _In_reads_(nimages) const Image* images, _In_ size_t nimages, _In_ const TexMetadata& metadata, _In_ DWORD flags, _Out_ Blob& blob ); HRESULT __cdecl SaveToDDSFile( _In_ const Image& image, _In_ DWORD flags, _In_z_ LPCWSTR szFile ); HRESULT __cdecl SaveToDDSFile( _In_reads_(nimages) const Image* images, _In_ size_t nimages, _In_ const TexMetadata& metadata, _In_ DWORD flags, _In_z_ LPCWSTR szFile ); // TGA operations HRESULT __cdecl LoadFromTGAMemory( _In_reads_bytes_(size) LPCVOID pSource, _In_ size_t size, _Out_opt_ TexMetadata* metadata, _Out_ ScratchImage& image ); HRESULT __cdecl LoadFromTGAFile( _In_z_ LPCWSTR szFile, _Out_opt_ TexMetadata* metadata, _Out_ ScratchImage& image ); HRESULT __cdecl SaveToTGAMemory( _In_ const Image& image, _Out_ Blob& blob ); HRESULT __cdecl SaveToTGAFile( _In_ const Image& image, _In_z_ LPCWSTR szFile ); // WIC operations HRESULT __cdecl LoadFromWICMemory( _In_reads_bytes_(size) LPCVOID pSource, _In_ size_t size, _In_ DWORD flags, _Out_opt_ TexMetadata* metadata, _Out_ ScratchImage& image ); HRESULT __cdecl LoadFromWICFile( _In_z_ LPCWSTR szFile, _In_ DWORD flags, _Out_opt_ TexMetadata* metadata, _Out_ ScratchImage& image ); HRESULT __cdecl SaveToWICMemory( _In_ const Image& image, _In_ DWORD flags, _In_ REFGUID guidContainerFormat, _Out_ Blob& blob, _In_opt_ const GUID* targetFormat = nullptr, _In_opt_ std::function setCustomProps = nullptr ); HRESULT __cdecl SaveToWICMemory( _In_count_(nimages) const Image* images, _In_ size_t nimages, _In_ DWORD flags, _In_ REFGUID guidContainerFormat, _Out_ Blob& blob, _In_opt_ const GUID* targetFormat = nullptr, _In_opt_ std::function setCustomProps = nullptr ); HRESULT __cdecl SaveToWICFile( _In_ const Image& image, _In_ DWORD flags, _In_ REFGUID guidContainerFormat, _In_z_ LPCWSTR szFile, _In_opt_ const GUID* targetFormat = nullptr, _In_opt_ std::function setCustomProps = nullptr ); HRESULT __cdecl SaveToWICFile( _In_count_(nimages) const Image* images, _In_ size_t nimages, _In_ DWORD flags, _In_ REFGUID guidContainerFormat, _In_z_ LPCWSTR szFile, _In_opt_ const GUID* targetFormat = nullptr, _In_opt_ std::function setCustomProps = nullptr ); enum WICCodecs { WIC_CODEC_BMP =1, // Windows Bitmap (.bmp) WIC_CODEC_JPEG, // Joint Photographic Experts Group (.jpg, .jpeg) WIC_CODEC_PNG, // Portable Network Graphics (.png) WIC_CODEC_TIFF, // Tagged Image File Format (.tif, .tiff) WIC_CODEC_GIF, // Graphics Interchange Format (.gif) WIC_CODEC_WMP, // Windows Media Photo / HD Photo / JPEG XR (.hdp, .jxr, .wdp) WIC_CODEC_ICO, // Windows Icon (.ico) }; REFGUID __cdecl GetWICCodec( _In_ WICCodecs codec ); //--------------------------------------------------------------------------------- // Texture conversion, resizing, mipmap generation, and block compression enum TEX_FR_FLAGS { TEX_FR_ROTATE0 = 0x0, TEX_FR_ROTATE90 = 0x1, TEX_FR_ROTATE180 = 0x2, TEX_FR_ROTATE270 = 0x3, TEX_FR_FLIP_HORIZONTAL = 0x08, TEX_FR_FLIP_VERTICAL = 0x10, }; HRESULT __cdecl FlipRotate( _In_ const Image& srcImage, _In_ DWORD flags, _Out_ ScratchImage& image ); HRESULT __cdecl FlipRotate( _In_reads_(nimages) const Image* srcImages, _In_ size_t nimages, _In_ const TexMetadata& metadata, _In_ DWORD flags, _Out_ ScratchImage& result ); // Flip and/or rotate image enum TEX_FILTER_FLAGS { TEX_FILTER_DEFAULT = 0, TEX_FILTER_WRAP_U = 0x1, TEX_FILTER_WRAP_V = 0x2, TEX_FILTER_WRAP_W = 0x4, TEX_FILTER_WRAP = ( TEX_FILTER_WRAP_U | TEX_FILTER_WRAP_V | TEX_FILTER_WRAP_W ), TEX_FILTER_MIRROR_U = 0x10, TEX_FILTER_MIRROR_V = 0x20, TEX_FILTER_MIRROR_W = 0x40, TEX_FILTER_MIRROR = ( TEX_FILTER_MIRROR_U | TEX_FILTER_MIRROR_V | TEX_FILTER_MIRROR_W ), // Wrap vs. Mirror vs. Clamp filtering options TEX_FILTER_SEPARATE_ALPHA = 0x100, // Resize color and alpha channel independently TEX_FILTER_RGB_COPY_RED = 0x1000, TEX_FILTER_RGB_COPY_GREEN = 0x2000, TEX_FILTER_RGB_COPY_BLUE = 0x4000, // When converting RGB to R, defaults to using grayscale. These flags indicate copying a specific channel instead // When converting RGB to RG, defaults to copying RED | GREEN. These flags control which channels are selected instead. TEX_FILTER_DITHER = 0x10000, // Use ordered 4x4 dithering for any required conversions TEX_FILTER_DITHER_DIFFUSION = 0x20000, // Use error-diffusion dithering for any required conversions TEX_FILTER_POINT = 0x100000, TEX_FILTER_LINEAR = 0x200000, TEX_FILTER_CUBIC = 0x300000, TEX_FILTER_BOX = 0x400000, TEX_FILTER_FANT = 0x400000, // Equiv to Box filtering for mipmap generation TEX_FILTER_TRIANGLE = 0x500000, // Filtering mode to use for any required image resizing TEX_FILTER_SRGB_IN = 0x1000000, TEX_FILTER_SRGB_OUT = 0x2000000, TEX_FILTER_SRGB = ( TEX_FILTER_SRGB_IN | TEX_FILTER_SRGB_OUT ), // sRGB <-> RGB for use in conversion operations // if the input format type is IsSRGB(), then SRGB_IN is on by default // if the output format type is IsSRGB(), then SRGB_OUT is on by default TEX_FILTER_FORCE_NON_WIC = 0x10000000, // Forces use of the non-WIC path when both are an option TEX_FILTER_FORCE_WIC = 0x20000000, // Forces use of the WIC path even when logic would have picked a non-WIC path when both are an option }; HRESULT __cdecl Resize( _In_ const Image& srcImage, _In_ size_t width, _In_ size_t height, _In_ DWORD filter, _Out_ ScratchImage& image ); HRESULT __cdecl Resize( _In_reads_(nimages) const Image* srcImages, _In_ size_t nimages, _In_ const TexMetadata& metadata, _In_ size_t width, _In_ size_t height, _In_ DWORD filter, _Out_ ScratchImage& result ); // Resize the image to width x height. Defaults to Fant filtering. // Note for a complex resize, the result will always have mipLevels == 1 HRESULT __cdecl Convert( _In_ const Image& srcImage, _In_ DXGI_FORMAT format, _In_ DWORD filter, _In_ float threshold, _Out_ ScratchImage& image ); HRESULT __cdecl Convert( _In_reads_(nimages) const Image* srcImages, _In_ size_t nimages, _In_ const TexMetadata& metadata, _In_ DXGI_FORMAT format, _In_ DWORD filter, _In_ float threshold, _Out_ ScratchImage& result ); // Convert the image to a new format HRESULT __cdecl ConvertToSinglePlane( _In_ const Image& srcImage, _Out_ ScratchImage& image ); HRESULT __cdecl ConvertToSinglePlane( _In_reads_(nimages) const Image* srcImages, _In_ size_t nimages, _In_ const TexMetadata& metadata, _Out_ ScratchImage& image ); // Converts the image from a planar format to an equivalent non-planar format HRESULT __cdecl GenerateMipMaps( _In_ const Image& baseImage, _In_ DWORD filter, _In_ size_t levels, _Inout_ ScratchImage& mipChain, _In_ bool allow1D = false ); HRESULT __cdecl GenerateMipMaps( _In_reads_(nimages) const Image* srcImages, _In_ size_t nimages, _In_ const TexMetadata& metadata, _In_ DWORD filter, _In_ size_t levels, _Inout_ ScratchImage& mipChain ); // levels of '0' indicates a full mipchain, otherwise is generates that number of total levels (including the source base image) // Defaults to Fant filtering which is equivalent to a box filter HRESULT __cdecl GenerateMipMaps3D( _In_reads_(depth) const Image* baseImages, _In_ size_t depth, _In_ DWORD filter, _In_ size_t levels, _Out_ ScratchImage& mipChain ); HRESULT __cdecl GenerateMipMaps3D( _In_reads_(nimages) const Image* srcImages, _In_ size_t nimages, _In_ const TexMetadata& metadata, _In_ DWORD filter, _In_ size_t levels, _Out_ ScratchImage& mipChain ); // levels of '0' indicates a full mipchain, otherwise is generates that number of total levels (including the source base image) // Defaults to Fant filtering which is equivalent to a box filter enum TEX_PMALPHA_FLAGS { TEX_PMALPHA_DEFAULT = 0, TEX_PMALPHA_IGNORE_SRGB = 0x1, // ignores sRGB colorspace conversions TEX_PMALPHA_SRGB_IN = 0x1000000, TEX_PMALPHA_SRGB_OUT = 0x2000000, TEX_PMALPHA_SRGB = ( TEX_PMALPHA_SRGB_IN | TEX_PMALPHA_SRGB_OUT ), // if the input format type is IsSRGB(), then SRGB_IN is on by default // if the output format type is IsSRGB(), then SRGB_OUT is on by default }; HRESULT __cdecl PremultiplyAlpha( _In_ const Image& srcImage, _In_ DWORD flags, _Out_ ScratchImage& image ); HRESULT __cdecl PremultiplyAlpha( _In_reads_(nimages) const Image* srcImages, _In_ size_t nimages, _In_ const TexMetadata& metadata, _In_ DWORD flags, _Out_ ScratchImage& result ); // Converts to a premultiplied alpha version of the texture enum TEX_COMPRESS_FLAGS { TEX_COMPRESS_DEFAULT = 0, TEX_COMPRESS_RGB_DITHER = 0x10000, // Enables dithering RGB colors for BC1-3 compression TEX_COMPRESS_A_DITHER = 0x20000, // Enables dithering alpha for BC1-3 compression TEX_COMPRESS_DITHER = 0x30000, // Enables both RGB and alpha dithering for BC1-3 compression TEX_COMPRESS_UNIFORM = 0x40000, // Uniform color weighting for BC1-3 compression; by default uses perceptual weighting TEX_COMPRESS_BC7_USE_3SUBSETS = 0x80000, // Enables exhaustive search for BC7 compress for mode 0 and 2; by default skips trying these modes TEX_COMPRESS_SRGB_IN = 0x1000000, TEX_COMPRESS_SRGB_OUT = 0x2000000, TEX_COMPRESS_SRGB = ( TEX_COMPRESS_SRGB_IN | TEX_COMPRESS_SRGB_OUT ), // if the input format type is IsSRGB(), then SRGB_IN is on by default // if the output format type is IsSRGB(), then SRGB_OUT is on by default TEX_COMPRESS_PARALLEL = 0x10000000, // Compress is free to use multithreading to improve performance (by default it does not use multithreading) }; HRESULT __cdecl Compress( _In_ const Image& srcImage, _In_ DXGI_FORMAT format, _In_ DWORD compress, _In_ float alphaRef, _Out_ ScratchImage& cImage ); HRESULT __cdecl Compress( _In_reads_(nimages) const Image* srcImages, _In_ size_t nimages, _In_ const TexMetadata& metadata, _In_ DXGI_FORMAT format, _In_ DWORD compress, _In_ float alphaRef, _Out_ ScratchImage& cImages ); // Note that alphaRef is only used by BC1. 0.5f is a typical value to use HRESULT __cdecl Compress( _In_ ID3D11Device* pDevice, _In_ const Image& srcImage, _In_ DXGI_FORMAT format, _In_ DWORD compress, _In_ float alphaWeight, _Out_ ScratchImage& image ); HRESULT __cdecl Compress( _In_ ID3D11Device* pDevice, _In_ const Image* srcImages, _In_ size_t nimages, _In_ const TexMetadata& metadata, _In_ DXGI_FORMAT format, _In_ DWORD compress, _In_ float alphaWeight, _Out_ ScratchImage& cImages ); // DirectCompute-based compression (alphaWeight is only used by BC7. 1.0 is the typical value to use) HRESULT __cdecl Decompress( _In_ const Image& cImage, _In_ DXGI_FORMAT format, _Out_ ScratchImage& image ); HRESULT __cdecl Decompress( _In_reads_(nimages) const Image* cImages, _In_ size_t nimages, _In_ const TexMetadata& metadata, _In_ DXGI_FORMAT format, _Out_ ScratchImage& images ); //--------------------------------------------------------------------------------- // Normal map operations enum CNMAP_FLAGS { CNMAP_DEFAULT = 0, CNMAP_CHANNEL_RED = 0x1, CNMAP_CHANNEL_GREEN = 0x2, CNMAP_CHANNEL_BLUE = 0x3, CNMAP_CHANNEL_ALPHA = 0x4, CNMAP_CHANNEL_LUMINANCE = 0x5, // Channel selection when evaluting color value for height // Luminance is a combination of red, green, and blue CNMAP_MIRROR_U = 0x1000, CNMAP_MIRROR_V = 0x2000, CNMAP_MIRROR = 0x3000, // Use mirror semantics for scanline references (defaults to wrap) CNMAP_INVERT_SIGN = 0x4000, // Inverts normal sign CNMAP_COMPUTE_OCCLUSION = 0x8000, // Computes a crude occlusion term stored in the alpha channel }; HRESULT __cdecl ComputeNormalMap( _In_ const Image& srcImage, _In_ DWORD flags, _In_ float amplitude, _In_ DXGI_FORMAT format, _Out_ ScratchImage& normalMap ); HRESULT __cdecl ComputeNormalMap( _In_reads_(nimages) const Image* srcImages, _In_ size_t nimages, _In_ const TexMetadata& metadata, _In_ DWORD flags, _In_ float amplitude, _In_ DXGI_FORMAT format, _Out_ ScratchImage& normalMaps ); //--------------------------------------------------------------------------------- // Misc image operations struct Rect { size_t x; size_t y; size_t w; size_t h; Rect() DIRECTX_CTOR_DEFAULT Rect( size_t _x, size_t _y, size_t _w, size_t _h ) : x(_x), y(_y), w(_w), h(_h) {} }; HRESULT __cdecl CopyRectangle( _In_ const Image& srcImage, _In_ const Rect& srcRect, _In_ const Image& dstImage, _In_ DWORD filter, _In_ size_t xOffset, _In_ size_t yOffset ); enum CMSE_FLAGS { CMSE_DEFAULT = 0, CMSE_IMAGE1_SRGB = 0x1, CMSE_IMAGE2_SRGB = 0x2, // Indicates that image needs gamma correction before comparision CMSE_IGNORE_RED = 0x10, CMSE_IGNORE_GREEN = 0x20, CMSE_IGNORE_BLUE = 0x40, CMSE_IGNORE_ALPHA = 0x80, // Ignore the channel when computing MSE CMSE_IMAGE1_X2_BIAS = 0x100, CMSE_IMAGE2_X2_BIAS = 0x200, // Indicates that image should be scaled and biased before comparison (i.e. UNORM -> SNORM) }; HRESULT __cdecl ComputeMSE( _In_ const Image& image1, _In_ const Image& image2, _Out_ float& mse, _Out_writes_opt_(4) float* mseV, _In_ DWORD flags = 0 ); //--------------------------------------------------------------------------------- // Direct3D 11 functions bool __cdecl IsSupportedTexture( _In_ ID3D11Device* pDevice, _In_ const TexMetadata& metadata ); HRESULT __cdecl CreateTexture( _In_ ID3D11Device* pDevice, _In_reads_(nimages) const Image* srcImages, _In_ size_t nimages, _In_ const TexMetadata& metadata, _Outptr_ ID3D11Resource** ppResource ); HRESULT __cdecl CreateShaderResourceView( _In_ ID3D11Device* pDevice, _In_reads_(nimages) const Image* srcImages, _In_ size_t nimages, _In_ const TexMetadata& metadata, _Outptr_ ID3D11ShaderResourceView** ppSRV ); HRESULT __cdecl CreateTextureEx( _In_ ID3D11Device* pDevice, _In_reads_(nimages) const Image* srcImages, _In_ size_t nimages, _In_ const TexMetadata& metadata, _In_ D3D11_USAGE usage, _In_ unsigned int bindFlags, _In_ unsigned int cpuAccessFlags, _In_ unsigned int miscFlags, _In_ bool forceSRGB, _Outptr_ ID3D11Resource** ppResource ); HRESULT __cdecl CreateShaderResourceViewEx( _In_ ID3D11Device* pDevice, _In_reads_(nimages) const Image* srcImages, _In_ size_t nimages, _In_ const TexMetadata& metadata, _In_ D3D11_USAGE usage, _In_ unsigned int bindFlags, _In_ unsigned int cpuAccessFlags, _In_ unsigned int miscFlags, _In_ bool forceSRGB, _Outptr_ ID3D11ShaderResourceView** ppSRV ); HRESULT __cdecl CaptureTexture( _In_ ID3D11Device* pDevice, _In_ ID3D11DeviceContext* pContext, _In_ ID3D11Resource* pSource, _Out_ ScratchImage& result ); #include "DirectXTex.inl" }; // namespace ================================================ FILE: 3rdParty/DirectXTex/DirectXTex/DirectXTex.inl ================================================ //------------------------------------------------------------------------------------- // DirectXTex.inl // // DirectX Texture Library // // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A // PARTICULAR PURPOSE. // // Copyright (c) Microsoft Corporation. All rights reserved. // // http://go.microsoft.com/fwlink/?LinkId=248926 //------------------------------------------------------------------------------------- #pragma once //===================================================================================== // DXGI Format Utilities //===================================================================================== _Use_decl_annotations_ inline bool __cdecl IsValid( DXGI_FORMAT fmt ) { return ( static_cast(fmt) >= 1 && static_cast(fmt) <= 120 ); } _Use_decl_annotations_ inline bool __cdecl IsCompressed(DXGI_FORMAT fmt) { switch ( fmt ) { case DXGI_FORMAT_BC1_TYPELESS: case DXGI_FORMAT_BC1_UNORM: case DXGI_FORMAT_BC1_UNORM_SRGB: case DXGI_FORMAT_BC2_TYPELESS: case DXGI_FORMAT_BC2_UNORM: case DXGI_FORMAT_BC2_UNORM_SRGB: case DXGI_FORMAT_BC3_TYPELESS: case DXGI_FORMAT_BC3_UNORM: case DXGI_FORMAT_BC3_UNORM_SRGB: case DXGI_FORMAT_BC4_TYPELESS: case DXGI_FORMAT_BC4_UNORM: case DXGI_FORMAT_BC4_SNORM: case DXGI_FORMAT_BC5_TYPELESS: case DXGI_FORMAT_BC5_UNORM: case DXGI_FORMAT_BC5_SNORM: case DXGI_FORMAT_BC6H_TYPELESS: case DXGI_FORMAT_BC6H_UF16: case DXGI_FORMAT_BC6H_SF16: case DXGI_FORMAT_BC7_TYPELESS: case DXGI_FORMAT_BC7_UNORM: case DXGI_FORMAT_BC7_UNORM_SRGB: return true; default: return false; } } _Use_decl_annotations_ inline bool __cdecl IsPacked(DXGI_FORMAT fmt) { switch( fmt ) { case DXGI_FORMAT_R8G8_B8G8_UNORM: case DXGI_FORMAT_G8R8_G8B8_UNORM: case DXGI_FORMAT_YUY2: // 4:2:2 8-bit case DXGI_FORMAT_Y210: // 4:2:2 10-bit case DXGI_FORMAT_Y216: // 4:2:2 16-bit return true; default: return false; } } _Use_decl_annotations_ inline bool __cdecl IsPlanar(DXGI_FORMAT fmt) { switch ( static_cast(fmt) ) { case DXGI_FORMAT_NV12: // 4:2:0 8-bit case DXGI_FORMAT_P010: // 4:2:0 10-bit case DXGI_FORMAT_P016: // 4:2:0 16-bit case DXGI_FORMAT_420_OPAQUE:// 4:2:0 8-bit case DXGI_FORMAT_NV11: // 4:1:1 8-bit return true; case 118 /* DXGI_FORMAT_D16_UNORM_S8_UINT */: case 119 /* DXGI_FORMAT_R16_UNORM_X8_TYPELESS */: case 120 /* DXGI_FORMAT_X16_TYPELESS_G8_UINT */: // These are Xbox One platform specific types return true; default: return false; } } _Use_decl_annotations_ inline bool __cdecl IsPalettized(DXGI_FORMAT fmt) { switch( fmt ) { case DXGI_FORMAT_AI44: case DXGI_FORMAT_IA44: case DXGI_FORMAT_P8: case DXGI_FORMAT_A8P8: return true; default: return false; } } _Use_decl_annotations_ inline bool __cdecl IsVideo(DXGI_FORMAT fmt) { switch ( fmt ) { case DXGI_FORMAT_AYUV: case DXGI_FORMAT_Y410: case DXGI_FORMAT_Y416: case DXGI_FORMAT_NV12: case DXGI_FORMAT_P010: case DXGI_FORMAT_P016: case DXGI_FORMAT_YUY2: case DXGI_FORMAT_Y210: case DXGI_FORMAT_Y216: case DXGI_FORMAT_NV11: // These video formats can be used with the 3D pipeline through special view mappings case DXGI_FORMAT_420_OPAQUE: case DXGI_FORMAT_AI44: case DXGI_FORMAT_IA44: case DXGI_FORMAT_P8: case DXGI_FORMAT_A8P8: // These are limited use video formats not usable in any way by the 3D pipeline return true; default: return false; } } _Use_decl_annotations_ inline bool __cdecl IsDepthStencil(DXGI_FORMAT fmt) { switch( static_cast(fmt) ) { case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: case DXGI_FORMAT_D32_FLOAT: case DXGI_FORMAT_D24_UNORM_S8_UINT: case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: case DXGI_FORMAT_X24_TYPELESS_G8_UINT: case DXGI_FORMAT_D16_UNORM: case 118 /* DXGI_FORMAT_D16_UNORM_S8_UINT */: case 119 /* DXGI_FORMAT_R16_UNORM_X8_TYPELESS */: case 120 /* DXGI_FORMAT_X16_TYPELESS_G8_UINT */: return true; default: return false; } } _Use_decl_annotations_ inline bool __cdecl IsSRGB(DXGI_FORMAT fmt) { switch( fmt ) { case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: case DXGI_FORMAT_BC1_UNORM_SRGB: case DXGI_FORMAT_BC2_UNORM_SRGB: case DXGI_FORMAT_BC3_UNORM_SRGB: case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: case DXGI_FORMAT_BC7_UNORM_SRGB: return true; default: return false; } } _Use_decl_annotations_ inline bool __cdecl IsTypeless(DXGI_FORMAT fmt, bool partialTypeless) { switch( static_cast(fmt) ) { case DXGI_FORMAT_R32G32B32A32_TYPELESS: case DXGI_FORMAT_R32G32B32_TYPELESS: case DXGI_FORMAT_R16G16B16A16_TYPELESS: case DXGI_FORMAT_R32G32_TYPELESS: case DXGI_FORMAT_R32G8X24_TYPELESS: case DXGI_FORMAT_R10G10B10A2_TYPELESS: case DXGI_FORMAT_R8G8B8A8_TYPELESS: case DXGI_FORMAT_R16G16_TYPELESS: case DXGI_FORMAT_R32_TYPELESS: case DXGI_FORMAT_R24G8_TYPELESS: case DXGI_FORMAT_R8G8_TYPELESS: case DXGI_FORMAT_R16_TYPELESS: case DXGI_FORMAT_R8_TYPELESS: case DXGI_FORMAT_BC1_TYPELESS: case DXGI_FORMAT_BC2_TYPELESS: case DXGI_FORMAT_BC3_TYPELESS: case DXGI_FORMAT_BC4_TYPELESS: case DXGI_FORMAT_BC5_TYPELESS: case DXGI_FORMAT_B8G8R8A8_TYPELESS: case DXGI_FORMAT_B8G8R8X8_TYPELESS: case DXGI_FORMAT_BC6H_TYPELESS: case DXGI_FORMAT_BC7_TYPELESS: return true; case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: case DXGI_FORMAT_X24_TYPELESS_G8_UINT: return partialTypeless; case 119 /* DXGI_FORMAT_R16_UNORM_X8_TYPELESS */: case 120 /* DXGI_FORMAT_X16_TYPELESS_G8_UINT */: // These are Xbox One platform specific types return partialTypeless; default: return false; } } _Use_decl_annotations_ inline bool __cdecl HasAlpha(DXGI_FORMAT fmt) { switch( static_cast(fmt) ) { case DXGI_FORMAT_R32G32B32A32_TYPELESS: case DXGI_FORMAT_R32G32B32A32_FLOAT: case DXGI_FORMAT_R32G32B32A32_UINT: case DXGI_FORMAT_R32G32B32A32_SINT: case DXGI_FORMAT_R16G16B16A16_TYPELESS: case DXGI_FORMAT_R16G16B16A16_FLOAT: case DXGI_FORMAT_R16G16B16A16_UNORM: case DXGI_FORMAT_R16G16B16A16_UINT: case DXGI_FORMAT_R16G16B16A16_SNORM: case DXGI_FORMAT_R16G16B16A16_SINT: case DXGI_FORMAT_R10G10B10A2_TYPELESS: case DXGI_FORMAT_R10G10B10A2_UNORM: case DXGI_FORMAT_R10G10B10A2_UINT: case DXGI_FORMAT_R8G8B8A8_TYPELESS: case DXGI_FORMAT_R8G8B8A8_UNORM: case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: case DXGI_FORMAT_R8G8B8A8_UINT: case DXGI_FORMAT_R8G8B8A8_SNORM: case DXGI_FORMAT_R8G8B8A8_SINT: case DXGI_FORMAT_A8_UNORM: case DXGI_FORMAT_BC1_TYPELESS: case DXGI_FORMAT_BC1_UNORM: case DXGI_FORMAT_BC1_UNORM_SRGB: case DXGI_FORMAT_BC2_TYPELESS: case DXGI_FORMAT_BC2_UNORM: case DXGI_FORMAT_BC2_UNORM_SRGB: case DXGI_FORMAT_BC3_TYPELESS: case DXGI_FORMAT_BC3_UNORM: case DXGI_FORMAT_BC3_UNORM_SRGB: case DXGI_FORMAT_B5G5R5A1_UNORM: case DXGI_FORMAT_B8G8R8A8_UNORM: case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM: case DXGI_FORMAT_B8G8R8A8_TYPELESS: case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: case DXGI_FORMAT_BC7_TYPELESS: case DXGI_FORMAT_BC7_UNORM: case DXGI_FORMAT_BC7_UNORM_SRGB: case DXGI_FORMAT_AYUV: case DXGI_FORMAT_Y410: case DXGI_FORMAT_Y416: case DXGI_FORMAT_AI44: case DXGI_FORMAT_IA44: case DXGI_FORMAT_A8P8: case DXGI_FORMAT_B4G4R4A4_UNORM: return true; case 116 /* DXGI_FORMAT_R10G10B10_7E3_A2_FLOAT */: case 117 /* DXGI_FORMAT_R10G10B10_6E4_A2_FLOAT */: // These are Xbox One platform specific types return true; default: return false; } } _Use_decl_annotations_ inline size_t __cdecl ComputeScanlines(DXGI_FORMAT fmt, size_t height) { if ( IsCompressed(fmt) ) { return std::max( 1, (height + 3) / 4 ); } else if ( fmt == DXGI_FORMAT_NV11 ) { // Direct3D makes this simplifying assumption, although it is larger than the 4:1:1 data return height * 2; } else if ( IsPlanar(fmt) ) { return height + ( ( height + 1 ) >> 1 ); } else { return height; } } //===================================================================================== // Image I/O //===================================================================================== _Use_decl_annotations_ inline HRESULT __cdecl SaveToDDSMemory(const Image& image, DWORD flags, Blob& blob) { TexMetadata mdata; memset( &mdata, 0, sizeof(mdata) ); mdata.width = image.width; mdata.height = image.height; mdata.depth = 1; mdata.arraySize = 1; mdata.mipLevels = 1; mdata.format = image.format; mdata.dimension = TEX_DIMENSION_TEXTURE2D; return SaveToDDSMemory( &image, 1, mdata, flags, blob ); } _Use_decl_annotations_ inline HRESULT __cdecl SaveToDDSFile(const Image& image, DWORD flags, LPCWSTR szFile) { TexMetadata mdata; memset( &mdata, 0, sizeof(mdata) ); mdata.width = image.width; mdata.height = image.height; mdata.depth = 1; mdata.arraySize = 1; mdata.mipLevels = 1; mdata.format = image.format; mdata.dimension = TEX_DIMENSION_TEXTURE2D; return SaveToDDSFile( &image, 1, mdata, flags, szFile ); } ================================================ FILE: 3rdParty/DirectXTex/DirectXTex/DirectXTexCompress.cpp ================================================ //------------------------------------------------------------------------------------- // DirectXTexCompress.cpp // // DirectX Texture Library - Texture compression // // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A // PARTICULAR PURPOSE. // // Copyright (c) Microsoft Corporation. All rights reserved. // // http://go.microsoft.com/fwlink/?LinkId=248926 //------------------------------------------------------------------------------------- #include "directxtexp.h" #ifdef _OPENMP #include #pragma warning(disable : 4616 6993) #endif #include "bc.h" namespace DirectX { inline static DWORD _GetBCFlags( _In_ DWORD compress ) { static_assert( TEX_COMPRESS_RGB_DITHER == BC_FLAGS_DITHER_RGB, "TEX_COMPRESS_* flags should match BC_FLAGS_*" ); static_assert( TEX_COMPRESS_A_DITHER == BC_FLAGS_DITHER_A, "TEX_COMPRESS_* flags should match BC_FLAGS_*" ); static_assert( TEX_COMPRESS_DITHER == (BC_FLAGS_DITHER_RGB | BC_FLAGS_DITHER_A), "TEX_COMPRESS_* flags should match BC_FLAGS_*" ); static_assert( TEX_COMPRESS_UNIFORM == BC_FLAGS_UNIFORM, "TEX_COMPRESS_* flags should match BC_FLAGS_*" ); static_assert( TEX_COMPRESS_BC7_USE_3SUBSETS == BC_FLAGS_USE_3SUBSETS, "TEX_COMPRESS_* flags should match BC_FLAGS_*" ); return ( compress & (BC_FLAGS_DITHER_RGB|BC_FLAGS_DITHER_A|BC_FLAGS_UNIFORM|BC_FLAGS_USE_3SUBSETS) ); } inline static DWORD _GetSRGBFlags( _In_ DWORD compress ) { static_assert( TEX_COMPRESS_SRGB_IN == TEX_FILTER_SRGB_IN, "TEX_COMPRESS_SRGB* should match TEX_FILTER_SRGB*" ); static_assert( TEX_COMPRESS_SRGB_OUT == TEX_FILTER_SRGB_OUT, "TEX_COMPRESS_SRGB* should match TEX_FILTER_SRGB*" ); static_assert( TEX_COMPRESS_SRGB == TEX_FILTER_SRGB, "TEX_COMPRESS_SRGB* should match TEX_FILTER_SRGB*" ); return ( compress & TEX_COMPRESS_SRGB ); } inline static bool _DetermineEncoderSettings( _In_ DXGI_FORMAT format, _Out_ BC_ENCODE& pfEncode, _Out_ size_t& blocksize, _Out_ DWORD& cflags ) { switch(format) { case DXGI_FORMAT_BC1_UNORM: case DXGI_FORMAT_BC1_UNORM_SRGB: pfEncode = nullptr; blocksize = 8; cflags = 0; break; case DXGI_FORMAT_BC2_UNORM: case DXGI_FORMAT_BC2_UNORM_SRGB: pfEncode = D3DXEncodeBC2; blocksize = 16; cflags = 0; break; case DXGI_FORMAT_BC3_UNORM: case DXGI_FORMAT_BC3_UNORM_SRGB: pfEncode = D3DXEncodeBC3; blocksize = 16; cflags = 0; break; case DXGI_FORMAT_BC4_UNORM: pfEncode = D3DXEncodeBC4U; blocksize = 8; cflags = TEX_FILTER_RGB_COPY_RED; break; case DXGI_FORMAT_BC4_SNORM: pfEncode = D3DXEncodeBC4S; blocksize = 8; cflags = TEX_FILTER_RGB_COPY_RED; break; case DXGI_FORMAT_BC5_UNORM: pfEncode = D3DXEncodeBC5U; blocksize = 16; cflags = TEX_FILTER_RGB_COPY_RED | TEX_FILTER_RGB_COPY_GREEN; break; case DXGI_FORMAT_BC5_SNORM: pfEncode = D3DXEncodeBC5S; blocksize = 16; cflags = TEX_FILTER_RGB_COPY_RED | TEX_FILTER_RGB_COPY_GREEN; break; case DXGI_FORMAT_BC6H_UF16: pfEncode = D3DXEncodeBC6HU; blocksize = 16; cflags = 0; break; case DXGI_FORMAT_BC6H_SF16: pfEncode = D3DXEncodeBC6HS; blocksize = 16; cflags = 0; break; case DXGI_FORMAT_BC7_UNORM: case DXGI_FORMAT_BC7_UNORM_SRGB: pfEncode = D3DXEncodeBC7; blocksize = 16; cflags = 0; break; default: pfEncode = nullptr; blocksize = 0; cflags = 0; return false; } return true; } //------------------------------------------------------------------------------------- static HRESULT _CompressBC( _In_ const Image& image, _In_ const Image& result, _In_ DWORD bcflags, _In_ DWORD srgb, _In_ float alphaRef ) { if ( !image.pixels || !result.pixels ) return E_POINTER; assert( image.width == result.width ); assert( image.height == result.height ); const DXGI_FORMAT format = image.format; size_t sbpp = BitsPerPixel( format ); if ( !sbpp ) return E_FAIL; if ( sbpp < 8 ) { // We don't support compressing from monochrome (DXGI_FORMAT_R1_UNORM) return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); } // Round to bytes sbpp = ( sbpp + 7 ) / 8; uint8_t *pDest = result.pixels; // Determine BC format encoder BC_ENCODE pfEncode; size_t blocksize; DWORD cflags; if ( !_DetermineEncoderSettings( result.format, pfEncode, blocksize, cflags ) ) return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); XMVECTOR temp[16]; const uint8_t *pSrc = image.pixels; const size_t rowPitch = image.rowPitch; for( size_t h=0; h < image.height; h += 4 ) { const uint8_t *sptr = pSrc; uint8_t* dptr = pDest; size_t ph = std::min( 4, image.height - h ); size_t w = 0; for( size_t count = 0; (count < result.rowPitch) && (w < image.width); count += blocksize, w += 4 ) { size_t pw = std::min( 4, image.width - w ); assert( pw > 0 && ph > 0 ); if ( !_LoadScanline( &temp[0], pw, sptr, rowPitch, format ) ) return E_FAIL; if ( ph > 1 ) { if ( !_LoadScanline( &temp[4], pw, sptr + rowPitch, rowPitch, format ) ) return E_FAIL; if ( ph > 2 ) { if ( !_LoadScanline( &temp[8], pw, sptr + rowPitch*2, rowPitch, format ) ) return E_FAIL; if ( ph > 3 ) { if ( !_LoadScanline( &temp[12], pw, sptr + rowPitch*3, rowPitch, format ) ) return E_FAIL; } } } if ( pw != 4 || ph != 4 ) { // Replicate pixels for partial block static const size_t uSrc[] = { 0, 0, 0, 1 }; if ( pw < 4 ) { for( size_t t = 0; t < ph && t < 4; ++t ) { for( size_t s = pw; s < 4; ++s ) { #pragma prefast(suppress: 26000, "PREFAST false positive") temp[ (t << 2) | s ] = temp[ (t << 2) | uSrc[s] ]; } } } if ( ph < 4 ) { for( size_t t = ph; t < 4; ++t ) { for( size_t s = 0; s < 4; ++s ) { #pragma prefast(suppress: 26000, "PREFAST false positive") temp[ (t << 2) | s ] = temp[ (uSrc[t] << 2) | s ]; } } } } _ConvertScanline( temp, 16, result.format, format, cflags | srgb ); if ( pfEncode ) pfEncode( dptr, temp, bcflags ); else D3DXEncodeBC1( dptr, temp, alphaRef, bcflags ); sptr += sbpp*4; dptr += blocksize; } pSrc += rowPitch*4; pDest += result.rowPitch; } return S_OK; } //------------------------------------------------------------------------------------- #ifdef _OPENMP static HRESULT _CompressBC_Parallel( _In_ const Image& image, _In_ const Image& result, _In_ DWORD bcflags, _In_ DWORD srgb, _In_ float alphaRef ) { if ( !image.pixels || !result.pixels ) return E_POINTER; assert( image.width == result.width ); assert( image.height == result.height ); const DXGI_FORMAT format = image.format; size_t sbpp = BitsPerPixel( format ); if ( !sbpp ) return E_FAIL; if ( sbpp < 8 ) { // We don't support compressing from monochrome (DXGI_FORMAT_R1_UNORM) return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); } // Round to bytes sbpp = ( sbpp + 7 ) / 8; // Determine BC format encoder BC_ENCODE pfEncode; size_t blocksize; DWORD cflags; if ( !_DetermineEncoderSettings( result.format, pfEncode, blocksize, cflags ) ) return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); // Refactored version of loop to support parallel independance const size_t nBlocks = std::max(1, (image.width + 3) / 4 ) * std::max(1, (image.height + 3) / 4 ); bool fail = false; #pragma omp parallel for for( int nb=0; nb < static_cast( nBlocks ); ++nb ) { const size_t nbWidth = std::max(1, (image.width + 3) / 4 ); const size_t y = nb / nbWidth; const size_t x = nb - (y*nbWidth); assert( x < image.width && y < image.height ); size_t rowPitch = image.rowPitch; const uint8_t *pSrc = image.pixels + (y*4*rowPitch) + (x*4*sbpp); uint8_t *pDest = result.pixels + (nb*blocksize); size_t ph = std::min( 4, image.height - y ); size_t pw = std::min( 4, image.width - x ); assert( pw > 0 && ph > 0 ); XMVECTOR temp[16]; if ( !_LoadScanline( &temp[0], pw, pSrc, rowPitch, format ) ) fail = true; if ( ph > 1 ) { if ( !_LoadScanline( &temp[4], pw, pSrc + rowPitch, rowPitch, format ) ) fail = true; if ( ph > 2 ) { if ( !_LoadScanline( &temp[8], pw, pSrc + rowPitch*2, rowPitch, format ) ) fail = true; if ( ph > 3 ) { if ( !_LoadScanline( &temp[12], pw, pSrc + rowPitch*3, rowPitch, format ) ) fail = true; } } } if ( pw != 4 || ph != 4 ) { // Replicate pixels for partial block static const size_t uSrc[] = { 0, 0, 0, 1 }; if ( pw < 4 ) { for( size_t t = 0; t < ph && t < 4; ++t ) { for( size_t s = pw; s < 4; ++s ) { temp[ (t << 2) | s ] = temp[ (t << 2) | uSrc[s] ]; } } } if ( ph < 4 ) { for( size_t t = ph; t < 4; ++t ) { for( size_t s = 0; s < 4; ++s ) { temp[ (t << 2) | s ] = temp[ (uSrc[t] << 2) | s ]; } } } } _ConvertScanline( temp, 16, result.format, format, cflags | srgb ); if ( pfEncode ) pfEncode( pDest, temp, bcflags ); else D3DXEncodeBC1( pDest, temp, alphaRef, bcflags ); } return (fail) ? E_FAIL : S_OK; } #endif // _OPENMP //------------------------------------------------------------------------------------- static DXGI_FORMAT _DefaultDecompress( _In_ DXGI_FORMAT format ) { switch( format ) { case DXGI_FORMAT_BC1_TYPELESS: case DXGI_FORMAT_BC1_UNORM: case DXGI_FORMAT_BC2_TYPELESS: case DXGI_FORMAT_BC2_UNORM: case DXGI_FORMAT_BC3_TYPELESS: case DXGI_FORMAT_BC3_UNORM: case DXGI_FORMAT_BC7_TYPELESS: case DXGI_FORMAT_BC7_UNORM: return DXGI_FORMAT_R8G8B8A8_UNORM; case DXGI_FORMAT_BC1_UNORM_SRGB: case DXGI_FORMAT_BC2_UNORM_SRGB: case DXGI_FORMAT_BC3_UNORM_SRGB: case DXGI_FORMAT_BC7_UNORM_SRGB: return DXGI_FORMAT_R8G8B8A8_UNORM_SRGB; case DXGI_FORMAT_BC4_TYPELESS: case DXGI_FORMAT_BC4_UNORM: return DXGI_FORMAT_R8_UNORM; case DXGI_FORMAT_BC4_SNORM: return DXGI_FORMAT_R8_SNORM; case DXGI_FORMAT_BC5_TYPELESS: case DXGI_FORMAT_BC5_UNORM: return DXGI_FORMAT_R8G8_UNORM; case DXGI_FORMAT_BC5_SNORM: return DXGI_FORMAT_R8G8_SNORM; case DXGI_FORMAT_BC6H_TYPELESS: case DXGI_FORMAT_BC6H_UF16: case DXGI_FORMAT_BC6H_SF16: // We could use DXGI_FORMAT_R32G32B32_FLOAT here since BC6H is always Alpha 1.0, // but this format is more supported by viewers return DXGI_FORMAT_R32G32B32A32_FLOAT; default: return DXGI_FORMAT_UNKNOWN; } } //------------------------------------------------------------------------------------- static HRESULT _DecompressBC( _In_ const Image& cImage, _In_ const Image& result ) { if ( !cImage.pixels || !result.pixels ) return E_POINTER; assert( cImage.width == result.width ); assert( cImage.height == result.height ); const DXGI_FORMAT format = result.format; size_t dbpp = BitsPerPixel( format ); if ( !dbpp ) return E_FAIL; if ( dbpp < 8 ) { // We don't support decompressing to monochrome (DXGI_FORMAT_R1_UNORM) return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); } // Round to bytes dbpp = ( dbpp + 7 ) / 8; uint8_t *pDest = result.pixels; if ( !pDest ) return E_POINTER; // Promote "typeless" BC formats DXGI_FORMAT cformat; switch( cImage.format ) { case DXGI_FORMAT_BC1_TYPELESS: cformat = DXGI_FORMAT_BC1_UNORM; break; case DXGI_FORMAT_BC2_TYPELESS: cformat = DXGI_FORMAT_BC2_UNORM; break; case DXGI_FORMAT_BC3_TYPELESS: cformat = DXGI_FORMAT_BC3_UNORM; break; case DXGI_FORMAT_BC4_TYPELESS: cformat = DXGI_FORMAT_BC4_UNORM; break; case DXGI_FORMAT_BC5_TYPELESS: cformat = DXGI_FORMAT_BC5_UNORM; break; case DXGI_FORMAT_BC6H_TYPELESS: cformat = DXGI_FORMAT_BC6H_UF16; break; case DXGI_FORMAT_BC7_TYPELESS: cformat = DXGI_FORMAT_BC7_UNORM; break; default: cformat = cImage.format; break; } // Determine BC format decoder BC_DECODE pfDecode; size_t sbpp; switch(cformat) { case DXGI_FORMAT_BC1_UNORM: case DXGI_FORMAT_BC1_UNORM_SRGB: pfDecode = D3DXDecodeBC1; sbpp = 8; break; case DXGI_FORMAT_BC2_UNORM: case DXGI_FORMAT_BC2_UNORM_SRGB: pfDecode = D3DXDecodeBC2; sbpp = 16; break; case DXGI_FORMAT_BC3_UNORM: case DXGI_FORMAT_BC3_UNORM_SRGB: pfDecode = D3DXDecodeBC3; sbpp = 16; break; case DXGI_FORMAT_BC4_UNORM: pfDecode = D3DXDecodeBC4U; sbpp = 8; break; case DXGI_FORMAT_BC4_SNORM: pfDecode = D3DXDecodeBC4S; sbpp = 8; break; case DXGI_FORMAT_BC5_UNORM: pfDecode = D3DXDecodeBC5U; sbpp = 16; break; case DXGI_FORMAT_BC5_SNORM: pfDecode = D3DXDecodeBC5S; sbpp = 16; break; case DXGI_FORMAT_BC6H_UF16: pfDecode = D3DXDecodeBC6HU; sbpp = 16; break; case DXGI_FORMAT_BC6H_SF16: pfDecode = D3DXDecodeBC6HS; sbpp = 16; break; case DXGI_FORMAT_BC7_UNORM: case DXGI_FORMAT_BC7_UNORM_SRGB: pfDecode = D3DXDecodeBC7; sbpp = 16; break; default: return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); } XMVECTOR temp[16]; const uint8_t *pSrc = cImage.pixels; const size_t rowPitch = result.rowPitch; for( size_t h=0; h < cImage.height; h += 4 ) { const uint8_t *sptr = pSrc; uint8_t* dptr = pDest; size_t ph = std::min( 4, cImage.height - h ); size_t w = 0; for( size_t count = 0; (count < cImage.rowPitch) && (w < cImage.width); count += sbpp, w += 4 ) { pfDecode( temp, sptr ); _ConvertScanline( temp, 16, format, cformat, 0 ); size_t pw = std::min( 4, cImage.width - w ); assert( pw > 0 && ph > 0 ); if ( !_StoreScanline( dptr, rowPitch, format, &temp[0], pw ) ) return E_FAIL; if ( ph > 1 ) { if ( !_StoreScanline( dptr + rowPitch, rowPitch, format, &temp[4], pw ) ) return E_FAIL; if ( ph > 2 ) { if ( !_StoreScanline( dptr + rowPitch*2, rowPitch, format, &temp[8], pw ) ) return E_FAIL; if ( ph > 3 ) { if ( !_StoreScanline( dptr + rowPitch*3, rowPitch, format, &temp[12], pw ) ) return E_FAIL; } } } sptr += sbpp; dptr += dbpp*4; } pSrc += cImage.rowPitch; pDest += rowPitch*4; } return S_OK; } //------------------------------------------------------------------------------------- bool _IsAlphaAllOpaqueBC( _In_ const Image& cImage ) { if ( !cImage.pixels ) return false; // Promote "typeless" BC formats DXGI_FORMAT cformat; switch( cImage.format ) { case DXGI_FORMAT_BC1_TYPELESS: cformat = DXGI_FORMAT_BC1_UNORM; break; case DXGI_FORMAT_BC2_TYPELESS: cformat = DXGI_FORMAT_BC2_UNORM; break; case DXGI_FORMAT_BC3_TYPELESS: cformat = DXGI_FORMAT_BC3_UNORM; break; case DXGI_FORMAT_BC7_TYPELESS: cformat = DXGI_FORMAT_BC7_UNORM; break; default: cformat = cImage.format; break; } // Determine BC format decoder BC_DECODE pfDecode; size_t sbpp; switch(cformat) { case DXGI_FORMAT_BC1_UNORM: case DXGI_FORMAT_BC1_UNORM_SRGB: pfDecode = D3DXDecodeBC1; sbpp = 8; break; case DXGI_FORMAT_BC2_UNORM: case DXGI_FORMAT_BC2_UNORM_SRGB: pfDecode = D3DXDecodeBC2; sbpp = 16; break; case DXGI_FORMAT_BC3_UNORM: case DXGI_FORMAT_BC3_UNORM_SRGB: pfDecode = D3DXDecodeBC3; sbpp = 16; break; case DXGI_FORMAT_BC7_UNORM: case DXGI_FORMAT_BC7_UNORM_SRGB: pfDecode = D3DXDecodeBC7; sbpp = 16; break; default: // BC4, BC5, and BC6 don't have alpha channels return false; } // Scan blocks for non-opaque alpha static const XMVECTORF32 threshold = { 0.99f, 0.99f, 0.99f, 0.99f }; XMVECTOR temp[16]; const uint8_t *pPixels = cImage.pixels; for( size_t h = 0; h < cImage.height; h += 4 ) { const uint8_t *ptr = pPixels; size_t ph = std::min( 4, cImage.height - h ); size_t w = 0; for( size_t count = 0; (count < cImage.rowPitch) && (w < cImage.width); count += sbpp, w += 4 ) { pfDecode( temp, ptr ); size_t pw = std::min( 4, cImage.width - w ); assert( pw > 0 && ph > 0 ); if ( pw == 4 && ph == 4 ) { // Full blocks for( size_t j = 0; j < 16; ++j ) { XMVECTOR alpha = XMVectorSplatW( temp[j] ); if ( XMVector4Less( alpha, threshold ) ) return false; } } else { // Handle partial blocks for( size_t y = 0; y < ph; ++y ) { for( size_t x = 0; x < pw; ++x ) { XMVECTOR alpha = XMVectorSplatW( temp[ y * 4 + x ] ); if ( XMVector4Less( alpha, threshold ) ) return false; } } } ptr += sbpp; } pPixels += cImage.rowPitch; } return true; } //===================================================================================== // Entry-points //===================================================================================== //------------------------------------------------------------------------------------- // Compression //------------------------------------------------------------------------------------- _Use_decl_annotations_ HRESULT Compress( const Image& srcImage, DXGI_FORMAT format, DWORD compress, float alphaRef, ScratchImage& image ) { if ( IsCompressed(srcImage.format) || !IsCompressed(format) ) return E_INVALIDARG; if ( IsTypeless(format) || IsTypeless(srcImage.format) || IsPlanar(srcImage.format) || IsPalettized(srcImage.format) ) return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); // Create compressed image HRESULT hr = image.Initialize2D( format, srcImage.width, srcImage.height, 1, 1 ); if ( FAILED(hr) ) return hr; const Image *img = image.GetImage( 0, 0, 0 ); if ( !img ) { image.Release(); return E_POINTER; } // Compress single image if (compress & TEX_COMPRESS_PARALLEL) { #ifndef _OPENMP return E_NOTIMPL; #else hr = _CompressBC_Parallel( srcImage, *img, _GetBCFlags( compress ), _GetSRGBFlags( compress ), alphaRef ); #endif // _OPENMP } else { hr = _CompressBC( srcImage, *img, _GetBCFlags( compress ), _GetSRGBFlags( compress ), alphaRef ); } if ( FAILED(hr) ) image.Release(); return hr; } _Use_decl_annotations_ HRESULT Compress( const Image* srcImages, size_t nimages, const TexMetadata& metadata, DXGI_FORMAT format, DWORD compress, float alphaRef, ScratchImage& cImages ) { if ( !srcImages || !nimages ) return E_INVALIDARG; if ( IsCompressed(metadata.format) || !IsCompressed(format) ) return E_INVALIDARG; if ( IsTypeless(format) || IsTypeless(metadata.format) || IsPlanar(metadata.format) || IsPalettized(metadata.format) ) return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); cImages.Release(); TexMetadata mdata2 = metadata; mdata2.format = format; HRESULT hr = cImages.Initialize( mdata2 ); if ( FAILED(hr) ) return hr; if ( nimages != cImages.GetImageCount() ) { cImages.Release(); return E_FAIL; } const Image* dest = cImages.GetImages(); if ( !dest ) { cImages.Release(); return E_POINTER; } for( size_t index=0; index < nimages; ++index ) { assert( dest[ index ].format == format ); const Image& src = srcImages[ index ]; if ( src.width != dest[ index ].width || src.height != dest[ index ].height ) { cImages.Release(); return E_FAIL; } if ( (compress & TEX_COMPRESS_PARALLEL) ) { #ifndef _OPENMP return E_NOTIMPL; #else if ( compress & TEX_COMPRESS_PARALLEL ) { hr = _CompressBC_Parallel( src, dest[ index ], _GetBCFlags( compress ), _GetSRGBFlags( compress ), alphaRef ); if ( FAILED(hr) ) { cImages.Release(); return hr; } } #endif // _OPENMP } else { hr = _CompressBC( src, dest[ index ], _GetBCFlags( compress ), _GetSRGBFlags( compress ), alphaRef ); if ( FAILED(hr) ) { cImages.Release(); return hr; } } } return S_OK; } //------------------------------------------------------------------------------------- // Decompression //------------------------------------------------------------------------------------- _Use_decl_annotations_ HRESULT Decompress( const Image& cImage, DXGI_FORMAT format, ScratchImage& image ) { if ( !IsCompressed(cImage.format) || IsCompressed(format) ) return E_INVALIDARG; if ( format == DXGI_FORMAT_UNKNOWN ) { // Pick a default decompressed format based on BC input format format = _DefaultDecompress( cImage.format ); if ( format == DXGI_FORMAT_UNKNOWN ) { // Input is not a compressed format return E_INVALIDARG; } } else { if ( !IsValid(format) ) return E_INVALIDARG; if ( IsTypeless(format) || IsPlanar(format) || IsPalettized(format) ) return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); } // Create decompressed image HRESULT hr = image.Initialize2D( format, cImage.width, cImage.height, 1, 1 ); if ( FAILED(hr) ) return hr; const Image *img = image.GetImage( 0, 0, 0 ); if ( !img ) { image.Release(); return E_POINTER; } // Decompress single image hr = _DecompressBC( cImage, *img ); if ( FAILED(hr) ) image.Release(); return hr; } _Use_decl_annotations_ HRESULT Decompress( const Image* cImages, size_t nimages, const TexMetadata& metadata, DXGI_FORMAT format, ScratchImage& images ) { if ( !cImages || !nimages ) return E_INVALIDARG; if ( !IsCompressed(metadata.format) || IsCompressed(format) ) return E_INVALIDARG; if ( format == DXGI_FORMAT_UNKNOWN ) { // Pick a default decompressed format based on BC input format format = _DefaultDecompress( cImages[0].format ); if ( format == DXGI_FORMAT_UNKNOWN ) { // Input is not a compressed format return E_FAIL; } } else { if ( !IsValid(format) ) return E_INVALIDARG; if ( IsTypeless(format) || IsPlanar(format) || IsPalettized(format) ) HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); } images.Release(); TexMetadata mdata2 = metadata; mdata2.format = format; HRESULT hr = images.Initialize( mdata2 ); if ( FAILED(hr) ) return hr; if ( nimages != images.GetImageCount() ) { images.Release(); return E_FAIL; } const Image* dest = images.GetImages(); if ( !dest ) { images.Release(); return E_POINTER; } for( size_t index=0; index < nimages; ++index ) { assert( dest[ index ].format == format ); const Image& src = cImages[ index ]; if ( !IsCompressed( src.format ) ) { images.Release(); return E_FAIL; } if ( src.width != dest[ index ].width || src.height != dest[ index ].height ) { images.Release(); return E_FAIL; } hr = _DecompressBC( src, dest[ index ] ); if ( FAILED(hr) ) { images.Release(); return hr; } } return S_OK; } }; // namespace ================================================ FILE: 3rdParty/DirectXTex/DirectXTex/DirectXTexCompressGPU.cpp ================================================ //------------------------------------------------------------------------------------- // DirectXTexCompressGPU.cpp // // DirectX Texture Library - DirectCompute-based texture compression // // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A // PARTICULAR PURPOSE. // // Copyright (c) Microsoft Corporation. All rights reserved. // // http://go.microsoft.com/fwlink/?LinkId=248926 //------------------------------------------------------------------------------------- #include "directxtexp.h" #include "bcdirectcompute.h" namespace DirectX { inline static DWORD _GetSRGBFlags( _In_ DWORD compress ) { static_assert( TEX_COMPRESS_SRGB_IN == TEX_FILTER_SRGB_IN, "TEX_COMPRESS_SRGB* should match TEX_FILTER_SRGB*" ); static_assert( TEX_COMPRESS_SRGB_OUT == TEX_FILTER_SRGB_OUT, "TEX_COMPRESS_SRGB* should match TEX_FILTER_SRGB*" ); static_assert( TEX_COMPRESS_SRGB == TEX_FILTER_SRGB, "TEX_COMPRESS_SRGB* should match TEX_FILTER_SRGB*" ); return ( compress & TEX_COMPRESS_SRGB ); } //------------------------------------------------------------------------------------- // Converts to R8G8B8A8_UNORM or R8G8B8A8_UNORM_SRGB doing any conversion logic needed //------------------------------------------------------------------------------------- static HRESULT _ConvertToRGBA32( _In_ const Image& srcImage, _In_ ScratchImage& image, bool srgb, _In_ DWORD filter ) { if ( !srcImage.pixels ) return E_POINTER; DXGI_FORMAT format = srgb ? DXGI_FORMAT_R8G8B8A8_UNORM_SRGB : DXGI_FORMAT_R8G8B8A8_UNORM; HRESULT hr = image.Initialize2D( format, srcImage.width, srcImage.height, 1, 1 ); if ( FAILED(hr) ) return hr; const Image *img = image.GetImage( 0, 0, 0 ); if ( !img ) { image.Release(); return E_POINTER; } uint8_t* pDest = img->pixels; if ( !pDest ) { image.Release(); return E_POINTER; } ScopedAlignedArrayXMVECTOR scanline( reinterpret_cast( _aligned_malloc( ( sizeof(XMVECTOR) * srcImage.width ), 16 ) ) ); if ( !scanline ) { image.Release(); return E_OUTOFMEMORY; } const uint8_t *pSrc = srcImage.pixels; for( size_t h = 0; h < srcImage.height; ++h ) { if ( !_LoadScanline( scanline.get(), srcImage.width, pSrc, srcImage.rowPitch, srcImage.format ) ) { image.Release(); return E_FAIL; } _ConvertScanline( scanline.get(), srcImage.width, format, srcImage.format, filter ); if ( !_StoreScanline( pDest, img->rowPitch, format, scanline.get(), srcImage.width ) ) { image.Release(); return E_FAIL; } pSrc += srcImage.rowPitch; pDest += img->rowPitch; } return S_OK; } //------------------------------------------------------------------------------------- // Converts to DXGI_FORMAT_R32G32B32A32_FLOAT doing any conversion logic needed //------------------------------------------------------------------------------------- static HRESULT _ConvertToRGBAF32( const Image& srcImage, ScratchImage& image, _In_ DWORD filter ) { if ( !srcImage.pixels ) return E_POINTER; HRESULT hr = image.Initialize2D( DXGI_FORMAT_R32G32B32A32_FLOAT, srcImage.width, srcImage.height, 1, 1 ); if ( FAILED(hr) ) return hr; const Image *img = image.GetImage( 0, 0, 0 ); if ( !img ) { image.Release(); return E_POINTER; } uint8_t* pDest = img->pixels; if ( !pDest ) { image.Release(); return E_POINTER; } const uint8_t *pSrc = srcImage.pixels; for( size_t h = 0; h < srcImage.height; ++h ) { if ( !_LoadScanline( reinterpret_cast(pDest), srcImage.width, pSrc, srcImage.rowPitch, srcImage.format ) ) { image.Release(); return E_FAIL; } _ConvertScanline( reinterpret_cast(pDest), srcImage.width, DXGI_FORMAT_R32G32B32A32_FLOAT, srcImage.format, filter ); pSrc += srcImage.rowPitch; pDest += img->rowPitch; } return S_OK; } //------------------------------------------------------------------------------------- // Compress using GPU, converting to the proper input format for the shader if needed //------------------------------------------------------------------------------------- inline static HRESULT _GPUCompress( _In_ GPUCompressBC* gpubc, _In_ const Image& srcImage, _In_ const Image& destImage, _In_ DWORD compress ) { if ( !gpubc ) return E_POINTER; assert( srcImage.pixels && destImage.pixels ); DXGI_FORMAT format = gpubc->GetSourceFormat(); if ( srcImage.format == format ) { // Input is already in our required source format return gpubc->Compress( srcImage, destImage ); } else { // Convert format and then use as the source image ScratchImage image; HRESULT hr; DWORD srgb = _GetSRGBFlags( compress ); switch( format ) { case DXGI_FORMAT_R8G8B8A8_UNORM: hr = _ConvertToRGBA32( srcImage, image, false, srgb ); break; case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: hr = _ConvertToRGBA32( srcImage, image, true, srgb ); break; case DXGI_FORMAT_R32G32B32A32_FLOAT: hr = _ConvertToRGBAF32( srcImage, image, srgb ); break; default: hr = E_UNEXPECTED; break; } if ( FAILED(hr) ) return hr; const Image *img = image.GetImage( 0, 0, 0 ); if ( !img ) return E_POINTER; return gpubc->Compress( *img, destImage ); } } //===================================================================================== // Entry-points //===================================================================================== //------------------------------------------------------------------------------------- // Compression //------------------------------------------------------------------------------------- _Use_decl_annotations_ HRESULT Compress( ID3D11Device* pDevice, const Image& srcImage, DXGI_FORMAT format, DWORD compress, float alphaWeight, ScratchImage& image ) { if ( !pDevice || IsCompressed(srcImage.format) || !IsCompressed(format) ) return E_INVALIDARG; if ( IsTypeless(format) || IsTypeless(srcImage.format) || IsPlanar(srcImage.format) || IsPalettized(srcImage.format) ) return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); // Setup GPU compressor std::unique_ptr gpubc( new (std::nothrow) GPUCompressBC ); if ( !gpubc ) return E_OUTOFMEMORY; HRESULT hr = gpubc->Initialize( pDevice ); if ( FAILED(hr) ) return hr; hr = gpubc->Prepare( srcImage.width, srcImage.height, format, alphaWeight, !(compress & TEX_COMPRESS_BC7_USE_3SUBSETS) ); if ( FAILED(hr) ) return hr; // Create workspace for result hr = image.Initialize2D( format, srcImage.width, srcImage.height, 1, 1 ); if ( FAILED(hr) ) return hr; const Image *img = image.GetImage( 0, 0, 0 ); if ( !img ) { image.Release(); return E_POINTER; } hr = _GPUCompress( gpubc.get(), srcImage, *img, compress ); if ( FAILED(hr) ) image.Release(); return hr; } _Use_decl_annotations_ HRESULT Compress( ID3D11Device* pDevice, const Image* srcImages, size_t nimages, const TexMetadata& metadata, DXGI_FORMAT format, DWORD compress, float alphaWeight, ScratchImage& cImages ) { if ( !pDevice || !srcImages || !nimages ) return E_INVALIDARG; if ( IsCompressed(metadata.format) || !IsCompressed(format) ) return E_INVALIDARG; if ( IsTypeless(format) || IsTypeless(metadata.format) || IsPlanar(metadata.format) || IsPalettized(metadata.format) ) return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); cImages.Release(); // Setup GPU compressor std::unique_ptr gpubc( new (std::nothrow) GPUCompressBC ); if ( !gpubc ) return E_OUTOFMEMORY; HRESULT hr = gpubc->Initialize( pDevice ); if ( FAILED(hr) ) return hr; // Create workspace for result TexMetadata mdata2 = metadata; mdata2.format = format; hr = cImages.Initialize( mdata2 ); if ( FAILED(hr) ) return hr; if ( nimages != cImages.GetImageCount() ) { cImages.Release(); return E_FAIL; } const Image* dest = cImages.GetImages(); if ( !dest ) { cImages.Release(); return E_POINTER; } // Process images (ordered by size) switch( metadata.dimension ) { case TEX_DIMENSION_TEXTURE1D: case TEX_DIMENSION_TEXTURE2D: { size_t w = metadata.width; size_t h = metadata.height; for( size_t level=0; level < metadata.mipLevels; ++level ) { hr = gpubc->Prepare( w, h, format, alphaWeight, !(compress & TEX_COMPRESS_BC7_USE_3SUBSETS) ); if ( FAILED(hr) ) { cImages.Release(); return hr; } for( size_t item = 0; item < metadata.arraySize; ++item ) { size_t index = metadata.ComputeIndex( level, item, 0 ); if ( index >= nimages ) { cImages.Release(); return E_FAIL; } assert( dest[ index ].format == format ); const Image& src = srcImages[ index ]; if ( src.width != dest[ index ].width || src.height != dest[ index ].height ) { cImages.Release(); return E_FAIL; } hr = _GPUCompress( gpubc.get(), src, dest[ index ], compress ); if ( FAILED(hr) ) { cImages.Release(); return hr; } } if ( h > 1 ) h >>= 1; if ( w > 1 ) w >>= 1; } } break; case TEX_DIMENSION_TEXTURE3D: { size_t w = metadata.width; size_t h = metadata.height; size_t d = metadata.depth; for( size_t level=0; level < metadata.mipLevels; ++level ) { hr = gpubc->Prepare( w, h, format, alphaWeight, !(compress & TEX_COMPRESS_BC7_USE_3SUBSETS) ); if ( FAILED(hr) ) { cImages.Release(); return hr; } for( size_t slice=0; slice < d; ++slice ) { size_t index = metadata.ComputeIndex( level, 0, slice ); if ( index >= nimages ) { cImages.Release(); return E_FAIL; } assert( dest[ index ].format == format ); const Image& src = srcImages[ index ]; if ( src.width != dest[ index ].width || src.height != dest[ index ].height ) { cImages.Release(); return E_FAIL; } hr = _GPUCompress( gpubc.get(), src, dest[ index ], compress ); if ( FAILED(hr) ) { cImages.Release(); return hr; } } if ( h > 1 ) h >>= 1; if ( w > 1 ) w >>= 1; if ( d > 1 ) d >>= 1; } } break; default: return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); } return S_OK; } }; // namespace ================================================ FILE: 3rdParty/DirectXTex/DirectXTex/DirectXTexConvert.cpp ================================================ //------------------------------------------------------------------------------------- // DirectXTexConvert.cpp // // DirectX Texture Library - Image conversion // // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A // PARTICULAR PURPOSE. // // Copyright (c) Microsoft Corporation. All rights reserved. // // http://go.microsoft.com/fwlink/?LinkId=248926 //------------------------------------------------------------------------------------- #include "directxtexp.h" using namespace DirectX::PackedVector; using Microsoft::WRL::ComPtr; namespace { #if DIRECTX_MATH_VERSION < 306 inline float round_to_nearest( float x ) { // Round to nearest (even) float i = floorf(x); x -= i; if(x < 0.5f) return i; if(x > 0.5f) return i + 1.f; float int_part; modff( i / 2.f, &int_part ); if ( (2.f*int_part) == i ) { return i; } return i + 1.f; } #endif inline uint32_t FloatTo7e3(float Value) { uint32_t IValue = reinterpret_cast(&Value)[0]; if ( IValue & 0x80000000U ) { // Positive only return 0; } else if (IValue > 0x41FF73FFU) { // The number is too large to be represented as a 7e3. Saturate. return 0x3FFU; } else { if (IValue < 0x3E800000U) { // The number is too small to be represented as a normalized 7e3. // Convert it to a denormalized value. uint32_t Shift = 125U - (IValue >> 23U); IValue = (0x800000U | (IValue & 0x7FFFFFU)) >> Shift; } else { // Rebias the exponent to represent the value as a normalized 7e3. IValue += 0xC2000000U; } return ((IValue + 0x7FFFU + ((IValue >> 16U) & 1U)) >> 16U)&0x3FFU; } } inline float FloatFrom7e3( uint32_t Value ) { uint32_t Mantissa = (uint32_t)(Value & 0x7F); uint32_t Exponent = (Value & 0x380); if (Exponent != 0) // The value is normalized { Exponent = (uint32_t)((Value >> 7) & 0x7); } else if (Mantissa != 0) // The value is denormalized { // Normalize the value in the resulting float Exponent = 1; do { Exponent--; Mantissa <<= 1; } while ((Mantissa & 0x80) == 0); Mantissa &= 0x7F; } else // The value is zero { Exponent = (uint32_t)-124; } uint32_t Result = ((Exponent + 124) << 23) | // Exponent (Mantissa << 16); // Mantissa return reinterpret_cast(&Result)[0]; } inline uint32_t FloatTo6e4(float Value) { uint32_t IValue = reinterpret_cast(&Value)[0]; if ( IValue & 0x80000000U ) { // Positive only return 0; } else if (IValue > 0x43FEFFFFU) { // The number is too large to be represented as a 6e4. Saturate. return 0x3FFU; } else { if (IValue < 0x3C800000U) { // The number is too small to be represented as a normalized 6e4. // Convert it to a denormalized value. uint32_t Shift = 121U - (IValue >> 23U); IValue = (0x800000U | (IValue & 0x7FFFFFU)) >> Shift; } else { // Rebias the exponent to represent the value as a normalized 6e4. IValue += 0xC4000000U; } return ((IValue + 0xFFFFU + ((IValue >> 17U) & 1U)) >> 17U)&0x3FFU; } } inline float FloatFrom6e4( uint32_t Value ) { uint32_t Mantissa = (uint32_t)(Value & 0x3F); uint32_t Exponent = (Value & 0x3C0); if (Exponent != 0) // The value is normalized { Exponent = (uint32_t)((Value >> 6) & 0xF); } else if (Mantissa != 0) // The value is denormalized { // Normalize the value in the resulting float Exponent = 1; do { Exponent--; Mantissa <<= 1; } while ((Mantissa & 0x40) == 0); Mantissa &= 0x3F; } else // The value is zero { Exponent = (uint32_t)-120; } uint32_t Result = ((Exponent + 120) << 23) | // Exponent (Mantissa << 17); // Mantissa return reinterpret_cast(&Result)[0]; } }; namespace DirectX { static const XMVECTORF32 g_Grayscale = { 0.2125f, 0.7154f, 0.0721f, 0.0f }; static const XMVECTORF32 g_HalfMin = { -65504.f, -65504.f, -65504.f, -65504.f }; static const XMVECTORF32 g_HalfMax = { 65504.f, 65504.f, 65504.f, 65504.f }; static const XMVECTORF32 g_8BitBias = { 0.5f/255.f, 0.5f/255.f, 0.5f/255.f, 0.5f/255.f }; //------------------------------------------------------------------------------------- // Copies an image row with optional clearing of alpha value to 1.0 // (can be used in place as well) otherwise copies the image row unmodified. //------------------------------------------------------------------------------------- void _CopyScanline(_When_(pDestination == pSource, _Inout_updates_bytes_(outSize)) _When_(pDestination != pSource, _Out_writes_bytes_(outSize)) LPVOID pDestination, _In_ size_t outSize, _In_reads_bytes_(inSize) LPCVOID pSource, _In_ size_t inSize, _In_ DXGI_FORMAT format, _In_ DWORD flags) { assert( pDestination && outSize > 0 ); assert( pSource && inSize > 0 ); assert( IsValid(format) && !IsPalettized(format) ); if ( flags & TEXP_SCANLINE_SETALPHA ) { switch( static_cast(format) ) { //----------------------------------------------------------------------------- case DXGI_FORMAT_R32G32B32A32_TYPELESS: case DXGI_FORMAT_R32G32B32A32_FLOAT: case DXGI_FORMAT_R32G32B32A32_UINT: case DXGI_FORMAT_R32G32B32A32_SINT: if ( inSize >= 16 && outSize >= 16 ) { uint32_t alpha; if ( format == DXGI_FORMAT_R32G32B32A32_FLOAT ) alpha = 0x3f800000; else if ( format == DXGI_FORMAT_R32G32B32A32_SINT ) alpha = 0x7fffffff; else alpha = 0xffffffff; if ( pDestination == pSource ) { uint32_t *dPtr = reinterpret_cast (pDestination); for( size_t count = 0; count < ( outSize - 15 ); count += 16 ) { dPtr += 3; *(dPtr++) = alpha; } } else { const uint32_t * __restrict sPtr = reinterpret_cast(pSource); uint32_t * __restrict dPtr = reinterpret_cast(pDestination); size_t size = std::min( outSize, inSize ); for( size_t count = 0; count < ( size - 15 ); count += 16 ) { *(dPtr++) = *(sPtr++); *(dPtr++) = *(sPtr++); *(dPtr++) = *(sPtr++); *(dPtr++) = alpha; sPtr++; } } } return; //----------------------------------------------------------------------------- case DXGI_FORMAT_R16G16B16A16_TYPELESS: case DXGI_FORMAT_R16G16B16A16_FLOAT: case DXGI_FORMAT_R16G16B16A16_UNORM: case DXGI_FORMAT_R16G16B16A16_UINT: case DXGI_FORMAT_R16G16B16A16_SNORM: case DXGI_FORMAT_R16G16B16A16_SINT: case DXGI_FORMAT_Y416: if ( inSize >= 8 && outSize >= 8 ) { uint16_t alpha; if ( format == DXGI_FORMAT_R16G16B16A16_FLOAT ) alpha = 0x3c00; else if ( format == DXGI_FORMAT_R16G16B16A16_SNORM || format == DXGI_FORMAT_R16G16B16A16_SINT ) alpha = 0x7fff; else alpha = 0xffff; if ( pDestination == pSource ) { uint16_t *dPtr = reinterpret_cast(pDestination); for( size_t count = 0; count < ( outSize - 7 ); count += 8 ) { dPtr += 3; *(dPtr++) = alpha; } } else { const uint16_t * __restrict sPtr = reinterpret_cast(pSource); uint16_t * __restrict dPtr = reinterpret_cast(pDestination); size_t size = std::min( outSize, inSize ); for( size_t count = 0; count < ( size - 7 ); count += 8 ) { *(dPtr++) = *(sPtr++); *(dPtr++) = *(sPtr++); *(dPtr++) = *(sPtr++); *(dPtr++) = alpha; sPtr++; } } } return; //----------------------------------------------------------------------------- case DXGI_FORMAT_R10G10B10A2_TYPELESS: case DXGI_FORMAT_R10G10B10A2_UNORM: case DXGI_FORMAT_R10G10B10A2_UINT: case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM: case DXGI_FORMAT_Y410: case 116 /* DXGI_FORMAT_R10G10B10_7E3_A2_FLOAT */: case 117 /* DXGI_FORMAT_R10G10B10_6E4_A2_FLOAT */: if ( inSize >= 4 && outSize >= 4 ) { if ( pDestination == pSource ) { uint32_t *dPtr = reinterpret_cast(pDestination); for( size_t count = 0; count < ( outSize - 3 ); count += 4 ) { *dPtr |= 0xC0000000; ++dPtr; } } else { const uint32_t * __restrict sPtr = reinterpret_cast(pSource); uint32_t * __restrict dPtr = reinterpret_cast(pDestination); size_t size = std::min( outSize, inSize ); for( size_t count = 0; count < ( size - 3 ); count += 4 ) { *(dPtr++) = *(sPtr++) | 0xC0000000; } } } return; //----------------------------------------------------------------------------- case DXGI_FORMAT_R8G8B8A8_TYPELESS: case DXGI_FORMAT_R8G8B8A8_UNORM: case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: case DXGI_FORMAT_R8G8B8A8_UINT: case DXGI_FORMAT_R8G8B8A8_SNORM: case DXGI_FORMAT_R8G8B8A8_SINT: case DXGI_FORMAT_B8G8R8A8_UNORM: case DXGI_FORMAT_B8G8R8A8_TYPELESS: case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: case DXGI_FORMAT_AYUV: if ( inSize >= 4 && outSize >= 4 ) { const uint32_t alpha = ( format == DXGI_FORMAT_R8G8B8A8_SNORM || format == DXGI_FORMAT_R8G8B8A8_SINT ) ? 0x7f000000 : 0xff000000; if ( pDestination == pSource ) { uint32_t *dPtr = reinterpret_cast(pDestination); for( size_t count = 0; count < ( outSize - 3 ); count += 4 ) { uint32_t t = *dPtr & 0xFFFFFF; t |= alpha; *(dPtr++) = t; } } else { const uint32_t * __restrict sPtr = reinterpret_cast(pSource); uint32_t * __restrict dPtr = reinterpret_cast(pDestination); size_t size = std::min( outSize, inSize ); for( size_t count = 0; count < ( size - 3 ); count += 4 ) { uint32_t t = *(sPtr++) & 0xFFFFFF; t |= alpha; *(dPtr++) = t; } } } return; //----------------------------------------------------------------------------- case DXGI_FORMAT_B5G5R5A1_UNORM: if ( inSize >= 2 && outSize >= 2 ) { if ( pDestination == pSource ) { uint16_t *dPtr = reinterpret_cast(pDestination); for( size_t count = 0; count < ( outSize - 1 ); count += 2 ) { *(dPtr++) |= 0x8000; } } else { const uint16_t * __restrict sPtr = reinterpret_cast(pSource); uint16_t * __restrict dPtr = reinterpret_cast(pDestination); size_t size = std::min( outSize, inSize ); for( size_t count = 0; count < ( size - 1 ); count += 2 ) { *(dPtr++) = *(sPtr++) | 0x8000; } } } return; //----------------------------------------------------------------------------- case DXGI_FORMAT_A8_UNORM: memset( pDestination, 0xff, outSize ); return; //----------------------------------------------------------------------------- case DXGI_FORMAT_B4G4R4A4_UNORM: if ( inSize >= 2 && outSize >= 2 ) { if ( pDestination == pSource ) { uint16_t *dPtr = reinterpret_cast(pDestination); for( size_t count = 0; count < ( outSize - 1 ); count += 2 ) { *(dPtr++) |= 0xF000; } } else { const uint16_t * __restrict sPtr = reinterpret_cast(pSource); uint16_t * __restrict dPtr = reinterpret_cast(pDestination); size_t size = std::min( outSize, inSize ); for( size_t count = 0; count < ( size - 1 ); count += 2 ) { *(dPtr++) = *(sPtr++) | 0xF000; } } } return; } } // Fall-through case is to just use memcpy (assuming this is not an in-place operation) if ( pDestination == pSource ) return; size_t size = std::min( outSize, inSize ); memcpy_s( pDestination, outSize, pSource, size ); } //------------------------------------------------------------------------------------- // Swizzles (RGB <-> BGR) an image row with optional clearing of alpha value to 1.0 // (can be used in place as well) otherwise copies the image row unmodified. //------------------------------------------------------------------------------------- _Use_decl_annotations_ void _SwizzleScanline( LPVOID pDestination, size_t outSize, LPCVOID pSource, size_t inSize, DXGI_FORMAT format, DWORD flags ) { assert( pDestination && outSize > 0 ); assert( pSource && inSize > 0 ); assert( IsValid(format) && !IsPlanar(format) && !IsPalettized(format) ); switch( format ) { //--------------------------------------------------------------------------------- case DXGI_FORMAT_R10G10B10A2_TYPELESS: case DXGI_FORMAT_R10G10B10A2_UNORM: case DXGI_FORMAT_R10G10B10A2_UINT: case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM: if ( inSize >= 4 && outSize >= 4 ) { if ( flags & TEXP_SCANLINE_LEGACY ) { // Swap Red (R) and Blue (B) channel (used for D3DFMT_A2R10G10B10 legacy sources) if ( pDestination == pSource ) { uint32_t *dPtr = reinterpret_cast(pDestination); for( size_t count = 0; count < ( outSize - 3 ); count += 4 ) { uint32_t t = *dPtr; uint32_t t1 = (t & 0x3ff00000) >> 20; uint32_t t2 = (t & 0x000003ff) << 20; uint32_t t3 = (t & 0x000ffc00); uint32_t ta = ( flags & TEXP_SCANLINE_SETALPHA ) ? 0xC0000000 : (t & 0xC0000000); *(dPtr++) = t1 | t2 | t3 | ta; } } else { const uint32_t * __restrict sPtr = reinterpret_cast(pSource); uint32_t * __restrict dPtr = reinterpret_cast(pDestination); size_t size = std::min( outSize, inSize ); for( size_t count = 0; count < ( size - 3 ); count += 4 ) { uint32_t t = *(sPtr++); uint32_t t1 = (t & 0x3ff00000) >> 20; uint32_t t2 = (t & 0x000003ff) << 20; uint32_t t3 = (t & 0x000ffc00); uint32_t ta = ( flags & TEXP_SCANLINE_SETALPHA ) ? 0xC0000000 : (t & 0xC0000000); *(dPtr++) = t1 | t2 | t3 | ta; } } return; } } break; //--------------------------------------------------------------------------------- case DXGI_FORMAT_R8G8B8A8_TYPELESS: case DXGI_FORMAT_R8G8B8A8_UNORM: case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: case DXGI_FORMAT_B8G8R8A8_UNORM: case DXGI_FORMAT_B8G8R8X8_UNORM: case DXGI_FORMAT_B8G8R8A8_TYPELESS: case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: case DXGI_FORMAT_B8G8R8X8_TYPELESS: case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: if ( inSize >= 4 && outSize >= 4 ) { // Swap Red (R) and Blue (B) channels (used to convert from DXGI 1.1 BGR formats to DXGI 1.0 RGB) if ( pDestination == pSource ) { uint32_t *dPtr = reinterpret_cast(pDestination); for( size_t count = 0; count < ( outSize - 3 ); count += 4 ) { uint32_t t = *dPtr; uint32_t t1 = (t & 0x00ff0000) >> 16; uint32_t t2 = (t & 0x000000ff) << 16; uint32_t t3 = (t & 0x0000ff00); uint32_t ta = ( flags & TEXP_SCANLINE_SETALPHA ) ? 0xff000000 : (t & 0xFF000000); *(dPtr++) = t1 | t2 | t3 | ta; } } else { const uint32_t * __restrict sPtr = reinterpret_cast(pSource); uint32_t * __restrict dPtr = reinterpret_cast(pDestination); size_t size = std::min( outSize, inSize ); for( size_t count = 0; count < ( size - 3 ); count += 4 ) { uint32_t t = *(sPtr++); uint32_t t1 = (t & 0x00ff0000) >> 16; uint32_t t2 = (t & 0x000000ff) << 16; uint32_t t3 = (t & 0x0000ff00); uint32_t ta = ( flags & TEXP_SCANLINE_SETALPHA ) ? 0xff000000 : (t & 0xFF000000); *(dPtr++) = t1 | t2 | t3 | ta; } } return; } break; //--------------------------------------------------------------------------------- case DXGI_FORMAT_YUY2: if ( inSize >= 4 && outSize >= 4 ) { if ( flags & TEXP_SCANLINE_LEGACY ) { // Reorder YUV components (used to convert legacy UYVY -> YUY2) if ( pDestination == pSource ) { uint32_t *dPtr = reinterpret_cast(pDestination); for( size_t count = 0; count < ( outSize - 3 ); count += 4 ) { uint32_t t = *dPtr; uint32_t t1 = (t & 0x000000ff) << 8; uint32_t t2 = (t & 0x0000ff00) >> 8; uint32_t t3 = (t & 0x00ff0000) << 8; uint32_t t4 = (t & 0xff000000) >> 8; *(dPtr++) = t1 | t2 | t3 | t4; } } else { const uint32_t * __restrict sPtr = reinterpret_cast(pSource); uint32_t * __restrict dPtr = reinterpret_cast(pDestination); size_t size = std::min( outSize, inSize ); for( size_t count = 0; count < ( size - 3 ); count += 4 ) { uint32_t t = *(sPtr++); uint32_t t1 = (t & 0x000000ff) << 8; uint32_t t2 = (t & 0x0000ff00) >> 8; uint32_t t3 = (t & 0x00ff0000) << 8; uint32_t t4 = (t & 0xff000000) >> 8; *(dPtr++) = t1 | t2 | t3 | t4; } } return; } } break; } // Fall-through case is to just use memcpy (assuming this is not an in-place operation) if ( pDestination == pSource ) return; size_t size = std::min( outSize, inSize ); memcpy_s( pDestination, outSize, pSource, size ); } //------------------------------------------------------------------------------------- // Converts an image row with optional clearing of alpha value to 1.0 // Returns true if supported, false if expansion case not supported //------------------------------------------------------------------------------------- _Use_decl_annotations_ bool _ExpandScanline( LPVOID pDestination, size_t outSize, DXGI_FORMAT outFormat, LPCVOID pSource, size_t inSize, DXGI_FORMAT inFormat, DWORD flags ) { assert( pDestination && outSize > 0 ); assert( pSource && inSize > 0 ); assert( IsValid(outFormat) && !IsPlanar(outFormat) && !IsPalettized(outFormat) ); assert( IsValid(inFormat) && !IsPlanar(inFormat) && !IsPalettized(inFormat) ); switch( inFormat ) { case DXGI_FORMAT_B5G6R5_UNORM: if ( outFormat != DXGI_FORMAT_R8G8B8A8_UNORM ) return false; // DXGI_FORMAT_B5G6R5_UNORM -> DXGI_FORMAT_R8G8B8A8_UNORM if ( inSize >= 2 && outSize >= 4 ) { const uint16_t * __restrict sPtr = reinterpret_cast(pSource); uint32_t * __restrict dPtr = reinterpret_cast(pDestination); for( size_t ocount = 0, icount = 0; ( ( icount < ( inSize - 1 ) ) && ( ocount < ( outSize - 3 ) ) ); icount += 2, ocount += 4 ) { uint16_t t = *(sPtr++); uint32_t t1 = ((t & 0xf800) >> 8) | ((t & 0xe000) >> 13); uint32_t t2 = ((t & 0x07e0) << 5) | ((t & 0x0600) >> 5); uint32_t t3 = ((t & 0x001f) << 19) | ((t & 0x001c) << 14); *(dPtr++) = t1 | t2 | t3 | 0xff000000; } return true; } return false; case DXGI_FORMAT_B5G5R5A1_UNORM: if ( outFormat != DXGI_FORMAT_R8G8B8A8_UNORM ) return false; // DXGI_FORMAT_B5G5R5A1_UNORM -> DXGI_FORMAT_R8G8B8A8_UNORM if ( inSize >= 2 && outSize >= 4 ) { const uint16_t * __restrict sPtr = reinterpret_cast(pSource); uint32_t * __restrict dPtr = reinterpret_cast(pDestination); for( size_t ocount = 0, icount = 0; ( ( icount < ( inSize - 1 ) ) && ( ocount < ( outSize - 3 ) ) ); icount += 2, ocount += 4 ) { uint16_t t = *(sPtr++); uint32_t t1 = ((t & 0x7c00) >> 7) | ((t & 0x7000) >> 12); uint32_t t2 = ((t & 0x03e0) << 6) | ((t & 0x0380) << 1); uint32_t t3 = ((t & 0x001f) << 19) | ((t & 0x001c) << 14); uint32_t ta = ( flags & TEXP_SCANLINE_SETALPHA ) ? 0xff000000 : ((t & 0x8000) ? 0xff000000 : 0); *(dPtr++) = t1 | t2 | t3 | ta; } return true; } return false; case DXGI_FORMAT_B4G4R4A4_UNORM: if ( outFormat != DXGI_FORMAT_R8G8B8A8_UNORM ) return false; // DXGI_FORMAT_B4G4R4A4_UNORM -> DXGI_FORMAT_R8G8B8A8_UNORM if ( inSize >= 2 && outSize >= 4 ) { const uint16_t * __restrict sPtr = reinterpret_cast(pSource); uint32_t * __restrict dPtr = reinterpret_cast(pDestination); for( size_t ocount = 0, icount = 0; ( ( icount < ( inSize - 1 ) ) && ( ocount < ( outSize - 3 ) ) ); icount += 2, ocount += 4 ) { uint16_t t = *(sPtr++); uint32_t t1 = ((t & 0x0f00) >> 4) | ((t & 0x0f00) >> 8); uint32_t t2 = ((t & 0x00f0) << 8) | ((t & 0x00f0) << 4); uint32_t t3 = ((t & 0x000f) << 20) | ((t & 0x000f) << 16); uint32_t ta = ( flags & TEXP_SCANLINE_SETALPHA ) ? 0xff000000 : (((t & 0xf000) << 16) | ((t & 0xf000) << 12)); *(dPtr++) = t1 | t2 | t3 | ta; } return true; } return false; } return false; } //------------------------------------------------------------------------------------- // Loads an image row into standard RGBA XMVECTOR (aligned) array //------------------------------------------------------------------------------------- #define LOAD_SCANLINE( type, func )\ if ( size >= sizeof(type) )\ {\ const type * __restrict sPtr = reinterpret_cast(pSource);\ for( size_t icount = 0; icount < ( size - sizeof(type) + 1 ); icount += sizeof(type) )\ {\ if ( dPtr >= ePtr ) break;\ *(dPtr++) = func( sPtr++ );\ }\ return true;\ }\ return false; #define LOAD_SCANLINE3( type, func, defvec )\ if ( size >= sizeof(type) )\ {\ const type * __restrict sPtr = reinterpret_cast(pSource);\ for( size_t icount = 0; icount < ( size - sizeof(type) + 1 ); icount += sizeof(type) )\ {\ XMVECTOR v = func( sPtr++ );\ if ( dPtr >= ePtr ) break;\ *(dPtr++) = XMVectorSelect( defvec, v, g_XMSelect1110 );\ }\ return true;\ }\ return false; #define LOAD_SCANLINE2( type, func, defvec )\ if ( size >= sizeof(type) )\ {\ const type * __restrict sPtr = reinterpret_cast(pSource);\ for( size_t icount = 0; icount < ( size - sizeof(type) + 1 ); icount += sizeof(type) )\ {\ XMVECTOR v = func( sPtr++ );\ if ( dPtr >= ePtr ) break;\ *(dPtr++) = XMVectorSelect( defvec, v, g_XMSelect1100 );\ }\ return true;\ }\ return false; #pragma warning(suppress: 6101) _Use_decl_annotations_ bool _LoadScanline( XMVECTOR* pDestination, size_t count, LPCVOID pSource, size_t size, DXGI_FORMAT format ) { assert( pDestination && count > 0 && (((uintptr_t)pDestination & 0xF) == 0) ); assert( pSource && size > 0 ); assert( IsValid(format) && !IsTypeless(format, false) && !IsCompressed(format) && !IsPlanar(format) && !IsPalettized(format) ); XMVECTOR* __restrict dPtr = pDestination; if ( !dPtr ) return false; const XMVECTOR* ePtr = pDestination + count; switch( static_cast(format) ) { case DXGI_FORMAT_R32G32B32A32_FLOAT: { size_t msize = (size > (sizeof(XMVECTOR)*count)) ? (sizeof(XMVECTOR)*count) : size; memcpy_s( dPtr, sizeof(XMVECTOR)*count, pSource, msize ); } return true; case DXGI_FORMAT_R32G32B32A32_UINT: LOAD_SCANLINE( XMUINT4, XMLoadUInt4 ) case DXGI_FORMAT_R32G32B32A32_SINT: LOAD_SCANLINE( XMINT4, XMLoadSInt4 ) case DXGI_FORMAT_R32G32B32_FLOAT: LOAD_SCANLINE3( XMFLOAT3, XMLoadFloat3, g_XMIdentityR3 ) case DXGI_FORMAT_R32G32B32_UINT: LOAD_SCANLINE3( XMUINT3, XMLoadUInt3, g_XMIdentityR3 ) case DXGI_FORMAT_R32G32B32_SINT: LOAD_SCANLINE3( XMINT3, XMLoadSInt3, g_XMIdentityR3 ) case DXGI_FORMAT_R16G16B16A16_FLOAT: LOAD_SCANLINE( XMHALF4, XMLoadHalf4 ) case DXGI_FORMAT_R16G16B16A16_UNORM: LOAD_SCANLINE( XMUSHORTN4, XMLoadUShortN4 ) case DXGI_FORMAT_R16G16B16A16_UINT: LOAD_SCANLINE( XMUSHORT4, XMLoadUShort4 ) case DXGI_FORMAT_R16G16B16A16_SNORM: LOAD_SCANLINE( XMSHORTN4, XMLoadShortN4 ) case DXGI_FORMAT_R16G16B16A16_SINT: LOAD_SCANLINE( XMSHORT4, XMLoadShort4 ) case DXGI_FORMAT_R32G32_FLOAT: LOAD_SCANLINE2( XMFLOAT2, XMLoadFloat2, g_XMIdentityR3 ) case DXGI_FORMAT_R32G32_UINT: LOAD_SCANLINE2( XMUINT2, XMLoadUInt2, g_XMIdentityR3 ) case DXGI_FORMAT_R32G32_SINT: LOAD_SCANLINE2( XMINT2, XMLoadSInt2, g_XMIdentityR3 ) case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: { const size_t psize = sizeof(float)+sizeof(uint32_t); if ( size >= psize ) { const float * sPtr = reinterpret_cast(pSource); for( size_t icount = 0; icount < ( size - psize + 1 ); icount += psize ) { const uint8_t* ps8 = reinterpret_cast( &sPtr[1] ); if ( dPtr >= ePtr ) break; *(dPtr++) = XMVectorSet( sPtr[0], static_cast( *ps8 ), 0.f, 1.f ); sPtr += 2; } return true; } } return false; case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: { const size_t psize = sizeof(float)+sizeof(uint32_t); if ( size >= psize ) { const float * sPtr = reinterpret_cast(pSource); for( size_t icount = 0; icount < ( size - psize + 1 ); icount += psize ) { if ( dPtr >= ePtr ) break; *(dPtr++) = XMVectorSet( sPtr[0], 0.f /* typeless component assumed zero */, 0.f, 1.f ); sPtr += 2; } return true; } } return false; case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: { const size_t psize = sizeof(float)+sizeof(uint32_t); if ( size >= psize ) { const float * sPtr = reinterpret_cast(pSource); for( size_t icount = 0; icount < ( size - psize + 1 ); icount += psize ) { const uint8_t* pg8 = reinterpret_cast( &sPtr[1] ); if ( dPtr >= ePtr ) break; *(dPtr++) = XMVectorSet( 0.f /* typeless component assumed zero */, static_cast( *pg8 ), 0.f, 1.f ); sPtr += 2; } return true; } } return false; case DXGI_FORMAT_R10G10B10A2_UNORM: LOAD_SCANLINE( XMUDECN4, XMLoadUDecN4 ); case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM: #if DIRECTX_MATH_VERSION >= 306 LOAD_SCANLINE( XMUDECN4, XMLoadUDecN4_XR ); #else if ( size >= sizeof(XMUDECN4) ) { const XMUDECN4 * __restrict sPtr = reinterpret_cast(pSource); for( size_t icount = 0; icount < ( size - sizeof(XMUDECN4) + 1 ); icount += sizeof(XMUDECN4) ) { if ( dPtr >= ePtr ) break; int32_t ElementX = sPtr->v & 0x3FF; int32_t ElementY = (sPtr->v >> 10) & 0x3FF; int32_t ElementZ = (sPtr->v >> 20) & 0x3FF; XMVECTORF32 vResult = { (float)(ElementX - 0x180) / 510.0f, (float)(ElementY - 0x180) / 510.0f, (float)(ElementZ - 0x180) / 510.0f, (float)(sPtr->v >> 30) / 3.0f }; ++sPtr; *(dPtr++) = vResult.v; } return true; } return false; #endif case DXGI_FORMAT_R10G10B10A2_UINT: LOAD_SCANLINE( XMUDEC4, XMLoadUDec4 ); case DXGI_FORMAT_R11G11B10_FLOAT: LOAD_SCANLINE3( XMFLOAT3PK, XMLoadFloat3PK, g_XMIdentityR3 ); case DXGI_FORMAT_R8G8B8A8_UNORM: case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: LOAD_SCANLINE( XMUBYTEN4, XMLoadUByteN4 ) case DXGI_FORMAT_R8G8B8A8_UINT: LOAD_SCANLINE( XMUBYTE4, XMLoadUByte4 ) case DXGI_FORMAT_R8G8B8A8_SNORM: LOAD_SCANLINE( XMBYTEN4, XMLoadByteN4 ) case DXGI_FORMAT_R8G8B8A8_SINT: LOAD_SCANLINE( XMBYTE4, XMLoadByte4 ) case DXGI_FORMAT_R16G16_FLOAT: LOAD_SCANLINE2( XMHALF2, XMLoadHalf2, g_XMIdentityR3 ) case DXGI_FORMAT_R16G16_UNORM: LOAD_SCANLINE2( XMUSHORTN2, XMLoadUShortN2, g_XMIdentityR3 ) case DXGI_FORMAT_R16G16_UINT: LOAD_SCANLINE2( XMUSHORT2, XMLoadUShort2, g_XMIdentityR3 ) case DXGI_FORMAT_R16G16_SNORM: LOAD_SCANLINE2( XMSHORTN2, XMLoadShortN2, g_XMIdentityR3 ) case DXGI_FORMAT_R16G16_SINT: LOAD_SCANLINE2( XMSHORT2, XMLoadShort2, g_XMIdentityR3 ) case DXGI_FORMAT_D32_FLOAT: case DXGI_FORMAT_R32_FLOAT: if ( size >= sizeof(float) ) { const float* __restrict sPtr = reinterpret_cast(pSource); for( size_t icount = 0; icount < ( size - sizeof(float) + 1 ); icount += sizeof(float) ) { XMVECTOR v = XMLoadFloat( sPtr++ ); if ( dPtr >= ePtr ) break; *(dPtr++) = XMVectorSelect( g_XMIdentityR3, v, g_XMSelect1000 ); } return true; } return false; case DXGI_FORMAT_R32_UINT: if ( size >= sizeof(uint32_t) ) { const uint32_t* __restrict sPtr = reinterpret_cast(pSource); for( size_t icount = 0; icount < ( size - sizeof(uint32_t) + 1 ); icount += sizeof(uint32_t) ) { XMVECTOR v = XMLoadInt( sPtr++ ); v = XMConvertVectorUIntToFloat( v, 0 ); if ( dPtr >= ePtr ) break; *(dPtr++) = XMVectorSelect( g_XMIdentityR3, v, g_XMSelect1000 ); } return true; } return false; case DXGI_FORMAT_R32_SINT: if ( size >= sizeof(int32_t) ) { const int32_t * __restrict sPtr = reinterpret_cast(pSource); for( size_t icount = 0; icount < ( size - sizeof(int32_t) + 1 ); icount += sizeof(int32_t) ) { XMVECTOR v = XMLoadInt( reinterpret_cast (sPtr++) ); v = XMConvertVectorIntToFloat( v, 0 ); if ( dPtr >= ePtr ) break; *(dPtr++) = XMVectorSelect( g_XMIdentityR3, v, g_XMSelect1000 ); } return true; } return false; case DXGI_FORMAT_D24_UNORM_S8_UINT: if ( size >= sizeof(uint32_t) ) { const uint32_t * sPtr = reinterpret_cast(pSource); for( size_t icount = 0; icount < ( size - sizeof(uint32_t) + 1 ); icount += sizeof(uint32_t) ) { float d = static_cast( *sPtr & 0xFFFFFF ) / 16777215.f; float s = static_cast( ( *sPtr & 0xFF000000 ) >> 24 ); ++sPtr; if ( dPtr >= ePtr ) break; *(dPtr++) = XMVectorSet( d, s, 0.f, 1.f ); } return true; } return false; case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: if ( size >= sizeof(uint32_t) ) { const uint32_t * sPtr = reinterpret_cast(pSource); for( size_t icount = 0; icount < ( size - sizeof(uint32_t) + 1 ); icount += sizeof(uint32_t) ) { float r = static_cast( *sPtr & 0xFFFFFF ) / 16777215.f; ++sPtr; if ( dPtr >= ePtr ) break; *(dPtr++) = XMVectorSet( r, 0.f /* typeless component assumed zero */, 0.f, 1.f ); } return true; } return false; case DXGI_FORMAT_X24_TYPELESS_G8_UINT: if ( size >= sizeof(uint32_t) ) { const uint32_t * sPtr = reinterpret_cast(pSource); for( size_t icount = 0; icount < ( size - sizeof(uint32_t) + 1 ); icount += sizeof(uint32_t) ) { float g = static_cast( ( *sPtr & 0xFF000000 ) >> 24 ); ++sPtr; if ( dPtr >= ePtr ) break; *(dPtr++) = XMVectorSet( 0.f /* typeless component assumed zero */, g, 0.f, 1.f ); } return true; } return false; case DXGI_FORMAT_R8G8_UNORM: LOAD_SCANLINE2( XMUBYTEN2, XMLoadUByteN2, g_XMIdentityR3 ) case DXGI_FORMAT_R8G8_UINT: LOAD_SCANLINE2( XMUBYTE2, XMLoadUByte2, g_XMIdentityR3 ) case DXGI_FORMAT_R8G8_SNORM: LOAD_SCANLINE2( XMBYTEN2, XMLoadByteN2, g_XMIdentityR3 ) case DXGI_FORMAT_R8G8_SINT: LOAD_SCANLINE2( XMBYTE2, XMLoadByte2, g_XMIdentityR3 ) case DXGI_FORMAT_R16_FLOAT: if ( size >= sizeof(HALF) ) { const HALF * __restrict sPtr = reinterpret_cast(pSource); for( size_t icount = 0; icount < ( size - sizeof(HALF) + 1 ); icount += sizeof(HALF) ) { if ( dPtr >= ePtr ) break; *(dPtr++) = XMVectorSet( XMConvertHalfToFloat(*sPtr++), 0.f, 0.f, 1.f ); } return true; } return false; case DXGI_FORMAT_D16_UNORM: case DXGI_FORMAT_R16_UNORM: if ( size >= sizeof(uint16_t) ) { const uint16_t* __restrict sPtr = reinterpret_cast(pSource); for( size_t icount = 0; icount < ( size - sizeof(uint16_t) + 1 ); icount += sizeof(uint16_t) ) { if ( dPtr >= ePtr ) break; *(dPtr++) = XMVectorSet( static_cast(*sPtr++) / 65535.f, 0.f, 0.f, 1.f ); } return true; } return false; case DXGI_FORMAT_R16_UINT: if ( size >= sizeof(uint16_t) ) { const uint16_t * __restrict sPtr = reinterpret_cast(pSource); for( size_t icount = 0; icount < ( size - sizeof(uint16_t) + 1 ); icount += sizeof(uint16_t) ) { if ( dPtr >= ePtr ) break; *(dPtr++) = XMVectorSet( static_cast(*sPtr++), 0.f, 0.f, 1.f ); } return true; } return false; case DXGI_FORMAT_R16_SNORM: if ( size >= sizeof(int16_t) ) { const int16_t * __restrict sPtr = reinterpret_cast(pSource); for( size_t icount = 0; icount < ( size - sizeof(int16_t) + 1 ); icount += sizeof(int16_t) ) { if ( dPtr >= ePtr ) break; *(dPtr++) = XMVectorSet( static_cast(*sPtr++) / 32767.f, 0.f, 0.f, 1.f ); } return true; } return false; case DXGI_FORMAT_R16_SINT: if ( size >= sizeof(int16_t) ) { const int16_t * __restrict sPtr = reinterpret_cast(pSource); for( size_t icount = 0; icount < ( size - sizeof(int16_t) + 1 ); icount += sizeof(int16_t) ) { if ( dPtr >= ePtr ) break; *(dPtr++) = XMVectorSet( static_cast(*sPtr++), 0.f, 0.f, 1.f ); } return true; } return false; case DXGI_FORMAT_R8_UNORM: if ( size >= sizeof(uint8_t) ) { const uint8_t * __restrict sPtr = reinterpret_cast(pSource); for( size_t icount = 0; icount < size; icount += sizeof(uint8_t) ) { if ( dPtr >= ePtr ) break; *(dPtr++) = XMVectorSet( static_cast(*sPtr++) / 255.f, 0.f, 0.f, 1.f ); } return true; } return false; case DXGI_FORMAT_R8_UINT: if ( size >= sizeof(uint8_t) ) { const uint8_t * __restrict sPtr = reinterpret_cast(pSource); for( size_t icount = 0; icount < size; icount += sizeof(uint8_t) ) { if ( dPtr >= ePtr ) break; *(dPtr++) = XMVectorSet( static_cast(*sPtr++), 0.f, 0.f, 1.f ); } return true; } return false; case DXGI_FORMAT_R8_SNORM: if ( size >= sizeof(int8_t) ) { const int8_t * __restrict sPtr = reinterpret_cast(pSource); for( size_t icount = 0; icount < size; icount += sizeof(int8_t) ) { if ( dPtr >= ePtr ) break; *(dPtr++) = XMVectorSet( static_cast(*sPtr++) / 127.f, 0.f, 0.f, 1.f ); } return true; } return false; case DXGI_FORMAT_R8_SINT: if ( size >= sizeof(int8_t) ) { const int8_t * __restrict sPtr = reinterpret_cast(pSource); for( size_t icount = 0; icount < size; icount += sizeof(int8_t) ) { if ( dPtr >= ePtr ) break; *(dPtr++) = XMVectorSet( static_cast(*sPtr++), 0.f, 0.f, 1.f ); } return true; } return false; case DXGI_FORMAT_A8_UNORM: if ( size >= sizeof(uint8_t) ) { const uint8_t * __restrict sPtr = reinterpret_cast(pSource); for( size_t icount = 0; icount < size; icount += sizeof(uint8_t) ) { if ( dPtr >= ePtr ) break; *(dPtr++) = XMVectorSet( 0.f, 0.f, 0.f, static_cast(*sPtr++) / 255.f ); } return true; } return false; case DXGI_FORMAT_R1_UNORM: if ( size >= sizeof(uint8_t) ) { const uint8_t * __restrict sPtr = reinterpret_cast(pSource); for( size_t icount = 0; icount < size; icount += sizeof(uint8_t) ) { for( size_t bcount = 8; bcount > 0; --bcount ) { if ( dPtr >= ePtr ) break; *(dPtr++) = XMVectorSet( (((*sPtr >> (bcount-1)) & 0x1) ? 1.f : 0.f), 0.f, 0.f, 1.f ); } ++sPtr; } return true; } return false; case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: #if DIRECTX_MATH_VERSION >= 306 LOAD_SCANLINE3( XMFLOAT3SE, XMLoadFloat3SE, g_XMIdentityR3 ) #else if ( size >= sizeof(XMFLOAT3SE) ) { const XMFLOAT3SE * __restrict sPtr = reinterpret_cast(pSource); for( size_t icount = 0; icount < ( size - sizeof(XMFLOAT3SE) + 1 ); icount += sizeof(XMFLOAT3SE) ) { union { float f; int32_t i; } fi; fi.i = 0x33800000 + (sPtr->e << 23); float Scale = fi.f; XMVECTORF32 v = { Scale * float( sPtr->xm ), Scale * float( sPtr->ym ), Scale * float( sPtr->zm ), 1.0f }; if ( dPtr >= ePtr ) break; *(dPtr++) = v; } return true; } return false; #endif case DXGI_FORMAT_R8G8_B8G8_UNORM: if ( size >= sizeof(XMUBYTEN4) ) { const XMUBYTEN4 * __restrict sPtr = reinterpret_cast(pSource); for( size_t icount = 0; icount < ( size - sizeof(XMUBYTEN4) + 1 ); icount += sizeof(XMUBYTEN4) ) { XMVECTOR v = XMLoadUByteN4( sPtr++ ); XMVECTOR v1 = XMVectorSwizzle<0, 3, 2, 1>( v ); if ( dPtr >= ePtr ) break; *(dPtr++) = XMVectorSelect( g_XMIdentityR3, v, g_XMSelect1110 ); if ( dPtr >= ePtr ) break; *(dPtr++) = XMVectorSelect( g_XMIdentityR3, v1, g_XMSelect1110 ); } return true; } return false; case DXGI_FORMAT_G8R8_G8B8_UNORM: if ( size >= sizeof(XMUBYTEN4) ) { const XMUBYTEN4 * __restrict sPtr = reinterpret_cast(pSource); for( size_t icount = 0; icount < ( size - sizeof(XMUBYTEN4) + 1 ); icount += sizeof(XMUBYTEN4) ) { XMVECTOR v = XMLoadUByteN4( sPtr++ ); XMVECTOR v0 = XMVectorSwizzle<1, 0, 3, 2>( v ); XMVECTOR v1 = XMVectorSwizzle<1, 2, 3, 0>( v ); if ( dPtr >= ePtr ) break; *(dPtr++) = XMVectorSelect( g_XMIdentityR3, v0, g_XMSelect1110 ); if ( dPtr >= ePtr ) break; *(dPtr++) = XMVectorSelect( g_XMIdentityR3, v1, g_XMSelect1110 ); } return true; } return false; case DXGI_FORMAT_B5G6R5_UNORM: if ( size >= sizeof(XMU565) ) { static const XMVECTORF32 s_Scale = { 1.f/31.f, 1.f/63.f, 1.f/31.f, 1.f }; const XMU565 * __restrict sPtr = reinterpret_cast(pSource); for( size_t icount = 0; icount < ( size - sizeof(XMU565) + 1 ); icount += sizeof(XMU565) ) { XMVECTOR v = XMLoadU565( sPtr++ ); v = XMVectorMultiply( v, s_Scale ); v = XMVectorSwizzle<2, 1, 0, 3>( v ); if ( dPtr >= ePtr ) break; *(dPtr++) = XMVectorSelect( g_XMIdentityR3, v, g_XMSelect1110 ); } return true; } return false; case DXGI_FORMAT_B5G5R5A1_UNORM: if ( size >= sizeof(XMU555) ) { static const XMVECTORF32 s_Scale = { 1.f/31.f, 1.f/31.f, 1.f/31.f, 1.f }; const XMU555 * __restrict sPtr = reinterpret_cast(pSource); for( size_t icount = 0; icount < ( size - sizeof(XMU555) + 1 ); icount += sizeof(XMU555) ) { XMVECTOR v = XMLoadU555( sPtr++ ); v = XMVectorMultiply( v, s_Scale ); if ( dPtr >= ePtr ) break; *(dPtr++) = XMVectorSwizzle<2, 1, 0, 3>( v ); } return true; } return false; case DXGI_FORMAT_B8G8R8A8_UNORM: case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: if ( size >= sizeof(XMUBYTEN4) ) { const XMUBYTEN4 * __restrict sPtr = reinterpret_cast(pSource); for( size_t icount = 0; icount < ( size - sizeof(XMUBYTEN4) + 1 ); icount += sizeof(XMUBYTEN4) ) { XMVECTOR v = XMLoadUByteN4( sPtr++ ); if ( dPtr >= ePtr ) break; *(dPtr++) = XMVectorSwizzle<2, 1, 0, 3>( v ); } return true; } return false; case DXGI_FORMAT_B8G8R8X8_UNORM: case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: if ( size >= sizeof(XMUBYTEN4) ) { const XMUBYTEN4 * __restrict sPtr = reinterpret_cast(pSource); for( size_t icount = 0; icount < ( size - sizeof(XMUBYTEN4) + 1 ); icount += sizeof(XMUBYTEN4) ) { XMVECTOR v = XMLoadUByteN4( sPtr++ ); v = XMVectorSwizzle<2, 1, 0, 3>( v ); if ( dPtr >= ePtr ) break; *(dPtr++) = XMVectorSelect( g_XMIdentityR3, v, g_XMSelect1110 ); } return true; } return false; case DXGI_FORMAT_AYUV: if ( size >= sizeof(XMUBYTEN4) ) { const XMUBYTEN4 * __restrict sPtr = reinterpret_cast(pSource); for( size_t icount = 0; icount < ( size - sizeof(XMUBYTEN4) + 1 ); icount += sizeof(XMUBYTEN4) ) { int v = int(sPtr->x) - 128; int u = int(sPtr->y) - 128; int y = int(sPtr->z) - 16; unsigned int a = sPtr->w; ++sPtr; // http://msdn.microsoft.com/en-us/library/windows/desktop/dd206750.aspx // Y = Y - 16 // Cb = Cb - 128 // Cr = Cr - 128 // R = 1.1644Y + 1.5960Cr // G = 1.1644Y - 0.3917Cb - 0.8128Cr // B = 1.1644Y + 2.0172Cb int r = (298 * y + 409 * v + 128) >> 8; int g = (298 * y - 100 * u - 208 * v + 128) >> 8; int b = (298 * y + 516 * u + 128) >> 8; if ( dPtr >= ePtr ) break; *(dPtr++) = XMVectorSet( float( std::min( std::max( r, 0 ), 255 ) ) / 255.f, float( std::min( std::max( g, 0 ), 255 ) ) / 255.f, float( std::min( std::max( b, 0 ), 255 ) ) / 255.f, float( a / 255.f ) ); } return true; } return false; case DXGI_FORMAT_Y410: if ( size >= sizeof(XMUDECN4) ) { const XMUDECN4 * __restrict sPtr = reinterpret_cast(pSource); for( size_t icount = 0; icount < ( size - sizeof(XMUDECN4) + 1 ); icount += sizeof(XMUDECN4) ) { int64_t u = int(sPtr->x) - 512; int64_t y = int(sPtr->y) - 64; int64_t v = int(sPtr->z) - 512; unsigned int a = sPtr->w; ++sPtr; // http://msdn.microsoft.com/en-us/library/windows/desktop/bb970578.aspx // Y = Y - 64 // Cb = Cb - 512 // Cr = Cr - 512 // R = 1.1678Y + 1.6007Cr // G = 1.1678Y - 0.3929Cb - 0.8152Cr // B = 1.1678Y + 2.0232Cb int r = static_cast( (76533 * y + 104905 * v + 32768) >> 16 ); int g = static_cast( (76533 * y - 25747 * u - 53425 * v + 32768) >> 16 ); int b = static_cast( (76533 * y + 132590 * u + 32768) >> 16 ); if ( dPtr >= ePtr ) break; *(dPtr++) = XMVectorSet( float( std::min( std::max( r, 0 ), 1023 ) ) / 1023.f, float( std::min( std::max( g, 0 ), 1023 ) ) / 1023.f, float( std::min( std::max( b, 0 ), 1023 ) ) / 1023.f, float( a / 3.f ) ); } return true; } return false; case DXGI_FORMAT_Y416: if ( size >= sizeof(XMUSHORTN4) ) { const XMUSHORTN4 * __restrict sPtr = reinterpret_cast(pSource); for( size_t icount = 0; icount < ( size - sizeof(XMUSHORTN4) + 1 ); icount += sizeof(XMUSHORTN4) ) { int64_t u = int64_t(sPtr->x) - 32768; int64_t y = int64_t(sPtr->y) - 4096; int64_t v = int64_t(sPtr->z) - 32768; unsigned int a = sPtr->w; ++sPtr; // http://msdn.microsoft.com/en-us/library/windows/desktop/bb970578.aspx // Y = Y - 4096 // Cb = Cb - 32768 // Cr = Cr - 32768 // R = 1.1689Y + 1.6023Cr // G = 1.1689Y - 0.3933Cb - 0.8160Cr // B = 1.1689Y+ 2.0251Cb int r = static_cast( (76607 * y + 105006 * v + 32768) >> 16 ); int g = static_cast( (76607 * y - 25772 * u - 53477 * v + 32768) >> 16 ); int b = static_cast( (76607 * y + 132718 * u + 32768) >> 16 ); if ( dPtr >= ePtr ) break; *(dPtr++) = XMVectorSet( float( std::min( std::max( r, 0 ), 65535 ) ) / 65535.f, float( std::min( std::max( g, 0 ), 65535 ) ) / 65535.f, float( std::min( std::max( b, 0 ), 65535 ) ) / 65535.f, float( std::min( std::max( a, 0 ), 65535 ) ) / 65535.f ); } return true; } return false; case DXGI_FORMAT_YUY2: if ( size >= sizeof(XMUBYTEN4) ) { const XMUBYTEN4 * __restrict sPtr = reinterpret_cast(pSource); for( size_t icount = 0; icount < ( size - sizeof(XMUBYTEN4) + 1 ); icount += sizeof(XMUBYTEN4) ) { int y0 = int(sPtr->x) - 16; int u = int(sPtr->y) - 128; int y1 = int(sPtr->z) - 16; int v = int(sPtr->w) - 128; ++sPtr; // See AYUV int r = (298 * y0 + 409 * v + 128) >> 8; int g = (298 * y0 - 100 * u - 208 * v + 128) >> 8; int b = (298 * y0 + 516 * u + 128) >> 8; if ( dPtr >= ePtr ) break; *(dPtr++) = XMVectorSet( float( std::min( std::max( r, 0 ), 255 ) ) / 255.f, float( std::min( std::max( g, 0 ), 255 ) ) / 255.f, float( std::min( std::max( b, 0 ), 255 ) ) / 255.f, 1.f ); r = (298 * y1 + 409 * v + 128) >> 8; g = (298 * y1 - 100 * u - 208 * v + 128) >> 8; b = (298 * y1 + 516 * u + 128) >> 8; if ( dPtr >= ePtr ) break; *(dPtr++) = XMVectorSet( float( std::min( std::max( r, 0 ), 255 ) ) / 255.f, float( std::min( std::max( g, 0 ), 255 ) ) / 255.f, float( std::min( std::max( b, 0 ), 255 ) ) / 255.f, 1.f ); } return true; } return false; case DXGI_FORMAT_Y210: // Same as Y216 with least significant 6 bits set to zero if ( size >= sizeof(XMUSHORTN4) ) { const XMUSHORTN4 * __restrict sPtr = reinterpret_cast(pSource); for( size_t icount = 0; icount < ( size - sizeof(XMUSHORTN4) + 1 ); icount += sizeof(XMUSHORTN4) ) { int64_t y0 = int64_t(sPtr->x >> 6) - 64; int64_t u = int64_t(sPtr->y >> 6) - 512; int64_t y1 = int64_t(sPtr->z >> 6) - 64; int64_t v = int64_t(sPtr->w >> 6) - 512; ++sPtr; // See Y410 int r = static_cast( (76533 * y0 + 104905 * v + 32768) >> 16 ); int g = static_cast( (76533 * y0 - 25747 * u - 53425 * v + 32768) >> 16 ); int b = static_cast( (76533 * y0 + 132590 * u + 32768) >> 16 ); if ( dPtr >= ePtr ) break; *(dPtr++) = XMVectorSet( float( std::min( std::max( r, 0 ), 1023 ) ) / 1023.f, float( std::min( std::max( g, 0 ), 1023 ) ) / 1023.f, float( std::min( std::max( b, 0 ), 1023 ) ) / 1023.f, 1.f ); r = static_cast( (76533 * y1 + 104905 * v + 32768) >> 16 ); g = static_cast( (76533 * y1 - 25747 * u - 53425 * v + 32768) >> 16 ); b = static_cast( (76533 * y1 + 132590 * u + 32768) >> 16 ); if ( dPtr >= ePtr ) break; *(dPtr++) = XMVectorSet( float( std::min( std::max( r, 0 ), 1023 ) ) / 1023.f, float( std::min( std::max( g, 0 ), 1023 ) ) / 1023.f, float( std::min( std::max( b, 0 ), 1023 ) ) / 1023.f, 1.f ); } return true; } return false; case DXGI_FORMAT_Y216: if ( size >= sizeof(XMUSHORTN4) ) { const XMUSHORTN4 * __restrict sPtr = reinterpret_cast(pSource); for( size_t icount = 0; icount < ( size - sizeof(XMUSHORTN4) + 1 ); icount += sizeof(XMUSHORTN4) ) { int64_t y0 = int64_t(sPtr->x) - 4096; int64_t u = int64_t(sPtr->y) - 32768; int64_t y1 = int64_t(sPtr->z) - 4096; int64_t v = int64_t(sPtr->w) - 32768; ++sPtr; // See Y416 int r = static_cast( (76607 * y0 + 105006 * v + 32768) >> 16 ); int g = static_cast( (76607 * y0 - 25772 * u - 53477 * v + 32768) >> 16 ); int b = static_cast( (76607 * y0 + 132718 * u + 32768) >> 16 ); if ( dPtr >= ePtr ) break; *(dPtr++) = XMVectorSet( float( std::min( std::max( r, 0 ), 65535 ) ) / 65535.f, float( std::min( std::max( g, 0 ), 65535 ) ) / 65535.f, float( std::min( std::max( b, 0 ), 65535 ) ) / 65535.f, 1.f ); r = static_cast( (76607 * y1 + 105006 * v + 32768) >> 16 ); g = static_cast( (76607 * y1 - 25772 * u - 53477 * v + 32768) >> 16 ); b = static_cast( (76607 * y1 + 132718 * u + 32768) >> 16 ); if ( dPtr >= ePtr ) break; *(dPtr++) = XMVectorSet( float( std::min( std::max( r, 0 ), 65535 ) ) / 65535.f, float( std::min( std::max( g, 0 ), 65535 ) ) / 65535.f, float( std::min( std::max( b, 0 ), 65535 ) ) / 65535.f, 1.f ); } return true; } return false; case DXGI_FORMAT_B4G4R4A4_UNORM: if ( size >= sizeof(XMUNIBBLE4) ) { static const XMVECTORF32 s_Scale = { 1.f/15.f, 1.f/15.f, 1.f/15.f, 1.f/15.f }; const XMUNIBBLE4 * __restrict sPtr = reinterpret_cast(pSource); for( size_t icount = 0; icount < ( size - sizeof(XMUNIBBLE4) + 1 ); icount += sizeof(XMUNIBBLE4) ) { XMVECTOR v = XMLoadUNibble4( sPtr++ ); v = XMVectorMultiply( v, s_Scale ); if ( dPtr >= ePtr ) break; *(dPtr++) = XMVectorSwizzle<2, 1, 0, 3>( v ); } return true; } return false; case 116 /* DXGI_FORMAT_R10G10B10_7E3_A2_FLOAT */: // Xbox One specific 7e3 format if ( size >= sizeof(XMUDECN4) ) { const XMUDECN4 * __restrict sPtr = reinterpret_cast(pSource); for( size_t icount = 0; icount < ( size - sizeof(XMUDECN4) + 1 ); icount += sizeof(XMUDECN4) ) { if ( dPtr >= ePtr ) break; XMVECTORF32 vResult = { FloatFrom7e3(sPtr->x), FloatFrom7e3(sPtr->y), FloatFrom7e3(sPtr->z), (float)(sPtr->v >> 30) / 3.0f }; ++sPtr; *(dPtr++) = vResult.v; } return true; } return false; case 117 /* DXGI_FORMAT_R10G10B10_6E4_A2_FLOAT */: // Xbox One specific 6e4 format if ( size >= sizeof(XMUDECN4) ) { const XMUDECN4 * __restrict sPtr = reinterpret_cast(pSource); for( size_t icount = 0; icount < ( size - sizeof(XMUDECN4) + 1 ); icount += sizeof(XMUDECN4) ) { if ( dPtr >= ePtr ) break; XMVECTORF32 vResult = { FloatFrom6e4(sPtr->x), FloatFrom6e4(sPtr->y), FloatFrom6e4(sPtr->z), (float)(sPtr->v >> 30) / 3.0f }; ++sPtr; *(dPtr++) = vResult.v; } return true; } return false; // We don't support the planar or palettized formats default: return false; } } #undef LOAD_SCANLINE #undef LOAD_SCANLINE3 #undef LOAD_SCANLINE2 //------------------------------------------------------------------------------------- // Stores an image row from standard RGBA XMVECTOR (aligned) array //------------------------------------------------------------------------------------- #define STORE_SCANLINE( type, func )\ if ( size >= sizeof(type) )\ {\ type * __restrict dPtr = reinterpret_cast(pDestination);\ for( size_t icount = 0; icount < ( size - sizeof(type) + 1 ); icount += sizeof(type) )\ {\ if ( sPtr >= ePtr ) break;\ func( dPtr++, *sPtr++ );\ }\ return true; \ }\ return false; _Use_decl_annotations_ bool _StoreScanline( LPVOID pDestination, size_t size, DXGI_FORMAT format, const XMVECTOR* pSource, size_t count, float threshold ) { assert( pDestination && size > 0 ); assert( pSource && count > 0 && (((uintptr_t)pSource & 0xF) == 0) ); assert( IsValid(format) && !IsTypeless(format) && !IsCompressed(format) && !IsPlanar(format) && !IsPalettized(format) ); const XMVECTOR* __restrict sPtr = pSource; if ( !sPtr ) return false; const XMVECTOR* ePtr = pSource + count; switch( static_cast(format) ) { case DXGI_FORMAT_R32G32B32A32_FLOAT: STORE_SCANLINE( XMFLOAT4, XMStoreFloat4 ) case DXGI_FORMAT_R32G32B32A32_UINT: STORE_SCANLINE( XMUINT4, XMStoreUInt4 ) case DXGI_FORMAT_R32G32B32A32_SINT: STORE_SCANLINE( XMINT4, XMStoreSInt4 ) case DXGI_FORMAT_R32G32B32_FLOAT: STORE_SCANLINE( XMFLOAT3, XMStoreFloat3 ) case DXGI_FORMAT_R32G32B32_UINT: STORE_SCANLINE( XMUINT3, XMStoreUInt3 ) case DXGI_FORMAT_R32G32B32_SINT: STORE_SCANLINE( XMINT3, XMStoreSInt3 ) case DXGI_FORMAT_R16G16B16A16_FLOAT: if ( size >= sizeof(XMHALF4) ) { XMHALF4* __restrict dPtr = reinterpret_cast(pDestination); for( size_t icount = 0; icount < ( size - sizeof(XMHALF4) + 1 ); icount += sizeof(XMHALF4) ) { if ( sPtr >= ePtr ) break; XMVECTOR v = *sPtr++; v = XMVectorClamp( v, g_HalfMin, g_HalfMax ); XMStoreHalf4( dPtr++, v ); } return true; } return false; case DXGI_FORMAT_R16G16B16A16_UNORM: STORE_SCANLINE( XMUSHORTN4, XMStoreUShortN4 ) case DXGI_FORMAT_R16G16B16A16_UINT: STORE_SCANLINE( XMUSHORT4, XMStoreUShort4 ) case DXGI_FORMAT_R16G16B16A16_SNORM: STORE_SCANLINE( XMSHORTN4, XMStoreShortN4 ) case DXGI_FORMAT_R16G16B16A16_SINT: STORE_SCANLINE( XMSHORT4, XMStoreShort4 ) case DXGI_FORMAT_R32G32_FLOAT: STORE_SCANLINE( XMFLOAT2, XMStoreFloat2 ) case DXGI_FORMAT_R32G32_UINT: STORE_SCANLINE( XMUINT2, XMStoreUInt2 ) case DXGI_FORMAT_R32G32_SINT: STORE_SCANLINE( XMINT2, XMStoreSInt2 ) case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: { const size_t psize = sizeof(float)+sizeof(uint32_t); if ( size >= psize ) { float *dPtr = reinterpret_cast(pDestination); for( size_t icount = 0; icount < ( size - psize + 1 ); icount += psize ) { if ( sPtr >= ePtr ) break; XMFLOAT4 f; XMStoreFloat4( &f, *sPtr++ ); dPtr[0] = f.x; uint8_t* ps8 = reinterpret_cast( &dPtr[1] ); ps8[0] = static_cast( std::min( 255.f, std::max( 0.f, f.y ) ) ); ps8[1] = ps8[2] = ps8[3] = 0; dPtr += 2; } return true; } } return false; case DXGI_FORMAT_R10G10B10A2_UNORM: STORE_SCANLINE( XMUDECN4, XMStoreUDecN4 ); case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM: #if DIRECTX_MATH_VERSION >= 306 STORE_SCANLINE( XMUDECN4, XMStoreUDecN4_XR ); #else if ( size >= sizeof(XMUDECN4) ) { static const XMVECTORF32 Scale = { 510.0f, 510.0f, 510.0f, 3.0f }; static const XMVECTORF32 Bias = { 384.0f, 384.0f, 384.0f, 0.0f }; static const XMVECTORF32 C = { 1023.f, 1023.f, 1023.f, 3.f }; XMUDECN4 * __restrict dPtr = reinterpret_cast(pDestination); for( size_t icount = 0; icount < ( size - sizeof(XMUDECN4) + 1 ); icount += sizeof(XMUDECN4) ) { if ( sPtr >= ePtr ) break; XMVECTOR N = XMVectorMultiplyAdd( *sPtr++, Scale, Bias ); N = XMVectorClamp( N, g_XMZero, C ); XMFLOAT4A tmp; XMStoreFloat4A(&tmp, N ); dPtr->v = ((uint32_t)tmp.w << 30) | (((uint32_t)tmp.z & 0x3FF) << 20) | (((uint32_t)tmp.y & 0x3FF) << 10) | (((uint32_t)tmp.x & 0x3FF)); ++dPtr; } return true; } return false; #endif case DXGI_FORMAT_R10G10B10A2_UINT: STORE_SCANLINE( XMUDEC4, XMStoreUDec4 ); case DXGI_FORMAT_R11G11B10_FLOAT: STORE_SCANLINE( XMFLOAT3PK, XMStoreFloat3PK ); case DXGI_FORMAT_R8G8B8A8_UNORM: case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: if ( size >= sizeof(XMUBYTEN4) ) { XMUBYTEN4 * __restrict dPtr = reinterpret_cast(pDestination); for( size_t icount = 0; icount < ( size - sizeof(XMUBYTEN4) + 1 ); icount += sizeof(XMUBYTEN4) ) { if ( sPtr >= ePtr ) break; XMVECTOR v = XMVectorAdd( *sPtr++, g_8BitBias ); XMStoreUByteN4( dPtr++, v ); } return true; } return false; case DXGI_FORMAT_R8G8B8A8_UINT: STORE_SCANLINE( XMUBYTE4, XMStoreUByte4 ) case DXGI_FORMAT_R8G8B8A8_SNORM: STORE_SCANLINE( XMBYTEN4, XMStoreByteN4 ) case DXGI_FORMAT_R8G8B8A8_SINT: STORE_SCANLINE( XMBYTE4, XMStoreByte4 ) case DXGI_FORMAT_R16G16_FLOAT: if ( size >= sizeof(XMHALF2) ) { XMHALF2* __restrict dPtr = reinterpret_cast(pDestination); for( size_t icount = 0; icount < ( size - sizeof(XMHALF2) + 1 ); icount += sizeof(XMHALF2) ) { if ( sPtr >= ePtr ) break; XMVECTOR v = *sPtr++; v = XMVectorClamp( v, g_HalfMin, g_HalfMax ); XMStoreHalf2( dPtr++, v ); } return true; } return false; case DXGI_FORMAT_R16G16_UNORM: STORE_SCANLINE( XMUSHORTN2, XMStoreUShortN2 ) case DXGI_FORMAT_R16G16_UINT: STORE_SCANLINE( XMUSHORT2, XMStoreUShort2 ) case DXGI_FORMAT_R16G16_SNORM: STORE_SCANLINE( XMSHORTN2, XMStoreShortN2 ) case DXGI_FORMAT_R16G16_SINT: STORE_SCANLINE( XMSHORT2, XMStoreShort2 ) case DXGI_FORMAT_D32_FLOAT: case DXGI_FORMAT_R32_FLOAT: if ( size >= sizeof(float) ) { float * __restrict dPtr = reinterpret_cast(pDestination); for( size_t icount = 0; icount < ( size - sizeof(float) + 1 ); icount += sizeof(float) ) { if ( sPtr >= ePtr ) break; XMStoreFloat( dPtr++, *(sPtr++) ); } return true; } return false; case DXGI_FORMAT_R32_UINT: if ( size >= sizeof(uint32_t) ) { uint32_t * __restrict dPtr = reinterpret_cast(pDestination); for( size_t icount = 0; icount < ( size - sizeof(uint32_t) + 1 ); icount += sizeof(uint32_t) ) { if ( sPtr >= ePtr ) break; XMVECTOR v = XMConvertVectorFloatToUInt( *(sPtr++), 0 ); XMStoreInt( dPtr++, v ); } return true; } return false; case DXGI_FORMAT_R32_SINT: if ( size >= sizeof(int32_t) ) { uint32_t * __restrict dPtr = reinterpret_cast(pDestination); for( size_t icount = 0; icount < ( size - sizeof(int32_t) + 1 ); icount += sizeof(int32_t) ) { if ( sPtr >= ePtr ) break; XMVECTOR v = XMConvertVectorFloatToInt( *(sPtr++), 0 ); XMStoreInt( dPtr++, v ); } return true; } return false; case DXGI_FORMAT_D24_UNORM_S8_UINT: if ( size >= sizeof(uint32_t) ) { static const XMVECTORF32 clamp = { 1.f, 255.f, 0.f, 0.f }; XMVECTOR zero = XMVectorZero(); uint32_t *dPtr = reinterpret_cast(pDestination); for( size_t icount = 0; icount < ( size - sizeof(uint32_t) + 1 ); icount += sizeof(uint32_t) ) { if ( sPtr >= ePtr ) break; XMFLOAT4 f; XMStoreFloat4( &f, XMVectorClamp( *sPtr++, zero, clamp ) ); *dPtr++ = (static_cast( f.x * 16777215.f ) & 0xFFFFFF) | ((static_cast( f.y ) & 0xFF) << 24); } return true; } return false; case DXGI_FORMAT_R8G8_UNORM: STORE_SCANLINE( XMUBYTEN2, XMStoreUByteN2 ) case DXGI_FORMAT_R8G8_UINT: STORE_SCANLINE( XMUBYTE2, XMStoreUByte2 ) case DXGI_FORMAT_R8G8_SNORM: STORE_SCANLINE( XMBYTEN2, XMStoreByteN2 ) case DXGI_FORMAT_R8G8_SINT: STORE_SCANLINE( XMBYTE2, XMStoreByte2 ) case DXGI_FORMAT_R16_FLOAT: if ( size >= sizeof(HALF) ) { HALF * __restrict dPtr = reinterpret_cast(pDestination); for( size_t icount = 0; icount < ( size - sizeof(HALF) + 1 ); icount += sizeof(HALF) ) { if ( sPtr >= ePtr ) break; float v = XMVectorGetX( *sPtr++ ); v = std::max( std::min( v, 65504.f ), -65504.f ); *(dPtr++) = XMConvertFloatToHalf(v); } return true; } return false; case DXGI_FORMAT_D16_UNORM: case DXGI_FORMAT_R16_UNORM: if ( size >= sizeof(uint16_t) ) { uint16_t * __restrict dPtr = reinterpret_cast(pDestination); for( size_t icount = 0; icount < ( size - sizeof(uint16_t) + 1 ); icount += sizeof(uint16_t) ) { if ( sPtr >= ePtr ) break; float v = XMVectorGetX( *sPtr++ ); v = std::max( std::min( v, 1.f ), 0.f ); *(dPtr++) = static_cast( v*65535.f + 0.5f ); } return true; } return false; case DXGI_FORMAT_R16_UINT: if ( size >= sizeof(uint16_t) ) { uint16_t * __restrict dPtr = reinterpret_cast(pDestination); for( size_t icount = 0; icount < ( size - sizeof(uint16_t) + 1 ); icount += sizeof(uint16_t) ) { if ( sPtr >= ePtr ) break; float v = XMVectorGetX( *sPtr++ ); v = std::max( std::min( v, 65535.f ), 0.f ); *(dPtr++) = static_cast(v); } return true; } return false; case DXGI_FORMAT_R16_SNORM: if ( size >= sizeof(int16_t) ) { int16_t * __restrict dPtr = reinterpret_cast(pDestination); for( size_t icount = 0; icount < ( size - sizeof(int16_t) + 1 ); icount += sizeof(int16_t) ) { if ( sPtr >= ePtr ) break; float v = XMVectorGetX( *sPtr++ ); v = std::max( std::min( v, 1.f ), -1.f ); *(dPtr++) = static_cast( v * 32767.f ); } return true; } return false; case DXGI_FORMAT_R16_SINT: if ( size >= sizeof(int16_t) ) { int16_t * __restrict dPtr = reinterpret_cast(pDestination); for( size_t icount = 0; icount < ( size - sizeof(int16_t) + 1 ); icount += sizeof(int16_t) ) { if ( sPtr >= ePtr ) break; float v = XMVectorGetX( *sPtr++ ); v = std::max( std::min( v, 32767.f ), -32767.f ); *(dPtr++) = static_cast(v); } return true; } return false; case DXGI_FORMAT_R8_UNORM: if ( size >= sizeof(uint8_t) ) { uint8_t * __restrict dPtr = reinterpret_cast(pDestination); for( size_t icount = 0; icount < size; icount += sizeof(uint8_t) ) { if ( sPtr >= ePtr ) break; float v = XMVectorGetX( *sPtr++ ); v = std::max( std::min( v, 1.f ), 0.f ); *(dPtr++) = static_cast( v * 255.f ); } return true; } return false; case DXGI_FORMAT_R8_UINT: if ( size >= sizeof(uint8_t) ) { uint8_t * __restrict dPtr = reinterpret_cast(pDestination); for( size_t icount = 0; icount < size; icount += sizeof(uint8_t) ) { if ( sPtr >= ePtr ) break; float v = XMVectorGetX( *sPtr++ ); v = std::max( std::min( v, 255.f ), 0.f ); *(dPtr++) = static_cast(v); } return true; } return false; case DXGI_FORMAT_R8_SNORM: if ( size >= sizeof(int8_t) ) { int8_t * __restrict dPtr = reinterpret_cast(pDestination); for( size_t icount = 0; icount < size; icount += sizeof(int8_t) ) { if ( sPtr >= ePtr ) break; float v = XMVectorGetX( *sPtr++ ); v = std::max( std::min( v, 1.f ), -1.f ); *(dPtr++) = static_cast( v * 127.f ); } return true; } return false; case DXGI_FORMAT_R8_SINT: if ( size >= sizeof(int8_t) ) { int8_t * __restrict dPtr = reinterpret_cast(pDestination); for( size_t icount = 0; icount < size; icount += sizeof(int8_t) ) { if ( sPtr >= ePtr ) break; float v = XMVectorGetX( *sPtr++ ); v = std::max( std::min( v, 127.f ), -127.f ); *(dPtr++) = static_cast( v ); } return true; } return false; case DXGI_FORMAT_A8_UNORM: if ( size >= sizeof(uint8_t) ) { uint8_t * __restrict dPtr = reinterpret_cast(pDestination); for( size_t icount = 0; icount < size; icount += sizeof(uint8_t) ) { if ( sPtr >= ePtr ) break; float v = XMVectorGetW( *sPtr++ ); v = std::max( std::min( v, 1.f ), 0.f ); *(dPtr++) = static_cast( v * 255.f); } return true; } return false; case DXGI_FORMAT_R1_UNORM: if ( size >= sizeof(uint8_t) ) { uint8_t * __restrict dPtr = reinterpret_cast(pDestination); for( size_t icount = 0; icount < size; icount += sizeof(uint8_t) ) { uint8_t pixels = 0; for( size_t bcount = 8; bcount > 0; --bcount ) { if ( sPtr >= ePtr ) break; float v = XMVectorGetX( *sPtr++ ); // Absolute thresholding generally doesn't give good results for all images // Picking the 'right' threshold automatically requires whole-image analysis if ( v > 0.25f ) pixels |= 1 << (bcount-1); } *(dPtr++) = pixels; } return true; } return false; case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: #if DIRECTX_MATH_VERSION >= 306 STORE_SCANLINE( XMFLOAT3SE, XMStoreFloat3SE ) #else if ( size >= sizeof(XMFLOAT3SE) ) { static const float maxf9 = float(0x1FF << 7); static const float minf9 = float(1.f / (1 << 16)); XMFLOAT3SE * __restrict dPtr = reinterpret_cast(pDestination); for( size_t icount = 0; icount < ( size - sizeof(XMFLOAT3SE) + 1 ); icount += sizeof(XMFLOAT3SE) ) { if ( sPtr >= ePtr ) break; XMFLOAT3 rgb; XMStoreFloat3( &rgb, *(sPtr++) ); float r = (rgb.x >= 0.f) ? ( (rgb.x > maxf9) ? maxf9 : rgb.x ) : 0.f; float g = (rgb.y >= 0.f) ? ( (rgb.y > maxf9) ? maxf9 : rgb.y ) : 0.f; float b = (rgb.z >= 0.f) ? ( (rgb.z > maxf9) ? maxf9 : rgb.z ) : 0.f; const float max_rg = (r > g) ? r : g; const float max_rgb = (max_rg > b) ? max_rg : b; const float maxColor = (max_rgb > minf9) ? max_rgb : minf9; union { float f; INT32 i; } fi; fi.f = maxColor; fi.i &= 0xFF800000; // cut off fraction dPtr->e = (fi.i - 0x37800000) >> 23; fi.i = 0x83000000 - fi.i; float ScaleR = fi.f; dPtr->xm = static_cast( round_to_nearest(r * ScaleR) ); dPtr->ym = static_cast( round_to_nearest(g * ScaleR) ); dPtr->zm = static_cast( round_to_nearest(b * ScaleR) ); ++dPtr; } return true; } return false; #endif case DXGI_FORMAT_R8G8_B8G8_UNORM: if ( size >= sizeof(XMUBYTEN4) ) { XMUBYTEN4 * __restrict dPtr = reinterpret_cast(pDestination); for( size_t icount = 0; icount < ( size - sizeof(XMUBYTEN4) + 1 ); icount += sizeof(XMUBYTEN4) ) { if ( sPtr >= ePtr ) break; XMVECTOR v0 = *sPtr++; XMVECTOR v1 = (sPtr < ePtr) ? XMVectorSplatY( *sPtr++ ) : XMVectorZero(); XMVECTOR v = XMVectorSelect( v1, v0, g_XMSelect1110 ); v = XMVectorAdd( v, g_8BitBias ); XMStoreUByteN4( dPtr++, v ); } return true; } return false; case DXGI_FORMAT_G8R8_G8B8_UNORM: if ( size >= sizeof(XMUBYTEN4) ) { static XMVECTORU32 select1101 = {XM_SELECT_1, XM_SELECT_1, XM_SELECT_0, XM_SELECT_1}; XMUBYTEN4 * __restrict dPtr = reinterpret_cast(pDestination); for( size_t icount = 0; icount < ( size - sizeof(XMUBYTEN4) + 1 ); icount += sizeof(XMUBYTEN4) ) { if ( sPtr >= ePtr ) break; XMVECTOR v0 = XMVectorSwizzle<1, 0, 3, 2>( *sPtr++ ); XMVECTOR v1 = (sPtr < ePtr) ? XMVectorSplatY( *sPtr++ ) : XMVectorZero(); XMVECTOR v = XMVectorSelect( v1, v0, select1101 ); v = XMVectorAdd( v, g_8BitBias ); XMStoreUByteN4( dPtr++, v ); } return true; } return false; case DXGI_FORMAT_B5G6R5_UNORM: if ( size >= sizeof(XMU565) ) { static const XMVECTORF32 s_Scale = { 31.f, 63.f, 31.f, 1.f }; XMU565 * __restrict dPtr = reinterpret_cast(pDestination); for( size_t icount = 0; icount < ( size - sizeof(XMU565) + 1 ); icount += sizeof(XMU565) ) { if ( sPtr >= ePtr ) break; XMVECTOR v = XMVectorSwizzle<2, 1, 0, 3>( *sPtr++ ); v = XMVectorMultiply( v, s_Scale ); XMStoreU565( dPtr++, v ); } return true; } return false; case DXGI_FORMAT_B5G5R5A1_UNORM: if ( size >= sizeof(XMU555) ) { static const XMVECTORF32 s_Scale = { 31.f, 31.f, 31.f, 1.f }; XMU555 * __restrict dPtr = reinterpret_cast(pDestination); for( size_t icount = 0; icount < ( size - sizeof(XMU555) + 1 ); icount += sizeof(XMU555) ) { if ( sPtr >= ePtr ) break; XMVECTOR v = XMVectorSwizzle<2, 1, 0, 3>( *sPtr++ ); v = XMVectorMultiply( v, s_Scale ); XMStoreU555( dPtr, v ); dPtr->w = ( XMVectorGetW( v ) > threshold ) ? 1 : 0; ++dPtr; } return true; } return false; case DXGI_FORMAT_B8G8R8A8_UNORM: case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: if ( size >= sizeof(XMUBYTEN4) ) { XMUBYTEN4 * __restrict dPtr = reinterpret_cast(pDestination); for( size_t icount = 0; icount < ( size - sizeof(XMUBYTEN4) + 1 ); icount += sizeof(XMUBYTEN4) ) { if ( sPtr >= ePtr ) break; XMVECTOR v = XMVectorSwizzle<2, 1, 0, 3>( *sPtr++ ); v = XMVectorAdd( v, g_8BitBias ); XMStoreUByteN4( dPtr++, v ); } return true; } return false; case DXGI_FORMAT_B8G8R8X8_UNORM: case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: if ( size >= sizeof(XMUBYTEN4) ) { XMUBYTEN4 * __restrict dPtr = reinterpret_cast(pDestination); for( size_t icount = 0; icount < ( size - sizeof(XMUBYTEN4) + 1 ); icount += sizeof(XMUBYTEN4) ) { if ( sPtr >= ePtr ) break; XMVECTOR v = XMVectorPermute<2, 1, 0, 7>( *sPtr++, g_XMIdentityR3 ); v = XMVectorAdd( v, g_8BitBias ); XMStoreUByteN4( dPtr++, v ); } return true; } return false; case DXGI_FORMAT_AYUV: if ( size >= sizeof(XMUBYTEN4) ) { XMUBYTEN4 * __restrict dPtr = reinterpret_cast(pDestination); for( size_t icount = 0; icount < ( size - sizeof(XMUBYTEN4) + 1 ); icount += sizeof(XMUBYTEN4) ) { if ( sPtr >= ePtr ) break; XMUBYTEN4 rgba; XMStoreUByteN4( &rgba, *sPtr++ ); // http://msdn.microsoft.com/en-us/library/windows/desktop/dd206750.aspx // Y = 0.2568R + 0.5041G + 0.1001B + 16 // Cb = -0.1482R - 0.2910G + 0.4392B + 128 // Cr = 0.4392R - 0.3678G - 0.0714B + 128 int y = ( ( 66 * rgba.x + 129 * rgba.y + 25 * rgba.z + 128) >> 8) + 16; int u = ( ( -38 * rgba.x - 74 * rgba.y + 112 * rgba.z + 128) >> 8) + 128; int v = ( ( 112 * rgba.x - 94 * rgba.y - 18 * rgba.z + 128) >> 8) + 128; dPtr->x = static_cast( std::min( std::max( v, 0 ), 255 ) ); dPtr->y = static_cast( std::min( std::max( u, 0 ), 255 ) ); dPtr->z = static_cast( std::min( std::max( y, 0 ), 255 ) ); dPtr->w = rgba.w; ++dPtr; } return true; } return false; case DXGI_FORMAT_Y410: if ( size >= sizeof(XMUDECN4) ) { XMUDECN4 * __restrict dPtr = reinterpret_cast(pDestination); for( size_t icount = 0; icount < ( size - sizeof(XMUDECN4) + 1 ); icount += sizeof(XMUDECN4) ) { if ( sPtr >= ePtr ) break; XMUDECN4 rgba; XMStoreUDecN4( &rgba, *sPtr++ ); // http://msdn.microsoft.com/en-us/library/windows/desktop/bb970578.aspx // Y = 0.2560R + 0.5027G + 0.0998B + 64 // Cb = -0.1478R - 0.2902G + 0.4379B + 512 // Cr = 0.4379R - 0.3667G - 0.0712B + 512 int64_t r = rgba.x; int64_t g = rgba.y; int64_t b = rgba.z; int y = static_cast( ( 16780 * r + 32942 * g + 6544 * b + 32768) >> 16) + 64; int u = static_cast( ( -9683 * r - 19017 * g + 28700 * b + 32768) >> 16) + 512; int v = static_cast( ( 28700 * r - 24033 * g - 4667 * b + 32768) >> 16) + 512; dPtr->x = static_cast( std::min( std::max( u, 0 ), 1023 ) ); dPtr->y = static_cast( std::min( std::max( y, 0 ), 1023 ) ); dPtr->z = static_cast( std::min( std::max( v, 0 ), 1023 ) ); dPtr->w = rgba.w; ++dPtr; } return true; } return false; case DXGI_FORMAT_Y416: if ( size >= sizeof(XMUSHORTN4) ) { XMUSHORTN4 * __restrict dPtr = reinterpret_cast(pDestination); for( size_t icount = 0; icount < ( size - sizeof(XMUSHORTN4) + 1 ); icount += sizeof(XMUSHORTN4) ) { if ( sPtr >= ePtr ) break; XMUSHORTN4 rgba; XMStoreUShortN4( &rgba, *sPtr++ ); // http://msdn.microsoft.com/en-us/library/windows/desktop/bb970578.aspx // Y = 0.2558R + 0.5022G + 0.0998B + 4096 // Cb = -0.1476R - 0.2899G + 0.4375B + 32768 // Cr = 0.4375R - 0.3664G - 0.0711B + 32768 int64_t r = int64_t(rgba.x); int64_t g = int64_t(rgba.y); int64_t b = int64_t(rgba.z); int y = static_cast( ( 16763 * r + 32910 * g + 6537 * b + 32768) >> 16) + 4096; int u = static_cast( ( -9674 * r - 18998 * g + 28672 * b + 32768) >> 16) + 32768; int v = static_cast( ( 28672 * r - 24010 * g - 4662 * b + 32768) >> 16) + 32768; dPtr->x = static_cast( std::min( std::max( u, 0 ), 65535 ) ); dPtr->y = static_cast( std::min( std::max( y, 0 ), 65535 ) ); dPtr->z = static_cast( std::min( std::max( v, 0 ), 65535 ) ); dPtr->w = rgba.w; ++dPtr; } return true; } return false; case DXGI_FORMAT_YUY2: if ( size >= sizeof(XMUBYTEN4) ) { XMUBYTEN4 * __restrict dPtr = reinterpret_cast(pDestination); for( size_t icount = 0; icount < ( size - sizeof(XMUBYTEN4) + 1 ); icount += sizeof(XMUBYTEN4) ) { if ( sPtr >= ePtr ) break; XMUBYTEN4 rgb1; XMStoreUByteN4( &rgb1, *sPtr++ ); // See AYUV int y0 = ( ( 66 * rgb1.x + 129 * rgb1.y + 25 * rgb1.z + 128) >> 8) + 16; int u0 = ( ( -38 * rgb1.x - 74 * rgb1.y + 112 * rgb1.z + 128) >> 8) + 128; int v0 = ( ( 112 * rgb1.x - 94 * rgb1.y - 18 * rgb1.z + 128) >> 8) + 128; XMUBYTEN4 rgb2; if(sPtr < ePtr) { XMStoreUByteN4( &rgb2, *sPtr++ ); } else { rgb2.x = rgb2.y = rgb2.z = rgb2.w = 0; } int y1 = ( ( 66 * rgb2.x + 129 * rgb2.y + 25 * rgb2.z + 128) >> 8) + 16; int u1 = ( ( -38 * rgb2.x - 74 * rgb2.y + 112 * rgb2.z + 128) >> 8) + 128; int v1 = ( ( 112 * rgb2.x - 94 * rgb2.y - 18 * rgb2.z + 128) >> 8) + 128; dPtr->x = static_cast( std::min( std::max( y0, 0 ), 255 ) ); dPtr->y = static_cast( std::min( std::max( (u0 + u1) >> 1, 0 ), 255 ) ); dPtr->z = static_cast( std::min( std::max( y1, 0 ), 255 ) ); dPtr->w = static_cast( std::min( std::max( (v0 + v1) >> 1, 0 ), 255 ) ); ++dPtr; } return true; } return false; case DXGI_FORMAT_Y210: // Same as Y216 with least significant 6 bits set to zero if ( size >= sizeof(XMUSHORTN4) ) { XMUSHORTN4 * __restrict dPtr = reinterpret_cast(pDestination); for( size_t icount = 0; icount < ( size - sizeof(XMUSHORTN4) + 1 ); icount += sizeof(XMUSHORTN4) ) { if ( sPtr >= ePtr ) break; XMUDECN4 rgb1; XMStoreUDecN4( &rgb1, *sPtr++ ); // See Y410 int64_t r = rgb1.x; int64_t g = rgb1.y; int64_t b = rgb1.z; int y0 = static_cast( ( 16780 * r + 32942 * g + 6544 * b + 32768) >> 16) + 64; int u0 = static_cast( ( -9683 * r - 19017 * g + 28700 * b + 32768) >> 16) + 512; int v0 = static_cast( ( 28700 * r - 24033 * g - 4667 * b + 32768) >> 16) + 512; XMUDECN4 rgb2; if(sPtr < ePtr) { XMStoreUDecN4( &rgb2, *sPtr++ ); } else { rgb2.x = rgb2.y = rgb2.z = rgb2.w = 0; } r = rgb2.x; g = rgb2.y; b = rgb2.z; int y1 = static_cast( ( 16780 * r + 32942 * g + 6544 * b + 32768) >> 16) + 64; int u1 = static_cast( ( -9683 * r - 19017 * g + 28700 * b + 32768) >> 16) + 512; int v1 = static_cast( ( 28700 * r - 24033 * g - 4667 * b + 32768) >> 16) + 512; dPtr->x = static_cast( std::min( std::max( y0, 0 ), 1023 ) << 6 ); dPtr->y = static_cast( std::min( std::max( (u0 + u1) >> 1, 0 ), 1023 ) << 6 ); dPtr->z = static_cast( std::min( std::max( y1, 0 ), 1023 ) << 6 ); dPtr->w = static_cast( std::min( std::max( (v0 + v1) >> 1, 0 ), 1023 ) << 6 ); ++dPtr; } return true; } return false; case DXGI_FORMAT_Y216: if ( size >= sizeof(XMUSHORTN4) ) { XMUSHORTN4 * __restrict dPtr = reinterpret_cast(pDestination); for( size_t icount = 0; icount < ( size - sizeof(XMUSHORTN4) + 1 ); icount += sizeof(XMUSHORTN4) ) { if ( sPtr >= ePtr ) break; XMUSHORTN4 rgb1; XMStoreUShortN4( &rgb1, *sPtr++ ); // See Y416 int64_t r = int64_t(rgb1.x); int64_t g = int64_t(rgb1.y); int64_t b = int64_t(rgb1.z); int y0 = static_cast( ( 16763 * r + 32910 * g + 6537 * b + 32768) >> 16) + 4096; int u0 = static_cast( (-9674 * r - 18998 * g + 28672 * b + 32768) >> 16) + 32768; int v0 = static_cast( ( 28672 * r - 24010 * g - 4662 * b + 32768) >> 16) + 32768; XMUSHORTN4 rgb2; if(sPtr < ePtr) { XMStoreUShortN4( &rgb2, *sPtr++ ); } else { rgb2.x = rgb2.y = rgb2.z = rgb2.w = 0; } r = int64_t(rgb2.x); g = int64_t(rgb2.y); b = int64_t(rgb2.z); int y1 = static_cast( ( 16763 * r + 32910 * g + 6537 * b + 32768) >> 16) + 4096; int u1 = static_cast( (-9674 * r - 18998 * g + 28672 * b + 32768) >> 16) + 32768; int v1 = static_cast( ( 28672 * r - 24010 * g - 4662 * b + 32768) >> 16) + 32768; dPtr->x = static_cast( std::min( std::max( y0, 0 ), 65535 ) ); dPtr->y = static_cast( std::min( std::max( (u0 + u1) >> 1, 0 ), 65535 ) ); dPtr->z = static_cast( std::min( std::max( y1, 0 ), 65535 ) ); dPtr->w = static_cast( std::min( std::max( (v0 + v1) >> 1, 0 ), 65535 ) ); ++dPtr; } return true; } return false; case DXGI_FORMAT_B4G4R4A4_UNORM: if ( size >= sizeof(XMUNIBBLE4) ) { static const XMVECTORF32 s_Scale = { 15.f, 15.f, 15.f, 15.f }; XMUNIBBLE4 * __restrict dPtr = reinterpret_cast(pDestination); for( size_t icount = 0; icount < ( size - sizeof(XMUNIBBLE4) + 1 ); icount += sizeof(XMUNIBBLE4) ) { if ( sPtr >= ePtr ) break; XMVECTOR v = XMVectorSwizzle<2, 1, 0, 3>( *sPtr++ ); v = XMVectorMultiply( v, s_Scale ); XMStoreUNibble4( dPtr++, v ); } return true; } return false; case 116 /* DXGI_FORMAT_R10G10B10_7E3_A2_FLOAT */: // Xbox One specific 7e3 format with alpha if ( size >= sizeof(XMUDECN4) ) { static const XMVECTORF32 Scale = { 1.0f, 1.0f, 1.0f, 3.0f }; static const XMVECTORF32 C = { 31.875f, 31.875f, 31.875f, 3.f }; XMUDECN4 * __restrict dPtr = reinterpret_cast(pDestination); for( size_t icount = 0; icount < ( size - sizeof(XMUDECN4) + 1 ); icount += sizeof(XMUDECN4) ) { if ( sPtr >= ePtr ) break; XMVECTOR V = XMVectorMultiply( *sPtr++, Scale ); V = XMVectorClamp( V, g_XMZero, C ); XMFLOAT4A tmp; XMStoreFloat4A( &tmp, V ); dPtr->x = FloatTo7e3( tmp.x ); dPtr->y = FloatTo7e3( tmp.y ); dPtr->z = FloatTo7e3( tmp.z ); dPtr->w = (uint32_t)tmp.w; ++dPtr; } return true; } return false; case 117 /* DXGI_FORMAT_R10G10B10_6E4_A2_FLOAT */: // Xbox One specific 6e4 format with alpha if ( size >= sizeof(XMUDECN4) ) { static const XMVECTORF32 Scale = { 1.0f, 1.0f, 1.0f, 3.0f }; static const XMVECTORF32 C = { 508.f, 508.f, 508.f, 3.f }; XMUDECN4 * __restrict dPtr = reinterpret_cast(pDestination); for( size_t icount = 0; icount < ( size - sizeof(XMUDECN4) + 1 ); icount += sizeof(XMUDECN4) ) { if ( sPtr >= ePtr ) break; XMVECTOR V = XMVectorMultiply( *sPtr++, Scale ); V = XMVectorClamp( V, g_XMZero, C ); XMFLOAT4A tmp; XMStoreFloat4A( &tmp, V ); dPtr->x = FloatTo6e4( tmp.x ); dPtr->y = FloatTo6e4( tmp.y ); dPtr->z = FloatTo6e4( tmp.z ); dPtr->w = (uint32_t)tmp.w; ++dPtr; } return true; } return false; // We don't support the planar or palettized formats default: return false; } } #undef STORE_SCANLINE //------------------------------------------------------------------------------------- // Convert DXGI image to/from GUID_WICPixelFormat128bppRGBAFloat (no range conversions) //------------------------------------------------------------------------------------- _Use_decl_annotations_ HRESULT _ConvertToR32G32B32A32( const Image& srcImage, ScratchImage& image ) { if ( !srcImage.pixels ) return E_POINTER; HRESULT hr = image.Initialize2D( DXGI_FORMAT_R32G32B32A32_FLOAT, srcImage.width, srcImage.height, 1, 1 ); if ( FAILED(hr) ) return hr; const Image *img = image.GetImage( 0, 0, 0 ); if ( !img ) { image.Release(); return E_POINTER; } uint8_t* pDest = img->pixels; if ( !pDest ) { image.Release(); return E_POINTER; } const uint8_t *pSrc = srcImage.pixels; for( size_t h = 0; h < srcImage.height; ++h ) { if ( !_LoadScanline( reinterpret_cast(pDest), srcImage.width, pSrc, srcImage.rowPitch, srcImage.format ) ) { image.Release(); return E_FAIL; } pSrc += srcImage.rowPitch; pDest += img->rowPitch; } return S_OK; } _Use_decl_annotations_ HRESULT _ConvertFromR32G32B32A32( const Image& srcImage, const Image& destImage ) { assert( srcImage.format == DXGI_FORMAT_R32G32B32A32_FLOAT ); if ( !srcImage.pixels || !destImage.pixels ) return E_POINTER; if ( srcImage.width != destImage.width || srcImage.height != destImage.height ) return E_FAIL; const uint8_t *pSrc = srcImage.pixels; uint8_t* pDest = destImage.pixels; for( size_t h = 0; h < srcImage.height; ++h ) { if ( !_StoreScanline( pDest, destImage.rowPitch, destImage.format, reinterpret_cast(pSrc), srcImage.width ) ) return E_FAIL; pSrc += srcImage.rowPitch; pDest += destImage.rowPitch; } return S_OK; } _Use_decl_annotations_ HRESULT _ConvertFromR32G32B32A32( const Image& srcImage, DXGI_FORMAT format, ScratchImage& image ) { if ( !srcImage.pixels ) return E_POINTER; HRESULT hr = image.Initialize2D( format, srcImage.width, srcImage.height, 1, 1 ); if ( FAILED(hr) ) return hr; const Image *img = image.GetImage( 0, 0, 0 ); if ( !img ) { image.Release(); return E_POINTER; } hr = _ConvertFromR32G32B32A32( srcImage, *img ); if ( FAILED(hr) ) { image.Release(); return hr; } return S_OK; } _Use_decl_annotations_ HRESULT _ConvertFromR32G32B32A32( const Image* srcImages, size_t nimages, const TexMetadata& metadata, DXGI_FORMAT format, ScratchImage& result ) { if ( !srcImages ) return E_POINTER; result.Release(); assert( metadata.format == DXGI_FORMAT_R32G32B32A32_FLOAT ); TexMetadata mdata2 = metadata; mdata2.format = format; HRESULT hr = result.Initialize( mdata2 ); if ( FAILED(hr) ) return hr; if ( nimages != result.GetImageCount() ) { result.Release(); return E_FAIL; } const Image* dest = result.GetImages(); if ( !dest ) { result.Release(); return E_POINTER; } for( size_t index=0; index < nimages; ++index ) { const Image& src = srcImages[ index ]; const Image& dst = dest[ index ]; assert( src.format == DXGI_FORMAT_R32G32B32A32_FLOAT ); assert( dst.format == format ); if ( src.width != dst.width || src.height != dst.height ) { result.Release(); return E_FAIL; } const uint8_t* pSrc = src.pixels; uint8_t* pDest = dst.pixels; if ( !pSrc || !pDest ) { result.Release(); return E_POINTER; } for( size_t h=0; h < src.height; ++h ) { if ( !_StoreScanline( pDest, dst.rowPitch, format, reinterpret_cast(pSrc), src.width ) ) { result.Release(); return E_FAIL; } pSrc += src.rowPitch; pDest += dst.rowPitch; } } return S_OK; } //------------------------------------------------------------------------------------- // Convert from Linear RGB to sRGB // // if C_linear <= 0.0031308 -> C_srgb = 12.92 * C_linear // if C_linear > 0.0031308 -> C_srgb = ( 1 + a ) * pow( C_Linear, 1 / 2.4 ) - a // where a = 0.055 //------------------------------------------------------------------------------------- #if DIRECTX_MATH_VERSION < 306 static inline XMVECTOR XMColorRGBToSRGB( FXMVECTOR rgb ) { static const XMVECTORF32 Cutoff = { 0.0031308f, 0.0031308f, 0.0031308f, 1.f }; static const XMVECTORF32 Linear = { 12.92f, 12.92f, 12.92f, 1.f }; static const XMVECTORF32 Scale = { 1.055f, 1.055f, 1.055f, 1.f }; static const XMVECTORF32 Bias = { 0.055f, 0.055f, 0.055f, 0.f }; static const XMVECTORF32 InvGamma = { 1.0f/2.4f, 1.0f/2.4f, 1.0f/2.4f, 1.f }; XMVECTOR V = XMVectorSaturate(rgb); XMVECTOR V0 = XMVectorMultiply( V, Linear ); XMVECTOR V1 = Scale * XMVectorPow( V, InvGamma ) - Bias; XMVECTOR select = XMVectorLess( V, Cutoff ); V = XMVectorSelect( V1, V0, select ); return XMVectorSelect( rgb, V, g_XMSelect1110 ); } #endif _Use_decl_annotations_ bool _StoreScanlineLinear( LPVOID pDestination, size_t size, DXGI_FORMAT format, XMVECTOR* pSource, size_t count, DWORD flags, float threshold ) { assert( pDestination && size > 0 ); assert( pSource && count > 0 && (((uintptr_t)pSource & 0xF) == 0) ); assert( IsValid(format) && !IsTypeless(format) && !IsCompressed(format) && !IsPlanar(format) && !IsPalettized(format) ); switch ( format ) { case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: flags |= TEX_FILTER_SRGB; break; case DXGI_FORMAT_R32G32B32A32_FLOAT: case DXGI_FORMAT_R32G32B32_FLOAT: case DXGI_FORMAT_R16G16B16A16_FLOAT: case DXGI_FORMAT_R16G16B16A16_UNORM: case DXGI_FORMAT_R32G32_FLOAT: case DXGI_FORMAT_R10G10B10A2_UNORM: case DXGI_FORMAT_R11G11B10_FLOAT: case DXGI_FORMAT_R8G8B8A8_UNORM: case DXGI_FORMAT_R16G16_FLOAT: case DXGI_FORMAT_R16G16_UNORM: case DXGI_FORMAT_R32_FLOAT: case DXGI_FORMAT_R8G8_UNORM: case DXGI_FORMAT_R16_FLOAT: case DXGI_FORMAT_R16_UNORM: case DXGI_FORMAT_R8_UNORM: case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: case DXGI_FORMAT_R8G8_B8G8_UNORM: case DXGI_FORMAT_G8R8_G8B8_UNORM: case DXGI_FORMAT_B5G6R5_UNORM: case DXGI_FORMAT_B5G5R5A1_UNORM: case DXGI_FORMAT_B8G8R8A8_UNORM: case DXGI_FORMAT_B8G8R8X8_UNORM: case DXGI_FORMAT_B4G4R4A4_UNORM: break; default: // can't treat A8, XR, Depth, SNORM, UINT, or SINT as sRGB flags &= ~TEX_FILTER_SRGB; break; } // sRGB output processing (Linear RGB -> sRGB) if ( flags & TEX_FILTER_SRGB_OUT ) { // To avoid the need for another temporary scanline buffer, we allow this function to overwrite the source buffer in-place // Given the intended usage in the filtering routines, this is not a problem. XMVECTOR* ptr = pSource; for( size_t i=0; i < count; ++i, ++ptr ) { *ptr = XMColorRGBToSRGB( *ptr ); } } return _StoreScanline( pDestination, size, format, pSource, count, threshold ); } //------------------------------------------------------------------------------------- // Convert from sRGB to Linear RGB // // if C_srgb <= 0.04045 -> C_linear = C_srgb / 12.92 // if C_srgb > 0.04045 -> C_linear = pow( ( C_srgb + a ) / ( 1 + a ), 2.4 ) // where a = 0.055 //------------------------------------------------------------------------------------- #if DIRECTX_MATH_VERSION < 306 static inline XMVECTOR XMColorSRGBToRGB( FXMVECTOR srgb ) { static const XMVECTORF32 Cutoff = { 0.04045f, 0.04045f, 0.04045f, 1.f }; static const XMVECTORF32 ILinear = { 1.f/12.92f, 1.f/12.92f, 1.f/12.92f, 1.f }; static const XMVECTORF32 Scale = { 1.f/1.055f, 1.f/1.055f, 1.f/1.055f, 1.f }; static const XMVECTORF32 Bias = { 0.055f, 0.055f, 0.055f, 0.f }; static const XMVECTORF32 Gamma = { 2.4f, 2.4f, 2.4f, 1.f }; XMVECTOR V = XMVectorSaturate(srgb); XMVECTOR V0 = XMVectorMultiply( V, ILinear ); XMVECTOR V1 = XMVectorPow( (V + Bias) * Scale, Gamma ); XMVECTOR select = XMVectorGreater( V, Cutoff ); V = XMVectorSelect( V0, V1, select ); return XMVectorSelect( srgb, V, g_XMSelect1110 ); } #endif _Use_decl_annotations_ bool _LoadScanlineLinear( XMVECTOR* pDestination, size_t count, LPCVOID pSource, size_t size, DXGI_FORMAT format, DWORD flags ) { assert( pDestination && count > 0 && (((uintptr_t)pDestination & 0xF) == 0) ); assert( pSource && size > 0 ); assert( IsValid(format) && !IsTypeless(format,false) && !IsCompressed(format) && !IsPlanar(format) && !IsPalettized(format) ); switch ( format ) { case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: flags |= TEX_FILTER_SRGB; break; case DXGI_FORMAT_R32G32B32A32_FLOAT: case DXGI_FORMAT_R32G32B32_FLOAT: case DXGI_FORMAT_R16G16B16A16_FLOAT: case DXGI_FORMAT_R16G16B16A16_UNORM: case DXGI_FORMAT_R32G32_FLOAT: case DXGI_FORMAT_R10G10B10A2_UNORM: case DXGI_FORMAT_R11G11B10_FLOAT: case DXGI_FORMAT_R8G8B8A8_UNORM: case DXGI_FORMAT_R16G16_FLOAT: case DXGI_FORMAT_R16G16_UNORM: case DXGI_FORMAT_R32_FLOAT: case DXGI_FORMAT_R8G8_UNORM: case DXGI_FORMAT_R16_FLOAT: case DXGI_FORMAT_R16_UNORM: case DXGI_FORMAT_R8_UNORM: case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: case DXGI_FORMAT_R8G8_B8G8_UNORM: case DXGI_FORMAT_G8R8_G8B8_UNORM: case DXGI_FORMAT_B5G6R5_UNORM: case DXGI_FORMAT_B5G5R5A1_UNORM: case DXGI_FORMAT_B8G8R8A8_UNORM: case DXGI_FORMAT_B8G8R8X8_UNORM: case DXGI_FORMAT_B4G4R4A4_UNORM: break; default: // can't treat A8, XR, Depth, SNORM, UINT, or SINT as sRGB flags &= ~TEX_FILTER_SRGB; break; } if ( _LoadScanline( pDestination, count, pSource, size, format ) ) { // sRGB input processing (sRGB -> Linear RGB) if ( flags & TEX_FILTER_SRGB_IN ) { XMVECTOR* ptr = pDestination; for( size_t i=0; i < count; ++i, ++ptr ) { *ptr = XMColorSRGBToRGB( *ptr ); } } return true; } return false; } //------------------------------------------------------------------------------------- // Convert scanline based on source/target formats //------------------------------------------------------------------------------------- struct ConvertData { DXGI_FORMAT format; size_t datasize; DWORD flags; }; static const ConvertData g_ConvertTable[] = { { DXGI_FORMAT_R32G32B32A32_FLOAT, 32, CONVF_FLOAT | CONVF_R | CONVF_G | CONVF_B | CONVF_A }, { DXGI_FORMAT_R32G32B32A32_UINT, 32, CONVF_UINT | CONVF_R | CONVF_G | CONVF_B | CONVF_A }, { DXGI_FORMAT_R32G32B32A32_SINT, 32, CONVF_SINT | CONVF_R | CONVF_G | CONVF_B | CONVF_A }, { DXGI_FORMAT_R32G32B32_FLOAT, 32, CONVF_FLOAT | CONVF_R | CONVF_G | CONVF_B }, { DXGI_FORMAT_R32G32B32_UINT, 32, CONVF_UINT | CONVF_R | CONVF_G | CONVF_B }, { DXGI_FORMAT_R32G32B32_SINT, 32, CONVF_SINT | CONVF_R | CONVF_G | CONVF_B }, { DXGI_FORMAT_R16G16B16A16_FLOAT, 16, CONVF_FLOAT | CONVF_R | CONVF_G | CONVF_B | CONVF_A }, { DXGI_FORMAT_R16G16B16A16_UNORM, 16, CONVF_UNORM | CONVF_R | CONVF_G | CONVF_B | CONVF_A }, { DXGI_FORMAT_R16G16B16A16_UINT, 16, CONVF_UINT | CONVF_R | CONVF_G | CONVF_B | CONVF_A }, { DXGI_FORMAT_R16G16B16A16_SNORM, 16, CONVF_SNORM | CONVF_R | CONVF_G | CONVF_B | CONVF_A }, { DXGI_FORMAT_R16G16B16A16_SINT, 16, CONVF_SINT | CONVF_R | CONVF_G | CONVF_B | CONVF_A }, { DXGI_FORMAT_R32G32_FLOAT, 32, CONVF_FLOAT | CONVF_R | CONVF_G }, { DXGI_FORMAT_R32G32_UINT, 32, CONVF_UINT | CONVF_R | CONVF_G }, { DXGI_FORMAT_R32G32_SINT, 32, CONVF_SINT | CONVF_R | CONVF_G }, { DXGI_FORMAT_D32_FLOAT_S8X24_UINT, 32, CONVF_FLOAT | CONVF_DEPTH | CONVF_STENCIL }, { DXGI_FORMAT_R10G10B10A2_UNORM, 10, CONVF_UNORM | CONVF_R | CONVF_G | CONVF_B | CONVF_A }, { DXGI_FORMAT_R10G10B10A2_UINT, 10, CONVF_UINT | CONVF_R | CONVF_G | CONVF_B | CONVF_A }, { DXGI_FORMAT_R11G11B10_FLOAT, 10, CONVF_FLOAT | CONVF_R | CONVF_G | CONVF_B }, { DXGI_FORMAT_R8G8B8A8_UNORM, 8, CONVF_UNORM | CONVF_R | CONVF_G | CONVF_B | CONVF_A }, { DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, 8, CONVF_UNORM | CONVF_R | CONVF_G | CONVF_B | CONVF_A }, { DXGI_FORMAT_R8G8B8A8_UINT, 8, CONVF_UINT | CONVF_R | CONVF_G | CONVF_B | CONVF_A }, { DXGI_FORMAT_R8G8B8A8_SNORM, 8, CONVF_SNORM | CONVF_R | CONVF_G | CONVF_B | CONVF_A }, { DXGI_FORMAT_R8G8B8A8_SINT, 8, CONVF_SINT | CONVF_R | CONVF_G | CONVF_B | CONVF_A }, { DXGI_FORMAT_R16G16_FLOAT, 16, CONVF_FLOAT | CONVF_R | CONVF_G }, { DXGI_FORMAT_R16G16_UNORM, 16, CONVF_UNORM | CONVF_R | CONVF_G }, { DXGI_FORMAT_R16G16_UINT, 16, CONVF_UINT | CONVF_R | CONVF_G }, { DXGI_FORMAT_R16G16_SNORM, 16, CONVF_SNORM | CONVF_R | CONVF_G }, { DXGI_FORMAT_R16G16_SINT, 16, CONVF_SINT | CONVF_R | CONVF_G }, { DXGI_FORMAT_D32_FLOAT, 32, CONVF_FLOAT | CONVF_DEPTH }, { DXGI_FORMAT_R32_FLOAT, 32, CONVF_FLOAT | CONVF_R }, { DXGI_FORMAT_R32_UINT, 32, CONVF_UINT | CONVF_R }, { DXGI_FORMAT_R32_SINT, 32, CONVF_SINT | CONVF_R }, { DXGI_FORMAT_D24_UNORM_S8_UINT, 32, CONVF_UNORM | CONVF_DEPTH | CONVF_STENCIL }, { DXGI_FORMAT_R8G8_UNORM, 8, CONVF_UNORM | CONVF_R | CONVF_G }, { DXGI_FORMAT_R8G8_UINT, 8, CONVF_UINT | CONVF_R | CONVF_G }, { DXGI_FORMAT_R8G8_SNORM, 8, CONVF_SNORM | CONVF_R | CONVF_G }, { DXGI_FORMAT_R8G8_SINT, 8, CONVF_SINT | CONVF_R | CONVF_G }, { DXGI_FORMAT_R16_FLOAT, 16, CONVF_FLOAT | CONVF_R }, { DXGI_FORMAT_D16_UNORM, 16, CONVF_UNORM | CONVF_DEPTH }, { DXGI_FORMAT_R16_UNORM, 16, CONVF_UNORM | CONVF_R }, { DXGI_FORMAT_R16_UINT, 16, CONVF_UINT | CONVF_R }, { DXGI_FORMAT_R16_SNORM, 16, CONVF_SNORM | CONVF_R }, { DXGI_FORMAT_R16_SINT, 16, CONVF_SINT | CONVF_R }, { DXGI_FORMAT_R8_UNORM, 8, CONVF_UNORM | CONVF_R }, { DXGI_FORMAT_R8_UINT, 8, CONVF_UINT | CONVF_R }, { DXGI_FORMAT_R8_SNORM, 8, CONVF_SNORM | CONVF_R }, { DXGI_FORMAT_R8_SINT, 8, CONVF_SINT | CONVF_R }, { DXGI_FORMAT_A8_UNORM, 8, CONVF_UNORM | CONVF_A }, { DXGI_FORMAT_R1_UNORM, 1, CONVF_UNORM | CONVF_R }, { DXGI_FORMAT_R9G9B9E5_SHAREDEXP, 9, CONVF_SHAREDEXP | CONVF_R | CONVF_G | CONVF_B }, { DXGI_FORMAT_R8G8_B8G8_UNORM, 8, CONVF_UNORM | CONVF_PACKED | CONVF_R | CONVF_G | CONVF_B }, { DXGI_FORMAT_G8R8_G8B8_UNORM, 8, CONVF_UNORM | CONVF_PACKED | CONVF_R | CONVF_G | CONVF_B }, { DXGI_FORMAT_BC1_UNORM, 8, CONVF_UNORM | CONVF_BC | CONVF_R | CONVF_G | CONVF_B | CONVF_A }, { DXGI_FORMAT_BC1_UNORM_SRGB, 8, CONVF_UNORM | CONVF_BC | CONVF_R | CONVF_G | CONVF_B | CONVF_A }, { DXGI_FORMAT_BC2_UNORM, 8, CONVF_UNORM | CONVF_BC | CONVF_R | CONVF_G | CONVF_B | CONVF_A }, { DXGI_FORMAT_BC2_UNORM_SRGB, 8, CONVF_UNORM | CONVF_BC | CONVF_R | CONVF_G | CONVF_B | CONVF_A }, { DXGI_FORMAT_BC3_UNORM, 8, CONVF_UNORM | CONVF_BC | CONVF_R | CONVF_G | CONVF_B | CONVF_A }, { DXGI_FORMAT_BC3_UNORM_SRGB, 8, CONVF_UNORM | CONVF_BC | CONVF_R | CONVF_G | CONVF_B | CONVF_A }, { DXGI_FORMAT_BC4_UNORM, 8, CONVF_UNORM | CONVF_BC | CONVF_R }, { DXGI_FORMAT_BC4_SNORM, 8, CONVF_SNORM | CONVF_BC | CONVF_R }, { DXGI_FORMAT_BC5_UNORM, 8, CONVF_UNORM | CONVF_BC | CONVF_R | CONVF_G }, { DXGI_FORMAT_BC5_SNORM, 8, CONVF_SNORM | CONVF_BC | CONVF_R | CONVF_G }, { DXGI_FORMAT_B5G6R5_UNORM, 5, CONVF_UNORM | CONVF_R | CONVF_G | CONVF_B }, { DXGI_FORMAT_B5G5R5A1_UNORM, 5, CONVF_UNORM | CONVF_R | CONVF_G | CONVF_B | CONVF_A }, { DXGI_FORMAT_B8G8R8A8_UNORM, 8, CONVF_UNORM | CONVF_BGR | CONVF_R | CONVF_G | CONVF_B | CONVF_A }, { DXGI_FORMAT_B8G8R8X8_UNORM, 8, CONVF_UNORM | CONVF_BGR | CONVF_R | CONVF_G | CONVF_B }, { DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM, 10, CONVF_UNORM | CONVF_XR | CONVF_R | CONVF_G | CONVF_B | CONVF_A }, { DXGI_FORMAT_B8G8R8A8_UNORM_SRGB, 8, CONVF_UNORM | CONVF_BGR | CONVF_R | CONVF_G | CONVF_B | CONVF_A }, { DXGI_FORMAT_B8G8R8X8_UNORM_SRGB, 8, CONVF_UNORM | CONVF_BGR | CONVF_R | CONVF_G | CONVF_B }, { DXGI_FORMAT_BC6H_UF16, 16, CONVF_FLOAT | CONVF_BC | CONVF_R | CONVF_G | CONVF_B | CONVF_A }, { DXGI_FORMAT_BC6H_SF16, 16, CONVF_FLOAT | CONVF_BC | CONVF_R | CONVF_G | CONVF_B | CONVF_A }, { DXGI_FORMAT_BC7_UNORM, 8, CONVF_UNORM | CONVF_BC | CONVF_R | CONVF_G | CONVF_B | CONVF_A }, { DXGI_FORMAT_BC7_UNORM_SRGB, 8, CONVF_UNORM | CONVF_BC | CONVF_R | CONVF_G | CONVF_B | CONVF_A }, { DXGI_FORMAT_AYUV, 8, CONVF_UNORM | CONVF_YUV | CONVF_R | CONVF_G | CONVF_B | CONVF_A }, { DXGI_FORMAT_Y410, 10, CONVF_UNORM | CONVF_YUV | CONVF_R | CONVF_G | CONVF_B | CONVF_A }, { DXGI_FORMAT_Y416, 16, CONVF_UNORM | CONVF_YUV | CONVF_R | CONVF_G | CONVF_B | CONVF_A }, { DXGI_FORMAT_YUY2, 8, CONVF_UNORM | CONVF_YUV | CONVF_PACKED | CONVF_R | CONVF_G | CONVF_B }, { DXGI_FORMAT_Y210, 10, CONVF_UNORM | CONVF_YUV | CONVF_PACKED | CONVF_R | CONVF_G | CONVF_B }, { DXGI_FORMAT_Y216, 16, CONVF_UNORM | CONVF_YUV | CONVF_PACKED | CONVF_R | CONVF_G | CONVF_B }, { DXGI_FORMAT_B4G4R4A4_UNORM, 4, CONVF_UNORM | CONVF_BGR | CONVF_R | CONVF_G | CONVF_B | CONVF_A }, { DXGI_FORMAT(116) /* DXGI_FORMAT_R10G10B10_7E3_A2_FLOAT */, 10, CONVF_FLOAT | CONVF_R | CONVF_G | CONVF_B | CONVF_A }, { DXGI_FORMAT(117) /* DXGI_FORMAT_R10G10B10_6E4_A2_FLOAT */, 10, CONVF_FLOAT | CONVF_R | CONVF_G | CONVF_B | CONVF_A }, }; #pragma prefast( suppress : 25004, "Signature must match bsearch_s" ); static int __cdecl _ConvertCompare( void *context, const void* ptr1, const void *ptr2 ) { UNREFERENCED_PARAMETER(context); const ConvertData *p1 = reinterpret_cast(ptr1); const ConvertData *p2 = reinterpret_cast(ptr2); if ( p1->format == p2->format ) return 0; else return (p1->format < p2->format ) ? -1 : 1; } _Use_decl_annotations_ DWORD _GetConvertFlags( DXGI_FORMAT format ) { #ifdef _DEBUG // Ensure conversion table is in ascending order assert( _countof(g_ConvertTable) > 0 ); DXGI_FORMAT lastvalue = g_ConvertTable[0].format; for( size_t index=1; index < _countof(g_ConvertTable); ++index ) { assert( g_ConvertTable[index].format > lastvalue ); lastvalue = g_ConvertTable[index].format; } #endif ConvertData key = { format, 0 }; const ConvertData* in = (const ConvertData*) bsearch_s( &key, g_ConvertTable, _countof(g_ConvertTable), sizeof(ConvertData), _ConvertCompare, 0 ); return (in) ? in->flags : 0; } _Use_decl_annotations_ void _ConvertScanline( XMVECTOR* pBuffer, size_t count, DXGI_FORMAT outFormat, DXGI_FORMAT inFormat, DWORD flags ) { assert( pBuffer && count > 0 && (((uintptr_t)pBuffer & 0xF) == 0) ); assert( IsValid(outFormat) && !IsTypeless(outFormat) && !IsPlanar(outFormat) && !IsPalettized(outFormat) ); assert( IsValid(inFormat) && !IsTypeless(inFormat) && !IsPlanar(inFormat) && !IsPalettized(inFormat) ); if ( !pBuffer ) return; #ifdef _DEBUG // Ensure conversion table is in ascending order assert( _countof(g_ConvertTable) > 0 ); DXGI_FORMAT lastvalue = g_ConvertTable[0].format; for( size_t index=1; index < _countof(g_ConvertTable); ++index ) { assert( g_ConvertTable[index].format > lastvalue ); lastvalue = g_ConvertTable[index].format; } #endif // Determine conversion details about source and dest formats ConvertData key = { inFormat, 0 }; const ConvertData* in = (const ConvertData*) bsearch_s( &key, g_ConvertTable, _countof(g_ConvertTable), sizeof(ConvertData), _ConvertCompare, 0 ); key.format = outFormat; const ConvertData* out = (const ConvertData*) bsearch_s( &key, g_ConvertTable, _countof(g_ConvertTable), sizeof(ConvertData), _ConvertCompare, 0 ); if ( !in || !out ) { assert(false); return; } assert( _GetConvertFlags( inFormat ) == in->flags ); assert( _GetConvertFlags( outFormat ) == out->flags ); // Handle SRGB filtering modes switch ( inFormat ) { case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: case DXGI_FORMAT_BC1_UNORM_SRGB: case DXGI_FORMAT_BC2_UNORM_SRGB: case DXGI_FORMAT_BC3_UNORM_SRGB: case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: case DXGI_FORMAT_BC7_UNORM_SRGB: flags |= TEX_FILTER_SRGB_IN; break; case DXGI_FORMAT_A8_UNORM: case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM: flags &= ~TEX_FILTER_SRGB_IN; break; } switch ( outFormat ) { case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: case DXGI_FORMAT_BC1_UNORM_SRGB: case DXGI_FORMAT_BC2_UNORM_SRGB: case DXGI_FORMAT_BC3_UNORM_SRGB: case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: case DXGI_FORMAT_BC7_UNORM_SRGB: flags |= TEX_FILTER_SRGB_OUT; break; case DXGI_FORMAT_A8_UNORM: case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM: flags &= ~TEX_FILTER_SRGB_OUT; break; } if ( (flags & (TEX_FILTER_SRGB_IN|TEX_FILTER_SRGB_OUT)) == (TEX_FILTER_SRGB_IN|TEX_FILTER_SRGB_OUT) ) { flags &= ~(TEX_FILTER_SRGB_IN|TEX_FILTER_SRGB_OUT); } // sRGB input processing (sRGB -> Linear RGB) if ( flags & TEX_FILTER_SRGB_IN ) { if ( !(in->flags & CONVF_DEPTH) && ( (in->flags & CONVF_FLOAT) || (in->flags & CONVF_UNORM) ) ) { XMVECTOR* ptr = pBuffer; for( size_t i=0; i < count; ++i, ++ptr ) { *ptr = XMColorSRGBToRGB( *ptr ); } } } // Handle conversion special cases DWORD diffFlags = in->flags ^ out->flags; if ( diffFlags != 0 ) { static const XMVECTORF32 s_two = { 2.0f, 2.0f, 2.0f, 2.0f }; if ( diffFlags & CONVF_DEPTH ) { if ( in->flags & CONVF_DEPTH ) { // CONVF_DEPTH -> !CONVF_DEPTH if ( in->flags & CONVF_STENCIL ) { // Stencil -> Alpha static const XMVECTORF32 S = { 1.f, 1.f, 1.f, 255.f }; if( out->flags & CONVF_UNORM ) { // UINT -> UNORM XMVECTOR* ptr = pBuffer; for( size_t i=0; i < count; ++i ) { XMVECTOR v = *ptr; XMVECTOR v1 = XMVectorSplatY( v ); v1 = XMVectorClamp( v1, g_XMZero, S ); v1 = XMVectorDivide( v1, S ); v = XMVectorSelect( v1, v, g_XMSelect1110 ); *ptr++ = v; } } else if ( out->flags & CONVF_SNORM ) { // UINT -> SNORM XMVECTOR* ptr = pBuffer; for( size_t i=0; i < count; ++i ) { XMVECTOR v = *ptr; XMVECTOR v1 = XMVectorSplatY( v ); v1 = XMVectorClamp( v1, g_XMZero, S ); v1 = XMVectorDivide( v1, S ); v1 = XMVectorMultiplyAdd( v1, s_two, g_XMNegativeOne ); v = XMVectorSelect( v1, v, g_XMSelect1110 ); *ptr++ = v; } } else { XMVECTOR* ptr = pBuffer; for( size_t i=0; i < count; ++i ) { XMVECTOR v = *ptr; XMVECTOR v1 = XMVectorSplatY( v ); v = XMVectorSelect( v1, v, g_XMSelect1110 ); *ptr++ = v; } } } // Depth -> RGB if ( ( out->flags & CONVF_UNORM ) && ( in->flags & CONVF_FLOAT ) ) { // Depth FLOAT -> UNORM XMVECTOR* ptr = pBuffer; for( size_t i=0; i < count; ++i ) { XMVECTOR v = *ptr; XMVECTOR v1 = XMVectorSaturate( v ); v1 = XMVectorSplatX( v1 ); v = XMVectorSelect( v, v1, g_XMSelect1110 ); *ptr++ = v; } } else if ( out->flags & CONVF_SNORM ) { if ( in->flags & CONVF_UNORM ) { // Depth UNORM -> SNORM XMVECTOR* ptr = pBuffer; for( size_t i=0; i < count; ++i ) { XMVECTOR v = *ptr; XMVECTOR v1 = XMVectorMultiplyAdd( v, s_two, g_XMNegativeOne ); v1 = XMVectorSplatX( v1 ); v = XMVectorSelect( v, v1, g_XMSelect1110 ); *ptr++ = v; } } else { // Depth FLOAT -> SNORM XMVECTOR* ptr = pBuffer; for( size_t i=0; i < count; ++i ) { XMVECTOR v = *ptr; XMVECTOR v1 = XMVectorClamp( v, g_XMNegativeOne, g_XMOne ); v1 = XMVectorSplatX( v1 ); v = XMVectorSelect( v, v1, g_XMSelect1110 ); *ptr++ = v; } } } else { XMVECTOR* ptr = pBuffer; for( size_t i=0; i < count; ++i ) { XMVECTOR v = *ptr; XMVECTOR v1 = XMVectorSplatX( v ); v = XMVectorSelect( v, v1, g_XMSelect1110 ); *ptr++ = v; } } } else { // !CONVF_DEPTH -> CONVF_DEPTH // RGB -> Depth (red channel) switch( flags & ( TEX_FILTER_RGB_COPY_RED | TEX_FILTER_RGB_COPY_GREEN | TEX_FILTER_RGB_COPY_BLUE ) ) { case TEX_FILTER_RGB_COPY_GREEN: { XMVECTOR* ptr = pBuffer; for( size_t i=0; i < count; ++i ) { XMVECTOR v = *ptr; XMVECTOR v1 = XMVectorSplatY( v ); v = XMVectorSelect( v, v1, g_XMSelect1000 ); *ptr++ = v; } } break; case TEX_FILTER_RGB_COPY_BLUE: { XMVECTOR* ptr = pBuffer; for( size_t i=0; i < count; ++i ) { XMVECTOR v = *ptr; XMVECTOR v1 = XMVectorSplatZ( v ); v = XMVectorSelect( v, v1, g_XMSelect1000 ); *ptr++ = v; } } break; default: if ( (in->flags & CONVF_UNORM) && ( (in->flags & CONVF_RGB_MASK) == (CONVF_R|CONVF_G|CONVF_B) ) ) { XMVECTOR* ptr = pBuffer; for( size_t i=0; i < count; ++i ) { XMVECTOR v = *ptr; XMVECTOR v1 = XMVector3Dot( v, g_Grayscale ); v = XMVectorSelect( v, v1, g_XMSelect1000 ); *ptr++ = v; } break; } // fall-through case TEX_FILTER_RGB_COPY_RED: { XMVECTOR* ptr = pBuffer; for( size_t i=0; i < count; ++i ) { XMVECTOR v = *ptr; XMVECTOR v1 = XMVectorSplatX( v ); v = XMVectorSelect( v, v1, g_XMSelect1000 ); *ptr++ = v; } } break; } // Finialize type conversion for depth (red channel) if ( out->flags & CONVF_UNORM ) { if ( in->flags & CONVF_SNORM ) { // SNORM -> UNORM XMVECTOR* ptr = pBuffer; for( size_t i=0; i < count; ++i ) { XMVECTOR v = *ptr; XMVECTOR v1 = XMVectorMultiplyAdd( v, g_XMOneHalf, g_XMOneHalf ); v = XMVectorSelect( v, v1, g_XMSelect1000 ); *ptr++ = v; } } else if ( in->flags & CONVF_FLOAT ) { // FLOAT -> UNORM XMVECTOR* ptr = pBuffer; for( size_t i=0; i < count; ++i ) { XMVECTOR v = *ptr; XMVECTOR v1 = XMVectorSaturate( v ); v = XMVectorSelect( v, v1, g_XMSelect1000 ); *ptr++ = v; } } } if ( out->flags & CONVF_STENCIL ) { // Alpha -> Stencil (green channel) static const XMVECTORU32 select0100 = { XM_SELECT_0, XM_SELECT_1, XM_SELECT_0, XM_SELECT_0 }; static const XMVECTORF32 S = { 255.f, 255.f, 255.f, 255.f }; if ( in->flags & CONVF_UNORM ) { // UNORM -> UINT XMVECTOR* ptr = pBuffer; for( size_t i=0; i < count; ++i ) { XMVECTOR v = *ptr; XMVECTOR v1 = XMVectorMultiply( v, S ); v1 = XMVectorSplatW( v1 ); v = XMVectorSelect( v, v1, select0100 ); *ptr++ = v; } } else if ( in->flags & CONVF_SNORM ) { // SNORM -> UINT XMVECTOR* ptr = pBuffer; for( size_t i=0; i < count; ++i ) { XMVECTOR v = *ptr; XMVECTOR v1 = XMVectorMultiplyAdd( v, g_XMOneHalf, g_XMOneHalf ); v1 = XMVectorMultiply( v1, S ); v1 = XMVectorSplatW( v1 ); v = XMVectorSelect( v, v1, select0100 ); *ptr++ = v; } } else { XMVECTOR* ptr = pBuffer; for( size_t i=0; i < count; ++i ) { XMVECTOR v = *ptr; XMVECTOR v1 = XMVectorSplatW( v ); v = XMVectorSelect( v, v1, select0100 ); *ptr++ = v; } } } } } else if ( out->flags & CONVF_DEPTH ) { // CONVF_DEPTH -> CONVF_DEPTH if ( diffFlags & CONVF_FLOAT ) { if ( in->flags & CONVF_FLOAT ) { // FLOAT -> UNORM depth, preserve stencil XMVECTOR* ptr = pBuffer; for( size_t i=0; i < count; ++i ) { XMVECTOR v = *ptr; XMVECTOR v1 = XMVectorSaturate( v ); v = XMVectorSelect( v, v1, g_XMSelect1000 ); *ptr++ = v; } } } } else if ( out->flags & CONVF_UNORM ) { if ( in->flags & CONVF_SNORM ) { // SNORM -> UNORM XMVECTOR* ptr = pBuffer; for( size_t i=0; i < count; ++i ) { XMVECTOR v = *ptr; *ptr++ = XMVectorMultiplyAdd( v, g_XMOneHalf, g_XMOneHalf ); } } else if ( in->flags & CONVF_FLOAT ) { // FLOAT -> UNORM XMVECTOR* ptr = pBuffer; for( size_t i=0; i < count; ++i ) { XMVECTOR v = *ptr; *ptr++ = XMVectorSaturate( v ); } } } else if ( out->flags & CONVF_SNORM ) { if ( in->flags & CONVF_UNORM ) { // UNORM -> SNORM XMVECTOR* ptr = pBuffer; for( size_t i=0; i < count; ++i ) { XMVECTOR v = *ptr; *ptr++ = XMVectorMultiplyAdd( v, s_two, g_XMNegativeOne ); } } else if ( in->flags & CONVF_FLOAT ) { // FLOAT -> SNORM XMVECTOR* ptr = pBuffer; for( size_t i=0; i < count; ++i ) { XMVECTOR v = *ptr; *ptr++ = XMVectorClamp( v, g_XMNegativeOne, g_XMOne ); } } } // !CONVF_A -> CONVF_A is handled because LoadScanline ensures alpha defaults to 1.0 for no-alpha formats // CONVF_PACKED cases are handled because LoadScanline/StoreScanline handles packing/unpacking if ( ((out->flags & CONVF_RGBA_MASK) == CONVF_A) && !(in->flags & CONVF_A) ) { // !CONVF_A -> A format switch( flags & ( TEX_FILTER_RGB_COPY_RED | TEX_FILTER_RGB_COPY_GREEN | TEX_FILTER_RGB_COPY_BLUE ) ) { case TEX_FILTER_RGB_COPY_GREEN: { XMVECTOR* ptr = pBuffer; for( size_t i=0; i < count; ++i ) { XMVECTOR v = *ptr; *ptr++ = XMVectorSplatY( v ); } } break; case TEX_FILTER_RGB_COPY_BLUE: { XMVECTOR* ptr = pBuffer; for( size_t i=0; i < count; ++i ) { XMVECTOR v = *ptr; *ptr++ = XMVectorSplatZ( v ); } } break; default: if ( (in->flags & CONVF_UNORM) && ( (in->flags & CONVF_RGB_MASK) == (CONVF_R|CONVF_G|CONVF_B) ) ) { XMVECTOR* ptr = pBuffer; for( size_t i=0; i < count; ++i ) { XMVECTOR v = *ptr; *ptr++ = XMVector3Dot( v, g_Grayscale ); } break; } // fall-through case TEX_FILTER_RGB_COPY_RED: { XMVECTOR* ptr = pBuffer; for( size_t i=0; i < count; ++i ) { XMVECTOR v = *ptr; *ptr++ = XMVectorSplatX( v ); } } break; } } else if ( ((in->flags & CONVF_RGBA_MASK) == CONVF_A) && !(out->flags & CONVF_A) ) { // A format -> !CONVF_A XMVECTOR* ptr = pBuffer; for( size_t i=0; i < count; ++i ) { XMVECTOR v = *ptr; *ptr++ = XMVectorSplatW( v ); } } else if ( (in->flags & CONVF_RGB_MASK) == CONVF_R ) { if ( (out->flags & CONVF_RGB_MASK) == (CONVF_R|CONVF_G|CONVF_B) ) { // R format -> RGB format XMVECTOR* ptr = pBuffer; for( size_t i=0; i < count; ++i ) { XMVECTOR v = *ptr; XMVECTOR v1 = XMVectorSplatX( v ); *ptr++ = XMVectorSelect( v, v1, g_XMSelect1110 ); } } else if ( (out->flags & CONVF_RGB_MASK) == (CONVF_R|CONVF_G) ) { // R format -> RG format XMVECTOR* ptr = pBuffer; for( size_t i=0; i < count; ++i ) { XMVECTOR v = *ptr; XMVECTOR v1 = XMVectorSplatX( v ); *ptr++ = XMVectorSelect( v, v1, g_XMSelect1100 ); } } } else if ( (in->flags & CONVF_RGB_MASK) == (CONVF_R|CONVF_G|CONVF_B) ) { if ( (out->flags & CONVF_RGB_MASK) == CONVF_R ) { // RGB format -> R format switch( flags & ( TEX_FILTER_RGB_COPY_RED | TEX_FILTER_RGB_COPY_GREEN | TEX_FILTER_RGB_COPY_BLUE ) ) { case TEX_FILTER_RGB_COPY_GREEN: { XMVECTOR* ptr = pBuffer; for( size_t i=0; i < count; ++i ) { XMVECTOR v = *ptr; XMVECTOR v1 = XMVectorSplatY( v ); *ptr++ = XMVectorSelect( v, v1, g_XMSelect1110 ); } } break; case TEX_FILTER_RGB_COPY_BLUE: { XMVECTOR* ptr = pBuffer; for( size_t i=0; i < count; ++i ) { XMVECTOR v = *ptr; XMVECTOR v1 = XMVectorSplatZ( v ); *ptr++ = XMVectorSelect( v, v1, g_XMSelect1110 ); } } break; default: if ( in->flags & CONVF_UNORM ) { XMVECTOR* ptr = pBuffer; for( size_t i=0; i < count; ++i ) { XMVECTOR v = *ptr; XMVECTOR v1 = XMVector3Dot( v, g_Grayscale ); *ptr++ = XMVectorSelect( v, v1, g_XMSelect1110 ); } break; } // fall-through case TEX_FILTER_RGB_COPY_RED: // Leave data unchanged and the store will handle this... break; } } else if ( (out->flags & CONVF_RGB_MASK) == (CONVF_R|CONVF_G) ) { // RGB format -> RG format switch( flags & ( TEX_FILTER_RGB_COPY_RED | TEX_FILTER_RGB_COPY_GREEN | TEX_FILTER_RGB_COPY_BLUE ) ) { case TEX_FILTER_RGB_COPY_RED | TEX_FILTER_RGB_COPY_BLUE: { XMVECTOR* ptr = pBuffer; for( size_t i=0; i < count; ++i ) { XMVECTOR v = *ptr; XMVECTOR v1 = XMVectorSwizzle<0,2,0,2>( v ); *ptr++ = XMVectorSelect( v, v1, g_XMSelect1100 ); } } break; case TEX_FILTER_RGB_COPY_GREEN | TEX_FILTER_RGB_COPY_BLUE: { XMVECTOR* ptr = pBuffer; for( size_t i=0; i < count; ++i ) { XMVECTOR v = *ptr; XMVECTOR v1 = XMVectorSwizzle<1,2,3,0>( v ); *ptr++ = XMVectorSelect( v, v1, g_XMSelect1100 ); } } break; case TEX_FILTER_RGB_COPY_RED | TEX_FILTER_RGB_COPY_GREEN: default: // Leave data unchanged and the store will handle this... break; } } } } // sRGB output processing (Linear RGB -> sRGB) if ( flags & TEX_FILTER_SRGB_OUT ) { if ( !(out->flags & CONVF_DEPTH) && ( (out->flags & CONVF_FLOAT) || (out->flags & CONVF_UNORM) ) ) { XMVECTOR* ptr = pBuffer; for( size_t i=0; i < count; ++i, ++ptr ) { *ptr = XMColorRGBToSRGB( *ptr ); } } } } //------------------------------------------------------------------------------------- // Dithering //------------------------------------------------------------------------------------- // 4X4X4 ordered dithering matrix static const float g_Dither[] = { // (z & 3) + ( (y & 3) * 8) + (x & 3) 0.468750f, -0.031250f, 0.343750f, -0.156250f, 0.468750f, -0.031250f, 0.343750f, -0.156250f, -0.281250f, 0.218750f, -0.406250f, 0.093750f, -0.281250f, 0.218750f, -0.406250f, 0.093750f, 0.281250f, -0.218750f, 0.406250f, -0.093750f, 0.281250f, -0.218750f, 0.406250f, -0.093750f, -0.468750f, 0.031250f, -0.343750f, 0.156250f, -0.468750f, 0.031250f, -0.343750f, 0.156250f, }; static const XMVECTORF32 g_Scale16pc = { 65535.f, 65535.f, 65535.f, 65535.f }; static const XMVECTORF32 g_Scale15pc = { 32767.f, 32767.f, 32767.f, 32767.f }; static const XMVECTORF32 g_Scale10pc = { 1023.f, 1023.f, 1023.f, 3.f }; static const XMVECTORF32 g_Scale8pc = { 255.f, 255.f, 255.f, 255.f }; static const XMVECTORF32 g_Scale7pc = { 127.f, 127.f, 127.f, 127.f }; static const XMVECTORF32 g_Scale565pc = { 31.f, 63.f, 31.f, 1.f }; static const XMVECTORF32 g_Scale5551pc = { 31.f, 31.f, 31.f, 1.f }; static const XMVECTORF32 g_Scale4pc = { 15.f, 15.f, 15.f, 15.f }; static const XMVECTORF32 g_ErrorWeight3 = { 3.f/16.f, 3.f/16.f, 3.f/16.f, 3.f/16.f }; static const XMVECTORF32 g_ErrorWeight5 = { 5.f/16.f, 5.f/16.f, 5.f/16.f, 5.f/16.f }; static const XMVECTORF32 g_ErrorWeight1 = { 1.f/16.f, 1.f/16.f, 1.f/16.f, 1.f/16.f }; static const XMVECTORF32 g_ErrorWeight7 = { 7.f/16.f, 7.f/16.f, 7.f/16.f, 7.f/16.f }; #define STORE_SCANLINE( type, scalev, clampzero, norm, itype, mask, row, bgr ) \ if ( size >= sizeof(type) ) \ { \ type * __restrict dest = reinterpret_cast(pDestination); \ for( size_t i = 0; i < count; ++i ) \ { \ ptrdiff_t index = static_cast( ( row & 1 ) ? ( count - i - 1 ) : i ); \ ptrdiff_t delta = ( row & 1 ) ? -2 : 0; \ \ XMVECTOR v = sPtr[ index ]; \ if ( bgr ) { v = XMVectorSwizzle<2, 1, 0, 3>( v ); } \ if ( norm && clampzero ) v = XMVectorSaturate( v ) ; \ else if ( clampzero ) v = XMVectorClamp( v, g_XMZero, scalev ); \ else if ( norm ) v = XMVectorClamp( v, g_XMNegativeOne, g_XMOne ); \ else v = XMVectorClamp( v, -scalev + g_XMOne, scalev ); \ v = XMVectorAdd( v, vError ); \ if ( norm ) v = XMVectorMultiply( v, scalev ); \ \ XMVECTOR target; \ if ( pDiffusionErrors ) \ { \ target = XMVectorRound( v ); \ vError = XMVectorSubtract( v, target ); \ if (norm) vError = XMVectorDivide( vError, scalev ); \ \ /* Distribute error to next scanline and next pixel */ \ pDiffusionErrors[ index-delta ] += XMVectorMultiply( g_ErrorWeight3, vError ); \ pDiffusionErrors[ index+1 ] += XMVectorMultiply( g_ErrorWeight5, vError ); \ pDiffusionErrors[ index+2+delta ] += XMVectorMultiply( g_ErrorWeight1, vError ); \ vError = XMVectorMultiply( vError, g_ErrorWeight7 ); \ } \ else \ { \ /* Applied ordered dither */ \ target = XMVectorAdd( v, ordered[ index & 3 ] ); \ target = XMVectorRound( target ); \ } \ \ target = XMVectorMin( scalev, target ); \ target = XMVectorMax( (clampzero) ? g_XMZero : ( -scalev + g_XMOne ), target ); \ \ XMFLOAT4A tmp; \ XMStoreFloat4A( &tmp, target ); \ \ auto dPtr = &dest[ index ]; \ dPtr->x = static_cast( tmp.x ) & mask; \ dPtr->y = static_cast( tmp.y ) & mask; \ dPtr->z = static_cast( tmp.z ) & mask; \ dPtr->w = static_cast( tmp.w ) & mask; \ } \ return true; \ } \ return false; #define STORE_SCANLINE2( type, scalev, clampzero, norm, itype, mask, row ) \ /* The 2 component cases are always bgr=false */ \ if ( size >= sizeof(type) ) \ { \ type * __restrict dest = reinterpret_cast(pDestination); \ for( size_t i = 0; i < count; ++i ) \ { \ ptrdiff_t index = static_cast( ( row & 1 ) ? ( count - i - 1 ) : i ); \ ptrdiff_t delta = ( row & 1 ) ? -2 : 0; \ \ XMVECTOR v = sPtr[ index ]; \ if ( norm && clampzero ) v = XMVectorSaturate( v ) ; \ else if ( clampzero ) v = XMVectorClamp( v, g_XMZero, scalev ); \ else if ( norm ) v = XMVectorClamp( v, g_XMNegativeOne, g_XMOne ); \ else v = XMVectorClamp( v, -scalev + g_XMOne, scalev ); \ v = XMVectorAdd( v, vError ); \ if ( norm ) v = XMVectorMultiply( v, scalev ); \ \ XMVECTOR target; \ if ( pDiffusionErrors ) \ { \ target = XMVectorRound( v ); \ vError = XMVectorSubtract( v, target ); \ if (norm) vError = XMVectorDivide( vError, scalev ); \ \ /* Distribute error to next scanline and next pixel */ \ pDiffusionErrors[ index-delta ] += XMVectorMultiply( g_ErrorWeight3, vError ); \ pDiffusionErrors[ index+1 ] += XMVectorMultiply( g_ErrorWeight5, vError ); \ pDiffusionErrors[ index+2+delta ] += XMVectorMultiply( g_ErrorWeight1, vError ); \ vError = XMVectorMultiply( vError, g_ErrorWeight7 ); \ } \ else \ { \ /* Applied ordered dither */ \ target = XMVectorAdd( v, ordered[ index & 3 ] ); \ target = XMVectorRound( target ); \ } \ \ target = XMVectorMin( scalev, target ); \ target = XMVectorMax( (clampzero) ? g_XMZero : ( -scalev + g_XMOne ), target ); \ \ XMFLOAT4A tmp; \ XMStoreFloat4A( &tmp, target ); \ \ auto dPtr = &dest[ index ]; \ dPtr->x = static_cast( tmp.x ) & mask; \ dPtr->y = static_cast( tmp.y ) & mask; \ } \ return true; \ } \ return false; #define STORE_SCANLINE1( type, scalev, clampzero, norm, mask, row, selectw ) \ /* The 1 component cases are always bgr=false */ \ if ( size >= sizeof(type) ) \ { \ type * __restrict dest = reinterpret_cast(pDestination); \ for( size_t i = 0; i < count; ++i ) \ { \ ptrdiff_t index = static_cast( ( row & 1 ) ? ( count - i - 1 ) : i ); \ ptrdiff_t delta = ( row & 1 ) ? -2 : 0; \ \ XMVECTOR v = sPtr[ index ]; \ if ( norm && clampzero ) v = XMVectorSaturate( v ) ; \ else if ( clampzero ) v = XMVectorClamp( v, g_XMZero, scalev ); \ else if ( norm ) v = XMVectorClamp( v, g_XMNegativeOne, g_XMOne ); \ else v = XMVectorClamp( v, -scalev + g_XMOne, scalev ); \ v = XMVectorAdd( v, vError ); \ if ( norm ) v = XMVectorMultiply( v, scalev ); \ \ XMVECTOR target; \ if ( pDiffusionErrors ) \ { \ target = XMVectorRound( v ); \ vError = XMVectorSubtract( v, target ); \ if (norm) vError = XMVectorDivide( vError, scalev ); \ \ /* Distribute error to next scanline and next pixel */ \ pDiffusionErrors[ index-delta ] += XMVectorMultiply( g_ErrorWeight3, vError ); \ pDiffusionErrors[ index+1 ] += XMVectorMultiply( g_ErrorWeight5, vError ); \ pDiffusionErrors[ index+2+delta ] += XMVectorMultiply( g_ErrorWeight1, vError ); \ vError = XMVectorMultiply( vError, g_ErrorWeight7 ); \ } \ else \ { \ /* Applied ordered dither */ \ target = XMVectorAdd( v, ordered[ index & 3 ] ); \ target = XMVectorRound( target ); \ } \ \ target = XMVectorMin( scalev, target ); \ target = XMVectorMax( (clampzero) ? g_XMZero : ( -scalev + g_XMOne ), target ); \ \ dest[ index ] = static_cast( (selectw) ? XMVectorGetW( target ) : XMVectorGetX( target ) ) & mask; \ } \ return true; \ } \ return false; #pragma warning(push) #pragma warning( disable : 4127 ) _Use_decl_annotations_ bool _StoreScanlineDither( LPVOID pDestination, size_t size, DXGI_FORMAT format, XMVECTOR* pSource, size_t count, float threshold, size_t y, size_t z, XMVECTOR* pDiffusionErrors ) { assert( pDestination && size > 0 ); assert( pSource && count > 0 && (((uintptr_t)pSource & 0xF) == 0) ); assert( IsValid(format) && !IsTypeless(format) && !IsCompressed(format) && !IsPlanar(format) && !IsPalettized(format) ); XMVECTOR ordered[4]; if ( pDiffusionErrors ) { // If pDiffusionErrors != 0, then this function performs error diffusion dithering (aka Floyd-Steinberg dithering) // To avoid the need for another temporary scanline buffer, we allow this function to overwrite the source buffer in-place // Given the intended usage in the conversion routines, this is not a problem. XMVECTOR* ptr = pSource; const XMVECTOR* err = pDiffusionErrors + 1; for( size_t i=0; i < count; ++i ) { // Add contribution from previous scanline XMVECTOR v = XMVectorAdd( *ptr, *err++ ); *ptr++ = v; } // Reset errors for next scanline memset( pDiffusionErrors, 0, sizeof(XMVECTOR)*(count+2) ); } else { // If pDiffusionErrors == 0, then this function performs ordered dithering XMVECTOR dither = XMLoadFloat4( reinterpret_cast( g_Dither + (z & 3) + ( (y & 3) * 8 ) ) ); ordered[0] = XMVectorSplatX( dither ); ordered[1] = XMVectorSplatY( dither ); ordered[2] = XMVectorSplatZ( dither ); ordered[3] = XMVectorSplatW( dither ); } const XMVECTOR* __restrict sPtr = pSource; if ( !sPtr ) return false; XMVECTOR vError = XMVectorZero(); switch( format ) { case DXGI_FORMAT_R16G16B16A16_UNORM: STORE_SCANLINE( XMUSHORTN4, g_Scale16pc, true, true, uint16_t, 0xFFFF, y, false ) case DXGI_FORMAT_R16G16B16A16_UINT: STORE_SCANLINE( XMUSHORT4, g_Scale16pc, true, false, uint16_t, 0xFFFF, y, false ) case DXGI_FORMAT_R16G16B16A16_SNORM: STORE_SCANLINE( XMSHORTN4, g_Scale15pc, false, true, int16_t, 0xFFFF, y, false ) case DXGI_FORMAT_R16G16B16A16_SINT: STORE_SCANLINE( XMSHORT4, g_Scale15pc, false, false, int16_t, 0xFFFF, y, false ) case DXGI_FORMAT_R10G10B10A2_UNORM: STORE_SCANLINE( XMUDECN4, g_Scale10pc, true, true, uint16_t, 0x3FF, y, false ) case DXGI_FORMAT_R10G10B10A2_UINT: STORE_SCANLINE( XMUDEC4, g_Scale10pc, true, false, uint16_t, 0x3FF, y, false ) case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM: if ( size >= sizeof(XMUDEC4) ) { static const XMVECTORF32 Scale = { 510.0f, 510.0f, 510.0f, 3.0f }; static const XMVECTORF32 Bias = { 384.0f, 384.0f, 384.0f, 0.0f }; static const XMVECTORF32 MinXR = { -0.7529f, -0.7529f, -0.7529f, 0.f }; static const XMVECTORF32 MaxXR = { 1.2529f, 1.2529f, 1.2529f, 1.0f }; XMUDEC4 * __restrict dest = reinterpret_cast(pDestination); for( size_t i = 0; i < count; ++i ) { ptrdiff_t index = static_cast( ( y & 1 ) ? ( count - i - 1 ) : i ); ptrdiff_t delta = ( y & 1 ) ? -2 : 0; XMVECTOR v = XMVectorClamp( sPtr[ index ], MinXR, MaxXR ); v = XMVectorMultiplyAdd( v, Scale, vError ); XMVECTOR target; if ( pDiffusionErrors ) { target = XMVectorRound( v ); vError = XMVectorSubtract( v, target ); vError = XMVectorDivide( vError, Scale ); // Distribute error to next scanline and next pixel pDiffusionErrors[ index-delta ] += XMVectorMultiply( g_ErrorWeight3, vError ); pDiffusionErrors[ index+1 ] += XMVectorMultiply( g_ErrorWeight5, vError ); pDiffusionErrors[ index+2+delta ] += XMVectorMultiply( g_ErrorWeight1, vError ); vError = XMVectorMultiply( vError, g_ErrorWeight7 ); } else { // Applied ordered dither target = XMVectorAdd( v, ordered[ index & 3 ] ); target = XMVectorRound( target ); } target = XMVectorAdd( target, Bias ); target = XMVectorClamp( target, g_XMZero, g_Scale10pc ); XMFLOAT4A tmp; XMStoreFloat4A( &tmp, target ); auto dPtr = &dest[ index ]; dPtr->x = static_cast( tmp.x ) & 0x3FF; dPtr->y = static_cast( tmp.y ) & 0x3FF; dPtr->z = static_cast( tmp.z ) & 0x3FF; dPtr->w = static_cast( tmp.w ); } return true; } return false; case DXGI_FORMAT_R8G8B8A8_UNORM: case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: STORE_SCANLINE( XMUBYTEN4, g_Scale8pc, true, true, uint8_t, 0xFF, y, false ) case DXGI_FORMAT_R8G8B8A8_UINT: STORE_SCANLINE( XMUBYTE4, g_Scale8pc, true, false, uint8_t, 0xFF, y, false ) case DXGI_FORMAT_R8G8B8A8_SNORM: STORE_SCANLINE( XMBYTEN4, g_Scale7pc, false, true, int8_t, 0xFF, y, false ) case DXGI_FORMAT_R8G8B8A8_SINT: STORE_SCANLINE( XMBYTE4, g_Scale7pc, false, false, int8_t, 0xFF, y, false ) case DXGI_FORMAT_R16G16_UNORM: STORE_SCANLINE2( XMUSHORTN2, g_Scale16pc, true, true, uint16_t, 0xFFFF, y ) case DXGI_FORMAT_R16G16_UINT: STORE_SCANLINE2( XMUSHORT2, g_Scale16pc, true, false, uint16_t, 0xFFFF, y ) case DXGI_FORMAT_R16G16_SNORM: STORE_SCANLINE2( XMSHORTN2, g_Scale15pc, false, true, int16_t, 0xFFFF, y ) case DXGI_FORMAT_R16G16_SINT: STORE_SCANLINE2( XMSHORT2, g_Scale15pc, false, false, int16_t, 0xFFFF, y ) case DXGI_FORMAT_D24_UNORM_S8_UINT: if ( size >= sizeof(uint32_t) ) { static const XMVECTORF32 Clamp = { 1.f, 255.f, 0.f, 0.f }; static const XMVECTORF32 Scale = { 16777215.f, 1.f, 0.f, 0.f }; static const XMVECTORF32 Scale2 = { 16777215.f, 255.f, 0.f, 0.f }; uint32_t * __restrict dest = reinterpret_cast(pDestination); for( size_t i = 0; i < count; ++i ) { ptrdiff_t index = static_cast( ( y & 1 ) ? ( count - i - 1 ) : i ); ptrdiff_t delta = ( y & 1 ) ? -2 : 0; XMVECTOR v = XMVectorClamp( sPtr[ index ], g_XMZero, Clamp ); v = XMVectorAdd( v, vError ); v = XMVectorMultiply( v, Scale ); XMVECTOR target; if ( pDiffusionErrors ) { target = XMVectorRound( v ); vError = XMVectorSubtract( v, target ); vError = XMVectorDivide( vError, Scale ); // Distribute error to next scanline and next pixel pDiffusionErrors[ index-delta ] += XMVectorMultiply( g_ErrorWeight3, vError ); pDiffusionErrors[ index+1 ] += XMVectorMultiply( g_ErrorWeight5, vError ); pDiffusionErrors[ index+2+delta ] += XMVectorMultiply( g_ErrorWeight1, vError ); vError = XMVectorMultiply( vError, g_ErrorWeight7 ); } else { // Applied ordered dither target = XMVectorAdd( v, ordered[ index & 3 ] ); target = XMVectorRound( target ); } target = XMVectorClamp( target, g_XMZero, Scale2 ); XMFLOAT4A tmp; XMStoreFloat4A( &tmp, target ); auto dPtr = &dest[ index ]; *dPtr = (static_cast( tmp.x ) & 0xFFFFFF) | ((static_cast( tmp.y ) & 0xFF) << 24); } return true; } return false; case DXGI_FORMAT_R8G8_UNORM: STORE_SCANLINE2( XMUBYTEN2, g_Scale8pc, true, true, uint8_t, 0xFF, y ) case DXGI_FORMAT_R8G8_UINT: STORE_SCANLINE2( XMUBYTE2, g_Scale8pc, true, false, uint8_t, 0xFF, y ) case DXGI_FORMAT_R8G8_SNORM: STORE_SCANLINE2( XMBYTEN2, g_Scale7pc, false, true, int8_t, 0xFF, y ) case DXGI_FORMAT_R8G8_SINT: STORE_SCANLINE2( XMBYTE2, g_Scale7pc, false, false, int8_t, 0xFF, y ) case DXGI_FORMAT_D16_UNORM: case DXGI_FORMAT_R16_UNORM: STORE_SCANLINE1( uint16_t, g_Scale16pc, true, true, 0xFFFF, y, false ) case DXGI_FORMAT_R16_UINT: STORE_SCANLINE1( uint16_t, g_Scale16pc, true, false, 0xFFFF, y, false ) case DXGI_FORMAT_R16_SNORM: STORE_SCANLINE1( int16_t, g_Scale15pc, false, true, 0xFFFF, y, false ) case DXGI_FORMAT_R16_SINT: STORE_SCANLINE1( int16_t, g_Scale15pc, false, false, 0xFFFF, y, false ) case DXGI_FORMAT_R8_UNORM: STORE_SCANLINE1( uint8_t, g_Scale8pc, true, true, 0xFF, y, false ) case DXGI_FORMAT_R8_UINT: STORE_SCANLINE1( uint8_t, g_Scale8pc, true, false, 0xFF, y, false ) case DXGI_FORMAT_R8_SNORM: STORE_SCANLINE1( int8_t, g_Scale7pc, false, true, 0xFF, y, false ) case DXGI_FORMAT_R8_SINT: STORE_SCANLINE1( int8_t, g_Scale7pc, false, false, 0xFF, y, false ) case DXGI_FORMAT_A8_UNORM: STORE_SCANLINE1( uint8_t, g_Scale8pc, true, true, 0xFF, y, true ) case DXGI_FORMAT_B5G6R5_UNORM: if ( size >= sizeof(XMU565) ) { XMU565 * __restrict dest = reinterpret_cast(pDestination); for( size_t i = 0; i < count; ++i ) { ptrdiff_t index = static_cast( ( y & 1 ) ? ( count - i - 1 ) : i ); ptrdiff_t delta = ( y & 1 ) ? -2 : 0; XMVECTOR v = XMVectorSwizzle<2, 1, 0, 3>( sPtr[ index ] ); v = XMVectorSaturate( v ); v = XMVectorAdd( v, vError ); v = XMVectorMultiply( v, g_Scale565pc ); XMVECTOR target; if ( pDiffusionErrors ) { target = XMVectorRound( v ); vError = XMVectorSubtract( v, target ); vError = XMVectorDivide( vError, g_Scale565pc ); // Distribute error to next scanline and next pixel pDiffusionErrors[ index-delta ] += XMVectorMultiply( g_ErrorWeight3, vError ); pDiffusionErrors[ index+1 ] += XMVectorMultiply( g_ErrorWeight5, vError ); pDiffusionErrors[ index+2+delta ] += XMVectorMultiply( g_ErrorWeight1, vError ); vError = XMVectorMultiply( vError, g_ErrorWeight7 ); } else { // Applied ordered dither target = XMVectorAdd( v, ordered[ index & 3 ] ); target = XMVectorRound( target ); } target = XMVectorClamp( target, g_XMZero, g_Scale565pc ); XMFLOAT4A tmp; XMStoreFloat4A( &tmp, target ); auto dPtr = &dest[ index ]; dPtr->x = static_cast( tmp.x ) & 0x1F; dPtr->y = static_cast( tmp.y ) & 0x3F; dPtr->z = static_cast( tmp.z ) & 0x1F; } return true; } return false; case DXGI_FORMAT_B5G5R5A1_UNORM: if ( size >= sizeof(XMU555) ) { XMU555 * __restrict dest = reinterpret_cast(pDestination); for( size_t i = 0; i < count; ++i ) { ptrdiff_t index = static_cast( ( y & 1 ) ? ( count - i - 1 ) : i ); ptrdiff_t delta = ( y & 1 ) ? -2 : 0; XMVECTOR v = XMVectorSwizzle<2, 1, 0, 3>( sPtr[ index ] ); v = XMVectorSaturate( v ); v = XMVectorAdd( v, vError ); v = XMVectorMultiply( v, g_Scale5551pc ); XMVECTOR target; if ( pDiffusionErrors ) { target = XMVectorRound( v ); vError = XMVectorSubtract( v, target ); vError = XMVectorDivide( vError, g_Scale5551pc ); // Distribute error to next scanline and next pixel pDiffusionErrors[ index-delta ] += XMVectorMultiply( g_ErrorWeight3, vError ); pDiffusionErrors[ index+1 ] += XMVectorMultiply( g_ErrorWeight5, vError ); pDiffusionErrors[ index+2+delta ] += XMVectorMultiply( g_ErrorWeight1, vError ); vError = XMVectorMultiply( vError, g_ErrorWeight7 ); } else { // Applied ordered dither target = XMVectorAdd( v, ordered[ index & 3 ] ); target = XMVectorRound( target ); } target = XMVectorClamp( target, g_XMZero, g_Scale5551pc ); XMFLOAT4A tmp; XMStoreFloat4A( &tmp, target ); auto dPtr = &dest[ index ]; dPtr->x = static_cast( tmp.x ) & 0x1F; dPtr->y = static_cast( tmp.y ) & 0x1F; dPtr->z = static_cast( tmp.z ) & 0x1F; dPtr->w = ( XMVectorGetW( target ) > threshold ) ? 1 : 0; } return true; } return false; case DXGI_FORMAT_B8G8R8A8_UNORM: case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: STORE_SCANLINE( XMUBYTEN4, g_Scale8pc, true, true, uint8_t, 0xFF, y, true ) case DXGI_FORMAT_B8G8R8X8_UNORM: case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: if ( size >= sizeof(XMUBYTEN4) ) { XMUBYTEN4 * __restrict dest = reinterpret_cast(pDestination); for( size_t i = 0; i < count; ++i ) { ptrdiff_t index = static_cast( ( y & 1 ) ? ( count - i - 1 ) : i ); ptrdiff_t delta = ( y & 1 ) ? -2 : 0; XMVECTOR v = XMVectorSwizzle<2, 1, 0, 3>( sPtr[ index ] ); v = XMVectorSaturate( v ); v = XMVectorAdd( v, vError ); v = XMVectorMultiply( v, g_Scale8pc ); XMVECTOR target; if ( pDiffusionErrors ) { target = XMVectorRound( v ); vError = XMVectorSubtract( v, target ); vError = XMVectorDivide( vError, g_Scale8pc ); // Distribute error to next scanline and next pixel pDiffusionErrors[ index-delta ] += XMVectorMultiply( g_ErrorWeight3, vError ); pDiffusionErrors[ index+1 ] += XMVectorMultiply( g_ErrorWeight5, vError ); pDiffusionErrors[ index+2+delta ] += XMVectorMultiply( g_ErrorWeight1, vError ); vError = XMVectorMultiply( vError, g_ErrorWeight7 ); } else { // Applied ordered dither target = XMVectorAdd( v, ordered[ index & 3 ] ); target = XMVectorRound( target ); } target = XMVectorClamp( target, g_XMZero, g_Scale8pc ); XMFLOAT4A tmp; XMStoreFloat4A( &tmp, target ); auto dPtr = &dest[ index ]; dPtr->x = static_cast( tmp.x ) & 0xFF; dPtr->y = static_cast( tmp.y ) & 0xFF; dPtr->z = static_cast( tmp.z ) & 0xFF; dPtr->w = 0; } return true; } return false; case DXGI_FORMAT_B4G4R4A4_UNORM: STORE_SCANLINE( XMUNIBBLE4, g_Scale4pc, true, true, uint8_t, 0xF, y, true ) default: return _StoreScanline( pDestination, size, format, pSource, count, threshold ); } } #pragma warning(pop) #undef STORE_SCANLINE #undef STORE_SCANLINE2 #undef STORE_SCANLINE1 //------------------------------------------------------------------------------------- // Selection logic for using WIC vs. our own routines //------------------------------------------------------------------------------------- static inline bool _UseWICConversion( _In_ DWORD filter, _In_ DXGI_FORMAT sformat, _In_ DXGI_FORMAT tformat, _Out_ WICPixelFormatGUID& pfGUID, _Out_ WICPixelFormatGUID& targetGUID ) { memcpy( &pfGUID, &GUID_NULL, sizeof(GUID) ); memcpy( &targetGUID, &GUID_NULL, sizeof(GUID) ); if ( filter & TEX_FILTER_FORCE_NON_WIC ) { // Explicit flag indicates use of non-WIC code paths return false; } if ( !_DXGIToWIC( sformat, pfGUID ) || !_DXGIToWIC( tformat, targetGUID ) ) { // Source or target format are not WIC supported native pixel formats return false; } if ( filter & TEX_FILTER_FORCE_WIC ) { // Explicit flag to use WIC code paths, skips all the case checks below return true; } if ( filter & TEX_FILTER_SEPARATE_ALPHA ) { // Alpha is not premultiplied, so use non-WIC code paths return false; } #if defined(_XBOX_ONE) && defined(_TITLE) if ( sformat == DXGI_FORMAT_R16G16B16A16_FLOAT || sformat == DXGI_FORMAT_R16_FLOAT || tformat == DXGI_FORMAT_R16G16B16A16_FLOAT || tformat == DXGI_FORMAT_R16_FLOAT ) { // Use non-WIC code paths as these conversions are not supported by Xbox One XDK return false; } #endif // Check for special cases switch ( sformat ) { case DXGI_FORMAT_R32G32B32A32_FLOAT: case DXGI_FORMAT_R32G32B32_FLOAT: case DXGI_FORMAT_R16G16B16A16_FLOAT: switch( tformat ) { case DXGI_FORMAT_R16_FLOAT: case DXGI_FORMAT_R32_FLOAT: case DXGI_FORMAT_D32_FLOAT: // WIC converts via UNORM formats and ends up converting colorspaces for these cases case DXGI_FORMAT_A8_UNORM: // Conversion logic for these kinds of textures is unintuitive for WIC code paths return false; } break; case DXGI_FORMAT_R16_FLOAT: switch( tformat ) { case DXGI_FORMAT_R32_FLOAT: case DXGI_FORMAT_D32_FLOAT: // WIC converts via UNORM formats and ends up converting colorspaces for these cases case DXGI_FORMAT_A8_UNORM: // Conversion logic for these kinds of textures is unintuitive for WIC code paths return false; } break; case DXGI_FORMAT_A8_UNORM: // Conversion logic for these kinds of textures is unintuitive for WIC code paths return false; default: switch( tformat ) { case DXGI_FORMAT_A8_UNORM: // Conversion logic for these kinds of textures is unintuitive for WIC code paths return false; } } // Check for implicit color space changes if ( IsSRGB( sformat ) ) filter |= TEX_FILTER_SRGB_IN; if ( IsSRGB( tformat ) ) filter |= TEX_FILTER_SRGB_OUT; if ( (filter & (TEX_FILTER_SRGB_IN|TEX_FILTER_SRGB_OUT)) == (TEX_FILTER_SRGB_IN|TEX_FILTER_SRGB_OUT) ) { filter &= ~(TEX_FILTER_SRGB_IN|TEX_FILTER_SRGB_OUT); } DWORD wicsrgb = _CheckWICColorSpace( pfGUID, targetGUID ); if ( wicsrgb != (filter & (TEX_FILTER_SRGB_IN|TEX_FILTER_SRGB_OUT)) ) { // WIC will perform a colorspace conversion we didn't request return false; } return true; } //------------------------------------------------------------------------------------- // Convert the source image using WIC //------------------------------------------------------------------------------------- static HRESULT _ConvertUsingWIC( _In_ const Image& srcImage, _In_ const WICPixelFormatGUID& pfGUID, _In_ const WICPixelFormatGUID& targetGUID, _In_ DWORD filter, _In_ float threshold, _In_ const Image& destImage ) { assert( srcImage.width == destImage.width ); assert( srcImage.height == destImage.height ); IWICImagingFactory* pWIC = _GetWIC(); if ( !pWIC ) return E_NOINTERFACE; ComPtr FC; HRESULT hr = pWIC->CreateFormatConverter( FC.GetAddressOf() ); if ( FAILED(hr) ) return hr; // Note that WIC conversion ignores the TEX_FILTER_SRGB_IN and TEX_FILTER_SRGB_OUT flags, // but also always assumes UNORM <-> FLOAT conversions are changing color spaces sRGB <-> scRGB BOOL canConvert = FALSE; hr = FC->CanConvert( pfGUID, targetGUID, &canConvert ); if ( FAILED(hr) || !canConvert ) { // This case is not an issue for the subset of WIC formats that map directly to DXGI return E_UNEXPECTED; } ComPtr source; hr = pWIC->CreateBitmapFromMemory( static_cast( srcImage.width ), static_cast( srcImage.height ), pfGUID, static_cast( srcImage.rowPitch ), static_cast( srcImage.slicePitch ), srcImage.pixels, source.GetAddressOf() ); if ( FAILED(hr) ) return hr; hr = FC->Initialize( source.Get(), targetGUID, _GetWICDither( filter ), 0, threshold * 100.f, WICBitmapPaletteTypeCustom ); if ( FAILED(hr) ) return hr; hr = FC->CopyPixels( 0, static_cast( destImage.rowPitch ), static_cast( destImage.slicePitch ), destImage.pixels ); if ( FAILED(hr) ) return hr; return S_OK; } //------------------------------------------------------------------------------------- // Convert the source image (not using WIC) //------------------------------------------------------------------------------------- static HRESULT _Convert( _In_ const Image& srcImage, _In_ DWORD filter, _In_ const Image& destImage, _In_ float threshold, _In_ size_t z ) { assert( srcImage.width == destImage.width ); assert( srcImage.height == destImage.height ); const uint8_t *pSrc = srcImage.pixels; uint8_t *pDest = destImage.pixels; if ( !pSrc || !pDest ) return E_POINTER; size_t width = srcImage.width; if ( filter & TEX_FILTER_DITHER_DIFFUSION ) { // Error diffusion dithering (aka Floyd-Steinberg dithering) ScopedAlignedArrayXMVECTOR scanline( reinterpret_cast( _aligned_malloc( (sizeof(XMVECTOR)*(width*2 + 2)), 16 ) ) ); if ( !scanline ) return E_OUTOFMEMORY; XMVECTOR* pDiffusionErrors = scanline.get() + width; memset( pDiffusionErrors, 0, sizeof(XMVECTOR)*(width+2) ); for( size_t h = 0; h < srcImage.height; ++h ) { if ( !_LoadScanline( scanline.get(), width, pSrc, srcImage.rowPitch, srcImage.format ) ) return E_FAIL; _ConvertScanline( scanline.get(), width, destImage.format, srcImage.format, filter ); if ( !_StoreScanlineDither( pDest, destImage.rowPitch, destImage.format, scanline.get(), width, threshold, h, z, pDiffusionErrors ) ) return E_FAIL; pSrc += srcImage.rowPitch; pDest += destImage.rowPitch; } } else { ScopedAlignedArrayXMVECTOR scanline( reinterpret_cast( _aligned_malloc( (sizeof(XMVECTOR)*width), 16 ) ) ); if ( !scanline ) return E_OUTOFMEMORY; if ( filter & TEX_FILTER_DITHER ) { // Ordered dithering for( size_t h = 0; h < srcImage.height; ++h ) { if ( !_LoadScanline( scanline.get(), width, pSrc, srcImage.rowPitch, srcImage.format ) ) return E_FAIL; _ConvertScanline( scanline.get(), width, destImage.format, srcImage.format, filter ); if ( !_StoreScanlineDither( pDest, destImage.rowPitch, destImage.format, scanline.get(), width, threshold, h, z, nullptr ) ) return E_FAIL; pSrc += srcImage.rowPitch; pDest += destImage.rowPitch; } } else { // No dithering for( size_t h = 0; h < srcImage.height; ++h ) { if ( !_LoadScanline( scanline.get(), width, pSrc, srcImage.rowPitch, srcImage.format ) ) return E_FAIL; _ConvertScanline( scanline.get(), width, destImage.format, srcImage.format, filter ); if ( !_StoreScanline( pDest, destImage.rowPitch, destImage.format, scanline.get(), width, threshold ) ) return E_FAIL; pSrc += srcImage.rowPitch; pDest += destImage.rowPitch; } } } return S_OK; } //------------------------------------------------------------------------------------- static DXGI_FORMAT _PlanarToSingle( _In_ DXGI_FORMAT format ) { switch (format) { case DXGI_FORMAT_NV12: case DXGI_FORMAT_NV11: return DXGI_FORMAT_YUY2; case DXGI_FORMAT_P010: return DXGI_FORMAT_Y210; case DXGI_FORMAT_P016: return DXGI_FORMAT_Y216; // We currently do not support conversion for Xbox One specific depth formats // We can't do anything with DXGI_FORMAT_420_OPAQUE because it's an opaque blob of bits default: return DXGI_FORMAT_UNKNOWN; } } //------------------------------------------------------------------------------------- // Convert the image from a planar to non-planar image //------------------------------------------------------------------------------------- #define CONVERT_420_TO_422( srcType, destType )\ {\ size_t rowPitch = srcImage.rowPitch;\ \ auto sourceE = reinterpret_cast( pSrc + srcImage.slicePitch );\ auto pSrcUV = pSrc + ( srcImage.height * rowPitch );\ \ for( size_t y = 0; y < srcImage.height; y+= 2 )\ {\ auto sPtrY0 = reinterpret_cast( pSrc );\ auto sPtrY2 = reinterpret_cast( pSrc + rowPitch );\ auto sPtrUV = reinterpret_cast( pSrcUV );\ \ destType * __restrict dPtr0 = reinterpret_cast(pDest);\ destType * __restrict dPtr1 = reinterpret_cast(pDest + destImage.rowPitch);\ \ for( size_t x = 0; x < srcImage.width; x+= 2 )\ {\ if ( (sPtrUV+1) >= sourceE ) break;\ \ srcType u = *(sPtrUV++);\ srcType v = *(sPtrUV++);\ \ dPtr0->x = *(sPtrY0++);\ dPtr0->y = u;\ dPtr0->z = *(sPtrY0++);\ dPtr0->w = v;\ ++dPtr0;\ \ dPtr1->x = *(sPtrY2++);\ dPtr1->y = u;\ dPtr1->z = *(sPtrY2++);\ dPtr1->w = v;\ ++dPtr1;\ }\ \ pSrc += rowPitch * 2;\ pSrcUV += rowPitch;\ \ pDest += destImage.rowPitch * 2;\ }\ } static HRESULT _ConvertToSinglePlane( _In_ const Image& srcImage, _In_ const Image& destImage ) { assert( srcImage.width == destImage.width ); assert( srcImage.height == destImage.height ); const uint8_t *pSrc = srcImage.pixels; uint8_t *pDest = destImage.pixels; if ( !pSrc || !pDest ) return E_POINTER; switch ( srcImage.format ) { case DXGI_FORMAT_NV12: assert( destImage.format == DXGI_FORMAT_YUY2 ); CONVERT_420_TO_422( uint8_t, XMUBYTEN4 ); return S_OK; case DXGI_FORMAT_P010: assert( destImage.format == DXGI_FORMAT_Y210 ); CONVERT_420_TO_422( uint16_t, XMUSHORTN4 ); return S_OK; case DXGI_FORMAT_P016: assert( destImage.format == DXGI_FORMAT_Y216 ); CONVERT_420_TO_422( uint16_t, XMUSHORTN4 ); return S_OK; case DXGI_FORMAT_NV11: assert( destImage.format == DXGI_FORMAT_YUY2 ); // Convert 4:1:1 to 4:2:2 { size_t rowPitch = srcImage.rowPitch; const uint8_t* sourceE = pSrc + srcImage.slicePitch; const uint8_t* pSrcUV = pSrc + ( srcImage.height * rowPitch ); for( size_t y = 0; y < srcImage.height; ++y ) { const uint8_t* sPtrY = pSrc; const uint8_t* sPtrUV = pSrcUV; XMUBYTEN4 * __restrict dPtr = reinterpret_cast(pDest); for( size_t x = 0; x < srcImage.width; x+= 4 ) { if ( (sPtrUV+1) >= sourceE ) break; uint8_t u = *(sPtrUV++); uint8_t v = *(sPtrUV++); dPtr->x = *(sPtrY++); dPtr->y = u; dPtr->z = *(sPtrY++); dPtr->w = v; ++dPtr; dPtr->x = *(sPtrY++); dPtr->y = u; dPtr->z = *(sPtrY++); dPtr->w = v; ++dPtr; } pSrc += rowPitch; pSrcUV += (rowPitch >> 1); pDest += destImage.rowPitch; } } return S_OK; default: return E_UNEXPECTED; } } #undef CONVERT_420_TO_422 //===================================================================================== // Entry-points //===================================================================================== //------------------------------------------------------------------------------------- // Convert image //------------------------------------------------------------------------------------- _Use_decl_annotations_ HRESULT Convert( const Image& srcImage, DXGI_FORMAT format, DWORD filter, float threshold, ScratchImage& image ) { if ( (srcImage.format == format) || !IsValid( format ) ) return E_INVALIDARG; if ( !srcImage.pixels ) return E_POINTER; if ( IsCompressed(srcImage.format) || IsCompressed(format) || IsPlanar(srcImage.format) || IsPlanar(format) || IsPalettized(srcImage.format) || IsPalettized(format) || IsTypeless(srcImage.format) || IsTypeless(format) ) return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); #ifdef _M_X64 if ( (srcImage.width > 0xFFFFFFFF) || (srcImage.height > 0xFFFFFFFF) ) return E_INVALIDARG; #endif HRESULT hr = image.Initialize2D( format, srcImage.width, srcImage.height, 1, 1 ); if ( FAILED(hr) ) return hr; const Image *rimage = image.GetImage( 0, 0, 0 ); if ( !rimage ) { image.Release(); return E_POINTER; } WICPixelFormatGUID pfGUID, targetGUID; if ( _UseWICConversion( filter, srcImage.format, format, pfGUID, targetGUID ) ) { hr = _ConvertUsingWIC( srcImage, pfGUID, targetGUID, filter, threshold, *rimage ); } else { hr = _Convert( srcImage, filter, *rimage, threshold, 0 ); } if ( FAILED(hr) ) { image.Release(); return hr; } return S_OK; } //------------------------------------------------------------------------------------- // Convert image (complex) //------------------------------------------------------------------------------------- _Use_decl_annotations_ HRESULT Convert( const Image* srcImages, size_t nimages, const TexMetadata& metadata, DXGI_FORMAT format, DWORD filter, float threshold, ScratchImage& result ) { if ( !srcImages || !nimages || (metadata.format == format) || !IsValid(format) ) return E_INVALIDARG; if ( IsCompressed(metadata.format) || IsCompressed(format) || IsPlanar(metadata.format) || IsPlanar(format) || IsPalettized(metadata.format) || IsPalettized(format) || IsTypeless(metadata.format) || IsTypeless(format) ) return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); #ifdef _M_X64 if ( (metadata.width > 0xFFFFFFFF) || (metadata.height > 0xFFFFFFFF) ) return E_INVALIDARG; #endif TexMetadata mdata2 = metadata; mdata2.format = format; HRESULT hr = result.Initialize( mdata2 ); if ( FAILED(hr) ) return hr; if ( nimages != result.GetImageCount() ) { result.Release(); return E_FAIL; } const Image* dest = result.GetImages(); if ( !dest ) { result.Release(); return E_POINTER; } WICPixelFormatGUID pfGUID, targetGUID; bool usewic = _UseWICConversion( filter, metadata.format, format, pfGUID, targetGUID ); switch (metadata.dimension) { case TEX_DIMENSION_TEXTURE1D: case TEX_DIMENSION_TEXTURE2D: for( size_t index=0; index < nimages; ++index ) { const Image& src = srcImages[ index ]; if ( src.format != metadata.format ) { result.Release(); return E_FAIL; } #ifdef _M_X64 if ( (src.width > 0xFFFFFFFF) || (src.height > 0xFFFFFFFF) ) return E_FAIL; #endif const Image& dst = dest[ index ]; assert( dst.format == format ); if ( src.width != dst.width || src.height != dst.height ) { result.Release(); return E_FAIL; } if ( usewic ) { hr = _ConvertUsingWIC( src, pfGUID, targetGUID, filter, threshold, dst ); } else { hr = _Convert( src, filter, dst, threshold, 0 ); } if ( FAILED(hr) ) { result.Release(); return hr; } } break; case TEX_DIMENSION_TEXTURE3D: { size_t index = 0; size_t d = metadata.depth; for( size_t level = 0; level < metadata.mipLevels; ++level ) { for( size_t slice = 0; slice < d; ++slice, ++index ) { if ( index >= nimages ) return E_FAIL; const Image& src = srcImages[ index ]; if ( src.format != metadata.format ) { result.Release(); return E_FAIL; } #ifdef _M_X64 if ( (src.width > 0xFFFFFFFF) || (src.height > 0xFFFFFFFF) ) return E_FAIL; #endif const Image& dst = dest[ index ]; assert( dst.format == format ); if ( src.width != dst.width || src.height != dst.height ) { result.Release(); return E_FAIL; } if ( usewic ) { hr = _ConvertUsingWIC( src, pfGUID, targetGUID, filter, threshold, dst ); } else { hr = _Convert( src, filter, dst, threshold, slice ); } if ( FAILED(hr) ) { result.Release(); return hr; } } if ( d > 1 ) d >>= 1; } } break; default: return E_FAIL; } return S_OK; } //------------------------------------------------------------------------------------- // Convert image from planar to single plane (image) //------------------------------------------------------------------------------------- _Use_decl_annotations_ HRESULT ConvertToSinglePlane( const Image& srcImage, ScratchImage& image ) { if ( !IsPlanar(srcImage.format) ) return E_INVALIDARG; if ( !srcImage.pixels ) return E_POINTER; DXGI_FORMAT format = _PlanarToSingle( srcImage.format ); if ( format == DXGI_FORMAT_UNKNOWN ) return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); #ifdef _M_X64 if ( (srcImage.width > 0xFFFFFFFF) || (srcImage.height > 0xFFFFFFFF) ) return E_INVALIDARG; #endif HRESULT hr = image.Initialize2D( format, srcImage.width, srcImage.height, 1, 1 ); if ( FAILED(hr) ) return hr; const Image *rimage = image.GetImage( 0, 0, 0 ); if ( !rimage ) { image.Release(); return E_POINTER; } hr = _ConvertToSinglePlane( srcImage, *rimage ); if ( FAILED(hr) ) { image.Release(); return hr; } return S_OK; } //------------------------------------------------------------------------------------- // Convert image from planar to single plane (complex) //------------------------------------------------------------------------------------- _Use_decl_annotations_ HRESULT ConvertToSinglePlane( const Image* srcImages, size_t nimages, const TexMetadata& metadata, ScratchImage& result ) { if ( !srcImages || !nimages ) return E_INVALIDARG; if ( metadata.IsVolumemap() ) { // Direct3D does not support any planar formats for Texture3D return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); } DXGI_FORMAT format = _PlanarToSingle( metadata.format ); if ( format == DXGI_FORMAT_UNKNOWN ) return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); #ifdef _M_X64 if ( (metadata.width > 0xFFFFFFFF) || (metadata.height > 0xFFFFFFFF) ) return E_INVALIDARG; #endif TexMetadata mdata2 = metadata; mdata2.format = format; HRESULT hr = result.Initialize( mdata2 ); if ( FAILED(hr) ) return hr; if ( nimages != result.GetImageCount() ) { result.Release(); return E_FAIL; } const Image* dest = result.GetImages(); if ( !dest ) { result.Release(); return E_POINTER; } for( size_t index=0; index < nimages; ++index ) { const Image& src = srcImages[ index ]; if ( src.format != metadata.format ) { result.Release(); return E_FAIL; } #ifdef _M_X64 if ( (src.width > 0xFFFFFFFF) || (src.height > 0xFFFFFFFF) ) return E_FAIL; #endif const Image& dst = dest[ index ]; assert( dst.format == format ); if ( src.width != dst.width || src.height != dst.height ) { result.Release(); return E_FAIL; } hr = _ConvertToSinglePlane( src, dst ); if ( FAILED(hr) ) { result.Release(); return hr; } } return S_OK; } }; // namespace ================================================ FILE: 3rdParty/DirectXTex/DirectXTex/DirectXTexD3D11.cpp ================================================ //------------------------------------------------------------------------------------- // DirectXTexD3D11.cpp // // DirectX Texture Library - Direct3D 11 helpers // // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A // PARTICULAR PURPOSE. // // Copyright (c) Microsoft Corporation. All rights reserved. // // http://go.microsoft.com/fwlink/?LinkId=248926 //------------------------------------------------------------------------------------- #include "directxtexp.h" #if !defined(_XBOX_ONE) || !defined(_TITLE) #include #endif using Microsoft::WRL::ComPtr; namespace DirectX { static HRESULT _Capture( _In_ ID3D11DeviceContext* pContext, _In_ ID3D11Resource* pSource, _In_ const TexMetadata& metadata, _In_ const ScratchImage& result ) { if ( !pContext || !pSource || !result.GetPixels() ) return E_POINTER; #if defined(_XBOX_ONE) && defined(_TITLE) ComPtr d3dDevice; pContext->GetDevice( d3dDevice.GetAddressOf() ); if ( d3dDevice->GetCreationFlags() & D3D11_CREATE_DEVICE_IMMEDIATE_CONTEXT_FAST_SEMANTICS ) { ComPtr d3dDeviceX; HRESULT hr = d3dDevice.As( &d3dDeviceX ); if ( FAILED(hr) ) return hr; ComPtr d3dContextX; hr = pContext->QueryInterface( __uuidof(ID3D11DeviceContextX), reinterpret_cast( d3dContextX.GetAddressOf() ) ); if ( FAILED(hr) ) return hr; UINT64 copyFence = d3dContextX->InsertFence(0); while ( d3dDeviceX->IsFencePending( copyFence ) ) { SwitchToThread(); } } #endif if ( metadata.IsVolumemap() ) { //--- Volume texture ---------------------------------------------------------- assert( metadata.arraySize == 1 ); size_t height = metadata.height; size_t depth = metadata.depth; for( size_t level = 0; level < metadata.mipLevels; ++level ) { UINT dindex = D3D11CalcSubresource( static_cast( level ), 0, static_cast( metadata.mipLevels ) ); D3D11_MAPPED_SUBRESOURCE mapped; HRESULT hr = pContext->Map( pSource, dindex, D3D11_MAP_READ, 0, &mapped ); if ( FAILED(hr) ) return hr; auto pslice = reinterpret_cast( mapped.pData ); if ( !pslice ) { pContext->Unmap( pSource, dindex ); return E_POINTER; } size_t lines = ComputeScanlines( metadata.format, height ); if ( !lines ) { pContext->Unmap( pSource, dindex ); return E_UNEXPECTED; } for( size_t slice = 0; slice < depth; ++slice ) { const Image* img = result.GetImage( level, 0, slice ); if ( !img ) { pContext->Unmap( pSource, dindex ); return E_FAIL; } if ( !img->pixels ) { pContext->Unmap( pSource, dindex ); return E_POINTER; } const uint8_t* sptr = pslice; uint8_t* dptr = img->pixels; for( size_t h = 0; h < lines; ++h ) { size_t msize = std::min( img->rowPitch, mapped.RowPitch ); memcpy_s( dptr, img->rowPitch, sptr, msize ); sptr += mapped.RowPitch; dptr += img->rowPitch; } pslice += mapped.DepthPitch; } pContext->Unmap( pSource, dindex ); if ( height > 1 ) height >>= 1; if ( depth > 1 ) depth >>= 1; } } else { //--- 1D or 2D texture -------------------------------------------------------- assert( metadata.depth == 1 ); for( size_t item = 0; item < metadata.arraySize; ++item ) { size_t height = metadata.height; for( size_t level = 0; level < metadata.mipLevels; ++level ) { UINT dindex = D3D11CalcSubresource( static_cast( level ), static_cast( item ), static_cast( metadata.mipLevels ) ); D3D11_MAPPED_SUBRESOURCE mapped; HRESULT hr = pContext->Map( pSource, dindex, D3D11_MAP_READ, 0, &mapped ); if ( FAILED(hr) ) return hr; const Image* img = result.GetImage( level, item, 0 ); if ( !img ) { pContext->Unmap( pSource, dindex ); return E_FAIL; } if ( !img->pixels ) { pContext->Unmap( pSource, dindex ); return E_POINTER; } size_t lines = ComputeScanlines( metadata.format, height ); if ( !lines ) { pContext->Unmap( pSource, dindex ); return E_UNEXPECTED; } auto sptr = reinterpret_cast( mapped.pData ); uint8_t* dptr = img->pixels; for( size_t h = 0; h < lines; ++h ) { size_t msize = std::min( img->rowPitch, mapped.RowPitch ); memcpy_s( dptr, img->rowPitch, sptr, msize ); sptr += mapped.RowPitch; dptr += img->rowPitch; } pContext->Unmap( pSource, dindex ); if ( height > 1 ) height >>= 1; } } } return S_OK; } //===================================================================================== // Entry-points //===================================================================================== //------------------------------------------------------------------------------------- // Determine if given texture metadata is supported on the given device //------------------------------------------------------------------------------------- _Use_decl_annotations_ bool IsSupportedTexture( ID3D11Device* pDevice, const TexMetadata& metadata ) { if ( !pDevice ) return false; D3D_FEATURE_LEVEL fl = pDevice->GetFeatureLevel(); // Validate format DXGI_FORMAT fmt = metadata.format; if ( !IsValid( fmt ) ) return false; switch( fmt ) { case DXGI_FORMAT_BC4_TYPELESS: case DXGI_FORMAT_BC4_UNORM: case DXGI_FORMAT_BC4_SNORM: case DXGI_FORMAT_BC5_TYPELESS: case DXGI_FORMAT_BC5_UNORM: case DXGI_FORMAT_BC5_SNORM: if ( fl < D3D_FEATURE_LEVEL_10_0 ) return false; break; case DXGI_FORMAT_BC6H_TYPELESS: case DXGI_FORMAT_BC6H_UF16: case DXGI_FORMAT_BC6H_SF16: case DXGI_FORMAT_BC7_TYPELESS: case DXGI_FORMAT_BC7_UNORM: case DXGI_FORMAT_BC7_UNORM_SRGB: if ( fl < D3D_FEATURE_LEVEL_11_0 ) return false; break; } // Validate miplevel count if ( metadata.mipLevels > D3D11_REQ_MIP_LEVELS ) return false; // Validate array size, dimension, and width/height size_t arraySize = metadata.arraySize; size_t iWidth = metadata.width; size_t iHeight = metadata.height; size_t iDepth = metadata.depth; // Most cases are known apriori based on feature level, but we use this for robustness to handle the few optional cases UINT formatSupport = 0; HRESULT hr = pDevice->CheckFormatSupport( fmt, &formatSupport ); if ( FAILED(hr) ) { formatSupport = 0; } switch ( metadata.dimension ) { case TEX_DIMENSION_TEXTURE1D: if ( !(formatSupport & D3D11_FORMAT_SUPPORT_TEXTURE1D) ) return false; if ( (arraySize > D3D11_REQ_TEXTURE1D_ARRAY_AXIS_DIMENSION) || (iWidth > D3D11_REQ_TEXTURE1D_U_DIMENSION) ) return false; if ( fl < D3D_FEATURE_LEVEL_11_0 ) { if ( (arraySize > D3D10_REQ_TEXTURE1D_ARRAY_AXIS_DIMENSION) || (iWidth > D3D10_REQ_TEXTURE1D_U_DIMENSION) ) return false; if ( fl < D3D_FEATURE_LEVEL_10_0 ) { if ( (arraySize > 1) || (iWidth > D3D_FL9_3_REQ_TEXTURE1D_U_DIMENSION) ) return false; if ( (fl < D3D_FEATURE_LEVEL_9_3) && (iWidth > D3D_FL9_1_REQ_TEXTURE1D_U_DIMENSION ) ) return false; } } break; case TEX_DIMENSION_TEXTURE2D: if ( metadata.IsCubemap() ) { if ( !(formatSupport & D3D11_FORMAT_SUPPORT_TEXTURECUBE) ) return false; if ( (arraySize > D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION) || (iWidth > D3D11_REQ_TEXTURECUBE_DIMENSION) || (iHeight > D3D11_REQ_TEXTURECUBE_DIMENSION)) return false; if ( fl < D3D_FEATURE_LEVEL_11_0 ) { if ( (arraySize > D3D10_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION) || (iWidth > D3D10_REQ_TEXTURECUBE_DIMENSION) || (iHeight > D3D10_REQ_TEXTURECUBE_DIMENSION)) return false; if ( (fl < D3D_FEATURE_LEVEL_10_1) && (arraySize != 6) ) return false; if ( fl < D3D_FEATURE_LEVEL_10_0 ) { if ( (iWidth > D3D_FL9_3_REQ_TEXTURECUBE_DIMENSION ) || (iHeight > D3D_FL9_3_REQ_TEXTURECUBE_DIMENSION ) ) return false; if ( (fl < D3D_FEATURE_LEVEL_9_3) && ( (iWidth > D3D_FL9_1_REQ_TEXTURECUBE_DIMENSION) || (iHeight > D3D_FL9_1_REQ_TEXTURECUBE_DIMENSION) ) ) return false; } } } else // Not a cube map { if ( !(formatSupport & D3D11_FORMAT_SUPPORT_TEXTURE2D) ) return false; if ( (arraySize > D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION) || (iWidth > D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION) || (iHeight > D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION)) return false; if ( fl < D3D_FEATURE_LEVEL_11_0 ) { if ( (arraySize > D3D10_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION) || (iWidth > D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION) || (iHeight > D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION)) return false; if ( fl < D3D_FEATURE_LEVEL_10_0 ) { if ( (arraySize > 1) || (iWidth > D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION) || (iHeight > D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION) ) return false; if ( (fl < D3D_FEATURE_LEVEL_9_3) && ( (iWidth > D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION) || (iHeight > D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION) ) ) return false; } } } break; case TEX_DIMENSION_TEXTURE3D: if ( !(formatSupport & D3D11_FORMAT_SUPPORT_TEXTURE3D) ) return false; if ( (arraySize > 1) || (iWidth > D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION) || (iHeight > D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION) || (iDepth > D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION) ) return false; if ( fl < D3D_FEATURE_LEVEL_11_0 ) { if ( (iWidth > D3D10_REQ_TEXTURE3D_U_V_OR_W_DIMENSION) || (iHeight > D3D10_REQ_TEXTURE3D_U_V_OR_W_DIMENSION) || (iDepth > D3D10_REQ_TEXTURE3D_U_V_OR_W_DIMENSION) ) return false; if ( fl < D3D_FEATURE_LEVEL_10_0 ) { if ( (iWidth > D3D_FL9_1_REQ_TEXTURE3D_U_V_OR_W_DIMENSION) || (iHeight > D3D_FL9_1_REQ_TEXTURE3D_U_V_OR_W_DIMENSION) || (iDepth > D3D_FL9_1_REQ_TEXTURE3D_U_V_OR_W_DIMENSION) ) return false; } } break; default: // Not a supported dimension return false; } return true; } //------------------------------------------------------------------------------------- // Create a texture resource //------------------------------------------------------------------------------------- _Use_decl_annotations_ HRESULT CreateTexture( ID3D11Device* pDevice, const Image* srcImages, size_t nimages, const TexMetadata& metadata, ID3D11Resource** ppResource ) { return CreateTextureEx( pDevice, srcImages, nimages, metadata, D3D11_USAGE_DEFAULT, D3D11_BIND_SHADER_RESOURCE, 0, 0, false, ppResource ); } _Use_decl_annotations_ HRESULT CreateTextureEx( ID3D11Device* pDevice, const Image* srcImages, size_t nimages, const TexMetadata& metadata, D3D11_USAGE usage, unsigned int bindFlags, unsigned int cpuAccessFlags, unsigned int miscFlags, bool forceSRGB, ID3D11Resource** ppResource ) { if ( !pDevice || !srcImages || !nimages || !ppResource ) return E_INVALIDARG; *ppResource = nullptr; if ( !metadata.mipLevels || !metadata.arraySize ) return E_INVALIDARG; #ifdef _M_X64 if ( (metadata.width > 0xFFFFFFFF) || (metadata.height > 0xFFFFFFFF) || (metadata.mipLevels > 0xFFFFFFFF) || (metadata.arraySize > 0xFFFFFFFF) ) return E_INVALIDARG; #endif std::unique_ptr initData( new (std::nothrow) D3D11_SUBRESOURCE_DATA[ metadata.mipLevels * metadata.arraySize ] ); if ( !initData ) return E_OUTOFMEMORY; // Fill out subresource array if ( metadata.IsVolumemap() ) { //--- Volume case ------------------------------------------------------------- if ( !metadata.depth ) return E_INVALIDARG; #ifdef _M_X64 if ( metadata.depth > 0xFFFFFFFF ) return E_INVALIDARG; #endif if ( metadata.arraySize > 1 ) // Direct3D 11 doesn't support arrays of 3D textures return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); size_t depth = metadata.depth; size_t idx = 0; for( size_t level = 0; level < metadata.mipLevels; ++level ) { size_t index = metadata.ComputeIndex( level, 0, 0 ); if ( index >= nimages ) return E_FAIL; const Image& img = srcImages[ index ]; if ( img.format != metadata.format ) return E_FAIL; if ( !img.pixels ) return E_POINTER; // Verify pixels in image 1 .. (depth-1) are exactly image->slicePitch apart // For 3D textures, this relies on all slices of the same miplevel being continous in memory // (this is how ScratchImage lays them out), which is why we just give the 0th slice to Direct3D 11 const uint8_t* pSlice = img.pixels + img.slicePitch; for( size_t slice = 1; slice < depth; ++slice ) { size_t tindex = metadata.ComputeIndex( level, 0, slice ); if ( tindex >= nimages ) return E_FAIL; const Image& timg = srcImages[ tindex ]; if ( !timg.pixels ) return E_POINTER; if ( timg.pixels != pSlice || timg.format != metadata.format || timg.rowPitch != img.rowPitch || timg.slicePitch != img.slicePitch ) return E_FAIL; pSlice = timg.pixels + img.slicePitch; } assert( idx < (metadata.mipLevels * metadata.arraySize) ); initData[idx].pSysMem = img.pixels; initData[idx].SysMemPitch = static_cast( img.rowPitch ); initData[idx].SysMemSlicePitch = static_cast( img.slicePitch ); ++idx; if ( depth > 1 ) depth >>= 1; } } else { //--- 1D or 2D texture case --------------------------------------------------- size_t idx = 0; for( size_t item = 0; item < metadata.arraySize; ++item ) { for( size_t level = 0; level < metadata.mipLevels; ++level ) { size_t index = metadata.ComputeIndex( level, item, 0 ); if ( index >= nimages ) return E_FAIL; const Image& img = srcImages[ index ]; if ( img.format != metadata.format ) return E_FAIL; if ( !img.pixels ) return E_POINTER; assert( idx < (metadata.mipLevels * metadata.arraySize) ); initData[idx].pSysMem = img.pixels; initData[idx].SysMemPitch = static_cast( img.rowPitch ); initData[idx].SysMemSlicePitch = static_cast( img.slicePitch ); ++idx; } } } // Create texture using static initialization data HRESULT hr = E_FAIL; DXGI_FORMAT tformat = ( forceSRGB ) ? MakeSRGB( metadata.format ) : metadata.format; switch ( metadata.dimension ) { case TEX_DIMENSION_TEXTURE1D: { D3D11_TEXTURE1D_DESC desc; desc.Width = static_cast( metadata.width ); desc.MipLevels = static_cast( metadata.mipLevels ); desc.ArraySize = static_cast( metadata.arraySize ); desc.Format = tformat; desc.Usage = usage; desc.BindFlags = bindFlags; desc.CPUAccessFlags = cpuAccessFlags; desc.MiscFlags = miscFlags & ~D3D11_RESOURCE_MISC_TEXTURECUBE; hr = pDevice->CreateTexture1D( &desc, initData.get(), reinterpret_cast(ppResource) ); } break; case TEX_DIMENSION_TEXTURE2D: { D3D11_TEXTURE2D_DESC desc; desc.Width = static_cast( metadata.width ); desc.Height = static_cast( metadata.height ); desc.MipLevels = static_cast( metadata.mipLevels ); desc.ArraySize = static_cast( metadata.arraySize ); desc.Format = tformat; desc.SampleDesc.Count = 1; desc.SampleDesc.Quality = 0; desc.Usage = usage; desc.BindFlags = bindFlags; desc.CPUAccessFlags = cpuAccessFlags; if ( metadata.IsCubemap() ) desc.MiscFlags = miscFlags | D3D11_RESOURCE_MISC_TEXTURECUBE; else desc.MiscFlags = miscFlags & ~D3D11_RESOURCE_MISC_TEXTURECUBE; hr = pDevice->CreateTexture2D( &desc, initData.get(), reinterpret_cast(ppResource) ); } break; case TEX_DIMENSION_TEXTURE3D: { D3D11_TEXTURE3D_DESC desc; desc.Width = static_cast( metadata.width ); desc.Height = static_cast( metadata.height ); desc.Depth = static_cast( metadata.depth ); desc.MipLevels = static_cast( metadata.mipLevels ); desc.Format = tformat; desc.Usage = usage; desc.BindFlags = bindFlags; desc.CPUAccessFlags = cpuAccessFlags; desc.MiscFlags = miscFlags & ~D3D11_RESOURCE_MISC_TEXTURECUBE; hr = pDevice->CreateTexture3D( &desc, initData.get(), reinterpret_cast(ppResource) ); } break; } return hr; } //------------------------------------------------------------------------------------- // Create a shader resource view and associated texture //------------------------------------------------------------------------------------- _Use_decl_annotations_ HRESULT CreateShaderResourceView( ID3D11Device* pDevice, const Image* srcImages, size_t nimages, const TexMetadata& metadata, ID3D11ShaderResourceView** ppSRV ) { return CreateShaderResourceViewEx( pDevice, srcImages, nimages, metadata, D3D11_USAGE_DEFAULT, D3D11_BIND_SHADER_RESOURCE, 0, 0, false, ppSRV ); } _Use_decl_annotations_ HRESULT CreateShaderResourceViewEx( ID3D11Device* pDevice, const Image* srcImages, size_t nimages, const TexMetadata& metadata, D3D11_USAGE usage, unsigned int bindFlags, unsigned int cpuAccessFlags, unsigned int miscFlags, bool forceSRGB, ID3D11ShaderResourceView** ppSRV ) { if ( !ppSRV ) return E_INVALIDARG; *ppSRV = nullptr; ComPtr resource; HRESULT hr = CreateTextureEx( pDevice, srcImages, nimages, metadata, usage, bindFlags, cpuAccessFlags, miscFlags, forceSRGB, resource.GetAddressOf() ); if ( FAILED(hr) ) return hr; assert( resource ); D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc; memset( &SRVDesc, 0, sizeof(SRVDesc) ); if ( forceSRGB ) SRVDesc.Format = MakeSRGB( metadata.format ); else SRVDesc.Format = metadata.format; switch ( metadata.dimension ) { case TEX_DIMENSION_TEXTURE1D: if ( metadata.arraySize > 1 ) { SRVDesc.ViewDimension = D3D_SRV_DIMENSION_TEXTURE1DARRAY; SRVDesc.Texture1DArray.MipLevels = static_cast( metadata.mipLevels ); SRVDesc.Texture1DArray.ArraySize = static_cast( metadata.arraySize ); } else { SRVDesc.ViewDimension = D3D_SRV_DIMENSION_TEXTURE1D; SRVDesc.Texture1D.MipLevels = static_cast( metadata.mipLevels ); } break; case TEX_DIMENSION_TEXTURE2D: if ( metadata.IsCubemap() ) { if (metadata.arraySize > 6) { assert( (metadata.arraySize % 6) == 0 ); SRVDesc.ViewDimension = D3D_SRV_DIMENSION_TEXTURECUBEARRAY; SRVDesc.TextureCubeArray.MipLevels = static_cast( metadata.mipLevels ); SRVDesc.TextureCubeArray.NumCubes = static_cast( metadata.arraySize / 6 ); } else { SRVDesc.ViewDimension = D3D_SRV_DIMENSION_TEXTURECUBE; SRVDesc.TextureCube.MipLevels = static_cast( metadata.mipLevels ); } } else if ( metadata.arraySize > 1 ) { SRVDesc.ViewDimension = D3D_SRV_DIMENSION_TEXTURE2DARRAY; SRVDesc.Texture2DArray.MipLevels = static_cast( metadata.mipLevels ); SRVDesc.Texture2DArray.ArraySize = static_cast( metadata.arraySize ); } else { SRVDesc.ViewDimension = D3D_SRV_DIMENSION_TEXTURE2D; SRVDesc.Texture2D.MipLevels = static_cast( metadata.mipLevels ); } break; case TEX_DIMENSION_TEXTURE3D: assert( metadata.arraySize == 1 ); SRVDesc.ViewDimension = D3D_SRV_DIMENSION_TEXTURE3D; SRVDesc.Texture3D.MipLevels = static_cast( metadata.mipLevels ); break; default: return E_FAIL; } hr = pDevice->CreateShaderResourceView( resource.Get(), &SRVDesc, ppSRV ); if ( FAILED(hr) ) return hr; assert( *ppSRV ); return S_OK; } //------------------------------------------------------------------------------------- // Save a texture resource to a DDS file in memory/on disk //------------------------------------------------------------------------------------- _Use_decl_annotations_ HRESULT CaptureTexture( ID3D11Device* pDevice, ID3D11DeviceContext* pContext, ID3D11Resource* pSource, ScratchImage& result ) { if ( !pDevice || !pContext || !pSource ) return E_INVALIDARG; D3D11_RESOURCE_DIMENSION resType = D3D11_RESOURCE_DIMENSION_UNKNOWN; pSource->GetType( &resType ); HRESULT hr; switch( resType ) { case D3D11_RESOURCE_DIMENSION_TEXTURE1D: { ComPtr pTexture; hr = pSource->QueryInterface( __uuidof(ID3D11Texture1D), reinterpret_cast( pTexture.GetAddressOf() ) ); if ( FAILED(hr) ) break; assert( pTexture ); D3D11_TEXTURE1D_DESC desc; pTexture->GetDesc( &desc ); desc.BindFlags = 0; desc.MiscFlags = 0; desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; desc.Usage = D3D11_USAGE_STAGING; ComPtr pStaging; hr = pDevice->CreateTexture1D( &desc, 0, pStaging.GetAddressOf() ); if ( FAILED(hr) ) break; assert( pStaging ); pContext->CopyResource( pStaging.Get(), pSource ); TexMetadata mdata; mdata.width = desc.Width; mdata.height = mdata.depth = 1; mdata.arraySize = desc.ArraySize; mdata.mipLevels = desc.MipLevels; mdata.miscFlags = 0; mdata.miscFlags2 = 0; mdata.format = desc.Format; mdata.dimension = TEX_DIMENSION_TEXTURE1D; hr = result.Initialize( mdata ); if ( FAILED(hr) ) break; hr = _Capture( pContext, pStaging.Get(), mdata, result ); } break; case D3D11_RESOURCE_DIMENSION_TEXTURE2D: { ComPtr pTexture; hr = pSource->QueryInterface( __uuidof(ID3D11Texture2D), reinterpret_cast( pTexture.GetAddressOf() ) ); if ( FAILED(hr) ) break; assert( pTexture ); D3D11_TEXTURE2D_DESC desc; pTexture->GetDesc( &desc ); ComPtr pStaging; if ( desc.SampleDesc.Count > 1 ) { desc.SampleDesc.Count = 1; desc.SampleDesc.Quality = 0; ComPtr pTemp; hr = pDevice->CreateTexture2D( &desc, 0, pTemp.GetAddressOf() ); if ( FAILED(hr) ) break; assert( pTemp ); DXGI_FORMAT fmt = desc.Format; if ( IsTypeless(fmt) ) { // Assume a UNORM if it exists otherwise use FLOAT fmt = MakeTypelessUNORM( fmt ); fmt = MakeTypelessFLOAT( fmt ); } UINT support = 0; hr = pDevice->CheckFormatSupport( fmt, &support ); if ( FAILED(hr) ) break; if ( !(support & D3D11_FORMAT_SUPPORT_MULTISAMPLE_RESOLVE) ) { hr = E_FAIL; break; } for( UINT item = 0; item < desc.ArraySize; ++item ) { for( UINT level = 0; level < desc.MipLevels; ++level ) { UINT index = D3D11CalcSubresource( level, item, desc.MipLevels ); pContext->ResolveSubresource( pTemp.Get(), index, pSource, index, fmt ); } } desc.BindFlags = 0; desc.MiscFlags &= D3D11_RESOURCE_MISC_TEXTURECUBE; desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; desc.Usage = D3D11_USAGE_STAGING; hr = pDevice->CreateTexture2D( &desc, 0, pStaging.GetAddressOf() ); if ( FAILED(hr) ) break; assert( pStaging ); pContext->CopyResource( pStaging.Get(), pTemp.Get() ); } else { desc.BindFlags = 0; desc.MiscFlags &= D3D11_RESOURCE_MISC_TEXTURECUBE; desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; desc.Usage = D3D11_USAGE_STAGING; hr = pDevice->CreateTexture2D( &desc, 0, &pStaging ); if ( FAILED(hr) ) break; assert( pStaging ); pContext->CopyResource( pStaging.Get(), pSource ); } TexMetadata mdata; mdata.width = desc.Width; mdata.height = desc.Height; mdata.depth = 1; mdata.arraySize = desc.ArraySize; mdata.mipLevels = desc.MipLevels; mdata.miscFlags = (desc.MiscFlags & D3D11_RESOURCE_MISC_TEXTURECUBE) ? TEX_MISC_TEXTURECUBE : 0; mdata.miscFlags2 = 0; mdata.format = desc.Format; mdata.dimension = TEX_DIMENSION_TEXTURE2D; hr = result.Initialize( mdata ); if ( FAILED(hr) ) break; hr = _Capture( pContext, pStaging.Get(), mdata, result ); } break; case D3D11_RESOURCE_DIMENSION_TEXTURE3D: { ComPtr pTexture; hr = pSource->QueryInterface( __uuidof(ID3D11Texture3D), reinterpret_cast( pTexture.GetAddressOf() ) ); if ( FAILED(hr) ) break; assert( pTexture ); D3D11_TEXTURE3D_DESC desc; pTexture->GetDesc( &desc ); desc.BindFlags = 0; desc.MiscFlags = 0; desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; desc.Usage = D3D11_USAGE_STAGING; ComPtr pStaging; hr = pDevice->CreateTexture3D( &desc, 0, pStaging.GetAddressOf() ); if ( FAILED(hr) ) break; assert( pStaging ); pContext->CopyResource( pStaging.Get(), pSource ); TexMetadata mdata; mdata.width = desc.Width; mdata.height = desc.Height; mdata.depth = desc.Depth; mdata.arraySize = 1; mdata.mipLevels = desc.MipLevels; mdata.miscFlags = 0; mdata.miscFlags2 = 0; mdata.format = desc.Format; mdata.dimension = TEX_DIMENSION_TEXTURE3D; hr = result.Initialize( mdata ); if ( FAILED(hr) ) break; hr = _Capture( pContext, pStaging.Get(), mdata, result ); } break; default: hr = E_FAIL; break; } if ( FAILED(hr) ) { result.Release(); return hr; } return S_OK; } }; // namespace ================================================ FILE: 3rdParty/DirectXTex/DirectXTex/DirectXTexDDS.cpp ================================================ //------------------------------------------------------------------------------------- // DirectXTexDDS.cpp // // DirectX Texture Library - Microsoft DirectDraw Surface (DDS) file format reader/writer // // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A // PARTICULAR PURPOSE. // // Copyright (c) Microsoft Corporation. All rights reserved. // // http://go.microsoft.com/fwlink/?LinkId=248926 //------------------------------------------------------------------------------------- #include "directxtexp.h" #include "dds.h" namespace DirectX { //------------------------------------------------------------------------------------- // Legacy format mapping table (used for DDS files without 'DX10' extended header) //------------------------------------------------------------------------------------- enum CONVERSION_FLAGS { CONV_FLAGS_NONE = 0x0, CONV_FLAGS_EXPAND = 0x1, // Conversion requires expanded pixel size CONV_FLAGS_NOALPHA = 0x2, // Conversion requires setting alpha to known value CONV_FLAGS_SWIZZLE = 0x4, // BGR/RGB order swizzling required CONV_FLAGS_PAL8 = 0x8, // Has an 8-bit palette CONV_FLAGS_888 = 0x10, // Source is an 8:8:8 (24bpp) format CONV_FLAGS_565 = 0x20, // Source is a 5:6:5 (16bpp) format CONV_FLAGS_5551 = 0x40, // Source is a 5:5:5:1 (16bpp) format CONV_FLAGS_4444 = 0x80, // Source is a 4:4:4:4 (16bpp) format CONV_FLAGS_44 = 0x100, // Source is a 4:4 (8bpp) format CONV_FLAGS_332 = 0x200, // Source is a 3:3:2 (8bpp) format CONV_FLAGS_8332 = 0x400, // Source is a 8:3:3:2 (16bpp) format CONV_FLAGS_A8P8 = 0x800, // Has an 8-bit palette with an alpha channel CONV_FLAGS_DX10 = 0x10000, // Has the 'DX10' extension header CONV_FLAGS_PMALPHA = 0x20000, // Contains premultiplied alpha data CONV_FLAGS_L8 = 0x40000, // Source is a 8 luminance format CONV_FLAGS_L16 = 0x80000, // Source is a 16 luminance format CONV_FLAGS_A8L8 = 0x100000, // Source is a 8:8 luminance format }; struct LegacyDDS { DXGI_FORMAT format; DWORD convFlags; DDS_PIXELFORMAT ddpf; }; const LegacyDDS g_LegacyDDSMap[] = { { DXGI_FORMAT_BC1_UNORM, CONV_FLAGS_NONE, DDSPF_DXT1 }, // D3DFMT_DXT1 { DXGI_FORMAT_BC2_UNORM, CONV_FLAGS_NONE, DDSPF_DXT3 }, // D3DFMT_DXT3 { DXGI_FORMAT_BC3_UNORM, CONV_FLAGS_NONE, DDSPF_DXT5 }, // D3DFMT_DXT5 { DXGI_FORMAT_BC2_UNORM, CONV_FLAGS_PMALPHA, DDSPF_DXT2 }, // D3DFMT_DXT2 { DXGI_FORMAT_BC3_UNORM, CONV_FLAGS_PMALPHA, DDSPF_DXT4 }, // D3DFMT_DXT4 { DXGI_FORMAT_BC4_UNORM, CONV_FLAGS_NONE, DDSPF_BC4_UNORM }, { DXGI_FORMAT_BC4_SNORM, CONV_FLAGS_NONE, DDSPF_BC4_SNORM }, { DXGI_FORMAT_BC5_UNORM, CONV_FLAGS_NONE, DDSPF_BC5_UNORM }, { DXGI_FORMAT_BC5_SNORM, CONV_FLAGS_NONE, DDSPF_BC5_SNORM }, { DXGI_FORMAT_BC4_UNORM, CONV_FLAGS_NONE, { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC( 'A', 'T', 'I', '1' ), 0, 0, 0, 0, 0 } }, { DXGI_FORMAT_BC5_UNORM, CONV_FLAGS_NONE, { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC( 'A', 'T', 'I', '2' ), 0, 0, 0, 0, 0 } }, { DXGI_FORMAT_R8G8_B8G8_UNORM, CONV_FLAGS_NONE, DDSPF_R8G8_B8G8 }, // D3DFMT_R8G8_B8G8 { DXGI_FORMAT_G8R8_G8B8_UNORM, CONV_FLAGS_NONE, DDSPF_G8R8_G8B8 }, // D3DFMT_G8R8_G8B8 { DXGI_FORMAT_B8G8R8A8_UNORM, CONV_FLAGS_NONE, DDSPF_A8R8G8B8 }, // D3DFMT_A8R8G8B8 (uses DXGI 1.1 format) { DXGI_FORMAT_B8G8R8X8_UNORM, CONV_FLAGS_NONE, DDSPF_X8R8G8B8 }, // D3DFMT_X8R8G8B8 (uses DXGI 1.1 format) { DXGI_FORMAT_R8G8B8A8_UNORM, CONV_FLAGS_NONE, DDSPF_A8B8G8R8 }, // D3DFMT_A8B8G8R8 { DXGI_FORMAT_R8G8B8A8_UNORM, CONV_FLAGS_NOALPHA, DDSPF_X8B8G8R8 }, // D3DFMT_X8B8G8R8 { DXGI_FORMAT_R16G16_UNORM, CONV_FLAGS_NONE, DDSPF_G16R16 }, // D3DFMT_G16R16 { DXGI_FORMAT_R10G10B10A2_UNORM, CONV_FLAGS_SWIZZLE, { sizeof(DDS_PIXELFORMAT), DDS_RGB, 0, 32, 0x000003ff, 0x000ffc00, 0x3ff00000, 0xc0000000 } }, // D3DFMT_A2R10G10B10 (D3DX reversal issue workaround) { DXGI_FORMAT_R10G10B10A2_UNORM, CONV_FLAGS_NONE, { sizeof(DDS_PIXELFORMAT), DDS_RGB, 0, 32, 0x3ff00000, 0x000ffc00, 0x000003ff, 0xc0000000 } }, // D3DFMT_A2B10G10R10 (D3DX reversal issue workaround) { DXGI_FORMAT_R8G8B8A8_UNORM, CONV_FLAGS_EXPAND | CONV_FLAGS_NOALPHA | CONV_FLAGS_888, DDSPF_R8G8B8 }, // D3DFMT_R8G8B8 { DXGI_FORMAT_B5G6R5_UNORM, CONV_FLAGS_565, DDSPF_R5G6B5 }, // D3DFMT_R5G6B5 { DXGI_FORMAT_B5G5R5A1_UNORM, CONV_FLAGS_5551, DDSPF_A1R5G5B5 }, // D3DFMT_A1R5G5B5 { DXGI_FORMAT_B5G5R5A1_UNORM, CONV_FLAGS_5551 | CONV_FLAGS_NOALPHA, { sizeof(DDS_PIXELFORMAT), DDS_RGB, 0, 16, 0x7c00, 0x03e0, 0x001f, 0x0000 } }, // D3DFMT_X1R5G5B5 { DXGI_FORMAT_R8G8B8A8_UNORM, CONV_FLAGS_EXPAND | CONV_FLAGS_8332, { sizeof(DDS_PIXELFORMAT), DDS_RGB, 0, 16, 0x00e0, 0x001c, 0x0003, 0xff00 } }, // D3DFMT_A8R3G3B2 { DXGI_FORMAT_B5G6R5_UNORM, CONV_FLAGS_EXPAND | CONV_FLAGS_332, { sizeof(DDS_PIXELFORMAT), DDS_RGB, 0, 8, 0xe0, 0x1c, 0x03, 0x00 } }, // D3DFMT_R3G3B2 { DXGI_FORMAT_R8_UNORM, CONV_FLAGS_NONE, DDSPF_L8 }, // D3DFMT_L8 { DXGI_FORMAT_R16_UNORM, CONV_FLAGS_NONE, DDSPF_L16 }, // D3DFMT_L16 { DXGI_FORMAT_R8G8_UNORM, CONV_FLAGS_NONE, DDSPF_A8L8 }, // D3DFMT_A8L8 { DXGI_FORMAT_A8_UNORM, CONV_FLAGS_NONE, DDSPF_A8 }, // D3DFMT_A8 { DXGI_FORMAT_R16G16B16A16_UNORM, CONV_FLAGS_NONE, { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, 36, 0, 0, 0, 0, 0 } }, // D3DFMT_A16B16G16R16 { DXGI_FORMAT_R16G16B16A16_SNORM, CONV_FLAGS_NONE, { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, 110, 0, 0, 0, 0, 0 } }, // D3DFMT_Q16W16V16U16 { DXGI_FORMAT_R16_FLOAT, CONV_FLAGS_NONE, { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, 111, 0, 0, 0, 0, 0 } }, // D3DFMT_R16F { DXGI_FORMAT_R16G16_FLOAT, CONV_FLAGS_NONE, { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, 112, 0, 0, 0, 0, 0 } }, // D3DFMT_G16R16F { DXGI_FORMAT_R16G16B16A16_FLOAT, CONV_FLAGS_NONE, { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, 113, 0, 0, 0, 0, 0 } }, // D3DFMT_A16B16G16R16F { DXGI_FORMAT_R32_FLOAT, CONV_FLAGS_NONE, { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, 114, 0, 0, 0, 0, 0 } }, // D3DFMT_R32F { DXGI_FORMAT_R32G32_FLOAT, CONV_FLAGS_NONE, { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, 115, 0, 0, 0, 0, 0 } }, // D3DFMT_G32R32F { DXGI_FORMAT_R32G32B32A32_FLOAT, CONV_FLAGS_NONE, { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, 116, 0, 0, 0, 0, 0 } }, // D3DFMT_A32B32G32R32F { DXGI_FORMAT_R32_FLOAT, CONV_FLAGS_NONE, { sizeof(DDS_PIXELFORMAT), DDS_RGB, 0, 32, 0xffffffff, 0x00000000, 0x00000000, 0x00000000 } }, // D3DFMT_R32F (D3DX uses FourCC 114 instead) { DXGI_FORMAT_R8G8B8A8_UNORM, CONV_FLAGS_EXPAND | CONV_FLAGS_PAL8 | CONV_FLAGS_A8P8, { sizeof(DDS_PIXELFORMAT), DDS_PAL8, 0, 16, 0, 0, 0, 0 } }, // D3DFMT_A8P8 { DXGI_FORMAT_R8G8B8A8_UNORM, CONV_FLAGS_EXPAND | CONV_FLAGS_PAL8, { sizeof(DDS_PIXELFORMAT), DDS_PAL8, 0, 8, 0, 0, 0, 0 } }, // D3DFMT_P8 { DXGI_FORMAT_B4G4R4A4_UNORM, CONV_FLAGS_4444, DDSPF_A4R4G4B4 }, // D3DFMT_A4R4G4B4 (uses DXGI 1.2 format) { DXGI_FORMAT_B4G4R4A4_UNORM, CONV_FLAGS_NOALPHA | CONV_FLAGS_4444, { sizeof(DDS_PIXELFORMAT), DDS_RGB, 0, 16, 0x0f00, 0x00f0, 0x000f, 0x0000 } }, // D3DFMT_X4R4G4B4 (uses DXGI 1.2 format) { DXGI_FORMAT_B4G4R4A4_UNORM, CONV_FLAGS_EXPAND | CONV_FLAGS_44, { sizeof(DDS_PIXELFORMAT), DDS_LUMINANCE, 0, 8, 0x0f, 0x00, 0x00, 0xf0 } }, // D3DFMT_A4L4 (uses DXGI 1.2 format) { DXGI_FORMAT_YUY2, CONV_FLAGS_NONE, DDSPF_YUY2 }, // D3DFMT_YUY2 (uses DXGI 1.2 format) { DXGI_FORMAT_YUY2, CONV_FLAGS_SWIZZLE, { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('U','Y','V','Y'), 0, 0, 0, 0, 0 } }, // D3DFMT_UYVY (uses DXGI 1.2 format) }; // Note that many common DDS reader/writers (including D3DX) swap the // the RED/BLUE masks for 10:10:10:2 formats. We assumme // below that the 'backwards' header mask is being used since it is most // likely written by D3DX. The more robust solution is to use the 'DX10' // header extension and specify the DXGI_FORMAT_R10G10B10A2_UNORM format directly // We do not support the following legacy Direct3D 9 formats: // BumpDuDv D3DFMT_V8U8, D3DFMT_Q8W8V8U8, D3DFMT_V16U16, D3DFMT_A2W10V10U10 // BumpLuminance D3DFMT_L6V5U5, D3DFMT_X8L8V8U8 // FourCC 117 D3DFMT_CxV8U8 // ZBuffer D3DFMT_D16_LOCKABLE // FourCC 82 D3DFMT_D32F_LOCKABLE static DXGI_FORMAT _GetDXGIFormat( const DDS_PIXELFORMAT& ddpf, DWORD flags, _Inout_ DWORD& convFlags ) { const size_t MAP_SIZE = sizeof(g_LegacyDDSMap) / sizeof(LegacyDDS); size_t index = 0; for( index = 0; index < MAP_SIZE; ++index ) { const LegacyDDS* entry = &g_LegacyDDSMap[index]; if ( ddpf.dwFlags & entry->ddpf.dwFlags ) { if ( entry->ddpf.dwFlags & DDS_FOURCC ) { if ( ddpf.dwFourCC == entry->ddpf.dwFourCC ) break; } else if ( entry->ddpf.dwFlags & DDS_PAL8 ) { if ( ddpf.dwRGBBitCount == entry->ddpf.dwRGBBitCount ) break; } else if ( ddpf.dwRGBBitCount == entry->ddpf.dwRGBBitCount ) { // RGB, RGBA, ALPHA, LUMINANCE if ( ddpf.dwRBitMask == entry->ddpf.dwRBitMask && ddpf.dwGBitMask == entry->ddpf.dwGBitMask && ddpf.dwBBitMask == entry->ddpf.dwBBitMask && ddpf.dwABitMask == entry->ddpf.dwABitMask ) break; } } } if ( index >= MAP_SIZE ) return DXGI_FORMAT_UNKNOWN; DWORD cflags = g_LegacyDDSMap[index].convFlags; DXGI_FORMAT format = g_LegacyDDSMap[index].format; if ( (cflags & CONV_FLAGS_EXPAND) && (flags & DDS_FLAGS_NO_LEGACY_EXPANSION) ) return DXGI_FORMAT_UNKNOWN; if ( (format == DXGI_FORMAT_R10G10B10A2_UNORM) && (flags & DDS_FLAGS_NO_R10B10G10A2_FIXUP) ) { cflags ^= CONV_FLAGS_SWIZZLE; } convFlags = cflags; return format; } //------------------------------------------------------------------------------------- // Decodes DDS header including optional DX10 extended header //------------------------------------------------------------------------------------- static HRESULT _DecodeDDSHeader( _In_reads_bytes_(size) LPCVOID pSource, size_t size, DWORD flags, _Out_ TexMetadata& metadata, _Inout_ DWORD& convFlags ) { if ( !pSource ) return E_INVALIDARG; memset( &metadata, 0, sizeof(TexMetadata) ); if ( size < (sizeof(DDS_HEADER) + sizeof(uint32_t)) ) { return HRESULT_FROM_WIN32( ERROR_INVALID_DATA ); } // DDS files always start with the same magic number ("DDS ") uint32_t dwMagicNumber = *reinterpret_cast(pSource); if ( dwMagicNumber != DDS_MAGIC ) { return E_FAIL; } auto pHeader = reinterpret_cast( (const uint8_t*)pSource + sizeof( uint32_t ) ); // Verify header to validate DDS file if ( pHeader->dwSize != sizeof(DDS_HEADER) || pHeader->ddspf.dwSize != sizeof(DDS_PIXELFORMAT) ) { return E_FAIL; } metadata.mipLevels = pHeader->dwMipMapCount; if ( metadata.mipLevels == 0 ) metadata.mipLevels = 1; // Check for DX10 extension if ( (pHeader->ddspf.dwFlags & DDS_FOURCC) && (MAKEFOURCC( 'D', 'X', '1', '0' ) == pHeader->ddspf.dwFourCC) ) { // Buffer must be big enough for both headers and magic value if ( size < ( sizeof(DDS_HEADER) + sizeof(uint32_t) + sizeof(DDS_HEADER_DXT10) ) ) { return E_FAIL; } auto d3d10ext = reinterpret_cast( (const uint8_t*)pSource + sizeof( uint32_t ) + sizeof(DDS_HEADER) ); convFlags |= CONV_FLAGS_DX10; metadata.arraySize = d3d10ext->arraySize; if ( metadata.arraySize == 0 ) { return HRESULT_FROM_WIN32( ERROR_INVALID_DATA ); } metadata.format = d3d10ext->dxgiFormat; if ( !IsValid( metadata.format ) || IsPalettized( metadata.format ) ) { return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); } static_assert( TEX_MISC_TEXTURECUBE == DDS_RESOURCE_MISC_TEXTURECUBE, "DDS header mismatch"); metadata.miscFlags = d3d10ext->miscFlag & ~TEX_MISC_TEXTURECUBE; switch ( d3d10ext->resourceDimension ) { case DDS_DIMENSION_TEXTURE1D: // D3DX writes 1D textures with a fixed Height of 1 if ( (pHeader->dwFlags & DDS_HEIGHT) && pHeader->dwHeight != 1 ) { return HRESULT_FROM_WIN32( ERROR_INVALID_DATA ); } metadata.width = pHeader->dwWidth; metadata.height = 1; metadata.depth = 1; metadata.dimension = TEX_DIMENSION_TEXTURE1D; break; case DDS_DIMENSION_TEXTURE2D: if ( d3d10ext->miscFlag & DDS_RESOURCE_MISC_TEXTURECUBE ) { metadata.miscFlags |= TEX_MISC_TEXTURECUBE; metadata.arraySize *= 6; } metadata.width = pHeader->dwWidth; metadata.height = pHeader->dwHeight; metadata.depth = 1; metadata.dimension = TEX_DIMENSION_TEXTURE2D; break; case DDS_DIMENSION_TEXTURE3D: if ( !(pHeader->dwFlags & DDS_HEADER_FLAGS_VOLUME) ) { return HRESULT_FROM_WIN32( ERROR_INVALID_DATA ); } if ( metadata.arraySize > 1 ) return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); metadata.width = pHeader->dwWidth; metadata.height = pHeader->dwHeight; metadata.depth = pHeader->dwDepth; metadata.dimension = TEX_DIMENSION_TEXTURE3D; break; default: return HRESULT_FROM_WIN32( ERROR_INVALID_DATA ); } static_assert( TEX_MISC2_ALPHA_MODE_MASK == DDS_MISC_FLAGS2_ALPHA_MODE_MASK, "DDS header mismatch"); static_assert( TEX_ALPHA_MODE_UNKNOWN == DDS_ALPHA_MODE_UNKNOWN, "DDS header mismatch"); static_assert( TEX_ALPHA_MODE_STRAIGHT == DDS_ALPHA_MODE_STRAIGHT, "DDS header mismatch"); static_assert( TEX_ALPHA_MODE_PREMULTIPLIED == DDS_ALPHA_MODE_PREMULTIPLIED, "DDS header mismatch"); static_assert( TEX_ALPHA_MODE_OPAQUE == DDS_ALPHA_MODE_OPAQUE, "DDS header mismatch"); static_assert( TEX_ALPHA_MODE_CUSTOM == DDS_ALPHA_MODE_CUSTOM, "DDS header mismatch"); metadata.miscFlags2 = d3d10ext->miscFlags2; } else { metadata.arraySize = 1; if ( pHeader->dwFlags & DDS_HEADER_FLAGS_VOLUME ) { metadata.width = pHeader->dwWidth; metadata.height = pHeader->dwHeight; metadata.depth = pHeader->dwDepth; metadata.dimension = TEX_DIMENSION_TEXTURE3D; } else { if ( pHeader->dwCaps2 & DDS_CUBEMAP ) { // We require all six faces to be defined if ( (pHeader->dwCaps2 & DDS_CUBEMAP_ALLFACES ) != DDS_CUBEMAP_ALLFACES ) return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); metadata.arraySize = 6; metadata.miscFlags |= TEX_MISC_TEXTURECUBE; } metadata.width = pHeader->dwWidth; metadata.height = pHeader->dwHeight; metadata.depth = 1; metadata.dimension = TEX_DIMENSION_TEXTURE2D; // Note there's no way for a legacy Direct3D 9 DDS to express a '1D' texture } metadata.format = _GetDXGIFormat( pHeader->ddspf, flags, convFlags ); if ( metadata.format == DXGI_FORMAT_UNKNOWN ) return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); if ( convFlags & CONV_FLAGS_PMALPHA ) metadata.miscFlags2 |= TEX_ALPHA_MODE_PREMULTIPLIED; // Special flag for handling LUMINANCE legacy formats if ( flags & DDS_FLAGS_EXPAND_LUMINANCE ) { switch ( metadata.format ) { case DXGI_FORMAT_R8_UNORM: metadata.format = DXGI_FORMAT_R8G8B8A8_UNORM; convFlags |= CONV_FLAGS_L8 | CONV_FLAGS_EXPAND; break; case DXGI_FORMAT_R8G8_UNORM: metadata.format = DXGI_FORMAT_R8G8B8A8_UNORM; convFlags |= CONV_FLAGS_A8L8 | CONV_FLAGS_EXPAND; break; case DXGI_FORMAT_R16_UNORM: metadata.format = DXGI_FORMAT_R16G16B16A16_UNORM; convFlags |= CONV_FLAGS_L16 | CONV_FLAGS_EXPAND; break; } } } // Special flag for handling BGR DXGI 1.1 formats if (flags & DDS_FLAGS_FORCE_RGB) { switch ( metadata.format ) { case DXGI_FORMAT_B8G8R8A8_UNORM: metadata.format = DXGI_FORMAT_R8G8B8A8_UNORM; convFlags |= CONV_FLAGS_SWIZZLE; break; case DXGI_FORMAT_B8G8R8X8_UNORM: metadata.format = DXGI_FORMAT_R8G8B8A8_UNORM; convFlags |= CONV_FLAGS_SWIZZLE | CONV_FLAGS_NOALPHA; break; case DXGI_FORMAT_B8G8R8A8_TYPELESS: metadata.format = DXGI_FORMAT_R8G8B8A8_TYPELESS; convFlags |= CONV_FLAGS_SWIZZLE; break; case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: metadata.format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB; convFlags |= CONV_FLAGS_SWIZZLE; break; case DXGI_FORMAT_B8G8R8X8_TYPELESS: metadata.format = DXGI_FORMAT_R8G8B8A8_TYPELESS; convFlags |= CONV_FLAGS_SWIZZLE | CONV_FLAGS_NOALPHA; break; case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: metadata.format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB; convFlags |= CONV_FLAGS_SWIZZLE | CONV_FLAGS_NOALPHA; break; } } // Special flag for handling 16bpp formats if (flags & DDS_FLAGS_NO_16BPP) { switch ( metadata.format ) { case DXGI_FORMAT_B5G6R5_UNORM: case DXGI_FORMAT_B5G5R5A1_UNORM: case DXGI_FORMAT_B4G4R4A4_UNORM: metadata.format = DXGI_FORMAT_R8G8B8A8_UNORM; convFlags |= CONV_FLAGS_EXPAND; if ( metadata.format == DXGI_FORMAT_B5G6R5_UNORM ) convFlags |= CONV_FLAGS_NOALPHA; } } return S_OK; } //------------------------------------------------------------------------------------- // Encodes DDS file header (magic value, header, optional DX10 extended header) //------------------------------------------------------------------------------------- _Use_decl_annotations_ HRESULT _EncodeDDSHeader( const TexMetadata& metadata, DWORD flags, LPVOID pDestination, size_t maxsize, size_t& required ) { if ( !IsValid( metadata.format ) ) return E_INVALIDARG; if ( IsPalettized( metadata.format ) ) return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); if ( metadata.arraySize > 1 ) { if ( (metadata.arraySize != 6) || (metadata.dimension != TEX_DIMENSION_TEXTURE2D) || !(metadata.IsCubemap()) ) { // Texture1D arrays, Texture2D arrays, and Cubemap arrays must be stored using 'DX10' extended header flags |= DDS_FLAGS_FORCE_DX10_EXT; } } if ( flags & DDS_FLAGS_FORCE_DX10_EXT_MISC2 ) { flags |= DDS_FLAGS_FORCE_DX10_EXT; } DDS_PIXELFORMAT ddpf = { 0 }; if ( !(flags & DDS_FLAGS_FORCE_DX10_EXT) ) { switch( metadata.format ) { case DXGI_FORMAT_R8G8B8A8_UNORM: memcpy_s( &ddpf, sizeof(ddpf), &DDSPF_A8B8G8R8, sizeof(DDS_PIXELFORMAT) ); break; case DXGI_FORMAT_R16G16_UNORM: memcpy_s( &ddpf, sizeof(ddpf), &DDSPF_G16R16, sizeof(DDS_PIXELFORMAT) ); break; case DXGI_FORMAT_R8G8_UNORM: memcpy_s( &ddpf, sizeof(ddpf), &DDSPF_A8L8, sizeof(DDS_PIXELFORMAT) ); break; case DXGI_FORMAT_R16_UNORM: memcpy_s( &ddpf, sizeof(ddpf), &DDSPF_L16, sizeof(DDS_PIXELFORMAT) ); break; case DXGI_FORMAT_R8_UNORM: memcpy_s( &ddpf, sizeof(ddpf), &DDSPF_L8, sizeof(DDS_PIXELFORMAT) ); break; case DXGI_FORMAT_A8_UNORM: memcpy_s( &ddpf, sizeof(ddpf), &DDSPF_A8, sizeof(DDS_PIXELFORMAT) ); break; case DXGI_FORMAT_R8G8_B8G8_UNORM: memcpy_s( &ddpf, sizeof(ddpf), &DDSPF_R8G8_B8G8, sizeof(DDS_PIXELFORMAT) ); break; case DXGI_FORMAT_G8R8_G8B8_UNORM: memcpy_s( &ddpf, sizeof(ddpf), &DDSPF_G8R8_G8B8, sizeof(DDS_PIXELFORMAT) ); break; case DXGI_FORMAT_BC1_UNORM: memcpy_s( &ddpf, sizeof(ddpf), &DDSPF_DXT1, sizeof(DDS_PIXELFORMAT) ); break; case DXGI_FORMAT_BC2_UNORM: memcpy_s( &ddpf, sizeof(ddpf), metadata.IsPMAlpha() ? (&DDSPF_DXT2) : (&DDSPF_DXT3), sizeof(DDS_PIXELFORMAT) ); break; case DXGI_FORMAT_BC3_UNORM: memcpy_s( &ddpf, sizeof(ddpf), metadata.IsPMAlpha() ? (&DDSPF_DXT4) : (&DDSPF_DXT5), sizeof(DDS_PIXELFORMAT) ); break; case DXGI_FORMAT_BC4_UNORM: memcpy_s( &ddpf, sizeof(ddpf), &DDSPF_BC4_UNORM, sizeof(DDS_PIXELFORMAT) ); break; case DXGI_FORMAT_BC4_SNORM: memcpy_s( &ddpf, sizeof(ddpf), &DDSPF_BC4_SNORM, sizeof(DDS_PIXELFORMAT) ); break; case DXGI_FORMAT_BC5_UNORM: memcpy_s( &ddpf, sizeof(ddpf), &DDSPF_BC5_UNORM, sizeof(DDS_PIXELFORMAT) ); break; case DXGI_FORMAT_BC5_SNORM: memcpy_s( &ddpf, sizeof(ddpf), &DDSPF_BC5_SNORM, sizeof(DDS_PIXELFORMAT) ); break; case DXGI_FORMAT_B5G6R5_UNORM: memcpy_s( &ddpf, sizeof(ddpf), &DDSPF_R5G6B5, sizeof(DDS_PIXELFORMAT) ); break; case DXGI_FORMAT_B5G5R5A1_UNORM: memcpy_s( &ddpf, sizeof(ddpf), &DDSPF_A1R5G5B5, sizeof(DDS_PIXELFORMAT) ); break; case DXGI_FORMAT_B8G8R8A8_UNORM: memcpy_s( &ddpf, sizeof(ddpf), &DDSPF_A8R8G8B8, sizeof(DDS_PIXELFORMAT) ); break; // DXGI 1.1 case DXGI_FORMAT_B8G8R8X8_UNORM: memcpy_s( &ddpf, sizeof(ddpf), &DDSPF_X8R8G8B8, sizeof(DDS_PIXELFORMAT) ); break; // DXGI 1.1 case DXGI_FORMAT_B4G4R4A4_UNORM: memcpy_s( &ddpf, sizeof(ddpf), &DDSPF_A4R4G4B4, sizeof(DDS_PIXELFORMAT) ); break; // DXGI 1.2 case DXGI_FORMAT_YUY2: memcpy_s( &ddpf, sizeof(ddpf), &DDSPF_YUY2, sizeof(DDS_PIXELFORMAT) ); break; // DXGI 1.2 // Legacy D3DX formats using D3DFMT enum value as FourCC case DXGI_FORMAT_R32G32B32A32_FLOAT: ddpf.dwSize = sizeof(DDS_PIXELFORMAT); ddpf.dwFlags = DDS_FOURCC; ddpf.dwFourCC = 116; // D3DFMT_A32B32G32R32F break; case DXGI_FORMAT_R16G16B16A16_FLOAT: ddpf.dwSize = sizeof(DDS_PIXELFORMAT); ddpf.dwFlags = DDS_FOURCC; ddpf.dwFourCC = 113; // D3DFMT_A16B16G16R16F break; case DXGI_FORMAT_R16G16B16A16_UNORM: ddpf.dwSize = sizeof(DDS_PIXELFORMAT); ddpf.dwFlags = DDS_FOURCC; ddpf.dwFourCC = 36; // D3DFMT_A16B16G16R16 break; case DXGI_FORMAT_R16G16B16A16_SNORM: ddpf.dwSize = sizeof(DDS_PIXELFORMAT); ddpf.dwFlags = DDS_FOURCC; ddpf.dwFourCC = 110; // D3DFMT_Q16W16V16U16 break; case DXGI_FORMAT_R32G32_FLOAT: ddpf.dwSize = sizeof(DDS_PIXELFORMAT); ddpf.dwFlags = DDS_FOURCC; ddpf.dwFourCC = 115; // D3DFMT_G32R32F break; case DXGI_FORMAT_R16G16_FLOAT: ddpf.dwSize = sizeof(DDS_PIXELFORMAT); ddpf.dwFlags = DDS_FOURCC; ddpf.dwFourCC = 112; // D3DFMT_G16R16F break; case DXGI_FORMAT_R32_FLOAT: ddpf.dwSize = sizeof(DDS_PIXELFORMAT); ddpf.dwFlags = DDS_FOURCC; ddpf.dwFourCC = 114; // D3DFMT_R32F break; case DXGI_FORMAT_R16_FLOAT: ddpf.dwSize = sizeof(DDS_PIXELFORMAT); ddpf.dwFlags = DDS_FOURCC; ddpf.dwFourCC = 111; // D3DFMT_R16F break; } } required = sizeof(uint32_t) + sizeof(DDS_HEADER); if ( ddpf.dwSize == 0 ) required += sizeof(DDS_HEADER_DXT10); if ( !pDestination ) return S_OK; if ( maxsize < required ) return E_NOT_SUFFICIENT_BUFFER; *reinterpret_cast(pDestination) = DDS_MAGIC; auto header = reinterpret_cast( reinterpret_cast(pDestination) + sizeof(uint32_t) ); assert( header ); memset( header, 0, sizeof(DDS_HEADER ) ); header->dwSize = sizeof( DDS_HEADER ); header->dwFlags = DDS_HEADER_FLAGS_TEXTURE; header->dwCaps = DDS_SURFACE_FLAGS_TEXTURE; if (metadata.mipLevels > 0) { header->dwFlags |= DDS_HEADER_FLAGS_MIPMAP; #ifdef _M_X64 if ( metadata.mipLevels > 0xFFFFFFFF ) return E_INVALIDARG; #endif header->dwMipMapCount = static_cast( metadata.mipLevels ); if ( header->dwMipMapCount > 1 ) header->dwCaps |= DDS_SURFACE_FLAGS_MIPMAP; } switch( metadata.dimension ) { case TEX_DIMENSION_TEXTURE1D: #ifdef _M_X64 if ( metadata.width > 0xFFFFFFFF ) return E_INVALIDARG; #endif header->dwWidth = static_cast( metadata.width ); header->dwHeight = header->dwDepth = 1; break; case TEX_DIMENSION_TEXTURE2D: #ifdef _M_X64 if ( metadata.height > 0xFFFFFFFF || metadata.width > 0xFFFFFFFF) return E_INVALIDARG; #endif header->dwHeight = static_cast( metadata.height ); header->dwWidth = static_cast( metadata.width ); header->dwDepth = 1; if ( metadata.IsCubemap() ) { header->dwCaps |= DDS_SURFACE_FLAGS_CUBEMAP; header->dwCaps2 |= DDS_CUBEMAP_ALLFACES; } break; case TEX_DIMENSION_TEXTURE3D: #ifdef _M_X64 if ( metadata.height > 0xFFFFFFFF || metadata.width > 0xFFFFFFFF || metadata.depth > 0xFFFFFFFF ) return E_INVALIDARG; #endif header->dwFlags |= DDS_HEADER_FLAGS_VOLUME; header->dwCaps2 |= DDS_FLAGS_VOLUME; header->dwHeight = static_cast( metadata.height ); header->dwWidth = static_cast( metadata.width ); header->dwDepth = static_cast( metadata.depth ); break; default: return E_FAIL; } size_t rowPitch, slicePitch; ComputePitch( metadata.format, metadata.width, metadata.height, rowPitch, slicePitch, CP_FLAGS_NONE ); #ifdef _M_X64 if ( slicePitch > 0xFFFFFFFF || rowPitch > 0xFFFFFFFF ) return E_FAIL; #endif if ( IsCompressed( metadata.format ) ) { header->dwFlags |= DDS_HEADER_FLAGS_LINEARSIZE; header->dwPitchOrLinearSize = static_cast( slicePitch ); } else { header->dwFlags |= DDS_HEADER_FLAGS_PITCH; header->dwPitchOrLinearSize = static_cast( rowPitch ); } if ( ddpf.dwSize == 0 ) { memcpy_s( &header->ddspf, sizeof(header->ddspf), &DDSPF_DX10, sizeof(DDS_PIXELFORMAT) ); auto ext = reinterpret_cast( reinterpret_cast(header) + sizeof(DDS_HEADER) ); assert( ext ); memset( ext, 0, sizeof(DDS_HEADER_DXT10) ); ext->dxgiFormat = metadata.format; ext->resourceDimension = metadata.dimension; #ifdef _M_X64 if ( metadata.arraySize > 0xFFFFFFFF ) return E_INVALIDARG; #endif static_assert( TEX_MISC_TEXTURECUBE == DDS_RESOURCE_MISC_TEXTURECUBE, "DDS header mismatch"); ext->miscFlag = metadata.miscFlags & ~TEX_MISC_TEXTURECUBE; if ( metadata.miscFlags & TEX_MISC_TEXTURECUBE ) { ext->miscFlag |= TEX_MISC_TEXTURECUBE; assert( (metadata.arraySize % 6) == 0 ); ext->arraySize = static_cast( metadata.arraySize / 6 ); } else { ext->arraySize = static_cast( metadata.arraySize ); } static_assert( TEX_MISC2_ALPHA_MODE_MASK == DDS_MISC_FLAGS2_ALPHA_MODE_MASK, "DDS header mismatch"); static_assert( TEX_ALPHA_MODE_UNKNOWN == DDS_ALPHA_MODE_UNKNOWN, "DDS header mismatch"); static_assert( TEX_ALPHA_MODE_STRAIGHT == DDS_ALPHA_MODE_STRAIGHT, "DDS header mismatch"); static_assert( TEX_ALPHA_MODE_PREMULTIPLIED == DDS_ALPHA_MODE_PREMULTIPLIED, "DDS header mismatch"); static_assert( TEX_ALPHA_MODE_OPAQUE == DDS_ALPHA_MODE_OPAQUE, "DDS header mismatch"); static_assert( TEX_ALPHA_MODE_CUSTOM == DDS_ALPHA_MODE_CUSTOM, "DDS header mismatch"); if ( flags & DDS_FLAGS_FORCE_DX10_EXT_MISC2 ) { // This was formerly 'reserved'. D3DX10 and D3DX11 will fail if this value is anything other than 0 ext->miscFlags2 = metadata.miscFlags2; } } else { memcpy_s( &header->ddspf, sizeof(header->ddspf), &ddpf, sizeof(ddpf) ); } return S_OK; } //------------------------------------------------------------------------------------- // Converts an image row with optional clearing of alpha value to 1.0 // Returns true if supported, false if expansion case not supported //------------------------------------------------------------------------------------- enum TEXP_LEGACY_FORMAT { TEXP_LEGACY_UNKNOWN = 0, TEXP_LEGACY_R8G8B8, TEXP_LEGACY_R3G3B2, TEXP_LEGACY_A8R3G3B2, TEXP_LEGACY_P8, TEXP_LEGACY_A8P8, TEXP_LEGACY_A4L4, TEXP_LEGACY_B4G4R4A4, TEXP_LEGACY_L8, TEXP_LEGACY_L16, TEXP_LEGACY_A8L8 }; inline static TEXP_LEGACY_FORMAT _FindLegacyFormat( DWORD flags ) { TEXP_LEGACY_FORMAT lformat = TEXP_LEGACY_UNKNOWN; if ( flags & CONV_FLAGS_PAL8 ) { lformat = ( flags & CONV_FLAGS_A8P8 ) ? TEXP_LEGACY_A8P8 : TEXP_LEGACY_P8; } else if ( flags & CONV_FLAGS_888 ) lformat = TEXP_LEGACY_R8G8B8; else if ( flags & CONV_FLAGS_332 ) lformat = TEXP_LEGACY_R3G3B2; else if ( flags & CONV_FLAGS_8332 ) lformat = TEXP_LEGACY_A8R3G3B2; else if ( flags & CONV_FLAGS_44 ) lformat = TEXP_LEGACY_A4L4; else if ( flags & CONV_FLAGS_4444 ) lformat = TEXP_LEGACY_B4G4R4A4; else if ( flags & CONV_FLAGS_L8 ) lformat = TEXP_LEGACY_L8; else if ( flags & CONV_FLAGS_L16 ) lformat = TEXP_LEGACY_L16; else if ( flags & CONV_FLAGS_A8L8 ) lformat = TEXP_LEGACY_A8L8; return lformat; } _Success_(return != false) static bool _LegacyExpandScanline( _Out_writes_bytes_(outSize) LPVOID pDestination, size_t outSize, _In_ DXGI_FORMAT outFormat, _In_reads_bytes_(inSize) LPCVOID pSource, size_t inSize, _In_ TEXP_LEGACY_FORMAT inFormat, _In_reads_opt_(256) const uint32_t* pal8, _In_ DWORD flags ) { assert( pDestination && outSize > 0 ); assert( pSource && inSize > 0 ); assert( IsValid(outFormat) && !IsPlanar(outFormat) && !IsPalettized(outFormat) ); switch( inFormat ) { case TEXP_LEGACY_R8G8B8: if ( outFormat != DXGI_FORMAT_R8G8B8A8_UNORM ) return false; // D3DFMT_R8G8B8 -> DXGI_FORMAT_R8G8B8A8_UNORM if ( inSize >= 3 && outSize >= 4 ) { const uint8_t * __restrict sPtr = reinterpret_cast(pSource); uint32_t * __restrict dPtr = reinterpret_cast(pDestination); for( size_t ocount = 0, icount = 0; ( ( icount < ( inSize - 2 ) ) && ( ocount < ( outSize - 3 ) ) ); icount += 3, ocount += 4 ) { // 24bpp Direct3D 9 files are actually BGR, so need to swizzle as well uint32_t t1 = ( *(sPtr) << 16 ); uint32_t t2 = ( *(sPtr+1) << 8 ); uint32_t t3 = *(sPtr+2); *(dPtr++) = t1 | t2 | t3 | 0xff000000; sPtr += 3; } return true; } return false; case TEXP_LEGACY_R3G3B2: switch( outFormat ) { case DXGI_FORMAT_R8G8B8A8_UNORM: // D3DFMT_R3G3B2 -> DXGI_FORMAT_R8G8B8A8_UNORM if ( inSize >= 1 && outSize >= 4 ) { const uint8_t* __restrict sPtr = reinterpret_cast(pSource); uint32_t * __restrict dPtr = reinterpret_cast(pDestination); for( size_t ocount = 0, icount = 0; ( ( icount < inSize ) && ( ocount < ( outSize - 3 ) ) ); ++icount, ocount += 4 ) { uint8_t t = *(sPtr++); uint32_t t1 = (t & 0xe0) | ((t & 0xe0) >> 3) | ((t & 0xc0) >> 6); uint32_t t2 = ((t & 0x1c) << 11) | ((t & 0x1c) << 8) | ((t & 0x18) << 5); uint32_t t3 = ((t & 0x03) << 22) | ((t & 0x03) << 20) | ((t & 0x03) << 18) | ((t & 0x03) << 16); *(dPtr++) = t1 | t2 | t3 | 0xff000000; } return true; } return false; case DXGI_FORMAT_B5G6R5_UNORM: // D3DFMT_R3G3B2 -> DXGI_FORMAT_B5G6R5_UNORM if ( inSize >= 1 && outSize >= 2 ) { const uint8_t* __restrict sPtr = reinterpret_cast(pSource); uint16_t * __restrict dPtr = reinterpret_cast(pDestination); for( size_t ocount = 0, icount = 0; ( ( icount < inSize ) && ( ocount < ( outSize - 1 ) ) ); ++icount, ocount += 2 ) { uint8_t t = *(sPtr++); uint16_t t1 = ((t & 0xe0) << 8) | ((t & 0xc0) << 5); uint16_t t2 = ((t & 0x1c) << 6) | ((t & 0x1c) << 3); uint16_t t3 = ((t & 0x03) << 3) | ((t & 0x03) << 1) | ((t & 0x02) >> 1); *(dPtr++) = t1 | t2 | t3; } return true; } return false; } break; case TEXP_LEGACY_A8R3G3B2: if ( outFormat != DXGI_FORMAT_R8G8B8A8_UNORM ) return false; // D3DFMT_A8R3G3B2 -> DXGI_FORMAT_R8G8B8A8_UNORM if ( inSize >= 2 && outSize >= 4 ) { const uint16_t* __restrict sPtr = reinterpret_cast(pSource); uint32_t * __restrict dPtr = reinterpret_cast(pDestination); for( size_t ocount = 0, icount = 0; ( ( icount < ( inSize - 1 ) ) && ( ocount < ( outSize - 3 ) ) ); icount += 2, ocount += 4 ) { uint16_t t = *(sPtr++); uint32_t t1 = (t & 0x00e0) | ((t & 0x00e0) >> 3) | ((t & 0x00c0) >> 6); uint32_t t2 = ((t & 0x001c) << 11) | ((t & 0x001c) << 8) | ((t & 0x0018) << 5); uint32_t t3 = ((t & 0x0003) << 22) | ((t & 0x0003) << 20) | ((t & 0x0003) << 18) | ((t & 0x0003) << 16); uint32_t ta = ( flags & TEXP_SCANLINE_SETALPHA ) ? 0xff000000 : ((t & 0xff00) << 16); *(dPtr++) = t1 | t2 | t3 | ta; } return true; } return false; case TEXP_LEGACY_P8: if ( (outFormat != DXGI_FORMAT_R8G8B8A8_UNORM) || !pal8 ) return false; // D3DFMT_P8 -> DXGI_FORMAT_R8G8B8A8_UNORM if ( inSize >= 1 && outSize >= 4 ) { const uint8_t* __restrict sPtr = reinterpret_cast(pSource); uint32_t * __restrict dPtr = reinterpret_cast(pDestination); for( size_t ocount = 0, icount = 0; ( ( icount < inSize ) && ( ocount < ( outSize - 3 ) ) ); ++icount, ocount += 4 ) { uint8_t t = *(sPtr++); *(dPtr++) = pal8[ t ]; } return true; } return false; case TEXP_LEGACY_A8P8: if ( (outFormat != DXGI_FORMAT_R8G8B8A8_UNORM) || !pal8 ) return false; // D3DFMT_A8P8 -> DXGI_FORMAT_R8G8B8A8_UNORM if ( inSize >= 2 && outSize >= 4 ) { const uint16_t* __restrict sPtr = reinterpret_cast(pSource); uint32_t * __restrict dPtr = reinterpret_cast(pDestination); for( size_t ocount = 0, icount = 0; ( ( icount < ( inSize - 1 ) ) && ( ocount < ( outSize - 3 ) ) ); icount += 2, ocount += 4 ) { uint16_t t = *(sPtr++); uint32_t t1 = pal8[ t & 0xff ]; uint32_t ta = ( flags & TEXP_SCANLINE_SETALPHA ) ? 0xff000000 : ((t & 0xff00) << 16); *(dPtr++) = t1 | ta; } return true; } return false; case TEXP_LEGACY_A4L4: switch( outFormat ) { case DXGI_FORMAT_B4G4R4A4_UNORM : // D3DFMT_A4L4 -> DXGI_FORMAT_B4G4R4A4_UNORM if ( inSize >= 1 && outSize >= 2 ) { const uint8_t * __restrict sPtr = reinterpret_cast(pSource); uint16_t * __restrict dPtr = reinterpret_cast(pDestination); for( size_t ocount = 0, icount = 0; ( ( icount < inSize ) && ( ocount < ( outSize - 1 ) ) ); ++icount, ocount += 2 ) { uint8_t t = *(sPtr++); uint16_t t1 = (t & 0x0f); uint16_t ta = ( flags & TEXP_SCANLINE_SETALPHA ) ? 0xf000 : ((t & 0xf0) << 8); *(dPtr++) = t1 | (t1 << 4) | (t1 << 8) | ta; } return true; } return false; case DXGI_FORMAT_R8G8B8A8_UNORM: // D3DFMT_A4L4 -> DXGI_FORMAT_R8G8B8A8_UNORM if ( inSize >= 1 && outSize >= 4 ) { const uint8_t * __restrict sPtr = reinterpret_cast(pSource); uint32_t * __restrict dPtr = reinterpret_cast(pDestination); for( size_t ocount = 0, icount = 0; ( ( icount < inSize ) && ( ocount < ( outSize - 3 ) ) ); ++icount, ocount += 4 ) { uint8_t t = *(sPtr++); uint32_t t1 = ((t & 0x0f) << 4) | (t & 0x0f); uint32_t ta = ( flags & TEXP_SCANLINE_SETALPHA ) ? 0xff000000 : (((t & 0xf0) << 24) | ((t & 0xf0) << 20)); *(dPtr++) = t1 | (t1 << 8) | (t1 << 16) | ta; } return true; } return false; } break; case TEXP_LEGACY_B4G4R4A4: if (outFormat != DXGI_FORMAT_R8G8B8A8_UNORM) return false; // D3DFMT_A4R4G4B4 -> DXGI_FORMAT_R8G8B8A8_UNORM if ( inSize >= 2 && outSize >= 4 ) { const uint16_t * __restrict sPtr = reinterpret_cast(pSource); uint32_t * __restrict dPtr = reinterpret_cast(pDestination); for( size_t ocount = 0, icount = 0; ( ( icount < ( inSize - 1 ) ) && ( ocount < ( outSize - 3 ) ) ); icount += 2, ocount += 4 ) { uint16_t t = *(sPtr++); uint32_t t1 = ((t & 0x0f00) >> 4) | ((t & 0x0f00) >> 8); uint32_t t2 = ((t & 0x00f0) << 8) | ((t & 0x00f0) << 4); uint32_t t3 = ((t & 0x000f) << 20) | ((t & 0x000f) << 16); uint32_t ta = ( flags & TEXP_SCANLINE_SETALPHA ) ? 0xff000000 : (((t & 0xf000) << 16) | ((t & 0xf000) << 12)); *(dPtr++) = t1 | t2 | t3 | ta; } return true; } return false; case TEXP_LEGACY_L8: if (outFormat != DXGI_FORMAT_R8G8B8A8_UNORM) return false; // D3DFMT_L8 -> DXGI_FORMAT_R8G8B8A8_UNORM if ( inSize >= 1 && outSize >= 4 ) { const uint8_t * __restrict sPtr = reinterpret_cast(pSource); uint32_t * __restrict dPtr = reinterpret_cast(pDestination); for( size_t ocount = 0, icount = 0; ( ( icount < inSize ) && ( ocount < ( outSize - 3 ) ) ); ++icount, ocount += 4 ) { uint32_t t1 = *(sPtr++); uint32_t t2 = (t1 << 8); uint32_t t3 = (t1 << 16); *(dPtr++) = t1 | t2 | t3 | 0xff000000; } return true; } return false; case TEXP_LEGACY_L16: if (outFormat != DXGI_FORMAT_R16G16B16A16_UNORM) return false; // D3DFMT_L16 -> DXGI_FORMAT_R16G16B16A16_UNORM if ( inSize >= 2 && outSize >= 8 ) { const uint16_t* __restrict sPtr = reinterpret_cast(pSource); uint64_t * __restrict dPtr = reinterpret_cast(pDestination); for( size_t ocount = 0, icount = 0; ( ( icount < ( inSize - 1 ) ) && ( ocount < ( outSize - 7 ) ) ); icount += 2, ocount += 8 ) { uint16_t t = *(sPtr++); uint64_t t1 = t; uint64_t t2 = (t1 << 16); uint64_t t3 = (t1 << 32); *(dPtr++) = t1 | t2 | t3 | 0xffff000000000000; } return true; } return false; case TEXP_LEGACY_A8L8: if (outFormat != DXGI_FORMAT_R8G8B8A8_UNORM) return false; // D3DFMT_A8L8 -> DXGI_FORMAT_R8G8B8A8_UNORM if ( inSize >= 2 && outSize >= 4 ) { const uint16_t* __restrict sPtr = reinterpret_cast(pSource); uint32_t * __restrict dPtr = reinterpret_cast(pDestination); for( size_t ocount = 0, icount = 0; ( ( icount < ( inSize - 1 ) ) && ( ocount < ( outSize - 3 ) ) ); icount += 2, ocount += 4 ) { uint16_t t = *(sPtr++); uint32_t t1 = (t & 0xff); uint32_t t2 = (t1 << 8); uint32_t t3 = (t1 << 16); uint32_t ta = ( flags & TEXP_SCANLINE_SETALPHA ) ? 0xff000000 : ((t & 0xff00) << 16); *(dPtr++) = t1 | t2 | t3 | ta; } return true; } return false; } return false; } //------------------------------------------------------------------------------------- // Converts or copies image data from pPixels into scratch image data //------------------------------------------------------------------------------------- static HRESULT _CopyImage( _In_reads_bytes_(size) const void* pPixels, _In_ size_t size, _In_ const TexMetadata& metadata, _In_ DWORD cpFlags, _In_ DWORD convFlags, _In_reads_opt_(256) const uint32_t *pal8, _In_ const ScratchImage& image ) { assert( pPixels ); assert( image.GetPixels() ); if ( !size ) return E_FAIL; if ( convFlags & CONV_FLAGS_EXPAND ) { if ( convFlags & CONV_FLAGS_888 ) cpFlags |= CP_FLAGS_24BPP; else if ( convFlags & (CONV_FLAGS_565 | CONV_FLAGS_5551 | CONV_FLAGS_4444 | CONV_FLAGS_8332 | CONV_FLAGS_A8P8 | CONV_FLAGS_L16 | CONV_FLAGS_A8L8) ) cpFlags |= CP_FLAGS_16BPP; else if ( convFlags & (CONV_FLAGS_44 | CONV_FLAGS_332 | CONV_FLAGS_PAL8 | CONV_FLAGS_L8) ) cpFlags |= CP_FLAGS_8BPP; } size_t pixelSize, nimages; _DetermineImageArray( metadata, cpFlags, nimages, pixelSize ); if ( (nimages == 0) || (nimages != image.GetImageCount()) ) { return E_FAIL; } assert( pixelSize <= size ); std::unique_ptr timages( new (std::nothrow) Image[nimages] ); if ( !timages ) { return E_OUTOFMEMORY; } if ( !_SetupImageArray( (uint8_t*)pPixels, size, metadata, cpFlags, timages.get(), nimages ) ) { return E_FAIL; } if ( nimages != image.GetImageCount() ) { return E_FAIL; } const Image* images = image.GetImages(); if ( !images ) { return E_FAIL; } DWORD tflags = (convFlags & CONV_FLAGS_NOALPHA) ? TEXP_SCANLINE_SETALPHA : 0; if ( convFlags & CONV_FLAGS_SWIZZLE ) tflags |= TEXP_SCANLINE_LEGACY; switch (metadata.dimension) { case TEX_DIMENSION_TEXTURE1D: case TEX_DIMENSION_TEXTURE2D: { size_t index = 0; for( size_t item = 0; item < metadata.arraySize; ++item ) { for( size_t level = 0; level < metadata.mipLevels; ++level, ++index ) { if ( index >= nimages ) return E_FAIL; if ( images[ index ].height != timages[ index ].height ) return E_FAIL; size_t dpitch = images[ index ].rowPitch; size_t spitch = timages[ index ].rowPitch; const uint8_t *pSrc = const_cast( timages[ index ].pixels ); if ( !pSrc ) return E_POINTER; uint8_t *pDest = images[ index ].pixels; if ( !pDest ) return E_POINTER; if ( IsCompressed( metadata.format ) ) { size_t csize = std::min( images[ index ].slicePitch, timages[ index ].slicePitch ); memcpy_s( pDest, images[ index ].slicePitch, pSrc, csize ); } else if ( IsPlanar( metadata.format ) ) { size_t count = ComputeScanlines( metadata.format, images[ index ].height ); if ( !count ) return E_UNEXPECTED; size_t csize = std::min( dpitch, spitch ); for( size_t h = 0; h < count; ++h ) { memcpy_s( pDest, dpitch, pSrc, csize ); pSrc += spitch; pDest += dpitch; } } else { for( size_t h = 0; h < images[ index ].height; ++h ) { if ( convFlags & CONV_FLAGS_EXPAND ) { if ( convFlags & (CONV_FLAGS_565|CONV_FLAGS_5551|CONV_FLAGS_4444) ) { if ( !_ExpandScanline( pDest, dpitch, DXGI_FORMAT_R8G8B8A8_UNORM, pSrc, spitch, (convFlags & CONV_FLAGS_565) ? DXGI_FORMAT_B5G6R5_UNORM : DXGI_FORMAT_B5G5R5A1_UNORM, tflags ) ) return E_FAIL; } else { TEXP_LEGACY_FORMAT lformat = _FindLegacyFormat( convFlags ); if ( !_LegacyExpandScanline( pDest, dpitch, metadata.format, pSrc, spitch, lformat, pal8, tflags ) ) return E_FAIL; } } else if ( convFlags & CONV_FLAGS_SWIZZLE ) { _SwizzleScanline( pDest, dpitch, pSrc, spitch, metadata.format, tflags ); } else { _CopyScanline( pDest, dpitch, pSrc, spitch, metadata.format, tflags ); } pSrc += spitch; pDest += dpitch; } } } } } break; case TEX_DIMENSION_TEXTURE3D: { size_t index = 0; size_t d = metadata.depth; for( size_t level = 0; level < metadata.mipLevels; ++level ) { for( size_t slice = 0; slice < d; ++slice, ++index ) { if ( index >= nimages ) return E_FAIL; if ( images[ index ].height != timages[ index ].height ) return E_FAIL; size_t dpitch = images[ index ].rowPitch; size_t spitch = timages[ index ].rowPitch; const uint8_t *pSrc = const_cast( timages[ index ].pixels ); if ( !pSrc ) return E_POINTER; uint8_t *pDest = images[ index ].pixels; if ( !pDest ) return E_POINTER; if ( IsCompressed( metadata.format ) ) { size_t csize = std::min( images[ index ].slicePitch, timages[ index ].slicePitch ); memcpy_s( pDest, images[ index ].slicePitch, pSrc, csize ); } else if ( IsPlanar( metadata.format ) ) { // Direct3D does not support any planar formats for Texture3D return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); } else { for( size_t h = 0; h < images[ index ].height; ++h ) { if ( convFlags & CONV_FLAGS_EXPAND ) { if ( convFlags & (CONV_FLAGS_565|CONV_FLAGS_5551|CONV_FLAGS_4444) ) { if ( !_ExpandScanline( pDest, dpitch, DXGI_FORMAT_R8G8B8A8_UNORM, pSrc, spitch, (convFlags & CONV_FLAGS_565) ? DXGI_FORMAT_B5G6R5_UNORM : DXGI_FORMAT_B5G5R5A1_UNORM, tflags ) ) return E_FAIL; } else { TEXP_LEGACY_FORMAT lformat = _FindLegacyFormat( convFlags ); if ( !_LegacyExpandScanline( pDest, dpitch, metadata.format, pSrc, spitch, lformat, pal8, tflags ) ) return E_FAIL; } } else if ( convFlags & CONV_FLAGS_SWIZZLE ) { _SwizzleScanline( pDest, dpitch, pSrc, spitch, metadata.format, tflags ); } else { _CopyScanline( pDest, dpitch, pSrc, spitch, metadata.format, tflags ); } pSrc += spitch; pDest += dpitch; } } } if ( d > 1 ) d >>= 1; } } break; default: return E_FAIL; } return S_OK; } static HRESULT _CopyImageInPlace( DWORD convFlags, _In_ const ScratchImage& image ) { if ( !image.GetPixels() ) return E_FAIL; const Image* images = image.GetImages(); if ( !images ) return E_FAIL; const TexMetadata& metadata = image.GetMetadata(); if ( IsPlanar( metadata.format ) ) return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); DWORD tflags = (convFlags & CONV_FLAGS_NOALPHA) ? TEXP_SCANLINE_SETALPHA : 0; if ( convFlags & CONV_FLAGS_SWIZZLE ) tflags |= TEXP_SCANLINE_LEGACY; for( size_t i = 0; i < image.GetImageCount(); ++i ) { const Image* img = &images[ i ]; uint8_t *pPixels = img->pixels; if ( !pPixels ) return E_POINTER; size_t rowPitch = img->rowPitch; for( size_t h = 0; h < img->height; ++h ) { if ( convFlags & CONV_FLAGS_SWIZZLE ) { _SwizzleScanline( pPixels, rowPitch, pPixels, rowPitch, metadata.format, tflags ); } else { _CopyScanline( pPixels, rowPitch, pPixels, rowPitch, metadata.format, tflags ); } pPixels += rowPitch; } } return S_OK; } //===================================================================================== // Entry-points //===================================================================================== //------------------------------------------------------------------------------------- // Obtain metadata from DDS file in memory/on disk //------------------------------------------------------------------------------------- _Use_decl_annotations_ HRESULT GetMetadataFromDDSMemory( LPCVOID pSource, size_t size, DWORD flags, TexMetadata& metadata ) { if ( !pSource || size == 0 ) return E_INVALIDARG; DWORD convFlags = 0; return _DecodeDDSHeader( pSource, size, flags, metadata, convFlags ); } _Use_decl_annotations_ HRESULT GetMetadataFromDDSFile( LPCWSTR szFile, DWORD flags, TexMetadata& metadata ) { if ( !szFile ) return E_INVALIDARG; #if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) ScopedHandle hFile( safe_handle( CreateFile2( szFile, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, 0 ) ) ); #else ScopedHandle hFile( safe_handle( CreateFileW( szFile, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, 0 ) ) ); #endif if ( !hFile ) { return HRESULT_FROM_WIN32( GetLastError() ); } // Get the file size LARGE_INTEGER fileSize = {0}; #if (_WIN32_WINNT >= _WIN32_WINNT_VISTA) FILE_STANDARD_INFO fileInfo; if ( !GetFileInformationByHandleEx( hFile.get(), FileStandardInfo, &fileInfo, sizeof(fileInfo) ) ) { return HRESULT_FROM_WIN32( GetLastError() ); } fileSize = fileInfo.EndOfFile; #else if ( !GetFileSizeEx( hFile.get(), &fileSize ) ) { return HRESULT_FROM_WIN32( GetLastError() ); } #endif // File is too big for 32-bit allocation, so reject read (4 GB should be plenty large enough for a valid DDS file) if ( fileSize.HighPart > 0 ) { return HRESULT_FROM_WIN32( ERROR_FILE_TOO_LARGE ); } // Need at least enough data to fill the standard header and magic number to be a valid DDS if ( fileSize.LowPart < ( sizeof(DDS_HEADER) + sizeof(uint32_t) ) ) { return E_FAIL; } // Read the header in (including extended header if present) const size_t MAX_HEADER_SIZE = sizeof(uint32_t) + sizeof(DDS_HEADER) + sizeof(DDS_HEADER_DXT10); uint8_t header[MAX_HEADER_SIZE]; DWORD bytesRead = 0; if ( !ReadFile( hFile.get(), header, MAX_HEADER_SIZE, &bytesRead, 0 ) ) { return HRESULT_FROM_WIN32( GetLastError() ); } DWORD convFlags = 0; return _DecodeDDSHeader( header, bytesRead, flags, metadata, convFlags ); } //------------------------------------------------------------------------------------- // Load a DDS file in memory //------------------------------------------------------------------------------------- _Use_decl_annotations_ HRESULT LoadFromDDSMemory( LPCVOID pSource, size_t size, DWORD flags, TexMetadata* metadata, ScratchImage& image ) { if ( !pSource || size == 0 ) return E_INVALIDARG; image.Release(); DWORD convFlags = 0; TexMetadata mdata; HRESULT hr = _DecodeDDSHeader( pSource, size, flags, mdata, convFlags ); if ( FAILED(hr) ) return hr; size_t offset = sizeof(uint32_t) + sizeof(DDS_HEADER); if ( convFlags & CONV_FLAGS_DX10 ) offset += sizeof(DDS_HEADER_DXT10); assert( offset <= size ); const uint32_t *pal8 = nullptr; if ( convFlags & CONV_FLAGS_PAL8 ) { pal8 = reinterpret_cast( reinterpret_cast(pSource) + offset ); assert( pal8 ); offset += ( 256 * sizeof(uint32_t) ); if ( size < offset ) return E_FAIL; } hr = image.Initialize( mdata ); if ( FAILED(hr) ) return hr; auto pPixels = reinterpret_cast( reinterpret_cast(pSource) + offset ); assert( pPixels ); hr = _CopyImage( pPixels, size - offset, mdata, (flags & DDS_FLAGS_LEGACY_DWORD) ? CP_FLAGS_LEGACY_DWORD : CP_FLAGS_NONE, convFlags, pal8, image ); if ( FAILED(hr) ) { image.Release(); return hr; } if ( metadata ) memcpy( metadata, &mdata, sizeof(TexMetadata) ); return S_OK; } //------------------------------------------------------------------------------------- // Load a DDS file from disk //------------------------------------------------------------------------------------- _Use_decl_annotations_ HRESULT LoadFromDDSFile( LPCWSTR szFile, DWORD flags, TexMetadata* metadata, ScratchImage& image ) { if ( !szFile ) return E_INVALIDARG; image.Release(); #if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) ScopedHandle hFile( safe_handle ( CreateFile2( szFile, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, 0 ) ) ); #else ScopedHandle hFile( safe_handle ( CreateFileW( szFile, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, 0 ) ) ); #endif if ( !hFile ) { return HRESULT_FROM_WIN32( GetLastError() ); } // Get the file size LARGE_INTEGER fileSize = {0}; #if (_WIN32_WINNT >= _WIN32_WINNT_VISTA) FILE_STANDARD_INFO fileInfo; if ( !GetFileInformationByHandleEx( hFile.get(), FileStandardInfo, &fileInfo, sizeof(fileInfo) ) ) { return HRESULT_FROM_WIN32( GetLastError() ); } fileSize = fileInfo.EndOfFile; #else if ( !GetFileSizeEx( hFile.get(), &fileSize ) ) { return HRESULT_FROM_WIN32( GetLastError() ); } #endif // File is too big for 32-bit allocation, so reject read (4 GB should be plenty large enough for a valid DDS file) if ( fileSize.HighPart > 0 ) { return HRESULT_FROM_WIN32( ERROR_FILE_TOO_LARGE ); } // Need at least enough data to fill the standard header and magic number to be a valid DDS if ( fileSize.LowPart < ( sizeof(DDS_HEADER) + sizeof(uint32_t) ) ) { return E_FAIL; } // Read the header in (including extended header if present) const size_t MAX_HEADER_SIZE = sizeof(uint32_t) + sizeof(DDS_HEADER) + sizeof(DDS_HEADER_DXT10); uint8_t header[MAX_HEADER_SIZE]; DWORD bytesRead = 0; if ( !ReadFile( hFile.get(), header, MAX_HEADER_SIZE, &bytesRead, 0 ) ) { return HRESULT_FROM_WIN32( GetLastError() ); } DWORD convFlags = 0; TexMetadata mdata; HRESULT hr = _DecodeDDSHeader( header, bytesRead, flags, mdata, convFlags ); if ( FAILED(hr) ) return hr; DWORD offset = MAX_HEADER_SIZE; if ( !(convFlags & CONV_FLAGS_DX10) ) { // Must reset file position since we read more than the standard header above LARGE_INTEGER filePos = { sizeof(uint32_t) + sizeof(DDS_HEADER), 0}; if ( !SetFilePointerEx( hFile.get(), filePos, 0, FILE_BEGIN ) ) { return HRESULT_FROM_WIN32( GetLastError() ); } offset = sizeof(uint32_t) + sizeof(DDS_HEADER); } std::unique_ptr pal8; if ( convFlags & CONV_FLAGS_PAL8 ) { pal8.reset( new (std::nothrow) uint32_t[256] ); if ( !pal8 ) { return E_OUTOFMEMORY; } if ( !ReadFile( hFile.get(), pal8.get(), 256 * sizeof(uint32_t), &bytesRead, 0 ) ) { return HRESULT_FROM_WIN32( GetLastError() ); } if ( bytesRead != (256 * sizeof(uint32_t)) ) { return E_FAIL; } offset += ( 256 * sizeof(uint32_t) ); } DWORD remaining = fileSize.LowPart - offset; if ( remaining == 0 ) return E_FAIL; hr = image.Initialize( mdata ); if ( FAILED(hr) ) return hr; if ( (convFlags & CONV_FLAGS_EXPAND) || (flags & DDS_FLAGS_LEGACY_DWORD) ) { std::unique_ptr temp( new (std::nothrow) uint8_t[ remaining ] ); if ( !temp ) { image.Release(); return E_OUTOFMEMORY; } if ( !ReadFile( hFile.get(), temp.get(), remaining, &bytesRead, 0 ) ) { image.Release(); return HRESULT_FROM_WIN32( GetLastError() ); } if ( bytesRead != remaining ) { image.Release(); return E_FAIL; } hr = _CopyImage( temp.get(), remaining, mdata, (flags & DDS_FLAGS_LEGACY_DWORD) ? CP_FLAGS_LEGACY_DWORD : CP_FLAGS_NONE, convFlags, pal8.get(), image ); if ( FAILED(hr) ) { image.Release(); return hr; } } else { if ( remaining < image.GetPixelsSize() ) { image.Release(); return E_FAIL; } if ( !ReadFile( hFile.get(), image.GetPixels(), static_cast( image.GetPixelsSize() ), &bytesRead, 0 ) ) { image.Release(); return HRESULT_FROM_WIN32( GetLastError() ); } if ( convFlags & (CONV_FLAGS_SWIZZLE|CONV_FLAGS_NOALPHA) ) { // Swizzle/copy image in place hr = _CopyImageInPlace( convFlags, image ); if ( FAILED(hr) ) { image.Release(); return hr; } } } if ( metadata ) memcpy( metadata, &mdata, sizeof(TexMetadata) ); return S_OK; } //------------------------------------------------------------------------------------- // Save a DDS file to memory //------------------------------------------------------------------------------------- _Use_decl_annotations_ HRESULT SaveToDDSMemory( const Image* images, size_t nimages, const TexMetadata& metadata, DWORD flags, Blob& blob ) { if ( !images || (nimages == 0) ) return E_INVALIDARG; // Determine memory required size_t required = 0; HRESULT hr = _EncodeDDSHeader( metadata, flags, 0, 0, required ); if ( FAILED(hr) ) return hr; bool fastpath = true; for( size_t i = 0; i < nimages; ++i ) { if ( !images[ i ].pixels ) return E_POINTER; if ( images[ i ].format != metadata.format ) return E_FAIL; size_t ddsRowPitch, ddsSlicePitch; ComputePitch( metadata.format, images[ i ].width, images[ i ].height, ddsRowPitch, ddsSlicePitch, CP_FLAGS_NONE ); assert( images[ i ].rowPitch > 0 ); assert( images[ i ].slicePitch > 0 ); if ( ( images[ i ].rowPitch != ddsRowPitch ) || ( images[ i ].slicePitch != ddsSlicePitch ) ) { fastpath = false; } required += ddsSlicePitch; } assert( required > 0 ); blob.Release(); hr = blob.Initialize( required ); if ( FAILED(hr) ) return hr; auto pDestination = reinterpret_cast( blob.GetBufferPointer() ); assert( pDestination ); hr = _EncodeDDSHeader( metadata, flags, pDestination, blob.GetBufferSize(), required ); if ( FAILED(hr) ) { blob.Release(); return hr; } size_t remaining = blob.GetBufferSize() - required; pDestination += required; if ( !remaining ) { blob.Release(); return E_FAIL; } switch( metadata.dimension ) { case DDS_DIMENSION_TEXTURE1D: case DDS_DIMENSION_TEXTURE2D: { size_t index = 0; for( size_t item = 0; item < metadata.arraySize; ++item ) { for( size_t level = 0; level < metadata.mipLevels; ++level ) { if ( index >= nimages ) { blob.Release(); return E_FAIL; } if ( fastpath ) { size_t pixsize = images[ index ].slicePitch; if ( memcpy_s( pDestination, remaining, images[ index ].pixels, pixsize ) ) { blob.Release(); return E_FAIL; } pDestination += pixsize; remaining -= pixsize; } else { size_t ddsRowPitch, ddsSlicePitch; ComputePitch( metadata.format, images[ index ].width, images[ index ].height, ddsRowPitch, ddsSlicePitch, CP_FLAGS_NONE ); size_t rowPitch = images[ index ].rowPitch; const uint8_t * __restrict sPtr = reinterpret_cast(images[ index ].pixels); uint8_t * __restrict dPtr = reinterpret_cast(pDestination); size_t lines = ComputeScanlines( metadata.format, images[ index ].height ); size_t csize = std::min( rowPitch, ddsRowPitch ); size_t tremaining = remaining; for( size_t j = 0; j < lines; ++j ) { if ( memcpy_s( dPtr, tremaining, sPtr, csize ) ) { blob.Release(); return E_FAIL; } sPtr += rowPitch; dPtr += ddsRowPitch; tremaining -= ddsRowPitch; } pDestination += ddsSlicePitch; remaining -= ddsSlicePitch; } ++index; } } } break; case DDS_DIMENSION_TEXTURE3D: { if ( metadata.arraySize != 1 ) { blob.Release(); return E_FAIL; } size_t d = metadata.depth; size_t index = 0; for( size_t level = 0; level < metadata.mipLevels; ++level ) { for( size_t slice = 0; slice < d; ++slice ) { if ( index >= nimages ) { blob.Release(); return E_FAIL; } if ( fastpath ) { size_t pixsize = images[ index ].slicePitch; if ( memcpy_s( pDestination, remaining, images[ index ].pixels, pixsize ) ) { blob.Release(); return E_FAIL; } pDestination += pixsize; remaining -= pixsize; } else { size_t ddsRowPitch, ddsSlicePitch; ComputePitch( metadata.format, images[ index ].width, images[ index ].height, ddsRowPitch, ddsSlicePitch, CP_FLAGS_NONE ); size_t rowPitch = images[ index ].rowPitch; const uint8_t * __restrict sPtr = reinterpret_cast(images[ index ].pixels); uint8_t * __restrict dPtr = reinterpret_cast(pDestination); size_t lines = ComputeScanlines( metadata.format, images[ index ].height ); size_t csize = std::min( rowPitch, ddsRowPitch ); size_t tremaining = remaining; for( size_t j = 0; j < lines; ++j ) { if ( memcpy_s( dPtr, tremaining, sPtr, csize ) ) { blob.Release(); return E_FAIL; } sPtr += rowPitch; dPtr += ddsRowPitch; tremaining -= ddsRowPitch; } pDestination += ddsSlicePitch; remaining -= ddsSlicePitch; } ++index; } if ( d > 1 ) d >>= 1; } } break; default: blob.Release(); return E_FAIL; } return S_OK; } //------------------------------------------------------------------------------------- // Save a DDS file to disk //------------------------------------------------------------------------------------- _Use_decl_annotations_ HRESULT SaveToDDSFile( const Image* images, size_t nimages, const TexMetadata& metadata, DWORD flags, LPCWSTR szFile ) { if ( !szFile ) return E_INVALIDARG; // Create DDS Header const size_t MAX_HEADER_SIZE = sizeof(uint32_t) + sizeof(DDS_HEADER) + sizeof(DDS_HEADER_DXT10); uint8_t header[MAX_HEADER_SIZE]; size_t required; HRESULT hr = _EncodeDDSHeader( metadata, flags, header, MAX_HEADER_SIZE, required ); if ( FAILED(hr) ) return hr; // Create file and write header #if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) ScopedHandle hFile( safe_handle( CreateFile2( szFile, GENERIC_WRITE, 0, CREATE_ALWAYS, 0 ) ) ); #else ScopedHandle hFile( safe_handle( CreateFileW( szFile, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0 ) ) ); #endif if ( !hFile ) { return HRESULT_FROM_WIN32( GetLastError() ); } DWORD bytesWritten; if ( !WriteFile( hFile.get(), header, static_cast( required ), &bytesWritten, 0 ) ) { return HRESULT_FROM_WIN32( GetLastError() ); } if ( bytesWritten != required ) { return E_FAIL; } // Write images switch( metadata.dimension ) { case DDS_DIMENSION_TEXTURE1D: case DDS_DIMENSION_TEXTURE2D: { size_t index = 0; for( size_t item = 0; item < metadata.arraySize; ++item ) { for( size_t level = 0; level < metadata.mipLevels; ++level, ++index ) { if ( index >= nimages ) return E_FAIL; if ( !images[ index ].pixels ) return E_POINTER; assert( images[ index ].rowPitch > 0 ); assert( images[ index ].slicePitch > 0 ); size_t ddsRowPitch, ddsSlicePitch; ComputePitch( metadata.format, images[ index ].width, images[ index ].height, ddsRowPitch, ddsSlicePitch, CP_FLAGS_NONE ); if ( images[ index ].slicePitch == ddsSlicePitch ) { if ( !WriteFile( hFile.get(), images[ index ].pixels, static_cast( ddsSlicePitch ), &bytesWritten, 0 ) ) { return HRESULT_FROM_WIN32( GetLastError() ); } if ( bytesWritten != ddsSlicePitch ) { return E_FAIL; } } else { size_t rowPitch = images[ index ].rowPitch; if ( rowPitch < ddsRowPitch ) { // DDS uses 1-byte alignment, so if this is happening then the input pitch isn't actually a full line of data return E_FAIL; } const uint8_t * __restrict sPtr = reinterpret_cast(images[ index ].pixels); size_t lines = ComputeScanlines( metadata.format, images[ index ].height ); for( size_t j = 0; j < lines; ++j ) { if ( !WriteFile( hFile.get(), sPtr, static_cast( ddsRowPitch ), &bytesWritten, 0 ) ) { return HRESULT_FROM_WIN32( GetLastError() ); } if ( bytesWritten != ddsRowPitch ) { return E_FAIL; } sPtr += rowPitch; } } } } } break; case DDS_DIMENSION_TEXTURE3D: { if ( metadata.arraySize != 1 ) return E_FAIL; size_t d = metadata.depth; size_t index = 0; for( size_t level = 0; level < metadata.mipLevels; ++level ) { for( size_t slice = 0; slice < d; ++slice, ++index ) { if ( index >= nimages ) return E_FAIL; if ( !images[ index ].pixels ) return E_POINTER; assert( images[ index ].rowPitch > 0 ); assert( images[ index ].slicePitch > 0 ); size_t ddsRowPitch, ddsSlicePitch; ComputePitch( metadata.format, images[ index ].width, images[ index ].height, ddsRowPitch, ddsSlicePitch, CP_FLAGS_NONE ); if ( images[ index ].slicePitch == ddsSlicePitch ) { if ( !WriteFile( hFile.get(), images[ index ].pixels, static_cast( ddsSlicePitch ), &bytesWritten, 0 ) ) { return HRESULT_FROM_WIN32( GetLastError() ); } if ( bytesWritten != ddsSlicePitch ) { return E_FAIL; } } else { size_t rowPitch = images[ index ].rowPitch; if ( rowPitch < ddsRowPitch ) { // DDS uses 1-byte alignment, so if this is happening then the input pitch isn't actually a full line of data return E_FAIL; } const uint8_t * __restrict sPtr = reinterpret_cast(images[ index ].pixels); size_t lines = ComputeScanlines( metadata.format, images[ index ].height ); for( size_t j = 0; j < lines; ++j ) { if ( !WriteFile( hFile.get(), sPtr, static_cast( ddsRowPitch ), &bytesWritten, 0 ) ) { return HRESULT_FROM_WIN32( GetLastError() ); } if ( bytesWritten != ddsRowPitch ) { return E_FAIL; } sPtr += rowPitch; } } } if ( d > 1 ) d >>= 1; } } break; default: return E_FAIL; } return S_OK; } }; // namespace ================================================ FILE: 3rdParty/DirectXTex/DirectXTex/DirectXTexFlipRotate.cpp ================================================ //------------------------------------------------------------------------------------- // DirectXTexFlipRotate.cpp // // DirectX Texture Library - Image flip/rotate operations // // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A // PARTICULAR PURPOSE. // // Copyright (c) Microsoft Corporation. All rights reserved. // // http://go.microsoft.com/fwlink/?LinkId=248926 //------------------------------------------------------------------------------------- #include "directxtexp.h" using Microsoft::WRL::ComPtr; namespace DirectX { //------------------------------------------------------------------------------------- // Do flip/rotate operation using WIC //------------------------------------------------------------------------------------- static HRESULT _PerformFlipRotateUsingWIC( _In_ const Image& srcImage, _In_ DWORD flags, _In_ const WICPixelFormatGUID& pfGUID, _In_ const Image& destImage ) { if ( !srcImage.pixels || !destImage.pixels ) return E_POINTER; assert( srcImage.format == destImage.format ); IWICImagingFactory* pWIC = _GetWIC(); if ( !pWIC ) return E_NOINTERFACE; ComPtr source; HRESULT hr = pWIC->CreateBitmapFromMemory( static_cast( srcImage.width ), static_cast( srcImage.height ), pfGUID, static_cast( srcImage.rowPitch ), static_cast( srcImage.slicePitch ), srcImage.pixels, source.GetAddressOf() ); if ( FAILED(hr) ) return hr; ComPtr FR; hr = pWIC->CreateBitmapFlipRotator( FR.GetAddressOf() ); if ( FAILED(hr) ) return hr; hr = FR->Initialize( source.Get(), static_cast( flags ) ); if ( FAILED(hr) ) return hr; WICPixelFormatGUID pfFR; hr = FR->GetPixelFormat( &pfFR ); if ( FAILED(hr) ) return hr; if ( memcmp( &pfFR, &pfGUID, sizeof(GUID) ) != 0 ) { // Flip/rotate should return the same format as the source... return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); } UINT nwidth, nheight; hr = FR->GetSize( &nwidth, &nheight ); if ( FAILED(hr) ) return hr; if ( destImage.width != nwidth || destImage.height != nheight ) return E_FAIL; hr = FR->CopyPixels( 0, static_cast( destImage.rowPitch ), static_cast( destImage.slicePitch ), destImage.pixels ); if ( FAILED(hr) ) return hr; return S_OK; } //------------------------------------------------------------------------------------- // Do conversion, flip/rotate using WIC, conversion cycle //------------------------------------------------------------------------------------- static HRESULT _PerformFlipRotateViaF32( _In_ const Image& srcImage, _In_ DWORD flags, _In_ const Image& destImage ) { if ( !srcImage.pixels || !destImage.pixels ) return E_POINTER; assert( srcImage.format != DXGI_FORMAT_R32G32B32A32_FLOAT ); assert( srcImage.format == destImage.format ); ScratchImage temp; HRESULT hr = _ConvertToR32G32B32A32( srcImage, temp ); if ( FAILED(hr) ) return hr; const Image *tsrc = temp.GetImage( 0, 0, 0 ); if ( !tsrc ) return E_POINTER; ScratchImage rtemp; hr = rtemp.Initialize2D( DXGI_FORMAT_R32G32B32A32_FLOAT, destImage.width, destImage.height, 1, 1 ); if ( FAILED(hr) ) return hr; const Image *tdest = rtemp.GetImage( 0, 0, 0 ); if ( !tdest ) return E_POINTER; hr = _PerformFlipRotateUsingWIC( *tsrc, flags, GUID_WICPixelFormat128bppRGBAFloat, *tdest ); if ( FAILED(hr) ) return hr; temp.Release(); hr = _ConvertFromR32G32B32A32( *tdest, destImage ); if ( FAILED(hr) ) return hr; return S_OK; } //===================================================================================== // Entry-points //===================================================================================== //------------------------------------------------------------------------------------- // Flip/rotate image //------------------------------------------------------------------------------------- _Use_decl_annotations_ HRESULT FlipRotate( const Image& srcImage, DWORD flags, ScratchImage& image ) { if ( !srcImage.pixels ) return E_POINTER; if ( !flags ) return E_INVALIDARG; #ifdef _M_X64 if ( (srcImage.width > 0xFFFFFFFF) || (srcImage.height > 0xFFFFFFFF) ) return E_INVALIDARG; #endif if ( IsCompressed( srcImage.format ) ) { // We don't support flip/rotate operations on compressed images return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); } static_assert( TEX_FR_ROTATE0 == WICBitmapTransformRotate0, "TEX_FR_ROTATE0 no longer matches WIC" ); static_assert( TEX_FR_ROTATE90 == WICBitmapTransformRotate90, "TEX_FR_ROTATE90 no longer matches WIC" ); static_assert( TEX_FR_ROTATE180 == WICBitmapTransformRotate180, "TEX_FR_ROTATE180 no longer matches WIC" ); static_assert( TEX_FR_ROTATE270 == WICBitmapTransformRotate270, "TEX_FR_ROTATE270 no longer matches WIC" ); static_assert( TEX_FR_FLIP_HORIZONTAL == WICBitmapTransformFlipHorizontal, "TEX_FR_FLIP_HORIZONTAL no longer matches WIC" ); static_assert( TEX_FR_FLIP_VERTICAL == WICBitmapTransformFlipVertical, "TEX_FR_FLIP_VERTICAL no longer matches WIC" ); // Only supports 90, 180, 270, or no rotation flags... not a combination of rotation flags switch ( flags & (TEX_FR_ROTATE90|TEX_FR_ROTATE180|TEX_FR_ROTATE270) ) { case 0: case TEX_FR_ROTATE90: case TEX_FR_ROTATE180: case TEX_FR_ROTATE270: break; default: return E_INVALIDARG; } size_t nwidth = srcImage.width; size_t nheight = srcImage.height; if (flags & (TEX_FR_ROTATE90|TEX_FR_ROTATE270)) { nwidth = srcImage.height; nheight = srcImage.width; } HRESULT hr = image.Initialize2D( srcImage.format, nwidth, nheight, 1, 1 ); if ( FAILED(hr) ) return hr; const Image *rimage = image.GetImage( 0, 0, 0 ); if ( !rimage ) return E_POINTER; WICPixelFormatGUID pfGUID; if ( _DXGIToWIC( srcImage.format, pfGUID ) ) { // Case 1: Source format is supported by Windows Imaging Component hr = _PerformFlipRotateUsingWIC( srcImage, flags, pfGUID, *rimage ); } else { // Case 2: Source format is not supported by WIC, so we have to convert, flip/rotate, and convert back hr = _PerformFlipRotateViaF32( srcImage, flags, *rimage ); } if ( FAILED(hr) ) { image.Release(); return hr; } return S_OK; } //------------------------------------------------------------------------------------- // Flip/rotate image (complex) //------------------------------------------------------------------------------------- _Use_decl_annotations_ HRESULT FlipRotate( const Image* srcImages, size_t nimages, const TexMetadata& metadata, DWORD flags, ScratchImage& result ) { if ( !srcImages || !nimages ) return E_INVALIDARG; if ( IsCompressed( metadata.format ) ) { // We don't support flip/rotate operations on compressed images return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); } static_assert( TEX_FR_ROTATE0 == WICBitmapTransformRotate0, "TEX_FR_ROTATE0 no longer matches WIC" ); static_assert( TEX_FR_ROTATE90 == WICBitmapTransformRotate90, "TEX_FR_ROTATE90 no longer matches WIC" ); static_assert( TEX_FR_ROTATE180 == WICBitmapTransformRotate180, "TEX_FR_ROTATE180 no longer matches WIC" ); static_assert( TEX_FR_ROTATE270 == WICBitmapTransformRotate270, "TEX_FR_ROTATE270 no longer matches WIC" ); static_assert( TEX_FR_FLIP_HORIZONTAL == WICBitmapTransformFlipHorizontal, "TEX_FR_FLIP_HORIZONTAL no longer matches WIC" ); static_assert( TEX_FR_FLIP_VERTICAL == WICBitmapTransformFlipVertical, "TEX_FR_FLIP_VERTICAL no longer matches WIC" ); // Only supports 90, 180, 270, or no rotation flags... not a combination of rotation flags switch ( flags & (TEX_FR_ROTATE90|TEX_FR_ROTATE180|TEX_FR_ROTATE270) ) { case 0: case TEX_FR_ROTATE90: case TEX_FR_ROTATE180: case TEX_FR_ROTATE270: break; default: return E_INVALIDARG; } TexMetadata mdata2 = metadata; bool flipwh = false; if (flags & (TEX_FR_ROTATE90|TEX_FR_ROTATE270)) { flipwh = true; mdata2.width = metadata.height; mdata2.height = metadata.width; } HRESULT hr = result.Initialize( mdata2 ); if ( FAILED(hr) ) return hr; if ( nimages != result.GetImageCount() ) { result.Release(); return E_FAIL; } const Image* dest = result.GetImages(); if ( !dest ) { result.Release(); return E_POINTER; } WICPixelFormatGUID pfGUID; bool wicpf = _DXGIToWIC( metadata.format, pfGUID ); for( size_t index=0; index < nimages; ++index ) { const Image& src = srcImages[ index ]; if ( src.format != metadata.format ) { result.Release(); return E_FAIL; } #ifdef _M_X64 if ( (src.width > 0xFFFFFFFF) || (src.height > 0xFFFFFFFF) ) return E_FAIL; #endif const Image& dst = dest[ index ]; assert( dst.format == metadata.format ); if ( flipwh ) { if ( src.width != dst.height || src.height != dst.width ) { result.Release(); return E_FAIL; } } else { if ( src.width != dst.width || src.height != dst.height ) { result.Release(); return E_FAIL; } } if (wicpf) { // Case 1: Source format is supported by Windows Imaging Component hr = _PerformFlipRotateUsingWIC( src, flags, pfGUID, dst ); } else { // Case 2: Source format is not supported by WIC, so we have to convert, flip/rotate, and convert back hr = _PerformFlipRotateViaF32( src, flags, dst ); } if ( FAILED(hr) ) { result.Release(); return hr; } } return S_OK; } }; // namespace ================================================ FILE: 3rdParty/DirectXTex/DirectXTex/DirectXTexImage.cpp ================================================ //------------------------------------------------------------------------------------- // DirectXTexImage.cpp // // DirectX Texture Library - Image container // // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A // PARTICULAR PURPOSE. // // Copyright (c) Microsoft Corporation. All rights reserved. // // http://go.microsoft.com/fwlink/?LinkId=248926 //------------------------------------------------------------------------------------- #include "directxtexp.h" namespace DirectX { extern bool _CalculateMipLevels( _In_ size_t width, _In_ size_t height, _Inout_ size_t& mipLevels ); extern bool _CalculateMipLevels3D( _In_ size_t width, _In_ size_t height, _In_ size_t depth, _Inout_ size_t& mipLevels ); extern bool _IsAlphaAllOpaqueBC( _In_ const Image& cImage ); //------------------------------------------------------------------------------------- // Determines number of image array entries and pixel size //------------------------------------------------------------------------------------- _Use_decl_annotations_ void _DetermineImageArray( const TexMetadata& metadata, DWORD cpFlags, size_t& nImages, size_t& pixelSize ) { assert( metadata.width > 0 && metadata.height > 0 && metadata.depth > 0 ); assert( metadata.arraySize > 0 ); assert( metadata.mipLevels > 0 ); size_t _pixelSize = 0; size_t _nimages = 0; switch( metadata.dimension ) { case TEX_DIMENSION_TEXTURE1D: case TEX_DIMENSION_TEXTURE2D: for( size_t item = 0; item < metadata.arraySize; ++item ) { size_t w = metadata.width; size_t h = metadata.height; for( size_t level=0; level < metadata.mipLevels; ++level ) { size_t rowPitch, slicePitch; ComputePitch( metadata.format, w, h, rowPitch, slicePitch, cpFlags ); _pixelSize += slicePitch; ++_nimages; if ( h > 1 ) h >>= 1; if ( w > 1 ) w >>= 1; } } break; case TEX_DIMENSION_TEXTURE3D: { size_t w = metadata.width; size_t h = metadata.height; size_t d = metadata.depth; for( size_t level=0; level < metadata.mipLevels; ++level ) { size_t rowPitch, slicePitch; ComputePitch( metadata.format, w, h, rowPitch, slicePitch, cpFlags ); for( size_t slice=0; slice < d; ++slice ) { _pixelSize += slicePitch; ++_nimages; } if ( h > 1 ) h >>= 1; if ( w > 1 ) w >>= 1; if ( d > 1 ) d >>= 1; } } break; default: assert( false ); break; } nImages = _nimages; pixelSize = _pixelSize; } //------------------------------------------------------------------------------------- // Fills in the image array entries //------------------------------------------------------------------------------------- _Use_decl_annotations_ bool _SetupImageArray( uint8_t *pMemory, size_t pixelSize, const TexMetadata& metadata, DWORD cpFlags, Image* images, size_t nImages ) { assert( pMemory ); assert( pixelSize > 0 ); assert( nImages > 0 ); if ( !images ) return false; size_t index = 0; uint8_t* pixels = pMemory; const uint8_t* pEndBits = pMemory + pixelSize; switch( metadata.dimension ) { case TEX_DIMENSION_TEXTURE1D: case TEX_DIMENSION_TEXTURE2D: if (metadata.arraySize == 0 || metadata.mipLevels == 0) { return false; } for( size_t item = 0; item < metadata.arraySize; ++item ) { size_t w = metadata.width; size_t h = metadata.height; for( size_t level=0; level < metadata.mipLevels; ++level ) { if ( index >= nImages ) { return false; } size_t rowPitch, slicePitch; ComputePitch( metadata.format, w, h, rowPitch, slicePitch, cpFlags ); images[index].width = w; images[index].height = h; images[index].format = metadata.format; images[index].rowPitch = rowPitch; images[index].slicePitch = slicePitch; images[index].pixels = pixels; ++index; pixels += slicePitch; if ( pixels > pEndBits ) { return false; } if ( h > 1 ) h >>= 1; if ( w > 1 ) w >>= 1; } } return true; case TEX_DIMENSION_TEXTURE3D: { if (metadata.mipLevels == 0 || metadata.depth == 0) { return false; } size_t w = metadata.width; size_t h = metadata.height; size_t d = metadata.depth; for( size_t level=0; level < metadata.mipLevels; ++level ) { size_t rowPitch, slicePitch; ComputePitch( metadata.format, w, h, rowPitch, slicePitch, cpFlags ); for( size_t slice=0; slice < d; ++slice ) { if ( index >= nImages ) { return false; } // We use the same memory organization that Direct3D 11 needs for D3D11_SUBRESOURCE_DATA // with all slices of a given miplevel being continuous in memory images[index].width = w; images[index].height = h; images[index].format = metadata.format; images[index].rowPitch = rowPitch; images[index].slicePitch = slicePitch; images[index].pixels = pixels; ++index; pixels += slicePitch; if ( pixels > pEndBits ) { return false; } } if ( h > 1 ) h >>= 1; if ( w > 1 ) w >>= 1; if ( d > 1 ) d >>= 1; } } return true; default: return false; } } //===================================================================================== // ScratchImage - Bitmap image container //===================================================================================== ScratchImage& ScratchImage::operator= (ScratchImage&& moveFrom) { if ( this != &moveFrom ) { Release(); _nimages = moveFrom._nimages; _size = moveFrom._size; _metadata = moveFrom._metadata; _image = moveFrom._image; _memory = moveFrom._memory; moveFrom._nimages = 0; moveFrom._size = 0; moveFrom._image = nullptr; moveFrom._memory = nullptr; } return *this; } //------------------------------------------------------------------------------------- // Methods //------------------------------------------------------------------------------------- _Use_decl_annotations_ HRESULT ScratchImage::Initialize( const TexMetadata& mdata, DWORD flags ) { if ( !IsValid(mdata.format) ) return E_INVALIDARG; if ( IsPalettized(mdata.format) ) return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); size_t mipLevels = mdata.mipLevels; switch( mdata.dimension ) { case TEX_DIMENSION_TEXTURE1D: if ( !mdata.width || mdata.height != 1 || mdata.depth != 1 || !mdata.arraySize ) return E_INVALIDARG; if ( !_CalculateMipLevels(mdata.width,1,mipLevels) ) return E_INVALIDARG; break; case TEX_DIMENSION_TEXTURE2D: if ( !mdata.width || !mdata.height || mdata.depth != 1 || !mdata.arraySize ) return E_INVALIDARG; if ( mdata.IsCubemap() ) { if ( (mdata.arraySize % 6) != 0 ) return E_INVALIDARG; } if ( !_CalculateMipLevels(mdata.width,mdata.height,mipLevels) ) return E_INVALIDARG; break; case TEX_DIMENSION_TEXTURE3D: if ( !mdata.width || !mdata.height || !mdata.depth || mdata.arraySize != 1 ) return E_INVALIDARG; if ( !_CalculateMipLevels3D(mdata.width,mdata.height,mdata.depth,mipLevels) ) return E_INVALIDARG; break; default: return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); } Release(); _metadata.width = mdata.width; _metadata.height = mdata.height; _metadata.depth = mdata.depth; _metadata.arraySize = mdata.arraySize; _metadata.mipLevels = mipLevels; _metadata.miscFlags = mdata.miscFlags; _metadata.miscFlags2 = mdata.miscFlags2; _metadata.format = mdata.format; _metadata.dimension = mdata.dimension; size_t pixelSize, nimages; _DetermineImageArray( _metadata, flags, nimages, pixelSize ); _image = new (std::nothrow) Image[ nimages ]; if ( !_image ) return E_OUTOFMEMORY; _nimages = nimages; memset( _image, 0, sizeof(Image) * nimages ); _memory = reinterpret_cast( _aligned_malloc( pixelSize, 16 ) ); if ( !_memory ) { Release(); return E_OUTOFMEMORY; } _size = pixelSize; if ( !_SetupImageArray( _memory, pixelSize, _metadata, flags, _image, nimages ) ) { Release(); return E_FAIL; } return S_OK; } _Use_decl_annotations_ HRESULT ScratchImage::Initialize1D( DXGI_FORMAT fmt, size_t length, size_t arraySize, size_t mipLevels, DWORD flags ) { if ( !length || !arraySize ) return E_INVALIDARG; // 1D is a special case of the 2D case HRESULT hr = Initialize2D( fmt, length, 1, arraySize, mipLevels, flags ); if ( FAILED(hr) ) return hr; _metadata.dimension = TEX_DIMENSION_TEXTURE1D; return S_OK; } _Use_decl_annotations_ HRESULT ScratchImage::Initialize2D( DXGI_FORMAT fmt, size_t width, size_t height, size_t arraySize, size_t mipLevels, DWORD flags ) { if ( !IsValid(fmt) || !width || !height || !arraySize ) return E_INVALIDARG; if ( IsPalettized(fmt) ) return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); if ( !_CalculateMipLevels(width,height,mipLevels) ) return E_INVALIDARG; Release(); _metadata.width = width; _metadata.height = height; _metadata.depth = 1; _metadata.arraySize = arraySize; _metadata.mipLevels = mipLevels; _metadata.miscFlags = 0; _metadata.miscFlags2 = 0; _metadata.format = fmt; _metadata.dimension = TEX_DIMENSION_TEXTURE2D; size_t pixelSize, nimages; _DetermineImageArray( _metadata, flags, nimages, pixelSize ); _image = new (std::nothrow) Image[ nimages ]; if ( !_image ) return E_OUTOFMEMORY; _nimages = nimages; memset( _image, 0, sizeof(Image) * nimages ); _memory = reinterpret_cast( _aligned_malloc( pixelSize, 16 ) ); if ( !_memory ) { Release(); return E_OUTOFMEMORY; } // clear the memory! memset(_memory, 0, pixelSize); _size = pixelSize; if ( !_SetupImageArray( _memory, pixelSize, _metadata, flags, _image, nimages ) ) { Release(); return E_FAIL; } return S_OK; } _Use_decl_annotations_ HRESULT ScratchImage::Initialize3D( DXGI_FORMAT fmt, size_t width, size_t height, size_t depth, size_t mipLevels, DWORD flags ) { if ( !IsValid(fmt) || !width || !height || !depth ) return E_INVALIDARG; if ( IsPalettized(fmt) ) return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); if ( !_CalculateMipLevels3D(width,height,depth,mipLevels) ) return E_INVALIDARG; Release(); _metadata.width = width; _metadata.height = height; _metadata.depth = depth; _metadata.arraySize = 1; // Direct3D 10.x/11 does not support arrays of 3D textures _metadata.mipLevels = mipLevels; _metadata.miscFlags = 0; _metadata.miscFlags2 = 0; _metadata.format = fmt; _metadata.dimension = TEX_DIMENSION_TEXTURE3D; size_t pixelSize, nimages; _DetermineImageArray( _metadata, flags, nimages, pixelSize ); _image = new (std::nothrow) Image[ nimages ]; if ( !_image ) { Release(); return E_OUTOFMEMORY; } _nimages = nimages; memset( _image, 0, sizeof(Image) * nimages ); _memory = reinterpret_cast( _aligned_malloc( pixelSize, 16 ) ); if ( !_memory ) { Release(); return E_OUTOFMEMORY; } _size = pixelSize; if ( !_SetupImageArray( _memory, pixelSize, _metadata, flags, _image, nimages ) ) { Release(); return E_FAIL; } return S_OK; } _Use_decl_annotations_ HRESULT ScratchImage::InitializeCube( DXGI_FORMAT fmt, size_t width, size_t height, size_t nCubes, size_t mipLevels, DWORD flags ) { if ( !width || !height || !nCubes ) return E_INVALIDARG; // A DirectX11 cubemap is just a 2D texture array that is a multiple of 6 for each cube HRESULT hr = Initialize2D( fmt, width, height, nCubes * 6, mipLevels, flags ); if ( FAILED(hr) ) return hr; _metadata.miscFlags |= TEX_MISC_TEXTURECUBE; return S_OK; } _Use_decl_annotations_ HRESULT ScratchImage::InitializeFromImage( const Image& srcImage, bool allow1D, DWORD flags ) { HRESULT hr = ( srcImage.height > 1 || !allow1D ) ? Initialize2D( srcImage.format, srcImage.width, srcImage.height, 1, 1, flags ) : Initialize1D( srcImage.format, srcImage.width, 1, 1, flags ); if ( FAILED(hr) ) return hr; size_t rowCount = ComputeScanlines( srcImage.format, srcImage.height ); if ( !rowCount ) return E_UNEXPECTED; const uint8_t* sptr = reinterpret_cast( srcImage.pixels ); if ( !sptr ) return E_POINTER; auto dptr = reinterpret_cast( _image[0].pixels ); if ( !dptr ) return E_POINTER; size_t spitch = srcImage.rowPitch; size_t dpitch = _image[0].rowPitch; size_t size = std::min( dpitch, spitch ); for( size_t y = 0; y < rowCount; ++y ) { memcpy_s( dptr, dpitch, sptr, size ); sptr += spitch; dptr += dpitch; } return S_OK; } _Use_decl_annotations_ HRESULT ScratchImage::InitializeArrayFromImages( const Image* images, size_t nImages, bool allow1D, DWORD flags ) { if ( !images || !nImages ) return E_INVALIDARG; DXGI_FORMAT format = images[0].format; size_t width = images[0].width; size_t height = images[0].height; for( size_t index=0; index < nImages; ++index ) { if ( !images[index].pixels ) return E_POINTER; if ( images[index].format != format || images[index].width != width || images[index].height != height ) { // All images must be the same format, width, and height return E_FAIL; } } HRESULT hr = ( height > 1 || !allow1D ) ? Initialize2D( format, width, height, nImages, 1, flags ) : Initialize1D( format, width, nImages, 1, flags ); if ( FAILED(hr) ) return hr; size_t rowCount = ComputeScanlines( format, height ); if ( !rowCount ) return E_UNEXPECTED; for( size_t index=0; index < nImages; ++index ) { auto sptr = reinterpret_cast( images[index].pixels ); if ( !sptr ) return E_POINTER; assert( index < _nimages ); auto dptr = reinterpret_cast( _image[index].pixels ); if ( !dptr ) return E_POINTER; size_t spitch = images[index].rowPitch; size_t dpitch = _image[index].rowPitch; size_t size = std::min( dpitch, spitch ); for( size_t y = 0; y < rowCount; ++y ) { memcpy_s( dptr, dpitch, sptr, size ); sptr += spitch; dptr += dpitch; } } return S_OK; } _Use_decl_annotations_ HRESULT ScratchImage::InitializeCubeFromImages( const Image* images, size_t nImages, DWORD flags ) { if ( !images || !nImages ) return E_INVALIDARG; // A DirectX11 cubemap is just a 2D texture array that is a multiple of 6 for each cube if ( ( nImages % 6 ) != 0 ) return E_INVALIDARG; HRESULT hr = InitializeArrayFromImages( images, nImages, false, flags ); if ( FAILED(hr) ) return hr; _metadata.miscFlags |= TEX_MISC_TEXTURECUBE; return S_OK; } _Use_decl_annotations_ HRESULT ScratchImage::Initialize3DFromImages( const Image* images, size_t depth, DWORD flags ) { if ( !images || !depth ) return E_INVALIDARG; DXGI_FORMAT format = images[0].format; size_t width = images[0].width; size_t height = images[0].height; for( size_t slice=0; slice < depth; ++slice ) { if ( !images[slice].pixels ) return E_POINTER; if ( images[slice].format != format || images[slice].width != width || images[slice].height != height ) { // All images must be the same format, width, and height return E_FAIL; } } HRESULT hr = Initialize3D( format, width, height, depth, 1, flags ); if ( FAILED(hr) ) return hr; size_t rowCount = ComputeScanlines( format, height ); if ( !rowCount ) return E_UNEXPECTED; for( size_t slice=0; slice < depth; ++slice ) { auto sptr = reinterpret_cast( images[slice].pixels ); if ( !sptr ) return E_POINTER; assert( slice < _nimages ); auto dptr = reinterpret_cast( _image[slice].pixels ); if ( !dptr ) return E_POINTER; size_t spitch = images[slice].rowPitch; size_t dpitch = _image[slice].rowPitch; size_t size = std::min( dpitch, spitch ); for( size_t y = 0; y < rowCount; ++y ) { memcpy_s( dptr, dpitch, sptr, size ); sptr += spitch; dptr += dpitch; } } return S_OK; } void ScratchImage::Release() { _nimages = 0; _size = 0; if ( _image ) { delete [] _image; _image = 0; } if ( _memory ) { _aligned_free( _memory ); _memory = 0; } memset(&_metadata, 0, sizeof(_metadata)); } _Use_decl_annotations_ bool ScratchImage::OverrideFormat( DXGI_FORMAT f ) { if ( !_image ) return false; if ( !IsValid( f ) || IsPlanar( f ) || IsPalettized( f ) ) return false; for( size_t index = 0; index < _nimages; ++index ) { _image[ index ].format = f; } _metadata.format = f; return true; } _Use_decl_annotations_ const Image* ScratchImage::GetImage(size_t mip, size_t item, size_t slice) const { if ( mip >= _metadata.mipLevels ) return nullptr; size_t index = 0; switch( _metadata.dimension ) { case TEX_DIMENSION_TEXTURE1D: case TEX_DIMENSION_TEXTURE2D: if ( slice > 0 ) return nullptr; if ( item >= _metadata.arraySize ) return nullptr; index = item*( _metadata.mipLevels ) + mip; break; case TEX_DIMENSION_TEXTURE3D: if ( item > 0 ) { // No support for arrays of volumes return nullptr; } else { size_t d = _metadata.depth; for( size_t level = 0; level < mip; ++level ) { index += d; if ( d > 1 ) d >>= 1; } if ( slice >= d ) return nullptr; index += slice; } break; default: return nullptr; } return &_image[index]; } bool ScratchImage::IsAlphaAllOpaque() const { if ( !_image ) return false; if ( !HasAlpha( _metadata.format ) ) return true; if ( IsCompressed( _metadata.format ) ) { for( size_t index = 0; index < _nimages; ++index ) { if ( !_IsAlphaAllOpaqueBC( _image[ index ] ) ) return false; } } else { ScopedAlignedArrayXMVECTOR scanline( reinterpret_cast( _aligned_malloc( (sizeof(XMVECTOR)*_metadata.width), 16 ) ) ); if ( !scanline ) return false; static const XMVECTORF32 threshold = { 0.99f, 0.99f, 0.99f, 0.99f }; for( size_t index = 0; index < _nimages; ++index ) { #pragma warning( suppress : 6011 ) const Image& img = _image[ index ]; const uint8_t *pPixels = img.pixels; assert( pPixels ); for( size_t h = 0; h < img.height; ++h ) { if ( !_LoadScanline( scanline.get(), img.width, pPixels, img.rowPitch, img.format ) ) return false; XMVECTOR* ptr = scanline.get(); for( size_t w = 0; w < img.width; ++w ) { XMVECTOR alpha = XMVectorSplatW( *ptr ); if ( XMVector4Less( alpha, threshold ) ) return false; ++ptr; } pPixels += img.rowPitch; } } } return true; } }; // namespace ================================================ FILE: 3rdParty/DirectXTex/DirectXTex/DirectXTexMipmaps.cpp ================================================ //------------------------------------------------------------------------------------- // DirectXTexMipMaps.cpp // // DirectX Texture Library - Mip-map generation // // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A // PARTICULAR PURPOSE. // // Copyright (c) Microsoft Corporation. All rights reserved. // // http://go.microsoft.com/fwlink/?LinkId=248926 //------------------------------------------------------------------------------------- #include "directxtexp.h" #include "filters.h" using Microsoft::WRL::ComPtr; namespace DirectX { //------------------------------------------------------------------------------------- // Mipmap helper functions //------------------------------------------------------------------------------------- inline static bool ispow2( _In_ size_t x ) { return ((x != 0) && !(x & (x - 1))); } //--- mipmap (1D/2D) levels computation --- static size_t _CountMips( _In_ size_t width, _In_ size_t height ) { size_t mipLevels = 1; while ( height > 1 || width > 1 ) { if ( height > 1 ) height >>= 1; if ( width > 1 ) width >>= 1; ++mipLevels; } return mipLevels; } bool _CalculateMipLevels( _In_ size_t width, _In_ size_t height, _Inout_ size_t& mipLevels ) { if ( mipLevels > 1 ) { size_t maxMips = _CountMips(width,height); if ( mipLevels > maxMips ) return false; } else if ( mipLevels == 0 ) { mipLevels = _CountMips(width,height); } else { mipLevels = 1; } return true; } //--- volume mipmap (3D) levels computation --- static size_t _CountMips3D( _In_ size_t width, _In_ size_t height, _In_ size_t depth ) { size_t mipLevels = 1; while ( height > 1 || width > 1 || depth > 1 ) { if ( height > 1 ) height >>= 1; if ( width > 1 ) width >>= 1; if ( depth > 1 ) depth >>= 1; ++mipLevels; } return mipLevels; } bool _CalculateMipLevels3D( _In_ size_t width, _In_ size_t height, _In_ size_t depth, _Inout_ size_t& mipLevels ) { if ( mipLevels > 1 ) { size_t maxMips = _CountMips3D(width,height,depth); if ( mipLevels > maxMips ) return false; } else if ( mipLevels == 0 ) { mipLevels = _CountMips3D(width,height,depth); } else { mipLevels = 1; } return true; } //------------------------------------------------------------------------------------- // WIC related helper functions //------------------------------------------------------------------------------------- static HRESULT _EnsureWicBitmapPixelFormat( _In_ IWICImagingFactory* pWIC, _In_ IWICBitmap* src, _In_ DWORD filter, _In_ const WICPixelFormatGUID& desiredPixelFormat, _Deref_out_ IWICBitmap** dest ) { if ( !pWIC || !src || !dest ) return E_POINTER; *dest = nullptr; WICPixelFormatGUID actualPixelFormat; HRESULT hr = src->GetPixelFormat( &actualPixelFormat ); if ( SUCCEEDED(hr) ) { if ( memcmp( &actualPixelFormat, &desiredPixelFormat, sizeof(WICPixelFormatGUID) ) == 0 ) { src->AddRef(); *dest = src; } else { ComPtr converter; hr = pWIC->CreateFormatConverter( converter.GetAddressOf() ); if ( SUCCEEDED(hr) ) { BOOL canConvert = FALSE; hr = converter->CanConvert( actualPixelFormat, desiredPixelFormat, &canConvert ); if ( FAILED(hr) || !canConvert ) { return E_UNEXPECTED; } } if ( SUCCEEDED(hr) ) { hr = converter->Initialize( src, desiredPixelFormat, _GetWICDither(filter), 0, 0, WICBitmapPaletteTypeCustom ); } if ( SUCCEEDED(hr) ) { hr = pWIC->CreateBitmapFromSource( converter.Get(), WICBitmapCacheOnDemand, dest ); } } } return hr; } //--- Resizing color and alpha channels separately using WIC --- HRESULT _ResizeSeparateColorAndAlpha( _In_ IWICImagingFactory* pWIC, _In_ IWICBitmap* original, _In_ size_t newWidth, _In_ size_t newHeight, _In_ DWORD filter, _Inout_ const Image* img ) { if ( !pWIC || !original || !img ) return E_POINTER; const WICBitmapInterpolationMode interpolationMode = _GetWICInterp(filter); WICPixelFormatGUID desiredPixelFormat = GUID_WICPixelFormatUndefined; HRESULT hr = original->GetPixelFormat( &desiredPixelFormat ); size_t colorBytesInPixel = 0; size_t colorBytesPerPixel = 0; size_t colorWithAlphaBytesPerPixel = 0; WICPixelFormatGUID colorPixelFormat = GUID_WICPixelFormatUndefined; WICPixelFormatGUID colorWithAlphaPixelFormat = GUID_WICPixelFormatUndefined; if ( SUCCEEDED(hr) ) { ComPtr componentInfo; hr = pWIC->CreateComponentInfo( desiredPixelFormat, componentInfo.GetAddressOf() ); ComPtr pixelFormatInfo; if ( SUCCEEDED(hr) ) { hr = componentInfo.As( &pixelFormatInfo ); } UINT bitsPerPixel = 0; if ( SUCCEEDED(hr) ) { hr = pixelFormatInfo->GetBitsPerPixel( &bitsPerPixel ); } if ( SUCCEEDED(hr) ) { if ( bitsPerPixel <= 32 ) { colorBytesInPixel = colorBytesPerPixel = 3; colorPixelFormat = GUID_WICPixelFormat24bppBGR; colorWithAlphaBytesPerPixel = 4; colorWithAlphaPixelFormat = GUID_WICPixelFormat32bppBGRA; } else { #if(_WIN32_WINNT >= _WIN32_WINNT_WIN8) || defined(_WIN7_PLATFORM_UPDATE) if ( _IsWIC2() ) { colorBytesInPixel = colorBytesPerPixel = 12; colorPixelFormat = GUID_WICPixelFormat96bppRGBFloat; } else #endif { colorBytesInPixel = 12; colorBytesPerPixel = 16; colorPixelFormat = GUID_WICPixelFormat128bppRGBFloat; } colorWithAlphaBytesPerPixel = 16; colorWithAlphaPixelFormat = GUID_WICPixelFormat128bppRGBAFloat; } } } // Resize color only image (no alpha channel) ComPtr resizedColor; if ( SUCCEEDED(hr) ) { ComPtr colorScaler; hr = pWIC->CreateBitmapScaler( colorScaler.GetAddressOf() ); if ( SUCCEEDED(hr) ) { ComPtr converted; hr = _EnsureWicBitmapPixelFormat( pWIC, original, filter, colorPixelFormat, converted.GetAddressOf() ); if ( SUCCEEDED(hr) ) { hr = colorScaler->Initialize( converted.Get(), static_cast(newWidth), static_cast(newHeight), interpolationMode ); } } if ( SUCCEEDED(hr) ) { ComPtr resized; hr = pWIC->CreateBitmapFromSource( colorScaler.Get(), WICBitmapCacheOnDemand, resized.GetAddressOf() ); if ( SUCCEEDED(hr) ) { hr = _EnsureWicBitmapPixelFormat( pWIC, resized.Get(), filter, colorPixelFormat, resizedColor.GetAddressOf() ); } } } // Resize color+alpha image ComPtr resizedColorWithAlpha; if ( SUCCEEDED(hr) ) { ComPtr colorWithAlphaScaler; hr = pWIC->CreateBitmapScaler( colorWithAlphaScaler.GetAddressOf() ); if ( SUCCEEDED(hr) ) { ComPtr converted; hr = _EnsureWicBitmapPixelFormat( pWIC, original, filter, colorWithAlphaPixelFormat, converted.GetAddressOf() ); if ( SUCCEEDED(hr) ) { hr = colorWithAlphaScaler->Initialize( converted.Get(), static_cast(newWidth), static_cast(newHeight), interpolationMode ); } } if ( SUCCEEDED(hr) ) { ComPtr resized; hr = pWIC->CreateBitmapFromSource( colorWithAlphaScaler.Get(), WICBitmapCacheOnDemand, resized.GetAddressOf() ); if ( SUCCEEDED(hr) ) { hr = _EnsureWicBitmapPixelFormat( pWIC, resized.Get(), filter, colorWithAlphaPixelFormat, resizedColorWithAlpha.GetAddressOf() ); } } } // Merge pixels (copying color channels from color only image to color+alpha image) if ( SUCCEEDED(hr) ) { ComPtr colorLock; ComPtr colorWithAlphaLock; hr = resizedColor->Lock( nullptr, WICBitmapLockRead, colorLock.GetAddressOf() ); if ( SUCCEEDED(hr) ) { hr = resizedColorWithAlpha->Lock( nullptr, WICBitmapLockWrite, colorWithAlphaLock.GetAddressOf() ); } if ( SUCCEEDED(hr) ) { WICInProcPointer colorWithAlphaData = nullptr; UINT colorWithAlphaSizeInBytes = 0; UINT colorWithAlphaStride = 0; hr = colorWithAlphaLock->GetDataPointer( &colorWithAlphaSizeInBytes, &colorWithAlphaData ); if ( SUCCEEDED(hr) ) { if ( !colorWithAlphaData ) { hr = E_POINTER; } else { hr = colorWithAlphaLock->GetStride( &colorWithAlphaStride ); } } WICInProcPointer colorData = nullptr; UINT colorSizeInBytes = 0; UINT colorStride = 0; if ( SUCCEEDED(hr) ) { hr = colorLock->GetDataPointer( &colorSizeInBytes, &colorData ); if ( SUCCEEDED(hr) ) { if ( !colorData ) { hr = E_POINTER; } else { hr = colorLock->GetStride( &colorStride ); } } } for ( size_t j = 0; SUCCEEDED(hr) && j < newHeight; j++ ) { for ( size_t i = 0; SUCCEEDED(hr) && i < newWidth; i++ ) { size_t colorWithAlphaIndex = (j * colorWithAlphaStride) + (i * colorWithAlphaBytesPerPixel); size_t colorIndex = (j * colorStride) + (i * colorBytesPerPixel); if ( ((colorWithAlphaIndex + colorBytesInPixel) > colorWithAlphaSizeInBytes) || ( (colorIndex + colorBytesPerPixel) > colorSizeInBytes) ) { hr = E_INVALIDARG; } else { #pragma warning( suppress : 26014 6386 ) // No overflow possible here memcpy_s( colorWithAlphaData + colorWithAlphaIndex, colorWithAlphaBytesPerPixel, colorData + colorIndex, colorBytesInPixel ); } } } } } if ( SUCCEEDED(hr) ) { ComPtr wicBitmap; hr = _EnsureWicBitmapPixelFormat( pWIC, resizedColorWithAlpha.Get(), filter, desiredPixelFormat, wicBitmap.GetAddressOf() ); if ( SUCCEEDED(hr) ) { hr = wicBitmap->CopyPixels( nullptr, static_cast(img->rowPitch), static_cast(img->slicePitch), img->pixels ); } } return hr; } //--- determine when to use WIC vs. non-WIC paths --- static bool _UseWICFiltering( _In_ DXGI_FORMAT format, _In_ DWORD filter ) { if ( filter & TEX_FILTER_FORCE_NON_WIC ) { // Explicit flag indicates use of non-WIC code paths return false; } if ( filter & TEX_FILTER_FORCE_WIC ) { // Explicit flag to use WIC code paths, skips all the case checks below return true; } if ( IsSRGB(format) || (filter & TEX_FILTER_SRGB) ) { // Use non-WIC code paths for sRGB correct filtering return false; } #if defined(_XBOX_ONE) && defined(_TITLE) if ( format == DXGI_FORMAT_R16G16B16A16_FLOAT || format == DXGI_FORMAT_R16_FLOAT ) { // Use non-WIC code paths as these conversions are not supported by Xbox One XDK return false; } #endif static_assert( TEX_FILTER_POINT == 0x100000, "TEX_FILTER_ flag values don't match TEX_FILTER_MASK" ); switch ( filter & TEX_FILTER_MASK ) { case TEX_FILTER_LINEAR: if ( filter & TEX_FILTER_WRAP ) { // WIC only supports 'clamp' semantics (MIRROR is equivalent to clamp for linear) return false; } if ( BitsPerColor(format) > 8 ) { // Avoid the WIC bitmap scaler when doing Linear filtering of XR/HDR formats return false; } break; case TEX_FILTER_CUBIC: if ( filter & ( TEX_FILTER_WRAP | TEX_FILTER_MIRROR ) ) { // WIC only supports 'clamp' semantics return false; } if ( BitsPerColor(format) > 8 ) { // Avoid the WIC bitmap scaler when doing Cubic filtering of XR/HDR formats return false; } break; case TEX_FILTER_TRIANGLE: // WIC does not implement this filter return false; } return true; } //--- mipmap (1D/2D) generation using WIC image scalar --- static HRESULT _GenerateMipMapsUsingWIC( _In_ const Image& baseImage, _In_ DWORD filter, _In_ size_t levels, _In_ const WICPixelFormatGUID& pfGUID, _In_ const ScratchImage& mipChain, _In_ size_t item ) { assert( levels > 1 ); if ( !baseImage.pixels || !mipChain.GetPixels() ) return E_POINTER; IWICImagingFactory* pWIC = _GetWIC(); if ( !pWIC ) return E_NOINTERFACE; size_t width = baseImage.width; size_t height = baseImage.height; ComPtr source; HRESULT hr = pWIC->CreateBitmapFromMemory( static_cast( width ), static_cast( height ), pfGUID, static_cast( baseImage.rowPitch ), static_cast( baseImage.slicePitch ), baseImage.pixels, source.GetAddressOf() ); if ( FAILED(hr) ) return hr; // Copy base image to top miplevel const Image *img0 = mipChain.GetImage( 0, item, 0 ); if ( !img0 ) return E_POINTER; uint8_t* pDest = img0->pixels; if ( !pDest ) return E_POINTER; const uint8_t *pSrc = baseImage.pixels; for( size_t h=0; h < height; ++h ) { size_t msize = std::min( img0->rowPitch, baseImage.rowPitch ); memcpy_s( pDest, img0->rowPitch, pSrc, msize ); pSrc += baseImage.rowPitch; pDest += img0->rowPitch; } ComPtr componentInfo; hr = pWIC->CreateComponentInfo( pfGUID, componentInfo.GetAddressOf() ); if ( FAILED(hr) ) return hr; ComPtr pixelFormatInfo; hr = componentInfo.As( &pixelFormatInfo ); if ( FAILED(hr) ) return hr; BOOL supportsTransparency = FALSE; hr = pixelFormatInfo->SupportsTransparency( &supportsTransparency ); if ( FAILED(hr) ) return hr; // Resize base image to each target mip level for( size_t level = 1; level < levels; ++level ) { const Image *img = mipChain.GetImage( level, item, 0 ); if ( !img ) return E_POINTER; if ( height > 1 ) height >>= 1; if ( width > 1 ) width >>= 1; assert( img->width == width && img->height == height && img->format == baseImage.format ); if ( (filter & TEX_FILTER_SEPARATE_ALPHA) && supportsTransparency ) { hr = _ResizeSeparateColorAndAlpha( pWIC, source.Get(), width, height, filter, img ); if ( FAILED(hr) ) return hr; } else { ComPtr scaler; hr = pWIC->CreateBitmapScaler( scaler.GetAddressOf() ); if ( FAILED(hr) ) return hr; hr = scaler->Initialize( source.Get(), static_cast( width ), static_cast( height ), _GetWICInterp( filter ) ); if ( FAILED(hr) ) return hr; WICPixelFormatGUID pfScaler; hr = scaler->GetPixelFormat( &pfScaler ); if ( FAILED(hr) ) return hr; if ( memcmp( &pfScaler, &pfGUID, sizeof(WICPixelFormatGUID) ) == 0 ) { hr = scaler->CopyPixels( 0, static_cast( img->rowPitch ), static_cast( img->slicePitch ), img->pixels ); if ( FAILED(hr) ) return hr; } else { // The WIC bitmap scaler is free to return a different pixel format than the source image, so here we // convert it back ComPtr FC; hr = pWIC->CreateFormatConverter( FC.GetAddressOf() ); if ( FAILED(hr) ) return hr; BOOL canConvert = FALSE; hr = FC->CanConvert( pfScaler, pfGUID, &canConvert ); if ( FAILED(hr) || !canConvert ) { return E_UNEXPECTED; } hr = FC->Initialize( scaler.Get(), pfGUID, _GetWICDither( filter ), 0, 0, WICBitmapPaletteTypeCustom ); if ( FAILED(hr) ) return hr; hr = FC->CopyPixels( 0, static_cast( img->rowPitch ), static_cast( img->slicePitch ), img->pixels ); if ( FAILED(hr) ) return hr; } } } return S_OK; } //------------------------------------------------------------------------------------- // Generate (1D/2D) mip-map helpers (custom filtering) //------------------------------------------------------------------------------------- static HRESULT _Setup2DMips( _In_reads_(nimages) const Image* baseImages, _In_ size_t nimages, _In_ const TexMetadata& mdata, _Out_ ScratchImage& mipChain ) { if ( !baseImages || !nimages ) return E_INVALIDARG; assert( mdata.mipLevels > 1 ); assert( mdata.arraySize == nimages ); assert( mdata.depth == 1 && mdata.dimension != TEX_DIMENSION_TEXTURE3D ); assert( mdata.width == baseImages[0].width ); assert( mdata.height == baseImages[0].height ); assert( mdata.format == baseImages[0].format ); HRESULT hr = mipChain.Initialize( mdata ); if ( FAILED(hr) ) return hr; // Copy base image(s) to top of mip chain for( size_t item=0; item < nimages; ++item ) { const Image& src = baseImages[item]; const Image *dest = mipChain.GetImage( 0, item, 0 ); if ( !dest ) { mipChain.Release(); return E_POINTER; } assert( src.format == dest->format ); uint8_t* pDest = dest->pixels; if ( !pDest ) { mipChain.Release(); return E_POINTER; } const uint8_t *pSrc = src.pixels; size_t rowPitch = src.rowPitch; for( size_t h=0; h < mdata.height; ++h ) { size_t msize = std::min( dest->rowPitch, rowPitch ); memcpy_s( pDest, dest->rowPitch, pSrc, msize ); pSrc += rowPitch; pDest += dest->rowPitch; } } return S_OK; } //--- 2D Point Filter --- static HRESULT _Generate2DMipsPointFilter( _In_ size_t levels, _In_ const ScratchImage& mipChain, _In_ size_t item ) { if ( !mipChain.GetImages() ) return E_INVALIDARG; // This assumes that the base image is already placed into the mipChain at the top level... (see _Setup2DMips) assert( levels > 1 ); size_t width = mipChain.GetMetadata().width; size_t height = mipChain.GetMetadata().height; // Allocate temporary space (2 scanlines) ScopedAlignedArrayXMVECTOR scanline( reinterpret_cast( _aligned_malloc( (sizeof(XMVECTOR)*width*2), 16 ) ) ); if ( !scanline ) return E_OUTOFMEMORY; XMVECTOR* target = scanline.get(); XMVECTOR* row = target + width; // Resize base image to each target mip level for( size_t level=1; level < levels; ++level ) { #ifdef _DEBUG memset( row, 0xCD, sizeof(XMVECTOR)*width ); #endif // 2D point filter const Image* src = mipChain.GetImage( level-1, item, 0 ); const Image* dest = mipChain.GetImage( level, item, 0 ); if ( !src || !dest ) return E_POINTER; const uint8_t* pSrc = src->pixels; uint8_t* pDest = dest->pixels; size_t rowPitch = src->rowPitch; size_t nwidth = (width > 1) ? (width >> 1) : 1; size_t nheight = (height > 1) ? (height >> 1) : 1; size_t xinc = ( width << 16 ) / nwidth; size_t yinc = ( height << 16 ) / nheight; size_t lasty = size_t(-1); size_t sy = 0; for( size_t y = 0; y < nheight; ++y ) { if ( (lasty ^ sy) >> 16 ) { if ( !_LoadScanline( row, width, pSrc + ( rowPitch * (sy >> 16) ), rowPitch, src->format ) ) return E_FAIL; lasty = sy; } size_t sx = 0; for( size_t x = 0; x < nwidth; ++x ) { target[ x ] = row[ sx >> 16 ]; sx += xinc; } if ( !_StoreScanline( pDest, dest->rowPitch, dest->format, target, nwidth ) ) return E_FAIL; pDest += dest->rowPitch; sy += yinc; } if ( height > 1 ) height >>= 1; if ( width > 1 ) width >>= 1; } return S_OK; } //--- 2D Box Filter --- static HRESULT _Generate2DMipsBoxFilter( _In_ size_t levels, _In_ DWORD filter, _In_ const ScratchImage& mipChain, _In_ size_t item ) { if ( !mipChain.GetImages() ) return E_INVALIDARG; // This assumes that the base image is already placed into the mipChain at the top level... (see _Setup2DMips) assert( levels > 1 ); size_t width = mipChain.GetMetadata().width; size_t height = mipChain.GetMetadata().height; if ( !ispow2(width) || !ispow2(height) ) return E_FAIL; // Allocate temporary space (3 scanlines) ScopedAlignedArrayXMVECTOR scanline( reinterpret_cast( _aligned_malloc( (sizeof(XMVECTOR)*width*3), 16 ) ) ); if ( !scanline ) return E_OUTOFMEMORY; XMVECTOR* target = scanline.get(); XMVECTOR* urow0 = target + width; XMVECTOR* urow1 = target + width*2; const XMVECTOR* urow2 = urow0 + 1; const XMVECTOR* urow3 = urow1 + 1; // Resize base image to each target mip level for( size_t level=1; level < levels; ++level ) { if ( height <= 1 ) { urow1 = urow0; } if ( width <= 1 ) { urow2 = urow0; urow3 = urow1; } // 2D box filter const Image* src = mipChain.GetImage( level-1, item, 0 ); const Image* dest = mipChain.GetImage( level, item, 0 ); if ( !src || !dest ) return E_POINTER; const uint8_t* pSrc = src->pixels; uint8_t* pDest = dest->pixels; size_t rowPitch = src->rowPitch; size_t nwidth = (width > 1) ? (width >> 1) : 1; size_t nheight = (height > 1) ? (height >> 1) : 1; for( size_t y = 0; y < nheight; ++y ) { if ( !_LoadScanlineLinear( urow0, width, pSrc, rowPitch, src->format, filter ) ) return E_FAIL; pSrc += rowPitch; if ( urow0 != urow1 ) { if ( !_LoadScanlineLinear( urow1, width, pSrc, rowPitch, src->format, filter ) ) return E_FAIL; pSrc += rowPitch; } for( size_t x = 0; x < nwidth; ++x ) { size_t x2 = x << 1; AVERAGE4( target[ x ], urow0[ x2 ], urow1[ x2 ], urow2[ x2 ], urow3[ x2 ] ); } if ( !_StoreScanlineLinear( pDest, dest->rowPitch, dest->format, target, nwidth, filter ) ) return E_FAIL; pDest += dest->rowPitch; } if ( height > 1 ) height >>= 1; if ( width > 1 ) width >>= 1; } return S_OK; } //--- 2D Linear Filter --- static HRESULT _Generate2DMipsLinearFilter( _In_ size_t levels, _In_ DWORD filter, _In_ const ScratchImage& mipChain, _In_ size_t item ) { if ( !mipChain.GetImages() ) return E_INVALIDARG; // This assumes that the base image is already placed into the mipChain at the top level... (see _Setup2DMips) assert( levels > 1 ); size_t width = mipChain.GetMetadata().width; size_t height = mipChain.GetMetadata().height; // Allocate temporary space (3 scanlines, plus X and Y filters) ScopedAlignedArrayXMVECTOR scanline( reinterpret_cast( _aligned_malloc( (sizeof(XMVECTOR)*width*3), 16 ) ) ); if ( !scanline ) return E_OUTOFMEMORY; std::unique_ptr lf( new (std::nothrow) LinearFilter[ width+height ] ); if ( !lf ) return E_OUTOFMEMORY; LinearFilter* lfX = lf.get(); LinearFilter* lfY = lf.get() + width; XMVECTOR* target = scanline.get(); XMVECTOR* row0 = target + width; XMVECTOR* row1 = target + width*2; // Resize base image to each target mip level for( size_t level=1; level < levels; ++level ) { // 2D linear filter const Image* src = mipChain.GetImage( level-1, item, 0 ); const Image* dest = mipChain.GetImage( level, item, 0 ); if ( !src || !dest ) return E_POINTER; const uint8_t* pSrc = src->pixels; uint8_t* pDest = dest->pixels; size_t rowPitch = src->rowPitch; size_t nwidth = (width > 1) ? (width >> 1) : 1; _CreateLinearFilter( width, nwidth, (filter & TEX_FILTER_WRAP_U) != 0, lfX ); size_t nheight = (height > 1) ? (height >> 1) : 1; _CreateLinearFilter( height, nheight, (filter & TEX_FILTER_WRAP_V) != 0, lfY ); #ifdef _DEBUG memset( row0, 0xCD, sizeof(XMVECTOR)*width ); memset( row1, 0xDD, sizeof(XMVECTOR)*width ); #endif size_t u0 = size_t(-1); size_t u1 = size_t(-1); for( size_t y = 0; y < nheight; ++y ) { auto& toY = lfY[ y ]; if ( toY.u0 != u0 ) { if ( toY.u0 != u1 ) { u0 = toY.u0; if ( !_LoadScanlineLinear( row0, width, pSrc + (rowPitch * u0), rowPitch, src->format, filter ) ) return E_FAIL; } else { u0 = u1; u1 = size_t(-1); std::swap( row0, row1 ); } } if ( toY.u1 != u1 ) { u1 = toY.u1; if ( !_LoadScanlineLinear( row1, width, pSrc + (rowPitch * u1), rowPitch, src->format, filter ) ) return E_FAIL; } for( size_t x = 0; x < nwidth; ++x ) { auto& toX = lfX[ x ]; BILINEAR_INTERPOLATE( target[x], toX, toY, row0, row1 ); } if ( !_StoreScanlineLinear( pDest, dest->rowPitch, dest->format, target, nwidth, filter ) ) return E_FAIL; pDest += dest->rowPitch; } if ( height > 1 ) height >>= 1; if ( width > 1 ) width >>= 1; } return S_OK; } //--- 2D Cubic Filter --- static HRESULT _Generate2DMipsCubicFilter( _In_ size_t levels, _In_ DWORD filter, _In_ const ScratchImage& mipChain, _In_ size_t item ) { if ( !mipChain.GetImages() ) return E_INVALIDARG; // This assumes that the base image is already placed into the mipChain at the top level... (see _Setup2DMips) assert( levels > 1 ); size_t width = mipChain.GetMetadata().width; size_t height = mipChain.GetMetadata().height; // Allocate temporary space (5 scanlines, plus X and Y filters) ScopedAlignedArrayXMVECTOR scanline( reinterpret_cast( _aligned_malloc( (sizeof(XMVECTOR)*width*5), 16 ) ) ); if ( !scanline ) return E_OUTOFMEMORY; std::unique_ptr cf( new (std::nothrow) CubicFilter[ width+height ] ); if ( !cf ) return E_OUTOFMEMORY; CubicFilter* cfX = cf.get(); CubicFilter* cfY = cf.get() + width; XMVECTOR* target = scanline.get(); XMVECTOR* row0 = target + width; XMVECTOR* row1 = target + width*2; XMVECTOR* row2 = target + width*3; XMVECTOR* row3 = target + width*4; // Resize base image to each target mip level for( size_t level=1; level < levels; ++level ) { // 2D cubic filter const Image* src = mipChain.GetImage( level-1, item, 0 ); const Image* dest = mipChain.GetImage( level, item, 0 ); if ( !src || !dest ) return E_POINTER; const uint8_t* pSrc = src->pixels; uint8_t* pDest = dest->pixels; size_t rowPitch = src->rowPitch; size_t nwidth = (width > 1) ? (width >> 1) : 1; _CreateCubicFilter( width, nwidth, (filter & TEX_FILTER_WRAP_U) != 0, (filter & TEX_FILTER_MIRROR_U) != 0, cfX ); size_t nheight = (height > 1) ? (height >> 1) : 1; _CreateCubicFilter( height, nheight, (filter & TEX_FILTER_WRAP_V) != 0, (filter & TEX_FILTER_MIRROR_V) != 0, cfY ); #ifdef _DEBUG memset( row0, 0xCD, sizeof(XMVECTOR)*width ); memset( row1, 0xDD, sizeof(XMVECTOR)*width ); memset( row2, 0xED, sizeof(XMVECTOR)*width ); memset( row3, 0xFD, sizeof(XMVECTOR)*width ); #endif size_t u0 = size_t(-1); size_t u1 = size_t(-1); size_t u2 = size_t(-1); size_t u3 = size_t(-1); for( size_t y = 0; y < nheight; ++y ) { auto& toY = cfY[ y ]; // Scanline 1 if ( toY.u0 != u0 ) { if ( toY.u0 != u1 && toY.u0 != u2 && toY.u0 != u3 ) { u0 = toY.u0; if ( !_LoadScanlineLinear( row0, width, pSrc + (rowPitch * u0), rowPitch, src->format, filter ) ) return E_FAIL; } else if ( toY.u0 == u1 ) { u0 = u1; u1 = size_t(-1); std::swap( row0, row1 ); } else if ( toY.u0 == u2 ) { u0 = u2; u2 = size_t(-1); std::swap( row0, row2 ); } else if ( toY.u0 == u3 ) { u0 = u3; u3 = size_t(-1); std::swap( row0, row3 ); } } // Scanline 2 if ( toY.u1 != u1 ) { if ( toY.u1 != u2 && toY.u1 != u3 ) { u1 = toY.u1; if ( !_LoadScanlineLinear( row1, width, pSrc + (rowPitch * u1), rowPitch, src->format, filter ) ) return E_FAIL; } else if ( toY.u1 == u2 ) { u1 = u2; u2 = size_t(-1); std::swap( row1, row2 ); } else if ( toY.u1 == u3 ) { u1 = u3; u3 = size_t(-1); std::swap( row1, row3 ); } } // Scanline 3 if ( toY.u2 != u2 ) { if ( toY.u2 != u3 ) { u2 = toY.u2; if ( !_LoadScanlineLinear( row2, width, pSrc + (rowPitch * u2), rowPitch, src->format, filter ) ) return E_FAIL; } else { u2 = u3; u3 = size_t(-1); std::swap( row2, row3 ); } } // Scanline 4 if ( toY.u3 != u3 ) { u3 = toY.u3; if ( !_LoadScanlineLinear( row3, width, pSrc + (rowPitch * u3), rowPitch, src->format, filter ) ) return E_FAIL; } for( size_t x = 0; x < nwidth; ++x ) { auto& toX = cfX[ x ]; XMVECTOR C0, C1, C2, C3; CUBIC_INTERPOLATE( C0, toX.x, row0[ toX.u0 ], row0[ toX.u1 ], row0[ toX.u2 ], row0[ toX.u3 ] ); CUBIC_INTERPOLATE( C1, toX.x, row1[ toX.u0 ], row1[ toX.u1 ], row1[ toX.u2 ], row1[ toX.u3 ] ); CUBIC_INTERPOLATE( C2, toX.x, row2[ toX.u0 ], row2[ toX.u1 ], row2[ toX.u2 ], row2[ toX.u3 ] ); CUBIC_INTERPOLATE( C3, toX.x, row3[ toX.u0 ], row3[ toX.u1 ], row3[ toX.u2 ], row3[ toX.u3 ] ); CUBIC_INTERPOLATE( target[x], toY.x, C0, C1, C2, C3 ); } if ( !_StoreScanlineLinear( pDest, dest->rowPitch, dest->format, target, nwidth, filter ) ) return E_FAIL; pDest += dest->rowPitch; } if ( height > 1 ) height >>= 1; if ( width > 1 ) width >>= 1; } return S_OK; } //--- 2D Triangle Filter --- static HRESULT _Generate2DMipsTriangleFilter( _In_ size_t levels, _In_ DWORD filter, _In_ const ScratchImage& mipChain, _In_ size_t item ) { if ( !mipChain.GetImages() ) return E_INVALIDARG; using namespace TriangleFilter; // This assumes that the base image is already placed into the mipChain at the top level... (see _Setup2DMips) assert( levels > 1 ); size_t width = mipChain.GetMetadata().width; size_t height = mipChain.GetMetadata().height; // Allocate initial temporary space (1 scanline, accumulation rows, plus X and Y filters) ScopedAlignedArrayXMVECTOR scanline( reinterpret_cast( _aligned_malloc( sizeof(XMVECTOR) * width, 16 ) ) ); if ( !scanline ) return E_OUTOFMEMORY; std::unique_ptr rowActive( new (std::nothrow) TriangleRow[ height ] ); if ( !rowActive ) return E_OUTOFMEMORY; TriangleRow * rowFree = nullptr; std::unique_ptr tfX, tfY; XMVECTOR* row = scanline.get(); // Resize base image to each target mip level for( size_t level=1; level < levels; ++level ) { // 2D triangle filter const Image* src = mipChain.GetImage( level-1, item, 0 ); const Image* dest = mipChain.GetImage( level, item, 0 ); if ( !src || !dest ) return E_POINTER; const uint8_t* pSrc = src->pixels; size_t rowPitch = src->rowPitch; const uint8_t* pEndSrc = pSrc + rowPitch * height; uint8_t* pDest = dest->pixels; size_t nwidth = (width > 1) ? (width >> 1) : 1; HRESULT hr = _Create( width, nwidth, (filter & TEX_FILTER_WRAP_U) != 0, tfX ); if ( FAILED(hr) ) return hr; size_t nheight = (height > 1) ? (height >> 1) : 1; hr = _Create( height, nheight, (filter & TEX_FILTER_WRAP_V) != 0, tfY ); if ( FAILED(hr) ) return hr; #ifdef _DEBUG memset( row, 0xCD, sizeof(XMVECTOR)*width ); #endif auto xFromEnd = reinterpret_cast( reinterpret_cast( tfX.get() ) + tfX->sizeInBytes ); auto yFromEnd = reinterpret_cast( reinterpret_cast( tfY.get() ) + tfY->sizeInBytes ); // Count times rows get written (and clear out any leftover accumulation rows from last miplevel) for( FilterFrom* yFrom = tfY->from; yFrom < yFromEnd; ) { for ( size_t j = 0; j < yFrom->count; ++j ) { size_t v = yFrom->to[ j ].u; assert( v < nheight ); TriangleRow* rowAcc = &rowActive[ v ]; ++rowAcc->remaining; if ( rowAcc->scanline ) { memset( rowAcc->scanline.get(), 0, sizeof(XMVECTOR) * nwidth ); } } yFrom = reinterpret_cast( reinterpret_cast( yFrom ) + yFrom->sizeInBytes ); } // Filter image for( FilterFrom* yFrom = tfY->from; yFrom < yFromEnd; ) { // Create accumulation rows as needed for ( size_t j = 0; j < yFrom->count; ++j ) { size_t v = yFrom->to[ j ].u; assert( v < nheight ); TriangleRow* rowAcc = &rowActive[ v ]; if ( !rowAcc->scanline ) { if ( rowFree ) { // Steal and reuse scanline from 'free row' list // (it will always be at least as wide as nwidth due to loop decending order) assert( rowFree->scanline != 0 ); rowAcc->scanline.reset( rowFree->scanline.release() ); rowFree = rowFree->next; } else { rowAcc->scanline.reset( reinterpret_cast( _aligned_malloc( sizeof(XMVECTOR) * nwidth, 16 ) ) ); if ( !rowAcc->scanline ) return E_OUTOFMEMORY; } memset( rowAcc->scanline.get(), 0, sizeof(XMVECTOR) * nwidth ); } } // Load source scanline if ( (pSrc + rowPitch) > pEndSrc ) return E_FAIL; if ( !_LoadScanlineLinear( row, width, pSrc, rowPitch, src->format, filter ) ) return E_FAIL; pSrc += rowPitch; // Process row size_t x = 0; for( FilterFrom* xFrom = tfX->from; xFrom < xFromEnd; ++x ) { for ( size_t j = 0; j < yFrom->count; ++j ) { size_t v = yFrom->to[ j ].u; assert( v < nheight ); float yweight = yFrom->to[ j ].weight; XMVECTOR* accPtr = rowActive[ v ].scanline.get(); if ( !accPtr ) return E_POINTER; for ( size_t k = 0; k < xFrom->count; ++k ) { size_t u = xFrom->to[ k ].u; assert( u < nwidth ); XMVECTOR weight = XMVectorReplicate( yweight * xFrom->to[ k ].weight ); assert( x < width ); accPtr[ u ] = XMVectorMultiplyAdd( row[ x ], weight, accPtr[ u ] ); } } xFrom = reinterpret_cast( reinterpret_cast( xFrom ) + xFrom->sizeInBytes ); } // Write completed accumulation rows for ( size_t j = 0; j < yFrom->count; ++j ) { size_t v = yFrom->to[ j ].u; assert( v < nheight ); TriangleRow* rowAcc = &rowActive[ v ]; assert( rowAcc->remaining > 0 ); --rowAcc->remaining; if ( !rowAcc->remaining ) { XMVECTOR* pAccSrc = rowAcc->scanline.get(); if ( !pAccSrc ) return E_POINTER; switch( dest->format ) { case DXGI_FORMAT_R10G10B10A2_UNORM: case DXGI_FORMAT_R10G10B10A2_UINT: { // Need to slightly bias results for floating-point error accumulation which can // be visible with harshly quantized values static const XMVECTORF32 Bias = { 0.f, 0.f, 0.f, 0.1f }; XMVECTOR* ptr = pAccSrc; for( size_t i=0; i < dest->width; ++i, ++ptr ) { *ptr = XMVectorAdd( *ptr, Bias ); } } break; } // This performs any required clamping if ( !_StoreScanlineLinear( pDest + (dest->rowPitch * v), dest->rowPitch, dest->format, pAccSrc, dest->width, filter ) ) return E_FAIL; // Put row on freelist to reuse it's allocated scanline rowAcc->next = rowFree; rowFree = rowAcc; } } yFrom = reinterpret_cast( reinterpret_cast( yFrom ) + yFrom->sizeInBytes ); } if ( height > 1 ) height >>= 1; if ( width > 1 ) width >>= 1; } return S_OK; } //------------------------------------------------------------------------------------- // Generate volume mip-map helpers //------------------------------------------------------------------------------------- static HRESULT _Setup3DMips( _In_reads_(depth) const Image* baseImages, _In_ size_t depth, size_t levels, _Out_ ScratchImage& mipChain ) { if ( !baseImages || !depth ) return E_INVALIDARG; assert( levels > 1 ); size_t width = baseImages[0].width; size_t height = baseImages[0].height; HRESULT hr = mipChain.Initialize3D( baseImages[0].format, width, height, depth, levels ); if ( FAILED(hr) ) return hr; // Copy base images to top slice for( size_t slice=0; slice < depth; ++slice ) { const Image& src = baseImages[slice]; const Image *dest = mipChain.GetImage( 0, 0, slice ); if ( !dest ) { mipChain.Release(); return E_POINTER; } assert( src.format == dest->format ); uint8_t* pDest = dest->pixels; if ( !pDest ) { mipChain.Release(); return E_POINTER; } const uint8_t *pSrc = src.pixels; size_t rowPitch = src.rowPitch; for( size_t h=0; h < height; ++h ) { size_t msize = std::min( dest->rowPitch, rowPitch ); memcpy_s( pDest, dest->rowPitch, pSrc, msize ); pSrc += rowPitch; pDest += dest->rowPitch; } } return S_OK; } //--- 3D Point Filter --- static HRESULT _Generate3DMipsPointFilter( _In_ size_t depth, _In_ size_t levels, _In_ const ScratchImage& mipChain ) { if ( !depth || !mipChain.GetImages() ) return E_INVALIDARG; // This assumes that the base images are already placed into the mipChain at the top level... (see _Setup3DMips) assert( levels > 1 ); size_t width = mipChain.GetMetadata().width; size_t height = mipChain.GetMetadata().height; // Allocate temporary space (2 scanlines) ScopedAlignedArrayXMVECTOR scanline( reinterpret_cast( _aligned_malloc( (sizeof(XMVECTOR)*width*2), 16 ) ) ); if ( !scanline ) return E_OUTOFMEMORY; XMVECTOR* target = scanline.get(); XMVECTOR* row = target + width; // Resize base image to each target mip level for( size_t level=1; level < levels; ++level ) { #ifdef _DEBUG memset( row, 0xCD, sizeof(XMVECTOR)*width ); #endif if ( depth > 1 ) { // 3D point filter size_t ndepth = depth >> 1; size_t zinc = ( depth << 16 ) / ndepth; size_t sz = 0; for( size_t slice=0; slice < ndepth; ++slice ) { const Image* src = mipChain.GetImage( level-1, 0, (sz >> 16) ); const Image* dest = mipChain.GetImage( level, 0, slice ); if ( !src || !dest ) return E_POINTER; const uint8_t* pSrc = src->pixels; uint8_t* pDest = dest->pixels; size_t rowPitch = src->rowPitch; size_t nwidth = (width > 1) ? (width >> 1) : 1; size_t nheight = (height > 1) ? (height >> 1) : 1; size_t xinc = ( width << 16 ) / nwidth; size_t yinc = ( height << 16 ) / nheight; size_t lasty = size_t(-1); size_t sy = 0; for( size_t y = 0; y < nheight; ++y ) { if ( (lasty ^ sy) >> 16 ) { if ( !_LoadScanline( row, width, pSrc + ( rowPitch * (sy >> 16) ), rowPitch, src->format ) ) return E_FAIL; lasty = sy; } size_t sx = 0; for( size_t x = 0; x < nwidth; ++x ) { target[ x ] = row[ sx >> 16 ]; sx += xinc; } if ( !_StoreScanline( pDest, dest->rowPitch, dest->format, target, nwidth ) ) return E_FAIL; pDest += dest->rowPitch; sy += yinc; } sz += zinc; } } else { // 2D point filter const Image* src = mipChain.GetImage( level-1, 0, 0 ); const Image* dest = mipChain.GetImage( level, 0, 0 ); if ( !src || !dest ) return E_POINTER; const uint8_t* pSrc = src->pixels; uint8_t* pDest = dest->pixels; size_t rowPitch = src->rowPitch; size_t nwidth = (width > 1) ? (width >> 1) : 1; size_t nheight = (height > 1) ? (height >> 1) : 1; size_t xinc = ( width << 16 ) / nwidth; size_t yinc = ( height << 16 ) / nheight; size_t lasty = size_t(-1); size_t sy = 0; for( size_t y = 0; y < nheight; ++y ) { if ( (lasty ^ sy) >> 16 ) { if ( !_LoadScanline( row, width, pSrc + ( rowPitch * (sy >> 16) ), rowPitch, src->format ) ) return E_FAIL; lasty = sy; } size_t sx = 0; for( size_t x = 0; x < nwidth; ++x ) { target[ x ] = row[ sx >> 16 ]; sx += xinc; } if ( !_StoreScanline( pDest, dest->rowPitch, dest->format, target, nwidth ) ) return E_FAIL; pDest += dest->rowPitch; sy += yinc; } } if ( height > 1 ) height >>= 1; if ( width > 1 ) width >>= 1; if ( depth > 1 ) depth >>= 1; } return S_OK; } //--- 3D Box Filter --- static HRESULT _Generate3DMipsBoxFilter( _In_ size_t depth, _In_ size_t levels, _In_ DWORD filter, _In_ const ScratchImage& mipChain ) { if ( !depth || !mipChain.GetImages() ) return E_INVALIDARG; // This assumes that the base images are already placed into the mipChain at the top level... (see _Setup3DMips) assert( levels > 1 ); size_t width = mipChain.GetMetadata().width; size_t height = mipChain.GetMetadata().height; if ( !ispow2(width) || !ispow2(height) || !ispow2(depth) ) return E_FAIL; // Allocate temporary space (5 scanlines) ScopedAlignedArrayXMVECTOR scanline( reinterpret_cast( _aligned_malloc( (sizeof(XMVECTOR)*width*5), 16 ) ) ); if ( !scanline ) return E_OUTOFMEMORY; XMVECTOR* target = scanline.get(); XMVECTOR* urow0 = target + width; XMVECTOR* urow1 = target + width*2; XMVECTOR* vrow0 = target + width*3; XMVECTOR* vrow1 = target + width*4; const XMVECTOR* urow2 = urow0 + 1; const XMVECTOR* urow3 = urow1 + 1; const XMVECTOR* vrow2 = vrow0 + 1; const XMVECTOR* vrow3 = vrow1 + 1; // Resize base image to each target mip level for( size_t level=1; level < levels; ++level ) { if ( height <= 1 ) { urow1 = urow0; vrow1 = vrow0; } if ( width <= 1 ) { urow2 = urow0; urow3 = urow1; vrow2 = vrow0; vrow3 = vrow1; } if ( depth > 1 ) { // 3D box filter size_t ndepth = depth >> 1; for( size_t slice=0; slice < ndepth; ++slice ) { size_t slicea = std::min( slice * 2, depth-1 ); size_t sliceb = std::min( slicea + 1, depth-1 ); const Image* srca = mipChain.GetImage( level-1, 0, slicea ); const Image* srcb = mipChain.GetImage( level-1, 0, sliceb ); const Image* dest = mipChain.GetImage( level, 0, slice ); if ( !srca || !srcb || !dest ) return E_POINTER; const uint8_t* pSrc1 = srca->pixels; const uint8_t* pSrc2 = srcb->pixels; uint8_t* pDest = dest->pixels; size_t aRowPitch = srca->rowPitch; size_t bRowPitch = srcb->rowPitch; size_t nwidth = (width > 1) ? (width >> 1) : 1; size_t nheight = (height > 1) ? (height >> 1) : 1; for( size_t y = 0; y < nheight; ++y ) { if ( !_LoadScanlineLinear( urow0, width, pSrc1, aRowPitch, srca->format, filter ) ) return E_FAIL; pSrc1 += aRowPitch; if ( urow0 != urow1 ) { if ( !_LoadScanlineLinear( urow1, width, pSrc1, aRowPitch, srca->format, filter ) ) return E_FAIL; pSrc1 += aRowPitch; } if ( !_LoadScanlineLinear( vrow0, width, pSrc2, bRowPitch, srcb->format, filter ) ) return E_FAIL; pSrc2 += bRowPitch; if ( vrow0 != vrow1 ) { if ( !_LoadScanlineLinear( vrow1, width, pSrc2, bRowPitch, srcb->format, filter ) ) return E_FAIL; pSrc2 += bRowPitch; } for( size_t x = 0; x < nwidth; ++x ) { size_t x2 = x << 1; AVERAGE8( target[x], urow0[ x2 ], urow1[ x2 ], urow2[ x2 ], urow3[ x2 ], vrow0[ x2 ], vrow1[ x2 ], vrow2[ x2 ], vrow3[ x2 ] ); } if ( !_StoreScanlineLinear( pDest, dest->rowPitch, dest->format, target, nwidth, filter ) ) return E_FAIL; pDest += dest->rowPitch; } } } else { // 2D box filter const Image* src = mipChain.GetImage( level-1, 0, 0 ); const Image* dest = mipChain.GetImage( level, 0, 0 ); if ( !src || !dest ) return E_POINTER; const uint8_t* pSrc = src->pixels; uint8_t* pDest = dest->pixels; size_t rowPitch = src->rowPitch; size_t nwidth = (width > 1) ? (width >> 1) : 1; size_t nheight = (height > 1) ? (height >> 1) : 1; for( size_t y = 0; y < nheight; ++y ) { if ( !_LoadScanlineLinear( urow0, width, pSrc, rowPitch, src->format, filter ) ) return E_FAIL; pSrc += rowPitch; if ( urow0 != urow1 ) { if ( !_LoadScanlineLinear( urow1, width, pSrc, rowPitch, src->format, filter ) ) return E_FAIL; pSrc += rowPitch; } for( size_t x = 0; x < nwidth; ++x ) { size_t x2 = x << 1; AVERAGE4( target[ x ], urow0[ x2 ], urow1[ x2 ], urow2[ x2 ], urow3[ x2 ] ); } if ( !_StoreScanlineLinear( pDest, dest->rowPitch, dest->format, target, nwidth, filter ) ) return E_FAIL; pDest += dest->rowPitch; } } if ( height > 1 ) height >>= 1; if ( width > 1 ) width >>= 1; if ( depth > 1 ) depth >>= 1; } return S_OK; } //--- 3D Linear Filter --- static HRESULT _Generate3DMipsLinearFilter( _In_ size_t depth, _In_ size_t levels, _In_ DWORD filter, _In_ const ScratchImage& mipChain ) { if ( !depth || !mipChain.GetImages() ) return E_INVALIDARG; // This assumes that the base images are already placed into the mipChain at the top level... (see _Setup3DMips) assert( levels > 1 ); size_t width = mipChain.GetMetadata().width; size_t height = mipChain.GetMetadata().height; // Allocate temporary space (5 scanlines, plus X/Y/Z filters) ScopedAlignedArrayXMVECTOR scanline( reinterpret_cast( _aligned_malloc( (sizeof(XMVECTOR)*width*5), 16 ) ) ); if ( !scanline ) return E_OUTOFMEMORY; std::unique_ptr lf( new (std::nothrow) LinearFilter[ width+height+depth ] ); if ( !lf ) return E_OUTOFMEMORY; LinearFilter* lfX = lf.get(); LinearFilter* lfY = lf.get() + width; LinearFilter* lfZ = lf.get() + width + height; XMVECTOR* target = scanline.get(); XMVECTOR* urow0 = target + width; XMVECTOR* urow1 = target + width*2; XMVECTOR* vrow0 = target + width*3; XMVECTOR* vrow1 = target + width*4; // Resize base image to each target mip level for( size_t level=1; level < levels; ++level ) { size_t nwidth = (width > 1) ? (width >> 1) : 1; _CreateLinearFilter( width, nwidth, (filter & TEX_FILTER_WRAP_U) != 0, lfX ); size_t nheight = (height > 1) ? (height >> 1) : 1; _CreateLinearFilter( height, nheight, (filter & TEX_FILTER_WRAP_V) != 0, lfY ); #ifdef _DEBUG memset( urow0, 0xCD, sizeof(XMVECTOR)*width ); memset( urow1, 0xDD, sizeof(XMVECTOR)*width ); memset( vrow0, 0xED, sizeof(XMVECTOR)*width ); memset( vrow1, 0xFD, sizeof(XMVECTOR)*width ); #endif if ( depth > 1 ) { // 3D linear filter size_t ndepth = depth >> 1; _CreateLinearFilter( depth, ndepth, (filter & TEX_FILTER_WRAP_W) != 0, lfZ ); for( size_t slice=0; slice < ndepth; ++slice ) { auto& toZ = lfZ[ slice ]; const Image* srca = mipChain.GetImage( level-1, 0, toZ.u0 ); const Image* srcb = mipChain.GetImage( level-1, 0, toZ.u1 ); if ( !srca || !srcb ) return E_POINTER; size_t u0 = size_t(-1); size_t u1 = size_t(-1); const Image* dest = mipChain.GetImage( level, 0, slice ); if ( !dest ) return E_POINTER; uint8_t* pDest = dest->pixels; for( size_t y = 0; y < nheight; ++y ) { auto& toY = lfY[ y ]; if ( toY.u0 != u0 ) { if ( toY.u0 != u1 ) { u0 = toY.u0; if ( !_LoadScanlineLinear( urow0, width, srca->pixels + (srca->rowPitch * u0), srca->rowPitch, srca->format, filter ) || !_LoadScanlineLinear( vrow0, width, srcb->pixels + (srcb->rowPitch * u0), srcb->rowPitch, srcb->format, filter ) ) return E_FAIL; } else { u0 = u1; u1 = size_t(-1); std::swap( urow0, urow1 ); std::swap( vrow0, vrow1 ); } } if ( toY.u1 != u1 ) { u1 = toY.u1; if ( !_LoadScanlineLinear( urow1, width, srca->pixels + (srca->rowPitch * u1), srca->rowPitch, srca->format, filter ) || !_LoadScanlineLinear( vrow1, width, srcb->pixels + (srcb->rowPitch * u1), srcb->rowPitch, srcb->format, filter ) ) return E_FAIL; } for( size_t x = 0; x < nwidth; ++x ) { auto& toX = lfX[ x ]; TRILINEAR_INTERPOLATE( target[x], toX, toY, toZ, urow0, urow1, vrow0, vrow1 ); } if ( !_StoreScanlineLinear( pDest, dest->rowPitch, dest->format, target, nwidth, filter ) ) return E_FAIL; pDest += dest->rowPitch; } } } else { // 2D linear filter const Image* src = mipChain.GetImage( level-1, 0, 0 ); const Image* dest = mipChain.GetImage( level, 0, 0 ); if ( !src || !dest ) return E_POINTER; const uint8_t* pSrc = src->pixels; uint8_t* pDest = dest->pixels; size_t rowPitch = src->rowPitch; size_t u0 = size_t(-1); size_t u1 = size_t(-1); for( size_t y = 0; y < nheight; ++y ) { auto& toY = lfY[ y ]; if ( toY.u0 != u0 ) { if ( toY.u0 != u1 ) { u0 = toY.u0; if ( !_LoadScanlineLinear( urow0, width, pSrc + (rowPitch * u0), rowPitch, src->format, filter ) ) return E_FAIL; } else { u0 = u1; u1 = size_t(-1); std::swap( urow0, urow1 ); } } if ( toY.u1 != u1 ) { u1 = toY.u1; if ( !_LoadScanlineLinear( urow1, width, pSrc + (rowPitch * u1), rowPitch, src->format, filter ) ) return E_FAIL; } for( size_t x = 0; x < nwidth; ++x ) { auto& toX = lfX[ x ]; BILINEAR_INTERPOLATE( target[x], toX, toY, urow0, urow1 ); } if ( !_StoreScanlineLinear( pDest, dest->rowPitch, dest->format, target, nwidth, filter ) ) return E_FAIL; pDest += dest->rowPitch; } } if ( height > 1 ) height >>= 1; if ( width > 1 ) width >>= 1; if ( depth > 1 ) depth >>= 1; } return S_OK; } //--- 3D Cubic Filter --- static HRESULT _Generate3DMipsCubicFilter( _In_ size_t depth, _In_ size_t levels, _In_ DWORD filter, _In_ const ScratchImage& mipChain ) { if ( !depth || !mipChain.GetImages() ) return E_INVALIDARG; // This assumes that the base images are already placed into the mipChain at the top level... (see _Setup3DMips) assert( levels > 1 ); size_t width = mipChain.GetMetadata().width; size_t height = mipChain.GetMetadata().height; // Allocate temporary space (17 scanlines, plus X/Y/Z filters) ScopedAlignedArrayXMVECTOR scanline( reinterpret_cast( _aligned_malloc( (sizeof(XMVECTOR)*width*17), 16 ) ) ); if ( !scanline ) return E_OUTOFMEMORY; std::unique_ptr cf( new (std::nothrow) CubicFilter[ width+height+depth ] ); if ( !cf ) return E_OUTOFMEMORY; CubicFilter* cfX = cf.get(); CubicFilter* cfY = cf.get() + width; CubicFilter* cfZ = cf.get() + width + height; XMVECTOR* target = scanline.get(); XMVECTOR* urow[4]; XMVECTOR* vrow[4]; XMVECTOR* srow[4]; XMVECTOR* trow[4]; XMVECTOR *ptr = scanline.get() + width; for( size_t j = 0; j < 4; ++j ) { urow[j] = ptr; ptr += width; vrow[j] = ptr; ptr += width; srow[j] = ptr; ptr += width; trow[j] = ptr; ptr += width; } // Resize base image to each target mip level for( size_t level=1; level < levels; ++level ) { size_t nwidth = (width > 1) ? (width >> 1) : 1; _CreateCubicFilter( width, nwidth, (filter & TEX_FILTER_WRAP_U) != 0, (filter & TEX_FILTER_MIRROR_U) != 0, cfX ); size_t nheight = (height > 1) ? (height >> 1) : 1; _CreateCubicFilter( height, nheight, (filter & TEX_FILTER_WRAP_V) != 0, (filter & TEX_FILTER_MIRROR_V) != 0, cfY ); #ifdef _DEBUG for( size_t j = 0; j < 4; ++j ) { memset( urow[j], 0xCD, sizeof(XMVECTOR)*width ); memset( vrow[j], 0xDD, sizeof(XMVECTOR)*width ); memset( srow[j], 0xED, sizeof(XMVECTOR)*width ); memset( trow[j], 0xFD, sizeof(XMVECTOR)*width ); } #endif if ( depth > 1 ) { // 3D cubic filter size_t ndepth = depth >> 1; _CreateCubicFilter( depth, ndepth, (filter & TEX_FILTER_WRAP_W) != 0, (filter & TEX_FILTER_MIRROR_W) != 0, cfZ ); for( size_t slice=0; slice < ndepth; ++slice ) { auto& toZ = cfZ[ slice ]; const Image* srca = mipChain.GetImage( level-1, 0, toZ.u0 ); const Image* srcb = mipChain.GetImage( level-1, 0, toZ.u1 ); const Image* srcc = mipChain.GetImage( level-1, 0, toZ.u2 ); const Image* srcd = mipChain.GetImage( level-1, 0, toZ.u3 ); if ( !srca || !srcb || !srcc || !srcd ) return E_POINTER; size_t u0 = size_t(-1); size_t u1 = size_t(-1); size_t u2 = size_t(-1); size_t u3 = size_t(-1); const Image* dest = mipChain.GetImage( level, 0, slice ); if ( !dest ) return E_POINTER; uint8_t* pDest = dest->pixels; for( size_t y = 0; y < nheight; ++y ) { auto& toY = cfY[ y ]; // Scanline 1 if ( toY.u0 != u0 ) { if ( toY.u0 != u1 && toY.u0 != u2 && toY.u0 != u3 ) { u0 = toY.u0; if ( !_LoadScanlineLinear( urow[0], width, srca->pixels + (srca->rowPitch * u0), srca->rowPitch, srca->format, filter ) || !_LoadScanlineLinear( urow[1], width, srcb->pixels + (srcb->rowPitch * u0), srcb->rowPitch, srcb->format, filter ) || !_LoadScanlineLinear( urow[2], width, srcc->pixels + (srcc->rowPitch * u0), srcc->rowPitch, srcc->format, filter ) || !_LoadScanlineLinear( urow[3], width, srcd->pixels + (srcd->rowPitch * u0), srcd->rowPitch, srcd->format, filter ) ) return E_FAIL; } else if ( toY.u0 == u1 ) { u0 = u1; u1 = size_t(-1); std::swap( urow[0], vrow[0] ); std::swap( urow[1], vrow[1] ); std::swap( urow[2], vrow[2] ); std::swap( urow[3], vrow[3] ); } else if ( toY.u0 == u2 ) { u0 = u2; u2 = size_t(-1); std::swap( urow[0], srow[0] ); std::swap( urow[1], srow[1] ); std::swap( urow[2], srow[2] ); std::swap( urow[3], srow[3] ); } else if ( toY.u0 == u3 ) { u0 = u3; u3 = size_t(-1); std::swap( urow[0], trow[0] ); std::swap( urow[1], trow[1] ); std::swap( urow[2], trow[2] ); std::swap( urow[3], trow[3] ); } } // Scanline 2 if ( toY.u1 != u1 ) { if ( toY.u1 != u2 && toY.u1 != u3 ) { u1 = toY.u1; if ( !_LoadScanlineLinear( vrow[0], width, srca->pixels + (srca->rowPitch * u1), srca->rowPitch, srca->format, filter ) || !_LoadScanlineLinear( vrow[1], width, srcb->pixels + (srcb->rowPitch * u1), srcb->rowPitch, srcb->format, filter ) || !_LoadScanlineLinear( vrow[2], width, srcc->pixels + (srcc->rowPitch * u1), srcc->rowPitch, srcc->format, filter ) || !_LoadScanlineLinear( vrow[3], width, srcd->pixels + (srcd->rowPitch * u1), srcd->rowPitch, srcd->format, filter ) ) return E_FAIL; } else if ( toY.u1 == u2 ) { u1 = u2; u2 = size_t(-1); std::swap( vrow[0], srow[0] ); std::swap( vrow[1], srow[1] ); std::swap( vrow[2], srow[2] ); std::swap( vrow[3], srow[3] ); } else if ( toY.u1 == u3 ) { u1 = u3; u3 = size_t(-1); std::swap( vrow[0], trow[0] ); std::swap( vrow[1], trow[1] ); std::swap( vrow[2], trow[2] ); std::swap( vrow[3], trow[3] ); } } // Scanline 3 if ( toY.u2 != u2 ) { if ( toY.u2 != u3 ) { u2 = toY.u2; if ( !_LoadScanlineLinear( srow[0], width, srca->pixels + (srca->rowPitch * u2), srca->rowPitch, srca->format, filter ) || !_LoadScanlineLinear( srow[1], width, srcb->pixels + (srcb->rowPitch * u2), srcb->rowPitch, srcb->format, filter ) || !_LoadScanlineLinear( srow[2], width, srcc->pixels + (srcc->rowPitch * u2), srcc->rowPitch, srcc->format, filter ) || !_LoadScanlineLinear( srow[3], width, srcd->pixels + (srcd->rowPitch * u2), srcd->rowPitch, srcd->format, filter ) ) return E_FAIL; } else { u2 = u3; u3 = size_t(-1); std::swap( srow[0], trow[0] ); std::swap( srow[1], trow[1] ); std::swap( srow[2], trow[2] ); std::swap( srow[3], trow[3] ); } } // Scanline 4 if ( toY.u3 != u3 ) { u3 = toY.u3; if ( !_LoadScanlineLinear( trow[0], width, srca->pixels + (srca->rowPitch * u3), srca->rowPitch, srca->format, filter ) || !_LoadScanlineLinear( trow[1], width, srcb->pixels + (srcb->rowPitch * u3), srcb->rowPitch, srcb->format, filter ) || !_LoadScanlineLinear( trow[2], width, srcc->pixels + (srcc->rowPitch * u3), srcc->rowPitch, srcc->format, filter ) || !_LoadScanlineLinear( trow[3], width, srcd->pixels + (srcd->rowPitch * u3), srcd->rowPitch, srcd->format, filter ) ) return E_FAIL; } for( size_t x = 0; x < nwidth; ++x ) { auto& toX = cfX[ x ]; XMVECTOR D[4]; for( size_t j=0; j < 4; ++j ) { XMVECTOR C0, C1, C2, C3; CUBIC_INTERPOLATE( C0, toX.x, urow[j][ toX.u0 ], urow[j][ toX.u1 ], urow[j][ toX.u2 ], urow[j][ toX.u3 ] ); CUBIC_INTERPOLATE( C1, toX.x, vrow[j][ toX.u0 ], vrow[j][ toX.u1 ], vrow[j][ toX.u2 ], vrow[j][ toX.u3 ] ); CUBIC_INTERPOLATE( C2, toX.x, srow[j][ toX.u0 ], srow[j][ toX.u1 ], srow[j][ toX.u2 ], srow[j][ toX.u3 ] ); CUBIC_INTERPOLATE( C3, toX.x, trow[j][ toX.u0 ], trow[j][ toX.u1 ], trow[j][ toX.u2 ], trow[j][ toX.u3 ] ); CUBIC_INTERPOLATE( D[j], toY.x, C0, C1, C2, C3 ); } CUBIC_INTERPOLATE( target[x], toZ.x, D[0], D[1], D[2], D[3] ); } if ( !_StoreScanlineLinear( pDest, dest->rowPitch, dest->format, target, nwidth, filter ) ) return E_FAIL; pDest += dest->rowPitch; } } } else { // 2D cubic filter const Image* src = mipChain.GetImage( level-1, 0, 0 ); const Image* dest = mipChain.GetImage( level, 0, 0 ); if ( !src || !dest ) return E_POINTER; const uint8_t* pSrc = src->pixels; uint8_t* pDest = dest->pixels; size_t rowPitch = src->rowPitch; size_t u0 = size_t(-1); size_t u1 = size_t(-1); size_t u2 = size_t(-1); size_t u3 = size_t(-1); for( size_t y = 0; y < nheight; ++y ) { auto& toY = cfY[ y ]; // Scanline 1 if ( toY.u0 != u0 ) { if ( toY.u0 != u1 && toY.u0 != u2 && toY.u0 != u3 ) { u0 = toY.u0; if ( !_LoadScanlineLinear( urow[0], width, pSrc + (rowPitch * u0), rowPitch, src->format, filter ) ) return E_FAIL; } else if ( toY.u0 == u1 ) { u0 = u1; u1 = size_t(-1); std::swap( urow[0], vrow[0] ); } else if ( toY.u0 == u2 ) { u0 = u2; u2 = size_t(-1); std::swap( urow[0], srow[0] ); } else if ( toY.u0 == u3 ) { u0 = u3; u3 = size_t(-1); std::swap( urow[0], trow[0] ); } } // Scanline 2 if ( toY.u1 != u1 ) { if ( toY.u1 != u2 && toY.u1 != u3 ) { u1 = toY.u1; if ( !_LoadScanlineLinear( vrow[0], width, pSrc + (rowPitch * u1), rowPitch, src->format, filter ) ) return E_FAIL; } else if ( toY.u1 == u2 ) { u1 = u2; u2 = size_t(-1); std::swap( vrow[0], srow[0] ); } else if ( toY.u1 == u3 ) { u1 = u3; u3 = size_t(-1); std::swap( vrow[0], trow[0] ); } } // Scanline 3 if ( toY.u2 != u2 ) { if ( toY.u2 != u3 ) { u2 = toY.u2; if ( !_LoadScanlineLinear( srow[0], width, pSrc + (rowPitch * u2), rowPitch, src->format, filter ) ) return E_FAIL; } else { u2 = u3; u3 = size_t(-1); std::swap( srow[0], trow[0] ); } } // Scanline 4 if ( toY.u3 != u3 ) { u3 = toY.u3; if ( !_LoadScanlineLinear( trow[0], width, pSrc + (rowPitch * u3), rowPitch, src->format, filter ) ) return E_FAIL; } for( size_t x = 0; x < nwidth; ++x ) { auto& toX = cfX[ x ]; XMVECTOR C0, C1, C2, C3; CUBIC_INTERPOLATE( C0, toX.x, urow[0][ toX.u0 ], urow[0][ toX.u1 ], urow[0][ toX.u2 ], urow[0][ toX.u3 ] ); CUBIC_INTERPOLATE( C1, toX.x, vrow[0][ toX.u0 ], vrow[0][ toX.u1 ], vrow[0][ toX.u2 ], vrow[0][ toX.u3 ] ); CUBIC_INTERPOLATE( C2, toX.x, srow[0][ toX.u0 ], srow[0][ toX.u1 ], srow[0][ toX.u2 ], srow[0][ toX.u3 ] ); CUBIC_INTERPOLATE( C3, toX.x, trow[0][ toX.u0 ], trow[0][ toX.u1 ], trow[0][ toX.u2 ], trow[0][ toX.u3 ] ); CUBIC_INTERPOLATE( target[x], toY.x, C0, C1, C2, C3 ); } if ( !_StoreScanlineLinear( pDest, dest->rowPitch, dest->format, target, nwidth, filter ) ) return E_FAIL; pDest += dest->rowPitch; } } if ( height > 1 ) height >>= 1; if ( width > 1 ) width >>= 1; if ( depth > 1 ) depth >>= 1; } return S_OK; } //--- 3D Triangle Filter --- static HRESULT _Generate3DMipsTriangleFilter( _In_ size_t depth, _In_ size_t levels, _In_ DWORD filter, _In_ const ScratchImage& mipChain ) { if ( !depth || !mipChain.GetImages() ) return E_INVALIDARG; using namespace TriangleFilter; // This assumes that the base images are already placed into the mipChain at the top level... (see _Setup3DMips) assert( levels > 1 ); size_t width = mipChain.GetMetadata().width; size_t height = mipChain.GetMetadata().height; // Allocate initial temporary space (1 scanline, accumulation rows, plus X/Y/Z filters) ScopedAlignedArrayXMVECTOR scanline( reinterpret_cast( _aligned_malloc( sizeof(XMVECTOR) * width, 16 ) ) ); if ( !scanline ) return E_OUTOFMEMORY; std::unique_ptr sliceActive( new (std::nothrow) TriangleRow[ depth ] ); if ( !sliceActive ) return E_OUTOFMEMORY; TriangleRow * sliceFree = nullptr; std::unique_ptr tfX, tfY, tfZ; XMVECTOR* row = scanline.get(); // Resize base image to each target mip level for( size_t level=1; level < levels; ++level ) { size_t nwidth = (width > 1) ? (width >> 1) : 1; HRESULT hr = _Create( width, nwidth, (filter & TEX_FILTER_WRAP_U) != 0, tfX ); if ( FAILED(hr) ) return hr; size_t nheight = (height > 1) ? (height >> 1) : 1; hr = _Create( height, nheight, (filter & TEX_FILTER_WRAP_V) != 0, tfY ); if ( FAILED(hr) ) return hr; size_t ndepth = (depth > 1 ) ? (depth >> 1) : 1; hr = _Create( depth, ndepth, (filter & TEX_FILTER_WRAP_W) != 0, tfZ ); if ( FAILED(hr) ) return hr; #ifdef _DEBUG memset( row, 0xCD, sizeof(XMVECTOR)*width ); #endif auto xFromEnd = reinterpret_cast( reinterpret_cast( tfX.get() ) + tfX->sizeInBytes ); auto yFromEnd = reinterpret_cast( reinterpret_cast( tfY.get() ) + tfY->sizeInBytes ); auto zFromEnd = reinterpret_cast( reinterpret_cast( tfZ.get() ) + tfZ->sizeInBytes ); // Count times slices get written (and clear out any leftover accumulation slices from last miplevel) for( FilterFrom* zFrom = tfZ->from; zFrom < zFromEnd; ) { for ( size_t j = 0; j < zFrom->count; ++j ) { size_t w = zFrom->to[ j ].u; assert( w < ndepth ); TriangleRow* sliceAcc = &sliceActive[ w ]; ++sliceAcc->remaining; if ( sliceAcc->scanline ) { memset( sliceAcc->scanline.get(), 0, sizeof(XMVECTOR) * nwidth * nheight ); } } zFrom = reinterpret_cast( reinterpret_cast( zFrom ) + zFrom->sizeInBytes ); } // Filter image size_t z = 0; for( FilterFrom* zFrom = tfZ->from; zFrom < zFromEnd; ++z ) { // Create accumulation slices as needed for ( size_t j = 0; j < zFrom->count; ++j ) { size_t w = zFrom->to[ j ].u; assert( w < ndepth ); TriangleRow* sliceAcc = &sliceActive[ w ]; if ( !sliceAcc->scanline ) { if ( sliceFree ) { // Steal and reuse scanline from 'free slice' list // (it will always be at least as large as nwidth*nheight due to loop decending order) assert( sliceFree->scanline != 0 ); sliceAcc->scanline.reset( sliceFree->scanline.release() ); sliceFree = sliceFree->next; } else { size_t bytes = sizeof(XMVECTOR) * nwidth * nheight; sliceAcc->scanline.reset( reinterpret_cast( _aligned_malloc( bytes, 16 ) ) ); if ( !sliceAcc->scanline ) return E_OUTOFMEMORY; } memset( sliceAcc->scanline.get(), 0, sizeof(XMVECTOR) * nwidth * nheight ); } } assert( z < depth ); const Image* src = mipChain.GetImage( level-1, 0, z ); if ( !src ) return E_POINTER; const uint8_t* pSrc = src->pixels; size_t rowPitch = src->rowPitch; const uint8_t* pEndSrc = pSrc + rowPitch * height; for( FilterFrom* yFrom = tfY->from; yFrom < yFromEnd; ) { // Load source scanline if ( (pSrc + rowPitch) > pEndSrc ) return E_FAIL; if ( !_LoadScanlineLinear( row, width, pSrc, rowPitch, src->format, filter ) ) return E_FAIL; pSrc += rowPitch; // Process row size_t x = 0; for( FilterFrom* xFrom = tfX->from; xFrom < xFromEnd; ++x ) { for ( size_t j = 0; j < zFrom->count; ++j ) { size_t w = zFrom->to[ j ].u; assert( w < ndepth ); float zweight = zFrom->to[ j ].weight; XMVECTOR* accSlice = sliceActive[ w ].scanline.get(); if ( !accSlice ) return E_POINTER; for ( size_t k = 0; k < yFrom->count; ++k ) { size_t v = yFrom->to[ k ].u; assert( v < nheight ); float yweight = yFrom->to[ k ].weight; XMVECTOR * accPtr = accSlice + v * nwidth; for ( size_t l = 0; l < xFrom->count; ++l ) { size_t u = xFrom->to[ l ].u; assert( u < nwidth ); XMVECTOR weight = XMVectorReplicate( zweight * yweight * xFrom->to[ l ].weight ); assert( x < width ); accPtr[ u ] = XMVectorMultiplyAdd( row[ x ], weight, accPtr[ u ] ); } } } xFrom = reinterpret_cast( reinterpret_cast( xFrom ) + xFrom->sizeInBytes ); } yFrom = reinterpret_cast( reinterpret_cast( yFrom ) + yFrom->sizeInBytes ); } // Write completed accumulation slices for ( size_t j = 0; j < zFrom->count; ++j ) { size_t w = zFrom->to[ j ].u; assert( w < ndepth ); TriangleRow* sliceAcc = &sliceActive[ w ]; assert( sliceAcc->remaining > 0 ); --sliceAcc->remaining; if ( !sliceAcc->remaining ) { const Image* dest = mipChain.GetImage( level, 0, w ); XMVECTOR* pAccSrc = sliceAcc->scanline.get(); if ( !dest || !pAccSrc ) return E_POINTER; uint8_t* pDest = dest->pixels; for( size_t h = 0; h < nheight; ++h ) { switch( dest->format ) { case DXGI_FORMAT_R10G10B10A2_UNORM: case DXGI_FORMAT_R10G10B10A2_UINT: { // Need to slightly bias results for floating-point error accumulation which can // be visible with harshly quantized values static const XMVECTORF32 Bias = { 0.f, 0.f, 0.f, 0.1f }; XMVECTOR* ptr = pAccSrc; for( size_t i=0; i < dest->width; ++i, ++ptr ) { *ptr = XMVectorAdd( *ptr, Bias ); } } break; } // This performs any required clamping if ( !_StoreScanlineLinear( pDest, dest->rowPitch, dest->format, pAccSrc, dest->width, filter ) ) return E_FAIL; pDest += dest->rowPitch; pAccSrc += nwidth; } // Put slice on freelist to reuse it's allocated scanline sliceAcc->next = sliceFree; sliceFree = sliceAcc; } } zFrom = reinterpret_cast( reinterpret_cast( zFrom ) + zFrom->sizeInBytes ); } if ( height > 1 ) height >>= 1; if ( width > 1 ) width >>= 1; if ( depth > 1 ) depth >>= 1; } return S_OK; } //===================================================================================== // Entry-points //===================================================================================== //------------------------------------------------------------------------------------- // Generate mipmap chain //------------------------------------------------------------------------------------- _Use_decl_annotations_ HRESULT GenerateMipMaps( const Image& baseImage, DWORD filter, size_t levels, ScratchImage& mipChain, bool allow1D ) { if ( !IsValid( baseImage.format ) ) return E_INVALIDARG; if ( !baseImage.pixels ) return E_POINTER; if ( !_CalculateMipLevels(baseImage.width, baseImage.height, levels) ) return E_INVALIDARG; if ( levels <= 1 ) return E_INVALIDARG; if ( IsCompressed(baseImage.format) || IsTypeless(baseImage.format) || IsPlanar(baseImage.format) || IsPalettized(baseImage.format) ) { return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); } HRESULT hr; static_assert( TEX_FILTER_POINT == 0x100000, "TEX_FILTER_ flag values don't match TEX_FILTER_MASK" ); if ( _UseWICFiltering( baseImage.format, filter ) ) { //--- Use WIC filtering to generate mipmaps ----------------------------------- switch(filter & TEX_FILTER_MASK) { case 0: case TEX_FILTER_POINT: case TEX_FILTER_FANT: // Equivalent to Box filter case TEX_FILTER_LINEAR: case TEX_FILTER_CUBIC: { static_assert( TEX_FILTER_FANT == TEX_FILTER_BOX, "TEX_FILTER_ flag alias mismatch" ); WICPixelFormatGUID pfGUID; if ( _DXGIToWIC( baseImage.format, pfGUID, true ) ) { // Case 1: Base image format is supported by Windows Imaging Component hr = (baseImage.height > 1 || !allow1D) ? mipChain.Initialize2D( baseImage.format, baseImage.width, baseImage.height, 1, levels ) : mipChain.Initialize1D( baseImage.format, baseImage.width, 1, levels ); if ( FAILED(hr) ) return hr; return _GenerateMipMapsUsingWIC( baseImage, filter, levels, pfGUID, mipChain, 0 ); } else { // Case 2: Base image format is not supported by WIC, so we have to convert, generate, and convert back assert( baseImage.format != DXGI_FORMAT_R32G32B32A32_FLOAT ); ScratchImage temp; hr = _ConvertToR32G32B32A32( baseImage, temp ); if ( FAILED(hr) ) return hr; const Image *timg = temp.GetImage( 0, 0, 0 ); if ( !timg ) return E_POINTER; ScratchImage tMipChain; hr = (baseImage.height > 1 || !allow1D) ? tMipChain.Initialize2D( DXGI_FORMAT_R32G32B32A32_FLOAT, baseImage.width, baseImage.height, 1, levels ) : tMipChain.Initialize1D( DXGI_FORMAT_R32G32B32A32_FLOAT, baseImage.width, 1, levels ); if ( FAILED(hr) ) return hr; hr = _GenerateMipMapsUsingWIC( *timg, filter, levels, GUID_WICPixelFormat128bppRGBAFloat, tMipChain, 0 ); if ( FAILED(hr) ) return hr; temp.Release(); return _ConvertFromR32G32B32A32( tMipChain.GetImages(), tMipChain.GetImageCount(), tMipChain.GetMetadata(), baseImage.format, mipChain ); } } break; default: return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); } } else { //--- Use custom filters to generate mipmaps ---------------------------------- TexMetadata mdata; memset( &mdata, 0, sizeof(mdata) ); mdata.width = baseImage.width; if ( baseImage.height > 1 || !allow1D ) { mdata.height = baseImage.height; mdata.dimension = TEX_DIMENSION_TEXTURE2D; } else { mdata.height = 1; mdata.dimension= TEX_DIMENSION_TEXTURE1D; } mdata.depth = mdata.arraySize = 1; mdata.mipLevels = levels; mdata.format = baseImage.format; DWORD filter_select = ( filter & TEX_FILTER_MASK ); if ( !filter_select ) { // Default filter choice filter_select = ( ispow2(baseImage.width) && ispow2(baseImage.height) ) ? TEX_FILTER_BOX : TEX_FILTER_LINEAR; } switch( filter_select ) { case TEX_FILTER_BOX: hr = _Setup2DMips( &baseImage, 1, mdata, mipChain ); if ( FAILED(hr) ) return hr; hr = _Generate2DMipsBoxFilter( levels, filter, mipChain, 0 ); if ( FAILED(hr) ) mipChain.Release(); return hr; case TEX_FILTER_POINT: hr = _Setup2DMips( &baseImage, 1, mdata, mipChain ); if ( FAILED(hr) ) return hr; hr = _Generate2DMipsPointFilter( levels, mipChain, 0 ); if ( FAILED(hr) ) mipChain.Release(); return hr; case TEX_FILTER_LINEAR: hr = _Setup2DMips( &baseImage, 1, mdata, mipChain ); if ( FAILED(hr) ) return hr; hr = _Generate2DMipsLinearFilter( levels, filter, mipChain, 0 ); if ( FAILED(hr) ) mipChain.Release(); return hr; case TEX_FILTER_CUBIC: hr = _Setup2DMips( &baseImage, 1, mdata, mipChain ); if ( FAILED(hr) ) return hr; hr = _Generate2DMipsCubicFilter( levels, filter, mipChain, 0 ); if ( FAILED(hr) ) mipChain.Release(); return hr; case TEX_FILTER_TRIANGLE: hr = _Setup2DMips( &baseImage, 1, mdata, mipChain ); if ( FAILED(hr) ) return hr; hr = _Generate2DMipsTriangleFilter( levels, filter, mipChain, 0 ); if ( FAILED(hr) ) mipChain.Release(); return hr; default: return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); } } } _Use_decl_annotations_ HRESULT GenerateMipMaps( const Image* srcImages, size_t nimages, const TexMetadata& metadata, DWORD filter, size_t levels, ScratchImage& mipChain ) { if ( !srcImages || !nimages || !IsValid(metadata.format) ) return E_INVALIDARG; if ( metadata.IsVolumemap() || IsCompressed(metadata.format) || IsTypeless(metadata.format) || IsPlanar(metadata.format) || IsPalettized(metadata.format) ) return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); if ( !_CalculateMipLevels(metadata.width, metadata.height, levels) ) return E_INVALIDARG; if ( levels <= 1 ) return E_INVALIDARG; std::vector baseImages; baseImages.reserve( metadata.arraySize ); for( size_t item=0; item < metadata.arraySize; ++item ) { size_t index = metadata.ComputeIndex( 0, item, 0); if ( index >= nimages ) return E_FAIL; const Image& src = srcImages[ index ]; if ( !src.pixels ) return E_POINTER; if ( src.format != metadata.format || src.width != metadata.width || src.height != metadata.height ) { // All base images must be the same format, width, and height return E_FAIL; } baseImages.push_back( src ); } assert( baseImages.size() == metadata.arraySize ); HRESULT hr; static_assert( TEX_FILTER_POINT == 0x100000, "TEX_FILTER_ flag values don't match TEX_FILTER_MASK" ); if ( _UseWICFiltering( metadata.format, filter ) ) { //--- Use WIC filtering to generate mipmaps ----------------------------------- switch(filter & TEX_FILTER_MASK) { case 0: case TEX_FILTER_POINT: case TEX_FILTER_FANT: // Equivalent to Box filter case TEX_FILTER_LINEAR: case TEX_FILTER_CUBIC: { static_assert( TEX_FILTER_FANT == TEX_FILTER_BOX, "TEX_FILTER_ flag alias mismatch" ); WICPixelFormatGUID pfGUID; if ( _DXGIToWIC( metadata.format, pfGUID, true ) ) { // Case 1: Base image format is supported by Windows Imaging Component TexMetadata mdata2 = metadata; mdata2.mipLevels = levels; hr = mipChain.Initialize( mdata2 ); if ( FAILED(hr) ) return hr; for( size_t item = 0; item < metadata.arraySize; ++item ) { hr = _GenerateMipMapsUsingWIC( baseImages[item], filter, levels, pfGUID, mipChain, item ); if ( FAILED(hr) ) { mipChain.Release(); return hr; } } return S_OK; } else { // Case 2: Base image format is not supported by WIC, so we have to convert, generate, and convert back assert( metadata.format != DXGI_FORMAT_R32G32B32A32_FLOAT ); TexMetadata mdata2 = metadata; mdata2.mipLevels = levels; mdata2.format = DXGI_FORMAT_R32G32B32A32_FLOAT; ScratchImage tMipChain; hr = tMipChain.Initialize( mdata2 ); if ( FAILED(hr) ) return hr; for( size_t item = 0; item < metadata.arraySize; ++item ) { ScratchImage temp; hr = _ConvertToR32G32B32A32( baseImages[item], temp ); if ( FAILED(hr) ) return hr; const Image *timg = temp.GetImage( 0, 0, 0 ); if ( !timg ) return E_POINTER; hr = _GenerateMipMapsUsingWIC( *timg, filter, levels, GUID_WICPixelFormat128bppRGBAFloat, tMipChain, item ); if ( FAILED(hr) ) return hr; } return _ConvertFromR32G32B32A32( tMipChain.GetImages(), tMipChain.GetImageCount(), tMipChain.GetMetadata(), metadata.format, mipChain ); } } break; default: return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); } } else { //--- Use custom filters to generate mipmaps ---------------------------------- TexMetadata mdata2 = metadata; mdata2.mipLevels = levels; DWORD filter_select = ( filter & TEX_FILTER_MASK ); if ( !filter_select ) { // Default filter choice filter_select = ( ispow2(metadata.width) && ispow2(metadata.height) ) ? TEX_FILTER_BOX : TEX_FILTER_LINEAR; } switch( filter_select ) { case TEX_FILTER_BOX: hr = _Setup2DMips( &baseImages[0], metadata.arraySize, mdata2, mipChain ); if ( FAILED(hr) ) return hr; for( size_t item = 0; item < metadata.arraySize; ++item ) { hr = _Generate2DMipsBoxFilter( levels, filter, mipChain, item ); if ( FAILED(hr) ) mipChain.Release(); } return hr; case TEX_FILTER_POINT: hr = _Setup2DMips( &baseImages[0], metadata.arraySize, mdata2, mipChain ); if ( FAILED(hr) ) return hr; for( size_t item = 0; item < metadata.arraySize; ++item ) { hr = _Generate2DMipsPointFilter( levels, mipChain, item ); if ( FAILED(hr) ) mipChain.Release(); } return hr; case TEX_FILTER_LINEAR: hr = _Setup2DMips( &baseImages[0], metadata.arraySize, mdata2, mipChain ); if ( FAILED(hr) ) return hr; for( size_t item = 0; item < metadata.arraySize; ++item ) { hr = _Generate2DMipsLinearFilter( levels, filter, mipChain, item ); if ( FAILED(hr) ) mipChain.Release(); } return hr; case TEX_FILTER_CUBIC: hr = _Setup2DMips( &baseImages[0], metadata.arraySize, mdata2, mipChain ); if ( FAILED(hr) ) return hr; for( size_t item = 0; item < metadata.arraySize; ++item ) { hr = _Generate2DMipsCubicFilter( levels, filter, mipChain, item ); if ( FAILED(hr) ) mipChain.Release(); } return hr; case TEX_FILTER_TRIANGLE: hr = _Setup2DMips( &baseImages[0], metadata.arraySize, mdata2, mipChain ); if ( FAILED(hr) ) return hr; for( size_t item = 0; item < metadata.arraySize; ++item ) { hr = _Generate2DMipsTriangleFilter( levels, filter, mipChain, item ); if ( FAILED(hr) ) mipChain.Release(); } return hr; default: return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); } } } //------------------------------------------------------------------------------------- // Generate mipmap chain for volume texture //------------------------------------------------------------------------------------- _Use_decl_annotations_ HRESULT GenerateMipMaps3D( const Image* baseImages, size_t depth, DWORD filter, size_t levels, ScratchImage& mipChain ) { if ( !baseImages || !depth ) return E_INVALIDARG; if ( filter & TEX_FILTER_FORCE_WIC ) return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); DXGI_FORMAT format = baseImages[0].format; size_t width = baseImages[0].width; size_t height = baseImages[0].height; if ( !_CalculateMipLevels3D(width, height, depth, levels) ) return E_INVALIDARG; if ( levels <= 1 ) return E_INVALIDARG; for( size_t slice=0; slice < depth; ++slice ) { if ( !baseImages[slice].pixels ) return E_POINTER; if ( baseImages[slice].format != format || baseImages[slice].width != width || baseImages[slice].height != height ) { // All base images must be the same format, width, and height return E_FAIL; } } if ( IsCompressed(format) || IsTypeless(format) || IsPlanar(format) || IsPalettized(format) ) return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); static_assert( TEX_FILTER_POINT == 0x100000, "TEX_FILTER_ flag values don't match TEX_FILTER_MASK" ); HRESULT hr; DWORD filter_select = ( filter & TEX_FILTER_MASK ); if ( !filter_select ) { // Default filter choice filter_select = ( ispow2(width) && ispow2(height) && ispow2(depth) ) ? TEX_FILTER_BOX : TEX_FILTER_TRIANGLE; } switch( filter_select ) { case TEX_FILTER_BOX: hr = _Setup3DMips( baseImages, depth, levels, mipChain ); if ( FAILED(hr) ) return hr; hr = _Generate3DMipsBoxFilter( depth, levels, filter, mipChain ); if ( FAILED(hr) ) mipChain.Release(); return hr; case TEX_FILTER_POINT: hr = _Setup3DMips( baseImages, depth, levels, mipChain ); if ( FAILED(hr) ) return hr; hr = _Generate3DMipsPointFilter( depth, levels, mipChain ); if ( FAILED(hr) ) mipChain.Release(); return hr; case TEX_FILTER_LINEAR: hr = _Setup3DMips( baseImages, depth, levels, mipChain ); if ( FAILED(hr) ) return hr; hr = _Generate3DMipsLinearFilter( depth, levels, filter, mipChain ); if ( FAILED(hr) ) mipChain.Release(); return hr; case TEX_FILTER_CUBIC: hr = _Setup3DMips( baseImages, depth, levels, mipChain ); if ( FAILED(hr) ) return hr; hr = _Generate3DMipsCubicFilter( depth, levels, filter, mipChain ); if ( FAILED(hr) ) mipChain.Release(); return hr; case TEX_FILTER_TRIANGLE: hr = _Setup3DMips( baseImages, depth, levels, mipChain ); if ( FAILED(hr) ) return hr; hr = _Generate3DMipsTriangleFilter( depth, levels, filter, mipChain ); if ( FAILED(hr) ) mipChain.Release(); return hr; default: return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); } } _Use_decl_annotations_ HRESULT GenerateMipMaps3D( const Image* srcImages, size_t nimages, const TexMetadata& metadata, DWORD filter, size_t levels, ScratchImage& mipChain ) { if ( !srcImages || !nimages || !IsValid(metadata.format) ) return E_INVALIDARG; if ( filter & TEX_FILTER_FORCE_WIC ) return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); if ( !metadata.IsVolumemap() || IsCompressed(metadata.format) || IsTypeless(metadata.format) || IsPlanar(metadata.format) || IsPalettized(metadata.format) ) return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); if ( !_CalculateMipLevels3D(metadata.width, metadata.height, metadata.depth, levels) ) return E_INVALIDARG; if ( levels <= 1 ) return E_INVALIDARG; std::vector baseImages; baseImages.reserve( metadata.depth ); for( size_t slice=0; slice < metadata.depth; ++slice ) { size_t index = metadata.ComputeIndex( 0, 0, slice ); if ( index >= nimages ) return E_FAIL; const Image& src = srcImages[ index ]; if ( !src.pixels ) return E_POINTER; if ( src.format != metadata.format || src.width != metadata.width || src.height != metadata.height ) { // All base images must be the same format, width, and height return E_FAIL; } baseImages.push_back( src ); } assert( baseImages.size() == metadata.depth ); HRESULT hr; static_assert( TEX_FILTER_POINT == 0x100000, "TEX_FILTER_ flag values don't match TEX_FILTER_MASK" ); DWORD filter_select = ( filter & TEX_FILTER_MASK ); if ( !filter_select ) { // Default filter choice filter_select = ( ispow2(metadata.width) && ispow2(metadata.height) && ispow2(metadata.depth) ) ? TEX_FILTER_BOX : TEX_FILTER_TRIANGLE; } switch( filter_select ) { case TEX_FILTER_BOX: hr = _Setup3DMips( &baseImages[0], metadata.depth, levels, mipChain ); if ( FAILED(hr) ) return hr; hr = _Generate3DMipsBoxFilter( metadata.depth, levels, filter, mipChain ); if ( FAILED(hr) ) mipChain.Release(); return hr; case TEX_FILTER_POINT: hr = _Setup3DMips( &baseImages[0], metadata.depth, levels, mipChain ); if ( FAILED(hr) ) return hr; hr = _Generate3DMipsPointFilter( metadata.depth, levels, mipChain ); if ( FAILED(hr) ) mipChain.Release(); return hr; case TEX_FILTER_LINEAR: hr = _Setup3DMips( &baseImages[0], metadata.depth, levels, mipChain ); if ( FAILED(hr) ) return hr; hr = _Generate3DMipsLinearFilter( metadata.depth, levels, filter, mipChain ); if ( FAILED(hr) ) mipChain.Release(); return hr; case TEX_FILTER_CUBIC: hr = _Setup3DMips( &baseImages[0], metadata.depth, levels, mipChain ); if ( FAILED(hr) ) return hr; hr = _Generate3DMipsCubicFilter( metadata.depth, levels, filter, mipChain ); if ( FAILED(hr) ) mipChain.Release(); return hr; case TEX_FILTER_TRIANGLE: hr = _Setup3DMips( &baseImages[0], metadata.depth, levels, mipChain ); if ( FAILED(hr) ) return hr; hr = _Generate3DMipsTriangleFilter( metadata.depth, levels, filter, mipChain ); if ( FAILED(hr) ) mipChain.Release(); return hr; default: return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); } } }; // namespace ================================================ FILE: 3rdParty/DirectXTex/DirectXTex/DirectXTexMisc.cpp ================================================ //------------------------------------------------------------------------------------- // DirectXTexMisc.cpp // // DirectX Texture Library - Misc image operations // // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A // PARTICULAR PURPOSE. // // Copyright (c) Microsoft Corporation. All rights reserved. // // http://go.microsoft.com/fwlink/?LinkId=248926 //------------------------------------------------------------------------------------- #include "directxtexp.h" namespace DirectX { static const XMVECTORF32 g_Gamma22 = { 2.2f, 2.2f, 2.2f, 1.f }; //------------------------------------------------------------------------------------- static HRESULT _ComputeMSE( _In_ const Image& image1, _In_ const Image& image2, _Out_ float& mse, _Out_writes_opt_(4) float* mseV, _In_ DWORD flags ) { if ( !image1.pixels || !image2.pixels ) return E_POINTER; assert( image1.width == image2.width && image1.height == image2.height ); assert( !IsCompressed( image1.format ) && !IsCompressed( image2.format ) ); const size_t width = image1.width; ScopedAlignedArrayXMVECTOR scanline( reinterpret_cast( _aligned_malloc( (sizeof(XMVECTOR)*width)*2, 16 ) ) ); if ( !scanline ) return E_OUTOFMEMORY; // Flags implied from image formats switch( image1.format ) { case DXGI_FORMAT_B8G8R8X8_UNORM: flags |= CMSE_IGNORE_ALPHA; break; case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: flags |= CMSE_IMAGE1_SRGB | CMSE_IGNORE_ALPHA; break; case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: case DXGI_FORMAT_BC1_UNORM_SRGB: case DXGI_FORMAT_BC2_UNORM_SRGB: case DXGI_FORMAT_BC3_UNORM_SRGB: case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: case DXGI_FORMAT_BC7_UNORM_SRGB: flags |= CMSE_IMAGE1_SRGB; break; } switch( image2.format ) { case DXGI_FORMAT_B8G8R8X8_UNORM: flags |= CMSE_IGNORE_ALPHA; break; case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: flags |= CMSE_IMAGE2_SRGB | CMSE_IGNORE_ALPHA; break; case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: case DXGI_FORMAT_BC1_UNORM_SRGB: case DXGI_FORMAT_BC2_UNORM_SRGB: case DXGI_FORMAT_BC3_UNORM_SRGB: case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: case DXGI_FORMAT_BC7_UNORM_SRGB: flags |= CMSE_IMAGE2_SRGB; break; } const uint8_t *pSrc1 = image1.pixels; const size_t rowPitch1 = image1.rowPitch; const uint8_t *pSrc2 = image2.pixels; const size_t rowPitch2 = image2.rowPitch; XMVECTOR acc = g_XMZero; static XMVECTORF32 two = { 2.0f, 2.0f, 2.0f, 2.0f }; for( size_t h = 0; h < image1.height; ++h ) { XMVECTOR* ptr1 = scanline.get(); if ( !_LoadScanline( ptr1, width, pSrc1, rowPitch1, image1.format ) ) return E_FAIL; XMVECTOR* ptr2 = scanline.get() + width; if ( !_LoadScanline( ptr2, width, pSrc2, rowPitch2, image2.format ) ) return E_FAIL; for( size_t i = 0; i < width; ++i ) { XMVECTOR v1 = *(ptr1++); if ( flags & CMSE_IMAGE1_SRGB ) { v1 = XMVectorPow( v1, g_Gamma22 ); } if ( flags & CMSE_IMAGE1_X2_BIAS ) { v1 = XMVectorMultiplyAdd( v1, two, g_XMNegativeOne ); } XMVECTOR v2 = *(ptr2++); if ( flags & CMSE_IMAGE2_SRGB ) { v2 = XMVectorPow( v2, g_Gamma22 ); } if ( flags & CMSE_IMAGE2_X2_BIAS ) { v1 = XMVectorMultiplyAdd( v2, two, g_XMNegativeOne ); } // sum[ (I1 - I2)^2 ] XMVECTOR v = XMVectorSubtract( v1, v2 ); if ( flags & CMSE_IGNORE_RED ) { v = XMVectorSelect( v, g_XMZero, g_XMMaskX ); } if ( flags & CMSE_IGNORE_GREEN ) { v = XMVectorSelect( v, g_XMZero, g_XMMaskY ); } if ( flags & CMSE_IGNORE_BLUE ) { v = XMVectorSelect( v, g_XMZero, g_XMMaskZ ); } if ( flags & CMSE_IGNORE_ALPHA ) { v = XMVectorSelect( v, g_XMZero, g_XMMaskW ); } acc = XMVectorMultiplyAdd( v, v, acc ); } pSrc1 += rowPitch1; pSrc2 += rowPitch2; } // MSE = sum[ (I1 - I2)^2 ] / w*h XMVECTOR d = XMVectorReplicate( float(image1.width * image1.height) ); XMVECTOR v = XMVectorDivide( acc, d ); if ( mseV ) { XMStoreFloat4( reinterpret_cast( mseV ), v ); mse = mseV[0] + mseV[1] + mseV[2] + mseV[3]; } else { XMFLOAT4 _mseV; XMStoreFloat4( &_mseV, v ); mse = _mseV.x + _mseV.y + _mseV.z + _mseV.w; } return S_OK; } //===================================================================================== // Entry points //===================================================================================== //------------------------------------------------------------------------------------- // Copies a rectangle from one image into another //------------------------------------------------------------------------------------- _Use_decl_annotations_ HRESULT CopyRectangle( const Image& srcImage, const Rect& srcRect, const Image& dstImage, DWORD filter, size_t xOffset, size_t yOffset ) { if ( !srcImage.pixels || !dstImage.pixels ) return E_POINTER; if ( IsCompressed( srcImage.format ) || IsCompressed( dstImage.format ) || IsPlanar( srcImage.format ) || IsPlanar( dstImage.format ) || IsPalettized( srcImage.format ) || IsPalettized( dstImage.format ) ) return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); // Validate rectangle/offset if ( !srcRect.w || !srcRect.h || ( (srcRect.x + srcRect.w) > srcImage.width ) || ( (srcRect.y + srcRect.h) > srcImage.height ) ) { return E_INVALIDARG; } if ( ( (xOffset + srcRect.w) > dstImage.width ) || ( (yOffset + srcRect.h) > dstImage.height ) ) { return E_INVALIDARG; } // Compute source bytes-per-pixel size_t sbpp = BitsPerPixel( srcImage.format ); if ( !sbpp ) return E_FAIL; if ( sbpp < 8 ) { // We don't support monochrome (DXGI_FORMAT_R1_UNORM) return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); } const uint8_t* pEndSrc = srcImage.pixels + srcImage.rowPitch*srcImage.height; const uint8_t* pEndDest = dstImage.pixels + dstImage.rowPitch*dstImage.height; // Round to bytes sbpp = ( sbpp + 7 ) / 8; const uint8_t* pSrc = srcImage.pixels + (srcRect.y * srcImage.rowPitch) + (srcRect.x * sbpp); if ( srcImage.format == dstImage.format ) { // Direct copy case (avoid intermediate conversions) uint8_t* pDest = dstImage.pixels + (yOffset * dstImage.rowPitch) + (xOffset * sbpp); const size_t copyW = srcRect.w * sbpp; for( size_t h=0; h < srcRect.h; ++h ) { if ( ( (pSrc+copyW) > pEndSrc ) || (pDest > pEndDest) ) return E_FAIL; memcpy_s( pDest, pEndDest - pDest, pSrc, copyW ); pSrc += srcImage.rowPitch; pDest += dstImage.rowPitch; } return S_OK; } // Compute destination bytes-per-pixel (not the same format as source) size_t dbpp = BitsPerPixel( dstImage.format ); if ( !dbpp ) return E_FAIL; if ( dbpp < 8 ) { // We don't support monochrome (DXGI_FORMAT_R1_UNORM) return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); } // Round to bytes dbpp = ( dbpp + 7 ) / 8; uint8_t* pDest = dstImage.pixels + (yOffset * dstImage.rowPitch) + (xOffset * dbpp); ScopedAlignedArrayXMVECTOR scanline( reinterpret_cast( _aligned_malloc( (sizeof(XMVECTOR)*srcRect.w), 16 ) ) ); if ( !scanline ) return E_OUTOFMEMORY; const size_t copyS = srcRect.w * sbpp; const size_t copyD = srcRect.w * dbpp; for( size_t h=0; h < srcRect.h; ++h ) { if ( ( (pSrc+copyS) > pEndSrc) || ((pDest+copyD) > pEndDest) ) return E_FAIL; if ( !_LoadScanline( scanline.get(), srcRect.w, pSrc, copyS, srcImage.format ) ) return E_FAIL; _ConvertScanline( scanline.get(), srcRect.w, dstImage.format, srcImage.format, filter ); if ( !_StoreScanline( pDest, copyD, dstImage.format, scanline.get(), srcRect.w ) ) return E_FAIL; pSrc += srcImage.rowPitch; pDest += dstImage.rowPitch; } return S_OK; } //------------------------------------------------------------------------------------- // Computes the Mean-Squared-Error (MSE) between two images //------------------------------------------------------------------------------------- _Use_decl_annotations_ HRESULT ComputeMSE( const Image& image1, const Image& image2, float& mse, float* mseV, DWORD flags ) { if ( !image1.pixels || !image2.pixels ) return E_POINTER; if ( image1.width != image2.width || image1.height != image2.height ) return E_INVALIDARG; if ( IsPlanar( image1.format ) || IsPlanar( image2.format ) || IsPalettized( image1.format ) || IsPalettized( image2.format ) ) return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); if ( IsCompressed(image1.format) ) { if ( IsCompressed(image2.format) ) { // Case 1: both images are compressed, expand to RGBA32F ScratchImage temp1; HRESULT hr = Decompress( image1, DXGI_FORMAT_R32G32B32A32_FLOAT, temp1 ); if ( FAILED(hr) ) return hr; ScratchImage temp2; hr = Decompress( image2, DXGI_FORMAT_R32G32B32A32_FLOAT, temp2 ); if ( FAILED(hr) ) return hr; const Image* img1 = temp1.GetImage(0,0,0); const Image* img2 = temp2.GetImage(0,0,0); if ( !img1 || !img2 ) return E_POINTER; return _ComputeMSE( *img1, *img2, mse, mseV, flags ); } else { // Case 2: image1 is compressed, expand to RGBA32F ScratchImage temp; HRESULT hr = Decompress( image1, DXGI_FORMAT_R32G32B32A32_FLOAT, temp ); if ( FAILED(hr) ) return hr; const Image* img = temp.GetImage(0,0,0); if ( !img ) return E_POINTER; return _ComputeMSE( *img, image2, mse, mseV, flags ); } } else { if ( IsCompressed(image2.format) ) { // Case 3: image2 is compressed, expand to RGBA32F ScratchImage temp; HRESULT hr = Decompress( image2, DXGI_FORMAT_R32G32B32A32_FLOAT, temp ); if ( FAILED(hr) ) return hr; const Image* img = temp.GetImage(0,0,0); if ( !img ) return E_POINTER; return _ComputeMSE( image1, *img, mse, mseV, flags ); } else { // Case 4: neither image is compressed return _ComputeMSE( image1, image2, mse, mseV, flags ); } } } }; // namespace ================================================ FILE: 3rdParty/DirectXTex/DirectXTex/DirectXTexNormalMaps.cpp ================================================ //------------------------------------------------------------------------------------- // DirectXTexNormalMaps.cpp // // DirectX Texture Library - Normal map operations // // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A // PARTICULAR PURPOSE. // // Copyright (c) Microsoft Corporation. All rights reserved. // // http://go.microsoft.com/fwlink/?LinkId=248926 //------------------------------------------------------------------------------------- #include "directxtexp.h" namespace DirectX { #pragma prefast(suppress : 25000, "FXMVECTOR is 16 bytes") static inline float _EvaluateColor( _In_ FXMVECTOR val, _In_ DWORD flags ) { XMFLOAT4A f; static XMVECTORF32 lScale = { 0.2125f, 0.7154f, 0.0721f, 1.f }; static_assert( CNMAP_CHANNEL_RED == 0x1, "CNMAP_CHANNEL_ flag values don't match mask" ); switch( flags & 0xf ) { case 0: case CNMAP_CHANNEL_RED: return XMVectorGetX( val ); case CNMAP_CHANNEL_GREEN: return XMVectorGetY( val ); case CNMAP_CHANNEL_BLUE: return XMVectorGetZ( val ); case CNMAP_CHANNEL_ALPHA: return XMVectorGetW( val ); case CNMAP_CHANNEL_LUMINANCE: { XMVECTOR v = XMVectorMultiply( val, lScale ); XMStoreFloat4A( &f, v ); return f.x + f.y + f.z; } break; default: assert(false); return 0.f; } } static void _EvaluateRow( _In_reads_(width) const XMVECTOR* pSource, _Out_writes_(width+2) float* pDest, _In_ size_t width, _In_ DWORD flags ) { assert( pSource && pDest ); assert( width > 0 ); for( size_t x = 0; x < width; ++x ) { pDest[x+1] = _EvaluateColor( pSource[x], flags ); } if ( flags & CNMAP_MIRROR_U ) { // Mirror in U pDest[0] = _EvaluateColor( pSource[0], flags ); pDest[width+1] = _EvaluateColor( pSource[width-1], flags ); } else { // Wrap in U pDest[0] = _EvaluateColor( pSource[width-1], flags ); pDest[width+1] = _EvaluateColor( pSource[0], flags ); } } static HRESULT _ComputeNMap( _In_ const Image& srcImage, _In_ DWORD flags, _In_ float amplitude, _In_ DXGI_FORMAT format, _In_ const Image& normalMap ) { if ( !srcImage.pixels || !normalMap.pixels ) return E_INVALIDARG; const DWORD convFlags = _GetConvertFlags( format ); if ( !convFlags ) return E_FAIL; if ( !( convFlags & (CONVF_UNORM | CONVF_SNORM | CONVF_FLOAT) ) ) return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); const size_t width = srcImage.width; const size_t height = srcImage.height; if ( width != normalMap.width || height != normalMap.height ) return E_FAIL; // Allocate temporary space (4 scanlines and 3 evaluated rows) ScopedAlignedArrayXMVECTOR scanline( reinterpret_cast( _aligned_malloc( (sizeof(XMVECTOR)*width*4), 16 ) ) ); if ( !scanline ) return E_OUTOFMEMORY; ScopedAlignedArrayFloat buffer( reinterpret_cast( _aligned_malloc( ( ( sizeof(float) * ( width + 2 ) ) * 3 ), 16 ) ) ); if ( !buffer ) return E_OUTOFMEMORY; uint8_t* pDest = normalMap.pixels; if ( !pDest ) return E_POINTER; XMVECTOR* row0 = scanline.get(); XMVECTOR* row1 = row0 + width; XMVECTOR* row2 = row1 + width; XMVECTOR* target = row2 + width; float* val0 = buffer.get(); float* val1 = val0 + width + 2; float* val2 = val1 + width + 2; const size_t rowPitch = srcImage.rowPitch; const uint8_t* pSrc = srcImage.pixels; // Read first scanline row into 'row1' if ( !_LoadScanline( row1, width, pSrc, rowPitch, srcImage.format ) ) return E_FAIL; // Setup 'row0' if ( flags & CNMAP_MIRROR_V ) { // Mirror first row memcpy_s( row0, rowPitch, row1, rowPitch ); } else { // Read last row (Wrap V) if ( !_LoadScanline( row0, width, pSrc + (rowPitch * (height-1)), rowPitch, srcImage.format ) ) return E_FAIL; } // Evaluate the initial rows _EvaluateRow( row0, val0, width, flags ); _EvaluateRow( row1, val1, width, flags ); pSrc += rowPitch; for( size_t y = 0; y < height; ++y ) { // Load next scanline of source image if ( y < (height-1) ) { if ( !_LoadScanline( row2, width, pSrc, rowPitch, srcImage.format ) ) return E_FAIL; } else { if ( flags & CNMAP_MIRROR_V ) { // Use last row of source image if ( !_LoadScanline( row2, width, srcImage.pixels + (rowPitch * (height-1)), rowPitch, srcImage.format ) ) return E_FAIL; } else { // Use first row of source image (Wrap V) if ( !_LoadScanline( row2, width, srcImage.pixels, rowPitch, srcImage.format ) ) return E_FAIL; } } // Evaluate row _EvaluateRow( row2, val2, width, flags ); // Generate target scanline XMVECTOR *dptr = target; for( size_t x = 0; x < width; ++x ) { // Compute normal via central differencing float totDelta = ( val0[x] - val0[x+2] ) + ( val1[x] - val1[x+2] ) + ( val2[x] - val2[x+2] ); float deltaZX = totDelta * amplitude / 6.f; totDelta = ( val0[x] - val2[x] ) + ( val0[x+1] - val2[x+1] ) + ( val0[x+2] - val2[x+2] ); float deltaZY = totDelta * amplitude / 6.f; XMVECTOR vx = XMVectorSetZ( g_XMNegIdentityR0, deltaZX ); // (-1.0f, 0.0f, deltaZX) XMVECTOR vy = XMVectorSetZ( g_XMNegIdentityR1, deltaZY ); // (0.0f, -1.0f, deltaZY) XMVECTOR normal = XMVector3Normalize( XMVector3Cross( vx, vy ) ); // Compute alpha (1.0 or an occlusion term) float alpha = 1.f; if ( flags & CNMAP_COMPUTE_OCCLUSION ) { float delta = 0.f; float c = val1[x+1]; float t = val0[x] - c; if ( t > 0.f ) delta += t; t = val0[x+1] - c; if ( t > 0.f ) delta += t; t = val0[x+2] - c; if ( t > 0.f ) delta += t; t = val1[x] - c; if ( t > 0.f ) delta += t; // Skip current pixel t = val1[x+2] - c; if ( t > 0.f ) delta += t; t = val2[x] - c; if ( t > 0.f ) delta += t; t = val2[x+1] - c; if ( t > 0.f ) delta += t; t = val2[x+2] - c; if ( t > 0.f ) delta += t; // Average delta (divide by 8, scale by amplitude factor) delta *= 0.125f * amplitude; if ( delta > 0.f ) { // If < 0, then no occlusion float r = sqrtf( 1.f + delta*delta ); alpha = (r - delta) / r; } } // Encode based on target format if ( convFlags & CONVF_UNORM ) { // 0.5f*normal + 0.5f -or- invert sign case: -0.5f*normal + 0.5f XMVECTOR n1 = XMVectorMultiplyAdd( (flags & CNMAP_INVERT_SIGN) ? g_XMNegativeOneHalf : g_XMOneHalf, normal, g_XMOneHalf ); *dptr++ = XMVectorSetW( n1, alpha ); } else if ( flags & CNMAP_INVERT_SIGN ) { *dptr++ = XMVectorSetW( XMVectorNegate( normal ), alpha ); } else { *dptr++ = XMVectorSetW( normal, alpha ); } } if ( !_StoreScanline( pDest, normalMap.rowPitch, format, target, width ) ) return E_FAIL; // Cycle buffers float* temp = val0; val0 = val1; val1 = val2; val2 = temp; pSrc += rowPitch; pDest += normalMap.rowPitch; } return S_OK; } //===================================================================================== // Entry points //===================================================================================== //------------------------------------------------------------------------------------- // Generates a normal map from a height-map //------------------------------------------------------------------------------------- _Use_decl_annotations_ HRESULT ComputeNormalMap( const Image& srcImage, DWORD flags, float amplitude, DXGI_FORMAT format, ScratchImage& normalMap ) { if ( !srcImage.pixels || !IsValid(format) ) return E_INVALIDARG; static_assert( CNMAP_CHANNEL_RED == 0x1, "CNMAP_CHANNEL_ flag values don't match mask" ); switch( flags & 0xf ) { case 0: case CNMAP_CHANNEL_RED: case CNMAP_CHANNEL_GREEN: case CNMAP_CHANNEL_BLUE: case CNMAP_CHANNEL_ALPHA: case CNMAP_CHANNEL_LUMINANCE: break; default: return E_INVALIDARG; } if ( IsCompressed(format) || IsCompressed(srcImage.format) || IsTypeless(format) || IsTypeless(srcImage.format) || IsPlanar(format) || IsPlanar(srcImage.format) || IsPalettized(format) || IsPalettized(srcImage.format) ) return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); // Setup target image normalMap.Release(); HRESULT hr = normalMap.Initialize2D( format, srcImage.width, srcImage.height, 1, 1 ); if ( FAILED(hr) ) return hr; const Image *img = normalMap.GetImage( 0, 0, 0 ); if ( !img ) { normalMap.Release(); return E_POINTER; } hr = _ComputeNMap( srcImage, flags, amplitude, format, *img ); if ( FAILED(hr) ) { normalMap.Release(); return hr; } return S_OK; } _Use_decl_annotations_ HRESULT ComputeNormalMap( const Image* srcImages, size_t nimages, const TexMetadata& metadata, DWORD flags, float amplitude, DXGI_FORMAT format, ScratchImage& normalMaps ) { if ( !srcImages || !nimages || !IsValid(format) ) return E_INVALIDARG; if ( IsCompressed(format) || IsCompressed(metadata.format) || IsTypeless(format) || IsTypeless(metadata.format) || IsPlanar(format) || IsPlanar(metadata.format) || IsPalettized(format) || IsPalettized(metadata.format) ) return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); static_assert( CNMAP_CHANNEL_RED == 0x1, "CNMAP_CHANNEL_ flag values don't match mask" ); switch( flags & 0xf ) { case 0: case CNMAP_CHANNEL_RED: case CNMAP_CHANNEL_GREEN: case CNMAP_CHANNEL_BLUE: case CNMAP_CHANNEL_ALPHA: case CNMAP_CHANNEL_LUMINANCE: break; default: return E_INVALIDARG; } normalMaps.Release(); TexMetadata mdata2 = metadata; mdata2.format = format; HRESULT hr = normalMaps.Initialize( mdata2 ); if ( FAILED(hr) ) return hr; if ( nimages != normalMaps.GetImageCount() ) { normalMaps.Release(); return E_FAIL; } const Image* dest = normalMaps.GetImages(); if ( !dest ) { normalMaps.Release(); return E_POINTER; } for( size_t index=0; index < nimages; ++index ) { assert( dest[ index ].format == format ); const Image& src = srcImages[ index ]; if ( IsCompressed( src.format ) || IsTypeless( src.format ) ) { normalMaps.Release(); return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); } if ( src.width != dest[ index ].width || src.height != dest[ index ].height ) { normalMaps.Release(); return E_FAIL; } hr = _ComputeNMap( src, flags, amplitude, format, dest[ index ] ); if ( FAILED(hr) ) { normalMaps.Release(); return hr; } } return S_OK; } }; // namespace ================================================ FILE: 3rdParty/DirectXTex/DirectXTex/DirectXTexP.h ================================================ //------------------------------------------------------------------------------------- // DirectXTexp.h // // DirectX Texture Library - Private header // // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A // PARTICULAR PURPOSE. // // Copyright (c) Microsoft Corporation. All rights reserved. // // http://go.microsoft.com/fwlink/?LinkId=248926 //------------------------------------------------------------------------------------- #pragma once #define NOMINMAX #include #include #include #include #include #include #include #include #include #include #include "directxtex.h" // VS 2010's stdint.h conflicts with intsafe.h #pragma warning(push) #pragma warning(disable : 4005) #include #include #pragma warning(pop) #include #include "scoped.h" struct IWICImagingFactory; #define TEX_FILTER_MASK 0xF00000 namespace DirectX { //--------------------------------------------------------------------------------- // WIC helper functions DXGI_FORMAT __cdecl _WICToDXGI( _In_ const GUID& guid ); bool __cdecl _DXGIToWIC( _In_ DXGI_FORMAT format, _Out_ GUID& guid, _In_ bool ignoreRGBvsBGR = false ); DWORD __cdecl _CheckWICColorSpace( _In_ const GUID& sourceGUID, _In_ const GUID& targetGUID ); IWICImagingFactory* __cdecl _GetWIC(); bool __cdecl _IsWIC2(); inline WICBitmapDitherType __cdecl _GetWICDither( _In_ DWORD flags ) { static_assert( TEX_FILTER_DITHER == 0x10000, "TEX_FILTER_DITHER* flag values don't match mask" ); static_assert( TEX_FILTER_DITHER == WIC_FLAGS_DITHER, "TEX_FILTER_DITHER* should match WIC_FLAGS_DITHER*" ); static_assert( TEX_FILTER_DITHER_DIFFUSION == WIC_FLAGS_DITHER_DIFFUSION, "TEX_FILTER_DITHER* should match WIC_FLAGS_DITHER*" ); switch( flags & 0xF0000 ) { case TEX_FILTER_DITHER: return WICBitmapDitherTypeOrdered4x4; case TEX_FILTER_DITHER_DIFFUSION: return WICBitmapDitherTypeErrorDiffusion; default: return WICBitmapDitherTypeNone; } } inline WICBitmapInterpolationMode __cdecl _GetWICInterp( _In_ DWORD flags ) { static_assert( TEX_FILTER_POINT == 0x100000, "TEX_FILTER_ flag values don't match TEX_FILTER_MASK" ); static_assert( TEX_FILTER_POINT == WIC_FLAGS_FILTER_POINT, "TEX_FILTER_* flags should match WIC_FLAGS_FILTER_*" ); static_assert( TEX_FILTER_LINEAR == WIC_FLAGS_FILTER_LINEAR, "TEX_FILTER_* flags should match WIC_FLAGS_FILTER_*" ); static_assert( TEX_FILTER_CUBIC == WIC_FLAGS_FILTER_CUBIC, "TEX_FILTER_* flags should match WIC_FLAGS_FILTER_*" ); static_assert( TEX_FILTER_FANT == WIC_FLAGS_FILTER_FANT, "TEX_FILTER_* flags should match WIC_FLAGS_FILTER_*" ); switch( flags & TEX_FILTER_MASK ) { case TEX_FILTER_POINT: return WICBitmapInterpolationModeNearestNeighbor; case TEX_FILTER_LINEAR: return WICBitmapInterpolationModeLinear; case TEX_FILTER_CUBIC: return WICBitmapInterpolationModeCubic; case TEX_FILTER_FANT: default: return WICBitmapInterpolationModeFant; } } //--------------------------------------------------------------------------------- // Image helper functions void __cdecl _DetermineImageArray( _In_ const TexMetadata& metadata, _In_ DWORD cpFlags, _Out_ size_t& nImages, _Out_ size_t& pixelSize ); _Success_(return != false) bool __cdecl _SetupImageArray( _In_reads_bytes_(pixelSize) uint8_t *pMemory, _In_ size_t pixelSize, _In_ const TexMetadata& metadata, _In_ DWORD cpFlags, _Out_writes_(nImages) Image* images, _In_ size_t nImages ); //--------------------------------------------------------------------------------- // Conversion helper functions enum TEXP_SCANLINE_FLAGS { TEXP_SCANLINE_NONE = 0, TEXP_SCANLINE_SETALPHA = 0x1, // Set alpha channel to known opaque value TEXP_SCANLINE_LEGACY = 0x2, // Enables specific legacy format conversion cases }; enum CONVERT_FLAGS { CONVF_FLOAT = 0x1, CONVF_UNORM = 0x2, CONVF_UINT = 0x4, CONVF_SNORM = 0x8, CONVF_SINT = 0x10, CONVF_DEPTH = 0x20, CONVF_STENCIL = 0x40, CONVF_SHAREDEXP = 0x80, CONVF_BGR = 0x100, CONVF_XR = 0x200, CONVF_PACKED = 0x400, CONVF_BC = 0x800, CONVF_YUV = 0x1000, CONVF_R = 0x10000, CONVF_G = 0x20000, CONVF_B = 0x40000, CONVF_A = 0x80000, CONVF_RGB_MASK = 0x70000, CONVF_RGBA_MASK = 0xF0000, }; DWORD __cdecl _GetConvertFlags( _In_ DXGI_FORMAT format ); void __cdecl _CopyScanline( _When_(pDestination == pSource, _Inout_updates_bytes_(outSize)) _When_(pDestination != pSource, _Out_writes_bytes_(outSize)) LPVOID pDestination, _In_ size_t outSize, _In_reads_bytes_(inSize) LPCVOID pSource, _In_ size_t inSize, _In_ DXGI_FORMAT format, _In_ DWORD flags ); void __cdecl _SwizzleScanline( _When_(pDestination == pSource, _In_) _When_(pDestination != pSource, _Out_writes_bytes_(outSize)) LPVOID pDestination, _In_ size_t outSize, _In_reads_bytes_(inSize) LPCVOID pSource, _In_ size_t inSize, _In_ DXGI_FORMAT format, _In_ DWORD flags ); _Success_(return != false) bool __cdecl _ExpandScanline( _Out_writes_bytes_(outSize) LPVOID pDestination, _In_ size_t outSize, _In_ DXGI_FORMAT outFormat, _In_reads_bytes_(inSize) LPCVOID pSource, _In_ size_t inSize, _In_ DXGI_FORMAT inFormat, _In_ DWORD flags ); _Success_(return != false) bool __cdecl _LoadScanline( _Out_writes_(count) XMVECTOR* pDestination, _In_ size_t count, _In_reads_bytes_(size) LPCVOID pSource, _In_ size_t size, _In_ DXGI_FORMAT format ); _Success_(return != false) bool __cdecl _LoadScanlineLinear( _Out_writes_(count) XMVECTOR* pDestination, _In_ size_t count, _In_reads_bytes_(size) LPCVOID pSource, _In_ size_t size, _In_ DXGI_FORMAT format, _In_ DWORD flags ); _Success_(return != false) bool __cdecl _StoreScanline( LPVOID pDestination, _In_ size_t size, _In_ DXGI_FORMAT format, _In_reads_(count) const XMVECTOR* pSource, _In_ size_t count, _In_ float threshold = 0 ); _Success_(return != false) bool __cdecl _StoreScanlineLinear( LPVOID pDestination, _In_ size_t size, _In_ DXGI_FORMAT format, _Inout_updates_all_(count) XMVECTOR* pSource, _In_ size_t count, _In_ DWORD flags, _In_ float threshold = 0 ); _Success_(return != false) bool __cdecl _StoreScanlineDither( LPVOID pDestination, _In_ size_t size, _In_ DXGI_FORMAT format, _Inout_updates_all_(count) XMVECTOR* pSource, _In_ size_t count, _In_ float threshold, size_t y, size_t z, _Inout_updates_all_opt_(count+2) XMVECTOR* pDiffusionErrors ); HRESULT __cdecl _ConvertToR32G32B32A32( _In_ const Image& srcImage, _Inout_ ScratchImage& image ); HRESULT __cdecl _ConvertFromR32G32B32A32( _In_ const Image& srcImage, _In_ const Image& destImage ); HRESULT __cdecl _ConvertFromR32G32B32A32( _In_ const Image& srcImage, _In_ DXGI_FORMAT format, _Inout_ ScratchImage& image ); HRESULT __cdecl _ConvertFromR32G32B32A32( _In_reads_(nimages) const Image* srcImages, _In_ size_t nimages, _In_ const TexMetadata& metadata, _In_ DXGI_FORMAT format, _Out_ ScratchImage& result ); void __cdecl _ConvertScanline( _Inout_updates_all_(count) XMVECTOR* pBuffer, _In_ size_t count, _In_ DXGI_FORMAT outFormat, _In_ DXGI_FORMAT inFormat, _In_ DWORD flags ); //--------------------------------------------------------------------------------- // DDS helper functions HRESULT __cdecl _EncodeDDSHeader( _In_ const TexMetadata& metadata, DWORD flags, _Out_writes_bytes_to_opt_(maxsize, required) LPVOID pDestination, _In_ size_t maxsize, _Out_ size_t& required ); }; // namespace ================================================ FILE: 3rdParty/DirectXTex/DirectXTex/DirectXTexPMAlpha.cpp ================================================ //------------------------------------------------------------------------------------- // DirectXTexPMAlpha.cpp // // DirectX Texture Library - Premultiplied alpha operations // // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A // PARTICULAR PURPOSE. // // Copyright (c) Microsoft Corporation. All rights reserved. // // http://go.microsoft.com/fwlink/?LinkId=248926 //------------------------------------------------------------------------------------- #include "directxtexp.h" namespace DirectX { static HRESULT _PremultiplyAlpha( _In_ const Image& srcImage, _In_ const Image& destImage ) { assert( srcImage.width == destImage.width ); assert( srcImage.height == destImage.height ); ScopedAlignedArrayXMVECTOR scanline( reinterpret_cast( _aligned_malloc( (sizeof(XMVECTOR)*srcImage.width), 16 ) ) ); if ( !scanline ) return E_OUTOFMEMORY; const uint8_t *pSrc = srcImage.pixels; uint8_t *pDest = destImage.pixels; if ( !pSrc || !pDest ) return E_POINTER; for( size_t h = 0; h < srcImage.height; ++h ) { if ( !_LoadScanline( scanline.get(), srcImage.width, pSrc, srcImage.rowPitch, srcImage.format ) ) return E_FAIL; XMVECTOR* ptr = scanline.get(); for( size_t w = 0; w < srcImage.width; ++w ) { XMVECTOR v = *ptr; XMVECTOR alpha = XMVectorSplatW( *ptr ); alpha = XMVectorMultiply( v, alpha ); *(ptr++) = XMVectorSelect( v, alpha, g_XMSelect1110 ); } if ( !_StoreScanline( pDest, destImage.rowPitch, destImage.format, scanline.get(), srcImage.width ) ) return E_FAIL; pSrc += srcImage.rowPitch; pDest += destImage.rowPitch; } return S_OK; } static HRESULT _PremultiplyAlphaLinear( _In_ const Image& srcImage, _In_ DWORD flags, _In_ const Image& destImage ) { assert( srcImage.width == destImage.width ); assert( srcImage.height == destImage.height ); static_assert( TEX_PMALPHA_SRGB_IN == TEX_FILTER_SRGB_IN, "TEX_PMALHPA_SRGB* should match TEX_FILTER_SRGB*" ); static_assert( TEX_PMALPHA_SRGB_OUT == TEX_FILTER_SRGB_OUT, "TEX_PMALHPA_SRGB* should match TEX_FILTER_SRGB*" ); static_assert( TEX_PMALPHA_SRGB == TEX_FILTER_SRGB, "TEX_PMALHPA_SRGB* should match TEX_FILTER_SRGB*" ); flags &= TEX_PMALPHA_SRGB; ScopedAlignedArrayXMVECTOR scanline( reinterpret_cast( _aligned_malloc( (sizeof(XMVECTOR)*srcImage.width), 16 ) ) ); if ( !scanline ) return E_OUTOFMEMORY; const uint8_t *pSrc = srcImage.pixels; uint8_t *pDest = destImage.pixels; if ( !pSrc || !pDest ) return E_POINTER; for( size_t h = 0; h < srcImage.height; ++h ) { if ( !_LoadScanlineLinear( scanline.get(), srcImage.width, pSrc, srcImage.rowPitch, srcImage.format, flags ) ) return E_FAIL; XMVECTOR* ptr = scanline.get(); for( size_t w = 0; w < srcImage.width; ++w ) { XMVECTOR v = *ptr; XMVECTOR alpha = XMVectorSplatW( *ptr ); alpha = XMVectorMultiply( v, alpha ); *(ptr++) = XMVectorSelect( v, alpha, g_XMSelect1110 ); } if ( !_StoreScanlineLinear( pDest, destImage.rowPitch, destImage.format, scanline.get(), srcImage.width, flags ) ) return E_FAIL; pSrc += srcImage.rowPitch; pDest += destImage.rowPitch; } return S_OK; } //===================================================================================== // Entry-points //===================================================================================== //------------------------------------------------------------------------------------- // Converts to a premultiplied alpha version of the texture //------------------------------------------------------------------------------------- _Use_decl_annotations_ HRESULT PremultiplyAlpha( const Image& srcImage, DWORD flags, ScratchImage& image ) { if ( !srcImage.pixels ) return E_POINTER; if ( IsCompressed(srcImage.format) || IsPlanar(srcImage.format) || IsPalettized(srcImage.format) || IsTypeless(srcImage.format) || !HasAlpha(srcImage.format) ) return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); #ifdef _M_X64 if ( (srcImage.width > 0xFFFFFFFF) || (srcImage.height > 0xFFFFFFFF) ) return E_INVALIDARG; #endif HRESULT hr = image.Initialize2D( srcImage.format, srcImage.width, srcImage.height, 1, 1 ); if ( FAILED(hr) ) return hr; const Image *rimage = image.GetImage( 0, 0, 0 ); if ( !rimage ) { image.Release(); return E_POINTER; } hr = ( flags & TEX_PMALPHA_IGNORE_SRGB ) ? _PremultiplyAlpha( srcImage, *rimage ) : _PremultiplyAlphaLinear( srcImage, flags, *rimage ); if ( FAILED(hr) ) { image.Release(); return hr; } return S_OK; } //------------------------------------------------------------------------------------- // Converts to a premultiplied alpha version of the texture (complex) //------------------------------------------------------------------------------------- _Use_decl_annotations_ HRESULT PremultiplyAlpha( const Image* srcImages, size_t nimages, const TexMetadata& metadata, DWORD flags, ScratchImage& result ) { if ( !srcImages || !nimages ) return E_INVALIDARG; if ( IsCompressed(metadata.format) || IsPlanar(metadata.format) || IsPalettized(metadata.format) || IsTypeless(metadata.format) || !HasAlpha(metadata.format) ) return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); #ifdef _M_X64 if ( (metadata.width > 0xFFFFFFFF) || (metadata.height > 0xFFFFFFFF) ) return E_INVALIDARG; #endif if ( metadata.IsPMAlpha() ) { // Already premultiplied return E_FAIL; } TexMetadata mdata2 = metadata; mdata2.SetAlphaMode(TEX_ALPHA_MODE_PREMULTIPLIED); HRESULT hr = result.Initialize( mdata2 ); if ( FAILED(hr) ) return hr; if ( nimages != result.GetImageCount() ) { result.Release(); return E_FAIL; } const Image* dest = result.GetImages(); if ( !dest ) { result.Release(); return E_POINTER; } for( size_t index=0; index < nimages; ++index ) { const Image& src = srcImages[ index ]; if ( src.format != metadata.format ) { result.Release(); return E_FAIL; } #ifdef _M_X64 if ( (src.width > 0xFFFFFFFF) || (src.height > 0xFFFFFFFF) ) return E_FAIL; #endif const Image& dst = dest[ index ]; assert( dst.format == metadata.format ); if ( src.width != dst.width || src.height != dst.height ) { result.Release(); return E_FAIL; } hr = ( flags & TEX_PMALPHA_IGNORE_SRGB ) ? _PremultiplyAlpha( src, dst ) : _PremultiplyAlphaLinear( src, flags, dst ); if ( FAILED(hr) ) { result.Release(); return hr; } } return S_OK; } }; // namespace ================================================ FILE: 3rdParty/DirectXTex/DirectXTex/DirectXTexResize.cpp ================================================ //------------------------------------------------------------------------------------- // DirectXTexResize.cpp // // DirectX Texture Library - Image resizing operations // // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A // PARTICULAR PURPOSE. // // Copyright (c) Microsoft Corporation. All rights reserved. // // http://go.microsoft.com/fwlink/?LinkId=248926 //------------------------------------------------------------------------------------- #include "directxtexp.h" #include "filters.h" using Microsoft::WRL::ComPtr; namespace DirectX { //------------------------------------------------------------------------------------- // WIC related helper functions //------------------------------------------------------------------------------------- extern HRESULT _ResizeSeparateColorAndAlpha( _In_ IWICImagingFactory* pWIC, _In_ IWICBitmap* original, _In_ size_t newWidth, _In_ size_t newHeight, _In_ DWORD filter, _Inout_ const Image* img ); //--- Do image resize using WIC --- static HRESULT _PerformResizeUsingWIC( _In_ const Image& srcImage, _In_ DWORD filter, _In_ const WICPixelFormatGUID& pfGUID, _In_ const Image& destImage ) { if ( !srcImage.pixels || !destImage.pixels ) return E_POINTER; assert( srcImage.format == destImage.format ); IWICImagingFactory* pWIC = _GetWIC(); if ( !pWIC ) return E_NOINTERFACE; ComPtr componentInfo; HRESULT hr = pWIC->CreateComponentInfo( pfGUID, componentInfo.GetAddressOf() ); if ( FAILED(hr) ) return hr; ComPtr pixelFormatInfo; hr = componentInfo.As( &pixelFormatInfo ); if ( FAILED(hr) ) return hr; BOOL supportsTransparency = FALSE; hr = pixelFormatInfo->SupportsTransparency( &supportsTransparency ); if ( FAILED(hr) ) return hr; ComPtr source; hr = pWIC->CreateBitmapFromMemory( static_cast( srcImage.width ), static_cast( srcImage.height ), pfGUID, static_cast( srcImage.rowPitch ), static_cast( srcImage.slicePitch ), srcImage.pixels, source.GetAddressOf() ); if ( FAILED(hr) ) return hr; if ( (filter & TEX_FILTER_SEPARATE_ALPHA) && supportsTransparency ) { hr = _ResizeSeparateColorAndAlpha( pWIC, source.Get(), destImage.width, destImage.height, filter, &destImage ); if ( FAILED(hr) ) return hr; } else { ComPtr scaler; hr = pWIC->CreateBitmapScaler( scaler.GetAddressOf() ); if ( FAILED(hr) ) return hr; hr = scaler->Initialize( source.Get(), static_cast( destImage.width ), static_cast( destImage.height ), _GetWICInterp( filter ) ); if ( FAILED(hr) ) return hr; WICPixelFormatGUID pfScaler; hr = scaler->GetPixelFormat( &pfScaler ); if ( FAILED(hr) ) return hr; if ( memcmp( &pfScaler, &pfGUID, sizeof(WICPixelFormatGUID) ) == 0 ) { hr = scaler->CopyPixels( 0, static_cast( destImage.rowPitch ), static_cast( destImage.slicePitch ), destImage.pixels ); if ( FAILED(hr) ) return hr; } else { // The WIC bitmap scaler is free to return a different pixel format than the source image, so here we // convert it back ComPtr FC; hr = pWIC->CreateFormatConverter( FC.GetAddressOf() ); if ( FAILED(hr) ) return hr; BOOL canConvert = FALSE; hr = FC->CanConvert( pfScaler, pfGUID, &canConvert ); if ( FAILED(hr) || !canConvert ) { return E_UNEXPECTED; } hr = FC->Initialize( scaler.Get(), pfGUID, _GetWICDither( filter ), 0, 0, WICBitmapPaletteTypeCustom ); if ( FAILED(hr) ) return hr; hr = FC->CopyPixels( 0, static_cast( destImage.rowPitch ), static_cast( destImage.slicePitch ), destImage.pixels ); if ( FAILED(hr) ) return hr; } } return S_OK; } //--- Do conversion, resize using WIC, conversion cycle --- static HRESULT _PerformResizeViaF32( _In_ const Image& srcImage, _In_ DWORD filter, _In_ const Image& destImage ) { if ( !srcImage.pixels || !destImage.pixels ) return E_POINTER; assert( srcImage.format != DXGI_FORMAT_R32G32B32A32_FLOAT ); assert( srcImage.format == destImage.format ); ScratchImage temp; HRESULT hr = _ConvertToR32G32B32A32( srcImage, temp ); if ( FAILED(hr) ) return hr; const Image *tsrc = temp.GetImage( 0, 0, 0 ); if ( !tsrc ) return E_POINTER; ScratchImage rtemp; hr = rtemp.Initialize2D( DXGI_FORMAT_R32G32B32A32_FLOAT, destImage.width, destImage.height, 1, 1 ); if ( FAILED(hr) ) return hr; const Image *tdest = rtemp.GetImage( 0, 0, 0 ); if ( !tdest ) return E_POINTER; hr = _PerformResizeUsingWIC( *tsrc, filter, GUID_WICPixelFormat128bppRGBAFloat, *tdest ); if ( FAILED(hr) ) return hr; temp.Release(); hr = _ConvertFromR32G32B32A32( *tdest, destImage ); if ( FAILED(hr) ) return hr; return S_OK; } //--- determine when to use WIC vs. non-WIC paths --- static bool _UseWICFiltering( _In_ DXGI_FORMAT format, _In_ DWORD filter ) { if ( filter & TEX_FILTER_FORCE_NON_WIC ) { // Explicit flag indicates use of non-WIC code paths return false; } if ( filter & TEX_FILTER_FORCE_WIC ) { // Explicit flag to use WIC code paths, skips all the case checks below return true; } if ( IsSRGB(format) || (filter & TEX_FILTER_SRGB) ) { // Use non-WIC code paths for sRGB correct filtering return false; } #if defined(_XBOX_ONE) && defined(_TITLE) if ( format == DXGI_FORMAT_R16G16B16A16_FLOAT || format == DXGI_FORMAT_R16_FLOAT ) { // Use non-WIC code paths as these conversions are not supported by Xbox One XDK return false; } #endif static_assert( TEX_FILTER_POINT == 0x100000, "TEX_FILTER_ flag values don't match TEX_FILTER_MASK" ); switch ( filter & TEX_FILTER_MASK ) { case TEX_FILTER_LINEAR: if ( filter & TEX_FILTER_WRAP ) { // WIC only supports 'clamp' semantics (MIRROR is equivalent to clamp for linear) return false; } if ( BitsPerColor(format) > 8 ) { // Avoid the WIC bitmap scaler when doing Linear filtering of XR/HDR formats return false; } break; case TEX_FILTER_CUBIC: if ( filter & ( TEX_FILTER_WRAP | TEX_FILTER_MIRROR ) ) { // WIC only supports 'clamp' semantics return false; } if ( BitsPerColor(format) > 8 ) { // Avoid the WIC bitmap scaler when doing Cubic filtering of XR/HDR formats return false; } break; case TEX_FILTER_TRIANGLE: // WIC does not implement this filter return false; } return true; } //------------------------------------------------------------------------------------- // Resize custom filters //------------------------------------------------------------------------------------- //--- Point Filter --- static HRESULT _ResizePointFilter( _In_ const Image& srcImage, _In_ const Image& destImage ) { assert( srcImage.pixels && destImage.pixels ); assert( srcImage.format == destImage.format ); // Allocate temporary space (2 scanlines) ScopedAlignedArrayXMVECTOR scanline( reinterpret_cast( _aligned_malloc( ( sizeof(XMVECTOR) * (srcImage.width + destImage.width ) ), 16 ) ) ); if ( !scanline ) return E_OUTOFMEMORY; XMVECTOR* target = scanline.get(); XMVECTOR* row = target + destImage.width; #ifdef _DEBUG memset( row, 0xCD, sizeof(XMVECTOR)*srcImage.width ); #endif const uint8_t* pSrc = srcImage.pixels; uint8_t* pDest = destImage.pixels; size_t rowPitch = srcImage.rowPitch; size_t xinc = ( srcImage.width << 16 ) / destImage.width; size_t yinc = ( srcImage.height << 16 ) / destImage.height; size_t lasty = size_t(-1); size_t sy = 0; for( size_t y = 0; y < destImage.height; ++y ) { if ( (lasty ^ sy) >> 16 ) { if ( !_LoadScanline( row, srcImage.width, pSrc + ( rowPitch * (sy >> 16) ), rowPitch, srcImage.format ) ) return E_FAIL; lasty = sy; } size_t sx = 0; for( size_t x = 0; x < destImage.width; ++x ) { target[ x ] = row[ sx >> 16 ]; sx += xinc; } if ( !_StoreScanline( pDest, destImage.rowPitch, destImage.format, target, destImage.width ) ) return E_FAIL; pDest += destImage.rowPitch; sy += yinc; } return S_OK; } //--- Box Filter --- static HRESULT _ResizeBoxFilter( _In_ const Image& srcImage, _In_ DWORD filter, _In_ const Image& destImage ) { assert( srcImage.pixels && destImage.pixels ); assert( srcImage.format == destImage.format ); if ( ( (destImage.width << 1) != srcImage.width ) || ( (destImage.height << 1) != srcImage.height ) ) return E_FAIL; // Allocate temporary space (3 scanlines) ScopedAlignedArrayXMVECTOR scanline( reinterpret_cast( _aligned_malloc( ( sizeof(XMVECTOR) * ( srcImage.width*2 + destImage.width ) ), 16 ) ) ); if ( !scanline ) return E_OUTOFMEMORY; XMVECTOR* target = scanline.get(); XMVECTOR* urow0 = target + destImage.width; XMVECTOR* urow1 = urow0 + srcImage.width; #ifdef _DEBUG memset( urow0, 0xCD, sizeof(XMVECTOR)*srcImage.width ); memset( urow1, 0xDD, sizeof(XMVECTOR)*srcImage.width ); #endif const XMVECTOR* urow2 = urow0 + 1; const XMVECTOR* urow3 = urow1 + 1; const uint8_t* pSrc = srcImage.pixels; uint8_t* pDest = destImage.pixels; size_t rowPitch = srcImage.rowPitch; for( size_t y = 0; y < destImage.height; ++y ) { if ( !_LoadScanlineLinear( urow0, srcImage.width, pSrc, rowPitch, srcImage.format, filter ) ) return E_FAIL; pSrc += rowPitch; if ( urow0 != urow1 ) { if ( !_LoadScanlineLinear( urow1, srcImage.width, pSrc, rowPitch, srcImage.format, filter ) ) return E_FAIL; pSrc += rowPitch; } for( size_t x = 0; x < destImage.width; ++x ) { size_t x2 = x << 1; AVERAGE4( target[ x ], urow0[ x2 ], urow1[ x2 ], urow2[ x2 ], urow3[ x2 ] ); } if ( !_StoreScanlineLinear( pDest, destImage.rowPitch, destImage.format, target, destImage.width, filter ) ) return E_FAIL; pDest += destImage.rowPitch; } return S_OK; } //--- Linear Filter --- static HRESULT _ResizeLinearFilter( _In_ const Image& srcImage, _In_ DWORD filter, _In_ const Image& destImage ) { assert( srcImage.pixels && destImage.pixels ); assert( srcImage.format == destImage.format ); // Allocate temporary space (3 scanlines, plus X and Y filters) ScopedAlignedArrayXMVECTOR scanline( reinterpret_cast( _aligned_malloc( ( sizeof(XMVECTOR) * ( srcImage.width*2 + destImage.width ) ), 16 ) ) ); if ( !scanline ) return E_OUTOFMEMORY; std::unique_ptr lf( new (std::nothrow) LinearFilter[ destImage.width + destImage.height ] ); if ( !lf ) return E_OUTOFMEMORY; LinearFilter* lfX = lf.get(); LinearFilter* lfY = lf.get() + destImage.width; _CreateLinearFilter( srcImage.width, destImage.width, (filter & TEX_FILTER_WRAP_U) != 0, lfX ); _CreateLinearFilter( srcImage.height, destImage.height, (filter & TEX_FILTER_WRAP_V) != 0, lfY ); XMVECTOR* target = scanline.get(); XMVECTOR* row0 = target + destImage.width; XMVECTOR* row1 = row0 + srcImage.width; #ifdef _DEBUG memset( row0, 0xCD, sizeof(XMVECTOR)*srcImage.width ); memset( row1, 0xDD, sizeof(XMVECTOR)*srcImage.width ); #endif const uint8_t* pSrc = srcImage.pixels; uint8_t* pDest = destImage.pixels; size_t rowPitch = srcImage.rowPitch; size_t u0 = size_t(-1); size_t u1 = size_t(-1); for( size_t y = 0; y < destImage.height; ++y ) { auto& toY = lfY[ y ]; if ( toY.u0 != u0 ) { if ( toY.u0 != u1 ) { u0 = toY.u0; if ( !_LoadScanlineLinear( row0, srcImage.width, pSrc + (rowPitch * u0), rowPitch, srcImage.format, filter ) ) return E_FAIL; } else { u0 = u1; u1 = size_t(-1); std::swap( row0, row1 ); } } if ( toY.u1 != u1 ) { u1 = toY.u1; if ( !_LoadScanlineLinear( row1, srcImage.width, pSrc + (rowPitch * u1), rowPitch, srcImage.format, filter ) ) return E_FAIL; } for( size_t x = 0; x < destImage.width; ++x ) { auto& toX = lfX[ x ]; BILINEAR_INTERPOLATE( target[x], toX, toY, row0, row1 ); } if ( !_StoreScanlineLinear( pDest, destImage.rowPitch, destImage.format, target, destImage.width, filter ) ) return E_FAIL; pDest += destImage.rowPitch; } return S_OK; } //--- Cubic Filter --- static HRESULT _ResizeCubicFilter( _In_ const Image& srcImage, _In_ DWORD filter, _In_ const Image& destImage ) { assert( srcImage.pixels && destImage.pixels ); assert( srcImage.format == destImage.format ); // Allocate temporary space (5 scanlines, plus X and Y filters) ScopedAlignedArrayXMVECTOR scanline( reinterpret_cast( _aligned_malloc( ( sizeof(XMVECTOR) * ( srcImage.width*4 + destImage.width ) ), 16 ) ) ); if ( !scanline ) return E_OUTOFMEMORY; std::unique_ptr cf( new (std::nothrow) CubicFilter[ destImage.width + destImage.height ] ); if ( !cf ) return E_OUTOFMEMORY; CubicFilter* cfX = cf.get(); CubicFilter* cfY = cf.get() + destImage.width; _CreateCubicFilter( srcImage.width, destImage.width, (filter & TEX_FILTER_WRAP_U) != 0, (filter & TEX_FILTER_MIRROR_U) != 0, cfX ); _CreateCubicFilter( srcImage.height, destImage.height, (filter & TEX_FILTER_WRAP_V) != 0, (filter & TEX_FILTER_MIRROR_V) != 0, cfY ); XMVECTOR* target = scanline.get(); XMVECTOR* row0 = target + destImage.width; XMVECTOR* row1 = row0 + srcImage.width; XMVECTOR* row2 = row0 + srcImage.width*2; XMVECTOR* row3 = row0 + srcImage.width*3; #ifdef _DEBUG memset( row0, 0xCD, sizeof(XMVECTOR)*srcImage.width ); memset( row1, 0xDD, sizeof(XMVECTOR)*srcImage.width ); memset( row2, 0xED, sizeof(XMVECTOR)*srcImage.width ); memset( row3, 0xFD, sizeof(XMVECTOR)*srcImage.width ); #endif const uint8_t* pSrc = srcImage.pixels; uint8_t* pDest = destImage.pixels; size_t rowPitch = srcImage.rowPitch; size_t u0 = size_t(-1); size_t u1 = size_t(-1); size_t u2 = size_t(-1); size_t u3 = size_t(-1); for( size_t y = 0; y < destImage.height; ++y ) { auto& toY = cfY[ y ]; // Scanline 1 if ( toY.u0 != u0 ) { if ( toY.u0 != u1 && toY.u0 != u2 && toY.u0 != u3 ) { u0 = toY.u0; if ( !_LoadScanlineLinear( row0, srcImage.width, pSrc + (rowPitch * u0), rowPitch, srcImage.format, filter ) ) return E_FAIL; } else if ( toY.u0 == u1 ) { u0 = u1; u1 = size_t(-1); std::swap( row0, row1 ); } else if ( toY.u0 == u2 ) { u0 = u2; u2 = size_t(-1); std::swap( row0, row2 ); } else if ( toY.u0 == u3 ) { u0 = u3; u3 = size_t(-1); std::swap( row0, row3 ); } } // Scanline 2 if ( toY.u1 != u1 ) { if ( toY.u1 != u2 && toY.u1 != u3 ) { u1 = toY.u1; if ( !_LoadScanlineLinear( row1, srcImage.width, pSrc + (rowPitch * u1), rowPitch, srcImage.format, filter ) ) return E_FAIL; } else if ( toY.u1 == u2 ) { u1 = u2; u2 = size_t(-1); std::swap( row1, row2 ); } else if ( toY.u1 == u3 ) { u1 = u3; u3 = size_t(-1); std::swap( row1, row3 ); } } // Scanline 3 if ( toY.u2 != u2 ) { if ( toY.u2 != u3 ) { u2 = toY.u2; if ( !_LoadScanlineLinear( row2, srcImage.width, pSrc + (rowPitch * u2), rowPitch, srcImage.format, filter ) ) return E_FAIL; } else { u2 = u3; u3 = size_t(-1); std::swap( row2, row3 ); } } // Scanline 4 if ( toY.u3 != u3 ) { u3 = toY.u3; if ( !_LoadScanlineLinear( row3, srcImage.width, pSrc + (rowPitch * u3), rowPitch, srcImage.format, filter ) ) return E_FAIL; } for( size_t x = 0; x < destImage.width; ++x ) { auto& toX = cfX[ x ]; XMVECTOR C0, C1, C2, C3; CUBIC_INTERPOLATE( C0, toX.x, row0[ toX.u0 ], row0[ toX.u1 ], row0[ toX.u2 ], row0[ toX.u3 ] ); CUBIC_INTERPOLATE( C1, toX.x, row1[ toX.u0 ], row1[ toX.u1 ], row1[ toX.u2 ], row1[ toX.u3 ] ); CUBIC_INTERPOLATE( C2, toX.x, row2[ toX.u0 ], row2[ toX.u1 ], row2[ toX.u2 ], row2[ toX.u3 ] ); CUBIC_INTERPOLATE( C3, toX.x, row3[ toX.u0 ], row3[ toX.u1 ], row3[ toX.u2 ], row3[ toX.u3 ] ); CUBIC_INTERPOLATE( target[x], toY.x, C0, C1, C2, C3 ); } if ( !_StoreScanlineLinear( pDest, destImage.rowPitch, destImage.format, target, destImage.width, filter ) ) return E_FAIL; pDest += destImage.rowPitch; } return S_OK; } //--- Triangle Filter --- static HRESULT _ResizeTriangleFilter( _In_ const Image& srcImage, _In_ DWORD filter, _In_ const Image& destImage ) { assert( srcImage.pixels && destImage.pixels ); assert( srcImage.format == destImage.format ); using namespace TriangleFilter; // Allocate initial temporary space (1 scanline, accumulation rows, plus X and Y filters) ScopedAlignedArrayXMVECTOR scanline( reinterpret_cast( _aligned_malloc( sizeof(XMVECTOR) * srcImage.width, 16 ) ) ); if ( !scanline ) return E_OUTOFMEMORY; std::unique_ptr rowActive( new (std::nothrow) TriangleRow[ destImage.height ] ); if ( !rowActive ) return E_OUTOFMEMORY; TriangleRow * rowFree = nullptr; std::unique_ptr tfX; HRESULT hr = _Create( srcImage.width, destImage.width, (filter & TEX_FILTER_WRAP_U) != 0, tfX ); if ( FAILED(hr) ) return hr; std::unique_ptr tfY; hr = _Create( srcImage.height, destImage.height, (filter & TEX_FILTER_WRAP_V) != 0, tfY ); if ( FAILED(hr) ) return hr; XMVECTOR* row = scanline.get(); #ifdef _DEBUG memset( row, 0xCD, sizeof(XMVECTOR)*srcImage.width ); #endif auto xFromEnd = reinterpret_cast( reinterpret_cast( tfX.get() ) + tfX->sizeInBytes ); auto yFromEnd = reinterpret_cast( reinterpret_cast( tfY.get() ) + tfY->sizeInBytes ); // Count times rows get written for( FilterFrom* yFrom = tfY->from; yFrom < yFromEnd; ) { for ( size_t j = 0; j < yFrom->count; ++j ) { size_t v = yFrom->to[ j ].u; assert( v < destImage.height ); ++rowActive[ v ].remaining; } yFrom = reinterpret_cast( reinterpret_cast( yFrom ) + yFrom->sizeInBytes ); } // Filter image const uint8_t* pSrc = srcImage.pixels; size_t rowPitch = srcImage.rowPitch; const uint8_t* pEndSrc = pSrc + rowPitch * srcImage.height; uint8_t* pDest = destImage.pixels; for( FilterFrom* yFrom = tfY->from; yFrom < yFromEnd; ) { // Create accumulation rows as needed for ( size_t j = 0; j < yFrom->count; ++j ) { size_t v = yFrom->to[ j ].u; assert( v < destImage.height ); TriangleRow* rowAcc = &rowActive[ v ]; if ( !rowAcc->scanline ) { if ( rowFree ) { // Steal and reuse scanline from 'free row' list assert( rowFree->scanline != 0 ); rowAcc->scanline.reset( rowFree->scanline.release() ); rowFree = rowFree->next; } else { rowAcc->scanline.reset( reinterpret_cast( _aligned_malloc( sizeof(XMVECTOR) * destImage.width, 16 ) ) ); if ( !rowAcc->scanline ) return E_OUTOFMEMORY; } memset( rowAcc->scanline.get(), 0, sizeof(XMVECTOR) * destImage.width ); } } // Load source scanline if ( (pSrc + rowPitch) > pEndSrc ) return E_FAIL; if ( !_LoadScanlineLinear( row, srcImage.width, pSrc, rowPitch, srcImage.format, filter ) ) return E_FAIL; pSrc += rowPitch; // Process row size_t x = 0; for( FilterFrom* xFrom = tfX->from; xFrom < xFromEnd; ++x ) { for ( size_t j = 0; j < yFrom->count; ++j ) { size_t v = yFrom->to[ j ].u; assert( v < destImage.height ); float yweight = yFrom->to[ j ].weight; XMVECTOR* accPtr = rowActive[ v ].scanline.get(); if ( !accPtr ) return E_POINTER; for ( size_t k = 0; k < xFrom->count; ++k ) { size_t u = xFrom->to[ k ].u; assert( u < destImage.width ); XMVECTOR weight = XMVectorReplicate( yweight * xFrom->to[ k ].weight ); assert( x < srcImage.width ); accPtr[ u ] = XMVectorMultiplyAdd( row[ x ], weight, accPtr[ u ] ); } } xFrom = reinterpret_cast( reinterpret_cast( xFrom ) + xFrom->sizeInBytes ); } // Write completed accumulation rows for ( size_t j = 0; j < yFrom->count; ++j ) { size_t v = yFrom->to[ j ].u; assert( v < destImage.height ); TriangleRow* rowAcc = &rowActive[ v ]; assert( rowAcc->remaining > 0 ); --rowAcc->remaining; if ( !rowAcc->remaining ) { XMVECTOR* pAccSrc = rowAcc->scanline.get(); if ( !pAccSrc ) return E_POINTER; switch( destImage.format ) { case DXGI_FORMAT_R10G10B10A2_UNORM: case DXGI_FORMAT_R10G10B10A2_UINT: { // Need to slightly bias results for floating-point error accumulation which can // be visible with harshly quantized values static const XMVECTORF32 Bias = { 0.f, 0.f, 0.f, 0.1f }; XMVECTOR* ptr = pAccSrc; for( size_t i=0; i < destImage.width; ++i, ++ptr ) { *ptr = XMVectorAdd( *ptr, Bias ); } } break; } // This performs any required clamping if ( !_StoreScanlineLinear( pDest + (destImage.rowPitch * v), destImage.rowPitch, destImage.format, pAccSrc, destImage.width, filter ) ) return E_FAIL; // Put row on freelist to reuse it's allocated scanline rowAcc->next = rowFree; rowFree = rowAcc; } } yFrom = reinterpret_cast( reinterpret_cast( yFrom ) + yFrom->sizeInBytes ); } return S_OK; } //--- Custom filter resize --- static HRESULT _PerformResizeUsingCustomFilters( _In_ const Image& srcImage, _In_ DWORD filter, _In_ const Image& destImage ) { if ( !srcImage.pixels || !destImage.pixels ) return E_POINTER; static_assert( TEX_FILTER_POINT == 0x100000, "TEX_FILTER_ flag values don't match TEX_FILTER_MASK" ); DWORD filter_select = ( filter & TEX_FILTER_MASK ); if ( !filter_select ) { // Default filter choice filter_select = ( ( (destImage.width << 1) == srcImage.width ) && ( (destImage.height << 1) == srcImage.height ) ) ? TEX_FILTER_BOX : TEX_FILTER_LINEAR; } switch( filter_select ) { case TEX_FILTER_POINT: return _ResizePointFilter( srcImage, destImage ); case TEX_FILTER_BOX: return _ResizeBoxFilter( srcImage, filter, destImage ); case TEX_FILTER_LINEAR: return _ResizeLinearFilter( srcImage, filter, destImage ); case TEX_FILTER_CUBIC: return _ResizeCubicFilter( srcImage, filter, destImage ); case TEX_FILTER_TRIANGLE: return _ResizeTriangleFilter( srcImage, filter, destImage ); default: return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); } } //===================================================================================== // Entry-points //===================================================================================== //------------------------------------------------------------------------------------- // Resize image //------------------------------------------------------------------------------------- _Use_decl_annotations_ HRESULT Resize( const Image& srcImage, size_t width, size_t height, DWORD filter, ScratchImage& image ) { if ( width == 0 || height == 0 ) return E_INVALIDARG; #ifdef _M_X64 if ( (srcImage.width > 0xFFFFFFFF) || (srcImage.height > 0xFFFFFFFF) ) return E_INVALIDARG; if ( (width > 0xFFFFFFFF) || (height > 0xFFFFFFFF) ) return E_INVALIDARG; #endif if ( !srcImage.pixels ) return E_POINTER; if ( IsCompressed( srcImage.format ) ) { // We don't support resizing compressed images return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); } HRESULT hr = image.Initialize2D( srcImage.format, width, height, 1, 1 ); if ( FAILED(hr) ) return hr; const Image *rimage = image.GetImage( 0, 0, 0 ); if ( !rimage ) return E_POINTER; if ( _UseWICFiltering( srcImage.format, filter ) ) { WICPixelFormatGUID pfGUID; if ( _DXGIToWIC( srcImage.format, pfGUID, true ) ) { // Case 1: Source format is supported by Windows Imaging Component hr = _PerformResizeUsingWIC( srcImage, filter, pfGUID, *rimage ); } else { // Case 2: Source format is not supported by WIC, so we have to convert, resize, and convert back hr = _PerformResizeViaF32( srcImage, filter, *rimage ); } } else { hr = _PerformResizeUsingCustomFilters( srcImage, filter, *rimage ); } if ( FAILED(hr) ) { image.Release(); return hr; } return S_OK; } //------------------------------------------------------------------------------------- // Resize image (complex) //------------------------------------------------------------------------------------- _Use_decl_annotations_ HRESULT Resize( const Image* srcImages, size_t nimages, const TexMetadata& metadata, size_t width, size_t height, DWORD filter, ScratchImage& result ) { if ( !srcImages || !nimages || width == 0 || height == 0 ) return E_INVALIDARG; #ifdef _M_X64 if ( (width > 0xFFFFFFFF) || (height > 0xFFFFFFFF) ) return E_INVALIDARG; #endif TexMetadata mdata2 = metadata; mdata2.width = width; mdata2.height = height; mdata2.mipLevels = 1; HRESULT hr = result.Initialize( mdata2 ); if ( FAILED(hr) ) return hr; bool usewic = _UseWICFiltering( metadata.format, filter ); WICPixelFormatGUID pfGUID = {0}; bool wicpf = ( usewic ) ? _DXGIToWIC( metadata.format, pfGUID, true ) : false; switch ( metadata.dimension ) { case TEX_DIMENSION_TEXTURE1D: case TEX_DIMENSION_TEXTURE2D: assert( metadata.depth == 1 ); for( size_t item = 0; item < metadata.arraySize; ++item ) { size_t srcIndex = metadata.ComputeIndex( 0, item, 0 ); if ( srcIndex >= nimages ) { result.Release(); return E_FAIL; } const Image* srcimg = &srcImages[ srcIndex ]; const Image* destimg = result.GetImage( 0, item, 0 ); if ( !srcimg || !destimg ) { result.Release(); return E_POINTER; } if ( srcimg->format != metadata.format ) { result.Release(); return E_FAIL; } #ifdef _M_X64 if ( (srcimg->width > 0xFFFFFFFF) || (srcimg->height > 0xFFFFFFFF) ) { result.Release(); return E_FAIL; } #endif if ( usewic ) { if ( wicpf ) { // Case 1: Source format is supported by Windows Imaging Component hr = _PerformResizeUsingWIC( *srcimg, filter, pfGUID, *destimg ); } else { // Case 2: Source format is not supported by WIC, so we have to convert, resize, and convert back hr = _PerformResizeViaF32( *srcimg, filter, *destimg ); } } else { // Case 3: not using WIC resizing hr = _PerformResizeUsingCustomFilters( *srcimg, filter, *destimg ); } if ( FAILED(hr) ) { result.Release(); return hr; } } break; case TEX_DIMENSION_TEXTURE3D: assert( metadata.arraySize == 1 ); for( size_t slice = 0; slice < metadata.depth; ++slice ) { size_t srcIndex = metadata.ComputeIndex( 0, 0, slice ); if ( srcIndex >= nimages ) { result.Release(); return E_FAIL; } const Image* srcimg = &srcImages[ srcIndex ]; const Image* destimg = result.GetImage( 0, 0, slice ); if ( !srcimg || !destimg ) { result.Release(); return E_POINTER; } if ( srcimg->format != metadata.format ) { result.Release(); return E_FAIL; } #ifdef _M_X64 if ( (srcimg->width > 0xFFFFFFFF) || (srcimg->height > 0xFFFFFFFF) ) { result.Release(); return E_FAIL; } #endif if ( usewic ) { if ( wicpf ) { // Case 1: Source format is supported by Windows Imaging Component hr = _PerformResizeUsingWIC( *srcimg, filter, pfGUID, *destimg ); } else { // Case 2: Source format is not supported by WIC, so we have to convert, resize, and convert back hr = _PerformResizeViaF32( *srcimg, filter, *destimg ); } } else { // Case 3: not using WIC resizing hr = _PerformResizeUsingCustomFilters( *srcimg, filter, *destimg ); } if ( FAILED(hr) ) { result.Release(); return hr; } } break; default: result.Release(); return E_FAIL; } return S_OK; } }; // namespace ================================================ FILE: 3rdParty/DirectXTex/DirectXTex/DirectXTexTGA.cpp ================================================ //------------------------------------------------------------------------------------- // DirectXTexTGA.cpp // // DirectX Texture Library - Targa Truevision (TGA) file format reader/writer // // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A // PARTICULAR PURPOSE. // // Copyright (c) Microsoft Corporation. All rights reserved. // // http://go.microsoft.com/fwlink/?LinkId=248926 //------------------------------------------------------------------------------------- #include "directxtexp.h" // // The implementation here has the following limitations: // * Does not support files that contain color maps (these are rare in practice) // * Interleaved files are not supported (deprecated aspect of TGA format) // * Only supports 8-bit grayscale; 16-, 24-, and 32-bit truecolor images // * Always writes uncompressed files (i.e. can read RLE compression, but does not write it) // enum TGAImageType { TGA_NO_IMAGE = 0, TGA_COLOR_MAPPED = 1, TGA_TRUECOLOR = 2, TGA_BLACK_AND_WHITE = 3, TGA_COLOR_MAPPED_RLE = 9, TGA_TRUECOLOR_RLE = 10, TGA_BLACK_AND_WHITE_RLE = 11, }; enum TGADescriptorFlags { TGA_FLAGS_INVERTX = 0x10, TGA_FLAGS_INVERTY = 0x20, TGA_FLAGS_INTERLEAVED_2WAY = 0x40, // Deprecated TGA_FLAGS_INTERLEAVED_4WAY = 0x80, // Deprecated }; const char* g_TGA20_Signature = "TRUEVISION-XFILE."; #pragma pack(push,1) struct TGA_HEADER { uint8_t bIDLength; uint8_t bColorMapType; uint8_t bImageType; uint16_t wColorMapFirst; uint16_t wColorMapLength; uint8_t bColorMapSize; uint16_t wXOrigin; uint16_t wYOrigin; uint16_t wWidth; uint16_t wHeight; uint8_t bBitsPerPixel; uint8_t bDescriptor; }; struct TGA_FOOTER { uint16_t dwExtensionOffset; uint16_t dwDeveloperOffset; char Signature[18]; }; struct TGA_EXTENSION { uint16_t wSize; char szAuthorName[41]; char szAuthorComment[324]; uint16_t wStampMonth; uint16_t wStampDay; uint16_t wStampYear; uint16_t wStampHour; uint16_t wStampMinute; uint16_t wStampSecond; char szJobName[41]; uint16_t wJobHour; uint16_t wJobMinute; uint16_t wJobSecond; char szSoftwareId[41]; uint16_t wVersionNumber; uint8_t bVersionLetter; uint32_t dwKeyColor; uint16_t wPixelNumerator; uint16_t wPixelDenominator; uint16_t wGammaNumerator; uint16_t wGammaDenominator; uint32_t dwColorOffset; uint32_t dwStampOffset; uint32_t dwScanOffset; uint8_t bAttributesType; }; #pragma pack(pop) enum CONVERSION_FLAGS { CONV_FLAGS_NONE = 0x0, CONV_FLAGS_EXPAND = 0x1, // Conversion requires expanded pixel size CONV_FLAGS_INVERTX = 0x2, // If set, scanlines are right-to-left CONV_FLAGS_INVERTY = 0x4, // If set, scanlines are top-to-bottom CONV_FLAGS_RLE = 0x8, // Source data is RLE compressed CONV_FLAGS_SWIZZLE = 0x10000, // Swizzle BGR<->RGB data CONV_FLAGS_888 = 0x20000, // 24bpp format }; namespace DirectX { //------------------------------------------------------------------------------------- // Decodes TGA header //------------------------------------------------------------------------------------- static HRESULT _DecodeTGAHeader( _In_reads_bytes_(size) LPCVOID pSource, size_t size, _Out_ TexMetadata& metadata, size_t& offset, _Inout_opt_ DWORD* convFlags ) { if ( !pSource ) return E_INVALIDARG; memset( &metadata, 0, sizeof(TexMetadata) ); if ( size < sizeof(TGA_HEADER) ) { return HRESULT_FROM_WIN32( ERROR_INVALID_DATA ); } auto pHeader = reinterpret_cast( pSource ); if ( pHeader->bColorMapType != 0 || pHeader->wColorMapLength != 0 ) { return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); } if ( pHeader->bDescriptor & (TGA_FLAGS_INTERLEAVED_2WAY|TGA_FLAGS_INTERLEAVED_4WAY) ) { return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); } if ( !pHeader->wWidth || !pHeader->wHeight ) { return HRESULT_FROM_WIN32( ERROR_INVALID_DATA ); } switch ( pHeader->bImageType ) { case TGA_TRUECOLOR: case TGA_TRUECOLOR_RLE: switch( pHeader->bBitsPerPixel ) { case 16: metadata.format = DXGI_FORMAT_B5G5R5A1_UNORM; break; case 24: metadata.format = DXGI_FORMAT_R8G8B8A8_UNORM; if ( convFlags ) *convFlags |= CONV_FLAGS_EXPAND; // We could use DXGI_FORMAT_B8G8R8X8_UNORM, but we prefer DXGI 1.0 formats break; case 32: metadata.format = DXGI_FORMAT_R8G8B8A8_UNORM; // We could use DXGI_FORMAT_B8G8R8A8_UNORM, but we prefer DXGI 1.0 formats break; } if ( convFlags && (pHeader->bImageType == TGA_TRUECOLOR_RLE) ) { *convFlags |= CONV_FLAGS_RLE; } break; case TGA_BLACK_AND_WHITE: case TGA_BLACK_AND_WHITE_RLE: switch( pHeader->bBitsPerPixel ) { case 8: metadata.format = DXGI_FORMAT_R8_UNORM; break; default: return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); } if ( convFlags && (pHeader->bImageType == TGA_BLACK_AND_WHITE_RLE) ) { *convFlags |= CONV_FLAGS_RLE; } break; case TGA_NO_IMAGE: case TGA_COLOR_MAPPED: case TGA_COLOR_MAPPED_RLE: return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); default: return HRESULT_FROM_WIN32( ERROR_INVALID_DATA ); } metadata.width = pHeader->wWidth; metadata.height = pHeader->wHeight; metadata.depth = metadata.arraySize = metadata.mipLevels = 1; metadata.dimension = TEX_DIMENSION_TEXTURE2D; if ( convFlags ) { if ( pHeader->bDescriptor & TGA_FLAGS_INVERTX ) *convFlags |= CONV_FLAGS_INVERTX; if ( pHeader->bDescriptor & TGA_FLAGS_INVERTY ) *convFlags |= CONV_FLAGS_INVERTY; } offset = sizeof( TGA_HEADER ); if ( pHeader->bIDLength != 0 ) { offset += pHeader->bIDLength; } return S_OK; } //------------------------------------------------------------------------------------- // Set alpha for images with all 0 alpha channel //------------------------------------------------------------------------------------- static HRESULT _SetAlphaChannelToOpaque( _In_ const Image* image ) { assert( image ); auto pPixels = reinterpret_cast( image->pixels ); if ( !pPixels ) return E_POINTER; for( size_t y = 0; y < image->height; ++y ) { _CopyScanline( pPixels, image->rowPitch, pPixels, image->rowPitch, image->format, TEXP_SCANLINE_SETALPHA ); pPixels += image->rowPitch; } return S_OK; } //------------------------------------------------------------------------------------- // Uncompress pixel data from a TGA into the target image //------------------------------------------------------------------------------------- static HRESULT _UncompressPixels( _In_reads_bytes_(size) LPCVOID pSource, size_t size, _In_ const Image* image, _In_ DWORD convFlags ) { assert( pSource && size > 0 ); if ( !image || !image->pixels ) return E_POINTER; // Compute TGA image data pitch size_t rowPitch; if ( convFlags & CONV_FLAGS_EXPAND ) { rowPitch = image->width * 3; } else { size_t slicePitch; ComputePitch( image->format, image->width, image->height, rowPitch, slicePitch, CP_FLAGS_NONE ); } auto sPtr = reinterpret_cast( pSource ); const uint8_t* endPtr = sPtr + size; switch( image->format ) { //--------------------------------------------------------------------------- 8-bit case DXGI_FORMAT_R8_UNORM: for( size_t y=0; y < image->height; ++y ) { size_t offset = ( (convFlags & CONV_FLAGS_INVERTX ) ? (image->width - 1) : 0 ); assert( offset < rowPitch); uint8_t* dPtr = reinterpret_cast( image->pixels ) + ( image->rowPitch * ( (convFlags & CONV_FLAGS_INVERTY) ? y : (image->height - y - 1) ) ) + offset; for( size_t x=0; x < image->width; ) { if ( sPtr >= endPtr ) return E_FAIL; if ( *sPtr & 0x80 ) { // Repeat size_t j = (*sPtr & 0x7F) + 1; if ( ++sPtr >= endPtr ) return E_FAIL; for( ; j > 0; --j, ++x ) { if ( x >= image->width ) return E_FAIL; *dPtr = *sPtr; if ( convFlags & CONV_FLAGS_INVERTX ) --dPtr; else ++dPtr; } ++sPtr; } else { // Literal size_t j = (*sPtr & 0x7F) + 1; ++sPtr; if ( sPtr+j > endPtr ) return E_FAIL; for( ; j > 0; --j, ++x ) { if ( x >= image->width ) return E_FAIL; *dPtr = *(sPtr++); if ( convFlags & CONV_FLAGS_INVERTX ) --dPtr; else ++dPtr; } } } } break; //-------------------------------------------------------------------------- 16-bit case DXGI_FORMAT_B5G5R5A1_UNORM: { bool nonzeroa = false; for( size_t y=0; y < image->height; ++y ) { size_t offset = ( (convFlags & CONV_FLAGS_INVERTX ) ? (image->width - 1) : 0 ); assert( offset*2 < rowPitch); uint16_t* dPtr = reinterpret_cast( reinterpret_cast( image->pixels ) + ( image->rowPitch * ( (convFlags & CONV_FLAGS_INVERTY) ? y : (image->height - y - 1) ) ) ) + offset; for( size_t x=0; x < image->width; ) { if ( sPtr >= endPtr ) return E_FAIL; if ( *sPtr & 0x80 ) { // Repeat size_t j = (*sPtr & 0x7F) + 1; ++sPtr; if ( sPtr+1 >= endPtr ) return E_FAIL; uint16_t t = *sPtr | (*(sPtr+1) << 8); if ( t & 0x8000 ) nonzeroa = true; sPtr += 2; for( ; j > 0; --j, ++x ) { if ( x >= image->width ) return E_FAIL; *dPtr = t; if ( convFlags & CONV_FLAGS_INVERTX ) --dPtr; else ++dPtr; } } else { // Literal size_t j = (*sPtr & 0x7F) + 1; ++sPtr; if ( sPtr+(j*2) > endPtr ) return E_FAIL; for( ; j > 0; --j, ++x ) { if ( x >= image->width ) return E_FAIL; uint16_t t = *sPtr | (*(sPtr+1) << 8); if ( t & 0x8000 ) nonzeroa = true; sPtr += 2; *dPtr = t; if ( convFlags & CONV_FLAGS_INVERTX ) --dPtr; else ++dPtr; } } } } // If there are no non-zero alpha channel entries, we'll assume alpha is not used and force it to opaque if ( !nonzeroa ) { HRESULT hr = _SetAlphaChannelToOpaque( image ); if ( FAILED(hr) ) return hr; } } break; //----------------------------------------------------------------------- 24/32-bit case DXGI_FORMAT_R8G8B8A8_UNORM: { bool nonzeroa = false; for( size_t y=0; y < image->height; ++y ) { size_t offset = ( (convFlags & CONV_FLAGS_INVERTX ) ? (image->width - 1) : 0 ); uint32_t* dPtr = reinterpret_cast( reinterpret_cast( image->pixels ) + ( image->rowPitch * ( (convFlags & CONV_FLAGS_INVERTY) ? y : (image->height - y - 1) ) ) ) + offset; for( size_t x=0; x < image->width; ) { if ( sPtr >= endPtr ) return E_FAIL; if ( *sPtr & 0x80 ) { // Repeat size_t j = (*sPtr & 0x7F) + 1; ++sPtr; DWORD t; if ( convFlags & CONV_FLAGS_EXPAND ) { assert( offset*3 < rowPitch); if ( sPtr+2 >= endPtr ) return E_FAIL; // BGR -> RGBA t = ( *sPtr << 16 ) | ( *(sPtr+1) << 8 ) | ( *(sPtr+2) ) | 0xFF000000; sPtr += 3; nonzeroa = true; } else { assert( offset*4 < rowPitch); if ( sPtr+3 >= endPtr ) return E_FAIL; // BGRA -> RGBA t = ( *sPtr << 16 ) | ( *(sPtr+1) << 8 ) | ( *(sPtr+2) ) | ( *(sPtr+3) << 24 ); if ( *(sPtr+3) > 0 ) nonzeroa = true; sPtr += 4; } for( ; j > 0; --j, ++x ) { if ( x >= image->width ) return E_FAIL; *dPtr = t; if ( convFlags & CONV_FLAGS_INVERTX ) --dPtr; else ++dPtr; } } else { // Literal size_t j = (*sPtr & 0x7F) + 1; ++sPtr; if ( convFlags & CONV_FLAGS_EXPAND ) { if ( sPtr+(j*3) > endPtr ) return E_FAIL; } else { if ( sPtr+(j*4) > endPtr ) return E_FAIL; } for( ; j > 0; --j, ++x ) { if ( x >= image->width ) return E_FAIL; if ( convFlags & CONV_FLAGS_EXPAND ) { assert( offset*3 < rowPitch); if ( sPtr+2 >= endPtr ) return E_FAIL; // BGR -> RGBA *dPtr = ( *sPtr << 16 ) | ( *(sPtr+1) << 8 ) | ( *(sPtr+2) ) | 0xFF000000; sPtr += 3; nonzeroa = true; } else { assert( offset*4 < rowPitch); if ( sPtr+3 >= endPtr ) return E_FAIL; // BGRA -> RGBA *dPtr = ( *sPtr << 16 ) | ( *(sPtr+1) << 8 ) | ( *(sPtr+2) ) | ( *(sPtr+3) << 24 ); if ( *(sPtr+3) > 0 ) nonzeroa = true; sPtr += 4; } if ( convFlags & CONV_FLAGS_INVERTX ) --dPtr; else ++dPtr; } } } } // If there are no non-zero alpha channel entries, we'll assume alpha is not used and force it to opaque if ( !nonzeroa ) { HRESULT hr = _SetAlphaChannelToOpaque( image ); if ( FAILED(hr) ) return hr; } } break; //--------------------------------------------------------------------------------- default: return E_FAIL; } return S_OK; } //------------------------------------------------------------------------------------- // Copies pixel data from a TGA into the target image //------------------------------------------------------------------------------------- static HRESULT _CopyPixels( _In_reads_bytes_(size) LPCVOID pSource, size_t size, _In_ const Image* image, _In_ DWORD convFlags ) { assert( pSource && size > 0 ); if ( !image || !image->pixels ) return E_POINTER; // Compute TGA image data pitch size_t rowPitch; if ( convFlags & CONV_FLAGS_EXPAND ) { rowPitch = image->width * 3; } else { size_t slicePitch; ComputePitch( image->format, image->width, image->height, rowPitch, slicePitch, CP_FLAGS_NONE ); } const uint8_t* sPtr = reinterpret_cast( pSource ); const uint8_t* endPtr = sPtr + size; switch( image->format ) { //--------------------------------------------------------------------------- 8-bit case DXGI_FORMAT_R8_UNORM: for( size_t y=0; y < image->height; ++y ) { size_t offset = ( (convFlags & CONV_FLAGS_INVERTX ) ? (image->width - 1) : 0 ); assert( offset < rowPitch); uint8_t* dPtr = reinterpret_cast( image->pixels ) + ( image->rowPitch * ( (convFlags & CONV_FLAGS_INVERTY) ? y : (image->height - y - 1) ) ) + offset; for( size_t x=0; x < image->width; ++x ) { if ( sPtr >= endPtr ) return E_FAIL; *dPtr = *(sPtr++); if ( convFlags & CONV_FLAGS_INVERTX ) --dPtr; else ++dPtr; } } break; //-------------------------------------------------------------------------- 16-bit case DXGI_FORMAT_B5G5R5A1_UNORM: { bool nonzeroa = false; for( size_t y=0; y < image->height; ++y ) { size_t offset = ( (convFlags & CONV_FLAGS_INVERTX ) ? (image->width - 1) : 0 ); assert( offset*2 < rowPitch); uint16_t* dPtr = reinterpret_cast( reinterpret_cast( image->pixels ) + ( image->rowPitch * ( (convFlags & CONV_FLAGS_INVERTY) ? y : (image->height - y - 1) ) ) ) + offset; for( size_t x=0; x < image->width; ++x ) { if ( sPtr+1 >= endPtr ) return E_FAIL; uint16_t t = *sPtr | (*(sPtr+1) << 8); sPtr += 2; *dPtr = t; if ( t & 0x8000 ) nonzeroa = true; if ( convFlags & CONV_FLAGS_INVERTX ) --dPtr; else ++dPtr; } } // If there are no non-zero alpha channel entries, we'll assume alpha is not used and force it to opaque if ( !nonzeroa ) { HRESULT hr = _SetAlphaChannelToOpaque( image ); if ( FAILED(hr) ) return hr; } } break; //----------------------------------------------------------------------- 24/32-bit case DXGI_FORMAT_R8G8B8A8_UNORM: { bool nonzeroa = false; for( size_t y=0; y < image->height; ++y ) { size_t offset = ( (convFlags & CONV_FLAGS_INVERTX ) ? (image->width - 1) : 0 ); uint32_t* dPtr = reinterpret_cast( reinterpret_cast( image->pixels ) + ( image->rowPitch * ( (convFlags & CONV_FLAGS_INVERTY) ? y : (image->height - y - 1) ) ) ) + offset; for( size_t x=0; x < image->width; ++x ) { if ( convFlags & CONV_FLAGS_EXPAND ) { assert( offset*3 < rowPitch); if ( sPtr+2 >= endPtr ) return E_FAIL; // BGR -> RGBA *dPtr = ( *sPtr << 16 ) | ( *(sPtr+1) << 8 ) | ( *(sPtr+2) ) | 0xFF000000; sPtr += 3; nonzeroa = true; } else { assert( offset*4 < rowPitch); if ( sPtr+3 >= endPtr ) return E_FAIL; // BGRA -> RGBA *dPtr = ( *sPtr << 16 ) | ( *(sPtr+1) << 8 ) | ( *(sPtr+2) ) | ( *(sPtr+3) << 24 ); if ( *(sPtr+3) > 0 ) nonzeroa = true; sPtr += 4; } if ( convFlags & CONV_FLAGS_INVERTX ) --dPtr; else ++dPtr; } } // If there are no non-zero alpha channel entries, we'll assume alpha is not used and force it to opaque if ( !nonzeroa ) { HRESULT hr = _SetAlphaChannelToOpaque( image ); if ( FAILED(hr) ) return hr; } } break; //--------------------------------------------------------------------------------- default: return E_FAIL; } return S_OK; } //------------------------------------------------------------------------------------- // Encodes TGA file header //------------------------------------------------------------------------------------- static HRESULT _EncodeTGAHeader( _In_ const Image& image, _Out_ TGA_HEADER& header, _Inout_ DWORD& convFlags ) { memset( &header, 0, sizeof(TGA_HEADER) ); if ( (image.width > 0xFFFF) || (image.height > 0xFFFF) ) { return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); } header.wWidth = static_cast( image.width ); header.wHeight = static_cast( image.height ); switch( image.format ) { case DXGI_FORMAT_R8G8B8A8_UNORM: case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: header.bImageType = TGA_TRUECOLOR; header.bBitsPerPixel = 32; header.bDescriptor = TGA_FLAGS_INVERTY | 8; convFlags |= CONV_FLAGS_SWIZZLE; break; case DXGI_FORMAT_B8G8R8A8_UNORM: case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: header.bImageType = TGA_TRUECOLOR; header.bBitsPerPixel = 32; header.bDescriptor = TGA_FLAGS_INVERTY | 8; break; case DXGI_FORMAT_B8G8R8X8_UNORM: case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: header.bImageType = TGA_TRUECOLOR; header.bBitsPerPixel = 24; header.bDescriptor = TGA_FLAGS_INVERTY; convFlags |= CONV_FLAGS_888; break; case DXGI_FORMAT_R8_UNORM: case DXGI_FORMAT_A8_UNORM: header.bImageType = TGA_BLACK_AND_WHITE; header.bBitsPerPixel = 8; header.bDescriptor = TGA_FLAGS_INVERTY; break; case DXGI_FORMAT_B5G5R5A1_UNORM: header.bImageType = TGA_TRUECOLOR; header.bBitsPerPixel = 16; header.bDescriptor = TGA_FLAGS_INVERTY | 1; break; default: return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); } return S_OK; } //------------------------------------------------------------------------------------- // Copies BGRX data to form BGR 24bpp data //------------------------------------------------------------------------------------- #pragma warning(suppress: 6001 6101) // In the case where outSize is insufficient we do not write to pDestination static void _Copy24bppScanline( _Out_writes_bytes_(outSize) LPVOID pDestination, _In_ size_t outSize, _In_reads_bytes_(inSize) LPCVOID pSource, _In_ size_t inSize ) { assert( pDestination && outSize > 0 ); assert( pSource && inSize > 0 ); assert( pDestination != pSource ); const uint32_t * __restrict sPtr = reinterpret_cast(pSource); uint8_t * __restrict dPtr = reinterpret_cast(pDestination); if ( inSize >= 4 && outSize >= 3 ) { const uint8_t* endPtr = dPtr + outSize; for( size_t count = 0; count < ( inSize - 3 ); count += 4 ) { uint32_t t = *(sPtr++); if ( dPtr+3 > endPtr ) return; *(dPtr++) = uint8_t(t & 0xFF); // Blue *(dPtr++) = uint8_t((t & 0xFF00) >> 8); // Green *(dPtr++) = uint8_t((t & 0xFF0000) >> 16); // Red } } } //===================================================================================== // Entry-points //===================================================================================== //------------------------------------------------------------------------------------- // Obtain metadata from TGA file in memory/on disk //------------------------------------------------------------------------------------- _Use_decl_annotations_ HRESULT GetMetadataFromTGAMemory( LPCVOID pSource, size_t size, TexMetadata& metadata ) { if ( !pSource || size == 0 ) return E_INVALIDARG; size_t offset; return _DecodeTGAHeader( pSource, size, metadata, offset, 0 ); } _Use_decl_annotations_ HRESULT GetMetadataFromTGAFile( LPCWSTR szFile, TexMetadata& metadata ) { if ( !szFile ) return E_INVALIDARG; #if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) ScopedHandle hFile( safe_handle( CreateFile2( szFile, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, 0 ) ) ); #else ScopedHandle hFile( safe_handle( CreateFileW( szFile, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, 0 ) ) ); #endif if ( !hFile ) { return HRESULT_FROM_WIN32( GetLastError() ); } // Get the file size LARGE_INTEGER fileSize = {0}; #if (_WIN32_WINNT >= _WIN32_WINNT_VISTA) FILE_STANDARD_INFO fileInfo; if ( !GetFileInformationByHandleEx( hFile.get(), FileStandardInfo, &fileInfo, sizeof(fileInfo) ) ) { return HRESULT_FROM_WIN32( GetLastError() ); } fileSize = fileInfo.EndOfFile; #else if ( !GetFileSizeEx( hFile.get(), &fileSize ) ) { return HRESULT_FROM_WIN32( GetLastError() ); } #endif // File is too big for 32-bit allocation, so reject read (4 GB should be plenty large enough for a valid TGA file) if ( fileSize.HighPart > 0 ) { return HRESULT_FROM_WIN32( ERROR_FILE_TOO_LARGE ); } // Need at least enough data to fill the standard header to be a valid TGA if ( fileSize.LowPart < ( sizeof(TGA_HEADER) ) ) { return E_FAIL; } // Read the standard header (we don't need the file footer to parse the file) uint8_t header[sizeof(TGA_HEADER)]; DWORD bytesRead = 0; if ( !ReadFile( hFile.get(), header, sizeof(TGA_HEADER), &bytesRead, 0 ) ) { return HRESULT_FROM_WIN32( GetLastError() ); } size_t offset; return _DecodeTGAHeader( header, bytesRead, metadata, offset, 0 ); } //------------------------------------------------------------------------------------- // Load a TGA file in memory //------------------------------------------------------------------------------------- _Use_decl_annotations_ HRESULT LoadFromTGAMemory( LPCVOID pSource, size_t size, TexMetadata* metadata, ScratchImage& image ) { if ( !pSource || size == 0 ) return E_INVALIDARG; image.Release(); size_t offset; DWORD convFlags = 0; TexMetadata mdata; HRESULT hr = _DecodeTGAHeader( pSource, size, mdata, offset, &convFlags ); if ( FAILED(hr) ) return hr; if ( offset > size ) return E_FAIL; auto pPixels = reinterpret_cast( reinterpret_cast(pSource) + offset ); size_t remaining = size - offset; if ( remaining == 0 ) return E_FAIL; hr = image.Initialize2D( mdata.format, mdata.width, mdata.height, 1, 1 ); if ( FAILED(hr) ) return hr; if ( convFlags & CONV_FLAGS_RLE ) { hr = _UncompressPixels( pPixels, remaining, image.GetImage(0,0,0), convFlags ); } else { hr = _CopyPixels( pPixels, remaining, image.GetImage(0,0,0), convFlags ); } if ( FAILED(hr) ) { image.Release(); return hr; } if ( metadata ) memcpy( metadata, &mdata, sizeof(TexMetadata) ); return S_OK; } //------------------------------------------------------------------------------------- // Load a TGA file from disk //------------------------------------------------------------------------------------- _Use_decl_annotations_ HRESULT LoadFromTGAFile( LPCWSTR szFile, TexMetadata* metadata, ScratchImage& image ) { if ( !szFile ) return E_INVALIDARG; image.Release(); #if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) ScopedHandle hFile( safe_handle( CreateFile2( szFile, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, 0 ) ) ); #else ScopedHandle hFile( safe_handle( CreateFileW( szFile, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, 0 ) ) ); #endif if ( !hFile ) { return HRESULT_FROM_WIN32( GetLastError() ); } // Get the file size LARGE_INTEGER fileSize = {0}; #if (_WIN32_WINNT >= _WIN32_WINNT_VISTA) FILE_STANDARD_INFO fileInfo; if ( !GetFileInformationByHandleEx( hFile.get(), FileStandardInfo, &fileInfo, sizeof(fileInfo) ) ) { return HRESULT_FROM_WIN32( GetLastError() ); } fileSize = fileInfo.EndOfFile; #else if ( !GetFileSizeEx( hFile.get(), &fileSize ) ) { return HRESULT_FROM_WIN32( GetLastError() ); } #endif // File is too big for 32-bit allocation, so reject read (4 GB should be plenty large enough for a valid TGA file) if ( fileSize.HighPart > 0 ) { return HRESULT_FROM_WIN32( ERROR_FILE_TOO_LARGE ); } // Need at least enough data to fill the header to be a valid TGA if ( fileSize.LowPart < sizeof(TGA_HEADER) ) { return E_FAIL; } // Read the header uint8_t header[sizeof(TGA_HEADER)]; DWORD bytesRead = 0; if ( !ReadFile( hFile.get(), header, sizeof(TGA_HEADER), &bytesRead, 0 ) ) { return HRESULT_FROM_WIN32( GetLastError() ); } size_t offset; DWORD convFlags = 0; TexMetadata mdata; HRESULT hr = _DecodeTGAHeader( header, bytesRead, mdata, offset, &convFlags ); if ( FAILED(hr) ) return hr; // Read the pixels DWORD remaining = static_cast( fileSize.LowPart - offset ); if ( remaining == 0 ) return E_FAIL; if ( offset > sizeof(TGA_HEADER) ) { // Skip past the id string LARGE_INTEGER filePos = { static_cast(offset), 0 }; if ( !SetFilePointerEx( hFile.get(), filePos, 0, FILE_BEGIN ) ) { return HRESULT_FROM_WIN32( GetLastError() ); } } hr = image.Initialize2D( mdata.format, mdata.width, mdata.height, 1, 1 ); if ( FAILED(hr) ) return hr; assert( image.GetPixels() ); if ( !(convFlags & (CONV_FLAGS_RLE | CONV_FLAGS_EXPAND | CONV_FLAGS_INVERTX)) && (convFlags & CONV_FLAGS_INVERTY) ) { // This case we can read directly into the image buffer in place if ( !ReadFile( hFile.get(), image.GetPixels(), static_cast( image.GetPixelsSize() ), &bytesRead, 0 ) ) { image.Release(); return HRESULT_FROM_WIN32( GetLastError() ); } if ( bytesRead != image.GetPixelsSize() ) { image.Release(); return E_FAIL; } switch( mdata.format ) { case DXGI_FORMAT_R8G8B8A8_UNORM: { // TGA stores 32-bit data in BGRA form, need to swizzle to RGBA assert( image.GetImageCount() == 1 ); const Image* img = image.GetImage(0,0,0); if ( !img ) return E_POINTER; uint8_t *pPixels = img->pixels; if ( !pPixels ) return E_POINTER; size_t rowPitch = img->rowPitch; // Scan for non-zero alpha channel bool nonzeroa = false; for( size_t h = 0; h < img->height; ++h ) { const uint32_t* sPtr = reinterpret_cast( pPixels ); for( size_t x=0; x < img->width; ++x ) { if ( (*sPtr) & 0xff000000 ) { nonzeroa = true; break; } ++sPtr; } if ( nonzeroa ) break; pPixels += rowPitch; } DWORD tflags = ( !nonzeroa ) ? TEXP_SCANLINE_SETALPHA : TEXP_SCANLINE_NONE; // Swizzle scanlines pPixels = img->pixels; for( size_t h = 0; h < img->height; ++h ) { _SwizzleScanline( pPixels, rowPitch, pPixels, rowPitch, mdata.format, tflags ); pPixels += rowPitch; } } break; // If we start using DXGI_FORMAT_B8G8R8X8_UNORM or DXGI_FORMAT_B8G8R8A8_UNORM we need to check for a fully 0 alpha channel case DXGI_FORMAT_B5G5R5A1_UNORM: { assert( image.GetImageCount() == 1 ); const Image* img = image.GetImage(0,0,0); if ( !img ) return E_POINTER; // Scan for non-zero alpha channel bool nonzeroa = false; const uint8_t *pPixels = img->pixels; if ( !pPixels ) return E_POINTER; size_t rowPitch = img->rowPitch; for( size_t h = 0; h < img->height; ++h ) { const uint16_t* sPtr = reinterpret_cast( pPixels ); for( size_t x=0; x < img->width; ++x ) { if ( *sPtr & 0x8000 ) { nonzeroa = true; break; } ++sPtr; } if ( nonzeroa ) break; pPixels += rowPitch; } // If there are no non-zero alpha channel entries, we'll assume alpha is not used and force it to opaque if ( !nonzeroa ) { hr = _SetAlphaChannelToOpaque( img ); if ( FAILED(hr) ) return hr; } } break; } } else // RLE || EXPAND || INVERTX || !INVERTY { std::unique_ptr temp( new (std::nothrow) uint8_t[ remaining ] ); if ( !temp ) { image.Release(); return E_OUTOFMEMORY; } if ( !ReadFile( hFile.get(), temp.get(), remaining, &bytesRead, 0 ) ) { image.Release(); return HRESULT_FROM_WIN32( GetLastError() ); } if ( bytesRead != remaining ) { image.Release(); return E_FAIL; } if ( convFlags & CONV_FLAGS_RLE ) { hr = _UncompressPixels( temp.get(), remaining, image.GetImage(0,0,0), convFlags ); } else { hr = _CopyPixels( temp.get(), remaining, image.GetImage(0,0,0), convFlags ); } if ( FAILED(hr) ) { image.Release(); return hr; } } if ( metadata ) memcpy( metadata, &mdata, sizeof(TexMetadata) ); return S_OK; } //------------------------------------------------------------------------------------- // Save a TGA file to memory //------------------------------------------------------------------------------------- _Use_decl_annotations_ HRESULT SaveToTGAMemory( const Image& image, Blob& blob ) { if ( !image.pixels ) return E_POINTER; TGA_HEADER tga_header; DWORD convFlags = 0; HRESULT hr = _EncodeTGAHeader( image, tga_header, convFlags ); if ( FAILED(hr) ) return hr; blob.Release(); // Determine memory required for image data size_t rowPitch, slicePitch; if ( convFlags & CONV_FLAGS_888 ) { rowPitch = image.width * 3; slicePitch = image.height * rowPitch; } else { ComputePitch( image.format, image.width, image.height, rowPitch, slicePitch, CP_FLAGS_NONE ); } hr = blob.Initialize( sizeof(TGA_HEADER) + slicePitch ); if ( FAILED(hr) ) return hr; // Copy header auto dPtr = reinterpret_cast( blob.GetBufferPointer() ); assert( dPtr != 0 ); memcpy_s( dPtr, blob.GetBufferSize(), &tga_header, sizeof(TGA_HEADER) ); dPtr += sizeof(TGA_HEADER); auto pPixels = reinterpret_cast( image.pixels ); assert( pPixels ); for( size_t y = 0; y < image.height; ++y ) { // Copy pixels if ( convFlags & CONV_FLAGS_888 ) { _Copy24bppScanline( dPtr, rowPitch, pPixels, image.rowPitch ); } else if ( convFlags & CONV_FLAGS_SWIZZLE ) { _SwizzleScanline( dPtr, rowPitch, pPixels, image.rowPitch, image.format, TEXP_SCANLINE_NONE ); } else { _CopyScanline( dPtr, rowPitch, pPixels, image.rowPitch, image.format, TEXP_SCANLINE_NONE ); } dPtr += rowPitch; pPixels += image.rowPitch; } return S_OK; } //------------------------------------------------------------------------------------- // Save a TGA file to disk //------------------------------------------------------------------------------------- _Use_decl_annotations_ HRESULT SaveToTGAFile( const Image& image, LPCWSTR szFile ) { if ( !szFile ) return E_INVALIDARG; if ( !image.pixels ) return E_POINTER; TGA_HEADER tga_header; DWORD convFlags = 0; HRESULT hr = _EncodeTGAHeader( image, tga_header, convFlags ); if ( FAILED(hr) ) return hr; // Create file and write header #if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) ScopedHandle hFile( safe_handle( CreateFile2( szFile, GENERIC_WRITE, 0, CREATE_ALWAYS, 0 ) ) ); #else ScopedHandle hFile( safe_handle( CreateFileW( szFile, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0 ) ) ); #endif if ( !hFile ) { return HRESULT_FROM_WIN32( GetLastError() ); } // Determine size for TGA pixel data size_t rowPitch, slicePitch; if ( convFlags & CONV_FLAGS_888 ) { rowPitch = image.width * 3; slicePitch = image.height * rowPitch; } else { ComputePitch( image.format, image.width, image.height, rowPitch, slicePitch, CP_FLAGS_NONE ); } if ( slicePitch < 65535 ) { // For small images, it is better to create an in-memory file and write it out Blob blob; hr = SaveToTGAMemory( image, blob ); if ( FAILED(hr) ) return hr; // Write blob const DWORD bytesToWrite = static_cast( blob.GetBufferSize() ); DWORD bytesWritten; if ( !WriteFile( hFile.get(), blob.GetBufferPointer(), bytesToWrite, &bytesWritten, 0 ) ) { return HRESULT_FROM_WIN32( GetLastError() ); } if ( bytesWritten != bytesToWrite ) { return E_FAIL; } } else { // Otherwise, write the image one scanline at a time... std::unique_ptr temp( new (std::nothrow) uint8_t[ rowPitch ] ); if ( !temp ) return E_OUTOFMEMORY; // Write header DWORD bytesWritten; if ( !WriteFile( hFile.get(), &tga_header, sizeof(TGA_HEADER), &bytesWritten, 0 ) ) { return HRESULT_FROM_WIN32( GetLastError() ); } if ( bytesWritten != sizeof(TGA_HEADER) ) return E_FAIL; // Write pixels auto pPixels = reinterpret_cast( image.pixels ); for( size_t y = 0; y < image.height; ++y ) { // Copy pixels if ( convFlags & CONV_FLAGS_888 ) { _Copy24bppScanline( temp.get(), rowPitch, pPixels, image.rowPitch ); } else if ( convFlags & CONV_FLAGS_SWIZZLE ) { _SwizzleScanline( temp.get(), rowPitch, pPixels, image.rowPitch, image.format, TEXP_SCANLINE_NONE ); } else { _CopyScanline( temp.get(), rowPitch, pPixels, image.rowPitch, image.format, TEXP_SCANLINE_NONE ); } pPixels += image.rowPitch; if ( !WriteFile( hFile.get(), temp.get(), static_cast( rowPitch ), &bytesWritten, 0 ) ) { return HRESULT_FROM_WIN32( GetLastError() ); } if ( bytesWritten != rowPitch ) return E_FAIL; } } return S_OK; } }; // namespace ================================================ FILE: 3rdParty/DirectXTex/DirectXTex/DirectXTexUtil.cpp ================================================ //------------------------------------------------------------------------------------- // DirectXTexUtil.cpp // // DirectX Texture Library - Utilities // // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A // PARTICULAR PURPOSE. // // Copyright (c) Microsoft Corporation. All rights reserved. // // http://go.microsoft.com/fwlink/?LinkId=248926 //------------------------------------------------------------------------------------- #include "directxtexp.h" //------------------------------------------------------------------------------------- // WIC Pixel Format Translation Data //------------------------------------------------------------------------------------- struct WICTranslate { GUID wic; DXGI_FORMAT format; bool srgb; }; static WICTranslate g_WICFormats[] = { { GUID_WICPixelFormat128bppRGBAFloat, DXGI_FORMAT_R32G32B32A32_FLOAT, false }, { GUID_WICPixelFormat64bppRGBAHalf, DXGI_FORMAT_R16G16B16A16_FLOAT, false }, { GUID_WICPixelFormat64bppRGBA, DXGI_FORMAT_R16G16B16A16_UNORM, true }, { GUID_WICPixelFormat32bppRGBA, DXGI_FORMAT_R8G8B8A8_UNORM, true }, { GUID_WICPixelFormat32bppBGRA, DXGI_FORMAT_B8G8R8A8_UNORM, true }, // DXGI 1.1 { GUID_WICPixelFormat32bppBGR, DXGI_FORMAT_B8G8R8X8_UNORM, true }, // DXGI 1.1 { GUID_WICPixelFormat32bppRGBA1010102XR, DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM, true }, // DXGI 1.1 { GUID_WICPixelFormat32bppRGBA1010102, DXGI_FORMAT_R10G10B10A2_UNORM, true }, { GUID_WICPixelFormat16bppBGRA5551, DXGI_FORMAT_B5G5R5A1_UNORM, true }, { GUID_WICPixelFormat16bppBGR565, DXGI_FORMAT_B5G6R5_UNORM, true }, { GUID_WICPixelFormat32bppGrayFloat, DXGI_FORMAT_R32_FLOAT, false }, { GUID_WICPixelFormat16bppGrayHalf, DXGI_FORMAT_R16_FLOAT, false }, { GUID_WICPixelFormat16bppGray, DXGI_FORMAT_R16_UNORM, true }, { GUID_WICPixelFormat8bppGray, DXGI_FORMAT_R8_UNORM, true }, { GUID_WICPixelFormat8bppAlpha, DXGI_FORMAT_A8_UNORM, false }, { GUID_WICPixelFormatBlackWhite, DXGI_FORMAT_R1_UNORM, false }, }; static bool g_WIC2 = false; namespace DirectX { //===================================================================================== // WIC Utilities //===================================================================================== _Use_decl_annotations_ DXGI_FORMAT _WICToDXGI( const GUID& guid ) { for( size_t i=0; i < _countof(g_WICFormats); ++i ) { if ( memcmp( &g_WICFormats[i].wic, &guid, sizeof(GUID) ) == 0 ) return g_WICFormats[i].format; } #if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) || defined(_WIN7_PLATFORM_UPDATE) if ( g_WIC2 ) { if ( memcmp( &GUID_WICPixelFormat96bppRGBFloat, &guid, sizeof(GUID) ) == 0 ) return DXGI_FORMAT_R32G32B32_FLOAT; } #endif return DXGI_FORMAT_UNKNOWN; } _Use_decl_annotations_ bool _DXGIToWIC( DXGI_FORMAT format, GUID& guid, bool ignoreRGBvsBGR ) { switch( format ) { case DXGI_FORMAT_R8G8B8A8_UNORM: case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: if ( ignoreRGBvsBGR ) { // If we are not doing conversion so don't really care about BGR vs RGB color-order, // we can use the canonical WIC 32bppBGRA format which avoids an extra format conversion when using the WIC scaler memcpy( &guid, &GUID_WICPixelFormat32bppBGRA, sizeof(GUID) ); } else { memcpy( &guid, &GUID_WICPixelFormat32bppRGBA, sizeof(GUID) ); } return true; case DXGI_FORMAT_D32_FLOAT: memcpy( &guid, &GUID_WICPixelFormat32bppGrayFloat, sizeof(GUID) ); return true; case DXGI_FORMAT_D16_UNORM: memcpy( &guid, &GUID_WICPixelFormat16bppGray, sizeof(GUID) ); return true; case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: memcpy( &guid, &GUID_WICPixelFormat32bppBGRA, sizeof(GUID) ); return true; case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: memcpy( &guid, &GUID_WICPixelFormat32bppBGR, sizeof(GUID) ); return true; #if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) || defined(_WIN7_PLATFORM_UPDATE) case DXGI_FORMAT_R32G32B32_FLOAT: if ( g_WIC2 ) { memcpy( &guid, &GUID_WICPixelFormat96bppRGBFloat, sizeof(GUID) ); return true; } break; #endif default: for( size_t i=0; i < _countof(g_WICFormats); ++i ) { if ( g_WICFormats[i].format == format ) { memcpy( &guid, &g_WICFormats[i].wic, sizeof(GUID) ); return true; } } break; } memcpy( &guid, &GUID_NULL, sizeof(GUID) ); return false; } DWORD _CheckWICColorSpace( _In_ const GUID& sourceGUID, _In_ const GUID& targetGUID ) { DWORD srgb = 0; for( size_t i=0; i < _countof(g_WICFormats); ++i ) { if ( memcmp( &g_WICFormats[i].wic, &sourceGUID, sizeof(GUID) ) == 0 ) { if ( g_WICFormats[i].srgb ) srgb |= TEX_FILTER_SRGB_IN; } if ( memcmp( &g_WICFormats[i].wic, &targetGUID, sizeof(GUID) ) == 0 ) { if ( g_WICFormats[i].srgb ) srgb |= TEX_FILTER_SRGB_OUT; } } if ( (srgb & (TEX_FILTER_SRGB_IN|TEX_FILTER_SRGB_OUT)) == (TEX_FILTER_SRGB_IN|TEX_FILTER_SRGB_OUT) ) { srgb &= ~(TEX_FILTER_SRGB_IN|TEX_FILTER_SRGB_OUT); } return srgb; } bool _IsWIC2() { return g_WIC2; } IWICImagingFactory* _GetWIC() { static IWICImagingFactory* s_Factory = nullptr; if ( s_Factory ) return s_Factory; #if(_WIN32_WINNT >= _WIN32_WINNT_WIN8) || defined(_WIN7_PLATFORM_UPDATE) HRESULT hr = CoCreateInstance( CLSID_WICImagingFactory2, nullptr, CLSCTX_INPROC_SERVER, __uuidof(IWICImagingFactory2), (LPVOID*)&s_Factory ); if ( SUCCEEDED(hr) ) { // WIC2 is available on Windows 8 and Windows 7 SP1 with KB 2670838 installed g_WIC2 = true; } else { hr = CoCreateInstance( CLSID_WICImagingFactory1, nullptr, CLSCTX_INPROC_SERVER, __uuidof(IWICImagingFactory), (LPVOID*)&s_Factory ); if ( FAILED(hr) ) { s_Factory = nullptr; return nullptr; } } #else HRESULT hr = CoCreateInstance( CLSID_WICImagingFactory, nullptr, CLSCTX_INPROC_SERVER, __uuidof(IWICImagingFactory), (LPVOID*)&s_Factory ); if ( FAILED(hr) ) { s_Factory = nullptr; return nullptr; } #endif return s_Factory; } //------------------------------------------------------------------------------------- // Public helper function to get common WIC codec GUIDs //------------------------------------------------------------------------------------- _Use_decl_annotations_ REFGUID GetWICCodec( WICCodecs codec ) { switch( codec ) { case WIC_CODEC_BMP: return GUID_ContainerFormatBmp; case WIC_CODEC_JPEG: return GUID_ContainerFormatJpeg; case WIC_CODEC_PNG: return GUID_ContainerFormatPng; case WIC_CODEC_TIFF: return GUID_ContainerFormatTiff; case WIC_CODEC_GIF: return GUID_ContainerFormatGif; case WIC_CODEC_WMP: return GUID_ContainerFormatWmp; case WIC_CODEC_ICO: return GUID_ContainerFormatIco; default: return GUID_NULL; } } //===================================================================================== // DXGI Format Utilities //===================================================================================== //------------------------------------------------------------------------------------- // Returns bits-per-pixel for a given DXGI format, or 0 on failure //------------------------------------------------------------------------------------- _Use_decl_annotations_ size_t BitsPerPixel( DXGI_FORMAT fmt ) { switch( static_cast(fmt) ) { case DXGI_FORMAT_R32G32B32A32_TYPELESS: case DXGI_FORMAT_R32G32B32A32_FLOAT: case DXGI_FORMAT_R32G32B32A32_UINT: case DXGI_FORMAT_R32G32B32A32_SINT: return 128; case DXGI_FORMAT_R32G32B32_TYPELESS: case DXGI_FORMAT_R32G32B32_FLOAT: case DXGI_FORMAT_R32G32B32_UINT: case DXGI_FORMAT_R32G32B32_SINT: return 96; case DXGI_FORMAT_R16G16B16A16_TYPELESS: case DXGI_FORMAT_R16G16B16A16_FLOAT: case DXGI_FORMAT_R16G16B16A16_UNORM: case DXGI_FORMAT_R16G16B16A16_UINT: case DXGI_FORMAT_R16G16B16A16_SNORM: case DXGI_FORMAT_R16G16B16A16_SINT: case DXGI_FORMAT_R32G32_TYPELESS: case DXGI_FORMAT_R32G32_FLOAT: case DXGI_FORMAT_R32G32_UINT: case DXGI_FORMAT_R32G32_SINT: case DXGI_FORMAT_R32G8X24_TYPELESS: case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: case DXGI_FORMAT_Y416: case DXGI_FORMAT_Y210: case DXGI_FORMAT_Y216: return 64; case DXGI_FORMAT_R10G10B10A2_TYPELESS: case DXGI_FORMAT_R10G10B10A2_UNORM: case DXGI_FORMAT_R10G10B10A2_UINT: case DXGI_FORMAT_R11G11B10_FLOAT: case DXGI_FORMAT_R8G8B8A8_TYPELESS: case DXGI_FORMAT_R8G8B8A8_UNORM: case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: case DXGI_FORMAT_R8G8B8A8_UINT: case DXGI_FORMAT_R8G8B8A8_SNORM: case DXGI_FORMAT_R8G8B8A8_SINT: case DXGI_FORMAT_R16G16_TYPELESS: case DXGI_FORMAT_R16G16_FLOAT: case DXGI_FORMAT_R16G16_UNORM: case DXGI_FORMAT_R16G16_UINT: case DXGI_FORMAT_R16G16_SNORM: case DXGI_FORMAT_R16G16_SINT: case DXGI_FORMAT_R32_TYPELESS: case DXGI_FORMAT_D32_FLOAT: case DXGI_FORMAT_R32_FLOAT: case DXGI_FORMAT_R32_UINT: case DXGI_FORMAT_R32_SINT: case DXGI_FORMAT_R24G8_TYPELESS: case DXGI_FORMAT_D24_UNORM_S8_UINT: case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: case DXGI_FORMAT_X24_TYPELESS_G8_UINT: case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: case DXGI_FORMAT_R8G8_B8G8_UNORM: case DXGI_FORMAT_G8R8_G8B8_UNORM: case DXGI_FORMAT_B8G8R8A8_UNORM: case DXGI_FORMAT_B8G8R8X8_UNORM: case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM: case DXGI_FORMAT_B8G8R8A8_TYPELESS: case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: case DXGI_FORMAT_B8G8R8X8_TYPELESS: case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: case DXGI_FORMAT_AYUV: case DXGI_FORMAT_Y410: case DXGI_FORMAT_YUY2: case 116 /* DXGI_FORMAT_R10G10B10_7E3_A2_FLOAT */: case 117 /* DXGI_FORMAT_R10G10B10_6E4_A2_FLOAT */: return 32; case DXGI_FORMAT_P010: case DXGI_FORMAT_P016: case 118 /* DXGI_FORMAT_D16_UNORM_S8_UINT */: case 119 /* DXGI_FORMAT_R16_UNORM_X8_TYPELESS */: case 120 /* DXGI_FORMAT_X16_TYPELESS_G8_UINT */: return 24; case DXGI_FORMAT_R8G8_TYPELESS: case DXGI_FORMAT_R8G8_UNORM: case DXGI_FORMAT_R8G8_UINT: case DXGI_FORMAT_R8G8_SNORM: case DXGI_FORMAT_R8G8_SINT: case DXGI_FORMAT_R16_TYPELESS: case DXGI_FORMAT_R16_FLOAT: case DXGI_FORMAT_D16_UNORM: case DXGI_FORMAT_R16_UNORM: case DXGI_FORMAT_R16_UINT: case DXGI_FORMAT_R16_SNORM: case DXGI_FORMAT_R16_SINT: case DXGI_FORMAT_B5G6R5_UNORM: case DXGI_FORMAT_B5G5R5A1_UNORM: case DXGI_FORMAT_A8P8: case DXGI_FORMAT_B4G4R4A4_UNORM: return 16; case DXGI_FORMAT_NV12: case DXGI_FORMAT_420_OPAQUE: case DXGI_FORMAT_NV11: return 12; case DXGI_FORMAT_R8_TYPELESS: case DXGI_FORMAT_R8_UNORM: case DXGI_FORMAT_R8_UINT: case DXGI_FORMAT_R8_SNORM: case DXGI_FORMAT_R8_SINT: case DXGI_FORMAT_A8_UNORM: case DXGI_FORMAT_AI44: case DXGI_FORMAT_IA44: case DXGI_FORMAT_P8: return 8; case DXGI_FORMAT_R1_UNORM: return 1; case DXGI_FORMAT_BC1_TYPELESS: case DXGI_FORMAT_BC1_UNORM: case DXGI_FORMAT_BC1_UNORM_SRGB: case DXGI_FORMAT_BC4_TYPELESS: case DXGI_FORMAT_BC4_UNORM: case DXGI_FORMAT_BC4_SNORM: return 4; case DXGI_FORMAT_BC2_TYPELESS: case DXGI_FORMAT_BC2_UNORM: case DXGI_FORMAT_BC2_UNORM_SRGB: case DXGI_FORMAT_BC3_TYPELESS: case DXGI_FORMAT_BC3_UNORM: case DXGI_FORMAT_BC3_UNORM_SRGB: case DXGI_FORMAT_BC5_TYPELESS: case DXGI_FORMAT_BC5_UNORM: case DXGI_FORMAT_BC5_SNORM: case DXGI_FORMAT_BC6H_TYPELESS: case DXGI_FORMAT_BC6H_UF16: case DXGI_FORMAT_BC6H_SF16: case DXGI_FORMAT_BC7_TYPELESS: case DXGI_FORMAT_BC7_UNORM: case DXGI_FORMAT_BC7_UNORM_SRGB: return 8; default: return 0; } } //------------------------------------------------------------------------------------- // Returns bits-per-color-channel for a given DXGI format, or 0 on failure // For mixed formats, it returns the largest color-depth in the format //------------------------------------------------------------------------------------- _Use_decl_annotations_ size_t BitsPerColor( DXGI_FORMAT fmt ) { switch( static_cast(fmt) ) { case DXGI_FORMAT_R32G32B32A32_TYPELESS: case DXGI_FORMAT_R32G32B32A32_FLOAT: case DXGI_FORMAT_R32G32B32A32_UINT: case DXGI_FORMAT_R32G32B32A32_SINT: case DXGI_FORMAT_R32G32B32_TYPELESS: case DXGI_FORMAT_R32G32B32_FLOAT: case DXGI_FORMAT_R32G32B32_UINT: case DXGI_FORMAT_R32G32B32_SINT: case DXGI_FORMAT_R32G32_TYPELESS: case DXGI_FORMAT_R32G32_FLOAT: case DXGI_FORMAT_R32G32_UINT: case DXGI_FORMAT_R32G32_SINT: case DXGI_FORMAT_R32G8X24_TYPELESS: case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: case DXGI_FORMAT_R32_TYPELESS: case DXGI_FORMAT_D32_FLOAT: case DXGI_FORMAT_R32_FLOAT: case DXGI_FORMAT_R32_UINT: case DXGI_FORMAT_R32_SINT: return 32; case DXGI_FORMAT_R24G8_TYPELESS: case DXGI_FORMAT_D24_UNORM_S8_UINT: case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: case DXGI_FORMAT_X24_TYPELESS_G8_UINT: return 24; case DXGI_FORMAT_R16G16B16A16_TYPELESS: case DXGI_FORMAT_R16G16B16A16_FLOAT: case DXGI_FORMAT_R16G16B16A16_UNORM: case DXGI_FORMAT_R16G16B16A16_UINT: case DXGI_FORMAT_R16G16B16A16_SNORM: case DXGI_FORMAT_R16G16B16A16_SINT: case DXGI_FORMAT_R16G16_TYPELESS: case DXGI_FORMAT_R16G16_FLOAT: case DXGI_FORMAT_R16G16_UNORM: case DXGI_FORMAT_R16G16_UINT: case DXGI_FORMAT_R16G16_SNORM: case DXGI_FORMAT_R16G16_SINT: case DXGI_FORMAT_R16_TYPELESS: case DXGI_FORMAT_R16_FLOAT: case DXGI_FORMAT_D16_UNORM: case DXGI_FORMAT_R16_UNORM: case DXGI_FORMAT_R16_UINT: case DXGI_FORMAT_R16_SNORM: case DXGI_FORMAT_R16_SINT: case DXGI_FORMAT_BC6H_TYPELESS: case DXGI_FORMAT_BC6H_UF16: case DXGI_FORMAT_BC6H_SF16: case DXGI_FORMAT_Y416: case DXGI_FORMAT_P016: case DXGI_FORMAT_Y216: return 16; case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: return 14; case DXGI_FORMAT_R11G11B10_FLOAT: return 11; case DXGI_FORMAT_R10G10B10A2_TYPELESS: case DXGI_FORMAT_R10G10B10A2_UNORM: case DXGI_FORMAT_R10G10B10A2_UINT: case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM: case DXGI_FORMAT_Y410: case DXGI_FORMAT_P010: case DXGI_FORMAT_Y210: return 10; case DXGI_FORMAT_R8G8B8A8_TYPELESS: case DXGI_FORMAT_R8G8B8A8_UNORM: case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: case DXGI_FORMAT_R8G8B8A8_UINT: case DXGI_FORMAT_R8G8B8A8_SNORM: case DXGI_FORMAT_R8G8B8A8_SINT: case DXGI_FORMAT_R8G8_TYPELESS: case DXGI_FORMAT_R8G8_UNORM: case DXGI_FORMAT_R8G8_UINT: case DXGI_FORMAT_R8G8_SNORM: case DXGI_FORMAT_R8G8_SINT: case DXGI_FORMAT_R8_TYPELESS: case DXGI_FORMAT_R8_UNORM: case DXGI_FORMAT_R8_UINT: case DXGI_FORMAT_R8_SNORM: case DXGI_FORMAT_R8_SINT: case DXGI_FORMAT_A8_UNORM: case DXGI_FORMAT_R8G8_B8G8_UNORM: case DXGI_FORMAT_G8R8_G8B8_UNORM: case DXGI_FORMAT_BC4_TYPELESS: case DXGI_FORMAT_BC4_UNORM: case DXGI_FORMAT_BC4_SNORM: case DXGI_FORMAT_BC5_TYPELESS: case DXGI_FORMAT_BC5_UNORM: case DXGI_FORMAT_BC5_SNORM: case DXGI_FORMAT_B8G8R8A8_UNORM: case DXGI_FORMAT_B8G8R8X8_UNORM: case DXGI_FORMAT_B8G8R8A8_TYPELESS: case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: case DXGI_FORMAT_B8G8R8X8_TYPELESS: case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: case DXGI_FORMAT_AYUV: case DXGI_FORMAT_NV12: case DXGI_FORMAT_420_OPAQUE: case DXGI_FORMAT_YUY2: case DXGI_FORMAT_NV11: return 8; case DXGI_FORMAT_BC7_TYPELESS: case DXGI_FORMAT_BC7_UNORM: case DXGI_FORMAT_BC7_UNORM_SRGB: return 7; case DXGI_FORMAT_BC1_TYPELESS: case DXGI_FORMAT_BC1_UNORM: case DXGI_FORMAT_BC1_UNORM_SRGB: case DXGI_FORMAT_BC2_TYPELESS: case DXGI_FORMAT_BC2_UNORM: case DXGI_FORMAT_BC2_UNORM_SRGB: case DXGI_FORMAT_BC3_TYPELESS: case DXGI_FORMAT_BC3_UNORM: case DXGI_FORMAT_BC3_UNORM_SRGB: case DXGI_FORMAT_B5G6R5_UNORM: return 6; case DXGI_FORMAT_B5G5R5A1_UNORM: return 5; case DXGI_FORMAT_B4G4R4A4_UNORM: return 4; case DXGI_FORMAT_R1_UNORM: return 1; case 116 /* DXGI_FORMAT_R10G10B10_7E3_A2_FLOAT */: case 117 /* DXGI_FORMAT_R10G10B10_6E4_A2_FLOAT */: // These are Xbox One platform specific types return 10; case 118 /* DXGI_FORMAT_D16_UNORM_S8_UINT */: case 119 /* DXGI_FORMAT_R16_UNORM_X8_TYPELESS */: case 120 /* DXGI_FORMAT_X16_TYPELESS_G8_UINT */: // These are Xbox One platform specific types return 16; case DXGI_FORMAT_AI44: case DXGI_FORMAT_IA44: case DXGI_FORMAT_P8: case DXGI_FORMAT_A8P8: // Palettized formats return 0 for this function default: return 0; } } //------------------------------------------------------------------------------------- // Computes the image row pitch in bytes, and the slice ptich (size in bytes of the image) // based on DXGI format, width, and height //------------------------------------------------------------------------------------- _Use_decl_annotations_ void ComputePitch( DXGI_FORMAT fmt, size_t width, size_t height, size_t& rowPitch, size_t& slicePitch, DWORD flags ) { assert( IsValid(fmt) ); if ( IsCompressed(fmt) ) { size_t bpb = ( fmt == DXGI_FORMAT_BC1_TYPELESS || fmt == DXGI_FORMAT_BC1_UNORM || fmt == DXGI_FORMAT_BC1_UNORM_SRGB || fmt == DXGI_FORMAT_BC4_TYPELESS || fmt == DXGI_FORMAT_BC4_UNORM || fmt == DXGI_FORMAT_BC4_SNORM) ? 8 : 16; size_t nbw = std::max( 1, (width + 3) / 4 ); size_t nbh = std::max( 1, (height + 3) / 4 ); rowPitch = nbw * bpb; slicePitch = rowPitch * nbh; } else if ( IsPacked(fmt) ) { size_t bpe = ( fmt == DXGI_FORMAT_Y210 || fmt == DXGI_FORMAT_Y216 ) ? 8 : 4; rowPitch = ( ( width + 1 ) >> 1 ) * bpe; slicePitch = rowPitch * height; } else if ( fmt == DXGI_FORMAT_NV11 ) { rowPitch = ( ( width + 3 ) >> 2 ) * 4; // Direct3D makes this simplifying assumption, although it is larger than the 4:1:1 data slicePitch = rowPitch * height * 2; } else if ( IsPlanar(fmt) ) { size_t bpe = ( fmt == DXGI_FORMAT_P010 || fmt == DXGI_FORMAT_P016 || fmt == DXGI_FORMAT(118 /* DXGI_FORMAT_D16_UNORM_S8_UINT */) || fmt == DXGI_FORMAT(119 /* DXGI_FORMAT_R16_UNORM_X8_TYPELESS */) || fmt == DXGI_FORMAT(120 /* DXGI_FORMAT_X16_TYPELESS_G8_UINT */) ) ? 4 : 2; rowPitch = ( ( width + 1 ) >> 1 ) * bpe; slicePitch = rowPitch * ( height + ( ( height + 1 ) >> 1 ) ); } else { size_t bpp; if ( flags & CP_FLAGS_24BPP ) bpp = 24; else if ( flags & CP_FLAGS_16BPP ) bpp = 16; else if ( flags & CP_FLAGS_8BPP ) bpp = 8; else bpp = BitsPerPixel( fmt ); if ( flags & ( CP_FLAGS_LEGACY_DWORD | CP_FLAGS_PARAGRAPH | CP_FLAGS_YMM | CP_FLAGS_ZMM | CP_FLAGS_PAGE4K ) ) { if ( flags & CP_FLAGS_PAGE4K ) { rowPitch = ( ( width * bpp + 32767 ) / 32768 ) * 4096; slicePitch = rowPitch * height; } else if ( flags & CP_FLAGS_ZMM ) { rowPitch = ( ( width * bpp + 511 ) / 512 ) * 64; slicePitch = rowPitch * height; } else if ( flags & CP_FLAGS_YMM ) { rowPitch = ( ( width * bpp + 255 ) / 256) * 32; slicePitch = rowPitch * height; } else if ( flags & CP_FLAGS_PARAGRAPH ) { rowPitch = ( ( width * bpp + 127 ) / 128 ) * 16; slicePitch = rowPitch * height; } else // DWORD alignment { // Special computation for some incorrectly created DDS files based on // legacy DirectDraw assumptions about pitch alignment rowPitch = ( ( width * bpp + 31 ) / 32 ) * sizeof(uint32_t); slicePitch = rowPitch * height; } } else { // Default byte alignment rowPitch = ( width * bpp + 7 ) / 8; slicePitch = rowPitch * height; } } } //------------------------------------------------------------------------------------- // Converts to an SRGB equivalent type if available //------------------------------------------------------------------------------------- _Use_decl_annotations_ DXGI_FORMAT MakeSRGB( DXGI_FORMAT fmt ) { switch( fmt ) { case DXGI_FORMAT_R8G8B8A8_UNORM: return DXGI_FORMAT_R8G8B8A8_UNORM_SRGB; case DXGI_FORMAT_BC1_UNORM: return DXGI_FORMAT_BC1_UNORM_SRGB; case DXGI_FORMAT_BC2_UNORM: return DXGI_FORMAT_BC2_UNORM_SRGB; case DXGI_FORMAT_BC3_UNORM: return DXGI_FORMAT_BC3_UNORM_SRGB; case DXGI_FORMAT_B8G8R8A8_UNORM: return DXGI_FORMAT_B8G8R8A8_UNORM_SRGB; case DXGI_FORMAT_B8G8R8X8_UNORM: return DXGI_FORMAT_B8G8R8X8_UNORM_SRGB; case DXGI_FORMAT_BC7_UNORM: return DXGI_FORMAT_BC7_UNORM_SRGB; default: return fmt; } } //------------------------------------------------------------------------------------- // Converts to a format to an equivalent TYPELESS format if available //------------------------------------------------------------------------------------- _Use_decl_annotations_ DXGI_FORMAT MakeTypeless( DXGI_FORMAT fmt ) { switch( fmt ) { case DXGI_FORMAT_R32G32B32A32_FLOAT: case DXGI_FORMAT_R32G32B32A32_UINT: case DXGI_FORMAT_R32G32B32A32_SINT: return DXGI_FORMAT_R32G32B32A32_TYPELESS; case DXGI_FORMAT_R32G32B32_FLOAT: case DXGI_FORMAT_R32G32B32_UINT: case DXGI_FORMAT_R32G32B32_SINT: return DXGI_FORMAT_R32G32B32_TYPELESS; case DXGI_FORMAT_R16G16B16A16_FLOAT: case DXGI_FORMAT_R16G16B16A16_UNORM: case DXGI_FORMAT_R16G16B16A16_UINT: case DXGI_FORMAT_R16G16B16A16_SNORM: case DXGI_FORMAT_R16G16B16A16_SINT: return DXGI_FORMAT_R16G16B16A16_TYPELESS; case DXGI_FORMAT_R32G32_FLOAT: case DXGI_FORMAT_R32G32_UINT: case DXGI_FORMAT_R32G32_SINT: return DXGI_FORMAT_R32G32_TYPELESS; case DXGI_FORMAT_R10G10B10A2_UNORM: case DXGI_FORMAT_R10G10B10A2_UINT: return DXGI_FORMAT_R10G10B10A2_TYPELESS; case DXGI_FORMAT_R8G8B8A8_UNORM: case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: case DXGI_FORMAT_R8G8B8A8_UINT: case DXGI_FORMAT_R8G8B8A8_SNORM: case DXGI_FORMAT_R8G8B8A8_SINT: return DXGI_FORMAT_R8G8B8A8_TYPELESS; case DXGI_FORMAT_R16G16_FLOAT: case DXGI_FORMAT_R16G16_UNORM: case DXGI_FORMAT_R16G16_UINT: case DXGI_FORMAT_R16G16_SNORM: case DXGI_FORMAT_R16G16_SINT: return DXGI_FORMAT_R16G16_TYPELESS; case DXGI_FORMAT_D32_FLOAT: case DXGI_FORMAT_R32_FLOAT: case DXGI_FORMAT_R32_UINT: case DXGI_FORMAT_R32_SINT: return DXGI_FORMAT_R32_TYPELESS; case DXGI_FORMAT_R8G8_UNORM: case DXGI_FORMAT_R8G8_UINT: case DXGI_FORMAT_R8G8_SNORM: case DXGI_FORMAT_R8G8_SINT: return DXGI_FORMAT_R8G8_TYPELESS; case DXGI_FORMAT_R16_FLOAT: case DXGI_FORMAT_D16_UNORM: case DXGI_FORMAT_R16_UNORM: case DXGI_FORMAT_R16_UINT: case DXGI_FORMAT_R16_SNORM: case DXGI_FORMAT_R16_SINT: return DXGI_FORMAT_R16_TYPELESS; case DXGI_FORMAT_R8_UNORM: case DXGI_FORMAT_R8_UINT: case DXGI_FORMAT_R8_SNORM: case DXGI_FORMAT_R8_SINT: return DXGI_FORMAT_R8_TYPELESS; case DXGI_FORMAT_BC1_UNORM: case DXGI_FORMAT_BC1_UNORM_SRGB: return DXGI_FORMAT_BC1_TYPELESS; case DXGI_FORMAT_BC2_UNORM: case DXGI_FORMAT_BC2_UNORM_SRGB: return DXGI_FORMAT_BC2_TYPELESS; case DXGI_FORMAT_BC3_UNORM: case DXGI_FORMAT_BC3_UNORM_SRGB: return DXGI_FORMAT_BC3_TYPELESS; case DXGI_FORMAT_BC4_UNORM: case DXGI_FORMAT_BC4_SNORM: return DXGI_FORMAT_BC4_TYPELESS; case DXGI_FORMAT_BC5_UNORM: case DXGI_FORMAT_BC5_SNORM: return DXGI_FORMAT_BC5_TYPELESS; case DXGI_FORMAT_B8G8R8A8_UNORM: case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: return DXGI_FORMAT_B8G8R8A8_TYPELESS; case DXGI_FORMAT_B8G8R8X8_UNORM: case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: return DXGI_FORMAT_B8G8R8X8_TYPELESS; case DXGI_FORMAT_BC6H_UF16: case DXGI_FORMAT_BC6H_SF16: return DXGI_FORMAT_BC6H_TYPELESS; case DXGI_FORMAT_BC7_UNORM: case DXGI_FORMAT_BC7_UNORM_SRGB: return DXGI_FORMAT_BC7_TYPELESS; default: return fmt; } } //------------------------------------------------------------------------------------- // Converts to a TYPELESS format to an equivalent UNORM format if available //------------------------------------------------------------------------------------- _Use_decl_annotations_ DXGI_FORMAT MakeTypelessUNORM( DXGI_FORMAT fmt ) { switch( fmt ) { case DXGI_FORMAT_R16G16B16A16_TYPELESS: return DXGI_FORMAT_R16G16B16A16_UNORM; case DXGI_FORMAT_R10G10B10A2_TYPELESS: return DXGI_FORMAT_R10G10B10A2_UNORM; case DXGI_FORMAT_R8G8B8A8_TYPELESS: return DXGI_FORMAT_R8G8B8A8_UNORM; case DXGI_FORMAT_R16G16_TYPELESS: return DXGI_FORMAT_R16G16_UNORM; case DXGI_FORMAT_R8G8_TYPELESS: return DXGI_FORMAT_R8G8_UNORM; case DXGI_FORMAT_R16_TYPELESS: return DXGI_FORMAT_R16_UNORM; case DXGI_FORMAT_R8_TYPELESS: return DXGI_FORMAT_R8_UNORM; case DXGI_FORMAT_BC1_TYPELESS: return DXGI_FORMAT_BC1_UNORM; case DXGI_FORMAT_BC2_TYPELESS: return DXGI_FORMAT_BC2_UNORM; case DXGI_FORMAT_BC3_TYPELESS: return DXGI_FORMAT_BC3_UNORM; case DXGI_FORMAT_BC4_TYPELESS: return DXGI_FORMAT_BC4_UNORM; case DXGI_FORMAT_BC5_TYPELESS: return DXGI_FORMAT_BC5_UNORM; case DXGI_FORMAT_B8G8R8A8_TYPELESS: return DXGI_FORMAT_B8G8R8A8_UNORM; case DXGI_FORMAT_B8G8R8X8_TYPELESS: return DXGI_FORMAT_B8G8R8X8_UNORM; case DXGI_FORMAT_BC7_TYPELESS: return DXGI_FORMAT_BC7_UNORM; default: return fmt; } } //------------------------------------------------------------------------------------- // Converts to a TYPELESS format to an equivalent FLOAT format if available //------------------------------------------------------------------------------------- _Use_decl_annotations_ DXGI_FORMAT MakeTypelessFLOAT( DXGI_FORMAT fmt ) { switch( fmt ) { case DXGI_FORMAT_R32G32B32A32_TYPELESS: return DXGI_FORMAT_R32G32B32A32_FLOAT; case DXGI_FORMAT_R32G32B32_TYPELESS: return DXGI_FORMAT_R32G32B32_FLOAT; case DXGI_FORMAT_R16G16B16A16_TYPELESS: return DXGI_FORMAT_R16G16B16A16_FLOAT; case DXGI_FORMAT_R32G32_TYPELESS: return DXGI_FORMAT_R32G32_FLOAT; case DXGI_FORMAT_R16G16_TYPELESS: return DXGI_FORMAT_R16G16_FLOAT; case DXGI_FORMAT_R32_TYPELESS: return DXGI_FORMAT_R32_FLOAT; case DXGI_FORMAT_R16_TYPELESS: return DXGI_FORMAT_R16_FLOAT; default: return fmt; } } //===================================================================================== // TexMetadata //===================================================================================== _Use_decl_annotations_ size_t TexMetadata::ComputeIndex( size_t mip, size_t item, size_t slice ) const { if ( mip >= mipLevels ) return size_t(-1); switch( dimension ) { case TEX_DIMENSION_TEXTURE1D: case TEX_DIMENSION_TEXTURE2D: if ( slice > 0 ) return size_t(-1); if ( item >= arraySize ) return size_t(-1); return (item*( mipLevels ) + mip); case TEX_DIMENSION_TEXTURE3D: if ( item > 0 ) { // No support for arrays of volumes return size_t(-1); } else { size_t index = 0; size_t d = depth; for( size_t level = 0; level < mip; ++level ) { index += d; if ( d > 1 ) d >>= 1; } if ( slice >= d ) return size_t(-1); index += slice; return index; } break; default: return size_t(-1); } } //===================================================================================== // Blob - Bitmap image container //===================================================================================== Blob& Blob::operator= (Blob&& moveFrom) { if ( this != &moveFrom ) { Release(); _buffer = moveFrom._buffer; _size = moveFrom._size; moveFrom._buffer = nullptr; moveFrom._size = 0; } return *this; } void Blob::Release() { if ( _buffer ) { _aligned_free( _buffer ); _buffer = nullptr; } _size = 0; } _Use_decl_annotations_ HRESULT Blob::Initialize( size_t size ) { if ( !size ) return E_INVALIDARG; Release(); _buffer = _aligned_malloc( size, 16 ); if ( !_buffer ) { Release(); return E_OUTOFMEMORY; } _size = size; return S_OK; } }; // namespace ================================================ FILE: 3rdParty/DirectXTex/DirectXTex/DirectXTexWIC.cpp ================================================ //------------------------------------------------------------------------------------- // DirectXTexWIC.cpp // // DirectX Texture Library - WIC-based file reader/writer // // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A // PARTICULAR PURPOSE. // // Copyright (c) Microsoft Corporation. All rights reserved. // // http://go.microsoft.com/fwlink/?LinkId=248926 //------------------------------------------------------------------------------------- #include "directxtexp.h" using Microsoft::WRL::ComPtr; //------------------------------------------------------------------------------------- // IStream support for WIC Memory routines //------------------------------------------------------------------------------------- #if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP) && (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP) #include #pragma comment(lib,"shcore.lib") #ifdef __cplusplus_winrt static inline HRESULT CreateMemoryStream( _Outptr_ IStream** stream ) { auto randomAccessStream = ref new ::Windows::Storage::Streams::InMemoryRandomAccessStream(); return CreateStreamOverRandomAccessStream( randomAccessStream, IID_PPV_ARGS( stream ) ); } #else #include #include #include static inline HRESULT CreateMemoryStream( _Outptr_ IStream** stream ) { Microsoft::WRL::ComPtr abiStream; HRESULT hr = Windows::Foundation::ActivateInstance( Microsoft::WRL::Wrappers::HStringReference( RuntimeClass_Windows_Storage_Streams_InMemoryRandomAccessStream ).Get(), abiStream.GetAddressOf() ); if (SUCCEEDED(hr)) { hr = CreateStreamOverRandomAccessStream( abiStream.Get(), IID_PPV_ARGS( stream ) ); } return hr; } #endif // __cplusplus_winrt #else #pragma prefast(suppress:28196, "a simple wrapper around an existing annotated function" ); static inline HRESULT CreateMemoryStream( _Outptr_ IStream** stream ) { return CreateStreamOnHGlobal( 0, TRUE, stream ); } #endif //------------------------------------------------------------------------------------- // WIC Pixel Format nearest conversion table //------------------------------------------------------------------------------------- struct WICConvert { GUID source; GUID target; }; static WICConvert g_WICConvert[] = { // Directly support the formats listed in XnaTexUtil::g_WICFormats, so no conversion required // Note target GUID in this conversion table must be one of those directly supported formats. { GUID_WICPixelFormat1bppIndexed, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM { GUID_WICPixelFormat2bppIndexed, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM { GUID_WICPixelFormat4bppIndexed, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM { GUID_WICPixelFormat8bppIndexed, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM { GUID_WICPixelFormat2bppGray, GUID_WICPixelFormat8bppGray }, // DXGI_FORMAT_R8_UNORM { GUID_WICPixelFormat4bppGray, GUID_WICPixelFormat8bppGray }, // DXGI_FORMAT_R8_UNORM { GUID_WICPixelFormat16bppGrayFixedPoint, GUID_WICPixelFormat16bppGrayHalf }, // DXGI_FORMAT_R16_FLOAT { GUID_WICPixelFormat32bppGrayFixedPoint, GUID_WICPixelFormat32bppGrayFloat }, // DXGI_FORMAT_R32_FLOAT { GUID_WICPixelFormat16bppBGR555, GUID_WICPixelFormat16bppBGRA5551 }, // DXGI_FORMAT_B5G5R5A1_UNORM { GUID_WICPixelFormat32bppBGR101010, GUID_WICPixelFormat32bppRGBA1010102 }, // DXGI_FORMAT_R10G10B10A2_UNORM { GUID_WICPixelFormat24bppBGR, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM { GUID_WICPixelFormat24bppRGB, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM { GUID_WICPixelFormat32bppPBGRA, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM { GUID_WICPixelFormat32bppPRGBA, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM { GUID_WICPixelFormat48bppRGB, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM { GUID_WICPixelFormat48bppBGR, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM { GUID_WICPixelFormat64bppBGRA, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM { GUID_WICPixelFormat64bppPRGBA, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM { GUID_WICPixelFormat64bppPBGRA, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM { GUID_WICPixelFormat48bppRGBFixedPoint, GUID_WICPixelFormat64bppRGBAHalf }, // DXGI_FORMAT_R16G16B16A16_FLOAT { GUID_WICPixelFormat48bppBGRFixedPoint, GUID_WICPixelFormat64bppRGBAHalf }, // DXGI_FORMAT_R16G16B16A16_FLOAT { GUID_WICPixelFormat64bppRGBAFixedPoint, GUID_WICPixelFormat64bppRGBAHalf }, // DXGI_FORMAT_R16G16B16A16_FLOAT { GUID_WICPixelFormat64bppBGRAFixedPoint, GUID_WICPixelFormat64bppRGBAHalf }, // DXGI_FORMAT_R16G16B16A16_FLOAT { GUID_WICPixelFormat64bppRGBFixedPoint, GUID_WICPixelFormat64bppRGBAHalf }, // DXGI_FORMAT_R16G16B16A16_FLOAT { GUID_WICPixelFormat64bppRGBHalf, GUID_WICPixelFormat64bppRGBAHalf }, // DXGI_FORMAT_R16G16B16A16_FLOAT { GUID_WICPixelFormat48bppRGBHalf, GUID_WICPixelFormat64bppRGBAHalf }, // DXGI_FORMAT_R16G16B16A16_FLOAT { GUID_WICPixelFormat128bppPRGBAFloat, GUID_WICPixelFormat128bppRGBAFloat }, // DXGI_FORMAT_R32G32B32A32_FLOAT { GUID_WICPixelFormat128bppRGBFloat, GUID_WICPixelFormat128bppRGBAFloat }, // DXGI_FORMAT_R32G32B32A32_FLOAT { GUID_WICPixelFormat128bppRGBAFixedPoint, GUID_WICPixelFormat128bppRGBAFloat }, // DXGI_FORMAT_R32G32B32A32_FLOAT { GUID_WICPixelFormat128bppRGBFixedPoint, GUID_WICPixelFormat128bppRGBAFloat }, // DXGI_FORMAT_R32G32B32A32_FLOAT { GUID_WICPixelFormat32bppRGBE, GUID_WICPixelFormat128bppRGBAFloat }, // DXGI_FORMAT_R32G32B32A32_FLOAT { GUID_WICPixelFormat32bppCMYK, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM { GUID_WICPixelFormat64bppCMYK, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM { GUID_WICPixelFormat40bppCMYKAlpha, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM { GUID_WICPixelFormat80bppCMYKAlpha, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM #if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) || defined(_WIN7_PLATFORM_UPDATE) { GUID_WICPixelFormat32bppRGB, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM { GUID_WICPixelFormat64bppRGB, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM { GUID_WICPixelFormat64bppPRGBAHalf, GUID_WICPixelFormat64bppRGBAHalf }, // DXGI_FORMAT_R16G16B16A16_FLOAT #endif // We don't support n-channel formats }; namespace DirectX { //------------------------------------------------------------------------------------- // Returns the DXGI format and optionally the WIC pixel GUID to convert to //------------------------------------------------------------------------------------- static DXGI_FORMAT _DetermineFormat( _In_ const WICPixelFormatGUID& pixelFormat, _In_ DWORD flags, _Out_opt_ WICPixelFormatGUID* pConvert ) { if ( pConvert ) memset( pConvert, 0, sizeof(WICPixelFormatGUID) ); DXGI_FORMAT format = _WICToDXGI( pixelFormat ); if ( format == DXGI_FORMAT_UNKNOWN ) { if ( memcmp( &GUID_WICPixelFormat96bppRGBFixedPoint, &pixelFormat, sizeof(WICPixelFormatGUID) ) == 0 ) { #if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) || defined(_WIN7_PLATFORM_UPDATE) if ( _IsWIC2() ) { if ( pConvert ) memcpy( pConvert, &GUID_WICPixelFormat96bppRGBFloat, sizeof(WICPixelFormatGUID) ); format = DXGI_FORMAT_R32G32B32_FLOAT; } else #endif { if ( pConvert ) memcpy( pConvert, &GUID_WICPixelFormat128bppRGBAFloat, sizeof(WICPixelFormatGUID) ); format = DXGI_FORMAT_R32G32B32A32_FLOAT; } } else { for( size_t i=0; i < _countof(g_WICConvert); ++i ) { if ( memcmp( &g_WICConvert[i].source, &pixelFormat, sizeof(WICPixelFormatGUID) ) == 0 ) { if ( pConvert ) memcpy( pConvert, &g_WICConvert[i].target, sizeof(WICPixelFormatGUID) ); format = _WICToDXGI( g_WICConvert[i].target ); assert( format != DXGI_FORMAT_UNKNOWN ); break; } } } } // Handle special cases based on flags switch (format) { case DXGI_FORMAT_B8G8R8A8_UNORM: // BGRA case DXGI_FORMAT_B8G8R8X8_UNORM: // BGRX if ( flags & WIC_FLAGS_FORCE_RGB ) { format = DXGI_FORMAT_R8G8B8A8_UNORM; if ( pConvert ) memcpy( pConvert, &GUID_WICPixelFormat32bppRGBA, sizeof(WICPixelFormatGUID) ); } break; case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM: if ( flags & WIC_FLAGS_NO_X2_BIAS ) { format = DXGI_FORMAT_R10G10B10A2_UNORM; if ( pConvert ) memcpy( pConvert, &GUID_WICPixelFormat32bppRGBA1010102, sizeof(WICPixelFormatGUID) ); } break; case DXGI_FORMAT_B5G5R5A1_UNORM: case DXGI_FORMAT_B5G6R5_UNORM: if ( flags & WIC_FLAGS_NO_16BPP ) { format = DXGI_FORMAT_R8G8B8A8_UNORM; if ( pConvert ) memcpy( pConvert, &GUID_WICPixelFormat32bppRGBA, sizeof(WICPixelFormatGUID) ); } break; case DXGI_FORMAT_R1_UNORM: if ( !(flags & WIC_FLAGS_ALLOW_MONO ) ) { // By default we want to promote a black & white to gresycale since R1 is not a generally supported D3D format format = DXGI_FORMAT_R8_UNORM; if ( pConvert ) memcpy( pConvert, &GUID_WICPixelFormat8bppGray, sizeof(WICPixelFormatGUID) ); } } return format; } //------------------------------------------------------------------------------------- // Determines metadata for image //------------------------------------------------------------------------------------- static HRESULT _DecodeMetadata( _In_ DWORD flags, _In_ IWICBitmapDecoder *decoder, _In_ IWICBitmapFrameDecode *frame, _Out_ TexMetadata& metadata, _Out_opt_ WICPixelFormatGUID* pConvert ) { if ( !decoder || !frame ) return E_POINTER; memset( &metadata, 0, sizeof(TexMetadata) ); metadata.depth = 1; metadata.mipLevels = 1; metadata.dimension = TEX_DIMENSION_TEXTURE2D; UINT w, h; HRESULT hr = frame->GetSize( &w, &h ); if ( FAILED(hr) ) return hr; metadata.width = w; metadata.height = h; if ( flags & WIC_FLAGS_ALL_FRAMES ) { UINT fcount; hr = decoder->GetFrameCount( &fcount ); if ( FAILED(hr) ) return hr; metadata.arraySize = fcount; } else metadata.arraySize = 1; WICPixelFormatGUID pixelFormat; hr = frame->GetPixelFormat( &pixelFormat ); if ( FAILED(hr) ) return hr; metadata.format = _DetermineFormat( pixelFormat, flags, pConvert ); if ( metadata.format == DXGI_FORMAT_UNKNOWN ) return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); if ( !( flags & WIC_FLAGS_IGNORE_SRGB ) ) { GUID containerFormat; hr = decoder->GetContainerFormat( &containerFormat ); if ( FAILED(hr) ) return hr; ComPtr metareader; hr = frame->GetMetadataQueryReader( metareader.GetAddressOf() ); if ( SUCCEEDED(hr) ) { // Check for sRGB colorspace metadata bool sRGB = false; PROPVARIANT value; PropVariantInit( &value ); if ( memcmp( &containerFormat, &GUID_ContainerFormatPng, sizeof(GUID) ) == 0 ) { // Check for sRGB chunk if ( SUCCEEDED( metareader->GetMetadataByName( L"/sRGB/RenderingIntent", &value ) ) && value.vt == VT_UI1 ) { sRGB = true; } } #if defined(_XBOX_ONE) && defined(_TITLE) else if ( memcmp( &containerFormat, &GUID_ContainerFormatJpeg, sizeof(GUID) ) == 0 ) { if ( SUCCEEDED( metareader->GetMetadataByName( L"/app1/ifd/exif/{ushort=40961}", &value ) ) && value.vt == VT_UI2 && value.uiVal == 1 ) { sRGB = true; } } else if ( memcmp( &containerFormat, &GUID_ContainerFormatTiff, sizeof(GUID) ) == 0 ) { if ( SUCCEEDED( metareader->GetMetadataByName( L"/ifd/exif/{ushort=40961}", &value ) ) && value.vt == VT_UI2 && value.uiVal == 1 ) { sRGB = true; } } #else else if ( SUCCEEDED( metareader->GetMetadataByName( L"System.Image.ColorSpace", &value ) ) && value.vt == VT_UI2 && value.uiVal == 1 ) { sRGB = true; } #endif PropVariantClear( &value ); if ( sRGB ) metadata.format = MakeSRGB( metadata.format ); } else if ( hr == WINCODEC_ERR_UNSUPPORTEDOPERATION ) { // Some formats just don't support metadata (BMP, ICO, etc.), so ignore this failure hr = S_OK; } } return hr; } //------------------------------------------------------------------------------------- // Decodes a single frame //------------------------------------------------------------------------------------- static HRESULT _DecodeSingleFrame( _In_ DWORD flags, _In_ const TexMetadata& metadata, _In_ const WICPixelFormatGUID& convertGUID, _In_ IWICBitmapFrameDecode *frame, _Inout_ ScratchImage& image ) { if ( !frame ) return E_POINTER; HRESULT hr = image.Initialize2D( metadata.format, metadata.width, metadata.height, 1, 1 ); if ( FAILED(hr) ) return hr; const Image *img = image.GetImage( 0, 0, 0 ); if ( !img ) return E_POINTER; IWICImagingFactory* pWIC = _GetWIC(); if ( !pWIC ) return E_NOINTERFACE; if ( memcmp( &convertGUID, &GUID_NULL, sizeof(GUID) ) == 0 ) { hr = frame->CopyPixels( 0, static_cast( img->rowPitch ), static_cast( img->slicePitch ), img->pixels ); if ( FAILED(hr) ) return hr; } else { ComPtr FC; hr = pWIC->CreateFormatConverter( FC.GetAddressOf() ); if ( FAILED(hr) ) return hr; WICPixelFormatGUID pixelFormat; hr = frame->GetPixelFormat( &pixelFormat ); if ( FAILED(hr) ) return hr; BOOL canConvert = FALSE; hr = FC->CanConvert( pixelFormat, convertGUID, &canConvert ); if ( FAILED(hr) || !canConvert ) { return E_UNEXPECTED; } hr = FC->Initialize( frame, convertGUID, _GetWICDither( flags ), 0, 0, WICBitmapPaletteTypeCustom ); if ( FAILED(hr) ) return hr; hr = FC->CopyPixels( 0, static_cast( img->rowPitch ), static_cast( img->slicePitch ), img->pixels ); if ( FAILED(hr) ) return hr; } return S_OK; } //------------------------------------------------------------------------------------- // Decodes an image array, resizing/format converting as needed //------------------------------------------------------------------------------------- static HRESULT _DecodeMultiframe( _In_ DWORD flags, _In_ const TexMetadata& metadata, _In_ IWICBitmapDecoder *decoder, _Inout_ ScratchImage& image ) { if ( !decoder ) return E_POINTER; HRESULT hr = image.Initialize2D( metadata.format, metadata.width, metadata.height, metadata.arraySize, 1 ); if ( FAILED(hr) ) return hr; IWICImagingFactory* pWIC = _GetWIC(); if ( !pWIC ) return E_NOINTERFACE; WICPixelFormatGUID sourceGUID; if ( !_DXGIToWIC( metadata.format, sourceGUID ) ) return E_FAIL; for( size_t index = 0; index < metadata.arraySize; ++index ) { const Image* img = image.GetImage( 0, index, 0 ); if ( !img ) return E_POINTER; ComPtr frame; hr = decoder->GetFrame( static_cast( index ), frame.GetAddressOf() ); if ( FAILED(hr) ) return hr; WICPixelFormatGUID pfGuid; hr = frame->GetPixelFormat( &pfGuid ); if ( FAILED(hr) ) return hr; UINT w, h; hr = frame->GetSize( &w, &h ); if ( FAILED(hr) ) return hr; if ( w == metadata.width && h == metadata.height ) { // This frame does not need resized if ( memcmp( &pfGuid, &sourceGUID, sizeof(WICPixelFormatGUID) ) == 0 ) { hr = frame->CopyPixels( 0, static_cast( img->rowPitch ), static_cast( img->slicePitch ), img->pixels ); if ( FAILED(hr) ) return hr; } else { ComPtr FC; hr = pWIC->CreateFormatConverter( FC.GetAddressOf() ); if ( FAILED(hr) ) return hr; BOOL canConvert = FALSE; hr = FC->CanConvert( pfGuid, sourceGUID, &canConvert ); if ( FAILED(hr) || !canConvert ) { return E_UNEXPECTED; } hr = FC->Initialize( frame.Get(), sourceGUID, _GetWICDither( flags ), 0, 0, WICBitmapPaletteTypeCustom ); if ( FAILED(hr) ) return hr; hr = FC->CopyPixels( 0, static_cast( img->rowPitch ), static_cast( img->slicePitch ), img->pixels ); if ( FAILED(hr) ) return hr; } } else { // This frame needs resizing ComPtr scaler; hr = pWIC->CreateBitmapScaler( scaler.GetAddressOf() ); if ( FAILED(hr) ) return hr; hr = scaler->Initialize( frame.Get(), static_cast( metadata.width ), static_cast( metadata.height ), _GetWICInterp( flags ) ); if ( FAILED(hr) ) return hr; WICPixelFormatGUID pfScaler; hr = scaler->GetPixelFormat( &pfScaler ); if ( FAILED(hr) ) return hr; if ( memcmp( &pfScaler, &sourceGUID, sizeof(WICPixelFormatGUID) ) == 0 ) { hr = scaler->CopyPixels( 0, static_cast( img->rowPitch ), static_cast( img->slicePitch ), img->pixels ); if ( FAILED(hr) ) return hr; } else { // The WIC bitmap scaler is free to return a different pixel format than the source image, so here we // convert it to our desired format ComPtr FC; hr = pWIC->CreateFormatConverter( FC.GetAddressOf() ); if ( FAILED(hr) ) return hr; BOOL canConvert = FALSE; hr = FC->CanConvert( pfScaler, sourceGUID, &canConvert ); if ( FAILED(hr) || !canConvert ) { return E_UNEXPECTED; } hr = FC->Initialize( scaler.Get(), sourceGUID, _GetWICDither( flags ), 0, 0, WICBitmapPaletteTypeCustom ); if ( FAILED(hr) ) return hr; hr = FC->CopyPixels( 0, static_cast( img->rowPitch ), static_cast( img->slicePitch ), img->pixels ); if ( FAILED(hr) ) return hr; } } } return S_OK; } //------------------------------------------------------------------------------------- // Encodes image metadata //------------------------------------------------------------------------------------- static HRESULT _EncodeMetadata( _In_ IWICBitmapFrameEncode* frame, _In_ const GUID& containerFormat, _In_ DXGI_FORMAT format ) { if ( !frame ) return E_POINTER; ComPtr metawriter; HRESULT hr = frame->GetMetadataQueryWriter( metawriter.GetAddressOf() ); if ( SUCCEEDED( hr ) ) { PROPVARIANT value; PropVariantInit( &value ); bool sRGB = IsSRGB( format ); value.vt = VT_LPSTR; value.pszVal = "DirectXTex"; if ( memcmp( &containerFormat, &GUID_ContainerFormatPng, sizeof(GUID) ) == 0 ) { // Set Software name (void)metawriter->SetMetadataByName( L"/tEXt/{str=Software}", &value ); // Set sRGB chunk if ( sRGB ) { value.vt = VT_UI1; value.bVal = 0; (void)metawriter->SetMetadataByName( L"/sRGB/RenderingIntent", &value ); } } #if defined(_XBOX_ONE) && defined(_TITLE) else if ( memcmp( &containerFormat, &GUID_ContainerFormatJpeg, sizeof(GUID) ) == 0 ) { // Set Software name (void)metawriter->SetMetadataByName( L"/app1/ifd/{ushort=305}", &value ); if ( sRGB ) { // Set EXIF Colorspace of sRGB value.vt = VT_UI2; value.uiVal = 1; (void)metawriter->SetMetadataByName( L"/app1/ifd/exif/{ushort=40961}", &value ); } } else if ( memcmp( &containerFormat, &GUID_ContainerFormatTiff, sizeof(GUID) ) == 0 ) { // Set Software name (void)metawriter->SetMetadataByName( L"/ifd/{ushort=305}", &value ); if ( sRGB ) { // Set EXIF Colorspace of sRGB value.vt = VT_UI2; value.uiVal = 1; (void)metawriter->SetMetadataByName( L"/ifd/exif/{ushort=40961}", &value ); } } #else else { // Set Software name (void)metawriter->SetMetadataByName( L"System.ApplicationName", &value ); if ( sRGB ) { // Set EXIF Colorspace of sRGB value.vt = VT_UI2; value.uiVal = 1; (void)metawriter->SetMetadataByName( L"System.Image.ColorSpace", &value ); } } #endif } else if ( hr == WINCODEC_ERR_UNSUPPORTEDOPERATION ) { // Some formats just don't support metadata (BMP, ICO, etc.), so ignore this failure hr = S_OK; } return hr; } //------------------------------------------------------------------------------------- // Encodes a single frame //------------------------------------------------------------------------------------- static HRESULT _EncodeImage( _In_ const Image& image, _In_ DWORD flags, _In_ REFGUID containerFormat, _In_ IWICBitmapFrameEncode* frame, _In_opt_ IPropertyBag2* props, _In_opt_ const GUID* targetFormat ) { if ( !frame ) return E_INVALIDARG; if ( !image.pixels ) return E_POINTER; WICPixelFormatGUID pfGuid; if ( !_DXGIToWIC( image.format, pfGuid ) ) return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); HRESULT hr = frame->Initialize( props ); if ( FAILED(hr) ) return hr; #ifdef _M_X64 if ( (image.width > 0xFFFFFFFF) || (image.height > 0xFFFFFFFF) ) return E_INVALIDARG; #endif hr = frame->SetSize( static_cast( image.width ), static_cast( image.height ) ); if ( FAILED(hr) ) return hr; hr = frame->SetResolution( 72, 72 ); if ( FAILED(hr) ) return hr; WICPixelFormatGUID targetGuid = (targetFormat) ? (*targetFormat) : pfGuid; hr = frame->SetPixelFormat( &targetGuid ); if ( FAILED(hr) ) return hr; if ( targetFormat && memcmp( targetFormat, &targetGuid, sizeof(WICPixelFormatGUID) ) != 0 ) { // Requested output pixel format is not supported by the WIC codec return E_FAIL; } hr = _EncodeMetadata( frame, containerFormat, image.format ); if ( FAILED(hr) ) return hr; if ( memcmp( &targetGuid, &pfGuid, sizeof(WICPixelFormatGUID) ) != 0 ) { // Conversion required to write IWICImagingFactory* pWIC = _GetWIC(); if ( !pWIC ) return E_NOINTERFACE; ComPtr source; hr = pWIC->CreateBitmapFromMemory( static_cast( image.width ), static_cast( image.height ), pfGuid, static_cast( image.rowPitch ), static_cast( image.slicePitch ), image.pixels, source.GetAddressOf() ); if ( FAILED(hr) ) return hr; ComPtr FC; hr = pWIC->CreateFormatConverter( FC.GetAddressOf() ); if ( FAILED(hr) ) return hr; BOOL canConvert = FALSE; hr = FC->CanConvert( pfGuid, targetGuid, &canConvert ); if ( FAILED(hr) || !canConvert ) { return E_UNEXPECTED; } hr = FC->Initialize( source.Get(), targetGuid, _GetWICDither( flags ), 0, 0, WICBitmapPaletteTypeCustom ); if ( FAILED(hr) ) return hr; WICRect rect = { 0, 0, static_cast( image.width ), static_cast( image.height ) }; hr = frame->WriteSource( FC.Get(), &rect ); if ( FAILED(hr) ) return hr; } else { // No conversion required hr = frame->WritePixels( static_cast( image.height ), static_cast( image.rowPitch ), static_cast( image.slicePitch ), reinterpret_cast( image.pixels ) ); if ( FAILED(hr) ) return hr; } hr = frame->Commit(); if ( FAILED(hr) ) return hr; return S_OK; } static HRESULT _EncodeSingleFrame( _In_ const Image& image, _In_ DWORD flags, _In_ REFGUID containerFormat, _Inout_ IStream* stream, _In_opt_ const GUID* targetFormat, _In_opt_ std::function setCustomProps ) { if ( !stream ) return E_INVALIDARG; // Initialize WIC IWICImagingFactory* pWIC = _GetWIC(); if ( !pWIC ) return E_NOINTERFACE; ComPtr encoder; HRESULT hr = pWIC->CreateEncoder( containerFormat, 0, encoder.GetAddressOf() ); if ( FAILED(hr) ) return hr; hr = encoder->Initialize( stream, WICBitmapEncoderNoCache ); if ( FAILED(hr) ) return hr; ComPtr frame; ComPtr props; hr = encoder->CreateNewFrame( frame.GetAddressOf(), props.GetAddressOf() ); if ( FAILED(hr) ) return hr; if ( memcmp( &containerFormat, &GUID_ContainerFormatBmp, sizeof(WICPixelFormatGUID) ) == 0 && _IsWIC2() ) { // Opt-in to the WIC2 support for writing 32-bit Windows BMP files with an alpha channel PROPBAG2 option = { 0 }; option.pstrName = L"EnableV5Header32bppBGRA"; VARIANT varValue; varValue.vt = VT_BOOL; varValue.boolVal = VARIANT_TRUE; (void)props->Write( 1, &option, &varValue ); } if ( setCustomProps ) { setCustomProps( props.Get() ); } hr = _EncodeImage( image, flags, containerFormat, frame.Get(), props.Get(), targetFormat ); if ( FAILED(hr) ) return hr; hr = encoder->Commit(); if ( FAILED(hr) ) return hr; return S_OK; } //------------------------------------------------------------------------------------- // Encodes an image array //------------------------------------------------------------------------------------- static HRESULT _EncodeMultiframe( _In_reads_(nimages) const Image* images, _In_ size_t nimages, _In_ DWORD flags, _In_ REFGUID containerFormat, _Inout_ IStream* stream, _In_opt_ const GUID* targetFormat, _In_opt_ std::function setCustomProps ) { if ( !stream || nimages < 2 ) return E_INVALIDARG; if ( !images ) return E_POINTER; // Initialize WIC IWICImagingFactory* pWIC = _GetWIC(); if ( !pWIC ) return E_NOINTERFACE; ComPtr encoder; HRESULT hr = pWIC->CreateEncoder( containerFormat, 0, encoder.GetAddressOf() ); if ( FAILED(hr) ) return hr; ComPtr einfo; hr = encoder->GetEncoderInfo( einfo.GetAddressOf() ); if ( FAILED(hr) ) return hr; BOOL mframe = FALSE; hr = einfo->DoesSupportMultiframe( &mframe ); if ( FAILED(hr) ) return hr; if ( !mframe ) return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); hr = encoder->Initialize( stream, WICBitmapEncoderNoCache ); if ( FAILED(hr) ) return hr; for( size_t index=0; index < nimages; ++index ) { ComPtr frame; ComPtr props; hr = encoder->CreateNewFrame( frame.GetAddressOf(), props.GetAddressOf() ); if ( FAILED(hr) ) return hr; if ( setCustomProps ) { setCustomProps( props.Get() ); } hr = _EncodeImage( images[index], flags, containerFormat, frame.Get(), props.Get(), targetFormat ); if ( FAILED(hr) ) return hr; } hr = encoder->Commit(); if ( FAILED(hr) ) return hr; return S_OK; } //===================================================================================== // Entry-points //===================================================================================== //------------------------------------------------------------------------------------- // Obtain metadata from WIC-supported file in memory //------------------------------------------------------------------------------------- _Use_decl_annotations_ HRESULT GetMetadataFromWICMemory( LPCVOID pSource, size_t size, DWORD flags, TexMetadata& metadata ) { if ( !pSource || size == 0 ) return E_INVALIDARG; #ifdef _M_X64 if ( size > 0xFFFFFFFF ) return HRESULT_FROM_WIN32( ERROR_FILE_TOO_LARGE ); #endif IWICImagingFactory* pWIC = _GetWIC(); if ( !pWIC ) return E_NOINTERFACE; // Create input stream for memory ComPtr stream; HRESULT hr = pWIC->CreateStream( stream.GetAddressOf() ); if ( FAILED(hr) ) return hr; hr = stream->InitializeFromMemory( reinterpret_cast( const_cast( pSource ) ), static_cast( size ) ); if ( FAILED(hr) ) return hr; // Initialize WIC ComPtr decoder; hr = pWIC->CreateDecoderFromStream( stream.Get(), 0, WICDecodeMetadataCacheOnDemand, decoder.GetAddressOf() ); if ( FAILED(hr) ) return hr; ComPtr frame; hr = decoder->GetFrame( 0, frame.GetAddressOf() ); if ( FAILED(hr) ) return hr; // Get metadata hr = _DecodeMetadata( flags, decoder.Get(), frame.Get(), metadata, 0 ); if ( FAILED(hr) ) return hr; return S_OK; } //------------------------------------------------------------------------------------- // Obtain metadata from WIC-supported file on disk //------------------------------------------------------------------------------------- _Use_decl_annotations_ HRESULT GetMetadataFromWICFile( LPCWSTR szFile, DWORD flags, TexMetadata& metadata ) { if ( !szFile ) return E_INVALIDARG; IWICImagingFactory* pWIC = _GetWIC(); if ( !pWIC ) return E_NOINTERFACE; // Initialize WIC ComPtr decoder; HRESULT hr = pWIC->CreateDecoderFromFilename( szFile, 0, GENERIC_READ, WICDecodeMetadataCacheOnDemand, decoder.GetAddressOf() ); if ( FAILED(hr) ) return hr; ComPtr frame; hr = decoder->GetFrame( 0, frame.GetAddressOf() ); if ( FAILED(hr) ) return hr; // Get metadata hr = _DecodeMetadata( flags, decoder.Get(), frame.Get(), metadata, 0 ); if ( FAILED(hr) ) return hr; return S_OK; } //------------------------------------------------------------------------------------- // Load a WIC-supported file in memory //------------------------------------------------------------------------------------- _Use_decl_annotations_ HRESULT LoadFromWICMemory( LPCVOID pSource, size_t size, DWORD flags, TexMetadata* metadata, ScratchImage& image ) { if ( !pSource || size == 0 ) return E_INVALIDARG; #ifdef _M_X64 if ( size > 0xFFFFFFFF ) return HRESULT_FROM_WIN32( ERROR_FILE_TOO_LARGE ); #endif IWICImagingFactory* pWIC = _GetWIC(); if ( !pWIC ) return E_NOINTERFACE; image.Release(); // Create input stream for memory ComPtr stream; HRESULT hr = pWIC->CreateStream( stream.GetAddressOf() ); if ( FAILED(hr) ) return hr; hr = stream->InitializeFromMemory( reinterpret_cast( const_cast( pSource ) ), static_cast( size ) ); if ( FAILED(hr) ) return hr; // Initialize WIC ComPtr decoder; hr = pWIC->CreateDecoderFromStream( stream.Get(), 0, WICDecodeMetadataCacheOnDemand, decoder.GetAddressOf() ); if ( FAILED(hr) ) return hr; ComPtr frame; hr = decoder->GetFrame( 0, frame.GetAddressOf() ); if ( FAILED(hr) ) return hr; // Get metadata TexMetadata mdata; WICPixelFormatGUID convertGUID = {0}; hr = _DecodeMetadata( flags, decoder.Get(), frame.Get(), mdata, &convertGUID ); if ( FAILED(hr) ) return hr; if ( (mdata.arraySize > 1) && (flags & WIC_FLAGS_ALL_FRAMES) ) { hr = _DecodeMultiframe( flags, mdata, decoder.Get(), image ); } else { hr = _DecodeSingleFrame( flags, mdata, convertGUID, frame.Get(), image ); } if ( FAILED(hr) ) { image.Release(); return hr; } if ( metadata ) memcpy( metadata, &mdata, sizeof(TexMetadata) ); return S_OK; } //------------------------------------------------------------------------------------- // Load a WIC-supported file from disk //------------------------------------------------------------------------------------- _Use_decl_annotations_ HRESULT LoadFromWICFile( LPCWSTR szFile, DWORD flags, TexMetadata* metadata, ScratchImage& image ) { if ( !szFile ) return E_INVALIDARG; IWICImagingFactory* pWIC = _GetWIC(); if ( !pWIC ) return E_NOINTERFACE; image.Release(); // Initialize WIC ComPtr decoder; HRESULT hr = pWIC->CreateDecoderFromFilename( szFile, 0, GENERIC_READ, WICDecodeMetadataCacheOnDemand, decoder.GetAddressOf() ); if ( FAILED(hr) ) return hr; ComPtr frame; hr = decoder->GetFrame( 0, frame.GetAddressOf() ); if ( FAILED(hr) ) return hr; // Get metadata TexMetadata mdata; WICPixelFormatGUID convertGUID = {0}; hr = _DecodeMetadata( flags, decoder.Get(), frame.Get(), mdata, &convertGUID ); if ( FAILED(hr) ) return hr; if ( (mdata.arraySize > 1) && (flags & WIC_FLAGS_ALL_FRAMES) ) { hr = _DecodeMultiframe( flags, mdata, decoder.Get(), image ); } else { hr = _DecodeSingleFrame( flags, mdata, convertGUID, frame.Get(), image ); } if ( FAILED(hr) ) { image.Release(); return hr; } if ( metadata ) memcpy( metadata, &mdata, sizeof(TexMetadata) ); return S_OK; } //------------------------------------------------------------------------------------- // Save a WIC-supported file to memory //------------------------------------------------------------------------------------- _Use_decl_annotations_ HRESULT SaveToWICMemory( const Image& image, DWORD flags, REFGUID containerFormat, Blob& blob, const GUID* targetFormat, std::function setCustomProps ) { if ( !image.pixels ) return E_POINTER; blob.Release(); ComPtr stream; HRESULT hr = CreateMemoryStream( stream.GetAddressOf() ); if ( FAILED(hr) ) return hr; hr = _EncodeSingleFrame( image, flags, containerFormat, stream.Get(), targetFormat, setCustomProps ); if ( FAILED(hr) ) return hr; // Copy stream data into blob STATSTG stat; hr = stream->Stat( &stat, STATFLAG_NONAME ); if ( FAILED(hr) ) return hr; if ( stat.cbSize.HighPart > 0 ) return HRESULT_FROM_WIN32( ERROR_FILE_TOO_LARGE ); hr = blob.Initialize( stat.cbSize.LowPart ); if ( FAILED(hr) ) return hr; LARGE_INTEGER li = { 0 }; hr = stream->Seek( li, STREAM_SEEK_SET, 0 ); if ( FAILED(hr) ) return hr; DWORD bytesRead; hr = stream->Read( blob.GetBufferPointer(), static_cast( blob.GetBufferSize() ), &bytesRead ); if ( FAILED(hr) ) return hr; if ( bytesRead != blob.GetBufferSize() ) return E_FAIL; return S_OK; } _Use_decl_annotations_ HRESULT SaveToWICMemory( const Image* images, size_t nimages, DWORD flags, REFGUID containerFormat, Blob& blob, const GUID* targetFormat, std::function setCustomProps ) { if ( !images || nimages == 0 ) return E_INVALIDARG; blob.Release(); ComPtr stream; HRESULT hr = CreateMemoryStream( stream.GetAddressOf() ); if ( FAILED(hr) ) return hr; if ( nimages > 1 ) hr = _EncodeMultiframe( images, nimages, flags, containerFormat, stream.Get(), targetFormat, setCustomProps ); else hr = _EncodeSingleFrame( images[0], flags, containerFormat, stream.Get(), targetFormat, setCustomProps ); if ( FAILED(hr) ) return hr; // Copy stream data into blob STATSTG stat; hr = stream->Stat( &stat, STATFLAG_NONAME ); if ( FAILED(hr) ) return hr; if ( stat.cbSize.HighPart > 0 ) return HRESULT_FROM_WIN32( ERROR_FILE_TOO_LARGE ); hr = blob.Initialize( stat.cbSize.LowPart ); if ( FAILED(hr) ) return hr; LARGE_INTEGER li = { 0 }; hr = stream->Seek( li, STREAM_SEEK_SET, 0 ); if ( FAILED(hr) ) return hr; DWORD bytesRead; hr = stream->Read( blob.GetBufferPointer(), static_cast( blob.GetBufferSize() ), &bytesRead ); if ( FAILED(hr) ) return hr; if ( bytesRead != blob.GetBufferSize() ) return E_FAIL; return S_OK; } //------------------------------------------------------------------------------------- // Save a WIC-supported file to disk //------------------------------------------------------------------------------------- _Use_decl_annotations_ HRESULT SaveToWICFile( const Image& image, DWORD flags, REFGUID containerFormat, LPCWSTR szFile, const GUID* targetFormat, std::function setCustomProps ) { if ( !szFile ) return E_INVALIDARG; if ( !image.pixels ) return E_POINTER; IWICImagingFactory* pWIC = _GetWIC(); if ( !pWIC ) return E_NOINTERFACE; ComPtr stream; HRESULT hr = pWIC->CreateStream( stream.GetAddressOf() ); if ( FAILED(hr) ) return hr; hr = stream->InitializeFromFilename( szFile, GENERIC_WRITE ); if ( FAILED(hr) ) return hr; hr = _EncodeSingleFrame( image, flags, containerFormat, stream.Get(), targetFormat, setCustomProps ); if ( FAILED(hr) ) return hr; return S_OK; } _Use_decl_annotations_ HRESULT SaveToWICFile( const Image* images, size_t nimages, DWORD flags, REFGUID containerFormat, LPCWSTR szFile, const GUID* targetFormat, std::function setCustomProps ) { if ( !szFile || !images || nimages == 0 ) return E_INVALIDARG; IWICImagingFactory* pWIC = _GetWIC(); if ( !pWIC ) return E_NOINTERFACE; ComPtr stream; HRESULT hr = pWIC->CreateStream( stream.GetAddressOf() ); if ( FAILED(hr) ) return hr; hr = stream->InitializeFromFilename( szFile, GENERIC_WRITE ); if ( FAILED(hr) ) return hr; if ( nimages > 1 ) hr = _EncodeMultiframe( images, nimages, flags, containerFormat, stream.Get(), targetFormat, setCustomProps ); else hr = _EncodeSingleFrame( images[0], flags, containerFormat, stream.Get(), targetFormat, setCustomProps ); if ( FAILED(hr) ) return hr; return S_OK; } }; // namespace ================================================ FILE: 3rdParty/DirectXTex/DirectXTex/DirectXTex_Desktop_2012.sln ================================================ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 2012 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DirectXTex", "DirectXTex_Desktop_2012.vcxproj", "{371B9FA9-4C90-4AC6-A123-ACED756D6C77}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Debug|x64 = Debug|x64 Profile|Win32 = Profile|Win32 Profile|x64 = Profile|x64 Release|Win32 = Release|Win32 Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Debug|Win32.ActiveCfg = Debug|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Debug|Win32.Build.0 = Debug|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Debug|x64.ActiveCfg = Debug|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Debug|x64.Build.0 = Debug|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Profile|Win32.ActiveCfg = Profile|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Profile|Win32.Build.0 = Profile|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Profile|x64.ActiveCfg = Profile|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Profile|x64.Build.0 = Profile|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Release|Win32.ActiveCfg = Release|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Release|Win32.Build.0 = Release|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Release|x64.ActiveCfg = Release|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal ================================================ FILE: 3rdParty/DirectXTex/DirectXTex/DirectXTex_Desktop_2012.vcxproj ================================================  Debug Win32 Debug x64 Profile Win32 Profile x64 Release Win32 Release x64 DirectXTex {371B9FA9-4C90-4AC6-A123-ACED756D6C77} DirectXTex Win32Proj $(VCTargetsPath11) StaticLibrary Unicode v110 StaticLibrary Unicode v110 StaticLibrary Unicode v110 StaticLibrary Unicode v110 StaticLibrary Unicode v110 StaticLibrary Unicode v110 Bin\Desktop_2012\$(Platform)\$(Configuration)\ Bin\Desktop_2012\$(Platform)\$(Configuration)\ DirectXTex true true Bin\Desktop_2012\$(Platform)\$(Configuration)\ Bin\Desktop_2012\$(Platform)\$(Configuration)\ DirectXTex true true Bin\Desktop_2012\$(Platform)\$(Configuration)\ Bin\Desktop_2012\$(Platform)\$(Configuration)\ DirectXTex false true Bin\Desktop_2012\$(Platform)\$(Configuration)\ Bin\Desktop_2012\$(Platform)\$(Configuration)\ DirectXTex false true Bin\Desktop_2012\$(Platform)\$(Configuration)\ Bin\Desktop_2012\$(Platform)\$(Configuration)\ DirectXTex false true Bin\Desktop_2012\$(Platform)\$(Configuration)\ Bin\Desktop_2012\$(Platform)\$(Configuration)\ DirectXTex false true Level4 Disabled MultiThreadedDebug true Fast StreamingSIMDExtensions2 Sync %(AdditionalOptions) _UNICODE;UNICODE;WIN32;_DEBUG;_LIB;_WIN7_PLATFORM_UPDATE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions) EditAndContinue EnableFastChecks Use DirectXTexP.h $(IntDir)$(TargetName).pdb %(AdditionalOptions) %(AdditionalDependencies) Windows true true true true MachineX86 AsInvoker %(DelayLoadDLLs) false Level4 Disabled MultiThreadedDebug true Fast Sync %(AdditionalOptions) _UNICODE;UNICODE;WIN32;_DEBUG;_LIB;_WIN7_PLATFORM_UPDATE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions) EnableFastChecks Use DirectXTexP.h $(IntDir)$(TargetName).pdb %(AdditionalOptions) %(AdditionalDependencies) Windows true true true true MachineX64 AsInvoker %(DelayLoadDLLs) false Level4 MaxSpeed MultiThreaded true true Fast StreamingSIMDExtensions2 Sync %(AdditionalOptions) _UNICODE;UNICODE;WIN32;NDEBUG;_LIB;_WIN7_PLATFORM_UPDATE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions) Use DirectXTexP.h $(IntDir)$(TargetName).pdb %(AdditionalOptions) %(AdditionalDependencies) true Windows true true true true true MachineX86 AsInvoker %(DelayLoadDLLs) false Level4 MaxSpeed MultiThreaded true true Fast Sync %(AdditionalOptions) _UNICODE;UNICODE;WIN32;NDEBUG;_LIB;_WIN7_PLATFORM_UPDATE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions) Use DirectXTexP.h $(IntDir)$(TargetName).pdb %(AdditionalOptions) %(AdditionalDependencies) true Windows true true true true true MachineX64 AsInvoker %(DelayLoadDLLs) false Level4 MaxSpeed MultiThreadedDLL true true Fast StreamingSIMDExtensions2 Sync %(AdditionalOptions) _UNICODE;UNICODE;WIN32;NDEBUG;PROFILE;_LIB;_WIN7_PLATFORM_UPDATE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions) Use DirectXTexP.h $(IntDir)$(TargetName).pdb %(AdditionalOptions) %(AdditionalDependencies) true Windows true true true true true MachineX86 AsInvoker %(DelayLoadDLLs) false Level4 MaxSpeed MultiThreadedDLL true true Fast Sync %(AdditionalOptions) _UNICODE;UNICODE;WIN32;NDEBUG;PROFILE;_LIB;_WIN7_PLATFORM_UPDATE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions) Use DirectXTexP.h $(IntDir)$(TargetName).pdb %(AdditionalOptions) %(AdditionalDependencies) true Windows true true true true true MachineX64 AsInvoker %(DelayLoadDLLs) false Create Create Create Create Create Create ================================================ FILE: 3rdParty/DirectXTex/DirectXTex/DirectXTex_Desktop_2012.vcxproj.filters ================================================  {8e114980-c1a3-4ada-ad7c-83caadf5daeb} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe ================================================ FILE: 3rdParty/DirectXTex/DirectXTex/DirectXTex_Desktop_2013.sln ================================================ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 2013 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DirectXTex", "DirectXTex_Desktop_2013.vcxproj", "{371B9FA9-4C90-4AC6-A123-ACED756D6C77}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Debug|x64 = Debug|x64 Profile|Win32 = Profile|Win32 Profile|x64 = Profile|x64 Release|Win32 = Release|Win32 Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Debug|Win32.ActiveCfg = Debug|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Debug|Win32.Build.0 = Debug|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Debug|x64.ActiveCfg = Debug|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Debug|x64.Build.0 = Debug|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Profile|Win32.ActiveCfg = Profile|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Profile|Win32.Build.0 = Profile|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Profile|x64.ActiveCfg = Profile|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Profile|x64.Build.0 = Profile|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Release|Win32.ActiveCfg = Release|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Release|Win32.Build.0 = Release|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Release|x64.ActiveCfg = Release|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal ================================================ FILE: 3rdParty/DirectXTex/DirectXTex/DirectXTex_Desktop_2013.vcxproj ================================================  Debug Win32 Debug x64 Profile Win32 Profile x64 Release Win32 Release x64 DirectXTex {371B9FA9-4C90-4AC6-A123-ACED756D6C77} DirectXTex Win32Proj $(VCTargetsPath11) StaticLibrary Unicode v120 StaticLibrary Unicode v120 StaticLibrary Unicode v120 StaticLibrary Unicode v120 StaticLibrary Unicode v120 StaticLibrary Unicode v120 Bin\Desktop_2013\$(Platform)\$(Configuration)\ Bin\Desktop_2013\$(Platform)\$(Configuration)\ DirectXTex true true Bin\Desktop_2013\$(Platform)\$(Configuration)\ Bin\Desktop_2013\$(Platform)\$(Configuration)\ DirectXTex true true Bin\Desktop_2013\$(Platform)\$(Configuration)\ Bin\Desktop_2013\$(Platform)\$(Configuration)\ DirectXTex false true Bin\Desktop_2013\$(Platform)\$(Configuration)\ Bin\Desktop_2013\$(Platform)\$(Configuration)\ DirectXTex false true Bin\Desktop_2013\$(Platform)\$(Configuration)\ Bin\Desktop_2013\$(Platform)\$(Configuration)\ DirectXTex false true Bin\Desktop_2013\$(Platform)\$(Configuration)\ Bin\Desktop_2013\$(Platform)\$(Configuration)\ DirectXTex false true Level4 Disabled MultiThreadedDebugDLL true true Fast StreamingSIMDExtensions2 Sync %(AdditionalOptions) _UNICODE;UNICODE;WIN32;_DEBUG;_LIB;_WIN7_PLATFORM_UPDATE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions) EditAndContinue EnableFastChecks Use DirectXTexP.h $(IntDir)$(TargetName).pdb %(AdditionalOptions) %(AdditionalDependencies) Windows true true true true MachineX86 AsInvoker %(DelayLoadDLLs) false Level4 Disabled MultiThreadedDebugDLL true true Fast Sync %(AdditionalOptions) _UNICODE;UNICODE;WIN32;_DEBUG;_LIB;_WIN7_PLATFORM_UPDATE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions) EnableFastChecks Use DirectXTexP.h $(IntDir)$(TargetName).pdb %(AdditionalOptions) %(AdditionalDependencies) Windows true true true true MachineX64 AsInvoker %(DelayLoadDLLs) false Level4 MaxSpeed MultiThreadedDLL true true true Fast StreamingSIMDExtensions2 Sync %(AdditionalOptions) _UNICODE;UNICODE;WIN32;NDEBUG;_LIB;_WIN7_PLATFORM_UPDATE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions) Use DirectXTexP.h $(IntDir)$(TargetName).pdb %(AdditionalOptions) %(AdditionalDependencies) true Windows true true true true true MachineX86 AsInvoker %(DelayLoadDLLs) false Level4 MaxSpeed MultiThreadedDLL true true true Fast Sync %(AdditionalOptions) _UNICODE;UNICODE;WIN32;NDEBUG;_LIB;_WIN7_PLATFORM_UPDATE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions) Use DirectXTexP.h $(IntDir)$(TargetName).pdb %(AdditionalOptions) %(AdditionalDependencies) true Windows true true true true true MachineX64 AsInvoker %(DelayLoadDLLs) false Level4 MaxSpeed MultiThreadedDLL true true true Fast StreamingSIMDExtensions2 Sync %(AdditionalOptions) _UNICODE;UNICODE;WIN32;NDEBUG;PROFILE;_LIB;_WIN7_PLATFORM_UPDATE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions) Use DirectXTexP.h $(IntDir)$(TargetName).pdb %(AdditionalOptions) %(AdditionalDependencies) true Windows true true true true true MachineX86 AsInvoker %(DelayLoadDLLs) false Level4 MaxSpeed MultiThreadedDLL true true true Fast Sync %(AdditionalOptions) _UNICODE;UNICODE;WIN32;NDEBUG;PROFILE;_LIB;_WIN7_PLATFORM_UPDATE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions) Use DirectXTexP.h $(IntDir)$(TargetName).pdb %(AdditionalOptions) %(AdditionalDependencies) true Windows true true true true true MachineX64 AsInvoker %(DelayLoadDLLs) false Create Create Create Create Create Create ================================================ FILE: 3rdParty/DirectXTex/DirectXTex/DirectXTex_Desktop_2013.vcxproj.filters ================================================  {8e114980-c1a3-4ada-ad7c-83caadf5daeb} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe ================================================ FILE: 3rdParty/DirectXTex/DirectXTex/DirectXTex_Desktop_2015.sln ================================================ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 2015 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DirectXTex", "DirectXTex_Desktop_2015.vcxproj", "{371B9FA9-4C90-4AC6-A123-ACED756D6C77}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Debug|x64 = Debug|x64 Profile|Win32 = Profile|Win32 Profile|x64 = Profile|x64 Release|Win32 = Release|Win32 Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Debug|Win32.ActiveCfg = Debug|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Debug|Win32.Build.0 = Debug|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Debug|x64.ActiveCfg = Debug|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Debug|x64.Build.0 = Debug|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Profile|Win32.ActiveCfg = Profile|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Profile|Win32.Build.0 = Profile|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Profile|x64.ActiveCfg = Profile|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Profile|x64.Build.0 = Profile|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Release|Win32.ActiveCfg = Release|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Release|Win32.Build.0 = Release|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Release|x64.ActiveCfg = Release|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal ================================================ FILE: 3rdParty/DirectXTex/DirectXTex/DirectXTex_Desktop_2015.vcxproj ================================================  Debug Win32 Debug x64 Profile Win32 Profile x64 Release Win32 Release x64 DirectXTex {371B9FA9-4C90-4AC6-A123-ACED756D6C77} DirectXTex Win32Proj StaticLibrary Unicode v140 StaticLibrary Unicode v140 StaticLibrary Unicode v140 StaticLibrary Unicode v140 StaticLibrary Unicode v140 StaticLibrary Unicode v140 Bin\Desktop_2015\$(Platform)\$(Configuration)\ Bin\Desktop_2015\$(Platform)\$(Configuration)\ DirectXTex true true Bin\Desktop_2015\$(Platform)\$(Configuration)\ Bin\Desktop_2015\$(Platform)\$(Configuration)\ DirectXTex true true Bin\Desktop_2015\$(Platform)\$(Configuration)\ Bin\Desktop_2015\$(Platform)\$(Configuration)\ DirectXTex false true Bin\Desktop_2015\$(Platform)\$(Configuration)\ Bin\Desktop_2015\$(Platform)\$(Configuration)\ DirectXTex false true Bin\Desktop_2015\$(Platform)\$(Configuration)\ Bin\Desktop_2015\$(Platform)\$(Configuration)\ DirectXTex false true Bin\Desktop_2015\$(Platform)\$(Configuration)\ Bin\Desktop_2015\$(Platform)\$(Configuration)\ DirectXTex false true Level4 Disabled MultiThreadedDebugDLL true true Fast StreamingSIMDExtensions2 Sync %(AdditionalOptions) _UNICODE;UNICODE;WIN32;_DEBUG;_LIB;_WIN7_PLATFORM_UPDATE;_WIN32_WINNT=0x0600;_CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS;%(PreprocessorDefinitions) EditAndContinue EnableFastChecks Use DirectXTexP.h $(IntDir)$(TargetName).pdb %(AdditionalOptions) %(AdditionalDependencies) Windows true true true true MachineX86 AsInvoker %(DelayLoadDLLs) false Level4 Disabled MultiThreadedDebugDLL true true Fast Sync %(AdditionalOptions) _UNICODE;UNICODE;WIN32;_DEBUG;_LIB;_WIN7_PLATFORM_UPDATE;_WIN32_WINNT=0x0600;_CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS;%(PreprocessorDefinitions) EnableFastChecks Use DirectXTexP.h $(IntDir)$(TargetName).pdb %(AdditionalOptions) %(AdditionalDependencies) Windows true true true true MachineX64 AsInvoker %(DelayLoadDLLs) false Level4 MaxSpeed MultiThreadedDLL true true true Fast StreamingSIMDExtensions2 Sync %(AdditionalOptions) _UNICODE;UNICODE;WIN32;NDEBUG;_LIB;_WIN7_PLATFORM_UPDATE;_WIN32_WINNT=0x0600;_CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS;%(PreprocessorDefinitions) Use DirectXTexP.h $(IntDir)$(TargetName).pdb %(AdditionalOptions) %(AdditionalDependencies) true Windows true true true true true MachineX86 AsInvoker %(DelayLoadDLLs) false Level4 MaxSpeed MultiThreadedDLL true true true Fast Sync %(AdditionalOptions) _UNICODE;UNICODE;WIN32;NDEBUG;_LIB;_WIN7_PLATFORM_UPDATE;_WIN32_WINNT=0x0600;_CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS;%(PreprocessorDefinitions) Use DirectXTexP.h $(IntDir)$(TargetName).pdb %(AdditionalOptions) %(AdditionalDependencies) true Windows true true true true true MachineX64 AsInvoker %(DelayLoadDLLs) false Level4 MaxSpeed MultiThreadedDLL true true true Fast StreamingSIMDExtensions2 Sync %(AdditionalOptions) _UNICODE;UNICODE;WIN32;NDEBUG;PROFILE;_LIB;_WIN7_PLATFORM_UPDATE;_WIN32_WINNT=0x0600;_CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS;%(PreprocessorDefinitions) Use DirectXTexP.h $(IntDir)$(TargetName).pdb %(AdditionalOptions) %(AdditionalDependencies) true Windows true true true true true MachineX86 AsInvoker %(DelayLoadDLLs) false Level4 MaxSpeed MultiThreadedDLL true true true Fast Sync %(AdditionalOptions) _UNICODE;UNICODE;WIN32;NDEBUG;PROFILE;_LIB;_WIN7_PLATFORM_UPDATE;_WIN32_WINNT=0x0600;_CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS;%(PreprocessorDefinitions) Use DirectXTexP.h $(IntDir)$(TargetName).pdb %(AdditionalOptions) %(AdditionalDependencies) true Windows true true true true true MachineX64 AsInvoker %(DelayLoadDLLs) false Create Create Create Create Create Create ================================================ FILE: 3rdParty/DirectXTex/DirectXTex/DirectXTex_Desktop_2015.vcxproj.filters ================================================  {8e114980-c1a3-4ada-ad7c-83caadf5daeb} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe ================================================ FILE: 3rdParty/DirectXTex/DirectXTex/DirectXTex_Windows10.sln ================================================  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 2015 VisualStudioVersion = 14.0.22609.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DirectXTex", "DirectXTex_Windows10.vcxproj", "{FB3F52B5-BFE8-43FD-836F-363735DAB738}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|ARM = Debug|ARM Debug|x64 = Debug|x64 Debug|x86 = Debug|x86 Release|ARM = Release|ARM Release|x64 = Release|x64 Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {FB3F52B5-BFE8-43FD-836F-363735DAB738}.Debug|ARM.ActiveCfg = Debug|ARM {FB3F52B5-BFE8-43FD-836F-363735DAB738}.Debug|ARM.Build.0 = Debug|ARM {FB3F52B5-BFE8-43FD-836F-363735DAB738}.Debug|x64.ActiveCfg = Debug|x64 {FB3F52B5-BFE8-43FD-836F-363735DAB738}.Debug|x64.Build.0 = Debug|x64 {FB3F52B5-BFE8-43FD-836F-363735DAB738}.Debug|x86.ActiveCfg = Debug|Win32 {FB3F52B5-BFE8-43FD-836F-363735DAB738}.Debug|x86.Build.0 = Debug|Win32 {FB3F52B5-BFE8-43FD-836F-363735DAB738}.Release|ARM.ActiveCfg = Release|ARM {FB3F52B5-BFE8-43FD-836F-363735DAB738}.Release|ARM.Build.0 = Release|ARM {FB3F52B5-BFE8-43FD-836F-363735DAB738}.Release|x64.ActiveCfg = Release|x64 {FB3F52B5-BFE8-43FD-836F-363735DAB738}.Release|x64.Build.0 = Release|x64 {FB3F52B5-BFE8-43FD-836F-363735DAB738}.Release|x86.ActiveCfg = Release|Win32 {FB3F52B5-BFE8-43FD-836F-363735DAB738}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal ================================================ FILE: 3rdParty/DirectXTex/DirectXTex/DirectXTex_Windows10.vcxproj ================================================  Debug ARM Debug Win32 Debug x64 Release ARM Release Win32 Release x64 Create Create Create Create Create Create {fb3f52b5-bfe8-43fd-836f-363735dab738} StaticLibrary DirectXTex DirectXTex en-US 14.0 true Windows Store 10.0.10240.0 10.0.10240.0 10.0 StaticLibrary true v140 StaticLibrary true v140 StaticLibrary true v140 StaticLibrary false v140 StaticLibrary false v140 StaticLibrary false v140 Bin\Windows10\$(Platform)\$(Configuration)\ Bin\Windows10\$(Platform)\$(Configuration)\ DirectXTex false Bin\Windows10\$(Platform)\$(Configuration)\ Bin\Windows10\$(Platform)\$(Configuration)\ DirectXTex false Bin\Windows10\$(Platform)\$(Configuration)\ Bin\Windows10\$(Platform)\$(Configuration)\ DirectXTex false Bin\Windows10\$(Platform)\$(Configuration)\ Bin\Windows10\$(Platform)\$(Configuration)\ DirectXTex false Bin\Windows10\$(Platform)\$(Configuration)\ Bin\Windows10\$(Platform)\$(Configuration)\ DirectXTex false Bin\Windows10\$(Platform)\$(Configuration)\ Bin\Windows10\$(Platform)\$(Configuration)\ DirectXTex false Use false true Fast StreamingSIMDExtensions2 $(IntDir)$(TargetName).pdb Level4 DirectXTexP.h _CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS;%(PreprocessorDefinitions) Console false false Use false true Fast StreamingSIMDExtensions2 $(IntDir)$(TargetName).pdb Level4 DirectXTexP.h _CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS;%(PreprocessorDefinitions) Console false false Use false true Fast $(IntDir)$(TargetName).pdb Level4 DirectXTexP.h _CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS;%(PreprocessorDefinitions) Console false false Use false true Fast $(IntDir)$(TargetName).pdb Level4 DirectXTexP.h _CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS;%(PreprocessorDefinitions) Console false false Use false true Fast $(IntDir)$(TargetName).pdb Level4 DirectXTexP.h _CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS;%(PreprocessorDefinitions) Console false false Use false true Fast $(IntDir)$(TargetName).pdb Level4 DirectXTexP.h _CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS;%(PreprocessorDefinitions) Console false false ================================================ FILE: 3rdParty/DirectXTex/DirectXTex/DirectXTex_Windows10.vcxproj.filters ================================================  ================================================ FILE: 3rdParty/DirectXTex/DirectXTex/DirectXTex_Windows81.sln ================================================  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 2013 VisualStudioVersion = 12.0.21005.1 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DirectXTex", "DirectXTex_Windows81.vcxproj", "{371B9FA9-4C90-4AC6-A123-ACED756D6C77}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|ARM = Debug|ARM Debug|Win32 = Debug|Win32 Debug|x64 = Debug|x64 Profile|ARM = Profile|ARM Profile|Win32 = Profile|Win32 Profile|x64 = Profile|x64 Release|ARM = Release|ARM Release|Win32 = Release|Win32 Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Debug|ARM.ActiveCfg = Debug|ARM {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Debug|ARM.Build.0 = Debug|ARM {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Debug|Win32.ActiveCfg = Debug|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Debug|Win32.Build.0 = Debug|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Debug|x64.ActiveCfg = Debug|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Debug|x64.Build.0 = Debug|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Profile|ARM.ActiveCfg = Profile|ARM {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Profile|ARM.Build.0 = Profile|ARM {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Profile|Win32.ActiveCfg = Profile|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Profile|Win32.Build.0 = Profile|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Profile|x64.ActiveCfg = Profile|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Profile|x64.Build.0 = Profile|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Release|ARM.ActiveCfg = Release|ARM {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Release|ARM.Build.0 = Release|ARM {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Release|Win32.ActiveCfg = Release|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Release|Win32.Build.0 = Release|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Release|x64.ActiveCfg = Release|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal ================================================ FILE: 3rdParty/DirectXTex/DirectXTex/DirectXTex_Windows81.vcxproj ================================================  Debug ARM Debug Win32 Debug x64 Profile ARM Profile Win32 Profile x64 Release ARM Release Win32 Release x64 DirectXTex {371B9FA9-4C90-4AC6-A123-ACED756D6C77} DirectXTex Win32Proj $(VCTargetsPath11) en-US 12.0 true Windows Store 8.1 StaticLibrary Unicode v120 StaticLibrary Unicode v120 StaticLibrary Unicode v120 StaticLibrary Unicode v120 StaticLibrary Unicode v120 StaticLibrary Unicode v120 StaticLibrary Unicode v120 StaticLibrary Unicode v120 StaticLibrary Unicode v120 Bin\Windows81\$(Platform)\$(Configuration)\ Bin\Windows81\$(Platform)\$(Configuration)\ DirectXTex true true Bin\Windows81\$(Platform)\$(Configuration)\ Bin\Windows81\$(Platform)\$(Configuration)\ DirectXTex true true Bin\Windows81\$(Platform)\$(Configuration)\ Bin\Windows81\$(Platform)\$(Configuration)\ DirectXTex true true Bin\Windows81\$(Platform)\$(Configuration)\ Bin\Windows81\$(Platform)\$(Configuration)\ DirectXTex false true Bin\Windows81\$(Platform)\$(Configuration)\ Bin\Windows81\$(Platform)\$(Configuration)\ DirectXTex false true Bin\Windows81\$(Platform)\$(Configuration)\ Bin\Windows81\$(Platform)\$(Configuration)\ DirectXTex false true Bin\Windows81\$(Platform)\$(Configuration)\ Bin\Windows81\$(Platform)\$(Configuration)\ DirectXTex false true Bin\Windows81\$(Platform)\$(Configuration)\ Bin\Windows81\$(Platform)\$(Configuration)\ DirectXTex false true Bin\Windows81\$(Platform)\$(Configuration)\ Bin\Windows81\$(Platform)\$(Configuration)\ DirectXTex false true Level4 Disabled MultiThreadedDebugDLL true true Fast StreamingSIMDExtensions2 Sync %(AdditionalOptions) _UNICODE;UNICODE;_DEBUG;_LIB;%(PreprocessorDefinitions) EnableFastChecks Use DirectXTexP.h $(IntDir)$(TargetName).pdb %(AdditionalOptions) %(AdditionalDependencies) Windows true true true true MachineX86 AsInvoker %(DelayLoadDLLs) false /IGNORE:4264 %(AdditionalOptions) Level4 Disabled MultiThreadedDebugDLL true true Fast Sync %(AdditionalOptions) _UNICODE;UNICODE;_DEBUG;_LIB;%(PreprocessorDefinitions) EnableFastChecks Use DirectXTexP.h $(IntDir)$(TargetName).pdb %(AdditionalOptions) %(AdditionalDependencies) Windows true true true true AsInvoker %(DelayLoadDLLs) false /IGNORE:4264 %(AdditionalOptions) Level4 Disabled MultiThreadedDebugDLL true true Fast Sync %(AdditionalOptions) _UNICODE;UNICODE;_DEBUG;_LIB;%(PreprocessorDefinitions) EnableFastChecks Use DirectXTexP.h $(IntDir)$(TargetName).pdb %(AdditionalOptions) %(AdditionalDependencies) Windows true true true true MachineX64 AsInvoker %(DelayLoadDLLs) false /IGNORE:4264 %(AdditionalOptions) Level4 MaxSpeed MultiThreadedDLL true true true Fast StreamingSIMDExtensions2 Sync %(AdditionalOptions) _UNICODE;UNICODE;NDEBUG;_LIB;%(PreprocessorDefinitions) Use DirectXTexP.h $(IntDir)$(TargetName).pdb %(AdditionalOptions) %(AdditionalDependencies) true Windows true true true true true MachineX86 AsInvoker %(DelayLoadDLLs) false /IGNORE:4264 %(AdditionalOptions) Level4 MaxSpeed MultiThreadedDLL true true true Fast Sync %(AdditionalOptions) _UNICODE;UNICODE;NDEBUG;_LIB;%(PreprocessorDefinitions) Use DirectXTexP.h $(IntDir)$(TargetName).pdb %(AdditionalOptions) %(AdditionalDependencies) true Windows true true true true true AsInvoker %(DelayLoadDLLs) false /IGNORE:4264 %(AdditionalOptions) Level4 MaxSpeed MultiThreadedDLL true true true Fast Sync %(AdditionalOptions) _UNICODE;UNICODE;NDEBUG;_LIB;%(PreprocessorDefinitions) Use DirectXTexP.h $(IntDir)$(TargetName).pdb %(AdditionalOptions) %(AdditionalDependencies) true Windows true true true true true MachineX64 AsInvoker %(DelayLoadDLLs) false /IGNORE:4264 %(AdditionalOptions) Level4 MaxSpeed MultiThreadedDLL true true true Fast StreamingSIMDExtensions2 Sync %(AdditionalOptions) _UNICODE;UNICODE;NDEBUG;PROFILE;_LIB;%(PreprocessorDefinitions) Use DirectXTexP.h $(IntDir)$(TargetName).pdb %(AdditionalOptions) %(AdditionalDependencies) true Windows true true true true true MachineX86 AsInvoker %(DelayLoadDLLs) false /IGNORE:4264 %(AdditionalOptions) Level4 MaxSpeed MultiThreadedDLL true true true Fast Sync %(AdditionalOptions) _UNICODE;UNICODE;NDEBUG;PROFILE;_LIB;%(PreprocessorDefinitions) Use DirectXTexP.h $(IntDir)$(TargetName).pdb %(AdditionalOptions) %(AdditionalDependencies) true Windows true true true true true AsInvoker %(DelayLoadDLLs) false /IGNORE:4264 %(AdditionalOptions) Level4 MaxSpeed MultiThreadedDLL true true true Fast Sync %(AdditionalOptions) _UNICODE;UNICODE;NDEBUG;PROFILE;_LIB;%(PreprocessorDefinitions) Use DirectXTexP.h $(IntDir)$(TargetName).pdb %(AdditionalOptions) %(AdditionalDependencies) true Windows true true true true true MachineX64 AsInvoker %(DelayLoadDLLs) false /IGNORE:4264 %(AdditionalOptions) Create Create Create Create Create Create Create Create Create ================================================ FILE: 3rdParty/DirectXTex/DirectXTex/DirectXTex_Windows81.vcxproj.filters ================================================ {8e114980-c1a3-4ada-ad7c-83caadf5daeb} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe ================================================ FILE: 3rdParty/DirectXTex/DirectXTex/DirectXTex_WindowsPhone81.sln ================================================  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 2013 VisualStudioVersion = 12.0.30324.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DirectXTex_WindowsPhone81", "DirectXTex_WindowsPhone81.vcxproj", "{5709AA1F-D4E3-4138-BDD6-55C8DAF3D983}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|ARM = Debug|ARM Debug|Win32 = Debug|Win32 Release|ARM = Release|ARM Release|Win32 = Release|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {5709AA1F-D4E3-4138-BDD6-55C8DAF3D983}.Debug|ARM.ActiveCfg = Debug|ARM {5709AA1F-D4E3-4138-BDD6-55C8DAF3D983}.Debug|ARM.Build.0 = Debug|ARM {5709AA1F-D4E3-4138-BDD6-55C8DAF3D983}.Debug|Win32.ActiveCfg = Debug|Win32 {5709AA1F-D4E3-4138-BDD6-55C8DAF3D983}.Debug|Win32.Build.0 = Debug|Win32 {5709AA1F-D4E3-4138-BDD6-55C8DAF3D983}.Release|ARM.ActiveCfg = Release|ARM {5709AA1F-D4E3-4138-BDD6-55C8DAF3D983}.Release|ARM.Build.0 = Release|ARM {5709AA1F-D4E3-4138-BDD6-55C8DAF3D983}.Release|Win32.ActiveCfg = Release|Win32 {5709AA1F-D4E3-4138-BDD6-55C8DAF3D983}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal ================================================ FILE: 3rdParty/DirectXTex/DirectXTex/DirectXTex_WindowsPhone81.vcxproj ================================================  Debug Win32 Release Win32 Debug ARM Release ARM {5709aa1f-d4e3-4138-bdd6-55c8daf3d983} Win32Proj DirectXTex DirectXTex en-US 12.0 true Windows Phone 8.1 StaticLibrary true v120_wp81 StaticLibrary false v120_wp81 StaticLibrary true v120_wp81 StaticLibrary false v120_wp81 Bin\WindowsPhone81\$(Platform)\$(Configuration)\ Bin\WindowsPhone81\$(Platform)\$(Configuration)\ DirectXTex Bin\WindowsPhone81\$(Platform)\$(Configuration)\ Bin\WindowsPhone81\$(Platform)\$(Configuration)\ DirectXTex Bin\WindowsPhone81\$(Platform)\$(Configuration)\ Bin\WindowsPhone81\$(Platform)\$(Configuration)\ DirectXTex Bin\WindowsPhone81\$(Platform)\$(Configuration)\ Bin\WindowsPhone81\$(Platform)\$(Configuration)\ DirectXTex Use false true DirectXTexP.h $(IntDir)$(TargetName).pdb Fast StreamingSIMDExtensions2 Console false false Use false true DirectXTexP.h $(IntDir)$(TargetName).pdb Fast StreamingSIMDExtensions2 Console false false Use false true DirectXTexP.h $(IntDir)$(TargetName).pdb Fast Console false false Use false true DirectXTexP.h $(IntDir)$(TargetName).pdb Fast Console false false Create Create Create Create ================================================ FILE: 3rdParty/DirectXTex/DirectXTex/DirectXTex_WindowsPhone81.vcxproj.filters ================================================  Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files {ae44e5d8-5e05-47c8-92f5-0d6464fff56b} {dc9e6b8b-d350-4f63-895f-790dbd53c33e} ================================================ FILE: 3rdParty/DirectXTex/DirectXTex/DirectXTex_XboxOneADK.sln ================================================  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 2012 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DirectXTex_XboxOneADK", "DirectXTex_XboxOneADK.vcxproj", "{8F6CD012-9AD4-4EE1-9CBE-7B112E5CEB39}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Durango = Debug|Durango Profile|Durango = Profile|Durango Release|Durango = Release|Durango EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {8F6CD012-9AD4-4EE1-9CBE-7B112E5CEB39}.Debug|Durango.ActiveCfg = Debug|Durango {8F6CD012-9AD4-4EE1-9CBE-7B112E5CEB39}.Debug|Durango.Build.0 = Debug|Durango {8F6CD012-9AD4-4EE1-9CBE-7B112E5CEB39}.Profile|Durango.ActiveCfg = Profile|Durango {8F6CD012-9AD4-4EE1-9CBE-7B112E5CEB39}.Profile|Durango.Build.0 = Profile|Durango {8F6CD012-9AD4-4EE1-9CBE-7B112E5CEB39}.Release|Durango.ActiveCfg = Release|Durango {8F6CD012-9AD4-4EE1-9CBE-7B112E5CEB39}.Release|Durango.Build.0 = Release|Durango EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal ================================================ FILE: 3rdParty/DirectXTex/DirectXTex/DirectXTex_XboxOneADK.vcxproj ================================================  Release Durango Profile Durango Debug Durango Create Create Create DirectXTex_XboxOneADK {8f6cd012-9ad4-4ee1-9cbe-7b112e5ceb39} en-US Win32Proj v110 11.0 Native StaticLibrary v110 false Unicode false false StaticLibrary v110 false Unicode false false StaticLibrary v110 true Unicode false false $(Console_SdkLibPath);$(Console_SdkWindowsMetadataPath) $(Console_SdkLibPath) $(Console_SdkLibPath);$(Console_SdkWindowsMetadataPath) $(Console_SdkIncludeRoot) $(Console_SdkRoot)bin;$(VCInstallDir)bin\x86_amd64;$(VCInstallDir)bin;$(WindowsSDK_ExecutablePath_x86);$(VSInstallDir)Common7\Tools\bin;$(VSInstallDir)Common7\tools;$(VSInstallDir)Common7\ide;$(ProgramFiles)\HTML Help Workshop;$(MSBuildToolsPath32);$(FxCopDir);$(PATH); Bin\XboxOneADK\$(Platform)\$(Configuration)\ Bin\XboxOneADK\$(Platform)\$(Configuration)\ DirectXTex $(Console_SdkLibPath);$(Console_SdkWindowsMetadataPath) $(Console_SdkLibPath) $(Console_SdkLibPath);$(Console_SdkWindowsMetadataPath) $(Console_SdkIncludeRoot) $(Console_SdkRoot)bin;$(VCInstallDir)bin\x86_amd64;$(VCInstallDir)bin;$(WindowsSDK_ExecutablePath_x86);$(VSInstallDir)Common7\Tools\bin;$(VSInstallDir)Common7\tools;$(VSInstallDir)Common7\ide;$(ProgramFiles)\HTML Help Workshop;$(MSBuildToolsPath32);$(FxCopDir);$(PATH); Bin\XboxOneADK\$(Platform)\$(Configuration)\ Bin\XboxOneADK\$(Platform)\$(Configuration)\ DirectXTex $(Console_SdkLibPath);$(Console_SdkWindowsMetadataPath) $(Console_SdkLibPath) $(Console_SdkLibPath);$(Console_SdkWindowsMetadataPath) $(Console_SdkIncludeRoot) $(Console_SdkRoot)bin;$(VCInstallDir)bin\x86_amd64;$(VCInstallDir)bin;$(WindowsSDK_ExecutablePath_x86);$(VSInstallDir)Common7\Tools\bin;$(VSInstallDir)Common7\tools;$(VSInstallDir)Common7\ide;$(ProgramFiles)\HTML Help Workshop;$(MSBuildToolsPath32);$(FxCopDir);$(PATH); Bin\XboxOneADK\$(Platform)\$(Configuration)\ Bin\XboxOneADK\$(Platform)\$(Configuration)\ DirectXTex d3d11.lib;runtimeobject.lib;mincore.lib;mincore_legacy.lib;mincore_obsolete.lib;user32.lib;uuid.lib; true Windows true true false Use DirectXTexP.h $(Console_SdkPackagesRoot);$(Console_SdkWindowsMetadataPath);%(AdditionalUsingDirectories) MaxSpeed NDEBUG;_LIB;%(PreprocessorDefinitions) Level4 true true false $(IntDir)$(TargetName).pdb d3d11.lib;runtimeobject.lib;mincore.lib;mincore_legacy.lib;mincore_obsolete.lib;user32.lib;uuid.lib; true Windows true true false Use DirectXTexP.h $(Console_SdkWindowsMetadataPath);%(AdditionalUsingDirectories) MaxSpeed NDEBUG;_LIB;PROFILE;%(PreprocessorDefinitions) Level4 true true false $(IntDir)$(TargetName).pdb d3d11.lib;runtimeobject.lib;mincore.lib;mincore_legacy.lib;mincore_obsolete.lib;user32.lib;uuid.lib; Windows true false DirectXTexP.h Use false $(Console_SdkPackagesRoot);$(Console_SdkWindowsMetadataPath);%(AdditionalUsingDirectories) Level4 Disabled _DEBUG;_LIB;%(PreprocessorDefinitions) false $(IntDir)$(TargetName).pdb ================================================ FILE: 3rdParty/DirectXTex/DirectXTex/DirectXTex_XboxOneADK.vcxproj.filters ================================================  {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hpp;hxx;hm;inl;inc;xsd {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files ================================================ FILE: 3rdParty/DirectXTex/DirectXTex/DirectXTex_XboxOneXDK.sln ================================================  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 2012 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DirectXTex_XboxOneXDK", "DirectXTex_XboxOneXDK.vcxproj", "{8424AED1-3DBF-44FA-9CF9-7FBDF1C18596}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Durango = Debug|Durango Profile|Durango = Profile|Durango Release|Durango = Release|Durango EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {8424AED1-3DBF-44FA-9CF9-7FBDF1C18596}.Debug|Durango.ActiveCfg = Debug|Durango {8424AED1-3DBF-44FA-9CF9-7FBDF1C18596}.Debug|Durango.Build.0 = Debug|Durango {8424AED1-3DBF-44FA-9CF9-7FBDF1C18596}.Profile|Durango.ActiveCfg = Profile|Durango {8424AED1-3DBF-44FA-9CF9-7FBDF1C18596}.Profile|Durango.Build.0 = Profile|Durango {8424AED1-3DBF-44FA-9CF9-7FBDF1C18596}.Release|Durango.ActiveCfg = Release|Durango {8424AED1-3DBF-44FA-9CF9-7FBDF1C18596}.Release|Durango.Build.0 = Release|Durango EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal ================================================ FILE: 3rdParty/DirectXTex/DirectXTex/DirectXTex_XboxOneXDK.vcxproj ================================================  Release Durango Profile Durango Debug Durango Create Create Create DirectXTex_XboxOneXDK {8424aed1-3dbf-44fa-9cf9-7fbdf1c18596} en-US Win32Proj title v110 11.0 Native StaticLibrary v110 false Unicode false false StaticLibrary v110 false Unicode false false StaticLibrary v110 true Unicode false false $(Console_SdkLibPath);$(Console_SdkWindowsMetadataPath) $(Console_SdkLibPath) $(Console_SdkLibPath);$(Console_SdkWindowsMetadataPath) $(Console_SdkIncludeRoot) $(Console_SdkRoot)bin;$(VCInstallDir)bin\x86_amd64;$(VCInstallDir)bin;$(WindowsSDK_ExecutablePath_x86);$(VSInstallDir)Common7\Tools\bin;$(VSInstallDir)Common7\tools;$(VSInstallDir)Common7\ide;$(ProgramFiles)\HTML Help Workshop;$(MSBuildToolsPath32);$(FxCopDir);$(PATH); Bin\XboxOneXDK\$(Platform)\$(Configuration)\ Bin\XboxOneXDK\$(Platform)\$(Configuration)\ DirectXTex $(Console_SdkLibPath);$(Console_SdkWindowsMetadataPath) $(Console_SdkLibPath) $(Console_SdkLibPath);$(Console_SdkWindowsMetadataPath) $(Console_SdkIncludeRoot) $(Console_SdkRoot)bin;$(VCInstallDir)bin\x86_amd64;$(VCInstallDir)bin;$(WindowsSDK_ExecutablePath_x86);$(VSInstallDir)Common7\Tools\bin;$(VSInstallDir)Common7\tools;$(VSInstallDir)Common7\ide;$(ProgramFiles)\HTML Help Workshop;$(MSBuildToolsPath32);$(FxCopDir);$(PATH); Bin\XboxOneXDK\$(Platform)\$(Configuration)\ Bin\XboxOneXDK\$(Platform)\$(Configuration)\ DirectXTex $(Console_SdkLibPath);$(Console_SdkWindowsMetadataPath) $(Console_SdkLibPath) $(Console_SdkLibPath);$(Console_SdkWindowsMetadataPath) $(Console_SdkIncludeRoot) $(Console_SdkRoot)bin;$(VCInstallDir)bin\x86_amd64;$(VCInstallDir)bin;$(WindowsSDK_ExecutablePath_x86);$(VSInstallDir)Common7\Tools\bin;$(VSInstallDir)Common7\tools;$(VSInstallDir)Common7\ide;$(ProgramFiles)\HTML Help Workshop;$(MSBuildToolsPath32);$(FxCopDir);$(PATH); Bin\XboxOneXDK\$(Platform)\$(Configuration)\ Bin\XboxOneXDK\$(Platform)\$(Configuration)\ DirectXTex d3d11_x.lib;combase.lib;kernelx.lib;uuid.lib; true Windows true true false Use DirectXTexP.h $(Console_SdkPackagesRoot);$(Console_SdkWindowsMetadataPath);%(AdditionalUsingDirectories) MaxSpeed NDEBUG;__WRL_NO_DEFAULT_LIB__;_LIB;%(PreprocessorDefinitions) Level4 true true false $(IntDir)$(TargetName).pdb pixEvt.lib;d3d11_x.lib;combase.lib;kernelx.lib;uuid.lib; true Windows true true false Use DirectXTexP.h $(Console_SdkPackagesRoot);$(Console_SdkWindowsMetadataPath);%(AdditionalUsingDirectories) MaxSpeed NDEBUG;__WRL_NO_DEFAULT_LIB__;_LIB;PROFILE;%(PreprocessorDefinitions) Level4 true true false $(IntDir)$(TargetName).pdb d3d11_x.lib;combase.lib;kernelx.lib;uuid.lib; Windows true false DirectXTexP.h Use false $(Console_SdkPackagesRoot);$(Console_SdkWindowsMetadataPath);%(AdditionalUsingDirectories) Level4 Disabled _DEBUG;__WRL_NO_DEFAULT_LIB__;_LIB;%(PreprocessorDefinitions) false $(IntDir)$(TargetName).pdb ================================================ FILE: 3rdParty/DirectXTex/DirectXTex/DirectXTex_XboxOneXDK.vcxproj.filters ================================================  {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hpp;hxx;hm;inl;inc;xsd {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files ================================================ FILE: 3rdParty/DirectXTex/DirectXTex/Filters.h ================================================ //------------------------------------------------------------------------------------- // filters.h // // Utility header with helpers for implementing image filters // // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A // PARTICULAR PURPOSE. // // Copyright (c) Microsoft Corporation. All rights reserved. //------------------------------------------------------------------------------------- #pragma once #include #include #include #include "scoped.h" namespace DirectX { //------------------------------------------------------------------------------------- // Box filtering helpers //------------------------------------------------------------------------------------- XMGLOBALCONST XMVECTORF32 g_boxScale = { 0.25f, 0.25f, 0.25f, 0.25f }; XMGLOBALCONST XMVECTORF32 g_boxScale3D = { 0.125f, 0.125f, 0.125f, 0.125f }; #define AVERAGE4( res, p0, p1, p2, p3 ) \ { \ XMVECTOR v = XMVectorAdd( (p0), (p1) ); \ v = XMVectorAdd( v, (p2) ); \ v = XMVectorAdd( v, (p3) ); \ res = XMVectorMultiply( v, g_boxScale ); \ } #define AVERAGE8( res, p0, p1, p2, p3, p4, p5, p6, p7) \ { \ XMVECTOR v = XMVectorAdd( (p0), (p1) ); \ v = XMVectorAdd( v, (p2) ); \ v = XMVectorAdd( v, (p3) ); \ v = XMVectorAdd( v, (p4) ); \ v = XMVectorAdd( v, (p5) ); \ v = XMVectorAdd( v, (p6) ); \ v = XMVectorAdd( v, (p7) ); \ res = XMVectorMultiply( v, g_boxScale3D ); \ } //------------------------------------------------------------------------------------- // Linear filtering helpers //------------------------------------------------------------------------------------- struct LinearFilter { size_t u0; float weight0; size_t u1; float weight1; }; inline void _CreateLinearFilter( _In_ size_t source, _In_ size_t dest, _In_ bool wrap, _Out_writes_(dest) LinearFilter* lf ) { assert( source > 0 ); assert( dest > 0 ); assert( lf != 0 ); float scale = float(source) / float(dest); // Mirror is the same case as clamp for linear for( size_t u = 0; u < dest; ++u ) { float srcB = ( float(u) + 0.5f ) * scale + 0.5f; ptrdiff_t isrcB = ptrdiff_t(srcB); ptrdiff_t isrcA = isrcB - 1; if ( isrcA < 0 ) { isrcA = ( wrap ) ? ( source - 1) : 0; } if ( size_t(isrcB) >= source ) { isrcB = ( wrap ) ? 0 : ( source - 1); } float weight = 1.0f + float(isrcB) - srcB; auto& entry = lf[ u ]; entry.u0 = size_t(isrcA); entry.weight0 = weight; entry.u1 = size_t(isrcB); entry.weight1 = 1.0f - weight; } } #define BILINEAR_INTERPOLATE( res, x, y, r0, r1 ) \ res = ( y.weight0 * ( (r0)[ x.u0 ] * x.weight0 + (r0)[ x.u1 ] * x.weight1 ) ) \ + ( y.weight1 * ( (r1)[ x.u0 ] * x.weight0 + (r1)[ x.u1 ] * x.weight1 ) ) #define TRILINEAR_INTERPOLATE( res, x, y, z, r0, r1, r2, r3 ) \ res = ( z.weight0 * ( ( y.weight0 * ( (r0)[ x.u0 ] * x.weight0 + (r0)[ x.u1 ] * x.weight1 ) ) \ + ( y.weight1 * ( (r1)[ x.u0 ] * x.weight0 + (r1)[ x.u1 ] * x.weight1 ) ) ) ) \ + ( z.weight1 * ( ( y.weight0 * ( (r2)[ x.u0 ] * x.weight0 + (r2)[ x.u1 ] * x.weight1 ) ) \ + ( y.weight1 * ( (r3)[ x.u0 ] * x.weight0 + (r3)[ x.u1 ] * x.weight1 ) ) ) ) //------------------------------------------------------------------------------------- // Cubic filtering helpers //------------------------------------------------------------------------------------- XMGLOBALCONST XMVECTORF32 g_cubicThird = { 1.f/3.f, 1.f/3.f, 1.f/3.f, 1.f/3.f }; XMGLOBALCONST XMVECTORF32 g_cubicSixth = { 1.f/6.f, 1.f/6.f, 1.f/6.f, 1.f/6.f }; XMGLOBALCONST XMVECTORF32 g_cubicHalf = { 1.f/2.f, 1.f/2.f, 1.f/2.f, 1.f/2.f }; inline ptrdiff_t bounduvw( ptrdiff_t u, ptrdiff_t maxu, bool wrap, bool mirror ) { if ( wrap ) { if ( u < 0 ) { u = maxu + u + 1; } else if ( u > maxu ) { u = u - maxu - 1; } } else if ( mirror ) { if ( u < 0 ) { u = ( -u ) - 1; } else if ( u > maxu ) { u = maxu - (u - maxu - 1); } } // Handles clamp, but also a safety factor for degenerate images for wrap/mirror u = std::min( u, maxu ); u = std::max( u, 0 ); return u; } struct CubicFilter { size_t u0; size_t u1; size_t u2; size_t u3; float x; }; inline void _CreateCubicFilter( _In_ size_t source, _In_ size_t dest, _In_ bool wrap, _In_ bool mirror, _Out_writes_(dest) CubicFilter* cf ) { assert( source > 0 ); assert( dest > 0 ); assert( cf != 0 ); float scale = float(source) / float(dest); for( size_t u = 0; u < dest; ++u ) { float srcB = ( float(u) + 0.5f ) * scale - 0.5f; ptrdiff_t isrcB = bounduvw( ptrdiff_t(srcB), source - 1, wrap, mirror ); ptrdiff_t isrcA = bounduvw( isrcB - 1, source - 1, wrap, mirror ); ptrdiff_t isrcC = bounduvw( isrcB + 1, source - 1, wrap, mirror ); ptrdiff_t isrcD = bounduvw( isrcB + 2, source - 1, wrap, mirror ); auto& entry = cf[ u ]; entry.u0 = size_t(isrcA); entry.u1 = size_t(isrcB); entry.u2 = size_t(isrcC); entry.u3 = size_t(isrcD); float x = srcB - float(isrcB); entry.x = x; } } #define CUBIC_INTERPOLATE( res, dx, p0, p1, p2, p3 ) \ { \ XMVECTOR a0 = (p1); \ XMVECTOR d0 = (p0) - a0; \ XMVECTOR d2 = (p2) - a0; \ XMVECTOR d3 = (p3) - a0; \ XMVECTOR a1 = d2 - g_cubicThird*d0 - g_cubicSixth*d3; \ XMVECTOR a2 = g_cubicHalf*d0 + g_cubicHalf*d2; \ XMVECTOR a3 = g_cubicSixth*d3 - g_cubicSixth*d0 - g_cubicHalf*d2; \ XMVECTOR vdx = XMVectorReplicate( dx ); \ XMVECTOR vdx2 = vdx * vdx; \ XMVECTOR vdx3 = vdx2 * vdx; \ res = a0 + a1*vdx + a2*vdx2 + a3*vdx3; \ } //------------------------------------------------------------------------------------- // Triangle filtering helpers //------------------------------------------------------------------------------------- namespace TriangleFilter { struct FilterTo { size_t u; float weight; }; struct FilterFrom { size_t count; size_t sizeInBytes; FilterTo to[1]; // variable-sized array }; struct Filter { size_t sizeInBytes; size_t totalSize; FilterFrom from[1]; // variable-sized array }; struct TriangleRow { size_t remaining; TriangleRow* next; ScopedAlignedArrayXMVECTOR scanline; TriangleRow() : remaining(0), next(nullptr) {} }; static const size_t TF_FILTER_SIZE = sizeof(Filter) - sizeof(FilterFrom); static const size_t TF_FROM_SIZE = sizeof(FilterFrom) - sizeof(FilterTo); static const size_t TF_TO_SIZE = sizeof(FilterTo); static const float TF_EPSILON = 0.00001f; inline HRESULT _Create( _In_ size_t source, _In_ size_t dest, _In_ bool wrap, _Inout_ std::unique_ptr& tf ) { assert( source > 0 ); assert( dest > 0 ); float scale = float(dest) / float(source); float scaleInv = 0.5f / scale; // Determine storage required for filter and allocate memory if needed size_t totalSize = TF_FILTER_SIZE + TF_FROM_SIZE + TF_TO_SIZE; float repeat = (wrap) ? 1.f : 0.f; for( size_t u = 0; u < source; ++u ) { float src = float(u) - 0.5f; float destMin = src * scale; float destMax = destMin + scale; totalSize += TF_FROM_SIZE + TF_TO_SIZE + size_t( destMax - destMin + repeat + 1.f ) * TF_TO_SIZE * 2; } uint8_t* pFilter = nullptr; if ( tf ) { // See if existing filter memory block is large enough to reuse if ( tf->totalSize >= totalSize ) { pFilter = reinterpret_cast( tf.get() ); } else { // Need to reallocate filter memory block tf.reset( nullptr ); } } if ( !tf ) { // Allocate filter memory block pFilter = new (std::nothrow) uint8_t[ totalSize ]; if ( !pFilter ) return E_OUTOFMEMORY; tf.reset( reinterpret_cast( pFilter ) ); tf->totalSize = totalSize; } assert( pFilter != 0 ); // Filter setup size_t sizeInBytes = TF_FILTER_SIZE; size_t accumU = 0; float accumWeight = 0.f; for( size_t u = 0; u < source; ++u ) { // Setup from entry size_t sizeFrom = sizeInBytes; auto pFrom = reinterpret_cast( pFilter + sizeInBytes ); sizeInBytes += TF_FROM_SIZE; if ( sizeInBytes > totalSize ) return E_FAIL; size_t toCount = 0; // Perform two passes to capture the influences from both sides for( size_t j = 0; j < 2; ++j ) { float src = float( u + j ) - 0.5f; float destMin = src * scale; float destMax = destMin + scale; if ( !wrap ) { // Clamp if ( destMin < 0.f ) destMin = 0.f; if ( destMax > float(dest) ) destMax = float(dest); } for( auto k = static_cast( floorf( destMin ) ); float(k) < destMax; ++k ) { float d0 = float(k); float d1 = d0 + 1.f; size_t u0; if ( k < 0 ) { // Handle wrap u0 = size_t( k + ptrdiff_t(dest) ); } else if ( k >= ptrdiff_t(dest) ) { // Handle wrap u0 = size_t( k - ptrdiff_t(dest) ); } else { u0 = size_t( k ); } // Save previous accumulated weight (if any) if ( u0 != accumU ) { if ( accumWeight > TF_EPSILON ) { auto pTo = reinterpret_cast( pFilter + sizeInBytes ); sizeInBytes += TF_TO_SIZE; ++toCount; if ( sizeInBytes > totalSize ) return E_FAIL; pTo->u = accumU; pTo->weight = accumWeight; } accumWeight = 0.f; accumU = u0; } // Clip destination if ( d0 < destMin ) d0 = destMin; if ( d1 > destMax ) d1 = destMax; // Calculate average weight over destination pixel float weight; if ( !wrap && src < 0.f ) weight = 1.f; else if ( !wrap && ( ( src + 1.f ) >= float(source) ) ) weight = 0.f; else weight = (d0 + d1) * scaleInv - src; accumWeight += (d1 - d0) * ( j ? (1.f - weight) : weight ); } } // Store accumulated weight if ( accumWeight > TF_EPSILON ) { auto pTo = reinterpret_cast( pFilter + sizeInBytes ); sizeInBytes += TF_TO_SIZE; ++toCount; if ( sizeInBytes > totalSize ) return E_FAIL; pTo->u = accumU; pTo->weight = accumWeight; } accumWeight = 0.f; // Finalize from entry pFrom->count = toCount; pFrom->sizeInBytes = sizeInBytes - sizeFrom; } tf->sizeInBytes = sizeInBytes; return S_OK; } }; // namespace }; // namespace ================================================ FILE: 3rdParty/DirectXTex/DirectXTex/Shaders/BC6HEncode.hlsl ================================================ //-------------------------------------------------------------------------------------- // File: BC6HEncode.hlsl // // The Compute Shader for BC6H Encoder // // Copyright (c) Microsoft Corporation. All rights reserved. //-------------------------------------------------------------------------------------- //#define REF_DEVICE #define UINTLENGTH 32 #define NCHANNELS 3 #define SIGNED_F16 96 #define UNSIGNED_F16 95 #define MAX_FLOAT asfloat(0x7F7FFFFF) #define MIN_FLOAT asfloat(0xFF7FFFFF) #define MAX_INT asint(0x7FFFFFFF) #define MIN_INT asint(0x80000000) cbuffer cbCS : register( b0 ) { uint g_tex_width; uint g_num_block_x; uint g_format; //either SIGNED_F16 for DXGI_FORMAT_BC6H_SF16 or UNSIGNED_F16 for DXGI_FORMAT_BC6H_UF16 uint g_mode_id; uint g_start_block_id; uint g_num_total_blocks; }; static const uint candidateModeMemory[14] = { 0x00, 0x01, 0x02, 0x06, 0x0A, 0x0E, 0x12, 0x16, 0x1A, 0x1E, 0x03, 0x07, 0x0B, 0x0F }; static const uint candidateModeFlag[14] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 }; static const bool candidateModeTransformed[14] = { true, true, true, true, true, true, true, true, true, false, false, true, true, true }; static const uint4 candidateModePrec[14] = { uint4(10,5,5,5), uint4(7,6,6,6), uint4(11,5,4,4), uint4(11,4,5,4), uint4(11,4,4,5), uint4(9,5,5,5), uint4(8,6,5,5), uint4(8,5,6,5), uint4(8,5,5,6), uint4(6,6,6,6), uint4(10,10,10,10), uint4(11,9,9,9), uint4(12,8,8,8), uint4(16,4,4,4) }; /*static const uint4x4 candidateSection[32] = { {0,0,1,1, 0,0,1,1, 0,0,1,1, 0,0,1,1}, {0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1}, {0,1,1,1, 0,1,1,1, 0,1,1,1, 0,1,1,1}, {0,0,0,1, 0,0,1,1, 0,0,1,1, 0,1,1,1}, {0,0,0,0, 0,0,0,1, 0,0,0,1, 0,0,1,1}, {0,0,1,1, 0,1,1,1, 0,1,1,1, 1,1,1,1}, {0,0,0,1, 0,0,1,1, 0,1,1,1, 1,1,1,1}, {0,0,0,0, 0,0,0,1, 0,0,1,1, 0,1,1,1}, {0,0,0,0, 0,0,0,0, 0,0,0,1, 0,0,1,1}, {0,0,1,1, 0,1,1,1, 1,1,1,1, 1,1,1,1}, {0,0,0,0, 0,0,0,1, 0,1,1,1, 1,1,1,1}, {0,0,0,0, 0,0,0,0, 0,0,0,1, 0,1,1,1}, {0,0,0,1, 0,1,1,1, 1,1,1,1, 1,1,1,1}, {0,0,0,0, 0,0,0,0, 1,1,1,1, 1,1,1,1}, {0,0,0,0, 1,1,1,1, 1,1,1,1, 1,1,1,1}, {0,0,0,0, 0,0,0,0, 0,0,0,0, 1,1,1,1}, {0,0,0,0, 1,0,0,0, 1,1,1,0, 1,1,1,1}, {0,1,1,1, 0,0,0,1, 0,0,0,0, 0,0,0,0}, {0,0,0,0, 0,0,0,0, 1,0,0,0, 1,1,1,0}, {0,1,1,1, 0,0,1,1, 0,0,0,1, 0,0,0,0}, {0,0,1,1, 0,0,0,1, 0,0,0,0, 0,0,0,0}, {0,0,0,0, 1,0,0,0, 1,1,0,0, 1,1,1,0}, {0,0,0,0, 0,0,0,0, 1,0,0,0, 1,1,0,0}, {0,1,1,1, 0,0,1,1, 0,0,1,1, 0,0,0,1}, {0,0,1,1, 0,0,0,1, 0,0,0,1, 0,0,0,0}, {0,0,0,0, 1,0,0,0, 1,0,0,0, 1,1,0,0}, {0,1,1,0, 0,1,1,0, 0,1,1,0, 0,1,1,0}, {0,0,1,1, 0,1,1,0, 0,1,1,0, 1,1,0,0}, {0,0,0,1, 0,1,1,1, 1,1,1,0, 1,0,0,0}, {0,0,0,0, 1,1,1,1, 1,1,1,1, 0,0,0,0}, {0,1,1,1, 0,0,0,1, 1,0,0,0, 1,1,1,0}, {0,0,1,1, 1,0,0,1, 1,0,0,1, 1,1,0,0} };*/ static const uint candidateSectionBit[32] = { 0xCCCC, 0x8888, 0xEEEE, 0xECC8, 0xC880, 0xFEEC, 0xFEC8, 0xEC80, 0xC800, 0xFFEC, 0xFE80, 0xE800, 0xFFE8, 0xFF00, 0xFFF0, 0xF000, 0xF710, 0x008E, 0x7100, 0x08CE, 0x008C, 0x7310, 0x3100, 0x8CCE, 0x088C, 0x3110, 0x6666, 0x366C, 0x17E8, 0x0FF0, 0x718E, 0x399C }; static const uint candidateFixUpIndex1D[32] = { 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, 15, 2, 8, 2, 2, 8, 8,15, 2, 8, 2, 2, 8, 8, 2, 2 }; //0, 9, 18, 27, 37, 46, 55, 64 static const uint aStep1[64] = {0,0,0,0,0,1,1,1, 1,1,1,1,1,1,2,2, 2,2,2,2,2,2,2,3, 3,3,3,3,3,3,3,3, 3,4,4,4,4,4,4,4, 4,4,5,5,5,5,5,5, 5,5,5,6,6,6,6,6, 6,6,6,6,7,7,7,7}; //0, 4, 9, 13, 17, 21, 26, 30, 34, 38, 43, 47, 51, 55, 60, 64 static const uint aStep2[64] = { 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9,10,10,10,10,10,11,11, 11,11,12,12,12,12,13,13, 13,13,14,14,14,14,15,15}; static const float3 RGB2LUM = float3(0.2126f, 0.7152f, 0.0722f); #define THREAD_GROUP_SIZE 64 #define BLOCK_SIZE_Y 4 #define BLOCK_SIZE_X 4 #define BLOCK_SIZE (BLOCK_SIZE_Y * BLOCK_SIZE_X) //Forward declaration uint3 float2half( float3 pixel_f ); int3 start_quantize( uint3 pixel_h ); void quantize( inout int2x3 endPoint, uint prec ); void finish_quantize_0( inout int bBadQuantize, inout int2x3 endPoint, uint4 prec, bool transformed ); void finish_quantize_1( inout int bBadQuantize, inout int2x3 endPoint, uint4 prec, bool transformed ); void finish_quantize( out bool bBadQuantize, inout int2x3 endPoint, uint4 prec, bool transformed ); void start_unquantize( inout int2x3 endPoint[2], uint4 prec, bool transformed ); void start_unquantize( inout int2x3 endPoint, uint4 prec, bool transformed ); void unquantize( inout int2x3 color, uint prec ); uint3 finish_unquantize( int3 color ); void generate_palette_unquantized8( out uint3 palette, int3 low, int3 high, int i ); void generate_palette_unquantized16( out uint3 palette, int3 low, int3 high, int i ); float3 half2float(uint3 color_h ); void block_package( inout uint4 block, int2x3 endPoint[2], uint mode_type, uint partition_index ); void block_package( inout uint4 block, int2x3 endPoint, uint mode_type ); void swap(inout int3 lhs, inout int3 rhs) { int3 tmp = lhs; lhs = rhs; rhs = tmp; } Texture2D g_Input : register( t0 ); StructuredBuffer g_InBuff : register( t1 ); RWStructuredBuffer g_OutBuff : register( u0 ); struct SharedData { float3 pixel; int3 pixel_ph; float3 pixel_hr; float pixel_lum; float error; uint best_mode; uint best_partition; int3 endPoint_low; int3 endPoint_high; float endPoint_lum_low; float endPoint_lum_high; }; groupshared SharedData shared_temp[THREAD_GROUP_SIZE]; [numthreads( THREAD_GROUP_SIZE, 1, 1 )] void TryModeG10CS( uint GI : SV_GroupIndex, uint3 groupID : SV_GroupID ) { const uint MAX_USED_THREAD = 16; uint BLOCK_IN_GROUP = THREAD_GROUP_SIZE / MAX_USED_THREAD; uint blockInGroup = GI / MAX_USED_THREAD; uint blockID = g_start_block_id + groupID.x * BLOCK_IN_GROUP + blockInGroup; uint threadBase = blockInGroup * MAX_USED_THREAD; uint threadInBlock = GI - threadBase; #ifndef REF_DEVICE if (blockID >= g_num_total_blocks) { return; } #endif uint block_y = blockID / g_num_block_x; uint block_x = blockID - block_y * g_num_block_x; uint base_x = block_x * BLOCK_SIZE_X; uint base_y = block_y * BLOCK_SIZE_Y; if (threadInBlock < 16) { shared_temp[GI].pixel = g_Input.Load( uint3( base_x + threadInBlock % 4, base_y + threadInBlock / 4, 0 ) ).rgb; uint3 pixel_h = float2half( shared_temp[GI].pixel ); shared_temp[GI].pixel_hr = half2float(pixel_h); shared_temp[GI].pixel_lum = dot(shared_temp[GI].pixel_hr, RGB2LUM); shared_temp[GI].pixel_ph = start_quantize( pixel_h ); shared_temp[GI].endPoint_low = shared_temp[GI].pixel_ph; shared_temp[GI].endPoint_high = shared_temp[GI].pixel_ph; shared_temp[GI].endPoint_lum_low = shared_temp[GI].pixel_lum; shared_temp[GI].endPoint_lum_high = shared_temp[GI].pixel_lum; } #ifdef REF_DEVICE GroupMemoryBarrierWithGroupSync(); #endif if (threadInBlock < 8) { if (shared_temp[GI].endPoint_lum_low > shared_temp[GI + 8].endPoint_lum_low) { shared_temp[GI].endPoint_low = shared_temp[GI + 8].endPoint_low; shared_temp[GI].endPoint_lum_low = shared_temp[GI + 8].endPoint_lum_low; } if (shared_temp[GI].endPoint_lum_high < shared_temp[GI + 8].endPoint_lum_high) { shared_temp[GI].endPoint_high = shared_temp[GI + 8].endPoint_high; shared_temp[GI].endPoint_lum_high = shared_temp[GI + 8].endPoint_lum_high; } } #ifdef REF_DEVICE GroupMemoryBarrierWithGroupSync(); #endif if (threadInBlock < 4) { if (shared_temp[GI].endPoint_lum_low > shared_temp[GI + 4].endPoint_lum_low) { shared_temp[GI].endPoint_low = shared_temp[GI + 4].endPoint_low; shared_temp[GI].endPoint_lum_low = shared_temp[GI + 4].endPoint_lum_low; } if (shared_temp[GI].endPoint_lum_high < shared_temp[GI + 4].endPoint_lum_high) { shared_temp[GI].endPoint_high = shared_temp[GI + 4].endPoint_high; shared_temp[GI].endPoint_lum_high = shared_temp[GI + 4].endPoint_lum_high; } } #ifdef REF_DEVICE GroupMemoryBarrierWithGroupSync(); #endif if (threadInBlock < 2) { if (shared_temp[GI].endPoint_lum_low > shared_temp[GI + 2].endPoint_lum_low) { shared_temp[GI].endPoint_low = shared_temp[GI + 2].endPoint_low; shared_temp[GI].endPoint_lum_low = shared_temp[GI + 2].endPoint_lum_low; } if (shared_temp[GI].endPoint_lum_high < shared_temp[GI + 2].endPoint_lum_high) { shared_temp[GI].endPoint_high = shared_temp[GI + 2].endPoint_high; shared_temp[GI].endPoint_lum_high = shared_temp[GI + 2].endPoint_lum_high; } } #ifdef REF_DEVICE GroupMemoryBarrierWithGroupSync(); #endif if (threadInBlock < 1) { if (shared_temp[GI].endPoint_lum_low > shared_temp[GI + 1].endPoint_lum_low) { shared_temp[GI].endPoint_low = shared_temp[GI + 1].endPoint_low; shared_temp[GI].endPoint_lum_low = shared_temp[GI + 1].endPoint_lum_low; } if (shared_temp[GI].endPoint_lum_high < shared_temp[GI + 1].endPoint_lum_high) { shared_temp[GI].endPoint_high = shared_temp[GI + 1].endPoint_high; shared_temp[GI].endPoint_lum_high = shared_temp[GI + 1].endPoint_lum_high; } } #ifdef REF_DEVICE GroupMemoryBarrierWithGroupSync(); #endif //ergod mode_type 11:14 if ( threadInBlock == 0 ) { int2x3 endPoint; // find_axis endPoint[0] = shared_temp[threadBase + 0].endPoint_low; endPoint[1] = shared_temp[threadBase + 0].endPoint_high; //compute_index float3 span = endPoint[1] - endPoint[0];// fixed a bug in v0.2 float span_norm_sqr = dot( span, span );// fixed a bug in v0.2 float dotProduct = dot( span, shared_temp[threadBase + 0].pixel_ph - endPoint[0] );// fixed a bug in v0.2 if ( span_norm_sqr > 0 && dotProduct >= 0 && uint( dotProduct * 63.49999 / span_norm_sqr ) > 32 ) { swap(endPoint[0], endPoint[1]); shared_temp[GI].endPoint_low = endPoint[0]; shared_temp[GI].endPoint_high = endPoint[1]; } } #ifdef REF_DEVICE GroupMemoryBarrierWithGroupSync(); #endif if (threadInBlock < 4) { int2x3 endPoint; endPoint[0] = shared_temp[threadBase + 0].endPoint_low; endPoint[1] = shared_temp[threadBase + 0].endPoint_high; float3 span = endPoint[1] - endPoint[0]; float span_norm_sqr = dot( span, span ); uint4 prec = candidateModePrec[threadInBlock + 10]; int2x3 endPoint_q = endPoint; quantize( endPoint_q, prec.x ); bool transformed = candidateModeTransformed[threadInBlock + 10]; if (transformed) { endPoint_q[1] -= endPoint_q[0]; } bool bBadQuantize; finish_quantize( bBadQuantize, endPoint_q, prec, transformed ); start_unquantize( endPoint_q, prec, transformed ); unquantize( endPoint_q, prec.x ); float error = 0; [loop]for ( uint j = 0; j < 16; j ++ ) { float dotProduct = dot( span, shared_temp[threadBase + j].pixel_ph - endPoint[0] );// fixed a bug in v0.2 uint index = ( span_norm_sqr <= 0 || dotProduct <= 0 ) ? 0 : ( ( dotProduct < span_norm_sqr ) ? aStep2[ uint( dotProduct * 63.49999 / span_norm_sqr ) ] : aStep2[63] ); uint3 pixel_rh; generate_palette_unquantized16( pixel_rh, endPoint_q[0], endPoint_q[1], index ); float3 pixel_r = half2float( pixel_rh ); pixel_r -= shared_temp[threadBase + j].pixel_hr; error += dot(pixel_r, pixel_r); } if ( bBadQuantize ) error = 1e20f; shared_temp[GI].error = error; shared_temp[GI].best_mode = candidateModeFlag[threadInBlock + 10]; } #ifdef REF_DEVICE GroupMemoryBarrierWithGroupSync(); #endif if (threadInBlock < 2) { if ( shared_temp[GI].error > shared_temp[GI + 2].error ) { shared_temp[GI].error = shared_temp[GI + 2].error; shared_temp[GI].best_mode = shared_temp[GI + 2].best_mode; } } #ifdef REF_DEVICE GroupMemoryBarrierWithGroupSync(); #endif if (threadInBlock < 1) { if ( shared_temp[GI].error > shared_temp[GI + 1].error ) { shared_temp[GI].error = shared_temp[GI + 1].error; shared_temp[GI].best_mode = shared_temp[GI + 1].best_mode; } g_OutBuff[blockID] = uint4(asuint(shared_temp[GI].error), shared_temp[GI].best_mode, 0, 0); } } [numthreads( THREAD_GROUP_SIZE, 1, 1 )] void TryModeLE10CS( uint GI : SV_GroupIndex, uint3 groupID : SV_GroupID ) { const uint MAX_USED_THREAD = 32; uint BLOCK_IN_GROUP = THREAD_GROUP_SIZE / MAX_USED_THREAD; uint blockInGroup = GI / MAX_USED_THREAD; uint blockID = g_start_block_id + groupID.x * BLOCK_IN_GROUP + blockInGroup; uint threadBase = blockInGroup * MAX_USED_THREAD; uint threadInBlock = GI - threadBase; #ifndef REF_DEVICE if (blockID >= g_num_total_blocks) { return; } if (asfloat(g_InBuff[blockID].x) < 1e-6f) { g_OutBuff[blockID] = g_InBuff[blockID]; return; } #endif uint block_y = blockID / g_num_block_x; uint block_x = blockID - block_y * g_num_block_x; uint base_x = block_x * BLOCK_SIZE_X; uint base_y = block_y * BLOCK_SIZE_Y; if (threadInBlock < 16) { shared_temp[GI].pixel = g_Input.Load( uint3( base_x + threadInBlock % 4, base_y + threadInBlock / 4, 0 ) ).rgb; uint3 pixel_h = float2half( shared_temp[GI].pixel ); shared_temp[GI].pixel_hr = half2float(pixel_h); shared_temp[GI].pixel_lum = dot(shared_temp[GI].pixel_hr, RGB2LUM); shared_temp[GI].pixel_ph = start_quantize( pixel_h ); } #ifdef REF_DEVICE GroupMemoryBarrierWithGroupSync(); #endif //ergod mode_type 1:10 if (threadInBlock < 32) { // find_axis int2x3 endPoint[2]; endPoint[0][0] = MAX_INT; endPoint[0][1] = MIN_INT; endPoint[1][0] = MAX_INT; endPoint[1][1] = MIN_INT; float2 endPoint_lum[2]; endPoint_lum[0][0] = MAX_FLOAT; endPoint_lum[0][1] = MIN_FLOAT; endPoint_lum[1][0] = MAX_FLOAT; endPoint_lum[1][1] = MIN_FLOAT; uint bit = candidateSectionBit[threadInBlock]; for ( uint i = 0; i < 16; i ++ ) { int3 pixel_ph = shared_temp[threadBase + i].pixel_ph; float pixel_lum = shared_temp[threadBase + i].pixel_lum; if ( (bit >> i) & 1 ) //It gets error when using "candidateSection" as "endPoint_ph" index { if (endPoint_lum[1][0] > pixel_lum) { endPoint[1][0] = pixel_ph; endPoint_lum[1][0] = pixel_lum; } if (endPoint_lum[1][1] < pixel_lum) { endPoint[1][1] = pixel_ph; endPoint_lum[1][1] = pixel_lum; } } else { if (endPoint_lum[0][0] > pixel_lum) { endPoint[0][0] = pixel_ph; endPoint_lum[0][0] = pixel_lum; } if (endPoint_lum[0][1] < pixel_lum) { endPoint[0][1] = pixel_ph; endPoint_lum[0][1] = pixel_lum; } } } //compute_index float3 span[2];// fixed a bug in v0.2 float span_norm_sqr[2];// fixed a bug in v0.2 [unroll] for (uint p = 0; p < 2; ++ p) { span[p] = endPoint[p][1] - endPoint[p][0]; span_norm_sqr[p] = dot( span[p], span[p] ); float dotProduct = dot( span[p], shared_temp[threadBase + (0 == p ? 0 : candidateFixUpIndex1D[threadInBlock])].pixel_ph - endPoint[p][0] );// fixed a bug in v0.2 if ( span_norm_sqr[p] > 0 && dotProduct >= 0 && uint( dotProduct * 63.49999 / span_norm_sqr[p] ) > 32 ) { span[p] = -span[p]; swap(endPoint[p][0], endPoint[p][1]); } } uint4 prec = candidateModePrec[g_mode_id]; int2x3 endPoint_q[2] = endPoint; quantize( endPoint_q[0], prec.x ); quantize( endPoint_q[1], prec.x ); bool transformed = candidateModeTransformed[g_mode_id]; if (transformed) { endPoint_q[0][1] -= endPoint_q[0][0]; endPoint_q[1][0] -= endPoint_q[0][0]; endPoint_q[1][1] -= endPoint_q[0][0]; } int bBadQuantize = 0; finish_quantize_0( bBadQuantize, endPoint_q[0], prec, transformed ); finish_quantize_1( bBadQuantize, endPoint_q[1], prec, transformed ); start_unquantize( endPoint_q, prec, transformed ); unquantize( endPoint_q[0], prec.x ); unquantize( endPoint_q[1], prec.x ); float error = 0; for ( uint j = 0; j < 16; j ++ ) { uint3 pixel_rh; if ((bit >> j) & 1) { float dotProduct = dot( span[1], shared_temp[threadBase + j].pixel_ph - endPoint[1][0] );// fixed a bug in v0.2 uint index = ( span_norm_sqr[1] <= 0 || dotProduct <= 0 ) ? 0 : ( ( dotProduct < span_norm_sqr[1] ) ? aStep1[ uint( dotProduct * 63.49999 / span_norm_sqr[1] ) ] : aStep1[63] ); generate_palette_unquantized8( pixel_rh, endPoint_q[1][0], endPoint_q[1][1], index ); } else { float dotProduct = dot( span[0], shared_temp[threadBase + j].pixel_ph - endPoint[0][0] );// fixed a bug in v0.2 uint index = ( span_norm_sqr[0] <= 0 || dotProduct <= 0 ) ? 0 : ( ( dotProduct < span_norm_sqr[0] ) ? aStep1[ uint( dotProduct * 63.49999 / span_norm_sqr[0] ) ] : aStep1[63] ); generate_palette_unquantized8( pixel_rh, endPoint_q[0][0], endPoint_q[0][1], index ); } float3 pixel_r = half2float( pixel_rh ); pixel_r -= shared_temp[threadBase + j].pixel_hr; error += dot(pixel_r, pixel_r); } if ( bBadQuantize ) error = 1e20f; shared_temp[GI].error = error; shared_temp[GI].best_mode = candidateModeFlag[g_mode_id]; shared_temp[GI].best_partition = threadInBlock; } #ifdef REF_DEVICE GroupMemoryBarrierWithGroupSync(); #endif if (threadInBlock < 16) { if ( shared_temp[GI].error > shared_temp[GI + 16].error ) { shared_temp[GI].error = shared_temp[GI + 16].error; shared_temp[GI].best_mode = shared_temp[GI + 16].best_mode; shared_temp[GI].best_partition = shared_temp[GI + 16].best_partition; } } #ifdef REF_DEVICE GroupMemoryBarrierWithGroupSync(); #endif if (threadInBlock < 8) { if ( shared_temp[GI].error > shared_temp[GI + 8].error ) { shared_temp[GI].error = shared_temp[GI + 8].error; shared_temp[GI].best_mode = shared_temp[GI + 8].best_mode; shared_temp[GI].best_partition = shared_temp[GI + 8].best_partition; } } #ifdef REF_DEVICE GroupMemoryBarrierWithGroupSync(); #endif if (threadInBlock < 4) { if ( shared_temp[GI].error > shared_temp[GI + 4].error ) { shared_temp[GI].error = shared_temp[GI + 4].error; shared_temp[GI].best_mode = shared_temp[GI + 4].best_mode; shared_temp[GI].best_partition = shared_temp[GI + 4].best_partition; } } #ifdef REF_DEVICE GroupMemoryBarrierWithGroupSync(); #endif if (threadInBlock < 2) { if ( shared_temp[GI].error > shared_temp[GI + 2].error ) { shared_temp[GI].error = shared_temp[GI + 2].error; shared_temp[GI].best_mode = shared_temp[GI + 2].best_mode; shared_temp[GI].best_partition = shared_temp[GI + 2].best_partition; } } #ifdef REF_DEVICE GroupMemoryBarrierWithGroupSync(); #endif if (threadInBlock < 1) { if ( shared_temp[GI].error > shared_temp[GI + 1].error ) { shared_temp[GI].error = shared_temp[GI + 1].error; shared_temp[GI].best_mode = shared_temp[GI + 1].best_mode; shared_temp[GI].best_partition = shared_temp[GI + 1].best_partition; } if (asfloat(g_InBuff[blockID].x) > shared_temp[GI].error) { g_OutBuff[blockID] = uint4(asuint(shared_temp[GI].error), shared_temp[GI].best_mode, shared_temp[GI].best_partition, 0); } else { g_OutBuff[blockID] = g_InBuff[blockID]; } } } [numthreads( THREAD_GROUP_SIZE, 1, 1 )] void EncodeBlockCS(uint GI : SV_GroupIndex, uint3 groupID : SV_GroupID) { const uint MAX_USED_THREAD = 32; uint BLOCK_IN_GROUP = THREAD_GROUP_SIZE / MAX_USED_THREAD; uint blockInGroup = GI / MAX_USED_THREAD; uint blockID = g_start_block_id + groupID.x * BLOCK_IN_GROUP + blockInGroup; uint threadBase = blockInGroup * MAX_USED_THREAD; uint threadInBlock = GI - threadBase; #ifndef REF_DEVICE if (blockID >= g_num_total_blocks) { return; } #endif uint block_y = blockID / g_num_block_x; uint block_x = blockID - block_y * g_num_block_x; uint base_x = block_x * BLOCK_SIZE_X; uint base_y = block_y * BLOCK_SIZE_Y; if (threadInBlock < 16) { shared_temp[GI].pixel = g_Input.Load( uint3( base_x + threadInBlock % 4, base_y + threadInBlock / 4, 0 ) ).rgb; shared_temp[GI].pixel_lum = dot(shared_temp[GI].pixel, RGB2LUM); uint3 pixel_h = float2half( shared_temp[GI].pixel ); shared_temp[GI].pixel_ph = start_quantize( pixel_h ); } #ifdef REF_DEVICE GroupMemoryBarrierWithGroupSync(); #endif uint best_mode = g_InBuff[blockID].y; uint best_partition = g_InBuff[blockID].z; uint4 block = 0; if (threadInBlock < 32) { int2x3 endPoint; endPoint[0] = MAX_INT; endPoint[1] = MIN_INT; float2 endPoint_lum; endPoint_lum[0] = MAX_FLOAT; endPoint_lum[1] = MIN_FLOAT; int2 endPoint_lum_index; endPoint_lum_index[0] = -1; endPoint_lum_index[1] = -1; int3 pixel_ph = shared_temp[threadBase + (threadInBlock & 0xF)].pixel_ph; float pixel_lum = shared_temp[threadBase + (threadInBlock & 0xF)].pixel_lum; if (threadInBlock < 16) { if (best_mode > 10) { endPoint[0] = endPoint[1] = pixel_ph; endPoint_lum[0] = endPoint_lum[1] = pixel_lum; } else { uint bits = candidateSectionBit[best_partition]; if (0 == ((bits >> threadInBlock) & 1)) { endPoint[0] = endPoint[1] = pixel_ph; endPoint_lum[0] = endPoint_lum[1] = pixel_lum; } } } else { if (best_mode <= 10) { uint bits = candidateSectionBit[best_partition]; if (1 == ((bits >> (threadInBlock & 0xF)) & 1)) { endPoint[0] = endPoint[1] = pixel_ph; endPoint_lum[0] = endPoint_lum[1] = pixel_lum; } } } shared_temp[GI].endPoint_low = endPoint[0]; shared_temp[GI].endPoint_high = endPoint[1]; shared_temp[GI].endPoint_lum_low = endPoint_lum[0]; shared_temp[GI].endPoint_lum_high = endPoint_lum[1]; } #ifdef REF_DEVICE GroupMemoryBarrierWithGroupSync(); #endif if ((threadInBlock & 0xF) < 8) { if (shared_temp[GI].endPoint_lum_low > shared_temp[GI + 8].endPoint_lum_low) { shared_temp[GI].endPoint_low = shared_temp[GI + 8].endPoint_low; shared_temp[GI].endPoint_lum_low = shared_temp[GI + 8].endPoint_lum_low; } if (shared_temp[GI].endPoint_lum_high < shared_temp[GI + 8].endPoint_lum_high) { shared_temp[GI].endPoint_high = shared_temp[GI + 8].endPoint_high; shared_temp[GI].endPoint_lum_high = shared_temp[GI + 8].endPoint_lum_high; } } #ifdef REF_DEVICE GroupMemoryBarrierWithGroupSync(); #endif if ((threadInBlock & 0xF) < 4) { if (shared_temp[GI].endPoint_lum_low > shared_temp[GI + 4].endPoint_lum_low) { shared_temp[GI].endPoint_low = shared_temp[GI + 4].endPoint_low; shared_temp[GI].endPoint_lum_low = shared_temp[GI + 4].endPoint_lum_low; } if (shared_temp[GI].endPoint_lum_high < shared_temp[GI + 4].endPoint_lum_high) { shared_temp[GI].endPoint_high = shared_temp[GI + 4].endPoint_high; shared_temp[GI].endPoint_lum_high = shared_temp[GI + 4].endPoint_lum_high; } } #ifdef REF_DEVICE GroupMemoryBarrierWithGroupSync(); #endif if ((threadInBlock & 0xF) < 2) { if (shared_temp[GI].endPoint_lum_low > shared_temp[GI + 2].endPoint_lum_low) { shared_temp[GI].endPoint_low = shared_temp[GI + 2].endPoint_low; shared_temp[GI].endPoint_lum_low = shared_temp[GI + 2].endPoint_lum_low; } if (shared_temp[GI].endPoint_lum_high < shared_temp[GI + 2].endPoint_lum_high) { shared_temp[GI].endPoint_high = shared_temp[GI + 2].endPoint_high; shared_temp[GI].endPoint_lum_high = shared_temp[GI + 2].endPoint_lum_high; } } #ifdef REF_DEVICE GroupMemoryBarrierWithGroupSync(); #endif if ((threadInBlock & 0xF) < 1) { if (shared_temp[GI].endPoint_lum_low > shared_temp[GI + 1].endPoint_lum_low) { shared_temp[GI].endPoint_low = shared_temp[GI + 1].endPoint_low; shared_temp[GI].endPoint_lum_low = shared_temp[GI + 1].endPoint_lum_low; } if (shared_temp[GI].endPoint_lum_high < shared_temp[GI + 1].endPoint_lum_high) { shared_temp[GI].endPoint_high = shared_temp[GI + 1].endPoint_high; shared_temp[GI].endPoint_lum_high = shared_temp[GI + 1].endPoint_lum_high; } } #ifdef REF_DEVICE GroupMemoryBarrierWithGroupSync(); #endif if (threadInBlock < 2) { // find_axis int2x3 endPoint; endPoint[0] = shared_temp[threadBase + threadInBlock * 16].endPoint_low; endPoint[1] = shared_temp[threadBase + threadInBlock * 16].endPoint_high; uint fixup = 0; if ((1 == threadInBlock) && (best_mode <= 10)) { fixup = candidateFixUpIndex1D[best_partition]; } float3 span = endPoint[1] - endPoint[0]; float span_norm_sqr = dot( span, span ); float dotProduct = dot( span, shared_temp[threadBase + fixup].pixel_ph - endPoint[0] ); if ( span_norm_sqr > 0 && dotProduct >= 0 && uint( dotProduct * 63.49999 / span_norm_sqr ) > 32 ) { swap(endPoint[0], endPoint[1]); } shared_temp[GI].endPoint_low = endPoint[0]; shared_temp[GI].endPoint_high = endPoint[1]; } #ifdef REF_DEVICE GroupMemoryBarrierWithGroupSync(); #endif if (threadInBlock < 16) { uint bits; if (best_mode > 10) { bits = 0; } else { bits = candidateSectionBit[best_partition]; } float3 span; float dotProduct; if ((bits >> threadInBlock) & 1) { span = shared_temp[threadBase + 1].endPoint_high - shared_temp[threadBase + 1].endPoint_low; dotProduct = dot( span, shared_temp[threadBase + threadInBlock].pixel_ph - shared_temp[threadBase + 1].endPoint_low ); } else { span = shared_temp[threadBase + 0].endPoint_high - shared_temp[threadBase + 0].endPoint_low; dotProduct = dot( span, shared_temp[threadBase + threadInBlock].pixel_ph - shared_temp[threadBase + 0].endPoint_low ); } float span_norm_sqr = dot( span, span ); if (best_mode > 10) { uint index = ( span_norm_sqr <= 0 || dotProduct <= 0 ) ? 0 : ( ( dotProduct < span_norm_sqr ) ? aStep2[ uint( dotProduct * 63.49999 / span_norm_sqr ) ] : aStep2[63] ); if (threadInBlock == 0) { block.z |= index << 1; } else if (threadInBlock < 8) { block.z |= index << (threadInBlock * 4); } else { block.w |= index << ((threadInBlock - 8) * 4); } } else { uint index = ( span_norm_sqr <= 0 || dotProduct <= 0 ) ? 0 : ( ( dotProduct < span_norm_sqr ) ? aStep1[ uint( dotProduct * 63.49999 / span_norm_sqr ) ] : aStep1[63] ); uint fixup = candidateFixUpIndex1D[best_partition]; int2 offset = int2((fixup != 2), (fixup == 15)); if (threadInBlock == 0) { block.z |= index << 18; } else if (threadInBlock < 3) { block.z |= index << (20 + (threadInBlock - 1) * 3); } else if (threadInBlock < 5) { block.z |= index << (25 + (threadInBlock - 3) * 3 + offset.x); } else if (threadInBlock == 5) { block.w |= index >> !offset.x; if (!offset.x) { block.z |= index << 31; } } else if (threadInBlock < 9) { block.w |= index << (2 + (threadInBlock - 6) * 3 + offset.x); } else { block.w |= index << (11 + (threadInBlock - 9) * 3 + offset.y); } } shared_temp[GI].pixel_hr.xy = asfloat(block.zw); } #ifdef REF_DEVICE GroupMemoryBarrierWithGroupSync(); #endif if (threadInBlock < 8) { shared_temp[GI].pixel_hr.xy = asfloat(asuint(shared_temp[GI].pixel_hr.xy) | asuint(shared_temp[GI + 8].pixel_hr.xy)); } #ifdef REF_DEVICE GroupMemoryBarrierWithGroupSync(); #endif if (threadInBlock < 4) { shared_temp[GI].pixel_hr.xy = asfloat(asuint(shared_temp[GI].pixel_hr.xy) | asuint(shared_temp[GI + 4].pixel_hr.xy)); } #ifdef REF_DEVICE GroupMemoryBarrierWithGroupSync(); #endif if (threadInBlock < 2) { shared_temp[GI].pixel_hr.xy = asfloat(asuint(shared_temp[GI].pixel_hr.xy) | asuint(shared_temp[GI + 2].pixel_hr.xy)); } #ifdef REF_DEVICE GroupMemoryBarrierWithGroupSync(); #endif if (threadInBlock < 1) { shared_temp[GI].pixel_hr.xy = asfloat(asuint(shared_temp[GI].pixel_hr.xy) | asuint(shared_temp[GI + 1].pixel_hr.xy)); block.zw = asuint(shared_temp[GI].pixel_hr.xy); } #ifdef REF_DEVICE GroupMemoryBarrierWithGroupSync(); #endif bool transformed = candidateModeTransformed[best_mode - 1]; uint4 prec = candidateModePrec[best_mode - 1]; if (threadInBlock == 2) { int2x3 endPoint_q; endPoint_q[0] = shared_temp[threadBase + 0].endPoint_low; endPoint_q[1] = shared_temp[threadBase + 0].endPoint_high; quantize( endPoint_q, prec.x ); if (transformed) { endPoint_q[1] -= endPoint_q[0]; } shared_temp[GI].endPoint_low = endPoint_q[0]; shared_temp[GI].endPoint_high = endPoint_q[1]; } #ifdef REF_DEVICE GroupMemoryBarrierWithGroupSync(); #endif if (threadInBlock == 3) { int3 ep0 = shared_temp[threadBase + 2].endPoint_low; int2x3 endPoint_q; endPoint_q[0] = shared_temp[threadBase + 1].endPoint_low; endPoint_q[1] = shared_temp[threadBase + 1].endPoint_high; if (best_mode <= 10) { quantize( endPoint_q, prec.x ); if (transformed) { endPoint_q[0] -= ep0; endPoint_q[1] -= ep0; } shared_temp[GI].endPoint_low = endPoint_q[0]; shared_temp[GI].endPoint_high = endPoint_q[1]; } } #ifdef REF_DEVICE GroupMemoryBarrierWithGroupSync(); #endif if (threadInBlock < 2) { int2x3 endPoint_q; endPoint_q[0] = shared_temp[threadBase + threadInBlock + 2].endPoint_low; endPoint_q[1] = shared_temp[threadBase + threadInBlock + 2].endPoint_high; int bBadQuantize = 0; if (threadInBlock == 0) { if (best_mode > 10) { finish_quantize( bBadQuantize, endPoint_q, prec, transformed ); } else { finish_quantize_0( bBadQuantize, endPoint_q, prec, transformed ); } } else // if (threadInBlock == 1) { if (best_mode <= 10) { finish_quantize_1( bBadQuantize, endPoint_q, prec, transformed ); } } shared_temp[GI].endPoint_low = endPoint_q[0]; shared_temp[GI].endPoint_high = endPoint_q[1]; } #ifdef REF_DEVICE GroupMemoryBarrierWithGroupSync(); #endif if ( threadInBlock == 0 ) { int2x3 endPoint_q[2]; endPoint_q[0][0] = shared_temp[threadBase + 0].endPoint_low; endPoint_q[0][1] = shared_temp[threadBase + 0].endPoint_high; endPoint_q[1][0] = shared_temp[threadBase + 1].endPoint_low; endPoint_q[1][1] = shared_temp[threadBase + 1].endPoint_high; if ( best_mode > 10 ) { block_package( block, endPoint_q[0], best_mode ); } else { block_package( block, endPoint_q, best_mode, best_partition ); } g_OutBuff[blockID] = block; } } uint float2half1( float f ) { uint Result; uint IValue = asuint(f); uint Sign = (IValue & 0x80000000U) >> 16U; IValue = IValue & 0x7FFFFFFFU; if (IValue > 0x47FFEFFFU) { // The number is too large to be represented as a half. Saturate to infinity. Result = 0x7FFFU; } else { if (IValue < 0x38800000U) { // The number is too small to be represented as a normalized half. // Convert it to a denormalized value. uint Shift = 113U - (IValue >> 23U); IValue = (0x800000U | (IValue & 0x7FFFFFU)) >> Shift; } else { // Rebias the exponent to represent the value as a normalized half. IValue += 0xC8000000U; } Result = ((IValue + 0x0FFFU + ((IValue >> 13U) & 1U)) >> 13U)&0x7FFFU; } return (Result|Sign); } uint3 float2half( float3 endPoint_f ) { //uint3 sign = asuint(endPoint_f) & 0x80000000; //uint3 expo = asuint(endPoint_f) & 0x7F800000; //uint3 base = asuint(endPoint_f) & 0x007FFFFF; //return ( expo < 0x33800000 ) ? 0 // //0x33800000 indicating 2^-24, which is minimal denormalized number that half can present // : ( ( expo < 0x38800000 ) ? ( sign >> 16 ) | ( ( base + 0x00800000 ) >> ( 23 - ( ( expo - 0x33800000 ) >> 23 ) ) )//fixed a bug in v0.2 // //0x38800000 indicating 2^-14, which is minimal normalized number that half can present, so need to use denormalized half presentation // : ( ( expo == 0x7F800000 || expo > 0x47000000 ) ? ( ( sign >> 16 ) | 0x7bff ) // // treat NaN as INF, treat INF (including NaN) as the maximum/minimum number that half can present // // 0x47000000 indicating 2^15, which is maximum exponent that half can present, so cut to 0x7bff which is the maximum half number // : ( ( sign >> 16 ) | ( ( ( expo - 0x38000000 ) | base ) >> 13 ) ) ) ); return uint3( float2half1( endPoint_f.x ), float2half1( endPoint_f.y ), float2half1( endPoint_f.z ) ); } int3 start_quantize( uint3 pixel_h ) { if ( g_format == UNSIGNED_F16 ) { return asint( ( pixel_h << 6 ) / 31 ); } else { return ( pixel_h < 0x8000 ) ? ( ( pixel_h == 0x7bff ) ? 0x7fff : asint( ( pixel_h << 5 ) / 31 ) )// fixed a bug in v0.2 : ( ( pixel_h == 0x7bff ) ? 0xffff8001 : -asint( ( ( 0x00007fff & pixel_h ) << 5 ) / 31 ) );// fixed a bug in v0.2 } } void quantize( inout int2x3 endPoint, uint prec ) { int iprec = asint( prec ); if ( g_format == UNSIGNED_F16 ) { endPoint = ( ( iprec >= 15 ) | ( endPoint == 0 ) ) ? endPoint : ( ( endPoint == asint(0xFFFF) ) ? ( ( 1 << iprec ) - 1 ) : ( ( ( endPoint << iprec ) + asint(0x0000) ) >> 16 ) ); } else { endPoint = ( ( iprec >= 16 ) | ( endPoint == 0 ) ) ? endPoint : ( ( endPoint >= 0 ) ? ( ( endPoint == asint(0x7FFF) ) ? ( ( 1 << ( iprec - 1 ) ) - 1 ) : ( ( ( endPoint << ( iprec - 1 ) ) + asint(0x0000) ) >> 15 ) ) : ( ( -endPoint == asint(0x7FFF) ) ? -( ( 1 << ( iprec - 1 ) ) - 1 ) : -( ( ( -endPoint << ( iprec - 1 ) ) + asint(0x0000) ) >> 15 ) ) ); } } void finish_quantize_0( inout int bBadQuantize, inout int2x3 endPoint, uint4 prec, bool transformed ) { if ( transformed ) { bool3 bBadComponent = ( endPoint[1] >= 0 ) ? ( endPoint[1] >= ( 1 << ( prec.yzw - 1 ) ) ) : ( -endPoint[1] > ( 1 << ( prec.yzw - 1 ) ) ); bBadQuantize |= any(bBadComponent); endPoint[0] = endPoint[0] & ( ( 1 << prec.x ) - 1 ); endPoint[1] = ( endPoint[1] >= 0 ) ? ( ( endPoint[1] >= ( 1 << ( prec.yzw - 1 ) ) ) ? ( ( 1 << ( prec.yzw - 1 ) ) - 1 ) : endPoint[1] ) : ( ( -endPoint[1] > ( 1 << ( prec.yzw - 1 ) ) ) ? ( 1 << ( prec.yzw - 1 ) ) : ( endPoint[1] & ( ( 1 << prec.yzw ) - 1 ) ) ); } else { endPoint &= ( ( 1 << prec.x ) - 1 ); } } void finish_quantize_1( inout int bBadQuantize, inout int2x3 endPoint, uint4 prec, bool transformed ) { if ( transformed ) { bool2x3 bBadComponent; bBadComponent[0] = ( endPoint[0] >= 0 ) ? ( endPoint[0] >= ( 1 << ( prec.yzw - 1 ) ) ) : ( -endPoint[0] > ( 1 << ( prec.yzw - 1 ) ) ); bBadComponent[1] = ( endPoint[1] >= 0 ) ? ( endPoint[1] >= ( 1 << ( prec.yzw - 1 ) ) ) : ( -endPoint[1] > ( 1 << ( prec.yzw - 1 ) ) ); bBadQuantize |= any(bBadComponent); endPoint[0] = ( endPoint[0] >= 0 ) ? ( ( endPoint[0] >= ( 1 << ( prec.yzw - 1 ) ) ) ? ( ( 1 << ( prec.yzw - 1 ) ) - 1 ) : endPoint[0] ) : ( ( -endPoint[0] > ( 1 << ( prec.yzw - 1 ) ) ) ? ( 1 << ( prec.yzw - 1 ) ) : ( endPoint[0] & ( ( 1 << prec.yzw ) - 1 ) ) ); endPoint[1] = ( endPoint[1] >= 0 ) ? ( ( endPoint[1] >= ( 1 << ( prec.yzw - 1 ) ) ) ? ( ( 1 << ( prec.yzw - 1 ) ) - 1 ) : endPoint[1] ) : ( ( -endPoint[1] > ( 1 << ( prec.yzw - 1 ) ) ) ? ( 1 << ( prec.yzw - 1 ) ) : ( endPoint[1] & ( ( 1 << prec.yzw ) - 1 ) ) ); } else { endPoint &= ( ( 1 << prec.x ) - 1 ); } } void finish_quantize( out bool bBadQuantize, inout int2x3 endPoint, uint4 prec, bool transformed ) { if ( transformed ) { bool3 bBadComponent; bBadComponent = ( endPoint[1] >= 0 ) ? ( endPoint[1] >= ( 1 << ( prec.yzw - 1 ) ) ) : ( -endPoint[1] > ( 1 << ( prec.yzw - 1 ) ) ); bBadQuantize = any( bBadComponent ); endPoint[0] = endPoint[0] & ( ( 1 << prec.x ) - 1 ); endPoint[1] = ( endPoint[1] >= 0 ) ? ( ( endPoint[1] >= ( 1 << ( prec.yzw - 1 ) ) ) ? ( ( 1 << ( prec.yzw - 1 ) ) - 1 ) : endPoint[1] ) : ( ( -endPoint[1] > ( 1 << ( prec.yzw - 1 ) ) ) ? ( 1 << ( prec.yzw - 1 ) ) : ( endPoint[1] & ( ( 1 << prec.yzw ) - 1 ) ) ); } else { endPoint &= ( ( 1 << prec.x ) - 1 ); bBadQuantize = 0; } } void SIGN_EXTEND( uint3 prec, inout int3 color ) { uint3 p = 1 << (prec - 1); color = (color & p) ? (color & (p - 1)) - p : color; } void sign_extend( bool transformed, uint4 prec, inout int2x3 endPoint ) { if ( g_format == SIGNED_F16 ) SIGN_EXTEND( prec.x, endPoint[0] ); if ( g_format == SIGNED_F16 || transformed ) SIGN_EXTEND( prec.yzw, endPoint[1] ); } void sign_extend( bool transformed, uint4 prec, inout int2x3 endPoint[2] ) { if ( g_format == SIGNED_F16 ) SIGN_EXTEND( prec.x, endPoint[0][0] ); if ( g_format == SIGNED_F16 || transformed ) { SIGN_EXTEND( prec.yzw, endPoint[0][1] ); SIGN_EXTEND( prec.yzw, endPoint[1][0] ); SIGN_EXTEND( prec.yzw, endPoint[1][1] ); } } void start_unquantize( inout int2x3 endPoint[2], uint4 prec, bool transformed ) { sign_extend( transformed, prec, endPoint ); if ( transformed ) { endPoint[0][1] += endPoint[0][0]; endPoint[1][0] += endPoint[0][0]; endPoint[1][1] += endPoint[0][0]; } } void start_unquantize( inout int2x3 endPoint, uint4 prec, bool transformed ) { sign_extend( transformed, prec, endPoint ); if ( transformed ) endPoint[1] += endPoint[0]; } void unquantize( inout int2x3 color, uint prec ) { int iprec = asint( prec ); if (g_format == UNSIGNED_F16 ) { if (prec < 15) { color = (color != 0) ? (color == ((1 << iprec) - 1) ? 0xFFFF : (((color << 16) + 0x8000) >> iprec)) : color; } } else { if (prec < 16) { uint2x3 s = color >= 0 ? 0 : 1; color = abs(color); color = (color != 0) ? (color >= ((1 << (iprec - 1)) - 1) ? 0x7FFF : (((color << 15) + 0x4000) >> (iprec - 1))) : color; color = s > 0 ? -color : color; } } } uint3 finish_unquantize( int3 color ) { if ( g_format == UNSIGNED_F16 ) color = ( color * 31 ) >> 6; else { color = ( color < 0 ) ? -( ( -color * 31 ) >> 5 ) : ( color * 31 ) >> 5; color = ( color < 0 ) ? ( ( -color ) | 0x8000 ) : color; } return asuint(color); } void generate_palette_unquantized8( out uint3 palette, int3 low, int3 high, int i ) { static const int aWeight3[] = {0, 9, 18, 27, 37, 46, 55, 64}; int3 tmp = ( low * ( 64 - aWeight3[i] ) + high * aWeight3[i] + 32 ) >> 6; palette = finish_unquantize( tmp ); } void generate_palette_unquantized16( out uint3 palette, int3 low, int3 high, int i ) { static const int aWeight4[] = {0, 4, 9, 13, 17, 21, 26, 30, 34, 38, 43, 47, 51, 55, 60, 64}; int3 tmp = ( low * ( 64 - aWeight4[i] ) + high * aWeight4[i] + 32 ) >> 6; palette = finish_unquantize( tmp ); } float half2float1( uint Value ) { uint Mantissa = (uint)(Value & 0x03FF); uint Exponent; if ((Value & 0x7C00) != 0) // The value is normalized { Exponent = (uint)((Value >> 10) & 0x1F); } else if (Mantissa != 0) // The value is denormalized { // Normalize the value in the resulting float Exponent = 1; do { Exponent--; Mantissa <<= 1; } while ((Mantissa & 0x0400) == 0); Mantissa &= 0x03FF; } else // The value is zero { Exponent = (uint)(-112); } uint Result = ((Value & 0x8000) << 16) | // Sign ((Exponent + 112) << 23) | // Exponent (Mantissa << 13); // Mantissa return asfloat(Result); } float3 half2float(uint3 color_h ) { //uint3 sign = color_h & 0x8000; //uint3 expo = color_h & 0x7C00; //uint3 base = color_h & 0x03FF; //return ( expo == 0 ) ? asfloat( ( sign << 16 ) | asuint( float3(base) / 16777216 ) ) //16777216 = 2^24 // : asfloat( ( sign << 16 ) | ( ( ( expo + 0x1C000 ) | base ) << 13 ) ); //0x1C000 = 0x1FC00 - 0x3C00 return float3( half2float1( color_h.x ), half2float1( color_h.y ), half2float1( color_h.z ) ); } void block_package( inout uint4 block, int2x3 endPoint[2], uint mode_type, uint partition_index ) // for mode 1 - 10 { block.xy = 0; block.z &= 0xFFFC0000; //block.z |= (partition_index & 0x1f) << 13; if ( mode_type == candidateModeFlag[0]) { /*block.x = candidateModeMemory[0]; block.x |= ( ( endPoint[0][0].r << 5 ) & 0x00007FE0 ) | ( ( endPoint[0][0].g << 15 ) & 0x01FF8000 ) | ( ( endPoint[0][0].b << 25 ) & 0xFE000000 ); block.x |= ( endPoint[1][0].g >> 2 ) & 0x00000004; block.x |= ( endPoint[1][0].b >> 1 ) & 0x00000008; block.x |= endPoint[1][1].b & 0x00000010; block.y |= ( ( endPoint[0][0].b >> 7 ) & 0x00000007 ); block.y |= ( ( endPoint[0][1].r << 3 ) & 0x000000F8 ) | ( ( endPoint[0][1].g << 13 ) & 0x0003E000 ) | ( ( endPoint[0][1].b << 23 ) & 0x0F800000 ); block.yz |= ( endPoint[1][0].gr << uint2(9, 1) ) & uint2(0x00001E00, 0x0000003E); block.y |= ( endPoint[1][0].b << 29 ) & 0xE0000000; block.y |= ( ( endPoint[1][1].g << 4 ) & 0x00000100 ); block.yz |= ( endPoint[1][1].gr << uint2(19, 7) ) & uint2(0x00780000, 0x00000F80); block.yz |= ( ( endPoint[1][1].b << uint2(27, 9) ) & uint2(0x10000000, 0x00001000) ) | ( ( endPoint[1][1].b << uint2(18, 4) ) & uint2(0x00040000, 0x00000040) ); block.z |= ( endPoint[1][0].b >> 3 ) & 0x00000001;*/ block.x |= ((candidateModeMemory[0] >> 0) & 1) << 0; block.x |= ((candidateModeMemory[0] >> 1) & 1) << 1; block.x |= ((endPoint[1][0].g >> 4) & 1) << 2; block.x |= ((endPoint[1][0].b >> 4) & 1) << 3; block.x |= ((endPoint[1][1].b >> 4) & 1) << 4; block.x |= ((endPoint[0][0].r >> 0) & 1) << 5; block.x |= ((endPoint[0][0].r >> 1) & 1) << 6; block.x |= ((endPoint[0][0].r >> 2) & 1) << 7; block.x |= ((endPoint[0][0].r >> 3) & 1) << 8; block.x |= ((endPoint[0][0].r >> 4) & 1) << 9; block.x |= ((endPoint[0][0].r >> 5) & 1) << 10; block.x |= ((endPoint[0][0].r >> 6) & 1) << 11; block.x |= ((endPoint[0][0].r >> 7) & 1) << 12; block.x |= ((endPoint[0][0].r >> 8) & 1) << 13; block.x |= ((endPoint[0][0].r >> 9) & 1) << 14; block.x |= ((endPoint[0][0].g >> 0) & 1) << 15; block.x |= ((endPoint[0][0].g >> 1) & 1) << 16; block.x |= ((endPoint[0][0].g >> 2) & 1) << 17; block.x |= ((endPoint[0][0].g >> 3) & 1) << 18; block.x |= ((endPoint[0][0].g >> 4) & 1) << 19; block.x |= ((endPoint[0][0].g >> 5) & 1) << 20; block.x |= ((endPoint[0][0].g >> 6) & 1) << 21; block.x |= ((endPoint[0][0].g >> 7) & 1) << 22; block.x |= ((endPoint[0][0].g >> 8) & 1) << 23; block.x |= ((endPoint[0][0].g >> 9) & 1) << 24; block.x |= ((endPoint[0][0].b >> 0) & 1) << 25; block.x |= ((endPoint[0][0].b >> 1) & 1) << 26; block.x |= ((endPoint[0][0].b >> 2) & 1) << 27; block.x |= ((endPoint[0][0].b >> 3) & 1) << 28; block.x |= ((endPoint[0][0].b >> 4) & 1) << 29; block.x |= ((endPoint[0][0].b >> 5) & 1) << 30; block.x |= ((endPoint[0][0].b >> 6) & 1) << 31; block.y |= ((endPoint[0][0].b >> 7) & 1) << 0; block.y |= ((endPoint[0][0].b >> 8) & 1) << 1; block.y |= ((endPoint[0][0].b >> 9) & 1) << 2; block.y |= ((endPoint[0][1].r >> 0) & 1) << 3; block.y |= ((endPoint[0][1].r >> 1) & 1) << 4; block.y |= ((endPoint[0][1].r >> 2) & 1) << 5; block.y |= ((endPoint[0][1].r >> 3) & 1) << 6; block.y |= ((endPoint[0][1].r >> 4) & 1) << 7; block.y |= ((endPoint[1][1].g >> 4) & 1) << 8; block.y |= ((endPoint[1][0].g >> 0) & 1) << 9; block.y |= ((endPoint[1][0].g >> 1) & 1) << 10; block.y |= ((endPoint[1][0].g >> 2) & 1) << 11; block.y |= ((endPoint[1][0].g >> 3) & 1) << 12; block.y |= ((endPoint[0][1].g >> 0) & 1) << 13; block.y |= ((endPoint[0][1].g >> 1) & 1) << 14; block.y |= ((endPoint[0][1].g >> 2) & 1) << 15; block.y |= ((endPoint[0][1].g >> 3) & 1) << 16; block.y |= ((endPoint[0][1].g >> 4) & 1) << 17; block.y |= ((endPoint[1][1].b >> 0) & 1) << 18; block.y |= ((endPoint[1][1].g >> 0) & 1) << 19; block.y |= ((endPoint[1][1].g >> 1) & 1) << 20; block.y |= ((endPoint[1][1].g >> 2) & 1) << 21; block.y |= ((endPoint[1][1].g >> 3) & 1) << 22; block.y |= ((endPoint[0][1].b >> 0) & 1) << 23; block.y |= ((endPoint[0][1].b >> 1) & 1) << 24; block.y |= ((endPoint[0][1].b >> 2) & 1) << 25; block.y |= ((endPoint[0][1].b >> 3) & 1) << 26; block.y |= ((endPoint[0][1].b >> 4) & 1) << 27; block.y |= ((endPoint[1][1].b >> 1) & 1) << 28; block.y |= ((endPoint[1][0].b >> 0) & 1) << 29; block.y |= ((endPoint[1][0].b >> 1) & 1) << 30; block.y |= ((endPoint[1][0].b >> 2) & 1) << 31; block.z |= ((endPoint[1][0].b >> 3) & 1) << 0; block.z |= ((endPoint[1][0].r >> 0) & 1) << 1; block.z |= ((endPoint[1][0].r >> 1) & 1) << 2; block.z |= ((endPoint[1][0].r >> 2) & 1) << 3; block.z |= ((endPoint[1][0].r >> 3) & 1) << 4; block.z |= ((endPoint[1][0].r >> 4) & 1) << 5; block.z |= ((endPoint[1][1].b >> 2) & 1) << 6; block.z |= ((endPoint[1][1].r >> 0) & 1) << 7; block.z |= ((endPoint[1][1].r >> 1) & 1) << 8; block.z |= ((endPoint[1][1].r >> 2) & 1) << 9; block.z |= ((endPoint[1][1].r >> 3) & 1) << 10; block.z |= ((endPoint[1][1].r >> 4) & 1) << 11; block.z |= ((endPoint[1][1].b >> 3) & 1) << 12; block.z |= ((partition_index >> 0) & 1) << 13; block.z |= ((partition_index >> 1) & 1) << 14; block.z |= ((partition_index >> 2) & 1) << 15; block.z |= ((partition_index >> 3) & 1) << 16; block.z |= ((partition_index >> 4) & 1) << 17; } else if ( mode_type == candidateModeFlag[1]) { /*block.x = candidateModeMemory[1]; block.x |= ( ( endPoint[0][0].r << 5 ) & 0x00000FE0 ) | ( ( endPoint[0][0].g << 15 ) & 0x003F8000 ) | ( ( endPoint[0][0].b << 25 ) & 0xFE000000 ); block.y |= ( ( endPoint[0][1].r << 3 ) & 0x000001F8 ) | ( ( endPoint[0][1].g << 13 ) & 0x0007E000 ) | ( ( endPoint[0][1].b << 23 ) & 0x1F800000 ); block.x |= ( ( endPoint[1][0].g >> 3 ) & 0x00000004 ) | ( ( endPoint[1][0].g << 20 ) & 0x01000000 ); block.x |= ( endPoint[1][1].g >> 1 ) & 0x00000018; block.x |= ( ( endPoint[1][1].b << 21 ) & 0x00800000 ) | ( ( endPoint[1][1].b << 12 ) & 0x00003000 ); block.x |= ( ( endPoint[1][0].b << 17 ) & 0x00400000 ) | ( ( endPoint[1][0].b << 10 ) & 0x00004000 ); block.yz |= ( endPoint[1][0].gr << uint2(9, 1) ) & uint2(0x00001E00, 0x0000007E); block.y |= ( endPoint[1][0].b << 29 ) & 0xE0000000; block.yz |= ( endPoint[1][1].gr << uint2(19, 7) ) & uint2(0x00780000, 0x00001F80); block.y |= ( ( endPoint[1][1].b >> 4 ) & 0x00000002 ) | ( ( endPoint[1][1].b >> 2 ) & 0x00000004 ) | ( ( endPoint[1][1].b >> 3 ) & 0x00000001 ); block.z |= ( endPoint[1][0].b >> 3 ) & 0x00000001;*/ block.x |= ((candidateModeMemory[1] >> 0) & 1) << 0; block.x |= ((candidateModeMemory[1] >> 1) & 1) << 1; block.x |= ((endPoint[1][0].g >> 5) & 1) << 2; block.x |= ((endPoint[1][1].g >> 4) & 1) << 3; block.x |= ((endPoint[1][1].g >> 5) & 1) << 4; block.x |= ((endPoint[0][0].r >> 0) & 1) << 5; block.x |= ((endPoint[0][0].r >> 1) & 1) << 6; block.x |= ((endPoint[0][0].r >> 2) & 1) << 7; block.x |= ((endPoint[0][0].r >> 3) & 1) << 8; block.x |= ((endPoint[0][0].r >> 4) & 1) << 9; block.x |= ((endPoint[0][0].r >> 5) & 1) << 10; block.x |= ((endPoint[0][0].r >> 6) & 1) << 11; block.x |= ((endPoint[1][1].b >> 0) & 1) << 12; block.x |= ((endPoint[1][1].b >> 1) & 1) << 13; block.x |= ((endPoint[1][0].b >> 4) & 1) << 14; block.x |= ((endPoint[0][0].g >> 0) & 1) << 15; block.x |= ((endPoint[0][0].g >> 1) & 1) << 16; block.x |= ((endPoint[0][0].g >> 2) & 1) << 17; block.x |= ((endPoint[0][0].g >> 3) & 1) << 18; block.x |= ((endPoint[0][0].g >> 4) & 1) << 19; block.x |= ((endPoint[0][0].g >> 5) & 1) << 20; block.x |= ((endPoint[0][0].g >> 6) & 1) << 21; block.x |= ((endPoint[1][0].b >> 5) & 1) << 22; block.x |= ((endPoint[1][1].b >> 2) & 1) << 23; block.x |= ((endPoint[1][0].g >> 4) & 1) << 24; block.x |= ((endPoint[0][0].b >> 0) & 1) << 25; block.x |= ((endPoint[0][0].b >> 1) & 1) << 26; block.x |= ((endPoint[0][0].b >> 2) & 1) << 27; block.x |= ((endPoint[0][0].b >> 3) & 1) << 28; block.x |= ((endPoint[0][0].b >> 4) & 1) << 29; block.x |= ((endPoint[0][0].b >> 5) & 1) << 30; block.x |= ((endPoint[0][0].b >> 6) & 1) << 31; block.y |= ((endPoint[1][1].b >> 3) & 1) << 0; block.y |= ((endPoint[1][1].b >> 5) & 1) << 1; block.y |= ((endPoint[1][1].b >> 4) & 1) << 2; block.y |= ((endPoint[0][1].r >> 0) & 1) << 3; block.y |= ((endPoint[0][1].r >> 1) & 1) << 4; block.y |= ((endPoint[0][1].r >> 2) & 1) << 5; block.y |= ((endPoint[0][1].r >> 3) & 1) << 6; block.y |= ((endPoint[0][1].r >> 4) & 1) << 7; block.y |= ((endPoint[0][1].r >> 5) & 1) << 8; block.y |= ((endPoint[1][0].g >> 0) & 1) << 9; block.y |= ((endPoint[1][0].g >> 1) & 1) << 10; block.y |= ((endPoint[1][0].g >> 2) & 1) << 11; block.y |= ((endPoint[1][0].g >> 3) & 1) << 12; block.y |= ((endPoint[0][1].g >> 0) & 1) << 13; block.y |= ((endPoint[0][1].g >> 1) & 1) << 14; block.y |= ((endPoint[0][1].g >> 2) & 1) << 15; block.y |= ((endPoint[0][1].g >> 3) & 1) << 16; block.y |= ((endPoint[0][1].g >> 4) & 1) << 17; block.y |= ((endPoint[0][1].g >> 5) & 1) << 18; block.y |= ((endPoint[1][1].g >> 0) & 1) << 19; block.y |= ((endPoint[1][1].g >> 1) & 1) << 20; block.y |= ((endPoint[1][1].g >> 2) & 1) << 21; block.y |= ((endPoint[1][1].g >> 3) & 1) << 22; block.y |= ((endPoint[0][1].b >> 0) & 1) << 23; block.y |= ((endPoint[0][1].b >> 1) & 1) << 24; block.y |= ((endPoint[0][1].b >> 2) & 1) << 25; block.y |= ((endPoint[0][1].b >> 3) & 1) << 26; block.y |= ((endPoint[0][1].b >> 4) & 1) << 27; block.y |= ((endPoint[0][1].b >> 5) & 1) << 28; block.y |= ((endPoint[1][0].b >> 0) & 1) << 29; block.y |= ((endPoint[1][0].b >> 1) & 1) << 30; block.y |= ((endPoint[1][0].b >> 2) & 1) << 31; block.z |= ((endPoint[1][0].b >> 3) & 1) << 0; block.z |= ((endPoint[1][0].r >> 0) & 1) << 1; block.z |= ((endPoint[1][0].r >> 1) & 1) << 2; block.z |= ((endPoint[1][0].r >> 2) & 1) << 3; block.z |= ((endPoint[1][0].r >> 3) & 1) << 4; block.z |= ((endPoint[1][0].r >> 4) & 1) << 5; block.z |= ((endPoint[1][0].r >> 5) & 1) << 6; block.z |= ((endPoint[1][1].r >> 0) & 1) << 7; block.z |= ((endPoint[1][1].r >> 1) & 1) << 8; block.z |= ((endPoint[1][1].r >> 2) & 1) << 9; block.z |= ((endPoint[1][1].r >> 3) & 1) << 10; block.z |= ((endPoint[1][1].r >> 4) & 1) << 11; block.z |= ((endPoint[1][1].r >> 5) & 1) << 12; block.z |= ((partition_index >> 0) & 1) << 13; block.z |= ((partition_index >> 1) & 1) << 14; block.z |= ((partition_index >> 2) & 1) << 15; block.z |= ((partition_index >> 3) & 1) << 16; block.z |= ((partition_index >> 4) & 1) << 17; } else if ( mode_type == candidateModeFlag[2]) { /*block.x = candidateModeMemory[2]; block.x |= ( ( endPoint[0][0].r << 5 ) & 0x00007FE0 ) | ( ( endPoint[0][0].g << 15 ) & 0x01FF8000 ) | ( ( endPoint[0][0].b << 25 ) & 0xFE000000 ); block.y |= ( endPoint[0][0].r >> 2 ) & 0x00000100; block.y |= ( endPoint[0][0].g << 7 ) & 0x00020000; block.y |= ( ( endPoint[0][0].b << 17 ) & 0x08000000 ) | ( ( endPoint[0][0].b >> 7 ) & 0x00000007 ); block.y |= ( ( endPoint[0][1].r << 3 ) & 0x000000F8 ) | ( ( endPoint[0][1].g << 13 ) & 0x0001E000 ) | ( ( endPoint[0][1].b << 23 ) & 0x07800000 ); block.yz |= ( endPoint[1][0].gr << uint2(9, 1) ) & uint2(0x00001E00, 0x0000003E); block.y |= ( endPoint[1][0].b << 29 ) & 0xE0000000; block.yz |= ( endPoint[1][1].gr << uint2(19, 7) ) & uint2(0x00780000, 0x00000F80); block.yz |= ( ( endPoint[1][1].b << uint2(27, 9) ) & uint2(0x10000000, 0x00001000) ) | ( ( endPoint[1][1].b << uint2(18, 4) ) & uint2(0x00040000, 0x00000040) ); block.z |= ( endPoint[1][0].b >> 3 ) & 0x00000001;*/ block.x |= ((candidateModeMemory[2] >> 0) & 1) << 0; block.x |= ((candidateModeMemory[2] >> 1) & 1) << 1; block.x |= ((candidateModeMemory[2] >> 2) & 1) << 2; block.x |= ((candidateModeMemory[2] >> 3) & 1) << 3; block.x |= ((candidateModeMemory[2] >> 4) & 1) << 4; block.x |= ((endPoint[0][0].r >> 0) & 1) << 5; block.x |= ((endPoint[0][0].r >> 1) & 1) << 6; block.x |= ((endPoint[0][0].r >> 2) & 1) << 7; block.x |= ((endPoint[0][0].r >> 3) & 1) << 8; block.x |= ((endPoint[0][0].r >> 4) & 1) << 9; block.x |= ((endPoint[0][0].r >> 5) & 1) << 10; block.x |= ((endPoint[0][0].r >> 6) & 1) << 11; block.x |= ((endPoint[0][0].r >> 7) & 1) << 12; block.x |= ((endPoint[0][0].r >> 8) & 1) << 13; block.x |= ((endPoint[0][0].r >> 9) & 1) << 14; block.x |= ((endPoint[0][0].g >> 0) & 1) << 15; block.x |= ((endPoint[0][0].g >> 1) & 1) << 16; block.x |= ((endPoint[0][0].g >> 2) & 1) << 17; block.x |= ((endPoint[0][0].g >> 3) & 1) << 18; block.x |= ((endPoint[0][0].g >> 4) & 1) << 19; block.x |= ((endPoint[0][0].g >> 5) & 1) << 20; block.x |= ((endPoint[0][0].g >> 6) & 1) << 21; block.x |= ((endPoint[0][0].g >> 7) & 1) << 22; block.x |= ((endPoint[0][0].g >> 8) & 1) << 23; block.x |= ((endPoint[0][0].g >> 9) & 1) << 24; block.x |= ((endPoint[0][0].b >> 0) & 1) << 25; block.x |= ((endPoint[0][0].b >> 1) & 1) << 26; block.x |= ((endPoint[0][0].b >> 2) & 1) << 27; block.x |= ((endPoint[0][0].b >> 3) & 1) << 28; block.x |= ((endPoint[0][0].b >> 4) & 1) << 29; block.x |= ((endPoint[0][0].b >> 5) & 1) << 30; block.x |= ((endPoint[0][0].b >> 6) & 1) << 31; block.y |= ((endPoint[0][0].b >> 7) & 1) << 0; block.y |= ((endPoint[0][0].b >> 8) & 1) << 1; block.y |= ((endPoint[0][0].b >> 9) & 1) << 2; block.y |= ((endPoint[0][1].r >> 0) & 1) << 3; block.y |= ((endPoint[0][1].r >> 1) & 1) << 4; block.y |= ((endPoint[0][1].r >> 2) & 1) << 5; block.y |= ((endPoint[0][1].r >> 3) & 1) << 6; block.y |= ((endPoint[0][1].r >> 4) & 1) << 7; block.y |= ((endPoint[0][0].r >> 10) & 1) << 8; block.y |= ((endPoint[1][0].g >> 0) & 1) << 9; block.y |= ((endPoint[1][0].g >> 1) & 1) << 10; block.y |= ((endPoint[1][0].g >> 2) & 1) << 11; block.y |= ((endPoint[1][0].g >> 3) & 1) << 12; block.y |= ((endPoint[0][1].g >> 0) & 1) << 13; block.y |= ((endPoint[0][1].g >> 1) & 1) << 14; block.y |= ((endPoint[0][1].g >> 2) & 1) << 15; block.y |= ((endPoint[0][1].g >> 3) & 1) << 16; block.y |= ((endPoint[0][0].g >> 10) & 1) << 17; block.y |= ((endPoint[1][1].b >> 0) & 1) << 18; block.y |= ((endPoint[1][1].g >> 0) & 1) << 19; block.y |= ((endPoint[1][1].g >> 1) & 1) << 20; block.y |= ((endPoint[1][1].g >> 2) & 1) << 21; block.y |= ((endPoint[1][1].g >> 3) & 1) << 22; block.y |= ((endPoint[0][1].b >> 0) & 1) << 23; block.y |= ((endPoint[0][1].b >> 1) & 1) << 24; block.y |= ((endPoint[0][1].b >> 2) & 1) << 25; block.y |= ((endPoint[0][1].b >> 3) & 1) << 26; block.y |= ((endPoint[0][0].b >> 10) & 1) << 27; block.y |= ((endPoint[1][1].b >> 1) & 1) << 28; block.y |= ((endPoint[1][0].b >> 0) & 1) << 29; block.y |= ((endPoint[1][0].b >> 1) & 1) << 30; block.y |= ((endPoint[1][0].b >> 2) & 1) << 31; block.z |= ((endPoint[1][0].b >> 3) & 1) << 0; block.z |= ((endPoint[1][0].r >> 0) & 1) << 1; block.z |= ((endPoint[1][0].r >> 1) & 1) << 2; block.z |= ((endPoint[1][0].r >> 2) & 1) << 3; block.z |= ((endPoint[1][0].r >> 3) & 1) << 4; block.z |= ((endPoint[1][0].r >> 4) & 1) << 5; block.z |= ((endPoint[1][1].b >> 2) & 1) << 6; block.z |= ((endPoint[1][1].r >> 0) & 1) << 7; block.z |= ((endPoint[1][1].r >> 1) & 1) << 8; block.z |= ((endPoint[1][1].r >> 2) & 1) << 9; block.z |= ((endPoint[1][1].r >> 3) & 1) << 10; block.z |= ((endPoint[1][1].r >> 4) & 1) << 11; block.z |= ((endPoint[1][1].b >> 3) & 1) << 12; block.z |= ((partition_index >> 0) & 1) << 13; block.z |= ((partition_index >> 1) & 1) << 14; block.z |= ((partition_index >> 2) & 1) << 15; block.z |= ((partition_index >> 3) & 1) << 16; block.z |= ((partition_index >> 4) & 1) << 17; } else if ( mode_type == candidateModeFlag[3]) { /*block.x = candidateModeMemory[3]; block.x |= ( ( endPoint[0][0].r << 5 ) & 0x00007FE0 ) | ( ( endPoint[0][0].g << 15 ) & 0x01FF8000 ) | ( ( endPoint[0][0].b << 25 ) & 0xFE000000 ); block.y |= ( endPoint[0][0].r >> 3 ) & 0x00000080; block.y |= ( endPoint[0][0].g << 8 ) & 0x00040000; block.y |= ( ( endPoint[0][0].b << 17 ) & 0x08000000 ) | ( ( endPoint[0][0].b >> 7 ) & 0x00000007 ); block.y |= ( ( endPoint[0][1].r << 3 ) & 0x00000078 ) | ( ( endPoint[0][1].g << 13 ) & 0x0003E000 ) | ( ( endPoint[0][1].b << 23 ) & 0x07800000 ); block.yz |= ( endPoint[1][0].gr << uint2(9, 1) ) & uint2(0x00001E00, 0x0000001E); block.y |= ( endPoint[1][0].b << 29 ) & 0xE0000000; block.y |= ( ( endPoint[1][1].g << 4 ) & 0x00000100 ); block.yz |= ( endPoint[1][1].gr << uint2(19, 7) ) & uint2(0x00780000, 0x00000780); block.yz |= ( endPoint[1][1].b << uint2(27, 9) ) & uint2(0x10000000, 0x00001000); block.z |= ( ( endPoint[1][0].g << 7 ) & 0x00000800 ); block.z |= ( endPoint[1][0].b >> 3 ) & 0x00000001; block.z |= ( endPoint[1][1].b << 4 ) & 0x00000040; block.z |= ( endPoint[1][1].b << 5 ) & 0x00000020;*/ block.x |= ((candidateModeMemory[3] >> 0) & 1) << 0; block.x |= ((candidateModeMemory[3] >> 1) & 1) << 1; block.x |= ((candidateModeMemory[3] >> 2) & 1) << 2; block.x |= ((candidateModeMemory[3] >> 3) & 1) << 3; block.x |= ((candidateModeMemory[3] >> 4) & 1) << 4; block.x |= ((endPoint[0][0].r >> 0) & 1) << 5; block.x |= ((endPoint[0][0].r >> 1) & 1) << 6; block.x |= ((endPoint[0][0].r >> 2) & 1) << 7; block.x |= ((endPoint[0][0].r >> 3) & 1) << 8; block.x |= ((endPoint[0][0].r >> 4) & 1) << 9; block.x |= ((endPoint[0][0].r >> 5) & 1) << 10; block.x |= ((endPoint[0][0].r >> 6) & 1) << 11; block.x |= ((endPoint[0][0].r >> 7) & 1) << 12; block.x |= ((endPoint[0][0].r >> 8) & 1) << 13; block.x |= ((endPoint[0][0].r >> 9) & 1) << 14; block.x |= ((endPoint[0][0].g >> 0) & 1) << 15; block.x |= ((endPoint[0][0].g >> 1) & 1) << 16; block.x |= ((endPoint[0][0].g >> 2) & 1) << 17; block.x |= ((endPoint[0][0].g >> 3) & 1) << 18; block.x |= ((endPoint[0][0].g >> 4) & 1) << 19; block.x |= ((endPoint[0][0].g >> 5) & 1) << 20; block.x |= ((endPoint[0][0].g >> 6) & 1) << 21; block.x |= ((endPoint[0][0].g >> 7) & 1) << 22; block.x |= ((endPoint[0][0].g >> 8) & 1) << 23; block.x |= ((endPoint[0][0].g >> 9) & 1) << 24; block.x |= ((endPoint[0][0].b >> 0) & 1) << 25; block.x |= ((endPoint[0][0].b >> 1) & 1) << 26; block.x |= ((endPoint[0][0].b >> 2) & 1) << 27; block.x |= ((endPoint[0][0].b >> 3) & 1) << 28; block.x |= ((endPoint[0][0].b >> 4) & 1) << 29; block.x |= ((endPoint[0][0].b >> 5) & 1) << 30; block.x |= ((endPoint[0][0].b >> 6) & 1) << 31; block.y |= ((endPoint[0][0].b >> 7) & 1) << 0; block.y |= ((endPoint[0][0].b >> 8) & 1) << 1; block.y |= ((endPoint[0][0].b >> 9) & 1) << 2; block.y |= ((endPoint[0][1].r >> 0) & 1) << 3; block.y |= ((endPoint[0][1].r >> 1) & 1) << 4; block.y |= ((endPoint[0][1].r >> 2) & 1) << 5; block.y |= ((endPoint[0][1].r >> 3) & 1) << 6; block.y |= ((endPoint[0][0].r >> 10) & 1) << 7; block.y |= ((endPoint[1][1].g >> 4) & 1) << 8; block.y |= ((endPoint[1][0].g >> 0) & 1) << 9; block.y |= ((endPoint[1][0].g >> 1) & 1) << 10; block.y |= ((endPoint[1][0].g >> 2) & 1) << 11; block.y |= ((endPoint[1][0].g >> 3) & 1) << 12; block.y |= ((endPoint[0][1].g >> 0) & 1) << 13; block.y |= ((endPoint[0][1].g >> 1) & 1) << 14; block.y |= ((endPoint[0][1].g >> 2) & 1) << 15; block.y |= ((endPoint[0][1].g >> 3) & 1) << 16; block.y |= ((endPoint[0][1].g >> 4) & 1) << 17; block.y |= ((endPoint[0][0].g >> 10) & 1) << 18; block.y |= ((endPoint[1][1].g >> 0) & 1) << 19; block.y |= ((endPoint[1][1].g >> 1) & 1) << 20; block.y |= ((endPoint[1][1].g >> 2) & 1) << 21; block.y |= ((endPoint[1][1].g >> 3) & 1) << 22; block.y |= ((endPoint[0][1].b >> 0) & 1) << 23; block.y |= ((endPoint[0][1].b >> 1) & 1) << 24; block.y |= ((endPoint[0][1].b >> 2) & 1) << 25; block.y |= ((endPoint[0][1].b >> 3) & 1) << 26; block.y |= ((endPoint[0][0].b >> 10) & 1) << 27; block.y |= ((endPoint[1][1].b >> 1) & 1) << 28; block.y |= ((endPoint[1][0].b >> 0) & 1) << 29; block.y |= ((endPoint[1][0].b >> 1) & 1) << 30; block.y |= ((endPoint[1][0].b >> 2) & 1) << 31; block.z |= ((endPoint[1][0].b >> 3) & 1) << 0; block.z |= ((endPoint[1][0].r >> 0) & 1) << 1; block.z |= ((endPoint[1][0].r >> 1) & 1) << 2; block.z |= ((endPoint[1][0].r >> 2) & 1) << 3; block.z |= ((endPoint[1][0].r >> 3) & 1) << 4; block.z |= ((endPoint[1][1].b >> 0) & 1) << 5; block.z |= ((endPoint[1][1].b >> 2) & 1) << 6; block.z |= ((endPoint[1][1].r >> 0) & 1) << 7; block.z |= ((endPoint[1][1].r >> 1) & 1) << 8; block.z |= ((endPoint[1][1].r >> 2) & 1) << 9; block.z |= ((endPoint[1][1].r >> 3) & 1) << 10; block.z |= ((endPoint[1][0].g >> 4) & 1) << 11; block.z |= ((endPoint[1][1].b >> 3) & 1) << 12; block.z |= ((partition_index >> 0) & 1) << 13; block.z |= ((partition_index >> 1) & 1) << 14; block.z |= ((partition_index >> 2) & 1) << 15; block.z |= ((partition_index >> 3) & 1) << 16; block.z |= ((partition_index >> 4) & 1) << 17; } else if ( mode_type == candidateModeFlag[4]) { /*block.x = candidateModeMemory[4]; block.x |= ( ( endPoint[0][0].r << 5 ) & 0x00007FE0 ) | ( ( endPoint[0][0].g << 15 ) & 0x01FF8000 ) | ( ( endPoint[0][0].b << 25 ) & 0xFE000000 ); block.y |= ( endPoint[0][0].r >> 3 ) & 0x00000080; block.y |= ( endPoint[0][0].g << 7 ) & 0x00020000; block.y |= ( ( endPoint[0][0].b << 18 ) & 0x10000000 ) | ( ( endPoint[0][0].b >> 7 ) & 0x00000007 ); block.y |= ( ( endPoint[0][1].r << 3 ) & 0x00000078 ) | ( ( endPoint[0][1].g << 13 ) & 0x0001E000 ) | ( ( endPoint[0][1].b << 23 ) & 0x0F800000 ); block.y |= ( ( endPoint[1][0].g << 9 ) & 0x00001E00 ) | ( ( endPoint[1][0].b << 4 ) & 0x00000100 ); block.y |= ( endPoint[1][0].b << 29 ) & 0xE0000000; block.yz |= ( endPoint[1][1].gr << uint2(19, 7) ) & uint2(0x00780000, 0x00000780); block.yz |= ( endPoint[1][1].b << uint2(18, 4) ) & uint2(0x00040000, 0x00000060); block.z |= ( endPoint[1][0].r << 1 ) & 0x0000001E; block.z |= ( endPoint[1][0].b >> 3 ) & 0x00000001; block.z |= ( ( endPoint[1][1].b << 7 ) & 0x00000800 ) | ( ( endPoint[1][1].b << 9 ) & 0x00001000 );*/ block.x |= ((candidateModeMemory[4] >> 0) & 1) << 0; block.x |= ((candidateModeMemory[4] >> 1) & 1) << 1; block.x |= ((candidateModeMemory[4] >> 2) & 1) << 2; block.x |= ((candidateModeMemory[4] >> 3) & 1) << 3; block.x |= ((candidateModeMemory[4] >> 4) & 1) << 4; block.x |= ((endPoint[0][0].r >> 0) & 1) << 5; block.x |= ((endPoint[0][0].r >> 1) & 1) << 6; block.x |= ((endPoint[0][0].r >> 2) & 1) << 7; block.x |= ((endPoint[0][0].r >> 3) & 1) << 8; block.x |= ((endPoint[0][0].r >> 4) & 1) << 9; block.x |= ((endPoint[0][0].r >> 5) & 1) << 10; block.x |= ((endPoint[0][0].r >> 6) & 1) << 11; block.x |= ((endPoint[0][0].r >> 7) & 1) << 12; block.x |= ((endPoint[0][0].r >> 8) & 1) << 13; block.x |= ((endPoint[0][0].r >> 9) & 1) << 14; block.x |= ((endPoint[0][0].g >> 0) & 1) << 15; block.x |= ((endPoint[0][0].g >> 1) & 1) << 16; block.x |= ((endPoint[0][0].g >> 2) & 1) << 17; block.x |= ((endPoint[0][0].g >> 3) & 1) << 18; block.x |= ((endPoint[0][0].g >> 4) & 1) << 19; block.x |= ((endPoint[0][0].g >> 5) & 1) << 20; block.x |= ((endPoint[0][0].g >> 6) & 1) << 21; block.x |= ((endPoint[0][0].g >> 7) & 1) << 22; block.x |= ((endPoint[0][0].g >> 8) & 1) << 23; block.x |= ((endPoint[0][0].g >> 9) & 1) << 24; block.x |= ((endPoint[0][0].b >> 0) & 1) << 25; block.x |= ((endPoint[0][0].b >> 1) & 1) << 26; block.x |= ((endPoint[0][0].b >> 2) & 1) << 27; block.x |= ((endPoint[0][0].b >> 3) & 1) << 28; block.x |= ((endPoint[0][0].b >> 4) & 1) << 29; block.x |= ((endPoint[0][0].b >> 5) & 1) << 30; block.x |= ((endPoint[0][0].b >> 6) & 1) << 31; block.y |= ((endPoint[0][0].b >> 7) & 1) << 0; block.y |= ((endPoint[0][0].b >> 8) & 1) << 1; block.y |= ((endPoint[0][0].b >> 9) & 1) << 2; block.y |= ((endPoint[0][1].r >> 0) & 1) << 3; block.y |= ((endPoint[0][1].r >> 1) & 1) << 4; block.y |= ((endPoint[0][1].r >> 2) & 1) << 5; block.y |= ((endPoint[0][1].r >> 3) & 1) << 6; block.y |= ((endPoint[0][0].r >> 10) & 1) << 7; block.y |= ((endPoint[1][0].b >> 4) & 1) << 8; block.y |= ((endPoint[1][0].g >> 0) & 1) << 9; block.y |= ((endPoint[1][0].g >> 1) & 1) << 10; block.y |= ((endPoint[1][0].g >> 2) & 1) << 11; block.y |= ((endPoint[1][0].g >> 3) & 1) << 12; block.y |= ((endPoint[0][1].g >> 0) & 1) << 13; block.y |= ((endPoint[0][1].g >> 1) & 1) << 14; block.y |= ((endPoint[0][1].g >> 2) & 1) << 15; block.y |= ((endPoint[0][1].g >> 3) & 1) << 16; block.y |= ((endPoint[0][0].g >> 10) & 1) << 17; block.y |= ((endPoint[1][1].b >> 0) & 1) << 18; block.y |= ((endPoint[1][1].g >> 0) & 1) << 19; block.y |= ((endPoint[1][1].g >> 1) & 1) << 20; block.y |= ((endPoint[1][1].g >> 2) & 1) << 21; block.y |= ((endPoint[1][1].g >> 3) & 1) << 22; block.y |= ((endPoint[0][1].b >> 0) & 1) << 23; block.y |= ((endPoint[0][1].b >> 1) & 1) << 24; block.y |= ((endPoint[0][1].b >> 2) & 1) << 25; block.y |= ((endPoint[0][1].b >> 3) & 1) << 26; block.y |= ((endPoint[0][1].b >> 4) & 1) << 27; block.y |= ((endPoint[0][0].b >> 10) & 1) << 28; block.y |= ((endPoint[1][0].b >> 0) & 1) << 29; block.y |= ((endPoint[1][0].b >> 1) & 1) << 30; block.y |= ((endPoint[1][0].b >> 2) & 1) << 31; block.z |= ((endPoint[1][0].b >> 3) & 1) << 0; block.z |= ((endPoint[1][0].r >> 0) & 1) << 1; block.z |= ((endPoint[1][0].r >> 1) & 1) << 2; block.z |= ((endPoint[1][0].r >> 2) & 1) << 3; block.z |= ((endPoint[1][0].r >> 3) & 1) << 4; block.z |= ((endPoint[1][1].b >> 1) & 1) << 5; block.z |= ((endPoint[1][1].b >> 2) & 1) << 6; block.z |= ((endPoint[1][1].r >> 0) & 1) << 7; block.z |= ((endPoint[1][1].r >> 1) & 1) << 8; block.z |= ((endPoint[1][1].r >> 2) & 1) << 9; block.z |= ((endPoint[1][1].r >> 3) & 1) << 10; block.z |= ((endPoint[1][1].b >> 4) & 1) << 11; block.z |= ((endPoint[1][1].b >> 3) & 1) << 12; block.z |= ((partition_index >> 0) & 1) << 13; block.z |= ((partition_index >> 1) & 1) << 14; block.z |= ((partition_index >> 2) & 1) << 15; block.z |= ((partition_index >> 3) & 1) << 16; block.z |= ((partition_index >> 4) & 1) << 17; } else if ( mode_type == candidateModeFlag[5]) { /*block.x = candidateModeMemory[5]; block.x |= ( ( endPoint[0][0].r << 5 ) & 0x00003FE0 ) | ( ( endPoint[0][0].g << 15 ) & 0x00FF8000 ) | ( ( endPoint[0][0].b << 25 ) & 0xFE000000); block.y |= ( endPoint[0][0].b >> 7 ) & 0x00000003; block.y |= ( ( endPoint[0][1].r << 3 ) & 0x000000F8 ) | ( ( endPoint[0][1].g << 13 ) & 0x0003E000 ) | ( ( endPoint[0][1].b << 23 ) & 0x0F800000 ); block.x |= ( ( endPoint[1][0].g << 20 ) & 0x01000000 ) | ( ( endPoint[1][0].b << 10 ) & 0x00004000 ); block.yz |= ( endPoint[1][0].gr << uint2(9, 1) ) & uint2(0x00001E00, 0x0000003E); block.y |= ( endPoint[1][0].b << 29 ) & 0xE0000000; block.y |= ( ( endPoint[1][1].g << 4 ) & 0x00000100 ) | ( ( endPoint[1][1].b >> 2 ) & 0x00000004 ); block.y |= ( ( endPoint[1][1].b << 27 ) & 0x10000000 ); block.yz |= ( endPoint[1][1].gr << uint2(19, 7) ) & uint2(0x00780000, 0x00000F80); block.yz |= ( endPoint[1][1].b << uint2(18, 4) ) & uint2(0x00040000, 0x00000040); block.z |= ( endPoint[1][0].b >> 3 ) & 0x00000001; block.z |= ( ( endPoint[1][1].b << 9 ) & 0x00001000 );*/ block.x |= ((candidateModeMemory[5] >> 0) & 1) << 0; block.x |= ((candidateModeMemory[5] >> 1) & 1) << 1; block.x |= ((candidateModeMemory[5] >> 2) & 1) << 2; block.x |= ((candidateModeMemory[5] >> 3) & 1) << 3; block.x |= ((candidateModeMemory[5] >> 4) & 1) << 4; block.x |= ((endPoint[0][0].r >> 0) & 1) << 5; block.x |= ((endPoint[0][0].r >> 1) & 1) << 6; block.x |= ((endPoint[0][0].r >> 2) & 1) << 7; block.x |= ((endPoint[0][0].r >> 3) & 1) << 8; block.x |= ((endPoint[0][0].r >> 4) & 1) << 9; block.x |= ((endPoint[0][0].r >> 5) & 1) << 10; block.x |= ((endPoint[0][0].r >> 6) & 1) << 11; block.x |= ((endPoint[0][0].r >> 7) & 1) << 12; block.x |= ((endPoint[0][0].r >> 8) & 1) << 13; block.x |= ((endPoint[1][0].b >> 4) & 1) << 14; block.x |= ((endPoint[0][0].g >> 0) & 1) << 15; block.x |= ((endPoint[0][0].g >> 1) & 1) << 16; block.x |= ((endPoint[0][0].g >> 2) & 1) << 17; block.x |= ((endPoint[0][0].g >> 3) & 1) << 18; block.x |= ((endPoint[0][0].g >> 4) & 1) << 19; block.x |= ((endPoint[0][0].g >> 5) & 1) << 20; block.x |= ((endPoint[0][0].g >> 6) & 1) << 21; block.x |= ((endPoint[0][0].g >> 7) & 1) << 22; block.x |= ((endPoint[0][0].g >> 8) & 1) << 23; block.x |= ((endPoint[1][0].g >> 4) & 1) << 24; block.x |= ((endPoint[0][0].b >> 0) & 1) << 25; block.x |= ((endPoint[0][0].b >> 1) & 1) << 26; block.x |= ((endPoint[0][0].b >> 2) & 1) << 27; block.x |= ((endPoint[0][0].b >> 3) & 1) << 28; block.x |= ((endPoint[0][0].b >> 4) & 1) << 29; block.x |= ((endPoint[0][0].b >> 5) & 1) << 30; block.x |= ((endPoint[0][0].b >> 6) & 1) << 31; block.y |= ((endPoint[0][0].b >> 7) & 1) << 0; block.y |= ((endPoint[0][0].b >> 8) & 1) << 1; block.y |= ((endPoint[1][1].b >> 4) & 1) << 2; block.y |= ((endPoint[0][1].r >> 0) & 1) << 3; block.y |= ((endPoint[0][1].r >> 1) & 1) << 4; block.y |= ((endPoint[0][1].r >> 2) & 1) << 5; block.y |= ((endPoint[0][1].r >> 3) & 1) << 6; block.y |= ((endPoint[0][1].r >> 4) & 1) << 7; block.y |= ((endPoint[1][1].g >> 4) & 1) << 8; block.y |= ((endPoint[1][0].g >> 0) & 1) << 9; block.y |= ((endPoint[1][0].g >> 1) & 1) << 10; block.y |= ((endPoint[1][0].g >> 2) & 1) << 11; block.y |= ((endPoint[1][0].g >> 3) & 1) << 12; block.y |= ((endPoint[0][1].g >> 0) & 1) << 13; block.y |= ((endPoint[0][1].g >> 1) & 1) << 14; block.y |= ((endPoint[0][1].g >> 2) & 1) << 15; block.y |= ((endPoint[0][1].g >> 3) & 1) << 16; block.y |= ((endPoint[0][1].g >> 4) & 1) << 17; block.y |= ((endPoint[1][1].b >> 0) & 1) << 18; block.y |= ((endPoint[1][1].g >> 0) & 1) << 19; block.y |= ((endPoint[1][1].g >> 1) & 1) << 20; block.y |= ((endPoint[1][1].g >> 2) & 1) << 21; block.y |= ((endPoint[1][1].g >> 3) & 1) << 22; block.y |= ((endPoint[0][1].b >> 0) & 1) << 23; block.y |= ((endPoint[0][1].b >> 1) & 1) << 24; block.y |= ((endPoint[0][1].b >> 2) & 1) << 25; block.y |= ((endPoint[0][1].b >> 3) & 1) << 26; block.y |= ((endPoint[0][1].b >> 4) & 1) << 27; block.y |= ((endPoint[1][1].b >> 1) & 1) << 28; block.y |= ((endPoint[1][0].b >> 0) & 1) << 29; block.y |= ((endPoint[1][0].b >> 1) & 1) << 30; block.y |= ((endPoint[1][0].b >> 2) & 1) << 31; block.z |= ((endPoint[1][0].b >> 3) & 1) << 0; block.z |= ((endPoint[1][0].r >> 0) & 1) << 1; block.z |= ((endPoint[1][0].r >> 1) & 1) << 2; block.z |= ((endPoint[1][0].r >> 2) & 1) << 3; block.z |= ((endPoint[1][0].r >> 3) & 1) << 4; block.z |= ((endPoint[1][0].r >> 4) & 1) << 5; block.z |= ((endPoint[1][1].b >> 2) & 1) << 6; block.z |= ((endPoint[1][1].r >> 0) & 1) << 7; block.z |= ((endPoint[1][1].r >> 1) & 1) << 8; block.z |= ((endPoint[1][1].r >> 2) & 1) << 9; block.z |= ((endPoint[1][1].r >> 3) & 1) << 10; block.z |= ((endPoint[1][1].r >> 4) & 1) << 11; block.z |= ((endPoint[1][1].b >> 3) & 1) << 12; block.z |= ((partition_index >> 0) & 1) << 13; block.z |= ((partition_index >> 1) & 1) << 14; block.z |= ((partition_index >> 2) & 1) << 15; block.z |= ((partition_index >> 3) & 1) << 16; block.z |= ((partition_index >> 4) & 1) << 17; } else if ( mode_type == candidateModeFlag[6]) { /*block.x = candidateModeMemory[6]; block.x |= ( ( endPoint[0][0].r << 5 ) & 0x00001FE0 ) | ( ( endPoint[0][0].g << 15 ) & 0x007F8000 ) | ( ( endPoint[0][0].b << 25 ) & 0xFE000000 ); block.y |= ( endPoint[0][0].b >> 7 ) & 0x00000001; block.y |= ( ( endPoint[0][1].r << 3 ) & 0x000001F8 ) | ( ( endPoint[0][1].g << 13 ) & 0x0003E000 ) | ( ( endPoint[0][1].b << 23 ) & 0x0F800000 ); block.x |= ( ( endPoint[1][0].g << 20 ) & 0x01000000 ) | ( ( endPoint[1][0].b << 10 ) & 0x00004000); block.x |= ( ( endPoint[1][1].g << 9 ) & 0x00002000 ) | ( ( endPoint[1][1].b << 21 ) & 0x00800000); block.yz |= ( endPoint[1][0].gr << uint2(9, 1) ) & uint2(0x00001E00, 0x0000007E); block.y |= ( endPoint[1][0].b << 29 ) & 0xE0000000; block.yz |= ( endPoint[1][1].gr << uint2(19, 7) ) & uint2(0x00780000, 0x00001F80); block.y |= ( ( endPoint[1][1].b >> 2 ) & 0x00000006 ); block.y |= ( ( endPoint[1][1].b << 27 ) & 0x10000000 ) | ( ( endPoint[1][1].b << 18 ) & 0x00040000 ); block.z |= ( endPoint[1][0].b >> 3 ) & 0x00000001;*/ block.x |= ((candidateModeMemory[6] >> 0) & 1) << 0; block.x |= ((candidateModeMemory[6] >> 1) & 1) << 1; block.x |= ((candidateModeMemory[6] >> 2) & 1) << 2; block.x |= ((candidateModeMemory[6] >> 3) & 1) << 3; block.x |= ((candidateModeMemory[6] >> 4) & 1) << 4; block.x |= ((endPoint[0][0].r >> 0) & 1) << 5; block.x |= ((endPoint[0][0].r >> 1) & 1) << 6; block.x |= ((endPoint[0][0].r >> 2) & 1) << 7; block.x |= ((endPoint[0][0].r >> 3) & 1) << 8; block.x |= ((endPoint[0][0].r >> 4) & 1) << 9; block.x |= ((endPoint[0][0].r >> 5) & 1) << 10; block.x |= ((endPoint[0][0].r >> 6) & 1) << 11; block.x |= ((endPoint[0][0].r >> 7) & 1) << 12; block.x |= ((endPoint[1][1].g >> 4) & 1) << 13; block.x |= ((endPoint[1][0].b >> 4) & 1) << 14; block.x |= ((endPoint[0][0].g >> 0) & 1) << 15; block.x |= ((endPoint[0][0].g >> 1) & 1) << 16; block.x |= ((endPoint[0][0].g >> 2) & 1) << 17; block.x |= ((endPoint[0][0].g >> 3) & 1) << 18; block.x |= ((endPoint[0][0].g >> 4) & 1) << 19; block.x |= ((endPoint[0][0].g >> 5) & 1) << 20; block.x |= ((endPoint[0][0].g >> 6) & 1) << 21; block.x |= ((endPoint[0][0].g >> 7) & 1) << 22; block.x |= ((endPoint[1][1].b >> 2) & 1) << 23; block.x |= ((endPoint[1][0].g >> 4) & 1) << 24; block.x |= ((endPoint[0][0].b >> 0) & 1) << 25; block.x |= ((endPoint[0][0].b >> 1) & 1) << 26; block.x |= ((endPoint[0][0].b >> 2) & 1) << 27; block.x |= ((endPoint[0][0].b >> 3) & 1) << 28; block.x |= ((endPoint[0][0].b >> 4) & 1) << 29; block.x |= ((endPoint[0][0].b >> 5) & 1) << 30; block.x |= ((endPoint[0][0].b >> 6) & 1) << 31; block.y |= ((endPoint[0][0].b >> 7) & 1) << 0; block.y |= ((endPoint[1][1].b >> 3) & 1) << 1; block.y |= ((endPoint[1][1].b >> 4) & 1) << 2; block.y |= ((endPoint[0][1].r >> 0) & 1) << 3; block.y |= ((endPoint[0][1].r >> 1) & 1) << 4; block.y |= ((endPoint[0][1].r >> 2) & 1) << 5; block.y |= ((endPoint[0][1].r >> 3) & 1) << 6; block.y |= ((endPoint[0][1].r >> 4) & 1) << 7; block.y |= ((endPoint[0][1].r >> 5) & 1) << 8; block.y |= ((endPoint[1][0].g >> 0) & 1) << 9; block.y |= ((endPoint[1][0].g >> 1) & 1) << 10; block.y |= ((endPoint[1][0].g >> 2) & 1) << 11; block.y |= ((endPoint[1][0].g >> 3) & 1) << 12; block.y |= ((endPoint[0][1].g >> 0) & 1) << 13; block.y |= ((endPoint[0][1].g >> 1) & 1) << 14; block.y |= ((endPoint[0][1].g >> 2) & 1) << 15; block.y |= ((endPoint[0][1].g >> 3) & 1) << 16; block.y |= ((endPoint[0][1].g >> 4) & 1) << 17; block.y |= ((endPoint[1][1].b >> 0) & 1) << 18; block.y |= ((endPoint[1][1].g >> 0) & 1) << 19; block.y |= ((endPoint[1][1].g >> 1) & 1) << 20; block.y |= ((endPoint[1][1].g >> 2) & 1) << 21; block.y |= ((endPoint[1][1].g >> 3) & 1) << 22; block.y |= ((endPoint[0][1].b >> 0) & 1) << 23; block.y |= ((endPoint[0][1].b >> 1) & 1) << 24; block.y |= ((endPoint[0][1].b >> 2) & 1) << 25; block.y |= ((endPoint[0][1].b >> 3) & 1) << 26; block.y |= ((endPoint[0][1].b >> 4) & 1) << 27; block.y |= ((endPoint[1][1].b >> 1) & 1) << 28; block.y |= ((endPoint[1][0].b >> 0) & 1) << 29; block.y |= ((endPoint[1][0].b >> 1) & 1) << 30; block.y |= ((endPoint[1][0].b >> 2) & 1) << 31; block.z |= ((endPoint[1][0].b >> 3) & 1) << 0; block.z |= ((endPoint[1][0].r >> 0) & 1) << 1; block.z |= ((endPoint[1][0].r >> 1) & 1) << 2; block.z |= ((endPoint[1][0].r >> 2) & 1) << 3; block.z |= ((endPoint[1][0].r >> 3) & 1) << 4; block.z |= ((endPoint[1][0].r >> 4) & 1) << 5; block.z |= ((endPoint[1][0].r >> 5) & 1) << 6; block.z |= ((endPoint[1][1].r >> 0) & 1) << 7; block.z |= ((endPoint[1][1].r >> 1) & 1) << 8; block.z |= ((endPoint[1][1].r >> 2) & 1) << 9; block.z |= ((endPoint[1][1].r >> 3) & 1) << 10; block.z |= ((endPoint[1][1].r >> 4) & 1) << 11; block.z |= ((endPoint[1][1].r >> 5) & 1) << 12; block.z |= ((partition_index >> 0) & 1) << 13; block.z |= ((partition_index >> 1) & 1) << 14; block.z |= ((partition_index >> 2) & 1) << 15; block.z |= ((partition_index >> 3) & 1) << 16; block.z |= ((partition_index >> 4) & 1) << 17; } else if ( mode_type == candidateModeFlag[7]) { /*block.x = candidateModeMemory[7]; block.x |= ( ( endPoint[0][0].r << 5 ) & 0x00001FE0 ) | ( ( endPoint[0][0].g << 15 ) & 0x007F8000 ) | ( ( endPoint[0][0].b << 25 ) & 0xFE000000 ); block.y |= ( endPoint[0][0].b >> 7 ) & 0x00000001; block.y |= ( ( endPoint[0][1].r << 3 ) & 0x000000F8 ) | ( ( endPoint[0][1].g << 13 ) & 0x0007E000 ) | ( ( endPoint[0][1].b << 23 ) & 0x0F800000 ); block.x |= ( ( endPoint[1][0].g << 20 ) & 0x01000000 ) | ( ( endPoint[1][0].b << 10 ) & 0x00004000 ); block.x |= ( ( endPoint[1][0].g << 18 ) & 0x00800000 ); block.x |= ( ( endPoint[1][1].b << 13 ) & 0x00002000 ); block.yz |= ( endPoint[1][0].gr << uint2(9, 1) ) & uint2(0x00001E00, 0x0000003E); block.yz |= ( endPoint[1][1].gr << uint2(19, 7) ) & uint2(0x00780000, 0x00000F80); block.y |= ( endPoint[1][0].b << 29 ) & 0xE0000000; block.y |= ( ( endPoint[1][1].g >> 4 ) & 0x00000002 ) | ( ( endPoint[1][1].g << 4 ) & 0x00000100 ) | ( ( endPoint[1][1].b >> 2 ) & 0x00000004 ); block.y |= ( endPoint[1][1].b << 27 ) & 0x10000000; block.z |= ( endPoint[1][0].b >> 3 ) & 0x00000001; block.z |= ( ( endPoint[1][1].b << 9 ) & 0x00001000 ) | ( ( endPoint[1][1].b << 4 ) & 0x00000040 );*/ block.x |= ((candidateModeMemory[7] >> 0) & 1) << 0; block.x |= ((candidateModeMemory[7] >> 1) & 1) << 1; block.x |= ((candidateModeMemory[7] >> 2) & 1) << 2; block.x |= ((candidateModeMemory[7] >> 3) & 1) << 3; block.x |= ((candidateModeMemory[7] >> 4) & 1) << 4; block.x |= ((endPoint[0][0].r >> 0) & 1) << 5; block.x |= ((endPoint[0][0].r >> 1) & 1) << 6; block.x |= ((endPoint[0][0].r >> 2) & 1) << 7; block.x |= ((endPoint[0][0].r >> 3) & 1) << 8; block.x |= ((endPoint[0][0].r >> 4) & 1) << 9; block.x |= ((endPoint[0][0].r >> 5) & 1) << 10; block.x |= ((endPoint[0][0].r >> 6) & 1) << 11; block.x |= ((endPoint[0][0].r >> 7) & 1) << 12; block.x |= ((endPoint[1][1].b >> 0) & 1) << 13; block.x |= ((endPoint[1][0].b >> 4) & 1) << 14; block.x |= ((endPoint[0][0].g >> 0) & 1) << 15; block.x |= ((endPoint[0][0].g >> 1) & 1) << 16; block.x |= ((endPoint[0][0].g >> 2) & 1) << 17; block.x |= ((endPoint[0][0].g >> 3) & 1) << 18; block.x |= ((endPoint[0][0].g >> 4) & 1) << 19; block.x |= ((endPoint[0][0].g >> 5) & 1) << 20; block.x |= ((endPoint[0][0].g >> 6) & 1) << 21; block.x |= ((endPoint[0][0].g >> 7) & 1) << 22; block.x |= ((endPoint[1][0].g >> 5) & 1) << 23; block.x |= ((endPoint[1][0].g >> 4) & 1) << 24; block.x |= ((endPoint[0][0].b >> 0) & 1) << 25; block.x |= ((endPoint[0][0].b >> 1) & 1) << 26; block.x |= ((endPoint[0][0].b >> 2) & 1) << 27; block.x |= ((endPoint[0][0].b >> 3) & 1) << 28; block.x |= ((endPoint[0][0].b >> 4) & 1) << 29; block.x |= ((endPoint[0][0].b >> 5) & 1) << 30; block.x |= ((endPoint[0][0].b >> 6) & 1) << 31; block.y |= ((endPoint[0][0].b >> 7) & 1) << 0; block.y |= ((endPoint[1][1].g >> 5) & 1) << 1; block.y |= ((endPoint[1][1].b >> 4) & 1) << 2; block.y |= ((endPoint[0][1].r >> 0) & 1) << 3; block.y |= ((endPoint[0][1].r >> 1) & 1) << 4; block.y |= ((endPoint[0][1].r >> 2) & 1) << 5; block.y |= ((endPoint[0][1].r >> 3) & 1) << 6; block.y |= ((endPoint[0][1].r >> 4) & 1) << 7; block.y |= ((endPoint[1][1].g >> 4) & 1) << 8; block.y |= ((endPoint[1][0].g >> 0) & 1) << 9; block.y |= ((endPoint[1][0].g >> 1) & 1) << 10; block.y |= ((endPoint[1][0].g >> 2) & 1) << 11; block.y |= ((endPoint[1][0].g >> 3) & 1) << 12; block.y |= ((endPoint[0][1].g >> 0) & 1) << 13; block.y |= ((endPoint[0][1].g >> 1) & 1) << 14; block.y |= ((endPoint[0][1].g >> 2) & 1) << 15; block.y |= ((endPoint[0][1].g >> 3) & 1) << 16; block.y |= ((endPoint[0][1].g >> 4) & 1) << 17; block.y |= ((endPoint[0][1].g >> 5) & 1) << 18; block.y |= ((endPoint[1][1].g >> 0) & 1) << 19; block.y |= ((endPoint[1][1].g >> 1) & 1) << 20; block.y |= ((endPoint[1][1].g >> 2) & 1) << 21; block.y |= ((endPoint[1][1].g >> 3) & 1) << 22; block.y |= ((endPoint[0][1].b >> 0) & 1) << 23; block.y |= ((endPoint[0][1].b >> 1) & 1) << 24; block.y |= ((endPoint[0][1].b >> 2) & 1) << 25; block.y |= ((endPoint[0][1].b >> 3) & 1) << 26; block.y |= ((endPoint[0][1].b >> 4) & 1) << 27; block.y |= ((endPoint[1][1].b >> 1) & 1) << 28; block.y |= ((endPoint[1][0].b >> 0) & 1) << 29; block.y |= ((endPoint[1][0].b >> 1) & 1) << 30; block.y |= ((endPoint[1][0].b >> 2) & 1) << 31; block.z |= ((endPoint[1][0].b >> 3) & 1) << 0; block.z |= ((endPoint[1][0].r >> 0) & 1) << 1; block.z |= ((endPoint[1][0].r >> 1) & 1) << 2; block.z |= ((endPoint[1][0].r >> 2) & 1) << 3; block.z |= ((endPoint[1][0].r >> 3) & 1) << 4; block.z |= ((endPoint[1][0].r >> 4) & 1) << 5; block.z |= ((endPoint[1][1].b >> 2) & 1) << 6; block.z |= ((endPoint[1][1].r >> 0) & 1) << 7; block.z |= ((endPoint[1][1].r >> 1) & 1) << 8; block.z |= ((endPoint[1][1].r >> 2) & 1) << 9; block.z |= ((endPoint[1][1].r >> 3) & 1) << 10; block.z |= ((endPoint[1][1].r >> 4) & 1) << 11; block.z |= ((endPoint[1][1].b >> 3) & 1) << 12; block.z |= ((partition_index >> 0) & 1) << 13; block.z |= ((partition_index >> 1) & 1) << 14; block.z |= ((partition_index >> 2) & 1) << 15; block.z |= ((partition_index >> 3) & 1) << 16; block.z |= ((partition_index >> 4) & 1) << 17; } else if ( mode_type == candidateModeFlag[8]) { /*block.x = candidateModeMemory[8]; block.x |= ( ( endPoint[0][0].r << 5 ) & 0x00001FE0 ) | ( ( endPoint[0][0].g << 15 ) & 0x007F8000 ) | ( ( endPoint[0][0].b << 25 ) & 0xFE000000 ); block.y |= ( endPoint[0][0].b >> 7 ) & 0x00000001; block.y |= ( ( endPoint[0][1].r << 3 ) & 0x000000F8 ) | ( ( endPoint[0][1].g << 13 ) & 0x0003E000 ) | ( ( endPoint[0][1].b << 23 ) & 0x1F800000 ); block.x |= ( ( endPoint[1][0].g << 20 ) & 0x01000000 ) | ( ( endPoint[1][0].b << 10 ) & 0x00004000 ); block.x |= ( ( endPoint[1][0].b << 18 ) & 0x00800000 ); block.x |= ( endPoint[1][1].b << 12 ) & 0x00002000; block.y |= ( endPoint[1][0].b << 29 ) & 0xE0000000; block.y |= ( ( endPoint[1][1].g << 4 ) & 0x00000100 ) | ( ( endPoint[1][1].b >> 4 ) & 0x00000002 ) | ( ( endPoint[1][1].b >> 2 ) & 0x00000004 ); block.yz |= ( endPoint[1][0].gr << uint2(9, 1) ) & uint2(0x00001E00, 0x0000003E); block.yz |= ( endPoint[1][1].gr << uint2(19, 7) ) & uint2(0x00780000, 0x00000F80); block.y |= ( endPoint[1][1].b << 18 ) & 0x00040000; block.z |= ( endPoint[1][0].b >> 3 ) & 0x00000001; block.z |= ( ( endPoint[1][1].b << 9 ) & 0x00001000 ) | ( ( endPoint[1][1].b << 4 ) & 0x00000040 );*/ block.x |= ((candidateModeMemory[8] >> 0) & 1) << 0; block.x |= ((candidateModeMemory[8] >> 1) & 1) << 1; block.x |= ((candidateModeMemory[8] >> 2) & 1) << 2; block.x |= ((candidateModeMemory[8] >> 3) & 1) << 3; block.x |= ((candidateModeMemory[8] >> 4) & 1) << 4; block.x |= ((endPoint[0][0].r >> 0) & 1) << 5; block.x |= ((endPoint[0][0].r >> 1) & 1) << 6; block.x |= ((endPoint[0][0].r >> 2) & 1) << 7; block.x |= ((endPoint[0][0].r >> 3) & 1) << 8; block.x |= ((endPoint[0][0].r >> 4) & 1) << 9; block.x |= ((endPoint[0][0].r >> 5) & 1) << 10; block.x |= ((endPoint[0][0].r >> 6) & 1) << 11; block.x |= ((endPoint[0][0].r >> 7) & 1) << 12; block.x |= ((endPoint[1][1].b >> 1) & 1) << 13; block.x |= ((endPoint[1][0].b >> 4) & 1) << 14; block.x |= ((endPoint[0][0].g >> 0) & 1) << 15; block.x |= ((endPoint[0][0].g >> 1) & 1) << 16; block.x |= ((endPoint[0][0].g >> 2) & 1) << 17; block.x |= ((endPoint[0][0].g >> 3) & 1) << 18; block.x |= ((endPoint[0][0].g >> 4) & 1) << 19; block.x |= ((endPoint[0][0].g >> 5) & 1) << 20; block.x |= ((endPoint[0][0].g >> 6) & 1) << 21; block.x |= ((endPoint[0][0].g >> 7) & 1) << 22; block.x |= ((endPoint[1][0].b >> 5) & 1) << 23; block.x |= ((endPoint[1][0].g >> 4) & 1) << 24; block.x |= ((endPoint[0][0].b >> 0) & 1) << 25; block.x |= ((endPoint[0][0].b >> 1) & 1) << 26; block.x |= ((endPoint[0][0].b >> 2) & 1) << 27; block.x |= ((endPoint[0][0].b >> 3) & 1) << 28; block.x |= ((endPoint[0][0].b >> 4) & 1) << 29; block.x |= ((endPoint[0][0].b >> 5) & 1) << 30; block.x |= ((endPoint[0][0].b >> 6) & 1) << 31; block.y |= ((endPoint[0][0].b >> 7) & 1) << 0; block.y |= ((endPoint[1][1].b >> 5) & 1) << 1; block.y |= ((endPoint[1][1].b >> 4) & 1) << 2; block.y |= ((endPoint[0][1].r >> 0) & 1) << 3; block.y |= ((endPoint[0][1].r >> 1) & 1) << 4; block.y |= ((endPoint[0][1].r >> 2) & 1) << 5; block.y |= ((endPoint[0][1].r >> 3) & 1) << 6; block.y |= ((endPoint[0][1].r >> 4) & 1) << 7; block.y |= ((endPoint[1][1].g >> 4) & 1) << 8; block.y |= ((endPoint[1][0].g >> 0) & 1) << 9; block.y |= ((endPoint[1][0].g >> 1) & 1) << 10; block.y |= ((endPoint[1][0].g >> 2) & 1) << 11; block.y |= ((endPoint[1][0].g >> 3) & 1) << 12; block.y |= ((endPoint[0][1].g >> 0) & 1) << 13; block.y |= ((endPoint[0][1].g >> 1) & 1) << 14; block.y |= ((endPoint[0][1].g >> 2) & 1) << 15; block.y |= ((endPoint[0][1].g >> 3) & 1) << 16; block.y |= ((endPoint[0][1].g >> 4) & 1) << 17; block.y |= ((endPoint[1][1].b >> 0) & 1) << 18; block.y |= ((endPoint[1][1].g >> 0) & 1) << 19; block.y |= ((endPoint[1][1].g >> 1) & 1) << 20; block.y |= ((endPoint[1][1].g >> 2) & 1) << 21; block.y |= ((endPoint[1][1].g >> 3) & 1) << 22; block.y |= ((endPoint[0][1].b >> 0) & 1) << 23; block.y |= ((endPoint[0][1].b >> 1) & 1) << 24; block.y |= ((endPoint[0][1].b >> 2) & 1) << 25; block.y |= ((endPoint[0][1].b >> 3) & 1) << 26; block.y |= ((endPoint[0][1].b >> 4) & 1) << 27; block.y |= ((endPoint[0][1].b >> 5) & 1) << 28; block.y |= ((endPoint[1][0].b >> 0) & 1) << 29; block.y |= ((endPoint[1][0].b >> 1) & 1) << 30; block.y |= ((endPoint[1][0].b >> 2) & 1) << 31; block.z |= ((endPoint[1][0].b >> 3) & 1) << 0; block.z |= ((endPoint[1][0].r >> 0) & 1) << 1; block.z |= ((endPoint[1][0].r >> 1) & 1) << 2; block.z |= ((endPoint[1][0].r >> 2) & 1) << 3; block.z |= ((endPoint[1][0].r >> 3) & 1) << 4; block.z |= ((endPoint[1][0].r >> 4) & 1) << 5; block.z |= ((endPoint[1][1].b >> 2) & 1) << 6; block.z |= ((endPoint[1][1].r >> 0) & 1) << 7; block.z |= ((endPoint[1][1].r >> 1) & 1) << 8; block.z |= ((endPoint[1][1].r >> 2) & 1) << 9; block.z |= ((endPoint[1][1].r >> 3) & 1) << 10; block.z |= ((endPoint[1][1].r >> 4) & 1) << 11; block.z |= ((endPoint[1][1].b >> 3) & 1) << 12; block.z |= ((partition_index >> 0) & 1) << 13; block.z |= ((partition_index >> 1) & 1) << 14; block.z |= ((partition_index >> 2) & 1) << 15; block.z |= ((partition_index >> 3) & 1) << 16; block.z |= ((partition_index >> 4) & 1) << 17; } else if ( mode_type == candidateModeFlag[9]) { /*block.x = candidateModeMemory[9]; block.x |= ( ( endPoint[0][0].r << 5 ) & 0x000007E0 ) | ( ( endPoint[0][0].g << 15 ) & 0x001F8000 ) | ( ( endPoint[0][0].b << 25 ) & 0x7E000000 ); block.y |= ( ( endPoint[0][1].r << 3 ) & 0x000001F8 ) | ( ( endPoint[0][1].g << 13 ) & 0x0007E000 ) | ( ( endPoint[0][1].b << 23 ) & 0x1F800000 ); block.x |= ( ( endPoint[1][0].g << 16 ) & 0x00200000 ) | ( ( endPoint[1][0].g << 20 ) & 0x01000000 ); block.x |= ( ( endPoint[1][0].b << 17 ) & 0x00400000 ) | ( ( endPoint[1][0].b << 10 ) & 0x00004000 ); block.x |= ( ( endPoint[1][1].b << 21 ) & 0x00800000 ) | ( ( endPoint[1][1].b << 12 ) & 0x00003000 ); block.x |= ( ( endPoint[1][1].g << 26 ) & 0x80000000 ) | ( ( endPoint[1][1].g << 7 ) & 0x00000800 ); block.yz |= ( endPoint[1][0].gr << uint2(9, 1) ) & uint2(0x00001E00, 0x0000007E); block.yz |= ( endPoint[1][1].gr << uint2(19, 7) ) & uint2(0x00780000, 0x00001F80); block.y |= ( endPoint[1][0].b << 29 ) & 0xE0000000; block.y |= ( ( endPoint[1][1].b >> 4 ) & 0x00000002 ) | ( ( endPoint[1][1].b >> 2 ) & 0x00000004 ) | ( ( endPoint[1][1].b >> 3 ) & 0x00000001 ); block.z |= ( endPoint[1][0].b >> 3 ) & 0x00000001;*/ block.x |= ((candidateModeMemory[9] >> 0) & 1) << 0; block.x |= ((candidateModeMemory[9] >> 1) & 1) << 1; block.x |= ((candidateModeMemory[9] >> 2) & 1) << 2; block.x |= ((candidateModeMemory[9] >> 3) & 1) << 3; block.x |= ((candidateModeMemory[9] >> 4) & 1) << 4; block.x |= ((endPoint[0][0].r >> 0) & 1) << 5; block.x |= ((endPoint[0][0].r >> 1) & 1) << 6; block.x |= ((endPoint[0][0].r >> 2) & 1) << 7; block.x |= ((endPoint[0][0].r >> 3) & 1) << 8; block.x |= ((endPoint[0][0].r >> 4) & 1) << 9; block.x |= ((endPoint[0][0].r >> 5) & 1) << 10; block.x |= ((endPoint[1][1].g >> 4) & 1) << 11; block.x |= ((endPoint[1][1].b >> 0) & 1) << 12; block.x |= ((endPoint[1][1].b >> 1) & 1) << 13; block.x |= ((endPoint[1][0].b >> 4) & 1) << 14; block.x |= ((endPoint[0][0].g >> 0) & 1) << 15; block.x |= ((endPoint[0][0].g >> 1) & 1) << 16; block.x |= ((endPoint[0][0].g >> 2) & 1) << 17; block.x |= ((endPoint[0][0].g >> 3) & 1) << 18; block.x |= ((endPoint[0][0].g >> 4) & 1) << 19; block.x |= ((endPoint[0][0].g >> 5) & 1) << 20; block.x |= ((endPoint[1][0].g >> 5) & 1) << 21; block.x |= ((endPoint[1][0].b >> 5) & 1) << 22; block.x |= ((endPoint[1][1].b >> 2) & 1) << 23; block.x |= ((endPoint[1][0].g >> 4) & 1) << 24; block.x |= ((endPoint[0][0].b >> 0) & 1) << 25; block.x |= ((endPoint[0][0].b >> 1) & 1) << 26; block.x |= ((endPoint[0][0].b >> 2) & 1) << 27; block.x |= ((endPoint[0][0].b >> 3) & 1) << 28; block.x |= ((endPoint[0][0].b >> 4) & 1) << 29; block.x |= ((endPoint[0][0].b >> 5) & 1) << 30; block.x |= ((endPoint[1][1].g >> 5) & 1) << 31; block.y |= ((endPoint[1][1].b >> 3) & 1) << 0; block.y |= ((endPoint[1][1].b >> 5) & 1) << 1; block.y |= ((endPoint[1][1].b >> 4) & 1) << 2; block.y |= ((endPoint[0][1].r >> 0) & 1) << 3; block.y |= ((endPoint[0][1].r >> 1) & 1) << 4; block.y |= ((endPoint[0][1].r >> 2) & 1) << 5; block.y |= ((endPoint[0][1].r >> 3) & 1) << 6; block.y |= ((endPoint[0][1].r >> 4) & 1) << 7; block.y |= ((endPoint[0][1].r >> 5) & 1) << 8; block.y |= ((endPoint[1][0].g >> 0) & 1) << 9; block.y |= ((endPoint[1][0].g >> 1) & 1) << 10; block.y |= ((endPoint[1][0].g >> 2) & 1) << 11; block.y |= ((endPoint[1][0].g >> 3) & 1) << 12; block.y |= ((endPoint[0][1].g >> 0) & 1) << 13; block.y |= ((endPoint[0][1].g >> 1) & 1) << 14; block.y |= ((endPoint[0][1].g >> 2) & 1) << 15; block.y |= ((endPoint[0][1].g >> 3) & 1) << 16; block.y |= ((endPoint[0][1].g >> 4) & 1) << 17; block.y |= ((endPoint[0][1].g >> 5) & 1) << 18; block.y |= ((endPoint[1][1].g >> 0) & 1) << 19; block.y |= ((endPoint[1][1].g >> 1) & 1) << 20; block.y |= ((endPoint[1][1].g >> 2) & 1) << 21; block.y |= ((endPoint[1][1].g >> 3) & 1) << 22; block.y |= ((endPoint[0][1].b >> 0) & 1) << 23; block.y |= ((endPoint[0][1].b >> 1) & 1) << 24; block.y |= ((endPoint[0][1].b >> 2) & 1) << 25; block.y |= ((endPoint[0][1].b >> 3) & 1) << 26; block.y |= ((endPoint[0][1].b >> 4) & 1) << 27; block.y |= ((endPoint[0][1].b >> 5) & 1) << 28; block.y |= ((endPoint[1][0].b >> 0) & 1) << 29; block.y |= ((endPoint[1][0].b >> 1) & 1) << 30; block.y |= ((endPoint[1][0].b >> 2) & 1) << 31; block.z |= ((endPoint[1][0].b >> 3) & 1) << 0; block.z |= ((endPoint[1][0].r >> 0) & 1) << 1; block.z |= ((endPoint[1][0].r >> 1) & 1) << 2; block.z |= ((endPoint[1][0].r >> 2) & 1) << 3; block.z |= ((endPoint[1][0].r >> 3) & 1) << 4; block.z |= ((endPoint[1][0].r >> 4) & 1) << 5; block.z |= ((endPoint[1][0].r >> 5) & 1) << 6; block.z |= ((endPoint[1][1].r >> 0) & 1) << 7; block.z |= ((endPoint[1][1].r >> 1) & 1) << 8; block.z |= ((endPoint[1][1].r >> 2) & 1) << 9; block.z |= ((endPoint[1][1].r >> 3) & 1) << 10; block.z |= ((endPoint[1][1].r >> 4) & 1) << 11; block.z |= ((endPoint[1][1].r >> 5) & 1) << 12; block.z |= ((partition_index >> 0) & 1) << 13; block.z |= ((partition_index >> 1) & 1) << 14; block.z |= ((partition_index >> 2) & 1) << 15; block.z |= ((partition_index >> 3) & 1) << 16; block.z |= ((partition_index >> 4) & 1) << 17; } } void block_package( inout uint4 block, int2x3 endPoint, uint mode_type ) // for mode 11 - 14 { /*block.x = ( ( endPoint[0].r << 5 ) & 0x00007FE0 ) | ( ( endPoint[0].g << 15 ) & 0x01FF8000 ) | ( ( endPoint[0].b << 25 ) & 0xFE000000 ); block.y |= ( endPoint[0].b >> 7 ) & 0x00000007;*/ block.xy = 0; block.z &= 0xFFFFFFFE; if ( mode_type == candidateModeFlag[10]) { /* block.x |= candidateModeMemory[10]; block.y |= ( ( endPoint[1].r << 3 ) & 0x00001FF8 ) | ( ( endPoint[1].g << 13 ) & 0x007FE000 ) | ( ( endPoint[1].b << 23 ) & 0xFF800000 ); block.z |= ( endPoint[1].b >> 9 ) & 0x00000001;*/ block.x |= ((candidateModeMemory[10] >> 0) & 1) << 0; block.x |= ((candidateModeMemory[10] >> 1) & 1) << 1; block.x |= ((candidateModeMemory[10] >> 2) & 1) << 2; block.x |= ((candidateModeMemory[10] >> 3) & 1) << 3; block.x |= ((candidateModeMemory[10] >> 4) & 1) << 4; block.x |= ((endPoint[0].r >> 0) & 1) << 5; block.x |= ((endPoint[0].r >> 1) & 1) << 6; block.x |= ((endPoint[0].r >> 2) & 1) << 7; block.x |= ((endPoint[0].r >> 3) & 1) << 8; block.x |= ((endPoint[0].r >> 4) & 1) << 9; block.x |= ((endPoint[0].r >> 5) & 1) << 10; block.x |= ((endPoint[0].r >> 6) & 1) << 11; block.x |= ((endPoint[0].r >> 7) & 1) << 12; block.x |= ((endPoint[0].r >> 8) & 1) << 13; block.x |= ((endPoint[0].r >> 9) & 1) << 14; block.x |= ((endPoint[0].g >> 0) & 1) << 15; block.x |= ((endPoint[0].g >> 1) & 1) << 16; block.x |= ((endPoint[0].g >> 2) & 1) << 17; block.x |= ((endPoint[0].g >> 3) & 1) << 18; block.x |= ((endPoint[0].g >> 4) & 1) << 19; block.x |= ((endPoint[0].g >> 5) & 1) << 20; block.x |= ((endPoint[0].g >> 6) & 1) << 21; block.x |= ((endPoint[0].g >> 7) & 1) << 22; block.x |= ((endPoint[0].g >> 8) & 1) << 23; block.x |= ((endPoint[0].g >> 9) & 1) << 24; block.x |= ((endPoint[0].b >> 0) & 1) << 25; block.x |= ((endPoint[0].b >> 1) & 1) << 26; block.x |= ((endPoint[0].b >> 2) & 1) << 27; block.x |= ((endPoint[0].b >> 3) & 1) << 28; block.x |= ((endPoint[0].b >> 4) & 1) << 29; block.x |= ((endPoint[0].b >> 5) & 1) << 30; block.x |= ((endPoint[0].b >> 6) & 1) << 31; block.y |= ((endPoint[0].b >> 7) & 1) << 0; block.y |= ((endPoint[0].b >> 8) & 1) << 1; block.y |= ((endPoint[0].b >> 9) & 1) << 2; block.y |= ((endPoint[1].r >> 0) & 1) << 3; block.y |= ((endPoint[1].r >> 1) & 1) << 4; block.y |= ((endPoint[1].r >> 2) & 1) << 5; block.y |= ((endPoint[1].r >> 3) & 1) << 6; block.y |= ((endPoint[1].r >> 4) & 1) << 7; block.y |= ((endPoint[1].r >> 5) & 1) << 8; block.y |= ((endPoint[1].r >> 6) & 1) << 9; block.y |= ((endPoint[1].r >> 7) & 1) << 10; block.y |= ((endPoint[1].r >> 8) & 1) << 11; block.y |= ((endPoint[1].r >> 9) & 1) << 12; block.y |= ((endPoint[1].g >> 0) & 1) << 13; block.y |= ((endPoint[1].g >> 1) & 1) << 14; block.y |= ((endPoint[1].g >> 2) & 1) << 15; block.y |= ((endPoint[1].g >> 3) & 1) << 16; block.y |= ((endPoint[1].g >> 4) & 1) << 17; block.y |= ((endPoint[1].g >> 5) & 1) << 18; block.y |= ((endPoint[1].g >> 6) & 1) << 19; block.y |= ((endPoint[1].g >> 7) & 1) << 20; block.y |= ((endPoint[1].g >> 8) & 1) << 21; block.y |= ((endPoint[1].g >> 9) & 1) << 22; block.y |= ((endPoint[1].b >> 0) & 1) << 23; block.y |= ((endPoint[1].b >> 1) & 1) << 24; block.y |= ((endPoint[1].b >> 2) & 1) << 25; block.y |= ((endPoint[1].b >> 3) & 1) << 26; block.y |= ((endPoint[1].b >> 4) & 1) << 27; block.y |= ((endPoint[1].b >> 5) & 1) << 28; block.y |= ((endPoint[1].b >> 6) & 1) << 29; block.y |= ((endPoint[1].b >> 7) & 1) << 30; block.y |= ((endPoint[1].b >> 8) & 1) << 31; block.z |= ((endPoint[1].b >> 9) & 1) << 0; } else if (mode_type == candidateModeFlag[11]) { /*block.x |= candidateModeMemory[11]; block.y |= ( ( endPoint[0].r << 2 ) & 0x00001000 ) | ( ( endPoint[0].g << 12 ) & 0x00400000 ); block.y |= ( ( endPoint[1].r << 3 ) & 0x00000FF8 ) | ( ( endPoint[1].g << 13 ) & 0x003FE000 ) | ( ( endPoint[1].b << 23 ) & 0xFF800000 ); block.z |= ( endPoint[0].b >> 10 ) & 0x00000001;*/ block.x |= ((candidateModeMemory[11] >> 0) & 1) << 0; block.x |= ((candidateModeMemory[11] >> 1) & 1) << 1; block.x |= ((candidateModeMemory[11] >> 2) & 1) << 2; block.x |= ((candidateModeMemory[11] >> 3) & 1) << 3; block.x |= ((candidateModeMemory[11] >> 4) & 1) << 4; block.x |= ((endPoint[0].r >> 0) & 1) << 5; block.x |= ((endPoint[0].r >> 1) & 1) << 6; block.x |= ((endPoint[0].r >> 2) & 1) << 7; block.x |= ((endPoint[0].r >> 3) & 1) << 8; block.x |= ((endPoint[0].r >> 4) & 1) << 9; block.x |= ((endPoint[0].r >> 5) & 1) << 10; block.x |= ((endPoint[0].r >> 6) & 1) << 11; block.x |= ((endPoint[0].r >> 7) & 1) << 12; block.x |= ((endPoint[0].r >> 8) & 1) << 13; block.x |= ((endPoint[0].r >> 9) & 1) << 14; block.x |= ((endPoint[0].g >> 0) & 1) << 15; block.x |= ((endPoint[0].g >> 1) & 1) << 16; block.x |= ((endPoint[0].g >> 2) & 1) << 17; block.x |= ((endPoint[0].g >> 3) & 1) << 18; block.x |= ((endPoint[0].g >> 4) & 1) << 19; block.x |= ((endPoint[0].g >> 5) & 1) << 20; block.x |= ((endPoint[0].g >> 6) & 1) << 21; block.x |= ((endPoint[0].g >> 7) & 1) << 22; block.x |= ((endPoint[0].g >> 8) & 1) << 23; block.x |= ((endPoint[0].g >> 9) & 1) << 24; block.x |= ((endPoint[0].b >> 0) & 1) << 25; block.x |= ((endPoint[0].b >> 1) & 1) << 26; block.x |= ((endPoint[0].b >> 2) & 1) << 27; block.x |= ((endPoint[0].b >> 3) & 1) << 28; block.x |= ((endPoint[0].b >> 4) & 1) << 29; block.x |= ((endPoint[0].b >> 5) & 1) << 30; block.x |= ((endPoint[0].b >> 6) & 1) << 31; block.y |= ((endPoint[0].b >> 7) & 1) << 0; block.y |= ((endPoint[0].b >> 8) & 1) << 1; block.y |= ((endPoint[0].b >> 9) & 1) << 2; block.y |= ((endPoint[1].r >> 0) & 1) << 3; block.y |= ((endPoint[1].r >> 1) & 1) << 4; block.y |= ((endPoint[1].r >> 2) & 1) << 5; block.y |= ((endPoint[1].r >> 3) & 1) << 6; block.y |= ((endPoint[1].r >> 4) & 1) << 7; block.y |= ((endPoint[1].r >> 5) & 1) << 8; block.y |= ((endPoint[1].r >> 6) & 1) << 9; block.y |= ((endPoint[1].r >> 7) & 1) << 10; block.y |= ((endPoint[1].r >> 8) & 1) << 11; block.y |= ((endPoint[0].r >> 10) & 1) << 12; block.y |= ((endPoint[1].g >> 0) & 1) << 13; block.y |= ((endPoint[1].g >> 1) & 1) << 14; block.y |= ((endPoint[1].g >> 2) & 1) << 15; block.y |= ((endPoint[1].g >> 3) & 1) << 16; block.y |= ((endPoint[1].g >> 4) & 1) << 17; block.y |= ((endPoint[1].g >> 5) & 1) << 18; block.y |= ((endPoint[1].g >> 6) & 1) << 19; block.y |= ((endPoint[1].g >> 7) & 1) << 20; block.y |= ((endPoint[1].g >> 8) & 1) << 21; block.y |= ((endPoint[0].g >> 10) & 1) << 22; block.y |= ((endPoint[1].b >> 0) & 1) << 23; block.y |= ((endPoint[1].b >> 1) & 1) << 24; block.y |= ((endPoint[1].b >> 2) & 1) << 25; block.y |= ((endPoint[1].b >> 3) & 1) << 26; block.y |= ((endPoint[1].b >> 4) & 1) << 27; block.y |= ((endPoint[1].b >> 5) & 1) << 28; block.y |= ((endPoint[1].b >> 6) & 1) << 29; block.y |= ((endPoint[1].b >> 7) & 1) << 30; block.y |= ((endPoint[1].b >> 8) & 1) << 31; block.z |= ((endPoint[0].b >> 10) & 1) << 0; } else if (mode_type == candidateModeFlag[12])// violate the spec in [0].low { /*block.x |= candidateModeMemory[12]; block.y |= ( ( endPoint[0].r << 2 ) & 0x00001000 ) | ( ( endPoint[0].g << 12 ) & 0x00400000 ); block.y |= ( ( endPoint[0].r << 0 ) & 0x00000800 ) | ( ( endPoint[0].g << 10 ) & 0x00200000 ); block.y |= ( endPoint[0].b << 20 ) & 0x80000000; block.y |= ( ( endPoint[1].r << 3 ) & 0x000007F8 ) | ( ( endPoint[1].g << 13 ) & 0x001FE000 ) | ( ( endPoint[1].b << 23 ) & 0x7F800000 ); block.z |= ( endPoint[0].b >> 10 ) & 0x00000001;*/ block.x |= ((candidateModeMemory[12] >> 0) & 1) << 0; block.x |= ((candidateModeMemory[12] >> 1) & 1) << 1; block.x |= ((candidateModeMemory[12] >> 2) & 1) << 2; block.x |= ((candidateModeMemory[12] >> 3) & 1) << 3; block.x |= ((candidateModeMemory[12] >> 4) & 1) << 4; block.x |= ((endPoint[0].r >> 0) & 1) << 5; block.x |= ((endPoint[0].r >> 1) & 1) << 6; block.x |= ((endPoint[0].r >> 2) & 1) << 7; block.x |= ((endPoint[0].r >> 3) & 1) << 8; block.x |= ((endPoint[0].r >> 4) & 1) << 9; block.x |= ((endPoint[0].r >> 5) & 1) << 10; block.x |= ((endPoint[0].r >> 6) & 1) << 11; block.x |= ((endPoint[0].r >> 7) & 1) << 12; block.x |= ((endPoint[0].r >> 8) & 1) << 13; block.x |= ((endPoint[0].r >> 9) & 1) << 14; block.x |= ((endPoint[0].g >> 0) & 1) << 15; block.x |= ((endPoint[0].g >> 1) & 1) << 16; block.x |= ((endPoint[0].g >> 2) & 1) << 17; block.x |= ((endPoint[0].g >> 3) & 1) << 18; block.x |= ((endPoint[0].g >> 4) & 1) << 19; block.x |= ((endPoint[0].g >> 5) & 1) << 20; block.x |= ((endPoint[0].g >> 6) & 1) << 21; block.x |= ((endPoint[0].g >> 7) & 1) << 22; block.x |= ((endPoint[0].g >> 8) & 1) << 23; block.x |= ((endPoint[0].g >> 9) & 1) << 24; block.x |= ((endPoint[0].b >> 0) & 1) << 25; block.x |= ((endPoint[0].b >> 1) & 1) << 26; block.x |= ((endPoint[0].b >> 2) & 1) << 27; block.x |= ((endPoint[0].b >> 3) & 1) << 28; block.x |= ((endPoint[0].b >> 4) & 1) << 29; block.x |= ((endPoint[0].b >> 5) & 1) << 30; block.x |= ((endPoint[0].b >> 6) & 1) << 31; block.y |= ((endPoint[0].b >> 7) & 1) << 0; block.y |= ((endPoint[0].b >> 8) & 1) << 1; block.y |= ((endPoint[0].b >> 9) & 1) << 2; block.y |= ((endPoint[1].r >> 0) & 1) << 3; block.y |= ((endPoint[1].r >> 1) & 1) << 4; block.y |= ((endPoint[1].r >> 2) & 1) << 5; block.y |= ((endPoint[1].r >> 3) & 1) << 6; block.y |= ((endPoint[1].r >> 4) & 1) << 7; block.y |= ((endPoint[1].r >> 5) & 1) << 8; block.y |= ((endPoint[1].r >> 6) & 1) << 9; block.y |= ((endPoint[1].r >> 7) & 1) << 10; block.y |= ((endPoint[0].r >> 11) & 1) << 11; block.y |= ((endPoint[0].r >> 10) & 1) << 12; block.y |= ((endPoint[1].g >> 0) & 1) << 13; block.y |= ((endPoint[1].g >> 1) & 1) << 14; block.y |= ((endPoint[1].g >> 2) & 1) << 15; block.y |= ((endPoint[1].g >> 3) & 1) << 16; block.y |= ((endPoint[1].g >> 4) & 1) << 17; block.y |= ((endPoint[1].g >> 5) & 1) << 18; block.y |= ((endPoint[1].g >> 6) & 1) << 19; block.y |= ((endPoint[1].g >> 7) & 1) << 20; block.y |= ((endPoint[0].g >> 11) & 1) << 21; block.y |= ((endPoint[0].g >> 10) & 1) << 22; block.y |= ((endPoint[1].b >> 0) & 1) << 23; block.y |= ((endPoint[1].b >> 1) & 1) << 24; block.y |= ((endPoint[1].b >> 2) & 1) << 25; block.y |= ((endPoint[1].b >> 3) & 1) << 26; block.y |= ((endPoint[1].b >> 4) & 1) << 27; block.y |= ((endPoint[1].b >> 5) & 1) << 28; block.y |= ((endPoint[1].b >> 6) & 1) << 29; block.y |= ((endPoint[1].b >> 7) & 1) << 30; block.y |= ((endPoint[0].b >> 11) & 1) << 31; block.z |= ((endPoint[0].b >> 10) & 1) << 0; } else if (mode_type == candidateModeFlag[13]) { /*block.x |= candidateModeMemory[13]; block.y |= ( ( endPoint[0].r >> 8 ) & 0x00000080 ); block.y |= ( ( endPoint[0].r >> 6 ) & 0x00000100 ); block.y |= ( ( endPoint[0].r >> 4 ) & 0x00000200 ); block.y |= ( ( endPoint[0].r >> 2 ) & 0x00000400 ); block.y |= ( ( endPoint[0].r >> 0 ) & 0x00000800 ); block.y |= ( ( endPoint[0].r << 2 ) & 0x00001000 ); block.y |= ( ( endPoint[0].g << 2 ) & 0x00020000 ); block.y |= ( ( endPoint[0].g << 4 ) & 0x00040000 ); block.y |= ( ( endPoint[0].g << 6 ) & 0x00080000 ); block.y |= ( ( endPoint[0].g << 8 ) & 0x00100000 ); block.y |= ( ( endPoint[0].g << 10 ) & 0x00200000 ); block.y |= ( ( endPoint[0].g << 12 ) & 0x00400000 ); block.y |= ( ( endPoint[0].b << 12 ) & 0x08000000 ); block.y |= ( ( endPoint[0].b << 14 ) & 0x10000000 ); block.y |= ( ( endPoint[0].b << 16 ) & 0x20000000 ); block.y |= ( ( endPoint[0].b << 18 ) & 0x40000000 ); block.y |= ( ( endPoint[0].b << 20 ) & 0x80000000 ); block.y |= ( ( endPoint[1].r << 3 ) & 0x00000078 ) | ( ( endPoint[1].g << 13 ) & 0x0001E000 ) | ( ( endPoint[1].b << 23 ) & 0x07800000 ); block.z |= ( endPoint[0].b >> 10 ) & 0x00000001;*/ block.x |= ((candidateModeMemory[13] >> 0) & 1) << 0; block.x |= ((candidateModeMemory[13] >> 1) & 1) << 1; block.x |= ((candidateModeMemory[13] >> 2) & 1) << 2; block.x |= ((candidateModeMemory[13] >> 3) & 1) << 3; block.x |= ((candidateModeMemory[13] >> 4) & 1) << 4; block.x |= ((endPoint[0].r >> 0) & 1) << 5; block.x |= ((endPoint[0].r >> 1) & 1) << 6; block.x |= ((endPoint[0].r >> 2) & 1) << 7; block.x |= ((endPoint[0].r >> 3) & 1) << 8; block.x |= ((endPoint[0].r >> 4) & 1) << 9; block.x |= ((endPoint[0].r >> 5) & 1) << 10; block.x |= ((endPoint[0].r >> 6) & 1) << 11; block.x |= ((endPoint[0].r >> 7) & 1) << 12; block.x |= ((endPoint[0].r >> 8) & 1) << 13; block.x |= ((endPoint[0].r >> 9) & 1) << 14; block.x |= ((endPoint[0].g >> 0) & 1) << 15; block.x |= ((endPoint[0].g >> 1) & 1) << 16; block.x |= ((endPoint[0].g >> 2) & 1) << 17; block.x |= ((endPoint[0].g >> 3) & 1) << 18; block.x |= ((endPoint[0].g >> 4) & 1) << 19; block.x |= ((endPoint[0].g >> 5) & 1) << 20; block.x |= ((endPoint[0].g >> 6) & 1) << 21; block.x |= ((endPoint[0].g >> 7) & 1) << 22; block.x |= ((endPoint[0].g >> 8) & 1) << 23; block.x |= ((endPoint[0].g >> 9) & 1) << 24; block.x |= ((endPoint[0].b >> 0) & 1) << 25; block.x |= ((endPoint[0].b >> 1) & 1) << 26; block.x |= ((endPoint[0].b >> 2) & 1) << 27; block.x |= ((endPoint[0].b >> 3) & 1) << 28; block.x |= ((endPoint[0].b >> 4) & 1) << 29; block.x |= ((endPoint[0].b >> 5) & 1) << 30; block.x |= ((endPoint[0].b >> 6) & 1) << 31; block.y |= ((endPoint[0].b >> 7) & 1) << 0; block.y |= ((endPoint[0].b >> 8) & 1) << 1; block.y |= ((endPoint[0].b >> 9) & 1) << 2; block.y |= ((endPoint[1].r >> 0) & 1) << 3; block.y |= ((endPoint[1].r >> 1) & 1) << 4; block.y |= ((endPoint[1].r >> 2) & 1) << 5; block.y |= ((endPoint[1].r >> 3) & 1) << 6; block.y |= ((endPoint[0].r >> 15) & 1) << 7; block.y |= ((endPoint[0].r >> 14) & 1) << 8; block.y |= ((endPoint[0].r >> 13) & 1) << 9; block.y |= ((endPoint[0].r >> 12) & 1) << 10; block.y |= ((endPoint[0].r >> 11) & 1) << 11; block.y |= ((endPoint[0].r >> 10) & 1) << 12; block.y |= ((endPoint[1].g >> 0) & 1) << 13; block.y |= ((endPoint[1].g >> 1) & 1) << 14; block.y |= ((endPoint[1].g >> 2) & 1) << 15; block.y |= ((endPoint[1].g >> 3) & 1) << 16; block.y |= ((endPoint[0].g >> 15) & 1) << 17; block.y |= ((endPoint[0].g >> 14) & 1) << 18; block.y |= ((endPoint[0].g >> 13) & 1) << 19; block.y |= ((endPoint[0].g >> 12) & 1) << 20; block.y |= ((endPoint[0].g >> 11) & 1) << 21; block.y |= ((endPoint[0].g >> 10) & 1) << 22; block.y |= ((endPoint[1].b >> 0) & 1) << 23; block.y |= ((endPoint[1].b >> 1) & 1) << 24; block.y |= ((endPoint[1].b >> 2) & 1) << 25; block.y |= ((endPoint[1].b >> 3) & 1) << 26; block.y |= ((endPoint[0].b >> 15) & 1) << 27; block.y |= ((endPoint[0].b >> 14) & 1) << 28; block.y |= ((endPoint[0].b >> 13) & 1) << 29; block.y |= ((endPoint[0].b >> 12) & 1) << 30; block.y |= ((endPoint[0].b >> 11) & 1) << 31; block.z |= ((endPoint[0].b >> 10) & 1) << 0; } } ================================================ FILE: 3rdParty/DirectXTex/DirectXTex/Shaders/BC7Encode.hlsl ================================================ //-------------------------------------------------------------------------------------- // File: BC7Encode.hlsl // // The Compute Shader for BC7 Encoder // // Copyright (c) Microsoft Corporation. All rights reserved. //-------------------------------------------------------------------------------------- //#define REF_DEVICE #define CHAR_LENGTH 8 #define NCHANNELS 4 #define BC7_UNORM 98 #define MAX_UINT 0xFFFFFFFF #define MIN_UINT 0 static const uint candidateSectionBit[64] = //Associated to partition 0-63 { 0xCCCC, 0x8888, 0xEEEE, 0xECC8, 0xC880, 0xFEEC, 0xFEC8, 0xEC80, 0xC800, 0xFFEC, 0xFE80, 0xE800, 0xFFE8, 0xFF00, 0xFFF0, 0xF000, 0xF710, 0x008E, 0x7100, 0x08CE, 0x008C, 0x7310, 0x3100, 0x8CCE, 0x088C, 0x3110, 0x6666, 0x366C, 0x17E8, 0x0FF0, 0x718E, 0x399C, 0xaaaa, 0xf0f0, 0x5a5a, 0x33cc, 0x3c3c, 0x55aa, 0x9696, 0xa55a, 0x73ce, 0x13c8, 0x324c, 0x3bdc, 0x6996, 0xc33c, 0x9966, 0x660, 0x272, 0x4e4, 0x4e40, 0x2720, 0xc936, 0x936c, 0x39c6, 0x639c, 0x9336, 0x9cc6, 0x817e, 0xe718, 0xccf0, 0xfcc, 0x7744, 0xee22, }; static const uint candidateSectionBit2[64] = //Associated to partition 64-127 { 0xaa685050, 0x6a5a5040, 0x5a5a4200, 0x5450a0a8, 0xa5a50000, 0xa0a05050, 0x5555a0a0, 0x5a5a5050, 0xaa550000, 0xaa555500, 0xaaaa5500, 0x90909090, 0x94949494, 0xa4a4a4a4, 0xa9a59450, 0x2a0a4250, 0xa5945040, 0x0a425054, 0xa5a5a500, 0x55a0a0a0, 0xa8a85454, 0x6a6a4040, 0xa4a45000, 0x1a1a0500, 0x0050a4a4, 0xaaa59090, 0x14696914, 0x69691400, 0xa08585a0, 0xaa821414, 0x50a4a450, 0x6a5a0200, 0xa9a58000, 0x5090a0a8, 0xa8a09050, 0x24242424, 0x00aa5500, 0x24924924, 0x24499224, 0x50a50a50, 0x500aa550, 0xaaaa4444, 0x66660000, 0xa5a0a5a0, 0x50a050a0, 0x69286928, 0x44aaaa44, 0x66666600, 0xaa444444, 0x54a854a8, 0x95809580, 0x96969600, 0xa85454a8, 0x80959580, 0xaa141414, 0x96960000, 0xaaaa1414, 0xa05050a0, 0xa0a5a5a0, 0x96000000, 0x40804080, 0xa9a8a9a8, 0xaaaaaa44, 0x2a4a5254, }; static const uint2 candidateFixUpIndex1D[128] = { {15, 0},{15, 0},{15, 0},{15, 0}, {15, 0},{15, 0},{15, 0},{15, 0}, {15, 0},{15, 0},{15, 0},{15, 0}, {15, 0},{15, 0},{15, 0},{15, 0}, {15, 0},{ 2, 0},{ 8, 0},{ 2, 0}, { 2, 0},{ 8, 0},{ 8, 0},{15, 0}, { 2, 0},{ 8, 0},{ 2, 0},{ 2, 0}, { 8, 0},{ 8, 0},{ 2, 0},{ 2, 0}, {15, 0},{15, 0},{ 6, 0},{ 8, 0}, { 2, 0},{ 8, 0},{15, 0},{15, 0}, { 2, 0},{ 8, 0},{ 2, 0},{ 2, 0}, { 2, 0},{15, 0},{15, 0},{ 6, 0}, { 6, 0},{ 2, 0},{ 6, 0},{ 8, 0}, {15, 0},{15, 0},{ 2, 0},{ 2, 0}, {15, 0},{15, 0},{15, 0},{15, 0}, {15, 0},{ 2, 0},{ 2, 0},{15, 0}, //candidateFixUpIndex1D[i][1], i < 64 should not be used { 3,15},{ 3, 8},{15, 8},{15, 3}, { 8,15},{ 3,15},{15, 3},{15, 8}, { 8,15},{ 8,15},{ 6,15},{ 6,15}, { 6,15},{ 5,15},{ 3,15},{ 3, 8}, { 3,15},{ 3, 8},{ 8,15},{15, 3}, { 3,15},{ 3, 8},{ 6,15},{10, 8}, { 5, 3},{ 8,15},{ 8, 6},{ 6,10}, { 8,15},{ 5,15},{15,10},{15, 8}, { 8,15},{15, 3},{ 3,15},{ 5,10}, { 6,10},{10, 8},{ 8, 9},{15,10}, {15, 6},{ 3,15},{15, 8},{ 5,15}, {15, 3},{15, 6},{15, 6},{15, 8}, //The Spec doesn't mark the first fixed up index in this row, so I apply 15 for them, and seems correct { 3,15},{15, 3},{ 5,15},{ 5,15}, { 5,15},{ 8,15},{ 5,15},{10,15}, { 5,15},{10,15},{ 8,15},{13,15}, {15, 3},{12,15},{ 3,15},{ 3, 8}, }; static const uint2 candidateFixUpIndex1DOrdered[128] = //Same with candidateFixUpIndex1D but order the result when i >= 64 { {15, 0},{15, 0},{15, 0},{15, 0}, {15, 0},{15, 0},{15, 0},{15, 0}, {15, 0},{15, 0},{15, 0},{15, 0}, {15, 0},{15, 0},{15, 0},{15, 0}, {15, 0},{ 2, 0},{ 8, 0},{ 2, 0}, { 2, 0},{ 8, 0},{ 8, 0},{15, 0}, { 2, 0},{ 8, 0},{ 2, 0},{ 2, 0}, { 8, 0},{ 8, 0},{ 2, 0},{ 2, 0}, {15, 0},{15, 0},{ 6, 0},{ 8, 0}, { 2, 0},{ 8, 0},{15, 0},{15, 0}, { 2, 0},{ 8, 0},{ 2, 0},{ 2, 0}, { 2, 0},{15, 0},{15, 0},{ 6, 0}, { 6, 0},{ 2, 0},{ 6, 0},{ 8, 0}, {15, 0},{15, 0},{ 2, 0},{ 2, 0}, {15, 0},{15, 0},{15, 0},{15, 0}, {15, 0},{ 2, 0},{ 2, 0},{15, 0}, //candidateFixUpIndex1DOrdered[i][1], i < 64 should not be used { 3,15},{ 3, 8},{ 8,15},{ 3,15}, { 8,15},{ 3,15},{ 3,15},{ 8,15}, { 8,15},{ 8,15},{ 6,15},{ 6,15}, { 6,15},{ 5,15},{ 3,15},{ 3, 8}, { 3,15},{ 3, 8},{ 8,15},{ 3,15}, { 3,15},{ 3, 8},{ 6,15},{ 8,10}, { 3, 5},{ 8,15},{ 6, 8},{ 6,10}, { 8,15},{ 5,15},{10,15},{ 8,15}, { 8,15},{ 3,15},{ 3,15},{ 5,10}, { 6,10},{ 8,10},{ 8, 9},{10,15}, { 6,15},{ 3,15},{ 8,15},{ 5,15}, { 3,15},{ 6,15},{ 6,15},{ 8,15}, //The Spec doesn't mark the first fixed up index in this row, so I apply 15 for them, and seems correct { 3,15},{ 3,15},{ 5,15},{ 5,15}, { 5,15},{ 8,15},{ 5,15},{10,15}, { 5,15},{10,15},{ 8,15},{13,15}, { 3,15},{12,15},{ 3,15},{ 3, 8}, }; //static const uint4x4 candidateRotation[4] = //{ // {1,0,0,0},{0,1,0,0},{0,0,1,0},{0,0,0,1}, // {0,0,0,1},{0,1,0,0},{0,0,1,0},{1,0,0,0}, // {1,0,0,0},{0,0,0,1},{0,0,1,0},{0,1,0,0}, // {1,0,0,0},{0,1,0,0},{0,0,0,1},{0,0,1,0} //}; //static const uint2 candidateIndexPrec[8] = {{3,0},{3,0},{2,0},{2,0}, // {2,3}, //color index and alpha index can exchange // {2,2},{4,4},{2,2}}; static const uint aWeight[3][16] = { {0, 4, 9, 13, 17, 21, 26, 30, 34, 38, 43, 47, 51, 55, 60, 64}, {0, 9, 18, 27, 37, 46, 55, 64, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 21, 43, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }; //4 bit index: 0, 4, 9, 13, 17, 21, 26, 30, 34, 38, 43, 47, 51, 55, 60, 64 static const uint aStep[3][64] = { { 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9,10,10,10,10,10,11,11, 11,11,12,12,12,12,13,13, 13,13,14,14,14,14,15,15 }, //3 bit index: 0, 9, 18, 27, 37, 46, 55, 64 { 0,0,0,0,0,1,1,1, 1,1,1,1,1,1,2,2, 2,2,2,2,2,2,2,3, 3,3,3,3,3,3,3,3, 3,4,4,4,4,4,4,4, 4,4,5,5,5,5,5,5, 5,5,5,6,6,6,6,6, 6,6,6,6,7,7,7,7 }, //2 bit index: 0, 21, 43, 64 { 0,0,0,0,0,0,0,0, 0,0,0,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,3,3, 3,3,3,3,3,3,3,3 } }; cbuffer cbCS : register( b0 ) { uint g_tex_width; uint g_num_block_x; uint g_format; uint g_mode_id; uint g_start_block_id; uint g_num_total_blocks; float g_alpha_weight; }; //Forward declaration uint2x4 compress_endpoints0( inout uint2x4 endPoint, uint2 P ); //Mode = 0 uint2x4 compress_endpoints1( inout uint2x4 endPoint, uint2 P ); //Mode = 1 uint2x4 compress_endpoints2( inout uint2x4 endPoint ); //Mode = 2 uint2x4 compress_endpoints3( inout uint2x4 endPoint, uint2 P ); //Mode = 3 uint2x4 compress_endpoints7( inout uint2x4 endPoint, uint2 P ); //Mode = 7 uint2x4 compress_endpoints6( inout uint2x4 endPoint, uint2 P ); //Mode = 6 uint2x4 compress_endpoints4( inout uint2x4 endPoint ); //Mode = 4 uint2x4 compress_endpoints5( inout uint2x4 endPoint ); //Mode = 5 void block_package0( out uint4 block, uint partition, uint threadBase ); //Mode0 void block_package1( out uint4 block, uint partition, uint threadBase ); //Mode1 void block_package2( out uint4 block, uint partition, uint threadBase ); //Mode2 void block_package3( out uint4 block, uint partition, uint threadBase ); //Mode3 void block_package4( out uint4 block, uint rotation, uint index_selector, uint threadBase ); //Mode4 void block_package5( out uint4 block, uint rotation, uint threadBase ); //Mode5 void block_package6( out uint4 block, uint threadBase ); //Mode6 void block_package7( out uint4 block, uint partition, uint threadBase ); //Mode7 void swap(inout uint4 lhs, inout uint4 rhs) { uint4 tmp = lhs; lhs = rhs; rhs = tmp; } void swap(inout uint3 lhs, inout uint3 rhs) { uint3 tmp = lhs; lhs = rhs; rhs = tmp; } void swap(inout uint lhs, inout uint rhs) { uint tmp = lhs; lhs = rhs; rhs = tmp; } uint ComputeError(in uint4 a, in uint4 b) { return dot(a.rgb, b.rgb) + g_alpha_weight * a.a*b.a; } void Ensure_A_Is_Larger( inout uint4 a, inout uint4 b ) { if ( a.x < b.x ) swap( a.x, b.x ); if ( a.y < b.y ) swap( a.y, b.y ); if ( a.z < b.z ) swap( a.z, b.z ); if ( a.w < b.w ) swap( a.w, b.w ); } Texture2D g_Input : register( t0 ); StructuredBuffer g_InBuff : register( t1 ); RWStructuredBuffer g_OutBuff : register( u0 ); #define THREAD_GROUP_SIZE 64 #define BLOCK_SIZE_Y 4 #define BLOCK_SIZE_X 4 #define BLOCK_SIZE (BLOCK_SIZE_Y * BLOCK_SIZE_X) struct BufferShared { uint4 pixel; uint error; uint mode; uint partition; uint index_selector; uint rotation; uint4 endPoint_low; uint4 endPoint_high; uint4 endPoint_low_quantized; uint4 endPoint_high_quantized; }; groupshared BufferShared shared_temp[THREAD_GROUP_SIZE]; [numthreads( THREAD_GROUP_SIZE, 1, 1 )] void TryMode456CS( uint GI : SV_GroupIndex, uint3 groupID : SV_GroupID ) // mode 4 5 6 all have 1 subset per block, and fix-up index is always index 0 { // we process 4 BC blocks per thread group const uint MAX_USED_THREAD = 16; // pixels in a BC (block compressed) block uint BLOCK_IN_GROUP = THREAD_GROUP_SIZE / MAX_USED_THREAD; // the number of BC blocks a thread group processes = 64 / 16 = 4 uint blockInGroup = GI / MAX_USED_THREAD; // what BC block this thread is on within this thread group uint blockID = g_start_block_id + groupID.x * BLOCK_IN_GROUP + blockInGroup; // what global BC block this thread is on uint threadBase = blockInGroup * MAX_USED_THREAD; // the first id of the pixel in this BC block in this thread group uint threadInBlock = GI - threadBase; // id of the pixel in this BC block #ifndef REF_DEVICE if (blockID >= g_num_total_blocks) { return; } #endif uint block_y = blockID / g_num_block_x; uint block_x = blockID - block_y * g_num_block_x; uint base_x = block_x * BLOCK_SIZE_X; uint base_y = block_y * BLOCK_SIZE_Y; if (threadInBlock < 16) { shared_temp[GI].pixel = clamp(uint4(g_Input.Load( uint3( base_x + threadInBlock % 4, base_y + threadInBlock / 4, 0 ) ) * 255), 0, 255); shared_temp[GI].endPoint_low = shared_temp[GI].pixel; shared_temp[GI].endPoint_high = shared_temp[GI].pixel; } #ifdef REF_DEVICE GroupMemoryBarrierWithGroupSync(); #endif if (threadInBlock < 8) { shared_temp[GI].endPoint_low = min(shared_temp[GI].endPoint_low, shared_temp[GI + 8].endPoint_low); shared_temp[GI].endPoint_high = max(shared_temp[GI].endPoint_high, shared_temp[GI + 8].endPoint_high); } #ifdef REF_DEVICE GroupMemoryBarrierWithGroupSync(); #endif if (threadInBlock < 4) { shared_temp[GI].endPoint_low = min(shared_temp[GI].endPoint_low, shared_temp[GI + 4].endPoint_low); shared_temp[GI].endPoint_high = max(shared_temp[GI].endPoint_high, shared_temp[GI + 4].endPoint_high); } #ifdef REF_DEVICE GroupMemoryBarrierWithGroupSync(); #endif if (threadInBlock < 2) { shared_temp[GI].endPoint_low = min(shared_temp[GI].endPoint_low, shared_temp[GI + 2].endPoint_low); shared_temp[GI].endPoint_high = max(shared_temp[GI].endPoint_high, shared_temp[GI + 2].endPoint_high); } #ifdef REF_DEVICE GroupMemoryBarrierWithGroupSync(); #endif if (threadInBlock < 1) { shared_temp[GI].endPoint_low = min(shared_temp[GI].endPoint_low, shared_temp[GI + 1].endPoint_low); shared_temp[GI].endPoint_high = max(shared_temp[GI].endPoint_high, shared_temp[GI + 1].endPoint_high); } #ifdef REF_DEVICE GroupMemoryBarrierWithGroupSync(); #endif uint2x4 endPoint; endPoint[0] = shared_temp[threadBase].endPoint_low; endPoint[1] = shared_temp[threadBase].endPoint_high; uint error = 0xFFFFFFFF; uint mode = 0; uint index_selector = 0; uint rotation = 0; uint2 indexPrec; if (threadInBlock < 8) // all threads of threadInBlock < 8 will be working on trying out mode 4, since only mode 4 has index selector bit { if (0 == (threadInBlock & 1)) // thread 0, 2, 4, 6 { //2 represents 2bit index precision; 1 represents 3bit index precision index_selector = 0; indexPrec = uint2( 2, 1 ); } else // thread 1, 3, 5, 7 { //2 represents 2bit index precision; 1 represents 3bit index precision index_selector = 1; indexPrec = uint2( 1, 2 ); } } else { //2 represents 2bit index precision indexPrec = uint2( 2, 2 ); } uint4 pixel_r; uint color_index; uint alpha_index; int4 span; int2 span_norm_sqr; int2 dotProduct; if (threadInBlock < 12) // Try mode 4 5 in threads 0..11 { // mode 4 5 have component rotation if ((threadInBlock < 2) || (8 == threadInBlock)) // rotation = 0 in thread 0, 1 { rotation = 0; } else if ((threadInBlock < 4) || (9 == threadInBlock)) // rotation = 1 in thread 2, 3 { endPoint[0].ra = endPoint[0].ar; endPoint[1].ra = endPoint[1].ar; rotation = 1; } else if ((threadInBlock < 6) || (10 == threadInBlock)) // rotation = 2 in thread 4, 5 { endPoint[0].ga = endPoint[0].ag; endPoint[1].ga = endPoint[1].ag; rotation = 2; } else if ((threadInBlock < 8) || (11 == threadInBlock)) // rotation = 3 in thread 6, 7 { endPoint[0].ba = endPoint[0].ab; endPoint[1].ba = endPoint[1].ab; rotation = 3; } if (threadInBlock < 8) // try mode 4 in threads 0..7 { // mode 4 thread distribution // Thread 0 1 2 3 4 5 6 7 // Rotation 0 0 1 1 2 2 3 3 // Index selector 0 1 0 1 0 1 0 1 mode = 4; compress_endpoints4( endPoint ); } else // try mode 5 in threads 8..11 { // mode 5 thread distribution // Thread 8 9 10 11 // Rotation 0 1 2 3 mode = 5; compress_endpoints5( endPoint ); } uint4 pixel = shared_temp[threadBase + 0].pixel; if (1 == rotation) { pixel.ra = pixel.ar; } else if (2 == rotation) { pixel.ga = pixel.ag; } else if (3 == rotation) { pixel.ba = pixel.ab; } span = endPoint[1] - endPoint[0]; span_norm_sqr = uint2( dot( span.rgb, span.rgb ), span.a * span.a ); // in mode 4 5 6, end point 0 must be closer to pixel 0 than end point 1, because of the fix-up index is always index 0 // TODO: this shouldn't be necessary here in error calculation /* dotProduct = int2( dot( span.rgb, pixel.rgb - endPoint[0].rgb ), span.a * ( pixel.a - endPoint[0].a ) ); if ( span_norm_sqr.x > 0 && dotProduct.x > 0 && uint( dotProduct.x * 63.49999 ) > uint( 32 * span_norm_sqr.x ) ) { span.rgb = -span.rgb; swap(endPoint[0].rgb, endPoint[1].rgb); } if ( span_norm_sqr.y > 0 && dotProduct.y > 0 && uint( dotProduct.y * 63.49999 ) > uint( 32 * span_norm_sqr.y ) ) { span.a = -span.a; swap(endPoint[0].a, endPoint[1].a); } */ // should be the same as above dotProduct = int2( dot( pixel.rgb - endPoint[0].rgb, pixel.rgb - endPoint[0].rgb ), dot( pixel.rgb - endPoint[1].rgb, pixel.rgb - endPoint[1].rgb ) ); if ( dotProduct.x > dotProduct.y ) { span.rgb = -span.rgb; swap(endPoint[0].rgb, endPoint[1].rgb); } dotProduct = int2( dot( pixel.a - endPoint[0].a, pixel.a - endPoint[0].a ), dot( pixel.a - endPoint[1].a, pixel.a - endPoint[1].a ) ); if ( dotProduct.x > dotProduct.y ) { span.a = -span.a; swap(endPoint[0].a, endPoint[1].a); } error = 0; for ( uint i = 0; i < 16; i ++ ) { pixel = shared_temp[threadBase + i].pixel; if (1 == rotation) { pixel.ra = pixel.ar; } else if (2 == rotation) { pixel.ga = pixel.ag; } else if (3 == rotation) { pixel.ba = pixel.ab; } dotProduct.x = dot( span.rgb, pixel.rgb - endPoint[0].rgb ); color_index = ( span_norm_sqr.x <= 0 /*endPoint[0] == endPoint[1]*/ || dotProduct.x <= 0 /*pixel == endPoint[0]*/ ) ? 0 : ( ( dotProduct.x < span_norm_sqr.x ) ? aStep[indexPrec.x][ uint( dotProduct.x * 63.49999 / span_norm_sqr.x ) ] : aStep[indexPrec.x][63] ); dotProduct.y = dot( span.a, pixel.a - endPoint[0].a ); alpha_index = ( span_norm_sqr.y <= 0 || dotProduct.y <= 0 ) ? 0 : ( ( dotProduct.y < span_norm_sqr.y ) ? aStep[indexPrec.y][ uint( dotProduct.y * 63.49999 / span_norm_sqr.y ) ] : aStep[indexPrec.y][63] ); // the same color_index and alpha_index should be used for reconstruction, so this should be left commented out /*if (index_selector) { swap(color_index, alpha_index); }*/ pixel_r.rgb = ( ( 64 - aWeight[indexPrec.x][color_index] ) * endPoint[0].rgb + aWeight[indexPrec.x][color_index] * endPoint[1].rgb + 32 ) >> 6; pixel_r.a = ( ( 64 - aWeight[indexPrec.y][alpha_index] ) * endPoint[0].a + aWeight[indexPrec.y][alpha_index] * endPoint[1].a + 32 ) >> 6; Ensure_A_Is_Larger( pixel_r, pixel ); pixel_r -= pixel; if (1 == rotation) { pixel_r.ra = pixel_r.ar; } else if (2 == rotation) { pixel_r.ga = pixel_r.ag; } else if (3 == rotation) { pixel_r.ba = pixel_r.ab; } error += ComputeError(pixel_r, pixel_r); } } else if (threadInBlock < 16) // Try mode 6 in threads 12..15, since in mode 4 5 6, only mode 6 has p bit { uint p = threadInBlock - 12; compress_endpoints6( endPoint, uint2(p >> 0, p >> 1) & 1 ); uint4 pixel = shared_temp[threadBase + 0].pixel; span = endPoint[1] - endPoint[0]; span_norm_sqr = dot( span, span ); dotProduct = dot( span, pixel - endPoint[0] ); if ( span_norm_sqr.x > 0 && dotProduct.x >= 0 && uint( dotProduct.x * 63.49999 ) > uint( 32 * span_norm_sqr.x ) ) { span = -span; swap(endPoint[0], endPoint[1]); } error = 0; for ( uint i = 0; i < 16; i ++ ) { pixel = shared_temp[threadBase + i].pixel; dotProduct.x = dot( span, pixel - endPoint[0] ); color_index = ( span_norm_sqr.x <= 0 || dotProduct.x <= 0 ) ? 0 : ( ( dotProduct.x < span_norm_sqr.x ) ? aStep[0][ uint( dotProduct.x * 63.49999 / span_norm_sqr.x ) ] : aStep[0][63] ); pixel_r = ( ( 64 - aWeight[0][color_index] ) * endPoint[0] + aWeight[0][color_index] * endPoint[1] + 32 ) >> 6; Ensure_A_Is_Larger( pixel_r, pixel ); pixel_r -= pixel; error += ComputeError(pixel_r, pixel_r); } mode = 6; rotation = p; // Borrow rotation for p } shared_temp[GI].error = error; shared_temp[GI].mode = mode; shared_temp[GI].index_selector = index_selector; shared_temp[GI].rotation = rotation; #ifdef REF_DEVICE GroupMemoryBarrierWithGroupSync(); #endif if (threadInBlock < 8) { if ( shared_temp[GI].error > shared_temp[GI + 8].error ) { shared_temp[GI].error = shared_temp[GI + 8].error; shared_temp[GI].mode = shared_temp[GI + 8].mode; shared_temp[GI].index_selector = shared_temp[GI + 8].index_selector; shared_temp[GI].rotation = shared_temp[GI + 8].rotation; } } #ifdef REF_DEVICE GroupMemoryBarrierWithGroupSync(); #endif if (threadInBlock < 4) { if ( shared_temp[GI].error > shared_temp[GI + 4].error ) { shared_temp[GI].error = shared_temp[GI + 4].error; shared_temp[GI].mode = shared_temp[GI + 4].mode; shared_temp[GI].index_selector = shared_temp[GI + 4].index_selector; shared_temp[GI].rotation = shared_temp[GI + 4].rotation; } } #ifdef REF_DEVICE GroupMemoryBarrierWithGroupSync(); #endif if (threadInBlock < 2) { if ( shared_temp[GI].error > shared_temp[GI + 2].error ) { shared_temp[GI].error = shared_temp[GI + 2].error; shared_temp[GI].mode = shared_temp[GI + 2].mode; shared_temp[GI].index_selector = shared_temp[GI + 2].index_selector; shared_temp[GI].rotation = shared_temp[GI + 2].rotation; } } #ifdef REF_DEVICE GroupMemoryBarrierWithGroupSync(); #endif if (threadInBlock < 1) { if ( shared_temp[GI].error > shared_temp[GI + 1].error ) { shared_temp[GI].error = shared_temp[GI + 1].error; shared_temp[GI].mode = shared_temp[GI + 1].mode; shared_temp[GI].index_selector = shared_temp[GI + 1].index_selector; shared_temp[GI].rotation = shared_temp[GI + 1].rotation; } g_OutBuff[blockID] = uint4(shared_temp[GI].error, (shared_temp[GI].index_selector << 31) | shared_temp[GI].mode, 0, shared_temp[GI].rotation); // rotation is indeed rotation for mode 4 5. for mode 6, rotation is p bit } } [numthreads( THREAD_GROUP_SIZE, 1, 1 )] void TryMode137CS( uint GI : SV_GroupIndex, uint3 groupID : SV_GroupID ) // mode 1 3 7 all have 2 subsets per block { const uint MAX_USED_THREAD = 64; uint BLOCK_IN_GROUP = THREAD_GROUP_SIZE / MAX_USED_THREAD; uint blockInGroup = GI / MAX_USED_THREAD; uint blockID = g_start_block_id + groupID.x * BLOCK_IN_GROUP + blockInGroup; uint threadBase = blockInGroup * MAX_USED_THREAD; uint threadInBlock = GI - threadBase; uint block_y = blockID / g_num_block_x; uint block_x = blockID - block_y * g_num_block_x; uint base_x = block_x * BLOCK_SIZE_X; uint base_y = block_y * BLOCK_SIZE_Y; if (threadInBlock < 16) { shared_temp[GI].pixel = clamp(uint4(g_Input.Load( uint3( base_x + threadInBlock % 4, base_y + threadInBlock / 4, 0 ) ) * 255), 0, 255); } GroupMemoryBarrierWithGroupSync(); shared_temp[GI].error = 0xFFFFFFFF; uint4 pixel_r; uint2x4 endPoint[2]; // endPoint[0..1 for subset id][0..1 for low and high in the subset] uint2x4 endPointBackup[2]; uint color_index; if (threadInBlock < 64) { uint partition = threadInBlock; endPoint[0][0] = MAX_UINT; endPoint[0][1] = MIN_UINT; endPoint[1][0] = MAX_UINT; endPoint[1][1] = MIN_UINT; uint bits = candidateSectionBit[partition]; for ( uint i = 0; i < 16; i ++ ) { uint4 pixel = shared_temp[threadBase + i].pixel; if ( (( bits >> i ) & 0x01) == 1 ) { endPoint[1][0] = min( endPoint[1][0], pixel ); endPoint[1][1] = max( endPoint[1][1], pixel ); } else { endPoint[0][0] = min( endPoint[0][0], pixel ); endPoint[0][1] = max( endPoint[0][1], pixel ); } } endPointBackup[0] = endPoint[0]; endPointBackup[1] = endPoint[1]; uint max_p; if (1 == g_mode_id) { // in mode 1, there is only one p bit per subset max_p = 4; } else { // in mode 3 7, there are two p bits per subset, one for each end point max_p = 16; } uint rotation = 0; uint error = MAX_UINT; for ( uint p = 0; p < max_p; p ++ ) { endPoint[0] = endPointBackup[0]; endPoint[1] = endPointBackup[1]; for ( i = 0; i < 2; i ++ ) // loop through 2 subsets { if (g_mode_id == 1) { compress_endpoints1( endPoint[i], (p >> i) & 1 ); } else if (g_mode_id == 3) { compress_endpoints3( endPoint[i], uint2(p >> (i * 2 + 0), p >> (i * 2 + 1)) & 1 ); } else if (g_mode_id == 7) { compress_endpoints7( endPoint[i], uint2(p >> (i * 2 + 0), p >> (i * 2 + 1)) & 1 ); } } int4 span[2]; span[0] = endPoint[0][1] - endPoint[0][0]; span[1] = endPoint[1][1] - endPoint[1][0]; if (g_mode_id != 7) { span[0].w = span[1].w = 0; } int span_norm_sqr[2]; span_norm_sqr[0] = dot( span[0], span[0] ); span_norm_sqr[1] = dot( span[1], span[1] ); // TODO: again, this shouldn't be necessary here in error calculation int dotProduct = dot( span[0], shared_temp[threadBase + 0].pixel - endPoint[0][0] ); if ( span_norm_sqr[0] > 0 && dotProduct > 0 && uint( dotProduct * 63.49999 ) > uint( 32 * span_norm_sqr[0] ) ) { span[0] = -span[0]; swap(endPoint[0][0], endPoint[0][1]); } dotProduct = dot( span[1], shared_temp[threadBase + candidateFixUpIndex1D[partition].x].pixel - endPoint[1][0] ); if ( span_norm_sqr[1] > 0 && dotProduct > 0 && uint( dotProduct * 63.49999 ) > uint( 32 * span_norm_sqr[1] ) ) { span[1] = -span[1]; swap(endPoint[1][0], endPoint[1][1]); } uint step_selector; if (g_mode_id != 1) { step_selector = 2; // mode 3 7 have 2 bit index } else { step_selector = 1; // mode 1 has 3 bit index } uint p_error = 0; for ( i = 0; i < 16; i ++ ) { if (((bits >> i) & 0x01) == 1) { dotProduct = dot( span[1], shared_temp[threadBase + i].pixel - endPoint[1][0] ); color_index = (span_norm_sqr[1] <= 0 || dotProduct <= 0) ? 0 : ((dotProduct < span_norm_sqr[1]) ? aStep[step_selector][uint(dotProduct * 63.49999 / span_norm_sqr[1])] : aStep[step_selector][63]); } else { dotProduct = dot( span[0], shared_temp[threadBase + i].pixel - endPoint[0][0] ); color_index = (span_norm_sqr[0] <= 0 || dotProduct <= 0) ? 0 : ((dotProduct < span_norm_sqr[0]) ? aStep[step_selector][uint(dotProduct * 63.49999 / span_norm_sqr[0])] : aStep[step_selector][63]); } uint subset_index = (bits >> i) & 0x01; pixel_r = ((64 - aWeight[step_selector][color_index]) * endPoint[subset_index][0] + aWeight[step_selector][color_index] * endPoint[subset_index][1] + 32) >> 6; if (g_mode_id != 7) { pixel_r.a = 255; } uint4 pixel = shared_temp[threadBase + i].pixel; Ensure_A_Is_Larger( pixel_r, pixel ); pixel_r -= pixel; p_error += ComputeError(pixel_r, pixel_r); } if (p_error < error) { error = p_error; rotation = p; } } shared_temp[GI].error = error; shared_temp[GI].mode = g_mode_id; shared_temp[GI].partition = partition; shared_temp[GI].rotation = rotation; // mode 1 3 7 don't have rotation, we use rotation for p bits } GroupMemoryBarrierWithGroupSync(); if (threadInBlock < 32) { if ( shared_temp[GI].error > shared_temp[GI + 32].error ) { shared_temp[GI].error = shared_temp[GI + 32].error; shared_temp[GI].mode = shared_temp[GI + 32].mode; shared_temp[GI].partition = shared_temp[GI + 32].partition; shared_temp[GI].rotation = shared_temp[GI + 32].rotation; } } #ifdef REF_DEVICE GroupMemoryBarrierWithGroupSync(); #endif if (threadInBlock < 16) { if ( shared_temp[GI].error > shared_temp[GI + 16].error ) { shared_temp[GI].error = shared_temp[GI + 16].error; shared_temp[GI].mode = shared_temp[GI + 16].mode; shared_temp[GI].partition = shared_temp[GI + 16].partition; shared_temp[GI].rotation = shared_temp[GI + 16].rotation; } } #ifdef REF_DEVICE GroupMemoryBarrierWithGroupSync(); #endif if (threadInBlock < 8) { if ( shared_temp[GI].error > shared_temp[GI + 8].error ) { shared_temp[GI].error = shared_temp[GI + 8].error; shared_temp[GI].mode = shared_temp[GI + 8].mode; shared_temp[GI].partition = shared_temp[GI + 8].partition; shared_temp[GI].rotation = shared_temp[GI + 8].rotation; } } #ifdef REF_DEVICE GroupMemoryBarrierWithGroupSync(); #endif if (threadInBlock < 4) { if ( shared_temp[GI].error > shared_temp[GI + 4].error ) { shared_temp[GI].error = shared_temp[GI + 4].error; shared_temp[GI].mode = shared_temp[GI + 4].mode; shared_temp[GI].partition = shared_temp[GI + 4].partition; shared_temp[GI].rotation = shared_temp[GI + 4].rotation; } } #ifdef REF_DEVICE GroupMemoryBarrierWithGroupSync(); #endif if (threadInBlock < 2) { if ( shared_temp[GI].error > shared_temp[GI + 2].error ) { shared_temp[GI].error = shared_temp[GI + 2].error; shared_temp[GI].mode = shared_temp[GI + 2].mode; shared_temp[GI].partition = shared_temp[GI + 2].partition; shared_temp[GI].rotation = shared_temp[GI + 2].rotation; } } #ifdef REF_DEVICE GroupMemoryBarrierWithGroupSync(); #endif if (threadInBlock < 1) { if ( shared_temp[GI].error > shared_temp[GI + 1].error ) { shared_temp[GI].error = shared_temp[GI + 1].error; shared_temp[GI].mode = shared_temp[GI + 1].mode; shared_temp[GI].partition = shared_temp[GI + 1].partition; shared_temp[GI].rotation = shared_temp[GI + 1].rotation; } if (g_InBuff[blockID].x > shared_temp[GI].error) { g_OutBuff[blockID] = uint4(shared_temp[GI].error, shared_temp[GI].mode, shared_temp[GI].partition, shared_temp[GI].rotation); // mode 1 3 7 don't have rotation, we use rotation for p bits } else { g_OutBuff[blockID] = g_InBuff[blockID]; } } } [numthreads( THREAD_GROUP_SIZE, 1, 1 )] void TryMode02CS( uint GI : SV_GroupIndex, uint3 groupID : SV_GroupID ) // mode 0 2 have 3 subsets per block { const uint MAX_USED_THREAD = 64; uint BLOCK_IN_GROUP = THREAD_GROUP_SIZE / MAX_USED_THREAD; uint blockInGroup = GI / MAX_USED_THREAD; uint blockID = g_start_block_id + groupID.x * BLOCK_IN_GROUP + blockInGroup; uint threadBase = blockInGroup * MAX_USED_THREAD; uint threadInBlock = GI - threadBase; uint block_y = blockID / g_num_block_x; uint block_x = blockID - block_y * g_num_block_x; uint base_x = block_x * BLOCK_SIZE_X; uint base_y = block_y * BLOCK_SIZE_Y; if (threadInBlock < 16) { shared_temp[GI].pixel = clamp(uint4(g_Input.Load( uint3( base_x + threadInBlock % 4, base_y + threadInBlock / 4, 0 ) ) * 255), 0, 255); } GroupMemoryBarrierWithGroupSync(); shared_temp[GI].error = 0xFFFFFFFF; uint num_partitions; if (0 == g_mode_id) { num_partitions = 16; } else { num_partitions = 64; } uint4 pixel_r; uint2x4 endPoint[3]; // endPoint[0..1 for subset id][0..1 for low and high in the subset] uint2x4 endPointBackup[3]; uint color_index[16]; if (threadInBlock < num_partitions) { uint partition = threadInBlock + 64; endPoint[0][0] = MAX_UINT; endPoint[0][1] = MIN_UINT; endPoint[1][0] = MAX_UINT; endPoint[1][1] = MIN_UINT; endPoint[2][0] = MAX_UINT; endPoint[2][1] = MIN_UINT; uint bits2 = candidateSectionBit2[partition - 64]; for ( uint i = 0; i < 16; i ++ ) { uint4 pixel = shared_temp[threadBase + i].pixel; uint subset_index = ( bits2 >> ( i * 2 ) ) & 0x03; if ( subset_index == 2 ) { endPoint[2][0] = min( endPoint[2][0], pixel ); endPoint[2][1] = max( endPoint[2][1], pixel ); } else if ( subset_index == 1 ) { endPoint[1][0] = min( endPoint[1][0], pixel ); endPoint[1][1] = max( endPoint[1][1], pixel ); } else { endPoint[0][0] = min( endPoint[0][0], pixel ); endPoint[0][1] = max( endPoint[0][1], pixel ); } } endPointBackup[0] = endPoint[0]; endPointBackup[1] = endPoint[1]; endPointBackup[2] = endPoint[2]; uint max_p; if (0 == g_mode_id) { max_p = 64; // changed from 32 to 64 } else { max_p = 1; } uint rotation = 0; uint error = MAX_UINT; for ( uint p = 0; p < max_p; p ++ ) { endPoint[0] = endPointBackup[0]; endPoint[1] = endPointBackup[1]; endPoint[2] = endPointBackup[2]; for ( i = 0; i < 3; i ++ ) { if (0 == g_mode_id) { compress_endpoints0( endPoint[i], uint2(p >> (i * 2 + 0), p >> (i * 2 + 1)) & 1 ); } else { compress_endpoints2( endPoint[i] ); } } uint step_selector = 1 + (2 == g_mode_id); int4 span[3]; span[0] = endPoint[0][1] - endPoint[0][0]; span[1] = endPoint[1][1] - endPoint[1][0]; span[2] = endPoint[2][1] - endPoint[2][0]; span[0].w = span[1].w = span[2].w = 0; int span_norm_sqr[3]; span_norm_sqr[0] = dot( span[0], span[0] ); span_norm_sqr[1] = dot( span[1], span[1] ); span_norm_sqr[2] = dot( span[2], span[2] ); // TODO: again, this shouldn't be necessary here in error calculation uint ci[3] = { 0, candidateFixUpIndex1D[partition].x, candidateFixUpIndex1D[partition].y }; for (i = 0; i < 3; i ++) { int dotProduct = dot( span[i], shared_temp[threadBase + ci[i]].pixel - endPoint[i][0] ); if ( span_norm_sqr[i] > 0 && dotProduct > 0 && uint( dotProduct * 63.49999 ) > uint( 32 * span_norm_sqr[i] ) ) { span[i] = -span[i]; swap(endPoint[i][0], endPoint[i][1]); } } uint p_error = 0; for ( i = 0; i < 16; i ++ ) { uint subset_index = ( bits2 >> ( i * 2 ) ) & 0x03; if ( subset_index == 2 ) { int dotProduct = dot( span[2], shared_temp[threadBase + i].pixel - endPoint[2][0] ); color_index[i] = ( span_norm_sqr[2] <= 0 || dotProduct <= 0 ) ? 0 : ( ( dotProduct < span_norm_sqr[2] ) ? aStep[step_selector][ uint( dotProduct * 63.49999 / span_norm_sqr[2] ) ] : aStep[step_selector][63] ); } else if ( subset_index == 1 ) { int dotProduct = dot( span[1], shared_temp[threadBase + i].pixel - endPoint[1][0] ); color_index[i] = ( span_norm_sqr[1] <= 0 || dotProduct <= 0 ) ? 0 : ( ( dotProduct < span_norm_sqr[1] ) ? aStep[step_selector][ uint( dotProduct * 63.49999 / span_norm_sqr[1] ) ] : aStep[step_selector][63] ); } else { int dotProduct = dot( span[0], shared_temp[threadBase + i].pixel - endPoint[0][0] ); color_index[i] = ( span_norm_sqr[0] <= 0 || dotProduct <= 0 ) ? 0 : ( ( dotProduct < span_norm_sqr[0] ) ? aStep[step_selector][ uint( dotProduct * 63.49999 / span_norm_sqr[0] ) ] : aStep[step_selector][63] ); } pixel_r = ( ( 64 - aWeight[step_selector][color_index[i]] ) * endPoint[subset_index][0] + aWeight[step_selector][color_index[i]] * endPoint[subset_index][1] + 32 ) >> 6; pixel_r.a = 255; uint4 pixel = shared_temp[threadBase + i].pixel; Ensure_A_Is_Larger( pixel_r, pixel ); pixel_r -= pixel; p_error += ComputeError(pixel_r, pixel_r); } if (p_error < error) { error = p_error; rotation = p; // Borrow rotation for p } } shared_temp[GI].error = error; shared_temp[GI].partition = partition; shared_temp[GI].rotation = rotation; } GroupMemoryBarrierWithGroupSync(); if (threadInBlock < 32) { if ( shared_temp[GI].error > shared_temp[GI + 32].error ) { shared_temp[GI].error = shared_temp[GI + 32].error; shared_temp[GI].partition = shared_temp[GI + 32].partition; shared_temp[GI].rotation = shared_temp[GI + 32].rotation; } } #ifdef REF_DEVICE GroupMemoryBarrierWithGroupSync(); #endif if (threadInBlock < 16) { if ( shared_temp[GI].error > shared_temp[GI + 16].error ) { shared_temp[GI].error = shared_temp[GI + 16].error; shared_temp[GI].partition = shared_temp[GI + 16].partition; shared_temp[GI].rotation = shared_temp[GI + 16].rotation; } } #ifdef REF_DEVICE GroupMemoryBarrierWithGroupSync(); #endif if (threadInBlock < 8) { if ( shared_temp[GI].error > shared_temp[GI + 8].error ) { shared_temp[GI].error = shared_temp[GI + 8].error; shared_temp[GI].partition = shared_temp[GI + 8].partition; shared_temp[GI].rotation = shared_temp[GI + 8].rotation; } } #ifdef REF_DEVICE GroupMemoryBarrierWithGroupSync(); #endif if (threadInBlock < 4) { if ( shared_temp[GI].error > shared_temp[GI + 4].error ) { shared_temp[GI].error = shared_temp[GI + 4].error; shared_temp[GI].partition = shared_temp[GI + 4].partition; shared_temp[GI].rotation = shared_temp[GI + 4].rotation; } } #ifdef REF_DEVICE GroupMemoryBarrierWithGroupSync(); #endif if (threadInBlock < 2) { if ( shared_temp[GI].error > shared_temp[GI + 2].error ) { shared_temp[GI].error = shared_temp[GI + 2].error; shared_temp[GI].partition = shared_temp[GI + 2].partition; shared_temp[GI].rotation = shared_temp[GI + 2].rotation; } } #ifdef REF_DEVICE GroupMemoryBarrierWithGroupSync(); #endif if (threadInBlock < 1) { if ( shared_temp[GI].error > shared_temp[GI + 1].error ) { shared_temp[GI].error = shared_temp[GI + 1].error; shared_temp[GI].partition = shared_temp[GI + 1].partition; shared_temp[GI].rotation = shared_temp[GI + 1].rotation; } if (g_InBuff[blockID].x > shared_temp[GI].error) { g_OutBuff[blockID] = uint4(shared_temp[GI].error, g_mode_id, shared_temp[GI].partition, shared_temp[GI].rotation); // rotation is actually p bit for mode 0. for mode 2, rotation is always 0 } else { g_OutBuff[blockID] = g_InBuff[blockID]; } } } [numthreads( THREAD_GROUP_SIZE, 1, 1 )] void EncodeBlockCS(uint GI : SV_GroupIndex, uint3 groupID : SV_GroupID) { const uint MAX_USED_THREAD = 16; uint BLOCK_IN_GROUP = THREAD_GROUP_SIZE / MAX_USED_THREAD; uint blockInGroup = GI / MAX_USED_THREAD; uint blockID = g_start_block_id + groupID.x * BLOCK_IN_GROUP + blockInGroup; uint threadBase = blockInGroup * MAX_USED_THREAD; uint threadInBlock = GI - threadBase; #ifndef REF_DEVICE if (blockID >= g_num_total_blocks) { return; } #endif uint block_y = blockID / g_num_block_x; uint block_x = blockID - block_y * g_num_block_x; uint base_x = block_x * BLOCK_SIZE_X; uint base_y = block_y * BLOCK_SIZE_Y; uint mode = g_InBuff[blockID].y & 0x7FFFFFFF; uint partition = g_InBuff[blockID].z; uint index_selector = (g_InBuff[blockID].y >> 31) & 1; uint rotation = g_InBuff[blockID].w; if (threadInBlock < 16) { uint4 pixel = clamp(uint4(g_Input.Load( uint3( base_x + threadInBlock % 4, base_y + threadInBlock / 4, 0 ) ) * 255), 0, 255); if ((4 == mode) || (5 == mode)) { if (1 == rotation) { pixel.ra = pixel.ar; } else if (2 == rotation) { pixel.ga = pixel.ag; } else if (3 == rotation) { pixel.ba = pixel.ab; } } shared_temp[GI].pixel = pixel; } #ifdef REF_DEVICE GroupMemoryBarrierWithGroupSync(); #endif uint bits = candidateSectionBit[partition]; uint bits2 = candidateSectionBit2[partition - 64]; uint2x4 ep; uint2x4 ep_quantized; [unroll] for (int ii = 2; ii >= 0; -- ii) { if (threadInBlock < 16) { uint2x4 ep; ep[0] = MAX_UINT; ep[1] = MIN_UINT; uint4 pixel = shared_temp[GI].pixel; uint subset_index = ( bits >> threadInBlock ) & 0x01; uint subset_index2 = ( bits2 >> ( threadInBlock * 2 ) ) & 0x03; if (0 == ii) { if ((0 == mode) || (2 == mode)) { if (0 == subset_index2) { ep[0] = ep[1] = pixel; } } else if ((1 == mode) || (3 == mode) || (7 == mode)) { if (0 == subset_index) { ep[0] = ep[1] = pixel; } } else if ((4 == mode) || (5 == mode) || (6 == mode)) { ep[0] = ep[1] = pixel; } } else if (1 == ii) { if ((0 == mode) || (2 == mode)) { if (1 == subset_index2) { ep[0] = ep[1] = pixel; } } else if ((1 == mode) || (3 == mode) || (7 == mode)) { if (1 == subset_index) { ep[0] = ep[1] = pixel; } } } else { if ((0 == mode) || (2 == mode)) { if (2 == subset_index2) { ep[0] = ep[1] = pixel; } } } shared_temp[GI].endPoint_low = ep[0]; shared_temp[GI].endPoint_high = ep[1]; } #ifdef REF_DEVICE GroupMemoryBarrierWithGroupSync(); #endif if (threadInBlock < 8) { shared_temp[GI].endPoint_low = min(shared_temp[GI].endPoint_low, shared_temp[GI + 8].endPoint_low); shared_temp[GI].endPoint_high = max(shared_temp[GI].endPoint_high, shared_temp[GI + 8].endPoint_high); } #ifdef REF_DEVICE GroupMemoryBarrierWithGroupSync(); #endif if (threadInBlock < 4) { shared_temp[GI].endPoint_low = min(shared_temp[GI].endPoint_low, shared_temp[GI + 4].endPoint_low); shared_temp[GI].endPoint_high = max(shared_temp[GI].endPoint_high, shared_temp[GI + 4].endPoint_high); } #ifdef REF_DEVICE GroupMemoryBarrierWithGroupSync(); #endif if (threadInBlock < 2) { shared_temp[GI].endPoint_low = min(shared_temp[GI].endPoint_low, shared_temp[GI + 2].endPoint_low); shared_temp[GI].endPoint_high = max(shared_temp[GI].endPoint_high, shared_temp[GI + 2].endPoint_high); } #ifdef REF_DEVICE GroupMemoryBarrierWithGroupSync(); #endif if (threadInBlock < 1) { shared_temp[GI].endPoint_low = min(shared_temp[GI].endPoint_low, shared_temp[GI + 1].endPoint_low); shared_temp[GI].endPoint_high = max(shared_temp[GI].endPoint_high, shared_temp[GI + 1].endPoint_high); } #ifdef REF_DEVICE GroupMemoryBarrierWithGroupSync(); #endif if (ii == (int)threadInBlock) { ep[0] = shared_temp[threadBase].endPoint_low; ep[1] = shared_temp[threadBase].endPoint_high; } } if (threadInBlock < 3) { uint2 P; if (1 == mode) { P = (rotation >> threadInBlock) & 1; } else { P = uint2(rotation >> (threadInBlock * 2 + 0), rotation >> (threadInBlock * 2 + 1)) & 1; } if (0 == mode) { ep_quantized = compress_endpoints0( ep, P ); } else if (1 == mode) { ep_quantized = compress_endpoints1( ep, P ); } else if (2 == mode) { ep_quantized = compress_endpoints2( ep ); } else if (3 == mode) { ep_quantized = compress_endpoints3( ep, P ); } else if (4 == mode) { ep_quantized = compress_endpoints4( ep ); } else if (5 == mode) { ep_quantized = compress_endpoints5( ep ); } else if (6 == mode) { ep_quantized = compress_endpoints6( ep, P ); } else //if (7 == mode) { ep_quantized = compress_endpoints7( ep, P ); } int4 span = ep[1] - ep[0]; if (mode < 4) { span.w = 0; } if ((4 == mode) || (5 == mode)) { if (0 == threadInBlock) { int2 span_norm_sqr = uint2( dot( span.rgb, span.rgb ), span.a * span.a ); int2 dotProduct = int2( dot( span.rgb, shared_temp[threadBase + 0].pixel.rgb - ep[0].rgb ), span.a * ( shared_temp[threadBase + 0].pixel.a - ep[0].a ) ); if ( span_norm_sqr.x > 0 && dotProduct.x > 0 && uint( dotProduct.x * 63.49999 ) > uint( 32 * span_norm_sqr.x ) ) { swap(ep[0].rgb, ep[1].rgb); swap(ep_quantized[0].rgb, ep_quantized[1].rgb); } if ( span_norm_sqr.y > 0 && dotProduct.y > 0 && uint( dotProduct.y * 63.49999 ) > uint( 32 * span_norm_sqr.y ) ) { swap(ep[0].a, ep[1].a); swap(ep_quantized[0].a, ep_quantized[1].a); } } } else //if ((0 == mode) || (2 == mode) || (1 == mode) || (3 == mode) || (7 == mode) || (6 == mode)) { int p; if (0 == threadInBlock) { p = 0; } else if (1 == threadInBlock) { p = candidateFixUpIndex1D[partition].x; } else //if (2 == threadInBlock) { p = candidateFixUpIndex1D[partition].y; } int span_norm_sqr = dot( span, span ); int dotProduct = dot( span, shared_temp[threadBase + p].pixel - ep[0] ); if ( span_norm_sqr > 0 && dotProduct > 0 && uint( dotProduct * 63.49999 ) > uint( 32 * span_norm_sqr ) ) { swap(ep[0], ep[1]); swap(ep_quantized[0], ep_quantized[1]); } } shared_temp[GI].endPoint_low = ep[0]; shared_temp[GI].endPoint_high = ep[1]; shared_temp[GI].endPoint_low_quantized = ep_quantized[0]; shared_temp[GI].endPoint_high_quantized = ep_quantized[1]; } #ifdef REF_DEVICE GroupMemoryBarrierWithGroupSync(); #endif if (threadInBlock < 16) { uint color_index = 0; uint alpha_index = 0; uint2x4 ep; uint2 indexPrec; if ((0 == mode) || (1 == mode)) { indexPrec = 1; } else if (6 == mode) { indexPrec = 0; } else if (4 == mode) { if (0 == index_selector) { indexPrec = uint2(2, 1); } else { indexPrec = uint2(1, 2); } } else { indexPrec = 2; } int subset_index; if ((0 == mode) || (2 == mode)) { subset_index = (bits2 >> (threadInBlock * 2)) & 0x03; } else if ((1 == mode) || (3 == mode) || (7 == mode)) { subset_index = (bits >> threadInBlock) & 0x01; } else { subset_index = 0; } ep[0] = shared_temp[threadBase + subset_index].endPoint_low; ep[1] = shared_temp[threadBase + subset_index].endPoint_high; int4 span = ep[1] - ep[0]; if (mode < 4) { span.w = 0; } if ((4 == mode) || (5 == mode)) { int2 span_norm_sqr; span_norm_sqr.x = dot( span.rgb, span.rgb ); span_norm_sqr.y = span.a * span.a; int dotProduct = dot( span.rgb, shared_temp[threadBase + threadInBlock].pixel.rgb - ep[0].rgb ); color_index = ( span_norm_sqr.x <= 0 || dotProduct <= 0 ) ? 0 : ( ( dotProduct < span_norm_sqr.x ) ? aStep[indexPrec.x][ uint( dotProduct * 63.49999 / span_norm_sqr.x ) ] : aStep[indexPrec.x][63] ); dotProduct = dot( span.a, shared_temp[threadBase + threadInBlock].pixel.a - ep[0].a ); alpha_index = ( span_norm_sqr.y <= 0 || dotProduct <= 0 ) ? 0 : ( ( dotProduct < span_norm_sqr.y ) ? aStep[indexPrec.y][ uint( dotProduct * 63.49999 / span_norm_sqr.y ) ] : aStep[indexPrec.y][63] ); if (index_selector) { swap(color_index, alpha_index); } } else { int span_norm_sqr = dot( span, span ); int dotProduct = dot( span, shared_temp[threadBase + threadInBlock].pixel - ep[0] ); color_index = ( span_norm_sqr <= 0 || dotProduct <= 0 ) ? 0 : ( ( dotProduct < span_norm_sqr ) ? aStep[indexPrec.x][ uint( dotProduct * 63.49999 / span_norm_sqr ) ] : aStep[indexPrec.x][63] ); } shared_temp[GI].error = color_index; shared_temp[GI].mode = alpha_index; } #ifdef REF_DEVICE GroupMemoryBarrierWithGroupSync(); #endif if (0 == threadInBlock) { uint4 block; if (0 == mode) { block_package0( block, partition, threadBase ); } else if (1 == mode) { block_package1( block, partition, threadBase ); } else if (2 == mode) { block_package2( block, partition, threadBase ); } else if (3 == mode) { block_package3( block, partition, threadBase ); } else if (4 == mode) { block_package4( block, rotation, index_selector, threadBase ); } else if (5 == mode) { block_package5( block, rotation, threadBase ); } else if (6 == mode) { block_package6( block, threadBase ); } else //if (7 == mode) { block_package7( block, partition, threadBase ); } g_OutBuff[blockID] = block; } } //uint4 truncate_and_round( uint4 color, uint bits) //{ // uint precisionMask = ((1 << bits) - 1) << (8 - bits); // uint precisionHalf = (1 << (7-bits)); // // uint4 truncated = color & precisionMask; // uint4 rounded = min(255, color + precisionHalf) & precisionMask; // // uint4 truncated_bak = truncated = truncated | (truncated >> bits); // uint4 rounded_bak = rounded = rounded | (rounded >> bits); // // uint4 color_bak = color; // // Ensure_A_Is_Larger( rounded, color ); // Ensure_A_Is_Larger( truncated, color_bak ); // // if (dot(rounded - color, rounded - color) < // dot(truncated - color_bak, truncated - color_bak)) // { // return rounded_bak; // } // else // { // return truncated_bak; // } //} uint4 quantize( uint4 color, uint uPrec ) { uint4 rnd = min(255, color + (1 << (7 - uPrec))); return rnd >> (8 - uPrec); } uint4 unquantize( uint4 color, uint uPrec ) { color = color << (8 - uPrec); return color | (color >> uPrec); } uint2x4 compress_endpoints0( inout uint2x4 endPoint, uint2 P ) { uint2x4 quantized; for ( uint j = 0; j < 2; j ++ ) { quantized[j].rgb = quantize(endPoint[j].rgbb, 5).rgb & 0xFFFFFFFE; quantized[j].rgb |= P[j]; quantized[j].a = 0xFF; endPoint[j].rgb = unquantize(quantized[j].rgbb, 5).rgb; endPoint[j].a = 0xFF; quantized[j] <<= 3; } return quantized; } uint2x4 compress_endpoints1( inout uint2x4 endPoint, uint2 P ) { uint2x4 quantized; for ( uint j = 0; j < 2; j ++ ) { quantized[j].rgb = quantize(endPoint[j].rgbb, 7).rgb & 0xFFFFFFFE; quantized[j].rgb |= P[j]; quantized[j].a = 0xFF; endPoint[j].rgb = unquantize(quantized[j].rgbb, 7).rgb; endPoint[j].a = 0xFF; quantized[j] <<= 1; } return quantized; } uint2x4 compress_endpoints2( inout uint2x4 endPoint ) { uint2x4 quantized; for ( uint j = 0; j < 2; j ++ ) { quantized[j].rgb = quantize(endPoint[j].rgbb, 5).rgb; quantized[j].a = 0xFF; endPoint[j].rgb = unquantize(quantized[j].rgbb, 5).rgb; endPoint[j].a = 0xFF; quantized[j] <<= 3; } return quantized; } uint2x4 compress_endpoints3( inout uint2x4 endPoint, uint2 P ) { uint2x4 quantized; for ( uint j = 0; j < 2; j ++ ) { quantized[j].rgb = endPoint[j].rgb & 0xFFFFFFFE; quantized[j].rgb |= P[j]; quantized[j].a = 0xFF; endPoint[j].rgb = quantized[j].rgb; endPoint[j].a = 0xFF; } return quantized; } uint2x4 compress_endpoints4( inout uint2x4 endPoint ) { uint2x4 quantized; for ( uint j = 0; j < 2; j ++ ) { quantized[j].rgb = quantize(endPoint[j].rgbb, 5).rgb; quantized[j].a = quantize(endPoint[j].a, 6).r; endPoint[j].rgb = unquantize(quantized[j].rgbb, 5).rgb; endPoint[j].a = unquantize(quantized[j].a, 6).r; quantized[j].rgb <<= 3; quantized[j].a <<= 2; } return quantized; } uint2x4 compress_endpoints5( inout uint2x4 endPoint ) { uint2x4 quantized; for ( uint j = 0; j < 2; j ++ ) { quantized[j].rgb = quantize(endPoint[j].rgbb, 7).rgb; quantized[j].a = endPoint[j].a; endPoint[j].rgb = unquantize(quantized[j].rgbb, 7).rgb; // endPoint[j].a Alpha is full precision quantized[j].rgb <<= 1; } return quantized; } uint2x4 compress_endpoints6( inout uint2x4 endPoint, uint2 P ) { uint2x4 quantized; for ( uint j = 0; j < 2; j ++ ) { quantized[j] = endPoint[j] & 0xFFFFFFFE; quantized[j] |= P[j]; endPoint[j] = quantized[j]; } return quantized; } uint2x4 compress_endpoints7( inout uint2x4 endPoint, uint2 P ) { uint2x4 quantized; for ( uint j = 0; j < 2; j ++ ) { quantized[j] = quantize(endPoint[j], 6) & 0xFFFFFFFE; quantized[j] |= P[j]; endPoint[j] = unquantize(quantized[j], 6); } return quantized << 2; } #define get_end_point_l(subset) shared_temp[threadBase + subset].endPoint_low_quantized #define get_end_point_h(subset) shared_temp[threadBase + subset].endPoint_high_quantized #define get_color_index(index) shared_temp[threadBase + index].error #define get_alpha_index(index) shared_temp[threadBase + index].mode void block_package0( out uint4 block, uint partition, uint threadBase ) { block.x = 0x01 | ( (partition - 64) << 1 ) | ( ( get_end_point_l(0).r & 0xF0 ) << 1 ) | ( ( get_end_point_h(0).r & 0xF0 ) << 5 ) | ( ( get_end_point_l(1).r & 0xF0 ) << 9 ) | ( ( get_end_point_h(1).r & 0xF0 ) << 13 ) | ( ( get_end_point_l(2).r & 0xF0 ) << 17 ) | ( ( get_end_point_h(2).r & 0xF0 ) << 21 ) | ( ( get_end_point_l(0).g & 0xF0 ) << 25 ); block.y = ( ( get_end_point_l(0).g & 0xF0 ) >> 7 ) | ( ( get_end_point_h(0).g & 0xF0 ) >> 3 ) | ( ( get_end_point_l(1).g & 0xF0 ) << 1 ) | ( ( get_end_point_h(1).g & 0xF0 ) << 5 ) | ( ( get_end_point_l(2).g & 0xF0 ) << 9 ) | ( ( get_end_point_h(2).g & 0xF0 ) << 13 ) | ( ( get_end_point_l(0).b & 0xF0 ) << 17 ) | ( ( get_end_point_h(0).b & 0xF0 ) << 21 ) | ( ( get_end_point_l(1).b & 0xF0 ) << 25 ); block.z = ( ( get_end_point_l(1).b & 0xF0 ) >> 7 ) | ( ( get_end_point_h(1).b & 0xF0 ) >> 3 ) | ( ( get_end_point_l(2).b & 0xF0 ) << 1 ) | ( ( get_end_point_h(2).b & 0xF0 ) << 5 ) | ( ( get_end_point_l(0).r & 0x08 ) << 10 ) | ( ( get_end_point_h(0).r & 0x08 ) << 11 ) | ( ( get_end_point_l(1).r & 0x08 ) << 12 ) | ( ( get_end_point_h(1).r & 0x08 ) << 13 ) | ( ( get_end_point_l(2).r & 0x08 ) << 14 ) | ( ( get_end_point_h(2).r & 0x08 ) << 15 ) | ( get_color_index(0) << 19 ); block.w = 0; uint i = 1; for ( ; i <= min( candidateFixUpIndex1DOrdered[partition][0], 4 ); i ++ ) { block.z |= get_color_index(i) << ( i * 3 + 18 ); } if ( candidateFixUpIndex1DOrdered[partition][0] < 4 ) //i = 4 { block.z |= get_color_index(4) << 29; i += 1; } else //i = 5 { block.w |= ( get_color_index(4) & 0x04 ) >> 2; for ( ; i <= candidateFixUpIndex1DOrdered[partition][0]; i ++ ) block.w |= get_color_index(i) << ( i * 3 - 14 ); } for ( ; i <= candidateFixUpIndex1DOrdered[partition][1]; i ++ ) { block.w |= get_color_index(i) << ( i * 3 - 15 ); } for ( ; i < 16; i ++ ) { block.w |= get_color_index(i) << ( i * 3 - 16 ); } } void block_package1( out uint4 block, uint partition, uint threadBase ) { block.x = 0x02 | ( partition << 2 ) | ( ( get_end_point_l(0).r & 0xFC ) << 6 ) | ( ( get_end_point_h(0).r & 0xFC ) << 12 ) | ( ( get_end_point_l(1).r & 0xFC ) << 18 ) | ( ( get_end_point_h(1).r & 0xFC ) << 24 ); block.y = ( ( get_end_point_l(0).g & 0xFC ) >> 2 ) | ( ( get_end_point_h(0).g & 0xFC ) << 4 ) | ( ( get_end_point_l(1).g & 0xFC ) << 10 ) | ( ( get_end_point_h(1).g & 0xFC ) << 16 ) | ( ( get_end_point_l(0).b & 0xFC ) << 22 ) | ( ( get_end_point_h(0).b & 0xFC ) << 28 ); block.z = ( ( get_end_point_h(0).b & 0xFC ) >> 4 ) | ( ( get_end_point_l(1).b & 0xFC ) << 2 ) | ( ( get_end_point_h(1).b & 0xFC ) << 8 ) | ( ( get_end_point_l(0).r & 0x02 ) << 15 ) | ( ( get_end_point_l(1).r & 0x02 ) << 16 ) | ( get_color_index(0) << 18 ); if ( candidateFixUpIndex1DOrdered[partition][0] == 15 ) { block.w = (get_color_index(15) << 30) | (get_color_index(14) << 27) | (get_color_index(13) << 24) | (get_color_index(12) << 21) | (get_color_index(11) << 18) | (get_color_index(10) << 15) | (get_color_index(9) << 12) | (get_color_index(8) << 9) | (get_color_index(7) << 6) | (get_color_index(6) << 3) | get_color_index(5); block.z |= (get_color_index(4) << 29) | (get_color_index(3) << 26) | (get_color_index(2) << 23) | (get_color_index(1) << 20) | (get_color_index(0) << 18); } else if ( candidateFixUpIndex1DOrdered[partition][0] == 2 ) { block.w = (get_color_index(15) << 29) | (get_color_index(14) << 26) | (get_color_index(13) << 23) | (get_color_index(12) << 20) | (get_color_index(11) << 17) | (get_color_index(10) << 14) | (get_color_index(9) << 11) | (get_color_index(8) << 8) | (get_color_index(7) << 5) | (get_color_index(6) << 2) | (get_color_index(5) >> 1); block.z |= (get_color_index(5) << 31) | (get_color_index(4) << 28) | (get_color_index(3) << 25) | (get_color_index(2) << 23) | (get_color_index(1) << 20) | (get_color_index(0) << 18); } else if ( candidateFixUpIndex1DOrdered[partition][0] == 8 ) { block.w = (get_color_index(15) << 29) | (get_color_index(14) << 26) | (get_color_index(13) << 23) | (get_color_index(12) << 20) | (get_color_index(11) << 17) | (get_color_index(10) << 14) | (get_color_index(9) << 11) | (get_color_index(8) << 9) | (get_color_index(7) << 6) | (get_color_index(6) << 3) | get_color_index(5); block.z |= (get_color_index(4) << 29) | (get_color_index(3) << 26) | (get_color_index(2) << 23) | (get_color_index(1) << 20) | (get_color_index(0) << 18); } else //candidateFixUpIndex1DOrdered[partition] == 6 { block.w = (get_color_index(15) << 29) | (get_color_index(14) << 26) | (get_color_index(13) << 23) | (get_color_index(12) << 20) | (get_color_index(11) << 17) | (get_color_index(10) << 14) | (get_color_index(9) << 11) | (get_color_index(8) << 8) | (get_color_index(7) << 6) | (get_color_index(6) << 4) | get_color_index(5); block.z |= (get_color_index(4) << 29) | (get_color_index(3) << 26) | (get_color_index(2) << 23) | (get_color_index(1) << 20) | (get_color_index(0) << 18); } } void block_package2( out uint4 block, uint partition, uint threadBase ) { block.x = 0x04 | ( (partition - 64) << 3 ) | ( ( get_end_point_l(0).r & 0xF8 ) << 6 ) | ( ( get_end_point_h(0).r & 0xF8 ) << 11 ) | ( ( get_end_point_l(1).r & 0xF8 ) << 16 ) | ( ( get_end_point_h(1).r & 0xF8 ) << 21 ) | ( ( get_end_point_l(2).r & 0xF8 ) << 26 ); block.y = ( ( get_end_point_l(2).r & 0xF8 ) >> 6 ) | ( ( get_end_point_h(2).r & 0xF8 ) >> 1 ) | ( ( get_end_point_l(0).g & 0xF8 ) << 4 ) | ( ( get_end_point_h(0).g & 0xF8 ) << 9 ) | ( ( get_end_point_l(1).g & 0xF8 ) << 14 ) | ( ( get_end_point_h(1).g & 0xF8 ) << 19 ) | ( ( get_end_point_l(2).g & 0xF8 ) << 24 ); block.z = ( ( get_end_point_h(2).g & 0xF8 ) >> 3 ) | ( ( get_end_point_l(0).b & 0xF8 ) << 2 ) | ( ( get_end_point_h(0).b & 0xF8 ) << 7 ) | ( ( get_end_point_l(1).b & 0xF8 ) << 12 ) | ( ( get_end_point_h(1).b & 0xF8 ) << 17 ) | ( ( get_end_point_l(2).b & 0xF8 ) << 22 ) | ( ( get_end_point_h(2).b & 0xF8 ) << 27 ); block.w = ( ( get_end_point_h(2).b & 0xF8 ) >> 5 ) | ( get_color_index(0) << 3 ); uint i = 1; for ( ; i <= candidateFixUpIndex1DOrdered[partition][0]; i ++ ) { block.w |= get_color_index(i) << ( i * 2 + 2 ); } for ( ; i <= candidateFixUpIndex1DOrdered[partition][1]; i ++ ) { block.w |= get_color_index(i) << ( i * 2 + 1 ); } for ( ; i < 16; i ++ ) { block.w |= get_color_index(i) << ( i * 2 ); } } void block_package3( out uint4 block, uint partition, uint threadBase ) { block.x = 0x08 | ( partition << 4 ) | ( ( get_end_point_l(0).r & 0xFE ) << 9 ) | ( ( get_end_point_h(0).r & 0xFE ) << 16 ) | ( ( get_end_point_l(1).r & 0xFE ) << 23 ) | ( ( get_end_point_h(1).r & 0xFE ) << 30 ); block.y = ( ( get_end_point_h(1).r & 0xFE ) >> 2 ) | ( ( get_end_point_l(0).g & 0xFE ) << 5 ) | ( ( get_end_point_h(0).g & 0xFE ) << 12 ) | ( ( get_end_point_l(1).g & 0xFE ) << 19 ) | ( ( get_end_point_h(1).g & 0xFE ) << 26 ); block.z = ( ( get_end_point_h(1).g & 0xFE ) >> 6 ) | ( ( get_end_point_l(0).b & 0xFE ) << 1 ) | ( ( get_end_point_h(0).b & 0xFE ) << 8 ) | ( ( get_end_point_l(1).b & 0xFE ) << 15 ) | ( ( get_end_point_h(1).b & 0xFE ) << 22 ) | ( ( get_end_point_l(0).r & 0x01 ) << 30 ) | ( ( get_end_point_h(0).r & 0x01 ) << 31 ); block.w = ( ( get_end_point_l(1).r & 0x01 ) << 0 ) | ( ( get_end_point_h(1).r & 0x01 ) << 1 ) | ( get_color_index(0) << 2 ); uint i = 1; for ( ; i <= candidateFixUpIndex1DOrdered[partition][0]; i ++ ) { block.w |= get_color_index(i) << ( i * 2 + 1 ); } for ( ; i < 16; i ++ ) { block.w |= get_color_index(i) << ( i * 2 ); } } void block_package4( out uint4 block, uint rotation, uint index_selector, uint threadBase ) { block.x = 0x10 | ( (rotation & 3) << 5 ) | ( (index_selector & 1) << 7 ) | ( ( get_end_point_l(0).r & 0xF8 ) << 5 ) | ( ( get_end_point_h(0).r & 0xF8 ) << 10 ) | ( ( get_end_point_l(0).g & 0xF8 ) << 15 ) | ( ( get_end_point_h(0).g & 0xF8 ) << 20 ) | ( ( get_end_point_l(0).b & 0xF8 ) << 25 ); block.y = ( ( get_end_point_l(0).b & 0xF8 ) >> 7 ) | ( ( get_end_point_h(0).b & 0xF8 ) >> 2 ) | ( ( get_end_point_l(0).a & 0xFC ) << 4 ) | ( ( get_end_point_h(0).a & 0xFC ) << 10 ) | ( (get_color_index(0) & 1) << 18 ) | ( get_color_index(1) << 19 ) | ( get_color_index(2) << 21 ) | ( get_color_index(3) << 23 ) | ( get_color_index(4) << 25 ) | ( get_color_index(5) << 27 ) | ( get_color_index(6) << 29 ) | ( get_color_index(7) << 31 ); block.z = ( get_color_index(7) >> 1 ) | ( get_color_index(8) << 1 ) | ( get_color_index(9) << 3 ) | ( get_color_index(10)<< 5 ) | ( get_color_index(11)<< 7 ) | ( get_color_index(12)<< 9 ) | ( get_color_index(13)<< 11 ) | ( get_color_index(14)<< 13 ) | ( get_color_index(15)<< 15 ) | ( (get_alpha_index(0) & 3) << 17 ) | ( get_alpha_index(1) << 19 ) | ( get_alpha_index(2) << 22 ) | ( get_alpha_index(3) << 25 ) | ( get_alpha_index(4) << 28 ) | ( get_alpha_index(5) << 31 ); block.w = ( get_alpha_index(5) >> 1 ) | ( get_alpha_index(6) << 2 ) | ( get_alpha_index(7) << 5 ) | ( get_alpha_index(8) << 8 ) | ( get_alpha_index(9) << 11 ) | ( get_alpha_index(10)<< 14 ) | ( get_alpha_index(11)<< 17 ) | ( get_alpha_index(12)<< 20 ) | ( get_alpha_index(13)<< 23 ) | ( get_alpha_index(14)<< 26 ) | ( get_alpha_index(15)<< 29 ); } void block_package5( out uint4 block, uint rotation, uint threadBase ) { block.x = 0x20 | ( rotation << 6 ) | ( ( get_end_point_l(0).r & 0xFE ) << 7 ) | ( ( get_end_point_h(0).r & 0xFE ) << 14 ) | ( ( get_end_point_l(0).g & 0xFE ) << 21 ) | ( ( get_end_point_h(0).g & 0xFE ) << 28 ); block.y = ( ( get_end_point_h(0).g & 0xFE ) >> 4 ) | ( ( get_end_point_l(0).b & 0xFE ) << 3 ) | ( ( get_end_point_h(0).b & 0xFE ) << 10 ) | ( get_end_point_l(0).a << 18 ) | ( get_end_point_h(0).a << 26 ); block.z = ( get_end_point_h(0).a >> 6 ) | ( get_color_index(0) << 2 ) | ( get_color_index(1) << 3 ) | ( get_color_index(2) << 5 ) | ( get_color_index(3) << 7 ) | ( get_color_index(4) << 9 ) | ( get_color_index(5) << 11 ) | ( get_color_index(6) << 13 ) | ( get_color_index(7) << 15 ) | ( get_color_index(8) << 17 ) | ( get_color_index(9) << 19 ) | ( get_color_index(10)<< 21 ) | ( get_color_index(11)<< 23 ) | ( get_color_index(12)<< 25 ) | ( get_color_index(13)<< 27 ) | ( get_color_index(14)<< 29 ) | ( get_color_index(15)<< 31 ); block.w = ( get_color_index(15)>> 1 ) | ( get_alpha_index(0) << 1 ) | ( get_alpha_index(1) << 2 ) | ( get_alpha_index(2) << 4 ) | ( get_alpha_index(3) << 6 ) | ( get_alpha_index(4) << 8 ) | ( get_alpha_index(5) << 10 ) | ( get_alpha_index(6) << 12 ) | ( get_alpha_index(7) << 14 ) | ( get_alpha_index(8) << 16 ) | ( get_alpha_index(9) << 18 ) | ( get_alpha_index(10)<< 20 ) | ( get_alpha_index(11)<< 22 ) | ( get_alpha_index(12)<< 24 ) | ( get_alpha_index(13)<< 26 ) | ( get_alpha_index(14)<< 28 ) | ( get_alpha_index(15)<< 30 ); } void block_package6( out uint4 block, uint threadBase ) { block.x = 0x40 | ( ( get_end_point_l(0).r & 0xFE ) << 6 ) | ( ( get_end_point_h(0).r & 0xFE ) << 13 ) | ( ( get_end_point_l(0).g & 0xFE ) << 20 ) | ( ( get_end_point_h(0).g & 0xFE ) << 27 ); block.y = ( ( get_end_point_h(0).g & 0xFE ) >> 5 ) | ( ( get_end_point_l(0).b & 0xFE ) << 2 ) | ( ( get_end_point_h(0).b & 0xFE ) << 9 ) | ( ( get_end_point_l(0).a & 0xFE ) << 16 ) | ( ( get_end_point_h(0).a & 0xFE ) << 23 ) | ( get_end_point_l(0).r & 0x01 ) << 31; block.z = ( get_end_point_h(0).r & 0x01 ) | ( get_color_index(0) << 1 ) | ( get_color_index(1) << 4 ) | ( get_color_index(2) << 8 ) | ( get_color_index(3) << 12 ) | ( get_color_index(4) << 16 ) | ( get_color_index(5) << 20 ) | ( get_color_index(6) << 24 ) | ( get_color_index(7) << 28 ); block.w = ( get_color_index(8) << 0 ) | ( get_color_index(9) << 4 ) | ( get_color_index(10)<< 8 ) | ( get_color_index(11)<< 12 ) | ( get_color_index(12)<< 16 ) | ( get_color_index(13)<< 20 ) | ( get_color_index(14)<< 24 ) | ( get_color_index(15)<< 28 ); } void block_package7( out uint4 block, uint partition, uint threadBase ) { block.x = 0x80 | ( partition << 8 ) | ( ( get_end_point_l(0).r & 0xF8 ) << 11 ) | ( ( get_end_point_h(0).r & 0xF8 ) << 16 ) | ( ( get_end_point_l(1).r & 0xF8 ) << 21 ) | ( ( get_end_point_h(1).r & 0xF8 ) << 26 ); block.y = ( ( get_end_point_h(1).r & 0xF8 ) >> 6 ) | ( ( get_end_point_l(0).g & 0xF8 ) >> 1 ) | ( ( get_end_point_h(0).g & 0xF8 ) << 4 ) | ( ( get_end_point_l(1).g & 0xF8 ) << 9 ) | ( ( get_end_point_h(1).g & 0xF8 ) << 14 ) | ( ( get_end_point_l(0).b & 0xF8 ) << 19 ) | ( ( get_end_point_h(0).b & 0xF8 ) << 24 ); block.z = ( ( get_end_point_l(1).b & 0xF8 ) >> 3 ) | ( ( get_end_point_h(1).b & 0xF8 ) << 2 ) | ( ( get_end_point_l(0).a & 0xF8 ) << 7 ) | ( ( get_end_point_h(0).a & 0xF8 ) << 12 ) | ( ( get_end_point_l(1).a & 0xF8 ) << 17 ) | ( ( get_end_point_h(1).a & 0xF8 ) << 22 ) | ( ( get_end_point_l(0).r & 0x04 ) << 28 ) | ( ( get_end_point_h(0).r & 0x04 ) << 29 ); block.w = ( ( get_end_point_l(1).r & 0x04 ) >> 2 ) | ( ( get_end_point_h(1).r & 0x04 ) >> 1 ) | ( get_color_index(0) << 2 ); uint i = 1; for ( ; i <= candidateFixUpIndex1DOrdered[partition][0]; i ++ ) { block.w |= get_color_index(i) << ( i * 2 + 1 ); } for ( ; i < 16; i ++ ) { block.w |= get_color_index(i) << ( i * 2 ); } } ================================================ FILE: 3rdParty/DirectXTex/DirectXTex/Shaders/CompileShaders.cmd ================================================ @echo off rem THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF rem ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO rem THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A rem PARTICULAR PURPOSE. rem rem Copyright (c) Microsoft Corporation. All rights reserved. setlocal set error=0 call :CompileShader BC7Encode TryMode456CS call :CompileShader BC7Encode TryMode137CS call :CompileShader BC7Encode TryMode02CS call :CompileShader BC7Encode EncodeBlockCS call :CompileShader BC6HEncode TryModeG10CS call :CompileShader BC6HEncode TryModeLE10CS call :CompileShader BC6HEncode EncodeBlockCS echo. if %error% == 0 ( echo Shaders compiled ok ) else ( echo There were shader compilation errors! ) endlocal exit /b :CompileShader set fxc=fxc /nologo %1.hlsl /Tcs_4_0 /Zpc /Qstrip_reflect /Qstrip_debug /E%2 /FhCompiled\%1_%2.inc /Vn%1_%2 echo. echo %fxc% %fxc% || set error=1 exit /b ================================================ FILE: 3rdParty/DirectXTex/DirectXTex/Shaders/Compiled/BC6HEncode_EncodeBlockCS.inc ================================================ #if 0 // // Generated by Microsoft (R) D3D Shader Disassembler // // /// // Input signature: // // Name Index Mask Register SysValue Format Used // -------------------- ----- ------ -------- -------- ------- ------ // no Input // // Output signature: // // Name Index Mask Register SysValue Format Used // -------------------- ----- ------ -------- -------- ------- ------ // no Output cs_4_0 dcl_globalFlags refactoringAllowed dcl_immediateConstantBuffer { { 0x0000cccc, 15, 0, 0}, { 0x00008888, 15, 0, 0}, { 0x0000eeee, 15, 0, 0}, { 0x0000ecc8, 15, 1, 0}, { 0x0000c880, 15, 1, 0}, { 0x0000feec, 15, 1, 1}, { 0x0000fec8, 15, 1, 1}, { 0x0000ec80, 15, 2, 1}, { 0x0000c800, 15, 2, 1}, { 0x0000ffec, 15, 2, 1}, { 0x0000fe80, 15, 2, 1}, { 0x0000e800, 15, 2, 1}, { 0x0000ffe8, 15, 3, 1}, { 0x0000ff00, 15, 3, 1}, { 0x0000fff0, 15, 3, 2}, { 0x0000f000, 15, 3, 2}, { 0x0000f710, 15, 4, 2}, { 142, 2, 4, 2}, { 0x00007100, 8, 4, 2}, { 2254, 2, 4, 2}, { 140, 2, 5, 2}, { 0x00007310, 8, 5, 2}, { 0x00003100, 8, 5, 2}, { 0x00008cce, 15, 5, 3}, { 2188, 2, 6, 3}, { 0x00003110, 8, 6, 3}, { 0x00006666, 2, 6, 3}, { 0x0000366c, 2, 6, 3}, { 6120, 8, 6, 3}, { 4080, 8, 7, 3}, { 0x0000718e, 2, 7, 3}, { 0x0000399c, 2, 7, 3}, { -1, 0, 7, 3}, { -1, 0, 8, 4}, { -1, 0, 8, 4}, { -1, 0, 8, 4}, { -1, 0, 8, 4}, { -1, 0, 9, 4}, { -1, 0, 9, 4}, { -1, 0, 9, 4}, { -1, 0, 9, 4}, { 0, 0, 10, 4}, { 0, 0, 10, 5}, { -1, 0, 10, 5}, { -1, 0, 10, 5}, { -1, 0, 10, 5}, { 0, 0, 11, 5}, { 0, 0, 11, 5}, { 0, 0, 11, 5}, { 0, 0, 11, 5}, { 0, 0, 12, 5}, { 0, 0, 12, 6}, { 0, 0, 12, 6}, { 0, 0, 12, 6}, { 0, 0, 13, 6}, { 0, 0, 13, 6}, { 0, 0, 13, 6}, { 0, 0, 13, 6}, { 0, 0, 14, 6}, { 0, 0, 14, 6}, { 0, 0, 14, 7}, { 0, 0, 14, 7}, { 0, 0, 15, 7}, { 0, 0, 15, 7}, { 10, 5, 5, 5}, { 7, 6, 6, 6}, { 11, 5, 4, 4}, { 11, 4, 5, 4}, { 11, 4, 4, 5}, { 9, 5, 5, 5}, { 8, 6, 5, 5}, { 8, 5, 6, 5}, { 8, 5, 5, 6}, { 6, 6, 6, 6}, { 10, 10, 10, 10}, { 11, 9, 9, 9}, { 12, 8, 8, 8}, { 16, 4, 4, 4} } dcl_constantbuffer cb0[2], immediateIndexed dcl_resource_texture2d (float,float,float,float) t0 dcl_resource_structured t1, 16 dcl_uav_structured u0, 16 dcl_input vThreadIDInGroupFlattened dcl_input vThreadGroupID.x dcl_temps 18 dcl_tgsm_structured g0, 84, 64 dcl_thread_group 64, 1, 1 ushr r0.x, vThreadIDInGroupFlattened.x, l(5) ishl r0.y, vThreadGroupID.x, l(1) iadd r0.y, r0.y, cb0[1].x iadd r0.x, r0.x, r0.y uge r0.y, r0.x, cb0[1].y if_nz r0.y ret endif and r0.y, vThreadIDInGroupFlattened.x, l(32) iadd r0.z, -r0.y, vThreadIDInGroupFlattened.x ult r1.xyzw, r0.zzzz, l(16, 32, 2, 8) if_nz r1.x udiv r0.w, null, r0.x, cb0[0].y imad r2.x, -r0.w, cb0[0].y, r0.x ishl r2.x, r2.x, l(2) ishl r0.w, r0.w, l(2) and r2.y, r0.z, l(3) iadd r2.x, r2.y, r2.x ushr r3.x, r0.z, l(2) iadd r2.y, r0.w, r3.x mov r2.zw, l(0,0,0,0) ld r2.xyzw, r2.xyzw, t0.xyzw dp3 r0.w, r2.xyzx, l(0.212600, 0.715200, 0.072200, 0.000000) store_structured g0.x, vThreadIDInGroupFlattened.x, l(36), r0.w ushr r3.xyz, r2.xyzx, l(16) and r3.xyz, r3.xyzx, l(0x00008000, 0x00008000, 0x00008000, 0) and r4.xyzw, r2.xxyy, l(0x7fffffff, 0x007fffff, 0x7fffffff, 0x007fffff) ult r2.xy, l(0x47ffefff, 0x47ffefff, 0, 0), r4.xzxx ult r5.xy, r4.xzxx, l(0x38800000, 0x38800000, 0, 0) ushr r5.zw, r4.xxxz, l(23) iadd r5.zw, -r5.zzzw, l(0, 0, 113, 113) iadd r4.yw, r4.yyyw, l(0, 0x00800000, 0, 0x00800000) ushr r6.x, r4.y, r5.z ushr r6.y, r4.w, r5.w iadd r4.xy, r4.xzxx, l(0xc8000000, 0xc8000000, 0, 0) movc r4.xy, r5.xyxx, r6.xyxx, r4.xyxx iadd r4.zw, r4.xxxy, l(0, 0, 4095, 4095) ushr r4.xy, r4.xyxx, l(13) and r4.xy, r4.xyxx, l(1, 1, 0, 0) iadd r4.xy, r4.xyxx, r4.zwzz ushr r4.xy, r4.xyxx, l(13) and r4.xy, r4.xyxx, l(0x00007fff, 0x00007fff, 0, 0) movc r2.xy, r2.xyxx, l(0x00007fff,0x00007fff,0,0), r4.xyxx iadd r4.xy, r3.xyxx, r2.xyxx and r2.xy, r2.zzzz, l(0x7fffffff, 0x007fffff, 0, 0) ult r0.w, l(0x47ffefff), r2.x ult r2.z, r2.x, l(0x38800000) ushr r2.w, r2.x, l(23) iadd r2.w, -r2.w, l(113) iadd r2.y, r2.y, l(0x00800000) ushr r2.y, r2.y, r2.w iadd r2.x, r2.x, l(0xc8000000) movc r2.x, r2.z, r2.y, r2.x iadd r2.y, r2.x, l(4095) ushr r2.x, r2.x, l(13) and r2.x, r2.x, l(1) iadd r2.x, r2.x, r2.y ushr r2.x, r2.x, l(13) and r2.x, r2.x, l(0x00007fff) movc r0.w, r0.w, l(0x00007fff), r2.x iadd r4.z, r3.z, r0.w ieq r0.w, cb0[0].z, l(95) ishl r2.xyz, r4.xyzx, l(6) udiv r2.xyz, null, r2.xyzx, l(31, 31, 31, 0) ult r3.xyz, r4.xyzx, l(0x00008000, 0x00008000, 0x00008000, 0) ieq r5.xyz, r4.xyzx, l(0x00007bff, 0x00007bff, 0x00007bff, 0) ishl r4.xyz, r4.xyzx, l(5) udiv r6.xyz, null, r4.xyzx, l(31, 31, 31, 0) movc r6.xyz, r5.xyzx, l(0x00007fff,0x00007fff,0x00007fff,0), r6.xyzx and r4.xyz, r4.xyzx, l(0x000fffe0, 0x000fffe0, 0x000fffe0, 0) udiv r4.xyz, null, r4.xyzx, l(31, 31, 31, 0) ineg r4.xyz, r4.xyzx movc r4.xyz, r5.xyzx, l(0xffff8001,0xffff8001,0xffff8001,0), r4.xyzx movc r3.xyz, r3.xyzx, r6.xyzx, r4.xyzx movc r2.xyz, r0.wwww, r2.xyzx, r3.xyzx store_structured g0.xyz, vThreadIDInGroupFlattened.x, l(12), r2.xyzx endif ld_structured r2.xy, r0.x, l(4), t1.xyxx if_nz r1.y and r0.w, r0.z, l(15) iadd r1.y, r0.w, r0.y ld_structured r3.xyz, r1.y, l(12), g0.xyzx ld_structured r3.w, r1.y, l(36), g0.xxxx if_nz r1.x ult r1.y, l(10), r2.x if_nz r1.y mov r4.xyzw, r3.xyzx mov r5.xyzw, r3.yzww else ushr r1.y, icb[r2.y + 0].x, r0.z and r1.y, r1.y, l(1) movc r4.xyzw, r1.yyyy, l(0x7fffffff,0x7fffffff,0x7fffffff,-0.000000), r3.xyzx movc r5.xyzw, r1.yyyy, l(-0.000000,-0.000000,340282346638528860000000000000000000000.000000,-340282346638528860000000000000000000000.000000), r3.yzww endif else uge r1.y, l(10), r2.x if_nz r1.y ushr r0.w, icb[r2.y + 0].x, r0.w and r0.w, r0.w, l(1) ieq r0.w, r0.w, l(1) movc r4.xyzw, r0.wwww, r3.xyzx, l(0x7fffffff,0x7fffffff,0x7fffffff,-0.000000) movc r5.xyzw, r0.wwww, r3.yzww, l(-0.000000,-0.000000,340282346638528860000000000000000000000.000000,-340282346638528860000000000000000000000.000000) else mov r4.xyzw, l(0x7fffffff,0x7fffffff,0x7fffffff,-0.000000) mov r5.xyzw, l(-0.000000,-0.000000,340282346638528860000000000000000000000.000000,-340282346638528860000000000000000000000.000000) endif endif store_structured g0.xyzw, vThreadIDInGroupFlattened.x, l(52), r4.xyzw store_structured g0.xyzw, vThreadIDInGroupFlattened.x, l(68), r5.xyzw endif and r0.w, r0.z, l(15) ult r3.xyzw, r0.wwww, l(8, 4, 2, 1) if_nz r3.x ld_structured r4.x, vThreadIDInGroupFlattened.x, l(76), g0.xxxx iadd r0.w, vThreadIDInGroupFlattened.x, l(8) ld_structured r5.x, r0.w, l(76), g0.xxxx lt r1.y, r5.x, r4.x if_nz r1.y ld_structured r4.xyz, r0.w, l(52), g0.xyzx store_structured g0.xyz, vThreadIDInGroupFlattened.x, l(52), r4.xyzx store_structured g0.x, vThreadIDInGroupFlattened.x, l(76), r5.x endif ld_structured r4.x, vThreadIDInGroupFlattened.x, l(80), g0.xxxx ld_structured r5.x, r0.w, l(80), g0.xxxx lt r1.y, r4.x, r5.x if_nz r1.y ld_structured r4.xyz, r0.w, l(64), g0.xyzx store_structured g0.xyz, vThreadIDInGroupFlattened.x, l(64), r4.xyzx store_structured g0.x, vThreadIDInGroupFlattened.x, l(80), r5.x endif endif if_nz r3.y ld_structured r4.x, vThreadIDInGroupFlattened.x, l(76), g0.xxxx iadd r0.w, vThreadIDInGroupFlattened.x, l(4) ld_structured r5.x, r0.w, l(76), g0.xxxx lt r1.y, r5.x, r4.x if_nz r1.y ld_structured r4.xyz, r0.w, l(52), g0.xyzx store_structured g0.xyz, vThreadIDInGroupFlattened.x, l(52), r4.xyzx store_structured g0.x, vThreadIDInGroupFlattened.x, l(76), r5.x endif ld_structured r4.x, vThreadIDInGroupFlattened.x, l(80), g0.xxxx ld_structured r5.x, r0.w, l(80), g0.xxxx lt r1.y, r4.x, r5.x if_nz r1.y ld_structured r4.xyz, r0.w, l(64), g0.xyzx store_structured g0.xyz, vThreadIDInGroupFlattened.x, l(64), r4.xyzx store_structured g0.x, vThreadIDInGroupFlattened.x, l(80), r5.x endif endif if_nz r3.z ld_structured r4.x, vThreadIDInGroupFlattened.x, l(76), g0.xxxx iadd r0.w, vThreadIDInGroupFlattened.x, l(2) ld_structured r5.x, r0.w, l(76), g0.xxxx lt r1.y, r5.x, r4.x if_nz r1.y ld_structured r4.xyz, r0.w, l(52), g0.xyzx store_structured g0.xyz, vThreadIDInGroupFlattened.x, l(52), r4.xyzx store_structured g0.x, vThreadIDInGroupFlattened.x, l(76), r5.x endif ld_structured r4.x, vThreadIDInGroupFlattened.x, l(80), g0.xxxx ld_structured r5.x, r0.w, l(80), g0.xxxx lt r1.y, r4.x, r5.x if_nz r1.y ld_structured r4.xyz, r0.w, l(64), g0.xyzx store_structured g0.xyz, vThreadIDInGroupFlattened.x, l(64), r4.xyzx store_structured g0.x, vThreadIDInGroupFlattened.x, l(80), r5.x endif endif if_nz r3.w ld_structured r3.x, vThreadIDInGroupFlattened.x, l(76), g0.xxxx iadd r0.w, vThreadIDInGroupFlattened.x, l(1) ld_structured r4.x, r0.w, l(76), g0.xxxx lt r1.y, r4.x, r3.x if_nz r1.y ld_structured r3.xyz, r0.w, l(52), g0.xyzx store_structured g0.xyz, vThreadIDInGroupFlattened.x, l(52), r3.xyzx endif ld_structured r3.x, vThreadIDInGroupFlattened.x, l(80), g0.xxxx ld_structured r4.x, r0.w, l(80), g0.xxxx lt r1.y, r3.x, r4.x if_nz r1.y ld_structured r3.xyz, r0.w, l(64), g0.xyzx store_structured g0.xyz, vThreadIDInGroupFlattened.x, l(64), r3.xyzx endif endif if_nz r1.z ishl r0.w, r0.z, l(4) iadd r0.w, r0.w, r0.y ld_structured r3.xyz, r0.w, l(52), g0.xyzx ld_structured r4.xyz, r0.w, l(64), g0.xyzx ieq r0.w, r0.z, l(1) uge r1.y, l(10), r2.x and r0.w, r0.w, r1.y if_nz r0.w mov r0.w, icb[r2.y + 0].y else mov r0.w, l(0) endif iadd r5.xyz, -r3.xyzx, r4.xyzx itof r5.xyz, r5.xyzx dp3 r1.y, r5.xyzx, r5.xyzx iadd r0.w, r0.w, r0.y ld_structured r6.xyz, r0.w, l(12), g0.xyzx iadd r6.xyz, -r3.xyzx, r6.xyzx itof r6.xyz, r6.xyzx dp3 r0.w, r5.xyzx, r6.xyzx lt r2.z, l(0.000000), r1.y ge r2.w, r0.w, l(0.000000) and r2.z, r2.w, r2.z mul r0.w, r0.w, l(63.499989) div r0.w, r0.w, r1.y ftou r0.w, r0.w ult r0.w, l(32), r0.w and r0.w, r0.w, r2.z mov r4.w, r3.x mov r3.w, r4.x movc r5.xyzw, r0.wwww, r4.xyzw, r3.xyzw movc r2.zw, r0.wwww, r3.yyyz, r4.yyyz store_structured g0.xyzw, vThreadIDInGroupFlattened.x, l(52), r5.xyzw store_structured g0.xy, vThreadIDInGroupFlattened.x, l(68), r2.zwzz endif if_nz r1.x ult r0.w, l(10), r2.x if_nz r0.w mov r1.x, l(0) else mov r1.x, icb[r2.y + 0].x endif ushr r1.x, r1.x, r0.z and r1.x, r1.x, l(1) if_nz r1.x iadd r1.x, r0.y, l(1) ld_structured r3.xyz, r1.x, l(64), g0.xyzx ld_structured r4.xyz, r1.x, l(52), g0.xyzx iadd r3.xyz, r3.xyzx, -r4.xyzx itof r3.xyz, r3.xyzx ld_structured r5.xyz, vThreadIDInGroupFlattened.x, l(12), g0.xyzx iadd r4.xyz, -r4.xyzx, r5.xyzx itof r4.xyz, r4.xyzx dp3 r1.x, r3.xyzx, r4.xyzx else ld_structured r4.xyz, r0.y, l(64), g0.xyzx ld_structured r5.xyz, r0.y, l(52), g0.xyzx iadd r4.xyz, r4.xyzx, -r5.xyzx itof r3.xyz, r4.xyzx ld_structured r4.xyz, vThreadIDInGroupFlattened.x, l(12), g0.xyzx iadd r4.xyz, -r5.xyzx, r4.xyzx itof r4.xyz, r4.xyzx dp3 r1.x, r3.xyzx, r4.xyzx endif dp3 r1.y, r3.xyzx, r3.xyzx if_nz r0.w ge r0.w, l(0.000000), r1.y ge r2.z, l(0.000000), r1.x or r0.w, r0.w, r2.z lt r2.z, r1.x, r1.y mul r2.w, r1.x, l(63.499989) div r2.w, r2.w, r1.y ftou r2.w, r2.w movc r2.z, r2.z, icb[r2.w + 0].z, l(15) movc r0.w, r0.w, l(0), r2.z ishl r3.x, r0.w, l(1) ult r2.z, r0.z, l(8) ishl r2.w, r0.z, l(2) ishl r4.x, r0.w, r2.w iadd r2.w, r2.w, l(-32) ishl r4.w, r0.w, r2.w mov r4.yz, l(0,0,0,0) movc r2.zw, r2.zzzz, r4.xxxy, r4.zzzw mov r3.y, l(0) movc r3.xy, r0.zzzz, r2.zwzz, r3.xyxx else ge r0.w, l(0.000000), r1.y ge r2.z, l(0.000000), r1.x or r0.w, r0.w, r2.z lt r2.z, r1.x, r1.y mul r1.x, r1.x, l(63.499989) div r1.x, r1.x, r1.y ftou r1.x, r1.x movc r1.x, r2.z, icb[r1.x + 0].w, l(7) movc r0.w, r0.w, l(0), r1.x if_z r0.z ishl r3.x, r0.w, l(18) mov r3.y, l(0) else ult r1.x, r0.z, l(3) if_nz r1.x imad r1.x, r0.z, l(3), l(17) ishl r3.x, r0.w, r1.x mov r3.y, l(0) else ine r1.x, l(2), icb[r2.y + 0].y ieq r1.y, l(15), icb[r2.y + 0].y and r2.zw, r1.xxxy, l(0, 0, 1, 1) ult r1.y, r0.z, l(5) if_nz r1.y imad r1.y, r0.z, l(3), r2.z iadd r1.y, r1.y, l(16) ishl r3.x, r0.w, r1.y mov r3.y, l(0) else ieq r1.y, r0.z, l(5) movc r4.x, r1.x, l(0), l(1) ushr r4.y, r0.w, r4.x ishl r4.z, r0.w, l(31) movc r4.x, r1.x, l(0), r4.z ult r1.x, r0.z, l(9) imad r2.zw, r0.zzzz, l(0, 0, 3, 3), r2.zzzw iadd r2.zw, r2.zzzw, l(0, 0, -16, -16) ishl r2.z, r0.w, r2.z ishl r0.w, r0.w, r2.w movc r5.y, r1.x, r2.z, r0.w mov r5.x, l(0) movc r3.xy, r1.yyyy, r4.xyxx, r5.xyxx endif endif endif endif store_structured g0.xy, vThreadIDInGroupFlattened.x, l(24), r3.xyxx else mov r3.xy, l(0,0,0,0) endif if_nz r1.w ld_structured r4.xy, vThreadIDInGroupFlattened.x, l(24), g0.xyxx iadd r0.w, vThreadIDInGroupFlattened.x, l(8) ld_structured r5.xy, r0.w, l(24), g0.xyxx or r1.xy, r4.xyxx, r5.xyxx store_structured g0.xy, vThreadIDInGroupFlattened.x, l(24), r1.xyxx endif ult r1.xy, r0.zzzz, l(4, 1, 0, 0) if_nz r1.x ld_structured r4.xy, vThreadIDInGroupFlattened.x, l(24), g0.xyxx iadd r0.w, vThreadIDInGroupFlattened.x, l(4) ld_structured r5.xy, r0.w, l(24), g0.xyxx or r1.xw, r4.xxxy, r5.xxxy store_structured g0.xy, vThreadIDInGroupFlattened.x, l(24), r1.xwxx endif if_nz r1.z ld_structured r4.xy, vThreadIDInGroupFlattened.x, l(24), g0.xyxx iadd r0.w, vThreadIDInGroupFlattened.x, l(2) ld_structured r5.xy, r0.w, l(24), g0.xyxx or r1.xw, r4.xxxy, r5.xxxy store_structured g0.xy, vThreadIDInGroupFlattened.x, l(24), r1.xwxx endif if_nz r1.y ld_structured r4.xy, vThreadIDInGroupFlattened.x, l(24), g0.xyxx iadd r0.w, vThreadIDInGroupFlattened.x, l(1) ld_structured r5.xy, r0.w, l(24), g0.xyxx or r3.xy, r4.xyxx, r5.xyxx endif iadd r0.w, r2.x, l(-1) ieq r1.xy, r0.zzzz, l(2, 3, 0, 0) if_nz r1.x ld_structured r4.xyz, r0.y, l(52), g0.xyzx ld_structured r5.xyz, r0.y, l(64), g0.xyzx ieq r1.x, cb0[0].z, l(95) if_nz r1.x ige r1.x, icb[r0.w + 64].x, l(15) and r1.x, r1.x, l(1) movc r6.xyz, r4.xyzx, l(0,0,0,0), l(1,1,1,0) movc r7.xyz, r5.xyzx, l(0,0,0,0), l(1,1,1,0) or r6.xyz, r1.xxxx, r6.xyzx or r7.xyz, r1.xxxx, r7.xyzx ieq r8.xyz, r4.xyzx, l(0x0000ffff, 0x0000ffff, 0x0000ffff, 0) ieq r9.xyz, r5.xyzx, l(0x0000ffff, 0x0000ffff, 0x0000ffff, 0) ishl r1.x, l(1), icb[r0.w + 64].x iadd r1.x, r1.x, l(-1) ishl r10.xyz, r4.xyzx, icb[r0.w + 64].x ishl r11.xyz, r5.xyzx, icb[r0.w + 64].x ishr r10.xyz, r10.xyzx, l(16) ishr r11.xyz, r11.xyzx, l(16) movc r8.xyz, r8.xyzx, r1.xxxx, r10.xyzx movc r9.xyz, r9.xyzx, r1.xxxx, r11.xyzx movc r6.xyz, r6.xyzx, r4.xyzx, r8.xyzx movc r7.xyz, r7.xyzx, r5.xyzx, r9.xyzx else ige r1.x, icb[r0.w + 64].x, l(16) and r1.x, r1.x, l(1) movc r8.xyz, r4.xyzx, l(0,0,0,0), l(1,1,1,0) movc r9.xyz, r5.xyzx, l(0,0,0,0), l(1,1,1,0) or r8.xyz, r1.xxxx, r8.xyzx or r9.xyz, r1.xxxx, r9.xyzx ige r10.xyz, r4.xyzx, l(0, 0, 0, 0) ige r11.xyz, r5.xyzx, l(0, 0, 0, 0) ieq r12.xyz, r4.xyzx, l(0x00007fff, 0x00007fff, 0x00007fff, 0) ieq r13.xyz, r5.xyzx, l(0x00007fff, 0x00007fff, 0x00007fff, 0) iadd r1.x, l(-1), icb[r0.w + 64].x ishl r1.w, l(1), r1.x iadd r2.z, r1.w, l(-1) ishl r14.xyz, r4.xyzx, r1.x ishl r15.xyz, r5.xyzx, r1.x ishr r14.xyz, r14.xyzx, l(15) ishr r15.xyz, r15.xyzx, l(15) movc r12.xyz, r12.xyzx, r2.zzzz, r14.xyzx movc r13.xyz, r13.xyzx, r2.zzzz, r15.xyzx ineg r14.xyz, r4.xyzx ineg r15.xyz, r5.xyzx ieq r16.xyz, r14.xyzx, l(0x00007fff, 0x00007fff, 0x00007fff, 0) ieq r17.xyz, r15.xyzx, l(0x00007fff, 0x00007fff, 0x00007fff, 0) iadd r1.w, -r1.w, l(1) ishl r14.xyz, r14.xyzx, r1.x ishl r15.xyz, r15.xyzx, r1.x ishr r14.xyz, r14.xyzx, l(15) ishr r15.xyz, r15.xyzx, l(15) ineg r14.xyz, r14.xyzx ineg r15.xyz, r15.xyzx movc r14.xyz, r16.xyzx, r1.wwww, r14.xyzx movc r15.xyz, r17.xyzx, r1.wwww, r15.xyzx movc r10.xyz, r10.xyzx, r12.xyzx, r14.xyzx movc r11.xyz, r11.xyzx, r13.xyzx, r15.xyzx movc r6.xyz, r8.xyzx, r4.xyzx, r10.xyzx movc r7.xyz, r9.xyzx, r5.xyzx, r11.xyzx endif iadd r4.xyz, -r6.xyzx, r7.xyzx movc r4.xyz, icb[r0.w + 32].xxxx, r4.xyzx, r7.xyzx mov r6.w, r4.x store_structured g0.xyzw, vThreadIDInGroupFlattened.x, l(52), r6.xyzw store_structured g0.xy, vThreadIDInGroupFlattened.x, l(68), r4.yzyy endif if_nz r1.y iadd r1.xy, r0.yyyy, l(2, 1, 0, 0) ld_structured r4.xyz, r1.x, l(52), g0.xyzx ld_structured r5.xyz, r1.y, l(52), g0.xyzx ld_structured r6.xyz, r1.y, l(64), g0.xyzx uge r1.x, l(10), r2.x if_nz r1.x ieq r1.x, cb0[0].z, l(95) if_nz r1.x ige r1.x, icb[r0.w + 64].x, l(15) and r1.x, r1.x, l(1) movc r7.xyz, r5.xyzx, l(0,0,0,0), l(1,1,1,0) movc r8.xyz, r6.xyzx, l(0,0,0,0), l(1,1,1,0) or r7.xyz, r1.xxxx, r7.xyzx or r1.xyw, r1.xxxx, r8.xyxz ieq r8.xyz, r5.xyzx, l(0x0000ffff, 0x0000ffff, 0x0000ffff, 0) ieq r9.xyz, r6.xyzx, l(0x0000ffff, 0x0000ffff, 0x0000ffff, 0) ishl r2.z, l(1), icb[r0.w + 64].x iadd r2.z, r2.z, l(-1) ishl r10.xyz, r5.xyzx, icb[r0.w + 64].x ishl r11.xyz, r6.xyzx, icb[r0.w + 64].x ishr r10.xyz, r10.xyzx, l(16) ishr r11.xyz, r11.xyzx, l(16) movc r8.xyz, r8.xyzx, r2.zzzz, r10.xyzx movc r9.xyz, r9.xyzx, r2.zzzz, r11.xyzx movc r7.xyz, r7.xyzx, r5.xyzx, r8.xyzx movc r1.xyw, r1.xyxw, r6.xyxz, r9.xyxz else ige r2.z, icb[r0.w + 64].x, l(16) and r2.z, r2.z, l(1) movc r8.xyz, r5.xyzx, l(0,0,0,0), l(1,1,1,0) movc r9.xyz, r6.xyzx, l(0,0,0,0), l(1,1,1,0) or r8.xyz, r2.zzzz, r8.xyzx or r9.xyz, r2.zzzz, r9.xyzx ige r10.xyz, r5.xyzx, l(0, 0, 0, 0) ige r11.xyz, r6.xyzx, l(0, 0, 0, 0) ieq r12.xyz, r5.xyzx, l(0x00007fff, 0x00007fff, 0x00007fff, 0) ieq r13.xyz, r6.xyzx, l(0x00007fff, 0x00007fff, 0x00007fff, 0) iadd r2.z, l(-1), icb[r0.w + 64].x ishl r2.w, l(1), r2.z iadd r4.w, r2.w, l(-1) ishl r14.xyz, r5.xyzx, r2.z ishl r15.xyz, r6.xyzx, r2.z ishr r14.xyz, r14.xyzx, l(15) ishr r15.xyz, r15.xyzx, l(15) movc r12.xyz, r12.xyzx, r4.wwww, r14.xyzx movc r13.xyz, r13.xyzx, r4.wwww, r15.xyzx ineg r14.xyz, r5.xyzx ineg r15.xyz, r6.xyzx ieq r16.xyz, r14.xyzx, l(0x00007fff, 0x00007fff, 0x00007fff, 0) ieq r17.xyz, r15.xyzx, l(0x00007fff, 0x00007fff, 0x00007fff, 0) iadd r2.w, -r2.w, l(1) ishl r14.xyz, r14.xyzx, r2.z ishl r15.xyz, r15.xyzx, r2.z ishr r14.xyz, r14.xyzx, l(15) ishr r15.xyz, r15.xyzx, l(15) ineg r14.xyz, r14.xyzx ineg r15.xyz, r15.xyzx movc r14.xyz, r16.xyzx, r2.wwww, r14.xyzx movc r15.xyz, r17.xyzx, r2.wwww, r15.xyzx movc r10.xyz, r10.xyzx, r12.xyzx, r14.xyzx movc r11.xyz, r11.xyzx, r13.xyzx, r15.xyzx movc r7.xyz, r8.xyzx, r5.xyzx, r10.xyzx movc r1.xyw, r9.xyxz, r6.xyxz, r11.xyxz endif iadd r5.xyz, -r4.xyzx, r7.xyzx iadd r4.xyz, -r4.xyzx, r1.xywx mov r5.w, r4.x mov r7.w, r1.x movc r5.xyzw, icb[r0.w + 32].xxxx, r5.xyzw, r7.xyzw movc r1.xy, icb[r0.w + 32].xxxx, r4.yzyy, r1.ywyy store_structured g0.xyzw, vThreadIDInGroupFlattened.x, l(52), r5.xyzw store_structured g0.xy, vThreadIDInGroupFlattened.x, l(68), r1.xyxx endif endif if_nz r1.z iadd r1.x, vThreadIDInGroupFlattened.x, l(2) ld_structured r4.xyz, r1.x, l(52), g0.xyzx ld_structured r1.xyz, r1.x, l(64), g0.yzxx if_z r0.z ult r1.w, l(10), r2.x if_nz r1.w ishl r5.x, l(1), icb[r0.w + 64].x ishl r5.y, l(1), icb[r0.w + 64].y ishl r5.z, l(1), icb[r0.w + 64].z ishl r5.w, l(1), icb[r0.w + 64].w ige r6.xyz, r1.zxyz, l(0, 0, 0, 0) iadd r7.xyz, l(-1, -1, -1, 0), icb[r0.w + 64].yzwy ishl r8.x, l(1), r7.x ishl r8.y, l(1), r7.y ishl r8.z, l(1), r7.z ige r7.xyz, r1.zxyz, r8.xyzx iadd r9.xyz, r8.xyzx, l(-1, -1, -1, 0) movc r7.xyz, r7.xyzx, r9.xyzx, r1.zxyz ineg r9.xyz, r1.zxyz ilt r9.xyz, r8.xyzx, r9.xyzx iadd r5.xyzw, r5.xyzw, l(-1, -1, -1, -1) and r5.yzw, r1.zzxy, r5.yyzw movc r5.yzw, r9.xxyz, r8.xxyz, r5.yyzw movc r5.yzw, r6.xxyz, r7.xxyz, r5.yyzw mov r4.w, r1.z and r6.xyzw, r4.xyzw, r5.xxxx and r2.zw, r1.xxxy, r5.xxxx mov r7.xyz, r6.xyzx mov r7.w, r5.y movc r4.xyzw, icb[r0.w + 32].xxxx, r7.xyzw, r6.xyzw movc r1.xy, icb[r0.w + 32].xxxx, r5.zwzz, r2.zwzz else if_nz icb[r0.w + 32].x ishl r5.x, l(1), icb[r0.w + 64].x ishl r5.y, l(1), icb[r0.w + 64].y ishl r5.z, l(1), icb[r0.w + 64].z ishl r5.w, l(1), icb[r0.w + 64].w iadd r5.xyzw, r5.xyzw, l(-1, -1, -1, -1) and r4.xyz, r4.xyzx, r5.xxxx ige r6.xyz, r1.zxyz, l(0, 0, 0, 0) iadd r7.xyz, l(-1, -1, -1, 0), icb[r0.w + 64].yzwy ishl r8.x, l(1), r7.x ishl r8.y, l(1), r7.y ishl r8.z, l(1), r7.z ige r7.xyz, r1.zxyz, r8.xyzx iadd r9.xyz, r8.xyzx, l(-1, -1, -1, 0) movc r7.xyz, r7.xyzx, r9.xyzx, r1.zxyz ineg r9.xyz, r1.zxyz ilt r9.xyz, r8.xyzx, r9.xyzx and r5.xyz, r1.zxyz, r5.yzwy movc r5.xyz, r9.xyzx, r8.xyzx, r5.xyzx movc r1.xyz, r6.yzxy, r7.yzxy, r5.yzxy mov r4.w, r1.z else ishl r1.w, l(1), icb[r0.w + 64].x iadd r1.w, r1.w, l(-1) mov r4.w, r1.z and r4.xyzw, r1.wwww, r4.xyzw and r1.xy, r1.wwww, r1.xyxx endif endif else uge r1.w, l(10), r2.x if_nz r1.w if_nz icb[r0.w + 32].x ige r5.xyz, r4.xyzx, l(0, 0, 0, 0) iadd r6.xyz, l(-1, -1, -1, 0), icb[r0.w + 64].yzwy ishl r7.x, l(1), r6.x ishl r7.y, l(1), r6.y ishl r7.z, l(1), r6.z ige r6.xyz, r4.xyzx, r7.xyzx iadd r8.xyz, r7.xyzx, l(-1, -1, -1, 0) movc r6.xyz, r6.xyzx, r8.xyzx, r4.xyzx ineg r9.xyz, r4.xyzx ilt r9.xyz, r7.xyzx, r9.xyzx ishl r10.x, l(1), icb[r0.w + 64].y ishl r10.y, l(1), icb[r0.w + 64].z ishl r10.z, l(1), icb[r0.w + 64].w iadd r10.xyz, r10.xyzx, l(-1, -1, -1, 0) and r11.xyz, r4.xyzx, r10.xyzx movc r9.xyz, r9.xyzx, r7.xyzx, r11.xyzx movc r4.xyz, r5.xyzx, r6.xyzx, r9.xyzx ige r5.xyz, r1.zxyz, l(0, 0, 0, 0) ige r6.xyz, r1.zxyz, r7.xyzx movc r6.xyz, r6.xyzx, r8.xyzx, r1.zxyz ineg r8.xyz, r1.zxyz ilt r8.xyz, r7.xyzx, r8.xyzx and r9.xyz, r1.zxyz, r10.xyzx movc r7.xyz, r8.xyzx, r7.xyzx, r9.xyzx movc r1.xyz, r5.yzxy, r6.yzxy, r7.yzxy mov r4.w, r1.z else ishl r0.w, l(1), icb[r0.w + 64].x iadd r0.w, r0.w, l(-1) mov r4.w, r1.z and r4.xyzw, r0.wwww, r4.xyzw and r1.xy, r0.wwww, r1.xyxx endif else mov r4.w, r1.z endif endif store_structured g0.xyzw, vThreadIDInGroupFlattened.x, l(52), r4.xyzw store_structured g0.xy, vThreadIDInGroupFlattened.x, l(68), r1.xyxx endif if_z r0.z ld_structured r1.xyzw, r0.y, l(52), g0.xyzw ld_structured r4.xy, r0.y, l(68), g0.xyxx ult r0.z, l(10), r2.x if_nz r0.z and r3.w, r3.x, l(-2) ieq r0.z, r2.x, l(11) if_nz r0.z ishl r5.x, r1.x, l(5) ishl r5.y, r1.y, l(15) ishl r5.z, r1.z, l(25) ishl r5.w, r1.w, l(3) and r5.xyzw, r5.xyzw, l(32, 0x00008000, 0x02000000, 8) iadd r0.z, r5.x, l(3) ishr r0.w, r1.x, l(1) ishr r2.z, r1.x, l(2) ishr r2.w, r1.x, l(3) ishr r4.z, r1.x, l(4) ishl r6.x, r0.w, l(6) ishl r6.y, r2.z, l(7) ishl r6.z, r2.w, l(8) ishl r6.w, r4.z, l(9) and r6.xyzw, r6.xyzw, l(64, 128, 256, 512) iadd r0.z, r0.z, r6.x iadd r0.z, r6.y, r0.z iadd r0.z, r6.z, r0.z iadd r0.z, r6.w, r0.z ishr r0.w, r1.x, l(5) ishr r2.z, r1.x, l(6) ishr r2.w, r1.x, l(7) ishr r4.z, r1.x, l(8) ishl r6.x, r0.w, l(10) ishl r6.y, r2.z, l(11) ishl r6.z, r2.w, l(12) ishl r6.w, r4.z, l(13) and r6.xyzw, r6.xyzw, l(1024, 2048, 4096, 8192) iadd r0.z, r0.z, r6.x iadd r0.z, r6.y, r0.z iadd r0.z, r6.z, r0.z iadd r0.z, r6.w, r0.z ishr r0.w, r1.x, l(9) ishr r2.z, r1.y, l(1) ishr r2.w, r1.y, l(2) ishr r4.z, r1.y, l(3) ishl r6.x, r0.w, l(14) ishl r6.y, r2.z, l(16) ishl r6.z, r2.w, l(17) ishl r6.w, r4.z, l(18) and r6.xyzw, r6.xyzw, l(0x00004000, 0x00010000, 0x00020000, 0x00040000) iadd r0.z, r0.z, r6.x iadd r0.z, r5.y, r0.z iadd r0.z, r6.y, r0.z iadd r0.z, r6.z, r0.z iadd r0.z, r6.w, r0.z ishr r0.w, r1.y, l(4) ishr r2.z, r1.y, l(5) ishr r2.w, r1.y, l(6) ishr r4.z, r1.y, l(7) ishl r6.x, r0.w, l(19) ishl r6.y, r2.z, l(20) ishl r6.z, r2.w, l(21) ishl r6.w, r4.z, l(22) and r6.xyzw, r6.xyzw, l(0x00080000, 0x00100000, 0x00200000, 0x00400000) iadd r0.z, r0.z, r6.x iadd r0.z, r6.y, r0.z iadd r0.z, r6.z, r0.z iadd r0.z, r6.w, r0.z ishr r0.w, r1.y, l(8) ishr r2.z, r1.y, l(9) ishr r2.w, r1.z, l(1) ishr r4.z, r1.z, l(2) ishl r6.x, r0.w, l(23) ishl r6.y, r2.z, l(24) ishl r6.z, r2.w, l(26) ishl r6.w, r4.z, l(27) and r6.xyzw, r6.xyzw, l(0x00800000, 0x01000000, 0x04000000, 0x08000000) iadd r0.z, r0.z, r6.x iadd r0.z, r6.y, r0.z iadd r0.z, r5.z, r0.z iadd r0.z, r6.z, r0.z iadd r0.z, r6.w, r0.z ishr r0.w, r1.z, l(3) ishr r2.z, r1.z, l(4) ishr r2.w, r1.z, l(5) ishr r4.z, r1.z, l(6) ishl r5.x, r0.w, l(28) ishl r5.y, r2.z, l(29) ishl r5.z, r2.w, l(30) ishl r0.w, r4.z, l(31) and r5.xyz, r5.xyzx, l(0x10000000, 0x20000000, 0x40000000, 0) iadd r0.z, r0.z, r5.x iadd r0.z, r5.y, r0.z iadd r0.z, r5.z, r0.z iadd r3.x, r0.w, r0.z ishr r0.z, r1.z, l(7) ishr r0.w, r1.z, l(8) ishr r2.z, r1.z, l(9) ishr r2.w, r1.w, l(1) and r0.z, r0.z, l(1) ishl r5.x, r0.w, l(1) ishl r5.y, r2.z, l(2) ishl r5.z, r2.w, l(4) and r5.xyz, r5.xyzx, l(2, 4, 16, 0) iadd r0.z, r0.z, r5.x iadd r0.z, r5.y, r0.z iadd r0.z, r5.w, r0.z iadd r0.z, r5.z, r0.z ishr r0.w, r1.w, l(2) ishr r2.z, r1.w, l(3) ishr r2.w, r1.w, l(4) ishr r4.z, r1.w, l(5) ishl r5.x, r0.w, l(5) ishl r5.y, r2.z, l(6) ishl r5.z, r2.w, l(7) ishl r5.w, r4.z, l(8) and r5.xyzw, r5.xyzw, l(32, 64, 128, 256) iadd r0.z, r0.z, r5.x iadd r0.z, r5.y, r0.z iadd r0.z, r5.z, r0.z iadd r0.z, r5.w, r0.z ishr r0.w, r1.w, l(6) ishr r2.z, r1.w, l(7) ishr r2.w, r1.w, l(8) ishr r4.z, r1.w, l(9) ishl r5.x, r0.w, l(9) ishl r5.y, r2.z, l(10) ishl r5.z, r2.w, l(11) ishl r5.w, r4.z, l(12) and r5.xyzw, r5.xyzw, l(512, 1024, 2048, 4096) iadd r0.z, r0.z, r5.x iadd r0.z, r5.y, r0.z iadd r0.z, r5.z, r0.z iadd r0.z, r5.w, r0.z ishl r5.x, r4.x, l(13) ishl r5.y, r4.y, l(23) and r2.zw, r5.xxxy, l(0, 0, 8192, 0x00800000) iadd r0.z, r0.z, r2.z ishr r0.w, r4.x, l(1) ishr r2.z, r4.x, l(2) ishr r4.z, r4.x, l(3) ishr r4.w, r4.x, l(4) ishl r5.x, r0.w, l(14) ishl r5.y, r2.z, l(15) ishl r5.z, r4.z, l(16) ishl r5.w, r4.w, l(17) and r5.xyzw, r5.xyzw, l(0x00004000, 0x00008000, 0x00010000, 0x00020000) iadd r0.z, r0.z, r5.x iadd r0.z, r5.y, r0.z iadd r0.z, r5.z, r0.z iadd r0.z, r5.w, r0.z ishr r0.w, r4.x, l(5) ishr r2.z, r4.x, l(6) ishr r4.z, r4.x, l(7) ishr r4.w, r4.x, l(8) ishl r5.x, r0.w, l(18) ishl r5.y, r2.z, l(19) ishl r5.z, r4.z, l(20) ishl r5.w, r4.w, l(21) and r5.xyzw, r5.xyzw, l(0x00040000, 0x00080000, 0x00100000, 0x00200000) iadd r0.z, r0.z, r5.x iadd r0.z, r5.y, r0.z iadd r0.z, r5.z, r0.z iadd r0.z, r5.w, r0.z ishr r0.w, r4.x, l(9) ishr r2.z, r4.y, l(1) ishr r4.z, r4.y, l(2) ishr r4.w, r4.y, l(3) ishl r5.x, r0.w, l(22) ishl r5.y, r2.z, l(24) ishl r5.z, r4.z, l(25) ishl r5.w, r4.w, l(26) and r5.xyzw, r5.xyzw, l(0x00400000, 0x01000000, 0x02000000, 0x04000000) iadd r0.z, r0.z, r5.x iadd r0.z, r2.w, r0.z iadd r0.z, r5.y, r0.z iadd r0.z, r5.z, r0.z iadd r0.z, r5.w, r0.z ishr r0.w, r4.y, l(4) ishr r2.z, r4.y, l(5) ishr r2.w, r4.y, l(6) ishr r4.z, r4.y, l(7) ishl r5.x, r0.w, l(27) ishl r5.y, r2.z, l(28) ishl r5.z, r2.w, l(29) ishl r5.w, r4.z, l(30) and r5.xyzw, r5.xyzw, l(0x08000000, 0x10000000, 0x20000000, 0x40000000) iadd r0.z, r0.z, r5.x iadd r0.z, r5.y, r0.z iadd r0.z, r5.z, r0.z iadd r0.z, r5.w, r0.z ishr r0.w, r4.y, l(8) ishr r2.z, r4.y, l(9) ishl r0.w, r0.w, l(31) iadd r3.z, r0.w, r0.z and r0.z, r2.z, l(1) iadd r3.w, r0.z, r3.w else ieq r0.z, r2.x, l(12) if_nz r0.z ishl r5.x, r1.x, l(5) ishl r5.y, r1.y, l(15) ishl r5.z, r1.z, l(25) ishl r5.w, r1.w, l(3) and r5.xyzw, r5.xyzw, l(32, 0x00008000, 0x02000000, 8) iadd r0.z, r5.x, l(7) ishr r0.w, r1.x, l(1) ishr r2.z, r1.x, l(2) ishr r2.w, r1.x, l(3) ishr r4.z, r1.x, l(4) ishl r6.x, r0.w, l(6) ishl r6.y, r2.z, l(7) ishl r6.z, r2.w, l(8) ishl r6.w, r4.z, l(9) and r6.xyzw, r6.xyzw, l(64, 128, 256, 512) iadd r0.z, r0.z, r6.x iadd r0.z, r6.y, r0.z iadd r0.z, r6.z, r0.z iadd r0.z, r6.w, r0.z ishr r0.w, r1.x, l(5) ishr r2.z, r1.x, l(6) ishr r2.w, r1.x, l(7) ishr r4.z, r1.x, l(8) ishl r6.x, r0.w, l(10) ishl r6.y, r2.z, l(11) ishl r6.z, r2.w, l(12) ishl r6.w, r4.z, l(13) and r6.xyzw, r6.xyzw, l(1024, 2048, 4096, 8192) iadd r0.z, r0.z, r6.x iadd r0.z, r6.y, r0.z iadd r0.z, r6.z, r0.z iadd r0.z, r6.w, r0.z ishr r0.w, r1.x, l(9) ishr r2.z, r1.y, l(1) ishr r2.w, r1.y, l(2) ishr r4.z, r1.y, l(3) ishl r6.x, r0.w, l(14) ishl r6.y, r2.z, l(16) ishl r6.z, r2.w, l(17) ishl r6.w, r4.z, l(18) and r6.xyzw, r6.xyzw, l(0x00004000, 0x00010000, 0x00020000, 0x00040000) iadd r0.z, r0.z, r6.x iadd r0.z, r5.y, r0.z iadd r0.z, r6.y, r0.z iadd r0.z, r6.z, r0.z iadd r0.z, r6.w, r0.z ishr r0.w, r1.y, l(4) ishr r2.z, r1.y, l(5) ishr r2.w, r1.y, l(6) ishr r4.z, r1.y, l(7) ishl r6.x, r0.w, l(19) ishl r6.y, r2.z, l(20) ishl r6.z, r2.w, l(21) ishl r6.w, r4.z, l(22) and r6.xyzw, r6.xyzw, l(0x00080000, 0x00100000, 0x00200000, 0x00400000) iadd r0.z, r0.z, r6.x iadd r0.z, r6.y, r0.z iadd r0.z, r6.z, r0.z iadd r0.z, r6.w, r0.z ishr r0.w, r1.y, l(8) ishr r2.z, r1.y, l(9) ishr r2.w, r1.z, l(1) ishr r4.z, r1.z, l(2) ishl r6.x, r0.w, l(23) ishl r6.y, r2.z, l(24) ishl r6.z, r2.w, l(26) ishl r6.w, r4.z, l(27) and r6.xyzw, r6.xyzw, l(0x00800000, 0x01000000, 0x04000000, 0x08000000) iadd r0.z, r0.z, r6.x iadd r0.z, r6.y, r0.z iadd r0.z, r5.z, r0.z iadd r0.z, r6.z, r0.z iadd r0.z, r6.w, r0.z ishr r0.w, r1.z, l(3) ishr r2.z, r1.z, l(4) ishr r2.w, r1.z, l(5) ishr r4.z, r1.z, l(6) ishl r5.x, r0.w, l(28) ishl r5.y, r2.z, l(29) ishl r5.z, r2.w, l(30) ishl r0.w, r4.z, l(31) and r5.xyz, r5.xyzx, l(0x10000000, 0x20000000, 0x40000000, 0) iadd r0.z, r0.z, r5.x iadd r0.z, r5.y, r0.z iadd r0.z, r5.z, r0.z iadd r3.x, r0.w, r0.z ishr r0.z, r1.z, l(7) ishr r0.w, r1.z, l(8) ishr r2.z, r1.z, l(9) ishr r2.w, r1.w, l(1) and r0.z, r0.z, l(1) ishl r5.x, r0.w, l(1) ishl r5.y, r2.z, l(2) ishl r5.z, r2.w, l(4) and r5.xyz, r5.xyzx, l(2, 4, 16, 0) iadd r0.z, r0.z, r5.x iadd r0.z, r5.y, r0.z iadd r0.z, r5.w, r0.z iadd r0.z, r5.z, r0.z ishr r0.w, r1.w, l(2) ishr r2.z, r1.w, l(3) ishr r2.w, r1.w, l(4) ishr r4.z, r1.w, l(5) ishl r5.x, r0.w, l(5) ishl r5.y, r2.z, l(6) ishl r5.z, r2.w, l(7) ishl r5.w, r4.z, l(8) and r5.xyzw, r5.xyzw, l(32, 64, 128, 256) iadd r0.z, r0.z, r5.x iadd r0.z, r5.y, r0.z iadd r0.z, r5.z, r0.z iadd r0.z, r5.w, r0.z ishr r0.w, r1.w, l(6) ishr r2.z, r1.w, l(7) ishr r2.w, r1.w, l(8) ishr r4.z, r1.x, l(10) ishl r5.x, r0.w, l(9) ishl r5.y, r2.z, l(10) ishl r5.z, r2.w, l(11) ishl r5.w, r4.z, l(12) and r5.xyzw, r5.xyzw, l(512, 1024, 2048, 4096) iadd r0.z, r0.z, r5.x iadd r0.z, r5.y, r0.z iadd r0.z, r5.z, r0.z iadd r0.z, r5.w, r0.z ishl r5.x, r4.x, l(13) ishl r5.y, r4.y, l(23) and r2.zw, r5.xxxy, l(0, 0, 8192, 0x00800000) iadd r0.z, r0.z, r2.z ishr r0.w, r4.x, l(1) ishr r2.z, r4.x, l(2) ishr r4.z, r4.x, l(3) ishr r4.w, r4.x, l(4) ishl r5.x, r0.w, l(14) ishl r5.y, r2.z, l(15) ishl r5.z, r4.z, l(16) ishl r5.w, r4.w, l(17) and r5.xyzw, r5.xyzw, l(0x00004000, 0x00008000, 0x00010000, 0x00020000) iadd r0.z, r0.z, r5.x iadd r0.z, r5.y, r0.z iadd r0.z, r5.z, r0.z iadd r0.z, r5.w, r0.z ishr r0.w, r4.x, l(5) ishr r2.z, r4.x, l(6) ishr r4.z, r4.x, l(7) ishr r4.w, r4.x, l(8) ishl r5.x, r0.w, l(18) ishl r5.y, r2.z, l(19) ishl r5.z, r4.z, l(20) ishl r5.w, r4.w, l(21) and r5.xyzw, r5.xyzw, l(0x00040000, 0x00080000, 0x00100000, 0x00200000) iadd r0.z, r0.z, r5.x iadd r0.z, r5.y, r0.z iadd r0.z, r5.z, r0.z iadd r0.z, r5.w, r0.z ishr r4.zw, r1.yyyz, l(10) ishl r0.w, r4.z, l(22) and r0.w, r0.w, l(0x00400000) iadd r0.z, r0.w, r0.z iadd r0.z, r2.w, r0.z ishr r0.w, r4.y, l(1) ishr r2.z, r4.y, l(2) ishr r2.w, r4.y, l(3) ishr r4.z, r4.y, l(4) ishl r5.x, r0.w, l(24) ishl r5.y, r2.z, l(25) ishl r5.z, r2.w, l(26) ishl r5.w, r4.z, l(27) and r5.xyzw, r5.xyzw, l(0x01000000, 0x02000000, 0x04000000, 0x08000000) iadd r0.z, r0.z, r5.x iadd r0.z, r5.y, r0.z iadd r0.z, r5.z, r0.z iadd r0.z, r5.w, r0.z ishr r0.w, r4.y, l(5) ishr r2.z, r4.y, l(6) ishr r2.w, r4.y, l(7) ishr r4.z, r4.y, l(8) ishl r5.x, r0.w, l(28) ishl r5.y, r2.z, l(29) ishl r5.z, r2.w, l(30) ishl r0.w, r4.z, l(31) and r5.xyz, r5.xyzx, l(0x10000000, 0x20000000, 0x40000000, 0) iadd r0.z, r0.z, r5.x iadd r0.z, r5.y, r0.z iadd r0.z, r5.z, r0.z iadd r3.z, r0.w, r0.z and r0.z, r4.w, l(1) iadd r3.w, r0.z, r3.w else ieq r0.z, r2.x, l(13) if_nz r0.z ishl r5.x, r1.x, l(5) ishl r5.y, r1.y, l(15) ishl r5.z, r1.z, l(25) ishl r5.w, r1.w, l(3) and r5.xyzw, r5.xyzw, l(32, 0x00008000, 0x02000000, 8) iadd r0.z, r5.x, l(11) ishr r0.w, r1.x, l(1) ishr r2.z, r1.x, l(2) ishr r2.w, r1.x, l(3) ishr r4.z, r1.x, l(4) ishl r6.x, r0.w, l(6) ishl r6.y, r2.z, l(7) ishl r6.z, r2.w, l(8) ishl r6.w, r4.z, l(9) and r6.xyzw, r6.xyzw, l(64, 128, 256, 512) iadd r0.z, r0.z, r6.x iadd r0.z, r6.y, r0.z iadd r0.z, r6.z, r0.z iadd r0.z, r6.w, r0.z ishr r0.w, r1.x, l(5) ishr r2.z, r1.x, l(6) ishr r2.w, r1.x, l(7) ishr r4.z, r1.x, l(8) ishl r6.x, r0.w, l(10) ishl r6.y, r2.z, l(11) ishl r6.z, r2.w, l(12) ishl r6.w, r4.z, l(13) and r6.xyzw, r6.xyzw, l(1024, 2048, 4096, 8192) iadd r0.z, r0.z, r6.x iadd r0.z, r6.y, r0.z iadd r0.z, r6.z, r0.z iadd r0.z, r6.w, r0.z ishr r0.w, r1.x, l(9) ishr r2.z, r1.y, l(1) ishr r2.w, r1.y, l(2) ishr r4.z, r1.y, l(3) ishl r6.x, r0.w, l(14) ishl r6.y, r2.z, l(16) ishl r6.z, r2.w, l(17) ishl r6.w, r4.z, l(18) and r6.xyzw, r6.xyzw, l(0x00004000, 0x00010000, 0x00020000, 0x00040000) iadd r0.z, r0.z, r6.x iadd r0.z, r5.y, r0.z iadd r0.z, r6.y, r0.z iadd r0.z, r6.z, r0.z iadd r0.z, r6.w, r0.z ishr r0.w, r1.y, l(4) ishr r2.z, r1.y, l(5) ishr r2.w, r1.y, l(6) ishr r4.z, r1.y, l(7) ishl r6.x, r0.w, l(19) ishl r6.y, r2.z, l(20) ishl r6.z, r2.w, l(21) ishl r6.w, r4.z, l(22) and r6.xyzw, r6.xyzw, l(0x00080000, 0x00100000, 0x00200000, 0x00400000) iadd r0.z, r0.z, r6.x iadd r0.z, r6.y, r0.z iadd r0.z, r6.z, r0.z iadd r0.z, r6.w, r0.z ishr r0.w, r1.y, l(8) ishr r2.z, r1.y, l(9) ishr r2.w, r1.z, l(1) ishr r4.z, r1.z, l(2) ishl r6.x, r0.w, l(23) ishl r6.y, r2.z, l(24) ishl r6.z, r2.w, l(26) ishl r6.w, r4.z, l(27) and r6.xyzw, r6.xyzw, l(0x00800000, 0x01000000, 0x04000000, 0x08000000) iadd r0.z, r0.z, r6.x iadd r0.z, r6.y, r0.z iadd r0.z, r5.z, r0.z iadd r0.z, r6.z, r0.z iadd r0.z, r6.w, r0.z ishr r0.w, r1.z, l(3) ishr r2.z, r1.z, l(4) ishr r2.w, r1.z, l(5) ishr r4.z, r1.z, l(6) ishl r5.x, r0.w, l(28) ishl r5.y, r2.z, l(29) ishl r5.z, r2.w, l(30) ishl r0.w, r4.z, l(31) and r5.xyz, r5.xyzx, l(0x10000000, 0x20000000, 0x40000000, 0) iadd r0.z, r0.z, r5.x iadd r0.z, r5.y, r0.z iadd r0.z, r5.z, r0.z iadd r3.x, r0.w, r0.z ishr r0.z, r1.z, l(7) ishr r0.w, r1.z, l(8) ishr r2.z, r1.z, l(9) ishr r2.w, r1.w, l(1) and r0.z, r0.z, l(1) ishl r5.x, r0.w, l(1) ishl r5.y, r2.z, l(2) ishl r5.z, r2.w, l(4) and r5.xyz, r5.xyzx, l(2, 4, 16, 0) iadd r0.z, r0.z, r5.x iadd r0.z, r5.y, r0.z iadd r0.z, r5.w, r0.z iadd r0.z, r5.z, r0.z ishr r0.w, r1.w, l(2) ishr r2.z, r1.w, l(3) ishr r2.w, r1.w, l(4) ishr r4.z, r1.w, l(5) ishl r5.x, r0.w, l(5) ishl r5.y, r2.z, l(6) ishl r5.z, r2.w, l(7) ishl r5.w, r4.z, l(8) and r5.xyzw, r5.xyzw, l(32, 64, 128, 256) iadd r0.z, r0.z, r5.x iadd r0.z, r5.y, r0.z iadd r0.z, r5.z, r0.z iadd r0.z, r5.w, r0.z ishr r0.w, r1.w, l(6) ishr r2.z, r1.w, l(7) ishr r2.w, r1.x, l(10) ishr r4.z, r1.y, l(11) ishl r5.x, r0.w, l(9) ishl r5.y, r2.z, l(10) ishl r5.z, r2.w, l(12) ishl r5.w, r4.z, l(21) and r5.xyzw, r5.xyzw, l(512, 1024, 4096, 0x00200000) iadd r0.z, r0.z, r5.x iadd r0.z, r5.y, r0.z and r0.w, r1.x, l(2048) iadd r0.z, r0.w, r0.z iadd r0.z, r5.z, r0.z ishl r5.x, r4.x, l(13) ishl r5.y, r4.y, l(23) and r2.zw, r5.xxxy, l(0, 0, 8192, 0x00800000) iadd r0.z, r0.z, r2.z ishr r0.w, r4.x, l(1) ishr r2.z, r4.x, l(2) ishr r4.z, r4.x, l(3) ishr r4.w, r4.x, l(4) ishl r6.x, r0.w, l(14) ishl r6.y, r2.z, l(15) ishl r6.z, r4.z, l(16) ishl r6.w, r4.w, l(17) and r6.xyzw, r6.xyzw, l(0x00004000, 0x00008000, 0x00010000, 0x00020000) iadd r0.z, r0.z, r6.x iadd r0.z, r6.y, r0.z iadd r0.z, r6.z, r0.z iadd r0.z, r6.w, r0.z ishr r0.w, r4.x, l(5) ishr r2.z, r4.x, l(6) ishr r4.z, r4.x, l(7) ishr r4.w, r4.y, l(1) ishl r6.x, r0.w, l(18) ishl r6.y, r2.z, l(19) ishl r6.z, r4.z, l(20) ishl r6.w, r4.w, l(24) and r6.xyzw, r6.xyzw, l(0x00040000, 0x00080000, 0x00100000, 0x01000000) iadd r0.z, r0.z, r6.x iadd r0.z, r6.y, r0.z iadd r0.z, r6.z, r0.z iadd r0.z, r5.w, r0.z ishr r4.zw, r1.yyyz, l(10) ishr r0.w, r1.z, l(11) ishl r2.z, r4.z, l(22) ishl r0.w, r0.w, l(31) and r2.z, r2.z, l(0x00400000) iadd r0.z, r0.z, r2.z iadd r0.z, r2.w, r0.z iadd r0.z, r6.w, r0.z ishr r2.z, r4.y, l(2) ishr r2.w, r4.y, l(3) ishr r4.z, r4.y, l(4) ishr r5.x, r4.y, l(5) ishl r6.x, r2.z, l(25) ishl r6.y, r2.w, l(26) ishl r6.z, r4.z, l(27) ishl r6.w, r5.x, l(28) and r5.xyzw, r6.xyzw, l(0x02000000, 0x04000000, 0x08000000, 0x10000000) iadd r0.z, r0.z, r5.x iadd r0.z, r5.y, r0.z iadd r0.z, r5.z, r0.z iadd r0.z, r5.w, r0.z ishr r2.z, r4.y, l(6) ishr r2.w, r4.y, l(7) ishl r5.x, r2.z, l(29) ishl r5.y, r2.w, l(30) and r2.zw, r5.xxxy, l(0, 0, 0x20000000, 0x40000000) iadd r0.z, r0.z, r2.z iadd r0.z, r2.w, r0.z iadd r3.z, r0.w, r0.z and r0.z, r4.w, l(1) iadd r3.w, r0.z, r3.w else ieq r0.z, r2.x, l(14) if_nz r0.z ishl r5.x, r1.x, l(5) ishl r5.y, r1.y, l(15) ishl r5.z, r1.z, l(25) ishl r5.w, r1.w, l(3) and r5.xyzw, r5.xyzw, l(32, 0x00008000, 0x02000000, 8) iadd r0.z, r5.x, l(15) ishr r0.w, r1.x, l(1) ishr r2.z, r1.x, l(2) ishr r2.w, r1.x, l(3) ishr r4.z, r1.x, l(4) ishl r6.x, r0.w, l(6) ishl r6.y, r2.z, l(7) ishl r6.z, r2.w, l(8) ishl r6.w, r4.z, l(9) and r6.xyzw, r6.xyzw, l(64, 128, 256, 512) iadd r0.z, r0.z, r6.x iadd r0.z, r6.y, r0.z iadd r0.z, r6.z, r0.z iadd r0.z, r6.w, r0.z ishr r0.w, r1.x, l(5) ishr r2.z, r1.x, l(6) ishr r2.w, r1.x, l(7) ishr r4.z, r1.x, l(8) ishl r6.x, r0.w, l(10) ishl r6.y, r2.z, l(11) ishl r6.z, r2.w, l(12) ishl r6.w, r4.z, l(13) and r6.xyzw, r6.xyzw, l(1024, 2048, 4096, 8192) iadd r0.z, r0.z, r6.x iadd r0.z, r6.y, r0.z iadd r0.z, r6.z, r0.z iadd r0.z, r6.w, r0.z ishr r0.w, r1.x, l(9) ishr r2.z, r1.y, l(1) ishr r2.w, r1.y, l(2) ishr r4.z, r1.y, l(3) ishl r6.x, r0.w, l(14) ishl r6.y, r2.z, l(16) ishl r6.z, r2.w, l(17) ishl r6.w, r4.z, l(18) and r6.xyzw, r6.xyzw, l(0x00004000, 0x00010000, 0x00020000, 0x00040000) iadd r0.z, r0.z, r6.x iadd r0.z, r5.y, r0.z iadd r0.z, r6.y, r0.z iadd r0.z, r6.z, r0.z iadd r0.z, r6.w, r0.z ishr r0.w, r1.y, l(4) ishr r2.z, r1.y, l(5) ishr r2.w, r1.y, l(6) ishr r4.z, r1.y, l(7) ishl r6.x, r0.w, l(19) ishl r6.y, r2.z, l(20) ishl r6.z, r2.w, l(21) ishl r6.w, r4.z, l(22) and r6.xyzw, r6.xyzw, l(0x00080000, 0x00100000, 0x00200000, 0x00400000) iadd r0.z, r0.z, r6.x iadd r0.z, r6.y, r0.z iadd r0.z, r6.z, r0.z iadd r0.z, r6.w, r0.z ishr r0.w, r1.y, l(8) ishr r2.z, r1.y, l(9) ishr r2.w, r1.z, l(1) ishr r4.z, r1.z, l(2) ishl r6.x, r0.w, l(23) ishl r6.y, r2.z, l(24) ishl r6.z, r2.w, l(26) ishl r6.w, r4.z, l(27) and r6.xyzw, r6.xyzw, l(0x00800000, 0x01000000, 0x04000000, 0x08000000) iadd r0.z, r0.z, r6.x iadd r0.z, r6.y, r0.z iadd r0.z, r5.z, r0.z iadd r0.z, r6.z, r0.z iadd r0.z, r6.w, r0.z ishr r0.w, r1.z, l(3) ishr r2.z, r1.z, l(4) ishr r2.w, r1.z, l(5) ishr r4.z, r1.z, l(6) ishl r5.x, r0.w, l(28) ishl r5.y, r2.z, l(29) ishl r5.z, r2.w, l(30) ishl r0.w, r4.z, l(31) and r5.xyz, r5.xyzx, l(0x10000000, 0x20000000, 0x40000000, 0) iadd r0.z, r0.z, r5.x iadd r0.z, r5.y, r0.z iadd r0.z, r5.z, r0.z iadd r3.x, r0.w, r0.z ishr r0.z, r1.z, l(7) ishr r0.w, r1.z, l(8) ishr r2.z, r1.z, l(9) ishr r2.w, r1.w, l(1) and r0.z, r0.z, l(1) ishl r5.x, r0.w, l(1) ishl r5.y, r2.z, l(2) ishl r5.z, r2.w, l(4) and r5.xyz, r5.xyzx, l(2, 4, 16, 0) iadd r0.z, r0.z, r5.x iadd r0.z, r5.y, r0.z iadd r0.z, r5.w, r0.z iadd r0.z, r5.z, r0.z ishr r0.w, r1.w, l(2) ishr r2.z, r1.w, l(3) ishr r2.w, r1.x, l(15) ishr r4.z, r1.x, l(14) ishl r5.x, r0.w, l(5) ishl r5.y, r2.z, l(6) ishl r5.z, r2.w, l(7) ishl r5.w, r4.z, l(8) and r5.xyzw, r5.xyzw, l(32, 64, 128, 256) iadd r0.z, r0.z, r5.x iadd r0.z, r5.y, r0.z iadd r0.z, r5.z, r0.z iadd r0.z, r5.w, r0.z ishr r0.w, r1.x, l(13) ishr r2.z, r1.x, l(12) ishr r2.w, r1.x, l(10) ishr r4.z, r1.y, l(15) ishl r5.x, r0.w, l(9) ishl r5.y, r2.z, l(10) ishl r5.z, r2.w, l(12) ishl r5.w, r4.z, l(17) and r5.xyzw, r5.xyzw, l(512, 1024, 4096, 0x00020000) iadd r0.z, r0.z, r5.x iadd r0.z, r5.y, r0.z and r0.w, r1.x, l(2048) iadd r0.z, r0.w, r0.z iadd r0.z, r5.z, r0.z ishl r5.x, r4.x, l(13) ishl r5.y, r4.y, l(23) and r2.zw, r5.xxxy, l(0, 0, 8192, 0x00800000) iadd r0.z, r0.z, r2.z ishr r4.zw, r4.xxxy, l(1) ishr r0.w, r4.x, l(2) ishr r2.z, r4.x, l(3) ishl r6.x, r4.z, l(14) ishl r6.y, r0.w, l(15) ishl r6.z, r2.z, l(16) ishl r6.w, r4.w, l(24) and r6.xyzw, r6.xyzw, l(0x00004000, 0x00008000, 0x00010000, 0x01000000) iadd r0.z, r0.z, r6.x iadd r0.z, r6.y, r0.z iadd r0.z, r6.z, r0.z iadd r0.z, r5.w, r0.z ishr r0.w, r1.y, l(14) ishr r2.z, r1.y, l(13) ishr r4.z, r1.y, l(12) ishr r4.w, r1.y, l(11) ishl r5.x, r0.w, l(18) ishl r5.y, r2.z, l(19) ishl r5.z, r4.z, l(20) ishl r5.w, r4.w, l(21) and r5.xyzw, r5.xyzw, l(0x00040000, 0x00080000, 0x00100000, 0x00200000) iadd r0.z, r0.z, r5.x iadd r0.z, r5.y, r0.z iadd r0.z, r5.z, r0.z iadd r0.z, r5.w, r0.z ishr r0.w, r1.y, l(10) ishr r2.z, r1.z, l(15) ishr r4.z, r1.z, l(14) ishr r4.w, r1.z, l(13) ishl r5.x, r0.w, l(22) ishl r5.y, r2.z, l(27) ishl r5.z, r4.z, l(28) ishl r5.w, r4.w, l(29) and r5.xyzw, r5.xyzw, l(0x00400000, 0x08000000, 0x10000000, 0x20000000) iadd r0.z, r0.z, r5.x iadd r0.z, r2.w, r0.z iadd r0.z, r6.w, r0.z ishr r0.w, r4.y, l(2) ishr r2.z, r4.y, l(3) ishl r6.x, r0.w, l(25) ishl r6.y, r2.z, l(26) and r2.zw, r6.xxxy, l(0, 0, 0x02000000, 0x04000000) iadd r0.z, r0.z, r2.z iadd r0.z, r2.w, r0.z iadd r0.z, r5.y, r0.z iadd r0.z, r5.z, r0.z iadd r0.z, r5.w, r0.z ishr r0.w, r1.z, l(12) ishr r2.z, r1.z, l(11) ishr r2.w, r1.z, l(10) ishl r0.w, r0.w, l(30) ishl r2.z, r2.z, l(31) and r0.w, r0.w, l(0x40000000) iadd r0.z, r0.w, r0.z iadd r3.z, r2.z, r0.z and r0.z, r2.w, l(1) iadd r3.w, r0.z, r3.w else mov r3.xz, l(0,0,0,0) endif endif endif endif else iadd r0.y, r0.y, l(1) ld_structured r5.xyzw, r0.y, l(52), g0.xyzw ld_structured r6.xy, r0.y, l(68), g0.xyxx and r3.w, r3.x, l(0xfffc0000) ieq r0.y, r2.x, l(1) if_nz r0.y ishr r0.yz, r5.yyzy, l(4) ishr r0.w, r5.y, l(1) ishr r2.z, r5.y, l(2) ishl r7.x, r0.y, l(2) ishl r7.y, r0.z, l(3) ishl r7.z, r0.w, l(10) ishl r7.w, r2.z, l(11) and r7.xyzw, r7.xyzw, l(4, 8, 1024, 2048) iadd r0.y, r7.y, r7.x and r0.z, r6.y, l(16) iadd r0.y, r0.z, r0.y ishl r8.x, r1.x, l(5) ishl r8.y, r1.y, l(15) ishl r8.z, r1.z, l(25) ishl r8.w, r1.w, l(3) and r8.xyzw, r8.xyzw, l(32, 0x00008000, 0x02000000, 8) iadd r0.y, r0.y, r8.x ishr r0.z, r1.x, l(1) ishr r0.w, r1.x, l(2) ishr r2.z, r1.x, l(3) ishr r2.w, r1.x, l(4) ishl r9.x, r0.z, l(6) ishl r9.y, r0.w, l(7) ishl r9.z, r2.z, l(8) ishl r9.w, r2.w, l(9) and r9.xyzw, r9.xyzw, l(64, 128, 256, 512) iadd r0.y, r0.y, r9.x iadd r0.y, r9.y, r0.y iadd r0.y, r9.z, r0.y iadd r0.y, r9.w, r0.y ishr r0.z, r1.x, l(5) ishr r0.w, r1.x, l(6) ishr r2.z, r1.x, l(7) ishr r2.w, r1.x, l(8) ishl r9.x, r0.z, l(10) ishl r9.y, r0.w, l(11) ishl r9.z, r2.z, l(12) ishl r9.w, r2.w, l(13) and r9.xyzw, r9.xyzw, l(1024, 2048, 4096, 8192) iadd r0.y, r0.y, r9.x iadd r0.y, r9.y, r0.y iadd r0.y, r9.z, r0.y iadd r0.y, r9.w, r0.y ishr r0.z, r1.x, l(9) ishr r0.w, r1.y, l(1) ishr r2.z, r1.y, l(2) ishr r2.w, r1.y, l(3) ishl r9.x, r0.z, l(14) ishl r9.y, r0.w, l(16) ishl r9.z, r2.z, l(17) ishl r9.w, r2.w, l(18) and r9.xyzw, r9.xyzw, l(0x00004000, 0x00010000, 0x00020000, 0x00040000) iadd r0.y, r0.y, r9.x iadd r0.y, r8.y, r0.y iadd r0.y, r9.y, r0.y iadd r0.y, r9.z, r0.y iadd r0.y, r9.w, r0.y ishr r0.z, r1.y, l(4) ishr r0.w, r1.y, l(5) ishr r2.z, r1.y, l(6) ishr r2.w, r1.y, l(7) ishl r9.x, r0.z, l(19) ishl r9.y, r0.w, l(20) ishl r9.z, r2.z, l(21) ishl r9.w, r2.w, l(22) and r9.xyzw, r9.xyzw, l(0x00080000, 0x00100000, 0x00200000, 0x00400000) iadd r0.y, r0.y, r9.x iadd r0.y, r9.y, r0.y iadd r0.y, r9.z, r0.y iadd r0.y, r9.w, r0.y ishr r0.z, r1.y, l(8) ishr r0.w, r1.y, l(9) ishr r2.z, r1.z, l(1) ishr r2.w, r1.z, l(2) ishl r9.x, r0.z, l(23) ishl r9.y, r0.w, l(24) ishl r9.z, r2.z, l(26) ishl r9.w, r2.w, l(27) and r9.xyzw, r9.xyzw, l(0x00800000, 0x01000000, 0x04000000, 0x08000000) iadd r0.y, r0.y, r9.x iadd r0.y, r9.y, r0.y iadd r0.y, r8.z, r0.y iadd r0.y, r9.z, r0.y iadd r0.y, r9.w, r0.y ishr r0.z, r1.z, l(3) ishr r0.w, r1.z, l(4) ishr r2.z, r1.z, l(5) ishr r2.w, r1.z, l(6) ishl r8.x, r0.z, l(28) ishl r8.y, r0.w, l(29) ishl r8.z, r2.z, l(30) ishl r0.z, r2.w, l(31) and r8.xyz, r8.xyzx, l(0x10000000, 0x20000000, 0x40000000, 0) iadd r0.y, r0.y, r8.x iadd r0.y, r8.y, r0.y iadd r0.y, r8.z, r0.y iadd r3.x, r0.z, r0.y ishr r0.y, r1.z, l(7) ishr r0.z, r1.z, l(8) ishr r0.w, r1.z, l(9) ishr r2.z, r1.w, l(1) and r0.y, r0.y, l(1) ishl r8.x, r0.z, l(1) ishl r8.y, r0.w, l(2) ishl r8.z, r2.z, l(4) and r8.xyz, r8.xyzx, l(2, 4, 16, 0) iadd r0.y, r0.y, r8.x iadd r0.y, r8.y, r0.y iadd r0.y, r8.w, r0.y iadd r0.y, r8.z, r0.y ishr r0.z, r1.w, l(2) ishr r0.w, r1.w, l(3) ishr r2.z, r1.w, l(4) ishl r8.x, r0.z, l(5) ishl r8.y, r0.w, l(6) ishl r8.z, r2.z, l(7) and r8.xyz, r8.xyzx, l(32, 64, 128, 0) iadd r0.y, r0.y, r8.x iadd r0.y, r8.y, r0.y iadd r0.y, r8.z, r0.y ishr r0.z, r6.x, l(4) ishr r0.w, r6.x, l(1) ishr r2.z, r6.x, l(2) ishr r2.w, r6.x, l(3) ishl r8.x, r0.z, l(8) ishl r8.y, r0.w, l(20) ishl r8.z, r2.z, l(21) ishl r8.w, r2.w, l(22) and r8.xyzw, r8.xyzw, l(256, 0x00100000, 0x00200000, 0x00400000) iadd r0.y, r0.y, r8.x ishl r9.x, r5.y, l(9) ishl r9.y, r5.z, l(29) ishl r9.z, r5.x, l(1) ishl r9.w, r5.w, l(7) and r9.xyzw, r9.xyzw, l(512, 0x20000000, 2, 128) iadd r0.y, r0.y, r9.x iadd r0.y, r7.z, r0.y iadd r0.y, r7.w, r0.y ishr r0.zw, r5.yyyz, l(3) ishr r2.z, r5.z, l(1) ishr r2.w, r5.z, l(2) ishl r7.x, r0.z, l(12) ishl r7.y, r2.z, l(30) ishl r0.z, r2.w, l(31) and r2.zw, r7.xxxy, l(0, 0, 4096, 0x40000000) iadd r0.y, r0.y, r2.z ishl r7.x, r4.x, l(13) ishl r7.y, r4.y, l(23) and r4.zw, r7.xxxy, l(0, 0, 8192, 0x00800000) iadd r0.y, r0.y, r4.z ishr r2.z, r4.x, l(1) ishr r4.z, r4.x, l(2) ishr r6.z, r4.x, l(3) ishr r6.w, r4.x, l(4) ishl r7.x, r2.z, l(14) ishl r7.y, r4.z, l(15) ishl r7.z, r6.z, l(16) ishl r7.w, r6.w, l(17) and r7.xyzw, r7.xyzw, l(0x00004000, 0x00008000, 0x00010000, 0x00020000) iadd r0.y, r0.y, r7.x iadd r0.y, r7.y, r0.y iadd r0.y, r7.z, r0.y iadd r0.y, r7.w, r0.y ishl r7.x, r6.y, l(18) ishl r7.y, r6.x, l(19) and r6.zw, r7.xxxy, l(0, 0, 0x00040000, 0x00080000) iadd r0.y, r0.y, r6.z iadd r0.y, r6.w, r0.y iadd r0.y, r8.y, r0.y iadd r0.y, r8.z, r0.y iadd r0.y, r8.w, r0.y iadd r0.y, r4.w, r0.y ishr r2.z, r4.y, l(1) ishr r4.z, r4.y, l(2) ishr r4.w, r4.y, l(3) ishr r6.z, r4.y, l(4) ishl r7.x, r2.z, l(24) ishl r7.y, r4.z, l(25) ishl r7.z, r4.w, l(26) ishl r7.w, r6.z, l(27) and r7.xyzw, r7.xyzw, l(0x01000000, 0x02000000, 0x04000000, 0x08000000) iadd r0.y, r0.y, r7.x iadd r0.y, r7.y, r0.y iadd r0.y, r7.z, r0.y iadd r0.y, r7.w, r0.y ishr r2.z, r6.y, l(1) ishr r4.z, r6.y, l(2) ishr r4.w, r6.y, l(3) ishl r7.x, r2.z, l(28) ishl r7.y, r4.z, l(6) ishl r7.z, r4.w, l(12) and r7.xyz, r7.xyzx, l(0x10000000, 64, 4096, 0) iadd r0.y, r0.y, r7.x iadd r0.y, r9.y, r0.y iadd r0.y, r2.w, r0.y iadd r3.z, r0.z, r0.y and r0.y, r0.w, l(1) iadd r0.y, r0.y, r3.w iadd r0.y, r9.z, r0.y ishr r0.z, r5.x, l(1) ishr r0.w, r5.x, l(2) ishr r2.z, r5.x, l(3) ishr r2.w, r5.x, l(4) ishl r8.x, r0.z, l(2) ishl r8.y, r0.w, l(3) ishl r8.z, r2.z, l(4) ishl r8.w, r2.w, l(5) and r8.xyzw, r8.xyzw, l(4, 8, 16, 32) iadd r0.y, r0.y, r8.x iadd r0.y, r8.y, r0.y iadd r0.y, r8.z, r0.y iadd r0.y, r8.w, r0.y iadd r0.y, r7.y, r0.y iadd r0.y, r9.w, r0.y ishr r0.z, r5.w, l(1) ishr r0.w, r5.w, l(2) ishr r2.z, r5.w, l(3) ishr r2.w, r5.w, l(4) ishl r8.x, r0.z, l(8) ishl r8.y, r0.w, l(9) ishl r8.z, r2.z, l(10) ishl r8.w, r2.w, l(11) and r8.xyzw, r8.xyzw, l(256, 512, 1024, 2048) iadd r0.y, r0.y, r8.x iadd r0.y, r8.y, r0.y iadd r0.y, r8.z, r0.y iadd r0.y, r8.w, r0.y iadd r0.y, r7.z, r0.y ishl r0.z, r2.y, l(13) and r0.z, r0.z, l(8192) iadd r0.y, r0.z, r0.y ushr r0.z, r2.y, l(1) ushr r0.w, r2.y, l(2) ushr r2.z, r2.y, l(3) ushr r2.w, r2.y, l(4) ishl r7.x, r0.z, l(14) ishl r7.y, r0.w, l(15) ishl r7.z, r2.z, l(16) ishl r7.w, r2.w, l(17) and r7.xyzw, r7.xyzw, l(0x00004000, 0x00008000, 0x00010000, 0x00020000) iadd r0.y, r0.y, r7.x iadd r0.y, r7.y, r0.y iadd r0.y, r7.z, r0.y iadd r3.w, r7.w, r0.y else ieq r0.y, r2.x, l(2) if_nz r0.y ishr r0.yz, r5.yyzy, l(5) ishr r2.zw, r5.zzzy, l(4) ishl r7.x, r0.y, l(2) ishl r7.y, r2.z, l(14) ishl r7.z, r0.z, l(22) ishl r7.w, r2.w, l(24) and r7.xyzw, r7.xyzw, l(4, 0x00004000, 0x00400000, 0x01000000) iadd r0.y, r7.x, l(1) ishr r0.z, r6.x, l(4) ishr r0.w, r6.x, l(5) ishr r2.z, r6.y, l(1) ishr r2.w, r6.y, l(2) ishl r8.x, r0.z, l(3) ishl r8.y, r0.w, l(4) ishl r8.z, r2.z, l(13) ishl r8.w, r2.w, l(23) and r8.xyzw, r8.xyzw, l(8, 16, 8192, 0x00800000) iadd r0.y, r0.y, r8.x iadd r0.y, r8.y, r0.y ishl r9.x, r1.x, l(5) ishl r9.y, r1.y, l(15) ishl r9.z, r1.z, l(25) ishl r9.w, r1.w, l(3) and r9.xyzw, r9.xyzw, l(32, 0x00008000, 0x02000000, 8) iadd r0.y, r0.y, r9.x ishr r0.z, r1.x, l(1) ishr r0.w, r1.x, l(2) ishr r2.z, r1.x, l(3) ishr r2.w, r1.x, l(4) ishl r10.x, r0.z, l(6) ishl r10.y, r0.w, l(7) ishl r10.z, r2.z, l(8) ishl r10.w, r2.w, l(9) and r10.xyzw, r10.xyzw, l(64, 128, 256, 512) iadd r0.y, r0.y, r10.x iadd r0.y, r10.y, r0.y iadd r0.y, r10.z, r0.y iadd r0.y, r10.w, r0.y ishr r0.z, r1.x, l(5) ishr r0.w, r1.x, l(6) ishr r2.z, r1.y, l(1) ishr r2.w, r1.y, l(2) ishl r10.x, r0.z, l(10) ishl r10.y, r0.w, l(11) ishl r10.z, r2.z, l(16) ishl r10.w, r2.w, l(17) and r10.xyzw, r10.xyzw, l(1024, 2048, 0x00010000, 0x00020000) iadd r0.y, r0.y, r10.x iadd r0.y, r10.y, r0.y ishl r8.x, r6.y, l(12) ishl r8.y, r6.x, l(19) and r0.zw, r8.xxxy, l(0, 0, 4096, 0x00080000) iadd r0.y, r0.z, r0.y iadd r0.y, r8.z, r0.y iadd r0.y, r7.y, r0.y iadd r0.y, r9.y, r0.y iadd r0.y, r10.z, r0.y iadd r0.y, r10.w, r0.y ishr r0.z, r1.y, l(3) ishr r2.z, r1.y, l(4) ishr r2.w, r1.y, l(5) ishr r4.z, r1.y, l(6) ishl r10.x, r0.z, l(18) ishl r10.y, r2.z, l(19) ishl r10.z, r2.w, l(20) ishl r10.w, r4.z, l(21) and r10.xyzw, r10.xyzw, l(0x00040000, 0x00080000, 0x00100000, 0x00200000) iadd r0.y, r0.y, r10.x iadd r0.y, r10.y, r0.y iadd r0.y, r10.z, r0.y iadd r0.y, r10.w, r0.y iadd r0.y, r7.z, r0.y iadd r0.y, r8.w, r0.y iadd r0.y, r7.w, r0.y iadd r0.y, r9.z, r0.y ishr r0.z, r1.z, l(1) ishr r2.z, r1.z, l(2) ishr r2.w, r1.z, l(3) ishr r4.z, r1.z, l(4) ishl r7.x, r0.z, l(26) ishl r7.y, r2.z, l(27) ishl r7.z, r2.w, l(28) ishl r7.w, r4.z, l(29) and r7.xyzw, r7.xyzw, l(0x04000000, 0x08000000, 0x10000000, 0x20000000) iadd r0.y, r0.y, r7.x iadd r0.y, r7.y, r0.y iadd r0.y, r7.z, r0.y iadd r0.y, r7.w, r0.y ishr r0.z, r1.z, l(5) ishr r2.z, r1.z, l(6) ishr r2.w, r1.w, l(1) ishr r4.z, r1.w, l(2) ishl r7.x, r0.z, l(30) ishl r0.z, r2.z, l(31) ishl r7.z, r2.w, l(4) ishl r7.w, r4.z, l(5) and r7.xyz, r7.xzwx, l(0x40000000, 16, 32, 0) iadd r0.y, r0.y, r7.x iadd r3.x, r0.z, r0.y ishr r0.y, r6.y, l(3) ishr r0.z, r6.y, l(5) ishr r2.z, r6.y, l(4) ishr r2.w, r6.x, l(1) and r0.y, r0.y, l(1) ishl r8.x, r0.z, l(1) ishl r8.y, r2.z, l(2) ishl r8.z, r2.w, l(20) and r8.xyz, r8.xyzx, l(2, 4, 0x00100000, 0) iadd r0.y, r0.y, r8.x iadd r0.y, r8.y, r0.y iadd r0.y, r9.w, r0.y iadd r0.y, r7.y, r0.y iadd r0.y, r7.z, r0.y ishr r0.z, r1.w, l(3) ishr r2.z, r1.w, l(4) ishr r2.w, r1.w, l(5) ishl r7.x, r0.z, l(6) ishl r7.y, r2.z, l(7) ishl r7.z, r2.w, l(8) and r7.xyz, r7.xyzx, l(64, 128, 256, 0) iadd r0.y, r0.y, r7.x iadd r0.y, r7.y, r0.y iadd r0.y, r7.z, r0.y ishl r7.x, r5.y, l(9) ishl r7.y, r5.z, l(29) ishl r7.z, r5.x, l(1) ishl r7.w, r5.w, l(7) and r7.xyzw, r7.xyzw, l(512, 0x20000000, 2, 128) iadd r0.y, r0.y, r7.x ishr r2.zw, r5.yyyz, l(1) ishr r0.z, r5.y, l(2) ishr r4.z, r5.y, l(3) ishl r9.x, r2.z, l(10) ishl r9.y, r0.z, l(11) ishl r9.z, r4.z, l(12) ishl r9.w, r2.w, l(30) and r9.xyzw, r9.xyzw, l(1024, 2048, 4096, 0x40000000) iadd r0.y, r0.y, r9.x iadd r0.y, r9.y, r0.y iadd r0.y, r9.z, r0.y ishl r8.x, r4.x, l(13) ishl r8.y, r4.y, l(23) and r2.zw, r8.xxxy, l(0, 0, 8192, 0x00800000) iadd r0.y, r0.y, r2.z ishr r0.z, r4.x, l(1) ishr r2.z, r4.x, l(2) ishr r4.z, r4.x, l(3) ishr r4.w, r4.x, l(4) ishl r10.x, r0.z, l(14) ishl r10.y, r2.z, l(15) ishl r10.z, r4.z, l(16) ishl r10.w, r4.w, l(17) and r10.xyzw, r10.xyzw, l(0x00004000, 0x00008000, 0x00010000, 0x00020000) iadd r0.y, r0.y, r10.x iadd r0.y, r10.y, r0.y iadd r0.y, r10.z, r0.y iadd r0.y, r10.w, r0.y ishr r0.z, r4.x, l(5) ishr r2.z, r4.y, l(1) ishr r4.z, r4.y, l(2) ishr r4.w, r4.y, l(3) ishl r10.x, r0.z, l(18) ishl r10.y, r2.z, l(24) ishl r10.z, r4.z, l(25) ishl r10.w, r4.w, l(26) and r10.xyzw, r10.xyzw, l(0x00040000, 0x01000000, 0x02000000, 0x04000000) iadd r0.y, r0.y, r10.x iadd r0.y, r0.w, r0.y iadd r0.y, r8.z, r0.y ishr r0.z, r6.x, l(2) ishr r0.w, r6.x, l(3) ishl r8.x, r0.z, l(21) ishl r8.y, r0.w, l(22) and r0.zw, r8.xxxy, l(0, 0, 0x00200000, 0x00400000) iadd r0.y, r0.z, r0.y iadd r0.y, r0.w, r0.y iadd r0.y, r2.w, r0.y iadd r0.y, r10.y, r0.y iadd r0.y, r10.z, r0.y iadd r0.y, r10.w, r0.y ishr r0.z, r4.y, l(4) ishr r0.w, r4.y, l(5) ishl r8.x, r0.z, l(27) ishl r8.y, r0.w, l(28) and r0.zw, r8.xxxy, l(0, 0, 0x08000000, 0x10000000) iadd r0.y, r0.z, r0.y iadd r0.y, r0.w, r0.y iadd r0.y, r7.y, r0.y iadd r0.y, r9.w, r0.y ishr r0.zw, r5.zzzx, l(2) ishr r2.z, r5.z, l(3) ishr r2.w, r5.x, l(1) ishl r8.x, r0.z, l(31) ishl r8.y, r2.w, l(2) ishl r8.z, r0.w, l(3) iadd r3.z, r0.y, r8.x and r0.y, r2.z, l(1) iadd r0.y, r0.y, r3.w iadd r0.y, r7.z, r0.y and r0.zw, r8.yyyz, l(0, 0, 4, 8) iadd r0.y, r0.z, r0.y iadd r0.y, r0.w, r0.y ishr r0.z, r5.x, l(3) ishr r0.w, r5.x, l(4) ishr r2.z, r5.x, l(5) ishr r2.w, r5.w, l(1) ishl r8.x, r0.z, l(4) ishl r8.y, r0.w, l(5) ishl r8.z, r2.z, l(6) ishl r8.w, r2.w, l(8) and r8.xyzw, r8.xyzw, l(16, 32, 64, 256) iadd r0.y, r0.y, r8.x iadd r0.y, r8.y, r0.y iadd r0.y, r8.z, r0.y iadd r0.y, r7.w, r0.y iadd r0.y, r8.w, r0.y ishr r0.z, r5.w, l(2) ishr r0.w, r5.w, l(3) ishr r2.z, r5.w, l(4) ishr r2.w, r5.w, l(5) ishl r7.x, r0.z, l(9) ishl r7.y, r0.w, l(10) ishl r7.z, r2.z, l(11) ishl r7.w, r2.w, l(12) and r7.xyzw, r7.xyzw, l(512, 1024, 2048, 4096) iadd r0.y, r0.y, r7.x iadd r0.y, r7.y, r0.y iadd r0.y, r7.z, r0.y iadd r0.y, r7.w, r0.y ishl r0.z, r2.y, l(13) and r0.z, r0.z, l(8192) iadd r0.y, r0.z, r0.y ushr r0.z, r2.y, l(1) ushr r0.w, r2.y, l(2) ushr r2.z, r2.y, l(3) ushr r2.w, r2.y, l(4) ishl r7.x, r0.z, l(14) ishl r7.y, r0.w, l(15) ishl r7.z, r2.z, l(16) ishl r7.w, r2.w, l(17) and r7.xyzw, r7.xyzw, l(0x00004000, 0x00008000, 0x00010000, 0x00020000) iadd r0.y, r0.y, r7.x iadd r0.y, r7.y, r0.y iadd r0.y, r7.z, r0.y iadd r3.w, r7.w, r0.y else ieq r0.y, r2.x, l(3) if_nz r0.y ishl r7.x, r1.x, l(5) ishl r7.y, r1.y, l(15) ishl r7.z, r1.z, l(25) ishl r7.w, r1.w, l(3) and r7.xyzw, r7.xyzw, l(32, 0x00008000, 0x02000000, 8) iadd r0.y, r7.x, l(2) ishr r0.z, r1.x, l(1) ishr r0.w, r1.x, l(2) ishr r2.z, r1.x, l(3) ishr r2.w, r1.x, l(4) ishl r8.x, r0.z, l(6) ishl r8.y, r0.w, l(7) ishl r8.z, r2.z, l(8) ishl r8.w, r2.w, l(9) and r8.xyzw, r8.xyzw, l(64, 128, 256, 512) iadd r0.y, r0.y, r8.x iadd r0.y, r8.y, r0.y iadd r0.y, r8.z, r0.y iadd r0.y, r8.w, r0.y ishr r0.z, r1.x, l(5) ishr r0.w, r1.x, l(6) ishr r2.z, r1.x, l(7) ishr r2.w, r1.x, l(8) ishl r8.x, r0.z, l(10) ishl r8.y, r0.w, l(11) ishl r8.z, r2.z, l(12) ishl r8.w, r2.w, l(13) and r8.xyzw, r8.xyzw, l(1024, 2048, 4096, 8192) iadd r0.y, r0.y, r8.x iadd r0.y, r8.y, r0.y iadd r0.y, r8.z, r0.y iadd r0.y, r8.w, r0.y ishr r0.z, r1.x, l(9) ishr r0.w, r1.y, l(1) ishr r2.z, r1.y, l(2) ishr r2.w, r1.y, l(3) ishl r8.x, r0.z, l(14) ishl r8.y, r0.w, l(16) ishl r8.z, r2.z, l(17) ishl r8.w, r2.w, l(18) and r8.xyzw, r8.xyzw, l(0x00004000, 0x00010000, 0x00020000, 0x00040000) iadd r0.y, r0.y, r8.x iadd r0.y, r7.y, r0.y iadd r0.y, r8.y, r0.y iadd r0.y, r8.z, r0.y iadd r0.y, r8.w, r0.y ishr r0.z, r1.y, l(4) ishr r0.w, r1.y, l(5) ishr r2.z, r1.y, l(6) ishr r2.w, r1.y, l(7) ishl r8.x, r0.z, l(19) ishl r8.y, r0.w, l(20) ishl r8.z, r2.z, l(21) ishl r8.w, r2.w, l(22) and r8.xyzw, r8.xyzw, l(0x00080000, 0x00100000, 0x00200000, 0x00400000) iadd r0.y, r0.y, r8.x iadd r0.y, r8.y, r0.y iadd r0.y, r8.z, r0.y iadd r0.y, r8.w, r0.y ishr r0.z, r1.y, l(8) ishr r0.w, r1.y, l(9) ishr r2.z, r1.z, l(1) ishr r2.w, r1.z, l(2) ishl r8.x, r0.z, l(23) ishl r8.y, r0.w, l(24) ishl r8.z, r2.z, l(26) ishl r8.w, r2.w, l(27) and r8.xyzw, r8.xyzw, l(0x00800000, 0x01000000, 0x04000000, 0x08000000) iadd r0.y, r0.y, r8.x iadd r0.y, r8.y, r0.y iadd r0.y, r7.z, r0.y iadd r0.y, r8.z, r0.y iadd r0.y, r8.w, r0.y ishr r0.z, r1.z, l(3) ishr r0.w, r1.z, l(4) ishr r2.z, r1.z, l(5) ishr r2.w, r1.z, l(6) ishl r7.x, r0.z, l(28) ishl r7.y, r0.w, l(29) ishl r7.z, r2.z, l(30) ishl r0.z, r2.w, l(31) and r7.xyz, r7.xyzx, l(0x10000000, 0x20000000, 0x40000000, 0) iadd r0.y, r0.y, r7.x iadd r0.y, r7.y, r0.y iadd r0.y, r7.z, r0.y iadd r3.x, r0.z, r0.y ishr r0.y, r1.z, l(7) ishr r0.z, r1.z, l(8) ishr r0.w, r1.z, l(9) ishr r2.z, r1.w, l(1) and r0.y, r0.y, l(1) ishl r7.x, r0.z, l(1) ishl r7.y, r0.w, l(2) ishl r7.z, r2.z, l(4) and r7.xyz, r7.xyzx, l(2, 4, 16, 0) iadd r0.y, r0.y, r7.x iadd r0.y, r7.y, r0.y iadd r0.y, r7.w, r0.y iadd r0.y, r7.z, r0.y ishr r0.z, r1.w, l(2) ishr r0.w, r1.w, l(3) ishr r2.z, r1.w, l(4) ishr r2.w, r1.x, l(10) ishl r7.x, r0.z, l(5) ishl r7.y, r0.w, l(6) ishl r7.z, r2.z, l(7) ishl r7.w, r2.w, l(8) and r7.xyzw, r7.xyzw, l(32, 64, 128, 256) iadd r0.y, r0.y, r7.x iadd r0.y, r7.y, r0.y iadd r0.y, r7.z, r0.y iadd r0.y, r7.w, r0.y ishl r7.x, r5.y, l(9) ishl r7.y, r5.z, l(29) ishl r7.z, r5.x, l(1) ishl r7.w, r5.w, l(7) and r7.xyzw, r7.xyzw, l(512, 0x20000000, 2, 128) iadd r0.y, r0.y, r7.x ishr r0.zw, r5.yyyz, l(1) ishr r2.z, r5.y, l(2) ishr r2.w, r5.y, l(3) ishl r8.x, r0.z, l(10) ishl r8.y, r2.z, l(11) ishl r8.z, r2.w, l(12) ishl r8.w, r0.w, l(30) and r8.xyzw, r8.xyzw, l(1024, 2048, 4096, 0x40000000) iadd r0.y, r0.y, r8.x iadd r0.y, r8.y, r0.y iadd r0.y, r8.z, r0.y ishl r8.x, r4.x, l(13) ishl r8.y, r4.y, l(23) and r0.zw, r8.xxxy, l(0, 0, 8192, 0x00800000) iadd r0.y, r0.z, r0.y ishr r2.zw, r4.xxxy, l(1) ishr r0.z, r4.x, l(2) ishr r4.z, r4.x, l(3) ishl r9.x, r2.z, l(14) ishl r9.y, r0.z, l(15) ishl r9.z, r4.z, l(16) ishl r9.w, r2.w, l(24) and r9.xyzw, r9.xyzw, l(0x00004000, 0x00008000, 0x00010000, 0x01000000) iadd r0.y, r0.y, r9.x iadd r0.y, r9.y, r0.y iadd r0.y, r9.z, r0.y ishr r2.zw, r1.yyyz, l(10) ishl r8.x, r2.z, l(17) ishl r8.y, r2.w, l(27) and r2.zw, r8.xxxy, l(0, 0, 0x00020000, 0x08000000) iadd r0.y, r0.y, r2.z ishl r8.x, r6.y, l(18) ishl r8.y, r6.x, l(19) and r4.zw, r8.xxxy, l(0, 0, 0x00040000, 0x00080000) iadd r0.y, r0.y, r4.z iadd r0.y, r4.w, r0.y ishr r4.zw, r6.xxxy, l(1) ishr r0.z, r6.x, l(2) ishr r2.z, r6.x, l(3) ishl r10.x, r4.z, l(20) ishl r10.y, r0.z, l(21) ishl r10.z, r2.z, l(22) ishl r10.w, r4.w, l(28) and r10.xyzw, r10.xyzw, l(0x00100000, 0x00200000, 0x00400000, 0x10000000) iadd r0.y, r0.y, r10.x iadd r0.y, r10.y, r0.y iadd r0.y, r10.z, r0.y iadd r0.y, r0.w, r0.y iadd r0.y, r9.w, r0.y ishr r0.z, r4.y, l(2) ishr r0.w, r4.y, l(3) ishl r8.x, r0.z, l(25) ishl r8.y, r0.w, l(26) and r0.zw, r8.xxxy, l(0, 0, 0x02000000, 0x04000000) iadd r0.y, r0.z, r0.y iadd r0.y, r0.w, r0.y iadd r0.y, r2.w, r0.y iadd r0.y, r10.w, r0.y iadd r0.y, r7.y, r0.y iadd r0.y, r8.w, r0.y ishr r0.zw, r5.zzzx, l(2) ishr r2.z, r5.z, l(3) ishr r2.w, r5.x, l(1) ishl r8.x, r0.z, l(31) ishl r8.y, r2.w, l(2) ishl r8.z, r0.w, l(3) iadd r3.z, r0.y, r8.x and r0.y, r2.z, l(1) iadd r0.y, r0.y, r3.w iadd r0.y, r7.z, r0.y and r0.zw, r8.yyyz, l(0, 0, 4, 8) iadd r0.y, r0.z, r0.y iadd r0.y, r0.w, r0.y ishr r0.z, r5.x, l(3) ishr r0.w, r5.x, l(4) ishr r2.z, r5.w, l(1) ishr r2.w, r5.w, l(2) ishl r8.x, r0.z, l(4) ishl r8.y, r0.w, l(5) ishl r8.z, r2.z, l(8) ishl r8.w, r2.w, l(9) and r8.xyzw, r8.xyzw, l(16, 32, 256, 512) iadd r0.y, r0.y, r8.x iadd r0.y, r8.y, r0.y ishr r0.z, r6.y, l(2) ishr r0.w, r6.y, l(3) ishl r7.x, r0.z, l(6) ishl r7.y, r0.w, l(12) and r0.zw, r7.xxxy, l(0, 0, 64, 4096) iadd r0.y, r0.z, r0.y iadd r0.y, r7.w, r0.y iadd r0.y, r8.z, r0.y iadd r0.y, r8.w, r0.y ishr r0.z, r5.w, l(3) ishr r2.z, r5.w, l(4) ishl r7.x, r0.z, l(10) ishl r7.y, r2.z, l(11) and r2.zw, r7.xxxy, l(0, 0, 1024, 2048) iadd r0.y, r0.y, r2.z iadd r0.y, r2.w, r0.y iadd r0.y, r0.w, r0.y ishl r0.z, r2.y, l(13) and r0.z, r0.z, l(8192) iadd r0.y, r0.z, r0.y ushr r0.z, r2.y, l(1) ushr r0.w, r2.y, l(2) ushr r2.z, r2.y, l(3) ushr r2.w, r2.y, l(4) ishl r7.x, r0.z, l(14) ishl r7.y, r0.w, l(15) ishl r7.z, r2.z, l(16) ishl r7.w, r2.w, l(17) and r7.xyzw, r7.xyzw, l(0x00004000, 0x00008000, 0x00010000, 0x00020000) iadd r0.y, r0.y, r7.x iadd r0.y, r7.y, r0.y iadd r0.y, r7.z, r0.y iadd r3.w, r7.w, r0.y else ieq r0.y, r2.x, l(4) if_nz r0.y ishl r7.x, r1.x, l(5) ishl r7.y, r1.y, l(15) ishl r7.z, r1.z, l(25) ishl r7.w, r1.w, l(3) and r7.xyzw, r7.xyzw, l(32, 0x00008000, 0x02000000, 8) iadd r0.y, r7.x, l(6) ishr r0.z, r1.x, l(1) ishr r0.w, r1.x, l(2) ishr r2.z, r1.x, l(3) ishr r2.w, r1.x, l(4) ishl r8.x, r0.z, l(6) ishl r8.y, r0.w, l(7) ishl r8.z, r2.z, l(8) ishl r8.w, r2.w, l(9) and r8.xyzw, r8.xyzw, l(64, 128, 256, 512) iadd r0.y, r0.y, r8.x iadd r0.y, r8.y, r0.y iadd r0.y, r8.z, r0.y iadd r0.y, r8.w, r0.y ishr r0.z, r1.x, l(5) ishr r0.w, r1.x, l(6) ishr r2.z, r1.x, l(7) ishr r2.w, r1.x, l(8) ishl r8.x, r0.z, l(10) ishl r8.y, r0.w, l(11) ishl r8.z, r2.z, l(12) ishl r8.w, r2.w, l(13) and r8.xyzw, r8.xyzw, l(1024, 2048, 4096, 8192) iadd r0.y, r0.y, r8.x iadd r0.y, r8.y, r0.y iadd r0.y, r8.z, r0.y iadd r0.y, r8.w, r0.y ishr r0.z, r1.x, l(9) ishr r0.w, r1.y, l(1) ishr r2.z, r1.y, l(2) ishr r2.w, r1.y, l(3) ishl r8.x, r0.z, l(14) ishl r8.y, r0.w, l(16) ishl r8.z, r2.z, l(17) ishl r8.w, r2.w, l(18) and r8.xyzw, r8.xyzw, l(0x00004000, 0x00010000, 0x00020000, 0x00040000) iadd r0.y, r0.y, r8.x iadd r0.y, r7.y, r0.y iadd r0.y, r8.y, r0.y iadd r0.y, r8.z, r0.y iadd r0.y, r8.w, r0.y ishr r0.z, r1.y, l(4) ishr r0.w, r1.y, l(5) ishr r2.z, r1.y, l(6) ishr r2.w, r1.y, l(7) ishl r8.x, r0.z, l(19) ishl r8.y, r0.w, l(20) ishl r8.z, r2.z, l(21) ishl r8.w, r2.w, l(22) and r8.xyzw, r8.xyzw, l(0x00080000, 0x00100000, 0x00200000, 0x00400000) iadd r0.y, r0.y, r8.x iadd r0.y, r8.y, r0.y iadd r0.y, r8.z, r0.y iadd r0.y, r8.w, r0.y ishr r0.z, r1.y, l(8) ishr r0.w, r1.y, l(9) ishr r2.z, r1.z, l(1) ishr r2.w, r1.z, l(2) ishl r8.x, r0.z, l(23) ishl r8.y, r0.w, l(24) ishl r8.z, r2.z, l(26) ishl r8.w, r2.w, l(27) and r8.xyzw, r8.xyzw, l(0x00800000, 0x01000000, 0x04000000, 0x08000000) iadd r0.y, r0.y, r8.x iadd r0.y, r8.y, r0.y iadd r0.y, r7.z, r0.y iadd r0.y, r8.z, r0.y iadd r0.y, r8.w, r0.y ishr r0.z, r1.z, l(3) ishr r0.w, r1.z, l(4) ishr r2.z, r1.z, l(5) ishr r2.w, r1.z, l(6) ishl r7.x, r0.z, l(28) ishl r7.y, r0.w, l(29) ishl r7.z, r2.z, l(30) ishl r0.z, r2.w, l(31) and r7.xyz, r7.xyzx, l(0x10000000, 0x20000000, 0x40000000, 0) iadd r0.y, r0.y, r7.x iadd r0.y, r7.y, r0.y iadd r0.y, r7.z, r0.y iadd r3.x, r0.z, r0.y ishr r0.y, r1.z, l(7) ishr r0.z, r1.z, l(8) ishr r0.w, r1.z, l(9) ishr r2.z, r1.w, l(1) and r0.y, r0.y, l(1) ishl r7.x, r0.z, l(1) ishl r7.y, r0.w, l(2) ishl r7.z, r2.z, l(4) and r7.xyz, r7.xyzx, l(2, 4, 16, 0) iadd r0.y, r0.y, r7.x iadd r0.y, r7.y, r0.y iadd r0.y, r7.w, r0.y iadd r0.y, r7.z, r0.y ishr r0.z, r1.w, l(2) ishr r0.w, r1.w, l(3) ishr r2.zw, r1.xxxy, l(10) ishl r7.x, r0.z, l(5) ishl r7.y, r0.w, l(6) ishl r7.z, r2.z, l(7) ishl r7.w, r2.w, l(18) and r7.xyzw, r7.xyzw, l(32, 64, 128, 0x00040000) iadd r0.y, r0.y, r7.x iadd r0.y, r7.y, r0.y iadd r0.y, r7.z, r0.y ishr r0.z, r6.x, l(4) ishr r0.w, r6.x, l(1) ishr r2.z, r6.x, l(2) ishr r2.w, r6.x, l(3) ishl r8.x, r0.z, l(8) ishl r8.y, r0.w, l(20) ishl r8.z, r2.z, l(21) ishl r8.w, r2.w, l(22) and r8.xyzw, r8.xyzw, l(256, 0x00100000, 0x00200000, 0x00400000) iadd r0.y, r0.y, r8.x ishl r9.x, r5.y, l(9) ishl r9.y, r5.z, l(29) ishl r9.z, r5.x, l(1) ishl r9.w, r5.w, l(7) and r9.xyzw, r9.xyzw, l(512, 0x20000000, 2, 128) iadd r0.y, r0.y, r9.x ishr r0.zw, r5.yyyz, l(1) ishr r2.z, r5.y, l(2) ishr r2.w, r5.y, l(3) ishl r10.x, r0.z, l(10) ishl r10.y, r2.z, l(11) ishl r10.z, r2.w, l(12) ishl r10.w, r0.w, l(30) and r10.xyzw, r10.xyzw, l(1024, 2048, 4096, 0x40000000) iadd r0.y, r0.y, r10.x iadd r0.y, r10.y, r0.y iadd r0.y, r10.z, r0.y ishl r7.x, r4.x, l(13) ishl r7.y, r4.y, l(23) and r0.zw, r7.xxxy, l(0, 0, 8192, 0x00800000) iadd r0.y, r0.z, r0.y ishr r0.z, r4.x, l(1) ishr r2.z, r4.x, l(2) ishr r2.w, r4.x, l(3) ishr r4.z, r4.x, l(4) ishl r11.x, r0.z, l(14) ishl r11.y, r2.z, l(15) ishl r11.z, r2.w, l(16) ishl r11.w, r4.z, l(17) and r11.xyzw, r11.xyzw, l(0x00004000, 0x00008000, 0x00010000, 0x00020000) iadd r0.y, r0.y, r11.x iadd r0.y, r11.y, r0.y iadd r0.y, r11.z, r0.y iadd r0.y, r11.w, r0.y iadd r0.y, r7.w, r0.y ishl r7.x, r6.x, l(19) ishl r7.y, r6.y, l(5) and r2.zw, r7.xxxy, l(0, 0, 0x00080000, 32) iadd r0.y, r0.y, r2.z iadd r0.y, r8.y, r0.y iadd r0.y, r8.z, r0.y iadd r0.y, r8.w, r0.y iadd r0.y, r0.w, r0.y ishr r0.z, r4.y, l(1) ishr r0.w, r4.y, l(2) ishr r2.z, r4.y, l(3) ishl r7.x, r0.z, l(24) ishl r7.y, r0.w, l(25) ishl r7.z, r2.z, l(26) and r7.xyz, r7.xyzx, l(0x01000000, 0x02000000, 0x04000000, 0) iadd r0.y, r0.y, r7.x iadd r0.y, r7.y, r0.y iadd r0.y, r7.z, r0.y ishr r0.z, r1.z, l(10) ishl r0.z, r0.z, l(27) and r0.z, r0.z, l(0x08000000) iadd r0.y, r0.z, r0.y ishr r0.z, r6.y, l(1) ishr r0.w, r6.y, l(2) ishr r2.z, r6.y, l(3) ishl r7.x, r0.z, l(28) ishl r7.y, r0.w, l(6) ishl r7.z, r2.z, l(12) and r7.xyz, r7.xyzx, l(0x10000000, 64, 4096, 0) iadd r0.y, r0.y, r7.x iadd r0.y, r9.y, r0.y iadd r0.y, r10.w, r0.y ishr r0.zw, r5.zzzx, l(2) ishr r2.z, r5.z, l(3) ishr r4.z, r5.x, l(1) ishl r8.x, r0.z, l(31) ishl r8.y, r4.z, l(2) ishl r8.z, r0.w, l(3) iadd r3.z, r0.y, r8.x and r0.y, r2.z, l(1) iadd r0.y, r0.y, r3.w iadd r0.y, r9.z, r0.y and r0.zw, r8.yyyz, l(0, 0, 4, 8) iadd r0.y, r0.z, r0.y iadd r0.y, r0.w, r0.y ishr r0.zw, r5.xxxw, l(3) ishr r2.z, r5.w, l(1) ishr r4.z, r5.w, l(2) ishl r8.x, r0.z, l(4) ishl r8.y, r2.z, l(8) ishl r8.z, r4.z, l(9) ishl r8.w, r0.w, l(10) and r8.xyzw, r8.xyzw, l(16, 256, 512, 1024) iadd r0.y, r0.y, r8.x iadd r0.y, r2.w, r0.y iadd r0.y, r7.y, r0.y iadd r0.y, r9.w, r0.y iadd r0.y, r8.y, r0.y iadd r0.y, r8.z, r0.y iadd r0.y, r8.w, r0.y ishr r0.z, r5.y, l(4) ishl r0.z, r0.z, l(11) and r0.z, r0.z, l(2048) iadd r0.y, r0.z, r0.y iadd r0.y, r7.z, r0.y ishl r0.z, r2.y, l(13) and r0.z, r0.z, l(8192) iadd r0.y, r0.z, r0.y ushr r0.z, r2.y, l(1) ushr r0.w, r2.y, l(2) ushr r2.z, r2.y, l(3) ushr r2.w, r2.y, l(4) ishl r7.x, r0.z, l(14) ishl r7.y, r0.w, l(15) ishl r7.z, r2.z, l(16) ishl r7.w, r2.w, l(17) and r7.xyzw, r7.xyzw, l(0x00004000, 0x00008000, 0x00010000, 0x00020000) iadd r0.y, r0.y, r7.x iadd r0.y, r7.y, r0.y iadd r0.y, r7.z, r0.y iadd r3.w, r7.w, r0.y else ieq r0.y, r2.x, l(5) if_nz r0.y ishl r7.x, r1.x, l(5) ishl r7.y, r1.y, l(15) ishl r7.z, r1.z, l(25) ishl r7.w, r1.w, l(3) and r7.xyzw, r7.xyzw, l(32, 0x00008000, 0x02000000, 8) iadd r0.y, r7.x, l(10) ishr r0.z, r1.x, l(1) ishr r0.w, r1.x, l(2) ishr r2.z, r1.x, l(3) ishr r2.w, r1.x, l(4) ishl r8.x, r0.z, l(6) ishl r8.y, r0.w, l(7) ishl r8.z, r2.z, l(8) ishl r8.w, r2.w, l(9) and r8.xyzw, r8.xyzw, l(64, 128, 256, 512) iadd r0.y, r0.y, r8.x iadd r0.y, r8.y, r0.y iadd r0.y, r8.z, r0.y iadd r0.y, r8.w, r0.y ishr r0.z, r1.x, l(5) ishr r0.w, r1.x, l(6) ishr r2.z, r1.x, l(7) ishr r2.w, r1.x, l(8) ishl r8.x, r0.z, l(10) ishl r8.y, r0.w, l(11) ishl r8.z, r2.z, l(12) ishl r8.w, r2.w, l(13) and r8.xyzw, r8.xyzw, l(1024, 2048, 4096, 8192) iadd r0.y, r0.y, r8.x iadd r0.y, r8.y, r0.y iadd r0.y, r8.z, r0.y iadd r0.y, r8.w, r0.y ishr r0.z, r1.x, l(9) ishr r0.w, r1.y, l(1) ishr r2.z, r1.y, l(2) ishr r2.w, r1.y, l(3) ishl r8.x, r0.z, l(14) ishl r8.y, r0.w, l(16) ishl r8.z, r2.z, l(17) ishl r8.w, r2.w, l(18) and r8.xyzw, r8.xyzw, l(0x00004000, 0x00010000, 0x00020000, 0x00040000) iadd r0.y, r0.y, r8.x iadd r0.y, r7.y, r0.y iadd r0.y, r8.y, r0.y iadd r0.y, r8.z, r0.y iadd r0.y, r8.w, r0.y ishr r0.z, r1.y, l(4) ishr r0.w, r1.y, l(5) ishr r2.z, r1.y, l(6) ishr r2.w, r1.y, l(7) ishl r8.x, r0.z, l(19) ishl r8.y, r0.w, l(20) ishl r8.z, r2.z, l(21) ishl r8.w, r2.w, l(22) and r8.xyzw, r8.xyzw, l(0x00080000, 0x00100000, 0x00200000, 0x00400000) iadd r0.y, r0.y, r8.x iadd r0.y, r8.y, r0.y iadd r0.y, r8.z, r0.y iadd r0.y, r8.w, r0.y ishr r0.z, r1.y, l(8) ishr r0.w, r1.y, l(9) ishr r2.z, r1.z, l(1) ishr r2.w, r1.z, l(2) ishl r8.x, r0.z, l(23) ishl r8.y, r0.w, l(24) ishl r8.z, r2.z, l(26) ishl r8.w, r2.w, l(27) and r8.xyzw, r8.xyzw, l(0x00800000, 0x01000000, 0x04000000, 0x08000000) iadd r0.y, r0.y, r8.x iadd r0.y, r8.y, r0.y iadd r0.y, r7.z, r0.y iadd r0.y, r8.z, r0.y iadd r0.y, r8.w, r0.y ishr r0.z, r1.z, l(3) ishr r0.w, r1.z, l(4) ishr r2.z, r1.z, l(5) ishr r2.w, r1.z, l(6) ishl r7.x, r0.z, l(28) ishl r7.y, r0.w, l(29) ishl r7.z, r2.z, l(30) ishl r0.z, r2.w, l(31) and r7.xyz, r7.xyzx, l(0x10000000, 0x20000000, 0x40000000, 0) iadd r0.y, r0.y, r7.x iadd r0.y, r7.y, r0.y iadd r0.y, r7.z, r0.y iadd r3.x, r0.z, r0.y ishr r0.y, r1.z, l(7) ishr r0.z, r1.z, l(8) ishr r0.w, r1.z, l(9) ishr r2.z, r1.w, l(1) and r0.y, r0.y, l(1) ishl r7.x, r0.z, l(1) ishl r7.y, r0.w, l(2) ishl r7.z, r2.z, l(4) and r7.xyz, r7.xyzx, l(2, 4, 16, 0) iadd r0.y, r0.y, r7.x iadd r0.y, r7.y, r0.y iadd r0.y, r7.w, r0.y iadd r0.y, r7.z, r0.y ishr r0.z, r1.w, l(2) ishr r0.w, r1.w, l(3) ishr r2.zw, r1.xxxy, l(10) ishl r7.x, r0.z, l(5) ishl r7.y, r0.w, l(6) ishl r7.z, r2.z, l(7) ishl r7.w, r2.w, l(17) and r7.xyzw, r7.xyzw, l(32, 64, 128, 0x00020000) iadd r0.y, r0.y, r7.x iadd r0.y, r7.y, r0.y iadd r0.y, r7.z, r0.y ishr r0.z, r5.z, l(4) ishr r0.w, r5.y, l(1) ishr r2.z, r5.y, l(2) ishr r2.w, r5.y, l(3) ishl r8.x, r0.z, l(8) ishl r8.y, r0.w, l(10) ishl r8.z, r2.z, l(11) ishl r8.w, r2.w, l(12) and r8.xyzw, r8.xyzw, l(256, 1024, 2048, 4096) iadd r0.y, r0.y, r8.x ishl r9.x, r5.y, l(9) ishl r9.y, r5.z, l(29) ishl r9.z, r5.x, l(1) ishl r9.w, r5.w, l(7) and r9.xyzw, r9.xyzw, l(512, 0x20000000, 2, 128) iadd r0.y, r0.y, r9.x iadd r0.y, r8.y, r0.y iadd r0.y, r8.z, r0.y iadd r0.y, r8.w, r0.y ishl r7.x, r4.x, l(13) ishl r7.y, r4.y, l(23) and r0.zw, r7.xxxy, l(0, 0, 8192, 0x00800000) iadd r0.y, r0.z, r0.y ishr r2.zw, r4.xxxy, l(1) ishr r0.z, r4.x, l(2) ishr r4.z, r4.x, l(3) ishl r8.x, r2.z, l(14) ishl r8.y, r0.z, l(15) ishl r8.z, r4.z, l(16) ishl r8.w, r2.w, l(24) and r8.xyzw, r8.xyzw, l(0x00004000, 0x00008000, 0x00010000, 0x01000000) iadd r0.y, r0.y, r8.x iadd r0.y, r8.y, r0.y iadd r0.y, r8.z, r0.y iadd r0.y, r7.w, r0.y ishl r7.x, r6.y, l(18) ishl r7.y, r6.x, l(19) and r2.zw, r7.xxxy, l(0, 0, 0x00040000, 0x00080000) iadd r0.y, r0.y, r2.z iadd r0.y, r2.w, r0.y ishr r2.zw, r6.xxxy, l(1) ishr r0.z, r6.x, l(2) ishr r4.z, r6.x, l(3) ishl r7.x, r2.z, l(20) ishl r7.y, r0.z, l(21) ishl r7.z, r4.z, l(22) ishl r7.w, r2.w, l(5) and r7.xyzw, r7.xyzw, l(0x00100000, 0x00200000, 0x00400000, 32) iadd r0.y, r0.y, r7.x iadd r0.y, r7.y, r0.y iadd r0.y, r7.z, r0.y iadd r0.y, r0.w, r0.y iadd r0.y, r8.w, r0.y ishr r0.z, r4.y, l(2) ishr r0.w, r4.y, l(3) ishr r2.z, r4.y, l(4) ishl r7.x, r0.z, l(25) ishl r7.y, r0.w, l(26) ishl r7.z, r2.z, l(27) and r7.xyz, r7.xyzx, l(0x02000000, 0x04000000, 0x08000000, 0) iadd r0.y, r0.y, r7.x iadd r0.y, r7.y, r0.y iadd r0.y, r7.z, r0.y ishr r0.z, r1.z, l(10) ishl r0.z, r0.z, l(28) and r0.z, r0.z, l(0x10000000) iadd r0.y, r0.z, r0.y iadd r0.y, r9.y, r0.y ishr r0.zw, r5.zzzx, l(1) ishr r2.z, r5.z, l(2) ishr r2.w, r5.z, l(3) ishl r7.x, r0.z, l(30) ishl r0.z, r2.z, l(31) ishl r7.z, r0.w, l(2) and r4.zw, r7.xxxz, l(0, 0, 0x40000000, 4) iadd r0.y, r0.y, r4.z iadd r3.z, r0.z, r0.y and r0.y, r2.w, l(1) iadd r0.y, r0.y, r3.w iadd r0.y, r9.z, r0.y iadd r0.y, r4.w, r0.y ishr r0.zw, r5.xxxw, l(2) ishr r2.z, r5.x, l(3) ishr r2.w, r5.w, l(1) ishl r8.x, r0.z, l(3) ishl r8.y, r2.z, l(4) ishl r8.z, r2.w, l(8) ishl r8.w, r0.w, l(9) and r8.xyzw, r8.xyzw, l(8, 16, 256, 512) iadd r0.y, r0.y, r8.x iadd r0.y, r8.y, r0.y iadd r0.y, r7.w, r0.y ishr r0.z, r6.y, l(2) ishr r0.w, r6.y, l(4) ishr r2.z, r6.y, l(3) ishl r7.x, r0.z, l(6) ishl r7.y, r0.w, l(11) ishl r7.z, r2.z, l(12) and r7.xyz, r7.xyzx, l(64, 2048, 4096, 0) iadd r0.y, r0.y, r7.x iadd r0.y, r9.w, r0.y iadd r0.y, r8.z, r0.y iadd r0.y, r8.w, r0.y ishr r0.z, r5.w, l(3) ishl r0.z, r0.z, l(10) and r0.z, r0.z, l(1024) iadd r0.y, r0.z, r0.y iadd r0.y, r7.y, r0.y iadd r0.y, r7.z, r0.y ishl r0.z, r2.y, l(13) and r0.z, r0.z, l(8192) iadd r0.y, r0.z, r0.y ushr r0.z, r2.y, l(1) ushr r0.w, r2.y, l(2) ushr r2.z, r2.y, l(3) ushr r2.w, r2.y, l(4) ishl r7.x, r0.z, l(14) ishl r7.y, r0.w, l(15) ishl r7.z, r2.z, l(16) ishl r7.w, r2.w, l(17) and r7.xyzw, r7.xyzw, l(0x00004000, 0x00008000, 0x00010000, 0x00020000) iadd r0.y, r0.y, r7.x iadd r0.y, r7.y, r0.y iadd r0.y, r7.z, r0.y iadd r3.w, r7.w, r0.y else ieq r0.y, r2.x, l(6) if_nz r0.y ishl r7.x, r1.x, l(5) ishl r7.y, r1.y, l(15) ishl r7.z, r1.z, l(25) ishl r7.w, r1.w, l(3) and r7.xyzw, r7.xyzw, l(32, 0x00008000, 0x02000000, 8) iadd r0.y, r7.x, l(14) ishr r0.z, r1.x, l(1) ishr r0.w, r1.x, l(2) ishr r2.z, r1.x, l(3) ishr r2.w, r1.x, l(4) ishl r8.x, r0.z, l(6) ishl r8.y, r0.w, l(7) ishl r8.z, r2.z, l(8) ishl r8.w, r2.w, l(9) and r8.xyzw, r8.xyzw, l(64, 128, 256, 512) iadd r0.y, r0.y, r8.x iadd r0.y, r8.y, r0.y iadd r0.y, r8.z, r0.y iadd r0.y, r8.w, r0.y ishr r0.z, r1.x, l(5) ishr r0.w, r1.x, l(6) ishr r2.z, r1.x, l(7) ishr r2.w, r1.x, l(8) ishl r8.x, r0.z, l(10) ishl r8.y, r0.w, l(11) ishl r8.z, r2.z, l(12) ishl r8.w, r2.w, l(13) and r8.xyzw, r8.xyzw, l(1024, 2048, 4096, 8192) iadd r0.y, r0.y, r8.x iadd r0.y, r8.y, r0.y iadd r0.y, r8.z, r0.y iadd r0.y, r8.w, r0.y ishr r0.zw, r5.zzzy, l(4) ishr r2.z, r5.y, l(1) ishr r2.w, r5.y, l(2) ishl r8.x, r0.z, l(14) ishl r8.y, r0.w, l(24) ishl r8.z, r2.z, l(10) ishl r8.w, r2.w, l(11) and r8.xyzw, r8.xyzw, l(0x00004000, 0x01000000, 1024, 2048) iadd r0.y, r0.y, r8.x iadd r0.y, r7.y, r0.y ishr r0.z, r1.y, l(1) ishr r0.w, r1.y, l(2) ishr r2.z, r1.y, l(3) ishr r2.w, r1.y, l(4) ishl r9.x, r0.z, l(16) ishl r9.y, r0.w, l(17) ishl r9.z, r2.z, l(18) ishl r9.w, r2.w, l(19) and r9.xyzw, r9.xyzw, l(0x00010000, 0x00020000, 0x00040000, 0x00080000) iadd r0.y, r0.y, r9.x iadd r0.y, r9.y, r0.y iadd r0.y, r9.z, r0.y iadd r0.y, r9.w, r0.y ishr r0.z, r1.y, l(5) ishr r0.w, r1.y, l(6) ishr r2.z, r1.y, l(7) ishr r2.w, r1.y, l(8) ishl r9.x, r0.z, l(20) ishl r9.y, r0.w, l(21) ishl r9.z, r2.z, l(22) ishl r9.w, r2.w, l(23) and r9.xyzw, r9.xyzw, l(0x00100000, 0x00200000, 0x00400000, 0x00800000) iadd r0.y, r0.y, r9.x iadd r0.y, r9.y, r0.y iadd r0.y, r9.z, r0.y iadd r0.y, r9.w, r0.y iadd r0.y, r8.y, r0.y iadd r0.y, r7.z, r0.y ishr r0.z, r1.z, l(1) ishr r0.w, r1.z, l(2) ishr r2.z, r1.z, l(3) ishr r2.w, r1.z, l(4) ishl r9.x, r0.z, l(26) ishl r9.y, r0.w, l(27) ishl r9.z, r2.z, l(28) ishl r9.w, r2.w, l(29) and r9.xyzw, r9.xyzw, l(0x04000000, 0x08000000, 0x10000000, 0x20000000) iadd r0.y, r0.y, r9.x iadd r0.y, r9.y, r0.y iadd r0.y, r9.z, r0.y iadd r0.y, r9.w, r0.y ishr r0.z, r1.z, l(5) ishr r0.w, r1.z, l(6) ishr r2.z, r1.z, l(7) ishr r2.w, r1.z, l(8) ishl r7.x, r0.z, l(30) ishl r0.z, r0.w, l(31) ishl r7.z, r2.w, l(1) and r4.zw, r7.xxxz, l(0, 0, 0x40000000, 2) iadd r0.y, r0.y, r4.z iadd r3.x, r0.z, r0.y and r0.y, r2.z, l(1) iadd r0.y, r4.w, r0.y ishr r0.zw, r6.yyyx, l(4) ishr r2.z, r6.x, l(1) ishr r2.w, r6.x, l(2) ishl r9.x, r0.z, l(2) ishl r9.y, r0.w, l(8) ishl r9.z, r2.z, l(20) ishl r9.w, r2.w, l(21) and r9.xyzw, r9.xyzw, l(4, 256, 0x00100000, 0x00200000) iadd r0.y, r0.y, r9.x iadd r0.y, r7.w, r0.y ishr r0.z, r1.w, l(1) ishr r0.w, r1.w, l(2) ishr r2.z, r1.w, l(3) ishr r2.w, r1.w, l(4) ishl r7.x, r0.z, l(4) ishl r7.y, r0.w, l(5) ishl r7.z, r2.z, l(6) ishl r7.w, r2.w, l(7) and r7.xyzw, r7.xyzw, l(16, 32, 64, 128) iadd r0.y, r0.y, r7.x iadd r0.y, r7.y, r0.y iadd r0.y, r7.z, r0.y iadd r0.y, r7.w, r0.y iadd r0.y, r9.y, r0.y ishl r7.x, r5.y, l(9) ishl r7.y, r5.z, l(29) ishl r7.z, r5.x, l(1) ishl r7.w, r5.w, l(7) and r7.xyzw, r7.xyzw, l(512, 0x20000000, 2, 128) iadd r0.y, r0.y, r7.x iadd r0.y, r8.z, r0.y iadd r0.y, r8.w, r0.y ishr r0.zw, r5.yyyz, l(3) ishr r2.z, r5.z, l(1) ishr r2.w, r5.z, l(2) ishl r8.x, r0.z, l(12) ishl r8.y, r2.z, l(30) ishl r0.z, r2.w, l(31) and r2.zw, r8.xxxy, l(0, 0, 4096, 0x40000000) iadd r0.y, r0.y, r2.z ishl r8.x, r4.x, l(13) ishl r8.y, r4.y, l(23) and r4.zw, r8.xxxy, l(0, 0, 8192, 0x00800000) iadd r0.y, r0.y, r4.z ishr r2.z, r4.x, l(1) ishr r4.z, r4.x, l(2) ishr r6.z, r4.x, l(3) ishr r6.w, r4.x, l(4) ishl r8.x, r2.z, l(14) ishl r8.y, r4.z, l(15) ishl r8.z, r6.z, l(16) ishl r8.w, r6.w, l(17) and r8.xyzw, r8.xyzw, l(0x00004000, 0x00008000, 0x00010000, 0x00020000) iadd r0.y, r0.y, r8.x iadd r0.y, r8.y, r0.y iadd r0.y, r8.z, r0.y iadd r0.y, r8.w, r0.y ishl r8.x, r6.y, l(18) ishl r8.y, r6.x, l(19) and r6.zw, r8.xxxy, l(0, 0, 0x00040000, 0x00080000) iadd r0.y, r0.y, r6.z iadd r0.y, r6.w, r0.y iadd r0.y, r9.z, r0.y iadd r0.y, r9.w, r0.y ishr r6.zw, r6.xxxy, l(3) ishr r2.z, r6.y, l(1) ishr r4.z, r6.y, l(2) ishl r8.x, r6.z, l(22) ishl r8.y, r2.z, l(28) ishl r8.z, r4.z, l(6) ishl r8.w, r6.w, l(12) and r8.xyzw, r8.xyzw, l(0x00400000, 0x10000000, 64, 4096) iadd r0.y, r0.y, r8.x iadd r0.y, r4.w, r0.y ishr r2.z, r4.y, l(1) ishr r4.z, r4.y, l(2) ishr r4.w, r4.y, l(3) ishr r6.z, r4.y, l(4) ishl r9.x, r2.z, l(24) ishl r9.y, r4.z, l(25) ishl r9.z, r4.w, l(26) ishl r9.w, r6.z, l(27) and r9.xyzw, r9.xyzw, l(0x01000000, 0x02000000, 0x04000000, 0x08000000) iadd r0.y, r0.y, r9.x iadd r0.y, r9.y, r0.y iadd r0.y, r9.z, r0.y iadd r0.y, r9.w, r0.y iadd r0.y, r8.y, r0.y iadd r0.y, r7.y, r0.y iadd r0.y, r2.w, r0.y iadd r3.z, r0.z, r0.y and r0.y, r0.w, l(1) iadd r0.y, r0.y, r3.w iadd r0.y, r7.z, r0.y ishr r0.z, r5.x, l(1) ishr r0.w, r5.x, l(2) ishr r2.z, r5.x, l(3) ishr r2.w, r5.x, l(4) ishl r9.x, r0.z, l(2) ishl r9.y, r0.w, l(3) ishl r9.z, r2.z, l(4) ishl r9.w, r2.w, l(5) and r9.xyzw, r9.xyzw, l(4, 8, 16, 32) iadd r0.y, r0.y, r9.x iadd r0.y, r9.y, r0.y iadd r0.y, r9.z, r0.y iadd r0.y, r9.w, r0.y iadd r0.y, r8.z, r0.y iadd r0.y, r7.w, r0.y ishr r0.z, r5.w, l(1) ishr r0.w, r5.w, l(2) ishr r2.z, r5.w, l(3) ishr r2.w, r5.w, l(4) ishl r7.x, r0.z, l(8) ishl r7.y, r0.w, l(9) ishl r7.z, r2.z, l(10) ishl r7.w, r2.w, l(11) and r7.xyzw, r7.xyzw, l(256, 512, 1024, 2048) iadd r0.y, r0.y, r7.x iadd r0.y, r7.y, r0.y iadd r0.y, r7.z, r0.y iadd r0.y, r7.w, r0.y iadd r0.y, r8.w, r0.y ishl r0.z, r2.y, l(13) and r0.z, r0.z, l(8192) iadd r0.y, r0.z, r0.y ushr r0.z, r2.y, l(1) ushr r0.w, r2.y, l(2) ushr r2.z, r2.y, l(3) ushr r2.w, r2.y, l(4) ishl r7.x, r0.z, l(14) ishl r7.y, r0.w, l(15) ishl r7.z, r2.z, l(16) ishl r7.w, r2.w, l(17) and r7.xyzw, r7.xyzw, l(0x00004000, 0x00008000, 0x00010000, 0x00020000) iadd r0.y, r0.y, r7.x iadd r0.y, r7.y, r0.y iadd r0.y, r7.z, r0.y iadd r3.w, r7.w, r0.y else ieq r0.y, r2.x, l(7) if_nz r0.y ishl r7.x, r1.x, l(5) ishl r7.y, r1.y, l(15) ishl r7.z, r1.z, l(25) ishl r7.w, r1.w, l(3) and r7.xyzw, r7.xyzw, l(32, 0x00008000, 0x02000000, 8) iadd r0.y, r7.x, l(18) ishr r0.z, r1.x, l(1) ishr r0.w, r1.x, l(2) ishr r2.z, r1.x, l(3) ishr r2.w, r1.x, l(4) ishl r8.x, r0.z, l(6) ishl r8.y, r0.w, l(7) ishl r8.z, r2.z, l(8) ishl r8.w, r2.w, l(9) and r8.xyzw, r8.xyzw, l(64, 128, 256, 512) iadd r0.y, r0.y, r8.x iadd r0.y, r8.y, r0.y iadd r0.y, r8.z, r0.y iadd r0.y, r8.w, r0.y ishr r0.z, r1.x, l(5) ishr r0.w, r1.x, l(6) ishr r2.z, r1.x, l(7) ishr r2.w, r1.y, l(1) ishl r8.x, r0.z, l(10) ishl r8.y, r0.w, l(11) ishl r8.z, r2.z, l(12) ishl r8.w, r2.w, l(16) and r8.xyzw, r8.xyzw, l(1024, 2048, 4096, 0x00010000) iadd r0.y, r0.y, r8.x iadd r0.y, r8.y, r0.y iadd r0.y, r8.z, r0.y ishr r0.zw, r6.xxxy, l(4) ishr r2.z, r6.y, l(2) ishr r2.w, r6.y, l(3) ishl r9.x, r0.z, l(13) ishl r9.y, r2.z, l(23) ishl r9.z, r2.w, l(1) ishl r9.w, r0.w, l(2) and r9.xyzw, r9.xyzw, l(8192, 0x00800000, 2, 4) iadd r0.y, r0.y, r9.x ishr r0.zw, r5.zzzy, l(4) ishr r2.z, r5.y, l(1) ishr r2.w, r5.y, l(2) ishl r10.x, r0.z, l(14) ishl r10.y, r0.w, l(24) ishl r10.z, r2.z, l(10) ishl r10.w, r2.w, l(11) and r10.xyzw, r10.xyzw, l(0x00004000, 0x01000000, 1024, 2048) iadd r0.y, r0.y, r10.x iadd r0.y, r7.y, r0.y iadd r0.y, r8.w, r0.y ishr r0.z, r1.y, l(2) ishr r0.w, r1.y, l(3) ishr r2.z, r1.y, l(4) ishr r2.w, r1.y, l(5) ishl r8.x, r0.z, l(17) ishl r8.y, r0.w, l(18) ishl r8.z, r2.z, l(19) ishl r8.w, r2.w, l(20) and r8.xyzw, r8.xyzw, l(0x00020000, 0x00040000, 0x00080000, 0x00100000) iadd r0.y, r0.y, r8.x iadd r0.y, r8.y, r0.y iadd r0.y, r8.z, r0.y iadd r0.y, r8.w, r0.y ishr r0.z, r1.y, l(6) ishr r0.w, r1.y, l(7) ishr r2.z, r1.z, l(1) ishr r2.w, r1.z, l(2) ishl r8.x, r0.z, l(21) ishl r8.y, r0.w, l(22) ishl r8.z, r2.z, l(26) ishl r8.w, r2.w, l(27) and r8.xyzw, r8.xyzw, l(0x00200000, 0x00400000, 0x04000000, 0x08000000) iadd r0.y, r0.y, r8.x iadd r0.y, r8.y, r0.y iadd r0.y, r9.y, r0.y iadd r0.y, r10.y, r0.y iadd r0.y, r7.z, r0.y iadd r0.y, r8.z, r0.y iadd r0.y, r8.w, r0.y ishr r0.z, r1.z, l(3) ishr r0.w, r1.z, l(4) ishr r2.z, r1.z, l(5) ishr r2.w, r1.z, l(6) ishl r7.x, r0.z, l(28) ishl r7.y, r0.w, l(29) ishl r7.z, r2.z, l(30) ishl r0.z, r2.w, l(31) and r7.xyz, r7.xyzx, l(0x10000000, 0x20000000, 0x40000000, 0) iadd r0.y, r0.y, r7.x iadd r0.y, r7.y, r0.y iadd r0.y, r7.z, r0.y iadd r3.x, r0.z, r0.y ishr r0.y, r1.z, l(7) ishr r0.z, r1.w, l(1) ishr r0.w, r1.w, l(2) ishr r2.z, r1.w, l(3) and r0.y, r0.y, l(1) iadd r0.y, r9.z, r0.y iadd r0.y, r9.w, r0.y iadd r0.y, r7.w, r0.y ishl r7.x, r0.z, l(4) ishl r7.y, r0.w, l(5) ishl r7.z, r2.z, l(6) and r7.xyz, r7.xyzx, l(16, 32, 64, 0) iadd r0.y, r0.y, r7.x iadd r0.y, r7.y, r0.y iadd r0.y, r7.z, r0.y ishr r0.z, r1.w, l(4) ishr r0.w, r1.w, l(5) ishl r7.x, r0.z, l(7) ishl r7.y, r0.w, l(8) and r0.zw, r7.xxxy, l(0, 0, 128, 256) iadd r0.y, r0.z, r0.y iadd r0.y, r0.w, r0.y ishl r7.x, r5.y, l(9) ishl r7.y, r5.z, l(29) ishl r7.z, r5.x, l(1) ishl r7.w, r5.w, l(7) and r7.xyzw, r7.xyzw, l(512, 0x20000000, 2, 128) iadd r0.y, r0.y, r7.x iadd r0.y, r10.z, r0.y iadd r0.y, r10.w, r0.y ishr r0.zw, r5.yyyz, l(3) ishr r2.z, r5.z, l(1) ishr r2.w, r5.z, l(2) ishl r8.x, r0.z, l(12) ishl r8.y, r2.z, l(30) ishl r0.z, r2.w, l(31) and r2.zw, r8.xxxy, l(0, 0, 4096, 0x40000000) iadd r0.y, r0.y, r2.z ishl r8.x, r4.x, l(13) ishl r8.y, r4.y, l(23) and r4.zw, r8.xxxy, l(0, 0, 8192, 0x00800000) iadd r0.y, r0.y, r4.z ishr r2.z, r4.x, l(1) ishr r4.z, r4.x, l(2) ishr r6.z, r4.x, l(3) ishr r6.w, r4.x, l(4) ishl r8.x, r2.z, l(14) ishl r8.y, r4.z, l(15) ishl r8.z, r6.z, l(16) ishl r8.w, r6.w, l(17) and r8.xyzw, r8.xyzw, l(0x00004000, 0x00008000, 0x00010000, 0x00020000) iadd r0.y, r0.y, r8.x iadd r0.y, r8.y, r0.y iadd r0.y, r8.z, r0.y iadd r0.y, r8.w, r0.y ishl r8.x, r6.y, l(18) ishl r8.y, r6.x, l(19) and r6.zw, r8.xxxy, l(0, 0, 0x00040000, 0x00080000) iadd r0.y, r0.y, r6.z iadd r0.y, r6.w, r0.y ishr r6.zw, r6.xxxy, l(1) ishr r2.z, r6.x, l(2) ishr r4.z, r6.x, l(3) ishl r8.x, r6.z, l(20) ishl r8.y, r2.z, l(21) ishl r8.z, r4.z, l(22) ishl r8.w, r6.w, l(28) and r8.xyzw, r8.xyzw, l(0x00100000, 0x00200000, 0x00400000, 0x10000000) iadd r0.y, r0.y, r8.x iadd r0.y, r8.y, r0.y iadd r0.y, r8.z, r0.y iadd r0.y, r4.w, r0.y ishr r2.z, r4.y, l(1) ishr r4.z, r4.y, l(2) ishr r4.w, r4.y, l(3) ishr r6.z, r4.y, l(4) ishl r9.x, r2.z, l(24) ishl r9.y, r4.z, l(25) ishl r9.z, r4.w, l(26) ishl r9.w, r6.z, l(27) and r9.xyzw, r9.xyzw, l(0x01000000, 0x02000000, 0x04000000, 0x08000000) iadd r0.y, r0.y, r9.x iadd r0.y, r9.y, r0.y iadd r0.y, r9.z, r0.y iadd r0.y, r9.w, r0.y iadd r0.y, r8.w, r0.y iadd r0.y, r7.y, r0.y iadd r0.y, r2.w, r0.y iadd r3.z, r0.z, r0.y and r0.y, r0.w, l(1) iadd r0.y, r0.y, r3.w iadd r0.y, r7.z, r0.y ishr r0.z, r5.x, l(1) ishr r0.w, r5.x, l(2) ishr r2.z, r5.x, l(3) ishr r2.w, r5.x, l(4) ishl r8.x, r0.z, l(2) ishl r8.y, r0.w, l(3) ishl r8.z, r2.z, l(4) ishl r8.w, r2.w, l(5) and r8.xyzw, r8.xyzw, l(4, 8, 16, 32) iadd r0.y, r0.y, r8.x iadd r0.y, r8.y, r0.y iadd r0.y, r8.z, r0.y iadd r0.y, r8.w, r0.y ishr r0.z, r5.x, l(5) ishr r0.w, r5.w, l(1) ishr r2.z, r5.w, l(2) ishr r2.w, r5.w, l(3) ishl r8.x, r0.z, l(6) ishl r8.y, r0.w, l(8) ishl r8.z, r2.z, l(9) ishl r8.w, r2.w, l(10) and r8.xyzw, r8.xyzw, l(64, 256, 512, 1024) iadd r0.y, r0.y, r8.x iadd r0.y, r7.w, r0.y iadd r0.y, r8.y, r0.y iadd r0.y, r8.z, r0.y iadd r0.y, r8.w, r0.y ishr r0.z, r5.w, l(4) ishr r0.w, r5.w, l(5) ishl r7.x, r0.z, l(11) ishl r7.y, r0.w, l(12) and r0.zw, r7.xxxy, l(0, 0, 2048, 4096) iadd r0.y, r0.z, r0.y iadd r0.y, r0.w, r0.y ishl r0.z, r2.y, l(13) and r0.z, r0.z, l(8192) iadd r0.y, r0.z, r0.y ushr r0.z, r2.y, l(1) ushr r0.w, r2.y, l(2) ushr r2.z, r2.y, l(3) ushr r2.w, r2.y, l(4) ishl r7.x, r0.z, l(14) ishl r7.y, r0.w, l(15) ishl r7.z, r2.z, l(16) ishl r7.w, r2.w, l(17) and r7.xyzw, r7.xyzw, l(0x00004000, 0x00008000, 0x00010000, 0x00020000) iadd r0.y, r0.y, r7.x iadd r0.y, r7.y, r0.y iadd r0.y, r7.z, r0.y iadd r3.w, r7.w, r0.y else ieq r0.y, r2.x, l(8) if_nz r0.y ishl r7.x, r1.x, l(5) ishl r7.y, r1.y, l(15) ishl r7.z, r1.z, l(25) ishl r7.w, r1.w, l(3) and r7.xyzw, r7.xyzw, l(32, 0x00008000, 0x02000000, 8) iadd r0.y, r7.x, l(22) ishr r0.z, r1.x, l(1) ishr r0.w, r1.x, l(2) ishr r2.z, r1.x, l(3) ishr r2.w, r1.x, l(4) ishl r8.x, r0.z, l(6) ishl r8.y, r0.w, l(7) ishl r8.z, r2.z, l(8) ishl r8.w, r2.w, l(9) and r8.xyzw, r8.xyzw, l(64, 128, 256, 512) iadd r0.y, r0.y, r8.x iadd r0.y, r8.y, r0.y iadd r0.y, r8.z, r0.y iadd r0.y, r8.w, r0.y ishr r0.z, r1.x, l(5) ishr r0.w, r1.x, l(6) ishr r2.z, r1.x, l(7) ishr r2.w, r1.y, l(1) ishl r8.x, r0.z, l(10) ishl r8.y, r0.w, l(11) ishl r8.z, r2.z, l(12) ishl r8.w, r2.w, l(16) and r8.xyzw, r8.xyzw, l(1024, 2048, 4096, 0x00010000) iadd r0.y, r0.y, r8.x iadd r0.y, r8.y, r0.y iadd r0.y, r8.z, r0.y ishl r8.x, r6.y, l(13) ishl r8.y, r6.x, l(19) and r0.zw, r8.xxxy, l(0, 0, 8192, 0x00080000) iadd r0.y, r0.z, r0.y ishr r2.zw, r5.zzzy, l(4) ishr r0.z, r5.y, l(5) ishr r4.z, r5.y, l(1) ishl r9.x, r2.z, l(14) ishl r9.y, r0.z, l(23) ishl r9.z, r2.w, l(24) ishl r9.w, r4.z, l(10) and r9.xyzw, r9.xyzw, l(0x00004000, 0x00800000, 0x01000000, 1024) iadd r0.y, r0.y, r9.x iadd r0.y, r7.y, r0.y iadd r0.y, r8.w, r0.y ishr r0.z, r1.y, l(2) ishr r2.z, r1.y, l(3) ishr r2.w, r1.y, l(4) ishr r4.z, r1.y, l(5) ishl r8.x, r0.z, l(17) ishl r8.y, r2.z, l(18) ishl r8.z, r2.w, l(19) ishl r8.w, r4.z, l(20) and r8.xyzw, r8.xyzw, l(0x00020000, 0x00040000, 0x00080000, 0x00100000) iadd r0.y, r0.y, r8.x iadd r0.y, r8.y, r0.y iadd r0.y, r8.z, r0.y iadd r0.y, r8.w, r0.y ishr r0.z, r1.y, l(6) ishr r2.z, r1.y, l(7) ishr r2.w, r1.z, l(1) ishr r4.z, r1.z, l(2) ishl r8.x, r0.z, l(21) ishl r8.y, r2.z, l(22) ishl r8.z, r2.w, l(26) ishl r8.w, r4.z, l(27) and r8.xyzw, r8.xyzw, l(0x00200000, 0x00400000, 0x04000000, 0x08000000) iadd r0.y, r0.y, r8.x iadd r0.y, r8.y, r0.y iadd r0.y, r9.y, r0.y iadd r0.y, r9.z, r0.y iadd r0.y, r7.z, r0.y iadd r0.y, r8.z, r0.y iadd r0.y, r8.w, r0.y ishr r0.z, r1.z, l(3) ishr r2.z, r1.z, l(4) ishr r2.w, r1.z, l(5) ishr r4.z, r1.z, l(6) ishl r7.x, r0.z, l(28) ishl r7.y, r2.z, l(29) ishl r7.z, r2.w, l(30) ishl r0.z, r4.z, l(31) and r7.xyz, r7.xyzx, l(0x10000000, 0x20000000, 0x40000000, 0) iadd r0.y, r0.y, r7.x iadd r0.y, r7.y, r0.y iadd r0.y, r7.z, r0.y iadd r3.x, r0.z, r0.y ishr r0.y, r1.z, l(7) ishr r0.z, r1.w, l(1) ishr r2.z, r1.w, l(2) ishr r2.w, r1.w, l(3) and r0.y, r0.y, l(1) ishr r4.z, r6.x, l(5) ishr r6.zw, r6.yyyx, l(4) ishr r4.w, r6.x, l(1) ishl r8.x, r4.z, l(1) ishl r8.y, r6.z, l(2) ishl r8.z, r6.w, l(8) ishl r8.w, r4.w, l(20) and r8.xyzw, r8.xyzw, l(2, 4, 256, 0x00100000) iadd r0.y, r0.y, r8.x iadd r0.y, r8.y, r0.y iadd r0.y, r7.w, r0.y ishl r7.x, r0.z, l(4) ishl r7.y, r2.z, l(5) ishl r7.z, r2.w, l(6) and r7.xyz, r7.xyzx, l(16, 32, 64, 0) iadd r0.y, r0.y, r7.x iadd r0.y, r7.y, r0.y iadd r0.y, r7.z, r0.y ishr r0.z, r1.w, l(4) ishl r0.z, r0.z, l(7) and r0.z, r0.z, l(128) iadd r0.y, r0.z, r0.y iadd r0.y, r8.z, r0.y ishl r7.x, r5.y, l(9) ishl r7.y, r5.z, l(29) ishl r7.z, r5.x, l(1) ishl r7.w, r5.w, l(7) and r7.xyzw, r7.xyzw, l(512, 0x20000000, 2, 128) iadd r0.y, r0.y, r7.x iadd r0.y, r9.w, r0.y ishr r2.zw, r5.yyyz, l(2) ishr r0.z, r5.y, l(3) ishr r4.z, r5.z, l(1) ishl r8.x, r2.z, l(11) ishl r8.y, r0.z, l(12) ishl r8.z, r4.z, l(30) ishl r0.z, r2.w, l(31) and r8.xyz, r8.xyzx, l(2048, 4096, 0x40000000, 0) iadd r0.y, r0.y, r8.x iadd r0.y, r8.y, r0.y ishl r8.x, r4.x, l(13) ishl r8.y, r4.y, l(23) and r2.zw, r8.xxxy, l(0, 0, 8192, 0x00800000) iadd r0.y, r0.y, r2.z ishr r2.z, r4.x, l(1) ishr r4.z, r4.x, l(2) ishr r4.w, r4.x, l(3) ishr r6.z, r4.x, l(4) ishl r9.x, r2.z, l(14) ishl r9.y, r4.z, l(15) ishl r9.z, r4.w, l(16) ishl r9.w, r6.z, l(17) and r9.xyzw, r9.xyzw, l(0x00004000, 0x00008000, 0x00010000, 0x00020000) iadd r0.y, r0.y, r9.x iadd r0.y, r9.y, r0.y iadd r0.y, r9.z, r0.y iadd r0.y, r9.w, r0.y ishr r2.z, r4.x, l(5) ishr r4.z, r4.y, l(1) ishr r4.w, r4.y, l(2) ishr r6.z, r4.y, l(3) ishl r9.x, r2.z, l(18) ishl r9.y, r4.z, l(24) ishl r9.z, r4.w, l(25) ishl r9.w, r6.z, l(26) and r9.xyzw, r9.xyzw, l(0x00040000, 0x01000000, 0x02000000, 0x04000000) iadd r0.y, r0.y, r9.x iadd r0.y, r0.w, r0.y iadd r0.y, r8.w, r0.y ishr r4.zw, r6.xxxy, l(2) ishr r0.w, r6.x, l(3) ishr r2.z, r6.y, l(1) ishl r10.x, r4.z, l(21) ishl r10.y, r0.w, l(22) ishl r10.z, r2.z, l(28) ishl r10.w, r4.w, l(6) and r10.xyzw, r10.xyzw, l(0x00200000, 0x00400000, 0x10000000, 64) iadd r0.y, r0.y, r10.x iadd r0.y, r10.y, r0.y iadd r0.y, r2.w, r0.y iadd r0.y, r9.y, r0.y iadd r0.y, r9.z, r0.y iadd r0.y, r9.w, r0.y ishr r0.w, r4.y, l(4) ishl r0.w, r0.w, l(27) and r0.w, r0.w, l(0x08000000) iadd r0.y, r0.w, r0.y iadd r0.y, r10.z, r0.y iadd r0.y, r7.y, r0.y iadd r0.y, r8.z, r0.y iadd r3.z, r0.z, r0.y ishr r0.yz, r5.zzxz, l(3) ishr r0.w, r5.x, l(1) ishr r2.z, r5.x, l(2) and r0.y, r0.y, l(1) iadd r0.y, r0.y, r3.w iadd r0.y, r7.z, r0.y ishl r7.x, r0.w, l(2) ishl r7.y, r2.z, l(3) ishl r7.z, r0.z, l(4) and r7.xyz, r7.xyzx, l(4, 8, 16, 0) iadd r0.y, r0.y, r7.x iadd r0.y, r7.y, r0.y iadd r0.y, r7.z, r0.y ishr r0.z, r5.x, l(4) ishr r0.w, r5.w, l(1) ishr r2.z, r5.w, l(2) ishr r2.w, r5.w, l(3) ishl r8.x, r0.z, l(5) ishl r8.y, r0.w, l(8) ishl r8.z, r2.z, l(9) ishl r8.w, r2.w, l(10) and r8.xyzw, r8.xyzw, l(32, 256, 512, 1024) iadd r0.y, r0.y, r8.x iadd r0.y, r10.w, r0.y iadd r0.y, r7.w, r0.y iadd r0.y, r8.y, r0.y iadd r0.y, r8.z, r0.y iadd r0.y, r8.w, r0.y ishr r0.z, r5.w, l(4) ishl r0.z, r0.z, l(11) and r0.z, r0.z, l(2048) iadd r0.y, r0.z, r0.y ishr r0.z, r6.y, l(3) ishl r0.z, r0.z, l(12) and r0.z, r0.z, l(4096) iadd r0.y, r0.z, r0.y ishl r0.z, r2.y, l(13) and r0.z, r0.z, l(8192) iadd r0.y, r0.z, r0.y ushr r0.z, r2.y, l(1) ushr r0.w, r2.y, l(2) ushr r2.z, r2.y, l(3) ushr r2.w, r2.y, l(4) ishl r7.x, r0.z, l(14) ishl r7.y, r0.w, l(15) ishl r7.z, r2.z, l(16) ishl r7.w, r2.w, l(17) and r7.xyzw, r7.xyzw, l(0x00004000, 0x00008000, 0x00010000, 0x00020000) iadd r0.y, r0.y, r7.x iadd r0.y, r7.y, r0.y iadd r0.y, r7.z, r0.y iadd r3.w, r7.w, r0.y else ieq r0.y, r2.x, l(9) if_nz r0.y ishl r7.x, r1.x, l(5) ishl r7.y, r1.y, l(15) ishl r7.z, r1.z, l(25) ishl r7.w, r1.w, l(3) and r7.xyzw, r7.xyzw, l(32, 0x00008000, 0x02000000, 8) iadd r0.y, r7.x, l(26) ishr r0.z, r1.x, l(1) ishr r0.w, r1.x, l(2) ishr r2.z, r1.x, l(3) ishr r2.w, r1.x, l(4) ishl r8.x, r0.z, l(6) ishl r8.y, r0.w, l(7) ishl r8.z, r2.z, l(8) ishl r8.w, r2.w, l(9) and r8.xyzw, r8.xyzw, l(64, 128, 256, 512) iadd r0.y, r0.y, r8.x iadd r0.y, r8.y, r0.y iadd r0.y, r8.z, r0.y iadd r0.y, r8.w, r0.y ishr r0.z, r1.x, l(5) ishr r0.w, r1.x, l(6) ishr r2.z, r1.x, l(7) ishr r2.w, r1.y, l(1) ishl r8.x, r0.z, l(10) ishl r8.y, r0.w, l(11) ishl r8.z, r2.z, l(12) ishl r8.w, r2.w, l(16) and r8.xyzw, r8.xyzw, l(1024, 2048, 4096, 0x00010000) iadd r0.y, r0.y, r8.x iadd r0.y, r8.y, r0.y iadd r0.y, r8.z, r0.y ishr r0.z, r6.y, l(1) ishr r0.w, r6.y, l(5) ishr r2.zw, r6.yyyx, l(4) ishl r9.x, r0.z, l(13) ishl r9.y, r0.w, l(1) ishl r9.z, r2.z, l(2) ishl r9.w, r2.w, l(8) and r9.xyzw, r9.xyzw, l(8192, 2, 4, 256) iadd r0.y, r0.y, r9.x ishr r0.zw, r5.zzzy, l(4) ishr r2.z, r5.z, l(5) ishr r2.w, r5.y, l(1) ishl r10.x, r0.z, l(14) ishl r10.y, r2.z, l(23) ishl r10.z, r0.w, l(24) ishl r10.w, r2.w, l(10) and r10.xyzw, r10.xyzw, l(0x00004000, 0x00800000, 0x01000000, 1024) iadd r0.y, r0.y, r10.x iadd r0.y, r7.y, r0.y iadd r0.y, r8.w, r0.y ishr r0.z, r1.y, l(2) ishr r0.w, r1.y, l(3) ishr r2.z, r1.y, l(4) ishr r2.w, r1.y, l(5) ishl r8.x, r0.z, l(17) ishl r8.y, r0.w, l(18) ishl r8.z, r2.z, l(19) ishl r8.w, r2.w, l(20) and r8.xyzw, r8.xyzw, l(0x00020000, 0x00040000, 0x00080000, 0x00100000) iadd r0.y, r0.y, r8.x iadd r0.y, r8.y, r0.y iadd r0.y, r8.z, r0.y iadd r0.y, r8.w, r0.y ishr r0.z, r1.y, l(6) ishr r0.w, r1.y, l(7) ishr r2.z, r1.z, l(1) ishr r2.w, r1.z, l(2) ishl r8.x, r0.z, l(21) ishl r8.y, r0.w, l(22) ishl r8.z, r2.z, l(26) ishl r8.w, r2.w, l(27) and r8.xyzw, r8.xyzw, l(0x00200000, 0x00400000, 0x04000000, 0x08000000) iadd r0.y, r0.y, r8.x iadd r0.y, r8.y, r0.y iadd r0.y, r10.y, r0.y iadd r0.y, r10.z, r0.y iadd r0.y, r7.z, r0.y iadd r0.y, r8.z, r0.y iadd r0.y, r8.w, r0.y ishr r0.z, r1.z, l(3) ishr r0.w, r1.z, l(4) ishr r2.z, r1.z, l(5) ishr r2.w, r1.z, l(6) ishl r7.x, r0.z, l(28) ishl r7.y, r0.w, l(29) ishl r7.z, r2.z, l(30) ishl r0.z, r2.w, l(31) and r7.xyz, r7.xyzx, l(0x10000000, 0x20000000, 0x40000000, 0) iadd r0.y, r0.y, r7.x iadd r0.y, r7.y, r0.y iadd r0.y, r7.z, r0.y iadd r3.x, r0.z, r0.y ishr r0.y, r1.z, l(7) ishr r0.z, r1.w, l(1) ishr r0.w, r1.w, l(2) ishr r2.z, r1.w, l(3) and r0.y, r0.y, l(1) iadd r0.y, r9.y, r0.y iadd r0.y, r9.z, r0.y iadd r0.y, r7.w, r0.y ishl r7.x, r0.z, l(4) ishl r7.y, r0.w, l(5) ishl r7.z, r2.z, l(6) and r7.xyz, r7.xyzx, l(16, 32, 64, 0) iadd r0.y, r0.y, r7.x iadd r0.y, r7.y, r0.y iadd r0.y, r7.z, r0.y ishr r0.z, r1.w, l(4) ishl r0.z, r0.z, l(7) and r0.z, r0.z, l(128) iadd r0.y, r0.z, r0.y iadd r0.y, r9.w, r0.y ishl r7.x, r5.y, l(9) ishl r7.y, r5.z, l(29) ishl r7.z, r5.x, l(1) ishl r7.w, r5.w, l(7) and r7.xyzw, r7.xyzw, l(512, 0x20000000, 2, 128) iadd r0.y, r0.y, r7.x iadd r0.y, r10.w, r0.y ishr r0.zw, r5.yyyz, l(2) ishr r2.z, r5.y, l(3) ishr r2.w, r5.z, l(1) ishl r8.x, r0.z, l(11) ishl r8.y, r2.z, l(12) ishl r8.z, r2.w, l(30) ishl r0.z, r0.w, l(31) and r8.xyz, r8.xyzx, l(2048, 4096, 0x40000000, 0) iadd r0.y, r0.y, r8.x iadd r0.y, r8.y, r0.y ishl r8.x, r4.x, l(13) ishl r8.y, r4.y, l(23) and r2.zw, r8.xxxy, l(0, 0, 8192, 0x00800000) iadd r0.y, r0.y, r2.z ishr r0.w, r4.x, l(1) ishr r2.z, r4.x, l(2) ishr r4.z, r4.x, l(3) ishr r4.w, r4.x, l(4) ishl r9.x, r0.w, l(14) ishl r9.y, r2.z, l(15) ishl r9.z, r4.z, l(16) ishl r9.w, r4.w, l(17) and r9.xyzw, r9.xyzw, l(0x00004000, 0x00008000, 0x00010000, 0x00020000) iadd r0.y, r0.y, r9.x iadd r0.y, r9.y, r0.y iadd r0.y, r9.z, r0.y iadd r0.y, r9.w, r0.y ishl r8.x, r6.y, l(18) ishl r8.y, r6.x, l(19) and r4.zw, r8.xxxy, l(0, 0, 0x00040000, 0x00080000) iadd r0.y, r0.y, r4.z iadd r0.y, r4.w, r0.y ishr r0.w, r6.x, l(1) ishr r4.zw, r6.xxxy, l(2) ishr r2.z, r6.x, l(3) ishl r9.x, r0.w, l(20) ishl r9.y, r4.z, l(21) ishl r9.z, r2.z, l(22) ishl r9.w, r4.w, l(6) and r9.xyzw, r9.xyzw, l(0x00100000, 0x00200000, 0x00400000, 64) iadd r0.y, r0.y, r9.x iadd r0.y, r9.y, r0.y iadd r0.y, r9.z, r0.y iadd r0.y, r2.w, r0.y ishr r0.w, r4.y, l(1) ishr r2.z, r4.y, l(2) ishr r2.w, r4.y, l(3) ishr r4.z, r4.y, l(4) ishl r10.x, r0.w, l(24) ishl r10.y, r2.z, l(25) ishl r10.z, r2.w, l(26) ishl r10.w, r4.z, l(27) and r10.xyzw, r10.xyzw, l(0x01000000, 0x02000000, 0x04000000, 0x08000000) iadd r0.y, r0.y, r10.x iadd r0.y, r10.y, r0.y iadd r0.y, r10.z, r0.y iadd r0.y, r10.w, r0.y ishr r0.w, r4.y, l(5) ishl r0.w, r0.w, l(28) and r0.w, r0.w, l(0x10000000) iadd r0.y, r0.w, r0.y iadd r0.y, r7.y, r0.y iadd r0.y, r8.z, r0.y iadd r3.z, r0.z, r0.y ishr r0.yz, r5.zzxz, l(3) ishr r0.w, r5.x, l(1) ishr r2.z, r5.x, l(2) and r0.y, r0.y, l(1) iadd r0.y, r0.y, r3.w iadd r0.y, r7.z, r0.y ishl r7.x, r0.w, l(2) ishl r7.y, r2.z, l(3) ishl r7.z, r0.z, l(4) and r7.xyz, r7.xyzx, l(4, 8, 16, 0) iadd r0.y, r0.y, r7.x iadd r0.y, r7.y, r0.y iadd r0.y, r7.z, r0.y ishr r0.z, r5.x, l(4) ishr r0.w, r5.w, l(1) ishr r2.z, r5.w, l(2) ishr r2.w, r5.w, l(3) ishl r8.x, r0.z, l(5) ishl r8.y, r0.w, l(8) ishl r8.z, r2.z, l(9) ishl r8.w, r2.w, l(10) and r8.xyzw, r8.xyzw, l(32, 256, 512, 1024) iadd r0.y, r0.y, r8.x iadd r0.y, r9.w, r0.y iadd r0.y, r7.w, r0.y iadd r0.y, r8.y, r0.y iadd r0.y, r8.z, r0.y iadd r0.y, r8.w, r0.y ishr r0.z, r5.w, l(4) ishl r0.z, r0.z, l(11) and r0.z, r0.z, l(2048) iadd r0.y, r0.z, r0.y ishr r0.z, r6.y, l(3) ishl r0.z, r0.z, l(12) and r0.z, r0.z, l(4096) iadd r0.y, r0.z, r0.y ishl r0.z, r2.y, l(13) and r0.z, r0.z, l(8192) iadd r0.y, r0.z, r0.y ushr r0.z, r2.y, l(1) ushr r0.w, r2.y, l(2) ushr r2.z, r2.y, l(3) ushr r2.w, r2.y, l(4) ishl r7.x, r0.z, l(14) ishl r7.y, r0.w, l(15) ishl r7.z, r2.z, l(16) ishl r7.w, r2.w, l(17) and r7.xyzw, r7.xyzw, l(0x00004000, 0x00008000, 0x00010000, 0x00020000) iadd r0.y, r0.y, r7.x iadd r0.y, r7.y, r0.y iadd r0.y, r7.z, r0.y iadd r3.w, r7.w, r0.y else ieq r0.y, r2.x, l(10) if_nz r0.y ishl r7.x, r1.x, l(5) ishl r7.y, r1.y, l(15) ishl r7.z, r1.z, l(25) ishl r7.w, r1.w, l(3) and r7.xyzw, r7.xyzw, l(32, 0x00008000, 0x02000000, 8) iadd r0.y, r7.x, l(30) ishr r0.z, r1.x, l(1) ishr r0.w, r1.x, l(2) ishr r2.x, r1.x, l(3) ishr r2.z, r1.x, l(4) ishl r8.x, r0.z, l(6) ishl r8.y, r0.w, l(7) ishl r8.z, r2.x, l(8) ishl r8.w, r2.z, l(9) and r8.xyzw, r8.xyzw, l(64, 128, 256, 512) iadd r0.y, r0.y, r8.x iadd r0.y, r8.y, r0.y iadd r0.y, r8.z, r0.y iadd r0.y, r8.w, r0.y ishr r0.z, r1.x, l(5) ishr r0.w, r1.y, l(1) ishr r1.x, r1.y, l(2) ishr r2.x, r1.y, l(3) ishl r8.x, r0.z, l(10) ishl r8.y, r0.w, l(16) ishl r8.z, r1.x, l(17) ishl r8.w, r2.x, l(18) and r8.xyzw, r8.xyzw, l(1024, 0x00010000, 0x00020000, 0x00040000) iadd r0.y, r0.y, r8.x ishr r0.z, r6.x, l(4) ishr r0.w, r6.y, l(1) ishr r1.x, r6.y, l(2) ishr r2.x, r6.x, l(5) ishl r9.x, r0.z, l(11) ishl r9.y, r0.w, l(13) ishl r9.z, r1.x, l(23) ishl r0.z, r2.x, l(31) and r2.xzw, r9.xxyz, l(2048, 0, 8192, 0x00800000) iadd r0.y, r0.y, r2.x ishl r9.x, r6.y, l(12) ishl r9.y, r6.x, l(19) and r4.zw, r9.xxxy, l(0, 0, 4096, 0x00080000) iadd r0.y, r0.y, r4.z iadd r0.y, r2.z, r0.y ishr r2.xz, r5.zzyz, l(4) ishr r6.zw, r5.yyyz, l(5) ishl r9.x, r2.x, l(14) ishl r9.y, r6.z, l(21) ishl r9.z, r6.w, l(22) ishl r9.w, r2.z, l(24) and r9.xyzw, r9.xyzw, l(0x00004000, 0x00200000, 0x00400000, 0x01000000) iadd r0.y, r0.y, r9.x iadd r0.y, r7.y, r0.y iadd r0.y, r8.y, r0.y iadd r0.y, r8.z, r0.y iadd r0.y, r8.w, r0.y ishr r0.w, r1.y, l(4) ishr r1.x, r1.y, l(5) ishr r1.y, r1.z, l(1) ishr r2.x, r1.z, l(2) ishl r8.x, r0.w, l(19) ishl r8.y, r1.x, l(20) ishl r8.z, r1.y, l(26) ishl r8.w, r2.x, l(27) and r8.xyzw, r8.xyzw, l(0x00080000, 0x00100000, 0x04000000, 0x08000000) iadd r0.y, r0.y, r8.x iadd r0.y, r8.y, r0.y iadd r0.y, r9.y, r0.y iadd r0.y, r9.z, r0.y iadd r0.y, r2.w, r0.y iadd r0.y, r9.w, r0.y iadd r0.y, r7.z, r0.y iadd r0.y, r8.z, r0.y iadd r0.y, r8.w, r0.y ishr r0.w, r1.z, l(3) ishr r1.x, r1.z, l(4) ishr r1.y, r1.z, l(5) ishr r1.z, r1.w, l(1) ishl r8.x, r0.w, l(28) ishl r8.y, r1.x, l(29) ishl r8.z, r1.y, l(30) ishl r8.w, r1.z, l(4) and r8.xyzw, r8.xyzw, l(0x10000000, 0x20000000, 0x40000000, 16) iadd r0.y, r0.y, r8.x iadd r0.y, r8.y, r0.y iadd r0.y, r8.z, r0.y iadd r3.x, r0.z, r0.y ishr r0.y, r6.y, l(3) ishr r0.z, r6.y, l(5) ishr r0.w, r6.y, l(4) ishr r1.x, r6.x, l(1) and r0.y, r0.y, l(1) ishl r7.x, r0.z, l(1) ishl r7.y, r0.w, l(2) ishl r7.z, r1.x, l(20) and r1.xyz, r7.xyzx, l(2, 4, 0x00100000, 0) iadd r0.y, r0.y, r1.x iadd r0.y, r1.y, r0.y iadd r0.y, r7.w, r0.y iadd r0.y, r8.w, r0.y ishr r0.z, r1.w, l(2) ishr r0.w, r1.w, l(3) ishr r1.x, r1.w, l(4) ishr r1.y, r1.w, l(5) ishl r7.x, r0.z, l(5) ishl r7.y, r0.w, l(6) ishl r7.z, r1.x, l(7) ishl r7.w, r1.y, l(8) and r7.xyzw, r7.xyzw, l(32, 64, 128, 256) iadd r0.y, r0.y, r7.x iadd r0.y, r7.y, r0.y iadd r0.y, r7.z, r0.y iadd r0.y, r7.w, r0.y ishl r7.x, r5.y, l(9) ishl r7.y, r5.z, l(29) ishl r7.z, r5.x, l(1) ishl r7.w, r5.w, l(7) and r7.xyzw, r7.xyzw, l(512, 0x20000000, 2, 128) iadd r0.y, r0.y, r7.x ishr r0.zw, r5.yyyz, l(1) ishr r1.x, r5.y, l(2) ishr r1.y, r5.y, l(3) ishl r8.x, r0.z, l(10) ishl r8.y, r1.x, l(11) ishl r8.z, r1.y, l(12) ishl r8.w, r0.w, l(30) and r8.xyzw, r8.xyzw, l(1024, 2048, 4096, 0x40000000) iadd r0.y, r0.y, r8.x iadd r0.y, r8.y, r0.y iadd r0.y, r8.z, r0.y ishl r1.x, r4.x, l(13) ishl r1.y, r4.y, l(23) and r0.zw, r1.xxxy, l(0, 0, 8192, 0x00800000) iadd r0.y, r0.z, r0.y ishr r0.z, r4.x, l(1) ishr r1.x, r4.x, l(2) ishr r1.y, r4.x, l(3) ishr r1.w, r4.x, l(4) ishl r9.x, r0.z, l(14) ishl r9.y, r1.x, l(15) ishl r9.z, r1.y, l(16) ishl r9.w, r1.w, l(17) and r9.xyzw, r9.xyzw, l(0x00004000, 0x00008000, 0x00010000, 0x00020000) iadd r0.y, r0.y, r9.x iadd r0.y, r9.y, r0.y iadd r0.y, r9.z, r0.y iadd r0.y, r9.w, r0.y ishr r0.z, r4.x, l(5) ishr r1.x, r4.y, l(1) ishr r1.y, r4.y, l(2) ishr r1.w, r4.y, l(3) ishl r9.x, r0.z, l(18) ishl r9.y, r1.x, l(24) ishl r9.z, r1.y, l(25) ishl r9.w, r1.w, l(26) and r9.xyzw, r9.xyzw, l(0x00040000, 0x01000000, 0x02000000, 0x04000000) iadd r0.y, r0.y, r9.x iadd r0.y, r4.w, r0.y iadd r0.y, r1.z, r0.y ishr r0.z, r6.x, l(2) ishr r1.x, r6.x, l(3) ishl r6.x, r0.z, l(21) ishl r6.y, r1.x, l(22) and r1.xy, r6.xyxx, l(0x00200000, 0x00400000, 0, 0) iadd r0.y, r0.y, r1.x iadd r0.y, r1.y, r0.y iadd r0.y, r0.w, r0.y iadd r0.y, r9.y, r0.y iadd r0.y, r9.z, r0.y iadd r0.y, r9.w, r0.y ishr r0.z, r4.y, l(4) ishr r0.w, r4.y, l(5) ishl r1.x, r0.z, l(27) ishl r1.y, r0.w, l(28) and r0.zw, r1.xxxy, l(0, 0, 0x08000000, 0x10000000) iadd r0.y, r0.z, r0.y iadd r0.y, r0.w, r0.y iadd r0.y, r7.y, r0.y iadd r0.y, r8.w, r0.y ishr r0.zw, r5.zzzx, l(2) ishr r1.x, r5.z, l(3) ishr r1.y, r5.x, l(1) ishl r4.x, r0.z, l(31) ishl r4.y, r1.y, l(2) ishl r4.z, r0.w, l(3) iadd r3.z, r0.y, r4.x and r0.y, r1.x, l(1) iadd r0.y, r0.y, r3.w iadd r0.y, r7.z, r0.y and r0.zw, r4.yyyz, l(0, 0, 4, 8) iadd r0.y, r0.z, r0.y iadd r0.y, r0.w, r0.y ishr r0.z, r5.x, l(3) ishr r0.w, r5.x, l(4) ishr r1.x, r5.x, l(5) ishr r1.y, r5.w, l(1) ishl r4.x, r0.z, l(4) ishl r4.y, r0.w, l(5) ishl r4.z, r1.x, l(6) ishl r4.w, r1.y, l(8) and r1.xyzw, r4.xyzw, l(16, 32, 64, 256) iadd r0.y, r0.y, r1.x iadd r0.y, r1.y, r0.y iadd r0.y, r1.z, r0.y iadd r0.y, r7.w, r0.y iadd r0.y, r1.w, r0.y ishr r0.z, r5.w, l(2) ishr r0.w, r5.w, l(3) ishr r1.x, r5.w, l(4) ishr r1.y, r5.w, l(5) ishl r4.x, r0.z, l(9) ishl r4.y, r0.w, l(10) ishl r4.z, r1.x, l(11) ishl r4.w, r1.y, l(12) and r1.xyzw, r4.xyzw, l(512, 1024, 2048, 4096) iadd r0.y, r0.y, r1.x iadd r0.y, r1.y, r0.y iadd r0.y, r1.z, r0.y iadd r0.y, r1.w, r0.y ishl r0.z, r2.y, l(13) and r0.z, r0.z, l(8192) iadd r0.y, r0.z, r0.y ushr r0.z, r2.y, l(1) ushr r0.w, r2.y, l(2) ushr r1.x, r2.y, l(3) ushr r1.y, r2.y, l(4) ishl r2.x, r0.z, l(14) ishl r2.y, r0.w, l(15) ishl r2.z, r1.x, l(16) ishl r2.w, r1.y, l(17) and r1.xyzw, r2.xyzw, l(0x00004000, 0x00008000, 0x00010000, 0x00020000) iadd r0.y, r0.y, r1.x iadd r0.y, r1.y, r0.y iadd r0.y, r1.z, r0.y iadd r3.w, r1.w, r0.y else mov r3.xz, l(0,0,0,0) endif endif endif endif endif endif endif endif endif endif endif store_structured u0.xyzw, r0.x, l(0), r3.xzwy endif ret // Approximately 0 instruction slots used #endif const BYTE BC6HEncode_EncodeBlockCS[] = { 68, 88, 66, 67, 175, 105, 37, 89, 105, 238, 20, 239, 19, 200, 75, 5, 33, 255, 18, 179, 1, 0, 0, 0, 20, 173, 1, 0, 3, 0, 0, 0, 44, 0, 0, 0, 60, 0, 0, 0, 76, 0, 0, 0, 73, 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 192, 172, 1, 0, 64, 0, 5, 0, 48, 107, 0, 0, 106, 8, 0, 1, 53, 24, 0, 0, 58, 1, 0, 0, 204, 204, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 136, 136, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 238, 238, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 200, 236, 0, 0, 15, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 128, 200, 0, 0, 15, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 236, 254, 0, 0, 15, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 200, 254, 0, 0, 15, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 128, 236, 0, 0, 15, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 200, 0, 0, 15, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 236, 255, 0, 0, 15, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 128, 254, 0, 0, 15, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 232, 0, 0, 15, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 232, 255, 0, 0, 15, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 0, 255, 0, 0, 15, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 240, 255, 0, 0, 15, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 240, 0, 0, 15, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 16, 247, 0, 0, 15, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 142, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 0, 113, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 206, 8, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 140, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 16, 115, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 0, 49, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 206, 140, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 140, 8, 0, 0, 2, 0, 0, 0, 6, 0, 0, 0, 3, 0, 0, 0, 16, 49, 0, 0, 8, 0, 0, 0, 6, 0, 0, 0, 3, 0, 0, 0, 102, 102, 0, 0, 2, 0, 0, 0, 6, 0, 0, 0, 3, 0, 0, 0, 108, 54, 0, 0, 2, 0, 0, 0, 6, 0, 0, 0, 3, 0, 0, 0, 232, 23, 0, 0, 8, 0, 0, 0, 6, 0, 0, 0, 3, 0, 0, 0, 240, 15, 0, 0, 8, 0, 0, 0, 7, 0, 0, 0, 3, 0, 0, 0, 142, 113, 0, 0, 2, 0, 0, 0, 7, 0, 0, 0, 3, 0, 0, 0, 156, 57, 0, 0, 2, 0, 0, 0, 7, 0, 0, 0, 3, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 7, 0, 0, 0, 3, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 9, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 9, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 9, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 9, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0, 6, 0, 0, 0, 6, 0, 0, 0, 11, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 11, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 11, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 9, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 8, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 6, 0, 0, 0, 6, 0, 0, 0, 6, 0, 0, 0, 6, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 12, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 89, 0, 0, 4, 70, 142, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 88, 24, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 162, 0, 0, 4, 0, 112, 16, 0, 1, 0, 0, 0, 16, 0, 0, 0, 158, 0, 0, 4, 0, 224, 17, 0, 0, 0, 0, 0, 16, 0, 0, 0, 95, 0, 0, 2, 0, 64, 2, 0, 95, 0, 0, 2, 18, 16, 2, 0, 104, 0, 0, 2, 18, 0, 0, 0, 160, 0, 0, 5, 0, 240, 17, 0, 0, 0, 0, 0, 84, 0, 0, 0, 64, 0, 0, 0, 155, 0, 0, 4, 64, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 85, 0, 0, 6, 18, 0, 16, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 6, 34, 0, 16, 0, 0, 0, 0, 0, 10, 16, 2, 0, 1, 64, 0, 0, 1, 0, 0, 0, 30, 0, 0, 8, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 128, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 80, 0, 0, 8, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 128, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 21, 0, 0, 1, 1, 0, 0, 6, 34, 0, 16, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 32, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 128, 65, 0, 0, 0, 0, 0, 0, 0, 10, 64, 2, 0, 79, 0, 0, 10, 242, 0, 16, 0, 1, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 1, 0, 0, 0, 78, 0, 0, 9, 130, 0, 16, 0, 0, 0, 0, 0, 0, 208, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 11, 18, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 128, 65, 0, 0, 0, 0, 0, 0, 0, 26, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 7, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 16, 0, 0, 10, 130, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 208, 179, 89, 62, 89, 23, 55, 63, 152, 221, 147, 61, 0, 0, 0, 0, 168, 0, 0, 8, 18, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 36, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 7, 114, 0, 16, 0, 3, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 3, 0, 0, 0, 70, 2, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 128, 0, 0, 0, 128, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 6, 5, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 255, 255, 255, 127, 255, 255, 127, 0, 255, 255, 255, 127, 255, 255, 127, 0, 79, 0, 0, 10, 50, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 255, 239, 255, 71, 255, 239, 255, 71, 0, 0, 0, 0, 0, 0, 0, 0, 134, 0, 16, 0, 4, 0, 0, 0, 79, 0, 0, 10, 50, 0, 16, 0, 5, 0, 0, 0, 134, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 56, 0, 0, 128, 56, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 194, 0, 16, 0, 5, 0, 0, 0, 6, 8, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 30, 0, 0, 11, 194, 0, 16, 0, 5, 0, 0, 0, 166, 14, 16, 128, 65, 0, 0, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 113, 0, 0, 0, 113, 0, 0, 0, 30, 0, 0, 10, 162, 0, 16, 0, 4, 0, 0, 0, 86, 13, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 128, 0, 85, 0, 0, 7, 18, 0, 16, 0, 6, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 85, 0, 0, 7, 34, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 30, 0, 0, 10, 50, 0, 16, 0, 4, 0, 0, 0, 134, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 200, 0, 0, 0, 200, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 50, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 5, 0, 0, 0, 70, 0, 16, 0, 6, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 30, 0, 0, 10, 194, 0, 16, 0, 4, 0, 0, 0, 6, 4, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 15, 0, 0, 255, 15, 0, 0, 85, 0, 0, 7, 50, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 1, 0, 0, 10, 50, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 230, 10, 16, 0, 4, 0, 0, 0, 85, 0, 0, 7, 50, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 1, 0, 0, 10, 50, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 127, 0, 0, 255, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 12, 50, 0, 16, 0, 2, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 255, 127, 0, 0, 255, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 10, 50, 0, 16, 0, 2, 0, 0, 0, 166, 10, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 255, 255, 255, 127, 255, 255, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 255, 239, 255, 71, 10, 0, 16, 0, 2, 0, 0, 0, 79, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 56, 85, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 30, 0, 0, 8, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 128, 65, 0, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 113, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 0, 85, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 200, 55, 0, 0, 9, 18, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 255, 15, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 255, 127, 0, 0, 55, 0, 0, 9, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 255, 127, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 32, 0, 0, 8, 130, 0, 16, 0, 0, 0, 0, 0, 42, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 95, 0, 0, 0, 41, 0, 0, 7, 114, 0, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 78, 0, 0, 11, 114, 0, 16, 0, 2, 0, 0, 0, 0, 208, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 31, 0, 0, 0, 31, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 79, 0, 0, 10, 114, 0, 16, 0, 3, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 128, 0, 0, 0, 128, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 32, 0, 0, 10, 114, 0, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 123, 0, 0, 255, 123, 0, 0, 255, 123, 0, 0, 0, 0, 0, 0, 41, 0, 0, 7, 114, 0, 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 78, 0, 0, 11, 114, 0, 16, 0, 6, 0, 0, 0, 0, 208, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 31, 0, 0, 0, 31, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 255, 127, 0, 0, 255, 127, 0, 0, 255, 127, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 224, 255, 15, 0, 224, 255, 15, 0, 224, 255, 15, 0, 0, 0, 0, 0, 78, 0, 0, 11, 114, 0, 16, 0, 4, 0, 0, 0, 0, 208, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 31, 0, 0, 0, 31, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 5, 114, 0, 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 1, 128, 255, 255, 1, 128, 255, 255, 1, 128, 255, 255, 0, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 3, 0, 0, 0, 70, 2, 16, 0, 3, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 2, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 3, 0, 0, 0, 168, 0, 0, 8, 114, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 12, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 21, 0, 0, 1, 167, 0, 0, 9, 50, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 70, 112, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 1, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 167, 0, 0, 9, 114, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 70, 242, 17, 0, 0, 0, 0, 0, 167, 0, 0, 9, 130, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 36, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 1, 0, 0, 0, 79, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 242, 0, 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 3, 0, 0, 0, 54, 0, 0, 5, 242, 0, 16, 0, 5, 0, 0, 0, 150, 15, 16, 0, 3, 0, 0, 0, 18, 0, 0, 1, 85, 0, 0, 8, 34, 0, 16, 0, 1, 0, 0, 0, 10, 144, 144, 0, 26, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 55, 0, 0, 12, 242, 0, 16, 0, 4, 0, 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 255, 255, 255, 127, 255, 255, 255, 127, 255, 255, 255, 127, 0, 0, 0, 128, 70, 2, 16, 0, 3, 0, 0, 0, 55, 0, 0, 12, 242, 0, 16, 0, 5, 0, 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 128, 0, 0, 0, 128, 255, 255, 127, 127, 255, 255, 127, 255, 150, 15, 16, 0, 3, 0, 0, 0, 21, 0, 0, 1, 18, 0, 0, 1, 80, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 1, 0, 0, 0, 85, 0, 0, 8, 130, 0, 16, 0, 0, 0, 0, 0, 10, 144, 144, 0, 26, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 32, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 55, 0, 0, 12, 242, 0, 16, 0, 4, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 255, 255, 255, 127, 255, 255, 255, 127, 255, 255, 255, 127, 0, 0, 0, 128, 55, 0, 0, 12, 242, 0, 16, 0, 5, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 150, 15, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 128, 0, 0, 0, 128, 255, 255, 127, 127, 255, 255, 127, 255, 18, 0, 0, 1, 54, 0, 0, 8, 242, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 255, 255, 127, 255, 255, 255, 127, 255, 255, 255, 127, 0, 0, 0, 128, 54, 0, 0, 8, 242, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 128, 0, 0, 0, 128, 255, 255, 127, 127, 255, 255, 127, 255, 21, 0, 0, 1, 21, 0, 0, 1, 168, 0, 0, 8, 242, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 168, 0, 0, 8, 242, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 68, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 21, 0, 0, 1, 1, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 79, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 3, 0, 0, 0, 167, 0, 0, 8, 18, 0, 16, 0, 4, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 76, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 30, 0, 0, 6, 130, 0, 16, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 8, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 76, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 49, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 9, 114, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 242, 17, 0, 0, 0, 0, 0, 168, 0, 0, 8, 114, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 168, 0, 0, 8, 18, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 76, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 21, 0, 0, 1, 167, 0, 0, 8, 18, 0, 16, 0, 4, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 80, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 80, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 49, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 9, 114, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 64, 0, 0, 0, 70, 242, 17, 0, 0, 0, 0, 0, 168, 0, 0, 8, 114, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 64, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 168, 0, 0, 8, 18, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 80, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 21, 0, 0, 1, 21, 0, 0, 1, 31, 0, 4, 3, 26, 0, 16, 0, 3, 0, 0, 0, 167, 0, 0, 8, 18, 0, 16, 0, 4, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 76, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 30, 0, 0, 6, 130, 0, 16, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 4, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 76, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 49, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 9, 114, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 242, 17, 0, 0, 0, 0, 0, 168, 0, 0, 8, 114, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 168, 0, 0, 8, 18, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 76, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 21, 0, 0, 1, 167, 0, 0, 8, 18, 0, 16, 0, 4, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 80, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 80, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 49, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 9, 114, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 64, 0, 0, 0, 70, 242, 17, 0, 0, 0, 0, 0, 168, 0, 0, 8, 114, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 64, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 168, 0, 0, 8, 18, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 80, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 21, 0, 0, 1, 21, 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 3, 0, 0, 0, 167, 0, 0, 8, 18, 0, 16, 0, 4, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 76, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 30, 0, 0, 6, 130, 0, 16, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 2, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 76, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 49, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 9, 114, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 242, 17, 0, 0, 0, 0, 0, 168, 0, 0, 8, 114, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 168, 0, 0, 8, 18, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 76, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 21, 0, 0, 1, 167, 0, 0, 8, 18, 0, 16, 0, 4, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 80, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 80, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 49, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 9, 114, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 64, 0, 0, 0, 70, 242, 17, 0, 0, 0, 0, 0, 168, 0, 0, 8, 114, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 64, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 168, 0, 0, 8, 18, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 80, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 21, 0, 0, 1, 21, 0, 0, 1, 31, 0, 4, 3, 58, 0, 16, 0, 3, 0, 0, 0, 167, 0, 0, 8, 18, 0, 16, 0, 3, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 76, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 30, 0, 0, 6, 130, 0, 16, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 1, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 76, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 49, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 9, 114, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 242, 17, 0, 0, 0, 0, 0, 168, 0, 0, 8, 114, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 2, 16, 0, 3, 0, 0, 0, 21, 0, 0, 1, 167, 0, 0, 8, 18, 0, 16, 0, 3, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 80, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 80, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 49, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 9, 114, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 64, 0, 0, 0, 70, 242, 17, 0, 0, 0, 0, 0, 168, 0, 0, 8, 114, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 64, 0, 0, 0, 70, 2, 16, 0, 3, 0, 0, 0, 21, 0, 0, 1, 21, 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 167, 0, 0, 9, 114, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 242, 17, 0, 0, 0, 0, 0, 167, 0, 0, 9, 114, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 64, 0, 0, 0, 70, 242, 17, 0, 0, 0, 0, 0, 32, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 80, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 130, 0, 16, 0, 0, 0, 0, 0, 26, 144, 144, 0, 26, 0, 16, 0, 2, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, 30, 0, 0, 8, 114, 0, 16, 0, 5, 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 3, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 43, 0, 0, 5, 114, 0, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 16, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 167, 0, 0, 9, 114, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 70, 242, 17, 0, 0, 0, 0, 0, 30, 0, 0, 8, 114, 0, 16, 0, 6, 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 3, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 43, 0, 0, 5, 114, 0, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 16, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 49, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 29, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 56, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 253, 255, 125, 66, 14, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 28, 0, 0, 5, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 79, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 55, 0, 0, 9, 242, 0, 16, 0, 5, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 55, 0, 0, 9, 194, 0, 16, 0, 2, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 86, 9, 16, 0, 3, 0, 0, 0, 86, 9, 16, 0, 4, 0, 0, 0, 168, 0, 0, 8, 242, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 168, 0, 0, 8, 50, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 68, 0, 0, 0, 230, 10, 16, 0, 2, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 10, 0, 16, 0, 1, 0, 0, 0, 79, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 6, 18, 0, 16, 0, 1, 0, 0, 0, 10, 144, 144, 0, 26, 0, 16, 0, 2, 0, 0, 0, 21, 0, 0, 1, 85, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 167, 0, 0, 9, 114, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 64, 0, 0, 0, 70, 242, 17, 0, 0, 0, 0, 0, 167, 0, 0, 9, 114, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 242, 17, 0, 0, 0, 0, 0, 30, 0, 0, 8, 114, 0, 16, 0, 3, 0, 0, 0, 70, 2, 16, 0, 3, 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 4, 0, 0, 0, 43, 0, 0, 5, 114, 0, 16, 0, 3, 0, 0, 0, 70, 2, 16, 0, 3, 0, 0, 0, 167, 0, 0, 8, 114, 0, 16, 0, 5, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 12, 0, 0, 0, 70, 242, 17, 0, 0, 0, 0, 0, 30, 0, 0, 8, 114, 0, 16, 0, 4, 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 4, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 43, 0, 0, 5, 114, 0, 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 16, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 3, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 18, 0, 0, 1, 167, 0, 0, 9, 114, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 64, 0, 0, 0, 70, 242, 17, 0, 0, 0, 0, 0, 167, 0, 0, 9, 114, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 242, 17, 0, 0, 0, 0, 0, 30, 0, 0, 8, 114, 0, 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 5, 0, 0, 0, 43, 0, 0, 5, 114, 0, 16, 0, 3, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 167, 0, 0, 8, 114, 0, 16, 0, 4, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 12, 0, 0, 0, 70, 242, 17, 0, 0, 0, 0, 0, 30, 0, 0, 8, 114, 0, 16, 0, 4, 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 5, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 43, 0, 0, 5, 114, 0, 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 16, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 3, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 21, 0, 0, 1, 16, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 3, 0, 0, 0, 70, 2, 16, 0, 3, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 0, 0, 0, 0, 29, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 29, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 60, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 49, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 56, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 253, 255, 125, 66, 14, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 28, 0, 0, 5, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 55, 0, 0, 10, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 42, 144, 144, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 55, 0, 0, 9, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 79, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 224, 255, 255, 255, 41, 0, 0, 7, 130, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 54, 0, 0, 8, 98, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 194, 0, 16, 0, 2, 0, 0, 0, 166, 10, 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, 4, 0, 0, 0, 166, 14, 16, 0, 4, 0, 0, 0, 54, 0, 0, 5, 34, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 50, 0, 16, 0, 3, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 230, 10, 16, 0, 2, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 18, 0, 0, 1, 29, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 29, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 60, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 49, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 56, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 253, 255, 125, 66, 14, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 28, 0, 0, 5, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 55, 0, 0, 10, 18, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 58, 144, 144, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 55, 0, 0, 9, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 31, 0, 0, 3, 42, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 18, 0, 0, 0, 54, 0, 0, 5, 34, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 18, 0, 0, 1, 79, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 1, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 17, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 34, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 18, 0, 0, 1, 39, 0, 0, 8, 18, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 26, 144, 144, 0, 26, 0, 16, 0, 2, 0, 0, 0, 32, 0, 0, 8, 34, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 26, 144, 144, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 79, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 1, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 34, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 18, 0, 0, 1, 32, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 55, 0, 0, 9, 18, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 34, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 31, 0, 0, 0, 55, 0, 0, 9, 18, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 79, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 35, 0, 0, 12, 194, 0, 16, 0, 2, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 30, 0, 0, 10, 194, 0, 16, 0, 2, 0, 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 240, 255, 255, 255, 240, 255, 255, 255, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 55, 0, 0, 9, 34, 0, 16, 0, 5, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 50, 0, 16, 0, 3, 0, 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 5, 0, 0, 0, 21, 0, 0, 1, 21, 0, 0, 1, 21, 0, 0, 1, 21, 0, 0, 1, 168, 0, 0, 8, 50, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 24, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 8, 50, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 58, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 8, 50, 0, 16, 0, 4, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 24, 0, 0, 0, 70, 240, 17, 0, 0, 0, 0, 0, 30, 0, 0, 6, 130, 0, 16, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 8, 0, 0, 0, 167, 0, 0, 9, 50, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 24, 0, 0, 0, 70, 240, 17, 0, 0, 0, 0, 0, 60, 0, 0, 7, 50, 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 5, 0, 0, 0, 168, 0, 0, 8, 50, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 24, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 79, 0, 0, 10, 50, 0, 16, 0, 1, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 8, 50, 0, 16, 0, 4, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 24, 0, 0, 0, 70, 240, 17, 0, 0, 0, 0, 0, 30, 0, 0, 6, 130, 0, 16, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 4, 0, 0, 0, 167, 0, 0, 9, 50, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 24, 0, 0, 0, 70, 240, 17, 0, 0, 0, 0, 0, 60, 0, 0, 7, 146, 0, 16, 0, 1, 0, 0, 0, 6, 4, 16, 0, 4, 0, 0, 0, 6, 4, 16, 0, 5, 0, 0, 0, 168, 0, 0, 8, 50, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 24, 0, 0, 0, 198, 0, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 8, 50, 0, 16, 0, 4, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 24, 0, 0, 0, 70, 240, 17, 0, 0, 0, 0, 0, 30, 0, 0, 6, 130, 0, 16, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 2, 0, 0, 0, 167, 0, 0, 9, 50, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 24, 0, 0, 0, 70, 240, 17, 0, 0, 0, 0, 0, 60, 0, 0, 7, 146, 0, 16, 0, 1, 0, 0, 0, 6, 4, 16, 0, 4, 0, 0, 0, 6, 4, 16, 0, 5, 0, 0, 0, 168, 0, 0, 8, 50, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 24, 0, 0, 0, 198, 0, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 26, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 8, 50, 0, 16, 0, 4, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 24, 0, 0, 0, 70, 240, 17, 0, 0, 0, 0, 0, 30, 0, 0, 6, 130, 0, 16, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 1, 0, 0, 0, 167, 0, 0, 9, 50, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 24, 0, 0, 0, 70, 240, 17, 0, 0, 0, 0, 0, 60, 0, 0, 7, 50, 0, 16, 0, 3, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 5, 0, 0, 0, 21, 0, 0, 1, 30, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 255, 255, 255, 255, 32, 0, 0, 10, 50, 0, 16, 0, 1, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 9, 114, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 242, 17, 0, 0, 0, 0, 0, 167, 0, 0, 9, 114, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 64, 0, 0, 0, 70, 242, 17, 0, 0, 0, 0, 0, 32, 0, 0, 8, 18, 0, 16, 0, 1, 0, 0, 0, 42, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 95, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 1, 0, 0, 0, 33, 0, 0, 9, 18, 0, 16, 0, 1, 0, 0, 0, 10, 144, 208, 0, 64, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 55, 0, 0, 15, 114, 0, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 15, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 114, 0, 16, 0, 6, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 60, 0, 0, 7, 114, 0, 16, 0, 7, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 32, 0, 0, 10, 114, 0, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 32, 0, 0, 10, 114, 0, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 41, 0, 0, 9, 18, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 10, 144, 208, 0, 64, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 255, 255, 255, 255, 41, 0, 0, 9, 114, 0, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 10, 144, 208, 0, 64, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 9, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 10, 144, 208, 0, 64, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 114, 0, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 42, 0, 0, 7, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 18, 0, 0, 1, 33, 0, 0, 9, 18, 0, 16, 0, 1, 0, 0, 0, 10, 144, 208, 0, 64, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 55, 0, 0, 15, 114, 0, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 15, 114, 0, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 114, 0, 16, 0, 8, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 60, 0, 0, 7, 114, 0, 16, 0, 9, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 33, 0, 0, 10, 114, 0, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 10, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 10, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 127, 0, 0, 255, 127, 0, 0, 255, 127, 0, 0, 0, 0, 0, 0, 32, 0, 0, 10, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 255, 127, 0, 0, 255, 127, 0, 0, 255, 127, 0, 0, 0, 0, 0, 0, 30, 0, 0, 9, 18, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 255, 255, 255, 255, 10, 144, 208, 0, 64, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 255, 255, 255, 255, 41, 0, 0, 7, 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 7, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 42, 0, 0, 7, 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 42, 0, 0, 7, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 166, 10, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 166, 10, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 40, 0, 0, 5, 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 40, 0, 0, 5, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 32, 0, 0, 10, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 255, 127, 0, 0, 255, 127, 0, 0, 255, 127, 0, 0, 0, 0, 0, 0, 32, 0, 0, 10, 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 255, 127, 0, 0, 255, 127, 0, 0, 255, 127, 0, 0, 0, 0, 0, 0, 30, 0, 0, 8, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 128, 65, 0, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 7, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 42, 0, 0, 7, 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 42, 0, 0, 7, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 40, 0, 0, 5, 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 40, 0, 0, 5, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 246, 15, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 246, 15, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 21, 0, 0, 1, 30, 0, 0, 8, 114, 0, 16, 0, 4, 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 6, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 55, 0, 0, 11, 114, 0, 16, 0, 4, 0, 0, 0, 6, 144, 208, 0, 32, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 6, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 168, 0, 0, 8, 242, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 168, 0, 0, 8, 50, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 68, 0, 0, 0, 150, 5, 16, 0, 4, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 26, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 10, 50, 0, 16, 0, 1, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 167, 0, 0, 9, 114, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 242, 17, 0, 0, 0, 0, 0, 167, 0, 0, 9, 114, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 242, 17, 0, 0, 0, 0, 0, 167, 0, 0, 9, 114, 0, 16, 0, 6, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 64, 0, 0, 0, 70, 242, 17, 0, 0, 0, 0, 0, 80, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 1, 0, 0, 0, 32, 0, 0, 8, 18, 0, 16, 0, 1, 0, 0, 0, 42, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 95, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 1, 0, 0, 0, 33, 0, 0, 9, 18, 0, 16, 0, 1, 0, 0, 0, 10, 144, 208, 0, 64, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 55, 0, 0, 15, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 15, 114, 0, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 114, 0, 16, 0, 7, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 60, 0, 0, 7, 178, 0, 16, 0, 1, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 70, 8, 16, 0, 8, 0, 0, 0, 32, 0, 0, 10, 114, 0, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 32, 0, 0, 10, 114, 0, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 41, 0, 0, 9, 66, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 10, 144, 208, 0, 64, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 255, 255, 255, 255, 41, 0, 0, 9, 114, 0, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 10, 144, 208, 0, 64, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 9, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 10, 144, 208, 0, 64, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 114, 0, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 42, 0, 0, 7, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 166, 10, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 166, 10, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 55, 0, 0, 9, 178, 0, 16, 0, 1, 0, 0, 0, 70, 12, 16, 0, 1, 0, 0, 0, 70, 8, 16, 0, 6, 0, 0, 0, 70, 8, 16, 0, 9, 0, 0, 0, 18, 0, 0, 1, 33, 0, 0, 9, 66, 0, 16, 0, 2, 0, 0, 0, 10, 144, 208, 0, 64, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 55, 0, 0, 15, 114, 0, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 15, 114, 0, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 114, 0, 16, 0, 8, 0, 0, 0, 166, 10, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 60, 0, 0, 7, 114, 0, 16, 0, 9, 0, 0, 0, 166, 10, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 33, 0, 0, 10, 114, 0, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 10, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 10, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 255, 127, 0, 0, 255, 127, 0, 0, 255, 127, 0, 0, 0, 0, 0, 0, 32, 0, 0, 10, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 255, 127, 0, 0, 255, 127, 0, 0, 255, 127, 0, 0, 0, 0, 0, 0, 30, 0, 0, 9, 66, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 255, 255, 255, 255, 10, 144, 208, 0, 64, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 255, 255, 255, 255, 41, 0, 0, 7, 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 7, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 42, 0, 0, 7, 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 42, 0, 0, 7, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 246, 15, 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 246, 15, 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 40, 0, 0, 5, 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 40, 0, 0, 5, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 32, 0, 0, 10, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 255, 127, 0, 0, 255, 127, 0, 0, 255, 127, 0, 0, 0, 0, 0, 0, 32, 0, 0, 10, 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 255, 127, 0, 0, 255, 127, 0, 0, 255, 127, 0, 0, 0, 0, 0, 0, 30, 0, 0, 8, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 128, 65, 0, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 7, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 42, 0, 0, 7, 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 42, 0, 0, 7, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 40, 0, 0, 5, 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 40, 0, 0, 5, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 246, 15, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 246, 15, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 55, 0, 0, 9, 178, 0, 16, 0, 1, 0, 0, 0, 70, 8, 16, 0, 9, 0, 0, 0, 70, 8, 16, 0, 6, 0, 0, 0, 70, 8, 16, 0, 11, 0, 0, 0, 21, 0, 0, 1, 30, 0, 0, 8, 114, 0, 16, 0, 5, 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 4, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 30, 0, 0, 8, 114, 0, 16, 0, 4, 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 4, 0, 0, 0, 70, 3, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 5, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 7, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 55, 0, 0, 11, 242, 0, 16, 0, 5, 0, 0, 0, 6, 144, 208, 0, 32, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 55, 0, 0, 11, 50, 0, 16, 0, 1, 0, 0, 0, 6, 144, 208, 0, 32, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 150, 5, 16, 0, 4, 0, 0, 0, 214, 5, 16, 0, 1, 0, 0, 0, 168, 0, 0, 8, 242, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 168, 0, 0, 8, 50, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 68, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 21, 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 6, 18, 0, 16, 0, 1, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 2, 0, 0, 0, 167, 0, 0, 9, 114, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 242, 17, 0, 0, 0, 0, 0, 167, 0, 0, 9, 114, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 64, 0, 0, 0, 150, 240, 17, 0, 0, 0, 0, 0, 31, 0, 0, 3, 42, 0, 16, 0, 0, 0, 0, 0, 79, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 9, 18, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 10, 144, 208, 0, 64, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 9, 34, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 26, 144, 208, 0, 64, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 9, 66, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 144, 208, 0, 64, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 9, 130, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 58, 144, 208, 0, 64, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 33, 0, 0, 10, 114, 0, 16, 0, 6, 0, 0, 0, 38, 9, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 12, 114, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 150, 151, 208, 0, 64, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 8, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 33, 0, 0, 7, 114, 0, 16, 0, 7, 0, 0, 0, 38, 9, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 38, 9, 16, 0, 1, 0, 0, 0, 40, 0, 0, 5, 114, 0, 16, 0, 9, 0, 0, 0, 38, 9, 16, 0, 1, 0, 0, 0, 34, 0, 0, 7, 114, 0, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 1, 0, 0, 7, 226, 0, 16, 0, 5, 0, 0, 0, 166, 4, 16, 0, 1, 0, 0, 0, 86, 14, 16, 0, 5, 0, 0, 0, 55, 0, 0, 9, 226, 0, 16, 0, 5, 0, 0, 0, 6, 9, 16, 0, 9, 0, 0, 0, 6, 9, 16, 0, 8, 0, 0, 0, 86, 14, 16, 0, 5, 0, 0, 0, 55, 0, 0, 9, 226, 0, 16, 0, 5, 0, 0, 0, 6, 9, 16, 0, 6, 0, 0, 0, 6, 9, 16, 0, 7, 0, 0, 0, 86, 14, 16, 0, 5, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 0, 0, 7, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 6, 0, 16, 0, 5, 0, 0, 0, 1, 0, 0, 7, 194, 0, 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, 1, 0, 0, 0, 6, 0, 16, 0, 5, 0, 0, 0, 54, 0, 0, 5, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 55, 0, 0, 11, 242, 0, 16, 0, 4, 0, 0, 0, 6, 144, 208, 0, 32, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 55, 0, 0, 11, 50, 0, 16, 0, 1, 0, 0, 0, 6, 144, 208, 0, 32, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 230, 10, 16, 0, 5, 0, 0, 0, 230, 10, 16, 0, 2, 0, 0, 0, 18, 0, 0, 1, 31, 0, 4, 5, 10, 144, 208, 0, 32, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 9, 18, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 10, 144, 208, 0, 64, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 9, 34, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 26, 144, 208, 0, 64, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 9, 66, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 144, 208, 0, 64, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 9, 130, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 58, 144, 208, 0, 64, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 1, 0, 0, 7, 114, 0, 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 6, 0, 16, 0, 5, 0, 0, 0, 33, 0, 0, 10, 114, 0, 16, 0, 6, 0, 0, 0, 38, 9, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 12, 114, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 150, 151, 208, 0, 64, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 8, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 33, 0, 0, 7, 114, 0, 16, 0, 7, 0, 0, 0, 38, 9, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 38, 9, 16, 0, 1, 0, 0, 0, 40, 0, 0, 5, 114, 0, 16, 0, 9, 0, 0, 0, 38, 9, 16, 0, 1, 0, 0, 0, 34, 0, 0, 7, 114, 0, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 1, 0, 0, 7, 114, 0, 16, 0, 5, 0, 0, 0, 38, 9, 16, 0, 1, 0, 0, 0, 150, 7, 16, 0, 5, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 1, 0, 0, 0, 150, 4, 16, 0, 6, 0, 0, 0, 150, 4, 16, 0, 7, 0, 0, 0, 150, 4, 16, 0, 5, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 18, 0, 0, 1, 41, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 10, 144, 208, 0, 64, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 255, 255, 255, 255, 54, 0, 0, 5, 130, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 0, 0, 7, 242, 0, 16, 0, 4, 0, 0, 0, 246, 15, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 1, 0, 0, 7, 50, 0, 16, 0, 1, 0, 0, 0, 246, 15, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 21, 0, 0, 1, 18, 0, 0, 1, 80, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 1, 0, 0, 0, 31, 0, 4, 5, 10, 144, 208, 0, 32, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 33, 0, 0, 10, 114, 0, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 12, 114, 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 150, 151, 208, 0, 64, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 33, 0, 0, 7, 114, 0, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 40, 0, 0, 5, 114, 0, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 34, 0, 0, 7, 114, 0, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 41, 0, 0, 9, 18, 0, 16, 0, 10, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 26, 144, 208, 0, 64, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 9, 34, 0, 16, 0, 10, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 144, 208, 0, 64, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 9, 66, 0, 16, 0, 10, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 58, 144, 208, 0, 64, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 7, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 33, 0, 0, 10, 114, 0, 16, 0, 5, 0, 0, 0, 38, 9, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 7, 114, 0, 16, 0, 6, 0, 0, 0, 38, 9, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 38, 9, 16, 0, 1, 0, 0, 0, 40, 0, 0, 5, 114, 0, 16, 0, 8, 0, 0, 0, 38, 9, 16, 0, 1, 0, 0, 0, 34, 0, 0, 7, 114, 0, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 1, 0, 0, 7, 114, 0, 16, 0, 9, 0, 0, 0, 38, 9, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 1, 0, 0, 0, 150, 4, 16, 0, 5, 0, 0, 0, 150, 4, 16, 0, 6, 0, 0, 0, 150, 4, 16, 0, 7, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 18, 0, 0, 1, 41, 0, 0, 9, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 10, 144, 208, 0, 64, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 255, 255, 255, 255, 54, 0, 0, 5, 130, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 0, 0, 7, 242, 0, 16, 0, 4, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 1, 0, 0, 7, 50, 0, 16, 0, 1, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 18, 0, 0, 1, 54, 0, 0, 5, 130, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 21, 0, 0, 1, 168, 0, 0, 8, 242, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 168, 0, 0, 8, 50, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 68, 0, 0, 0, 70, 0, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 31, 0, 0, 3, 42, 0, 16, 0, 0, 0, 0, 0, 167, 0, 0, 9, 242, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 167, 0, 0, 9, 50, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 68, 0, 0, 0, 70, 240, 17, 0, 0, 0, 0, 0, 79, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 254, 255, 255, 255, 32, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 5, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 25, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 32, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 2, 8, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 64, 0, 0, 0, 128, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 14, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 17, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 18, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 64, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 4, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 19, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 20, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 21, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 22, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 64, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 24, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 26, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 27, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 0, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 8, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 28, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 29, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 30, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 31, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 64, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 32, 0, 0, 0, 64, 0, 0, 0, 128, 0, 0, 0, 0, 1, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 5, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 128, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 14, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 17, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 64, 0, 0, 0, 128, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 18, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 19, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 20, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 21, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 32, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 22, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 24, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 25, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 26, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 64, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 4, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 27, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 28, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 29, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 30, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 64, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 31, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 18, 0, 0, 1, 32, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 5, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 25, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 32, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 2, 8, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 64, 0, 0, 0, 128, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 14, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 17, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 18, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 64, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 4, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 19, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 20, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 21, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 22, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 64, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 24, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 26, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 27, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 0, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 8, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 28, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 29, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 30, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 31, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 64, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 32, 0, 0, 0, 64, 0, 0, 0, 128, 0, 0, 0, 0, 1, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 5, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 128, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 14, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 17, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 64, 0, 0, 0, 128, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 18, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 19, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 20, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 21, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 32, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 194, 0, 16, 0, 4, 0, 0, 0, 86, 9, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 22, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 64, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 24, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 25, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 26, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 27, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 8, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 28, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 29, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 30, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 31, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 64, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 18, 0, 0, 1, 32, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 5, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 25, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 32, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 2, 8, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 64, 0, 0, 0, 128, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 14, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 17, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 18, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 64, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 4, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 19, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 20, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 21, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 22, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 64, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 24, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 26, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 27, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 0, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 8, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 28, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 29, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 30, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 31, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 64, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 32, 0, 0, 0, 64, 0, 0, 0, 128, 0, 0, 0, 0, 1, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 21, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 16, 0, 0, 0, 0, 32, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 8, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 5, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 128, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 14, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 17, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 64, 0, 0, 0, 128, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 18, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 19, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 20, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 24, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 0, 1, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 194, 0, 16, 0, 4, 0, 0, 0, 86, 9, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 22, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 31, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 64, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 0, 7, 18, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 25, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 26, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 27, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 6, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 28, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 16, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 29, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 30, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 64, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 18, 0, 0, 1, 32, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 14, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 5, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 25, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 32, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 2, 8, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 64, 0, 0, 0, 128, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 14, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 17, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 18, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 64, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 4, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 19, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 20, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 21, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 22, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 64, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 24, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 26, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 27, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 0, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 8, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 28, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 29, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 30, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 31, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 64, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 14, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 32, 0, 0, 0, 64, 0, 0, 0, 128, 0, 0, 0, 0, 1, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 17, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 16, 0, 0, 0, 0, 2, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 8, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 5, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 128, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 42, 0, 0, 7, 194, 0, 16, 0, 4, 0, 0, 0, 6, 4, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 14, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 24, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 64, 0, 0, 0, 128, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 14, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 18, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 19, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 20, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 21, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 32, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 14, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 22, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 27, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 28, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 29, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 64, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 32, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 25, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 26, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 30, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 31, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 64, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 8, 82, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, 21, 0, 0, 1, 21, 0, 0, 1, 21, 0, 0, 1, 18, 0, 0, 1, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 167, 0, 0, 9, 242, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 167, 0, 0, 9, 50, 0, 16, 0, 6, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 68, 0, 0, 0, 70, 240, 17, 0, 0, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 0, 252, 255, 32, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 98, 0, 16, 0, 0, 0, 0, 0, 86, 6, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 25, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 32, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 2, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 64, 0, 0, 0, 128, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 9, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 9, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 14, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 17, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 18, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 64, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 4, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 9, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 19, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 20, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 21, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 22, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 64, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 9, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 24, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 26, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 27, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 0, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 8, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 9, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 28, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 29, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 30, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 31, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 64, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 32, 0, 0, 0, 64, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 20, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 21, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 22, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 1, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 64, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 29, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 9, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 2, 0, 0, 0, 0, 0, 32, 2, 0, 0, 0, 128, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 9, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 194, 0, 16, 0, 0, 0, 0, 0, 86, 9, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 30, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 31, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 64, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 4, 0, 0, 0, 6, 4, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 128, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 6, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 6, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 14, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 17, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 64, 0, 0, 0, 128, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 18, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 19, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 6, 0, 0, 0, 6, 4, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 8, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 6, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 24, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 25, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 26, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 27, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 8, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 28, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 16, 64, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 32, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 85, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 14, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 17, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 64, 0, 0, 0, 128, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 18, 0, 0, 1, 32, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 98, 0, 16, 0, 0, 0, 0, 0, 86, 6, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 42, 0, 0, 7, 194, 0, 16, 0, 2, 0, 0, 0, 166, 6, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 14, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 22, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 24, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 0, 64, 0, 0, 0, 0, 64, 0, 0, 0, 0, 1, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 0, 32, 0, 0, 0, 0, 128, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 9, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 25, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 32, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 2, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 9, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 10, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 10, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 64, 0, 0, 0, 128, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 10, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 10, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 10, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 10, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 10, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 10, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 17, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 10, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 10, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 19, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 0, 0, 0, 0, 6, 4, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 8, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 10, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 10, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 10, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 18, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 10, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 19, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 20, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 10, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 21, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 32, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 10, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 10, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 10, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 10, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 26, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 27, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 28, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 29, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 32, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 30, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 31, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 7, 0, 0, 0, 134, 3, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 64, 16, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 20, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 64, 0, 0, 0, 128, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 29, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 2, 0, 0, 0, 0, 0, 32, 2, 0, 0, 0, 128, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 42, 0, 0, 7, 194, 0, 16, 0, 2, 0, 0, 0, 86, 9, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 30, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 0, 0, 64, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 9, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 128, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 10, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 14, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 10, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 10, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 17, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 64, 0, 0, 0, 128, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 10, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 10, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 10, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 10, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 10, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 18, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 10, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 24, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 10, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 25, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 26, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 4, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 4, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 10, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 21, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 22, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 0, 0, 0, 0, 6, 4, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 64, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 10, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 10, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 10, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 27, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 28, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 0, 0, 0, 0, 6, 4, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 194, 0, 16, 0, 0, 0, 0, 0, 166, 2, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 31, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 1, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 0, 0, 0, 0, 86, 9, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 64, 0, 0, 0, 0, 1, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 32, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 85, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 14, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 17, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 64, 0, 0, 0, 128, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 18, 0, 0, 1, 32, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 25, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 32, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 2, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 64, 0, 0, 0, 128, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 14, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 17, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 18, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 64, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 4, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 19, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 20, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 21, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 22, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 64, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 24, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 26, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 27, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 0, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 8, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 28, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 29, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 30, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 31, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 64, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 32, 0, 0, 0, 64, 0, 0, 0, 128, 0, 0, 0, 0, 1, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 29, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 2, 0, 0, 0, 0, 0, 32, 2, 0, 0, 0, 128, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 42, 0, 0, 7, 194, 0, 16, 0, 0, 0, 0, 0, 86, 9, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 30, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 0, 0, 64, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 0, 0, 0, 0, 6, 4, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 128, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 194, 0, 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 14, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 24, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 64, 0, 0, 0, 128, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 9, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 194, 0, 16, 0, 2, 0, 0, 0, 86, 9, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 17, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 27, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 8, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 18, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 19, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 4, 0, 0, 0, 6, 4, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 8, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 194, 0, 16, 0, 4, 0, 0, 0, 6, 4, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 10, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 20, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 10, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 21, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 10, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 22, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 28, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 64, 0, 0, 0, 0, 16, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 10, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 10, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 10, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 25, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 26, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 0, 0, 0, 0, 6, 4, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 10, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 194, 0, 16, 0, 0, 0, 0, 0, 166, 2, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 31, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 1, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 0, 0, 0, 0, 86, 9, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 0, 0, 0, 0, 6, 4, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 16, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 32, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 85, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 14, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 17, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 64, 0, 0, 0, 128, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 18, 0, 0, 1, 32, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 25, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 32, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 2, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 64, 0, 0, 0, 128, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 14, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 17, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 18, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 64, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 4, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 19, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 20, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 21, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 22, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 64, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 24, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 26, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 27, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 0, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 8, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 28, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 29, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 30, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 31, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 64, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 194, 0, 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 18, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 32, 0, 0, 0, 64, 0, 0, 0, 128, 0, 0, 0, 0, 0, 4, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 20, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 21, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 22, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 1, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 64, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 29, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 9, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 2, 0, 0, 0, 0, 0, 32, 2, 0, 0, 0, 128, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 9, 0, 0, 0, 42, 0, 0, 7, 194, 0, 16, 0, 0, 0, 0, 0, 86, 9, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 10, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 10, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 30, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 0, 0, 64, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 10, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 10, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 10, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 0, 0, 0, 0, 6, 4, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 128, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 11, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 14, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 11, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 11, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 11, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 17, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 64, 0, 0, 0, 128, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 11, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 11, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 11, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 11, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 19, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 32, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 24, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 25, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 26, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 27, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 8, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 28, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 16, 64, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 10, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 194, 0, 16, 0, 0, 0, 0, 0, 166, 2, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 31, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 1, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 0, 0, 0, 0, 86, 9, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 194, 0, 16, 0, 0, 0, 0, 0, 6, 12, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 8, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 32, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 85, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 14, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 17, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 64, 0, 0, 0, 128, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 18, 0, 0, 1, 32, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 25, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 32, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 2, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 64, 0, 0, 0, 128, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 14, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 17, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 18, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 64, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 4, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 19, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 20, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 21, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 22, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 64, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 24, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 26, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 27, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 0, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 8, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 28, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 29, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 30, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 31, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 64, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 194, 0, 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 17, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 32, 0, 0, 0, 64, 0, 0, 0, 128, 0, 0, 0, 0, 0, 2, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 29, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 9, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 2, 0, 0, 0, 0, 0, 32, 2, 0, 0, 0, 128, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 9, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 0, 0, 0, 0, 6, 4, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 128, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 194, 0, 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 14, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 24, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 64, 0, 0, 0, 128, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 18, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 19, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 8, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 194, 0, 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 20, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 21, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 22, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 64, 0, 32, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 25, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 26, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 27, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 28, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 16, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 194, 0, 16, 0, 0, 0, 0, 0, 166, 2, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 30, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 31, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 4, 0, 0, 0, 6, 8, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 4, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 194, 0, 16, 0, 0, 0, 0, 0, 6, 12, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 64, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 4, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 32, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 85, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 14, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 17, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 64, 0, 0, 0, 128, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 18, 0, 0, 1, 32, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 25, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 32, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 2, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 14, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 64, 0, 0, 0, 128, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 194, 0, 16, 0, 0, 0, 0, 0, 166, 6, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 14, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 24, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 64, 0, 0, 0, 0, 0, 1, 0, 4, 0, 0, 0, 8, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 17, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 18, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 19, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 8, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 9, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 20, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 21, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 22, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 64, 0, 0, 0, 128, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 9, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 26, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 27, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 28, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 29, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 32, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 9, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 30, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 31, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 4, 0, 0, 0, 6, 8, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 2, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 194, 0, 16, 0, 0, 0, 0, 0, 86, 1, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 20, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 21, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 0, 1, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 9, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 64, 0, 0, 0, 128, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 29, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 2, 0, 0, 0, 0, 0, 32, 2, 0, 0, 0, 128, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 194, 0, 16, 0, 0, 0, 0, 0, 86, 9, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 30, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 31, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 64, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 4, 0, 0, 0, 6, 4, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 128, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 6, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 6, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 14, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 17, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 64, 0, 0, 0, 128, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 18, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 19, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 6, 0, 0, 0, 6, 4, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 8, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 194, 0, 16, 0, 6, 0, 0, 0, 6, 4, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 22, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 28, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 64, 0, 0, 0, 0, 16, 64, 0, 0, 0, 0, 16, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 6, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 24, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 25, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 26, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 27, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 8, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 9, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 9, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 32, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 85, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 14, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 17, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 64, 0, 0, 0, 128, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 18, 0, 0, 1, 32, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 25, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 32, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 2, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 18, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 64, 0, 0, 0, 128, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 0, 1, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 194, 0, 16, 0, 0, 0, 0, 0, 6, 4, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 32, 0, 0, 0, 0, 128, 0, 2, 0, 0, 0, 4, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 9, 0, 0, 0, 42, 0, 0, 7, 194, 0, 16, 0, 0, 0, 0, 0, 166, 6, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 10, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 14, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 24, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 10, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 64, 0, 0, 0, 0, 0, 1, 0, 4, 0, 0, 0, 8, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 10, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 17, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 18, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 19, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 20, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 16, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 21, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 22, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 26, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 27, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 32, 0, 0, 0, 64, 0, 0, 0, 0, 4, 0, 0, 0, 8, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 10, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 28, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 29, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 30, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 31, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 64, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 0, 0, 0, 0, 6, 4, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 1, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 29, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 2, 0, 0, 0, 0, 0, 32, 2, 0, 0, 0, 128, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 10, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 10, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 194, 0, 16, 0, 0, 0, 0, 0, 86, 9, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 30, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 31, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 64, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 4, 0, 0, 0, 6, 4, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 128, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 6, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 6, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 14, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 17, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 64, 0, 0, 0, 128, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 18, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 19, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 6, 0, 0, 0, 6, 4, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 8, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 194, 0, 16, 0, 6, 0, 0, 0, 6, 4, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 20, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 21, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 22, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 28, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 64, 0, 0, 0, 0, 16, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 6, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 24, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 25, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 26, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 27, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 8, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 9, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 64, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 0, 0, 0, 0, 6, 4, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 32, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 85, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 14, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 17, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 64, 0, 0, 0, 128, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 18, 0, 0, 1, 32, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 25, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 32, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 2, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 22, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 64, 0, 0, 0, 128, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 0, 1, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 19, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 0, 0, 0, 0, 6, 4, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 8, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 194, 0, 16, 0, 2, 0, 0, 0, 166, 6, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 14, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 24, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 64, 0, 0, 0, 0, 128, 0, 0, 0, 0, 1, 0, 4, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 9, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 17, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 18, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 19, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 20, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 16, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 21, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 22, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 26, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 27, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 32, 0, 0, 0, 64, 0, 0, 0, 0, 4, 0, 0, 0, 8, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 28, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 29, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 30, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 31, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 64, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 42, 0, 0, 7, 194, 0, 16, 0, 6, 0, 0, 0, 86, 1, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 20, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 0, 1, 0, 0, 0, 0, 16, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 128, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 29, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 2, 0, 0, 0, 0, 0, 32, 2, 0, 0, 0, 128, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 194, 0, 16, 0, 2, 0, 0, 0, 86, 9, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 30, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 31, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 128, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 6, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 14, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 17, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 64, 0, 0, 0, 128, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 9, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 6, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 18, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 24, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 25, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 26, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 4, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 4, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 9, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 194, 0, 16, 0, 4, 0, 0, 0, 6, 4, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 10, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 21, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 22, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 10, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 28, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 32, 0, 0, 0, 64, 0, 0, 0, 0, 16, 64, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 10, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 10, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 27, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 8, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 10, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 98, 0, 16, 0, 0, 0, 0, 0, 166, 8, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 32, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 10, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 8, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 16, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 32, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 85, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 14, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 17, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 64, 0, 0, 0, 128, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 18, 0, 0, 1, 32, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 25, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 32, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 2, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 26, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 64, 0, 0, 0, 128, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 0, 1, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 42, 0, 0, 7, 194, 0, 16, 0, 2, 0, 0, 0, 86, 1, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 32, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 0, 1, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 9, 0, 0, 0, 42, 0, 0, 7, 194, 0, 16, 0, 0, 0, 0, 0, 166, 6, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 10, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 14, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 10, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 24, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 64, 0, 0, 0, 0, 128, 0, 0, 0, 0, 1, 0, 4, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 10, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 17, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 18, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 19, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 20, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 16, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 21, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 22, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 26, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 27, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 32, 0, 0, 0, 64, 0, 0, 0, 0, 4, 0, 0, 0, 8, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 10, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 10, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 28, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 29, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 30, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 31, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 64, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 128, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 29, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 2, 0, 0, 0, 0, 0, 32, 2, 0, 0, 0, 128, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 10, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 194, 0, 16, 0, 0, 0, 0, 0, 86, 9, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 30, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 31, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 128, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 14, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 17, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 64, 0, 0, 0, 128, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 9, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 18, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 19, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 4, 0, 0, 0, 6, 4, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 8, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 194, 0, 16, 0, 4, 0, 0, 0, 6, 4, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 20, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 21, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 22, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 64, 0, 64, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 9, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 24, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 10, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 25, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 26, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 10, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 27, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 8, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 10, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 10, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 10, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 10, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 28, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 16, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 98, 0, 16, 0, 0, 0, 0, 0, 166, 8, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 32, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 8, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 16, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 32, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 85, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 14, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 17, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 64, 0, 0, 0, 128, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 18, 0, 0, 1, 32, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 25, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 32, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 2, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 30, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 8, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 64, 0, 0, 0, 128, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 8, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 17, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 18, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 4, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 4, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 9, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 31, 0, 0, 0, 1, 0, 0, 10, 210, 0, 16, 0, 2, 0, 0, 0, 6, 9, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 128, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 9, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 19, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 4, 0, 0, 0, 6, 4, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 8, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 82, 0, 16, 0, 2, 0, 0, 0, 166, 9, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 0, 7, 194, 0, 16, 0, 6, 0, 0, 0, 86, 9, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 9, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 14, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 21, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 22, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 24, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 64, 0, 0, 0, 0, 32, 0, 0, 0, 64, 0, 0, 0, 0, 1, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 9, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 42, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 19, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 20, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 26, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 27, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 0, 4, 0, 0, 0, 8, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 28, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 29, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 30, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 64, 16, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 20, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 32, 0, 0, 0, 64, 0, 0, 0, 128, 0, 0, 0, 0, 1, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 29, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 2, 0, 0, 0, 0, 0, 32, 2, 0, 0, 0, 128, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 42, 0, 0, 7, 194, 0, 16, 0, 0, 0, 0, 0, 86, 9, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 30, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 0, 0, 64, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 0, 0, 0, 0, 6, 4, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 128, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 14, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 9, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 17, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 64, 0, 0, 0, 128, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 9, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 42, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 18, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 9, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 24, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 25, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 26, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 4, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 4, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 9, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 21, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 6, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 22, 0, 0, 0, 1, 0, 0, 10, 50, 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 32, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 27, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 28, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 0, 0, 0, 0, 6, 4, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 16, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 194, 0, 16, 0, 0, 0, 0, 0, 166, 2, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 31, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 0, 0, 0, 0, 86, 9, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 42, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 64, 0, 0, 0, 0, 1, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 42, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 42, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 42, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 32, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 85, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 14, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 17, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 64, 0, 0, 0, 128, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 8, 82, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, 21, 0, 0, 1, 21, 0, 0, 1, 21, 0, 0, 1, 21, 0, 0, 1, 21, 0, 0, 1, 21, 0, 0, 1, 21, 0, 0, 1, 21, 0, 0, 1, 21, 0, 0, 1, 21, 0, 0, 1, 168, 0, 0, 9, 242, 224, 17, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 134, 7, 16, 0, 3, 0, 0, 0, 21, 0, 0, 1, 62, 0, 0, 1 }; ================================================ FILE: 3rdParty/DirectXTex/DirectXTex/Shaders/Compiled/BC6HEncode_TryModeG10CS.inc ================================================ #if 0 // // Generated by Microsoft (R) D3D Shader Disassembler // // /// // Input signature: // // Name Index Mask Register SysValue Format Used // -------------------- ----- ------ -------- -------- ------- ------ // no Input // // Output signature: // // Name Index Mask Register SysValue Format Used // -------------------- ----- ------ -------- -------- ------- ------ // no Output cs_4_0 dcl_globalFlags refactoringAllowed dcl_immediateConstantBuffer { { 10, 5, 5, 5}, { 7, 6, 6, 6}, { 11, 5, 4, 4}, { 11, 4, 5, 4}, { 11, 4, 4, 5}, { 9, 5, 5, 5}, { 8, 6, 5, 5}, { 8, 5, 6, 5}, { 8, 5, 5, 6}, { 6, 6, 6, 6}, { 10, 10, 10, 10}, { 11, 9, 9, 9}, { 12, 8, 8, 8}, { 16, 4, 4, 4}, { -1, 0, 0, 0}, { -1, 0, 4, 0}, { -1, 0, 9, 0}, { -1, 1, 13, 0}, { -1, 1, 17, 0}, { -1, 1, 21, 0}, { -1, 1, 26, 0}, { -1, 2, 30, 0}, { -1, 2, 34, 0}, { 0, 2, 38, 0}, { 0, 2, 43, 0}, { -1, 2, 47, 0}, { -1, 3, 51, 0}, { -1, 3, 55, 0}, { 0, 3, 60, 0}, { 0, 3, 64, 0}, { 0, 4, 0, 0}, { 0, 4, 0, 0}, { 0, 4, 0, 0}, { 0, 4, 0, 0}, { 0, 5, 0, 0}, { 0, 5, 0, 0}, { 0, 5, 0, 0}, { 0, 5, 0, 0}, { 0, 6, 0, 0}, { 0, 6, 0, 0}, { 0, 6, 0, 0}, { 0, 6, 0, 0}, { 0, 6, 0, 0}, { 0, 7, 0, 0}, { 0, 7, 0, 0}, { 0, 7, 0, 0}, { 0, 7, 0, 0}, { 0, 8, 0, 0}, { 0, 8, 0, 0}, { 0, 8, 0, 0}, { 0, 8, 0, 0}, { 0, 9, 0, 0}, { 0, 9, 0, 0}, { 0, 9, 0, 0}, { 0, 9, 0, 0}, { 0, 10, 0, 0}, { 0, 10, 0, 0}, { 0, 10, 0, 0}, { 0, 10, 0, 0}, { 0, 10, 0, 0}, { 0, 11, 0, 0}, { 0, 11, 0, 0}, { 0, 11, 0, 0}, { 0, 11, 0, 0}, { 0, 12, 0, 0}, { 0, 12, 0, 0}, { 0, 12, 0, 0}, { 0, 12, 0, 0}, { 0, 13, 0, 0}, { 0, 13, 0, 0}, { 0, 13, 0, 0}, { 0, 13, 0, 0}, { 0, 14, 0, 0}, { 0, 14, 0, 0}, { 0, 14, 0, 0}, { 0, 14, 0, 0}, { 0, 15, 0, 0}, { 0, 15, 0, 0} } dcl_constantbuffer cb0[2], immediateIndexed dcl_resource_texture2d (float,float,float,float) t0 dcl_uav_structured u0, 16 dcl_input vThreadIDInGroupFlattened dcl_input vThreadGroupID.x dcl_temps 19 dcl_tgsm_structured g0, 84, 64 dcl_thread_group 64, 1, 1 ushr r0.x, vThreadIDInGroupFlattened.x, l(4) ishl r0.y, vThreadGroupID.x, l(2) iadd r0.y, r0.y, cb0[1].x iadd r0.x, r0.x, r0.y uge r0.y, r0.x, cb0[1].y if_nz r0.y ret endif and r0.y, vThreadIDInGroupFlattened.x, l(48) iadd r0.z, -r0.y, vThreadIDInGroupFlattened.x ult r1.xyzw, r0.zzzz, l(16, 8, 4, 2) if_nz r1.x udiv r0.w, null, r0.x, cb0[0].y imad r1.x, -r0.w, cb0[0].y, r0.x ishl r1.x, r1.x, l(2) ishl r0.w, r0.w, l(2) and r2.x, r0.z, l(3) iadd r2.x, r1.x, r2.x ushr r1.x, r0.z, l(2) iadd r2.y, r0.w, r1.x mov r2.zw, l(0,0,0,0) ld r2.xyzw, r2.xyzw, t0.xyzw ushr r3.xyz, r2.xyzx, l(16) and r3.xyz, r3.xyzx, l(0x00008000, 0x00008000, 0x00008000, 0) and r4.xyzw, r2.xxyy, l(0x7fffffff, 0x007fffff, 0x7fffffff, 0x007fffff) ult r2.xy, l(0x47ffefff, 0x47ffefff, 0, 0), r4.xzxx ult r5.xy, r4.xzxx, l(0x38800000, 0x38800000, 0, 0) ushr r5.zw, r4.xxxz, l(23) iadd r5.zw, -r5.zzzw, l(0, 0, 113, 113) iadd r4.yw, r4.yyyw, l(0, 0x00800000, 0, 0x00800000) ushr r6.x, r4.y, r5.z ushr r6.y, r4.w, r5.w iadd r4.xy, r4.xzxx, l(0xc8000000, 0xc8000000, 0, 0) movc r4.xy, r5.xyxx, r6.xyxx, r4.xyxx iadd r4.zw, r4.xxxy, l(0, 0, 4095, 4095) ushr r4.xy, r4.xyxx, l(13) and r4.xy, r4.xyxx, l(1, 1, 0, 0) iadd r4.xy, r4.xyxx, r4.zwzz ushr r4.xy, r4.xyxx, l(13) and r4.xy, r4.xyxx, l(0x00007fff, 0x00007fff, 0, 0) movc r2.xy, r2.xyxx, l(0x00007fff,0x00007fff,0,0), r4.xyxx iadd r4.xy, r3.xyxx, r2.xyxx and r2.xy, r2.zzzz, l(0x7fffffff, 0x007fffff, 0, 0) ult r0.w, l(0x47ffefff), r2.x ult r1.x, r2.x, l(0x38800000) ushr r2.z, r2.x, l(23) iadd r2.z, -r2.z, l(113) iadd r2.y, r2.y, l(0x00800000) ushr r2.y, r2.y, r2.z iadd r2.x, r2.x, l(0xc8000000) movc r1.x, r1.x, r2.y, r2.x iadd r2.x, r1.x, l(4095) ushr r1.x, r1.x, l(13) and r1.x, r1.x, l(1) iadd r1.x, r1.x, r2.x ushr r1.x, r1.x, l(13) and r1.x, r1.x, l(0x00007fff) movc r0.w, r0.w, l(0x00007fff), r1.x iadd r4.z, r3.z, r0.w and r2.xyzw, r4.xxyy, l(1023, 0x00007c00, 1023, 0x00007c00) if_nz r2.y ushr r0.w, r4.x, l(10) and r0.w, r0.w, l(31) else if_nz r2.x ishl r1.x, r2.x, l(1) mov r2.y, r1.x mov r0.w, l(0) loop and r3.x, r2.y, l(1024) breakc_nz r3.x iadd r0.w, r0.w, l(-1) ishl r2.y, r2.y, l(1) endloop and r2.x, r2.y, l(1022) else mov r2.x, l(0) mov r0.w, l(-112) endif endif ishl r3.xyz, r4.xyzx, l(16) and r3.xyz, r3.xyzx, l(0x80000000, 0x80000000, 0x80000000, 0) ishl r0.w, r0.w, l(23) iadd r0.w, r0.w, l(0x38000000) or r0.w, r0.w, r3.x ishl r1.x, r2.x, l(13) iadd r5.x, r0.w, r1.x if_nz r2.w ushr r0.w, r4.y, l(10) and r0.w, r0.w, l(31) else if_nz r2.z ishl r1.x, r2.z, l(1) mov r2.x, r1.x mov r0.w, l(0) loop and r2.y, r2.x, l(1024) breakc_nz r2.y iadd r0.w, r0.w, l(-1) ishl r2.x, r2.x, l(1) endloop and r2.z, r2.x, l(1022) else mov r2.z, l(0) mov r0.w, l(-112) endif endif ishl r0.w, r0.w, l(23) iadd r0.w, r0.w, l(0x38000000) or r0.w, r0.w, r3.y ishl r1.x, r2.z, l(13) iadd r5.y, r0.w, r1.x and r2.xy, r4.zzzz, l(1023, 0x00007c00, 0, 0) if_nz r2.y ushr r0.w, r4.z, l(10) and r0.w, r0.w, l(31) else if_nz r2.x ishl r1.x, r2.x, l(1) mov r2.y, r1.x mov r0.w, l(0) loop and r2.z, r2.y, l(1024) breakc_nz r2.z iadd r0.w, r0.w, l(-1) ishl r2.y, r2.y, l(1) endloop and r2.x, r2.y, l(1022) else mov r2.x, l(0) mov r0.w, l(-112) endif endif ishl r0.w, r0.w, l(23) iadd r0.w, r0.w, l(0x38000000) or r0.w, r0.w, r3.z ishl r1.x, r2.x, l(13) iadd r5.z, r0.w, r1.x store_structured g0.xyz, vThreadIDInGroupFlattened.x, l(24), r5.xyzx dp3 r2.w, r5.xyzx, l(0.212600, 0.715200, 0.072200, 0.000000) ieq r0.w, cb0[0].z, l(95) ishl r3.xyz, r4.xyzx, l(6) udiv r3.xyz, null, r3.xyzx, l(31, 31, 31, 0) ult r5.xyz, r4.xyzx, l(0x00008000, 0x00008000, 0x00008000, 0) ieq r6.xyz, r4.xyzx, l(0x00007bff, 0x00007bff, 0x00007bff, 0) ishl r4.xyz, r4.xyzx, l(5) udiv r7.xyz, null, r4.xyzx, l(31, 31, 31, 0) movc r7.xyz, r6.xyzx, l(0x00007fff,0x00007fff,0x00007fff,0), r7.xyzx and r4.xyz, r4.xyzx, l(0x000fffe0, 0x000fffe0, 0x000fffe0, 0) udiv r4.xyz, null, r4.xyzx, l(31, 31, 31, 0) ineg r4.xyz, r4.xyzx movc r4.xyz, r6.xyzx, l(0xffff8001,0xffff8001,0xffff8001,0), r4.xyzx movc r4.xyz, r5.xyzx, r7.xyzx, r4.xyzx movc r2.xyz, r0.wwww, r3.xyzx, r4.xyzx store_structured g0.xyz, vThreadIDInGroupFlattened.x, l(12), r2.xyzx store_structured g0.xyzw, vThreadIDInGroupFlattened.x, l(52), r2.xyzx store_structured g0.xyzw, vThreadIDInGroupFlattened.x, l(68), r2.yzww endif if_nz r1.y ld_structured r2.x, vThreadIDInGroupFlattened.x, l(76), g0.xxxx iadd r0.w, vThreadIDInGroupFlattened.x, l(8) ld_structured r3.x, r0.w, l(76), g0.xxxx lt r1.x, r3.x, r2.x if_nz r1.x ld_structured r2.xyz, r0.w, l(52), g0.xyzx store_structured g0.xyz, vThreadIDInGroupFlattened.x, l(52), r2.xyzx store_structured g0.x, vThreadIDInGroupFlattened.x, l(76), r3.x endif ld_structured r2.x, vThreadIDInGroupFlattened.x, l(80), g0.xxxx ld_structured r3.x, r0.w, l(80), g0.xxxx lt r1.x, r2.x, r3.x if_nz r1.x ld_structured r2.xyz, r0.w, l(64), g0.xyzx store_structured g0.xyz, vThreadIDInGroupFlattened.x, l(64), r2.xyzx store_structured g0.x, vThreadIDInGroupFlattened.x, l(80), r3.x endif endif if_nz r1.z ld_structured r2.x, vThreadIDInGroupFlattened.x, l(76), g0.xxxx iadd r0.w, vThreadIDInGroupFlattened.x, l(4) ld_structured r3.x, r0.w, l(76), g0.xxxx lt r1.x, r3.x, r2.x if_nz r1.x ld_structured r2.xyz, r0.w, l(52), g0.xyzx store_structured g0.xyz, vThreadIDInGroupFlattened.x, l(52), r2.xyzx store_structured g0.x, vThreadIDInGroupFlattened.x, l(76), r3.x endif ld_structured r2.x, vThreadIDInGroupFlattened.x, l(80), g0.xxxx ld_structured r3.x, r0.w, l(80), g0.xxxx lt r1.x, r2.x, r3.x if_nz r1.x ld_structured r2.xyz, r0.w, l(64), g0.xyzx store_structured g0.xyz, vThreadIDInGroupFlattened.x, l(64), r2.xyzx store_structured g0.x, vThreadIDInGroupFlattened.x, l(80), r3.x endif endif if_nz r1.w ld_structured r2.x, vThreadIDInGroupFlattened.x, l(76), g0.xxxx iadd r0.w, vThreadIDInGroupFlattened.x, l(2) ld_structured r3.x, r0.w, l(76), g0.xxxx lt r1.x, r3.x, r2.x if_nz r1.x ld_structured r2.xyz, r0.w, l(52), g0.xyzx store_structured g0.xyz, vThreadIDInGroupFlattened.x, l(52), r2.xyzx store_structured g0.x, vThreadIDInGroupFlattened.x, l(76), r3.x endif ld_structured r2.x, vThreadIDInGroupFlattened.x, l(80), g0.xxxx ld_structured r3.x, r0.w, l(80), g0.xxxx lt r1.x, r2.x, r3.x if_nz r1.x ld_structured r2.xyz, r0.w, l(64), g0.xyzx store_structured g0.xyz, vThreadIDInGroupFlattened.x, l(64), r2.xyzx store_structured g0.x, vThreadIDInGroupFlattened.x, l(80), r3.x endif endif ult r0.w, r0.z, l(1) if_nz r0.w ld_structured r2.x, vThreadIDInGroupFlattened.x, l(76), g0.xxxx iadd r1.x, vThreadIDInGroupFlattened.x, l(1) ld_structured r3.x, r1.x, l(76), g0.xxxx lt r1.y, r3.x, r2.x if_nz r1.y ld_structured r2.xyz, r1.x, l(52), g0.xyzx store_structured g0.xyz, vThreadIDInGroupFlattened.x, l(52), r2.xyzx endif ld_structured r2.x, vThreadIDInGroupFlattened.x, l(80), g0.xxxx ld_structured r3.x, r1.x, l(80), g0.xxxx lt r1.y, r2.x, r3.x if_nz r1.y ld_structured r2.xyz, r1.x, l(64), g0.xyzx store_structured g0.xyz, vThreadIDInGroupFlattened.x, l(64), r2.xyzx endif endif if_z r0.z ld_structured r2.xyz, r0.y, l(52), g0.xyzx ld_structured r3.xyz, r0.y, l(64), g0.xyzx iadd r4.xyz, -r2.xyzx, r3.xyzx itof r4.xyz, r4.xyzx dp3 r1.x, r4.xyzx, r4.xyzx ld_structured r5.xyz, r0.y, l(12), g0.xyzx iadd r5.xyz, -r2.xyzx, r5.xyzx itof r5.xyz, r5.xyzx dp3 r1.y, r4.xyzx, r5.xyzx lt r2.w, l(0.000000), r1.x ge r4.x, r1.y, l(0.000000) and r2.w, r2.w, r4.x mul r1.y, r1.y, l(63.499989) div r1.x, r1.y, r1.x ftou r1.x, r1.x ult r1.x, l(32), r1.x and r1.x, r1.x, r2.w if_nz r1.x mov r3.w, r2.x store_structured g0.xyzw, vThreadIDInGroupFlattened.x, l(52), r3.xyzw store_structured g0.xy, vThreadIDInGroupFlattened.x, l(68), r2.yzyy endif endif if_nz r1.z ld_structured r2.xyz, r0.y, l(52), g0.xyzx ld_structured r3.xyz, r0.y, l(64), g0.xyzx ineg r1.xyz, r2.xyzx iadd r4.xyz, r1.xyzx, r3.xyzx itof r4.xyz, r4.xyzx dp3 r2.w, r4.xyzx, r4.xyzx iadd r5.yz, r0.zzzz, l(0, 10, 11, 0) ieq r6.xy, cb0[0].zzzz, l(95, 96, 0, 0) if_nz r6.x ige r0.z, icb[r5.y + 0].x, l(15) and r0.z, r0.z, l(1) movc r7.xyz, r2.xyzx, l(0,0,0,0), l(1,1,1,0) movc r8.xyz, r3.xyzx, l(0,0,0,0), l(1,1,1,0) or r7.xyz, r0.zzzz, r7.xyzx or r8.xyz, r0.zzzz, r8.xyzx ieq r9.xyz, r2.xyzx, l(0x0000ffff, 0x0000ffff, 0x0000ffff, 0) ieq r10.xyz, r3.xyzx, l(0x0000ffff, 0x0000ffff, 0x0000ffff, 0) ishl r0.z, l(1), icb[r5.y + 0].x iadd r0.z, r0.z, l(-1) ishl r11.xyz, r2.xyzx, icb[r5.y + 0].x ishl r12.xyz, r3.xyzx, icb[r5.y + 0].x ishr r11.xyz, r11.xyzx, l(16) ishr r12.xyz, r12.xyzx, l(16) movc r9.xyz, r9.xyzx, r0.zzzz, r11.xyzx movc r10.xyz, r10.xyzx, r0.zzzz, r12.xyzx movc r7.xyz, r7.xyzx, r2.xyzx, r9.xyzx movc r8.xyz, r8.xyzx, r3.xyzx, r10.xyzx else ige r0.z, icb[r5.y + 0].x, l(16) and r0.z, r0.z, l(1) movc r9.xyz, r2.xyzx, l(0,0,0,0), l(1,1,1,0) movc r10.xyz, r3.xyzx, l(0,0,0,0), l(1,1,1,0) or r9.xyz, r0.zzzz, r9.xyzx or r10.xyz, r0.zzzz, r10.xyzx ige r11.xyz, r2.xyzx, l(0, 0, 0, 0) ige r12.xyz, r3.xyzx, l(0, 0, 0, 0) ieq r13.xyz, r2.xyzx, l(0x00007fff, 0x00007fff, 0x00007fff, 0) ieq r14.xyz, r3.xyzx, l(0x00007fff, 0x00007fff, 0x00007fff, 0) iadd r0.z, l(-1), icb[r5.y + 0].x ishl r3.w, l(1), r0.z iadd r4.w, r3.w, l(-1) ishl r15.xyz, r2.xyzx, r0.z ishl r16.xyz, r3.xyzx, r0.z ishr r15.xyz, r15.xyzx, l(15) ishr r16.xyz, r16.xyzx, l(15) movc r13.xyz, r13.xyzx, r4.wwww, r15.xyzx movc r14.xyz, r14.xyzx, r4.wwww, r16.xyzx ineg r15.xyz, r3.xyzx ieq r16.xyz, r1.xyzx, l(0x00007fff, 0x00007fff, 0x00007fff, 0) ieq r17.xyz, r15.xyzx, l(0x00007fff, 0x00007fff, 0x00007fff, 0) iadd r3.w, -r3.w, l(1) ishl r18.xyz, r1.xyzx, r0.z ishl r15.xyz, r15.xyzx, r0.z ishr r18.xyz, r18.xyzx, l(15) ishr r15.xyz, r15.xyzx, l(15) ineg r18.xyz, r18.xyzx ineg r15.xyz, r15.xyzx movc r16.xyz, r16.xyzx, r3.wwww, r18.xyzx movc r15.xyz, r17.xyzx, r3.wwww, r15.xyzx movc r11.xyz, r11.xyzx, r13.xyzx, r16.xyzx movc r12.xyz, r12.xyzx, r14.xyzx, r15.xyzx movc r7.xyz, r9.xyzx, r2.xyzx, r11.xyzx movc r8.xyz, r10.xyzx, r3.xyzx, r12.xyzx endif iadd r2.xyz, -r7.xyzx, r8.xyzx movc r2.xyz, icb[r5.y + 14].xxxx, r2.xyzx, r8.xyzx ige r3.xyz, r2.xyzx, l(0, 0, 0, 0) iadd r8.xyzw, l(-1, -1, -1, -1), icb[r5.y + 0].xyzw ishl r9.x, l(1), r8.x ishl r9.y, l(1), r8.y ishl r9.z, l(1), r8.z ishl r9.w, l(1), r8.w ige r8.yzw, r2.xxyz, r9.yyzw ineg r10.xyz, r2.xyzx ilt r10.xyz, r9.yzwy, r10.xyzx movc r11.xyz, r3.xyzx, r8.yzwy, r10.xyzx or r0.z, r11.y, r11.x or r11.x, r11.z, r0.z ishl r12.x, l(1), icb[r5.y + 0].x ishl r12.y, l(1), icb[r5.y + 0].y ishl r12.z, l(1), icb[r5.y + 0].z ishl r12.w, l(1), icb[r5.y + 0].w iadd r12.xyzw, r12.xyzw, l(-1, -1, -1, -1) and r7.xyz, r7.xyzx, r12.xxxx iadd r13.xyzw, r9.yzwx, l(-1, -1, -1, -1) movc r8.yzw, r8.yyzw, r13.xxyz, r2.xxyz and r12.yzw, r2.xxyz, r12.yyzw movc r10.xyz, r10.xyzx, r9.yzwy, r12.yzwy movc r11.yzw, r3.xxyz, r8.yyzw, r10.xxyz and r3.yzw, r2.xxyz, r12.xxxx mov r3.x, l(0) movc r3.xyzw, icb[r5.y + 14].xxxx, r11.xyzw, r3.xyzw and r2.xyz, r9.xxxx, r7.xyzx and r8.yzw, r7.xxyz, r13.wwww iadd r8.yzw, -r9.xxxx, r8.yyzw movc r2.xyz, r2.xyzx, r8.yzwy, r7.xyzx movc r2.xyz, r6.yyyy, r2.xyzx, r7.xyzx or r0.z, r6.y, icb[r5.y + 14].x and r6.yzw, r9.yyzw, r3.yyzw and r7.xyz, r13.xyzx, r3.yzwy iadd r7.xyz, -r9.yzwy, r7.xyzx movc r6.yzw, r6.yyzw, r7.xxyz, r3.yyzw movc r3.yzw, r0.zzzz, r6.yyzw, r3.yyzw iadd r6.yzw, r2.xxyz, r3.yyzw movc r3.yzw, icb[r5.y + 14].xxxx, r6.yyzw, r3.yyzw ult r6.yz, icb[r5.y + 0].xxxx, l(0, 15, 16, 0) ieq r7.xyz, r12.xxxx, r2.xyzx ieq r8.yzw, r12.xxxx, r3.yyzw ishl r9.xyz, r2.xyzx, l(16) ishl r10.xyz, r3.yzwy, l(16) iadd r9.xyz, r9.xyzx, l(0x00008000, 0x00008000, 0x00008000, 0) iadd r10.xyz, r10.xyzx, l(0x00008000, 0x00008000, 0x00008000, 0) ushr r9.xyz, r9.xyzx, icb[r5.y + 0].x ushr r10.xyz, r10.xyzx, icb[r5.y + 0].x movc r7.xyz, r7.xyzx, l(0x0000ffff,0x0000ffff,0x0000ffff,0), r9.xyzx movc r8.yzw, r8.yyzw, l(0,0x0000ffff,0x0000ffff,0x0000ffff), r10.xxyz movc r7.xyz, r2.xyzx, r7.xyzx, l(0,0,0,0) movc r8.yzw, r3.yyzw, r8.yyzw, l(0,0,0,0) movc r7.xyz, r6.yyyy, r7.xyzx, r2.xyzx movc r8.yzw, r6.yyyy, r8.yyzw, r3.yyzw ige r9.xyz, r2.xyzx, l(0, 0, 0, 0) ige r10.xyz, r3.yzwy, l(0, 0, 0, 0) imax r11.xyz, -r2.xyzx, r2.xyzx imax r12.xyz, -r3.yzwy, r3.yzwy ige r13.xyz, r11.xyzx, r13.wwww ige r14.xyz, r12.xyzx, r13.wwww ishl r15.xyz, r11.xyzx, l(15) ishl r16.xyz, r12.xyzx, l(15) iadd r15.xyz, r15.xyzx, l(0x00004000, 0x00004000, 0x00004000, 0) iadd r16.xyz, r16.xyzx, l(0x00004000, 0x00004000, 0x00004000, 0) ushr r15.xyz, r15.xyzx, r8.x ushr r16.xyz, r16.xyzx, r8.x movc r13.xyz, r13.xyzx, l(0x00007fff,0x00007fff,0x00007fff,0), r15.xyzx movc r14.xyz, r14.xyzx, l(0x00007fff,0x00007fff,0x00007fff,0), r16.xyzx movc r11.xyz, r11.xyzx, r13.xyzx, l(0,0,0,0) movc r12.xyz, r12.xyzx, r14.xyzx, l(0,0,0,0) ineg r13.xyz, r11.xyzx ineg r14.xyz, r12.xyzx movc r9.xyz, r9.xyzx, r11.xyzx, r13.xyzx movc r10.xyz, r10.xyzx, r12.xyzx, r14.xyzx movc r2.xyz, r6.zzzz, r9.xyzx, r2.xyzx movc r3.yzw, r6.zzzz, r10.xxyz, r3.yyzw movc r2.xyz, r6.xxxx, r7.xyzx, r2.xyzx movc r3.yzw, r6.xxxx, r8.yyzw, r3.yyzw ge r0.z, l(0.000000), r2.w mov r4.w, cb0[0].z mov r5.yw, l(0,0,0,0) loop uge r6.x, r5.w, l(16) breakc_nz r6.x iadd r6.x, r0.y, r5.w ld_structured r7.xyz, r6.x, l(12), g0.xyzx iadd r6.yzw, r1.xxyz, r7.xxyz itof r6.yzw, r6.yyzw dp3 r6.y, r4.xyzx, r6.yzwy ge r6.z, l(0.000000), r6.y or r6.z, r0.z, r6.z lt r6.w, r6.y, r2.w mul r6.y, r6.y, l(63.499989) div r6.y, r6.y, r2.w ftou r6.y, r6.y movc r6.y, r6.w, icb[r6.y + 14].y, l(15) movc r6.y, r6.z, l(0), r6.y iadd r6.z, l(64), -icb[r6.y + 14].z imul null, r7.xyz, r3.yzwy, icb[r6.y + 14].zzzz imad r6.yzw, r2.xxyz, r6.zzzz, r7.xxyz iadd r6.yzw, r6.yyzw, l(0, 32, 32, 32) ishr r6.yzw, r6.yyzw, l(6) ieq r7.x, r4.w, l(95) imul null, r7.yzw, r6.yyzw, l(0, 31, 31, 31) ishr r8.xyz, r7.yzwy, l(6) ilt r9.xyz, r6.yzwy, l(0, 0, 0, 0) imul null, r6.yzw, r6.yyzw, l(0, -31, -31, -31) ishr r6.yzw, r6.yyzw, l(5) ineg r6.yzw, r6.yyzw ishr r7.yzw, r7.yyzw, l(5) movc r6.yzw, r9.xxyz, r6.yyzw, r7.yyzw ilt r7.yzw, r6.yyzw, l(0, 0, 0, 0) ineg r9.xyz, r6.yzwy or r9.xyz, r9.xyzx, l(0x00008000, 0x00008000, 0x00008000, 0) movc r6.yzw, r7.yyzw, r9.xxyz, r6.yyzw movc r6.yzw, r7.xxxx, r8.xxyz, r6.yyzw and r7.xyzw, r6.yyzz, l(1023, 0x00007c00, 1023, 0x00007c00) if_nz r7.y ushr r7.y, r6.y, l(10) and r7.y, r7.y, l(31) else if_nz r7.x ishl r8.x, r7.x, l(1) mov r8.y, r8.x mov r7.y, l(0) loop and r8.z, r8.y, l(1024) breakc_nz r8.z iadd r7.y, r7.y, l(-1) ishl r8.y, r8.y, l(1) endloop and r7.x, r8.y, l(1022) else mov r7.xy, l(0,-112,0,0) endif endif ishl r8.xzw, r6.yyzw, l(16) and r8.xzw, r8.xxzw, l(0x80000000, 0, 0x80000000, 0x80000000) ishl r6.y, r7.y, l(23) iadd r6.y, r6.y, l(0x38000000) or r6.y, r6.y, r8.x ishl r7.x, r7.x, l(13) iadd r9.x, r6.y, r7.x if_nz r7.w ushr r6.y, r6.z, l(10) and r6.y, r6.y, l(31) else if_nz r7.z ishl r6.z, r7.z, l(1) mov r7.x, r6.z mov r6.y, l(0) loop and r7.w, r7.x, l(1024) breakc_nz r7.w iadd r6.y, r6.y, l(-1) ishl r7.x, r7.x, l(1) endloop and r7.z, r7.x, l(1022) else mov r7.z, l(0) mov r6.y, l(-112) endif endif ishl r6.z, r6.y, l(23) iadd r6.z, r6.z, l(0x38000000) or r6.z, r6.z, r8.z ishl r7.z, r7.z, l(13) iadd r9.y, r6.z, r7.z and r7.zw, r6.wwww, l(0, 0, 1023, 0x00007c00) if_nz r7.w ushr r6.z, r6.w, l(10) and r6.z, r6.z, l(31) else if_nz r7.z ishl r6.w, r7.z, l(1) mov r7.w, r6.w mov r6.z, l(0) loop and r8.x, r7.w, l(1024) breakc_nz r8.x iadd r6.z, r6.z, l(-1) ishl r7.w, r7.w, l(1) endloop and r7.z, r7.w, l(1022) else mov r7.z, l(0) mov r6.z, l(-112) endif endif ishl r6.w, r6.z, l(23) iadd r6.w, r6.w, l(0x38000000) or r6.w, r6.w, r8.w ishl r7.z, r7.z, l(13) iadd r9.z, r6.w, r7.z ld_structured r10.xyz, r6.x, l(24), g0.xyzx add r8.xzw, r9.xxyz, -r10.xxyz dp3 r6.x, r8.xzwx, r8.xzwx add r5.y, r5.y, r6.x iadd r5.w, r5.w, l(1) endloop movc r5.x, r3.x, l(100000002004087730000.000000), r5.y store_structured g0.xy, vThreadIDInGroupFlattened.x, l(40), r5.xzxx endif if_nz r1.w ld_structured r1.x, vThreadIDInGroupFlattened.x, l(40), g0.xxxx iadd r0.y, vThreadIDInGroupFlattened.x, l(2) ld_structured r2.yz, r0.y, l(40), g0.xxyx lt r0.z, r2.y, r1.x if_nz r0.z ld_structured r2.x, r0.y, l(40), g0.xxxx store_structured g0.xy, vThreadIDInGroupFlattened.x, l(40), r2.xzxx endif endif if_nz r0.w ld_structured r1.x, vThreadIDInGroupFlattened.x, l(40), g0.xxxx iadd r0.y, vThreadIDInGroupFlattened.x, l(1) ld_structured r2.yz, r0.y, l(40), g0.xxyx lt r0.z, r2.y, r1.x if_nz r0.z ld_structured r2.x, r0.y, l(40), g0.xxxx store_structured g0.xy, vThreadIDInGroupFlattened.x, l(40), r2.xzxx endif ld_structured r1.xy, vThreadIDInGroupFlattened.x, l(40), g0.xyxx mov r1.zw, l(0,0,0,0) store_structured u0.xyzw, r0.x, l(0), r1.xyzw endif ret // Approximately 0 instruction slots used #endif const BYTE BC6HEncode_TryModeG10CS[] = { 68, 88, 66, 67, 170, 22, 38, 105, 9, 0, 89, 149, 206, 186, 157, 215, 127, 90, 232, 184, 1, 0, 0, 0, 148, 63, 0, 0, 3, 0, 0, 0, 44, 0, 0, 0, 60, 0, 0, 0, 76, 0, 0, 0, 73, 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 64, 63, 0, 0, 64, 0, 5, 0, 208, 15, 0, 0, 106, 8, 0, 1, 53, 24, 0, 0, 58, 1, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0, 6, 0, 0, 0, 6, 0, 0, 0, 11, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 11, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 11, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 9, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 8, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 6, 0, 0, 0, 6, 0, 0, 0, 6, 0, 0, 0, 6, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 12, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 2, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 2, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 43, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 2, 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 3, 0, 0, 0, 51, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 3, 0, 0, 0, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 89, 0, 0, 4, 70, 142, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 88, 24, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 158, 0, 0, 4, 0, 224, 17, 0, 0, 0, 0, 0, 16, 0, 0, 0, 95, 0, 0, 2, 0, 64, 2, 0, 95, 0, 0, 2, 18, 16, 2, 0, 104, 0, 0, 2, 19, 0, 0, 0, 160, 0, 0, 5, 0, 240, 17, 0, 0, 0, 0, 0, 84, 0, 0, 0, 64, 0, 0, 0, 155, 0, 0, 4, 64, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 85, 0, 0, 6, 18, 0, 16, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 6, 34, 0, 16, 0, 0, 0, 0, 0, 10, 16, 2, 0, 1, 64, 0, 0, 2, 0, 0, 0, 30, 0, 0, 8, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 128, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 80, 0, 0, 8, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 128, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 21, 0, 0, 1, 1, 0, 0, 6, 34, 0, 16, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 48, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 128, 65, 0, 0, 0, 0, 0, 0, 0, 10, 64, 2, 0, 79, 0, 0, 10, 242, 0, 16, 0, 1, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 1, 0, 0, 0, 78, 0, 0, 9, 130, 0, 16, 0, 0, 0, 0, 0, 0, 208, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 11, 18, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 128, 65, 0, 0, 0, 0, 0, 0, 0, 26, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 7, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 85, 0, 0, 7, 114, 0, 16, 0, 3, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 3, 0, 0, 0, 70, 2, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 128, 0, 0, 0, 128, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 6, 5, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 255, 255, 255, 127, 255, 255, 127, 0, 255, 255, 255, 127, 255, 255, 127, 0, 79, 0, 0, 10, 50, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 255, 239, 255, 71, 255, 239, 255, 71, 0, 0, 0, 0, 0, 0, 0, 0, 134, 0, 16, 0, 4, 0, 0, 0, 79, 0, 0, 10, 50, 0, 16, 0, 5, 0, 0, 0, 134, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 56, 0, 0, 128, 56, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 194, 0, 16, 0, 5, 0, 0, 0, 6, 8, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 30, 0, 0, 11, 194, 0, 16, 0, 5, 0, 0, 0, 166, 14, 16, 128, 65, 0, 0, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 113, 0, 0, 0, 113, 0, 0, 0, 30, 0, 0, 10, 162, 0, 16, 0, 4, 0, 0, 0, 86, 13, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 128, 0, 85, 0, 0, 7, 18, 0, 16, 0, 6, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 85, 0, 0, 7, 34, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 30, 0, 0, 10, 50, 0, 16, 0, 4, 0, 0, 0, 134, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 200, 0, 0, 0, 200, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 50, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 5, 0, 0, 0, 70, 0, 16, 0, 6, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 30, 0, 0, 10, 194, 0, 16, 0, 4, 0, 0, 0, 6, 4, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 15, 0, 0, 255, 15, 0, 0, 85, 0, 0, 7, 50, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 1, 0, 0, 10, 50, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 230, 10, 16, 0, 4, 0, 0, 0, 85, 0, 0, 7, 50, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 1, 0, 0, 10, 50, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 127, 0, 0, 255, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 12, 50, 0, 16, 0, 2, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 255, 127, 0, 0, 255, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 10, 50, 0, 16, 0, 2, 0, 0, 0, 166, 10, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 255, 255, 255, 127, 255, 255, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 255, 239, 255, 71, 10, 0, 16, 0, 2, 0, 0, 0, 79, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 56, 85, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 30, 0, 0, 8, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 128, 65, 0, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 113, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 0, 85, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 200, 55, 0, 0, 9, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 255, 15, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 255, 127, 0, 0, 55, 0, 0, 9, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 255, 127, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 6, 5, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 0, 124, 0, 0, 255, 3, 0, 0, 0, 124, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 2, 0, 0, 0, 85, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 31, 0, 0, 0, 18, 0, 0, 1, 31, 0, 4, 3, 10, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 54, 0, 0, 5, 34, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 48, 0, 0, 1, 1, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 4, 0, 0, 3, 0, 4, 3, 10, 0, 16, 0, 3, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 255, 255, 255, 255, 41, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 22, 0, 0, 1, 1, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 254, 3, 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 18, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 144, 255, 255, 255, 21, 0, 0, 1, 21, 0, 0, 1, 41, 0, 0, 7, 114, 0, 16, 0, 3, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 3, 0, 0, 0, 70, 2, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 128, 0, 0, 0, 128, 0, 0, 0, 128, 0, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 56, 60, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 2, 0, 0, 0, 85, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 31, 0, 0, 0, 18, 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 48, 0, 0, 1, 1, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 4, 0, 0, 3, 0, 4, 3, 26, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 255, 255, 255, 255, 41, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 22, 0, 0, 1, 1, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 254, 3, 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 66, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 144, 255, 255, 255, 21, 0, 0, 1, 21, 0, 0, 1, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 56, 60, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 0, 0, 10, 50, 0, 16, 0, 2, 0, 0, 0, 166, 10, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 0, 124, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 2, 0, 0, 0, 85, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 31, 0, 0, 0, 18, 0, 0, 1, 31, 0, 4, 3, 10, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 54, 0, 0, 5, 34, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 48, 0, 0, 1, 1, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 4, 0, 0, 3, 0, 4, 3, 42, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 255, 255, 255, 255, 41, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 22, 0, 0, 1, 1, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 254, 3, 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 18, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 144, 255, 255, 255, 21, 0, 0, 1, 21, 0, 0, 1, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 56, 60, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 168, 0, 0, 8, 114, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 24, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 16, 0, 0, 10, 130, 0, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 208, 179, 89, 62, 89, 23, 55, 63, 152, 221, 147, 61, 0, 0, 0, 0, 32, 0, 0, 8, 130, 0, 16, 0, 0, 0, 0, 0, 42, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 95, 0, 0, 0, 41, 0, 0, 7, 114, 0, 16, 0, 3, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 78, 0, 0, 11, 114, 0, 16, 0, 3, 0, 0, 0, 0, 208, 0, 0, 70, 2, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 31, 0, 0, 0, 31, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 79, 0, 0, 10, 114, 0, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 128, 0, 0, 0, 128, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 32, 0, 0, 10, 114, 0, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 123, 0, 0, 255, 123, 0, 0, 255, 123, 0, 0, 0, 0, 0, 0, 41, 0, 0, 7, 114, 0, 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 78, 0, 0, 11, 114, 0, 16, 0, 7, 0, 0, 0, 0, 208, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 31, 0, 0, 0, 31, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 255, 127, 0, 0, 255, 127, 0, 0, 255, 127, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 224, 255, 15, 0, 224, 255, 15, 0, 224, 255, 15, 0, 0, 0, 0, 0, 78, 0, 0, 11, 114, 0, 16, 0, 4, 0, 0, 0, 0, 208, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 31, 0, 0, 0, 31, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 5, 114, 0, 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 1, 128, 255, 255, 1, 128, 255, 255, 1, 128, 255, 255, 0, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 2, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 3, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 168, 0, 0, 8, 114, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 12, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 168, 0, 0, 8, 242, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 168, 0, 0, 8, 242, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 68, 0, 0, 0, 150, 15, 16, 0, 2, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 26, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 8, 18, 0, 16, 0, 2, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 76, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 30, 0, 0, 6, 130, 0, 16, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 8, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 76, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 49, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 9, 114, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 242, 17, 0, 0, 0, 0, 0, 168, 0, 0, 8, 114, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 168, 0, 0, 8, 18, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 76, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 21, 0, 0, 1, 167, 0, 0, 8, 18, 0, 16, 0, 2, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 80, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 80, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 49, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 9, 114, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 64, 0, 0, 0, 70, 242, 17, 0, 0, 0, 0, 0, 168, 0, 0, 8, 114, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 64, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 168, 0, 0, 8, 18, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 80, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 21, 0, 0, 1, 21, 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 8, 18, 0, 16, 0, 2, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 76, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 30, 0, 0, 6, 130, 0, 16, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 4, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 76, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 49, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 9, 114, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 242, 17, 0, 0, 0, 0, 0, 168, 0, 0, 8, 114, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 168, 0, 0, 8, 18, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 76, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 21, 0, 0, 1, 167, 0, 0, 8, 18, 0, 16, 0, 2, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 80, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 80, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 49, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 9, 114, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 64, 0, 0, 0, 70, 242, 17, 0, 0, 0, 0, 0, 168, 0, 0, 8, 114, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 64, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 168, 0, 0, 8, 18, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 80, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 21, 0, 0, 1, 21, 0, 0, 1, 31, 0, 4, 3, 58, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 8, 18, 0, 16, 0, 2, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 76, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 30, 0, 0, 6, 130, 0, 16, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 2, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 76, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 49, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 9, 114, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 242, 17, 0, 0, 0, 0, 0, 168, 0, 0, 8, 114, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 168, 0, 0, 8, 18, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 76, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 21, 0, 0, 1, 167, 0, 0, 8, 18, 0, 16, 0, 2, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 80, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 80, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 49, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 9, 114, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 64, 0, 0, 0, 70, 242, 17, 0, 0, 0, 0, 0, 168, 0, 0, 8, 114, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 64, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 168, 0, 0, 8, 18, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 80, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 21, 0, 0, 1, 21, 0, 0, 1, 79, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 0, 0, 0, 0, 167, 0, 0, 8, 18, 0, 16, 0, 2, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 76, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 30, 0, 0, 6, 18, 0, 16, 0, 1, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 1, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 76, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 49, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 9, 114, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 242, 17, 0, 0, 0, 0, 0, 168, 0, 0, 8, 114, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 21, 0, 0, 1, 167, 0, 0, 8, 18, 0, 16, 0, 2, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 80, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 80, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 49, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 9, 114, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 64, 0, 0, 0, 70, 242, 17, 0, 0, 0, 0, 0, 168, 0, 0, 8, 114, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 64, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 21, 0, 0, 1, 21, 0, 0, 1, 31, 0, 0, 3, 42, 0, 16, 0, 0, 0, 0, 0, 167, 0, 0, 9, 114, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 242, 17, 0, 0, 0, 0, 0, 167, 0, 0, 9, 114, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 64, 0, 0, 0, 70, 242, 17, 0, 0, 0, 0, 0, 30, 0, 0, 8, 114, 0, 16, 0, 4, 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 2, 0, 0, 0, 70, 2, 16, 0, 3, 0, 0, 0, 43, 0, 0, 5, 114, 0, 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 16, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 167, 0, 0, 9, 114, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 70, 242, 17, 0, 0, 0, 0, 0, 30, 0, 0, 8, 114, 0, 16, 0, 5, 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 2, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 43, 0, 0, 5, 114, 0, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 16, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 49, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 29, 0, 0, 7, 18, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 56, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 253, 255, 125, 66, 14, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 28, 0, 0, 5, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 79, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 168, 0, 0, 8, 242, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 168, 0, 0, 8, 50, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 68, 0, 0, 0, 150, 5, 16, 0, 2, 0, 0, 0, 21, 0, 0, 1, 21, 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 9, 114, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 242, 17, 0, 0, 0, 0, 0, 167, 0, 0, 9, 114, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 64, 0, 0, 0, 70, 242, 17, 0, 0, 0, 0, 0, 40, 0, 0, 5, 114, 0, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 3, 0, 0, 0, 43, 0, 0, 5, 114, 0, 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 16, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 30, 0, 0, 10, 98, 0, 16, 0, 5, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 11, 50, 0, 16, 0, 6, 0, 0, 0, 166, 138, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 95, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 6, 0, 0, 0, 33, 0, 0, 8, 66, 0, 16, 0, 0, 0, 0, 0, 10, 144, 144, 0, 26, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 55, 0, 0, 15, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 15, 114, 0, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 114, 0, 16, 0, 7, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 60, 0, 0, 7, 114, 0, 16, 0, 8, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 32, 0, 0, 10, 114, 0, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 32, 0, 0, 10, 114, 0, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 41, 0, 0, 8, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 10, 144, 144, 0, 26, 0, 16, 0, 5, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 255, 255, 255, 255, 41, 0, 0, 8, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 10, 144, 144, 0, 26, 0, 16, 0, 5, 0, 0, 0, 41, 0, 0, 8, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 3, 0, 0, 0, 10, 144, 144, 0, 26, 0, 16, 0, 5, 0, 0, 0, 42, 0, 0, 7, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 42, 0, 0, 7, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 3, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 18, 0, 0, 1, 33, 0, 0, 8, 66, 0, 16, 0, 0, 0, 0, 0, 10, 144, 144, 0, 26, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 55, 0, 0, 15, 114, 0, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 15, 114, 0, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 114, 0, 16, 0, 9, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 60, 0, 0, 7, 114, 0, 16, 0, 10, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 33, 0, 0, 10, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 10, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 10, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 255, 127, 0, 0, 255, 127, 0, 0, 255, 127, 0, 0, 0, 0, 0, 0, 32, 0, 0, 10, 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 255, 127, 0, 0, 255, 127, 0, 0, 255, 127, 0, 0, 0, 0, 0, 0, 30, 0, 0, 8, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 255, 255, 255, 255, 10, 144, 144, 0, 26, 0, 16, 0, 5, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 255, 255, 255, 255, 41, 0, 0, 7, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 42, 0, 0, 7, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 246, 15, 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 246, 15, 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 40, 0, 0, 5, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 3, 0, 0, 0, 32, 0, 0, 10, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 255, 127, 0, 0, 255, 127, 0, 0, 255, 127, 0, 0, 0, 0, 0, 0, 32, 0, 0, 10, 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 255, 127, 0, 0, 255, 127, 0, 0, 255, 127, 0, 0, 0, 0, 0, 0, 30, 0, 0, 8, 130, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 128, 65, 0, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 114, 0, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 0, 7, 114, 0, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 42, 0, 0, 7, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 40, 0, 0, 5, 114, 0, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 40, 0, 0, 5, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 246, 15, 16, 0, 3, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 246, 15, 16, 0, 3, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 3, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 21, 0, 0, 1, 30, 0, 0, 8, 114, 0, 16, 0, 2, 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 7, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 55, 0, 0, 11, 114, 0, 16, 0, 2, 0, 0, 0, 6, 144, 208, 0, 14, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 33, 0, 0, 10, 114, 0, 16, 0, 3, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 11, 242, 0, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 70, 158, 144, 0, 26, 0, 16, 0, 5, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 9, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 9, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 9, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 9, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 33, 0, 0, 7, 226, 0, 16, 0, 8, 0, 0, 0, 6, 9, 16, 0, 2, 0, 0, 0, 86, 14, 16, 0, 9, 0, 0, 0, 40, 0, 0, 5, 114, 0, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 34, 0, 0, 7, 114, 0, 16, 0, 10, 0, 0, 0, 150, 7, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 3, 0, 0, 0, 150, 7, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 11, 0, 0, 0, 10, 0, 16, 0, 11, 0, 0, 0, 60, 0, 0, 7, 18, 0, 16, 0, 11, 0, 0, 0, 42, 0, 16, 0, 11, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 8, 18, 0, 16, 0, 12, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 10, 144, 144, 0, 26, 0, 16, 0, 5, 0, 0, 0, 41, 0, 0, 8, 34, 0, 16, 0, 12, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 26, 144, 144, 0, 26, 0, 16, 0, 5, 0, 0, 0, 41, 0, 0, 8, 66, 0, 16, 0, 12, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 144, 144, 0, 26, 0, 16, 0, 5, 0, 0, 0, 41, 0, 0, 8, 130, 0, 16, 0, 12, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 58, 144, 144, 0, 26, 0, 16, 0, 5, 0, 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 1, 0, 0, 7, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 6, 0, 16, 0, 12, 0, 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, 13, 0, 0, 0, 150, 3, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 55, 0, 0, 9, 226, 0, 16, 0, 8, 0, 0, 0, 86, 14, 16, 0, 8, 0, 0, 0, 6, 9, 16, 0, 13, 0, 0, 0, 6, 9, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 226, 0, 16, 0, 12, 0, 0, 0, 6, 9, 16, 0, 2, 0, 0, 0, 86, 14, 16, 0, 12, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 150, 7, 16, 0, 9, 0, 0, 0, 150, 7, 16, 0, 12, 0, 0, 0, 55, 0, 0, 9, 226, 0, 16, 0, 11, 0, 0, 0, 6, 9, 16, 0, 3, 0, 0, 0, 86, 14, 16, 0, 8, 0, 0, 0, 6, 9, 16, 0, 10, 0, 0, 0, 1, 0, 0, 7, 226, 0, 16, 0, 3, 0, 0, 0, 6, 9, 16, 0, 2, 0, 0, 0, 6, 0, 16, 0, 12, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 55, 0, 0, 11, 242, 0, 16, 0, 3, 0, 0, 0, 6, 144, 208, 0, 14, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 1, 0, 0, 7, 114, 0, 16, 0, 2, 0, 0, 0, 6, 0, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 1, 0, 0, 7, 226, 0, 16, 0, 8, 0, 0, 0, 6, 9, 16, 0, 7, 0, 0, 0, 246, 15, 16, 0, 13, 0, 0, 0, 30, 0, 0, 8, 226, 0, 16, 0, 8, 0, 0, 0, 6, 0, 16, 128, 65, 0, 0, 0, 9, 0, 0, 0, 86, 14, 16, 0, 8, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 150, 7, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 2, 0, 0, 0, 86, 5, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 60, 0, 0, 9, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 10, 144, 208, 0, 14, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 1, 0, 0, 7, 226, 0, 16, 0, 6, 0, 0, 0, 86, 14, 16, 0, 9, 0, 0, 0, 86, 14, 16, 0, 3, 0, 0, 0, 1, 0, 0, 7, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 150, 7, 16, 0, 3, 0, 0, 0, 30, 0, 0, 8, 114, 0, 16, 0, 7, 0, 0, 0, 150, 7, 16, 128, 65, 0, 0, 0, 9, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 55, 0, 0, 9, 226, 0, 16, 0, 6, 0, 0, 0, 86, 14, 16, 0, 6, 0, 0, 0, 6, 9, 16, 0, 7, 0, 0, 0, 86, 14, 16, 0, 3, 0, 0, 0, 55, 0, 0, 9, 226, 0, 16, 0, 3, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 86, 14, 16, 0, 6, 0, 0, 0, 86, 14, 16, 0, 3, 0, 0, 0, 30, 0, 0, 7, 226, 0, 16, 0, 6, 0, 0, 0, 6, 9, 16, 0, 2, 0, 0, 0, 86, 14, 16, 0, 3, 0, 0, 0, 55, 0, 0, 11, 226, 0, 16, 0, 3, 0, 0, 0, 6, 144, 208, 0, 14, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 86, 14, 16, 0, 6, 0, 0, 0, 86, 14, 16, 0, 3, 0, 0, 0, 79, 0, 0, 11, 98, 0, 16, 0, 6, 0, 0, 0, 6, 144, 144, 0, 26, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 7, 114, 0, 16, 0, 7, 0, 0, 0, 6, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 32, 0, 0, 7, 226, 0, 16, 0, 8, 0, 0, 0, 6, 0, 16, 0, 12, 0, 0, 0, 86, 14, 16, 0, 3, 0, 0, 0, 41, 0, 0, 7, 114, 0, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 41, 0, 0, 7, 114, 0, 16, 0, 10, 0, 0, 0, 150, 7, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 128, 0, 0, 0, 128, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 128, 0, 0, 0, 128, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 85, 0, 0, 8, 114, 0, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 10, 144, 144, 0, 26, 0, 16, 0, 5, 0, 0, 0, 85, 0, 0, 8, 114, 0, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 10, 144, 144, 0, 26, 0, 16, 0, 5, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 55, 0, 0, 12, 226, 0, 16, 0, 8, 0, 0, 0, 86, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 6, 9, 16, 0, 10, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 12, 226, 0, 16, 0, 8, 0, 0, 0, 86, 14, 16, 0, 3, 0, 0, 0, 86, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 7, 0, 0, 0, 86, 5, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 55, 0, 0, 9, 226, 0, 16, 0, 8, 0, 0, 0, 86, 5, 16, 0, 6, 0, 0, 0, 86, 14, 16, 0, 8, 0, 0, 0, 86, 14, 16, 0, 3, 0, 0, 0, 33, 0, 0, 10, 114, 0, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 10, 114, 0, 16, 0, 10, 0, 0, 0, 150, 7, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 8, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 2, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 36, 0, 0, 8, 114, 0, 16, 0, 12, 0, 0, 0, 150, 7, 16, 128, 65, 0, 0, 0, 3, 0, 0, 0, 150, 7, 16, 0, 3, 0, 0, 0, 33, 0, 0, 7, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 246, 15, 16, 0, 13, 0, 0, 0, 33, 0, 0, 7, 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 246, 15, 16, 0, 13, 0, 0, 0, 41, 0, 0, 7, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 41, 0, 0, 7, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 85, 0, 0, 7, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 255, 127, 0, 0, 255, 127, 0, 0, 255, 127, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 255, 127, 0, 0, 255, 127, 0, 0, 255, 127, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 5, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 40, 0, 0, 5, 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 2, 0, 0, 0, 166, 10, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 55, 0, 0, 9, 226, 0, 16, 0, 3, 0, 0, 0, 166, 10, 16, 0, 6, 0, 0, 0, 6, 9, 16, 0, 10, 0, 0, 0, 86, 14, 16, 0, 3, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 2, 0, 0, 0, 6, 0, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 55, 0, 0, 9, 226, 0, 16, 0, 3, 0, 0, 0, 6, 0, 16, 0, 6, 0, 0, 0, 86, 14, 16, 0, 8, 0, 0, 0, 86, 14, 16, 0, 3, 0, 0, 0, 29, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 54, 0, 0, 6, 130, 0, 16, 0, 4, 0, 0, 0, 42, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 162, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 0, 0, 1, 80, 0, 0, 7, 18, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 3, 0, 4, 3, 10, 0, 16, 0, 6, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 6, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 167, 0, 0, 9, 114, 0, 16, 0, 7, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 70, 242, 17, 0, 0, 0, 0, 0, 30, 0, 0, 7, 226, 0, 16, 0, 6, 0, 0, 0, 6, 9, 16, 0, 1, 0, 0, 0, 6, 9, 16, 0, 7, 0, 0, 0, 43, 0, 0, 5, 226, 0, 16, 0, 6, 0, 0, 0, 86, 14, 16, 0, 6, 0, 0, 0, 16, 0, 0, 7, 34, 0, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 150, 7, 16, 0, 6, 0, 0, 0, 29, 0, 0, 7, 66, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 49, 0, 0, 7, 130, 0, 16, 0, 6, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 56, 0, 0, 7, 34, 0, 16, 0, 6, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 253, 255, 125, 66, 14, 0, 0, 7, 34, 0, 16, 0, 6, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 28, 0, 0, 5, 34, 0, 16, 0, 6, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 55, 0, 0, 11, 34, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 26, 144, 208, 0, 14, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 55, 0, 0, 9, 34, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 30, 0, 0, 10, 66, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 64, 0, 0, 0, 42, 144, 208, 128, 65, 0, 0, 0, 14, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 38, 0, 0, 10, 0, 208, 0, 0, 114, 0, 16, 0, 7, 0, 0, 0, 150, 7, 16, 0, 3, 0, 0, 0, 166, 154, 208, 0, 14, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 35, 0, 0, 9, 226, 0, 16, 0, 6, 0, 0, 0, 6, 9, 16, 0, 2, 0, 0, 0, 166, 10, 16, 0, 6, 0, 0, 0, 6, 9, 16, 0, 7, 0, 0, 0, 30, 0, 0, 10, 226, 0, 16, 0, 6, 0, 0, 0, 86, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 32, 0, 0, 0, 32, 0, 0, 0, 42, 0, 0, 7, 226, 0, 16, 0, 6, 0, 0, 0, 86, 14, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 32, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 95, 0, 0, 0, 38, 0, 0, 11, 0, 208, 0, 0, 226, 0, 16, 0, 7, 0, 0, 0, 86, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 31, 0, 0, 0, 31, 0, 0, 0, 42, 0, 0, 7, 114, 0, 16, 0, 8, 0, 0, 0, 150, 7, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 34, 0, 0, 10, 114, 0, 16, 0, 9, 0, 0, 0, 150, 7, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 11, 0, 208, 0, 0, 226, 0, 16, 0, 6, 0, 0, 0, 86, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 225, 255, 255, 255, 225, 255, 255, 255, 225, 255, 255, 255, 42, 0, 0, 7, 226, 0, 16, 0, 6, 0, 0, 0, 86, 14, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 40, 0, 0, 5, 226, 0, 16, 0, 6, 0, 0, 0, 86, 14, 16, 0, 6, 0, 0, 0, 42, 0, 0, 7, 226, 0, 16, 0, 7, 0, 0, 0, 86, 14, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 55, 0, 0, 9, 226, 0, 16, 0, 6, 0, 0, 0, 6, 9, 16, 0, 9, 0, 0, 0, 86, 14, 16, 0, 6, 0, 0, 0, 86, 14, 16, 0, 7, 0, 0, 0, 34, 0, 0, 10, 226, 0, 16, 0, 7, 0, 0, 0, 86, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 5, 114, 0, 16, 0, 9, 0, 0, 0, 150, 7, 16, 0, 6, 0, 0, 0, 60, 0, 0, 10, 114, 0, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 128, 0, 0, 0, 128, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 226, 0, 16, 0, 6, 0, 0, 0, 86, 14, 16, 0, 7, 0, 0, 0, 6, 9, 16, 0, 9, 0, 0, 0, 86, 14, 16, 0, 6, 0, 0, 0, 55, 0, 0, 9, 226, 0, 16, 0, 6, 0, 0, 0, 6, 0, 16, 0, 7, 0, 0, 0, 6, 9, 16, 0, 8, 0, 0, 0, 86, 14, 16, 0, 6, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 86, 10, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 0, 124, 0, 0, 255, 3, 0, 0, 0, 124, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 7, 0, 0, 0, 85, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 1, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 31, 0, 0, 0, 18, 0, 0, 1, 31, 0, 4, 3, 10, 0, 16, 0, 7, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 54, 0, 0, 5, 34, 0, 16, 0, 8, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 54, 0, 0, 5, 34, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 48, 0, 0, 1, 1, 0, 0, 7, 66, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 1, 64, 0, 0, 0, 4, 0, 0, 3, 0, 4, 3, 42, 0, 16, 0, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 255, 255, 255, 255, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 22, 0, 0, 1, 1, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 1, 64, 0, 0, 254, 3, 0, 0, 18, 0, 0, 1, 54, 0, 0, 8, 50, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 144, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, 21, 0, 0, 1, 41, 0, 0, 7, 210, 0, 16, 0, 8, 0, 0, 0, 86, 14, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 1, 0, 0, 10, 210, 0, 16, 0, 8, 0, 0, 0, 6, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 128, 41, 0, 0, 7, 34, 0, 16, 0, 6, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 6, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 56, 60, 0, 0, 7, 34, 0, 16, 0, 6, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 7, 0, 0, 0, 85, 0, 0, 7, 34, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 1, 0, 0, 7, 34, 0, 16, 0, 6, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 31, 0, 0, 0, 18, 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 7, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 54, 0, 0, 5, 34, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 48, 0, 0, 1, 1, 0, 0, 7, 130, 0, 16, 0, 7, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 0, 4, 0, 0, 3, 0, 4, 3, 58, 0, 16, 0, 7, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 6, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 255, 255, 255, 255, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 22, 0, 0, 1, 1, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 254, 3, 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 66, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 34, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 144, 255, 255, 255, 21, 0, 0, 1, 21, 0, 0, 1, 41, 0, 0, 7, 66, 0, 16, 0, 6, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 56, 60, 0, 0, 7, 66, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 7, 0, 0, 0, 246, 15, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 3, 0, 0, 0, 124, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 7, 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 31, 0, 0, 0, 18, 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 7, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 54, 0, 0, 5, 66, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 48, 0, 0, 1, 1, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 0, 4, 0, 0, 3, 0, 4, 3, 10, 0, 16, 0, 8, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 255, 255, 255, 255, 41, 0, 0, 7, 130, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 22, 0, 0, 1, 1, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 254, 3, 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 66, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 66, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 144, 255, 255, 255, 21, 0, 0, 1, 21, 0, 0, 1, 41, 0, 0, 7, 130, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 56, 60, 0, 0, 7, 130, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 167, 0, 0, 9, 114, 0, 16, 0, 10, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 24, 0, 0, 0, 70, 242, 17, 0, 0, 0, 0, 0, 0, 0, 0, 8, 210, 0, 16, 0, 8, 0, 0, 0, 6, 9, 16, 0, 9, 0, 0, 0, 6, 9, 16, 128, 65, 0, 0, 0, 10, 0, 0, 0, 16, 0, 0, 7, 18, 0, 16, 0, 6, 0, 0, 0, 134, 3, 16, 0, 8, 0, 0, 0, 134, 3, 16, 0, 8, 0, 0, 0, 0, 0, 0, 7, 34, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 22, 0, 0, 1, 55, 0, 0, 9, 18, 0, 16, 0, 5, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 236, 120, 173, 96, 26, 0, 16, 0, 5, 0, 0, 0, 168, 0, 0, 8, 50, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 40, 0, 0, 0, 134, 0, 16, 0, 5, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 58, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 8, 18, 0, 16, 0, 1, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 40, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 30, 0, 0, 6, 34, 0, 16, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 2, 0, 0, 0, 167, 0, 0, 9, 98, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 40, 0, 0, 0, 6, 241, 17, 0, 0, 0, 0, 0, 49, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 40, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 168, 0, 0, 8, 50, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 40, 0, 0, 0, 134, 0, 16, 0, 2, 0, 0, 0, 21, 0, 0, 1, 21, 0, 0, 1, 31, 0, 4, 3, 58, 0, 16, 0, 0, 0, 0, 0, 167, 0, 0, 8, 18, 0, 16, 0, 1, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 40, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 30, 0, 0, 6, 34, 0, 16, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 1, 0, 0, 0, 167, 0, 0, 9, 98, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 40, 0, 0, 0, 6, 241, 17, 0, 0, 0, 0, 0, 49, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 40, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 168, 0, 0, 8, 50, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 40, 0, 0, 0, 134, 0, 16, 0, 2, 0, 0, 0, 21, 0, 0, 1, 167, 0, 0, 8, 50, 0, 16, 0, 1, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 40, 0, 0, 0, 70, 240, 17, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 168, 0, 0, 9, 242, 224, 17, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 62, 0, 0, 1 }; ================================================ FILE: 3rdParty/DirectXTex/DirectXTex/Shaders/Compiled/BC6HEncode_TryModeLE10CS.inc ================================================ #if 0 // // Generated by Microsoft (R) D3D Shader Disassembler // // /// // Input signature: // // Name Index Mask Register SysValue Format Used // -------------------- ----- ------ -------- -------- ------- ------ // no Input // // Output signature: // // Name Index Mask Register SysValue Format Used // -------------------- ----- ------ -------- -------- ------- ------ // no Output cs_4_0 dcl_globalFlags refactoringAllowed dcl_immediateConstantBuffer { { 0x0000cccc, 15, -1, 0}, { 0x00008888, 15, -1, 9}, { 0x0000eeee, 15, -1, 18}, { 0x0000ecc8, 15, -1, 27}, { 0x0000c880, 15, -1, 37}, { 0x0000feec, 15, -1, 46}, { 0x0000fec8, 15, -1, 55}, { 0x0000ec80, 15, -1, 64}, { 0x0000c800, 15, -1, 0}, { 0x0000ffec, 15, 0, 0}, { 0x0000fe80, 15, 0, 0}, { 0x0000e800, 15, -1, 0}, { 0x0000ffe8, 15, -1, 0}, { 0x0000ff00, 15, -1, 0}, { 0x0000fff0, 15, 0, 0}, { 0x0000f000, 15, 0, 0}, { 0x0000f710, 15, 0, 0}, { 142, 2, 0, 0}, { 0x00007100, 8, 0, 0}, { 2254, 2, 0, 0}, { 140, 2, 0, 0}, { 0x00007310, 8, 0, 0}, { 0x00003100, 8, 0, 0}, { 0x00008cce, 15, 0, 0}, { 2188, 2, 0, 0}, { 0x00003110, 8, 0, 0}, { 0x00006666, 2, 0, 0}, { 0x0000366c, 2, 0, 0}, { 6120, 8, 0, 0}, { 4080, 8, 0, 0}, { 0x0000718e, 2, 0, 0}, { 0x0000399c, 2, 0, 0}, { 10, 5, 5, 5}, { 7, 6, 6, 6}, { 11, 5, 4, 4}, { 11, 4, 5, 4}, { 11, 4, 4, 5}, { 9, 5, 5, 5}, { 8, 6, 5, 5}, { 8, 5, 6, 5}, { 8, 5, 5, 6}, { 6, 6, 6, 6}, { 10, 10, 10, 10}, { 11, 9, 9, 9}, { 12, 8, 8, 8}, { 16, 4, 4, 4}, { 0, 0, 0, 0}, { 0, 0, 0, 0}, { 0, 0, 0, 0}, { 0, 0, 0, 0}, { 0, 0, 0, 0}, { 1, 0, 0, 0}, { 1, 0, 0, 0}, { 1, 0, 0, 0}, { 1, 0, 0, 0}, { 1, 0, 0, 0}, { 1, 0, 0, 0}, { 1, 0, 0, 0}, { 1, 0, 0, 0}, { 1, 0, 0, 0}, { 2, 0, 0, 0}, { 2, 0, 0, 0}, { 2, 0, 0, 0}, { 2, 0, 0, 0}, { 2, 0, 0, 0}, { 2, 0, 0, 0}, { 2, 0, 0, 0}, { 2, 0, 0, 0}, { 2, 0, 0, 0}, { 3, 0, 0, 0}, { 3, 0, 0, 0}, { 3, 0, 0, 0}, { 3, 0, 0, 0}, { 3, 0, 0, 0}, { 3, 0, 0, 0}, { 3, 0, 0, 0}, { 3, 0, 0, 0}, { 3, 0, 0, 0}, { 3, 0, 0, 0}, { 4, 0, 0, 0}, { 4, 0, 0, 0}, { 4, 0, 0, 0}, { 4, 0, 0, 0}, { 4, 0, 0, 0}, { 4, 0, 0, 0}, { 4, 0, 0, 0}, { 4, 0, 0, 0}, { 4, 0, 0, 0}, { 5, 0, 0, 0}, { 5, 0, 0, 0}, { 5, 0, 0, 0}, { 5, 0, 0, 0}, { 5, 0, 0, 0}, { 5, 0, 0, 0}, { 5, 0, 0, 0}, { 5, 0, 0, 0}, { 5, 0, 0, 0}, { 6, 0, 0, 0}, { 6, 0, 0, 0}, { 6, 0, 0, 0}, { 6, 0, 0, 0}, { 6, 0, 0, 0}, { 6, 0, 0, 0}, { 6, 0, 0, 0}, { 6, 0, 0, 0}, { 6, 0, 0, 0}, { 7, 0, 0, 0}, { 7, 0, 0, 0}, { 7, 0, 0, 0}, { 7, 0, 0, 0} } dcl_constantbuffer cb0[2], immediateIndexed dcl_resource_texture2d (float,float,float,float) t0 dcl_resource_structured t1, 16 dcl_uav_structured u0, 16 dcl_input vThreadIDInGroupFlattened dcl_input vThreadGroupID.x dcl_temps 25 dcl_indexableTemp x0[6], 4 dcl_indexableTemp x1[2], 4 dcl_tgsm_structured g0, 84, 64 dcl_thread_group 64, 1, 1 ushr r0.x, vThreadIDInGroupFlattened.x, l(5) ishl r0.y, vThreadGroupID.x, l(1) iadd r0.y, r0.y, cb0[1].x iadd r0.x, r0.x, r0.y uge r0.y, r0.x, cb0[1].y if_nz r0.y ret endif ld_structured r1.x, r0.x, l(0), t1.xxxx lt r0.y, r1.x, l(0.000001) if_nz r0.y ld_structured r2.xyzw, r0.x, l(0), t1.xyzw store_structured u0.xyzw, r0.x, l(0), r2.xyzw ret endif and r0.y, vThreadIDInGroupFlattened.x, l(32) iadd r2.z, -r0.y, vThreadIDInGroupFlattened.x ult r3.xyzw, r2.zzzz, l(16, 32, 8, 4) if_nz r3.x udiv r0.z, null, r0.x, cb0[0].y imad r0.w, -r0.z, cb0[0].y, r0.x ishl r0.w, r0.w, l(2) ishl r0.z, r0.z, l(2) and r1.y, r2.z, l(3) iadd r4.x, r0.w, r1.y ushr r0.w, r2.z, l(2) iadd r4.y, r0.w, r0.z mov r4.zw, l(0,0,0,0) ld r4.xyzw, r4.xyzw, t0.xyzw ushr r1.yzw, r4.xxyz, l(16) and r1.yzw, r1.yyzw, l(0, 0x00008000, 0x00008000, 0x00008000) and r5.xyzw, r4.xxyy, l(0x7fffffff, 0x007fffff, 0x7fffffff, 0x007fffff) ult r0.zw, l(0, 0, 0x47ffefff, 0x47ffefff), r5.xxxz ult r4.xy, r5.xzxx, l(0x38800000, 0x38800000, 0, 0) ushr r6.xy, r5.xzxx, l(23) iadd r6.xy, -r6.xyxx, l(113, 113, 0, 0) iadd r5.yw, r5.yyyw, l(0, 0x00800000, 0, 0x00800000) ushr r7.x, r5.y, r6.x ushr r7.y, r5.w, r6.y iadd r5.xy, r5.xzxx, l(0xc8000000, 0xc8000000, 0, 0) movc r4.xy, r4.xyxx, r7.xyxx, r5.xyxx iadd r5.xy, r4.xyxx, l(4095, 4095, 0, 0) ushr r4.xy, r4.xyxx, l(13) and r4.xy, r4.xyxx, l(1, 1, 0, 0) iadd r4.xy, r4.xyxx, r5.xyxx ushr r4.xy, r4.xyxx, l(13) and r4.xy, r4.xyxx, l(0x00007fff, 0x00007fff, 0, 0) movc r0.zw, r0.zzzw, l(0,0,0x00007fff,0x00007fff), r4.xxxy iadd r5.xy, r1.yzyy, r0.zwzz and r0.zw, r4.zzzz, l(0, 0, 0x7fffffff, 0x007fffff) ult r1.y, l(0x47ffefff), r0.z ult r1.z, r0.z, l(0x38800000) ushr r2.w, r0.z, l(23) iadd r2.w, -r2.w, l(113) iadd r0.w, r0.w, l(0x00800000) ushr r0.w, r0.w, r2.w iadd r0.z, r0.z, l(0xc8000000) movc r0.z, r1.z, r0.w, r0.z iadd r0.w, r0.z, l(4095) ushr r0.z, r0.z, l(13) and r0.z, r0.z, l(1) iadd r0.z, r0.z, r0.w ushr r0.z, r0.z, l(13) and r0.z, r0.z, l(0x00007fff) movc r0.z, r1.y, l(0x00007fff), r0.z iadd r5.z, r1.w, r0.z and r4.xyzw, r5.xxyy, l(1023, 0x00007c00, 1023, 0x00007c00) if_nz r4.y ushr r0.z, r5.x, l(10) and r0.z, r0.z, l(31) else if_nz r4.x ishl r0.w, r4.x, l(1) mov r1.y, r0.w mov r0.z, l(0) loop and r1.z, r1.y, l(1024) breakc_nz r1.z iadd r0.z, r0.z, l(-1) ishl r1.y, r1.y, l(1) endloop and r4.x, r1.y, l(1022) else mov r4.x, l(0) mov r0.z, l(-112) endif endif ishl r1.yzw, r5.xxyz, l(16) and r1.yzw, r1.yyzw, l(0, 0x80000000, 0x80000000, 0x80000000) ishl r0.z, r0.z, l(23) iadd r0.z, r0.z, l(0x38000000) or r0.z, r0.z, r1.y ishl r0.w, r4.x, l(13) iadd r6.x, r0.w, r0.z if_nz r4.w ushr r0.z, r5.y, l(10) and r0.z, r0.z, l(31) else if_nz r4.z ishl r0.w, r4.z, l(1) mov r1.y, r0.w mov r0.z, l(0) loop and r2.w, r1.y, l(1024) breakc_nz r2.w iadd r0.z, r0.z, l(-1) ishl r1.y, r1.y, l(1) endloop and r4.z, r1.y, l(1022) else mov r4.z, l(0) mov r0.z, l(-112) endif endif ishl r0.z, r0.z, l(23) iadd r0.z, r0.z, l(0x38000000) or r0.z, r0.z, r1.z ishl r0.w, r4.z, l(13) iadd r6.y, r0.w, r0.z and r0.zw, r5.zzzz, l(0, 0, 1023, 0x00007c00) if_nz r0.w ushr r0.w, r5.z, l(10) and r0.w, r0.w, l(31) else if_nz r0.z ishl r1.y, r0.z, l(1) mov r1.z, r1.y mov r0.w, l(0) loop and r2.w, r1.z, l(1024) breakc_nz r2.w iadd r0.w, r0.w, l(-1) ishl r1.z, r1.z, l(1) endloop and r0.z, r1.z, l(1022) else mov r0.zw, l(0,0,0,-112) endif endif ishl r0.w, r0.w, l(23) iadd r0.w, r0.w, l(0x38000000) or r0.w, r0.w, r1.w ishl r0.z, r0.z, l(13) iadd r6.z, r0.z, r0.w dp3 r6.w, r6.xyzx, l(0.212600, 0.715200, 0.072200, 0.000000) store_structured g0.xyzw, vThreadIDInGroupFlattened.x, l(24), r6.xyzw ieq r0.z, cb0[0].z, l(95) ishl r1.yzw, r5.xxyz, l(6) udiv r1.yzw, null, r1.yyzw, l(0, 31, 31, 31) ult r4.xyz, r5.xyzx, l(0x00008000, 0x00008000, 0x00008000, 0) ieq r6.xyz, r5.xyzx, l(0x00007bff, 0x00007bff, 0x00007bff, 0) ishl r5.xyz, r5.xyzx, l(5) udiv r7.xyz, null, r5.xyzx, l(31, 31, 31, 0) movc r7.xyz, r6.xyzx, l(0x00007fff,0x00007fff,0x00007fff,0), r7.xyzx and r5.xyz, r5.xyzx, l(0x000fffe0, 0x000fffe0, 0x000fffe0, 0) udiv r5.xyz, null, r5.xyzx, l(31, 31, 31, 0) ineg r5.xyz, r5.xyzx movc r5.xyz, r6.xyzx, l(0xffff8001,0xffff8001,0xffff8001,0), r5.xyzx movc r4.xyz, r4.xyzx, r7.xyzx, r5.xyzx movc r1.yzw, r0.zzzz, r1.yyzw, r4.xxyz store_structured g0.xyz, vThreadIDInGroupFlattened.x, l(12), r1.yzwy endif if_nz r3.y mov x0[0].x, l(0x7fffffff) mov x0[1].x, l(0x7fffffff) mov x0[2].x, l(0x7fffffff) mov x0[0].y, l(-0.000000) mov x0[1].y, l(-0.000000) mov x0[2].y, l(-0.000000) mov x0[3].x, l(0x7fffffff) mov x0[4].x, l(0x7fffffff) mov x0[5].x, l(0x7fffffff) mov x0[3].y, l(-0.000000) mov x0[4].y, l(-0.000000) mov x0[5].y, l(-0.000000) mov x1[0].x, l(340282346638528860000000000000000000000.000000) mov x1[0].y, l(-340282346638528860000000000000000000000.000000) mov x1[1].x, l(340282346638528860000000000000000000000.000000) mov x1[1].y, l(-340282346638528860000000000000000000000.000000) mov r0.z, l(0) loop uge r0.w, r0.z, l(16) breakc_nz r0.w iadd r0.w, r0.z, r0.y ld_structured r4.xyz, r0.w, l(12), g0.xyzx ld_structured r5.x, r0.w, l(36), g0.xxxx ushr r0.w, icb[r2.z + 0].x, r0.z and r0.w, r0.w, l(1) if_nz r0.w mov r0.w, x1[1].x lt r1.y, r5.x, r0.w mov r1.z, x0[3].x movc r1.z, r1.y, r4.x, r1.z mov x0[3].x, r1.z mov r1.z, x0[4].x movc r1.z, r1.y, r4.y, r1.z mov x0[4].x, r1.z mov r1.z, x0[5].x movc r1.z, r1.y, r4.z, r1.z mov x0[5].x, r1.z movc r0.w, r1.y, r5.x, r0.w mov x1[1].x, r0.w mov r0.w, x1[1].y lt r1.y, r0.w, r5.x mov r1.z, x0[3].y movc r1.z, r1.y, r4.x, r1.z mov x0[3].y, r1.z mov r1.z, x0[4].y movc r1.z, r1.y, r4.y, r1.z mov x0[4].y, r1.z mov r1.z, x0[5].y movc r1.z, r1.y, r4.z, r1.z mov x0[5].y, r1.z movc r0.w, r1.y, r5.x, r0.w mov x1[1].y, r0.w else mov r0.w, x1[0].x lt r1.y, r5.x, r0.w mov r1.z, x0[0].x movc r1.z, r1.y, r4.x, r1.z mov x0[0].x, r1.z mov r1.z, x0[1].x movc r1.z, r1.y, r4.y, r1.z mov x0[1].x, r1.z mov r1.z, x0[2].x movc r1.z, r1.y, r4.z, r1.z mov x0[2].x, r1.z movc r0.w, r1.y, r5.x, r0.w mov x1[0].x, r0.w mov r0.w, x1[0].y lt r1.y, r0.w, r5.x mov r1.z, x0[0].y movc r1.z, r1.y, r4.x, r1.z mov x0[0].y, r1.z mov r1.z, x0[1].y movc r1.z, r1.y, r4.y, r1.z mov x0[1].y, r1.z mov r1.z, x0[2].y movc r1.z, r1.y, r4.z, r1.z mov x0[2].y, r1.z movc r0.w, r1.y, r5.x, r0.w mov x1[0].y, r0.w endif iadd r0.z, r0.z, l(1) endloop mov r4.x, x0[0].y mov r4.y, x0[1].y mov r4.z, x0[2].y mov r0.z, x0[0].x mov r0.w, x0[1].x mov r1.y, x0[2].x ineg r5.xy, r0.zwzz ineg r5.z, r1.y iadd r6.xyz, r4.xyzx, r5.xyzx itof r6.xyz, r6.xyzx dp3 r1.z, r6.xyzx, r6.xyzx ld_structured r7.xyz, r0.y, l(12), g0.xyzx iadd r5.xyz, r5.xyzx, r7.xyzx itof r5.xyz, r5.xyzx dp3 r1.w, r6.xyzx, r5.xyzx lt r2.w, l(0.000000), r1.z ge r3.y, r1.w, l(0.000000) and r2.w, r2.w, r3.y mul r1.w, r1.w, l(63.499989) div r1.w, r1.w, r1.z ftou r1.w, r1.w ult r1.w, l(32), r1.w and r1.w, r1.w, r2.w movc r5.xyz, r1.wwww, -r6.xyzx, r6.xyzx movc r6.xy, r1.wwww, r4.xyxx, r0.zwzz movc r6.z, r1.w, r4.z, r1.y movc r7.xy, r1.wwww, r0.zwzz, r4.xyxx movc r7.z, r1.w, r1.y, r4.z mov r4.x, x0[3].y mov r4.y, x0[4].y mov r4.z, x0[5].y mov r0.z, x0[3].x mov r0.w, x0[4].x mov r1.y, x0[5].x ineg r8.xy, r0.zwzz ineg r8.z, r1.y iadd r9.xyz, r4.xyzx, r8.xyzx itof r9.xyz, r9.xyzx dp3 r1.w, r9.xyzx, r9.xyzx iadd r2.w, r0.y, icb[r2.z + 0].y ld_structured r10.xyz, r2.w, l(12), g0.xyzx iadd r8.xyz, r8.xyzx, r10.xyzx itof r8.xyz, r8.xyzx dp3 r2.w, r9.xyzx, r8.xyzx lt r3.y, l(0.000000), r1.w ge r4.w, r2.w, l(0.000000) and r3.y, r3.y, r4.w mul r2.w, r2.w, l(63.499989) div r2.w, r2.w, r1.w ftou r2.w, r2.w ult r2.w, l(32), r2.w and r2.w, r2.w, r3.y movc r8.xyz, r2.wwww, -r9.xyzx, r9.xyzx movc r9.xy, r2.wwww, r4.xyxx, r0.zwzz movc r9.z, r2.w, r4.z, r1.y movc r10.xy, r2.wwww, r0.zwzz, r4.xyxx movc r10.z, r2.w, r1.y, r4.z ieq r0.zw, cb0[0].zzzz, l(0, 0, 95, 96) if_nz r0.z mov r1.y, cb0[0].w ige r2.w, icb[r1.y + 32].x, l(15) and r2.w, r2.w, l(1) movc r4.xyz, r6.xyzx, l(0,0,0,0), l(1,1,1,0) movc r11.xyz, r7.xyzx, l(0,0,0,0), l(1,1,1,0) or r4.xyz, r2.wwww, r4.xyzx or r11.xyz, r2.wwww, r11.xyzx ieq r12.xyz, r6.xyzx, l(0x0000ffff, 0x0000ffff, 0x0000ffff, 0) ieq r13.xyz, r7.xyzx, l(0x0000ffff, 0x0000ffff, 0x0000ffff, 0) ishl r3.y, l(1), icb[r1.y + 32].x iadd r3.y, r3.y, l(-1) ishl r14.xyz, r6.xyzx, icb[r1.y + 32].x ishl r15.xyz, r7.xyzx, icb[r1.y + 32].x ishr r14.xyz, r14.xyzx, l(16) ishr r15.xyz, r15.xyzx, l(16) movc r12.xyz, r12.xyzx, r3.yyyy, r14.xyzx movc r13.xyz, r13.xyzx, r3.yyyy, r15.xyzx movc r4.xyz, r4.xyzx, r6.xyzx, r12.xyzx movc r11.xyz, r11.xyzx, r7.xyzx, r13.xyzx movc r12.xyz, r9.xyzx, l(0,0,0,0), l(1,1,1,0) movc r13.xyz, r10.xyzx, l(0,0,0,0), l(1,1,1,0) or r12.xyz, r2.wwww, r12.xyzx or r13.xyz, r2.wwww, r13.xyzx ieq r14.xyz, r9.xyzx, l(0x0000ffff, 0x0000ffff, 0x0000ffff, 0) ieq r15.xyz, r10.xyzx, l(0x0000ffff, 0x0000ffff, 0x0000ffff, 0) mov r1.y, cb0[0].w ishl r16.xyz, r9.xyzx, icb[r1.y + 32].x ishl r17.xyz, r10.xyzx, icb[r1.y + 32].x ishr r16.xyz, r16.xyzx, l(16) ishr r17.xyz, r17.xyzx, l(16) movc r14.xyz, r14.xyzx, r3.yyyy, r16.xyzx movc r15.xyz, r15.xyzx, r3.yyyy, r17.xyzx movc r12.xyz, r12.xyzx, r9.xyzx, r14.xyzx movc r13.xyz, r13.xyzx, r10.xyzx, r15.xyzx else mov r1.y, cb0[0].w ige r2.w, icb[r1.y + 32].x, l(16) and r2.w, r2.w, l(1) movc r14.xyz, r6.xyzx, l(0,0,0,0), l(1,1,1,0) movc r15.xyz, r7.xyzx, l(0,0,0,0), l(1,1,1,0) or r14.xyz, r2.wwww, r14.xyzx or r15.xyz, r2.wwww, r15.xyzx ige r16.xyz, r6.xyzx, l(0, 0, 0, 0) ige r17.xyz, r7.xyzx, l(0, 0, 0, 0) ieq r18.xyz, r6.xyzx, l(0x00007fff, 0x00007fff, 0x00007fff, 0) ieq r19.xyz, r7.xyzx, l(0x00007fff, 0x00007fff, 0x00007fff, 0) iadd r1.y, l(-1), icb[r1.y + 32].x ishl r3.y, l(1), r1.y iadd r4.w, r3.y, l(-1) ishl r20.xyz, r6.xyzx, r1.y ishl r21.xyz, r7.xyzx, r1.y ishr r20.xyz, r20.xyzx, l(15) ishr r21.xyz, r21.xyzx, l(15) movc r18.xyz, r18.xyzx, r4.wwww, r20.xyzx movc r19.xyz, r19.xyzx, r4.wwww, r21.xyzx ineg r20.xyz, r6.xyzx ineg r21.xyz, r7.xyzx ieq r22.xyz, r20.xyzx, l(0x00007fff, 0x00007fff, 0x00007fff, 0) ieq r23.xyz, r21.xyzx, l(0x00007fff, 0x00007fff, 0x00007fff, 0) iadd r3.y, -r3.y, l(1) ishl r20.xyz, r20.xyzx, r1.y ishl r21.xyz, r21.xyzx, r1.y ishr r20.xyz, r20.xyzx, l(15) ishr r21.xyz, r21.xyzx, l(15) ineg r20.xyz, r20.xyzx ineg r21.xyz, r21.xyzx movc r20.xyz, r22.xyzx, r3.yyyy, r20.xyzx movc r21.xyz, r23.xyzx, r3.yyyy, r21.xyzx movc r16.xyz, r16.xyzx, r18.xyzx, r20.xyzx movc r17.xyz, r17.xyzx, r19.xyzx, r21.xyzx movc r4.xyz, r14.xyzx, r6.xyzx, r16.xyzx movc r11.xyz, r15.xyzx, r7.xyzx, r17.xyzx movc r7.xyz, r9.xyzx, l(0,0,0,0), l(1,1,1,0) movc r14.xyz, r10.xyzx, l(0,0,0,0), l(1,1,1,0) or r7.xyz, r2.wwww, r7.xyzx or r14.xyz, r2.wwww, r14.xyzx ige r15.xyz, r9.xyzx, l(0, 0, 0, 0) ige r16.xyz, r10.xyzx, l(0, 0, 0, 0) ieq r17.xyz, r9.xyzx, l(0x00007fff, 0x00007fff, 0x00007fff, 0) ieq r18.xyz, r10.xyzx, l(0x00007fff, 0x00007fff, 0x00007fff, 0) ishl r19.xyz, r9.xyzx, r1.y ishl r20.xyz, r10.xyzx, r1.y ishr r19.xyz, r19.xyzx, l(15) ishr r20.xyz, r20.xyzx, l(15) movc r17.xyz, r17.xyzx, r4.wwww, r19.xyzx movc r18.xyz, r18.xyzx, r4.wwww, r20.xyzx ineg r19.xyz, r9.xyzx ineg r20.xyz, r10.xyzx ieq r21.xyz, r19.xyzx, l(0x00007fff, 0x00007fff, 0x00007fff, 0) ieq r22.xyz, r20.xyzx, l(0x00007fff, 0x00007fff, 0x00007fff, 0) ishl r19.xyz, r19.xyzx, r1.y ishl r20.xyz, r20.xyzx, r1.y ishr r19.xyz, r19.xyzx, l(15) ishr r20.xyz, r20.xyzx, l(15) ineg r19.xyz, r19.xyzx ineg r20.xyz, r20.xyzx movc r19.xyz, r21.xyzx, r3.yyyy, r19.xyzx movc r20.xyz, r22.xyzx, r3.yyyy, r20.xyzx movc r15.xyz, r15.xyzx, r17.xyzx, r19.xyzx movc r16.xyz, r16.xyzx, r18.xyzx, r20.xyzx movc r12.xyz, r7.xyzx, r9.xyzx, r15.xyzx movc r13.xyz, r14.xyzx, r10.xyzx, r16.xyzx endif iadd r7.xyz, -r4.xyzx, r11.xyzx mov r1.y, cb0[0].w movc r7.xyz, icb[r1.y + 0].zzzz, r7.xyzx, r11.xyzx iadd r10.xyz, -r4.xyzx, r12.xyzx movc r10.xyz, icb[r1.y + 0].zzzz, r10.xyzx, r12.xyzx iadd r11.xyz, -r4.xyzx, r13.xyzx movc r11.xyz, icb[r1.y + 0].zzzz, r11.xyzx, r13.xyzx if_nz icb[r1.y + 0].z ige r12.xyz, r7.xyzx, l(0, 0, 0, 0) iadd r13.xyz, l(-1, -1, -1, 0), icb[r1.y + 32].yzwy ishl r14.x, l(1), r13.x ishl r14.y, l(1), r13.y ishl r14.z, l(1), r13.z ige r13.xyz, r7.xyzx, r14.xyzx ineg r15.xyz, r7.xyzx ilt r15.xyz, r14.xyzx, r15.xyzx movc r16.xyz, r12.xyzx, r13.xyzx, r15.xyzx or r2.w, r16.y, r16.x or r2.w, r16.z, r2.w ishl r16.x, l(1), icb[r1.y + 32].x ishl r16.y, l(1), icb[r1.y + 32].y ishl r16.z, l(1), icb[r1.y + 32].z ishl r16.w, l(1), icb[r1.y + 32].w iadd r16.xyzw, r16.xyzw, l(-1, -1, -1, -1) and r17.xyz, r4.xyzx, r16.xxxx iadd r18.xyz, r14.xyzx, l(-1, -1, -1, 0) movc r13.xyz, r13.xyzx, r18.xyzx, r7.xyzx and r19.xyz, r7.xyzx, r16.yzwy movc r15.xyz, r15.xyzx, r14.xyzx, r19.xyzx movc r12.xyz, r12.xyzx, r13.xyzx, r15.xyzx ige r13.xyz, r10.xyzx, l(0, 0, 0, 0) ige r15.xyz, r10.xyzx, r14.xyzx ineg r19.xyz, r10.xyzx ilt r19.xyz, r14.xyzx, r19.xyzx movc r20.xyz, r13.xyzx, r15.xyzx, r19.xyzx ige r21.xyz, r11.xyzx, l(0, 0, 0, 0) ige r22.xyz, r11.xyzx, r14.xyzx ineg r23.xyz, r11.xyzx ilt r23.xyz, r14.xyzx, r23.xyzx movc r24.xyz, r21.xyzx, r22.xyzx, r23.xyzx or r20.xyz, r20.xyzx, r24.xyzx or r3.y, r20.y, r20.x or r3.y, r20.z, r3.y or r2.w, r2.w, r3.y and r2.w, r2.w, l(1) movc r15.xyz, r15.xyzx, r18.xyzx, r10.xyzx and r20.xyz, r10.xyzx, r16.yzwy movc r19.xyz, r19.xyzx, r14.xyzx, r20.xyzx movc r13.xyz, r13.xyzx, r15.xyzx, r19.xyzx movc r15.xyz, r22.xyzx, r18.xyzx, r11.xyzx and r16.xyz, r11.xyzx, r16.yzwy movc r14.xyz, r23.xyzx, r14.xyzx, r16.xyzx movc r14.xyz, r21.xyzx, r15.xyzx, r14.xyzx else ishl r3.y, l(1), icb[r1.y + 32].x iadd r3.y, r3.y, l(-1) and r17.xyz, r3.yyyy, r4.xyzx and r12.xyz, r3.yyyy, r7.xyzx and r13.xyz, r3.yyyy, r10.xyzx and r14.xyz, r3.yyyy, r11.xyzx mov r2.w, l(0) endif iadd r4.xyzw, l(-1, -1, -1, -1), icb[r1.y + 32].xyzw ishl r7.x, l(1), r4.x ishl r7.y, l(1), r4.y ishl r7.z, l(1), r4.z ishl r7.w, l(1), r4.w and r4.yzw, r7.xxxx, r17.xxyz iadd r10.xyzw, r7.xyzw, l(-1, -1, -1, -1) and r11.xyz, r10.xxxx, r17.xyzx iadd r11.xyz, -r7.xxxx, r11.xyzx movc r4.yzw, r4.yyzw, r11.xxyz, r17.xxyz movc r4.yzw, r0.wwww, r4.yyzw, r17.xxyz or r0.w, r0.w, icb[r1.y + 0].z and r11.xyz, r7.yzwy, r12.xyzx and r15.xyz, r10.yzwy, r12.xyzx iadd r15.xyz, -r7.yzwy, r15.xyzx movc r11.xyz, r11.xyzx, r15.xyzx, r12.xyzx movc r11.xyz, r0.wwww, r11.xyzx, r12.xyzx and r12.xyz, r7.yzwy, r13.xyzx and r15.xyz, r10.yzwy, r13.xyzx iadd r15.xyz, -r7.yzwy, r15.xyzx movc r12.xyz, r12.xyzx, r15.xyzx, r13.xyzx movc r12.xyz, r0.wwww, r12.xyzx, r13.xyzx and r13.xyz, r7.yzwy, r14.xyzx and r10.yzw, r10.yyzw, r14.xxyz iadd r7.xyz, -r7.yzwy, r10.yzwy movc r7.xyz, r13.xyzx, r7.xyzx, r14.xyzx movc r7.xyz, r0.wwww, r7.xyzx, r14.xyzx iadd r10.yzw, r4.yyzw, r11.xxyz movc r10.yzw, icb[r1.y + 0].zzzz, r10.yyzw, r11.xxyz iadd r11.xyz, r4.yzwy, r12.xyzx movc r11.xyz, icb[r1.y + 0].zzzz, r11.xyzx, r12.xyzx iadd r12.xyz, r4.yzwy, r7.xyzx movc r7.xyz, icb[r1.y + 0].zzzz, r12.xyzx, r7.xyzx ult r12.xy, icb[r1.y + 32].xxxx, l(15, 16, 0, 0) ishl r0.w, l(1), icb[r1.y + 32].x iadd r0.w, r0.w, l(-1) ieq r13.xyz, r0.wwww, r4.yzwy ieq r14.xyz, r0.wwww, r10.yzwy ishl r15.xyz, r4.yzwy, l(16) ishl r16.xyz, r10.yzwy, l(16) iadd r15.xyz, r15.xyzx, l(0x00008000, 0x00008000, 0x00008000, 0) iadd r16.xyz, r16.xyzx, l(0x00008000, 0x00008000, 0x00008000, 0) ushr r15.xyz, r15.xyzx, icb[r1.y + 32].x ushr r16.xyz, r16.xyzx, icb[r1.y + 32].x movc r13.xyz, r13.xyzx, l(0x0000ffff,0x0000ffff,0x0000ffff,0), r15.xyzx movc r14.xyz, r14.xyzx, l(0x0000ffff,0x0000ffff,0x0000ffff,0), r16.xyzx movc r13.xyz, r4.yzwy, r13.xyzx, l(0,0,0,0) movc r14.xyz, r10.yzwy, r14.xyzx, l(0,0,0,0) movc r13.xyz, r12.xxxx, r13.xyzx, r4.yzwy movc r14.xyz, r12.xxxx, r14.xyzx, r10.yzwy ige r15.xyz, r4.yzwy, l(0, 0, 0, 0) ige r16.xyz, r10.yzwy, l(0, 0, 0, 0) imax r17.xyz, -r4.yzwy, r4.yzwy imax r18.xyz, -r10.yzwy, r10.yzwy ige r19.xyz, r17.xyzx, r10.xxxx ige r20.xyz, r18.xyzx, r10.xxxx ishl r21.xyz, r17.xyzx, l(15) ishl r22.xyz, r18.xyzx, l(15) iadd r21.xyz, r21.xyzx, l(0x00004000, 0x00004000, 0x00004000, 0) iadd r22.xyz, r22.xyzx, l(0x00004000, 0x00004000, 0x00004000, 0) ushr r21.xyz, r21.xyzx, r4.x ushr r22.xyz, r22.xyzx, r4.x movc r19.xyz, r19.xyzx, l(0x00007fff,0x00007fff,0x00007fff,0), r21.xyzx movc r20.xyz, r20.xyzx, l(0x00007fff,0x00007fff,0x00007fff,0), r22.xyzx movc r17.xyz, r17.xyzx, r19.xyzx, l(0,0,0,0) movc r18.xyz, r18.xyzx, r20.xyzx, l(0,0,0,0) ineg r19.xyz, r17.xyzx ineg r20.xyz, r18.xyzx movc r15.xyz, r15.xyzx, r17.xyzx, r19.xyzx movc r16.xyz, r16.xyzx, r18.xyzx, r20.xyzx movc r4.yzw, r12.yyyy, r15.xxyz, r4.yyzw movc r10.yzw, r12.yyyy, r16.xxyz, r10.yyzw movc r4.yzw, r0.zzzz, r13.xxyz, r4.yyzw movc r10.yzw, r0.zzzz, r14.xxyz, r10.yyzw ieq r13.xyz, r0.wwww, r11.xyzx ieq r14.xyz, r0.wwww, r7.xyzx ishl r15.xyz, r11.xyzx, l(16) ishl r16.xyz, r7.xyzx, l(16) iadd r15.xyz, r15.xyzx, l(0x00008000, 0x00008000, 0x00008000, 0) iadd r16.xyz, r16.xyzx, l(0x00008000, 0x00008000, 0x00008000, 0) ushr r15.xyz, r15.xyzx, icb[r1.y + 32].x ushr r16.xyz, r16.xyzx, icb[r1.y + 32].x movc r13.xyz, r13.xyzx, l(0x0000ffff,0x0000ffff,0x0000ffff,0), r15.xyzx movc r14.xyz, r14.xyzx, l(0x0000ffff,0x0000ffff,0x0000ffff,0), r16.xyzx movc r13.xyz, r11.xyzx, r13.xyzx, l(0,0,0,0) movc r14.xyz, r7.xyzx, r14.xyzx, l(0,0,0,0) movc r13.xyz, r12.xxxx, r13.xyzx, r11.xyzx movc r12.xzw, r12.xxxx, r14.xxyz, r7.xxyz ige r14.xyz, r11.xyzx, l(0, 0, 0, 0) ige r15.xyz, r7.xyzx, l(0, 0, 0, 0) imax r16.xyz, -r11.xyzx, r11.xyzx imax r17.xyz, -r7.xyzx, r7.xyzx ige r18.xyz, r16.xyzx, r10.xxxx ige r19.xyz, r17.xyzx, r10.xxxx ishl r20.xyz, r16.xyzx, l(15) ishl r21.xyz, r17.xyzx, l(15) iadd r20.xyz, r20.xyzx, l(0x00004000, 0x00004000, 0x00004000, 0) iadd r21.xyz, r21.xyzx, l(0x00004000, 0x00004000, 0x00004000, 0) ushr r20.xyz, r20.xyzx, r4.x ushr r21.xyz, r21.xyzx, r4.x movc r18.xyz, r18.xyzx, l(0x00007fff,0x00007fff,0x00007fff,0), r20.xyzx movc r19.xyz, r19.xyzx, l(0x00007fff,0x00007fff,0x00007fff,0), r21.xyzx movc r16.xyz, r16.xyzx, r18.xyzx, l(0,0,0,0) movc r17.xyz, r17.xyzx, r19.xyzx, l(0,0,0,0) ineg r18.xyz, r16.xyzx ineg r19.xyz, r17.xyzx movc r14.xyz, r14.xyzx, r16.xyzx, r18.xyzx movc r15.xyz, r15.xyzx, r17.xyzx, r19.xyzx movc r11.xyz, r12.yyyy, r14.xyzx, r11.xyzx movc r7.xyz, r12.yyyy, r15.xyzx, r7.xyzx movc r11.xyz, r0.zzzz, r13.xyzx, r11.xyzx movc r7.xyz, r0.zzzz, r12.xzwx, r7.xyzx ge r0.zw, l(0.000000, 0.000000, 0.000000, 0.000000), r1.wwwz mov r1.y, cb0[0].z mov r3.y, l(0) mov r4.x, l(0) loop uge r5.w, r4.x, l(16) breakc_nz r5.w ushr r5.w, icb[r2.z + 0].x, r4.x and r5.w, r5.w, l(1) if_nz r5.w iadd r5.w, r0.y, r4.x ld_structured r12.xyz, r5.w, l(12), g0.xyzx iadd r12.xyz, -r9.xyzx, r12.xyzx itof r12.xyz, r12.xyzx dp3 r5.w, r8.xyzx, r12.xyzx ge r6.w, l(0.000000), r5.w or r6.w, r0.z, r6.w lt r7.w, r5.w, r1.w mul r5.w, r5.w, l(63.499989) div r5.w, r5.w, r1.w ftou r5.w, r5.w movc r5.w, r7.w, icb[r5.w + 46].x, l(7) movc r5.w, r6.w, l(0), r5.w iadd r6.w, l(64), -icb[r5.w + 0].w imul null, r12.xyz, r7.xyzx, icb[r5.w + 0].wwww imad r12.xyz, r11.xyzx, r6.wwww, r12.xyzx iadd r12.xyz, r12.xyzx, l(32, 32, 32, 0) ishr r12.xyz, r12.xyzx, l(6) ieq r5.w, r1.y, l(95) imul null, r13.xyz, r12.xyzx, l(31, 31, 31, 0) ishr r14.xyz, r13.xyzx, l(6) ilt r15.xyz, r12.xyzx, l(0, 0, 0, 0) imul null, r12.xyz, r12.xyzx, l(-31, -31, -31, 0) ishr r12.xyz, r12.xyzx, l(5) ineg r12.xyz, r12.xyzx ishr r13.xyz, r13.xyzx, l(5) movc r12.xyz, r15.xyzx, r12.xyzx, r13.xyzx ilt r13.xyz, r12.xyzx, l(0, 0, 0, 0) ineg r15.xyz, r12.xyzx or r15.xyz, r15.xyzx, l(0x00008000, 0x00008000, 0x00008000, 0) movc r12.xyz, r13.xyzx, r15.xyzx, r12.xyzx movc r12.xyz, r5.wwww, r14.xyzx, r12.xyzx else iadd r5.w, r0.y, r4.x ld_structured r13.xyz, r5.w, l(12), g0.xyzx iadd r13.xyz, -r6.xyzx, r13.xyzx itof r13.xyz, r13.xyzx dp3 r5.w, r5.xyzx, r13.xyzx ge r6.w, l(0.000000), r5.w or r6.w, r0.w, r6.w lt r7.w, r5.w, r1.z mul r5.w, r5.w, l(63.499989) div r5.w, r5.w, r1.z ftou r5.w, r5.w movc r5.w, r7.w, icb[r5.w + 46].x, l(7) movc r5.w, r6.w, l(0), r5.w iadd r6.w, l(64), -icb[r5.w + 0].w imul null, r13.xyz, r10.yzwy, icb[r5.w + 0].wwww imad r13.xyz, r4.yzwy, r6.wwww, r13.xyzx iadd r13.xyz, r13.xyzx, l(32, 32, 32, 0) ishr r13.xyz, r13.xyzx, l(6) ieq r5.w, r1.y, l(95) imul null, r14.xyz, r13.xyzx, l(31, 31, 31, 0) ishr r15.xyz, r14.xyzx, l(6) ilt r16.xyz, r13.xyzx, l(0, 0, 0, 0) imul null, r13.xyz, r13.xyzx, l(-31, -31, -31, 0) ishr r13.xyz, r13.xyzx, l(5) ineg r13.xyz, r13.xyzx ishr r14.xyz, r14.xyzx, l(5) movc r13.xyz, r16.xyzx, r13.xyzx, r14.xyzx ilt r14.xyz, r13.xyzx, l(0, 0, 0, 0) ineg r16.xyz, r13.xyzx or r16.xyz, r16.xyzx, l(0x00008000, 0x00008000, 0x00008000, 0) movc r13.xyz, r14.xyzx, r16.xyzx, r13.xyzx movc r12.xyz, r5.wwww, r15.xyzx, r13.xyzx endif and r13.xy, r12.xxxx, l(1023, 0x00007c00, 0, 0) if_nz r13.y ushr r5.w, r12.x, l(10) and r5.w, r5.w, l(31) else if_nz r13.x ishl r6.w, r13.x, l(1) mov r7.w, r6.w mov r5.w, l(0) loop and r8.w, r7.w, l(1024) breakc_nz r8.w iadd r5.w, r5.w, l(-1) ishl r7.w, r7.w, l(1) endloop and r13.x, r7.w, l(1022) else mov r13.x, l(0) mov r5.w, l(-112) endif endif ishl r6.w, r12.x, l(16) and r6.w, r6.w, l(0x80000000) ishl r8.w, r5.w, l(23) iadd r8.w, r8.w, l(0x38000000) or r6.w, r6.w, r8.w ishl r8.w, r13.x, l(13) iadd r13.x, r6.w, r8.w and r12.xw, r12.yyyy, l(1023, 0, 0, 0x00007c00) if_nz r12.w ushr r6.w, r12.y, l(10) and r6.w, r6.w, l(31) else if_nz r12.x ishl r8.w, r12.x, l(1) mov r9.w, r8.w mov r6.w, l(0) loop and r10.x, r9.w, l(1024) breakc_nz r10.x iadd r6.w, r6.w, l(-1) ishl r9.w, r9.w, l(1) endloop and r12.x, r9.w, l(1022) else mov r12.x, l(0) mov r6.w, l(-112) endif endif ishl r8.w, r12.y, l(16) and r8.w, r8.w, l(0x80000000) ishl r10.x, r6.w, l(23) iadd r10.x, r10.x, l(0x38000000) or r8.w, r8.w, r10.x ishl r10.x, r12.x, l(13) iadd r13.y, r8.w, r10.x and r12.xy, r12.zzzz, l(1023, 0x00007c00, 0, 0) if_nz r12.y ushr r8.w, r12.z, l(10) and r8.w, r8.w, l(31) else if_nz r12.x ishl r10.x, r12.x, l(1) mov r11.w, r10.x mov r8.w, l(0) loop and r12.y, r11.w, l(1024) breakc_nz r12.y iadd r8.w, r8.w, l(-1) ishl r11.w, r11.w, l(1) endloop and r12.x, r11.w, l(1022) else mov r12.x, l(0) mov r8.w, l(-112) endif endif ishl r10.x, r12.z, l(16) and r10.x, r10.x, l(0x80000000) ishl r12.y, r8.w, l(23) iadd r12.y, r12.y, l(0x38000000) or r10.x, r10.x, r12.y ishl r12.x, r12.x, l(13) iadd r13.z, r10.x, r12.x iadd r10.x, r0.y, r4.x ld_structured r12.xyz, r10.x, l(24), g0.xyzx add r12.xyz, -r12.xyzx, r13.xyzx dp3 r10.x, r12.xyzx, r12.xyzx add r3.y, r3.y, r10.x iadd r4.x, r4.x, l(1) endloop movc r2.x, r2.w, l(100000002004087730000.000000), r3.y iadd r2.y, cb0[0].w, l(1) store_structured g0.xyz, vThreadIDInGroupFlattened.x, l(40), r2.xyzx endif if_nz r3.x ld_structured r4.x, vThreadIDInGroupFlattened.x, l(40), g0.xxxx iadd r0.y, vThreadIDInGroupFlattened.x, l(16) ld_structured r5.yzw, r0.y, l(40), g0.xxyz lt r0.z, r5.y, r4.x if_nz r0.z ld_structured r5.x, r0.y, l(40), g0.xxxx store_structured g0.xyz, vThreadIDInGroupFlattened.x, l(40), r5.xzwx endif endif if_nz r3.z ld_structured r4.x, vThreadIDInGroupFlattened.x, l(40), g0.xxxx iadd r0.y, vThreadIDInGroupFlattened.x, l(8) ld_structured r5.yzw, r0.y, l(40), g0.xxyz lt r0.z, r5.y, r4.x if_nz r0.z ld_structured r5.x, r0.y, l(40), g0.xxxx store_structured g0.xyz, vThreadIDInGroupFlattened.x, l(40), r5.xzwx endif endif if_nz r3.w ld_structured r3.x, vThreadIDInGroupFlattened.x, l(40), g0.xxxx iadd r0.y, vThreadIDInGroupFlattened.x, l(4) ld_structured r4.yzw, r0.y, l(40), g0.xxyz lt r0.z, r4.y, r3.x if_nz r0.z ld_structured r4.x, r0.y, l(40), g0.xxxx store_structured g0.xyz, vThreadIDInGroupFlattened.x, l(40), r4.xzwx endif endif ult r0.yz, r2.zzzz, l(0, 2, 1, 0) if_nz r0.y ld_structured r2.x, vThreadIDInGroupFlattened.x, l(40), g0.xxxx iadd r0.y, vThreadIDInGroupFlattened.x, l(2) ld_structured r3.yzw, r0.y, l(40), g0.xxyz lt r0.w, r3.y, r2.x if_nz r0.w ld_structured r3.x, r0.y, l(40), g0.xxxx store_structured g0.xyz, vThreadIDInGroupFlattened.x, l(40), r3.xzwx endif endif if_nz r0.z ld_structured r2.x, vThreadIDInGroupFlattened.x, l(40), g0.xxxx iadd r0.y, vThreadIDInGroupFlattened.x, l(1) ld_structured r3.yzw, r0.y, l(40), g0.xxyz lt r0.z, r3.y, r2.x if_nz r0.z ld_structured r3.x, r0.y, l(40), g0.xxxx store_structured g0.xyz, vThreadIDInGroupFlattened.x, l(40), r3.xzwx endif ld_structured r2.x, vThreadIDInGroupFlattened.x, l(40), g0.xxxx lt r0.y, r2.x, r1.x if_nz r0.y ld_structured r1.xyz, vThreadIDInGroupFlattened.x, l(40), g0.xyzx mov r1.w, l(0) else ld_structured r1.xyzw, r0.x, l(0), t1.xyzw endif store_structured u0.xyzw, r0.x, l(0), r1.xyzw endif ret // Approximately 0 instruction slots used #endif const BYTE BC6HEncode_TryModeLE10CS[] = { 68, 88, 66, 67, 191, 79, 190, 54, 160, 248, 4, 120, 116, 121, 130, 112, 95, 120, 188, 77, 1, 0, 0, 0, 32, 97, 0, 0, 3, 0, 0, 0, 44, 0, 0, 0, 60, 0, 0, 0, 76, 0, 0, 0, 73, 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 204, 96, 0, 0, 64, 0, 5, 0, 51, 24, 0, 0, 106, 8, 0, 1, 53, 24, 0, 0, 186, 1, 0, 0, 204, 204, 0, 0, 15, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 136, 136, 0, 0, 15, 0, 0, 0, 255, 255, 255, 255, 9, 0, 0, 0, 238, 238, 0, 0, 15, 0, 0, 0, 255, 255, 255, 255, 18, 0, 0, 0, 200, 236, 0, 0, 15, 0, 0, 0, 255, 255, 255, 255, 27, 0, 0, 0, 128, 200, 0, 0, 15, 0, 0, 0, 255, 255, 255, 255, 37, 0, 0, 0, 236, 254, 0, 0, 15, 0, 0, 0, 255, 255, 255, 255, 46, 0, 0, 0, 200, 254, 0, 0, 15, 0, 0, 0, 255, 255, 255, 255, 55, 0, 0, 0, 128, 236, 0, 0, 15, 0, 0, 0, 255, 255, 255, 255, 64, 0, 0, 0, 0, 200, 0, 0, 15, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 236, 255, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 254, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 232, 0, 0, 15, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 232, 255, 0, 0, 15, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 255, 0, 0, 15, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 240, 255, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 240, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 247, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 142, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 113, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 206, 8, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 115, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 206, 140, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 140, 8, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 49, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 102, 102, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 108, 54, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 232, 23, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 240, 15, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 142, 113, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156, 57, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0, 6, 0, 0, 0, 6, 0, 0, 0, 11, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 11, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 11, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 9, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 8, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 6, 0, 0, 0, 6, 0, 0, 0, 6, 0, 0, 0, 6, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 12, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 89, 0, 0, 4, 70, 142, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 88, 24, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 162, 0, 0, 4, 0, 112, 16, 0, 1, 0, 0, 0, 16, 0, 0, 0, 158, 0, 0, 4, 0, 224, 17, 0, 0, 0, 0, 0, 16, 0, 0, 0, 95, 0, 0, 2, 0, 64, 2, 0, 95, 0, 0, 2, 18, 16, 2, 0, 104, 0, 0, 2, 25, 0, 0, 0, 105, 0, 0, 4, 0, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 105, 0, 0, 4, 1, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 160, 0, 0, 5, 0, 240, 17, 0, 0, 0, 0, 0, 84, 0, 0, 0, 64, 0, 0, 0, 155, 0, 0, 4, 64, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 85, 0, 0, 6, 18, 0, 16, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 6, 34, 0, 16, 0, 0, 0, 0, 0, 10, 16, 2, 0, 1, 64, 0, 0, 1, 0, 0, 0, 30, 0, 0, 8, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 128, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 80, 0, 0, 8, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 128, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 21, 0, 0, 1, 167, 0, 0, 9, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 6, 112, 16, 0, 1, 0, 0, 0, 49, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 189, 55, 134, 53, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 167, 0, 0, 9, 242, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 70, 126, 16, 0, 1, 0, 0, 0, 168, 0, 0, 9, 242, 224, 17, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 62, 0, 0, 1, 21, 0, 0, 1, 1, 0, 0, 6, 34, 0, 16, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 32, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 128, 65, 0, 0, 0, 0, 0, 0, 0, 10, 64, 2, 0, 79, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 166, 10, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 3, 0, 0, 0, 78, 0, 0, 9, 66, 0, 16, 0, 0, 0, 0, 0, 0, 208, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 11, 130, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 128, 65, 0, 0, 0, 0, 0, 0, 0, 26, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 85, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 7, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 85, 0, 0, 7, 226, 0, 16, 0, 1, 0, 0, 0, 6, 9, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 1, 0, 0, 10, 226, 0, 16, 0, 1, 0, 0, 0, 86, 14, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 128, 0, 0, 0, 128, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 6, 5, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 255, 255, 127, 255, 255, 127, 0, 255, 255, 255, 127, 255, 255, 127, 0, 79, 0, 0, 10, 194, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 239, 255, 71, 255, 239, 255, 71, 6, 8, 16, 0, 5, 0, 0, 0, 79, 0, 0, 10, 50, 0, 16, 0, 4, 0, 0, 0, 134, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 56, 0, 0, 128, 56, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 50, 0, 16, 0, 6, 0, 0, 0, 134, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 30, 0, 0, 11, 50, 0, 16, 0, 6, 0, 0, 0, 70, 0, 16, 128, 65, 0, 0, 0, 6, 0, 0, 0, 2, 64, 0, 0, 113, 0, 0, 0, 113, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 162, 0, 16, 0, 5, 0, 0, 0, 86, 13, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 128, 0, 85, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 85, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 30, 0, 0, 10, 50, 0, 16, 0, 5, 0, 0, 0, 134, 0, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 200, 0, 0, 0, 200, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 50, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 7, 0, 0, 0, 70, 0, 16, 0, 5, 0, 0, 0, 30, 0, 0, 10, 50, 0, 16, 0, 5, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 15, 0, 0, 255, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 50, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 1, 0, 0, 10, 50, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 5, 0, 0, 0, 85, 0, 0, 7, 50, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 1, 0, 0, 10, 50, 0, 16, 0, 4, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 127, 0, 0, 255, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 12, 194, 0, 16, 0, 0, 0, 0, 0, 166, 14, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 127, 0, 0, 255, 127, 0, 0, 6, 4, 16, 0, 4, 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 5, 0, 0, 0, 150, 5, 16, 0, 1, 0, 0, 0, 230, 10, 16, 0, 0, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 0, 0, 0, 0, 166, 10, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 127, 255, 255, 127, 0, 79, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 255, 239, 255, 71, 42, 0, 16, 0, 0, 0, 0, 0, 79, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 56, 85, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 30, 0, 0, 8, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 128, 65, 0, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 113, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 0, 85, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 200, 55, 0, 0, 9, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 255, 15, 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 255, 127, 0, 0, 55, 0, 0, 9, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 255, 127, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 6, 5, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 0, 124, 0, 0, 255, 3, 0, 0, 0, 124, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 4, 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 31, 0, 0, 0, 18, 0, 0, 1, 31, 0, 4, 3, 10, 0, 16, 0, 4, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 54, 0, 0, 5, 34, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 48, 0, 0, 1, 1, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 4, 0, 0, 3, 0, 4, 3, 42, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 255, 255, 255, 255, 41, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 22, 0, 0, 1, 1, 0, 0, 7, 18, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 254, 3, 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 18, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 144, 255, 255, 255, 21, 0, 0, 1, 21, 0, 0, 1, 41, 0, 0, 7, 226, 0, 16, 0, 1, 0, 0, 0, 6, 9, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 1, 0, 0, 10, 226, 0, 16, 0, 1, 0, 0, 0, 86, 14, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 128, 0, 0, 0, 128, 41, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 56, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 4, 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 31, 0, 0, 0, 18, 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 4, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 54, 0, 0, 5, 34, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 48, 0, 0, 1, 1, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 4, 0, 0, 3, 0, 4, 3, 58, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 255, 255, 255, 255, 41, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 22, 0, 0, 1, 1, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 254, 3, 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 66, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 144, 255, 255, 255, 21, 0, 0, 1, 21, 0, 0, 1, 41, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 56, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 0, 0, 0, 0, 166, 10, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 3, 0, 0, 0, 124, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 31, 0, 0, 0, 18, 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 54, 0, 0, 5, 66, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 48, 0, 0, 1, 1, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 4, 0, 0, 3, 0, 4, 3, 58, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 255, 255, 255, 255, 41, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 22, 0, 0, 1, 1, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 254, 3, 0, 0, 18, 0, 0, 1, 54, 0, 0, 8, 194, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 144, 255, 255, 255, 21, 0, 0, 1, 21, 0, 0, 1, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 56, 60, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 16, 0, 0, 10, 130, 0, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 208, 179, 89, 62, 89, 23, 55, 63, 152, 221, 147, 61, 0, 0, 0, 0, 168, 0, 0, 8, 242, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 24, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 32, 0, 0, 8, 66, 0, 16, 0, 0, 0, 0, 0, 42, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 95, 0, 0, 0, 41, 0, 0, 7, 226, 0, 16, 0, 1, 0, 0, 0, 6, 9, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 78, 0, 0, 11, 226, 0, 16, 0, 1, 0, 0, 0, 0, 208, 0, 0, 86, 14, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 31, 0, 0, 0, 31, 0, 0, 0, 79, 0, 0, 10, 114, 0, 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 128, 0, 0, 0, 128, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 32, 0, 0, 10, 114, 0, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 255, 123, 0, 0, 255, 123, 0, 0, 255, 123, 0, 0, 0, 0, 0, 0, 41, 0, 0, 7, 114, 0, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 78, 0, 0, 11, 114, 0, 16, 0, 7, 0, 0, 0, 0, 208, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 31, 0, 0, 0, 31, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 255, 127, 0, 0, 255, 127, 0, 0, 255, 127, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 224, 255, 15, 0, 224, 255, 15, 0, 224, 255, 15, 0, 0, 0, 0, 0, 78, 0, 0, 11, 114, 0, 16, 0, 5, 0, 0, 0, 0, 208, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 31, 0, 0, 0, 31, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 5, 114, 0, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 1, 128, 255, 255, 1, 128, 255, 255, 1, 128, 255, 255, 0, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 55, 0, 0, 9, 226, 0, 16, 0, 1, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 86, 14, 16, 0, 1, 0, 0, 0, 6, 9, 16, 0, 4, 0, 0, 0, 168, 0, 0, 8, 114, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 12, 0, 0, 0, 150, 7, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 26, 0, 16, 0, 3, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 255, 255, 255, 127, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 255, 255, 255, 127, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 255, 255, 255, 127, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 128, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 128, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 128, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 255, 255, 255, 127, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 64, 0, 0, 255, 255, 255, 127, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 5, 0, 0, 0, 1, 64, 0, 0, 255, 255, 255, 127, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 128, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 128, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 5, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 128, 54, 0, 0, 6, 18, 48, 32, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 255, 255, 127, 127, 54, 0, 0, 6, 34, 48, 32, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 255, 255, 127, 255, 54, 0, 0, 6, 18, 48, 32, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 255, 255, 127, 127, 54, 0, 0, 6, 34, 48, 32, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 255, 255, 127, 255, 54, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 48, 0, 0, 1, 80, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 3, 0, 4, 3, 58, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 167, 0, 0, 9, 114, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 70, 242, 17, 0, 0, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 36, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 85, 0, 0, 8, 130, 0, 16, 0, 0, 0, 0, 0, 10, 144, 144, 0, 42, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 130, 0, 16, 0, 0, 0, 0, 0, 10, 48, 32, 0, 1, 0, 0, 0, 1, 0, 0, 0, 49, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 66, 0, 16, 0, 1, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 3, 0, 0, 0, 55, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 3, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 54, 0, 0, 6, 66, 0, 16, 0, 1, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 4, 0, 0, 0, 55, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 4, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 54, 0, 0, 6, 66, 0, 16, 0, 1, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 5, 0, 0, 0, 55, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 5, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 55, 0, 0, 9, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 1, 0, 0, 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 130, 0, 16, 0, 0, 0, 0, 0, 26, 48, 32, 0, 1, 0, 0, 0, 1, 0, 0, 0, 49, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 54, 0, 0, 6, 66, 0, 16, 0, 1, 0, 0, 0, 26, 48, 32, 0, 0, 0, 0, 0, 3, 0, 0, 0, 55, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 3, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 54, 0, 0, 6, 66, 0, 16, 0, 1, 0, 0, 0, 26, 48, 32, 0, 0, 0, 0, 0, 4, 0, 0, 0, 55, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 4, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 54, 0, 0, 6, 66, 0, 16, 0, 1, 0, 0, 0, 26, 48, 32, 0, 0, 0, 0, 0, 5, 0, 0, 0, 55, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 5, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 55, 0, 0, 9, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 1, 0, 0, 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 6, 130, 0, 16, 0, 0, 0, 0, 0, 10, 48, 32, 0, 1, 0, 0, 0, 0, 0, 0, 0, 49, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 66, 0, 16, 0, 1, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 54, 0, 0, 6, 66, 0, 16, 0, 1, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 55, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 54, 0, 0, 6, 66, 0, 16, 0, 1, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 55, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 55, 0, 0, 9, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 1, 0, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 130, 0, 16, 0, 0, 0, 0, 0, 26, 48, 32, 0, 1, 0, 0, 0, 0, 0, 0, 0, 49, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 54, 0, 0, 6, 66, 0, 16, 0, 1, 0, 0, 0, 26, 48, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 54, 0, 0, 6, 66, 0, 16, 0, 1, 0, 0, 0, 26, 48, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 55, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 54, 0, 0, 6, 66, 0, 16, 0, 1, 0, 0, 0, 26, 48, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 55, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 55, 0, 0, 9, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 1, 0, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 21, 0, 0, 1, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 22, 0, 0, 1, 54, 0, 0, 6, 18, 0, 16, 0, 4, 0, 0, 0, 26, 48, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 34, 0, 16, 0, 4, 0, 0, 0, 26, 48, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 54, 0, 0, 6, 66, 0, 16, 0, 4, 0, 0, 0, 26, 48, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 54, 0, 0, 6, 66, 0, 16, 0, 0, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 130, 0, 16, 0, 0, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 54, 0, 0, 6, 34, 0, 16, 0, 1, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 40, 0, 0, 5, 50, 0, 16, 0, 5, 0, 0, 0, 230, 10, 16, 0, 0, 0, 0, 0, 40, 0, 0, 5, 66, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 43, 0, 0, 5, 114, 0, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 16, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 167, 0, 0, 9, 114, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 70, 242, 17, 0, 0, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 43, 0, 0, 5, 114, 0, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 16, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 49, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 29, 0, 0, 7, 34, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 56, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 253, 255, 125, 66, 14, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 28, 0, 0, 5, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 79, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 55, 0, 0, 10, 114, 0, 16, 0, 5, 0, 0, 0, 246, 15, 16, 0, 1, 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 6, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 55, 0, 0, 9, 50, 0, 16, 0, 6, 0, 0, 0, 246, 15, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 230, 10, 16, 0, 0, 0, 0, 0, 55, 0, 0, 9, 66, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 55, 0, 0, 9, 50, 0, 16, 0, 7, 0, 0, 0, 246, 15, 16, 0, 1, 0, 0, 0, 230, 10, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 55, 0, 0, 9, 66, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 54, 0, 0, 6, 18, 0, 16, 0, 4, 0, 0, 0, 26, 48, 32, 0, 0, 0, 0, 0, 3, 0, 0, 0, 54, 0, 0, 6, 34, 0, 16, 0, 4, 0, 0, 0, 26, 48, 32, 0, 0, 0, 0, 0, 4, 0, 0, 0, 54, 0, 0, 6, 66, 0, 16, 0, 4, 0, 0, 0, 26, 48, 32, 0, 0, 0, 0, 0, 5, 0, 0, 0, 54, 0, 0, 6, 66, 0, 16, 0, 0, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 3, 0, 0, 0, 54, 0, 0, 6, 130, 0, 16, 0, 0, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 4, 0, 0, 0, 54, 0, 0, 6, 34, 0, 16, 0, 1, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 5, 0, 0, 0, 40, 0, 0, 5, 50, 0, 16, 0, 8, 0, 0, 0, 230, 10, 16, 0, 0, 0, 0, 0, 40, 0, 0, 5, 66, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 43, 0, 0, 5, 114, 0, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 16, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 30, 0, 0, 8, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 26, 144, 144, 0, 42, 0, 16, 0, 2, 0, 0, 0, 167, 0, 0, 9, 114, 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 70, 242, 17, 0, 0, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 43, 0, 0, 5, 114, 0, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 16, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 49, 0, 0, 7, 34, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 29, 0, 0, 7, 130, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 34, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 56, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 253, 255, 125, 66, 14, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 28, 0, 0, 5, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 79, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 55, 0, 0, 10, 114, 0, 16, 0, 8, 0, 0, 0, 246, 15, 16, 0, 2, 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 9, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 55, 0, 0, 9, 50, 0, 16, 0, 9, 0, 0, 0, 246, 15, 16, 0, 2, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 230, 10, 16, 0, 0, 0, 0, 0, 55, 0, 0, 9, 66, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 55, 0, 0, 9, 50, 0, 16, 0, 10, 0, 0, 0, 246, 15, 16, 0, 2, 0, 0, 0, 230, 10, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 55, 0, 0, 9, 66, 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 32, 0, 0, 11, 194, 0, 16, 0, 0, 0, 0, 0, 166, 138, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95, 0, 0, 0, 96, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 34, 0, 16, 0, 1, 0, 0, 0, 58, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 9, 130, 0, 16, 0, 2, 0, 0, 0, 10, 144, 208, 0, 32, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 55, 0, 0, 15, 114, 0, 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 15, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 114, 0, 16, 0, 4, 0, 0, 0, 246, 15, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 60, 0, 0, 7, 114, 0, 16, 0, 11, 0, 0, 0, 246, 15, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 32, 0, 0, 10, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 32, 0, 0, 10, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 41, 0, 0, 9, 34, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 10, 144, 208, 0, 32, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 255, 255, 255, 255, 41, 0, 0, 9, 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 10, 144, 208, 0, 32, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 9, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 10, 144, 208, 0, 32, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 42, 0, 0, 7, 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 42, 0, 0, 7, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 86, 5, 16, 0, 3, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 86, 5, 16, 0, 3, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 55, 0, 0, 15, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 15, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 114, 0, 16, 0, 12, 0, 0, 0, 246, 15, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 60, 0, 0, 7, 114, 0, 16, 0, 13, 0, 0, 0, 246, 15, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 32, 0, 0, 10, 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 32, 0, 0, 10, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 34, 0, 16, 0, 1, 0, 0, 0, 58, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 9, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 10, 144, 208, 0, 32, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 9, 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 10, 144, 208, 0, 32, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 42, 0, 0, 7, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 42, 0, 0, 7, 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 86, 5, 16, 0, 3, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 86, 5, 16, 0, 3, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 6, 34, 0, 16, 0, 1, 0, 0, 0, 58, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 9, 130, 0, 16, 0, 2, 0, 0, 0, 10, 144, 208, 0, 32, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 55, 0, 0, 15, 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 15, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 114, 0, 16, 0, 14, 0, 0, 0, 246, 15, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 60, 0, 0, 7, 114, 0, 16, 0, 15, 0, 0, 0, 246, 15, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 33, 0, 0, 10, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 10, 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 10, 114, 0, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 255, 127, 0, 0, 255, 127, 0, 0, 255, 127, 0, 0, 0, 0, 0, 0, 32, 0, 0, 10, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 255, 127, 0, 0, 255, 127, 0, 0, 255, 127, 0, 0, 0, 0, 0, 0, 30, 0, 0, 9, 34, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 255, 255, 255, 255, 10, 144, 208, 0, 32, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 255, 255, 255, 255, 41, 0, 0, 7, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 7, 114, 0, 16, 0, 21, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 42, 0, 0, 7, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 42, 0, 0, 7, 114, 0, 16, 0, 21, 0, 0, 0, 70, 2, 16, 0, 21, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 246, 15, 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 246, 15, 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 21, 0, 0, 0, 40, 0, 0, 5, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 40, 0, 0, 5, 114, 0, 16, 0, 21, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 32, 0, 0, 10, 114, 0, 16, 0, 22, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 2, 64, 0, 0, 255, 127, 0, 0, 255, 127, 0, 0, 255, 127, 0, 0, 0, 0, 0, 0, 32, 0, 0, 10, 114, 0, 16, 0, 23, 0, 0, 0, 70, 2, 16, 0, 21, 0, 0, 0, 2, 64, 0, 0, 255, 127, 0, 0, 255, 127, 0, 0, 255, 127, 0, 0, 0, 0, 0, 0, 30, 0, 0, 8, 34, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 128, 65, 0, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 7, 114, 0, 16, 0, 21, 0, 0, 0, 70, 2, 16, 0, 21, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 42, 0, 0, 7, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 42, 0, 0, 7, 114, 0, 16, 0, 21, 0, 0, 0, 70, 2, 16, 0, 21, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 40, 0, 0, 5, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 40, 0, 0, 5, 114, 0, 16, 0, 21, 0, 0, 0, 70, 2, 16, 0, 21, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 22, 0, 0, 0, 86, 5, 16, 0, 3, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 21, 0, 0, 0, 70, 2, 16, 0, 23, 0, 0, 0, 86, 5, 16, 0, 3, 0, 0, 0, 70, 2, 16, 0, 21, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 21, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 55, 0, 0, 15, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 15, 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 114, 0, 16, 0, 7, 0, 0, 0, 246, 15, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 60, 0, 0, 7, 114, 0, 16, 0, 14, 0, 0, 0, 246, 15, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 33, 0, 0, 10, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 10, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 10, 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 255, 127, 0, 0, 255, 127, 0, 0, 255, 127, 0, 0, 0, 0, 0, 0, 32, 0, 0, 10, 114, 0, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 255, 127, 0, 0, 255, 127, 0, 0, 255, 127, 0, 0, 0, 0, 0, 0, 41, 0, 0, 7, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 7, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 42, 0, 0, 7, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 42, 0, 0, 7, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 246, 15, 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 246, 15, 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 40, 0, 0, 5, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 40, 0, 0, 5, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 32, 0, 0, 10, 114, 0, 16, 0, 21, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 255, 127, 0, 0, 255, 127, 0, 0, 255, 127, 0, 0, 0, 0, 0, 0, 32, 0, 0, 10, 114, 0, 16, 0, 22, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 2, 64, 0, 0, 255, 127, 0, 0, 255, 127, 0, 0, 255, 127, 0, 0, 0, 0, 0, 0, 41, 0, 0, 7, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 7, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 42, 0, 0, 7, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 42, 0, 0, 7, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 40, 0, 0, 5, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 40, 0, 0, 5, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 21, 0, 0, 0, 86, 5, 16, 0, 3, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 22, 0, 0, 0, 86, 5, 16, 0, 3, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 21, 0, 0, 1, 30, 0, 0, 8, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 4, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 54, 0, 0, 6, 34, 0, 16, 0, 1, 0, 0, 0, 58, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 10, 114, 0, 16, 0, 7, 0, 0, 0, 166, 154, 144, 0, 26, 0, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 30, 0, 0, 8, 114, 0, 16, 0, 10, 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 4, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 55, 0, 0, 10, 114, 0, 16, 0, 10, 0, 0, 0, 166, 154, 144, 0, 26, 0, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 30, 0, 0, 8, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 4, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 55, 0, 0, 10, 114, 0, 16, 0, 11, 0, 0, 0, 166, 154, 144, 0, 26, 0, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 31, 0, 4, 4, 42, 144, 144, 0, 26, 0, 16, 0, 1, 0, 0, 0, 33, 0, 0, 10, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 12, 114, 0, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 150, 151, 208, 0, 32, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 14, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 10, 0, 16, 0, 13, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 14, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 26, 0, 16, 0, 13, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 14, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 16, 0, 13, 0, 0, 0, 33, 0, 0, 7, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 40, 0, 0, 5, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 34, 0, 0, 7, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 60, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 16, 0, 0, 0, 10, 0, 16, 0, 16, 0, 0, 0, 60, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 16, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 9, 18, 0, 16, 0, 16, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 10, 144, 208, 0, 32, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 9, 34, 0, 16, 0, 16, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 26, 144, 208, 0, 32, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 9, 66, 0, 16, 0, 16, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 144, 208, 0, 32, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 9, 130, 0, 16, 0, 16, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 58, 144, 208, 0, 32, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, 16, 0, 0, 0, 70, 14, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 1, 0, 0, 7, 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 6, 0, 16, 0, 16, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 1, 0, 0, 7, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 150, 7, 16, 0, 16, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 33, 0, 0, 10, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 7, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 40, 0, 0, 5, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 34, 0, 0, 7, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 33, 0, 0, 10, 114, 0, 16, 0, 21, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 7, 114, 0, 16, 0, 22, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 40, 0, 0, 5, 114, 0, 16, 0, 23, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 34, 0, 0, 7, 114, 0, 16, 0, 23, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 23, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 24, 0, 0, 0, 70, 2, 16, 0, 21, 0, 0, 0, 70, 2, 16, 0, 22, 0, 0, 0, 70, 2, 16, 0, 23, 0, 0, 0, 60, 0, 0, 7, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 24, 0, 0, 0, 60, 0, 0, 7, 34, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 20, 0, 0, 0, 10, 0, 16, 0, 20, 0, 0, 0, 60, 0, 0, 7, 34, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 20, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 60, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 1, 0, 0, 7, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 150, 7, 16, 0, 16, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 22, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 1, 0, 0, 7, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 150, 7, 16, 0, 16, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 23, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 21, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 18, 0, 0, 1, 41, 0, 0, 9, 34, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 10, 144, 208, 0, 32, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 255, 255, 255, 255, 1, 0, 0, 7, 114, 0, 16, 0, 17, 0, 0, 0, 86, 5, 16, 0, 3, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 1, 0, 0, 7, 114, 0, 16, 0, 12, 0, 0, 0, 86, 5, 16, 0, 3, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 1, 0, 0, 7, 114, 0, 16, 0, 13, 0, 0, 0, 86, 5, 16, 0, 3, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 1, 0, 0, 7, 114, 0, 16, 0, 14, 0, 0, 0, 86, 5, 16, 0, 3, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, 30, 0, 0, 12, 242, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 70, 158, 208, 0, 32, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 1, 0, 0, 7, 226, 0, 16, 0, 4, 0, 0, 0, 6, 0, 16, 0, 7, 0, 0, 0, 6, 9, 16, 0, 17, 0, 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 1, 0, 0, 7, 114, 0, 16, 0, 11, 0, 0, 0, 6, 0, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 30, 0, 0, 8, 114, 0, 16, 0, 11, 0, 0, 0, 6, 0, 16, 128, 65, 0, 0, 0, 7, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 55, 0, 0, 9, 226, 0, 16, 0, 4, 0, 0, 0, 86, 14, 16, 0, 4, 0, 0, 0, 6, 9, 16, 0, 11, 0, 0, 0, 6, 9, 16, 0, 17, 0, 0, 0, 55, 0, 0, 9, 226, 0, 16, 0, 4, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 86, 14, 16, 0, 4, 0, 0, 0, 6, 9, 16, 0, 17, 0, 0, 0, 60, 0, 0, 8, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 144, 144, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 0, 0, 7, 114, 0, 16, 0, 11, 0, 0, 0, 150, 7, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 1, 0, 0, 7, 114, 0, 16, 0, 15, 0, 0, 0, 150, 7, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 30, 0, 0, 8, 114, 0, 16, 0, 15, 0, 0, 0, 150, 7, 16, 128, 65, 0, 0, 0, 7, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 11, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 1, 0, 0, 7, 114, 0, 16, 0, 12, 0, 0, 0, 150, 7, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 1, 0, 0, 7, 114, 0, 16, 0, 15, 0, 0, 0, 150, 7, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 30, 0, 0, 8, 114, 0, 16, 0, 15, 0, 0, 0, 150, 7, 16, 128, 65, 0, 0, 0, 7, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 12, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 1, 0, 0, 7, 114, 0, 16, 0, 13, 0, 0, 0, 150, 7, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 1, 0, 0, 7, 226, 0, 16, 0, 10, 0, 0, 0, 86, 14, 16, 0, 10, 0, 0, 0, 6, 9, 16, 0, 14, 0, 0, 0, 30, 0, 0, 8, 114, 0, 16, 0, 7, 0, 0, 0, 150, 7, 16, 128, 65, 0, 0, 0, 7, 0, 0, 0, 150, 7, 16, 0, 10, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 7, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 30, 0, 0, 7, 226, 0, 16, 0, 10, 0, 0, 0, 86, 14, 16, 0, 4, 0, 0, 0, 6, 9, 16, 0, 11, 0, 0, 0, 55, 0, 0, 10, 226, 0, 16, 0, 10, 0, 0, 0, 166, 154, 144, 0, 26, 0, 16, 0, 1, 0, 0, 0, 86, 14, 16, 0, 10, 0, 0, 0, 6, 9, 16, 0, 11, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 11, 0, 0, 0, 150, 7, 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 55, 0, 0, 10, 114, 0, 16, 0, 11, 0, 0, 0, 166, 154, 144, 0, 26, 0, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 12, 0, 0, 0, 150, 7, 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 55, 0, 0, 10, 114, 0, 16, 0, 7, 0, 0, 0, 166, 154, 144, 0, 26, 0, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 79, 0, 0, 12, 50, 0, 16, 0, 12, 0, 0, 0, 6, 144, 208, 0, 32, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 15, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 9, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 10, 144, 208, 0, 32, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 255, 255, 255, 255, 32, 0, 0, 7, 114, 0, 16, 0, 13, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 150, 7, 16, 0, 4, 0, 0, 0, 32, 0, 0, 7, 114, 0, 16, 0, 14, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 150, 7, 16, 0, 10, 0, 0, 0, 41, 0, 0, 7, 114, 0, 16, 0, 15, 0, 0, 0, 150, 7, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 41, 0, 0, 7, 114, 0, 16, 0, 16, 0, 0, 0, 150, 7, 16, 0, 10, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 128, 0, 0, 0, 128, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 128, 0, 0, 0, 128, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 85, 0, 0, 9, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 10, 144, 208, 0, 32, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 85, 0, 0, 9, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 10, 144, 208, 0, 32, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 13, 0, 0, 0, 150, 7, 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 14, 0, 0, 0, 150, 7, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 13, 0, 0, 0, 6, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 150, 7, 16, 0, 4, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 14, 0, 0, 0, 6, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 150, 7, 16, 0, 10, 0, 0, 0, 33, 0, 0, 10, 114, 0, 16, 0, 15, 0, 0, 0, 150, 7, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 10, 114, 0, 16, 0, 16, 0, 0, 0, 150, 7, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 8, 114, 0, 16, 0, 17, 0, 0, 0, 150, 7, 16, 128, 65, 0, 0, 0, 4, 0, 0, 0, 150, 7, 16, 0, 4, 0, 0, 0, 36, 0, 0, 8, 114, 0, 16, 0, 18, 0, 0, 0, 150, 7, 16, 128, 65, 0, 0, 0, 10, 0, 0, 0, 150, 7, 16, 0, 10, 0, 0, 0, 33, 0, 0, 7, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 6, 0, 16, 0, 10, 0, 0, 0, 33, 0, 0, 7, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 6, 0, 16, 0, 10, 0, 0, 0, 41, 0, 0, 7, 114, 0, 16, 0, 21, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 41, 0, 0, 7, 114, 0, 16, 0, 22, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 21, 0, 0, 0, 70, 2, 16, 0, 21, 0, 0, 0, 2, 64, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 22, 0, 0, 0, 70, 2, 16, 0, 22, 0, 0, 0, 2, 64, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 114, 0, 16, 0, 21, 0, 0, 0, 70, 2, 16, 0, 21, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 85, 0, 0, 7, 114, 0, 16, 0, 22, 0, 0, 0, 70, 2, 16, 0, 22, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 255, 127, 0, 0, 255, 127, 0, 0, 255, 127, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 21, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 2, 64, 0, 0, 255, 127, 0, 0, 255, 127, 0, 0, 255, 127, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 22, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 5, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 40, 0, 0, 5, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 55, 0, 0, 9, 226, 0, 16, 0, 4, 0, 0, 0, 86, 5, 16, 0, 12, 0, 0, 0, 6, 9, 16, 0, 15, 0, 0, 0, 86, 14, 16, 0, 4, 0, 0, 0, 55, 0, 0, 9, 226, 0, 16, 0, 10, 0, 0, 0, 86, 5, 16, 0, 12, 0, 0, 0, 6, 9, 16, 0, 16, 0, 0, 0, 86, 14, 16, 0, 10, 0, 0, 0, 55, 0, 0, 9, 226, 0, 16, 0, 4, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 6, 9, 16, 0, 13, 0, 0, 0, 86, 14, 16, 0, 4, 0, 0, 0, 55, 0, 0, 9, 226, 0, 16, 0, 10, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 6, 9, 16, 0, 14, 0, 0, 0, 86, 14, 16, 0, 10, 0, 0, 0, 32, 0, 0, 7, 114, 0, 16, 0, 13, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 32, 0, 0, 7, 114, 0, 16, 0, 14, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 41, 0, 0, 7, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 41, 0, 0, 7, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 128, 0, 0, 0, 128, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 128, 0, 0, 0, 128, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 85, 0, 0, 9, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 10, 144, 208, 0, 32, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 85, 0, 0, 9, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 10, 144, 208, 0, 32, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 13, 0, 0, 0, 6, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 55, 0, 0, 9, 210, 0, 16, 0, 12, 0, 0, 0, 6, 0, 16, 0, 12, 0, 0, 0, 6, 9, 16, 0, 14, 0, 0, 0, 6, 9, 16, 0, 7, 0, 0, 0, 33, 0, 0, 10, 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 10, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 8, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 11, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 36, 0, 0, 8, 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 7, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 33, 0, 0, 7, 114, 0, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 6, 0, 16, 0, 10, 0, 0, 0, 33, 0, 0, 7, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 6, 0, 16, 0, 10, 0, 0, 0, 41, 0, 0, 7, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 41, 0, 0, 7, 114, 0, 16, 0, 21, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 2, 64, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 21, 0, 0, 0, 70, 2, 16, 0, 21, 0, 0, 0, 2, 64, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 85, 0, 0, 7, 114, 0, 16, 0, 21, 0, 0, 0, 70, 2, 16, 0, 21, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 255, 127, 0, 0, 255, 127, 0, 0, 255, 127, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 255, 127, 0, 0, 255, 127, 0, 0, 255, 127, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 21, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 5, 114, 0, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 40, 0, 0, 5, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 11, 0, 0, 0, 86, 5, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 7, 0, 0, 0, 86, 5, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 11, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 7, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 134, 3, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 29, 0, 0, 10, 194, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 246, 11, 16, 0, 1, 0, 0, 0, 54, 0, 0, 6, 34, 0, 16, 0, 1, 0, 0, 0, 42, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 34, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 48, 0, 0, 1, 80, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 3, 0, 4, 3, 58, 0, 16, 0, 5, 0, 0, 0, 85, 0, 0, 8, 130, 0, 16, 0, 5, 0, 0, 0, 10, 144, 144, 0, 42, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 5, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 167, 0, 0, 9, 114, 0, 16, 0, 12, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 70, 242, 17, 0, 0, 0, 0, 0, 30, 0, 0, 8, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 9, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 43, 0, 0, 5, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 16, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 29, 0, 0, 7, 130, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 60, 0, 0, 7, 130, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 49, 0, 0, 7, 130, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 56, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 253, 255, 125, 66, 14, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 28, 0, 0, 5, 130, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 55, 0, 0, 11, 130, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 10, 144, 208, 0, 46, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 55, 0, 0, 9, 130, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 30, 0, 0, 9, 130, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 64, 0, 0, 0, 58, 144, 144, 128, 65, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 38, 0, 0, 9, 0, 208, 0, 0, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 246, 159, 144, 0, 58, 0, 16, 0, 5, 0, 0, 0, 35, 0, 0, 9, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 246, 15, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 32, 0, 0, 0, 32, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 7, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 32, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 95, 0, 0, 0, 38, 0, 0, 11, 0, 208, 0, 0, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 31, 0, 0, 0, 31, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 7, 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 34, 0, 0, 10, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 11, 0, 208, 0, 0, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 225, 255, 255, 255, 225, 255, 255, 255, 225, 255, 255, 255, 0, 0, 0, 0, 42, 0, 0, 7, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 40, 0, 0, 5, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 42, 0, 0, 7, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 34, 0, 0, 10, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 5, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 60, 0, 0, 10, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 128, 0, 0, 0, 128, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 12, 0, 0, 0, 246, 15, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 18, 0, 0, 1, 30, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 167, 0, 0, 9, 114, 0, 16, 0, 13, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 70, 242, 17, 0, 0, 0, 0, 0, 30, 0, 0, 8, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 6, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 43, 0, 0, 5, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 16, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 29, 0, 0, 7, 130, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 60, 0, 0, 7, 130, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 49, 0, 0, 7, 130, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 56, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 253, 255, 125, 66, 14, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 28, 0, 0, 5, 130, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 55, 0, 0, 11, 130, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 10, 144, 208, 0, 46, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 55, 0, 0, 9, 130, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 30, 0, 0, 9, 130, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 64, 0, 0, 0, 58, 144, 144, 128, 65, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 38, 0, 0, 9, 0, 208, 0, 0, 114, 0, 16, 0, 13, 0, 0, 0, 150, 7, 16, 0, 10, 0, 0, 0, 246, 159, 144, 0, 58, 0, 16, 0, 5, 0, 0, 0, 35, 0, 0, 9, 114, 0, 16, 0, 13, 0, 0, 0, 150, 7, 16, 0, 4, 0, 0, 0, 246, 15, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 32, 0, 0, 0, 32, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 7, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 32, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 95, 0, 0, 0, 38, 0, 0, 11, 0, 208, 0, 0, 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 31, 0, 0, 0, 31, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 7, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 34, 0, 0, 10, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 11, 0, 208, 0, 0, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 225, 255, 255, 255, 225, 255, 255, 255, 225, 255, 255, 255, 0, 0, 0, 0, 42, 0, 0, 7, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 40, 0, 0, 5, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 42, 0, 0, 7, 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 34, 0, 0, 10, 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 5, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 60, 0, 0, 10, 114, 0, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 128, 0, 0, 0, 128, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 12, 0, 0, 0, 246, 15, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 21, 0, 0, 1, 1, 0, 0, 10, 50, 0, 16, 0, 13, 0, 0, 0, 6, 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 0, 124, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 13, 0, 0, 0, 85, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 10, 0, 16, 0, 12, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 31, 0, 0, 0, 18, 0, 0, 1, 31, 0, 4, 3, 10, 0, 16, 0, 13, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 6, 0, 0, 0, 10, 0, 16, 0, 13, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 48, 0, 0, 1, 1, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 0, 4, 0, 0, 3, 0, 4, 3, 58, 0, 16, 0, 8, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 255, 255, 255, 255, 41, 0, 0, 7, 130, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 22, 0, 0, 1, 1, 0, 0, 7, 18, 0, 16, 0, 13, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 254, 3, 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 18, 0, 16, 0, 13, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 144, 255, 255, 255, 21, 0, 0, 1, 21, 0, 0, 1, 41, 0, 0, 7, 130, 0, 16, 0, 6, 0, 0, 0, 10, 0, 16, 0, 12, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 128, 41, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 56, 60, 0, 0, 7, 130, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 10, 0, 16, 0, 13, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 13, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 1, 0, 0, 10, 146, 0, 16, 0, 12, 0, 0, 0, 86, 5, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 124, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 12, 0, 0, 0, 85, 0, 0, 7, 130, 0, 16, 0, 6, 0, 0, 0, 26, 0, 16, 0, 12, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 31, 0, 0, 0, 18, 0, 0, 1, 31, 0, 4, 3, 10, 0, 16, 0, 12, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 10, 0, 16, 0, 12, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 48, 0, 0, 1, 1, 0, 0, 7, 18, 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 1, 64, 0, 0, 0, 4, 0, 0, 3, 0, 4, 3, 10, 0, 16, 0, 10, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 255, 255, 255, 255, 41, 0, 0, 7, 130, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 22, 0, 0, 1, 1, 0, 0, 7, 18, 0, 16, 0, 12, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 1, 64, 0, 0, 254, 3, 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 18, 0, 16, 0, 12, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 144, 255, 255, 255, 21, 0, 0, 1, 21, 0, 0, 1, 41, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 12, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 128, 41, 0, 0, 7, 18, 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 10, 0, 0, 0, 10, 0, 16, 0, 10, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 56, 60, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 10, 0, 16, 0, 10, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 10, 0, 0, 0, 10, 0, 16, 0, 12, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 13, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 10, 0, 16, 0, 10, 0, 0, 0, 1, 0, 0, 10, 50, 0, 16, 0, 12, 0, 0, 0, 166, 10, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 255, 3, 0, 0, 0, 124, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 12, 0, 0, 0, 85, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 12, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 1, 64, 0, 0, 31, 0, 0, 0, 18, 0, 0, 1, 31, 0, 4, 3, 10, 0, 16, 0, 12, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 10, 0, 0, 0, 10, 0, 16, 0, 12, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 11, 0, 0, 0, 10, 0, 16, 0, 10, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 8, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 48, 0, 0, 1, 1, 0, 0, 7, 34, 0, 16, 0, 12, 0, 0, 0, 58, 0, 16, 0, 11, 0, 0, 0, 1, 64, 0, 0, 0, 4, 0, 0, 3, 0, 4, 3, 26, 0, 16, 0, 12, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 1, 64, 0, 0, 255, 255, 255, 255, 41, 0, 0, 7, 130, 0, 16, 0, 11, 0, 0, 0, 58, 0, 16, 0, 11, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 22, 0, 0, 1, 1, 0, 0, 7, 18, 0, 16, 0, 12, 0, 0, 0, 58, 0, 16, 0, 11, 0, 0, 0, 1, 64, 0, 0, 254, 3, 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 18, 0, 16, 0, 12, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 8, 0, 0, 0, 1, 64, 0, 0, 144, 255, 255, 255, 21, 0, 0, 1, 21, 0, 0, 1, 41, 0, 0, 7, 18, 0, 16, 0, 10, 0, 0, 0, 42, 0, 16, 0, 12, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 10, 0, 0, 0, 10, 0, 16, 0, 10, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 128, 41, 0, 0, 7, 34, 0, 16, 0, 12, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 12, 0, 0, 0, 26, 0, 16, 0, 12, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 56, 60, 0, 0, 7, 18, 0, 16, 0, 10, 0, 0, 0, 10, 0, 16, 0, 10, 0, 0, 0, 26, 0, 16, 0, 12, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 12, 0, 0, 0, 10, 0, 16, 0, 12, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 13, 0, 0, 0, 10, 0, 16, 0, 10, 0, 0, 0, 10, 0, 16, 0, 12, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 10, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 167, 0, 0, 9, 114, 0, 16, 0, 12, 0, 0, 0, 10, 0, 16, 0, 10, 0, 0, 0, 1, 64, 0, 0, 24, 0, 0, 0, 70, 242, 17, 0, 0, 0, 0, 0, 0, 0, 0, 8, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 12, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 16, 0, 0, 7, 18, 0, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 0, 0, 0, 7, 34, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 10, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 22, 0, 0, 1, 55, 0, 0, 9, 18, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 236, 120, 173, 96, 26, 0, 16, 0, 3, 0, 0, 0, 30, 0, 0, 8, 34, 0, 16, 0, 2, 0, 0, 0, 58, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 168, 0, 0, 8, 114, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 40, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 10, 0, 16, 0, 3, 0, 0, 0, 167, 0, 0, 8, 18, 0, 16, 0, 4, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 40, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 30, 0, 0, 6, 34, 0, 16, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 16, 0, 0, 0, 167, 0, 0, 9, 226, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 40, 0, 0, 0, 6, 249, 17, 0, 0, 0, 0, 0, 49, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 40, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 168, 0, 0, 8, 114, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 40, 0, 0, 0, 134, 3, 16, 0, 5, 0, 0, 0, 21, 0, 0, 1, 21, 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 3, 0, 0, 0, 167, 0, 0, 8, 18, 0, 16, 0, 4, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 40, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 30, 0, 0, 6, 34, 0, 16, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 8, 0, 0, 0, 167, 0, 0, 9, 226, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 40, 0, 0, 0, 6, 249, 17, 0, 0, 0, 0, 0, 49, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 40, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 168, 0, 0, 8, 114, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 40, 0, 0, 0, 134, 3, 16, 0, 5, 0, 0, 0, 21, 0, 0, 1, 21, 0, 0, 1, 31, 0, 4, 3, 58, 0, 16, 0, 3, 0, 0, 0, 167, 0, 0, 8, 18, 0, 16, 0, 3, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 40, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 30, 0, 0, 6, 34, 0, 16, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 4, 0, 0, 0, 167, 0, 0, 9, 226, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 40, 0, 0, 0, 6, 249, 17, 0, 0, 0, 0, 0, 49, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 40, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 168, 0, 0, 8, 114, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 40, 0, 0, 0, 134, 3, 16, 0, 4, 0, 0, 0, 21, 0, 0, 1, 21, 0, 0, 1, 79, 0, 0, 10, 98, 0, 16, 0, 0, 0, 0, 0, 166, 10, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 167, 0, 0, 8, 18, 0, 16, 0, 2, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 40, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 30, 0, 0, 6, 34, 0, 16, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 2, 0, 0, 0, 167, 0, 0, 9, 226, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 40, 0, 0, 0, 6, 249, 17, 0, 0, 0, 0, 0, 49, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 0, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 40, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 168, 0, 0, 8, 114, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 40, 0, 0, 0, 134, 3, 16, 0, 3, 0, 0, 0, 21, 0, 0, 1, 21, 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 167, 0, 0, 8, 18, 0, 16, 0, 2, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 40, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 30, 0, 0, 6, 34, 0, 16, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 1, 0, 0, 0, 167, 0, 0, 9, 226, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 40, 0, 0, 0, 6, 249, 17, 0, 0, 0, 0, 0, 49, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 40, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 168, 0, 0, 8, 114, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 40, 0, 0, 0, 134, 3, 16, 0, 3, 0, 0, 0, 21, 0, 0, 1, 167, 0, 0, 8, 18, 0, 16, 0, 2, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 40, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 49, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 167, 0, 0, 8, 114, 0, 16, 0, 1, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 40, 0, 0, 0, 70, 242, 17, 0, 0, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 18, 0, 0, 1, 167, 0, 0, 9, 242, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 70, 126, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 168, 0, 0, 9, 242, 224, 17, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 62, 0, 0, 1 }; ================================================ FILE: 3rdParty/DirectXTex/DirectXTex/Shaders/Compiled/BC7Encode_EncodeBlockCS.inc ================================================ #if 0 // // Generated by Microsoft (R) D3D Shader Disassembler // // /// // Input signature: // // Name Index Mask Register SysValue Format Used // -------------------- ----- ------ -------- -------- ------- ------ // no Input // // Output signature: // // Name Index Mask Register SysValue Format Used // -------------------- ----- ------ -------- -------- ------- ------ // no Output cs_4_0 dcl_globalFlags refactoringAllowed dcl_immediateConstantBuffer { { 0x0000cccc, -0.000000, 15, 0}, { 0x00008888, 65981199646559862000000000.000000, 15, 0}, { 0x0000eeee, 15358528172589056.000000, 15, 0}, { 0x0000ecc8, 3584194248704.000000, 15, 0}, { 0x0000c880, -0.000000, 15, 0}, { 0x0000feec, -0.000000, 15, 0}, { 0x0000fec8, 14680365989888.000000, 15, 0}, { 0x0000ec80, 15362462362632192.000000, 15, 0}, { 0x0000c800, -0.000000, 15, 0}, { 0x0000ffec, -0.000000, 15, 0}, { 0x0000fe80, -0.000000, 15, 0}, { 0x0000e800, -0.000000, 15, 0}, { 0x0000ffe8, -0.000000, 15, 0}, { 0x0000ff00, -0.000000, 15, 0}, { 0x0000fff0, -0.000000, 15, 0}, { 0x0000f000, 0.000000, 15, 0}, { 0x0000f710, -0.000000, 15, 0}, { 142, 0.000000, 2, 0}, { 0x00007100, -0.000000, 8, 0}, { 2254, 22076467445760.000000, 2, 0}, { 140, -0.000000, 2, 0}, { 0x00007310, 70798013459086900000000000.000000, 8, 0}, { 0x00003100, -0.000000, 8, 0}, { 0x00008cce, 0.000000, 15, 0}, { 2188, 0x0050a4a4, 2, 0}, { 0x00003110, -0.000000, 8, 0}, { 0x00006666, 0.000000, 2, 0}, { 0x0000366c, 17610885206241624000000000.000000, 2, 0}, { 6120, -0.000000, 8, 0}, { 4080, -0.000000, 8, 0}, { 0x0000718e, 22097854464.000000, 2, 0}, { 0x0000399c, 65888818352238725000000000.000000, 2, 0}, { 0x0000aaaa, -0.000000, 15, 0}, { 0x0000f0f0, 19411582976.000000, 15, 0}, { 0x00005a5a, -0.000000, 6, 0}, { 0x000033cc, 0.000000, 8, 0}, { 0x00003c3c, 0.000000, 2, 0}, { 0x000055aa, 0.000000, 8, 0}, { 0x00009696, 0.000000, 15, 0}, { 0x0000a55a, 22151331840.000000, 15, 0}, { 0x000073ce, 9304358912.000000, 2, 0}, { 5064, -0.000000, 8, 0}, { 0x0000324c, 271536072765004600000000.000000, 2, 0}, { 0x00003bdc, -0.000000, 2, 0}, { 0x00006996, 21517107200.000000, 2, 0}, { 0x0000c33c, 12724757752857623000000000.000000, 15, 0}, { 0x00009966, 1365.320801, 15, 0}, { 1632, 272006464738884190000000.000000, 6, 0}, { 626, -0.000000, 6, 0}, { 1252, 5783798415360.000000, 2, 0}, { 0x00004e40, -0.000000, 6, 0}, { 0x00002720, -0.000000, 8, 0}, { 0x0000c936, -0.000000, 15, 0}, { 0x0000936c, -0.000000, 15, 0}, { 0x000039c6, -0.000000, 2, 0}, { 0x0000639c, -0.000000, 2, 0}, { 0x00009336, -0.000000, 15, 0}, { 0x00009cc6, -0.000000, 15, 0}, { 0x0000817e, -0.000000, 15, 0}, { 0x0000e718, -0.000000, 15, 0}, { 0x0000ccf0, 4.007874, 15, 0}, { 4044, -0.000000, 2, 0}, { 0x00007744, -0.000000, 2, 0}, { 0x0000ee22, 0.000000, 15, 0}, { 0, 0, 3, 15}, { 0, 0, 3, 8}, { 0, 0, 15, 8}, { 1, 0, 15, 3}, { 1, 0, 8, 15}, { 1, 0, 3, 15}, { 1, 0, 15, 3}, { 2, 0, 15, 8}, { 2, 0, 8, 15}, { 2, 0, 8, 15}, { 2, 0, 6, 15}, { 2, 0, 6, 15}, { 3, 0, 6, 15}, { 3, 0, 5, 15}, { 3, 0, 3, 15}, { 3, 0, 3, 8}, { 4, 0, 3, 15}, { 4, 0, 3, 8}, { 4, 0, 8, 15}, { 4, 0, 15, 3}, { 5, 0, 3, 15}, { 5, 0, 3, 8}, { 5, 0, 6, 15}, { 5, 0, 10, 8}, { 6, 0, 5, 3}, { 6, 0, 8, 15}, { 6, 0, 8, 6}, { 6, 0, 6, 10}, { 6, 0, 8, 15}, { 7, 0, 5, 15}, { 7, 0, 15, 10}, { 7, 0, 15, 8}, { 7, 0, 8, 15}, { 8, 0, 15, 3}, { 8, 0, 3, 15}, { 8, 0, 5, 10}, { 8, 0, 6, 10}, { 9, 0, 10, 8}, { 9, 0, 8, 9}, { 9, 0, 15, 10}, { 9, 0, 15, 6}, { 10, 0, 3, 15}, { 10, 0, 15, 8}, { 10, 0, 5, 15}, { 10, 0, 15, 3}, { 10, 0, 15, 6}, { 11, 0, 15, 6}, { 11, 0, 15, 8}, { 11, 0, 3, 15}, { 11, 0, 15, 3}, { 12, 0, 5, 15}, { 12, 0, 5, 15}, { 12, 0, 5, 15}, { 12, 0, 8, 15}, { 13, 0, 5, 15}, { 13, 0, 10, 15}, { 13, 0, 5, 15}, { 13, 0, 10, 15}, { 14, 0, 8, 15}, { 14, 0, 13, 15}, { 14, 0, 15, 3}, { 14, 0, 12, 15}, { 15, 0, 3, 15}, { 15, 0, 3, 8}, { 0, 15, 0, 0}, { 0, 15, 0, 0}, { 0, 15, 0, 0}, { 0, 15, 0, 0}, { 0, 15, 0, 0}, { 1, 15, 0, 0}, { 1, 15, 0, 0}, { 1, 15, 0, 0}, { 1, 15, 0, 0}, { 1, 15, 0, 0}, { 1, 15, 0, 0}, { 1, 15, 0, 0}, { 1, 15, 0, 0}, { 1, 15, 0, 0}, { 2, 15, 0, 0}, { 2, 15, 0, 0}, { 2, 15, 0, 0}, { 2, 2, 0, 0}, { 2, 8, 0, 0}, { 2, 2, 0, 0}, { 2, 2, 0, 0}, { 2, 8, 0, 0}, { 2, 8, 0, 0}, { 3, 15, 0, 0}, { 3, 2, 0, 0}, { 3, 8, 0, 0}, { 3, 2, 0, 0}, { 3, 2, 0, 0}, { 3, 8, 0, 0}, { 3, 8, 0, 0}, { 3, 2, 0, 0}, { 3, 2, 0, 0}, { 3, 15, 0, 0}, { 4, 15, 0, 0}, { 4, 6, 0, 0}, { 4, 8, 0, 0}, { 4, 2, 0, 0}, { 4, 8, 0, 0}, { 4, 15, 0, 0}, { 4, 15, 0, 0}, { 4, 2, 0, 0}, { 4, 8, 0, 0}, { 5, 2, 0, 0}, { 5, 2, 0, 0}, { 5, 2, 0, 0}, { 5, 15, 0, 0}, { 5, 15, 0, 0}, { 5, 6, 0, 0}, { 5, 6, 0, 0}, { 5, 2, 0, 0}, { 5, 6, 0, 0}, { 6, 8, 0, 0}, { 6, 15, 0, 0}, { 6, 15, 0, 0}, { 6, 2, 0, 0}, { 6, 2, 0, 0}, { 6, 15, 0, 0}, { 6, 15, 0, 0}, { 6, 15, 0, 0}, { 6, 15, 0, 0}, { 7, 15, 0, 0}, { 7, 2, 0, 0}, { 7, 2, 0, 0}, { 7, 15, 0, 0}, { 0, 3, 15, 0}, { 0, 3, 8, 0}, { 0, 8, 15, 0}, { 0, 3, 15, 0}, { 0, 8, 15, 0}, { 0, 3, 15, 0}, { 0, 3, 15, 0}, { 0, 8, 15, 0}, { 0, 8, 15, 0}, { 0, 8, 15, 0}, { 0, 6, 15, 0}, { 1, 6, 15, 0}, { 1, 6, 15, 0}, { 1, 5, 15, 0}, { 1, 3, 15, 0}, { 1, 3, 8, 0}, { 1, 3, 15, 0}, { 1, 3, 8, 0}, { 1, 8, 15, 0}, { 1, 3, 15, 0}, { 1, 3, 15, 0}, { 1, 3, 8, 0}, { 1, 6, 15, 0}, { 1, 8, 10, 0}, { 1, 3, 5, 0}, { 1, 8, 15, 0}, { 1, 6, 8, 0}, { 1, 6, 10, 0}, { 1, 8, 15, 0}, { 1, 5, 15, 0}, { 1, 10, 15, 0}, { 1, 8, 15, 0}, { 1, 8, 15, 0}, { 2, 3, 15, 0}, { 2, 3, 15, 0}, { 2, 5, 10, 0}, { 2, 6, 10, 0}, { 2, 8, 10, 0}, { 2, 8, 9, 0}, { 2, 10, 15, 0}, { 2, 6, 15, 0}, { 2, 3, 15, 0}, { 2, 8, 15, 0}, { 2, 5, 15, 0}, { 2, 3, 15, 0}, { 2, 6, 15, 0}, { 2, 6, 15, 0}, { 2, 8, 15, 0}, { 2, 3, 15, 0}, { 2, 3, 15, 0}, { 2, 5, 15, 0}, { 2, 5, 15, 0}, { 2, 5, 15, 0}, { 2, 8, 15, 0}, { 3, 5, 15, 0}, { 3, 10, 15, 0}, { 3, 5, 15, 0}, { 3, 10, 15, 0}, { 3, 8, 15, 0}, { 3, 13, 15, 0}, { 3, 3, 15, 0}, { 3, 12, 15, 0}, { 3, 3, 15, 0}, { 3, 3, 8, 0} } dcl_constantbuffer cb0[2], immediateIndexed dcl_resource_texture2d (float,float,float,float) t0 dcl_resource_structured t1, 16 dcl_uav_structured u0, 16 dcl_input vThreadIDInGroupFlattened dcl_input vThreadGroupID.x dcl_temps 15 dcl_tgsm_structured g0, 100, 64 dcl_thread_group 64, 1, 1 ushr r0.x, vThreadIDInGroupFlattened.x, l(4) ishl r0.y, vThreadGroupID.x, l(2) iadd r0.y, r0.y, cb0[1].x iadd r0.x, r0.x, r0.y uge r0.y, r0.x, cb0[1].y if_nz r0.y ret endif and r0.y, vThreadIDInGroupFlattened.x, l(48) iadd r0.z, -r0.y, vThreadIDInGroupFlattened.x ld_structured r1.xyz, r0.x, l(4), t1.xyzx and r0.w, r1.x, l(0x7fffffff) ld_structured r2.x, r0.x, l(4), t1.xxxx ushr r1.x, r2.x, l(31) ult r2.xyzw, r0.zzzz, l(16, 8, 4, 2) if_nz r2.x udiv r1.w, null, r0.x, cb0[0].y imad r3.x, -r1.w, cb0[0].y, r0.x ishl r3.x, r3.x, l(2) ishl r1.w, r1.w, l(2) and r3.y, r0.z, l(3) iadd r3.x, r3.y, r3.x ushr r4.x, r0.z, l(2) iadd r3.y, r1.w, r4.x mov r3.zw, l(0,0,0,0) ld r3.xyzw, r3.xyzw, t0.xyzw mul r3.xyzw, r3.xyzw, l(255.000000, 255.000000, 255.000000, 255.000000) ftou r3.xyzw, r3.xyzw umin r3.xyzw, r3.xyzw, l(255, 255, 255, 255) ieq r4.xy, r0.wwww, l(4, 5, 0, 0) or r1.w, r4.y, r4.x ieq r4.xyz, r1.zzzz, l(1, 2, 3, 0) movc r5.zw, r4.zzzz, r3.wwwz, r3.zzzw mov r5.xy, r3.xyxx movc r5.yzw, r4.yyyy, r3.wwzy, r5.yyzw movc r4.xyzw, r4.xxxx, r3.wyzx, r5.xyzw movc r3.xyzw, r1.wwww, r4.xyzw, r3.xyzw store_structured g0.xyzw, vThreadIDInGroupFlattened.x, l(0), r3.xyzw endif iadd r1.w, r1.y, l(-64) if_nz r2.x ld_structured r3.xyzw, vThreadIDInGroupFlattened.x, l(0), g0.xyzw ishl r4.x, r0.z, l(1) ushr r4.x, icb[r1.w + 0].y, r4.x and r4.x, r4.x, l(3) ieq r4.yz, r0.wwww, l(0, 0, 2, 0) or r4.y, r4.z, r4.y ieq r4.x, r4.x, l(2) movc r5.xyzw, r4.xxxx, r3.xyzw, l(-1,-1,-1,-1) and r3.xyzw, r3.xyzw, r4.xxxx movc r5.xyzw, r4.yyyy, r5.xyzw, l(-1,-1,-1,-1) and r3.xyzw, r3.xyzw, r4.yyyy store_structured g0.xyzw, vThreadIDInGroupFlattened.x, l(36), r5.xyzw store_structured g0.xyzw, vThreadIDInGroupFlattened.x, l(52), r3.xyzw endif if_nz r2.y ld_structured r3.xyzw, vThreadIDInGroupFlattened.x, l(36), g0.xyzw ld_structured r4.xyzw, vThreadIDInGroupFlattened.x, l(52), g0.xyzw iadd r5.x, vThreadIDInGroupFlattened.x, l(8) ld_structured r6.xyzw, r5.x, l(36), g0.xyzw ld_structured r5.xyzw, r5.x, l(52), g0.xyzw umin r3.xyzw, r3.xyzw, r6.xyzw store_structured g0.xyzw, vThreadIDInGroupFlattened.x, l(36), r3.xyzw umax r3.xyzw, r4.xyzw, r5.xyzw store_structured g0.xyzw, vThreadIDInGroupFlattened.x, l(52), r3.xyzw endif if_nz r2.z ld_structured r3.xyzw, vThreadIDInGroupFlattened.x, l(36), g0.xyzw ld_structured r4.xyzw, vThreadIDInGroupFlattened.x, l(52), g0.xyzw iadd r5.x, vThreadIDInGroupFlattened.x, l(4) ld_structured r6.xyzw, r5.x, l(36), g0.xyzw ld_structured r5.xyzw, r5.x, l(52), g0.xyzw umin r3.xyzw, r3.xyzw, r6.xyzw store_structured g0.xyzw, vThreadIDInGroupFlattened.x, l(36), r3.xyzw umax r3.xyzw, r4.xyzw, r5.xyzw store_structured g0.xyzw, vThreadIDInGroupFlattened.x, l(52), r3.xyzw endif if_nz r2.w ld_structured r3.xyzw, vThreadIDInGroupFlattened.x, l(36), g0.xyzw ld_structured r4.xyzw, vThreadIDInGroupFlattened.x, l(52), g0.xyzw iadd r5.x, vThreadIDInGroupFlattened.x, l(2) ld_structured r6.xyzw, r5.x, l(36), g0.xyzw ld_structured r5.xyzw, r5.x, l(52), g0.xyzw umin r3.xyzw, r3.xyzw, r6.xyzw store_structured g0.xyzw, vThreadIDInGroupFlattened.x, l(36), r3.xyzw umax r3.xyzw, r4.xyzw, r5.xyzw store_structured g0.xyzw, vThreadIDInGroupFlattened.x, l(52), r3.xyzw endif ult r3.xy, r0.zzzz, l(1, 3, 0, 0) if_nz r3.x ld_structured r4.xyzw, vThreadIDInGroupFlattened.x, l(36), g0.xyzw ld_structured r5.xyzw, vThreadIDInGroupFlattened.x, l(52), g0.xyzw iadd r3.z, vThreadIDInGroupFlattened.x, l(1) ld_structured r6.xyzw, r3.z, l(36), g0.xyzw ld_structured r7.xyzw, r3.z, l(52), g0.xyzw umin r4.xyzw, r4.xyzw, r6.xyzw store_structured g0.xyzw, vThreadIDInGroupFlattened.x, l(36), r4.xyzw umax r4.xyzw, r5.xyzw, r7.xyzw store_structured g0.xyzw, vThreadIDInGroupFlattened.x, l(52), r4.xyzw endif ieq r3.zw, r0.zzzz, l(0, 0, 2, 1) if_nz r3.z ld_structured r4.xyzw, r0.y, l(36), g0.xyzw ld_structured r5.xyzw, r0.y, l(52), g0.xyzw endif if_nz r2.x ld_structured r6.xyzw, vThreadIDInGroupFlattened.x, l(0), g0.xyzw ushr r3.z, icb[r1.y + 0].x, r0.z and r3.z, r3.z, l(1) ishl r7.x, r0.z, l(1) ushr r7.x, icb[r1.w + 0].y, r7.x and r7.x, r7.x, l(3) ieq r8.xyzw, r0.wwww, l(0, 2, 1, 3) ieq r7.x, r7.x, l(1) movc r9.xyzw, r7.xxxx, r6.xyzw, l(-1,-1,-1,-1) and r7.xyzw, r6.xyzw, r7.xxxx or r8.xy, r8.ywyy, r8.xzxx ieq r8.z, r0.w, l(7) or r8.y, r8.z, r8.y ieq r3.z, r3.z, l(1) movc r10.xyzw, r3.zzzz, r6.xyzw, l(-1,-1,-1,-1) and r6.xyzw, r6.xyzw, r3.zzzz movc r10.xyzw, r8.yyyy, r10.xyzw, l(-1,-1,-1,-1) and r6.xyzw, r6.xyzw, r8.yyyy movc r9.xyzw, r8.xxxx, r9.xyzw, r10.xyzw movc r6.xyzw, r8.xxxx, r7.xyzw, r6.xyzw store_structured g0.xyzw, vThreadIDInGroupFlattened.x, l(36), r9.xyzw store_structured g0.xyzw, vThreadIDInGroupFlattened.x, l(52), r6.xyzw endif if_nz r2.y ld_structured r6.xyzw, vThreadIDInGroupFlattened.x, l(36), g0.xyzw ld_structured r7.xyzw, vThreadIDInGroupFlattened.x, l(52), g0.xyzw iadd r3.z, vThreadIDInGroupFlattened.x, l(8) ld_structured r8.xyzw, r3.z, l(36), g0.xyzw ld_structured r9.xyzw, r3.z, l(52), g0.xyzw umin r6.xyzw, r6.xyzw, r8.xyzw store_structured g0.xyzw, vThreadIDInGroupFlattened.x, l(36), r6.xyzw umax r6.xyzw, r7.xyzw, r9.xyzw store_structured g0.xyzw, vThreadIDInGroupFlattened.x, l(52), r6.xyzw endif if_nz r2.z ld_structured r6.xyzw, vThreadIDInGroupFlattened.x, l(36), g0.xyzw ld_structured r7.xyzw, vThreadIDInGroupFlattened.x, l(52), g0.xyzw iadd r3.z, vThreadIDInGroupFlattened.x, l(4) ld_structured r8.xyzw, r3.z, l(36), g0.xyzw ld_structured r9.xyzw, r3.z, l(52), g0.xyzw umin r6.xyzw, r6.xyzw, r8.xyzw store_structured g0.xyzw, vThreadIDInGroupFlattened.x, l(36), r6.xyzw umax r6.xyzw, r7.xyzw, r9.xyzw store_structured g0.xyzw, vThreadIDInGroupFlattened.x, l(52), r6.xyzw endif if_nz r2.w ld_structured r6.xyzw, vThreadIDInGroupFlattened.x, l(36), g0.xyzw ld_structured r7.xyzw, vThreadIDInGroupFlattened.x, l(52), g0.xyzw iadd r3.z, vThreadIDInGroupFlattened.x, l(2) ld_structured r8.xyzw, r3.z, l(36), g0.xyzw ld_structured r9.xyzw, r3.z, l(52), g0.xyzw umin r6.xyzw, r6.xyzw, r8.xyzw store_structured g0.xyzw, vThreadIDInGroupFlattened.x, l(36), r6.xyzw umax r6.xyzw, r7.xyzw, r9.xyzw store_structured g0.xyzw, vThreadIDInGroupFlattened.x, l(52), r6.xyzw endif if_nz r3.x ld_structured r6.xyzw, vThreadIDInGroupFlattened.x, l(36), g0.xyzw ld_structured r7.xyzw, vThreadIDInGroupFlattened.x, l(52), g0.xyzw iadd r3.z, vThreadIDInGroupFlattened.x, l(1) ld_structured r8.xyzw, r3.z, l(36), g0.xyzw ld_structured r9.xyzw, r3.z, l(52), g0.xyzw umin r6.xyzw, r6.xyzw, r8.xyzw store_structured g0.xyzw, vThreadIDInGroupFlattened.x, l(36), r6.xyzw umax r6.xyzw, r7.xyzw, r9.xyzw store_structured g0.xyzw, vThreadIDInGroupFlattened.x, l(52), r6.xyzw endif if_nz r3.w ld_structured r4.xyzw, r0.y, l(36), g0.xyzw ld_structured r5.xyzw, r0.y, l(52), g0.xyzw endif if_nz r2.x ld_structured r6.xyzw, vThreadIDInGroupFlattened.x, l(0), g0.xyzw ushr r3.z, icb[r1.y + 0].x, r0.z and r3.z, r3.z, l(1) ishl r7.x, r0.z, l(1) ushr r7.x, icb[r1.w + 0].y, r7.x and r7.x, r7.x, l(3) ieq r8.xyzw, r0.wwww, l(0, 2, 1, 3) movc r9.xyzw, r7.xxxx, l(-1,-1,-1,-1), r6.xyzw movc r7.xyzw, r7.xxxx, l(0,0,0,0), r6.xyzw or r8.xy, r8.ywyy, r8.xzxx ieq r10.xyzw, r0.wwww, l(7, 4, 5, 6) or r8.y, r8.y, r10.x movc r11.xyzw, r3.zzzz, l(-1,-1,-1,-1), r6.xyzw movc r12.xyzw, r3.zzzz, l(0,0,0,0), r6.xyzw or r3.z, r10.z, r10.y or r3.z, r10.w, r3.z movc r10.xyzw, r3.zzzz, r6.xyzw, l(-1,-1,-1,-1) and r6.xyzw, r6.xyzw, r3.zzzz movc r10.xyzw, r8.yyyy, r11.xyzw, r10.xyzw movc r6.xyzw, r8.yyyy, r12.xyzw, r6.xyzw movc r9.xyzw, r8.xxxx, r9.xyzw, r10.xyzw movc r6.xyzw, r8.xxxx, r7.xyzw, r6.xyzw store_structured g0.xyzw, vThreadIDInGroupFlattened.x, l(36), r9.xyzw store_structured g0.xyzw, vThreadIDInGroupFlattened.x, l(52), r6.xyzw endif if_nz r2.y ld_structured r6.xyzw, vThreadIDInGroupFlattened.x, l(36), g0.xyzw ld_structured r7.xyzw, vThreadIDInGroupFlattened.x, l(52), g0.xyzw iadd r2.y, vThreadIDInGroupFlattened.x, l(8) ld_structured r8.xyzw, r2.y, l(36), g0.xyzw ld_structured r9.xyzw, r2.y, l(52), g0.xyzw umin r6.xyzw, r6.xyzw, r8.xyzw store_structured g0.xyzw, vThreadIDInGroupFlattened.x, l(36), r6.xyzw umax r6.xyzw, r7.xyzw, r9.xyzw store_structured g0.xyzw, vThreadIDInGroupFlattened.x, l(52), r6.xyzw endif if_nz r2.z ld_structured r6.xyzw, vThreadIDInGroupFlattened.x, l(36), g0.xyzw ld_structured r7.xyzw, vThreadIDInGroupFlattened.x, l(52), g0.xyzw iadd r2.y, vThreadIDInGroupFlattened.x, l(4) ld_structured r8.xyzw, r2.y, l(36), g0.xyzw ld_structured r9.xyzw, r2.y, l(52), g0.xyzw umin r6.xyzw, r6.xyzw, r8.xyzw store_structured g0.xyzw, vThreadIDInGroupFlattened.x, l(36), r6.xyzw umax r6.xyzw, r7.xyzw, r9.xyzw store_structured g0.xyzw, vThreadIDInGroupFlattened.x, l(52), r6.xyzw endif if_nz r2.w ld_structured r6.xyzw, vThreadIDInGroupFlattened.x, l(36), g0.xyzw ld_structured r7.xyzw, vThreadIDInGroupFlattened.x, l(52), g0.xyzw iadd r2.y, vThreadIDInGroupFlattened.x, l(2) ld_structured r8.xyzw, r2.y, l(36), g0.xyzw ld_structured r9.xyzw, r2.y, l(52), g0.xyzw umin r6.xyzw, r6.xyzw, r8.xyzw store_structured g0.xyzw, vThreadIDInGroupFlattened.x, l(36), r6.xyzw umax r6.xyzw, r7.xyzw, r9.xyzw store_structured g0.xyzw, vThreadIDInGroupFlattened.x, l(52), r6.xyzw endif if_nz r3.x ld_structured r6.xyzw, vThreadIDInGroupFlattened.x, l(36), g0.xyzw ld_structured r7.xyzw, vThreadIDInGroupFlattened.x, l(52), g0.xyzw iadd r2.y, vThreadIDInGroupFlattened.x, l(1) ld_structured r8.xyzw, r2.y, l(36), g0.xyzw ld_structured r9.xyzw, r2.y, l(52), g0.xyzw umin r6.xyzw, r6.xyzw, r8.xyzw store_structured g0.xyzw, vThreadIDInGroupFlattened.x, l(36), r6.xyzw umax r6.xyzw, r7.xyzw, r9.xyzw store_structured g0.xyzw, vThreadIDInGroupFlattened.x, l(52), r6.xyzw endif if_z r0.z ld_structured r4.xyzw, r0.y, l(36), g0.xyzw ld_structured r5.xyzw, r0.y, l(52), g0.xyzw endif if_nz r3.y ieq r2.yzw, r0.wwww, l(0, 1, 4, 5) ushr r3.x, r1.z, r0.z and r3.x, r3.x, l(1) ishl r3.y, r0.z, l(1) ushr r6.x, r1.z, r3.y iadd r3.y, r3.y, l(1) ushr r6.y, r1.z, r3.y and r3.yz, r6.xxyx, l(0, 1, 1, 0) movc r3.xy, r2.yyyy, r3.xxxx, r3.yzyy if_z r0.w iadd r6.xyz, r4.xyzx, l(4, 4, 4, 0) umin r6.xyz, r6.xyzx, l(255, 255, 255, 0) ushr r6.xyz, r6.xyzx, l(3) and r6.xyz, r6.xyzx, l(30, 30, 30, 0) iadd r6.xyz, r3.xxxx, r6.xyzx ishl r6.xyz, r6.xyzx, l(3) ushr r7.xyz, r6.xyzx, l(5) iadd r7.xyz, r6.xyzx, r7.xyzx iadd r8.xyz, r5.xyzx, l(4, 4, 4, 0) umin r8.xyz, r8.xyzx, l(255, 255, 255, 0) ushr r8.xyz, r8.xyzx, l(3) and r8.xyz, r8.xyzx, l(30, 30, 30, 0) iadd r8.xyz, r3.yyyy, r8.xyzx ishl r8.xyz, r8.xyzx, l(3) ushr r9.xyz, r8.xyzx, l(5) iadd r5.xyz, r8.xyzx, r9.xyzx mov r5.w, l(255) mov r4.xyw, l(255,2040,0,2040) else if_nz r2.y iadd r9.xyz, r4.xyzx, l(1, 1, 1, 0) umin r9.xyz, r9.xyzx, l(255, 255, 255, 0) ushr r9.xyz, r9.xyzx, l(1) and r9.xyz, r9.xyzx, l(126, 126, 126, 0) iadd r9.xyz, r3.xxxx, r9.xyzx ishl r6.xyz, r9.xyzx, l(1) ushr r9.xyz, r6.xyzx, l(7) iadd r7.xyz, r6.xyzx, r9.xyzx iadd r9.xyz, r5.xyzx, l(1, 1, 1, 0) umin r9.xyz, r9.xyzx, l(255, 255, 255, 0) ushr r9.xyz, r9.xyzx, l(1) and r9.xyz, r9.xyzx, l(126, 126, 126, 0) iadd r9.xyz, r3.yyyy, r9.xyzx ishl r8.xyz, r9.xyzx, l(1) ushr r9.xyz, r8.xyzx, l(7) iadd r5.xyz, r8.xyzx, r9.xyzx mov r5.w, l(255) mov r4.xyw, l(255,510,0,510) else ieq r2.y, r0.w, l(2) if_nz r2.y iadd r9.xyz, r4.xyzx, l(4, 4, 4, 0) umin r9.xyz, r9.xyzx, l(255, 255, 255, 0) and r6.xyz, r9.xyzx, l(248, 248, 248, 0) ushr r9.xyz, r9.xyzx, l(5) iadd r7.xyz, r6.xyzx, r9.xyzx iadd r9.xyz, r5.xyzx, l(4, 4, 4, 0) umin r9.xyz, r9.xyzx, l(255, 255, 255, 0) and r8.xyz, r9.xyzx, l(248, 248, 248, 0) ushr r9.xyz, r9.xyzx, l(5) iadd r5.xyz, r8.xyzx, r9.xyzx mov r5.w, l(255) mov r4.xyw, l(255,2040,0,2040) else ieq r2.y, r0.w, l(3) if_nz r2.y and r9.xyz, r4.xyzx, l(-2, -2, -2, 0) iadd r6.xyz, r3.xxxx, r9.xyzx and r9.xyz, r5.xyzx, l(-2, -2, -2, 0) iadd r8.xyz, r3.yyyy, r9.xyzx mov r7.xyz, r6.xyzx mov r5.xyz, r8.xyzx mov r5.w, l(255) mov r4.xyw, l(255,255,0,255) else ieq r2.y, r0.w, l(4) if_nz r2.y iadd r9.xyzw, r4.xyzw, l(4, 4, 4, 2) umin r9.xyzw, r9.xyzw, l(255, 255, 255, 255) and r6.xyzw, r9.xyzw, l(248, 248, 248, 252) ushr r10.xyz, r9.xyzx, l(5) ushr r10.w, r9.w, l(6) iadd r7.xyzw, r6.xyzw, r10.xyzw iadd r9.xyzw, r5.xyzw, l(4, 4, 4, 2) umin r9.xyzw, r9.xyzw, l(255, 255, 255, 255) and r4.xyzw, r9.xwzy, l(248, 252, 248, 248) ushr r10.xyz, r9.xyzx, l(5) ushr r10.w, r9.w, l(6) iadd r5.xyzw, r4.xwzy, r10.xyzw mov r8.xyz, r4.xwzx mov r4.x, r7.w mov r4.w, r6.w else ieq r2.y, r0.w, l(5) if_nz r2.y iadd r9.xyz, r4.xyzx, l(1, 1, 1, 0) umin r9.xyz, r9.xyzx, l(255, 255, 255, 0) and r6.xyz, r9.xyzx, l(254, 254, 254, 0) ushr r9.xyz, r9.xyzx, l(7) iadd r7.xyz, r6.xyzx, r9.xyzx iadd r9.xyz, r5.xyzx, l(1, 1, 1, 0) umin r9.xyz, r9.xyzx, l(255, 255, 255, 0) and r8.xyz, r9.xyzx, l(254, 254, 254, 0) ushr r9.xyz, r9.xyzx, l(7) iadd r5.xyz, r8.xyzx, r9.xyzx mov r4.x, r4.w mov r4.y, r5.w else ieq r2.y, r0.w, l(6) if_nz r2.y and r9.xyzw, r4.xyzw, l(-2, -2, -2, -2) iadd r6.xyzw, r3.xxxx, r9.xyzw and r9.xyzw, r5.xyzw, l(-2, -2, -2, -2) iadd r4.xyzw, r3.yyyy, r9.xwzy mov r7.xyz, r6.xyzx mov r5.xyzw, r4.xwzy mov r8.xyz, r4.xwzx mov r4.xw, r6.wwww else iadd r9.xyzw, r4.xyzw, l(2, 2, 2, 2) umin r9.xyzw, r9.xyzw, l(255, 255, 255, 255) ushr r9.xyzw, r9.xyzw, l(2) and r9.xyzw, r9.xyzw, l(62, 62, 62, 62) iadd r9.xyzw, r3.xxxx, r9.xyzw ishl r6.xyzw, r9.xyzw, l(2) ushr r10.xyzw, r6.xyzw, l(6) iadd r4.xyzw, r6.wxzy, r10.wxzy iadd r10.xyzw, r5.xyzw, l(2, 2, 2, 2) umin r10.xyzw, r10.xyzw, l(255, 255, 255, 255) ushr r10.xyzw, r10.xyzw, l(2) and r10.xyzw, r10.xyzw, l(62, 62, 62, 62) iadd r10.xyzw, r3.yyyy, r10.xwyz ishl r8.xyzw, r10.xzwy, l(2) ushr r11.xyzw, r8.xyzw, l(6) iadd r5.xyzw, r8.xyzw, r11.xyzw mov r10.x, r9.w ishl r3.xy, r10.xyxx, l(2) mov r7.xyz, r4.ywzy mov r4.yw, r3.yyyx endif endif endif endif endif endif endif ineg r9.xyz, r7.xyzx ineg r9.w, r4.x iadd r10.xyzw, r5.xyzw, r9.xyzw ult r2.y, r0.w, l(4) movc r2.y, r2.y, l(0), r10.w or r2.z, r2.w, r2.z if_nz r2.z if_z r0.z imul null, r2.zw, r10.xxxy, r10.xxxy iadd r2.z, r2.w, r2.z imad r2.z, r10.z, r10.z, r2.z imul null, r2.w, r2.y, r2.y ld_structured r11.xyzw, r0.y, l(0), g0.xyzw iadd r3.xyz, -r7.xyzx, r11.xyzx imul null, r3.xy, r3.xyxx, r10.xyxx iadd r3.x, r3.y, r3.x imad r3.x, r10.z, r3.z, r3.x iadd r3.y, -r4.x, r11.w imul null, r3.y, r2.y, r3.y ilt r3.z, l(0), r2.z ilt r10.w, l(0), r3.x and r3.z, r3.z, r10.w itof r3.x, r3.x mul r3.x, r3.x, l(63.499989) ftou r3.x, r3.x ishl r2.z, r2.z, l(5) ult r2.z, r2.z, r3.x and r2.z, r2.z, r3.z movc r11.xyz, r2.zzzz, r5.xyzx, r7.xyzx movc r5.xyz, r2.zzzz, r7.xyzx, r5.xyzx movc r12.xyz, r2.zzzz, r8.xyzx, r6.xyzx movc r8.xyz, r2.zzzz, r6.xyzx, r8.xyzx ilt r2.z, l(0), r2.w ilt r3.x, l(0), r3.y and r2.z, r2.z, r3.x itof r3.x, r3.y mul r3.x, r3.x, l(63.499989) ftou r3.x, r3.x ishl r2.w, r2.w, l(5) ult r2.w, r2.w, r3.x and r2.z, r2.w, r2.z mov r4.z, r5.w movc r13.xyzw, r2.zzzz, r4.zxyw, r4.xzwy mov r11.w, r13.x mov r5.w, r13.y mov r12.w, r13.z mov r6.xyzw, r12.xyzw mov r8.w, r13.w else mov r7.w, r4.x mov r11.xyzw, r7.xyzw mov r6.w, r4.w mov r8.w, r4.y endif else if_z r0.z mov r2.z, l(0) else if_nz r3.w mov r2.z, icb[r1.y + 0].z else mov r2.z, icb[r1.y + 0].w endif endif imul null, r3.xy, r10.xyxx, r10.xyxx iadd r2.w, r3.y, r3.x imad r2.w, r10.z, r10.z, r2.w imad r2.w, r2.y, r2.y, r2.w iadd r2.z, r0.y, r2.z ld_structured r3.xyzw, r2.z, l(0), g0.xyzw iadd r3.xyzw, r9.xyzw, r3.xyzw imul null, r3.xy, r3.xyxx, r10.xyxx iadd r2.z, r3.y, r3.x imad r2.z, r10.z, r3.z, r2.z imad r2.y, r2.y, r3.w, r2.z ilt r2.z, l(0), r2.w ilt r3.x, l(0), r2.y and r2.z, r2.z, r3.x itof r2.y, r2.y mul r2.y, r2.y, l(63.499989) ftou r2.y, r2.y ishl r2.w, r2.w, l(5) ult r2.y, r2.w, r2.y and r2.y, r2.y, r2.z mov r7.w, r4.x movc r11.xyzw, r2.yyyy, r5.xyzw, r7.xyzw movc r5.xyzw, r2.yyyy, r7.xyzw, r5.xyzw mov r8.w, r4.y mov r4.xyz, r6.xyzx movc r6.xyzw, r2.yyyy, r8.xyzw, r4.xyzw movc r8.xyzw, r2.yyyy, r4.xyzw, r8.xyzw endif store_structured g0.xyzw, vThreadIDInGroupFlattened.x, l(36), r11.xyzw store_structured g0.xyzw, vThreadIDInGroupFlattened.x, l(52), r5.xyzw store_structured g0.xyzw, vThreadIDInGroupFlattened.x, l(68), r6.xyzw store_structured g0.xyzw, vThreadIDInGroupFlattened.x, l(84), r8.xyzw endif if_nz r2.x ieq r2.xyzw, r0.wwww, l(0, 1, 6, 4) or r3.x, r2.y, r2.x movc r3.yz, r1.xxxx, l(0,1,2,0), l(0,2,1,0) movc r3.yz, r2.wwww, r3.yyzy, l(0,2,2,0) movc r3.yz, r2.zzzz, l(0,0,0,0), r3.yyzy movc r3.xy, r3.xxxx, l(1,1,0,0), r3.yzyy ieq r4.xyzw, r0.wwww, l(2, 3, 7, 5) ishl r2.z, r0.z, l(1) ushr r1.w, icb[r1.w + 0].y, r2.z and r1.w, r1.w, l(3) or r2.xyz, r2.xywx, r4.xywx or r2.y, r4.z, r2.y ushr r2.w, icb[r1.y + 0].x, r0.z and r2.y, r2.y, r2.w and r2.y, r2.y, l(1) movc r1.w, r2.x, r1.w, r2.y iadd r1.w, r0.y, r1.w ld_structured r4.xyzw, r1.w, l(36), g0.xyzw ld_structured r5.xyzw, r1.w, l(52), g0.xyzw iadd r5.xyzw, -r4.xyzw, r5.xyzw ult r1.w, r0.w, l(4) movc r1.w, r1.w, l(0), r5.w if_nz r2.z imul null, r2.xy, r5.xyxx, r5.xyxx iadd r2.x, r2.y, r2.x imad r2.x, r5.z, r5.z, r2.x imul null, r2.y, r1.w, r1.w ld_structured r6.xyzw, vThreadIDInGroupFlattened.x, l(0), g0.xyzw iadd r7.xyzw, -r4.xyzw, r6.xyzw imul null, r2.zw, r5.xxxy, r7.xxxy iadd r2.z, r2.w, r2.z imad r2.z, r5.z, r7.z, r2.z ige r2.w, l(0), r2.x ige r3.z, l(0), r2.z or r2.w, r2.w, r3.z ilt r3.z, r2.z, r2.x itof r2.xz, r2.xxzx mul r2.z, r2.z, l(63.499989) div r2.x, r2.z, r2.x ftou r2.x, r2.x ishl r3.yw, r3.xxxy, l(6) iadd r2.x, r2.x, r3.y iadd r6.xy, r3.ywyy, l(11, 11, 0, 0) udiv null, r6.xy, r6.xyxx, l(68, 68, 0, 0) ult r7.xy, r3.ywyy, l(1, 1, 0, 0) movc r6.xy, r7.xyxx, l(15,15,0,0), r6.xyxx movc r2.x, r3.z, icb[r2.x + 64].x, r6.x movc r7.y, r2.w, l(0), r2.x imul null, r2.x, r1.w, r7.w ige r2.zw, l(0, 0, 0, 0), r2.yyyx or r2.z, r2.w, r2.z ilt r2.w, r2.x, r2.y itof r2.xy, r2.xyxx mul r2.x, r2.x, l(63.499989) div r2.x, r2.x, r2.y ftou r2.x, r2.x iadd r2.x, r2.x, r3.w movc r2.x, r2.w, icb[r2.x + 64].x, r6.y movc r7.x, r2.z, l(0), r2.x movc r2.xy, r1.xxxx, r7.xyxx, r7.yxyy else imul null, r2.zw, r5.xxxy, r5.xxxy iadd r2.z, r2.w, r2.z imad r2.z, r5.z, r5.z, r2.z imad r2.z, r1.w, r1.w, r2.z ld_structured r6.xyzw, vThreadIDInGroupFlattened.x, l(0), g0.xyzw iadd r4.xyzw, -r4.xyzw, r6.xyzw imul null, r3.yz, r4.xxyx, r5.xxyx iadd r2.w, r3.z, r3.y imad r2.w, r5.z, r4.z, r2.w imad r1.w, r1.w, r4.w, r2.w ige r2.w, l(0), r2.z ige r3.y, l(0), r1.w or r2.w, r2.w, r3.y ilt r3.y, r1.w, r2.z itof r1.w, r1.w mul r1.w, r1.w, l(63.499989) itof r2.z, r2.z div r1.w, r1.w, r2.z ftou r1.w, r1.w ishl r2.z, r3.x, l(6) iadd r1.w, r1.w, r2.z iadd r3.x, r2.z, l(11) udiv null, r3.x, r3.x, l(68) ult r2.z, r2.z, l(1) movc r2.z, r2.z, l(15), r3.x movc r1.w, r3.y, icb[r1.w + 64].x, r2.z movc r2.x, r2.w, l(0), r1.w mov r2.y, l(0) endif store_structured g0.xy, vThreadIDInGroupFlattened.x, l(16), r2.xyxx endif if_z r0.z if_z r0.w ishl r0.z, r1.y, l(1) iadd r0.z, r0.z, l(-128) iadd r0.z, r0.z, l(1) ld_structured r2.xyz, r0.y, l(68), g0.xyzx ishl r3.x, r2.x, l(1) ishl r3.y, r2.y, l(25) ishl r3.z, r2.z, l(17) and r3.xyz, r3.xyzx, l(480, 0xe0000000, 0x01e00000, 0) or r0.z, r0.z, r3.x ld_structured r4.xyz, r0.y, l(84), g0.xyzx ishl r5.x, r4.x, l(5) ishl r5.y, r4.z, l(21) and r2.xw, r5.xxxy, l(7680, 0, 0, 0x1e000000) or r0.z, r0.z, r2.x iadd r3.xw, r0.yyyy, l(1, 0, 0, 2) ld_structured r5.xyz, r3.x, l(68), g0.xyzx ishl r6.x, r5.x, l(9) ishl r6.y, r5.y, l(1) ishl r6.z, r5.z, l(25) and r6.xyz, r6.xyzx, l(0x0001e000, 480, 0xe0000000, 0) or r0.z, r0.z, r6.x ld_structured r7.xyz, r3.x, l(84), g0.xyzx ishl r8.x, r7.x, l(13) ishl r8.y, r7.y, l(5) and r4.xw, r8.xxxy, l(0x001e0000, 0, 0, 7680) or r0.z, r0.z, r4.x ld_structured r8.xyz, r3.w, l(68), g0.xyzx ishl r9.x, r8.x, l(17) ishl r9.y, r8.y, l(9) ishl r9.z, r8.z, l(1) and r9.xyz, r9.xyzx, l(0x01e00000, 0x0001e000, 480, 0) or r0.z, r0.z, r9.x ld_structured r10.xyz, r3.w, l(84), g0.xyzx ishl r11.x, r10.x, l(21) ishl r11.y, r10.y, l(13) ishl r11.z, r10.z, l(5) and r11.xyz, r11.xyzx, l(0x1e000000, 0x001e0000, 7680, 0) or r0.z, r0.z, r11.x or r12.x, r3.y, r0.z ld_structured r13.xy, r0.y, l(68), g0.xyxx ushr r0.z, r13.y, l(7) and r0.z, r0.z, l(1) ushr r1.w, r4.y, l(3) and r1.w, r1.w, l(30) iadd r0.z, r0.z, r1.w iadd r0.z, r6.y, r0.z iadd r0.z, r4.w, r0.z iadd r0.z, r9.y, r0.z iadd r0.z, r11.y, r0.z iadd r0.z, r3.z, r0.z iadd r0.z, r2.w, r0.z iadd r12.y, r6.z, r0.z ld_structured r2.x, r3.x, l(76), g0.xxxx ushr r0.z, r2.x, l(7) and r0.z, r0.z, l(1) ushr r1.w, r7.z, l(3) and r1.w, r1.w, l(30) iadd r0.z, r0.z, r1.w iadd r0.z, r9.z, r0.z iadd r0.z, r11.z, r0.z ishl r1.w, r13.x, l(10) and r1.w, r1.w, l(8192) iadd r0.z, r0.z, r1.w ld_structured r2.x, r0.y, l(84), g0.xxxx ishl r1.w, r2.x, l(11) and r1.w, r1.w, l(0x00004000) iadd r0.z, r0.z, r1.w ld_structured r2.x, r3.x, l(68), g0.xxxx ishl r1.w, r2.x, l(12) and r1.w, r1.w, l(0x00008000) iadd r0.z, r0.z, r1.w ld_structured r2.x, r3.x, l(84), g0.xxxx ishl r1.w, r2.x, l(13) and r1.w, r1.w, l(0x00010000) iadd r0.z, r0.z, r1.w ld_structured r2.x, r3.w, l(68), g0.xxxx ishl r1.w, r2.x, l(14) and r1.w, r1.w, l(0x00020000) iadd r0.z, r0.z, r1.w ld_structured r2.x, r3.w, l(84), g0.xxxx ishl r1.w, r2.x, l(15) and r1.w, r1.w, l(0x00040000) iadd r0.z, r0.z, r1.w ld_structured r2.x, r0.y, l(16), g0.xxxx ishl r1.w, r2.x, l(19) iadd r0.z, r0.z, r1.w umin r1.w, l(4), icb[r1.y + 128].y mov r12.z, r0.z mov r2.x, l(1) loop ult r2.y, r1.w, r2.x breakc_nz r2.y iadd r2.y, r0.y, r2.x ld_structured r3.x, r2.y, l(16), g0.xxxx imad r2.y, r2.x, l(3), l(18) ishl r2.y, r3.x, r2.y or r12.z, r2.y, r12.z iadd r2.x, r2.x, l(1) endloop ult r0.z, icb[r1.y + 128].y, l(4) if_nz r0.z iadd r0.z, r0.y, l(4) ld_structured r3.x, r0.z, l(16), g0.xxxx ishl r0.z, r3.x, l(29) or r12.z, r0.z, r12.z iadd r2.z, r2.x, l(1) mov r2.y, l(0) else iadd r0.z, r0.y, l(4) ld_structured r3.x, r0.z, l(16), g0.xxxx ushr r0.z, r3.x, l(2) and r0.z, r0.z, l(1) mov r2.y, r0.z mov r2.z, r2.x loop ult r1.w, icb[r1.y + 128].y, r2.z breakc_nz r1.w iadd r1.w, r0.y, r2.z ld_structured r3.x, r1.w, l(16), g0.xxxx imad r1.w, r2.z, l(3), l(-14) ishl r1.w, r3.x, r1.w or r2.y, r1.w, r2.y iadd r2.z, r2.z, l(1) endloop endif mov r0.z, r2.y mov r1.w, r2.z loop ult r2.x, icb[r1.y + 128].z, r1.w breakc_nz r2.x iadd r2.x, r0.y, r1.w ld_structured r3.x, r2.x, l(16), g0.xxxx imad r2.x, r1.w, l(3), l(-15) ishl r2.x, r3.x, r2.x or r0.z, r0.z, r2.x iadd r1.w, r1.w, l(1) endloop mov r12.w, r0.z mov r2.x, r1.w loop uge r2.y, r2.x, l(16) breakc_nz r2.y iadd r2.y, r0.y, r2.x ld_structured r3.x, r2.y, l(16), g0.xxxx imad r2.y, r2.x, l(3), l(-16) ishl r2.y, r3.x, r2.y or r12.w, r2.y, r12.w iadd r2.x, r2.x, l(1) endloop else ieq r0.z, r0.w, l(1) if_nz r0.z ishl r0.z, r1.y, l(2) iadd r0.z, r0.z, l(2) ld_structured r2.xyz, r0.y, l(68), g0.xyzx ishl r3.x, r2.x, l(6) ishl r3.y, r2.z, l(22) and r2.xz, r3.xxyx, l(0x00003f00, 0, 0x3f000000, 0) or r0.z, r0.z, r2.x ld_structured r3.xyz, r0.y, l(84), g0.xyzx ishl r4.x, r3.x, l(12) ishl r4.y, r3.y, l(4) ishl r4.z, r3.z, l(28) and r3.xyz, r4.xyzx, l(0x000fc000, 4032, 0xc0000000, 0) or r0.z, r0.z, r3.x iadd r1.w, r0.y, l(1) ld_structured r4.xyz, r1.w, l(68), g0.xyzx ishl r5.x, r4.x, l(18) ishl r5.y, r4.y, l(10) ishl r5.z, r4.z, l(2) and r4.xyz, r5.xyzx, l(0x03f00000, 0x0003f000, 1008, 0) or r0.z, r0.z, r4.x ld_structured r5.xyz, r1.w, l(84), g0.xyzx ishl r6.x, r5.x, l(24) ishl r6.y, r5.y, l(16) ishl r6.z, r5.z, l(8) and r5.xyz, r6.xyzx, l(0xfc000000, 0x00fc0000, 0x0000fc00, 0) or r12.x, r0.z, r5.x ushr r0.z, r2.y, l(2) and r0.z, r0.z, l(63) iadd r0.z, r3.y, r0.z iadd r0.z, r4.y, r0.z iadd r0.z, r5.y, r0.z iadd r0.z, r2.z, r0.z iadd r12.y, r3.z, r0.z ld_structured r2.x, r0.y, l(92), g0.xxxx ushr r0.z, r2.x, l(4) and r0.z, r0.z, l(15) iadd r0.z, r4.z, r0.z iadd r0.z, r5.z, r0.z ld_structured r2.x, r0.y, l(68), g0.xxxx ishl r2.x, r2.x, l(15) and r2.x, r2.x, l(0x00010000) iadd r0.z, r0.z, r2.x ld_structured r2.x, r1.w, l(68), g0.xxxx ishl r2.x, r2.x, l(16) and r2.x, r2.x, l(0x00020000) iadd r0.z, r0.z, r2.x ld_structured r2.x, r0.y, l(16), g0.xxxx ishl r2.x, r2.x, l(18) iadd r0.z, r0.z, r2.x ieq r2.y, l(15), icb[r1.y + 128].y if_nz r2.y iadd r3.xyzw, r0.yyyy, l(15, 14, 13, 12) ld_structured r4.x, r3.x, l(16), g0.xxxx ishl r2.y, r4.x, l(30) ld_structured r4.x, r3.y, l(16), g0.xxxx ishl r2.z, r4.x, l(27) or r2.y, r2.z, r2.y ld_structured r4.x, r3.z, l(16), g0.xxxx ishl r2.z, r4.x, l(24) or r2.y, r2.z, r2.y ld_structured r3.x, r3.w, l(16), g0.xxxx ishl r2.z, r3.x, l(21) or r2.y, r2.z, r2.y iadd r3.xyzw, r0.yyyy, l(11, 10, 9, 8) ld_structured r4.x, r3.x, l(16), g0.xxxx ishl r2.z, r4.x, l(18) or r2.y, r2.z, r2.y ld_structured r4.x, r3.y, l(16), g0.xxxx ishl r2.z, r4.x, l(15) or r2.y, r2.z, r2.y ld_structured r4.x, r3.z, l(16), g0.xxxx ishl r2.z, r4.x, l(12) or r2.y, r2.z, r2.y ld_structured r3.x, r3.w, l(16), g0.xxxx ishl r2.z, r3.x, l(9) or r2.y, r2.z, r2.y iadd r3.xyzw, r0.yyyy, l(7, 6, 5, 4) ld_structured r4.x, r3.x, l(16), g0.xxxx ishl r2.z, r4.x, l(6) or r2.y, r2.z, r2.y ld_structured r4.x, r3.y, l(16), g0.xxxx ishl r2.z, r4.x, l(3) or r2.y, r2.z, r2.y ld_structured r4.x, r3.z, l(16), g0.xxxx or r12.w, r2.y, r4.x ld_structured r3.x, r3.w, l(16), g0.xxxx ishl r2.y, r3.x, l(29) iadd r2.zw, r0.yyyy, l(0, 0, 3, 2) ld_structured r3.x, r2.z, l(16), g0.xxxx ishl r2.z, r3.x, l(26) or r2.y, r2.z, r2.y ld_structured r3.x, r2.w, l(16), g0.xxxx ishl r2.z, r3.x, l(23) or r2.y, r2.z, r2.y ld_structured r3.x, r1.w, l(16), g0.xxxx ishl r2.z, r3.x, l(20) or r2.y, r2.z, r2.y or r2.y, r2.x, r2.y or r12.z, r0.z, r2.y else ieq r2.y, l(2), icb[r1.y + 128].y if_nz r2.y iadd r3.xyzw, r0.yyyy, l(15, 14, 13, 12) ld_structured r4.x, r3.x, l(16), g0.xxxx ishl r2.y, r4.x, l(29) ld_structured r4.x, r3.y, l(16), g0.xxxx ishl r2.z, r4.x, l(26) or r2.y, r2.z, r2.y ld_structured r4.x, r3.z, l(16), g0.xxxx ishl r2.z, r4.x, l(23) or r2.y, r2.z, r2.y ld_structured r3.x, r3.w, l(16), g0.xxxx ishl r2.z, r3.x, l(20) or r2.y, r2.z, r2.y iadd r3.xyzw, r0.yyyy, l(11, 10, 9, 8) ld_structured r4.x, r3.x, l(16), g0.xxxx ishl r2.z, r4.x, l(17) or r2.y, r2.z, r2.y ld_structured r4.x, r3.y, l(16), g0.xxxx ishl r2.z, r4.x, l(14) or r2.y, r2.z, r2.y ld_structured r4.x, r3.z, l(16), g0.xxxx ishl r2.z, r4.x, l(11) or r2.y, r2.z, r2.y ld_structured r3.x, r3.w, l(16), g0.xxxx ishl r2.z, r3.x, l(8) or r2.y, r2.z, r2.y iadd r3.xyzw, r0.yyyy, l(7, 6, 5, 4) ld_structured r4.x, r3.x, l(16), g0.xxxx ishl r2.z, r4.x, l(5) or r2.y, r2.z, r2.y ld_structured r4.x, r3.y, l(16), g0.xxxx ishl r2.z, r4.x, l(2) or r2.y, r2.z, r2.y ld_structured r4.x, r3.z, l(16), g0.xxxx ushr r2.z, r4.x, l(1) or r12.w, r2.z, r2.y ishl r2.y, r4.x, l(31) ld_structured r3.x, r3.w, l(16), g0.xxxx ishl r2.z, r3.x, l(28) or r2.y, r2.z, r2.y iadd r2.zw, r0.yyyy, l(0, 0, 3, 2) ld_structured r3.x, r2.z, l(16), g0.xxxx ishl r2.z, r3.x, l(25) or r2.y, r2.z, r2.y ld_structured r3.x, r2.w, l(16), g0.xxxx ishl r2.z, r3.x, l(23) or r2.y, r2.z, r2.y ld_structured r3.x, r1.w, l(16), g0.xxxx ishl r2.z, r3.x, l(20) or r2.y, r2.z, r2.y or r2.y, r2.x, r2.y or r12.z, r0.z, r2.y else ieq r2.y, l(8), icb[r1.y + 128].y if_nz r2.y iadd r3.xyzw, r0.yyyy, l(15, 14, 13, 12) ld_structured r4.x, r3.x, l(16), g0.xxxx ishl r2.y, r4.x, l(29) ld_structured r4.x, r3.y, l(16), g0.xxxx ishl r2.z, r4.x, l(26) or r2.y, r2.z, r2.y ld_structured r4.x, r3.z, l(16), g0.xxxx ishl r2.z, r4.x, l(23) or r2.y, r2.z, r2.y ld_structured r3.x, r3.w, l(16), g0.xxxx ishl r2.z, r3.x, l(20) or r2.y, r2.z, r2.y iadd r3.xyzw, r0.yyyy, l(11, 10, 9, 8) ld_structured r4.x, r3.x, l(16), g0.xxxx ishl r2.z, r4.x, l(17) or r2.y, r2.z, r2.y ld_structured r4.x, r3.y, l(16), g0.xxxx ishl r2.z, r4.x, l(14) or r2.y, r2.z, r2.y ld_structured r4.x, r3.z, l(16), g0.xxxx ishl r2.z, r4.x, l(11) or r2.y, r2.z, r2.y ld_structured r3.x, r3.w, l(16), g0.xxxx ishl r2.z, r3.x, l(9) or r2.y, r2.z, r2.y iadd r3.xyzw, r0.yyyy, l(7, 6, 5, 4) ld_structured r4.x, r3.x, l(16), g0.xxxx ishl r2.z, r4.x, l(6) or r2.y, r2.z, r2.y ld_structured r4.x, r3.y, l(16), g0.xxxx ishl r2.z, r4.x, l(3) or r2.y, r2.z, r2.y ld_structured r4.x, r3.z, l(16), g0.xxxx or r12.w, r2.y, r4.x ld_structured r3.x, r3.w, l(16), g0.xxxx ishl r2.y, r3.x, l(29) iadd r2.zw, r0.yyyy, l(0, 0, 3, 2) ld_structured r3.x, r2.z, l(16), g0.xxxx ishl r2.z, r3.x, l(26) or r2.y, r2.z, r2.y ld_structured r3.x, r2.w, l(16), g0.xxxx ishl r2.z, r3.x, l(23) or r2.y, r2.z, r2.y ld_structured r3.x, r1.w, l(16), g0.xxxx ishl r2.z, r3.x, l(20) or r2.y, r2.z, r2.y or r2.y, r2.x, r2.y or r12.z, r0.z, r2.y else iadd r3.xyzw, r0.yyyy, l(15, 14, 13, 12) ld_structured r4.x, r3.x, l(16), g0.xxxx ishl r2.y, r4.x, l(29) ld_structured r4.x, r3.y, l(16), g0.xxxx ishl r2.z, r4.x, l(26) or r2.y, r2.z, r2.y ld_structured r4.x, r3.z, l(16), g0.xxxx ishl r2.z, r4.x, l(23) or r2.y, r2.z, r2.y ld_structured r3.x, r3.w, l(16), g0.xxxx ishl r2.z, r3.x, l(20) or r2.y, r2.z, r2.y iadd r3.xyzw, r0.yyyy, l(11, 10, 9, 8) ld_structured r4.x, r3.x, l(16), g0.xxxx ishl r2.z, r4.x, l(17) or r2.y, r2.z, r2.y ld_structured r4.x, r3.y, l(16), g0.xxxx ishl r2.z, r4.x, l(14) or r2.y, r2.z, r2.y ld_structured r4.x, r3.z, l(16), g0.xxxx ishl r2.z, r4.x, l(11) or r2.y, r2.z, r2.y ld_structured r3.x, r3.w, l(16), g0.xxxx ishl r2.z, r3.x, l(8) or r2.y, r2.z, r2.y iadd r3.xyzw, r0.yyyy, l(7, 6, 5, 4) ld_structured r4.x, r3.x, l(16), g0.xxxx ishl r2.z, r4.x, l(6) or r2.y, r2.z, r2.y ld_structured r4.x, r3.y, l(16), g0.xxxx ishl r2.z, r4.x, l(4) or r2.y, r2.z, r2.y ld_structured r4.x, r3.z, l(16), g0.xxxx or r12.w, r2.y, r4.x ld_structured r3.x, r3.w, l(16), g0.xxxx ishl r2.y, r3.x, l(29) iadd r2.zw, r0.yyyy, l(0, 0, 3, 2) ld_structured r3.x, r2.z, l(16), g0.xxxx ishl r2.z, r3.x, l(26) or r2.y, r2.z, r2.y ld_structured r3.x, r2.w, l(16), g0.xxxx ishl r2.z, r3.x, l(23) or r2.y, r2.z, r2.y ld_structured r3.x, r1.w, l(16), g0.xxxx ishl r1.w, r3.x, l(20) or r1.w, r1.w, r2.y or r1.w, r2.x, r1.w or r12.z, r0.z, r1.w endif endif endif else ieq r0.z, r0.w, l(2) if_nz r0.z ishl r0.z, r1.y, l(3) iadd r0.z, r0.z, l(-512) iadd r0.z, r0.z, l(4) ld_structured r2.xyz, r0.y, l(68), g0.xyzx ishl r3.x, r2.x, l(6) ishl r3.y, r2.y, l(4) ishl r3.z, r2.z, l(2) and r3.xyz, r3.xyzx, l(0x00003e00, 3968, 992, 0) or r0.z, r0.z, r3.x ld_structured r4.xyz, r0.y, l(84), g0.xyzx ishl r5.x, r4.x, l(11) ishl r5.y, r4.y, l(9) ishl r5.z, r4.z, l(7) and r5.xyz, r5.xyzx, l(0x0007c000, 0x0001f000, 0x00007c00, 0) or r0.z, r0.z, r5.x iadd r2.xw, r0.yyyy, l(1, 0, 0, 2) ld_structured r6.xyz, r2.x, l(68), g0.xyzx ishl r7.x, r6.x, l(16) ishl r7.y, r6.y, l(14) ishl r7.z, r6.z, l(12) and r7.xyz, r7.xyzx, l(0x00f80000, 0x003e0000, 0x000f8000, 0) or r0.z, r0.z, r7.x ld_structured r8.xyz, r2.x, l(84), g0.xyzx ishl r9.x, r8.x, l(21) ishl r9.y, r8.y, l(19) ishl r9.z, r8.z, l(17) and r9.xyz, r9.xyzx, l(0x1f000000, 0x07c00000, 0x01f00000, 0) or r0.z, r0.z, r9.x ld_structured r10.xyz, r2.w, l(68), g0.xyzx ishl r11.x, r10.x, l(26) ishl r11.y, r10.y, l(24) ishl r11.z, r10.z, l(22) and r11.xyz, r11.xyzx, l(0xe0000000, 0xf8000000, 0x3e000000, 0) or r12.x, r0.z, r11.x ld_structured r13.x, r2.w, l(68), g0.xxxx ushr r0.z, r13.x, l(6) and r0.z, r0.z, l(3) ld_structured r13.xyz, r2.w, l(84), g0.xyzx ushr r14.x, r13.x, l(1) ushr r14.y, r13.y, l(3) and r3.xw, r14.xxxy, l(124, 0, 0, 31) iadd r0.z, r0.z, r3.x iadd r0.z, r3.y, r0.z iadd r0.z, r5.y, r0.z iadd r0.z, r7.y, r0.z iadd r0.z, r9.y, r0.z iadd r12.y, r11.y, r0.z iadd r0.z, r3.z, r3.w iadd r0.z, r5.z, r0.z iadd r0.z, r7.z, r0.z iadd r0.z, r9.z, r0.z iadd r0.z, r11.z, r0.z ishl r1.w, r13.z, l(27) and r1.w, r1.w, l(0xc0000000) iadd r12.z, r0.z, r1.w ld_structured r2.x, r2.w, l(92), g0.xxxx ushr r0.z, r2.x, l(5) and r0.z, r0.z, l(7) ld_structured r2.x, r0.y, l(16), g0.xxxx ishl r1.w, r2.x, l(3) iadd r0.z, r0.z, r1.w mov r1.w, r0.z mov r2.x, l(1) loop ult r2.y, icb[r1.y + 128].y, r2.x breakc_nz r2.y iadd r2.y, r0.y, r2.x ld_structured r3.x, r2.y, l(16), g0.xxxx ishl r2.y, r2.x, l(1) iadd r2.y, r2.y, l(2) ishl r2.y, r3.x, r2.y or r1.w, r1.w, r2.y iadd r2.x, r2.x, l(1) endloop mov r0.z, r1.w mov r2.y, r2.x loop ult r2.z, icb[r1.y + 128].z, r2.y breakc_nz r2.z iadd r2.z, r0.y, r2.y ld_structured r3.x, r2.z, l(16), g0.xxxx ishl r2.z, r2.y, l(1) iadd r2.z, r2.z, l(1) ishl r2.z, r3.x, r2.z or r0.z, r0.z, r2.z iadd r2.y, r2.y, l(1) endloop mov r12.w, r0.z mov r1.w, r2.y loop uge r2.x, r1.w, l(16) breakc_nz r2.x iadd r2.x, r0.y, r1.w ld_structured r3.x, r2.x, l(16), g0.xxxx ishl r2.x, r1.w, l(1) ishl r2.x, r3.x, r2.x or r12.w, r2.x, r12.w iadd r1.w, r1.w, l(1) endloop else ieq r0.z, r0.w, l(3) if_nz r0.z ishl r0.z, r1.y, l(4) iadd r0.z, r0.z, l(8) ld_structured r2.xyz, r0.y, l(68), g0.xyzx ishl r3.x, r2.x, l(9) ishl r3.y, r2.y, l(5) ishl r3.z, r2.z, l(1) and r3.xyz, r3.xyzx, l(0x0001fc00, 8128, 508, 0) or r0.z, r0.z, r3.x ld_structured r4.xyz, r0.y, l(84), g0.xyzx ishl r5.x, r4.x, l(16) ishl r5.y, r4.y, l(12) ishl r5.z, r4.z, l(8) and r5.xyz, r5.xyzx, l(0x00fe0000, 0x000fe000, 0x0000fe00, 0) or r0.z, r0.z, r5.x iadd r1.w, r0.y, l(1) ld_structured r6.xyz, r1.w, l(68), g0.xyzx ishl r7.x, r6.x, l(23) ishl r7.y, r6.y, l(19) ishl r7.z, r6.z, l(15) and r7.xyz, r7.xyzx, l(0x7f000000, 0x07f00000, 0x007f0000, 0) or r0.z, r0.z, r7.x ld_structured r8.xyz, r1.w, l(84), g0.xyzx ishl r9.x, r8.x, l(30) ishl r9.y, r8.y, l(26) ishl r9.z, r8.z, l(22) and r9.xyz, r9.xyzx, l(0x80000000, 0xf8000000, 0x3f800000, 0) or r12.x, r0.z, r9.x ld_structured r10.xy, r1.w, l(84), g0.xyxx ushr r11.x, r10.x, l(2) ushr r11.y, r10.y, l(6) and r2.xw, r11.xxxy, l(63, 0, 0, 3) iadd r2.xy, r3.yzyy, r2.xwxx iadd r2.xy, r5.yzyy, r2.xyxx iadd r2.xy, r7.yzyy, r2.xyxx iadd r2.xy, r9.yzyy, r2.xyxx ld_structured r3.x, r0.y, l(68), g0.xxxx ishl r0.z, r3.x, l(30) and r0.z, r0.z, l(0x40000000) iadd r0.z, r0.z, r2.y ld_structured r3.x, r0.y, l(84), g0.xxxx ishl r2.y, r3.x, l(31) iadd r12.z, r0.z, r2.y ld_structured r3.x, r1.w, l(68), g0.xxxx and r0.z, r3.x, l(1) ld_structured r3.x, r1.w, l(84), g0.xxxx ishl r1.w, r3.x, l(1) and r1.w, r1.w, l(2) iadd r0.z, r0.z, r1.w ld_structured r3.x, r0.y, l(16), g0.xxxx ishl r1.w, r3.x, l(2) iadd r0.z, r0.z, r1.w mov r1.w, r0.z mov r2.y, l(1) loop ult r2.z, icb[r1.y + 128].y, r2.y breakc_nz r2.z iadd r2.z, r0.y, r2.y ld_structured r3.x, r2.z, l(16), g0.xxxx ishl r2.z, r2.y, l(1) iadd r2.z, r2.z, l(1) ishl r2.z, r3.x, r2.z or r1.w, r1.w, r2.z iadd r2.y, r2.y, l(1) endloop mov r12.w, r1.w mov r0.z, r2.y loop uge r2.z, r0.z, l(16) breakc_nz r2.z iadd r2.z, r0.z, r0.y ld_structured r3.x, r2.z, l(16), g0.xxxx ishl r2.z, r0.z, l(1) ishl r2.z, r3.x, r2.z or r12.w, r2.z, r12.w iadd r0.z, r0.z, l(1) endloop mov r12.y, r2.x else ieq r0.z, r0.w, l(4) if_nz r0.z ishl r0.z, r1.z, l(5) and r0.z, r0.z, l(96) iadd r0.z, r0.z, l(16) ishl r1.x, r1.x, l(7) iadd r0.z, r0.z, r1.x ld_structured r2.xyzw, r0.y, l(68), g0.xyzw ishl r3.x, r2.x, l(5) ishl r3.y, r2.y, l(15) ishl r3.z, r2.z, l(25) ishl r3.w, r2.w, l(4) and r2.xyzw, r3.xyzw, l(7936, 0x007c0000, 0xf0000000, 4032) iadd r0.z, r0.z, r2.x ld_structured r3.xyzw, r0.y, l(84), g0.xyzw ishl r4.xz, r3.xxwx, l(10) ishl r4.y, r3.y, l(20) and r3.xyw, r4.xyxz, l(0x0003e000, 0x0f800000, 0, 0x0003f000) iadd r0.z, r0.z, r3.x iadd r0.z, r2.y, r0.z iadd r0.z, r3.y, r0.z iadd r12.x, r2.z, r0.z ld_structured r4.x, r0.y, l(76), g0.xxxx ushr r0.z, r4.x, l(7) and r0.z, r0.z, l(1) ushr r1.x, r3.z, l(2) and r1.x, r1.x, l(62) iadd r0.z, r0.z, r1.x iadd r0.z, r2.w, r0.z iadd r0.z, r3.w, r0.z ld_structured r2.xy, r0.y, l(16), g0.xyxx ishl r3.x, r2.x, l(18) ishl r3.y, r2.y, l(17) and r1.xw, r3.xxxy, l(0x00040000, 0, 0, 0x00060000) iadd r0.z, r0.z, r1.x iadd r2.xyzw, r0.yyyy, l(1, 2, 3, 4) ld_structured r3.xy, r2.x, l(16), g0.xyxx ishl r3.xy, r3.xyxx, l(19) iadd r0.z, r0.z, r3.x ld_structured r4.xy, r2.y, l(16), g0.xyxx ishl r1.x, r4.x, l(21) ishl r2.x, r4.y, l(22) or r0.z, r0.z, r1.x ld_structured r4.xy, r2.z, l(16), g0.xyxx ishl r1.x, r4.x, l(23) ishl r2.y, r4.y, l(25) or r0.z, r0.z, r1.x ld_structured r4.xy, r2.w, l(16), g0.xyxx ishl r1.x, r4.x, l(25) ishl r2.z, r4.y, l(28) or r0.z, r0.z, r1.x iadd r4.xyzw, r0.yyyy, l(5, 6, 7, 8) ld_structured r5.xy, r4.x, l(16), g0.xyxx ishl r1.x, r5.x, l(27) ishl r2.w, r5.y, l(31) or r0.z, r0.z, r1.x ld_structured r5.xy, r4.y, l(16), g0.xyxx ishl r1.x, r5.x, l(29) ishl r3.x, r5.y, l(2) or r0.z, r0.z, r1.x ld_structured r5.xy, r4.z, l(16), g0.xyxx ishl r1.x, r5.x, l(31) ishl r3.z, r5.y, l(5) or r12.y, r0.z, r1.x ld_structured r5.x, r4.z, l(16), g0.xxxx ushr r0.z, r5.x, l(1) ld_structured r5.xy, r4.w, l(16), g0.xyxx ishl r1.x, r5.x, l(1) ishl r3.w, r5.y, l(8) or r0.z, r0.z, r1.x iadd r5.xyzw, r0.yyyy, l(9, 10, 11, 12) ld_structured r6.xy, r5.x, l(16), g0.xyxx ishl r1.x, r6.x, l(3) ishl r4.y, r6.y, l(11) or r0.z, r0.z, r1.x ld_structured r6.xy, r5.y, l(16), g0.xyxx ishl r1.x, r6.x, l(5) ishl r4.z, r6.y, l(14) or r0.z, r0.z, r1.x ld_structured r6.xy, r5.z, l(16), g0.xyxx ishl r1.x, r6.x, l(7) ishl r4.w, r6.y, l(17) or r0.z, r0.z, r1.x ld_structured r5.xy, r5.w, l(16), g0.xyxx ishl r1.x, r5.x, l(9) ishl r5.x, r5.y, l(20) or r0.z, r0.z, r1.x iadd r5.yzw, r0.yyyy, l(0, 13, 14, 15) ld_structured r6.xy, r5.y, l(16), g0.xyxx ishl r1.x, r6.x, l(11) ishl r5.y, r6.y, l(23) or r0.z, r0.z, r1.x ld_structured r6.xy, r5.z, l(16), g0.xyxx ishl r1.x, r6.x, l(13) ishl r5.z, r6.y, l(26) or r0.z, r0.z, r1.x ld_structured r6.xy, r5.w, l(16), g0.xyxx ishl r1.x, r6.x, l(15) ishl r5.w, r6.y, l(29) or r0.z, r0.z, r1.x or r0.z, r1.w, r0.z or r0.z, r3.y, r0.z or r0.z, r2.x, r0.z or r0.z, r2.y, r0.z or r0.z, r2.z, r0.z or r12.z, r2.w, r0.z ld_structured r2.x, r4.x, l(20), g0.xxxx ushr r0.z, r2.x, l(1) or r0.z, r3.x, r0.z or r0.z, r3.z, r0.z or r0.z, r3.w, r0.z or r0.z, r4.y, r0.z or r0.z, r4.z, r0.z or r0.z, r4.w, r0.z or r0.z, r5.x, r0.z or r0.z, r5.y, r0.z or r0.z, r5.z, r0.z or r12.w, r5.w, r0.z else ieq r0.z, r0.w, l(5) if_nz r0.z ishl r0.z, r1.z, l(6) iadd r0.z, r0.z, l(32) ld_structured r2.xyzw, r0.y, l(68), g0.xyzw ishl r3.x, r2.x, l(7) ishl r3.y, r2.y, l(21) ishl r3.z, r2.z, l(3) ishl r1.x, r2.w, l(18) and r2.xyz, r3.xyzx, l(0x00007f00, 0x1fc00000, 2032, 0) or r0.z, r0.z, r2.x ld_structured r3.xyzw, r0.y, l(84), g0.xyzw ishl r4.x, r3.x, l(14) ishl r4.y, r3.y, l(28) ishl r4.z, r3.z, l(10) ishl r1.z, r3.w, l(26) and r3.xyz, r4.xyzx, l(0x003f8000, 0xe0000000, 0x0003f800, 0) or r0.z, r0.z, r3.x or r0.z, r2.y, r0.z or r12.x, r3.y, r0.z ld_structured r4.x, r0.y, l(88), g0.xxxx ushr r0.z, r4.x, l(4) and r0.z, r0.z, l(15) iadd r0.z, r2.z, r0.z iadd r0.z, r3.z, r0.z iadd r0.z, r1.x, r0.z or r12.y, r1.z, r0.z ld_structured r2.x, r0.y, l(96), g0.xxxx ushr r0.z, r2.x, l(6) ld_structured r2.xy, r0.y, l(16), g0.xyxx ishl r1.x, r2.x, l(2) ishl r1.z, r2.y, l(1) or r0.z, r0.z, r1.x iadd r2.xyzw, r0.yyyy, l(1, 2, 3, 4) ld_structured r3.xy, r2.x, l(16), g0.xyxx ishl r1.x, r3.x, l(3) ishl r1.w, r3.y, l(2) or r0.z, r0.z, r1.x ld_structured r3.xy, r2.y, l(16), g0.xyxx ishl r1.x, r3.x, l(5) ishl r2.x, r3.y, l(4) or r0.z, r0.z, r1.x ld_structured r3.xy, r2.z, l(16), g0.xyxx ishl r1.x, r3.x, l(7) ishl r2.y, r3.y, l(6) or r0.z, r0.z, r1.x ld_structured r3.xy, r2.w, l(16), g0.xyxx ishl r1.x, r3.x, l(9) ishl r2.z, r3.y, l(8) or r0.z, r0.z, r1.x iadd r3.xyzw, r0.yyyy, l(5, 6, 7, 8) ld_structured r4.xy, r3.x, l(16), g0.xyxx ishl r1.x, r4.x, l(11) ishl r2.w, r4.y, l(10) or r0.z, r0.z, r1.x ld_structured r4.xy, r3.y, l(16), g0.xyxx ishl r1.x, r4.x, l(13) ishl r3.x, r4.y, l(12) or r0.z, r0.z, r1.x ld_structured r4.xy, r3.z, l(16), g0.xyxx ishl r1.x, r4.x, l(15) ishl r3.y, r4.y, l(14) or r0.z, r0.z, r1.x ld_structured r4.xy, r3.w, l(16), g0.xyxx ishl r1.x, r4.x, l(17) ishl r3.z, r4.y, l(16) or r0.z, r0.z, r1.x iadd r4.xyzw, r0.yyyy, l(9, 10, 11, 12) ld_structured r5.xy, r4.x, l(16), g0.xyxx ishl r1.x, r5.x, l(19) ishl r3.w, r5.y, l(18) or r0.z, r0.z, r1.x ld_structured r5.xy, r4.y, l(16), g0.xyxx ishl r1.x, r5.x, l(21) ishl r4.x, r5.y, l(20) or r0.z, r0.z, r1.x ld_structured r5.xy, r4.z, l(16), g0.xyxx ishl r1.x, r5.x, l(23) ishl r4.y, r5.y, l(22) or r0.z, r0.z, r1.x ld_structured r5.xy, r4.w, l(16), g0.xyxx ishl r1.x, r5.x, l(25) ishl r4.z, r5.y, l(24) or r0.z, r0.z, r1.x iadd r5.xyz, r0.yyyy, l(13, 14, 15, 0) ld_structured r6.xy, r5.x, l(16), g0.xyxx ishl r1.x, r6.x, l(27) ishl r4.w, r6.y, l(26) or r0.z, r0.z, r1.x ld_structured r6.xy, r5.y, l(16), g0.xyxx ishl r1.x, r6.x, l(29) ishl r5.x, r6.y, l(28) or r0.z, r0.z, r1.x ld_structured r6.xy, r5.z, l(16), g0.xyxx ishl r1.x, r6.x, l(31) ishl r5.y, r6.y, l(30) or r12.z, r0.z, r1.x ld_structured r6.x, r5.z, l(16), g0.xxxx ushr r0.z, r6.x, l(1) or r0.z, r1.z, r0.z or r0.z, r1.w, r0.z or r0.z, r2.x, r0.z or r0.z, r2.y, r0.z or r0.z, r2.z, r0.z or r0.z, r2.w, r0.z or r0.z, r3.x, r0.z or r0.z, r3.y, r0.z or r0.z, r3.z, r0.z or r0.z, r3.w, r0.z or r0.z, r4.x, r0.z or r0.z, r4.y, r0.z or r0.z, r4.z, r0.z or r0.z, r4.w, r0.z or r0.z, r5.x, r0.z or r12.w, r5.y, r0.z else ieq r0.z, r0.w, l(6) if_nz r0.z ld_structured r2.xyzw, r0.y, l(68), g0.xyzw ishl r3.x, r2.x, l(6) ishl r3.y, r2.y, l(20) ishl r3.z, r2.z, l(2) ishl r3.w, r2.w, l(16) and r2.xyzw, r3.xyzw, l(0x00003f80, 0x0fe00000, 1016, 0x00fe0000) iadd r0.z, r2.x, l(64) ld_structured r3.xyzw, r0.y, l(84), g0.xyzw ishl r4.x, r3.x, l(13) ishl r4.y, r3.y, l(27) ishl r4.z, r3.z, l(9) ishl r4.w, r3.w, l(23) and r3.xyzw, r4.xyzw, l(0x001fc000, 0xf0000000, 0x0001fc00, 0x7f000000) iadd r0.z, r0.z, r3.x iadd r0.z, r2.y, r0.z iadd r12.x, r3.y, r0.z ld_structured r4.xy, r0.y, l(84), g0.xyxx ushr r0.z, r4.y, l(5) and r0.z, r0.z, l(7) iadd r0.z, r2.z, r0.z iadd r0.z, r3.z, r0.z iadd r0.z, r2.w, r0.z iadd r0.z, r3.w, r0.z ld_structured r2.x, r0.y, l(68), g0.xxxx ishl r0.w, r2.x, l(31) iadd r12.y, r0.w, r0.z and r0.z, r4.x, l(1) ld_structured r2.x, r0.y, l(16), g0.xxxx ishl r0.w, r2.x, l(1) iadd r0.z, r0.w, r0.z iadd r2.xyzw, r0.yyyy, l(1, 2, 3, 4) ld_structured r3.x, r2.x, l(16), g0.xxxx ishl r0.w, r3.x, l(4) or r0.z, r0.w, r0.z ld_structured r3.x, r2.y, l(16), g0.xxxx ishl r0.w, r3.x, l(8) or r0.z, r0.w, r0.z ld_structured r3.x, r2.z, l(16), g0.xxxx ishl r0.w, r3.x, l(12) or r0.z, r0.w, r0.z ld_structured r2.x, r2.w, l(16), g0.xxxx ishl r0.w, r2.x, l(16) or r0.z, r0.w, r0.z iadd r2.xyzw, r0.yyyy, l(5, 6, 7, 8) ld_structured r3.x, r2.x, l(16), g0.xxxx ishl r0.w, r3.x, l(20) or r0.z, r0.w, r0.z ld_structured r3.x, r2.y, l(16), g0.xxxx ishl r0.w, r3.x, l(24) or r0.z, r0.w, r0.z ld_structured r3.x, r2.z, l(16), g0.xxxx ishl r0.w, r3.x, l(28) or r12.z, r0.w, r0.z ld_structured r2.x, r2.w, l(16), g0.xxxx iadd r3.xyzw, r0.yyyy, l(9, 10, 11, 12) ld_structured r4.x, r3.x, l(16), g0.xxxx ishl r0.z, r4.x, l(4) or r0.z, r0.z, r2.x ld_structured r2.x, r3.y, l(16), g0.xxxx ishl r0.w, r2.x, l(8) or r0.z, r0.w, r0.z ld_structured r2.x, r3.z, l(16), g0.xxxx ishl r0.w, r2.x, l(12) or r0.z, r0.w, r0.z ld_structured r2.x, r3.w, l(16), g0.xxxx ishl r0.w, r2.x, l(16) or r0.z, r0.w, r0.z iadd r1.xzw, r0.yyyy, l(13, 0, 14, 15) ld_structured r2.x, r1.x, l(16), g0.xxxx ishl r0.w, r2.x, l(20) or r0.z, r0.w, r0.z ld_structured r2.x, r1.z, l(16), g0.xxxx ishl r0.w, r2.x, l(24) or r0.z, r0.w, r0.z ld_structured r2.x, r1.w, l(16), g0.xxxx ishl r0.w, r2.x, l(28) or r12.w, r0.w, r0.z else ishl r0.z, r1.y, l(8) iadd r0.z, r0.z, l(128) ld_structured r2.xyzw, r0.y, l(68), g0.xyzw ishl r3.x, r2.x, l(11) ishl r3.y, r2.z, l(19) ishl r3.z, r2.w, l(7) and r1.xzw, r3.xxyz, l(0x0007c000, 0, 0x07c00000, 0x00007c00) or r0.z, r0.z, r1.x ld_structured r3.xyzw, r0.y, l(84), g0.xyzw ishl r4.x, r3.x, l(16) ishl r4.y, r3.y, l(4) ishl r4.z, r3.z, l(24) ishl r4.w, r3.w, l(12) and r4.xyzw, r4.xyzw, l(0x00f80000, 3968, 0xf8000000, 0x000f8000) or r0.z, r0.z, r4.x iadd r0.w, r0.y, l(1) ld_structured r5.xyzw, r0.w, l(68), g0.xyzw ishl r6.x, r5.x, l(21) ishl r6.y, r5.y, l(9) ishl r6.z, r5.w, l(17) and r6.xyz, r6.xyzx, l(0x1f000000, 0x0001f000, 0x01f00000, 0) or r0.z, r0.z, r6.x ld_structured r7.xyzw, r0.w, l(84), g0.xyzw ishl r8.x, r7.x, l(26) ishl r8.y, r7.y, l(14) ishl r8.z, r7.z, l(2) ishl r8.w, r7.w, l(22) and r8.xyzw, r8.xyzw, l(0xe0000000, 0x003e0000, 992, 0x3e000000) or r12.x, r0.z, r8.x ld_structured r9.x, r0.w, l(84), g0.xxxx ushr r10.x, r9.x, l(6) ushr r10.y, r9.x, l(1) and r6.xw, r10.xxxy, l(3, 0, 0, 2) ushr r0.z, r2.y, l(1) and r0.z, r0.z, l(124) iadd r0.z, r0.z, r6.x iadd r0.z, r4.y, r0.z iadd r0.z, r6.y, r0.z iadd r0.z, r8.y, r0.z iadd r0.z, r1.z, r0.z iadd r12.y, r4.z, r0.z ushr r0.z, r5.z, l(3) and r0.z, r0.z, l(31) iadd r0.z, r8.z, r0.z iadd r0.z, r1.w, r0.z iadd r0.z, r4.w, r0.z iadd r0.z, r6.z, r0.z iadd r0.z, r8.w, r0.z ld_structured r2.x, r0.y, l(68), g0.xxxx ishl r1.x, r2.x, l(28) and r1.x, r1.x, l(0x40000000) iadd r0.z, r0.z, r1.x ld_structured r2.x, r0.y, l(84), g0.xxxx ishl r1.x, r2.x, l(29) and r1.x, r1.x, l(0x80000000) iadd r12.z, r0.z, r1.x ld_structured r2.x, r0.w, l(68), g0.xxxx ushr r0.z, r2.x, l(2) and r0.z, r0.z, l(1) iadd r0.z, r6.w, r0.z ld_structured r2.x, r0.y, l(16), g0.xxxx ishl r0.w, r2.x, l(2) iadd r0.z, r0.w, r0.z mov r0.w, r0.z mov r1.x, l(1) loop ult r1.z, icb[r1.y + 128].y, r1.x breakc_nz r1.z iadd r1.z, r0.y, r1.x ld_structured r2.x, r1.z, l(16), g0.xxxx ishl r1.z, r1.x, l(1) iadd r1.z, r1.z, l(1) ishl r1.z, r2.x, r1.z or r0.w, r0.w, r1.z iadd r1.x, r1.x, l(1) endloop mov r12.w, r0.w mov r0.z, r1.x loop uge r1.y, r0.z, l(16) breakc_nz r1.y iadd r1.y, r0.z, r0.y ld_structured r2.x, r1.y, l(16), g0.xxxx ishl r1.y, r0.z, l(1) ishl r1.y, r2.x, r1.y or r12.w, r1.y, r12.w iadd r0.z, r0.z, l(1) endloop endif endif endif endif endif endif endif store_structured u0.xyzw, r0.x, l(0), r12.xyzw endif ret // Approximately 0 instruction slots used #endif const BYTE BC7Encode_EncodeBlockCS[] = { 68, 88, 66, 67, 38, 175, 165, 204, 73, 182, 127, 102, 182, 246, 162, 152, 80, 235, 28, 253, 1, 0, 0, 0, 200, 193, 0, 0, 3, 0, 0, 0, 44, 0, 0, 0, 60, 0, 0, 0, 76, 0, 0, 0, 73, 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 116, 193, 0, 0, 64, 0, 5, 0, 93, 48, 0, 0, 106, 8, 0, 1, 53, 24, 0, 0, 2, 4, 0, 0, 204, 204, 0, 0, 80, 80, 104, 170, 15, 0, 0, 0, 0, 0, 0, 0, 136, 136, 0, 0, 64, 80, 90, 106, 15, 0, 0, 0, 0, 0, 0, 0, 238, 238, 0, 0, 0, 66, 90, 90, 15, 0, 0, 0, 0, 0, 0, 0, 200, 236, 0, 0, 168, 160, 80, 84, 15, 0, 0, 0, 0, 0, 0, 0, 128, 200, 0, 0, 0, 0, 165, 165, 15, 0, 0, 0, 0, 0, 0, 0, 236, 254, 0, 0, 80, 80, 160, 160, 15, 0, 0, 0, 0, 0, 0, 0, 200, 254, 0, 0, 160, 160, 85, 85, 15, 0, 0, 0, 0, 0, 0, 0, 128, 236, 0, 0, 80, 80, 90, 90, 15, 0, 0, 0, 0, 0, 0, 0, 0, 200, 0, 0, 0, 0, 85, 170, 15, 0, 0, 0, 0, 0, 0, 0, 236, 255, 0, 0, 0, 85, 85, 170, 15, 0, 0, 0, 0, 0, 0, 0, 128, 254, 0, 0, 0, 85, 170, 170, 15, 0, 0, 0, 0, 0, 0, 0, 0, 232, 0, 0, 144, 144, 144, 144, 15, 0, 0, 0, 0, 0, 0, 0, 232, 255, 0, 0, 148, 148, 148, 148, 15, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 164, 164, 164, 164, 15, 0, 0, 0, 0, 0, 0, 0, 240, 255, 0, 0, 80, 148, 165, 169, 15, 0, 0, 0, 0, 0, 0, 0, 0, 240, 0, 0, 80, 66, 10, 42, 15, 0, 0, 0, 0, 0, 0, 0, 16, 247, 0, 0, 64, 80, 148, 165, 15, 0, 0, 0, 0, 0, 0, 0, 142, 0, 0, 0, 84, 80, 66, 10, 2, 0, 0, 0, 0, 0, 0, 0, 0, 113, 0, 0, 0, 165, 165, 165, 8, 0, 0, 0, 0, 0, 0, 0, 206, 8, 0, 0, 160, 160, 160, 85, 2, 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, 0, 84, 84, 168, 168, 2, 0, 0, 0, 0, 0, 0, 0, 16, 115, 0, 0, 64, 64, 106, 106, 8, 0, 0, 0, 0, 0, 0, 0, 0, 49, 0, 0, 0, 80, 164, 164, 8, 0, 0, 0, 0, 0, 0, 0, 206, 140, 0, 0, 0, 5, 26, 26, 15, 0, 0, 0, 0, 0, 0, 0, 140, 8, 0, 0, 164, 164, 80, 0, 2, 0, 0, 0, 0, 0, 0, 0, 16, 49, 0, 0, 144, 144, 165, 170, 8, 0, 0, 0, 0, 0, 0, 0, 102, 102, 0, 0, 20, 105, 105, 20, 2, 0, 0, 0, 0, 0, 0, 0, 108, 54, 0, 0, 0, 20, 105, 105, 2, 0, 0, 0, 0, 0, 0, 0, 232, 23, 0, 0, 160, 133, 133, 160, 8, 0, 0, 0, 0, 0, 0, 0, 240, 15, 0, 0, 20, 20, 130, 170, 8, 0, 0, 0, 0, 0, 0, 0, 142, 113, 0, 0, 80, 164, 164, 80, 2, 0, 0, 0, 0, 0, 0, 0, 156, 57, 0, 0, 0, 2, 90, 106, 2, 0, 0, 0, 0, 0, 0, 0, 170, 170, 0, 0, 0, 128, 165, 169, 15, 0, 0, 0, 0, 0, 0, 0, 240, 240, 0, 0, 168, 160, 144, 80, 15, 0, 0, 0, 0, 0, 0, 0, 90, 90, 0, 0, 80, 144, 160, 168, 6, 0, 0, 0, 0, 0, 0, 0, 204, 51, 0, 0, 36, 36, 36, 36, 8, 0, 0, 0, 0, 0, 0, 0, 60, 60, 0, 0, 0, 85, 170, 0, 2, 0, 0, 0, 0, 0, 0, 0, 170, 85, 0, 0, 36, 73, 146, 36, 8, 0, 0, 0, 0, 0, 0, 0, 150, 150, 0, 0, 36, 146, 73, 36, 15, 0, 0, 0, 0, 0, 0, 0, 90, 165, 0, 0, 80, 10, 165, 80, 15, 0, 0, 0, 0, 0, 0, 0, 206, 115, 0, 0, 80, 165, 10, 80, 2, 0, 0, 0, 0, 0, 0, 0, 200, 19, 0, 0, 68, 68, 170, 170, 8, 0, 0, 0, 0, 0, 0, 0, 76, 50, 0, 0, 0, 0, 102, 102, 2, 0, 0, 0, 0, 0, 0, 0, 220, 59, 0, 0, 160, 165, 160, 165, 2, 0, 0, 0, 0, 0, 0, 0, 150, 105, 0, 0, 160, 80, 160, 80, 2, 0, 0, 0, 0, 0, 0, 0, 60, 195, 0, 0, 40, 105, 40, 105, 15, 0, 0, 0, 0, 0, 0, 0, 102, 153, 0, 0, 68, 170, 170, 68, 15, 0, 0, 0, 0, 0, 0, 0, 96, 6, 0, 0, 0, 102, 102, 102, 6, 0, 0, 0, 0, 0, 0, 0, 114, 2, 0, 0, 68, 68, 68, 170, 6, 0, 0, 0, 0, 0, 0, 0, 228, 4, 0, 0, 168, 84, 168, 84, 2, 0, 0, 0, 0, 0, 0, 0, 64, 78, 0, 0, 128, 149, 128, 149, 6, 0, 0, 0, 0, 0, 0, 0, 32, 39, 0, 0, 0, 150, 150, 150, 8, 0, 0, 0, 0, 0, 0, 0, 54, 201, 0, 0, 168, 84, 84, 168, 15, 0, 0, 0, 0, 0, 0, 0, 108, 147, 0, 0, 128, 149, 149, 128, 15, 0, 0, 0, 0, 0, 0, 0, 198, 57, 0, 0, 20, 20, 20, 170, 2, 0, 0, 0, 0, 0, 0, 0, 156, 99, 0, 0, 0, 0, 150, 150, 2, 0, 0, 0, 0, 0, 0, 0, 54, 147, 0, 0, 20, 20, 170, 170, 15, 0, 0, 0, 0, 0, 0, 0, 198, 156, 0, 0, 160, 80, 80, 160, 15, 0, 0, 0, 0, 0, 0, 0, 126, 129, 0, 0, 160, 165, 165, 160, 15, 0, 0, 0, 0, 0, 0, 0, 24, 231, 0, 0, 0, 0, 0, 150, 15, 0, 0, 0, 0, 0, 0, 0, 240, 204, 0, 0, 128, 64, 128, 64, 15, 0, 0, 0, 0, 0, 0, 0, 204, 15, 0, 0, 168, 169, 168, 169, 2, 0, 0, 0, 0, 0, 0, 0, 68, 119, 0, 0, 68, 170, 170, 170, 2, 0, 0, 0, 0, 0, 0, 0, 34, 238, 0, 0, 84, 82, 74, 42, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 15, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 15, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 8, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 15, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 15, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 15, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 15, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 15, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 15, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 15, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 15, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 15, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 8, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 15, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 6, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 15, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 15, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 10, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 8, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 15, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 15, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 10, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 10, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 10, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 6, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 15, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 15, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 3, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 6, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 6, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 8, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 15, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 3, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 15, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 15, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 15, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 15, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 15, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 15, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 15, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 15, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 15, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 15, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 3, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 6, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 6, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 6, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 6, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 10, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 6, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 10, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 6, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 6, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 6, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 10, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 10, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 13, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 12, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 89, 0, 0, 4, 70, 142, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 88, 24, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 162, 0, 0, 4, 0, 112, 16, 0, 1, 0, 0, 0, 16, 0, 0, 0, 158, 0, 0, 4, 0, 224, 17, 0, 0, 0, 0, 0, 16, 0, 0, 0, 95, 0, 0, 2, 0, 64, 2, 0, 95, 0, 0, 2, 18, 16, 2, 0, 104, 0, 0, 2, 15, 0, 0, 0, 160, 0, 0, 5, 0, 240, 17, 0, 0, 0, 0, 0, 100, 0, 0, 0, 64, 0, 0, 0, 155, 0, 0, 4, 64, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 85, 0, 0, 6, 18, 0, 16, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 6, 34, 0, 16, 0, 0, 0, 0, 0, 10, 16, 2, 0, 1, 64, 0, 0, 2, 0, 0, 0, 30, 0, 0, 8, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 128, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 80, 0, 0, 8, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 128, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 21, 0, 0, 1, 1, 0, 0, 6, 34, 0, 16, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 48, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 128, 65, 0, 0, 0, 0, 0, 0, 0, 10, 64, 2, 0, 167, 0, 0, 9, 114, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 70, 114, 16, 0, 1, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 255, 255, 255, 127, 167, 0, 0, 9, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 6, 112, 16, 0, 1, 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 31, 0, 0, 0, 79, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 2, 0, 0, 0, 78, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, 0, 208, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 11, 18, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 128, 65, 0, 0, 0, 1, 0, 0, 0, 26, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 0, 0, 7, 34, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 7, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, 127, 67, 28, 0, 0, 5, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 84, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 32, 0, 0, 10, 50, 0, 16, 0, 4, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 32, 0, 0, 10, 114, 0, 16, 0, 4, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 194, 0, 16, 0, 5, 0, 0, 0, 166, 10, 16, 0, 4, 0, 0, 0, 246, 11, 16, 0, 3, 0, 0, 0, 166, 14, 16, 0, 3, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 5, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 55, 0, 0, 9, 226, 0, 16, 0, 5, 0, 0, 0, 86, 5, 16, 0, 4, 0, 0, 0, 246, 6, 16, 0, 3, 0, 0, 0, 86, 14, 16, 0, 5, 0, 0, 0, 55, 0, 0, 9, 242, 0, 16, 0, 4, 0, 0, 0, 6, 0, 16, 0, 4, 0, 0, 0, 118, 2, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 55, 0, 0, 9, 242, 0, 16, 0, 3, 0, 0, 0, 246, 15, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 168, 0, 0, 8, 242, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 0, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 21, 0, 0, 1, 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 192, 255, 255, 255, 31, 0, 4, 3, 10, 0, 16, 0, 2, 0, 0, 0, 167, 0, 0, 8, 242, 0, 16, 0, 3, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 0, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 85, 0, 0, 8, 18, 0, 16, 0, 4, 0, 0, 0, 26, 144, 144, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 32, 0, 0, 10, 98, 0, 16, 0, 4, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 34, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 32, 0, 0, 7, 18, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 55, 0, 0, 12, 242, 0, 16, 0, 5, 0, 0, 0, 6, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 1, 0, 0, 7, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 6, 0, 16, 0, 4, 0, 0, 0, 55, 0, 0, 12, 242, 0, 16, 0, 5, 0, 0, 0, 86, 5, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 1, 0, 0, 7, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 86, 5, 16, 0, 4, 0, 0, 0, 168, 0, 0, 8, 242, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 36, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 168, 0, 0, 8, 242, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 26, 0, 16, 0, 2, 0, 0, 0, 167, 0, 0, 8, 242, 0, 16, 0, 3, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 36, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 167, 0, 0, 8, 242, 0, 16, 0, 4, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 30, 0, 0, 6, 18, 0, 16, 0, 5, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 8, 0, 0, 0, 167, 0, 0, 9, 242, 0, 16, 0, 6, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 36, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 167, 0, 0, 9, 242, 0, 16, 0, 5, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 84, 0, 0, 7, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 168, 0, 0, 8, 242, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 36, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 83, 0, 0, 7, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 168, 0, 0, 8, 242, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 2, 0, 0, 0, 167, 0, 0, 8, 242, 0, 16, 0, 3, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 36, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 167, 0, 0, 8, 242, 0, 16, 0, 4, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 30, 0, 0, 6, 18, 0, 16, 0, 5, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 4, 0, 0, 0, 167, 0, 0, 9, 242, 0, 16, 0, 6, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 36, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 167, 0, 0, 9, 242, 0, 16, 0, 5, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 84, 0, 0, 7, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 168, 0, 0, 8, 242, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 36, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 83, 0, 0, 7, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 168, 0, 0, 8, 242, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 58, 0, 16, 0, 2, 0, 0, 0, 167, 0, 0, 8, 242, 0, 16, 0, 3, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 36, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 167, 0, 0, 8, 242, 0, 16, 0, 4, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 30, 0, 0, 6, 18, 0, 16, 0, 5, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 2, 0, 0, 0, 167, 0, 0, 9, 242, 0, 16, 0, 6, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 36, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 167, 0, 0, 9, 242, 0, 16, 0, 5, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 84, 0, 0, 7, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 168, 0, 0, 8, 242, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 36, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 83, 0, 0, 7, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 168, 0, 0, 8, 242, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 21, 0, 0, 1, 79, 0, 0, 10, 50, 0, 16, 0, 3, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 3, 0, 0, 0, 167, 0, 0, 8, 242, 0, 16, 0, 4, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 36, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 167, 0, 0, 8, 242, 0, 16, 0, 5, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 30, 0, 0, 6, 66, 0, 16, 0, 3, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 1, 0, 0, 0, 167, 0, 0, 9, 242, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 36, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 167, 0, 0, 9, 242, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 84, 0, 0, 7, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 168, 0, 0, 8, 242, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 36, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 83, 0, 0, 7, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 168, 0, 0, 8, 242, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 21, 0, 0, 1, 32, 0, 0, 10, 194, 0, 16, 0, 3, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 3, 0, 0, 0, 167, 0, 0, 9, 242, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 36, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 167, 0, 0, 9, 242, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 10, 0, 16, 0, 2, 0, 0, 0, 167, 0, 0, 8, 242, 0, 16, 0, 6, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 0, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 85, 0, 0, 8, 66, 0, 16, 0, 3, 0, 0, 0, 10, 144, 144, 0, 26, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 85, 0, 0, 8, 18, 0, 16, 0, 7, 0, 0, 0, 26, 144, 144, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 32, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 32, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 55, 0, 0, 12, 242, 0, 16, 0, 9, 0, 0, 0, 6, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 1, 0, 0, 7, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 6, 0, 16, 0, 7, 0, 0, 0, 60, 0, 0, 7, 50, 0, 16, 0, 8, 0, 0, 0, 214, 5, 16, 0, 8, 0, 0, 0, 134, 0, 16, 0, 8, 0, 0, 0, 32, 0, 0, 7, 66, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 60, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 32, 0, 0, 7, 66, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 55, 0, 0, 12, 242, 0, 16, 0, 10, 0, 0, 0, 166, 10, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 1, 0, 0, 7, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 166, 10, 16, 0, 3, 0, 0, 0, 55, 0, 0, 12, 242, 0, 16, 0, 10, 0, 0, 0, 86, 5, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 1, 0, 0, 7, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 86, 5, 16, 0, 8, 0, 0, 0, 55, 0, 0, 9, 242, 0, 16, 0, 9, 0, 0, 0, 6, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 55, 0, 0, 9, 242, 0, 16, 0, 6, 0, 0, 0, 6, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 168, 0, 0, 8, 242, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 36, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 168, 0, 0, 8, 242, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 26, 0, 16, 0, 2, 0, 0, 0, 167, 0, 0, 8, 242, 0, 16, 0, 6, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 36, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 167, 0, 0, 8, 242, 0, 16, 0, 7, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 30, 0, 0, 6, 66, 0, 16, 0, 3, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 8, 0, 0, 0, 167, 0, 0, 9, 242, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 36, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 167, 0, 0, 9, 242, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 84, 0, 0, 7, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 168, 0, 0, 8, 242, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 36, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 83, 0, 0, 7, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 168, 0, 0, 8, 242, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 2, 0, 0, 0, 167, 0, 0, 8, 242, 0, 16, 0, 6, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 36, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 167, 0, 0, 8, 242, 0, 16, 0, 7, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 30, 0, 0, 6, 66, 0, 16, 0, 3, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 4, 0, 0, 0, 167, 0, 0, 9, 242, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 36, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 167, 0, 0, 9, 242, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 84, 0, 0, 7, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 168, 0, 0, 8, 242, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 36, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 83, 0, 0, 7, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 168, 0, 0, 8, 242, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 58, 0, 16, 0, 2, 0, 0, 0, 167, 0, 0, 8, 242, 0, 16, 0, 6, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 36, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 167, 0, 0, 8, 242, 0, 16, 0, 7, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 30, 0, 0, 6, 66, 0, 16, 0, 3, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 2, 0, 0, 0, 167, 0, 0, 9, 242, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 36, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 167, 0, 0, 9, 242, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 84, 0, 0, 7, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 168, 0, 0, 8, 242, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 36, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 83, 0, 0, 7, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 168, 0, 0, 8, 242, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 10, 0, 16, 0, 3, 0, 0, 0, 167, 0, 0, 8, 242, 0, 16, 0, 6, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 36, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 167, 0, 0, 8, 242, 0, 16, 0, 7, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 30, 0, 0, 6, 66, 0, 16, 0, 3, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 1, 0, 0, 0, 167, 0, 0, 9, 242, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 36, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 167, 0, 0, 9, 242, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 84, 0, 0, 7, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 168, 0, 0, 8, 242, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 36, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 83, 0, 0, 7, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 168, 0, 0, 8, 242, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 58, 0, 16, 0, 3, 0, 0, 0, 167, 0, 0, 9, 242, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 36, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 167, 0, 0, 9, 242, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 10, 0, 16, 0, 2, 0, 0, 0, 167, 0, 0, 8, 242, 0, 16, 0, 6, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 0, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 85, 0, 0, 8, 66, 0, 16, 0, 3, 0, 0, 0, 10, 144, 144, 0, 26, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 85, 0, 0, 8, 18, 0, 16, 0, 7, 0, 0, 0, 26, 144, 144, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 32, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 55, 0, 0, 12, 242, 0, 16, 0, 9, 0, 0, 0, 6, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 70, 14, 16, 0, 6, 0, 0, 0, 55, 0, 0, 12, 242, 0, 16, 0, 7, 0, 0, 0, 6, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 60, 0, 0, 7, 50, 0, 16, 0, 8, 0, 0, 0, 214, 5, 16, 0, 8, 0, 0, 0, 134, 0, 16, 0, 8, 0, 0, 0, 32, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 60, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 10, 0, 16, 0, 10, 0, 0, 0, 55, 0, 0, 12, 242, 0, 16, 0, 11, 0, 0, 0, 166, 10, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 70, 14, 16, 0, 6, 0, 0, 0, 55, 0, 0, 12, 242, 0, 16, 0, 12, 0, 0, 0, 166, 10, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 10, 0, 0, 0, 26, 0, 16, 0, 10, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 10, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 55, 0, 0, 12, 242, 0, 16, 0, 10, 0, 0, 0, 166, 10, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 1, 0, 0, 7, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 166, 10, 16, 0, 3, 0, 0, 0, 55, 0, 0, 9, 242, 0, 16, 0, 10, 0, 0, 0, 86, 5, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 55, 0, 0, 9, 242, 0, 16, 0, 6, 0, 0, 0, 86, 5, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 55, 0, 0, 9, 242, 0, 16, 0, 9, 0, 0, 0, 6, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 55, 0, 0, 9, 242, 0, 16, 0, 6, 0, 0, 0, 6, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 168, 0, 0, 8, 242, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 36, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 168, 0, 0, 8, 242, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 26, 0, 16, 0, 2, 0, 0, 0, 167, 0, 0, 8, 242, 0, 16, 0, 6, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 36, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 167, 0, 0, 8, 242, 0, 16, 0, 7, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 30, 0, 0, 6, 34, 0, 16, 0, 2, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 8, 0, 0, 0, 167, 0, 0, 9, 242, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 36, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 167, 0, 0, 9, 242, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 84, 0, 0, 7, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 168, 0, 0, 8, 242, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 36, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 83, 0, 0, 7, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 168, 0, 0, 8, 242, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 2, 0, 0, 0, 167, 0, 0, 8, 242, 0, 16, 0, 6, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 36, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 167, 0, 0, 8, 242, 0, 16, 0, 7, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 30, 0, 0, 6, 34, 0, 16, 0, 2, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 4, 0, 0, 0, 167, 0, 0, 9, 242, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 36, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 167, 0, 0, 9, 242, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 84, 0, 0, 7, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 168, 0, 0, 8, 242, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 36, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 83, 0, 0, 7, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 168, 0, 0, 8, 242, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 58, 0, 16, 0, 2, 0, 0, 0, 167, 0, 0, 8, 242, 0, 16, 0, 6, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 36, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 167, 0, 0, 8, 242, 0, 16, 0, 7, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 30, 0, 0, 6, 34, 0, 16, 0, 2, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 2, 0, 0, 0, 167, 0, 0, 9, 242, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 36, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 167, 0, 0, 9, 242, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 84, 0, 0, 7, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 168, 0, 0, 8, 242, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 36, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 83, 0, 0, 7, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 168, 0, 0, 8, 242, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 10, 0, 16, 0, 3, 0, 0, 0, 167, 0, 0, 8, 242, 0, 16, 0, 6, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 36, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 167, 0, 0, 8, 242, 0, 16, 0, 7, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 30, 0, 0, 6, 34, 0, 16, 0, 2, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 1, 0, 0, 0, 167, 0, 0, 9, 242, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 36, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 167, 0, 0, 9, 242, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 84, 0, 0, 7, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 168, 0, 0, 8, 242, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 36, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 83, 0, 0, 7, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 168, 0, 0, 8, 242, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 21, 0, 0, 1, 31, 0, 0, 3, 42, 0, 16, 0, 0, 0, 0, 0, 167, 0, 0, 9, 242, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 36, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 167, 0, 0, 9, 242, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 26, 0, 16, 0, 3, 0, 0, 0, 32, 0, 0, 10, 226, 0, 16, 0, 2, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 34, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 0, 0, 10, 98, 0, 16, 0, 3, 0, 0, 0, 6, 1, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 50, 0, 16, 0, 3, 0, 0, 0, 86, 5, 16, 0, 2, 0, 0, 0, 6, 0, 16, 0, 3, 0, 0, 0, 150, 5, 16, 0, 3, 0, 0, 0, 31, 0, 0, 3, 58, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 84, 0, 0, 10, 114, 0, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 114, 0, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 30, 0, 0, 0, 30, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 6, 0, 0, 0, 6, 0, 16, 0, 3, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 41, 0, 0, 7, 114, 0, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 85, 0, 0, 7, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 84, 0, 0, 10, 114, 0, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 114, 0, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 30, 0, 0, 0, 30, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 8, 0, 0, 0, 86, 5, 16, 0, 3, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 41, 0, 0, 7, 114, 0, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 85, 0, 0, 7, 114, 0, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 255, 0, 0, 0, 54, 0, 0, 8, 178, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 248, 7, 0, 0, 0, 0, 0, 0, 248, 7, 0, 0, 18, 0, 0, 1, 31, 0, 4, 3, 26, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 84, 0, 0, 10, 114, 0, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 114, 0, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 126, 0, 0, 0, 126, 0, 0, 0, 126, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 9, 0, 0, 0, 6, 0, 16, 0, 3, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 41, 0, 0, 7, 114, 0, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 114, 0, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 84, 0, 0, 10, 114, 0, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 114, 0, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 126, 0, 0, 0, 126, 0, 0, 0, 126, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 9, 0, 0, 0, 86, 5, 16, 0, 3, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 41, 0, 0, 7, 114, 0, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 114, 0, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 255, 0, 0, 0, 54, 0, 0, 8, 178, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 254, 1, 0, 0, 0, 0, 0, 0, 254, 1, 0, 0, 18, 0, 0, 1, 32, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 84, 0, 0, 10, 114, 0, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 248, 0, 0, 0, 248, 0, 0, 0, 248, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 114, 0, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 84, 0, 0, 10, 114, 0, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 248, 0, 0, 0, 248, 0, 0, 0, 248, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 114, 0, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 255, 0, 0, 0, 54, 0, 0, 8, 178, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 248, 7, 0, 0, 0, 0, 0, 0, 248, 7, 0, 0, 18, 0, 0, 1, 32, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 254, 255, 255, 255, 254, 255, 255, 255, 254, 255, 255, 255, 0, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 6, 0, 0, 0, 6, 0, 16, 0, 3, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 254, 255, 255, 255, 254, 255, 255, 255, 254, 255, 255, 255, 0, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 8, 0, 0, 0, 86, 5, 16, 0, 3, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 54, 0, 0, 5, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 54, 0, 0, 5, 114, 0, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 255, 0, 0, 0, 54, 0, 0, 8, 178, 0, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 18, 0, 0, 1, 32, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 84, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 248, 0, 0, 0, 248, 0, 0, 0, 248, 0, 0, 0, 252, 0, 0, 0, 85, 0, 0, 7, 114, 0, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 85, 0, 0, 7, 130, 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 84, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 198, 6, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 248, 0, 0, 0, 252, 0, 0, 0, 248, 0, 0, 0, 248, 0, 0, 0, 85, 0, 0, 7, 114, 0, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 85, 0, 0, 7, 130, 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 5, 0, 0, 0, 198, 6, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 54, 0, 0, 5, 114, 0, 16, 0, 8, 0, 0, 0, 198, 2, 16, 0, 4, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 18, 0, 0, 1, 32, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 84, 0, 0, 10, 114, 0, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 254, 0, 0, 0, 254, 0, 0, 0, 254, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 114, 0, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 84, 0, 0, 10, 114, 0, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 254, 0, 0, 0, 254, 0, 0, 0, 254, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 114, 0, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 54, 0, 0, 5, 34, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 18, 0, 0, 1, 32, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 254, 255, 255, 255, 254, 255, 255, 255, 254, 255, 255, 255, 254, 255, 255, 255, 30, 0, 0, 7, 242, 0, 16, 0, 6, 0, 0, 0, 6, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 254, 255, 255, 255, 254, 255, 255, 255, 254, 255, 255, 255, 254, 255, 255, 255, 30, 0, 0, 7, 242, 0, 16, 0, 4, 0, 0, 0, 86, 5, 16, 0, 3, 0, 0, 0, 198, 6, 16, 0, 9, 0, 0, 0, 54, 0, 0, 5, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 54, 0, 0, 5, 242, 0, 16, 0, 5, 0, 0, 0, 198, 6, 16, 0, 4, 0, 0, 0, 54, 0, 0, 5, 114, 0, 16, 0, 8, 0, 0, 0, 198, 2, 16, 0, 4, 0, 0, 0, 54, 0, 0, 5, 146, 0, 16, 0, 4, 0, 0, 0, 246, 15, 16, 0, 6, 0, 0, 0, 18, 0, 0, 1, 30, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 84, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 85, 0, 0, 7, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 9, 0, 0, 0, 6, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 41, 0, 0, 7, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 85, 0, 0, 7, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 4, 0, 0, 0, 54, 6, 16, 0, 6, 0, 0, 0, 54, 6, 16, 0, 10, 0, 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 84, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 85, 0, 0, 7, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 10, 0, 0, 0, 86, 5, 16, 0, 3, 0, 0, 0, 198, 9, 16, 0, 10, 0, 0, 0, 41, 0, 0, 7, 242, 0, 16, 0, 8, 0, 0, 0, 134, 7, 16, 0, 10, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 85, 0, 0, 7, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 41, 0, 0, 7, 50, 0, 16, 0, 3, 0, 0, 0, 70, 0, 16, 0, 10, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 54, 0, 0, 5, 114, 0, 16, 0, 7, 0, 0, 0, 214, 6, 16, 0, 4, 0, 0, 0, 54, 0, 0, 5, 162, 0, 16, 0, 4, 0, 0, 0, 86, 1, 16, 0, 3, 0, 0, 0, 21, 0, 0, 1, 21, 0, 0, 1, 21, 0, 0, 1, 21, 0, 0, 1, 21, 0, 0, 1, 21, 0, 0, 1, 21, 0, 0, 1, 40, 0, 0, 5, 114, 0, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 40, 0, 0, 5, 130, 0, 16, 0, 9, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 79, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 55, 0, 0, 9, 34, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 10, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 2, 0, 0, 0, 31, 0, 0, 3, 42, 0, 16, 0, 0, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 194, 0, 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, 10, 0, 0, 0, 6, 4, 16, 0, 10, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 10, 0, 0, 0, 42, 0, 16, 0, 10, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 167, 0, 0, 9, 242, 0, 16, 0, 11, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 30, 0, 0, 8, 114, 0, 16, 0, 3, 0, 0, 0, 70, 2, 16, 128, 65, 0, 0, 0, 7, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 50, 0, 16, 0, 3, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 70, 0, 16, 0, 10, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 10, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 30, 0, 0, 8, 34, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 128, 65, 0, 0, 0, 4, 0, 0, 0, 58, 0, 16, 0, 11, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 34, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 34, 0, 0, 7, 66, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 34, 0, 0, 7, 130, 0, 16, 0, 10, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 10, 0, 0, 0, 43, 0, 0, 5, 18, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 56, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 253, 255, 125, 66, 28, 0, 0, 5, 18, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 79, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 11, 0, 0, 0, 166, 10, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 5, 0, 0, 0, 166, 10, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 12, 0, 0, 0, 166, 10, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 8, 0, 0, 0, 166, 10, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 34, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 34, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 43, 0, 0, 5, 18, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 56, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 253, 255, 125, 66, 28, 0, 0, 5, 18, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 79, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 54, 0, 0, 5, 66, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 55, 0, 0, 9, 242, 0, 16, 0, 13, 0, 0, 0, 166, 10, 16, 0, 2, 0, 0, 0, 38, 13, 16, 0, 4, 0, 0, 0, 134, 7, 16, 0, 4, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 11, 0, 0, 0, 10, 0, 16, 0, 13, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 13, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 12, 0, 0, 0, 42, 0, 16, 0, 13, 0, 0, 0, 54, 0, 0, 5, 242, 0, 16, 0, 6, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 13, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 130, 0, 16, 0, 7, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 54, 0, 0, 5, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 21, 0, 0, 1, 18, 0, 0, 1, 31, 0, 0, 3, 42, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 66, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 18, 0, 0, 1, 31, 0, 4, 3, 58, 0, 16, 0, 3, 0, 0, 0, 54, 0, 0, 6, 66, 0, 16, 0, 2, 0, 0, 0, 42, 144, 144, 0, 26, 0, 16, 0, 1, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 6, 66, 0, 16, 0, 2, 0, 0, 0, 58, 144, 144, 0, 26, 0, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 21, 0, 0, 1, 38, 0, 0, 8, 0, 208, 0, 0, 50, 0, 16, 0, 3, 0, 0, 0, 70, 0, 16, 0, 10, 0, 0, 0, 70, 0, 16, 0, 10, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 10, 0, 0, 0, 42, 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 167, 0, 0, 9, 242, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 50, 0, 16, 0, 3, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 70, 0, 16, 0, 10, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 10, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 34, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 34, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 43, 0, 0, 5, 34, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 56, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 253, 255, 125, 66, 28, 0, 0, 5, 34, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 79, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 7, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 55, 0, 0, 9, 242, 0, 16, 0, 11, 0, 0, 0, 86, 5, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 55, 0, 0, 9, 242, 0, 16, 0, 5, 0, 0, 0, 86, 5, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 54, 0, 0, 5, 114, 0, 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 55, 0, 0, 9, 242, 0, 16, 0, 6, 0, 0, 0, 86, 5, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 55, 0, 0, 9, 242, 0, 16, 0, 8, 0, 0, 0, 86, 5, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 21, 0, 0, 1, 168, 0, 0, 8, 242, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 36, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 168, 0, 0, 8, 242, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 168, 0, 0, 8, 242, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 68, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 168, 0, 0, 8, 242, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 84, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 10, 0, 16, 0, 2, 0, 0, 0, 32, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 60, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 55, 0, 0, 15, 98, 0, 16, 0, 3, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 12, 98, 0, 16, 0, 3, 0, 0, 0, 246, 15, 16, 0, 2, 0, 0, 0, 86, 6, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 12, 98, 0, 16, 0, 3, 0, 0, 0, 166, 10, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 6, 16, 0, 3, 0, 0, 0, 55, 0, 0, 12, 50, 0, 16, 0, 3, 0, 0, 0, 6, 0, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 150, 5, 16, 0, 3, 0, 0, 0, 32, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 85, 0, 0, 8, 130, 0, 16, 0, 1, 0, 0, 0, 26, 144, 144, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 60, 0, 0, 7, 114, 0, 16, 0, 2, 0, 0, 0, 70, 3, 16, 0, 2, 0, 0, 0, 70, 3, 16, 0, 4, 0, 0, 0, 60, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 85, 0, 0, 8, 130, 0, 16, 0, 2, 0, 0, 0, 10, 144, 144, 0, 26, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 55, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 9, 242, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 36, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 167, 0, 0, 9, 242, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 30, 0, 0, 8, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 128, 65, 0, 0, 0, 4, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 79, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 55, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 2, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 50, 0, 16, 0, 2, 0, 0, 0, 70, 0, 16, 0, 5, 0, 0, 0, 70, 0, 16, 0, 5, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 34, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 8, 242, 0, 16, 0, 6, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 0, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 30, 0, 0, 8, 242, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 128, 65, 0, 0, 0, 4, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 194, 0, 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, 5, 0, 0, 0, 6, 4, 16, 0, 7, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 33, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 33, 0, 0, 7, 66, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 60, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 34, 0, 0, 7, 66, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 43, 0, 0, 5, 82, 0, 16, 0, 2, 0, 0, 0, 6, 2, 16, 0, 2, 0, 0, 0, 56, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 253, 255, 125, 66, 14, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 28, 0, 0, 5, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 7, 162, 0, 16, 0, 3, 0, 0, 0, 6, 4, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 30, 0, 0, 10, 50, 0, 16, 0, 6, 0, 0, 0, 214, 5, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 11, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 78, 0, 0, 11, 0, 208, 0, 0, 50, 0, 16, 0, 6, 0, 0, 0, 70, 0, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79, 0, 0, 10, 50, 0, 16, 0, 7, 0, 0, 0, 214, 5, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 12, 50, 0, 16, 0, 6, 0, 0, 0, 70, 0, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 0, 16, 0, 6, 0, 0, 0, 55, 0, 0, 11, 18, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 10, 144, 208, 0, 64, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 55, 0, 0, 9, 34, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 18, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 33, 0, 0, 10, 194, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 1, 16, 0, 2, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 34, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 43, 0, 0, 5, 50, 0, 16, 0, 2, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 56, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 253, 255, 125, 66, 14, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 28, 0, 0, 5, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 55, 0, 0, 11, 18, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 10, 144, 208, 0, 64, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 55, 0, 0, 9, 18, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 55, 0, 0, 9, 50, 0, 16, 0, 2, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 70, 0, 16, 0, 7, 0, 0, 0, 22, 5, 16, 0, 7, 0, 0, 0, 18, 0, 0, 1, 38, 0, 0, 8, 0, 208, 0, 0, 194, 0, 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, 5, 0, 0, 0, 6, 4, 16, 0, 5, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 167, 0, 0, 8, 242, 0, 16, 0, 6, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 0, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 30, 0, 0, 8, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 128, 65, 0, 0, 0, 4, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 98, 0, 16, 0, 3, 0, 0, 0, 6, 1, 16, 0, 4, 0, 0, 0, 6, 1, 16, 0, 5, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 33, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 33, 0, 0, 7, 34, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 60, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 34, 0, 0, 7, 34, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 43, 0, 0, 5, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 56, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 253, 255, 125, 66, 43, 0, 0, 5, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 14, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 28, 0, 0, 5, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 78, 0, 0, 8, 0, 208, 0, 0, 18, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 68, 0, 0, 0, 79, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 55, 0, 0, 9, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 55, 0, 0, 11, 130, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 10, 144, 208, 0, 64, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 55, 0, 0, 9, 18, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 34, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, 168, 0, 0, 8, 50, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 16, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 21, 0, 0, 1, 31, 0, 0, 3, 42, 0, 16, 0, 0, 0, 0, 0, 31, 0, 0, 3, 58, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 128, 255, 255, 255, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 167, 0, 0, 9, 114, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 68, 0, 0, 0, 70, 242, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 25, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 17, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 3, 0, 0, 0, 70, 2, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 224, 1, 0, 0, 0, 0, 0, 224, 0, 0, 224, 1, 0, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 167, 0, 0, 9, 114, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 84, 0, 0, 0, 70, 242, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 5, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 21, 0, 0, 0, 1, 0, 0, 10, 146, 0, 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 10, 146, 0, 16, 0, 3, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 167, 0, 0, 9, 114, 0, 16, 0, 5, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 68, 0, 0, 0, 70, 242, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 6, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 6, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 25, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 224, 1, 0, 224, 1, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 167, 0, 0, 9, 114, 0, 16, 0, 7, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 84, 0, 0, 0, 70, 242, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 1, 0, 0, 10, 146, 0, 16, 0, 4, 0, 0, 0, 6, 4, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 167, 0, 0, 9, 114, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 68, 0, 0, 0, 70, 242, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 9, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 1, 64, 0, 0, 17, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 224, 1, 0, 224, 1, 0, 224, 1, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 9, 0, 0, 0, 167, 0, 0, 9, 114, 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 84, 0, 0, 0, 70, 242, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 11, 0, 0, 0, 10, 0, 16, 0, 10, 0, 0, 0, 1, 64, 0, 0, 21, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 11, 0, 0, 0, 26, 0, 16, 0, 10, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 11, 0, 0, 0, 42, 0, 16, 0, 10, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 30, 0, 0, 30, 0, 0, 30, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 11, 0, 0, 0, 60, 0, 0, 7, 18, 0, 16, 0, 12, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 167, 0, 0, 9, 50, 0, 16, 0, 13, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 68, 0, 0, 0, 70, 240, 17, 0, 0, 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 13, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 30, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 11, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 12, 0, 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 76, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 30, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 11, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 13, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 32, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 84, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 64, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 68, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 128, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 84, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 1, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 68, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 14, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 2, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 84, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 4, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 19, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 84, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 26, 144, 208, 0, 128, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 66, 0, 16, 0, 12, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 48, 0, 0, 1, 79, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 3, 0, 4, 3, 26, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 18, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 12, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 12, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 22, 0, 0, 1, 79, 0, 0, 9, 66, 0, 16, 0, 0, 0, 0, 0, 26, 144, 208, 0, 128, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 29, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 12, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 12, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 54, 0, 0, 5, 34, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 18, 0, 0, 1, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 54, 0, 0, 5, 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 48, 0, 0, 1, 79, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, 26, 144, 208, 0, 128, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 3, 0, 4, 3, 58, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 242, 255, 255, 255, 41, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 60, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 22, 0, 0, 1, 21, 0, 0, 1, 54, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 48, 0, 0, 1, 79, 0, 0, 9, 18, 0, 16, 0, 2, 0, 0, 0, 42, 144, 208, 0, 128, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 3, 0, 4, 3, 10, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 241, 255, 255, 255, 41, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 22, 0, 0, 1, 54, 0, 0, 5, 130, 0, 16, 0, 12, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 48, 0, 0, 1, 80, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 3, 0, 4, 3, 26, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 240, 255, 255, 255, 41, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 60, 0, 0, 7, 130, 0, 16, 0, 12, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 12, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 22, 0, 0, 1, 18, 0, 0, 1, 32, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 167, 0, 0, 9, 114, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 68, 0, 0, 0, 70, 242, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 22, 0, 0, 0, 1, 0, 0, 10, 82, 0, 16, 0, 2, 0, 0, 0, 6, 1, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 167, 0, 0, 9, 114, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 84, 0, 0, 0, 70, 242, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 28, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 3, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 192, 15, 0, 192, 15, 0, 0, 0, 0, 0, 192, 0, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 167, 0, 0, 9, 114, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 68, 0, 0, 0, 70, 242, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 5, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 18, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 240, 3, 0, 240, 3, 0, 240, 3, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 167, 0, 0, 9, 114, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 84, 0, 0, 0, 70, 242, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 6, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 24, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 6, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 252, 0, 0, 252, 0, 0, 252, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 18, 0, 16, 0, 12, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 63, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 12, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 92, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 68, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 1, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 68, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 2, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 18, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 32, 0, 0, 9, 34, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 26, 144, 208, 0, 128, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 15, 0, 0, 0, 14, 0, 0, 0, 13, 0, 0, 0, 12, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 30, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 27, 0, 0, 0, 60, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 24, 0, 0, 0, 60, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 21, 0, 0, 0, 60, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 11, 0, 0, 0, 10, 0, 0, 0, 9, 0, 0, 0, 8, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 18, 0, 0, 0, 60, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 60, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 60, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 60, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 60, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 60, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 60, 0, 0, 7, 130, 0, 16, 0, 12, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 29, 0, 0, 0, 30, 0, 0, 10, 194, 0, 16, 0, 2, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 26, 0, 0, 0, 60, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 60, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 20, 0, 0, 0, 60, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 60, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 12, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 18, 0, 0, 1, 32, 0, 0, 9, 34, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 26, 144, 208, 0, 128, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 15, 0, 0, 0, 14, 0, 0, 0, 13, 0, 0, 0, 12, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 29, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 26, 0, 0, 0, 60, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 60, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 20, 0, 0, 0, 60, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 11, 0, 0, 0, 10, 0, 0, 0, 9, 0, 0, 0, 8, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 17, 0, 0, 0, 60, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 14, 0, 0, 0, 60, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 60, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 60, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 60, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 60, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 130, 0, 16, 0, 12, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 31, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 28, 0, 0, 0, 60, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 10, 194, 0, 16, 0, 2, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 25, 0, 0, 0, 60, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 60, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 20, 0, 0, 0, 60, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 60, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 12, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 18, 0, 0, 1, 32, 0, 0, 9, 34, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 26, 144, 208, 0, 128, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 15, 0, 0, 0, 14, 0, 0, 0, 13, 0, 0, 0, 12, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 29, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 26, 0, 0, 0, 60, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 60, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 20, 0, 0, 0, 60, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 11, 0, 0, 0, 10, 0, 0, 0, 9, 0, 0, 0, 8, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 17, 0, 0, 0, 60, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 14, 0, 0, 0, 60, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 60, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 60, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 60, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 60, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 60, 0, 0, 7, 130, 0, 16, 0, 12, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 29, 0, 0, 0, 30, 0, 0, 10, 194, 0, 16, 0, 2, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 26, 0, 0, 0, 60, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 60, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 20, 0, 0, 0, 60, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 60, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 12, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 18, 0, 0, 1, 30, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 15, 0, 0, 0, 14, 0, 0, 0, 13, 0, 0, 0, 12, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 29, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 26, 0, 0, 0, 60, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 60, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 20, 0, 0, 0, 60, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 11, 0, 0, 0, 10, 0, 0, 0, 9, 0, 0, 0, 8, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 17, 0, 0, 0, 60, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 14, 0, 0, 0, 60, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 60, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 60, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 60, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 60, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 60, 0, 0, 7, 130, 0, 16, 0, 12, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 29, 0, 0, 0, 30, 0, 0, 10, 194, 0, 16, 0, 2, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 26, 0, 0, 0, 60, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 60, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 20, 0, 0, 0, 60, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 60, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 12, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 21, 0, 0, 1, 21, 0, 0, 1, 18, 0, 0, 1, 32, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 254, 255, 255, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 167, 0, 0, 9, 114, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 68, 0, 0, 0, 70, 242, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 3, 0, 0, 0, 70, 2, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 62, 0, 0, 128, 15, 0, 0, 224, 3, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 167, 0, 0, 9, 114, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 84, 0, 0, 0, 70, 242, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 5, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 192, 7, 0, 0, 240, 1, 0, 0, 124, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 30, 0, 0, 10, 146, 0, 16, 0, 2, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 167, 0, 0, 9, 114, 0, 16, 0, 6, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 68, 0, 0, 0, 70, 242, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 14, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 248, 0, 0, 0, 62, 0, 0, 128, 15, 0, 0, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 167, 0, 0, 9, 114, 0, 16, 0, 8, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 84, 0, 0, 0, 70, 242, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 9, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 1, 64, 0, 0, 21, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 1, 64, 0, 0, 19, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 1, 64, 0, 0, 17, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 31, 0, 0, 192, 7, 0, 0, 240, 1, 0, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 9, 0, 0, 0, 167, 0, 0, 9, 114, 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 68, 0, 0, 0, 70, 242, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 11, 0, 0, 0, 10, 0, 16, 0, 10, 0, 0, 0, 1, 64, 0, 0, 26, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 11, 0, 0, 0, 26, 0, 16, 0, 10, 0, 0, 0, 1, 64, 0, 0, 24, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 11, 0, 0, 0, 42, 0, 16, 0, 10, 0, 0, 0, 1, 64, 0, 0, 22, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 224, 0, 0, 0, 248, 0, 0, 0, 62, 0, 0, 0, 0, 60, 0, 0, 7, 18, 0, 16, 0, 12, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 11, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 13, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 68, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 13, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 167, 0, 0, 9, 114, 0, 16, 0, 13, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 84, 0, 0, 0, 70, 242, 17, 0, 0, 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 14, 0, 0, 0, 10, 0, 16, 0, 13, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 34, 0, 16, 0, 14, 0, 0, 0, 26, 0, 16, 0, 13, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 0, 0, 10, 146, 0, 16, 0, 3, 0, 0, 0, 6, 4, 16, 0, 14, 0, 0, 0, 2, 64, 0, 0, 124, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 12, 0, 0, 0, 26, 0, 16, 0, 11, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 11, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 13, 0, 0, 0, 1, 64, 0, 0, 27, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 192, 30, 0, 0, 7, 66, 0, 16, 0, 12, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 92, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 48, 0, 0, 1, 79, 0, 0, 9, 34, 0, 16, 0, 2, 0, 0, 0, 26, 144, 208, 0, 128, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 3, 0, 4, 3, 26, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 60, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 22, 0, 0, 1, 54, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 34, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 48, 0, 0, 1, 79, 0, 0, 9, 66, 0, 16, 0, 2, 0, 0, 0, 42, 144, 208, 0, 128, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 3, 0, 4, 3, 42, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 22, 0, 0, 1, 54, 0, 0, 5, 130, 0, 16, 0, 12, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 48, 0, 0, 1, 80, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 3, 0, 4, 3, 10, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 60, 0, 0, 7, 130, 0, 16, 0, 12, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 12, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 22, 0, 0, 1, 18, 0, 0, 1, 32, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 167, 0, 0, 9, 114, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 68, 0, 0, 0, 70, 242, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 3, 0, 0, 0, 70, 2, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 252, 1, 0, 192, 31, 0, 0, 252, 1, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 167, 0, 0, 9, 114, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 84, 0, 0, 0, 70, 242, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 5, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 0, 0, 254, 0, 0, 224, 15, 0, 0, 254, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 167, 0, 0, 9, 114, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 68, 0, 0, 0, 70, 242, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 19, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 127, 0, 0, 240, 7, 0, 0, 127, 0, 0, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 167, 0, 0, 9, 114, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 84, 0, 0, 0, 70, 242, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 9, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 1, 64, 0, 0, 30, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 1, 64, 0, 0, 26, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 1, 64, 0, 0, 22, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 128, 0, 0, 0, 248, 0, 0, 128, 63, 0, 0, 0, 0, 60, 0, 0, 7, 18, 0, 16, 0, 12, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 9, 0, 0, 0, 167, 0, 0, 9, 50, 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 84, 0, 0, 0, 70, 240, 17, 0, 0, 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 11, 0, 0, 0, 10, 0, 16, 0, 10, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 85, 0, 0, 7, 34, 0, 16, 0, 11, 0, 0, 0, 26, 0, 16, 0, 10, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 1, 0, 0, 10, 146, 0, 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 2, 0, 0, 0, 150, 5, 16, 0, 3, 0, 0, 0, 198, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 2, 0, 0, 0, 150, 5, 16, 0, 5, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 2, 0, 0, 0, 150, 5, 16, 0, 7, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 2, 0, 0, 0, 150, 5, 16, 0, 9, 0, 0, 0, 70, 0, 16, 0, 2, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 68, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 30, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 64, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 84, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 31, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 12, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 68, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 84, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 34, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 48, 0, 0, 1, 79, 0, 0, 9, 66, 0, 16, 0, 2, 0, 0, 0, 26, 144, 208, 0, 128, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 3, 0, 4, 3, 42, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 60, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 22, 0, 0, 1, 54, 0, 0, 5, 130, 0, 16, 0, 12, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 48, 0, 0, 1, 80, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 3, 0, 4, 3, 42, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 60, 0, 0, 7, 130, 0, 16, 0, 12, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 12, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 22, 0, 0, 1, 54, 0, 0, 5, 34, 0, 16, 0, 12, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 18, 0, 0, 1, 32, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 96, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 9, 242, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 68, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 25, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 31, 0, 0, 0, 0, 124, 0, 0, 0, 0, 240, 192, 15, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 167, 0, 0, 9, 242, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 84, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 82, 0, 16, 0, 4, 0, 0, 0, 6, 3, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 20, 0, 0, 0, 1, 0, 0, 10, 178, 0, 16, 0, 3, 0, 0, 0, 70, 8, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 224, 3, 0, 0, 0, 128, 15, 0, 0, 0, 0, 0, 240, 3, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 12, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 76, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 62, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 167, 0, 0, 9, 50, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 70, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 18, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 17, 0, 0, 0, 1, 0, 0, 10, 146, 0, 16, 0, 1, 0, 0, 0, 6, 4, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 167, 0, 0, 9, 50, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 70, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 50, 0, 16, 0, 3, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 19, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 167, 0, 0, 9, 50, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 70, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 21, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 22, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 9, 50, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 70, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 25, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 9, 50, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 70, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 25, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 28, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 8, 0, 0, 0, 167, 0, 0, 9, 50, 0, 16, 0, 5, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 70, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 27, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 31, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 9, 50, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 70, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 29, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 9, 50, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 70, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 31, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 60, 0, 0, 7, 34, 0, 16, 0, 12, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 167, 0, 0, 9, 50, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 70, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 167, 0, 0, 9, 50, 0, 16, 0, 6, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 70, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 9, 50, 0, 16, 0, 6, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 70, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 14, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 9, 50, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 70, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 17, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 9, 50, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 70, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 20, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 10, 226, 0, 16, 0, 5, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 14, 0, 0, 0, 15, 0, 0, 0, 167, 0, 0, 9, 50, 0, 16, 0, 6, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 70, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 9, 50, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 70, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 26, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 9, 50, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 70, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 29, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 12, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 20, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 60, 0, 0, 7, 130, 0, 16, 0, 12, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 18, 0, 0, 1, 32, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 167, 0, 0, 9, 242, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 68, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 21, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 18, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 127, 0, 0, 0, 0, 192, 31, 240, 7, 0, 0, 0, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 167, 0, 0, 9, 242, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 84, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 14, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 28, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 26, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 3, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 128, 63, 0, 0, 0, 0, 224, 0, 248, 3, 0, 0, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 60, 0, 0, 7, 18, 0, 16, 0, 12, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 88, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 60, 0, 0, 7, 34, 0, 16, 0, 12, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 96, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 167, 0, 0, 9, 50, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 70, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 167, 0, 0, 9, 50, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 70, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 9, 50, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 70, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 9, 50, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 70, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 9, 50, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 70, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 8, 0, 0, 0, 167, 0, 0, 9, 50, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 70, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 10, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 9, 50, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 70, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 9, 50, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 70, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 14, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 9, 50, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 70, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 17, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 167, 0, 0, 9, 50, 0, 16, 0, 5, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 70, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 19, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 18, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 9, 50, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 70, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 21, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 20, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 9, 50, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 70, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 22, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 9, 50, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 70, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 25, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 24, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 5, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 13, 0, 0, 0, 14, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 167, 0, 0, 9, 50, 0, 16, 0, 6, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 70, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 27, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 26, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 9, 50, 0, 16, 0, 6, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 70, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 29, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 28, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 9, 50, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 70, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 31, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 30, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 12, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 60, 0, 0, 7, 130, 0, 16, 0, 12, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 18, 0, 0, 1, 32, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 167, 0, 0, 9, 242, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 68, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 20, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 128, 63, 0, 0, 0, 0, 224, 15, 248, 3, 0, 0, 0, 0, 254, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 64, 0, 0, 0, 167, 0, 0, 9, 242, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 84, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 13, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 27, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 23, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 192, 31, 0, 0, 0, 0, 240, 0, 252, 1, 0, 0, 0, 0, 127, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 12, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 167, 0, 0, 9, 50, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 84, 0, 0, 0, 70, 240, 17, 0, 0, 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 68, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 31, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 12, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 8, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 20, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 24, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 28, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 12, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, 3, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 10, 210, 0, 16, 0, 1, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 15, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 20, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 24, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 28, 0, 0, 0, 60, 0, 0, 7, 130, 0, 16, 0, 12, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 18, 0, 0, 1, 41, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 8, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 128, 0, 0, 0, 167, 0, 0, 9, 242, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 68, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 11, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 19, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 1, 0, 0, 10, 210, 0, 16, 0, 1, 0, 0, 0, 6, 9, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 0, 192, 7, 0, 0, 0, 0, 0, 0, 0, 192, 7, 0, 124, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 9, 242, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 84, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 24, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 12, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 0, 0, 248, 0, 128, 15, 0, 0, 0, 0, 0, 248, 0, 128, 15, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 167, 0, 0, 9, 242, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 68, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 6, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 21, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 6, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 9, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 17, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 31, 0, 240, 1, 0, 0, 0, 240, 1, 0, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 167, 0, 0, 9, 242, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 84, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 8, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 26, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 14, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 22, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 224, 0, 0, 62, 0, 224, 3, 0, 0, 0, 0, 0, 62, 60, 0, 0, 7, 18, 0, 16, 0, 12, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 84, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 10, 0, 0, 0, 10, 0, 16, 0, 9, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 85, 0, 0, 7, 34, 0, 16, 0, 10, 0, 0, 0, 10, 0, 16, 0, 9, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 10, 146, 0, 16, 0, 6, 0, 0, 0, 6, 4, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 124, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 12, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 31, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 68, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 28, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 64, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 84, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 29, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 128, 30, 0, 0, 7, 66, 0, 16, 0, 12, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 68, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 85, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 48, 0, 0, 1, 79, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 26, 144, 208, 0, 128, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 3, 0, 4, 3, 42, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 60, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 22, 0, 0, 1, 54, 0, 0, 5, 130, 0, 16, 0, 12, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 48, 0, 0, 1, 80, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 3, 0, 4, 3, 26, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 60, 0, 0, 7, 130, 0, 16, 0, 12, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 12, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 22, 0, 0, 1, 21, 0, 0, 1, 21, 0, 0, 1, 21, 0, 0, 1, 21, 0, 0, 1, 21, 0, 0, 1, 21, 0, 0, 1, 21, 0, 0, 1, 168, 0, 0, 9, 242, 224, 17, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 21, 0, 0, 1, 62, 0, 0, 1 }; ================================================ FILE: 3rdParty/DirectXTex/DirectXTex/Shaders/Compiled/BC7Encode_TryMode02CS.inc ================================================ #if 0 // // Generated by Microsoft (R) D3D Shader Disassembler // // /// // Input signature: // // Name Index Mask Register SysValue Format Used // -------------------- ----- ------ -------- -------- ------- ------ // no Input // // Output signature: // // Name Index Mask Register SysValue Format Used // -------------------- ----- ------ -------- -------- ------- ------ // no Output cs_4_0 dcl_globalFlags refactoringAllowed dcl_immediateConstantBuffer { { -0.000000, 15, 0, 0}, { 65981199646559862000000000.000000, 15, 0, 0}, { 15358528172589056.000000, 15, 0, 0}, { 3584194248704.000000, 15, 0, 1}, { -0.000000, 15, 0, 1}, { -0.000000, 15, 0, 1}, { 14680365989888.000000, 15, 0, 1}, { 15362462362632192.000000, 15, 0, 2}, { -0.000000, 15, 0, 2}, { -0.000000, 15, 0, 2}, { -0.000000, 15, 0, 2}, { -0.000000, 15, 0, 2}, { -0.000000, 15, 0, 3}, { -0.000000, 15, 0, 3}, { -0.000000, 15, 0, 3}, { 0.000000, 15, 0, 3}, { -0.000000, 15, 0, 4}, { 0.000000, 2, 0, 4}, { -0.000000, 8, 0, 4}, { 22076467445760.000000, 2, 0, 4}, { -0.000000, 2, 0, 5}, { 70798013459086900000000000.000000, 8, 0, 5}, { -0.000000, 8, 0, 5}, { 0.000000, 15, 0, 5}, { 0x0050a4a4, 2, 0, 6}, { -0.000000, 8, 0, 6}, { 0.000000, 2, 0, 6}, { 17610885206241624000000000.000000, 2, 0, 6}, { -0.000000, 8, 0, 6}, { -0.000000, 8, 0, 7}, { 22097854464.000000, 2, 0, 7}, { 65888818352238725000000000.000000, 2, 0, 7}, { -0.000000, 15, 0, 7}, { 19411582976.000000, 15, 0, 8}, { -0.000000, 6, 0, 8}, { 0.000000, 8, 0, 8}, { 0.000000, 2, 0, 8}, { 0.000000, 8, 0, 9}, { 0.000000, 15, 0, 9}, { 22151331840.000000, 15, 0, 9}, { 9304358912.000000, 2, 0, 9}, { -0.000000, 8, 0, 10}, { 271536072765004600000000.000000, 2, 0, 10}, { -0.000000, 2, 0, 10}, { 21517107200.000000, 2, 0, 10}, { 12724757752857623000000000.000000, 15, 0, 10}, { 1365.320801, 15, 0, 11}, { 272006464738884190000000.000000, 6, 0, 11}, { -0.000000, 6, 0, 11}, { 5783798415360.000000, 2, 0, 11}, { -0.000000, 6, 0, 12}, { -0.000000, 8, 0, 12}, { -0.000000, 15, 0, 12}, { -0.000000, 15, 0, 12}, { -0.000000, 2, 0, 13}, { -0.000000, 2, 0, 13}, { -0.000000, 15, 0, 13}, { -0.000000, 15, 0, 13}, { -0.000000, 15, 0, 14}, { -0.000000, 15, 0, 14}, { 4.007874, 15, 0, 14}, { -0.000000, 2, 0, 14}, { -0.000000, 2, 0, 15}, { 0.000000, 15, 0, 15}, { 0, 3, 15, 0}, { 4, 3, 8, 0}, { 9, 15, 8, 0}, { 13, 15, 3, 0}, { 17, 8, 15, 0}, { 21, 3, 15, 1}, { 26, 15, 3, 1}, { 30, 15, 8, 1}, { 34, 8, 15, 1}, { 38, 8, 15, 1}, { 43, 6, 15, 1}, { 47, 6, 15, 1}, { 51, 6, 15, 1}, { 55, 5, 15, 1}, { 60, 3, 15, 2}, { 64, 3, 8, 2}, { 0, 3, 15, 2}, { 9, 3, 8, 2}, { 18, 8, 15, 2}, { 27, 15, 3, 2}, { 37, 3, 15, 2}, { 46, 3, 8, 2}, { 55, 6, 15, 2}, { 64, 10, 8, 3}, { 0, 5, 3, 3}, { 0, 8, 15, 3}, { 0, 8, 6, 3}, { 0, 6, 10, 3}, { 0, 8, 15, 3}, { 0, 5, 15, 3}, { 0, 15, 10, 3}, { 0, 15, 8, 3}, { 0, 8, 15, 3}, { 21, 15, 3, 4}, { 43, 3, 15, 4}, { 64, 5, 10, 4}, { 0, 6, 10, 4}, { 0, 10, 8, 4}, { 0, 8, 9, 4}, { 0, 15, 10, 4}, { 0, 15, 6, 4}, { 0, 3, 15, 4}, { 0, 15, 8, 5}, { 0, 5, 15, 5}, { 0, 15, 3, 5}, { 0, 15, 6, 5}, { 0, 15, 6, 5}, { 0, 15, 8, 5}, { 0, 3, 15, 5}, { 0, 15, 3, 5}, { 0, 5, 15, 5}, { 0, 5, 15, 6}, { 0, 5, 15, 6}, { 0, 8, 15, 6}, { 0, 5, 15, 6}, { 0, 10, 15, 6}, { 0, 5, 15, 6}, { 0, 10, 15, 6}, { 0, 8, 15, 6}, { 0, 13, 15, 6}, { 0, 15, 3, 7}, { 0, 12, 15, 7}, { 0, 3, 15, 7}, { 0, 3, 8, 7}, { 0, 0, 0, 0}, { 0, 0, 0, 0}, { 0, 0, 0, 0}, { 0, 0, 0, 0}, { 0, 0, 0, 0}, { 0, 0, 0, 0}, { 0, 0, 0, 0}, { 0, 0, 0, 0}, { 0, 0, 0, 0}, { 0, 0, 0, 0}, { 0, 0, 0, 0}, { 0, 0, 0, 1}, { 0, 0, 0, 1}, { 0, 0, 0, 1}, { 0, 0, 0, 1}, { 0, 0, 0, 1}, { 0, 0, 0, 1}, { 0, 0, 0, 1}, { 0, 0, 0, 1}, { 0, 0, 0, 1}, { 0, 0, 0, 1}, { 0, 0, 0, 1}, { 0, 0, 0, 1}, { 0, 0, 0, 1}, { 0, 0, 0, 1}, { 0, 0, 0, 1}, { 0, 0, 0, 1}, { 0, 0, 0, 1}, { 0, 0, 0, 1}, { 0, 0, 0, 1}, { 0, 0, 0, 1}, { 0, 0, 0, 1}, { 0, 0, 0, 1}, { 0, 0, 0, 2}, { 0, 0, 0, 2}, { 0, 0, 0, 2}, { 0, 0, 0, 2}, { 0, 0, 0, 2}, { 0, 0, 0, 2}, { 0, 0, 0, 2}, { 0, 0, 0, 2}, { 0, 0, 0, 2}, { 0, 0, 0, 2}, { 0, 0, 0, 2}, { 0, 0, 0, 2}, { 0, 0, 0, 2}, { 0, 0, 0, 2}, { 0, 0, 0, 2}, { 0, 0, 0, 2}, { 0, 0, 0, 2}, { 0, 0, 0, 2}, { 0, 0, 0, 2}, { 0, 0, 0, 2}, { 0, 0, 0, 2}, { 0, 0, 0, 3}, { 0, 0, 0, 3}, { 0, 0, 0, 3}, { 0, 0, 0, 3}, { 0, 0, 0, 3}, { 0, 0, 0, 3}, { 0, 0, 0, 3}, { 0, 0, 0, 3}, { 0, 0, 0, 3}, { 0, 0, 0, 3} } dcl_constantbuffer cb0[2], immediateIndexed dcl_resource_texture2d (float,float,float,float) t0 dcl_resource_structured t1, 16 dcl_uav_structured u0, 16 dcl_input vThreadIDInGroupFlattened dcl_input vThreadGroupID.x dcl_temps 29 dcl_indexableTemp x0[12], 4 dcl_indexableTemp x1[3], 4 dcl_indexableTemp x2[3], 4 dcl_indexableTemp x3[3], 4 dcl_tgsm_structured g0, 100, 64 dcl_thread_group 64, 1, 1 iadd r0.x, vThreadGroupID.x, cb0[1].x ult r1.xyzw, vThreadIDInGroupFlattened.xxxx, l(16, 32, 8, 4) if_nz r1.x udiv r0.y, null, r0.x, cb0[0].y imad r0.z, -r0.y, cb0[0].y, r0.x ishl r0.z, r0.z, l(2) ishl r0.y, r0.y, l(2) and r0.w, vThreadIDInGroupFlattened.x, l(3) iadd r2.x, r0.w, r0.z ushr r0.z, vThreadIDInGroupFlattened.x, l(2) iadd r2.y, r0.z, r0.y mov r2.zw, l(0,0,0,0) ld r2.xyzw, r2.xyzw, t0.xyzw mul r2.xyzw, r2.xyzw, l(255.000000, 255.000000, 255.000000, 255.000000) ftou r2.xyzw, r2.xyzw umin r2.xyzw, r2.xyzw, l(255, 255, 255, 255) store_structured g0.xyzw, vThreadIDInGroupFlattened.x, l(0), r2.xyzw endif sync_g_t store_structured g0.x, vThreadIDInGroupFlattened.x, l(16), l(-1) movc r0.y, cb0[0].w, l(64), l(16) ult r0.y, vThreadIDInGroupFlattened.x, r0.y if_nz r0.y iadd r0.y, vThreadIDInGroupFlattened.x, l(64) mov x0[0].x, l(-1) mov x0[1].x, l(-1) mov x0[2].x, l(-1) mov x0[0].y, l(0) mov x0[1].y, l(0) mov x0[2].y, l(0) mov x0[4].x, l(-1) mov x0[5].x, l(-1) mov x0[6].x, l(-1) mov x0[4].y, l(0) mov x0[5].y, l(0) mov x0[6].y, l(0) mov x0[8].x, l(-1) mov x0[9].x, l(-1) mov x0[10].x, l(-1) mov x0[8].y, l(0) mov x0[9].y, l(0) mov x0[10].y, l(0) iadd r0.z, r0.y, l(-64) mov r0.w, l(0) loop uge r2.x, r0.w, l(16) breakc_nz r2.x ld_structured r2.xyz, r0.w, l(0), g0.xyzx ishl r2.w, r0.w, l(1) ushr r2.w, icb[r0.z + 0].x, r2.w and r2.w, r2.w, l(3) ieq r3.x, r2.w, l(2) if_nz r3.x mov r3.x, x0[8].x mov r3.y, x0[9].x mov r3.z, x0[10].x umin r3.xyz, r2.xyzx, r3.xyzx mov x0[8].x, r3.x mov x0[9].x, r3.y mov x0[10].x, r3.z mov r3.x, x0[8].y mov r3.y, x0[9].y mov r3.z, x0[10].y umax r3.xyz, r2.xyzx, r3.xyzx mov x0[8].y, r3.x mov x0[9].y, r3.y mov x0[10].y, r3.z else ieq r2.w, r2.w, l(1) if_nz r2.w mov r3.x, x0[4].x mov r3.y, x0[5].x mov r3.z, x0[6].x umin r3.xyz, r2.xyzx, r3.xyzx mov x0[4].x, r3.x mov x0[5].x, r3.y mov x0[6].x, r3.z mov r3.x, x0[4].y mov r3.y, x0[5].y mov r3.z, x0[6].y umax r3.xyz, r2.xyzx, r3.xyzx mov x0[4].y, r3.x mov x0[5].y, r3.y mov x0[6].y, r3.z else mov r3.x, x0[0].x mov r3.y, x0[1].x mov r3.z, x0[2].x umin r3.xyz, r2.xyzx, r3.xyzx mov x0[0].x, r3.x mov x0[1].x, r3.y mov x0[2].x, r3.z mov r3.x, x0[0].y mov r3.y, x0[1].y mov r3.z, x0[2].y umax r2.xyz, r2.xyzx, r3.xyzx mov x0[0].y, r2.x mov x0[1].y, r2.y mov x0[2].y, r2.z endif endif iadd r0.w, r0.w, l(1) endloop mov r2.x, x0[0].x mov r2.y, x0[1].x mov r2.z, x0[2].x mov r3.x, x0[0].y mov r3.y, x0[1].y mov r3.z, x0[2].y mov r4.x, x0[4].x mov r4.y, x0[5].x mov r4.z, x0[6].x mov r5.x, x0[4].y mov r5.y, x0[5].y mov r5.z, x0[6].y mov r6.x, x0[8].x mov r6.y, x0[9].x mov r6.z, x0[10].x mov r7.x, x0[8].y mov r7.y, x0[9].y mov r7.z, x0[10].y movc r0.w, cb0[0].w, l(1), l(64) iadd r2.xyz, r2.xyzx, l(4, 4, 4, 0) umin r2.xyz, r2.xyzx, l(255, 255, 255, 0) ushr r8.xyz, r2.xyzx, l(3) and r8.xyz, r8.xyzx, l(30, 30, 30, 0) iadd r3.xyz, r3.xyzx, l(4, 4, 4, 0) umin r3.xyz, r3.xyzx, l(255, 255, 255, 0) ushr r9.xyz, r3.xyzx, l(3) and r9.xyz, r9.xyzx, l(30, 30, 30, 0) and r10.xyz, r2.xyzx, l(248, 248, 248, 0) ushr r2.xyz, r2.xyzx, l(5) iadd r2.xyz, r2.xyzx, r10.xyzx and r10.xyz, r3.xyzx, l(248, 248, 248, 0) ushr r3.xyz, r3.xyzx, l(5) iadd r3.xyz, r3.xyzx, r10.xyzx iadd r4.xyz, r4.xyzx, l(4, 4, 4, 0) umin r4.xyz, r4.xyzx, l(255, 255, 255, 0) ushr r10.xyz, r4.xyzx, l(3) and r10.xyz, r10.xyzx, l(30, 30, 30, 0) iadd r5.xyz, r5.xyzx, l(4, 4, 4, 0) umin r5.xyz, r5.xyzx, l(255, 255, 255, 0) ushr r11.xyz, r5.xyzx, l(3) and r11.xyz, r11.xyzx, l(30, 30, 30, 0) and r12.xyz, r4.xyzx, l(248, 248, 248, 0) ushr r4.xyz, r4.xyzx, l(5) iadd r4.xyz, r4.xyzx, r12.xyzx and r12.xyz, r5.xyzx, l(248, 248, 248, 0) ushr r5.xyz, r5.xyzx, l(5) iadd r5.xyz, r5.xyzx, r12.xyzx iadd r6.xyz, r6.xyzx, l(4, 4, 4, 0) umin r6.xyz, r6.xyzx, l(255, 255, 255, 0) ushr r12.xyz, r6.xyzx, l(3) and r12.xyz, r12.xyzx, l(30, 30, 30, 0) iadd r7.xyz, r7.xyzx, l(4, 4, 4, 0) umin r7.xyz, r7.xyzx, l(255, 255, 255, 0) ushr r13.xyz, r7.xyzx, l(3) and r13.xyz, r13.xyzx, l(30, 30, 30, 0) and r14.xyz, r6.xyzx, l(248, 248, 248, 0) ushr r6.xyz, r6.xyzx, l(5) iadd r6.xyz, r6.xyzx, r14.xyzx and r14.xyz, r7.xyzx, l(248, 248, 248, 0) ushr r7.xyz, r7.xyzx, l(5) iadd r7.xyz, r7.xyzx, r14.xyzx mov r2.w, r3.z mov r3.w, r2.y mov r4.w, r5.z mov r5.w, r4.y mov r6.w, r7.z mov r7.w, r6.y mov r14.y, l(255) mov r2.y, cb0[0].w mov r15.xy, l(0,-1,0,0) mov r16.x, l(0) loop uge r3.z, r16.x, r0.w breakc_nz r3.z ieq r3.z, r2.y, l(2) if_z r2.y ushr r16.y, r16.x, l(1) and r14.zw, r16.xxxy, l(0, 0, 1, 1) iadd r17.xyz, r8.xyzx, r14.zzzz ishl r17.xyz, r17.xyzx, l(3) ushr r18.xyz, r17.xyzx, l(5) iadd r17.xzw, r17.zzxy, r18.zzxy iadd r18.xyz, r9.xyzx, r14.wwww ishl r18.xyz, r18.xyzx, l(3) ushr r19.xyz, r18.xyzx, l(5) iadd r18.xyz, r18.yxzy, r19.yxzy mov r17.y, r18.z mov r18.w, r17.w mov r14.zw, r18.wwwx mov r18.x, r17.z else mov r17.xy, r2.zwzz mov r14.zw, r3.wwwy mov r18.x, r2.x mov r18.y, r3.x endif mov x0[3].xy, l(255,255,0,0) mov x0[2].xy, r17.xyxx mov x0[1].xy, r14.zwzz mov x0[0].xy, r18.xyxx if_z r2.y ushr r19.x, r16.x, l(2) ushr r19.y, r16.x, l(3) and r15.zw, r19.xxxy, l(0, 0, 1, 1) iadd r19.xyz, r10.xyzx, r15.zzzz ishl r19.xyz, r19.xyzx, l(3) ushr r20.xyz, r19.xyzx, l(5) iadd r19.xzw, r19.zzxy, r20.zzxy iadd r20.xyz, r11.xyzx, r15.wwww ishl r20.xyz, r20.xyzx, l(3) ushr r21.xyz, r20.xyzx, l(5) iadd r20.xyz, r20.yxzy, r21.yxzy mov r19.y, r20.z mov r20.w, r19.w mov r15.zw, r20.wwwx mov r20.x, r19.z else mov r19.xy, r4.zwzz mov r15.zw, r5.wwwy mov r20.x, r4.x mov r20.y, r5.x endif mov x0[7].xy, l(255,255,0,0) mov x0[6].xy, r19.xyxx mov x0[5].xy, r15.zwzz mov x0[4].xy, r20.xyxx if_z r2.y ushr r21.x, r16.x, l(4) ushr r21.y, r16.x, l(5) and r16.zw, r21.xxxy, l(0, 0, 1, 1) iadd r21.xyz, r12.xyzx, r16.zzzz ishl r21.xyz, r21.xyzx, l(3) ushr r22.xyz, r21.xyzx, l(5) iadd r21.xzw, r21.zzxy, r22.zzxy iadd r22.xyz, r13.xyzx, r16.wwww ishl r22.xyz, r22.xyzx, l(3) ushr r23.xyz, r22.xyzx, l(5) iadd r22.xyz, r22.yxzy, r23.yxzy mov r21.y, r22.z mov r22.w, r21.w mov r16.zw, r22.wwwx mov r22.x, r21.z else mov r21.xy, r6.zwzz mov r16.zw, r7.wwwy mov r22.x, r6.x mov r22.y, r7.x endif mov x0[11].xy, l(255,255,0,0) mov x0[10].xy, r21.xyxx mov x0[9].xy, r16.zwzz mov x0[8].xy, r22.xyxx ineg r23.x, r18.x ineg r23.y, r14.z ineg r23.z, r17.x mov r18.z, r14.w mov r18.w, r17.y iadd r17.xyz, r18.yzwy, r23.xyzx mov x1[0].xyz, r17.xyzx ineg r18.x, r20.x ineg r18.y, r15.z ineg r18.z, r19.x mov r20.z, r15.w mov r20.w, r19.y iadd r18.xyz, r18.xyzx, r20.yzwy mov x1[1].xyz, r18.xyzx ineg r19.x, r22.x ineg r19.y, r16.z ineg r19.z, r21.x mov r22.z, r16.w mov r22.w, r21.y iadd r19.xyz, r19.xyzx, r22.yzwy mov x1[2].xyz, r19.xyzx mov x1[2].w, l(0) mov x1[1].w, l(0) mov x1[0].w, l(0) imul null, r14.zw, r17.xxxy, r17.xxxy iadd r4.y, r14.w, r14.z imad r4.y, r17.z, r17.z, r4.y mov x2[0].x, r4.y imul null, r14.zw, r18.xxxy, r18.xxxy iadd r5.z, r14.w, r14.z imad r5.z, r18.z, r18.z, r5.z mov x2[1].x, r5.z imul null, r14.zw, r19.xxxy, r19.xxxy iadd r6.y, r14.w, r14.z imad r6.y, r19.z, r19.z, r6.y mov x2[2].x, r6.y mov x3[0].x, l(0) mov x3[1].x, icb[r0.y + 0].y mov x3[2].x, icb[r0.y + 0].z mov r7.z, l(0) loop uge r8.w, r7.z, l(3) breakc_nz r8.w mov r17.xyzw, x1[r7.z + 0].xyzw mov r8.w, x3[r7.z + 0].x ld_structured r18.xyzw, r8.w, l(0), g0.xyzw ishl r8.w, r7.z, l(2) mov r9.w, x0[r8.w + 0].x mov r10.w, x0[r8.w + 1].x mov r11.w, x0[r8.w + 2].x mov r12.w, x0[r8.w + 3].x ineg r19.x, r9.w ineg r19.y, r10.w ineg r19.z, r11.w ineg r19.w, r12.w iadd r18.xyzw, r18.xyzw, r19.xyzw imul null, r14.zw, r17.xxxy, r18.xxxy iadd r13.w, r14.w, r14.z imad r13.w, r17.z, r18.z, r13.w imad r13.w, r17.w, r18.w, r13.w mov r14.z, x2[r7.z + 0].x ilt r14.w, l(0), r14.z ilt r15.z, l(0), r13.w and r14.w, r14.w, r15.z itof r13.w, r13.w mul r13.w, r13.w, l(63.499989) ftou r13.w, r13.w ishl r14.z, r14.z, l(5) ult r13.w, r14.z, r13.w and r13.w, r13.w, r14.w if_nz r13.w ineg r17.xyzw, r17.xyzw mov x1[r7.z + 0].xyzw, r17.xyzw mov r13.w, x0[r8.w + 0].y mov r14.z, x0[r8.w + 1].y mov r14.w, x0[r8.w + 2].y mov r15.z, x0[r8.w + 3].y mov x0[r8.w + 0].x, r13.w mov x0[r8.w + 1].x, r14.z mov x0[r8.w + 2].x, r14.w mov x0[r8.w + 3].x, r15.z mov x0[r8.w + 0].y, r9.w mov x0[r8.w + 1].y, r10.w mov x0[r8.w + 2].y, r11.w mov x0[r8.w + 3].y, r12.w endif iadd r7.z, r7.z, l(1) endloop mov r17.xyzw, x1[2].xyzw mov r7.z, x0[8].x mov r8.w, x0[9].x mov r9.w, x0[10].x mov r10.w, x0[11].x ineg r18.x, r7.z ineg r18.y, r8.w ineg r18.z, r9.w ineg r18.w, r10.w ige r11.w, l(0), r6.y itof r12.w, r6.y movc r19.xyz, r3.zzzz, l(128,3,32,0), l(64,7,16,0) mov r20.xyzw, x1[1].xyzw mov r3.z, x0[4].x mov r13.w, x0[5].x mov r14.z, x0[6].x mov r14.w, x0[7].x ineg r21.x, r3.z ineg r21.y, r13.w ineg r21.zw, r14.zzzw ige r15.z, l(0), r5.z itof r15.w, r5.z mov r22.xyzw, x1[0].xyzw mov r16.z, x0[0].x mov r16.w, x0[1].x mov r19.w, x0[2].x mov r23.x, x0[3].x ineg r24.xy, r16.zwzz ineg r24.z, r19.w ineg r24.w, r23.x ige r23.y, l(0), r4.y itof r23.z, r4.y mov r23.w, l(0) mov r16.y, l(0) loop uge r25.x, r23.w, l(16) breakc_nz r25.x ishl r25.x, r23.w, l(1) ushr r25.x, icb[r0.z + 0].x, r25.x and r25.x, r25.x, l(3) ieq r25.y, r25.x, l(2) if_nz r25.y ld_structured r26.xyzw, r23.w, l(0), g0.xyzw iadd r26.xyzw, r18.xyzw, r26.xyzw imul null, r25.yz, r17.xxyx, r26.xxyx iadd r25.y, r25.z, r25.y imad r25.y, r17.z, r26.z, r25.y imad r25.y, r17.w, r26.w, r25.y ige r25.z, l(0), r25.y or r25.z, r11.w, r25.z ilt r25.w, r25.y, r6.y itof r25.y, r25.y mul r25.y, r25.y, l(63.499989) div r25.y, r25.y, r12.w ftou r25.y, r25.y iadd r25.y, r19.x, r25.y movc r25.y, r25.w, icb[r25.y + 0].w, r19.y movc r25.y, r25.z, l(0), r25.y else ieq r25.z, r25.x, l(1) if_nz r25.z ld_structured r26.xyzw, r23.w, l(0), g0.xyzw iadd r26.xyzw, r21.xyzw, r26.xyzw imul null, r25.zw, r20.xxxy, r26.xxxy iadd r25.z, r25.w, r25.z imad r25.z, r20.z, r26.z, r25.z imad r25.z, r20.w, r26.w, r25.z ige r25.w, l(0), r25.z or r25.w, r15.z, r25.w ilt r26.x, r25.z, r5.z itof r25.z, r25.z mul r25.z, r25.z, l(63.499989) div r25.z, r25.z, r15.w ftou r25.z, r25.z iadd r25.z, r19.x, r25.z movc r25.z, r26.x, icb[r25.z + 0].w, r19.y movc r25.y, r25.w, l(0), r25.z else ld_structured r26.xyzw, r23.w, l(0), g0.xyzw iadd r26.xyzw, r24.xyzw, r26.xyzw imul null, r25.zw, r22.xxxy, r26.xxxy iadd r25.z, r25.w, r25.z imad r25.z, r22.z, r26.z, r25.z imad r25.z, r22.w, r26.w, r25.z ige r25.w, l(0), r25.z or r25.w, r23.y, r25.w ilt r26.x, r25.z, r4.y itof r25.z, r25.z mul r25.z, r25.z, l(63.499989) div r25.z, r25.z, r23.z ftou r25.z, r25.z iadd r25.z, r19.x, r25.z movc r25.z, r26.x, icb[r25.z + 0].w, r19.y movc r25.y, r25.w, l(0), r25.z endif endif iadd r25.y, r19.z, r25.y iadd r25.z, l(64), -icb[r25.y + 64].x ishl r25.x, r25.x, l(2) mov r26.x, x0[r25.x + 0].x mov r26.y, x0[r25.x + 1].x mov r26.z, x0[r25.x + 2].x mov r27.x, x0[r25.x + 0].y mov r27.y, x0[r25.x + 1].y mov r27.z, x0[r25.x + 2].y imul null, r25.xyw, r27.xyxz, icb[r25.y + 64].xxxx imad r25.xyz, r25.zzzz, r26.xyzx, r25.xywx iadd r25.xyz, r25.xyzx, l(32, 32, 32, 0) ushr r25.xyw, r25.xyxz, l(6) ld_structured r26.xyzw, r23.w, l(0), g0.xyzw ult r27.xyz, r25.xywx, r26.xyzx mov r25.z, r26.x movc r27.xw, r27.xxxx, r25.zzzx, r25.xxxz mov r25.xz, r26.yyzy movc r25.xyzw, r27.yyzz, r25.xyzw, r25.yxwz ult r26.x, l(255), r26.w mov r14.x, r26.w movc r26.xw, r26.xxxx, r14.yyyx, r14.xxxy ineg r28.x, r27.w ineg r28.yz, r25.yywy ineg r28.w, r26.x mov r26.x, r27.x mov r26.yz, r25.xxzx iadd r25.xyzw, r28.xyzw, r26.xyzw imul null, r25.xy, r25.xyxx, r25.xyxx iadd r14.x, r25.y, r25.x imad r14.x, r25.z, r25.z, r14.x utof r14.x, r14.x utof r25.x, r25.w mul r25.x, r25.x, r25.x mad r14.x, r25.x, cb0[1].z, r14.x ftou r14.x, r14.x iadd r16.y, r14.x, r16.y iadd r23.w, r23.w, l(1) endloop ult r3.z, r16.y, r15.y movc r15.xy, r3.zzzz, r16.xyxx, r15.xyxx iadd r16.x, r16.x, l(1) endloop store_structured g0.x, vThreadIDInGroupFlattened.x, l(16), r15.y store_structured g0.x, vThreadIDInGroupFlattened.x, l(24), r0.y store_structured g0.x, vThreadIDInGroupFlattened.x, l(32), r15.x endif sync_g_t if_nz r1.y ld_structured r2.x, vThreadIDInGroupFlattened.x, l(16), g0.xxxx iadd r0.y, vThreadIDInGroupFlattened.x, l(32) ld_structured r3.x, r0.y, l(16), g0.xxxx ld_structured r4.x, r0.y, l(24), g0.xxxx ld_structured r5.x, r0.y, l(32), g0.xxxx ult r0.y, r3.x, r2.x if_nz r0.y store_structured g0.x, vThreadIDInGroupFlattened.x, l(16), r3.x store_structured g0.x, vThreadIDInGroupFlattened.x, l(24), r4.x store_structured g0.x, vThreadIDInGroupFlattened.x, l(32), r5.x endif endif if_nz r1.x ld_structured r2.x, vThreadIDInGroupFlattened.x, l(16), g0.xxxx iadd r0.y, vThreadIDInGroupFlattened.x, l(16) ld_structured r3.x, r0.y, l(16), g0.xxxx ld_structured r4.x, r0.y, l(24), g0.xxxx ld_structured r5.x, r0.y, l(32), g0.xxxx ult r0.y, r3.x, r2.x if_nz r0.y store_structured g0.x, vThreadIDInGroupFlattened.x, l(16), r3.x store_structured g0.x, vThreadIDInGroupFlattened.x, l(24), r4.x store_structured g0.x, vThreadIDInGroupFlattened.x, l(32), r5.x endif endif if_nz r1.z ld_structured r2.x, vThreadIDInGroupFlattened.x, l(16), g0.xxxx iadd r0.y, vThreadIDInGroupFlattened.x, l(8) ld_structured r3.x, r0.y, l(16), g0.xxxx ld_structured r4.x, r0.y, l(24), g0.xxxx ld_structured r5.x, r0.y, l(32), g0.xxxx ult r0.y, r3.x, r2.x if_nz r0.y store_structured g0.x, vThreadIDInGroupFlattened.x, l(16), r3.x store_structured g0.x, vThreadIDInGroupFlattened.x, l(24), r4.x store_structured g0.x, vThreadIDInGroupFlattened.x, l(32), r5.x endif endif if_nz r1.w ld_structured r1.x, vThreadIDInGroupFlattened.x, l(16), g0.xxxx iadd r0.y, vThreadIDInGroupFlattened.x, l(4) ld_structured r2.x, r0.y, l(16), g0.xxxx ld_structured r3.x, r0.y, l(24), g0.xxxx ld_structured r4.x, r0.y, l(32), g0.xxxx ult r0.y, r2.x, r1.x if_nz r0.y store_structured g0.x, vThreadIDInGroupFlattened.x, l(16), r2.x store_structured g0.x, vThreadIDInGroupFlattened.x, l(24), r3.x store_structured g0.x, vThreadIDInGroupFlattened.x, l(32), r4.x endif endif ult r0.yz, vThreadIDInGroupFlattened.xxxx, l(0, 2, 1, 0) if_nz r0.y ld_structured r1.x, vThreadIDInGroupFlattened.x, l(16), g0.xxxx iadd r0.y, vThreadIDInGroupFlattened.x, l(2) ld_structured r2.x, r0.y, l(16), g0.xxxx ld_structured r3.x, r0.y, l(24), g0.xxxx ld_structured r4.x, r0.y, l(32), g0.xxxx ult r0.y, r2.x, r1.x if_nz r0.y store_structured g0.x, vThreadIDInGroupFlattened.x, l(16), r2.x store_structured g0.x, vThreadIDInGroupFlattened.x, l(24), r3.x store_structured g0.x, vThreadIDInGroupFlattened.x, l(32), r4.x endif endif if_nz r0.z ld_structured r1.x, vThreadIDInGroupFlattened.x, l(16), g0.xxxx iadd r0.y, vThreadIDInGroupFlattened.x, l(1) ld_structured r2.x, r0.y, l(16), g0.xxxx ld_structured r3.x, r0.y, l(24), g0.xxxx ld_structured r4.x, r0.y, l(32), g0.xxxx ult r0.y, r2.x, r1.x if_nz r0.y store_structured g0.x, vThreadIDInGroupFlattened.x, l(16), r2.x store_structured g0.x, vThreadIDInGroupFlattened.x, l(24), r3.x store_structured g0.x, vThreadIDInGroupFlattened.x, l(32), r4.x endif ld_structured r1.x, r0.x, l(0), t1.xxxx ld_structured r2.x, vThreadIDInGroupFlattened.x, l(16), g0.xxxx ult r0.y, r2.x, r1.x if_nz r0.y ld_structured r2.z, vThreadIDInGroupFlattened.x, l(24), g0.xxxx ld_structured r2.w, vThreadIDInGroupFlattened.x, l(32), g0.xxxx mov r2.y, cb0[0].w else ld_structured r2.xyzw, r0.x, l(0), t1.xyzw endif store_structured u0.xyzw, r0.x, l(0), r2.xyzw endif ret // Approximately 0 instruction slots used #endif const BYTE BC7Encode_TryMode02CS[] = { 68, 88, 66, 67, 122, 4, 188, 46, 162, 127, 38, 170, 88, 175, 162, 101, 250, 119, 32, 234, 1, 0, 0, 0, 172, 70, 0, 0, 3, 0, 0, 0, 44, 0, 0, 0, 60, 0, 0, 0, 76, 0, 0, 0, 73, 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 88, 70, 0, 0, 64, 0, 5, 0, 150, 17, 0, 0, 106, 8, 0, 1, 53, 24, 0, 0, 2, 3, 0, 0, 80, 80, 104, 170, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 80, 90, 106, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 90, 90, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 168, 160, 80, 84, 15, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 165, 165, 15, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 80, 80, 160, 160, 15, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 160, 160, 85, 85, 15, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 80, 80, 90, 90, 15, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 85, 170, 15, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 85, 85, 170, 15, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 85, 170, 170, 15, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 144, 144, 144, 144, 15, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 148, 148, 148, 148, 15, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 164, 164, 164, 164, 15, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 80, 148, 165, 169, 15, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 80, 66, 10, 42, 15, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 64, 80, 148, 165, 15, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 84, 80, 66, 10, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 165, 165, 165, 8, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 160, 160, 160, 85, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 84, 84, 168, 168, 2, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 64, 64, 106, 106, 8, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 80, 164, 164, 8, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 5, 26, 26, 15, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 164, 164, 80, 0, 2, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 144, 144, 165, 170, 8, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 20, 105, 105, 20, 2, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 20, 105, 105, 2, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 160, 133, 133, 160, 8, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 20, 20, 130, 170, 8, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 80, 164, 164, 80, 2, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 2, 90, 106, 2, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 128, 165, 169, 15, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 168, 160, 144, 80, 15, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 80, 144, 160, 168, 6, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 36, 36, 36, 36, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 85, 170, 0, 2, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 36, 73, 146, 36, 8, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 36, 146, 73, 36, 15, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 80, 10, 165, 80, 15, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 80, 165, 10, 80, 2, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 68, 68, 170, 170, 8, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 102, 102, 2, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 160, 165, 160, 165, 2, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 160, 80, 160, 80, 2, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 40, 105, 40, 105, 15, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 68, 170, 170, 68, 15, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 102, 102, 102, 6, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 68, 68, 68, 170, 6, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 168, 84, 168, 84, 2, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 128, 149, 128, 149, 6, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 150, 150, 150, 8, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 168, 84, 84, 168, 15, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 128, 149, 149, 128, 15, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 20, 20, 20, 170, 2, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 150, 150, 2, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 20, 20, 170, 170, 15, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 160, 80, 80, 160, 15, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 160, 165, 165, 160, 15, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 150, 15, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 128, 64, 128, 64, 15, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 168, 169, 168, 169, 2, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 68, 170, 170, 170, 2, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 84, 82, 74, 42, 15, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 15, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 15, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 8, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 3, 0, 0, 0, 15, 0, 0, 0, 1, 0, 0, 0, 26, 0, 0, 0, 15, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 30, 0, 0, 0, 15, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 15, 0, 0, 0, 1, 0, 0, 0, 38, 0, 0, 0, 8, 0, 0, 0, 15, 0, 0, 0, 1, 0, 0, 0, 43, 0, 0, 0, 6, 0, 0, 0, 15, 0, 0, 0, 1, 0, 0, 0, 47, 0, 0, 0, 6, 0, 0, 0, 15, 0, 0, 0, 1, 0, 0, 0, 51, 0, 0, 0, 6, 0, 0, 0, 15, 0, 0, 0, 1, 0, 0, 0, 55, 0, 0, 0, 5, 0, 0, 0, 15, 0, 0, 0, 1, 0, 0, 0, 60, 0, 0, 0, 3, 0, 0, 0, 15, 0, 0, 0, 2, 0, 0, 0, 64, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 15, 0, 0, 0, 2, 0, 0, 0, 9, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 2, 0, 0, 0, 18, 0, 0, 0, 8, 0, 0, 0, 15, 0, 0, 0, 2, 0, 0, 0, 27, 0, 0, 0, 15, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 37, 0, 0, 0, 3, 0, 0, 0, 15, 0, 0, 0, 2, 0, 0, 0, 46, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 2, 0, 0, 0, 55, 0, 0, 0, 6, 0, 0, 0, 15, 0, 0, 0, 2, 0, 0, 0, 64, 0, 0, 0, 10, 0, 0, 0, 8, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 15, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 6, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 10, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 15, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 15, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 10, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 8, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 15, 0, 0, 0, 3, 0, 0, 0, 21, 0, 0, 0, 15, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 43, 0, 0, 0, 3, 0, 0, 0, 15, 0, 0, 0, 4, 0, 0, 0, 64, 0, 0, 0, 5, 0, 0, 0, 10, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 10, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 10, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 15, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 15, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 15, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 15, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 15, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 15, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 15, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 15, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 15, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 15, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 15, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 15, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 89, 0, 0, 4, 70, 142, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 88, 24, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 162, 0, 0, 4, 0, 112, 16, 0, 1, 0, 0, 0, 16, 0, 0, 0, 158, 0, 0, 4, 0, 224, 17, 0, 0, 0, 0, 0, 16, 0, 0, 0, 95, 0, 0, 2, 0, 64, 2, 0, 95, 0, 0, 2, 18, 16, 2, 0, 104, 0, 0, 2, 29, 0, 0, 0, 105, 0, 0, 4, 0, 0, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, 105, 0, 0, 4, 1, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 105, 0, 0, 4, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 105, 0, 0, 4, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 160, 0, 0, 5, 0, 240, 17, 0, 0, 0, 0, 0, 100, 0, 0, 0, 64, 0, 0, 0, 155, 0, 0, 4, 64, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 16, 2, 0, 10, 128, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 79, 0, 0, 9, 242, 0, 16, 0, 1, 0, 0, 0, 6, 64, 2, 0, 2, 64, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 1, 0, 0, 0, 78, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 0, 208, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 11, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 128, 65, 0, 0, 0, 0, 0, 0, 0, 26, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 0, 0, 6, 130, 0, 16, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 3, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 6, 66, 0, 16, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 2, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 7, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, 127, 67, 28, 0, 0, 5, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 84, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 168, 0, 0, 8, 242, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 0, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 21, 0, 0, 1, 190, 24, 0, 1, 168, 0, 0, 8, 18, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 16, 0, 0, 0, 1, 64, 0, 0, 255, 255, 255, 255, 55, 0, 0, 10, 34, 0, 16, 0, 0, 0, 0, 0, 58, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 64, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 79, 0, 0, 6, 34, 0, 16, 0, 0, 0, 0, 0, 10, 64, 2, 0, 26, 0, 16, 0, 0, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 6, 34, 0, 16, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 64, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 255, 255, 255, 255, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 255, 255, 255, 255, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 255, 255, 255, 255, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 64, 0, 0, 255, 255, 255, 255, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 5, 0, 0, 0, 1, 64, 0, 0, 255, 255, 255, 255, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, 255, 255, 255, 255, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 5, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 8, 0, 0, 0, 1, 64, 0, 0, 255, 255, 255, 255, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 9, 0, 0, 0, 1, 64, 0, 0, 255, 255, 255, 255, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 10, 0, 0, 0, 1, 64, 0, 0, 255, 255, 255, 255, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 8, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 9, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 10, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 192, 255, 255, 255, 54, 0, 0, 5, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 48, 0, 0, 1, 80, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 3, 0, 4, 3, 10, 0, 16, 0, 2, 0, 0, 0, 167, 0, 0, 9, 114, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 70, 242, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 85, 0, 0, 8, 130, 0, 16, 0, 2, 0, 0, 0, 10, 144, 144, 0, 42, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 32, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 3, 0, 0, 0, 54, 0, 0, 6, 18, 0, 16, 0, 3, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 8, 0, 0, 0, 54, 0, 0, 6, 34, 0, 16, 0, 3, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 9, 0, 0, 0, 54, 0, 0, 6, 66, 0, 16, 0, 3, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 10, 0, 0, 0, 84, 0, 0, 7, 114, 0, 16, 0, 3, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 3, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 8, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 9, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 10, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 54, 0, 0, 6, 18, 0, 16, 0, 3, 0, 0, 0, 26, 48, 32, 0, 0, 0, 0, 0, 8, 0, 0, 0, 54, 0, 0, 6, 34, 0, 16, 0, 3, 0, 0, 0, 26, 48, 32, 0, 0, 0, 0, 0, 9, 0, 0, 0, 54, 0, 0, 6, 66, 0, 16, 0, 3, 0, 0, 0, 26, 48, 32, 0, 0, 0, 0, 0, 10, 0, 0, 0, 83, 0, 0, 7, 114, 0, 16, 0, 3, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 3, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 8, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 9, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 10, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 18, 0, 0, 1, 32, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 2, 0, 0, 0, 54, 0, 0, 6, 18, 0, 16, 0, 3, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 4, 0, 0, 0, 54, 0, 0, 6, 34, 0, 16, 0, 3, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 5, 0, 0, 0, 54, 0, 0, 6, 66, 0, 16, 0, 3, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 6, 0, 0, 0, 84, 0, 0, 7, 114, 0, 16, 0, 3, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 3, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 4, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 5, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 6, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 54, 0, 0, 6, 18, 0, 16, 0, 3, 0, 0, 0, 26, 48, 32, 0, 0, 0, 0, 0, 4, 0, 0, 0, 54, 0, 0, 6, 34, 0, 16, 0, 3, 0, 0, 0, 26, 48, 32, 0, 0, 0, 0, 0, 5, 0, 0, 0, 54, 0, 0, 6, 66, 0, 16, 0, 3, 0, 0, 0, 26, 48, 32, 0, 0, 0, 0, 0, 6, 0, 0, 0, 83, 0, 0, 7, 114, 0, 16, 0, 3, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 3, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 4, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 5, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 6, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 6, 18, 0, 16, 0, 3, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 34, 0, 16, 0, 3, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 54, 0, 0, 6, 66, 0, 16, 0, 3, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 84, 0, 0, 7, 114, 0, 16, 0, 3, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 3, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 54, 0, 0, 6, 18, 0, 16, 0, 3, 0, 0, 0, 26, 48, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 34, 0, 16, 0, 3, 0, 0, 0, 26, 48, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 54, 0, 0, 6, 66, 0, 16, 0, 3, 0, 0, 0, 26, 48, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 83, 0, 0, 7, 114, 0, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 3, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 21, 0, 0, 1, 21, 0, 0, 1, 30, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 22, 0, 0, 1, 54, 0, 0, 6, 18, 0, 16, 0, 2, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 34, 0, 16, 0, 2, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 54, 0, 0, 6, 66, 0, 16, 0, 2, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 54, 0, 0, 6, 18, 0, 16, 0, 3, 0, 0, 0, 26, 48, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 34, 0, 16, 0, 3, 0, 0, 0, 26, 48, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 54, 0, 0, 6, 66, 0, 16, 0, 3, 0, 0, 0, 26, 48, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 54, 0, 0, 6, 18, 0, 16, 0, 4, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 4, 0, 0, 0, 54, 0, 0, 6, 34, 0, 16, 0, 4, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 5, 0, 0, 0, 54, 0, 0, 6, 66, 0, 16, 0, 4, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 6, 0, 0, 0, 54, 0, 0, 6, 18, 0, 16, 0, 5, 0, 0, 0, 26, 48, 32, 0, 0, 0, 0, 0, 4, 0, 0, 0, 54, 0, 0, 6, 34, 0, 16, 0, 5, 0, 0, 0, 26, 48, 32, 0, 0, 0, 0, 0, 5, 0, 0, 0, 54, 0, 0, 6, 66, 0, 16, 0, 5, 0, 0, 0, 26, 48, 32, 0, 0, 0, 0, 0, 6, 0, 0, 0, 54, 0, 0, 6, 18, 0, 16, 0, 6, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 8, 0, 0, 0, 54, 0, 0, 6, 34, 0, 16, 0, 6, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 9, 0, 0, 0, 54, 0, 0, 6, 66, 0, 16, 0, 6, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 10, 0, 0, 0, 54, 0, 0, 6, 18, 0, 16, 0, 7, 0, 0, 0, 26, 48, 32, 0, 0, 0, 0, 0, 8, 0, 0, 0, 54, 0, 0, 6, 34, 0, 16, 0, 7, 0, 0, 0, 26, 48, 32, 0, 0, 0, 0, 0, 9, 0, 0, 0, 54, 0, 0, 6, 66, 0, 16, 0, 7, 0, 0, 0, 26, 48, 32, 0, 0, 0, 0, 0, 10, 0, 0, 0, 55, 0, 0, 10, 130, 0, 16, 0, 0, 0, 0, 0, 58, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 64, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 84, 0, 0, 10, 114, 0, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 114, 0, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 30, 0, 0, 0, 30, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 3, 0, 0, 0, 70, 2, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 84, 0, 0, 10, 114, 0, 16, 0, 3, 0, 0, 0, 70, 2, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 114, 0, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 30, 0, 0, 0, 30, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 248, 0, 0, 0, 248, 0, 0, 0, 248, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 114, 0, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 248, 0, 0, 0, 248, 0, 0, 0, 248, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 114, 0, 16, 0, 3, 0, 0, 0, 70, 2, 16, 0, 3, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 3, 0, 0, 0, 70, 2, 16, 0, 3, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 84, 0, 0, 10, 114, 0, 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 114, 0, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 30, 0, 0, 0, 30, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 84, 0, 0, 10, 114, 0, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 30, 0, 0, 0, 30, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 248, 0, 0, 0, 248, 0, 0, 0, 248, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 114, 0, 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 248, 0, 0, 0, 248, 0, 0, 0, 248, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 114, 0, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 84, 0, 0, 10, 114, 0, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 30, 0, 0, 0, 30, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 84, 0, 0, 10, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 30, 0, 0, 0, 30, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 248, 0, 0, 0, 248, 0, 0, 0, 248, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 114, 0, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 248, 0, 0, 0, 248, 0, 0, 0, 248, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 54, 0, 0, 5, 34, 0, 16, 0, 14, 0, 0, 0, 1, 64, 0, 0, 255, 0, 0, 0, 54, 0, 0, 6, 34, 0, 16, 0, 2, 0, 0, 0, 58, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 50, 0, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 16, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 48, 0, 0, 1, 80, 0, 0, 7, 66, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 16, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 3, 0, 4, 3, 42, 0, 16, 0, 3, 0, 0, 0, 32, 0, 0, 7, 66, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 31, 0, 0, 3, 26, 0, 16, 0, 2, 0, 0, 0, 85, 0, 0, 7, 34, 0, 16, 0, 16, 0, 0, 0, 10, 0, 16, 0, 16, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 14, 0, 0, 0, 6, 4, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 166, 10, 16, 0, 14, 0, 0, 0, 41, 0, 0, 7, 114, 0, 16, 0, 17, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 85, 0, 0, 7, 114, 0, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 30, 0, 0, 7, 210, 0, 16, 0, 17, 0, 0, 0, 166, 4, 16, 0, 17, 0, 0, 0, 166, 4, 16, 0, 18, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 246, 15, 16, 0, 14, 0, 0, 0, 41, 0, 0, 7, 114, 0, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 85, 0, 0, 7, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 18, 0, 0, 0, 22, 6, 16, 0, 18, 0, 0, 0, 22, 6, 16, 0, 19, 0, 0, 0, 54, 0, 0, 5, 34, 0, 16, 0, 17, 0, 0, 0, 42, 0, 16, 0, 18, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 18, 0, 0, 0, 58, 0, 16, 0, 17, 0, 0, 0, 54, 0, 0, 5, 194, 0, 16, 0, 14, 0, 0, 0, 246, 3, 16, 0, 18, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 18, 0, 0, 0, 42, 0, 16, 0, 17, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 50, 0, 16, 0, 17, 0, 0, 0, 230, 10, 16, 0, 2, 0, 0, 0, 54, 0, 0, 5, 194, 0, 16, 0, 14, 0, 0, 0, 246, 7, 16, 0, 3, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 18, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 54, 0, 0, 5, 34, 0, 16, 0, 18, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 21, 0, 0, 1, 54, 0, 0, 9, 50, 48, 32, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 50, 48, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 70, 0, 16, 0, 17, 0, 0, 0, 54, 0, 0, 6, 50, 48, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 230, 10, 16, 0, 14, 0, 0, 0, 54, 0, 0, 6, 50, 48, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 0, 16, 0, 18, 0, 0, 0, 31, 0, 0, 3, 26, 0, 16, 0, 2, 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 19, 0, 0, 0, 10, 0, 16, 0, 16, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 85, 0, 0, 7, 34, 0, 16, 0, 19, 0, 0, 0, 10, 0, 16, 0, 16, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 15, 0, 0, 0, 6, 4, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 166, 10, 16, 0, 15, 0, 0, 0, 41, 0, 0, 7, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 85, 0, 0, 7, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 30, 0, 0, 7, 210, 0, 16, 0, 19, 0, 0, 0, 166, 4, 16, 0, 19, 0, 0, 0, 166, 4, 16, 0, 20, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 246, 15, 16, 0, 15, 0, 0, 0, 41, 0, 0, 7, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 85, 0, 0, 7, 114, 0, 16, 0, 21, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 20, 0, 0, 0, 22, 6, 16, 0, 20, 0, 0, 0, 22, 6, 16, 0, 21, 0, 0, 0, 54, 0, 0, 5, 34, 0, 16, 0, 19, 0, 0, 0, 42, 0, 16, 0, 20, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 20, 0, 0, 0, 58, 0, 16, 0, 19, 0, 0, 0, 54, 0, 0, 5, 194, 0, 16, 0, 15, 0, 0, 0, 246, 3, 16, 0, 20, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 20, 0, 0, 0, 42, 0, 16, 0, 19, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 50, 0, 16, 0, 19, 0, 0, 0, 230, 10, 16, 0, 4, 0, 0, 0, 54, 0, 0, 5, 194, 0, 16, 0, 15, 0, 0, 0, 246, 7, 16, 0, 5, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 20, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 54, 0, 0, 5, 34, 0, 16, 0, 20, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 21, 0, 0, 1, 54, 0, 0, 9, 50, 48, 32, 0, 0, 0, 0, 0, 7, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 50, 48, 32, 0, 0, 0, 0, 0, 6, 0, 0, 0, 70, 0, 16, 0, 19, 0, 0, 0, 54, 0, 0, 6, 50, 48, 32, 0, 0, 0, 0, 0, 5, 0, 0, 0, 230, 10, 16, 0, 15, 0, 0, 0, 54, 0, 0, 6, 50, 48, 32, 0, 0, 0, 0, 0, 4, 0, 0, 0, 70, 0, 16, 0, 20, 0, 0, 0, 31, 0, 0, 3, 26, 0, 16, 0, 2, 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 21, 0, 0, 0, 10, 0, 16, 0, 16, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 85, 0, 0, 7, 34, 0, 16, 0, 21, 0, 0, 0, 10, 0, 16, 0, 16, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 16, 0, 0, 0, 6, 4, 16, 0, 21, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 21, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 166, 10, 16, 0, 16, 0, 0, 0, 41, 0, 0, 7, 114, 0, 16, 0, 21, 0, 0, 0, 70, 2, 16, 0, 21, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 85, 0, 0, 7, 114, 0, 16, 0, 22, 0, 0, 0, 70, 2, 16, 0, 21, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 30, 0, 0, 7, 210, 0, 16, 0, 21, 0, 0, 0, 166, 4, 16, 0, 21, 0, 0, 0, 166, 4, 16, 0, 22, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 22, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 246, 15, 16, 0, 16, 0, 0, 0, 41, 0, 0, 7, 114, 0, 16, 0, 22, 0, 0, 0, 70, 2, 16, 0, 22, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 85, 0, 0, 7, 114, 0, 16, 0, 23, 0, 0, 0, 70, 2, 16, 0, 22, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 22, 0, 0, 0, 22, 6, 16, 0, 22, 0, 0, 0, 22, 6, 16, 0, 23, 0, 0, 0, 54, 0, 0, 5, 34, 0, 16, 0, 21, 0, 0, 0, 42, 0, 16, 0, 22, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 22, 0, 0, 0, 58, 0, 16, 0, 21, 0, 0, 0, 54, 0, 0, 5, 194, 0, 16, 0, 16, 0, 0, 0, 246, 3, 16, 0, 22, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 22, 0, 0, 0, 42, 0, 16, 0, 21, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 5, 50, 0, 16, 0, 21, 0, 0, 0, 230, 10, 16, 0, 6, 0, 0, 0, 54, 0, 0, 5, 194, 0, 16, 0, 16, 0, 0, 0, 246, 7, 16, 0, 7, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 22, 0, 0, 0, 10, 0, 16, 0, 6, 0, 0, 0, 54, 0, 0, 5, 34, 0, 16, 0, 22, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 21, 0, 0, 1, 54, 0, 0, 9, 50, 48, 32, 0, 0, 0, 0, 0, 11, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 50, 48, 32, 0, 0, 0, 0, 0, 10, 0, 0, 0, 70, 0, 16, 0, 21, 0, 0, 0, 54, 0, 0, 6, 50, 48, 32, 0, 0, 0, 0, 0, 9, 0, 0, 0, 230, 10, 16, 0, 16, 0, 0, 0, 54, 0, 0, 6, 50, 48, 32, 0, 0, 0, 0, 0, 8, 0, 0, 0, 70, 0, 16, 0, 22, 0, 0, 0, 40, 0, 0, 5, 18, 0, 16, 0, 23, 0, 0, 0, 10, 0, 16, 0, 18, 0, 0, 0, 40, 0, 0, 5, 34, 0, 16, 0, 23, 0, 0, 0, 42, 0, 16, 0, 14, 0, 0, 0, 40, 0, 0, 5, 66, 0, 16, 0, 23, 0, 0, 0, 10, 0, 16, 0, 17, 0, 0, 0, 54, 0, 0, 5, 66, 0, 16, 0, 18, 0, 0, 0, 58, 0, 16, 0, 14, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 18, 0, 0, 0, 26, 0, 16, 0, 17, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 17, 0, 0, 0, 150, 7, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 23, 0, 0, 0, 54, 0, 0, 6, 114, 48, 32, 0, 1, 0, 0, 0, 0, 0, 0, 0, 70, 2, 16, 0, 17, 0, 0, 0, 40, 0, 0, 5, 18, 0, 16, 0, 18, 0, 0, 0, 10, 0, 16, 0, 20, 0, 0, 0, 40, 0, 0, 5, 34, 0, 16, 0, 18, 0, 0, 0, 42, 0, 16, 0, 15, 0, 0, 0, 40, 0, 0, 5, 66, 0, 16, 0, 18, 0, 0, 0, 10, 0, 16, 0, 19, 0, 0, 0, 54, 0, 0, 5, 66, 0, 16, 0, 20, 0, 0, 0, 58, 0, 16, 0, 15, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 20, 0, 0, 0, 26, 0, 16, 0, 19, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 18, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 150, 7, 16, 0, 20, 0, 0, 0, 54, 0, 0, 6, 114, 48, 32, 0, 1, 0, 0, 0, 1, 0, 0, 0, 70, 2, 16, 0, 18, 0, 0, 0, 40, 0, 0, 5, 18, 0, 16, 0, 19, 0, 0, 0, 10, 0, 16, 0, 22, 0, 0, 0, 40, 0, 0, 5, 34, 0, 16, 0, 19, 0, 0, 0, 42, 0, 16, 0, 16, 0, 0, 0, 40, 0, 0, 5, 66, 0, 16, 0, 19, 0, 0, 0, 10, 0, 16, 0, 21, 0, 0, 0, 54, 0, 0, 5, 66, 0, 16, 0, 22, 0, 0, 0, 58, 0, 16, 0, 16, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 22, 0, 0, 0, 26, 0, 16, 0, 21, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 19, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 150, 7, 16, 0, 22, 0, 0, 0, 54, 0, 0, 6, 114, 48, 32, 0, 1, 0, 0, 0, 2, 0, 0, 0, 70, 2, 16, 0, 19, 0, 0, 0, 54, 0, 0, 6, 130, 48, 32, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 130, 48, 32, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 130, 48, 32, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 194, 0, 16, 0, 14, 0, 0, 0, 6, 4, 16, 0, 17, 0, 0, 0, 6, 4, 16, 0, 17, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 14, 0, 0, 0, 42, 0, 16, 0, 14, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 4, 0, 0, 0, 42, 0, 16, 0, 17, 0, 0, 0, 42, 0, 16, 0, 17, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 2, 0, 0, 0, 0, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 194, 0, 16, 0, 14, 0, 0, 0, 6, 4, 16, 0, 18, 0, 0, 0, 6, 4, 16, 0, 18, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 14, 0, 0, 0, 42, 0, 16, 0, 14, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 18, 0, 0, 0, 42, 0, 16, 0, 18, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 2, 0, 0, 0, 1, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 194, 0, 16, 0, 14, 0, 0, 0, 6, 4, 16, 0, 19, 0, 0, 0, 6, 4, 16, 0, 19, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 14, 0, 0, 0, 42, 0, 16, 0, 14, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 19, 0, 0, 0, 42, 0, 16, 0, 19, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 2, 0, 0, 0, 2, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 3, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 54, 0, 0, 7, 18, 48, 32, 0, 3, 0, 0, 0, 1, 0, 0, 0, 26, 144, 144, 0, 26, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 7, 18, 48, 32, 0, 3, 0, 0, 0, 2, 0, 0, 0, 42, 144, 144, 0, 26, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 66, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 48, 0, 0, 1, 80, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 3, 0, 4, 3, 58, 0, 16, 0, 8, 0, 0, 0, 54, 0, 0, 7, 242, 0, 16, 0, 17, 0, 0, 0, 70, 62, 32, 4, 1, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 54, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 10, 48, 32, 4, 3, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 167, 0, 0, 9, 242, 0, 16, 0, 18, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 54, 0, 0, 7, 130, 0, 16, 0, 9, 0, 0, 0, 10, 48, 32, 4, 0, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 54, 0, 0, 8, 130, 0, 16, 0, 10, 0, 0, 0, 10, 48, 32, 6, 0, 0, 0, 0, 1, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 54, 0, 0, 8, 130, 0, 16, 0, 11, 0, 0, 0, 10, 48, 32, 6, 0, 0, 0, 0, 2, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 54, 0, 0, 8, 130, 0, 16, 0, 12, 0, 0, 0, 10, 48, 32, 6, 0, 0, 0, 0, 3, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 40, 0, 0, 5, 18, 0, 16, 0, 19, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 40, 0, 0, 5, 34, 0, 16, 0, 19, 0, 0, 0, 58, 0, 16, 0, 10, 0, 0, 0, 40, 0, 0, 5, 66, 0, 16, 0, 19, 0, 0, 0, 58, 0, 16, 0, 11, 0, 0, 0, 40, 0, 0, 5, 130, 0, 16, 0, 19, 0, 0, 0, 58, 0, 16, 0, 12, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 18, 0, 0, 0, 70, 14, 16, 0, 18, 0, 0, 0, 70, 14, 16, 0, 19, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 194, 0, 16, 0, 14, 0, 0, 0, 6, 4, 16, 0, 17, 0, 0, 0, 6, 4, 16, 0, 18, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 13, 0, 0, 0, 58, 0, 16, 0, 14, 0, 0, 0, 42, 0, 16, 0, 14, 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 13, 0, 0, 0, 42, 0, 16, 0, 17, 0, 0, 0, 42, 0, 16, 0, 18, 0, 0, 0, 58, 0, 16, 0, 13, 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 13, 0, 0, 0, 58, 0, 16, 0, 17, 0, 0, 0, 58, 0, 16, 0, 18, 0, 0, 0, 58, 0, 16, 0, 13, 0, 0, 0, 54, 0, 0, 7, 66, 0, 16, 0, 14, 0, 0, 0, 10, 48, 32, 4, 2, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 34, 0, 0, 7, 130, 0, 16, 0, 14, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 14, 0, 0, 0, 34, 0, 0, 7, 66, 0, 16, 0, 15, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 13, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 14, 0, 0, 0, 58, 0, 16, 0, 14, 0, 0, 0, 42, 0, 16, 0, 15, 0, 0, 0, 43, 0, 0, 5, 130, 0, 16, 0, 13, 0, 0, 0, 58, 0, 16, 0, 13, 0, 0, 0, 56, 0, 0, 7, 130, 0, 16, 0, 13, 0, 0, 0, 58, 0, 16, 0, 13, 0, 0, 0, 1, 64, 0, 0, 253, 255, 125, 66, 28, 0, 0, 5, 130, 0, 16, 0, 13, 0, 0, 0, 58, 0, 16, 0, 13, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 14, 0, 0, 0, 42, 0, 16, 0, 14, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 79, 0, 0, 7, 130, 0, 16, 0, 13, 0, 0, 0, 42, 0, 16, 0, 14, 0, 0, 0, 58, 0, 16, 0, 13, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 13, 0, 0, 0, 58, 0, 16, 0, 13, 0, 0, 0, 58, 0, 16, 0, 14, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 13, 0, 0, 0, 40, 0, 0, 5, 242, 0, 16, 0, 17, 0, 0, 0, 70, 14, 16, 0, 17, 0, 0, 0, 54, 0, 0, 7, 242, 48, 32, 4, 1, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 17, 0, 0, 0, 54, 0, 0, 7, 130, 0, 16, 0, 13, 0, 0, 0, 26, 48, 32, 4, 0, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 54, 0, 0, 8, 66, 0, 16, 0, 14, 0, 0, 0, 26, 48, 32, 6, 0, 0, 0, 0, 1, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 54, 0, 0, 8, 130, 0, 16, 0, 14, 0, 0, 0, 26, 48, 32, 6, 0, 0, 0, 0, 2, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 54, 0, 0, 8, 66, 0, 16, 0, 15, 0, 0, 0, 26, 48, 32, 6, 0, 0, 0, 0, 3, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 54, 0, 0, 7, 18, 48, 32, 4, 0, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 13, 0, 0, 0, 54, 0, 0, 8, 18, 48, 32, 6, 0, 0, 0, 0, 1, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 14, 0, 0, 0, 54, 0, 0, 8, 18, 48, 32, 6, 0, 0, 0, 0, 2, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 14, 0, 0, 0, 54, 0, 0, 8, 18, 48, 32, 6, 0, 0, 0, 0, 3, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 15, 0, 0, 0, 54, 0, 0, 7, 34, 48, 32, 4, 0, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 54, 0, 0, 8, 34, 48, 32, 6, 0, 0, 0, 0, 1, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 10, 0, 0, 0, 54, 0, 0, 8, 34, 48, 32, 6, 0, 0, 0, 0, 2, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 11, 0, 0, 0, 54, 0, 0, 8, 34, 48, 32, 6, 0, 0, 0, 0, 3, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 12, 0, 0, 0, 21, 0, 0, 1, 30, 0, 0, 7, 66, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 22, 0, 0, 1, 54, 0, 0, 6, 242, 0, 16, 0, 17, 0, 0, 0, 70, 62, 32, 0, 1, 0, 0, 0, 2, 0, 0, 0, 54, 0, 0, 6, 66, 0, 16, 0, 7, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 8, 0, 0, 0, 54, 0, 0, 6, 130, 0, 16, 0, 8, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 9, 0, 0, 0, 54, 0, 0, 6, 130, 0, 16, 0, 9, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 10, 0, 0, 0, 54, 0, 0, 6, 130, 0, 16, 0, 10, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 11, 0, 0, 0, 40, 0, 0, 5, 18, 0, 16, 0, 18, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 40, 0, 0, 5, 34, 0, 16, 0, 18, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 40, 0, 0, 5, 66, 0, 16, 0, 18, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 40, 0, 0, 5, 130, 0, 16, 0, 18, 0, 0, 0, 58, 0, 16, 0, 10, 0, 0, 0, 33, 0, 0, 7, 130, 0, 16, 0, 11, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 43, 0, 0, 5, 130, 0, 16, 0, 12, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 55, 0, 0, 15, 114, 0, 16, 0, 19, 0, 0, 0, 166, 10, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 128, 0, 0, 0, 3, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 64, 0, 0, 0, 7, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 0, 16, 0, 20, 0, 0, 0, 70, 62, 32, 0, 1, 0, 0, 0, 1, 0, 0, 0, 54, 0, 0, 6, 66, 0, 16, 0, 3, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 4, 0, 0, 0, 54, 0, 0, 6, 130, 0, 16, 0, 13, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 5, 0, 0, 0, 54, 0, 0, 6, 66, 0, 16, 0, 14, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 6, 0, 0, 0, 54, 0, 0, 6, 130, 0, 16, 0, 14, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 7, 0, 0, 0, 40, 0, 0, 5, 18, 0, 16, 0, 21, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 40, 0, 0, 5, 34, 0, 16, 0, 21, 0, 0, 0, 58, 0, 16, 0, 13, 0, 0, 0, 40, 0, 0, 5, 194, 0, 16, 0, 21, 0, 0, 0, 166, 14, 16, 0, 14, 0, 0, 0, 33, 0, 0, 7, 66, 0, 16, 0, 15, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 43, 0, 0, 5, 130, 0, 16, 0, 15, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 54, 0, 0, 6, 242, 0, 16, 0, 22, 0, 0, 0, 70, 62, 32, 0, 1, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 66, 0, 16, 0, 16, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 130, 0, 16, 0, 16, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 54, 0, 0, 6, 130, 0, 16, 0, 19, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 54, 0, 0, 6, 18, 0, 16, 0, 23, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 3, 0, 0, 0, 40, 0, 0, 5, 50, 0, 16, 0, 24, 0, 0, 0, 230, 10, 16, 0, 16, 0, 0, 0, 40, 0, 0, 5, 66, 0, 16, 0, 24, 0, 0, 0, 58, 0, 16, 0, 19, 0, 0, 0, 40, 0, 0, 5, 130, 0, 16, 0, 24, 0, 0, 0, 10, 0, 16, 0, 23, 0, 0, 0, 33, 0, 0, 7, 34, 0, 16, 0, 23, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 43, 0, 0, 5, 66, 0, 16, 0, 23, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 23, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 34, 0, 16, 0, 16, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 48, 0, 0, 1, 80, 0, 0, 7, 18, 0, 16, 0, 25, 0, 0, 0, 58, 0, 16, 0, 23, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 3, 0, 4, 3, 10, 0, 16, 0, 25, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 25, 0, 0, 0, 58, 0, 16, 0, 23, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 85, 0, 0, 8, 18, 0, 16, 0, 25, 0, 0, 0, 10, 144, 144, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 25, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 25, 0, 0, 0, 10, 0, 16, 0, 25, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 32, 0, 0, 7, 34, 0, 16, 0, 25, 0, 0, 0, 10, 0, 16, 0, 25, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 25, 0, 0, 0, 167, 0, 0, 9, 242, 0, 16, 0, 26, 0, 0, 0, 58, 0, 16, 0, 23, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 26, 0, 0, 0, 70, 14, 16, 0, 18, 0, 0, 0, 70, 14, 16, 0, 26, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 98, 0, 16, 0, 25, 0, 0, 0, 6, 1, 16, 0, 17, 0, 0, 0, 6, 1, 16, 0, 26, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 25, 0, 0, 0, 42, 0, 16, 0, 25, 0, 0, 0, 26, 0, 16, 0, 25, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 25, 0, 0, 0, 42, 0, 16, 0, 17, 0, 0, 0, 42, 0, 16, 0, 26, 0, 0, 0, 26, 0, 16, 0, 25, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 25, 0, 0, 0, 58, 0, 16, 0, 17, 0, 0, 0, 58, 0, 16, 0, 26, 0, 0, 0, 26, 0, 16, 0, 25, 0, 0, 0, 33, 0, 0, 7, 66, 0, 16, 0, 25, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 26, 0, 16, 0, 25, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 25, 0, 0, 0, 58, 0, 16, 0, 11, 0, 0, 0, 42, 0, 16, 0, 25, 0, 0, 0, 34, 0, 0, 7, 130, 0, 16, 0, 25, 0, 0, 0, 26, 0, 16, 0, 25, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 43, 0, 0, 5, 34, 0, 16, 0, 25, 0, 0, 0, 26, 0, 16, 0, 25, 0, 0, 0, 56, 0, 0, 7, 34, 0, 16, 0, 25, 0, 0, 0, 26, 0, 16, 0, 25, 0, 0, 0, 1, 64, 0, 0, 253, 255, 125, 66, 14, 0, 0, 7, 34, 0, 16, 0, 25, 0, 0, 0, 26, 0, 16, 0, 25, 0, 0, 0, 58, 0, 16, 0, 12, 0, 0, 0, 28, 0, 0, 5, 34, 0, 16, 0, 25, 0, 0, 0, 26, 0, 16, 0, 25, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 25, 0, 0, 0, 10, 0, 16, 0, 19, 0, 0, 0, 26, 0, 16, 0, 25, 0, 0, 0, 55, 0, 0, 10, 34, 0, 16, 0, 25, 0, 0, 0, 58, 0, 16, 0, 25, 0, 0, 0, 58, 144, 144, 0, 26, 0, 16, 0, 25, 0, 0, 0, 26, 0, 16, 0, 19, 0, 0, 0, 55, 0, 0, 9, 34, 0, 16, 0, 25, 0, 0, 0, 42, 0, 16, 0, 25, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 26, 0, 16, 0, 25, 0, 0, 0, 18, 0, 0, 1, 32, 0, 0, 7, 66, 0, 16, 0, 25, 0, 0, 0, 10, 0, 16, 0, 25, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 25, 0, 0, 0, 167, 0, 0, 9, 242, 0, 16, 0, 26, 0, 0, 0, 58, 0, 16, 0, 23, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 26, 0, 0, 0, 70, 14, 16, 0, 21, 0, 0, 0, 70, 14, 16, 0, 26, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 194, 0, 16, 0, 25, 0, 0, 0, 6, 4, 16, 0, 20, 0, 0, 0, 6, 4, 16, 0, 26, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 25, 0, 0, 0, 58, 0, 16, 0, 25, 0, 0, 0, 42, 0, 16, 0, 25, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 25, 0, 0, 0, 42, 0, 16, 0, 20, 0, 0, 0, 42, 0, 16, 0, 26, 0, 0, 0, 42, 0, 16, 0, 25, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 25, 0, 0, 0, 58, 0, 16, 0, 20, 0, 0, 0, 58, 0, 16, 0, 26, 0, 0, 0, 42, 0, 16, 0, 25, 0, 0, 0, 33, 0, 0, 7, 130, 0, 16, 0, 25, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 25, 0, 0, 0, 60, 0, 0, 7, 130, 0, 16, 0, 25, 0, 0, 0, 42, 0, 16, 0, 15, 0, 0, 0, 58, 0, 16, 0, 25, 0, 0, 0, 34, 0, 0, 7, 18, 0, 16, 0, 26, 0, 0, 0, 42, 0, 16, 0, 25, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 43, 0, 0, 5, 66, 0, 16, 0, 25, 0, 0, 0, 42, 0, 16, 0, 25, 0, 0, 0, 56, 0, 0, 7, 66, 0, 16, 0, 25, 0, 0, 0, 42, 0, 16, 0, 25, 0, 0, 0, 1, 64, 0, 0, 253, 255, 125, 66, 14, 0, 0, 7, 66, 0, 16, 0, 25, 0, 0, 0, 42, 0, 16, 0, 25, 0, 0, 0, 58, 0, 16, 0, 15, 0, 0, 0, 28, 0, 0, 5, 66, 0, 16, 0, 25, 0, 0, 0, 42, 0, 16, 0, 25, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 25, 0, 0, 0, 10, 0, 16, 0, 19, 0, 0, 0, 42, 0, 16, 0, 25, 0, 0, 0, 55, 0, 0, 10, 66, 0, 16, 0, 25, 0, 0, 0, 10, 0, 16, 0, 26, 0, 0, 0, 58, 144, 144, 0, 42, 0, 16, 0, 25, 0, 0, 0, 26, 0, 16, 0, 19, 0, 0, 0, 55, 0, 0, 9, 34, 0, 16, 0, 25, 0, 0, 0, 58, 0, 16, 0, 25, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 25, 0, 0, 0, 18, 0, 0, 1, 167, 0, 0, 9, 242, 0, 16, 0, 26, 0, 0, 0, 58, 0, 16, 0, 23, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 26, 0, 0, 0, 70, 14, 16, 0, 24, 0, 0, 0, 70, 14, 16, 0, 26, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 194, 0, 16, 0, 25, 0, 0, 0, 6, 4, 16, 0, 22, 0, 0, 0, 6, 4, 16, 0, 26, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 25, 0, 0, 0, 58, 0, 16, 0, 25, 0, 0, 0, 42, 0, 16, 0, 25, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 25, 0, 0, 0, 42, 0, 16, 0, 22, 0, 0, 0, 42, 0, 16, 0, 26, 0, 0, 0, 42, 0, 16, 0, 25, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 25, 0, 0, 0, 58, 0, 16, 0, 22, 0, 0, 0, 58, 0, 16, 0, 26, 0, 0, 0, 42, 0, 16, 0, 25, 0, 0, 0, 33, 0, 0, 7, 130, 0, 16, 0, 25, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 25, 0, 0, 0, 60, 0, 0, 7, 130, 0, 16, 0, 25, 0, 0, 0, 26, 0, 16, 0, 23, 0, 0, 0, 58, 0, 16, 0, 25, 0, 0, 0, 34, 0, 0, 7, 18, 0, 16, 0, 26, 0, 0, 0, 42, 0, 16, 0, 25, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 43, 0, 0, 5, 66, 0, 16, 0, 25, 0, 0, 0, 42, 0, 16, 0, 25, 0, 0, 0, 56, 0, 0, 7, 66, 0, 16, 0, 25, 0, 0, 0, 42, 0, 16, 0, 25, 0, 0, 0, 1, 64, 0, 0, 253, 255, 125, 66, 14, 0, 0, 7, 66, 0, 16, 0, 25, 0, 0, 0, 42, 0, 16, 0, 25, 0, 0, 0, 42, 0, 16, 0, 23, 0, 0, 0, 28, 0, 0, 5, 66, 0, 16, 0, 25, 0, 0, 0, 42, 0, 16, 0, 25, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 25, 0, 0, 0, 10, 0, 16, 0, 19, 0, 0, 0, 42, 0, 16, 0, 25, 0, 0, 0, 55, 0, 0, 10, 66, 0, 16, 0, 25, 0, 0, 0, 10, 0, 16, 0, 26, 0, 0, 0, 58, 144, 144, 0, 42, 0, 16, 0, 25, 0, 0, 0, 26, 0, 16, 0, 19, 0, 0, 0, 55, 0, 0, 9, 34, 0, 16, 0, 25, 0, 0, 0, 58, 0, 16, 0, 25, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 25, 0, 0, 0, 21, 0, 0, 1, 21, 0, 0, 1, 30, 0, 0, 7, 34, 0, 16, 0, 25, 0, 0, 0, 42, 0, 16, 0, 19, 0, 0, 0, 26, 0, 16, 0, 25, 0, 0, 0, 30, 0, 0, 10, 66, 0, 16, 0, 25, 0, 0, 0, 1, 64, 0, 0, 64, 0, 0, 0, 10, 144, 208, 128, 65, 0, 0, 0, 64, 0, 0, 0, 26, 0, 16, 0, 25, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 25, 0, 0, 0, 10, 0, 16, 0, 25, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 54, 0, 0, 7, 18, 0, 16, 0, 26, 0, 0, 0, 10, 48, 32, 4, 0, 0, 0, 0, 10, 0, 16, 0, 25, 0, 0, 0, 54, 0, 0, 8, 34, 0, 16, 0, 26, 0, 0, 0, 10, 48, 32, 6, 0, 0, 0, 0, 1, 0, 0, 0, 10, 0, 16, 0, 25, 0, 0, 0, 54, 0, 0, 8, 66, 0, 16, 0, 26, 0, 0, 0, 10, 48, 32, 6, 0, 0, 0, 0, 2, 0, 0, 0, 10, 0, 16, 0, 25, 0, 0, 0, 54, 0, 0, 7, 18, 0, 16, 0, 27, 0, 0, 0, 26, 48, 32, 4, 0, 0, 0, 0, 10, 0, 16, 0, 25, 0, 0, 0, 54, 0, 0, 8, 34, 0, 16, 0, 27, 0, 0, 0, 26, 48, 32, 6, 0, 0, 0, 0, 1, 0, 0, 0, 10, 0, 16, 0, 25, 0, 0, 0, 54, 0, 0, 8, 66, 0, 16, 0, 27, 0, 0, 0, 26, 48, 32, 6, 0, 0, 0, 0, 2, 0, 0, 0, 10, 0, 16, 0, 25, 0, 0, 0, 38, 0, 0, 10, 0, 208, 0, 0, 178, 0, 16, 0, 25, 0, 0, 0, 70, 8, 16, 0, 27, 0, 0, 0, 6, 144, 208, 0, 64, 0, 0, 0, 26, 0, 16, 0, 25, 0, 0, 0, 35, 0, 0, 9, 114, 0, 16, 0, 25, 0, 0, 0, 166, 10, 16, 0, 25, 0, 0, 0, 70, 2, 16, 0, 26, 0, 0, 0, 70, 3, 16, 0, 25, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 25, 0, 0, 0, 70, 2, 16, 0, 25, 0, 0, 0, 2, 64, 0, 0, 32, 0, 0, 0, 32, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 178, 0, 16, 0, 25, 0, 0, 0, 70, 8, 16, 0, 25, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 167, 0, 0, 9, 242, 0, 16, 0, 26, 0, 0, 0, 58, 0, 16, 0, 23, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 79, 0, 0, 7, 114, 0, 16, 0, 27, 0, 0, 0, 70, 3, 16, 0, 25, 0, 0, 0, 70, 2, 16, 0, 26, 0, 0, 0, 54, 0, 0, 5, 66, 0, 16, 0, 25, 0, 0, 0, 10, 0, 16, 0, 26, 0, 0, 0, 55, 0, 0, 9, 146, 0, 16, 0, 27, 0, 0, 0, 6, 0, 16, 0, 27, 0, 0, 0, 166, 2, 16, 0, 25, 0, 0, 0, 6, 8, 16, 0, 25, 0, 0, 0, 54, 0, 0, 5, 82, 0, 16, 0, 25, 0, 0, 0, 86, 6, 16, 0, 26, 0, 0, 0, 55, 0, 0, 9, 242, 0, 16, 0, 25, 0, 0, 0, 86, 10, 16, 0, 27, 0, 0, 0, 70, 14, 16, 0, 25, 0, 0, 0, 22, 11, 16, 0, 25, 0, 0, 0, 79, 0, 0, 7, 18, 0, 16, 0, 26, 0, 0, 0, 1, 64, 0, 0, 255, 0, 0, 0, 58, 0, 16, 0, 26, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 14, 0, 0, 0, 58, 0, 16, 0, 26, 0, 0, 0, 55, 0, 0, 9, 146, 0, 16, 0, 26, 0, 0, 0, 6, 0, 16, 0, 26, 0, 0, 0, 86, 1, 16, 0, 14, 0, 0, 0, 6, 4, 16, 0, 14, 0, 0, 0, 40, 0, 0, 5, 18, 0, 16, 0, 28, 0, 0, 0, 58, 0, 16, 0, 27, 0, 0, 0, 40, 0, 0, 5, 98, 0, 16, 0, 28, 0, 0, 0, 86, 7, 16, 0, 25, 0, 0, 0, 40, 0, 0, 5, 130, 0, 16, 0, 28, 0, 0, 0, 10, 0, 16, 0, 26, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 26, 0, 0, 0, 10, 0, 16, 0, 27, 0, 0, 0, 54, 0, 0, 5, 98, 0, 16, 0, 26, 0, 0, 0, 6, 2, 16, 0, 25, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 25, 0, 0, 0, 70, 14, 16, 0, 28, 0, 0, 0, 70, 14, 16, 0, 26, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 50, 0, 16, 0, 25, 0, 0, 0, 70, 0, 16, 0, 25, 0, 0, 0, 70, 0, 16, 0, 25, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 14, 0, 0, 0, 26, 0, 16, 0, 25, 0, 0, 0, 10, 0, 16, 0, 25, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 14, 0, 0, 0, 42, 0, 16, 0, 25, 0, 0, 0, 42, 0, 16, 0, 25, 0, 0, 0, 10, 0, 16, 0, 14, 0, 0, 0, 86, 0, 0, 5, 18, 0, 16, 0, 14, 0, 0, 0, 10, 0, 16, 0, 14, 0, 0, 0, 86, 0, 0, 5, 18, 0, 16, 0, 25, 0, 0, 0, 58, 0, 16, 0, 25, 0, 0, 0, 56, 0, 0, 7, 18, 0, 16, 0, 25, 0, 0, 0, 10, 0, 16, 0, 25, 0, 0, 0, 10, 0, 16, 0, 25, 0, 0, 0, 50, 0, 0, 10, 18, 0, 16, 0, 14, 0, 0, 0, 10, 0, 16, 0, 25, 0, 0, 0, 42, 128, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 10, 0, 16, 0, 14, 0, 0, 0, 28, 0, 0, 5, 18, 0, 16, 0, 14, 0, 0, 0, 10, 0, 16, 0, 14, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 16, 0, 0, 0, 10, 0, 16, 0, 14, 0, 0, 0, 26, 0, 16, 0, 16, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 23, 0, 0, 0, 58, 0, 16, 0, 23, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 22, 0, 0, 1, 79, 0, 0, 7, 66, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 16, 0, 0, 0, 26, 0, 16, 0, 15, 0, 0, 0, 55, 0, 0, 9, 50, 0, 16, 0, 15, 0, 0, 0, 166, 10, 16, 0, 3, 0, 0, 0, 70, 0, 16, 0, 16, 0, 0, 0, 70, 0, 16, 0, 15, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 16, 0, 0, 0, 10, 0, 16, 0, 16, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 22, 0, 0, 1, 168, 0, 0, 8, 18, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 16, 0, 0, 0, 26, 0, 16, 0, 15, 0, 0, 0, 168, 0, 0, 8, 18, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 24, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 168, 0, 0, 8, 18, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 32, 0, 0, 0, 10, 0, 16, 0, 15, 0, 0, 0, 21, 0, 0, 1, 190, 24, 0, 1, 31, 0, 4, 3, 26, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 8, 18, 0, 16, 0, 2, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 30, 0, 0, 6, 34, 0, 16, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 32, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 24, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 79, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 168, 0, 0, 8, 18, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 16, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 168, 0, 0, 8, 18, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 24, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 168, 0, 0, 8, 18, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 32, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 21, 0, 0, 1, 21, 0, 0, 1, 31, 0, 4, 3, 10, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 8, 18, 0, 16, 0, 2, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 30, 0, 0, 6, 34, 0, 16, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 16, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 24, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 79, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 168, 0, 0, 8, 18, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 16, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 168, 0, 0, 8, 18, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 24, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 168, 0, 0, 8, 18, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 32, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 21, 0, 0, 1, 21, 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 8, 18, 0, 16, 0, 2, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 30, 0, 0, 6, 34, 0, 16, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 8, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 24, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 79, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 168, 0, 0, 8, 18, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 16, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 168, 0, 0, 8, 18, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 24, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 168, 0, 0, 8, 18, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 32, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 21, 0, 0, 1, 21, 0, 0, 1, 31, 0, 4, 3, 58, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 8, 18, 0, 16, 0, 1, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 30, 0, 0, 6, 34, 0, 16, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 4, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 24, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 79, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 168, 0, 0, 8, 18, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 16, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 168, 0, 0, 8, 18, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 24, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 168, 0, 0, 8, 18, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 32, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 21, 0, 0, 1, 21, 0, 0, 1, 79, 0, 0, 9, 98, 0, 16, 0, 0, 0, 0, 0, 6, 64, 2, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 167, 0, 0, 8, 18, 0, 16, 0, 1, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 30, 0, 0, 6, 34, 0, 16, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 2, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 24, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 79, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 168, 0, 0, 8, 18, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 16, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 168, 0, 0, 8, 18, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 24, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 168, 0, 0, 8, 18, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 32, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 21, 0, 0, 1, 21, 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 167, 0, 0, 8, 18, 0, 16, 0, 1, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 30, 0, 0, 6, 34, 0, 16, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 1, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 24, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 79, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 168, 0, 0, 8, 18, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 16, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 168, 0, 0, 8, 18, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 24, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 168, 0, 0, 8, 18, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 32, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 21, 0, 0, 1, 167, 0, 0, 9, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 6, 112, 16, 0, 1, 0, 0, 0, 167, 0, 0, 8, 18, 0, 16, 0, 2, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 79, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 167, 0, 0, 8, 66, 0, 16, 0, 2, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 24, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 167, 0, 0, 8, 130, 0, 16, 0, 2, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 32, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 54, 0, 0, 6, 34, 0, 16, 0, 2, 0, 0, 0, 58, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 1, 167, 0, 0, 9, 242, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 70, 126, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 168, 0, 0, 9, 242, 224, 17, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 21, 0, 0, 1, 62, 0, 0, 1 }; ================================================ FILE: 3rdParty/DirectXTex/DirectXTex/Shaders/Compiled/BC7Encode_TryMode137CS.inc ================================================ #if 0 // // Generated by Microsoft (R) D3D Shader Disassembler // // /// // Input signature: // // Name Index Mask Register SysValue Format Used // -------------------- ----- ------ -------- -------- ------- ------ // no Input // // Output signature: // // Name Index Mask Register SysValue Format Used // -------------------- ----- ------ -------- -------- ------- ------ // no Output cs_4_0 dcl_globalFlags refactoringAllowed dcl_immediateConstantBuffer { { 0x0000cccc, 15, 0, 0}, { 0x00008888, 15, 0, 0}, { 0x0000eeee, 15, 0, 0}, { 0x0000ecc8, 15, 0, 1}, { 0x0000c880, 15, 0, 1}, { 0x0000feec, 15, 0, 1}, { 0x0000fec8, 15, 0, 1}, { 0x0000ec80, 15, 0, 2}, { 0x0000c800, 15, 0, 2}, { 0x0000ffec, 15, 0, 2}, { 0x0000fe80, 15, 0, 2}, { 0x0000e800, 15, 0, 2}, { 0x0000ffe8, 15, 0, 3}, { 0x0000ff00, 15, 0, 3}, { 0x0000fff0, 15, 0, 3}, { 0x0000f000, 15, 0, 3}, { 0x0000f710, 15, 0, 4}, { 142, 2, 0, 4}, { 0x00007100, 8, 0, 4}, { 2254, 2, 0, 4}, { 140, 2, 0, 5}, { 0x00007310, 8, 0, 5}, { 0x00003100, 8, 0, 5}, { 0x00008cce, 15, 0, 5}, { 2188, 2, 0, 6}, { 0x00003110, 8, 0, 6}, { 0x00006666, 2, 0, 6}, { 0x0000366c, 2, 0, 6}, { 6120, 8, 0, 6}, { 4080, 8, 0, 7}, { 0x0000718e, 2, 0, 7}, { 0x0000399c, 2, 0, 7}, { 0x0000aaaa, 15, 0, 7}, { 0x0000f0f0, 15, 0, 8}, { 0x00005a5a, 6, 0, 8}, { 0x000033cc, 8, 0, 8}, { 0x00003c3c, 2, 0, 8}, { 0x000055aa, 8, 0, 9}, { 0x00009696, 15, 0, 9}, { 0x0000a55a, 15, 0, 9}, { 0x000073ce, 2, 0, 9}, { 5064, 8, 0, 10}, { 0x0000324c, 2, 0, 10}, { 0x00003bdc, 2, 0, 10}, { 0x00006996, 2, 0, 10}, { 0x0000c33c, 15, 0, 10}, { 0x00009966, 15, 0, 11}, { 1632, 6, 0, 11}, { 626, 6, 0, 11}, { 1252, 2, 0, 11}, { 0x00004e40, 6, 0, 12}, { 0x00002720, 8, 0, 12}, { 0x0000c936, 15, 0, 12}, { 0x0000936c, 15, 0, 12}, { 0x000039c6, 2, 0, 13}, { 0x0000639c, 2, 0, 13}, { 0x00009336, 15, 0, 13}, { 0x00009cc6, 15, 0, 13}, { 0x0000817e, 15, 0, 14}, { 0x0000e718, 15, 0, 14}, { 0x0000ccf0, 15, 0, 14}, { 4044, 2, 0, 14}, { 0x00007744, 2, 0, 15}, { 0x0000ee22, 15, 0, 15}, { 0, 3, 15, 0}, { 4, 3, 8, 0}, { 9, 15, 8, 0}, { 13, 15, 3, 0}, { 17, 8, 15, 0}, { 21, 3, 15, 1}, { 26, 15, 3, 1}, { 30, 15, 8, 1}, { 34, 8, 15, 1}, { 38, 8, 15, 1}, { 43, 6, 15, 1}, { 47, 6, 15, 1}, { 51, 6, 15, 1}, { 55, 5, 15, 1}, { 60, 3, 15, 2}, { 64, 3, 8, 2}, { 0, 3, 15, 2}, { 9, 3, 8, 2}, { 18, 8, 15, 2}, { 27, 15, 3, 2}, { 37, 3, 15, 2}, { 46, 3, 8, 2}, { 55, 6, 15, 2}, { 64, 10, 8, 3}, { 0, 5, 3, 3}, { 0, 8, 15, 3}, { 0, 8, 6, 3}, { 0, 6, 10, 3}, { 0, 8, 15, 3}, { 0, 5, 15, 3}, { 0, 15, 10, 3}, { 0, 15, 8, 3}, { 0, 8, 15, 3}, { 21, 15, 3, 4}, { 43, 3, 15, 4}, { 64, 5, 10, 4}, { 0, 6, 10, 4}, { 0, 10, 8, 4}, { 0, 8, 9, 4}, { 0, 15, 10, 4}, { 0, 15, 6, 4}, { 0, 3, 15, 4}, { 0, 15, 8, 5}, { 0, 5, 15, 5}, { 0, 15, 3, 5}, { 0, 15, 6, 5}, { 0, 15, 6, 5}, { 0, 15, 8, 5}, { 0, 3, 15, 5}, { 0, 15, 3, 5}, { 0, 5, 15, 5}, { 0, 5, 15, 6}, { 0, 5, 15, 6}, { 0, 8, 15, 6}, { 0, 5, 15, 6}, { 0, 10, 15, 6}, { 0, 5, 15, 6}, { 0, 10, 15, 6}, { 0, 8, 15, 6}, { 0, 13, 15, 6}, { 0, 15, 3, 7}, { 0, 12, 15, 7}, { 0, 3, 15, 7}, { 0, 3, 8, 7}, { 0, 0, 0, 0}, { 0, 0, 0, 0}, { 0, 0, 0, 0}, { 0, 0, 0, 0}, { 0, 0, 0, 0}, { 0, 0, 0, 0}, { 0, 0, 0, 0}, { 0, 0, 0, 0}, { 0, 0, 0, 0}, { 0, 0, 0, 0}, { 0, 0, 0, 0}, { 0, 0, 0, 1}, { 0, 0, 0, 1}, { 0, 0, 0, 1}, { 0, 0, 0, 1}, { 0, 0, 0, 1}, { 0, 0, 0, 1}, { 0, 0, 0, 1}, { 0, 0, 0, 1}, { 0, 0, 0, 1}, { 0, 0, 0, 1}, { 0, 0, 0, 1}, { 0, 0, 0, 1}, { 0, 0, 0, 1}, { 0, 0, 0, 1}, { 0, 0, 0, 1}, { 0, 0, 0, 1}, { 0, 0, 0, 1}, { 0, 0, 0, 1}, { 0, 0, 0, 1}, { 0, 0, 0, 1}, { 0, 0, 0, 1}, { 0, 0, 0, 1}, { 0, 0, 0, 2}, { 0, 0, 0, 2}, { 0, 0, 0, 2}, { 0, 0, 0, 2}, { 0, 0, 0, 2}, { 0, 0, 0, 2}, { 0, 0, 0, 2}, { 0, 0, 0, 2}, { 0, 0, 0, 2}, { 0, 0, 0, 2}, { 0, 0, 0, 2}, { 0, 0, 0, 2}, { 0, 0, 0, 2}, { 0, 0, 0, 2}, { 0, 0, 0, 2}, { 0, 0, 0, 2}, { 0, 0, 0, 2}, { 0, 0, 0, 2}, { 0, 0, 0, 2}, { 0, 0, 0, 2}, { 0, 0, 0, 2}, { 0, 0, 0, 3}, { 0, 0, 0, 3}, { 0, 0, 0, 3}, { 0, 0, 0, 3}, { 0, 0, 0, 3}, { 0, 0, 0, 3}, { 0, 0, 0, 3}, { 0, 0, 0, 3}, { 0, 0, 0, 3}, { 0, 0, 0, 3} } dcl_constantbuffer cb0[2], immediateIndexed dcl_resource_texture2d (float,float,float,float) t0 dcl_resource_structured t1, 16 dcl_uav_structured u0, 16 dcl_input vThreadIDInGroupFlattened dcl_input vThreadGroupID.x dcl_temps 29 dcl_indexableTemp x0[8], 4 dcl_tgsm_structured g0, 100, 64 dcl_thread_group 64, 1, 1 iadd r0.x, vThreadGroupID.x, cb0[1].x ult r1.xyzw, vThreadIDInGroupFlattened.xxxx, l(16, 32, 8, 4) if_nz r1.x udiv r0.y, null, r0.x, cb0[0].y imad r0.z, -r0.y, cb0[0].y, r0.x ishl r0.z, r0.z, l(2) ishl r0.y, r0.y, l(2) and r0.w, vThreadIDInGroupFlattened.x, l(3) iadd r2.x, r0.w, r0.z ushr r0.z, vThreadIDInGroupFlattened.x, l(2) iadd r2.y, r0.z, r0.y mov r2.zw, l(0,0,0,0) ld r2.xyzw, r2.xyzw, t0.xyzw mul r2.xyzw, r2.xyzw, l(255.000000, 255.000000, 255.000000, 255.000000) ftou r2.xyzw, r2.xyzw umin r2.xyzw, r2.xyzw, l(255, 255, 255, 255) store_structured g0.xyzw, vThreadIDInGroupFlattened.x, l(0), r2.xyzw endif sync_g_t mov x0[0].x, l(-1) mov x0[1].x, l(-1) mov x0[2].x, l(-1) mov x0[3].x, l(-1) mov x0[0].y, l(0) mov x0[1].y, l(0) mov x0[2].y, l(0) mov x0[3].y, l(0) mov x0[4].x, l(-1) mov x0[5].x, l(-1) mov x0[6].x, l(-1) mov x0[7].x, l(-1) mov x0[4].y, l(0) mov x0[5].y, l(0) mov x0[6].y, l(0) mov x0[7].y, l(0) mov r0.y, l(0) loop uge r0.z, r0.y, l(16) breakc_nz r0.z ld_structured r2.xyzw, r0.y, l(0), g0.xyzw mov r0.z, vThreadIDInGroupFlattened.x ushr r0.z, icb[r0.z + 0].x, r0.y and r0.z, r0.z, l(1) ieq r0.z, r0.z, l(1) if_nz r0.z mov r3.x, x0[4].x mov r3.y, x0[5].x mov r3.z, x0[6].x mov r3.w, x0[7].x umin r3.xyzw, r2.xyzw, r3.xyzw mov x0[4].x, r3.x mov x0[5].x, r3.y mov x0[6].x, r3.z mov x0[7].x, r3.w mov r3.x, x0[4].y mov r3.y, x0[5].y mov r3.z, x0[6].y mov r3.w, x0[7].y umax r3.xyzw, r2.xyzw, r3.xyzw mov x0[4].y, r3.x mov x0[5].y, r3.y mov x0[6].y, r3.z mov x0[7].y, r3.w else mov r3.x, x0[0].x mov r3.y, x0[1].x mov r3.z, x0[2].x mov r3.w, x0[3].x umin r3.xyzw, r2.xyzw, r3.xyzw mov x0[0].x, r3.x mov x0[1].x, r3.y mov x0[2].x, r3.z mov x0[3].x, r3.w mov r3.x, x0[0].y mov r3.y, x0[1].y mov r3.z, x0[2].y mov r3.w, x0[3].y umax r2.xyzw, r2.xyzw, r3.xyzw mov x0[0].y, r2.x mov x0[1].y, r2.y mov x0[2].y, r2.z mov x0[3].y, r2.w endif iadd r0.y, r0.y, l(1) endloop mov r2.x, x0[0].x mov r2.y, x0[1].x mov r2.z, x0[2].x mov r2.w, x0[3].x mov r3.x, x0[0].y mov r3.y, x0[1].y mov r3.z, x0[2].y mov r3.w, x0[3].y mov r4.x, x0[4].x mov r4.y, x0[5].x mov r4.z, x0[6].x mov r4.w, x0[7].x mov r5.x, x0[4].y mov r5.y, x0[5].y mov r5.z, x0[6].y mov r5.w, x0[7].y ieq r0.y, cb0[0].w, l(1) movc r0.y, r0.y, l(4), l(16) iadd r6.xyz, r2.xyzx, l(1, 1, 1, 0) umin r6.xyz, r6.xyzx, l(255, 255, 255, 0) ushr r6.xyz, r6.xyzx, l(1) and r6.xyz, r6.xyzx, l(126, 126, 126, 0) iadd r7.xyz, r3.xyzx, l(1, 1, 1, 0) umin r7.xyz, r7.xyzx, l(255, 255, 255, 0) ushr r7.xyz, r7.xyzx, l(1) and r7.xyz, r7.xyzx, l(126, 126, 126, 0) iadd r8.xyz, r4.xyzx, l(1, 1, 1, 0) and r9.xyz, r2.xyzx, l(-2, -2, -2, 0) and r10.xyz, r3.xyzx, l(-2, -2, -2, 0) umin r8.xyz, r8.xyzx, l(255, 255, 255, 0) iadd r11.xyzw, r2.xyzw, l(2, 2, 2, 2) umin r11.xyzw, r11.xyzw, l(255, 255, 255, 255) ushr r11.xyzw, r11.xyzw, l(2) and r11.xyzw, r11.xyzw, l(62, 62, 62, 62) iadd r12.xyzw, r3.xyzw, l(2, 2, 2, 2) umin r12.xyzw, r12.xyzw, l(255, 255, 255, 255) ushr r12.xyzw, r12.xyzw, l(2) and r12.xyzw, r12.xyzw, l(62, 62, 62, 62) ushr r8.xyz, r8.xyzx, l(1) and r8.xyz, r8.xyzx, l(126, 126, 126, 0) iadd r13.xyz, r5.xyzx, l(1, 1, 1, 0) umin r13.xyz, r13.xyzx, l(255, 255, 255, 0) ushr r13.xyz, r13.xyzx, l(1) and r13.xyz, r13.xyzx, l(126, 126, 126, 0) and r14.xyz, r4.xyzx, l(-2, -2, -2, 0) and r15.xyz, r5.xyzx, l(-2, -2, -2, 0) iadd r16.xyzw, r4.xyzw, l(2, 2, 2, 2) umin r16.xyzw, r16.xyzw, l(255, 255, 255, 255) ushr r16.xyzw, r16.xyzw, l(2) and r16.xyzw, r16.xyzw, l(62, 62, 62, 62) iadd r17.xyzw, r5.xyzw, l(2, 2, 2, 2) umin r17.xyzw, r17.xyzw, l(255, 255, 255, 255) ushr r17.xyzw, r17.xyzw, l(2) and r17.xyzw, r17.xyzw, l(62, 62, 62, 62) mov r0.z, cb0[0].w mov r0.w, l(0) mov r18.y, l(-1) mov r19.x, l(0) loop uge r6.w, r19.x, r0.y breakc_nz r6.w mov x0[0].x, r2.x mov x0[1].x, r2.y mov x0[2].x, r2.z mov x0[3].x, r2.w mov x0[0].y, r3.x mov x0[1].y, r3.y mov x0[2].y, r3.z mov x0[3].y, r3.w mov x0[4].x, r4.x mov x0[5].x, r4.y mov x0[6].x, r4.z mov x0[7].x, r4.w mov x0[4].y, r5.x mov x0[5].y, r5.y mov x0[6].y, r5.z mov x0[7].y, r5.w ieq r6.w, r0.z, l(1) if_nz r6.w and r6.w, r19.x, l(1) iadd r20.xyz, r6.wwww, r6.xyzx ishl r20.xyz, r20.xyzx, l(1) ushr r21.xyz, r20.xyzx, l(7) iadd r20.xyz, r20.xyzx, r21.xyzx iadd r21.xyz, r6.wwww, r7.xyzx ishl r21.xyz, r21.xyzx, l(1) ushr r22.xyz, r21.xyzx, l(7) iadd r21.xyz, r21.xyzx, r22.xyzx mov x0[0].x, r20.x mov x0[1].x, r20.y mov x0[2].x, r20.z mov x0[3].x, l(255) mov x0[0].y, r21.x mov x0[1].y, r21.y mov x0[2].y, r21.z mov x0[3].y, l(255) ushr r6.w, r19.x, l(1) and r6.w, r6.w, l(1) iadd r20.xyz, r6.wwww, r8.xyzx ishl r20.xyz, r20.xyzx, l(1) ushr r21.xyz, r20.xyzx, l(7) iadd r20.xyz, r20.xyzx, r21.xyzx iadd r21.xyz, r6.wwww, r13.xyzx ishl r21.xyz, r21.xyzx, l(1) ushr r22.xyz, r21.xyzx, l(7) iadd r21.xyz, r21.xyzx, r22.xyzx mov x0[4].x, r20.x mov x0[5].x, r20.y mov x0[6].x, r20.z mov x0[7].x, l(255) mov x0[4].y, r21.x mov x0[5].y, r21.y mov x0[6].y, r21.z mov x0[7].y, l(255) else ieq r6.w, r0.z, l(3) if_nz r6.w ushr r19.y, r19.x, l(1) and r19.zw, r19.xxxy, l(0, 0, 1, 1) iadd r20.xyz, r9.xyzx, r19.zzzz iadd r21.xyz, r10.xyzx, r19.wwww mov x0[0].x, r20.x mov x0[1].x, r20.y mov x0[2].x, r20.z mov x0[3].x, l(255) mov x0[0].y, r21.x mov x0[1].y, r21.y mov x0[2].y, r21.z mov x0[3].y, l(255) else ieq r7.w, r0.z, l(7) if_nz r7.w ushr r19.y, r19.x, l(1) and r19.zw, r19.xxxy, l(0, 0, 1, 1) iadd r20.xyzw, r11.xyzw, r19.zzzz ishl r20.xyzw, r20.xyzw, l(2) ushr r21.xyzw, r20.xyzw, l(6) iadd r20.xyzw, r20.xyzw, r21.xyzw iadd r21.xyzw, r12.xyzw, r19.wwww ishl r21.xyzw, r21.xyzw, l(2) ushr r22.xyzw, r21.xyzw, l(6) iadd r21.xyzw, r21.xyzw, r22.xyzw mov x0[0].x, r20.x mov x0[1].x, r20.y mov x0[2].x, r20.z mov x0[3].x, r20.w mov x0[0].y, r21.x mov x0[1].y, r21.y mov x0[2].y, r21.z mov x0[3].y, r21.w endif endif if_nz r6.w ushr r20.x, r19.x, l(2) ushr r20.y, r19.x, l(3) and r19.zw, r20.xxxy, l(0, 0, 1, 1) iadd r20.xyz, r14.xyzx, r19.zzzz iadd r21.xyz, r15.xyzx, r19.wwww mov x0[4].x, r20.x mov x0[5].x, r20.y mov x0[6].x, r20.z mov x0[7].x, l(255) mov x0[4].y, r21.x mov x0[5].y, r21.y mov x0[6].y, r21.z mov x0[7].y, l(255) else ieq r6.w, r0.z, l(7) if_nz r6.w ushr r20.x, r19.x, l(2) ushr r20.y, r19.x, l(3) and r19.zw, r20.xxxy, l(0, 0, 1, 1) iadd r20.xyzw, r16.xyzw, r19.zzzz ishl r20.xyzw, r20.xyzw, l(2) ushr r21.xyzw, r20.xyzw, l(6) iadd r20.xyzw, r20.xyzw, r21.xyzw iadd r21.xyzw, r17.xyzw, r19.wwww ishl r21.xyzw, r21.xyzw, l(2) ushr r22.xyzw, r21.xyzw, l(6) iadd r21.xyzw, r21.xyzw, r22.xyzw mov x0[4].x, r20.x mov x0[5].x, r20.y mov x0[6].x, r20.z mov x0[7].x, r20.w mov x0[4].y, r21.x mov x0[5].y, r21.y mov x0[6].y, r21.z mov x0[7].y, r21.w endif endif endif mov r20.x, x0[0].y mov r20.y, x0[1].y mov r20.z, x0[2].y mov r20.w, x0[3].y mov r6.w, x0[0].x mov r7.w, x0[1].x mov r8.w, x0[2].x mov r9.w, x0[3].x ineg r21.x, r6.w ineg r21.y, r7.w ineg r21.z, r8.w ineg r21.w, r9.w iadd r22.xyzw, r20.xyzw, r21.xyzw mov r23.x, x0[4].y mov r23.y, x0[5].y mov r23.z, x0[6].y mov r23.w, x0[7].y mov r10.w, x0[4].x mov r13.w, x0[5].x mov r14.w, x0[6].x mov r15.w, x0[7].x ineg r24.x, r10.w ineg r24.y, r13.w ineg r24.z, r14.w ineg r24.w, r15.w iadd r23.xyzw, r23.xyzw, r24.xyzw ine r19.zw, r0.zzzz, l(0, 0, 7, 1) movc r23.w, r19.z, l(0), r23.w movc r22.w, r19.z, l(0), r22.w imul null, r24.xy, r22.xyxx, r22.xyxx iadd r10.w, r24.y, r24.x imad r10.w, r22.z, r22.z, r10.w imad r10.w, r22.w, r22.w, r10.w imul null, r24.xy, r23.xyxx, r23.xyxx iadd r13.w, r24.y, r24.x imad r13.w, r23.z, r23.z, r13.w imad r13.w, r23.w, r23.w, r13.w ld_structured r24.xyzw, l(0), l(0), g0.xyzw iadd r21.xyzw, r21.xyzw, r24.xyzw imul null, r21.xy, r21.xyxx, r22.xyxx iadd r14.w, r21.y, r21.x imad r14.w, r22.z, r21.z, r14.w imad r14.w, r22.w, r21.w, r14.w ilt r15.w, l(0), r10.w ilt r18.w, l(0), r14.w and r15.w, r15.w, r18.w itof r14.w, r14.w mul r14.w, r14.w, l(63.499989) ftou r14.w, r14.w ishl r18.w, r10.w, l(5) ult r14.w, r18.w, r14.w and r14.w, r14.w, r15.w ineg r21.xyzw, r22.xyzw movc r21.xyzw, r14.wwww, r21.xyzw, r22.xyzw movc r15.w, r14.w, r20.x, r6.w mov x0[0].x, r15.w mov r18.w, x0[1].x movc r18.w, r14.w, r20.y, r18.w mov x0[1].x, r18.w mov r20.x, x0[2].x movc r20.x, r14.w, r20.z, r20.x mov x0[2].x, r20.x mov r20.y, x0[3].x movc r20.y, r14.w, r20.w, r20.y mov x0[3].x, r20.y mov r20.z, x0[0].y movc r6.w, r14.w, r6.w, r20.z mov x0[0].y, r6.w mov r6.w, x0[1].y movc r6.w, r14.w, r7.w, r6.w mov x0[1].y, r6.w mov r6.w, x0[2].y movc r6.w, r14.w, r8.w, r6.w mov x0[2].y, r6.w mov r6.w, x0[3].y movc r6.w, r14.w, r9.w, r6.w mov x0[3].y, r6.w mov r6.w, vThreadIDInGroupFlattened.x mov r7.w, icb[r6.w + 0].y ld_structured r22.xyzw, r7.w, l(0), g0.xyzw mov r7.w, x0[4].x mov r8.w, x0[5].x mov r9.w, x0[6].x mov r14.w, x0[7].x ineg r24.x, r7.w ineg r24.y, r8.w ineg r24.z, r9.w ineg r24.w, r14.w iadd r22.xyzw, r22.xyzw, r24.xyzw imul null, r20.zw, r22.xxxy, r23.xxxy iadd r20.z, r20.w, r20.z imad r20.z, r23.z, r22.z, r20.z imad r20.z, r23.w, r22.w, r20.z ilt r20.w, l(0), r13.w ilt r22.x, l(0), r20.z and r20.w, r20.w, r22.x itof r20.z, r20.z mul r20.z, r20.z, l(63.499989) ftou r20.z, r20.z ishl r22.x, r13.w, l(5) ult r20.z, r22.x, r20.z and r20.z, r20.z, r20.w ineg r22.xyzw, r23.xyzw movc r22.xyzw, r20.zzzz, r22.xyzw, r23.xyzw mov r20.w, x0[4].y mov r23.x, x0[5].y mov r23.y, x0[6].y mov r23.z, x0[7].y movc r20.w, r20.z, r20.w, r7.w mov x0[4].x, r20.w mov r23.w, x0[5].x movc r23.x, r20.z, r23.x, r23.w mov x0[5].x, r23.x mov r23.w, x0[6].x movc r23.y, r20.z, r23.y, r23.w mov x0[6].x, r23.y mov r23.w, x0[7].x movc r23.z, r20.z, r23.z, r23.w mov x0[7].x, r23.z mov r23.w, x0[4].y movc r7.w, r20.z, r7.w, r23.w mov x0[4].y, r7.w mov r7.w, x0[5].y movc r7.w, r20.z, r8.w, r7.w mov x0[5].y, r7.w mov r7.w, x0[6].y movc r7.w, r20.z, r9.w, r7.w mov x0[6].y, r7.w mov r7.w, x0[7].y movc r7.w, r20.z, r14.w, r7.w mov x0[7].y, r7.w ineg r24.x, r20.w ineg r24.yzw, r23.xxyz ige r7.w, l(0), r13.w itof r8.w, r13.w movc r23.xyz, r19.wwww, l(32,128,3,0), l(16,64,7,0) ineg r25.x, r15.w ineg r25.y, r18.w ineg r25.zw, r20.xxxy ige r9.w, l(0), r10.w itof r14.w, r10.w mov r15.w, l(0) mov r19.y, l(0) loop uge r18.w, r15.w, l(16) breakc_nz r18.w ushr r18.w, icb[r6.w + 0].x, r15.w and r18.w, r18.w, l(1) ieq r19.w, r18.w, l(1) if_nz r19.w ld_structured r20.xyzw, r15.w, l(0), g0.xyzw iadd r20.xyzw, r24.xyzw, r20.xyzw imul null, r20.xy, r20.xyxx, r22.xyxx iadd r19.w, r20.y, r20.x imad r19.w, r22.z, r20.z, r19.w imad r19.w, r22.w, r20.w, r19.w ige r20.x, l(0), r19.w or r20.x, r7.w, r20.x ilt r20.y, r19.w, r13.w itof r19.w, r19.w mul r19.w, r19.w, l(63.499989) div r19.w, r19.w, r8.w ftou r19.w, r19.w iadd r19.w, r19.w, r23.y movc r19.w, r20.y, icb[r19.w + 0].w, r23.z movc r19.w, r20.x, l(0), r19.w else ld_structured r20.xyzw, r15.w, l(0), g0.xyzw iadd r20.xyzw, r25.xyzw, r20.xyzw imul null, r20.xy, r20.xyxx, r21.xyxx iadd r20.x, r20.y, r20.x imad r20.x, r21.z, r20.z, r20.x imad r20.x, r21.w, r20.w, r20.x ige r20.y, l(0), r20.x or r20.y, r9.w, r20.y ilt r20.z, r20.x, r10.w itof r20.x, r20.x mul r20.x, r20.x, l(63.499989) div r20.x, r20.x, r14.w ftou r20.x, r20.x iadd r20.x, r20.x, r23.y movc r20.x, r20.z, icb[r20.x + 0].w, r23.z movc r19.w, r20.y, l(0), r20.x endif iadd r19.w, r19.w, r23.x iadd r20.x, l(64), -icb[r19.w + 64].x ishl r18.w, r18.w, l(2) mov r26.x, x0[r18.w + 0].x mov r26.y, x0[r18.w + 1].x mov r26.z, x0[r18.w + 2].x mov r26.w, x0[r18.w + 3].x mov r27.x, x0[r18.w + 0].y mov r27.y, x0[r18.w + 1].y mov r27.z, x0[r18.w + 2].y mov r27.w, x0[r18.w + 3].y imul null, r27.xyzw, r27.xyzw, icb[r19.w + 64].xxxx imad r20.xyzw, r20.xxxx, r26.xyzw, r27.xyzw iadd r20.xyzw, r20.xyzw, l(32, 32, 32, 32) ushr r20.xyzw, r20.xzyw, l(6) movc r20.w, r19.z, l(255), r20.w ld_structured r26.xyzw, r15.w, l(0), g0.xyzw ult r27.xyz, r20.xzyx, r26.xyzx mov r28.xz, r26.xxyx mov r28.yw, r20.xxxz movc r28.xyzw, r27.xxyy, r28.xyzw, r28.yxwz mov r20.xz, r26.zzwz movc r20.xy, r27.zzzz, r20.xyxx, r20.yxyy ult r18.w, r20.w, r26.w movc r26.xw, r18.wwww, r20.wwwz, r20.zzzw ineg r27.xy, r28.ywyy ineg r27.z, r20.y ineg r27.w, r26.x mov r26.xy, r28.xzxx mov r26.z, r20.x iadd r20.xyzw, r27.xyzw, r26.xyzw imul null, r20.xy, r20.xyxx, r20.xyxx iadd r18.w, r20.y, r20.x imad r18.w, r20.z, r20.z, r18.w utof r18.w, r18.w utof r19.w, r20.w mul r19.w, r19.w, r19.w mad r18.w, r19.w, cb0[1].z, r18.w ftou r18.w, r18.w iadd r19.y, r18.w, r19.y iadd r15.w, r15.w, l(1) endloop ult r6.w, r19.y, r18.y mov r18.x, r0.w movc r18.xy, r6.wwww, r19.xyxx, r18.xyxx iadd r19.x, r19.x, l(1) mov r0.w, r18.x endloop mov r18.x, cb0[0].w mov r18.z, vThreadIDInGroupFlattened.x store_structured g0.xyz, vThreadIDInGroupFlattened.x, l(16), r18.yxzy store_structured g0.x, vThreadIDInGroupFlattened.x, l(32), r0.w sync_g_t if_nz r1.y iadd r0.y, vThreadIDInGroupFlattened.x, l(32) ld_structured r2.yzw, r0.y, l(16), g0.xxyz ld_structured r3.x, r0.y, l(32), g0.xxxx ult r0.z, r2.y, r18.y if_nz r0.z ld_structured r2.x, r0.y, l(16), g0.xxxx store_structured g0.xyz, vThreadIDInGroupFlattened.x, l(16), r2.xzwx store_structured g0.x, vThreadIDInGroupFlattened.x, l(32), r3.x endif endif if_nz r1.x ld_structured r2.x, vThreadIDInGroupFlattened.x, l(16), g0.xxxx iadd r0.y, vThreadIDInGroupFlattened.x, l(16) ld_structured r3.yzw, r0.y, l(16), g0.xxyz ld_structured r4.x, r0.y, l(32), g0.xxxx ult r0.z, r3.y, r2.x if_nz r0.z ld_structured r3.x, r0.y, l(16), g0.xxxx store_structured g0.xyz, vThreadIDInGroupFlattened.x, l(16), r3.xzwx store_structured g0.x, vThreadIDInGroupFlattened.x, l(32), r4.x endif endif if_nz r1.z ld_structured r2.x, vThreadIDInGroupFlattened.x, l(16), g0.xxxx iadd r0.y, vThreadIDInGroupFlattened.x, l(8) ld_structured r3.yzw, r0.y, l(16), g0.xxyz ld_structured r4.x, r0.y, l(32), g0.xxxx ult r0.z, r3.y, r2.x if_nz r0.z ld_structured r3.x, r0.y, l(16), g0.xxxx store_structured g0.xyz, vThreadIDInGroupFlattened.x, l(16), r3.xzwx store_structured g0.x, vThreadIDInGroupFlattened.x, l(32), r4.x endif endif if_nz r1.w ld_structured r1.x, vThreadIDInGroupFlattened.x, l(16), g0.xxxx iadd r0.y, vThreadIDInGroupFlattened.x, l(4) ld_structured r2.yzw, r0.y, l(16), g0.xxyz ld_structured r3.x, r0.y, l(32), g0.xxxx ult r0.z, r2.y, r1.x if_nz r0.z ld_structured r2.x, r0.y, l(16), g0.xxxx store_structured g0.xyz, vThreadIDInGroupFlattened.x, l(16), r2.xzwx store_structured g0.x, vThreadIDInGroupFlattened.x, l(32), r3.x endif endif ult r0.yz, vThreadIDInGroupFlattened.xxxx, l(0, 2, 1, 0) if_nz r0.y ld_structured r1.x, vThreadIDInGroupFlattened.x, l(16), g0.xxxx iadd r0.y, vThreadIDInGroupFlattened.x, l(2) ld_structured r2.yzw, r0.y, l(16), g0.xxyz ld_structured r3.x, r0.y, l(32), g0.xxxx ult r0.w, r2.y, r1.x if_nz r0.w ld_structured r2.x, r0.y, l(16), g0.xxxx store_structured g0.xyz, vThreadIDInGroupFlattened.x, l(16), r2.xzwx store_structured g0.x, vThreadIDInGroupFlattened.x, l(32), r3.x endif endif if_nz r0.z ld_structured r1.x, vThreadIDInGroupFlattened.x, l(16), g0.xxxx iadd r0.y, vThreadIDInGroupFlattened.x, l(1) ld_structured r2.yzw, r0.y, l(16), g0.xxyz ld_structured r3.x, r0.y, l(32), g0.xxxx ult r0.z, r2.y, r1.x if_nz r0.z ld_structured r2.x, r0.y, l(16), g0.xxxx store_structured g0.xyz, vThreadIDInGroupFlattened.x, l(16), r2.xzwx store_structured g0.x, vThreadIDInGroupFlattened.x, l(32), r3.x endif ld_structured r1.x, r0.x, l(0), t1.xxxx ld_structured r2.x, vThreadIDInGroupFlattened.x, l(16), g0.xxxx ult r0.y, r2.x, r1.x if_nz r0.y ld_structured r1.xyz, vThreadIDInGroupFlattened.x, l(16), g0.xyzx ld_structured r1.w, vThreadIDInGroupFlattened.x, l(32), g0.xxxx else ld_structured r1.xyzw, r0.x, l(0), t1.xyzw endif store_structured u0.xyzw, r0.x, l(0), r1.xyzw endif ret // Approximately 0 instruction slots used #endif const BYTE BC7Encode_TryMode137CS[] = { 68, 88, 66, 67, 24, 142, 44, 233, 135, 73, 185, 32, 139, 70, 101, 2, 121, 203, 167, 180, 1, 0, 0, 0, 144, 73, 0, 0, 3, 0, 0, 0, 44, 0, 0, 0, 60, 0, 0, 0, 76, 0, 0, 0, 73, 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 60, 73, 0, 0, 64, 0, 5, 0, 79, 18, 0, 0, 106, 8, 0, 1, 53, 24, 0, 0, 2, 3, 0, 0, 204, 204, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 136, 136, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 238, 238, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 200, 236, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 128, 200, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 236, 254, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 200, 254, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 128, 236, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 200, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 236, 255, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 128, 254, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 232, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 232, 255, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 255, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 240, 255, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 240, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 16, 247, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 142, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 113, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 206, 8, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 140, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 16, 115, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 49, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 206, 140, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 140, 8, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 16, 49, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 102, 102, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 108, 54, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 232, 23, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 240, 15, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 142, 113, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 156, 57, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 170, 170, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 240, 240, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 90, 90, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 204, 51, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 60, 60, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 170, 85, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 150, 150, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 90, 165, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 206, 115, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 200, 19, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 76, 50, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 220, 59, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 150, 105, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 60, 195, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 102, 153, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 96, 6, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 114, 2, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 228, 4, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 64, 78, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 32, 39, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 54, 201, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 108, 147, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 198, 57, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 156, 99, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 54, 147, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 198, 156, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 126, 129, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 24, 231, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 240, 204, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 204, 15, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 68, 119, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 34, 238, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 15, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 15, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 8, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 3, 0, 0, 0, 15, 0, 0, 0, 1, 0, 0, 0, 26, 0, 0, 0, 15, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 30, 0, 0, 0, 15, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 15, 0, 0, 0, 1, 0, 0, 0, 38, 0, 0, 0, 8, 0, 0, 0, 15, 0, 0, 0, 1, 0, 0, 0, 43, 0, 0, 0, 6, 0, 0, 0, 15, 0, 0, 0, 1, 0, 0, 0, 47, 0, 0, 0, 6, 0, 0, 0, 15, 0, 0, 0, 1, 0, 0, 0, 51, 0, 0, 0, 6, 0, 0, 0, 15, 0, 0, 0, 1, 0, 0, 0, 55, 0, 0, 0, 5, 0, 0, 0, 15, 0, 0, 0, 1, 0, 0, 0, 60, 0, 0, 0, 3, 0, 0, 0, 15, 0, 0, 0, 2, 0, 0, 0, 64, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 15, 0, 0, 0, 2, 0, 0, 0, 9, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 2, 0, 0, 0, 18, 0, 0, 0, 8, 0, 0, 0, 15, 0, 0, 0, 2, 0, 0, 0, 27, 0, 0, 0, 15, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 37, 0, 0, 0, 3, 0, 0, 0, 15, 0, 0, 0, 2, 0, 0, 0, 46, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 2, 0, 0, 0, 55, 0, 0, 0, 6, 0, 0, 0, 15, 0, 0, 0, 2, 0, 0, 0, 64, 0, 0, 0, 10, 0, 0, 0, 8, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 15, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 6, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 10, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 15, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 15, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 10, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 8, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 15, 0, 0, 0, 3, 0, 0, 0, 21, 0, 0, 0, 15, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 43, 0, 0, 0, 3, 0, 0, 0, 15, 0, 0, 0, 4, 0, 0, 0, 64, 0, 0, 0, 5, 0, 0, 0, 10, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 10, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 10, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 15, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 15, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 15, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 15, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 15, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 15, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 15, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 15, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 15, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 15, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 15, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 15, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 89, 0, 0, 4, 70, 142, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 88, 24, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 162, 0, 0, 4, 0, 112, 16, 0, 1, 0, 0, 0, 16, 0, 0, 0, 158, 0, 0, 4, 0, 224, 17, 0, 0, 0, 0, 0, 16, 0, 0, 0, 95, 0, 0, 2, 0, 64, 2, 0, 95, 0, 0, 2, 18, 16, 2, 0, 104, 0, 0, 2, 29, 0, 0, 0, 105, 0, 0, 4, 0, 0, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 160, 0, 0, 5, 0, 240, 17, 0, 0, 0, 0, 0, 100, 0, 0, 0, 64, 0, 0, 0, 155, 0, 0, 4, 64, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 16, 2, 0, 10, 128, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 79, 0, 0, 9, 242, 0, 16, 0, 1, 0, 0, 0, 6, 64, 2, 0, 2, 64, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 1, 0, 0, 0, 78, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 0, 208, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 11, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 128, 65, 0, 0, 0, 0, 0, 0, 0, 26, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 0, 0, 6, 130, 0, 16, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 3, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 85, 0, 0, 6, 66, 0, 16, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 2, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 7, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, 127, 67, 28, 0, 0, 5, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 84, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 168, 0, 0, 8, 242, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 0, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 21, 0, 0, 1, 190, 24, 0, 1, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 255, 255, 255, 255, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 255, 255, 255, 255, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 255, 255, 255, 255, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 255, 255, 255, 255, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 64, 0, 0, 255, 255, 255, 255, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 5, 0, 0, 0, 1, 64, 0, 0, 255, 255, 255, 255, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, 255, 255, 255, 255, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 7, 0, 0, 0, 1, 64, 0, 0, 255, 255, 255, 255, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 5, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 7, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 48, 0, 0, 1, 80, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 3, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 167, 0, 0, 9, 242, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 54, 0, 0, 4, 66, 0, 16, 0, 0, 0, 0, 0, 10, 64, 2, 0, 85, 0, 0, 8, 66, 0, 16, 0, 0, 0, 0, 0, 10, 144, 144, 0, 42, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 32, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 0, 16, 0, 3, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 4, 0, 0, 0, 54, 0, 0, 6, 34, 0, 16, 0, 3, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 5, 0, 0, 0, 54, 0, 0, 6, 66, 0, 16, 0, 3, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 6, 0, 0, 0, 54, 0, 0, 6, 130, 0, 16, 0, 3, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 7, 0, 0, 0, 84, 0, 0, 7, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 4, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 5, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 6, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 7, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 54, 0, 0, 6, 18, 0, 16, 0, 3, 0, 0, 0, 26, 48, 32, 0, 0, 0, 0, 0, 4, 0, 0, 0, 54, 0, 0, 6, 34, 0, 16, 0, 3, 0, 0, 0, 26, 48, 32, 0, 0, 0, 0, 0, 5, 0, 0, 0, 54, 0, 0, 6, 66, 0, 16, 0, 3, 0, 0, 0, 26, 48, 32, 0, 0, 0, 0, 0, 6, 0, 0, 0, 54, 0, 0, 6, 130, 0, 16, 0, 3, 0, 0, 0, 26, 48, 32, 0, 0, 0, 0, 0, 7, 0, 0, 0, 83, 0, 0, 7, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 4, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 5, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 6, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 7, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 6, 18, 0, 16, 0, 3, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 34, 0, 16, 0, 3, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 54, 0, 0, 6, 66, 0, 16, 0, 3, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 54, 0, 0, 6, 130, 0, 16, 0, 3, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 3, 0, 0, 0, 84, 0, 0, 7, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 3, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 54, 0, 0, 6, 18, 0, 16, 0, 3, 0, 0, 0, 26, 48, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 34, 0, 16, 0, 3, 0, 0, 0, 26, 48, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 54, 0, 0, 6, 66, 0, 16, 0, 3, 0, 0, 0, 26, 48, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 54, 0, 0, 6, 130, 0, 16, 0, 3, 0, 0, 0, 26, 48, 32, 0, 0, 0, 0, 0, 3, 0, 0, 0, 83, 0, 0, 7, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 3, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 21, 0, 0, 1, 30, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 22, 0, 0, 1, 54, 0, 0, 6, 18, 0, 16, 0, 2, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 34, 0, 16, 0, 2, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 54, 0, 0, 6, 66, 0, 16, 0, 2, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 54, 0, 0, 6, 130, 0, 16, 0, 2, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 3, 0, 0, 0, 54, 0, 0, 6, 18, 0, 16, 0, 3, 0, 0, 0, 26, 48, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 34, 0, 16, 0, 3, 0, 0, 0, 26, 48, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 54, 0, 0, 6, 66, 0, 16, 0, 3, 0, 0, 0, 26, 48, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 54, 0, 0, 6, 130, 0, 16, 0, 3, 0, 0, 0, 26, 48, 32, 0, 0, 0, 0, 0, 3, 0, 0, 0, 54, 0, 0, 6, 18, 0, 16, 0, 4, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 4, 0, 0, 0, 54, 0, 0, 6, 34, 0, 16, 0, 4, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 5, 0, 0, 0, 54, 0, 0, 6, 66, 0, 16, 0, 4, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 6, 0, 0, 0, 54, 0, 0, 6, 130, 0, 16, 0, 4, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 7, 0, 0, 0, 54, 0, 0, 6, 18, 0, 16, 0, 5, 0, 0, 0, 26, 48, 32, 0, 0, 0, 0, 0, 4, 0, 0, 0, 54, 0, 0, 6, 34, 0, 16, 0, 5, 0, 0, 0, 26, 48, 32, 0, 0, 0, 0, 0, 5, 0, 0, 0, 54, 0, 0, 6, 66, 0, 16, 0, 5, 0, 0, 0, 26, 48, 32, 0, 0, 0, 0, 0, 6, 0, 0, 0, 54, 0, 0, 6, 130, 0, 16, 0, 5, 0, 0, 0, 26, 48, 32, 0, 0, 0, 0, 0, 7, 0, 0, 0, 32, 0, 0, 8, 34, 0, 16, 0, 0, 0, 0, 0, 58, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 55, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 84, 0, 0, 10, 114, 0, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 114, 0, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 126, 0, 0, 0, 126, 0, 0, 0, 126, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 84, 0, 0, 10, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 126, 0, 0, 0, 126, 0, 0, 0, 126, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 9, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 254, 255, 255, 255, 254, 255, 255, 255, 254, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 254, 255, 255, 255, 254, 255, 255, 255, 254, 255, 255, 255, 0, 0, 0, 0, 84, 0, 0, 10, 114, 0, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 84, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 85, 0, 0, 7, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 84, 0, 0, 10, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 85, 0, 0, 7, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 12, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 85, 0, 0, 7, 114, 0, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 126, 0, 0, 0, 126, 0, 0, 0, 126, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 84, 0, 0, 10, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 126, 0, 0, 0, 126, 0, 0, 0, 126, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 14, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 254, 255, 255, 255, 254, 255, 255, 255, 254, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 15, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 254, 255, 255, 255, 254, 255, 255, 255, 254, 255, 255, 255, 0, 0, 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, 16, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 84, 0, 0, 10, 242, 0, 16, 0, 16, 0, 0, 0, 70, 14, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 85, 0, 0, 7, 242, 0, 16, 0, 16, 0, 0, 0, 70, 14, 16, 0, 16, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 16, 0, 0, 0, 70, 14, 16, 0, 16, 0, 0, 0, 2, 64, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, 17, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 84, 0, 0, 10, 242, 0, 16, 0, 17, 0, 0, 0, 70, 14, 16, 0, 17, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 85, 0, 0, 7, 242, 0, 16, 0, 17, 0, 0, 0, 70, 14, 16, 0, 17, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 17, 0, 0, 0, 70, 14, 16, 0, 17, 0, 0, 0, 2, 64, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 62, 0, 0, 0, 54, 0, 0, 6, 66, 0, 16, 0, 0, 0, 0, 0, 58, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 34, 0, 16, 0, 18, 0, 0, 0, 1, 64, 0, 0, 255, 255, 255, 255, 54, 0, 0, 5, 18, 0, 16, 0, 19, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 48, 0, 0, 1, 80, 0, 0, 7, 130, 0, 16, 0, 6, 0, 0, 0, 10, 0, 16, 0, 19, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 3, 0, 4, 3, 58, 0, 16, 0, 6, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 3, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 3, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 4, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 5, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 6, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 7, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 4, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 5, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 6, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 7, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 32, 0, 0, 7, 130, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 6, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 6, 0, 0, 0, 10, 0, 16, 0, 19, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 20, 0, 0, 0, 246, 15, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 41, 0, 0, 7, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 114, 0, 16, 0, 21, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 21, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 21, 0, 0, 0, 246, 15, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 41, 0, 0, 7, 114, 0, 16, 0, 21, 0, 0, 0, 70, 2, 16, 0, 21, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 114, 0, 16, 0, 22, 0, 0, 0, 70, 2, 16, 0, 21, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 21, 0, 0, 0, 70, 2, 16, 0, 21, 0, 0, 0, 70, 2, 16, 0, 22, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 20, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 26, 0, 16, 0, 20, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 42, 0, 16, 0, 20, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 255, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 21, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 26, 0, 16, 0, 21, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 42, 0, 16, 0, 21, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 255, 0, 0, 0, 85, 0, 0, 7, 130, 0, 16, 0, 6, 0, 0, 0, 10, 0, 16, 0, 19, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 20, 0, 0, 0, 246, 15, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 41, 0, 0, 7, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 114, 0, 16, 0, 21, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 21, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 21, 0, 0, 0, 246, 15, 16, 0, 6, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 41, 0, 0, 7, 114, 0, 16, 0, 21, 0, 0, 0, 70, 2, 16, 0, 21, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 85, 0, 0, 7, 114, 0, 16, 0, 22, 0, 0, 0, 70, 2, 16, 0, 21, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 21, 0, 0, 0, 70, 2, 16, 0, 21, 0, 0, 0, 70, 2, 16, 0, 22, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 4, 0, 0, 0, 10, 0, 16, 0, 20, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 5, 0, 0, 0, 26, 0, 16, 0, 20, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 6, 0, 0, 0, 42, 0, 16, 0, 20, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 7, 0, 0, 0, 1, 64, 0, 0, 255, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 4, 0, 0, 0, 10, 0, 16, 0, 21, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 5, 0, 0, 0, 26, 0, 16, 0, 21, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 6, 0, 0, 0, 42, 0, 16, 0, 21, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 7, 0, 0, 0, 1, 64, 0, 0, 255, 0, 0, 0, 18, 0, 0, 1, 32, 0, 0, 7, 130, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 6, 0, 0, 0, 85, 0, 0, 7, 34, 0, 16, 0, 19, 0, 0, 0, 10, 0, 16, 0, 19, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 19, 0, 0, 0, 6, 4, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 166, 10, 16, 0, 19, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 21, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 246, 15, 16, 0, 19, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 20, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 26, 0, 16, 0, 20, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 42, 0, 16, 0, 20, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 255, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 21, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 26, 0, 16, 0, 21, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 42, 0, 16, 0, 21, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 64, 0, 0, 255, 0, 0, 0, 18, 0, 0, 1, 32, 0, 0, 7, 130, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 7, 0, 0, 0, 85, 0, 0, 7, 34, 0, 16, 0, 19, 0, 0, 0, 10, 0, 16, 0, 19, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 19, 0, 0, 0, 6, 4, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 20, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 166, 10, 16, 0, 19, 0, 0, 0, 41, 0, 0, 7, 242, 0, 16, 0, 20, 0, 0, 0, 70, 14, 16, 0, 20, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 85, 0, 0, 7, 242, 0, 16, 0, 21, 0, 0, 0, 70, 14, 16, 0, 20, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 20, 0, 0, 0, 70, 14, 16, 0, 20, 0, 0, 0, 70, 14, 16, 0, 21, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 21, 0, 0, 0, 70, 14, 16, 0, 12, 0, 0, 0, 246, 15, 16, 0, 19, 0, 0, 0, 41, 0, 0, 7, 242, 0, 16, 0, 21, 0, 0, 0, 70, 14, 16, 0, 21, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 85, 0, 0, 7, 242, 0, 16, 0, 22, 0, 0, 0, 70, 14, 16, 0, 21, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 21, 0, 0, 0, 70, 14, 16, 0, 21, 0, 0, 0, 70, 14, 16, 0, 22, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 20, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 26, 0, 16, 0, 20, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 42, 0, 16, 0, 20, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 3, 0, 0, 0, 58, 0, 16, 0, 20, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 21, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 26, 0, 16, 0, 21, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 42, 0, 16, 0, 21, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 3, 0, 0, 0, 58, 0, 16, 0, 21, 0, 0, 0, 21, 0, 0, 1, 21, 0, 0, 1, 31, 0, 4, 3, 58, 0, 16, 0, 6, 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 20, 0, 0, 0, 10, 0, 16, 0, 19, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 85, 0, 0, 7, 34, 0, 16, 0, 20, 0, 0, 0, 10, 0, 16, 0, 19, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 19, 0, 0, 0, 6, 4, 16, 0, 20, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 166, 10, 16, 0, 19, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 21, 0, 0, 0, 70, 2, 16, 0, 15, 0, 0, 0, 246, 15, 16, 0, 19, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 4, 0, 0, 0, 10, 0, 16, 0, 20, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 5, 0, 0, 0, 26, 0, 16, 0, 20, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 6, 0, 0, 0, 42, 0, 16, 0, 20, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 7, 0, 0, 0, 1, 64, 0, 0, 255, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 4, 0, 0, 0, 10, 0, 16, 0, 21, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 5, 0, 0, 0, 26, 0, 16, 0, 21, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 6, 0, 0, 0, 42, 0, 16, 0, 21, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 7, 0, 0, 0, 1, 64, 0, 0, 255, 0, 0, 0, 18, 0, 0, 1, 32, 0, 0, 7, 130, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 6, 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 20, 0, 0, 0, 10, 0, 16, 0, 19, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 85, 0, 0, 7, 34, 0, 16, 0, 20, 0, 0, 0, 10, 0, 16, 0, 19, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 19, 0, 0, 0, 6, 4, 16, 0, 20, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 20, 0, 0, 0, 70, 14, 16, 0, 16, 0, 0, 0, 166, 10, 16, 0, 19, 0, 0, 0, 41, 0, 0, 7, 242, 0, 16, 0, 20, 0, 0, 0, 70, 14, 16, 0, 20, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 85, 0, 0, 7, 242, 0, 16, 0, 21, 0, 0, 0, 70, 14, 16, 0, 20, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 20, 0, 0, 0, 70, 14, 16, 0, 20, 0, 0, 0, 70, 14, 16, 0, 21, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 21, 0, 0, 0, 70, 14, 16, 0, 17, 0, 0, 0, 246, 15, 16, 0, 19, 0, 0, 0, 41, 0, 0, 7, 242, 0, 16, 0, 21, 0, 0, 0, 70, 14, 16, 0, 21, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 85, 0, 0, 7, 242, 0, 16, 0, 22, 0, 0, 0, 70, 14, 16, 0, 21, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 21, 0, 0, 0, 70, 14, 16, 0, 21, 0, 0, 0, 70, 14, 16, 0, 22, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 4, 0, 0, 0, 10, 0, 16, 0, 20, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 5, 0, 0, 0, 26, 0, 16, 0, 20, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 6, 0, 0, 0, 42, 0, 16, 0, 20, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 7, 0, 0, 0, 58, 0, 16, 0, 20, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 4, 0, 0, 0, 10, 0, 16, 0, 21, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 5, 0, 0, 0, 26, 0, 16, 0, 21, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 6, 0, 0, 0, 42, 0, 16, 0, 21, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 7, 0, 0, 0, 58, 0, 16, 0, 21, 0, 0, 0, 21, 0, 0, 1, 21, 0, 0, 1, 21, 0, 0, 1, 54, 0, 0, 6, 18, 0, 16, 0, 20, 0, 0, 0, 26, 48, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 34, 0, 16, 0, 20, 0, 0, 0, 26, 48, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 54, 0, 0, 6, 66, 0, 16, 0, 20, 0, 0, 0, 26, 48, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 54, 0, 0, 6, 130, 0, 16, 0, 20, 0, 0, 0, 26, 48, 32, 0, 0, 0, 0, 0, 3, 0, 0, 0, 54, 0, 0, 6, 130, 0, 16, 0, 6, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 130, 0, 16, 0, 7, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 54, 0, 0, 6, 130, 0, 16, 0, 8, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 54, 0, 0, 6, 130, 0, 16, 0, 9, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 3, 0, 0, 0, 40, 0, 0, 5, 18, 0, 16, 0, 21, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 40, 0, 0, 5, 34, 0, 16, 0, 21, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 40, 0, 0, 5, 66, 0, 16, 0, 21, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 40, 0, 0, 5, 130, 0, 16, 0, 21, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 22, 0, 0, 0, 70, 14, 16, 0, 20, 0, 0, 0, 70, 14, 16, 0, 21, 0, 0, 0, 54, 0, 0, 6, 18, 0, 16, 0, 23, 0, 0, 0, 26, 48, 32, 0, 0, 0, 0, 0, 4, 0, 0, 0, 54, 0, 0, 6, 34, 0, 16, 0, 23, 0, 0, 0, 26, 48, 32, 0, 0, 0, 0, 0, 5, 0, 0, 0, 54, 0, 0, 6, 66, 0, 16, 0, 23, 0, 0, 0, 26, 48, 32, 0, 0, 0, 0, 0, 6, 0, 0, 0, 54, 0, 0, 6, 130, 0, 16, 0, 23, 0, 0, 0, 26, 48, 32, 0, 0, 0, 0, 0, 7, 0, 0, 0, 54, 0, 0, 6, 130, 0, 16, 0, 10, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 4, 0, 0, 0, 54, 0, 0, 6, 130, 0, 16, 0, 13, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 5, 0, 0, 0, 54, 0, 0, 6, 130, 0, 16, 0, 14, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 6, 0, 0, 0, 54, 0, 0, 6, 130, 0, 16, 0, 15, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 7, 0, 0, 0, 40, 0, 0, 5, 18, 0, 16, 0, 24, 0, 0, 0, 58, 0, 16, 0, 10, 0, 0, 0, 40, 0, 0, 5, 34, 0, 16, 0, 24, 0, 0, 0, 58, 0, 16, 0, 13, 0, 0, 0, 40, 0, 0, 5, 66, 0, 16, 0, 24, 0, 0, 0, 58, 0, 16, 0, 14, 0, 0, 0, 40, 0, 0, 5, 130, 0, 16, 0, 24, 0, 0, 0, 58, 0, 16, 0, 15, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 23, 0, 0, 0, 70, 14, 16, 0, 23, 0, 0, 0, 70, 14, 16, 0, 24, 0, 0, 0, 39, 0, 0, 10, 194, 0, 16, 0, 19, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 1, 0, 0, 0, 55, 0, 0, 9, 130, 0, 16, 0, 23, 0, 0, 0, 42, 0, 16, 0, 19, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 23, 0, 0, 0, 55, 0, 0, 9, 130, 0, 16, 0, 22, 0, 0, 0, 42, 0, 16, 0, 19, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 22, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 50, 0, 16, 0, 24, 0, 0, 0, 70, 0, 16, 0, 22, 0, 0, 0, 70, 0, 16, 0, 22, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 10, 0, 0, 0, 26, 0, 16, 0, 24, 0, 0, 0, 10, 0, 16, 0, 24, 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 10, 0, 0, 0, 42, 0, 16, 0, 22, 0, 0, 0, 42, 0, 16, 0, 22, 0, 0, 0, 58, 0, 16, 0, 10, 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, 0, 22, 0, 0, 0, 58, 0, 16, 0, 22, 0, 0, 0, 58, 0, 16, 0, 10, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 50, 0, 16, 0, 24, 0, 0, 0, 70, 0, 16, 0, 23, 0, 0, 0, 70, 0, 16, 0, 23, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 13, 0, 0, 0, 26, 0, 16, 0, 24, 0, 0, 0, 10, 0, 16, 0, 24, 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 13, 0, 0, 0, 42, 0, 16, 0, 23, 0, 0, 0, 42, 0, 16, 0, 23, 0, 0, 0, 58, 0, 16, 0, 13, 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 13, 0, 0, 0, 58, 0, 16, 0, 23, 0, 0, 0, 58, 0, 16, 0, 23, 0, 0, 0, 58, 0, 16, 0, 13, 0, 0, 0, 167, 0, 0, 9, 242, 0, 16, 0, 24, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 21, 0, 0, 0, 70, 14, 16, 0, 21, 0, 0, 0, 70, 14, 16, 0, 24, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 50, 0, 16, 0, 21, 0, 0, 0, 70, 0, 16, 0, 21, 0, 0, 0, 70, 0, 16, 0, 22, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 14, 0, 0, 0, 26, 0, 16, 0, 21, 0, 0, 0, 10, 0, 16, 0, 21, 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 14, 0, 0, 0, 42, 0, 16, 0, 22, 0, 0, 0, 42, 0, 16, 0, 21, 0, 0, 0, 58, 0, 16, 0, 14, 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 14, 0, 0, 0, 58, 0, 16, 0, 22, 0, 0, 0, 58, 0, 16, 0, 21, 0, 0, 0, 58, 0, 16, 0, 14, 0, 0, 0, 34, 0, 0, 7, 130, 0, 16, 0, 15, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 10, 0, 0, 0, 34, 0, 0, 7, 130, 0, 16, 0, 18, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 14, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 15, 0, 0, 0, 58, 0, 16, 0, 15, 0, 0, 0, 58, 0, 16, 0, 18, 0, 0, 0, 43, 0, 0, 5, 130, 0, 16, 0, 14, 0, 0, 0, 58, 0, 16, 0, 14, 0, 0, 0, 56, 0, 0, 7, 130, 0, 16, 0, 14, 0, 0, 0, 58, 0, 16, 0, 14, 0, 0, 0, 1, 64, 0, 0, 253, 255, 125, 66, 28, 0, 0, 5, 130, 0, 16, 0, 14, 0, 0, 0, 58, 0, 16, 0, 14, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 18, 0, 0, 0, 58, 0, 16, 0, 10, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 79, 0, 0, 7, 130, 0, 16, 0, 14, 0, 0, 0, 58, 0, 16, 0, 18, 0, 0, 0, 58, 0, 16, 0, 14, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 14, 0, 0, 0, 58, 0, 16, 0, 14, 0, 0, 0, 58, 0, 16, 0, 15, 0, 0, 0, 40, 0, 0, 5, 242, 0, 16, 0, 21, 0, 0, 0, 70, 14, 16, 0, 22, 0, 0, 0, 55, 0, 0, 9, 242, 0, 16, 0, 21, 0, 0, 0, 246, 15, 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, 21, 0, 0, 0, 70, 14, 16, 0, 22, 0, 0, 0, 55, 0, 0, 9, 130, 0, 16, 0, 15, 0, 0, 0, 58, 0, 16, 0, 14, 0, 0, 0, 10, 0, 16, 0, 20, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 15, 0, 0, 0, 54, 0, 0, 6, 130, 0, 16, 0, 18, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 55, 0, 0, 9, 130, 0, 16, 0, 18, 0, 0, 0, 58, 0, 16, 0, 14, 0, 0, 0, 26, 0, 16, 0, 20, 0, 0, 0, 58, 0, 16, 0, 18, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 58, 0, 16, 0, 18, 0, 0, 0, 54, 0, 0, 6, 18, 0, 16, 0, 20, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 55, 0, 0, 9, 18, 0, 16, 0, 20, 0, 0, 0, 58, 0, 16, 0, 14, 0, 0, 0, 42, 0, 16, 0, 20, 0, 0, 0, 10, 0, 16, 0, 20, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 10, 0, 16, 0, 20, 0, 0, 0, 54, 0, 0, 6, 34, 0, 16, 0, 20, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 3, 0, 0, 0, 55, 0, 0, 9, 34, 0, 16, 0, 20, 0, 0, 0, 58, 0, 16, 0, 14, 0, 0, 0, 58, 0, 16, 0, 20, 0, 0, 0, 26, 0, 16, 0, 20, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 3, 0, 0, 0, 26, 0, 16, 0, 20, 0, 0, 0, 54, 0, 0, 6, 66, 0, 16, 0, 20, 0, 0, 0, 26, 48, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 130, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 14, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 42, 0, 16, 0, 20, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 54, 0, 0, 6, 130, 0, 16, 0, 6, 0, 0, 0, 26, 48, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 55, 0, 0, 9, 130, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 14, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 54, 0, 0, 6, 130, 0, 16, 0, 6, 0, 0, 0, 26, 48, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 55, 0, 0, 9, 130, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 14, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 54, 0, 0, 6, 130, 0, 16, 0, 6, 0, 0, 0, 26, 48, 32, 0, 0, 0, 0, 0, 3, 0, 0, 0, 55, 0, 0, 9, 130, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 14, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 3, 0, 0, 0, 58, 0, 16, 0, 6, 0, 0, 0, 54, 0, 0, 4, 130, 0, 16, 0, 6, 0, 0, 0, 10, 64, 2, 0, 54, 0, 0, 6, 130, 0, 16, 0, 7, 0, 0, 0, 26, 144, 144, 0, 58, 0, 16, 0, 6, 0, 0, 0, 167, 0, 0, 9, 242, 0, 16, 0, 22, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 54, 0, 0, 6, 130, 0, 16, 0, 7, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 4, 0, 0, 0, 54, 0, 0, 6, 130, 0, 16, 0, 8, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 5, 0, 0, 0, 54, 0, 0, 6, 130, 0, 16, 0, 9, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 6, 0, 0, 0, 54, 0, 0, 6, 130, 0, 16, 0, 14, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 7, 0, 0, 0, 40, 0, 0, 5, 18, 0, 16, 0, 24, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 40, 0, 0, 5, 34, 0, 16, 0, 24, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 40, 0, 0, 5, 66, 0, 16, 0, 24, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 40, 0, 0, 5, 130, 0, 16, 0, 24, 0, 0, 0, 58, 0, 16, 0, 14, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 22, 0, 0, 0, 70, 14, 16, 0, 22, 0, 0, 0, 70, 14, 16, 0, 24, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 194, 0, 16, 0, 20, 0, 0, 0, 6, 4, 16, 0, 22, 0, 0, 0, 6, 4, 16, 0, 23, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 20, 0, 0, 0, 58, 0, 16, 0, 20, 0, 0, 0, 42, 0, 16, 0, 20, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 20, 0, 0, 0, 42, 0, 16, 0, 23, 0, 0, 0, 42, 0, 16, 0, 22, 0, 0, 0, 42, 0, 16, 0, 20, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 20, 0, 0, 0, 58, 0, 16, 0, 23, 0, 0, 0, 58, 0, 16, 0, 22, 0, 0, 0, 42, 0, 16, 0, 20, 0, 0, 0, 34, 0, 0, 7, 130, 0, 16, 0, 20, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 13, 0, 0, 0, 34, 0, 0, 7, 18, 0, 16, 0, 22, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 20, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 20, 0, 0, 0, 58, 0, 16, 0, 20, 0, 0, 0, 10, 0, 16, 0, 22, 0, 0, 0, 43, 0, 0, 5, 66, 0, 16, 0, 20, 0, 0, 0, 42, 0, 16, 0, 20, 0, 0, 0, 56, 0, 0, 7, 66, 0, 16, 0, 20, 0, 0, 0, 42, 0, 16, 0, 20, 0, 0, 0, 1, 64, 0, 0, 253, 255, 125, 66, 28, 0, 0, 5, 66, 0, 16, 0, 20, 0, 0, 0, 42, 0, 16, 0, 20, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 22, 0, 0, 0, 58, 0, 16, 0, 13, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 79, 0, 0, 7, 66, 0, 16, 0, 20, 0, 0, 0, 10, 0, 16, 0, 22, 0, 0, 0, 42, 0, 16, 0, 20, 0, 0, 0, 1, 0, 0, 7, 66, 0, 16, 0, 20, 0, 0, 0, 42, 0, 16, 0, 20, 0, 0, 0, 58, 0, 16, 0, 20, 0, 0, 0, 40, 0, 0, 5, 242, 0, 16, 0, 22, 0, 0, 0, 70, 14, 16, 0, 23, 0, 0, 0, 55, 0, 0, 9, 242, 0, 16, 0, 22, 0, 0, 0, 166, 10, 16, 0, 20, 0, 0, 0, 70, 14, 16, 0, 22, 0, 0, 0, 70, 14, 16, 0, 23, 0, 0, 0, 54, 0, 0, 6, 130, 0, 16, 0, 20, 0, 0, 0, 26, 48, 32, 0, 0, 0, 0, 0, 4, 0, 0, 0, 54, 0, 0, 6, 18, 0, 16, 0, 23, 0, 0, 0, 26, 48, 32, 0, 0, 0, 0, 0, 5, 0, 0, 0, 54, 0, 0, 6, 34, 0, 16, 0, 23, 0, 0, 0, 26, 48, 32, 0, 0, 0, 0, 0, 6, 0, 0, 0, 54, 0, 0, 6, 66, 0, 16, 0, 23, 0, 0, 0, 26, 48, 32, 0, 0, 0, 0, 0, 7, 0, 0, 0, 55, 0, 0, 9, 130, 0, 16, 0, 20, 0, 0, 0, 42, 0, 16, 0, 20, 0, 0, 0, 58, 0, 16, 0, 20, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 4, 0, 0, 0, 58, 0, 16, 0, 20, 0, 0, 0, 54, 0, 0, 6, 130, 0, 16, 0, 23, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 5, 0, 0, 0, 55, 0, 0, 9, 18, 0, 16, 0, 23, 0, 0, 0, 42, 0, 16, 0, 20, 0, 0, 0, 10, 0, 16, 0, 23, 0, 0, 0, 58, 0, 16, 0, 23, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 5, 0, 0, 0, 10, 0, 16, 0, 23, 0, 0, 0, 54, 0, 0, 6, 130, 0, 16, 0, 23, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 6, 0, 0, 0, 55, 0, 0, 9, 34, 0, 16, 0, 23, 0, 0, 0, 42, 0, 16, 0, 20, 0, 0, 0, 26, 0, 16, 0, 23, 0, 0, 0, 58, 0, 16, 0, 23, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 6, 0, 0, 0, 26, 0, 16, 0, 23, 0, 0, 0, 54, 0, 0, 6, 130, 0, 16, 0, 23, 0, 0, 0, 10, 48, 32, 0, 0, 0, 0, 0, 7, 0, 0, 0, 55, 0, 0, 9, 66, 0, 16, 0, 23, 0, 0, 0, 42, 0, 16, 0, 20, 0, 0, 0, 42, 0, 16, 0, 23, 0, 0, 0, 58, 0, 16, 0, 23, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 7, 0, 0, 0, 42, 0, 16, 0, 23, 0, 0, 0, 54, 0, 0, 6, 130, 0, 16, 0, 23, 0, 0, 0, 26, 48, 32, 0, 0, 0, 0, 0, 4, 0, 0, 0, 55, 0, 0, 9, 130, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 20, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 23, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 4, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 54, 0, 0, 6, 130, 0, 16, 0, 7, 0, 0, 0, 26, 48, 32, 0, 0, 0, 0, 0, 5, 0, 0, 0, 55, 0, 0, 9, 130, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 20, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 5, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 54, 0, 0, 6, 130, 0, 16, 0, 7, 0, 0, 0, 26, 48, 32, 0, 0, 0, 0, 0, 6, 0, 0, 0, 55, 0, 0, 9, 130, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 20, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 6, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 54, 0, 0, 6, 130, 0, 16, 0, 7, 0, 0, 0, 26, 48, 32, 0, 0, 0, 0, 0, 7, 0, 0, 0, 55, 0, 0, 9, 130, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 20, 0, 0, 0, 58, 0, 16, 0, 14, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 54, 0, 0, 6, 34, 48, 32, 0, 0, 0, 0, 0, 7, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 40, 0, 0, 5, 18, 0, 16, 0, 24, 0, 0, 0, 58, 0, 16, 0, 20, 0, 0, 0, 40, 0, 0, 5, 226, 0, 16, 0, 24, 0, 0, 0, 6, 9, 16, 0, 23, 0, 0, 0, 33, 0, 0, 7, 130, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 13, 0, 0, 0, 43, 0, 0, 5, 130, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 13, 0, 0, 0, 55, 0, 0, 15, 114, 0, 16, 0, 23, 0, 0, 0, 246, 15, 16, 0, 19, 0, 0, 0, 2, 64, 0, 0, 32, 0, 0, 0, 128, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 64, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 5, 18, 0, 16, 0, 25, 0, 0, 0, 58, 0, 16, 0, 15, 0, 0, 0, 40, 0, 0, 5, 34, 0, 16, 0, 25, 0, 0, 0, 58, 0, 16, 0, 18, 0, 0, 0, 40, 0, 0, 5, 194, 0, 16, 0, 25, 0, 0, 0, 6, 4, 16, 0, 20, 0, 0, 0, 33, 0, 0, 7, 130, 0, 16, 0, 9, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 10, 0, 0, 0, 43, 0, 0, 5, 130, 0, 16, 0, 14, 0, 0, 0, 58, 0, 16, 0, 10, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 15, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 34, 0, 16, 0, 19, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 48, 0, 0, 1, 80, 0, 0, 7, 130, 0, 16, 0, 18, 0, 0, 0, 58, 0, 16, 0, 15, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 3, 0, 4, 3, 58, 0, 16, 0, 18, 0, 0, 0, 85, 0, 0, 8, 130, 0, 16, 0, 18, 0, 0, 0, 10, 144, 144, 0, 58, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 15, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 18, 0, 0, 0, 58, 0, 16, 0, 18, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 32, 0, 0, 7, 130, 0, 16, 0, 19, 0, 0, 0, 58, 0, 16, 0, 18, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 19, 0, 0, 0, 167, 0, 0, 9, 242, 0, 16, 0, 20, 0, 0, 0, 58, 0, 16, 0, 15, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 20, 0, 0, 0, 70, 14, 16, 0, 24, 0, 0, 0, 70, 14, 16, 0, 20, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 50, 0, 16, 0, 20, 0, 0, 0, 70, 0, 16, 0, 20, 0, 0, 0, 70, 0, 16, 0, 22, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 19, 0, 0, 0, 26, 0, 16, 0, 20, 0, 0, 0, 10, 0, 16, 0, 20, 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 19, 0, 0, 0, 42, 0, 16, 0, 22, 0, 0, 0, 42, 0, 16, 0, 20, 0, 0, 0, 58, 0, 16, 0, 19, 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 19, 0, 0, 0, 58, 0, 16, 0, 22, 0, 0, 0, 58, 0, 16, 0, 20, 0, 0, 0, 58, 0, 16, 0, 19, 0, 0, 0, 33, 0, 0, 7, 18, 0, 16, 0, 20, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 19, 0, 0, 0, 60, 0, 0, 7, 18, 0, 16, 0, 20, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 10, 0, 16, 0, 20, 0, 0, 0, 34, 0, 0, 7, 34, 0, 16, 0, 20, 0, 0, 0, 58, 0, 16, 0, 19, 0, 0, 0, 58, 0, 16, 0, 13, 0, 0, 0, 43, 0, 0, 5, 130, 0, 16, 0, 19, 0, 0, 0, 58, 0, 16, 0, 19, 0, 0, 0, 56, 0, 0, 7, 130, 0, 16, 0, 19, 0, 0, 0, 58, 0, 16, 0, 19, 0, 0, 0, 1, 64, 0, 0, 253, 255, 125, 66, 14, 0, 0, 7, 130, 0, 16, 0, 19, 0, 0, 0, 58, 0, 16, 0, 19, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 28, 0, 0, 5, 130, 0, 16, 0, 19, 0, 0, 0, 58, 0, 16, 0, 19, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 19, 0, 0, 0, 58, 0, 16, 0, 19, 0, 0, 0, 26, 0, 16, 0, 23, 0, 0, 0, 55, 0, 0, 10, 130, 0, 16, 0, 19, 0, 0, 0, 26, 0, 16, 0, 20, 0, 0, 0, 58, 144, 144, 0, 58, 0, 16, 0, 19, 0, 0, 0, 42, 0, 16, 0, 23, 0, 0, 0, 55, 0, 0, 9, 130, 0, 16, 0, 19, 0, 0, 0, 10, 0, 16, 0, 20, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 19, 0, 0, 0, 18, 0, 0, 1, 167, 0, 0, 9, 242, 0, 16, 0, 20, 0, 0, 0, 58, 0, 16, 0, 15, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 20, 0, 0, 0, 70, 14, 16, 0, 25, 0, 0, 0, 70, 14, 16, 0, 20, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 50, 0, 16, 0, 20, 0, 0, 0, 70, 0, 16, 0, 20, 0, 0, 0, 70, 0, 16, 0, 21, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 20, 0, 0, 0, 26, 0, 16, 0, 20, 0, 0, 0, 10, 0, 16, 0, 20, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 20, 0, 0, 0, 42, 0, 16, 0, 21, 0, 0, 0, 42, 0, 16, 0, 20, 0, 0, 0, 10, 0, 16, 0, 20, 0, 0, 0, 35, 0, 0, 9, 18, 0, 16, 0, 20, 0, 0, 0, 58, 0, 16, 0, 21, 0, 0, 0, 58, 0, 16, 0, 20, 0, 0, 0, 10, 0, 16, 0, 20, 0, 0, 0, 33, 0, 0, 7, 34, 0, 16, 0, 20, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 20, 0, 0, 0, 60, 0, 0, 7, 34, 0, 16, 0, 20, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 20, 0, 0, 0, 34, 0, 0, 7, 66, 0, 16, 0, 20, 0, 0, 0, 10, 0, 16, 0, 20, 0, 0, 0, 58, 0, 16, 0, 10, 0, 0, 0, 43, 0, 0, 5, 18, 0, 16, 0, 20, 0, 0, 0, 10, 0, 16, 0, 20, 0, 0, 0, 56, 0, 0, 7, 18, 0, 16, 0, 20, 0, 0, 0, 10, 0, 16, 0, 20, 0, 0, 0, 1, 64, 0, 0, 253, 255, 125, 66, 14, 0, 0, 7, 18, 0, 16, 0, 20, 0, 0, 0, 10, 0, 16, 0, 20, 0, 0, 0, 58, 0, 16, 0, 14, 0, 0, 0, 28, 0, 0, 5, 18, 0, 16, 0, 20, 0, 0, 0, 10, 0, 16, 0, 20, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 20, 0, 0, 0, 10, 0, 16, 0, 20, 0, 0, 0, 26, 0, 16, 0, 23, 0, 0, 0, 55, 0, 0, 10, 18, 0, 16, 0, 20, 0, 0, 0, 42, 0, 16, 0, 20, 0, 0, 0, 58, 144, 144, 0, 10, 0, 16, 0, 20, 0, 0, 0, 42, 0, 16, 0, 23, 0, 0, 0, 55, 0, 0, 9, 130, 0, 16, 0, 19, 0, 0, 0, 26, 0, 16, 0, 20, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 20, 0, 0, 0, 21, 0, 0, 1, 30, 0, 0, 7, 130, 0, 16, 0, 19, 0, 0, 0, 58, 0, 16, 0, 19, 0, 0, 0, 10, 0, 16, 0, 23, 0, 0, 0, 30, 0, 0, 10, 18, 0, 16, 0, 20, 0, 0, 0, 1, 64, 0, 0, 64, 0, 0, 0, 10, 144, 208, 128, 65, 0, 0, 0, 64, 0, 0, 0, 58, 0, 16, 0, 19, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 18, 0, 0, 0, 58, 0, 16, 0, 18, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 54, 0, 0, 7, 18, 0, 16, 0, 26, 0, 0, 0, 10, 48, 32, 4, 0, 0, 0, 0, 58, 0, 16, 0, 18, 0, 0, 0, 54, 0, 0, 8, 34, 0, 16, 0, 26, 0, 0, 0, 10, 48, 32, 6, 0, 0, 0, 0, 1, 0, 0, 0, 58, 0, 16, 0, 18, 0, 0, 0, 54, 0, 0, 8, 66, 0, 16, 0, 26, 0, 0, 0, 10, 48, 32, 6, 0, 0, 0, 0, 2, 0, 0, 0, 58, 0, 16, 0, 18, 0, 0, 0, 54, 0, 0, 8, 130, 0, 16, 0, 26, 0, 0, 0, 10, 48, 32, 6, 0, 0, 0, 0, 3, 0, 0, 0, 58, 0, 16, 0, 18, 0, 0, 0, 54, 0, 0, 7, 18, 0, 16, 0, 27, 0, 0, 0, 26, 48, 32, 4, 0, 0, 0, 0, 58, 0, 16, 0, 18, 0, 0, 0, 54, 0, 0, 8, 34, 0, 16, 0, 27, 0, 0, 0, 26, 48, 32, 6, 0, 0, 0, 0, 1, 0, 0, 0, 58, 0, 16, 0, 18, 0, 0, 0, 54, 0, 0, 8, 66, 0, 16, 0, 27, 0, 0, 0, 26, 48, 32, 6, 0, 0, 0, 0, 2, 0, 0, 0, 58, 0, 16, 0, 18, 0, 0, 0, 54, 0, 0, 8, 130, 0, 16, 0, 27, 0, 0, 0, 26, 48, 32, 6, 0, 0, 0, 0, 3, 0, 0, 0, 58, 0, 16, 0, 18, 0, 0, 0, 38, 0, 0, 10, 0, 208, 0, 0, 242, 0, 16, 0, 27, 0, 0, 0, 70, 14, 16, 0, 27, 0, 0, 0, 6, 144, 208, 0, 64, 0, 0, 0, 58, 0, 16, 0, 19, 0, 0, 0, 35, 0, 0, 9, 242, 0, 16, 0, 20, 0, 0, 0, 6, 0, 16, 0, 20, 0, 0, 0, 70, 14, 16, 0, 26, 0, 0, 0, 70, 14, 16, 0, 27, 0, 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, 20, 0, 0, 0, 70, 14, 16, 0, 20, 0, 0, 0, 2, 64, 0, 0, 32, 0, 0, 0, 32, 0, 0, 0, 32, 0, 0, 0, 32, 0, 0, 0, 85, 0, 0, 7, 242, 0, 16, 0, 20, 0, 0, 0, 134, 13, 16, 0, 20, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 55, 0, 0, 9, 130, 0, 16, 0, 20, 0, 0, 0, 42, 0, 16, 0, 19, 0, 0, 0, 1, 64, 0, 0, 255, 0, 0, 0, 58, 0, 16, 0, 20, 0, 0, 0, 167, 0, 0, 9, 242, 0, 16, 0, 26, 0, 0, 0, 58, 0, 16, 0, 15, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 79, 0, 0, 7, 114, 0, 16, 0, 27, 0, 0, 0, 134, 1, 16, 0, 20, 0, 0, 0, 70, 2, 16, 0, 26, 0, 0, 0, 54, 0, 0, 5, 82, 0, 16, 0, 28, 0, 0, 0, 6, 1, 16, 0, 26, 0, 0, 0, 54, 0, 0, 5, 162, 0, 16, 0, 28, 0, 0, 0, 6, 8, 16, 0, 20, 0, 0, 0, 55, 0, 0, 9, 242, 0, 16, 0, 28, 0, 0, 0, 6, 5, 16, 0, 27, 0, 0, 0, 70, 14, 16, 0, 28, 0, 0, 0, 22, 11, 16, 0, 28, 0, 0, 0, 54, 0, 0, 5, 82, 0, 16, 0, 20, 0, 0, 0, 166, 11, 16, 0, 26, 0, 0, 0, 55, 0, 0, 9, 50, 0, 16, 0, 20, 0, 0, 0, 166, 10, 16, 0, 27, 0, 0, 0, 70, 0, 16, 0, 20, 0, 0, 0, 22, 5, 16, 0, 20, 0, 0, 0, 79, 0, 0, 7, 130, 0, 16, 0, 18, 0, 0, 0, 58, 0, 16, 0, 20, 0, 0, 0, 58, 0, 16, 0, 26, 0, 0, 0, 55, 0, 0, 9, 146, 0, 16, 0, 26, 0, 0, 0, 246, 15, 16, 0, 18, 0, 0, 0, 246, 11, 16, 0, 20, 0, 0, 0, 166, 14, 16, 0, 20, 0, 0, 0, 40, 0, 0, 5, 50, 0, 16, 0, 27, 0, 0, 0, 214, 5, 16, 0, 28, 0, 0, 0, 40, 0, 0, 5, 66, 0, 16, 0, 27, 0, 0, 0, 26, 0, 16, 0, 20, 0, 0, 0, 40, 0, 0, 5, 130, 0, 16, 0, 27, 0, 0, 0, 10, 0, 16, 0, 26, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 26, 0, 0, 0, 134, 0, 16, 0, 28, 0, 0, 0, 54, 0, 0, 5, 66, 0, 16, 0, 26, 0, 0, 0, 10, 0, 16, 0, 20, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 20, 0, 0, 0, 70, 14, 16, 0, 27, 0, 0, 0, 70, 14, 16, 0, 26, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 50, 0, 16, 0, 20, 0, 0, 0, 70, 0, 16, 0, 20, 0, 0, 0, 70, 0, 16, 0, 20, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 18, 0, 0, 0, 26, 0, 16, 0, 20, 0, 0, 0, 10, 0, 16, 0, 20, 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 18, 0, 0, 0, 42, 0, 16, 0, 20, 0, 0, 0, 42, 0, 16, 0, 20, 0, 0, 0, 58, 0, 16, 0, 18, 0, 0, 0, 86, 0, 0, 5, 130, 0, 16, 0, 18, 0, 0, 0, 58, 0, 16, 0, 18, 0, 0, 0, 86, 0, 0, 5, 130, 0, 16, 0, 19, 0, 0, 0, 58, 0, 16, 0, 20, 0, 0, 0, 56, 0, 0, 7, 130, 0, 16, 0, 19, 0, 0, 0, 58, 0, 16, 0, 19, 0, 0, 0, 58, 0, 16, 0, 19, 0, 0, 0, 50, 0, 0, 10, 130, 0, 16, 0, 18, 0, 0, 0, 58, 0, 16, 0, 19, 0, 0, 0, 42, 128, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 58, 0, 16, 0, 18, 0, 0, 0, 28, 0, 0, 5, 130, 0, 16, 0, 18, 0, 0, 0, 58, 0, 16, 0, 18, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 19, 0, 0, 0, 58, 0, 16, 0, 18, 0, 0, 0, 26, 0, 16, 0, 19, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 15, 0, 0, 0, 58, 0, 16, 0, 15, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 22, 0, 0, 1, 79, 0, 0, 7, 130, 0, 16, 0, 6, 0, 0, 0, 26, 0, 16, 0, 19, 0, 0, 0, 26, 0, 16, 0, 18, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 18, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 55, 0, 0, 9, 50, 0, 16, 0, 18, 0, 0, 0, 246, 15, 16, 0, 6, 0, 0, 0, 70, 0, 16, 0, 19, 0, 0, 0, 70, 0, 16, 0, 18, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 19, 0, 0, 0, 10, 0, 16, 0, 19, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 18, 0, 0, 0, 22, 0, 0, 1, 54, 0, 0, 6, 18, 0, 16, 0, 18, 0, 0, 0, 58, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 4, 66, 0, 16, 0, 18, 0, 0, 0, 10, 64, 2, 0, 168, 0, 0, 8, 114, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 16, 0, 0, 0, 22, 6, 16, 0, 18, 0, 0, 0, 168, 0, 0, 8, 18, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 32, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 190, 24, 0, 1, 31, 0, 4, 3, 26, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 6, 34, 0, 16, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 32, 0, 0, 0, 167, 0, 0, 9, 226, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 249, 17, 0, 0, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 79, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 18, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 168, 0, 0, 8, 114, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 16, 0, 0, 0, 134, 3, 16, 0, 2, 0, 0, 0, 168, 0, 0, 8, 18, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 32, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 21, 0, 0, 1, 21, 0, 0, 1, 31, 0, 4, 3, 10, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 8, 18, 0, 16, 0, 2, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 30, 0, 0, 6, 34, 0, 16, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 16, 0, 0, 0, 167, 0, 0, 9, 226, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 249, 17, 0, 0, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 79, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 168, 0, 0, 8, 114, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 16, 0, 0, 0, 134, 3, 16, 0, 3, 0, 0, 0, 168, 0, 0, 8, 18, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 32, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 21, 0, 0, 1, 21, 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 8, 18, 0, 16, 0, 2, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 30, 0, 0, 6, 34, 0, 16, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 8, 0, 0, 0, 167, 0, 0, 9, 226, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 249, 17, 0, 0, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 79, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 168, 0, 0, 8, 114, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 16, 0, 0, 0, 134, 3, 16, 0, 3, 0, 0, 0, 168, 0, 0, 8, 18, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 32, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 21, 0, 0, 1, 21, 0, 0, 1, 31, 0, 4, 3, 58, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 8, 18, 0, 16, 0, 1, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 30, 0, 0, 6, 34, 0, 16, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 4, 0, 0, 0, 167, 0, 0, 9, 226, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 249, 17, 0, 0, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 79, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 168, 0, 0, 8, 114, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 16, 0, 0, 0, 134, 3, 16, 0, 2, 0, 0, 0, 168, 0, 0, 8, 18, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 32, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 21, 0, 0, 1, 21, 0, 0, 1, 79, 0, 0, 9, 98, 0, 16, 0, 0, 0, 0, 0, 6, 64, 2, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 167, 0, 0, 8, 18, 0, 16, 0, 1, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 30, 0, 0, 6, 34, 0, 16, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 2, 0, 0, 0, 167, 0, 0, 9, 226, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 249, 17, 0, 0, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 79, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, 58, 0, 16, 0, 0, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 168, 0, 0, 8, 114, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 16, 0, 0, 0, 134, 3, 16, 0, 2, 0, 0, 0, 168, 0, 0, 8, 18, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 32, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 21, 0, 0, 1, 21, 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 167, 0, 0, 8, 18, 0, 16, 0, 1, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 30, 0, 0, 6, 34, 0, 16, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 1, 0, 0, 0, 167, 0, 0, 9, 226, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 249, 17, 0, 0, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 79, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 168, 0, 0, 8, 114, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 16, 0, 0, 0, 134, 3, 16, 0, 2, 0, 0, 0, 168, 0, 0, 8, 18, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 32, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 21, 0, 0, 1, 167, 0, 0, 9, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 6, 112, 16, 0, 1, 0, 0, 0, 167, 0, 0, 8, 18, 0, 16, 0, 2, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 79, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 167, 0, 0, 8, 114, 0, 16, 0, 1, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 16, 0, 0, 0, 70, 242, 17, 0, 0, 0, 0, 0, 167, 0, 0, 8, 130, 0, 16, 0, 1, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 32, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 18, 0, 0, 1, 167, 0, 0, 9, 242, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 70, 126, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 168, 0, 0, 9, 242, 224, 17, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 62, 0, 0, 1 }; ================================================ FILE: 3rdParty/DirectXTex/DirectXTex/Shaders/Compiled/BC7Encode_TryMode456CS.inc ================================================ #if 0 // // Generated by Microsoft (R) D3D Shader Disassembler // // /// // Input signature: // // Name Index Mask Register SysValue Format Used // -------------------- ----- ------ -------- -------- ------- ------ // no Input // // Output signature: // // Name Index Mask Register SysValue Format Used // -------------------- ----- ------ -------- -------- ------- ------ // no Output cs_4_0 dcl_globalFlags refactoringAllowed dcl_immediateConstantBuffer { { 0, 0, 0, 0}, { 0, 4, 0, 0}, { 0, 9, 0, 0}, { 1, 13, 0, 0}, { 1, 17, 0, 0}, { 1, 21, 0, 0}, { 1, 26, 0, 0}, { 2, 30, 0, 0}, { 2, 34, 0, 0}, { 2, 38, 0, 0}, { 2, 43, 0, 0}, { 2, 47, 0, 0}, { 3, 51, 0, 0}, { 3, 55, 0, 0}, { 3, 60, 0, 0}, { 3, 64, 0, 0}, { 4, 0, 0, 0}, { 4, 9, 0, 0}, { 4, 18, 0, 0}, { 4, 27, 0, 0}, { 5, 37, 0, 0}, { 5, 46, 0, 0}, { 5, 55, 0, 0}, { 5, 64, 0, 0}, { 6, 0, 0, 0}, { 6, 0, 0, 0}, { 6, 0, 0, 0}, { 6, 0, 0, 0}, { 6, 0, 0, 0}, { 7, 0, 0, 0}, { 7, 0, 0, 0}, { 7, 0, 0, 0}, { 7, 0, 0, 0}, { 8, 21, 0, 0}, { 8, 43, 0, 0}, { 8, 64, 0, 0}, { 8, 0, 0, 0}, { 9, 0, 0, 0}, { 9, 0, 0, 0}, { 9, 0, 0, 0}, { 9, 0, 0, 0}, { 10, 0, 0, 0}, { 10, 0, 0, 0}, { 10, 0, 0, 0}, { 10, 0, 0, 0}, { 10, 0, 0, 0}, { 11, 0, 0, 0}, { 11, 0, 0, 0}, { 11, 0, 0, 0}, { 11, 0, 0, 0}, { 12, 0, 0, 0}, { 12, 0, 0, 0}, { 12, 0, 0, 0}, { 12, 0, 0, 0}, { 13, 0, 0, 0}, { 13, 0, 0, 0}, { 13, 0, 0, 0}, { 13, 0, 0, 0}, { 14, 0, 0, 0}, { 14, 0, 0, 0}, { 14, 0, 0, 0}, { 14, 0, 0, 0}, { 15, 0, 0, 0}, { 15, 0, 0, 0}, { 0, 0, 0, 0}, { 0, 0, 0, 0}, { 0, 0, 0, 0}, { 0, 0, 0, 0}, { 0, 0, 0, 0}, { 1, 0, 0, 0}, { 1, 0, 0, 0}, { 1, 0, 0, 0}, { 1, 0, 0, 0}, { 1, 0, 0, 0}, { 1, 0, 0, 0}, { 1, 0, 0, 0}, { 1, 0, 0, 0}, { 1, 0, 0, 0}, { 2, 0, 0, 0}, { 2, 0, 0, 0}, { 2, 0, 0, 0}, { 2, 0, 0, 0}, { 2, 0, 0, 0}, { 2, 0, 0, 0}, { 2, 0, 0, 0}, { 2, 0, 0, 0}, { 2, 0, 0, 0}, { 3, 0, 0, 0}, { 3, 0, 0, 0}, { 3, 0, 0, 0}, { 3, 0, 0, 0}, { 3, 0, 0, 0}, { 3, 0, 0, 0}, { 3, 0, 0, 0}, { 3, 0, 0, 0}, { 3, 0, 0, 0}, { 3, 0, 0, 0}, { 4, 0, 0, 0}, { 4, 0, 0, 0}, { 4, 0, 0, 0}, { 4, 0, 0, 0}, { 4, 0, 0, 0}, { 4, 0, 0, 0}, { 4, 0, 0, 0}, { 4, 0, 0, 0}, { 4, 0, 0, 0}, { 5, 0, 0, 0}, { 5, 0, 0, 0}, { 5, 0, 0, 0}, { 5, 0, 0, 0}, { 5, 0, 0, 0}, { 5, 0, 0, 0}, { 5, 0, 0, 0}, { 5, 0, 0, 0}, { 5, 0, 0, 0}, { 6, 0, 0, 0}, { 6, 0, 0, 0}, { 6, 0, 0, 0}, { 6, 0, 0, 0}, { 6, 0, 0, 0}, { 6, 0, 0, 0}, { 6, 0, 0, 0}, { 6, 0, 0, 0}, { 6, 0, 0, 0}, { 7, 0, 0, 0}, { 7, 0, 0, 0}, { 7, 0, 0, 0}, { 7, 0, 0, 0}, { 0, 0, 0, 0}, { 0, 0, 0, 0}, { 0, 0, 0, 0}, { 0, 0, 0, 0}, { 0, 0, 0, 0}, { 0, 0, 0, 0}, { 0, 0, 0, 0}, { 0, 0, 0, 0}, { 0, 0, 0, 0}, { 0, 0, 0, 0}, { 0, 0, 0, 0}, { 1, 0, 0, 0}, { 1, 0, 0, 0}, { 1, 0, 0, 0}, { 1, 0, 0, 0}, { 1, 0, 0, 0}, { 1, 0, 0, 0}, { 1, 0, 0, 0}, { 1, 0, 0, 0}, { 1, 0, 0, 0}, { 1, 0, 0, 0}, { 1, 0, 0, 0}, { 1, 0, 0, 0}, { 1, 0, 0, 0}, { 1, 0, 0, 0}, { 1, 0, 0, 0}, { 1, 0, 0, 0}, { 1, 0, 0, 0}, { 1, 0, 0, 0}, { 1, 0, 0, 0}, { 1, 0, 0, 0}, { 1, 0, 0, 0}, { 1, 0, 0, 0}, { 2, 0, 0, 0}, { 2, 0, 0, 0}, { 2, 0, 0, 0}, { 2, 0, 0, 0}, { 2, 0, 0, 0}, { 2, 0, 0, 0}, { 2, 0, 0, 0}, { 2, 0, 0, 0}, { 2, 0, 0, 0}, { 2, 0, 0, 0}, { 2, 0, 0, 0}, { 2, 0, 0, 0}, { 2, 0, 0, 0}, { 2, 0, 0, 0}, { 2, 0, 0, 0}, { 2, 0, 0, 0}, { 2, 0, 0, 0}, { 2, 0, 0, 0}, { 2, 0, 0, 0}, { 2, 0, 0, 0}, { 2, 0, 0, 0}, { 3, 0, 0, 0}, { 3, 0, 0, 0}, { 3, 0, 0, 0}, { 3, 0, 0, 0}, { 3, 0, 0, 0}, { 3, 0, 0, 0}, { 3, 0, 0, 0}, { 3, 0, 0, 0}, { 3, 0, 0, 0}, { 3, 0, 0, 0} } dcl_constantbuffer cb0[2], immediateIndexed dcl_resource_texture2d (float,float,float,float) t0 dcl_uav_structured u0, 16 dcl_input vThreadIDInGroupFlattened dcl_input vThreadGroupID.x dcl_temps 19 dcl_tgsm_structured g0, 100, 64 dcl_thread_group 64, 1, 1 ushr r0.x, vThreadIDInGroupFlattened.x, l(4) ishl r0.y, vThreadGroupID.x, l(2) iadd r0.y, r0.y, cb0[1].x iadd r0.x, r0.x, r0.y uge r0.y, r0.x, cb0[1].y if_nz r0.y ret endif and r0.y, vThreadIDInGroupFlattened.x, l(48) iadd r0.z, -r0.y, vThreadIDInGroupFlattened.x ult r1.xyzw, r0.zzzz, l(16, 8, 4, 2) if_nz r1.x udiv r0.w, null, r0.x, cb0[0].y imad r2.x, -r0.w, cb0[0].y, r0.x ishl r2.x, r2.x, l(2) ishl r0.w, r0.w, l(2) and r2.y, r0.z, l(3) iadd r2.x, r2.y, r2.x ushr r3.x, r0.z, l(2) iadd r2.y, r0.w, r3.x mov r2.zw, l(0,0,0,0) ld r2.xyzw, r2.xyzw, t0.xyzw mul r2.xyzw, r2.xyzw, l(255.000000, 255.000000, 255.000000, 255.000000) ftou r2.xyzw, r2.xyzw umin r2.xyzw, r2.xyzw, l(255, 255, 255, 255) store_structured g0.xyzw, vThreadIDInGroupFlattened.x, l(0), r2.xyzw store_structured g0.xyzw, vThreadIDInGroupFlattened.x, l(36), r2.xyzw store_structured g0.xyzw, vThreadIDInGroupFlattened.x, l(52), r2.xyzw endif if_nz r1.y ld_structured r2.xyzw, vThreadIDInGroupFlattened.x, l(36), g0.xyzw ld_structured r3.xyzw, vThreadIDInGroupFlattened.x, l(52), g0.xyzw iadd r0.w, vThreadIDInGroupFlattened.x, l(8) ld_structured r4.xyzw, r0.w, l(36), g0.xyzw ld_structured r5.xyzw, r0.w, l(52), g0.xyzw umin r2.xyzw, r2.xyzw, r4.xyzw store_structured g0.xyzw, vThreadIDInGroupFlattened.x, l(36), r2.xyzw umax r2.xyzw, r3.xyzw, r5.xyzw store_structured g0.xyzw, vThreadIDInGroupFlattened.x, l(52), r2.xyzw endif if_nz r1.z ld_structured r2.xyzw, vThreadIDInGroupFlattened.x, l(36), g0.xyzw ld_structured r3.xyzw, vThreadIDInGroupFlattened.x, l(52), g0.xyzw iadd r0.w, vThreadIDInGroupFlattened.x, l(4) ld_structured r4.xyzw, r0.w, l(36), g0.xyzw ld_structured r5.xyzw, r0.w, l(52), g0.xyzw umin r2.xyzw, r2.xyzw, r4.xyzw store_structured g0.xyzw, vThreadIDInGroupFlattened.x, l(36), r2.xyzw umax r2.xyzw, r3.xyzw, r5.xyzw store_structured g0.xyzw, vThreadIDInGroupFlattened.x, l(52), r2.xyzw endif if_nz r1.w ld_structured r2.xyzw, vThreadIDInGroupFlattened.x, l(36), g0.xyzw ld_structured r3.xyzw, vThreadIDInGroupFlattened.x, l(52), g0.xyzw iadd r0.w, vThreadIDInGroupFlattened.x, l(2) ld_structured r4.xyzw, r0.w, l(36), g0.xyzw ld_structured r5.xyzw, r0.w, l(52), g0.xyzw umin r2.xyzw, r2.xyzw, r4.xyzw store_structured g0.xyzw, vThreadIDInGroupFlattened.x, l(36), r2.xyzw umax r2.xyzw, r3.xyzw, r5.xyzw store_structured g0.xyzw, vThreadIDInGroupFlattened.x, l(52), r2.xyzw endif ult r2.xy, r0.zzzz, l(1, 12, 0, 0) if_nz r2.x ld_structured r3.xyzw, vThreadIDInGroupFlattened.x, l(36), g0.xyzw ld_structured r4.xyzw, vThreadIDInGroupFlattened.x, l(52), g0.xyzw iadd r0.w, vThreadIDInGroupFlattened.x, l(1) ld_structured r5.xyzw, r0.w, l(36), g0.xyzw ld_structured r6.xyzw, r0.w, l(52), g0.xyzw umin r3.xyzw, r3.xyzw, r5.xyzw store_structured g0.xyzw, vThreadIDInGroupFlattened.x, l(36), r3.xyzw umax r3.xyzw, r4.xyzw, r6.xyzw store_structured g0.xyzw, vThreadIDInGroupFlattened.x, l(52), r3.xyzw endif ld_structured r3.xyzw, r0.y, l(0), g0.xyzw ld_structured r4.xyzw, r0.y, l(36), g0.xyzw ld_structured r5.xyzw, r0.y, l(52), g0.xyzw and r0.w, r0.z, l(1) movc r6.xyz, r0.wwww, l(1,1,2,0), l(0,2,1,0) movc r6.xyz, r1.yyyy, r6.xyzx, l(0,2,2,0) if_nz r2.y ieq r7.xyzw, r0.zzzz, l(8, 9, 10, 11) ult r0.w, r0.z, l(6) or r0.w, r7.z, r0.w or r2.yzw, r1.wwzy, r7.xxyw mov r7.y, r4.z mov r7.w, r5.z mov r7.x, l(3) mov r8.x, r4.w mov r8.y, r5.w mov r8.z, l(0) movc r9.xyz, r2.wwww, r7.ywxy, r8.xyzx movc r10.yw, r2.wwww, r8.xxxy, r7.yyyw mov r11.x, r4.y mov r11.y, r5.y mov r11.z, l(2) movc r9.xyz, r0.wwww, r11.xyzx, r9.xyzx mov r7.xz, r8.xxyx mov r10.xz, r11.xxyx movc r7.xyzw, r0.wwww, r7.xzwy, r10.xzwy mov r10.x, r4.x mov r10.yz, r7.xxwx movc r11.xyz, r2.zzzz, r4.wyzw, r10.xyzx mov r10.y, r5.x mov r10.z, l(1) movc r9.xyz, r2.zzzz, r10.xyzx, r9.xyzx mov r7.x, r10.y movc r7.xyz, r2.zzzz, r5.wyzw, r7.xyzx movc r10.xyz, r2.yyyy, r4.xyzx, r11.xyzx movc r7.xyz, r2.yyyy, r5.xyzx, r7.xyzx movc r2.yzw, r2.yyyy, r8.xxyz, r9.xxyz if_nz r1.y iadd r8.xyz, r10.xyzx, l(4, 4, 4, 0) umin r8.xyz, r8.xyzx, l(255, 255, 255, 0) iadd r9.xy, r2.yzyy, l(2, 2, 0, 0) umin r9.xy, r9.xyxx, l(255, 255, 0, 0) and r11.xyz, r8.xyzx, l(248, 248, 248, 0) ushr r8.xyz, r8.xyzx, l(5) iadd r8.xyz, r8.xyzx, r11.xyzx and r9.zw, r9.xxxy, l(0, 0, 252, 252) ushr r9.xy, r9.xyxx, l(6) iadd r11.xyz, r7.xyzx, l(4, 4, 4, 0) umin r11.xyz, r11.xyzx, l(255, 255, 255, 0) and r12.xyz, r11.xyzx, l(248, 248, 248, 0) ushr r11.xyz, r11.xyzx, l(5) iadd r11.xyz, r11.xyzx, r12.xyzx iadd r9.xy, r9.xyxx, r9.zwzz mov r11.w, r9.y mov r12.y, l(4) else iadd r10.xyz, r10.xyzx, l(1, 1, 1, 0) umin r10.xyz, r10.xyzx, l(255, 255, 255, 0) and r13.xyz, r10.xyzx, l(254, 254, 254, 0) ushr r10.xyz, r10.xyzx, l(7) iadd r8.xyz, r10.xyzx, r13.xyzx iadd r7.xyz, r7.xyzx, l(1, 1, 1, 0) umin r7.xyz, r7.xyzx, l(255, 255, 255, 0) and r10.xyz, r7.xyzx, l(254, 254, 254, 0) ushr r7.xyz, r7.xyzx, l(7) iadd r11.xyz, r7.xyzx, r10.xyzx mov r9.x, r2.y mov r11.w, r2.z mov r12.y, l(5) endif ieq r7.xyz, r2.wwww, l(1, 2, 3, 0) movc r10.zw, r7.zzzz, r3.wwwz, r3.zzzw mov r10.xy, r3.xyxx movc r10.yzw, r7.yyyy, r3.wwzy, r10.yyzw movc r10.xyzw, r7.xxxx, r3.wyzx, r10.xyzw ineg r13.xyz, r8.xyzx ineg r13.w, r9.x iadd r14.xyzw, r11.xyzw, r13.xyzw imul null, r15.xyz, r14.xywx, r14.xywx iadd r0.w, r15.y, r15.x imad r0.w, r14.z, r14.z, r0.w iadd r13.xyzw, r10.xyzw, r13.xyzw imul null, r13.xyw, r13.xyxw, r13.xyxw iadd r2.y, r13.y, r13.x imad r2.y, r13.z, r13.z, r2.y iadd r10.xyzw, -r11.xyzw, r10.xyzw imul null, r10.xyw, r10.xyxw, r10.xyxw iadd r2.z, r10.y, r10.x imad r2.z, r10.z, r10.z, r2.z ilt r2.y, r2.z, r2.y ineg r16.xyzw, r14.xyzw movc r10.xyz, r2.yyyy, r11.xyzx, r8.xyzx movc r8.xyz, r2.yyyy, r8.xyzx, r11.xyzx movc r11.xyz, r2.yyyy, r16.xyzx, r14.xyzx ilt r2.y, r10.w, r13.w mov r9.y, r11.w mov r9.z, r16.w mov r9.w, r14.w movc r9.xyz, r2.yyyy, r9.yxzy, r9.xywx ige r2.y, l(0), r0.w itof r2.z, r0.w ishl r12.zw, r6.yyyz, l(6) ishl r6.yz, r6.yyzy, l(4) iadd r13.xy, r12.zwzz, l(11, 11, 0, 0) ige r7.w, l(0), r15.z itof r8.w, r15.z udiv null, r13.xy, r13.xyxx, l(68, 68, 0, 0) mov r13.zw, l(0,0,0,0) loop uge r9.w, r13.w, l(16) breakc_nz r9.w iadd r9.w, r0.y, r13.w ld_structured r14.xyzw, r9.w, l(0), g0.xyzw movc r16.zw, r7.zzzz, r14.wwwz, r14.zzzw mov r16.xy, r14.xyxx movc r16.yzw, r7.yyyy, r14.wwzy, r16.yyzw movc r14.xyzw, r7.xxxx, r14.wyzx, r16.xyzw iadd r15.xyw, -r10.xyxz, r14.xyxz imul null, r15.xy, r11.xyxx, r15.xyxx iadd r9.w, r15.y, r15.x imad r9.w, r11.z, r15.w, r9.w ige r10.w, l(0), r9.w or r10.w, r2.y, r10.w ilt r11.w, r9.w, r0.w itof r9.w, r9.w mul r9.w, r9.w, l(63.499989) div r9.w, r9.w, r2.z ftou r9.w, r9.w iadd r9.w, r9.w, r12.z movc r9.w, r11.w, icb[r9.w + 0].x, r13.x movc r9.w, r10.w, l(0), r9.w iadd r10.w, -r9.x, r14.w imul null, r10.w, r9.z, r10.w ige r11.w, l(0), r10.w or r11.w, r7.w, r11.w ilt r15.x, r10.w, r15.z itof r10.w, r10.w mul r10.w, r10.w, l(63.499989) div r10.w, r10.w, r8.w ftou r10.w, r10.w iadd r10.w, r10.w, r12.w movc r10.w, r15.x, icb[r10.w + 0].x, r13.y movc r10.w, r11.w, l(0), r10.w iadd r9.w, r6.y, r9.w iadd r11.w, l(64), -icb[r9.w + 0].y imul null, r15.xyw, r8.xyxz, icb[r9.w + 0].yyyy imad r15.xyw, r11.wwww, r10.xyxz, r15.xyxw iadd r15.xyw, r15.xyxw, l(32, 32, 0, 32) ushr r16.xyw, r15.xyxw, l(6) iadd r9.w, r6.z, r10.w iadd r10.w, l(64), -icb[r9.w + 0].y imul null, r9.w, r9.y, icb[r9.w + 0].y imad r9.w, r10.w, r9.x, r9.w iadd r9.w, r9.w, l(32) ushr r15.y, r9.w, l(6) ult r17.xyz, r16.xywx, r14.xyzx mov r16.z, r14.x movc r17.xw, r17.xxxx, r16.zzzx, r16.xxxz mov r16.xz, r14.yyzy movc r16.xyzw, r17.yyzz, r16.xyzw, r16.yxwz ult r9.w, r15.y, r14.w mov r15.x, r14.w movc r14.xy, r9.wwww, r15.xyxx, r15.yxyy ineg r18.w, r17.w ineg r18.yz, r16.yywy ineg r18.x, r14.y mov r14.w, r17.x mov r14.yz, r16.xxzx iadd r14.xyzw, r18.xyzw, r14.xyzw movc r16.zw, r7.zzzz, r14.xxxz, r14.zzzx mov r16.xy, r14.wyww movc r16.yzw, r7.yyyy, r14.xxzy, r16.yyzw movc r14.xyzw, r7.xxxx, r14.xyzw, r16.xyzw imul null, r14.xy, r14.xyxx, r14.xyxx iadd r9.w, r14.y, r14.x imad r9.w, r14.z, r14.z, r9.w utof r9.w, r9.w utof r10.w, r14.w mul r10.w, r10.w, r10.w mad r9.w, r10.w, cb0[1].z, r9.w ftou r9.w, r9.w iadd r13.z, r9.w, r13.z iadd r13.w, r13.w, l(1) endloop mov r12.x, r13.z mov r6.w, r2.w else if_nz r1.x iadd r7.x, r0.z, l(-12) ushr r7.y, r7.x, l(1) and r0.zw, r7.xxxy, l(0, 0, 1, 1) and r4.xyzw, r4.xyzw, l(-2, -2, -2, -2) iadd r4.xyzw, r0.zzzz, r4.xyzw and r5.xyzw, r5.xyzw, l(-2, -2, -2, -2) iadd r5.xyzw, r0.wwww, r5.xyzw iadd r8.xyzw, -r4.xyzw, r5.xyzw imul null, r0.zw, r8.xxxy, r8.xxxy iadd r0.z, r0.w, r0.z imad r0.z, r8.z, r8.z, r0.z imad r0.z, r8.w, r8.w, r0.z iadd r3.xyzw, r3.xyzw, -r4.xyzw imul null, r2.yz, r3.xxyx, r8.xxyx iadd r0.w, r2.z, r2.y imad r0.w, r8.z, r3.z, r0.w imad r0.w, r8.w, r3.w, r0.w ilt r1.x, l(0), r0.z ige r2.y, r0.w, l(0) and r1.x, r1.x, r2.y itof r0.w, r0.w mul r0.w, r0.w, l(63.499989) ftou r0.w, r0.w ishl r2.y, r0.z, l(5) ult r0.w, r2.y, r0.w and r0.w, r0.w, r1.x ineg r3.xyzw, r8.xyzw movc r9.xyzw, r0.wwww, r5.xyzw, r4.xyzw movc r4.xyzw, r0.wwww, r4.xyzw, r5.xyzw movc r3.xyzw, r0.wwww, r3.xyzw, r8.xyzw ige r0.w, l(0), r0.z itof r1.x, r0.z mov r12.xy, l(0,0,0,0) loop uge r2.y, r12.y, l(16) breakc_nz r2.y iadd r2.y, r0.y, r12.y ld_structured r5.xyzw, r2.y, l(0), g0.xyzw iadd r8.xyzw, -r9.xyzw, r5.xyzw imul null, r2.yz, r3.xxyx, r8.xxyx iadd r2.y, r2.z, r2.y imad r2.y, r3.z, r8.z, r2.y imad r2.y, r3.w, r8.w, r2.y ige r2.z, l(0), r2.y or r2.z, r0.w, r2.z ilt r2.w, r2.y, r0.z itof r2.y, r2.y mul r2.y, r2.y, l(63.499989) div r2.y, r2.y, r1.x ftou r2.y, r2.y movc r2.y, r2.w, icb[r2.y + 0].x, l(15) movc r2.y, r2.z, l(0), r2.y iadd r2.z, l(64), -icb[r2.y + 0].y imul null, r8.xyzw, r4.xyzw, icb[r2.y + 0].yyyy imad r8.xyzw, r2.zzzz, r9.xyzw, r8.xyzw iadd r8.xyzw, r8.xyzw, l(32, 32, 32, 32) ushr r8.xyzw, r8.xzyw, l(6) ult r10.xyzw, r8.xzyw, r5.xyzw mov r11.xz, r5.xxyx mov r11.yw, r8.xxxz movc r11.xyzw, r10.xxyy, r11.xyzw, r11.yxwz mov r8.xz, r5.zzwz movc r5.xyzw, r10.zwzw, r8.ywxz, r8.xzyw ineg r8.xy, r11.ywyy ineg r8.zw, r5.xxxy mov r5.xy, r11.xzxx iadd r5.xyzw, r8.xyzw, r5.xyzw imul null, r2.yz, r5.xxyx, r5.xxyx iadd r2.y, r2.z, r2.y imad r2.y, r5.z, r5.z, r2.y utof r2.y, r2.y utof r2.z, r5.w mul r2.z, r2.z, r2.z mad r2.y, r2.z, cb0[1].z, r2.y ftou r2.y, r2.y iadd r12.x, r2.y, r12.x iadd r12.y, r12.y, l(1) endloop mov r12.y, l(6) mov r6.w, r7.x else mov r12.xy, l(-1,0,0,0) mov r6.w, l(0) endif endif store_structured g0.xy, vThreadIDInGroupFlattened.x, l(16), r12.xyxx store_structured g0.xy, vThreadIDInGroupFlattened.x, l(28), r6.xwxx if_nz r1.y iadd r0.y, vThreadIDInGroupFlattened.x, l(8) ld_structured r3.yz, r0.y, l(16), g0.xxyx ld_structured r4.xy, r0.y, l(28), g0.xyxx ult r0.z, r3.y, r12.x if_nz r0.z ld_structured r3.x, r0.y, l(16), g0.xxxx store_structured g0.xy, vThreadIDInGroupFlattened.x, l(16), r3.xzxx store_structured g0.xy, vThreadIDInGroupFlattened.x, l(28), r4.xyxx endif endif if_nz r1.z ld_structured r3.x, vThreadIDInGroupFlattened.x, l(16), g0.xxxx iadd r0.y, vThreadIDInGroupFlattened.x, l(4) ld_structured r4.yz, r0.y, l(16), g0.xxyx ld_structured r5.xy, r0.y, l(28), g0.xyxx ult r0.z, r4.y, r3.x if_nz r0.z ld_structured r4.x, r0.y, l(16), g0.xxxx store_structured g0.xy, vThreadIDInGroupFlattened.x, l(16), r4.xzxx store_structured g0.xy, vThreadIDInGroupFlattened.x, l(28), r5.xyxx endif endif if_nz r1.w ld_structured r1.x, vThreadIDInGroupFlattened.x, l(16), g0.xxxx iadd r0.y, vThreadIDInGroupFlattened.x, l(2) ld_structured r3.yz, r0.y, l(16), g0.xxyx ld_structured r4.xy, r0.y, l(28), g0.xyxx ult r0.z, r3.y, r1.x if_nz r0.z ld_structured r3.x, r0.y, l(16), g0.xxxx store_structured g0.xy, vThreadIDInGroupFlattened.x, l(16), r3.xzxx store_structured g0.xy, vThreadIDInGroupFlattened.x, l(28), r4.xyxx endif endif if_nz r2.x ld_structured r1.x, vThreadIDInGroupFlattened.x, l(16), g0.xxxx iadd r0.y, vThreadIDInGroupFlattened.x, l(1) ld_structured r2.yz, r0.y, l(16), g0.xxyx ld_structured r3.xy, r0.y, l(28), g0.xyxx ult r0.z, r2.y, r1.x if_nz r0.z ld_structured r2.x, r0.y, l(16), g0.xxxx store_structured g0.xy, vThreadIDInGroupFlattened.x, l(16), r2.xzxx store_structured g0.xy, vThreadIDInGroupFlattened.x, l(28), r3.xyxx endif ld_structured r1.xw, vThreadIDInGroupFlattened.x, l(28), g0.xxxy ishl r0.y, r1.x, l(31) ld_structured r1.xy, vThreadIDInGroupFlattened.x, l(16), g0.xyxx or r1.y, r0.y, r1.y mov r1.z, l(0) store_structured u0.xyzw, r0.x, l(0), r1.xyzw endif ret // Approximately 0 instruction slots used #endif const BYTE BC7Encode_TryMode456CS[] = { 68, 88, 66, 67, 193, 29, 43, 212, 231, 175, 144, 60, 211, 12, 231, 93, 197, 161, 15, 183, 1, 0, 0, 0, 56, 56, 0, 0, 3, 0, 0, 0, 44, 0, 0, 0, 60, 0, 0, 0, 76, 0, 0, 0, 73, 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 228, 55, 0, 0, 64, 0, 5, 0, 249, 13, 0, 0, 106, 8, 0, 1, 53, 24, 0, 0, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 89, 0, 0, 4, 70, 142, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 88, 24, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 158, 0, 0, 4, 0, 224, 17, 0, 0, 0, 0, 0, 16, 0, 0, 0, 95, 0, 0, 2, 0, 64, 2, 0, 95, 0, 0, 2, 18, 16, 2, 0, 104, 0, 0, 2, 19, 0, 0, 0, 160, 0, 0, 5, 0, 240, 17, 0, 0, 0, 0, 0, 100, 0, 0, 0, 64, 0, 0, 0, 155, 0, 0, 4, 64, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 85, 0, 0, 6, 18, 0, 16, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 4, 0, 0, 0, 41, 0, 0, 6, 34, 0, 16, 0, 0, 0, 0, 0, 10, 16, 2, 0, 1, 64, 0, 0, 2, 0, 0, 0, 30, 0, 0, 8, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 128, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 80, 0, 0, 8, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 128, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 21, 0, 0, 1, 1, 0, 0, 6, 34, 0, 16, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 48, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 128, 65, 0, 0, 0, 0, 0, 0, 0, 10, 64, 2, 0, 79, 0, 0, 10, 242, 0, 16, 0, 1, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 16, 0, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 1, 0, 0, 0, 78, 0, 0, 9, 130, 0, 16, 0, 0, 0, 0, 0, 0, 208, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 11, 18, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 128, 65, 0, 0, 0, 0, 0, 0, 0, 26, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 41, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 1, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 2, 0, 0, 0, 85, 0, 0, 7, 18, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 7, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, 127, 67, 28, 0, 0, 5, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 84, 0, 0, 10, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 168, 0, 0, 8, 242, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 0, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 168, 0, 0, 8, 242, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 36, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 168, 0, 0, 8, 242, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 26, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 8, 242, 0, 16, 0, 2, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 36, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 167, 0, 0, 8, 242, 0, 16, 0, 3, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 30, 0, 0, 6, 130, 0, 16, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 8, 0, 0, 0, 167, 0, 0, 9, 242, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 36, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 167, 0, 0, 9, 242, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 84, 0, 0, 7, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 168, 0, 0, 8, 242, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 36, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 83, 0, 0, 7, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 168, 0, 0, 8, 242, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 8, 242, 0, 16, 0, 2, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 36, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 167, 0, 0, 8, 242, 0, 16, 0, 3, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 30, 0, 0, 6, 130, 0, 16, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 4, 0, 0, 0, 167, 0, 0, 9, 242, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 36, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 167, 0, 0, 9, 242, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 84, 0, 0, 7, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 168, 0, 0, 8, 242, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 36, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 83, 0, 0, 7, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 168, 0, 0, 8, 242, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 21, 0, 0, 1, 31, 0, 4, 3, 58, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 8, 242, 0, 16, 0, 2, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 36, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 167, 0, 0, 8, 242, 0, 16, 0, 3, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 30, 0, 0, 6, 130, 0, 16, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 2, 0, 0, 0, 167, 0, 0, 9, 242, 0, 16, 0, 4, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 36, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 167, 0, 0, 9, 242, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 84, 0, 0, 7, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 168, 0, 0, 8, 242, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 36, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 83, 0, 0, 7, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 168, 0, 0, 8, 242, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 21, 0, 0, 1, 79, 0, 0, 10, 50, 0, 16, 0, 2, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 2, 0, 0, 0, 167, 0, 0, 8, 242, 0, 16, 0, 3, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 36, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 167, 0, 0, 8, 242, 0, 16, 0, 4, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 30, 0, 0, 6, 130, 0, 16, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 1, 0, 0, 0, 167, 0, 0, 9, 242, 0, 16, 0, 5, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 36, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 167, 0, 0, 9, 242, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 84, 0, 0, 7, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 168, 0, 0, 8, 242, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 36, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 83, 0, 0, 7, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 6, 0, 0, 0, 168, 0, 0, 8, 242, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 21, 0, 0, 1, 167, 0, 0, 9, 242, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 167, 0, 0, 9, 242, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 36, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 167, 0, 0, 9, 242, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 52, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 55, 0, 0, 15, 114, 0, 16, 0, 6, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 12, 114, 0, 16, 0, 6, 0, 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 6, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 2, 0, 0, 0, 32, 0, 0, 10, 242, 0, 16, 0, 7, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 79, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 60, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 60, 0, 0, 7, 226, 0, 16, 0, 2, 0, 0, 0, 246, 6, 16, 0, 1, 0, 0, 0, 6, 13, 16, 0, 7, 0, 0, 0, 54, 0, 0, 5, 34, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 4, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 4, 0, 0, 0, 54, 0, 0, 5, 34, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 54, 0, 0, 5, 66, 0, 16, 0, 8, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 9, 0, 0, 0, 246, 15, 16, 0, 2, 0, 0, 0, 214, 4, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 55, 0, 0, 9, 162, 0, 16, 0, 10, 0, 0, 0, 246, 15, 16, 0, 2, 0, 0, 0, 6, 4, 16, 0, 8, 0, 0, 0, 86, 13, 16, 0, 7, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 11, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 54, 0, 0, 5, 34, 0, 16, 0, 11, 0, 0, 0, 26, 0, 16, 0, 5, 0, 0, 0, 54, 0, 0, 5, 66, 0, 16, 0, 11, 0, 0, 0, 1, 64, 0, 0, 2, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 9, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 54, 0, 0, 5, 82, 0, 16, 0, 7, 0, 0, 0, 6, 1, 16, 0, 8, 0, 0, 0, 54, 0, 0, 5, 82, 0, 16, 0, 10, 0, 0, 0, 6, 1, 16, 0, 11, 0, 0, 0, 55, 0, 0, 9, 242, 0, 16, 0, 7, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 134, 7, 16, 0, 7, 0, 0, 0, 134, 7, 16, 0, 10, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 10, 0, 0, 0, 10, 0, 16, 0, 4, 0, 0, 0, 54, 0, 0, 5, 98, 0, 16, 0, 10, 0, 0, 0, 6, 3, 16, 0, 7, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 11, 0, 0, 0, 166, 10, 16, 0, 2, 0, 0, 0, 118, 14, 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 54, 0, 0, 5, 34, 0, 16, 0, 10, 0, 0, 0, 10, 0, 16, 0, 5, 0, 0, 0, 54, 0, 0, 5, 66, 0, 16, 0, 10, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 9, 0, 0, 0, 166, 10, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 9, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 7, 0, 0, 0, 26, 0, 16, 0, 10, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 7, 0, 0, 0, 166, 10, 16, 0, 2, 0, 0, 0, 118, 14, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 10, 0, 0, 0, 86, 5, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 4, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 7, 0, 0, 0, 86, 5, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 5, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 55, 0, 0, 9, 226, 0, 16, 0, 2, 0, 0, 0, 86, 5, 16, 0, 2, 0, 0, 0, 6, 9, 16, 0, 8, 0, 0, 0, 6, 9, 16, 0, 9, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 84, 0, 0, 10, 114, 0, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 10, 50, 0, 16, 0, 9, 0, 0, 0, 150, 5, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84, 0, 0, 10, 50, 0, 16, 0, 9, 0, 0, 0, 70, 0, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 248, 0, 0, 0, 248, 0, 0, 0, 248, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 114, 0, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 9, 0, 0, 0, 6, 4, 16, 0, 9, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 252, 0, 0, 0, 252, 0, 0, 0, 85, 0, 0, 7, 50, 0, 16, 0, 9, 0, 0, 0, 70, 0, 16, 0, 9, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 84, 0, 0, 10, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 12, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 2, 64, 0, 0, 248, 0, 0, 0, 248, 0, 0, 0, 248, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 12, 0, 0, 0, 30, 0, 0, 7, 50, 0, 16, 0, 9, 0, 0, 0, 70, 0, 16, 0, 9, 0, 0, 0, 230, 10, 16, 0, 9, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 11, 0, 0, 0, 26, 0, 16, 0, 9, 0, 0, 0, 54, 0, 0, 5, 34, 0, 16, 0, 12, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 18, 0, 0, 1, 30, 0, 0, 10, 114, 0, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 84, 0, 0, 10, 114, 0, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 2, 64, 0, 0, 254, 0, 0, 0, 254, 0, 0, 0, 254, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 114, 0, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 13, 0, 0, 0, 30, 0, 0, 10, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 84, 0, 0, 10, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 114, 0, 16, 0, 10, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 254, 0, 0, 0, 254, 0, 0, 0, 254, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 7, 114, 0, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 7, 0, 0, 0, 30, 0, 0, 7, 114, 0, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 7, 0, 0, 0, 70, 2, 16, 0, 10, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 11, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 54, 0, 0, 5, 34, 0, 16, 0, 12, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 21, 0, 0, 1, 32, 0, 0, 10, 114, 0, 16, 0, 7, 0, 0, 0, 246, 15, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 194, 0, 16, 0, 10, 0, 0, 0, 166, 10, 16, 0, 7, 0, 0, 0, 246, 11, 16, 0, 3, 0, 0, 0, 166, 14, 16, 0, 3, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 10, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 55, 0, 0, 9, 226, 0, 16, 0, 10, 0, 0, 0, 86, 5, 16, 0, 7, 0, 0, 0, 246, 6, 16, 0, 3, 0, 0, 0, 86, 14, 16, 0, 10, 0, 0, 0, 55, 0, 0, 9, 242, 0, 16, 0, 10, 0, 0, 0, 6, 0, 16, 0, 7, 0, 0, 0, 118, 2, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 40, 0, 0, 5, 114, 0, 16, 0, 13, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 40, 0, 0, 5, 130, 0, 16, 0, 13, 0, 0, 0, 10, 0, 16, 0, 9, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 114, 0, 16, 0, 15, 0, 0, 0, 70, 3, 16, 0, 14, 0, 0, 0, 70, 3, 16, 0, 14, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 15, 0, 0, 0, 10, 0, 16, 0, 15, 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 14, 0, 0, 0, 42, 0, 16, 0, 14, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 13, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 13, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 178, 0, 16, 0, 13, 0, 0, 0, 70, 12, 16, 0, 13, 0, 0, 0, 70, 12, 16, 0, 13, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 13, 0, 0, 0, 10, 0, 16, 0, 13, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 13, 0, 0, 0, 42, 0, 16, 0, 13, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 8, 242, 0, 16, 0, 10, 0, 0, 0, 70, 14, 16, 128, 65, 0, 0, 0, 11, 0, 0, 0, 70, 14, 16, 0, 10, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 178, 0, 16, 0, 10, 0, 0, 0, 70, 12, 16, 0, 10, 0, 0, 0, 70, 12, 16, 0, 10, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 10, 0, 0, 0, 10, 0, 16, 0, 10, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 10, 0, 0, 0, 42, 0, 16, 0, 10, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 34, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 40, 0, 0, 5, 242, 0, 16, 0, 16, 0, 0, 0, 70, 14, 16, 0, 14, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 10, 0, 0, 0, 86, 5, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 8, 0, 0, 0, 86, 5, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 8, 0, 0, 0, 70, 2, 16, 0, 11, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 11, 0, 0, 0, 86, 5, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 34, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, 0, 13, 0, 0, 0, 54, 0, 0, 5, 34, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 11, 0, 0, 0, 54, 0, 0, 5, 66, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 16, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 14, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 9, 0, 0, 0, 86, 5, 16, 0, 2, 0, 0, 0, 22, 6, 16, 0, 9, 0, 0, 0, 70, 3, 16, 0, 9, 0, 0, 0, 33, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 43, 0, 0, 5, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 194, 0, 16, 0, 12, 0, 0, 0, 86, 9, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 41, 0, 0, 7, 98, 0, 16, 0, 6, 0, 0, 0, 86, 6, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 4, 0, 0, 0, 30, 0, 0, 10, 50, 0, 16, 0, 13, 0, 0, 0, 230, 10, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 11, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 7, 130, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 15, 0, 0, 0, 43, 0, 0, 5, 130, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 15, 0, 0, 0, 78, 0, 0, 11, 0, 208, 0, 0, 50, 0, 16, 0, 13, 0, 0, 0, 70, 0, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 13, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 0, 0, 1, 80, 0, 0, 7, 130, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 13, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 3, 0, 4, 3, 58, 0, 16, 0, 9, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 13, 0, 0, 0, 167, 0, 0, 9, 242, 0, 16, 0, 14, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 55, 0, 0, 9, 194, 0, 16, 0, 16, 0, 0, 0, 166, 10, 16, 0, 7, 0, 0, 0, 246, 11, 16, 0, 14, 0, 0, 0, 166, 14, 16, 0, 14, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 16, 0, 0, 0, 70, 0, 16, 0, 14, 0, 0, 0, 55, 0, 0, 9, 226, 0, 16, 0, 16, 0, 0, 0, 86, 5, 16, 0, 7, 0, 0, 0, 246, 6, 16, 0, 14, 0, 0, 0, 86, 14, 16, 0, 16, 0, 0, 0, 55, 0, 0, 9, 242, 0, 16, 0, 14, 0, 0, 0, 6, 0, 16, 0, 7, 0, 0, 0, 118, 2, 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, 16, 0, 0, 0, 30, 0, 0, 8, 178, 0, 16, 0, 15, 0, 0, 0, 70, 8, 16, 128, 65, 0, 0, 0, 10, 0, 0, 0, 70, 8, 16, 0, 14, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 50, 0, 16, 0, 15, 0, 0, 0, 70, 0, 16, 0, 11, 0, 0, 0, 70, 0, 16, 0, 15, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 15, 0, 0, 0, 10, 0, 16, 0, 15, 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 11, 0, 0, 0, 58, 0, 16, 0, 15, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 33, 0, 0, 7, 130, 0, 16, 0, 10, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 60, 0, 0, 7, 130, 0, 16, 0, 10, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 10, 0, 0, 0, 34, 0, 0, 7, 130, 0, 16, 0, 11, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 43, 0, 0, 5, 130, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 56, 0, 0, 7, 130, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 1, 64, 0, 0, 253, 255, 125, 66, 14, 0, 0, 7, 130, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 28, 0, 0, 5, 130, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 12, 0, 0, 0, 55, 0, 0, 10, 130, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 11, 0, 0, 0, 10, 144, 144, 0, 58, 0, 16, 0, 9, 0, 0, 0, 10, 0, 16, 0, 13, 0, 0, 0, 55, 0, 0, 9, 130, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 10, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 30, 0, 0, 8, 130, 0, 16, 0, 10, 0, 0, 0, 10, 0, 16, 128, 65, 0, 0, 0, 9, 0, 0, 0, 58, 0, 16, 0, 14, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 130, 0, 16, 0, 10, 0, 0, 0, 42, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 10, 0, 0, 0, 33, 0, 0, 7, 130, 0, 16, 0, 11, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 10, 0, 0, 0, 60, 0, 0, 7, 130, 0, 16, 0, 11, 0, 0, 0, 58, 0, 16, 0, 7, 0, 0, 0, 58, 0, 16, 0, 11, 0, 0, 0, 34, 0, 0, 7, 18, 0, 16, 0, 15, 0, 0, 0, 58, 0, 16, 0, 10, 0, 0, 0, 42, 0, 16, 0, 15, 0, 0, 0, 43, 0, 0, 5, 130, 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, 0, 10, 0, 0, 0, 56, 0, 0, 7, 130, 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, 0, 10, 0, 0, 0, 1, 64, 0, 0, 253, 255, 125, 66, 14, 0, 0, 7, 130, 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 28, 0, 0, 5, 130, 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, 0, 10, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, 0, 12, 0, 0, 0, 55, 0, 0, 10, 130, 0, 16, 0, 10, 0, 0, 0, 10, 0, 16, 0, 15, 0, 0, 0, 10, 144, 144, 0, 58, 0, 16, 0, 10, 0, 0, 0, 26, 0, 16, 0, 13, 0, 0, 0, 55, 0, 0, 9, 130, 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, 0, 11, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 10, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 30, 0, 0, 9, 130, 0, 16, 0, 11, 0, 0, 0, 1, 64, 0, 0, 64, 0, 0, 0, 26, 144, 144, 128, 65, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 38, 0, 0, 9, 0, 208, 0, 0, 178, 0, 16, 0, 15, 0, 0, 0, 70, 8, 16, 0, 8, 0, 0, 0, 86, 149, 144, 0, 58, 0, 16, 0, 9, 0, 0, 0, 35, 0, 0, 9, 178, 0, 16, 0, 15, 0, 0, 0, 246, 15, 16, 0, 11, 0, 0, 0, 70, 8, 16, 0, 10, 0, 0, 0, 70, 12, 16, 0, 15, 0, 0, 0, 30, 0, 0, 10, 178, 0, 16, 0, 15, 0, 0, 0, 70, 12, 16, 0, 15, 0, 0, 0, 2, 64, 0, 0, 32, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 85, 0, 0, 7, 178, 0, 16, 0, 16, 0, 0, 0, 70, 12, 16, 0, 15, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 10, 0, 0, 0, 30, 0, 0, 9, 130, 0, 16, 0, 10, 0, 0, 0, 1, 64, 0, 0, 64, 0, 0, 0, 26, 144, 144, 128, 65, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 38, 0, 0, 9, 0, 208, 0, 0, 130, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 9, 0, 0, 0, 26, 144, 144, 0, 58, 0, 16, 0, 9, 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 10, 0, 0, 0, 10, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 1, 64, 0, 0, 32, 0, 0, 0, 85, 0, 0, 7, 34, 0, 16, 0, 15, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 79, 0, 0, 7, 114, 0, 16, 0, 17, 0, 0, 0, 70, 3, 16, 0, 16, 0, 0, 0, 70, 2, 16, 0, 14, 0, 0, 0, 54, 0, 0, 5, 66, 0, 16, 0, 16, 0, 0, 0, 10, 0, 16, 0, 14, 0, 0, 0, 55, 0, 0, 9, 146, 0, 16, 0, 17, 0, 0, 0, 6, 0, 16, 0, 17, 0, 0, 0, 166, 2, 16, 0, 16, 0, 0, 0, 6, 8, 16, 0, 16, 0, 0, 0, 54, 0, 0, 5, 82, 0, 16, 0, 16, 0, 0, 0, 86, 6, 16, 0, 14, 0, 0, 0, 55, 0, 0, 9, 242, 0, 16, 0, 16, 0, 0, 0, 86, 10, 16, 0, 17, 0, 0, 0, 70, 14, 16, 0, 16, 0, 0, 0, 22, 11, 16, 0, 16, 0, 0, 0, 79, 0, 0, 7, 130, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 15, 0, 0, 0, 58, 0, 16, 0, 14, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 15, 0, 0, 0, 58, 0, 16, 0, 14, 0, 0, 0, 55, 0, 0, 9, 50, 0, 16, 0, 14, 0, 0, 0, 246, 15, 16, 0, 9, 0, 0, 0, 70, 0, 16, 0, 15, 0, 0, 0, 22, 5, 16, 0, 15, 0, 0, 0, 40, 0, 0, 5, 130, 0, 16, 0, 18, 0, 0, 0, 58, 0, 16, 0, 17, 0, 0, 0, 40, 0, 0, 5, 98, 0, 16, 0, 18, 0, 0, 0, 86, 7, 16, 0, 16, 0, 0, 0, 40, 0, 0, 5, 18, 0, 16, 0, 18, 0, 0, 0, 26, 0, 16, 0, 14, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 14, 0, 0, 0, 10, 0, 16, 0, 17, 0, 0, 0, 54, 0, 0, 5, 98, 0, 16, 0, 14, 0, 0, 0, 6, 2, 16, 0, 16, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, 18, 0, 0, 0, 70, 14, 16, 0, 14, 0, 0, 0, 55, 0, 0, 9, 194, 0, 16, 0, 16, 0, 0, 0, 166, 10, 16, 0, 7, 0, 0, 0, 6, 8, 16, 0, 14, 0, 0, 0, 166, 2, 16, 0, 14, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 16, 0, 0, 0, 118, 15, 16, 0, 14, 0, 0, 0, 55, 0, 0, 9, 226, 0, 16, 0, 16, 0, 0, 0, 86, 5, 16, 0, 7, 0, 0, 0, 6, 6, 16, 0, 14, 0, 0, 0, 86, 14, 16, 0, 16, 0, 0, 0, 55, 0, 0, 9, 242, 0, 16, 0, 14, 0, 0, 0, 6, 0, 16, 0, 7, 0, 0, 0, 70, 14, 16, 0, 14, 0, 0, 0, 70, 14, 16, 0, 16, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 50, 0, 16, 0, 14, 0, 0, 0, 70, 0, 16, 0, 14, 0, 0, 0, 70, 0, 16, 0, 14, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 9, 0, 0, 0, 26, 0, 16, 0, 14, 0, 0, 0, 10, 0, 16, 0, 14, 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 14, 0, 0, 0, 42, 0, 16, 0, 14, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 86, 0, 0, 5, 130, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 86, 0, 0, 5, 130, 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, 0, 14, 0, 0, 0, 56, 0, 0, 7, 130, 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, 0, 10, 0, 0, 0, 58, 0, 16, 0, 10, 0, 0, 0, 50, 0, 0, 10, 130, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 10, 0, 0, 0, 42, 128, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 28, 0, 0, 5, 130, 0, 16, 0, 9, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 13, 0, 0, 0, 58, 0, 16, 0, 9, 0, 0, 0, 42, 0, 16, 0, 13, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 13, 0, 0, 0, 58, 0, 16, 0, 13, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 22, 0, 0, 1, 54, 0, 0, 5, 18, 0, 16, 0, 12, 0, 0, 0, 42, 0, 16, 0, 13, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 6, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 18, 0, 0, 1, 31, 0, 4, 3, 10, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 7, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 244, 255, 255, 255, 85, 0, 0, 7, 34, 0, 16, 0, 7, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 1, 0, 0, 10, 194, 0, 16, 0, 0, 0, 0, 0, 6, 4, 16, 0, 7, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 2, 64, 0, 0, 254, 255, 255, 255, 254, 255, 255, 255, 254, 255, 255, 255, 254, 255, 255, 255, 30, 0, 0, 7, 242, 0, 16, 0, 4, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 1, 0, 0, 10, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 2, 64, 0, 0, 254, 255, 255, 255, 254, 255, 255, 255, 254, 255, 255, 255, 254, 255, 255, 255, 30, 0, 0, 7, 242, 0, 16, 0, 5, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 30, 0, 0, 8, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 128, 65, 0, 0, 0, 4, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 194, 0, 16, 0, 0, 0, 0, 0, 6, 4, 16, 0, 8, 0, 0, 0, 6, 4, 16, 0, 8, 0, 0, 0, 30, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, 9, 66, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 30, 0, 0, 8, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 128, 65, 0, 0, 0, 4, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 98, 0, 16, 0, 2, 0, 0, 0, 6, 1, 16, 0, 3, 0, 0, 0, 6, 1, 16, 0, 8, 0, 0, 0, 30, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 35, 0, 0, 9, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 34, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 33, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 43, 0, 0, 5, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 253, 255, 125, 66, 28, 0, 0, 5, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 5, 0, 0, 0, 79, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 1, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 40, 0, 0, 5, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 55, 0, 0, 9, 242, 0, 16, 0, 9, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 55, 0, 0, 9, 242, 0, 16, 0, 4, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 55, 0, 0, 9, 242, 0, 16, 0, 3, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 33, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 43, 0, 0, 5, 18, 0, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 8, 50, 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 0, 0, 1, 80, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 12, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 3, 0, 4, 3, 26, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 12, 0, 0, 0, 167, 0, 0, 9, 242, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 70, 254, 17, 0, 0, 0, 0, 0, 30, 0, 0, 8, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 128, 65, 0, 0, 0, 9, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 98, 0, 16, 0, 2, 0, 0, 0, 6, 1, 16, 0, 3, 0, 0, 0, 6, 1, 16, 0, 8, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 3, 0, 0, 0, 42, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 3, 0, 0, 0, 58, 0, 16, 0, 8, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 33, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 60, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 34, 0, 0, 7, 130, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 43, 0, 0, 5, 34, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 56, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 253, 255, 125, 66, 14, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 28, 0, 0, 5, 34, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 55, 0, 0, 10, 34, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 2, 0, 0, 0, 10, 144, 144, 0, 26, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 15, 0, 0, 0, 55, 0, 0, 9, 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 9, 66, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 64, 0, 0, 0, 26, 144, 144, 128, 65, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 38, 0, 0, 9, 0, 208, 0, 0, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 4, 0, 0, 0, 86, 149, 144, 0, 26, 0, 16, 0, 2, 0, 0, 0, 35, 0, 0, 9, 242, 0, 16, 0, 8, 0, 0, 0, 166, 10, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 9, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 30, 0, 0, 10, 242, 0, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 2, 64, 0, 0, 32, 0, 0, 0, 32, 0, 0, 0, 32, 0, 0, 0, 32, 0, 0, 0, 85, 0, 0, 7, 242, 0, 16, 0, 8, 0, 0, 0, 134, 13, 16, 0, 8, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 79, 0, 0, 7, 242, 0, 16, 0, 10, 0, 0, 0, 134, 13, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 54, 0, 0, 5, 82, 0, 16, 0, 11, 0, 0, 0, 6, 1, 16, 0, 5, 0, 0, 0, 54, 0, 0, 5, 162, 0, 16, 0, 11, 0, 0, 0, 6, 8, 16, 0, 8, 0, 0, 0, 55, 0, 0, 9, 242, 0, 16, 0, 11, 0, 0, 0, 6, 5, 16, 0, 10, 0, 0, 0, 70, 14, 16, 0, 11, 0, 0, 0, 22, 11, 16, 0, 11, 0, 0, 0, 54, 0, 0, 5, 82, 0, 16, 0, 8, 0, 0, 0, 166, 11, 16, 0, 5, 0, 0, 0, 55, 0, 0, 9, 242, 0, 16, 0, 5, 0, 0, 0, 230, 14, 16, 0, 10, 0, 0, 0, 214, 8, 16, 0, 8, 0, 0, 0, 134, 13, 16, 0, 8, 0, 0, 0, 40, 0, 0, 5, 50, 0, 16, 0, 8, 0, 0, 0, 214, 5, 16, 0, 11, 0, 0, 0, 40, 0, 0, 5, 194, 0, 16, 0, 8, 0, 0, 0, 6, 4, 16, 0, 5, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 5, 0, 0, 0, 134, 0, 16, 0, 11, 0, 0, 0, 30, 0, 0, 7, 242, 0, 16, 0, 5, 0, 0, 0, 70, 14, 16, 0, 8, 0, 0, 0, 70, 14, 16, 0, 5, 0, 0, 0, 38, 0, 0, 8, 0, 208, 0, 0, 98, 0, 16, 0, 2, 0, 0, 0, 6, 1, 16, 0, 5, 0, 0, 0, 6, 1, 16, 0, 5, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 35, 0, 0, 9, 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 42, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 86, 0, 0, 5, 34, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 86, 0, 0, 5, 66, 0, 16, 0, 2, 0, 0, 0, 58, 0, 16, 0, 5, 0, 0, 0, 56, 0, 0, 7, 66, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 50, 0, 0, 10, 34, 0, 16, 0, 2, 0, 0, 0, 42, 0, 16, 0, 2, 0, 0, 0, 42, 128, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 28, 0, 0, 5, 34, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 12, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 12, 0, 0, 0, 30, 0, 0, 7, 34, 0, 16, 0, 12, 0, 0, 0, 26, 0, 16, 0, 12, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 22, 0, 0, 1, 54, 0, 0, 5, 34, 0, 16, 0, 12, 0, 0, 0, 1, 64, 0, 0, 6, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 6, 0, 0, 0, 10, 0, 16, 0, 7, 0, 0, 0, 18, 0, 0, 1, 54, 0, 0, 8, 50, 0, 16, 0, 12, 0, 0, 0, 2, 64, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 6, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, 21, 0, 0, 1, 168, 0, 0, 8, 50, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 16, 0, 0, 0, 70, 0, 16, 0, 12, 0, 0, 0, 168, 0, 0, 8, 50, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 28, 0, 0, 0, 198, 0, 16, 0, 6, 0, 0, 0, 31, 0, 4, 3, 26, 0, 16, 0, 1, 0, 0, 0, 30, 0, 0, 6, 34, 0, 16, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 8, 0, 0, 0, 167, 0, 0, 9, 98, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 241, 17, 0, 0, 0, 0, 0, 167, 0, 0, 9, 50, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 28, 0, 0, 0, 70, 240, 17, 0, 0, 0, 0, 0, 79, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 12, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 168, 0, 0, 8, 50, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 16, 0, 0, 0, 134, 0, 16, 0, 3, 0, 0, 0, 168, 0, 0, 8, 50, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 28, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 21, 0, 0, 1, 21, 0, 0, 1, 31, 0, 4, 3, 42, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 8, 18, 0, 16, 0, 3, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 30, 0, 0, 6, 34, 0, 16, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 4, 0, 0, 0, 167, 0, 0, 9, 98, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 241, 17, 0, 0, 0, 0, 0, 167, 0, 0, 9, 50, 0, 16, 0, 5, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 28, 0, 0, 0, 70, 240, 17, 0, 0, 0, 0, 0, 79, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 4, 0, 0, 0, 10, 0, 16, 0, 3, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 168, 0, 0, 8, 50, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 16, 0, 0, 0, 134, 0, 16, 0, 4, 0, 0, 0, 168, 0, 0, 8, 50, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 28, 0, 0, 0, 70, 0, 16, 0, 5, 0, 0, 0, 21, 0, 0, 1, 21, 0, 0, 1, 31, 0, 4, 3, 58, 0, 16, 0, 1, 0, 0, 0, 167, 0, 0, 8, 18, 0, 16, 0, 1, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 30, 0, 0, 6, 34, 0, 16, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 2, 0, 0, 0, 167, 0, 0, 9, 98, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 241, 17, 0, 0, 0, 0, 0, 167, 0, 0, 9, 50, 0, 16, 0, 4, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 28, 0, 0, 0, 70, 240, 17, 0, 0, 0, 0, 0, 79, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 3, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 168, 0, 0, 8, 50, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 16, 0, 0, 0, 134, 0, 16, 0, 3, 0, 0, 0, 168, 0, 0, 8, 50, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 28, 0, 0, 0, 70, 0, 16, 0, 4, 0, 0, 0, 21, 0, 0, 1, 21, 0, 0, 1, 31, 0, 4, 3, 10, 0, 16, 0, 2, 0, 0, 0, 167, 0, 0, 8, 18, 0, 16, 0, 1, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 30, 0, 0, 6, 34, 0, 16, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 1, 0, 0, 0, 167, 0, 0, 9, 98, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 241, 17, 0, 0, 0, 0, 0, 167, 0, 0, 9, 50, 0, 16, 0, 3, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 28, 0, 0, 0, 70, 240, 17, 0, 0, 0, 0, 0, 79, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 31, 0, 4, 3, 42, 0, 16, 0, 0, 0, 0, 0, 167, 0, 0, 9, 18, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 16, 0, 0, 0, 6, 240, 17, 0, 0, 0, 0, 0, 168, 0, 0, 8, 50, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 16, 0, 0, 0, 134, 0, 16, 0, 2, 0, 0, 0, 168, 0, 0, 8, 50, 240, 17, 0, 0, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 28, 0, 0, 0, 70, 0, 16, 0, 3, 0, 0, 0, 21, 0, 0, 1, 167, 0, 0, 8, 146, 0, 16, 0, 1, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 28, 0, 0, 0, 6, 244, 17, 0, 0, 0, 0, 0, 41, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 31, 0, 0, 0, 167, 0, 0, 8, 50, 0, 16, 0, 1, 0, 0, 0, 10, 64, 2, 0, 1, 64, 0, 0, 16, 0, 0, 0, 70, 240, 17, 0, 0, 0, 0, 0, 60, 0, 0, 7, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 168, 0, 0, 9, 242, 224, 17, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 21, 0, 0, 1, 62, 0, 0, 1 }; ================================================ FILE: 3rdParty/DirectXTex/DirectXTex/scoped.h ================================================ //------------------------------------------------------------------------------------- // scoped.h // // Utility header with helper classes for exception-safe handling of resources // // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A // PARTICULAR PURPOSE. // // Copyright (c) Microsoft Corporation. All rights reserved. //------------------------------------------------------------------------------------- #pragma once #include #include #include //--------------------------------------------------------------------------------- struct aligned_deleter { void operator()(void* p) { _aligned_free(p); } }; typedef std::unique_ptr ScopedAlignedArrayFloat; typedef std::unique_ptr ScopedAlignedArrayXMVECTOR; //--------------------------------------------------------------------------------- struct handle_closer { void operator()(HANDLE h) { assert(h != INVALID_HANDLE_VALUE); if (h) CloseHandle(h); } }; typedef public std::unique_ptr ScopedHandle; inline HANDLE safe_handle( HANDLE h ) { return (h == INVALID_HANDLE_VALUE) ? 0 : h; } ================================================ FILE: 3rdParty/DirectXTex/MIT.txt ================================================ The MIT License (MIT) Copyright (c) 2015 Microsoft Corp Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: 3rdParty/DirectXTex/ReadMe.txt ================================================ DIRECTX TEXTURE LIBRARY (DirectXTex) ------------------------------------ Copyright (c) Microsoft Corporation. All rights reserved. July 29, 2015 This package contains DirectXTex, a shared source library for reading and writing DDS files, and performing various texture content processing operations including resizing, format conversion, mip-map generation, block compression for Direct3D runtime texture resources, and height-map to normal-map conversion. This library makes use of the Windows Image Component (WIC) APIs. It also includes a simple .TGA reader and writer since this image file format is commonly used for texture content processing pipelines, but is not currently supported by a built-in WIC codec. The source is written for Visual Studio 2012, 2013, or 2015. It is recommended that you make use of the Windows 8.1 SDK and Windows 7 Service Pack 1 or later. NOTE: DirectXTex is not supported on Windows phone 8.0 because WIC is not available on that platform. It is available on Windows phone starting in version 8.1. DDSTextureLoader\ This contains a streamlined version of the DirectX SDK sample DDSWithoutD3DX11 texture loading code for a simple light-weight runtime DDS loader. This version only supports Direct3D 11 and performs no runtime pixel data conversions (i.e. 24bpp legacy DDS files always fail). This is ideal for runtime usage, and supports the full complement of Direct3D 11 texture resources (1D, 2D, volume maps, cubemaps, mipmap levels, texture arrays, BC formats, etc.). WICTextureLoader\ This contains a Direct3D 11 2D texture loader that uses WIC to load a bitmap (BMP, JPEG, PNG, HD Photo, or other WIC supported file container), resize if needed based on the current feature level (or by explicit parameter), format convert to a DXGI_FORMAT if required, and then create a 2D texture. Furthermore, if a Direct3D 11 device context is provided and the current device supports it for the given pixel format, it will auto-generate mipmaps. Note this does not support 1D textures, volume textures, cubemaps, or texture arrays. DDSTextureLoader is recommended for fully "precooked" textures for maximum performance and image quality, but this loader can be useful for creating simple 2D texture from standard image files at runtime. Note: This function is not thread-safe if given a non-NULL device context for the auto-gen mip-map support. DirectXTex\ This contains the DirectXTex library. This includes a full-featured DDS reader and writer including legacy format conversions, a TGA reader and writer, a WIC-based bitmap reader and writer (BMP, JPEG, PNG, TIFF, and HD Photo), and various texture processing functions. This is intended primarily for tool usage. Note that the majority of the header files here are intended for internal implementation of the library only (BC.h, DDS.h, DirectXTexP.h, and scoped.h). Only DirectXTex.h is meant as a 'public' header for the library. Texconv\ This DirectXTex sample is an implementation of the "texconv" command-line texture utility from the DirectX SDK utilizing DirectXTex rather than D3DX. It supports the same arguments as the Texture Conversion Tool Extended (texconvex.exe) DirectX SDK utility. See . The primary differences are the -10 and -11 arguments are not applicable; the filter names (POINT, LINEAR, CUBIC, FANT or BOX, TRIANGLE, *_DITHER, *_DITHER_DIFFUSION); and support for the .TGA file format. This also includes support for JPEG XR/HD Photo bitmap formats (see ) Texassemble\ This DirectXTex sample is a command-line utility for creating cubemaps, volume maps, or texture arrays from a set of individual input image files. DDSView\ This DirectXTex sample is a simple Direct3D 11-based viewer for DDS files. For array textures or volume maps, the "<" and ">" keyboard keys will show different images contained in the DDS. The "1" through "0" keys can also be used to jump to a specific image index. All content and source code for this package are subject to the terms of the MIT License. . Documentation is available at . For the latest version of DirectXTex, bug reports, etc. please visit the project site. http://go.microsoft.com/fwlink/?LinkId=248926 ------------------------------------ RELEASE NOTES * The alpha mode specification for DDS files was updated between the March 2013 and April 2013 releases. Any DDS files created using the DDS_FLAGS_FORCE_DX10_EXT_MISC2 flag or the texconv -dx10 switch using the March 2013 release should be refreshed. * Due to the underlying Windows BMP WIC codec, alpha channels are not supported for 16bpp or 32bpp BMP pixel format files. The Windows 8.x version of the Windows BMP WIC codec does support 32bpp pixel formats with alpha when using the BITMAPV5HEADER file header. Note the updated WIC is available on Windows 7 SP1 with KB 2670838 installed. * While DXGI 1.0 and DXGI 1.1 include 5:6:5 (DXGI_FORMAT_B5G6R5_UNORM) and 5:5:5:1 (DXGI_FORMAT_B5G5R5A1_UNORM) pixel format enumerations, the DirectX 10.x and 11.0 Runtimes do not support these formats for use with Direct3D. The DirectX 11.1 runtime, DXGI 1.2, and the WDDM 1.2 driver model fully support 16bpp formats (5:6:5, 5:5:5:1, and 4:4:4:4). * WICTextureLoader cannot load .TGA files unless the system has a 3rd party WIC codec installed. You must use the DirectXTex library for TGA file format support without relying on an add-on WIC codec. * Loading of 96bpp floating-point TIFF files results in a corrupted image prior to Windows 8. This fix is available on Windows 7 SP1 with KB 2670838 installed. ------------------------------------ RELEASE HISTORY July 29, 2015 Fixed rounding problem with 32-bit RGBA/BGRA format conversions texconv: use CPU parallel compression for BC1-BC5 (-singleproc disables) Updated for VS 2015 and Windows 10 SDK RTM Retired VS 2010 and Windows 8.0 Store projects June 18, 2015 New BC_FLAGS_USE_3SUBSETS option for BC7 compressors; now defaults to skipping 3 subset blocks Fixed bug with MakeTypeless and A8_UNORM Fixed file length validation problem in LoadDDSFromFile March 27, 2015 Added projects for Windows apps Technical Preview Fixed bug with WIC-based mipmap generation for non-WIC supported formats Fixed bug with WIC multiframe loader when resizing required texconv: Added -nmap/-nmapamp for generating normal maps from height maps texconv/texassemble: Updated to load multiframe WIC files (tiff, gif) Minor code cleanup November 24, 2014 Updates for Visual Studio 2015 Technical Preview Minor code cleanup September 22, 2014 Format conversion improvements and bug fixes (depth/stencil, alpha-only, float16, RGB -> 1 channel) Fixed issue when BC decompressing non-standard compressed rowPitch images Explicit calling-convention annotation for all 'public' functions Code cleanup Xbox One platform updates July 15, 2014 texconv command-line tool fixes Fixed problem with 'wide' images with CPU Compress Updates to Xbox One platform support April 3, 2014 Windows phone 8.1 platform support February 24, 2014 Direct3D 11 video and Xbox One extended format support New APIs: IsPlanar, IsPalettized, IsDepthStencil, ConvertToSinglePlane Added 'alphaWeight' parameter to GPU Compress [breaking change] texconv '-aw' switch to control the alpha weighting for the BC7 GPU compressor Fixed bug with ordered dithering in non-WIC conversion codepaths Fixed SaveToDDS* functions when using arbitrary row pitch values January 24, 2014 Added sRGB flags for Compress (TEX_COMPRESS_SRGB*) Added 'compress' flag parameter to GPU versions of Compress [breaking change] Minor fix for potential rounding problem in GPU Compress Code cleanup (removed DXGI_1_2_FORMATS control define; ScopedObject typedef removed) Dropped VS 2010 support without the Windows 8.1 SDK (removed USE_XNAMATH control define) December 24, 2013 texconv updated with -fl and -pow2 command-line switches Fixed bug in Resize when doing custom filtering which occurred when exactly doubling the image size Added move operators to ScratchImage and Blob classes Xbox One platform support October 21, 2013 Updated for Visual Studio 2013 and Windows 8.1 SDK RTM PremultiplyAlpha updated with new 'flags' parameter and to use sRGB correct blending Fixed colorspace conversion issue with DirectCompute compressor when compressing for BC7 SRGB August 13, 2013 DirectCompute 4.0 BC6H/BC7 compressor integration texconv utility uses DirectCompute compression by default for BC6H/BC7, -nogpu disables use of DirectCompute August 1, 2013 Support for BC compression/decompression of non-power-of-2 mipmapped textures Fixes for BC6H / BC7 codecs to better match published standard Fix for BC4 / BC5 codecs when compressing RGB images Minor fix for the BC1-3 codec New optional flags for ComputeMSE to compare UNORM vs. SNORM images New WIC loading flag added to control use of WIC metadata to return sRGB vs. non-sRGB formats Code cleanup and /analyze fixes Project file cleanup Texconv utility uses parallel BC compression by default for BC6H/BC7, -singleproc disables multithreaded behavior July 1, 2013 VS 2013 Preview projects added SaveToWIC functions updated with new optional setCustomProps parameter June 15, 2013 Custom filtering implementation for Resize & GenerateMipMaps(3D) - Point, Box, Linear, Cubic, and Triangle TEX_FILTER_TRIANGLE finite low-pass triangle filter TEX_FILTER_WRAP, TEX_FILTER_MIRROR texture semantics for custom filtering TEX_FILTER_BOX alias for TEX_FILTER_FANT WIC Ordered and error diffusion dithering for non-WIC conversion sRGB gamma correct custom filtering and conversion DDS_FLAGS_EXPAND_LUMINANCE - Reader conversion option for L8, L16, and A8L8 legacy DDS files Added use of WIC metadata for sRGB pixel formats Added BitsPerColor utility function Fixed Convert threshold parameter usage Non-power-of-2 volume map support, fixed bug with non-square volume maps Texconv utility update with -xlum, -wrap, and -mirror options; reworked -if options for improved dithering Texassemble utility for creating cubemaps, volume maps, and texture arrays DDSTextureLoader and WICTextureLoader sync'd with DirectXTK versions April 16, 2013 Updated alpha-mode metadata details in .DDS files Added new control flags for Convert Added new optional flags for ComputeMSE Fixed conversion handling for sRGB formats Fixed internal routines for handling R10G10B10_XR_BIAS_A2_UNORM, R9G9B9E5_SHAREDEXP, and FORMAT_R1_UNORM Fixed WIC I/O for GUID_WICPixelFormat32bppRGBE pixel format files (HD Photo) Fixed non-square image handling in GenerateMipMaps3D Fixed some error handling in the DDS load code March 22, 2013 Supports reading and writing alpha-mode (straight, premultiplied, etc.) metadata in .DDS files Added build option to use WICCreateImagingFactory_Proxy instead of CoCreateInstance to obtain WIC factory January 29, 2013 Added PremultiplyAlpha to DirectXTex; -pmalpha switch for texconv command-line tool Fixed problem with forceSRGB implementation for Ex versions of CreateTexture, CreateShaderResourceView, DDSTextureLoader and WICTextureLoader December 11, 2012 Ex versions of CreateTexture, CreateShaderResourceView, DDSTextureLoader and WICTextureLoader Fixed BC2 and BC3 decompression issue for unusual color encoding case Converted annotation to SAL2 for improved VS 2012 /analyze experience Updated DirectXTex, DDSView, and Texconv with VS 2010 + Windows 8.0 SDK project using official 'property sheets' November 15, 2012 Added support for WIC2 when available on Windows 8 and Windows 7 with KB 2670838 Added optional targetGUID parameter to SaveWIC* APIs to influence final container pixel format choice Fixed bug in SaveDDS* which was generating invalid DDS files for 1D dimension textures Improved robustness of CaptureTexture when resolving MSAA source textures Sync'd DDSTextureLoader, ScreenGrab, and WICTextureLoader standalone versions with latest DirectXTK release September 28, 2012 Added ScreenGrab module for creating runtime screenshots Renamed project files for better naming consistency New Typeless utilities for DirectXTex Some minor code cleanup for DirectXTex's WIC writer function Bug fixes and new -tu/-tf options for texconv June 22, 2012 Moved to using XNA Math 2.05 instead of XNA Math 2.04 for USE_XNAMATH builds Fixed BGR vs. RGB color channel swizzle problem with 24bpp legacy .DDS files in DirectXTex Update to DirectXTex WIC and WICTextureLoader for additional 96bpp float format handling on Windows 8 May 31, 2012 Minor fix for DDSTextureLoader's retry fallback that can happen with 10level9 feature levels Switched to use "_DEBUG" instead of "DEBUG" and cleaned up debug warnings added Metro style application project files for DirectXTex April 20, 2012 DirectTex's WIC-based writer opts-in for the Windows 8 BMP encoder option for writing 32 bpp RGBA files with the BITMAPV5HEADER March 30, 2012 WICTextureLoader updated with Windows 8 WIC pixel formats DirectXTex updated with limited non-power-of-2 texture support and TEX_FILTER_SEPARATE_ALPHA option Texconv updated with '-sepalpha' command-line option Added USE_XNAMATH control define to build DirectXTex using either XNAMath or DirectXMath Added VS 2012 project files (which use DirectXMath instead of XNAMath and define DXGI_1_2_FORMATS) March 15, 2012 Fix for resource leak in CreateShaderResourceView() Direct3D 11 helper function in DirectXTex March 5, 2012 Fix for too much temp memory allocated by WICTextureLoader; cleaned up legacy 'min/max' macro usage in DirectXTex February 21, 2012 WICTextureLoader updated to handle systems and device drivers without BGRA or 16bpp format support February 20, 2012 Some code cleanup for DirectXTex and DDSTextureLoader Fixed bug in 10:10:10:2 format fixup in the LoadDDSFromMemory function Fixed bugs in "non-zero alpha" special-case handling in LoadTGAFromFile Fixed bug in _SwizzleScanline when copying alpha channel for BGRA<->RGBA swizzling February 11, 2012 Update of DDSTextureLoader to also build in Metro style apps; added WICTextureLoader Added CMYK WIC pixel formats to the DirectXTex conversion table January 30, 2012 Minor code-cleanup for DirectXTex to enable use of PCH through 'directxtexp.h' header January 24, 2011 Some code-cleanup for DirectXTex Added DXGI 1.2 implementation for DDSTextureLoader and DirectXTex guarded with DXGI_1_2_FORMATS compiliation define December 16, 2011 Fixed x64 compilation warnings in DDSTextureLoader November 30, 2011 Fixed some of the constants used in IsSupportedTexture(), added ability to strip off top levels of mips in DDSTextureLoader, changed DirectXTex to use CoCreateInstance rather than LoadLibrary to obtain the WIC factory, a few minor /analyze related annotations for DirectXTex October 27, 2011 Original release ================================================ FILE: 3rdParty/DirectXTex/ScreenGrab/ScreenGrab.cpp ================================================ //-------------------------------------------------------------------------------------- // File: ScreenGrab.cpp // // Function for capturing a 2D texture and saving it to a file (aka a 'screenshot' // when used on a Direct3D 11 Render Target). // // Note these functions are useful as a light-weight runtime screen grabber. For // full-featured texture capture, DDS writer, and texture processing pipeline, // see the 'Texconv' sample and the 'DirectXTex' library. // // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A // PARTICULAR PURPOSE. // // Copyright (c) Microsoft Corporation. All rights reserved. // // http://go.microsoft.com/fwlink/?LinkId=248926 // http://go.microsoft.com/fwlink/?LinkId=248929 //-------------------------------------------------------------------------------------- // Does not capture 1D textures or 3D textures (volume maps) // Does not capture mipmap chains, only the top-most texture level is saved // For 2D array textures and cubemaps, it captures only the first image in the array #include #include #if !defined(WINAPI_FAMILY) || (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP) || (_WIN32_WINNT > _WIN32_WINNT_WIN8) // VS 2010's stdint.h conflicts with intsafe.h #pragma warning(push) #pragma warning(disable : 4005) #include #include #pragma warning(pop) #endif #include #include #include "ScreenGrab.h" using Microsoft::WRL::ComPtr; //-------------------------------------------------------------------------------------- // Macros //-------------------------------------------------------------------------------------- #ifndef MAKEFOURCC #define MAKEFOURCC(ch0, ch1, ch2, ch3) \ ((uint32_t)(uint8_t)(ch0) | ((uint32_t)(uint8_t)(ch1) << 8) | \ ((uint32_t)(uint8_t)(ch2) << 16) | ((uint32_t)(uint8_t)(ch3) << 24 )) #endif /* defined(MAKEFOURCC) */ //-------------------------------------------------------------------------------------- // DDS file structure definitions // // See DDS.h in the 'Texconv' sample and the 'DirectXTex' library //-------------------------------------------------------------------------------------- #pragma pack(push,1) #define DDS_MAGIC 0x20534444 // "DDS " struct DDS_PIXELFORMAT { uint32_t size; uint32_t flags; uint32_t fourCC; uint32_t RGBBitCount; uint32_t RBitMask; uint32_t GBitMask; uint32_t BBitMask; uint32_t ABitMask; }; #define DDS_FOURCC 0x00000004 // DDPF_FOURCC #define DDS_RGB 0x00000040 // DDPF_RGB #define DDS_RGBA 0x00000041 // DDPF_RGB | DDPF_ALPHAPIXELS #define DDS_LUMINANCE 0x00020000 // DDPF_LUMINANCE #define DDS_LUMINANCEA 0x00020001 // DDPF_LUMINANCE | DDPF_ALPHAPIXELS #define DDS_ALPHA 0x00000002 // DDPF_ALPHA #define DDS_HEADER_FLAGS_TEXTURE 0x00001007 // DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT #define DDS_HEADER_FLAGS_MIPMAP 0x00020000 // DDSD_MIPMAPCOUNT #define DDS_HEADER_FLAGS_PITCH 0x00000008 // DDSD_PITCH #define DDS_HEADER_FLAGS_LINEARSIZE 0x00080000 // DDSD_LINEARSIZE #define DDS_HEIGHT 0x00000002 // DDSD_HEIGHT #define DDS_WIDTH 0x00000004 // DDSD_WIDTH #define DDS_SURFACE_FLAGS_TEXTURE 0x00001000 // DDSCAPS_TEXTURE typedef struct { uint32_t size; uint32_t flags; uint32_t height; uint32_t width; uint32_t pitchOrLinearSize; uint32_t depth; // only if DDS_HEADER_FLAGS_VOLUME is set in flags uint32_t mipMapCount; uint32_t reserved1[11]; DDS_PIXELFORMAT ddspf; uint32_t caps; uint32_t caps2; uint32_t caps3; uint32_t caps4; uint32_t reserved2; } DDS_HEADER; typedef struct { DXGI_FORMAT dxgiFormat; uint32_t resourceDimension; uint32_t miscFlag; // see D3D11_RESOURCE_MISC_FLAG uint32_t arraySize; uint32_t reserved; } DDS_HEADER_DXT10; #pragma pack(pop) static const DDS_PIXELFORMAT DDSPF_DXT1 = { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D','X','T','1'), 0, 0, 0, 0, 0 }; static const DDS_PIXELFORMAT DDSPF_DXT3 = { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D','X','T','3'), 0, 0, 0, 0, 0 }; static const DDS_PIXELFORMAT DDSPF_DXT5 = { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D','X','T','5'), 0, 0, 0, 0, 0 }; static const DDS_PIXELFORMAT DDSPF_BC4_UNORM = { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('B','C','4','U'), 0, 0, 0, 0, 0 }; static const DDS_PIXELFORMAT DDSPF_BC4_SNORM = { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('B','C','4','S'), 0, 0, 0, 0, 0 }; static const DDS_PIXELFORMAT DDSPF_BC5_UNORM = { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('B','C','5','U'), 0, 0, 0, 0, 0 }; static const DDS_PIXELFORMAT DDSPF_BC5_SNORM = { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('B','C','5','S'), 0, 0, 0, 0, 0 }; static const DDS_PIXELFORMAT DDSPF_R8G8_B8G8 = { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('R','G','B','G'), 0, 0, 0, 0, 0 }; static const DDS_PIXELFORMAT DDSPF_G8R8_G8B8 = { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('G','R','G','B'), 0, 0, 0, 0, 0 }; static const DDS_PIXELFORMAT DDSPF_YUY2 = { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('Y','U','Y','2'), 0, 0, 0, 0, 0 }; static const DDS_PIXELFORMAT DDSPF_A8R8G8B8 = { sizeof(DDS_PIXELFORMAT), DDS_RGBA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }; static const DDS_PIXELFORMAT DDSPF_X8R8G8B8 = { sizeof(DDS_PIXELFORMAT), DDS_RGB, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000 }; static const DDS_PIXELFORMAT DDSPF_A8B8G8R8 = { sizeof(DDS_PIXELFORMAT), DDS_RGBA, 0, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 }; static const DDS_PIXELFORMAT DDSPF_G16R16 = { sizeof(DDS_PIXELFORMAT), DDS_RGB, 0, 32, 0x0000ffff, 0xffff0000, 0x00000000, 0x00000000 }; static const DDS_PIXELFORMAT DDSPF_R5G6B5 = { sizeof(DDS_PIXELFORMAT), DDS_RGB, 0, 16, 0x0000f800, 0x000007e0, 0x0000001f, 0x00000000 }; static const DDS_PIXELFORMAT DDSPF_A1R5G5B5 = { sizeof(DDS_PIXELFORMAT), DDS_RGBA, 0, 16, 0x00007c00, 0x000003e0, 0x0000001f, 0x00008000 }; static const DDS_PIXELFORMAT DDSPF_A4R4G4B4 = { sizeof(DDS_PIXELFORMAT), DDS_RGBA, 0, 16, 0x00000f00, 0x000000f0, 0x0000000f, 0x0000f000 }; static const DDS_PIXELFORMAT DDSPF_L8 = { sizeof(DDS_PIXELFORMAT), DDS_LUMINANCE, 0, 8, 0xff, 0x00, 0x00, 0x00 }; static const DDS_PIXELFORMAT DDSPF_L16 = { sizeof(DDS_PIXELFORMAT), DDS_LUMINANCE, 0, 16, 0xffff, 0x0000, 0x0000, 0x0000 }; static const DDS_PIXELFORMAT DDSPF_A8L8 = { sizeof(DDS_PIXELFORMAT), DDS_LUMINANCEA, 0, 16, 0x00ff, 0x0000, 0x0000, 0xff00 }; static const DDS_PIXELFORMAT DDSPF_A8 = { sizeof(DDS_PIXELFORMAT), DDS_ALPHA, 0, 8, 0x00, 0x00, 0x00, 0xff }; // DXGI_FORMAT_R10G10B10A2_UNORM should be written using DX10 extension to avoid D3DX 10:10:10:2 reversal issue // This indicates the DDS_HEADER_DXT10 extension is present (the format is in dxgiFormat) static const DDS_PIXELFORMAT DDSPF_DX10 = { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D','X','1','0'), 0, 0, 0, 0, 0 }; //--------------------------------------------------------------------------------- struct handle_closer { void operator()(HANDLE h) { if (h) CloseHandle(h); } }; typedef public std::unique_ptr ScopedHandle; inline HANDLE safe_handle( HANDLE h ) { return (h == INVALID_HANDLE_VALUE) ? 0 : h; } //-------------------------------------------------------------------------------------- // Return the BPP for a particular format //-------------------------------------------------------------------------------------- static size_t BitsPerPixel( _In_ DXGI_FORMAT fmt ) { switch( fmt ) { case DXGI_FORMAT_R32G32B32A32_TYPELESS: case DXGI_FORMAT_R32G32B32A32_FLOAT: case DXGI_FORMAT_R32G32B32A32_UINT: case DXGI_FORMAT_R32G32B32A32_SINT: return 128; case DXGI_FORMAT_R32G32B32_TYPELESS: case DXGI_FORMAT_R32G32B32_FLOAT: case DXGI_FORMAT_R32G32B32_UINT: case DXGI_FORMAT_R32G32B32_SINT: return 96; case DXGI_FORMAT_R16G16B16A16_TYPELESS: case DXGI_FORMAT_R16G16B16A16_FLOAT: case DXGI_FORMAT_R16G16B16A16_UNORM: case DXGI_FORMAT_R16G16B16A16_UINT: case DXGI_FORMAT_R16G16B16A16_SNORM: case DXGI_FORMAT_R16G16B16A16_SINT: case DXGI_FORMAT_R32G32_TYPELESS: case DXGI_FORMAT_R32G32_FLOAT: case DXGI_FORMAT_R32G32_UINT: case DXGI_FORMAT_R32G32_SINT: case DXGI_FORMAT_R32G8X24_TYPELESS: case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: case DXGI_FORMAT_Y416: case DXGI_FORMAT_Y210: case DXGI_FORMAT_Y216: return 64; case DXGI_FORMAT_R10G10B10A2_TYPELESS: case DXGI_FORMAT_R10G10B10A2_UNORM: case DXGI_FORMAT_R10G10B10A2_UINT: case DXGI_FORMAT_R11G11B10_FLOAT: case DXGI_FORMAT_R8G8B8A8_TYPELESS: case DXGI_FORMAT_R8G8B8A8_UNORM: case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: case DXGI_FORMAT_R8G8B8A8_UINT: case DXGI_FORMAT_R8G8B8A8_SNORM: case DXGI_FORMAT_R8G8B8A8_SINT: case DXGI_FORMAT_R16G16_TYPELESS: case DXGI_FORMAT_R16G16_FLOAT: case DXGI_FORMAT_R16G16_UNORM: case DXGI_FORMAT_R16G16_UINT: case DXGI_FORMAT_R16G16_SNORM: case DXGI_FORMAT_R16G16_SINT: case DXGI_FORMAT_R32_TYPELESS: case DXGI_FORMAT_D32_FLOAT: case DXGI_FORMAT_R32_FLOAT: case DXGI_FORMAT_R32_UINT: case DXGI_FORMAT_R32_SINT: case DXGI_FORMAT_R24G8_TYPELESS: case DXGI_FORMAT_D24_UNORM_S8_UINT: case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: case DXGI_FORMAT_X24_TYPELESS_G8_UINT: case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: case DXGI_FORMAT_R8G8_B8G8_UNORM: case DXGI_FORMAT_G8R8_G8B8_UNORM: case DXGI_FORMAT_B8G8R8A8_UNORM: case DXGI_FORMAT_B8G8R8X8_UNORM: case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM: case DXGI_FORMAT_B8G8R8A8_TYPELESS: case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: case DXGI_FORMAT_B8G8R8X8_TYPELESS: case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: case DXGI_FORMAT_AYUV: case DXGI_FORMAT_Y410: case DXGI_FORMAT_YUY2: return 32; case DXGI_FORMAT_P010: case DXGI_FORMAT_P016: return 24; case DXGI_FORMAT_R8G8_TYPELESS: case DXGI_FORMAT_R8G8_UNORM: case DXGI_FORMAT_R8G8_UINT: case DXGI_FORMAT_R8G8_SNORM: case DXGI_FORMAT_R8G8_SINT: case DXGI_FORMAT_R16_TYPELESS: case DXGI_FORMAT_R16_FLOAT: case DXGI_FORMAT_D16_UNORM: case DXGI_FORMAT_R16_UNORM: case DXGI_FORMAT_R16_UINT: case DXGI_FORMAT_R16_SNORM: case DXGI_FORMAT_R16_SINT: case DXGI_FORMAT_B5G6R5_UNORM: case DXGI_FORMAT_B5G5R5A1_UNORM: case DXGI_FORMAT_A8P8: case DXGI_FORMAT_B4G4R4A4_UNORM: return 16; case DXGI_FORMAT_NV12: case DXGI_FORMAT_420_OPAQUE: case DXGI_FORMAT_NV11: return 12; case DXGI_FORMAT_R8_TYPELESS: case DXGI_FORMAT_R8_UNORM: case DXGI_FORMAT_R8_UINT: case DXGI_FORMAT_R8_SNORM: case DXGI_FORMAT_R8_SINT: case DXGI_FORMAT_A8_UNORM: case DXGI_FORMAT_AI44: case DXGI_FORMAT_IA44: case DXGI_FORMAT_P8: return 8; case DXGI_FORMAT_R1_UNORM: return 1; case DXGI_FORMAT_BC1_TYPELESS: case DXGI_FORMAT_BC1_UNORM: case DXGI_FORMAT_BC1_UNORM_SRGB: case DXGI_FORMAT_BC4_TYPELESS: case DXGI_FORMAT_BC4_UNORM: case DXGI_FORMAT_BC4_SNORM: return 4; case DXGI_FORMAT_BC2_TYPELESS: case DXGI_FORMAT_BC2_UNORM: case DXGI_FORMAT_BC2_UNORM_SRGB: case DXGI_FORMAT_BC3_TYPELESS: case DXGI_FORMAT_BC3_UNORM: case DXGI_FORMAT_BC3_UNORM_SRGB: case DXGI_FORMAT_BC5_TYPELESS: case DXGI_FORMAT_BC5_UNORM: case DXGI_FORMAT_BC5_SNORM: case DXGI_FORMAT_BC6H_TYPELESS: case DXGI_FORMAT_BC6H_UF16: case DXGI_FORMAT_BC6H_SF16: case DXGI_FORMAT_BC7_TYPELESS: case DXGI_FORMAT_BC7_UNORM: case DXGI_FORMAT_BC7_UNORM_SRGB: return 8; default: return 0; } } //-------------------------------------------------------------------------------------- // Determines if the format is block compressed //-------------------------------------------------------------------------------------- static bool IsCompressed( _In_ DXGI_FORMAT fmt ) { switch ( fmt ) { case DXGI_FORMAT_BC1_TYPELESS: case DXGI_FORMAT_BC1_UNORM: case DXGI_FORMAT_BC1_UNORM_SRGB: case DXGI_FORMAT_BC2_TYPELESS: case DXGI_FORMAT_BC2_UNORM: case DXGI_FORMAT_BC2_UNORM_SRGB: case DXGI_FORMAT_BC3_TYPELESS: case DXGI_FORMAT_BC3_UNORM: case DXGI_FORMAT_BC3_UNORM_SRGB: case DXGI_FORMAT_BC4_TYPELESS: case DXGI_FORMAT_BC4_UNORM: case DXGI_FORMAT_BC4_SNORM: case DXGI_FORMAT_BC5_TYPELESS: case DXGI_FORMAT_BC5_UNORM: case DXGI_FORMAT_BC5_SNORM: case DXGI_FORMAT_BC6H_TYPELESS: case DXGI_FORMAT_BC6H_UF16: case DXGI_FORMAT_BC6H_SF16: case DXGI_FORMAT_BC7_TYPELESS: case DXGI_FORMAT_BC7_UNORM: case DXGI_FORMAT_BC7_UNORM_SRGB: return true; default: return false; } } //-------------------------------------------------------------------------------------- // Get surface information for a particular format //-------------------------------------------------------------------------------------- static void GetSurfaceInfo( _In_ size_t width, _In_ size_t height, _In_ DXGI_FORMAT fmt, _Out_opt_ size_t* outNumBytes, _Out_opt_ size_t* outRowBytes, _Out_opt_ size_t* outNumRows ) { size_t numBytes = 0; size_t rowBytes = 0; size_t numRows = 0; bool bc = false; bool packed = false; bool planar = false; size_t bpe = 0; switch (fmt) { case DXGI_FORMAT_BC1_TYPELESS: case DXGI_FORMAT_BC1_UNORM: case DXGI_FORMAT_BC1_UNORM_SRGB: case DXGI_FORMAT_BC4_TYPELESS: case DXGI_FORMAT_BC4_UNORM: case DXGI_FORMAT_BC4_SNORM: bc=true; bpe = 8; break; case DXGI_FORMAT_BC2_TYPELESS: case DXGI_FORMAT_BC2_UNORM: case DXGI_FORMAT_BC2_UNORM_SRGB: case DXGI_FORMAT_BC3_TYPELESS: case DXGI_FORMAT_BC3_UNORM: case DXGI_FORMAT_BC3_UNORM_SRGB: case DXGI_FORMAT_BC5_TYPELESS: case DXGI_FORMAT_BC5_UNORM: case DXGI_FORMAT_BC5_SNORM: case DXGI_FORMAT_BC6H_TYPELESS: case DXGI_FORMAT_BC6H_UF16: case DXGI_FORMAT_BC6H_SF16: case DXGI_FORMAT_BC7_TYPELESS: case DXGI_FORMAT_BC7_UNORM: case DXGI_FORMAT_BC7_UNORM_SRGB: bc = true; bpe = 16; break; case DXGI_FORMAT_R8G8_B8G8_UNORM: case DXGI_FORMAT_G8R8_G8B8_UNORM: case DXGI_FORMAT_YUY2: packed = true; bpe = 4; break; case DXGI_FORMAT_Y210: case DXGI_FORMAT_Y216: packed = true; bpe = 8; break; case DXGI_FORMAT_NV12: case DXGI_FORMAT_420_OPAQUE: planar = true; bpe = 2; break; case DXGI_FORMAT_P010: case DXGI_FORMAT_P016: planar = true; bpe = 4; break; } if (bc) { size_t numBlocksWide = 0; if (width > 0) { numBlocksWide = std::max( 1, (width + 3) / 4 ); } size_t numBlocksHigh = 0; if (height > 0) { numBlocksHigh = std::max( 1, (height + 3) / 4 ); } rowBytes = numBlocksWide * bpe; numRows = numBlocksHigh; numBytes = rowBytes * numBlocksHigh; } else if (packed) { rowBytes = ( ( width + 1 ) >> 1 ) * bpe; numRows = height; numBytes = rowBytes * height; } else if ( fmt == DXGI_FORMAT_NV11 ) { rowBytes = ( ( width + 3 ) >> 2 ) * 4; numRows = height * 2; // Direct3D makes this simplifying assumption, although it is larger than the 4:1:1 data numBytes = rowBytes * numRows; } else if (planar) { rowBytes = ( ( width + 1 ) >> 1 ) * bpe; numBytes = ( rowBytes * height ) + ( ( rowBytes * height + 1 ) >> 1 ); numRows = height + ( ( height + 1 ) >> 1 ); } else { size_t bpp = BitsPerPixel( fmt ); rowBytes = ( width * bpp + 7 ) / 8; // round up to nearest byte numRows = height; numBytes = rowBytes * height; } if (outNumBytes) { *outNumBytes = numBytes; } if (outRowBytes) { *outRowBytes = rowBytes; } if (outNumRows) { *outNumRows = numRows; } } //-------------------------------------------------------------------------------------- static DXGI_FORMAT EnsureNotTypeless( DXGI_FORMAT fmt ) { // Assumes UNORM or FLOAT; doesn't use UINT or SINT switch( fmt ) { case DXGI_FORMAT_R32G32B32A32_TYPELESS: return DXGI_FORMAT_R32G32B32A32_FLOAT; case DXGI_FORMAT_R32G32B32_TYPELESS: return DXGI_FORMAT_R32G32B32_FLOAT; case DXGI_FORMAT_R16G16B16A16_TYPELESS: return DXGI_FORMAT_R16G16B16A16_UNORM; case DXGI_FORMAT_R32G32_TYPELESS: return DXGI_FORMAT_R32G32_FLOAT; case DXGI_FORMAT_R10G10B10A2_TYPELESS: return DXGI_FORMAT_R10G10B10A2_UNORM; case DXGI_FORMAT_R8G8B8A8_TYPELESS: return DXGI_FORMAT_R8G8B8A8_UNORM; case DXGI_FORMAT_R16G16_TYPELESS: return DXGI_FORMAT_R16G16_UNORM; case DXGI_FORMAT_R32_TYPELESS: return DXGI_FORMAT_R32_FLOAT; case DXGI_FORMAT_R8G8_TYPELESS: return DXGI_FORMAT_R8G8_UNORM; case DXGI_FORMAT_R16_TYPELESS: return DXGI_FORMAT_R16_UNORM; case DXGI_FORMAT_R8_TYPELESS: return DXGI_FORMAT_R8_UNORM; case DXGI_FORMAT_BC1_TYPELESS: return DXGI_FORMAT_BC1_UNORM; case DXGI_FORMAT_BC2_TYPELESS: return DXGI_FORMAT_BC2_UNORM; case DXGI_FORMAT_BC3_TYPELESS: return DXGI_FORMAT_BC3_UNORM; case DXGI_FORMAT_BC4_TYPELESS: return DXGI_FORMAT_BC4_UNORM; case DXGI_FORMAT_BC5_TYPELESS: return DXGI_FORMAT_BC5_UNORM; case DXGI_FORMAT_B8G8R8A8_TYPELESS: return DXGI_FORMAT_B8G8R8A8_UNORM; case DXGI_FORMAT_B8G8R8X8_TYPELESS: return DXGI_FORMAT_B8G8R8X8_UNORM; case DXGI_FORMAT_BC7_TYPELESS: return DXGI_FORMAT_BC7_UNORM; default: return fmt; } } //-------------------------------------------------------------------------------------- static HRESULT CaptureTexture( _In_ ID3D11DeviceContext* pContext, _In_ ID3D11Resource* pSource, _Inout_ D3D11_TEXTURE2D_DESC& desc, _Inout_ ComPtr& pStaging ) { if ( !pContext || !pSource ) return E_INVALIDARG; D3D11_RESOURCE_DIMENSION resType = D3D11_RESOURCE_DIMENSION_UNKNOWN; pSource->GetType( &resType ); if ( resType != D3D11_RESOURCE_DIMENSION_TEXTURE2D ) return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); ComPtr pTexture; HRESULT hr = pSource->QueryInterface( __uuidof(ID3D11Texture2D), reinterpret_cast( pTexture.GetAddressOf() ) ); if ( FAILED(hr) ) return hr; assert( pTexture ); pTexture->GetDesc( &desc ); ComPtr d3dDevice; pContext->GetDevice( d3dDevice.GetAddressOf() ); if ( desc.SampleDesc.Count > 1 ) { // MSAA content must be resolved before being copied to a staging texture desc.SampleDesc.Count = 1; desc.SampleDesc.Quality = 0; ComPtr pTemp; hr = d3dDevice->CreateTexture2D( &desc, 0, pTemp.GetAddressOf() ); if ( FAILED(hr) ) return hr; assert( pTemp ); DXGI_FORMAT fmt = EnsureNotTypeless( desc.Format ); UINT support = 0; hr = d3dDevice->CheckFormatSupport( fmt, &support ); if ( FAILED(hr) ) return hr; if ( !(support & D3D11_FORMAT_SUPPORT_MULTISAMPLE_RESOLVE) ) return E_FAIL; for( UINT item = 0; item < desc.ArraySize; ++item ) { for( UINT level = 0; level < desc.MipLevels; ++level ) { UINT index = D3D11CalcSubresource( level, item, desc.MipLevels ); pContext->ResolveSubresource( pTemp.Get(), index, pSource, index, fmt ); } } desc.BindFlags = 0; desc.MiscFlags &= D3D11_RESOURCE_MISC_TEXTURECUBE; desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; desc.Usage = D3D11_USAGE_STAGING; hr = d3dDevice->CreateTexture2D( &desc, 0, pStaging.GetAddressOf() ); if ( FAILED(hr) ) return hr; assert( pStaging ); pContext->CopyResource( pStaging.Get(), pTemp.Get() ); } else if ( (desc.Usage == D3D11_USAGE_STAGING) && (desc.CPUAccessFlags & D3D11_CPU_ACCESS_READ) ) { // Handle case where the source is already a staging texture we can use directly pStaging = pTexture; } else { // Otherwise, create a staging texture from the non-MSAA source desc.BindFlags = 0; desc.MiscFlags &= D3D11_RESOURCE_MISC_TEXTURECUBE; desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; desc.Usage = D3D11_USAGE_STAGING; hr = d3dDevice->CreateTexture2D( &desc, 0, pStaging.GetAddressOf() ); if ( FAILED(hr) ) return hr; assert( pStaging ); pContext->CopyResource( pStaging.Get(), pSource ); } return S_OK; } //-------------------------------------------------------------------------------------- #if !defined(WINAPI_FAMILY) || (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP) || (_WIN32_WINNT > _WIN32_WINNT_WIN8) static bool g_WIC2 = false; static IWICImagingFactory* _GetWIC() { static IWICImagingFactory* s_Factory = nullptr; if ( s_Factory ) return s_Factory; #if(_WIN32_WINNT >= _WIN32_WINNT_WIN8) || defined(_WIN7_PLATFORM_UPDATE) HRESULT hr = CoCreateInstance( CLSID_WICImagingFactory2, nullptr, CLSCTX_INPROC_SERVER, __uuidof(IWICImagingFactory2), (LPVOID*)&s_Factory ); if ( SUCCEEDED(hr) ) { // WIC2 is available on Windows 8 and Windows 7 SP1 with KB 2670838 installed g_WIC2 = true; } else { hr = CoCreateInstance( CLSID_WICImagingFactory1, nullptr, CLSCTX_INPROC_SERVER, __uuidof(IWICImagingFactory), (LPVOID*)&s_Factory ); if ( FAILED(hr) ) { s_Factory = nullptr; return nullptr; } } #else HRESULT hr = CoCreateInstance( CLSID_WICImagingFactory, nullptr, CLSCTX_INPROC_SERVER, __uuidof(IWICImagingFactory), (LPVOID*)&s_Factory ); if ( FAILED(hr) ) { s_Factory = nullptr; return nullptr; } #endif return s_Factory; } #endif //-------------------------------------------------------------------------------------- HRESULT DirectX::SaveDDSTextureToFile( _In_ ID3D11DeviceContext* pContext, _In_ ID3D11Resource* pSource, _In_z_ LPCWSTR fileName ) { if ( !fileName ) return E_INVALIDARG; D3D11_TEXTURE2D_DESC desc = { 0 }; ComPtr pStaging; HRESULT hr = CaptureTexture( pContext, pSource, desc, pStaging ); if ( FAILED(hr) ) return hr; // Create file #if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) ScopedHandle hFile( safe_handle( CreateFile2( fileName, GENERIC_WRITE, 0, CREATE_ALWAYS, 0 ) ) ); #else ScopedHandle hFile( safe_handle( CreateFileW( fileName, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0 ) ) ); #endif if ( !hFile ) return HRESULT_FROM_WIN32( GetLastError() ); // Setup header const size_t MAX_HEADER_SIZE = sizeof(uint32_t) + sizeof(DDS_HEADER) + sizeof(DDS_HEADER_DXT10); uint8_t fileHeader[ MAX_HEADER_SIZE ]; *reinterpret_cast(&fileHeader[0]) = DDS_MAGIC; auto header = reinterpret_cast( &fileHeader[0] + sizeof(uint32_t) ); size_t headerSize = sizeof(uint32_t) + sizeof(DDS_HEADER); memset( header, 0, sizeof(DDS_HEADER) ); header->size = sizeof( DDS_HEADER ); header->flags = DDS_HEADER_FLAGS_TEXTURE | DDS_HEADER_FLAGS_MIPMAP; header->height = desc.Height; header->width = desc.Width; header->mipMapCount = 1; header->caps = DDS_SURFACE_FLAGS_TEXTURE; // Try to use a legacy .DDS pixel format for better tools support, otherwise fallback to 'DX10' header extension DDS_HEADER_DXT10* extHeader = nullptr; switch( desc.Format ) { case DXGI_FORMAT_R8G8B8A8_UNORM: memcpy_s( &header->ddspf, sizeof(header->ddspf), &DDSPF_A8B8G8R8, sizeof(DDS_PIXELFORMAT) ); break; case DXGI_FORMAT_R16G16_UNORM: memcpy_s( &header->ddspf, sizeof(header->ddspf), &DDSPF_G16R16, sizeof(DDS_PIXELFORMAT) ); break; case DXGI_FORMAT_R8G8_UNORM: memcpy_s( &header->ddspf, sizeof(header->ddspf), &DDSPF_A8L8, sizeof(DDS_PIXELFORMAT) ); break; case DXGI_FORMAT_R16_UNORM: memcpy_s( &header->ddspf, sizeof(header->ddspf), &DDSPF_L16, sizeof(DDS_PIXELFORMAT) ); break; case DXGI_FORMAT_R8_UNORM: memcpy_s( &header->ddspf, sizeof(header->ddspf), &DDSPF_L8, sizeof(DDS_PIXELFORMAT) ); break; case DXGI_FORMAT_A8_UNORM: memcpy_s( &header->ddspf, sizeof(header->ddspf), &DDSPF_A8, sizeof(DDS_PIXELFORMAT) ); break; case DXGI_FORMAT_R8G8_B8G8_UNORM: memcpy_s( &header->ddspf, sizeof(header->ddspf), &DDSPF_R8G8_B8G8, sizeof(DDS_PIXELFORMAT) ); break; case DXGI_FORMAT_G8R8_G8B8_UNORM: memcpy_s( &header->ddspf, sizeof(header->ddspf), &DDSPF_G8R8_G8B8, sizeof(DDS_PIXELFORMAT) ); break; case DXGI_FORMAT_BC1_UNORM: memcpy_s( &header->ddspf, sizeof(header->ddspf), &DDSPF_DXT1, sizeof(DDS_PIXELFORMAT) ); break; case DXGI_FORMAT_BC2_UNORM: memcpy_s( &header->ddspf, sizeof(header->ddspf), &DDSPF_DXT3, sizeof(DDS_PIXELFORMAT) ); break; case DXGI_FORMAT_BC3_UNORM: memcpy_s( &header->ddspf, sizeof(header->ddspf), &DDSPF_DXT5, sizeof(DDS_PIXELFORMAT) ); break; case DXGI_FORMAT_BC4_UNORM: memcpy_s( &header->ddspf, sizeof(header->ddspf), &DDSPF_BC4_UNORM, sizeof(DDS_PIXELFORMAT) ); break; case DXGI_FORMAT_BC4_SNORM: memcpy_s( &header->ddspf, sizeof(header->ddspf), &DDSPF_BC4_SNORM, sizeof(DDS_PIXELFORMAT) ); break; case DXGI_FORMAT_BC5_UNORM: memcpy_s( &header->ddspf, sizeof(header->ddspf), &DDSPF_BC5_UNORM, sizeof(DDS_PIXELFORMAT) ); break; case DXGI_FORMAT_BC5_SNORM: memcpy_s( &header->ddspf, sizeof(header->ddspf), &DDSPF_BC5_SNORM, sizeof(DDS_PIXELFORMAT) ); break; case DXGI_FORMAT_B5G6R5_UNORM: memcpy_s( &header->ddspf, sizeof(header->ddspf), &DDSPF_R5G6B5, sizeof(DDS_PIXELFORMAT) ); break; case DXGI_FORMAT_B5G5R5A1_UNORM: memcpy_s( &header->ddspf, sizeof(header->ddspf), &DDSPF_A1R5G5B5, sizeof(DDS_PIXELFORMAT) ); break; case DXGI_FORMAT_B8G8R8A8_UNORM: memcpy_s( &header->ddspf, sizeof(header->ddspf), &DDSPF_A8R8G8B8, sizeof(DDS_PIXELFORMAT) ); break; // DXGI 1.1 case DXGI_FORMAT_B8G8R8X8_UNORM: memcpy_s( &header->ddspf, sizeof(header->ddspf), &DDSPF_X8R8G8B8, sizeof(DDS_PIXELFORMAT) ); break; // DXGI 1.1 case DXGI_FORMAT_YUY2: memcpy_s( &header->ddspf, sizeof(header->ddspf), &DDSPF_YUY2, sizeof(DDS_PIXELFORMAT) ); break; // DXGI 1.2 case DXGI_FORMAT_B4G4R4A4_UNORM: memcpy_s( &header->ddspf, sizeof(header->ddspf), &DDSPF_A4R4G4B4, sizeof(DDS_PIXELFORMAT) ); break; // DXGI 1.2 // Legacy D3DX formats using D3DFMT enum value as FourCC case DXGI_FORMAT_R32G32B32A32_FLOAT: header->ddspf.size = sizeof(DDS_PIXELFORMAT); header->ddspf.flags = DDS_FOURCC; header->ddspf.fourCC = 116; break; // D3DFMT_A32B32G32R32F case DXGI_FORMAT_R16G16B16A16_FLOAT: header->ddspf.size = sizeof(DDS_PIXELFORMAT); header->ddspf.flags = DDS_FOURCC; header->ddspf.fourCC = 113; break; // D3DFMT_A16B16G16R16F case DXGI_FORMAT_R16G16B16A16_UNORM: header->ddspf.size = sizeof(DDS_PIXELFORMAT); header->ddspf.flags = DDS_FOURCC; header->ddspf.fourCC = 36; break; // D3DFMT_A16B16G16R16 case DXGI_FORMAT_R16G16B16A16_SNORM: header->ddspf.size = sizeof(DDS_PIXELFORMAT); header->ddspf.flags = DDS_FOURCC; header->ddspf.fourCC = 110; break; // D3DFMT_Q16W16V16U16 case DXGI_FORMAT_R32G32_FLOAT: header->ddspf.size = sizeof(DDS_PIXELFORMAT); header->ddspf.flags = DDS_FOURCC; header->ddspf.fourCC = 115; break; // D3DFMT_G32R32F case DXGI_FORMAT_R16G16_FLOAT: header->ddspf.size = sizeof(DDS_PIXELFORMAT); header->ddspf.flags = DDS_FOURCC; header->ddspf.fourCC = 112; break; // D3DFMT_G16R16F case DXGI_FORMAT_R32_FLOAT: header->ddspf.size = sizeof(DDS_PIXELFORMAT); header->ddspf.flags = DDS_FOURCC; header->ddspf.fourCC = 114; break; // D3DFMT_R32F case DXGI_FORMAT_R16_FLOAT: header->ddspf.size = sizeof(DDS_PIXELFORMAT); header->ddspf.flags = DDS_FOURCC; header->ddspf.fourCC = 111; break; // D3DFMT_R16F case DXGI_FORMAT_AI44: case DXGI_FORMAT_IA44: case DXGI_FORMAT_P8: case DXGI_FORMAT_A8P8: return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); default: memcpy_s( &header->ddspf, sizeof(header->ddspf), &DDSPF_DX10, sizeof(DDS_PIXELFORMAT) ); headerSize += sizeof(DDS_HEADER_DXT10); extHeader = reinterpret_cast( reinterpret_cast(&fileHeader[0]) + sizeof(uint32_t) + sizeof(DDS_HEADER) ); memset( extHeader, 0, sizeof(DDS_HEADER_DXT10) ); extHeader->dxgiFormat = desc.Format; extHeader->resourceDimension = D3D11_RESOURCE_DIMENSION_TEXTURE2D; extHeader->arraySize = 1; break; } size_t rowPitch, slicePitch, rowCount; GetSurfaceInfo( desc.Width, desc.Height, desc.Format, &slicePitch, &rowPitch, &rowCount ); if ( IsCompressed( desc.Format ) ) { header->flags |= DDS_HEADER_FLAGS_LINEARSIZE; header->pitchOrLinearSize = static_cast( slicePitch ); } else { header->flags |= DDS_HEADER_FLAGS_PITCH; header->pitchOrLinearSize = static_cast( rowPitch ); } // Setup pixels std::unique_ptr pixels( new (std::nothrow) uint8_t[ slicePitch ] ); if (!pixels) return E_OUTOFMEMORY; D3D11_MAPPED_SUBRESOURCE mapped; hr = pContext->Map( pStaging.Get(), 0, D3D11_MAP_READ, 0, &mapped ); if ( FAILED(hr) ) return hr; auto sptr = reinterpret_cast( mapped.pData ); if ( !sptr ) { pContext->Unmap( pStaging.Get(), 0 ); return E_POINTER; } uint8_t* dptr = pixels.get(); size_t msize = std::min( rowPitch, mapped.RowPitch ); for( size_t h = 0; h < rowCount; ++h ) { memcpy_s( dptr, rowPitch, sptr, msize ); sptr += mapped.RowPitch; dptr += rowPitch; } pContext->Unmap( pStaging.Get(), 0 ); // Write header & pixels DWORD bytesWritten; if ( !WriteFile( hFile.get(), fileHeader, static_cast( headerSize ), &bytesWritten, 0 ) ) return HRESULT_FROM_WIN32( GetLastError() ); if ( bytesWritten != headerSize ) return E_FAIL; if ( !WriteFile( hFile.get(), pixels.get(), static_cast( slicePitch ), &bytesWritten, 0 ) ) return HRESULT_FROM_WIN32( GetLastError() ); if ( bytesWritten != slicePitch ) return E_FAIL; return S_OK; } //-------------------------------------------------------------------------------------- #if !defined(WINAPI_FAMILY) || (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP) || (_WIN32_WINNT > _WIN32_WINNT_WIN8) HRESULT DirectX::SaveWICTextureToFile( _In_ ID3D11DeviceContext* pContext, _In_ ID3D11Resource* pSource, _In_ REFGUID guidContainerFormat, _In_z_ LPCWSTR fileName, _In_opt_ const GUID* targetFormat, _In_opt_ std::function setCustomProps ) { if ( !fileName ) return E_INVALIDARG; D3D11_TEXTURE2D_DESC desc = { 0 }; ComPtr pStaging; HRESULT hr = CaptureTexture( pContext, pSource, desc, pStaging ); if ( FAILED(hr) ) return hr; // Determine source format's WIC equivalent WICPixelFormatGUID pfGuid; bool sRGB = false; switch ( desc.Format ) { case DXGI_FORMAT_R32G32B32A32_FLOAT: pfGuid = GUID_WICPixelFormat128bppRGBAFloat; break; case DXGI_FORMAT_R16G16B16A16_FLOAT: pfGuid = GUID_WICPixelFormat64bppRGBAHalf; break; case DXGI_FORMAT_R16G16B16A16_UNORM: pfGuid = GUID_WICPixelFormat64bppRGBA; break; case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM: pfGuid = GUID_WICPixelFormat32bppRGBA1010102XR; break; // DXGI 1.1 case DXGI_FORMAT_R10G10B10A2_UNORM: pfGuid = GUID_WICPixelFormat32bppRGBA1010102; break; case DXGI_FORMAT_B5G5R5A1_UNORM: pfGuid = GUID_WICPixelFormat16bppBGRA5551; break; case DXGI_FORMAT_B5G6R5_UNORM: pfGuid = GUID_WICPixelFormat16bppBGR565; break; case DXGI_FORMAT_R32_FLOAT: pfGuid = GUID_WICPixelFormat32bppGrayFloat; break; case DXGI_FORMAT_R16_FLOAT: pfGuid = GUID_WICPixelFormat16bppGrayHalf; break; case DXGI_FORMAT_R16_UNORM: pfGuid = GUID_WICPixelFormat16bppGray; break; case DXGI_FORMAT_R8_UNORM: pfGuid = GUID_WICPixelFormat8bppGray; break; case DXGI_FORMAT_A8_UNORM: pfGuid = GUID_WICPixelFormat8bppAlpha; break; case DXGI_FORMAT_R8G8B8A8_UNORM: pfGuid = GUID_WICPixelFormat32bppRGBA; break; case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: pfGuid = GUID_WICPixelFormat32bppRGBA; sRGB = true; break; case DXGI_FORMAT_B8G8R8A8_UNORM: // DXGI 1.1 pfGuid = GUID_WICPixelFormat32bppBGRA; break; case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: // DXGI 1.1 pfGuid = GUID_WICPixelFormat32bppBGRA; sRGB = true; break; case DXGI_FORMAT_B8G8R8X8_UNORM: // DXGI 1.1 pfGuid = GUID_WICPixelFormat32bppBGR; break; case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: // DXGI 1.1 pfGuid = GUID_WICPixelFormat32bppBGR; sRGB = true; break; default: return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); } IWICImagingFactory* pWIC = _GetWIC(); if ( !pWIC ) return E_NOINTERFACE; ComPtr stream; hr = pWIC->CreateStream( stream.GetAddressOf() ); if ( FAILED(hr) ) return hr; hr = stream->InitializeFromFilename( fileName, GENERIC_WRITE ); if ( FAILED(hr) ) return hr; ComPtr encoder; hr = pWIC->CreateEncoder( guidContainerFormat, 0, encoder.GetAddressOf() ); if ( FAILED(hr) ) return hr; hr = encoder->Initialize( stream.Get(), WICBitmapEncoderNoCache ); if ( FAILED(hr) ) return hr; ComPtr frame; ComPtr props; hr = encoder->CreateNewFrame( frame.GetAddressOf(), props.GetAddressOf() ); if ( FAILED(hr) ) return hr; if ( targetFormat && memcmp( &guidContainerFormat, &GUID_ContainerFormatBmp, sizeof(WICPixelFormatGUID) ) == 0 && g_WIC2 ) { // Opt-in to the WIC2 support for writing 32-bit Windows BMP files with an alpha channel PROPBAG2 option = { 0 }; option.pstrName = L"EnableV5Header32bppBGRA"; VARIANT varValue; varValue.vt = VT_BOOL; varValue.boolVal = VARIANT_TRUE; (void)props->Write( 1, &option, &varValue ); } if ( setCustomProps ) { setCustomProps( props.Get() ); } hr = frame->Initialize( props.Get() ); if ( FAILED(hr) ) return hr; hr = frame->SetSize( desc.Width , desc.Height ); if ( FAILED(hr) ) return hr; hr = frame->SetResolution( 72, 72 ); if ( FAILED(hr) ) return hr; // Pick a target format WICPixelFormatGUID targetGuid; if ( targetFormat ) { targetGuid = *targetFormat; } else { // Screenshots dont typically include the alpha channel of the render target switch ( desc.Format ) { #if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) || defined(_WIN7_PLATFORM_UPDATE) case DXGI_FORMAT_R32G32B32A32_FLOAT: case DXGI_FORMAT_R16G16B16A16_FLOAT: if ( g_WIC2 ) { targetGuid = GUID_WICPixelFormat96bppRGBFloat; } else { targetGuid = GUID_WICPixelFormat24bppBGR; } break; #endif case DXGI_FORMAT_R16G16B16A16_UNORM: targetGuid = GUID_WICPixelFormat48bppBGR; break; case DXGI_FORMAT_B5G5R5A1_UNORM: targetGuid = GUID_WICPixelFormat16bppBGR555; break; case DXGI_FORMAT_B5G6R5_UNORM: targetGuid = GUID_WICPixelFormat16bppBGR565; break; case DXGI_FORMAT_R32_FLOAT: case DXGI_FORMAT_R16_FLOAT: case DXGI_FORMAT_R16_UNORM: case DXGI_FORMAT_R8_UNORM: case DXGI_FORMAT_A8_UNORM: targetGuid = GUID_WICPixelFormat8bppGray; break; default: targetGuid = GUID_WICPixelFormat24bppBGR; break; } } hr = frame->SetPixelFormat( &targetGuid ); if ( FAILED(hr) ) return hr; if ( targetFormat && memcmp( targetFormat, &targetGuid, sizeof(WICPixelFormatGUID) ) != 0 ) { // Requested output pixel format is not supported by the WIC codec return E_FAIL; } // Encode WIC metadata ComPtr metawriter; if ( SUCCEEDED( frame->GetMetadataQueryWriter( metawriter.GetAddressOf() ) ) ) { PROPVARIANT value; PropVariantInit( &value ); value.vt = VT_LPSTR; value.pszVal = "DirectXTK"; if ( memcmp( &guidContainerFormat, &GUID_ContainerFormatPng, sizeof(GUID) ) == 0 ) { // Set Software name (void)metawriter->SetMetadataByName( L"/tEXt/{str=Software}", &value ); // Set sRGB chunk if ( sRGB ) { value.vt = VT_UI1; value.bVal = 0; (void)metawriter->SetMetadataByName( L"/sRGB/RenderingIntent", &value ); } } else { // Set Software name (void)metawriter->SetMetadataByName( L"System.ApplicationName", &value ); if ( sRGB ) { // Set JPEG EXIF Colorspace of sRGB value.vt = VT_UI2; value.uiVal = 1; (void)metawriter->SetMetadataByName( L"System.Image.ColorSpace", &value ); } } } D3D11_MAPPED_SUBRESOURCE mapped; hr = pContext->Map( pStaging.Get(), 0, D3D11_MAP_READ, 0, &mapped ); if ( FAILED(hr) ) return hr; if ( memcmp( &targetGuid, &pfGuid, sizeof(WICPixelFormatGUID) ) != 0 ) { // Conversion required to write ComPtr source; hr = pWIC->CreateBitmapFromMemory( desc.Width, desc.Height, pfGuid, mapped.RowPitch, mapped.RowPitch * desc.Height, reinterpret_cast( mapped.pData ), source.GetAddressOf() ); if ( FAILED(hr) ) { pContext->Unmap( pStaging.Get(), 0 ); return hr; } ComPtr FC; hr = pWIC->CreateFormatConverter( FC.GetAddressOf() ); if ( FAILED(hr) ) { pContext->Unmap( pStaging.Get(), 0 ); return hr; } BOOL canConvert = FALSE; hr = FC->CanConvert( pfGuid, targetGuid, &canConvert ); if ( FAILED(hr) || !canConvert ) { return E_UNEXPECTED; } hr = FC->Initialize( source.Get(), targetGuid, WICBitmapDitherTypeNone, 0, 0, WICBitmapPaletteTypeCustom ); if ( FAILED(hr) ) { pContext->Unmap( pStaging.Get(), 0 ); return hr; } WICRect rect = { 0, 0, static_cast( desc.Width ), static_cast( desc.Height ) }; hr = frame->WriteSource( FC.Get(), &rect ); if ( FAILED(hr) ) { pContext->Unmap( pStaging.Get(), 0 ); return hr; } } else { // No conversion required hr = frame->WritePixels( desc.Height, mapped.RowPitch, mapped.RowPitch * desc.Height, reinterpret_cast( mapped.pData ) ); if ( FAILED(hr) ) return hr; } pContext->Unmap( pStaging.Get(), 0 ); hr = frame->Commit(); if ( FAILED(hr) ) return hr; hr = encoder->Commit(); if ( FAILED(hr) ) return hr; return S_OK; } #endif // !WINAPI_FAMILY || (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP) || (_WIN32_WINNT > _WIN32_WINNT_WIN8) ================================================ FILE: 3rdParty/DirectXTex/ScreenGrab/ScreenGrab.h ================================================ //-------------------------------------------------------------------------------------- // File: ScreenGrab.h // // Function for capturing a 2D texture and saving it to a file (aka a 'screenshot' // when used on a Direct3D 11 Render Target). // // Note these functions are useful as a light-weight runtime screen grabber. For // full-featured texture capture, DDS writer, and texture processing pipeline, // see the 'Texconv' sample and the 'DirectXTex' library. // // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A // PARTICULAR PURPOSE. // // Copyright (c) Microsoft Corporation. All rights reserved. // // http://go.microsoft.com/fwlink/?LinkId=248926 // http://go.microsoft.com/fwlink/?LinkId=248929 //-------------------------------------------------------------------------------------- #ifdef _MSC_VER #pragma once #endif #include #include #pragma warning(push) #pragma warning(disable : 4005) #include #pragma warning(pop) #include namespace DirectX { HRESULT SaveDDSTextureToFile( _In_ ID3D11DeviceContext* pContext, _In_ ID3D11Resource* pSource, _In_z_ LPCWSTR fileName ); #if !defined(WINAPI_FAMILY) || (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP) || (_WIN32_WINNT > _WIN32_WINNT_WIN8) HRESULT SaveWICTextureToFile( _In_ ID3D11DeviceContext* pContext, _In_ ID3D11Resource* pSource, _In_ REFGUID guidContainerFormat, _In_z_ LPCWSTR fileName, _In_opt_ const GUID* targetFormat = nullptr, _In_opt_ std::function setCustomProps = nullptr ); #endif } ================================================ FILE: 3rdParty/DirectXTex/Texassemble/Texassemble_Desktop_2012.sln ================================================ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 2012 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "texassemble", "Texassemble_Desktop_2012.vcxproj", "{8F18CBD7-4116-4956-BCD8-20D688A4CBD1}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DirectXTex", "..\DirectXTex\DirectXTex_Desktop_2012.vcxproj", "{371B9FA9-4C90-4AC6-A123-ACED756D6C77}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Debug|x64 = Debug|x64 Profile|Win32 = Profile|Win32 Profile|x64 = Profile|x64 Release|Win32 = Release|Win32 Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {8F18CBD7-4116-4956-BCD8-20D688A4CBD1}.Debug|Win32.ActiveCfg = Debug|Win32 {8F18CBD7-4116-4956-BCD8-20D688A4CBD1}.Debug|Win32.Build.0 = Debug|Win32 {8F18CBD7-4116-4956-BCD8-20D688A4CBD1}.Debug|x64.ActiveCfg = Debug|x64 {8F18CBD7-4116-4956-BCD8-20D688A4CBD1}.Debug|x64.Build.0 = Debug|x64 {8F18CBD7-4116-4956-BCD8-20D688A4CBD1}.Profile|Win32.ActiveCfg = Profile|Win32 {8F18CBD7-4116-4956-BCD8-20D688A4CBD1}.Profile|Win32.Build.0 = Profile|Win32 {8F18CBD7-4116-4956-BCD8-20D688A4CBD1}.Profile|x64.ActiveCfg = Profile|x64 {8F18CBD7-4116-4956-BCD8-20D688A4CBD1}.Profile|x64.Build.0 = Profile|x64 {8F18CBD7-4116-4956-BCD8-20D688A4CBD1}.Release|Win32.ActiveCfg = Release|Win32 {8F18CBD7-4116-4956-BCD8-20D688A4CBD1}.Release|Win32.Build.0 = Release|Win32 {8F18CBD7-4116-4956-BCD8-20D688A4CBD1}.Release|x64.ActiveCfg = Release|x64 {8F18CBD7-4116-4956-BCD8-20D688A4CBD1}.Release|x64.Build.0 = Release|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Debug|Win32.ActiveCfg = Debug|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Debug|Win32.Build.0 = Debug|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Debug|x64.ActiveCfg = Debug|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Debug|x64.Build.0 = Debug|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Profile|Win32.ActiveCfg = Profile|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Profile|Win32.Build.0 = Profile|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Profile|x64.ActiveCfg = Profile|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Profile|x64.Build.0 = Profile|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Release|Win32.ActiveCfg = Release|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Release|Win32.Build.0 = Release|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Release|x64.ActiveCfg = Release|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal ================================================ FILE: 3rdParty/DirectXTex/Texassemble/Texassemble_Desktop_2012.vcxproj ================================================  Debug Win32 Debug x64 Profile Win32 Profile x64 Release Win32 Release x64 texassemble {8F18CBD7-4116-4956-BCD8-20D688A4CBD1} texassemble Win32Proj $(VCTargetsPath11) Application Unicode v110 Application Unicode v110 Application true Unicode v110 Application true Unicode v110 Application true Unicode v110 Application true Unicode v110 true true $(ExecutablePath) $(IncludePath) $(LibraryPath) true true $(ExecutablePath) $(IncludePath) $(LibraryPath) false true $(ExecutablePath) $(IncludePath) $(LibraryPath) false true $(ExecutablePath) $(IncludePath) $(LibraryPath) false true $(ExecutablePath) $(IncludePath) $(LibraryPath) false true $(ExecutablePath) $(IncludePath) $(LibraryPath) Level4 Disabled MultiThreadedDebugDLL false true Fast StreamingSIMDExtensions2 Sync ..\DirectXTex;%(AdditionalIncludeDirectories) %(AdditionalOptions) WIN32;_DEBUG;DEBUG;PROFILE;_CONSOLE;D3DXFX_LARGEADDRESS_HANDLE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions) EditAndContinue EnableFastChecks %(AdditionalOptions) ole32.lib;windowscodecs.lib;uuid.lib;%(AdditionalDependencies) Console true true true true MachineX86 AsInvoker %(DelayLoadDLLs) false Level4 Disabled MultiThreadedDebugDLL false true Fast Sync ..\DirectXTex;%(AdditionalIncludeDirectories) %(AdditionalOptions) WIN32;_DEBUG;DEBUG;PROFILE;_CONSOLE;D3DXFX_LARGEADDRESS_HANDLE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions) EnableFastChecks %(AdditionalOptions) ole32.lib;windowscodecs.lib;uuid.lib;%(AdditionalDependencies) Console true true true true MachineX64 AsInvoker %(DelayLoadDLLs) false Level4 MaxSpeed MultiThreadedDLL false true true Fast StreamingSIMDExtensions2 Sync ..\DirectXTex;%(AdditionalIncludeDirectories) %(AdditionalOptions) WIN32;NDEBUG;_CONSOLE;D3DXFX_LARGEADDRESS_HANDLE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions) %(AdditionalOptions) ole32.lib;windowscodecs.lib;uuid.lib;%(AdditionalDependencies) true Console true true true true true MachineX86 AsInvoker %(DelayLoadDLLs) false Level4 MaxSpeed MultiThreadedDLL false true true Fast Sync ..\DirectXTex;%(AdditionalIncludeDirectories) %(AdditionalOptions) WIN32;NDEBUG;_CONSOLE;D3DXFX_LARGEADDRESS_HANDLE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions) %(AdditionalOptions) ole32.lib;windowscodecs.lib;uuid.lib;%(AdditionalDependencies) true Console true true true true true MachineX64 AsInvoker %(DelayLoadDLLs) false Level4 MaxSpeed MultiThreadedDLL false true true Fast StreamingSIMDExtensions2 Sync ..\DirectXTex;%(AdditionalIncludeDirectories) %(AdditionalOptions) WIN32;NDEBUG;PROFILE;_CONSOLE;D3DXFX_LARGEADDRESS_HANDLE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions) %(AdditionalOptions) ole32.lib;windowscodecs.lib;uuid.lib;%(AdditionalDependencies) true Console true true true true true MachineX86 AsInvoker %(DelayLoadDLLs) false Level4 MaxSpeed MultiThreadedDLL false true true Fast Sync ..\DirectXTex;%(AdditionalIncludeDirectories) %(AdditionalOptions) WIN32;NDEBUG;PROFILE;_CONSOLE;D3DXFX_LARGEADDRESS_HANDLE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions) %(AdditionalOptions) ole32.lib;windowscodecs.lib;uuid.lib;%(AdditionalDependencies) true Console true true true true true MachineX64 AsInvoker %(DelayLoadDLLs) false {371b9fa9-4c90-4ac6-a123-aced756d6c77} ================================================ FILE: 3rdParty/DirectXTex/Texassemble/Texassemble_Desktop_2012.vcxproj.filters ================================================  {8e114980-c1a3-4ada-ad7c-83caadf5daeb} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe Resource Files ================================================ FILE: 3rdParty/DirectXTex/Texassemble/Texassemble_Desktop_2013.sln ================================================ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 2013 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "texassemble", "Texassemble_Desktop_2013.vcxproj", "{8F18CBD7-4116-4956-BCD8-20D688A4CBD1}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DirectXTex", "..\DirectXTex\DirectXTex_Desktop_2013.vcxproj", "{371B9FA9-4C90-4AC6-A123-ACED756D6C77}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Debug|x64 = Debug|x64 Profile|Win32 = Profile|Win32 Profile|x64 = Profile|x64 Release|Win32 = Release|Win32 Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {8F18CBD7-4116-4956-BCD8-20D688A4CBD1}.Debug|Win32.ActiveCfg = Debug|Win32 {8F18CBD7-4116-4956-BCD8-20D688A4CBD1}.Debug|Win32.Build.0 = Debug|Win32 {8F18CBD7-4116-4956-BCD8-20D688A4CBD1}.Debug|x64.ActiveCfg = Debug|x64 {8F18CBD7-4116-4956-BCD8-20D688A4CBD1}.Debug|x64.Build.0 = Debug|x64 {8F18CBD7-4116-4956-BCD8-20D688A4CBD1}.Profile|Win32.ActiveCfg = Profile|Win32 {8F18CBD7-4116-4956-BCD8-20D688A4CBD1}.Profile|Win32.Build.0 = Profile|Win32 {8F18CBD7-4116-4956-BCD8-20D688A4CBD1}.Profile|x64.ActiveCfg = Profile|x64 {8F18CBD7-4116-4956-BCD8-20D688A4CBD1}.Profile|x64.Build.0 = Profile|x64 {8F18CBD7-4116-4956-BCD8-20D688A4CBD1}.Release|Win32.ActiveCfg = Release|Win32 {8F18CBD7-4116-4956-BCD8-20D688A4CBD1}.Release|Win32.Build.0 = Release|Win32 {8F18CBD7-4116-4956-BCD8-20D688A4CBD1}.Release|x64.ActiveCfg = Release|x64 {8F18CBD7-4116-4956-BCD8-20D688A4CBD1}.Release|x64.Build.0 = Release|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Debug|Win32.ActiveCfg = Debug|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Debug|Win32.Build.0 = Debug|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Debug|x64.ActiveCfg = Debug|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Debug|x64.Build.0 = Debug|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Profile|Win32.ActiveCfg = Profile|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Profile|Win32.Build.0 = Profile|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Profile|x64.ActiveCfg = Profile|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Profile|x64.Build.0 = Profile|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Release|Win32.ActiveCfg = Release|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Release|Win32.Build.0 = Release|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Release|x64.ActiveCfg = Release|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal ================================================ FILE: 3rdParty/DirectXTex/Texassemble/Texassemble_Desktop_2013.vcxproj ================================================  Debug Win32 Debug x64 Profile Win32 Profile x64 Release Win32 Release x64 texassemble {8F18CBD7-4116-4956-BCD8-20D688A4CBD1} texassemble Win32Proj $(VCTargetsPath11) Application Unicode v120 Application Unicode v120 Application true Unicode v120 Application true Unicode v120 Application true Unicode v120 Application true Unicode v120 true true $(ExecutablePath) $(IncludePath) $(LibraryPath) true true $(ExecutablePath) $(IncludePath) $(LibraryPath) false true $(ExecutablePath) $(IncludePath) $(LibraryPath) false true $(ExecutablePath) $(IncludePath) $(LibraryPath) false true $(ExecutablePath) $(IncludePath) $(LibraryPath) false true $(ExecutablePath) $(IncludePath) $(LibraryPath) Level4 Disabled MultiThreadedDebugDLL false true Fast StreamingSIMDExtensions2 Sync ..\DirectXTex;%(AdditionalIncludeDirectories) %(AdditionalOptions) WIN32;_DEBUG;DEBUG;PROFILE;_CONSOLE;D3DXFX_LARGEADDRESS_HANDLE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions) EditAndContinue EnableFastChecks %(AdditionalOptions) ole32.lib;windowscodecs.lib;uuid.lib;%(AdditionalDependencies) Console true true true true MachineX86 AsInvoker %(DelayLoadDLLs) false Level4 Disabled MultiThreadedDebugDLL false true Fast Sync ..\DirectXTex;%(AdditionalIncludeDirectories) %(AdditionalOptions) WIN32;_DEBUG;DEBUG;PROFILE;_CONSOLE;D3DXFX_LARGEADDRESS_HANDLE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions) EnableFastChecks %(AdditionalOptions) ole32.lib;windowscodecs.lib;uuid.lib;%(AdditionalDependencies) Console true true true true MachineX64 AsInvoker %(DelayLoadDLLs) false Level4 MaxSpeed MultiThreadedDLL false true true Fast StreamingSIMDExtensions2 Sync ..\DirectXTex;%(AdditionalIncludeDirectories) %(AdditionalOptions) WIN32;NDEBUG;_CONSOLE;D3DXFX_LARGEADDRESS_HANDLE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions) %(AdditionalOptions) ole32.lib;windowscodecs.lib;uuid.lib;%(AdditionalDependencies) true Console true true true true true MachineX86 AsInvoker %(DelayLoadDLLs) false Level4 MaxSpeed MultiThreadedDLL false true true Fast Sync ..\DirectXTex;%(AdditionalIncludeDirectories) %(AdditionalOptions) WIN32;NDEBUG;_CONSOLE;D3DXFX_LARGEADDRESS_HANDLE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions) %(AdditionalOptions) ole32.lib;windowscodecs.lib;uuid.lib;%(AdditionalDependencies) true Console true true true true true MachineX64 AsInvoker %(DelayLoadDLLs) false Level4 MaxSpeed MultiThreadedDLL false true true Fast StreamingSIMDExtensions2 Sync ..\DirectXTex;%(AdditionalIncludeDirectories) %(AdditionalOptions) WIN32;NDEBUG;PROFILE;_CONSOLE;D3DXFX_LARGEADDRESS_HANDLE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions) %(AdditionalOptions) ole32.lib;windowscodecs.lib;uuid.lib;%(AdditionalDependencies) true Console true true true true true MachineX86 AsInvoker %(DelayLoadDLLs) false Level4 MaxSpeed MultiThreadedDLL false true true Fast Sync ..\DirectXTex;%(AdditionalIncludeDirectories) %(AdditionalOptions) WIN32;NDEBUG;PROFILE;_CONSOLE;D3DXFX_LARGEADDRESS_HANDLE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions) %(AdditionalOptions) ole32.lib;windowscodecs.lib;uuid.lib;%(AdditionalDependencies) true Console true true true true true MachineX64 AsInvoker %(DelayLoadDLLs) false {371b9fa9-4c90-4ac6-a123-aced756d6c77} ================================================ FILE: 3rdParty/DirectXTex/Texassemble/Texassemble_Desktop_2013.vcxproj.filters ================================================  {8e114980-c1a3-4ada-ad7c-83caadf5daeb} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe Resource Files ================================================ FILE: 3rdParty/DirectXTex/Texassemble/Texassemble_Desktop_2015.sln ================================================ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 2015 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "texassemble", "Texassemble_Desktop_2015.vcxproj", "{8F18CBD7-4116-4956-BCD8-20D688A4CBD1}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DirectXTex", "..\DirectXTex\DirectXTex_Desktop_2015.vcxproj", "{371B9FA9-4C90-4AC6-A123-ACED756D6C77}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Debug|x64 = Debug|x64 Profile|Win32 = Profile|Win32 Profile|x64 = Profile|x64 Release|Win32 = Release|Win32 Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {8F18CBD7-4116-4956-BCD8-20D688A4CBD1}.Debug|Win32.ActiveCfg = Debug|Win32 {8F18CBD7-4116-4956-BCD8-20D688A4CBD1}.Debug|Win32.Build.0 = Debug|Win32 {8F18CBD7-4116-4956-BCD8-20D688A4CBD1}.Debug|x64.ActiveCfg = Debug|x64 {8F18CBD7-4116-4956-BCD8-20D688A4CBD1}.Debug|x64.Build.0 = Debug|x64 {8F18CBD7-4116-4956-BCD8-20D688A4CBD1}.Profile|Win32.ActiveCfg = Profile|Win32 {8F18CBD7-4116-4956-BCD8-20D688A4CBD1}.Profile|Win32.Build.0 = Profile|Win32 {8F18CBD7-4116-4956-BCD8-20D688A4CBD1}.Profile|x64.ActiveCfg = Profile|x64 {8F18CBD7-4116-4956-BCD8-20D688A4CBD1}.Profile|x64.Build.0 = Profile|x64 {8F18CBD7-4116-4956-BCD8-20D688A4CBD1}.Release|Win32.ActiveCfg = Release|Win32 {8F18CBD7-4116-4956-BCD8-20D688A4CBD1}.Release|Win32.Build.0 = Release|Win32 {8F18CBD7-4116-4956-BCD8-20D688A4CBD1}.Release|x64.ActiveCfg = Release|x64 {8F18CBD7-4116-4956-BCD8-20D688A4CBD1}.Release|x64.Build.0 = Release|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Debug|Win32.ActiveCfg = Debug|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Debug|Win32.Build.0 = Debug|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Debug|x64.ActiveCfg = Debug|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Debug|x64.Build.0 = Debug|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Profile|Win32.ActiveCfg = Profile|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Profile|Win32.Build.0 = Profile|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Profile|x64.ActiveCfg = Profile|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Profile|x64.Build.0 = Profile|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Release|Win32.ActiveCfg = Release|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Release|Win32.Build.0 = Release|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Release|x64.ActiveCfg = Release|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal ================================================ FILE: 3rdParty/DirectXTex/Texassemble/Texassemble_Desktop_2015.vcxproj ================================================  Debug Win32 Debug x64 Profile Win32 Profile x64 Release Win32 Release x64 texassemble {8F18CBD7-4116-4956-BCD8-20D688A4CBD1} texassemble Win32Proj Application Unicode v140 Application Unicode v140 Application true Unicode v140 Application true Unicode v140 Application true Unicode v140 Application true Unicode v140 true true $(ExecutablePath) $(IncludePath) $(LibraryPath) true true $(ExecutablePath) $(IncludePath) $(LibraryPath) false true $(ExecutablePath) $(IncludePath) $(LibraryPath) false true $(ExecutablePath) $(IncludePath) $(LibraryPath) false true $(ExecutablePath) $(IncludePath) $(LibraryPath) false true $(ExecutablePath) $(IncludePath) $(LibraryPath) Level4 Disabled MultiThreadedDebugDLL false true Fast StreamingSIMDExtensions2 Sync ..\DirectXTex;%(AdditionalIncludeDirectories) %(AdditionalOptions) WIN32;_DEBUG;DEBUG;PROFILE;_CONSOLE;D3DXFX_LARGEADDRESS_HANDLE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions) EditAndContinue EnableFastChecks %(AdditionalOptions) ole32.lib;windowscodecs.lib;uuid.lib;%(AdditionalDependencies) Console true true true true MachineX86 AsInvoker %(DelayLoadDLLs) false Level4 Disabled MultiThreadedDebugDLL false true Fast Sync ..\DirectXTex;%(AdditionalIncludeDirectories) %(AdditionalOptions) WIN32;_DEBUG;DEBUG;PROFILE;_CONSOLE;D3DXFX_LARGEADDRESS_HANDLE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions) EnableFastChecks %(AdditionalOptions) ole32.lib;windowscodecs.lib;uuid.lib;%(AdditionalDependencies) Console true true true true MachineX64 AsInvoker %(DelayLoadDLLs) false Level4 MaxSpeed MultiThreadedDLL false true true Fast StreamingSIMDExtensions2 Sync ..\DirectXTex;%(AdditionalIncludeDirectories) %(AdditionalOptions) WIN32;NDEBUG;_CONSOLE;D3DXFX_LARGEADDRESS_HANDLE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions) %(AdditionalOptions) ole32.lib;windowscodecs.lib;uuid.lib;%(AdditionalDependencies) true Console true true true true true MachineX86 AsInvoker %(DelayLoadDLLs) false Level4 MaxSpeed MultiThreadedDLL false true true Fast Sync ..\DirectXTex;%(AdditionalIncludeDirectories) %(AdditionalOptions) WIN32;NDEBUG;_CONSOLE;D3DXFX_LARGEADDRESS_HANDLE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions) %(AdditionalOptions) ole32.lib;windowscodecs.lib;uuid.lib;%(AdditionalDependencies) true Console true true true true true MachineX64 AsInvoker %(DelayLoadDLLs) false Level4 MaxSpeed MultiThreadedDLL false true true Fast StreamingSIMDExtensions2 Sync ..\DirectXTex;%(AdditionalIncludeDirectories) %(AdditionalOptions) WIN32;NDEBUG;PROFILE;_CONSOLE;D3DXFX_LARGEADDRESS_HANDLE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions) %(AdditionalOptions) ole32.lib;windowscodecs.lib;uuid.lib;%(AdditionalDependencies) true Console true true true true true MachineX86 AsInvoker %(DelayLoadDLLs) false Level4 MaxSpeed MultiThreadedDLL false true true Fast Sync ..\DirectXTex;%(AdditionalIncludeDirectories) %(AdditionalOptions) WIN32;NDEBUG;PROFILE;_CONSOLE;D3DXFX_LARGEADDRESS_HANDLE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions) %(AdditionalOptions) ole32.lib;windowscodecs.lib;uuid.lib;%(AdditionalDependencies) true Console true true true true true MachineX64 AsInvoker %(DelayLoadDLLs) false {371b9fa9-4c90-4ac6-a123-aced756d6c77} ================================================ FILE: 3rdParty/DirectXTex/Texassemble/Texassemble_Desktop_2015.vcxproj.filters ================================================  {8e114980-c1a3-4ada-ad7c-83caadf5daeb} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe Resource Files ================================================ FILE: 3rdParty/DirectXTex/Texassemble/texassemble.cpp ================================================ //-------------------------------------------------------------------------------------- // File: Texassemble.cpp // // DirectX 11 Texture assembler for cube maps, volume maps, and arrays // // Copyright (c) Microsoft Corporation. All rights reserved. //-------------------------------------------------------------------------------------- #include #include #include #include #include #include #include #include "directxtex.h" using namespace DirectX; enum OPTIONS // Note: dwOptions below assumes 32 or less options. { OPT_CUBE = 1, OPT_VOLUME, OPT_ARRAY, OPT_CUBEARRAY, OPT_WIDTH, OPT_HEIGHT, OPT_FORMAT, OPT_FILTER, OPT_OUTPUTFILE, OPT_USE_DX10, OPT_NOLOGO, OPT_SEPALPHA, OPT_MAX }; static_assert( OPT_MAX <= 32, "dwOptions is a DWORD bitfield" ); struct SConversion { WCHAR szSrc [MAX_PATH]; }; struct SValue { LPCWSTR pName; DWORD dwValue; }; ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// SValue g_pOptions[] = { { L"cube", OPT_CUBE }, { L"volume", OPT_VOLUME }, { L"array", OPT_ARRAY }, { L"cubearray", OPT_CUBEARRAY }, { L"w", OPT_WIDTH }, { L"h", OPT_HEIGHT }, { L"f", OPT_FORMAT }, { L"if", OPT_FILTER }, { L"o", OPT_OUTPUTFILE }, { L"dx10", OPT_USE_DX10 }, { L"nologo", OPT_NOLOGO }, { L"sepalpha", OPT_SEPALPHA }, { nullptr, 0 } }; #define DEFFMT(fmt) { L#fmt, DXGI_FORMAT_ ## fmt } SValue g_pFormats[] = { // List does not include _TYPELESS or depth/stencil formats DEFFMT(R32G32B32A32_FLOAT), DEFFMT(R32G32B32A32_UINT), DEFFMT(R32G32B32A32_SINT), DEFFMT(R32G32B32_FLOAT), DEFFMT(R32G32B32_UINT), DEFFMT(R32G32B32_SINT), DEFFMT(R16G16B16A16_FLOAT), DEFFMT(R16G16B16A16_UNORM), DEFFMT(R16G16B16A16_UINT), DEFFMT(R16G16B16A16_SNORM), DEFFMT(R16G16B16A16_SINT), DEFFMT(R32G32_FLOAT), DEFFMT(R32G32_UINT), DEFFMT(R32G32_SINT), DEFFMT(R10G10B10A2_UNORM), DEFFMT(R10G10B10A2_UINT), DEFFMT(R11G11B10_FLOAT), DEFFMT(R8G8B8A8_UNORM), DEFFMT(R8G8B8A8_UNORM_SRGB), DEFFMT(R8G8B8A8_UINT), DEFFMT(R8G8B8A8_SNORM), DEFFMT(R8G8B8A8_SINT), DEFFMT(R16G16_FLOAT), DEFFMT(R16G16_UNORM), DEFFMT(R16G16_UINT), DEFFMT(R16G16_SNORM), DEFFMT(R16G16_SINT), DEFFMT(R32_FLOAT), DEFFMT(R32_UINT), DEFFMT(R32_SINT), DEFFMT(R8G8_UNORM), DEFFMT(R8G8_UINT), DEFFMT(R8G8_SNORM), DEFFMT(R8G8_SINT), DEFFMT(R16_FLOAT), DEFFMT(R16_UNORM), DEFFMT(R16_UINT), DEFFMT(R16_SNORM), DEFFMT(R16_SINT), DEFFMT(R8_UNORM), DEFFMT(R8_UINT), DEFFMT(R8_SNORM), DEFFMT(R8_SINT), DEFFMT(A8_UNORM), //DEFFMT(R1_UNORM) DEFFMT(R9G9B9E5_SHAREDEXP), DEFFMT(R8G8_B8G8_UNORM), DEFFMT(G8R8_G8B8_UNORM), DEFFMT(B5G6R5_UNORM), DEFFMT(B5G5R5A1_UNORM), // DXGI 1.1 formats DEFFMT(B8G8R8A8_UNORM), DEFFMT(B8G8R8X8_UNORM), DEFFMT(R10G10B10_XR_BIAS_A2_UNORM), DEFFMT(B8G8R8A8_UNORM_SRGB), DEFFMT(B8G8R8X8_UNORM_SRGB), // DXGI 1.2 formats DEFFMT(B4G4R4A4_UNORM), { nullptr, DXGI_FORMAT_UNKNOWN } }; SValue g_pFilters[] = { { L"POINT", TEX_FILTER_POINT }, { L"LINEAR", TEX_FILTER_LINEAR }, { L"CUBIC", TEX_FILTER_CUBIC }, { L"FANT", TEX_FILTER_FANT }, { L"BOX", TEX_FILTER_BOX }, { L"TRIANGLE", TEX_FILTER_TRIANGLE }, { L"POINT_DITHER", TEX_FILTER_POINT | TEX_FILTER_DITHER }, { L"LINEAR_DITHER", TEX_FILTER_LINEAR | TEX_FILTER_DITHER }, { L"CUBIC_DITHER", TEX_FILTER_CUBIC | TEX_FILTER_DITHER }, { L"FANT_DITHER", TEX_FILTER_FANT | TEX_FILTER_DITHER }, { L"BOX_DITHER", TEX_FILTER_BOX | TEX_FILTER_DITHER }, { L"TRIANGLE_DITHER", TEX_FILTER_TRIANGLE | TEX_FILTER_DITHER }, { L"POINT_DITHER_DIFFUSION", TEX_FILTER_POINT | TEX_FILTER_DITHER_DIFFUSION }, { L"LINEAR_DITHER_DIFFUSION", TEX_FILTER_LINEAR | TEX_FILTER_DITHER_DIFFUSION }, { L"CUBIC_DITHER_DIFFUSION", TEX_FILTER_CUBIC | TEX_FILTER_DITHER_DIFFUSION }, { L"FANT_DITHER_DIFFUSION", TEX_FILTER_FANT | TEX_FILTER_DITHER_DIFFUSION }, { L"BOX_DITHER_DIFFUSION", TEX_FILTER_BOX | TEX_FILTER_DITHER_DIFFUSION }, { L"TRIANGLE_DITHER_DIFFUSION", TEX_FILTER_TRIANGLE | TEX_FILTER_DITHER_DIFFUSION }, { nullptr, TEX_FILTER_DEFAULT } }; ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// #pragma prefast(disable : 26018, "Only used with static internal arrays") DWORD LookupByName(const WCHAR *pName, const SValue *pArray) { while(pArray->pName) { if(!_wcsicmp(pName, pArray->pName)) return pArray->dwValue; pArray++; } return 0; } const WCHAR* LookupByValue(DWORD pValue, const SValue *pArray) { while(pArray->pName) { if(pValue == pArray->dwValue) return pArray->pName; pArray++; } return L""; } void PrintFormat(DXGI_FORMAT Format) { for(SValue *pFormat = g_pFormats; pFormat->pName; pFormat++) { if((DXGI_FORMAT) pFormat->dwValue == Format) { wprintf( pFormat->pName ); break; } } } void PrintInfo( const TexMetadata& info ) { wprintf( L" (%Iux%Iu", info.width, info.height); if ( TEX_DIMENSION_TEXTURE3D == info.dimension ) wprintf( L"x%Iu", info.depth); if ( info.mipLevels > 1 ) wprintf( L",%Iu", info.mipLevels); if ( info.arraySize > 1 ) wprintf( L",%Iu", info.arraySize); wprintf( L" "); PrintFormat( info.format ); switch ( info.dimension ) { case TEX_DIMENSION_TEXTURE1D: wprintf( (info.arraySize > 1) ? L" 1DArray" : L" 1D" ); break; case TEX_DIMENSION_TEXTURE2D: if ( info.IsCubemap() ) { wprintf( (info.arraySize > 6) ? L" CubeArray" : L" Cube" ); } else { wprintf( (info.arraySize > 1) ? L" 2DArray" : L" 2D" ); } break; case TEX_DIMENSION_TEXTURE3D: wprintf( L" 3D"); break; } wprintf( L")"); } void PrintList(size_t cch, SValue *pValue) { while(pValue->pName) { size_t cchName = wcslen(pValue->pName); if(cch + cchName + 2>= 80) { wprintf( L"\n "); cch = 6; } wprintf( L"%ls ", pValue->pName ); cch += cchName + 2; pValue++; } wprintf( L"\n"); } void PrintLogo() { wprintf( L"Microsoft (R) DirectX 11 Texture Assembler (DirectXTex version)\n"); wprintf( L"Copyright (C) Microsoft Corp. All rights reserved.\n"); wprintf( L"\n"); } void PrintUsage() { PrintLogo(); wprintf( L"Usage: texassemble [-cube | - volume | -array | -cubearray] \n"); wprintf( L"\n"); wprintf( L" -cube create cubemap\n"); wprintf( L" -volume create volume map\n"); wprintf( L" -array create texture array\n"); wprintf( L" -cubearray create cubemap array\n"); wprintf( L" -w width\n"); wprintf( L" -h height\n"); wprintf( L" -f format\n"); wprintf( L" -if image filtering\n"); wprintf( L" -o output filename\n"); wprintf( L" -sepalpha resize alpha channel separately from color channels\n"); wprintf( L" -dx10 Force use of 'DX10' extended header\n"); wprintf( L" -nologo suppress copyright message\n"); wprintf( L"\n"); wprintf( L" : "); PrintList(13, g_pFormats); wprintf( L"\n"); wprintf( L" : "); PrintList(13, g_pFilters); } //-------------------------------------------------------------------------------------- // Entry-point //-------------------------------------------------------------------------------------- #pragma prefast(disable : 28198, "Command-line tool, frees all memory on exit") int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[]) { // Parameters and defaults size_t width = 0; size_t height = 0; DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN; DWORD dwFilter = TEX_FILTER_DEFAULT; DWORD dwFilterOpts = 0; WCHAR szOutputFile[MAX_PATH] = { 0 }; // Initialize COM (needed for WIC) HRESULT hr = hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED); if( FAILED(hr) ) { wprintf( L"Failed to initialize COM (%08X)\n", hr); return 1; } // Process command line DWORD dwOptions = 0; std::list conversion; for(int iArg = 1; iArg < argc; iArg++) { PWSTR pArg = argv[iArg]; if(('-' == pArg[0]) || ('/' == pArg[0])) { pArg++; PWSTR pValue; for(pValue = pArg; *pValue && (':' != *pValue); pValue++); if(*pValue) *pValue++ = 0; DWORD dwOption = LookupByName(pArg, g_pOptions); if(!dwOption || (dwOptions & (1 << dwOption))) { PrintUsage(); return 1; } dwOptions |= 1 << dwOption; if( (OPT_NOLOGO != dwOption) && (OPT_SEPALPHA != dwOption) && (OPT_USE_DX10 != dwOption) && (OPT_CUBE != dwOption) && (OPT_VOLUME != dwOption) && (OPT_ARRAY != dwOption) && (OPT_CUBEARRAY != dwOption) ) { if(!*pValue) { if((iArg + 1 >= argc)) { PrintUsage(); return 1; } iArg++; pValue = argv[iArg]; } } switch(dwOption) { case OPT_WIDTH: if (swscanf_s(pValue, L"%Iu", &width) != 1) { wprintf( L"Invalid value specified with -w (%ls)\n", pValue); return 1; } break; case OPT_HEIGHT: if (swscanf_s(pValue, L"%Iu", &height) != 1) { wprintf( L"Invalid value specified with -h (%ls)\n", pValue); return 1; } break; case OPT_FORMAT: format = (DXGI_FORMAT) LookupByName(pValue, g_pFormats); if ( !format ) { wprintf( L"Invalid value specified with -f (%ls)\n", pValue); return 1; } break; case OPT_FILTER: dwFilter = LookupByName(pValue, g_pFilters); if ( !dwFilter ) { wprintf( L"Invalid value specified with -if (%ls)\n", pValue); return 1; } break; case OPT_SEPALPHA: dwFilterOpts |= TEX_FILTER_SEPARATE_ALPHA; break; case OPT_OUTPUTFILE: wcscpy_s(szOutputFile, MAX_PATH, pValue); break; } } else { SConversion conv; wcscpy_s(conv.szSrc, MAX_PATH, pArg); conversion.push_back(conv); } } if(conversion.empty()) { PrintUsage(); return 0; } switch( dwOptions & ( (1 << OPT_CUBE) | (1 << OPT_VOLUME) | (1 << OPT_ARRAY) | (1 << OPT_CUBEARRAY) ) ) { case (1 << OPT_VOLUME): case (1 << OPT_ARRAY): case (1 << OPT_CUBE): case (1 << OPT_CUBEARRAY): break; default: wprintf( L"Must use one of: -cube, -volume, -array, or -cubearray\n\n" ); return 1; } if(~dwOptions & (1 << OPT_NOLOGO)) PrintLogo(); // Convert images size_t images = 0; std::vector> loadedImages; for( auto pConv = conversion.begin(); pConv != conversion.end(); ++pConv ) { WCHAR ext[_MAX_EXT]; WCHAR fname[_MAX_FNAME]; _wsplitpath_s( pConv->szSrc, nullptr, 0, nullptr, 0, fname, _MAX_FNAME, ext, _MAX_EXT ); // Load source image if( pConv != conversion.begin() ) wprintf( L"\n"); else if ( !*szOutputFile ) { if ( _wcsicmp( ext, L".dds" ) == 0 ) { wprintf( L"ERROR: Need to specify output file via -o\n"); return 1; } _wmakepath_s( szOutputFile, nullptr, nullptr, fname, L".dds" ); } wprintf( L"reading %ls", pConv->szSrc ); fflush(stdout); TexMetadata info; std::unique_ptr image( new (std::nothrow) ScratchImage ); if ( !image ) { wprintf( L" ERROR: Memory allocation failed\n" ); return 1; } if ( _wcsicmp( ext, L".dds" ) == 0 ) { hr = LoadFromDDSFile( pConv->szSrc, DDS_FLAGS_NONE, &info, *image.get() ); if ( FAILED(hr) ) { wprintf( L" FAILED (%x)\n", hr); return 1; } if ( info.depth > 1 || info.mipLevels > 1 || info.IsCubemap() ) { wprintf( L" ERROR: Can't assemble complex surfaces\n" ); return 1; } } else if ( _wcsicmp( ext, L".tga" ) == 0 ) { hr = LoadFromTGAFile( pConv->szSrc, &info, *image.get() ); if ( FAILED(hr) ) { wprintf( L" FAILED (%x)\n", hr); return 1; } } else { // WIC shares the same filter values for mode and dither static_assert( WIC_FLAGS_DITHER == TEX_FILTER_DITHER, "WIC_FLAGS_* & TEX_FILTER_* should match" ); static_assert( WIC_FLAGS_DITHER_DIFFUSION == TEX_FILTER_DITHER_DIFFUSION, "WIC_FLAGS_* & TEX_FILTER_* should match" ); static_assert( WIC_FLAGS_FILTER_POINT == TEX_FILTER_POINT, "WIC_FLAGS_* & TEX_FILTER_* should match" ); static_assert( WIC_FLAGS_FILTER_LINEAR == TEX_FILTER_LINEAR, "WIC_FLAGS_* & TEX_FILTER_* should match" ); static_assert( WIC_FLAGS_FILTER_CUBIC == TEX_FILTER_CUBIC, "WIC_FLAGS_* & TEX_FILTER_* should match" ); static_assert( WIC_FLAGS_FILTER_FANT == TEX_FILTER_FANT, "WIC_FLAGS_* & TEX_FILTER_* should match" ); hr = LoadFromWICFile( pConv->szSrc, dwFilter | WIC_FLAGS_ALL_FRAMES, &info, *image.get() ); if ( FAILED(hr) ) { wprintf( L" FAILED (%x)\n", hr); return 1; } } PrintInfo( info ); // Convert texture fflush(stdout); // --- Decompress -------------------------------------------------------------- if ( IsCompressed( info.format ) ) { const Image* img = image->GetImage(0,0,0); assert( img ); size_t nimg = image->GetImageCount(); std::unique_ptr timage( new (std::nothrow) ScratchImage ); if ( !timage ) { wprintf( L" ERROR: Memory allocation failed\n" ); return 1; } hr = Decompress( img, nimg, info, DXGI_FORMAT_UNKNOWN /* picks good default */, *timage.get() ); if ( FAILED(hr) ) { wprintf( L" FAILED [decompress] (%x)\n", hr); continue; } const TexMetadata& tinfo = timage->GetMetadata(); info.format = tinfo.format; assert( info.width == tinfo.width ); assert( info.height == tinfo.height ); assert( info.depth == tinfo.depth ); assert( info.arraySize == tinfo.arraySize ); assert( info.mipLevels == tinfo.mipLevels ); assert( info.miscFlags == tinfo.miscFlags ); assert( info.miscFlags2 == tinfo.miscFlags2 ); assert( info.dimension == tinfo.dimension ); image.swap( timage ); } // --- Resize ------------------------------------------------------------------ if ( !width ) { width = info.width; } if ( !height ) { height = info.height; } if ( info.width != width || info.height != height ) { std::unique_ptr timage( new (std::nothrow) ScratchImage ); if ( !timage ) { wprintf( L" ERROR: Memory allocation failed\n" ); return 1; } hr = Resize( image->GetImages(), image->GetImageCount(), image->GetMetadata(), width, height, dwFilter | dwFilterOpts, *timage.get() ); if ( FAILED(hr) ) { wprintf( L" FAILED [resize] (%x)\n", hr); return 1; } const TexMetadata& tinfo = timage->GetMetadata(); assert( tinfo.width == width && tinfo.height == height && tinfo.mipLevels == 1 ); info.width = tinfo.width; info.height = tinfo.height; info.mipLevels = 1; assert( info.depth == tinfo.depth ); assert( info.arraySize == tinfo.arraySize ); assert( info.miscFlags == tinfo.miscFlags ); assert( info.miscFlags2 == tinfo.miscFlags2 ); assert( info.format == tinfo.format ); assert( info.dimension == tinfo.dimension ); image.swap( timage ); } // --- Convert ----------------------------------------------------------------- if ( format == DXGI_FORMAT_UNKNOWN ) { format = info.format; } else if ( info.format != format && !IsCompressed( format ) ) { std::unique_ptr timage( new (std::nothrow) ScratchImage ); if ( !timage ) { wprintf( L" ERROR: Memory allocation failed\n" ); return 1; } hr = Convert( image->GetImages(), image->GetImageCount(), image->GetMetadata(), format, dwFilter | dwFilterOpts, 0.5f, *timage.get() ); if ( FAILED(hr) ) { wprintf( L" FAILED [convert] (%x)\n", hr); return 1; } const TexMetadata& tinfo = timage->GetMetadata(); assert( tinfo.format == format ); info.format = tinfo.format; assert( info.width == tinfo.width ); assert( info.height == tinfo.height ); assert( info.depth == tinfo.depth ); assert( info.arraySize == tinfo.arraySize ); assert( info.mipLevels == tinfo.mipLevels ); assert( info.miscFlags == tinfo.miscFlags ); assert( info.miscFlags2 == tinfo.miscFlags2 ); assert( info.dimension == tinfo.dimension ); image.swap( timage ); } images += info.arraySize; loadedImages.push_back( std::move( image ) ); } if( images < 2 ) { wprintf( L" ERROR: Need at least 2 images to assemble\n\n"); return 1; } switch( dwOptions & ( (1 << OPT_CUBE) | (1 << OPT_VOLUME) | (1 << OPT_ARRAY) | (1 << OPT_CUBEARRAY) ) ) { case (1 << OPT_CUBE): if ( images != 6 ) { wprintf( L" ERROR: -cube requires six images to form the faces of the cubemap\n"); return 1; } break; case (1 << OPT_CUBEARRAY): if ( ( images < 6) || ( images % 6 ) != 0 ) { wprintf( L"-cubearray requires a multiple of 6 images to form the faces of the cubemaps\n"); return 1; } break; } // --- Create result --------------------------------------------------------------- { std::vector imageArray; imageArray.reserve( images ); for( auto it = loadedImages.cbegin(); it != loadedImages.cend(); ++it ) { const ScratchImage* simage = it->get(); assert( simage != 0 ); for( size_t j = 0; j < simage->GetMetadata().arraySize; ++j ) { const Image* img = simage->GetImage(0,j,0); assert( img != 0 ); imageArray.push_back( *img ); } } ScratchImage result; switch( dwOptions & ( (1 << OPT_CUBE) | (1 << OPT_VOLUME) | (1 << OPT_ARRAY) | (1 << OPT_CUBEARRAY) ) ) { case (1 << OPT_VOLUME): hr = result.Initialize3DFromImages( &imageArray[0], imageArray.size() ); break; case (1 << OPT_ARRAY): hr = result.InitializeArrayFromImages( &imageArray[0], imageArray.size(), (dwOptions & (1 << OPT_USE_DX10)) != 0 ); break; case (1 << OPT_CUBE): case (1 << OPT_CUBEARRAY): hr = result.InitializeCubeFromImages( &imageArray[0], imageArray.size() ); break; } if ( FAILED(hr ) ) { wprintf( L"FAILED building result image (%x)\n", hr); return 1; } // Write texture wprintf( L"\nWriting %ls ", szOutputFile); PrintInfo( result.GetMetadata() ); wprintf( L"\n" ); fflush(stdout); hr = SaveToDDSFile( result.GetImages(), result.GetImageCount(), result.GetMetadata(), (dwOptions & (1 << OPT_USE_DX10) ) ? (DDS_FLAGS_FORCE_DX10_EXT|DDS_FLAGS_FORCE_DX10_EXT_MISC2) : DDS_FLAGS_NONE, szOutputFile ); if(FAILED(hr)) { wprintf( L"\nFAILED (%x)\n", hr); return 1; } wprintf( L"\n"); } return 0; } ================================================ FILE: 3rdParty/DirectXTex/Texassemble/texassemble.rc ================================================ // Microsoft Visual C++ generated resource script. // #define APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 2 resource. // #define IDC_STATIC -1 #include ///////////////////////////////////////////////////////////////////////////// #undef APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // English (U.S.) resources #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) #ifdef _WIN32 LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US #pragma code_page(1252) #endif //_WIN32 ///////////////////////////////////////////////////////////////////////////// // // Icon // // Icon with lowest ID value placed first to ensure application icon // remains consistent on all systems. IDI_MAIN_ICON ICON "directx.ico" #ifdef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // TEXTINCLUDE // 1 TEXTINCLUDE BEGIN "resource.h\0" END 2 TEXTINCLUDE BEGIN "#define IDC_STATIC -1\r\n" "#include \r\n" "\r\n" "\r\n" "\0" END 3 TEXTINCLUDE BEGIN "\r\n" "\0" END #endif // APSTUDIO_INVOKED #endif // English (U.S.) resources ///////////////////////////////////////////////////////////////////////////// #ifndef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 3 resource. // ///////////////////////////////////////////////////////////////////////////// #endif // not APSTUDIO_INVOKED ================================================ FILE: 3rdParty/DirectXTex/Texconv/Texconv.rc ================================================ // Microsoft Visual C++ generated resource script. // #define APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 2 resource. // #define IDC_STATIC -1 #include ///////////////////////////////////////////////////////////////////////////// #undef APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // English (U.S.) resources #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) #ifdef _WIN32 LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US #pragma code_page(1252) #endif //_WIN32 ///////////////////////////////////////////////////////////////////////////// // // Icon // // Icon with lowest ID value placed first to ensure application icon // remains consistent on all systems. IDI_MAIN_ICON ICON "directx.ico" #ifdef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // TEXTINCLUDE // 1 TEXTINCLUDE BEGIN "resource.h\0" END 2 TEXTINCLUDE BEGIN "#define IDC_STATIC -1\r\n" "#include \r\n" "\r\n" "\r\n" "\0" END 3 TEXTINCLUDE BEGIN "\r\n" "\0" END #endif // APSTUDIO_INVOKED #endif // English (U.S.) resources ///////////////////////////////////////////////////////////////////////////// #ifndef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 3 resource. // ///////////////////////////////////////////////////////////////////////////// #endif // not APSTUDIO_INVOKED ================================================ FILE: 3rdParty/DirectXTex/Texconv/Texconv_Desktop_2012.sln ================================================ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 2012 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "texconv", "Texconv_Desktop_2012.vcxproj", "{C3A65381-8FD3-4F69-B29E-654B4B0ED136}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DirectXTex", "..\DirectXTex\DirectXTex_Desktop_2012.vcxproj", "{371B9FA9-4C90-4AC6-A123-ACED756D6C77}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Debug|x64 = Debug|x64 Profile|Win32 = Profile|Win32 Profile|x64 = Profile|x64 Release|Win32 = Release|Win32 Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {C3A65381-8FD3-4F69-B29E-654B4B0ED136}.Debug|Win32.ActiveCfg = Debug|Win32 {C3A65381-8FD3-4F69-B29E-654B4B0ED136}.Debug|Win32.Build.0 = Debug|Win32 {C3A65381-8FD3-4F69-B29E-654B4B0ED136}.Debug|x64.ActiveCfg = Debug|x64 {C3A65381-8FD3-4F69-B29E-654B4B0ED136}.Debug|x64.Build.0 = Debug|x64 {C3A65381-8FD3-4F69-B29E-654B4B0ED136}.Profile|Win32.ActiveCfg = Profile|Win32 {C3A65381-8FD3-4F69-B29E-654B4B0ED136}.Profile|Win32.Build.0 = Profile|Win32 {C3A65381-8FD3-4F69-B29E-654B4B0ED136}.Profile|x64.ActiveCfg = Profile|x64 {C3A65381-8FD3-4F69-B29E-654B4B0ED136}.Profile|x64.Build.0 = Profile|x64 {C3A65381-8FD3-4F69-B29E-654B4B0ED136}.Release|Win32.ActiveCfg = Release|Win32 {C3A65381-8FD3-4F69-B29E-654B4B0ED136}.Release|Win32.Build.0 = Release|Win32 {C3A65381-8FD3-4F69-B29E-654B4B0ED136}.Release|x64.ActiveCfg = Release|x64 {C3A65381-8FD3-4F69-B29E-654B4B0ED136}.Release|x64.Build.0 = Release|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Debug|Win32.ActiveCfg = Debug|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Debug|Win32.Build.0 = Debug|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Debug|x64.ActiveCfg = Debug|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Debug|x64.Build.0 = Debug|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Profile|Win32.ActiveCfg = Profile|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Profile|Win32.Build.0 = Profile|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Profile|x64.ActiveCfg = Profile|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Profile|x64.Build.0 = Profile|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Release|Win32.ActiveCfg = Release|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Release|Win32.Build.0 = Release|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Release|x64.ActiveCfg = Release|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal ================================================ FILE: 3rdParty/DirectXTex/Texconv/Texconv_Desktop_2012.vcxproj ================================================  Debug Win32 Debug x64 Profile Win32 Profile x64 Release Win32 Release x64 texconv {C3A65381-8FD3-4F69-B29E-654B4B0ED136} texconv Win32Proj $(VCTargetsPath11) Application Unicode v110 Application Unicode v110 Application true Unicode v110 Application true Unicode v110 Application true Unicode v110 Application true Unicode v110 true true $(ExecutablePath) $(IncludePath) $(LibraryPath) true true $(ExecutablePath) $(IncludePath) $(LibraryPath) false true $(ExecutablePath) $(IncludePath) $(LibraryPath) false true $(ExecutablePath) $(IncludePath) $(LibraryPath) false true $(ExecutablePath) $(IncludePath) $(LibraryPath) false true $(ExecutablePath) $(IncludePath) $(LibraryPath) Level4 Disabled MultiThreadedDebugDLL true true Fast StreamingSIMDExtensions2 Sync ..\DirectXTex;%(AdditionalIncludeDirectories) %(AdditionalOptions) WIN32;_DEBUG;DEBUG;PROFILE;_CONSOLE;D3DXFX_LARGEADDRESS_HANDLE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions) EditAndContinue EnableFastChecks %(AdditionalOptions) ole32.lib;windowscodecs.lib;uuid.lib;%(AdditionalDependencies) Console true true true true MachineX86 AsInvoker %(DelayLoadDLLs) false Level4 Disabled MultiThreadedDebugDLL true true Fast Sync ..\DirectXTex;%(AdditionalIncludeDirectories) %(AdditionalOptions) WIN32;_DEBUG;DEBUG;PROFILE;_CONSOLE;D3DXFX_LARGEADDRESS_HANDLE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions) EnableFastChecks %(AdditionalOptions) ole32.lib;windowscodecs.lib;uuid.lib;%(AdditionalDependencies) Console true true true true MachineX64 AsInvoker %(DelayLoadDLLs) false Level4 MaxSpeed MultiThreadedDLL true true true Fast StreamingSIMDExtensions2 Sync ..\DirectXTex;%(AdditionalIncludeDirectories) %(AdditionalOptions) WIN32;NDEBUG;_CONSOLE;D3DXFX_LARGEADDRESS_HANDLE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions) %(AdditionalOptions) ole32.lib;windowscodecs.lib;uuid.lib;%(AdditionalDependencies) true Console true true true true true MachineX86 AsInvoker %(DelayLoadDLLs) false Level4 MaxSpeed MultiThreadedDLL true true true Fast Sync ..\DirectXTex;%(AdditionalIncludeDirectories) %(AdditionalOptions) WIN32;NDEBUG;_CONSOLE;D3DXFX_LARGEADDRESS_HANDLE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions) %(AdditionalOptions) ole32.lib;windowscodecs.lib;uuid.lib;%(AdditionalDependencies) true Console true true true true true MachineX64 AsInvoker %(DelayLoadDLLs) false Level4 MaxSpeed MultiThreadedDLL true true true Fast StreamingSIMDExtensions2 Sync ..\DirectXTex;%(AdditionalIncludeDirectories) %(AdditionalOptions) WIN32;NDEBUG;PROFILE;_CONSOLE;D3DXFX_LARGEADDRESS_HANDLE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions) %(AdditionalOptions) ole32.lib;windowscodecs.lib;uuid.lib;%(AdditionalDependencies) true Console true true true true true MachineX86 AsInvoker %(DelayLoadDLLs) false Level4 MaxSpeed MultiThreadedDLL true true true Fast Sync ..\DirectXTex;%(AdditionalIncludeDirectories) %(AdditionalOptions) WIN32;NDEBUG;PROFILE;_CONSOLE;D3DXFX_LARGEADDRESS_HANDLE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions) %(AdditionalOptions) ole32.lib;windowscodecs.lib;uuid.lib;%(AdditionalDependencies) true Console true true true true true MachineX64 AsInvoker %(DelayLoadDLLs) false {371b9fa9-4c90-4ac6-a123-aced756d6c77} ================================================ FILE: 3rdParty/DirectXTex/Texconv/Texconv_Desktop_2012.vcxproj.filters ================================================  {8e114980-c1a3-4ada-ad7c-83caadf5daeb} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe Resource Files ================================================ FILE: 3rdParty/DirectXTex/Texconv/Texconv_Desktop_2013.sln ================================================ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 2013 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "texconv", "Texconv_Desktop_2013.vcxproj", "{C3A65381-8FD3-4F69-B29E-654B4B0ED136}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DirectXTex", "..\DirectXTex\DirectXTex_Desktop_2013.vcxproj", "{371B9FA9-4C90-4AC6-A123-ACED756D6C77}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Debug|x64 = Debug|x64 Profile|Win32 = Profile|Win32 Profile|x64 = Profile|x64 Release|Win32 = Release|Win32 Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {C3A65381-8FD3-4F69-B29E-654B4B0ED136}.Debug|Win32.ActiveCfg = Debug|Win32 {C3A65381-8FD3-4F69-B29E-654B4B0ED136}.Debug|Win32.Build.0 = Debug|Win32 {C3A65381-8FD3-4F69-B29E-654B4B0ED136}.Debug|x64.ActiveCfg = Debug|x64 {C3A65381-8FD3-4F69-B29E-654B4B0ED136}.Debug|x64.Build.0 = Debug|x64 {C3A65381-8FD3-4F69-B29E-654B4B0ED136}.Profile|Win32.ActiveCfg = Profile|Win32 {C3A65381-8FD3-4F69-B29E-654B4B0ED136}.Profile|Win32.Build.0 = Profile|Win32 {C3A65381-8FD3-4F69-B29E-654B4B0ED136}.Profile|x64.ActiveCfg = Profile|x64 {C3A65381-8FD3-4F69-B29E-654B4B0ED136}.Profile|x64.Build.0 = Profile|x64 {C3A65381-8FD3-4F69-B29E-654B4B0ED136}.Release|Win32.ActiveCfg = Release|Win32 {C3A65381-8FD3-4F69-B29E-654B4B0ED136}.Release|Win32.Build.0 = Release|Win32 {C3A65381-8FD3-4F69-B29E-654B4B0ED136}.Release|x64.ActiveCfg = Release|x64 {C3A65381-8FD3-4F69-B29E-654B4B0ED136}.Release|x64.Build.0 = Release|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Debug|Win32.ActiveCfg = Debug|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Debug|Win32.Build.0 = Debug|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Debug|x64.ActiveCfg = Debug|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Debug|x64.Build.0 = Debug|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Profile|Win32.ActiveCfg = Profile|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Profile|Win32.Build.0 = Profile|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Profile|x64.ActiveCfg = Profile|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Profile|x64.Build.0 = Profile|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Release|Win32.ActiveCfg = Release|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Release|Win32.Build.0 = Release|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Release|x64.ActiveCfg = Release|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal ================================================ FILE: 3rdParty/DirectXTex/Texconv/Texconv_Desktop_2013.vcxproj ================================================  Debug Win32 Debug x64 Profile Win32 Profile x64 Release Win32 Release x64 texconv {C3A65381-8FD3-4F69-B29E-654B4B0ED136} texconv Win32Proj $(VCTargetsPath11) Application Unicode v120 Application Unicode v120 Application true Unicode v120 Application true Unicode v120 Application true Unicode v120 Application true Unicode v120 true true $(ExecutablePath) $(IncludePath) $(LibraryPath) true true $(ExecutablePath) $(IncludePath) $(LibraryPath) false true $(ExecutablePath) $(IncludePath) $(LibraryPath) false true $(ExecutablePath) $(IncludePath) $(LibraryPath) false true $(ExecutablePath) $(IncludePath) $(LibraryPath) false true $(ExecutablePath) $(IncludePath) $(LibraryPath) Level4 Disabled MultiThreadedDebugDLL true true Fast StreamingSIMDExtensions2 Sync ..\DirectXTex;%(AdditionalIncludeDirectories) %(AdditionalOptions) WIN32;_DEBUG;DEBUG;PROFILE;_CONSOLE;D3DXFX_LARGEADDRESS_HANDLE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions) EditAndContinue EnableFastChecks %(AdditionalOptions) ole32.lib;windowscodecs.lib;uuid.lib;%(AdditionalDependencies) Console true true true true MachineX86 AsInvoker %(DelayLoadDLLs) false Level4 Disabled MultiThreadedDebugDLL true true Fast Sync ..\DirectXTex;%(AdditionalIncludeDirectories) %(AdditionalOptions) WIN32;_DEBUG;DEBUG;PROFILE;_CONSOLE;D3DXFX_LARGEADDRESS_HANDLE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions) EnableFastChecks %(AdditionalOptions) ole32.lib;windowscodecs.lib;uuid.lib;%(AdditionalDependencies) Console true true true true MachineX64 AsInvoker %(DelayLoadDLLs) false Level4 MaxSpeed MultiThreadedDLL true true true Fast StreamingSIMDExtensions2 Sync ..\DirectXTex;%(AdditionalIncludeDirectories) %(AdditionalOptions) WIN32;NDEBUG;_CONSOLE;D3DXFX_LARGEADDRESS_HANDLE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions) %(AdditionalOptions) ole32.lib;windowscodecs.lib;uuid.lib;%(AdditionalDependencies) true Console true true true true true MachineX86 AsInvoker %(DelayLoadDLLs) false Level4 MaxSpeed MultiThreadedDLL true true true Fast Sync ..\DirectXTex;%(AdditionalIncludeDirectories) %(AdditionalOptions) WIN32;NDEBUG;_CONSOLE;D3DXFX_LARGEADDRESS_HANDLE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions) %(AdditionalOptions) ole32.lib;windowscodecs.lib;uuid.lib;%(AdditionalDependencies) true Console true true true true true MachineX64 AsInvoker %(DelayLoadDLLs) false Level4 MaxSpeed MultiThreadedDLL true true true Fast StreamingSIMDExtensions2 Sync ..\DirectXTex;%(AdditionalIncludeDirectories) %(AdditionalOptions) WIN32;NDEBUG;PROFILE;_CONSOLE;D3DXFX_LARGEADDRESS_HANDLE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions) %(AdditionalOptions) ole32.lib;windowscodecs.lib;uuid.lib;%(AdditionalDependencies) true Console true true true true true MachineX86 AsInvoker %(DelayLoadDLLs) false Level4 MaxSpeed MultiThreadedDLL true true true Fast Sync ..\DirectXTex;%(AdditionalIncludeDirectories) %(AdditionalOptions) WIN32;NDEBUG;PROFILE;_CONSOLE;D3DXFX_LARGEADDRESS_HANDLE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions) %(AdditionalOptions) ole32.lib;windowscodecs.lib;uuid.lib;%(AdditionalDependencies) true Console true true true true true MachineX64 AsInvoker %(DelayLoadDLLs) false {371b9fa9-4c90-4ac6-a123-aced756d6c77} ================================================ FILE: 3rdParty/DirectXTex/Texconv/Texconv_Desktop_2013.vcxproj.filters ================================================  {8e114980-c1a3-4ada-ad7c-83caadf5daeb} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe Resource Files ================================================ FILE: 3rdParty/DirectXTex/Texconv/Texconv_Desktop_2015.sln ================================================ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 2015 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "texconv", "Texconv_Desktop_2015.vcxproj", "{C3A65381-8FD3-4F69-B29E-654B4B0ED136}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DirectXTex", "..\DirectXTex\DirectXTex_Desktop_2015.vcxproj", "{371B9FA9-4C90-4AC6-A123-ACED756D6C77}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Debug|x64 = Debug|x64 Profile|Win32 = Profile|Win32 Profile|x64 = Profile|x64 Release|Win32 = Release|Win32 Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {C3A65381-8FD3-4F69-B29E-654B4B0ED136}.Debug|Win32.ActiveCfg = Debug|Win32 {C3A65381-8FD3-4F69-B29E-654B4B0ED136}.Debug|Win32.Build.0 = Debug|Win32 {C3A65381-8FD3-4F69-B29E-654B4B0ED136}.Debug|x64.ActiveCfg = Debug|x64 {C3A65381-8FD3-4F69-B29E-654B4B0ED136}.Debug|x64.Build.0 = Debug|x64 {C3A65381-8FD3-4F69-B29E-654B4B0ED136}.Profile|Win32.ActiveCfg = Profile|Win32 {C3A65381-8FD3-4F69-B29E-654B4B0ED136}.Profile|Win32.Build.0 = Profile|Win32 {C3A65381-8FD3-4F69-B29E-654B4B0ED136}.Profile|x64.ActiveCfg = Profile|x64 {C3A65381-8FD3-4F69-B29E-654B4B0ED136}.Profile|x64.Build.0 = Profile|x64 {C3A65381-8FD3-4F69-B29E-654B4B0ED136}.Release|Win32.ActiveCfg = Release|Win32 {C3A65381-8FD3-4F69-B29E-654B4B0ED136}.Release|Win32.Build.0 = Release|Win32 {C3A65381-8FD3-4F69-B29E-654B4B0ED136}.Release|x64.ActiveCfg = Release|x64 {C3A65381-8FD3-4F69-B29E-654B4B0ED136}.Release|x64.Build.0 = Release|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Debug|Win32.ActiveCfg = Debug|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Debug|Win32.Build.0 = Debug|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Debug|x64.ActiveCfg = Debug|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Debug|x64.Build.0 = Debug|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Profile|Win32.ActiveCfg = Profile|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Profile|Win32.Build.0 = Profile|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Profile|x64.ActiveCfg = Profile|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Profile|x64.Build.0 = Profile|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Release|Win32.ActiveCfg = Release|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Release|Win32.Build.0 = Release|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Release|x64.ActiveCfg = Release|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal ================================================ FILE: 3rdParty/DirectXTex/Texconv/Texconv_Desktop_2015.vcxproj ================================================  Debug Win32 Debug x64 Profile Win32 Profile x64 Release Win32 Release x64 texconv {C3A65381-8FD3-4F69-B29E-654B4B0ED136} texconv Win32Proj Application Unicode v140 Application Unicode v140 Application true Unicode v140 Application true Unicode v140 Application true Unicode v140 Application true Unicode v140 true true $(ExecutablePath) $(IncludePath) $(LibraryPath) true true $(ExecutablePath) $(IncludePath) $(LibraryPath) false true $(ExecutablePath) $(IncludePath) $(LibraryPath) false true $(ExecutablePath) $(IncludePath) $(LibraryPath) false true $(ExecutablePath) $(IncludePath) $(LibraryPath) false true $(ExecutablePath) $(IncludePath) $(LibraryPath) Level4 Disabled MultiThreadedDebugDLL true true Fast StreamingSIMDExtensions2 Sync ..\DirectXTex;%(AdditionalIncludeDirectories) %(AdditionalOptions) WIN32;_DEBUG;DEBUG;PROFILE;_CONSOLE;D3DXFX_LARGEADDRESS_HANDLE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions) EditAndContinue EnableFastChecks %(AdditionalOptions) ole32.lib;windowscodecs.lib;uuid.lib;%(AdditionalDependencies) Console true true true true MachineX86 AsInvoker %(DelayLoadDLLs) false Level4 Disabled MultiThreadedDebugDLL true true Fast Sync ..\DirectXTex;%(AdditionalIncludeDirectories) %(AdditionalOptions) WIN32;_DEBUG;DEBUG;PROFILE;_CONSOLE;D3DXFX_LARGEADDRESS_HANDLE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions) EnableFastChecks %(AdditionalOptions) ole32.lib;windowscodecs.lib;uuid.lib;%(AdditionalDependencies) Console true true true true MachineX64 AsInvoker %(DelayLoadDLLs) false Level4 MaxSpeed MultiThreadedDLL true true true Fast StreamingSIMDExtensions2 Sync ..\DirectXTex;%(AdditionalIncludeDirectories) %(AdditionalOptions) WIN32;NDEBUG;_CONSOLE;D3DXFX_LARGEADDRESS_HANDLE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions) %(AdditionalOptions) ole32.lib;windowscodecs.lib;uuid.lib;%(AdditionalDependencies) true Console true true true true true MachineX86 AsInvoker %(DelayLoadDLLs) false Level4 MaxSpeed MultiThreadedDLL true true true Fast Sync ..\DirectXTex;%(AdditionalIncludeDirectories) %(AdditionalOptions) WIN32;NDEBUG;_CONSOLE;D3DXFX_LARGEADDRESS_HANDLE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions) %(AdditionalOptions) ole32.lib;windowscodecs.lib;uuid.lib;%(AdditionalDependencies) true Console true true true true true MachineX64 AsInvoker %(DelayLoadDLLs) false Level4 MaxSpeed MultiThreadedDLL true true true Fast StreamingSIMDExtensions2 Sync ..\DirectXTex;%(AdditionalIncludeDirectories) %(AdditionalOptions) WIN32;NDEBUG;PROFILE;_CONSOLE;D3DXFX_LARGEADDRESS_HANDLE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions) %(AdditionalOptions) ole32.lib;windowscodecs.lib;uuid.lib;%(AdditionalDependencies) true Console true true true true true MachineX86 AsInvoker %(DelayLoadDLLs) false Level4 MaxSpeed MultiThreadedDLL true true true Fast Sync ..\DirectXTex;%(AdditionalIncludeDirectories) %(AdditionalOptions) WIN32;NDEBUG;PROFILE;_CONSOLE;D3DXFX_LARGEADDRESS_HANDLE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions) %(AdditionalOptions) ole32.lib;windowscodecs.lib;uuid.lib;%(AdditionalDependencies) true Console true true true true true MachineX64 AsInvoker %(DelayLoadDLLs) false {371b9fa9-4c90-4ac6-a123-aced756d6c77} ================================================ FILE: 3rdParty/DirectXTex/Texconv/Texconv_Desktop_2015.vcxproj.filters ================================================  {8e114980-c1a3-4ada-ad7c-83caadf5daeb} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe Resource Files ================================================ FILE: 3rdParty/DirectXTex/Texconv/texconv.cpp ================================================ //-------------------------------------------------------------------------------------- // File: TexConv.cpp // // DirectX 11 Texture Converter // // Copyright (c) Microsoft Corporation. All rights reserved. //-------------------------------------------------------------------------------------- #include #include #include #include #include #include #include #include "directxtex.h" using namespace DirectX; using Microsoft::WRL::ComPtr; enum OPTIONS // Note: dwOptions below assumes 64 or less options. { OPT_WIDTH = 1, OPT_HEIGHT, OPT_MIPLEVELS, OPT_FORMAT, OPT_FILTER, OPT_SRGBI, OPT_SRGBO, OPT_SRGB, OPT_PREFIX, OPT_SUFFIX, OPT_OUTPUTDIR, OPT_FILETYPE, OPT_HFLIP, OPT_VFLIP, OPT_DDS_DWORD_ALIGN, OPT_USE_DX10, OPT_NOLOGO, OPT_TIMING, OPT_SEPALPHA, OPT_TYPELESS_UNORM, OPT_TYPELESS_FLOAT, OPT_PREMUL_ALPHA, OPT_EXPAND_LUMINANCE, OPT_TA_WRAP, OPT_TA_MIRROR, OPT_FORCE_SINGLEPROC, OPT_NOGPU, OPT_FEATURE_LEVEL, OPT_FIT_POWEROF2, OPT_ALPHA_WEIGHT, OPT_NORMAL_MAP, OPT_NORMAL_MAP_AMPLITUDE, OPT_COMPRESS_UNIFORM, OPT_COMPRESS_MAX, OPT_COMPRESS_DITHER, OPT_MAX }; static_assert( OPT_MAX <= 64, "dwOptions is a DWORD64 bitfield" ); struct SConversion { WCHAR szSrc [MAX_PATH]; WCHAR szDest[MAX_PATH]; }; struct SValue { LPCWSTR pName; DWORD dwValue; }; ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// SValue g_pOptions[] = { { L"w", OPT_WIDTH }, { L"h", OPT_HEIGHT }, { L"m", OPT_MIPLEVELS }, { L"f", OPT_FORMAT }, { L"if", OPT_FILTER }, { L"srgbi", OPT_SRGBI }, { L"srgbo", OPT_SRGBO }, { L"srgb", OPT_SRGB }, { L"px", OPT_PREFIX }, { L"sx", OPT_SUFFIX }, { L"o", OPT_OUTPUTDIR }, { L"ft", OPT_FILETYPE }, { L"hflip", OPT_HFLIP }, { L"vflip", OPT_VFLIP }, { L"dword", OPT_DDS_DWORD_ALIGN }, { L"dx10", OPT_USE_DX10 }, { L"nologo", OPT_NOLOGO }, { L"timing", OPT_TIMING }, { L"sepalpha", OPT_SEPALPHA }, { L"tu", OPT_TYPELESS_UNORM }, { L"tf", OPT_TYPELESS_FLOAT }, { L"pmalpha", OPT_PREMUL_ALPHA }, { L"xlum", OPT_EXPAND_LUMINANCE }, { L"wrap", OPT_TA_WRAP }, { L"mirror", OPT_TA_MIRROR }, { L"singleproc", OPT_FORCE_SINGLEPROC }, { L"nogpu", OPT_NOGPU }, { L"fl", OPT_FEATURE_LEVEL }, { L"pow2", OPT_FIT_POWEROF2 }, { L"aw", OPT_ALPHA_WEIGHT }, { L"nmap", OPT_NORMAL_MAP }, { L"nmapamp", OPT_NORMAL_MAP_AMPLITUDE }, { L"bcuniform", OPT_COMPRESS_UNIFORM }, { L"bcmax", OPT_COMPRESS_MAX }, { L"bcdither", OPT_COMPRESS_DITHER }, { nullptr, 0 } }; #define DEFFMT(fmt) { L#fmt, DXGI_FORMAT_ ## fmt } SValue g_pFormats[] = { // List does not include _TYPELESS or depth/stencil formats DEFFMT(R32G32B32A32_FLOAT), DEFFMT(R32G32B32A32_UINT), DEFFMT(R32G32B32A32_SINT), DEFFMT(R32G32B32_FLOAT), DEFFMT(R32G32B32_UINT), DEFFMT(R32G32B32_SINT), DEFFMT(R16G16B16A16_FLOAT), DEFFMT(R16G16B16A16_UNORM), DEFFMT(R16G16B16A16_UINT), DEFFMT(R16G16B16A16_SNORM), DEFFMT(R16G16B16A16_SINT), DEFFMT(R32G32_FLOAT), DEFFMT(R32G32_UINT), DEFFMT(R32G32_SINT), DEFFMT(R10G10B10A2_UNORM), DEFFMT(R10G10B10A2_UINT), DEFFMT(R11G11B10_FLOAT), DEFFMT(R8G8B8A8_UNORM), DEFFMT(R8G8B8A8_UNORM_SRGB), DEFFMT(R8G8B8A8_UINT), DEFFMT(R8G8B8A8_SNORM), DEFFMT(R8G8B8A8_SINT), DEFFMT(R16G16_FLOAT), DEFFMT(R16G16_UNORM), DEFFMT(R16G16_UINT), DEFFMT(R16G16_SNORM), DEFFMT(R16G16_SINT), DEFFMT(R32_FLOAT), DEFFMT(R32_UINT), DEFFMT(R32_SINT), DEFFMT(R8G8_UNORM), DEFFMT(R8G8_UINT), DEFFMT(R8G8_SNORM), DEFFMT(R8G8_SINT), DEFFMT(R16_FLOAT), DEFFMT(R16_UNORM), DEFFMT(R16_UINT), DEFFMT(R16_SNORM), DEFFMT(R16_SINT), DEFFMT(R8_UNORM), DEFFMT(R8_UINT), DEFFMT(R8_SNORM), DEFFMT(R8_SINT), DEFFMT(A8_UNORM), DEFFMT(R9G9B9E5_SHAREDEXP), DEFFMT(R8G8_B8G8_UNORM), DEFFMT(G8R8_G8B8_UNORM), DEFFMT(BC1_UNORM), DEFFMT(BC1_UNORM_SRGB), DEFFMT(BC2_UNORM), DEFFMT(BC2_UNORM_SRGB), DEFFMT(BC3_UNORM), DEFFMT(BC3_UNORM_SRGB), DEFFMT(BC4_UNORM), DEFFMT(BC4_SNORM), DEFFMT(BC5_UNORM), DEFFMT(BC5_SNORM), DEFFMT(B5G6R5_UNORM), DEFFMT(B5G5R5A1_UNORM), // DXGI 1.1 formats DEFFMT(B8G8R8A8_UNORM), DEFFMT(B8G8R8X8_UNORM), DEFFMT(R10G10B10_XR_BIAS_A2_UNORM), DEFFMT(B8G8R8A8_UNORM_SRGB), DEFFMT(B8G8R8X8_UNORM_SRGB), DEFFMT(BC6H_UF16), DEFFMT(BC6H_SF16), DEFFMT(BC7_UNORM), DEFFMT(BC7_UNORM_SRGB), // DXGI 1.2 formats DEFFMT(AYUV), DEFFMT(Y410), DEFFMT(Y416), DEFFMT(YUY2), DEFFMT(Y210), DEFFMT(Y216), // No support for legacy paletted video formats (AI44, IA44, P8, A8P8) DEFFMT(B4G4R4A4_UNORM), { nullptr, DXGI_FORMAT_UNKNOWN } }; SValue g_pReadOnlyFormats[] = { DEFFMT(R32G32B32A32_TYPELESS), DEFFMT(R32G32B32_TYPELESS), DEFFMT(R16G16B16A16_TYPELESS), DEFFMT(R32G32_TYPELESS), DEFFMT(R32G8X24_TYPELESS), DEFFMT(D32_FLOAT_S8X24_UINT), DEFFMT(R32_FLOAT_X8X24_TYPELESS), DEFFMT(X32_TYPELESS_G8X24_UINT), DEFFMT(R10G10B10A2_TYPELESS), DEFFMT(R8G8B8A8_TYPELESS), DEFFMT(R16G16_TYPELESS), DEFFMT(R32_TYPELESS), DEFFMT(D32_FLOAT), DEFFMT(R24G8_TYPELESS), DEFFMT(D24_UNORM_S8_UINT), DEFFMT(R24_UNORM_X8_TYPELESS), DEFFMT(X24_TYPELESS_G8_UINT), DEFFMT(R8G8_TYPELESS), DEFFMT(R16_TYPELESS), DEFFMT(R8_TYPELESS), DEFFMT(BC1_TYPELESS), DEFFMT(BC2_TYPELESS), DEFFMT(BC3_TYPELESS), DEFFMT(BC4_TYPELESS), DEFFMT(BC5_TYPELESS), // DXGI 1.1 formats DEFFMT(B8G8R8A8_TYPELESS), DEFFMT(B8G8R8X8_TYPELESS), DEFFMT(BC6H_TYPELESS), DEFFMT(BC7_TYPELESS), // DXGI 1.2 formats DEFFMT(NV12), DEFFMT(P010), DEFFMT(P016), DEFFMT(420_OPAQUE), DEFFMT(NV11), { nullptr, DXGI_FORMAT_UNKNOWN } }; SValue g_pFilters[] = { { L"POINT", TEX_FILTER_POINT }, { L"LINEAR", TEX_FILTER_LINEAR }, { L"CUBIC", TEX_FILTER_CUBIC }, { L"FANT", TEX_FILTER_FANT }, { L"BOX", TEX_FILTER_BOX }, { L"TRIANGLE", TEX_FILTER_TRIANGLE }, { L"POINT_DITHER", TEX_FILTER_POINT | TEX_FILTER_DITHER }, { L"LINEAR_DITHER", TEX_FILTER_LINEAR | TEX_FILTER_DITHER }, { L"CUBIC_DITHER", TEX_FILTER_CUBIC | TEX_FILTER_DITHER }, { L"FANT_DITHER", TEX_FILTER_FANT | TEX_FILTER_DITHER }, { L"BOX_DITHER", TEX_FILTER_BOX | TEX_FILTER_DITHER }, { L"TRIANGLE_DITHER", TEX_FILTER_TRIANGLE | TEX_FILTER_DITHER }, { L"POINT_DITHER_DIFFUSION", TEX_FILTER_POINT | TEX_FILTER_DITHER_DIFFUSION }, { L"LINEAR_DITHER_DIFFUSION", TEX_FILTER_LINEAR | TEX_FILTER_DITHER_DIFFUSION }, { L"CUBIC_DITHER_DIFFUSION", TEX_FILTER_CUBIC | TEX_FILTER_DITHER_DIFFUSION }, { L"FANT_DITHER_DIFFUSION", TEX_FILTER_FANT | TEX_FILTER_DITHER_DIFFUSION }, { L"BOX_DITHER_DIFFUSION", TEX_FILTER_BOX | TEX_FILTER_DITHER_DIFFUSION }, { L"TRIANGLE_DITHER_DIFFUSION", TEX_FILTER_TRIANGLE | TEX_FILTER_DITHER_DIFFUSION }, { nullptr, TEX_FILTER_DEFAULT } }; #define CODEC_DDS 0xFFFF0001 #define CODEC_TGA 0xFFFF0002 SValue g_pSaveFileTypes[] = // valid formats to write to { { L"BMP", WIC_CODEC_BMP }, { L"JPG", WIC_CODEC_JPEG }, { L"JPEG", WIC_CODEC_JPEG }, { L"PNG", WIC_CODEC_PNG }, { L"DDS", CODEC_DDS }, { L"TGA", CODEC_TGA }, { L"TIF", WIC_CODEC_TIFF }, { L"TIFF", WIC_CODEC_TIFF }, { L"WDP", WIC_CODEC_WMP }, { L"HDP", WIC_CODEC_WMP }, { nullptr, CODEC_DDS } }; SValue g_pFeatureLevels[] = // valid feature levels for -fl for maximimum size { { L"9.1", 2048 }, { L"9.2", 2048 }, { L"9.3", 4096 }, { L"10.0", 8192 }, { L"10.1", 8192 }, { L"11.0", 16384 }, { L"11.1", 16384 }, { nullptr, 0 }, }; ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// #pragma warning( disable : 4616 6211 ) inline static bool ispow2(size_t x) { return ((x != 0) && !(x & (x - 1))); } #pragma prefast(disable : 26018, "Only used with static internal arrays") DWORD LookupByName(const WCHAR *pName, const SValue *pArray) { while(pArray->pName) { if(!_wcsicmp(pName, pArray->pName)) return pArray->dwValue; pArray++; } return 0; } const WCHAR* LookupByValue(DWORD pValue, const SValue *pArray) { while(pArray->pName) { if(pValue == pArray->dwValue) return pArray->pName; pArray++; } return L""; } void PrintFormat(DXGI_FORMAT Format) { for(SValue *pFormat = g_pFormats; pFormat->pName; pFormat++) { if((DXGI_FORMAT) pFormat->dwValue == Format) { wprintf( pFormat->pName ); return; } } for(SValue *pFormat = g_pReadOnlyFormats; pFormat->pName; pFormat++) { if((DXGI_FORMAT) pFormat->dwValue == Format) { wprintf( pFormat->pName ); return; } } wprintf( L"*UNKNOWN*" ); } void PrintInfo( const TexMetadata& info ) { wprintf( L" (%Iux%Iu", info.width, info.height); if ( TEX_DIMENSION_TEXTURE3D == info.dimension ) wprintf( L"x%Iu", info.depth); if ( info.mipLevels > 1 ) wprintf( L",%Iu", info.mipLevels); if ( info.arraySize > 1 ) wprintf( L",%Iu", info.arraySize); wprintf( L" "); PrintFormat( info.format ); switch ( info.dimension ) { case TEX_DIMENSION_TEXTURE1D: wprintf( (info.arraySize > 1) ? L" 1DArray" : L" 1D" ); break; case TEX_DIMENSION_TEXTURE2D: if ( info.IsCubemap() ) { wprintf( (info.arraySize > 6) ? L" CubeArray" : L" Cube" ); } else { wprintf( (info.arraySize > 1) ? L" 2DArray" : L" 2D" ); } break; case TEX_DIMENSION_TEXTURE3D: wprintf( L" 3D"); break; } wprintf( L")"); } void PrintList(size_t cch, SValue *pValue) { while(pValue->pName) { size_t cchName = wcslen(pValue->pName); if(cch + cchName + 2>= 80) { wprintf( L"\n "); cch = 6; } wprintf( L"%ls ", pValue->pName ); cch += cchName + 2; pValue++; } wprintf( L"\n"); } void PrintLogo() { wprintf( L"Microsoft (R) DirectX 11 Texture Converter (DirectXTex version)\n"); wprintf( L"Copyright (C) Microsoft Corp. All rights reserved.\n"); #ifdef _DEBUG wprintf( L"*** Debug build ***\n"); #endif wprintf( L"\n"); } void PrintUsage() { PrintLogo(); wprintf( L"Usage: texconv \n"); wprintf( L"\n"); wprintf( L" -w width\n"); wprintf( L" -h height\n"); wprintf( L" -m miplevels\n"); wprintf( L" -f format\n"); wprintf( L" -if image filtering\n"); wprintf( L" -srgb{i|o} sRGB {input, output}\n"); wprintf( L" -px name prefix\n"); wprintf( L" -sx name suffix\n"); wprintf( L" -o output directory\n"); wprintf( L" -ft output file type\n"); wprintf( L" -hflip horizonal flip of source image\n"); wprintf( L" -vflip vertical flip of source image\n"); wprintf( L" -sepalpha resize/generate mips alpha channel separately\n"); wprintf( L" from color channels\n"); wprintf( L" -wrap, -mirror texture addressing mode (wrap, mirror, or clamp)\n"); wprintf( L" -pmalpha convert final texture to use premultiplied alpha\n"); wprintf( L" -pow2 resize to fit a power-of-2, respecting aspect ratio\n" ); wprintf (L" -nmap converts height-map to normal-map\n" L" options must be one or more of\n" L" r, g, b, a, l, m, u, v, i, o\n" ); wprintf (L" -nmapamp normal map amplitude (defaults to 1.0)\n" ); wprintf( L" -fl Set maximum feature level target (defaults to 11.0)\n"); wprintf( L"\n (DDS input only)\n"); wprintf( L" -t{u|f} TYPELESS format is treated as UNORM or FLOAT\n"); wprintf( L" -dword Use DWORD instead of BYTE alignment\n"); wprintf( L" -xlum expand legacy L8, L16, and A8P8 formats\n"); wprintf( L"\n (DDS output only)\n"); wprintf( L" -dx10 Force use of 'DX10' extended header\n"); wprintf( L"\n -nologo suppress copyright message\n"); wprintf( L" -timing Display elapsed processing time\n\n"); #ifdef _OPENMP wprintf( L" -singleproc Do not use multi-threaded compression\n"); #endif wprintf( L" -nogpu Do not use DirectCompute-based codecs\n"); wprintf( L" -bcuniform Use uniform rather than perceptual weighting for BC1-3\n"); wprintf( L" -bcdither Use dithering for BC1-3\n"); wprintf( L" -bcmax Use exchaustive compression (BC7 only)\n"); wprintf( L" -aw BC7 GPU compressor weighting for alpha error metric\n" L" (defaults to 1.0)\n" ); wprintf( L"\n"); wprintf( L" : "); PrintList(13, g_pFormats); wprintf( L"\n"); wprintf( L" : "); PrintList(13, g_pFilters); wprintf( L"\n"); wprintf( L" : "); PrintList(15, g_pSaveFileTypes); wprintf( L"\n"); wprintf( L" : "); PrintList(13, g_pFeatureLevels); } _Success_(return != false) bool CreateDevice( _Outptr_ ID3D11Device** pDevice ) { if ( !pDevice ) return false; *pDevice = nullptr; static PFN_D3D11_CREATE_DEVICE s_DynamicD3D11CreateDevice = nullptr; if ( !s_DynamicD3D11CreateDevice ) { HMODULE hModD3D11 = LoadLibrary( L"d3d11.dll" ); if ( !hModD3D11 ) return false; s_DynamicD3D11CreateDevice = reinterpret_cast( reinterpret_cast( GetProcAddress( hModD3D11, "D3D11CreateDevice" ) ) ); if ( !s_DynamicD3D11CreateDevice ) return false; } D3D_FEATURE_LEVEL featureLevels[] = { D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0, }; UINT createDeviceFlags = 0; #ifdef _DEBUG createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG; #endif D3D_FEATURE_LEVEL fl; HRESULT hr = s_DynamicD3D11CreateDevice( nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, createDeviceFlags, featureLevels, _countof(featureLevels), D3D11_SDK_VERSION, pDevice, &fl, nullptr ); if ( SUCCEEDED(hr) ) { if ( fl < D3D_FEATURE_LEVEL_11_0 ) { D3D11_FEATURE_DATA_D3D10_X_HARDWARE_OPTIONS hwopts; hr = (*pDevice)->CheckFeatureSupport( D3D11_FEATURE_D3D10_X_HARDWARE_OPTIONS, &hwopts, sizeof(hwopts) ); if ( FAILED(hr) ) memset( &hwopts, 0, sizeof(hwopts) ); if ( !hwopts.ComputeShaders_Plus_RawAndStructuredBuffers_Via_Shader_4_x ) { if ( *pDevice ) { (*pDevice)->Release(); *pDevice = nullptr; } hr = HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); } } } if ( SUCCEEDED(hr) ) { ComPtr dxgiDevice; hr = (*pDevice)->QueryInterface( __uuidof( IDXGIDevice ), reinterpret_cast< void** >( dxgiDevice.GetAddressOf() ) ); if ( SUCCEEDED(hr) ) { ComPtr pAdapter; hr = dxgiDevice->GetAdapter( pAdapter.GetAddressOf() ); if ( SUCCEEDED(hr) ) { DXGI_ADAPTER_DESC desc; hr = pAdapter->GetDesc( &desc ); if ( SUCCEEDED(hr) ) { wprintf( L"\n[Using DirectCompute on \"%ls\"]\n", desc.Description ); } } } return true; } else return false; } void FitPowerOf2( size_t origx, size_t origy, size_t& targetx, size_t& targety, size_t maxsize ) { float origAR = float(origx) / float(origy); if ( origx > origy ) { size_t x; for( x = maxsize; x > 1; x >>= 1 ) { if ( x <= targetx ) break; }; targetx = x; float bestScore = FLT_MAX; for( size_t y = maxsize; y > 0; y >>= 1 ) { float score = fabs( (float(x) / float(y)) - origAR ); if ( score < bestScore ) { bestScore = score; targety = y; } } } else { size_t y; for( y = maxsize; y > 1; y >>= 1 ) { if ( y <= targety ) break; }; targety = y; float bestScore = FLT_MAX; for( size_t x = maxsize; x > 0; x >>= 1 ) { float score = fabs( (float(x) / float(y)) - origAR ); if ( score < bestScore ) { bestScore = score; targetx = x; } } } } //-------------------------------------------------------------------------------------- // Entry-point //-------------------------------------------------------------------------------------- #pragma prefast(disable : 28198, "Command-line tool, frees all memory on exit") int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[]) { // Parameters and defaults size_t width = 0; size_t height = 0; size_t mipLevels = 0; DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN; DWORD dwFilter = TEX_FILTER_DEFAULT; DWORD dwSRGB = 0; DWORD dwCompress = TEX_COMPRESS_DEFAULT; DWORD dwFilterOpts = 0; DWORD FileType = CODEC_DDS; DWORD maxSize = 16384; float alphaWeight = 1.f; DWORD dwNormalMap = 0; float nmapAmplitude = 1.f; WCHAR szPrefix [MAX_PATH]; WCHAR szSuffix [MAX_PATH]; WCHAR szOutputDir[MAX_PATH]; szPrefix[0] = 0; szSuffix[0] = 0; szOutputDir[0] = 0; // Initialize COM (needed for WIC) HRESULT hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED); if( FAILED(hr) ) { wprintf( L"Failed to initialize COM (%08X)\n", hr); return 1; } // Process command line DWORD64 dwOptions = 0; std::list conversion; for(int iArg = 1; iArg < argc; iArg++) { PWSTR pArg = argv[iArg]; if(('-' == pArg[0]) || ('/' == pArg[0])) { pArg++; PWSTR pValue; for(pValue = pArg; *pValue && (':' != *pValue); pValue++); if(*pValue) *pValue++ = 0; DWORD dwOption = LookupByName(pArg, g_pOptions); if(!dwOption || (dwOptions & (DWORD64(1) << dwOption))) { PrintUsage(); return 1; } dwOptions |= (DWORD64(1) << dwOption); if( (OPT_NOLOGO != dwOption) && (OPT_TIMING != dwOption) && (OPT_TYPELESS_UNORM != dwOption) && (OPT_TYPELESS_FLOAT != dwOption) && (OPT_SEPALPHA != dwOption) && (OPT_PREMUL_ALPHA != dwOption) && (OPT_EXPAND_LUMINANCE != dwOption) && (OPT_TA_WRAP != dwOption) && (OPT_TA_MIRROR != dwOption) && (OPT_FORCE_SINGLEPROC != dwOption) && (OPT_NOGPU != dwOption) && (OPT_FIT_POWEROF2 != dwOption) && (OPT_SRGB != dwOption) && (OPT_SRGBI != dwOption) && (OPT_SRGBO != dwOption) && (OPT_HFLIP != dwOption) && (OPT_VFLIP != dwOption) && (OPT_COMPRESS_UNIFORM != dwOption) && (OPT_COMPRESS_MAX != dwOption) && (OPT_COMPRESS_DITHER != dwOption) && (OPT_DDS_DWORD_ALIGN != dwOption) && (OPT_USE_DX10 != dwOption) ) { if(!*pValue) { if((iArg + 1 >= argc)) { PrintUsage(); return 1; } iArg++; pValue = argv[iArg]; } } switch(dwOption) { case OPT_WIDTH: if (swscanf_s(pValue, L"%Iu", &width) != 1) { wprintf( L"Invalid value specified with -w (%ls)\n", pValue); wprintf( L"\n"); PrintUsage(); return 1; } break; case OPT_HEIGHT: if (swscanf_s(pValue, L"%Iu", &height) != 1) { wprintf( L"Invalid value specified with -h (%ls)\n", pValue); printf("\n"); PrintUsage(); return 1; } break; case OPT_MIPLEVELS: if (swscanf_s(pValue, L"%Iu", &mipLevels) != 1) { wprintf( L"Invalid value specified with -m (%ls)\n", pValue); wprintf( L"\n"); PrintUsage(); return 1; } break; case OPT_FORMAT: format = (DXGI_FORMAT) LookupByName(pValue, g_pFormats); if ( !format ) { wprintf( L"Invalid value specified with -f (%ls)\n", pValue); wprintf( L"\n"); PrintUsage(); return 1; } break; case OPT_FILTER: dwFilter = LookupByName(pValue, g_pFilters); if ( !dwFilter ) { wprintf( L"Invalid value specified with -if (%ls)\n", pValue); wprintf( L"\n"); PrintUsage(); return 1; } break; case OPT_SRGBI: dwSRGB |= TEX_FILTER_SRGB_IN; break; case OPT_SRGBO: dwSRGB |= TEX_FILTER_SRGB_OUT; break; case OPT_SRGB: dwSRGB |= TEX_FILTER_SRGB; break; case OPT_SEPALPHA: dwFilterOpts |= TEX_FILTER_SEPARATE_ALPHA; break; case OPT_PREFIX: wcscpy_s(szPrefix, MAX_PATH, pValue); break; case OPT_SUFFIX: wcscpy_s(szSuffix, MAX_PATH, pValue); break; case OPT_OUTPUTDIR: wcscpy_s(szOutputDir, MAX_PATH, pValue); break; case OPT_FILETYPE: FileType = LookupByName(pValue, g_pSaveFileTypes); if ( !FileType ) { wprintf( L"Invalid value specified with -ft (%ls)\n", pValue); wprintf( L"\n"); PrintUsage(); return 1; } break; case OPT_TA_WRAP: if ( dwFilterOpts & TEX_FILTER_MIRROR ) { wprintf( L"Can't use -wrap and -mirror at same time\n\n"); PrintUsage(); return 1; } dwFilterOpts |= TEX_FILTER_WRAP; break; case OPT_TA_MIRROR: if ( dwFilterOpts & TEX_FILTER_WRAP ) { wprintf( L"Can't use -wrap and -mirror at same time\n\n"); PrintUsage(); return 1; } dwFilterOpts |= TEX_FILTER_MIRROR; break; case OPT_NORMAL_MAP: { dwNormalMap = 0; if ( wcschr( pValue, L'l' ) ) { dwNormalMap |= CNMAP_CHANNEL_LUMINANCE; } else if ( wcschr( pValue, L'r' ) ) { dwNormalMap |= CNMAP_CHANNEL_RED; } else if ( wcschr( pValue, L'g' ) ) { dwNormalMap |= CNMAP_CHANNEL_GREEN; } else if ( wcschr( pValue, L'b' ) ) { dwNormalMap |= CNMAP_CHANNEL_BLUE; } else if ( wcschr( pValue, L'a' ) ) { dwNormalMap |= CNMAP_CHANNEL_ALPHA; } else { wprintf( L"Invalid value specified for -nmap (%ls), missing l, r, g, b, or a\n\n", pValue ); PrintUsage(); return 1; } if ( wcschr( pValue, L'm' ) ) { dwNormalMap |= CNMAP_MIRROR; } else { if ( wcschr( pValue, L'u' ) ) { dwNormalMap |= CNMAP_MIRROR_U; } if ( wcschr( pValue, L'v' ) ) { dwNormalMap |= CNMAP_MIRROR_V; } } if ( wcschr( pValue, L'i' ) ) { dwNormalMap |= CNMAP_INVERT_SIGN; } if ( wcschr( pValue, L'o' ) ) { dwNormalMap |= CNMAP_COMPUTE_OCCLUSION; } } break; case OPT_NORMAL_MAP_AMPLITUDE: if ( !dwNormalMap ) { wprintf( L"-nmapamp requires -nmap\n\n" ); PrintUsage(); return 1; } else if (swscanf_s(pValue, L"%f", &nmapAmplitude) != 1) { wprintf( L"Invalid value specified with -nmapamp (%ls)\n\n", pValue); PrintUsage(); return 1; } else if ( nmapAmplitude < 0.f ) { wprintf( L"Normal map amplitude must be positive (%ls)\n\n", pValue); PrintUsage(); return 1; } break; case OPT_FEATURE_LEVEL: maxSize = LookupByName( pValue, g_pFeatureLevels ); if ( !maxSize ) { wprintf( L"Invalid value specified with -fl (%ls)\n", pValue); wprintf( L"\n"); PrintUsage(); return 1; } break; case OPT_ALPHA_WEIGHT: if (swscanf_s(pValue, L"%f", &alphaWeight) != 1) { wprintf( L"Invalid value specified with -aw (%ls)\n", pValue); wprintf( L"\n"); PrintUsage(); return 1; } else if ( alphaWeight < 0.f ) { wprintf( L"-aw (%ls) parameter must be positive\n", pValue); wprintf( L"\n"); return 1; } break; case OPT_COMPRESS_UNIFORM: dwCompress |= TEX_COMPRESS_UNIFORM; break; case OPT_COMPRESS_MAX: dwCompress |= TEX_COMPRESS_BC7_USE_3SUBSETS; break; case OPT_COMPRESS_DITHER: dwCompress |= TEX_COMPRESS_DITHER; break; } } else { SConversion conv; wcscpy_s(conv.szSrc, MAX_PATH, pArg); conv.szDest[0] = 0; conversion.push_back(conv); } } if(conversion.empty()) { PrintUsage(); return 0; } if(~dwOptions & (DWORD64(1) << OPT_NOLOGO)) PrintLogo(); // Work out out filename prefix and suffix if(szOutputDir[0] && (L'\\' != szOutputDir[wcslen(szOutputDir) - 1])) wcscat_s( szOutputDir, MAX_PATH, L"\\" ); if(szPrefix[0]) wcscat_s(szOutputDir, MAX_PATH, szPrefix); wcscpy_s(szPrefix, MAX_PATH, szOutputDir); const WCHAR* fileTypeName = LookupByValue(FileType, g_pSaveFileTypes); if (fileTypeName) { wcscat_s(szSuffix, MAX_PATH, L"."); wcscat_s(szSuffix, MAX_PATH, fileTypeName); } else { wcscat_s(szSuffix, MAX_PATH, L".unknown"); } if (FileType != CODEC_DDS) { mipLevels = 1; } LARGE_INTEGER qpcFreq; if ( !QueryPerformanceFrequency( &qpcFreq ) ) { qpcFreq.QuadPart = 0; } LARGE_INTEGER qpcStart; if ( !QueryPerformanceCounter( &qpcStart ) ) { qpcStart.QuadPart = 0; } // Convert images bool nonpow2warn = false; bool non4bc = false; ComPtr pDevice; for( auto pConv = conversion.begin(); pConv != conversion.end(); ++pConv ) { if ( pConv != conversion.begin() ) wprintf( L"\n"); // Load source image wprintf( L"reading %ls", pConv->szSrc ); fflush(stdout); WCHAR ext[_MAX_EXT]; WCHAR fname[_MAX_FNAME]; _wsplitpath_s( pConv->szSrc, nullptr, 0, nullptr, 0, fname, _MAX_FNAME, ext, _MAX_EXT ); TexMetadata info; std::unique_ptr image( new (std::nothrow) ScratchImage ); if ( !image ) { wprintf( L" ERROR: Memory allocation failed\n" ); return 1; } if ( _wcsicmp( ext, L".dds" ) == 0 ) { DWORD ddsFlags = DDS_FLAGS_NONE; if ( dwOptions & (DWORD64(1) << OPT_DDS_DWORD_ALIGN) ) ddsFlags |= DDS_FLAGS_LEGACY_DWORD; if ( dwOptions & (DWORD64(1) << OPT_EXPAND_LUMINANCE) ) ddsFlags |= DDS_FLAGS_EXPAND_LUMINANCE; hr = LoadFromDDSFile( pConv->szSrc, ddsFlags, &info, *image ); if ( FAILED(hr) ) { wprintf( L" FAILED (%x)\n", hr); continue; } if ( IsTypeless( info.format ) ) { if ( dwOptions & (DWORD64(1) << OPT_TYPELESS_UNORM) ) { info.format = MakeTypelessUNORM( info.format ); } else if ( dwOptions & (DWORD64(1) << OPT_TYPELESS_FLOAT) ) { info.format = MakeTypelessFLOAT( info.format ); } if ( IsTypeless( info.format ) ) { wprintf( L" FAILED due to Typeless format %d\n", info.format ); continue; } image->OverrideFormat( info.format ); } } else if ( _wcsicmp( ext, L".tga" ) == 0 ) { hr = LoadFromTGAFile( pConv->szSrc, &info, *image ); if ( FAILED(hr) ) { wprintf( L" FAILED (%x)\n", hr); continue; } } else { // WIC shares the same filter values for mode and dither static_assert( WIC_FLAGS_DITHER == TEX_FILTER_DITHER, "WIC_FLAGS_* & TEX_FILTER_* should match" ); static_assert( WIC_FLAGS_DITHER_DIFFUSION == TEX_FILTER_DITHER_DIFFUSION, "WIC_FLAGS_* & TEX_FILTER_* should match" ); static_assert( WIC_FLAGS_FILTER_POINT == TEX_FILTER_POINT, "WIC_FLAGS_* & TEX_FILTER_* should match" ); static_assert( WIC_FLAGS_FILTER_LINEAR == TEX_FILTER_LINEAR, "WIC_FLAGS_* & TEX_FILTER_* should match" ); static_assert( WIC_FLAGS_FILTER_CUBIC == TEX_FILTER_CUBIC, "WIC_FLAGS_* & TEX_FILTER_* should match" ); static_assert( WIC_FLAGS_FILTER_FANT == TEX_FILTER_FANT, "WIC_FLAGS_* & TEX_FILTER_* should match" ); DWORD wicFlags = dwFilter; if (FileType == CODEC_DDS) wicFlags |= WIC_FLAGS_ALL_FRAMES; hr = LoadFromWICFile( pConv->szSrc, wicFlags, &info, *image ); if ( FAILED(hr) ) { wprintf( L" FAILED (%x)\n", hr); continue; } } PrintInfo( info ); size_t tMips = ( !mipLevels && info.mipLevels > 1 ) ? info.mipLevels : mipLevels; bool sizewarn = false; size_t twidth = ( !width ) ? info.width : width; if ( twidth > maxSize ) { if ( !width ) twidth = maxSize; else sizewarn = true; } size_t theight = ( !height ) ? info.height : height; if ( theight > maxSize ) { if ( !height ) theight = maxSize; else sizewarn = true; } if ( sizewarn ) { wprintf( L"\nWARNING: Target size exceeds maximum size for feature level (%u)\n", maxSize ); } if (dwOptions & (DWORD64(1) << OPT_FIT_POWEROF2)) { FitPowerOf2( info.width, info.height, twidth, theight, maxSize ); } // Convert texture wprintf( L" as"); fflush(stdout); // --- Planar ------------------------------------------------------------------ if ( IsPlanar( info.format ) ) { auto img = image->GetImage(0,0,0); assert( img ); size_t nimg = image->GetImageCount(); std::unique_ptr timage( new (std::nothrow) ScratchImage ); if ( !timage ) { wprintf( L" ERROR: Memory allocation failed\n" ); return 1; } hr = ConvertToSinglePlane( img, nimg, info, *timage ); if ( FAILED(hr) ) { wprintf( L" FAILED [converttosingeplane] (%x)\n", hr); continue; } auto& tinfo = timage->GetMetadata(); info.format = tinfo.format; assert( info.width == tinfo.width ); assert( info.height == tinfo.height ); assert( info.depth == tinfo.depth ); assert( info.arraySize == tinfo.arraySize ); assert( info.mipLevels == tinfo.mipLevels ); assert( info.miscFlags == tinfo.miscFlags ); assert( info.miscFlags2 == tinfo.miscFlags2 ); assert( info.dimension == tinfo.dimension ); image.swap( timage ); } DXGI_FORMAT tformat = ( format == DXGI_FORMAT_UNKNOWN ) ? info.format : format; // --- Decompress -------------------------------------------------------------- std::unique_ptr cimage; if ( IsCompressed( info.format ) ) { auto img = image->GetImage(0,0,0); assert( img ); size_t nimg = image->GetImageCount(); std::unique_ptr timage( new (std::nothrow) ScratchImage ); if ( !timage ) { wprintf( L" ERROR: Memory allocation failed\n" ); return 1; } hr = Decompress( img, nimg, info, DXGI_FORMAT_UNKNOWN /* picks good default */, *timage ); if ( FAILED(hr) ) { wprintf( L" FAILED [decompress] (%x)\n", hr); continue; } auto& tinfo = timage->GetMetadata(); info.format = tinfo.format; assert( info.width == tinfo.width ); assert( info.height == tinfo.height ); assert( info.depth == tinfo.depth ); assert( info.arraySize == tinfo.arraySize ); assert( info.mipLevels == tinfo.mipLevels ); assert( info.miscFlags == tinfo.miscFlags ); assert( info.miscFlags2 == tinfo.miscFlags2 ); assert( info.dimension == tinfo.dimension ); if ( FileType == CODEC_DDS ) { // Keep the original compressed image in case we can reuse it cimage.reset( image.release() ); image.reset( timage.release() ); } else { image.swap( timage ); } } // --- Flip/Rotate ------------------------------------------------------------- if ( dwOptions & ( (DWORD64(1) << OPT_HFLIP) | (DWORD64(1) << OPT_VFLIP) ) ) { std::unique_ptr timage( new (std::nothrow) ScratchImage ); if ( !timage ) { wprintf( L" ERROR: Memory allocation failed\n" ); return 1; } DWORD dwFlags = 0; if ( dwOptions & (DWORD64(1) << OPT_HFLIP) ) dwFlags |= TEX_FR_FLIP_HORIZONTAL; if ( dwOptions & (DWORD64(1) << OPT_VFLIP) ) dwFlags |= TEX_FR_FLIP_VERTICAL; assert( dwFlags != 0 ); hr = FlipRotate( image->GetImages(), image->GetImageCount(), image->GetMetadata(), dwFlags, *timage ); if ( FAILED(hr) ) { wprintf( L" FAILED [fliprotate] (%x)\n", hr); return 1; } auto& tinfo = timage->GetMetadata(); assert( tinfo.width == twidth && tinfo.height == theight ); info.width = tinfo.width; info.height = tinfo.height; assert( info.depth == tinfo.depth ); assert( info.arraySize == tinfo.arraySize ); assert( info.mipLevels == tinfo.mipLevels ); assert( info.miscFlags == tinfo.miscFlags ); assert( info.miscFlags2 == tinfo.miscFlags2 ); assert( info.format == tinfo.format ); assert( info.dimension == tinfo.dimension ); image.swap( timage ); cimage.reset(); } // --- Resize ------------------------------------------------------------------ if ( info.width != twidth || info.height != theight ) { std::unique_ptr timage( new (std::nothrow) ScratchImage ); if ( !timage ) { wprintf( L" ERROR: Memory allocation failed\n" ); return 1; } hr = Resize( image->GetImages(), image->GetImageCount(), image->GetMetadata(), twidth, theight, dwFilter | dwFilterOpts, *timage ); if ( FAILED(hr) ) { wprintf( L" FAILED [resize] (%x)\n", hr); return 1; } auto& tinfo = timage->GetMetadata(); assert( tinfo.width == twidth && tinfo.height == theight && tinfo.mipLevels == 1 ); info.width = tinfo.width; info.height = tinfo.height; info.mipLevels = 1; assert( info.depth == tinfo.depth ); assert( info.arraySize == tinfo.arraySize ); assert( info.miscFlags == tinfo.miscFlags ); assert( info.miscFlags2 == tinfo.miscFlags2 ); assert( info.format == tinfo.format ); assert( info.dimension == tinfo.dimension ); image.swap( timage ); cimage.reset(); } // --- Convert ----------------------------------------------------------------- if ( dwOptions & (DWORD64(1) << OPT_NORMAL_MAP) ) { std::unique_ptr timage( new (std::nothrow) ScratchImage ); if ( !timage ) { wprintf( L" ERROR: Memory allocation failed\n" ); return 1; } DXGI_FORMAT nmfmt = tformat; if ( IsCompressed( tformat ) ) { nmfmt = (dwNormalMap & CNMAP_COMPUTE_OCCLUSION) ? DXGI_FORMAT_R32G32B32A32_FLOAT : DXGI_FORMAT_R32G32B32_FLOAT; } hr = ComputeNormalMap( image->GetImages(), image->GetImageCount(), image->GetMetadata(), dwNormalMap, nmapAmplitude, nmfmt, *timage ); if ( FAILED(hr) ) { wprintf( L" FAILED [normalmap] (%x)\n", hr); return 1; } auto& tinfo = timage->GetMetadata(); assert( tinfo.format == nmfmt ); info.format = tinfo.format; assert( info.width == tinfo.width ); assert( info.height == tinfo.height ); assert( info.depth == tinfo.depth ); assert( info.arraySize == tinfo.arraySize ); assert( info.mipLevels == tinfo.mipLevels ); assert( info.miscFlags == tinfo.miscFlags ); assert( info.miscFlags2 == tinfo.miscFlags2 ); assert( info.dimension == tinfo.dimension ); image.swap( timage ); cimage.reset(); } else if ( info.format != tformat && !IsCompressed( tformat ) ) { std::unique_ptr timage( new (std::nothrow) ScratchImage ); if ( !timage ) { wprintf( L" ERROR: Memory allocation failed\n" ); return 1; } hr = Convert( image->GetImages(), image->GetImageCount(), image->GetMetadata(), tformat, dwFilter | dwFilterOpts | dwSRGB, 0.5f, *timage ); if ( FAILED(hr) ) { wprintf( L" FAILED [convert] (%x)\n", hr); return 1; } auto& tinfo = timage->GetMetadata(); assert( tinfo.format == tformat ); info.format = tinfo.format; assert( info.width == tinfo.width ); assert( info.height == tinfo.height ); assert( info.depth == tinfo.depth ); assert( info.arraySize == tinfo.arraySize ); assert( info.mipLevels == tinfo.mipLevels ); assert( info.miscFlags == tinfo.miscFlags ); assert( info.miscFlags2 == tinfo.miscFlags2 ); assert( info.dimension == tinfo.dimension ); image.swap( timage ); cimage.reset(); } // --- Generate mips ----------------------------------------------------------- if ( !ispow2(info.width) || !ispow2(info.height) || !ispow2(info.depth) ) { if ( info.dimension == TEX_DIMENSION_TEXTURE3D ) { if ( !tMips ) { tMips = 1; } else { wprintf( L" ERROR: Cannot generate mips for non-power-of-2 volume textures\n" ); return 1; } } else if ( !tMips || info.mipLevels != 1 ) { nonpow2warn = true; } } if ( (!tMips || info.mipLevels != tMips) && ( info.mipLevels != 1 ) ) { // Mips generation only works on a single base image, so strip off existing mip levels std::unique_ptr timage( new (std::nothrow) ScratchImage ); if ( !timage ) { wprintf( L" ERROR: Memory allocation failed\n" ); return 1; } TexMetadata mdata = info; mdata.mipLevels = 1; hr = timage->Initialize( mdata ); if ( FAILED(hr) ) { wprintf( L" FAILED [copy to single level] (%x)\n", hr); return 1; } if ( info.dimension == TEX_DIMENSION_TEXTURE3D ) { for( size_t d = 0; d < info.depth; ++d ) { hr = CopyRectangle( *image->GetImage( 0, 0, d ), Rect( 0, 0, info.width, info.height ), *timage->GetImage( 0, 0, d ), TEX_FILTER_DEFAULT, 0, 0 ); if ( FAILED(hr) ) { wprintf( L" FAILED [copy to single level] (%x)\n", hr); return 1; } } } else { for( size_t i = 0; i < info.arraySize; ++i ) { hr = CopyRectangle( *image->GetImage( 0, i, 0 ), Rect( 0, 0, info.width, info.height ), *timage->GetImage( 0, i, 0 ), TEX_FILTER_DEFAULT, 0, 0 ); if ( FAILED(hr) ) { wprintf( L" FAILED [copy to single level] (%x)\n", hr); return 1; } } } image.swap( timage ); info.mipLevels = image->GetMetadata().mipLevels; if ( cimage && ( tMips == 1 ) ) { // Special case for trimming mips off compressed images and keeping the original compressed highest level mip mdata = cimage->GetMetadata(); mdata.mipLevels = 1; hr = timage->Initialize( mdata ); if ( FAILED(hr) ) { wprintf( L" FAILED [copy compressed to single level] (%x)\n", hr); return 1; } if ( mdata.dimension == TEX_DIMENSION_TEXTURE3D ) { for( size_t d = 0; d < mdata.depth; ++d ) { auto simg = cimage->GetImage( 0, 0, d ); auto dimg = timage->GetImage( 0, 0, d ); memcpy_s( dimg->pixels, dimg->slicePitch, simg->pixels, simg->slicePitch ); } } else { for( size_t i = 0; i < mdata.arraySize; ++i ) { auto simg = cimage->GetImage( 0, i, 0 ); auto dimg = timage->GetImage( 0, i, 0 ); memcpy_s( dimg->pixels, dimg->slicePitch, simg->pixels, simg->slicePitch ); } } cimage.swap( timage ); } else { cimage.reset(); } } if ( ( !tMips || info.mipLevels != tMips ) && ( info.width > 1 || info.height > 1 || info.depth > 1 ) ) { std::unique_ptr timage( new (std::nothrow) ScratchImage ); if ( !timage ) { wprintf( L" ERROR: Memory allocation failed\n" ); return 1; } if ( info.dimension == TEX_DIMENSION_TEXTURE3D ) { hr = GenerateMipMaps3D( image->GetImages(), image->GetImageCount(), image->GetMetadata(), dwFilter | dwFilterOpts, tMips, *timage ); } else { hr = GenerateMipMaps( image->GetImages(), image->GetImageCount(), image->GetMetadata(), dwFilter | dwFilterOpts, tMips, *timage ); } if ( FAILED(hr) ) { wprintf( L" FAILED [mipmaps] (%x)\n", hr); return 1; } auto& tinfo = timage->GetMetadata(); info.mipLevels = tinfo.mipLevels; assert( info.width == tinfo.width ); assert( info.height == tinfo.height ); assert( info.depth == tinfo.depth ); assert( info.arraySize == tinfo.arraySize ); assert( info.mipLevels == tinfo.mipLevels ); assert( info.miscFlags == tinfo.miscFlags ); assert( info.miscFlags2 == tinfo.miscFlags2 ); assert( info.dimension == tinfo.dimension ); image.swap( timage ); cimage.reset(); } // --- Premultiplied alpha (if requested) -------------------------------------- if ( ( dwOptions & (DWORD64(1) << OPT_PREMUL_ALPHA) ) && HasAlpha( info.format ) && info.format != DXGI_FORMAT_A8_UNORM ) { if ( info.IsPMAlpha() ) { printf("WARNING: Image is already using premultiplied alpha\n"); } else { auto img = image->GetImage(0,0,0); assert( img ); size_t nimg = image->GetImageCount(); std::unique_ptr timage( new (std::nothrow) ScratchImage ); if ( !timage ) { wprintf( L" ERROR: Memory allocation failed\n" ); return 1; } hr = PremultiplyAlpha( img, nimg, info, dwSRGB, *timage ); if ( FAILED(hr) ) { wprintf( L" FAILED [premultiply alpha] (%x)\n", hr); continue; } auto& tinfo = timage->GetMetadata(); info.miscFlags2 = tinfo.miscFlags2; assert( info.width == tinfo.width ); assert( info.height == tinfo.height ); assert( info.depth == tinfo.depth ); assert( info.arraySize == tinfo.arraySize ); assert( info.mipLevels == tinfo.mipLevels ); assert( info.miscFlags == tinfo.miscFlags ); assert( info.miscFlags2 == tinfo.miscFlags2 ); assert( info.dimension == tinfo.dimension ); image.swap( timage ); cimage.reset(); } } // --- Compress ---------------------------------------------------------------- if ( IsCompressed( tformat ) && (FileType == CODEC_DDS) ) { if ( cimage && ( cimage->GetMetadata().format == tformat ) ) { // We never changed the image and it was already compressed in our desired format, use original data image.reset( cimage.release() ); auto& tinfo = image->GetMetadata(); if ( (tinfo.width % 4) != 0 || (tinfo.height % 4) != 0 ) { non4bc = true; } info.format = tinfo.format; assert( info.width == tinfo.width ); assert( info.height == tinfo.height ); assert( info.depth == tinfo.depth ); assert( info.arraySize == tinfo.arraySize ); assert( info.mipLevels == tinfo.mipLevels ); assert( info.miscFlags == tinfo.miscFlags ); assert( info.miscFlags2 == tinfo.miscFlags2 ); assert( info.dimension == tinfo.dimension ); } else { cimage.reset(); auto img = image->GetImage(0,0,0); assert( img ); size_t nimg = image->GetImageCount(); std::unique_ptr timage( new (std::nothrow) ScratchImage ); if ( !timage ) { wprintf( L" ERROR: Memory allocation failed\n" ); return 1; } bool bc6hbc7=false; switch( tformat ) { case DXGI_FORMAT_BC6H_TYPELESS: case DXGI_FORMAT_BC6H_UF16: case DXGI_FORMAT_BC6H_SF16: case DXGI_FORMAT_BC7_TYPELESS: case DXGI_FORMAT_BC7_UNORM: case DXGI_FORMAT_BC7_UNORM_SRGB: bc6hbc7=true; { static bool s_tryonce = false; if ( !s_tryonce ) { s_tryonce = true; if ( !(dwOptions & (DWORD64(1) << OPT_NOGPU) ) ) { if ( !CreateDevice( pDevice.GetAddressOf() ) ) wprintf( L"\nWARNING: DirectCompute is not available, using BC6H / BC7 CPU codec\n" ); } else { wprintf( L"\nWARNING: using BC6H / BC7 CPU codec\n" ); } } } break; } DWORD cflags = dwCompress; #ifdef _OPENMP if ( !(dwOptions & (DWORD64(1) << OPT_FORCE_SINGLEPROC) ) ) { cflags |= TEX_COMPRESS_PARALLEL; } #endif if ( (img->width % 4) != 0 || (img->height % 4) != 0 ) { non4bc = true; } if ( bc6hbc7 && pDevice ) { hr = Compress( pDevice.Get(), img, nimg, info, tformat, dwCompress | dwSRGB, alphaWeight, *timage ); } else { hr = Compress( img, nimg, info, tformat, cflags | dwSRGB, 0.5f, *timage ); } if ( FAILED(hr) ) { wprintf( L" FAILED [compress] (%x)\n", hr); continue; } auto& tinfo = timage->GetMetadata(); info.format = tinfo.format; assert( info.width == tinfo.width ); assert( info.height == tinfo.height ); assert( info.depth == tinfo.depth ); assert( info.arraySize == tinfo.arraySize ); assert( info.mipLevels == tinfo.mipLevels ); assert( info.miscFlags == tinfo.miscFlags ); assert( info.miscFlags2 == tinfo.miscFlags2 ); assert( info.dimension == tinfo.dimension ); image.swap( timage ); } } else { cimage.reset(); } // --- Set alpha mode ---------------------------------------------------------- if ( HasAlpha( info.format ) && info.format != DXGI_FORMAT_A8_UNORM ) { if ( image->IsAlphaAllOpaque() ) { info.SetAlphaMode(TEX_ALPHA_MODE_OPAQUE); } else if ( info.IsPMAlpha() ) { // Aleady set TEX_ALPHA_MODE_PREMULTIPLIED } else if ( dwOptions & (DWORD64(1) << OPT_SEPALPHA) ) { info.SetAlphaMode(TEX_ALPHA_MODE_CUSTOM); } else { info.SetAlphaMode(TEX_ALPHA_MODE_STRAIGHT); } } else { info.miscFlags2 &= ~TEX_MISC2_ALPHA_MODE_MASK; } // --- Save result ------------------------------------------------------------- { auto img = image->GetImage(0,0,0); assert( img ); size_t nimg = image->GetImageCount(); PrintInfo( info ); wprintf( L"\n"); // Figure out dest filename WCHAR *pchSlash, *pchDot; wcscpy_s(pConv->szDest, MAX_PATH, szPrefix); pchSlash = wcsrchr(pConv->szSrc, L'\\'); if(pchSlash != 0) wcscat_s(pConv->szDest, MAX_PATH, pchSlash + 1); else wcscat_s(pConv->szDest, MAX_PATH, pConv->szSrc); pchSlash = wcsrchr(pConv->szDest, '\\'); pchDot = wcsrchr(pConv->szDest, '.'); if(pchDot > pchSlash) *pchDot = 0; wcscat_s(pConv->szDest, MAX_PATH, szSuffix); // Write texture wprintf( L"writing %ls", pConv->szDest); fflush(stdout); switch( FileType ) { case CODEC_DDS: hr = SaveToDDSFile( img, nimg, info, (dwOptions & (DWORD64(1) << OPT_USE_DX10) ) ? (DDS_FLAGS_FORCE_DX10_EXT|DDS_FLAGS_FORCE_DX10_EXT_MISC2) : DDS_FLAGS_NONE, pConv->szDest ); break; case CODEC_TGA: hr = SaveToTGAFile( img[0], pConv->szDest ); break; default: hr = SaveToWICFile( img, nimg, WIC_FLAGS_ALL_FRAMES, GetWICCodec( static_cast(FileType) ), pConv->szDest ); break; } if(FAILED(hr)) { wprintf( L" FAILED (%x)\n", hr); continue; } wprintf( L"\n"); } } if ( nonpow2warn ) wprintf( L"\n WARNING: Not all feature levels support non-power-of-2 textures with mipmaps\n" ); if ( non4bc ) wprintf( L"\n WARNING: Direct3D requires BC image to be multiple of 4 in width & height\n" ); if(dwOptions & (DWORD64(1) << OPT_TIMING)) { LARGE_INTEGER qpcEnd; if ( QueryPerformanceCounter( &qpcEnd ) ) { LONGLONG delta = qpcEnd.QuadPart - qpcStart.QuadPart; wprintf( L"\n Processing time: %f seconds\n", double(delta) / double(qpcFreq.QuadPart) ); } } return 0; } ================================================ FILE: 3rdParty/DirectXTex/WICTextureLoader/WICTextureLoader.cpp ================================================ //-------------------------------------------------------------------------------------- // File: WICTextureLoader.cpp // // Function for loading a WIC image and creating a Direct3D 11 runtime texture for it // (auto-generating mipmaps if possible) // // Note: Assumes application has already called CoInitializeEx // // Warning: CreateWICTexture* functions are not thread-safe if given a d3dContext instance for // auto-gen mipmap support. // // Note these functions are useful for images created as simple 2D textures. For // more complex resources, DDSTextureLoader is an excellent light-weight runtime loader. // For a full-featured DDS file reader, writer, and texture processing pipeline see // the 'Texconv' sample and the 'DirectXTex' library. // // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A // PARTICULAR PURPOSE. // // Copyright (c) Microsoft Corporation. All rights reserved. // // http://go.microsoft.com/fwlink/?LinkId=248926 // http://go.microsoft.com/fwlink/?LinkId=248929 //-------------------------------------------------------------------------------------- // We could load multi-frame images (TIFF/GIF) into a texture array. // For now, we just load the first frame (note: DirectXTex supports multi-frame images) #include #include // VS 2010's stdint.h conflicts with intsafe.h #pragma warning(push) #pragma warning(disable : 4005) #include #include #pragma warning(pop) #include #include #include "WICTextureLoader.h" #if !defined(NO_D3D11_DEBUG_NAME) && ( defined(_DEBUG) || defined(PROFILE) ) #pragma comment(lib,"dxguid.lib") #endif using Microsoft::WRL::ComPtr; //-------------------------------------------------------------------------------------- template inline void SetDebugObjectName(_In_ ID3D11DeviceChild* resource, _In_ const char (&name)[TNameLength]) { #if !defined(NO_D3D11_DEBUG_NAME) && ( defined(_DEBUG) || defined(PROFILE) ) resource->SetPrivateData(WKPDID_D3DDebugObjectName, TNameLength - 1, name); #else UNREFERENCED_PARAMETER(resource); UNREFERENCED_PARAMETER(name); #endif } //------------------------------------------------------------------------------------- // WIC Pixel Format Translation Data //------------------------------------------------------------------------------------- struct WICTranslate { GUID wic; DXGI_FORMAT format; }; static WICTranslate g_WICFormats[] = { { GUID_WICPixelFormat128bppRGBAFloat, DXGI_FORMAT_R32G32B32A32_FLOAT }, { GUID_WICPixelFormat64bppRGBAHalf, DXGI_FORMAT_R16G16B16A16_FLOAT }, { GUID_WICPixelFormat64bppRGBA, DXGI_FORMAT_R16G16B16A16_UNORM }, { GUID_WICPixelFormat32bppRGBA, DXGI_FORMAT_R8G8B8A8_UNORM }, { GUID_WICPixelFormat32bppBGRA, DXGI_FORMAT_B8G8R8A8_UNORM }, // DXGI 1.1 { GUID_WICPixelFormat32bppBGR, DXGI_FORMAT_B8G8R8X8_UNORM }, // DXGI 1.1 { GUID_WICPixelFormat32bppRGBA1010102XR, DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM }, // DXGI 1.1 { GUID_WICPixelFormat32bppRGBA1010102, DXGI_FORMAT_R10G10B10A2_UNORM }, { GUID_WICPixelFormat16bppBGRA5551, DXGI_FORMAT_B5G5R5A1_UNORM }, { GUID_WICPixelFormat16bppBGR565, DXGI_FORMAT_B5G6R5_UNORM }, { GUID_WICPixelFormat32bppGrayFloat, DXGI_FORMAT_R32_FLOAT }, { GUID_WICPixelFormat16bppGrayHalf, DXGI_FORMAT_R16_FLOAT }, { GUID_WICPixelFormat16bppGray, DXGI_FORMAT_R16_UNORM }, { GUID_WICPixelFormat8bppGray, DXGI_FORMAT_R8_UNORM }, { GUID_WICPixelFormat8bppAlpha, DXGI_FORMAT_A8_UNORM }, }; //------------------------------------------------------------------------------------- // WIC Pixel Format nearest conversion table //------------------------------------------------------------------------------------- struct WICConvert { GUID source; GUID target; }; static WICConvert g_WICConvert[] = { // Note target GUID in this conversion table must be one of those directly supported formats (above). { GUID_WICPixelFormatBlackWhite, GUID_WICPixelFormat8bppGray }, // DXGI_FORMAT_R8_UNORM { GUID_WICPixelFormat1bppIndexed, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM { GUID_WICPixelFormat2bppIndexed, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM { GUID_WICPixelFormat4bppIndexed, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM { GUID_WICPixelFormat8bppIndexed, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM { GUID_WICPixelFormat2bppGray, GUID_WICPixelFormat8bppGray }, // DXGI_FORMAT_R8_UNORM { GUID_WICPixelFormat4bppGray, GUID_WICPixelFormat8bppGray }, // DXGI_FORMAT_R8_UNORM { GUID_WICPixelFormat16bppGrayFixedPoint, GUID_WICPixelFormat16bppGrayHalf }, // DXGI_FORMAT_R16_FLOAT { GUID_WICPixelFormat32bppGrayFixedPoint, GUID_WICPixelFormat32bppGrayFloat }, // DXGI_FORMAT_R32_FLOAT { GUID_WICPixelFormat16bppBGR555, GUID_WICPixelFormat16bppBGRA5551 }, // DXGI_FORMAT_B5G5R5A1_UNORM { GUID_WICPixelFormat32bppBGR101010, GUID_WICPixelFormat32bppRGBA1010102 }, // DXGI_FORMAT_R10G10B10A2_UNORM { GUID_WICPixelFormat24bppBGR, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM { GUID_WICPixelFormat24bppRGB, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM { GUID_WICPixelFormat32bppPBGRA, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM { GUID_WICPixelFormat32bppPRGBA, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM { GUID_WICPixelFormat48bppRGB, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM { GUID_WICPixelFormat48bppBGR, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM { GUID_WICPixelFormat64bppBGRA, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM { GUID_WICPixelFormat64bppPRGBA, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM { GUID_WICPixelFormat64bppPBGRA, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM { GUID_WICPixelFormat48bppRGBFixedPoint, GUID_WICPixelFormat64bppRGBAHalf }, // DXGI_FORMAT_R16G16B16A16_FLOAT { GUID_WICPixelFormat48bppBGRFixedPoint, GUID_WICPixelFormat64bppRGBAHalf }, // DXGI_FORMAT_R16G16B16A16_FLOAT { GUID_WICPixelFormat64bppRGBAFixedPoint, GUID_WICPixelFormat64bppRGBAHalf }, // DXGI_FORMAT_R16G16B16A16_FLOAT { GUID_WICPixelFormat64bppBGRAFixedPoint, GUID_WICPixelFormat64bppRGBAHalf }, // DXGI_FORMAT_R16G16B16A16_FLOAT { GUID_WICPixelFormat64bppRGBFixedPoint, GUID_WICPixelFormat64bppRGBAHalf }, // DXGI_FORMAT_R16G16B16A16_FLOAT { GUID_WICPixelFormat64bppRGBHalf, GUID_WICPixelFormat64bppRGBAHalf }, // DXGI_FORMAT_R16G16B16A16_FLOAT { GUID_WICPixelFormat48bppRGBHalf, GUID_WICPixelFormat64bppRGBAHalf }, // DXGI_FORMAT_R16G16B16A16_FLOAT { GUID_WICPixelFormat128bppPRGBAFloat, GUID_WICPixelFormat128bppRGBAFloat }, // DXGI_FORMAT_R32G32B32A32_FLOAT { GUID_WICPixelFormat128bppRGBFloat, GUID_WICPixelFormat128bppRGBAFloat }, // DXGI_FORMAT_R32G32B32A32_FLOAT { GUID_WICPixelFormat128bppRGBAFixedPoint, GUID_WICPixelFormat128bppRGBAFloat }, // DXGI_FORMAT_R32G32B32A32_FLOAT { GUID_WICPixelFormat128bppRGBFixedPoint, GUID_WICPixelFormat128bppRGBAFloat }, // DXGI_FORMAT_R32G32B32A32_FLOAT { GUID_WICPixelFormat32bppRGBE, GUID_WICPixelFormat128bppRGBAFloat }, // DXGI_FORMAT_R32G32B32A32_FLOAT { GUID_WICPixelFormat32bppCMYK, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM { GUID_WICPixelFormat64bppCMYK, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM { GUID_WICPixelFormat40bppCMYKAlpha, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM { GUID_WICPixelFormat80bppCMYKAlpha, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM #if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) || defined(_WIN7_PLATFORM_UPDATE) { GUID_WICPixelFormat32bppRGB, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM { GUID_WICPixelFormat64bppRGB, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM { GUID_WICPixelFormat64bppPRGBAHalf, GUID_WICPixelFormat64bppRGBAHalf }, // DXGI_FORMAT_R16G16B16A16_FLOAT #endif // We don't support n-channel formats }; static bool g_WIC2 = false; //-------------------------------------------------------------------------------------- static IWICImagingFactory* _GetWIC() { static IWICImagingFactory* s_Factory = nullptr; if ( s_Factory ) return s_Factory; #if(_WIN32_WINNT >= _WIN32_WINNT_WIN8) || defined(_WIN7_PLATFORM_UPDATE) HRESULT hr = CoCreateInstance( CLSID_WICImagingFactory2, nullptr, CLSCTX_INPROC_SERVER, __uuidof(IWICImagingFactory2), (LPVOID*)&s_Factory ); if ( SUCCEEDED(hr) ) { // WIC2 is available on Windows 8 and Windows 7 SP1 with KB 2670838 installed g_WIC2 = true; } else { hr = CoCreateInstance( CLSID_WICImagingFactory1, nullptr, CLSCTX_INPROC_SERVER, __uuidof(IWICImagingFactory), (LPVOID*)&s_Factory ); if ( FAILED(hr) ) { s_Factory = nullptr; return nullptr; } } #else HRESULT hr = CoCreateInstance( CLSID_WICImagingFactory, nullptr, CLSCTX_INPROC_SERVER, __uuidof(IWICImagingFactory), (LPVOID*)&s_Factory ); if ( FAILED(hr) ) { s_Factory = nullptr; return nullptr; } #endif return s_Factory; } //--------------------------------------------------------------------------------- static DXGI_FORMAT _WICToDXGI( const GUID& guid ) { for( size_t i=0; i < _countof(g_WICFormats); ++i ) { if ( memcmp( &g_WICFormats[i].wic, &guid, sizeof(GUID) ) == 0 ) return g_WICFormats[i].format; } #if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) || defined(_WIN7_PLATFORM_UPDATE) if ( g_WIC2 ) { if ( memcmp( &GUID_WICPixelFormat96bppRGBFloat, &guid, sizeof(GUID) ) == 0 ) return DXGI_FORMAT_R32G32B32_FLOAT; } #endif return DXGI_FORMAT_UNKNOWN; } //--------------------------------------------------------------------------------- static size_t _WICBitsPerPixel( REFGUID targetGuid ) { IWICImagingFactory* pWIC = _GetWIC(); if ( !pWIC ) return 0; ComPtr cinfo; if ( FAILED( pWIC->CreateComponentInfo( targetGuid, cinfo.GetAddressOf() ) ) ) return 0; WICComponentType type; if ( FAILED( cinfo->GetComponentType( &type ) ) ) return 0; if ( type != WICPixelFormat ) return 0; ComPtr pfinfo; if ( FAILED( cinfo.As( &pfinfo ) ) ) return 0; UINT bpp; if ( FAILED( pfinfo->GetBitsPerPixel( &bpp ) ) ) return 0; return bpp; } //-------------------------------------------------------------------------------------- static DXGI_FORMAT MakeSRGB( _In_ DXGI_FORMAT format ) { switch( format ) { case DXGI_FORMAT_R8G8B8A8_UNORM: return DXGI_FORMAT_R8G8B8A8_UNORM_SRGB; case DXGI_FORMAT_BC1_UNORM: return DXGI_FORMAT_BC1_UNORM_SRGB; case DXGI_FORMAT_BC2_UNORM: return DXGI_FORMAT_BC2_UNORM_SRGB; case DXGI_FORMAT_BC3_UNORM: return DXGI_FORMAT_BC3_UNORM_SRGB; case DXGI_FORMAT_B8G8R8A8_UNORM: return DXGI_FORMAT_B8G8R8A8_UNORM_SRGB; case DXGI_FORMAT_B8G8R8X8_UNORM: return DXGI_FORMAT_B8G8R8X8_UNORM_SRGB; case DXGI_FORMAT_BC7_UNORM: return DXGI_FORMAT_BC7_UNORM_SRGB; default: return format; } } //--------------------------------------------------------------------------------- static HRESULT CreateTextureFromWIC( _In_ ID3D11Device* d3dDevice, _In_opt_ ID3D11DeviceContext* d3dContext, _In_ IWICBitmapFrameDecode *frame, _In_ size_t maxsize, _In_ D3D11_USAGE usage, _In_ unsigned int bindFlags, _In_ unsigned int cpuAccessFlags, _In_ unsigned int miscFlags, _In_ bool forceSRGB, _Out_opt_ ID3D11Resource** texture, _Out_opt_ ID3D11ShaderResourceView** textureView ) { UINT width, height; HRESULT hr = frame->GetSize( &width, &height ); if ( FAILED(hr) ) return hr; assert( width > 0 && height > 0 ); if ( !maxsize ) { // This is a bit conservative because the hardware could support larger textures than // the Feature Level defined minimums, but doing it this way is much easier and more // performant for WIC than the 'fail and retry' model used by DDSTextureLoader switch( d3dDevice->GetFeatureLevel() ) { case D3D_FEATURE_LEVEL_9_1: case D3D_FEATURE_LEVEL_9_2: maxsize = 2048 /*D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION*/; break; case D3D_FEATURE_LEVEL_9_3: maxsize = 4096 /*D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION*/; break; case D3D_FEATURE_LEVEL_10_0: case D3D_FEATURE_LEVEL_10_1: maxsize = 8192 /*D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION*/; break; default: maxsize = D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION; break; } } assert( maxsize > 0 ); UINT twidth, theight; if ( width > maxsize || height > maxsize ) { float ar = static_cast(height) / static_cast(width); if ( width > height ) { twidth = static_cast( maxsize ); theight = static_cast( static_cast(maxsize) * ar ); } else { theight = static_cast( maxsize ); twidth = static_cast( static_cast(maxsize) / ar ); } assert( twidth <= maxsize && theight <= maxsize ); } else { twidth = width; theight = height; } // Determine format WICPixelFormatGUID pixelFormat; hr = frame->GetPixelFormat( &pixelFormat ); if ( FAILED(hr) ) return hr; WICPixelFormatGUID convertGUID; memcpy( &convertGUID, &pixelFormat, sizeof(WICPixelFormatGUID) ); size_t bpp = 0; DXGI_FORMAT format = _WICToDXGI( pixelFormat ); if ( format == DXGI_FORMAT_UNKNOWN ) { if ( memcmp( &GUID_WICPixelFormat96bppRGBFixedPoint, &pixelFormat, sizeof(WICPixelFormatGUID) ) == 0 ) { #if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) || defined(_WIN7_PLATFORM_UPDATE) if ( g_WIC2 ) { memcpy( &convertGUID, &GUID_WICPixelFormat96bppRGBFloat, sizeof(WICPixelFormatGUID) ); format = DXGI_FORMAT_R32G32B32_FLOAT; } else #endif { memcpy( &convertGUID, &GUID_WICPixelFormat128bppRGBAFloat, sizeof(WICPixelFormatGUID) ); format = DXGI_FORMAT_R32G32B32A32_FLOAT; } } else { for( size_t i=0; i < _countof(g_WICConvert); ++i ) { if ( memcmp( &g_WICConvert[i].source, &pixelFormat, sizeof(WICPixelFormatGUID) ) == 0 ) { memcpy( &convertGUID, &g_WICConvert[i].target, sizeof(WICPixelFormatGUID) ); format = _WICToDXGI( g_WICConvert[i].target ); assert( format != DXGI_FORMAT_UNKNOWN ); bpp = _WICBitsPerPixel( convertGUID ); break; } } } if ( format == DXGI_FORMAT_UNKNOWN ) return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); } else { bpp = _WICBitsPerPixel( pixelFormat ); } #if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) || defined(_WIN7_PLATFORM_UPDATE) if ( (format == DXGI_FORMAT_R32G32B32_FLOAT) && d3dContext != 0 && textureView != 0 ) { // Special case test for optional device support for autogen mipchains for R32G32B32_FLOAT UINT fmtSupport = 0; hr = d3dDevice->CheckFormatSupport( DXGI_FORMAT_R32G32B32_FLOAT, &fmtSupport ); if ( FAILED(hr) || !( fmtSupport & D3D11_FORMAT_SUPPORT_MIP_AUTOGEN ) ) { // Use R32G32B32A32_FLOAT instead which is required for Feature Level 10.0 and up memcpy( &convertGUID, &GUID_WICPixelFormat128bppRGBAFloat, sizeof(WICPixelFormatGUID) ); format = DXGI_FORMAT_R32G32B32A32_FLOAT; bpp = 128; } } #endif if ( !bpp ) return E_FAIL; // Handle sRGB formats if ( forceSRGB ) { format = MakeSRGB( format ); } else { ComPtr metareader; if ( SUCCEEDED( frame->GetMetadataQueryReader( metareader.GetAddressOf() ) ) ) { GUID containerFormat; if ( SUCCEEDED( metareader->GetContainerFormat( &containerFormat ) ) ) { // Check for sRGB colorspace metadata bool sRGB = false; PROPVARIANT value; PropVariantInit( &value ); if ( memcmp( &containerFormat, &GUID_ContainerFormatPng, sizeof(GUID) ) == 0 ) { // Check for sRGB chunk if ( SUCCEEDED( metareader->GetMetadataByName( L"/sRGB/RenderingIntent", &value ) ) && value.vt == VT_UI1 ) { sRGB = true; } } else if ( SUCCEEDED( metareader->GetMetadataByName( L"System.Image.ColorSpace", &value ) ) && value.vt == VT_UI2 && value.uiVal == 1 ) { sRGB = true; } PropVariantClear( &value ); if ( sRGB ) format = MakeSRGB( format ); } } } // Verify our target format is supported by the current device // (handles WDDM 1.0 or WDDM 1.1 device driver cases as well as DirectX 11.0 Runtime without 16bpp format support) UINT support = 0; hr = d3dDevice->CheckFormatSupport( format, &support ); if ( FAILED(hr) || !(support & D3D11_FORMAT_SUPPORT_TEXTURE2D) ) { // Fallback to RGBA 32-bit format which is supported by all devices memcpy( &convertGUID, &GUID_WICPixelFormat32bppRGBA, sizeof(WICPixelFormatGUID) ); format = DXGI_FORMAT_R8G8B8A8_UNORM; bpp = 32; } // Allocate temporary memory for image size_t rowPitch = ( twidth * bpp + 7 ) / 8; size_t imageSize = rowPitch * theight; std::unique_ptr temp( new (std::nothrow) uint8_t[ imageSize ] ); if (!temp) return E_OUTOFMEMORY; // Load image data if ( memcmp( &convertGUID, &pixelFormat, sizeof(GUID) ) == 0 && twidth == width && theight == height ) { // No format conversion or resize needed hr = frame->CopyPixels( 0, static_cast( rowPitch ), static_cast( imageSize ), temp.get() ); if ( FAILED(hr) ) return hr; } else if ( twidth != width || theight != height ) { // Resize IWICImagingFactory* pWIC = _GetWIC(); if ( !pWIC ) return E_NOINTERFACE; ComPtr scaler; hr = pWIC->CreateBitmapScaler( scaler.GetAddressOf() ); if ( FAILED(hr) ) return hr; hr = scaler->Initialize( frame, twidth, theight, WICBitmapInterpolationModeFant ); if ( FAILED(hr) ) return hr; WICPixelFormatGUID pfScaler; hr = scaler->GetPixelFormat( &pfScaler ); if ( FAILED(hr) ) return hr; if ( memcmp( &convertGUID, &pfScaler, sizeof(GUID) ) == 0 ) { // No format conversion needed hr = scaler->CopyPixels( 0, static_cast( rowPitch ), static_cast( imageSize ), temp.get() ); if ( FAILED(hr) ) return hr; } else { ComPtr FC; hr = pWIC->CreateFormatConverter( FC.GetAddressOf() ); if ( FAILED(hr) ) return hr; BOOL canConvert = FALSE; hr = FC->CanConvert( pfScaler, convertGUID, &canConvert ); if ( FAILED(hr) || !canConvert ) { return E_UNEXPECTED; } hr = FC->Initialize( scaler.Get(), convertGUID, WICBitmapDitherTypeErrorDiffusion, 0, 0, WICBitmapPaletteTypeCustom ); if ( FAILED(hr) ) return hr; hr = FC->CopyPixels( 0, static_cast( rowPitch ), static_cast( imageSize ), temp.get() ); if ( FAILED(hr) ) return hr; } } else { // Format conversion but no resize IWICImagingFactory* pWIC = _GetWIC(); if ( !pWIC ) return E_NOINTERFACE; ComPtr FC; hr = pWIC->CreateFormatConverter( FC.GetAddressOf() ); if ( FAILED(hr) ) return hr; BOOL canConvert = FALSE; hr = FC->CanConvert( pixelFormat, convertGUID, &canConvert ); if ( FAILED(hr) || !canConvert ) { return E_UNEXPECTED; } hr = FC->Initialize( frame, convertGUID, WICBitmapDitherTypeErrorDiffusion, 0, 0, WICBitmapPaletteTypeCustom ); if ( FAILED(hr) ) return hr; hr = FC->CopyPixels( 0, static_cast( rowPitch ), static_cast( imageSize ), temp.get() ); if ( FAILED(hr) ) return hr; } // See if format is supported for auto-gen mipmaps (varies by feature level) bool autogen = false; if ( d3dContext != 0 && textureView != 0 ) // Must have context and shader-view to auto generate mipmaps { UINT fmtSupport = 0; hr = d3dDevice->CheckFormatSupport( format, &fmtSupport ); if ( SUCCEEDED(hr) && ( fmtSupport & D3D11_FORMAT_SUPPORT_MIP_AUTOGEN ) ) { autogen = true; } } // Create texture D3D11_TEXTURE2D_DESC desc; desc.Width = twidth; desc.Height = theight; desc.MipLevels = (autogen) ? 0 : 1; desc.ArraySize = 1; desc.Format = format; desc.SampleDesc.Count = 1; desc.SampleDesc.Quality = 0; desc.Usage = usage; desc.CPUAccessFlags = cpuAccessFlags; if ( autogen ) { desc.BindFlags = bindFlags | D3D11_BIND_RENDER_TARGET; desc.MiscFlags = miscFlags | D3D11_RESOURCE_MISC_GENERATE_MIPS; } else { desc.BindFlags = bindFlags; desc.MiscFlags = miscFlags; } D3D11_SUBRESOURCE_DATA initData; initData.pSysMem = temp.get(); initData.SysMemPitch = static_cast( rowPitch ); initData.SysMemSlicePitch = static_cast( imageSize ); ID3D11Texture2D* tex = nullptr; hr = d3dDevice->CreateTexture2D( &desc, (autogen) ? nullptr : &initData, &tex ); if ( SUCCEEDED(hr) && tex != 0 ) { if (textureView != 0) { D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc; memset( &SRVDesc, 0, sizeof( SRVDesc ) ); SRVDesc.Format = desc.Format; SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; SRVDesc.Texture2D.MipLevels = (autogen) ? -1 : 1; hr = d3dDevice->CreateShaderResourceView( tex, &SRVDesc, textureView ); if ( FAILED(hr) ) { tex->Release(); return hr; } if ( autogen ) { assert( d3dContext != 0 ); d3dContext->UpdateSubresource( tex, 0, nullptr, temp.get(), static_cast(rowPitch), static_cast(imageSize) ); d3dContext->GenerateMips( *textureView ); } } if (texture != 0) { *texture = tex; } else { SetDebugObjectName(tex, "WICTextureLoader"); tex->Release(); } } return hr; } //-------------------------------------------------------------------------------------- _Use_decl_annotations_ HRESULT DirectX::CreateWICTextureFromMemory( ID3D11Device* d3dDevice, const uint8_t* wicData, size_t wicDataSize, ID3D11Resource** texture, ID3D11ShaderResourceView** textureView, size_t maxsize ) { return CreateWICTextureFromMemoryEx( d3dDevice, nullptr, wicData, wicDataSize, maxsize, D3D11_USAGE_DEFAULT, D3D11_BIND_SHADER_RESOURCE, 0, 0, false, texture, textureView ); } _Use_decl_annotations_ HRESULT DirectX::CreateWICTextureFromMemory( ID3D11Device* d3dDevice, ID3D11DeviceContext* d3dContext, const uint8_t* wicData, size_t wicDataSize, ID3D11Resource** texture, ID3D11ShaderResourceView** textureView, size_t maxsize ) { return CreateWICTextureFromMemoryEx( d3dDevice, d3dContext, wicData, wicDataSize, maxsize, D3D11_USAGE_DEFAULT, D3D11_BIND_SHADER_RESOURCE, 0, 0, false, texture, textureView ); } _Use_decl_annotations_ HRESULT DirectX::CreateWICTextureFromMemoryEx( ID3D11Device* d3dDevice, const uint8_t* wicData, size_t wicDataSize, size_t maxsize, D3D11_USAGE usage, unsigned int bindFlags, unsigned int cpuAccessFlags, unsigned int miscFlags, bool forceSRGB, ID3D11Resource** texture, ID3D11ShaderResourceView** textureView ) { return CreateWICTextureFromMemoryEx( d3dDevice, nullptr, wicData, wicDataSize, maxsize, usage, bindFlags, cpuAccessFlags, miscFlags, forceSRGB, texture, textureView ); } _Use_decl_annotations_ HRESULT DirectX::CreateWICTextureFromMemoryEx( ID3D11Device* d3dDevice, ID3D11DeviceContext* d3dContext, const uint8_t* wicData, size_t wicDataSize, size_t maxsize, D3D11_USAGE usage, unsigned int bindFlags, unsigned int cpuAccessFlags, unsigned int miscFlags, bool forceSRGB, ID3D11Resource** texture, ID3D11ShaderResourceView** textureView ) { if ( texture ) { *texture = nullptr; } if ( textureView ) { *textureView = nullptr; } if (!d3dDevice || !wicData || (!texture && !textureView)) return E_INVALIDARG; if ( !wicDataSize ) return E_FAIL; #ifdef _M_AMD64 if ( wicDataSize > 0xFFFFFFFF ) return HRESULT_FROM_WIN32( ERROR_FILE_TOO_LARGE ); #endif IWICImagingFactory* pWIC = _GetWIC(); if ( !pWIC ) return E_NOINTERFACE; // Create input stream for memory ComPtr stream; HRESULT hr = pWIC->CreateStream( stream.GetAddressOf() ); if ( FAILED(hr) ) return hr; hr = stream->InitializeFromMemory( const_cast( wicData ), static_cast( wicDataSize ) ); if ( FAILED(hr) ) return hr; // Initialize WIC ComPtr decoder; hr = pWIC->CreateDecoderFromStream( stream.Get(), 0, WICDecodeMetadataCacheOnDemand, decoder.GetAddressOf() ); if ( FAILED(hr) ) return hr; ComPtr frame; hr = decoder->GetFrame( 0, frame.GetAddressOf() ); if ( FAILED(hr) ) return hr; hr = CreateTextureFromWIC( d3dDevice, d3dContext, frame.Get(), maxsize, usage, bindFlags, cpuAccessFlags, miscFlags, forceSRGB, texture, textureView ); if ( FAILED(hr)) return hr; if (texture != 0 && *texture != 0) { SetDebugObjectName(*texture, "WICTextureLoader"); } if (textureView != 0 && *textureView != 0) { SetDebugObjectName(*textureView, "WICTextureLoader"); } return hr; } //-------------------------------------------------------------------------------------- _Use_decl_annotations_ HRESULT DirectX::CreateWICTextureFromFile( ID3D11Device* d3dDevice, const wchar_t* fileName, ID3D11Resource** texture, ID3D11ShaderResourceView** textureView, size_t maxsize ) { return CreateWICTextureFromFileEx( d3dDevice, nullptr, fileName, maxsize, D3D11_USAGE_DEFAULT, D3D11_BIND_SHADER_RESOURCE, 0, 0, false, texture, textureView ); } _Use_decl_annotations_ HRESULT DirectX::CreateWICTextureFromFile( ID3D11Device* d3dDevice, ID3D11DeviceContext* d3dContext, const wchar_t* fileName, ID3D11Resource** texture, ID3D11ShaderResourceView** textureView, size_t maxsize ) { return CreateWICTextureFromFileEx( d3dDevice, d3dContext, fileName, maxsize, D3D11_USAGE_DEFAULT, D3D11_BIND_SHADER_RESOURCE, 0, 0, false, texture, textureView ); } _Use_decl_annotations_ HRESULT DirectX::CreateWICTextureFromFileEx( ID3D11Device* d3dDevice, const wchar_t* fileName, size_t maxsize, D3D11_USAGE usage, unsigned int bindFlags, unsigned int cpuAccessFlags, unsigned int miscFlags, bool forceSRGB, ID3D11Resource** texture, ID3D11ShaderResourceView** textureView ) { return CreateWICTextureFromFileEx( d3dDevice, nullptr, fileName, maxsize, usage, bindFlags, cpuAccessFlags, miscFlags, forceSRGB, texture, textureView ); } _Use_decl_annotations_ HRESULT DirectX::CreateWICTextureFromFileEx( ID3D11Device* d3dDevice, ID3D11DeviceContext* d3dContext, const wchar_t* fileName, size_t maxsize, D3D11_USAGE usage, unsigned int bindFlags, unsigned int cpuAccessFlags, unsigned int miscFlags, bool forceSRGB, ID3D11Resource** texture, ID3D11ShaderResourceView** textureView ) { if ( texture ) { *texture = nullptr; } if ( textureView ) { *textureView = nullptr; } if (!d3dDevice || !fileName || (!texture && !textureView)) return E_INVALIDARG; IWICImagingFactory* pWIC = _GetWIC(); if ( !pWIC ) return E_NOINTERFACE; // Initialize WIC ComPtr decoder; HRESULT hr = pWIC->CreateDecoderFromFilename( fileName, 0, GENERIC_READ, WICDecodeMetadataCacheOnDemand, decoder.GetAddressOf() ); if ( FAILED(hr) ) return hr; ComPtr frame; hr = decoder->GetFrame( 0, frame.GetAddressOf() ); if ( FAILED(hr) ) return hr; hr = CreateTextureFromWIC( d3dDevice, d3dContext, frame.Get(), maxsize, usage, bindFlags, cpuAccessFlags, miscFlags, forceSRGB, texture, textureView ); #if !defined(NO_D3D11_DEBUG_NAME) && ( defined(_DEBUG) || defined(PROFILE) ) if ( SUCCEEDED(hr) ) { if (texture != 0 || textureView != 0) { CHAR strFileA[MAX_PATH]; int result = WideCharToMultiByte( CP_ACP, WC_NO_BEST_FIT_CHARS, fileName, -1, strFileA, MAX_PATH, nullptr, FALSE ); if ( result > 0 ) { const CHAR* pstrName = strrchr( strFileA, '\\' ); if (!pstrName) { pstrName = strFileA; } else { pstrName++; } if (texture != 0 && *texture != 0) { (*texture)->SetPrivateData( WKPDID_D3DDebugObjectName, static_cast( strnlen_s(pstrName, MAX_PATH) ), pstrName ); } if (textureView != 0 && *textureView != 0 ) { (*textureView)->SetPrivateData( WKPDID_D3DDebugObjectName, static_cast( strnlen_s(pstrName, MAX_PATH) ), pstrName ); } } } } #endif return hr; } ================================================ FILE: 3rdParty/DirectXTex/WICTextureLoader/WICTextureLoader.h ================================================ //-------------------------------------------------------------------------------------- // File: WICTextureLoader.h // // Function for loading a WIC image and creating a Direct3D 11 runtime texture for it // (auto-generating mipmaps if possible) // // Note: Assumes application has already called CoInitializeEx // // Warning: CreateWICTexture* functions are not thread-safe if given a d3dContext instance for // auto-gen mipmap support. // // Note these functions are useful for images created as simple 2D textures. For // more complex resources, DDSTextureLoader is an excellent light-weight runtime loader. // For a full-featured DDS file reader, writer, and texture processing pipeline see // the 'Texconv' sample and the 'DirectXTex' library. // // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A // PARTICULAR PURPOSE. // // Copyright (c) Microsoft Corporation. All rights reserved. // // http://go.microsoft.com/fwlink/?LinkId=248926 // http://go.microsoft.com/fwlink/?LinkId=248929 //-------------------------------------------------------------------------------------- #ifdef _MSC_VER #pragma once #endif #if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) && (_WIN32_WINNT <= _WIN32_WINNT_WIN8) #error WIC is not supported on Windows Phone 8.0 #endif #include #pragma warning(push) #pragma warning(disable : 4005) #include #pragma warning(pop) #if defined(_MSC_VER) && (_MSC_VER<1610) && !defined(_In_reads_) #define _In_reads_(exp) #define _Out_writes_(exp) #define _In_reads_bytes_(exp) #endif #ifndef _Use_decl_annotations_ #define _Use_decl_annotations_ #endif namespace DirectX { // Standard version HRESULT CreateWICTextureFromMemory( _In_ ID3D11Device* d3dDevice, _In_reads_bytes_(wicDataSize) const uint8_t* wicData, _In_ size_t wicDataSize, _Out_opt_ ID3D11Resource** texture, _Out_opt_ ID3D11ShaderResourceView** textureView, _In_ size_t maxsize = 0 ); HRESULT CreateWICTextureFromFile( _In_ ID3D11Device* d3dDevice, _In_z_ const wchar_t* szFileName, _Out_opt_ ID3D11Resource** texture, _Out_opt_ ID3D11ShaderResourceView** textureView, _In_ size_t maxsize = 0 ); // Standard version with optional auto-gen mipmap support HRESULT CreateWICTextureFromMemory( _In_ ID3D11Device* d3dDevice, _In_opt_ ID3D11DeviceContext* d3dContext, _In_reads_bytes_(wicDataSize) const uint8_t* wicData, _In_ size_t wicDataSize, _Out_opt_ ID3D11Resource** texture, _Out_opt_ ID3D11ShaderResourceView** textureView, _In_ size_t maxsize = 0 ); HRESULT CreateWICTextureFromFile( _In_ ID3D11Device* d3dDevice, _In_opt_ ID3D11DeviceContext* d3dContext, _In_z_ const wchar_t* szFileName, _Out_opt_ ID3D11Resource** texture, _Out_opt_ ID3D11ShaderResourceView** textureView, _In_ size_t maxsize = 0 ); // Extended version HRESULT CreateWICTextureFromMemoryEx( _In_ ID3D11Device* d3dDevice, _In_reads_bytes_(wicDataSize) const uint8_t* wicData, _In_ size_t wicDataSize, _In_ size_t maxsize, _In_ D3D11_USAGE usage, _In_ unsigned int bindFlags, _In_ unsigned int cpuAccessFlags, _In_ unsigned int miscFlags, _In_ bool forceSRGB, _Out_opt_ ID3D11Resource** texture, _Out_opt_ ID3D11ShaderResourceView** textureView ); HRESULT CreateWICTextureFromFileEx( _In_ ID3D11Device* d3dDevice, _In_z_ const wchar_t* szFileName, _In_ size_t maxsize, _In_ D3D11_USAGE usage, _In_ unsigned int bindFlags, _In_ unsigned int cpuAccessFlags, _In_ unsigned int miscFlags, _In_ bool forceSRGB, _Out_opt_ ID3D11Resource** texture, _Out_opt_ ID3D11ShaderResourceView** textureView ); // Extended version with optional auto-gen mipmap support HRESULT CreateWICTextureFromMemoryEx( _In_ ID3D11Device* d3dDevice, _In_opt_ ID3D11DeviceContext* d3dContext, _In_reads_bytes_(wicDataSize) const uint8_t* wicData, _In_ size_t wicDataSize, _In_ size_t maxsize, _In_ D3D11_USAGE usage, _In_ unsigned int bindFlags, _In_ unsigned int cpuAccessFlags, _In_ unsigned int miscFlags, _In_ bool forceSRGB, _Out_opt_ ID3D11Resource** texture, _Out_opt_ ID3D11ShaderResourceView** textureView ); HRESULT CreateWICTextureFromFileEx( _In_ ID3D11Device* d3dDevice, _In_opt_ ID3D11DeviceContext* d3dContext, _In_z_ const wchar_t* szFileName, _In_ size_t maxsize, _In_ D3D11_USAGE usage, _In_ unsigned int bindFlags, _In_ unsigned int cpuAccessFlags, _In_ unsigned int miscFlags, _In_ bool forceSRGB, _Out_opt_ ID3D11Resource** texture, _Out_opt_ ID3D11ShaderResourceView** textureView ); } ================================================ FILE: 3rdParty/Intel/Source/StopWatch.cpp ================================================ //////////////////////////////////////////////////////////////////////////////// // Copyright 2017 Intel Corporation // // Licensed under the Apache License, Version 2.0 (the "License"); you may not // use this file except in compliance with the License. You may obtain a copy // of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the // License for the specific language governing permissions and limitations // under the License. //////////////////////////////////////////////////////////////////////////////// #include "StopWatch.h" #include // Initialize member variables. StopWatch::StopWatch() : frequency(0), start(0), stop(0), affinityMask(0) { // Initialize the performance counter frequency. LARGE_INTEGER perfQuery; BOOL supported = QueryPerformanceFrequency(&perfQuery); assert(supported == TRUE); this->frequency = perfQuery.QuadPart; } // Start the stopwatch. void StopWatch::Start() { // MSDN recommends setting the thread affinity to avoid bugs in the BIOS and HAL. // Create an affinity mask for the current processor. affinityMask = (DWORD_PTR)1 << GetCurrentProcessorNumber(); HANDLE currThread = GetCurrentThread(); DWORD_PTR prevAffinityMask = SetThreadAffinityMask(currThread, affinityMask); assert(prevAffinityMask != 0); // Query the performance counter. LARGE_INTEGER perfQuery; BOOL result = QueryPerformanceCounter(&perfQuery); assert(result); start = perfQuery.QuadPart; // Restore the thread's affinity mask. prevAffinityMask = SetThreadAffinityMask(currThread, prevAffinityMask); assert(prevAffinityMask != 0); } // Stop the stopwatch. void StopWatch::Stop() { // MSDN recommends setting the thread affinity to avoid bugs in the BIOS and HAL. // Use the affinity mask that was created in the Start function. HANDLE currThread = GetCurrentThread(); DWORD_PTR prevAffinityMask = SetThreadAffinityMask(currThread, affinityMask); assert(prevAffinityMask != 0); // Query the performance counter. LARGE_INTEGER perfQuery; BOOL result = QueryPerformanceCounter(&perfQuery); assert(result); stop = perfQuery.QuadPart; // Restore the thread's affinity mask. prevAffinityMask = SetThreadAffinityMask(currThread, prevAffinityMask); assert(prevAffinityMask != 0); } // Reset the stopwatch. void StopWatch::Reset() { start = 0; stop = 0; affinityMask = 0; } // Get the elapsed time in seconds. double StopWatch::TimeInSeconds() const { // Return the elapsed time in seconds. assert((stop - start) > 0); return double(stop - start) / double(frequency); } // Get the elapsed time in milliseconds. double StopWatch::TimeInMilliseconds() const { // Return the elapsed time in milliseconds. assert((stop - start) > 0); return double(stop - start) / double(frequency) * 1000.0; } // Get the elapsed time in microseconds. double StopWatch::TimeInMicroseconds() const { // Return the elapsed time in microseconds. assert((stop - start) > 0); return double(stop - start) / double(frequency) * 1000000.0; } ================================================ FILE: 3rdParty/Intel/Source/StopWatch.h ================================================ //////////////////////////////////////////////////////////////////////////////// // Copyright 2017 Intel Corporation // // Licensed under the Apache License, Version 2.0 (the "License"); you may not // use this file except in compliance with the License. You may obtain a copy // of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the // License for the specific language governing permissions and limitations // under the License. //////////////////////////////////////////////////////////////////////////////// #pragma once #include "Windows.h" // A simple stopwatch class using Windows' high-resolution performance counters. class StopWatch { public: StopWatch(); void Start(); void Stop(); void Reset(); double TimeInSeconds() const; double TimeInMilliseconds() const; double TimeInMicroseconds() const; private: LONGLONG frequency; LONGLONG start; LONGLONG stop; DWORD_PTR affinityMask; }; ================================================ FILE: 3rdParty/Intel/Source/ispc_texcomp.cpp ================================================ //////////////////////////////////////////////////////////////////////////////// // Copyright 2017 Intel Corporation // // Licensed under the Apache License, Version 2.0 (the "License"); you may not // use this file except in compliance with the License. You may obtain a copy // of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the // License for the specific language governing permissions and limitations // under the License. //////////////////////////////////////////////////////////////////////////////// #include "ispc_texcomp.h" #include "kernel_ispc.h" void GetProfile_ultrafast(bc7_enc_settings* settings) { settings->channels = 3; // mode02 settings->mode_selection[0] = false; settings->skip_mode2 = true; settings->refineIterations[0] = 2; settings->refineIterations[2] = 2; // mode13 settings->mode_selection[1] = false; settings->fastSkipTreshold_mode1 = 3; settings->fastSkipTreshold_mode3 = 1; settings->fastSkipTreshold_mode7 = 0; settings->refineIterations[1] = 2; settings->refineIterations[3] = 1; // mode45 settings->mode_selection[2] = false; settings->mode45_channel0 = 0; settings->refineIterations_channel = 0; settings->refineIterations[4] = 2; settings->refineIterations[5] = 2; // mode6 settings->mode_selection[3] = true; settings->refineIterations[6] = 1; } void GetProfile_veryfast(bc7_enc_settings* settings) { settings->channels = 3; // mode02 settings->mode_selection[0] = false; settings->skip_mode2 = true; settings->refineIterations[0] = 2; settings->refineIterations[2] = 2; // mode13 settings->mode_selection[1] = true; settings->fastSkipTreshold_mode1 = 3; settings->fastSkipTreshold_mode3 = 1; settings->fastSkipTreshold_mode7 = 0; settings->refineIterations[1] = 2; settings->refineIterations[3] = 1; // mode45 settings->mode_selection[2] = false; settings->mode45_channel0 = 0; settings->refineIterations_channel = 0; settings->refineIterations[4] = 2; settings->refineIterations[5] = 2; // mode6 settings->mode_selection[3] = true; settings->refineIterations[6] = 1; } void GetProfile_fast(bc7_enc_settings* settings) { settings->channels = 3; // mode02 settings->mode_selection[0] = false; settings->skip_mode2 = true; settings->refineIterations[0] = 2; settings->refineIterations[2] = 2; // mode13 settings->mode_selection[1] = true; settings->fastSkipTreshold_mode1 = 12; settings->fastSkipTreshold_mode3 = 4; settings->fastSkipTreshold_mode7 = 0; settings->refineIterations[1] = 2; settings->refineIterations[3] = 1; // mode45 settings->mode_selection[2] = false; settings->mode45_channel0 = 0; settings->refineIterations_channel = 0; settings->refineIterations[4] = 2; settings->refineIterations[5] = 2; // mode6 settings->mode_selection[3] = true; settings->refineIterations[6] = 2; } void GetProfile_basic(bc7_enc_settings* settings) { settings->channels = 3; // mode02 settings->mode_selection[0] = true; settings->skip_mode2 = true; settings->refineIterations[0] = 2; settings->refineIterations[2] = 2; // mode13 settings->mode_selection[1] = true; settings->fastSkipTreshold_mode1 = 8+4; settings->fastSkipTreshold_mode3 = 8; settings->fastSkipTreshold_mode7 = 0; settings->refineIterations[1] = 2; settings->refineIterations[3] = 2; // mode45 settings->mode_selection[2] = true; settings->mode45_channel0 = 0; settings->refineIterations_channel = 2; settings->refineIterations[4] = 2; settings->refineIterations[5] = 2; // mode6 settings->mode_selection[3] = true; settings->refineIterations[6] = 2; } void GetProfile_slow(bc7_enc_settings* settings) { settings->channels = 3; int moreRefine = 2; // mode02 settings->mode_selection[0] = true; settings->skip_mode2 = false; settings->refineIterations[0] = 2+moreRefine; settings->refineIterations[2] = 2+moreRefine; // mode13 settings->mode_selection[1] = true; settings->fastSkipTreshold_mode1 = 64; settings->fastSkipTreshold_mode3 = 64; settings->fastSkipTreshold_mode7 = 0; settings->refineIterations[1] = 2+moreRefine; settings->refineIterations[3] = 2+moreRefine; // mode45 settings->mode_selection[2] = true; settings->mode45_channel0 = 0; settings->refineIterations_channel = 2+moreRefine; settings->refineIterations[4] = 2+moreRefine; settings->refineIterations[5] = 2+moreRefine; // mode6 settings->mode_selection[3] = true; settings->refineIterations[6] = 2+moreRefine; } void GetProfile_alpha_ultrafast(bc7_enc_settings* settings) { settings->channels = 4; // mode02 settings->mode_selection[0] = false; settings->skip_mode2 = true; settings->refineIterations[0] = 2; settings->refineIterations[2] = 2; // mode137 settings->mode_selection[1] = false; settings->fastSkipTreshold_mode1 = 0; settings->fastSkipTreshold_mode3 = 0; settings->fastSkipTreshold_mode7 = 4; settings->refineIterations[1] = 1; settings->refineIterations[3] = 1; settings->refineIterations[7] = 2; // mode45 settings->mode_selection[2] = true; settings->mode45_channel0 = 3; settings->refineIterations_channel = 1; settings->refineIterations[4] = 1; settings->refineIterations[5] = 1; // mode6 settings->mode_selection[3] = true; settings->refineIterations[6] = 2; } void GetProfile_alpha_veryfast(bc7_enc_settings* settings) { settings->channels = 4; // mode02 settings->mode_selection[0] = false; settings->skip_mode2 = true; settings->refineIterations[0] = 2; settings->refineIterations[2] = 2; // mode137 settings->mode_selection[1] = true; settings->fastSkipTreshold_mode1 = 0; settings->fastSkipTreshold_mode3 = 0; settings->fastSkipTreshold_mode7 = 4; settings->refineIterations[1] = 1; settings->refineIterations[3] = 1; settings->refineIterations[7] = 2; // mode45 settings->mode_selection[2] = true; settings->mode45_channel0 = 3; settings->refineIterations_channel = 2; settings->refineIterations[4] = 2; settings->refineIterations[5] = 2; // mode6 settings->mode_selection[3] = true; settings->refineIterations[6] = 2; } void GetProfile_alpha_fast(bc7_enc_settings* settings) { settings->channels = 4; // mode02 settings->mode_selection[0] = false; settings->skip_mode2 = true; settings->refineIterations[0] = 2; settings->refineIterations[2] = 2; // mode137 settings->mode_selection[1] = true; settings->fastSkipTreshold_mode1 = 4; settings->fastSkipTreshold_mode3 = 4; settings->fastSkipTreshold_mode7 = 8; settings->refineIterations[1] = 1; settings->refineIterations[3] = 1; settings->refineIterations[7] = 2; // mode45 settings->mode_selection[2] = true; settings->mode45_channel0 = 3; settings->refineIterations_channel = 2; settings->refineIterations[4] = 2; settings->refineIterations[5] = 2; // mode6 settings->mode_selection[3] = true; settings->refineIterations[6] = 2; } void GetProfile_alpha_basic(bc7_enc_settings* settings) { settings->channels = 4; // mode02 settings->mode_selection[0] = true; settings->skip_mode2 = true; settings->refineIterations[0] = 2; settings->refineIterations[2] = 2; // mode137 settings->mode_selection[1] = true; settings->fastSkipTreshold_mode1 = 8+4; settings->fastSkipTreshold_mode3 = 8; settings->fastSkipTreshold_mode7 = 8; settings->refineIterations[1] = 2; settings->refineIterations[3] = 2; settings->refineIterations[7] = 2; // mode45 settings->mode_selection[2] = true; settings->mode45_channel0 = 0; settings->refineIterations_channel = 2; settings->refineIterations[4] = 2; settings->refineIterations[5] = 2; // mode6 settings->mode_selection[3] = true; settings->refineIterations[6] = 2; } void GetProfile_alpha_slow(bc7_enc_settings* settings) { settings->channels = 4; int moreRefine = 2; // mode02 settings->mode_selection[0] = true; settings->skip_mode2 = false; settings->refineIterations[0] = 2+moreRefine; settings->refineIterations[2] = 2+moreRefine; // mode137 settings->mode_selection[1] = true; settings->fastSkipTreshold_mode1 = 64; settings->fastSkipTreshold_mode3 = 64; settings->fastSkipTreshold_mode7 = 64; settings->refineIterations[1] = 2+moreRefine; settings->refineIterations[3] = 2+moreRefine; settings->refineIterations[7] = 2+moreRefine; // mode45 settings->mode_selection[2] = true; settings->mode45_channel0 = 0; settings->refineIterations_channel = 2+moreRefine; settings->refineIterations[4] = 2+moreRefine; settings->refineIterations[5] = 2+moreRefine; // mode6 settings->mode_selection[3] = true; settings->refineIterations[6] = 2+moreRefine; } void GetProfile_bc6h_veryfast(bc6h_enc_settings* settings) { settings->slow_mode = false; settings->fast_mode = true; settings->fastSkipTreshold = 0; settings->refineIterations_1p = 0; settings->refineIterations_2p = 0; } void GetProfile_bc6h_fast(bc6h_enc_settings* settings) { settings->slow_mode = false; settings->fast_mode = true; settings->fastSkipTreshold = 2; settings->refineIterations_1p = 0; settings->refineIterations_2p = 1; } void GetProfile_bc6h_basic(bc6h_enc_settings* settings) { settings->slow_mode = false; settings->fast_mode = false; settings->fastSkipTreshold = 4; settings->refineIterations_1p = 2; settings->refineIterations_2p = 2; } void GetProfile_bc6h_slow(bc6h_enc_settings* settings) { settings->slow_mode = true; settings->fast_mode = false; settings->fastSkipTreshold = 10; settings->refineIterations_1p = 2; settings->refineIterations_2p = 2; } void GetProfile_bc6h_veryslow(bc6h_enc_settings* settings) { settings->slow_mode = true; settings->fast_mode = false; settings->fastSkipTreshold = 32; settings->refineIterations_1p = 2; settings->refineIterations_2p = 2; } void GetProfile_etc_slow(etc_enc_settings* settings) { settings->fastSkipTreshold = 6; } void CompressBlocksBC1(const rgba_surface* src, uint8_t* dst) { ispc::CompressBlocksBC1_ispc((ispc::rgba_surface*)src, dst); } void CompressBlocksBC3(const rgba_surface* src, uint8_t* dst) { ispc::CompressBlocksBC3_ispc((ispc::rgba_surface*)src, dst); } void CompressBlocksBC7(const rgba_surface* src, uint8_t* dst, bc7_enc_settings* settings) { ispc::CompressBlocksBC7_ispc((ispc::rgba_surface*)src, dst, (ispc::bc7_enc_settings*)settings); } void CompressBlocksBC6H(const rgba_surface* src, uint8_t* dst, bc6h_enc_settings* settings) { ispc::CompressBlocksBC6H_ispc((ispc::rgba_surface*)src, dst, (ispc::bc6h_enc_settings*)settings); } void CompressBlocksETC1(const rgba_surface* src, uint8_t* dst, etc_enc_settings* settings) { ispc::CompressBlocksETC1_ispc((ispc::rgba_surface*)src, dst, (ispc::etc_enc_settings*)settings); } ================================================ FILE: 3rdParty/Intel/Source/ispc_texcomp.h ================================================ //////////////////////////////////////////////////////////////////////////////// // Copyright 2017 Intel Corporation // // Licensed under the Apache License, Version 2.0 (the "License"); you may not // use this file except in compliance with the License. You may obtain a copy // of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the // License for the specific language governing permissions and limitations // under the License. //////////////////////////////////////////////////////////////////////////////// #include struct rgba_surface { uint8_t* ptr; int32_t width; int32_t height; int32_t stride; }; struct bc7_enc_settings { bool mode_selection[4]; int refineIterations[8]; bool skip_mode2; int fastSkipTreshold_mode1; int fastSkipTreshold_mode3; int fastSkipTreshold_mode7; int mode45_channel0; int refineIterations_channel; int channels; }; struct bc6h_enc_settings { bool slow_mode; bool fast_mode; int refineIterations_1p; int refineIterations_2p; int fastSkipTreshold; }; struct etc_enc_settings { int fastSkipTreshold; }; struct astc_enc_settings { int block_width; int block_height; int fastSkipTreshold; int refineIterations; }; // profiles for RGB data (alpha channel will be ignored) extern "C" void GetProfile_ultrafast(bc7_enc_settings* settings); extern "C" void GetProfile_veryfast(bc7_enc_settings* settings); extern "C" void GetProfile_fast(bc7_enc_settings* settings); extern "C" void GetProfile_basic(bc7_enc_settings* settings); extern "C" void GetProfile_slow(bc7_enc_settings* settings); // profiles for RGBA inputs extern "C" void GetProfile_alpha_ultrafast(bc7_enc_settings* settings); extern "C" void GetProfile_alpha_veryfast(bc7_enc_settings* settings); extern "C" void GetProfile_alpha_fast(bc7_enc_settings* settings); extern "C" void GetProfile_alpha_basic(bc7_enc_settings* settings); extern "C" void GetProfile_alpha_slow(bc7_enc_settings* settings); // profiles for BC6H (RGB HDR) extern "C" void GetProfile_bc6h_veryfast(bc6h_enc_settings* settings); extern "C" void GetProfile_bc6h_fast(bc6h_enc_settings* settings); extern "C" void GetProfile_bc6h_basic(bc6h_enc_settings* settings); extern "C" void GetProfile_bc6h_slow(bc6h_enc_settings* settings); extern "C" void GetProfile_bc6h_veryslow(bc6h_enc_settings* settings); // profiles for ETC extern "C" void GetProfile_etc_slow(etc_enc_settings* settings); // profiles for ASTC extern "C" void GetProfile_astc_fast(astc_enc_settings* settings, int block_width, int block_height); /* Notes: - input width and height need to be a multiple of block size - LDR input is 32 bit/pixel (sRGB), HDR is 64 bit/pixel (half float) - dst buffer must be allocated with enough space for the compressed texture: 4 bytes/block for BC1/ETC1, 8 bytes/block for BC3/BC6H/BC7/ASTC the blocks are stored in raster scan order (natural CPU texture layout) - you can use GetProfile_* functions to select various speed/quality tradeoffs. - the RGB profiles are slightly faster as they ignore the alpha channel */ extern "C" void CompressBlocksBC1(const rgba_surface* src, uint8_t* dst); extern "C" void CompressBlocksBC3(const rgba_surface* src, uint8_t* dst); extern "C" void CompressBlocksBC6H(const rgba_surface* src, uint8_t* dst, bc6h_enc_settings* settings); extern "C" void CompressBlocksBC7(const rgba_surface* src, uint8_t* dst, bc7_enc_settings* settings); extern "C" void CompressBlocksETC1(const rgba_surface* src, uint8_t* dst, etc_enc_settings* settings); extern "C" void CompressBlocksASTC(const rgba_surface* src, uint8_t* dst, astc_enc_settings* settings); ================================================ FILE: 3rdParty/Intel/Source/win32Threads.cpp ================================================ //////////////////////////////////////////////////////////////////////////////// // Copyright 2017 Intel Corporation // // Licensed under the Apache License, Version 2.0 (the "License"); you may not // use this file except in compliance with the License. You may obtain a copy // of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the // License for the specific language governing permissions and limitations // under the License. //////////////////////////////////////////////////////////////////////////////// #include #include #include /* assert */ #include "win32Threads.h" #include // Win32 thread API const int kMaxWinThreads = 64; WinThreadData gWinThreadData[kMaxWinThreads]; HANDLE gWinThreadWorkEvent[kMaxWinThreads]; HANDLE gWinThreadStartEvent = NULL; HANDLE gWinThreadDoneEvent = NULL; int gNumWinThreads = 0; DWORD dwThreadIdArray[kMaxWinThreads]; HANDLE hThreadArray[kMaxWinThreads]; #define CHECK_WIN_THREAD_FUNC(x) \ do { \ if(NULL == (x)) { \ wchar_t wstr[256]; \ swprintf_s(wstr, L"Error detected from call %s at line %d of main.cpp", _T(#x), __LINE__); \ ReportWinThreadError(wstr); \ } \ } \ while(0) DWORD WINAPI CompressImageMT_Thread( LPVOID lpParam ); void ReportWinThreadError(const wchar_t *str) { // Retrieve the system error message for the last-error code. LPVOID lpMsgBuf; LPVOID lpDisplayBuf; DWORD dw = GetLastError(); FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL ); // Display the error message. lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, (lstrlen((LPCTSTR) lpMsgBuf) + lstrlen((LPCTSTR)str) + 40) * sizeof(TCHAR)); StringCchPrintf((LPTSTR)lpDisplayBuf, LocalSize(lpDisplayBuf) / sizeof(TCHAR), TEXT("%s failed with error %d: %s"), str, dw, lpMsgBuf); MessageBox(NULL, (LPCTSTR) lpDisplayBuf, TEXT("Error"), MB_OK); // Free error-handling buffer allocations. LocalFree(lpMsgBuf); LocalFree(lpDisplayBuf); } // Figure out how many cores there are on this machine int GetProcessorCount() { static int sProcessorCount; if (sProcessorCount == 0) { SYSTEM_INFO sysinfo = {}; GetSystemInfo(&sysinfo); sProcessorCount = sysinfo.dwNumberOfProcessors; if (sProcessorCount < 1) sProcessorCount = 1; } return sProcessorCount; } void InitWin32Threads() { // Already initialized? if(gNumWinThreads > 0) { return; } SetLastError(0); gNumWinThreads = GetProcessorCount(); if(gNumWinThreads >= MAXIMUM_WAIT_OBJECTS) gNumWinThreads = MAXIMUM_WAIT_OBJECTS; assert(gNumWinThreads <= kMaxWinThreads); // Create the synchronization events. for(int i = 0; i < gNumWinThreads; i++) { CHECK_WIN_THREAD_FUNC(gWinThreadWorkEvent[i] = CreateEvent(NULL, FALSE, FALSE, NULL)); } CHECK_WIN_THREAD_FUNC(gWinThreadStartEvent = CreateEvent(NULL, TRUE, FALSE, NULL)); CHECK_WIN_THREAD_FUNC(gWinThreadDoneEvent = CreateEvent(NULL, TRUE, FALSE, NULL)); // Create threads for(int threadIdx = 0; threadIdx < gNumWinThreads; threadIdx++) { gWinThreadData[threadIdx].state = eThreadState_WaitForData; CHECK_WIN_THREAD_FUNC(hThreadArray[threadIdx] = CreateThread(NULL, 0, CompressImageMT_Thread, &gWinThreadData[threadIdx], 0, &dwThreadIdArray[threadIdx])); } } void DestroyThreads() { //if(gMultithreaded) //{ // Release all windows threads that may be active... for(int i=0; i < gNumWinThreads; i++) { gWinThreadData[i].state = eThreadState_Done; } // Send the event for the threads to start. CHECK_WIN_THREAD_FUNC(ResetEvent(gWinThreadDoneEvent)); CHECK_WIN_THREAD_FUNC(SetEvent(gWinThreadStartEvent)); // Wait for all the threads to finish.... DWORD dwWaitRet = WaitForMultipleObjects(gNumWinThreads, hThreadArray, TRUE, INFINITE); if(WAIT_FAILED == dwWaitRet) ReportWinThreadError(L"DestroyThreads() -- WaitForMultipleObjects"); // !HACK! This doesn't actually do anything. There is either a bug in the // Intel compiler or the windows run-time that causes the threads to not // be cleaned up properly if the following two lines of code are not present. // Since we're passing INFINITE to WaitForMultipleObjects, that function will // never time out and per-microsoft spec, should never give this return value... // Even with these lines, the bug does not consistently disappear unless you // clean and rebuild. Heigenbug? // // If we compile with MSVC, then the following two lines are not necessary. else if(WAIT_TIMEOUT == dwWaitRet) OutputDebugString("DestroyThreads() -- WaitForMultipleObjects -- TIMEOUT"); // Reset the start event CHECK_WIN_THREAD_FUNC(ResetEvent(gWinThreadStartEvent)); CHECK_WIN_THREAD_FUNC(SetEvent(gWinThreadDoneEvent)); // Close all thread handles. for(int i=0; i < gNumWinThreads; i++) { CHECK_WIN_THREAD_FUNC(CloseHandle(hThreadArray[i])); } for(int i =0; i < kMaxWinThreads; i++ ){ hThreadArray[i] = NULL; } // Close all event handles... CHECK_WIN_THREAD_FUNC(CloseHandle(gWinThreadDoneEvent)); gWinThreadDoneEvent = NULL; CHECK_WIN_THREAD_FUNC(CloseHandle(gWinThreadStartEvent)); gWinThreadStartEvent = NULL; for(int i = 0; i < gNumWinThreads; i++) { CHECK_WIN_THREAD_FUNC(CloseHandle(gWinThreadWorkEvent[i])); } for(int i = 0; i < kMaxWinThreads; i++) { gWinThreadWorkEvent[i] = NULL; } gNumWinThreads = 0; //} } int GetBytesPerBlock(DXGI_FORMAT format) { switch(format) { default: case DXGI_FORMAT_BC1_UNORM_SRGB: case DXGI_FORMAT_BC1_UNORM: return 8; case DXGI_FORMAT_BC3_UNORM_SRGB: case DXGI_FORMAT_BC3_UNORM: case DXGI_FORMAT_BC7_UNORM_SRGB: case DXGI_FORMAT_BC7_UNORM: case DXGI_FORMAT_BC6H_UF16: case DXGI_FORMAT_BC6H_SF16: return 16; } } bool CompressImageMT(const rgba_surface* input, BYTE* output, CompressionFunc* cmpFunc, DXGI_FORMAT compformat) { const int numThreads = gNumWinThreads; const int bytesPerBlock = GetBytesPerBlock(compformat); // We want to split the data evenly among all threads. const int linesPerThread = (input->height + numThreads - 1) / numThreads; // Load the threads. for(int threadIdx = 0; threadIdx < numThreads; threadIdx++) { int y_start = (linesPerThread*threadIdx)/4*4; int y_end = (linesPerThread*(threadIdx+1))/4*4; if (y_end > input->height) y_end = input->height; WinThreadData *data = &gWinThreadData[threadIdx]; data->input = *input; data->input.ptr = input->ptr + y_start * input->stride; data->input.height = y_end-y_start; data->output = output + (y_start/4) * (input->width/4) * bytesPerBlock; data->state = eThreadState_DataLoaded; data->threadIdx = threadIdx; data->cmpFunc = cmpFunc; } // Send the event for the threads to start. CHECK_WIN_THREAD_FUNC(ResetEvent(gWinThreadDoneEvent)); CHECK_WIN_THREAD_FUNC(SetEvent(gWinThreadStartEvent)); // Wait for all the threads to finish if(WAIT_FAILED == WaitForMultipleObjects(numThreads, gWinThreadWorkEvent, TRUE, INFINITE)) ReportWinThreadError(L"CompressImageDXTWIN -- WaitForMultipleObjects"); // Reset the start event CHECK_WIN_THREAD_FUNC(ResetEvent(gWinThreadStartEvent)); CHECK_WIN_THREAD_FUNC(SetEvent(gWinThreadDoneEvent)); return true; } DWORD WINAPI CompressImageMT_Thread( LPVOID lpParam ) { WinThreadData *data = reinterpret_cast(lpParam); while(data->state != eThreadState_Done) { if(WAIT_FAILED == WaitForSingleObject(gWinThreadStartEvent, INFINITE)) ReportWinThreadError(L"CompressImageDXTWinThread -- WaitForSingleObject"); if(data->state == eThreadState_Done) break; data->state = eThreadState_Running; (*(data->cmpFunc))(&data->input, data->output); data->state = eThreadState_WaitForData; HANDLE workEvent = gWinThreadWorkEvent[data->threadIdx]; if(WAIT_FAILED == SignalObjectAndWait(workEvent, gWinThreadDoneEvent, INFINITE, FALSE)) ReportWinThreadError(L"CompressImageDXTWinThread -- SignalObjectAndWait"); } return 0; } bool CompressImageST(const rgba_surface* input, uint8_t* output, CompressionFunc* cmpFunc, DXGI_FORMAT compformat) { (*cmpFunc)(input, output); return true; } ///////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////// //CALL IN TO ISPC CODE void CompressImageBC1(const rgba_surface* input, BYTE* output) { CompressBlocksBC1(input, output); } void CompressImageBC3(const rgba_surface* input, BYTE* output) { CompressBlocksBC3(input, output); } #define DECLARE_CompressImageBC7_profile(profile) \ void CompressImageBC7_ ## profile(const rgba_surface* input, BYTE* output) \ { \ bc7_enc_settings settings; \ GetProfile_ ## profile(&settings); \ CompressBlocksBC7(input, output, &settings); \ } #define DECLARE_CompressImageBC6H_profile(profile) \ void CompressImageBC6H_ ## profile(const rgba_surface* input, BYTE* output) \ { \ bc6h_enc_settings settings; \ GetProfile_bc6h_ ## profile(&settings); \ CompressBlocksBC6H(input, output, &settings); \ } DECLARE_CompressImageBC6H_profile(veryfast); DECLARE_CompressImageBC6H_profile(fast); DECLARE_CompressImageBC6H_profile(basic); DECLARE_CompressImageBC6H_profile(slow); DECLARE_CompressImageBC6H_profile(veryslow); DECLARE_CompressImageBC7_profile(ultrafast); DECLARE_CompressImageBC7_profile(veryfast); DECLARE_CompressImageBC7_profile(fast); DECLARE_CompressImageBC7_profile(basic); DECLARE_CompressImageBC7_profile(slow); DECLARE_CompressImageBC7_profile(alpha_ultrafast); DECLARE_CompressImageBC7_profile(alpha_veryfast); DECLARE_CompressImageBC7_profile(alpha_fast); DECLARE_CompressImageBC7_profile(alpha_basic); DECLARE_CompressImageBC7_profile(alpha_slow); ================================================ FILE: 3rdParty/Intel/Source/win32Threads.h ================================================ //////////////////////////////////////////////////////////////////////////////// // Copyright 2017 Intel Corporation // // Licensed under the Apache License, Version 2.0 (the "License"); you may not // use this file except in compliance with the License. You may obtain a copy // of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the // License for the specific language governing permissions and limitations // under the License. //////////////////////////////////////////////////////////////////////////////// #pragma once #include #include #include "ispc_texcomp.h" typedef void (CompressionFunc)(const rgba_surface* input, BYTE* output); enum EThreadState { eThreadState_WaitForData, eThreadState_DataLoaded, eThreadState_Running, eThreadState_Done }; struct WinThreadData { EThreadState state; int threadIdx; CompressionFunc* cmpFunc; rgba_surface input; BYTE *output; // Defaults.. WinThreadData() : state(eThreadState_Done), threadIdx(-1), input(), output(NULL), cmpFunc(NULL) { } }; // Win32 thread API int GetProcessorCount(); // 1 or more void DestroyThreads(); void InitWin32Threads(); bool CompressImageMT(const rgba_surface* input, BYTE* output, CompressionFunc* cmpFunc, DXGI_FORMAT compformat); bool CompressImageST(const rgba_surface* input, uint8_t* output, CompressionFunc* cmpFunc, DXGI_FORMAT compformat); ///////////////////////////////////////////////////////////////////////////////////////////////////// //CALL IN TO ISPC CODE void CompressImageBC1(const rgba_surface* input, BYTE* output); void CompressImageBC3(const rgba_surface* input, BYTE* output); void CompressImageBC7_ultrafast(const rgba_surface* input, BYTE* output); void CompressImageBC7_veryfast(const rgba_surface* input, BYTE* output); void CompressImageBC7_fast(const rgba_surface* input, BYTE* output); void CompressImageBC7_basic(const rgba_surface* input, BYTE* output); void CompressImageBC7_slow(const rgba_surface* input, BYTE* output); void CompressImageBC7_alpha_ultrafast(const rgba_surface* input, BYTE* output); void CompressImageBC7_alpha_veryfast(const rgba_surface* input, BYTE* output); void CompressImageBC7_alpha_fast(const rgba_surface* input, BYTE* output); void CompressImageBC7_alpha_basic(const rgba_surface* input, BYTE* output); void CompressImageBC7_alpha_slow(const rgba_surface* input, BYTE* output); void CompressImageBC6H_veryfast(const rgba_surface* input, BYTE* output); void CompressImageBC6H_fast(const rgba_surface* input, BYTE* output); void CompressImageBC6H_basic(const rgba_surface* input, BYTE* output); void CompressImageBC6H_slow(const rgba_surface* input, BYTE* output); void CompressImageBC6H_veryslow(const rgba_surface* input, BYTE* output); ================================================ FILE: IntelCompressionPlugin/IntelPlugin.cpp ================================================ //////////////////////////////////////////////////////////////////////////////// // Copyright 2017 Intel Corporation // // Licensed under the Apache License, Version 2.0 (the "License"); you may not // use this file except in compliance with the License. You may obtain a copy // of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the // License for the specific language governing permissions and limitations // under the License. //////////////////////////////////////////////////////////////////////////////// #include "IntelPlugin.h" #include "IntelPluginUIWin.h" #include "SaveOptionsDialog.h" using namespace DirectX; // this global pointer is necessary to use code from PIUSuites.cpp SPBasicSuite * sSPBasic = NULL; IntelPlugin& IntelPlugin::GetInstance() { static IntelPlugin singleton; return singleton; } IntelPlugin::IntelPlugin(void) { memset(&ps, 0, sizeof(ps)); } IntelPlugin::~IntelPlugin(void) { } // =========================================================================== bool IntelPlugin::IsCombinationValid(TextureTypeEnum textype, CompressionTypeEnum comptype) { if (textype < TextureTypeEnum::TEXTURE_TYPE_COUNT && comptype < CompressionTypeEnum::COMPRESSION_TYPE_COUNT) { // --------------------------------------------------------------------------- //Matrix of which compression options make sense depending on the selected texture type //Rows are the TextureTypeEnum, and Columns the Compression types bool CompressionVsTextureTypeMatrix[][CompressionTypeEnum::COMPRESSION_TYPE_COUNT] = { // BC1, BC1_SRGB, BC3, BC3_SRGB, BC6H_FAST BC6H_FINE BC7_FAST BC7_FINE BC7_SRGB_FAST BC7_SRGB_FINE BC4 BC5 NONE {true, true, false, false, true, true, true, true, true, true, true, false, true}, //COLOR {false, false, true, true, false, false, true, true, true, true, false, false, true}, //COLOR+A {true, true, true, true, true, true, true, true, true, true, false, false, true}, //CUBEMAP+LAYER {true, true, true, true, true, true, true, true, true, true, false, false, true}, //CUBEMAP+CROSS {false, false, false, false, false, false, false, false, false, false, false, true, true}, //NORMAL MAP }; return CompressionVsTextureTypeMatrix[textype][comptype]; } return false; } /*****************************************************************************/ /*****************************************************************************/ //Cursor WAIT->ARROW convenince functions void IntelPlugin::showLoadingCursor() { ::SetCursor( LoadCursor( 0, IDC_WAIT ) ); } void IntelPlugin::showNormalCursor() { //Forces a WM_SETCURSOR message. POINT pt; // Screen coordinates! ::GetCursorPos(&pt); ::SetCursorPos( pt.x, pt.y ); } /*****************************************************************************/ /*****************************************************************************/ //Copy data from photoshop buffer into scrUncompressedImageScratch_ bool IntelPlugin::CopyDataForEncoding(ScratchImage *scrUncompressedImageScratch_, bool hasAlpha_, bool DoMipMaps_, bool gammaCorrect) { //Do advanceState to get image data, fill the ps.formatRecord->data buffer FetchImageData(); int planesToGet_ = ps.formatRecord->hiPlane - ps.formatRecord->loPlane + 1; if (ps.data->encoding_g == DXGI_FORMAT_BC6H_UF16) { //Allocate space for one rgba 16bit float image scrUncompressedImageScratch_->Initialize2D(DXGI_FORMAT_R16G16B16A16_FLOAT, ps.formatRecord->imageSize.h, ps.formatRecord->imageSize.v, 1, 1, DDS_FLAGS_NONE); //Get pointer to first (and only) image, cast to 16bit for BC6 unsigned16 *rowBigDataPtr = reinterpret_cast(scrUncompressedImageScratch_->GetImages()->pixels); //Copy data from photoshop buffer into scrUncompressedImageScratch //Convert pixels to 16Bit for BC6 encoding if (ps.formatRecord->depth == 8) { ConvertToBC6From8Bit(rowBigDataPtr, planesToGet_, hasAlpha_); } else if (ps.formatRecord->depth == 16) { ConvertToBC6From16Bit(rowBigDataPtr, planesToGet_, hasAlpha_); } else if (ps.formatRecord->depth == 32) { ConvertToBC6From32Bit(rowBigDataPtr, planesToGet_, hasAlpha_); } else { return false; } } else if (ps.data->encoding_g == DXGI_FORMAT_BC4_UNORM || ps.data->encoding_g == DXGI_FORMAT_BC5_UNORM) { //Allocate space for one rgba 8bit image scrUncompressedImageScratch_->Initialize2D(DXGI_FORMAT_R8G8B8A8_UNORM, ps.formatRecord->imageSize.h, ps.formatRecord->imageSize.v, 1, 1, DDS_FLAGS_NONE); //Get pointer to first (and only) image unsigned8 *rowBigDataPtr = scrUncompressedImageScratch_->GetImages()->pixels; //Copy data from photoshop buffer into scrUncompressedImageScratch //Convert pixels to 8bit for BC4/5 encoding if (ps.formatRecord->depth == 8) { ConvertToBC4or5From8Bit(rowBigDataPtr, planesToGet_, hasAlpha_); } else if (ps.formatRecord->depth == 16) { ConvertToBC4or5From16Bit(rowBigDataPtr, planesToGet_, hasAlpha_); } else if (ps.formatRecord->depth == 32) { ConvertToBC4or5From32Bit(rowBigDataPtr, planesToGet_, hasAlpha_, gammaCorrect); } else { return false; } } else //BC1,3,7 or uncompressed { //Allocate space for one rgba 8bit image scrUncompressedImageScratch_->Initialize2D(DXGI_FORMAT_R8G8B8A8_UNORM, ps.formatRecord->imageSize.h, ps.formatRecord->imageSize.v, 1, 1, DDS_FLAGS_NONE); //If SRGB encoding, force Scratch image to SRGB format. So that the MipMap generation is done correctly for RGB images if (IsSRGB(ps.data->encoding_g) && DoMipMaps_) scrUncompressedImageScratch_->OverrideFormat(DXGI_FORMAT_R8G8B8A8_UNORM_SRGB); //Get pointer to first (and only) image unsigned8 *rowBigDataPtr = scrUncompressedImageScratch_->GetImages()->pixels; //Copy data from photoshop buffer into scrUncompressedImageScratch //Convert pixels to 8bit for BC encoding if (ps.formatRecord->depth == 8) { ConvertToBCFrom8Bit(rowBigDataPtr, planesToGet_, hasAlpha_); } else if (ps.formatRecord->depth == 16) { ConvertToBCFrom16Bit(rowBigDataPtr, planesToGet_, hasAlpha_); } else if (ps.formatRecord->depth == 32) { ConvertToBCFrom32Bit(rowBigDataPtr, planesToGet_, hasAlpha_, gammaCorrect); } else { return false; } } return true; } /*****************************************************************************/ /*****************************************************************************/ //Take an Uncompressed ScratchImage scrUncompressedImageScratch_ and Compresses it into scrImageScratch_ bool IntelPlugin::CompressToScratchImage(ScratchImage **scrImageScratch_, ScratchImage **scrUncompressedImageScratch_, bool hasAlpha_) { //============================================================================================ //============================================================================================ //Compress image, section //ISPC is used for BC1,3,6,7. BC4,5 is done using DirectXTex Lib in one of the previous sections if (ps.data->encoding_g != DXGI_FORMAT_BC4_UNORM && ps.data->encoding_g != DXGI_FORMAT_BC5_UNORM && ps.data->encoding_g !=DXGI_FORMAT_R8G8B8A8_UNORM) { //How many mip levels are generated? If no mip map override this is 1 so that only one image is encoded size_t mipLevels = (*scrUncompressedImageScratch_)->GetMetadata().mipLevels; //Allocate space for Image + mip chain, according to what the uncompressed image size/miplevel //Check if cubemap or not (a cubemap has an arraysize of six) if ((*scrUncompressedImageScratch_)->GetMetadata().arraySize == 6) { //Image is a CubeMap (*scrImageScratch_)->InitializeCube(ps.data->encoding_g, (*scrUncompressedImageScratch_)->GetMetadata().width, (*scrUncompressedImageScratch_)->GetMetadata().height, 1, mipLevels); } else { //Image is a 2D texture (*scrImageScratch_)->Initialize2D(ps.data->encoding_g, (*scrUncompressedImageScratch_)->GetMetadata().width, (*scrUncompressedImageScratch_)->GetMetadata().height, 1, mipLevels, DDS_FLAGS_NONE); } //Get pointer to image chains for compressed and uncompressed scratchImage const Image* imgCompressed = (*scrImageScratch_)->GetImages(); const Image* imgUnCompressedMipMap = (*scrUncompressedImageScratch_)->GetImages(); //Number of total images (Image1+MipChain), (Image2+MipChain), ..... (Multiple Images image array only in case of Cube Maps) size_t nimgCompressed = (*scrImageScratch_)->GetImageCount(); if (nimgCompressed == 0) { UserError("Can not allocate compressed image"); return false; } //StopWatch stopWatch; //stopWatch.Reset(); //stopWatch.Start(); //ISPC is used on for BC1,3,6,7. //Iterate over the whole image chain (Image+MipChain) for (size_t allImagesIndex = 0; allImagesIndex < nimgCompressed; allImagesIndex++) { //Fill in the struct needed by Intel ispc code with the uncompressed image rgba_surface input; //Get pointer to this image in the chain const Image* rgbaimg = &imgUnCompressedMipMap[allImagesIndex]; input.height = int32_t(rgbaimg->height); input.width = int32_t(rgbaimg->width); input.ptr = rgbaimg->pixels; //buffer in unsigned8* format input.stride = int32_t(rgbaimg->rowPitch); //number of bytes of a row //Determine if the image size is not multiples of 4. //In that case it needs padding when encoding bool DoPadding = ((input.height | input.width) & 0x3) != 0; //If it needs padding, process it if (DoPadding) input = DoPaddingToMultiplesOf4(input); //Call in ISPC compression functions, output compressed image into imgCompressed[allImagesIndex] ISPC_compression(input, imgCompressed[allImagesIndex], hasAlpha_); //If padding free buffer that got allocated if (DoPadding) delete [] input.ptr; } //stopWatch.Stop(); //std::stringstream ss; //ss << stopWatch.TimeInMilliseconds(); //errorMessage(ss.str(),"Time"); } else if (ps.data->encoding_g == DXGI_FORMAT_R8G8B8A8_UNORM) { //Uncompressed do nothing, just swap pointers and free space delete *scrImageScratch_; *scrImageScratch_ = *scrUncompressedImageScratch_; *scrUncompressedImageScratch_ = NULL; } else { //Compress into srcImageScratch using the DirectXTex BC4,5 routines HRESULT hr = Compress((*scrUncompressedImageScratch_)->GetImages(), (*scrUncompressedImageScratch_)->GetImageCount(), (*scrUncompressedImageScratch_)->GetMetadata(), ps.data->encoding_g, TEX_COMPRESS_DEFAULT, 0.5f, **scrImageScratch_); if (hr != S_OK) { if (ps.data->encoding_g == DXGI_FORMAT_BC4_UNORM) UserError("Could not compress to BC4"); else UserError("Could not compress to BC5"); return false; } } return true; } /*****************************************************************************/ /*****************************************************************************/ //Conversion functions from Photoshop buffer to 8bit/16bit ready encoding buffer bool IntelPlugin::ConvertToBC6From8Bit(unsigned16 *tgtDataPtr, int planesToGet, bool hasAlphaChannel) { if (ps.formatRecord->depth != 8) return false; //Get image pointer unsigned8 *rowData = static_cast(ps.formatRecord->data); //Copy image into RGBA buffer, alpha is not copied for now for (int height=0; height< ps.formatRecord->imageSize.v; height++) for (int width=0; width< ps.formatRecord->imageSize.h; width++) { int index = height*ps.formatRecord->imageSize.h*planesToGet + width*planesToGet; //We assign black to other channels if photoshop does not provide enough channels, as the compressed image must be RGBA tgtDataPtr[0] = ConvertTo16Bit(rowData[index]); tgtDataPtr[1] = (planesToGet > 1)? ConvertTo16Bit(rowData[index+1]) : 0; tgtDataPtr[2] = (planesToGet > 2)? ConvertTo16Bit(rowData[index+2]) : 0; //BC6 does not have alpha, but we copy it for preview. It will get discarded on compression tgtDataPtr[3] = hasAlphaChannel? ConvertTo16Bit(rowData[index+3]) : F32toF16(1.f); tgtDataPtr +=4; } return true; } bool IntelPlugin::ConvertToBC6From16Bit(unsigned16 *tgtDataPtr, int planesToGet, bool hasAlphaChannel) { if (ps.formatRecord->depth != 16) return false; unsigned16 *rowData16bit = static_cast(ps.formatRecord->data); //Copy image into RGBA buffer, alpha is not copied for now for (int height=0; height< ps.formatRecord->imageSize.v; height++) for (int width=0; width< ps.formatRecord->imageSize.h; width++) { int index = height*ps.formatRecord->imageSize.h*planesToGet + width*planesToGet; //We assign black to other channels if photoshop does not provide enough channels, as the compressed text must be RGBA tgtDataPtr[0] = ConvertTo16Bit(rowData16bit[index]); tgtDataPtr[1] = (planesToGet > 1)? ConvertTo16Bit(rowData16bit[index+1]) : 0; tgtDataPtr[2] = (planesToGet > 2)? ConvertTo16Bit(rowData16bit[index+2]) : 0; //BC6 does not have alpha, but we copy it for preview. It will get discarded on compression tgtDataPtr[3] = hasAlphaChannel? ConvertTo16Bit(rowData16bit[index+3]) : F32toF16(1.f); tgtDataPtr +=4; } return true; } bool IntelPlugin::ConvertToBC6From32Bit(unsigned16 *tgtDataPtr, int planesToGet, bool hasAlphaChannel) { if (ps.formatRecord->depth != 32) return false; float *rowData32bit = static_cast(ps.formatRecord->data); //Copy image into RGBA buffer, alpha is not copied for now for (int height=0; height< ps.formatRecord->imageSize.v; height++) for (int width=0; width< ps.formatRecord->imageSize.h; width++) { int index = height*ps.formatRecord->imageSize.h*planesToGet + width*planesToGet; //We assign black to other channels if photoshop does not provide enough channels, as the compressed text must be RGBA tgtDataPtr[0] = ConvertTo16Bit(rowData32bit[index]); tgtDataPtr[1] = (planesToGet > 1)? ConvertTo16Bit(rowData32bit[index+1]) : 0; tgtDataPtr[2] = (planesToGet > 2)? ConvertTo16Bit(rowData32bit[index+2]) : 0; //BC6 does not have alpha, but we copy it for preview. It will get discarded on compression tgtDataPtr[3] = hasAlphaChannel? ConvertTo16Bit(rowData32bit[index+2]) : F32toF16(1.f); tgtDataPtr +=4; } return true; } bool IntelPlugin::ConvertToBC4or5From32Bit(unsigned8 *tgtDataPtr, int planesToGet, bool hasAlphaChannel, bool gammaCorrect) { if (ps.formatRecord->depth != 32) return false; float *rowData32bit = static_cast(ps.formatRecord->data); for (int height=0; height< ps.formatRecord->imageSize.v; height++) for (int width=0; width< ps.formatRecord->imageSize.h; width++) { int index = height*ps.formatRecord->imageSize.h*planesToGet + width*planesToGet;//height*ps.formatRecord->imageSize.h*ps.formatRecord->planes + width*ps.formatRecord->planes; tgtDataPtr[0] = ConvertTo8Bit(rowData32bit[index], gammaCorrect); tgtDataPtr[1] = (planesToGet>1)? ConvertTo8Bit(rowData32bit[index+1], gammaCorrect) : tgtDataPtr[0]; //if BC4 all channels get the R plane, if BC5 we take the RG planes tgtDataPtr[2] = (planesToGet>2)? ConvertTo8Bit(rowData32bit[index+2], gammaCorrect) : tgtDataPtr[0]; //Copy the B channel for preview, it will get discarded on compression tgtDataPtr[3] = hasAlphaChannel? ConvertTo8Bit(rowData32bit[index+3], gammaCorrect) : 255; //Copy the A channel for preview, it will get discarded on compression tgtDataPtr +=4; } return true; } bool IntelPlugin::ConvertToBC4or5From16Bit(unsigned8 *tgtDataPtr, int planesToGet, bool hasAlphaChannel) { if (ps.formatRecord->depth != 16) return false; unsigned16 *rowData16bit = static_cast(ps.formatRecord->data); for (int height=0; height< ps.formatRecord->imageSize.v; height++) for (int width=0; width< ps.formatRecord->imageSize.h; width++) { int index = height*ps.formatRecord->imageSize.h*planesToGet + width*planesToGet;//height*ps.formatRecord->imageSize.h*ps.formatRecord->planes + width*ps.formatRecord->planes; tgtDataPtr[0] = ConvertTo8Bit(rowData16bit[index]); tgtDataPtr[1] = (planesToGet>1)? ConvertTo8Bit(rowData16bit[index+1]) : tgtDataPtr[0]; //if BC4 all channels get the R plane, if BC5 we take the RG planes tgtDataPtr[2] = (planesToGet>2)? ConvertTo8Bit(rowData16bit[index+2]) : tgtDataPtr[0]; //Copy the B channel for preview, it will get discarded on compression tgtDataPtr[3] = hasAlphaChannel? ConvertTo8Bit(rowData16bit[index+3]) : 255; //Copy the A channel for preview, it will get discarded on compression tgtDataPtr +=4; } return true; } bool IntelPlugin::ConvertToBC4or5From8Bit(unsigned8 *tgtDataPtr, int planesToGet, bool hasAlphaChannel) { if (ps.formatRecord->depth != 8) return false; //Get image pointer unsigned8 *rowData = static_cast(ps.formatRecord->data); //Copy image into RGBA buffer, alpha is not copied for (int height=0; height< ps.formatRecord->imageSize.v; height++) for (int width=0; width< ps.formatRecord->imageSize.h; width++) { int index = height*ps.formatRecord->imageSize.h*planesToGet + width*planesToGet; tgtDataPtr[0] = ConvertTo8Bit(rowData[index]); tgtDataPtr[1] = (planesToGet>1)? ConvertTo8Bit(rowData[index+1]) : tgtDataPtr[0]; //if BC4 all channels get the R plane, if BC5 we take the RG planes tgtDataPtr[2] = (planesToGet>2)? ConvertTo8Bit(rowData[index+2]) : tgtDataPtr[0]; //Copy the B channel for preview, it will get discarded on compression tgtDataPtr[3] = hasAlphaChannel? ConvertTo8Bit(rowData[index+3]) : 255; //Copy the A channel for preview, it will get discarded on compression tgtDataPtr +=4; } return true; } POINT IntelPlugin::GetPreviewDimensions() { POINT ret = {ps.formatRecord->imageSize.h, ps.formatRecord->imageSize.v}; if (ps.data->TextureTypeIndex==TextureTypeEnum::CUBEMAP_LAYERS) { ret.x *= 4; ret.y *= 3; } return ret; } int IntelPlugin::GetCompressedByteSize() { return preview.compressedSize; } int IntelPlugin::GetOriginalBitsPerPixel() { int planes = ps.formatRecord->planes; if (planes > 3 && ps.data->TextureTypeIndex!=TextureTypeEnum::COLOR_ALPHA) // we have enough planes for alpha but are not exporting it right now planes--; return ps.formatRecord->depth * planes; } int IntelPlugin::GetOriginalByteSize() { int byteSize = ps.formatRecord->imageSize.h * ps.formatRecord->imageSize.v * ((GetOriginalBitsPerPixel() + 7) >> 3); switch (ps.data->TextureTypeIndex) { case TextureTypeEnum::CUBEMAP_LAYERS: byteSize *= 6; break; case TextureTypeEnum::CUBEMAP_CROSSED: // a cross view only uses half the image resolution byteSize = byteSize >> 1; break; } return byteSize; } int IntelPlugin::GetLayerCount() { int layerCount = 0; for (auto layer = ps.formatRecord->documentInfo->layersDescriptor; layer; layer = layer->next) layerCount++; return layerCount; } // get RGB buffer void IntelPlugin::FetchPreviewRGB(unsigned8 *dst, int width, int height, int xo, int yo, double zoom, int previewOptions, int matteColor) { FetchImageData(); if (!(previewOptions & PREVIEW_CHANNEL_MASK)) previewOptions |= PREVIEW_CHANNEL_RGB; // default use original source int planes = ps.formatRecord->hiPlane - ps.formatRecord->loPlane + 1; int srcWidth = ps.formatRecord->theRect.right - ps.formatRecord->theRect.left; int srcHeight = ps.formatRecord->theRect.bottom - ps.formatRecord->theRect.top; int depthOrFormat = ps.formatRecord->depth; int rowPitch = ps.formatRecord->rowBytes; const uint8 * pixelData = static_cast(ps.formatRecord->data); auto exposure = ps.data->exposure; int mipLevel = (ps.data->SetMipLevel ? ps.data->MipLevel : 0); zoom = zoom / (1 << mipLevel); //Note //The Get(Un)CompressedImageForPreview() functions and the preview scratchimage are only used if the image to be fetched is compressed //or its a cube map or has mip layers. Otherwise the above pixelData is used as is. // flush invalid previews based on parameter changes... if (preview.textureType != ps.data->TextureTypeIndex || preview.mipMap != ps.data->MipMapTypeIndex || preview.mipLevel != mipLevel || preview.flipRChannel != ps.data->FlipX || preview.flipGChannel != ps.data->FlipY) { if (preview.uncompressedImage) { delete preview.uncompressedImage; preview.uncompressedImage = NULL; } if (preview.compressedImage) { delete preview.compressedImage; preview.compressedImage = NULL; preview.compressedSize = 0; } preview.textureType = ps.data->TextureTypeIndex; preview.mipMap = ps.data->MipMapTypeIndex; preview.mipLevel = mipLevel; preview.flipRChannel = ps.data->FlipX; preview.flipGChannel = ps.data->FlipY; } if (preview.encoding != ps.data->encoding_g || preview.fastBc67 != ps.data->fast_bc67) { if (preview.compressedImage) { delete preview.compressedImage; preview.compressedImage = NULL; } preview.encoding = ps.data->encoding_g; preview.fastBc67 = ps.data->fast_bc67; } if ((previewOptions & PREVIEW_SOURCE_MASK) == PREVIEW_SOURCE_COMPRESSED) { if (!preview.compressedImage) preview.compressedImage = GetCompressedImageForPreview(planes, preview.compressedSize); if (!preview.compressedImage) // Compressed can return NULL, ie no compression, so set it to uncompressed version preview.compressedImage = GetUncompressedImageForPreview(planes); if (preview.compressedImage) // shouldn't be null { auto image = preview.compressedImage->GetImages(); planes = 4; srcWidth = int(image->width); srcHeight = int(image->height); depthOrFormat = image->format; rowPitch = int(image->rowPitch); pixelData = image->pixels; } } else if (ps.data->MipMapTypeIndex == MipmapEnum::FROM_LAYERS || ps.data->TextureTypeIndex==TextureTypeEnum::CUBEMAP_CROSSED || ps.data->TextureTypeIndex==TextureTypeEnum::CUBEMAP_LAYERS) { if (!preview.uncompressedImage) preview.uncompressedImage = GetUncompressedImageForPreview(planes); if (preview.uncompressedImage) // shouldn't be null { auto image = preview.uncompressedImage->GetImages(); planes = 4; srcWidth = int(image->width); srcHeight = int(image->height); depthOrFormat = image->format; rowPitch = int(image->rowPitch); pixelData = image->pixels; } } preview.width = srcWidth; preview.height = srcHeight; int channelIndex[4] = {-1,-1,-1,-1}; switch (previewOptions & PREVIEW_CHANNEL_MASK) { // pure channels will return as grayscale case PREVIEW_CHANNEL_RED: channelIndex[0] = channelIndex[1] = channelIndex[2] = 0; break; case PREVIEW_CHANNEL_GREEN: channelIndex[0] = channelIndex[1] = channelIndex[2] = planes > 1 ? 1 : -1; break; case PREVIEW_CHANNEL_BLUE: channelIndex[0] = channelIndex[1] = channelIndex[2] = planes > 2 ? 2 : -1; break; case PREVIEW_CHANNEL_ALPHA: channelIndex[0] = channelIndex[1] = channelIndex[2] = planes > 3 ? 3 : -1; break; default: // a mixture of channels if ((previewOptions & PREVIEW_CHANNEL_RED) && planes > 0) channelIndex[0] = 0; if ((previewOptions & PREVIEW_CHANNEL_GREEN) && planes > 1) channelIndex[1] = 1; if ((previewOptions & PREVIEW_CHANNEL_BLUE) && planes > 2) channelIndex[2] = 2; if ((previewOptions & PREVIEW_CHANNEL_ALPHA) && planes > 3) channelIndex[2] = 3; break; } if ((previewOptions & PREVIEW_CHANNEL_ALPHA) && planes > 3) { if ((previewOptions & PREVIEW_CHANNEL_MASK) == PREVIEW_CHANNEL_ALPHA) // only alpha? { channelIndex[0] = channelIndex[1] = channelIndex[2] = 3; exposure = 1; } else channelIndex[3] = 3; } switch (depthOrFormat) { case DXGI_FORMAT_R32G32B32A32_FLOAT: case 32: for (int yt=0; yt < height; yt++) { int y = int((yt + yo) * zoom); for (int xt=0; xt< width; xt++) { auto pixelDst = dst + (width * yt + xt) * 3; int x = int((xt + xo) * zoom); if (y < 0 || y >= srcHeight || x < 0 || x >= srcWidth) // out of bounds? { pixelDst[0] = matteColor & 0xFF; pixelDst[1] = (matteColor >> 8) & 0xFF; pixelDst[2] = (matteColor >> 16) & 0xFF; } else { auto pixelSrc = reinterpret_cast(pixelData + rowPitch * y) + x * planes; pixelDst[0] = channelIndex[0] >= 0 ? ConvertTo8Bit(pixelSrc[channelIndex[0]] * exposure, false) : 0; pixelDst[1] = channelIndex[1] >= 0 ? ConvertTo8Bit(pixelSrc[channelIndex[1]] * exposure, false) : 0; pixelDst[2] = channelIndex[2] >= 0 ? ConvertTo8Bit(pixelSrc[channelIndex[2]] * exposure, false) : 0; } } } break; case DXGI_FORMAT_R16G16B16A16_FLOAT: // DX 16 bit is a float type for (int yt=0; yt < height; yt++) { int y = int((yt + yo) * zoom); for (int xt=0; xt< width; xt++) { auto pixelDst = dst + (width * yt + xt) * 3; int x = int((xt + xo) * zoom); if (y < 0 || y >= srcHeight || x < 0 || x >= srcWidth) // out of bounds? { pixelDst[0] = matteColor & 0xFF; pixelDst[1] = (matteColor >> 8) & 0xFF; pixelDst[2] = (matteColor >> 16) & 0xFF; } else { auto pixelSrc = reinterpret_cast(pixelData + rowPitch * y) + x * planes; pixelDst[0] = channelIndex[0] >= 0 ? FloatToByte(F16toF32(pixelSrc[channelIndex[0]]) * exposure) : 0; pixelDst[1] = channelIndex[1] >= 0 ? FloatToByte(F16toF32(pixelSrc[channelIndex[1]]) * exposure) : 0; pixelDst[2] = channelIndex[2] >= 0 ? FloatToByte(F16toF32(pixelSrc[channelIndex[2]]) * exposure) : 0; } } } break; case 16: // photoshop 16 bit is integer type for (int yt=0; yt < height; yt++) { int y = int((yt + yo) * zoom); for (int xt=0; xt< width; xt++) { auto pixelDst = dst + (width * yt + xt) * 3; int x = int((xt + xo) * zoom); if (y < 0 || y >= srcHeight || x < 0 || x >= srcWidth) // out of bounds? { pixelDst[0] = matteColor & 0xFF; pixelDst[1] = (matteColor >> 8) & 0xFF; pixelDst[2] = (matteColor >> 16) & 0xFF; } else { auto pixelSrc = reinterpret_cast(pixelData + rowPitch * y) + x * planes; pixelDst[0] = channelIndex[0] >= 0 ? ConvertTo8Bit(pixelSrc[channelIndex[0]]) : 0; pixelDst[1] = channelIndex[1] >= 0 ? ConvertTo8Bit(pixelSrc[channelIndex[1]]) : 0; pixelDst[2] = channelIndex[2] >= 0 ? ConvertTo8Bit(pixelSrc[channelIndex[2]]) : 0; } } } break; case DXGI_FORMAT_R8G8B8A8_UNORM: case 8: for (int yt=0; yt < height; yt++) { int y = int((yt + yo) * zoom); for (int xt=0; xt< width; xt++) { auto pixelDst = dst + (width * yt + xt) * 3; int x = int((xt + xo) * zoom); if (y < 0 || y >= srcHeight || x < 0 || x >= srcWidth) // out of bounds? { pixelDst[0] = matteColor & 0xFF; pixelDst[1] = (matteColor >> 8) & 0xFF; pixelDst[2] = (matteColor >> 16) & 0xFF; } else { auto pixelSrc = reinterpret_cast(pixelData + rowPitch * y) + x * planes; pixelDst[0] = channelIndex[0] >= 0 ? pixelSrc[channelIndex[0]] : 0; pixelDst[1] = channelIndex[1] >= 0 ? pixelSrc[channelIndex[1]] : 0; pixelDst[2] = channelIndex[2] >= 0 ? pixelSrc[channelIndex[2]] : 0; } } } break; } } bool IntelPlugin::ConvertToBCFrom32Bit(unsigned8 *tgtDataPtr, int planesToGet, bool hasAlphaChannel, bool gammaCorrect) { if (ps.formatRecord->depth != 32) return false; float *rowData32bit = static_cast(ps.formatRecord->data); for (int height=0; height< ps.formatRecord->imageSize.v; height++) for (int width=0; width< ps.formatRecord->imageSize.h; width++) { int index = height*ps.formatRecord->imageSize.h*planesToGet + width*planesToGet;//height*ps.formatRecord->imageSize.h*ps.formatRecord->planes + width*ps.formatRecord->planes; //We assign black to other channels if photoshop does not provide enough channels as the compressed text must be RGBA tgtDataPtr[0] = ConvertTo8Bit(rowData32bit[index], gammaCorrect); tgtDataPtr[1] = (planesToGet > 1)? ConvertTo8Bit(rowData32bit[index+1], gammaCorrect) : 0; tgtDataPtr[2] = (planesToGet > 2)? ConvertTo8Bit(rowData32bit[index+2], gammaCorrect) : 0; tgtDataPtr[3] = hasAlphaChannel? ConvertTo8Bit(rowData32bit[index+3], gammaCorrect) : 255; tgtDataPtr +=4; } return true; } bool IntelPlugin::ConvertToBCFrom16Bit(unsigned8 *tgtDataPtr, int planesToGet, bool hasAlphaChannel) { if (ps.formatRecord->depth != 16) return false; unsigned16 *rowData16bit = static_cast(ps.formatRecord->data); for (int height=0; height< ps.formatRecord->imageSize.v; height++) for (int width=0; width< ps.formatRecord->imageSize.h; width++) { int index = height*ps.formatRecord->imageSize.h*planesToGet + width*planesToGet;//height*ps.formatRecord->imageSize.h*ps.formatRecord->planes + width*ps.formatRecord->planes; //We assign black to other channels if photoshop does not provide enough channels as the compressed text must be RGBA tgtDataPtr[0] = ConvertTo8Bit(rowData16bit[index]); tgtDataPtr[1] = (planesToGet > 1)? ConvertTo8Bit(rowData16bit[index+1]) : 0; tgtDataPtr[2] = (planesToGet > 2)? ConvertTo8Bit(rowData16bit[index+2]) : 0; tgtDataPtr[3] = hasAlphaChannel? ConvertTo8Bit(rowData16bit[index+3]) : 255; tgtDataPtr +=4; } return true; } bool IntelPlugin::ConvertToBCFrom8Bit(unsigned8 *tgtDataPtr, int planesToGet, bool hasAlphaChannel) { if (ps.formatRecord->depth != 8) return false; //Get image pointer unsigned8 *rowData = static_cast(ps.formatRecord->data); //Copy data from photoshop buffer into local buffer for (int height=0; height< ps.formatRecord->imageSize.v; height++) for (int width=0; width< ps.formatRecord->imageSize.h; width++) { int index = height*ps.formatRecord->imageSize.h*planesToGet + width*planesToGet;//height*ps.formatRecord->imageSize.h*ps.formatRecord->planes + width*ps.formatRecord->planes; //We assign black to other channels is photoshop does not provide enought channels as the compressed text must be RGBA tgtDataPtr[0] = ConvertTo8Bit(rowData[index]); tgtDataPtr[1] = (planesToGet > 1)? ConvertTo8Bit(rowData[index+1]) : 0; tgtDataPtr[2] = (planesToGet > 2)? ConvertTo8Bit(rowData[index+2]) : 0; tgtDataPtr[3] = hasAlphaChannel? ConvertTo8Bit(rowData[index+3]) : 255; tgtDataPtr +=4; } return true; } /*****************************************************************************/ /*****************************************************************************/ //Compress rgba_surface into tgtPixels, uisng Intel ISPC encoders bool IntelPlugin::ISPC_compression(rgba_surface &source, const Image& target, bool hasAlpha_rgba) { CompressionFunc* cmpFunc = NULL; switch (ps.data->encoding_g) { case DXGI_FORMAT_BC1_UNORM_SRGB: case DXGI_FORMAT_BC1_UNORM: cmpFunc = CompressImageBC1; break; case DXGI_FORMAT_BC3_UNORM_SRGB: case DXGI_FORMAT_BC3_UNORM: cmpFunc = CompressImageBC3; break; case DXGI_FORMAT_BC7_UNORM_SRGB: case DXGI_FORMAT_BC7_UNORM: if (hasAlpha_rgba) cmpFunc = ps.data->fast_bc67 ? CompressImageBC7_alpha_veryfast : CompressImageBC7_alpha_basic; else cmpFunc = ps.data->fast_bc67 ? CompressImageBC7_veryfast : CompressImageBC7_basic; break; case DXGI_FORMAT_BC6H_UF16: case DXGI_FORMAT_BC6H_SF16: cmpFunc = ps.data->fast_bc67 ? CompressImageBC6H_fast : CompressImageBC6H_slow; break; default: break; } if (cmpFunc) { int slices = (source.width * source.height) / 0x40000; // 256K pixels per chunk if (slices < 1) slices = 1; for (int i = 0; i < slices; i++) { if (i > 0 && !SetProgress(i, slices)) // allow an early out return false; int ylo = (i * source.height / slices) & ~0x3; // 4 pixels per block row int yhi = ((i+1) * source.height / slices) & ~0x3; // 4 pixels per block row if (yhi > source.height) yhi = source.height; if (yhi > ylo) { auto input = source; input.ptr += input.stride * ylo; input.height = yhi - ylo; auto dst = target.pixels + target.rowPitch * (ylo >> 2); // rowPitch is actually blockRowPitch here if (ps.data->gMultithreaded) CompressImageMT(&input, dst, cmpFunc, ps.data->encoding_g); else CompressImageST(&input, dst, cmpFunc, ps.data->encoding_g); } } return true; } return false; } /*****************************************************************************/ /*****************************************************************************/ //Pad the surface size to boundaries of 4 //Calculates new width,height,stride and new buffer //It does not deallocate the old buffer //It does return the new surface //It is the responsibility of the user to deallocate the new/old buffer when not needed anymore rgba_surface IntelPlugin::DoPaddingToMultiplesOf4(const rgba_surface &input) { rgba_surface out; // now we're going to copy to a new buffer to do padding to boundaries of 4 // boundaries of 4 are needed for the compression algorithms to work // since they rely on 4x4 blocks int pixelSize = 4 * (ps.data->encoding_g == DXGI_FORMAT_BC6H_UF16 ? 2 : 1); out.width = (input.width+3) & ~3; //pad witdh to boundaries of 4 out.height = (input.height+3) & ~3; //pad height to boundaries of 4 out.stride = out.width * pixelSize; //size of a row out.ptr = new uint8_t[out.height * out.stride]; //new buffer //Copy row by row into new buffer for (int y = 0; y < input.height; y++) { auto rowSrc = input.ptr + y * input.stride; auto rowDst = out.ptr + y * out.stride; //Copy existing rows memcpy(rowDst, rowSrc, input.width * pixelSize); //Pad to new width, copy the last pixel of the old row into the remaining pixels of new row for (int x=input.width; x < out.width; x++) // trailing pixels memcpy(rowDst + x * pixelSize, rowSrc + (input.width-1) * pixelSize, pixelSize); } //Pad to new height, copy last row multiple times to fill new rows for (int y = input.height; y < out.height; y++) // extra rows { auto rowDst = out.ptr + y * out.stride; memcpy(rowDst, rowDst - out.stride, out.stride); } return out; } /*****************************************************************************/ /*****************************************************************************/ //AdvanceState () has to be called before entering this function so that the ps.formatRecord->data buffer is full; ScratchImage* IntelPlugin::GetCompressedImageForPreview(int planesToGet_, int &compressedSize) { //Returns null if image to preview is uncompressed if (ps.data->encoding_g == DXGI_FORMAT_R8G8B8A8_UNORM) { //just compute size, the preview will use the uncompressed iamge for both views compressedSize = ps.formatRecord->imageSize.h*ps.formatRecord->imageSize.v*4; return NULL; } //Show loading cursor showLoadingCursor(); bool hasAlpha_ = false; //Open a empty compressed scratch image ScratchImage *scrImageScratch = new ScratchImage(); //Open a empty uncompressed scratch image ScratchImage *scrUncompressedImageScratch = new ScratchImage(); //Flag if there is alpha channel and corresponding texture type Color+Alpha specified if (planesToGet_ > 3) hasAlpha_ = true; if (!CopyDataForEncoding(scrUncompressedImageScratch, hasAlpha_, false, true)) { errorMessage("Unsupported bit depth", "Preview Error"); return NULL; } //============================================================================================ //============================================================================================ //Special preview operation, create a horiz. crossed 2D image out of the cube map if (ps.data->TextureTypeIndex==TextureTypeEnum::CUBEMAP_CROSSED && IsCubeMapWithSetMipLevelOverride()) { //If a SetMipLevel was specified you have to turn even Crossed image into proper CubeMap Scratchimages to the the mipmap //If this is a cube map, change scrUncompressedImageScratch into a CubeMap type image, section ConvertToCubeMapFromCross(&scrUncompressedImageScratch); //create a horiz. crossed 2D image out of the cube map ConvertToHorizontalCrossFromCubeMap(&scrUncompressedImageScratch); } else if (ps.data->TextureTypeIndex == TextureTypeEnum::CUBEMAP_LAYERS) { //If this is a cube map, change scrUncompressedImageScratch into a CubeMap type image, section ConvertToCubeMapFromLayers(&scrUncompressedImageScratch, hasAlpha_); //create a horiz. crossed 2D image out of the cube map ConvertToHorizontalCrossFromCubeMap(&scrUncompressedImageScratch); } //============================================================================================ //============================================================================================ //MipMap from Layers //Overwrite only the initial image MipLevel 0 from Layer 0, in order to generate automatic MipMaps if (IsMipMapsDefinedByLayer()) { //We use this to avoid having to disable the visibility of all layers when creating mip level 0. //By default all images are composited onto mip level 0 CopyLayersIntoMipMaps(scrUncompressedImageScratch, hasAlpha_, 0, 1); } //============================================================================================ //============================================================================================ //If FlipX/Y true, invert R/G channels scrUncompressedImageScratch only if Normal Map, section if ((ps.data->FlipX || ps.data->FlipY) && (ps.data->TextureTypeIndex==TextureTypeEnum::NORMALMAP)) { FlipXYChannelNormalMap(scrUncompressedImageScratch); } //============================================================================================ //============================================================================================ //If Normalization Postprocess option has been specified and this is a Normal Type texture type //Normalize all mip chain if (ps.data->Normalize && ps.data->TextureTypeIndex == TextureTypeEnum::NORMALMAP) { NormalizeNormalMapChain(scrUncompressedImageScratch); } //============================================================================================ //============================================================================================ //Compress scrUncompressedImageScratch into scrImageScratch, section ps.data->previewing = true; if (!CompressToScratchImage(&scrImageScratch, &scrUncompressedImageScratch, hasAlpha_)) { return NULL; } //Get compressed size of first image compressedSize = int(scrImageScratch->GetImages()->slicePitch); //This is not needed when saving out the image, its just needed for SRGB or 32 bit formats //to compensate for monitor gamma and have it look ok in preview. if (ps.formatRecord->depth == 32) { //Force SRGB if 32bit, to diplay ok. Otherwise it previews to bright scrImageScratch->OverrideFormat(MakeSRGB(scrImageScratch->GetMetadata().format)); } else { //If SRGB remove SRGB flag to display OK. DXGI_FORMAT fmt = scrImageScratch->GetMetadata().format; switch ( fmt ) { case DXGI_FORMAT_BC1_UNORM_SRGB: scrImageScratch->OverrideFormat(DXGI_FORMAT_BC1_UNORM); break; case DXGI_FORMAT_BC3_UNORM_SRGB: scrImageScratch->OverrideFormat(DXGI_FORMAT_BC3_UNORM); break; case DXGI_FORMAT_BC7_UNORM_SRGB: scrImageScratch->OverrideFormat(DXGI_FORMAT_BC7_UNORM); break; default: break; } } //Decompress scrImageScratch image into and uncpressed one ScratchImage *destImage = new ScratchImage(); HRESULT hr; auto targetFormat = DXGI_FORMAT_R8G8B8A8_UNORM; if (ps.formatRecord->depth == 32 && (ps.data->encoding_g == DXGI_FORMAT_BC6H_UF16 || ps.data->encoding_g == DXGI_FORMAT_BC6H_SF16)) targetFormat = DXGI_FORMAT_R32G32B32A32_FLOAT; hr = Decompress( scrImageScratch->GetImages(), scrImageScratch->GetImageCount(), scrImageScratch->GetMetadata(), targetFormat, *destImage ); if ( FAILED(hr) ) { errorMessage("Can not decompress image", "Preview Error"); delete destImage; destImage = NULL; } //Cleanup, section //Dispose compressed image if (scrUncompressedImageScratch != NULL) delete scrUncompressedImageScratch; if (scrImageScratch != NULL) delete scrImageScratch; //Go back to normal cursor showNormalCursor(); return destImage; } /*****************************************************************************/ /*****************************************************************************/ //AdvanceState () has to be called before entering this function so that the ps.formatRecord->data buffer is full; ScratchImage* IntelPlugin::GetUncompressedImageForPreview(int planesToGet_) { bool hasAlpha_ = false; //Open a empty uncompressed scratch image ScratchImage *scrUncompressedImageScratch = new ScratchImage(); //Flag if there is alpha channel and corresponding texture type Color+Alpha specified if (planesToGet_ > 3) hasAlpha_ = true; if (!CopyDataForEncoding(scrUncompressedImageScratch, hasAlpha_, false, false)) { errorMessage("Unsupported bit depth", "Preview Error"); return NULL; } //============================================================================================ //============================================================================================ //Special preview operation, create a horiz. crossed 2D image out of the cube map if (ps.data->TextureTypeIndex==TextureTypeEnum::CUBEMAP_CROSSED && IsCubeMapWithSetMipLevelOverride()) { //If a SetMipLevel was specified you have to turn even Crossed image into proper CubeMap Scratchimages to the the mipmap //If this is a cube map, change scrUncompressedImageScratch into a CubeMap type image, section ConvertToCubeMapFromCross(&scrUncompressedImageScratch); //create a horiz. crossed 2D image out of the cube map ConvertToHorizontalCrossFromCubeMap(&scrUncompressedImageScratch); } else if (ps.data->TextureTypeIndex == TextureTypeEnum::CUBEMAP_LAYERS) { //If this is a cube map, change scrUncompressedImageScratch into a CubeMap type image, section ConvertToCubeMapFromLayers(&scrUncompressedImageScratch, hasAlpha_); //create a horiz. crossed 2D image out of the cube map ConvertToHorizontalCrossFromCubeMap(&scrUncompressedImageScratch); } //============================================================================================ //============================================================================================ //MipMap from Layers //Overwrite only the initial image MipLevel 0 from Layer 0, in order to generate automatic MipMaps if (IsMipMapsDefinedByLayer()) { //We use this to avoid having to disable the visibility of all layers when creating mip level 0. //By default all images are composited onto mip level 0 CopyLayersIntoMipMaps(scrUncompressedImageScratch, hasAlpha_, 0, 1); } //============================================================================================ //============================================================================================ //If FlipX/Y true, invert R/G channels scrUncompressedImageScratch only if Normal Map, section if ((ps.data->FlipX || ps.data->FlipY) && (ps.data->TextureTypeIndex==TextureTypeEnum::NORMALMAP)) { FlipXYChannelNormalMap(scrUncompressedImageScratch); } //If 16 bit convert to 8 bit if (scrUncompressedImageScratch->GetMetadata().format == DXGI_FORMAT_R16G16B16A16_FLOAT) { //Decompress scrImageScratch image into and uncpressed one ScratchImage *destImage = new ScratchImage(); HRESULT hr; hr = Convert( scrUncompressedImageScratch->GetImages(), scrUncompressedImageScratch->GetImageCount(), scrUncompressedImageScratch->GetMetadata(), DXGI_FORMAT_R8G8B8A8_UNORM, TEX_FILTER_DEFAULT, 0.5f, *destImage ); if ( FAILED(hr) ) { errorMessage("Can not convert image", "Preview Error"); delete destImage; destImage = NULL; } //Cleanup, section //Dispose compressed image if (scrUncompressedImageScratch != NULL) delete scrUncompressedImageScratch; return destImage; } return scrUncompressedImageScratch; } /*****************************************************************************/ /*****************************************************************************/ //Return true if texture type cube maps and the setMipLevel is checked bool IntelPlugin::IsCubeMapWithSetMipLevelOverride() { if (ps.data->SetMipLevel && (ps.data->TextureTypeIndex == TextureTypeEnum::CUBEMAP_CROSSED || ps.data->TextureTypeIndex == TextureTypeEnum::CUBEMAP_LAYERS)) return true; return false; } /*****************************************************************************/ /*****************************************************************************/ //Returns true if mip maps are defined by layers //Mip map form layers is not applicable to cube maps. bool IntelPlugin::IsMipMapsDefinedByLayer() { if (ps.data->MipMapTypeIndex == MipmapEnum::FROM_LAYERS && ps.data->TextureTypeIndex != TextureTypeEnum::CUBEMAP_CROSSED && ps.data->TextureTypeIndex != TextureTypeEnum::CUBEMAP_LAYERS && ps.formatRecord->documentInfo->layerCount > 1) return true; return false; } /*****************************************************************************/ /*****************************************************************************/ //Convert scrUncompressedImageScratch_ from a crossed layout image to a cube map ScratchImage void IntelPlugin::ConvertToCubeMapFromCross(ScratchImage **scrUncompressedImageScratch_) { //Open a empty uncompressed scratch image ScratchImage *cubemapUncompressedImageScratch = new ScratchImage(); //Hold the rectangles which define the siz cube face in the large image DirectX::Rect coords[6]; //These coords are for the following cubemap order +X,-X,+Y,-Y,+Z,-Z . This is the order CubemapGen likes //They define a absolute width/height multiplactor into the image to get the coords for horizontal.vertical crossed layout cubemap . //CubeMaps have all their 6 faces equal. int crossedCoords[6][2] = {{2,1}, {0,1}, {1,0}, {1,2}, {1,1}, {3,1}}; //Setup width/height with Horziontal(4x3) cross layout as default int width = ps.formatRecord->imageSize.h/4; int height = ps.formatRecord->imageSize.v/3; //Determine if Vertical(3x4) cubemap layout if (ps.formatRecord->imageSize.h < ps.formatRecord->imageSize.v) { //Vertical Cross layout width = ps.formatRecord->imageSize.h/3; height = ps.formatRecord->imageSize.v/4; //flip the last coords if in vertical layout crossedCoords[5][0] = 1; crossedCoords[5][1] = 3; } //Compute final coordinates for (int i=0; i<6; i++) { coords[i] = DirectX::Rect(crossedCoords[i][0]*width, crossedCoords[i][1]*height, width, height); } //Allocate a cubemap scratchImage if (ps.data->encoding_g == DXGI_FORMAT_BC6H_UF16) { //Allocate space for one cube map rgba 16bit float image cubemapUncompressedImageScratch->InitializeCube(DXGI_FORMAT_R16G16B16A16_FLOAT, width, height, 1, 1); } else //BC1,3,7 or uncompressed { //Allocate space for one cube map rgba 8bit float image cubemapUncompressedImageScratch->InitializeCube(DXGI_FORMAT_R8G8B8A8_UNORM, width, height, 1, 1); } //Copy from crossed cubemap from big scrUncompressedImageScratch_ to images in cubemapUncompressedImageScratch const Image *crossedImage = (*scrUncompressedImageScratch_)->GetImages(); const Image *cubeImage = cubemapUncompressedImageScratch->GetImages(); for (int i=0; i<6; i++) { DirectX::CopyRectangle(*crossedImage, coords[i], cubeImage[i], TEX_FILTER_DEFAULT, 0, 0); } //Free previous space delete *scrUncompressedImageScratch_; //Copy over pointer from ScratchImage which has CubeMap, //now scrUncompressedImageScratch holds the crossed cubemap disected *scrUncompressedImageScratch_ = cubemapUncompressedImageScratch; } /*****************************************************************************/ /*****************************************************************************/ //Convert scrUncompressedImageScratch_ from document layers to a cube map DirectX::ScratchImage bool IntelPlugin::ConvertToCubeMapFromLayers(ScratchImage **scrUncompressedImageScratch_, bool hasAlpha_) { ReadChannelDesc *pChannel; ReadLayerDesc *layerDesc; char *pLayerData; if (ps.formatRecord->documentInfo->layerCount < 6) { return false; } // Get a buffer to hold each channel as we process, formatRecord->planeBytes are computed the first time fetchImage() is called pLayerData = sPSBuffer->New(NULL, ps.formatRecord->imageSize.h * ps.formatRecord->imageSize.v * ps.formatRecord->planeBytes); if (pLayerData == NULL) { SetResult(memFullErr); return false; } //Open a empty uncompressed scratch image ScratchImage *cubemapUncompressedImageScratch = new ScratchImage(); //All layers must have these names and feature the correspanding image +X,-X,+Y,-Y,+Z,-Z. //Any layers with different names will be ignored. //There must be at least 6 layers present including the background layer, otherwise some cube faces will be blank. //The final Cubemap dds will have the images in this order, +X,-X,+Y,-Y,+Z,-Z. This is the order CubemapGen likes and sort of a standard. //Which face goes into what index inside the cubemap std::map facesmap; facesmap["+X"]=0; facesmap["-X"]=1; facesmap["+Y"]=2; facesmap["-Y"]=3; facesmap["+Z"]=4; facesmap["-Z"]=5; //Setup width/height int width = static_cast((*scrUncompressedImageScratch_)->GetMetadata().width); int height = static_cast((*scrUncompressedImageScratch_)->GetMetadata().height); //Allocate a cubemap scratchImage if (ps.data->encoding_g == DXGI_FORMAT_BC6H_UF16) { //Allocate space for one cube map rgba 16bit float image cubemapUncompressedImageScratch->InitializeCube(DXGI_FORMAT_R16G16B16A16_FLOAT, width, height, 1, 1); } else //BC1,3,7 or uncompressed { //Allocate space for one cube map rgba 8bit float image cubemapUncompressedImageScratch->InitializeCube(DXGI_FORMAT_R8G8B8A8_UNORM, width, height, 1, 1); } //***************************************************** //Copy from Layers into cubemapUncompressedImageScratch const Image *cubeImage = cubemapUncompressedImageScratch->GetImages(); //Get the first layer in this layer list layerDesc = ps.formatRecord->documentInfo->layersDescriptor; //Cycle through remaining layers, Assign each layer to a different mip map in ScratchImage while (layerDesc != NULL) { std::map::iterator it; //Check layername for validity only these are supported "+X","-X","+Y","-Y","+Z","-Z" it = facesmap.find(layerDesc->name); if ( it != facesmap.end()) { //Get index into SratchImage array for this face name int i = it->second; //Get the first channel in this channel list pChannel = layerDesc->compositeChannelsList; int planeNumber = 0; //Get the RGB channels while (pChannel != NULL) { //Get pixel data from channel ReadLayerData(pChannel, pLayerData, ps.formatRecord->imageSize.h, ps.formatRecord->imageSize.v); for (size_t y = 0; y < cubeImage[i].height; y++) { for (size_t x = 0; x < cubeImage[i].width; x++) { int indexToImage = int(cubeImage[i].width*y*4 + x*4); //the ScratchImage is always RGBA therefore pitch of 4 int indexToLayerChannel = int(ps.formatRecord->imageSize.h*y + x); //here the pitch is only 1 CopyFromLayerChannelIntoImage(pLayerData, &cubeImage[i], indexToImage+planeNumber, indexToLayerChannel); } } pChannel = pChannel->next; planeNumber++; } //Get first layermask and set as alpha //If no layermask then use transparency channel if (!(pChannel = layerDesc->layerMask)) { //Get first Transparency channel and set as alpha pChannel = layerDesc->transparency; } //Get alpha if (hasAlpha_ && (pChannel != NULL)) { //Get pixel data from channel ReadLayerData(pChannel, pLayerData, ps.formatRecord->imageSize.h, ps.formatRecord->imageSize.v); } else { FillLayerDataToWhite(pLayerData, ps.formatRecord->imageSize.h, ps.formatRecord->imageSize.v); } for (size_t y = 0; y < cubeImage[i].height; y++) { for (size_t x = 0; x < cubeImage[i].width; x++) { int indexToImage = int(cubeImage[i].width*y*4 + x*4); //the ScratchImage is always RGBA therefore pitch of 4 int indexToLayerChannel = int(ps.formatRecord->imageSize.h*y + x); //here the pitch is only 1 //Here the plane number is 3 for alpha CopyFromLayerChannelIntoImage(pLayerData, &cubeImage[i], indexToImage+3, indexToLayerChannel); } } } layerDesc = layerDesc->next; //Get next layer } sPSBuffer->Dispose(static_cast(&pLayerData)); //Free previous space delete *scrUncompressedImageScratch_; //Copy over pointer from ScratchImage which has CubeMap, //now scrUncompressedImageScratch holds the crossed cubemap disected *scrUncompressedImageScratch_ = cubemapUncompressedImageScratch; return true; } /*****************************************************************************/ /*****************************************************************************/ //Convert scrUncompressedImageScratch_ from a cube map to a horizontal crossed layout image void IntelPlugin::ConvertToHorizontalCrossFromCubeMap(ScratchImage **scrUncompressedImageScratch_) { //Open a empty uncompressed scratch image ScratchImage *crossedUncompressedImageScratch = new ScratchImage(); //Hold the rectangles which define the siz cube face in the large image DirectX::Rect coord; //Which mipLevel to get for crossed image cubemap preview. Normaly 0 but can change when setMipLevels is specified int mipLevel = 0; //These coords are for the following cubemap order +X,-X,+Y,-Y,+Z,-Z . This is the order CubemapGen likes //They define a absolute width/height multiplactor into the image to get the coords for horizontal.vertical crossed layout cubemap . //CubeMaps have all their 6 faces equal. int crossedCoords[6][2] = {{2,1}, {0,1}, {1,0}, {1,2}, {1,1}, {3,1}}; //Setup width/height with Horziontal(4x3) cross layout as default int width = static_cast((*scrUncompressedImageScratch_)->GetMetadata().width); int height = static_cast((*scrUncompressedImageScratch_)->GetMetadata().height); //============================================================================================ //============================================================================================ //Force mipmaps if setMipLevels on cube maps are specified if (IsCubeMapWithSetMipLevelOverride()) { //Open temporary imageScratch to save mipmaps ScratchImage *scrImageMipMapScratch = new ScratchImage(); //Generate MipMaps from scrUncompressedImageScratch and save to scrImageMipMapScratch HRESULT hr = GenerateMipMaps((*scrUncompressedImageScratch_)->GetImages(), (*scrUncompressedImageScratch_)->GetImageCount(), (*scrUncompressedImageScratch_)->GetMetadata(), TEX_FILTER_DEFAULT|TEX_FILTER_SEPARATE_ALPHA, 0, *scrImageMipMapScratch ); if( hr != S_OK ) { UserError("Could not create MipMaps"); return; } //Override with mip level size width = int(scrImageMipMapScratch->GetImage(ps.data->MipLevel, 0, 0)->width); height = int(scrImageMipMapScratch->GetImage(ps.data->MipLevel, 0, 0)->height); //Set which mip level to geto for creating crossed image mipLevel = ps.data->MipLevel; //free previous space delete *scrUncompressedImageScratch_; //Copy over pointer from ScratchImage which has MipMap, now scrUncompressedImageScratch holds the initial image + mip chain (*scrUncompressedImageScratch_) = scrImageMipMapScratch; } coord = DirectX::Rect(0, 0, width, height); //Allocate a scratchImage if (ps.data->encoding_g == DXGI_FORMAT_BC6H_UF16) { //Allocate space for one cube map rgba 16bit float image crossedUncompressedImageScratch->Initialize2D(DXGI_FORMAT_R16G16B16A16_FLOAT, width*4, height*3, 1, 1); } else //BC1,3,7 or uncompressed { //Allocate space for one cube map rgba 8bit float image crossedUncompressedImageScratch->Initialize2D(DXGI_FORMAT_R8G8B8A8_UNORM, width*4, height*3, 1, 1); } //Copy from cubemap scrUncompressedImageScratch_ to crossed horizontal layout in crossedUncompressedImageScratch const Image *crossedImage = crossedUncompressedImageScratch->GetImages(); for (int i=0; i<6; i++) { const Image *cubeImage = (*scrUncompressedImageScratch_)->GetImage(mipLevel, i, 0); DirectX::CopyRectangle(*cubeImage, coord, *crossedImage, TEX_FILTER_DEFAULT, crossedCoords[i][0]*width, crossedCoords[i][1]*height); } //Free previous space delete *scrUncompressedImageScratch_; //Copy over pointer from ScratchImage which has CubeMap, //now scrUncompressedImageScratch holds the crossed cubemap disected *scrUncompressedImageScratch_ = crossedUncompressedImageScratch; } /*****************************************************************************/ /*****************************************************************************/ //Flip the X(Red) channel and or the Y(Green) channel of the normal map void IntelPlugin::FlipXYChannelNormalMap(ScratchImage *scrUncompressedImageScratch_) { //Get first on only image const Image *image = scrUncompressedImageScratch_->GetImages(); //Traverse all pixels for (size_t i = 0; i < image->height*image->width; i++) { //scrUncompressedImageScratch is by default RGBA data so we need a pitch of 4 int index = (int)i*4; if (image->format == DXGI_FORMAT_R8G8B8A8_UNORM) { //Get pointer to first (and only) image unsigned8 *rowBigDataPtr = image->pixels; //Inverse values of R/G channels only if (ps.data->FlipX) rowBigDataPtr[index] = 255 - rowBigDataPtr[index]; if (ps.data->FlipY) rowBigDataPtr[index + 1] = 255 - rowBigDataPtr[index + 1]; } else if (image->format == DXGI_FORMAT_R16G16B16A16_FLOAT) { //Get pointer to first (and only) image, cast to 16bit for BC6 unsigned16 *rowBigDataPtr = reinterpret_cast(image->pixels); //Inverse values of R/G channels only float r = F16toF32(rowBigDataPtr[index]); float g = F16toF32(rowBigDataPtr[index+1]); if (ps.data->FlipX) rowBigDataPtr[index] = F32toF16(1.f - r); if (ps.data->FlipY) rowBigDataPtr[index+1] = F32toF16(1.f - g); } } } /*****************************************************************************/ /*****************************************************************************/ //Normalize all values of this Nomral map in main image and all mip maps void IntelPlugin::NormalizeNormalMapChain(ScratchImage *scrUncompressedImageScratch_) { //Open temporary imageScratch to save mipmaps for (size_t i = 0; i < scrUncompressedImageScratch_->GetImageCount(); i++) { if (auto image = scrUncompressedImageScratch_->GetImages() + i) { for (size_t y = 0; y < image->height; y++) { auto ptr = image->pixels + image->rowPitch * y; if (image->format == DXGI_FORMAT_R8G8B8A8_UNORM) { for (size_t x = 0; x < image->width; x++) { auto p = ptr + x * 4; float r = static_cast(p[0] - 128); float g = static_cast(p[1] - 128); float b = static_cast(p[2] - 128); float m = sqrt(r*r + g*g + b*b); if (m > 0) { m = 127/m; p[0] = static_cast(r*m + 128); p[1] = static_cast(g*m + 128); p[2] = static_cast(b*m + 128); } else { //This is the default normal vector (0,0,1) p[0] = 128; p[1] = 128; p[2] = 255; } } } else if (image->format == DXGI_FORMAT_R16G16B16A16_FLOAT) { for (size_t x = 0; x < image->width; x++) { auto p = reinterpret_cast(ptr) + x * 4; float r = F16toF32(p[0]); float g = F16toF32(p[1]); float b = F16toF32(p[2]); float m = sqrt(r*r + g*g + b*b); if (m > 0) { m = 1.0f/m; p[0] = F32toF16(r * m); p[1] = F32toF16(g * m); p[2] = F32toF16(b * m); } else { //This is the default normal vector (0,0,1) p[0] = F32toF16(0); p[1] = F32toF16(0); p[2] = F32toF16(1); } } } } } } } /*****************************************************************************/ /*****************************************************************************/ /* Read in the channel data from the original document. */ void IntelPlugin::ReadLayerData(ReadChannelDesc *pChannel, char *pLayerData, int width, int height) { // Make sure there is something for me to read from if (pChannel == NULL || pChannel->port == NULL || pLayerData == NULL) return; Boolean canRead; if (sPSChannelProcs->CanRead(pChannel->port, &canRead)) { // this function should not error, tell the host accordingly SetResult(errPlugInHostInsufficient); return; } if (!canRead) return; // some local variables to play with VRect read_rect; PixelMemoryDesc destination; // What area of the document do we want to read from read_rect.top = 0; read_rect.left = 0; read_rect.bottom = height; read_rect.right = width; // set up the PixelMemoryDesc destination.data = pLayerData; destination.depth = pChannel->depth; destination.rowBits = width*pChannel->depth; destination.colBits = pChannel->depth; destination.bitOffset = 0; // Read this data into our buffer, you could check the read_rect to see if you got everything you desired if (sPSChannelProcs->ReadPixelsFromLevel( pChannel->port, 0, &read_rect, &destination)) { SetResult(errPlugInHostInsufficient); return; } } void IntelPlugin::FillLayerDataToWhite(char *pLayerData, int width, int height) { for (int x=0; xdepth == 8) { unsigned8 *rowData = reinterpret_cast(pLayerData); rowData[indexToLayerChannel] = 255; } else if (ps.formatRecord->depth == 16) { unsigned16 *rowData16bit = reinterpret_cast(pLayerData); rowData16bit[indexToLayerChannel] = ConvertTo16Bit(static_cast(255)); } else if (ps.formatRecord->depth == 32) { float *rowData32bit = reinterpret_cast(pLayerData); rowData32bit[indexToLayerChannel] = 1.0; } } } } /*****************************************************************************/ /*****************************************************************************/ // Copy one component from layer channel to Image void IntelPlugin::CopyFromLayerChannelIntoImage(char *pLayerData, const Image *image, int indexToImage, int indexToLayerChannel) { if (ps.data->encoding_g == DXGI_FORMAT_BC6H_UF16) { //Get pointer to first (and only) image, cast to 16bit for BC6 unsigned16 *rowBigDataPtr = reinterpret_cast(image->pixels); //Copy data from photoshop buffer into scrUncompressedImageScratch //Convert pixels to 16Bit for BC6 encoding if (ps.formatRecord->depth == 8) { unsigned8 *rowData = reinterpret_cast(pLayerData); rowBigDataPtr[indexToImage] = ConvertTo16Bit(rowData[indexToLayerChannel]); } else if (ps.formatRecord->depth == 16) { unsigned16 *rowData16bit = reinterpret_cast(pLayerData); rowBigDataPtr[indexToImage] = ConvertTo16Bit(rowData16bit[indexToLayerChannel]); } else if (ps.formatRecord->depth == 32) { float *rowData32bit = reinterpret_cast(pLayerData); rowBigDataPtr[indexToImage] = ConvertTo16Bit(rowData32bit[indexToLayerChannel]); } } else //BC1,3,7,4,5 or uncompressed (same treatment since we process by existing channel and they are all 8 bit) { //Get pointer to first (and only) image unsigned8 *rowBigDataPtr = image->pixels; //Convert pixels to 8bit for BC encoding if (ps.formatRecord->depth == 8) { unsigned8 *rowData = reinterpret_cast(pLayerData); //Get image pointer rowBigDataPtr[indexToImage] = ConvertTo8Bit(rowData[indexToLayerChannel]); } else if (ps.formatRecord->depth == 16) { unsigned16 *rowData16bit = reinterpret_cast(pLayerData); //Get image pointer rowBigDataPtr[indexToImage] = ConvertTo8Bit(rowData16bit[indexToLayerChannel]); } else if (ps.formatRecord->depth == 32) { float *rowData32bit = reinterpret_cast(pLayerData); //Get image pointer rowBigDataPtr[indexToImage] = ConvertTo8Bit(rowData32bit[indexToLayerChannel]); } } } /*****************************************************************************/ /*****************************************************************************/ //Copy document Layers into mipmap Images of ScratchImage //startMipIndex: specify from which layer to start copy. //endMipIndex: until which layer to copy. You can leave this blank in which case it will copy al remaining layers. //Each layer copies into the corresponding mip map level accorsing to its order from the base layer. void IntelPlugin::CopyLayersIntoMipMaps(ScratchImage *scrUncompressedImageScratch_, bool hasAlpha_, int startMipIndex, int endMipIndex) { int mipMapIndex = startMipIndex; // mip level=0 is original image ReadChannelDesc *pChannel; ReadLayerDesc *layerDesc; char *pLayerData; // Get a buffer to hold each channel as we process, formatRecord->planeBytes are computed the first time fetchImage() is called pLayerData = sPSBuffer->New(NULL, ps.formatRecord->imageSize.h * ps.formatRecord->imageSize.v * ps.formatRecord->planeBytes); if (pLayerData == NULL) { SetResult(memFullErr); return; } //Get the first layer (usually Backround) in this layer list layerDesc = ps.formatRecord->documentInfo->layersDescriptor; //Skip initial layers to startLayerIndex int startLayerIndex = startMipIndex; while (startLayerIndex != 0) { layerDesc = layerDesc->next; startLayerIndex--; } //Cycle through remaining layers, Assign each layer to a different mip map in ScratchImage while ((layerDesc != NULL) && (mipMapIndex <= endMipIndex)) { //There are not enough mip maps in this Image, there are too much layers if (int(scrUncompressedImageScratch_->GetImageCount()) <= mipMapIndex) break; //Get mip map image const Image *image = scrUncompressedImageScratch_->GetImages() + mipMapIndex; if (!image) break; //Get the first channel in this channel list pChannel = layerDesc->compositeChannelsList; int planeNumber = 0; //Get the RGB channels while (pChannel != NULL) { //Get pixel data from channel ReadLayerData(pChannel, pLayerData, ps.formatRecord->imageSize.h, ps.formatRecord->imageSize.v); for (size_t y = 0; y < image->height; y++) { for (size_t x = 0; x < image->width; x++) { int indexToImage = int(image->width*y*4 + x*4); //the ScratchImage is always RGBA therefore pitch of 4 int indexToLayerChannel = int(ps.formatRecord->imageSize.h*y + x); //here the pitch is only 1 CopyFromLayerChannelIntoImage(pLayerData, image, indexToImage+planeNumber, indexToLayerChannel); } } pChannel = pChannel->next; planeNumber++; } //Get first layermask and set as alpha //If no layermask then use transparency channel if (!(pChannel = layerDesc->layerMask)) { //Get first Transparency channel and set as alpha pChannel = layerDesc->transparency; } //Get alpha if (hasAlpha_ && (pChannel != NULL)) { //Get pixel data from channel ReadLayerData(pChannel, pLayerData, ps.formatRecord->imageSize.h, ps.formatRecord->imageSize.v); } else { FillLayerDataToWhite(pLayerData, ps.formatRecord->imageSize.h, ps.formatRecord->imageSize.v); } for (size_t y = 0; y < image->height; y++) { for (size_t x = 0; x < image->width; x++) { int indexToImage = int(image->width*y*4 + x*4); //the ScratchImage is always RGBA therefore pitch of 4 int indexToLayerChannel = int(ps.formatRecord->imageSize.h*y + x); //here the pitch is only 1 //Here the planeumber is 3 for alpha CopyFromLayerChannelIntoImage(pLayerData, image, indexToImage+3, indexToLayerChannel); } } layerDesc = layerDesc->next; //Get next layer mipMapIndex++; //Next mip map } sPSBuffer->Dispose(static_cast(&(pLayerData))); } /*****************************************************************************/ /*****************************************************************************/ //Saves a special mip version of acube map out as a normal cube map. Special function to save out low res cubemaps HRESULT IntelPlugin::SaveCubeMipLevelToDDSFile(ScratchImage *scrImageScratch_, Blob& blob) { //Open a empty uncompressed scratch image ScratchImage customMipLevelScratch; Image customMipLevel[6]; //Get specific mip images for (int i=0; i<6; i++) customMipLevel[i] = *scrImageScratch_->GetImage(ps.data->MipLevel, i, 0); //Init new cube map from these images customMipLevelScratch.InitializeCubeFromImages(customMipLevel, 6); //Save to file return SaveToDDSMemory(customMipLevelScratch.GetImages(), customMipLevelScratch.GetImageCount(), customMipLevelScratch.GetMetadata(), DDS_FLAGS_NONE, blob); } void IntelPlugin::InitData() { memset(ps.data, 0, sizeof(*ps.data)); ps.data->gMultithreaded = GetProcessorCount() > 1; ps.data->encoding_g = DXGI_FORMAT_BC3_UNORM; ps.data->queryForParameters = true; ps.data->TextureTypeIndex = TextureTypeEnum::COLOR; //Col,Col+alpha,CubeFromLayer,CubefromCross,NM ps.data->MipMapTypeIndex = MipmapEnum::NONE; //None,Autogen,FromLayers ps.data->MipLevel=0; // only valid if SetMipLevel == true ps.data->SetMipLevel = false; ps.data->Normalize = false; ps.data->FlipX = false; ps.data->FlipY = false; ps.data->fast_bc67 = false; ps.data->exposure = 1; ps.data->mipmapBatchAllowed = false; ps.data->alphaBatchSeperate = false; } void IntelPlugin::DoWritePrepare() { ps.formatRecord->maxData = 0; //this signifies that we will provide our own buffer ps.formatRecord->layerData = 0; //we dont want the layers handed in separately, we read them ourselfes } void IntelPlugin::DoWriteStart() { InitData(); /* check with the scripting system whether to pop our dialog */ ps.data->queryForParameters = ReadScriptParamsForWrite(); //If Multithreading init win32 threads and events if (ps.data->gMultithreaded) { InitWin32Threads(); } //Show main dialog and get parameters if (OptionsDialog::DoModal(this) != IDOK) SetResult(userCanceledErr); if (GetResult() == noErr) { DoWriteDDS(); } DisposeImageData(); DestroyThreads(); } void IntelPlugin::DoWriteContinue() { // should not be called as data has already been disposed } void IntelPlugin::DoWriteFinish() { // only called if not cancelled WriteScriptParamsForWrite(); // should be different for read/write } //Report error to Photoshop, plugin aborts by itself depicting this error message automatically void IntelPlugin::UserError(const char *usrerror) { unsigned char *pErrorString = reinterpret_cast(ps.formatRecord->errorString); if (pErrorString != NULL && (strlen(usrerror) < 256)) { *ps.resultPtr = errReportString; *pErrorString = unsigned char(strlen(usrerror)); memcpy(pErrorString+1, usrerror, unsigned char(*pErrorString)); } } void IntelPlugin::FetchImageData() { if (!ps.formatRecord->data) { int planesToGet = ps.formatRecord->planes; if (planesToGet > 4) planesToGet = 4; ps.formatRecord->theRect.left = 0; ps.formatRecord->theRect.right = ps.formatRecord->imageSize.h; ps.formatRecord->theRect.top = 0; ps.formatRecord->theRect.bottom = ps.formatRecord->imageSize.v; ps.formatRecord->loPlane = 0; ps.formatRecord->hiPlane = planesToGet - 1; //The offset in bytes between planes of data in the buffers, for 8 bit interleved data this is 1. Doing this operation computes correctly for depth 16,32 etc ps.formatRecord->planeBytes = (ps.formatRecord->depth + 7) >> 3; //The offset in bytes between columns of data in the buffer. usually 1 for non-interleaved data, or hiPlane-loPlane+1 for interleaved data. ps.formatRecord->colBytes = (ps.formatRecord->hiPlane - ps.formatRecord->loPlane + 1) * ps.formatRecord->planeBytes; //The offset in bytes between rows of data in the buffer. ps.formatRecord->rowBytes = ps.formatRecord->colBytes * (ps.formatRecord->theRect.right - ps.formatRecord->theRect.left); // seems we have to allocate for ourselves here because we set maxData to 0 uint32 bufferSize = (ps.formatRecord->theRect.bottom - ps.formatRecord->theRect.top) * ps.formatRecord->rowBytes; if (ps.formatRecord->data = sPSBuffer->New( &bufferSize, bufferSize)) { if (ps.formatRecord->documentInfo->layerCount > 1) { //Because Layermode is enabled for dds mip loading we can not just use the alpha as ususal when there are layers. //RGBA should come from the merged layer data, all this is done in FillFromCompositedLayers(). FillFromCompositedLayers(); } else { SetResult(ps.formatRecord->advanceState()); } } else SetResult(memFullErr); } } void IntelPlugin::DisposeImageData() { if (ps.formatRecord->data) { sPSBuffer->Dispose(reinterpret_cast(&ps.formatRecord->data)); ps.formatRecord->data = NULL; } if (preview.compressedImage) { delete preview.compressedImage; preview.compressedImage = NULL; } if (preview.uncompressedImage) { delete preview.uncompressedImage; preview.uncompressedImage = NULL; } } bool IntelPlugin::SetProgress(int part, int total) { if (ps.formatRecord) { if (ps.data->previewing) // don't do progress if we have UI! Allow cancel though { return !ps.formatRecord->abortProc(); } else { if (ps.formatRecord->progressProc) ps.formatRecord->progressProc(part, total); if (ps.formatRecord->abortProc) { if (ps.formatRecord->abortProc()) // TRUE if user aborted { SetResult(userCanceledErr); return false; } } } } return true; // continue! } /*****************************************************************************/ //Main compression function which calls all other functions and saves dds void IntelPlugin::DoWriteDDS() { if (GetResult() != noErr) return; bool DoMipMaps = ps.data->MipMapTypeIndex == MipmapEnum::AUTOGEN || ps.data->MipMapTypeIndex == MipmapEnum::FROM_LAYERS; //============================================================================================ //============================================================================================ //Setup Photoshop callback structs and what data to get, section bool hasAlpha = HasAlpha(); ScratchImage* scrUncompressedImageScratch = new ScratchImage(); if (!CopyDataForEncoding(scrUncompressedImageScratch, hasAlpha, DoMipMaps, true)) { UserError("Unsupported bit depth"); return; } //============================================================================================ //============================================================================================ //If this is a cube map, change scrUncompressedImageScratch into a CubeMap type image, section if (ps.data->TextureTypeIndex==TextureTypeEnum::CUBEMAP_CROSSED) { ConvertToCubeMapFromCross(&scrUncompressedImageScratch); } else if (ps.data->TextureTypeIndex==TextureTypeEnum::CUBEMAP_LAYERS) { if (!ConvertToCubeMapFromLayers(&scrUncompressedImageScratch, hasAlpha)) { UserError("Cubemap has not enough layers available. Consult the documentation (question mark next to the TextureType drop down) on how to create cubemaps"); return; } } //============================================================================================ //============================================================================================ //MipMap from Layers //Here we overwrite only the initial image MipLevel 0 from Layer 0, in order to generate automatic MipMaps //the second step of MipMap from layers is furter down if (IsMipMapsDefinedByLayer()) { //We use this to avoid having to disable the visibility of all layers when creating mip level 0. //By default all images are composited onto mip level 0 CopyLayersIntoMipMaps(scrUncompressedImageScratch, hasAlpha, 0, 1); } //============================================================================================ //============================================================================================ //If FlipX/Y true, invert R/G channels scrUncompressedImageScratch only if Normal Map, section if ((ps.data->FlipX || ps.data->FlipY) && (ps.data->TextureTypeIndex==TextureTypeEnum::NORMALMAP)) { FlipXYChannelNormalMap(scrUncompressedImageScratch); } //============================================================================================ //============================================================================================ //If MipMaps generate using DirectXTexLib, section //Also force mipmaps if setMipLevels on cube maps are specified if (DoMipMaps || IsCubeMapWithSetMipLevelOverride()) { //Open temporary imageScratch to save mipmaps ScratchImage *scrImageMipMapScratch = new ScratchImage(); DWORD mimapFilter = TEX_FILTER_DEFAULT|TEX_FILTER_SEPARATE_ALPHA; //Use the non Windows Imaging Components path if BC6 due to problems in mipmapping if (ps.data->encoding_g == DXGI_FORMAT_BC6H_UF16) mimapFilter |= TEX_FILTER_FORCE_NON_WIC; //Generate MipMaps from scrUncompressedImageScratch and save to scrImageMipMapScratch HRESULT hr = GenerateMipMaps(scrUncompressedImageScratch->GetImages(), scrUncompressedImageScratch->GetImageCount(), scrUncompressedImageScratch->GetMetadata(), mimapFilter, 0, *scrImageMipMapScratch ); if( hr != S_OK ) { UserError("Could not create MipMaps"); return; } //free previous space delete scrUncompressedImageScratch; //Copy over pointer from ScratchImage which has MipMap, now scrUncompressedImageScratch holds the initial image + mip chain scrUncompressedImageScratch = scrImageMipMapScratch; //MipMap from Layers //If we should get the mip maps from layers then override the existing mip maps with the layer images if (IsMipMapsDefinedByLayer()) { //Copy all Layers starting 1. We omit 0 becasue we already copied it above. CopyLayersIntoMipMaps(scrUncompressedImageScratch, hasAlpha, 1); } } // If Normalization Postprocess option has been specified and this is a Normal Type texture type // Normalize all mip chain if (ps.data->Normalize && ps.data->TextureTypeIndex == TextureTypeEnum::NORMALMAP) NormalizeNormalMapChain(scrUncompressedImageScratch); // Compress scrUncompressedImageScratch into scrImageScratch, section ScratchImage* scrImageScratch = new ScratchImage(); ps.data->previewing = false; if (!CompressToScratchImage(&scrImageScratch, &scrUncompressedImageScratch, hasAlpha)) return; // Save compressed DirectXTex image structure to file, section Blob blob; HRESULT hr; // Save compressed image if (IsCubeMapWithSetMipLevelOverride()) //If setMipLevel on cubemap specified hr = SaveCubeMipLevelToDDSFile(scrImageScratch, blob); else hr = SaveToDDSMemory(scrImageScratch->GetImages(), scrImageScratch->GetImageCount(), scrImageScratch->GetMetadata(), DDS_FLAGS_NONE, blob); if (hr == S_OK) { if (int size = int(blob.GetBufferSize())) { if (!WriteFile(reinterpret_cast(ps.formatRecord->dataFork), blob.GetBufferPointer(), size, reinterpret_cast(&size), NULL)) SetResult(writErr); else if (size < int(blob.GetBufferSize())) SetResult(dskFulErr); } } else UserError("Failed to save"); // Cleanup if (scrImageScratch != NULL) delete scrImageScratch; if (scrUncompressedImageScratch != NULL) delete scrUncompressedImageScratch; } bool IntelPlugin::ReadScriptParamsForWrite() { // Populate this array if we're expecting any keys, // must be NULLID terminated: DescriptorKeyIDArray array = { NULLID }; // Assume we want to pop our dialog unless explicitly told not to: Boolean returnValue = true; auto descParams = ps.formatRecord->descriptorParameters; if (HostDescriptorAvailable(descParams, NULL)) { // descriptor suite is available, go ahead and open descriptor: auto reader = descParams->readDescriptorProcs; // PIUtilities routine to open descriptor handed to us by host: if (PIReadDescriptor token = reader->openReadDescriptorProc(descParams->descriptor, array)) { // token was valid, so read keys from it: DescriptorKeyID key = NULLID; // the next key DescriptorTypeID type = NULLID; // the type of the key we read int32 flags = 0; // any flags for the key while (reader->getKeyProc(token, &key, &type, &flags)) { // got a valid key. Figure out where to put it: switch (key) { // match a key to its expected type:case keyAmount: case keyPreset: reader->getStringProc(token, &(ps.data->presetBatchName)); break; // ignore all other cases and classes // See PIActions.h and PIUtilities.h for // routines and macros for scripting functions. } // key } // PIGetKey // PIUtilities routine that automatically deallocates, // closes, and sets token to NULL: if (OSErr err = HostCloseReader(descParams, ps.formatRecord->handleProcs, &token)) { // an error did occur while we were reading keys: if (err == errMissingParameter) // missedParamErr == -1715 { // missing parameter somewhere. Walk IDarray to find which one. } else { // serious error. Return it as a global result: SetResult(err); } } // stickyError } // didn't have a valid token // Whether we had a valid token or not, we were given information // as to whether to pop our dialog or not. PIUtilities has a routine // to check that and return TRUE if we should pop it, FALSE if not: returnValue = HostPlayDialog(descParams); } // descriptor suite unavailable return !!returnValue; } OSErr IntelPlugin::WriteScriptParamsForWrite (void) { OSErr gotErr = writErr; if (auto descParams = ps.formatRecord->descriptorParameters) { if (auto writeProcs = descParams->writeDescriptorProcs) { if (auto token = writeProcs->openWriteDescriptorProc()) { // now write our data writeProcs->putStringProc(token, keyPreset, ps.data->presetBatchName); sPSHandle->Dispose(descParams->descriptor); PIDescriptorHandle h; writeProcs->closeWriteDescriptorProc(token, &h); descParams->descriptor = h; gotErr = noErr; // we're ok! } } } return gotErr; } bool IntelPlugin::ReadScriptParamsForRead() { // Populate this array if we're expecting any keys, // must be NULLID terminated: DescriptorKeyIDArray array = { NULLID }; // Assume we want to pop our dialog unless explicitly told not to: Boolean returnValue = true; auto descParams = ps.formatRecord->descriptorParameters; if (HostDescriptorAvailable(descParams, NULL)) { // descriptor suite is available, go ahead and open descriptor: auto reader = descParams->readDescriptorProcs; // PIUtilities routine to open descriptor handed to us by host: if (PIReadDescriptor token = reader->openReadDescriptorProc(descParams->descriptor, array)) { // token was valid, so read keys from it: DescriptorKeyID key = NULLID; // the next key DescriptorTypeID type = NULLID; // the type of the key we read int32 flags = 0; // any flags for the key Boolean mipFlag = false; Boolean alphaFlag = false; while (reader->getKeyProc(token, &key, &type, &flags)) { // got a valid key. Figure out where to put it: switch (key) { // match a key to its expected type:case keyAmount: case keyMipMap: reader->getBooleanProc(token, &mipFlag); ps.data->mipmapBatchAllowed = !!mipFlag; //conve form Boolean to bool break; case keyAlphaS: reader->getBooleanProc(token, &alphaFlag); ps.data->alphaBatchSeperate = !!alphaFlag; //conve form Boolean to bool break; // ignore all other cases and classes // See PIActions.h and PIUtilities.h for // routines and macros for scripting functions. } // key } // PIGetKey // PIUtilities routine that automatically deallocates, // closes, and sets token to NULL: if (OSErr err = HostCloseReader(descParams, ps.formatRecord->handleProcs, &token)) { // an error did occur while we were reading keys: if (err == errMissingParameter) // missedParamErr == -1715 { // missing parameter somewhere. Walk IDarray to find which one. } else { // serious error. Return it as a global result: SetResult(err); } } // stickyError } // didn't have a valid token // Whether we had a valid token or not, we were given information // as to whether to pop our dialog or not. PIUtilities has a routine // to check that and return TRUE if we should pop it, FALSE if not: returnValue = HostPlayDialog(descParams); } // descriptor suite unavailable return !!returnValue; //auto descParams = ps.formatRecord->descriptorParameters; //return descParams->playInfo == plugInDialogDisplay; } OSErr IntelPlugin::WriteScriptParamsForRead () { OSErr gotErr = writErr; if (auto descParams = ps.formatRecord->descriptorParameters) { if (auto writeProcs = descParams->writeDescriptorProcs) { if (auto token = writeProcs->openWriteDescriptorProc()) { // now write our data Boolean temp = ps.data->mipmapBatchAllowed; writeProcs->putBooleanProc(token, keyMipMap, temp); temp = ps.data->alphaBatchSeperate; writeProcs->putBooleanProc(token, keyAlphaS, temp); sPSHandle->Dispose(descParams->descriptor); PIDescriptorHandle h; writeProcs->closeWriteDescriptorProc(token, &h); descParams->descriptor = h; gotErr = noErr; // we're ok! } } } return gotErr; } void IntelPlugin::DoFilterFile (void) { // File can be tested for validity here //SetResult(formatCannotRead); SetResult(noErr); } void IntelPlugin::DoReadPrepare() { ps.formatRecord->maxData = 0; loadInfo.isCubeMap = false; loadInfo.readImagePtr = NULL; loadInfo.loadMipMapIndex = 0; loadInfo.hasMips = false; loadInfo.hasAlpha = false; } void IntelPlugin::DoReadStart() { LARGE_INTEGER fileSize; showLoadingCursor(); //Read any descriptor values for scripting support and return if we are in batch mode. ps.data->queryForParameters = ReadScriptParamsForRead(); //Rewind to start of file OSErr err= PSSDKSetFPos (ps.formatRecord->dataFork, fsFromStart, 0); if (err != noErr) { SetResult(err); showNormalCursor(); return; } //Get filesize GetFileSizeEx(reinterpret_cast(ps.formatRecord->dataFork), &fileSize); //Allocate buffer equal filesize uint8 *wholeFileBuffer = new uint8[size_t(fileSize.QuadPart)]; int32 readCount = int32(fileSize.QuadPart); //ReadIn whole file err = PSSDKRead (ps.formatRecord->dataFork, &readCount, wholeFileBuffer); if (err != noErr) { SetResult(err); showNormalCursor(); return; } //If not enough bytes read, error if (err == noErr && readCount != fileSize.QuadPart) { SetResult(eofErr); showNormalCursor(); return; } //Load DDS from memory ScratchImage *ddsCompressedImage = new ScratchImage; TexMetadata readImageInfo; HRESULT hr = LoadFromDDSMemory( wholeFileBuffer, readCount, DDS_FLAGS_NONE, &readImageInfo, *ddsCompressedImage); //Check if the image suports alpha. Note For DX, BC1 supports alpha for us not bool alphaIsWhite = ddsCompressedImage->IsAlphaAllOpaque(); bool compressedImageHasAlpha = (DirectX::HasAlpha(readImageInfo.format) && !alphaIsWhite && readImageInfo.format != DXGI_FORMAT_BC1_UNORM && readImageInfo.format != DXGI_FORMAT_BC1_UNORM_SRGB); loadInfo.hasAlpha = compressedImageHasAlpha; //Check if there are mip maps bool compressedImageHasMipMaps = (readImageInfo.mipLevels > 1) ? true : false; bool separateAlphaChannel = ps.data->alphaBatchSeperate; //get predefined values for batching from descriptors in ReadScriptParamsForRead() bool loadDDSMipMaps = ps.data->mipmapBatchAllowed; //get predefined values for batching from descriptors in ReadScriptParamsForRead bool compressedImageIsCubemap = (readImageInfo.arraySize == 6) ? true : false; //For cube maps disable alpha and mip maps for now if (compressedImageIsCubemap) { compressedImageHasAlpha = compressedImageHasMipMaps = false; separateAlphaChannel = false; } //Show load dialog //Do we need the user to make a selection regarding alpha or mip maps? if (compressedImageHasAlpha || compressedImageHasMipMaps) { //ask user if he wants them, and not in batch if (ps.data->queryForParameters) { unsigned8 loadDialogResult = ShowLoadDialog (compressedImageHasAlpha, compressedImageHasMipMaps, GetActiveWindow()); //decode result separateAlphaChannel = (loadDialogResult & LoadInfoEnum::USE_SEPARATEALPHA) ? true : false; loadDDSMipMaps = (loadDialogResult & LoadInfoEnum::USE_MIPMAPS) ? true : false; //store descriptor values for scripting. Actual write happens in DoReadFinish() ps.data->alphaBatchSeperate = separateAlphaChannel; ps.data->mipmapBatchAllowed = loadDDSMipMaps; } } //init to no layers ps.formatRecord->layerData = 0; //Do we have mip maps, is this a cube map, or a simple image if (compressedImageIsCubemap) { //Cube map loadInfo.isCubeMap = true; ps.formatRecord->layerData = 6; //specify the creatoin of six layers } else if (compressedImageHasMipMaps) { //Image has mip maps if (loadDDSMipMaps) { loadInfo.hasMips = true; ps.formatRecord->layerData = uint32(readImageInfo.mipLevels); //specify creation of layers } } //By default we use layer transparency when the image has alpha, but when the separatealpha flag //is set we use the background image with a dedicated alpha channel if (!separateAlphaChannel && compressedImageHasAlpha && ps.formatRecord->layerData == 0) { ps.formatRecord->layerData = 1; } // pick a target format auto targetFormat = DXGI_FORMAT_R8G8B8A8_UNORM; if (readImageInfo.format == DXGI_FORMAT_BC6H_SF16 || readImageInfo.format == DXGI_FORMAT_BC6H_UF16) // 16 bit short floats targetFormat = DXGI_FORMAT_R32G32B32A32_FLOAT; else if (BitsPerColor(readImageInfo.format) > 16) targetFormat = DXGI_FORMAT_R32G32B32A32_FLOAT; else if (BitsPerColor(readImageInfo.format) > 8) targetFormat = DXGI_FORMAT_R16G16B16A16_UNORM; else if (IsSRGB(readImageInfo.format)) targetFormat = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB; // Is it already in the correct format? if (readImageInfo.format == targetFormat) { // No conversion required, just swap pointers loadInfo.readImagePtr = ddsCompressedImage; ddsCompressedImage = NULL; } else { loadInfo.readImagePtr = new ScratchImage(); if (IsCompressed(readImageInfo.format)) // is it compressed? hr = Decompress( ddsCompressedImage->GetImages(), ddsCompressedImage->GetImageCount(), ddsCompressedImage->GetMetadata(), targetFormat, *loadInfo.readImagePtr); else hr = Convert( ddsCompressedImage->GetImages(), ddsCompressedImage->GetImageCount(), ddsCompressedImage->GetMetadata(), targetFormat, 0, 0, *loadInfo.readImagePtr); } if ( FAILED(hr) ) { UserError("Can not load image."); delete loadInfo.readImagePtr; delete ddsCompressedImage; delete[] wholeFileBuffer; showNormalCursor(); return; } // update the metadata readImageInfo = loadInfo.readImagePtr->GetMetadata(); //Setup formatRecord for loading ps.formatRecord->imageRsrcData = NULL; ps.formatRecord->imageRsrcSize = 0; ps.formatRecord->imageMode = plugInModeRGBColor; if (ps.formatRecord->HostSupports32BitCoordinates && ps.formatRecord->PluginUsing32BitCoordinates) { ps.formatRecord->imageSize32.v = static_cast(readImageInfo.height); ps.formatRecord->imageSize32.h = static_cast(readImageInfo.width); } else { ps.formatRecord->imageSize.v = static_cast(readImageInfo.height); ps.formatRecord->imageSize.h = static_cast(readImageInfo.width); } ps.formatRecord->depth = int(BitsPerColor(targetFormat)); if (separateAlphaChannel) { ps.formatRecord->planes = compressedImageHasAlpha ? 4 : 3; // 4 channels for alpha ps.formatRecord->transparencyPlane = 3; } else { ps.formatRecord->planes = (ps.formatRecord->layerData > 0) ? 4 : 3; // layers have alpha, background not so much ps.formatRecord->transparencyPlane = 3; } ps.formatRecord->transparencyMatting = 0; //Cleanup delete[] wholeFileBuffer; if (ddsCompressedImage) delete ddsCompressedImage; } void IntelPlugin::DoReadContinue() { //Prepare formatRecord to get whole image ps.formatRecord->loPlane = 0; ps.formatRecord->hiPlane = ps.formatRecord->planes - 1; ps.formatRecord->theRect.left = 0; ps.formatRecord->theRect.right = ps.formatRecord->imageSize.h; ps.formatRecord->theRect.top = 0; ps.formatRecord->theRect.bottom = ps.formatRecord->imageSize.v; //The offset in BYTES between planes of data in the buffers, for 8 bit interleved data this is 1. Doing this operation computes correctly for depth 16 bit, 32 bit etc ps.formatRecord->planeBytes = (ps.formatRecord->depth + 7) >> 3; //The offset in bytes between columns of data in the buffer. usually 1 for non-interleaved data, or hiPlane-loPlane+1 for interleaved data. ps.formatRecord->colBytes = (ps.formatRecord->hiPlane - ps.formatRecord->loPlane + 1) * ps.formatRecord->planeBytes; //The offset in bytes between rows of data in the buffer. ps.formatRecord->rowBytes = ps.formatRecord->colBytes * (ps.formatRecord->theRect.right - ps.formatRecord->theRect.left); //Allocate buffer for ->data field //seems we have to allocate for ourselves here because we set maxData to 0 uint32 bufferSize = (ps.formatRecord->theRect.bottom - ps.formatRecord->theRect.top) * ps.formatRecord->rowBytes; Ptr pixelData = sPSBuffer->New( &bufferSize, bufferSize ); if (pixelData == NULL) { SetResult(memFullErr); return; } else { memset(pixelData, 0, bufferSize); //init buffer to 0 //Assign buffer to photoshop buffer ps.formatRecord->data = pixelData; } //Get pointer to image const Image *img; //Get the right image for this iteration (this function is called multiple times in case of mips or cube map) if (loadInfo.isCubeMap) { //Cube map load six images as layers img = loadInfo.readImagePtr->GetImage(0, loadInfo.loadMipMapIndex, 0); loadInfo.loadMipMapIndex++; } else if (loadInfo.hasMips) { //Load image maps as layers img = loadInfo.readImagePtr->GetImage(loadInfo.loadMipMapIndex, 0, 0); loadInfo.loadMipMapIndex++; } else { //Normal single mip image img= loadInfo.readImagePtr->GetImages(); } //Now copy image into photoshop buffer unsigned8 *rowSrcDataPtr = img->pixels; unsigned8 *rowTgtDataPtr = reinterpret_cast(pixelData); for (size_t y=0; yheight; y++) { for (size_t x=0; xwidth; x++) { switch (img->format) { case DXGI_FORMAT_R8G8B8A8_UNORM: case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: { unsigned8 *src = rowSrcDataPtr + y * img->rowPitch + x * 4; unsigned8 *dst = rowTgtDataPtr + y * ps.formatRecord->rowBytes + x * ps.formatRecord->colBytes; for (int p=0; pplanes; p++) { dst[p] = src[p]; //If we are loading a cube map face then force alpha to white if (loadInfo.isCubeMap && loadInfo.hasAlpha) dst[ps.formatRecord->planes-1] = 255; } } break; case DXGI_FORMAT_R16G16B16A16_UNORM: { const uint16 *src = reinterpret_cast(rowSrcDataPtr + y * img->rowPitch + x * 8); uint16 *dst = reinterpret_cast(rowTgtDataPtr + y * ps.formatRecord->rowBytes + x * ps.formatRecord->colBytes); for (int p=0; pplanes; p++) { dst[p] = src[p]; //If we are loading a cube map face then force alpha to white if (loadInfo.isCubeMap && loadInfo.hasAlpha) dst[ps.formatRecord->planes-1] = ConvertTo16Bit(static_cast(255)); } } break; case DXGI_FORMAT_R32G32B32A32_FLOAT: // any hdr should be decompressed to this format if possible { const float *src = reinterpret_cast(rowSrcDataPtr + y * img->rowPitch + x * 16); float *dst = reinterpret_cast(rowTgtDataPtr + y * ps.formatRecord->rowBytes + x * ps.formatRecord->colBytes); for (int p=0; pplanes; p++) { dst[p] = src[p]; //If we are loading a cube map face then force alpha to white if (loadInfo.isCubeMap && loadInfo.hasAlpha) dst[ps.formatRecord->planes-1] = 1.0f; } } break; default: // not recognized break; } } } SetResult(ps.formatRecord->advanceState()); //Cleanup ps.formatRecord->data = NULL; sPSBuffer->Dispose(&pixelData); } void IntelPlugin::DoReadFinish() { delete loadInfo.readImagePtr; loadInfo.readImagePtr = NULL; WriteScriptParamsForRead(); showNormalCursor(); } void IntelPlugin::DoReadLayerStart() { static uint16 gLayerNameUtf16[10]; char gLayerNameAscii[10]; int i=0; //Assign layer names if (loadInfo.hasMips) { //Create mip layer name sprintf(gLayerNameAscii,"Mip%d", loadInfo.loadMipMapIndex); do { gLayerNameUtf16[i] = gLayerNameAscii[i]; i++; } while (gLayerNameAscii[i] != '\0'); gLayerNameUtf16[i] = '\0'; ps.formatRecord->layerName = gLayerNameUtf16; } else if (loadInfo.isCubeMap) { char* facesmap[] = {"+X","-X","+Y","-Y","+Z","-Z"}; sprintf(gLayerNameAscii,"%s", facesmap[loadInfo.loadMipMapIndex]); do { gLayerNameUtf16[i] = gLayerNameAscii[i]; i++; } while (gLayerNameAscii[i] != '\0'); gLayerNameUtf16[i] = '\0'; ps.formatRecord->layerName = gLayerNameUtf16; } else { //ps.formatRecord->layerName = L"Layer 0"; } } //------------------------------------------------------------------------------- // // CreateDataHandle // // Create a handle to our Data structure. Photoshop will take ownership of this // handle and delete it when necessary. //------------------------------------------------------------------------------- void IntelPlugin::CreateDataHandle(void) { Handle h = sPSHandle->New(sizeof(Globals)); if (h != NULL) *ps.dataPtr = reinterpret_cast(h); else *ps.resultPtr = memFullErr; } //------------------------------------------------------------------------------- // // LockHandles // // Lock the handles and get the pointers for data // Set the global error, *ps.resultPtr, if there is trouble // //------------------------------------------------------------------------------- void IntelPlugin::LockHandles(void) { if ( ! (*ps.dataPtr) ) { *ps.resultPtr = formatBadParameters; return; } Boolean oldLock = FALSE; sPSHandle->SetLock(reinterpret_cast(*ps.dataPtr), true, reinterpret_cast(&ps.data), &oldLock); if (ps.data == NULL) { *ps.resultPtr = memFullErr; return; } } //------------------------------------------------------------------------------- // // UnlockHandles // // Unlock the handles used by the data and params pointers // //------------------------------------------------------------------------------- void IntelPlugin::UnlockHandles(void) { Boolean oldLock = FALSE; if (*ps.dataPtr) sPSHandle->SetLock(reinterpret_cast(*ps.dataPtr), false, reinterpret_cast(&ps.data), &oldLock); } void IntelPlugin::PluginMain(const int16 selector, FormatRecordPtr formatRecord, intptr_t * data, int16 * result) { //--------------------------------------------------------------------------- // Store persistent data //--------------------------------------------------------------------------- ps.formatRecord = formatRecord; ps.pluginRef = reinterpret_cast(formatRecord->plugInRef); ps.resultPtr = result; ps.dataPtr = data; //--------------------------------------------------------------------------- // (2) Check for about box request. // // The about box is a special request; the parameter block is not filled // out, none of the callbacks or standard data is available. Instead, // the parameter block points to an AboutRecord, which is used // on Windows. //--------------------------------------------------------------------------- if (selector == formatSelectorAbout) { AboutRecordPtr aboutRecord = reinterpret_cast(formatRecord); sSPBasic = aboutRecord->sSPBasic; ShowAboutIntel(aboutRecord); } else { // do the rest of the process as normal: sSPBasic = ps.formatRecord->sSPBasic; if (formatRecord->advanceState == NULL) { *ps.resultPtr = errPlugInHostInsufficient; return; } // new for Photoshop 8, big documents, rows and columns are now > 30000 pixels //if (formatRecord->HostSupports32BitCoordinates) // formatRecord->PluginUsing32BitCoordinates = true; //----------------------------------------------------------------------- // (3) Allocate and initalize ps.data. // //----------------------------------------------------------------------- if ( ! (*ps.dataPtr) ) { CreateDataHandle(); if (*ps.resultPtr != noErr) return; LockHandles(); if (*ps.resultPtr != noErr) return; InitData(); } if (*ps.resultPtr == noErr) { LockHandles(); if (*ps.resultPtr != noErr) return; } //----------------------------------------------------------------------- // (4) Dispatch selector. //----------------------------------------------------------------------- switch (selector) { case formatSelectorReadPrepare: DoReadPrepare(); break; case formatSelectorReadStart: DoReadStart(); break; case formatSelectorReadContinue: DoReadContinue(); //This is run when no layers are set break; case formatSelectorReadFinish: DoReadFinish(); break; case formatSelectorOptionsPrepare: ps.formatRecord->maxData = 0; break; case formatSelectorOptionsStart: ps.formatRecord->data = NULL; break; case formatSelectorOptionsContinue: break; case formatSelectorOptionsFinish: break; // estimations case formatSelectorEstimatePrepare: ps.formatRecord->maxData = 0; break; case formatSelectorEstimateStart: { int dataBytes = ps.formatRecord->imageSize32.h * ps.formatRecord->imageSize32.v; formatRecord->minDataBytes = dataBytes >> 1; formatRecord->maxDataBytes = dataBytes * 4; formatRecord->data = NULL; } break; case formatSelectorEstimateContinue: break; case formatSelectorEstimateFinish: break; case formatSelectorWritePrepare: DoWritePrepare(); break; case formatSelectorWriteStart: DoWriteStart(); break; case formatSelectorWriteContinue: DoWriteContinue(); break; case formatSelectorWriteFinish: DoWriteFinish(); break; case formatSelectorFilterFile: DoFilterFile(); break; case formatSelectorReadLayerStart: DoReadLayerStart(); break; case formatSelectorReadLayerContinue: DoReadContinue(); //this is run when layers are set break; case formatSelectorReadLayerFinish: break; case formatSelectorWriteLayerStart: break; case formatSelectorWriteLayerContinue: break; case formatSelectorWriteLayerFinish: break; } //----------------------------------------------------------------------- // (5) Unlock data, and exit resource. // // Result is automatically returned in *result, which is // pointed to by ps.resultPtr. //----------------------------------------------------------------------- UnlockHandles(); } // about selector special // release any suites that we may have acquired if (selector == formatSelectorAbout || selector == formatSelectorWriteFinish || selector == formatSelectorReadFinish || selector == formatSelectorOptionsFinish || selector == formatSelectorEstimateFinish || selector == formatSelectorFilterFile || *ps.resultPtr != noErr) { PIUSuitesRelease(); } } DLLExport MACPASCAL void PluginMain (const int16 selector, FormatRecordPtr formatRecord, intptr_t * data, int16 * result) { try { IntelPlugin::GetInstance().PluginMain(selector, formatRecord, data, result); } catch(...) { if (NULL != result) *result = -1; } } // end PluginMain //Fill ps.formatRecord->data with the mergedLayers. void IntelPlugin::FillFromCompositedLayers() { ReadChannelDesc *pChannel; char *pLayerData; int planesToGet_ = ps.formatRecord->hiPlane - ps.formatRecord->loPlane + 1; // Get a buffer to hold each channel as we process, formatRecord->planeBytes are computed the first time fetchImage() is called pLayerData = sPSBuffer->New(NULL, ps.formatRecord->imageSize.h * ps.formatRecord->imageSize.v * ps.formatRecord->planeBytes); if (pLayerData == NULL) { SetResult(memFullErr); return; } //Get the composite channel in this channel list pChannel = ps.formatRecord->documentInfo->mergedCompositeChannels; int planeNumber = 0; //Copy the RGB channels while (pChannel != NULL) { //Get pixel data from channel ReadLayerData(pChannel, pLayerData, ps.formatRecord->imageSize.h, ps.formatRecord->imageSize.v); ///Copy int data rgb for (size_t y = 0; y < ps.formatRecord->imageSize.v; y++) { for (size_t x = 0; x < ps.formatRecord->imageSize.h; x++) { int indexToImage = static_cast(ps.formatRecord->imageSize.h*y*planesToGet_ + x*planesToGet_); //the ScratchImage is always RGBA therefore pitch of 4 int indexToLayerChannel = static_cast(ps.formatRecord->imageSize.h*y + x); //here the pitch is only 1 if (ps.formatRecord->depth == 8) { unsigned8 *rowBigDataPtr = (unsigned8 *)ps.formatRecord->data; unsigned8 *rowData = reinterpret_cast(pLayerData); //Get image pointer rowBigDataPtr[indexToImage+planeNumber] = rowData[indexToLayerChannel]; } else if (ps.formatRecord->depth == 16) { unsigned16 *rowBigDataPtr = (unsigned16 *)ps.formatRecord->data; unsigned16 *rowData = reinterpret_cast(pLayerData); //Get image pointer rowBigDataPtr[indexToImage+planeNumber] = rowData[indexToLayerChannel]; } else if (ps.formatRecord->depth == 32) { float *rowBigDataPtr = (float *)ps.formatRecord->data; float *rowData = reinterpret_cast(pLayerData); //Get image pointer rowBigDataPtr[indexToImage+planeNumber] = rowData[indexToLayerChannel]; } } } pChannel = pChannel->next; planeNumber++; } //Get first alpha channel and set as alpha, of not get transparency planes if (!(pChannel = ps.formatRecord->documentInfo->alphaChannels)) { pChannel = ps.formatRecord->documentInfo->mergedTransparency; } //Copy alpha if ((ps.formatRecord->planes > 3) && (pChannel != NULL)) { //Get pixel data from channel ReadLayerData(pChannel, pLayerData, ps.formatRecord->imageSize.h, ps.formatRecord->imageSize.v); //Copy into data alpha for (size_t y = 0; y < ps.formatRecord->imageSize.v; y++) { for (size_t x = 0; x < ps.formatRecord->imageSize.h; x++) { int indexToImage = static_cast(ps.formatRecord->imageSize.h*y*planesToGet_ + x*planesToGet_); //the ScratchImage is always RGBA therefore pitch of 4 int indexToLayerChannel = static_cast(ps.formatRecord->imageSize.h*y + x); //here the pitch is only 1 //Here the planeumber is 3 for alpha if (ps.formatRecord->depth == 8) { unsigned8 *rowBigDataPtr = (unsigned8 *)ps.formatRecord->data; unsigned8 *rowData = reinterpret_cast(pLayerData); //Get image pointer rowBigDataPtr[indexToImage+3] = rowData[indexToLayerChannel]; } else if (ps.formatRecord->depth == 16) { unsigned16 *rowBigDataPtr = (unsigned16 *)ps.formatRecord->data; unsigned16 *rowData = reinterpret_cast(pLayerData); //Get image pointer rowBigDataPtr[indexToImage+3] = rowData[indexToLayerChannel]; } else if (ps.formatRecord->depth == 32) { float *rowBigDataPtr = (float *)ps.formatRecord->data; float *rowData = reinterpret_cast(pLayerData); //Get image pointer rowBigDataPtr[indexToImage+3] = rowData[indexToLayerChannel]; } } } } sPSBuffer->Dispose(static_cast(&pLayerData)); } ================================================ FILE: IntelCompressionPlugin/IntelPlugin.h ================================================ //////////////////////////////////////////////////////////////////////////////// // Copyright 2017 Intel Corporation // // Licensed under the Apache License, Version 2.0 (the "License"); you may not // use this file except in compliance with the License. You may obtain a copy // of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the // License for the specific language governing permissions and limitations // under the License. //////////////////////////////////////////////////////////////////////////////// #pragma once #include "IntelPluginName.h" #include // Export Photoshop header file. #include // SDK Utility library. #include #include #include #include #include #include inline float F16toF32(unsigned short f16) { return DirectX::PackedVector::XMConvertHalfToFloat(f16); } inline unsigned short F32toF16(float val) { return DirectX::PackedVector::XMConvertFloatToHalf(val); } inline unsigned char FloatToByte(double v) { if (v > 1) return 255; else if (v < 0) return 0; return static_cast(v * 255); } inline unsigned char F16toByte(unsigned short f16) { return FloatToByte(F16toF32(f16)); } //Three different convert to 8bit functions (8->8, 16->8, 32->8 all photoshop specific) inline unsigned8 ConvertTo8Bit(unsigned8 val) { return val; } inline unsigned8 ConvertTo8Bit(unsigned16 val) { //Photoshop uses an internal representation of 16 bit data of 0 - 32768 double max_16bitPhotoshop = 32768; return FloatToByte(val/max_16bitPhotoshop); } inline unsigned8 ConvertTo8Bit(double val, bool gammaCorrect=true) { //Photoshop uses for 32 bit a gamma of 1.0. So do gamma adjustment for gamma 2.2 //Avoid gamma corrrection for preview if (gammaCorrect) val = pow(val, 1/2.2); return FloatToByte(val); } //Three different 16bit functions (8->16, 16->16, 32->16 all photoshop specific) inline unsigned16 ConvertTo16Bit(unsigned8 val) { return F32toF16(val/255.f); } inline unsigned16 ConvertTo16Bit(unsigned16 val) { //Photoshop uses an internal representation of 16 bit data of 0 - 32768 double max_16bitPhotoshop = 32768; return F32toF16(static_cast(val/max_16bitPhotoshop)); } inline unsigned16 ConvertTo16Bit(float val) { //Photoshop uses for 32 bit a gamma of 1.0. So do gamma adjustment for gamma 2.2. //Avoid gamma corrrection for preview //if (gammaCorrect) // val = pow(val, 1/2.2); return F32toF16(val); } enum TextureTypeEnum { COLOR, COLOR_ALPHA, CUBEMAP_LAYERS, CUBEMAP_CROSSED, NORMALMAP, TEXTURE_TYPE_COUNT }; enum MipmapEnum { NONE, AUTOGEN, FROM_LAYERS }; enum LoadInfoEnum { USE_NONE = 0x0, USE_MIPMAPS = 0x1, USE_SEPARATEALPHA = 0x2 }; enum CompressionTypeEnum { BC1, BC1_SRGB, BC3, BC3_SRGB, BC6H_FAST, BC6H_FINE, BC7_FAST, BC7_FINE, BC7_SRGB_FAST, BC7_SRGB_FINE, BC4, BC5, UNCOMPRESSED, COMPRESSION_TYPE_COUNT }; class IntelPlugin { public: // This is our structure that we use to pass globals between routines: struct Globals { Boolean queryForParameters; Boolean sameNames; PSBufferSuite2 *sPSBufferSuite64; PSColorSpaceSuite2 *sPSColorSpaceSuite64; bool gMultithreaded; DXGI_FORMAT encoding_g; //Which encoding to use bool fast_bc67; //Use fast encoding, else use fine, only valid for BC6 and BC7 TextureTypeEnum TextureTypeIndex; //Col,Col+alpha,CubeFrmLayera,CubefromCross,NM MipmapEnum MipMapTypeIndex; //None,Autogen,FromLayers uint32 MipLevel; // only valid if SetMipLevel == true, specified the mip level to be exported when in cube map mode. bool SetMipLevel; //Specify that a specific mip level has to be exported. Only valid for cube map mode. float exposure; // multiplier for HDR viewing (and downsampling) // normal map processing bool Normalize; //Specify if normalization of values is needed. Only valid for Normal Maps bool FlipX; bool FlipY; //Name of used preset for Descriptor parameter and batching Str255 presetBatchName; bool mipmapBatchAllowed; bool alphaBatchSeperate; // quick way to tell if we are currently showing preview UI bool previewing; }; private: struct { FormatRecordPtr formatRecord; SPPlugin* pluginRef; int16* resultPtr; intptr_t* dataPtr; Globals* data; } ps; struct { // state at which previews were generated TextureTypeEnum textureType; MipmapEnum mipMap; bool flipRChannel; bool flipGChannel; DXGI_FORMAT encoding; uint32 mipLevel; bool fastBc67; DirectX::ScratchImage *compressedImage, *uncompressedImage; int compressedSize; int width, height; } preview; struct { DirectX::ScratchImage *readImagePtr; int loadMipMapIndex; bool isCubeMap; bool hasMips; bool hasAlpha; } loadInfo; public: FormatRecordPtr GetFormatRecord() const { return ps.formatRecord; } Globals* GetData() const { return ps.data; } int16 GetResult() const { return ps.resultPtr ? *ps.resultPtr : 0; } void SetResult(int e) { if (ps.resultPtr) *ps.resultPtr = static_cast(e); } //Decide which combination are valid, based in the CompressionVsTextureTypeMatrix table static bool IsCombinationValid(TextureTypeEnum textype, CompressionTypeEnum comptype); //Preview functions. AdvanceState () has to be called before entering this function so that the globals->exportParamBlock->data buffer is full; DirectX::ScratchImage* GetCompressedImageForPreview(int planesToGet_, int &compressedSize); DirectX::ScratchImage* GetUncompressedImageForPreview(int planesToGet_); //Copy data from photoshop buffer into scrUncompressedImageScratch_ bool CopyDataForEncoding(DirectX::ScratchImage *scrUncompressedImageScratch_, bool hasAlpha_, bool DoMipMaps_, bool gammaCorrect); //Take an Uncompressed DirectX::ScratchImage scrUncompressedImageScratch_ and Compresses it into scrImageScratch_ bool CompressToScratchImage(DirectX::ScratchImage **scrImageScratch_, DirectX::ScratchImage **scrUncompressedImageScratch_, bool hasAlpha_); //Conversion functions from Photoshop buffer to 8bit/16bit ready encoding buffer bool ConvertToBC6From8Bit(unsigned16 *tgtDataPtr, int planesToGet, bool hasAlphaChannel); bool ConvertToBC6From16Bit(unsigned16 *tgtDataPtr, int planesToGet, bool hasAlphaChannel); bool ConvertToBC6From32Bit(unsigned16 *tgtDataPtr, int planesToGet, bool hasAlphaChannel); bool ConvertToBC4or5From32Bit(unsigned8 *tgtDataPtr, int planesToGet, bool hasAlphaChannel, bool gammaCorrect); bool ConvertToBC4or5From16Bit(unsigned8 *tgtDataPtr, int planesToGet, bool hasAlphaChannel); bool ConvertToBC4or5From8Bit(unsigned8 *tgtDataPtr, int planesToGet, bool hasAlphaChannel); bool ConvertToBCFrom32Bit(unsigned8 *tgtDataPtr, int planesToGet, bool hasAlphaChannel, bool gammaCorrect); bool ConvertToBCFrom16Bit(unsigned8 *tgtDataPtr, int planesToGet, bool hasAlphaChannel); bool ConvertToBCFrom8Bit(unsigned8 *tgtDataPtr, int planesToGet, bool hasAlphaChannel); enum PREVIEW_OPTIONS { PREVIEW_SOURCE_ORIGINAL = 0x0, PREVIEW_SOURCE_COMPRESSED = 0x1, PREVIEW_SOURCE_MASK = 0x3, PREVIEW_CHANNEL_RED = 0x4, PREVIEW_CHANNEL_GREEN = 0x8, PREVIEW_CHANNEL_BLUE = 0x10, PREVIEW_CHANNEL_ALPHA = 0x20, PREVIEW_CHANNEL_RGB = PREVIEW_CHANNEL_RED | PREVIEW_CHANNEL_GREEN | PREVIEW_CHANNEL_BLUE, PREVIEW_CHANNEL_RGBA = PREVIEW_CHANNEL_RED | PREVIEW_CHANNEL_GREEN | PREVIEW_CHANNEL_BLUE | PREVIEW_CHANNEL_ALPHA, PREVIEW_CHANNEL_MASK = PREVIEW_CHANNEL_RGBA, }; // returns byte size of entire image void FetchPreviewRGB(unsigned8* dst, int width, int height, int x, int y, double zoom, int previewOptions = PREVIEW_SOURCE_ORIGINAL | PREVIEW_CHANNEL_RGB, int matteColor = 0); POINT GetPreviewDimensions(); int GetCompressedByteSize(); int GetOriginalBitsPerPixel(); int GetOriginalByteSize(); int GetLayerCount(); //Copy from layer channel to Image void CopyFromLayerChannelIntoImage(char *pLayerData, const DirectX::Image *image, int indexToImage, int indexToLayerChannel); //Copy document Layers into mipmap Images of ScratchImage void CopyLayersIntoMipMaps(DirectX::ScratchImage *scrUncompressedImageScratch_, bool hasAlpha_, int startMipIndex, int endMipIndex=INT_MAX); //Compress rgba_surface into tgtPixels, uisng Intel ISPC encoders bool ISPC_compression(rgba_surface &input_rgba, const DirectX::Image& target, bool hasAlpha_rgba); //Pad the surface size to boundaries of 4 rgba_surface DoPaddingToMultiplesOf4(const rgba_surface &input); //Return true if texture type cube maps and the setMipLevel is checked bool IsCubeMapWithSetMipLevelOverride(); //Returns true if mip maps are defined by layers bool IsMipMapsDefinedByLayer(); //Convert scrUncompressedImageScratch_ from a crossed layout image to a cube map DirectX::ScratchImage void ConvertToCubeMapFromCross(DirectX::ScratchImage **scrUncompressedImageScratch_); //Convert scrUncompressedImageScratch_ from document layers to a cube map DirectX::ScratchImage bool ConvertToCubeMapFromLayers(DirectX::ScratchImage **scrUncompressedImageScratch_, bool hasAlpha_); //Convert scrUncompressedImageScratch_ from a cube map to a horizontal crossed layout image void ConvertToHorizontalCrossFromCubeMap(DirectX::ScratchImage **scrUncompressedImageScratch_); //Flip the X(Red) channel and or the Y(Green) channel of thei normal map void FlipXYChannelNormalMap(DirectX::ScratchImage *scrUncompressedImageScratch_); //Normalize all values of this Nomral map in main image and all mip maps void NormalizeNormalMapChain(DirectX::ScratchImage *scrUncompressedImageScratch_); //Saves a special mip version of acube map out as a normal cube map. Special function to save out low res cubemaps HRESULT SaveCubeMipLevelToDDSFile(DirectX::ScratchImage* scrImageScratch_, DirectX::Blob& blob); //Copy from layer Channel into a buffer void ReadLayerData(ReadChannelDesc *pChannel, char *pLayerData, int width, int height); void FillLayerDataToWhite(char *pLayerData, int width, int height); void FillFromCompositedLayers(); //Does the image loaded have alpha, ist it specified to have alpha bool HasAlpha() { return (ps.formatRecord->planes > 3) && (ps.data->TextureTypeIndex==TextureTypeEnum::COLOR_ALPHA);} //Show hide wait cursor void showLoadingCursor(); void showNormalCursor(); private: void InitData(); void DoWritePrepare(); void DoWriteStart(); void DoWriteDDS(); void DoReadPrepare(); void DoReadStart(); void DoReadContinue(); void DoReadFinish(); void DoReadLayerStart(); // scripting support bool ReadScriptParamsForWrite(); OSErr WriteScriptParamsForWrite(); bool ReadScriptParamsForRead(); OSErr WriteScriptParamsForRead(); void DoFilterFile(); void CreateDataHandle(); void LockHandles(); void UnlockHandles(); IntelPlugin(void); ~IntelPlugin(void); public: void DoWriteFinish(); void DoWriteContinue(); void PluginMain(const int16 selector, FormatRecordPtr formatParamBlock, intptr_t* data, int16* result); void UserError(const char* usrerror); void FetchImageData(); void DisposeImageData(); bool SetProgress(int part, int total); // true if can continue static IntelPlugin& GetInstance(); }; ================================================ FILE: IntelCompressionPlugin/IntelPlugin.r ================================================ // ADOBE SYSTEMS INCORPORATED // Copyright 1993 - 2002 Adobe Systems Incorporated // All Rights Reserved // // NOTICE: Adobe permits you to use, modify, and distribute this // file in accordance with the terms of the Adobe license agreement // accompanying it. If you have received this file from a source // other than Adobe, then your use, modification, or distribution // of it requires the prior written permission of Adobe. //------------------------------------------------------------------- //------------------------------------------------------------------------------- // // File: // Outbound.r // // Copyright 1990-1992, Thomas Knoll. // All Rights Reserved. // // Description: // This file contains the resource information // for the Export module Outbound, a module that // creates a file and stores raw pixel data in it. // // Use: // This module shows how to export raw data to a file. // It uses a simple "FileUtilities" library that comes // with the SDK. You use it via File>>Export>>Outbound. // //------------------------------------------------------------------------------- #include "IntelPluginName.h" //------------------------------------------------------------------------------- // Definitions -- Required by include files. //------------------------------------------------------------------------------- // The About box and resources are created in PIUtilities.r. // You can easily override them, if you like. #define plugInName DDSExporterPluginName #define plugInCopyrightYear "2015" #define plugInDescription \ "A DDS Export plug-in for Adobe Photoshop." //------------------------------------------------------------------------------- // Definitions -- Required by other resources in this rez file. //------------------------------------------------------------------------------- // Dictionary (aete) resources: #define vendorName DDSExporterPluginName #define plugInAETEComment "history export plug-in" #define plugInSuiteID 'sdK5' #define plugInClassID 'ddsX' #define plugInEventID typeNull // must be this //------------------------------------------------------------------------------- // Set up included files for Macintosh and Windows. //------------------------------------------------------------------------------- #include "PIDefines.h" #ifdef __PIMac__ #include "PIGeneral.r" #include "PIUtilities.r" #elif defined(__PIWin__) #define Rez #include "PIGeneral.h" #include "PIUtilities.r" #endif #include "PITerminology.h" #include "PIActions.h" //------------------------------------------------------------------------------- // PiPL resource //------------------------------------------------------------------------------- resource 'PiPL' (ResourceID, plugInName " PiPL", purgeable) { { Kind { ImageFormat }, Name { plugInName }, Category { ".."vendorName }, Version { (latestFormatVersion << 16) | latestFormatSubVersion }, #ifdef __PIMac__ #if (defined(__x86_64__)) CodeMacIntel64 { "PluginMain" }, #endif #if (defined(__i386__)) CodeMacIntel32 { "PluginMain" }, #endif #else #if defined(_WIN64) CodeWin64X86 { "PluginMain" }, #else CodeWin32X86 { "PluginMain" }, #endif #endif // ClassID, eventID, aete ID, uniqueString: HasTerminology { plugInClassID, plugInEventID, ResourceID, vendorName " " plugInName }, SupportedModes { noBitmap, doesSupportGrayScale, noIndexedColor, doesSupportRGBColor, noCMYKColor, noHSLColor, noHSBColor, doesSupportMultichannel, noDuotone, noLABColor }, EnableInfo { "in (PSHOP_ImageMode, GrayScaleMode, RGBMode, MultichannelMode) || PSHOP_ImageDepth == 16 || PSHOP_ImageDepth == 32" }, // New for Photoshop 8, document sizes that are really big // 32 bit row and columns, 2,000,000 current limit but we can handle more PlugInMaxSize { 32767, 32767 }, // For older Photoshops that only support 30000 pixel documents, // 16 bit row and columns FormatMaxSize { { 32767, 32767 } }, FormatMaxChannels { { 1, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24 } }, FmtFileType { 'DDS ', 'DDSX' }, //ReadTypes { { 'DDSX', ' ' } }, FilteredTypes { { 'DDSX', ' ' } }, ReadExtensions { { 'DDS ' } }, WriteExtensions { { 'DDS ' } }, FilteredExtensions { { 'DDS ' } }, FormatFlags { fmtDoesNotSaveImageResources, fmtCanRead, fmtCanWrite, fmtCanWriteIfRead, fmtCanWriteTransparency, fmtCanCreateThumbnail }, FormatICCFlags { iccCannotEmbedGray, iccCannotEmbedIndexed, iccCannotEmbedRGB, iccCannotEmbedCMYK }, FormatLayerSupport { doesSupportFormatLayers } } }; //------------------------------------------------------------------------------- //------------------------------------------------------------------------------- // Dictionary (scripting) resource //------------------------------------------------------------------------------- resource 'aete' (ResourceID, plugInName " dictionary", purgeable) { 1, 0, english, roman, /* aete version and language specifiers */ { vendorName, /* vendor suite name */ DDSExporterPluginName, /* optional description */ plugInSuiteID, /* suite ID */ 1, /* suite code, must be 1 */ 1, /* suite level, must be 1 */ {}, /* structure for filters */ { /* non-filter plug-in class here */ vendorName " " plugInName, /* unique class name */ plugInClassID, /* class ID, must be unique or Suite ID */ plugInAETEComment, /* optional description */ { /* define inheritance */ "", /* must be exactly this */ keyInherits, /* must be keyInherits */ classExport, /* parent: Format, Import, Export */ "parent class export", /* optional description */ flagsSingleProperty, /* if properties, list below */ "preset", /* our path */ keyPreset, /* common key */ typeChar, /* preset namecorrect path for platform */ "Preset name", /* optional description */ flagsSingleProperty, "mipmap", /* mipmaps on/off */ keyMipMap, /* common key */ typeBoolean, /* basic value type */ "MipMaps enabled", /* optional description */ flagsSingleProperty, "alphaseprate", /* use dedicated alpha channel for transp */ keyAlphaS, /* common key */ typeBoolean, /* basic value type */ "Alpha seperate", /* optional description */ flagsSingleProperty, /* no more properties */ }, {}, /* elements (not supported) */ /* class descriptions */ }, {}, /* comparison ops (not supported) */ {} /* any enumerations */ } }; //------------------------------------------------------------------------------- // Resource text entries // // Entering these as separate resources because then they // transfer directly over to windows via CNVTPIPL. // // If I use a Macintosh 'STR#' resource, I could put all these // strings into a single resource, but there is no // parallel on Windows. 'STR ' resources, which hold // one string per ID, exist on Windows and Macintosh. //------------------------------------------------------------------------------- // Prompt string: resource StringResource (kPrompt, plugInName " Prompt", purgeable) { "DDS export to file:" }; // Creator and type: resource StringResource (kCreatorAndType, plugInName " CreatorAndType", purgeable) { "Copyright 2015, Intel Corporation. All rights reserved." // creator "????" // type }; //------------------------------------------------------------------------------- // end Outbound.r ================================================ FILE: IntelCompressionPlugin/IntelPlugin.rc ================================================ // Microsoft Visual C++ generated resource script. // #include "resource.h" #define APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 2 resource. // #define APSTUDIO_HIDDEN_SYMBOLS #include "windows.h" #undef APSTUDIO_HIDDEN_SYMBOLS ///////////////////////////////////////////////////////////////////////////// #undef APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // English (United States) resources #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US #pragma code_page(1252) ///////////////////////////////////////////////////////////////////////////// // // Dialog // IDD_MAINDIALOG DIALOGEX 0, 0, 287, 263 STYLE DS_SETFONT | DS_MODALFRAME | DS_3DLOOK | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Intel Texture Works" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN COMBOBOX IDC_PRESET_COMBO,79,7,135,58,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP COMBOBOX IDC_TEXTURETYPE_COMBO,79,49,199,75,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP COMBOBOX IDC_COMPRESSION_COMBO,79,89,199,71,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP CONTROL "Export a specific mip level for Cube maps",IDC_CUBEMIPLEVEL_CHECK, "Button",BS_AUTOCHECKBOX | WS_TABSTOP,27,135,148,10 LTEXT "Mip Level:",14,207,136,36,8 COMBOBOX IDC_MIPLEVEL_COMBO,245,135,33,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP CONTROL "Normalize",IDC_NORMALIZE_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,27,175,46,10 CONTROL "Flip Red (X)",IDC_FLIPX_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,89,175,53,10 CONTROL "Flip Green (Y)",IDC_FLIPY_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,157,175,65,10 COMBOBOX IDC_MIPMAP_COMBO,79,196,199,99,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP PUSHBUTTON "Preview",IDC_PREVIEW_BUTTON,27,240,77,14 DEFPUSHBUTTON "&OK",IDOK,174,240,50,14 PUSHBUTTON "&Cancel",IDCANCEL,228,240,50,14 PUSHBUTTON "Save",IDC_PRESETSAVE_BUTTON,219,7,29,14 PUSHBUTTON "Delete",IDC_PRESETDELETE_BUTTON,251,7,29,14,BS_ICON LTEXT "Presets",26,27,9,42,8 LTEXT "Compression:",5,25,92,47,8 LTEXT "Texture Type:",9,27,51,52,8 LTEXT "Mip Maps:",22,27,198,43,8 LTEXT "Pre-compress Normal Map Operations:",17,27,159,191,8 PUSHBUTTON "?",IDC_COMPRESSION_HELP,7,89,16,14 PUSHBUTTON "?",IDC_TEXTURETYPE_HELP,7,49,16,14 PUSHBUTTON "?",IDC_PRECOMPRESS_HELP,7,156,16,14 PUSHBUTTON "?",IDC_MIPMAP_HELP,7,195,16,14 LTEXT "Context Info",IDC_COMPRESSION_HINT,27,105,251,20 LTEXT "Context Info",IDC_TEXTURETYPE_HINT,27,64,251,20 LTEXT "Context Info",IDC_MIPMAPS_HINT,27,211,251,20 END IDD_ABOUT DIALOGEX 0, 0, 225, 63 STYLE DS_SETFONT | DS_MODALFRAME | DS_3DLOOK | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Intel Texture Works" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN CTEXT "Copyright 2015, Intel Corporation.\nAll rights reserved.",26,10,10,205,18 DEFPUSHBUTTON "OK",IDOK,86,37,52,16 END IDD_PREVIEW DIALOGEX 0, 0, 585, 329 STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Preview" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN DEFPUSHBUTTON "OK",IDOK,528,308,50,14 CTEXT "",IDC_PREVIEWPROXY_ORIGINAL,7,28,282,263,NOT WS_VISIBLE | WS_DISABLED | WS_BORDER CTEXT "ORIGINAL",IDC_PREVIEWPROXY_ORIGINALTEXT,7,11,282,8 CTEXT "",IDC_PREVIEWPROXY_COMPRESSED,296,28,282,263,NOT WS_VISIBLE | WS_DISABLED | WS_BORDER PUSHBUTTON "",IDC_PREVIEWPROXY_ZOOMIN,307,309,13,13,BS_ICON PUSHBUTTON "",IDC_PREVIEWPROXY_ZOOMOUT,264,309,13,13,BS_ICON LTEXT "100%",IDC_PREVIEWPROXY_ZOOMTEXT,283,311,20,11 PUSHBUTTON "1x",IDC_PREVIEWPROXY_ZOOM1X,478,309,13,13 PUSHBUTTON "2x",IDC_PREVIEWPROXY_ZOOM2X,491,309,13,13 PUSHBUTTON "4x",IDC_PREVIEWPROXY_ZOOM4X,504,309,13,13 PUSHBUTTON "Fit",IDC_PREVIEWPROXY_ZOOMFIT,465,309,13,13 PUSHBUTTON "1/2x",IDC_PREVIEWPROXY_ZOOMHALF,446,309,19,13 PUSHBUTTON "1/4x",IDC_PREVIEWPROXY_ZOOMQUARTER,427,309,19,13 PUSHBUTTON "RGB",IDC_PREVIEWPROXY_RGB,7,309,19,13 PUSHBUTTON "R",IDC_PREVIEWPROXY_R,27,309,13,13 PUSHBUTTON "G",IDC_PREVIEWPROXY_G,41,309,13,13 PUSHBUTTON "B",IDC_PREVIEWPROXY_B,55,309,13,13 PUSHBUTTON "A",IDC_PREVIEWPROXY_A,69,309,13,13 COMBOBOX IDC_PREVIEWPROXY_COMBOBOX,410,8,168,30,CBS_DROPDOWNLIST | WS_TABSTOP CTEXT "120 kB",IDC_PREVIEWPROXY_TEXTSIZECOMPRESSED,296,295,282,8 CTEXT "120 kB",IDC_PREVIEWPROXY_TEXTSIZEUNCOMPRESSED,7,295,282,8 CONTROL "",IDC_EXPOSURE_SLIDER,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,87,310,73,12 END IDD_GETNAME DIALOGEX 0, 0, 173, 26 STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Enter Preset Name" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN EDITTEXT IDC_NAME_EDIT,7,7,159,12,ES_AUTOHSCROLL END IDD_LOADDIALOG DIALOGEX 0, 0, 199, 95 STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Load Options" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN DEFPUSHBUTTON "OK",IDOK,83,74,50,14 PUSHBUTTON "Cancel",IDCANCEL,142,74,50,14 CONTROL " Load mip-maps into separate layers.",IDC_LOADDIALOG_MIPMAPCHECK, "Button",BS_AUTOCHECKBOX | WS_TABSTOP,27,51,137,10 GROUPBOX "This File contains mip-maps. ",IDC_LOADDIALOG_MIPMAPGROUP,7,40,185,26,BS_LEFT GROUPBOX "This File contains Transparency",IDC_LOADDIALOG_ALPHAGROUP,7,7,185,27,BS_LEFT CONTROL " Load Transparency as Alpha channel",IDC_LOADDIALOG_ALPHACHECK, "Button",BS_AUTOCHECKBOX | WS_TABSTOP,27,18,135,10 END ///////////////////////////////////////////////////////////////////////////// // // Version // VS_VERSION_INFO VERSIONINFO FILEVERSION 15,0,0,0 PRODUCTVERSION 15,0,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L #else FILEFLAGS 0x0L #endif FILEOS 0x40004L FILETYPE 0x2L FILESUBTYPE 0x0L BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "040904b0" BEGIN VALUE "CompanyName", "Intel" VALUE "FileDescription", "Intel Texture Works" VALUE "FileVersion", "1.0" VALUE "InternalName", "Intel Texture Works" VALUE "LegalCopyright", "Copyright Intel Corporation. All rights reserved 2015" VALUE "OriginalFilename", "IntelCompressionPlugin" VALUE "ProductName", "Intel Texture Works" VALUE "ProductVersion", "1.0" END END BLOCK "VarFileInfo" BEGIN VALUE "Translation", 0x409, 1200 END END #ifdef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // TEXTINCLUDE // 1 TEXTINCLUDE BEGIN "resource.h\0" END 2 TEXTINCLUDE BEGIN "#define APSTUDIO_HIDDEN_SYMBOLS\r\n" "#include ""windows.h""\r\n" "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n" "\r\n" "\r\n" "\0" END 3 TEXTINCLUDE BEGIN "#include ""IntelPlugin.pipl""\r\n" "\0" END #endif // APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // DESIGNINFO // #ifdef APSTUDIO_INVOKED GUIDELINES DESIGNINFO BEGIN IDD_MAINDIALOG, DIALOG BEGIN RIGHTMARGIN, 281 VERTGUIDE, 6 VERTGUIDE, 27 VERTGUIDE, 79 VERTGUIDE, 278 HORZGUIDE, 7 END IDD_ABOUT, DIALOG BEGIN END IDD_PREVIEW, DIALOG BEGIN LEFTMARGIN, 7 RIGHTMARGIN, 578 VERTGUIDE, 185 VERTGUIDE, 395 TOPMARGIN, 8 BOTTOMMARGIN, 322 END IDD_GETNAME, DIALOG BEGIN LEFTMARGIN, 7 RIGHTMARGIN, 166 TOPMARGIN, 7 BOTTOMMARGIN, 19 END IDD_LOADDIALOG, DIALOG BEGIN LEFTMARGIN, 7 RIGHTMARGIN, 192 VERTGUIDE, 27 TOPMARGIN, 7 BOTTOMMARGIN, 88 END END #endif // APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // Icon // // Icon with lowest ID value placed first to ensure application icon // remains consistent on all systems. ZOOMOUTICON ICON "zoomout.ico" ZOOMINICON ICON "zoomin.ico" #endif // English (United States) resources ///////////////////////////////////////////////////////////////////////////// #ifndef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 3 resource. // #include "IntelPlugin.pipl" ///////////////////////////////////////////////////////////////////////////// #endif // not APSTUDIO_INVOKED ================================================ FILE: IntelCompressionPlugin/IntelPluginName.h ================================================ //////////////////////////////////////////////////////////////////////////////// // Copyright 2017 Intel Corporation // // Licensed under the Apache License, Version 2.0 (the "License"); you may not // use this file except in compliance with the License. You may obtain a copy // of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the // License for the specific language governing permissions and limitations // under the License. //////////////////////////////////////////////////////////////////////////////// #pragma once //Change this define to rename the plugin //It changes the pipl photoshop resource and also the window UI on runtime. //Be sure also to change the TargetName for the DDSExporter Project in "ConfigurationProperties->General->TargetName" (left click on DDSExporter), //both for Win32 and x64 settigns. #define DDSExporterPluginName "Intel Texture Works" #define DDSExporterPluginVersion " v1.0.4" // Terminology specific to this plug-in. #define kPrompt 16100 #define kCreatorAndType kPrompt+1 // scripting keys #define keyPreset 'pres' #define keyMipMap 'mipm' #define keyAlphaS 'alps' ================================================ FILE: IntelCompressionPlugin/IntelPluginUIWin.cpp ================================================ //////////////////////////////////////////////////////////////////////////////// // Copyright 2017 Intel Corporation // // Licensed under the Apache License, Version 2.0 (the "License"); you may not // use this file except in compliance with the License. You may obtain a copy // of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the // License for the specific language governing permissions and limitations // under the License. //////////////////////////////////////////////////////////////////////////////// #include "IntelPlugin.h" #include "SaveOptionsDialog.h" #include "IntelPluginUIWin.h" #include "IntelPluginName.h" #include "resource.h" /*****************************************************************************/ /*****************************************************************************/ /*****************************************************************************/ //Simple plugin About box INT_PTR WINAPI AboutDlgProcIntel(HWND hDlg, UINT wMsg, WPARAM wParam, LPARAM /*lParam*/) { switch (wMsg) { case WM_INITDIALOG: { //Set window name string windowTitle = DDSExporterPluginName; windowTitle += DDSExporterPluginVersion; SetWindowText(hDlg, windowTitle.c_str()); CenterDialog(hDlg); } break; case WM_CHAR: { TCHAR chCharCode = TCHAR(wParam); if (chCharCode == VK_ESCAPE || chCharCode == VK_RETURN) EndDialog(hDlg, 0); } break; case WM_LBUTTONDOWN: EndDialog(hDlg, 0); break; case WM_COMMAND: switch (COMMANDID(wParam)) { case OK: EndDialog(hDlg, 0); break; case CANCEL: EndDialog(hDlg, 0); break; default: return FALSE; } break; default: return FALSE; } // switch (wMsg) return TRUE; } void ShowAboutIntel (AboutRecordPtr aboutPtr) { PlatformData * platform = static_cast(aboutPtr->platformData); HWND h = reinterpret_cast(platform->hwnd); DialogBoxParam(GetDLLInstance(), MAKEINTRESOURCE( IDD_ABOUT ), h, AboutDlgProcIntel, 0); } /*****************************************************************************/ /*****************************************************************************/ /*****************************************************************************/ //Get name dialog INT_PTR WINAPI DlgGetNameProc(HWND hDlg, UINT wMsg, WPARAM wParam, LPARAM lParam) { static string * str; switch (wMsg) { case WM_INITDIALOG: { if (lParam) { str = reinterpret_cast(lParam); SetDlgItemTextA(hDlg, IDC_NAME_EDIT, str->c_str()); } CenterDialog(hDlg); } break; case WM_COMMAND: switch (COMMANDID(wParam)) { case IDOK: { char buf[MAX_PATH+1] = {}; GetDlgItemTextA(hDlg, IDC_NAME_EDIT, buf, MAX_PATH); *str = buf; str = NULL; EndDialog(hDlg, IDOK); } break; case IDCANCEL: str = NULL; EndDialog(hDlg, IDCANCEL); break; default: return FALSE; } break; default: return FALSE; } // switch (wMsg) return TRUE; } string GetPresetName(string str, HWND parent) { if (DialogBoxParam(GetDLLInstance(), MAKEINTRESOURCE( IDD_GETNAME ), parent, DlgGetNameProc, reinterpret_cast(&str)) == IDOK) { return str; } return ""; } /*****************************************************************************/ /*****************************************************************************/ /*****************************************************************************/ //Load Dialog box INT_PTR WINAPI DlgLoadProc(HWND hDlg, UINT wMsg, WPARAM wParam, LPARAM lParam) { static unsigned8* result; switch (wMsg) { case WM_INITDIALOG: { if (lParam) { result = reinterpret_cast(lParam); //If no mip maps hide controls if (!(*result & LoadInfoEnum::USE_MIPMAPS)) { ShowWindow(GetDlgItem(hDlg, IDC_LOADDIALOG_MIPMAPGROUP), SW_HIDE); ShowWindow(GetDlgItem(hDlg, IDC_LOADDIALOG_MIPMAPCHECK), SW_HIDE); } //If no alpha hide controls if (!(*result & LoadInfoEnum::USE_SEPARATEALPHA)) { ShowWindow(GetDlgItem(hDlg, IDC_LOADDIALOG_ALPHAGROUP), SW_HIDE); ShowWindow(GetDlgItem(hDlg, IDC_LOADDIALOG_ALPHACHECK), SW_HIDE); //move mipmap controls up RECT rcGroup = {}; RECT rcCheckbox = {}; HWND group = GetDlgItem(hDlg, IDC_LOADDIALOG_MIPMAPGROUP); HWND checkbox = GetDlgItem(hDlg, IDC_LOADDIALOG_MIPMAPCHECK); //Get alpha rectangles in client coordinates and set them to mip map controls GetWindowRect(GetDlgItem(hDlg, IDC_LOADDIALOG_ALPHAGROUP), &rcGroup); MapWindowRect(NULL, hDlg, &rcGroup); MoveWindow(group, rcGroup.left, rcGroup.top, rcGroup.right - rcGroup.left, rcGroup.bottom - rcGroup.top, TRUE); GetWindowRect(GetDlgItem(hDlg, IDC_LOADDIALOG_ALPHACHECK), &rcCheckbox); MapWindowRect(NULL, hDlg, &rcCheckbox); MoveWindow(checkbox, rcCheckbox.left, rcCheckbox.top, rcCheckbox.right - rcCheckbox.left, rcCheckbox.bottom - rcCheckbox.top, TRUE); } //Reset result to pass back info *result = LoadInfoEnum::USE_NONE; } CenterDialog(hDlg); } break; case WM_COMMAND: switch (COMMANDID(wParam)) { case IDOK: { EndDialog(hDlg, IDOK); } break; case IDCANCEL: { *result = LoadInfoEnum::USE_NONE; EndDialog(hDlg, IDCANCEL); } break; case IDC_LOADDIALOG_MIPMAPCHECK: { HWND alphachkbox = GetDlgItem(hDlg, IDC_LOADDIALOG_ALPHACHECK); bool checked = (SendMessage(GetDlgItem(hDlg, IDC_LOADDIALOG_MIPMAPCHECK), BM_GETCHECK, 0, 0) == BST_CHECKED); //Set the flag depending on the checked state if (checked) { *result |= LoadInfoEnum::USE_MIPMAPS; //uncheck and disable separate alpha setting on mip maps; if (GetWindowLong(alphachkbox, GWL_STYLE) | WS_VISIBLE) { SendMessage(alphachkbox, BM_SETCHECK, 0, 0); ::EnableWindow(alphachkbox, false); } } else { *result &= ~LoadInfoEnum::USE_MIPMAPS; //reenable alpha checkbox if (GetWindowLong(alphachkbox, GWL_STYLE) | WS_VISIBLE) { ::EnableWindow(alphachkbox, true); } } } break; case IDC_LOADDIALOG_ALPHACHECK: { bool checked = (SendMessage(GetDlgItem(hDlg, IDC_LOADDIALOG_ALPHACHECK), BM_GETCHECK, 0, 0) == BST_CHECKED); //set the flag depending on the checked state if (checked) *result |= LoadInfoEnum::USE_SEPARATEALPHA; else *result &= ~LoadInfoEnum::USE_SEPARATEALPHA; } break; default: return FALSE; } break; case WM_CTLCOLORSTATIC: { //set the background color of the chackbox controls static HBRUSH hBrushColor; if (!hBrushColor) { hBrushColor = CreateSolidBrush(RGB(255, 255, 255)); SetBkColor((HDC)wParam, RGB(255, 255, 255)); } return (LRESULT)hBrushColor; } break; case WM_PAINT: { PAINTSTRUCT ps; HDC hDC; hDC = BeginPaint(hDlg, &ps); RECT rcParent = {5, 5, 295, 115}; //Paint the white rectabgle where the checkboxes are positioned FillRect(hDC, &rcParent, static_cast(GetStockObject(WHITE_BRUSH))); EndPaint(hDlg, &ps); return FALSE; } break; default: return FALSE; } // switch (wMsg) return TRUE; } unsigned8 ShowLoadDialog (bool showAlphaGroup, bool showMipMapGroup, HWND parent) { //encode flags into results unsigned8 result = LoadInfoEnum::USE_NONE; result |= showAlphaGroup ? LoadInfoEnum::USE_SEPARATEALPHA : LoadInfoEnum::USE_NONE; result |= showMipMapGroup ? LoadInfoEnum::USE_MIPMAPS : LoadInfoEnum::USE_NONE; if (DialogBoxParam(GetDLLInstance(), MAKEINTRESOURCE( IDD_LOADDIALOG ), parent, DlgLoadProc, reinterpret_cast(&result)) == IDOK) { return result; } return 0; } //Show just a message box void errorMessage(std::string msg, std::string title) { MessageBox(GetActiveWindow(), msg.c_str(), title.c_str(), MB_OK); } // end OutboundUIWin.cpp ================================================ FILE: IntelCompressionPlugin/IntelPluginUIWin.h ================================================ //////////////////////////////////////////////////////////////////////////////// // Copyright 2017 Intel Corporation // // Licensed under the Apache License, Version 2.0 (the "License"); you may not // use this file except in compliance with the License. You may obtain a copy // of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the // License for the specific language governing permissions and limitations // under the License. //////////////////////////////////////////////////////////////////////////////// #pragma once void ShowAboutIntel (AboutRecordPtr aboutPtr); // Pop about box. std::string GetPresetName(std::string str, HWND parent); //Get preset name dialog unsigned8 ShowLoadDialog (bool showAlphaGroup, bool showMipMapGroup, HWND parent); //Load dialog void errorMessage(std::string msg, std::string title); //pops a message dialog ================================================ FILE: IntelCompressionPlugin/IntelTextureWorks.vcxproj ================================================  Debug Win32 Debug x64 Release Win32 Release x64 {FAA37424-40A7-47F4-98CB-4B9464145B0D} IntelCompressionPlugin IntelTextureWorks DynamicLibrary false v110 NotSet DynamicLibrary false v110 NotSet DynamicLibrary false v110 NotSet DynamicLibrary false v110 NotSet <_ProjectFileVersion>10.0.30319.1 false false AllRules.ruleset AllRules.ruleset AllRules.ruleset AllRules.ruleset .8bi .8bi .8bi .8bi false false _DEBUG;%(PreprocessorDefinitions) true true Win32 $(Intdir)Debug/Outbound.tlb /MP /GS %(AdditionalOptions) Disabled .;..\3rdParty\Intel\Source;..\3rdParty\DirectXTex\DirectXTex;$(PHOTOSHOP_SDK_CS6)\pluginsdk\PhotoshopAPI\Photoshop;$(PHOTOSHOP_SDK_CS6)\pluginsdk\PhotoshopAPI\PICA_SP;$(PHOTOSHOP_SDK_CS6)\pluginsdk\samplecode\common\includes;%(AdditionalIncludeDirectories) _ALLOW_KEYWORD_MACROS=1;ISOLATION_AWARE_ENABLED=1;_DEBUG;_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_DEPRECATE;DEV_$(USERNAME);WIN32=1;_WINDOWS;%(PreprocessorDefinitions) true Level3 true Default MultiThreadedDebug _DEBUG;%(PreprocessorDefinitions) 0x0409 ..\common;%(AdditionalIncludeDirectories) odbc32.lib;odbccp32.lib;version.lib;%(AdditionalDependencies) true true Windows false MachineX86 md "$(SolutionDir)Plugins\$(Platform)" copy "$(TargetPath)" "$(SolutionDir)Plugins\$(Platform)\*" if not defined PHOTOSHOP_SDK_CS6 ( echo PHOTOSHOP_SDK_CS6 must be defined. See ReadMe for setup information exit 1 ) _DEBUG;%(PreprocessorDefinitions) true true Win32 $(Intdir)Debug/Outbound.tlb /MP /GS %(AdditionalOptions) Disabled .;..\3rdParty\Intel\Source;..\3rdParty\DirectXTex\DirectXTex;$(PHOTOSHOP_SDK_CS6)\pluginsdk\PhotoshopAPI\Photoshop;$(PHOTOSHOP_SDK_CS6)\pluginsdk\PhotoshopAPI\PICA_SP;$(PHOTOSHOP_SDK_CS6)\pluginsdk\samplecode\common\includes;%(AdditionalIncludeDirectories) _ALLOW_KEYWORD_MACROS=1;ISOLATION_AWARE_ENABLED=1;NDEBUG;_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_DEPRECATE;DEV_$(USERNAME);WIN32=1;_WINDOWS;%(PreprocessorDefinitions) true Level3 true Default MultiThreaded NDEBUG;%(PreprocessorDefinitions) 0x0409 ..\common;%(AdditionalIncludeDirectories) odbc32.lib;odbccp32.lib;version.lib;%(AdditionalDependencies) true true Windows false MachineX86 md "$(SolutionDir)Plugins\$(Platform)" copy "$(TargetPath)" "$(SolutionDir)Plugins\$(Platform)\*" if not defined PHOTOSHOP_SDK_CS6 ( echo PHOTOSHOP_SDK_CS6 must be defined. See ReadMe for setup information exit 1 ) _DEBUG;%(PreprocessorDefinitions) true true X64 $(Intdir)Debug/Outbound.tlb /MP /GS %(AdditionalOptions) Disabled .;..\3rdParty\Intel\Source;..\3rdParty\DirectXTex\DirectXTex;$(PHOTOSHOP_SDK_CS6)\pluginsdk\PhotoshopAPI\Photoshop;$(PHOTOSHOP_SDK_CS6)\pluginsdk\PhotoshopAPI\PICA_SP;$(PHOTOSHOP_SDK_CS6)\pluginsdk\samplecode\common\includes;%(AdditionalIncludeDirectories) _ALLOW_KEYWORD_MACROS=1;ISOLATION_AWARE_ENABLED=1;_DEBUG;_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_DEPRECATE;DEV_$(USERNAME);WIN32=1;_WINDOWS;%(PreprocessorDefinitions) MultiThreadedDebug $(IntDir) $(IntDir) $(IntDir)vc$(PlatformToolsetVersion).pdb true Level3 true ProgramDatabase Default _DEBUG;%(PreprocessorDefinitions) 0x0409 ..\common;%(AdditionalIncludeDirectories) odbc32.lib;odbccp32.lib;version.lib;%(AdditionalDependencies) true %(AdditionalLibraryDirectories) true $(OutDir)$(TargetName).pdb Windows false $(OutDir)$(TargetName).lib MachineX64 md "$(SolutionDir)Plugins\$(Platform)" copy "$(TargetPath)" "$(SolutionDir)Plugins\$(Platform)\*" if not defined PHOTOSHOP_SDK_CS6 ( echo PHOTOSHOP_SDK_CS6 must be defined. See ReadMe for setup information exit 1 ) _DEBUG;%(PreprocessorDefinitions) true true X64 $(Intdir)Debug/Outbound.tlb /MP /GS %(AdditionalOptions) Disabled .;..\3rdParty\Intel\Source;..\3rdParty\DirectXTex\DirectXTex;$(PHOTOSHOP_SDK_CS6)\pluginsdk\PhotoshopAPI\Photoshop;$(PHOTOSHOP_SDK_CS6)\pluginsdk\PhotoshopAPI\PICA_SP;$(PHOTOSHOP_SDK_CS6)\pluginsdk\samplecode\common\includes;%(AdditionalIncludeDirectories) _ALLOW_KEYWORD_MACROS=1;ISOLATION_AWARE_ENABLED=1;NDEBUG;_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_DEPRECATE;DEV_$(USERNAME);WIN32=1;_WINDOWS;%(PreprocessorDefinitions) MultiThreaded $(IntDir) $(IntDir) $(IntDir)vc$(PlatformToolsetVersion).pdb true Level3 true ProgramDatabase Default NDEBUG;%(PreprocessorDefinitions) 0x0409 ..\common;%(AdditionalIncludeDirectories) odbc32.lib;odbccp32.lib;version.lib;%(AdditionalDependencies) true %(AdditionalLibraryDirectories) true $(OutDir)$(TargetName).pdb Windows false $(OutDir)$(TargetName).lib MachineX64 md "$(SolutionDir)Plugins\$(Platform)" copy "$(TargetPath)" "$(SolutionDir)Plugins\$(Platform)\*" if not defined PHOTOSHOP_SDK_CS6 ( echo PHOTOSHOP_SDK_CS6 must be defined. See ReadMe for setup information exit 1 ) Disabled Disabled %(AdditionalIncludeDirectories) %(AdditionalIncludeDirectories) true true Disabled Disabled %(AdditionalIncludeDirectories) %(AdditionalIncludeDirectories) true true Compiling PiPL resource... Compiling PiPL resource... cl /I$(PHOTOSHOP_SDK_CS6)\pluginsdk\PhotoshopAPI\PICA_SP /I$(PHOTOSHOP_SDK_CS6)\pluginsdk\PhotoshopAPI\Photoshop /I$(PHOTOSHOP_SDK_CS6)\pluginsdk\PhotoshopAPI\Resources /I$(PHOTOSHOP_SDK_CS6)\pluginsdk\samplecode\common\Resources /I$(PHOTOSHOP_SDK_CS6)\pluginsdk\samplecode\common\Includes /EP /DMSWindows=1 /Tc"%(FullPath)" > "$(IntDir)%(Filename).rr" "$(PHOTOSHOP_SDK_CS6)\pluginsdk\samplecode\resources\Cnvtpipl.exe" "$(IntDir)%(Filename).rr" "%(Filename).pipl" del "$(IntDir)%(Filename).rr" cl /I$(PHOTOSHOP_SDK_CS6)\pluginsdk\PhotoshopAPI\PICA_SP /I$(PHOTOSHOP_SDK_CS6)\pluginsdk\PhotoshopAPI\Photoshop /I$(PHOTOSHOP_SDK_CS6)\pluginsdk\PhotoshopAPI\Resources /I$(PHOTOSHOP_SDK_CS6)\pluginsdk\samplecode\common\Resources /I$(PHOTOSHOP_SDK_CS6)\pluginsdk\samplecode\common\Includes /EP /DMSWindows=1 /Tc"%(FullPath)" > "$(IntDir)%(Filename).rr" "$(PHOTOSHOP_SDK_CS6)\pluginsdk\samplecode\resources\Cnvtpipl.exe" "$(IntDir)%(Filename).rr" "%(Filename).pipl" del "$(IntDir)%(Filename).rr" %(Filename).pipl;%(Outputs) %(Filename).pipl;%(Outputs) Compiling PiPL resource... Compiling PiPL resource... cl /I$(PHOTOSHOP_SDK_CS6)\pluginsdk\PhotoshopAPI\PICA_SP /I$(PHOTOSHOP_SDK_CS6)\pluginsdk\PhotoshopAPI\Photoshop /I$(PHOTOSHOP_SDK_CS6)\pluginsdk\PhotoshopAPI\Resources /I$(PHOTOSHOP_SDK_CS6)\pluginsdk\samplecode\common\Resources /I$(PHOTOSHOP_SDK_CS6)\pluginsdk\samplecode\common\Includes /EP /DMSWindows=1 /Tc"%(FullPath)" > "$(IntDir)%(Filename).rr" "$(PHOTOSHOP_SDK_CS6)\pluginsdk\samplecode\resources\Cnvtpipl.exe" "$(IntDir)%(Filename).rr" "%(Filename).pipl" del "$(IntDir)%(Filename).rr" cl /I$(PHOTOSHOP_SDK_CS6)\pluginsdk\PhotoshopAPI\PICA_SP /I$(PHOTOSHOP_SDK_CS6)\pluginsdk\PhotoshopAPI\Photoshop /I$(PHOTOSHOP_SDK_CS6)\pluginsdk\PhotoshopAPI\Resources /I$(PHOTOSHOP_SDK_CS6)\pluginsdk\samplecode\common\Resources /I$(PHOTOSHOP_SDK_CS6)\pluginsdk\samplecode\common\Includes /EP /DMSWindows=1 /Tc"%(FullPath)" > "$(IntDir)%(Filename).rr" "$(PHOTOSHOP_SDK_CS6)\pluginsdk\samplecode\resources\Cnvtpipl.exe" "$(IntDir)%(Filename).rr" "%(Filename).pipl" del "$(IntDir)%(Filename).rr" %(Filename).pipl;%(Outputs) %(Filename).pipl;%(Outputs) %(PreprocessorDefinitions) %(PreprocessorDefinitions) %(PreprocessorDefinitions) %(PreprocessorDefinitions) Document ..\3rdParty\Intel\Tools\ispc -O2 "%(Filename).ispc" -o "$(IntDir)%(Filename).obj" -h "$(ProjectDir)%(Filename)_ispc.h" --arch=x86-64 --target=sse2,sse4,avx,avx2 --opt=fast-math ..\3rdParty\Intel\Tools\ispc -O2 "%(Filename).ispc" -o "$(IntDir)%(Filename).obj" -h "$(ProjectDir)%(Filename)_ispc.h" --arch=x86-64 --target=sse2,sse4,avx,avx2 --opt=fast-math $(IntDir)%(Filename).obj;$(IntDir)%(Filename)_sse2.obj;$(IntDir)%(Filename)_sse4.obj;$(IntDir)%(Filename)_avx.obj;$(IntDir)%(Filename)_avx2.obj $(IntDir)%(Filename).obj;$(IntDir)%(Filename)_sse2.obj;$(IntDir)%(Filename)_sse4.obj;$(IntDir)%(Filename)_avx.obj;$(IntDir)%(Filename)_avx2.obj ..\3rdParty\Intel\Tools\ispc -O2 "%(Filename).ispc" -o "$(IntDir)%(Filename).obj" -h "$(ProjectDir)%(Filename)_ispc.h" --arch=x86 --target=sse2,sse4,avx,avx2 --opt=fast-math ..\3rdParty\Intel\Tools\ispc -O2 "%(Filename).ispc" -o "$(IntDir)%(Filename).obj" -h "$(ProjectDir)%(Filename)_ispc.h" --arch=x86 --target=sse2,sse4,avx,avx2 --opt=fast-math $(IntDir)%(Filename).obj;$(IntDir)%(Filename)_sse2.obj;$(IntDir)%(Filename)_sse4.obj;$(IntDir)%(Filename)_avx.obj;$(IntDir)%(Filename)_avx2.obj $(IntDir)%(Filename).obj;$(IntDir)%(Filename)_sse2.obj;$(IntDir)%(Filename)_sse4.obj;$(IntDir)%(Filename)_avx.obj;$(IntDir)%(Filename)_avx2.obj {371b9fa9-4c90-4ac6-a123-aced756d6c77} ================================================ FILE: IntelCompressionPlugin/IntelTextureWorks.vcxproj.filters ================================================  {81d03a0f-9d1f-46dd-96e0-69897c8513aa} cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90 {975e039f-859d-47c7-ba81-3b597888543c} h;hpp;hxx;hm;inl;fi;fd {4b9a019f-f424-43e5-b946-e90e6484bc01} ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe {e52f075d-7c14-4f4e-a040-b491da9d7c79} {9e5bf2b7-e988-41b3-b16f-de1570fba0fa} {4184a4d2-ab32-4c21-a69a-dac5104aeab0} Source Files 3rd Party\Photoshop SDK 3rd Party\Photoshop SDK 3rd Party\Photoshop SDK 3rd Party\Photoshop SDK 3rd Party\Photoshop SDK 3rd Party\Photoshop SDK 3rd Party\Photoshop SDK 3rd Party\Photoshop SDK 3rd Party\Intel 3rd Party\Intel Source Files Source Files Source Files Resource Files Header Files Header Files 3rd Party\Intel 3rd Party\Intel Header Files Header Files Header Files Resource Files 3rd Party\Intel Resource Files Resource Files Resource Files ================================================ FILE: IntelCompressionPlugin/PreviewDialog.cpp ================================================ //////////////////////////////////////////////////////////////////////////////// // Copyright 2017 Intel Corporation // // Licensed under the Apache License, Version 2.0 (the "License"); you may not // use this file except in compliance with the License. You may obtain a copy // of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the // License for the specific language governing permissions and limitations // under the License. //////////////////////////////////////////////////////////////////////////////// #include "PreviewDialog.h" #include "IntelPluginUIWin.h" #include "resource.h" #include #include #include #include #include using namespace DirectX; //For mouse tracking, when panning zooming POINT mouseDownPos, mouseOldpos; bool mouseTracking = false; //Offset of small preview area into larger 100% image buffer, used for panning int previewOffsetXTrackingStart = 0; int previewOffsetYTrackingStart = 0; /*****************************************************************************/ template T clampGeneral(T x, T a, T b) { return x < a ? a : (x > b ? b : x); } /*****************************************************************************/ /*****************************************************************************/ /*****************************************************************************/ PreviewDialog::PreviewDialog(IntelPlugin* _plugin) { hDlg = NULL; plugin = _plugin; globalParams = plugin->GetData(); formatRecord = plugin->GetFormatRecord(); previewOffsetX=0; previewOffsetY=0; previewSpecificChannel = -1; //-1=RGB,0=R,1=G,2=B,3=A previewPlanes = 3; //Default is RGB previewZoom = 1.0f; previewBuffer = NULL; previewCompressedBuffer = NULL; pixelStep = mouseStep = 0; previewBufferWidth = 0; previewBufferHeight = 0; } PreviewDialog::~PreviewDialog() { //Exiting the dialog, free space if (previewBuffer != NULL) { delete[] previewBuffer; previewBuffer = NULL; } if (previewCompressedBuffer != NULL) { delete[] previewCompressedBuffer; previewCompressedBuffer = NULL; } } void PreviewDialog::CalculateOptimizationParameters(int width, int height) { int bigestValue = (width>height) ? width:height; float divVal = bigestValue/400.f; //400 found by trial and error, every 400 pixels we change opt step pixelStep = int(divVal) + 1; //how many pixels to skip when mouseTracking is on (panning) pixelStep = clampGeneral(pixelStep, 1, 4); mouseStep = int(pixelStep*bigestValue/100.f); //percentage of size threshold to update screen when mouse is moved } //Convert a channel value (R/G/B) from srcDataPtr to 8bit and copy into tgtDataPtr //the blitting routines only support 8bit images bool PreviewDialog::ConvertToUncompressedPreviewTo8Bit(unsigned8 *tgtDataPtr, ScratchImage *srcDataPtr, int index) { const Image *image = srcDataPtr->GetImages(); if (image->format == DXGI_FORMAT_R8G8B8A8_UNORM) { //Get pointer to first (and only) image unsigned8 *rowData8bit = image->pixels; tgtDataPtr[0] = rowData8bit[index]; } else if (image->format == DXGI_FORMAT_R16G16B16A16_FLOAT) { //Get pointer to first (and only) image, cast to 16bit for BC6 unsigned16 *rowData16bit = reinterpret_cast(image->pixels); //Inverse values of R/G channels only tgtDataPtr[0] = FloatToByte(F16toF32(rowData16bit[index])); } return true; } //Return bytes in human readable format std::string PreviewDialog::DisplayHumanReadable(int sizeInBytes) { char buffer[MAX_PATH] = {}; float MBinBytes = 1024.f*1024.f; float KBinBytes = 1024.f; if (sizeInBytes >= MBinBytes * 100) sprintf(buffer, "%d MB", sizeInBytes/(int)MBinBytes); else if (sizeInBytes >= MBinBytes) sprintf(buffer, "%.1f MB", sizeInBytes/MBinBytes); else if (sizeInBytes >= KBinBytes * 100) sprintf(buffer, "%d KB", sizeInBytes/(int)KBinBytes); else if (sizeInBytes >= KBinBytes) sprintf(buffer, "%.1f KB", sizeInBytes/KBinBytes); else sprintf(buffer, "%d B", sizeInBytes); return buffer; } //Update text control void PreviewDialog::UpdateSizeText() { int byteSize = plugin->GetCompressedByteSize(); if (globalParams->MipMapTypeIndex != MipmapEnum::NONE) // mip map size included byteSize = byteSize * 4 / 3; std::string text = DisplayHumanReadable(byteSize); SendMessage(GetDlgItem(hDlg, IDC_PREVIEWPROXY_TEXTSIZECOMPRESSED), WM_SETTEXT, 0, reinterpret_cast(text.c_str())); text = DisplayHumanReadable(plugin->GetOriginalByteSize()); SendMessage(GetDlgItem(hDlg, IDC_PREVIEWPROXY_TEXTSIZEUNCOMPRESSED), WM_SETTEXT, 0, reinterpret_cast(text.c_str())); } //Win32 Preview window //Update the text contol which diplays the zoom level void PreviewDialog::UpdateZoomText() { char buf[10]; sprintf(buf,"%3d%%", int(previewZoom*100.f)); SendMessage(GetDlgItem(hDlg, IDC_PREVIEWPROXY_ZOOMTEXT), WM_SETTEXT, 0, reinterpret_cast(buf)); } //Issue a redraw on the client window in the previe areas. //the redraw parameter indicates if the backgound needs to be erased. void PreviewDialog::InvalidatePreviews(bool redraw) { //Issue a redraw for these areas InvalidateRect (hDlg, &previewProxyRect, redraw); InvalidateRect (hDlg, &previewProxyCompressedRect, redraw); } //Clip offsets to bounds void PreviewDialog::ClipOffsetsToBounds() { previewOffsetX = clampGeneral(previewOffsetX, 0, int(previewDimensions.x*previewZoom) - previewBufferWidth); previewOffsetY = clampGeneral(previewOffsetY, 0, int(previewDimensions.y*previewZoom) - previewBufferHeight); } //Called after zoom, to recalculate the correct previewOffset. //Parameter previosZoom is the previous zoom value. //Special handling required to have it zoom always towards the center of the image part visible void PreviewDialog::ClipPreviewOffset(float previousZoom) { //Half width of preview area in dialog float halfWidth = previewAreaDimensions.x*0.5f; float halfHeight = previewAreaDimensions.y*0.5f; //Calculate preview offset for CENTER for 100% zoom. We use the previous zoom value here. //Center is the image pixel(x,y) which is in the center of the currelty visible part float origX = (previewOffsetX+halfWidth)*(1.f/previousZoom); float origY = (previewOffsetY+halfHeight)*(1.f/previousZoom); //Get factor for this offset for unscaled image relative to image size origX = origX/previewDimensions.x; origY = origY/previewDimensions.y; //Calculate new offset now based on the new zoom factor previewOffsetX=static_cast(previewDimensions.x*previewZoom*origX-halfWidth); previewOffsetY=static_cast(previewDimensions.y*previewZoom*origY-halfHeight); //Clip offsets to bounds ClipOffsetsToBounds(); } //Compute the client areas of the preview rectangles and the image width that is visible. //Should be the size of the preview are unless the image is smaller. //Returns a flag indicating the need for background clear. //Is to be called after zoom or window resize bool PreviewDialog::CalculateBounds() { previewDimensions = plugin->GetPreviewDimensions(); bool redraw = false; //Get window rectangles for bitmaps (for displayPixels) in client coordinates //Get in screen coordinates, for compressed texture GetWindowRect(GetDlgItem(hDlg, IDC_PREVIEWPROXY_COMPRESSED), &previewProxyCompressedRect); //Translate to client coords MapWindowRect(NULL, hDlg, &previewProxyCompressedRect); //Get in screen coordinates, for original texture GetWindowRect(GetDlgItem(hDlg, IDC_PREVIEWPROXY_ORIGINAL), &previewProxyRect); //Translate to client coords MapWindowRect(NULL, hDlg, &previewProxyRect); //Calculate width,height of preview area (calculated only once because both windows are the same) int width = previewProxyRect.right - previewProxyRect.left; int height = previewProxyRect.bottom - previewProxyRect.top; //Store locally in global previewAreaDimensions.x = width; previewAreaDimensions.y = height; //If previewarea bigger than real image (scaled using zoom factor) then clip size and //since the image displayed is smaller then the preview window flag a background clear if (width > previewDimensions.x*previewZoom) { redraw=true; width = int(previewDimensions.x*previewZoom); } if (height > previewDimensions.y*previewZoom) { redraw=true; height = int(previewDimensions.y*previewZoom); } //Store width of visible image (is same as preview area width, except when image is smaller than preview area, or zoomlevel <1) previewBufferWidth = width; previewBufferHeight = height; CalculateOptimizationParameters(previewAreaDimensions.x, previewAreaDimensions.y); //Return flag indicating the need of a background redraw or not return redraw; } //Copy into the previewBuffer/previewCompressedBuffer which gets displayed in PaintProxy the part of the image that is visible //The image that is visible is determined using the previewOffset (resulting from panning the image) and //the zoomLevel specified void PreviewDialog::updatePreviewBuffer() { static int colorMask[] = { IntelPlugin::PREVIEW_CHANNEL_RGB, IntelPlugin::PREVIEW_CHANNEL_RED, IntelPlugin::PREVIEW_CHANNEL_GREEN, IntelPlugin::PREVIEW_CHANNEL_BLUE, IntelPlugin::PREVIEW_CHANNEL_ALPHA }; int mask = colorMask[previewSpecificChannel+1]; // see definition, -1 is used for all channels plugin->FetchPreviewRGB(previewBuffer, previewAreaDimensions.x, previewAreaDimensions.y, previewOffsetX, previewOffsetY, 1.f/previewZoom, mask); plugin->FetchPreviewRGB(previewCompressedBuffer, previewAreaDimensions.x, previewAreaDimensions.y, previewOffsetX, previewOffsetY, 1.f/previewZoom, mask | IntelPlugin::PREVIEW_SOURCE_COMPRESSED); UpdateSizeText(); } //Draw two image proxies void PreviewDialog::PaintProxy() { PSPixelMap pixels; PSPixelMap pixelsCompressed; //PSPixelMask mask; PAINTSTRUCT ps; //POINT mapOrigin; HDC hDC; //Src rect which will get rendered form inside previeBuffer VRect inRect = {0, 0, previewBufferHeight, previewBufferWidth}; //If there is an error return if (plugin->GetResult() != noErr) return; //Compute offset to centre the image if its smaller than the preview Area int centreXOffset = 0; int centreYOffset = 0; if (previewAreaDimensions.x > previewBufferWidth) centreXOffset = static_cast((previewAreaDimensions.x - previewBufferWidth)*0.5); if (previewAreaDimensions.y > previewBufferHeight) centreYOffset = static_cast((previewAreaDimensions.y - previewBufferHeight)*0.5); hDC = BeginPaint(hDlg, &ps); //Paint the black frame with a one pixel space //between the image and the frame InflateRect(&previewProxyRect, 2, 2); FrameRect(hDC, &previewProxyRect, static_cast(GetStockObject(BLACK_BRUSH))); InflateRect(&previewProxyRect, -2, -2); InflateRect(&previewProxyCompressedRect, 2, 2); FrameRect(hDC, &previewProxyCompressedRect, static_cast(GetStockObject(BLACK_BRUSH))); InflateRect(&previewProxyCompressedRect, -2, -2); //Init the PSPixel map pixels.version = 1; pixels.bounds.top = 0; pixels.bounds.left = 0; pixels.bounds.bottom = inRect.bottom; pixels.bounds.right = inRect.right; pixels.imageMode = plugInModeRGBColor; pixels.rowBytes = previewAreaDimensions.x*3; pixels.colBytes = 3; pixels.planeBytes = 1; pixels.baseAddr = previewBuffer; pixels.mat = NULL; pixels.masks = NULL; pixels.maskPhaseRow = 0; pixels.maskPhaseCol = 0; pixelsCompressed = pixels; pixelsCompressed.baseAddr = previewCompressedBuffer; (plugin->GetFormatRecord()->displayPixels)(&pixels, &inRect,//&pixels.bounds, previewProxyRect.top + centreYOffset, previewProxyRect.left + centreXOffset, hDC); (plugin->GetFormatRecord()->displayPixels)(&pixelsCompressed, &inRect,//&pixels.bounds, previewProxyCompressedRect.top + centreYOffset, previewProxyCompressedRect.left + centreXOffset, hDC); EndPaint(hDlg, &ps); } //Zoom proxy preview //Calculates new bounds (width/height of viewable area), new offsets, //updates the buffer, text controls, and issues a win32 redraw void PreviewDialog::zoomImage(float previousZoom, float currentZoom) { previewZoom = currentZoom; //Calculate preview area sizes because of new zoom bool redraw = CalculateBounds(); //Calculate new offset because zoom changed ClipPreviewOffset(previousZoom); //Update the pixel buffer with this zoomLevel updatePreviewBuffer(); //Update ui which shows the zoom level UpdateZoomText(); //Issue a redraw for these areas InvalidatePreviews(redraw); } //Fill the preview compression table with valid entries for the texture type defined in gGlobalParams->TextureTypeIndex void PreviewDialog::FillCompressionCombo() { compressionModesTable_.clear(); //BC1, BC1_SRGB, BC3, BC3_SRGB, BC6H_FAST, BC6H_FINE, BC7_FAST, BC7_FINE, BC7_SRGB_FAST, BC7_SRGB_FINE, BC4, BC5, NONE if (plugin->IsCombinationValid(globalParams->TextureTypeIndex,CompressionTypeEnum::BC1)) compressionModesTable_.push_back(CompressModesStruct(DXGI_FORMAT_BC1_UNORM, "BC1 4bpp (Linear)", false)); if (plugin->IsCombinationValid(globalParams->TextureTypeIndex,CompressionTypeEnum::BC1_SRGB)) compressionModesTable_.push_back(CompressModesStruct(DXGI_FORMAT_BC1_UNORM_SRGB, "BC1 4bpp (sRGB, DX10+)", false)); if (plugin->IsCombinationValid(globalParams->TextureTypeIndex,CompressionTypeEnum::BC3)) compressionModesTable_.push_back(CompressModesStruct(DXGI_FORMAT_BC3_UNORM, "BC3 8bpp (Linear)", false)); if (plugin->IsCombinationValid(globalParams->TextureTypeIndex,CompressionTypeEnum::BC3_SRGB)) compressionModesTable_.push_back(CompressModesStruct(DXGI_FORMAT_BC3_UNORM_SRGB, "BC3 8bpp (sRGB, DX10+)", false)); if (plugin->IsCombinationValid(globalParams->TextureTypeIndex,CompressionTypeEnum::BC6H_FAST)) compressionModesTable_.push_back(CompressModesStruct(DXGI_FORMAT_BC6H_UF16, "BC6H 8bpp Fast (Linear, DX11+)", true)); if (plugin->IsCombinationValid(globalParams->TextureTypeIndex,CompressionTypeEnum::BC6H_FINE)) compressionModesTable_.push_back(CompressModesStruct(DXGI_FORMAT_BC6H_UF16, "BC6H 8bpp Fine (Linear, DX11+)", false)); if (plugin->IsCombinationValid(globalParams->TextureTypeIndex,CompressionTypeEnum::BC7_FAST)) compressionModesTable_.push_back(CompressModesStruct(DXGI_FORMAT_BC7_UNORM, "BC7 8bpp Fast (Linear, DX11+)", true)); if (plugin->IsCombinationValid(globalParams->TextureTypeIndex,CompressionTypeEnum::BC7_FINE)) compressionModesTable_.push_back(CompressModesStruct(DXGI_FORMAT_BC7_UNORM, "BC7 8bpp Fine (Linear, DX11+)", false)); if (plugin->IsCombinationValid(globalParams->TextureTypeIndex,CompressionTypeEnum::BC7_SRGB_FAST)) compressionModesTable_.push_back(CompressModesStruct(DXGI_FORMAT_BC7_UNORM_SRGB, "BC7 8bpp Fast (sRGB, DX11+)", true)); if (plugin->IsCombinationValid(globalParams->TextureTypeIndex,CompressionTypeEnum::BC7_SRGB_FINE)) compressionModesTable_.push_back(CompressModesStruct(DXGI_FORMAT_BC7_UNORM_SRGB, "BC7 8bpp Fine (sRGB, DX11+)", false)); if (plugin->IsCombinationValid(globalParams->TextureTypeIndex,CompressionTypeEnum::BC4)) compressionModesTable_.push_back(CompressModesStruct(DXGI_FORMAT_BC4_UNORM, "BC4 4bpp (Linear, Grayscale)", false)); if (plugin->IsCombinationValid(globalParams->TextureTypeIndex,CompressionTypeEnum::BC5)) compressionModesTable_.push_back(CompressModesStruct(DXGI_FORMAT_BC5_UNORM, "BC5 8bpp (Linear, 2 Channel tangent map)", false)); if (plugin->IsCombinationValid(globalParams->TextureTypeIndex,CompressionTypeEnum::UNCOMPRESSED)) compressionModesTable_.push_back(CompressModesStruct(DXGI_FORMAT_R8G8B8A8_UNORM, "none 32bpp", false)); } //Fill Preview combo with all current compression settings and select the current one //The current settings are taken from the global plugin struct void PreviewDialog::InitPreviewComboBox() { //Init Combo Box Instead of the static text HWND combo = GetDlgItem(hDlg, IDC_PREVIEWPROXY_COMBOBOX); //Clear combo SendMessage(combo, CB_RESETCONTENT, 0, 0); //Fill compressionModesTable FillCompressionCombo(); //Fill Combo with predefined compressionModesTable entries for (int i=0;i(compressionModesTable_[i].formatName.c_str())); //Set selected index, if this is the matching index. if (globalParams->encoding_g == compressionModesTable_[i].format && globalParams->fast_bc67 == compressionModesTable_[i].fast) SendMessage(combo, CB_SETCURSEL, WPARAM(i), 0); } //Define Font LOGFONT lf = {}; // to define the font lf.lfHeight = 14; //lf.lfWidth = ; lf.lfWeight = FW_NORMAL; lf.lfCharSet = ANSI_CHARSET; lf.lfOutPrecision = OUT_DEFAULT_PRECIS; lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; lf.lfQuality = PROOF_QUALITY; lf.lfPitchAndFamily = FIXED_PITCH | FF_MODERN; strcpy(lf.lfFaceName,"Consolas"); if (auto hFont = ::CreateFontIndirect(&lf)) { SendMessage(combo, WM_SETFONT, reinterpret_cast(hFont), LPARAM(TRUE)); } } //Calculate zoom value so that image is shown in its entirety void PreviewDialog::zoomToFit() { if (previewDimensions.x > previewDimensions.y) { //Image is wider than tall previewZoom = clampGeneral (float(previewAreaDimensions.x) / previewDimensions.x, 0.01f, 1.f); } else { //Image is taller than wide previewZoom = clampGeneral (float(previewAreaDimensions.y) / previewDimensions.y, 0.01f, 1.f); } } //Allocate preview buffer for this proxy area, proxyBuffer can only be RGB. Therefore 3 void PreviewDialog::allocateBuffers() { if (previewBuffer != NULL) delete[] previewBuffer; if (previewCompressedBuffer != NULL) delete[] previewCompressedBuffer; previewBuffer = new unsigned8[previewAreaDimensions.x*previewAreaDimensions.y*3]; previewCompressedBuffer = new unsigned8[previewAreaDimensions.x*previewAreaDimensions.y*3]; } //Init planes and fill photoshop buffer with image void PreviewDialog::Init() { //Store number of available planes previewPlanes = plugin->GetFormatRecord()->planes; previewPlanes = clampGeneral(previewPlanes, 1, 4); } //Test if global state different then the one selected in combo box bool PreviewDialog::IsSelectedEncodingDifferent(int index) { if (index < compressionModesTable_.size()) { return (!(globalParams->encoding_g == compressionModesTable_[index].format && globalParams->fast_bc67 == compressionModesTable_[index].fast)); } return false; } //Set global state encoding from table. The index into the table is taken form the combo box void PreviewDialog::SetGlobalEncoding(int index) { if (index < compressionModesTable_.size()) { globalParams->encoding_g = compressionModesTable_[index].format; globalParams->fast_bc67 = compressionModesTable_[index].fast; } } // maxDimension is a percentage of parent size (null = desktop) // eg passing max dim 0.3 means the window must fit within a rectangle that is // 0.3 times the size of the parent. // minWidth sets a lower limit to stop dialogs collapsing too much void PreviewDialog::RelativeScale(HWND hwnd, HWND parent_hwnd, float maxDimension, int minWidth) { if (parent_hwnd == NULL) parent_hwnd = GetDesktopWindow(); RECT rcSelf = {}; RECT rcParent = {}; GetWindowRect(hwnd, &rcSelf); GetWindowRect(parent_hwnd, &rcParent); // pick a size relative to desktop/parent size float scale = (rcParent.right - rcParent.left) * maxDimension / (rcSelf.right - rcSelf.left); float scaleY = (rcParent.bottom - rcParent.top) * maxDimension / (rcSelf.bottom - rcSelf.top); if (scaleY < scale) scale = scaleY; // make sure we don't make it too small float scaleMin = float(minWidth) / (rcSelf.right - rcSelf.left); if (scale < scaleMin) scale = scaleMin; rcSelf.right = int((rcSelf.right - rcSelf.left) * scale + rcSelf.left); rcSelf.bottom = int((rcSelf.bottom - rcSelf.top) * scale + rcSelf.top); // our coordinates are screen based, convert to client here MapWindowRect(NULL, parent_hwnd, &rcSelf); MoveWindow(hwnd, rcSelf.left, rcSelf.top, rcSelf.right - rcSelf.left, rcSelf.bottom - rcSelf.top, FALSE); } BOOL CALLBACK PreviewDialog::WndEnumProc(HWND hwnd, LPARAM self_lparam) { PreviewDialog* self = reinterpret_cast(self_lparam); RECT rcParent; RECT rc; GetClientRect(self->hDlg, &rcParent); GetWindowRect(hwnd, &rc); MapWindowRect(NULL, self->hDlg, &rc); self->scaledPositions.push_back(std::make_pair(hwnd, ScalableRect(rcParent, rc))); return TRUE; } // message handler BOOL PreviewDialog::WindowProc(UINT wMsg, WPARAM wParam, LPARAM lParam) // Win32 Change { switch (wMsg) { case WM_INITDIALOG: { //Save as static for cross functiona call use // Initialize compression name text control, or combo box with names InitPreviewComboBox(); EnumChildWindows(hDlg, WndEnumProc, reinterpret_cast(this)); // pick a reasonable default for current view RelativeScale(hDlg, NULL, 0.4f, 600); //Center dialog and update zoom level ui indication CenterDialog(hDlg); Init(); //Calculate initial bounds with zoom of 1 preview area sizes CalculateBounds(); //Calculate zoom so that image is shown in its entirety zoomToFit(); //Calculate new bounds because zoom changed CalculateBounds(); //Calculate new offset because zoom changed ClipPreviewOffset(1.f); //Update zoom level ui text UpdateZoomText(); //Allocate preview buffer for this proxy area, proxyBuffer can only be RGB. allocateBuffers(); //Fill preview buffer updatePreviewBuffer(); //Load zoom icons into the buttons HANDLE hMyIcon = LoadImage(GetDLLInstance(), "ZOOMINICON",IMAGE_ICON,13,13,NULL); HANDLE hMyIcon2 = LoadImage(GetDLLInstance(), "ZOOMOUTICON",IMAGE_ICON,13,13,NULL); if (hMyIcon != NULL) { SendDlgItemMessage(hDlg, IDC_PREVIEWPROXY_ZOOMIN, BM_SETIMAGE, IMAGE_ICON, reinterpret_cast(hMyIcon)); } if (hMyIcon2 != NULL) { SendDlgItemMessage(hDlg, IDC_PREVIEWPROXY_ZOOMOUT, BM_SETIMAGE, IMAGE_ICON, reinterpret_cast(hMyIcon2)); } if (auto slider = GetDlgItem(hDlg, IDC_EXPOSURE_SLIDER)) { if (plugin->GetFormatRecord()->depth > 16) { ShowWindow(slider, SW_SHOW); SendMessage(slider, TBM_SETRANGEMIN, FALSE, -1000); SendMessage(slider, TBM_SETRANGEMAX, TRUE, 1000); SendMessage(slider, TBM_SETPOS, TRUE, 0); } else { ShowWindow(slider, SW_HIDE); } } return TRUE; } case WM_PAINT: PaintProxy(); return FALSE; case WM_SIZE: { //new width, height of window int width=LOWORD (lParam); int height=HIWORD (lParam); if (true) { RECT rect = {}; rect.right = width; rect.bottom = height; for (auto it = scaledPositions.begin(); it != scaledPositions.end(); ++it) { auto hwnd = it->first; auto scalableRect = it->second; if (IsWindow(hwnd)) { RECT rc = scalableRect.Get(rect); MoveWindow(hwnd, rc.left, rc.top, rc.right - rc.left, rc.bottom-rc.top,FALSE); } } CalculateBounds(); allocateBuffers(); } //Update view float prevZoom = getCurrentZoom(); zoomImage(prevZoom, prevZoom); InvalidateRect(hDlg, NULL, true); break; } case WM_COMMAND: { float prevZoom = 0; float newZoom = 1; int idd = COMMANDID (wParam); // WIN32 Change switch (idd) { case OK: case CANCEL: EndDialog(hDlg, idd); break; case IDC_PREVIEWPROXY_ZOOMIN: //Zoom in button was pressed //Compute new zoom level prevZoom = getCurrentZoom(); newZoom = prevZoom + 0.1f; newZoom =clampGeneral(newZoom, 0.05f, 4.f); zoomImage(prevZoom, newZoom); break; case IDC_PREVIEWPROXY_ZOOMOUT: //Zoom in button was pressed //Compute new zoom level prevZoom = getCurrentZoom(); newZoom = prevZoom - 0.1f; newZoom =clampGeneral(newZoom, 0.05f, 4.f); zoomImage(prevZoom, newZoom); break; case IDC_PREVIEWPROXY_ZOOM1X: //Zoom 1x button was pressed //Compute new zoom level prevZoom = getCurrentZoom(); zoomImage(prevZoom, 1); break; case IDC_PREVIEWPROXY_ZOOM2X: //Zoom 2x button was pressed //Compute new zoom level prevZoom = getCurrentZoom(); zoomImage(prevZoom, 2); break; case IDC_PREVIEWPROXY_ZOOM4X: //Zoom 4x button was pressed //Compute new zoom level prevZoom = getCurrentZoom(); zoomImage(prevZoom, 4); break; case IDC_PREVIEWPROXY_ZOOMHALF: //Zoom 1/2x button was pressed //Compute new zoom level prevZoom = getCurrentZoom(); zoomImage(prevZoom, 0.5f); break; case IDC_PREVIEWPROXY_ZOOMQUARTER: //Zoom 1/2x button was pressed //Compute new zoom level prevZoom = getCurrentZoom(); zoomImage(prevZoom, 0.25f); break; case IDC_PREVIEWPROXY_ZOOMFIT: //Calculate zoom so that image is shown in its entirety //Compute new zoom level prevZoom = getCurrentZoom(); zoomToFit(); zoomImage(prevZoom, getCurrentZoom()); break; case IDC_PREVIEWPROXY_RGB: setPreviewSpecificChannel(-1); //RGB //Update the pixel buffer with this channel info updatePreviewBuffer(); //Issue a redraw for these areas InvalidatePreviews(false); break; case IDC_PREVIEWPROXY_R: setPreviewSpecificChannel(0); //R //Update the pixel buffer with this channel info updatePreviewBuffer(); //Issue a redraw for these areas InvalidatePreviews(false); break; case IDC_PREVIEWPROXY_G: setPreviewSpecificChannel(1); //G //Update the pixel buffer with this channel info updatePreviewBuffer(); //Issue a redraw for these areas InvalidatePreviews(false); break; case IDC_PREVIEWPROXY_B: setPreviewSpecificChannel(2); //B //Update the pixel buffer with this channel info updatePreviewBuffer(); //Issue a redraw for these areas InvalidatePreviews(false); break; case IDC_PREVIEWPROXY_A: setPreviewSpecificChannel(3); //A //Update the pixel buffer with this channel info updatePreviewBuffer(); //Issue a redraw for these areas InvalidatePreviews(false); break; case IDC_PREVIEWPROXY_COMBOBOX: { //Did the combo box change if ( HIWORD(wParam) == CBN_SELCHANGE) { //Get its current index HWND combo = GetDlgItem(hDlg, IDC_PREVIEWPROXY_COMBOBOX); int index = int(SendMessage(combo, CB_GETCURSEL, 0, 0)); //If encoding different if (IsSelectedEncodingDifferent(index)) { //Store settigns selected in combo box SetGlobalEncoding(index); } //Update the pixel buffer with this channel info updatePreviewBuffer(); //Issue a redraw for these areas InvalidatePreviews(false); } } break; default: return FALSE; } break; } case WM_DESTROY: { return FALSE; } case WM_LBUTTONDOWN: //Set focus to window, since the combo will have the focus by default SetFocus(GetActiveWindow()); //Start mouse tracking GetCursorPos(&mouseDownPos); //Get mouse pos in screen coords mouseOldpos = mouseDownPos; //Store old mouse position for update every 5 pixels //Store offset value getPreviewOffset(previewOffsetXTrackingStart, previewOffsetYTrackingStart); SetCapture(hDlg); break; case WM_MOUSEMOVE: if (GetCapture() == hDlg) { //Do we track the mouse for panning POINT newpos; GetCursorPos(&newpos); //Get mouse pos in screen coords //Calculate new offset values setPreviewOffset(previewOffsetXTrackingStart - (newpos.x - mouseDownPos.x), previewOffsetYTrackingStart - (newpos.y - mouseDownPos.y)); //Clip offsets to bounds ClipOffsetsToBounds(); //Update only if mouse moved 5 pixels (otherwise lock gaps) if ((abs(mouseOldpos.x - newpos.x) > getMouseStep()) || (abs(mouseOldpos.y - newpos.y) > getMouseStep())) { mouseOldpos = newpos; updatePreviewBuffer(); } //Issue a redraw for these areas InvalidatePreviews(false); } break; case WM_LBUTTONUP: //Stop mouse tracking if (GetCapture() == hDlg) ReleaseCapture(); break; case WM_CAPTURECHANGED: updatePreviewBuffer(); //Issue a redraw for these areas InvalidatePreviews(false); break; case WM_MOUSEWHEEL: { //Zoom in/out using mouse wheel, update value and text float prevZoom = getCurrentZoom(); float zDelta = GET_WHEEL_DELTA_WPARAM(wParam); float newZoom = float(prevZoom * pow(1.05, zDelta / WHEEL_DELTA)); newZoom =clampGeneral(newZoom, 0.05f, 4.f); zoomImage(prevZoom, newZoom); break; } case WM_HSCROLL: case WM_VSCROLL: switch(LOWORD(wParam)) { case SB_ENDSCROLL: case SB_THUMBPOSITION: case SB_THUMBTRACK: if (auto slider = GetDlgItem(hDlg, IDC_EXPOSURE_SLIDER)) { auto pos = SendMessage(slider, TBM_GETPOS, 0, 0); float v = float(pow(2, pos * 0.01)); if (globalParams->exposure != v) { globalParams->exposure = v; updatePreviewBuffer(); InvalidatePreviews(false); } } break; } break; default: return FALSE; } return TRUE; } // static callback for DialogBoxParam INT_PTR WINAPI PreviewDialog::PreviewProc(HWND hwnd, UINT wMsg, WPARAM wParam, LPARAM lParam) // Win32 Change { PreviewDialog *previewDialog = NULL; if (wMsg == WM_INITDIALOG) { previewDialog = reinterpret_cast(lParam); previewDialog->hDlg = hwnd; SetWindowLongPtr(hwnd, DWLP_USER, reinterpret_cast(previewDialog)); } else if (hwnd) { previewDialog = reinterpret_cast(GetWindowLongPtr(hwnd, DWLP_USER)); } if (previewDialog) return previewDialog->WindowProc(wMsg, wParam, lParam); return 0; } //Show the UI dialog void PreviewDialog::Modal() { //If not enought layers for cubemaps preview exit if ((globalParams->TextureTypeIndex == TextureTypeEnum::CUBEMAP_LAYERS) && plugin->GetLayerCount() < 6) { errorMessage("Cubemap has not enough layers available. Consult the documentation (question mark next to the TextureType drop down) on how to create cubemaps", "Preview Error"); return; } DialogBoxParam(GetDLLInstance(), MAKEINTRESOURCE( IDD_PREVIEW ), GetActiveWindow(), PreviewProc, reinterpret_cast(this)); } ================================================ FILE: IntelCompressionPlugin/PreviewDialog.h ================================================ //////////////////////////////////////////////////////////////////////////////// // Copyright 2017 Intel Corporation // // Licensed under the Apache License, Version 2.0 (the "License"); you may not // use this file except in compliance with the License. You may obtain a copy // of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the // License for the specific language governing permissions and limitations // under the License. //////////////////////////////////////////////////////////////////////////////// #pragma once #include "IntelPlugin.h" #include #include class ScalableOrdinate { double anchor; // 0 = left/top, 1 = right/bottom double offset; // simple offset to add public: ScalableOrdinate() { anchor = offset = 0; } double Get(double lo, double hi) const { return lo * (1-anchor) + hi * anchor + offset; } void Set(double _anchor, double _offset) { anchor = _anchor; offset = _offset; } void Set(double lo, double hi, double v) { anchor = (v - lo) / (hi - lo); offset = 0; // auto select segment to pin to here if (anchor > 0.6666) anchor = 1; else if (anchor > 0.33333) anchor = 0.5; else anchor = 0; Set(lo, hi, anchor, v); } void Set(double lo, double hi, double _anchor, double v) { anchor = _anchor; offset = v - (lo * (1-anchor) + hi * anchor); } }; class ScalableRect { ScalableOrdinate left, top, right, bottom; public: void Set(const RECT& parent, const RECT& rc) { left.Set(parent.left, parent.right, rc.left); right.Set(parent.left, parent.right, rc.right); top.Set(parent.bottom, parent.top, rc.top); bottom.Set(parent.bottom, parent.top, rc.bottom); } ScalableRect(const RECT& parent, const RECT& rc) // construct { Set(parent, rc); } RECT Get(const RECT& parent) const { RECT rc; rc.left = int(left.Get(parent.left, parent.right)); rc.right = int(right.Get(parent.left, parent.right)); rc.top = int(top.Get(parent.bottom, parent.top)); rc.bottom = int(bottom.Get(parent.bottom, parent.top)); return rc; } }; class PreviewDialog { private: HWND hDlg; std::list> scaledPositions; //Structure for representing Compression pairs for the Preview Combo box struct CompressModesStruct { DXGI_FORMAT format; std::string formatName; bool fast; CompressModesStruct(DXGI_FORMAT format_, std::string formatname_, bool fast_) : format(format_), formatName(formatname_), fast(fast_) { } }; //All available preview compression options for the texture type defined in gGlobalParams->TextureTypeIndex std::vector compressionModesTable_; //Pointer to photoshop API IntelPlugin* plugin; IntelPlugin::Globals* globalParams; const FormatRecord* formatRecord; // data about the source image from photoshop (caution!) //Areas in client space where the image proxies are located RECT previewProxyRect; RECT previewProxyCompressedRect; //Size of image displayed in preview buffer. //Normaly the preview are, except when the image (or the zoomed image) is smaller than the preview area. int previewBufferWidth; int previewBufferHeight; //Preview buffer, just the size of the preview area uint8_t *previewBuffer; uint8_t *previewCompressedBuffer; //Stores width,height of preview area, convenience variable POINT previewAreaDimensions; POINT previewDimensions; //Zoom scale of original image. 100%=1 float previewZoom; //Offset of small preview area into larger 100% image buffer, used for panning int previewOffsetX; int previewOffsetY; int previewSpecificChannel; //-1=RGB,0=R,1=G,2=B,3=A int previewPlanes; //Default is RGB=3 static void RelativeScale(HWND hwnd, HWND parent_hwnd, float maxDimension,int minWidth); static BOOL CALLBACK WndEnumProc(HWND, LPARAM); static INT_PTR WINAPI PreviewProc(HWND hwnd, UINT wMsg, WPARAM wParam, LPARAM lParam); BOOL WindowProc(UINT wMsg, WPARAM wParam, LPARAM lParam); //Preview Optimization parameters int pixelStep; int mouseStep; public: //Getter/Setters void setPreviewSpecificChannel(int channel) { previewSpecificChannel=channel;} void getPreviewOffset(int &X, int &Y) { X = previewOffsetX; Y=previewOffsetY;} void setPreviewOffset(int X, int Y) { previewOffsetX = X; previewOffsetY = Y;} float getCurrentZoom() { return previewZoom; } int getMouseStep() { return mouseStep;} bool IsSelectedEncodingDifferent(int index); void SetGlobalEncoding(int index); //Allocate preview buffer for this proxy area void allocateBuffers(); //Show main UI void Modal(); //First function to call void Init(); bool ConvertToUncompressedPreviewTo8Bit(unsigned8 *tgtDataPtr, DirectX::ScratchImage *srcDataPtr, int index); void UpdateZoomText(); void InvalidatePreviews(bool redraw); void ClipOffsetsToBounds(); void ClipPreviewOffset(float previousZoom); bool CalculateBounds(); void updatePreviewBuffer(); void PaintProxy(); void zoomImage(float previousZoom, float currentZoom); void FillCompressionCombo(); void InitPreviewComboBox(); void zoomToFit(); void UpdateSizeText(); std::string DisplayHumanReadable(int sizeInBytes); void CalculateOptimizationParameters(int width, int height); explicit PreviewDialog(IntelPlugin* plugin); ~PreviewDialog(); }; ================================================ FILE: IntelCompressionPlugin/SaveOptionsDialog.cpp ================================================ //////////////////////////////////////////////////////////////////////////////// // Copyright 2017 Intel Corporation // // Licensed under the Apache License, Version 2.0 (the "License"); you may not // use this file except in compliance with the License. You may obtain a copy // of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the // License for the specific language governing permissions and limitations // under the License. //////////////////////////////////////////////////////////////////////////////// #include #include #include #include #include "PIUFile.h" #include "SaveOptionsDialog.h" #include "IntelPluginName.h" #include "IntelPlugin.h" #include "IntelPluginUIWin.h" #include "resource.h" #include "PreviewDialog.h" typedef vector(*VStringFunc)(void); // Container for the data to associate a help button WinForm ID with the corresponding function to display the help text. typedef struct { const int itemNum; // WinForm ID of the help button VStringFunc func; // Function to call to get the help text to display } HelpButtonAndTextFunc; // Struct to associate the Dropdown list WinForm ID with the Context Text WinForm ID // so we know where to display the context info when the user picks a different dropdown list item. typedef struct { const int itemNum; // DropDown list WinForm ID const int contextItemNum; // Context Text WinForm ID. } ComboAndContextStringID; vector GetCompressionHelpText(void); // Helper functions to specify the text for the help button (?) next to various UI elements vector GetTextureTypeHelpText(void); vector GetPreCompressOpsHelpText(void); vector GetMipMapsHelpText(void); HelpButtonAndTextFunc const helpButtonTextItem[] = { { IDC_COMPRESSION_HELP, GetCompressionHelpText }, { IDC_TEXTURETYPE_HELP, GetTextureTypeHelpText }, { IDC_PRECOMPRESS_HELP, GetPreCompressOpsHelpText }, { IDC_MIPMAP_HELP, GetMipMapsHelpText } }; // The list of associations. ComboAndContextStringID const gComboContextItems[] = { { IDC_COMPRESSION_COMBO, IDC_COMPRESSION_HINT }, { IDC_TEXTURETYPE_COMBO, IDC_TEXTURETYPE_HINT }, { IDC_MIPMAP_COMBO, IDC_MIPMAPS_HINT } }; #if !__LP64__ OptionsDialog::OptionsDialog(IntelPlugin* plugin_) : PIDialog() { plugin = plugin_; globalParams = plugin->GetData(); mPathToPresetDirectory.clear(); MaxMipLevel =static_cast(1 + floor(Log2(max((plugin->GetFormatRecord()->imageSize.h),(plugin->GetFormatRecord()->imageSize.v))))); /*Get path to Local per user configuration files, %USERPROFILE%\\AppData\Local\\Intel\\PhotoshopDDSPlugin\\ */ wchar_t* localAppData = 0; HRESULT hr = SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, NULL, &localAppData); //Path exists if (SUCCEEDED(hr)) { //Convert wide char to char, append name of directory char str[MAX_PATH+1] = {}; wcstombs(str, localAppData, MAX_PATH); CoTaskMemFree(static_cast(localAppData)); mPathToPresetDirectory = str; //Free mem //Create directory if does not exist mPathToPresetDirectory.append("\\Intel"); if (CreateDirectory(mPathToPresetDirectory.c_str(), NULL) || ERROR_ALREADY_EXISTS == GetLastError()) { mPathToPresetDirectory.append("\\PhotoshopDDSPlugin\\"); if (!(CreateDirectory(mPathToPresetDirectory.c_str(), NULL) || ERROR_ALREADY_EXISTS == GetLastError())) { // Failed to create directory. plugin->UserError("Failed to Create Presets Directory"); } } else { // Failed to create directory. plugin->UserError("Failed to Create Presets Directory"); } } else { // Failed to create directory. plugin->UserError("Failed to get path to %USERPROFILE%\\AppData\\Local"); } } // Calculates log2 of number. double OptionsDialog::Log2( double n ) { // log(n)/log(2) is log2. return log( n ) / log( 2. ); } // =========================================================================== bool OptionsDialog::LoadPresetNonUIMode(string nameOfPreset) { //If not presets directory return with error if (mPathToPresetDirectory.empty()) return false; //Initialize with defaults InitDataNoPreset(mDialogData); //This loads all the settings and the last-used setting LoadPresets(); InitDataFromPreset(nameOfPreset); InitComboItems(); return true; } // =========================================================================== //Fill global plugin struct with UI data void OptionsDialog::FillGlobalStruct() { //Get the compressionType from the CompressionTypeComboBox, the combo box always has the list of the valid types //The itemUserData has the actual compression enumeration defined in IntelPlugin.h for a given combo box entry int copressionTypeID = gComboItems[COMPRESSION_COMBO].itemAndContextStrings[mDialogData.CompressionTypeIndex].itemUserData; switch (copressionTypeID) { case CompressionTypeEnum::BC1:globalParams->encoding_g = DXGI_FORMAT_BC1_UNORM; globalParams->fast_bc67 = false; break; case CompressionTypeEnum::BC1_SRGB:globalParams->encoding_g = DXGI_FORMAT_BC1_UNORM_SRGB; globalParams->fast_bc67 = false; break; case CompressionTypeEnum::BC3:globalParams->encoding_g = DXGI_FORMAT_BC3_UNORM; globalParams->fast_bc67 = false; break; case CompressionTypeEnum::BC3_SRGB:globalParams->encoding_g = DXGI_FORMAT_BC3_UNORM_SRGB; globalParams->fast_bc67 = false; break; case CompressionTypeEnum::BC6H_FAST:globalParams->encoding_g = DXGI_FORMAT_BC6H_UF16; globalParams->fast_bc67 = true; break; case CompressionTypeEnum::BC6H_FINE:globalParams->encoding_g = DXGI_FORMAT_BC6H_UF16; globalParams->fast_bc67 = false; break; case CompressionTypeEnum::BC7_FAST:globalParams->encoding_g = DXGI_FORMAT_BC7_UNORM; globalParams->fast_bc67 = true; break; case CompressionTypeEnum::BC7_FINE:globalParams->encoding_g = DXGI_FORMAT_BC7_UNORM; globalParams->fast_bc67 = false; break; case CompressionTypeEnum::BC7_SRGB_FAST:globalParams->encoding_g = DXGI_FORMAT_BC7_UNORM_SRGB; globalParams->fast_bc67 = true; break; case CompressionTypeEnum::BC7_SRGB_FINE:globalParams->encoding_g = DXGI_FORMAT_BC7_UNORM_SRGB; globalParams->fast_bc67 = false; break; case CompressionTypeEnum::BC4:globalParams->encoding_g = DXGI_FORMAT_BC4_UNORM; globalParams->fast_bc67 = false; break; case CompressionTypeEnum::BC5:globalParams->encoding_g = DXGI_FORMAT_BC5_UNORM; globalParams->fast_bc67 = false; break; case CompressionTypeEnum::UNCOMPRESSED:globalParams->encoding_g = DXGI_FORMAT_R8G8B8A8_UNORM; globalParams->fast_bc67 = false; break; default: globalParams->encoding_g = DXGI_FORMAT_BC1_UNORM; globalParams->fast_bc67 = false; break; } globalParams->TextureTypeIndex = mDialogData.TextureTypeIndex; //Col,Col+alpha,CubeFrmLayera,CubefromCross,NM globalParams->MipMapTypeIndex = mDialogData.MipMapTypeIndex; //None,Autogen,FromLayers globalParams->MipLevel = mDialogData.MipLevel; // only valid if SetMipLevel == true globalParams->SetMipLevel = mDialogData.SetMipLevel; globalParams->Normalize = mDialogData.Normalize; globalParams->FlipX = mDialogData.FlipX; globalParams->FlipY = mDialogData.FlipY; //presetBatchName is a PString (first byte is the size), convert C to PString CToPStr(mDialogData.PresetName.c_str(), reinterpret_cast(globalParams->presetBatchName)); } //Fill UI data struct with global plugin struct void OptionsDialog::GetGlobalStruct() { int CompressionTypeIndex=0; CompressionTypeEnum compressionID; //Find compression ID. switch (globalParams->encoding_g) { case DXGI_FORMAT_BC1_UNORM: compressionID = CompressionTypeEnum::BC1; break; case DXGI_FORMAT_BC1_UNORM_SRGB: compressionID = CompressionTypeEnum::BC1_SRGB; break; case DXGI_FORMAT_BC3_UNORM: compressionID = CompressionTypeEnum::BC3; break; case DXGI_FORMAT_BC3_UNORM_SRGB: compressionID = CompressionTypeEnum::BC3_SRGB; break; case DXGI_FORMAT_BC6H_UF16: if (globalParams->fast_bc67) compressionID = CompressionTypeEnum::BC6H_FAST; else compressionID = CompressionTypeEnum::BC6H_FINE; break; case DXGI_FORMAT_BC7_UNORM: if (globalParams->fast_bc67) compressionID = CompressionTypeEnum::BC7_FAST; else compressionID = CompressionTypeEnum::BC7_FINE; break; case DXGI_FORMAT_BC7_UNORM_SRGB: if (globalParams->fast_bc67) compressionID = CompressionTypeEnum::BC7_SRGB_FAST; else compressionID = CompressionTypeEnum::BC7_SRGB_FINE; break; case DXGI_FORMAT_BC4_UNORM: compressionID = CompressionTypeEnum::BC4; break; case DXGI_FORMAT_BC5_UNORM: compressionID = CompressionTypeEnum::BC5; break; case DXGI_FORMAT_R8G8B8A8_UNORM: compressionID = CompressionTypeEnum::UNCOMPRESSED; break; default: compressionID = CompressionTypeEnum::BC1; break; } //Iteration over all available compression for this texture type and find the compression combobox index. //Compression types which are not available are not show in the combo box, therefore the index is not incremented if matrix is false for (int i=0; iTextureTypeIndex, static_cast(i))) { //If its the selected encoding and this encoding is available then break out if (i == compressionID ) break; CompressionTypeIndex++; } } mDialogData.CompressionTypeIndex = CompressionTypeIndex; mDialogData.TextureTypeIndex = globalParams->TextureTypeIndex; //Col,Col+alpha,CubeFrmLayera,CubefromCross,NM mDialogData.MipMapTypeIndex = globalParams->MipMapTypeIndex; //None,Autogen,FromLayers mDialogData.MipLevel = globalParams->MipLevel; // only valid if SetMipLevel == true mDialogData.SetMipLevel = globalParams->SetMipLevel; mDialogData.Normalize = globalParams->Normalize; mDialogData.FlipX = globalParams->FlipX; mDialogData.FlipY = globalParams->FlipY; } // =========================================================================== //Fills in Combo items structures for Presets, Compression, Textype, and MipMap generation //fills control id, startindex and strings void OptionsDialog::InitComboItems() { gComboItems.reserve(NUMBEROF_COMBOS); gComboItems.push_back(ComboData(IDC_PRESET_COMBO)); GetPresetNames(gComboItems[PRESETS_COMBO]); gComboItems.push_back(ComboData(IDC_COMPRESSION_COMBO)); GetCompressionNames(gComboItems[COMPRESSION_COMBO]); gComboItems.push_back(ComboData(IDC_TEXTURETYPE_COMBO)); GetTextureTypeNames(gComboItems[TEXTURETYPE_COMBO]); gComboItems.push_back(ComboData(IDC_MIPMAP_COMBO)); GetMipMapNames(gComboItems[MIPMAP_COMBO]); } // =========================================================================== // Scan the %USERPROFILE%\\AppData\Local\\Intel\\PhotoshopDDSPlugin\\ folder to find .preset files and reads them in as preset data to populate the Presets dialog. void OptionsDialog::LoadPresets(void) { mPresets.clear(); //List all prest files string fullPath = mPathToPresetDirectory+"*.preset"; // Find the first file in the directory. WIN32_FIND_DATA ffd; HANDLE hFind = FindFirstFile(fullPath.c_str(), &ffd); if (INVALID_HANDLE_VALUE == hFind) { return; } // Walk the list of files in the dir that match our pattern and add the names to our list, skipping the 'none' preset file (handled separately). list fileNames; do { if (!(ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { string fname(ffd.cFileName); fileNames.push_back(fname); } } while (FindNextFile(hFind, &ffd) != 0); DWORD dwError = GetLastError(); if (dwError != ERROR_NO_MORE_FILES) { return; } FindClose(hFind); // Now, read the rest of the files and load up the presets menu with them. for (auto it = fileNames.begin(); it != fileNames.end(); ++it) { string presetPath = mPathToPresetDirectory + *it; ReadPreset(presetPath); } } // =========================================================================== //Fills in the DialogData structs which are stored in the mPresets array void OptionsDialog::ReadPreset(string fname) { ifstream fileIn; fileIn.open(fname); if (fileIn.is_open()) { string line; uint32 lineNum = 0; DialogData dd; size_t foundBSlash = fname.rfind("\\"); string justName = fname; if (foundBSlash != string::npos) { justName = fname.substr(foundBSlash+1); } else { size_t foundFSlash = fname.rfind("/"); // handle those other OSes. if (foundFSlash != string::npos) { justName = fname.substr(foundFSlash+1); } } size_t foundDot = justName.rfind("."); if (foundDot != string::npos) { dd.PresetName = justName.substr(0, foundDot); } else { dd.PresetName = justName; } try { while (getline(fileIn, line)) { bool done = false; switch (lineNum-1) { case -1: if (atoi(line.c_str()) != PRESET_FILE_VERSION) // version check throw std::exception(); case 0: dd.CompressionTypeIndex = atoi(line.c_str()); break; case 1: dd.TextureTypeIndex = static_cast(atoi(line.c_str())); break; case 2: dd.MipMapTypeIndex = static_cast(atoi(line.c_str())); break; case 3: dd.MipLevel = atoi(line.c_str()); break; case 4: dd.SetMipLevel = atoi(line.c_str()) == 1; break; case 5: dd.Normalize = atoi(line.c_str()) == 1; break; case 6: dd.FlipX = atoi(line.c_str()) == 1; break; case 7: dd.FlipY = atoi(line.c_str()) == 1; done = true; break; default: done = true; } ++lineNum; if (done) { break; } } if (dd.PresetName.compare(LAST_SETTINGS_PRESET_NAME) == 0) { mDialogData = dd; } else { mPresets[dd.PresetName] = dd; } } catch (std::exception &) { // bad settings read } fileIn.close(); } } // =========================================================================== // Writes the passed-in settings out to the specified file, so they'll be available as a preset next time the plugin loads. // Also updates the presets dropdown list. void OptionsDialog::SaveNewPreset(string presetName, DialogData dd) { bool fileWriteSucceeded = true; dd.PresetName = presetName; //path to new preset file string fullPath = mPathToPresetDirectory + presetName + ".preset"; ofstream fileOut; fileOut.open(fullPath); if (fileOut.is_open()) { fileOut << PRESET_FILE_VERSION << "\n"; fileOut << dd.CompressionTypeIndex << "\n"; fileOut << dd.TextureTypeIndex << "\n"; fileOut << dd.MipMapTypeIndex << "\n"; fileOut << dd.MipLevel << "\n"; fileOut << (dd.SetMipLevel ? "1" : "0") << "\n"; fileOut << (dd.Normalize ? "1" : "0") << "\n"; fileOut << (dd.FlipX ? "1" : "0") << "\n"; fileOut << (dd.FlipY ? "1" : "0") << "\n"; fileOut.close(); } else { fileWriteSucceeded = false; errorMessage("Can not save "+fullPath, "Preset save erorr"); } if (fileWriteSucceeded) { if ((presetName.compare(LAST_SETTINGS_PRESET_NAME) == 0) && (!mPresets.empty())) { // TODO } else { mPresets[presetName] = dd; } // Update the main working data InitDataFromPreset(presetName); mDialogData.PresetName = presetName; // rebuild combo items data list for presets ComboData & cd = gComboItems[PRESETS_COMBO]; cd.itemAndContextStrings.clear(); GetPresetNames(cd); // rebuild combobox for presets -- making sure it has the right selected item (newly created preset) InitComboFromItems(PRESETS_COMBO); // Update UI to reflect new Preset. SetUIFromData(); } } void OptionsDialog::UpdatePreset(string presetName, DialogData dd) { dd.PresetName = presetName; //path to existing preset file string fullPath = mPathToPresetDirectory + presetName + ".preset"; ofstream fileOut; fileOut.open(fullPath); //Save change into preset file if (fileOut.is_open()) { fileOut << PRESET_FILE_VERSION << "\n"; fileOut << dd.CompressionTypeIndex << "\n"; fileOut << dd.TextureTypeIndex << "\n"; fileOut << dd.MipMapTypeIndex << "\n"; fileOut << dd.MipLevel << "\n"; fileOut << (dd.SetMipLevel ? "1" : "0") << "\n"; fileOut << (dd.Normalize ? "1" : "0") << "\n"; fileOut << (dd.FlipX ? "1" : "0") << "\n"; fileOut << (dd.FlipY ? "1" : "0") << "\n"; fileOut.close(); } else { errorMessage("Can not save "+fullPath, "Preset save erorr"); } //Save change also into mPresets array mPresets[presetName] = dd; } // =========================================================================== // Remove a preset from the list and delete the .preset file for it. void OptionsDialog::DeletePreset(string presetName) { if (mPresets.erase(presetName)) { // rebuild combo items data list for presets ComboData & cd = gComboItems[PRESETS_COMBO]; cd.itemAndContextStrings.clear(); GetPresetNames(cd); // rebuild combobox for presets -- making sure it has the right selected item (newly created preset) InitComboFromItems(PRESETS_COMBO); // Update UI to reflect new Preset. SetUIFromData(); //path to presets file string fullPath = mPathToPresetDirectory + presetName + ".preset"; BOOL fileDeleted = DeleteFile(fullPath.c_str()); if (!fileDeleted) { errorMessage("Can not delete "+fullPath, "Preset delete erorr"); } } } // =========================================================================== // Initialize a DialogData structure (dd) with default settings void OptionsDialog::InitDataNoPreset(DialogData & dd) { dd.PresetName = LAST_SETTINGS_PRESET_NAME; dd.CompressionTypeIndex = 0; dd.TextureTypeIndex = TextureTypeEnum::COLOR; dd.MipMapTypeIndex = MipmapEnum::NONE; dd.SetMipLevel = false; dd.MipLevel = 0; dd.Normalize = false; dd.FlipX = false; dd.FlipY = false; } // =========================================================================== // Populate the mDialogData with the UI settings from the specified Preset in mPresets. void OptionsDialog::InitDataFromPreset(string presetName) { auto item = mPresets.find(presetName); if (item != mPresets.end()) mDialogData = item->second; } // =========================================================================== //Fill now the combo controls with the strings stored in the ComboData structs void OptionsDialog::InitComboFromItems(int32 comboItemsIndex) { ComboData & cd = gComboItems[comboItemsIndex]; PIComboBox combo = GetItem(cd.itemNum); combo.Clear(); if (!cd.itemAndContextStrings.empty()) { //Add the description strings to the Combo box for (size_t i = 0; i < cd.itemAndContextStrings.size(); ++i) { combo.AppendItem(cd.itemAndContextStrings[i].itemText.c_str()); } //Set the selected item uint32 selectedIndex = cd.startIndex; combo.SetCurrentSelection(selectedIndex); //Iterate over only the 3 combo boxes and set the text of the according Context Control //Compression, Textype, and MipMap for (uint32 j = 0; j < sizeof(gComboContextItems) / sizeof(ComboAndContextStringID); ++j) { if (cd.itemNum == gComboContextItems[j].itemNum) { PIText sText = GetItem(gComboContextItems[j].contextItemNum); sText.SetText(cd.itemAndContextStrings[selectedIndex].itemContextInfo); break; } } } } // =========================================================================== // Override the combo box font so as to get alignment right void OptionsDialog::SetFontCompressionCombo() { PIComboBox comboCompression = GetItem(IDC_COMPRESSION_COMBO); PIComboBox comboTexType = GetItem(IDC_TEXTURETYPE_COMBO); PIComboBox comboMipMap = GetItem(IDC_MIPMAP_COMBO); LOGFONT lf = {}; // to define the font lf.lfHeight = 14; //lf.lfWidth = ; lf.lfWeight = FW_NORMAL; lf.lfCharSet = ANSI_CHARSET; lf.lfOutPrecision = OUT_DEFAULT_PRECIS; lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; lf.lfQuality = PROOF_QUALITY; lf.lfPitchAndFamily = FIXED_PITCH | FF_MODERN; strcpy(lf.lfFaceName,"Consolas"); if (auto hFont = ::CreateFontIndirect(&lf)) { SendMessage(comboCompression.GetItem(), WM_SETFONT, reinterpret_cast(hFont), TRUE); SendMessage(comboTexType.GetItem(), WM_SETFONT, reinterpret_cast(hFont), TRUE); SendMessage(comboMipMap.GetItem(), WM_SETFONT, reinterpret_cast(hFont), TRUE); } } // =========================================================================== // Main initialization of the UI - Load the preset files, build out the programmatically populated UI items, and set the initial UI state. void OptionsDialog::Init(void) { //Set window name string windowTitle = DDSExporterPluginName; windowTitle += DDSExporterPluginVersion; SetWindowText(GetDialog(), windowTitle.c_str()); //If not presets directory return with error if (mPathToPresetDirectory.empty()) return; InitDataNoPreset(mDialogData); // sets defaults, may be overridden in next call LoadPresets(); //Fills in gComboItems array for Presets, Compression, Textype, and MipMap generation InitComboItems(); //Now fill in Combo boxes with text and the correxponding context controls with text for (int32 i = 0; i < gComboItems.size(); ++i) { InitComboFromItems(i); } // Override the combo box font so as to get alignment right SetFontCompressionCombo(); PICheckBox setMipLevel = GetItem(IDC_CUBEMIPLEVEL_CHECK); setMipLevel.SetChecked(mDialogData.SetMipLevel); //Fill in the miplevel selector for cube maps if (mDialogData.SetMipLevel) { PopulateMipLevelsCombo(); } else { PIComboBox mipLevelCombo = GetItem(IDC_MIPLEVEL_COMBO); mipLevelCombo.Clear(); } PICheckBox normalizeCheck = GetItem(IDC_NORMALIZE_CHECK); normalizeCheck.SetChecked(mDialogData.Normalize); PICheckBox flipXCheck = GetItem(IDC_FLIPX_CHECK); flipXCheck.SetChecked(mDialogData.FlipX); PICheckBox flipYCheck = GetItem(IDC_FLIPY_CHECK); flipYCheck.SetChecked(mDialogData.FlipY); //Disable any controls they do not apply based on the choosen texture type DisableUnavailableControls(); } // =========================================================================== // Update the UI state based on the current state of the current mDialogData struct. void OptionsDialog::SetUIFromData() { //Change entries in compression/mipmap combo based on texture type UpdateCompressionCombo(); UpdateMipMapCombo(); //Initialize compression combo from mDialogData.CompressionTypeIndex PIComboBox CompressionCombo = GetItem(IDC_COMPRESSION_COMBO); CompressionCombo.SetCurrentSelection(mDialogData.CompressionTypeIndex); //Update context string based on selected entry SetContextString(IDC_COMPRESSION_HINT, IDC_COMPRESSION_COMBO); //Initialize texture type combo from mDialogData.TextureTypeIndex PIComboBox TextureTypeCombo = GetItem(IDC_TEXTURETYPE_COMBO); TextureTypeCombo.SetCurrentSelection(mDialogData.TextureTypeIndex); //Update context string based on selected entry SetContextString(IDC_TEXTURETYPE_HINT, IDC_TEXTURETYPE_COMBO); //Initialize mip map creation combo from mDialogData.MipMapTypeIndex PIComboBox MipMapCombo = GetItem(IDC_MIPMAP_COMBO); MipMapCombo.SetCurrentSelection(mDialogData.MipMapTypeIndex); //Update context string based on selected entry SetContextString(IDC_MIPMAPS_HINT, IDC_MIPMAP_COMBO); PICheckBox mipLevelCheck = GetItem(IDC_CUBEMIPLEVEL_CHECK); bool wasMipLevelChecked = mipLevelCheck.GetChecked(); mipLevelCheck.SetChecked(mDialogData.SetMipLevel); if (wasMipLevelChecked && !mDialogData.SetMipLevel) { PIComboBox MipMapLevelCombo = GetItem(IDC_MIPLEVEL_COMBO); MipMapLevelCombo.Clear(); } else if (!wasMipLevelChecked && mDialogData.SetMipLevel) { PopulateMipLevelsCombo(); } else if (wasMipLevelChecked && mDialogData.SetMipLevel) { PIComboBox MipMapLevelCombo = GetItem(IDC_MIPLEVEL_COMBO); MipMapLevelCombo.SetCurrentSelection(mDialogData.MipLevel); } PICheckBox NormalizeCheckBox = GetItem(IDC_NORMALIZE_CHECK); NormalizeCheckBox.SetChecked(mDialogData.Normalize); PICheckBox FlipXCheckBox = GetItem(IDC_FLIPX_CHECK); FlipXCheckBox.SetChecked(mDialogData.FlipX); PICheckBox FlipYCheckBox = GetItem(IDC_FLIPY_CHECK); FlipYCheckBox.SetChecked(mDialogData.FlipY); //Disable any controls they do not apply based on the choosen texture type DisableUnavailableControls(); } // =========================================================================== // Called whenever user interacts with the UI - clicks a button or ticks a check box, selects a dropdown, etc. //parameters index: has the resource index of the control acted upon. void OptionsDialog::Notify(int index) { //Shows MessageBox for help [?] buttons. Index into array and get function which return strings to display for (uint32 i = 0; i < sizeof(helpButtonTextItem) / sizeof(HelpButtonAndTextFunc); ++i) { if (index == helpButtonTextItem[i].itemNum) { vector captionAndText = helpButtonTextItem[i].func(); MessageBox(GetActiveWindow(), captionAndText[0].c_str(), captionAndText[1].c_str(), 0); return; } } //One of the Combo boxes was changed, update context string for (uint32 i = 0; i < sizeof(gComboContextItems) / sizeof(ComboAndContextStringID); ++i) { if (index == gComboContextItems[i].itemNum) { //Update context string based on selected entry SetContextString(gComboContextItems[i].contextItemNum, index); break; // no return - want this to fall through to the end block that backs up the change. } } if (index == IDC_CUBEMIPLEVEL_CHECK) { PICheckBox mipLevelCheck = GetItem(IDC_CUBEMIPLEVEL_CHECK); if (mipLevelCheck.GetChecked()) { PopulateMipLevelsCombo(); } else { PIComboBox mipLevelCombo = GetItem(IDC_MIPLEVEL_COMBO); mipLevelCombo.Clear(); } // no return - want this to fall through to the end block that backs up the change. } //Change preset, preset combo whas changed if (index == IDC_PRESET_COMBO) { PIComboBox presetCombo = GetItem(IDC_PRESET_COMBO); string selectedItem; //if (command == CBN_SELCHANGE) { //Get the string entry of the selected item in the combo box presetCombo.GetCurrentSelection(selectedItem); //Did we select a different preset if (selectedItem.compare(mDialogData.PresetName) != 0) { //Store changes in current preset before swapping #ifdef AUTO_SAVE_PRESETS UpdatePreset(mDialogData.PresetName, mDialogData); #endif //Load new data in struct InitDataFromPreset(selectedItem); //Update UI from struct SetUIFromData(); // If we want a callback or notify that a preset has changed, here is where to place that call. } } return; } if (index == IDC_PRESETDELETE_BUTTON) { PIComboBox presetCombo = GetItem(IDC_PRESET_COMBO); string selectedPreset; presetCombo.GetCurrentSelection(selectedPreset); if (selectedPreset.compare(LAST_SETTINGS_PRESET_NAME) == 0) { MessageBox(GetActiveWindow(), "You must select a preset from the dropdown to be deleted", "Delete Preset", MB_OK); return; } stringstream ss; // TODO -- localization? ss << "Are you sure you want to delete the preset: " << selectedPreset << "?"; int delResult = MessageBox(GetActiveWindow(), ss.str().c_str(), "Delete Preset", MB_OKCANCEL); if (delResult == IDOK) { DeletePreset(selectedPreset); } return; } if (index == IDC_PRESETSAVE_BUTTON) { PIComboBox presetCombo = GetItem(IDC_PRESET_COMBO); string newPresetName; presetCombo.GetCurrentSelection(newPresetName); newPresetName = GetPresetName(newPresetName, GetActiveWindow()); if (!newPresetName.empty()) { bool doSave = mPresets.find(newPresetName) == mPresets.end(); if (!doSave) // already exists? { doSave = IDOK == MessageBox(GetActiveWindow(), "That Preset name exists - save over it?", "Confirm Save", MB_OKCANCEL); } if (doSave) { DialogData dd; ExtractDataFromUI(dd); SaveNewPreset(newPresetName, dd); } } return; } if (index == IDC_PREVIEW_BUTTON) { //Copy over UI to global struct for preview routined FillGlobalStruct(); //Show previewUI (modal does not return until OK is pressed) PreviewDialog dlg(plugin); dlg.Modal(); //Copy any changes back into UI struct (preview can change compression) GetGlobalStruct(); //Update UI from struct SetUIFromData(); return; } if (index == IDOK) // OK button pressed. { PIComboBox presetCombo = GetItem(IDC_PRESET_COMBO); presetCombo.GetCurrentSelection(mDialogData.PresetName); ExtractDataFromUI(mDialogData); //We have the none preset set so save only to the none preset so that it remember the next time it loads if (mDialogData.PresetName.compare(LAST_SETTINGS_PRESET_NAME) == 0) { UpdatePreset(LAST_SETTINGS_PRESET_NAME, mDialogData); } else { //Update currently set preset and none preset so that it remember the next time it loads #ifdef AUTO_SAVE_PRESETS UpdatePreset(mDialogData.PresetName, mDialogData); #endif UpdatePreset(LAST_SETTINGS_PRESET_NAME, mDialogData); } return; } auto old = mDialogData; //Some other changes happened to the UI which did not have custom actions just update the struct ExtractDataFromUI(mDialogData); //Rebuild CompressionTypes Combo box and disable not applicable controls //If Texture or MipMap type changed (apply last to have mDialog updated) if (old.TextureTypeIndex != mDialogData.TextureTypeIndex || old.MipMapTypeIndex != mDialogData.MipMapTypeIndex) { //Update compression/mipmap combo box UpdateCompressionCombo(); UpdateMipMapCombo(); //Disable any controls they do not apply based on the choosen texture type DisableUnavailableControls(); } } // =========================================================================== // Interrogate the state of the UI elements to find their current selections and copy that into the specified DialogData struct (dd) void OptionsDialog::ExtractDataFromUI(DialogData & dd) { dd.CompressionTypeIndex = GetSelectedItem(IDC_COMPRESSION_COMBO); dd.TextureTypeIndex = static_cast(GetSelectedItem(IDC_TEXTURETYPE_COMBO)); dd.MipMapTypeIndex = static_cast(GetSelectedItem(IDC_MIPMAP_COMBO)); PICheckBox MipLevelCheck = GetItem(IDC_CUBEMIPLEVEL_CHECK); dd.SetMipLevel = MipLevelCheck.GetChecked(); if (dd.SetMipLevel) { uint32 MipLevelIndex = GetSelectedMipLevelIndex(); dd.MipLevel = MipLevelIndex; } PICheckBox NormalizeCheck = GetItem(IDC_NORMALIZE_CHECK); dd.Normalize = NormalizeCheck.GetChecked(); PICheckBox FlipXCheck = GetItem(IDC_FLIPX_CHECK); dd.FlipX = FlipXCheck.GetChecked(); PICheckBox FlipYCheck = GetItem(IDC_FLIPY_CHECK); dd.FlipY = FlipYCheck.GetChecked(); } //Enables or disables caontrols depending on the texture type void OptionsDialog::DisableUnavailableControls() { PICheckBox NormalizeCheck = GetItem(IDC_NORMALIZE_CHECK); PICheckBox FlipXCheck = GetItem(IDC_FLIPX_CHECK); PICheckBox FlipYCheck = GetItem(IDC_FLIPY_CHECK); PICheckBox MipLevelCheck = GetItem(IDC_CUBEMIPLEVEL_CHECK); PIComboBox combo = GetItem(IDC_MIPLEVEL_COMBO); //if texture type normal map then enable/disable relevant checkboxes if (mDialogData.TextureTypeIndex != TextureTypeEnum::NORMALMAP) { //disable and clear normalize checkbox ::EnableWindow(NormalizeCheck.GetItem(), false); NormalizeCheck.SetChecked(false); //disable and clear flipx checkbox ::EnableWindow(FlipXCheck.GetItem(), false); FlipXCheck.SetChecked(false); //disable and clear flipy checkbox ::EnableWindow(FlipYCheck.GetItem(), false); FlipYCheck.SetChecked(false); } else { //enable normalize, flipx,y checkboxes ::EnableWindow(NormalizeCheck.GetItem(), true); ::EnableWindow(FlipXCheck.GetItem(), true); ::EnableWindow(FlipYCheck.GetItem(), true); } //if texture type is/isnot cubemap then enable/disable combo+checkbox if (mDialogData.TextureTypeIndex != TextureTypeEnum::CUBEMAP_CROSSED && mDialogData.TextureTypeIndex != TextureTypeEnum::CUBEMAP_LAYERS) { //disable miplevel checkbox and combo ::EnableWindow(MipLevelCheck.GetItem(), false); ::EnableWindow(combo.GetItem(), false); //uncheck and clear MipLevelCheck.SetChecked(false); combo.Clear(); } else { //enable miplevel checkbox and combo ::EnableWindow(MipLevelCheck.GetItem(), true); ::EnableWindow(combo.GetItem(), true); } } //Update compression combo box based on textyreType. Convenience funtion void OptionsDialog::UpdateCompressionCombo() { //Fill new entries into struct GetCompressionNames(gComboItems[COMPRESSION_COMBO]); //Clear and fill combo box from struct InitComboFromItems(COMPRESSION_COMBO); } //Update mipmap combo box based on textyreType. Convenience funtion void OptionsDialog::UpdateMipMapCombo() { //Fill new entries into struct GetMipMapNames(gComboItems[MIPMAP_COMBO]); //Clear and fill combo box from struct InitComboFromItems(MIPMAP_COMBO); } // =========================================================================== // Populate the data struct for the Presets dropdown list - uses the mPresets filled in from LoadPresets(). void OptionsDialog::GetPresetNames(ComboData & comboItem) { comboItem.startIndex = -1; comboItem.itemAndContextStrings.clear(); //push info for stored presets for (auto it = mPresets.begin(); it != mPresets.end(); ++it) { comboItem.itemAndContextStrings.push_back(ComboItemAndContext(it->first, "")); if (it->first.compare(mDialogData.PresetName) == 0) { comboItem.startIndex = static_cast(comboItem.itemAndContextStrings.size()-1); } } } // =========================================================================== void OptionsDialog::GetCompressionNames(ComboData & comboItem) { comboItem.itemAndContextStrings.clear(); //BC1, BC1_SRGB, BC3, BC3_SRGB, BC6H_FAST, BC6H_FINE, BC7_FAST, BC7_FINE, BC7_SRGB_FAST, BC7_SRGB_FINE, BC4, BC5, NONE if (IntelPlugin::IsCombinationValid(mDialogData.TextureTypeIndex,CompressionTypeEnum::BC1)) comboItem.itemAndContextStrings.push_back(ComboItemAndContext("BC1 4bpp (Linear)", "Also DXT1. Maximum compatibility. No Alpha Channel", CompressionTypeEnum::BC1)); if (IntelPlugin::IsCombinationValid(mDialogData.TextureTypeIndex,CompressionTypeEnum::BC1_SRGB)) comboItem.itemAndContextStrings.push_back(ComboItemAndContext("BC1 4bpp (sRGB, DX10+)", "No Alpha Channel. Use SRGB gamma.", CompressionTypeEnum::BC1_SRGB)); if (IntelPlugin::IsCombinationValid(mDialogData.TextureTypeIndex,CompressionTypeEnum::BC3)) comboItem.itemAndContextStrings.push_back(ComboItemAndContext("BC3 8bpp (Linear)", "Also DXT5. Maximum compatibility. Supports Alpha.", CompressionTypeEnum::BC3)); if (IntelPlugin::IsCombinationValid(mDialogData.TextureTypeIndex,CompressionTypeEnum::BC3_SRGB)) comboItem.itemAndContextStrings.push_back(ComboItemAndContext("BC3 8bpp (sRGB, DX10+)", "Supports Alpha. Use sRGB gamma.", CompressionTypeEnum::BC3_SRGB)); if (IntelPlugin::IsCombinationValid(mDialogData.TextureTypeIndex,CompressionTypeEnum::BC6H_FAST)) comboItem.itemAndContextStrings.push_back(ComboItemAndContext("BC6H 8bpp Fast (Linear, DX11+)", "16 bit HDR images. No alpha. Only DX11+ level H/W. Fast Intel compression settings.", CompressionTypeEnum::BC6H_FAST)); if (IntelPlugin::IsCombinationValid(mDialogData.TextureTypeIndex,CompressionTypeEnum::BC6H_FINE)) comboItem.itemAndContextStrings.push_back(ComboItemAndContext("BC6H 8bpp Fine (Linear, DX11+)", "16 bit HDR images. No alpha. Only DX11+ level H/W. Fine Intel compression settings.", CompressionTypeEnum::BC6H_FINE)); if (IntelPlugin::IsCombinationValid(mDialogData.TextureTypeIndex,CompressionTypeEnum::BC7_FAST)) comboItem.itemAndContextStrings.push_back(ComboItemAndContext("BC7 8bpp Fast (Linear, DX11+)", "Best quality. Supports Alpha. Only DX11+ level H/W. Fast Intel compression settings.", CompressionTypeEnum::BC7_FAST)); if (IntelPlugin::IsCombinationValid(mDialogData.TextureTypeIndex,CompressionTypeEnum::BC7_FINE)) comboItem.itemAndContextStrings.push_back(ComboItemAndContext("BC7 8bpp Fine (Linear, DX11+)", "Best quality. Supports Alpha. Only DX11+ level H/W. Fine Intel compression settings.", CompressionTypeEnum::BC7_FINE)); if (IntelPlugin::IsCombinationValid(mDialogData.TextureTypeIndex,CompressionTypeEnum::BC7_SRGB_FAST)) comboItem.itemAndContextStrings.push_back(ComboItemAndContext("BC7 8bpp Fast (sRGB, DX11+)", "Best quality. Supports Alpha. Only DX11+ level H/W. Fast Intel compression settings. Use sRGB gamma.", CompressionTypeEnum::BC7_SRGB_FAST)); if (IntelPlugin::IsCombinationValid(mDialogData.TextureTypeIndex,CompressionTypeEnum::BC7_SRGB_FINE)) comboItem.itemAndContextStrings.push_back(ComboItemAndContext("BC7 8bpp Fine (sRGB, DX11+)", "Best quality. Supports Alpha. Only DX11+ level H/W. Fine Intel compression settings. Use sRGB gamma.", CompressionTypeEnum::BC7_SRGB_FINE)); if (IntelPlugin::IsCombinationValid(mDialogData.TextureTypeIndex,CompressionTypeEnum::BC4)) comboItem.itemAndContextStrings.push_back(ComboItemAndContext("BC4 4bpp (Linear, Grayscale)", "For Grayscale images, smallest size. Only the first image channel is used.", CompressionTypeEnum::BC4)); if (IntelPlugin::IsCombinationValid(mDialogData.TextureTypeIndex,CompressionTypeEnum::BC5)) comboItem.itemAndContextStrings.push_back(ComboItemAndContext("BC5 8bpp (Linear, 2 Channel tangent map)", "Use for Normalmap encoding. Best quality. Only the first two image channels are used.", CompressionTypeEnum::BC5)); if (IntelPlugin::IsCombinationValid(mDialogData.TextureTypeIndex,CompressionTypeEnum::UNCOMPRESSED)) comboItem.itemAndContextStrings.push_back(ComboItemAndContext("none 32bpp", "Lossless, no compression applied.", CompressionTypeEnum::UNCOMPRESSED)); if (mDialogData.CompressionTypeIndex < comboItem.itemAndContextStrings.size()) { comboItem.startIndex = mDialogData.CompressionTypeIndex; } else // Somehow have an index off the end of the list? Reset to 0... best to be safe. { comboItem.startIndex = 0; } } // =========================================================================== void OptionsDialog::GetTextureTypeNames(ComboData & comboItem) { comboItem.itemAndContextStrings.push_back(ComboItemAndContext("Color", "Export only the RGB channels.")); comboItem.itemAndContextStrings.push_back(ComboItemAndContext("Color + Alpha", "Export RGB and alpha channel.")); comboItem.itemAndContextStrings.push_back(ComboItemAndContext("Cube Map from Layers", "Export a cube map using layers for faces (6 layers required).")); comboItem.itemAndContextStrings.push_back(ComboItemAndContext("Cube Map from crossed image", "Export a cube map from faces arranged in a horizontal or vertical crossed format.")); comboItem.itemAndContextStrings.push_back(ComboItemAndContext("Normal Map", "Export as a normal map.")); if (mDialogData.TextureTypeIndex < comboItem.itemAndContextStrings.size()) { comboItem.startIndex = mDialogData.TextureTypeIndex; } else // Somehow have an index off the end of the list? Reset to 0... best to be safe. { comboItem.startIndex = 0; } } // =========================================================================== void OptionsDialog::GetMipMapNames(ComboData & comboItem) { comboItem.itemAndContextStrings.clear(); comboItem.itemAndContextStrings.push_back(ComboItemAndContext("None", "No Mip Maps.")); comboItem.itemAndContextStrings.push_back(ComboItemAndContext("Auto Generate", "Autogenerate Mip Maps.")); //If cube maps user can not specify its own mip levels if (mDialogData.TextureTypeIndex != TextureTypeEnum::CUBEMAP_CROSSED && mDialogData.TextureTypeIndex != TextureTypeEnum::CUBEMAP_LAYERS) comboItem.itemAndContextStrings.push_back(ComboItemAndContext("From Layers", "Mip Maps are specified by the user, stored in layers.")); if (mDialogData.MipMapTypeIndex < comboItem.itemAndContextStrings.size()) { comboItem.startIndex = mDialogData.MipMapTypeIndex; } else // Somehow have an index off the end of the list? Reset to 0... best to be safe. { comboItem.startIndex = 0; } } // =========================================================================== //Fills the combo which allows to slect a mip level for cube map export void OptionsDialog::PopulateMipLevelsCombo() { PIComboBox mipLevelCombo = GetItem(IDC_MIPLEVEL_COMBO); mipLevelCombo.Clear(); for (uint32 i = 0; i <= MaxMipLevel; ++i) { stringstream s; s << i; mipLevelCombo.AppendItem(s.str().c_str()); } uint32 selectedIndex = mDialogData.MipLevel; // Convert level to index mipLevelCombo.SetCurrentSelection(selectedIndex); } // =========================================================================== vector GetCompressionHelpText(void) { vector vs; // Help Text vs.push_back("Specify the compression settings for the dds texture.\n\n\ BC1: Also known as DXT1. Uses 4 bits per pixel and contains RGB types of data. Useful for color maps or normal maps if memory is tight.\n\n\ BC3: Also known as DXT5. Uses 8 bits per pixel and contains RGBA types of data. Useful for color maps with full alpha, packing color and mono maps together\n\n\ BC4: Uses 4 bits per pixel and contains grey-scale types of data. Useful for height maps, gloss maps, font atlases or any other grey-scale image.\n\n\ BC5: Uses 8 bits per pixel and contains 2 x grey-scale types of data. Useful for tangent space normal maps.\n\n\ BC6: Uses 8 bits per pixel and contains RGB floating point types of data. Useful for HDR 16 images but works only on DX11+ level hardware.\n\n\ BC7: Uses 8 bits per pixel and contains RGBA types of data. Useful for high quality color maps, color maps with full alpha. It provides the best quality compression ratio but needs DX11+ level hardware."); vs.push_back("Compression Options"); // Window Caption return vs; } // =========================================================================== vector GetTextureTypeHelpText(void) { vector vs; // Help Text vs.push_back("Specify in what way the data in your texture should be exported.\n\n\ Color: Export only the RGB part of the image. Use for Images without alpha or when alpha is not wanted. Can also be combined with BC4 to get the R channel as a grey-scale image, or BC5 to get the RG channels as a tangent space normal map.\n\n\ Color+Alpha: Same as Color, but also save the alpha channel.\n\n\ CubeMap from Layers: Export as a cube map consisting of six separate images specified in Layers. The layer names designate the face that each layer corresponds to. \n\ \"-X\" is Left, \"+Z\" is Front, \"+X\" is Right, \"-Z\" is Back, \"+Y\" is Top, \"-Y\" is Bottom.\n\n\ CubeMap Crossed: Export as a cube map. The image has all the cube map faces unwrapped needs to be in horizontal or vertical cross layout with aspect ratio 4x3 or 3x4.\n\n\ For cube maps, a specific mip level can be selected for exporting a low resolution cube map which is useful for low end platforms or when a blurred cube map is needed.\n\n\ Normal Map: Export as Normal Map. The Normalization option is available as a post process step which normalizes the values. The Flip Red(X) and Flip Green (Y) \ option is also available as a post-process which inverts the X, Y component of the Normal Map.\n\n\ Depending on the texture type chosen, the compression formats that are not compatible are removed and cannot be selected. The special \ post-process operations that do not apply are disabled."); vs.push_back("Texture Type Options"); // Window Caption return vs; } // =========================================================================== vector GetPreCompressOpsHelpText(void) { vector vs; vs.push_back("These are convenience functions that are applied before a Normal map export.\n\n\ Normalization: This operation normalizes the Normal Map vector values for the image and all its mip maps.\n\n\ Flip Red (X): This operation inverts the Red channel of the Normal Map.\n\n\ Flip Green (Y): This operation inverts the Green channel of the Normal Map so that bumps become indents and indents become bumps.\n\ Note that in order to flip normal maps correctly both the Red and Green channel have to be inverted."); // Help Text vs.push_back("Pre Compression Normal Map Operations"); // Window Caption return vs; } // =========================================================================== vector GetMipMapsHelpText(void) { vector vs; vs.push_back("Specify if the image will have mip maps pre-calculated in the dds file.\n\n\ None: No Mip Maps will be generated for this image.\n\n\ Auto Generate: The Mip Maps will be generated automatically by resizing the original image using a box filter. The whole Mip Map range will be created \ starting from the original size until a 1x1 texture is reached.\n\n\ From Layers: The Mip Maps will be created from the Layers within the image. It is the responsibility of the creator to specify the correct size and the correct amount. \ The base layer will hold the first mip level (i.e. mip level 0, or the original image) and each layer after that specifies the next mip map in the chain.\n\n\ Its not needed to specify all the mip maps, the user can choose to create a small consecutive range. The rest will be autogenerated.\n\n\ Please remember that each mip level is half the size in dimension of its previous level image and the smallest size is 1x1."); // Help Text vs.push_back("MipMap Generation Options"); // Window Caption return vs; } // =========================================================================== //Changes the context Text field of the combo box //parameters contextStringID: id of context text control, index: ID of combo box control void OptionsDialog::SetContextString(uint32 contextStringID, uint32 index) { //Get controls PIText sText = GetItem(contextStringID); PIComboBox combo = GetItem(index); //Get the index straight from control int combo_index = int(SendMessage(combo.GetItem(), CB_GETCURSEL, 0, 0)); // find the struct with the combo box data for the selected combo box // search the array where cobo items are stored for (uint32 j = 0; j < gComboItems.size(); ++j) { //Correct combo box if (gComboItems[j].itemNum == index) { sText.SetText(gComboItems[j].itemAndContextStrings[combo_index].itemContextInfo); return; } } } // =========================================================================== uint32 OptionsDialog::GetSelectedItem(uint32 comboBoxID) { PIComboBox combo = GetItem(comboBoxID); //Get the index straight from control int index = int(SendMessage(combo.GetItem(), CB_GETCURSEL, 0, 0)); return index; } // =========================================================================== uint32 OptionsDialog::GetSelectedMipLevelIndex() { PIComboBox combo = GetItem(IDC_MIPLEVEL_COMBO); string selectedText; combo.GetCurrentSelection(selectedText); // Could replace atoi() call with a struct to track the values pushed into the dropdown, or a GetSelectedIndex() function on the PIComboBox itself. int mipLevelValue = atoi(selectedText.c_str()); return mipLevelValue; } int32 OptionsDialog::DoModal(IntelPlugin* plugin) { OptionsDialog dialog(plugin); int32 id = IDOK; if (plugin->GetData()->queryForParameters) { //Interactive mode, show UI id = dialog.Modal(NULL, NULL, IDD_MAINDIALOG); } else { //presetBatchName is a PString (first byte is the size) string presetStringname = reinterpret_cast(plugin->GetData()->presetBatchName)+1; //Load preset without UI id = dialog.LoadPresetNonUIMode(presetStringname)?1:2; } if (id == IDOK) { //Fill gloabl struct with UI info dialog.FillGlobalStruct(); } return id; } #endif // #if !__LP64__ // end PropetizerUI.cpp ================================================ FILE: IntelCompressionPlugin/SaveOptionsDialog.h ================================================ //////////////////////////////////////////////////////////////////////////////// // Copyright 2017 Intel Corporation // // Licensed under the Apache License, Version 2.0 (the "License"); you may not // use this file except in compliance with the License. You may obtain a copy // of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the // License for the specific language governing permissions and limitations // under the License. //////////////////////////////////////////////////////////////////////////////// #pragma once #include "PIUI.h" #include "IntelPlugin.h" #undef true #undef false #include #include //This struct hold the UI data, all info do produced a compressed image is located here. used also to store/load into presets. struct DialogData { // NOTE - assumed to be POD. std::string PresetName; //The name of this preset uint32 CompressionTypeIndex; //The current selection index of the combo box holding the compression. Translate into encoding with matrix CompressionVsTextureTypeMatrix in IntelPlugin.cpp TextureTypeEnum TextureTypeIndex; //Holds the texture type of the image MipmapEnum MipMapTypeIndex; //Holds the mip map generation method uint32 MipLevel; // only valid if SetMipLevel == true, specified the mip level to be exported when in cube map mode. bool SetMipLevel; //Specify that a specific mip level has to be exported. Only valid for cube map mode. bool Normalize; //Specify if normalization of values is needed. Only valid for Normal Maps bool FlipX; bool FlipY; }; // Our main class - handles creation of and all input to the Export dialog UI. class OptionsDialog : public PIDialog { private: // Struct to hold a dropdown list item and the corresponding context info for it. // The userData field can hold specific IDs depending on the dropdown. For example in the compression drop box it holds the CompressionTypeEnum ID. // Assembled for each such dropdown in functions below. struct ComboItemAndContext { string itemText; string itemContextInfo; int itemUserData; ComboItemAndContext(string text, string contextInfo, int userData=0) : itemText(text), itemContextInfo(contextInfo), itemUserData(userData) { } }; // Data to init the dropdown lists (Windows calls them ComboBoxes) struct ComboData { const uint32 itemNum; // WinForm ID of the dropdown list for this particular dropdown uint32 startIndex; // Which item in the dropdown to select when creating the list - 0 unless a preset is being loaded. vector itemAndContextStrings; // list of strings and any corresponding context info for the dropdown list (context could be blank) explicit ComboData(int num) : itemNum(num) { } }; enum {PRESETS_COMBO, COMPRESSION_COMBO, TEXTURETYPE_COMBO, MIPMAP_COMBO, NUMBEROF_COMBOS}; IntelPlugin* plugin; //Pointer to photoshop API IntelPlugin::Globals* globalParams; //Pointer to photoshop API DialogData mDialogData; // Current working data set - updated based on user interaction with UI map mPresets; vector gComboItems; // The master list of dropdown init data. string mPathToPresetDirectory; uint32 MaxMipLevel; // based on image properties void LoadPresets(void); void ReadPreset(string fname); void SaveNewPreset(string presetName, DialogData dd); void UpdatePreset(string presetName, DialogData dd); void DeletePreset(string presetName); void InitDataNoPreset(DialogData & dd); void InitDataFromPreset(string presetName); void SetUIFromData(); void ExtractDataFromUI(DialogData & dd); void GetPresetNames(ComboData & comboItem); void GetCompressionNames(ComboData & comboItem); void GetTextureTypeNames(ComboData & comboItem); void GetMipMapNames(ComboData & comboItem); void PopulateMipLevelsCombo(); void DisableUnavailableControls(); void UpdateCompressionCombo(); void UpdateMipMapCombo(); void SetFontCompressionCombo(); void InitComboItems(); void InitComboFromItems(int32 comboItemsIndex); uint32 GetSelectedItem(uint32 comboBoxID); uint32 GetSelectedMipLevelIndex(); void SetContextString(uint32 contextStringID, uint32 index); // overrides virtual void Init(void) override; virtual void Notify(int32 item) override; double Log2( double n ); public: explicit OptionsDialog(IntelPlugin* globals); ~OptionsDialog() {} bool LoadPresetNonUIMode(string name); void FillGlobalStruct(); void GetGlobalStruct(); const DialogData & GetData() const { return mDialogData; } static int32 DoModal(IntelPlugin* plugin); }; #define PRESET_FILE_VERSION (int)100 #define LAST_SETTINGS_PRESET_NAME "-last-used-" // #define AUTO_SAVE_PRESETS // sets presets to autosave ================================================ FILE: IntelCompressionPlugin/kernel.ispc ================================================ //////////////////////////////////////////////////////////////////////////////// // Copyright 2017 Intel Corporation // // Licensed under the Apache License, Version 2.0 (the "License"); you may not // use this file except in compliance with the License. You may obtain a copy // of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the // License for the specific language governing permissions and limitations // under the License. //////////////////////////////////////////////////////////////////////////////// typedef unsigned int8 uint8; typedef unsigned int32 uint32; typedef unsigned int64 uint64; /////////////////////////// // generic helpers inline void swap_ints(int u[], int v[], uniform int n) { for (uniform int i=0; i>bits; // (perf warning expected) } /////////////////////////////////////////////////////////// // BC1/BC7 shared struct rgba_surface { uint8* ptr; int width, height, stride; }; inline void load_block_interleaved(float block[48], uniform rgba_surface* uniform src, int xx, uniform int yy) { for (uniform int y = 0; y<4; y++) for (uniform int x = 0; x<4; x++) { uniform unsigned int32* uniform src_ptr = (unsigned int32*)&src->ptr[(yy * 4 + y)*src->stride]; unsigned int32 rgba = gather_uint(src_ptr, xx * 4 + x); block[16 * 0 + y * 4 + x] = (int)((rgba >> 0) & 255); block[16 * 1 + y * 4 + x] = (int)((rgba >> 8) & 255); block[16 * 2 + y * 4 + x] = (int)((rgba >> 16) & 255); } } inline void load_block_interleaved_rgba(float block[64], uniform rgba_surface* uniform src, int xx, uniform int yy) { for (uniform int y=0; y<4; y++) for (uniform int x=0; x<4; x++) { uniform unsigned int32* uniform src_ptr = (unsigned int32*)&src->ptr[(yy*4+y)*src->stride]; unsigned int32 rgba = gather_uint(src_ptr, xx*4+x); block[16*0+y*4+x] = (int)((rgba>> 0)&255); block[16*1+y*4+x] = (int)((rgba>> 8)&255); block[16*2+y*4+x] = (int)((rgba>>16)&255); block[16*3+y*4+x] = (int)((rgba>>24)&255); } } inline void load_block_interleaved_16bit(float block[48], uniform rgba_surface* uniform src, int xx, uniform int yy) { for (uniform int y = 0; y<4; y++) for (uniform int x = 0; x<4; x++) { uniform unsigned int32* uniform src_ptr_r = (unsigned int32*)&src->ptr[(yy * 4 + y)*src->stride + 0]; uniform unsigned int32* uniform src_ptr_g = (unsigned int32*)&src->ptr[(yy * 4 + y)*src->stride + 2]; uniform unsigned int32* uniform src_ptr_b = (unsigned int32*)&src->ptr[(yy * 4 + y)*src->stride + 4]; unsigned int32 xr = gather_uint(src_ptr_r, (xx * 4 + x) * 2); unsigned int32 xg = gather_uint(src_ptr_g, (xx * 4 + x) * 2); unsigned int32 xb = gather_uint(src_ptr_b, (xx * 4 + x) * 2); block[16 * 0 + y * 4 + x] = (int)(xr & 0xFFFF); block[16 * 1 + y * 4 + x] = (int)(xg & 0xFFFF); block[16 * 2 + y * 4 + x] = (int)(xb & 0xFFFF); block[16 * 3 + y * 4 + x] = 0; } } inline void store_data(uniform uint8 dst[], int width, int xx, uniform int yy, uint32 data[], int data_size) { for (uniform int k=0; k> 8)) >> 8; } inline unsigned int16 stb__As16Bit(int r, int g, int b) { return (stb__Mul8Bit(r,31) << 11) + (stb__Mul8Bit(g,63) << 5) + stb__Mul8Bit(b,31); } inline unsigned int16 enc_rgb565(float c[3]) { return stb__As16Bit((int)c[0], (int)c[1], (int)c[2]); } inline void dec_rgb565(float c[3], int p) { int c2 = (p>>0)&31; int c1 = (p>>5)&63; int c0 = (p>>11)&31; c[0] = (c0<<3)+(c0>>2); c[1] = (c1<<2)+(c1>>4); c[2] = (c2<<3)+(c2>>2); } inline void pick_endpoints_dc(int c0[3], int c1[3], int block[48], int iaxis[3]) { for (uniform int p=0; p<3; p++) for (uniform int y=0; y<4; y++) for (uniform int x=0; x<4; x++) { c0[p] += block[p*16+y*4+x]; } for (uniform int p=0; p<3; p++) c0[p] >>= 4; } inline void pick_endpoints(float c0[3], float c1[3], float block[48], float axis[3], float dc[3]) { float min_dot = 256*256; float max_dot = 0; for (uniform int y=0; y<4; y++) for (uniform int x=0; x<4; x++) { float dot = 0; for (uniform int p=0; p<3; p++) dot += (block[p*16+y*4+x]-dc[p])*axis[p]; min_dot = min(min_dot, dot); max_dot = max(max_dot, dot); } if (max_dot-min_dot < 1f) { min_dot -= 0.5f; max_dot += 0.5f; } float norm_sq = 0; for (uniform int p=0; p<3; p++) norm_sq += axis[p]*axis[p]; float rnorm_sq = rcp(norm_sq); for (uniform int p=0; p<3; p++) { c0[p] = clamp(dc[p]+min_dot*rnorm_sq*axis[p], 0, 255); c1[p] = clamp(dc[p]+max_dot*rnorm_sq*axis[p], 0, 255); } } inline uint32 fast_quant(float block[48], int p0, int p1) { float c0[3]; float c1[3]; dec_rgb565(c0, p0); dec_rgb565(c1, p1); float dir[3]; for (uniform int p=0; p<3; p++) dir[p] = c1[p]-c0[p]; float sq_norm = 0; for (uniform int p=0; p<3; p++) sq_norm += sq(dir[p]); float rsq_norm = rcp(sq_norm); for (uniform int p=0; p<3; p++) dir[p] *= rsq_norm*3; float bias = 0.5; for (uniform int p=0; p<3; p++) bias -= c0[p]*dir[p]; uint32 bits = 0; uint32 scaler = 1; for (uniform int k=0; k<16; k++) { float dot = 0; for (uniform int p=0; p<3; p++) dot += block[k+p*16]*dir[p]; int q = clamp((int)(dot+bias), 0, 3); //bits += q<<(k*2); bits += q*scaler; scaler *= 4; } return bits; } inline void compute_covar_dc(float covar[6], float dc[3], float block[48]) { for (uniform int i=0; i<6; i++) covar[i] = 0; for (uniform int p=0; p<3; p++) dc[p] = 0; for (uniform int k=0; k<16; k++) { for (uniform int p=0; p<3; p++) dc[p] += block[k+p*16]; } for (uniform int p=0; p<3; p++) dc[p] /= 16; for (uniform int k=0; k<16; k++) { float rgb[3]; for (uniform int p=0; p<3; p++) rgb[p] = block[k+p*16]-dc[p]; covar[0] += rgb[0]*rgb[0]; covar[1] += rgb[0]*rgb[1]; covar[2] += rgb[0]*rgb[2]; covar[3] += rgb[1]*rgb[1]; covar[4] += rgb[1]*rgb[2]; covar[5] += rgb[2]*rgb[2]; } } // ugly, but makes BC1 compression 20% faster overall inline void compute_covar_dc_ugly(float covar[6], float dc[3], float block[48]) { for (uniform int p=0; p<3; p++) { float acc = 0; for (uniform int k=0; k<16; k++) acc += block[k+p*16]; dc[p] = acc/16; } float covar0 = 0f; float covar1 = 0f; float covar2 = 0f; float covar3 = 0f; float covar4 = 0f; float covar5 = 0f; for (uniform int k=0; k<16; k++) { float rgb0, rgb1, rgb2; rgb0 = block[k+0*16]-dc[0]; rgb1 = block[k+1*16]-dc[1]; rgb2 = block[k+2*16]-dc[2]; covar0 += rgb0*rgb0; covar1 += rgb0*rgb1; covar2 += rgb0*rgb2; covar3 += rgb1*rgb1; covar4 += rgb1*rgb2; covar5 += rgb2*rgb2; } covar[0] = covar0; covar[1] = covar1; covar[2] = covar2; covar[3] = covar3; covar[4] = covar4; covar[5] = covar5; } inline void bc1_refine(int pe[2], float block[48], unsigned int32 bits, float dc[3]) { float c0[3]; float c1[3]; if ((bits ^ (bits*4)) < 4) { // single color for (uniform int p=0; p<3; p++) { c0[p] = dc[p]; c1[p] = dc[p]; } } else { float Atb1[3] = {0,0,0}; float sum_q = 0; float sum_qq = 0; unsigned int32 shifted_bits = bits; for (uniform int k=0; k<16; k++) { float q = (int)(shifted_bits&3); shifted_bits >>= 2; float x = 3-q; float y = q; sum_q += q; sum_qq += q*q; for (uniform int p=0; p<3; p++) Atb1[p] += x*block[k+p*16]; } float sum[3]; float Atb2[3]; for (uniform int p=0; p<3; p++) { sum[p] = dc[p]*16; Atb2[p] = 3*sum[p]-Atb1[p]; } float Cxx = 16*sq(3)-2*3*sum_q+sum_qq; float Cyy = sum_qq; float Cxy = 3*sum_q-sum_qq; float scale = 3f * rcp(Cxx*Cyy - Cxy*Cxy); for (uniform int p=0; p<3; p++) { c0[p] = (Atb1[p]*Cyy - Atb2[p]*Cxy)*scale; c1[p] = (Atb2[p]*Cxx - Atb1[p]*Cxy)*scale; c0[p] = clamp(c0[p], 0, 255); c1[p] = clamp(c1[p], 0, 255); } } pe[0] = enc_rgb565(c0); pe[1] = enc_rgb565(c1); } inline uint32 fix_qbits(uint32 qbits) { uniform const uint32 mask_01b = 0x55555555; uniform const uint32 mask_10b = 0xAAAAAAAA; uint32 qbits0 = qbits&mask_01b; uint32 qbits1 = qbits&mask_10b; qbits = (qbits1>>1) + (qbits1 ^ (qbits0<<1)); return qbits; } inline void CompressBlockBC1_core(float block[48], uint32 data[2]) { uniform const int powerIterations = 4; uniform const int refineIterations = 1; float covar[6]; float dc[3]; compute_covar_dc_ugly(covar, dc, block); float eps = 0.001; covar[0] += eps; covar[3] += eps; covar[5] += eps; float axis[3]; compute_axis3(axis, covar, powerIterations); float c0[3]; float c1[3]; pick_endpoints(c0, c1, block, axis, dc); int p[2]; p[0] = enc_rgb565(c0); p[1] = enc_rgb565(c1); if (p[0] 0) q++; if (q==8) q = 1; qblock[k/8] |= q << ((k%8)*3); } // (could be improved by refinement) data[0] = clamp((int)ep[0], 0, 255)*256+clamp((int)ep[1], 0, 255); data[0] |= qblock[0]<<16; data[1] = qblock[0]>>16; data[1] |= qblock[1]<<8; } inline void CompressBlockBC1(uniform rgba_surface src[], int xx, uniform int yy, uniform uint8 dst[]) { float block[48]; uint32 data[2]; load_block_interleaved(block, src, xx, yy); CompressBlockBC1_core(block, data); store_data(dst, src->width, xx, yy, data, 2); } inline void CompressBlockBC3(uniform rgba_surface src[], int xx, uniform int yy, uniform uint8 dst[]) { float block[64]; uint32 data[4]; load_block_interleaved_rgba(block, src, xx, yy); CompressBlockBC3_alpha(&block[48], &data[0]); CompressBlockBC1_core(block, &data[2]); store_data(dst, src->width, xx, yy, data, 4); } export void CompressBlocksBC1_ispc(uniform rgba_surface src[], uniform uint8 dst[]) { for (uniform int yy = 0; yyheight/4; yy++) foreach (xx = 0 ... src->width/4) { CompressBlockBC1(src, xx, yy, dst); } } export void CompressBlocksBC3_ispc(uniform rgba_surface src[], uniform uint8 dst[]) { for (uniform int yy = 0; yyheight/4; yy++) foreach (xx = 0 ... src->width/4) { CompressBlockBC3(src, xx, yy, dst); } } /////////////////////////////////////////////////////////// // BC7 encoding struct bc7_enc_settings { bool mode_selection[4]; int refineIterations[8]; bool skip_mode2; int fastSkipTreshold_mode1; int fastSkipTreshold_mode3; int fastSkipTreshold_mode7; int mode45_channel0; int refineIterations_channel; int channels; }; struct bc7_enc_state { float block[64]; float opaque_err; // error for coding alpha=255 float best_err; uint32 best_data[5]; // 4, +1 margin for skips // settings uniform bool mode_selection[4]; uniform int refineIterations[8]; uniform bool skip_mode2; uniform int fastSkipTreshold_mode1; uniform int fastSkipTreshold_mode3; uniform int fastSkipTreshold_mode7; uniform int mode45_channel0; uniform int refineIterations_channel; uniform int channels; }; struct mode45_parameters { int qep[8]; uint32 qblock[2]; int aqep[2]; uint32 aqblock[2]; int rotation; int swap; }; void bc7_code_mode01237(uint32 data[5], int qep[6], uint32 qblock[2], int part_id, uniform int mode); void bc7_code_mode45(uint32 data[5], mode45_parameters params[], uniform int mode); void bc7_code_mode6(uint32 data[5], int qep[8], uint32 qblock[2]); /////////////////////////// // BC7 format data inline uniform const int* uniform get_unquant_table(uniform int bits) { assert(bits>=2 && bits<=4); // invalid bit size static uniform const int unquant_table_2bits[] = { 0, 21, 43, 64 }; static uniform const int unquant_table_3bits[] = { 0, 9, 18, 27, 37, 46, 55, 64 }; static uniform const int unquant_table_4bits[] = { 0, 4, 9, 13, 17, 21, 26, 30, 34, 38, 43, 47, 51, 55, 60, 64 }; uniform const int* uniform unquant_tables[] = {unquant_table_2bits, unquant_table_3bits, unquant_table_4bits}; return unquant_tables[bits-2]; } inline uint32 get_pattern(int part_id) { static uniform const uint32 pattern_table[] = { 0x50505050u, 0x40404040u, 0x54545454u, 0x54505040u, 0x50404000u, 0x55545450u, 0x55545040u, 0x54504000u, 0x50400000u, 0x55555450u, 0x55544000u, 0x54400000u, 0x55555440u, 0x55550000u, 0x55555500u, 0x55000000u, 0x55150100u, 0x00004054u, 0x15010000u, 0x00405054u, 0x00004050u, 0x15050100u, 0x05010000u, 0x40505054u, 0x00404050u, 0x05010100u, 0x14141414u, 0x05141450u, 0x01155440u, 0x00555500u, 0x15014054u, 0x05414150u, 0x44444444u, 0x55005500u, 0x11441144u, 0x05055050u, 0x05500550u, 0x11114444u, 0x41144114u, 0x44111144u, 0x15055054u, 0x01055040u, 0x05041050u, 0x05455150u, 0x14414114u, 0x50050550u, 0x41411414u, 0x00141400u, 0x00041504u, 0x00105410u, 0x10541000u, 0x04150400u, 0x50410514u, 0x41051450u, 0x05415014u, 0x14054150u, 0x41050514u, 0x41505014u, 0x40011554u, 0x54150140u, 0x50505500u, 0x00555050u, 0x15151010u, 0x54540404u, 0xAA685050u, 0x6A5A5040u, 0x5A5A4200u, 0x5450A0A8u, 0xA5A50000u, 0xA0A05050u, 0x5555A0A0u, 0x5A5A5050u, 0xAA550000u, 0xAA555500u, 0xAAAA5500u, 0x90909090u, 0x94949494u, 0xA4A4A4A4u, 0xA9A59450u, 0x2A0A4250u, 0xA5945040u, 0x0A425054u, 0xA5A5A500u, 0x55A0A0A0u, 0xA8A85454u, 0x6A6A4040u, 0xA4A45000u, 0x1A1A0500u, 0x0050A4A4u, 0xAAA59090u, 0x14696914u, 0x69691400u, 0xA08585A0u, 0xAA821414u, 0x50A4A450u, 0x6A5A0200u, 0xA9A58000u, 0x5090A0A8u, 0xA8A09050u, 0x24242424u, 0x00AA5500u, 0x24924924u, 0x24499224u, 0x50A50A50u, 0x500AA550u, 0xAAAA4444u, 0x66660000u, 0xA5A0A5A0u, 0x50A050A0u, 0x69286928u, 0x44AAAA44u, 0x66666600u, 0xAA444444u, 0x54A854A8u, 0x95809580u, 0x96969600u, 0xA85454A8u, 0x80959580u, 0xAA141414u, 0x96960000u, 0xAAAA1414u, 0xA05050A0u, 0xA0A5A5A0u, 0x96000000u, 0x40804080u, 0xA9A8A9A8u, 0xAAAAAA44u, 0x2A4A5254u }; return gather_uint(pattern_table, part_id); } inline int get_pattern_mask(int part_id, int j) { static uniform const uint32 pattern_mask_table[] = { 0xCCCC3333u, 0x88887777u, 0xEEEE1111u, 0xECC81337u, 0xC880377Fu, 0xFEEC0113u, 0xFEC80137u, 0xEC80137Fu, 0xC80037FFu, 0xFFEC0013u, 0xFE80017Fu, 0xE80017FFu, 0xFFE80017u, 0xFF0000FFu, 0xFFF0000Fu, 0xF0000FFFu, 0xF71008EFu, 0x008EFF71u, 0x71008EFFu, 0x08CEF731u, 0x008CFF73u, 0x73108CEFu, 0x3100CEFFu, 0x8CCE7331u, 0x088CF773u, 0x3110CEEFu, 0x66669999u, 0x366CC993u, 0x17E8E817u, 0x0FF0F00Fu, 0x718E8E71u, 0x399CC663u, 0xAAAA5555u, 0xF0F00F0Fu, 0x5A5AA5A5u, 0x33CCCC33u, 0x3C3CC3C3u, 0x55AAAA55u, 0x96966969u, 0xA55A5AA5u, 0x73CE8C31u, 0x13C8EC37u, 0x324CCDB3u, 0x3BDCC423u, 0x69969669u, 0xC33C3CC3u, 0x99666699u, 0x0660F99Fu, 0x0272FD8Du, 0x04E4FB1Bu, 0x4E40B1BFu, 0x2720D8DFu, 0xC93636C9u, 0x936C6C93u, 0x39C6C639u, 0x639C9C63u, 0x93366CC9u, 0x9CC66339u, 0x817E7E81u, 0xE71818E7u, 0xCCF0330Fu, 0x0FCCF033u, 0x774488BBu, 0xEE2211DDu, 0x08CC0133u, 0x8CC80037u, 0xCC80006Fu, 0xEC001331u, 0x330000FFu, 0x00CC3333u, 0xFF000033u, 0xCCCC0033u, 0x0F0000FFu, 0x0FF0000Fu, 0x00F0000Fu, 0x44443333u, 0x66661111u, 0x22221111u, 0x136C0013u, 0x008C8C63u, 0x36C80137u, 0x08CEC631u, 0x3330000Fu, 0xF0000333u, 0x00EE1111u, 0x88880077u, 0x22C0113Fu, 0x443088CFu, 0x0C22F311u, 0x03440033u, 0x69969009u, 0x9960009Fu, 0x03303443u, 0x00660699u, 0xC22C3113u, 0x8C0000EFu, 0x1300007Fu, 0xC4003331u, 0x004C1333u, 0x22229999u, 0x00F0F00Fu, 0x24929249u, 0x29429429u, 0xC30C30C3u, 0xC03C3C03u, 0x00AA0055u, 0xAA0000FFu, 0x30300303u, 0xC0C03333u, 0x90900909u, 0xA00A5005u, 0xAAA0000Fu, 0x0AAA0555u, 0xE0E01111u, 0x70700707u, 0x6660000Fu, 0x0EE01111u, 0x07707007u, 0x06660999u, 0x660000FFu, 0x00660099u, 0x0CC03333u, 0x03303003u, 0x60000FFFu, 0x80807777u, 0x10100101u, 0x000A0005u, 0x08CE8421u }; uint32 mask_packed = gather_uint(pattern_mask_table, part_id); int mask0 = mask_packed&0xFFFF; int mask1 = mask_packed>>16; int mask = (j==2) ? (~mask0)&(~mask1) : ( (j==0) ? mask0 : mask1 ); return mask; } inline void get_skips(int skips[3], int part_id) { static uniform const int skip_table[] = { 0xf0u, 0xf0u, 0xf0u, 0xf0u, 0xf0u, 0xf0u, 0xf0u, 0xf0u, 0xf0u, 0xf0u, 0xf0u, 0xf0u, 0xf0u, 0xf0u, 0xf0u, 0xf0u, 0xf0u, 0x20u, 0x80u, 0x20u, 0x20u, 0x80u, 0x80u, 0xf0u, 0x20u, 0x80u, 0x20u, 0x20u, 0x80u, 0x80u, 0x20u, 0x20u, 0xf0u, 0xf0u, 0x60u, 0x80u, 0x20u, 0x80u, 0xf0u, 0xf0u, 0x20u, 0x80u, 0x20u, 0x20u, 0x20u, 0xf0u, 0xf0u, 0x60u, 0x60u, 0x20u, 0x60u, 0x80u, 0xf0u, 0xf0u, 0x20u, 0x20u, 0xf0u, 0xf0u, 0xf0u, 0xf0u, 0xf0u, 0x20u, 0x20u, 0xf0u, 0x3fu, 0x38u, 0xf8u, 0xf3u, 0x8fu, 0x3fu, 0xf3u, 0xf8u, 0x8fu, 0x8fu, 0x6fu, 0x6fu, 0x6fu, 0x5fu, 0x3fu, 0x38u, 0x3fu, 0x38u, 0x8fu, 0xf3u, 0x3fu, 0x38u, 0x6fu, 0xa8u, 0x53u, 0x8fu, 0x86u, 0x6au, 0x8fu, 0x5fu, 0xfau, 0xf8u, 0x8fu, 0xf3u, 0x3fu, 0x5au, 0x6au, 0xa8u, 0x89u, 0xfau, 0xf6u, 0x3fu, 0xf8u, 0x5fu, 0xf3u, 0xf6u, 0xf6u, 0xf8u, 0x3fu, 0xf3u, 0x5fu, 0x5fu, 0x5fu, 0x8fu, 0x5fu, 0xafu, 0x5fu, 0xafu, 0x8fu, 0xdfu, 0xf3u, 0xcfu, 0x3fu, 0x38u }; int skip_packed = gather_int(skip_table, part_id); skips[0] = 0; skips[1] = skip_packed>>4; skips[2] = skip_packed&15; } /////////////////////////// // PCA helpers inline void compute_stats_masked(float stats[15], float block[64], int mask, uniform int channels) { for (uniform int i=0; i<15; i++) stats[i] = 0; int mask_shifted = mask<<1; for (uniform int k=0; k<16; k++) { mask_shifted >>= 1; //if ((mask_shifted&1) == 0) continue; int flag = (mask_shifted&1); float rgba[4]; for (uniform int p=0; p>= 1; if ((mask_shifted&1) == 0) continue; float dot = 0; for (uniform int p=0; p= 4); int vv = v<<(8-bits); return vv + shift_right(vv, bits); } void ep_quant0367(int qep[], float ep[], uniform int mode, uniform int channels) { uniform int bits = 7; if (mode == 0) bits = 4; if (mode == 7) bits = 5; uniform int levels = 1 << bits; uniform int levels2 = levels*2-1; for (uniform int i=0; i<2; i++) { int qep_b[8]; for (uniform int b=0; b<2; b++) for (uniform int p=0; p<4; p++) { int v = (int)((ep[i*4+p]/255f*levels2-b)/2+0.5)*2+b; qep_b[b*4+p] = clamp(v, b, levels2-1+b); } float ep_b[8]; for (uniform int j=0; j<8; j++) ep_b[j] = qep_b[j]; if (mode==0) for (uniform int j=0; j<8; j++) ep_b[j] = unpack_to_byte(qep_b[j], 5); float err0 = 0f; float err1 = 0f; for (uniform int p=0; p>= 2; float proj = 0; float div = 0; for (uniform int p=0; p=0 && best_q<=levels-1); qblock[k/8] += ((uint32)best_q) << 4*(k%8); total_err += best_err; } return total_err; } /////////////////////////// // LS endpoint refinement void opt_endpoints(float ep[], float block[64], uniform int bits, uint32 qblock[2], int mask, uniform int channels) { uniform int levels = 1 << bits; float Atb1[4] = {0,0,0,0}; float sum_q = 0; float sum_qq = 0; float sum[5] = {0,0,0,0,0}; int mask_shifted = mask<<1; for (uniform int k1=0; k1<2; k1++) { uint32 qbits_shifted = qblock[k1]; for (uniform int k2=0; k2<8; k2++) { uniform int k = k1*8+k2; float q = (int)(qbits_shifted&15); qbits_shifted >>= 4; mask_shifted >>= 1; if ((mask_shifted&1) == 0) continue; int x = (levels-1)-q; int y = q; sum_q += q; sum_qq += q*q; sum[4] += 1; for (uniform int p=0; pblock, part_id, mode); if (errrefineIterations[mode]; for (uniform int _=0; _block, bits, best_qblock, mask, channels); } int qep[24]; uint32 qblock[2]; ep_quant_dequant(qep, ep, mode, state->channels); uint32 pattern = get_pattern(best_part_id); float err = block_quant(qblock, state->block, bits, ep, pattern, channels); if (erropaque_err; // take into account alpha channel if (best_errbest_err) { state->best_err = best_err; bc7_code_mode01237(state->best_data, best_qep, best_qblock, best_part_id, mode); } } void partial_sort_list(int list[], uniform int length, uniform int partial_count) { for (uniform int k=0; k list[i]) { best_value = list[i]; best_idx = i; } } // swap scatter_int(list, best_idx, list[k]); list[k] = best_value; } } void bc7_enc_mode02(bc7_enc_state state[]) { int part_list[64]; for (uniform int part=0; part<64; part++) part_list[part] = part; bc7_enc_mode01237(state, 0, part_list, 16); if (!state->skip_mode2) bc7_enc_mode01237(state, 2, part_list, 64); // usually not worth the time } void bc7_enc_mode13(bc7_enc_state state[]) { if (state->fastSkipTreshold_mode1 == 0 && state->fastSkipTreshold_mode3 == 0) return; float full_stats[15]; compute_stats_masked(full_stats, state->block, -1, 3); int part_list[64]; for (uniform int part=0; part<64; part++) { int mask = get_pattern_mask(part+0, 0); float bound12 = block_pca_bound_split(state->block, mask, full_stats, 3); int bound = (int)(bound12); part_list[part] = part+bound*64; } partial_sort_list(part_list, 64, max(state->fastSkipTreshold_mode1, state->fastSkipTreshold_mode3)); bc7_enc_mode01237(state, 1, part_list, state->fastSkipTreshold_mode1); bc7_enc_mode01237(state, 3, part_list, state->fastSkipTreshold_mode3); } void bc7_enc_mode7(bc7_enc_state state[]) { if (state->fastSkipTreshold_mode7 == 0) return; float full_stats[15]; compute_stats_masked(full_stats, state->block, -1, state->channels); int part_list[64]; for (uniform int part=0; part<64; part++) { int mask = get_pattern_mask(part+0, 0); float bound12 = block_pca_bound_split(state->block, mask, full_stats, state->channels); int bound = (int)(bound12); part_list[part] = part+bound*64; } partial_sort_list(part_list, 64, state->fastSkipTreshold_mode7); bc7_enc_mode01237(state, 7, part_list, state->fastSkipTreshold_mode7); } void channel_quant_dequant(int qep[2], float ep[2], uniform int epbits) { int elevels = (1<>= 4; int x = (levels-1)-q; int y = q; sum_q += q; sum_qq += q*q; sum += block[k]; Atb1 += x*block[k]; } } float Atb2 = (levels-1)*sum-Atb1; float Cxx = 16*sq(levels-1)-2*(levels-1)*sum_q+sum_qq; float Cyy = sum_qq; float Cxy = (levels-1)*sum_q-sum_qq; float scale = (levels-1) / (Cxx*Cyy - Cxy*Cxy); ep[0] = (Atb1*Cyy - Atb2*Cxy)*scale; ep[1] = (Atb2*Cxx - Atb1*Cxy)*scale; ep[0] = clamp(ep[0], 0, 255); ep[1] = clamp(ep[1], 0, 255); if (abs(Cxx*Cyy - Cxy*Cxy) < 0.001) { ep[0] = sum/16; ep[1] = ep[0]; } } float channel_opt_quant(uint32 qblock[2], float block[16], uniform int bits, float ep[]) { uniform const int* uniform unquant_table = get_unquant_table(bits); int levels = (1<refineIterations_channel; for (uniform int i=0; iblock[k+p*16]; if (rotation < 3) { // apply channel rotation if (state->channels == 4) block[k+rotation*16] = state->block[k+3*16]; if (state->channels == 3) block[k+rotation*16] = 255; } } float ep[8]; block_segment(ep, block, -1, 3); int qep[8]; ep_quant_dequant(qep, ep, mode, 3); uint32 qblock[2]; float err = block_quant(qblock, block, bits, ep, 0, 3); // refine uniform int refineIterations = state->refineIterations[mode]; for (uniform int i=0; iblock[rotation*16], abits, aepbits); if (err<*best_err) { swap_ints(best_candidate->qep, qep, 8); swap_uints(best_candidate->qblock, qblock, 2); swap_ints(best_candidate->aqep, aqep, 2); swap_uints(best_candidate->aqblock, aqblock, 2); best_candidate->rotation = rotation; best_candidate->swap = swap; *best_err = err; } } void bc7_enc_mode45(bc7_enc_state state[]) { mode45_parameters best_candidate; float best_err = state->best_err; memset(&best_candidate, 0, sizeof(mode45_parameters)); uniform int channel0 = state->mode45_channel0; for (uniform int p=channel0; pchannels; p++) { bc7_enc_mode45_candidate(state, &best_candidate, &best_err, 4, p, 0); bc7_enc_mode45_candidate(state, &best_candidate, &best_err, 4, p, 1); } // mode 4 if (best_errbest_err) { state->best_err = best_err; bc7_code_mode45(state->best_data, &best_candidate, 4); } for (uniform int p=channel0; pchannels; p++) { bc7_enc_mode45_candidate(state, &best_candidate, &best_err, 5, p, 0); } // mode 5 if (best_errbest_err) { state->best_err = best_err; bc7_code_mode45(state->best_data, &best_candidate, 5); } } void bc7_enc_mode6(bc7_enc_state state[]) { uniform int mode = 6; uniform int bits = 4; float ep[8]; block_segment(ep, state->block, -1, state->channels); if (state->channels == 3) { ep[3] = ep[7] = 255; } int qep[8]; ep_quant_dequant(qep, ep, mode, state->channels); uint32 qblock[2]; float err = block_quant(qblock, state->block, bits, ep, 0, state->channels); // refine uniform int refineIterations = state->refineIterations[mode]; for (uniform int i=0; iblock, bits, qblock, -1, state->channels); ep_quant_dequant(qep, ep, mode, state->channels); err = block_quant(qblock, state->block, bits, ep, 0, state->channels); } if (errbest_err) { state->best_err = err; bc7_code_mode6(state->best_data, qep, qblock); } } ////////////////////////// // BC7 bitstream coding void bc7_code_apply_swap_mode456(int qep[], uniform int channels, uint32 qblock[2], uniform int bits) { uniform int levels = 1 << bits; if ((qblock[0]&15)>=levels/2) { swap_ints(&qep[0], &qep[channels], channels); for (uniform int k=0; k<2; k++) qblock[k] = (uint32)(0x11111111*(levels-1)) - qblock[k]; } assert((qblock[0]&15) < levels/2); } int bc7_code_apply_swap_mode01237(int qep[], uint32 qblock[2], uniform int mode, int part_id) { uniform int bits = 2; if (mode == 0 || mode == 1) bits = 3; uniform int pairs = 2; if (mode == 0 || mode == 2) pairs = 3; int flips = 0; uniform int levels = 1 << bits; int skips[3]; get_skips(skips, part_id); for (uniform int j=0; j>((k0%8)*4))&15; int q = ((gather_uint(qblock, k0>>3)<<(28-(k0&7)*4))>>28); if (q>=levels/2) { swap_ints(&qep[8*j], &qep[8*j+4], 4); uint32 pmask = get_pattern_mask(part_id, j); flips |= pmask; } } return flips; } void put_bits(uint32 data[5], uniform int* uniform pos, uniform int bits, int v) { assert(v32) { data[*pos/32+1] |= shift_right(v, 32-*pos%32); } *pos += bits; } inline void data_shl_1bit_from(uint32 data[5], int from) { if (from < 96) { assert(from > 64+10); uint32 shifted = (data[2]>>1) | (data[3]<<31); uint32 mask = (pow2(from-64)-1)>>1; data[2] = (mask&data[2]) | (~mask&shifted); data[3] = (data[3]>>1) | (data[4]<<31); data[4] = data[4]>>1; } else if (from < 128) { uint32 shifted = (data[3]>>1) | (data[4]<<31); uint32 mask = (pow2(from-96)-1)>>1; data[3] = (mask&data[3]) | (~mask&shifted); data[4] = data[4]>>1; } } void bc7_code_qblock(uint32 data[5], uniform int* uniform pPos, uint32 qblock[2], uniform int bits, int flips) { uniform int levels = 1 << bits; int flips_shifted = flips; for (uniform int k1=0; k1<2; k1++) { uint32 qbits_shifted = qblock[k1]; for (uniform int k2=0; k2<8; k2++) { int q = qbits_shifted&15; if ((flips_shifted&1)>0) q = (levels-1)-q; if (k1==0 && k2==0) put_bits(data, pPos, bits-1, q); else put_bits(data, pPos, bits , q); qbits_shifted >>= 4; flips_shifted >>= 1; } } } void bc7_code_adjust_skip_mode01237(uint32 data[5], uniform int mode, int part_id) { uniform int bits = 2; if (mode == 0 || mode == 1) bits = 3; uniform int pairs = 2; if (mode == 0 || mode == 2) pairs = 3; int skips[3]; get_skips(skips, part_id); if (pairs>2 && skips[1] < skips[2]) { int t = skips[1]; skips[1] = skips[2]; skips[2] = t; } for (uniform int j=1; j>1); } else if (mode == 1) { put_bits(data, &pos, 6, qep[j*4+0+p]>>1); } else if (mode == 2) { put_bits(data, &pos, 5, qep[j*4+0+p]); } else if (mode == 3) { put_bits(data, &pos, 7, qep[j*4+0+p]>>1); } else if (mode == 7) { put_bits(data, &pos, 5, qep[j*4+0+p]>>1); } else { assert(false); } } // p bits if (mode == 1) for (uniform int j=0; j<2; j++) { put_bits(data, &pos, 1, qep[j*8]&1); } if (mode == 0 || mode == 3 || mode == 7) for (uniform int j=0; jqep, qep, 8); swap_uints(params->qblock, qblock, 2); swap_ints(params->aqep, aqep, 2); swap_uints(params->aqblock, aqblock, 2); int rotation = params->rotation; int swap = params->swap; uniform int bits = 2; uniform int abits = 2; if (mode==4) abits = 3; uniform int epbits = 7; if (mode==4) epbits = 5; uniform int aepbits = 8; if (mode==4) aepbits = 6; if (!swap) { bc7_code_apply_swap_mode456(qep, 4, qblock, bits); bc7_code_apply_swap_mode456(aqep, 1, aqblock, abits); } else { swap_uints(qblock, aqblock, 2); bc7_code_apply_swap_mode456(aqep, 1, qblock, bits); bc7_code_apply_swap_mode456(qep, 4, aqblock, abits); } for (uniform int k=0; k<5; k++) data[k] = 0; uniform int pos = 0; // mode 4-5 put_bits(data, &pos, mode+1, 1<>1); put_bits(data, &pos, 7, qep[4+p]>>1); } // p bits put_bits(data, &pos, 1, qep[0]&1); put_bits(data, &pos, 1, qep[4]&1); // quantized values bc7_code_qblock(data, &pos, qblock, 4, 0); } ////////////////////////// // BC7 core inline void CompressBlockBC7_core(bc7_enc_state state[]) { if (state->mode_selection[0]) bc7_enc_mode02(state); if (state->mode_selection[1]) bc7_enc_mode13(state); if (state->mode_selection[1]) bc7_enc_mode7(state); if (state->mode_selection[2]) bc7_enc_mode45(state); if (state->mode_selection[3]) bc7_enc_mode6(state); } void bc7_enc_copy_settings(bc7_enc_state state[], uniform bc7_enc_settings settings[]) { state->channels = settings->channels; // mode02 state->mode_selection[0] = settings->mode_selection[0]; state->skip_mode2 = settings->skip_mode2; state->refineIterations[0] = settings->refineIterations[0]; state->refineIterations[2] = settings->refineIterations[2]; // mode137 state->mode_selection[1] = settings->mode_selection[1]; state->fastSkipTreshold_mode1 = settings->fastSkipTreshold_mode1; state->fastSkipTreshold_mode3 = settings->fastSkipTreshold_mode3; state->fastSkipTreshold_mode7 = settings->fastSkipTreshold_mode7; state->refineIterations[1] = settings->refineIterations[1]; state->refineIterations[3] = settings->refineIterations[3]; state->refineIterations[7] = settings->refineIterations[7]; // mode45 state->mode_selection[2] = settings->mode_selection[2]; state->mode45_channel0 = settings->mode45_channel0; state->refineIterations_channel = settings->refineIterations_channel; state->refineIterations[4] = settings->refineIterations[4]; state->refineIterations[5] = settings->refineIterations[5]; // mode6 state->mode_selection[3] = settings->mode_selection[3]; state->refineIterations[6] = settings->refineIterations[6]; } inline void CompressBlockBC7(uniform rgba_surface src[], int xx, uniform int yy, uniform uint8 dst[], uniform bc7_enc_settings settings[]) { bc7_enc_state _state; varying bc7_enc_state* uniform state = &_state; bc7_enc_copy_settings(state, settings); load_block_interleaved_rgba(state->block, src, xx, yy); state->best_err = 1e99; state->opaque_err = compute_opaque_err(state->block, state->channels); CompressBlockBC7_core(state); store_data(dst, src->width, xx, yy, state->best_data, 4); } export void CompressBlocksBC7_ispc(uniform rgba_surface src[], uniform uint8 dst[], uniform bc7_enc_settings settings[]) { for (uniform int yy = 0; yyheight/4; yy++) foreach (xx = 0 ... src->width/4) { CompressBlockBC7(src, xx, yy, dst, settings); } } /////////////////////////////////////////////////////////// // BC6H encoding struct bc6h_enc_settings { bool slow_mode; bool fast_mode; int refineIterations_1p; int refineIterations_2p; int fastSkipTreshold; }; struct bc6h_enc_state { float block[64]; float best_err; uint32 best_data[5]; // 4, +1 margin for skips float rgb_bounds[6]; float max_span; int max_span_idx; int mode; int epb; int qbounds[8]; // settings uniform bool slow_mode; uniform bool fast_mode; uniform int refineIterations_1p; uniform int refineIterations_2p; uniform int fastSkipTreshold; }; void bc6h_code_2p(uint32 data[5], int pqep[], uint32 qblock[2], int part_id, int mode); void bc6h_code_1p(uint32 data[5], int qep[8], uint32 qblock[2], int mode); /////////////////////////// // BC6H format data inline uniform int get_mode_prefix(uniform int mode) { static uniform const int mode_prefix_table[] = { 0, 1, 2, 6, 10, 14, 18, 22, 26, 30, 3, 7, 11, 15 }; return mode_prefix_table[mode]; } inline uniform float get_span(uniform int mode) { static uniform const float span_table[] = { 0.9 * 0xFFFF / 64, // (0) 4 / 10 0.9 * 0xFFFF / 4, // (1) 5 / 7 0.8 * 0xFFFF / 256, // (2) 3 / 11 -1, -1, 0.9 * 0xFFFF / 32, // (5) 4 / 9 0.9 * 0xFFFF / 16, // (6) 4 / 8 -1, -1, 0xFFFF, // (9) absolute 0xFFFF, // (10) absolute 0.95 * 0xFFFF / 8, // (11) 8 / 11 0.95 * 0xFFFF / 32, // (12) 7 / 12 6, // (13) 3 / 16 }; uniform int span = span_table[mode]; assert(span > 0); return span; } inline uniform int get_mode_bits(uniform int mode) { static uniform const int mode_bits_table[] = { 10, 7, 11, -1, -1, 9, 8, -1, -1, 6, 10, 11, 12, 16, }; uniform int mode_bits = mode_bits_table[mode]; assert(mode_bits > 0); return mode_bits; } /////////////////////////// // endpoint quantization inline int unpack_to_uf16(uint32 v, int bits) { if (bits >= 15) return v; if (v == 0) return 0; if (v == (1<epb; ep_quant_bc6h(qep, ep, bits, pairs); for (uniform int i = 0; i < 2 * pairs; i++) for (uniform int p = 0; p < 3; p++) { qep[i * 4 + p] = clamp(qep[i * 4 + p], state->qbounds[p], state->qbounds[4 + p]); } ep_dequant_bc6h(ep, qep, bits, pairs); } ////////////////////////// // parameter estimation float bc6h_enc_2p_part_fast(bc6h_enc_state state[], int qep[16], uint32 qblock[2], int part_id) { uint32 pattern = get_pattern(part_id); uniform int bits = 3; uniform int pairs = 2; uniform int channels = 3; float ep[16]; for (uniform int j = 0; jblock, mask, channels); } ep_quant_dequant_bc6h(state, qep, ep, 2); float total_err = block_quant(qblock, state->block, bits, ep, pattern, channels); return total_err; } void bc6h_enc_2p_list(bc6h_enc_state state[], int part_list[], uniform int part_count) { if (part_count == 0) return; uniform int bits = 3; uniform int pairs = 2; uniform int channels = 3; int best_qep[24]; uint32 best_qblock[2]; int best_part_id = -1; float best_err = 1e99; for (uniform int part = 0; partrefineIterations_2p; for (uniform int _ = 0; _block, bits, best_qblock, mask, channels); } int qep[24]; uint32 qblock[2]; ep_quant_dequant_bc6h(state, qep, ep, 2); uint32 pattern = get_pattern(best_part_id); float err = block_quant(qblock, state->block, bits, ep, pattern, channels); if (errbest_err) { state->best_err = best_err; bc6h_code_2p(state->best_data, best_qep, best_qblock, best_part_id, state->mode); } } void bc6h_enc_2p(bc6h_enc_state state[]) { float full_stats[15]; compute_stats_masked(full_stats, state->block, -1, 3); int part_list[32]; for (uniform int part = 0; part < 32; part++) { int mask = get_pattern_mask(part, 0); float bound12 = block_pca_bound_split(state->block, mask, full_stats, 3); int bound = (int)(bound12); part_list[part] = part + bound * 64; } partial_sort_list(part_list, 32, state->fastSkipTreshold); bc6h_enc_2p_list(state, part_list, state->fastSkipTreshold); } void bc6h_enc_1p(bc6h_enc_state state[]) { float ep[8]; block_segment_core(ep, state->block, -1, 3); int qep[8]; ep_quant_dequant_bc6h(state, qep, ep, 1); uint32 qblock[2]; float err = block_quant(qblock, state->block, 4, ep, 0, 3); // refine uniform int refineIterations = state->refineIterations_1p; for (uniform int i = 0; iblock, 4, qblock, -1, 3); ep_quant_dequant_bc6h(state, qep, ep, 1); err = block_quant(qblock, state->block, 4, ep, 0, 3); } if (err < state->best_err) { state->best_err = err; bc6h_code_1p(state->best_data, qep, qblock, state->mode); } } inline void compute_qbounds(bc6h_enc_state state[], float rgb_span[3]) { float bounds[8]; for (uniform int p = 0; p < 3; p++) { float middle = (state->rgb_bounds[p] + state->rgb_bounds[3 + p]) / 2; bounds[ p] = middle - rgb_span[p] / 2; bounds[4+p] = middle + rgb_span[p] / 2; } ep_quant_bc6h(state->qbounds, bounds, state->epb, 1); } void compute_qbounds(bc6h_enc_state state[], float span) { float rgb_span[3] = { span, span, span }; compute_qbounds(state, rgb_span); } void compute_qbounds2(bc6h_enc_state state[], float span, int max_span_idx) { float rgb_span[3] = { span, span, span }; for (uniform int p = 0; p < 3; p++) { rgb_span[p] *= (p == max_span_idx) ? 2 : 1; } compute_qbounds(state, rgb_span); } void bc6h_test_mode(bc6h_enc_state state[], uniform int mode, uniform bool enc, uniform float margin) { uniform int mode_bits = get_mode_bits(mode); uniform float span = get_span(mode); float max_span = state->max_span; int max_span_idx = state->max_span_idx; if (max_span * margin > span) return; if (mode >= 10) { state->epb = mode_bits; state->mode = mode; compute_qbounds(state, span); if (enc) bc6h_enc_1p(state); } else if (mode <= 1 || mode == 5 || mode == 9) { state->epb = mode_bits; state->mode = mode; compute_qbounds(state, span); if (enc) bc6h_enc_2p(state); } else { state->epb = mode_bits; state->mode = mode + max_span_idx; compute_qbounds2(state, span, max_span_idx); if (enc) bc6h_enc_2p(state); } } ////////////////////////// // BC6H bitstream coding int bit_at(int v, uniform int pos) { return (v >> pos) & 1; } uint32 reverse_bits(uint32 v, uniform int bits) { if (bits == 2) { return (v >> 1) + (v & 1) * 2; } if (bits == 6) { v = (v & 0x5555) * 2 + ((v >> 1) & 0x5555); return (v >> 4) + ((v >> 2) & 3) * 4 + (v & 3) * 16; } else { assert(false); } } void bc6h_pack(uint32 packed[], int qep[], int mode) { if (mode == 0) { int pred_qep[16]; for (uniform int p = 0; p < 3; p++) { pred_qep[ p] = qep[p]; pred_qep[ 4 + p] = (qep[ 4 + p] - qep[p]) & 31; pred_qep[ 8 + p] = (qep[ 8 + p] - qep[p]) & 31; pred_qep[12 + p] = (qep[12 + p] - qep[p]) & 31; } for (uniform int i = 1; i < 4; i++) for (uniform int p = 0; p < 3; p++) { assert( qep[i * 4 + p] - qep[p] <= 15); assert(-16 <= qep[i * 4 + p] - qep[p]); } /* g2[4], b2[4], b3[4], r0[9:0], g0[9:0], b0[9:0], r1[4:0], g3[4], g2[3:0], g1[4:0], b3[0], g3[3:0], b1[4:0], b3[1], b2[3:0], r2[4:0], b3[2], r3[4:0], b3[3] */ uint32 pqep[10]; pqep[4] = pred_qep[4] + (pred_qep[ 8 + 1] & 15) * 64; pqep[5] = pred_qep[5] + (pred_qep[12 + 1] & 15) * 64; pqep[6] = pred_qep[6] + (pred_qep[ 8 + 2] & 15) * 64; pqep[4] += bit_at(pred_qep[12 + 1], 4) << 5; pqep[5] += bit_at(pred_qep[12 + 2], 0) << 5; pqep[6] += bit_at(pred_qep[12 + 2], 1) << 5; pqep[8] = pred_qep[ 8] + bit_at(pred_qep[12 + 2], 2) * 32; pqep[9] = pred_qep[12] + bit_at(pred_qep[12 + 2], 3) * 32; packed[0] = get_mode_prefix(0); packed[0] += bit_at(pred_qep[ 8 + 1], 4) << 2; packed[0] += bit_at(pred_qep[ 8 + 2], 4) << 3; packed[0] += bit_at(pred_qep[12 + 2], 4) << 4; packed[1] = (pred_qep[2] << 20) + (pred_qep[1] << 10) + pred_qep[0]; packed[2] = (pqep[6] << 20) + (pqep[5] << 10) + pqep[4]; packed[3] = (pqep[9] << 6) + pqep[8]; } else if (mode == 1) { int pred_qep[16]; for (uniform int p = 0; p < 3; p++) { pred_qep[ p] = qep[p]; pred_qep[ 4 + p] = (qep[ 4 + p] - qep[p]) & 63; pred_qep[ 8 + p] = (qep[ 8 + p] - qep[p]) & 63; pred_qep[12 + p] = (qep[12 + p] - qep[p]) & 63; } for (uniform int i = 1; i < 4; i++) for (uniform int p = 0; p < 3; p++) { assert( qep[i * 4 + p] - qep[p] <= 31); assert(-32 <= qep[i * 4 + p] - qep[p]); } /* g2[5], g3[4], g3[5], r0[6:0], b3[0], b3[1], b2[4], g0[6:0], b2[5], b3[2], g2[4], b0[6:0], b3[3], b3[5], b3[4], r1[5:0], g2[3:0], g1[5:0], g3[3:0], b1[5:0], b2[3:0], r2[5:0], r3[5:0] */ uint32 pqep[8]; pqep[0] = pred_qep[0]; pqep[0] += bit_at(pred_qep[12 + 2], 0) << 7; pqep[0] += bit_at(pred_qep[12 + 2], 1) << 8; pqep[0] += bit_at(pred_qep[ 8 + 2], 4) << 9; pqep[1] = pred_qep[1]; pqep[1] += bit_at(pred_qep[ 8 + 2], 5) << 7; pqep[1] += bit_at(pred_qep[12 + 2], 2) << 8; pqep[1] += bit_at(pred_qep[ 8 + 1], 4) << 9; pqep[2] = pred_qep[2]; pqep[2] += bit_at(pred_qep[12 + 2], 3) << 7; pqep[2] += bit_at(pred_qep[12 + 2], 5) << 8; pqep[2] += bit_at(pred_qep[12 + 2], 4) << 9; pqep[4] = pred_qep[4] + (pred_qep[ 8 + 1] & 15) * 64; pqep[5] = pred_qep[5] + (pred_qep[12 + 1] & 15) * 64; pqep[6] = pred_qep[6] + (pred_qep[ 8 + 2] & 15) * 64; packed[0] = get_mode_prefix(1); packed[0] += bit_at(pred_qep[ 8 + 1], 5) << 2; packed[0] += bit_at(pred_qep[12 + 1], 4) << 3; packed[0] += bit_at(pred_qep[12 + 1], 5) << 4; packed[1] = (pqep[2] << 20) + (pqep[1] << 10) + pqep[0]; packed[2] = (pqep[6] << 20) + (pqep[5] << 10) + pqep[4]; packed[3] = (pred_qep[12] << 6) + pred_qep[8]; } else if (mode == 2 || mode == 3 || mode == 4) { /* r0[9:0], g0[9:0], b0[9:0], r1[3:0], xx[y], xx[y], g2[3:0], g1[3:0], xx[y], xx[y], g3[3:0], b1[3:0], xx[y], xx[y], b2[3:0], r2[3:0], xx[y], xx[y], r3[3:0], xx[y], xx[y] */ int dqep[16]; for (uniform int p = 0; p < 3; p++) { int mask = 15; if (p == mode - 2) mask = 31; dqep[p] = qep[p]; dqep[ 4 + p] = (qep[ 4 + p] - qep[p]) & mask; dqep[ 8 + p] = (qep[ 8 + p] - qep[p]) & mask; dqep[12 + p] = (qep[12 + p] - qep[p]) & mask; } for (uniform int i = 1; i < 4; i++) for (uniform int p = 0; p < 3; p++) { int bits = 4; if (p == mode - 2) bits = 5; assert( qep[i * 4 + p] - qep[p] <= (1<> 10) * 512; pqep[5] = dqep[5] + (dqep[1] >> 10) * 512; pqep[6] = dqep[6] + (dqep[2] >> 10) * 512; packed[0] = get_mode_prefix(11); packed[1] = (pqep[2] << 20) + (pqep[1] << 10) + pqep[0]; packed[2] = (pqep[6] << 20) + (pqep[5] << 10) + pqep[4]; } else if (mode == 12) { int dqep[8]; for (uniform int p = 0; p < 3; p++) { dqep[p] = qep[p]; dqep[4 + p] = (qep[4 + p] - qep[p]) & 255; } for (uniform int i = 1; i < 2; i++) for (uniform int p = 0; p < 3; p++) { assert( qep[i * 4 + p] - qep[p] <= 127); assert(-128 <= qep[i * 4 + p] - qep[p]); } /* r0[9:0], g0[9:0], b0[9:0], r1[7:0], r0[10:11], g1[7:0], g0[10:11], b1[7:0], b0[10:11] */ uint32 pqep[8]; pqep[0] = dqep[0] & 1023; pqep[1] = dqep[1] & 1023; pqep[2] = dqep[2] & 1023; pqep[4] = dqep[4] + reverse_bits(dqep[0] >> 10, 2) * 256; pqep[5] = dqep[5] + reverse_bits(dqep[1] >> 10, 2) * 256; pqep[6] = dqep[6] + reverse_bits(dqep[2] >> 10, 2) * 256; packed[0] = get_mode_prefix(12); packed[1] = (pqep[2] << 20) + (pqep[1] << 10) + pqep[0]; packed[2] = (pqep[6] << 20) + (pqep[5] << 10) + pqep[4]; } else if (mode == 13) { int dqep[8]; for (uniform int p = 0; p < 3; p++) { dqep[p] = qep[p]; dqep[4 + p] = (qep[4 + p] - qep[p]) & 15; } for (uniform int i = 1; i < 2; i++) for (uniform int p = 0; p < 3; p++) { assert( qep[i * 4 + p] - qep[p] <= 7); assert(-8 <= qep[i * 4 + p] - qep[p]); } /* r0[9:0], g0[9:0], b0[9:0], r1[3:0], r0[10:15], g1[3:0], g0[10:15], b1[3:0], b0[10:15] */ uint32 pqep[8]; pqep[0] = dqep[0] & 1023; pqep[1] = dqep[1] & 1023; pqep[2] = dqep[2] & 1023; pqep[4] = dqep[4] + reverse_bits(dqep[0] >> 10, 6) * 16; pqep[5] = dqep[5] + reverse_bits(dqep[1] >> 10, 6) * 16; pqep[6] = dqep[6] + reverse_bits(dqep[2] >> 10, 6) * 16; packed[0] = get_mode_prefix(13); packed[1] = (pqep[2] << 20) + (pqep[1] << 10) + pqep[0]; packed[2] = (pqep[6] << 20) + (pqep[5] << 10) + pqep[4]; } else { assert(false); } } void bc6h_code_2p(uint32 data[5], int qep[], uint32 qblock[2], int part_id, int mode) { uniform int bits = 3; uniform int pairs = 2; uniform int channels = 3; int flips = bc7_code_apply_swap_mode01237(qep, qblock, 1, part_id); for (uniform int k=0; k<5; k++) data[k] = 0; uniform int pos = 0; uint32 packed[4]; bc6h_pack(packed, qep, mode); // mode put_bits(data, &pos, 5, packed[0]); // endpoints put_bits(data, &pos, 30, packed[1]); put_bits(data, &pos, 30, packed[2]); put_bits(data, &pos, 12, packed[3]); // partition put_bits(data, &pos, 5, part_id); // quantized values bc7_code_qblock(data, &pos, qblock, bits, flips); bc7_code_adjust_skip_mode01237(data, 1, part_id); } void bc6h_code_1p(uint32 data[5], int qep[8], uint32 qblock[2], int mode) { bc7_code_apply_swap_mode456(qep, 4, qblock, 4); for (uniform int k = 0; k<5; k++) data[k] = 0; uniform int pos = 0; uint32 packed[4]; bc6h_pack(packed, qep, mode); // mode put_bits(data, &pos, 5, packed[0]); // endpoints put_bits(data, &pos, 30, packed[1]); put_bits(data, &pos, 30, packed[2]); // quantized values bc7_code_qblock(data, &pos, qblock, 4, 0); } ////////////////////////// // BC6H core void bc6h_setup(bc6h_enc_state state[]) { for (uniform int p = 0; p < 3; p++) { state->rgb_bounds[p ] = 0xFFFF; state->rgb_bounds[3+p] = 0; } // uf16 conversion, min/max for (uniform int p = 0; p < 3; p++) for (uniform int k = 0; k < 16; k++) { state->block[p * 16 + k] = (state->block[p * 16 + k] / 31) * 64; state->rgb_bounds[p ] = min(state->rgb_bounds[p ], state->block[p * 16 + k]); state->rgb_bounds[3+p] = max(state->rgb_bounds[3+p], state->block[p * 16 + k]); } state->max_span = 0; state->max_span_idx = 0; float rgb_span[0] = { 0, 0, 0 }; for (uniform int p = 0; p < 3; p++) { rgb_span[p] = state->rgb_bounds[3+p] - state->rgb_bounds[p]; if (rgb_span[p] > state->max_span) { state->max_span_idx = p; state->max_span = rgb_span[p]; } } } inline void CompressBlockBC6H_core(bc6h_enc_state state[]) { bc6h_setup(state); if (state->slow_mode) { bc6h_test_mode(state, 0, true, 0); bc6h_test_mode(state, 1, true, 0); bc6h_test_mode(state, 2, true, 0); bc6h_test_mode(state, 5, true, 0); bc6h_test_mode(state, 6, true, 0); bc6h_test_mode(state, 9, true, 0); bc6h_test_mode(state, 10, true, 0); bc6h_test_mode(state, 11, true, 0); bc6h_test_mode(state, 12, true, 0); bc6h_test_mode(state, 13, true, 0); } else { if (state->fastSkipTreshold > 0) { bc6h_test_mode(state, 9, false, 0); if (state->fast_mode) bc6h_test_mode(state, 1, false, 1); bc6h_test_mode(state, 6, false, 1 / 1.2); bc6h_test_mode(state, 5, false, 1 / 1.2); bc6h_test_mode(state, 0, false, 1 / 1.2); bc6h_test_mode(state, 2, false, 1); bc6h_enc_2p(state); if (!state->fast_mode) bc6h_test_mode(state, 1, true, 0); } bc6h_test_mode(state, 10, false, 0); bc6h_test_mode(state, 11, false, 1); bc6h_test_mode(state, 12, false, 1); bc6h_test_mode(state, 13, false, 1); bc6h_enc_1p(state); } } void bc6h_enc_copy_settings(bc6h_enc_state state[], uniform bc6h_enc_settings settings[]) { state->slow_mode = settings->slow_mode; state->fast_mode = settings->fast_mode; state->fastSkipTreshold = settings->fastSkipTreshold; state->refineIterations_1p = settings->refineIterations_1p; state->refineIterations_2p = settings->refineIterations_2p; } inline void CompressBlockBC6H(uniform rgba_surface src[], int xx, uniform int yy, uniform uint8 dst[], uniform bc6h_enc_settings settings[]) { bc6h_enc_state _state; varying bc6h_enc_state* uniform state = &_state; bc6h_enc_copy_settings(state, settings); load_block_interleaved_16bit(state->block, src, xx, yy); state->best_err = 1e99; CompressBlockBC6H_core(state); store_data(dst, src->width, xx, yy, state->best_data, 4); } export void CompressBlocksBC6H_ispc(uniform rgba_surface src[], uniform uint8 dst[], uniform bc6h_enc_settings settings[]) { for (uniform int yy = 0; yyheight / 4; yy++) foreach(xx = 0 ... src->width / 4) { CompressBlockBC6H(src, xx, yy, dst, settings); } } /////////////////////////////////////////////////////////// // ETC encoding struct etc_enc_settings { int fastSkipTreshold; }; struct etc_enc_state { float block[64]; int prev_qcenter[3]; float best_err; uint32 best_data[2]; uniform bool diff; // settings uniform int fastSkipTreshold; }; inline uniform int get_etc1_dY(uniform int table, uniform int q) { static uniform const int etc_codeword_table[8][4] = { { -8, -2, 2, 8 }, { -17, -5, 5, 17 }, { -29, -9, 9, 29 }, { -42, -13, 13, 42 }, { -60, -18, 18, 60 }, { -80, -24, 24, 80 }, { -106, -33, 33, 106 }, { -183, -47, 47, 183 }, }; return etc_codeword_table[table][q]; } uniform int remap_q[] = { 2, 3, 1, 0 }; int get_remap2_q(int x) { x -= 2; if (x < 0) x = 1 - x; return x; } int extend_4to8bits(int value) { return (value << 4) | value; } int extend_5to8bits(int value) { return (value << 3) | (value >> 2); } int quantize_4bits(float value) { return clamp((value / 255.0f) * 15 + 0.5, 0, 15); } int quantize_5bits(float value) { return clamp((value / 255.0f) * 31 + 0.5, 0, 31); } void center_quant_dequant(int qcenter[3], float center[3], uniform bool diff, int prev_qcenter[3]) { if (diff) { for (uniform int p = 0; p < 3; p++) { qcenter[p] = quantize_5bits(center[p]); if (prev_qcenter[0] >= 0) { if (qcenter[p] - prev_qcenter[p] > 3) qcenter[p] = prev_qcenter[p] + 3; if (qcenter[p] - prev_qcenter[p] < -4) qcenter[p] = prev_qcenter[p] - 4; } center[p] = extend_5to8bits(qcenter[p]); } } else { for (uniform int p = 0; p < 3; p++) { qcenter[p] = quantize_4bits(center[p]); center[p] = extend_4to8bits(qcenter[p]); } } } float quantize_pixels_etc1_half(uint32 qblock[1], float block[48], float center[3], uniform int table) { float total_err = 0; uint32 bits = 0; for (uniform int y = 0; y < 2; y++) for (uniform int x = 0; x < 4; x++) { float best_err = sq(255) * 3; int best_q = -1; for (uniform int q = 0; q < 4; q++) { int dY = get_etc1_dY(table, remap_q[q]); float err = 0; for (int p = 0; p < 3; p++) err += sq(block[16 * p + y*4+x] - clamp(center[p] + dY, 0, 255)); if (err < best_err) { best_err = err; best_q = q; } } assert(best_q >= 0); bits |= (best_q & 1) << (x * 4 + y); bits |= (best_q >> 1) << (x * 4 + y + 16); total_err += best_err; } qblock[0] = bits; return total_err; } float compress_etc1_half_1(uint32 out_qbits[1], int out_table[1], int out_qcenter[3], float half_pixels[], uniform bool diff, int prev_qcenter[3]) { float dc[3]; for (uniform int p = 0; p<3; p++) dc[p] = 0; for (uniform int k = 0; k<8; k++) { for (uniform int p = 0; p<3; p++) dc[p] += half_pixels[k + p * 16]; } float best_error = sq(255) * 3 * 8.0f; int best_table = -1; int best_qcenter[3]; uint32 best_qbits; for (uniform int table_level = 0; table_level < 8; table_level++) { float center[3]; int qcenter[3]; uint32 qbits; for (uniform int p = 0; p < 3; p++) center[p] = dc[p] / 8 - get_etc1_dY(table_level, 2); center_quant_dequant(qcenter, center, diff, prev_qcenter); float err = quantize_pixels_etc1_half(&qbits, half_pixels, center, table_level); if (err < best_error) { best_error = err; best_table = table_level; best_qbits = qbits; for (uniform int p = 0; p < 3; p++) best_qcenter[p] = qcenter[p]; } } out_table[0] = best_table; out_qbits[0] = best_qbits; for (uniform int p = 0; p < 3; p++) out_qcenter[p] = best_qcenter[p]; return best_error; } float optimize_center(float colors[4][10], uniform int p, uniform int table_level) { float best_center = 0; for (uniform int q = 0; q < 4; q++) { best_center += (colors[q][7 + p] - get_etc1_dY(table_level, q)) * colors[q][3]; } best_center /= 8; float best_err = 0; for (uniform int q = 0; q < 4; q++) { float dY = get_etc1_dY(table_level, q); best_err += sq(clamp(best_center + dY, 0, 255) - colors[q][7 + p]) * colors[q][3]; } for (uniform int branch = 0; branch < 4; branch++) { float new_center = 0; float sum = 0; for (uniform int q = 0; q < 4; q++) { if (branch <= 1 && q <= branch) continue; if (branch >= 2 && q >= branch) continue; new_center += (colors[q][7 + p] - get_etc1_dY(table_level, q)) * colors[q][3]; sum += colors[q][3]; } new_center /= sum; float err = 0; for (uniform int q = 0; q < 4; q++) { float dY = get_etc1_dY(table_level, q); err += sq(clamp(new_center + dY, 0, 255) - colors[q][7 + p]) * colors[q][3]; } if (err < best_err) { best_err = err; best_center = new_center; } } return best_center; } float compress_etc1_half_7(uint32 out_qbits[1], int out_table[1], int out_qcenter[3], float half_pixels[], etc_enc_state state[]) { int err_list[165]; int y_sorted_inv[8]; float y_sorted[8]; { int y_sorted_idx[8]; for (uniform int k = 0; k < 8; k++) { float value = 0; for (uniform int p = 0; p < 3; p++) value += half_pixels[k + p * 16]; y_sorted_idx[k] = (((int)value) << 4) + k; } partial_sort_list(y_sorted_idx, 8, 8); for (uniform int k = 0; k < 8; k++) y_sorted_inv[k] = ((y_sorted_idx[k] & 0xF) << 4) + k; for (uniform int k = 0; k < 8; k++) y_sorted[k] = (y_sorted_idx[k] >> 4) / 3.0f; partial_sort_list(y_sorted_inv, 8, 8); } uniform int idx = -1; for (uniform int level1 = 0; level1 <= 8; level1++) for (uniform int level2 = level1; level2 <= 8; level2++) for (uniform int level3 = level2; level3 <= 8; level3++) { idx++; assert(idx < 165); float sum[4]; float sum_sq[4]; float count[4]; float inv_count[4]; for (uniform int q = 0; q < 4; q++) { sum[q] = 0; sum_sq[q] = 0; count[q] = 0; inv_count[q] = 0; } for (uniform int k = 0; k < 8; k++) { uniform int q = 0; if (k >= level1) q = 1; if (k >= level2) q = 2; if (k >= level3) q = 3; sum[q] += y_sorted[k]; sum_sq[q] += sq(y_sorted[k]); count[q] += 1; } for (uniform int q = 0; q < 4; q++) { if (count[q] > 0) inv_count[q] = 1 / count[q]; } float base_err = 0; for (uniform int q = 0; q < 4; q++) base_err += sum_sq[q] - sq(sum[q]) * inv_count[q]; float t_err = sq(256) * 8; for (uniform int table_level = 0; table_level < 8; table_level++) { float center = 0; for (uniform int q = 0; q < 4; q++) center += sum[q] - get_etc1_dY(table_level, q) * count[q]; center /= 8; float err = base_err; for (uniform int q = 0; q < 4; q++) { err += sq(center + get_etc1_dY(table_level, q) - sum[q] * inv_count[q])*count[q]; } t_err = min(t_err, err); } int packed = (level1 * 16 + level2) * 16 + level3; err_list[idx] = (((int)t_err) << 12) + packed; } partial_sort_list(err_list, 165, state->fastSkipTreshold); float best_error = sq(255) * 3 * 8.0f; int best_table = -1; int best_qcenter[3]; uint32 best_qbits; for (uniform int i = 0; i < state->fastSkipTreshold; i++) { int packed = err_list[i] & 0xFFF; int level1 = (packed >> 8) & 0xF; int level2 = (packed >> 4) & 0xF; int level3 = (packed >> 0) & 0xF; float colors[4][10]; for (uniform int p = 0; p < 7; p++) for (uniform int q = 0; q < 4; q++) colors[q][p] = 0; uint32 qbits = 0; for (uniform int kk = 0; kk < 8; kk++) { int k = y_sorted_inv[kk] & 0xF; int qq = 0; if (k >= level1) qq = 1; if (k >= level2) qq = 2; if (k >= level3) qq = 3; uniform int xx = kk & 3; uniform int yy = kk >> 2; int qqq = get_remap2_q(qq); qbits |= (qqq & 1) << (yy + xx * 4); qbits |= (qqq >> 1) << (16 + yy + xx * 4); float qvec[4]; for (uniform int q = 0; q < 4; q++) { qvec[q] = q == qq ? 1.0 : 0.0; colors[q][3] += qvec[q]; } for (uniform int p = 0; p < 3; p++) { float value = half_pixels[16 * p + kk]; for (uniform int q = 0; q < 4; q++) { colors[q][p] += value * qvec[q]; colors[q][4 + p] += sq(value) * qvec[q]; } } } float base_err = 0; for (uniform int q = 0; q < 4; q++) { if (colors[q][3] > 0) for (uniform int p = 0; p < 3; p++) { colors[q][7 + p] = colors[q][p] / colors[q][3]; base_err += colors[q][4 + p] - sq(colors[q][7 + p])*colors[q][3]; } } for (uniform int table_level = 0; table_level < 8; table_level++) { float center[3]; int qcenter[3]; for (uniform int p = 0; p < 3; p++) { center[p] = optimize_center(colors, p, table_level); } center_quant_dequant(qcenter, center, state->diff, state->prev_qcenter); float err = base_err; for (uniform int q = 0; q < 4; q++) { int dY = get_etc1_dY(table_level, q); for (uniform int p = 0; p < 3; p++) err += sq(clamp(center[p] + dY, 0, 255) - colors[q][7 + p])*colors[q][3]; } if (err < best_error) { best_error = err; best_table = table_level; best_qbits = qbits; for (uniform int p = 0; p < 3; p++) best_qcenter[p] = qcenter[p]; } } } out_table[0] = best_table; out_qbits[0] = best_qbits; for (uniform int p = 0; p < 3; p++) out_qcenter[p] = best_qcenter[p]; return best_error; } float compress_etc1_half(uint32 qbits[1], int table[1], int qcenter[3], float half_pixels[], etc_enc_state state[]) { float err = compress_etc1_half_7(qbits, table, qcenter, half_pixels, state); for (uniform int p = 0; p < 3; p++) state->prev_qcenter[p] = qcenter[p]; return err; } ////////////////////////// // ETC1 core inline uint32 bswap32(uint32 v) { uint32 r = 0; r += ((v >> 24) & 255) << 0; r += ((v >> 16) & 255) << 8; r += ((v >> 8) & 255) << 16; r += ((v >> 0) & 255) << 24; return r; } void etc_pack(uint32 data[], uint32 qbits[2], int tables[2], int qcenters[2][3], uniform int diff, uniform int flip) { for (uniform int k = 0; k < 2; k++) data[k] = 0; uniform int pos = 0; if (diff == 0) { put_bits(data, &pos, 4, qcenters[1][0]); put_bits(data, &pos, 4, qcenters[0][0]); put_bits(data, &pos, 4, qcenters[1][1]); put_bits(data, &pos, 4, qcenters[0][1]); put_bits(data, &pos, 4, qcenters[1][2]); put_bits(data, &pos, 4, qcenters[0][2]); } else { put_bits(data, &pos, 3, (qcenters[1][0] - qcenters[0][0]) & 7); put_bits(data, &pos, 5, qcenters[0][0]); put_bits(data, &pos, 3, (qcenters[1][1] - qcenters[0][1]) & 7); put_bits(data, &pos, 5, qcenters[0][1]); put_bits(data, &pos, 3, (qcenters[1][2] - qcenters[0][2]) & 7); put_bits(data, &pos, 5, qcenters[0][2]); } put_bits(data, &pos, 1, flip); put_bits(data, &pos, 1, diff); put_bits(data, &pos, 3, tables[1]); put_bits(data, &pos, 3, tables[0]); uint32 all_qbits_flipped = (qbits[1] << 2) | qbits[0]; uint32 all_qbits = 0; if (flip != 0) all_qbits = all_qbits_flipped; if (flip == 0) for (uniform int k = 0; k < 2; k++) for (uniform int y = 0; y < 4; y++) for (uniform int x = 0; x < 4; x++) { int bit = (all_qbits_flipped >> (k * 16 + x * 4 + y)) & 1; all_qbits += bit << (k * 16 + y * 4 + x); } data[1] = bswap32(all_qbits); } inline void CompressBlockETC1_core(etc_enc_state state[]) { float flipped_block[48]; for (uniform int y = 0; y < 4; y++) for (uniform int x = 0; x < 4; x++) for (uniform int p = 0; p < 3; p++) { flipped_block[16 * p + x * 4 + y] = state->block[16 * p + y * 4 + x]; } for (uniform int flip = 0; flip < 2; flip++) for (uniform int diff = 1; diff >= 0; diff--) { state->diff = diff == 1; state->prev_qcenter[0] = -1; varying float * uniform pixels = state->block; if (flip == 0) pixels = flipped_block; uint32 qbits[2]; int tables[2]; int qcenters[2][3]; float err = 0; err += compress_etc1_half(&qbits[0], &tables[0], qcenters[0], &pixels[0], state); err += compress_etc1_half(&qbits[1], &tables[1], qcenters[1], &pixels[8], state); if (err < state->best_err) { state->best_err = err; etc_pack(state->best_data, qbits, tables, qcenters, diff, flip); } } } void etc_enc_copy_settings(etc_enc_state state[], uniform etc_enc_settings settings[]) { state->fastSkipTreshold = settings->fastSkipTreshold; } inline void CompressBlockETC1(uniform rgba_surface src[], int xx, uniform int yy, uniform uint8 dst[], uniform etc_enc_settings settings[]) { etc_enc_state _state; varying etc_enc_state* uniform state = &_state; etc_enc_copy_settings(state, settings); load_block_interleaved(state->block, src, xx, yy); state->best_err = 1e99; CompressBlockETC1_core(state); store_data(dst, src->width, xx, yy, state->best_data, 2); } export void CompressBlocksETC1_ispc(uniform rgba_surface src[], uniform uint8 dst[], uniform etc_enc_settings settings[]) { for (uniform int yy = 0; yyheight / 4; yy++) foreach(xx = 0 ... src->width / 4) { CompressBlockETC1(src, xx, yy, dst, settings); } } ================================================ FILE: IntelCompressionPlugin/resource.h ================================================ //{{NO_DEPENDENCIES}} // Microsoft Visual C++ generated include file. // Used by IntelPlugin.rc // #define IDC_PRESETDELETE_BUTTON 3 #define IDC_COMPRESSION_HELP 4 #define IDC_COMPRESSION_COMBO 6 #define IDC_COMPRESSION_HINT 7 #define IDC_TEXTURETYPE_HELP 8 #define IDC_TEXTURETYPE_COMBO 10 #define IDC_TEXTURETYPE_HINT 11 #define IDC_CUBEMIPLEVEL_CHECK 13 #define IDC_MIPLEVEL_COMBO 15 #define IDC_PRECOMPRESS_HELP 16 #define IDC_NORMALIZE_CHECK 18 #define IDC_FLIPX_CHECK 19 #define IDC_FLIPY_CHECK 20 #define IDC_MIPMAP_HELP 21 #define IDC_MIPMAPCOMBO 23 #define IDC_MIPMAP_COMBO 23 #define IDC_PREVIEWPROXY_ORIGINAL 23 #define IDC_MIPMAPS_HINT 24 #define IDC_PREVIEWPROXY_COMPRESSED 24 #define IDC_PREVIEW_BUTTON 25 #define IDC_PREVIEWPROXY_ORIGINALTEXT 25 #define IDC_PREVIEWPROXY_TEXT 26 #define IDC_PRESET_COMBO 27 #define IDC_PRESETSAVE_BUTTON 28 #define IDC_PREVIEWPROXY_ZOOMIN 31 #define IDC_PREVIEWPROXY_ZOOMOUT 32 #define IDC_PREVIEWPROXY_ZOOMTEXT 33 #define IDC_PREVIEWPROXY_ZOOM1X 34 #define IDC_PREVIEWPROXY_ZOOM2X 35 #define IDC_PREVIEWPROXY_ZOOM4X 36 #define IDC_PREVIEWPROXY_ZOOMFIT 37 #define IDC_PREVIEWPROXY_ZOOMHALF 38 #define IDC_PREVIEWPROXY_ZOOMQUARTER 39 #define IDC_PREVIEWPROXY_RGB 40 #define IDC_PREVIEWPROXY_R 41 #define IDC_PREVIEWPROXY_G 42 #define IDC_PREVIEWPROXY_B 43 #define IDC_PREVIEWPROXY_A 44 #define IDC_PREVIEWPROXY_COMBOBOX 50 #define IDC_PREVIEWPROXY_TEXTSIZEUNCOMPRESSED 54 #define IDC_PREVIEWPROXY_TEXTSIZECOMPRESSED 55 #define IDD_GETNAME 109 #define IDD_PREVIEW 110 #define IDD_LOADDIALOG 111 #define IDC_BUTTON1 1001 #define IDC_COMBO1 1003 #define IDC_EDIT1 1005 #define IDC_NAME_EDIT 1005 #define IDC_EXPOSURE_SLIDER 1006 #define IDC_LOADDIALOG_MIPMAPCHECK 1007 #define IDC_LOADDIALOG_ALPHAGROUP 1008 #define IDC_LOADDIALOG_ALPHACHECK 1009 #define IDC_LOADDIALOG_MIPMAPGROUP 1010 #define IDD_MAINDIALOG 16001 #define IDD_ABOUT 28950 // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NO_MFC 1 #define _APS_NEXT_RESOURCE_VALUE 112 #define _APS_NEXT_COMMAND_VALUE 40001 #define _APS_NEXT_CONTROL_VALUE 1010 #define _APS_NEXT_SYMED_VALUE 121 #endif #endif ================================================ FILE: IntelTextureWorks.sln ================================================  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 2012 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{AB3F9437-325F-430D-A6E0-5CBDBD53B73F}" ProjectSection(SolutionItems) = preProject README.md = README.md EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DirectXTex", "3rdParty\DirectXTex\DirectXTex\DirectXTex_Desktop_2012.vcxproj", "{371B9FA9-4C90-4AC6-A123-ACED756D6C77}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "IntelTextureWorks", "IntelCompressionPlugin\IntelTextureWorks.vcxproj", "{FAA37424-40A7-47F4-98CB-4B9464145B0D}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Debug|x64 = Debug|x64 Profile|Win32 = Profile|Win32 Profile|x64 = Profile|x64 Release|Win32 = Release|Win32 Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Debug|Win32.ActiveCfg = Debug|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Debug|Win32.Build.0 = Debug|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Debug|x64.ActiveCfg = Debug|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Debug|x64.Build.0 = Debug|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Profile|Win32.ActiveCfg = Profile|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Profile|Win32.Build.0 = Profile|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Profile|x64.ActiveCfg = Profile|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Profile|x64.Build.0 = Profile|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Release|Win32.ActiveCfg = Release|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Release|Win32.Build.0 = Release|Win32 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Release|x64.ActiveCfg = Release|x64 {371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Release|x64.Build.0 = Release|x64 {FAA37424-40A7-47F4-98CB-4B9464145B0D}.Debug|Win32.ActiveCfg = Debug|Win32 {FAA37424-40A7-47F4-98CB-4B9464145B0D}.Debug|Win32.Build.0 = Debug|Win32 {FAA37424-40A7-47F4-98CB-4B9464145B0D}.Debug|x64.ActiveCfg = Debug|x64 {FAA37424-40A7-47F4-98CB-4B9464145B0D}.Debug|x64.Build.0 = Debug|x64 {FAA37424-40A7-47F4-98CB-4B9464145B0D}.Profile|Win32.ActiveCfg = Release|Win32 {FAA37424-40A7-47F4-98CB-4B9464145B0D}.Profile|Win32.Build.0 = Release|Win32 {FAA37424-40A7-47F4-98CB-4B9464145B0D}.Profile|x64.ActiveCfg = Release|x64 {FAA37424-40A7-47F4-98CB-4B9464145B0D}.Profile|x64.Build.0 = Release|x64 {FAA37424-40A7-47F4-98CB-4B9464145B0D}.Release|Win32.ActiveCfg = Release|Win32 {FAA37424-40A7-47F4-98CB-4B9464145B0D}.Release|Win32.Build.0 = Release|Win32 {FAA37424-40A7-47F4-98CB-4B9464145B0D}.Release|x64.ActiveCfg = Release|x64 {FAA37424-40A7-47F4-98CB-4B9464145B0D}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal ================================================ FILE: PhotoshopScripts/IntelTextureWorks-ConvertCubeMap.jsx ================================================ // Description: // This script has been tried on Adobe Photoshop CC 2014. // The script runs on both Windows or Mac-OS versions of Photoshop. // The script should work with all color spaces and pixel depths // To use, have an image open and run the script from Photoshop's "File->Scripts" menu. // This script converts Layered cube maps with layer names -X,+X,-Z,+Z,-Y,+Y, to horizontal single layer format. // Or horizontal/vertical cube map fomated documents to Layered cube map documents. // The original image reamins unatered, a new image is always created. // Any additional layer like Adjustment layers etc, will get duplicated into the new image. // // Use this script to export a cubemap in split faces (into layers) format when color operating layers like adjustment layers // are situates ontop of it. Then export the new file with the Intel Texture Works dds file format. // This circumvents photoshops limitation to apply these color operation adjustment layers onto the inidividual layers and then // save out the dds preserving the layers and not flattening it. // // Installation: // Place this script in your Photoshop Presets\Scripts directory and re-start Photoshop. // The script will then appear in your "File->Scripts..." menu items. // For more info on Photoshop scripting, see // http://partners.Adobe.com/public/developer/photoshop/devcenter.html // var gSquare = new UnitValue(256,"px"); var gZero = new UnitValue(0,"px"); function main_body() { if (!app.documents.length > 0) { // stop if no document is opened. alert("Sorry, No Current Document"); } else { var strtRulerUnits = app.preferences.rulerUnits; if (strtRulerUnits != Units.PIXELS) { app.preferences.rulerUnits = Units.PIXELS; // selections are always in pixels } var origDoc = app.activeDocument; var w = origDoc.width; var h = origDoc.height; var bits = origDoc.bitsPerChannel; var layerName = new Array("+Y","-X","+Z","+X","-Z","-Y"); var orgCorners; //image cubemap face coords into original Doc var orgRot; var newCornrner; //image cubemap face coords into new Doc var newDoc; //Determine cube map format if (origDoc.artLayers.length >= 6) //copy layered to horizontal cubemap format ---------------------------------------------------------------------------------- { //-----------------Preparation----------------------------------------------------------------- //store tile width gSquare = w; //get coordinates to copy tioles from old to new document orgCorners = square_corners(); newCorners = horizontal_corners(); orgRot = new Array(0,0,0,0,0,0); //no rotations by default //create new document ready for horizoal cube map aligment newDoc = app.documents.add(gSquare*4,gSquare*3, origDoc.resolution,"cubeMapHorizontal",NewDocumentMode.RGB,DocumentFill.TRANSPARENT); newDoc.bitsPerChannel = bits; newDoc.info.source = "Generated by IntelTextureTools from '" + origDoc.name + "'"; newDoc.info.category = "cubemap"; // duplicate original document to be safe var tempDoc; activeDocument = origDoc; tempDoc = origDoc.duplicate(); activeDocument = tempDoc; //force rgb mode if (tempDoc.mode != DocumentMode.RGB) { tempDoc.changeMode(ChangeMode.RGB); } //-----------------------face copy------------------------------------------------------ //copy faces from 'tempDoc' to 'newDoc'. Search for the 6 faces by name var i; for (i=0; i<6; i++) { //get layer var layerRef = app.activeDocument.artLayers.getByName(layerName[i]); //if layer exists copy it into new document if (layerRef != null) { CopyTile(tempDoc, newDoc, orgCorners[i], newCorners[i], orgRot[i], layerRef); } } app.activeDocument = newDoc; app.activeDocument.mergeVisibleLayers(); //----------------------rest layers copy-------------------------------------------------------- //Now copy over using duplication the rest of the layers from temDoc to newDoc var layerNameStr = layerName.toString(); //create a string array for searching //for all layers in the document app.activeDocument = tempDoc; for (i=activeDocument.artLayers.length-1; i>=0; i--) { //Ommit the already processed cubemap faces. Search by name if the selected layer is a cubemap face if (layerNameStr.indexOf(activeDocument.artLayers[i].name) == -1) { //Duplicate form src doc into dst doc activeDocument.artLayers[i].duplicate(newDoc, ElementPlacement.INSIDE); } } //------------------------clean up------------------------------------------------------------ //close it without saving tempDoc.close(SaveOptions.DONOTSAVECHANGES); } else if (w/4 == h/3) //copy horizontal cubemap format to layered ---------------------------------------------------------------------------------- { //-----------------Preparation----------------------------------------------------------------- //store tile width gSquare = w/4; //get coordinates to copy tioles from old to new document orgCorners = horizontal_corners(); newCorners = square_corners(); //create new document ready for horizoal cube map aligment newDoc = app.documents.add(gSquare,gSquare, origDoc.resolution,"cubeMapLayered",NewDocumentMode.RGB,DocumentFill.TRANSPARENT); newDoc.bitsPerChannel = bits; newDoc.info.source = "Generated by IntelTextureTools from '" + origDoc.name + "'"; newDoc.info.category = "cubemap"; app.activeDocument = origDoc; //-----------------------face copy------------------------------------------------------ //get first layer where the cubemap is assumed and copy tiles into new doc as layers var layerRef = app.activeDocument.artLayers[app.activeDocument.artLayers.length-1]; app.activeDocument.activeLayer = layerRef; for (var i=0; i=0; i1--) { //Duplicate from src doc into dst doc app.activeDocument.artLayers[i1].duplicate(newDoc, ElementPlacement.INSIDE); } app.activeDocument = newDoc; } else if (w/3 == h/4) //copy vertical cubemap format to layered---------------------------------------------------------------------------------- { //-----------------Preparation----------------------------------------------------------------- //store tile width gSquare = w/3; //get coordinates to copy tioles from old to new document orgCorners = vertical_corners(); newCorners = square_corners(); //create new document ready for horizoal cube map aligment newDoc = app.documents.add(gSquare,gSquare, origDoc.resolution,"cubeMapLayered",NewDocumentMode.RGB,DocumentFill.TRANSPARENT); newDoc.bitsPerChannel = bits; newDoc.info.source = "Generated by IntelTextureTools from '" + origDoc.name + "'"; newDoc.info.category = "cubemap"; app.activeDocument = origDoc; //-----------------------face copy------------------------------------------------------ //get first layer where the cubemap is assumed and copy tiles into new doc as layers var layerRef = app.activeDocument.artLayers[app.activeDocument.artLayers.length-1]; app.activeDocument.activeLayer = layerRef; for (var i=0; i=0; i1--) { //Duplicate from src doc into dst doc app.activeDocument.artLayers[i1].duplicate(newDoc, ElementPlacement.INSIDE); } app.activeDocument = newDoc; } else { alert("Document has not the right format. This script converts Layered cube maps with layer names -X,+X,-Z,+Z,-Y,+Y, to horizontal single layer format. Or horizontal/vertical cube map fomated documents to Layered cube map documents."); } if (strtRulerUnits != Units.PIXELS) app.preferences.rulerUnits = strtRulerUnits; } } main_body(); //The target doc is layed out in a horizontal cubemap format // +Y //-X +Z +X -Z // -Y function horizontal_corners() { var pyCorner = new Array(gSquare,gZero); var pzCorner = step_down(pyCorner,gSquare); var nyCorner = step_down(pzCorner,gSquare); var nxCorner = step_right(pzCorner,-gSquare); var pxCorner = step_right(pzCorner,gSquare); var nzCorner = step_right(pxCorner,gSquare); return new Array(pyCorner,nxCorner,pzCorner,pxCorner,nzCorner,nyCorner); } //The target doc is layed out in a vertical cubemap format // +Y //-X +Z +X // -Y // -Z function vertical_corners() { var pyCorner = new Array(gSquare,gZero); var pzCorner = step_down(pyCorner,gSquare); var nyCorner = step_down(pzCorner,gSquare); var nxCorner = step_right(pzCorner,-gSquare); var pxCorner = step_right(pzCorner,gSquare); var nzCorner = step_down(nyCorner,gSquare); return new Array(pyCorner,nxCorner,pzCorner,pxCorner,nzCorner,nyCorner); } //The original doc has one face per layer so the coords are at 0,0 function square_corners() { var origin = new Array(gZero,gZero); return new Array(origin,origin,origin,origin,origin,origin); } function step_right(corner,size) { return new Array(corner[0]+size,corner[1]); } function step_down(corner,size) { return new Array(corner[0],corner[1]+size); } function CopyTilesToLayeredFormat(oDoc, nDoc, oCorner, nCorner, srcLayer, layerName) { var s = gSquare; //src coordinates of the copy rectangle corers var oX = new Array(oCorner[0]+s, oCorner[1]); var oY = new Array(oCorner[0], oCorner[1]+s); var oXY = new Array(oCorner[0]+s, oCorner[1]+s); //destination coordinates of the copy rectangle corners var nX = new Array(nCorner[0]+s, nCorner[1]); var nY = new Array(nCorner[0], nCorner[1]+s); var nXY = new Array(nCorner[0]+s, nCorner[1]+s); // store full copy coordinated var oBound = new Array(oCorner,oX,oXY,oY); var nBound = new Array(nCorner,nX,nXY,nY); //start form src document and activate layer, select and copy activeDocument = oDoc; activeDocument.activeLayer = srcLayer; oDoc.selection.select(oBound); oDoc.selection.copy(); oDoc.selection.deselect(); //activate dst document, select and past into selection activeDocument = nDoc; nDoc.selection.select(nBound); var newLayer = nDoc.paste(); newLayer.name = layerName; nDoc.selection.deselect(); //revert to active src documetn activeDocument = oDoc; } //Copy from srcLayer from oDoc to nDoc. The coordinates for copy selection are also passed. function CopyTile(oDoc, nDoc, oCorner, nCorner, angle, srcLayer) { var s = gSquare; //src coordinates of the copy rectangle corers var oX = new Array(oCorner[0]+s, oCorner[1]); var oY = new Array(oCorner[0], oCorner[1]+s); var oXY = new Array(oCorner[0]+s, oCorner[1]+s); //destination coordinates of the copy rectangle corners var nX = new Array(nCorner[0]+s, nCorner[1]); var nY = new Array(nCorner[0], nCorner[1]+s); var nXY = new Array(nCorner[0]+s, nCorner[1]+s); // store full copy coordinated var oBound = new Array(oCorner,oX,oXY,oY); var nBound = new Array(nCorner,nX,nXY,nY); //start form src document and activate layer, select and copy activeDocument = oDoc; activeDocument.activeLayer = srcLayer; oDoc.selection.select(oBound); oDoc.selection.copy(); oDoc.selection.deselect(); //activate dst document, select and past into selection activeDocument = nDoc; nDoc.selection.select(nBound); var newLayer = nDoc.paste(); //rotate dst copy selection if needed if (nDoc.bitsPerChannel == BitsPerChannelType.THIRTYTWO) { nDoc.selection.rotate(angle); } else { if (angle != 0) { newLayer.rotate(angle); } } nDoc.selection.deselect(); //revert to active src documetn activeDocument = oDoc; } // eof ================================================ FILE: PhotoshopScripts/IntelTextureWorks-CubeMapGaussianBlur.jsx ================================================ // Description: // This script has been tried on Adobe Photoshop CC 2014. // The script runs on both Windows or Mac-OS versions of Photoshop. // The script should work with all color spaces and pixel depths // To use, have an image open and run the script from Photoshop's "File->Scripts" menu. // The currently open document should be a cubemap, each face should be in a layer // and have the appropriate name +Y,-Y,+X,-X,+Z,-Z. Without the proper naming it will not work. // It applies a Gaussian Blur Filter onto the CubeMap, mathcing also the edge pixels to alleviate discontiniouties between faces. // The original image reamins unatered, a new image is always created. // // Installation: // Place this script in your Photoshop Presets\Scripts directory and re-start Photoshop. // The script will then appear in your "File->Scripts..." menu items. // For more info on Photoshop scripting, see // http://partners.Adobe.com/public/developer/photoshop/devcenter.html // var gSquare = new UnitValue(256,"px"); var gZero = new UnitValue(0,"px"); var bluramount = 100; var isBreak = false; var windowResourcePopUp = "palette { \ orientation: 'column', \ alignChildren: ['fill', 'top'], \ preferredSize:[300, 70], \ text: 'CubeMapBlur', \ margins:15, \ \ bottomGroup: Group{ \ txtMessage: StaticText {text:'Start Processing', size: [180,30], alignment:['center', 'center']} \ cancelButton: Button { text: 'Cancel', properties:{name:'cancel'}, size: [60,24], alignment:['right', 'center'] }, \ }\ }" // String containing info needed to build the ScriptUI window var windowResource = "dialog { \ valuePanel: Panel { \ orientation: 'column', \ alignChildren: ['fill', 'top'], \ text: 'Radius (1-200)', \ valueText: EditText {}, \ buttonsGroup: Group { \ cancelButton: Button {text: 'cancel', properties: {name: 'cancel'}}, \ okButton: Button {text: 'Ok', properties: {name: 'ok'}} \ } \ } \ }" var win; function showPopUp(message) { win.show(); win.bottomGroup. txtMessage.text=message; app.refresh(); } function closePopUp() { win.close(); } function CloseAll(newDoc, tgtDoc, strtRulerUnits) { newDoc.close(SaveOptions.DONOTSAVECHANGES); tgtDoc.close(SaveOptions.DONOTSAVECHANGES); if (strtRulerUnits != Units.PIXELS) app.preferences.rulerUnits = strtRulerUnits; } function main_body() { if (!app.documents.length > 0) { // stop if no document is opened. alert("Sorry, No Current Document"); } else { //Modal UI window win = new Window(windowResource); win.text = "CubeMap Gaussian Blur"; win.valuePanel.valueText.active = true; // button callbacks win.valuePanel.buttonsGroup.cancelButton.onClick = function() { bluramount=0; return win.close(); }; win.valuePanel.buttonsGroup.okButton.onClick = function() { bluramount = Number(win.valuePanel.valueText.text); win.close(); }; win.center(); win.show(); //Create Non Modal UI mesage window win = new Window(windowResourcePopUp); win.bottomGroup.cancelButton.onClick = function() { isBreak = true; win.close(); }; if (bluramount <=0 || bluramount >200) return; var strtRulerUnits = app.preferences.rulerUnits; if (strtRulerUnits != Units.PIXELS) { app.preferences.rulerUnits = Units.PIXELS; // selections are always in pixels } var origDoc = app.activeDocument; var newDoc; var tgtDoc; var w = origDoc.width; var h = origDoc.height; var bits = origDoc.bitsPerChannel; var frontFacesNames = new Array("+Z","-X","+X","-Y","+Y"); //have to be in this order center,left, right,bottom,top var faceTargetCoords = new Array (new Array(1,1), new Array(0,1), new Array(2,1), new Array(1,2), new Array(1,0)); var frontFaceRotations = new Array(0,0,0,0,0); var rightFacesNames = new Array("+X","+Z","-Z","-Y","+Y"); var rightFaceRotations = new Array(0,0,0,-90,90); var backFacesNames = new Array("-Z","+X","-X","-Y","+Y"); var backFaceRotations = new Array(0,0,0,180,180); var leftFacesNames = new Array("-X","-Z","+Z","-Y","+Y"); var leftFaceRotations = new Array(0,0,0,90,-90); var upFacesNames = new Array("+Y","-X","+X","+Z","-Z"); var upFaceRotations = new Array(0,90,-90,0,180); var bottomFacesNames = new Array("-Y","-X","+X","-Z","+Z"); var bottomFaceRotations = new Array(0,-90,90,180,0); if (origDoc.artLayers.length >= 6) { //-----------------Preparation----------------------------------------------------------------- gSquare = w; //store tile width //create new document ready for horizoal cube map aligment newDoc = app.documents.add(gSquare*3,gSquare*3, origDoc.resolution, "cubeMapBlurr", NewDocumentMode.RGB, DocumentFill.TRANSPARENT); newDoc.bitsPerChannel = bits; tgtDoc = app.documents.add(gSquare,gSquare, origDoc.resolution, " Blured"+origDoc.name, NewDocumentMode.RGB, DocumentFill.TRANSPARENT); tgtDoc.bitsPerChannel = bits; showPopUp("Processing Face +Z (1/6)"); BlurCubeMapFaceAlternate(frontFacesNames, faceTargetCoords, frontFaceRotations, bluramount, origDoc, newDoc, "Blur +Z", tgtDoc); closePopUp(); if (isBreak) { CloseAll(newDoc, tgtDoc, strtRulerUnits); return; } showPopUp("Processing Face +X (2/6)"); BlurCubeMapFaceAlternate(rightFacesNames, faceTargetCoords,rightFaceRotations, bluramount, origDoc, newDoc, "Blur +X", tgtDoc); closePopUp(); if (isBreak) { CloseAll(newDoc, tgtDoc, strtRulerUnits); return; } showPopUp("Processing Face -X (3/6)"); BlurCubeMapFaceAlternate(leftFacesNames, faceTargetCoords,leftFaceRotations, bluramount, origDoc, newDoc, "Blur -X", tgtDoc); closePopUp(); if (isBreak) { CloseAll(newDoc, tgtDoc, strtRulerUnits); return; } showPopUp("Processing Face -Z (4/6)"); BlurCubeMapFaceAlternate(backFacesNames, faceTargetCoords,backFaceRotations, bluramount, origDoc, newDoc, "Blur -Z", tgtDoc); closePopUp(); if (isBreak) { CloseAll(newDoc, tgtDoc, strtRulerUnits); return; } showPopUp("Processing Face +Y (5/6)"); BlurCubeMapFace(upFacesNames, faceTargetCoords,upFaceRotations, bluramount, origDoc, newDoc, "Blur +Y", tgtDoc); closePopUp(); if (isBreak) { CloseAll(newDoc, tgtDoc, strtRulerUnits); return; } showPopUp("Processing Face -Y (6/6)"); BlurCubeMapFace(bottomFacesNames, faceTargetCoords,bottomFaceRotations, bluramount, origDoc, newDoc, "Blur -Y", tgtDoc); closePopUp(); if (isBreak) { CloseAll(newDoc, tgtDoc, strtRulerUnits); return; } showPopUp("FinalTouchUp"); finalTouch(upFacesNames, faceTargetCoords, upFaceRotations, bluramount, tgtDoc, newDoc, "FinalTouch Up", tgtDoc); if (isBreak) { CloseAll(newDoc, tgtDoc, strtRulerUnits); return; } finalTouch(bottomFacesNames, faceTargetCoords, bottomFaceRotations, bluramount, tgtDoc, newDoc, "FinalTouch Up", tgtDoc); closePopUp(); if (isBreak) { CloseAll(newDoc, tgtDoc, strtRulerUnits); return; } //------------------------clean up------------------------------------------------------------ //close it without saving newDoc.close(SaveOptions.DONOTSAVECHANGES); if (strtRulerUnits != Units.PIXELS) app.preferences.rulerUnits = strtRulerUnits; } else { alert("Please define 6 layers, one for each face of the cubemap with names -X,+X,-Z,+Z,-Y,+Y"); } } } main_body(); function finalTouch(frontFacesNames, faceTargetCoords, frontFaceRotations, bluramount, origDoc, tmpDoc, descriptionStr, tgtDoc) { //clear temp doc app.activeDocument = tmpDoc; app.activeDocument.activelayer = app.activeDocument.artLayers[0]; app.activeDocument.activelayer.clear(); //Copy specific face (the first in list) and all adjacent faces (next 4) for bluring var i=0; for (i=0; i Save As 2. Select "Save as type" > **Intel® Texture Works (\*.DDS;\*.DDS)** 2. Navigate to store location 3. Assign file name 4. Save 5. Select desired plugin options and preview (pan/zoom), as necessary 6. Ok ## Loading Files Saved via Plugin Multiple resident DDS plugins can result in a texture display error on load. To avoid this, use the following process to reload textures saved with the Intel® Texture Works plugin for Photoshop 1. File > Open As 2. Select **Intel® Texture Works (\*.DDS;\*.DDS)** as type (to the right of "File name" field) 3. Select file 4. Select desired mipmap loading options if applicable 5. Select desired color profile loading options ## Logging Bugs, Enhancements, & Feedback Use the [GitHub Issue Tracking System](https://github.com/GameTechDev/Intel-Texture-Works-Plugin/issues) to log your bugs, enhancement (requests), and feedback (general impressions appreciated). **Labels really help here - please use them**. ## NOTE: * Not all authoring apps can read the latest BCn textures. We're keeping a running list of authoring app BCn load status on the Wiki [here](https://github.com/GameTechDev/Intel-Texture-Works-Plugin/wiki/BCn-App-Support) * To implement BCn texture compression in your own apps and engines [download the sample source code here](https://software.intel.com/en-us/articles/fast-ispc-texture-compressor-update) * The [FAQ](https://github.com/GameTechDev/Intel-Texture-Works-Plugin/wiki/FAQ) is also available on the Wiki ## Requirements * Windows\* (32/64) versions 7, 8, 10 * Photoshop\* CS6 through CC2015 * * * # Source Code ## Prerequisites ## - Visual Studio 2012 (or possibly higher, although so far all builds created with 2012) - Photoshop CS6 SDK, can be obtained from here: http://www.adobe.com/devnet/photoshop/sdk.html - Adobe Photoshop 32 or 64 bit, CS6 or higher. - Intel® Implicit SPMD Program Compiler (https://github.com/ispc/ispc/releases) ## First time set-up ## - Install Photoshop CS6 SDK on developer machine - Copy ispc.exe to 3rdParty\Intel\Tools\ directory - Open IntelTextureTools solution - Go to Property Manager and edit settings for Microsoft.Cpp.Win32.user and Microsoft.Cpp.x64.user, adding the following User Macro PHOTOSHOP_SDK_CS6 = - Choose platform appropriate to the version of Photoshop you wish to test with (Win32 or x64) - Build! For convenience plugin binaries will be copied to "~/Plugins/[platform]" folder. ## To easily run/debug from Visual Studio ## - create an alias/shortcut to the appropriate platform folder and place it in the matching Photoshop Plug-ins folder (this will allow photoshop to load plugin from build location) - in plugin project, select Properties->Configuration->Debugging->Target and browse to photoshop executable ## 3rd Party code ## This project utilizes the following code (located under 3rdParty folder) - DirectXTex, from https://github.com/Microsoft/DirectXTex (Sourced from tag Jul2015) - Intel, BC compression code and helpers ``` * Other names and brands may be claimed by their owners. ``` ================================================ FILE: license.txt ================================================ Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: You must give any other recipients of the Work or Derivative Works a copy of this License; and You must cause any modified files to carry prominent notices stating that You changed the files; and You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.