From: <sag...@us...> - 2011-03-19 22:02:47
|
Revision: 822 http://modplug.svn.sourceforge.net/modplug/?rev=822&view=rev Author: saga-games Date: 2011-03-19 22:02:38 +0000 (Sat, 19 Mar 2011) Log Message: ----------- [Fix] FreePattern() was not deallocating pattern data properly (delete vs. delete[]). [Ref] Moved AllocatePattern() / FreePattern() to CPattern, as I think it makes more sense. Modified Paths: -------------- trunk/OpenMPT/mptrack/CleanupSong.cpp trunk/OpenMPT/mptrack/Modedit.cpp trunk/OpenMPT/mptrack/Undo.cpp trunk/OpenMPT/mptrack/View_pat.cpp trunk/OpenMPT/soundlib/LOAD_AMF.CPP trunk/OpenMPT/soundlib/Load_itp.cpp trunk/OpenMPT/soundlib/Load_mdl.cpp trunk/OpenMPT/soundlib/Load_mid.cpp trunk/OpenMPT/soundlib/Sndfile.cpp trunk/OpenMPT/soundlib/pattern.cpp trunk/OpenMPT/soundlib/pattern.h trunk/OpenMPT/soundlib/patternContainer.cpp trunk/OpenMPT/soundlib/patternContainer.h Modified: trunk/OpenMPT/mptrack/CleanupSong.cpp =================================================================== --- trunk/OpenMPT/mptrack/CleanupSong.cpp 2011-03-19 16:37:10 UTC (rev 821) +++ trunk/OpenMPT/mptrack/CleanupSong.cpp 2011-03-19 22:02:38 UTC (rev 822) @@ -392,6 +392,7 @@ } // Remove all completely empty patterns above last used pattern (those are safe to remove) + BEGIN_CRITICAL(); for (PATTERNINDEX nPat = maxpat; nPat < maxPatIndex; nPat++) if ((pSndFile->Patterns[nPat]) && (nPat >= nMinToRemove)) { if(pSndFile->Patterns.IsPatternEmpty(nPat)) @@ -400,6 +401,7 @@ nPatRemoved++; } } + END_CRITICAL(); // Number of unused patterns size_t nWaste = 0; Modified: trunk/OpenMPT/mptrack/Modedit.cpp =================================================================== --- trunk/OpenMPT/mptrack/Modedit.cpp 2011-03-19 16:37:10 UTC (rev 821) +++ trunk/OpenMPT/mptrack/Modedit.cpp 2011-03-19 22:02:38 UTC (rev 822) @@ -74,7 +74,7 @@ for (UINT i=0; i<m_SndFile.Patterns.Size(); i++) if (m_SndFile.Patterns[i]) { MODCOMMAND *p = m_SndFile.Patterns[i]; - MODCOMMAND *newp = CSoundFile::AllocatePattern(m_SndFile.Patterns[i].GetNumRows(), nNewChannels); + MODCOMMAND *newp = CPattern::AllocatePattern(m_SndFile.Patterns[i].GetNumRows(), nNewChannels); if (!newp) { END_CRITICAL(); @@ -86,7 +86,7 @@ memcpy(&newp[j*nNewChannels], &p[j*m_SndFile.m_nChannels], m_SndFile.m_nChannels*sizeof(MODCOMMAND)); } m_SndFile.Patterns[i] = newp; - CSoundFile::FreePattern(p); + CPattern::FreePattern(p); } //if channel was removed before and is added again, mute status has to be unset! (bug 1814) @@ -134,7 +134,7 @@ for (i=0; i<m_SndFile.Patterns.Size(); i++) if (m_SndFile.Patterns[i]) { MODCOMMAND *p = m_SndFile.Patterns[i]; - MODCOMMAND *newp = CSoundFile::AllocatePattern(m_SndFile.Patterns[i].GetNumRows(), nRemainingChannels); + MODCOMMAND *newp = CPattern::AllocatePattern(m_SndFile.Patterns[i].GetNumRows(), nRemainingChannels); if (!newp) { END_CRITICAL(); @@ -150,7 +150,7 @@ } } m_SndFile.Patterns[i] = newp; - CSoundFile::FreePattern(p); + CPattern::FreePattern(p); } UINT tmpchn = 0; for (i=0; i<m_SndFile.m_nChannels; i++) @@ -517,10 +517,8 @@ if ((nPat < m_SndFile.Patterns.Size()) && (m_SndFile.Patterns[nPat])) { BEGIN_CRITICAL(); - LPVOID p = m_SndFile.Patterns[nPat]; - m_SndFile.Patterns[nPat] = nullptr; m_SndFile.SetPatternName(nPat, ""); - CSoundFile::FreePattern(p); + m_SndFile.Patterns.Remove(nPat); END_CRITICAL(); SetModified(); return true; Modified: trunk/OpenMPT/mptrack/Undo.cpp =================================================================== --- trunk/OpenMPT/mptrack/Undo.cpp 2011-03-19 16:37:10 UTC (rev 821) +++ trunk/OpenMPT/mptrack/Undo.cpp 2011-03-19 22:02:38 UTC (rev 822) @@ -133,7 +133,7 @@ { if((!pSndFile->Patterns[nPattern]) || (pSndFile->Patterns[nPattern].GetNumRows() < nRows)) { - MODCOMMAND *newPattern = CSoundFile::AllocatePattern(nRows, pSndFile->m_nChannels); + MODCOMMAND *newPattern = CPattern::AllocatePattern(nRows, pSndFile->m_nChannels); MODCOMMAND *oldPattern = pSndFile->Patterns[nPattern]; if (!newPattern) return PATTERNINDEX_INVALID; const ROWINDEX nOldRowCount = pSndFile->Patterns[nPattern].GetNumRows(); @@ -141,7 +141,7 @@ if(oldPattern) { memcpy(newPattern, oldPattern, pSndFile->m_nChannels * nOldRowCount * sizeof(MODCOMMAND)); - CSoundFile::FreePattern(oldPattern); + CPattern::FreePattern(oldPattern); } } linkToPrevious = pUndo->linkToPrevious; Modified: trunk/OpenMPT/mptrack/View_pat.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_pat.cpp 2011-03-19 16:37:10 UTC (rev 821) +++ trunk/OpenMPT/mptrack/View_pat.cpp 2011-03-19 22:02:38 UTC (rev 822) @@ -2483,7 +2483,7 @@ dy = (int)(m_dwDragPos >> 16) - (int)(m_dwStartSel >> 16); if ((!dx) && (!dy)) return; pModDoc->GetPatternUndo()->PrepareUndo(m_nPattern, 0,0, nChannels, nRows); - pNewPattern = CSoundFile::AllocatePattern(nRows, nChannels); + pNewPattern = CPattern::AllocatePattern(nRows, nChannels); if (!pNewPattern) return; x1 = (m_dwBeginSel & 0xFFF8) >> 3; y1 = (m_dwBeginSel) >> 16; @@ -2559,7 +2559,7 @@ SetCursorPosition( y1, (x1<<3)|c1 ); SetCurSel((y1<<16)|(x1<<3)|c1, (y2<<16)|(x2<<3)|c2); InvalidatePattern(); - CSoundFile::FreePattern(pOldPattern); + CPattern::FreePattern(pOldPattern); pModDoc->SetModified(); EndWaitCursor(); } Modified: trunk/OpenMPT/soundlib/LOAD_AMF.CPP =================================================================== --- trunk/OpenMPT/soundlib/LOAD_AMF.CPP 2011-03-19 16:37:10 UTC (rev 821) +++ trunk/OpenMPT/soundlib/LOAD_AMF.CPP 2011-03-19 22:02:38 UTC (rev 822) @@ -312,13 +312,13 @@ } // Setup sequence list Order.resize(pfh->numorders, Order.GetInvalidPatIndex()); + vector<ROWINDEX> patternLength(pfh->numorders, 64); for (UINT iOrd=0; iOrd < pfh->numorders; iOrd++) { Order[iOrd] = iOrd; - Patterns[iOrd].Resize(64, false); if (pfh->version >= 14) { - Patterns[iOrd].Resize(LittleEndianW(*(USHORT *)(lpStream+dwMemPos))); + patternLength[iOrd] = LittleEndianW(*(uint16 *)(lpStream+dwMemPos)); dwMemPos += 2; } ptracks[iOrd] = (USHORT *)(lpStream+dwMemPos); @@ -386,9 +386,10 @@ // Create the patterns from the list of tracks for (UINT iPat=0; iPat<pfh->numorders; iPat++) { - MODCOMMAND *p = AllocatePattern(Patterns[iPat].GetNumRows(), m_nChannels); - if (!p) break; - Patterns[iPat] = p; + if(Patterns.Insert(iPat, patternLength[iPat])) + { + break; + } for (UINT iChn=0; iChn<m_nChannels; iChn++) { UINT nTrack = LittleEndianW(ptracks[iPat][iChn]); @@ -400,7 +401,7 @@ realtrk--; if ((realtrk < realtrackcnt) && (pTrackData[realtrk])) { - AMF_Unpack(p+iChn, pTrackData[realtrk], Patterns[iPat].GetNumRows(), m_nChannels); + AMF_Unpack(Patterns[iPat].GetpModCommand(0, iChn), pTrackData[realtrk], Patterns[iPat].GetNumRows(), m_nChannels); } } } Modified: trunk/OpenMPT/soundlib/Load_itp.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_itp.cpp 2011-03-19 16:37:10 UTC (rev 821) +++ trunk/OpenMPT/soundlib/Load_itp.cpp 2011-03-19 22:02:38 UTC (rev 822) @@ -256,21 +256,20 @@ for(PATTERNINDEX npat=0; npat<size; npat++) { - // Free pattern if not empty - if(Patterns[npat]) { FreePattern(Patterns[npat]); Patterns[npat] = NULL; } - // Patterns[npat].GetNumRows() ASSERT_CAN_READ(4); memcpy(&id,lpStream+dwMemPos,sizeof(DWORD)); if(id > MAX_PATTERN_ROWS) return false; - Patterns[npat].Resize(id, false); + const ROWINDEX nRows = id; dwMemPos += sizeof(DWORD); // Try to allocate & read only sized patterns - if(Patterns[npat].GetNumRows()){ + if(nRows) + { // Allocate pattern - if(Patterns.Insert(npat, Patterns[npat].GetNumRows())){ + if(Patterns.Insert(npat, nRows)) + { dwMemPos += m_nChannels * Patterns[npat].GetNumRows() * n; continue; } Modified: trunk/OpenMPT/soundlib/Load_mdl.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_mdl.cpp 2011-03-19 16:37:10 UTC (rev 821) +++ trunk/OpenMPT/soundlib/Load_mdl.cpp 2011-03-19 22:02:38 UTC (rev 822) @@ -241,6 +241,7 @@ BYTE inspanenv[MAX_INSTRUMENTS]; LPCBYTE pvolenv, ppanenv, ppitchenv; UINT nvolenv, npanenv, npitchenv; + vector<ROWINDEX> patternLength; if ((!lpStream) || (dwMemLength < 1024)) return false; if ((pmsh->id != 0x4C444D44) || ((pmsh->version & 0xF0) > 0x10)) return false; @@ -313,6 +314,9 @@ npatterns = lpStream[dwMemPos]; if (npatterns > MAX_PATTERNS) npatterns = MAX_PATTERNS; dwPos = dwMemPos + 1; + + patternLength.assign(npatterns, 64); + for (i=0; i<npatterns; i++) { const WORD *pdata; @@ -323,7 +327,7 @@ { const MDLPATTERNDATA *pmpd = (const MDLPATTERNDATA *)(lpStream + dwPos); if (pmpd->channels > 32) break; - Patterns[i].Resize(pmpd->lastrow+1); + patternLength[i] = pmpd->lastrow + 1; if (m_nChannels < pmpd->channels) m_nChannels = pmpd->channels; dwPos += 18 + 2*pmpd->channels; pdata = pmpd->data; @@ -331,7 +335,7 @@ } else { pdata = (const WORD *)(lpStream + dwPos); - Patterns[i].Resize(64, false); + //Patterns[i].Resize(64, false); if (m_nChannels < 32) m_nChannels = 32; dwPos += 2*32; ch = 32; @@ -527,7 +531,10 @@ { for (UINT ipat=0; ipat<npatterns; ipat++) { - if ((Patterns[ipat] = AllocatePattern(Patterns[ipat].GetNumRows(), m_nChannels)) == NULL) break; + if(Patterns.Insert(ipat, patternLength[ipat])) + { + break; + } for (UINT chn=0; chn<m_nChannels; chn++) if ((patterntracks[ipat*32+chn]) && (patterntracks[ipat*32+chn] <= ntracks)) { MODCOMMAND *m = Patterns[ipat] + chn; Modified: trunk/OpenMPT/soundlib/Load_mid.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_mid.cpp 2011-03-19 16:37:10 UTC (rev 821) +++ trunk/OpenMPT/soundlib/Load_mid.cpp 2011-03-19 22:02:38 UTC (rev 822) @@ -571,7 +571,6 @@ memset(midichstate, 0, sizeof(midichstate)); // Initializing Patterns Order[0] = 0; - for (UINT ipat=0; ipat<Patterns.Size(); ipat++) Patterns[ipat].Resize(gnMidiPatternLen, false); // Initializing Channels for (UINT ics=0; ics<MAX_BASECHANNELS; ics++) { @@ -628,10 +627,9 @@ do { // Allocate current pattern if not allocated yet - if (!Patterns[pat]) + if (!Patterns[pat] && Patterns.Insert(pat, gnMidiPatternLen)) { - Patterns[pat] = AllocatePattern(Patterns[pat].GetNumRows(), m_nChannels); - if (!Patterns[pat]) break; + break; } dwGlobalFlags |= MIDIGLOBAL_SONGENDED; MODCOMMAND *m = Patterns[pat] + row * m_nChannels; Modified: trunk/OpenMPT/soundlib/Sndfile.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.cpp 2011-03-19 16:37:10 UTC (rev 821) +++ trunk/OpenMPT/soundlib/Sndfile.cpp 2011-03-19 22:02:38 UTC (rev 822) @@ -517,9 +517,9 @@ BOOL CSoundFile::Create(LPCBYTE lpStream, CModDoc *pModDoc, DWORD dwMemLength) -//--------------------------------------------------------------------------- +//---------------------------------------------------------------------------- { - m_pModDoc=pModDoc; + m_pModDoc = pModDoc; m_nType = MOD_TYPE_NONE; m_dwSongFlags = 0; m_nChannels = 0; @@ -564,7 +564,6 @@ memset(&m_SongEQ, 0, sizeof(m_SongEQ)); ResetMidiCfg(); - //for (UINT npt=0; npt<Patterns.Size(); npt++) Patterns[npt].GetNumRows() = 64; for (CHANNELINDEX nChn = 0; nChn < MAX_BASECHANNELS; nChn++) { InitChannel(nChn); @@ -731,8 +730,8 @@ pSmp->nSustainStart = 0; pSmp->nSustainEnd = 0; } - if (!pSmp->nLoopEnd) pSmp->uFlags &= ~CHN_LOOP; - if (!pSmp->nSustainEnd) pSmp->uFlags &= ~CHN_SUSTAINLOOP; + if (!pSmp->nLoopEnd) pSmp->uFlags &= ~(CHN_LOOP|CHN_PINGPONGLOOP); + if (!pSmp->nSustainEnd) pSmp->uFlags &= ~(CHN_SUSTAINLOOP|CHN_PINGPONGSUSTAIN); if (pSmp->nGlobalVol > 64) pSmp->nGlobalVol = 64; } // Check invalid instruments @@ -827,7 +826,7 @@ for(std::list<PLUGINDEX>::iterator i = notFoundIDs.begin(); i != notFoundIDs.end(); ++i) { CString sUrl; - sUrl.Format("http://www.kvraudio.com/search.php?q=%s&lq=db", m_MixPlugins[*i].Info.szLibraryName); + sUrl.Format("http://www.kvraudio.com/search.php?lq=inurl%3Aget&q=%s", m_MixPlugins[*i].Info.szLibraryName); CTrackApp::OpenURL(sUrl); } } @@ -853,11 +852,7 @@ //------------------------ { size_t i; - for (i=0; i<Patterns.Size(); i++) if (Patterns[i]) - { - FreePattern(Patterns[i]); - Patterns[i] = NULL; - } + Patterns.DestroyPatterns(); m_nPatternNames = 0; delete[] m_lpszPatternNames; @@ -903,23 +898,6 @@ ////////////////////////////////////////////////////////////////////////// // Memory Allocation -MODCOMMAND *CSoundFile::AllocatePattern(UINT rows, UINT nchns) -//------------------------------------------------------------ -{ - MODCOMMAND *p = new MODCOMMAND[rows*nchns]; - if (p) memset(p, 0, rows*nchns*sizeof(MODCOMMAND)); - return p; -} - - -void CSoundFile::FreePattern(LPVOID pat) -//-------------------------------------- -{ - - if (pat) delete pat; -} - - LPSTR CSoundFile::AllocateSample(UINT nbytes) //------------------------------------------- { @@ -1551,7 +1529,7 @@ if (Patterns[nPat]) { MODCOMMAND *p = Patterns[nPat]; - MODCOMMAND *newp = CSoundFile::AllocatePattern(Patterns[nPat].GetNumRows(), nRemainingChannels); + MODCOMMAND *newp = CPattern::AllocatePattern(Patterns[nPat].GetNumRows(), nRemainingChannels); if (!newp) { END_CRITICAL(); @@ -1571,7 +1549,7 @@ } } Patterns[nPat] = newp; - CSoundFile::FreePattern(p); + CPattern::FreePattern(p); } } Modified: trunk/OpenMPT/soundlib/pattern.cpp =================================================================== --- trunk/OpenMPT/soundlib/pattern.cpp 2011-03-19 16:37:10 UTC (rev 821) +++ trunk/OpenMPT/soundlib/pattern.cpp 2011-03-19 22:02:38 UTC (rev 822) @@ -55,11 +55,11 @@ BEGIN_CRITICAL(); if (newRowCount > m_Rows) { - MODCOMMAND *p = CSoundFile::AllocatePattern(newRowCount, sndFile.m_nChannels); + MODCOMMAND *p = AllocatePattern(newRowCount, sndFile.m_nChannels); if (p) { memcpy(p, m_ModCommands, sndFile.m_nChannels*m_Rows*sizeof(MODCOMMAND)); - CSoundFile::FreePattern(m_ModCommands); + FreePattern(m_ModCommands); m_ModCommands = p; m_Rows = newRowCount; } @@ -93,11 +93,11 @@ #endif // MODPLUG_TRACKER if (bOk) { - MODCOMMAND *pnew = CSoundFile::AllocatePattern(newRowCount, sndFile.m_nChannels); + MODCOMMAND *pnew = AllocatePattern(newRowCount, sndFile.m_nChannels); if (pnew) { memcpy(pnew, m_ModCommands, sndFile.m_nChannels*newRowCount*sizeof(MODCOMMAND)); - CSoundFile::FreePattern(m_ModCommands); + FreePattern(m_ModCommands); m_ModCommands = pnew; m_Rows = newRowCount; } @@ -121,11 +121,12 @@ void CPattern::Deallocate() //------------------------- { - BEGIN_CRITICAL(); + // Removed critical section as it can cause problems when destroying patterns in the CSoundFile constructor. + //BEGIN_CRITICAL(); m_Rows = m_RowsPerBeat = m_RowsPerMeasure = 0; - CSoundFile::FreePattern(m_ModCommands); + FreePattern(m_ModCommands); m_ModCommands = nullptr; - END_CRITICAL(); + //END_CRITICAL(); } bool CPattern::Expand() @@ -143,7 +144,7 @@ rModDoc.BeginWaitCursor(); const ROWINDEX nRows = m_Rows; const CHANNELINDEX nChns = sndFile.m_nChannels; - newPattern = CSoundFile::AllocatePattern(nRows * 2, nChns); + newPattern = AllocatePattern(nRows * 2, nChns); if (!newPattern) return true; const PATTERNINDEX nPattern = m_rPatternContainer.GetIndex(this); @@ -155,7 +156,7 @@ } m_ModCommands = newPattern; m_Rows = nRows * 2; - CSoundFile::FreePattern(oldPattern); oldPattern = nullptr; + FreePattern(oldPattern); oldPattern = nullptr; rModDoc.SetModified(); rModDoc.UpdateAllViews(NULL, HINT_PATTERNDATA | (nPattern << HINT_SHIFT_PAT), NULL); rModDoc.EndWaitCursor(); @@ -210,7 +211,22 @@ } +MODCOMMAND *CPattern::AllocatePattern(ROWINDEX rows, CHANNELINDEX nchns) +//---------------------------------------------------------------------- +{ + MODCOMMAND *p = new MODCOMMAND[rows*nchns]; + if (p) memset(p, 0, rows*nchns*sizeof(MODCOMMAND)); + return p; +} + +void CPattern::FreePattern(MODCOMMAND *pat) +//----------------------------------------- +{ + if (pat) delete[] pat; +} + + bool CPattern::WriteITPdata(FILE* f) const //---------------------------------------- { Modified: trunk/OpenMPT/soundlib/pattern.h =================================================================== --- trunk/OpenMPT/soundlib/pattern.h 2011-03-19 16:37:10 UTC (rev 821) +++ trunk/OpenMPT/soundlib/pattern.h 2011-03-19 22:02:38 UTC (rev 822) @@ -86,6 +86,10 @@ //4. Length of the stream. //Returns true on error. + // Static allocation / deallocation helpers + static MODCOMMAND* AllocatePattern(ROWINDEX rows, CHANNELINDEX nchns); + static void FreePattern(MODCOMMAND *pat); + //END: INTERFACE METHODS typedef MODCOMMAND* iterator; Modified: trunk/OpenMPT/soundlib/patternContainer.cpp =================================================================== --- trunk/OpenMPT/soundlib/patternContainer.cpp 2011-03-19 16:37:10 UTC (rev 821) +++ trunk/OpenMPT/soundlib/patternContainer.cpp 2011-03-19 22:02:38 UTC (rev 822) @@ -5,11 +5,30 @@ #include "../mptrack/serialization_utils.h" #include "../mptrack/version.h" + +void CPatternContainer::ClearPatterns() +//------------------------------------- +{ + DestroyPatterns(); + m_Patterns.assign(m_Patterns.size(), MODPATTERN(*this)); +} + + +void CPatternContainer::DestroyPatterns() +//--------------------------------------- +{ + for(PATTERNINDEX i = 0; i < m_Patterns.size(); i++) + { + Remove(i); + } +} + + PATTERNINDEX CPatternContainer::Insert(const ROWINDEX rows) //--------------------------------------------------------- { PATTERNINDEX i = 0; - for(i = 0; i<m_Patterns.size(); i++) + for(i = 0; i < m_Patterns.size(); i++) if(!m_Patterns[i]) break; if(Insert(i, rows)) return PATTERNINDEX_INVALID; @@ -38,7 +57,11 @@ } } - m_Patterns[index] = CSoundFile::AllocatePattern(rows, m_rSndFile.m_nChannels); + if(m_Patterns[index].m_ModCommands != nullptr) + { + CPattern::FreePattern(m_Patterns[index].m_ModCommands); + } + m_Patterns[index].m_ModCommands = CPattern::AllocatePattern(rows, m_rSndFile.m_nChannels); m_Patterns[index].m_Rows = rows; m_Patterns[index].RemoveSignature(); Modified: trunk/OpenMPT/soundlib/patternContainer.h =================================================================== --- trunk/OpenMPT/soundlib/patternContainer.h 2011-03-19 16:37:10 UTC (rev 821) +++ trunk/OpenMPT/soundlib/patternContainer.h 2011-03-19 22:02:38 UTC (rev 822) @@ -31,8 +31,10 @@ // Clears existing patterns and resizes array to default size. void Init(); - //Note: No memory handling here. - void ClearPatterns() {m_Patterns.assign(m_Patterns.size(), MODPATTERN(*this));} + // Empty and initialize all patterns. + void ClearPatterns(); + // Delete all patterns. + void DestroyPatterns(); //Insert (default)pattern to given position. If pattern already exists at that position, //ignoring request. Returns true on failure, false otherwise. This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |