Skip to content

Commit

Permalink
do not crash if no channel is selected, use WIC-codec on Windows
Browse files Browse the repository at this point in the history
  • Loading branch information
ptahmose committed Apr 23, 2020
1 parent 97cd89e commit 58650d4
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 60 deletions.
134 changes: 79 additions & 55 deletions wllczi/src/CziReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ MImage CziReader::GetMultiChannelScalingTileComposite(WolframLibraryData libData
{
if (displaySettingsJson == nullptr || *displaySettingsJson == '\0')
{
return CziReader::GetMultiChannelScalingTileComposite(libData, roi, planeCoordinate, zoom);
return CziReader::GetMultiChannelScalingTileComposite(libData, roi, planeCoordinate, zoom, this->GetDispaySettingsFromCzi().get());
}

ChannelDisplaySettingsInfo dsinfo = CziUtilities::ParseDisplaySettings(displaySettingsJson);
Expand All @@ -182,11 +182,79 @@ MImage CziReader::GetMultiChannelScalingTileComposite(WolframLibraryData libData
}
}

MImage CziReader::GetMultiChannelScalingTileComposite(WolframLibraryData libData, const libCZI::IntRect& roi, const libCZI::IDimCoordinate* planeCoordinate, float zoom)
//MImage CziReader::GetMultiChannelScalingTileComposite(WolframLibraryData libData, const libCZI::IntRect& roi, const libCZI::IDimCoordinate* planeCoordinate, float zoom)
//{
// auto displaySettings = this->GetDispaySettingsFromCzi();
//
// std::vector<int> activeChannels = libCZI::CDisplaySettingsHelper::GetActiveChannels(displaySettings.get());
// std::vector<shared_ptr<IBitmapData>> channelBitmaps;
// IntSize sizeResult;
// try
// {
// channelBitmaps = CziUtilities::GetBitmapsFromSpecifiedChannels(
// this->reader.get(),
// planeCoordinate,
// roi,
// zoom,
// [&](int idx, int& chNo)->bool
// {
// if (idx < (int)activeChannels.size())
// {
// chNo = activeChannels.at(idx);
// return true;
// }
//
// return false;
// },
// &sizeResult);
// }
// catch (LibCZIInvalidPlaneCoordinateException& /*invalidCoordExcp*/)
// {
// return nullptr;
// }
//
// libCZI::CDisplaySettingsHelper dsplHlp;
// dsplHlp.Initialize(displaySettings.get(), [&](int chIndx)->libCZI::PixelType
// {
// int idx = (int)std::distance(activeChannels.cbegin(), std::find(activeChannels.cbegin(), activeChannels.cend(), chIndx));
// return channelBitmaps[idx]->GetPixelType();
// });
//
// std::vector<IBitmapData*> vecBm; vecBm.reserve(channelBitmaps.size());
// for (int i = 0; i < channelBitmaps.size(); ++i)
// {
// vecBm.emplace_back(channelBitmaps[i].get());
// }
//
// auto mimagedeleter = std::bind(
// [](WolframImageLibrary_Functions imgLibFuncs, MImage mimg)->void {imgLibFuncs->MImage_free(mimg); },
// libData->imageLibraryFunctions, std::placeholders::_1);
// std::unique_ptr<IMAGEOBJ_ENTRY, decltype(mimagedeleter)> spMimg(
// MImageHelper::CreateMImage(libData->imageLibraryFunctions, sizeResult, libCZI::PixelType::Bgr24),
// mimagedeleter);
//
// CMImageWrapper mimgWrapper(libData->imageLibraryFunctions, spMimg.get());
// libCZI::Compositors::ComposeMultiChannel_Bgr24(
// &mimgWrapper,
// (int)channelBitmaps.size(),
// &vecBm[0],
// dsplHlp.GetChannelInfosArray());
//
// MImageHelper::SwapRgb(&mimgWrapper);
//
// return spMimg.release();
//}

MImage CziReader::GetMultiChannelScalingTileComposite(WolframLibraryData libData, const libCZI::IntRect& roi, const libCZI::IDimCoordinate* planeCoordinate, float zoom, const libCZI::IDisplaySettings* displaySettings)
{
auto displaySettings = this->GetDispaySettingsFromCzi();
std::vector<int> activeChannels = libCZI::CDisplaySettingsHelper::GetActiveChannels(displaySettings);

// we need to deal with the pathologic case that all channels are disabled
if (activeChannels.empty())
{
return CziReader::GetMultiChannelScalingTileCompositeAllChannelsDisabled(libData, roi, zoom);
}

std::vector<int> activeChannels = libCZI::CDisplaySettingsHelper::GetActiveChannels(displaySettings.get());
std::vector<shared_ptr<IBitmapData>> channelBitmaps;
IntSize sizeResult;
try
Expand Down Expand Up @@ -214,9 +282,9 @@ MImage CziReader::GetMultiChannelScalingTileComposite(WolframLibraryData libData
}

libCZI::CDisplaySettingsHelper dsplHlp;
dsplHlp.Initialize(displaySettings.get(), [&](int chIndx)->libCZI::PixelType
dsplHlp.Initialize(displaySettings, [&](int chIndx)->libCZI::PixelType
{
int idx = (int)std::distance(activeChannels.cbegin(), std::find(activeChannels.cbegin(), activeChannels.cend(), chIndx));
const auto idx = std::distance(activeChannels.cbegin(), std::find(activeChannels.cbegin(), activeChannels.cend(), chIndx));
return channelBitmaps[idx]->GetPixelType();
});

Expand Down Expand Up @@ -245,64 +313,20 @@ MImage CziReader::GetMultiChannelScalingTileComposite(WolframLibraryData libData
return spMimg.release();
}

MImage CziReader::GetMultiChannelScalingTileComposite(WolframLibraryData libData, const libCZI::IntRect& roi, const libCZI::IDimCoordinate* planeCoordinate, float zoom, const libCZI::IDisplaySettings* displaySettings)
MImage CziReader::GetMultiChannelScalingTileCompositeAllChannelsDisabled(WolframLibraryData libData, const libCZI::IntRect& roi, float zoom)
{
std::vector<int> activeChannels = libCZI::CDisplaySettingsHelper::GetActiveChannels(displaySettings);
std::vector<shared_ptr<IBitmapData>> channelBitmaps;
IntSize sizeResult;
try
{
channelBitmaps = CziUtilities::GetBitmapsFromSpecifiedChannels(
this->reader.get(),
planeCoordinate,
roi,
zoom,
[&](int idx, int& chNo)->bool
{
if (idx < (int)activeChannels.size())
{
chNo = activeChannels.at(idx);
return true;
}

return false;
},
&sizeResult);
}
catch (LibCZIInvalidPlaneCoordinateException& /*invalidCoordExcp*/)
{
return nullptr;
}

libCZI::CDisplaySettingsHelper dsplHlp;
dsplHlp.Initialize(displaySettings, [&](int chIndx)->libCZI::PixelType
{
int idx = (int)std::distance(activeChannels.cbegin(), std::find(activeChannels.cbegin(), activeChannels.cend(), chIndx));
return channelBitmaps[idx]->GetPixelType();
});

std::vector<IBitmapData*> vecBm; vecBm.reserve(channelBitmaps.size());
for (int i = 0; i < channelBitmaps.size(); ++i)
{
vecBm.emplace_back(channelBitmaps[i].get());
}
auto accessor = reader->CreateSingleChannelScalingTileAccessor();
const auto sizeResult = accessor->CalcSize(roi, zoom);
RgbFloatColor color{ 0,0,0 };

auto mimagedeleter = std::bind(
[](WolframImageLibrary_Functions imgLibFuncs, MImage mimg)->void {imgLibFuncs->MImage_free(mimg); },
libData->imageLibraryFunctions, std::placeholders::_1);
std::unique_ptr<IMAGEOBJ_ENTRY, decltype(mimagedeleter)> spMimg(
MImageHelper::CreateMImage(libData->imageLibraryFunctions, sizeResult, libCZI::PixelType::Bgr24),
mimagedeleter);

CMImageWrapper mimgWrapper(libData->imageLibraryFunctions, spMimg.get());
libCZI::Compositors::ComposeMultiChannel_Bgr24(
&mimgWrapper,
(int)channelBitmaps.size(),
&vecBm[0],
dsplHlp.GetChannelInfosArray());

MImageHelper::SwapRgb(&mimgWrapper);

libCZI::Utils::FillBitmap(&mimgWrapper, color);
return spMimg.release();
}

Expand Down
5 changes: 3 additions & 2 deletions wllczi/src/CziReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class CziReader

MImage GetSubBlockImage(WolframLibraryData libData,int no);
MImage GetSingleChannelScalingTileComposite(WolframLibraryData libData, const libCZI::IntRect& roi, const libCZI::IDimCoordinate* planeCoordinate, float zoom);
MImage GetMultiChannelScalingTileComposite(WolframLibraryData libData, const libCZI::IntRect& roi, const libCZI::IDimCoordinate* planeCoordinate, float zoom);
//MImage GetMultiChannelScalingTileComposite(WolframLibraryData libData, const libCZI::IntRect& roi, const libCZI::IDimCoordinate* planeCoordinate, float zoom);

MImage GetMultiChannelScalingTileComposite(WolframLibraryData libData, const libCZI::IntRect& roi, const libCZI::IDimCoordinate* planeCoordinate, float zoom, const char* displaySettingsJson);
private:
Expand All @@ -34,5 +34,6 @@ class CziReader
static void CopyStrided_RGB24_to_BGR24(libCZI::IBitmapData* bitmapData, void* pDst);
static void CopyStrided_RGB48_to_BGR48(libCZI::IBitmapData* bitmapData, void* pDst);

MImage GetMultiChannelScalingTileComposite(WolframLibraryData libData, const libCZI::IntRect& roi, const libCZI::IDimCoordinate* planeCoordinate, float zoom, const libCZI::IDisplaySettings* displSettings);
MImage GetMultiChannelScalingTileComposite(WolframLibraryData libData, const libCZI::IntRect& roi, const libCZI::IDimCoordinate* planeCoordinate, float zoom, const libCZI::IDisplaySettings* displaySettings);
MImage GetMultiChannelScalingTileCompositeAllChannelsDisabled(WolframLibraryData libData, const libCZI::IntRect& roi, float zoom);
};
2 changes: 1 addition & 1 deletion wllczi/src/CziUtilities.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ bool ChannelDisplaySettingsValidity::Get(Property prop) const
std::vector<std::shared_ptr<IBitmapData>> chBitmaps;
libCZI::CDimCoordinate coordinate = planeCoordinate;

auto subBlockStatistics = reader->GetStatistics();
const auto subBlockStatistics = reader->GetStatistics();

libCZI::ISingleChannelScalingTileAccessor::Options sctaOptions; sctaOptions.Clear();
sctaOptions.backGroundColor = RgbFloatColor{ 0, 0, 0 };
Expand Down
13 changes: 11 additions & 2 deletions wllczi/src/Initialization.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "CziInstanceManager.h"
#include "errorhelper.h"
#include "dbgprint.h"
#include "inc_libCzi.h"

using namespace std;

Expand All @@ -21,14 +22,22 @@ static void manage_czi_instance(WolframLibraryData libData, mbool mode, mint id)
}
}

mint WolframLibrary_getVersion( )
mint WolframLibrary_getVersion()
{
DBGPRINT((CDbg::Level::Trace, "WolframLibrary_getVersion: Enter"));
return (WolframLibraryVersion);
}

int WolframLibrary_initialize( WolframLibraryData libData)
int WolframLibrary_initialize(WolframLibraryData libData)
{
#if _WIN32API
// on Windows, prefer to use the Microsoft-WIC-JPGXR-codec
const auto site = libCZI::GetDefaultSiteObject(libCZI::SiteObjectType::WithWICDecoder);
if (site != nullptr)
{
libCZI::SetSiteObject(site);
}
#endif
int r = libData->registerLibraryExpressionManager(LibraryExpressionNameCziReader, manage_czi_instance);
return r;
}
Expand Down

0 comments on commit 58650d4

Please sign in to comment.