#include #include #include #ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Weverything" #endif #define STB_IMAGE_RESIZE_IMPLEMENTATION #include "stb_image_resize.h" #define STB_IMAGE_WRITE_IMPLEMENTATION #include "stb_image_write.h" #ifdef __clang__ #pragma clang diagnostic pop #endif #include "tinyexr.h" inline unsigned char ftouc(float f, float gamma) { int i = static_cast(255.0f * powf(f, 1.0f / gamma)); if (i > 255) i = 255; if (i < 0) i = 0; return static_cast(i); } bool SaveImage(const char* filename, const float* rgba, float scale, float gamma, int width, int height, bool ignore_alpha) { std::vector dst(width * height * 4); // alpha channel is also affected by `scale` parameter. if(ignore_alpha) { for (size_t i = 0; i < width * height; i++) { dst[i * 4 + 0] = ftouc(rgba[i * 4 + 0] * scale, gamma); dst[i * 4 + 1] = ftouc(rgba[i * 4 + 1] * scale, gamma); dst[i * 4 + 2] = ftouc(rgba[i * 4 + 2] * scale, gamma); dst[i * 4 + 3] = 255; } } else { for (size_t i = 0; i < width * height * 4; i++) { dst[i] = ftouc(rgba[i] * scale, gamma); } } int ret = stbi_write_png(filename, width, height, 4, static_cast(dst.data()), width * 4); return (ret > 0); } int main(int argc, char** argv) { if (argc < 3) { printf("Usage: exr2ldr input.exr output.png (scale) (resize_factor) (gammavalue) (-i or --ignore-alpha).\n"); printf(" Pixel value [0.0, 1.0] in EXR is mapped to [0, 255] for LDR image.\n"); printf(" You can adjust pixel value by `scale`(default = 1.0).\n"); printf(" Resize image using `resize_factor`(default = 1.0). 2 = create half size image, 4 = 1/4 image, and so on\n"); printf(" gammmavalue will be used for gamma correction when saving png image(default = 2.2).\n"); printf(" Ignore alpha value of input using -i or --ignore-alpha flag, and alpha of output is set to 255.\n"); exit(-1); } float scale = 1.0f; if (argc > 3) { scale = atof(argv[3]); } float resize_factor = 1.0f; if (argc > 4) { resize_factor = atof(argv[4]); } float gamma = 2.2f; if (argc > 5) { gamma = atof(argv[5]); } bool ignore_alpha = false; if (argc > 6 && (strcmp(argv[6], "-i") == 0 || strcmp(argv[6], "--ignore-alpha") == 0)) { ignore_alpha = true; } int width, height; float* rgba; const char* err; { int ret = LoadEXR(&rgba, &width, &height, argv[1], &err); if (ret != 0) { printf("err: %s\n", err); return -1; } } int dst_width = width / resize_factor; int dst_height = height / resize_factor; printf("dst = %d, %d\n", dst_width, dst_height); std::vector buf(dst_width * dst_height * 4); int ret = stbir_resize_float(rgba, width, height, width*4*sizeof(float), &buf.at(0), dst_width, dst_height,dst_width*4*sizeof(float), 4); assert(ret != 0); bool ok = SaveImage(argv[2], &buf.at(0), scale, gamma, dst_width, dst_height, ignore_alpha); free(rgba); return (ok ? 0 : -1); }