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

Code before:
        outputs.assign(1, t);
    }

    void forward(InputArrayOfArrays inputs_arr, OutputArrayOfArrays outputs_arr, OutputArrayOfArrays internals_arr) CV_OVERRIDE
    {
        CV_TRACE_FUNCTION();
        CV_TRACE_ARG_VALUE(name, "name", name.c_str());

        std::vector<Mat> inputs, outputs;
        inputs_arr.getMatVector(inputs);
        outputs_arr.getMatVector(outputs);
        CV_Assert(inputs[0].isContinuous());
        CV_Assert(outputs[0].isContinuous());

        int t = inputs[0].type();
        size_t size = inputs[0].total();
        if (t == CV_Bool)
        {
            bool* input = inputs[0].ptr<bool>();
            bool* output = outputs[0].ptr<bool>();
            for (size_t i = 0; i < size; ++i)
                output[i] = !input[i];
            return;
        }

        switch (t)
        {
            case CV_8U: {
                const uint8_t* in = inputs[0].ptr<uint8_t>();
                uint8_t* out = outputs[0].ptr<uint8_t>();
                for (size_t i = 0; i < size; ++i) out[i] = static_cast<uint8_t>(~in[i]);
                break; }
            case CV_8S: {
                const int8_t* in = inputs[0].ptr<int8_t>();
                int8_t* out = outputs[0].ptr<int8_t>();
                for (size_t i = 0; i < size; ++i) out[i] = static_cast<int8_t>(~in[i]);
                break; }
            case CV_16U: {
                const uint16_t* in = inputs[0].ptr<uint16_t>();
                uint16_t* out = outputs[0].ptr<uint16_t>();
                for (size_t i = 0; i < size; ++i) out[i] = static_cast<uint16_t>(~in[i]);
                break; }
            case CV_16S: {
                const int16_t* in = inputs[0].ptr<int16_t>();
                int16_t* out = outputs[0].ptr<int16_t>();
                for (size_t i = 0; i < size; ++i) out[i] = static_cast<int16_t>(~in[i]);
                break; }
            case CV_32U: {
                const uint32_t* in = inputs[0].ptr<uint32_t>();
                uint32_t* out = outputs[0].ptr<uint32_t>();
                for (size_t i = 0; i < size; ++i) out[i] = static_cast<uint32_t>(~in[i]);

Review comment (suggestion):
please, don't do that. Just multiply size by the element size and use a single loop for all types.

Code after:
        outputs.assign(1, t);
    }

    void forward(InputArrayOfArrays inputs_arr, OutputArrayOfArrays outputs_arr, OutputArrayOfArrays internals_arr) CV_OVERRIDE
    {
        CV_TRACE_FUNCTION();
        CV_TRACE_ARG_VALUE(name, "name", name.c_str());

        std::vector<Mat> inputs, outputs;
        inputs_arr.getMatVector(inputs);
        outputs_arr.getMatVector(outputs);
        CV_Assert(inputs[0].isContinuous());
        CV_Assert(outputs[0].isContinuous());

        int t = inputs[0].type();
        size_t size = inputs[0].total();
        if (t == CV_Bool)
        {
            bool* input = inputs[0].ptr<bool>();
            bool* output = outputs[0].ptr<bool>();
            for (size_t i = 0; i < size; ++i)
                output[i] = !input[i];
            return;
        }

        const unsigned char* in = inputs[0].ptr<unsigned char>();
        unsigned char* out = outputs[0].ptr<unsigned char>();
        size_t totalBytes = size * inputs[0].elemSize();
        for (size_t i = 0; i < totalBytes; ++i)
            out[i] = static_cast<unsigned char>(~in[i]);
    }

#ifdef HAVE_DNN_NGRAPH
    virtual Ptr<BackendNode> initNgraph(const std::vector<Ptr<BackendWrapper> >& inputs,
                                        const std::vector<Ptr<BackendNode> >& nodes) CV_OVERRIDE
    {
        auto node = std::make_shared<ov::op::v1::LogicalNot>(nodes[0].dynamicCast<InfEngineNgraphNode>()->node);
        return Ptr<BackendNode>(new InfEngineNgraphNode(node));
    }
#endif  // HAVE_DNN_NGRAPH

};

Ptr<NotLayer> NotLayer::create(const LayerParams& params)
{
    return makePtr<NotLayerImpl>(params);
}

}}  // namespace cv::dnn