| 31 | } |
| 32 | |
| 33 | static bool writeTiffHeader(FILE *file, int width, int height, int channels) { |
| 34 | #ifdef __BIG_ENDIAN__ |
| 35 | writeValue<uint16_t>(file, 0x4d4du); |
| 36 | #else |
| 37 | writeValue<uint16_t>(file, 0x4949u); |
| 38 | #endif |
| 39 | writeValue<uint16_t>(file, 42); |
| 40 | writeValue<uint32_t>(file, 0x0008u); // Offset of first IFD |
| 41 | // Offset = 0x0008 |
| 42 | |
| 43 | writeValue<uint16_t>(file, 15); // Number of IFD entries |
| 44 | |
| 45 | // ImageWidth |
| 46 | writeValue<uint16_t>(file, 0x0100u); |
| 47 | writeValue<uint16_t>(file, 0x0004u); |
| 48 | writeValue<uint32_t>(file, 1); |
| 49 | writeValue<int32_t>(file, width); |
| 50 | // ImageLength |
| 51 | writeValue<uint16_t>(file, 0x0101u); |
| 52 | writeValue<uint16_t>(file, 0x0004u); |
| 53 | writeValue<uint32_t>(file, 1); |
| 54 | writeValue<int32_t>(file, height); |
| 55 | // BitsPerSample |
| 56 | writeValue<uint16_t>(file, 0x0102u); |
| 57 | writeValue<uint16_t>(file, 0x0003u); |
| 58 | writeValue<uint32_t>(file, channels); |
| 59 | if (channels > 1) |
| 60 | writeValue<uint32_t>(file, 0x00c2u); // Offset of 32, 32, ... |
| 61 | else { |
| 62 | writeValue<uint16_t>(file, 32); |
| 63 | writeValue<uint16_t>(file, 0); |
| 64 | } |
| 65 | // Compression |
| 66 | writeValue<uint16_t>(file, 0x0103u); |
| 67 | writeValue<uint16_t>(file, 0x0003u); |
| 68 | writeValue<uint32_t>(file, 1); |
| 69 | writeValue<uint16_t>(file, 1); |
| 70 | writeValue<uint16_t>(file, 0); |
| 71 | // PhotometricInterpretation |
| 72 | writeValue<uint16_t>(file, 0x0106u); |
| 73 | writeValue<uint16_t>(file, 0x0003u); |
| 74 | writeValue<uint32_t>(file, 1); |
| 75 | writeValue<uint16_t>(file, channels >= 3 ? 2 : 1); |
| 76 | writeValue<uint16_t>(file, 0); |
| 77 | // StripOffsets |
| 78 | writeValue<uint16_t>(file, 0x0111u); |
| 79 | writeValue<uint16_t>(file, 0x0004u); |
| 80 | writeValue<uint32_t>(file, 1); |
| 81 | writeValue<uint32_t>(file, 0x00d2u+(channels > 1)*channels*12); // Offset of pixel data |
| 82 | // SamplesPerPixel |
| 83 | writeValue<uint16_t>(file, 0x0115u); |
| 84 | writeValue<uint16_t>(file, 0x0003u); |
| 85 | writeValue<uint32_t>(file, 1); |
| 86 | writeValue<uint16_t>(file, channels); |
| 87 | writeValue<uint16_t>(file, 0); |
| 88 | // RowsPerStrip |
| 89 | writeValue<uint16_t>(file, 0x0116u); |
| 90 | writeValue<uint16_t>(file, 0x0004u); |