Property write small .hdr files (#750)
* Cleanup ImageEncoder code * Properly write HDR files when width < 8 or > 32767 A little oddity in the original Radiance file format encoding.
This commit is contained in:
@@ -39,6 +39,8 @@
|
||||
#include <math/vec3.h>
|
||||
#include <math/vec4.h>
|
||||
|
||||
#include <utils/compiler.h>
|
||||
|
||||
#include <image/ColorTransform.h>
|
||||
|
||||
using namespace math;
|
||||
@@ -55,17 +57,17 @@ public:
|
||||
|
||||
static PNGEncoder* create(std::ostream& stream, PixelFormat format = PixelFormat::sRGB);
|
||||
|
||||
PNGEncoder(const PNGEncoder&) = delete;
|
||||
PNGEncoder& operator=(const PNGEncoder&) = delete;
|
||||
|
||||
private:
|
||||
PNGEncoder(std::ostream& stream, PixelFormat format);
|
||||
PNGEncoder(const PNGEncoder&) = delete;
|
||||
~PNGEncoder();
|
||||
|
||||
PNGEncoder& operator = (const PNGEncoder&) = delete;
|
||||
~PNGEncoder() override;
|
||||
|
||||
void init();
|
||||
|
||||
// ImageEncoder::Encoder interface
|
||||
virtual bool encode(const LinearImage& image) override;
|
||||
bool encode(const LinearImage& image) override;
|
||||
|
||||
int chooseColorType(const LinearImage& image) const;
|
||||
uint32_t getChannelsCount() const;
|
||||
@@ -90,17 +92,17 @@ class HDREncoder : public ImageEncoder::Encoder {
|
||||
public:
|
||||
static HDREncoder* create(std::ostream& stream);
|
||||
|
||||
HDREncoder(const HDREncoder&) = delete;
|
||||
HDREncoder& operator=(const HDREncoder&) = delete;
|
||||
|
||||
private:
|
||||
explicit HDREncoder(std::ostream& stream);
|
||||
HDREncoder(const HDREncoder&) = delete;
|
||||
~HDREncoder();
|
||||
|
||||
HDREncoder& operator = (const HDREncoder&) = delete;
|
||||
~HDREncoder() override = default;
|
||||
|
||||
// ImageEncoder::Encoder interface
|
||||
virtual bool encode(const LinearImage& image) override;
|
||||
bool encode(const LinearImage& image) override;
|
||||
|
||||
static void float2rgbe(uint8_t rgbe[4], const math::float3& color);
|
||||
static void float2rgbe(uint8_t rgbe[4], const math::float3& in);
|
||||
static size_t countRepeats(uint8_t const* data, size_t length);
|
||||
static size_t countNonRepeats(uint8_t const* data, size_t length);
|
||||
static void rle(std::ostream& out, uint8_t const* data, size_t length);
|
||||
@@ -115,15 +117,15 @@ class PSDEncoder : public ImageEncoder::Encoder {
|
||||
public:
|
||||
static PSDEncoder* create(std::ostream& stream, const std::string& compression);
|
||||
|
||||
PSDEncoder(const PSDEncoder&) = delete;
|
||||
PSDEncoder& operator=(const PSDEncoder&) = delete;
|
||||
|
||||
private:
|
||||
PSDEncoder(std::ostream& stream, const std::string& compression);
|
||||
PSDEncoder(const PSDEncoder&) = delete;
|
||||
~PSDEncoder();
|
||||
|
||||
PSDEncoder& operator = (const PSDEncoder&) = delete;
|
||||
~PSDEncoder() override = default;
|
||||
|
||||
// ImageEncoder::Encoder interface
|
||||
virtual bool encode(const LinearImage& image) override;
|
||||
bool encode(const LinearImage& image) override;
|
||||
|
||||
std::ostream& mStream;
|
||||
std::streampos mStreamStartPos;
|
||||
@@ -139,15 +141,15 @@ public:
|
||||
static EXREncoder* create(std::ostream& stream, const std::string& compression,
|
||||
const std::string& destName);
|
||||
|
||||
EXREncoder(const EXREncoder&) = delete;
|
||||
EXREncoder& operator=(const EXREncoder&) = delete;
|
||||
|
||||
private:
|
||||
EXREncoder(std::ostream& stream, const std::string& compression, const std::string& destName);
|
||||
EXREncoder(const EXREncoder&) = delete;
|
||||
~EXREncoder();
|
||||
|
||||
EXREncoder& operator = (const EXREncoder&) = delete;
|
||||
~EXREncoder() override = default;
|
||||
|
||||
// ImageEncoder::Encoder interface
|
||||
virtual bool encode(const LinearImage& image) override;
|
||||
bool encode(const LinearImage& image) override;
|
||||
|
||||
std::ostream& mStream;
|
||||
std::streampos mStreamStartPos;
|
||||
@@ -167,15 +169,15 @@ public:
|
||||
static DDSEncoder* create(std::ostream& stream, const std::string& compression,
|
||||
PixelFormat format = PixelFormat::sRGB);
|
||||
|
||||
DDSEncoder(const DDSEncoder&) = delete;
|
||||
DDSEncoder& operator=(const DDSEncoder&) = delete;
|
||||
|
||||
private:
|
||||
DDSEncoder(std::ostream& stream, const std::string& compression, PixelFormat format);
|
||||
DDSEncoder(const DDSEncoder&) = delete;
|
||||
~DDSEncoder();
|
||||
|
||||
DDSEncoder& operator = (const DDSEncoder&) = delete;
|
||||
~DDSEncoder() override = default;
|
||||
|
||||
// ImageEncoder::Encoder interface
|
||||
virtual bool encode(const LinearImage& image) override;
|
||||
bool encode(const LinearImage& image) override;
|
||||
|
||||
std::ostream& mStream;
|
||||
std::streampos mStreamStartPos;
|
||||
@@ -219,7 +221,7 @@ bool ImageEncoder::encode(std::ostream& stream, Format format, const LinearImage
|
||||
|
||||
ImageEncoder::Format ImageEncoder::chooseFormat(const std::string& name, bool forceLinear) {
|
||||
std::string ext;
|
||||
size_t index = name.rfind(".");
|
||||
size_t index = name.rfind('.');
|
||||
if (index != std::string::npos && index != 0) {
|
||||
ext = name.substr(index + 1);
|
||||
}
|
||||
@@ -270,8 +272,8 @@ PNGEncoder* PNGEncoder::create(std::ostream& stream, PixelFormat format) {
|
||||
}
|
||||
|
||||
PNGEncoder::PNGEncoder(std::ostream& stream, PixelFormat format)
|
||||
: mStream(stream), mStreamStartPos(stream.tellp()), mFormat(format) {
|
||||
mPNG = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
||||
: mStream(stream), mStreamStartPos(stream.tellp()), mFormat(format),
|
||||
mPNG(png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr)) {
|
||||
}
|
||||
|
||||
PNGEncoder::~PNGEncoder() {
|
||||
@@ -279,8 +281,8 @@ PNGEncoder::~PNGEncoder() {
|
||||
}
|
||||
|
||||
void PNGEncoder::init() {
|
||||
png_set_error_fn(mPNG, this, cb_error, NULL);
|
||||
png_set_write_fn(mPNG, this, cb_stream, NULL);
|
||||
png_set_error_fn(mPNG, this, cb_error, nullptr);
|
||||
png_set_write_fn(mPNG, this, cb_stream, nullptr);
|
||||
}
|
||||
|
||||
int PNGEncoder::chooseColorType(const LinearImage& image) const {
|
||||
@@ -404,9 +406,6 @@ HDREncoder::HDREncoder(std::ostream& stream)
|
||||
: mStream(stream), mStreamStartPos(stream.tellp()) {
|
||||
}
|
||||
|
||||
HDREncoder::~HDREncoder() {
|
||||
}
|
||||
|
||||
void HDREncoder::float2rgbe(uint8_t rgbe[4], const float3& in) {
|
||||
int e;
|
||||
|
||||
@@ -417,11 +416,10 @@ void HDREncoder::float2rgbe(uint8_t rgbe[4], const float3& in) {
|
||||
if (color.b < 0) color.b = 0;
|
||||
|
||||
float v = std::max(color.r, std::max(color.g, color.b));
|
||||
float m = std::frexp(v, &e); // m*2^e = v
|
||||
if (e < -128) {
|
||||
if (v < 1e-32f) {
|
||||
rgbe[0] = rgbe[1] = rgbe[2] = rgbe[3] = 0;
|
||||
} else {
|
||||
v = (m * 256) / v;
|
||||
v = std::frexp(v, &e) * 256 / v; // m*2^e = v
|
||||
rgbe[0] = uint8_t(color.r * v);
|
||||
rgbe[1] = uint8_t(color.g * v);
|
||||
rgbe[2] = uint8_t(color.b * v);
|
||||
@@ -450,9 +448,10 @@ size_t HDREncoder::countNonRepeats(uint8_t const* data, size_t length) {
|
||||
if (same >= 3) {
|
||||
// non-repeats are always at least 3 bytes long
|
||||
return i;
|
||||
} else {
|
||||
same = 1;
|
||||
}
|
||||
} else {
|
||||
same = 1;
|
||||
v = data[i];
|
||||
}
|
||||
}
|
||||
return length;
|
||||
@@ -494,33 +493,47 @@ bool HDREncoder::encode(const LinearImage& image) {
|
||||
mStream << "-Y " << std::to_string(height) << " "
|
||||
<< "+X " << std::to_string(width) << std::endl;
|
||||
|
||||
std::unique_ptr<uint8_t[]> rgbe(new uint8_t[width*4]);
|
||||
uint8_t* const r = &rgbe[0];
|
||||
uint8_t* const g = &rgbe[width];
|
||||
uint8_t* const b = &rgbe[2*width];
|
||||
uint8_t* const e = &rgbe[3*width];
|
||||
uint16_t magic = 0x0202;
|
||||
uint16_t widthNetwork = htons(width);
|
||||
|
||||
for (size_t y=0 ; y<height ; y++) {
|
||||
// convert one scanline to RGBE
|
||||
uint8_t p[4];
|
||||
auto data = image.get<float3>(0, y);
|
||||
for (size_t x=0 ; x<width ; ++x, ++data) {
|
||||
float2rgbe(p, *data);
|
||||
r[x] = p[0];
|
||||
g[x] = p[1];
|
||||
b[x] = p[2];
|
||||
e[x] = p[3];
|
||||
// The Radiance format is not expected to use RLE encoding when
|
||||
// scanlines are less than 8 pixels or more than 32,767 pixels
|
||||
if (width < 8 || width > 32767) {
|
||||
for (uint32_t y = 0; y < height; y++) {
|
||||
uint8_t p[4];
|
||||
auto data = image.get<float3>(0, y);
|
||||
for (size_t x = 0; x < width; ++x, ++data) {
|
||||
float2rgbe(p, *data);
|
||||
mStream.write((char*) &p, 4);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
std::unique_ptr<uint8_t[]> rgbe(new uint8_t[width*4]);
|
||||
uint8_t* const r = &rgbe[0];
|
||||
uint8_t* const g = &rgbe[width];
|
||||
uint8_t* const b = &rgbe[2*width];
|
||||
uint8_t* const e = &rgbe[3*width];
|
||||
uint16_t magic = 0x0202;
|
||||
uint16_t widthNetwork = htons(width);
|
||||
|
||||
for (uint32_t y = 0; y < height; y++) {
|
||||
// convert one scanline to RGBE
|
||||
uint8_t p[4];
|
||||
auto data = image.get<float3>(0, y);
|
||||
for (size_t x = 0; x < width; ++x, ++data) {
|
||||
float2rgbe(p, *data);
|
||||
r[x] = p[0];
|
||||
g[x] = p[1];
|
||||
b[x] = p[2];
|
||||
e[x] = p[3];
|
||||
}
|
||||
// now RLE-compress each plane
|
||||
mStream.write((char*) &magic, 2);
|
||||
mStream.write((char*) &widthNetwork, 2);
|
||||
rle(mStream, r, width);
|
||||
rle(mStream, g, width);
|
||||
rle(mStream, b, width);
|
||||
rle(mStream, e, width);
|
||||
}
|
||||
// now RLE-compress each plane
|
||||
mStream.write((char*)&magic, 2);
|
||||
mStream.write((char*)&widthNetwork, 2);
|
||||
rle(mStream, r, width);
|
||||
rle(mStream, g, width);
|
||||
rle(mStream, b, width);
|
||||
rle(mStream, e, width);
|
||||
}
|
||||
|
||||
mStream.flush();
|
||||
} catch(std::runtime_error& e) {
|
||||
// reset the stream, like we found it
|
||||
@@ -544,9 +557,6 @@ PSDEncoder::PSDEncoder(std::ostream& stream, const std::string& compression)
|
||||
: mStream(stream), mStreamStartPos(stream.tellp()), mCompression(compression) {
|
||||
}
|
||||
|
||||
PSDEncoder::~PSDEncoder() {
|
||||
}
|
||||
|
||||
static inline void write32(std::ostream& stream, float f) {
|
||||
uint32_t data = htonl(*reinterpret_cast<uint32_t*>(&f));
|
||||
stream.write(reinterpret_cast<char*>(&data), sizeof(uint32_t));
|
||||
@@ -663,7 +673,7 @@ bool PSDEncoder::encode(const LinearImage& image) {
|
||||
|
||||
if (depth == 32) {
|
||||
for (size_t channel = 0; channel < 3; channel++) {
|
||||
for (size_t y = 0; y < height; y++) {
|
||||
for (uint32_t y = 0; y < height; y++) {
|
||||
auto data = image.get<float3>(0, y);
|
||||
for (size_t x = 0; x < width; x++) {
|
||||
write32(mStream, (*data)[channel]);
|
||||
@@ -673,7 +683,7 @@ bool PSDEncoder::encode(const LinearImage& image) {
|
||||
}
|
||||
} else {
|
||||
for (size_t channel = 0; channel < 3; channel++) {
|
||||
for (size_t y = 0; y < height; y++) {
|
||||
for (uint32_t y = 0; y < height; y++) {
|
||||
auto data = image.get<float3>(0, y);
|
||||
for (size_t x = 0; x < width; x++) {
|
||||
write16(mStream, linearTosRGB((*data)[channel]));
|
||||
@@ -707,9 +717,6 @@ EXREncoder::EXREncoder(std::ostream& stream, const std::string& compression,
|
||||
mCompression(compression), mDestName(destName) {
|
||||
}
|
||||
|
||||
EXREncoder::~EXREncoder() {
|
||||
}
|
||||
|
||||
static int toEXRCompression(const std::string& c) {
|
||||
if (c.empty()) {
|
||||
return TINYEXR_COMPRESSIONTYPE_PIZ;
|
||||
@@ -751,7 +758,7 @@ bool EXREncoder::encode(const LinearImage& image) {
|
||||
std::unique_ptr<float[]> b(new float[width * height]);
|
||||
|
||||
size_t i = 0;
|
||||
for (size_t y = 0; y < height; y++) {
|
||||
for (uint32_t y = 0; y < height; y++) {
|
||||
auto data = image.get<float3>(0, y);
|
||||
for (size_t x = 0; x < width; x++, data++) {
|
||||
r[i] = data->r;
|
||||
@@ -816,39 +823,39 @@ const uint32_t DDS_FOURCC_DX10 = 0x30315844; // "DX10"
|
||||
|
||||
#pragma pack(push, 1)
|
||||
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;
|
||||
uint32_t UTILS_UNUSED dwSize;
|
||||
uint32_t dwFlags;
|
||||
uint32_t UTILS_UNUSED dwFourCC;
|
||||
uint32_t UTILS_UNUSED dwRGBBitCount;
|
||||
uint32_t UTILS_UNUSED dwRBitMask;
|
||||
uint32_t UTILS_UNUSED dwGBitMask;
|
||||
uint32_t UTILS_UNUSED dwBBitMask;
|
||||
uint32_t UTILS_UNUSED dwABitMask;
|
||||
};
|
||||
|
||||
struct DDS_HEADER {
|
||||
uint32_t dwSize;
|
||||
uint32_t dwFlags;
|
||||
uint32_t dwHeight;
|
||||
uint32_t dwWidth;
|
||||
uint32_t dwPitchOrLinearSize;
|
||||
uint32_t dwDepth;
|
||||
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;
|
||||
uint32_t UTILS_UNUSED dwSize;
|
||||
uint32_t dwFlags;
|
||||
uint32_t UTILS_UNUSED dwHeight;
|
||||
uint32_t UTILS_UNUSED dwWidth;
|
||||
uint32_t UTILS_UNUSED dwPitchOrLinearSize;
|
||||
uint32_t UTILS_UNUSED dwDepth;
|
||||
uint32_t UTILS_UNUSED dwMipMapCount;
|
||||
uint32_t UTILS_UNUSED dwReserved1[11];
|
||||
DDS_PIXELFORMAT UTILS_UNUSED ddspf;
|
||||
uint32_t UTILS_UNUSED dwCaps;
|
||||
uint32_t UTILS_UNUSED dwCaps2;
|
||||
uint32_t UTILS_UNUSED dwCaps3;
|
||||
uint32_t UTILS_UNUSED dwCaps4;
|
||||
uint32_t UTILS_UNUSED dwReserved2;
|
||||
};
|
||||
|
||||
struct DDS_HEADER_DXT10 {
|
||||
uint32_t dxgiFormat;
|
||||
uint32_t resourceDimension;
|
||||
uint32_t miscFlag;
|
||||
uint32_t arraySize;
|
||||
uint32_t miscFlags2;
|
||||
uint32_t dxgiFormat;
|
||||
uint32_t UTILS_UNUSED resourceDimension;
|
||||
uint32_t UTILS_UNUSED miscFlag;
|
||||
uint32_t UTILS_UNUSED arraySize;
|
||||
uint32_t UTILS_UNUSED miscFlags2;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
@@ -888,9 +895,6 @@ DDSEncoder::DDSEncoder(std::ostream& stream, const std::string& compression, Pix
|
||||
}
|
||||
}
|
||||
|
||||
DDSEncoder::~DDSEncoder() {
|
||||
}
|
||||
|
||||
static uint32_t chooseBpp(const LinearImage& image, const std::string& compression) {
|
||||
size_t depth = 16;
|
||||
if (compression == "8") depth = 8;
|
||||
@@ -928,14 +932,12 @@ bool DDSEncoder::encode(const LinearImage& image) {
|
||||
size_t width = image.getWidth();
|
||||
size_t height = image.getHeight();
|
||||
|
||||
DDS_PIXELFORMAT ddspf;
|
||||
memset(&ddspf, 0, sizeof(ddspf));
|
||||
DDS_PIXELFORMAT ddspf = { };
|
||||
ddspf.dwSize = sizeof(ddspf);
|
||||
ddspf.dwFlags = DDPF_FOURCC;
|
||||
ddspf.dwFourCC = DDS_FOURCC_DX10;
|
||||
|
||||
DDS_HEADER header;
|
||||
memset(&header, 0, sizeof(header));
|
||||
DDS_HEADER header = { };
|
||||
header.dwSize = sizeof(header);
|
||||
header.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH |
|
||||
DDSD_PIXELFORMAT | DDSD_PITCH;
|
||||
@@ -947,8 +949,7 @@ bool DDSEncoder::encode(const LinearImage& image) {
|
||||
header.ddspf = ddspf;
|
||||
header.dwCaps = DDSCAPS_TEXTURE;
|
||||
|
||||
DDS_HEADER_DXT10 headerDX10;
|
||||
memset(&headerDX10, 0, sizeof(headerDX10));
|
||||
DDS_HEADER_DXT10 headerDX10 = { };
|
||||
headerDX10.dxgiFormat = chooseDXGIFormat(image, mCompression);
|
||||
headerDX10.resourceDimension = DDS_RESOURCE_DIMENSION_TEXTURE2D;
|
||||
headerDX10.arraySize = 1;
|
||||
@@ -961,7 +962,7 @@ bool DDSEncoder::encode(const LinearImage& image) {
|
||||
case DXGI_FORMAT_R8_UINT: {
|
||||
switch (mFormat) {
|
||||
case PixelFormat::sRGB:
|
||||
for (size_t y = 0; y < height; y++) {
|
||||
for (uint32_t y = 0; y < height; y++) {
|
||||
const float* data = image.getPixelRef(0, y);
|
||||
for (size_t x = 0; x < width; x++) {
|
||||
uint8_t b = (uint8_t) (linearTosRGB(saturate(*data)) * 255);
|
||||
@@ -971,7 +972,7 @@ bool DDSEncoder::encode(const LinearImage& image) {
|
||||
}
|
||||
break;
|
||||
case PixelFormat::LINEAR_RGB:
|
||||
for (size_t y = 0; y < height; y++) {
|
||||
for (uint32_t y = 0; y < height; y++) {
|
||||
const float* data = image.getPixelRef(0, y);
|
||||
for (size_t x = 0; x < width; x++) {
|
||||
uint8_t b = (uint8_t) (saturate(*data) * 255);
|
||||
@@ -984,7 +985,7 @@ bool DDSEncoder::encode(const LinearImage& image) {
|
||||
break;
|
||||
}
|
||||
case DXGI_FORMAT_R16_FLOAT: {
|
||||
for (size_t y = 0; y < height; y++) {
|
||||
for (uint32_t y = 0; y < height; y++) {
|
||||
const float* data = image.getPixelRef(0, y);
|
||||
for (size_t x = 0; x < width; x++) {
|
||||
math::half p = math::half(*data);
|
||||
@@ -995,7 +996,7 @@ bool DDSEncoder::encode(const LinearImage& image) {
|
||||
break;
|
||||
}
|
||||
case DXGI_FORMAT_R32_FLOAT: {
|
||||
for (size_t y = 0; y < height; y++) {
|
||||
for (uint32_t y = 0; y < height; y++) {
|
||||
const float* data = image.getPixelRef(0, y);
|
||||
mStream.write((const char*) data, width * sizeof(float));
|
||||
}
|
||||
@@ -1004,7 +1005,7 @@ bool DDSEncoder::encode(const LinearImage& image) {
|
||||
case DXGI_FORMAT_R8G8_UINT: {
|
||||
switch (mFormat) {
|
||||
case PixelFormat::sRGB:
|
||||
for (size_t y = 0; y < height; y++) {
|
||||
for (uint32_t y = 0; y < height; y++) {
|
||||
const float2* data = reinterpret_cast<float2 const*>(image.getPixelRef(0, y));
|
||||
for (size_t x = 0; x < width; x++) {
|
||||
uint8_t b;
|
||||
@@ -1017,7 +1018,7 @@ bool DDSEncoder::encode(const LinearImage& image) {
|
||||
}
|
||||
break;
|
||||
case PixelFormat::LINEAR_RGB:
|
||||
for (size_t y = 0; y < height; y++) {
|
||||
for (uint32_t y = 0; y < height; y++) {
|
||||
const float2* data = reinterpret_cast<float2 const*>(image.getPixelRef(0, y));
|
||||
for (size_t x = 0; x < width; x++) {
|
||||
uint8_t b;
|
||||
@@ -1033,7 +1034,7 @@ bool DDSEncoder::encode(const LinearImage& image) {
|
||||
break;
|
||||
}
|
||||
case DXGI_FORMAT_R16G16_FLOAT: {
|
||||
for (size_t y = 0; y < height; y++) {
|
||||
for (uint32_t y = 0; y < height; y++) {
|
||||
const float2* data = reinterpret_cast<float2 const*>(image.getPixelRef(0, y));
|
||||
for (size_t x = 0; x < width; x++) {
|
||||
half2 p = half2(*data);
|
||||
@@ -1044,7 +1045,7 @@ bool DDSEncoder::encode(const LinearImage& image) {
|
||||
break;
|
||||
}
|
||||
case DXGI_FORMAT_R32G32_FLOAT: {
|
||||
for (size_t y = 0; y < height; y++) {
|
||||
for (uint32_t y = 0; y < height; y++) {
|
||||
const float2* data = reinterpret_cast<float2 const*>(image.getPixelRef(0, y));
|
||||
mStream.write((const char*) data, width * sizeof(float2));
|
||||
}
|
||||
@@ -1053,7 +1054,7 @@ bool DDSEncoder::encode(const LinearImage& image) {
|
||||
case DXGI_FORMAT_R8G8B8A8_UINT: {
|
||||
switch (mFormat) {
|
||||
case PixelFormat::sRGB:
|
||||
for (size_t y = 0; y < height; y++) {
|
||||
for (uint32_t y = 0; y < height; y++) {
|
||||
auto data = image.get<float3>(0, y);
|
||||
for (size_t x = 0; x < width; x++) {
|
||||
uint8_t r = (uint8_t) (linearTosRGB(saturate(data->r)) * 255);
|
||||
@@ -1067,7 +1068,7 @@ bool DDSEncoder::encode(const LinearImage& image) {
|
||||
|
||||
break;
|
||||
case PixelFormat::LINEAR_RGB:
|
||||
for (size_t y = 0; y < height; y++) {
|
||||
for (uint32_t y = 0; y < height; y++) {
|
||||
auto data = image.get<float3>(0, y);
|
||||
for (size_t x = 0; x < width; x++) {
|
||||
uint8_t r = (uint8_t) (saturate(data->r) * 255);
|
||||
@@ -1083,7 +1084,7 @@ bool DDSEncoder::encode(const LinearImage& image) {
|
||||
break;
|
||||
}
|
||||
case DXGI_FORMAT_R16G16B16A16_FLOAT: {
|
||||
for (size_t y = 0; y < height; y++) {
|
||||
for (uint32_t y = 0; y < height; y++) {
|
||||
auto data = image.get<float3>(0, y);
|
||||
for (size_t x = 0; x < width; x++) {
|
||||
half4 p = half4(half3(*data), 1);
|
||||
@@ -1094,7 +1095,7 @@ bool DDSEncoder::encode(const LinearImage& image) {
|
||||
break;
|
||||
}
|
||||
case DXGI_FORMAT_R32G32B32A32_FLOAT: {
|
||||
for (size_t y = 0; y < height; y++) {
|
||||
for (uint32_t y = 0; y < height; y++) {
|
||||
auto data = image.get<float3>(0, y);
|
||||
for (size_t x = 0; x < width; x++) {
|
||||
float4 p = float4(3.0f, 3.0f, 3.0f, 1.0f);
|
||||
|
||||
Reference in New Issue
Block a user