@@ -16,12 +16,15 @@ static const VSFrameRef *VS_CC remapGetFrame(int n, int activationReason, void *
1616 RemapData *d{ static_cast <RemapData*>(*instanceData) };
1717
1818 if (activationReason == arInitial) {
19- // We check whether node2 is a null pointer. If it is, we use baseclip (node1).
20- // Else, sourceclip (node2) is used.
21- vsapi->requestFrameFilter (d->frameMap [n], (d->node2 ? d->node2 : d->node1 ), frameCtx);
19+ if (d->frameMap [n] == UINT_MAX)
20+ vsapi->requestFrameFilter (n, d->node1 , frameCtx);
21+ else
22+ vsapi->requestFrameFilter (d->frameMap [n], d->node2 , frameCtx);
2223 }
2324 else if (activationReason == arAllFramesReady) {
24- return vsapi->getFrameFilter (d->frameMap [n], (d->node2 ? d->node2 : d->node1 ), frameCtx);
25+ if (d->frameMap [n] == UINT_MAX)
26+ return vsapi->getFrameFilter (n, d->node1 , frameCtx);
27+ return vsapi->getFrameFilter (d->frameMap [n], d->node2 , frameCtx);
2528 }
2629
2730 return nullptr ;
@@ -30,7 +33,7 @@ static const VSFrameRef *VS_CC remapGetFrame(int n, int activationReason, void *
3033static void VS_CC remapFree (void *instanceData, VSCore *core, const VSAPI *vsapi) {
3134 RemapData *d{ static_cast <RemapData*>(instanceData) };
3235 vsapi->freeNode (d->node1 );
33- if (d->node2 )
36+ if (d->node1 != d-> node2 )
3437 vsapi->freeNode (d->node2 );
3538 delete d;
3639}
@@ -78,7 +81,7 @@ static void matchRangeToRange(const std::string &str, int &col, std::vector<unsi
7881//
7982// If it isn't able to parse the string as any of the above three patterns, it throws a runtime error (Parse Error).
8083// Runtime errors (Index out of Bounds, Overflow, or Parse errors) can also be thrown from inside getInt and fillRange.
81- static void parse (std::string name, std::vector<unsigned int > &frameMap, void *stream, bool file, int maxFrames) {
84+ static void parse (std::string name, std::vector<unsigned int > &frameMap, void *stream, bool file, int maxFrames, const VSAPI *vsapi ) {
8285
8386 int line{ 0 }; // Current line. This is simply for throwing detailed errors and has no other use.
8487 int col{ 0 }; // Current column. This is used to track the current column position in the string we are at.
@@ -93,42 +96,40 @@ static void parse(std::string name, std::vector<unsigned int> &frameMap, void *s
9396 std::string temp;
9497 while (file ? std::getline (*static_cast <std::ifstream*>(stream), temp) : std::getline (*static_cast <std::stringstream*>(stream), temp)) {
9598 col = 0 ;
96- skipWhitespace (temp, col);
97- char ch{ getChar (temp, col) };
98- if (ch != 0 ) {
99- if (ch == ' #' )
100- continue ;
101- else if (std::isdigit (ch) || ch == ' -' )
102- matchIntToInt (temp, col, frameMap, line, file, maxFrames);
103- else if (ch == ' [' ) {
104- ++col;
105- Range rangeIn;
106- fillRange (temp, col, rangeIn, line, file, maxFrames, Filter::REMAP_FRAMES);
107- if (rangeIn.start > rangeIn.end ) {
99+ while (col < temp.size ()) {
100+ skipWhitespace (temp, col);
101+ char ch{ getChar (temp, col) };
102+ if (ch != 0 ) {
103+ if (ch == ' #' )
104+ continue ;
105+ else if (std::isdigit (ch) || ch == ' -' )
106+ matchIntToInt (temp, col, frameMap, line, file, maxFrames);
107+ else if (ch == ' [' ) {
108+ ++col;
109+ Range rangeIn;
110+ fillRange (temp, col, rangeIn, line, file, maxFrames, Filter::REMAP_FRAMES);
111+ if (rangeIn.start > rangeIn.end ) {
112+ std::string location{ file ? " text file " : " mappings " };
113+ std::string error{ " RemapFrames: Index out of bounds in" + location + " at line " + std::to_string (line + 1 ) + " , column " + std::to_string (col + 1 ) };
114+ throw std::runtime_error (error);
115+ }
116+ skipWhitespace (temp, col);
117+ ch = getChar (temp, col);
118+ if (ch != 0 ) {
119+ if (std::isdigit (ch) || ch == ' -' ) {
120+ matchRangeToInt (temp, col, frameMap, rangeIn, line, file, maxFrames);
121+ }
122+ else if (ch == ' [' ) {
123+ ++col;
124+ matchRangeToRange (temp, col, frameMap, rangeIn, line, file, maxFrames);
125+ }
126+ }
127+ }
128+ else {
108129 std::string location{ file ? " text file " : " mappings " };
109- std::string error{ " RemapFrames: Index out of bounds in" + location + " at line " + std::to_string (line + 1 ) + " , column " + std::to_string (col + 1 ) };
130+ std::string error{ " RemapFrames: Parse Error in" + location + " at line " + std::to_string (line + 1 ) + " , column " + std::to_string (col + 1 ) };
110131 throw std::runtime_error (error);
111132 }
112- skipWhitespace (temp, col);
113- ch = getChar (temp, col);
114- if (ch != 0 ) {
115- if (std::isdigit (ch) || ch == ' -' )
116- matchRangeToInt (temp, col, frameMap, rangeIn, line, file, maxFrames);
117- else if (ch == ' [' )
118- ++col;
119- matchRangeToRange (temp, col, frameMap, rangeIn, line, file, maxFrames);
120- }
121- }
122- else {
123- std::string location{ file ? " text file " : " mappings " };
124- std::string error{ " RemapFrames: Parse Error in" + location + " at line " + std::to_string (line + 1 ) + " , column " + std::to_string (col + 1 ) };
125- throw std::runtime_error (error);
126- }
127- skipWhitespace (temp, col);
128- if (col != temp.size ()) {
129- std::string location{ file ? " text file " : " mappings " };
130- std::string error{ " RemapFrames: Parse Error in" + location + " at line " + std::to_string (line + 1 ) + " , column " + std::to_string (col + 1 ) };
131- throw std::runtime_error (error);
132133 }
133134 }
134135 line++;
@@ -148,18 +149,18 @@ void VS_CC remapCreate(const VSMap *in, VSMap *out, void *userData, VSCore *core
148149 filename = " " ;
149150 else
150151 filename = fn;
151-
152+
152153 std::string mappings;
153154 const char * mp{ vsapi->propGetData (in, " mappings" , 0 , &err) };
154155 if (err)
155156 mappings = " " ;
156157 else
157158 mappings = mp;
158159
159- // If sourceclip is not provided, we set node2 to a null pointer .
160+ // If sourceclip is not provided, we set sourceclip equal to baseclip .
160161 d.node2 = vsapi->propGetNode (in, " sourceclip" , 0 , &err);
161162 if (err)
162- d.node2 = nullptr ;
163+ d.node2 = d. node1 ;
163164
164165 bool mismatch{ !!vsapi->propGetInt (in, " mismatch" , 0 , &err) };
165166 if (err)
@@ -169,9 +170,12 @@ void VS_CC remapCreate(const VSMap *in, VSMap *out, void *userData, VSCore *core
169170 MismatchCauses mismatchCause = findCommonVi (&d.vi , d.node2 , vsapi);
170171 if (mismatchCause == MismatchCauses::DIFFERENT_LENGTHS) {
171172 vsapi->setError (out, " RemapFrames: Clip lengths don't match" );
173+ // Free baseclip.
172174 vsapi->freeNode (d.node1 );
173- if (d.node2 )
174- vsapi->freeNode (d.node2 ); // We check whether node2 is a null pointer. If it isn't, we free the node.
175+ // If sourceclip and baseclip aren't the same, then free sourceclip.
176+ // freeNode(node) doesn't change the value of node so the comparison is safe.
177+ if (d.node1 != d.node2 )
178+ vsapi->freeNode (d.node2 );
175179 return ;
176180 }
177181
@@ -183,19 +187,15 @@ void VS_CC remapCreate(const VSMap *in, VSMap *out, void *userData, VSCore *core
183187 else if (mismatchCause == MismatchCauses::DIFFERENT_FRAMERATES)
184188 vsapi->setError (out, " RemapFrames: Clip frame rates don't match" );
185189 vsapi->freeNode (d.node1 );
186- if (d.node2 )
190+ if (d.node1 != d. node2 )
187191 vsapi->freeNode (d.node2 );
188192 return ;
189193 }
190194
191195 // We use a vector to store frame mappings. Each index represents a frame number,
192196 // and each value at that index represents which frame it going to be replaced with.
193- d.frameMap .resize (d.vi .numFrames );
194-
195- // All frames map to themselves by default.
196- for (int i = 0 ; i < d.frameMap .size (); i++) {
197- d.frameMap [i] = i;
198- }
197+ // A value of UINT_MAX indicates that the frame doesn't need to be replaced.
198+ d.frameMap .assign (d.vi .numFrames , UINT_MAX);
199199
200200 // Enclosed in a try catch block to catch any runtime errors.
201201 // Frame mappings in the mappings string have higher precedence than
@@ -207,21 +207,21 @@ void VS_CC remapCreate(const VSMap *in, VSMap *out, void *userData, VSCore *core
207207 if (!file) {
208208 vsapi->setError (out, " RemapFrames: Failed to open the timecodes file." );
209209 vsapi->freeNode (d.node1 );
210- if (d.node2 )
210+ if (d.node1 != d. node2 )
211211 vsapi->freeNode (d.node2 );
212212 return ;
213213 }
214- parse (filename, d.frameMap , &file, true , d.vi .numFrames );
214+ parse (filename, d.frameMap , &file, true , d.vi .numFrames , vsapi );
215215 }
216216 if (!mappings.empty ()) {
217217 std::stringstream stream (mappings);
218- parse (mappings, d.frameMap , &stream, false , d.vi .numFrames );
218+ parse (mappings, d.frameMap , &stream, false , d.vi .numFrames , vsapi );
219219 }
220220 }
221221 catch (const std::exception &ex) {
222222 vsapi->setError (out, ex.what ());
223223 vsapi->freeNode (d.node1 );
224- if (d.node2 )
224+ if (d.node1 != d. node2 )
225225 vsapi->freeNode (d.node2 );
226226 return ;
227227 }
0 commit comments