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

127 lines
3.5 KiB

  1. // https://gist.github.com/mmp/ba384e1f509e2e38d5df#file-exrcat-cpp
  2. #include "tinyexr/tinyexr.h"
  3. #include "tinyexr/tinyexr.cc"
  4. #include <stdio.h>
  5. #include <assert.h>
  6. #include <vector>
  7. #include <ImfInputFile.h>
  8. #include <ImfRgbaFile.h>
  9. #include <ImfChannelList.h>
  10. #include <ImfFrameBuffer.h>
  11. #include <half.h>
  12. using namespace Imf;
  13. using namespace Imath;
  14. #if 0
  15. void
  16. SaveAsPFM(const char* filename, int width, int height, float* data)
  17. {
  18. FILE* fp = fopen(filename, "wb");
  19. if (!fp) {
  20. fprintf(stderr, "failed to write a PFM file.\n");
  21. return;
  22. }
  23. fprintf(fp, "PF\n");
  24. fprintf(fp, "%d %d\n", width, height);
  25. fprintf(fp, "-1\n"); // -1: little endian, 1: big endian
  26. // RGBA -> RGB
  27. std::vector<float> rgb(width*height*3);
  28. for (size_t i = 0; i < width * height; i++) {
  29. rgb[3*i+0] = data[4*i+0];
  30. rgb[3*i+1] = data[4*i+1];
  31. rgb[3*i+2] = data[4*i+2];
  32. }
  33. fwrite(&rgb.at(0), sizeof(float), width * height * 3, fp);
  34. fclose(fp);
  35. }
  36. #endif
  37. static float *OpenExrLoad(const char *name, int *width, int *height) {
  38. try {
  39. RgbaInputFile file (name);
  40. Box2i dw = file.dataWindow();
  41. *width = dw.max.x - dw.min.x + 1;
  42. *height = dw.max.y - dw.min.y + 1;
  43. std::vector<Rgba> pixels(*width * *height);
  44. file.setFrameBuffer(&pixels[0] - dw.min.x - dw.min.y * *width, 1, *width);
  45. file.readPixels(dw.min.y, dw.max.y);
  46. printf("OpenExr\n datawindow: (%d %d) - (%d %d)\n", dw.min.x, dw.min.y,
  47. dw.max.x, dw.max.y);
  48. printf(" line order %s\n", (file.lineOrder() == INCREASING_Y) ?
  49. "increasing y" : ((file.lineOrder() == DECREASING_Y) ? "decreasing y"
  50. : "random y"));
  51. printf(" compression: ");
  52. switch (file.compression()) {
  53. case NO_COMPRESSION: printf("none"); break;
  54. case RLE_COMPRESSION: printf("RLE"); break;
  55. case ZIPS_COMPRESSION: printf("zip"); break;
  56. case ZIP_COMPRESSION: printf("zips"); break;
  57. case PIZ_COMPRESSION: printf("piz"); break;
  58. case PXR24_COMPRESSION: printf("pxr24"); break;
  59. case B44_COMPRESSION: printf("b44"); break;
  60. case B44A_COMPRESSION: printf("b44a"); break;
  61. default: printf("unknown!");
  62. }
  63. printf("\n");
  64. printf(" channels: ");
  65. RgbaChannels channels = file.channels();
  66. if (channels & WRITE_R) printf("R");
  67. if (channels & WRITE_G) printf("G");
  68. if (channels & WRITE_B) printf("B");
  69. if (channels & WRITE_A) printf("A");
  70. if (channels & WRITE_Y) printf("Y");
  71. if (channels & WRITE_C) printf("C");
  72. printf("\n");
  73. float *ret = new float[4 * *width * *height];
  74. for (int i = 0; i < *width * *height; ++i) {
  75. ret[4*i] = pixels[i].r;
  76. ret[4*i+1] = pixels[i].g;
  77. ret[4*i+2] = pixels[i].b;
  78. ret[4*i+3] = pixels[i].a;
  79. }
  80. return ret;
  81. } catch (const std::exception &e) {
  82. return NULL;
  83. }
  84. }
  85. int main(int argc, char *argv[]) {
  86. if (argc != 2) {
  87. fprintf(stderr, "usage: exrcat <file.exr>\n");
  88. return 1;
  89. }
  90. int ow, oh;
  91. float *orgb = OpenExrLoad(argv[1], &ow, &oh);
  92. //SaveAsPFM("out.pfm", ow, oh, orgb);
  93. int tw, th;
  94. float *trgb;
  95. const char *err;
  96. if (LoadEXR(&trgb, &tw, &th, argv[1], &err) != 0) {
  97. fprintf(stderr, "exrcat: %s %s\n", argv[1], err);
  98. return 1;
  99. }
  100. assert(ow == tw && oh == th);
  101. int o = 0;
  102. for (int y = 0; y < th; ++y) {
  103. for (int x = 0; x < tw; ++x, ++o) {
  104. printf("(%d, %d): %f %f %f %f - %f %f %f %f\n", x, y,
  105. orgb[4*o], orgb[4*o+1], orgb[4*o+2], orgb[4*o+3],
  106. trgb[4*o], trgb[4*o+1], trgb[4*o+2], trgb[4*o+3]);
  107. }
  108. }
  109. return 0;
  110. }