std::pair<TweakableState, bool> TweakableParser<bool>::parse(Containers::ArrayView<const char> value) { if(value.size() == 4 && std::strncmp(value.data(), "true", value.size()) == 0) return {TweakableState::Success, true}; if(value.size() == 5 && std::strncmp(value.data(), "false", value.size()) == 0) return {TweakableState::Success, false}; Warning{} << "Utility::TweakableParser:" << std::string{value, value.size()} << "is not a boolean literal"; return {TweakableState::Recompile, {}}; }
bool Directory::write(const std::string& filename, const Containers::ArrayView<const void> data) { std::ofstream file(filename, std::ofstream::binary); if(!file) return false; file.write(reinterpret_cast<const char*>(data.data()), data.size()); return true; }
template<UnsignedInt dimensions> void BufferImage<dimensions>::setData(const PixelStorage storage, const PixelFormat format, const PixelType type, const VectorTypeFor<dimensions, Int>& size, Containers::ArrayView<const void> const data, const BufferUsage usage) { _storage = storage; _format = format; _type = type; _size = size; /* Keep the old storage if zero-sized nullptr buffer was passed */ if(data.data() == nullptr && data.size() == 0) CORRADE_ASSERT(Implementation::imageDataSize(*this) <= _dataSize, "BufferImage::setData(): bad current storage size, got" << _dataSize << "but expected at least" << Implementation::imageDataSize(*this), ); else {
void StbVorbisImporter::doOpenData(Containers::ArrayView<const char> data) { Int numChannels, frequency; Short* decodedData = nullptr; Int samples = stb_vorbis_decode_memory(reinterpret_cast<const UnsignedByte*>(data.data()), data.size(), &numChannels, &frequency, &decodedData); if(samples == -1) { Error() << "Audio::StbVorbisImporter::openData(): the file signature is invalid"; return; } else if (samples == -2) { /* memory allocation failure */ Error() << "Audio::StbVorbisImporter::openData(): out of memory"; return; } Containers::Array<char> tempData{reinterpret_cast<char*>(decodedData), size_t(samples*numChannels*2), [](char* data, size_t) { std::free(data); }}; _frequency = frequency; /* Decide about format */ if(numChannels == 1) _format = Buffer::Format::Mono16; else if(numChannels == 2) _format = Buffer::Format::Stereo16; /** @todo Buffer::Format::*Float32 when extension support is done */ else { Error() << "Audio::StbVorbisImporter::openData(): unsupported channel count" << numChannels << "with" << 16 << "bits per sample"; return; } _data = std::move(tempData); return; }
void DrWavImporter::doOpenData(const Containers::ArrayView<const char> data) { drwav* const handle = drwav_open_memory(data.data(), data.size()); if(!handle) { Error() << "Audio::DrWavImporter::openData(): failed to open and decode WAV data"; return; } Containers::ScopeGuard drwavClose{handle, drwav_close}; const std::uint64_t samples = handle->totalSampleCount; const std::uint32_t frequency = handle->sampleRate; const std::uint8_t numChannels = handle->channels; const std::uint8_t bitsPerSample = handle->bitsPerSample; /* If the bits per sample is exact, we can read data raw */ const Int notExactBitsPerSample = ((bitsPerSample % 8) ? 1 : 0); /* Normalize bit amounts to multiples of 8, rounding up */ const UnsignedInt normalizedBytesPerSample = (bitsPerSample / 8) + notExactBitsPerSample; if(numChannels == 0 || numChannels == 3 || numChannels == 5 || numChannels > 8 || normalizedBytesPerSample == 0 || normalizedBytesPerSample > 8) { Error() << "Audio::DrWavImporter::openData(): unsupported channel count" << numChannels << "with" << bitsPerSample << "bits per sample"; return; } /* Can't load something with no samples */ if(samples == 0) { Error() << "Audio::DrWavImporter::openData(): no samples"; return; } _frequency = frequency; /* PCM has a lot of special cases, as we can read many formats directly */ if(handle->translatedFormatTag == DR_WAVE_FORMAT_PCM) { _format = PcmFormatTable[numChannels-1][normalizedBytesPerSample-1]; CORRADE_INTERNAL_ASSERT(_format != BufferFormat{}); /* If the data is exactly 8 or 16 bits, we can read it raw */ if(!notExactBitsPerSample && normalizedBytesPerSample < 3) { _data = readRaw(handle, samples, normalizedBytesPerSample); return; /* If the data is approximately 24 bits or has many channels, a float is more than enough */ } else if(normalizedBytesPerSample == 3 || (normalizedBytesPerSample > 3 && numChannels > 3)) { _data = read32fPcm(handle, samples, numChannels, _format); return; /* If the data is close to 8 or 16 bits, we can convert it from 32-bit PCM */ } else if(normalizedBytesPerSample == 1 || normalizedBytesPerSample == 2) { Containers::Array<char> tempData(samples*sizeof(Int)); drwav_read_s32(handle, samples, reinterpret_cast<Int*>(tempData.begin())); /* 32-bit PCM can be sliced down to 8 or 16 for direct reading */ _data = convert32Pcm(tempData, samples, normalizedBytesPerSample); /* Convert 8 bit data to unsigned */ if(normalizedBytesPerSample == 1) for(char& item: _data) item = item - 128; return; } /** @todo Allow loading of 32/64 bit streams to Double format to preserve all information */ /* ALaw of 8/16 bits with 1/2 channels can be loaded directly */ } else if(handle->translatedFormatTag == DR_WAVE_FORMAT_ALAW) { if(numChannels < 3 && !notExactBitsPerSample && (bitsPerSample == 8 || bitsPerSample == 16) ) { _format = ALawFormatTable[numChannels-1][normalizedBytesPerSample-1]; _data = readRaw(handle, samples, normalizedBytesPerSample); return; } /* MuLaw of 8/16 bits with 1/2 channels can be loaded directly */ } else if(handle->translatedFormatTag == DR_WAVE_FORMAT_MULAW) { if(numChannels < 3 && !notExactBitsPerSample && (bitsPerSample == 8 || bitsPerSample == 16) ) { _format = MuLawFormatTable[numChannels-1][normalizedBytesPerSample-1]; _data = readRaw(handle, samples, normalizedBytesPerSample); return; } /* IEEE float or double can be loaded directly */ } else if(handle->translatedFormatTag == DR_WAVE_FORMAT_IEEE_FLOAT) { if(!notExactBitsPerSample && (bitsPerSample == 32 || bitsPerSample == 64)) { _format = IeeeFormatTable[numChannels-1][(normalizedBytesPerSample / 4)-1]; _data = readRaw(handle, samples, normalizedBytesPerSample); return; } } /* If we don't know what the format is, read it out as 32 bit float for compatibility */ _data = read32fPcm(handle, samples, numChannels, _format); return; }
void DrFlacImporter::doOpenData(Containers::ArrayView<const char> data) { drflac* const handle = drflac_open_memory(data.data(), data.size()); if(!handle) { Error() << "Audio::DrFlacImporter::openData(): failed to open and decode FLAC data"; return; } Containers::ScopeGuard drflacClose{handle, drflac_close}; const std::uint64_t samples = handle->totalSampleCount; const std::uint8_t numChannels = handle->channels; const std::uint8_t bitsPerSample = handle->bitsPerSample; /* FLAC supports any bitspersample from 4 to 64, but DrFlac always gives us 32-bit samples. So we normalize bit amounts to multiples of 8, rounding up. */ const UnsignedInt normalizedBytesPerSample = (bitsPerSample + 7)/8; if(numChannels == 0 || numChannels == 3 || numChannels == 5 || numChannels > 8 || normalizedBytesPerSample == 0 || normalizedBytesPerSample > 8) { Error() << "Audio::DrFlacImporter::openData(): unsupported channel count" << numChannels << "with" << bitsPerSample << "bits per sample"; return; } /* Can't load something with no samples */ if(samples == 0) { Error() << "Audio::DrFlacImporter::openData(): no samples"; return; } _frequency = handle->sampleRate; _format = flacFormatTable[numChannels-1][normalizedBytesPerSample-1]; CORRADE_INTERNAL_ASSERT(_format != BufferFormat{}); /* 32-bit integers need to be normalized to Double (with a 32 bit mantissa) */ if(normalizedBytesPerSample == 4) { Containers::Array<Int> tempData(samples); drflac_read_s32(handle, samples, reinterpret_cast<Int*>(tempData.begin())); /* If the channel is mono/stereo, we can use double samples */ if(numChannels < 3) { Containers::Array<Double> doubleData(samples); for(std::size_t i = 0; i < samples; ++i) { doubleData[i] = Math::unpack<Double>(tempData[i]); } const char* doubleBegin = reinterpret_cast<const char*>(doubleData.begin()); const char* doubleEnd = reinterpret_cast<const char*>(doubleData.end()); _data = Containers::Array<char>(samples*sizeof(Double)); std::copy(doubleBegin, doubleEnd, _data.begin()); /* Otherwise, convert to float */ } else { Containers::Array<Float> floatData(samples); for(std::size_t i = 0; i < samples; ++i) { floatData[i] = Math::unpack<Float>(tempData[i]); } const char* floatBegin = reinterpret_cast<const char*>(floatData.begin()); const char* floatEnd = reinterpret_cast<const char*>(floatData.end()); _data = Containers::Array<char>(samples*sizeof(Float)); std::copy(floatBegin, floatEnd, _data.begin()); } return; } Containers::Array<char> tempData(samples*sizeof(Int)); drflac_read_s32(handle, samples, reinterpret_cast<Int*>(tempData.begin())); _data = convert32PCM(tempData, samples, normalizedBytesPerSample); /* 8-bit needs to become unsigned */ if(normalizedBytesPerSample == 1) { for(char& item: _data) item = item - 128; /* 24-bit needs to become float */ } else if(normalizedBytesPerSample == 3) { Containers::Array<Float> floatData(samples); for(std::size_t i = 0; i != samples; ++i) { const UnsignedInt s0 = _data[i*3 + 0]; const UnsignedInt s1 = _data[i*3 + 1]; const UnsignedInt s2 = _data[i*3 + 2]; const Int intData = Int((s0 << 8) | (s1 << 16) | (s2 << 24)); floatData[i] = Math::unpack<Float>(intData); } const char* const floatBegin = reinterpret_cast<const char*>(floatData.begin()); const char* const floatEnd = reinterpret_cast<const char*>(floatData.end()); _data = Containers::Array<char>(samples*sizeof(Float)); std::copy(floatBegin, floatEnd, _data.begin()); } return; }