anchor.diff:  
   procedure TForm1.DoInterpTree(aTree: Integer; var aPicOffset: Integer; aDryRun: Boolean);
   
  -  function Is4xAnim(A: TKMAnimLoop): Boolean;
  -  begin
  -    Result := A.Count >= 8;
  -    if Result then
  -      Result := (A.Step[1] = A.Step[2]) and (A.Step[1] = A.Step[3]) and (A.Step[1] = A.Step[4])
  -            and (A.Step[5] = A.Step[6]) and (A.Step[5] = A.Step[7]) and (A.Step[5] = A.Step[8]);
  +  function GetAnimSpeed(A: TKMAnimLoop): Integer;
  +  var
  +    I: Integer;
  +  begin
  +    Result := 1;
  +    while (Result < A.Count) and (A.Step[Result] = A.Step[Result+1]) do
  +      Inc(Result);
     end;
   
   var
     A: TKMAnimLoop;
  -  Step, SubStep, InterpOffset,StepSprite, StepNextSprite: Integer;
  +  S, Step, SubStep, InterpOffset, StepSprite, StepNextSprite: Integer;
     suffixPath, outDirLocal, outPrefix: string;
   begin
     A := gMapElements[aTree].Anim;
  
positive.code: end;
  
  
  procedure TForm1.Make4xInterpImages(RT: TRXType; aID_1, aID_2: Integer; aBaseDir: string; aExportType: TInterpExportType);
  var
    origSpritesDir, interpSpritesDir: string;
    I: Integer;
  
negative.code:     Exit;
    end;
  
    S := GetAnimSpeed(A);
    if (S = 2) or (S = 4) then
    begin
      //Custom handler for tree animations that only update every 4 frames
      outDirLocal := fOutDir+IntToStr(Byte(rxTrees)+1)+'\';
      outPrefix := outDirLocal+IntToStr(Byte(rxTrees)+1)+'_';
      ForceDirectories(outDirLocal);
  
      for Step := 1 to (32 div S) do
      begin
        if Step > (A.Count div S) then
        begin
          for SubStep := 1 to 8*S do
            fOutputStream.Write(Integer(-1));
          Continue;
        end;
  
        StepSprite := A.Step[Step*S] + 1;
        StepNextSprite := A.Step[((Step*S) mod A.Count) + 1] + 1;
  
        fOutputStream.Write(StepSprite);
  
        InterpOffset := aPicOffset;
        //Update return values
        Inc(aPicOffset, 8*S - 1);
        for SubStep := 0 to (8*S - 2) do
          fOutputStream.Write(InterpOffset+SubStep);
  
        if aDryRun then
          Continue;
  
        MakeCustomInterpImages(S, rxTrees, StepSprite, StepNextSprite, fWorkDir+'base\', ietBase);
        MakeCustomInterpImages(S, rxTrees, StepSprite, StepNextSprite, fWorkDir+'shad\', ietShadows);
        for SubStep := 0 to (8*S - 2) do
        begin
          //Filenames are 1-based, and skip the first one since it's the original
          suffixPath := 'interpolated_frames\' + format('%.15d.png', [SubStep+1+1]);
  