--- libgig/trunk/src/gig.cpp 2021/05/12 18:55:31 3904 +++ libgig/trunk/src/gig.cpp 2021/06/15 11:00:50 3927 @@ -482,8 +482,8 @@ ScanCompressedSample(); } - // we use a buffer for decompression and for truncating 24 bit samples to 16 bit - if ((Compressed || BitDepth == 24) && !InternalDecompressionBuffer.Size) { + // we use a buffer for decompression only + if (Compressed && !InternalDecompressionBuffer.Size) { InternalDecompressionBuffer.pStart = new unsigned char[INITIAL_SAMPLE_BUFFER_SIZE]; InternalDecompressionBuffer.Size = INITIAL_SAMPLE_BUFFER_SIZE; } @@ -3498,13 +3498,14 @@ RIFF::List* _3prg = rgn->GetSubList(LIST_TYPE_3PRG); if (_3prg) { int dimensionRegionNr = 0; - RIFF::List* _3ewl = _3prg->GetFirstSubList(); - while (_3ewl) { + size_t i = 0; + for (RIFF::List* _3ewl = _3prg->GetSubListAt(i); _3ewl; + _3ewl = _3prg->GetSubListAt(++i)) + { if (_3ewl->GetListType() == LIST_TYPE_3EWL) { pDimensionRegions[dimensionRegionNr] = new DimensionRegion(this, _3ewl); dimensionRegionNr++; } - _3ewl = _3prg->GetNextSubList(); } if (dimensionRegionNr == 0) throw gig::Exception("No dimension region found."); } @@ -4906,8 +4907,9 @@ pScripts = new std::list; if (!pList) return; - for (RIFF::Chunk* ck = pList->GetFirstSubChunk(); ck; - ck = pList->GetNextSubChunk()) + size_t i = 0; + for (RIFF::Chunk* ck = pList->GetSubChunkAt(i); ck; + ck = pList->GetSubChunkAt(++i)) { if (ck->GetChunkID() == CHUNK_ID_SCRI) { pScripts->push_back(new Script(this, ck)); @@ -4987,14 +4989,15 @@ if (!pRegions) pRegions = new RegionList; RIFF::List* lrgn = insList->GetSubList(LIST_TYPE_LRGN); if (lrgn) { - RIFF::List* rgn = lrgn->GetFirstSubList(); - while (rgn) { + size_t i = 0; + for (RIFF::List* rgn = lrgn->GetSubListAt(i); rgn; + rgn = lrgn->GetSubListAt(++i)) + { if (rgn->GetListType() == LIST_TYPE_RGN) { if (pProgress) __notify_progress(pProgress, (float) pRegions->size() / (float) Regions); pRegions->push_back(new Region(this, rgn)); } - rgn = lrgn->GetNextSubList(); } // Creating Region Key Table for fast lookup UpdateRegionKeyTable(); @@ -5298,11 +5301,28 @@ } /** + * Returns Region at supplied @a pos position within the region list of + * this instrument. If supplied @a pos is out of bounds then @c NULL is + * returned. + * + * @param pos - position of sought Region in region list + * @returns pointer address to requested region or @c NULL if @a pos is + * out of bounds + */ + Region* Instrument::GetRegionAt(size_t pos) { + if (!pRegions) return NULL; + if (pos >= pRegions->size()) return NULL; + return static_cast( (*pRegions)[pos] ); + } + + /** * Returns the first Region of the instrument. You have to call this * method once before you use GetNextRegion(). * * @returns pointer address to first region or NULL if there is none * @see GetNextRegion() + * @deprecated This method is not reentrant-safe, use GetRegionAt() + * instead. */ Region* Instrument::GetFirstRegion() { if (!pRegions) return NULL; @@ -5317,6 +5337,8 @@ * * @returns pointer address to the next region or NULL if end reached * @see GetFirstRegion() + * @deprecated This method is not reentrant-safe, use GetRegionAt() + * instead. */ Region* Instrument::GetNextRegion() { if (!pRegions) return NULL; @@ -5983,7 +6005,7 @@ pMidiRules[0] = NULL; // delete all old regions - while (Regions) DeleteRegion(GetFirstRegion()); + while (Regions) DeleteRegion(GetRegionAt(0)); // create new regions and copy them from original { RegionList::const_iterator it = orig->pRegions->begin(); @@ -6083,7 +6105,8 @@ if (!pNameChunk && pFile->pVersion && pFile->pVersion->major > 2) { // v3 has a fixed list of 128 strings, find a free one - for (RIFF::Chunk* ck = _3gnl->GetFirstSubChunk() ; ck ; ck = _3gnl->GetNextSubChunk()) { + size_t i = 0; + for (RIFF::Chunk* ck = _3gnl->GetSubChunkAt(i); ck; ck = _3gnl->GetSubChunkAt(++i)) { if (strcmp(static_cast(ck->LoadChunkData()), "") == 0) { pNameChunk = ck; break; @@ -6336,9 +6359,10 @@ // remove all references to the sample for (Instrument* instrument = GetFirstInstrument() ; instrument ; instrument = GetNextInstrument()) { - for (Region* region = instrument->GetFirstRegion() ; region ; - region = instrument->GetNextRegion()) { - + size_t iRgn = 0; + for (Region* region = instrument->GetRegionAt(iRgn); region; + region = instrument->GetRegionAt(++iRgn)) + { if (region->GetSample() == pSample) region->SetSample(NULL); for (int i = 0 ; i < region->DimensionRegions ; i++) { @@ -6361,8 +6385,6 @@ if (!pSamples) pSamples = new SampleList; - RIFF::File* file = pRIFF; - // just for progress calculation int iSampleIndex = 0; int iTotalSamples = WavePoolCount; @@ -6443,8 +6465,10 @@ if (wvpl) { file_offset_t wvplFileOffset = wvpl->GetFilePos() - wvpl->GetPos(); // should be zero, but just to be sure - RIFF::List* wave = wvpl->GetFirstSubList(); - while (wave) { + size_t i = 0; + for (RIFF::List* wave = wvpl->GetSubListAt(i); wave; + wave = wvpl->GetSubListAt(++i)) + { if (wave->GetListType() == LIST_TYPE_WAVE) { // notify current progress if (pProgress) { @@ -6457,7 +6481,6 @@ iSampleIndex++; } - wave = wvpl->GetNextSubList(); } } } @@ -6690,8 +6713,10 @@ RIFF::List* lstInstruments = pRIFF->GetSubList(LIST_TYPE_LINS); if (lstInstruments) { int iInstrumentIndex = 0; - RIFF::List* lstInstr = lstInstruments->GetFirstSubList(); - while (lstInstr) { + size_t i = 0; + for (RIFF::List* lstInstr = lstInstruments->GetSubListAt(i); + lstInstr; lstInstr = lstInstruments->GetSubListAt(++i)) + { if (lstInstr->GetListType() == LIST_TYPE_INS) { if (pProgress) { // notify current progress @@ -6709,7 +6734,6 @@ iInstrumentIndex++; } - lstInstr = lstInstruments->GetNextSubList(); } if (pProgress) __notify_progress(pProgress, 1.0); // notify done @@ -6975,15 +6999,16 @@ if (lst3gri) { RIFF::List* lst3gnl = lst3gri->GetSubList(LIST_TYPE_3GNL); if (lst3gnl) { - RIFF::Chunk* ck = lst3gnl->GetFirstSubChunk(); - while (ck) { + size_t i = 0; + for (RIFF::Chunk* ck = lst3gnl->GetSubChunkAt(i); ck; + ck = lst3gnl->GetSubChunkAt(++i)) + { if (ck->GetChunkID() == CHUNK_ID_3GNM) { if (pVersion && pVersion->major > 2 && strcmp(static_cast(ck->LoadChunkData()), "") == 0) break; pGroups->push_back(new Group(this, ck)); } - ck = lst3gnl->GetNextSubChunk(); } } } @@ -7073,8 +7098,9 @@ pScriptGroups = new std::list; RIFF::List* lstLS = pRIFF->GetSubList(LIST_TYPE_3LS); if (lstLS) { - for (RIFF::List* lst = lstLS->GetFirstSubList(); lst; - lst = lstLS->GetNextSubList()) + size_t i = 0; + for (RIFF::List* lst = lstLS->GetSubListAt(i); lst; + lst = lstLS->GetSubListAt(++i)) { if (lst->GetListType() == LIST_TYPE_RTIS) { pScriptGroups->push_back(new ScriptGroup(this, lst)); @@ -7135,7 +7161,7 @@ // INFO was added by Resource::UpdateChunks - make sure it // is placed first in file RIFF::Chunk* info = pRIFF->GetSubList(LIST_TYPE_INFO); - RIFF::Chunk* first = pRIFF->GetFirstSubChunk(); + RIFF::Chunk* first = pRIFF->GetSubChunkAt(0); if (first != info) { pRIFF->MoveSubChunk(info, first); } @@ -7156,12 +7182,13 @@ // v3: make sure the file has 128 3gnm chunks // (before updating the Group chunks) if (pVersion && pVersion->major > 2) { - RIFF::Chunk* _3gnm = _3gnl->GetFirstSubChunk(); - for (int i = 0 ; i < 128 ; i++) { + size_t i = 0; + for (RIFF::Chunk* _3gnm = _3gnl->GetSubChunkAt(i); i < 128; + _3gnm = _3gnl->GetSubChunkAt(++i)) + { // create 128 empty placeholder strings which will either // be filled by Group::UpdateChunks below or left empty. ::SaveString(CHUNK_ID_3GNM, _3gnm, _3gnl, "", "", true, 64); - if (_3gnm) _3gnm = _3gnl->GetNextSubChunk(); } } @@ -7227,8 +7254,10 @@ memset(&pData[(instrumentIdx + 1) * sublen + 48], 0, sublen - 48); - for (Region* region = instrument->GetFirstRegion() ; region ; - region = instrument->GetNextRegion()) { + size_t iRgn = 0; + for (Region* region = instrument->GetRegionAt(iRgn); region; + region = instrument->GetRegionAt(++iRgn)) + { for (int i = 0 ; i < region->DimensionRegions ; i++) { gig::DimensionRegion *d = region->pDimensionRegions[i]; if (d->pSample) {