CrackMe.apk
Download file
package com.google.android.exoplayer2.text.ssa;
import android.text.Layout;
import android.text.SpannableString;
import android.text.style.BackgroundColorSpan;
import android.text.style.ForegroundColorSpan;
import android.text.style.StrikethroughSpan;
import android.text.style.StyleSpan;
import android.text.style.UnderlineSpan;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.text.Cue;
import com.google.android.exoplayer2.text.SimpleSubtitleDecoder;
import com.google.android.exoplayer2.text.Subtitle;
import com.google.android.exoplayer2.text.ssa.SsaStyle;
import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.Log;
import com.google.android.exoplayer2.util.ParsableByteArray;
import com.google.android.exoplayer2.util.Util;
import com.google.common.base.Ascii;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public final class SsaDecoder extends SimpleSubtitleDecoder {
private static final float DEFAULT_MARGIN = 0.05f;
private static final String DIALOGUE_LINE_PREFIX = "Dialogue:";
static final String FORMAT_LINE_PREFIX = "Format:";
private static final Pattern SSA_TIMECODE_PATTERN = Pattern.compile("(?:(\\d+):)?(\\d+):(\\d+)[:.](\\d+)");
static final String STYLE_LINE_PREFIX = "Style:";
private static final String TAG = "SsaDecoder";
private final SsaDialogueFormat dialogueFormatFromInitializationData;
private final boolean haveInitializationData;
private float screenHeight;
private float screenWidth;
private Map<String, SsaStyle> styles;
private static float computeDefaultLineOrPosition(int i) {
if (i == 0) {
return DEFAULT_MARGIN;
}
if (i != 1) {
return i != 2 ? -3.4028235E38f : 0.95f;
}
return 0.5f;
}
public SsaDecoder() {
this((List<byte[]>) null);
}
public SsaDecoder(List<byte[]> list) {
super(TAG);
this.screenWidth = -3.4028235E38f;
this.screenHeight = -3.4028235E38f;
if (list == null || list.isEmpty()) {
this.haveInitializationData = false;
this.dialogueFormatFromInitializationData = null;
return;
}
this.haveInitializationData = true;
String fromUtf8Bytes = Util.fromUtf8Bytes(list.get(0));
Assertions.checkArgument(fromUtf8Bytes.startsWith(FORMAT_LINE_PREFIX));
this.dialogueFormatFromInitializationData = (SsaDialogueFormat) Assertions.checkNotNull(SsaDialogueFormat.fromFormatLine(fromUtf8Bytes));
parseHeader(new ParsableByteArray(list.get(1)));
}
/* access modifiers changed from: protected */
public Subtitle decode(byte[] bArr, int i, boolean z) {
ArrayList arrayList = new ArrayList();
ArrayList arrayList2 = new ArrayList();
ParsableByteArray parsableByteArray = new ParsableByteArray(bArr, i);
if (!this.haveInitializationData) {
parseHeader(parsableByteArray);
}
parseEventBody(parsableByteArray, arrayList, arrayList2);
return new SsaSubtitle(arrayList, arrayList2);
}
private void parseHeader(ParsableByteArray parsableByteArray) {
while (true) {
String readLine = parsableByteArray.readLine();
if (readLine == null) {
return;
}
if ("[Script Info]".equalsIgnoreCase(readLine)) {
parseScriptInfo(parsableByteArray);
} else if ("[V4+ Styles]".equalsIgnoreCase(readLine)) {
this.styles = parseStyles(parsableByteArray);
} else if ("[V4 Styles]".equalsIgnoreCase(readLine)) {
Log.i(TAG, "[V4 Styles] are not supported");
} else if ("[Events]".equalsIgnoreCase(readLine)) {
return;
}
}
}
private void parseScriptInfo(ParsableByteArray parsableByteArray) {
while (true) {
String readLine = parsableByteArray.readLine();
if (readLine == null) {
return;
}
if (parsableByteArray.bytesLeft() == 0 || parsableByteArray.peekUnsignedByte() != 91) {
String[] split = readLine.split(":");
if (split.length == 2) {
String lowerCase = Ascii.toLowerCase(split[0].trim());
lowerCase.hashCode();
if (lowerCase.equals("playresx")) {
this.screenWidth = Float.parseFloat(split[1].trim());
} else if (lowerCase.equals("playresy")) {
try {
this.screenHeight = Float.parseFloat(split[1].trim());
} catch (NumberFormatException unused) {
}
}
}
} else {
return;
}
}
}
private static Map<String, SsaStyle> parseStyles(ParsableByteArray parsableByteArray) {
LinkedHashMap linkedHashMap = new LinkedHashMap();
SsaStyle.Format format = null;
while (true) {
String readLine = parsableByteArray.readLine();
if (readLine == null || (parsableByteArray.bytesLeft() != 0 && parsableByteArray.peekUnsignedByte() == 91)) {
return linkedHashMap;
}
if (readLine.startsWith(FORMAT_LINE_PREFIX)) {
format = SsaStyle.Format.fromFormatLine(readLine);
} else if (readLine.startsWith(STYLE_LINE_PREFIX)) {
if (format == null) {
Log.w(TAG, "Skipping 'Style:' line before 'Format:' line: " + readLine);
} else {
SsaStyle fromStyleLine = SsaStyle.fromStyleLine(readLine, format);
if (fromStyleLine != null) {
linkedHashMap.put(fromStyleLine.name, fromStyleLine);
}
}
}
}
return linkedHashMap;
}
private void parseEventBody(ParsableByteArray parsableByteArray, List<List<Cue>> list, List<Long> list2) {
SsaDialogueFormat ssaDialogueFormat = this.haveInitializationData ? this.dialogueFormatFromInitializationData : null;
while (true) {
String readLine = parsableByteArray.readLine();
if (readLine == null) {
return;
}
if (readLine.startsWith(FORMAT_LINE_PREFIX)) {
ssaDialogueFormat = SsaDialogueFormat.fromFormatLine(readLine);
} else if (readLine.startsWith(DIALOGUE_LINE_PREFIX)) {
if (ssaDialogueFormat == null) {
Log.w(TAG, "Skipping dialogue line before complete format: " + readLine);
} else {
parseDialogueLine(readLine, ssaDialogueFormat, list, list2);
}
}
}
}
private void parseDialogueLine(String str, SsaDialogueFormat ssaDialogueFormat, List<List<Cue>> list, List<Long> list2) {
Assertions.checkArgument(str.startsWith(DIALOGUE_LINE_PREFIX));
String[] split = str.substring(9).split(",", ssaDialogueFormat.length);
if (split.length != ssaDialogueFormat.length) {
Log.w(TAG, "Skipping dialogue line with fewer columns than format: " + str);
return;
}
long parseTimecodeUs = parseTimecodeUs(split[ssaDialogueFormat.startTimeIndex]);
if (parseTimecodeUs == C.TIME_UNSET) {
Log.w(TAG, "Skipping invalid timing: " + str);
return;
}
long parseTimecodeUs2 = parseTimecodeUs(split[ssaDialogueFormat.endTimeIndex]);
if (parseTimecodeUs2 == C.TIME_UNSET) {
Log.w(TAG, "Skipping invalid timing: " + str);
return;
}
SsaStyle ssaStyle = (this.styles == null || ssaDialogueFormat.styleIndex == -1) ? null : this.styles.get(split[ssaDialogueFormat.styleIndex].trim());
String str2 = split[ssaDialogueFormat.textIndex];
Cue createCue = createCue(SsaStyle.Overrides.stripStyleOverrides(str2).replace("\\N", "\n").replace("\\n", "\n").replace("\\h", " "), ssaStyle, SsaStyle.Overrides.parseFromDialogue(str2), this.screenWidth, this.screenHeight);
int addCuePlacerholderByTime = addCuePlacerholderByTime(parseTimecodeUs2, list2, list);
for (int addCuePlacerholderByTime2 = addCuePlacerholderByTime(parseTimecodeUs, list2, list); addCuePlacerholderByTime2 < addCuePlacerholderByTime; addCuePlacerholderByTime2++) {
list.get(addCuePlacerholderByTime2).add(createCue);
}
}
private static long parseTimecodeUs(String str) {
Matcher matcher = SSA_TIMECODE_PATTERN.matcher(str.trim());
if (!matcher.matches()) {
return C.TIME_UNSET;
}
return (Long.parseLong((String) Util.castNonNull(matcher.group(1))) * 60 * 60 * 1000000) + (Long.parseLong((String) Util.castNonNull(matcher.group(2))) * 60 * 1000000) + (Long.parseLong((String) Util.castNonNull(matcher.group(3))) * 1000000) + (Long.parseLong((String) Util.castNonNull(matcher.group(4))) * 10000);
}
private static Cue createCue(String str, SsaStyle ssaStyle, SsaStyle.Overrides overrides, float f, float f2) {
SpannableString spannableString = new SpannableString(str);
Cue.Builder text = new Cue.Builder().setText(spannableString);
if (ssaStyle != null) {
if (ssaStyle.primaryColor != null) {
spannableString.setSpan(new ForegroundColorSpan(ssaStyle.primaryColor.intValue()), 0, spannableString.length(), 33);
}
if (ssaStyle.borderStyle == 3 && ssaStyle.outlineColor != null) {
spannableString.setSpan(new BackgroundColorSpan(ssaStyle.outlineColor.intValue()), 0, spannableString.length(), 33);
}
if (!(ssaStyle.fontSize == -3.4028235E38f || f2 == -3.4028235E38f)) {
text.setTextSize(ssaStyle.fontSize / f2, 1);
}
if (ssaStyle.bold && ssaStyle.italic) {
spannableString.setSpan(new StyleSpan(3), 0, spannableString.length(), 33);
} else if (ssaStyle.bold) {
spannableString.setSpan(new StyleSpan(1), 0, spannableString.length(), 33);
} else if (ssaStyle.italic) {
spannableString.setSpan(new StyleSpan(2), 0, spannableString.length(), 33);
}
if (ssaStyle.underline) {
spannableString.setSpan(new UnderlineSpan(), 0, spannableString.length(), 33);
}
if (ssaStyle.strikeout) {
spannableString.setSpan(new StrikethroughSpan(), 0, spannableString.length(), 33);
}
}
int i = -1;
if (overrides.alignment != -1) {
i = overrides.alignment;
} else if (ssaStyle != null) {
i = ssaStyle.alignment;
}
text.setTextAlignment(toTextAlignment(i)).setPositionAnchor(toPositionAnchor(i)).setLineAnchor(toLineAnchor(i));
if (overrides.position == null || f2 == -3.4028235E38f || f == -3.4028235E38f) {
text.setPosition(computeDefaultLineOrPosition(text.getPositionAnchor()));
text.setLine(computeDefaultLineOrPosition(text.getLineAnchor()), 0);
} else {
text.setPosition(overrides.position.x / f);
text.setLine(overrides.position.y / f2, 0);
}
return text.build();
}
private static Layout.Alignment toTextAlignment(int i) {
switch (i) {
case -1:
return null;
case 1:
case 4:
case 7:
return Layout.Alignment.ALIGN_NORMAL;
case 2:
case 5:
case 8:
return Layout.Alignment.ALIGN_CENTER;
case 3:
case 6:
case 9:
return Layout.Alignment.ALIGN_OPPOSITE;
default:
Log.w(TAG, "Unknown alignment: " + i);
return null;
}
}
private static int toLineAnchor(int i) {
switch (i) {
case -1:
return Integer.MIN_VALUE;
case 1:
case 2:
case 3:
return 2;
case 4:
case 5:
case 6:
return 1;
case 7:
case 8:
case 9:
return 0;
default:
Log.w(TAG, "Unknown alignment: " + i);
return Integer.MIN_VALUE;
}
}
private static int toPositionAnchor(int i) {
switch (i) {
case -1:
return Integer.MIN_VALUE;
case 1:
case 4:
case 7:
return 0;
case 2:
case 5:
case 8:
return 1;
case 3:
case 6:
case 9:
return 2;
default:
Log.w(TAG, "Unknown alignment: " + i);
return Integer.MIN_VALUE;
}
}
private static int addCuePlacerholderByTime(long j, List<Long> list, List<List<Cue>> list2) {
int i;
ArrayList arrayList;
int size = list.size() - 1;
while (true) {
if (size < 0) {
i = 0;
break;
} else if (list.get(size).longValue() == j) {
return size;
} else {
if (list.get(size).longValue() < j) {
i = size + 1;
break;
}
size--;
}
}
list.add(i, Long.valueOf(j));
if (i != 0) {
arrayList = new ArrayList(list2.get(i - 1));
}
list2.add(i, arrayList);
return i;
}
}
Download file