void ToMayaImageConverter::writeChannel( MImage &image, typename TypedData< std::vector<T> >::Ptr channelData, unsigned channelOffset, unsigned numChannels ) const { assert( channelOffset < numChannels ); ConstImagePrimitivePtr toConvert = runTimeCast<const ImagePrimitive>( srcParameter()->getValidatedValue() ); assert( toConvert ); unsigned width, height; image.getSize( width, height ); const Imath::Box2i &dataWindow = toConvert->getDataWindow(); const Imath::Box2i &displayWindow = toConvert->getDisplayWindow(); unsigned int dataWidth = dataWindow.size().x + 1; unsigned int dataHeight = dataWindow.size().y + 1; Imath::V2i dataOffset = dataWindow.min - displayWindow.min ; boost::multi_array_ref< const T, 2 > src( &channelData->readable()[0], boost::extents[dataHeight][dataWidth] ); boost::multi_array_ref< T, 3 > dst( MImageAccessor<T>::getPixels( image ), boost::extents[ height ][ width ][ numChannels ] ); for ( unsigned x = 0; x < dataWidth; x++ ) { for ( unsigned y = 0; y < dataHeight; y++ ) { /// Vertical flip, to match Maya dst[ ( height - 1 ) - ( y + dataOffset.y ) ][ x + dataOffset.x ][channelOffset] = src[y][x]; } } }
typename TypedData< std::vector< U > >::Ptr vectorLookup( Lookup<T,U> &lookup, typename TypedData< std::vector< T > >::Ptr x ) { typename TypedData< std::vector< U > >::Ptr res = new TypedData< std::vector< U > >; res->writable().resize( x->readable().size() ); typename std::vector< T >::const_iterator xIt = x->readable().begin(); typename std::vector< U >::iterator yIt = res->writable().begin(); for ( ; xIt != x->readable().end(); xIt++, yIt++ ) { *yIt = lookup( *xIt ); } return res; }
static void triangulate( T &t, typename TypedData<std::vector<typename T::Point> >::ConstPtr p ) { t.triangulate( p->readable().begin(), p->readable().end() ); }
DataPtr SGIImageReader::readTypedChannel( const std::string &name, const Box2i &dataWindow ) { typedef TypedData< std::vector< V > > TargetVector; assert( open() ); assert( m_header ); typename TypedData< std::vector<T > >::ConstPtr dataBuffer = assertedStaticCast< TypedData< std::vector<T > > >( m_buffer ); assert( dataBuffer ); const typename TypedData< std::vector<T > >::ValueType &buffer = dataBuffer->readable(); assert( m_header->m_channelOffsets.find( name ) != m_header->m_channelOffsets.end() ); int channelOffset = m_header->m_channelOffsets[name]; typename TargetVector::Ptr dataContainer = new TargetVector(); typename TargetVector::ValueType &data = dataContainer->writable(); int area = ( dataWindow.size().x + 1 ) * ( dataWindow.size().y + 1 ); assert( area >= 0 ); data.resize( area ); int dataWidth = 1 + dataWindow.size().x; Box2i wholeDataWindow = this->dataWindow(); int wholeDataHeight = 1 + wholeDataWindow.size().y; int wholeDataWidth = 1 + wholeDataWindow.size().x; const int yMin = dataWindow.min.y - wholeDataWindow.min.y; const int yMax = dataWindow.max.y - wholeDataWindow.min.y; const int xMin = dataWindow.min.x - wholeDataWindow.min.x; const int xMax = dataWindow.max.x - wholeDataWindow.min.x; ScaledDataConversion<T, V> converter; if ( m_header->m_fileHeader.m_storageFormat >= 1 ) /// RLE { int dataY = 0; for ( int y = yMin ; y <= yMax ; ++y, ++dataY ) { assert( yMin >= 0 ); assert( yMin < wholeDataHeight ); /// Images are unencoded "upside down" (flipped in Y), for our purposes uint32_t rowOffset = m_header->m_offsetTable[ channelOffset * wholeDataHeight + ( wholeDataHeight - 1 - y ) ]; if ( rowOffset >= buffer.size() ) { throw IOException( "SGIImageReader: Invalid RLE row offset found while reading " + fileName() ); } std::vector<T> scanline( wholeDataWidth ); uint32_t scanlineOffset = 0; bool done = false; while ( !done ) { T pixel = buffer[ rowOffset ++ ]; T count = pixel & 0x7f; if ( count == 0 ) { done = true; } else { if ( pixel & 0x80 ) { if ( scanlineOffset + count - 1 >= scanline.size() || rowOffset + count - 1 >= buffer.size() ) { throw IOException( "SGIImageReader: Invalid RLE data found while reading " + fileName() ); } while ( count -- ) { assert( scanlineOffset < scanline.size() ); assert( rowOffset < buffer.size() ); scanline[ scanlineOffset++ ] = buffer[ rowOffset ++ ]; } } else { if ( scanlineOffset + count - 1 >= scanline.size() || rowOffset - 1 >= buffer.size() ) { throw IOException( "SGIImageReader: Invalid RLE data found while reading " + fileName() ); } assert( rowOffset < buffer.size() ); pixel = buffer[ rowOffset ++ ]; while ( count -- ) { assert( scanlineOffset < scanline.size() ); scanline[ scanlineOffset++ ] = pixel; } } } } if ( scanlineOffset != scanline.size() ) { throw IOException( "SGIImageReader: Error occurred during RLE decode while reading " + fileName() ); } int dataOffset = dataY * dataWidth; for ( int x = xMin; x <= xMax ; ++x, ++dataOffset ) { data[dataOffset] = converter( scanline[x] ); } } } else /// Not RLE { int dataY = 0; for ( int y = dataWindow.min.y; y <= dataWindow.max.y; ++y, ++dataY ) { typename TargetVector::ValueType::size_type dataOffset = dataY * dataWidth; for ( int x = dataWindow.min.x; x <= dataWindow.max.x; ++x, ++dataOffset ) { assert( dataOffset < data.size() ); /// Images are unencoded "upside down" (flipped in Y), for our purposes data[dataOffset] = converter( buffer[ ( channelOffset * wholeDataHeight * wholeDataWidth ) + ( wholeDataHeight - 1 - y ) * wholeDataWidth + x ] ); } } } return dataContainer; }