| 7539 | #endif |
| 7540 | |
| 7541 | int SaveMultiChannelEXR(const EXRImage *exrImage, const char *filename, |
| 7542 | const char **err) { |
| 7543 | if (exrImage == NULL || filename == NULL) { |
| 7544 | if (err) { |
| 7545 | (*err) = "Invalid argument."; |
| 7546 | } |
| 7547 | return -1; |
| 7548 | } |
| 7549 | |
| 7550 | FILE *fp = fopen(filename, "wb"); |
| 7551 | if (!fp) { |
| 7552 | if (err) { |
| 7553 | (*err) = "Cannot write a file."; |
| 7554 | } |
| 7555 | return -1; |
| 7556 | } |
| 7557 | |
| 7558 | // Header |
| 7559 | { |
| 7560 | const char header[] = {0x76, 0x2f, 0x31, 0x01}; |
| 7561 | size_t n = fwrite(header, 1, 4, fp); |
| 7562 | assert(n == 4); |
| 7563 | } |
| 7564 | |
| 7565 | // Version, scanline. |
| 7566 | { |
| 7567 | const char marker[] = {2, 0, 0, 0}; |
| 7568 | size_t n = fwrite(marker, 1, 4, fp); |
| 7569 | assert(n == 4); |
| 7570 | } |
| 7571 | |
| 7572 | int numScanlineBlocks = 16; // 16 for ZIP compression. |
| 7573 | |
| 7574 | // Write attributes. |
| 7575 | { |
| 7576 | std::vector<unsigned char> data; |
| 7577 | |
| 7578 | std::vector<ChannelInfo> channels; |
| 7579 | for (int c = 0; c < exrImage->num_channels; c++) { |
| 7580 | ChannelInfo info; |
| 7581 | info.pLinear = 0; |
| 7582 | info.pixelType = 1; // Assume HALF |
| 7583 | info.xSampling = 1; |
| 7584 | info.ySampling = 1; |
| 7585 | info.name = std::string(exrImage->channel_names[c]); |
| 7586 | channels.push_back(info); |
| 7587 | } |
| 7588 | |
| 7589 | WriteChannelInfo(data, channels); |
| 7590 | |
| 7591 | WriteAttribute(fp, "channels", "chlist", &data.at(0), |
| 7592 | data.size()); // +1 = null |
| 7593 | } |
| 7594 | |
| 7595 | { |
| 7596 | int compressionType = 3; // ZIP compression |
| 7597 | if (IsBigEndian()) { |
| 7598 | swap4(reinterpret_cast<unsigned int*>(&compressionType)); |
no test coverage detected