| 7062 | } |
| 7063 | |
| 7064 | int LoadMultiChannelEXR(EXRImage *exrImage, const char *filename, |
| 7065 | const char **err) { |
| 7066 | if (exrImage == NULL) { |
| 7067 | if (err) { |
| 7068 | (*err) = "Invalid argument."; |
| 7069 | } |
| 7070 | return -1; |
| 7071 | } |
| 7072 | |
| 7073 | FILE *fp = fopen(filename, "rb"); |
| 7074 | if (!fp) { |
| 7075 | if (err) { |
| 7076 | (*err) = "Cannot read file."; |
| 7077 | } |
| 7078 | return -1; |
| 7079 | } |
| 7080 | |
| 7081 | size_t filesize; |
| 7082 | // Compute size |
| 7083 | fseek(fp, 0, SEEK_END); |
| 7084 | filesize = ftell(fp); |
| 7085 | fseek(fp, 0, SEEK_SET); |
| 7086 | |
| 7087 | std::vector<char> buf(filesize); // @todo { use mmap } |
| 7088 | { |
| 7089 | size_t ret; |
| 7090 | ret = fread(&buf[0], 1, filesize, fp); |
| 7091 | assert(ret == filesize); |
| 7092 | fclose(fp); |
| 7093 | } |
| 7094 | |
| 7095 | const char *head = &buf[0]; |
| 7096 | const char *marker = &buf[0]; |
| 7097 | |
| 7098 | // Header check. |
| 7099 | { |
| 7100 | const char header[] = {0x76, 0x2f, 0x31, 0x01}; |
| 7101 | |
| 7102 | if (memcmp(marker, header, 4) != 0) { |
| 7103 | if (err) { |
| 7104 | (*err) = "Header mismatch."; |
| 7105 | } |
| 7106 | return -3; |
| 7107 | } |
| 7108 | marker += 4; |
| 7109 | } |
| 7110 | |
| 7111 | // Version, scanline. |
| 7112 | { |
| 7113 | // must be [2, 0, 0, 0] |
| 7114 | if (marker[0] != 2 || marker[1] != 0 || marker[2] != 0 || marker[3] != 0) { |
| 7115 | if (err) { |
| 7116 | (*err) = "Unsupported version or scanline."; |
| 7117 | } |
| 7118 | return -4; |
| 7119 | } |
| 7120 | |
| 7121 | marker += 4; |
no test coverage detected