nareshmlx/opencv-pr huggingface dataset:
**File:** modules/imgcodecs/src/loadsave.cpp
**Change Type:** modified
**Context:** PR #25608: Animated WebP and AVIF Support

**Code Changes:**
```diff
@@ -682,6 +682,116 @@ bool imreadmulti(const String& filename, std::vector<Mat>& mats, int start, int
     return imreadmulti_(filename, flags, mats, start, count);
 }
 
+static bool
+imreadanimation_(const String& filename, int flags, int start, int count, Animation& animation)
+{
+    bool success = false;
+    if (start < 0) {
+        start = 0;
```

Review comment:
CV_LOG_ERROR
**File:** modules/imgcodecs/src/loadsave.cpp
**Change Type:** modified
**Context:** PR #25608: Animated WebP and AVIF Support
**Review Line:** 703

**Code Changes:**
```diff
+    decoder = findDecoder(filename);
+
+    /// if no decoder was found, return false.
+    if (!decoder) {
+        CV_LOG_WARNING(NULL, "Decoder for " << filename << " not found!\n");
+        return false;
+    }
+
+    /// set the filename in the driver
+    decoder->setSource(filename);
+    // read the header to make sure it succeeds
```

Review comment:
Log message us useful here
**File:** modules/imgcodecs/src/loadsave.cpp
**Change Type:** modified
**Context:** PR #25608: Animated WebP and AVIF Support
**Review Line:** 779

**Code Changes:**
```diff
+        }
+
+        if (!decoder->nextPage())
+        {
+            break;
+        }
+        ++current;
+    }
+    animation.bgcolor = decoder->animation().bgcolor;
+    animation.loop_count = decoder->animation().loop_count;
+
```

Review comment:
Need to add check, if we do not have unexpected early exit. E.g. header reports 10 frames, but we get only 5 from the very beginning.
**File:** modules/imgcodecs/src/grfmt_webp.cpp
**Change Type:** modified
**Context:** PR #25608: Animated WebP and AVIF Support

**Code Changes:**
```diff
@@ -44,17 +44,15 @@
 
 #include "precomp.hpp"
 
-#include <webp/decode.h>
-#include <webp/encode.h>
-
 #include <stdio.h>
 #include <limits.h>
-
```

Review comment:
Need to discuss it.
**File:** modules/imgcodecs/src/grfmt_webp.cpp
**Change Type:** modified
**Context:** PR #25608: Animated WebP and AVIF Support

**Code Changes:**
```diff
@@ -44,17 +44,15 @@
 
 #include "precomp.hpp"
 
-#include <webp/decode.h>
-#include <webp/encode.h>
-
 #include <stdio.h>
 #include <limits.h>
-
```

Review comment:
CV_LOG_ERROR
**File:** modules/imgcodecs/src/grfmt_webp.cpp
**Change Type:** modified
**Context:** PR #25608: Animated WebP and AVIF Support

**Code Changes:**
```diff
@@ -44,17 +44,15 @@
 
 #include "precomp.hpp"
 
-#include <webp/decode.h>
-#include <webp/encode.h>
-
 #include <stdio.h>
 #include <limits.h>
-
```

Review comment:
Need to aandle both RGB(a) and BGR(a) here.
**File:** modules/imgcodecs/src/grfmt_webp.cpp
**Change Type:** modified
**Context:** PR #25608: Animated WebP and AVIF Support
**Review Line:** 147

**Code Changes:**
```diff
-            m_type = CV_8UC3;
-            channels = 3;
+            fs.seekg(0, std::ios::beg); CV_Assert(fs && "File stream error");
+            data.create(1, validateToInt(fs_size), CV_8UC1);
+            fs.read((char*)data.ptr(), fs_size);
+            CV_Assert(fs && "Can't read file data");
+            fs.close();
         }
 
-        return true;
+        CV_Assert(data.type() == CV_8UC1); CV_Assert(data.rows == 1);
```

Review comment:
Assert raises exception. The file is not closed on the next line.
**File:** doc/tutorials/app/animations.markdown
**Change Type:** added
**Context:** PR #25608: Animated WebP and AVIF Support

**Code Changes:**
```diff
@@ -0,0 +1,91 @@
+Handling Animated Image Files {#tutorial_animations}
+===========================
+
+@tableofcontents
+
+|    |    |
+| -: | :- |
+| Original author | Suleyman Turkmen (with help of ChatGPT) |
+| Compatibility | OpenCV >= 4.11 |
```

Review comment:
Aninmated PNG (APNG)
**File:** modules/imgcodecs/src/grfmt_webp.cpp
**Change Type:** modified
**Context:** PR #25608: Animated WebP and AVIF Support
**Review Line:** 147

**Code Changes:**
```diff
-            m_type = CV_8UC3;
-            channels = 3;
+            fs.seekg(0, std::ios::beg); CV_Assert(fs && "File stream error");
+            data.create(1, validateToInt(fs_size), CV_8UC1);
+            fs.read((char*)data.ptr(), fs_size);
+            CV_Assert(fs && "Can't read file data");
+            fs.close();
         }
 
-        return true;
+        CV_Assert(data.type() == CV_8UC1); CV_Assert(data.rows == 1);
```

Review comment:
ifstream destructor closes the file. fs is decoder field, no need to wary about it here.
**File:** modules/imgcodecs/src/grfmt_avif.cpp
**Change Type:** modified
**Context:** PR #25608: Animated WebP and AVIF Support

**Code Changes:**
```diff
@@ -11,6 +11,7 @@
 #include <memory>
 
 #include <opencv2/core/utils/configuration.private.hpp>
+#include <opencv2/core/utils/logger.hpp>
 #include "opencv2/imgproc.hpp"
 #include "grfmt_avif.hpp"
 
@@ -242,6 +243,8 @@ bool AvifDecoder::readData(Mat &img) {
     return false;
```

Review comment:
Looks like timestamps are used differently in writemulti and writeanimation. If I got correctly, timestamps contains frame duration rather then timestamp. In this case, `timestamp` should not be incremented, but set equal to 10 once outside the loop. Also I recommends something like 33ms (fps).
**File:** modules/imgcodecs/src/grfmt_avif.cpp
**Change Type:** modified
**Context:** PR #25608: Animated WebP and AVIF Support

**Code Changes:**
```diff
@@ -11,6 +11,7 @@
 #include <memory>
 
 #include <opencv2/core/utils/configuration.private.hpp>
+#include <opencv2/core/utils/logger.hpp>
 #include "opencv2/imgproc.hpp"
 #include "grfmt_avif.hpp"
 
@@ -242,6 +243,8 @@ bool AvifDecoder::readData(Mat &img) {
     return false;
```

Review comment:
i removed the line `timestamp += 10;`
**File:** modules/imgcodecs/include/opencv2/imgcodecs.hpp
**Change Type:** modified
**Context:** PR #25608: Animated WebP and AVIF Support

**Code Changes:**
```diff
@@ -218,6 +218,36 @@ enum ImwriteHDRCompressionFlags {
 
 //! @} imgcodecs_flags
 
+/** @brief Represents an animation with multiple frames.
+The `Animation` struct is designed to store and manage data for animated sequences such as those from animated formats (e.g., GIF, AVIF, APNG, WebP).
+It provides support for looping, background color settings, frame timing, and frame storage.
+*/
+struct CV_EXPORTS_W_SIMPLE Animation
+{
```

Review comment:
Let it be BGRA as everywhere in OpenCV.
**File:** modules/imgcodecs/include/opencv2/imgcodecs.hpp
**Change Type:** modified
**Context:** PR #25608: Animated WebP and AVIF Support

**Code Changes:**
```diff
@@ -218,6 +218,36 @@ enum ImwriteHDRCompressionFlags {
 
 //! @} imgcodecs_flags
 
+/** @brief Represents an animation with multiple frames.
+The `Animation` struct is designed to store and manage data for animated sequences such as those from animated formats (e.g., GIF, AVIF, APNG, WebP).
+It provides support for looping, background color settings, frame timing, and frame storage.
+*/
+struct CV_EXPORTS_W_SIMPLE Animation
+{
```

Review comment:
Also you can use cv::Scalar.
**File:** modules/imgcodecs/src/grfmt_base.hpp
**Change Type:** modified
**Context:** PR #25608: Animated WebP and AVIF Support

**Code Changes:**
```diff
@@ -133,6 +133,8 @@ class BaseImageDecoder {
      */
     virtual bool checkSignature(const String& signature) const;
 
+    const Animation& animation() const { return m_animation; };
+
     /**
      * @brief Create and return a new instance of the derived image decoder.
      * @return A new ImageDecoder object.
@@ -151,6 +153,7 @@ class BaseImageDecoder {
```

Review comment:
That should be a `Animation&`. Maybe a `const Animation&` if it compiles.
**File:** modules/imgcodecs/src/grfmt_avif.cpp
**Change Type:** modified
**Context:** PR #25608: Animated WebP and AVIF Support

**Code Changes:**
```diff
@@ -11,6 +11,7 @@
 #include <memory>
 
 #include <opencv2/core/utils/configuration.private.hpp>
+#include <opencv2/core/utils/logger.hpp>
 #include "opencv2/imgproc.hpp"
 #include "grfmt_avif.hpp"
 
@@ -242,6 +243,8 @@ bool AvifDecoder::readData(Mat &img) {
     return false;
```

Review comment:
move this line to above avifEncoderAddImage because avifEncoderAddImage expects a duration, not a timestamp.
**File:** modules/core/src/opengl.cpp
**Change Type:** modified
**Context:** PR #26281: Rewrote OpenCL-OpenGL-interop device discovery routine without extensions and with Apple support
**Review Line:** 1671

**Code Changes:**
```diff
-    {
-        // query platform extension: presence of "cl_khr_gl_sharing" extension is required
-        {
-            AutoBuffer<char> extensionStr;
+        try {
+            devices = new cl_device_id[devCnt];
 
-            size_t extensionSize;
-            status = clGetPlatformInfo(platforms[i], CL_PLATFORM_EXTENSIONS, 0, NULL, &extensionSize);
-            if (status == CL_SUCCESS)
-            {
```

Review comment:
Let's use `std::vector<>` or `cv::AutoBuffer` for locals to prevent leaks.
**File:** modules/core/src/opengl.cpp
**Change Type:** modified
**Context:** PR #26281: Rewrote OpenCL-OpenGL-interop device discovery routine without extensions and with Apple support
**Review Line:** 1688

**Code Changes:**
```diff
+                if(extensionSize > 0)
+                {
+                    char* extensions = nullptr;
+
+                    try {
+                        extensions = new char[extensionSize];
+
+                        status = clGetDeviceInfo(devices[j], CL_DEVICE_EXTENSIONS, extensionSize, extensions, &extensionSize);
+                        if (status != CL_SUCCESS)
+                            continue;
+                    } catch(...) {
```

Review comment:
The same on memory management.
**File:** modules/core/src/opengl.cpp
**Change Type:** modified
**Context:** PR #26281: Rewrote OpenCL-OpenGL-interop device discovery routine without extensions and with Apple support
**Review Line:** 1724

**Code Changes:**
```diff
+                            oldPos = spacePos + 1;
+                            spacePos = devString.find(' ', oldPos);
+                        } while (spacePos == oldPos);
+                    }
+                }
+            }
+        } catch(...) {
+            CV_Error(cv::Error::OpenCLInitError, "OpenCL: Exception thrown during device information gathering");
+            if(devices != nullptr) {
+                delete[] devices;
+            }
```

Review comment:
Let's extract extension search as dedicated static function. It should make the code more readable.
**File:** modules/imgcodecs/src/grfmt_jpegxl.cpp
**Change Type:** added
**Context:** PR #26379: Add jxl (JPEG XL) codec support

**Code Changes:**
```diff
@@ -0,0 +1,420 @@
+// This file is part of OpenCV project.
+// It is subject to the license terms in the LICENSE file found in the top-level directory
+// of this distribution and at http://opencv.org/license.html.
+#include "precomp.hpp"
+#include "grfmt_jpegxl.hpp"
+
+#ifdef HAVE_JPEGXL
+
+#include <jxl/encode_cxx.h>
```

Review comment:
please use modern copyright header like in https://github.com/opencv/opencv/blob/4.x/modules/dnn/src/backend.cpp
**File:** modules/imgcodecs/src/grfmt_jpegxl.cpp
**Change Type:** added
**Context:** PR #26379: Add jxl (JPEG XL) codec support

**Code Changes:**
```diff
@@ -0,0 +1,420 @@
+// This file is part of OpenCV project.
+// It is subject to the license terms in the LICENSE file found in the top-level directory
+// of this distribution and at http://opencv.org/license.html.
+#include "precomp.hpp"
+#include "grfmt_jpegxl.hpp"
+
+#ifdef HAVE_JPEGXL
+
+#include <jxl/encode_cxx.h>
```

Review comment:
OpenCV supports IMREAD_COLOR_RGB flag to get RGB without conversion.
**File:** modules/imgcodecs/src/grfmt_jpegxl.cpp
**Change Type:** added
**Context:** PR #26379: Add jxl (JPEG XL) codec support

**Code Changes:**
```diff
@@ -0,0 +1,420 @@
+// This file is part of OpenCV project.
+// It is subject to the license terms in the LICENSE file found in the top-level directory
+// of this distribution and at http://opencv.org/license.html.
+#include "precomp.hpp"
+#include "grfmt_jpegxl.hpp"
+
+#ifdef HAVE_JPEGXL
+
+#include <jxl/encode_cxx.h>
```

Review comment:
I propose to use `num_worker_threads = cv::getNumThreads()` to make it manageable outside. See https://docs.opencv.org/4.x/db/de0/group__core__utils.html#ga2db334ec41d98da3129ef4a2342fc4d4
**File:** modules/imgcodecs/src/grfmt_jpegxl.cpp
**Change Type:** added
**Context:** PR #26379: Add jxl (JPEG XL) codec support

**Code Changes:**
```diff
@@ -0,0 +1,420 @@
+// This file is part of OpenCV project.
+// It is subject to the license terms in the LICENSE file found in the top-level directory
+// of this distribution and at http://opencv.org/license.html.
+#include "precomp.hpp"
+#include "grfmt_jpegxl.hpp"
+
+#ifdef HAVE_JPEGXL
+
+#include <jxl/encode_cxx.h>
```

Review comment:
OpenCV's `imread` is exception safe. Please use CV_LOG_WARNING and analogs and return satus instead of exception.
**File:** modules/imgcodecs/src/grfmt_jpegxl.cpp
**Change Type:** added
**Context:** PR #26379: Add jxl (JPEG XL) codec support

**Code Changes:**
```diff
@@ -0,0 +1,420 @@
+// This file is part of OpenCV project.
+// It is subject to the license terms in the LICENSE file found in the top-level directory
+// of this distribution and at http://opencv.org/license.html.
+#include "precomp.hpp"
+#include "grfmt_jpegxl.hpp"
+
+#ifdef HAVE_JPEGXL
+
+#include <jxl/encode_cxx.h>
```

Review comment:
cv::getNumThreads().
**File:** modules/imgcodecs/src/grfmt_jpegxl.cpp
**Change Type:** added
**Context:** PR #26379: Add jxl (JPEG XL) codec support

**Code Changes:**
```diff
@@ -0,0 +1,420 @@
+// This file is part of OpenCV project.
+// It is subject to the license terms in the LICENSE file found in the top-level directory
+// of this distribution and at http://opencv.org/license.html.
+#include "precomp.hpp"
+#include "grfmt_jpegxl.hpp"
+
+#ifdef HAVE_JPEGXL
+
+#include <jxl/encode_cxx.h>
```

Review comment:
Can you pls elaborate? An example?
**File:** cmake/OpenCVFindJPEGXL.cmake
**Change Type:** added
**Context:** PR #26379: Add jxl (JPEG XL) codec support
**Review Line:** 52

**Code Changes:**
```diff
+#]=======================================================================]
+
+if(NOT OPENCV_SKIP_JPEGXL_FIND_PACKAGE)
+find_package(PkgConfig QUIET)
+if (PkgConfig_FOUND)
+    pkg_check_modules(PC_JPEGXL QUIET jxl)
+    set(JPEGXL_COMPILE_OPTIONS ${PC_JPEGXL_CFLAGS_OTHER})
+    set(JPEGXL_VERSION ${PC_JPEGXL_VERSION})
+endif ()
+find_path(JPEGXL_INCLUDE_DIR
+    NAMES jxl/decode.h
```

Review comment:
I tried building standalone libjxl and it uses `libjxl` name for pkg-config, so this line fails to find it. I understand that this file is taken from another project, but perhaps we could tune it slightly for our needs. Another thing in my opinion is that it mixes pkg-config and separate `find_*` calls, it could result in mixing incompatible library versions - some found by pkg-config, others from system root. Maybe it would be better to add two blocks: ```.cmake # 1. try pkg-config pkg_check_modules(...) if(FOUND) # create targets using pc # success end() # 2. manual detection find_path(...) find_library(...) ... if(..all components were found...) # create targets using found components # success endif() ```
**File:** CMakeLists.txt
**Change Type:** modified
**Context:** PR #26379: Add jxl (JPEG XL) codec support

**Code Changes:**
```diff
@@ -306,6 +306,9 @@ OCV_OPTION(WITH_OPENJPEG "Include JPEG2K support (OpenJPEG)" ON
 OCV_OPTION(WITH_JPEG "Include JPEG support" ON
   VISIBLE_IF TRUE
   VERIFY HAVE_JPEG)
+OCV_OPTION(WITH_JPEGXL "Include JPEG XL support" OFF
+  VISIBLE_IF TRUE
+  VERIFY HAVE_JPEGXL)
 OCV_OPTION(WITH_WEBP "Include WebP support" ON
   VISIBLE_IF NOT WINRT
   VERIFY HAVE_WEBP)
```

Review comment:
Maybe we should turn it OFF by default for some time to stabilize this integration.
**File:** modules/imgcodecs/src/grfmt_jpegxl.cpp
**Change Type:** added
**Context:** PR #26379: Add jxl (JPEG XL) codec support
**Review Line:** 214

**Code Changes:**
```diff
+                }
+                if (!pimg)
+                    return true;
+                break;
+            }
+            case JXL_DEC_FULL_IMAGE: {
+                // Image is ready
+                if (m_convert != -1)
+                    cv::cvtColor(*pimg, *pimg, m_convert);
+                break;
+            }
```

Review comment:
Is it possible that this event will occure before `JXL_DEC_BASIC_INFO`? I didn't find this guarantee in the libjxl documentation.
**File:** cmake/OpenCVFindJPEGXL.cmake
**Change Type:** added
**Context:** PR #26379: Add jxl (JPEG XL) codec support
**Review Line:** 50

**Code Changes:**
```diff
+  this should be passed to target_compile_options(), if the
+  target is not used for linking
+#]=======================================================================]
+
+if(NOT OPENCV_SKIP_JPEGXL_FIND_PACKAGE)
+find_package(PkgConfig QUIET)
+if (PkgConfig_FOUND)
+    pkg_check_modules(PC_JPEGXL QUIET jxl)
+    set(JPEGXL_COMPILE_OPTIONS ${PC_JPEGXL_CFLAGS_OTHER})
+    set(JPEGXL_VERSION ${PC_JPEGXL_VERSION})
+endif ()
```

Review comment:
There is the same call in the root cmake-file: https://github.com/opencv/opencv/blob/6873bdee70528ba6101bd5f4091b5f5302ee70c9/CMakeLists.txt#L710 We don't need to repeat it here.
**File:** modules/imgcodecs/src/grfmt_jpegxl.cpp
**Change Type:** added
**Context:** PR #26379: Add jxl (JPEG XL) codec support
**Review Line:** 118

**Code Changes:**
```diff
+
+    // Create image if needed
+    if (m_type != -1 && pimg) {
+        pimg->create(m_height, m_width, m_type);
+        if (!pimg->isContinuous())
+            return false;
+        if (JXL_DEC_SUCCESS != JxlDecoderSetImageOutBuffer(m_decoder.get(),
+                                                           &m_format,
+                                                           pimg->ptr<uint8_t>(),
+                                                           pimg->total() * pimg->elemSize())) {
+            return false;
```

Review comment:
Log warning at least.
**File:** modules/imgcodecs/test/test_jpegxl.cpp
**Change Type:** added
**Context:** PR #26379: Add jxl (JPEG XL) codec support
**Review Line:** 37

**Code Changes:**
```diff
+            break;
+        default:
+        case CV_8U:
+            col = cv::Scalar(124, 76, 42, 192);
+            th = 3; // = 255 / 100 (1%);
+            break;
+    }
+
+    // If increasing distanceParam, threshold should be increased.
+    th *= (distanceParam >= 25) ? 5 : ( distanceParam > 2 ) ? 3 : (distanceParam == 2) ? 2: 1;
+
```

Review comment:
Add assert to default branch.
**File:** modules/imgcodecs/test/test_jpegxl.cpp
**Change Type:** added
**Context:** PR #26379: Add jxl (JPEG XL) codec support
**Review Line:** 85

**Code Changes:**
```diff
+            break;
+        default:
+        case CV_8U:
+            col = cv::Scalar(124, 76, 42, 192);
+            th = 3; // = 255 / 100 (1%);
+            break;
+    }
+
+    // If increasing distanceParam, threshold should be increased.
+    th *= (distanceParam >= 25) ? 5 : ( distanceParam > 2 ) ? 3 : (distanceParam == 2) ? 2: 1;
+
```

Review comment:
Add assert to default branch.
**File:** modules/core/test/test_mat.cpp
**Change Type:** modified
**Context:** PR #26254: Added extra tests for reshape
**Review Line:** 2687

**Code Changes:**
```diff
+    EXPECT_EQ(m.total(), v.size());
+
+    int sz[] = {(int)v.size()};
+    Mat m1 = m.reshape(0, 1, sz);
+    EXPECT_EQ(m1.dims, 1);
+    EXPECT_EQ(m1.type(), CV_32S);
+    EXPECT_EQ(m1.ptr<int>(), &v[0]);
+    EXPECT_EQ(m1.rows, 1);
+    EXPECT_EQ(m1.total(), v.size());
+
+    int sz3d[] = {2, -1, 3};
```

Review comment:
Signature for `_EQ` is `ASSERT_EQ(expected_reference, actual_result);`. Correct order of parameters are required to emit valid error messages. Reference: https://github.com/opencv/opencv/blob/4.0.0/modules/ts/include/opencv2/ts/ts_gtest.h#L8196-L8200 ``` GTEST_API_ AssertionResult EqFailure(const char* expected_expression, const char* actual_expression, const std::string& expected_value, const std::string& actual_value, bool ignoring_case); ```
**File:** modules/core/test/test_mat.cpp
**Change Type:** modified
**Context:** PR #26254: Added extra tests for reshape

**Code Changes:**
```diff
@@ -2669,4 +2669,219 @@ TEST(Mat, regression_26322)
     EXPECT_EQ(0, (int)mat3.total());
 }
 
+TEST(Mat, reshape_1d)
+{
+    std::vector<int> v = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
+    int newrows = 2;
+    Mat m = Mat(v).reshape(0, newrows);
+
```

Review comment:
It should be just 2, but not `newrows`. They are not correlated.
**File:** modules/core/test/test_mat.cpp
**Change Type:** modified
**Context:** PR #26254: Added extra tests for reshape

**Code Changes:**
```diff
@@ -2669,4 +2669,219 @@ TEST(Mat, regression_26322)
     EXPECT_EQ(0, (int)mat3.total());
 }
 
+TEST(Mat, reshape_1d)
+{
+    std::vector<int> v = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
+    int newrows = 2;
+    Mat m = Mat(v).reshape(0, newrows);
+
```

Review comment:
The same newrows -> 2.
**File:** modules/core/src/umatrix.cpp
**Change Type:** modified
**Context:** PR #26254: Added extra tests for reshape

**Code Changes:**
```diff
@@ -1063,9 +1063,6 @@ UMat UMat::reshape(int new_cn, int new_rows) const
             CV_Error( cv::Error::BadStep,
             "The matrix is not continuous, thus its number of rows can not be changed" );
 
-        if( (unsigned)new_rows > (unsigned)total_size )
-            CV_Error( cv::Error::StsOutOfRange, "Bad new number of rows" );
-
         total_width = total_size / new_rows;
 
         if( total_width * new_rows != total_size )
```

Review comment:
should it be a part of dst.create()?
**File:** modules/core/src/matrix.cpp
**Change Type:** modified
**Context:** PR #26254: Added extra tests for reshape
**Review Line:** 1743

**Code Changes:**
```diff
-        if( new_rows > 0 )
-        {
-            int sz[] = { new_rows, (int)(total()*cn/new_rows) };
-            return reshape(new_cn, 2, sz);
-        }
+        CV_Assert( new_rows > 0 );
+        int sz[] = { new_rows, (int)(total()*cn/new_rows) };
+        return reshape(new_cn, 2, sz);
     }
 
-    CV_Assert( dims <= 2 );
```

Review comment:
Looks like the assert is redundant here. if (new_rows == 0) leads to return.
**File:** modules/core/src/matrix.cpp
**Change Type:** modified
**Context:** PR #26254: Added extra tests for reshape
**Review Line:** 1743

**Code Changes:**
```diff
-        if( new_rows > 0 )
-        {
-            int sz[] = { new_rows, (int)(total()*cn/new_rows) };
-            return reshape(new_cn, 2, sz);
-        }
+        CV_Assert( new_rows > 0 );
+        int sz[] = { new_rows, (int)(total()*cn/new_rows) };
+        return reshape(new_cn, 2, sz);
     }
 
-    CV_Assert( dims <= 2 );
```

Review comment:
what about `new_rows < 0` case? we should handle 'bad args' somehow
**File:** modules/core/src/umatrix.cpp
**Change Type:** modified
**Context:** PR #26254: Added extra tests for reshape

**Code Changes:**
```diff
@@ -1063,9 +1063,6 @@ UMat UMat::reshape(int new_cn, int new_rows) const
             CV_Error( cv::Error::BadStep,
             "The matrix is not continuous, thus its number of rows can not be changed" );
 
-        if( (unsigned)new_rows > (unsigned)total_size )
-            CV_Error( cv::Error::StsOutOfRange, "Bad new number of rows" );
-
         total_width = total_size / new_rows;
 
         if( total_width * new_rows != total_size )
```

Review comment:
please, look more carefully. This is called _after_ release(), not after create(). I found that empty matrix is not copied correctly, type is replaced with 'CV_8U', which is wrong in general. This code fixes it.
**File:** modules/core/test/test_io.cpp
**Change Type:** modified
**Context:** PR #26446: Empty Mat in FileStorage

**Code Changes:**
```diff
@@ -2018,7 +2018,25 @@ T fsWriteRead(const T& expectedValue, const char* ext)
     return value;
 }
 
+void testExactMat(const Mat& src, const char* ext)
+{
+    bool srcIsEmpty = src.empty();
+    Mat dst = fsWriteRead(src, ext);
+    EXPECT_EQ(dst.empty(), srcIsEmpty);
+    EXPECT_EQ(src.dims, dst.dims);
```

Review comment:
We do not have 1d Mat support in 4.x. 2+d only.