CVB cube saving to ENVI crashes

I have a strange problem with the saving of a cvb::Cube. Consider the following MS unit test:

///////////////////////////////////////////
//  Write data to ENVI BIP file
TEST_METHOD(TestCVBCrashOnCubeSave)
{
    const auto rows = 100;
    const auto cols = 50;
    const auto dims = 10;

    auto waveLengts = std::vector<double>{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

    for (auto iteration = 0; iteration < 10; ++iteration) 
    {
		try
		{
            auto ptr = Cvb::Spectral::Cube::Create(rows, cols, dims, Cvb::DataType::Int8BppUnsigned(), Cvb::Spectral::CubeEncoding::BandInterleavedByPixel);
            //std::memcpy((void*)ptr->LinearAccess().BasePtr(), rawDataset.data_ptr(), sizeof(torch::kInt8) * rawDataset.numel());

            ptr->MetaData()->WriteField<int>(Cvb::Spectral::FieldID::Bands, dims);
            ptr->MetaData()->WriteField<int>(Cvb::Spectral::FieldID::DataType, 1);
            ptr->MetaData()->WriteField<int>(Cvb::Spectral::FieldID::Lines, rows);
            ptr->MetaData()->WriteField<int>(Cvb::Spectral::FieldID::Samples, cols);
            ptr->MetaData()->WriteField<Cvb::String>(Cvb::Spectral::FieldID::Interleave, CVB_LIT("BIP"));
            ptr->MetaData()->WriteField<std::vector<double>>(Cvb::Spectral::FieldID::Wavelength, waveLengts);

            Cvb::String enviHeaderFile(Cvb::ExpandPath(CVB_LIT("test.hdr")));
            Cvb::String enviBinaryFile(Cvb::ExpandPath(CVB_LIT("test.raw")));
            ptr->Save(enviHeaderFile, enviBinaryFile);
            //ptr.reset();

            Logger::WriteMessage("ITERATION DONE: ");
            Logger::WriteMessage(std::to_string(iteration).c_str());
            Logger::WriteMessage("\n");
		}
		catch (const std::exception& e)
		{
            Logger::WriteMessage("CVB ENVI WRITE CRASHES!");
            Assert::Fail();
        }
    }
}

The result of this test is that the ptr->Save(…) statement crashes in the SECOND (and following) iteration(s) of the loop. The first iteration saves the envi file correctly. The exception itself is a std::domain error.

Why does the save statement crash? …; and how is it resolved??
Thanks in advance!
Iwein

Hi @iwein,
Sorry for the late response. I can reproduce the issue and this is probably a bug in CVB Spectral which will be fixed in the next release where we update CVB Spectral.
To get a fix faster, please contact support@stemmer-imaging.com. And refer to this forum post.

Thanks for your comment @Sebastian !

This is for sure a bug, and this is explicitly related with CVB’s unorthodox license policy as the unit test will prove: If you have a license file the bug does not manifest itself… so, my question is what you will fix exactly: either remove the envi/spectral license part in the envi write code (?) or will you fix the bug so that no envi files can be created if you do not have a license (?).

I contacted support@stemmer before I wrote the aforementioned post… they replied with a ~1500 Euro quote. We, in turn, kicked CVB::Spectral::ENVI out of our software - which was only one day of work :wink:

The strange part of this all is the fact that our (spinoff) company buys multiple spectral cameras each year (which are not cheat, to say the least). I would suspect that CVB/Stemmer has an agreement with the camera manufacturers in a way that we do not have to buy an extra 2k license… these are spectral cameras after all :wink:

Sincerely,
Dr. ir. ing. Vranckx

@iwein
I need to correct my previous statement. I realized that I tested your code without having my CVB Dongle connected to the system.
When I use a valid licence, I was able to save all the images from every iteration.

So there is no bug here. To save more than the first image, you need to have a valid licence for the Image Manager and CVB Spectral.

1 Like

Sebastian,
The bug is that > The first iteration saves the envi file correctly.

  1. it should not be possible to do this without a licence
  2. the procedure should throw a clear exception, e.g. throw std::exception(“CVB Spectral licence not installed”);

Hi @iwein

I see this discussion has been going on for a while and is more or less concluded, nevertheless I’d like to add one or two comments if I may.

The fact that the first attempt to save actually works is by design. A number of customers launch their application in one of the Windows or Linux auto start facilities. With these the order of initialization is not always well-defined (and in fact not always well-definable), which made it possible that even though a license is present, for a short period during startup the software could behave as if that were not the case. Therefore we did introduce a short grace period after startup during which the software will act as if licensed, to help in these scenarios. Therefore we do not consider this behavior a bug.

The fact that the return value / exception doesn’t point to license issues is a (fairly old) design choice (and arguably not a great one) that was aimed at preventing users from just guessing the license codes by calling such a function over while iterating over all possible codes (in some cases these could actually be as simple as a four-digit-number, so a for loop running for some 5 minutes would have done the trick). I guess the time has come to review and challenge that choice…