@@ -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 )
@@ -314,7 +335,8 @@ SoftimageInput::read_pixels_uncompressed(
314335 // read the data into the correct place
315336 if (fread (&scanlineData[(pixelX * pixelChannelSize
316337 * m_spec.nchannels )
317- + (channel * pixelChannelSize)
338+ + (m_channel_map[channel]
339+ * pixelChannelSize)
318340 + curByte],
319341 1 , 1 , m_fd)
320342 != 1 )
@@ -383,7 +405,8 @@ SoftimageInput::read_pixels_pure_run_length(
383405 // put the data into the correct place
384406 scanlineData[(pixelX * pixelChannelSize
385407 * m_spec.nchannels )
386- + (channels[curChan] * pixelChannelSize)
408+ + (m_channel_map[channels[curChan]]
409+ * pixelChannelSize)
387410 + curByte]
388411 = pixelData[(curChan * pixelChannelSize) + curByte];
389412 }
@@ -445,12 +468,12 @@ SoftimageInput::read_pixels_mixed_run_length(
445468 curByte = ((pixelChannelSize)-1 ) - curByte;
446469
447470 // read the data into the correct place
448- if (fread (
449- &scanlineData[(pixelX * pixelChannelSize
450- * m_spec. nchannels )
451- + (channel * pixelChannelSize)
452- + curByte],
453- 1 , 1 , m_fd)
471+ if (fread (&scanlineData[(pixelX * pixelChannelSize
472+ * m_spec. nchannels )
473+ + (m_channel_map[channel]
474+ * pixelChannelSize)
475+ + curByte],
476+ 1 , 1 , m_fd)
454477 != 1 )
455478 return false ;
456479 }
@@ -519,7 +542,8 @@ SoftimageInput::read_pixels_mixed_run_length(
519542 // put the data into the correct place
520543 scanlineData[(pixelX * pixelChannelSize
521544 * m_spec.nchannels )
522- + (channels[curChan] * pixelChannelSize)
545+ + (m_channel_map[channels[curChan]]
546+ * pixelChannelSize)
523547 + curByte]
524548 = pixelData[(curChan * pixelChannelSize)
525549 + curByte];
0 commit comments