mirror of
https://github.com/opencv/opencv.git
synced 2025-06-11 20:09:23 +08:00
Merge pull request #19109 from tailsu:sd/imdecode-jp2k-codestream
* OpenJPEG: decoder for J2K codestreams * code review fixes * exclude .j2c from GDAL tests
This commit is contained in:
parent
15265918a7
commit
b13b5d86f6
@ -495,20 +495,16 @@ detail::StreamPtr opjCreateBufferInputStream(detail::OpjMemoryBuffer* buf)
|
||||
|
||||
/////////////////////// Jpeg2KOpjDecoder ///////////////////
|
||||
|
||||
Jpeg2KOpjDecoder::Jpeg2KOpjDecoder()
|
||||
namespace detail {
|
||||
|
||||
Jpeg2KOpjDecoderBase::Jpeg2KOpjDecoderBase(OPJ_CODEC_FORMAT format)
|
||||
: format_(format)
|
||||
{
|
||||
static const unsigned char signature[] = { 0, 0, 0, 0x0c, 'j', 'P', ' ', ' ', 13, 10, 0x87, 10 };
|
||||
m_signature = String((const char*)(signature), sizeof(signature));
|
||||
m_buf_supported = true;
|
||||
}
|
||||
|
||||
|
||||
ImageDecoder Jpeg2KOpjDecoder::newDecoder() const
|
||||
{
|
||||
return makePtr<Jpeg2KOpjDecoder>();
|
||||
}
|
||||
|
||||
bool Jpeg2KOpjDecoder::readHeader()
|
||||
bool Jpeg2KOpjDecoderBase::readHeader()
|
||||
{
|
||||
if (!m_buf.empty()) {
|
||||
opjBuf_ = detail::OpjMemoryBuffer(m_buf);
|
||||
@ -521,7 +517,7 @@ bool Jpeg2KOpjDecoder::readHeader()
|
||||
if (!stream_)
|
||||
return false;
|
||||
|
||||
codec_.reset(opj_create_decompress(OPJ_CODEC_JP2));
|
||||
codec_.reset(opj_create_decompress(format_));
|
||||
if (!codec_)
|
||||
return false;
|
||||
|
||||
@ -587,7 +583,7 @@ bool Jpeg2KOpjDecoder::readHeader()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Jpeg2KOpjDecoder::readData( Mat& img )
|
||||
bool Jpeg2KOpjDecoderBase::readData( Mat& img )
|
||||
{
|
||||
using DecodeFunc = bool(*)(const opj_image_t&, cv::Mat&, uint8_t shift);
|
||||
|
||||
@ -606,7 +602,9 @@ bool Jpeg2KOpjDecoder::readData( Mat& img )
|
||||
switch (image_->color_space)
|
||||
{
|
||||
case OPJ_CLRSPC_UNKNOWN:
|
||||
CV_LOG_WARNING(NULL, "OpenJPEG2000: Image has unknown color space, SRGB is assumed");
|
||||
/* FALLTHRU */
|
||||
case OPJ_CLRSPC_UNSPECIFIED:
|
||||
CV_LOG_WARNING(NULL, "OpenJPEG2000: Image has unknown or unspecified color space, SRGB is assumed");
|
||||
/* FALLTHRU */
|
||||
case OPJ_CLRSPC_SRGB:
|
||||
decode = decodeSRGBData;
|
||||
@ -617,8 +615,6 @@ bool Jpeg2KOpjDecoder::readData( Mat& img )
|
||||
case OPJ_CLRSPC_SYCC:
|
||||
decode = decodeSYCCData;
|
||||
break;
|
||||
case OPJ_CLRSPC_UNSPECIFIED:
|
||||
CV_Error(Error::StsNotImplemented, "OpenJPEG2000: Image has unspecified color space");
|
||||
default:
|
||||
CV_Error(Error::StsNotImplemented,
|
||||
cv::format("OpenJPEG2000: Unsupported color space conversion: %s -> %s",
|
||||
@ -654,6 +650,31 @@ bool Jpeg2KOpjDecoder::readData( Mat& img )
|
||||
return decode(*image_, img, shift);
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
Jpeg2KJP2OpjDecoder::Jpeg2KJP2OpjDecoder()
|
||||
: Jpeg2KOpjDecoderBase(OPJ_CODEC_JP2)
|
||||
{
|
||||
static const unsigned char JP2Signature[] = { 0, 0, 0, 0x0c, 'j', 'P', ' ', ' ', 13, 10, 0x87, 10 };
|
||||
m_signature = String((const char*) JP2Signature, sizeof(JP2Signature));
|
||||
}
|
||||
|
||||
ImageDecoder Jpeg2KJP2OpjDecoder::newDecoder() const
|
||||
{
|
||||
return makePtr<Jpeg2KJP2OpjDecoder>();
|
||||
}
|
||||
|
||||
Jpeg2KJ2KOpjDecoder::Jpeg2KJ2KOpjDecoder()
|
||||
: Jpeg2KOpjDecoderBase(OPJ_CODEC_J2K)
|
||||
{
|
||||
static const unsigned char J2KSignature[] = { 0xff, 0x4f, 0xff, 0x51 };
|
||||
m_signature = String((const char*) J2KSignature, sizeof(J2KSignature));
|
||||
}
|
||||
|
||||
ImageDecoder Jpeg2KJ2KOpjDecoder::newDecoder() const
|
||||
{
|
||||
return makePtr<Jpeg2KJ2KOpjDecoder>();
|
||||
}
|
||||
|
||||
/////////////////////// Jpeg2KOpjEncoder ///////////////////
|
||||
|
||||
|
@ -59,15 +59,11 @@ using StreamPtr = std::unique_ptr<opj_stream_t, detail::OpjStreamDeleter>;
|
||||
using CodecPtr = std::unique_ptr<opj_codec_t, detail::OpjCodecDeleter>;
|
||||
using ImagePtr = std::unique_ptr<opj_image_t, detail::OpjImageDeleter>;
|
||||
|
||||
} // namespace detail
|
||||
|
||||
class Jpeg2KOpjDecoder CV_FINAL : public BaseImageDecoder
|
||||
class Jpeg2KOpjDecoderBase : public BaseImageDecoder
|
||||
{
|
||||
public:
|
||||
Jpeg2KOpjDecoder();
|
||||
~Jpeg2KOpjDecoder() CV_OVERRIDE = default;
|
||||
Jpeg2KOpjDecoderBase(OPJ_CODEC_FORMAT format);
|
||||
|
||||
ImageDecoder newDecoder() const CV_OVERRIDE;
|
||||
bool readData( Mat& img ) CV_OVERRIDE;
|
||||
bool readHeader() CV_OVERRIDE;
|
||||
|
||||
@ -79,6 +75,23 @@ private:
|
||||
detail::OpjMemoryBuffer opjBuf_;
|
||||
|
||||
OPJ_UINT32 m_maxPrec = 0;
|
||||
OPJ_CODEC_FORMAT format_;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
class Jpeg2KJP2OpjDecoder CV_FINAL : public detail::Jpeg2KOpjDecoderBase {
|
||||
public:
|
||||
Jpeg2KJP2OpjDecoder();
|
||||
|
||||
ImageDecoder newDecoder() const CV_OVERRIDE;
|
||||
};
|
||||
|
||||
class Jpeg2KJ2KOpjDecoder CV_FINAL : public detail::Jpeg2KOpjDecoderBase {
|
||||
public:
|
||||
Jpeg2KJ2KOpjDecoder();
|
||||
|
||||
ImageDecoder newDecoder() const CV_OVERRIDE;
|
||||
};
|
||||
|
||||
class Jpeg2KOpjEncoder CV_FINAL : public BaseImageEncoder
|
||||
|
@ -179,7 +179,8 @@ struct ImageCodecInitializer
|
||||
encoders.push_back( makePtr<Jpeg2KEncoder>() );
|
||||
#endif
|
||||
#ifdef HAVE_OPENJPEG
|
||||
decoders.push_back( makePtr<Jpeg2KOpjDecoder>() );
|
||||
decoders.push_back( makePtr<Jpeg2KJP2OpjDecoder>() );
|
||||
decoders.push_back( makePtr<Jpeg2KJ2KOpjDecoder>() );
|
||||
encoders.push_back( makePtr<Jpeg2KOpjEncoder>() );
|
||||
#endif
|
||||
#ifdef HAVE_OPENEXR
|
||||
|
@ -78,7 +78,9 @@ const string all_images[] =
|
||||
"readwrite/Bretagne2.jp2",
|
||||
"readwrite/Grey.jp2",
|
||||
"readwrite/Grey.jp2",
|
||||
"readwrite/balloon.j2c",
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GDCM
|
||||
"readwrite/int16-mono1.dcm",
|
||||
"readwrite/uint8-mono2.dcm",
|
||||
@ -109,11 +111,11 @@ INSTANTIATE_TEST_CASE_P(All, Imgcodecs_FileMode,
|
||||
testing::ValuesIn(all_images),
|
||||
testing::ValuesIn(basic_modes)));
|
||||
|
||||
// GDAL does not support "hdr", "dcm" and have problems with "jp2"
|
||||
// GDAL does not support "hdr", "dcm" and has problems with JPEG2000 files (jp2, j2c)
|
||||
struct notForGDAL {
|
||||
bool operator()(const string &name) const {
|
||||
const string &ext = name.substr(name.size() - 3, 3);
|
||||
return ext == "hdr" || ext == "dcm" || ext == "jp2" ||
|
||||
return ext == "hdr" || ext == "dcm" || ext == "jp2" || ext == "j2c" ||
|
||||
name.find("rle8.bmp") != std::string::npos;
|
||||
}
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user