380 lines
13 KiB
Java
380 lines
13 KiB
Java
package com.bumptech.glide.load.resource.bitmap;
|
|
|
|
import android.util.Log;
|
|
import com.bumptech.glide.load.ImageHeaderParser;
|
|
import com.bumptech.glide.load.engine.bitmap_recycle.ArrayPool;
|
|
import com.bumptech.glide.util.Preconditions;
|
|
import java.io.IOException;
|
|
import java.io.InputStream;
|
|
import java.nio.ByteBuffer;
|
|
import java.nio.ByteOrder;
|
|
import java.nio.charset.Charset;
|
|
|
|
/* loaded from: classes.dex */
|
|
public final class DefaultImageHeaderParser implements ImageHeaderParser {
|
|
static final byte[] a = "Exif\u0000\u0000".getBytes(Charset.forName("UTF-8"));
|
|
private static final int[] b = {0, 1, 1, 2, 4, 8, 1, 1, 2, 4, 8, 4, 8};
|
|
|
|
private static final class ByteBufferReader implements Reader {
|
|
private final ByteBuffer a;
|
|
|
|
ByteBufferReader(ByteBuffer byteBuffer) {
|
|
this.a = byteBuffer;
|
|
byteBuffer.order(ByteOrder.BIG_ENDIAN);
|
|
}
|
|
|
|
@Override // com.bumptech.glide.load.resource.bitmap.DefaultImageHeaderParser.Reader
|
|
public int a() {
|
|
return ((c() << 8) & 65280) | (c() & 255);
|
|
}
|
|
|
|
@Override // com.bumptech.glide.load.resource.bitmap.DefaultImageHeaderParser.Reader
|
|
public short b() {
|
|
return (short) (c() & 255);
|
|
}
|
|
|
|
@Override // com.bumptech.glide.load.resource.bitmap.DefaultImageHeaderParser.Reader
|
|
public int c() {
|
|
if (this.a.remaining() < 1) {
|
|
return -1;
|
|
}
|
|
return this.a.get();
|
|
}
|
|
|
|
@Override // com.bumptech.glide.load.resource.bitmap.DefaultImageHeaderParser.Reader
|
|
public int read(byte[] bArr, int i) {
|
|
int min = Math.min(i, this.a.remaining());
|
|
if (min == 0) {
|
|
return -1;
|
|
}
|
|
this.a.get(bArr, 0, min);
|
|
return min;
|
|
}
|
|
|
|
@Override // com.bumptech.glide.load.resource.bitmap.DefaultImageHeaderParser.Reader
|
|
public long skip(long j) {
|
|
int min = (int) Math.min(this.a.remaining(), j);
|
|
ByteBuffer byteBuffer = this.a;
|
|
byteBuffer.position(byteBuffer.position() + min);
|
|
return min;
|
|
}
|
|
}
|
|
|
|
private static final class RandomAccessReader {
|
|
private final ByteBuffer a;
|
|
|
|
RandomAccessReader(byte[] bArr, int i) {
|
|
this.a = (ByteBuffer) ByteBuffer.wrap(bArr).order(ByteOrder.BIG_ENDIAN).limit(i);
|
|
}
|
|
|
|
void a(ByteOrder byteOrder) {
|
|
this.a.order(byteOrder);
|
|
}
|
|
|
|
int b(int i) {
|
|
if (a(i, 4)) {
|
|
return this.a.getInt(i);
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
int a() {
|
|
return this.a.remaining();
|
|
}
|
|
|
|
short a(int i) {
|
|
if (a(i, 2)) {
|
|
return this.a.getShort(i);
|
|
}
|
|
return (short) -1;
|
|
}
|
|
|
|
private boolean a(int i, int i2) {
|
|
return this.a.remaining() - i >= i2;
|
|
}
|
|
}
|
|
|
|
private interface Reader {
|
|
int a() throws IOException;
|
|
|
|
short b() throws IOException;
|
|
|
|
int c() throws IOException;
|
|
|
|
int read(byte[] bArr, int i) throws IOException;
|
|
|
|
long skip(long j) throws IOException;
|
|
}
|
|
|
|
private static final class StreamReader implements Reader {
|
|
private final InputStream a;
|
|
|
|
StreamReader(InputStream inputStream) {
|
|
this.a = inputStream;
|
|
}
|
|
|
|
@Override // com.bumptech.glide.load.resource.bitmap.DefaultImageHeaderParser.Reader
|
|
public int a() throws IOException {
|
|
return ((this.a.read() << 8) & 65280) | (this.a.read() & 255);
|
|
}
|
|
|
|
@Override // com.bumptech.glide.load.resource.bitmap.DefaultImageHeaderParser.Reader
|
|
public short b() throws IOException {
|
|
return (short) (this.a.read() & 255);
|
|
}
|
|
|
|
@Override // com.bumptech.glide.load.resource.bitmap.DefaultImageHeaderParser.Reader
|
|
public int c() throws IOException {
|
|
return this.a.read();
|
|
}
|
|
|
|
@Override // com.bumptech.glide.load.resource.bitmap.DefaultImageHeaderParser.Reader
|
|
public int read(byte[] bArr, int i) throws IOException {
|
|
int i2 = i;
|
|
while (i2 > 0) {
|
|
int read = this.a.read(bArr, i - i2, i2);
|
|
if (read == -1) {
|
|
break;
|
|
}
|
|
i2 -= read;
|
|
}
|
|
return i - i2;
|
|
}
|
|
|
|
@Override // com.bumptech.glide.load.resource.bitmap.DefaultImageHeaderParser.Reader
|
|
public long skip(long j) throws IOException {
|
|
if (j < 0) {
|
|
return 0L;
|
|
}
|
|
long j2 = j;
|
|
while (j2 > 0) {
|
|
long skip = this.a.skip(j2);
|
|
if (skip <= 0) {
|
|
if (this.a.read() == -1) {
|
|
break;
|
|
}
|
|
skip = 1;
|
|
}
|
|
j2 -= skip;
|
|
}
|
|
return j - j2;
|
|
}
|
|
}
|
|
|
|
private static int a(int i, int i2) {
|
|
return i + 2 + (i2 * 12);
|
|
}
|
|
|
|
private static boolean a(int i) {
|
|
return (i & 65496) == 65496 || i == 19789 || i == 18761;
|
|
}
|
|
|
|
private int b(Reader reader) throws IOException {
|
|
short b2;
|
|
int a2;
|
|
long j;
|
|
long skip;
|
|
do {
|
|
short b3 = reader.b();
|
|
if (b3 != 255) {
|
|
if (Log.isLoggable("DfltImageHeaderParser", 3)) {
|
|
Log.d("DfltImageHeaderParser", "Unknown segmentId=" + ((int) b3));
|
|
}
|
|
return -1;
|
|
}
|
|
b2 = reader.b();
|
|
if (b2 == 218) {
|
|
return -1;
|
|
}
|
|
if (b2 == 217) {
|
|
if (Log.isLoggable("DfltImageHeaderParser", 3)) {
|
|
Log.d("DfltImageHeaderParser", "Found MARKER_EOI in exif segment");
|
|
}
|
|
return -1;
|
|
}
|
|
a2 = reader.a() - 2;
|
|
if (b2 == 225) {
|
|
return a2;
|
|
}
|
|
j = a2;
|
|
skip = reader.skip(j);
|
|
} while (skip == j);
|
|
if (Log.isLoggable("DfltImageHeaderParser", 3)) {
|
|
Log.d("DfltImageHeaderParser", "Unable to skip enough data, type: " + ((int) b2) + ", wanted to skip: " + a2 + ", but actually skipped: " + skip);
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
@Override // com.bumptech.glide.load.ImageHeaderParser
|
|
public ImageHeaderParser.ImageType a(InputStream inputStream) throws IOException {
|
|
Preconditions.a(inputStream);
|
|
return a(new StreamReader(inputStream));
|
|
}
|
|
|
|
@Override // com.bumptech.glide.load.ImageHeaderParser
|
|
public ImageHeaderParser.ImageType a(ByteBuffer byteBuffer) throws IOException {
|
|
Preconditions.a(byteBuffer);
|
|
return a(new ByteBufferReader(byteBuffer));
|
|
}
|
|
|
|
@Override // com.bumptech.glide.load.ImageHeaderParser
|
|
public int a(InputStream inputStream, ArrayPool arrayPool) throws IOException {
|
|
Preconditions.a(inputStream);
|
|
StreamReader streamReader = new StreamReader(inputStream);
|
|
Preconditions.a(arrayPool);
|
|
return a(streamReader, arrayPool);
|
|
}
|
|
|
|
private ImageHeaderParser.ImageType a(Reader reader) throws IOException {
|
|
int a2 = reader.a();
|
|
if (a2 == 65496) {
|
|
return ImageHeaderParser.ImageType.JPEG;
|
|
}
|
|
int a3 = ((a2 << 16) & (-65536)) | (reader.a() & 65535);
|
|
if (a3 == -1991225785) {
|
|
reader.skip(21L);
|
|
return reader.c() >= 3 ? ImageHeaderParser.ImageType.PNG_A : ImageHeaderParser.ImageType.PNG;
|
|
}
|
|
if ((a3 >> 8) == 4671814) {
|
|
return ImageHeaderParser.ImageType.GIF;
|
|
}
|
|
if (a3 != 1380533830) {
|
|
return ImageHeaderParser.ImageType.UNKNOWN;
|
|
}
|
|
reader.skip(4L);
|
|
if ((((reader.a() << 16) & (-65536)) | (reader.a() & 65535)) != 1464156752) {
|
|
return ImageHeaderParser.ImageType.UNKNOWN;
|
|
}
|
|
int a4 = ((reader.a() << 16) & (-65536)) | (reader.a() & 65535);
|
|
if ((a4 & (-256)) != 1448097792) {
|
|
return ImageHeaderParser.ImageType.UNKNOWN;
|
|
}
|
|
int i = a4 & 255;
|
|
if (i == 88) {
|
|
reader.skip(4L);
|
|
return (reader.c() & 16) != 0 ? ImageHeaderParser.ImageType.WEBP_A : ImageHeaderParser.ImageType.WEBP;
|
|
}
|
|
if (i == 76) {
|
|
reader.skip(4L);
|
|
return (reader.c() & 8) != 0 ? ImageHeaderParser.ImageType.WEBP_A : ImageHeaderParser.ImageType.WEBP;
|
|
}
|
|
return ImageHeaderParser.ImageType.WEBP;
|
|
}
|
|
|
|
private int a(Reader reader, ArrayPool arrayPool) throws IOException {
|
|
int a2 = reader.a();
|
|
if (!a(a2)) {
|
|
if (Log.isLoggable("DfltImageHeaderParser", 3)) {
|
|
Log.d("DfltImageHeaderParser", "Parser doesn't handle magic number: " + a2);
|
|
}
|
|
return -1;
|
|
}
|
|
int b2 = b(reader);
|
|
if (b2 == -1) {
|
|
if (Log.isLoggable("DfltImageHeaderParser", 3)) {
|
|
Log.d("DfltImageHeaderParser", "Failed to parse exif segment length, or exif segment not found");
|
|
}
|
|
return -1;
|
|
}
|
|
byte[] bArr = (byte[]) arrayPool.b(b2, byte[].class);
|
|
try {
|
|
return a(reader, bArr, b2);
|
|
} finally {
|
|
arrayPool.put(bArr);
|
|
}
|
|
}
|
|
|
|
private int a(Reader reader, byte[] bArr, int i) throws IOException {
|
|
int read = reader.read(bArr, i);
|
|
if (read != i) {
|
|
if (Log.isLoggable("DfltImageHeaderParser", 3)) {
|
|
Log.d("DfltImageHeaderParser", "Unable to read exif segment data, length: " + i + ", actually read: " + read);
|
|
}
|
|
return -1;
|
|
}
|
|
if (a(bArr, i)) {
|
|
return a(new RandomAccessReader(bArr, i));
|
|
}
|
|
if (Log.isLoggable("DfltImageHeaderParser", 3)) {
|
|
Log.d("DfltImageHeaderParser", "Missing jpeg exif preamble");
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
private boolean a(byte[] bArr, int i) {
|
|
boolean z = bArr != null && i > a.length;
|
|
if (!z) {
|
|
return z;
|
|
}
|
|
int i2 = 0;
|
|
while (true) {
|
|
byte[] bArr2 = a;
|
|
if (i2 >= bArr2.length) {
|
|
return z;
|
|
}
|
|
if (bArr[i2] != bArr2[i2]) {
|
|
return false;
|
|
}
|
|
i2++;
|
|
}
|
|
}
|
|
|
|
private static int a(RandomAccessReader randomAccessReader) {
|
|
ByteOrder byteOrder;
|
|
short a2 = randomAccessReader.a(6);
|
|
if (a2 == 18761) {
|
|
byteOrder = ByteOrder.LITTLE_ENDIAN;
|
|
} else if (a2 != 19789) {
|
|
if (Log.isLoggable("DfltImageHeaderParser", 3)) {
|
|
Log.d("DfltImageHeaderParser", "Unknown endianness = " + ((int) a2));
|
|
}
|
|
byteOrder = ByteOrder.BIG_ENDIAN;
|
|
} else {
|
|
byteOrder = ByteOrder.BIG_ENDIAN;
|
|
}
|
|
randomAccessReader.a(byteOrder);
|
|
int b2 = randomAccessReader.b(10) + 6;
|
|
short a3 = randomAccessReader.a(b2);
|
|
for (int i = 0; i < a3; i++) {
|
|
int a4 = a(b2, i);
|
|
short a5 = randomAccessReader.a(a4);
|
|
if (a5 == 274) {
|
|
short a6 = randomAccessReader.a(a4 + 2);
|
|
if (a6 >= 1 && a6 <= 12) {
|
|
int b3 = randomAccessReader.b(a4 + 4);
|
|
if (b3 < 0) {
|
|
if (Log.isLoggable("DfltImageHeaderParser", 3)) {
|
|
Log.d("DfltImageHeaderParser", "Negative tiff component count");
|
|
}
|
|
} else {
|
|
if (Log.isLoggable("DfltImageHeaderParser", 3)) {
|
|
Log.d("DfltImageHeaderParser", "Got tagIndex=" + i + " tagType=" + ((int) a5) + " formatCode=" + ((int) a6) + " componentCount=" + b3);
|
|
}
|
|
int i2 = b3 + b[a6];
|
|
if (i2 > 4) {
|
|
if (Log.isLoggable("DfltImageHeaderParser", 3)) {
|
|
Log.d("DfltImageHeaderParser", "Got byte count > 4, not orientation, continuing, formatCode=" + ((int) a6));
|
|
}
|
|
} else {
|
|
int i3 = a4 + 8;
|
|
if (i3 >= 0 && i3 <= randomAccessReader.a()) {
|
|
if (i2 >= 0 && i2 + i3 <= randomAccessReader.a()) {
|
|
return randomAccessReader.a(i3);
|
|
}
|
|
if (Log.isLoggable("DfltImageHeaderParser", 3)) {
|
|
Log.d("DfltImageHeaderParser", "Illegal number of bytes for TI tag data tagType=" + ((int) a5));
|
|
}
|
|
} else if (Log.isLoggable("DfltImageHeaderParser", 3)) {
|
|
Log.d("DfltImageHeaderParser", "Illegal tagValueOffset=" + i3 + " tagType=" + ((int) a5));
|
|
}
|
|
}
|
|
}
|
|
} else if (Log.isLoggable("DfltImageHeaderParser", 3)) {
|
|
Log.d("DfltImageHeaderParser", "Got invalid format code = " + ((int) a6));
|
|
}
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
}
|