if (channels == 1) {
identifier = "Pf";
outChannels = 1;
- } else {
+ } else if (channels <= 3) {
identifier = "PF";
- outChannels = 3;
+ outChannels = 4;
+ } else {
+ // Non-standard extension for 4 floats
+ identifier = "PX";
+ outChannels = 4;
}
break;
default:
if (channelType == TYPE_UNORM8) {
os << "255" << "\n";
+ } else {
+ os << "1" << "\n";
}
const unsigned char *row;
* Need to add/remove channels, one pixel at a time.
*/
- unsigned char *tmp = new unsigned char[width*bytesPerPixel];
+ unsigned char *tmp = new unsigned char[width*outChannels*bytesPerChannel];
if (channelType == TYPE_UNORM8) {
/*
* General path for float images.
*/
+ unsigned copyChannels = std::min(channels, outChannels);
+
assert(channelType == TYPE_FLOAT);
for (row = start(); row != end(); row += stride()) {
float *dst = (float *)tmp;
for (unsigned x = 0; x < width; ++x) {
unsigned channel = 0;
- for (; channel < channels; ++channel) {
+ for (; channel < copyChannels; ++channel) {
*dst++ = *src++;
}
- for (; channel < channels; ++channel) {
+ for (; channel < outChannels; ++channel) {
*dst++ = 0;
}
}
- os.write((const char *)tmp, width*bytesPerPixel);
+ os.write((const char *)tmp, width*outChannels*bytesPerChannel);
}
}
info.channels = 3;
info.channelType = TYPE_FLOAT;
break;
+ case 'X':
+ info.channels = 4;
+ info.channelType = TYPE_FLOAT;
+ break;
default:
return NULL;
}
bufferSize -= nextBuffer - currentBuffer;
currentBuffer = nextBuffer;
- if (info.channelType == TYPE_UNORM8) {
- // skip over "255\n" at end of header
- nextBuffer = (const char *) memchr((const void *) currentBuffer, '\n', bufferSize) + 1;
- }
+ // skip scale factor / endianness line
+ nextBuffer = (const char *) memchr((const void *) currentBuffer, '\n', bufferSize) + 1;
// return start of image data
return nextBuffer;