mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
Move inflate method to Util class
------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=207857927
This commit is contained in:
parent
a3c08465eb
commit
eda408dc09
@ -25,7 +25,6 @@ import com.google.android.exoplayer2.util.Util;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.zip.DataFormatException;
|
|
||||||
import java.util.zip.Inflater;
|
import java.util.zip.Inflater;
|
||||||
|
|
||||||
/** A {@link SimpleSubtitleDecoder} for PGS subtitles. */
|
/** A {@link SimpleSubtitleDecoder} for PGS subtitles. */
|
||||||
@ -39,25 +38,22 @@ public final class PgsDecoder extends SimpleSubtitleDecoder {
|
|||||||
private static final byte INFLATE_HEADER = 0x78;
|
private static final byte INFLATE_HEADER = 0x78;
|
||||||
|
|
||||||
private final ParsableByteArray buffer;
|
private final ParsableByteArray buffer;
|
||||||
|
private final ParsableByteArray inflatedBuffer;
|
||||||
private final CueBuilder cueBuilder;
|
private final CueBuilder cueBuilder;
|
||||||
|
|
||||||
private Inflater inflater;
|
private Inflater inflater;
|
||||||
private byte[] inflatedData;
|
|
||||||
private int inflatedDataSize;
|
|
||||||
|
|
||||||
public PgsDecoder() {
|
public PgsDecoder() {
|
||||||
super("PgsDecoder");
|
super("PgsDecoder");
|
||||||
buffer = new ParsableByteArray();
|
buffer = new ParsableByteArray();
|
||||||
|
inflatedBuffer = new ParsableByteArray();
|
||||||
cueBuilder = new CueBuilder();
|
cueBuilder = new CueBuilder();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Subtitle decode(byte[] data, int size, boolean reset) throws SubtitleDecoderException {
|
protected Subtitle decode(byte[] data, int size, boolean reset) throws SubtitleDecoderException {
|
||||||
if (maybeInflateData(data, size)) {
|
buffer.reset(data, size);
|
||||||
buffer.reset(inflatedData, inflatedDataSize);
|
maybeInflateData(buffer);
|
||||||
} else {
|
|
||||||
buffer.reset(data, size);
|
|
||||||
}
|
|
||||||
cueBuilder.reset();
|
cueBuilder.reset();
|
||||||
ArrayList<Cue> cues = new ArrayList<>();
|
ArrayList<Cue> cues = new ArrayList<>();
|
||||||
while (buffer.bytesLeft() >= 3) {
|
while (buffer.bytesLeft() >= 3) {
|
||||||
@ -69,31 +65,14 @@ public final class PgsDecoder extends SimpleSubtitleDecoder {
|
|||||||
return new PgsSubtitle(Collections.unmodifiableList(cues));
|
return new PgsSubtitle(Collections.unmodifiableList(cues));
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean maybeInflateData(byte[] data, int size) {
|
private void maybeInflateData(ParsableByteArray buffer) {
|
||||||
if (size == 0 || data[0] != INFLATE_HEADER) {
|
if (buffer.bytesLeft() > 0 && buffer.peekUnsignedByte() == INFLATE_HEADER) {
|
||||||
return false;
|
if (inflater == null) {
|
||||||
}
|
inflater = new Inflater();
|
||||||
if (inflater == null) {
|
|
||||||
inflater = new Inflater();
|
|
||||||
inflatedData = new byte[size];
|
|
||||||
}
|
|
||||||
inflatedDataSize = 0;
|
|
||||||
inflater.setInput(data, 0, size);
|
|
||||||
try {
|
|
||||||
while (!inflater.finished() && !inflater.needsDictionary() && !inflater.needsInput()) {
|
|
||||||
if (inflatedDataSize == inflatedData.length) {
|
|
||||||
inflatedData = Arrays.copyOf(inflatedData, inflatedData.length * 2);
|
|
||||||
}
|
|
||||||
inflatedDataSize +=
|
|
||||||
inflater.inflate(
|
|
||||||
inflatedData, inflatedDataSize, inflatedData.length - inflatedDataSize);
|
|
||||||
}
|
}
|
||||||
return inflater.finished();
|
if (Util.inflate(buffer, inflatedBuffer, inflater)) {
|
||||||
} catch (DataFormatException e) {
|
buffer.reset(inflatedBuffer.data, inflatedBuffer.limit());
|
||||||
// Assume data is not compressed.
|
} // else assume data is not compressed.
|
||||||
return false;
|
|
||||||
} finally {
|
|
||||||
inflater.reset();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,6 +69,8 @@ import java.util.concurrent.Executors;
|
|||||||
import java.util.concurrent.ThreadFactory;
|
import java.util.concurrent.ThreadFactory;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
import java.util.zip.DataFormatException;
|
||||||
|
import java.util.zip.Inflater;
|
||||||
import org.checkerframework.checker.initialization.qual.UnknownInitialization;
|
import org.checkerframework.checker.initialization.qual.UnknownInitialization;
|
||||||
import org.checkerframework.checker.nullness.qual.EnsuresNonNull;
|
import org.checkerframework.checker.nullness.qual.EnsuresNonNull;
|
||||||
import org.checkerframework.checker.nullness.qual.PolyNull;
|
import org.checkerframework.checker.nullness.qual.PolyNull;
|
||||||
@ -1639,6 +1641,53 @@ public final class Util {
|
|||||||
return toUpperInvariant(Locale.getDefault().getCountry());
|
return toUpperInvariant(Locale.getDefault().getCountry());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uncompresses the data in {@code input}.
|
||||||
|
*
|
||||||
|
* @param input Wraps the compressed input data.
|
||||||
|
* @param output Wraps an output buffer to be used to store the uncompressed data. If {@code
|
||||||
|
* output.data} is null or it isn't big enough to hold the uncompressed data, a new array is
|
||||||
|
* created. If {@code true} is returned then the output's position will be set to 0 and its
|
||||||
|
* length will be set to the length of the uncompressed data.
|
||||||
|
* @param inflater If not null, used to uncompressed the input. Otherwise a new {@link Inflater}
|
||||||
|
* is created.
|
||||||
|
* @return Whether the input is uncompressed successfully.
|
||||||
|
*/
|
||||||
|
public static boolean inflate(
|
||||||
|
ParsableByteArray input, ParsableByteArray output, @Nullable Inflater inflater) {
|
||||||
|
if (input.bytesLeft() <= 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
byte[] outputData = output.data;
|
||||||
|
if (outputData == null) {
|
||||||
|
outputData = new byte[input.bytesLeft()];
|
||||||
|
}
|
||||||
|
if (inflater == null) {
|
||||||
|
inflater = new Inflater();
|
||||||
|
}
|
||||||
|
inflater.setInput(input.data, input.getPosition(), input.bytesLeft());
|
||||||
|
try {
|
||||||
|
int outputSize = 0;
|
||||||
|
while (true) {
|
||||||
|
outputSize += inflater.inflate(outputData, outputSize, outputData.length - outputSize);
|
||||||
|
if (inflater.finished()) {
|
||||||
|
output.reset(outputData, outputSize);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (inflater.needsDictionary() || inflater.needsInput()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (outputSize == outputData.length) {
|
||||||
|
outputData = Arrays.copyOf(outputData, outputData.length * 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (DataFormatException e) {
|
||||||
|
return false;
|
||||||
|
} finally {
|
||||||
|
inflater.reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the physical size of the default display, in pixels.
|
* Gets the physical size of the default display, in pixels.
|
||||||
*
|
*
|
||||||
|
@ -27,8 +27,10 @@ import static com.google.common.truth.Truth.assertThat;
|
|||||||
import com.google.android.exoplayer2.C;
|
import com.google.android.exoplayer2.C;
|
||||||
import com.google.android.exoplayer2.testutil.TestUtil;
|
import com.google.android.exoplayer2.testutil.TestUtil;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
import java.util.zip.Deflater;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.robolectric.RobolectricTestRunner;
|
import org.robolectric.RobolectricTestRunner;
|
||||||
@ -247,6 +249,23 @@ public class UtilTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testInflate() {
|
||||||
|
byte[] testData = TestUtil.buildTestData(/*arbitrary test data size*/ 256 * 1024);
|
||||||
|
byte[] compressedData = new byte[testData.length * 2];
|
||||||
|
Deflater compresser = new Deflater(9);
|
||||||
|
compresser.setInput(testData);
|
||||||
|
compresser.finish();
|
||||||
|
int compressedDataLength = compresser.deflate(compressedData);
|
||||||
|
compresser.end();
|
||||||
|
|
||||||
|
ParsableByteArray input = new ParsableByteArray(compressedData, compressedDataLength);
|
||||||
|
ParsableByteArray output = new ParsableByteArray();
|
||||||
|
assertThat(Util.inflate(input, output, /* inflater= */ null)).isTrue();
|
||||||
|
assertThat(output.limit()).isEqualTo(testData.length);
|
||||||
|
assertThat(Arrays.copyOf(output.data, output.limit())).isEqualTo(testData);
|
||||||
|
}
|
||||||
|
|
||||||
private static void assertEscapeUnescapeFileName(String fileName, String escapedFileName) {
|
private static void assertEscapeUnescapeFileName(String fileName, String escapedFileName) {
|
||||||
assertThat(escapeFileName(fileName)).isEqualTo(escapedFileName);
|
assertThat(escapeFileName(fileName)).isEqualTo(escapedFileName);
|
||||||
assertThat(unescapeFileName(escapedFileName)).isEqualTo(fileName);
|
assertThat(unescapeFileName(escapedFileName)).isEqualTo(fileName);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user