nareshmlx/opencv-pr huggingface dataset:
**File:** modules/videoio/src/cap_ffmpeg.cpp
**Change Type:** modified
**Context:** PR #25584: Open VideoCapture from data stream

**Code Changes:**
```diff
@@ -74,6 +74,11 @@ class CvCapture_FFMPEG_proxy CV_FINAL : public cv::VideoCaptureBase
     {
         open(filename, params);
     }
+    CvCapture_FFMPEG_proxy(const Ptr<IStreamReader>& stream, const cv::VideoCaptureParameters& params)
+        : ffmpegCapture(NULL)
+    {
+        open(stream, params);
+    }
     virtual ~CvCapture_FFMPEG_proxy() { close(); }
```

Review comment:
Removed completely
**File:** modules/videoio/misc/python/pyopencv_videoio.hpp
**Change Type:** modified
**Context:** PR #25584: Open VideoCapture from data stream

**Code Changes:**
```diff
@@ -31,4 +31,114 @@ template<> bool pyopencv_to(PyObject* obj, cv::VideoCapture& stream, const ArgIn
     return true;
 }
 
+class PythonStreamReader : public cv::IStreamReader
+{
+public:
+    PythonStreamReader(PyObject* _obj = nullptr) : obj(_obj)
+    {
+        if (obj)
```

Review comment:
Added an alias like done for std::string in python generator. However std:: prefix is still missed somewhere
**File:** modules/videoio/include/opencv2/videoio/registry.hpp
**Change Type:** modified
**Context:** PR #25584: Open VideoCapture from data stream

**Code Changes:**
```diff
@@ -35,6 +35,9 @@ CV_EXPORTS_W std::vector<VideoCaptureAPIs> getCameraBackends();
 /** @brief Returns list of available backends which works via `cv::VideoCapture(filename)` */
 CV_EXPORTS_W std::vector<VideoCaptureAPIs> getStreamBackends();
 
+/** @brief Returns list of available backends which works via `cv::VideoCapture(buffer)` */
+CV_EXPORTS_W std::vector<VideoCaptureAPIs> getStreamBufferedBackends();
+
 /** @brief Returns list of available backends which works via `cv::VideoWriter()` */
 CV_EXPORTS_W std::vector<VideoCaptureAPIs> getWriterBackends();
 
```

Review comment:
Buffer => Stream
**File:** modules/videoio/src/cap_ffmpeg.cpp
**Change Type:** modified
**Context:** PR #25584: Open VideoCapture from data stream

**Code Changes:**
```diff
@@ -74,6 +74,11 @@ class CvCapture_FFMPEG_proxy CV_FINAL : public cv::VideoCaptureBase
     {
         open(filename, params);
     }
+    CvCapture_FFMPEG_proxy(const Ptr<IStreamReader>& stream, const cv::VideoCaptureParameters& params)
+        : ffmpegCapture(NULL)
+    {
+        open(stream, params);
+    }
     virtual ~CvCapture_FFMPEG_proxy() { close(); }
```

Review comment:
> `Ptr<IReadStream>(new ...` `makePtr` / `std::make_shared`
**File:** modules/videoio/include/opencv2/videoio.hpp
**Change Type:** modified
**Context:** PR #25584: Open VideoCapture from data stream

**Code Changes:**
```diff
@@ -719,6 +719,25 @@ enum VideoCaptureOBSensorProperties{
 
 //! @} videoio_flags_others
 
+/** @brief Read data stream interface
+ */
+class CV_EXPORTS_W IStreamReader
+{
+public:
+    virtual ~IStreamReader();
```

Review comment:
> in memory buffer Opens a video using data stream.
**File:** modules/videoio/include/opencv2/videoio/utils.private.hpp
**Change Type:** modified
**Context:** PR #25584: Open VideoCapture from data stream

**Code Changes:**
```diff
@@ -10,6 +10,37 @@
 
 namespace cv {
 CV_EXPORTS std::string icvExtractPattern(const std::string& filename, unsigned *offset);
+
+class PluginStreamReader : public IStreamReader
+{
+public:
+    PluginStreamReader(void* _opaque,
+                       long long (*_read)(void* opaque, char* buffer, long long size),
```

Review comment:
`ReadStreamPluginProvider` Usually `Callback` means abstract interface description. We already have the `IReadStream` for that.
**File:** modules/videoio/misc/python/pyopencv_videoio.hpp
**Change Type:** modified
**Context:** PR #25584: Open VideoCapture from data stream

**Code Changes:**
```diff
@@ -31,4 +31,114 @@ template<> bool pyopencv_to(PyObject* obj, cv::VideoCapture& stream, const ArgIn
     return true;
 }
 
+class PythonStreamReader : public cv::IStreamReader
+{
+public:
+    PythonStreamReader(PyObject* _obj = nullptr) : obj(_obj)
+    {
+        if (obj)
```

Review comment:
Check `len < n`
**File:** modules/videoio/misc/python/pyopencv_videoio.hpp
**Change Type:** modified
**Context:** PR #25584: Open VideoCapture from data stream
**Review Line:** 116

**Code Changes:**
```diff
+            CV_Error(cv::Error::StsError, "Python .seek() result => long long conversion error");
+        return pos;
+    }
+
+private:
+    PyObject* obj;
+};
+
+template<>
+bool pyopencv_to(PyObject* obj, Ptr<cv::IStreamReader>& p, const ArgInfo&)
+{
```

Review comment:
Who calls `Py_DECREF` ?
**File:** modules/videoio/src/cap.cpp
**Change Type:** modified
**Context:** PR #25584: Open VideoCapture from data stream

**Code Changes:**
```diff
@@ -65,6 +65,10 @@ static bool param_VIDEOWRITER_DEBUG = utils::getConfigurationParameterBool("OPEN
 void DefaultDeleter<CvCapture>::operator ()(CvCapture* obj) const { cvReleaseCapture(&obj); }
 void DefaultDeleter<CvVideoWriter>::operator ()(CvVideoWriter* obj) const { cvReleaseVideoWriter(&obj); }
 
+IStreamReader::~IStreamReader()
+{
+    // nothing
+}
 
 VideoCapture::VideoCapture() : throwOnFail(false)
```

Review comment:
Who performs `seek(0, 0)` between trials? Perhaps we should not allow `CAP_ANY` in this API.
**File:** modules/videoio/include/opencv2/videoio/utils.private.hpp
**Change Type:** modified
**Context:** PR #25584: Open VideoCapture from data stream

**Code Changes:**
```diff
@@ -10,6 +10,37 @@
 
 namespace cv {
 CV_EXPORTS std::string icvExtractPattern(const std::string& filename, unsigned *offset);
+
+class PluginStreamReader : public IStreamReader
+{
+public:
+    PluginStreamReader(void* _opaque,
+                       long long (*_read)(void* opaque, char* buffer, long long size),
```

Review comment:
There is no guarantee for lifetime of this. Perhaps we need to pass `std::shared_ptr<std::streambuf>` in public API.
**File:** modules/videoio/include/opencv2/videoio/utils.private.hpp
**Change Type:** modified
**Context:** PR #25584: Open VideoCapture from data stream

**Code Changes:**
```diff
@@ -10,6 +10,37 @@
 
 namespace cv {
 CV_EXPORTS std::string icvExtractPattern(const std::string& filename, unsigned *offset);
+
+class PluginStreamReader : public IStreamReader
+{
+public:
+    PluginStreamReader(void* _opaque,
+                       long long (*_read)(void* opaque, char* buffer, long long size),
```

Review comment:
Looks useless because it could not (and should not) create independent objects (at least seek pointer is shared). See below comment about lifetime.
**File:** modules/videoio/src/videoio_registry.cpp
**Change Type:** modified
**Context:** PR #25584: Open VideoCapture from data stream

**Code Changes:**
```diff
@@ -47,7 +47,12 @@ namespace {
 
 #define DECLARE_STATIC_BACKEND(cap, name, mode, createCaptureFile, createCaptureCamera, createWriter) \
 { \
-    cap, (BackendMode)(mode), 1000, name, createBackendFactory(createCaptureFile, createCaptureCamera, createWriter) \
+    cap, (BackendMode)(mode), 1000, name, createBackendFactory(createCaptureFile, createCaptureCamera, 0, createWriter) \
+},
+
+#define DECLARE_STATIC_BACKEND_WITH_STREAM_SUPPORT(cap, name, mode, createCaptureStream) \
+{ \
```

Review comment:
Please add new macro instead of massive refactoring: `DECLARE_STATIC_BACKEND_WITH_STREAM_SUPPORT`
**File:** modules/videoio/src/videoio_registry.hpp
**Change Type:** modified
**Context:** PR #25584: Open VideoCapture from data stream

**Code Changes:**
```diff
@@ -14,6 +14,7 @@ namespace cv
 enum BackendMode {
     MODE_CAPTURE_BY_INDEX    = 1 << 0,           //!< device index
     MODE_CAPTURE_BY_FILENAME = 1 << 1,           //!< filename or device path (v4l2)
+    MODE_CAPTURE_BY_STREAM   = 1 << 2,           //!< data stream
     MODE_WRITER              = 1 << 4,            //!< writer
 
     MODE_CAPTURE_ALL = MODE_CAPTURE_BY_INDEX + MODE_CAPTURE_BY_FILENAME,
@@ -38,6 +39,7 @@ namespace videoio_registry {
 
```

Review comment:
need to update comment too.
**File:** modules/videoio/src/videoio_registry.hpp
**Change Type:** modified
**Context:** PR #25584: Open VideoCapture from data stream

**Code Changes:**
```diff
@@ -14,6 +14,7 @@ namespace cv
 enum BackendMode {
     MODE_CAPTURE_BY_INDEX    = 1 << 0,           //!< device index
     MODE_CAPTURE_BY_FILENAME = 1 << 1,           //!< filename or device path (v4l2)
+    MODE_CAPTURE_BY_STREAM   = 1 << 2,           //!< data stream
     MODE_WRITER              = 1 << 4,            //!< writer
 
     MODE_CAPTURE_ALL = MODE_CAPTURE_BY_INDEX + MODE_CAPTURE_BY_FILENAME,
@@ -38,6 +39,7 @@ namespace videoio_registry {
 
```

Review comment:
`getAvailableBackends_CaptureByStream`
**File:** modules/videoio/include/opencv2/videoio/registry.hpp
**Change Type:** modified
**Context:** PR #25584: Open VideoCapture from data stream

**Code Changes:**
```diff
@@ -35,6 +35,9 @@ CV_EXPORTS_W std::vector<VideoCaptureAPIs> getCameraBackends();
 /** @brief Returns list of available backends which works via `cv::VideoCapture(filename)` */
 CV_EXPORTS_W std::vector<VideoCaptureAPIs> getStreamBackends();
 
+/** @brief Returns list of available backends which works via `cv::VideoCapture(buffer)` */
+CV_EXPORTS_W std::vector<VideoCaptureAPIs> getStreamBufferedBackends();
+
 /** @brief Returns list of available backends which works via `cv::VideoWriter()` */
 CV_EXPORTS_W std::vector<VideoCaptureAPIs> getWriterBackends();
 
```

Review comment:
Oh, seems like `getStreamBackends` is busy (see above)
**File:** modules/videoio/include/opencv2/videoio/utils.private.hpp
**Change Type:** modified
**Context:** PR #25584: Open VideoCapture from data stream

**Code Changes:**
```diff
@@ -10,6 +10,37 @@
 
 namespace cv {
 CV_EXPORTS std::string icvExtractPattern(const std::string& filename, unsigned *offset);
+
+class PluginStreamReader : public IStreamReader
+{
+public:
+    PluginStreamReader(void* _opaque,
+                       long long (*_read)(void* opaque, char* buffer, long long size),
```

Review comment:
Removed `clone` method completely in last commit. As I understand, `struct CvCapture_FFMPEG` cannot hold a copy of `Ptr<IReadStream>` because there is no default constructor to allocate it: https://github.com/opencv/opencv/blob/b42075f3e2c7eca4a12e55b32cfc95fa90982a21/modules/videoio/src/cap_ffmpeg_impl.hpp#L3296 So I used `CvCapture_FFMPEG_proxy` to increase a counter
**File:** modules/videoio/misc/python/pyopencv_videoio.hpp
**Change Type:** modified
**Context:** PR #25584: Open VideoCapture from data stream
**Review Line:** 116

**Code Changes:**
```diff
+            CV_Error(cv::Error::StsError, "Python .seek() result => long long conversion error");
+        return pos;
+    }
+
+private:
+    PyObject* obj;
+};
+
+template<>
+bool pyopencv_to(PyObject* obj, Ptr<cv::IStreamReader>& p, const ArgInfo&)
+{
```

Review comment:
Added `Py_INCREF` as well
**File:** modules/videoio/include/opencv2/videoio/utils.private.hpp
**Change Type:** modified
**Context:** PR #25584: Open VideoCapture from data stream

**Code Changes:**
```diff
@@ -10,6 +10,37 @@
 
 namespace cv {
 CV_EXPORTS std::string icvExtractPattern(const std::string& filename, unsigned *offset);
+
+class PluginStreamReader : public IStreamReader
+{
+public:
+    PluginStreamReader(void* _opaque,
+                       long long (*_read)(void* opaque, char* buffer, long long size),
```

Review comment:
Agree, I think it can simplify other bindings addition in future.
**File:** modules/videoio/src/cap.cpp
**Change Type:** modified
**Context:** PR #25584: Open VideoCapture from data stream

**Code Changes:**
```diff
@@ -65,6 +65,10 @@ static bool param_VIDEOWRITER_DEBUG = utils::getConfigurationParameterBool("OPEN
 void DefaultDeleter<CvCapture>::operator ()(CvCapture* obj) const { cvReleaseCapture(&obj); }
 void DefaultDeleter<CvVideoWriter>::operator ()(CvVideoWriter* obj) const { cvReleaseVideoWriter(&obj); }
 
+IStreamReader::~IStreamReader()
+{
+    // nothing
+}
 
 VideoCapture::VideoCapture() : throwOnFail(false)
```

Review comment:
Good point, there is no explicit seek. Added a check that `apiPref != CAP_ANY`
**File:** modules/videoio/include/opencv2/videoio/registry.hpp
**Change Type:** modified
**Context:** PR #25584: Open VideoCapture from data stream

**Code Changes:**
```diff
@@ -35,6 +35,9 @@ CV_EXPORTS_W std::vector<VideoCaptureAPIs> getCameraBackends();
 /** @brief Returns list of available backends which works via `cv::VideoCapture(filename)` */
 CV_EXPORTS_W std::vector<VideoCaptureAPIs> getStreamBackends();
 
+/** @brief Returns list of available backends which works via `cv::VideoCapture(buffer)` */
+CV_EXPORTS_W std::vector<VideoCaptureAPIs> getStreamBufferedBackends();
+
 /** @brief Returns list of available backends which works via `cv::VideoWriter()` */
 CV_EXPORTS_W std::vector<VideoCaptureAPIs> getWriterBackends();
 
```

Review comment:
`getStreamBufferedBackends` ?
**File:** modules/videoio/include/opencv2/videoio.hpp
**Change Type:** modified
**Context:** PR #25584: Open VideoCapture from data stream

**Code Changes:**
```diff
@@ -719,6 +719,25 @@ enum VideoCaptureOBSensorProperties{
 
 //! @} videoio_flags_others
 
+/** @brief Read data stream interface
+ */
+class CV_EXPORTS_W IStreamReader
+{
+public:
+    virtual ~IStreamReader();
```

Review comment:
`const reference` here and below (or we should use `std::move()` massively)
**File:** modules/videoio/misc/python/pyopencv_videoio.hpp
**Change Type:** modified
**Context:** PR #25584: Open VideoCapture from data stream

**Code Changes:**
```diff
@@ -31,4 +31,114 @@ template<> bool pyopencv_to(PyObject* obj, cv::VideoCapture& stream, const ArgIn
     return true;
 }
 
+class PythonStreamReader : public cv::IStreamReader
+{
+public:
+    PythonStreamReader(PyObject* _obj = nullptr) : obj(_obj)
+    {
+        if (obj)
```

Review comment:
`CV_Error` doesn't call cleanup (release GIL and release `type`). ``` if (...) has_error = true; ... cleanup ... if (has_error) CV_Error(...); ```
**File:** modules/videoio/src/cap_ffmpeg.cpp
**Change Type:** modified
**Context:** PR #25584: Open VideoCapture from data stream

**Code Changes:**
```diff
@@ -74,6 +74,11 @@ class CvCapture_FFMPEG_proxy CV_FINAL : public cv::VideoCaptureBase
     {
         open(filename, params);
     }
+    CvCapture_FFMPEG_proxy(const Ptr<IStreamReader>& stream, const cv::VideoCaptureParameters& params)
+        : ffmpegCapture(NULL)
+    {
+        open(stream, params);
+    }
     virtual ~CvCapture_FFMPEG_proxy() { close(); }
```

Review comment:
> `makePtr<ReadStreamPluginProvider>(opaque, read, seek)` Released right after this call because it is not saved anywhere.
**File:** modules/videoio/src/cap_ffmpeg.cpp
**Change Type:** modified
**Context:** PR #25584: Open VideoCapture from data stream

**Code Changes:**
```diff
@@ -74,6 +74,11 @@ class CvCapture_FFMPEG_proxy CV_FINAL : public cv::VideoCaptureBase
     {
         open(filename, params);
     }
+    CvCapture_FFMPEG_proxy(const Ptr<IStreamReader>& stream, const cv::VideoCaptureParameters& params)
+        : ffmpegCapture(NULL)
+    {
+        open(stream, params);
+    }
     virtual ~CvCapture_FFMPEG_proxy() { close(); }
```

Review comment:
As a workaround, `readStream = stream` for now
**File:** modules/videoio/include/opencv2/videoio/registry.hpp
**Change Type:** modified
**Context:** PR #25584: Open VideoCapture from data stream

**Code Changes:**
```diff
@@ -35,6 +35,9 @@ CV_EXPORTS_W std::vector<VideoCaptureAPIs> getCameraBackends();
 /** @brief Returns list of available backends which works via `cv::VideoCapture(filename)` */
 CV_EXPORTS_W std::vector<VideoCaptureAPIs> getStreamBackends();
 
+/** @brief Returns list of available backends which works via `cv::VideoCapture(buffer)` */
+CV_EXPORTS_W std::vector<VideoCaptureAPIs> getStreamBufferedBackends();
+
 /** @brief Returns list of available backends which works via `cv::VideoWriter()` */
 CV_EXPORTS_W std::vector<VideoCaptureAPIs> getWriterBackends();
 
```

Review comment:
Changed locally, can commit with https://github.com/opencv/opencv/pull/25584#discussion_r1896904920 if actual
**File:** modules/videoio/include/opencv2/videoio.hpp
**Change Type:** modified
**Context:** PR #25584: Open VideoCapture from data stream

**Code Changes:**
```diff
@@ -719,6 +719,25 @@ enum VideoCaptureOBSensorProperties{
 
 //! @} videoio_flags_others
 
+/** @brief Read data stream interface
+ */
+class CV_EXPORTS_W IStreamReader
+{
+public:
+    virtual ~IStreamReader();
```

Review comment:
Do we really need methods with `std::streambuf`? Maybe it would be better to make `StreambufReadStream` or similar class or just its factory public instead? For example: ```.cpp shared_ptr<IStreamReader> source = createStdStream(filename); // can accept filename or &&filebuf or &&istream or &&ifstream VideoCapture cap(source, ...); ```
**File:** modules/videoio/include/opencv2/videoio.hpp
**Change Type:** modified
**Context:** PR #25584: Open VideoCapture from data stream

**Code Changes:**
```diff
@@ -719,6 +719,25 @@ enum VideoCaptureOBSensorProperties{
 
 //! @} videoio_flags_others
 
+/** @brief Read data stream interface
+ */
+class CV_EXPORTS_W IStreamReader
+{
+public:
+    virtual ~IStreamReader();
```

Review comment:
Good point. But I think we can even remove it completely. `std::streambuf` might introduce more limitations than just seek/read interface. So I can move `class StreambufReadStream : public IStreamReader` example to the tests for now and remove option from public API.
**File:** modules/videoio/include/opencv2/videoio.hpp
**Change Type:** modified
**Context:** PR #25584: Open VideoCapture from data stream
**Review Line:** 735

**Code Changes:**
```diff
+    virtual long long read(char* buffer, long long size) = 0;
+
+    /** @brief Sets the stream position
+     *
+     * @param offset Seek offset
+     * @param origin SEEK_SET / SEEK_END / SEEK_CUR
+     *
+     * @see fseek
+     */
+    virtual long long seek(long long offset, int origin) = 0;
+};
```

Review comment:
Wouldn't it be better to completely avoid C/C++ constants in public interface and introduce our own?
**File:** modules/videoio/include/opencv2/videoio.hpp
**Change Type:** modified
**Context:** PR #25584: Open VideoCapture from data stream
**Review Line:** 735

**Code Changes:**
```diff
+    virtual long long read(char* buffer, long long size) = 0;
+
+    /** @brief Sets the stream position
+     *
+     * @param offset Seek offset
+     * @param origin SEEK_SET / SEEK_END / SEEK_CUR
+     *
+     * @see fseek
+     */
+    virtual long long seek(long long offset, int origin) = 0;
+};
```

Review comment:
FFmpeg (basically) and Python use them too (with same values). IMHO, it is not necessary to introduce extra conversions to/from own values.
**File:** modules/videoio/include/opencv2/videoio.hpp
**Change Type:** modified
**Context:** PR #25584: Open VideoCapture from data stream
**Review Line:** 735

**Code Changes:**
```diff
+    virtual long long read(char* buffer, long long size) = 0;
+
+    /** @brief Sets the stream position
+     *
+     * @param offset Seek offset
+     * @param origin SEEK_SET / SEEK_END / SEEK_CUR
+     *
+     * @see fseek
+     */
+    virtual long long seek(long long offset, int origin) = 0;
+};
```

Review comment:
Agree, we can add such enum but potential user will still cast to integer or introduce long if/else/switch
**File:** modules/videoio/include/opencv2/videoio.hpp
**Change Type:** modified
**Context:** PR #25584: Open VideoCapture from data stream
**Review Line:** 735

**Code Changes:**
```diff
+    virtual long long read(char* buffer, long long size) = 0;
+
+    /** @brief Sets the stream position
+     *
+     * @param offset Seek offset
+     * @param origin SEEK_SET / SEEK_END / SEEK_CUR
+     *
+     * @see fseek
+     */
+    virtual long long seek(long long offset, int origin) = 0;
+};
```

Review comment:
My concern was that user would be required to include `<stdio.h>`/`<cstdio>` in order to use this seemingly unrelated class. Though perhaps it's fine.
**File:** modules/imgcodecs/src/grfmt_gif.cpp
**Change Type:** modified
**Context:** PR #26738: fix bugs in GIF decoding
**Review Line:** 438

**Code Changes:**
```diff
+                    CV_LOG_WARNING(NULL, "found Unknown Extension Type: " + std::to_string(extension));
+                }
+                int len = m_strm.getByte();
+                while (len) {
+                    m_strm.skip(len);
+                    len = m_strm.getByte();
                 }
             }
         } else if (!(type ^ 0x2C)) {
```

Review comment:
I propose to print info/warning message about skipped extensions with CV_LOG_INFO/CV_LOG_WARNING. It helps to highlight unexpected behaviour in some cases.
**File:** modules/imgcodecs/src/grfmt_gif.cpp
**Change Type:** modified
**Context:** PR #26738: fix bugs in GIF decoding

**Code Changes:**
```diff
@@ -4,6 +4,7 @@
 
 #include "precomp.hpp"
 #include "grfmt_gif.hpp"
+#include "opencv2/core/utils/logger.hpp"
 
 #ifdef HAVE_IMGCODEC_GIF
 namespace cv
@@ -293,11 +294,12 @@ void GifDecoder::code2pixel(Mat& img, int start, int k){
 bool GifDecoder::lzwDecode() {
```

Review comment:
I propose to use local len variable here and in the else branch like `int len = m_strm.getByte();`. It allows to get rid of "uninitialized varible" warnings by compiler and some tools like valgrind/asan, etc.
**File:** modules/imgcodecs/src/grfmt_gif.cpp
**Change Type:** modified
**Context:** PR #26738: fix bugs in GIF decoding

**Code Changes:**
```diff
@@ -4,6 +4,7 @@
 
 #include "precomp.hpp"
 #include "grfmt_gif.hpp"
+#include "opencv2/core/utils/logger.hpp"
 
 #ifdef HAVE_IMGCODEC_GIF
 namespace cv
@@ -293,11 +294,12 @@ void GifDecoder::code2pixel(Mat& img, int start, int k){
 bool GifDecoder::lzwDecode() {
```

Review comment:
Why not `lzwTableSize`?
**File:** modules/imgcodecs/src/grfmt_gif.cpp
**Change Type:** modified
**Context:** PR #26738: fix bugs in GIF decoding

**Code Changes:**
```diff
@@ -4,6 +4,7 @@
 
 #include "precomp.hpp"
 #include "grfmt_gif.hpp"
+#include "opencv2/core/utils/logger.hpp"
 
 #ifdef HAVE_IMGCODEC_GIF
 namespace cv
@@ -293,11 +294,12 @@ void GifDecoder::code2pixel(Mat& img, int start, int k){
 bool GifDecoder::lzwDecode() {
```

Review comment:
because (1<<12) is the maximum size of lzwtable, thus i use (1<<12)+1 here
**File:** modules/imgcodecs/src/grfmt_gif.cpp
**Change Type:** modified
**Context:** PR #26738: fix bugs in GIF decoding
**Review Line:** 438

**Code Changes:**
```diff
+                    CV_LOG_WARNING(NULL, "found Unknown Extension Type: " + std::to_string(extension));
+                }
+                int len = m_strm.getByte();
+                while (len) {
+                    m_strm.skip(len);
+                    len = m_strm.getByte();
                 }
             }
         } else if (!(type ^ 0x2C)) {
```

Review comment:
> I propose to print info/warning message about skipped extensions with CV_LOG_INFO/CV_LOG_WARNING. It helps to highlight unexpected behaviour in some cases. i think no need. ( probably we see lots of warning )
**File:** modules/imgcodecs/src/grfmt_gif.cpp
**Change Type:** modified
**Context:** PR #26738: fix bugs in GIF decoding

**Code Changes:**
```diff
@@ -4,6 +4,7 @@
 
 #include "precomp.hpp"
 #include "grfmt_gif.hpp"
+#include "opencv2/core/utils/logger.hpp"
 
 #ifdef HAVE_IMGCODEC_GIF
 namespace cv
@@ -293,11 +294,12 @@ void GifDecoder::code2pixel(Mat& img, int start, int k){
 bool GifDecoder::lzwDecode() {
```

Review comment:
Not variable, but constant.