|
|
- #include <cstdio>
- #include <cstdlib>
- #include <vector>
-
- #define STB_IMAGE_IMPLEMENTATION
- #include "stb_image.h"
-
- #include "tinyexr.h"
-
- int main(int argc, char** argv)
- {
- if (argc < 3) {
- printf("Usage: ldr2exr input.[png|bmp|tga|jpg|...] output.exr\n");
- printf(" NOTE: Supported LDR image format = stb_image can load.\n");
- printf(" NOTE: Input pixel value [0, 255] is mapped to [0.0, 1.0] in output EXR file.\n");
- printf(" NOTE: Only supports RGB pixel format.\n");
-
- exit(-1);
- }
-
- int width, height;
- int n;
- unsigned char *rgb = stbi_load(argv[1], &width, &height, &n, 0);
- if (!rgb || n != 3) {
- return -1;
- }
-
- EXRHeader header;
- InitEXRHeader(&header);
-
- EXRImage image;
- InitEXRImage(&image);
-
- image.num_channels = 3;
-
- std::vector<float> images[3];
- images[0].resize(width * height);
- images[1].resize(width * height);
- images[2].resize(width * height);
-
- for (int i = 0; i < width * height; i++) {
- images[0][i] = rgb[3*i+0] / 255.0f;
- images[1][i] = rgb[3*i+1] / 255.0f;
- images[2][i] = rgb[3*i+2] / 255.0f;
- }
-
- float* image_ptr[3];
- image_ptr[0] = &(images[2].at(0)); // B
- image_ptr[1] = &(images[1].at(0)); // G
- image_ptr[2] = &(images[0].at(0)); // R
-
- image.images = (unsigned char**)image_ptr;
- image.width = width;
- image.height = height;
-
- header.num_channels = 3;
- header.channels = (EXRChannelInfo *)malloc(sizeof(EXRChannelInfo) * header.num_channels);
- // Must be BGR(A) order, since most of EXR viewers expect this channel order.
- strncpy(header.channels[0].name, "B", 255); header.channels[0].name[strlen("B")] = '\0';
- strncpy(header.channels[1].name, "G", 255); header.channels[1].name[strlen("G")] = '\0';
- strncpy(header.channels[2].name, "R", 255); header.channels[2].name[strlen("R")] = '\0';
-
- header.pixel_types = (int *)malloc(sizeof(int) * header.num_channels);
- header.requested_pixel_types = (int *)malloc(sizeof(int) * header.num_channels);
- for (int i = 0; i < header.num_channels; i++) {
- header.pixel_types[i] = TINYEXR_PIXELTYPE_FLOAT; // pixel type of input image
- header.requested_pixel_types[i] = TINYEXR_PIXELTYPE_HALF; // pixel type of output image to be stored in .EXR
- }
-
- const char* err;
- int ret = SaveEXRImageToFile(&image, &header, argv[2], &err);
- if (ret != TINYEXR_SUCCESS) {
- fprintf(stderr, "Save EXR err: %s\n", err);
- return ret;
- }
- printf("Saved exr file. [ %s ] \n", argv[2]);
-
- free(rgb);
-
- free(header.channels);
- free(header.pixel_types);
- free(header.requested_pixel_types);
-
- return 0;
- }
|