summaryrefslogtreecommitdiff
path: root/thirdparty/msdfgen/core/save-tiff.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'thirdparty/msdfgen/core/save-tiff.cpp')
-rw-r--r--thirdparty/msdfgen/core/save-tiff.cpp190
1 files changed, 190 insertions, 0 deletions
diff --git a/thirdparty/msdfgen/core/save-tiff.cpp b/thirdparty/msdfgen/core/save-tiff.cpp
new file mode 100644
index 0000000000..71405e00e5
--- /dev/null
+++ b/thirdparty/msdfgen/core/save-tiff.cpp
@@ -0,0 +1,190 @@
+
+#define _CRT_SECURE_NO_WARNINGS
+
+#include "save-tiff.h"
+
+#include <cstdio>
+
+#ifdef MSDFGEN_USE_CPP11
+ #include <cstdint>
+#else
+ typedef int int32_t;
+ typedef unsigned uint32_t;
+ typedef unsigned short uint16_t;
+ typedef unsigned char uint8_t;
+#endif
+
+namespace msdfgen {
+
+template <typename T>
+static bool writeValue(FILE *file, T value) {
+ return fwrite(&value, sizeof(T), 1, file) == 1;
+}
+template <typename T>
+static void writeValueRepeated(FILE *file, T value, int times) {
+ for (int i = 0; i < times; ++i)
+ writeValue(file, value);
+}
+
+static bool writeTiffHeader(FILE *file, int width, int height, int channels) {
+ #ifdef __BIG_ENDIAN__
+ writeValue<uint16_t>(file, 0x4d4du);
+ #else
+ writeValue<uint16_t>(file, 0x4949u);
+ #endif
+ writeValue<uint16_t>(file, 42);
+ writeValue<uint32_t>(file, 0x0008u); // Offset of first IFD
+ // Offset = 0x0008
+
+ writeValue<uint16_t>(file, 15); // Number of IFD entries
+
+ // ImageWidth
+ writeValue<uint16_t>(file, 0x0100u);
+ writeValue<uint16_t>(file, 0x0004u);
+ writeValue<uint32_t>(file, 1);
+ writeValue<int32_t>(file, width);
+ // ImageLength
+ writeValue<uint16_t>(file, 0x0101u);
+ writeValue<uint16_t>(file, 0x0004u);
+ writeValue<uint32_t>(file, 1);
+ writeValue<int32_t>(file, height);
+ // BitsPerSample
+ writeValue<uint16_t>(file, 0x0102u);
+ writeValue<uint16_t>(file, 0x0003u);
+ writeValue<uint32_t>(file, channels);
+ if (channels > 1)
+ writeValue<uint32_t>(file, 0x00c2u); // Offset of 32, 32, ...
+ else {
+ writeValue<uint16_t>(file, 32);
+ writeValue<uint16_t>(file, 0);
+ }
+ // Compression
+ writeValue<uint16_t>(file, 0x0103u);
+ writeValue<uint16_t>(file, 0x0003u);
+ writeValue<uint32_t>(file, 1);
+ writeValue<uint16_t>(file, 1);
+ writeValue<uint16_t>(file, 0);
+ // PhotometricInterpretation
+ writeValue<uint16_t>(file, 0x0106u);
+ writeValue<uint16_t>(file, 0x0003u);
+ writeValue<uint32_t>(file, 1);
+ writeValue<uint16_t>(file, channels >= 3 ? 2 : 1);
+ writeValue<uint16_t>(file, 0);
+ // StripOffsets
+ writeValue<uint16_t>(file, 0x0111u);
+ writeValue<uint16_t>(file, 0x0004u);
+ writeValue<uint32_t>(file, 1);
+ writeValue<uint32_t>(file, 0x00d2u+(channels > 1)*channels*12); // Offset of pixel data
+ // SamplesPerPixel
+ writeValue<uint16_t>(file, 0x0115u);
+ writeValue<uint16_t>(file, 0x0003u);
+ writeValue<uint32_t>(file, 1);
+ writeValue<uint16_t>(file, channels);
+ writeValue<uint16_t>(file, 0);
+ // RowsPerStrip
+ writeValue<uint16_t>(file, 0x0116u);
+ writeValue<uint16_t>(file, 0x0004u);
+ writeValue<uint32_t>(file, 1);
+ writeValue<int32_t>(file, height);
+ // StripByteCounts
+ writeValue<uint16_t>(file, 0x0117u);
+ writeValue<uint16_t>(file, 0x0004u);
+ writeValue<uint32_t>(file, 1);
+ writeValue<int32_t>(file, sizeof(float)*channels*width*height);
+ // XResolution
+ writeValue<uint16_t>(file, 0x011au);
+ writeValue<uint16_t>(file, 0x0005u);
+ writeValue<uint32_t>(file, 1);
+ writeValue<uint32_t>(file, 0x00c2u+(channels > 1)*channels*2); // Offset of 300, 1
+ // YResolution
+ writeValue<uint16_t>(file, 0x011bu);
+ writeValue<uint16_t>(file, 0x0005u);
+ writeValue<uint32_t>(file, 1);
+ writeValue<uint32_t>(file, 0x00cau+(channels > 1)*channels*2); // Offset of 300, 1
+ // ResolutionUnit
+ writeValue<uint16_t>(file, 0x0128u);
+ writeValue<uint16_t>(file, 0x0003u);
+ writeValue<uint32_t>(file, 1);
+ writeValue<uint16_t>(file, 2);
+ writeValue<uint16_t>(file, 0);
+ // SampleFormat
+ writeValue<uint16_t>(file, 0x0153u);
+ writeValue<uint16_t>(file, 0x0003u);
+ writeValue<uint32_t>(file, channels);
+ if (channels > 1)
+ writeValue<uint32_t>(file, 0x00d2u+channels*2); // Offset of 3, 3, ...
+ else {
+ writeValue<uint16_t>(file, 3);
+ writeValue<uint16_t>(file, 0);
+ }
+ // SMinSampleValue
+ writeValue<uint16_t>(file, 0x0154u);
+ writeValue<uint16_t>(file, 0x000bu);
+ writeValue<uint32_t>(file, channels);
+ if (channels > 1)
+ writeValue<uint32_t>(file, 0x00d2u+channels*4); // Offset of 0.f, 0.f, ...
+ else
+ writeValue<float>(file, 0.f);
+ // SMaxSampleValue
+ writeValue<uint16_t>(file, 0x0155u);
+ writeValue<uint16_t>(file, 0x000bu);
+ writeValue<uint32_t>(file, channels);
+ if (channels > 1)
+ writeValue<uint32_t>(file, 0x00d2u+channels*8); // Offset of 1.f, 1.f, ...
+ else
+ writeValue<float>(file, 1.f);
+ // Offset = 0x00be
+
+ writeValue<uint32_t>(file, 0);
+
+ if (channels > 1) {
+ // 0x00c2 BitsPerSample data
+ writeValueRepeated<uint16_t>(file, 32, channels);
+ // 0x00c2 + 2*N XResolution data
+ writeValue<uint32_t>(file, 300);
+ writeValue<uint32_t>(file, 1);
+ // 0x00ca + 2*N YResolution data
+ writeValue<uint32_t>(file, 300);
+ writeValue<uint32_t>(file, 1);
+ // 0x00d2 + 2*N SampleFormat data
+ writeValueRepeated<uint16_t>(file, 3, channels);
+ // 0x00d2 + 4*N SMinSampleValue data
+ writeValueRepeated<float>(file, 0.f, channels);
+ // 0x00d2 + 8*N SMaxSampleValue data
+ writeValueRepeated<float>(file, 1.f, channels);
+ // Offset = 0x00d2 + 12*N
+ } else {
+ // 0x00c2 XResolution data
+ writeValue<uint32_t>(file, 300);
+ writeValue<uint32_t>(file, 1);
+ // 0x00ca YResolution data
+ writeValue<uint32_t>(file, 300);
+ writeValue<uint32_t>(file, 1);
+ // Offset = 0x00d2
+ }
+
+ return true;
+}
+
+template <int N>
+bool saveTiffFloat(const BitmapConstRef<float, N> &bitmap, const char *filename) {
+ FILE *file = fopen(filename, "wb");
+ if (!file)
+ return false;
+ writeTiffHeader(file, bitmap.width, bitmap.height, N);
+ for (int y = bitmap.height-1; y >= 0; --y)
+ fwrite(bitmap(0, y), sizeof(float), N*bitmap.width, file);
+ return !fclose(file);
+}
+
+bool saveTiff(const BitmapConstRef<float, 1> &bitmap, const char *filename) {
+ return saveTiffFloat(bitmap, filename);
+}
+bool saveTiff(const BitmapConstRef<float, 3> &bitmap, const char *filename) {
+ return saveTiffFloat(bitmap, filename);
+}
+bool saveTiff(const BitmapConstRef<float, 4> &bitmap, const char *filename) {
+ return saveTiffFloat(bitmap, filename);
+}
+
+}