Repository: opencv
Issue: Thread sanitizer reports data race in imencode for JPEG format
Labels: bug,category: imgcodecs

### System Information

OpenCV 4.5.5
Ubuntu 22.04
gcc 11.4

### Detailed description

Thread sanitizer reports a data race when I call imencode from multi threads. I don't know if this a false positive (although I suspect it is, but it seems like it would be coming up more commonly because this is used a lot.



### Steps to reproduce
```
#include <opencv2/imgcodecs.hpp>
#include <opencv2/imgproc.hpp>  // Include the header for cv::Scalar

#include <unistd.h>  // Include the header for usleep
#include <algorithm>
#include <future>
#include <iostream>  // Include for debugging purposes
#include <vector>

int main() {
    std::vector<std::future<void>> futures;
    for (auto i = 0U; i < 1000; ++i) {
        auto future = std::async(std::launch::async, []() {
            usleep(rand() %
                   1000);  // Add a random delay to increase the chance
                           // that threads try to imencode at the same time
            std::vector<uchar> result;
            cv::Mat test_in(100, 100, CV_8UC3, cv::Scalar(0, 0, 0));
            std::string format = ".jpg";
            cv::imencode(format, test_in, result);
        });

        futures.push_back(std::move(future));
    }
    std::for_each(futures.begin(), futures.end(),
                  [](std::future<void>& f) { f.wait(); });
}
```


```
WARNING: ThreadSanitizer: data race (pid=741387)
  Read of size 8 at 0x7b0800001020 by thread T2:
    #0 memcpy ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:827 (libtsan.so.0+0x6243e)
    #1 memcpy ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:819 (libtsan.so.0+0x6243e)
    #2 cv::BaseImageEncoder::getDescription[abi:cxx11]() const <null> (test_out+0x50887)
    #3 std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>::operator()() const /usr/include/c++/11/bits/std_function.h:590 (test_out+0x498db)
    #4 std::__future_base::_State_baseV2::_M_do_set(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*) /usr/include/c++/11/future:571 (test_out+0x498db)
    #5 void std::__invoke_impl<void, void (std::__future_base::_State_baseV2::*)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*>(std::__invoke_memfun_deref, void (std::__future_base::_State_baseV2::*&&)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*&&, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*&&, bool*&&) /usr/include/c++/11/bits/invoke.h:74 (test_out+0x494ff)
    #6 std::__invoke_result<void (std::__future_base::_State_baseV2::*)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*>::type std::__invoke<void (std::__future_base::_State_baseV2::*)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*>(void (std::__future_base::_State_baseV2::*&&)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*&&, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*&&, bool*&&) /usr/include/c++/11/bits/invoke.h:96 (test_out+0x494ff)
    #7 std::call_once<void (std::__future_base::_State_baseV2::*)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*>(std::once_flag&, void (std::__future_base::_State_baseV2::*&&)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*&&, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*&&, bool*&&)::{lambda()#1}::operator()() const /usr/include/c++/11/mutex:776 (test_out+0x494ff)
    #8 std::once_flag::_Prepare_execution::_Prepare_execution<std::call_once<void (std::__future_base::_State_baseV2::*)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*>(std::once_flag&, void (std::__future_base::_State_baseV2::*&&)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*&&, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*&&, bool*&&)::{lambda()#1}>(void (std::__future_base::_State_baseV2::*&)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*))::{lambda()#1}::operator()() const /usr/include/c++/11/mutex:712 (test_out+0x494ff)
    #9 std::once_flag::_Prepare_execution::_Prepare_execution<std::call_once<void (std::__future_base::_State_baseV2::*)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*>(std::once_flag&, void (std::__future_base::_State_baseV2::*&&)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*&&, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*&&, bool*&&)::{lambda()#1}>(void (std::__future_base::_State_baseV2::*&)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*))::{lambda()#1}::_FUN() /usr/include/c++/11/mutex:712 (test_out+0x494ff)
    #10 pthread_once ../../../../src/libsanitizer/tsan/tsan_interceptors_posix.cpp:1449 (libtsan.so.0+0x42e6a)
    #11 __gthread_once /usr/include/x86_64-linux-gnu/c++/11/bits/gthr-default.h:700 (test_out+0x4909b)
    #12 void std::call_once<void (std::__future_base::_State_baseV2::*)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*>(std::once_flag&, void (std::__future_base::_State_baseV2::*&&)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*&&, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*&&, bool*&&) /usr/include/c++/11/mutex:783 (test_out+0x4909b)
    #13 std::__future_base::_State_baseV2::_M_set_result(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>, bool) /usr/include/c++/11/future:411 (test_out+0x4909b)
    #14 _M_run /usr/include/c++/11/future:1748 (test_out+0x4909b)
    #15 __invoke_impl<void, void (std::__future_base::_Async_state_impl<std::thread::_Invoker<std::tuple<main()::<lambda()> > >, void>::*)(), std::__future_base::_Async_state_impl<std::thread::_Invoker<std::tuple<main()::<lambda()> > >, void>*> /usr/include/c++/11/bits/invoke.h:74 (test_out+0x47f83)
    #16 __invoke<void (std::__future_base::_Async_state_impl<std::thread::_Invoker<std::tuple<main()::<lambda()> > >, void>::*)(), std::__future_base::_Async_state_impl<std::thread::_Invoker<std::tuple<main()::<lambda()> > >, void>*> /usr/include/c++/11/bits/invoke.h:96 (test_out+0x47f83)
    #17 _M_invoke<0, 1> /usr/include/c++/11/bits/std_thread.h:259 (test_out+0x47f83)
    #18 operator() /usr/include/c++/11/bits/std_thread.h:266 (test_out+0x47f83)
    #19 _M_run /usr/include/c++/11/bits/std_thread.h:211 (test_out+0x47f83)
    #20 <null> <null> (libstdc++.so.6+0xdc252)

  Previous write of size 8 at 0x7b0800001020 by thread T1:
    #0 operator new(unsigned long) ../../../../src/libsanitizer/tsan/tsan_new_delete.cpp:64 (libtsan.so.0+0x8f162)
    #1 __gnu_cxx::new_allocator<char>::allocate(unsigned long, void const*) /usr/include/c++/11/ext/new_allocator.h:127 (test_out+0x48074)
    #2 std::allocator<char>::allocate(unsigned long) /usr/include/c++/11/bits/allocator.h:185 (test_out+0x48074)
    #3 std::allocator_traits<std::allocator<char> >::allocate(std::allocator<char>&, unsigned long) /usr/include/c++/11/bits/alloc_traits.h:464 (test_out+0x48074)
    #4 std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_create(unsigned long&, unsigned long) /usr/include/c++/11/bits/basic_string.tcc:153 (test_out+0x48074)
    #5 std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_mutate(unsigned long, unsigned long, char const*, unsigned long) /usr/include/c++/11/bits/basic_string.tcc:307 (test_out+0x4a122)
    #6 std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_replace(unsigned long, unsigned long, char const*, unsigned long) /usr/include/c++/11/bits/basic_string.tcc:498 (test_out+0x4a4d7)
```







### Issue submission checklist

- [X] I report the issue, it's not a question
- [X] I checked the problem with documentation, FAQ, open issues, forum.opencv.org, Stack Overflow, etc and have not found any solution
- [ ] I updated to the latest OpenCV version and the issue is still there
- [X] There is reproducer code and related data files (videos, images, onnx, etc)