Skip to content

Commit 61c974c

Browse files
author
Floyd Huizinga
committed
Add FreeImage image loading (and updated FreeImage static libraries)
1 parent 8ebb83a commit 61c974c

File tree

8 files changed

+186
-37
lines changed

8 files changed

+186
-37
lines changed

lib/FreeImage/include/FreeImage.h

+15-5
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
// Version information ------------------------------------------------------
3030

3131
#define FREEIMAGE_MAJOR_VERSION 3
32-
#define FREEIMAGE_MINOR_VERSION 17
32+
#define FREEIMAGE_MINOR_VERSION 18
3333
#define FREEIMAGE_RELEASE_SERIAL 0
3434

3535
// Compiler options ---------------------------------------------------------
@@ -75,7 +75,7 @@
7575
// or define any of FREEIMAGE_BIGENDIAN and FREEIMAGE_LITTLEENDIAN directly
7676
// to specify the desired endianness.
7777
#if (!defined(FREEIMAGE_BIGENDIAN) && !defined(FREEIMAGE_LITTLEENDIAN))
78-
#if (defined(BYTE_ORDER) && BYTE_ORDER==BIG_ENDIAN) || (defined(__BYTE_ORDER) && __BYTE_ORDER==__BIG_ENDIAN) || defined(__BIG_ENDIAN__)
78+
#if (defined(BYTE_ORDER) && BYTE_ORDER==BIG_ENDIAN) || (defined(__BYTE_ORDER) && __BYTE_ORDER==__BIG_ENDIAN) || (defined(__BYTE_ORDER) && __BYTE_ORDER==__ORDER_BIG_ENDIAN__) || defined(__BIG_ENDIAN__)
7979
#define FREEIMAGE_BIGENDIAN
8080
#endif // BYTE_ORDER
8181
#endif // !FREEIMAGE_[BIG|LITTLE]ENDIAN
@@ -731,6 +731,9 @@ typedef void (DLL_CALLCONV *FI_InitProc)(Plugin *plugin, int format_id);
731731
#define PSD_DEFAULT 0
732732
#define PSD_CMYK 1 //! reads tags for separated CMYK (default is conversion to RGB)
733733
#define PSD_LAB 2 //! reads tags for CIELab (default is conversion to RGB)
734+
#define PSD_NONE 0x0100 //! save without any compression
735+
#define PSD_RLE 0x0200 //! save using RLE compression
736+
#define PSD_PSB 0x2000 //! save using Adobe Large Document Format (use | to combine with other save flags)
734737
#define RAS_DEFAULT 0
735738
#define RAW_DEFAULT 0 //! load the file as linear RGB 48-bit
736739
#define RAW_PREVIEW 1 //! try to load the embedded JPEG preview with included Exif Data or default to RGB 24-bit
@@ -873,13 +876,19 @@ DLL_API void DLL_CALLCONV FreeImage_UnlockPage(FIMULTIBITMAP *bitmap, FIBITMAP *
873876
DLL_API BOOL DLL_CALLCONV FreeImage_MovePage(FIMULTIBITMAP *bitmap, int target, int source);
874877
DLL_API BOOL DLL_CALLCONV FreeImage_GetLockedPageNumbers(FIMULTIBITMAP *bitmap, int *pages, int *count);
875878

876-
// Filetype request routines ------------------------------------------------
879+
// File type request routines ------------------------------------------------
877880

878881
DLL_API FREE_IMAGE_FORMAT DLL_CALLCONV FreeImage_GetFileType(const char *filename, int size FI_DEFAULT(0));
879882
DLL_API FREE_IMAGE_FORMAT DLL_CALLCONV FreeImage_GetFileTypeU(const wchar_t *filename, int size FI_DEFAULT(0));
880883
DLL_API FREE_IMAGE_FORMAT DLL_CALLCONV FreeImage_GetFileTypeFromHandle(FreeImageIO *io, fi_handle handle, int size FI_DEFAULT(0));
881884
DLL_API FREE_IMAGE_FORMAT DLL_CALLCONV FreeImage_GetFileTypeFromMemory(FIMEMORY *stream, int size FI_DEFAULT(0));
882885

886+
DLL_API BOOL DLL_CALLCONV FreeImage_Validate(FREE_IMAGE_FORMAT fif, const char *filename);
887+
DLL_API BOOL DLL_CALLCONV FreeImage_ValidateU(FREE_IMAGE_FORMAT fif, const wchar_t *filename);
888+
DLL_API BOOL DLL_CALLCONV FreeImage_ValidateFromHandle(FREE_IMAGE_FORMAT fif, FreeImageIO *io, fi_handle handle);
889+
DLL_API BOOL DLL_CALLCONV FreeImage_ValidateFromMemory(FREE_IMAGE_FORMAT fif, FIMEMORY *stream);
890+
891+
883892
// Image type request routine -----------------------------------------------
884893

885894
DLL_API FREE_IMAGE_TYPE DLL_CALLCONV FreeImage_GetImageType(FIBITMAP *dib);
@@ -979,8 +988,11 @@ DLL_API void DLL_CALLCONV FreeImage_ConvertLine16To24_555(BYTE *target, BYTE *so
979988
DLL_API void DLL_CALLCONV FreeImage_ConvertLine16To24_565(BYTE *target, BYTE *source, int width_in_pixels);
980989
DLL_API void DLL_CALLCONV FreeImage_ConvertLine32To24(BYTE *target, BYTE *source, int width_in_pixels);
981990
DLL_API void DLL_CALLCONV FreeImage_ConvertLine1To32(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette);
991+
DLL_API void DLL_CALLCONV FreeImage_ConvertLine1To32MapTransparency(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette, BYTE *table, int transparent_pixels);
982992
DLL_API void DLL_CALLCONV FreeImage_ConvertLine4To32(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette);
993+
DLL_API void DLL_CALLCONV FreeImage_ConvertLine4To32MapTransparency(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette, BYTE *table, int transparent_pixels);
983994
DLL_API void DLL_CALLCONV FreeImage_ConvertLine8To32(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette);
995+
DLL_API void DLL_CALLCONV FreeImage_ConvertLine8To32MapTransparency(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette, BYTE *table, int transparent_pixels);
984996
DLL_API void DLL_CALLCONV FreeImage_ConvertLine16To32_555(BYTE *target, BYTE *source, int width_in_pixels);
985997
DLL_API void DLL_CALLCONV FreeImage_ConvertLine16To32_565(BYTE *target, BYTE *source, int width_in_pixels);
986998
DLL_API void DLL_CALLCONV FreeImage_ConvertLine24To32(BYTE *target, BYTE *source, int width_in_pixels);
@@ -1092,8 +1104,6 @@ DLL_API BOOL DLL_CALLCONV FreeImage_JPEGTransformCombinedFromMemory(FIMEMORY* sr
10921104
// --------------------------------------------------------------------------
10931105

10941106
// rotation and flipping
1095-
/// @deprecated see FreeImage_Rotate
1096-
DLL_API FIBITMAP *DLL_CALLCONV FreeImage_RotateClassic(FIBITMAP *dib, double angle);
10971107
DLL_API FIBITMAP *DLL_CALLCONV FreeImage_Rotate(FIBITMAP *dib, double angle, const void *bkcolor FI_DEFAULT(NULL));
10981108
DLL_API FIBITMAP *DLL_CALLCONV FreeImage_RotateEx(FIBITMAP *dib, double angle, double x_shift, double y_shift, double x_origin, double y_origin, BOOL use_mask);
10991109
DLL_API BOOL DLL_CALLCONV FreeImage_FlipHorizontal(FIBITMAP *dib);

lib/FreeImage/lib/FreeImage.lib

-62.1 KB
Binary file not shown.

lib/FreeImage/lib/FreeImageLib.lib

19.7 MB
Binary file not shown.

lib/FreeImage/lib/FreeImageLibd.lib

73.2 MB
Binary file not shown.

src/Cpp/1-getting-started/1-3-1-ImageLibrary/1-3-1-ImageLibrary.vcxproj

+5-3
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@
5555
<OutDir>bin\$(Configuration)\</OutDir>
5656
<IntDir>obj\$(Configuration)\</IntDir>
5757
<IncludePath>$(SolutionDir)..\lib\glfw-3.3.6\include\;$(SolutionDir)..\lib\FreeImage\include\;$(SolutionDir)..\lib\DirectXTex\include\;$(SolutionDir)Cpp\Framework\;</IncludePath>
58-
<LibraryPath>$(SolutionDir)..\lib\glfw-3.3.6\lib-vc2022\;$(SolutionDir)..\lib\DirectXTex\lib\$(Configuration)\;$(SolutionDir)..\lib\FreeImage\lib\;$(LibraryPath);$(SolutionDir)Cpp\Framework\lib\$(Configuration)\;</LibraryPath>
58+
<LibraryPath>$(SolutionDir)..\lib\glfw-3.3.6\lib-vc2022\;$(SolutionDir)..\lib\DirectXTex\lib\$(Configuration)\;$(SolutionDir)..\lib\FreeImage\lib\;$(LibraryPath);$(SolutionDir)Cpp\Framework\lib\$(Configuration)\</LibraryPath>
5959
</PropertyGroup>
6060
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
6161
<ClCompile>
@@ -64,11 +64,12 @@
6464
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
6565
<ConformanceMode>true</ConformanceMode>
6666
<LanguageStandard>stdcpp17</LanguageStandard>
67+
<AdditionalOptions>/D FREEIMAGE_LIB %(AdditionalOptions)</AdditionalOptions>
6768
</ClCompile>
6869
<Link>
6970
<SubSystem>Console</SubSystem>
7071
<GenerateDebugInformation>true</GenerateDebugInformation>
71-
<AdditionalDependencies>Framework.lib;FreeImage.lib;DirectXTex.lib;glfw3.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
72+
<AdditionalDependencies>Framework.lib;DirectXTex.lib;glfw3.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
7273
<IgnoreSpecificDefaultLibraries>msvcrt</IgnoreSpecificDefaultLibraries>
7374
</Link>
7475
<PostBuildEvent>
@@ -89,13 +90,14 @@ xcopy /Y $(ProjectDir)Assets\Textures\*.* $(OutDir)Assets\Textures\</Command>
8990
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
9091
<ConformanceMode>true</ConformanceMode>
9192
<LanguageStandard>stdcpp17</LanguageStandard>
93+
<AdditionalOptions>/D FREEIMAGE_LIB %(AdditionalOptions)</AdditionalOptions>
9294
</ClCompile>
9395
<Link>
9496
<SubSystem>Console</SubSystem>
9597
<EnableCOMDATFolding>true</EnableCOMDATFolding>
9698
<OptimizeReferences>true</OptimizeReferences>
9799
<GenerateDebugInformation>true</GenerateDebugInformation>
98-
<AdditionalDependencies>Framework.lib;FreeImage.lib;DirectXTex.lib;glfw3.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
100+
<AdditionalDependencies>Framework.lib;DirectXTex.lib;glfw3.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
99101
</Link>
100102
<PostBuildEvent>
101103
<Command>mkdir $(OutDir)Assets\Models\
Loading

src/Cpp/1-getting-started/1-3-1-ImageLibrary/ImageLibraryApplication.cpp

+165-29
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <d3dcompiler.h>
1313

1414
#include <DirectXTex.h>
15+
#include <FreeImage.h>
1516

1617
#include <iostream>
1718

@@ -21,6 +22,12 @@
2122
#pragma comment(lib, "winmm.lib")
2223
#pragma comment(lib, "dxguid.lib")
2324

25+
#if defined(_DEBUG)
26+
#pragma comment(lib, "FreeImageLibd.lib")
27+
#else
28+
#pragma comment(lib, "FreeImageLib.lib")
29+
#endif
30+
2431
template <UINT TDebugNameLength>
2532
inline void SetDebugName(_In_ ID3D11DeviceChild* deviceResource, _In_z_ const char (&debugName)[TDebugNameLength])
2633
{
@@ -133,9 +140,161 @@ bool ImageLibraryApplication::Initialize()
133140

134141
_pipelineFactory = std::make_unique<PipelineFactory>(_device);
135142

143+
FreeImage_Initialise();
136144
return true;
137145
}
138146

147+
WRL::ComPtr<ID3D11ShaderResourceView> CreateTextureViewFromDDS(ID3D11Device* device, const std::wstring& pathToDDS)
148+
{
149+
DirectX::TexMetadata metaData = {};
150+
DirectX::ScratchImage scratchImage;
151+
if (FAILED(DirectX::LoadFromDDSFile(pathToDDS.c_str(), DirectX::DDS_FLAGS_NONE, &metaData, scratchImage)))
152+
{
153+
std::cout << "DXTEX: Failed to load image\n";
154+
return nullptr;
155+
}
156+
157+
WRL::ComPtr<ID3D11Resource> texture = nullptr;
158+
if (FAILED(DirectX::CreateTexture(
159+
device,
160+
scratchImage.GetImages(),
161+
scratchImage.GetImageCount(),
162+
metaData,
163+
&texture)))
164+
{
165+
std::cout << "DXTEX: Failed to create texture out of image\n";
166+
scratchImage.Release();
167+
return nullptr;
168+
}
169+
170+
ID3D11ShaderResourceView* srv = nullptr;
171+
172+
if (FAILED(DirectX::CreateShaderResourceView(
173+
device,
174+
scratchImage.GetImages(),
175+
scratchImage.GetImageCount(),
176+
metaData,
177+
&srv)))
178+
{
179+
std::cout << "DXTEX: Failed to create shader resource view out of texture\n";
180+
scratchImage.Release();
181+
return nullptr;
182+
}
183+
184+
return srv;
185+
}
186+
187+
188+
WRL::ComPtr<ID3D11ShaderResourceView> CreateTextureView(ID3D11Device* device, const std::wstring& pathToTexture)
189+
{
190+
FIBITMAP* image = nullptr;
191+
//Open our file
192+
HANDLE file = CreateFileW(pathToTexture.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, 0);
193+
194+
size_t fileSize = GetFileSize(file, nullptr);
195+
//Create our data buffer and read in the entire file
196+
{
197+
std::vector<BYTE> fileDataRaw(fileSize);
198+
if (!ReadFile(file, fileDataRaw.data(), fileDataRaw.size(), nullptr, nullptr))
199+
{
200+
CloseHandle(file);
201+
return nullptr;
202+
}
203+
204+
//Close our file handle as we don't need it anymore
205+
CloseHandle(file);
206+
207+
FIMEMORY* memHandle = FreeImage_OpenMemory(fileDataRaw.data(), fileDataRaw.size());
208+
FREE_IMAGE_FORMAT imageFormat = FreeImage_GetFileTypeFromMemory(memHandle);
209+
if (imageFormat == FIF_UNKNOWN)
210+
{
211+
FreeImage_CloseMemory(memHandle);
212+
std::cout << "CreateTextureView: Unsupported texture format from file: '" << pathToTexture.c_str() << "'\n";
213+
return nullptr;
214+
}
215+
image = FreeImage_LoadFromMemory(imageFormat, memHandle);
216+
217+
//We no longer need the original data
218+
FreeImage_CloseMemory(memHandle);
219+
220+
} //local scope cleans up fileDataRaw
221+
222+
//Flip the image vertically so this matches up with what DirectXTex loads
223+
FreeImage_FlipVertical(image);
224+
225+
uint32_t textureWidth = FreeImage_GetWidth(image);
226+
uint32_t textureHeight = FreeImage_GetHeight(image);
227+
uint32_t textureBPP = FreeImage_GetBPP(image);
228+
229+
D3D11_TEXTURE2D_DESC textureDesc{};
230+
D3D11_SUBRESOURCE_DATA initialData{};
231+
WRL::ComPtr<ID3D11Texture2D> texture = nullptr;
232+
233+
DXGI_FORMAT textureFormat;
234+
switch (textureBPP)
235+
{
236+
case 8:
237+
textureFormat = DXGI_FORMAT::DXGI_FORMAT_R8_UNORM;
238+
break;
239+
case 16:
240+
textureFormat = DXGI_FORMAT::DXGI_FORMAT_R8G8_UNORM;
241+
break;
242+
case 24:
243+
//D3D11 does not support 24 bit formats for textures, we'll need to convert
244+
{
245+
textureBPP = 32;
246+
FIBITMAP* newImage = FreeImage_ConvertTo32Bits(image);
247+
FreeImage_Unload(image);
248+
image = newImage;
249+
textureFormat = DXGI_FORMAT::DXGI_FORMAT_R8G8B8A8_UNORM;
250+
}
251+
break;
252+
case 32:
253+
textureFormat = DXGI_FORMAT::DXGI_FORMAT_R8G8B8A8_UNORM;
254+
break;
255+
default:
256+
{
257+
//we could try to handle some weird bitcount, but these will probably be HDR or some antique format, just exit instead..
258+
std::cout << "CreateTextureView: Texture has nontrivial bits per pixel ( " << textureBPP << " ), file: '" << pathToTexture.c_str() << "'\n";
259+
return nullptr;
260+
}
261+
break;
262+
}
263+
textureDesc.Format = textureFormat;
264+
textureDesc.ArraySize = 1;
265+
textureDesc.MipLevels = 1;
266+
textureDesc.Height = textureHeight;
267+
textureDesc.Width = textureWidth;
268+
textureDesc.SampleDesc.Count = 1;
269+
textureDesc.Usage = D3D11_USAGE_IMMUTABLE;
270+
textureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
271+
272+
//populate initial data
273+
initialData.pSysMem = FreeImage_GetBits(image);
274+
initialData.SysMemPitch = (textureBPP / 8) * textureWidth;
275+
276+
if (FAILED(device->CreateTexture2D(&textureDesc, &initialData, texture.GetAddressOf())))
277+
{
278+
FreeImage_Unload(image);
279+
return nullptr;
280+
}
281+
FreeImage_Unload(image);
282+
283+
ID3D11ShaderResourceView* srv = nullptr;
284+
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc{};
285+
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
286+
srvDesc.Format = textureDesc.Format;
287+
srvDesc.Texture2D.MipLevels = textureDesc.MipLevels;
288+
289+
if (FAILED(device->CreateShaderResourceView(texture.Get(), &srvDesc, &srv)))
290+
{
291+
std::cout << "CreateTextureView: Failed to create SRV from texture: " << pathToTexture.c_str() << "\n";
292+
return nullptr;
293+
}
294+
295+
return srv;
296+
}
297+
139298
bool ImageLibraryApplication::Load()
140299
{
141300
PipelineDescriptor pipelineDescriptor = {};
@@ -176,37 +335,14 @@ bool ImageLibraryApplication::Load()
176335
return false;
177336
}
178337

179-
DirectX::TexMetadata metaData = {};
180-
DirectX::ScratchImage scratchImage;
181-
if (FAILED(DirectX::LoadFromDDSFile(L"Assets/Textures/T_Froge.dds", DirectX::DDS_FLAGS_NONE, &metaData, scratchImage)))
182-
{
183-
std::cout << "DXTEX: Failed to load image\n";
184-
return false;
185-
}
338+
_fallbackTextureSrv = CreateTextureView(_device.Get(), L"Assets/Textures/default.png");
339+
assert(_fallbackTextureSrv != nullptr); //as a fallback resource, this "needs" to exist
186340

187-
WRL::ComPtr<ID3D11Resource> texture = nullptr;
188-
if (FAILED(DirectX::CreateTexture(
189-
_device.Get(),
190-
scratchImage.GetImages(),
191-
scratchImage.GetImageCount(),
192-
metaData,
193-
&texture)))
194-
{
195-
std::cout << "DXTEX: Failed to create texture out of image\n";
196-
scratchImage.Release();
197-
return false;
198-
}
199-
200-
if (FAILED(DirectX::CreateShaderResourceView(
201-
_device.Get(),
202-
scratchImage.GetImages(),
203-
scratchImage.GetImageCount(),
204-
metaData,
205-
&_textureSrv)))
341+
_textureSrv = CreateTextureViewFromDDS(_device.Get(), L"Assets/Textures/T_Froge.dds");
342+
if (_textureSrv == nullptr)
206343
{
207-
std::cout << "DXTEX: Failed to create shader resource view out of texture\n";
208-
scratchImage.Release();
209-
return false;
344+
//this is "fine", we can use our fallback!
345+
_textureSrv = _fallbackTextureSrv;
210346
}
211347

212348
_pipeline->BindTexture(0, _textureSrv.Get());

src/Cpp/1-getting-started/1-3-1-ImageLibrary/ImageLibraryApplication.hpp

+1
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,5 @@ class ImageLibraryApplication final : public Application
4343

4444
WRL::ComPtr<ID3D11SamplerState> _linearSamplerState = nullptr;
4545
WRL::ComPtr<ID3D11ShaderResourceView> _textureSrv = nullptr;
46+
WRL::ComPtr<ID3D11ShaderResourceView> _fallbackTextureSrv = nullptr;
4647
};

0 commit comments

Comments
 (0)