SourcePP
Several modern C++20 libraries for sanely parsing Valve's formats.
Loading...
Searching...
No Matches
ImageConversion.cpp File Reference
#include <vtfpp/ImageConversion.h>
#include <algorithm>
#include <bit>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <memory>
#include <span>
#include <string_view>
#include <unordered_map>
#include <bcdec.h>
#include <sourcepp/Macros.h>
#include <sourcepp/MathExtended.h>
#include <stb_image.h>
#include <stb_image_resize2.h>
#include <stb_image_write.h>
#include <vtfpp/ImagePixel.h>
Include dependency graph for ImageConversion.cpp:

Go to the source code of this file.

Macros

#define BCDEC_IMPLEMENTATION
#define STB_IMAGE_IMPLEMENTATION
#define STB_IMAGE_STATIC
#define STBI_NO_FAILURE_STRINGS
#define STBI_NO_STDIO
#define STB_IMAGE_RESIZE_IMPLEMENTATION
#define STB_IMAGE_RESIZE_STATIC
#define STB_IMAGE_WRITE_IMPLEMENTATION
#define STB_IMAGE_WRITE_STATIC
#define STBI_WRITE_NO_STDIO
#define VTFPP_REMAP_TO_8(value, shift)
#define VTFPP_CASE_CONVERT(InputType, r, g, b, a)
#define VTFPP_REMAP_FROM_8(value, shift)
#define VTFPP_CASE_CONVERT(OutputType, ...)
#define VTFPP_REMAP_TO_16(value, shift)
#define VTFPP_CASE_CONVERT(InputType, r, g, b, a)
#define VTFPP_REMAP_FROM_16(value, shift)
#define VTFPP_CASE_CONVERT(OutputType, ...)
#define VTFPP_CASE_CONVERT(InputType, r, g, b, a)
#define VTFPP_CASE_CONVERT(OutputType, ...)
#define VTFPP_CREATE_GAMMA_LUTS(InputType)
#define VTFPP_APPLY_GAMMA_RED(value)
#define VTFPP_APPLY_GAMMA_GREEN(value)
#define VTFPP_APPLY_GAMMA_BLUE(value)
#define VTFPP_GAMMA_CORRECT_CASE(InputType, ...)
#define VTFPP_INVERT_GREEN_CASE_OVERRIDE(PixelType, ChannelName, ChannelNameCaps, ...)
#define VTFPP_INVERT_GREEN_CASE(PixelType)
#define VTFPP_TONEMAP_CASE(InputType, ...)

Macro Definition Documentation

◆ BCDEC_IMPLEMENTATION

#define BCDEC_IMPLEMENTATION

Definition at line 26 of file ImageConversion.cpp.

◆ STB_IMAGE_IMPLEMENTATION

#define STB_IMAGE_IMPLEMENTATION

Definition at line 42 of file ImageConversion.cpp.

◆ STB_IMAGE_RESIZE_IMPLEMENTATION

#define STB_IMAGE_RESIZE_IMPLEMENTATION

Definition at line 48 of file ImageConversion.cpp.

◆ STB_IMAGE_RESIZE_STATIC

#define STB_IMAGE_RESIZE_STATIC

Definition at line 49 of file ImageConversion.cpp.

◆ STB_IMAGE_STATIC

#define STB_IMAGE_STATIC

Definition at line 43 of file ImageConversion.cpp.

◆ STB_IMAGE_WRITE_IMPLEMENTATION

#define STB_IMAGE_WRITE_IMPLEMENTATION

Definition at line 52 of file ImageConversion.cpp.

◆ STB_IMAGE_WRITE_STATIC

#define STB_IMAGE_WRITE_STATIC

Definition at line 53 of file ImageConversion.cpp.

◆ STBI_NO_FAILURE_STRINGS

#define STBI_NO_FAILURE_STRINGS

Definition at line 44 of file ImageConversion.cpp.

◆ STBI_NO_STDIO

#define STBI_NO_STDIO

Definition at line 45 of file ImageConversion.cpp.

◆ STBI_WRITE_NO_STDIO

#define STBI_WRITE_NO_STDIO

Definition at line 54 of file ImageConversion.cpp.

◆ VTFPP_APPLY_GAMMA_BLUE

#define VTFPP_APPLY_GAMMA_BLUE ( value)
Value:
static_cast<decltype(value)>(gammaLUTs.at(ImageFormatDetails::blue(PIXEL_TYPE::FORMAT))[value])
constexpr int8_t blue(ImageFormat format)
Get the number of bits of precision of the blue channel in the given format.

◆ VTFPP_APPLY_GAMMA_GREEN

#define VTFPP_APPLY_GAMMA_GREEN ( value)
Value:
static_cast<decltype(value)>(gammaLUTs.at(ImageFormatDetails::green(PIXEL_TYPE::FORMAT))[value])
constexpr int8_t green(ImageFormat format)
Get the number of bits of precision of the green channel in the given format.

◆ VTFPP_APPLY_GAMMA_RED

#define VTFPP_APPLY_GAMMA_RED ( value)
Value:
static_cast<decltype(value)>(gammaLUTs.at(ImageFormatDetails::red(PIXEL_TYPE::FORMAT))[value])
constexpr int8_t red(ImageFormat format)
Get the number of bits of precision of the red channel in the given format.

◆ VTFPP_CASE_CONVERT [1/6]

#define VTFPP_CASE_CONVERT ( InputType,
r,
g,
b,
a )
Value:
case InputType: return ImagePixel::transform<ImagePixel::InputType, ImagePixel::RGBA32323232F>(imageData, [](ImagePixel::InputType pixel) -> ImagePixel::RGBA32323232F { \
return {{(r), (g), (b), (a)}}; \
})
std::vector< std::byte > transform(std::span< const std::byte > imageData, Func callback)
Run a parallelizable/vectorizable operation on the given image data, and return new image data.
Definition ImagePixel.h:567

◆ VTFPP_CASE_CONVERT [2/6]

#define VTFPP_CASE_CONVERT ( InputType,
r,
g,
b,
a )
Value:
case InputType: return ImagePixel::transform<ImagePixel::InputType, ImagePixel::RGBA16161616>(imageData, [](ImagePixel::InputType pixel) -> ImagePixel::RGBA16161616 { \
return {{(r), (g), (b), (a)}}; \
})

◆ VTFPP_CASE_CONVERT [3/6]

#define VTFPP_CASE_CONVERT ( InputType,
r,
g,
b,
a )
Value:
case InputType: return ImagePixel::transform<ImagePixel::InputType, ImagePixel::RGBA8888>(imageData, [](ImagePixel::InputType pixel) -> ImagePixel::RGBA8888 { \
return {{(r), (g), (b), (a)}}; \
})

◆ VTFPP_CASE_CONVERT [4/6]

#define VTFPP_CASE_CONVERT ( OutputType,
... )
Value:
case OutputType: return ImagePixel::transform<ImagePixel::RGBA32323232F, ImagePixel::OutputType>(imageData, [](ImagePixel::RGBA32323232F pixel) -> ImagePixel::OutputType { \
return {__VA_ARGS__}; \
})

◆ VTFPP_CASE_CONVERT [5/6]

#define VTFPP_CASE_CONVERT ( OutputType,
... )
Value:
case OutputType: return ImagePixel::transform<ImagePixel::RGBA16161616, ImagePixel::OutputType>(imageData, [](ImagePixel::RGBA16161616 pixel) -> ImagePixel::OutputType { \
return {__VA_ARGS__}; \
})

◆ VTFPP_CASE_CONVERT [6/6]

#define VTFPP_CASE_CONVERT ( OutputType,
... )
Value:
case OutputType: return ImagePixel::transform<ImagePixel::RGBA8888, ImagePixel::OutputType>(imageData, [](ImagePixel::RGBA8888 pixel) -> ImagePixel::OutputType { \
return {__VA_ARGS__}; \
})

◆ VTFPP_CREATE_GAMMA_LUTS

#define VTFPP_CREATE_GAMMA_LUTS ( InputType)
Value:
std::unordered_map<uint8_t, std::array<uint8_t, 256>> gammaLUTs; \
if constexpr (ImageFormatDetails::red(ImageFormat::InputType) > 0) { \
if (!gammaLUTs.contains(ImageFormatDetails::red(ImageFormat::InputType))) { \
gammaLUTs[ImageFormatDetails::red(ImageFormat::InputType)] = calculateGammaLUT(gamma, ImageFormatDetails::red(ImageFormat::InputType)); \
} \
} \
if constexpr (ImageFormatDetails::green(ImageFormat::InputType) > 0) { \
if (!gammaLUTs.contains(ImageFormatDetails::green(ImageFormat::InputType))) { \
gammaLUTs[ImageFormatDetails::green(ImageFormat::InputType)] = calculateGammaLUT(gamma, ImageFormatDetails::green(ImageFormat::InputType)); \
} \
} \
if constexpr (ImageFormatDetails::blue(ImageFormat::InputType) > 0) { \
if (!gammaLUTs.contains(ImageFormatDetails::blue(ImageFormat::InputType))) { \
gammaLUTs[ImageFormatDetails::blue(ImageFormat::InputType)] = calculateGammaLUT(gamma, ImageFormatDetails::blue(ImageFormat::InputType)); \
} \
}

◆ VTFPP_GAMMA_CORRECT_CASE

#define VTFPP_GAMMA_CORRECT_CASE ( InputType,
... )
Value:
case InputType: { \
VTFPP_CREATE_GAMMA_LUTS(InputType) \
return ImagePixel::transformInPlace<ImagePixel::InputType>(imageData, [&gammaLUTs](ImagePixel::InputType pixel) -> ImagePixel::InputType { \
using PIXEL_TYPE = ImagePixel::InputType; \
return {__VA_ARGS__}; \
}); \
}
void transformInPlace(std::span< std::byte > imageData, Func callback)
Run a parallelizable/vectorizable operation on the given image data.
Definition ImagePixel.h:548

◆ VTFPP_INVERT_GREEN_CASE

#define VTFPP_INVERT_GREEN_CASE ( PixelType)
Value:
#define VTFPP_INVERT_GREEN_CASE_OVERRIDE(PixelType, ChannelName, ChannelNameCaps,...)

◆ VTFPP_INVERT_GREEN_CASE_OVERRIDE

#define VTFPP_INVERT_GREEN_CASE_OVERRIDE ( PixelType,
ChannelName,
ChannelNameCaps,
... )
Value:
case PixelType: return ImagePixel::transformInPlace<ImagePixel::PixelType>(imageData, [](ImagePixel::PixelType pixel) -> ImagePixel::PixelType { \
static constexpr auto channelSize = ImageFormatDetails::green(ImagePixel::PixelType::FORMAT); \
if constexpr (std::same_as<decltype(pixel.ChannelName()), float> || std::same_as<decltype(pixel.ChannelName()), half>) { \
pixel.set##ChannelNameCaps(static_cast<decltype(pixel.ChannelName())>(static_cast<float>(static_cast<uint64_t>(1) << channelSize) - 1.f - static_cast<float>(pixel.ChannelName()))); \
} else { \
if constexpr (channelSize >= sizeof(uint32_t) * 8) { \
pixel.set##ChannelNameCaps(static_cast<decltype(pixel.ChannelName())>((static_cast<uint64_t>(1) << channelSize) - 1 - static_cast<uint32_t>(pixel.ChannelName()))); \
} else { \
pixel.set##ChannelNameCaps(static_cast<decltype(pixel.ChannelName())>(static_cast<uint32_t>(1 << channelSize) - 1 - static_cast<uint32_t>(pixel.ChannelName()))); \
} \
} \
return pixel; \
})

◆ VTFPP_REMAP_FROM_16

#define VTFPP_REMAP_FROM_16 ( value,
shift )
Value:
static_cast<uint8_t>(math::remap<uint16_t>((value), (1 << 16) - 1, (1 << (shift)) - 1))
constexpr T remap(T value, T l1, T h1, T l2, T h2)
Definition Math.h:37

◆ VTFPP_REMAP_FROM_8

#define VTFPP_REMAP_FROM_8 ( value,
shift )
Value:
math::remap<uint8_t>((value), (1 << 8) - 1, (1 << (shift)) - 1)

◆ VTFPP_REMAP_TO_16

#define VTFPP_REMAP_TO_16 ( value,
shift )
Value:
math::remap<uint16_t>((value), (1 << (shift)) - 1, (1 << 16) - 1)

◆ VTFPP_REMAP_TO_8

#define VTFPP_REMAP_TO_8 ( value,
shift )
Value:
math::remap<uint8_t>((value), (1 << (shift)) - 1, (1 << 8) - 1)

◆ VTFPP_TONEMAP_CASE

#define VTFPP_TONEMAP_CASE ( InputType,
... )
Value:
case InputType: \
return ImagePixel::transformInPlace<ImagePixel::InputType>(imageData, [](ImagePixel::InputType pixel) -> ImagePixel::InputType { \
return {__VA_ARGS__}; \
})