# CVB cube saving to ENVI crashes

**URL:** <https://forum.commonvisionblox.com/t/cvb-cube-saving-to-envi-crashes/1999>\
**Category:** C++ API\
**Tags:** hyperspectral\
**Created:** [August 11, 2023, 1:15pm UTC](https://forum.commonvisionblox.com/t/cvb-cube-saving-to-envi-crashes/1999 "2023-08-11T13:15:30Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![iwein](https://avatars.discourse-cdn.com/v4/letter/i/8baadc/32.png) [@iwein](https://forum.commonvisionblox.com/u/iwein)\
**Post date:** [August 11, 2023, 1:15pm UTC](https://forum.commonvisionblox.com/t/cvb-cube-saving-to-envi-crashes/1999/1 "2023-08-11T13:15:30Z")

</div>

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

```auto
///////////////////////////////////////////
// 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

---

<div class="post-metadata">

**Author:** ![Sebastian](https://yyz1.discourse-cdn.com/flex027/user_avatar/forum.commonvisionblox.com/sebastian/32/1267_2.png) [@Sebastian](https://forum.commonvisionblox.com/u/Sebastian)\
**Post date:** [September 4, 2023, 12:42pm UTC](https://forum.commonvisionblox.com/t/cvb-cube-saving-to-envi-crashes/1999/2 "2023-09-04T12:42:38Z")

</div>

> [@iwein](#):
>
> ```auto
> 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();
> }
> }
> 
> ```

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](mailto:support@stemmer-imaging.com). And refer to this forum post.

---

<div class="post-metadata">

**Author:** ![iwein](https://avatars.discourse-cdn.com/v4/letter/i/8baadc/32.png) [@iwein](https://forum.commonvisionblox.com/u/iwein)\
**Post date:** [September 5, 2023, 1:33pm UTC](https://forum.commonvisionblox.com/t/cvb-cube-saving-to-envi-crashes/1999/3 "2023-09-05T13:33:29Z")

</div>

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 😉

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 😉

Sincerely,  
Dr. ir. ing. Vranckx

---

<div class="post-metadata">

**Author:** ![Sebastian](https://yyz1.discourse-cdn.com/flex027/user_avatar/forum.commonvisionblox.com/sebastian/32/1267_2.png) [@Sebastian](https://forum.commonvisionblox.com/u/Sebastian)\
**Post date:** [September 6, 2023, 2:17pm UTC](https://forum.commonvisionblox.com/t/cvb-cube-saving-to-envi-crashes/1999/4 "2023-09-06T14:17:32Z")

</div>

@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.

---

<div class="post-metadata">

**Author:** ![iwein](https://avatars.discourse-cdn.com/v4/letter/i/8baadc/32.png) [@iwein](https://forum.commonvisionblox.com/u/iwein)\
**Post date:** [September 6, 2023, 2:33pm UTC](https://forum.commonvisionblox.com/t/cvb-cube-saving-to-envi-crashes/1999/5 "2023-09-06T14:33:21Z")

</div>

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”);

---

<div class="post-metadata">

**Author:** ![illusive](https://yyz1.discourse-cdn.com/flex027/user_avatar/forum.commonvisionblox.com/illusive/32/61_2.png) [@illusive](https://forum.commonvisionblox.com/u/illusive)\
**Post date:** [September 27, 2023, 9:34am UTC](https://forum.commonvisionblox.com/t/cvb-cube-saving-to-envi-crashes/1999/6 "2023-09-27T09:34:01Z")

</div>

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…
