@@ -50,6 +50,9 @@ class SoftimageInput final : public ImageInput {
5050 std::vector<softimage_pvt::ChannelPacket> m_channel_packets;
5151 std::string m_filename;
5252 std::vector<fpos_t > m_scanline_markers;
53+ // Maps absolute channel index (0=R,1=G,2=B,3=A) to sequential output
54+ // offset within the scanline buffer. Initialized to -1 (unused).
55+ int m_channel_map[4 ];
5356};
5457
5558
@@ -76,6 +79,7 @@ SoftimageInput::init()
7679 m_filename.clear ();
7780 m_channel_packets.clear ();
7881 m_scanline_markers.clear ();
82+ std::fill (m_channel_map, m_channel_map + 4 , -1 );
7983}
8084
8185
@@ -110,7 +114,6 @@ SoftimageInput::open(const std::string& name, ImageSpec& spec)
110114
111115 // Get the ChannelPackets
112116 ChannelPacket curPacket;
113- int nchannels = 0 ;
114117 std::vector<std::string> encodings;
115118 do {
116119 // Read the next packet into curPacket and store it off
@@ -126,13 +129,31 @@ SoftimageInput::open(const std::string& name, ImageSpec& spec)
126129 close ();
127130 return false ;
128131 }
132+ if (curPacket.channelCode == 0 ) {
133+ errorfmt (" Channel packet with no channels" );
134+ close ();
135+ return false ;
136+ }
129137 m_channel_packets.push_back (curPacket);
130138
131- // Add the number of channels in this packet to nchannels
132- nchannels += curPacket.channels ().size ();
133139 encodings.push_back (encoding_name (m_channel_packets.back ().type ));
140+
141+ if (m_channel_packets.size () > 4 ) {
142+ errorfmt (" Too many channel packets" );
143+ close ();
144+ return false ;
145+ }
134146 } while (curPacket.chained );
135147
148+ // Build channel map: absolute RGBA index -> sequential output offset
149+ int nchannels = 0 ;
150+ {
151+ for (auto & cp : m_channel_packets)
152+ for (int ch : cp.channels ())
153+ if (m_channel_map[ch] == -1 )
154+ m_channel_map[ch] = nchannels++;
155+ }
156+
136157 // Get the depth per pixel per channel
137158 TypeDesc chanType = TypeDesc::UINT8;
138159 if (curPacket.size == 16 )
@@ -307,7 +328,8 @@ SoftimageInput::read_pixels_uncompressed(
307328 // read the data into the correct place
308329 if (fread (&scanlineData[(pixelX * pixelChannelSize
309330 * m_spec.nchannels )
310- + (channel * pixelChannelSize)
331+ + (m_channel_map[channel]
332+ * pixelChannelSize)
311333 + curByte],
312334 1 , 1 , m_fd)
313335 != 1 )
@@ -370,7 +392,8 @@ SoftimageInput::read_pixels_pure_run_length(
370392 // put the data into the correct place
371393 scanlineData[(pixelX * pixelChannelSize
372394 * m_spec.nchannels )
373- + (channels[curChan] * pixelChannelSize)
395+ + (m_channel_map[channels[curChan]]
396+ * pixelChannelSize)
374397 + curByte]
375398 = pixelData[(curChan * pixelChannelSize) + curByte];
376399 }
@@ -432,12 +455,12 @@ SoftimageInput::read_pixels_mixed_run_length(
432455 curByte = ((pixelChannelSize)-1 ) - curByte;
433456
434457 // read the data into the correct place
435- if (fread (
436- &scanlineData[(pixelX * pixelChannelSize
437- * m_spec. nchannels )
438- + (channel * pixelChannelSize)
439- + curByte],
440- 1 , 1 , m_fd)
458+ if (fread (&scanlineData[(pixelX * pixelChannelSize
459+ * m_spec. nchannels )
460+ + (m_channel_map[channel]
461+ * pixelChannelSize)
462+ + curByte],
463+ 1 , 1 , m_fd)
441464 != 1 )
442465 return false ;
443466 }
@@ -500,7 +523,8 @@ SoftimageInput::read_pixels_mixed_run_length(
500523 // put the data into the correct place
501524 scanlineData[(pixelX * pixelChannelSize
502525 * m_spec.nchannels )
503- + (channels[curChan] * pixelChannelSize)
526+ + (m_channel_map[channels[curChan]]
527+ * pixelChannelSize)
504528 + curByte]
505529 = pixelData[(curChan * pixelChannelSize)
506530 + curByte];
0 commit comments