diff --git a/modules/imgcodecs/src/grfmt_gdal.cpp b/modules/imgcodecs/src/grfmt_gdal.cpp index 1a5a680a9b..c04e287711 100644 --- a/modules/imgcodecs/src/grfmt_gdal.cpp +++ b/modules/imgcodecs/src/grfmt_gdal.cpp @@ -78,7 +78,7 @@ int gdalPaletteInterpretation2OpenCV( GDALPaletteInterp const& paletteInterp, G /// RGB case GPI_RGB: - if( gdalType == GDT_Byte ){ return CV_8UC1; } + if( gdalType == GDT_Byte ){ return CV_8UC3; } if( gdalType == GDT_UInt16 ){ return CV_16UC3; } if( gdalType == GDT_Int16 ){ return CV_16SC3; } if( gdalType == GDT_UInt32 ){ return CV_32SC3; } @@ -256,35 +256,35 @@ void write_pixel( const double& pixelValue, // input: 3 channel, output: 3 channel else if( gdalChannels == 3 && image.channels() == 3 ){ - if( image.depth() == CV_8U ){ image.at(row,col)[channel] = newValue; } - else if( image.depth() == CV_16U ){ image.ptr(row,col)[channel] = newValue; } - else if( image.depth() == CV_16S ){ image.ptr(row,col)[channel] = newValue; } - else if( image.depth() == CV_32S ){ image.ptr(row,col)[channel] = newValue; } - else if( image.depth() == CV_32F ){ image.ptr(row,col)[channel] = newValue; } - else if( image.depth() == CV_64F ){ image.ptr(row,col)[channel] = newValue; } + if( image.depth() == CV_8U ){ (*image.ptr(row,col))[channel] = newValue; } + else if( image.depth() == CV_16U ){ (*image.ptr(row,col))[channel] = newValue; } + else if( image.depth() == CV_16S ){ (*image.ptr(row,col))[channel] = newValue; } + else if( image.depth() == CV_32S ){ (*image.ptr(row,col))[channel] = newValue; } + else if( image.depth() == CV_32F ){ (*image.ptr(row,col))[channel] = newValue; } + else if( image.depth() == CV_64F ){ (*image.ptr(row,col))[channel] = newValue; } else{ throw std::runtime_error("Unknown image depth, gdal: 3, image: 3"); } } // input: 4 channel, output: 3 channel else if( gdalChannels == 4 && image.channels() == 3 ){ if( channel >= 4 ){ return; } - else if( image.depth() == CV_8U && channel < 4 ){ image.ptr(row,col)[channel] = newValue; } - else if( image.depth() == CV_16U && channel < 4 ){ image.ptr(row,col)[channel] = newValue; } - else if( image.depth() == CV_16S && channel < 4 ){ image.ptr(row,col)[channel] = newValue; } - else if( image.depth() == CV_32S && channel < 4 ){ image.ptr(row,col)[channel] = newValue; } - else if( image.depth() == CV_32F && channel < 4 ){ image.ptr(row,col)[channel] = newValue; } - else if( image.depth() == CV_64F && channel < 4 ){ image.ptr(row,col)[channel] = newValue; } + else if( image.depth() == CV_8U && channel < 4 ){ (*image.ptr(row,col))[channel] = newValue; } + else if( image.depth() == CV_16U && channel < 4 ){ (*image.ptr(row,col))[channel] = newValue; } + else if( image.depth() == CV_16S && channel < 4 ){ (*image.ptr(row,col))[channel] = newValue; } + else if( image.depth() == CV_32S && channel < 4 ){ (*image.ptr(row,col))[channel] = newValue; } + else if( image.depth() == CV_32F && channel < 4 ){ (*image.ptr(row,col))[channel] = newValue; } + else if( image.depth() == CV_64F && channel < 4 ){ (*image.ptr(row,col))[channel] = newValue; } else{ throw std::runtime_error("Unknown image depth, gdal: 4, image: 3"); } } // input: 4 channel, output: 4 channel else if( gdalChannels == 4 && image.channels() == 4 ){ - if( image.depth() == CV_8U ){ image.at(row,col)[channel] = newValue; } - else if( image.depth() == CV_16U ){ image.at(row,col)[channel] = newValue; } - else if( image.depth() == CV_16S ){ image.at(row,col)[channel] = newValue; } - else if( image.depth() == CV_32S ){ image.at(row,col)[channel] = newValue; } - else if( image.depth() == CV_32F ){ image.at(row,col)[channel] = newValue; } - else if( image.depth() == CV_64F ){ image.at(row,col)[channel] = newValue; } + if( image.depth() == CV_8U ){ (*image.ptr(row,col))[channel] = newValue; } + else if( image.depth() == CV_16U ){ (*image.ptr(row,col))[channel] = newValue; } + else if( image.depth() == CV_16S ){ (*image.ptr(row,col))[channel] = newValue; } + else if( image.depth() == CV_32S ){ (*image.ptr(row,col))[channel] = newValue; } + else if( image.depth() == CV_32F ){ (*image.ptr(row,col))[channel] = newValue; } + else if( image.depth() == CV_64F ){ (*image.ptr(row,col))[channel] = newValue; } else{ throw std::runtime_error("Unknown image depth, gdal: 4, image: 4"); } } @@ -388,6 +388,30 @@ bool GdalDecoder::readData( Mat& img ){ // get the GDAL Band GDALRasterBand* band = m_dataset->GetRasterBand(c+1); + /* Map palette band and gray band to color index 0 and red, green, + blue, alpha bands to BGRA indexes. Note: ignoring HSL, CMY, + CMYK, and YCbCr color spaces, rather than converting them + to BGR. */ + int color = 0; + switch (band->GetColorInterpretation()) { + case GCI_PaletteIndex: + case GCI_GrayIndex: + case GCI_BlueBand: + color = 0; + break; + case GCI_GreenBand: + color = 1; + break; + case GCI_RedBand: + color = 2; + break; + case GCI_AlphaBand: + color = 3; + break; + default: + CV_ErrorNoReturn(cv::Error::StsError, "Invalid/unsupported mode"); + } + // make sure the image band has the same dimensions as the image if( band->GetXSize() != m_width || band->GetYSize() != m_height ){ return false; } @@ -410,10 +434,10 @@ bool GdalDecoder::readData( Mat& img ){ // set depending on image types // given boost, I would use enable_if to speed up. Avoid for now. if( hasColorTable == false ){ - write_pixel( scanline[x], gdalType, nChannels, img, y, x, c ); + write_pixel( scanline[x], gdalType, nChannels, img, y, x, color ); } else{ - write_ctable_pixel( scanline[x], gdalType, gdalColorTable, img, y, x, c ); + write_ctable_pixel( scanline[x], gdalType, gdalColorTable, img, y, x, color ); } } }