🛠️🐜 Antkeeper superbuild with dependencies included https://antkeeper.com
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

85 lines
2.5 KiB

  1. #include <cstdio>
  2. #include <cstdlib>
  3. #include <vector>
  4. #define STB_IMAGE_IMPLEMENTATION
  5. #include "stb_image.h"
  6. #include "tinyexr.h"
  7. int main(int argc, char** argv)
  8. {
  9. if (argc < 3) {
  10. printf("Usage: ldr2exr input.[png|bmp|tga|jpg|...] output.exr\n");
  11. printf(" NOTE: Supported LDR image format = stb_image can load.\n");
  12. printf(" NOTE: Input pixel value [0, 255] is mapped to [0.0, 1.0] in output EXR file.\n");
  13. printf(" NOTE: Only supports RGB pixel format.\n");
  14. exit(-1);
  15. }
  16. int width, height;
  17. int n;
  18. unsigned char *rgb = stbi_load(argv[1], &width, &height, &n, 0);
  19. if (!rgb || n != 3) {
  20. return -1;
  21. }
  22. EXRHeader header;
  23. InitEXRHeader(&header);
  24. EXRImage image;
  25. InitEXRImage(&image);
  26. image.num_channels = 3;
  27. std::vector<float> images[3];
  28. images[0].resize(width * height);
  29. images[1].resize(width * height);
  30. images[2].resize(width * height);
  31. for (int i = 0; i < width * height; i++) {
  32. images[0][i] = rgb[3*i+0] / 255.0f;
  33. images[1][i] = rgb[3*i+1] / 255.0f;
  34. images[2][i] = rgb[3*i+2] / 255.0f;
  35. }
  36. float* image_ptr[3];
  37. image_ptr[0] = &(images[2].at(0)); // B
  38. image_ptr[1] = &(images[1].at(0)); // G
  39. image_ptr[2] = &(images[0].at(0)); // R
  40. image.images = (unsigned char**)image_ptr;
  41. image.width = width;
  42. image.height = height;
  43. header.num_channels = 3;
  44. header.channels = (EXRChannelInfo *)malloc(sizeof(EXRChannelInfo) * header.num_channels);
  45. // Must be BGR(A) order, since most of EXR viewers expect this channel order.
  46. strncpy(header.channels[0].name, "B", 255); header.channels[0].name[strlen("B")] = '\0';
  47. strncpy(header.channels[1].name, "G", 255); header.channels[1].name[strlen("G")] = '\0';
  48. strncpy(header.channels[2].name, "R", 255); header.channels[2].name[strlen("R")] = '\0';
  49. header.pixel_types = (int *)malloc(sizeof(int) * header.num_channels);
  50. header.requested_pixel_types = (int *)malloc(sizeof(int) * header.num_channels);
  51. for (int i = 0; i < header.num_channels; i++) {
  52. header.pixel_types[i] = TINYEXR_PIXELTYPE_FLOAT; // pixel type of input image
  53. header.requested_pixel_types[i] = TINYEXR_PIXELTYPE_HALF; // pixel type of output image to be stored in .EXR
  54. }
  55. const char* err;
  56. int ret = SaveEXRImageToFile(&image, &header, argv[2], &err);
  57. if (ret != TINYEXR_SUCCESS) {
  58. fprintf(stderr, "Save EXR err: %s\n", err);
  59. return ret;
  60. }
  61. printf("Saved exr file. [ %s ] \n", argv[2]);
  62. free(rgb);
  63. free(header.channels);
  64. free(header.pixel_types);
  65. free(header.requested_pixel_types);
  66. return 0;
  67. }