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:
@@ -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.
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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++ )
|
||||
{
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user