Jpeg2k color to greyscale conversion on non-Windows is done post decoding because system libjasper segfaults when decoding color images as greyscale.

This commit is contained in:
Ashod Nakashian 2015-04-03 20:59:13 -04:00
parent 54ab3137d5
commit f75f2ffd48
3 changed files with 39 additions and 17 deletions

View File

@ -45,6 +45,7 @@
#ifdef HAVE_JASPER #ifdef HAVE_JASPER
#include "grfmt_jpeg2000.hpp" #include "grfmt_jpeg2000.hpp"
#include "opencv2/imgproc.hpp"
#ifdef WIN32 #ifdef WIN32
#define JAS_WIN_MSVC_BUILD 1 #define JAS_WIN_MSVC_BUILD 1
@ -159,6 +160,21 @@ bool Jpeg2KDecoder::readData( Mat& img )
jas_stream_t* stream = (jas_stream_t*)m_stream; jas_stream_t* stream = (jas_stream_t*)m_stream;
jas_image_t* image = (jas_image_t*)m_image; jas_image_t* image = (jas_image_t*)m_image;
#ifndef WIN32
// At least on some Linux instances the
// system libjasper segfaults when
// converting color to grey.
// We do this conversion manually at the end.
Mat clr;
if (CV_MAT_CN(img.type()) < CV_MAT_CN(this->type()))
{
clr.create(img.size().height, img.size().width, this->type());
color = true;
data = clr.ptr();
step = (int)clr.step;
}
#endif
if( stream && image ) if( stream && image )
{ {
bool convert; bool convert;
@ -171,7 +187,7 @@ bool Jpeg2KDecoder::readData( Mat& img )
else else
{ {
convert = (jas_clrspc_fam( jas_image_clrspc( image ) ) != JAS_CLRSPC_FAM_GRAY); convert = (jas_clrspc_fam( jas_image_clrspc( image ) ) != JAS_CLRSPC_FAM_GRAY);
colorspace = JAS_CLRSPC_SGRAY; // TODO GENGRAY or SGRAY? colorspace = JAS_CLRSPC_SGRAY; // TODO GENGRAY or SGRAY? (GENGRAY fails on Win.)
} }
// convert to the desired colorspace // convert to the desired colorspace
@ -256,6 +272,13 @@ bool Jpeg2KDecoder::readData( Mat& img )
close(); close();
#ifndef WIN32
if (!clr.empty())
{
cv::cvtColor(clr, img, COLOR_BGR2GRAY);
}
#endif
return result; return result;
} }

View File

@ -374,15 +374,8 @@ imreadmulti_(const String& filename, int flags, std::vector<Mat>& mats)
type = CV_MAKETYPE(CV_MAT_DEPTH(type), 1); type = CV_MAKETYPE(CV_MAT_DEPTH(type), 1);
} }
// established the required input image size.
CvSize size;
size.width = decoder->width();
size.height = decoder->height();
Mat mat;
mat.create(size.height, size.width, type);
// read the image data // read the image data
Mat mat(decoder->height(), decoder->width(), type);
if (!decoder->readData(mat)) if (!decoder->readData(mat))
{ {
break; break;

View File

@ -102,13 +102,17 @@ TEST(Imgcodecs_imread, regression)
for (size_t i = 0; i < sizeof(filenames) / sizeof(filenames[0]); ++i) for (size_t i = 0; i < sizeof(filenames) / sizeof(filenames[0]); ++i)
{ {
ASSERT_TRUE(imread_compare(folder + string(filenames[i]), IMREAD_UNCHANGED)); const string path = folder + string(filenames[i]);
ASSERT_TRUE(imread_compare(folder + string(filenames[i]), IMREAD_GRAYSCALE)); ASSERT_TRUE(imread_compare(path, IMREAD_UNCHANGED));
ASSERT_TRUE(imread_compare(folder + string(filenames[i]), IMREAD_COLOR)); ASSERT_TRUE(imread_compare(path, IMREAD_GRAYSCALE));
ASSERT_TRUE(imread_compare(folder + string(filenames[i]), IMREAD_ANYDEPTH)); ASSERT_TRUE(imread_compare(path, IMREAD_COLOR));
ASSERT_TRUE(imread_compare(folder + string(filenames[i]), IMREAD_ANYCOLOR)); ASSERT_TRUE(imread_compare(path, IMREAD_ANYDEPTH));
if (i != 2) // GDAL does not support hdr ASSERT_TRUE(imread_compare(path, IMREAD_ANYCOLOR));
ASSERT_TRUE(imread_compare(folder + string(filenames[i]), IMREAD_LOAD_GDAL)); if (path.substr(path.length() - 3) != "hdr")
{
// GDAL does not support hdr
ASSERT_TRUE(imread_compare(path, IMREAD_LOAD_GDAL));
}
} }
} }
@ -117,8 +121,10 @@ TEST(Imgcodecs_jasper, regression)
{ {
const string folder = string(cvtest::TS::ptr()->get_data_path()) + "/readwrite/"; const string folder = string(cvtest::TS::ptr()->get_data_path()) + "/readwrite/";
ASSERT_TRUE(imread_compare(folder + "Bretagne2.jp2", IMREAD_UNCHANGED)); ASSERT_TRUE(imread_compare(folder + "Bretagne2.jp2", IMREAD_COLOR));
ASSERT_TRUE(imread_compare(folder + "Bretagne2.jp2", IMREAD_GRAYSCALE)); ASSERT_TRUE(imread_compare(folder + "Bretagne2.jp2", IMREAD_GRAYSCALE));
ASSERT_TRUE(imread_compare(folder + "Grey.jp2", IMREAD_COLOR));
ASSERT_TRUE(imread_compare(folder + "Grey.jp2", IMREAD_GRAYSCALE));
} }
#endif #endif