nareshmlx/opencv-pr huggingface dataset:
**File:** modules/photo/src/ccm/ccm.cpp
**Change Type:** added
**Context:** PR #27051: Adding color correction module to photo module from opencv_contrib

**Code Changes:**
```diff
@@ -0,0 +1,557 @@
+// 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.
+//
+// Author: Longbu Wang <wanglongbu@huawei.com.com>
+//         Jinheng Zhang <zhangjinheng1@huawei.com>
+//         Chenqi Shan <shanchenqi@huawei.com>
+
+#include "opencv2/photo.hpp"
```

Review comment:
You add even more operations with memory. simgle mixChannels without split and merge can do it.
**File:** modules/photo/src/ccm/ccm.cpp
**Change Type:** added
**Context:** PR #27051: Adding color correction module to photo module from opencv_contrib

**Code Changes:**
```diff
@@ -0,0 +1,557 @@
+// 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.
+//
+// Author: Longbu Wang <wanglongbu@huawei.com.com>
+//         Jinheng Zhang <zhangjinheng1@huawei.com>
+//         Chenqi Shan <shanchenqi@huawei.com>
+
+#include "opencv2/photo.hpp"
```

Review comment:
The code with ccm0 and coeffs looks very cryptic. I proposr to create ccm0 with proper shape with zeros , e.g. cv::Mat::zeros() and then set non-zero values for it. It's less amount of code, but there is no strange resize/reshape and `shape/3` values.
**File:** modules/photo/src/ccm/utils.hpp
**Change Type:** added
**Context:** PR #27051: Adding color correction module to photo module from opencv_contrib

**Code Changes:**
```diff
@@ -0,0 +1,145 @@
+// 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.
+//
+// Author: Longbu Wang <wanglongbu@huawei.com.com>
+//         Jinheng Zhang <zhangjinheng1@huawei.com>
+//         Chenqi Shan <shanchenqi@huawei.com>
+
+#ifndef __OPENCV_CCM_UTILS_HPP__
```

Review comment:
It should go to make ccm header to be included into documentation and bindings. Please CV_EXPORTS_W to generate Java and Python bindings for it too.
**File:** modules/photo/src/ccm/utils.cpp
**Change Type:** added
**Context:** PR #27051: Adding color correction module to photo module from opencv_contrib
**Review Line:** 111

**Code Changes:**
```diff
+    Mat mask;
+    inRange(src, lower_bound, upper_bound, mask);
+    mask /= 255;
+
+    return mask;
+}
+}
+}  // namespace cv::ccm
```

Review comment:
The function needs the mask as an output of values in upper bound and lower bound. I don't think this can be replaced
**File:** modules/photo/src/ccm/operations.cpp
**Change Type:** added
**Context:** PR #27051: Adding color correction module to photo module from opencv_contrib
**Review Line:** 50

**Code Changes:**
```diff
+{
+    ops.insert(ops.end(), other.ops.begin(), other.ops.end());
+    return *this;
+};
+
+Mat Operations::run(Mat abc)
+{
+    Operation hd;
+    for (auto& op : ops)
+    {
+        if (op.linear)
```

Review comment:
I tried it, but it cannot be replaced by Mat&
**File:** modules/photo/include/opencv2/photo/ccm.hpp
**Change Type:** added
**Context:** PR #27051: Adding color correction module to photo module from opencv_contrib

**Code Changes:**
```diff
@@ -0,0 +1,322 @@
+// 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.
+//
+// Author: Longbu Wang <wanglongbu@huawei.com.com>
+//         Jinheng Zhang <zhangjinheng1@huawei.com>
+//         Chenqi Shan <shanchenqi@huawei.com>
+
+#ifndef OPENCV_PHOTO_CCM_HPP
```

Review comment:
`\n` is not needed here and other documentation strings.
**File:** modules/photo/perf/perf_ccm.cpp
**Change Type:** added
**Context:** PR #27051: Adding color correction module to photo module from opencv_contrib
**Review Line:** 41

**Code Changes:**
```diff
+PERF_TEST(CV_ccm_perf_720_1280, correctImage)
+{
+    string path = cvtest::findDataFile("cv/mcc/mcc_ccm_test.yml");
+    FileStorage fs(path, FileStorage::READ);
+    Mat chartsRGB;
+    fs["chartsRGB"] >> chartsRGB;
+    fs.release();
+    ASSERT_FALSE(chartsRGB.empty()) << "chartsRGB is empty after loading from: " << path;
+
+    cv::ccm::ColorCorrectionModel model(
+        chartsRGB.col(1).clone().reshape(3, chartsRGB.rows/3) / 255.0,
```

Review comment:
`ASSERT_FALSE(chartsRGB.empty());` here and bellow.
**File:** samples/cpp/color_correction_model.cpp
**Change Type:** added
**Context:** PR #27051: Adding color correction module to photo module from opencv_contrib

**Code Changes:**
```diff
@@ -0,0 +1,224 @@
+//! [tutorial]
+#include <opencv2/core.hpp>
+#include <opencv2/highgui.hpp>
+#include <opencv2/imgcodecs.hpp>
+#include <opencv2/imgproc.hpp>
+#include <opencv2/photo.hpp>
+#include <opencv2/objdetect.hpp>
+#include <opencv2/dnn.hpp>
+#include <iostream>
```

Review comment:
I propose to Move BRG/RGB logic into model with a flag (default to bgr). All OpenCV functions are designed for BGR. The flag allows to make optimizations without API change.
**File:** modules/photo/src/ccm/linearize.cpp
**Change Type:** added
**Context:** PR #27051: Adding color correction module to photo module from opencv_contrib

**Code Changes:**
```diff
@@ -0,0 +1,284 @@
+// 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.
+//
+// Author: Longbu Wang <wanglongbu@huawei.com.com>
+//         Jinheng Zhang <zhangjinheng1@huawei.com>
+//         Chenqi Shan <shanchenqi@huawei.com>
+
+#include "linearize.hpp"
```

Review comment:
`make_shared<>`
**File:** modules/photo/src/ccm/utils.cpp
**Change Type:** added
**Context:** PR #27051: Adding color correction module to photo module from opencv_contrib
**Review Line:** 16

**Code Changes:**
```diff
+namespace cv {
+namespace ccm {
+
+void gammaCorrection(InputArray _src, OutputArray _dst, double gamma)
+{
+    Mat src = _src.getMat();
+    CV_Assert(gamma > 0);
+
+    double  maxVal;
+    int     depth = src.depth();
+    switch (depth)
```

Review comment:
It's still relevant.
**File:** modules/photo/src/ccm/utils.hpp
**Change Type:** added
**Context:** PR #27051: Adding color correction module to photo module from opencv_contrib
**Review Line:** 39

**Code Changes:**
```diff
+/** @brief multiple the function used to compute an array with n channels
+      mulipied by ccm.
+    @param xyz the input array, type of Mat.
+    @param ccm the ccm matrix to make color correction.
+ */
+Mat multiple(const Mat& xyz, const Mat& ccm);
+
+/** @brief multiple the function used to get the mask of saturated colors,
+            colors between low and up will be choosed.
+    @param src the input array, type of Mat.
+    @param low  the threshold to choose saturated colors
```

Review comment:
Still relevant.
**File:** modules/objdetect/include/opencv2/objdetect.hpp
**Change Type:** modified
**Context:** PR #24426: Consider QRCode ECI encoding

**Code Changes:**
```diff
@@ -729,7 +729,8 @@ class CV_EXPORTS_W QRCodeEncoder {
     };
 
     enum ECIEncodings {
-        ECI_UTF8 = 26
+        ECI_SHIFT_JIS = 20,
+        ECI_UTF8 = 26,
     };
 
     /** @brief QR code encoder parameters. */
```

Review comment:
This enum confuses a bit
**File:** modules/objdetect/include/opencv2/objdetect.hpp
**Change Type:** modified
**Context:** PR #24426: Consider QRCode ECI encoding

**Code Changes:**
```diff
@@ -729,7 +729,8 @@ class CV_EXPORTS_W QRCodeEncoder {
     };
 
     enum ECIEncodings {
-        ECI_UTF8 = 26
+        ECI_SHIFT_JIS = 20,
+        ECI_UTF8 = 26,
     };
 
     /** @brief QR code encoder parameters. */
```

Review comment:
m.b. latest frame or latest detectAndDecode call.
**File:** modules/objdetect/src/qrcode.cpp
**Change Type:** modified
**Context:** PR #24426: Consider QRCode ECI encoding

**Code Changes:**
```diff
@@ -963,6 +963,7 @@ struct ImplContour : public GraphicalCodeDetector::Impl
     double epsX, epsY;
     mutable vector<vector<Point2f>> alignmentMarkers;
     mutable vector<Point2f> updateQrCorners;
+    mutable vector<QRCodeEncoder::ECIEncodings> encodings;
     bool useAlignmentMarkers = true;
 
     bool detect(InputArray in, OutputArray points) const override;
@@ -978,6 +979,8 @@ struct ImplContour : public GraphicalCodeDetector::Impl
     String decodeCurved(InputArray in, InputArray points, OutputArray straight_qrcode);
```

Review comment:
why not just int for codeIdx + assert? Unsigned types is a pain for Java.
**File:** modules/objdetect/misc/java/gen_dict.json
**Change Type:** added
**Context:** PR #24426: Consider QRCode ECI encoding

**Code Changes:**
```diff
@@ -0,0 +1,68 @@
+{
+    "ManualFuncs" : {
+        "QRCodeEncoder" : {
+            "QRCodeEncoder" : {
+                "j_code"   : [
+                    "\n",
+                    "/** Generates QR code from input string.",
+                    "@param encoded_info Input bytes to encode.",
+                    "@param qrcode Generated QR code.",
```

Review comment:
The comments are not related.
**File:** modules/objdetect/include/opencv2/objdetect/graphical_code_detector.hpp
**Change Type:** modified
**Context:** PR #24426: Consider QRCode ECI encoding

**Code Changes:**
```diff
@@ -73,6 +73,17 @@ class CV_EXPORTS_W_SIMPLE GraphicalCodeDetector {
     */
     CV_WRAP bool detectAndDecodeMulti(InputArray img, CV_OUT std::vector<std::string>& decoded_info, OutputArray points = noArray(),
                                       OutputArrayOfArrays straight_code = noArray()) const;
+
+#ifdef OPENCV_BINDINGS_PARSER
+    CV_WRAP_AS(detectAndDecodeBytes) NativeByteArray detectAndDecode(InputArray img, OutputArray points = noArray(),
+                                                                     OutputArray straight_code = noArray()) const;
+    CV_WRAP_AS(decodeBytes) NativeByteArray decode(InputArray img, InputArray points, OutputArray straight_code = noArray()) const;
+    CV_WRAP_AS(decodeBytesMulti) bool decodeMulti(InputArray img, InputArray points, CV_OUT std::vector<NativeByteArray>& decoded_info,
```

Review comment:
Java bindings use just cv::Mat for it. There is MatOfBytes specialization. M.b. reuse it too?
**File:** modules/objdetect/include/opencv2/objdetect/graphical_code_detector.hpp
**Change Type:** modified
**Context:** PR #24426: Consider QRCode ECI encoding

**Code Changes:**
```diff
@@ -73,6 +73,17 @@ class CV_EXPORTS_W_SIMPLE GraphicalCodeDetector {
     */
     CV_WRAP bool detectAndDecodeMulti(InputArray img, CV_OUT std::vector<std::string>& decoded_info, OutputArray points = noArray(),
                                       OutputArrayOfArrays straight_code = noArray()) const;
+
+#ifdef OPENCV_BINDINGS_PARSER
+    CV_WRAP_AS(detectAndDecodeBytes) NativeByteArray detectAndDecode(InputArray img, OutputArray points = noArray(),
+                                                                     OutputArray straight_code = noArray()) const;
+    CV_WRAP_AS(decodeBytes) NativeByteArray decode(InputArray img, InputArray points, OutputArray straight_code = noArray()) const;
+    CV_WRAP_AS(decodeBytesMulti) bool decodeMulti(InputArray img, InputArray points, CV_OUT std::vector<NativeByteArray>& decoded_info,
```

Review comment:
In such way user should call an extra method: ```java MatOfByte output = detector.detectAndDecodeBytes(qrcode); new String(output.toArray(), "Shift_JIS")); ```
**File:** modules/objdetect/src/qrcode.cpp
**Change Type:** modified
**Context:** PR #24426: Consider QRCode ECI encoding

**Code Changes:**
```diff
@@ -963,6 +963,7 @@ struct ImplContour : public GraphicalCodeDetector::Impl
     double epsX, epsY;
     mutable vector<vector<Point2f>> alignmentMarkers;
     mutable vector<Point2f> updateQrCorners;
+    mutable vector<QRCodeEncoder::ECIEncodings> encodings;
     bool useAlignmentMarkers = true;
 
     bool detect(InputArray in, OutputArray points) const override;
@@ -978,6 +979,8 @@ struct ImplContour : public GraphicalCodeDetector::Impl
     String decodeCurved(InputArray in, InputArray points, OutputArray straight_qrcode);
```

Review comment:
It makes resize/reserve `encodings` vector first to reduce reallocs.
**File:** modules/java/generator/android-21/java/org/opencv/android/JavaCamera2View.java
**Change Type:** modified
**Context:** PR #27419: Fixed Android setCameraIndex issue.

**Code Changes:**
```diff
@@ -96,8 +96,10 @@ protected boolean selectCamera() {
                 Log.e(LOGTAG, "Error: camera isn't detected.");
                 return false;
             }
+            boolean chosen = false;  // remember whether the camera ID is set.
             if (mCameraIndex == CameraBridgeViewBase.CAMERA_ID_ANY) {
                 mCameraID = camList[0];
+                chosen = true;
             } else {
                 for (String cameraID : camList) {
```

Review comment:
`chosen`
**File:** modules/videoio/misc/java/test/VideoCaptureTest.java
**Change Type:** modified
**Context:** PR #27421: Cover all seek directions in VideoCapture Java test

**Code Changes:**
```diff
@@ -123,6 +123,10 @@ public long seek(long offset, int origin)
                 {
                     if (origin == 0)
                         f.seek(offset);
+                    else if (origin == 1)
+                        f.seek(f.getFilePointer() + offset);
+                    else if (origin == 2)
+                        f.seek(f.length() + offset);
                     return f.getFilePointer();
                 }
```

Review comment:
`(0, SEEK_END)` should point to `f.length()` not `f.length() - 1`
**File:** modules/dnn/CMakeLists.txt
**Change Type:** modified
**Context:** PR #27428: Cmake protobuf_generate_cpp deprecated use protobuf_generate

**Code Changes:**
```diff
@@ -115,8 +115,22 @@ if(HAVE_PROTOBUF)
 
   if(PROTOBUF_UPDATE_FILES)
     file(GLOB proto_files "${CMAKE_CURRENT_LIST_DIR}/src/tensorflow/*.proto" "${CMAKE_CURRENT_LIST_DIR}/src/caffe/opencv-caffe.proto" "${CMAKE_CURRENT_LIST_DIR}/src/onnx/opencv-onnx.proto")
-    set(PROTOBUF_GENERATE_CPP_APPEND_PATH ON) # required for tensorflow
-    protobuf_generate_cpp(fw_srcs fw_hdrs ${proto_files})
+    if(CMAKE_VERSION VERSION_LESS "3.13.0")
+      set(PROTOBUF_GENERATE_CPP_APPEND_PATH ON) # required for tensorflow
+      protobuf_generate_cpp(fw_srcs fw_hdrs ${proto_files})
+    else()
```

Review comment:
> protobuf_generate Added in version 3.13. It breaks build with older CMake. I propose to add CMake version check and presume the old branch for old CMake.
**File:** hal/ipp/include/ipp_hal_core.hpp
**Change Type:** modified
**Context:** PR #27354: Update IPP integration - Please merge together with https://github.com/opencv/opencv_3rdparty/pull/96 Supported IPP version was updated to ...
**Review Line:** 20

**Code Changes:**
```diff
@@ -17,15 +17,18 @@ int ipp_hal_minMaxIdxMaskStep(const uchar* src_data, size_t src_step, int width,
 #undef cv_hal_minMaxIdxMaskStep
 #define cv_hal_minMaxIdxMaskStep ipp_hal_minMaxIdxMaskStep
 
-#define IPP_DISABLE_NORM_8U             1 // accuracy difference in perf test sanity check
+#if (IPP_VERSION_X100 == 202200)
+# define IPP_DISABLE_NORM_8U             1 // accuracy difference in perf test sanity check
+# else
+# define IPP_DISABLE_NORM_8U             0
+#endif
 
```

Review comment:
There is still old versions (e.g. Apple Mac, Linux 32-bit) Also there are generic IPP releases, which may behave in different way and may have these "old" issues. Could you please add version check instead (with using of `HAVE_IPP_ICV` if necessary)?
**File:** hal/ipp/include/ipp_hal_core.hpp
**Change Type:** modified
**Context:** PR #27354: Update IPP integration - Please merge together with https://github.com/opencv/opencv_3rdparty/pull/96 Supported IPP version was updated to ...
**Review Line:** 20

**Code Changes:**
```diff
@@ -17,15 +17,18 @@ int ipp_hal_minMaxIdxMaskStep(const uchar* src_data, size_t src_step, int width,
 #undef cv_hal_minMaxIdxMaskStep
 #define cv_hal_minMaxIdxMaskStep ipp_hal_minMaxIdxMaskStep
 
-#define IPP_DISABLE_NORM_8U             1 // accuracy difference in perf test sanity check
+#if (IPP_VERSION_X100 == 202200)
+# define IPP_DISABLE_NORM_8U             1 // accuracy difference in perf test sanity check
+# else
+# define IPP_DISABLE_NORM_8U             0
+#endif
 
```

Review comment:
I've returned it, but comparison with only one version, because the issue appeared only in the previous update, which is already was done for 64-bit Linux and Windows only.
**File:** modules/imgproc/src/distransform.cpp
**Change Type:** modified
**Context:** PR #24535: Handle huge images in IPP distanceTransform

**Code Changes:**
```diff
@@ -817,14 +817,15 @@ void cv::distanceTransform( InputArray _src, OutputArray _dst, OutputArray _labe
     Size size = src.size();
 
     int border = maskSize == CV_DIST_MASK_3 ? 1 : 2;
-    Mat temp( size.height + border*2, size.width + border*2, CV_32SC1 );
+    Mat temp;
 
     if( !need_labels )
     {
         if( maskSize == CV_DIST_MASK_3 )
```

Review comment:
Need to check how it worked with ROI dst before.
**File:** modules/imgproc/src/distransform.cpp
**Change Type:** modified
**Context:** PR #24535: Handle huge images in IPP distanceTransform

**Code Changes:**
```diff
@@ -817,14 +817,15 @@ void cv::distanceTransform( InputArray _src, OutputArray _dst, OutputArray _labe
     Size size = src.size();
 
     int border = maskSize == CV_DIST_MASK_3 ? 1 : 2;
-    Mat temp( size.height + border*2, size.width + border*2, CV_32SC1 );
+    Mat temp;
 
     if( !need_labels )
     {
         if( maskSize == CV_DIST_MASK_3 )
```

Review comment:
probably related to this discussion: https://github.com/opencv/opencv/issues/12018. Changed check to INT_MAX overflow
**File:** modules/imgproc/src/distransform.cpp
**Change Type:** modified
**Context:** PR #24535: Handle huge images in IPP distanceTransform

**Code Changes:**
```diff
@@ -817,14 +817,15 @@ void cv::distanceTransform( InputArray _src, OutputArray _dst, OutputArray _labe
     Size size = src.size();
 
     int border = maskSize == CV_DIST_MASK_3 ? 1 : 2;
-    Mat temp( size.height + border*2, size.width + border*2, CV_32SC1 );
+    Mat temp;
 
     if( !need_labels )
     {
         if( maskSize == CV_DIST_MASK_3 )
```

Review comment:
the right link about `isContinuous()` mess: #11505
**File:** modules/videoio/src/cap_ffmpeg_impl.hpp
**Change Type:** modified
**Context:** PR #27153: fix #26276: cv::VideoWriter fails writing colorless images

**Code Changes:**
```diff
@@ -2525,11 +2525,13 @@ bool CvVideoWriter_FFMPEG::writeFrame( const unsigned char* data, int step, int
     // check parameters
     if (input_pix_fmt == AV_PIX_FMT_BGR24) {
         if (cn != 3) {
+            CV_LOG_WARNING(NULL, "write frame skipped - expected 3 channels but got " << cn);
             return false;
         }
     }
     else if (input_pix_fmt == AV_PIX_FMT_GRAY8 || input_pix_fmt == AV_PIX_FMT_GRAY16LE) {
         if (cn != 1) {
```

Review comment:
In case of `encode_video = False` we should accept only raw bytes arrays. So we should have CV_8UC1 data type only. Expected layout is 1xN or Nx1. This change must be reverted.
**File:** modules/videoio/src/cap_ffmpeg_impl.hpp
**Change Type:** modified
**Context:** PR #27153: fix #26276: cv::VideoWriter fails writing colorless images

**Code Changes:**
```diff
@@ -2525,11 +2525,13 @@ bool CvVideoWriter_FFMPEG::writeFrame( const unsigned char* data, int step, int
     // check parameters
     if (input_pix_fmt == AV_PIX_FMT_BGR24) {
         if (cn != 3) {
+            CV_LOG_WARNING(NULL, "write frame skipped - expected 3 channels but got " << cn);
             return false;
         }
     }
     else if (input_pix_fmt == AV_PIX_FMT_GRAY8 || input_pix_fmt == AV_PIX_FMT_GRAY16LE) {
         if (cn != 1) {
```

Review comment:
> inputMat ... inputMat "In-place" ops should not be used in general (causes extra `.clone()` call).
**File:** modules/videoio/src/cap_ffmpeg_impl.hpp
**Change Type:** modified
**Context:** PR #27153: fix #26276: cv::VideoWriter fails writing colorless images

**Code Changes:**
```diff
@@ -2525,11 +2525,13 @@ bool CvVideoWriter_FFMPEG::writeFrame( const unsigned char* data, int step, int
     // check parameters
     if (input_pix_fmt == AV_PIX_FMT_BGR24) {
         if (cn != 3) {
+            CV_LOG_WARNING(NULL, "write frame skipped - expected 3 channels but got " << cn);
             return false;
         }
     }
     else if (input_pix_fmt == AV_PIX_FMT_GRAY8 || input_pix_fmt == AV_PIX_FMT_GRAY16LE) {
         if (cn != 1) {
```

Review comment:
What is about other cases? 16UC3?
**File:** modules/videoio/src/cap_ffmpeg_impl.hpp
**Change Type:** modified
**Context:** PR #27153: fix #26276: cv::VideoWriter fails writing colorless images

**Code Changes:**
```diff
@@ -2525,11 +2525,13 @@ bool CvVideoWriter_FFMPEG::writeFrame( const unsigned char* data, int step, int
     // check parameters
     if (input_pix_fmt == AV_PIX_FMT_BGR24) {
         if (cn != 3) {
+            CV_LOG_WARNING(NULL, "write frame skipped - expected 3 channels but got " << cn);
             return false;
         }
     }
     else if (input_pix_fmt == AV_PIX_FMT_GRAY8 || input_pix_fmt == AV_PIX_FMT_GRAY16LE) {
         if (cn != 1) {
```

Review comment:
Good point. I had focused only on the explicitly supported types (CV_8UC1, CV_16UC1, CV_8UC3) and overlooked the possibility of unsupported inputs like CV_16UC3. I’ll address this as well.
**File:** modules/videoio/src/cap_ffmpeg_impl.hpp
**Change Type:** modified
**Context:** PR #27153: fix #26276: cv::VideoWriter fails writing colorless images

**Code Changes:**
```diff
@@ -2525,11 +2525,13 @@ bool CvVideoWriter_FFMPEG::writeFrame( const unsigned char* data, int step, int
     // check parameters
     if (input_pix_fmt == AV_PIX_FMT_BGR24) {
         if (cn != 3) {
+            CV_LOG_WARNING(NULL, "write frame skipped - expected 3 channels but got " << cn);
             return false;
         }
     }
     else if (input_pix_fmt == AV_PIX_FMT_GRAY8 || input_pix_fmt == AV_PIX_FMT_GRAY16LE) {
         if (cn != 1) {
```

Review comment:
This is a part of external API (`cap_ffmpeg_legacy_api.hpp`), we can't just change parameters meaning.
**File:** modules/videoio/src/cap_ffmpeg_impl.hpp
**Change Type:** modified
**Context:** PR #27153: fix #26276: cv::VideoWriter fails writing colorless images

**Code Changes:**
```diff
@@ -2525,11 +2525,13 @@ bool CvVideoWriter_FFMPEG::writeFrame( const unsigned char* data, int step, int
     // check parameters
     if (input_pix_fmt == AV_PIX_FMT_BGR24) {
         if (cn != 3) {
+            CV_LOG_WARNING(NULL, "write frame skipped - expected 3 channels but got " << cn);
             return false;
         }
     }
     else if (input_pix_fmt == AV_PIX_FMT_GRAY8 || input_pix_fmt == AV_PIX_FMT_GRAY16LE) {
         if (cn != 1) {
```

Review comment:
I completely missed that detail... As its part of external API, I'm going to revert it back to using the number of channels
**File:** modules/core/test/test_mat.cpp
**Change Type:** modified
**Context:** PR #27362: Fix empty ND-array construction
**Review Line:** 1466

**Code Changes:**
```diff
+    EXPECT_LE(mat_nd.total(), 1u);
+    EXPECT_FALSE(mat_nd.empty());
+#endif
+    EXPECT_EQ(mat.total(), 0u);
+    EXPECT_TRUE(mat.empty());
+}
+
 TEST(Core_InputArray, empty)
 {
     vector<vector<Point> > data;
```

Review comment:
suggest to add some checks to the test: ``` TEST(Core_Mat, empty) { // Should not crash. uint8_t data[2] = {0, 1}; cv::Mat mat_nd(/*ndims=*/0, /*sizes=*/nullptr, CV_8UC1, /*data=*/data); cv::Mat1b mat(0, 0, /*data=*/data, /*steps=*/1); EXPECT_EQ(mat_nd.dims, 0); EXPECT_EQ(mat.dims, 2); EXPECT_LE(mat_nd.total(), 1u); // 0 for 4.x, 1 for 5.x EXPECT_EQ(mat.total(), 0u); EXPECT_TRUE(mat.empty()); // mat_nd.empty() should return true for 4.x and false for 5.x } ```