8274096: Improve decoding of image files
Reviewed-by: prr, kizune, rhalade, mschoene
This commit is contained in:
parent
3603e754ce
commit
82d6afe675
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -28,6 +28,8 @@ package com.sun.imageio.plugins.common;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import javax.imageio.stream.ImageInputStream;
|
||||
|
||||
/**
|
||||
@ -213,4 +215,47 @@ public class ReaderUtil {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* An utility method to allocate and initialize a byte array
|
||||
* step by step with pre-defined limit, instead of allocating
|
||||
* a large array up-front based on the length derived from
|
||||
* an image header.
|
||||
*
|
||||
* @param iis a {@code ImageInputStream} to decode data and store
|
||||
* it in byte array.
|
||||
* @param length the size of data to decode
|
||||
*
|
||||
* @return array of size length when decode succeeeds
|
||||
*
|
||||
* @throws IOException if decoding of stream fails
|
||||
*/
|
||||
public static byte[] staggeredReadByteStream(ImageInputStream iis,
|
||||
int length) throws IOException {
|
||||
final int UNIT_SIZE = 1024000;
|
||||
byte[] decodedData;
|
||||
if (length < UNIT_SIZE) {
|
||||
decodedData = new byte[length];
|
||||
iis.readFully(decodedData, 0, length);
|
||||
} else {
|
||||
int bytesToRead = length;
|
||||
int bytesRead = 0;
|
||||
List<byte[]> bufs = new ArrayList<>();
|
||||
while (bytesToRead != 0) {
|
||||
int sz = Math.min(bytesToRead, UNIT_SIZE);
|
||||
byte[] unit = new byte[sz];
|
||||
iis.readFully(unit, 0, sz);
|
||||
bufs.add(unit);
|
||||
bytesRead += sz;
|
||||
bytesToRead -= sz;
|
||||
}
|
||||
decodedData = new byte[bytesRead];
|
||||
int copiedBytes = 0;
|
||||
for (byte[] ba : bufs) {
|
||||
System.arraycopy(ba, 0, decodedData, copiedBytes, ba.length);
|
||||
copiedBytes += ba.length;
|
||||
}
|
||||
}
|
||||
return decodedData;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -1438,7 +1438,11 @@ public abstract class TIFFDecompressor {
|
||||
*
|
||||
* @param byteCount the number of bytes of compressed data.
|
||||
*/
|
||||
public void setByteCount(int byteCount) {
|
||||
public void setByteCount(int byteCount) throws IOException{
|
||||
if (byteCount < 0) {
|
||||
throw new IIOException("Strip byte count can't be"
|
||||
+ " negative: " + byteCount);
|
||||
}
|
||||
this.byteCount = byteCount;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -29,6 +29,7 @@ import java.io.EOFException;
|
||||
import javax.imageio.IIOException;
|
||||
import javax.imageio.plugins.tiff.BaselineTIFFTagSet;
|
||||
import javax.imageio.plugins.tiff.TIFFField;
|
||||
import com.sun.imageio.plugins.common.ReaderUtil;
|
||||
|
||||
class TIFFFaxDecompressor extends TIFFDecompressor {
|
||||
|
||||
@ -637,14 +638,14 @@ class TIFFFaxDecompressor extends TIFFDecompressor {
|
||||
this.bitsPerScanline = scanlineStride*8;
|
||||
this.lineBitNum = 8*dstOffset;
|
||||
|
||||
this.data = new byte[byteCount];
|
||||
this.bitPointer = 0;
|
||||
this.bytePointer = 0;
|
||||
this.prevChangingElems = new int[w + 1];
|
||||
this.currChangingElems = new int[w + 1];
|
||||
|
||||
stream.seek(offset);
|
||||
stream.readFully(data);
|
||||
this.data = ReaderUtil.
|
||||
staggeredReadByteStream(stream, byteCount);
|
||||
|
||||
if (compression == BaselineTIFFTagSet.COMPRESSION_CCITT_RLE) {
|
||||
decodeRLE();
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -27,6 +27,7 @@ package com.sun.imageio.plugins.tiff;
|
||||
import java.io.IOException;
|
||||
import javax.imageio.IIOException;
|
||||
import javax.imageio.plugins.tiff.BaselineTIFFTagSet;
|
||||
import com.sun.imageio.plugins.common.ReaderUtil;
|
||||
|
||||
class TIFFLZWDecompressor extends TIFFDecompressor {
|
||||
|
||||
@ -95,9 +96,8 @@ class TIFFLZWDecompressor extends TIFFDecompressor {
|
||||
}
|
||||
|
||||
stream.seek(offset);
|
||||
|
||||
byte[] sdata = new byte[byteCount];
|
||||
stream.readFully(sdata);
|
||||
byte[] sdata = ReaderUtil.
|
||||
staggeredReadByteStream(stream, byteCount);
|
||||
|
||||
if (flipBits) {
|
||||
for (int i = 0; i < byteCount; i++) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -25,6 +25,7 @@
|
||||
package com.sun.imageio.plugins.tiff;
|
||||
|
||||
import java.io.IOException;
|
||||
import com.sun.imageio.plugins.common.ReaderUtil;
|
||||
|
||||
public class TIFFPackBitsDecompressor extends TIFFDecompressor {
|
||||
|
||||
@ -77,8 +78,8 @@ public class TIFFPackBitsDecompressor extends TIFFDecompressor {
|
||||
int scanlineStride) throws IOException {
|
||||
stream.seek(offset);
|
||||
|
||||
byte[] srcData = new byte[byteCount];
|
||||
stream.readFully(srcData);
|
||||
byte[] srcData = ReaderUtil.
|
||||
staggeredReadByteStream(stream, byteCount);
|
||||
|
||||
int bytesPerRow = (srcWidth*bitsPerPixel + 7)/8;
|
||||
byte[] buf;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -180,7 +180,7 @@ public class TIFFYCbCrDecompressor extends TIFFDecompressor {
|
||||
super.setOffset(offset);
|
||||
}
|
||||
|
||||
public void setByteCount(int byteCount) {
|
||||
public void setByteCount(int byteCount) throws IOException {
|
||||
if(decompressor != null) {
|
||||
decompressor.setByteCount(byteCount);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user