void FreezeScript::AssignVisitor::visitSequence(const SequenceDataPtr& dest) { Slice::TypePtr type = dest->getType(); SequenceDataPtr src = SequenceDataPtr::dynamicCast(_src); if(src && isCompatible(type, src->getType())) { DataList& srcElements = src->getElements(); DataList destElements; Slice::SequencePtr seqType = Slice::SequencePtr::dynamicCast(type); assert(seqType); Slice::TypePtr elemType = seqType->type(); string typeName = typeToString(type); for(DataList::const_iterator p = srcElements.begin(); p != srcElements.end(); ++p) { DataPtr element = _factory->create(elemType, false); Destroyer<DataPtr> elementDestroyer(element); AssignVisitor v(*p, _factory, _errorReporter, _convert, typeName + " element"); element->visit(v); destElements.push_back(element); elementDestroyer.release(); } DataList& l = dest->getElements(); l.swap(destElements); } else { typeMismatchError(type, _src->getType()); } }
void FreezeScript::TransformVisitor::visitSequence(const SequenceDataPtr& dest) { Slice::TypePtr type = dest->getType(); if(_info->doDefaultTransform(type)) { SequenceDataPtr s = SequenceDataPtr::dynamicCast(_src); if(s && isCompatible(type, _src->getType())) { DataList& srcElements = s->getElements(); DataList destElements; Slice::SequencePtr seqType = Slice::SequencePtr::dynamicCast(type); assert(seqType); Slice::TypePtr elemType = seqType->type(); string typeName = typeToString(type); for(DataList::const_iterator p = srcElements.begin(); p != srcElements.end(); ++p) { DataPtr element = _info->getDataFactory()->create(elemType, false); Destroyer<DataPtr> elementDestroyer(element); try { TransformVisitor v(*p, _info, typeName + " element"); element->visit(v); destElements.push_back(element); elementDestroyer.release(); } catch(const ClassNotFoundException& ex) { // // If transformation of the sequence element fails because a class // could not be found, then we invoke purgeObjects() to determine // whether we should ignore the situation (and remove the element // from the sequence) or raise the exception again. // if(!_info->purgeObjects()) { throw; } warning("purging element of sequence " + typeToString(type) + " due to missing class type " + ex.id); } } DataList& l = dest->getElements(); l.swap(destElements); } else { typeMismatchError(type, _src->getType()); } } _info->executeCustomTransform(dest, _src); }
SequenceDataPtr CastTransformer::TypedCast<TElementTo>::Apply(SequenceDataPtr sequence) { auto shape = m_parent->m_inputStream.m_sampleLayout; if (shape.IsUnknown()) // Taking the shape from the sequence. shape = sequence->GetSampleShape(); if (shape.IsUnknown()) RuntimeError("Unknown shape of the sample in stream '%ls'.", m_parent->m_inputStream.m_name.c_str()); auto& inputSequence = static_cast<DenseSequenceData&>(*sequence); size_t count = shape.TotalSize() * sequence->m_numberOfSamples; auto result = std::make_shared<DenseSequenceWithBuffer<TElementTo>>(m_memBuffers, count, shape); result->m_key = sequence->m_key; auto src = reinterpret_cast<const TElementFrom*>(inputSequence.GetDataBuffer()); auto dst = result->GetBuffer(); for (size_t i = 0; i < count; i++) { dst[i] = static_cast<TElementTo>(src[i]); } result->m_numberOfSamples = inputSequence.m_numberOfSamples; return result; }
// Transformation of the sequence. SequenceDataPtr TransposeTransformer::Transform(SequenceDataPtr sequence) { auto inputSequence = dynamic_cast<ImageSequenceData*>(sequence.get()); if (inputSequence == nullptr) RuntimeError("Currently Transpose transform only works with images."); DataType elementType = m_inputStream.m_elementType != DataType::Unknown ? m_inputStream.m_elementType : sequence->m_elementType; switch (elementType) { case DataType::Double: if (m_precision == DataType::Float) return m_floatTransform.Apply<double>(inputSequence); if (m_precision == DataType::Double) return m_doubleTransform.Apply<double>(inputSequence); case DataType::Float: if (m_precision == DataType::Double) return m_doubleTransform.Apply<float>(inputSequence); if (m_precision == DataType::Float) return m_floatTransform.Apply<float>(inputSequence); case DataType::UChar: if (m_precision == DataType::Double) return m_doubleTransform.Apply<unsigned char>(inputSequence); if (m_precision == DataType::Float) return m_floatTransform.Apply<unsigned char>(inputSequence); default: RuntimeError("Unsupported type. Please apply a cast transform with 'double' or 'float' precision."); } return nullptr; // Make compiler happy }
SequenceDataPtr TransposeTransformer::TypedApply(SequenceDataPtr sequence, const StreamDescription &inputStream, const StreamDescription &outputStream) { assert(inputStream.m_storageType == StorageType::dense); auto inputSequence = static_cast<DenseSequenceData&>(*sequence.get()); assert(inputSequence.m_numberOfSamples == 1); assert(inputStream.m_sampleLayout->GetNumElements() == outputStream.m_sampleLayout->GetNumElements()); size_t count = inputStream.m_sampleLayout->GetNumElements() * GetSizeByType(inputStream.m_elementType); auto result = std::make_shared<DenseSequenceWithBuffer>(); result->m_buffer.resize(count); ImageDimensions dimensions(*inputStream.m_sampleLayout, ImageLayoutKind::HWC); size_t rowCount = dimensions.m_height * dimensions.m_width; size_t channelCount = dimensions.m_numChannels; auto src = reinterpret_cast<TElemType*>(inputSequence.m_data); auto dst = reinterpret_cast<TElemType*>(result->m_buffer.data()); for (size_t irow = 0; irow < rowCount; irow++) { for (size_t icol = 0; icol < channelCount; icol++) { dst[icol * rowCount + irow] = src[irow * channelCount + icol]; } } result->m_sampleLayout = outputStream.m_sampleLayout; result->m_data = result->m_buffer.data(); result->m_numberOfSamples = inputSequence.m_numberOfSamples; return result; }