🛠️🐜 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.

81 lines
2.2 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: rgbe2exr input.hdr output.exr\n");
  11. exit(-1);
  12. }
  13. int width, height;
  14. int n;
  15. float *rgb = stbi_loadf(argv[1], &width, &height, &n, 0);
  16. if (!rgb || n != 3) {
  17. return -1;
  18. }
  19. EXRHeader header;
  20. InitEXRHeader(&header);
  21. EXRImage image;
  22. InitEXRImage(&image);
  23. image.num_channels = 3;
  24. std::vector<float> images[3];
  25. images[0].resize(width * height);
  26. images[1].resize(width * height);
  27. images[2].resize(width * height);
  28. for (int i = 0; i < width * height; i++) {
  29. images[0][i] = rgb[3*i+0];
  30. images[1][i] = rgb[3*i+1];
  31. images[2][i] = rgb[3*i+2];
  32. }
  33. float* image_ptr[3];
  34. image_ptr[0] = &(images[2].at(0)); // B
  35. image_ptr[1] = &(images[1].at(0)); // G
  36. image_ptr[2] = &(images[0].at(0)); // R
  37. image.images = (unsigned char**)image_ptr;
  38. image.width = width;
  39. image.height = height;
  40. header.num_channels = 3;
  41. header.channels = (EXRChannelInfo *)malloc(sizeof(EXRChannelInfo) * header.num_channels);
  42. // Must be BGR(A) order, since most of EXR viewers expect this channel order.
  43. strncpy(header.channels[0].name, "B", 255); header.channels[0].name[strlen("B")] = '\0';
  44. strncpy(header.channels[1].name, "G", 255); header.channels[1].name[strlen("G")] = '\0';
  45. strncpy(header.channels[2].name, "R", 255); header.channels[2].name[strlen("R")] = '\0';
  46. header.pixel_types = (int *)malloc(sizeof(int) * header.num_channels);
  47. header.requested_pixel_types = (int *)malloc(sizeof(int) * header.num_channels);
  48. for (int i = 0; i < header.num_channels; i++) {
  49. header.pixel_types[i] = TINYEXR_PIXELTYPE_FLOAT; // pixel type of input image
  50. header.requested_pixel_types[i] = TINYEXR_PIXELTYPE_HALF; // pixel type of output image to be stored in .EXR
  51. }
  52. const char* err;
  53. int ret = SaveEXRImageToFile(&image, &header, argv[2], &err);
  54. if (ret != TINYEXR_SUCCESS) {
  55. fprintf(stderr, "Save EXR err: %s\n", err);
  56. return ret;
  57. }
  58. printf("Saved exr file. [ %s ] \n", argv[2]);
  59. free(rgb);
  60. free(header.channels);
  61. free(header.pixel_types);
  62. free(header.requested_pixel_types);
  63. return 0;
  64. }