Repository: opencv/opencv
File: modules/dnn/src/layers/dft_layer.cpp (C++)

Code before:
            if (ax == INT_MIN)
            {
                ax = (inshape.back() == 2 || inshape.back() == 1) ? ndims_in - 2 : ndims_in - 1;
            }
            if (ax < 0) ax += ndims_in;
            if (ax >= 0 && ax < (int)out.size() - 1)
            {
                int signalLen = dft_length > 0 ? dft_length : (ax < (int)inshape.size() ? inshape[ax] : out[ax]);
                out[ax] = onesided ? (signalLen / 2 + 1) : signalLen;
            }
        }
        outputs.assign(1, out);
        return false;
    }

    void forward(InputArrayOfArrays inputs_arr, OutputArrayOfArrays outputs_arr, OutputArrayOfArrays /*internals_arr*/) CV_OVERRIDE
    {
        std::vector<Mat> inputs, outputs;
        inputs_arr.getMatVector(inputs);

        CV_Assert(!inputs.empty());
        CV_Assert(inputs[0].dims >= 1);

        const Mat &src = inputs[0];

        const int ndims = src.dims;
        CV_Assert(ndims >= 1);
        const bool srcHasComplex = (src.size[ndims - 1] == 2);
        const bool srcLastIsOne = (src.size[ndims - 1] == 1);
        int axis = (srcHasComplex ? ndims - 2 : ndims - 1);
        if (axis_attr != INT_MIN)
        {
            axis = axis_attr;
            if (axis < 0) axis += ndims;
        }
        else if (!axes.empty())
        {
            CV_Assert(axes.size() == 1);
            axis = axes[0];
            if (axis < 0) axis += ndims;
        }
        CV_Assert(axis >= 0 && axis < (srcHasComplex ? ndims - 1 : ndims));
        if (onesided)
        {
            CV_Assert(!srcHasComplex);
            CV_Assert(!inverse);
        }

        std::vector<int> outSizesVec;
        outSizesVec.resize(srcHasComplex ? ndims : ndims + (srcLastIsOne ? 0 : 1));
        for (int i = 0; i < ndims; ++i) outSizesVec[i] = src.size[i];

Review comment (suggestion):
if the second input (dft_length) is non-constant, it means that the shape is dynamic. Please, override the corresponding method and handle that.

Code after:
            return -1;
        }

        Net::Impl* netimpl_ = getNetImpl(const_cast<DFTLayerImpl*>(this));
        if (!netimpl_)
        {
            return -1;
        }

        Mat dft_length_tensor = netimpl_->argTensor(this->inputs[1]);
        if (dft_length_tensor.empty() || dft_length_tensor.total() != 1)
        {
            return -1;
        }

        int64_t dft_length64 = 0;
        tensorToScalar(dft_length_tensor, CV_64S, &dft_length64);
        if (dft_length64 > 0)
        {
            return static_cast<int>(dft_length64);
        }
        return -1;
    }

public:
    virtual bool getMemoryShapes(const std::vector<MatShape> &inputs,
                                 const int /*requiredOutputs*/,
                                 std::vector<MatShape> &outputs,
                                 std::vector<MatShape> &/*internals*/) const CV_OVERRIDE
    {
        CV_Assert(inputs.size() >= 1);
        const MatShape &inshape = inputs[0];
        CV_Assert(!inshape.empty());
        MatShape out = inshape;

        int last = out.back();
        if (last == 1)
            out.back() = 2;
        else if (last != 2)
            out.push_back(2);

        int ndims_in = (int)inshape.size();
        int ax = axis_attr;
        if (ax == INT_MIN)
        {
            ax = (inshape.back() == 2 || inshape.back() == 1) ? ndims_in - 2 : ndims_in - 1;
        }
        if (ax < 0) ax += ndims_in;
        if (ax >= 0 && ax < (int)out.size() - 1)
        {
            int dft_length = getDftLengthFromConstant();