1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-30 07:43:03 +04:00

Merge branch 4.x

This commit is contained in:
Alexander Smorkalov
2025-12-02 15:22:25 +03:00
56 changed files with 1639 additions and 876 deletions
@@ -113,7 +113,7 @@ enum ImwriteFlags {
IMWRITE_TIFF_PREDICTOR = 317,//!< For TIFF, use to specify predictor. See cv::ImwriteTiffPredictorFlags. Default is IMWRITE_TIFF_PREDICTOR_HORIZONTAL .
IMWRITE_JPEG2000_COMPRESSION_X1000 = 272,//!< For JPEG2000, use to specify the target compression rate (multiplied by 1000). The value can be from 0 to 1000. Default is 1000.
IMWRITE_AVIF_QUALITY = 512,//!< For AVIF, it can be a quality between 0 and 100 (the higher the better). Default is 95.
IMWRITE_AVIF_DEPTH = 513,//!< For AVIF, it can be 8, 10 or 12. If >8, it is stored/read as CV_32F. Default is 8.
IMWRITE_AVIF_DEPTH = 513,//!< For AVIF, it can be 8, 10 or 12. If >8, it is stored/read as CV_16U. Default is 8.
IMWRITE_AVIF_SPEED = 514,//!< For AVIF, it is between 0 (slowest) and 10(fastest). Default is 9.
IMWRITE_JPEGXL_QUALITY = 640,//!< For JPEG XL, it can be a quality from 0 to 100 (the higher is the better). Default value is 95. If set, distance parameter is re-calicurated from quality level automatically. This parameter request libjxl v0.10 or later.
IMWRITE_JPEGXL_EFFORT = 641,//!< For JPEG XL, encoder effort/speed level without affecting decoding speed; it is between 1 (fastest) and 10 (slowest). Default is 7.
@@ -539,6 +539,11 @@ can be saved using this function, with these exceptions:
To achieve this, create an 8-bit 4-channel (CV_8UC4) BGRA image, ensuring the alpha channel is the last component.
Fully transparent pixels should have an alpha value of 0, while fully opaque pixels should have an alpha value of 255.
- 8-bit single-channel images (CV_8UC1) are not supported due to GIF's limitation to indexed color formats.
- With AVIF encoder, 8-bit unsigned (CV_8U) and 16-bit unsigned (CV_16U) images can be saved.
- CV_16U images can be saved as only 10-bit or 12-bit (not 16-bit). See IMWRITE_AVIF_DEPTH.
- AVIF images with an alpha channel can be saved using this function.
To achieve this, create an 8-bit 4-channel (CV_8UC4) / 16-bit 4-channel (CV_16UC4) BGRA image, ensuring the alpha channel is the last component.
Fully transparent pixels should have an alpha value of 0, while fully opaque pixels should have an alpha value of 255 (8-bit) / 1023 (10-bit) / 4095 (12-bit) (see the code sample below).
If the image format is not supported, the image will be converted to 8-bit unsigned (CV_8U) and saved that way.
+19 -20
View File
@@ -86,15 +86,12 @@ AvifImageUniquePtr ConvertToAvif(const cv::Mat &img, bool lossless, int bit_dept
result->yuvFormat = AVIF_PIXEL_FORMAT_YUV400;
result->colorPrimaries = AVIF_COLOR_PRIMARIES_UNSPECIFIED;
result->transferCharacteristics = AVIF_TRANSFER_CHARACTERISTICS_UNSPECIFIED;
result->matrixCoefficients = AVIF_MATRIX_COEFFICIENTS_IDENTITY;
result->matrixCoefficients = AVIF_MATRIX_COEFFICIENTS_UNSPECIFIED;
result->yuvRange = AVIF_RANGE_FULL;
result->yuvPlanes[0] = img.data;
result->yuvRowBytes[0] = img.step[0];
result->imageOwnsYUVPlanes = AVIF_FALSE;
return AvifImageUniquePtr(result);
}
if (lossless) {
} else if (lossless) {
result =
avifImageCreate(width, height, bit_depth, AVIF_PIXEL_FORMAT_YUV444);
if (result == nullptr) return nullptr;
@@ -139,22 +136,24 @@ AvifImageUniquePtr ConvertToAvif(const cv::Mat &img, bool lossless, int bit_dept
#endif
}
avifRGBImage rgba;
avifRGBImageSetDefaults(&rgba, result);
if (img.channels() == 3) {
rgba.format = AVIF_RGB_FORMAT_BGR;
} else {
CV_Assert(img.channels() == 4);
rgba.format = AVIF_RGB_FORMAT_BGRA;
}
rgba.rowBytes = (uint32_t)img.step[0];
rgba.depth = bit_depth;
rgba.pixels =
const_cast<uint8_t *>(reinterpret_cast<const uint8_t *>(img.data));
if (img.channels() > 1) {
avifRGBImage rgba;
avifRGBImageSetDefaults(&rgba, result);
if (img.channels() == 3) {
rgba.format = AVIF_RGB_FORMAT_BGR;
} else {
CV_Assert(img.channels() == 4);
rgba.format = AVIF_RGB_FORMAT_BGRA;
}
rgba.rowBytes = (uint32_t)img.step[0];
rgba.depth = bit_depth;
rgba.pixels =
const_cast<uint8_t *>(reinterpret_cast<const uint8_t *>(img.data));
if (avifImageRGBToYUV(result, &rgba) != AVIF_RESULT_OK) {
avifImageDestroy(result);
return nullptr;
if (avifImageRGBToYUV(result, &rgba) != AVIF_RESULT_OK) {
avifImageDestroy(result);
return nullptr;
}
}
return AvifImageUniquePtr(result);
}
+3 -3
View File
@@ -337,7 +337,7 @@ bool BmpDecoder::readData( Mat& img )
}
else
{
int x_shift3 = (int)(line_end - data);
ptrdiff_t x_shift3 = line_end - data;
if( code == 2 )
{
@@ -430,7 +430,7 @@ decode_rle4_bad: ;
}
else
{
int x_shift3 = (int)(line_end - data);
ptrdiff_t x_shift3 = line_end - data;
int y_shift = m_height - y;
if( code || !line_end_flag || x_shift3 < width3 )
@@ -441,7 +441,7 @@ decode_rle4_bad: ;
y_shift = m_strm.getByte();
}
x_shift3 += (y_shift * width3) & ((code == 0) - 1);
x_shift3 += ((ptrdiff_t)y_shift * width3) & ((code == 0) - 1);
if( y >= m_height )
break;
+4 -4
View File
@@ -435,7 +435,7 @@ bool IsColorPalette( PaletteEntry* palette, int bpp )
uchar* FillUniColor( uchar* data, uchar*& line_end,
int step, int width3,
int& y, int height,
int count3, PaletteEntry clr )
ptrdiff_t count3, PaletteEntry clr )
{
do
{
@@ -444,7 +444,7 @@ uchar* FillUniColor( uchar* data, uchar*& line_end,
if( end > line_end )
end = line_end;
count3 -= (int)(end - data);
count3 -= end - data;
for( ; data < end; data += 3 )
{
@@ -467,7 +467,7 @@ uchar* FillUniColor( uchar* data, uchar*& line_end,
uchar* FillUniGray( uchar* data, uchar*& line_end,
int step, int width,
int& y, int height,
int count, uchar clr )
ptrdiff_t count, uchar clr )
{
do
{
@@ -476,7 +476,7 @@ uchar* FillUniGray( uchar* data, uchar*& line_end,
if( end > line_end )
end = line_end;
count -= (int)(end - data);
count -= end - data;
for( ; data < end; data++ )
{
+2 -2
View File
@@ -124,9 +124,9 @@ void FillGrayPalette( PaletteEntry* palette, int bpp, bool negative = false );
bool IsColorPalette( PaletteEntry* palette, int bpp );
void CvtPaletteToGray( const PaletteEntry* palette, uchar* grayPalette, int entries );
uchar* FillUniColor( uchar* data, uchar*& line_end, int step, int width3,
int& y, int height, int count3, PaletteEntry clr );
int& y, int height, ptrdiff_t count3, PaletteEntry clr );
uchar* FillUniGray( uchar* data, uchar*& line_end, int step, int width3,
int& y, int height, int count3, uchar clr );
int& y, int height, ptrdiff_t count3, uchar clr );
uchar* FillColorRow8( uchar* data, uchar* indices, int len, PaletteEntry* palette );
uchar* FillGrayRow8( uchar* data, uchar* indices, int len, uchar* palette );
+8 -3
View File
@@ -296,13 +296,15 @@ INSTANTIATE_TEST_CASE_P(Imgcodecs, Exif,
testing::ValuesIn(exif_files));
#ifdef HAVE_AVIF
TEST(Imgcodecs_Avif, ReadWriteWithExif)
typedef testing::TestWithParam<int> MatChannels;
TEST_P(MatChannels, Imgcodecs_Avif_ReadWriteWithExif)
{
int avif_nbits = 10;
int avif_speed = 10;
int avif_quality = 85;
int imgdepth = avif_nbits > 8 ? CV_16U : CV_8U;
int imgtype = CV_MAKETYPE(imgdepth, 3);
int imgtype = CV_MAKETYPE(imgdepth, GetParam());
const string outputname = cv::tempfile(".avif");
Mat img = makeCirclesImage(Size(1280, 720), imgtype, avif_nbits);
@@ -328,7 +330,7 @@ TEST(Imgcodecs_Avif, ReadWriteWithExif)
EXPECT_EQ(img2.rows, img.rows);
EXPECT_EQ(img2.type(), imgtype);
EXPECT_EQ(read_metadata_types, read_metadata_types2);
EXPECT_GE(read_metadata_types.size(), 1u);
ASSERT_GE(read_metadata_types.size(), 1u);
EXPECT_EQ(read_metadata, read_metadata2);
EXPECT_EQ(read_metadata_types[0], IMAGE_METADATA_EXIF);
EXPECT_EQ(read_metadata_types.size(), read_metadata.size());
@@ -338,6 +340,9 @@ TEST(Imgcodecs_Avif, ReadWriteWithExif)
EXPECT_LT(mse, 1500);
remove(outputname.c_str());
}
INSTANTIATE_TEST_CASE_P(Imgcodecs, MatChannels,
testing::Values(1,3,4));
#endif // HAVE_AVIF
#ifdef HAVE_WEBP