first commit
This commit is contained in:
commit
4d332ef662
27586 changed files with 3281783 additions and 0 deletions
12
rus/WEB-INF/lib/jai_codec_src/META-INF/MANIFEST.MF
Normal file
12
rus/WEB-INF/lib/jai_codec_src/META-INF/MANIFEST.MF
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
Manifest-Version: 1.0
|
||||
Ant-Version: Apache Ant 1.6.2
|
||||
Created-By: 1.4.2_12-b03 (Sun Microsystems Inc.)
|
||||
Specification-Title: Java Advanced Imaging Codecs
|
||||
Specification-Version: 1.1-mr
|
||||
Specification-Vendor: Sun Microsystems, Inc.
|
||||
Implementation-Title: com.sun.media.jai.codec
|
||||
Implementation-Version: 1.1.3
|
||||
Implementation-Vendor: Sun Microsystems, Inc.
|
||||
Extension-Name: com.sun.media.jai.codec
|
||||
Sealed: true
|
||||
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
package com.sun.media.jai.codec;
|
||||
|
||||
public class BMPEncodeParam implements ImageEncodeParam {
|
||||
public static final int VERSION_2 = 0;
|
||||
|
||||
public static final int VERSION_3 = 1;
|
||||
|
||||
public static final int VERSION_4 = 2;
|
||||
|
||||
private int version = 1;
|
||||
|
||||
private boolean compressed = false;
|
||||
|
||||
private boolean topDown = false;
|
||||
|
||||
public void setVersion(int versionNumber) {
|
||||
checkVersion(versionNumber);
|
||||
this.version = versionNumber;
|
||||
}
|
||||
|
||||
public int getVersion() {
|
||||
return this.version;
|
||||
}
|
||||
|
||||
public void setCompressed(boolean compressed) {
|
||||
this.compressed = compressed;
|
||||
}
|
||||
|
||||
public boolean isCompressed() {
|
||||
return this.compressed;
|
||||
}
|
||||
|
||||
public void setTopDown(boolean topDown) {
|
||||
this.topDown = topDown;
|
||||
}
|
||||
|
||||
public boolean isTopDown() {
|
||||
return this.topDown;
|
||||
}
|
||||
|
||||
private void checkVersion(int versionNumber) {
|
||||
if (versionNumber != 0 && versionNumber != 1 && versionNumber != 2)
|
||||
throw new RuntimeException(JaiI18N.getString("BMPEncodeParam0"));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
package com.sun.media.jai.codec;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class ByteArraySeekableStream extends SeekableStream {
|
||||
private byte[] src;
|
||||
|
||||
private int offset;
|
||||
|
||||
private int length;
|
||||
|
||||
private int pointer;
|
||||
|
||||
public ByteArraySeekableStream(byte[] src, int offset, int length) throws IOException {
|
||||
this.src = src;
|
||||
this.offset = offset;
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
public ByteArraySeekableStream(byte[] src) throws IOException {
|
||||
this(src, 0, src.length);
|
||||
}
|
||||
|
||||
public synchronized int available() {
|
||||
ensureOpen();
|
||||
return Math.min(this.offset + this.length, this.src.length) - this.pointer;
|
||||
}
|
||||
|
||||
public boolean canSeekBackwards() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public long getFilePointer() {
|
||||
return (long)this.pointer;
|
||||
}
|
||||
|
||||
public void seek(long pos) {
|
||||
this.pointer = (int)pos;
|
||||
}
|
||||
|
||||
public int read() {
|
||||
if (this.pointer < this.length + this.offset)
|
||||
return this.src[this.pointer++ + this.offset] & 0xFF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
public int read(byte[] b, int off, int len) {
|
||||
if (b == null)
|
||||
throw new NullPointerException();
|
||||
if (off < 0 || len < 0 || off + len > b.length)
|
||||
throw new IndexOutOfBoundsException();
|
||||
if (len == 0)
|
||||
return 0;
|
||||
int oldPointer = this.pointer;
|
||||
this.pointer = Math.min(this.pointer + len, this.length + this.offset);
|
||||
if (this.pointer == oldPointer)
|
||||
return -1;
|
||||
System.arraycopy(this.src, oldPointer, b, off, this.pointer - oldPointer);
|
||||
return this.pointer - oldPointer;
|
||||
}
|
||||
|
||||
public int skipBytes(int n) {
|
||||
int oldPointer = this.pointer;
|
||||
this.pointer = Math.min(this.pointer + n, this.length + this.offset);
|
||||
return this.pointer - oldPointer;
|
||||
}
|
||||
|
||||
public void close() {}
|
||||
|
||||
public long length() {
|
||||
return (long)this.length;
|
||||
}
|
||||
|
||||
private void ensureOpen() {}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
package com.sun.media.jai.codec;
|
||||
|
||||
public class FPXDecodeParam implements ImageDecodeParam {
|
||||
private int resolution = -1;
|
||||
|
||||
public FPXDecodeParam() {}
|
||||
|
||||
public FPXDecodeParam(int resolution) {
|
||||
this.resolution = resolution;
|
||||
}
|
||||
|
||||
public void setResolution(int resolution) {
|
||||
this.resolution = resolution;
|
||||
}
|
||||
|
||||
public int getResolution() {
|
||||
return this.resolution;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,117 @@
|
|||
package com.sun.media.jai.codec;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public final class FileCacheSeekableStream extends SeekableStream {
|
||||
private static TempFileCleanupThread cleanupThread = null;
|
||||
|
||||
private InputStream stream;
|
||||
|
||||
private File cacheFile;
|
||||
|
||||
private RandomAccessFile cache;
|
||||
|
||||
private int bufLen = 1024;
|
||||
|
||||
private byte[] buf = new byte[this.bufLen];
|
||||
|
||||
private long length = 0L;
|
||||
|
||||
private long pointer = 0L;
|
||||
|
||||
private boolean foundEOF = false;
|
||||
|
||||
static {
|
||||
try {
|
||||
Method shutdownMethod = Runtime.class.getDeclaredMethod("addShutdownHook", new Class[] { Thread.class });
|
||||
cleanupThread = new TempFileCleanupThread();
|
||||
shutdownMethod.invoke(Runtime.getRuntime(), new Object[] { cleanupThread });
|
||||
} catch (Exception e) {
|
||||
cleanupThread = null;
|
||||
}
|
||||
}
|
||||
|
||||
public FileCacheSeekableStream(InputStream stream) throws IOException {
|
||||
this.stream = stream;
|
||||
this.cacheFile = File.createTempFile("jai-FCSS-", ".tmp");
|
||||
this.cacheFile.deleteOnExit();
|
||||
this.cache = new RandomAccessFile(this.cacheFile, "rw");
|
||||
if (cleanupThread != null)
|
||||
cleanupThread.addFile(this.cacheFile);
|
||||
}
|
||||
|
||||
private long readUntil(long pos) throws IOException {
|
||||
if (pos < this.length)
|
||||
return pos;
|
||||
if (this.foundEOF)
|
||||
return this.length;
|
||||
long len = pos - this.length;
|
||||
this.cache.seek(this.length);
|
||||
while (len > 0L) {
|
||||
int nbytes = this.stream.read(this.buf, 0, (int)Math.min(len, (long)this.bufLen));
|
||||
if (nbytes == -1) {
|
||||
this.foundEOF = true;
|
||||
return this.length;
|
||||
}
|
||||
this.cache.setLength(this.cache.length() + (long)nbytes);
|
||||
this.cache.write(this.buf, 0, nbytes);
|
||||
len -= (long)nbytes;
|
||||
this.length += (long)nbytes;
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
public boolean canSeekBackwards() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public long getFilePointer() {
|
||||
return this.pointer;
|
||||
}
|
||||
|
||||
public void seek(long pos) throws IOException {
|
||||
if (pos < 0L)
|
||||
throw new IOException(JaiI18N.getString("FileCacheSeekableStream0"));
|
||||
this.pointer = pos;
|
||||
}
|
||||
|
||||
public int read() throws IOException {
|
||||
long next = this.pointer + 1L;
|
||||
long pos = readUntil(next);
|
||||
if (pos >= next) {
|
||||
this.cache.seek(this.pointer++);
|
||||
return this.cache.read();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public int read(byte[] b, int off, int len) throws IOException {
|
||||
if (b == null)
|
||||
throw new NullPointerException();
|
||||
if (off < 0 || len < 0 || off + len > b.length)
|
||||
throw new IndexOutOfBoundsException();
|
||||
if (len == 0)
|
||||
return 0;
|
||||
long pos = readUntil(this.pointer + (long)len);
|
||||
len = (int)Math.min((long)len, pos - this.pointer);
|
||||
if (len > 0) {
|
||||
this.cache.seek(this.pointer);
|
||||
this.cache.readFully(b, off, len);
|
||||
this.pointer += (long)len;
|
||||
return len;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
super.close();
|
||||
this.cache.close();
|
||||
this.cacheFile.delete();
|
||||
if (cleanupThread != null)
|
||||
cleanupThread.removeFile(this.cacheFile);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,130 @@
|
|||
package com.sun.media.jai.codec;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
|
||||
public class FileSeekableStream extends SeekableStream {
|
||||
private RandomAccessFile file;
|
||||
|
||||
private long markPos = -1L;
|
||||
|
||||
private static final int PAGE_SHIFT = 9;
|
||||
|
||||
private static final int PAGE_SIZE = 512;
|
||||
|
||||
private static final int PAGE_MASK = 511;
|
||||
|
||||
private static final int NUM_PAGES = 32;
|
||||
|
||||
private static final int READ_CACHE_LIMIT = 512;
|
||||
|
||||
private byte[][] pageBuf = new byte[512][32];
|
||||
|
||||
private int[] currentPage = new int[32];
|
||||
|
||||
private long length = 0L;
|
||||
|
||||
private long pointer = 0L;
|
||||
|
||||
public FileSeekableStream(RandomAccessFile file) throws IOException {
|
||||
this.file = file;
|
||||
file.seek(0L);
|
||||
this.length = file.length();
|
||||
for (int i = 0; i < 32; i++) {
|
||||
this.pageBuf[i] = new byte[512];
|
||||
this.currentPage[i] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
public FileSeekableStream(File file) throws IOException {
|
||||
this(new RandomAccessFile(file, "r"));
|
||||
}
|
||||
|
||||
public FileSeekableStream(String name) throws IOException {
|
||||
this(new RandomAccessFile(name, "r"));
|
||||
}
|
||||
|
||||
public final boolean canSeekBackwards() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public final long getFilePointer() throws IOException {
|
||||
return this.pointer;
|
||||
}
|
||||
|
||||
public final void seek(long pos) throws IOException {
|
||||
if (pos < 0L)
|
||||
throw new IOException(JaiI18N.getString("FileSeekableStream0"));
|
||||
this.pointer = pos;
|
||||
}
|
||||
|
||||
public final int skip(int n) throws IOException {
|
||||
this.pointer += (long)n;
|
||||
return n;
|
||||
}
|
||||
|
||||
private byte[] readPage(long pointer) throws IOException {
|
||||
int page = (int)(pointer >> 9L);
|
||||
for (int i = 0; i < 32; i++) {
|
||||
if (this.currentPage[i] == page)
|
||||
return this.pageBuf[i];
|
||||
}
|
||||
int index = (int)(Math.random() * 32.0D);
|
||||
this.currentPage[index] = page;
|
||||
long pos = (long)page << 9L;
|
||||
long remaining = this.length - pos;
|
||||
int len = (512L < remaining) ? 512 : (int)remaining;
|
||||
this.file.seek(pos);
|
||||
this.file.readFully(this.pageBuf[index], 0, len);
|
||||
return this.pageBuf[index];
|
||||
}
|
||||
|
||||
public final int read() throws IOException {
|
||||
if (this.pointer >= this.length)
|
||||
return -1;
|
||||
byte[] buf = readPage(this.pointer);
|
||||
return buf[(int)(this.pointer++ & 0x1FFL)] & 0xFF;
|
||||
}
|
||||
|
||||
public final int read(byte[] b, int off, int len) throws IOException {
|
||||
if (b == null)
|
||||
throw new NullPointerException();
|
||||
if (off < 0 || len < 0 || off + len > b.length)
|
||||
throw new IndexOutOfBoundsException();
|
||||
if (len == 0)
|
||||
return 0;
|
||||
len = (int)Math.min((long)len, this.length - this.pointer);
|
||||
if (len <= 0)
|
||||
return -1;
|
||||
if (len > 512) {
|
||||
this.file.seek(this.pointer);
|
||||
int nbytes = this.file.read(b, off, len);
|
||||
this.pointer += (long)nbytes;
|
||||
return nbytes;
|
||||
}
|
||||
byte[] buf = readPage(this.pointer);
|
||||
int remaining = 512 - (int)(this.pointer & 0x1FFL);
|
||||
int newLen = (len < remaining) ? len : remaining;
|
||||
System.arraycopy(buf, (int)(this.pointer & 0x1FFL), b, off, newLen);
|
||||
this.pointer += (long)newLen;
|
||||
return newLen;
|
||||
}
|
||||
|
||||
public final void close() throws IOException {
|
||||
this.file.close();
|
||||
}
|
||||
|
||||
public final synchronized void mark(int readLimit) {
|
||||
this.markPos = this.pointer;
|
||||
}
|
||||
|
||||
public final synchronized void reset() throws IOException {
|
||||
if (this.markPos != -1L)
|
||||
this.pointer = this.markPos;
|
||||
}
|
||||
|
||||
public boolean markSupported() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
package com.sun.media.jai.codec;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
public class ForwardSeekableStream extends SeekableStream {
|
||||
private InputStream src;
|
||||
|
||||
long pointer = 0L;
|
||||
|
||||
long markPos = -1L;
|
||||
|
||||
public ForwardSeekableStream(InputStream src) {
|
||||
this.src = src;
|
||||
}
|
||||
|
||||
public final int read() throws IOException {
|
||||
int result = this.src.read();
|
||||
if (result != -1)
|
||||
this.pointer++;
|
||||
return result;
|
||||
}
|
||||
|
||||
public final int read(byte[] b, int off, int len) throws IOException {
|
||||
int result = this.src.read(b, off, len);
|
||||
if (result != -1)
|
||||
this.pointer += (long)result;
|
||||
return result;
|
||||
}
|
||||
|
||||
public final long skip(long n) throws IOException {
|
||||
long skipped = this.src.skip(n);
|
||||
this.pointer += skipped;
|
||||
return skipped;
|
||||
}
|
||||
|
||||
public final int available() throws IOException {
|
||||
return this.src.available();
|
||||
}
|
||||
|
||||
public final void close() throws IOException {
|
||||
this.src.close();
|
||||
}
|
||||
|
||||
public final synchronized void mark(int readLimit) {
|
||||
this.markPos = this.pointer;
|
||||
this.src.mark(readLimit);
|
||||
}
|
||||
|
||||
public final synchronized void reset() throws IOException {
|
||||
if (this.markPos != -1L)
|
||||
this.pointer = this.markPos;
|
||||
this.src.reset();
|
||||
}
|
||||
|
||||
public boolean markSupported() {
|
||||
return this.src.markSupported();
|
||||
}
|
||||
|
||||
public final boolean canSeekBackwards() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public final long getFilePointer() {
|
||||
return this.pointer;
|
||||
}
|
||||
|
||||
public final void seek(long pos) throws IOException {
|
||||
while (pos - this.pointer > 0L)
|
||||
this.pointer += this.src.skip(pos - this.pointer);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,389 @@
|
|||
package com.sun.media.jai.codec;
|
||||
|
||||
import com.sun.media.jai.codecimpl.BMPCodec;
|
||||
import com.sun.media.jai.codecimpl.FPXCodec;
|
||||
import com.sun.media.jai.codecimpl.GIFCodec;
|
||||
import com.sun.media.jai.codecimpl.ImagingListenerProxy;
|
||||
import com.sun.media.jai.codecimpl.JPEGCodec;
|
||||
import com.sun.media.jai.codecimpl.PNGCodec;
|
||||
import com.sun.media.jai.codecimpl.PNMCodec;
|
||||
import com.sun.media.jai.codecimpl.TIFFCodec;
|
||||
import com.sun.media.jai.codecimpl.WBMPCodec;
|
||||
import com.sun.media.jai.codecimpl.util.FloatDoubleColorModel;
|
||||
import java.awt.color.ColorSpace;
|
||||
import java.awt.image.ColorModel;
|
||||
import java.awt.image.ComponentColorModel;
|
||||
import java.awt.image.IndexColorModel;
|
||||
import java.awt.image.RenderedImage;
|
||||
import java.awt.image.SampleModel;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Vector;
|
||||
|
||||
public abstract class ImageCodec {
|
||||
private static Hashtable codecs = new Hashtable();
|
||||
|
||||
static {
|
||||
registerCodec(new BMPCodec());
|
||||
registerCodec(new GIFCodec());
|
||||
registerCodec(new FPXCodec());
|
||||
registerCodec(new JPEGCodec());
|
||||
registerCodec(new PNGCodec());
|
||||
registerCodec(new PNMCodec());
|
||||
registerCodec(new TIFFCodec());
|
||||
registerCodec(new WBMPCodec());
|
||||
}
|
||||
|
||||
public static ImageCodec getCodec(String name) {
|
||||
return (ImageCodec)codecs.get(name.toLowerCase());
|
||||
}
|
||||
|
||||
public static void registerCodec(ImageCodec codec) {
|
||||
codecs.put(codec.getFormatName().toLowerCase(), codec);
|
||||
}
|
||||
|
||||
public static void unregisterCodec(String name) {
|
||||
codecs.remove(name.toLowerCase());
|
||||
}
|
||||
|
||||
public static Enumeration getCodecs() {
|
||||
return codecs.elements();
|
||||
}
|
||||
|
||||
public static ImageEncoder createImageEncoder(String name, OutputStream dst, ImageEncodeParam param) {
|
||||
ImageCodec codec = getCodec(name);
|
||||
if (codec == null)
|
||||
return null;
|
||||
return codec.createImageEncoder(dst, param);
|
||||
}
|
||||
|
||||
public static ImageDecoder createImageDecoder(String name, InputStream src, ImageDecodeParam param) {
|
||||
ImageCodec codec = getCodec(name);
|
||||
if (codec == null)
|
||||
return null;
|
||||
return codec.createImageDecoder(src, param);
|
||||
}
|
||||
|
||||
public static ImageDecoder createImageDecoder(String name, File src, ImageDecodeParam param) throws IOException {
|
||||
ImageCodec codec = getCodec(name);
|
||||
if (codec == null)
|
||||
return null;
|
||||
return codec.createImageDecoder(src, param);
|
||||
}
|
||||
|
||||
public static ImageDecoder createImageDecoder(String name, SeekableStream src, ImageDecodeParam param) {
|
||||
ImageCodec codec = getCodec(name);
|
||||
if (codec == null)
|
||||
return null;
|
||||
return codec.createImageDecoder(src, param);
|
||||
}
|
||||
|
||||
private static String[] vectorToStrings(Vector nameVec) {
|
||||
int count = nameVec.size();
|
||||
String[] names = new String[count];
|
||||
for (int i = 0; i < count; i++)
|
||||
names[i] = (String)nameVec.elementAt(i);
|
||||
return names;
|
||||
}
|
||||
|
||||
public static String[] getDecoderNames(SeekableStream src) {
|
||||
if (!src.canSeekBackwards() && !src.markSupported())
|
||||
throw new IllegalArgumentException(JaiI18N.getString("ImageCodec2"));
|
||||
Enumeration enumeration = codecs.elements();
|
||||
Vector nameVec = new Vector();
|
||||
String opName = null;
|
||||
while (enumeration.hasMoreElements()) {
|
||||
ImageCodec codec = (ImageCodec)enumeration.nextElement();
|
||||
int bytesNeeded = codec.getNumHeaderBytes();
|
||||
if (bytesNeeded == 0 && !src.canSeekBackwards())
|
||||
continue;
|
||||
try {
|
||||
if (bytesNeeded > 0) {
|
||||
src.mark(bytesNeeded);
|
||||
byte[] header = new byte[bytesNeeded];
|
||||
src.readFully(header);
|
||||
src.reset();
|
||||
if (codec.isFormatRecognized(header))
|
||||
nameVec.add(codec.getFormatName());
|
||||
continue;
|
||||
}
|
||||
long pointer = src.getFilePointer();
|
||||
src.seek(0L);
|
||||
if (codec.isFormatRecognized(src))
|
||||
nameVec.add(codec.getFormatName());
|
||||
src.seek(pointer);
|
||||
} catch (IOException e) {
|
||||
ImagingListenerProxy.errorOccurred(JaiI18N.getString("ImageCodec3"), e, ImageCodec.class, false);
|
||||
}
|
||||
}
|
||||
return vectorToStrings(nameVec);
|
||||
}
|
||||
|
||||
public static String[] getEncoderNames(RenderedImage im, ImageEncodeParam param) {
|
||||
Enumeration enumeration = codecs.elements();
|
||||
Vector nameVec = new Vector();
|
||||
String opName = null;
|
||||
while (enumeration.hasMoreElements()) {
|
||||
ImageCodec codec = (ImageCodec)enumeration.nextElement();
|
||||
if (codec.canEncodeImage(im, param))
|
||||
nameVec.add(codec.getFormatName());
|
||||
}
|
||||
return vectorToStrings(nameVec);
|
||||
}
|
||||
|
||||
public int getNumHeaderBytes() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public boolean isFormatRecognized(byte[] header) {
|
||||
throw new RuntimeException(JaiI18N.getString("ImageCodec0"));
|
||||
}
|
||||
|
||||
public boolean isFormatRecognized(SeekableStream src) throws IOException {
|
||||
throw new RuntimeException(JaiI18N.getString("ImageCodec1"));
|
||||
}
|
||||
|
||||
protected ImageDecoder createImageDecoder(InputStream src, ImageDecodeParam param) {
|
||||
SeekableStream stream = SeekableStream.wrapInputStream(src, true);
|
||||
return createImageDecoder(stream, param);
|
||||
}
|
||||
|
||||
protected ImageDecoder createImageDecoder(File src, ImageDecodeParam param) throws IOException {
|
||||
return createImageDecoder((SeekableStream)new FileSeekableStream(src), param);
|
||||
}
|
||||
|
||||
private static final byte[][] grayIndexCmaps = new byte[][] { null, new byte[] { 0, -1 }, new byte[] { 0, 85, -86, -1 }, null, new byte[] {
|
||||
0, 17, 34, 51, 68, 85, 102, 119, -120, -103,
|
||||
-86, -69, -52, -35, -18, -1 } };
|
||||
|
||||
public static ColorModel createGrayIndexColorModel(SampleModel sm, boolean blackIsZero) {
|
||||
if (sm.getNumBands() != 1)
|
||||
throw new IllegalArgumentException();
|
||||
int sampleSize = sm.getSampleSize(0);
|
||||
byte[] cmap = null;
|
||||
if (sampleSize < 8) {
|
||||
cmap = grayIndexCmaps[sampleSize];
|
||||
if (!blackIsZero) {
|
||||
int length = cmap.length;
|
||||
byte[] newCmap = new byte[length];
|
||||
for (int i = 0; i < length; i++)
|
||||
newCmap[i] = cmap[length - i - 1];
|
||||
cmap = newCmap;
|
||||
}
|
||||
} else {
|
||||
cmap = new byte[256];
|
||||
if (blackIsZero) {
|
||||
for (int i = 0; i < 256; i++)
|
||||
cmap[i] = (byte)i;
|
||||
} else {
|
||||
for (int i = 0; i < 256; i++)
|
||||
cmap[i] = (byte)(255 - i);
|
||||
}
|
||||
}
|
||||
return new IndexColorModel(sampleSize, cmap.length, cmap, cmap, cmap);
|
||||
}
|
||||
|
||||
private static final int[] GrayBits8 = new int[] { 8 };
|
||||
|
||||
private static final ComponentColorModel colorModelGray8 = new ComponentColorModel(ColorSpace.getInstance(1003), GrayBits8, false, false, 1, 0);
|
||||
|
||||
private static final int[] GrayAlphaBits8 = new int[] { 8, 8 };
|
||||
|
||||
private static final ComponentColorModel colorModelGrayAlpha8 = new ComponentColorModel(ColorSpace.getInstance(1003), GrayAlphaBits8, true, false, 3, 0);
|
||||
|
||||
private static final int[] GrayBits16 = new int[] { 16 };
|
||||
|
||||
private static final ComponentColorModel colorModelGray16 = new ComponentColorModel(ColorSpace.getInstance(1003), GrayBits16, false, false, 1, 1);
|
||||
|
||||
private static final int[] GrayAlphaBits16 = new int[] { 16, 16 };
|
||||
|
||||
private static final ComponentColorModel colorModelGrayAlpha16 = new ComponentColorModel(ColorSpace.getInstance(1003), GrayAlphaBits16, true, false, 3, 1);
|
||||
|
||||
private static final int[] GrayBits32 = new int[] { 32 };
|
||||
|
||||
private static final ComponentColorModel colorModelGray32 = new ComponentColorModel(ColorSpace.getInstance(1003), GrayBits32, false, false, 1, 3);
|
||||
|
||||
private static final int[] GrayAlphaBits32 = new int[] { 32, 32 };
|
||||
|
||||
private static final ComponentColorModel colorModelGrayAlpha32 = new ComponentColorModel(ColorSpace.getInstance(1003), GrayAlphaBits32, true, false, 3, 3);
|
||||
|
||||
private static final int[] RGBBits8 = new int[] { 8, 8, 8 };
|
||||
|
||||
private static final ComponentColorModel colorModelRGB8 = new ComponentColorModel(ColorSpace.getInstance(1000), RGBBits8, false, false, 1, 0);
|
||||
|
||||
private static final int[] RGBABits8 = new int[] { 8, 8, 8, 8 };
|
||||
|
||||
private static final ComponentColorModel colorModelRGBA8 = new ComponentColorModel(ColorSpace.getInstance(1000), RGBABits8, true, false, 3, 0);
|
||||
|
||||
private static final int[] RGBBits16 = new int[] { 16, 16, 16 };
|
||||
|
||||
private static final ComponentColorModel colorModelRGB16 = new ComponentColorModel(ColorSpace.getInstance(1000), RGBBits16, false, false, 1, 1);
|
||||
|
||||
private static final int[] RGBABits16 = new int[] { 16, 16, 16, 16 };
|
||||
|
||||
private static final ComponentColorModel colorModelRGBA16 = new ComponentColorModel(ColorSpace.getInstance(1000), RGBABits16, true, false, 3, 1);
|
||||
|
||||
private static final int[] RGBBits32 = new int[] { 32, 32, 32 };
|
||||
|
||||
private static final ComponentColorModel colorModelRGB32 = new ComponentColorModel(ColorSpace.getInstance(1000), RGBBits32, false, false, 1, 3);
|
||||
|
||||
private static final int[] RGBABits32 = new int[] { 32, 32, 32, 32 };
|
||||
|
||||
private static final ComponentColorModel colorModelRGBA32 = new ComponentColorModel(ColorSpace.getInstance(1000), RGBABits32, true, false, 3, 3);
|
||||
|
||||
public static ColorModel createComponentColorModel(SampleModel sm) {
|
||||
int type = sm.getDataType();
|
||||
int bands = sm.getNumBands();
|
||||
ComponentColorModel cm = null;
|
||||
if (type == 0) {
|
||||
switch (bands) {
|
||||
case 1:
|
||||
cm = colorModelGray8;
|
||||
break;
|
||||
case 2:
|
||||
cm = colorModelGrayAlpha8;
|
||||
break;
|
||||
case 3:
|
||||
cm = colorModelRGB8;
|
||||
break;
|
||||
case 4:
|
||||
cm = colorModelRGBA8;
|
||||
break;
|
||||
}
|
||||
} else if (type == 1) {
|
||||
switch (bands) {
|
||||
case 1:
|
||||
cm = colorModelGray16;
|
||||
break;
|
||||
case 2:
|
||||
cm = colorModelGrayAlpha16;
|
||||
break;
|
||||
case 3:
|
||||
cm = colorModelRGB16;
|
||||
break;
|
||||
case 4:
|
||||
cm = colorModelRGBA16;
|
||||
break;
|
||||
}
|
||||
} else if (type == 3) {
|
||||
switch (bands) {
|
||||
case 1:
|
||||
cm = colorModelGray32;
|
||||
break;
|
||||
case 2:
|
||||
cm = colorModelGrayAlpha32;
|
||||
break;
|
||||
case 3:
|
||||
cm = colorModelRGB32;
|
||||
break;
|
||||
case 4:
|
||||
cm = colorModelRGBA32;
|
||||
break;
|
||||
}
|
||||
} else if (type == 4 && bands >= 1 && bands <= 4) {
|
||||
ColorSpace cs = (bands <= 2) ? ColorSpace.getInstance(1003) : ColorSpace.getInstance(1000);
|
||||
boolean hasAlpha = (bands % 2 == 0);
|
||||
cm = new FloatDoubleColorModel(cs, hasAlpha, false, hasAlpha ? 3 : 1, 4);
|
||||
}
|
||||
return cm;
|
||||
}
|
||||
|
||||
public static ColorModel createComponentColorModel(SampleModel sm, ColorSpace cp) {
|
||||
if (cp == null)
|
||||
return createComponentColorModel(sm);
|
||||
int type = sm.getDataType();
|
||||
int bands = sm.getNumBands();
|
||||
ComponentColorModel cm = null;
|
||||
int[] bits = null;
|
||||
int transferType = -1;
|
||||
boolean hasAlpha = (bands % 2 == 0);
|
||||
if (cp instanceof com.sun.media.jai.util.SimpleCMYKColorSpace)
|
||||
hasAlpha = false;
|
||||
int transparency = hasAlpha ? 3 : 1;
|
||||
if (type == 0) {
|
||||
transferType = 0;
|
||||
switch (bands) {
|
||||
case 1:
|
||||
bits = GrayBits8;
|
||||
break;
|
||||
case 2:
|
||||
bits = GrayAlphaBits8;
|
||||
break;
|
||||
case 3:
|
||||
bits = RGBBits8;
|
||||
break;
|
||||
case 4:
|
||||
bits = RGBABits8;
|
||||
break;
|
||||
}
|
||||
} else if (type == 1) {
|
||||
transferType = 1;
|
||||
switch (bands) {
|
||||
case 1:
|
||||
bits = GrayBits16;
|
||||
break;
|
||||
case 2:
|
||||
bits = GrayAlphaBits16;
|
||||
break;
|
||||
case 3:
|
||||
bits = RGBBits16;
|
||||
break;
|
||||
case 4:
|
||||
bits = RGBABits16;
|
||||
break;
|
||||
}
|
||||
} else if (type == 3) {
|
||||
transferType = 3;
|
||||
switch (bands) {
|
||||
case 1:
|
||||
bits = GrayBits32;
|
||||
break;
|
||||
case 2:
|
||||
bits = GrayAlphaBits32;
|
||||
break;
|
||||
case 3:
|
||||
bits = RGBBits32;
|
||||
break;
|
||||
case 4:
|
||||
bits = RGBABits32;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (type == 4 && bands >= 1 && bands <= 4) {
|
||||
cm = new FloatDoubleColorModel(cp, hasAlpha, false, transparency, 4);
|
||||
} else {
|
||||
cm = new ComponentColorModel(cp, bits, hasAlpha, false, transparency, transferType);
|
||||
}
|
||||
return cm;
|
||||
}
|
||||
|
||||
public static boolean isIndicesForGrayscale(byte[] r, byte[] g, byte[] b) {
|
||||
if (r.length != g.length || r.length != b.length)
|
||||
return false;
|
||||
int size = r.length;
|
||||
if (size != 256)
|
||||
return false;
|
||||
for (int i = 0; i < size; i++) {
|
||||
byte temp = (byte)i;
|
||||
if (r[i] != temp || g[i] != temp || b[i] != temp)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public abstract String getFormatName();
|
||||
|
||||
protected abstract Class getEncodeParamClass();
|
||||
|
||||
protected abstract Class getDecodeParamClass();
|
||||
|
||||
protected abstract ImageEncoder createImageEncoder(OutputStream paramOutputStream, ImageEncodeParam paramImageEncodeParam);
|
||||
|
||||
public abstract boolean canEncodeImage(RenderedImage paramRenderedImage, ImageEncodeParam paramImageEncodeParam);
|
||||
|
||||
protected abstract ImageDecoder createImageDecoder(SeekableStream paramSeekableStream, ImageDecodeParam paramImageDecodeParam);
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
package com.sun.media.jai.codec;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public interface ImageDecodeParam extends Cloneable, Serializable {}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
package com.sun.media.jai.codec;
|
||||
|
||||
import java.awt.image.Raster;
|
||||
import java.awt.image.RenderedImage;
|
||||
import java.io.IOException;
|
||||
|
||||
public interface ImageDecoder {
|
||||
ImageDecodeParam getParam();
|
||||
|
||||
void setParam(ImageDecodeParam paramImageDecodeParam);
|
||||
|
||||
SeekableStream getInputStream();
|
||||
|
||||
int getNumPages() throws IOException;
|
||||
|
||||
Raster decodeAsRaster() throws IOException;
|
||||
|
||||
Raster decodeAsRaster(int paramInt) throws IOException;
|
||||
|
||||
RenderedImage decodeAsRenderedImage() throws IOException;
|
||||
|
||||
RenderedImage decodeAsRenderedImage(int paramInt) throws IOException;
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
package com.sun.media.jai.codec;
|
||||
|
||||
import java.awt.image.Raster;
|
||||
import java.awt.image.RenderedImage;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
public abstract class ImageDecoderImpl implements ImageDecoder {
|
||||
protected SeekableStream input;
|
||||
|
||||
protected ImageDecodeParam param;
|
||||
|
||||
public ImageDecoderImpl(SeekableStream input, ImageDecodeParam param) {
|
||||
this.input = input;
|
||||
this.param = param;
|
||||
}
|
||||
|
||||
public ImageDecoderImpl(InputStream input, ImageDecodeParam param) {
|
||||
this.input = new ForwardSeekableStream(input);
|
||||
this.param = param;
|
||||
}
|
||||
|
||||
public ImageDecodeParam getParam() {
|
||||
return this.param;
|
||||
}
|
||||
|
||||
public void setParam(ImageDecodeParam param) {
|
||||
this.param = param;
|
||||
}
|
||||
|
||||
public SeekableStream getInputStream() {
|
||||
return this.input;
|
||||
}
|
||||
|
||||
public int getNumPages() throws IOException {
|
||||
return 1;
|
||||
}
|
||||
|
||||
public Raster decodeAsRaster() throws IOException {
|
||||
return decodeAsRaster(0);
|
||||
}
|
||||
|
||||
public Raster decodeAsRaster(int page) throws IOException {
|
||||
RenderedImage im = decodeAsRenderedImage(page);
|
||||
return im.getData();
|
||||
}
|
||||
|
||||
public RenderedImage decodeAsRenderedImage() throws IOException {
|
||||
return decodeAsRenderedImage(0);
|
||||
}
|
||||
|
||||
public abstract RenderedImage decodeAsRenderedImage(int paramInt) throws IOException;
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
package com.sun.media.jai.codec;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public interface ImageEncodeParam extends ImageDecodeParam, Cloneable, Serializable {}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
package com.sun.media.jai.codec;
|
||||
|
||||
import java.awt.image.ColorModel;
|
||||
import java.awt.image.Raster;
|
||||
import java.awt.image.RenderedImage;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
public interface ImageEncoder {
|
||||
ImageEncodeParam getParam();
|
||||
|
||||
void setParam(ImageEncodeParam paramImageEncodeParam);
|
||||
|
||||
OutputStream getOutputStream();
|
||||
|
||||
void encode(Raster paramRaster, ColorModel paramColorModel) throws IOException;
|
||||
|
||||
void encode(RenderedImage paramRenderedImage) throws IOException;
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
package com.sun.media.jai.codec;
|
||||
|
||||
import com.sun.media.jai.codecimpl.SingleTileRenderedImage;
|
||||
import java.awt.image.ColorModel;
|
||||
import java.awt.image.Raster;
|
||||
import java.awt.image.RenderedImage;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
public abstract class ImageEncoderImpl implements ImageEncoder {
|
||||
protected OutputStream output;
|
||||
|
||||
protected ImageEncodeParam param;
|
||||
|
||||
public ImageEncoderImpl(OutputStream output, ImageEncodeParam param) {
|
||||
this.output = output;
|
||||
this.param = param;
|
||||
}
|
||||
|
||||
public ImageEncodeParam getParam() {
|
||||
return this.param;
|
||||
}
|
||||
|
||||
public void setParam(ImageEncodeParam param) {
|
||||
this.param = param;
|
||||
}
|
||||
|
||||
public OutputStream getOutputStream() {
|
||||
return this.output;
|
||||
}
|
||||
|
||||
public void encode(Raster ras, ColorModel cm) throws IOException {
|
||||
RenderedImage im = new SingleTileRenderedImage(ras, cm);
|
||||
encode(im);
|
||||
}
|
||||
|
||||
public abstract void encode(RenderedImage paramRenderedImage) throws IOException;
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package com.sun.media.jai.codec;
|
||||
|
||||
public class JPEGDecodeParam implements ImageDecodeParam {
|
||||
private boolean decodeToCSM = true;
|
||||
|
||||
public void setDecodeToCSM(boolean decodeToCSM) {
|
||||
this.decodeToCSM = decodeToCSM;
|
||||
}
|
||||
|
||||
public boolean getDecodeToCSM() {
|
||||
return this.decodeToCSM;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,163 @@
|
|||
package com.sun.media.jai.codec;
|
||||
|
||||
public class JPEGEncodeParam implements ImageEncodeParam {
|
||||
private static int JPEG_MAX_BANDS = 3;
|
||||
|
||||
private int[] hSamp;
|
||||
|
||||
private int[] vSamp;
|
||||
|
||||
private int[][] qTab;
|
||||
|
||||
private int[] qTabSlot;
|
||||
|
||||
private float qual;
|
||||
|
||||
private int rstInterval;
|
||||
|
||||
private boolean writeImageOnly;
|
||||
|
||||
private boolean writeTablesOnly;
|
||||
|
||||
private boolean writeJFIFHeader;
|
||||
|
||||
private boolean qualitySet;
|
||||
|
||||
private boolean[] qTabSet;
|
||||
|
||||
public JPEGEncodeParam() {
|
||||
this.hSamp = new int[JPEG_MAX_BANDS];
|
||||
this.vSamp = new int[JPEG_MAX_BANDS];
|
||||
this.qTabSlot = new int[JPEG_MAX_BANDS];
|
||||
this.qTab = new int[JPEG_MAX_BANDS][];
|
||||
this.qTabSet = new boolean[JPEG_MAX_BANDS];
|
||||
this.hSamp[0] = 1;
|
||||
this.vSamp[0] = 1;
|
||||
this.qTabSlot[0] = 0;
|
||||
this.qTab[0] = null;
|
||||
this.qTabSet[0] = false;
|
||||
this.hSamp[1] = 2;
|
||||
this.vSamp[1] = 2;
|
||||
this.qTabSlot[1] = 1;
|
||||
this.qTab[1] = null;
|
||||
this.qTabSet[1] = false;
|
||||
this.hSamp[2] = 2;
|
||||
this.vSamp[2] = 2;
|
||||
this.qTabSlot[2] = 1;
|
||||
this.qTab[2] = null;
|
||||
this.qTabSet[2] = false;
|
||||
this.qual = 0.75F;
|
||||
this.rstInterval = 0;
|
||||
this.writeImageOnly = false;
|
||||
this.writeTablesOnly = false;
|
||||
this.writeJFIFHeader = true;
|
||||
}
|
||||
|
||||
public void setHorizontalSubsampling(int component, int subsample) {
|
||||
this.hSamp[component] = subsample;
|
||||
}
|
||||
|
||||
public int getHorizontalSubsampling(int component) {
|
||||
return this.hSamp[component];
|
||||
}
|
||||
|
||||
public void setVerticalSubsampling(int component, int subsample) {
|
||||
this.vSamp[component] = subsample;
|
||||
}
|
||||
|
||||
public int getVerticalSubsampling(int component) {
|
||||
return this.vSamp[component];
|
||||
}
|
||||
|
||||
public void setLumaQTable(int[] qTable) {
|
||||
setQTable(0, 0, qTable);
|
||||
this.qTabSet[0] = true;
|
||||
this.qualitySet = false;
|
||||
}
|
||||
|
||||
public void setChromaQTable(int[] qTable) {
|
||||
setQTable(1, 1, qTable);
|
||||
setQTable(2, 1, qTable);
|
||||
this.qTabSet[1] = true;
|
||||
this.qTabSet[2] = true;
|
||||
this.qualitySet = false;
|
||||
}
|
||||
|
||||
public void setQTable(int component, int tableSlot, int[] qTable) {
|
||||
this.qTab[component] = (int[])qTable.clone();
|
||||
this.qTabSlot[component] = tableSlot;
|
||||
this.qTabSet[component] = true;
|
||||
this.qualitySet = false;
|
||||
}
|
||||
|
||||
public boolean isQTableSet(int component) {
|
||||
return this.qTabSet[component];
|
||||
}
|
||||
|
||||
public int[] getQTable(int component) {
|
||||
if (!this.qTabSet[component])
|
||||
throw new IllegalStateException(JaiI18N.getString("JPEGEncodeParam0"));
|
||||
return this.qTab[component];
|
||||
}
|
||||
|
||||
public int getQTableSlot(int component) {
|
||||
if (!this.qTabSet[component])
|
||||
throw new IllegalStateException(JaiI18N.getString("JPEGEncodeParam0"));
|
||||
return this.qTabSlot[component];
|
||||
}
|
||||
|
||||
public void setRestartInterval(int restartInterval) {
|
||||
this.rstInterval = restartInterval;
|
||||
}
|
||||
|
||||
public int getRestartInterval() {
|
||||
return this.rstInterval;
|
||||
}
|
||||
|
||||
public void setQuality(float quality) {
|
||||
this.qual = quality;
|
||||
for (int i = 0; i < JPEG_MAX_BANDS; i++)
|
||||
this.qTabSet[i] = false;
|
||||
this.qualitySet = true;
|
||||
}
|
||||
|
||||
public boolean isQualitySet() {
|
||||
return this.qualitySet;
|
||||
}
|
||||
|
||||
public float getQuality() {
|
||||
return this.qual;
|
||||
}
|
||||
|
||||
public void setWriteTablesOnly(boolean tablesOnly) {
|
||||
this.writeTablesOnly = tablesOnly;
|
||||
}
|
||||
|
||||
public boolean getWriteTablesOnly() {
|
||||
return this.writeTablesOnly;
|
||||
}
|
||||
|
||||
public void setWriteImageOnly(boolean imageOnly) {
|
||||
this.writeImageOnly = imageOnly;
|
||||
}
|
||||
|
||||
public boolean getWriteImageOnly() {
|
||||
return this.writeImageOnly;
|
||||
}
|
||||
|
||||
public void setWriteJFIFHeader(boolean writeJFIF) {
|
||||
this.writeJFIFHeader = writeJFIF;
|
||||
}
|
||||
|
||||
public boolean getWriteJFIFHeader() {
|
||||
return this.writeJFIFHeader;
|
||||
}
|
||||
|
||||
public Object clone() {
|
||||
try {
|
||||
return super.clone();
|
||||
} catch (CloneNotSupportedException e) {
|
||||
throw new InternalError();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
package com.sun.media.jai.codec;
|
||||
|
||||
import com.sun.media.jai.codecimpl.util.PropertyUtil;
|
||||
|
||||
class JaiI18N {
|
||||
static String packageName = "com.sun.media.jai.codec";
|
||||
|
||||
public static String getString(String key) {
|
||||
return PropertyUtil.getString(packageName, key);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,100 @@
|
|||
package com.sun.media.jai.codec;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Vector;
|
||||
|
||||
public final class MemoryCacheSeekableStream extends SeekableStream {
|
||||
private InputStream src;
|
||||
|
||||
private long pointer = 0L;
|
||||
|
||||
private static final int SECTOR_SHIFT = 9;
|
||||
|
||||
private static final int SECTOR_SIZE = 512;
|
||||
|
||||
private static final int SECTOR_MASK = 511;
|
||||
|
||||
private Vector data = new Vector();
|
||||
|
||||
int sectors = 0;
|
||||
|
||||
int length = 0;
|
||||
|
||||
boolean foundEOS = false;
|
||||
|
||||
public MemoryCacheSeekableStream(InputStream src) {
|
||||
this.src = src;
|
||||
}
|
||||
|
||||
public final int available() throws IOException {
|
||||
return this.src.available();
|
||||
}
|
||||
|
||||
private long readUntil(long pos) throws IOException {
|
||||
if (pos < (long)this.length)
|
||||
return pos;
|
||||
if (this.foundEOS)
|
||||
return (long)this.length;
|
||||
int sector = (int)(pos >> 9L);
|
||||
int startSector = this.length >> 9;
|
||||
for (int i = startSector; i <= sector; i++) {
|
||||
byte[] buf = new byte[512];
|
||||
this.data.addElement(buf);
|
||||
int len = 512;
|
||||
int off = 0;
|
||||
while (len > 0) {
|
||||
int nbytes = this.src.read(buf, off, len);
|
||||
if (nbytes == -1) {
|
||||
this.foundEOS = true;
|
||||
return (long)this.length;
|
||||
}
|
||||
off += nbytes;
|
||||
len -= nbytes;
|
||||
this.length += nbytes;
|
||||
}
|
||||
}
|
||||
return (long)this.length;
|
||||
}
|
||||
|
||||
public boolean canSeekBackwards() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public long getFilePointer() {
|
||||
return this.pointer;
|
||||
}
|
||||
|
||||
public void seek(long pos) throws IOException {
|
||||
if (pos < 0L)
|
||||
throw new IOException(JaiI18N.getString("MemoryCacheSeekableStream0"));
|
||||
this.pointer = pos;
|
||||
}
|
||||
|
||||
public int read() throws IOException {
|
||||
long next = this.pointer + 1L;
|
||||
long pos = readUntil(next);
|
||||
if (pos >= next) {
|
||||
byte[] buf = (byte[])this.data.elementAt((int)(this.pointer >> 9L));
|
||||
return buf[(int)(this.pointer++ & 0x1FFL)] & 0xFF;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public int read(byte[] b, int off, int len) throws IOException {
|
||||
if (b == null)
|
||||
throw new NullPointerException();
|
||||
if (off < 0 || len < 0 || off + len > b.length)
|
||||
throw new IndexOutOfBoundsException();
|
||||
if (len == 0)
|
||||
return 0;
|
||||
long pos = readUntil(this.pointer + (long)len);
|
||||
if (pos <= this.pointer)
|
||||
return -1;
|
||||
byte[] buf = (byte[])this.data.elementAt((int)(this.pointer >> 9L));
|
||||
int nbytes = Math.min((int)((pos < this.pointer + (long)len) ? (pos - this.pointer) : (long)len), 512 - (int)(this.pointer & 0x1FFL));
|
||||
System.arraycopy(buf, (int)(this.pointer & 0x1FFL), b, off, nbytes);
|
||||
this.pointer += (long)nbytes;
|
||||
return nbytes;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
package com.sun.media.jai.codec;
|
||||
|
||||
public class PNGDecodeParam implements ImageDecodeParam {
|
||||
private boolean suppressAlpha = false;
|
||||
|
||||
public boolean getSuppressAlpha() {
|
||||
return this.suppressAlpha;
|
||||
}
|
||||
|
||||
public void setSuppressAlpha(boolean suppressAlpha) {
|
||||
this.suppressAlpha = suppressAlpha;
|
||||
}
|
||||
|
||||
private boolean expandPalette = false;
|
||||
|
||||
public boolean getExpandPalette() {
|
||||
return this.expandPalette;
|
||||
}
|
||||
|
||||
public void setExpandPalette(boolean expandPalette) {
|
||||
this.expandPalette = expandPalette;
|
||||
}
|
||||
|
||||
private boolean output8BitGray = false;
|
||||
|
||||
public boolean getOutput8BitGray() {
|
||||
return this.output8BitGray;
|
||||
}
|
||||
|
||||
public void setOutput8BitGray(boolean output8BitGray) {
|
||||
this.output8BitGray = output8BitGray;
|
||||
}
|
||||
|
||||
private boolean performGammaCorrection = false;
|
||||
|
||||
public boolean getPerformGammaCorrection() {
|
||||
return this.performGammaCorrection;
|
||||
}
|
||||
|
||||
public void setPerformGammaCorrection(boolean performGammaCorrection) {
|
||||
this.performGammaCorrection = performGammaCorrection;
|
||||
}
|
||||
|
||||
private float userExponent = 1.0F;
|
||||
|
||||
public float getUserExponent() {
|
||||
return this.userExponent;
|
||||
}
|
||||
|
||||
public void setUserExponent(float userExponent) {
|
||||
if (userExponent <= 0.0F)
|
||||
throw new IllegalArgumentException(JaiI18N.getString("PNGDecodeParam0"));
|
||||
this.userExponent = userExponent;
|
||||
}
|
||||
|
||||
private float displayExponent = 2.2F;
|
||||
|
||||
public float getDisplayExponent() {
|
||||
return this.displayExponent;
|
||||
}
|
||||
|
||||
public void setDisplayExponent(float displayExponent) {
|
||||
if (displayExponent <= 0.0F)
|
||||
throw new IllegalArgumentException(JaiI18N.getString("PNGDecodeParam1"));
|
||||
this.displayExponent = displayExponent;
|
||||
}
|
||||
|
||||
private boolean expandGrayAlpha = false;
|
||||
|
||||
public boolean getExpandGrayAlpha() {
|
||||
return this.expandGrayAlpha;
|
||||
}
|
||||
|
||||
public void setExpandGrayAlpha(boolean expandGrayAlpha) {
|
||||
this.expandGrayAlpha = expandGrayAlpha;
|
||||
}
|
||||
|
||||
private boolean generateEncodeParam = false;
|
||||
|
||||
private PNGEncodeParam encodeParam = null;
|
||||
|
||||
public boolean getGenerateEncodeParam() {
|
||||
return this.generateEncodeParam;
|
||||
}
|
||||
|
||||
public void setGenerateEncodeParam(boolean generateEncodeParam) {
|
||||
this.generateEncodeParam = generateEncodeParam;
|
||||
}
|
||||
|
||||
public PNGEncodeParam getEncodeParam() {
|
||||
return this.encodeParam;
|
||||
}
|
||||
|
||||
public void setEncodeParam(PNGEncodeParam encodeParam) {
|
||||
this.encodeParam = encodeParam;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,739 @@
|
|||
package com.sun.media.jai.codec;
|
||||
|
||||
import java.awt.color.ICC_Profile;
|
||||
import java.awt.color.ICC_ProfileGray;
|
||||
import java.awt.color.ICC_ProfileRGB;
|
||||
import java.awt.image.ColorModel;
|
||||
import java.awt.image.RenderedImage;
|
||||
import java.awt.image.SampleModel;
|
||||
import java.util.Date;
|
||||
import java.util.Vector;
|
||||
|
||||
public abstract class PNGEncodeParam implements ImageEncodeParam {
|
||||
public static final int INTENT_PERCEPTUAL = 0;
|
||||
|
||||
public static final int INTENT_RELATIVE = 1;
|
||||
|
||||
public static final int INTENT_SATURATION = 2;
|
||||
|
||||
public static final int INTENT_ABSOLUTE = 3;
|
||||
|
||||
public static final int PNG_FILTER_NONE = 0;
|
||||
|
||||
public static final int PNG_FILTER_SUB = 1;
|
||||
|
||||
public static final int PNG_FILTER_UP = 2;
|
||||
|
||||
public static final int PNG_FILTER_AVERAGE = 3;
|
||||
|
||||
public static final int PNG_FILTER_PAETH = 4;
|
||||
|
||||
protected int bitDepth;
|
||||
|
||||
public static PNGEncodeParam getDefaultEncodeParam(RenderedImage im) {
|
||||
ColorModel colorModel = im.getColorModel();
|
||||
if (colorModel instanceof java.awt.image.IndexColorModel)
|
||||
return new Palette();
|
||||
SampleModel sampleModel = im.getSampleModel();
|
||||
int numBands = sampleModel.getNumBands();
|
||||
if (numBands == 1 || numBands == 2)
|
||||
return new Gray();
|
||||
return new RGB();
|
||||
}
|
||||
|
||||
public static class Palette extends PNGEncodeParam {
|
||||
private boolean backgroundSet = false;
|
||||
|
||||
public void unsetBackground() {
|
||||
this.backgroundSet = false;
|
||||
}
|
||||
|
||||
public boolean isBackgroundSet() {
|
||||
return this.backgroundSet;
|
||||
}
|
||||
|
||||
public void setBitDepth(int bitDepth) {
|
||||
if (bitDepth != 1 && bitDepth != 2 && bitDepth != 4 && bitDepth != 8)
|
||||
throw new IllegalArgumentException(JaiI18N.getString("PNGEncodeParam2"));
|
||||
this.bitDepth = bitDepth;
|
||||
this.bitDepthSet = true;
|
||||
}
|
||||
|
||||
private int[] palette = null;
|
||||
|
||||
private boolean paletteSet = false;
|
||||
|
||||
private int backgroundPaletteIndex;
|
||||
|
||||
private int[] transparency;
|
||||
|
||||
public void setPalette(int[] rgb) {
|
||||
if (rgb.length < 3 || rgb.length > 768)
|
||||
throw new IllegalArgumentException(JaiI18N.getString("PNGEncodeParam0"));
|
||||
if (rgb.length % 3 != 0)
|
||||
throw new IllegalArgumentException(JaiI18N.getString("PNGEncodeParam1"));
|
||||
this.palette = (int[])rgb.clone();
|
||||
this.paletteSet = true;
|
||||
}
|
||||
|
||||
public int[] getPalette() {
|
||||
if (!this.paletteSet)
|
||||
throw new IllegalStateException(JaiI18N.getString("PNGEncodeParam3"));
|
||||
return (int[])this.palette.clone();
|
||||
}
|
||||
|
||||
public void unsetPalette() {
|
||||
this.palette = null;
|
||||
this.paletteSet = false;
|
||||
}
|
||||
|
||||
public boolean isPaletteSet() {
|
||||
return this.paletteSet;
|
||||
}
|
||||
|
||||
public void setBackgroundPaletteIndex(int index) {
|
||||
this.backgroundPaletteIndex = index;
|
||||
this.backgroundSet = true;
|
||||
}
|
||||
|
||||
public int getBackgroundPaletteIndex() {
|
||||
if (!this.backgroundSet)
|
||||
throw new IllegalStateException(JaiI18N.getString("PNGEncodeParam4"));
|
||||
return this.backgroundPaletteIndex;
|
||||
}
|
||||
|
||||
public void setPaletteTransparency(byte[] alpha) {
|
||||
this.transparency = new int[alpha.length];
|
||||
for (int i = 0; i < alpha.length; i++)
|
||||
this.transparency[i] = alpha[i] & 0xFF;
|
||||
this.transparencySet = true;
|
||||
}
|
||||
|
||||
public byte[] getPaletteTransparency() {
|
||||
if (!this.transparencySet)
|
||||
throw new IllegalStateException(JaiI18N.getString("PNGEncodeParam5"));
|
||||
byte[] alpha = new byte[this.transparency.length];
|
||||
for (int i = 0; i < alpha.length; i++)
|
||||
alpha[i] = (byte)this.transparency[i];
|
||||
return alpha;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Gray extends PNGEncodeParam {
|
||||
private boolean backgroundSet = false;
|
||||
|
||||
private int backgroundPaletteGray;
|
||||
|
||||
private int[] transparency;
|
||||
|
||||
private int bitShift;
|
||||
|
||||
public void unsetBackground() {
|
||||
this.backgroundSet = false;
|
||||
}
|
||||
|
||||
public boolean isBackgroundSet() {
|
||||
return this.backgroundSet;
|
||||
}
|
||||
|
||||
public void setBitDepth(int bitDepth) {
|
||||
if (bitDepth != 1 && bitDepth != 2 && bitDepth != 4 && bitDepth != 8 && bitDepth != 16)
|
||||
throw new IllegalArgumentException();
|
||||
this.bitDepth = bitDepth;
|
||||
this.bitDepthSet = true;
|
||||
}
|
||||
|
||||
public void setBackgroundGray(int gray) {
|
||||
this.backgroundPaletteGray = gray;
|
||||
this.backgroundSet = true;
|
||||
}
|
||||
|
||||
public int getBackgroundGray() {
|
||||
if (!this.backgroundSet)
|
||||
throw new IllegalStateException(JaiI18N.getString("PNGEncodeParam6"));
|
||||
return this.backgroundPaletteGray;
|
||||
}
|
||||
|
||||
public void setTransparentGray(int transparentGray) {
|
||||
this.transparency = new int[1];
|
||||
this.transparency[0] = transparentGray;
|
||||
this.transparencySet = true;
|
||||
}
|
||||
|
||||
public int getTransparentGray() {
|
||||
if (!this.transparencySet)
|
||||
throw new IllegalStateException(JaiI18N.getString("PNGEncodeParam7"));
|
||||
int gray = this.transparency[0];
|
||||
return gray;
|
||||
}
|
||||
|
||||
private boolean bitShiftSet = false;
|
||||
|
||||
public void setBitShift(int bitShift) {
|
||||
if (bitShift < 0)
|
||||
throw new RuntimeException();
|
||||
this.bitShift = bitShift;
|
||||
this.bitShiftSet = true;
|
||||
}
|
||||
|
||||
public int getBitShift() {
|
||||
if (!this.bitShiftSet)
|
||||
throw new IllegalStateException(JaiI18N.getString("PNGEncodeParam8"));
|
||||
return this.bitShift;
|
||||
}
|
||||
|
||||
public void unsetBitShift() {
|
||||
this.bitShiftSet = false;
|
||||
}
|
||||
|
||||
public boolean isBitShiftSet() {
|
||||
return this.bitShiftSet;
|
||||
}
|
||||
|
||||
public boolean isBitDepthSet() {
|
||||
return this.bitDepthSet;
|
||||
}
|
||||
}
|
||||
|
||||
public static class RGB extends PNGEncodeParam {
|
||||
private boolean backgroundSet = false;
|
||||
|
||||
private int[] backgroundRGB;
|
||||
|
||||
private int[] transparency;
|
||||
|
||||
public void unsetBackground() {
|
||||
this.backgroundSet = false;
|
||||
}
|
||||
|
||||
public boolean isBackgroundSet() {
|
||||
return this.backgroundSet;
|
||||
}
|
||||
|
||||
public void setBitDepth(int bitDepth) {
|
||||
if (bitDepth != 8 && bitDepth != 16)
|
||||
throw new RuntimeException();
|
||||
this.bitDepth = bitDepth;
|
||||
this.bitDepthSet = true;
|
||||
}
|
||||
|
||||
public void setBackgroundRGB(int[] rgb) {
|
||||
if (rgb.length != 3)
|
||||
throw new RuntimeException();
|
||||
this.backgroundRGB = rgb;
|
||||
this.backgroundSet = true;
|
||||
}
|
||||
|
||||
public int[] getBackgroundRGB() {
|
||||
if (!this.backgroundSet)
|
||||
throw new IllegalStateException(JaiI18N.getString("PNGEncodeParam9"));
|
||||
return this.backgroundRGB;
|
||||
}
|
||||
|
||||
public void setTransparentRGB(int[] transparentRGB) {
|
||||
this.transparency = (int[])transparentRGB.clone();
|
||||
this.transparencySet = true;
|
||||
}
|
||||
|
||||
public int[] getTransparentRGB() {
|
||||
if (!this.transparencySet)
|
||||
throw new IllegalStateException(JaiI18N.getString("PNGEncodeParam10"));
|
||||
return (int[])this.transparency.clone();
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean bitDepthSet = false;
|
||||
|
||||
public abstract void setBitDepth(int paramInt);
|
||||
|
||||
public int getBitDepth() {
|
||||
if (!this.bitDepthSet)
|
||||
throw new IllegalStateException(JaiI18N.getString("PNGEncodeParam11"));
|
||||
return this.bitDepth;
|
||||
}
|
||||
|
||||
public void unsetBitDepth() {
|
||||
this.bitDepthSet = false;
|
||||
}
|
||||
|
||||
private boolean useInterlacing = false;
|
||||
|
||||
public void setInterlacing(boolean useInterlacing) {
|
||||
this.useInterlacing = useInterlacing;
|
||||
}
|
||||
|
||||
public boolean getInterlacing() {
|
||||
return this.useInterlacing;
|
||||
}
|
||||
|
||||
public void unsetBackground() {
|
||||
throw new RuntimeException(JaiI18N.getString("PNGEncodeParam23"));
|
||||
}
|
||||
|
||||
public boolean isBackgroundSet() {
|
||||
throw new RuntimeException(JaiI18N.getString("PNGEncodeParam24"));
|
||||
}
|
||||
|
||||
private float[] chromaticity = null;
|
||||
|
||||
private boolean chromaticitySet = false;
|
||||
|
||||
private float gamma;
|
||||
|
||||
public void setChromaticity(float[] chromaticity) {
|
||||
if (chromaticity.length != 8)
|
||||
throw new IllegalArgumentException();
|
||||
this.chromaticity = (float[])chromaticity.clone();
|
||||
this.chromaticitySet = true;
|
||||
}
|
||||
|
||||
public void setChromaticity(float whitePointX, float whitePointY, float redX, float redY, float greenX, float greenY, float blueX, float blueY) {
|
||||
float[] chroma = new float[8];
|
||||
chroma[0] = whitePointX;
|
||||
chroma[1] = whitePointY;
|
||||
chroma[2] = redX;
|
||||
chroma[3] = redY;
|
||||
chroma[4] = greenX;
|
||||
chroma[5] = greenY;
|
||||
chroma[6] = blueX;
|
||||
chroma[7] = blueY;
|
||||
setChromaticity(chroma);
|
||||
}
|
||||
|
||||
public float[] getChromaticity() {
|
||||
if (!this.chromaticitySet)
|
||||
throw new IllegalStateException(JaiI18N.getString("PNGEncodeParam12"));
|
||||
return (float[])this.chromaticity.clone();
|
||||
}
|
||||
|
||||
public void unsetChromaticity() {
|
||||
this.chromaticity = null;
|
||||
this.chromaticitySet = false;
|
||||
}
|
||||
|
||||
public boolean isChromaticitySet() {
|
||||
return this.chromaticitySet;
|
||||
}
|
||||
|
||||
private boolean gammaSet = false;
|
||||
|
||||
public void setGamma(float gamma) {
|
||||
this.gamma = gamma;
|
||||
this.gammaSet = true;
|
||||
}
|
||||
|
||||
public float getGamma() {
|
||||
if (!this.gammaSet)
|
||||
throw new IllegalStateException(JaiI18N.getString("PNGEncodeParam13"));
|
||||
return this.gamma;
|
||||
}
|
||||
|
||||
public void unsetGamma() {
|
||||
this.gammaSet = false;
|
||||
}
|
||||
|
||||
public boolean isGammaSet() {
|
||||
return this.gammaSet;
|
||||
}
|
||||
|
||||
private int[] paletteHistogram = null;
|
||||
|
||||
private boolean paletteHistogramSet = false;
|
||||
|
||||
public void setPaletteHistogram(int[] paletteHistogram) {
|
||||
this.paletteHistogram = (int[])paletteHistogram.clone();
|
||||
this.paletteHistogramSet = true;
|
||||
}
|
||||
|
||||
public int[] getPaletteHistogram() {
|
||||
if (!this.paletteHistogramSet)
|
||||
throw new IllegalStateException(JaiI18N.getString("PNGEncodeParam14"));
|
||||
return this.paletteHistogram;
|
||||
}
|
||||
|
||||
public void unsetPaletteHistogram() {
|
||||
this.paletteHistogram = null;
|
||||
this.paletteHistogramSet = false;
|
||||
}
|
||||
|
||||
public boolean isPaletteHistogramSet() {
|
||||
return this.paletteHistogramSet;
|
||||
}
|
||||
|
||||
private byte[] ICCProfileData = null;
|
||||
|
||||
private boolean ICCProfileDataSet = false;
|
||||
|
||||
private String ICCProfileName = null;
|
||||
|
||||
public void setICCProfileData(byte[] ICCProfileData) {
|
||||
this.ICCProfileData = (byte[])ICCProfileData.clone();
|
||||
this.ICCProfileDataSet = true;
|
||||
ICC_Profile profile = ICC_Profile.getInstance(this.ICCProfileData);
|
||||
if (!(profile instanceof ICC_ProfileRGB) && !(profile instanceof ICC_ProfileGray))
|
||||
return;
|
||||
try {
|
||||
if (profile instanceof ICC_ProfileRGB) {
|
||||
setGamma(((ICC_ProfileRGB)profile).getGamma(0));
|
||||
} else if (profile instanceof ICC_ProfileGray) {
|
||||
setGamma(((ICC_ProfileGray)profile).getGamma());
|
||||
}
|
||||
} catch (Exception e) {}
|
||||
if (profile instanceof ICC_ProfileGray)
|
||||
return;
|
||||
float[] chrom = new float[8];
|
||||
float[] whitePoint = ((ICC_ProfileRGB)profile).getMediaWhitePoint();
|
||||
if (whitePoint == null)
|
||||
return;
|
||||
float sum = whitePoint[0] + whitePoint[1] + whitePoint[2];
|
||||
chrom[0] = whitePoint[0] / sum;
|
||||
chrom[1] = whitePoint[1] / sum;
|
||||
float[][] temp = ((ICC_ProfileRGB)profile).getMatrix();
|
||||
if (temp == null)
|
||||
return;
|
||||
for (int i = 0; i < 3; i++) {
|
||||
sum = temp[0][i] + temp[1][i] + temp[2][i];
|
||||
chrom[2 + (i << 1)] = temp[0][i] / sum;
|
||||
chrom[3 + (i << 1)] = temp[1][i] / sum;
|
||||
}
|
||||
setChromaticity(chrom);
|
||||
}
|
||||
|
||||
public byte[] getICCProfileData() {
|
||||
if (!this.ICCProfileDataSet)
|
||||
throw new IllegalStateException(JaiI18N.getString("PNGEncodeParam15"));
|
||||
return (byte[])this.ICCProfileData.clone();
|
||||
}
|
||||
|
||||
public void unsetICCProfileData() {
|
||||
this.ICCProfileData = null;
|
||||
this.ICCProfileDataSet = false;
|
||||
this.ICCProfileName = null;
|
||||
}
|
||||
|
||||
public void setICCProfileName(String name) {
|
||||
if (!this.ICCProfileDataSet)
|
||||
throw new IllegalStateException(JaiI18N.getString("PNGEncodeParam15"));
|
||||
this.ICCProfileName = name;
|
||||
}
|
||||
|
||||
public String getICCProfileName() {
|
||||
if (!this.ICCProfileDataSet)
|
||||
throw new IllegalStateException(JaiI18N.getString("PNGEncodeParam15"));
|
||||
return this.ICCProfileName;
|
||||
}
|
||||
|
||||
public boolean isICCProfileDataSet() {
|
||||
return this.ICCProfileDataSet;
|
||||
}
|
||||
|
||||
private int[] physicalDimension = null;
|
||||
|
||||
private boolean physicalDimensionSet = false;
|
||||
|
||||
public void setPhysicalDimension(int[] physicalDimension) {
|
||||
this.physicalDimension = (int[])physicalDimension.clone();
|
||||
this.physicalDimensionSet = true;
|
||||
}
|
||||
|
||||
public void setPhysicalDimension(int xPixelsPerUnit, int yPixelsPerUnit, int unitSpecifier) {
|
||||
int[] pd = new int[3];
|
||||
pd[0] = xPixelsPerUnit;
|
||||
pd[1] = yPixelsPerUnit;
|
||||
pd[2] = unitSpecifier;
|
||||
setPhysicalDimension(pd);
|
||||
}
|
||||
|
||||
public int[] getPhysicalDimension() {
|
||||
if (!this.physicalDimensionSet)
|
||||
throw new IllegalStateException(JaiI18N.getString("PNGEncodeParam16"));
|
||||
return (int[])this.physicalDimension.clone();
|
||||
}
|
||||
|
||||
public void unsetPhysicalDimension() {
|
||||
this.physicalDimension = null;
|
||||
this.physicalDimensionSet = false;
|
||||
}
|
||||
|
||||
public boolean isPhysicalDimensionSet() {
|
||||
return this.physicalDimensionSet;
|
||||
}
|
||||
|
||||
private PNGSuggestedPaletteEntry[] suggestedPalette = null;
|
||||
|
||||
private boolean suggestedPaletteSet = false;
|
||||
|
||||
public void setSuggestedPalette(PNGSuggestedPaletteEntry[] palette) {
|
||||
this.suggestedPalette = (PNGSuggestedPaletteEntry[])palette.clone();
|
||||
this.suggestedPaletteSet = true;
|
||||
}
|
||||
|
||||
public PNGSuggestedPaletteEntry[] getSuggestedPalette() {
|
||||
if (!this.suggestedPaletteSet)
|
||||
throw new IllegalStateException(JaiI18N.getString("PNGEncodeParam17"));
|
||||
return (PNGSuggestedPaletteEntry[])this.suggestedPalette.clone();
|
||||
}
|
||||
|
||||
public void unsetSuggestedPalette() {
|
||||
this.suggestedPalette = null;
|
||||
this.suggestedPaletteSet = false;
|
||||
}
|
||||
|
||||
public boolean isSuggestedPaletteSet() {
|
||||
return this.suggestedPaletteSet;
|
||||
}
|
||||
|
||||
private int[] significantBits = null;
|
||||
|
||||
private boolean significantBitsSet = false;
|
||||
|
||||
private int SRGBIntent;
|
||||
|
||||
public void setSignificantBits(int[] significantBits) {
|
||||
this.significantBits = (int[])significantBits.clone();
|
||||
this.significantBitsSet = true;
|
||||
}
|
||||
|
||||
public int[] getSignificantBits() {
|
||||
if (!this.significantBitsSet)
|
||||
throw new IllegalStateException(JaiI18N.getString("PNGEncodeParam18"));
|
||||
return (int[])this.significantBits.clone();
|
||||
}
|
||||
|
||||
public void unsetSignificantBits() {
|
||||
this.significantBits = null;
|
||||
this.significantBitsSet = false;
|
||||
}
|
||||
|
||||
public boolean isSignificantBitsSet() {
|
||||
return this.significantBitsSet;
|
||||
}
|
||||
|
||||
private boolean SRGBIntentSet = false;
|
||||
|
||||
public void setSRGBIntent(int SRGBIntent) {
|
||||
this.SRGBIntent = SRGBIntent;
|
||||
this.SRGBIntentSet = true;
|
||||
}
|
||||
|
||||
public int getSRGBIntent() {
|
||||
if (!this.SRGBIntentSet)
|
||||
throw new IllegalStateException(JaiI18N.getString("PNGEncodeParam19"));
|
||||
return this.SRGBIntent;
|
||||
}
|
||||
|
||||
public void unsetSRGBIntent() {
|
||||
this.SRGBIntentSet = false;
|
||||
}
|
||||
|
||||
public boolean isSRGBIntentSet() {
|
||||
return this.SRGBIntentSet;
|
||||
}
|
||||
|
||||
private String[] text = null;
|
||||
|
||||
private boolean textSet = false;
|
||||
|
||||
private Date modificationTime;
|
||||
|
||||
public void setText(String[] text) {
|
||||
this.text = text;
|
||||
this.textSet = true;
|
||||
}
|
||||
|
||||
public String[] getText() {
|
||||
if (!this.textSet)
|
||||
throw new IllegalStateException(JaiI18N.getString("PNGEncodeParam20"));
|
||||
return this.text;
|
||||
}
|
||||
|
||||
public void unsetText() {
|
||||
this.text = null;
|
||||
this.textSet = false;
|
||||
}
|
||||
|
||||
public boolean isTextSet() {
|
||||
return this.textSet;
|
||||
}
|
||||
|
||||
private boolean modificationTimeSet = false;
|
||||
|
||||
public void setModificationTime(Date modificationTime) {
|
||||
this.modificationTime = modificationTime;
|
||||
this.modificationTimeSet = true;
|
||||
}
|
||||
|
||||
public Date getModificationTime() {
|
||||
if (!this.modificationTimeSet)
|
||||
throw new IllegalStateException(JaiI18N.getString("PNGEncodeParam21"));
|
||||
return this.modificationTime;
|
||||
}
|
||||
|
||||
public void unsetModificationTime() {
|
||||
this.modificationTime = null;
|
||||
this.modificationTimeSet = false;
|
||||
}
|
||||
|
||||
public boolean isModificationTimeSet() {
|
||||
return this.modificationTimeSet;
|
||||
}
|
||||
|
||||
boolean transparencySet = false;
|
||||
|
||||
public void unsetTransparency() {
|
||||
this.transparencySet = false;
|
||||
}
|
||||
|
||||
public boolean isTransparencySet() {
|
||||
return this.transparencySet;
|
||||
}
|
||||
|
||||
private String[] zText = null;
|
||||
|
||||
private boolean zTextSet = false;
|
||||
|
||||
public void setCompressedText(String[] text) {
|
||||
this.zText = text;
|
||||
this.zTextSet = true;
|
||||
}
|
||||
|
||||
public String[] getCompressedText() {
|
||||
if (!this.zTextSet)
|
||||
throw new IllegalStateException(JaiI18N.getString("PNGEncodeParam22"));
|
||||
return this.zText;
|
||||
}
|
||||
|
||||
public void unsetCompressedText() {
|
||||
this.zText = null;
|
||||
this.zTextSet = false;
|
||||
}
|
||||
|
||||
public boolean isCompressedTextSet() {
|
||||
return this.zTextSet;
|
||||
}
|
||||
|
||||
Vector chunkType = new Vector();
|
||||
|
||||
Vector chunkData = new Vector();
|
||||
|
||||
public synchronized void addPrivateChunk(String type, byte[] data) {
|
||||
this.chunkType.add(type);
|
||||
this.chunkData.add(data.clone());
|
||||
}
|
||||
|
||||
public synchronized int getNumPrivateChunks() {
|
||||
return this.chunkType.size();
|
||||
}
|
||||
|
||||
public synchronized String getPrivateChunkType(int index) {
|
||||
return (String)this.chunkType.elementAt(index);
|
||||
}
|
||||
|
||||
public synchronized byte[] getPrivateChunkData(int index) {
|
||||
return (byte[])this.chunkData.elementAt(index);
|
||||
}
|
||||
|
||||
public synchronized void removeUnsafeToCopyPrivateChunks() {
|
||||
Vector newChunkType = new Vector();
|
||||
Vector newChunkData = new Vector();
|
||||
int len = getNumPrivateChunks();
|
||||
for (int i = 0; i < len; i++) {
|
||||
String type = getPrivateChunkType(i);
|
||||
char lastChar = type.charAt(3);
|
||||
if (lastChar >= 'a' && lastChar <= 'z') {
|
||||
newChunkType.add(type);
|
||||
newChunkData.add(getPrivateChunkData(i));
|
||||
}
|
||||
}
|
||||
this.chunkType = newChunkType;
|
||||
this.chunkData = newChunkData;
|
||||
}
|
||||
|
||||
public synchronized void removeAllPrivateChunks() {
|
||||
this.chunkType = new Vector();
|
||||
this.chunkData = new Vector();
|
||||
}
|
||||
|
||||
private static final int abs(int x) {
|
||||
return (x < 0) ? -x : x;
|
||||
}
|
||||
|
||||
public static final int paethPredictor(int a, int b, int c) {
|
||||
int p = a + b - c;
|
||||
int pa = abs(p - a);
|
||||
int pb = abs(p - b);
|
||||
int pc = abs(p - c);
|
||||
if (pa <= pb && pa <= pc)
|
||||
return a;
|
||||
if (pb <= pc)
|
||||
return b;
|
||||
return c;
|
||||
}
|
||||
|
||||
public int filterRow(byte[] currRow, byte[] prevRow, byte[][] scratchRows, int bytesPerRow, int bytesPerPixel) {
|
||||
int[] filterBadness = new int[5];
|
||||
for (int i = 0; i < 5; i++)
|
||||
filterBadness[i] = Integer.MAX_VALUE;
|
||||
int badness = 0;
|
||||
for (int k = bytesPerPixel; k < bytesPerRow + bytesPerPixel; k++) {
|
||||
int curr = currRow[k] & 0xFF;
|
||||
badness += curr;
|
||||
}
|
||||
filterBadness[0] = badness;
|
||||
byte[] subFilteredRow = scratchRows[1];
|
||||
int j = 0;
|
||||
for (int i3 = bytesPerPixel; i3 < bytesPerRow + bytesPerPixel; i3++) {
|
||||
int curr = currRow[i3] & 0xFF;
|
||||
int left = currRow[i3 - bytesPerPixel] & 0xFF;
|
||||
int difference = curr - left;
|
||||
subFilteredRow[i3] = (byte)difference;
|
||||
j += abs(difference);
|
||||
}
|
||||
filterBadness[1] = j;
|
||||
byte[] upFilteredRow = scratchRows[2];
|
||||
j = 0;
|
||||
for (int i2 = bytesPerPixel; i2 < bytesPerRow + bytesPerPixel; i2++) {
|
||||
int curr = currRow[i2] & 0xFF;
|
||||
int up = prevRow[i2] & 0xFF;
|
||||
int difference = curr - up;
|
||||
upFilteredRow[i2] = (byte)difference;
|
||||
j += abs(difference);
|
||||
}
|
||||
filterBadness[2] = j;
|
||||
byte[] averageFilteredRow = scratchRows[3];
|
||||
j = 0;
|
||||
for (int i1 = bytesPerPixel; i1 < bytesPerRow + bytesPerPixel; i1++) {
|
||||
int curr = currRow[i1] & 0xFF;
|
||||
int left = currRow[i1 - bytesPerPixel] & 0xFF;
|
||||
int up = prevRow[i1] & 0xFF;
|
||||
int difference = curr - (left + up) / 2;
|
||||
averageFilteredRow[i1] = (byte)difference;
|
||||
j += abs(difference);
|
||||
}
|
||||
filterBadness[3] = j;
|
||||
byte[] paethFilteredRow = scratchRows[4];
|
||||
j = 0;
|
||||
for (int n = bytesPerPixel; n < bytesPerRow + bytesPerPixel; n++) {
|
||||
int curr = currRow[n] & 0xFF;
|
||||
int left = currRow[n - bytesPerPixel] & 0xFF;
|
||||
int up = prevRow[n] & 0xFF;
|
||||
int upleft = prevRow[n - bytesPerPixel] & 0xFF;
|
||||
int predictor = paethPredictor(left, up, upleft);
|
||||
int difference = curr - predictor;
|
||||
paethFilteredRow[n] = (byte)difference;
|
||||
j += abs(difference);
|
||||
}
|
||||
filterBadness[4] = j;
|
||||
int filterType = 0;
|
||||
int minBadness = filterBadness[0];
|
||||
for (int m = 1; m < 5; m++) {
|
||||
if (filterBadness[m] < minBadness) {
|
||||
minBadness = filterBadness[m];
|
||||
filterType = m;
|
||||
}
|
||||
}
|
||||
if (filterType == 0)
|
||||
System.arraycopy(currRow, bytesPerPixel, scratchRows[0], bytesPerPixel, bytesPerRow);
|
||||
return filterType;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
package com.sun.media.jai.codec;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class PNGSuggestedPaletteEntry implements Serializable {
|
||||
public String name;
|
||||
|
||||
public int sampleDepth;
|
||||
|
||||
public int red;
|
||||
|
||||
public int green;
|
||||
|
||||
public int blue;
|
||||
|
||||
public int alpha;
|
||||
|
||||
public int frequency;
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package com.sun.media.jai.codec;
|
||||
|
||||
public class PNMEncodeParam implements ImageEncodeParam {
|
||||
private boolean raw = true;
|
||||
|
||||
public void setRaw(boolean raw) {
|
||||
this.raw = raw;
|
||||
}
|
||||
|
||||
public boolean getRaw() {
|
||||
return this.raw;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
package com.sun.media.jai.codec;
|
||||
|
||||
class SectorStreamSegmentMapper implements StreamSegmentMapper {
|
||||
long[] segmentPositions;
|
||||
|
||||
int segmentLength;
|
||||
|
||||
int totalLength;
|
||||
|
||||
int lastSegmentLength;
|
||||
|
||||
public SectorStreamSegmentMapper(long[] segmentPositions, int segmentLength, int totalLength) {
|
||||
this.segmentPositions = (long[])segmentPositions.clone();
|
||||
this.segmentLength = segmentLength;
|
||||
this.totalLength = totalLength;
|
||||
this.lastSegmentLength = totalLength - (segmentPositions.length - 1) * segmentLength;
|
||||
}
|
||||
|
||||
public StreamSegment getStreamSegment(long position, int length) {
|
||||
int index = (int)(position / (long)this.segmentLength);
|
||||
int len = (index == this.segmentPositions.length - 1) ? this.lastSegmentLength : this.segmentLength;
|
||||
position -= (long)(index * this.segmentLength);
|
||||
len = (int)((long)len - position);
|
||||
if (len > length)
|
||||
len = length;
|
||||
return new StreamSegment(this.segmentPositions[index] + position, len);
|
||||
}
|
||||
|
||||
public void getStreamSegment(long position, int length, StreamSegment seg) {
|
||||
int index = (int)(position / (long)this.segmentLength);
|
||||
int len = (index == this.segmentPositions.length - 1) ? this.lastSegmentLength : this.segmentLength;
|
||||
position -= (long)(index * this.segmentLength);
|
||||
len = (int)((long)len - position);
|
||||
if (len > length)
|
||||
len = length;
|
||||
seg.setStartPos(this.segmentPositions[index] + position);
|
||||
seg.setSegmentLength(len);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
package com.sun.media.jai.codec;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.RandomAccessFile;
|
||||
|
||||
public class SeekableOutputStream extends OutputStream {
|
||||
private RandomAccessFile file;
|
||||
|
||||
public SeekableOutputStream(RandomAccessFile file) {
|
||||
if (file == null)
|
||||
throw new IllegalArgumentException(JaiI18N.getString("SeekableOutputStream0"));
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
public void write(int b) throws IOException {
|
||||
this.file.write(b);
|
||||
}
|
||||
|
||||
public void write(byte[] b) throws IOException {
|
||||
this.file.write(b);
|
||||
}
|
||||
|
||||
public void write(byte[] b, int off, int len) throws IOException {
|
||||
this.file.write(b, off, len);
|
||||
}
|
||||
|
||||
public void flush() throws IOException {
|
||||
FileDescriptor fd = this.file.getFD();
|
||||
if (fd.valid())
|
||||
fd.sync();
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
this.file.close();
|
||||
}
|
||||
|
||||
public long getFilePointer() throws IOException {
|
||||
return this.file.getFilePointer();
|
||||
}
|
||||
|
||||
public void seek(long pos) throws IOException {
|
||||
this.file.seek(pos);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,244 @@
|
|||
package com.sun.media.jai.codec;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
public abstract class SeekableStream extends InputStream implements DataInput {
|
||||
public static SeekableStream wrapInputStream(InputStream is, boolean canSeekBackwards) {
|
||||
SeekableStream stream = null;
|
||||
if (canSeekBackwards) {
|
||||
try {
|
||||
stream = new FileCacheSeekableStream(is);
|
||||
} catch (Exception e) {
|
||||
stream = new MemoryCacheSeekableStream(is);
|
||||
}
|
||||
} else {
|
||||
stream = new ForwardSeekableStream(is);
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
protected long markPos = -1L;
|
||||
|
||||
public abstract int read() throws IOException;
|
||||
|
||||
public abstract int read(byte[] paramArrayOfbyte, int paramInt1, int paramInt2) throws IOException;
|
||||
|
||||
public synchronized void mark(int readLimit) {
|
||||
try {
|
||||
this.markPos = getFilePointer();
|
||||
} catch (IOException e) {
|
||||
this.markPos = -1L;
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void reset() throws IOException {
|
||||
if (this.markPos != -1L)
|
||||
seek(this.markPos);
|
||||
}
|
||||
|
||||
public boolean markSupported() {
|
||||
return canSeekBackwards();
|
||||
}
|
||||
|
||||
public boolean canSeekBackwards() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public abstract long getFilePointer() throws IOException;
|
||||
|
||||
public abstract void seek(long paramLong) throws IOException;
|
||||
|
||||
public final void readFully(byte[] b) throws IOException {
|
||||
readFully(b, 0, b.length);
|
||||
}
|
||||
|
||||
public final void readFully(byte[] b, int off, int len) throws IOException {
|
||||
int n = 0;
|
||||
do {
|
||||
int count = read(b, off + n, len - n);
|
||||
if (count < 0)
|
||||
throw new EOFException();
|
||||
n += count;
|
||||
} while (n < len);
|
||||
}
|
||||
|
||||
public int skipBytes(int n) throws IOException {
|
||||
if (n <= 0)
|
||||
return 0;
|
||||
return (int)skip((long)n);
|
||||
}
|
||||
|
||||
public final boolean readBoolean() throws IOException {
|
||||
int ch = read();
|
||||
if (ch < 0)
|
||||
throw new EOFException();
|
||||
return (ch != 0);
|
||||
}
|
||||
|
||||
public final byte readByte() throws IOException {
|
||||
int ch = read();
|
||||
if (ch < 0)
|
||||
throw new EOFException();
|
||||
return (byte)ch;
|
||||
}
|
||||
|
||||
public final int readUnsignedByte() throws IOException {
|
||||
int ch = read();
|
||||
if (ch < 0)
|
||||
throw new EOFException();
|
||||
return ch;
|
||||
}
|
||||
|
||||
public final short readShort() throws IOException {
|
||||
int ch1 = read();
|
||||
int ch2 = read();
|
||||
if ((ch1 | ch2) < 0)
|
||||
throw new EOFException();
|
||||
return (short)((ch1 << 8) + (ch2 << 0));
|
||||
}
|
||||
|
||||
public final short readShortLE() throws IOException {
|
||||
int ch1 = read();
|
||||
int ch2 = read();
|
||||
if ((ch1 | ch2) < 0)
|
||||
throw new EOFException();
|
||||
return (short)((ch2 << 8) + (ch1 << 0));
|
||||
}
|
||||
|
||||
public final int readUnsignedShort() throws IOException {
|
||||
int ch1 = read();
|
||||
int ch2 = read();
|
||||
if ((ch1 | ch2) < 0)
|
||||
throw new EOFException();
|
||||
return (ch1 << 8) + (ch2 << 0);
|
||||
}
|
||||
|
||||
public final int readUnsignedShortLE() throws IOException {
|
||||
int ch1 = read();
|
||||
int ch2 = read();
|
||||
if ((ch1 | ch2) < 0)
|
||||
throw new EOFException();
|
||||
return (ch2 << 8) + (ch1 << 0);
|
||||
}
|
||||
|
||||
public final char readChar() throws IOException {
|
||||
int ch1 = read();
|
||||
int ch2 = read();
|
||||
if ((ch1 | ch2) < 0)
|
||||
throw new EOFException();
|
||||
return (char)((ch1 << 8) + (ch2 << 0));
|
||||
}
|
||||
|
||||
public final char readCharLE() throws IOException {
|
||||
int ch1 = read();
|
||||
int ch2 = read();
|
||||
if ((ch1 | ch2) < 0)
|
||||
throw new EOFException();
|
||||
return (char)((ch2 << 8) + (ch1 << 0));
|
||||
}
|
||||
|
||||
public final int readInt() throws IOException {
|
||||
int ch1 = read();
|
||||
int ch2 = read();
|
||||
int ch3 = read();
|
||||
int ch4 = read();
|
||||
if ((ch1 | ch2 | ch3 | ch4) < 0)
|
||||
throw new EOFException();
|
||||
return (ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0);
|
||||
}
|
||||
|
||||
public final int readIntLE() throws IOException {
|
||||
int ch1 = read();
|
||||
int ch2 = read();
|
||||
int ch3 = read();
|
||||
int ch4 = read();
|
||||
if ((ch1 | ch2 | ch3 | ch4) < 0)
|
||||
throw new EOFException();
|
||||
return (ch4 << 24) + (ch3 << 16) + (ch2 << 8) + (ch1 << 0);
|
||||
}
|
||||
|
||||
public final long readUnsignedInt() throws IOException {
|
||||
long ch1 = (long)read();
|
||||
long ch2 = (long)read();
|
||||
long ch3 = (long)read();
|
||||
long ch4 = (long)read();
|
||||
if ((ch1 | ch2 | ch3 | ch4) < 0L)
|
||||
throw new EOFException();
|
||||
return (ch1 << 24L) + (ch2 << 16L) + (ch3 << 8L) + (ch4 << 0L);
|
||||
}
|
||||
|
||||
private byte[] ruileBuf = new byte[4];
|
||||
|
||||
public final long readUnsignedIntLE() throws IOException {
|
||||
readFully(this.ruileBuf);
|
||||
long ch1 = (long)(this.ruileBuf[0] & 0xFF);
|
||||
long ch2 = (long)(this.ruileBuf[1] & 0xFF);
|
||||
long ch3 = (long)(this.ruileBuf[2] & 0xFF);
|
||||
long ch4 = (long)(this.ruileBuf[3] & 0xFF);
|
||||
return (ch4 << 24L) + (ch3 << 16L) + (ch2 << 8L) + (ch1 << 0L);
|
||||
}
|
||||
|
||||
public final long readLong() throws IOException {
|
||||
return ((long)readInt() << 32L) + ((long)readInt() & 0xFFFFFFFFL);
|
||||
}
|
||||
|
||||
public final long readLongLE() throws IOException {
|
||||
int i1 = readIntLE();
|
||||
int i2 = readIntLE();
|
||||
return ((long)i2 << 32L) + ((long)i1 & 0xFFFFFFFFL);
|
||||
}
|
||||
|
||||
public final float readFloat() throws IOException {
|
||||
return Float.intBitsToFloat(readInt());
|
||||
}
|
||||
|
||||
public final float readFloatLE() throws IOException {
|
||||
return Float.intBitsToFloat(readIntLE());
|
||||
}
|
||||
|
||||
public final double readDouble() throws IOException {
|
||||
return Double.longBitsToDouble(readLong());
|
||||
}
|
||||
|
||||
public final double readDoubleLE() throws IOException {
|
||||
return Double.longBitsToDouble(readLongLE());
|
||||
}
|
||||
|
||||
public final String readLine() throws IOException {
|
||||
StringBuffer input = new StringBuffer();
|
||||
int c = -1;
|
||||
boolean eol = false;
|
||||
while (!eol) {
|
||||
long cur;
|
||||
switch (c = read()) {
|
||||
case -1:
|
||||
case 10:
|
||||
eol = true;
|
||||
continue;
|
||||
case 13:
|
||||
eol = true;
|
||||
cur = getFilePointer();
|
||||
if (read() != 10)
|
||||
seek(cur);
|
||||
continue;
|
||||
}
|
||||
input.append((char)c);
|
||||
}
|
||||
if (c == -1 && input.length() == 0)
|
||||
return null;
|
||||
return input.toString();
|
||||
}
|
||||
|
||||
public final String readUTF() throws IOException {
|
||||
return DataInputStream.readUTF(this);
|
||||
}
|
||||
|
||||
protected void finalize() throws Throwable {
|
||||
super.finalize();
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
package com.sun.media.jai.codec;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class SegmentedSeekableStream extends SeekableStream {
|
||||
private SeekableStream stream;
|
||||
|
||||
private StreamSegmentMapper mapper;
|
||||
|
||||
private long pointer = 0L;
|
||||
|
||||
private boolean canSeekBackwards;
|
||||
|
||||
public SegmentedSeekableStream(SeekableStream stream, StreamSegmentMapper mapper, boolean canSeekBackwards) {
|
||||
this.stream = stream;
|
||||
this.mapper = mapper;
|
||||
this.canSeekBackwards = canSeekBackwards;
|
||||
if (canSeekBackwards && !stream.canSeekBackwards())
|
||||
throw new IllegalArgumentException(JaiI18N.getString("SegmentedSeekableStream0"));
|
||||
}
|
||||
|
||||
public SegmentedSeekableStream(SeekableStream stream, long[] segmentPositions, int[] segmentLengths, boolean canSeekBackwards) {
|
||||
this(stream, new StreamSegmentMapperImpl(segmentPositions, segmentLengths), canSeekBackwards);
|
||||
}
|
||||
|
||||
public SegmentedSeekableStream(SeekableStream stream, long[] segmentPositions, int segmentLength, int totalLength, boolean canSeekBackwards) {
|
||||
this(stream, new SectorStreamSegmentMapper(segmentPositions, segmentLength, totalLength), canSeekBackwards);
|
||||
}
|
||||
|
||||
public long getFilePointer() {
|
||||
return this.pointer;
|
||||
}
|
||||
|
||||
public boolean canSeekBackwards() {
|
||||
return this.canSeekBackwards;
|
||||
}
|
||||
|
||||
public void seek(long pos) throws IOException {
|
||||
if (pos < 0L)
|
||||
throw new IOException();
|
||||
this.pointer = pos;
|
||||
}
|
||||
|
||||
private StreamSegment streamSegment = new StreamSegment();
|
||||
|
||||
public int read() throws IOException {
|
||||
this.mapper.getStreamSegment(this.pointer, 1, this.streamSegment);
|
||||
this.stream.seek(this.streamSegment.getStartPos());
|
||||
int val = this.stream.read();
|
||||
this.pointer++;
|
||||
return val;
|
||||
}
|
||||
|
||||
public int read(byte[] b, int off, int len) throws IOException {
|
||||
if (b == null)
|
||||
throw new NullPointerException();
|
||||
if (off < 0 || len < 0 || off + len > b.length)
|
||||
throw new IndexOutOfBoundsException();
|
||||
if (len == 0)
|
||||
return 0;
|
||||
this.mapper.getStreamSegment(this.pointer, len, this.streamSegment);
|
||||
this.stream.seek(this.streamSegment.getStartPos());
|
||||
int nbytes = this.stream.read(b, off, this.streamSegment.getSegmentLength());
|
||||
this.pointer += (long)nbytes;
|
||||
return nbytes;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
package com.sun.media.jai.codec;
|
||||
|
||||
public class StreamSegment {
|
||||
private long startPos = 0L;
|
||||
|
||||
private int segmentLength = 0;
|
||||
|
||||
public StreamSegment() {}
|
||||
|
||||
public StreamSegment(long startPos, int segmentLength) {
|
||||
this.startPos = startPos;
|
||||
this.segmentLength = segmentLength;
|
||||
}
|
||||
|
||||
public final long getStartPos() {
|
||||
return this.startPos;
|
||||
}
|
||||
|
||||
public final void setStartPos(long startPos) {
|
||||
this.startPos = startPos;
|
||||
}
|
||||
|
||||
public final int getSegmentLength() {
|
||||
return this.segmentLength;
|
||||
}
|
||||
|
||||
public final void setSegmentLength(int segmentLength) {
|
||||
this.segmentLength = segmentLength;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
package com.sun.media.jai.codec;
|
||||
|
||||
public interface StreamSegmentMapper {
|
||||
StreamSegment getStreamSegment(long paramLong, int paramInt);
|
||||
|
||||
void getStreamSegment(long paramLong, int paramInt, StreamSegment paramStreamSegment);
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
package com.sun.media.jai.codec;
|
||||
|
||||
class StreamSegmentMapperImpl implements StreamSegmentMapper {
|
||||
private long[] segmentPositions;
|
||||
|
||||
private int[] segmentLengths;
|
||||
|
||||
public StreamSegmentMapperImpl(long[] segmentPositions, int[] segmentLengths) {
|
||||
this.segmentPositions = (long[])segmentPositions.clone();
|
||||
this.segmentLengths = (int[])segmentLengths.clone();
|
||||
}
|
||||
|
||||
public StreamSegment getStreamSegment(long position, int length) {
|
||||
int numSegments = this.segmentLengths.length;
|
||||
for (int i = 0; i < numSegments; i++) {
|
||||
int len = this.segmentLengths[i];
|
||||
if (position < (long)len)
|
||||
return new StreamSegment(this.segmentPositions[i] + position, Math.min(len - (int)position, length));
|
||||
position -= (long)len;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void getStreamSegment(long position, int length, StreamSegment seg) {
|
||||
int numSegments = this.segmentLengths.length;
|
||||
for (int i = 0; i < numSegments; i++) {
|
||||
int len = this.segmentLengths[i];
|
||||
if (position < (long)len) {
|
||||
seg.setStartPos(this.segmentPositions[i] + position);
|
||||
seg.setSegmentLength(Math.min(len - (int)position, length));
|
||||
return;
|
||||
}
|
||||
position -= (long)len;
|
||||
}
|
||||
seg.setStartPos(-1L);
|
||||
seg.setSegmentLength(-1);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
package com.sun.media.jai.codec;
|
||||
|
||||
public class TIFFDecodeParam implements ImageDecodeParam {
|
||||
private boolean decodePaletteAsShorts = false;
|
||||
|
||||
private Long ifdOffset = null;
|
||||
|
||||
private boolean convertJPEGYCbCrToRGB = true;
|
||||
|
||||
public void setDecodePaletteAsShorts(boolean decodePaletteAsShorts) {
|
||||
this.decodePaletteAsShorts = decodePaletteAsShorts;
|
||||
}
|
||||
|
||||
public boolean getDecodePaletteAsShorts() {
|
||||
return this.decodePaletteAsShorts;
|
||||
}
|
||||
|
||||
public byte decode16BitsTo8Bits(int s) {
|
||||
return (byte)(s >> 8 & 0xFFFF);
|
||||
}
|
||||
|
||||
public byte decodeSigned16BitsTo8Bits(short s) {
|
||||
return (byte)(s + -32768 >> 8);
|
||||
}
|
||||
|
||||
public void setIFDOffset(long offset) {
|
||||
this.ifdOffset = new Long(offset);
|
||||
}
|
||||
|
||||
public Long getIFDOffset() {
|
||||
return this.ifdOffset;
|
||||
}
|
||||
|
||||
public void setJPEGDecompressYCbCrToRGB(boolean convertJPEGYCbCrToRGB) {
|
||||
this.convertJPEGYCbCrToRGB = convertJPEGYCbCrToRGB;
|
||||
}
|
||||
|
||||
public boolean getJPEGDecompressYCbCrToRGB() {
|
||||
return this.convertJPEGYCbCrToRGB;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,357 @@
|
|||
package com.sun.media.jai.codec;
|
||||
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Vector;
|
||||
|
||||
public class TIFFDirectory implements Serializable {
|
||||
boolean isBigEndian;
|
||||
|
||||
int numEntries;
|
||||
|
||||
TIFFField[] fields;
|
||||
|
||||
Hashtable fieldIndex = new Hashtable();
|
||||
|
||||
long IFDOffset = 8L;
|
||||
|
||||
long nextIFDOffset = 0L;
|
||||
|
||||
TIFFDirectory() {}
|
||||
|
||||
private static boolean isValidEndianTag(int endian) {
|
||||
return (endian == 18761 || endian == 19789);
|
||||
}
|
||||
|
||||
public TIFFDirectory(SeekableStream stream, int directory) throws IOException {
|
||||
long global_save_offset = stream.getFilePointer();
|
||||
stream.seek(0L);
|
||||
int endian = stream.readUnsignedShort();
|
||||
if (!isValidEndianTag(endian))
|
||||
throw new IllegalArgumentException(JaiI18N.getString("TIFFDirectory1"));
|
||||
this.isBigEndian = (endian == 19789);
|
||||
int magic = readUnsignedShort(stream);
|
||||
if (magic != 42)
|
||||
throw new IllegalArgumentException(JaiI18N.getString("TIFFDirectory2"));
|
||||
long ifd_offset = readUnsignedInt(stream);
|
||||
for (int i = 0; i < directory; i++) {
|
||||
if (ifd_offset == 0L)
|
||||
throw new IllegalArgumentException(JaiI18N.getString("TIFFDirectory3"));
|
||||
stream.seek(ifd_offset);
|
||||
int entries = readUnsignedShort(stream);
|
||||
stream.skip((long)(12 * entries));
|
||||
ifd_offset = readUnsignedInt(stream);
|
||||
}
|
||||
stream.seek(ifd_offset);
|
||||
initialize(stream);
|
||||
stream.seek(global_save_offset);
|
||||
}
|
||||
|
||||
public TIFFDirectory(SeekableStream stream, long ifd_offset, int directory) throws IOException {
|
||||
long global_save_offset = stream.getFilePointer();
|
||||
stream.seek(0L);
|
||||
int endian = stream.readUnsignedShort();
|
||||
if (!isValidEndianTag(endian))
|
||||
throw new IllegalArgumentException(JaiI18N.getString("TIFFDirectory1"));
|
||||
this.isBigEndian = (endian == 19789);
|
||||
stream.seek(ifd_offset);
|
||||
int dirNum = 0;
|
||||
while (dirNum < directory) {
|
||||
int numEntries = readUnsignedShort(stream);
|
||||
stream.seek(ifd_offset + (long)(12 * numEntries));
|
||||
ifd_offset = readUnsignedInt(stream);
|
||||
stream.seek(ifd_offset);
|
||||
dirNum++;
|
||||
}
|
||||
initialize(stream);
|
||||
stream.seek(global_save_offset);
|
||||
}
|
||||
|
||||
private static final int[] sizeOfType = new int[] {
|
||||
0, 1, 1, 2, 4, 8, 1, 1, 2, 4,
|
||||
8, 4, 8 };
|
||||
|
||||
private void initialize(SeekableStream stream) throws IOException {
|
||||
this.IFDOffset = stream.getFilePointer();
|
||||
this.numEntries = readUnsignedShort(stream);
|
||||
this.fields = new TIFFField[this.numEntries];
|
||||
for (int i = 0; i < this.numEntries; i++) {
|
||||
int tag = readUnsignedShort(stream);
|
||||
int type = readUnsignedShort(stream);
|
||||
int count = (int)readUnsignedInt(stream);
|
||||
int value = 0;
|
||||
long nextTagOffset = stream.getFilePointer() + 4L;
|
||||
try {
|
||||
if (count * sizeOfType[type] > 4) {
|
||||
value = (int)readUnsignedInt(stream);
|
||||
stream.seek((long)value);
|
||||
}
|
||||
} catch (ArrayIndexOutOfBoundsException ae) {
|
||||
System.err.println(tag + " " + JaiI18N.getString("TIFFDirectory4"));
|
||||
stream.seek(nextTagOffset);
|
||||
}
|
||||
this.fieldIndex.put(new Integer(tag), new Integer(i));
|
||||
Object obj = null;
|
||||
try {
|
||||
int j;
|
||||
byte[] bvalues;
|
||||
char[] cvalues;
|
||||
long lvalues[], llvalues[][];
|
||||
short[] svalues;
|
||||
int ivalues[], iivalues[][];
|
||||
float[] fvalues;
|
||||
double[] dvalues;
|
||||
switch (type) {
|
||||
case 1:
|
||||
case 2:
|
||||
case 6:
|
||||
case 7:
|
||||
bvalues = new byte[count];
|
||||
stream.readFully(bvalues, 0, count);
|
||||
if (type == 2) {
|
||||
int index = 0, prevIndex = 0;
|
||||
Vector v = new Vector();
|
||||
while (index < count) {
|
||||
while (index < count && bvalues[index++] != 0);
|
||||
v.add(new String(bvalues, prevIndex, index - prevIndex));
|
||||
prevIndex = index;
|
||||
}
|
||||
count = v.size();
|
||||
String[] strings = new String[count];
|
||||
for (int c = 0; c < count; c++)
|
||||
strings[c] = (String)v.elementAt(c);
|
||||
obj = strings;
|
||||
} else {
|
||||
obj = bvalues;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
cvalues = new char[count];
|
||||
for (j = 0; j < count; j++)
|
||||
cvalues[j] = (char)readUnsignedShort(stream);
|
||||
obj = cvalues;
|
||||
break;
|
||||
case 4:
|
||||
lvalues = new long[count];
|
||||
for (j = 0; j < count; j++)
|
||||
lvalues[j] = readUnsignedInt(stream);
|
||||
obj = lvalues;
|
||||
break;
|
||||
case 5:
|
||||
llvalues = new long[count][2];
|
||||
for (j = 0; j < count; j++) {
|
||||
llvalues[j][0] = readUnsignedInt(stream);
|
||||
llvalues[j][1] = readUnsignedInt(stream);
|
||||
}
|
||||
obj = llvalues;
|
||||
break;
|
||||
case 8:
|
||||
svalues = new short[count];
|
||||
for (j = 0; j < count; j++)
|
||||
svalues[j] = readShort(stream);
|
||||
obj = svalues;
|
||||
break;
|
||||
case 9:
|
||||
ivalues = new int[count];
|
||||
for (j = 0; j < count; j++)
|
||||
ivalues[j] = readInt(stream);
|
||||
obj = ivalues;
|
||||
break;
|
||||
case 10:
|
||||
iivalues = new int[count][2];
|
||||
for (j = 0; j < count; j++) {
|
||||
iivalues[j][0] = readInt(stream);
|
||||
iivalues[j][1] = readInt(stream);
|
||||
}
|
||||
obj = iivalues;
|
||||
break;
|
||||
case 11:
|
||||
fvalues = new float[count];
|
||||
for (j = 0; j < count; j++)
|
||||
fvalues[j] = readFloat(stream);
|
||||
obj = fvalues;
|
||||
break;
|
||||
case 12:
|
||||
dvalues = new double[count];
|
||||
for (j = 0; j < count; j++)
|
||||
dvalues[j] = readDouble(stream);
|
||||
obj = dvalues;
|
||||
break;
|
||||
default:
|
||||
System.err.println(JaiI18N.getString("TIFFDirectory0"));
|
||||
break;
|
||||
}
|
||||
this.fields[i] = new TIFFField(tag, type, count, obj);
|
||||
} catch (EOFException eofe) {
|
||||
if (tag <= 532 || tag == 33432)
|
||||
throw eofe;
|
||||
this.fieldIndex.remove(new Integer(tag));
|
||||
}
|
||||
stream.seek(nextTagOffset);
|
||||
}
|
||||
this.nextIFDOffset = readUnsignedInt(stream);
|
||||
}
|
||||
|
||||
public int getNumEntries() {
|
||||
return this.numEntries;
|
||||
}
|
||||
|
||||
public TIFFField getField(int tag) {
|
||||
Integer i = (Integer)this.fieldIndex.get(new Integer(tag));
|
||||
if (i == null)
|
||||
return null;
|
||||
return this.fields[i.intValue()];
|
||||
}
|
||||
|
||||
public boolean isTagPresent(int tag) {
|
||||
return this.fieldIndex.containsKey(new Integer(tag));
|
||||
}
|
||||
|
||||
public int[] getTags() {
|
||||
int[] tags = new int[this.fieldIndex.size()];
|
||||
Enumeration enumeration = this.fieldIndex.keys();
|
||||
int i = 0;
|
||||
while (enumeration.hasMoreElements())
|
||||
tags[i++] = ((Integer)enumeration.nextElement()).intValue();
|
||||
return tags;
|
||||
}
|
||||
|
||||
public TIFFField[] getFields() {
|
||||
return this.fields;
|
||||
}
|
||||
|
||||
public byte getFieldAsByte(int tag, int index) {
|
||||
Integer i = (Integer)this.fieldIndex.get(new Integer(tag));
|
||||
byte[] b = this.fields[i.intValue()].getAsBytes();
|
||||
return b[index];
|
||||
}
|
||||
|
||||
public byte getFieldAsByte(int tag) {
|
||||
return getFieldAsByte(tag, 0);
|
||||
}
|
||||
|
||||
public long getFieldAsLong(int tag, int index) {
|
||||
Integer i = (Integer)this.fieldIndex.get(new Integer(tag));
|
||||
return this.fields[i.intValue()].getAsLong(index);
|
||||
}
|
||||
|
||||
public long getFieldAsLong(int tag) {
|
||||
return getFieldAsLong(tag, 0);
|
||||
}
|
||||
|
||||
public float getFieldAsFloat(int tag, int index) {
|
||||
Integer i = (Integer)this.fieldIndex.get(new Integer(tag));
|
||||
return this.fields[i.intValue()].getAsFloat(index);
|
||||
}
|
||||
|
||||
public float getFieldAsFloat(int tag) {
|
||||
return getFieldAsFloat(tag, 0);
|
||||
}
|
||||
|
||||
public double getFieldAsDouble(int tag, int index) {
|
||||
Integer i = (Integer)this.fieldIndex.get(new Integer(tag));
|
||||
return this.fields[i.intValue()].getAsDouble(index);
|
||||
}
|
||||
|
||||
public double getFieldAsDouble(int tag) {
|
||||
return getFieldAsDouble(tag, 0);
|
||||
}
|
||||
|
||||
private short readShort(SeekableStream stream) throws IOException {
|
||||
if (this.isBigEndian)
|
||||
return stream.readShort();
|
||||
return stream.readShortLE();
|
||||
}
|
||||
|
||||
private int readUnsignedShort(SeekableStream stream) throws IOException {
|
||||
if (this.isBigEndian)
|
||||
return stream.readUnsignedShort();
|
||||
return stream.readUnsignedShortLE();
|
||||
}
|
||||
|
||||
private int readInt(SeekableStream stream) throws IOException {
|
||||
if (this.isBigEndian)
|
||||
return stream.readInt();
|
||||
return stream.readIntLE();
|
||||
}
|
||||
|
||||
private long readUnsignedInt(SeekableStream stream) throws IOException {
|
||||
if (this.isBigEndian)
|
||||
return stream.readUnsignedInt();
|
||||
return stream.readUnsignedIntLE();
|
||||
}
|
||||
|
||||
private long readLong(SeekableStream stream) throws IOException {
|
||||
if (this.isBigEndian)
|
||||
return stream.readLong();
|
||||
return stream.readLongLE();
|
||||
}
|
||||
|
||||
private float readFloat(SeekableStream stream) throws IOException {
|
||||
if (this.isBigEndian)
|
||||
return stream.readFloat();
|
||||
return stream.readFloatLE();
|
||||
}
|
||||
|
||||
private double readDouble(SeekableStream stream) throws IOException {
|
||||
if (this.isBigEndian)
|
||||
return stream.readDouble();
|
||||
return stream.readDoubleLE();
|
||||
}
|
||||
|
||||
private static int readUnsignedShort(SeekableStream stream, boolean isBigEndian) throws IOException {
|
||||
if (isBigEndian)
|
||||
return stream.readUnsignedShort();
|
||||
return stream.readUnsignedShortLE();
|
||||
}
|
||||
|
||||
private static long readUnsignedInt(SeekableStream stream, boolean isBigEndian) throws IOException {
|
||||
if (isBigEndian)
|
||||
return stream.readUnsignedInt();
|
||||
return stream.readUnsignedIntLE();
|
||||
}
|
||||
|
||||
public static int getNumDirectories(SeekableStream stream) throws IOException {
|
||||
long pointer = stream.getFilePointer();
|
||||
stream.seek(0L);
|
||||
int endian = stream.readUnsignedShort();
|
||||
if (!isValidEndianTag(endian))
|
||||
throw new IllegalArgumentException(JaiI18N.getString("TIFFDirectory1"));
|
||||
boolean isBigEndian = (endian == 19789);
|
||||
int magic = readUnsignedShort(stream, isBigEndian);
|
||||
if (magic != 42)
|
||||
throw new IllegalArgumentException(JaiI18N.getString("TIFFDirectory2"));
|
||||
stream.seek(4L);
|
||||
long offset = readUnsignedInt(stream, isBigEndian);
|
||||
int numDirectories = 0;
|
||||
while (offset != 0L) {
|
||||
numDirectories++;
|
||||
try {
|
||||
stream.seek(offset);
|
||||
int entries = readUnsignedShort(stream, isBigEndian);
|
||||
stream.skip((long)(12 * entries));
|
||||
offset = readUnsignedInt(stream, isBigEndian);
|
||||
} catch (EOFException eof) {
|
||||
numDirectories--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
stream.seek(pointer);
|
||||
return numDirectories;
|
||||
}
|
||||
|
||||
public boolean isBigEndian() {
|
||||
return this.isBigEndian;
|
||||
}
|
||||
|
||||
public long getIFDOffset() {
|
||||
return this.IFDOffset;
|
||||
}
|
||||
|
||||
public long getNextIFDOffset() {
|
||||
return this.nextIFDOffset;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,173 @@
|
|||
package com.sun.media.jai.codec;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
public class TIFFEncodeParam implements ImageEncodeParam {
|
||||
public static final int COMPRESSION_NONE = 1;
|
||||
|
||||
public static final int COMPRESSION_PACKBITS = 32773;
|
||||
|
||||
public static final int COMPRESSION_GROUP3_1D = 2;
|
||||
|
||||
public static final int COMPRESSION_GROUP3_2D = 3;
|
||||
|
||||
public static final int COMPRESSION_GROUP4 = 4;
|
||||
|
||||
public static final int COMPRESSION_LZW = 5;
|
||||
|
||||
public static final int COMPRESSION_JPEG_TTN2 = 7;
|
||||
|
||||
public static final int COMPRESSION_DEFLATE = 32946;
|
||||
|
||||
private int compression = 1;
|
||||
|
||||
private boolean reverseFillOrder = false;
|
||||
|
||||
private boolean T4Encode2D = true;
|
||||
|
||||
private boolean T4PadEOLs = false;
|
||||
|
||||
private boolean writeTiled = false;
|
||||
|
||||
private int tileWidth;
|
||||
|
||||
private int tileHeight;
|
||||
|
||||
private Iterator extraImages;
|
||||
|
||||
private TIFFField[] extraFields;
|
||||
|
||||
private boolean convertJPEGRGBToYCbCr = true;
|
||||
|
||||
private JPEGEncodeParam jpegEncodeParam = null;
|
||||
|
||||
private int deflateLevel = -1;
|
||||
|
||||
private boolean isLittleEndian = false;
|
||||
|
||||
public int getCompression() {
|
||||
return this.compression;
|
||||
}
|
||||
|
||||
public void setCompression(int compression) {
|
||||
switch (compression) {
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
case 7:
|
||||
case 32773:
|
||||
case 32946:
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException(JaiI18N.getString("TIFFEncodeParam0"));
|
||||
}
|
||||
this.compression = compression;
|
||||
}
|
||||
|
||||
public boolean getReverseFillOrder() {
|
||||
return this.reverseFillOrder;
|
||||
}
|
||||
|
||||
public void setReverseFillOrder(boolean reverseFillOrder) {
|
||||
this.reverseFillOrder = reverseFillOrder;
|
||||
}
|
||||
|
||||
public boolean getT4Encode2D() {
|
||||
return this.T4Encode2D;
|
||||
}
|
||||
|
||||
public void setT4Encode2D(boolean T4Encode2D) {
|
||||
this.T4Encode2D = T4Encode2D;
|
||||
}
|
||||
|
||||
public boolean getT4PadEOLs() {
|
||||
return this.T4PadEOLs;
|
||||
}
|
||||
|
||||
public void setT4PadEOLs(boolean T4PadEOLs) {
|
||||
this.T4PadEOLs = T4PadEOLs;
|
||||
}
|
||||
|
||||
public boolean getWriteTiled() {
|
||||
return this.writeTiled;
|
||||
}
|
||||
|
||||
public void setWriteTiled(boolean writeTiled) {
|
||||
this.writeTiled = writeTiled;
|
||||
}
|
||||
|
||||
public void setTileSize(int tileWidth, int tileHeight) {
|
||||
this.tileWidth = tileWidth;
|
||||
this.tileHeight = tileHeight;
|
||||
}
|
||||
|
||||
public int getTileWidth() {
|
||||
return this.tileWidth;
|
||||
}
|
||||
|
||||
public int getTileHeight() {
|
||||
return this.tileHeight;
|
||||
}
|
||||
|
||||
public synchronized void setExtraImages(Iterator extraImages) {
|
||||
this.extraImages = extraImages;
|
||||
}
|
||||
|
||||
public synchronized Iterator getExtraImages() {
|
||||
return this.extraImages;
|
||||
}
|
||||
|
||||
public void setDeflateLevel(int deflateLevel) {
|
||||
if (deflateLevel < 1 && deflateLevel > 9 && deflateLevel != -1)
|
||||
throw new IllegalArgumentException(JaiI18N.getString("TIFFEncodeParam1"));
|
||||
this.deflateLevel = deflateLevel;
|
||||
}
|
||||
|
||||
public int getDeflateLevel() {
|
||||
return this.deflateLevel;
|
||||
}
|
||||
|
||||
public void setJPEGCompressRGBToYCbCr(boolean convertJPEGRGBToYCbCr) {
|
||||
this.convertJPEGRGBToYCbCr = convertJPEGRGBToYCbCr;
|
||||
}
|
||||
|
||||
public boolean getJPEGCompressRGBToYCbCr() {
|
||||
return this.convertJPEGRGBToYCbCr;
|
||||
}
|
||||
|
||||
public void setJPEGEncodeParam(JPEGEncodeParam jpegEncodeParam) {
|
||||
if (jpegEncodeParam != null) {
|
||||
jpegEncodeParam = (JPEGEncodeParam)jpegEncodeParam.clone();
|
||||
jpegEncodeParam.setWriteTablesOnly(false);
|
||||
jpegEncodeParam.setWriteJFIFHeader(false);
|
||||
}
|
||||
this.jpegEncodeParam = jpegEncodeParam;
|
||||
}
|
||||
|
||||
public JPEGEncodeParam getJPEGEncodeParam() {
|
||||
if (this.jpegEncodeParam == null) {
|
||||
this.jpegEncodeParam = new JPEGEncodeParam();
|
||||
this.jpegEncodeParam.setWriteTablesOnly(false);
|
||||
this.jpegEncodeParam.setWriteImageOnly(true);
|
||||
this.jpegEncodeParam.setWriteJFIFHeader(false);
|
||||
}
|
||||
return this.jpegEncodeParam;
|
||||
}
|
||||
|
||||
public void setExtraFields(TIFFField[] extraFields) {
|
||||
this.extraFields = extraFields;
|
||||
}
|
||||
|
||||
public TIFFField[] getExtraFields() {
|
||||
return this.extraFields;
|
||||
}
|
||||
|
||||
public void setLittleEndian(boolean isLittleEndian) {
|
||||
this.isLittleEndian = isLittleEndian;
|
||||
}
|
||||
|
||||
public boolean getLittleEndian() {
|
||||
return this.isLittleEndian;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,213 @@
|
|||
package com.sun.media.jai.codec;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class TIFFField implements Comparable, Serializable {
|
||||
public static final int TIFF_BYTE = 1;
|
||||
|
||||
public static final int TIFF_ASCII = 2;
|
||||
|
||||
public static final int TIFF_SHORT = 3;
|
||||
|
||||
public static final int TIFF_LONG = 4;
|
||||
|
||||
public static final int TIFF_RATIONAL = 5;
|
||||
|
||||
public static final int TIFF_SBYTE = 6;
|
||||
|
||||
public static final int TIFF_UNDEFINED = 7;
|
||||
|
||||
public static final int TIFF_SSHORT = 8;
|
||||
|
||||
public static final int TIFF_SLONG = 9;
|
||||
|
||||
public static final int TIFF_SRATIONAL = 10;
|
||||
|
||||
public static final int TIFF_FLOAT = 11;
|
||||
|
||||
public static final int TIFF_DOUBLE = 12;
|
||||
|
||||
int tag;
|
||||
|
||||
int type;
|
||||
|
||||
int count;
|
||||
|
||||
Object data;
|
||||
|
||||
TIFFField() {}
|
||||
|
||||
public TIFFField(int tag, int type, int count, Object data) {
|
||||
this.tag = tag;
|
||||
this.type = type;
|
||||
this.count = count;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public int getTag() {
|
||||
return this.tag;
|
||||
}
|
||||
|
||||
public int getType() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
public int getCount() {
|
||||
return this.count;
|
||||
}
|
||||
|
||||
public byte[] getAsBytes() {
|
||||
return (byte[])this.data;
|
||||
}
|
||||
|
||||
public char[] getAsChars() {
|
||||
return (char[])this.data;
|
||||
}
|
||||
|
||||
public short[] getAsShorts() {
|
||||
return (short[])this.data;
|
||||
}
|
||||
|
||||
public int[] getAsInts() {
|
||||
return (int[])this.data;
|
||||
}
|
||||
|
||||
public long[] getAsLongs() {
|
||||
return (long[])this.data;
|
||||
}
|
||||
|
||||
public float[] getAsFloats() {
|
||||
return (float[])this.data;
|
||||
}
|
||||
|
||||
public double[] getAsDoubles() {
|
||||
return (double[])this.data;
|
||||
}
|
||||
|
||||
public int[][] getAsSRationals() {
|
||||
return (int[][])this.data;
|
||||
}
|
||||
|
||||
public long[][] getAsRationals() {
|
||||
return (long[][])this.data;
|
||||
}
|
||||
|
||||
public int getAsInt(int index) {
|
||||
switch (this.type) {
|
||||
case 1:
|
||||
case 7:
|
||||
return ((byte[])this.data)[index] & 0xFF;
|
||||
case 6:
|
||||
return ((byte[])this.data)[index];
|
||||
case 3:
|
||||
return ((char[])this.data)[index] & Character.MAX_VALUE;
|
||||
case 8:
|
||||
return ((short[])this.data)[index];
|
||||
case 9:
|
||||
return ((int[])this.data)[index];
|
||||
}
|
||||
throw new ClassCastException();
|
||||
}
|
||||
|
||||
public long getAsLong(int index) {
|
||||
switch (this.type) {
|
||||
case 1:
|
||||
case 7:
|
||||
return (long)(((byte[])this.data)[index] & 0xFF);
|
||||
case 6:
|
||||
return (long)((byte[])this.data)[index];
|
||||
case 3:
|
||||
return (long)(((char[])this.data)[index] & Character.MAX_VALUE);
|
||||
case 8:
|
||||
return (long)((short[])this.data)[index];
|
||||
case 9:
|
||||
return (long)((int[])this.data)[index];
|
||||
case 4:
|
||||
return ((long[])this.data)[index];
|
||||
}
|
||||
throw new ClassCastException();
|
||||
}
|
||||
|
||||
public float getAsFloat(int index) {
|
||||
int[] ivalue;
|
||||
long[] lvalue;
|
||||
switch (this.type) {
|
||||
case 1:
|
||||
return (float)(((byte[])this.data)[index] & 0xFF);
|
||||
case 6:
|
||||
return (float)((byte[])this.data)[index];
|
||||
case 3:
|
||||
return (float)(((char[])this.data)[index] & Character.MAX_VALUE);
|
||||
case 8:
|
||||
return (float)((short[])this.data)[index];
|
||||
case 9:
|
||||
return (float)((int[])this.data)[index];
|
||||
case 4:
|
||||
return (float)((long[])this.data)[index];
|
||||
case 11:
|
||||
return ((float[])this.data)[index];
|
||||
case 12:
|
||||
return (float)((double[])this.data)[index];
|
||||
case 10:
|
||||
ivalue = getAsSRational(index);
|
||||
return (float)((double)ivalue[0] / (double)ivalue[1]);
|
||||
case 5:
|
||||
lvalue = getAsRational(index);
|
||||
return (float)((double)lvalue[0] / (double)lvalue[1]);
|
||||
}
|
||||
throw new ClassCastException();
|
||||
}
|
||||
|
||||
public double getAsDouble(int index) {
|
||||
int[] ivalue;
|
||||
long[] lvalue;
|
||||
switch (this.type) {
|
||||
case 1:
|
||||
return (double)(((byte[])this.data)[index] & 0xFF);
|
||||
case 6:
|
||||
return (double)((byte[])this.data)[index];
|
||||
case 3:
|
||||
return (double)(((char[])this.data)[index] & Character.MAX_VALUE);
|
||||
case 8:
|
||||
return (double)((short[])this.data)[index];
|
||||
case 9:
|
||||
return (double)((int[])this.data)[index];
|
||||
case 4:
|
||||
return (double)((long[])this.data)[index];
|
||||
case 11:
|
||||
return (double)((float[])this.data)[index];
|
||||
case 12:
|
||||
return ((double[])this.data)[index];
|
||||
case 10:
|
||||
ivalue = getAsSRational(index);
|
||||
return (double)ivalue[0] / (double)ivalue[1];
|
||||
case 5:
|
||||
lvalue = getAsRational(index);
|
||||
return (double)lvalue[0] / (double)lvalue[1];
|
||||
}
|
||||
throw new ClassCastException();
|
||||
}
|
||||
|
||||
public String getAsString(int index) {
|
||||
return ((String[])this.data)[index];
|
||||
}
|
||||
|
||||
public int[] getAsSRational(int index) {
|
||||
return ((int[][])this.data)[index];
|
||||
}
|
||||
|
||||
public long[] getAsRational(int index) {
|
||||
return ((long[][])this.data)[index];
|
||||
}
|
||||
|
||||
public int compareTo(Object o) {
|
||||
if (o == null)
|
||||
throw new IllegalArgumentException();
|
||||
int oTag = ((TIFFField)o).getTag();
|
||||
if (this.tag < oTag)
|
||||
return -1;
|
||||
if (this.tag > oTag)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
package com.sun.media.jai.codec;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
|
||||
class TempFileCleanupThread extends Thread {
|
||||
private HashSet tempFiles = null;
|
||||
|
||||
TempFileCleanupThread() {
|
||||
setPriority(1);
|
||||
}
|
||||
|
||||
public void run() {
|
||||
if (this.tempFiles != null && this.tempFiles.size() > 0) {
|
||||
Iterator fileIter = this.tempFiles.iterator();
|
||||
while (fileIter.hasNext()) {
|
||||
try {
|
||||
File file = (File)fileIter.next();
|
||||
file.delete();
|
||||
} catch (Exception e) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
synchronized void addFile(File file) {
|
||||
if (this.tempFiles == null)
|
||||
this.tempFiles = new HashSet();
|
||||
this.tempFiles.add(file);
|
||||
}
|
||||
|
||||
synchronized void removeFile(File file) {
|
||||
this.tempFiles.remove(file);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
2006-09-11 17:23:56.159-0700
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
#
|
||||
# $RCSfile: com.sun.media.jai.codec.properties,v $
|
||||
#
|
||||
# Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
|
||||
#
|
||||
# Use is subject to license terms.
|
||||
#
|
||||
# $Revision: 1.1 $
|
||||
# $Date: 2005/02/11 04:55:34 $
|
||||
# $State: Exp $
|
||||
#
|
||||
BMPEncodeParam0=Unsupported version number specified for BMP file.
|
||||
FileSeekableStream0=pos < 0.
|
||||
FileCacheSeekableStream0=pos < 0.
|
||||
ImageCodec0=Method unimplemented, should be implemented by subclass.
|
||||
ImageCodec1=Method unimplemented, should be implemented by subclass.
|
||||
ImageCodec2=src must support seeking backwards or marking.
|
||||
ImageCodec3=IOException occurs when search for propriate codecs.
|
||||
JPEGEncodeParam0=A quantization table has not been set for this component.
|
||||
MemoryCacheSeekableStream0=pos < 0.
|
||||
PNGDecodeParam0=User exponent must not be negative.
|
||||
PNGDecodeParam1=Display exponent must not be negative.
|
||||
PNGEncodeParam0=Bad palette length.
|
||||
PNGEncodeParam1=Not divisible by 3.
|
||||
PNGEncodeParam2=Bit depth not equal to 1, 2, 4, or 8.
|
||||
PNGEncodeParam3=RGB palette has not been set.
|
||||
PNGEncodeParam4=background palette index has not been set.
|
||||
PNGEncodeParam5=Palette transparency has not been set.
|
||||
PNGEncodeParam6=Background gray level has not been set.
|
||||
PNGEncodeParam7=Transparent gray value has not been set.
|
||||
PNGEncodeParam8=Bit shift has not been set.
|
||||
PNGEncodeParam9=RGB background color has not been set.
|
||||
PNGEncodeParam10=Transparent RGB value has not been set.
|
||||
PNGEncodeParam11=Grayscale bit depth has not been set.
|
||||
PNGEncodeParam12=Chromaticity has not been set.
|
||||
PNGEncodeParam13=Gamma has not been set.
|
||||
PNGEncodeParam14=Palette histogram has not been set.
|
||||
PNGEncodeParam15=ICC profile has not been set.
|
||||
PNGEncodeParam16=Physical dimension information has not been set.
|
||||
PNGEncodeParam17=Suggested palette information has not been set.
|
||||
PNGEncodeParam18=Significant bits values have not been set.
|
||||
PNGEncodeParam19=sRGB rendereding intent has not been set.
|
||||
PNGEncodeParam20=Uncompressed text strings have not been set.
|
||||
PNGEncodeParam21=Modification time has not been set.
|
||||
PNGEncodeParam22=Compressed text strings have not been set.
|
||||
PNGEncodeParam23='unsetBackground' not implemented by the superclass 'PNGEncodeParam'.
|
||||
PNGEncodeParam24='isBackgroundSet' not implemented by the superclass 'PNGEncodeParam'.
|
||||
SeekableOutputStream0=The constructor RandomAccessFile parameter cannot be null.
|
||||
SegmentedSeekableStream0=Source stream does not support seeking backwards.
|
||||
TIFFDirectory0=Unsupported TIFFField tag.
|
||||
TIFFDirectory1=Bad endianness tag (not 0x4949 or 0x4d4d).
|
||||
TIFFDirectory2=Bad magic number, should be 42.
|
||||
TIFFDirectory3=Directory number too large.
|
||||
TIFFDirectory4=- Ignoring this tag due to invalid data type.
|
||||
TIFFEncodeParam0=Unsupported compression scheme specified.
|
||||
TIFFEncodeParam1=Illegal DEFLATE compression level specified.
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
#
|
||||
# $RCSfile: com.sun.media.jai.codecimpl.fpx.properties,v $
|
||||
#
|
||||
# Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
|
||||
#
|
||||
# Use is subject to license terms.
|
||||
#
|
||||
# $Revision: 1.1 $
|
||||
# $Date: 2005/02/11 04:55:41 $
|
||||
# $State: Exp $
|
||||
#
|
||||
FPXImage0=IOException occurs when get a tile.
|
||||
FPXImage1=IOException occurs when get the summery information.
|
||||
FPXImage2=IOException occurs when get the image information.
|
||||
PropertySet0=Not implemented.
|
||||
PropertySet1=IOException occurs when get I4.
|
||||
PropertySet2=IOException occurs when get UI1.
|
||||
PropertySet3=IOException occurs when get UI2.
|
||||
PropertySet4=IOException occurs when get UI4.
|
||||
PropertySet5=IOException occurs when get LPSTR/LPWSTR.
|
||||
PropertySet6=IOException occurs when get R4.
|
||||
PropertySet7=IOException occurs when get blob.
|
||||
|
||||
|
|
@ -0,0 +1,139 @@
|
|||
#
|
||||
# $RCSfile: com.sun.media.jai.codecimpl.properties,v $
|
||||
#
|
||||
# Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
|
||||
#
|
||||
# Use is subject to license terms.
|
||||
#
|
||||
# $Revision: 1.3 $
|
||||
# $Date: 2006/04/12 18:08:11 $
|
||||
# $State: Exp $
|
||||
#
|
||||
BMPImageDecoder0=Invalid magic value for BMP file
|
||||
BMPImageDecoder1=Invalid compression specified in BMP file.
|
||||
BMPImageDecoder2=Not implemented yet.
|
||||
BMPImageDecoder3=Invalid compression specified for BMP file.
|
||||
BMPImageDecoder4=BMP version 5 not implemented yet.
|
||||
BMPImageDecoder5=IOException while reading the BMP file headers.
|
||||
BMPImageDecoder6=Error while reading the BMP file.
|
||||
BMPImageDecoder7=Illegal tile requested from a BMPImage.
|
||||
BMPImageDecoder8=Illegal page requested from a BMP file.
|
||||
BMPImageDecoder9=IOException while resetting and skipping bytes from InputStream.
|
||||
BMPImageEncoder0=Image to be written has ushort/short/int/float/double data type, unsuitable for BMP file format.
|
||||
BMPImageEncoder1=Only images with either 1 or 3 bands can be written out as BMP files.
|
||||
BMPImageEncoder2=BMP file format cannot support data with a bitdepth
|
||||
greater than 8.
|
||||
BMPImageEncoder3=All samples must have the same size.
|
||||
BMPImageEncoder4=IOException occurs when read data.
|
||||
BMPImageEncoder5=Encoding of BMP files in any format other than Version 3 is not implemented yet.
|
||||
BMPImageEncoder6=If Image is to be compressed, then the OutputStream parameter must be a SeekableOutputStream.
|
||||
FPXCodec0=FPX encoding not supported yet.
|
||||
FPXImageDecoder0=Illegal page requested from an FPX file.
|
||||
GIFImage0=Unexpected block type
|
||||
GIFImage1=Error reading GIF image header.
|
||||
GIFImage2=Illegal tile requested from a GIFImage.
|
||||
GIFImage3=Error reading GIF image data.
|
||||
GIFImageDecoder0=Error reading GIF stream header.
|
||||
GIFImageDecoder1=Illegal page requested from a GIF file.
|
||||
JPEGImageDecoder0=Illegal page requested from a JPEG file.
|
||||
JPEGImageDecoder1=Unable to process image stream, incorrect format.
|
||||
JPEGImageDecoder2=Unable to process image stream, I/O error.
|
||||
JPEGImageDecoder3=Cannot decode a 2-banded image with a PackedColorModel.
|
||||
JPEGImageDecoder4=Illegal tile requested from a JPEG image.
|
||||
JPEGImageEncoder0=Only 1, or 3-band byte data may be written.
|
||||
JPEGImageEncoder1=ColorSpace must be TYPE_RGB for numBands > 1
|
||||
JPEGImageEncoder2=IOException occurs when encode the image.
|
||||
PNGCodec0=PNG encoding not supported yet.
|
||||
PNGImageDecoder0=PNG magic number not found.
|
||||
PNGImageDecoder1=Error reading PNG header.
|
||||
PNGImageDecoder2=I/O error reading PNG file.
|
||||
PNGImageDecoder3=Illegal bit depth for a PNG image.
|
||||
PNGImageDecoder4=Bad color type for a PNG image.
|
||||
PNGImageDecoder5=An RGB PNG image can't have a bit depth less than 8.
|
||||
PNGImageDecoder6=A palette-color PNG image can't have a bit depth of 16.
|
||||
PNGImageDecoder7=A PNG Gray+Alpha image can't have a bit depth less than 8.
|
||||
PNGImageDecoder8=A PNG RGB+Alpha image can't have a bit depth less than 8.
|
||||
PNGImageDecoder9=Unsupported PNG compression method (not 0).
|
||||
PNGImageDecoder10=Unsupported PNG filter method (not 0).
|
||||
PNGImageDecoder11=Unsupported PNG interlace method (not 0 or 1).
|
||||
PNGImageDecoder12=Unknown PNG pHYs unit specifier (not 0 or 1).
|
||||
PNGImageDecoder13=Illegal PNG sBit value (< 0 or > bit depth).
|
||||
PNGImageDecoder14=Too many PNG alpha palette entries.
|
||||
PNGImageDecoder15=PNG image already has alpha, can't have tRNS chunk.
|
||||
PNGImageDecoder16=Unknown PNG filter type (not 0-4).
|
||||
PNGImageDecoder17=Illegal tile requested from a PNG image.
|
||||
PNGImageDecoder18=PNG can't have hIST chunk without a PLTE chunk.
|
||||
PNGImageDecoder19=Illegal page requested from a PNG file.
|
||||
PNGImageDecoder20=IOException occurs when get the chunk type.
|
||||
PNGImageDecoder21=IOException occurs when get a chunk.
|
||||
|
||||
PNMImageDecoder0=Invalid magic value for PBM/PGM/PPM file.
|
||||
PNMImageDecoder1=Unrecognized file variant.
|
||||
PNMImageDecoder2=IOException occured while reading PNM file header.
|
||||
PNMImageDecoder3=IOException occured while processing PNM file.
|
||||
PNMImageDecoder4=Illegal tile requested from a PNMImage.
|
||||
PNMImageDecoder5=Illegal page requested from a PNM file.
|
||||
PNMImageDecoder6=IOException occurs when read the image header.
|
||||
PNMImageDecoder7=IOException occurs when read the image data.
|
||||
|
||||
|
||||
PNMImageEncoder0=Source image has float/double data type, unsuitable for PNM file format.
|
||||
PNMImageEncoder1=Image has an IndexColorModel whose map size is to small for the data type obtained from SampleModel.
|
||||
PNMImageEncoder2=Source image has unsuitable number of bands for PNM file format.
|
||||
|
||||
SimpleRenderedImage0=The specified region, if not null, must intersect the image bounds.
|
||||
|
||||
SingleTileRenderedImage0=Illegal tile requested from a SingleTileRenderedImage.
|
||||
TIFFFaxDecoder0=Invalid code encountered.
|
||||
TIFFFaxDecoder1=EOL code word encountered in White run.
|
||||
TIFFFaxDecoder2=EOL code word encountered in Black run.
|
||||
TIFFFaxDecoder3=First scanline must be 1D encoded.
|
||||
TIFFFaxDecoder4=Invalid code encountered while decoding 2D group 3 compressed data.
|
||||
TIFFFaxDecoder5=Invalid code encountered while decoding 2D group 4 compressed data.
|
||||
TIFFFaxDecoder6=Scanline must begin with EOL code word.
|
||||
TIFFFaxDecoder7=TIFF_FILL_ORDER tag must be either 1 or 2.
|
||||
TIFFFaxDecoder8=All fill bits preceding EOL code must be 0.
|
||||
TIFFFaxDecoder9=End of data reached before next EOL encountered.
|
||||
|
||||
TIFFImage0=Planar (band-sequential) format TIFF is not supported.
|
||||
TIFFImage1=All samples must have the same bit depth.
|
||||
TIFFImage2=All samples must have the same data format.
|
||||
TIFFImage3=Unsupported combination of bit depth and sample format.
|
||||
TIFFImage4=Unsupported combination of photometric interpretation, samples per pixel, and bit depth.
|
||||
TIFFImage5="{0}", a required field, is not present in the TIFF file.
|
||||
TIFFImage7=Unsupported compression type for non-bilevel data.
|
||||
TIFFImage8=Illegal value for Predictor in TIFF file.
|
||||
TIFFImage9=-bit samples are not supported for Horizontal differencing Predictor.
|
||||
TIFFImage10=Unsupported compression type.
|
||||
TIFFImage11=Colormap must be present for a Palette Color image.
|
||||
TIFFImage12=Illegal tile requested from a TIFFImage.
|
||||
TIFFImage13=IOException occured while reading TIFF image data.
|
||||
TIFFImage14=Unable to decode Packbits compressed data - not enough data.
|
||||
TIFFImage15=Decoding of old style JPEG-in-TIFF data is not supported.
|
||||
TIFFImage16=JPEG-in-TIFF decoding supported only for 8-bit samples and either 1 (grayscale or palette-color) or 3 (RGB or YCbCr) samples per pixel.
|
||||
TIFFImage17=Error inflating data
|
||||
TIFFImage18=Error extracting data array from floating point DataBuffer.
|
||||
|
||||
TIFFImageDecoder0=Illegal page requested from a TIFF file.
|
||||
|
||||
TIFFImageEncoder0=All samples must have the same bit depth.
|
||||
TIFFImageEncoder1=1- and 4-bit data supported for single band images only.
|
||||
TIFFImageEncoder2=Byte buffers require 1-, 4-, or 8-bit data.
|
||||
TIFFImageEncoder3=Short or unsigned short buffers require 16-bit data.
|
||||
TIFFImageEncoder4=Int or float buffers require 32-bit data.
|
||||
TIFFImageEncoder5=Unsupported output data type.
|
||||
TIFFImageEncoder6=TIFF encoder does not support (unsigned) short palette images.
|
||||
TIFFImageEncoder7=Invalid image - An image with sampleSize of 1 bit must have IndexColorModel with mapsize of 2.
|
||||
TIFFImageEncoder8=Image type not supported for output.
|
||||
TIFFImageEncoder9=JPEG-in-TIFF encoding supported only for 8-bit samples and either 1 (grayscale) or 3 (RGB or YCbCr) samples per pixel.
|
||||
TIFFImageEncoder10=Unsupported TIFFField type.
|
||||
TIFFImageEncoder11=JPEG-in-TIFF encoding is not supported for palette-color images.
|
||||
TIFFImageEncoder12=Bilevel encodings are supported for bilevel images only.
|
||||
|
||||
TIFFLZWDecoder0=TIFF 5.0-style LZW codes are not supported.
|
||||
|
||||
WBMPImageDecoder0=Illegal page requested from a WBMP file.
|
||||
|
||||
WBMPImageEncoder0=WBMP encoder does not support FLOAT or DOUBLE buffers.
|
||||
WBMPImageEncoder1=WBMP encoder can write only 1-band images.
|
||||
WBMPImageEncoder2=WBMP encoder can write only bilevel (1 bit per pixel) images.
|
||||
|
|
@ -0,0 +1,346 @@
|
|||
#
|
||||
# $RCSfile: javax.media.jai.properties,v $
|
||||
#
|
||||
# Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
|
||||
#
|
||||
# Use is subject to license terms.
|
||||
#
|
||||
# $Revision: 1.1 $
|
||||
# $Date: 2005/02/11 04:57:25 $
|
||||
# $State: Exp $
|
||||
#
|
||||
Generic0=The input argument(s) may not be null.
|
||||
Generic1=The sourceIndex must be non-negative and less than the number of sources this image has.
|
||||
Generic2=The argument(s) may not be null or of zero length.
|
||||
Generic3=Unsupported data type.
|
||||
Generic4=The TileRequest parameter may not be null.
|
||||
Generic5=Source Vector must contain at least one element.
|
||||
|
||||
AreaOpImage0=The user-supplied image bounds do not intersect the source bounds.
|
||||
AttributedImageCollection0=The collection passed to the constructor cannot be null.
|
||||
AttributedImageCollection1=The object(s) could not be added to the collection.
|
||||
|
||||
BorderExtender0=Illegal value of extenderType.
|
||||
BorderExtenderConstant0=Band count exceeds non-unity number of constants.
|
||||
CRIFImpl0=Cannot render a node for the operation :
|
||||
CollectionOp0= - Cannot render CollectionOp for this operation.
|
||||
|
||||
ColorCube0=Unsupported data type requested.
|
||||
ColorCube1=Zero-length dimension array.
|
||||
ColorCube2=Zero-valued dimension.
|
||||
ColorCube3=Color cube too large for 32 bit addressability.
|
||||
ColorCube4=Color cube offset + size exceeds type maximum.
|
||||
ColorCube5=This statement should be unreachable.
|
||||
ColorCube6=Non-byte data types not yet implemented.
|
||||
ColorCube7=Unsupported data type.
|
||||
|
||||
ColorSpaceJAI0=Source raster should not be null.
|
||||
ColorSpaceJAI1=Source should have 3 bands.
|
||||
ColorSpaceJAI2=Destination should have 3 bands.
|
||||
ColorSpaceJAI3=Length of source component size array should be 3.
|
||||
ColorSpaceJAI4=Length of Destination component size array should be 3.
|
||||
|
||||
DataBuffer0=Size of supplied array should be greater or equal to "size" parameter
|
||||
DataBuffer1=Size of supplied array should be greater or equal to size + offset parameters
|
||||
DeferredData0=Null parameter supplied to constructor.
|
||||
DeferredData1=The data object must be null or an instance of dataClass.
|
||||
DeferredProperty0=The specified property is not emitted by the PropertySource.
|
||||
|
||||
DescriptorCache0=A descriptor is already registered against the name "{0}" under registry mode "{1}"
|
||||
DescriptorCache1=No descriptor is registered against the name "{0}" under registry mode "{1}"
|
||||
DescriptorCache2=PropertyGenerator #{0,number,integer} is null for descriptor "{1}" under registry mode "{2}"
|
||||
DescriptorCache3=No products are registered against the descriptor "{0}" under registry mode "{1}"
|
||||
DescriptorCache4=No product by name "{2}" is registered against the descriptor "{0}" under registry mode "{1}"
|
||||
DescriptorCache5=No product preferences have been set for descriptor "{0}" under registry mode "{1}"
|
||||
DescriptorCache6=Registry mode "{0}" does not support preferences. Can not set/unset/clear/get product preferences.
|
||||
DescriptorCache7=Registry mode "{0}" does not support properties.
|
||||
|
||||
FactoryCache0=Input factory object of class "{0}" is not an instance of registry mode "{1}"`s factory class "{2}".
|
||||
FactoryCache1=Registry mode "{0}" does not support preferences. Can not set/unset/clear/get factory preferences.
|
||||
FactoryCache2=No preference was previously set between "{0}" and "{1}" for mode = "{2}", descriptor = "{3}" and product = "{4}".
|
||||
FactoryCache3=Specified instance of "{0}" was not previously registered against descriptor "{1}" under "{2}".
|
||||
FactoryCache4=Specified instance of "{0}" was not previously registered against descriptor "{1}".
|
||||
|
||||
FloatDoubleColorModel1=getRed(int) not supported by this ColorModel.
|
||||
FloatDoubleColorModel0=transferType must be DataBuffer.TYPE_FLOAT or DataBuffer.TYPE_DOUBLE.
|
||||
FloatDoubleColorModel2=getGreen(int) not supported by this ColorModel.
|
||||
FloatDoubleColorModel3=getBlue(int) not supported by this ColorModel.
|
||||
FloatDoubleColorModel4=getAlpha(int) not supported by this ColorModel.
|
||||
FloatDoubleColorModel5=getRGB(int) not supported by this ColorModel.
|
||||
FloatDoubleColorModel6=raster transfer type must match that of this ColorModel.
|
||||
FloatDoubleColorModel7=Type of pixel does not match transfer type.
|
||||
FloatDoubleColorModel8=pixel array is not large enough to hold all color/alpha components.
|
||||
FloatDoubleColorModel9=Pixel values for FloatDoubleColorModel cannot be represented as a single integer.
|
||||
FloatDoubleColorModel10=elements required in the components array.
|
||||
|
||||
Histogram0=The three arguments, numBins, lowValue, and highValue, do not have the same array length.
|
||||
Histogram1=The array lengths of the three arguments are 0.
|
||||
Histogram2=The numBins is less than or equal to 0; it should be greater than 0.
|
||||
Histogram3=The lowValue is greater than or equal to its corresponding highValue; it should be less than the highValue.
|
||||
Histogram4=The pixels stored in the Raster and the histogram`s bins do not have the same number of bands.
|
||||
Histogram5=The requested bin sub-range falls outside of the overall bin range of the indicated band .
|
||||
Histogram6=The requested moment number is non-positive.
|
||||
Histogram7=The specified smoothing parameter is negative.
|
||||
Histogram8=The specified standard deviation is negative.
|
||||
Histogram9=The specified sample proportion is not in the range (0,1).
|
||||
Histogram10=minBin is greater than maxBin; it must be less than or equal to maxBin.
|
||||
Histogram11=data type must be one of the DataBuffer.TYPE_BYTE,..., DataBuff.TYPE_DOUBLE.
|
||||
|
||||
ImageLayout0=The specified dimensional parameter is non-positive.
|
||||
|
||||
ImageMIPMap0=No highest resolution image found in the downSampler chain.
|
||||
ImageMIPMap1=An object other than a RenderedImage is in the downSampler chain.
|
||||
IntegerSequence0=Illegal element requested while enumerating.
|
||||
IntegerSequence1=min is greater than max.
|
||||
Interpolation0=Unrecognized interpolation type.
|
||||
InterpolationTable0=dataH must contain exactly width * 2^subsampleBitsH entries.
|
||||
InterpolationTable1=dataV must contain exactly height * 2^subsampleBitsV entries.
|
||||
|
||||
JAI0=No OperationDescriptor is registered in the current operation registry under this name.
|
||||
JAI2=This operation does not produce a java.awt.image.RenderedImage.
|
||||
JAI4=This operation does not produce a java.awt.image.renderable.RenderableImage.
|
||||
JAI5=This operation does not produce a java.awt.image.RenderedImage or a javax.media.jai.CollectionImage.
|
||||
JAI6=This operation does not produce a java.awt.image.renderable.RenderableImage or a javax.media.jai.CollectionImage.
|
||||
JAI7=key parameter is null.
|
||||
JAI8=At least one of the default rendering size dimensions must be positive.
|
||||
JAI9=value parameter is null.
|
||||
JAI10=TileCache capacity must be a non-negative number.
|
||||
JAI13=JAI Build version unavailable.
|
||||
JAI14=The operation name parameter may not be null.
|
||||
JAI15=The ParameterBlock parameter may not be null.
|
||||
JAI16=Cannot create an instance of :
|
||||
|
||||
KernelJAI0=Kernel width must be a positive number.
|
||||
KernelJAI1=Kernel height must be a positive number.
|
||||
KernelJAI2=Kernel data array must have width*height elements.
|
||||
KernelJAI3=Separable KernelJAI constructor argument dataH array must have width elements.
|
||||
KernelJAI4=Separable KernelJAI constructor argument dataV array must have height elements.
|
||||
LookupTableJAI0=data.getType() is not one of the legal data types.
|
||||
LookupTableJAI1=src argument is null.
|
||||
LookupTableJAI2=src must have a SampleModel of integral type.
|
||||
LookupTableJAI3=dst does not have the correct data type or number of bands.
|
||||
MultiResolutionRenderableImage0=The rendering-independent height must be positive.
|
||||
MultiResolutionRenderableImage1=Non-positive width and height specified.
|
||||
|
||||
NullOpImage0=The specified computeType is not among the known values.
|
||||
|
||||
OperationDescriptorImpl0=Need an array of {0} for each mode (numModes = {1,number,integer}).
|
||||
OperationDescriptorImpl1=Number of source names {0,number,integer} != number of source classes {1,number,integer} per mode.
|
||||
OperationDescriptorImpl2=Number of source classes {0,number,integer} != number of sources {1,number,integer} for mode "{2}".
|
||||
OperationDescriptorImpl3=Mode "{0}" does not support properties.
|
||||
OperationDescriptorImpl4=operation "{0}" requires {1,number,integer} source object(s).
|
||||
OperationDescriptorImpl5=operation "{0}" requires {1,number,integer} parameter object(s).
|
||||
OperationDescriptorImpl6=operation "{0}" requires {1,number,integer} source object(s).
|
||||
OperationDescriptorImpl7=operation "{0}" requires all source objects to be valid input; a null is supplied.
|
||||
OperationDescriptorImpl8=operation "{0}" requires source at index {1,number,integer} to be an object of {2}; an object of {3} was supplied.
|
||||
OperationDescriptorImpl9=operation "{0}" requires {1,number,integer} parameter object(s).
|
||||
OperationDescriptorImpl10="{0}" operation`s value for parameter "{1}" is invalid.
|
||||
OperationDescriptorImpl11=operation "{0}" requires parameter at index {1,number,integer} to be non-null.
|
||||
OperationDescriptorImpl12=registry mode name can not be null.
|
||||
OperationDescriptorImpl13=operation "{0}" does not support registry mode "{1}".
|
||||
|
||||
OperationNodeSupport0=Non-serializable source in this operation`s ParameterBlock.
|
||||
OperationNodeSupport1=Non-serializable parameter in this operation`s ParameterBlock.
|
||||
|
||||
OperationRegistry0=Mode name "{0}" is not a valid (registered) registry mode.
|
||||
OperationRegistry1=Registry initialization file not found.
|
||||
OperationRegistry2=Error in parsing registry initialization file.
|
||||
OperationRegistry3=Can not descriptor "{0}" under mode "{1}". Mode "{1}" is not a valid registry mode.
|
||||
OperationRegistry4=There no registry modes associated with descriptor class "{0}".
|
||||
OperationRegistry5=No descriptor by name "{0}" is registered under mode "{1}".
|
||||
OperationRegistry6=One factory fails for the operation
|
||||
OperationRegistry7=All factories fail for the operation
|
||||
|
||||
OpImage0=must override the implementation of void computeRect(Raster[], WritableRaster, Rectangle) from javax.media.jai.OpImage.
|
||||
OpImage1=must override the implementation of void computeRect(PlanarImage[], WritableRaster, Rectangle) from javax.media.jai.OpImage.
|
||||
OpImage2=The supplied source Vector must not be null.
|
||||
OpImage3=The supplied RenderedImage source parameter(s) may not be null.
|
||||
|
||||
ParameterBlockJAI0=The parameter does not have the correct class type.
|
||||
ParameterBlockJAI1=does not have an OperationDescriptor registered with the OperationRegistry.
|
||||
ParameterBlockJAI2= the parameter value is not valid.
|
||||
ParameterBlockJAI3=The supplied source is null.
|
||||
ParameterBlockJAI4=The supplied source does not have the correct class type for either rendered or renderable mode.
|
||||
ParameterBlockJAI5=Use the set methods to add parameters to the ParameterBlockJAI
|
||||
ParameterBlockJAI6= the parameter value has not yet been set and has no default value.
|
||||
ParameterBlockJAI7=The length of the supplied parameter Vector does no match the number of parameters of the corresponding operation.
|
||||
ParameterBlockJAI8=can not set parameter to NO_PARAMETER_DEFAULT
|
||||
|
||||
ParameterListDescriptorImpl0=EnumeratedParameter with duplicate name or value.
|
||||
ParameterListDescriptorImpl1=Number of parameter defaults not the same as number of parameter names.
|
||||
ParameterListDescriptorImpl2=Number of valid parameter values not the same as number of parameter names.
|
||||
ParameterListDescriptorImpl3=Number of parameter classes not the same as number of parameter names.
|
||||
ParameterListDescriptorImpl4=Parameter default`s class "{0}" is not an instance of the parameter class "{1}" for parameter "{2}".
|
||||
ParameterListDescriptorImpl5=Parameter "{0}" is an enumerated parameter, but it`s validParamValue is not a Set.
|
||||
ParameterListDescriptorImpl6=The element class of Range ({0}) does not match with the parameter class ({1}) for parameter "{2}".
|
||||
ParameterListDescriptorImpl7=Valid parameter value`s class ({0}) is not an instance of the parameter class ({1}) for parameter "{2}".
|
||||
ParameterListDescriptorImpl8= is not an enumerated parameter.
|
||||
ParameterListDescriptorImpl9=Parameter value`s class ({0}) is not an instance of the parameter class ({1}) for parameter "{2}".
|
||||
ParameterListDescriptorImpl10=The input parameter class ({0}) is not an EnumeratedParameter.class
|
||||
|
||||
ParameterListImpl0=Object`s class ({0}) is not an instance of the parameter class ({1}) for parameter "{2}".
|
||||
ParameterListImpl1= parameter value is invalid.
|
||||
ParameterListImpl2= the parameter value has not yet been set and has no default value.
|
||||
|
||||
PerspectiveTransform0=PerspectiveTransform.createInverse
|
||||
PerspectiveTransform1=Divide by zero error.
|
||||
|
||||
PixelAccessor0=The specified Rectangle is not completely contained within the Raster`s bounds.
|
||||
PixelAccessor1=The specified type is not one of the valid data types defined in DataBuffer.
|
||||
PixelAccessor2=The specified type is not large enough to hold the Raster`s pixel samples.
|
||||
PixelAccessor3=The pixel data described by the specified Raster`s SampleModel is not single-band and single-bit.
|
||||
PixelAccessor4=The specified type is not large enough to hold the image`s color/alpha components.
|
||||
PixelAccessor5=The image does not have a valid ColorModel that is compatible with the image`s SampleModel.
|
||||
|
||||
PlanarImage0=There is no source corresponding to the specified index value.
|
||||
PlanarImage1=getGraphics() is not implemented in this class.
|
||||
PlanarImage2=Requested region cannot be represented by a single Raster.
|
||||
PlanarImage3=The supplied ColorModel is not compatible with this image`s SampleModel.
|
||||
PlanarImage4=The specified region, if not null, must intersect with the image`s bounds.
|
||||
PlanarImage5=The specified ColorModel is incompatible with the image SampleModel.
|
||||
PlanarImage6=No ColorModel is supplied and the image ColorModel is null.
|
||||
PlanarImage7=Null element encountered in sources Vector.
|
||||
|
||||
PointOpImage0=The intersection of all the source bounds is empty.
|
||||
PointOpImage1=The user-supplied image bounds is empty.
|
||||
PointOpImage2=The user-supplied image bounds is not within the intersection of all the source bounds.
|
||||
|
||||
PropertyChangeEventJAI0=The source of the PropertyChangeEvent is null.
|
||||
PropertyChangeEventJAI1=The old and new values of the PropertyChangeEvent are both null.
|
||||
|
||||
PropertySourceChangeEvent0=The old value of the PropertySourceChangeEvent is null.
|
||||
PropertySourceChangeEvent1=The new value of the PropertySourceChangeEvent is null.
|
||||
|
||||
ROI0=Can construct from single-banded images only.
|
||||
ROI1=Not yet implemented.
|
||||
ROI2=The requested area is not within the ROI.
|
||||
ROI3=mask argument array is too small.
|
||||
ROI4=Unsupported data type.
|
||||
ROI5=The supplied AffineTransform is null.
|
||||
ROI6=The supplied Interpolation object is null.
|
||||
ROIShape0=Mask argument array is too small.
|
||||
ROIShape1=Unknown polygon type.
|
||||
ROIShape2=Constructor parameter is null.
|
||||
ROIShape3=The supplied ROI parameter is null.
|
||||
|
||||
RasterAccessor0=DataBuffer must have getOffsets().length equal to 1 or numBands.
|
||||
RasterAccessor1=Binary tag case encountered for non-binary SampleModel.
|
||||
RasterAccessor2=Requested rectangle bounds is not contained in the input raster`s bounds.
|
||||
|
||||
RasterFactory0=Number of bands must be greater than 0.
|
||||
RasterFactory1=Bank indices array is null.
|
||||
RasterFactory2=bankIndices.length != bandOffsets.length
|
||||
RasterFactory3=Unsupported data type.
|
||||
RasterFactory4=Band offsets array is null.
|
||||
RasterFactory5=Offsets between bands must be less than the scanline stride.
|
||||
RasterFactory6=Pixel stride times width must be less than the scanline stride.
|
||||
RasterFactory7=Pixel stride must be greater than or equal to the offset between bands.
|
||||
RasterFactory8=This method does not support the input data type.
|
||||
RasterFactory9=parentX lies outside raster.
|
||||
RasterFactory10=parentY lies outside raster.
|
||||
RasterFactory11=(parentX + width) is outside raster.
|
||||
RasterFactory12=(parentY + height) is outside raster.
|
||||
RasterFactory13=Illegal value for transparency.
|
||||
RasterFactory14=Transparency cannot be opaque when useAlpha is true.
|
||||
RasterFactory15=bitsPerBands must be greater than 0.
|
||||
RasterFactory16=Size of array must be smaller than Integer.MAX_VALUE.
|
||||
|
||||
RegistryFileParser0=Error in registry file at line number #{0,number,integer}
|
||||
RegistryFileParser1=Format expected: descriptor RegistryElementDescriptor-class-name
|
||||
RegistryFileParser2=Format expected: modeName factory-class-name product-name descriptor-name local-name
|
||||
RegistryFileParser3=Format expected: modeName factory-class-name descriptor-name
|
||||
RegistryFileParser4=Format expected: pref modeName descriptor-name product-name preferred-local-name other-local-name
|
||||
RegistryFileParser5=Format expected: productPref modeName descriptor-name preferred-product-name other-product-name
|
||||
RegistryFileParser6=Can not parse line.
|
||||
RegistryFileParser7=Can not set factory preferences for registry modes that do not support preferences.
|
||||
RegistryFileParser8=Local name does not map to a registered factory object.
|
||||
RegistryFileParser9=Can not set product preferences for registry modes that do not support preferences.
|
||||
RegistryFileParser10=Can not add registry mode since it already exists.
|
||||
RegistryFileParser11=Error while parsing JAI registry file "{0}" :
|
||||
|
||||
RemoteImage0=Caught RemoteException, going to sleep.
|
||||
RemoteImage1=Source parameter may not be null.
|
||||
RemoteImage2=Rect must be null or must intersect the image bounds.
|
||||
RemoteImage3=Retries parameter must be positive.
|
||||
RemoteImage4=Timeout parameter must be positive.
|
||||
|
||||
RenderableImageAdapter0=The supplied String parameter is null.
|
||||
|
||||
RenderedImageList0=Argument must not be null.
|
||||
RenderedImageList1=The list must not be empty.
|
||||
RenderedImageList2=The specified object must be an instance of RenderedImage.
|
||||
RenderedImageList3=Index is out of bounds.
|
||||
|
||||
RenderableGraphics0=Empty dimensions parameter.
|
||||
RenderableGraphics1=One of w and h must be positive for scaled rendering.
|
||||
RenderableOp2=No adequate CRIF exists in the registry.
|
||||
RenderableOp3=One of w or h must be non-zero.
|
||||
|
||||
RenderedOp0= - Unable to render RenderedOp for this operation.
|
||||
RenderedOp3=Attempt to set a property on a rendered node!
|
||||
RenderedOp4=Attempted to set a synthetic property!
|
||||
RenderedOp5=Synthetic properties cannot be suppressed.
|
||||
RenderedOp6=pg must not be null.
|
||||
|
||||
SourcelessOpImage0=Can not perform rectangle mapping between source and destinatioon because the image has no sources.
|
||||
|
||||
TiledImage0=Cannot construct graphics objects for non-integral data types.
|
||||
TiledImage1=More releases than gets!
|
||||
TiledImage2=Cannot clear tiles while any tile is being held by a writer.
|
||||
TiledImageGraphics0=Cannot construct a TiledImageGraphics object from a TiledImage with non-integral data type.
|
||||
TiledImageGraphics1=Unable to derive an appropriate ColorModel.
|
||||
TiledImageGraphics2=Can not find the method:
|
||||
TiledImageGraphics3=The affine transformation is not invertible.
|
||||
TiledImageGraphics4=Fails to invoke the method:
|
||||
|
||||
Warp0=Supplied warp destination array is too small.
|
||||
WarpAffine0=WarpAffine requires 3 coefficients each for X and Y coordinates.
|
||||
WarpCubic0=WarpCubic requires 10 coefficients each for X and Y coordinates.
|
||||
WarpGrid0=WarpPositions.length != 2*xNumCells + 1*yNumCells + 1.
|
||||
WarpPerspective0=WarpPerspective constructor requires a valid input; null is supplied.
|
||||
WarpPolynomial0=Wrong number of coefficients for X and/or Y coordinate supplied to polynomial warp.
|
||||
WarpPolynomial1=Insufficient number of points available to compute polynomial.
|
||||
WarpQuadratic0=WarpQuadratic requires 6 coefficients each for X and Y coordinates.
|
||||
|
||||
WritableRenderedImageAdapter0=The TileObserver parameter supplied is null.
|
||||
WritableRenderedImageAdapter1=The Raster parameter supplied is null.
|
||||
#
|
||||
# $RCSfile: com.sun.media.jai.util.properties,v $
|
||||
#
|
||||
# Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
|
||||
#
|
||||
# Use is subject to license terms.
|
||||
#
|
||||
# $Revision: 1.1 $
|
||||
# $Date: 2005/02/11 04:57:02 $
|
||||
# $State: Exp $
|
||||
#
|
||||
CaselessStringArrayTable0=Can not look up a null key.
|
||||
CaselessStringArrayTable1=Could not find the key.
|
||||
DataBufferUtils0=Cannot find class for
|
||||
DataBufferUtils1=Cannot construct DataBuffer.
|
||||
DataBufferUtils2=Cannot invoke DataBuffer method
|
||||
Generic0=The input argument(s) may not be null.
|
||||
ImageUtil0=The supplied Raster does not represent a binary data set.
|
||||
ImageUtil1=Default ColorModel method is non-static.
|
||||
ImageUtil2=Default ColorModel method return type is not ColorModel.
|
||||
ImageUtil3=Default ColorModel method does not accept a single parameter of class SampleModel.
|
||||
ImageUtil4=Exception occurs when generate a compatible color model for a sample model.
|
||||
JDKWorkarounds0=SampleModel and ColorModel parameters must be non-null.
|
||||
PropertyGeneratorImpl0=The parameter(s) may not be null.
|
||||
PropertyGeneratorImpl1=The parameter arrays may not be zero length.
|
||||
PropertyGeneratorImpl2=The property name and class array lengths must be equal.
|
||||
PropertyGeneratorImpl3=The class of the operation node is not supported.
|
||||
PropertyGeneratorImpl4=Property classes cannot correspond to a primitive type.
|
||||
PropertyUtil0=The property name prefix may not be null.
|
||||
SunTileCache=Tile cache memory capacity must be greater than or equal to 0.
|
||||
SunTileCache0=ConcurrentModificationException occurs when remove tiles from cache.
|
||||
SunTileScheduler0=All parameters must be non-null.
|
||||
SunTileScheduler1=The image parameter must be non-null.
|
||||
SunTileScheduler2=The parallelism must be non-negative.
|
||||
SunTileScheduler3=The request parameter must be non-null.
|
||||
SunTileScheduler4=The target and tileIndices parameters must be non-null.
|
||||
SunTileScheduler5=Waiting thread received a null tile.
|
||||
SunTileScheduler6=Problem occurs when computing a tile by the owner.
|
||||
SunTileScheduler7=Exception occurs when computing tiles.
|
||||
SunTileSchedulerName=SunTileScheduler
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
package com.sun.media.jai.codecimpl;
|
||||
|
||||
import com.sun.media.jai.codec.BMPEncodeParam;
|
||||
import com.sun.media.jai.codec.ImageCodec;
|
||||
import com.sun.media.jai.codec.ImageDecodeParam;
|
||||
import com.sun.media.jai.codec.ImageDecoder;
|
||||
import com.sun.media.jai.codec.ImageEncodeParam;
|
||||
import com.sun.media.jai.codec.ImageEncoder;
|
||||
import com.sun.media.jai.codec.SeekableStream;
|
||||
import java.awt.image.RenderedImage;
|
||||
import java.awt.image.SampleModel;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
public final class BMPCodec extends ImageCodec {
|
||||
public String getFormatName() {
|
||||
return "bmp";
|
||||
}
|
||||
|
||||
public Class getEncodeParamClass() {
|
||||
return BMPEncodeParam.class;
|
||||
}
|
||||
|
||||
public Class getDecodeParamClass() {
|
||||
return Object.class;
|
||||
}
|
||||
|
||||
public boolean canEncodeImage(RenderedImage im, ImageEncodeParam param) {
|
||||
SampleModel sampleModel = im.getSampleModel();
|
||||
int dataType = sampleModel.getTransferType();
|
||||
if (dataType != 0 && !CodecUtils.isPackedByteImage(im))
|
||||
return false;
|
||||
if (param != null) {
|
||||
if (!(param instanceof BMPEncodeParam))
|
||||
return false;
|
||||
BMPEncodeParam BMPParam = (BMPEncodeParam)param;
|
||||
int version = BMPParam.getVersion();
|
||||
if (version == 0 || version == 2)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected ImageEncoder createImageEncoder(OutputStream dst, ImageEncodeParam param) {
|
||||
BMPEncodeParam p = null;
|
||||
if (param != null)
|
||||
p = (BMPEncodeParam)param;
|
||||
return new BMPImageEncoder(dst, p);
|
||||
}
|
||||
|
||||
protected ImageDecoder createImageDecoder(InputStream src, ImageDecodeParam param) {
|
||||
return new BMPImageDecoder(src, null);
|
||||
}
|
||||
|
||||
protected ImageDecoder createImageDecoder(File src, ImageDecodeParam param) throws IOException {
|
||||
return new BMPImageDecoder(new FileInputStream(src), null);
|
||||
}
|
||||
|
||||
protected ImageDecoder createImageDecoder(SeekableStream src, ImageDecodeParam param) {
|
||||
return new BMPImageDecoder(src, null);
|
||||
}
|
||||
|
||||
public int getNumHeaderBytes() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
public boolean isFormatRecognized(byte[] header) {
|
||||
return (header[0] == 66 && header[1] == 77);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,861 @@
|
|||
package com.sun.media.jai.codecimpl;
|
||||
|
||||
import com.sun.media.jai.codec.ImageCodec;
|
||||
import com.sun.media.jai.codecimpl.util.ImagingException;
|
||||
import com.sun.media.jai.codecimpl.util.RasterFactory;
|
||||
import java.awt.Point;
|
||||
import java.awt.color.ColorSpace;
|
||||
import java.awt.image.DataBufferByte;
|
||||
import java.awt.image.DataBufferInt;
|
||||
import java.awt.image.DataBufferUShort;
|
||||
import java.awt.image.DirectColorModel;
|
||||
import java.awt.image.IndexColorModel;
|
||||
import java.awt.image.MultiPixelPackedSampleModel;
|
||||
import java.awt.image.Raster;
|
||||
import java.awt.image.SinglePixelPackedSampleModel;
|
||||
import java.awt.image.WritableRaster;
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
class BMPImage extends SimpleRenderedImage {
|
||||
private BufferedInputStream inputStream;
|
||||
|
||||
private long bitmapFileSize;
|
||||
|
||||
private long bitmapOffset;
|
||||
|
||||
private long compression;
|
||||
|
||||
private long imageSize;
|
||||
|
||||
private byte[] palette;
|
||||
|
||||
private int imageType;
|
||||
|
||||
private int numBands;
|
||||
|
||||
private boolean isBottomUp;
|
||||
|
||||
private int bitsPerPixel;
|
||||
|
||||
private int redMask;
|
||||
|
||||
private int greenMask;
|
||||
|
||||
private int blueMask;
|
||||
|
||||
private int alphaMask;
|
||||
|
||||
private static final int VERSION_2_1_BIT = 0;
|
||||
|
||||
private static final int VERSION_2_4_BIT = 1;
|
||||
|
||||
private static final int VERSION_2_8_BIT = 2;
|
||||
|
||||
private static final int VERSION_2_24_BIT = 3;
|
||||
|
||||
private static final int VERSION_3_1_BIT = 4;
|
||||
|
||||
private static final int VERSION_3_4_BIT = 5;
|
||||
|
||||
private static final int VERSION_3_8_BIT = 6;
|
||||
|
||||
private static final int VERSION_3_24_BIT = 7;
|
||||
|
||||
private static final int VERSION_3_NT_16_BIT = 8;
|
||||
|
||||
private static final int VERSION_3_NT_32_BIT = 9;
|
||||
|
||||
private static final int VERSION_4_1_BIT = 10;
|
||||
|
||||
private static final int VERSION_4_4_BIT = 11;
|
||||
|
||||
private static final int VERSION_4_8_BIT = 12;
|
||||
|
||||
private static final int VERSION_4_16_BIT = 13;
|
||||
|
||||
private static final int VERSION_4_24_BIT = 14;
|
||||
|
||||
private static final int VERSION_4_32_BIT = 15;
|
||||
|
||||
private static final int LCS_CALIBRATED_RGB = 0;
|
||||
|
||||
private static final int LCS_sRGB = 1;
|
||||
|
||||
private static final int LCS_CMYK = 2;
|
||||
|
||||
private static final int BI_RGB = 0;
|
||||
|
||||
private static final int BI_RLE8 = 1;
|
||||
|
||||
private static final int BI_RLE4 = 2;
|
||||
|
||||
private static final int BI_BITFIELDS = 3;
|
||||
|
||||
private WritableRaster theTile = null;
|
||||
|
||||
public BMPImage(InputStream stream) {
|
||||
if (stream instanceof BufferedInputStream) {
|
||||
this.inputStream = (BufferedInputStream)stream;
|
||||
} else {
|
||||
this.inputStream = new BufferedInputStream(stream);
|
||||
}
|
||||
try {
|
||||
this.inputStream.mark(Integer.MAX_VALUE);
|
||||
if (readUnsignedByte(this.inputStream) != 66 || readUnsignedByte(this.inputStream) != 77)
|
||||
throw new RuntimeException(JaiI18N.getString("BMPImageDecoder0"));
|
||||
this.bitmapFileSize = readDWord(this.inputStream);
|
||||
readWord(this.inputStream);
|
||||
readWord(this.inputStream);
|
||||
this.bitmapOffset = readDWord(this.inputStream);
|
||||
long size = readDWord(this.inputStream);
|
||||
if (size == 12L) {
|
||||
this.width = readWord(this.inputStream);
|
||||
this.height = readWord(this.inputStream);
|
||||
} else {
|
||||
this.width = readLong(this.inputStream);
|
||||
this.height = readLong(this.inputStream);
|
||||
}
|
||||
int planes = readWord(this.inputStream);
|
||||
this.bitsPerPixel = readWord(this.inputStream);
|
||||
this.properties.put("color_planes", new Integer(planes));
|
||||
this.properties.put("bits_per_pixel", new Integer(this.bitsPerPixel));
|
||||
this.numBands = 3;
|
||||
if (size == 12L) {
|
||||
this.properties.put("bmp_version", "BMP v. 2.x");
|
||||
if (this.bitsPerPixel == 1) {
|
||||
this.imageType = 0;
|
||||
} else if (this.bitsPerPixel == 4) {
|
||||
this.imageType = 1;
|
||||
} else if (this.bitsPerPixel == 8) {
|
||||
this.imageType = 2;
|
||||
} else if (this.bitsPerPixel == 24) {
|
||||
this.imageType = 3;
|
||||
}
|
||||
int numberOfEntries = (int)((this.bitmapOffset - 14L - size) / 3L);
|
||||
int sizeOfPalette = numberOfEntries * 3;
|
||||
this.palette = new byte[sizeOfPalette];
|
||||
this.inputStream.read(this.palette, 0, sizeOfPalette);
|
||||
this.properties.put("palette", this.palette);
|
||||
} else {
|
||||
this.compression = readDWord(this.inputStream);
|
||||
this.imageSize = readDWord(this.inputStream);
|
||||
long xPelsPerMeter = (long)readLong(this.inputStream);
|
||||
long yPelsPerMeter = (long)readLong(this.inputStream);
|
||||
long colorsUsed = readDWord(this.inputStream);
|
||||
long colorsImportant = readDWord(this.inputStream);
|
||||
switch ((int)this.compression) {
|
||||
case 0:
|
||||
this.properties.put("compression", "BI_RGB");
|
||||
break;
|
||||
case 1:
|
||||
this.properties.put("compression", "BI_RLE8");
|
||||
break;
|
||||
case 2:
|
||||
this.properties.put("compression", "BI_RLE4");
|
||||
break;
|
||||
case 3:
|
||||
this.properties.put("compression", "BI_BITFIELDS");
|
||||
break;
|
||||
}
|
||||
this.properties.put("x_pixels_per_meter", new Long(xPelsPerMeter));
|
||||
this.properties.put("y_pixels_per_meter", new Long(yPelsPerMeter));
|
||||
this.properties.put("colors_used", new Long(colorsUsed));
|
||||
this.properties.put("colors_important", new Long(colorsImportant));
|
||||
if (size == 40L) {
|
||||
int numberOfEntries, sizeOfPalette;
|
||||
switch ((int)this.compression) {
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
numberOfEntries = (int)((this.bitmapOffset - 14L - size) / 4L);
|
||||
sizeOfPalette = numberOfEntries * 4;
|
||||
this.palette = new byte[sizeOfPalette];
|
||||
this.inputStream.read(this.palette, 0, sizeOfPalette);
|
||||
this.properties.put("palette", this.palette);
|
||||
if (this.bitsPerPixel == 1) {
|
||||
this.imageType = 4;
|
||||
} else if (this.bitsPerPixel == 4) {
|
||||
this.imageType = 5;
|
||||
} else if (this.bitsPerPixel == 8) {
|
||||
this.imageType = 6;
|
||||
} else if (this.bitsPerPixel == 24) {
|
||||
this.imageType = 7;
|
||||
} else if (this.bitsPerPixel == 16) {
|
||||
this.imageType = 8;
|
||||
this.redMask = 31744;
|
||||
this.greenMask = 992;
|
||||
this.blueMask = 31;
|
||||
this.properties.put("red_mask", new Integer(this.redMask));
|
||||
this.properties.put("green_mask", new Integer(this.greenMask));
|
||||
this.properties.put("blue_mask", new Integer(this.blueMask));
|
||||
} else if (this.bitsPerPixel == 32) {
|
||||
this.imageType = 9;
|
||||
this.redMask = 16711680;
|
||||
this.greenMask = 65280;
|
||||
this.blueMask = 255;
|
||||
this.properties.put("red_mask", new Integer(this.redMask));
|
||||
this.properties.put("green_mask", new Integer(this.greenMask));
|
||||
this.properties.put("blue_mask", new Integer(this.blueMask));
|
||||
}
|
||||
this.properties.put("bmp_version", "BMP v. 3.x");
|
||||
break;
|
||||
case 3:
|
||||
if (this.bitsPerPixel == 16) {
|
||||
this.imageType = 8;
|
||||
} else if (this.bitsPerPixel == 32) {
|
||||
this.imageType = 9;
|
||||
}
|
||||
this.redMask = (int)readDWord(this.inputStream);
|
||||
this.greenMask = (int)readDWord(this.inputStream);
|
||||
this.blueMask = (int)readDWord(this.inputStream);
|
||||
this.properties.put("red_mask", new Integer(this.redMask));
|
||||
this.properties.put("green_mask", new Integer(this.greenMask));
|
||||
this.properties.put("blue_mask", new Integer(this.blueMask));
|
||||
if (colorsUsed != 0L) {
|
||||
sizeOfPalette = (int)colorsUsed * 4;
|
||||
this.palette = new byte[sizeOfPalette];
|
||||
this.inputStream.read(this.palette, 0, sizeOfPalette);
|
||||
this.properties.put("palette", this.palette);
|
||||
}
|
||||
this.properties.put("bmp_version", "BMP v. 3.x NT");
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException(JaiI18N.getString("BMPImageDecoder1"));
|
||||
}
|
||||
} else if (size == 108L) {
|
||||
this.properties.put("bmp_version", "BMP v. 4.x");
|
||||
this.redMask = (int)readDWord(this.inputStream);
|
||||
this.greenMask = (int)readDWord(this.inputStream);
|
||||
this.blueMask = (int)readDWord(this.inputStream);
|
||||
this.alphaMask = (int)readDWord(this.inputStream);
|
||||
long csType = readDWord(this.inputStream);
|
||||
int redX = readLong(this.inputStream);
|
||||
int redY = readLong(this.inputStream);
|
||||
int redZ = readLong(this.inputStream);
|
||||
int greenX = readLong(this.inputStream);
|
||||
int greenY = readLong(this.inputStream);
|
||||
int greenZ = readLong(this.inputStream);
|
||||
int blueX = readLong(this.inputStream);
|
||||
int blueY = readLong(this.inputStream);
|
||||
int blueZ = readLong(this.inputStream);
|
||||
long gammaRed = readDWord(this.inputStream);
|
||||
long gammaGreen = readDWord(this.inputStream);
|
||||
long gammaBlue = readDWord(this.inputStream);
|
||||
int numberOfEntries = (int)((this.bitmapOffset - 14L - size) / 4L);
|
||||
int sizeOfPalette = numberOfEntries * 4;
|
||||
this.palette = new byte[sizeOfPalette];
|
||||
this.inputStream.read(this.palette, 0, sizeOfPalette);
|
||||
if (this.palette != null || this.palette.length != 0)
|
||||
this.properties.put("palette", this.palette);
|
||||
switch ((int)csType) {
|
||||
case 0:
|
||||
this.properties.put("color_space", "LCS_CALIBRATED_RGB");
|
||||
this.properties.put("redX", new Integer(redX));
|
||||
this.properties.put("redY", new Integer(redY));
|
||||
this.properties.put("redZ", new Integer(redZ));
|
||||
this.properties.put("greenX", new Integer(greenX));
|
||||
this.properties.put("greenY", new Integer(greenY));
|
||||
this.properties.put("greenZ", new Integer(greenZ));
|
||||
this.properties.put("blueX", new Integer(blueX));
|
||||
this.properties.put("blueY", new Integer(blueY));
|
||||
this.properties.put("blueZ", new Integer(blueZ));
|
||||
this.properties.put("gamma_red", new Long(gammaRed));
|
||||
this.properties.put("gamma_green", new Long(gammaGreen));
|
||||
this.properties.put("gamma_blue", new Long(gammaBlue));
|
||||
throw new RuntimeException(JaiI18N.getString("BMPImageDecoder2"));
|
||||
case 1:
|
||||
this.properties.put("color_space", "LCS_sRGB");
|
||||
break;
|
||||
case 2:
|
||||
this.properties.put("color_space", "LCS_CMYK");
|
||||
throw new RuntimeException(JaiI18N.getString("BMPImageDecoder2"));
|
||||
}
|
||||
if (this.bitsPerPixel == 1) {
|
||||
this.imageType = 10;
|
||||
} else if (this.bitsPerPixel == 4) {
|
||||
this.imageType = 11;
|
||||
} else if (this.bitsPerPixel == 8) {
|
||||
this.imageType = 12;
|
||||
} else if (this.bitsPerPixel == 16) {
|
||||
this.imageType = 13;
|
||||
if ((int)this.compression == 0) {
|
||||
this.redMask = 31744;
|
||||
this.greenMask = 992;
|
||||
this.blueMask = 31;
|
||||
}
|
||||
} else if (this.bitsPerPixel == 24) {
|
||||
this.imageType = 14;
|
||||
} else if (this.bitsPerPixel == 32) {
|
||||
this.imageType = 15;
|
||||
if ((int)this.compression == 0) {
|
||||
this.redMask = 16711680;
|
||||
this.greenMask = 65280;
|
||||
this.blueMask = 255;
|
||||
}
|
||||
}
|
||||
this.properties.put("red_mask", new Integer(this.redMask));
|
||||
this.properties.put("green_mask", new Integer(this.greenMask));
|
||||
this.properties.put("blue_mask", new Integer(this.blueMask));
|
||||
this.properties.put("alpha_mask", new Integer(this.alphaMask));
|
||||
} else {
|
||||
this.properties.put("bmp_version", "BMP v. 5.x");
|
||||
throw new RuntimeException(JaiI18N.getString("BMPImageDecoder4"));
|
||||
}
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
String message = JaiI18N.getString("BMPImageDecoder5");
|
||||
ImagingListenerProxy.errorOccurred(message, new ImagingException(message, ioe), this, false);
|
||||
}
|
||||
if (this.height > 0) {
|
||||
this.isBottomUp = true;
|
||||
} else {
|
||||
this.isBottomUp = false;
|
||||
this.height = Math.abs(this.height);
|
||||
}
|
||||
this.tileWidth = this.width;
|
||||
this.tileHeight = this.height;
|
||||
if (this.bitsPerPixel == 1 || this.bitsPerPixel == 4 || this.bitsPerPixel == 8) {
|
||||
byte[] r, g, b;
|
||||
int size;
|
||||
this.numBands = 1;
|
||||
if (this.bitsPerPixel == 8) {
|
||||
this.sampleModel = RasterFactory.createPixelInterleavedSampleModel(0, this.width, this.height, this.numBands);
|
||||
} else {
|
||||
this.sampleModel = new MultiPixelPackedSampleModel(0, this.width, this.height, this.bitsPerPixel);
|
||||
}
|
||||
if (this.imageType == 0 || this.imageType == 1 || this.imageType == 2) {
|
||||
size = this.palette.length / 3;
|
||||
if (size > 256)
|
||||
size = 256;
|
||||
r = new byte[size];
|
||||
g = new byte[size];
|
||||
b = new byte[size];
|
||||
for (int i = 0; i < size; i++) {
|
||||
int off = 3 * i;
|
||||
b[i] = this.palette[off];
|
||||
g[i] = this.palette[off + 1];
|
||||
r[i] = this.palette[off + 2];
|
||||
}
|
||||
} else {
|
||||
size = this.palette.length / 4;
|
||||
if (size > 256)
|
||||
size = 256;
|
||||
r = new byte[size];
|
||||
g = new byte[size];
|
||||
b = new byte[size];
|
||||
for (int i = 0; i < size; i++) {
|
||||
int off = 4 * i;
|
||||
b[i] = this.palette[off];
|
||||
g[i] = this.palette[off + 1];
|
||||
r[i] = this.palette[off + 2];
|
||||
}
|
||||
}
|
||||
if (ImageCodec.isIndicesForGrayscale(r, g, b)) {
|
||||
this.colorModel = ImageCodec.createComponentColorModel(this.sampleModel);
|
||||
} else {
|
||||
this.colorModel = new IndexColorModel(this.bitsPerPixel, size, r, g, b);
|
||||
}
|
||||
} else if (this.bitsPerPixel == 16) {
|
||||
this.numBands = 3;
|
||||
this.sampleModel = new SinglePixelPackedSampleModel(1, this.width, this.height, new int[] { this.redMask, this.greenMask, this.blueMask });
|
||||
this.colorModel = new DirectColorModel(ColorSpace.getInstance(1000), 16, this.redMask, this.greenMask, this.blueMask, 0, false, 1);
|
||||
} else if (this.bitsPerPixel == 32) {
|
||||
this.numBands = (this.alphaMask == 0) ? 3 : 4;
|
||||
int[] bitMasks = (this.numBands == 3) ? new int[] { this.redMask, this.greenMask, this.blueMask } : new int[] { this.redMask, this.greenMask, this.blueMask, this.alphaMask };
|
||||
this.sampleModel = new SinglePixelPackedSampleModel(3, this.width, this.height, bitMasks);
|
||||
this.colorModel = new DirectColorModel(ColorSpace.getInstance(1000), 32, this.redMask, this.greenMask, this.blueMask, this.alphaMask, false, 3);
|
||||
} else {
|
||||
this.numBands = 3;
|
||||
this.sampleModel = RasterFactory.createPixelInterleavedSampleModel(0, this.width, this.height, this.numBands);
|
||||
this.colorModel = ImageCodec.createComponentColorModel(this.sampleModel);
|
||||
}
|
||||
try {
|
||||
this.inputStream.reset();
|
||||
this.inputStream.skip(this.bitmapOffset);
|
||||
} catch (IOException ioe) {
|
||||
String message = JaiI18N.getString("BMPImageDecoder9");
|
||||
ImagingListenerProxy.errorOccurred(message, new ImagingException(message, ioe), this, false);
|
||||
}
|
||||
}
|
||||
|
||||
private void read1Bit(byte[] bdata, int paletteEntries) {
|
||||
int padding = 0;
|
||||
int bytesPerScanline = (int)Math.ceil((double)this.width / 8.0D);
|
||||
int remainder = bytesPerScanline % 4;
|
||||
if (remainder != 0)
|
||||
padding = 4 - remainder;
|
||||
int imSize = (bytesPerScanline + padding) * this.height;
|
||||
byte[] values = new byte[imSize];
|
||||
try {
|
||||
int bytesRead = 0;
|
||||
while (bytesRead < imSize)
|
||||
bytesRead += this.inputStream.read(values, bytesRead, imSize - bytesRead);
|
||||
} catch (IOException ioe) {
|
||||
String message = JaiI18N.getString("BMPImageDecoder6");
|
||||
ImagingListenerProxy.errorOccurred(message, new ImagingException(message, ioe), this, false);
|
||||
}
|
||||
if (this.isBottomUp) {
|
||||
for (int i = 0; i < this.height; i++)
|
||||
System.arraycopy(values, imSize - (i + 1) * (bytesPerScanline + padding), bdata, i * bytesPerScanline, bytesPerScanline);
|
||||
} else {
|
||||
for (int i = 0; i < this.height; i++)
|
||||
System.arraycopy(values, i * (bytesPerScanline + padding), bdata, i * bytesPerScanline, bytesPerScanline);
|
||||
}
|
||||
}
|
||||
|
||||
private void read4Bit(byte[] bdata, int paletteEntries) {
|
||||
int padding = 0;
|
||||
int bytesPerScanline = (int)Math.ceil((double)this.width / 2.0D);
|
||||
int remainder = bytesPerScanline % 4;
|
||||
if (remainder != 0)
|
||||
padding = 4 - remainder;
|
||||
int imSize = (bytesPerScanline + padding) * this.height;
|
||||
byte[] values = new byte[imSize];
|
||||
try {
|
||||
int bytesRead = 0;
|
||||
while (bytesRead < imSize)
|
||||
bytesRead += this.inputStream.read(values, bytesRead, imSize - bytesRead);
|
||||
} catch (IOException ioe) {
|
||||
String message = JaiI18N.getString("BMPImageDecoder6");
|
||||
ImagingListenerProxy.errorOccurred(message, new ImagingException(message, ioe), this, false);
|
||||
}
|
||||
if (this.isBottomUp) {
|
||||
for (int i = 0; i < this.height; i++)
|
||||
System.arraycopy(values, imSize - (i + 1) * (bytesPerScanline + padding), bdata, i * bytesPerScanline, bytesPerScanline);
|
||||
} else {
|
||||
for (int i = 0; i < this.height; i++)
|
||||
System.arraycopy(values, i * (bytesPerScanline + padding), bdata, i * bytesPerScanline, bytesPerScanline);
|
||||
}
|
||||
}
|
||||
|
||||
private void read8Bit(byte[] bdata, int paletteEntries) {
|
||||
int padding = 0;
|
||||
int bitsPerScanline = this.width * 8;
|
||||
if (bitsPerScanline % 32 != 0) {
|
||||
padding = (bitsPerScanline / 32 + 1) * 32 - bitsPerScanline;
|
||||
padding = (int)Math.ceil((double)padding / 8.0D);
|
||||
}
|
||||
int imSize = (this.width + padding) * this.height;
|
||||
byte[] values = new byte[imSize];
|
||||
try {
|
||||
int bytesRead = 0;
|
||||
while (bytesRead < imSize)
|
||||
bytesRead += this.inputStream.read(values, bytesRead, imSize - bytesRead);
|
||||
} catch (IOException ioe) {
|
||||
String message = JaiI18N.getString("BMPImageDecoder6");
|
||||
ImagingListenerProxy.errorOccurred(message, new ImagingException(message, ioe), this, false);
|
||||
}
|
||||
if (this.isBottomUp) {
|
||||
for (int i = 0; i < this.height; i++)
|
||||
System.arraycopy(values, imSize - (i + 1) * (this.width + padding), bdata, i * this.width, this.width);
|
||||
} else {
|
||||
for (int i = 0; i < this.height; i++)
|
||||
System.arraycopy(values, i * (this.width + padding), bdata, i * this.width, this.width);
|
||||
}
|
||||
}
|
||||
|
||||
private void read24Bit(byte[] bdata) {
|
||||
int padding = 0;
|
||||
int bitsPerScanline = this.width * 24;
|
||||
if (bitsPerScanline % 32 != 0) {
|
||||
padding = (bitsPerScanline / 32 + 1) * 32 - bitsPerScanline;
|
||||
padding = (int)Math.ceil((double)padding / 8.0D);
|
||||
}
|
||||
int imSize = (int)this.imageSize;
|
||||
if (imSize == 0)
|
||||
imSize = (int)(this.bitmapFileSize - this.bitmapOffset);
|
||||
byte[] values = new byte[imSize];
|
||||
try {
|
||||
int bytesRead = 0;
|
||||
while (bytesRead < imSize)
|
||||
bytesRead += this.inputStream.read(values, bytesRead, imSize - bytesRead);
|
||||
} catch (IOException ioe) {
|
||||
String message = JaiI18N.getString("BMPImageDecoder4");
|
||||
ImagingListenerProxy.errorOccurred(message, new ImagingException(message, ioe), this, false);
|
||||
}
|
||||
int l = 0;
|
||||
if (this.isBottomUp) {
|
||||
int max = this.width * this.height * 3 - 1;
|
||||
int count = -padding;
|
||||
for (int i = 0; i < this.height; i++) {
|
||||
l = max - (i + 1) * this.width * 3 + 1;
|
||||
count += padding;
|
||||
for (int j = 0; j < this.width; j++) {
|
||||
bdata[l++] = values[count++];
|
||||
bdata[l++] = values[count++];
|
||||
bdata[l++] = values[count++];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int count = -padding;
|
||||
for (int i = 0; i < this.height; i++) {
|
||||
count += padding;
|
||||
for (int j = 0; j < this.width; j++) {
|
||||
bdata[l++] = values[count++];
|
||||
bdata[l++] = values[count++];
|
||||
bdata[l++] = values[count++];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void read16Bit(short[] sdata) {
|
||||
int padding = 0;
|
||||
int bitsPerScanline = this.width * 16;
|
||||
if (bitsPerScanline % 32 != 0) {
|
||||
padding = (bitsPerScanline / 32 + 1) * 32 - bitsPerScanline;
|
||||
padding = (int)Math.ceil((double)padding / 8.0D);
|
||||
}
|
||||
int imSize = (int)this.imageSize;
|
||||
if (imSize == 0)
|
||||
imSize = (int)(this.bitmapFileSize - this.bitmapOffset);
|
||||
int l = 0;
|
||||
try {
|
||||
if (this.isBottomUp) {
|
||||
int max = this.width * this.height - 1;
|
||||
for (int i = 0; i < this.height; i++) {
|
||||
l = max - (i + 1) * this.width + 1;
|
||||
for (int j = 0; j < this.width; j++)
|
||||
sdata[l++] = (short)(readWord(this.inputStream) & 0xFFFF);
|
||||
for (int m = 0; m < padding; m++)
|
||||
this.inputStream.read();
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < this.height; i++) {
|
||||
for (int j = 0; j < this.width; j++)
|
||||
sdata[l++] = (short)(readWord(this.inputStream) & 0xFFFF);
|
||||
for (int m = 0; m < padding; m++)
|
||||
this.inputStream.read();
|
||||
}
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
String message = JaiI18N.getString("BMPImageDecoder6");
|
||||
ImagingListenerProxy.errorOccurred(message, new ImagingException(message, ioe), this, false);
|
||||
}
|
||||
}
|
||||
|
||||
private void read32Bit(int[] idata) {
|
||||
int imSize = (int)this.imageSize;
|
||||
if (imSize == 0)
|
||||
imSize = (int)(this.bitmapFileSize - this.bitmapOffset);
|
||||
int l = 0;
|
||||
try {
|
||||
if (this.isBottomUp) {
|
||||
int max = this.width * this.height - 1;
|
||||
for (int i = 0; i < this.height; i++) {
|
||||
l = max - (i + 1) * this.width + 1;
|
||||
for (int j = 0; j < this.width; j++)
|
||||
idata[l++] = (int)readDWord(this.inputStream);
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < this.height; i++) {
|
||||
for (int j = 0; j < this.width; j++)
|
||||
idata[l++] = (int)readDWord(this.inputStream);
|
||||
}
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
String message = JaiI18N.getString("BMPImageDecoder6");
|
||||
ImagingListenerProxy.errorOccurred(message, new ImagingException(message, ioe), this, false);
|
||||
}
|
||||
}
|
||||
|
||||
private void readRLE8(byte[] bdata) {
|
||||
int imSize = (int)this.imageSize;
|
||||
if (imSize == 0)
|
||||
imSize = (int)(this.bitmapFileSize - this.bitmapOffset);
|
||||
int padding = 0;
|
||||
int remainder = this.width % 4;
|
||||
if (remainder != 0)
|
||||
padding = 4 - remainder;
|
||||
byte[] values = new byte[imSize];
|
||||
try {
|
||||
int bytesRead = 0;
|
||||
while (bytesRead < imSize)
|
||||
bytesRead += this.inputStream.read(values, bytesRead, imSize - bytesRead);
|
||||
} catch (IOException ioe) {
|
||||
String message = JaiI18N.getString("BMPImageDecoder6");
|
||||
ImagingListenerProxy.errorOccurred(message, new ImagingException(message, ioe), this, false);
|
||||
}
|
||||
byte[] val = decodeRLE8(imSize, padding, values);
|
||||
imSize = this.width * this.height;
|
||||
if (this.isBottomUp) {
|
||||
int bytesPerScanline = this.width;
|
||||
for (int i = 0; i < this.height; i++)
|
||||
System.arraycopy(val, imSize - (i + 1) * bytesPerScanline, bdata, i * bytesPerScanline, bytesPerScanline);
|
||||
} else {
|
||||
bdata = val;
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] decodeRLE8(int imSize, int padding, byte[] values) {
|
||||
byte[] val = new byte[this.width * this.height];
|
||||
int count = 0, l = 0;
|
||||
boolean flag = false;
|
||||
while (count != imSize) {
|
||||
int value = values[count++] & 0xFF;
|
||||
if (value == 0) {
|
||||
int xoff, yoff, end, i;
|
||||
switch (values[count++] & 0xFF) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
flag = true;
|
||||
break;
|
||||
case 2:
|
||||
xoff = values[count++] & 0xFF;
|
||||
yoff = values[count] & 0xFF;
|
||||
l += xoff + yoff * this.width;
|
||||
break;
|
||||
default:
|
||||
end = values[count - 1] & 0xFF;
|
||||
for (i = 0; i < end; i++)
|
||||
val[l++] = (byte)(values[count++] & 0xFF);
|
||||
if (!isEven(end))
|
||||
count++;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < value; i++)
|
||||
val[l++] = (byte)(values[count] & 0xFF);
|
||||
count++;
|
||||
}
|
||||
if (flag)
|
||||
break;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
private int[] readRLE4() {
|
||||
int imSize = (int)this.imageSize;
|
||||
if (imSize == 0)
|
||||
imSize = (int)(this.bitmapFileSize - this.bitmapOffset);
|
||||
int padding = 0;
|
||||
int remainder = this.width % 4;
|
||||
if (remainder != 0)
|
||||
padding = 4 - remainder;
|
||||
int[] values = new int[imSize];
|
||||
try {
|
||||
for (int i = 0; i < imSize; i++)
|
||||
values[i] = this.inputStream.read();
|
||||
} catch (IOException ioe) {
|
||||
String message = JaiI18N.getString("BMPImageDecoder6");
|
||||
ImagingListenerProxy.errorOccurred(message, new ImagingException(message, ioe), this, false);
|
||||
}
|
||||
int[] val = decodeRLE4(imSize, padding, values);
|
||||
if (this.isBottomUp) {
|
||||
int[] inverted = val;
|
||||
val = new int[this.width * this.height];
|
||||
int l = 0;
|
||||
for (int i = this.height - 1; i >= 0; i--) {
|
||||
int index = i * this.width;
|
||||
int lineEnd = l + this.width;
|
||||
while (l != lineEnd)
|
||||
val[l++] = inverted[index++];
|
||||
}
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
private int[] decodeRLE4(int imSize, int padding, int[] values) {
|
||||
int[] val = new int[this.width * this.height];
|
||||
int count = 0, l = 0;
|
||||
boolean flag = false;
|
||||
while (count != imSize) {
|
||||
int value = values[count++];
|
||||
if (value == 0) {
|
||||
int xoff, yoff, end, i;
|
||||
switch (values[count++]) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
flag = true;
|
||||
break;
|
||||
case 2:
|
||||
xoff = values[count++];
|
||||
yoff = values[count];
|
||||
l += xoff + yoff * this.width;
|
||||
break;
|
||||
default:
|
||||
end = values[count - 1];
|
||||
for (i = 0; i < end; i++)
|
||||
val[l++] = isEven(i) ? ((values[count] & 0xF0) >> 4) : (values[count++] & 0xF);
|
||||
if (!isEven(end))
|
||||
count++;
|
||||
if (!isEven((int)Math.ceil((double)(end / 2))))
|
||||
count++;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
int[] alternate = { (values[count] & 0xF0) >> 4, values[count] & 0xF };
|
||||
for (int i = 0; i < value; i++)
|
||||
val[l++] = alternate[i % 2];
|
||||
count++;
|
||||
}
|
||||
if (flag)
|
||||
break;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
private boolean isEven(int number) {
|
||||
return (number % 2 == 0);
|
||||
}
|
||||
|
||||
private int readUnsignedByte(InputStream stream) throws IOException {
|
||||
return stream.read() & 0xFF;
|
||||
}
|
||||
|
||||
private int readUnsignedShort(InputStream stream) throws IOException {
|
||||
int b1 = readUnsignedByte(stream);
|
||||
int b2 = readUnsignedByte(stream);
|
||||
return (b2 << 8 | b1) & 0xFFFF;
|
||||
}
|
||||
|
||||
private int readShort(InputStream stream) throws IOException {
|
||||
int b1 = readUnsignedByte(stream);
|
||||
int b2 = readUnsignedByte(stream);
|
||||
return b2 << 8 | b1;
|
||||
}
|
||||
|
||||
private int readWord(InputStream stream) throws IOException {
|
||||
return readUnsignedShort(stream);
|
||||
}
|
||||
|
||||
private long readUnsignedInt(InputStream stream) throws IOException {
|
||||
int b1 = readUnsignedByte(stream);
|
||||
int b2 = readUnsignedByte(stream);
|
||||
int b3 = readUnsignedByte(stream);
|
||||
int b4 = readUnsignedByte(stream);
|
||||
long l = (long)(b4 << 24 | b3 << 16 | b2 << 8 | b1);
|
||||
return l & 0xFFFFFFFFFFFFFFFFL;
|
||||
}
|
||||
|
||||
private int readInt(InputStream stream) throws IOException {
|
||||
int b1 = readUnsignedByte(stream);
|
||||
int b2 = readUnsignedByte(stream);
|
||||
int b3 = readUnsignedByte(stream);
|
||||
int b4 = readUnsignedByte(stream);
|
||||
return b4 << 24 | b3 << 16 | b2 << 8 | b1;
|
||||
}
|
||||
|
||||
private long readDWord(InputStream stream) throws IOException {
|
||||
return readUnsignedInt(stream);
|
||||
}
|
||||
|
||||
private int readLong(InputStream stream) throws IOException {
|
||||
return readInt(stream);
|
||||
}
|
||||
|
||||
private synchronized Raster computeTile(int tileX, int tileY) {
|
||||
int[] pixels;
|
||||
if (this.theTile != null)
|
||||
return this.theTile;
|
||||
Point org = new Point(tileXToX(tileX), tileYToY(tileY));
|
||||
WritableRaster tile = RasterFactory.createWritableRaster(this.sampleModel, org);
|
||||
byte[] bdata = null;
|
||||
short[] sdata = null;
|
||||
int[] idata = null;
|
||||
if (this.sampleModel.getDataType() == 0) {
|
||||
bdata = ((DataBufferByte)tile.getDataBuffer()).getData();
|
||||
} else if (this.sampleModel.getDataType() == 1) {
|
||||
sdata = ((DataBufferUShort)tile.getDataBuffer()).getData();
|
||||
} else if (this.sampleModel.getDataType() == 3) {
|
||||
idata = ((DataBufferInt)tile.getDataBuffer()).getData();
|
||||
}
|
||||
switch (this.imageType) {
|
||||
case 0:
|
||||
read1Bit(bdata, 3);
|
||||
break;
|
||||
case 1:
|
||||
read4Bit(bdata, 3);
|
||||
break;
|
||||
case 2:
|
||||
read8Bit(bdata, 3);
|
||||
break;
|
||||
case 3:
|
||||
read24Bit(bdata);
|
||||
break;
|
||||
case 4:
|
||||
read1Bit(bdata, 4);
|
||||
break;
|
||||
case 5:
|
||||
switch ((int)this.compression) {
|
||||
case 0:
|
||||
read4Bit(bdata, 4);
|
||||
break;
|
||||
case 2:
|
||||
pixels = readRLE4();
|
||||
tile.setPixels(0, 0, this.width, this.height, pixels);
|
||||
break;
|
||||
}
|
||||
throw new RuntimeException(JaiI18N.getString("BMPImageDecoder3"));
|
||||
case 6:
|
||||
switch ((int)this.compression) {
|
||||
case 0:
|
||||
read8Bit(bdata, 4);
|
||||
break;
|
||||
case 1:
|
||||
readRLE8(bdata);
|
||||
break;
|
||||
}
|
||||
throw new RuntimeException(JaiI18N.getString("BMPImageDecoder3"));
|
||||
case 7:
|
||||
read24Bit(bdata);
|
||||
break;
|
||||
case 8:
|
||||
read16Bit(sdata);
|
||||
break;
|
||||
case 9:
|
||||
read32Bit(idata);
|
||||
break;
|
||||
case 10:
|
||||
read1Bit(bdata, 4);
|
||||
break;
|
||||
case 11:
|
||||
switch ((int)this.compression) {
|
||||
case 0:
|
||||
read4Bit(bdata, 4);
|
||||
break;
|
||||
case 2:
|
||||
pixels = readRLE4();
|
||||
tile.setPixels(0, 0, this.width, this.height, pixels);
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException(JaiI18N.getString("BMPImageDecoder3"));
|
||||
}
|
||||
case 12:
|
||||
switch ((int)this.compression) {
|
||||
case 0:
|
||||
read8Bit(bdata, 4);
|
||||
break;
|
||||
case 1:
|
||||
readRLE8(bdata);
|
||||
break;
|
||||
}
|
||||
throw new RuntimeException(JaiI18N.getString("BMPImageDecoder3"));
|
||||
case 13:
|
||||
read16Bit(sdata);
|
||||
break;
|
||||
case 14:
|
||||
read24Bit(bdata);
|
||||
break;
|
||||
case 15:
|
||||
read32Bit(idata);
|
||||
break;
|
||||
}
|
||||
this.theTile = tile;
|
||||
return tile;
|
||||
}
|
||||
|
||||
public synchronized Raster getTile(int tileX, int tileY) {
|
||||
if (tileX != 0 || tileY != 0)
|
||||
throw new IllegalArgumentException(JaiI18N.getString("BMPImageDecoder7"));
|
||||
return computeTile(tileX, tileY);
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
this.theTile = null;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
package com.sun.media.jai.codecimpl;
|
||||
|
||||
import com.sun.media.jai.codec.ImageDecodeParam;
|
||||
import com.sun.media.jai.codec.ImageDecoderImpl;
|
||||
import java.awt.image.RenderedImage;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
public class BMPImageDecoder extends ImageDecoderImpl {
|
||||
public BMPImageDecoder(InputStream input, ImageDecodeParam param) {
|
||||
super(input, param);
|
||||
}
|
||||
|
||||
public RenderedImage decodeAsRenderedImage(int page) throws IOException {
|
||||
if (page != 0)
|
||||
throw new IOException(JaiI18N.getString("BMPImageDecoder8"));
|
||||
try {
|
||||
return new BMPImage(this.input);
|
||||
} catch (Exception e) {
|
||||
throw CodecUtils.toIOException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,671 @@
|
|||
package com.sun.media.jai.codecimpl;
|
||||
|
||||
import com.sun.media.jai.codec.BMPEncodeParam;
|
||||
import com.sun.media.jai.codec.ImageEncodeParam;
|
||||
import com.sun.media.jai.codec.ImageEncoderImpl;
|
||||
import com.sun.media.jai.codec.SeekableOutputStream;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.image.ColorModel;
|
||||
import java.awt.image.DataBuffer;
|
||||
import java.awt.image.DataBufferInt;
|
||||
import java.awt.image.DataBufferShort;
|
||||
import java.awt.image.DataBufferUShort;
|
||||
import java.awt.image.DirectColorModel;
|
||||
import java.awt.image.IndexColorModel;
|
||||
import java.awt.image.Raster;
|
||||
import java.awt.image.RenderedImage;
|
||||
import java.awt.image.SampleModel;
|
||||
import java.awt.image.SinglePixelPackedSampleModel;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
public class BMPImageEncoder extends ImageEncoderImpl {
|
||||
private OutputStream output;
|
||||
|
||||
private int version;
|
||||
|
||||
private boolean isCompressed;
|
||||
|
||||
private boolean isTopDown;
|
||||
|
||||
private int w;
|
||||
|
||||
private int h;
|
||||
|
||||
private int compImageSize;
|
||||
|
||||
public BMPImageEncoder(OutputStream output, ImageEncodeParam param) {
|
||||
super(output, param);
|
||||
BMPEncodeParam bmpParam;
|
||||
this.compImageSize = 0;
|
||||
this.output = output;
|
||||
if (param == null) {
|
||||
bmpParam = new BMPEncodeParam();
|
||||
} else {
|
||||
bmpParam = (BMPEncodeParam)param;
|
||||
}
|
||||
this.version = bmpParam.getVersion();
|
||||
this.isCompressed = bmpParam.isCompressed();
|
||||
if (this.isCompressed && !(output instanceof SeekableOutputStream))
|
||||
throw new IllegalArgumentException(JaiI18N.getString("BMPImageEncoder6"));
|
||||
this.isTopDown = bmpParam.isTopDown();
|
||||
}
|
||||
|
||||
public void encode(RenderedImage im) throws IOException {
|
||||
int minX = im.getMinX();
|
||||
int minY = im.getMinY();
|
||||
this.w = im.getWidth();
|
||||
this.h = im.getHeight();
|
||||
int bitsPerPixel = 24;
|
||||
boolean isPalette = false;
|
||||
int paletteEntries = 0;
|
||||
IndexColorModel icm = null;
|
||||
SampleModel sm = im.getSampleModel();
|
||||
int numBands = sm.getNumBands();
|
||||
ColorModel cm = im.getColorModel();
|
||||
if (numBands != 1 && numBands != 3)
|
||||
throw new IllegalArgumentException(JaiI18N.getString("BMPImageEncoder1"));
|
||||
int[] sampleSize = sm.getSampleSize();
|
||||
if (sampleSize[0] > 8)
|
||||
throw new RuntimeException(JaiI18N.getString("BMPImageEncoder2"));
|
||||
for (int i = 1; i < sampleSize.length; i++) {
|
||||
if (sampleSize[i] != sampleSize[0])
|
||||
throw new RuntimeException(JaiI18N.getString("BMPImageEncoder3"));
|
||||
}
|
||||
int dataType = sm.getTransferType();
|
||||
if (dataType != 0 && !CodecUtils.isPackedByteImage(im))
|
||||
throw new RuntimeException(JaiI18N.getString("BMPImageEncoder0"));
|
||||
int destScanlineBytes = this.w * numBands;
|
||||
int compression = 0;
|
||||
byte[] r = null, g = null, b = null, a = null;
|
||||
if (cm instanceof IndexColorModel) {
|
||||
isPalette = true;
|
||||
icm = (IndexColorModel)cm;
|
||||
paletteEntries = icm.getMapSize();
|
||||
if (paletteEntries <= 2) {
|
||||
bitsPerPixel = 1;
|
||||
destScanlineBytes = (int)Math.ceil((double)this.w / 8.0D);
|
||||
} else if (paletteEntries <= 16) {
|
||||
bitsPerPixel = 4;
|
||||
destScanlineBytes = (int)Math.ceil((double)this.w / 2.0D);
|
||||
} else if (paletteEntries <= 256) {
|
||||
bitsPerPixel = 8;
|
||||
} else {
|
||||
bitsPerPixel = 24;
|
||||
isPalette = false;
|
||||
paletteEntries = 0;
|
||||
destScanlineBytes = this.w * 3;
|
||||
}
|
||||
if (isPalette == true) {
|
||||
r = new byte[paletteEntries];
|
||||
g = new byte[paletteEntries];
|
||||
b = new byte[paletteEntries];
|
||||
a = new byte[paletteEntries];
|
||||
icm.getAlphas(a);
|
||||
icm.getReds(r);
|
||||
icm.getGreens(g);
|
||||
icm.getBlues(b);
|
||||
}
|
||||
} else if (numBands == 1) {
|
||||
isPalette = true;
|
||||
paletteEntries = 256;
|
||||
bitsPerPixel = sampleSize[0];
|
||||
destScanlineBytes = (int)Math.ceil((double)(this.w * bitsPerPixel) / 8.0D);
|
||||
r = new byte[256];
|
||||
g = new byte[256];
|
||||
b = new byte[256];
|
||||
a = new byte[256];
|
||||
for (int j = 0; j < 256; j++) {
|
||||
r[j] = (byte)j;
|
||||
g[j] = (byte)j;
|
||||
b[j] = (byte)j;
|
||||
a[j] = -1;
|
||||
}
|
||||
} else if (sm instanceof SinglePixelPackedSampleModel) {
|
||||
bitsPerPixel = DataBuffer.getDataTypeSize(sm.getDataType());
|
||||
destScanlineBytes = this.w * bitsPerPixel + 7 >> 3;
|
||||
}
|
||||
int fileSize = 0;
|
||||
int offset = 0;
|
||||
int headerSize = 0;
|
||||
int imageSize = 0;
|
||||
int xPelsPerMeter = 0;
|
||||
int yPelsPerMeter = 0;
|
||||
int colorsUsed = 0;
|
||||
int colorsImportant = paletteEntries;
|
||||
int padding = 0;
|
||||
int remainder = destScanlineBytes % 4;
|
||||
if (remainder != 0)
|
||||
padding = 4 - remainder;
|
||||
switch (this.version) {
|
||||
case 0:
|
||||
offset = 26 + paletteEntries * 3;
|
||||
headerSize = 12;
|
||||
imageSize = (destScanlineBytes + padding) * this.h;
|
||||
fileSize = imageSize + offset;
|
||||
throw new RuntimeException(JaiI18N.getString("BMPImageEncoder5"));
|
||||
case 1:
|
||||
if (this.isCompressed && bitsPerPixel == 8) {
|
||||
compression = 1;
|
||||
} else if (this.isCompressed && bitsPerPixel == 4) {
|
||||
compression = 2;
|
||||
}
|
||||
offset = 54 + paletteEntries * 4;
|
||||
imageSize = (destScanlineBytes + padding) * this.h;
|
||||
fileSize = imageSize + offset;
|
||||
headerSize = 40;
|
||||
break;
|
||||
case 2:
|
||||
headerSize = 108;
|
||||
throw new RuntimeException(JaiI18N.getString("BMPImageEncoder5"));
|
||||
}
|
||||
int redMask = 0, blueMask = 0, greenMask = 0;
|
||||
if (cm instanceof DirectColorModel) {
|
||||
redMask = ((DirectColorModel)cm).getRedMask();
|
||||
greenMask = ((DirectColorModel)cm).getGreenMask();
|
||||
blueMask = ((DirectColorModel)cm).getBlueMask();
|
||||
destScanlineBytes = this.w;
|
||||
compression = 3;
|
||||
fileSize += 12;
|
||||
offset += 12;
|
||||
}
|
||||
writeFileHeader(fileSize, offset);
|
||||
writeInfoHeader(headerSize, bitsPerPixel);
|
||||
writeDWord(compression);
|
||||
writeDWord(imageSize);
|
||||
writeDWord(xPelsPerMeter);
|
||||
writeDWord(yPelsPerMeter);
|
||||
writeDWord(colorsUsed);
|
||||
writeDWord(colorsImportant);
|
||||
if (compression == 3) {
|
||||
writeDWord(redMask);
|
||||
writeDWord(greenMask);
|
||||
writeDWord(blueMask);
|
||||
}
|
||||
if (compression == 3) {
|
||||
for (int j = 0; j < this.h; j++) {
|
||||
short[] sdata;
|
||||
int m;
|
||||
short[] usdata;
|
||||
int k, idata[], n;
|
||||
int row = minY + j;
|
||||
if (!this.isTopDown)
|
||||
row = minY + this.h - j - 1;
|
||||
Rectangle srcRect = new Rectangle(minX, row, this.w, 1);
|
||||
Raster src = im.getData(srcRect);
|
||||
SampleModel sm1 = src.getSampleModel();
|
||||
int pos = 0;
|
||||
int startX = srcRect.x - src.getSampleModelTranslateX();
|
||||
int startY = srcRect.y - src.getSampleModelTranslateY();
|
||||
if (sm1 instanceof SinglePixelPackedSampleModel) {
|
||||
SinglePixelPackedSampleModel sppsm = (SinglePixelPackedSampleModel)sm1;
|
||||
pos = sppsm.getOffset(startX, startY);
|
||||
}
|
||||
switch (dataType) {
|
||||
case 2:
|
||||
sdata = ((DataBufferShort)src.getDataBuffer()).getData();
|
||||
for (m = 0; m < sdata.length; m++)
|
||||
writeWord(sdata[m]);
|
||||
break;
|
||||
case 1:
|
||||
usdata = ((DataBufferUShort)src.getDataBuffer()).getData();
|
||||
for (k = 0; k < usdata.length; k++)
|
||||
writeWord(usdata[k]);
|
||||
break;
|
||||
case 3:
|
||||
idata = ((DataBufferInt)src.getDataBuffer()).getData();
|
||||
for (n = 0; n < idata.length; n++)
|
||||
writeDWord(idata[n]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (isPalette == true) {
|
||||
int j;
|
||||
switch (this.version) {
|
||||
case 0:
|
||||
for (j = 0; j < paletteEntries; j++) {
|
||||
this.output.write(b[j]);
|
||||
this.output.write(g[j]);
|
||||
this.output.write(r[j]);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
for (j = 0; j < paletteEntries; j++) {
|
||||
this.output.write(b[j]);
|
||||
this.output.write(g[j]);
|
||||
this.output.write(r[j]);
|
||||
this.output.write(a[j]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
int scanlineBytes = this.w * numBands;
|
||||
int[] pixels = new int[8 * scanlineBytes];
|
||||
byte[] bpixels = new byte[destScanlineBytes];
|
||||
if (!this.isTopDown) {
|
||||
int lastRow = minY + this.h;
|
||||
for (int row = lastRow - 1; row >= minY; row -= 8) {
|
||||
int rows = Math.min(8, row - minY + 1);
|
||||
Raster src = im.getData(new Rectangle(minX, row - rows + 1, this.w, rows));
|
||||
src.getPixels(minX, row - rows + 1, this.w, rows, pixels);
|
||||
int l = 0;
|
||||
int max = scanlineBytes * rows - 1;
|
||||
for (int j = 0; j < rows; j++) {
|
||||
l = max - (j + 1) * scanlineBytes + 1;
|
||||
writePixels(l, scanlineBytes, bitsPerPixel, pixels, bpixels, padding, numBands, icm);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int lastRow = minY + this.h;
|
||||
for (int row = minY; row < lastRow; row += 8) {
|
||||
int rows = Math.min(8, lastRow - row);
|
||||
Raster src = im.getData(new Rectangle(minX, row, this.w, rows));
|
||||
src.getPixels(minX, row, this.w, rows, pixels);
|
||||
int l = 0;
|
||||
for (int j = 0; j < rows; j++)
|
||||
writePixels(l, scanlineBytes, bitsPerPixel, pixels, bpixels, padding, numBands, icm);
|
||||
}
|
||||
}
|
||||
if (this.isCompressed && (bitsPerPixel == 4 || bitsPerPixel == 8)) {
|
||||
this.output.write(0);
|
||||
this.output.write(1);
|
||||
incCompImageSize(2);
|
||||
imageSize = this.compImageSize;
|
||||
fileSize = this.compImageSize + offset;
|
||||
writeSize(fileSize, 2);
|
||||
writeSize(imageSize, 34);
|
||||
}
|
||||
}
|
||||
|
||||
private void writePixels(int l, int scanlineBytes, int bitsPerPixel, int[] pixels, byte[] bpixels, int padding, int numBands, IndexColorModel icm) throws IOException {
|
||||
int j, entries;
|
||||
byte[] r, g, b;
|
||||
int i;
|
||||
int pixel = 0;
|
||||
int k = 0;
|
||||
switch (bitsPerPixel) {
|
||||
case 1:
|
||||
for (j = 0; j < scanlineBytes / 8; j++)
|
||||
bpixels[k++] = (byte)(pixels[l++] << 7 | pixels[l++] << 6 | pixels[l++] << 5 | pixels[l++] << 4 | pixels[l++] << 3 | pixels[l++] << 2 | pixels[l++] << 1 | pixels[l++]);
|
||||
if (scanlineBytes % 8 > 0) {
|
||||
pixel = 0;
|
||||
for (int m = 0; m < scanlineBytes % 8; m++)
|
||||
pixel |= pixels[l++] << 7 - m;
|
||||
bpixels[k++] = (byte)pixel;
|
||||
}
|
||||
this.output.write(bpixels, 0, (scanlineBytes + 7) / 8);
|
||||
break;
|
||||
case 4:
|
||||
if (this.isCompressed) {
|
||||
byte[] bipixels = new byte[scanlineBytes];
|
||||
for (int h = 0; h < scanlineBytes; h++)
|
||||
bipixels[h] = (byte)pixels[l++];
|
||||
encodeRLE4(bipixels, scanlineBytes);
|
||||
break;
|
||||
}
|
||||
for (j = 0; j < scanlineBytes / 2; j++) {
|
||||
pixel = pixels[l++] << 4 | pixels[l++];
|
||||
bpixels[k++] = (byte)pixel;
|
||||
}
|
||||
if (scanlineBytes % 2 == 1) {
|
||||
pixel = pixels[l] << 4;
|
||||
bpixels[k++] = (byte)pixel;
|
||||
}
|
||||
this.output.write(bpixels, 0, (scanlineBytes + 1) / 2);
|
||||
break;
|
||||
case 8:
|
||||
if (this.isCompressed) {
|
||||
for (int h = 0; h < scanlineBytes; h++)
|
||||
bpixels[h] = (byte)pixels[l++];
|
||||
encodeRLE8(bpixels, scanlineBytes);
|
||||
break;
|
||||
}
|
||||
for (j = 0; j < scanlineBytes; j++)
|
||||
bpixels[j] = (byte)pixels[l++];
|
||||
this.output.write(bpixels, 0, scanlineBytes);
|
||||
break;
|
||||
case 24:
|
||||
if (numBands == 3) {
|
||||
for (int m = 0; m < scanlineBytes; m += 3) {
|
||||
bpixels[k++] = (byte)pixels[l + 2];
|
||||
bpixels[k++] = (byte)pixels[l + 1];
|
||||
bpixels[k++] = (byte)pixels[l];
|
||||
l += 3;
|
||||
}
|
||||
this.output.write(bpixels, 0, scanlineBytes);
|
||||
break;
|
||||
}
|
||||
entries = icm.getMapSize();
|
||||
r = new byte[entries];
|
||||
g = new byte[entries];
|
||||
b = new byte[entries];
|
||||
icm.getReds(r);
|
||||
icm.getGreens(g);
|
||||
icm.getBlues(b);
|
||||
for (i = 0; i < scanlineBytes; i++) {
|
||||
int index = pixels[l];
|
||||
bpixels[k++] = b[index];
|
||||
bpixels[k++] = g[index];
|
||||
bpixels[k++] = b[index];
|
||||
l++;
|
||||
}
|
||||
this.output.write(bpixels, 0, scanlineBytes * 3);
|
||||
break;
|
||||
}
|
||||
if (!this.isCompressed || (bitsPerPixel != 8 && bitsPerPixel != 4))
|
||||
for (int m = 0; m < padding; m++)
|
||||
this.output.write(0);
|
||||
}
|
||||
|
||||
private void encodeRLE8(byte[] bpixels, int scanlineBytes) throws IOException {
|
||||
int runCount = 1, absVal = -1, j = -1;
|
||||
byte runVal = 0, nextVal = 0;
|
||||
runVal = bpixels[++j];
|
||||
byte[] absBuf = new byte[256];
|
||||
while (j < scanlineBytes - 1) {
|
||||
nextVal = bpixels[++j];
|
||||
if (nextVal == runVal) {
|
||||
if (absVal >= 3) {
|
||||
this.output.write(0);
|
||||
this.output.write(absVal);
|
||||
incCompImageSize(2);
|
||||
for (int a = 0; a < absVal; a++) {
|
||||
this.output.write(absBuf[a]);
|
||||
incCompImageSize(1);
|
||||
}
|
||||
if (!isEven(absVal)) {
|
||||
this.output.write(0);
|
||||
incCompImageSize(1);
|
||||
}
|
||||
} else if (absVal > -1) {
|
||||
for (int b = 0; b < absVal; b++) {
|
||||
this.output.write(1);
|
||||
this.output.write(absBuf[b]);
|
||||
incCompImageSize(2);
|
||||
}
|
||||
}
|
||||
absVal = -1;
|
||||
runCount++;
|
||||
if (runCount == 256) {
|
||||
this.output.write(runCount - 1);
|
||||
this.output.write(runVal);
|
||||
incCompImageSize(2);
|
||||
runCount = 1;
|
||||
}
|
||||
} else {
|
||||
if (runCount > 1) {
|
||||
this.output.write(runCount);
|
||||
this.output.write(runVal);
|
||||
incCompImageSize(2);
|
||||
} else if (absVal < 0) {
|
||||
absBuf[++absVal] = runVal;
|
||||
absBuf[++absVal] = nextVal;
|
||||
} else if (absVal < 254) {
|
||||
absBuf[++absVal] = nextVal;
|
||||
} else {
|
||||
this.output.write(0);
|
||||
this.output.write(absVal + 1);
|
||||
incCompImageSize(2);
|
||||
for (int a = 0; a <= absVal; a++) {
|
||||
this.output.write(absBuf[a]);
|
||||
incCompImageSize(1);
|
||||
}
|
||||
this.output.write(0);
|
||||
incCompImageSize(1);
|
||||
absVal = -1;
|
||||
}
|
||||
runVal = nextVal;
|
||||
runCount = 1;
|
||||
}
|
||||
if (j == scanlineBytes - 1) {
|
||||
if (absVal == -1) {
|
||||
this.output.write(runCount);
|
||||
this.output.write(runVal);
|
||||
incCompImageSize(2);
|
||||
runCount = 1;
|
||||
} else if (absVal >= 2) {
|
||||
this.output.write(0);
|
||||
this.output.write(absVal + 1);
|
||||
incCompImageSize(2);
|
||||
for (int a = 0; a <= absVal; a++) {
|
||||
this.output.write(absBuf[a]);
|
||||
incCompImageSize(1);
|
||||
}
|
||||
if (!isEven(absVal + 1)) {
|
||||
this.output.write(0);
|
||||
incCompImageSize(1);
|
||||
}
|
||||
} else if (absVal > -1) {
|
||||
for (int b = 0; b <= absVal; b++) {
|
||||
this.output.write(1);
|
||||
this.output.write(absBuf[b]);
|
||||
incCompImageSize(2);
|
||||
}
|
||||
}
|
||||
this.output.write(0);
|
||||
this.output.write(0);
|
||||
incCompImageSize(2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void encodeRLE4(byte[] bipixels, int scanlineBytes) throws IOException {
|
||||
int runCount = 2, absVal = -1, j = -1, pixel = 0, q = 0;
|
||||
byte runVal1 = 0, runVal2 = 0, nextVal1 = 0, nextVal2 = 0;
|
||||
byte[] absBuf = new byte[256];
|
||||
runVal1 = bipixels[++j];
|
||||
runVal2 = bipixels[++j];
|
||||
while (j < scanlineBytes - 2) {
|
||||
nextVal1 = bipixels[++j];
|
||||
nextVal2 = bipixels[++j];
|
||||
if (nextVal1 == runVal1) {
|
||||
if (absVal >= 4) {
|
||||
this.output.write(0);
|
||||
this.output.write(absVal - 1);
|
||||
incCompImageSize(2);
|
||||
for (int a = 0; a < absVal - 2; a += 2) {
|
||||
pixel = absBuf[a] << 4 | absBuf[a + 1];
|
||||
this.output.write((byte)pixel);
|
||||
incCompImageSize(1);
|
||||
}
|
||||
if (!isEven(absVal - 1)) {
|
||||
q = absBuf[absVal - 2] << 4 | 0x0;
|
||||
this.output.write(q);
|
||||
incCompImageSize(1);
|
||||
}
|
||||
if (!isEven((int)Math.ceil((double)((absVal - 1) / 2)))) {
|
||||
this.output.write(0);
|
||||
incCompImageSize(1);
|
||||
}
|
||||
} else if (absVal > -1) {
|
||||
this.output.write(2);
|
||||
pixel = absBuf[0] << 4 | absBuf[1];
|
||||
this.output.write(pixel);
|
||||
incCompImageSize(2);
|
||||
}
|
||||
absVal = -1;
|
||||
if (nextVal2 == runVal2) {
|
||||
runCount += 2;
|
||||
if (runCount == 256) {
|
||||
this.output.write(runCount - 1);
|
||||
pixel = runVal1 << 4 | runVal2;
|
||||
this.output.write(pixel);
|
||||
incCompImageSize(2);
|
||||
runCount = 2;
|
||||
if (j < scanlineBytes - 1) {
|
||||
runVal1 = runVal2;
|
||||
runVal2 = bipixels[++j];
|
||||
} else {
|
||||
this.output.write(1);
|
||||
int r = runVal2 << 4 | 0x0;
|
||||
this.output.write(r);
|
||||
incCompImageSize(2);
|
||||
runCount = -1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
runCount++;
|
||||
pixel = runVal1 << 4 | runVal2;
|
||||
this.output.write(runCount);
|
||||
this.output.write(pixel);
|
||||
incCompImageSize(2);
|
||||
runCount = 2;
|
||||
runVal1 = nextVal2;
|
||||
if (j < scanlineBytes - 1) {
|
||||
runVal2 = bipixels[++j];
|
||||
} else {
|
||||
this.output.write(1);
|
||||
int r = nextVal2 << 4 | 0x0;
|
||||
this.output.write(r);
|
||||
incCompImageSize(2);
|
||||
runCount = -1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (runCount > 2) {
|
||||
pixel = runVal1 << 4 | runVal2;
|
||||
this.output.write(runCount);
|
||||
this.output.write(pixel);
|
||||
incCompImageSize(2);
|
||||
} else if (absVal < 0) {
|
||||
absBuf[++absVal] = runVal1;
|
||||
absBuf[++absVal] = runVal2;
|
||||
absBuf[++absVal] = nextVal1;
|
||||
absBuf[++absVal] = nextVal2;
|
||||
} else if (absVal < 253) {
|
||||
absBuf[++absVal] = nextVal1;
|
||||
absBuf[++absVal] = nextVal2;
|
||||
} else {
|
||||
this.output.write(0);
|
||||
this.output.write(absVal + 1);
|
||||
incCompImageSize(2);
|
||||
for (int a = 0; a < absVal; a += 2) {
|
||||
pixel = absBuf[a] << 4 | absBuf[a + 1];
|
||||
this.output.write((byte)pixel);
|
||||
incCompImageSize(1);
|
||||
}
|
||||
this.output.write(0);
|
||||
incCompImageSize(1);
|
||||
absVal = -1;
|
||||
}
|
||||
runVal1 = nextVal1;
|
||||
runVal2 = nextVal2;
|
||||
runCount = 2;
|
||||
}
|
||||
if (j >= scanlineBytes - 2) {
|
||||
if (absVal == -1 && runCount >= 2) {
|
||||
if (j == scanlineBytes - 2) {
|
||||
if (bipixels[++j] == runVal1) {
|
||||
runCount++;
|
||||
pixel = runVal1 << 4 | runVal2;
|
||||
this.output.write(runCount);
|
||||
this.output.write(pixel);
|
||||
incCompImageSize(2);
|
||||
} else {
|
||||
pixel = runVal1 << 4 | runVal2;
|
||||
this.output.write(runCount);
|
||||
this.output.write(pixel);
|
||||
this.output.write(1);
|
||||
pixel = bipixels[j] << 4 | 0x0;
|
||||
this.output.write(pixel);
|
||||
int n = bipixels[j] << 4 | 0x0;
|
||||
incCompImageSize(4);
|
||||
}
|
||||
} else {
|
||||
this.output.write(runCount);
|
||||
pixel = runVal1 << 4 | runVal2;
|
||||
this.output.write(pixel);
|
||||
incCompImageSize(2);
|
||||
}
|
||||
} else if (absVal > -1) {
|
||||
if (j == scanlineBytes - 2)
|
||||
absBuf[++absVal] = bipixels[++j];
|
||||
if (absVal >= 2) {
|
||||
this.output.write(0);
|
||||
this.output.write(absVal + 1);
|
||||
incCompImageSize(2);
|
||||
for (int a = 0; a < absVal; a += 2) {
|
||||
pixel = absBuf[a] << 4 | absBuf[a + 1];
|
||||
this.output.write((byte)pixel);
|
||||
incCompImageSize(1);
|
||||
}
|
||||
if (!isEven(absVal + 1)) {
|
||||
q = absBuf[absVal] << 4 | 0x0;
|
||||
this.output.write(q);
|
||||
incCompImageSize(1);
|
||||
}
|
||||
if (!isEven((int)Math.ceil((double)((absVal + 1) / 2)))) {
|
||||
this.output.write(0);
|
||||
incCompImageSize(1);
|
||||
}
|
||||
} else {
|
||||
int n;
|
||||
switch (absVal) {
|
||||
case 0:
|
||||
this.output.write(1);
|
||||
n = absBuf[0] << 4 | 0x0;
|
||||
this.output.write(n);
|
||||
incCompImageSize(2);
|
||||
break;
|
||||
case 1:
|
||||
this.output.write(2);
|
||||
pixel = absBuf[0] << 4 | absBuf[1];
|
||||
this.output.write(pixel);
|
||||
incCompImageSize(2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
this.output.write(0);
|
||||
this.output.write(0);
|
||||
incCompImageSize(2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized void incCompImageSize(int value) {
|
||||
this.compImageSize += value;
|
||||
}
|
||||
|
||||
private boolean isEven(int number) {
|
||||
return (number % 2 == 0);
|
||||
}
|
||||
|
||||
private void writeFileHeader(int fileSize, int offset) throws IOException {
|
||||
this.output.write(66);
|
||||
this.output.write(77);
|
||||
writeDWord(fileSize);
|
||||
this.output.write(0);
|
||||
this.output.write(0);
|
||||
this.output.write(0);
|
||||
this.output.write(0);
|
||||
writeDWord(offset);
|
||||
}
|
||||
|
||||
private void writeInfoHeader(int headerSize, int bitsPerPixel) throws IOException {
|
||||
writeDWord(headerSize);
|
||||
writeDWord(this.w);
|
||||
writeDWord(this.h);
|
||||
writeWord(1);
|
||||
writeWord(bitsPerPixel);
|
||||
}
|
||||
|
||||
public void writeWord(int word) throws IOException {
|
||||
this.output.write(word & 0xFF);
|
||||
this.output.write((word & 0xFF00) >> 8);
|
||||
}
|
||||
|
||||
public void writeDWord(int dword) throws IOException {
|
||||
this.output.write(dword & 0xFF);
|
||||
this.output.write((dword & 0xFF00) >> 8);
|
||||
this.output.write((dword & 0xFF0000) >> 16);
|
||||
this.output.write((dword & 0xFF000000) >> 24);
|
||||
}
|
||||
|
||||
private void writeSize(int dword, int offset) throws IOException {
|
||||
((SeekableOutputStream)this.output).seek((long)offset);
|
||||
writeDWord(dword);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
package com.sun.media.jai.codecimpl;
|
||||
|
||||
class CRC {
|
||||
private static int[] crcTable = new int[256];
|
||||
|
||||
static {
|
||||
for (int n = 0; n < 256; n++) {
|
||||
int c = n;
|
||||
for (int k = 0; k < 8; k++) {
|
||||
if ((c & 0x1) == 1) {
|
||||
c = 0xEDB88320 ^ c >>> 1;
|
||||
} else {
|
||||
c >>>= 1;
|
||||
}
|
||||
crcTable[n] = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static int updateCRC(int crc, byte[] data, int off, int len) {
|
||||
int c = crc;
|
||||
for (int n = 0; n < len; n++)
|
||||
c = crcTable[(c ^ data[off + n]) & 0xFF] ^ c >>> 8;
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
package com.sun.media.jai.codecimpl;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataOutput;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
class ChunkStream extends OutputStream implements DataOutput {
|
||||
private String type;
|
||||
|
||||
private ByteArrayOutputStream baos;
|
||||
|
||||
private DataOutputStream dos;
|
||||
|
||||
public ChunkStream(String type) throws IOException {
|
||||
this.type = type;
|
||||
this.baos = new ByteArrayOutputStream();
|
||||
this.dos = new DataOutputStream(this.baos);
|
||||
}
|
||||
|
||||
public void write(byte[] b) throws IOException {
|
||||
this.dos.write(b);
|
||||
}
|
||||
|
||||
public void write(byte[] b, int off, int len) throws IOException {
|
||||
this.dos.write(b, off, len);
|
||||
}
|
||||
|
||||
public void write(int b) throws IOException {
|
||||
this.dos.write(b);
|
||||
}
|
||||
|
||||
public void writeBoolean(boolean v) throws IOException {
|
||||
this.dos.writeBoolean(v);
|
||||
}
|
||||
|
||||
public void writeByte(int v) throws IOException {
|
||||
this.dos.writeByte(v);
|
||||
}
|
||||
|
||||
public void writeBytes(String s) throws IOException {
|
||||
this.dos.writeBytes(s);
|
||||
}
|
||||
|
||||
public void writeChar(int v) throws IOException {
|
||||
this.dos.writeChar(v);
|
||||
}
|
||||
|
||||
public void writeChars(String s) throws IOException {
|
||||
this.dos.writeChars(s);
|
||||
}
|
||||
|
||||
public void writeDouble(double v) throws IOException {
|
||||
this.dos.writeDouble(v);
|
||||
}
|
||||
|
||||
public void writeFloat(float v) throws IOException {
|
||||
this.dos.writeFloat(v);
|
||||
}
|
||||
|
||||
public void writeInt(int v) throws IOException {
|
||||
this.dos.writeInt(v);
|
||||
}
|
||||
|
||||
public void writeLong(long v) throws IOException {
|
||||
this.dos.writeLong(v);
|
||||
}
|
||||
|
||||
public void writeShort(int v) throws IOException {
|
||||
this.dos.writeShort(v);
|
||||
}
|
||||
|
||||
public void writeUTF(String str) throws IOException {
|
||||
this.dos.writeUTF(str);
|
||||
}
|
||||
|
||||
public void writeToStream(DataOutputStream output) throws IOException {
|
||||
byte[] typeSignature = new byte[4];
|
||||
typeSignature[0] = (byte)this.type.charAt(0);
|
||||
typeSignature[1] = (byte)this.type.charAt(1);
|
||||
typeSignature[2] = (byte)this.type.charAt(2);
|
||||
typeSignature[3] = (byte)this.type.charAt(3);
|
||||
this.dos.flush();
|
||||
this.baos.flush();
|
||||
byte[] data = this.baos.toByteArray();
|
||||
int len = data.length;
|
||||
output.writeInt(len);
|
||||
output.write(typeSignature);
|
||||
output.write(data, 0, len);
|
||||
int crc = -1;
|
||||
crc = CRC.updateCRC(crc, typeSignature, 0, 4);
|
||||
crc = CRC.updateCRC(crc, data, 0, len);
|
||||
output.writeInt(crc ^ 0xFFFFFFFF);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
package com.sun.media.jai.codecimpl;
|
||||
|
||||
import java.awt.image.RenderedImage;
|
||||
import java.awt.image.SampleModel;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
class CodecUtils {
|
||||
static Method ioExceptionInitCause;
|
||||
|
||||
static {
|
||||
try {
|
||||
Class c = Class.forName("java.io.IOException");
|
||||
ioExceptionInitCause = c.getMethod("initCause", new Class[] { Throwable.class });
|
||||
} catch (Exception e) {
|
||||
ioExceptionInitCause = null;
|
||||
}
|
||||
}
|
||||
|
||||
static final boolean isPackedByteImage(RenderedImage im) {
|
||||
SampleModel imageSampleModel = im.getSampleModel();
|
||||
if (imageSampleModel instanceof java.awt.image.SinglePixelPackedSampleModel) {
|
||||
for (int i = 0; i < imageSampleModel.getNumBands(); i++) {
|
||||
if (imageSampleModel.getSampleSize(i) > 8)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static final IOException toIOException(Exception cause) {
|
||||
IOException ioe;
|
||||
if (cause != null) {
|
||||
if (cause instanceof IOException) {
|
||||
ioe = (IOException)cause;
|
||||
} else if (ioExceptionInitCause != null) {
|
||||
ioe = new IOException(cause.getMessage());
|
||||
try {
|
||||
ioExceptionInitCause.invoke(ioe, new Object[] { cause });
|
||||
} catch (Exception e2) {}
|
||||
} else {
|
||||
ioe = new IOException(cause.getClass().getName() + ": " + cause.getMessage());
|
||||
}
|
||||
} else {
|
||||
ioe = new IOException();
|
||||
}
|
||||
return ioe;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
package com.sun.media.jai.codecimpl;
|
||||
|
||||
import com.sun.media.jai.codec.FPXDecodeParam;
|
||||
import com.sun.media.jai.codec.ImageCodec;
|
||||
import com.sun.media.jai.codec.ImageDecodeParam;
|
||||
import com.sun.media.jai.codec.ImageDecoder;
|
||||
import com.sun.media.jai.codec.ImageEncodeParam;
|
||||
import com.sun.media.jai.codec.ImageEncoder;
|
||||
import com.sun.media.jai.codec.SeekableStream;
|
||||
import java.awt.image.RenderedImage;
|
||||
import java.io.OutputStream;
|
||||
|
||||
public final class FPXCodec extends ImageCodec {
|
||||
public String getFormatName() {
|
||||
return "fpx";
|
||||
}
|
||||
|
||||
public Class getEncodeParamClass() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Class getDecodeParamClass() {
|
||||
return FPXDecodeParam.class;
|
||||
}
|
||||
|
||||
public boolean canEncodeImage(RenderedImage im, ImageEncodeParam param) {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected ImageEncoder createImageEncoder(OutputStream dst, ImageEncodeParam param) {
|
||||
throw new RuntimeException(JaiI18N.getString("FPXCodec0"));
|
||||
}
|
||||
|
||||
protected ImageDecoder createImageDecoder(SeekableStream src, ImageDecodeParam param) {
|
||||
return new FPXImageDecoder(src, param);
|
||||
}
|
||||
|
||||
public int getNumHeaderBytes() {
|
||||
return 8;
|
||||
}
|
||||
|
||||
public boolean isFormatRecognized(byte[] header) {
|
||||
return (header[0] == -48 && header[1] == -49 && header[2] == 17 && header[3] == -32 && header[4] == -95 && header[5] == -79 && header[6] == 26 && header[7] == -31);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
package com.sun.media.jai.codecimpl;
|
||||
|
||||
import com.sun.media.jai.codec.FPXDecodeParam;
|
||||
import com.sun.media.jai.codec.ImageDecodeParam;
|
||||
import com.sun.media.jai.codec.ImageDecoderImpl;
|
||||
import com.sun.media.jai.codec.SeekableStream;
|
||||
import com.sun.media.jai.codecimpl.fpx.FPXImage;
|
||||
import java.awt.image.RenderedImage;
|
||||
import java.io.IOException;
|
||||
|
||||
public class FPXImageDecoder extends ImageDecoderImpl {
|
||||
public FPXImageDecoder(SeekableStream input, ImageDecodeParam param) {
|
||||
super(input, param);
|
||||
}
|
||||
|
||||
public RenderedImage decodeAsRenderedImage(int page) throws IOException {
|
||||
if (page != 0)
|
||||
throw new IOException(JaiI18N.getString("FPXImageDecoder0"));
|
||||
try {
|
||||
return new FPXImage(this.input, (FPXDecodeParam)this.param);
|
||||
} catch (Exception e) {
|
||||
throw CodecUtils.toIOException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
package com.sun.media.jai.codecimpl;
|
||||
|
||||
import com.sun.media.jai.codec.ImageCodec;
|
||||
import com.sun.media.jai.codec.ImageDecodeParam;
|
||||
import com.sun.media.jai.codec.ImageDecoder;
|
||||
import com.sun.media.jai.codec.ImageEncodeParam;
|
||||
import com.sun.media.jai.codec.ImageEncoder;
|
||||
import com.sun.media.jai.codec.SeekableStream;
|
||||
import java.awt.image.RenderedImage;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
public final class GIFCodec extends ImageCodec {
|
||||
public String getFormatName() {
|
||||
return "gif";
|
||||
}
|
||||
|
||||
public Class getEncodeParamClass() {
|
||||
return Object.class;
|
||||
}
|
||||
|
||||
public Class getDecodeParamClass() {
|
||||
return Object.class;
|
||||
}
|
||||
|
||||
public boolean canEncodeImage(RenderedImage im, ImageEncodeParam param) {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected ImageEncoder createImageEncoder(OutputStream dst, ImageEncodeParam param) {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected ImageDecoder createImageDecoder(InputStream src, ImageDecodeParam param) {
|
||||
return new GIFImageDecoder(src, param);
|
||||
}
|
||||
|
||||
protected ImageDecoder createImageDecoder(File src, ImageDecodeParam param) throws IOException {
|
||||
return new GIFImageDecoder(new FileInputStream(src), null);
|
||||
}
|
||||
|
||||
protected ImageDecoder createImageDecoder(SeekableStream src, ImageDecodeParam param) {
|
||||
return new GIFImageDecoder(src, param);
|
||||
}
|
||||
|
||||
public int getNumHeaderBytes() {
|
||||
return 4;
|
||||
}
|
||||
|
||||
public boolean isFormatRecognized(byte[] header) {
|
||||
return (header[0] == 71 && header[1] == 73 && header[2] == 70 && header[3] == 56);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,336 @@
|
|||
package com.sun.media.jai.codecimpl;
|
||||
|
||||
import com.sun.media.jai.codec.ImageCodec;
|
||||
import com.sun.media.jai.codec.SeekableStream;
|
||||
import java.awt.Point;
|
||||
import java.awt.image.IndexColorModel;
|
||||
import java.awt.image.PixelInterleavedSampleModel;
|
||||
import java.awt.image.Raster;
|
||||
import java.awt.image.WritableRaster;
|
||||
import java.io.IOException;
|
||||
|
||||
class GIFImage extends SimpleRenderedImage {
|
||||
private static final int[] INTERLACE_INCREMENT = new int[] { 8, 8, 4, 2, -1 };
|
||||
|
||||
private static final int[] INTERLACE_OFFSET = new int[] { 0, 4, 2, 1, -1 };
|
||||
|
||||
private SeekableStream input;
|
||||
|
||||
private boolean interlaceFlag;
|
||||
|
||||
private byte[] block;
|
||||
|
||||
private int blockLength;
|
||||
|
||||
private int bitPos;
|
||||
|
||||
private int nextByte;
|
||||
|
||||
private int initCodeSize;
|
||||
|
||||
private int clearCode;
|
||||
|
||||
private int eofCode;
|
||||
|
||||
private int bitsLeft;
|
||||
|
||||
private int next32Bits;
|
||||
|
||||
private boolean lastBlockFound;
|
||||
|
||||
private int interlacePass;
|
||||
|
||||
private WritableRaster theTile;
|
||||
|
||||
private void skipBlocks() throws IOException {
|
||||
while (true) {
|
||||
int length = this.input.readUnsignedByte();
|
||||
if (length == 0)
|
||||
break;
|
||||
this.input.skipBytes(length);
|
||||
}
|
||||
}
|
||||
|
||||
GIFImage(SeekableStream input, byte[] globalColorTable) throws IOException {
|
||||
byte[] colorTable;
|
||||
int bits;
|
||||
this.interlaceFlag = false;
|
||||
this.block = new byte[255];
|
||||
this.blockLength = 0;
|
||||
this.bitPos = 0;
|
||||
this.nextByte = 0;
|
||||
this.next32Bits = 0;
|
||||
this.lastBlockFound = false;
|
||||
this.interlacePass = 0;
|
||||
this.theTile = null;
|
||||
this.input = input;
|
||||
byte[] localColorTable = null;
|
||||
boolean transparentColorFlag = false;
|
||||
int transparentColorIndex = 0;
|
||||
try {
|
||||
long startPosition = input.getFilePointer();
|
||||
label81: while (true) {
|
||||
int blockType = input.readUnsignedByte();
|
||||
if (blockType == 44) {
|
||||
input.skipBytes(4);
|
||||
this.width = input.readUnsignedShortLE();
|
||||
this.height = input.readUnsignedShortLE();
|
||||
int idPackedFields = input.readUnsignedByte();
|
||||
boolean localColorTableFlag = ((idPackedFields & 0x80) != 0);
|
||||
this.interlaceFlag = ((idPackedFields & 0x40) != 0);
|
||||
int numLCTEntries = 1 << (idPackedFields & 0x7) + 1;
|
||||
if (localColorTableFlag) {
|
||||
localColorTable = new byte[3 * numLCTEntries];
|
||||
input.readFully(localColorTable);
|
||||
break;
|
||||
}
|
||||
localColorTable = null;
|
||||
break;
|
||||
}
|
||||
if (blockType == 33) {
|
||||
int label = input.readUnsignedByte();
|
||||
if (label == 249) {
|
||||
input.read();
|
||||
int gcePackedFields = input.readUnsignedByte();
|
||||
transparentColorFlag = ((gcePackedFields & 0x1) != 0);
|
||||
input.skipBytes(2);
|
||||
transparentColorIndex = input.readUnsignedByte();
|
||||
input.read();
|
||||
continue;
|
||||
}
|
||||
if (label == 1) {
|
||||
input.skipBytes(13);
|
||||
skipBlocks();
|
||||
continue;
|
||||
}
|
||||
if (label == 254) {
|
||||
skipBlocks();
|
||||
continue;
|
||||
}
|
||||
if (label == 255) {
|
||||
input.skipBytes(12);
|
||||
skipBlocks();
|
||||
continue;
|
||||
}
|
||||
int j = 0;
|
||||
while (true) {
|
||||
j = input.readUnsignedByte();
|
||||
input.skipBytes(j);
|
||||
if (j <= 0)
|
||||
continue label81;
|
||||
}
|
||||
}
|
||||
throw new IOException(JaiI18N.getString("GIFImage0") + " " + blockType + "!");
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
throw new IOException(JaiI18N.getString("GIFImage1"));
|
||||
}
|
||||
this.minX = this.minY = this.tileGridXOffset = this.tileGridYOffset = 0;
|
||||
this.tileWidth = this.width;
|
||||
this.tileHeight = this.height;
|
||||
if (localColorTable != null) {
|
||||
colorTable = localColorTable;
|
||||
} else {
|
||||
colorTable = globalColorTable;
|
||||
}
|
||||
int length = colorTable.length / 3;
|
||||
if (length == 2) {
|
||||
bits = 1;
|
||||
} else if (length == 4) {
|
||||
bits = 2;
|
||||
} else if (length == 8 || length == 16) {
|
||||
bits = 4;
|
||||
} else {
|
||||
bits = 8;
|
||||
}
|
||||
int lutLength = 1 << bits;
|
||||
byte[] r = new byte[lutLength];
|
||||
byte[] g = new byte[lutLength];
|
||||
byte[] b = new byte[lutLength];
|
||||
int rgbIndex = 0;
|
||||
for (int i = 0; i < length; i++) {
|
||||
r[i] = colorTable[rgbIndex++];
|
||||
g[i] = colorTable[rgbIndex++];
|
||||
b[i] = colorTable[rgbIndex++];
|
||||
}
|
||||
int[] bitsPerSample = new int[1];
|
||||
bitsPerSample[0] = bits;
|
||||
this.sampleModel = new PixelInterleavedSampleModel(0, this.width, this.height, 1, this.width, new int[] { 0 });
|
||||
if (!transparentColorFlag) {
|
||||
if (ImageCodec.isIndicesForGrayscale(r, g, b)) {
|
||||
this.colorModel = ImageCodec.createComponentColorModel(this.sampleModel);
|
||||
return;
|
||||
}
|
||||
this.colorModel = new IndexColorModel(bits, r.length, r, g, b);
|
||||
return;
|
||||
}
|
||||
this.colorModel = new IndexColorModel(bits, r.length, r, g, b, transparentColorIndex);
|
||||
}
|
||||
|
||||
private void initNext32Bits() {
|
||||
this.next32Bits = this.block[0] & 0xFF;
|
||||
this.next32Bits |= (this.block[1] & 0xFF) << 8;
|
||||
this.next32Bits |= (this.block[2] & 0xFF) << 16;
|
||||
this.next32Bits |= this.block[3] << 24;
|
||||
this.nextByte = 4;
|
||||
}
|
||||
|
||||
private int getCode(int codeSize, int codeMask) throws IOException {
|
||||
if (this.bitsLeft <= 0)
|
||||
return this.eofCode;
|
||||
int code = this.next32Bits >> this.bitPos & codeMask;
|
||||
this.bitPos += codeSize;
|
||||
this.bitsLeft -= codeSize;
|
||||
while (this.bitPos >= 8 && !this.lastBlockFound) {
|
||||
this.next32Bits >>>= 8;
|
||||
this.bitPos -= 8;
|
||||
if (this.nextByte >= this.blockLength) {
|
||||
this.blockLength = this.input.readUnsignedByte();
|
||||
if (this.blockLength == 0) {
|
||||
this.lastBlockFound = true;
|
||||
if (this.bitsLeft < 0)
|
||||
return this.eofCode;
|
||||
return code;
|
||||
}
|
||||
int left = this.blockLength;
|
||||
int off = 0;
|
||||
while (left > 0) {
|
||||
int nbytes = this.input.read(this.block, off, left);
|
||||
off += nbytes;
|
||||
left -= nbytes;
|
||||
}
|
||||
this.bitsLeft += this.blockLength << 3;
|
||||
this.nextByte = 0;
|
||||
}
|
||||
this.next32Bits |= this.block[this.nextByte++] << 24;
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
private void initializeStringTable(int[] prefix, byte[] suffix, byte[] initial, int[] length) {
|
||||
int numEntries = 1 << this.initCodeSize;
|
||||
for (int j = 0; j < numEntries; j++) {
|
||||
prefix[j] = -1;
|
||||
suffix[j] = (byte)j;
|
||||
initial[j] = (byte)j;
|
||||
length[j] = 1;
|
||||
}
|
||||
for (int i = numEntries; i < 4096; i++) {
|
||||
prefix[i] = -1;
|
||||
length[i] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
private Point outputPixels(byte[] string, int len, Point streamPos, byte[] rowBuf) {
|
||||
if (this.interlacePass < 0 || this.interlacePass > 3)
|
||||
return streamPos;
|
||||
for (int i = 0; i < len; i++) {
|
||||
if (streamPos.x >= this.minX)
|
||||
rowBuf[streamPos.x - this.minX] = string[i];
|
||||
streamPos.x++;
|
||||
if (streamPos.x == this.width) {
|
||||
this.theTile.setDataElements(this.minX, streamPos.y, this.width, 1, rowBuf);
|
||||
streamPos.x = 0;
|
||||
if (this.interlaceFlag) {
|
||||
streamPos.y += INTERLACE_INCREMENT[this.interlacePass];
|
||||
if (streamPos.y >= this.height) {
|
||||
this.interlacePass++;
|
||||
if (this.interlacePass > 3)
|
||||
return streamPos;
|
||||
streamPos.y = INTERLACE_OFFSET[this.interlacePass];
|
||||
}
|
||||
} else {
|
||||
streamPos.y++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return streamPos;
|
||||
}
|
||||
|
||||
public synchronized Raster getTile(int tileX, int tileY) {
|
||||
if (tileX != 0 || tileY != 0)
|
||||
throw new IllegalArgumentException(JaiI18N.getString("GIFImage2"));
|
||||
if (this.theTile != null)
|
||||
return this.theTile;
|
||||
this.theTile = WritableRaster.createWritableRaster(this.sampleModel, this.sampleModel.createDataBuffer(), null);
|
||||
Point streamPos = new Point(0, 0);
|
||||
byte[] rowBuf = new byte[this.width];
|
||||
try {
|
||||
this.initCodeSize = this.input.readUnsignedByte();
|
||||
this.blockLength = this.input.readUnsignedByte();
|
||||
int left = this.blockLength;
|
||||
int off = 0;
|
||||
while (left > 0) {
|
||||
int nbytes = this.input.read(this.block, off, left);
|
||||
left -= nbytes;
|
||||
off += nbytes;
|
||||
}
|
||||
this.bitPos = 0;
|
||||
this.nextByte = 0;
|
||||
this.lastBlockFound = false;
|
||||
this.bitsLeft = this.blockLength << 3;
|
||||
initNext32Bits();
|
||||
this.clearCode = 1 << this.initCodeSize;
|
||||
this.eofCode = this.clearCode + 1;
|
||||
int oldCode = 0;
|
||||
int[] prefix = new int[4096];
|
||||
byte[] suffix = new byte[4096];
|
||||
byte[] initial = new byte[4096];
|
||||
int[] length = new int[4096];
|
||||
byte[] string = new byte[4096];
|
||||
initializeStringTable(prefix, suffix, initial, length);
|
||||
int tableIndex = (1 << this.initCodeSize) + 2;
|
||||
int codeSize = this.initCodeSize + 1;
|
||||
int codeMask = (1 << codeSize) - 1;
|
||||
while (true) {
|
||||
int code = getCode(codeSize, codeMask);
|
||||
if (code == this.clearCode) {
|
||||
initializeStringTable(prefix, suffix, initial, length);
|
||||
tableIndex = (1 << this.initCodeSize) + 2;
|
||||
codeSize = this.initCodeSize + 1;
|
||||
codeMask = (1 << codeSize) - 1;
|
||||
code = getCode(codeSize, codeMask);
|
||||
if (code == this.eofCode)
|
||||
return this.theTile;
|
||||
} else {
|
||||
int newSuffixIndex;
|
||||
if (code == this.eofCode)
|
||||
return this.theTile;
|
||||
if (code < tableIndex) {
|
||||
newSuffixIndex = code;
|
||||
} else {
|
||||
newSuffixIndex = oldCode;
|
||||
}
|
||||
int ti = tableIndex;
|
||||
int oc = oldCode;
|
||||
prefix[ti] = oc;
|
||||
suffix[ti] = initial[newSuffixIndex];
|
||||
initial[ti] = initial[oc];
|
||||
length[ti] = length[oc] + 1;
|
||||
tableIndex++;
|
||||
if (tableIndex == 1 << codeSize && tableIndex < 4096) {
|
||||
codeSize++;
|
||||
codeMask = (1 << codeSize) - 1;
|
||||
}
|
||||
}
|
||||
int c = code;
|
||||
int len = length[c];
|
||||
for (int i = len - 1; i >= 0; i--) {
|
||||
string[i] = suffix[c];
|
||||
c = prefix[c];
|
||||
}
|
||||
outputPixels(string, len, streamPos, rowBuf);
|
||||
oldCode = code;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
String message = JaiI18N.getString("GIFImage3");
|
||||
return this.theTile;
|
||||
} finally {
|
||||
Exception exception = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
this.theTile = null;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
package com.sun.media.jai.codecimpl;
|
||||
|
||||
import com.sun.media.jai.codec.ImageDecodeParam;
|
||||
import com.sun.media.jai.codec.ImageDecoderImpl;
|
||||
import com.sun.media.jai.codec.SeekableStream;
|
||||
import com.sun.media.jai.codecimpl.util.ImagingException;
|
||||
import java.awt.image.RenderedImage;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class GIFImageDecoder extends ImageDecoderImpl {
|
||||
private byte[] globalColorTable = null;
|
||||
|
||||
private boolean maxPageFound = false;
|
||||
|
||||
private int maxPage;
|
||||
|
||||
private int prevPage = -1;
|
||||
|
||||
private int prevSyncedPage = -1;
|
||||
|
||||
private HashMap images = new HashMap();
|
||||
|
||||
private static byte[] readHeader(SeekableStream input) throws IOException {
|
||||
byte[] globalColorTable = null;
|
||||
try {
|
||||
input.skipBytes(10);
|
||||
int packedFields = input.readUnsignedByte();
|
||||
boolean globalColorTableFlag = ((packedFields & 0x80) != 0);
|
||||
int numGCTEntries = 1 << (packedFields & 0x7) + 1;
|
||||
int backgroundColorIndex = input.readUnsignedByte();
|
||||
input.read();
|
||||
if (globalColorTableFlag) {
|
||||
globalColorTable = new byte[3 * numGCTEntries];
|
||||
input.readFully(globalColorTable);
|
||||
} else {
|
||||
globalColorTable = null;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
String message = JaiI18N.getString("GIFImageDecoder0");
|
||||
ImagingListenerProxy.errorOccurred(message, new ImagingException(message, e), GIFImageDecoder.class, false);
|
||||
}
|
||||
return globalColorTable;
|
||||
}
|
||||
|
||||
public GIFImageDecoder(SeekableStream input, ImageDecodeParam param) {
|
||||
super(input, param);
|
||||
}
|
||||
|
||||
public GIFImageDecoder(InputStream input, ImageDecodeParam param) {
|
||||
super(input, param);
|
||||
}
|
||||
|
||||
public int getNumPages() throws IOException {
|
||||
int page = this.prevPage + 1;
|
||||
while (!this.maxPageFound) {
|
||||
try {
|
||||
decodeAsRenderedImage(page++);
|
||||
} catch (IOException e) {}
|
||||
}
|
||||
return this.maxPage + 1;
|
||||
}
|
||||
|
||||
public synchronized RenderedImage decodeAsRenderedImage(int page) throws IOException {
|
||||
if (page < 0 || (this.maxPageFound && page > this.maxPage))
|
||||
throw new IOException(JaiI18N.getString("GIFImageDecoder1"));
|
||||
Integer pageKey = new Integer(page);
|
||||
if (this.images.containsKey(pageKey))
|
||||
return (RenderedImage)this.images.get(pageKey);
|
||||
if (this.prevPage == -1)
|
||||
try {
|
||||
this.globalColorTable = readHeader(this.input);
|
||||
} catch (IOException e) {
|
||||
this.maxPageFound = true;
|
||||
this.maxPage = -1;
|
||||
throw e;
|
||||
}
|
||||
if (page > 0)
|
||||
for (int idx = this.prevSyncedPage + 1; idx < page; idx++) {
|
||||
RenderedImage im = (RenderedImage)this.images.get(new Integer(idx));
|
||||
im.getTile(0, 0);
|
||||
this.prevSyncedPage = idx;
|
||||
}
|
||||
RenderedImage image = null;
|
||||
while (this.prevPage < page) {
|
||||
int index = this.prevPage + 1;
|
||||
RenderedImage ri = null;
|
||||
try {
|
||||
ri = new GIFImage(this.input, this.globalColorTable);
|
||||
this.images.put(new Integer(index), ri);
|
||||
if (index < page) {
|
||||
ri.getTile(0, 0);
|
||||
this.prevSyncedPage = index;
|
||||
}
|
||||
this.prevPage = index;
|
||||
if (index == page) {
|
||||
image = ri;
|
||||
break;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
this.maxPageFound = true;
|
||||
this.maxPage = this.prevPage;
|
||||
String message = JaiI18N.getString("GIFImage3");
|
||||
ImagingListenerProxy.errorOccurred(message, new ImagingException(message, e), this, false);
|
||||
}
|
||||
}
|
||||
return image;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
package com.sun.media.jai.codecimpl;
|
||||
|
||||
import java.io.FilterOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
class IDATOutputStream extends FilterOutputStream {
|
||||
private static final byte[] typeSignature = new byte[] { 73, 68, 65, 84 };
|
||||
|
||||
private int bytesWritten = 0;
|
||||
|
||||
private int segmentLength;
|
||||
|
||||
byte[] buffer;
|
||||
|
||||
public IDATOutputStream(OutputStream output, int segmentLength) {
|
||||
super(output);
|
||||
this.segmentLength = segmentLength;
|
||||
this.buffer = new byte[segmentLength];
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
flush();
|
||||
}
|
||||
|
||||
private void writeInt(int x) throws IOException {
|
||||
this.out.write(x >> 24);
|
||||
this.out.write(x >> 16 & 0xFF);
|
||||
this.out.write(x >> 8 & 0xFF);
|
||||
this.out.write(x & 0xFF);
|
||||
}
|
||||
|
||||
public void flush() throws IOException {
|
||||
writeInt(this.bytesWritten);
|
||||
this.out.write(typeSignature);
|
||||
this.out.write(this.buffer, 0, this.bytesWritten);
|
||||
int crc = -1;
|
||||
crc = CRC.updateCRC(crc, typeSignature, 0, 4);
|
||||
crc = CRC.updateCRC(crc, this.buffer, 0, this.bytesWritten);
|
||||
writeInt(crc ^ 0xFFFFFFFF);
|
||||
this.bytesWritten = 0;
|
||||
}
|
||||
|
||||
public void write(byte[] b) throws IOException {
|
||||
write(b, 0, b.length);
|
||||
}
|
||||
|
||||
public void write(byte[] b, int off, int len) throws IOException {
|
||||
while (len > 0) {
|
||||
int bytes = Math.min(this.segmentLength - this.bytesWritten, len);
|
||||
System.arraycopy(b, off, this.buffer, this.bytesWritten, bytes);
|
||||
off += bytes;
|
||||
len -= bytes;
|
||||
this.bytesWritten += bytes;
|
||||
if (this.bytesWritten == this.segmentLength)
|
||||
flush();
|
||||
}
|
||||
}
|
||||
|
||||
public void write(int b) throws IOException {
|
||||
this.buffer[this.bytesWritten++] = (byte)b;
|
||||
if (this.bytesWritten == this.segmentLength)
|
||||
flush();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
package com.sun.media.jai.codecimpl;
|
||||
|
||||
import com.sun.media.jai.codecimpl.util.ImagingException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class ImagingListenerProxy {
|
||||
public static synchronized boolean errorOccurred(String message, Throwable thrown, Object where, boolean isRetryable) throws RuntimeException {
|
||||
Method errorOccurred = null;
|
||||
Object listener = null;
|
||||
try {
|
||||
Class jaiClass = Class.forName("javax.media.jai.JAI");
|
||||
if (jaiClass == null)
|
||||
return defaultImpl(message, thrown, where, isRetryable);
|
||||
Method jaiInstance = jaiClass.getMethod("getDefaultInstance", null);
|
||||
Method getListener = jaiClass.getMethod("getImagingListener", null);
|
||||
Object jai = jaiInstance.invoke(null, null);
|
||||
if (jai == null)
|
||||
return defaultImpl(message, thrown, where, isRetryable);
|
||||
listener = getListener.invoke(jai, null);
|
||||
Class listenerClass = listener.getClass();
|
||||
errorOccurred = listenerClass.getMethod("errorOccurred", new Class[] { String.class, Throwable.class, Object.class, boolean.class });
|
||||
} catch (Throwable e) {
|
||||
return defaultImpl(message, thrown, where, isRetryable);
|
||||
}
|
||||
try {
|
||||
Boolean result = (Boolean)errorOccurred.invoke(listener, new Object[] { message, thrown, where, new Boolean(isRetryable) });
|
||||
return result.booleanValue();
|
||||
} catch (InvocationTargetException e) {
|
||||
Throwable te = e.getTargetException();
|
||||
throw new ImagingException(te);
|
||||
} catch (Throwable e) {
|
||||
return defaultImpl(message, thrown, where, isRetryable);
|
||||
}
|
||||
}
|
||||
|
||||
private static synchronized boolean defaultImpl(String message, Throwable thrown, Object where, boolean isRetryable) throws RuntimeException {
|
||||
if (thrown instanceof RuntimeException)
|
||||
throw (RuntimeException)thrown;
|
||||
System.err.println("Error: " + message);
|
||||
System.err.println("Occurs in: " + ((where instanceof Class) ? ((Class)where).getName() : where.getClass().getName()));
|
||||
thrown.printStackTrace(System.err);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
package com.sun.media.jai.codecimpl;
|
||||
|
||||
import com.sun.media.jai.codec.ImageCodec;
|
||||
import com.sun.media.jai.codec.ImageDecodeParam;
|
||||
import com.sun.media.jai.codec.ImageDecoder;
|
||||
import com.sun.media.jai.codec.ImageEncodeParam;
|
||||
import com.sun.media.jai.codec.ImageEncoder;
|
||||
import com.sun.media.jai.codec.JPEGDecodeParam;
|
||||
import com.sun.media.jai.codec.JPEGEncodeParam;
|
||||
import com.sun.media.jai.codec.SeekableStream;
|
||||
import java.awt.image.RenderedImage;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
public final class JPEGCodec extends ImageCodec {
|
||||
public String getFormatName() {
|
||||
return "jpeg";
|
||||
}
|
||||
|
||||
public Class getEncodeParamClass() {
|
||||
return JPEGEncodeParam.class;
|
||||
}
|
||||
|
||||
public Class getDecodeParamClass() {
|
||||
return JPEGDecodeParam.class;
|
||||
}
|
||||
|
||||
public boolean canEncodeImage(RenderedImage im, ImageEncodeParam param) {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected ImageEncoder createImageEncoder(OutputStream dst, ImageEncodeParam param) {
|
||||
JPEGEncodeParam p = null;
|
||||
if (param != null)
|
||||
p = (JPEGEncodeParam)param;
|
||||
return new JPEGImageEncoder(dst, p);
|
||||
}
|
||||
|
||||
protected ImageDecoder createImageDecoder(InputStream src, ImageDecodeParam param) {
|
||||
return new JPEGImageDecoder(src, param);
|
||||
}
|
||||
|
||||
protected ImageDecoder createImageDecoder(File src, ImageDecodeParam param) throws IOException {
|
||||
return new JPEGImageDecoder(new FileInputStream(src), param);
|
||||
}
|
||||
|
||||
protected ImageDecoder createImageDecoder(SeekableStream src, ImageDecodeParam param) {
|
||||
return new JPEGImageDecoder(src, param);
|
||||
}
|
||||
|
||||
public int getNumHeaderBytes() {
|
||||
return 3;
|
||||
}
|
||||
|
||||
public boolean isFormatRecognized(byte[] header) {
|
||||
return (header[0] == -1 && header[1] == -40 && header[2] == -1);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
package com.sun.media.jai.codecimpl;
|
||||
|
||||
import com.sun.image.codec.jpeg.ImageFormatException;
|
||||
import com.sun.media.jai.codec.ImageDecodeParam;
|
||||
import com.sun.media.jai.codec.JPEGDecodeParam;
|
||||
import com.sun.media.jai.codecimpl.util.ImagingException;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.Raster;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
class JPEGImage extends SimpleRenderedImage {
|
||||
private static final Object LOCK = new Object();
|
||||
|
||||
private Raster theTile = null;
|
||||
|
||||
public JPEGImage(InputStream stream, ImageDecodeParam param) {
|
||||
if (stream.markSupported())
|
||||
stream = new NoMarkStream(stream);
|
||||
BufferedImage image = null;
|
||||
synchronized (LOCK) {
|
||||
com.sun.image.codec.jpeg.JPEGImageDecoder decoder = com.sun.image.codec.jpeg.JPEGCodec.createJPEGDecoder(stream);
|
||||
try {
|
||||
image = decoder.decodeAsBufferedImage();
|
||||
} catch (ImageFormatException e) {
|
||||
String message = JaiI18N.getString("JPEGImageDecoder1");
|
||||
sendExceptionToListener(message, (Exception)e);
|
||||
} catch (IOException e) {
|
||||
String message = JaiI18N.getString("JPEGImageDecoder1");
|
||||
sendExceptionToListener(message, e);
|
||||
}
|
||||
}
|
||||
this.minX = 0;
|
||||
this.minY = 0;
|
||||
this.tileWidth = this.width = image.getWidth();
|
||||
this.tileHeight = this.height = image.getHeight();
|
||||
if ((param == null || (param instanceof JPEGDecodeParam && ((JPEGDecodeParam)param).getDecodeToCSM())) && !(image.getSampleModel() instanceof java.awt.image.ComponentSampleModel)) {
|
||||
int type = -1;
|
||||
int numBands = image.getSampleModel().getNumBands();
|
||||
if (numBands == 1) {
|
||||
type = 10;
|
||||
} else if (numBands == 3) {
|
||||
type = 5;
|
||||
} else if (numBands == 4) {
|
||||
type = 6;
|
||||
} else {
|
||||
throw new RuntimeException(JaiI18N.getString("JPEGImageDecoder3"));
|
||||
}
|
||||
BufferedImage bi = new BufferedImage(this.width, this.height, type);
|
||||
bi.getWritableTile(0, 0).setRect(image.getWritableTile(0, 0));
|
||||
bi.releaseWritableTile(0, 0);
|
||||
image = bi;
|
||||
}
|
||||
this.sampleModel = image.getSampleModel();
|
||||
this.colorModel = image.getColorModel();
|
||||
this.theTile = image.getWritableTile(0, 0);
|
||||
}
|
||||
|
||||
public synchronized Raster getTile(int tileX, int tileY) {
|
||||
if (tileX != 0 || tileY != 0)
|
||||
throw new IllegalArgumentException(JaiI18N.getString("JPEGImageDecoder4"));
|
||||
return this.theTile;
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
this.theTile = null;
|
||||
}
|
||||
|
||||
private void sendExceptionToListener(String message, Exception e) {
|
||||
ImagingListenerProxy.errorOccurred(message, new ImagingException(message, e), this, false);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
package com.sun.media.jai.codecimpl;
|
||||
|
||||
import com.sun.media.jai.codec.ImageDecodeParam;
|
||||
import com.sun.media.jai.codec.ImageDecoderImpl;
|
||||
import java.awt.image.RenderedImage;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
public class JPEGImageDecoder extends ImageDecoderImpl {
|
||||
public JPEGImageDecoder(InputStream input, ImageDecodeParam param) {
|
||||
super(input, param);
|
||||
}
|
||||
|
||||
public RenderedImage decodeAsRenderedImage(int page) throws IOException {
|
||||
if (page != 0)
|
||||
throw new IOException(JaiI18N.getString("JPEGImageDecoder0"));
|
||||
try {
|
||||
return new JPEGImage(this.input, this.param);
|
||||
} catch (Exception e) {
|
||||
throw CodecUtils.toIOException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
package com.sun.media.jai.codecimpl;
|
||||
|
||||
import com.sun.image.codec.jpeg.JPEGQTable;
|
||||
import com.sun.media.jai.codec.ImageEncodeParam;
|
||||
import com.sun.media.jai.codec.ImageEncoderImpl;
|
||||
import com.sun.media.jai.codec.JPEGEncodeParam;
|
||||
import com.sun.media.jai.codecimpl.util.ImagingException;
|
||||
import java.awt.Point;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.ColorModel;
|
||||
import java.awt.image.DirectColorModel;
|
||||
import java.awt.image.IndexColorModel;
|
||||
import java.awt.image.PackedColorModel;
|
||||
import java.awt.image.Raster;
|
||||
import java.awt.image.RenderedImage;
|
||||
import java.awt.image.SampleModel;
|
||||
import java.awt.image.WritableRaster;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
public class JPEGImageEncoder extends ImageEncoderImpl {
|
||||
private JPEGEncodeParam jaiEP = null;
|
||||
|
||||
public JPEGImageEncoder(OutputStream output, ImageEncodeParam param) {
|
||||
super(output, param);
|
||||
if (param != null)
|
||||
this.jaiEP = (JPEGEncodeParam)param;
|
||||
}
|
||||
|
||||
static void modifyEncodeParam(JPEGEncodeParam jaiEP, com.sun.image.codec.jpeg.JPEGEncodeParam j2dEP, int nbands) {
|
||||
for (int i = 0; i < nbands; i++) {
|
||||
int j = jaiEP.getHorizontalSubsampling(i);
|
||||
j2dEP.setHorizontalSubsampling(i, j);
|
||||
j = jaiEP.getVerticalSubsampling(i);
|
||||
j2dEP.setVerticalSubsampling(i, j);
|
||||
if (jaiEP.isQTableSet(i)) {
|
||||
int[] qTab = jaiEP.getQTable(i);
|
||||
j = jaiEP.getQTableSlot(i);
|
||||
j2dEP.setQTableComponentMapping(i, j);
|
||||
j2dEP.setQTable(j, new JPEGQTable(qTab));
|
||||
}
|
||||
}
|
||||
if (jaiEP.isQualitySet()) {
|
||||
float fval = jaiEP.getQuality();
|
||||
j2dEP.setQuality(fval, true);
|
||||
}
|
||||
int val = jaiEP.getRestartInterval();
|
||||
j2dEP.setRestartInterval(val);
|
||||
if (jaiEP.getWriteTablesOnly() == true) {
|
||||
j2dEP.setImageInfoValid(false);
|
||||
j2dEP.setTableInfoValid(true);
|
||||
}
|
||||
if (jaiEP.getWriteImageOnly() == true) {
|
||||
j2dEP.setTableInfoValid(false);
|
||||
j2dEP.setImageInfoValid(true);
|
||||
}
|
||||
if (!jaiEP.getWriteJFIFHeader())
|
||||
j2dEP.setMarkerData(224, null);
|
||||
}
|
||||
|
||||
public void encode(RenderedImage im) throws IOException {
|
||||
BufferedImage bi;
|
||||
SampleModel sampleModel = im.getSampleModel();
|
||||
ColorModel colorModel = im.getColorModel();
|
||||
int numBands = colorModel.getNumColorComponents();
|
||||
int transType = sampleModel.getTransferType();
|
||||
if ((transType != 0 && !CodecUtils.isPackedByteImage(im)) || (numBands != 1 && numBands != 3))
|
||||
throw new RuntimeException(JaiI18N.getString("JPEGImageEncoder0"));
|
||||
int cspaceType = colorModel.getColorSpace().getType();
|
||||
if (cspaceType != 6 && cspaceType != 5)
|
||||
throw new RuntimeException(JaiI18N.getString("JPEGImageEncoder1"));
|
||||
if (im instanceof BufferedImage) {
|
||||
bi = (BufferedImage)im;
|
||||
} else {
|
||||
Raster ras;
|
||||
WritableRaster wRas;
|
||||
if (im.getNumXTiles() == 1 && im.getNumYTiles() == 1) {
|
||||
ras = im.getTile(im.getMinTileX(), im.getMinTileY());
|
||||
} else {
|
||||
WritableRaster target = (sampleModel.getSampleSize(0) == 8) ? Raster.createInterleavedRaster(0, im.getWidth(), im.getHeight(), sampleModel.getNumBands(), new Point(im.getMinX(), im.getMinY())) : null;
|
||||
ras = im.copyData(target);
|
||||
}
|
||||
if (ras instanceof WritableRaster) {
|
||||
wRas = (WritableRaster)ras;
|
||||
} else {
|
||||
wRas = Raster.createWritableRaster(ras.getSampleModel(), ras.getDataBuffer(), new Point(ras.getSampleModelTranslateX(), ras.getSampleModelTranslateY()));
|
||||
}
|
||||
if (wRas.getMinX() != 0 || wRas.getMinY() != 0 || wRas.getWidth() != im.getWidth() || wRas.getHeight() != im.getHeight())
|
||||
wRas = wRas.createWritableChild(wRas.getMinX(), wRas.getMinY(), im.getWidth(), im.getHeight(), 0, 0, null);
|
||||
bi = new BufferedImage(colorModel, wRas, false, null);
|
||||
}
|
||||
if (colorModel instanceof IndexColorModel) {
|
||||
IndexColorModel icm = (IndexColorModel)colorModel;
|
||||
bi = icm.convertToIntDiscrete(bi.getRaster(), false);
|
||||
if (bi.getSampleModel().getNumBands() == 4) {
|
||||
WritableRaster rgbaRas = bi.getRaster();
|
||||
WritableRaster rgbRas = rgbaRas.createWritableChild(0, 0, bi.getWidth(), bi.getHeight(), 0, 0, new int[] { 0, 1, 2 });
|
||||
PackedColorModel pcm = (PackedColorModel)bi.getColorModel();
|
||||
int bits = pcm.getComponentSize(0) + pcm.getComponentSize(1) + pcm.getComponentSize(2);
|
||||
DirectColorModel dcm = new DirectColorModel(bits, pcm.getMask(0), pcm.getMask(1), pcm.getMask(2));
|
||||
bi = new BufferedImage(dcm, rgbRas, false, null);
|
||||
}
|
||||
}
|
||||
com.sun.image.codec.jpeg.JPEGEncodeParam j2dEP = com.sun.image.codec.jpeg.JPEGCodec.getDefaultJPEGEncodeParam(bi);
|
||||
if (this.jaiEP != null)
|
||||
modifyEncodeParam(this.jaiEP, j2dEP, numBands);
|
||||
com.sun.image.codec.jpeg.JPEGImageEncoder encoder = com.sun.image.codec.jpeg.JPEGCodec.createJPEGEncoder(this.output, j2dEP);
|
||||
try {
|
||||
encoder.encode(bi);
|
||||
} catch (IOException e) {
|
||||
String message = JaiI18N.getString("JPEGImageEncoder2");
|
||||
ImagingListenerProxy.errorOccurred(message, new ImagingException(message, e), this, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
package com.sun.media.jai.codecimpl;
|
||||
|
||||
import com.sun.media.jai.codecimpl.util.PropertyUtil;
|
||||
|
||||
class JaiI18N {
|
||||
static String packageName = "com.sun.media.jai.codecimpl";
|
||||
|
||||
public static String getString(String key) {
|
||||
return PropertyUtil.getString(packageName, key);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
package com.sun.media.jai.codecimpl;
|
||||
|
||||
import com.sun.media.jai.codec.SeekableStream;
|
||||
import java.io.IOException;
|
||||
|
||||
class NoEOFStream extends SeekableStream {
|
||||
private SeekableStream stream;
|
||||
|
||||
NoEOFStream(SeekableStream ss) {
|
||||
if (ss == null)
|
||||
throw new IllegalArgumentException();
|
||||
this.stream = ss;
|
||||
}
|
||||
|
||||
public int read() throws IOException {
|
||||
int b = this.stream.read();
|
||||
return (b < 0) ? 0 : b;
|
||||
}
|
||||
|
||||
public int read(byte[] b, int off, int len) throws IOException {
|
||||
int count = this.stream.read(b, off, len);
|
||||
return (count < 0) ? len : count;
|
||||
}
|
||||
|
||||
public long getFilePointer() throws IOException {
|
||||
return this.stream.getFilePointer();
|
||||
}
|
||||
|
||||
public void seek(long pos) throws IOException {
|
||||
this.stream.seek(pos);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
package com.sun.media.jai.codecimpl;
|
||||
|
||||
import java.io.FilterInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
class NoMarkStream extends FilterInputStream {
|
||||
NoMarkStream(InputStream in) {
|
||||
super(in);
|
||||
}
|
||||
|
||||
public boolean markSupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public final void close() throws IOException {}
|
||||
}
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
package com.sun.media.jai.codecimpl;
|
||||
|
||||
class PNGChunk {
|
||||
int length;
|
||||
|
||||
int type;
|
||||
|
||||
byte[] data;
|
||||
|
||||
int crc;
|
||||
|
||||
String typeString;
|
||||
|
||||
public PNGChunk(int length, int type, byte[] data, int crc) {
|
||||
this.length = length;
|
||||
this.type = type;
|
||||
this.data = data;
|
||||
this.crc = crc;
|
||||
this.typeString = new String();
|
||||
this.typeString += (char)(type >> 24);
|
||||
this.typeString += (char)(type >> 16 & 0xFF);
|
||||
this.typeString += (char)(type >> 8 & 0xFF);
|
||||
this.typeString += (char)(type & 0xFF);
|
||||
}
|
||||
|
||||
public int getLength() {
|
||||
return this.length;
|
||||
}
|
||||
|
||||
public int getType() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
public String getTypeString() {
|
||||
return this.typeString;
|
||||
}
|
||||
|
||||
public byte[] getData() {
|
||||
return this.data;
|
||||
}
|
||||
|
||||
public byte getByte(int offset) {
|
||||
return this.data[offset];
|
||||
}
|
||||
|
||||
public int getInt1(int offset) {
|
||||
return this.data[offset] & 0xFF;
|
||||
}
|
||||
|
||||
public int getInt2(int offset) {
|
||||
return (this.data[offset] & 0xFF) << 8 | this.data[offset + 1] & 0xFF;
|
||||
}
|
||||
|
||||
public int getInt4(int offset) {
|
||||
return (this.data[offset] & 0xFF) << 24 | (this.data[offset + 1] & 0xFF) << 16 | (this.data[offset + 2] & 0xFF) << 8 | this.data[offset + 3] & 0xFF;
|
||||
}
|
||||
|
||||
public String getString4(int offset) {
|
||||
String s = new String();
|
||||
s = s + (char)this.data[offset];
|
||||
s = s + (char)this.data[offset + 1];
|
||||
s = s + (char)this.data[offset + 2];
|
||||
s = s + (char)this.data[offset + 3];
|
||||
return s;
|
||||
}
|
||||
|
||||
public boolean isType(String typeName) {
|
||||
return this.typeString.equals(typeName);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
package com.sun.media.jai.codecimpl;
|
||||
|
||||
import com.sun.media.jai.codec.ImageCodec;
|
||||
import com.sun.media.jai.codec.ImageDecodeParam;
|
||||
import com.sun.media.jai.codec.ImageDecoder;
|
||||
import com.sun.media.jai.codec.ImageEncodeParam;
|
||||
import com.sun.media.jai.codec.ImageEncoder;
|
||||
import com.sun.media.jai.codec.PNGDecodeParam;
|
||||
import com.sun.media.jai.codec.PNGEncodeParam;
|
||||
import com.sun.media.jai.codec.SeekableStream;
|
||||
import java.awt.image.ColorModel;
|
||||
import java.awt.image.RenderedImage;
|
||||
import java.awt.image.SampleModel;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
public final class PNGCodec extends ImageCodec {
|
||||
public String getFormatName() {
|
||||
return "png";
|
||||
}
|
||||
|
||||
public Class getEncodeParamClass() {
|
||||
return PNGEncodeParam.class;
|
||||
}
|
||||
|
||||
public Class getDecodeParamClass() {
|
||||
return PNGDecodeParam.class;
|
||||
}
|
||||
|
||||
public boolean canEncodeImage(RenderedImage im, ImageEncodeParam param) {
|
||||
SampleModel sampleModel = im.getSampleModel();
|
||||
int dataType = sampleModel.getTransferType();
|
||||
if (dataType == 4 || dataType == 5)
|
||||
return false;
|
||||
int[] sampleSize = sampleModel.getSampleSize();
|
||||
int bitDepth = sampleSize[0];
|
||||
int i;
|
||||
for (i = 1; i < sampleSize.length; i++) {
|
||||
if (sampleSize[i] != bitDepth)
|
||||
return false;
|
||||
}
|
||||
if (bitDepth < 1 || bitDepth > 16)
|
||||
return false;
|
||||
i = sampleModel.getNumBands();
|
||||
if (i < 1 || i > 4)
|
||||
return false;
|
||||
ColorModel colorModel = im.getColorModel();
|
||||
if (colorModel instanceof java.awt.image.IndexColorModel && (
|
||||
i != 1 || bitDepth > 8))
|
||||
return false;
|
||||
if (param != null)
|
||||
if (param instanceof PNGEncodeParam) {
|
||||
if (colorModel instanceof java.awt.image.IndexColorModel) {
|
||||
if (!(param instanceof PNGEncodeParam.Palette))
|
||||
return false;
|
||||
} else if (i < 3) {
|
||||
if (!(param instanceof PNGEncodeParam.Gray))
|
||||
return false;
|
||||
} else if (!(param instanceof PNGEncodeParam.RGB)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected ImageEncoder createImageEncoder(OutputStream dst, ImageEncodeParam param) {
|
||||
PNGEncodeParam p = null;
|
||||
if (param != null)
|
||||
p = (PNGEncodeParam)param;
|
||||
return new PNGImageEncoder(dst, p);
|
||||
}
|
||||
|
||||
protected ImageDecoder createImageDecoder(InputStream src, ImageDecodeParam param) {
|
||||
PNGDecodeParam p = null;
|
||||
if (param != null)
|
||||
p = (PNGDecodeParam)param;
|
||||
return new PNGImageDecoder(src, p);
|
||||
}
|
||||
|
||||
protected ImageDecoder createImageDecoder(File src, ImageDecodeParam param) throws IOException {
|
||||
PNGDecodeParam p = null;
|
||||
if (param != null)
|
||||
p = (PNGDecodeParam)param;
|
||||
return new PNGImageDecoder(new FileInputStream(src), p);
|
||||
}
|
||||
|
||||
protected ImageDecoder createImageDecoder(SeekableStream src, ImageDecodeParam param) {
|
||||
PNGDecodeParam p = null;
|
||||
if (param != null)
|
||||
p = (PNGDecodeParam)param;
|
||||
return new PNGImageDecoder(src, p);
|
||||
}
|
||||
|
||||
public int getNumHeaderBytes() {
|
||||
return 8;
|
||||
}
|
||||
|
||||
public boolean isFormatRecognized(byte[] header) {
|
||||
return (header[0] == -119 && header[1] == 80 && header[2] == 78 && header[3] == 71 && header[4] == 13 && header[5] == 10 && header[6] == 26 && header[7] == 10);
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,23 @@
|
|||
package com.sun.media.jai.codecimpl;
|
||||
|
||||
import com.sun.media.jai.codec.ImageDecoderImpl;
|
||||
import com.sun.media.jai.codec.PNGDecodeParam;
|
||||
import java.awt.image.RenderedImage;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
public class PNGImageDecoder extends ImageDecoderImpl {
|
||||
public PNGImageDecoder(InputStream input, PNGDecodeParam param) {
|
||||
super(input, param);
|
||||
}
|
||||
|
||||
public RenderedImage decodeAsRenderedImage(int page) throws IOException {
|
||||
if (page != 0)
|
||||
throw new IOException(JaiI18N.getString("PNGImageDecoder19"));
|
||||
try {
|
||||
return new PNGImage(this.input, (PNGDecodeParam)this.param);
|
||||
} catch (Exception e) {
|
||||
throw CodecUtils.toIOException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,627 @@
|
|||
package com.sun.media.jai.codecimpl;
|
||||
|
||||
import com.sun.media.jai.codec.ImageEncoderImpl;
|
||||
import com.sun.media.jai.codec.PNGEncodeParam;
|
||||
import java.awt.image.ColorModel;
|
||||
import java.awt.image.IndexColorModel;
|
||||
import java.awt.image.Raster;
|
||||
import java.awt.image.RenderedImage;
|
||||
import java.awt.image.SampleModel;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.TimeZone;
|
||||
import java.util.zip.Deflater;
|
||||
import java.util.zip.DeflaterOutputStream;
|
||||
|
||||
public class PNGImageEncoder extends ImageEncoderImpl {
|
||||
private static final int PNG_COLOR_GRAY = 0;
|
||||
|
||||
private static final int PNG_COLOR_RGB = 2;
|
||||
|
||||
private static final int PNG_COLOR_PALETTE = 3;
|
||||
|
||||
private static final int PNG_COLOR_GRAY_ALPHA = 4;
|
||||
|
||||
private static final int PNG_COLOR_RGB_ALPHA = 6;
|
||||
|
||||
private static final byte[] magic = new byte[] { -119, 80, 78, 71, 13, 10, 26, 10 };
|
||||
|
||||
private PNGEncodeParam param;
|
||||
|
||||
private RenderedImage image;
|
||||
|
||||
private int width;
|
||||
|
||||
private int height;
|
||||
|
||||
private int bitDepth;
|
||||
|
||||
private int bitShift;
|
||||
|
||||
private int numBands;
|
||||
|
||||
private int colorType;
|
||||
|
||||
private int bpp;
|
||||
|
||||
private static int filterPrintableLatin1(byte[] data) {
|
||||
int len = 0;
|
||||
int prev = 0;
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
int d = data[i] & 0xFF;
|
||||
if (prev != 32 || d != 32) {
|
||||
if ((d > 32 && d <= 126) || (d >= 161 && d <= 255))
|
||||
data[len++] = (byte)d;
|
||||
prev = d;
|
||||
}
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
private boolean skipAlpha = false;
|
||||
|
||||
private boolean compressGray = false;
|
||||
|
||||
private boolean interlace;
|
||||
|
||||
private byte[] redPalette = null;
|
||||
|
||||
private byte[] greenPalette = null;
|
||||
|
||||
private byte[] bluePalette = null;
|
||||
|
||||
private byte[] alphaPalette = null;
|
||||
|
||||
private DataOutputStream dataOutput;
|
||||
|
||||
public PNGImageEncoder(OutputStream output, PNGEncodeParam param) {
|
||||
super(output, param);
|
||||
if (param != null)
|
||||
this.param = param;
|
||||
this.dataOutput = new DataOutputStream(output);
|
||||
}
|
||||
|
||||
private void writeMagic() throws IOException {
|
||||
this.dataOutput.write(magic);
|
||||
}
|
||||
|
||||
private void writeIHDR() throws IOException {
|
||||
ChunkStream cs = new ChunkStream("IHDR");
|
||||
cs.writeInt(this.width);
|
||||
cs.writeInt(this.height);
|
||||
cs.writeByte((byte)this.bitDepth);
|
||||
cs.writeByte((byte)this.colorType);
|
||||
cs.writeByte(0);
|
||||
cs.writeByte(0);
|
||||
cs.writeByte(this.interlace ? 1 : 0);
|
||||
cs.writeToStream(this.dataOutput);
|
||||
}
|
||||
|
||||
private byte[] prevRow = null;
|
||||
|
||||
private byte[] currRow = null;
|
||||
|
||||
private byte[][] filteredRows = null;
|
||||
|
||||
private static int clamp(int val, int maxValue) {
|
||||
return (val > maxValue) ? maxValue : val;
|
||||
}
|
||||
|
||||
private void encodePass(OutputStream os, Raster ras, int xOffset, int yOffset, int xSkip, int ySkip) throws IOException {
|
||||
int minX = ras.getMinX();
|
||||
int minY = ras.getMinY();
|
||||
int width = ras.getWidth();
|
||||
int height = ras.getHeight();
|
||||
xOffset *= this.numBands;
|
||||
xSkip *= this.numBands;
|
||||
int samplesPerByte = 8 / this.bitDepth;
|
||||
int numSamples = width * this.numBands;
|
||||
int[] samples = new int[numSamples];
|
||||
int pixels = (numSamples - xOffset + xSkip - 1) / xSkip;
|
||||
int bytesPerRow = pixels * this.numBands;
|
||||
if (this.bitDepth < 8) {
|
||||
bytesPerRow = (bytesPerRow + samplesPerByte - 1) / samplesPerByte;
|
||||
} else if (this.bitDepth == 16) {
|
||||
bytesPerRow *= 2;
|
||||
}
|
||||
if (bytesPerRow == 0)
|
||||
return;
|
||||
this.currRow = new byte[bytesPerRow + this.bpp];
|
||||
this.prevRow = new byte[bytesPerRow + this.bpp];
|
||||
this.filteredRows = new byte[5][bytesPerRow + this.bpp];
|
||||
int maxValue = (1 << this.bitDepth) - 1;
|
||||
for (int row = minY + yOffset; row < minY + height; row += ySkip) {
|
||||
int mask, s;
|
||||
ras.getPixels(minX, row, width, 1, samples);
|
||||
if (this.compressGray) {
|
||||
int shift = 8 - this.bitDepth;
|
||||
for (int i = 0; i < width; i++)
|
||||
samples[i] = samples[i] >> shift;
|
||||
}
|
||||
int count = this.bpp;
|
||||
int pos = 0;
|
||||
int tmp = 0;
|
||||
switch (this.bitDepth) {
|
||||
case 1:
|
||||
case 2:
|
||||
case 4:
|
||||
mask = samplesPerByte - 1;
|
||||
for (s = xOffset; s < numSamples; s += xSkip) {
|
||||
int val = clamp(samples[s] >> this.bitShift, maxValue);
|
||||
tmp = tmp << this.bitDepth | val;
|
||||
if ((pos++ & mask) == mask) {
|
||||
this.currRow[count++] = (byte)tmp;
|
||||
tmp = 0;
|
||||
}
|
||||
}
|
||||
if ((pos & mask) != 0) {
|
||||
tmp <<= (8 / this.bitDepth - (pos & mask)) * this.bitDepth;
|
||||
this.currRow[count++] = (byte)tmp;
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
for (s = xOffset; s < numSamples; s += xSkip) {
|
||||
for (int b = 0; b < this.numBands; b++)
|
||||
this.currRow[count++] = (byte)clamp(samples[s + b] >> this.bitShift, maxValue);
|
||||
}
|
||||
break;
|
||||
case 16:
|
||||
for (s = xOffset; s < numSamples; s += xSkip) {
|
||||
for (int b = 0; b < this.numBands; b++) {
|
||||
int val = clamp(samples[s + b] >> this.bitShift, maxValue);
|
||||
this.currRow[count++] = (byte)(val >> 8);
|
||||
this.currRow[count++] = (byte)(val & 0xFF);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
int filterType = this.param.filterRow(this.currRow, this.prevRow, this.filteredRows, bytesPerRow, this.bpp);
|
||||
os.write(filterType);
|
||||
os.write(this.filteredRows[filterType], this.bpp, bytesPerRow);
|
||||
byte[] swap = this.currRow;
|
||||
this.currRow = this.prevRow;
|
||||
this.prevRow = swap;
|
||||
}
|
||||
}
|
||||
|
||||
private void writeIDAT() throws IOException {
|
||||
IDATOutputStream ios = new IDATOutputStream(this.dataOutput, 8192);
|
||||
DeflaterOutputStream dos = new DeflaterOutputStream(ios, new Deflater(9));
|
||||
Raster ras = this.image.getData();
|
||||
if (this.skipAlpha) {
|
||||
int numBands = ras.getNumBands() - 1;
|
||||
int[] bandList = new int[numBands];
|
||||
for (int i = 0; i < numBands; i++)
|
||||
bandList[i] = i;
|
||||
ras = ras.createChild(0, 0, ras.getWidth(), ras.getHeight(), 0, 0, bandList);
|
||||
}
|
||||
if (this.interlace) {
|
||||
encodePass(dos, ras, 0, 0, 8, 8);
|
||||
encodePass(dos, ras, 4, 0, 8, 8);
|
||||
encodePass(dos, ras, 0, 4, 4, 8);
|
||||
encodePass(dos, ras, 2, 0, 4, 4);
|
||||
encodePass(dos, ras, 0, 2, 2, 4);
|
||||
encodePass(dos, ras, 1, 0, 2, 2);
|
||||
encodePass(dos, ras, 0, 1, 1, 2);
|
||||
} else {
|
||||
encodePass(dos, ras, 0, 0, 1, 1);
|
||||
}
|
||||
dos.finish();
|
||||
ios.flush();
|
||||
}
|
||||
|
||||
private void writeIEND() throws IOException {
|
||||
ChunkStream cs = new ChunkStream("IEND");
|
||||
cs.writeToStream(this.dataOutput);
|
||||
}
|
||||
|
||||
private static final float[] srgbChroma = new float[] { 0.3127F, 0.329F, 0.64F, 0.33F, 0.3F, 0.6F, 0.15F, 0.06F };
|
||||
|
||||
private void writeCHRM() throws IOException {
|
||||
if (this.param.isChromaticitySet() || this.param.isSRGBIntentSet()) {
|
||||
float[] chroma;
|
||||
ChunkStream cs = new ChunkStream("cHRM");
|
||||
if (!this.param.isSRGBIntentSet()) {
|
||||
chroma = this.param.getChromaticity();
|
||||
} else {
|
||||
chroma = srgbChroma;
|
||||
}
|
||||
for (int i = 0; i < 8; i++)
|
||||
cs.writeInt((int)(chroma[i] * 100000.0F));
|
||||
cs.writeToStream(this.dataOutput);
|
||||
}
|
||||
}
|
||||
|
||||
private void writeGAMA() throws IOException {
|
||||
if (this.param.isGammaSet() || this.param.isSRGBIntentSet()) {
|
||||
float gamma;
|
||||
ChunkStream cs = new ChunkStream("gAMA");
|
||||
if (!this.param.isSRGBIntentSet()) {
|
||||
gamma = this.param.getGamma();
|
||||
} else {
|
||||
gamma = 0.45454544F;
|
||||
}
|
||||
cs.writeInt((int)(gamma * 100000.0F));
|
||||
cs.writeToStream(this.dataOutput);
|
||||
}
|
||||
}
|
||||
|
||||
private void writeICCP() throws IOException {
|
||||
if (this.param.isICCProfileDataSet()) {
|
||||
ChunkStream cs = new ChunkStream("iCCP");
|
||||
String name = this.param.getICCProfileName();
|
||||
if (name == null || name.length() < 1) {
|
||||
name = "JAI-Placed Profile";
|
||||
} else {
|
||||
name = name.trim();
|
||||
if (name.length() > 79)
|
||||
name = name.substring(0, 79);
|
||||
}
|
||||
byte[] ICCProfileName = name.getBytes("ISO-8859-1");
|
||||
int length = filterPrintableLatin1(ICCProfileName);
|
||||
byte[] ICCProfileData = this.param.getICCProfileData();
|
||||
ByteArrayOutputStream iccDflStream = new ByteArrayOutputStream(ICCProfileData.length);
|
||||
DeflaterOutputStream dfl = new DeflaterOutputStream(iccDflStream);
|
||||
dfl.write(ICCProfileData);
|
||||
dfl.finish();
|
||||
cs.write(ICCProfileName, 0, length);
|
||||
cs.writeByte(0);
|
||||
cs.writeByte(0);
|
||||
cs.write(iccDflStream.toByteArray());
|
||||
dfl.close();
|
||||
cs.writeToStream(this.dataOutput);
|
||||
}
|
||||
}
|
||||
|
||||
private void writeSBIT() throws IOException {
|
||||
if (this.param.isSignificantBitsSet()) {
|
||||
ChunkStream cs = new ChunkStream("sBIT");
|
||||
int[] significantBits = this.param.getSignificantBits();
|
||||
int len = significantBits.length;
|
||||
for (int i = 0; i < len; i++)
|
||||
cs.writeByte(significantBits[i]);
|
||||
cs.writeToStream(this.dataOutput);
|
||||
}
|
||||
}
|
||||
|
||||
private void writeSRGB() throws IOException {
|
||||
if (this.param.isSRGBIntentSet()) {
|
||||
ChunkStream cs = new ChunkStream("sRGB");
|
||||
int intent = this.param.getSRGBIntent();
|
||||
cs.write(intent);
|
||||
cs.writeToStream(this.dataOutput);
|
||||
}
|
||||
}
|
||||
|
||||
private void writePLTE() throws IOException {
|
||||
if (this.redPalette == null)
|
||||
return;
|
||||
ChunkStream cs = new ChunkStream("PLTE");
|
||||
for (int i = 0; i < this.redPalette.length; i++) {
|
||||
cs.writeByte(this.redPalette[i]);
|
||||
cs.writeByte(this.greenPalette[i]);
|
||||
cs.writeByte(this.bluePalette[i]);
|
||||
}
|
||||
cs.writeToStream(this.dataOutput);
|
||||
}
|
||||
|
||||
private void writeBKGD() throws IOException {
|
||||
if (this.param.isBackgroundSet()) {
|
||||
int gray, index, rgb[];
|
||||
ChunkStream cs = new ChunkStream("bKGD");
|
||||
switch (this.colorType) {
|
||||
case 0:
|
||||
case 4:
|
||||
gray = ((PNGEncodeParam.Gray)this.param).getBackgroundGray();
|
||||
cs.writeShort(gray);
|
||||
break;
|
||||
case 3:
|
||||
index = ((PNGEncodeParam.Palette)this.param).getBackgroundPaletteIndex();
|
||||
cs.writeByte(index);
|
||||
break;
|
||||
case 2:
|
||||
case 6:
|
||||
rgb = ((PNGEncodeParam.RGB)this.param).getBackgroundRGB();
|
||||
cs.writeShort(rgb[0]);
|
||||
cs.writeShort(rgb[1]);
|
||||
cs.writeShort(rgb[2]);
|
||||
break;
|
||||
}
|
||||
cs.writeToStream(this.dataOutput);
|
||||
}
|
||||
}
|
||||
|
||||
private void writeHIST() throws IOException {
|
||||
if (this.param.isPaletteHistogramSet()) {
|
||||
ChunkStream cs = new ChunkStream("hIST");
|
||||
int[] hist = this.param.getPaletteHistogram();
|
||||
for (int i = 0; i < hist.length; i++)
|
||||
cs.writeShort(hist[i]);
|
||||
cs.writeToStream(this.dataOutput);
|
||||
}
|
||||
}
|
||||
|
||||
private void writeTRNS() throws IOException {
|
||||
if (this.param.isTransparencySet() && this.colorType != 4 && this.colorType != 6) {
|
||||
ChunkStream cs = new ChunkStream("tRNS");
|
||||
if (this.param instanceof PNGEncodeParam.Palette) {
|
||||
byte[] t = ((PNGEncodeParam.Palette)this.param).getPaletteTransparency();
|
||||
for (int i = 0; i < t.length; i++)
|
||||
cs.writeByte(t[i]);
|
||||
} else if (this.param instanceof PNGEncodeParam.Gray) {
|
||||
int t = ((PNGEncodeParam.Gray)this.param).getTransparentGray();
|
||||
cs.writeShort(t);
|
||||
} else if (this.param instanceof PNGEncodeParam.RGB) {
|
||||
int[] t = ((PNGEncodeParam.RGB)this.param).getTransparentRGB();
|
||||
cs.writeShort(t[0]);
|
||||
cs.writeShort(t[1]);
|
||||
cs.writeShort(t[2]);
|
||||
}
|
||||
cs.writeToStream(this.dataOutput);
|
||||
} else if (this.colorType == 3) {
|
||||
int lastEntry = Math.min(255, this.alphaPalette.length - 1);
|
||||
int nonOpaque;
|
||||
for (nonOpaque = lastEntry; nonOpaque >= 0 &&
|
||||
this.alphaPalette[nonOpaque] == -1; nonOpaque--);
|
||||
if (nonOpaque >= 0) {
|
||||
ChunkStream cs = new ChunkStream("tRNS");
|
||||
for (int i = 0; i <= nonOpaque; i++)
|
||||
cs.writeByte(this.alphaPalette[i]);
|
||||
cs.writeToStream(this.dataOutput);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void writePHYS() throws IOException {
|
||||
if (this.param.isPhysicalDimensionSet()) {
|
||||
ChunkStream cs = new ChunkStream("pHYs");
|
||||
int[] dims = this.param.getPhysicalDimension();
|
||||
cs.writeInt(dims[0]);
|
||||
cs.writeInt(dims[1]);
|
||||
cs.writeByte((byte)dims[2]);
|
||||
cs.writeToStream(this.dataOutput);
|
||||
}
|
||||
}
|
||||
|
||||
private void writeSPLT() throws IOException {
|
||||
if (this.param.isSuggestedPaletteSet()) {
|
||||
ChunkStream cs = new ChunkStream("sPLT");
|
||||
System.out.println("sPLT not supported yet.");
|
||||
cs.writeToStream(this.dataOutput);
|
||||
}
|
||||
}
|
||||
|
||||
private void writeTIME() throws IOException {
|
||||
if (this.param.isModificationTimeSet()) {
|
||||
ChunkStream cs = new ChunkStream("tIME");
|
||||
Date date = this.param.getModificationTime();
|
||||
TimeZone gmt = TimeZone.getTimeZone("GMT");
|
||||
GregorianCalendar cal = new GregorianCalendar(gmt);
|
||||
cal.setTime(date);
|
||||
int year = cal.get(1);
|
||||
int month = cal.get(2);
|
||||
int day = cal.get(5);
|
||||
int hour = cal.get(11);
|
||||
int minute = cal.get(12);
|
||||
int second = cal.get(13);
|
||||
cs.writeShort(year);
|
||||
cs.writeByte(month + 1);
|
||||
cs.writeByte(day);
|
||||
cs.writeByte(hour);
|
||||
cs.writeByte(minute);
|
||||
cs.writeByte(second);
|
||||
cs.writeToStream(this.dataOutput);
|
||||
}
|
||||
}
|
||||
|
||||
private void writeTEXT() throws IOException {
|
||||
if (this.param.isTextSet()) {
|
||||
String[] text = this.param.getText();
|
||||
for (int i = 0; i < text.length / 2; i++) {
|
||||
text[i << 1] = text[i << 1].trim();
|
||||
byte[] keyword = text[2 * i].getBytes("ISO-8859-1");
|
||||
int len = filterPrintableLatin1(keyword);
|
||||
ChunkStream cs = new ChunkStream("tEXt");
|
||||
cs.write(keyword, 0, Math.min(len, 79));
|
||||
text[(i << 1) + 1] = text[(i << 1) + 1].trim();
|
||||
byte[] value = text[(i << 1) + 1].getBytes();
|
||||
len = filterPrintableLatin1(value);
|
||||
cs.write(0);
|
||||
cs.write(value, 0, len);
|
||||
cs.writeToStream(this.dataOutput);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void writeZTXT() throws IOException {
|
||||
if (this.param.isCompressedTextSet()) {
|
||||
String[] text = this.param.getCompressedText();
|
||||
for (int i = 0; i < text.length / 2; i++) {
|
||||
text[i << 1] = text[i << 1].trim();
|
||||
byte[] keyword = text[2 * i].getBytes();
|
||||
int len = filterPrintableLatin1(keyword);
|
||||
ChunkStream cs = new ChunkStream("zTXt");
|
||||
cs.write(keyword, 0, Math.min(len, 79));
|
||||
text[(i << 1) + 1] = text[(i << 1) + 1].trim();
|
||||
byte[] value = text[2 * i + 1].getBytes();
|
||||
len = filterPrintableLatin1(value);
|
||||
cs.write(0);
|
||||
cs.write(0);
|
||||
DeflaterOutputStream dos = new DeflaterOutputStream(cs);
|
||||
dos.write(value, 0, len);
|
||||
dos.finish();
|
||||
cs.writeToStream(this.dataOutput);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void writePrivateChunks() throws IOException {
|
||||
int numChunks = this.param.getNumPrivateChunks();
|
||||
for (int i = 0; i < numChunks; i++) {
|
||||
String type = this.param.getPrivateChunkType(i);
|
||||
char char3 = type.charAt(3);
|
||||
byte[] data = this.param.getPrivateChunkData(i);
|
||||
ChunkStream cs = new ChunkStream(type);
|
||||
cs.write(data);
|
||||
cs.writeToStream(this.dataOutput);
|
||||
}
|
||||
}
|
||||
|
||||
private PNGEncodeParam.Gray createGrayParam(byte[] redPalette, byte[] greenPalette, byte[] bluePalette, byte[] alphaPalette) {
|
||||
PNGEncodeParam.Gray param = new PNGEncodeParam.Gray();
|
||||
int numTransparent = 0;
|
||||
int grayFactor = 255 / ((1 << this.bitDepth) - 1);
|
||||
int entries = 1 << this.bitDepth;
|
||||
for (int i = 0; i < entries; i++) {
|
||||
byte red = redPalette[i];
|
||||
if (red != i * grayFactor || red != greenPalette[i] || red != bluePalette[i])
|
||||
return null;
|
||||
byte alpha = alphaPalette[i];
|
||||
if (alpha == 0) {
|
||||
param.setTransparentGray(i);
|
||||
numTransparent++;
|
||||
if (numTransparent > 1)
|
||||
return null;
|
||||
} else if (alpha != -1) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return param;
|
||||
}
|
||||
|
||||
public void encode(RenderedImage im) throws IOException {
|
||||
this.image = im;
|
||||
this.width = this.image.getWidth();
|
||||
this.height = this.image.getHeight();
|
||||
SampleModel sampleModel = this.image.getSampleModel();
|
||||
int[] sampleSize = sampleModel.getSampleSize();
|
||||
this.bitDepth = -1;
|
||||
this.bitShift = 0;
|
||||
if (this.param instanceof PNGEncodeParam.Gray) {
|
||||
PNGEncodeParam.Gray paramg = (PNGEncodeParam.Gray)this.param;
|
||||
if (paramg.isBitDepthSet())
|
||||
this.bitDepth = paramg.getBitDepth();
|
||||
if (paramg.isBitShiftSet())
|
||||
this.bitShift = paramg.getBitShift();
|
||||
}
|
||||
if (this.bitDepth == -1) {
|
||||
this.bitDepth = sampleSize[0];
|
||||
for (int i = 1; i < sampleSize.length; i++) {
|
||||
if (sampleSize[i] != this.bitDepth)
|
||||
throw new RuntimeException();
|
||||
}
|
||||
if (this.bitDepth > 2 && this.bitDepth < 4) {
|
||||
this.bitDepth = 4;
|
||||
} else if (this.bitDepth > 4 && this.bitDepth < 8) {
|
||||
this.bitDepth = 8;
|
||||
} else if (this.bitDepth > 8 && this.bitDepth < 16) {
|
||||
this.bitDepth = 16;
|
||||
} else if (this.bitDepth > 16) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
this.numBands = sampleModel.getNumBands();
|
||||
this.bpp = this.numBands * ((this.bitDepth == 16) ? 2 : 1);
|
||||
ColorModel colorModel = this.image.getColorModel();
|
||||
if (colorModel instanceof IndexColorModel) {
|
||||
if (this.bitDepth < 1 || this.bitDepth > 8)
|
||||
throw new RuntimeException();
|
||||
if (sampleModel.getNumBands() != 1)
|
||||
throw new RuntimeException();
|
||||
IndexColorModel icm = (IndexColorModel)colorModel;
|
||||
int size = icm.getMapSize();
|
||||
this.redPalette = new byte[size];
|
||||
this.greenPalette = new byte[size];
|
||||
this.bluePalette = new byte[size];
|
||||
this.alphaPalette = new byte[size];
|
||||
icm.getReds(this.redPalette);
|
||||
icm.getGreens(this.greenPalette);
|
||||
icm.getBlues(this.bluePalette);
|
||||
icm.getAlphas(this.alphaPalette);
|
||||
this.bpp = 1;
|
||||
if (this.param == null)
|
||||
this.param = createGrayParam(this.redPalette, this.greenPalette, this.bluePalette, this.alphaPalette);
|
||||
if (this.param == null)
|
||||
this.param = new PNGEncodeParam.Palette();
|
||||
if (this.param instanceof PNGEncodeParam.Palette) {
|
||||
PNGEncodeParam.Palette parami = (PNGEncodeParam.Palette)this.param;
|
||||
if (parami.isPaletteSet()) {
|
||||
int[] palette = parami.getPalette();
|
||||
size = palette.length / 3;
|
||||
int index = 0;
|
||||
for (int i = 0; i < size; i++) {
|
||||
this.redPalette[i] = (byte)palette[index++];
|
||||
this.greenPalette[i] = (byte)palette[index++];
|
||||
this.bluePalette[i] = (byte)palette[index++];
|
||||
this.alphaPalette[i] = -1;
|
||||
}
|
||||
}
|
||||
this.colorType = 3;
|
||||
} else if (this.param instanceof PNGEncodeParam.Gray) {
|
||||
this.redPalette = this.greenPalette = this.bluePalette = this.alphaPalette = null;
|
||||
this.colorType = 0;
|
||||
} else {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
} else if (this.numBands == 1) {
|
||||
if (this.param == null)
|
||||
this.param = new PNGEncodeParam.Gray();
|
||||
this.colorType = 0;
|
||||
} else if (this.numBands == 2) {
|
||||
if (this.param == null)
|
||||
this.param = new PNGEncodeParam.Gray();
|
||||
if (this.param.isTransparencySet()) {
|
||||
this.skipAlpha = true;
|
||||
this.numBands = 1;
|
||||
if (sampleSize[0] == 8 && this.bitDepth < 8)
|
||||
this.compressGray = true;
|
||||
this.bpp = (this.bitDepth == 16) ? 2 : 1;
|
||||
this.colorType = 0;
|
||||
} else {
|
||||
if (this.bitDepth < 8)
|
||||
this.bitDepth = 8;
|
||||
this.colorType = 4;
|
||||
}
|
||||
} else if (this.numBands == 3) {
|
||||
if (this.param == null)
|
||||
this.param = new PNGEncodeParam.RGB();
|
||||
this.colorType = 2;
|
||||
} else if (this.numBands == 4) {
|
||||
if (this.param == null)
|
||||
this.param = new PNGEncodeParam.RGB();
|
||||
if (this.param.isTransparencySet()) {
|
||||
this.skipAlpha = true;
|
||||
this.numBands = 3;
|
||||
this.bpp = (this.bitDepth == 16) ? 6 : 3;
|
||||
this.colorType = 2;
|
||||
} else {
|
||||
this.colorType = 6;
|
||||
}
|
||||
}
|
||||
this.interlace = this.param.getInterlacing();
|
||||
writeMagic();
|
||||
writeIHDR();
|
||||
writeCHRM();
|
||||
writeGAMA();
|
||||
writeICCP();
|
||||
writeSBIT();
|
||||
writeSRGB();
|
||||
writePLTE();
|
||||
writeHIST();
|
||||
writeTRNS();
|
||||
writeBKGD();
|
||||
writePHYS();
|
||||
writeSPLT();
|
||||
writeTIME();
|
||||
writeTEXT();
|
||||
writeZTXT();
|
||||
writePrivateChunks();
|
||||
writeIDAT();
|
||||
writeIEND();
|
||||
this.dataOutput.flush();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
package com.sun.media.jai.codecimpl;
|
||||
|
||||
import com.sun.media.jai.codec.ForwardSeekableStream;
|
||||
import com.sun.media.jai.codec.ImageCodec;
|
||||
import com.sun.media.jai.codec.ImageDecodeParam;
|
||||
import com.sun.media.jai.codec.ImageDecoder;
|
||||
import com.sun.media.jai.codec.ImageEncodeParam;
|
||||
import com.sun.media.jai.codec.ImageEncoder;
|
||||
import com.sun.media.jai.codec.PNMEncodeParam;
|
||||
import com.sun.media.jai.codec.SeekableStream;
|
||||
import java.awt.image.RenderedImage;
|
||||
import java.awt.image.SampleModel;
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
public final class PNMCodec extends ImageCodec {
|
||||
public String getFormatName() {
|
||||
return "pnm";
|
||||
}
|
||||
|
||||
public Class getEncodeParamClass() {
|
||||
return PNMEncodeParam.class;
|
||||
}
|
||||
|
||||
public Class getDecodeParamClass() {
|
||||
return Object.class;
|
||||
}
|
||||
|
||||
public boolean canEncodeImage(RenderedImage im, ImageEncodeParam param) {
|
||||
SampleModel sampleModel = im.getSampleModel();
|
||||
int dataType = sampleModel.getTransferType();
|
||||
if (dataType == 4 || dataType == 5)
|
||||
return false;
|
||||
int numBands = sampleModel.getNumBands();
|
||||
if (numBands != 1 && numBands != 3)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
protected ImageEncoder createImageEncoder(OutputStream dst, ImageEncodeParam param) {
|
||||
PNMEncodeParam p = null;
|
||||
if (param != null)
|
||||
p = (PNMEncodeParam)param;
|
||||
return new PNMImageEncoder(dst, p);
|
||||
}
|
||||
|
||||
protected ImageDecoder createImageDecoder(InputStream src, ImageDecodeParam param) {
|
||||
if (!(src instanceof BufferedInputStream))
|
||||
src = new BufferedInputStream(src);
|
||||
return new PNMImageDecoder(new ForwardSeekableStream(src), null);
|
||||
}
|
||||
|
||||
protected ImageDecoder createImageDecoder(SeekableStream src, ImageDecodeParam param) {
|
||||
return new PNMImageDecoder(src, null);
|
||||
}
|
||||
|
||||
public int getNumHeaderBytes() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
public boolean isFormatRecognized(byte[] header) {
|
||||
return (header[0] == 80 && header[1] >= 49 && header[1] <= 54);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,224 @@
|
|||
package com.sun.media.jai.codecimpl;
|
||||
|
||||
import com.sun.media.jai.codec.ImageCodec;
|
||||
import com.sun.media.jai.codec.SeekableStream;
|
||||
import com.sun.media.jai.codecimpl.util.ImagingException;
|
||||
import com.sun.media.jai.codecimpl.util.RasterFactory;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.image.DataBuffer;
|
||||
import java.awt.image.DataBufferByte;
|
||||
import java.awt.image.DataBufferInt;
|
||||
import java.awt.image.DataBufferUShort;
|
||||
import java.awt.image.MultiPixelPackedSampleModel;
|
||||
import java.awt.image.Raster;
|
||||
import java.awt.image.WritableRaster;
|
||||
import java.io.IOException;
|
||||
import java.security.AccessController;
|
||||
import sun.security.action.GetPropertyAction;
|
||||
|
||||
class PNMImage extends SimpleRenderedImage {
|
||||
private static final int PBM_ASCII = 49;
|
||||
|
||||
private static final int PGM_ASCII = 50;
|
||||
|
||||
private static final int PPM_ASCII = 51;
|
||||
|
||||
private static final int PBM_RAW = 52;
|
||||
|
||||
private static final int PGM_RAW = 53;
|
||||
|
||||
private static final int PPM_RAW = 54;
|
||||
|
||||
private static final int LINE_FEED = 10;
|
||||
|
||||
private SeekableStream input;
|
||||
|
||||
private byte[] lineSeparator;
|
||||
|
||||
private int variant;
|
||||
|
||||
private int maxValue;
|
||||
|
||||
private Raster theTile;
|
||||
|
||||
private int numBands;
|
||||
|
||||
private int dataType;
|
||||
|
||||
public PNMImage(SeekableStream input) {
|
||||
this.theTile = null;
|
||||
this.input = input;
|
||||
String ls = (String)AccessController.doPrivileged(new GetPropertyAction("line.separator"));
|
||||
this.lineSeparator = ls.getBytes();
|
||||
try {
|
||||
if (this.input.read() != 80)
|
||||
throw new RuntimeException(JaiI18N.getString("PNMImageDecoder0"));
|
||||
this.variant = this.input.read();
|
||||
if (this.variant < 49 || this.variant > 54)
|
||||
throw new RuntimeException(JaiI18N.getString("PNMImageDecoder1"));
|
||||
this.width = readInteger(this.input);
|
||||
this.height = readInteger(this.input);
|
||||
if (this.variant == 49 || this.variant == 52) {
|
||||
this.maxValue = 1;
|
||||
} else {
|
||||
this.maxValue = readInteger(this.input);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
String message = JaiI18N.getString("PNMImageDecoder6");
|
||||
sendExceptionToListener(message, e);
|
||||
}
|
||||
if (isRaw(this.variant) && this.maxValue >= 256)
|
||||
this.maxValue = 255;
|
||||
this.tileWidth = this.width;
|
||||
this.tileHeight = this.height;
|
||||
if (this.variant == 51 || this.variant == 54) {
|
||||
this.numBands = 3;
|
||||
} else {
|
||||
this.numBands = 1;
|
||||
}
|
||||
if (this.maxValue < 256) {
|
||||
this.dataType = 0;
|
||||
} else if (this.maxValue < 65536) {
|
||||
this.dataType = 1;
|
||||
} else {
|
||||
this.dataType = 3;
|
||||
}
|
||||
if (this.variant == 49 || this.variant == 52) {
|
||||
this.sampleModel = new MultiPixelPackedSampleModel(0, this.width, this.height, 1);
|
||||
this.colorModel = ImageCodec.createGrayIndexColorModel(this.sampleModel, false);
|
||||
} else {
|
||||
int[] bandOffsets = (this.numBands == 1) ? new int[] { 0 } : new int[] { 0, 1, 2 };
|
||||
this.sampleModel = RasterFactory.createPixelInterleavedSampleModel(this.dataType, this.tileWidth, this.tileHeight, this.numBands, this.tileWidth * this.numBands, bandOffsets);
|
||||
this.colorModel = ImageCodec.createComponentColorModel(this.sampleModel);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isRaw(int v) {
|
||||
return (v >= 52);
|
||||
}
|
||||
|
||||
private int readInteger(SeekableStream in) throws IOException {
|
||||
int ret = 0;
|
||||
boolean foundDigit = false;
|
||||
int b;
|
||||
while ((b = in.read()) != -1) {
|
||||
char c = (char)b;
|
||||
if (Character.isDigit(c)) {
|
||||
ret = ret * 10 + Character.digit(c, 10);
|
||||
foundDigit = true;
|
||||
continue;
|
||||
}
|
||||
if (c == '#') {
|
||||
int length = this.lineSeparator.length;
|
||||
while ((b = in.read()) != -1) {
|
||||
boolean eol = false;
|
||||
for (int i = 0; i < length; i++) {
|
||||
if (b == this.lineSeparator[i]) {
|
||||
eol = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (eol)
|
||||
break;
|
||||
}
|
||||
if (b == -1)
|
||||
break;
|
||||
}
|
||||
if (foundDigit)
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
private Raster computeTile(int tileX, int tileY) {
|
||||
Point org = new Point(tileXToX(tileX), tileYToY(tileY));
|
||||
WritableRaster tile = Raster.createWritableRaster(this.sampleModel, org);
|
||||
Rectangle tileRect = tile.getBounds();
|
||||
try {
|
||||
DataBuffer dataBuffer;
|
||||
byte[] pixels;
|
||||
int size, offset;
|
||||
DataBufferByte bbuf;
|
||||
int row;
|
||||
byte[] byteArray;
|
||||
int i;
|
||||
DataBufferUShort sbuf;
|
||||
short[] shortArray;
|
||||
int j;
|
||||
DataBufferInt ibuf;
|
||||
int intArray[], k;
|
||||
switch (this.variant) {
|
||||
case 49:
|
||||
case 52:
|
||||
dataBuffer = tile.getDataBuffer();
|
||||
if (isRaw(this.variant)) {
|
||||
byte[] buf = ((DataBufferByte)dataBuffer).getData();
|
||||
this.input.readFully(buf, 0, buf.length);
|
||||
break;
|
||||
}
|
||||
pixels = new byte[8 * this.width];
|
||||
offset = 0;
|
||||
for (row = 0; row < this.tileHeight; row += 8) {
|
||||
int rows = Math.min(8, this.tileHeight - row);
|
||||
int len = (rows * this.width + 7) / 8;
|
||||
for (int m = 0; m < rows * this.width; m++)
|
||||
pixels[m] = (byte)readInteger(this.input);
|
||||
this.sampleModel.setDataElements(tileRect.x, row, tileRect.width, rows, pixels, dataBuffer);
|
||||
}
|
||||
break;
|
||||
case 50:
|
||||
case 51:
|
||||
case 53:
|
||||
case 54:
|
||||
size = this.width * this.height * this.numBands;
|
||||
switch (this.dataType) {
|
||||
case 0:
|
||||
bbuf = (DataBufferByte)tile.getDataBuffer();
|
||||
byteArray = bbuf.getData();
|
||||
if (isRaw(this.variant)) {
|
||||
this.input.readFully(byteArray);
|
||||
break;
|
||||
}
|
||||
for (i = 0; i < size; i++)
|
||||
byteArray[i] = (byte)readInteger(this.input);
|
||||
break;
|
||||
case 1:
|
||||
sbuf = (DataBufferUShort)tile.getDataBuffer();
|
||||
shortArray = sbuf.getData();
|
||||
for (j = 0; j < size; j++)
|
||||
shortArray[j] = (short)readInteger(this.input);
|
||||
break;
|
||||
case 3:
|
||||
ibuf = (DataBufferInt)tile.getDataBuffer();
|
||||
intArray = ibuf.getData();
|
||||
for (k = 0; k < size; k++)
|
||||
intArray[k] = readInteger(this.input);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
this.input.close();
|
||||
} catch (IOException e) {
|
||||
String message = JaiI18N.getString("PNMImageDecoder7");
|
||||
sendExceptionToListener(message, e);
|
||||
}
|
||||
return tile;
|
||||
}
|
||||
|
||||
public synchronized Raster getTile(int tileX, int tileY) {
|
||||
if (tileX != 0 || tileY != 0)
|
||||
throw new IllegalArgumentException(JaiI18N.getString("PNMImageDecoder4"));
|
||||
if (this.theTile == null)
|
||||
this.theTile = computeTile(tileX, tileY);
|
||||
return this.theTile;
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
this.theTile = null;
|
||||
}
|
||||
|
||||
private void sendExceptionToListener(String message, Exception e) {
|
||||
ImagingListenerProxy.errorOccurred(message, new ImagingException(message, e), this, false);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
package com.sun.media.jai.codecimpl;
|
||||
|
||||
import com.sun.media.jai.codec.ImageDecodeParam;
|
||||
import com.sun.media.jai.codec.ImageDecoderImpl;
|
||||
import com.sun.media.jai.codec.SeekableStream;
|
||||
import java.awt.image.RenderedImage;
|
||||
import java.io.IOException;
|
||||
|
||||
public class PNMImageDecoder extends ImageDecoderImpl {
|
||||
public PNMImageDecoder(SeekableStream input, ImageDecodeParam param) {
|
||||
super(input, param);
|
||||
}
|
||||
|
||||
public RenderedImage decodeAsRenderedImage(int page) throws IOException {
|
||||
if (page != 0)
|
||||
throw new IOException(JaiI18N.getString("PNMImageDecoder5"));
|
||||
try {
|
||||
return new PNMImage(this.input);
|
||||
} catch (Exception e) {
|
||||
throw CodecUtils.toIOException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,288 @@
|
|||
package com.sun.media.jai.codecimpl;
|
||||
|
||||
import com.sun.media.jai.codec.ImageEncodeParam;
|
||||
import com.sun.media.jai.codec.ImageEncoderImpl;
|
||||
import com.sun.media.jai.codec.PNMEncodeParam;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.image.ColorModel;
|
||||
import java.awt.image.ComponentSampleModel;
|
||||
import java.awt.image.DataBufferByte;
|
||||
import java.awt.image.IndexColorModel;
|
||||
import java.awt.image.MultiPixelPackedSampleModel;
|
||||
import java.awt.image.Raster;
|
||||
import java.awt.image.RenderedImage;
|
||||
import java.awt.image.SampleModel;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.security.AccessController;
|
||||
import sun.security.action.GetPropertyAction;
|
||||
|
||||
public class PNMImageEncoder extends ImageEncoderImpl {
|
||||
private static final int PBM_ASCII = 49;
|
||||
|
||||
private static final int PGM_ASCII = 50;
|
||||
|
||||
private static final int PPM_ASCII = 51;
|
||||
|
||||
private static final int PBM_RAW = 52;
|
||||
|
||||
private static final int PGM_RAW = 53;
|
||||
|
||||
private static final int PPM_RAW = 54;
|
||||
|
||||
private static final int SPACE = 32;
|
||||
|
||||
private static final String COMMENT = "# written by com.sun.media.jai.codecimpl.PNMImageEncoder";
|
||||
|
||||
private byte[] lineSeparator;
|
||||
|
||||
private int variant;
|
||||
|
||||
private int maxValue;
|
||||
|
||||
public PNMImageEncoder(OutputStream output, ImageEncodeParam param) {
|
||||
super(output, param);
|
||||
if (this.param == null)
|
||||
this.param = new PNMEncodeParam();
|
||||
}
|
||||
|
||||
public void encode(RenderedImage im) throws IOException {
|
||||
int minX = im.getMinX();
|
||||
int minY = im.getMinY();
|
||||
int width = im.getWidth();
|
||||
int height = im.getHeight();
|
||||
int tileHeight = im.getTileHeight();
|
||||
SampleModel sampleModel = im.getSampleModel();
|
||||
ColorModel colorModel = im.getColorModel();
|
||||
String ls = (String)AccessController.doPrivileged(new GetPropertyAction("line.separator"));
|
||||
this.lineSeparator = ls.getBytes();
|
||||
int dataType = sampleModel.getTransferType();
|
||||
if (dataType == 4 || dataType == 5)
|
||||
throw new RuntimeException(JaiI18N.getString("PNMImageEncoder0"));
|
||||
int[] sampleSize = sampleModel.getSampleSize();
|
||||
int numBands = sampleModel.getNumBands();
|
||||
byte[] reds = null;
|
||||
byte[] greens = null;
|
||||
byte[] blues = null;
|
||||
boolean isPBMInverted = false;
|
||||
if (numBands == 1) {
|
||||
if (colorModel instanceof IndexColorModel) {
|
||||
IndexColorModel icm = (IndexColorModel)colorModel;
|
||||
int mapSize = icm.getMapSize();
|
||||
if (mapSize < 1 << sampleSize[0])
|
||||
throw new RuntimeException(JaiI18N.getString("PNMImageEncoder1"));
|
||||
if (sampleSize[0] == 1) {
|
||||
this.variant = 52;
|
||||
isPBMInverted = (icm.getRed(1) + icm.getGreen(1) + icm.getBlue(1) > icm.getRed(0) + icm.getGreen(0) + icm.getBlue(0));
|
||||
} else {
|
||||
this.variant = 54;
|
||||
reds = new byte[mapSize];
|
||||
greens = new byte[mapSize];
|
||||
blues = new byte[mapSize];
|
||||
icm.getReds(reds);
|
||||
icm.getGreens(greens);
|
||||
icm.getBlues(blues);
|
||||
}
|
||||
} else if (sampleSize[0] == 1) {
|
||||
this.variant = 52;
|
||||
} else if (sampleSize[0] <= 8) {
|
||||
this.variant = 53;
|
||||
} else {
|
||||
this.variant = 50;
|
||||
}
|
||||
} else if (numBands == 3) {
|
||||
if (sampleSize[0] <= 8 && sampleSize[1] <= 8 && sampleSize[2] <= 8) {
|
||||
this.variant = 54;
|
||||
} else {
|
||||
this.variant = 51;
|
||||
}
|
||||
} else {
|
||||
throw new RuntimeException(JaiI18N.getString("PNMImageEncoder2"));
|
||||
}
|
||||
if (((PNMEncodeParam)this.param).getRaw()) {
|
||||
if (!isRaw(this.variant)) {
|
||||
boolean canUseRaw = true;
|
||||
for (int i = 0; i < sampleSize.length; i++) {
|
||||
if (sampleSize[i] > 8) {
|
||||
canUseRaw = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (canUseRaw)
|
||||
this.variant += 3;
|
||||
}
|
||||
} else if (isRaw(this.variant)) {
|
||||
this.variant -= 3;
|
||||
}
|
||||
this.maxValue = (1 << sampleSize[0]) - 1;
|
||||
this.output.write(80);
|
||||
this.output.write(this.variant);
|
||||
this.output.write(this.lineSeparator);
|
||||
this.output.write("# written by com.sun.media.jai.codecimpl.PNMImageEncoder".getBytes());
|
||||
this.output.write(this.lineSeparator);
|
||||
writeInteger(this.output, width);
|
||||
this.output.write(32);
|
||||
writeInteger(this.output, height);
|
||||
if (this.variant != 52 && this.variant != 49) {
|
||||
this.output.write(this.lineSeparator);
|
||||
writeInteger(this.output, this.maxValue);
|
||||
}
|
||||
if (this.variant == 52 || this.variant == 53 || this.variant == 54)
|
||||
this.output.write(10);
|
||||
boolean writeOptimal = false;
|
||||
if (this.variant == 52 && sampleModel.getTransferType() == 0 && sampleModel instanceof MultiPixelPackedSampleModel) {
|
||||
MultiPixelPackedSampleModel mppsm = (MultiPixelPackedSampleModel)sampleModel;
|
||||
if (mppsm.getDataBitOffset() == 0 && mppsm.getPixelBitStride() == 1)
|
||||
writeOptimal = true;
|
||||
} else if ((this.variant == 53 || this.variant == 54) && sampleModel instanceof ComponentSampleModel && !(colorModel instanceof IndexColorModel)) {
|
||||
ComponentSampleModel csm = (ComponentSampleModel)sampleModel;
|
||||
if (csm.getPixelStride() == numBands) {
|
||||
writeOptimal = true;
|
||||
if (this.variant == 54) {
|
||||
int[] bandOffsets = csm.getBandOffsets();
|
||||
for (int b = 0; b < numBands; b++) {
|
||||
if (bandOffsets[b] != b) {
|
||||
writeOptimal = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (writeOptimal) {
|
||||
int bytesPerRow = (this.variant == 52) ? ((width + 7) / 8) : (width * sampleModel.getNumBands());
|
||||
int numYTiles = im.getNumYTiles();
|
||||
Rectangle imageBounds = new Rectangle(im.getMinX(), im.getMinY(), im.getWidth(), im.getHeight());
|
||||
Rectangle stripRect = new Rectangle(im.getMinX(), im.getMinTileY() * im.getTileHeight() + im.getTileGridYOffset(), im.getWidth(), im.getTileHeight());
|
||||
byte[] invertedData = null;
|
||||
if (isPBMInverted)
|
||||
invertedData = new byte[bytesPerRow];
|
||||
for (int j = 0; j < numYTiles; j++) {
|
||||
if (j == numYTiles - 1)
|
||||
stripRect.height = im.getHeight() - stripRect.y;
|
||||
Rectangle encodedRect = stripRect.intersection(imageBounds);
|
||||
Raster strip = im.getData(encodedRect);
|
||||
byte[] bdata = ((DataBufferByte)strip.getDataBuffer()).getData();
|
||||
int rowStride = (this.variant == 52) ? ((MultiPixelPackedSampleModel)strip.getSampleModel()).getScanlineStride() : ((ComponentSampleModel)strip.getSampleModel()).getScanlineStride();
|
||||
if (rowStride == bytesPerRow && !isPBMInverted) {
|
||||
this.output.write(bdata, 0, bdata.length);
|
||||
} else {
|
||||
int offset = 0;
|
||||
for (int i = 0; i < encodedRect.height; i++) {
|
||||
if (isPBMInverted) {
|
||||
for (int k = 0; k < bytesPerRow; k++)
|
||||
invertedData[k] = (byte)(bdata[offset + k] & 0xFF ^ 0xFFFFFFFF);
|
||||
this.output.write(invertedData, 0, bytesPerRow);
|
||||
} else {
|
||||
this.output.write(bdata, offset, bytesPerRow);
|
||||
}
|
||||
offset += rowStride;
|
||||
}
|
||||
}
|
||||
stripRect.y += tileHeight;
|
||||
}
|
||||
this.output.flush();
|
||||
return;
|
||||
}
|
||||
int[] pixels = new int[8 * width * numBands];
|
||||
byte[] bpixels = (reds == null) ? new byte[8 * width * numBands] : new byte[8 * width * 3];
|
||||
int count = 0;
|
||||
int lastRow = minY + height;
|
||||
for (int row = minY; row < lastRow; row += 8) {
|
||||
int i, kdst, ksrc, j;
|
||||
int rows = Math.min(8, lastRow - row);
|
||||
int size = rows * width * numBands;
|
||||
Raster src = im.getData(new Rectangle(minX, row, width, rows));
|
||||
src.getPixels(minX, row, width, rows, pixels);
|
||||
if (isPBMInverted)
|
||||
for (int k = 0; k < size; k++)
|
||||
pixels[k] = pixels[k] ^ 0x1;
|
||||
switch (this.variant) {
|
||||
case 49:
|
||||
case 50:
|
||||
for (i = 0; i < size; i++) {
|
||||
if (count++ % 16 == 0) {
|
||||
this.output.write(this.lineSeparator);
|
||||
} else {
|
||||
this.output.write(32);
|
||||
}
|
||||
writeInteger(this.output, pixels[i]);
|
||||
}
|
||||
this.output.write(this.lineSeparator);
|
||||
break;
|
||||
case 51:
|
||||
if (reds == null) {
|
||||
for (int k = 0; k < size; k++) {
|
||||
if (count++ % 16 == 0) {
|
||||
this.output.write(this.lineSeparator);
|
||||
} else {
|
||||
this.output.write(32);
|
||||
}
|
||||
writeInteger(this.output, pixels[k]);
|
||||
}
|
||||
} else {
|
||||
for (int k = 0; k < size; k++) {
|
||||
if (count++ % 16 == 0) {
|
||||
this.output.write(this.lineSeparator);
|
||||
} else {
|
||||
this.output.write(32);
|
||||
}
|
||||
writeInteger(this.output, reds[pixels[k]] & 0xFF);
|
||||
this.output.write(32);
|
||||
writeInteger(this.output, greens[pixels[k]] & 0xFF);
|
||||
this.output.write(32);
|
||||
writeInteger(this.output, blues[pixels[k]] & 0xFF);
|
||||
}
|
||||
}
|
||||
this.output.write(this.lineSeparator);
|
||||
break;
|
||||
case 52:
|
||||
kdst = 0;
|
||||
ksrc = 0;
|
||||
for (j = 0; j < size / 8; j++) {
|
||||
int b = pixels[ksrc++] << 7 | pixels[ksrc++] << 6 | pixels[ksrc++] << 5 | pixels[ksrc++] << 4 | pixels[ksrc++] << 3 | pixels[ksrc++] << 2 | pixels[ksrc++] << 1 | pixels[ksrc++];
|
||||
bpixels[kdst++] = (byte)b;
|
||||
}
|
||||
if (size % 8 > 0) {
|
||||
int b = 0;
|
||||
for (int k = 0; k < size % 8; k++)
|
||||
b |= pixels[size + k] << 7 - k;
|
||||
bpixels[kdst++] = (byte)b;
|
||||
}
|
||||
this.output.write(bpixels, 0, (size + 7) / 8);
|
||||
break;
|
||||
case 53:
|
||||
for (j = 0; j < size; j++)
|
||||
bpixels[j] = (byte)pixels[j];
|
||||
this.output.write(bpixels, 0, size);
|
||||
break;
|
||||
case 54:
|
||||
if (reds == null) {
|
||||
for (int k = 0; k < size; k++)
|
||||
bpixels[k] = (byte)(pixels[k] & 0xFF);
|
||||
} else {
|
||||
for (int k = 0, m = 0; k < size; k++) {
|
||||
bpixels[m++] = reds[pixels[k]];
|
||||
bpixels[m++] = greens[pixels[k]];
|
||||
bpixels[m++] = blues[pixels[k]];
|
||||
}
|
||||
}
|
||||
this.output.write(bpixels, 0, bpixels.length);
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.output.flush();
|
||||
}
|
||||
|
||||
private void writeInteger(OutputStream output, int i) throws IOException {
|
||||
output.write(Integer.toString(i).getBytes());
|
||||
}
|
||||
|
||||
private void writeByte(OutputStream output, byte b) throws IOException {
|
||||
output.write(Byte.toString(b).getBytes());
|
||||
}
|
||||
|
||||
private boolean isRaw(int v) {
|
||||
return (v >= 52);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,267 @@
|
|||
package com.sun.media.jai.codecimpl;
|
||||
|
||||
import com.sun.media.jai.codecimpl.util.RasterFactory;
|
||||
import java.awt.Image;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.image.ColorModel;
|
||||
import java.awt.image.Raster;
|
||||
import java.awt.image.RenderedImage;
|
||||
import java.awt.image.SampleModel;
|
||||
import java.awt.image.WritableRaster;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Iterator;
|
||||
import java.util.Vector;
|
||||
|
||||
public abstract class SimpleRenderedImage implements RenderedImage {
|
||||
protected int minX;
|
||||
|
||||
protected int minY;
|
||||
|
||||
protected int width;
|
||||
|
||||
protected int height;
|
||||
|
||||
protected int tileWidth;
|
||||
|
||||
protected int tileHeight;
|
||||
|
||||
protected int tileGridXOffset = 0;
|
||||
|
||||
protected int tileGridYOffset = 0;
|
||||
|
||||
protected SampleModel sampleModel = null;
|
||||
|
||||
protected ColorModel colorModel = null;
|
||||
|
||||
protected Vector sources = new Vector();
|
||||
|
||||
protected Hashtable properties = new Hashtable();
|
||||
|
||||
public int getMinX() {
|
||||
return this.minX;
|
||||
}
|
||||
|
||||
public final int getMaxX() {
|
||||
return getMinX() + getWidth();
|
||||
}
|
||||
|
||||
public int getMinY() {
|
||||
return this.minY;
|
||||
}
|
||||
|
||||
public final int getMaxY() {
|
||||
return getMinY() + getHeight();
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
return this.width;
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
return this.height;
|
||||
}
|
||||
|
||||
public Rectangle getBounds() {
|
||||
return new Rectangle(getMinX(), getMinY(), getWidth(), getHeight());
|
||||
}
|
||||
|
||||
public int getTileWidth() {
|
||||
return this.tileWidth;
|
||||
}
|
||||
|
||||
public int getTileHeight() {
|
||||
return this.tileHeight;
|
||||
}
|
||||
|
||||
public int getTileGridXOffset() {
|
||||
return this.tileGridXOffset;
|
||||
}
|
||||
|
||||
public int getTileGridYOffset() {
|
||||
return this.tileGridYOffset;
|
||||
}
|
||||
|
||||
public int getMinTileX() {
|
||||
return XToTileX(getMinX());
|
||||
}
|
||||
|
||||
public int getMaxTileX() {
|
||||
return XToTileX(getMaxX() - 1);
|
||||
}
|
||||
|
||||
public int getNumXTiles() {
|
||||
return getMaxTileX() - getMinTileX() + 1;
|
||||
}
|
||||
|
||||
public int getMinTileY() {
|
||||
return YToTileY(getMinY());
|
||||
}
|
||||
|
||||
public int getMaxTileY() {
|
||||
return YToTileY(getMaxY() - 1);
|
||||
}
|
||||
|
||||
public int getNumYTiles() {
|
||||
return getMaxTileY() - getMinTileY() + 1;
|
||||
}
|
||||
|
||||
public SampleModel getSampleModel() {
|
||||
return this.sampleModel;
|
||||
}
|
||||
|
||||
public ColorModel getColorModel() {
|
||||
return this.colorModel;
|
||||
}
|
||||
|
||||
public Object getProperty(String name) {
|
||||
name = name.toLowerCase();
|
||||
Object value = this.properties.get(name);
|
||||
return (value != null) ? value : Image.UndefinedProperty;
|
||||
}
|
||||
|
||||
public String[] getPropertyNames() {
|
||||
String[] names = null;
|
||||
if (this.properties.size() > 0) {
|
||||
names = new String[this.properties.size()];
|
||||
int index = 0;
|
||||
Enumeration e = this.properties.keys();
|
||||
while (e.hasMoreElements()) {
|
||||
String name = (String)e.nextElement();
|
||||
names[index++] = name;
|
||||
}
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
public String[] getPropertyNames(String prefix) {
|
||||
String[] propertyNames = getPropertyNames();
|
||||
if (propertyNames == null)
|
||||
return null;
|
||||
prefix = prefix.toLowerCase();
|
||||
Vector names = new Vector();
|
||||
for (int i = 0; i < propertyNames.length; i++) {
|
||||
if (propertyNames[i].startsWith(prefix))
|
||||
names.addElement(propertyNames[i]);
|
||||
}
|
||||
if (names.size() == 0)
|
||||
return null;
|
||||
String[] arrayOfString1 = new String[names.size()];
|
||||
int count = 0;
|
||||
for (Iterator it = names.iterator(); it.hasNext();)
|
||||
arrayOfString1[count++] = (String)it.next();
|
||||
return arrayOfString1;
|
||||
}
|
||||
|
||||
public static int XToTileX(int x, int tileGridXOffset, int tileWidth) {
|
||||
x -= tileGridXOffset;
|
||||
if (x < 0)
|
||||
x += 1 - tileWidth;
|
||||
return x / tileWidth;
|
||||
}
|
||||
|
||||
public static int YToTileY(int y, int tileGridYOffset, int tileHeight) {
|
||||
y -= tileGridYOffset;
|
||||
if (y < 0)
|
||||
y += 1 - tileHeight;
|
||||
return y / tileHeight;
|
||||
}
|
||||
|
||||
public int XToTileX(int x) {
|
||||
return XToTileX(x, getTileGridXOffset(), getTileWidth());
|
||||
}
|
||||
|
||||
public int YToTileY(int y) {
|
||||
return YToTileY(y, getTileGridYOffset(), getTileHeight());
|
||||
}
|
||||
|
||||
public static int tileXToX(int tx, int tileGridXOffset, int tileWidth) {
|
||||
return tx * tileWidth + tileGridXOffset;
|
||||
}
|
||||
|
||||
public static int tileYToY(int ty, int tileGridYOffset, int tileHeight) {
|
||||
return ty * tileHeight + tileGridYOffset;
|
||||
}
|
||||
|
||||
public int tileXToX(int tx) {
|
||||
return tx * this.tileWidth + this.tileGridXOffset;
|
||||
}
|
||||
|
||||
public int tileYToY(int ty) {
|
||||
return ty * this.tileHeight + this.tileGridYOffset;
|
||||
}
|
||||
|
||||
public Vector getSources() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Raster getData() {
|
||||
Rectangle rect = new Rectangle(getMinX(), getMinY(), getWidth(), getHeight());
|
||||
return getData(rect);
|
||||
}
|
||||
|
||||
public Raster getData(Rectangle bounds) {
|
||||
Rectangle imageBounds = getBounds();
|
||||
if (bounds == null) {
|
||||
bounds = imageBounds;
|
||||
} else if (!bounds.intersects(imageBounds)) {
|
||||
throw new IllegalArgumentException(JaiI18N.getString("SimpleRenderedImage0"));
|
||||
}
|
||||
int startX = XToTileX(bounds.x);
|
||||
int startY = YToTileY(bounds.y);
|
||||
int endX = XToTileX(bounds.x + bounds.width - 1);
|
||||
int endY = YToTileY(bounds.y + bounds.height - 1);
|
||||
if (startX == endX && startY == endY) {
|
||||
Raster tile = getTile(startX, startY);
|
||||
return tile.createChild(bounds.x, bounds.y, bounds.width, bounds.height, bounds.x, bounds.y, null);
|
||||
}
|
||||
if (!imageBounds.contains(bounds)) {
|
||||
Rectangle xsect = bounds.intersection(imageBounds);
|
||||
startX = XToTileX(xsect.x);
|
||||
startY = YToTileY(xsect.y);
|
||||
endX = XToTileX(xsect.x + xsect.width - 1);
|
||||
endY = YToTileY(xsect.y + xsect.height - 1);
|
||||
}
|
||||
SampleModel sm = this.sampleModel.createCompatibleSampleModel(bounds.width, bounds.height);
|
||||
WritableRaster dest = RasterFactory.createWritableRaster(sm, bounds.getLocation());
|
||||
for (int j = startY; j <= endY; j++) {
|
||||
for (int i = startX; i <= endX; i++) {
|
||||
Raster tile = getTile(i, j);
|
||||
Rectangle tileRect = tile.getBounds();
|
||||
Rectangle intersectRect = bounds.intersection(tile.getBounds());
|
||||
Raster liveRaster = tile.createChild(intersectRect.x, intersectRect.y, intersectRect.width, intersectRect.height, intersectRect.x, intersectRect.y, null);
|
||||
dest.setRect(liveRaster);
|
||||
}
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
|
||||
public WritableRaster copyData(WritableRaster dest) {
|
||||
Rectangle bounds;
|
||||
Rectangle imageBounds = getBounds();
|
||||
if (dest == null) {
|
||||
bounds = imageBounds;
|
||||
Point p = new Point(this.minX, this.minY);
|
||||
SampleModel sm = this.sampleModel.createCompatibleSampleModel(this.width, this.height);
|
||||
dest = RasterFactory.createWritableRaster(sm, p);
|
||||
} else {
|
||||
bounds = dest.getBounds();
|
||||
}
|
||||
Rectangle xsect = imageBounds.contains(bounds) ? bounds : bounds.intersection(imageBounds);
|
||||
int startX = XToTileX(xsect.x);
|
||||
int startY = YToTileY(xsect.y);
|
||||
int endX = XToTileX(xsect.x + xsect.width - 1);
|
||||
int endY = YToTileY(xsect.y + xsect.height - 1);
|
||||
for (int j = startY; j <= endY; j++) {
|
||||
for (int i = startX; i <= endX; i++) {
|
||||
Raster tile = getTile(i, j);
|
||||
Rectangle tileRect = tile.getBounds();
|
||||
Rectangle intersectRect = bounds.intersection(tile.getBounds());
|
||||
Raster liveRaster = tile.createChild(intersectRect.x, intersectRect.y, intersectRect.width, intersectRect.height, intersectRect.x, intersectRect.y, null);
|
||||
dest.setRect(liveRaster);
|
||||
}
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
package com.sun.media.jai.codecimpl;
|
||||
|
||||
import java.awt.image.ColorModel;
|
||||
import java.awt.image.Raster;
|
||||
|
||||
public class SingleTileRenderedImage extends SimpleRenderedImage {
|
||||
Raster ras;
|
||||
|
||||
public SingleTileRenderedImage(Raster ras, ColorModel colorModel) {
|
||||
this.ras = ras;
|
||||
this.tileGridXOffset = this.minX = ras.getMinX();
|
||||
this.tileGridYOffset = this.minY = ras.getMinY();
|
||||
this.tileWidth = this.width = ras.getWidth();
|
||||
this.tileHeight = this.height = ras.getHeight();
|
||||
this.sampleModel = ras.getSampleModel();
|
||||
this.colorModel = colorModel;
|
||||
}
|
||||
|
||||
public Raster getTile(int tileX, int tileY) {
|
||||
if (tileX != 0 || tileY != 0)
|
||||
throw new IllegalArgumentException(JaiI18N.getString("SingleTileRenderedImage0"));
|
||||
return this.ras;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
package com.sun.media.jai.codecimpl;
|
||||
|
||||
import com.sun.media.jai.codec.ImageCodec;
|
||||
import com.sun.media.jai.codec.ImageDecodeParam;
|
||||
import com.sun.media.jai.codec.ImageDecoder;
|
||||
import com.sun.media.jai.codec.ImageEncodeParam;
|
||||
import com.sun.media.jai.codec.ImageEncoder;
|
||||
import com.sun.media.jai.codec.SeekableStream;
|
||||
import com.sun.media.jai.codec.TIFFDecodeParam;
|
||||
import com.sun.media.jai.codec.TIFFEncodeParam;
|
||||
import java.awt.image.RenderedImage;
|
||||
import java.io.OutputStream;
|
||||
|
||||
public final class TIFFCodec extends ImageCodec {
|
||||
public String getFormatName() {
|
||||
return "tiff";
|
||||
}
|
||||
|
||||
public Class getEncodeParamClass() {
|
||||
return TIFFEncodeParam.class;
|
||||
}
|
||||
|
||||
public Class getDecodeParamClass() {
|
||||
return TIFFDecodeParam.class;
|
||||
}
|
||||
|
||||
public boolean canEncodeImage(RenderedImage im, ImageEncodeParam param) {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected ImageEncoder createImageEncoder(OutputStream dst, ImageEncodeParam param) {
|
||||
return new TIFFImageEncoder(dst, param);
|
||||
}
|
||||
|
||||
protected ImageDecoder createImageDecoder(SeekableStream src, ImageDecodeParam param) {
|
||||
return new TIFFImageDecoder(src, param);
|
||||
}
|
||||
|
||||
public int getNumHeaderBytes() {
|
||||
return 4;
|
||||
}
|
||||
|
||||
public boolean isFormatRecognized(byte[] header) {
|
||||
if (header[0] == 73 && header[1] == 73 && header[2] == 42 && header[3] == 0)
|
||||
return true;
|
||||
if (header[0] == 77 && header[1] == 77 && header[2] == 0 && header[3] == 42)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,899 @@
|
|||
package com.sun.media.jai.codecimpl;
|
||||
|
||||
class TIFFFaxDecoder {
|
||||
private int bitPointer;
|
||||
|
||||
private int bytePointer;
|
||||
|
||||
private byte[] data;
|
||||
|
||||
private int w;
|
||||
|
||||
private int h;
|
||||
|
||||
private int fillOrder;
|
||||
|
||||
private int changingElemSize = 0;
|
||||
|
||||
private int[] prevChangingElems;
|
||||
|
||||
private int[] currChangingElems;
|
||||
|
||||
private int lastChangingElement = 0;
|
||||
|
||||
private int compression = 2;
|
||||
|
||||
private int uncompressedMode = 0;
|
||||
|
||||
private int fillBits = 0;
|
||||
|
||||
private int oneD;
|
||||
|
||||
static int[] table1 = new int[] { 0, 1, 3, 7, 15, 31, 63, 127, 255 };
|
||||
|
||||
static int[] table2 = new int[] { 0, 128, 192, 224, 240, 248, 252, 254, 255 };
|
||||
|
||||
static byte[] flipTable = new byte[] {
|
||||
0, Byte.MIN_VALUE, 64, -64, 32, -96, 96, -32, 16, -112,
|
||||
80, -48, 48, -80, 112, -16, 8, -120, 72, -56,
|
||||
40, -88, 104, -24, 24, -104, 88, -40, 56, -72,
|
||||
120, -8, 4, -124, 68, -60, 36, -92, 100, -28,
|
||||
20, -108, 84, -44, 52, -76, 116, -12, 12, -116,
|
||||
76, -52, 44, -84, 108, -20, 28, -100, 92, -36,
|
||||
60, -68, 124, -4, 2, -126, 66, -62, 34, -94,
|
||||
98, -30, 18, -110, 82, -46, 50, -78, 114, -14,
|
||||
10, -118, 74, -54, 42, -86, 106, -22, 26, -102,
|
||||
90, -38, 58, -70, 122, -6, 6, -122, 70, -58,
|
||||
38, -90, 102, -26, 22, -106, 86, -42, 54, -74,
|
||||
118, -10, 14, -114, 78, -50, 46, -82, 110, -18,
|
||||
30, -98, 94, -34, 62, -66, 126, -2, 1, -127,
|
||||
65, -63, 33, -95, 97, -31, 17, -111, 81, -47,
|
||||
49, -79, 113, -15, 9, -119, 73, -55, 41, -87,
|
||||
105, -23, 25, -103, 89, -39, 57, -71, 121, -7,
|
||||
5, -123, 69, -59, 37, -91, 101, -27, 21, -107,
|
||||
85, -43, 53, -75, 117, -11, 13, -115, 77, -51,
|
||||
45, -83, 109, -19, 29, -99, 93, -35, 61, -67,
|
||||
125, -3, 3, -125, 67, -61, 35, -93, 99, -29,
|
||||
19, -109, 83, -45, 51, -77, 115, -13, 11, -117,
|
||||
75, -53, 43, -85, 107, -21, 27, -101, 91, -37,
|
||||
59, -69, 123, -5, 7, -121, 71, -57, 39, -89,
|
||||
103, -25, 23, -105, 87, -41, 55, -73, 119, -9,
|
||||
15, -113, 79, -49, 47, -81, 111, -17, 31, -97,
|
||||
95, -33, 63, -65, Byte.MAX_VALUE, -1 };
|
||||
|
||||
static short[] white = new short[] {
|
||||
6430, 6400, 6400, 6400, 3225, 3225, 3225, 3225, 944, 944,
|
||||
944, 944, 976, 976, 976, 976, 1456, 1456, 1456, 1456,
|
||||
1488, 1488, 1488, 1488, 718, 718, 718, 718, 718, 718,
|
||||
718, 718, 750, 750, 750, 750, 750, 750, 750, 750,
|
||||
1520, 1520, 1520, 1520, 1552, 1552, 1552, 1552, 428, 428,
|
||||
428, 428, 428, 428, 428, 428, 428, 428, 428, 428,
|
||||
428, 428, 428, 428, 654, 654, 654, 654, 654, 654,
|
||||
654, 654, 1072, 1072, 1072, 1072, 1104, 1104, 1104, 1104,
|
||||
1136, 1136, 1136, 1136, 1168, 1168, 1168, 1168, 1200, 1200,
|
||||
1200, 1200, 1232, 1232, 1232, 1232, 622, 622, 622, 622,
|
||||
622, 622, 622, 622, 1008, 1008, 1008, 1008, 1040, 1040,
|
||||
1040, 1040, 44, 44, 44, 44, 44, 44, 44, 44,
|
||||
44, 44, 44, 44, 44, 44, 44, 44, 396, 396,
|
||||
396, 396, 396, 396, 396, 396, 396, 396, 396, 396,
|
||||
396, 396, 396, 396, 1712, 1712, 1712, 1712, 1744, 1744,
|
||||
1744, 1744, 846, 846, 846, 846, 846, 846, 846, 846,
|
||||
1264, 1264, 1264, 1264, 1296, 1296, 1296, 1296, 1328, 1328,
|
||||
1328, 1328, 1360, 1360, 1360, 1360, 1392, 1392, 1392, 1392,
|
||||
1424, 1424, 1424, 1424, 686, 686, 686, 686, 686, 686,
|
||||
686, 686, 910, 910, 910, 910, 910, 910, 910, 910,
|
||||
1968, 1968, 1968, 1968, 2000, 2000, 2000, 2000, 2032, 2032,
|
||||
2032, 2032, 16, 16, 16, 16, 10257, 10257, 10257, 10257,
|
||||
12305, 12305, 12305, 12305, 330, 330, 330, 330, 330, 330,
|
||||
330, 330, 330, 330, 330, 330, 330, 330, 330, 330,
|
||||
330, 330, 330, 330, 330, 330, 330, 330, 330, 330,
|
||||
330, 330, 330, 330, 330, 330, 362, 362, 362, 362,
|
||||
362, 362, 362, 362, 362, 362, 362, 362, 362, 362,
|
||||
362, 362, 362, 362, 362, 362, 362, 362, 362, 362,
|
||||
362, 362, 362, 362, 362, 362, 362, 362, 878, 878,
|
||||
878, 878, 878, 878, 878, 878, 1904, 1904, 1904, 1904,
|
||||
1936, 1936, 1936, 1936, -18413, -18413, -16365, -16365, -14317, -14317,
|
||||
-10221, -10221, 590, 590, 590, 590, 590, 590, 590, 590,
|
||||
782, 782, 782, 782, 782, 782, 782, 782, 1584, 1584,
|
||||
1584, 1584, 1616, 1616, 1616, 1616, 1648, 1648, 1648, 1648,
|
||||
1680, 1680, 1680, 1680, 814, 814, 814, 814, 814, 814,
|
||||
814, 814, 1776, 1776, 1776, 1776, 1808, 1808, 1808, 1808,
|
||||
1840, 1840, 1840, 1840, 1872, 1872, 1872, 1872, 6157, 6157,
|
||||
6157, 6157, 6157, 6157, 6157, 6157, 6157, 6157, 6157, 6157,
|
||||
6157, 6157, 6157, 6157, -12275, -12275, -12275, -12275, -12275, -12275,
|
||||
-12275, -12275, -12275, -12275, -12275, -12275, -12275, -12275, -12275, -12275,
|
||||
14353, 14353, 14353, 14353, 16401, 16401, 16401, 16401, 22547, 22547,
|
||||
24595, 24595, 20497, 20497, 20497, 20497, 18449, 18449, 18449, 18449,
|
||||
26643, 26643, 28691, 28691, 30739, 30739, -32749, -32749, -30701, -30701,
|
||||
-28653, -28653, -26605, -26605, -24557, -24557, -22509, -22509, -20461, -20461,
|
||||
8207, 8207, 8207, 8207, 8207, 8207, 8207, 8207, 72, 72,
|
||||
72, 72, 72, 72, 72, 72, 72, 72, 72, 72,
|
||||
72, 72, 72, 72, 72, 72, 72, 72, 72, 72,
|
||||
72, 72, 72, 72, 72, 72, 72, 72, 72, 72,
|
||||
72, 72, 72, 72, 72, 72, 72, 72, 72, 72,
|
||||
72, 72, 72, 72, 72, 72, 72, 72, 72, 72,
|
||||
72, 72, 72, 72, 72, 72, 72, 72, 72, 72,
|
||||
72, 72, 104, 104, 104, 104, 104, 104, 104, 104,
|
||||
104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
|
||||
104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
|
||||
104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
|
||||
104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
|
||||
104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
|
||||
104, 104, 104, 104, 104, 104, 4107, 4107, 4107, 4107,
|
||||
4107, 4107, 4107, 4107, 4107, 4107, 4107, 4107, 4107, 4107,
|
||||
4107, 4107, 4107, 4107, 4107, 4107, 4107, 4107, 4107, 4107,
|
||||
4107, 4107, 4107, 4107, 4107, 4107, 4107, 4107, 266, 266,
|
||||
266, 266, 266, 266, 266, 266, 266, 266, 266, 266,
|
||||
266, 266, 266, 266, 266, 266, 266, 266, 266, 266,
|
||||
266, 266, 266, 266, 266, 266, 266, 266, 266, 266,
|
||||
298, 298, 298, 298, 298, 298, 298, 298, 298, 298,
|
||||
298, 298, 298, 298, 298, 298, 298, 298, 298, 298,
|
||||
298, 298, 298, 298, 298, 298, 298, 298, 298, 298,
|
||||
298, 298, 524, 524, 524, 524, 524, 524, 524, 524,
|
||||
524, 524, 524, 524, 524, 524, 524, 524, 556, 556,
|
||||
556, 556, 556, 556, 556, 556, 556, 556, 556, 556,
|
||||
556, 556, 556, 556, 136, 136, 136, 136, 136, 136,
|
||||
136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
|
||||
136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
|
||||
136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
|
||||
136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
|
||||
136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
|
||||
136, 136, 136, 136, 136, 136, 136, 136, 168, 168,
|
||||
168, 168, 168, 168, 168, 168, 168, 168, 168, 168,
|
||||
168, 168, 168, 168, 168, 168, 168, 168, 168, 168,
|
||||
168, 168, 168, 168, 168, 168, 168, 168, 168, 168,
|
||||
168, 168, 168, 168, 168, 168, 168, 168, 168, 168,
|
||||
168, 168, 168, 168, 168, 168, 168, 168, 168, 168,
|
||||
168, 168, 168, 168, 168, 168, 168, 168, 168, 168,
|
||||
168, 168, 460, 460, 460, 460, 460, 460, 460, 460,
|
||||
460, 460, 460, 460, 460, 460, 460, 460, 492, 492,
|
||||
492, 492, 492, 492, 492, 492, 492, 492, 492, 492,
|
||||
492, 492, 492, 492, 2059, 2059, 2059, 2059, 2059, 2059,
|
||||
2059, 2059, 2059, 2059, 2059, 2059, 2059, 2059, 2059, 2059,
|
||||
2059, 2059, 2059, 2059, 2059, 2059, 2059, 2059, 2059, 2059,
|
||||
2059, 2059, 2059, 2059, 2059, 2059, 200, 200, 200, 200,
|
||||
200, 200, 200, 200, 200, 200, 200, 200, 200, 200,
|
||||
200, 200, 200, 200, 200, 200, 200, 200, 200, 200,
|
||||
200, 200, 200, 200, 200, 200, 200, 200, 200, 200,
|
||||
200, 200, 200, 200, 200, 200, 200, 200, 200, 200,
|
||||
200, 200, 200, 200, 200, 200, 200, 200, 200, 200,
|
||||
200, 200, 200, 200, 200, 200, 200, 200, 200, 200,
|
||||
232, 232, 232, 232, 232, 232, 232, 232, 232, 232,
|
||||
232, 232, 232, 232, 232, 232, 232, 232, 232, 232,
|
||||
232, 232, 232, 232, 232, 232, 232, 232, 232, 232,
|
||||
232, 232, 232, 232, 232, 232, 232, 232, 232, 232,
|
||||
232, 232, 232, 232, 232, 232, 232, 232, 232, 232,
|
||||
232, 232, 232, 232, 232, 232, 232, 232, 232, 232,
|
||||
232, 232, 232, 232 };
|
||||
|
||||
static short[] additionalMakeup = new short[] {
|
||||
28679, 28679, 31752, -32759, -31735, -30711, -29687, -28663, 29703, 29703,
|
||||
30727, 30727, -27639, -26615, -25591, -24567 };
|
||||
|
||||
static short[] initBlack = new short[] {
|
||||
3226, 6412, 200, 168, 38, 38, 134, 134, 100, 100,
|
||||
100, 100, 68, 68, 68, 68 };
|
||||
|
||||
static short[] twoBitBlack = new short[] { 292, 260, 226, 226 };
|
||||
|
||||
static short[] black = new short[] {
|
||||
62, 62, 30, 30, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225,
|
||||
3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225,
|
||||
3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225,
|
||||
3225, 3225, 3225, 3225, 588, 588, 588, 588, 588, 588,
|
||||
588, 588, 1680, 1680, 20499, 22547, 24595, 26643, 1776, 1776,
|
||||
1808, 1808, -24557, -22509, -20461, -18413, 1904, 1904, 1936, 1936,
|
||||
-16365, -14317, 782, 782, 782, 782, 814, 814, 814, 814,
|
||||
-12269, -10221, 10257, 10257, 12305, 12305, 14353, 14353, 16403, 18451,
|
||||
1712, 1712, 1744, 1744, 28691, 30739, -32749, -30701, -28653, -26605,
|
||||
2061, 2061, 2061, 2061, 2061, 2061, 2061, 2061, 424, 424,
|
||||
424, 424, 424, 424, 424, 424, 424, 424, 424, 424,
|
||||
424, 424, 424, 424, 424, 424, 424, 424, 424, 424,
|
||||
424, 424, 424, 424, 424, 424, 424, 424, 424, 424,
|
||||
750, 750, 750, 750, 1616, 1616, 1648, 1648, 1424, 1424,
|
||||
1456, 1456, 1488, 1488, 1520, 1520, 1840, 1840, 1872, 1872,
|
||||
1968, 1968, 8209, 8209, 524, 524, 524, 524, 524, 524,
|
||||
524, 524, 556, 556, 556, 556, 556, 556, 556, 556,
|
||||
1552, 1552, 1584, 1584, 2000, 2000, 2032, 2032, 976, 976,
|
||||
1008, 1008, 1040, 1040, 1072, 1072, 1296, 1296, 1328, 1328,
|
||||
718, 718, 718, 718, 456, 456, 456, 456, 456, 456,
|
||||
456, 456, 456, 456, 456, 456, 456, 456, 456, 456,
|
||||
456, 456, 456, 456, 456, 456, 456, 456, 456, 456,
|
||||
456, 456, 456, 456, 456, 456, 326, 326, 326, 326,
|
||||
326, 326, 326, 326, 326, 326, 326, 326, 326, 326,
|
||||
326, 326, 326, 326, 326, 326, 326, 326, 326, 326,
|
||||
326, 326, 326, 326, 326, 326, 326, 326, 326, 326,
|
||||
326, 326, 326, 326, 326, 326, 326, 326, 326, 326,
|
||||
326, 326, 326, 326, 326, 326, 326, 326, 326, 326,
|
||||
326, 326, 326, 326, 326, 326, 326, 326, 326, 326,
|
||||
358, 358, 358, 358, 358, 358, 358, 358, 358, 358,
|
||||
358, 358, 358, 358, 358, 358, 358, 358, 358, 358,
|
||||
358, 358, 358, 358, 358, 358, 358, 358, 358, 358,
|
||||
358, 358, 358, 358, 358, 358, 358, 358, 358, 358,
|
||||
358, 358, 358, 358, 358, 358, 358, 358, 358, 358,
|
||||
358, 358, 358, 358, 358, 358, 358, 358, 358, 358,
|
||||
358, 358, 358, 358, 490, 490, 490, 490, 490, 490,
|
||||
490, 490, 490, 490, 490, 490, 490, 490, 490, 490,
|
||||
4113, 4113, 6161, 6161, 848, 848, 880, 880, 912, 912,
|
||||
944, 944, 622, 622, 622, 622, 654, 654, 654, 654,
|
||||
1104, 1104, 1136, 1136, 1168, 1168, 1200, 1200, 1232, 1232,
|
||||
1264, 1264, 686, 686, 686, 686, 1360, 1360, 1392, 1392,
|
||||
12, 12, 12, 12, 12, 12, 12, 12, 390, 390,
|
||||
390, 390, 390, 390, 390, 390, 390, 390, 390, 390,
|
||||
390, 390, 390, 390, 390, 390, 390, 390, 390, 390,
|
||||
390, 390, 390, 390, 390, 390, 390, 390, 390, 390,
|
||||
390, 390, 390, 390, 390, 390, 390, 390, 390, 390,
|
||||
390, 390, 390, 390, 390, 390, 390, 390, 390, 390,
|
||||
390, 390, 390, 390, 390, 390, 390, 390, 390, 390,
|
||||
390, 390 };
|
||||
|
||||
static byte[] twoDCodes = new byte[] {
|
||||
80, 88, 23, 71, 30, 30, 62, 62, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 11, 11, 11, 11,
|
||||
11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
|
||||
11, 11, 35, 35, 35, 35, 35, 35, 35, 35,
|
||||
35, 35, 35, 35, 35, 35, 35, 35, 51, 51,
|
||||
51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
|
||||
51, 51, 51, 51, 41, 41, 41, 41, 41, 41,
|
||||
41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
|
||||
41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
|
||||
41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
|
||||
41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
|
||||
41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
|
||||
41, 41, 41, 41, 41, 41, 41, 41 };
|
||||
|
||||
public TIFFFaxDecoder(int fillOrder, int w, int h) {
|
||||
this.fillOrder = fillOrder;
|
||||
this.w = w;
|
||||
this.h = h;
|
||||
this.bitPointer = 0;
|
||||
this.bytePointer = 0;
|
||||
this.prevChangingElems = new int[w + 1];
|
||||
this.currChangingElems = new int[w + 1];
|
||||
}
|
||||
|
||||
public void decode1D(byte[] buffer, byte[] compData, int startX, int height) {
|
||||
this.data = compData;
|
||||
int lineOffset = 0;
|
||||
int scanlineStride = (this.w + 7) / 8;
|
||||
this.bitPointer = 0;
|
||||
this.bytePointer = 0;
|
||||
for (int i = 0; i < height; i++) {
|
||||
decodeNextScanline(buffer, lineOffset, startX);
|
||||
lineOffset += scanlineStride;
|
||||
}
|
||||
}
|
||||
|
||||
public void decodeNextScanline(byte[] buffer, int lineOffset, int bitOffset) {
|
||||
int bits = 0, code = 0, isT = 0;
|
||||
boolean isWhite = true;
|
||||
int dstEnd = 0;
|
||||
this.changingElemSize = 0;
|
||||
while (bitOffset < this.w) {
|
||||
while (isWhite) {
|
||||
int current = nextNBits(10);
|
||||
int entry = white[current];
|
||||
isT = entry & 0x1;
|
||||
bits = entry >>> 1 & 0xF;
|
||||
if (bits == 12) {
|
||||
int twoBits = nextLesserThan8Bits(2);
|
||||
current = current << 2 & 0xC | twoBits;
|
||||
entry = additionalMakeup[current];
|
||||
bits = entry >>> 1 & 0x7;
|
||||
code = entry >>> 4 & 0xFFF;
|
||||
bitOffset += code;
|
||||
updatePointer(4 - bits);
|
||||
continue;
|
||||
}
|
||||
if (bits == 0)
|
||||
throw new RuntimeException(JaiI18N.getString("TIFFFaxDecoder0"));
|
||||
if (bits == 15) {
|
||||
updatePointer(12);
|
||||
return;
|
||||
}
|
||||
code = entry >>> 5 & 0x7FF;
|
||||
bitOffset += code;
|
||||
updatePointer(10 - bits);
|
||||
if (isT == 0) {
|
||||
isWhite = false;
|
||||
this.currChangingElems[this.changingElemSize++] = bitOffset;
|
||||
}
|
||||
}
|
||||
if (bitOffset == this.w) {
|
||||
if (this.compression == 2) {
|
||||
advancePointer();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
while (!isWhite) {
|
||||
int current = nextLesserThan8Bits(4);
|
||||
int entry = initBlack[current];
|
||||
isT = entry & 0x1;
|
||||
bits = entry >>> 1 & 0xF;
|
||||
code = entry >>> 5 & 0x7FF;
|
||||
if (code == 100) {
|
||||
current = nextNBits(9);
|
||||
entry = black[current];
|
||||
isT = entry & 0x1;
|
||||
bits = entry >>> 1 & 0xF;
|
||||
code = entry >>> 5 & 0x7FF;
|
||||
if (bits == 12) {
|
||||
updatePointer(5);
|
||||
current = nextLesserThan8Bits(4);
|
||||
entry = additionalMakeup[current];
|
||||
bits = entry >>> 1 & 0x7;
|
||||
code = entry >>> 4 & 0xFFF;
|
||||
setToBlack(buffer, lineOffset, bitOffset, code);
|
||||
bitOffset += code;
|
||||
updatePointer(4 - bits);
|
||||
continue;
|
||||
}
|
||||
if (bits == 15) {
|
||||
updatePointer(12);
|
||||
return;
|
||||
}
|
||||
setToBlack(buffer, lineOffset, bitOffset, code);
|
||||
bitOffset += code;
|
||||
updatePointer(9 - bits);
|
||||
if (isT == 0) {
|
||||
isWhite = true;
|
||||
this.currChangingElems[this.changingElemSize++] = bitOffset;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (code == 200) {
|
||||
current = nextLesserThan8Bits(2);
|
||||
entry = twoBitBlack[current];
|
||||
code = entry >>> 5 & 0x7FF;
|
||||
bits = entry >>> 1 & 0xF;
|
||||
setToBlack(buffer, lineOffset, bitOffset, code);
|
||||
bitOffset += code;
|
||||
updatePointer(2 - bits);
|
||||
isWhite = true;
|
||||
this.currChangingElems[this.changingElemSize++] = bitOffset;
|
||||
continue;
|
||||
}
|
||||
setToBlack(buffer, lineOffset, bitOffset, code);
|
||||
bitOffset += code;
|
||||
updatePointer(4 - bits);
|
||||
isWhite = true;
|
||||
this.currChangingElems[this.changingElemSize++] = bitOffset;
|
||||
}
|
||||
if (bitOffset == this.w) {
|
||||
if (this.compression == 2) {
|
||||
advancePointer();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.currChangingElems[this.changingElemSize++] = bitOffset;
|
||||
}
|
||||
|
||||
public void decode2D(byte[] buffer, byte[] compData, int startX, int height, long tiffT4Options) {
|
||||
this.data = compData;
|
||||
this.compression = 3;
|
||||
this.bitPointer = 0;
|
||||
this.bytePointer = 0;
|
||||
int scanlineStride = (this.w + 7) / 8;
|
||||
int[] b = new int[2];
|
||||
int currIndex = 0;
|
||||
this.oneD = (int)(tiffT4Options & 0x1L);
|
||||
this.uncompressedMode = (int)((tiffT4Options & 0x2L) >> 1L);
|
||||
this.fillBits = (int)((tiffT4Options & 0x4L) >> 2L);
|
||||
if (readEOL(true) != 1)
|
||||
throw new RuntimeException(JaiI18N.getString("TIFFFaxDecoder3"));
|
||||
int lineOffset = 0;
|
||||
decodeNextScanline(buffer, lineOffset, startX);
|
||||
lineOffset += scanlineStride;
|
||||
for (int lines = 1; lines < height; lines++) {
|
||||
if (readEOL(false) == 0) {
|
||||
int[] temp = this.prevChangingElems;
|
||||
this.prevChangingElems = this.currChangingElems;
|
||||
this.currChangingElems = temp;
|
||||
currIndex = 0;
|
||||
int a0 = -1;
|
||||
boolean isWhite = true;
|
||||
int bitOffset = startX;
|
||||
this.lastChangingElement = 0;
|
||||
while (bitOffset < this.w) {
|
||||
getNextChangingElement(a0, isWhite, b);
|
||||
int b1 = b[0];
|
||||
int b2 = b[1];
|
||||
int entry = nextLesserThan8Bits(7);
|
||||
entry = twoDCodes[entry] & 0xFF;
|
||||
int code = (entry & 0x78) >>> 3;
|
||||
int bits = entry & 0x7;
|
||||
if (code == 0) {
|
||||
if (!isWhite)
|
||||
setToBlack(buffer, lineOffset, bitOffset, b2 - bitOffset);
|
||||
bitOffset = a0 = b2;
|
||||
updatePointer(7 - bits);
|
||||
continue;
|
||||
}
|
||||
if (code == 1) {
|
||||
updatePointer(7 - bits);
|
||||
if (isWhite) {
|
||||
int number = decodeWhiteCodeWord();
|
||||
bitOffset += number;
|
||||
this.currChangingElems[currIndex++] = bitOffset;
|
||||
number = decodeBlackCodeWord();
|
||||
setToBlack(buffer, lineOffset, bitOffset, number);
|
||||
bitOffset += number;
|
||||
this.currChangingElems[currIndex++] = bitOffset;
|
||||
} else {
|
||||
int number = decodeBlackCodeWord();
|
||||
setToBlack(buffer, lineOffset, bitOffset, number);
|
||||
bitOffset += number;
|
||||
this.currChangingElems[currIndex++] = bitOffset;
|
||||
number = decodeWhiteCodeWord();
|
||||
bitOffset += number;
|
||||
this.currChangingElems[currIndex++] = bitOffset;
|
||||
}
|
||||
a0 = bitOffset;
|
||||
continue;
|
||||
}
|
||||
if (code <= 8) {
|
||||
int a1 = b1 + code - 5;
|
||||
this.currChangingElems[currIndex++] = a1;
|
||||
if (!isWhite)
|
||||
setToBlack(buffer, lineOffset, bitOffset, a1 - bitOffset);
|
||||
bitOffset = a0 = a1;
|
||||
isWhite = !isWhite;
|
||||
updatePointer(7 - bits);
|
||||
continue;
|
||||
}
|
||||
throw new RuntimeException(JaiI18N.getString("TIFFFaxDecoder4"));
|
||||
}
|
||||
this.currChangingElems[currIndex++] = bitOffset;
|
||||
this.changingElemSize = currIndex;
|
||||
} else {
|
||||
decodeNextScanline(buffer, lineOffset, startX);
|
||||
}
|
||||
lineOffset += scanlineStride;
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void decodeT6(byte[] buffer, byte[] compData, int startX, int height, long tiffT6Options) {
|
||||
this.data = compData;
|
||||
this.compression = 4;
|
||||
this.bitPointer = 0;
|
||||
this.bytePointer = 0;
|
||||
int scanlineStride = (this.w + 7) / 8;
|
||||
int bufferOffset = 0;
|
||||
int[] b = new int[2];
|
||||
this.uncompressedMode = (int)((tiffT6Options & 0x2L) >> 1L);
|
||||
int[] cce = this.currChangingElems;
|
||||
this.changingElemSize = 0;
|
||||
cce[this.changingElemSize++] = this.w;
|
||||
cce[this.changingElemSize++] = this.w;
|
||||
int lineOffset = 0;
|
||||
for (int lines = 0; lines < height; lines++) {
|
||||
int a0 = -1;
|
||||
boolean isWhite = true;
|
||||
int[] temp = this.prevChangingElems;
|
||||
this.prevChangingElems = this.currChangingElems;
|
||||
cce = this.currChangingElems = temp;
|
||||
int currIndex = 0;
|
||||
int bitOffset = startX;
|
||||
this.lastChangingElement = 0;
|
||||
while (bitOffset < this.w) {
|
||||
getNextChangingElement(a0, isWhite, b);
|
||||
int b1 = b[0];
|
||||
int b2 = b[1];
|
||||
int entry = nextLesserThan8Bits(7);
|
||||
entry = twoDCodes[entry] & 0xFF;
|
||||
int code = (entry & 0x78) >>> 3;
|
||||
int bits = entry & 0x7;
|
||||
if (code == 0) {
|
||||
if (!isWhite) {
|
||||
if (b2 > this.w)
|
||||
b2 = this.w;
|
||||
setToBlack(buffer, lineOffset, bitOffset, b2 - bitOffset);
|
||||
}
|
||||
bitOffset = a0 = b2;
|
||||
updatePointer(7 - bits);
|
||||
continue;
|
||||
}
|
||||
if (code == 1) {
|
||||
updatePointer(7 - bits);
|
||||
if (isWhite) {
|
||||
int number = decodeWhiteCodeWord();
|
||||
bitOffset += number;
|
||||
cce[currIndex++] = bitOffset;
|
||||
number = decodeBlackCodeWord();
|
||||
if (number > this.w - bitOffset)
|
||||
number = this.w - bitOffset;
|
||||
setToBlack(buffer, lineOffset, bitOffset, number);
|
||||
bitOffset += number;
|
||||
cce[currIndex++] = bitOffset;
|
||||
} else {
|
||||
int number = decodeBlackCodeWord();
|
||||
if (number > this.w - bitOffset)
|
||||
number = this.w - bitOffset;
|
||||
setToBlack(buffer, lineOffset, bitOffset, number);
|
||||
bitOffset += number;
|
||||
cce[currIndex++] = bitOffset;
|
||||
number = decodeWhiteCodeWord();
|
||||
bitOffset += number;
|
||||
cce[currIndex++] = bitOffset;
|
||||
}
|
||||
a0 = bitOffset;
|
||||
continue;
|
||||
}
|
||||
if (code <= 8) {
|
||||
int a1 = b1 + code - 5;
|
||||
cce[currIndex++] = a1;
|
||||
if (!isWhite) {
|
||||
if (a1 > this.w)
|
||||
a1 = this.w;
|
||||
setToBlack(buffer, lineOffset, bitOffset, a1 - bitOffset);
|
||||
}
|
||||
bitOffset = a0 = a1;
|
||||
isWhite = !isWhite;
|
||||
updatePointer(7 - bits);
|
||||
continue;
|
||||
}
|
||||
if (code == 11) {
|
||||
if (nextLesserThan8Bits(3) != 7)
|
||||
throw new RuntimeException(JaiI18N.getString("TIFFFaxDecoder5"));
|
||||
int zeros = 0;
|
||||
boolean exit = false;
|
||||
while (!exit) {
|
||||
while (nextLesserThan8Bits(1) != 1)
|
||||
zeros++;
|
||||
if (zeros > 5) {
|
||||
zeros -= 6;
|
||||
if (!isWhite && zeros > 0)
|
||||
cce[currIndex++] = bitOffset;
|
||||
bitOffset += zeros;
|
||||
if (zeros > 0)
|
||||
isWhite = true;
|
||||
if (nextLesserThan8Bits(1) == 0) {
|
||||
if (!isWhite)
|
||||
cce[currIndex++] = bitOffset;
|
||||
isWhite = true;
|
||||
} else {
|
||||
if (isWhite)
|
||||
cce[currIndex++] = bitOffset;
|
||||
isWhite = false;
|
||||
}
|
||||
exit = true;
|
||||
}
|
||||
if (zeros == 5) {
|
||||
if (!isWhite)
|
||||
cce[currIndex++] = bitOffset;
|
||||
bitOffset += zeros;
|
||||
isWhite = true;
|
||||
continue;
|
||||
}
|
||||
bitOffset += zeros;
|
||||
cce[currIndex++] = bitOffset;
|
||||
setToBlack(buffer, lineOffset, bitOffset, 1);
|
||||
bitOffset++;
|
||||
isWhite = false;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
throw new RuntimeException(JaiI18N.getString("TIFFFaxDecoder5"));
|
||||
}
|
||||
if (currIndex <= this.w)
|
||||
cce[currIndex++] = bitOffset;
|
||||
this.changingElemSize = currIndex;
|
||||
lineOffset += scanlineStride;
|
||||
}
|
||||
}
|
||||
|
||||
private void setToBlack(byte[] buffer, int lineOffset, int bitOffset, int numBits) {
|
||||
int bitNum = 8 * lineOffset + bitOffset;
|
||||
int lastBit = bitNum + numBits;
|
||||
int byteNum = bitNum >> 3;
|
||||
int shift = bitNum & 0x7;
|
||||
if (shift > 0) {
|
||||
int maskVal = 1 << 7 - shift;
|
||||
byte val = buffer[byteNum];
|
||||
while (maskVal > 0 && bitNum < lastBit) {
|
||||
val = (byte)(val | maskVal);
|
||||
maskVal >>= 1;
|
||||
bitNum++;
|
||||
}
|
||||
buffer[byteNum] = val;
|
||||
}
|
||||
byteNum = bitNum >> 3;
|
||||
while (bitNum < lastBit - 7) {
|
||||
buffer[byteNum++] = -1;
|
||||
bitNum += 8;
|
||||
}
|
||||
while (bitNum < lastBit) {
|
||||
byteNum = bitNum >> 3;
|
||||
buffer[byteNum] = (byte)(buffer[byteNum] | 1 << 7 - (bitNum & 0x7));
|
||||
bitNum++;
|
||||
}
|
||||
}
|
||||
|
||||
private int decodeWhiteCodeWord() {
|
||||
int code = -1;
|
||||
int runLength = 0;
|
||||
boolean isWhite = true;
|
||||
while (isWhite) {
|
||||
int current = nextNBits(10);
|
||||
int entry = white[current];
|
||||
int isT = entry & 0x1;
|
||||
int bits = entry >>> 1 & 0xF;
|
||||
if (bits == 12) {
|
||||
int twoBits = nextLesserThan8Bits(2);
|
||||
current = current << 2 & 0xC | twoBits;
|
||||
entry = additionalMakeup[current];
|
||||
bits = entry >>> 1 & 0x7;
|
||||
code = entry >>> 4 & 0xFFF;
|
||||
runLength += code;
|
||||
updatePointer(4 - bits);
|
||||
continue;
|
||||
}
|
||||
if (bits == 0)
|
||||
throw new RuntimeException(JaiI18N.getString("TIFFFaxDecoder0"));
|
||||
if (bits == 15)
|
||||
throw new RuntimeException(JaiI18N.getString("TIFFFaxDecoder1"));
|
||||
code = entry >>> 5 & 0x7FF;
|
||||
runLength += code;
|
||||
updatePointer(10 - bits);
|
||||
if (isT == 0)
|
||||
isWhite = false;
|
||||
}
|
||||
return runLength;
|
||||
}
|
||||
|
||||
private int decodeBlackCodeWord() {
|
||||
int code = -1;
|
||||
int runLength = 0;
|
||||
boolean isWhite = false;
|
||||
while (!isWhite) {
|
||||
int current = nextLesserThan8Bits(4);
|
||||
int entry = initBlack[current];
|
||||
int isT = entry & 0x1;
|
||||
int bits = entry >>> 1 & 0xF;
|
||||
code = entry >>> 5 & 0x7FF;
|
||||
if (code == 100) {
|
||||
current = nextNBits(9);
|
||||
entry = black[current];
|
||||
isT = entry & 0x1;
|
||||
bits = entry >>> 1 & 0xF;
|
||||
code = entry >>> 5 & 0x7FF;
|
||||
if (bits == 12) {
|
||||
updatePointer(5);
|
||||
current = nextLesserThan8Bits(4);
|
||||
entry = additionalMakeup[current];
|
||||
bits = entry >>> 1 & 0x7;
|
||||
code = entry >>> 4 & 0xFFF;
|
||||
runLength += code;
|
||||
updatePointer(4 - bits);
|
||||
continue;
|
||||
}
|
||||
if (bits == 15)
|
||||
throw new RuntimeException(JaiI18N.getString("TIFFFaxDecoder2"));
|
||||
runLength += code;
|
||||
updatePointer(9 - bits);
|
||||
if (isT == 0)
|
||||
isWhite = true;
|
||||
continue;
|
||||
}
|
||||
if (code == 200) {
|
||||
current = nextLesserThan8Bits(2);
|
||||
entry = twoBitBlack[current];
|
||||
code = entry >>> 5 & 0x7FF;
|
||||
runLength += code;
|
||||
bits = entry >>> 1 & 0xF;
|
||||
updatePointer(2 - bits);
|
||||
isWhite = true;
|
||||
continue;
|
||||
}
|
||||
runLength += code;
|
||||
updatePointer(4 - bits);
|
||||
isWhite = true;
|
||||
}
|
||||
return runLength;
|
||||
}
|
||||
|
||||
private boolean seekEOL() {
|
||||
int bitIndexMax = this.data.length * 8 - 1;
|
||||
int bitIndex = this.bytePointer * 8 + this.bitPointer;
|
||||
while (bitIndex <= bitIndexMax - 12) {
|
||||
int next12Bits = nextNBits(12);
|
||||
bitIndex += 12;
|
||||
while (next12Bits != 1 && bitIndex < bitIndexMax) {
|
||||
next12Bits = (next12Bits & 0x7FF) << 1 | nextLesserThan8Bits(1) & 0x1;
|
||||
bitIndex++;
|
||||
}
|
||||
if (next12Bits == 1) {
|
||||
updatePointer(12);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private int readEOL(boolean isFirstEOL) {
|
||||
if (this.oneD == 0)
|
||||
if (!seekEOL())
|
||||
throw new RuntimeException(JaiI18N.getString("TIFFFaxDecoder9"));
|
||||
if (this.fillBits == 0) {
|
||||
int next12Bits = nextNBits(12);
|
||||
if (isFirstEOL && next12Bits == 0)
|
||||
if (nextNBits(4) == 1) {
|
||||
this.fillBits = 1;
|
||||
return 1;
|
||||
}
|
||||
if (next12Bits != 1)
|
||||
throw new RuntimeException(JaiI18N.getString("TIFFFaxDecoder6"));
|
||||
} else if (this.fillBits == 1) {
|
||||
int bitsLeft = 8 - this.bitPointer;
|
||||
if (nextNBits(bitsLeft) != 0)
|
||||
throw new RuntimeException(JaiI18N.getString("TIFFFaxDecoder8"));
|
||||
if (bitsLeft < 4 &&
|
||||
nextNBits(8) != 0)
|
||||
throw new RuntimeException(JaiI18N.getString("TIFFFaxDecoder8"));
|
||||
int next8 = nextNBits(8);
|
||||
if (isFirstEOL && (next8 & 0xF0) == 16) {
|
||||
this.fillBits = 0;
|
||||
updatePointer(4);
|
||||
} else {
|
||||
while (next8 != 1) {
|
||||
if (next8 != 0)
|
||||
throw new RuntimeException(JaiI18N.getString("TIFFFaxDecoder8"));
|
||||
next8 = nextNBits(8);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (this.oneD == 0)
|
||||
return 1;
|
||||
return nextLesserThan8Bits(1);
|
||||
}
|
||||
|
||||
private void getNextChangingElement(int a0, boolean isWhite, int[] ret) {
|
||||
int[] pce = this.prevChangingElems;
|
||||
int ces = this.changingElemSize;
|
||||
int start = (this.lastChangingElement > 0) ? (this.lastChangingElement - 1) : 0;
|
||||
if (isWhite) {
|
||||
start &= 0xFFFFFFFE;
|
||||
} else {
|
||||
start |= 0x1;
|
||||
}
|
||||
int i = start;
|
||||
for (; i < ces; i += 2) {
|
||||
int temp = pce[i];
|
||||
if (temp > a0) {
|
||||
this.lastChangingElement = i;
|
||||
ret[0] = temp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i + 1 < ces)
|
||||
ret[1] = pce[i + 1];
|
||||
}
|
||||
|
||||
private int nextNBits(int bitsToGet) {
|
||||
byte b, next, next2next;
|
||||
int l = this.data.length - 1;
|
||||
int bp = this.bytePointer;
|
||||
if (this.fillOrder == 1) {
|
||||
b = this.data[bp];
|
||||
if (bp == l) {
|
||||
next = 0;
|
||||
next2next = 0;
|
||||
} else if (bp + 1 == l) {
|
||||
next = this.data[bp + 1];
|
||||
next2next = 0;
|
||||
} else {
|
||||
next = this.data[bp + 1];
|
||||
next2next = this.data[bp + 2];
|
||||
}
|
||||
} else if (this.fillOrder == 2) {
|
||||
b = flipTable[this.data[bp] & 0xFF];
|
||||
if (bp == l) {
|
||||
next = 0;
|
||||
next2next = 0;
|
||||
} else if (bp + 1 == l) {
|
||||
next = flipTable[this.data[bp + 1] & 0xFF];
|
||||
next2next = 0;
|
||||
} else {
|
||||
next = flipTable[this.data[bp + 1] & 0xFF];
|
||||
next2next = flipTable[this.data[bp + 2] & 0xFF];
|
||||
}
|
||||
} else {
|
||||
throw new RuntimeException(JaiI18N.getString("TIFFFaxDecoder7"));
|
||||
}
|
||||
int bitsLeft = 8 - this.bitPointer;
|
||||
int bitsFromNextByte = bitsToGet - bitsLeft;
|
||||
int bitsFromNext2NextByte = 0;
|
||||
if (bitsFromNextByte > 8) {
|
||||
bitsFromNext2NextByte = bitsFromNextByte - 8;
|
||||
bitsFromNextByte = 8;
|
||||
}
|
||||
this.bytePointer++;
|
||||
int i1 = (b & table1[bitsLeft]) << bitsToGet - bitsLeft;
|
||||
int i2 = (next & table2[bitsFromNextByte]) >>> 8 - bitsFromNextByte;
|
||||
int i3 = 0;
|
||||
if (bitsFromNext2NextByte != 0) {
|
||||
i2 <<= bitsFromNext2NextByte;
|
||||
i3 = (next2next & table2[bitsFromNext2NextByte]) >>> 8 - bitsFromNext2NextByte;
|
||||
i2 |= i3;
|
||||
this.bytePointer++;
|
||||
this.bitPointer = bitsFromNext2NextByte;
|
||||
} else if (bitsFromNextByte == 8) {
|
||||
this.bitPointer = 0;
|
||||
this.bytePointer++;
|
||||
} else {
|
||||
this.bitPointer = bitsFromNextByte;
|
||||
}
|
||||
int i = i1 | i2;
|
||||
return i;
|
||||
}
|
||||
|
||||
private int nextLesserThan8Bits(int bitsToGet) {
|
||||
byte b, next;
|
||||
int i1;
|
||||
int l = this.data.length - 1;
|
||||
int bp = this.bytePointer;
|
||||
if (this.fillOrder == 1) {
|
||||
b = this.data[bp];
|
||||
if (bp == l) {
|
||||
next = 0;
|
||||
} else {
|
||||
next = this.data[bp + 1];
|
||||
}
|
||||
} else if (this.fillOrder == 2) {
|
||||
b = flipTable[this.data[bp] & 0xFF];
|
||||
if (bp == l) {
|
||||
next = 0;
|
||||
} else {
|
||||
next = flipTable[this.data[bp + 1] & 0xFF];
|
||||
}
|
||||
} else {
|
||||
throw new RuntimeException(JaiI18N.getString("TIFFFaxDecoder7"));
|
||||
}
|
||||
int bitsLeft = 8 - this.bitPointer;
|
||||
int bitsFromNextByte = bitsToGet - bitsLeft;
|
||||
int shift = bitsLeft - bitsToGet;
|
||||
if (shift >= 0) {
|
||||
i1 = (b & table1[bitsLeft]) >>> shift;
|
||||
this.bitPointer += bitsToGet;
|
||||
if (this.bitPointer == 8) {
|
||||
this.bitPointer = 0;
|
||||
this.bytePointer++;
|
||||
}
|
||||
} else {
|
||||
i1 = (b & table1[bitsLeft]) << -shift;
|
||||
int i2 = (next & table2[bitsFromNextByte]) >>> 8 - bitsFromNextByte;
|
||||
i1 |= i2;
|
||||
this.bytePointer++;
|
||||
this.bitPointer = bitsFromNextByte;
|
||||
}
|
||||
return i1;
|
||||
}
|
||||
|
||||
private void updatePointer(int bitsToMoveBack) {
|
||||
if (bitsToMoveBack > 8) {
|
||||
this.bytePointer -= bitsToMoveBack / 8;
|
||||
bitsToMoveBack %= 8;
|
||||
}
|
||||
int i = this.bitPointer - bitsToMoveBack;
|
||||
if (i < 0) {
|
||||
this.bytePointer--;
|
||||
this.bitPointer = 8 + i;
|
||||
} else {
|
||||
this.bitPointer = i;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean advancePointer() {
|
||||
if (this.bitPointer != 0) {
|
||||
this.bytePointer++;
|
||||
this.bitPointer = 0;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,364 @@
|
|||
package com.sun.media.jai.codecimpl;
|
||||
|
||||
class TIFFFaxEncoder {
|
||||
private static final int WHITE = 0;
|
||||
|
||||
private static final int BLACK = 1;
|
||||
|
||||
private static byte[] byteTable = new byte[] {
|
||||
8, 7, 6, 6, 5, 5, 5, 5, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 3, 3, 3, 3,
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
3, 3, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0 };
|
||||
|
||||
private static int[] termCodesBlack = new int[] {
|
||||
230686730, 1073741827, -1073741822, -2147483646, 1610612739, 805306372, 536870916, 402653189, 335544326, 268435462,
|
||||
134217735, 167772167, 234881031, 67108872, 117440520, 201326601, 96469002, 100663306, 33554442, 216006667,
|
||||
218103819, 226492427, 115343371, 83886091, 48234507, 50331659, 211812364, 212860940, 213909516, 214958092,
|
||||
109051916, 110100492, 111149068, 112197644, 220200972, 221249548, 222298124, 223346700, 224395276, 225443852,
|
||||
113246220, 114294796, 228589580, 229638156, 88080396, 89128972, 90177548, 91226124, 104857612, 105906188,
|
||||
85983244, 87031820, 37748748, 57671692, 58720268, 40894476, 41943052, 92274700, 93323276, 45088780,
|
||||
46137356, 94371852, 106954764, 108003340 };
|
||||
|
||||
private static int[] termCodesWhite = new int[] {
|
||||
889192456, 469762054, 1879048196, -2147483644, -1342177276, -1073741820, -536870908, -268435452, -1744830459, -1610612731,
|
||||
939524101, 1073741829, 536870918, 201326598, -805306362, -738197498, -1476395002, -1409286138, 1308622855, 402653191,
|
||||
268435463, 771751943, 100663303, 134217735, 1342177287, 1442840583, 637534215, 1207959559, 805306375, 33554440,
|
||||
50331656, 436207624, 452984840, 301989896, 318767112, 335544328, 352321544, 369098760, 385875976, 671088648,
|
||||
687865864, 704643080, 721420296, 738197512, 754974728, 67108872, 83886088, 167772168, 184549384, 1375731720,
|
||||
1392508936, 1409286152, 1426063368, 603979784, 620757000, 1476395016, 1493172232, 1509949448, 1526726664, 1241513992,
|
||||
1258291208, 838860808, 855638024, 872415240 };
|
||||
|
||||
private static int[] makeupCodesBlack = new int[] {
|
||||
0, 62914570, 209715212, 210763788, 95420428, 53477388, 54525964, 55574540, 56623117, 57147405,
|
||||
38797325, 39321613, 39845901, 40370189, 59768845, 60293133, 60817421, 61341709, 61865997, 62390285,
|
||||
42991629, 43515917, 44040205, 44564493, 47185933, 47710221, 52428813, 52953101, 16777227, 25165835,
|
||||
27262987, 18874380, 19922956, 20971532, 22020108, 23068684, 24117260, 29360140, 30408716, 31457292,
|
||||
32505868, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
private static int[] makeupCodesWhite = new int[] {
|
||||
0, -671088635, -1879048187, 1543503878, 1845493767, 905969672, 922746888, 1677721608, 1694498824, 1744830472,
|
||||
1728053256, 1711276041, 1719664649, 1761607689, 1769996297, 1778384905, 1786773513, 1795162121, 1803550729, 1811939337,
|
||||
1820327945, 1828716553, 1837105161, 1275068425, 1283457033, 1291845641, 1610612742, 1300234249, 16777227, 25165835,
|
||||
27262987, 18874380, 19922956, 20971532, 22020108, 23068684, 24117260, 29360140, 30408716, 31457292,
|
||||
32505868, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
private static int[] passMode = new int[] { 268435460 };
|
||||
|
||||
private static int[] vertMode = new int[] { 100663303, 201326598, 1610612739, -2147483647, 1073741827, 134217734, 67108871 };
|
||||
|
||||
private static int[] horzMode = new int[] { 536870915 };
|
||||
|
||||
private static int[][] termCodes = new int[][] { termCodesWhite, termCodesBlack };
|
||||
|
||||
private static int[][] makeupCodes = new int[][] { makeupCodesWhite, makeupCodesBlack };
|
||||
|
||||
private static int[][] pass = new int[][] { passMode, passMode };
|
||||
|
||||
private static int[][] vert = new int[][] { vertMode, vertMode };
|
||||
|
||||
private static int[][] horz = new int[][] { horzMode, horzMode };
|
||||
|
||||
private boolean inverseFill;
|
||||
|
||||
private int bits;
|
||||
|
||||
private int ndex;
|
||||
|
||||
TIFFFaxEncoder(boolean inverseFill) {
|
||||
this.inverseFill = inverseFill;
|
||||
}
|
||||
|
||||
private int nextState(byte[] data, int base, int bitOffset, int maxOffset) {
|
||||
int testbyte;
|
||||
if (data == null)
|
||||
return maxOffset;
|
||||
int next = base + (bitOffset >>> 3);
|
||||
if (next >= data.length)
|
||||
return maxOffset;
|
||||
int end = base + (maxOffset >>> 3);
|
||||
if (end == data.length)
|
||||
end--;
|
||||
int extra = bitOffset & 0x7;
|
||||
if ((data[next] & 128 >>> extra) != 0) {
|
||||
testbyte = (data[next] ^ 0xFFFFFFFF) & 255 >>> extra;
|
||||
while (next < end &&
|
||||
testbyte == 0)
|
||||
testbyte = (data[++next] ^ 0xFFFFFFFF) & 0xFF;
|
||||
} else {
|
||||
if ((testbyte = data[next] & 255 >>> extra) != 0) {
|
||||
bitOffset = (next - base) * 8 + byteTable[testbyte];
|
||||
return (bitOffset < maxOffset) ? bitOffset : maxOffset;
|
||||
}
|
||||
while (next < end) {
|
||||
if ((testbyte = data[++next] & 0xFF) != 0) {
|
||||
bitOffset = (next - base) * 8 + byteTable[testbyte];
|
||||
return (bitOffset < maxOffset) ? bitOffset : maxOffset;
|
||||
}
|
||||
}
|
||||
}
|
||||
bitOffset = (next - base) * 8 + byteTable[testbyte];
|
||||
return (bitOffset < maxOffset) ? bitOffset : maxOffset;
|
||||
}
|
||||
|
||||
private void initBitBuf() {
|
||||
this.ndex = 0;
|
||||
this.bits = 0;
|
||||
}
|
||||
|
||||
private int add1DBits(byte[] buf, int where, int count, int color) {
|
||||
int len = where;
|
||||
int sixtyfours = count >>> 6;
|
||||
count &= 0x3F;
|
||||
if (sixtyfours != 0) {
|
||||
for (; sixtyfours > 40; sixtyfours -= 40) {
|
||||
int j = makeupCodes[color][40];
|
||||
this.bits |= (j & 0xFFF80000) >>> this.ndex;
|
||||
this.ndex += j & 0xFFFF;
|
||||
while (this.ndex > 7) {
|
||||
buf[len++] = (byte)(this.bits >>> 24);
|
||||
this.bits <<= 8;
|
||||
this.ndex -= 8;
|
||||
}
|
||||
}
|
||||
int i = makeupCodes[color][sixtyfours];
|
||||
this.bits |= (i & 0xFFF80000) >>> this.ndex;
|
||||
this.ndex += i & 0xFFFF;
|
||||
while (this.ndex > 7) {
|
||||
buf[len++] = (byte)(this.bits >>> 24);
|
||||
this.bits <<= 8;
|
||||
this.ndex -= 8;
|
||||
}
|
||||
}
|
||||
int mask = termCodes[color][count];
|
||||
this.bits |= (mask & 0xFFF80000) >>> this.ndex;
|
||||
this.ndex += mask & 0xFFFF;
|
||||
while (this.ndex > 7) {
|
||||
buf[len++] = (byte)(this.bits >>> 24);
|
||||
this.bits <<= 8;
|
||||
this.ndex -= 8;
|
||||
}
|
||||
return len - where;
|
||||
}
|
||||
|
||||
private int add2DBits(byte[] buf, int where, int[][] mode, int entry) {
|
||||
int len = where;
|
||||
int color = 0;
|
||||
int mask = mode[color][entry];
|
||||
this.bits |= (mask & 0xFFF80000) >>> this.ndex;
|
||||
this.ndex += mask & 0xFFFF;
|
||||
while (this.ndex > 7) {
|
||||
buf[len++] = (byte)(this.bits >>> 24);
|
||||
this.bits <<= 8;
|
||||
this.ndex -= 8;
|
||||
}
|
||||
return len - where;
|
||||
}
|
||||
|
||||
private int addEOL(boolean is1DMode, boolean addFill, boolean add1, byte[] buf, int where) {
|
||||
int len = where;
|
||||
if (addFill)
|
||||
this.ndex += (this.ndex <= 4) ? (4 - this.ndex) : (12 - this.ndex);
|
||||
if (is1DMode) {
|
||||
this.bits |= 1048576 >>> this.ndex;
|
||||
this.ndex += 12;
|
||||
} else {
|
||||
this.bits |= (add1 ? 1572864 : 1048576) >>> this.ndex;
|
||||
this.ndex += 13;
|
||||
}
|
||||
while (this.ndex > 7) {
|
||||
buf[len++] = (byte)(this.bits >>> 24);
|
||||
this.bits <<= 8;
|
||||
this.ndex -= 8;
|
||||
}
|
||||
return len - where;
|
||||
}
|
||||
|
||||
private int addEOFB(byte[] buf, int where) {
|
||||
int len = where;
|
||||
this.bits |= 1048832 >>> this.ndex;
|
||||
this.ndex += 24;
|
||||
while (this.ndex > 0) {
|
||||
buf[len++] = (byte)(this.bits >>> 24);
|
||||
this.bits <<= 8;
|
||||
this.ndex -= 8;
|
||||
}
|
||||
return len - where;
|
||||
}
|
||||
|
||||
private int encode1D(byte[] data, int rowOffset, int colOffset, int rowLength, byte[] compData, int compOffset) {
|
||||
int lineAddr = rowOffset;
|
||||
int bitIndex = colOffset;
|
||||
int last = bitIndex + rowLength;
|
||||
int outIndex = compOffset;
|
||||
int testbit = (data[lineAddr + (bitIndex >>> 3)] & 0xFF) >>> 7 - (bitIndex & 0x7) & 0x1;
|
||||
int currentColor = 1;
|
||||
if (testbit != 0) {
|
||||
outIndex += add1DBits(compData, outIndex, 0, 0);
|
||||
} else {
|
||||
currentColor = 0;
|
||||
}
|
||||
while (bitIndex < last) {
|
||||
int bitCount = nextState(data, lineAddr, bitIndex, last) - bitIndex;
|
||||
outIndex += add1DBits(compData, outIndex, bitCount, currentColor);
|
||||
bitIndex += bitCount;
|
||||
currentColor ^= 0x1;
|
||||
}
|
||||
return outIndex - compOffset;
|
||||
}
|
||||
|
||||
synchronized int encodeRLE(byte[] data, int rowOffset, int colOffset, int rowLength, byte[] compData) {
|
||||
initBitBuf();
|
||||
int outIndex = encode1D(data, rowOffset, colOffset, rowLength, compData, 0);
|
||||
while (this.ndex > 0) {
|
||||
compData[outIndex++] = (byte)(this.bits >>> 24);
|
||||
this.bits <<= 8;
|
||||
this.ndex -= 8;
|
||||
}
|
||||
if (this.inverseFill) {
|
||||
byte[] flipTable = TIFFFaxDecoder.flipTable;
|
||||
for (int i = 0; i < outIndex; i++)
|
||||
compData[i] = flipTable[compData[i] & 0xFF];
|
||||
}
|
||||
return outIndex;
|
||||
}
|
||||
|
||||
synchronized int encodeT4(boolean is1DMode, boolean isEOLAligned, byte[] data, int lineStride, int colOffset, int width, int height, byte[] compData) {
|
||||
byte[] refData = data;
|
||||
int lineAddr = 0;
|
||||
int outIndex = 0;
|
||||
initBitBuf();
|
||||
int KParameter = 2;
|
||||
for (int numRows = 0; numRows < height; numRows++) {
|
||||
if (is1DMode || numRows % KParameter == 0) {
|
||||
outIndex += addEOL(is1DMode, isEOLAligned, true, compData, outIndex);
|
||||
outIndex += encode1D(data, lineAddr, colOffset, width, compData, outIndex);
|
||||
} else {
|
||||
outIndex += addEOL(is1DMode, isEOLAligned, false, compData, outIndex);
|
||||
int refAddr = lineAddr - lineStride;
|
||||
int a0 = colOffset;
|
||||
int last = a0 + width;
|
||||
int testbit = (data[lineAddr + (a0 >>> 3)] & 0xFF) >>> 7 - (a0 & 0x7) & 0x1;
|
||||
int a1 = (testbit != 0) ? a0 : nextState(data, lineAddr, a0, last);
|
||||
testbit = (refData[refAddr + (a0 >>> 3)] & 0xFF) >>> 7 - (a0 & 0x7) & 0x1;
|
||||
int b1 = (testbit != 0) ? a0 : nextState(refData, refAddr, a0, last);
|
||||
int color = 0;
|
||||
while (true) {
|
||||
int b2 = nextState(refData, refAddr, b1, last);
|
||||
if (b2 < a1) {
|
||||
outIndex += add2DBits(compData, outIndex, pass, 0);
|
||||
a0 = b2;
|
||||
} else {
|
||||
int tmp = b1 - a1 + 3;
|
||||
if (tmp <= 6 && tmp >= 0) {
|
||||
outIndex += add2DBits(compData, outIndex, vert, tmp);
|
||||
a0 = a1;
|
||||
} else {
|
||||
int a2 = nextState(data, lineAddr, a1, last);
|
||||
outIndex += add2DBits(compData, outIndex, horz, 0);
|
||||
outIndex += add1DBits(compData, outIndex, a1 - a0, color);
|
||||
outIndex += add1DBits(compData, outIndex, a2 - a1, color ^ 0x1);
|
||||
a0 = a2;
|
||||
}
|
||||
}
|
||||
if (a0 >= last)
|
||||
break;
|
||||
color = (data[lineAddr + (a0 >>> 3)] & 0xFF) >>> 7 - (a0 & 0x7) & 0x1;
|
||||
a1 = nextState(data, lineAddr, a0, last);
|
||||
b1 = nextState(refData, refAddr, a0, last);
|
||||
testbit = (refData[refAddr + (b1 >>> 3)] & 0xFF) >>> 7 - (b1 & 0x7) & 0x1;
|
||||
if (testbit == color)
|
||||
b1 = nextState(refData, refAddr, b1, last);
|
||||
}
|
||||
}
|
||||
lineAddr += lineStride;
|
||||
}
|
||||
for (int i = 0; i < 6; i++)
|
||||
outIndex += addEOL(is1DMode, isEOLAligned, true, compData, outIndex);
|
||||
while (this.ndex > 0) {
|
||||
compData[outIndex++] = (byte)(this.bits >>> 24);
|
||||
this.bits <<= 8;
|
||||
this.ndex -= 8;
|
||||
}
|
||||
if (this.inverseFill)
|
||||
for (int j = 0; j < outIndex; j++)
|
||||
compData[j] = TIFFFaxDecoder.flipTable[compData[j] & 0xFF];
|
||||
return outIndex;
|
||||
}
|
||||
|
||||
public synchronized int encodeT6(byte[] data, int lineStride, int colOffset, int width, int height, byte[] compData) {
|
||||
byte[] refData = null;
|
||||
int refAddr = 0;
|
||||
int lineAddr = 0;
|
||||
int outIndex = 0;
|
||||
initBitBuf();
|
||||
while (height-- != 0) {
|
||||
int a0 = colOffset;
|
||||
int last = a0 + width;
|
||||
int testbit = (data[lineAddr + (a0 >>> 3)] & 0xFF) >>> 7 - (a0 & 0x7) & 0x1;
|
||||
int a1 = (testbit != 0) ? a0 : nextState(data, lineAddr, a0, last);
|
||||
testbit = (refData == null) ? 0 : ((refData[refAddr + (a0 >>> 3)] & 0xFF) >>> 7 - (a0 & 0x7) & 0x1);
|
||||
int b1 = (testbit != 0) ? a0 : nextState(refData, refAddr, a0, last);
|
||||
int color = 0;
|
||||
while (true) {
|
||||
int b2 = nextState(refData, refAddr, b1, last);
|
||||
if (b2 < a1) {
|
||||
outIndex += add2DBits(compData, outIndex, pass, 0);
|
||||
a0 = b2;
|
||||
} else {
|
||||
int tmp = b1 - a1 + 3;
|
||||
if (tmp <= 6 && tmp >= 0) {
|
||||
outIndex += add2DBits(compData, outIndex, vert, tmp);
|
||||
a0 = a1;
|
||||
} else {
|
||||
int a2 = nextState(data, lineAddr, a1, last);
|
||||
outIndex += add2DBits(compData, outIndex, horz, 0);
|
||||
outIndex += add1DBits(compData, outIndex, a1 - a0, color);
|
||||
outIndex += add1DBits(compData, outIndex, a2 - a1, color ^ 0x1);
|
||||
a0 = a2;
|
||||
}
|
||||
}
|
||||
if (a0 >= last)
|
||||
break;
|
||||
color = (data[lineAddr + (a0 >>> 3)] & 0xFF) >>> 7 - (a0 & 0x7) & 0x1;
|
||||
a1 = nextState(data, lineAddr, a0, last);
|
||||
b1 = nextState(refData, refAddr, a0, last);
|
||||
testbit = (refData == null) ? 0 : ((refData[refAddr + (b1 >>> 3)] & 0xFF) >>> 7 - (b1 & 0x7) & 0x1);
|
||||
if (testbit == color)
|
||||
b1 = nextState(refData, refAddr, b1, last);
|
||||
}
|
||||
refData = data;
|
||||
refAddr = lineAddr;
|
||||
lineAddr += lineStride;
|
||||
}
|
||||
outIndex += addEOFB(compData, outIndex);
|
||||
if (this.inverseFill)
|
||||
for (int i = 0; i < outIndex; i++)
|
||||
compData[i] = TIFFFaxDecoder.flipTable[compData[i] & 0xFF];
|
||||
return outIndex;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,85 @@
|
|||
package com.sun.media.jai.codecimpl;
|
||||
|
||||
import com.sun.media.jai.codec.ImageDecodeParam;
|
||||
import com.sun.media.jai.codec.ImageDecoderImpl;
|
||||
import com.sun.media.jai.codec.SeekableStream;
|
||||
import com.sun.media.jai.codec.TIFFDecodeParam;
|
||||
import com.sun.media.jai.codec.TIFFDirectory;
|
||||
import java.awt.image.RenderedImage;
|
||||
import java.io.IOException;
|
||||
|
||||
public class TIFFImageDecoder extends ImageDecoderImpl {
|
||||
public static final int TIFF_IMAGE_WIDTH = 256;
|
||||
|
||||
public static final int TIFF_IMAGE_LENGTH = 257;
|
||||
|
||||
public static final int TIFF_BITS_PER_SAMPLE = 258;
|
||||
|
||||
public static final int TIFF_COMPRESSION = 259;
|
||||
|
||||
public static final int TIFF_PHOTOMETRIC_INTERPRETATION = 262;
|
||||
|
||||
public static final int TIFF_FILL_ORDER = 266;
|
||||
|
||||
public static final int TIFF_STRIP_OFFSETS = 273;
|
||||
|
||||
public static final int TIFF_SAMPLES_PER_PIXEL = 277;
|
||||
|
||||
public static final int TIFF_ROWS_PER_STRIP = 278;
|
||||
|
||||
public static final int TIFF_STRIP_BYTE_COUNTS = 279;
|
||||
|
||||
public static final int TIFF_X_RESOLUTION = 282;
|
||||
|
||||
public static final int TIFF_Y_RESOLUTION = 283;
|
||||
|
||||
public static final int TIFF_PLANAR_CONFIGURATION = 284;
|
||||
|
||||
public static final int TIFF_T4_OPTIONS = 292;
|
||||
|
||||
public static final int TIFF_T6_OPTIONS = 293;
|
||||
|
||||
public static final int TIFF_RESOLUTION_UNIT = 296;
|
||||
|
||||
public static final int TIFF_PREDICTOR = 317;
|
||||
|
||||
public static final int TIFF_COLORMAP = 320;
|
||||
|
||||
public static final int TIFF_TILE_WIDTH = 322;
|
||||
|
||||
public static final int TIFF_TILE_LENGTH = 323;
|
||||
|
||||
public static final int TIFF_TILE_OFFSETS = 324;
|
||||
|
||||
public static final int TIFF_TILE_BYTE_COUNTS = 325;
|
||||
|
||||
public static final int TIFF_EXTRA_SAMPLES = 338;
|
||||
|
||||
public static final int TIFF_SAMPLE_FORMAT = 339;
|
||||
|
||||
public static final int TIFF_S_MIN_SAMPLE_VALUE = 340;
|
||||
|
||||
public static final int TIFF_S_MAX_SAMPLE_VALUE = 341;
|
||||
|
||||
public TIFFImageDecoder(SeekableStream input, ImageDecodeParam param) {
|
||||
super(input, param);
|
||||
}
|
||||
|
||||
public int getNumPages() throws IOException {
|
||||
try {
|
||||
return TIFFDirectory.getNumDirectories(this.input);
|
||||
} catch (Exception e) {
|
||||
throw CodecUtils.toIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public RenderedImage decodeAsRenderedImage(int page) throws IOException {
|
||||
if (page < 0 || page >= getNumPages())
|
||||
throw new IOException(JaiI18N.getString("TIFFImageDecoder0"));
|
||||
try {
|
||||
return new TIFFImage(this.input, (TIFFDecodeParam)this.param, page);
|
||||
} catch (Exception e) {
|
||||
throw CodecUtils.toIOException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,156 @@
|
|||
package com.sun.media.jai.codecimpl;
|
||||
|
||||
public class TIFFLZWDecoder {
|
||||
byte[][] stringTable;
|
||||
|
||||
byte[] data = null;
|
||||
|
||||
byte[] uncompData;
|
||||
|
||||
int tableIndex;
|
||||
|
||||
int bitsToGet = 9;
|
||||
|
||||
int bytePointer;
|
||||
|
||||
int bitPointer;
|
||||
|
||||
int dstIndex;
|
||||
|
||||
int w;
|
||||
|
||||
int h;
|
||||
|
||||
int predictor;
|
||||
|
||||
int samplesPerPixel;
|
||||
|
||||
int nextData = 0;
|
||||
|
||||
int nextBits = 0;
|
||||
|
||||
int[] andTable = new int[] { 511, 1023, 2047, 4095 };
|
||||
|
||||
public TIFFLZWDecoder(int w, int predictor, int samplesPerPixel) {
|
||||
this.w = w;
|
||||
this.predictor = predictor;
|
||||
this.samplesPerPixel = samplesPerPixel;
|
||||
}
|
||||
|
||||
public byte[] decode(byte[] data, byte[] uncompData, int h) {
|
||||
if (data[0] == 0 && data[1] == 1)
|
||||
throw new UnsupportedOperationException(JaiI18N.getString("TIFFLZWDecoder0"));
|
||||
initializeStringTable();
|
||||
this.data = data;
|
||||
this.h = h;
|
||||
this.uncompData = uncompData;
|
||||
this.bytePointer = 0;
|
||||
this.bitPointer = 0;
|
||||
this.dstIndex = 0;
|
||||
this.nextData = 0;
|
||||
this.nextBits = 0;
|
||||
int oldCode = 0;
|
||||
int uncompDataLength = uncompData.length;
|
||||
int code;
|
||||
while ((code = getNextCode()) != 257 && this.dstIndex < uncompDataLength) {
|
||||
if (code == 256) {
|
||||
initializeStringTable();
|
||||
code = getNextCode();
|
||||
if (code == 257)
|
||||
break;
|
||||
writeString(this.stringTable[code]);
|
||||
oldCode = code;
|
||||
continue;
|
||||
}
|
||||
if (code < this.tableIndex) {
|
||||
byte[] arrayOfByte = this.stringTable[code];
|
||||
writeString(arrayOfByte);
|
||||
addStringToTable(this.stringTable[oldCode], arrayOfByte[0]);
|
||||
oldCode = code;
|
||||
continue;
|
||||
}
|
||||
byte[] string = this.stringTable[oldCode];
|
||||
string = composeString(string, string[0]);
|
||||
writeString(string);
|
||||
addStringToTable(string);
|
||||
oldCode = code;
|
||||
}
|
||||
if (this.predictor == 2)
|
||||
for (int j = 0; j < h; j++) {
|
||||
int count = this.samplesPerPixel * (j * this.w + 1);
|
||||
for (int i = this.samplesPerPixel; i < this.w * this.samplesPerPixel; i++) {
|
||||
uncompData[count] = (byte)(uncompData[count] + uncompData[count - this.samplesPerPixel]);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return uncompData;
|
||||
}
|
||||
|
||||
public void initializeStringTable() {
|
||||
this.stringTable = new byte[4096][];
|
||||
for (int i = 0; i < 256; i++) {
|
||||
this.stringTable[i] = new byte[1];
|
||||
this.stringTable[i][0] = (byte)i;
|
||||
}
|
||||
this.tableIndex = 258;
|
||||
this.bitsToGet = 9;
|
||||
}
|
||||
|
||||
public void writeString(byte[] string) {
|
||||
if (this.dstIndex < this.uncompData.length) {
|
||||
int maxIndex = Math.min(string.length, this.uncompData.length - this.dstIndex);
|
||||
for (int i = 0; i < maxIndex; i++)
|
||||
this.uncompData[this.dstIndex++] = string[i];
|
||||
}
|
||||
}
|
||||
|
||||
public void addStringToTable(byte[] oldString, byte newString) {
|
||||
int length = oldString.length;
|
||||
byte[] string = new byte[length + 1];
|
||||
System.arraycopy(oldString, 0, string, 0, length);
|
||||
string[length] = newString;
|
||||
this.stringTable[this.tableIndex++] = string;
|
||||
if (this.tableIndex == 511) {
|
||||
this.bitsToGet = 10;
|
||||
} else if (this.tableIndex == 1023) {
|
||||
this.bitsToGet = 11;
|
||||
} else if (this.tableIndex == 2047) {
|
||||
this.bitsToGet = 12;
|
||||
}
|
||||
}
|
||||
|
||||
public void addStringToTable(byte[] string) {
|
||||
this.stringTable[this.tableIndex++] = string;
|
||||
if (this.tableIndex == 511) {
|
||||
this.bitsToGet = 10;
|
||||
} else if (this.tableIndex == 1023) {
|
||||
this.bitsToGet = 11;
|
||||
} else if (this.tableIndex == 2047) {
|
||||
this.bitsToGet = 12;
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] composeString(byte[] oldString, byte newString) {
|
||||
int length = oldString.length;
|
||||
byte[] string = new byte[length + 1];
|
||||
System.arraycopy(oldString, 0, string, 0, length);
|
||||
string[length] = newString;
|
||||
return string;
|
||||
}
|
||||
|
||||
public int getNextCode() {
|
||||
try {
|
||||
this.nextData = this.nextData << 8 | this.data[this.bytePointer++] & 0xFF;
|
||||
this.nextBits += 8;
|
||||
if (this.nextBits < this.bitsToGet) {
|
||||
this.nextData = this.nextData << 8 | this.data[this.bytePointer++] & 0xFF;
|
||||
this.nextBits += 8;
|
||||
}
|
||||
int code = this.nextData >> this.nextBits - this.bitsToGet & this.andTable[this.bitsToGet - 9];
|
||||
this.nextBits -= this.bitsToGet;
|
||||
return code;
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
return 257;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
package com.sun.media.jai.codecimpl;
|
||||
|
||||
import com.sun.media.jai.codec.ForwardSeekableStream;
|
||||
import com.sun.media.jai.codec.ImageCodec;
|
||||
import com.sun.media.jai.codec.ImageDecodeParam;
|
||||
import com.sun.media.jai.codec.ImageDecoder;
|
||||
import com.sun.media.jai.codec.ImageEncodeParam;
|
||||
import com.sun.media.jai.codec.ImageEncoder;
|
||||
import com.sun.media.jai.codec.SeekableStream;
|
||||
import java.awt.image.RenderedImage;
|
||||
import java.awt.image.SampleModel;
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
public final class WBMPCodec extends ImageCodec {
|
||||
public String getFormatName() {
|
||||
return "wbmp";
|
||||
}
|
||||
|
||||
public Class getEncodeParamClass() {
|
||||
return Object.class;
|
||||
}
|
||||
|
||||
public Class getDecodeParamClass() {
|
||||
return Object.class;
|
||||
}
|
||||
|
||||
public boolean canEncodeImage(RenderedImage im, ImageEncodeParam param) {
|
||||
SampleModel sampleModel = im.getSampleModel();
|
||||
int dataType = sampleModel.getTransferType();
|
||||
if (dataType == 4 || dataType == 5 || sampleModel.getNumBands() != 1 || sampleModel.getSampleSize(0) != 1)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
protected ImageEncoder createImageEncoder(OutputStream dst, ImageEncodeParam param) {
|
||||
return new WBMPImageEncoder(dst, null);
|
||||
}
|
||||
|
||||
protected ImageDecoder createImageDecoder(InputStream src, ImageDecodeParam param) {
|
||||
if (!(src instanceof BufferedInputStream))
|
||||
src = new BufferedInputStream(src);
|
||||
return new WBMPImageDecoder(new ForwardSeekableStream(src), null);
|
||||
}
|
||||
|
||||
protected ImageDecoder createImageDecoder(SeekableStream src, ImageDecodeParam param) {
|
||||
return new WBMPImageDecoder(src, null);
|
||||
}
|
||||
|
||||
public int getNumHeaderBytes() {
|
||||
return 3;
|
||||
}
|
||||
|
||||
public boolean isFormatRecognized(byte[] header) {
|
||||
return (header[0] == 0 && header[1] == 0 && ((header[2] & 0x8F) != 0 || (header[2] & Byte.MAX_VALUE) != 0));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
package com.sun.media.jai.codecimpl;
|
||||
|
||||
import com.sun.media.jai.codec.ImageDecodeParam;
|
||||
import com.sun.media.jai.codec.ImageDecoderImpl;
|
||||
import com.sun.media.jai.codec.SeekableStream;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.DataBufferByte;
|
||||
import java.awt.image.MultiPixelPackedSampleModel;
|
||||
import java.awt.image.RenderedImage;
|
||||
import java.awt.image.WritableRaster;
|
||||
import java.io.IOException;
|
||||
|
||||
final class WBMPImageDecoder extends ImageDecoderImpl {
|
||||
public WBMPImageDecoder(SeekableStream input, ImageDecodeParam param) {
|
||||
super(input, param);
|
||||
}
|
||||
|
||||
public RenderedImage decodeAsRenderedImage(int page) throws IOException {
|
||||
if (page != 0)
|
||||
throw new IOException(JaiI18N.getString(JaiI18N.getString("WBMPImageDecoder0")));
|
||||
this.input.read();
|
||||
this.input.read();
|
||||
int value = this.input.read();
|
||||
int width = value & 0x7F;
|
||||
while ((value & 0x80) == 128) {
|
||||
width <<= 7;
|
||||
value = this.input.read();
|
||||
width |= value & 0x7F;
|
||||
}
|
||||
value = this.input.read();
|
||||
int height = value & 0x7F;
|
||||
while ((value & 0x80) == 128) {
|
||||
height <<= 7;
|
||||
value = this.input.read();
|
||||
height |= value & 0x7F;
|
||||
}
|
||||
BufferedImage bi = new BufferedImage(width, height, 12);
|
||||
WritableRaster tile = bi.getWritableTile(0, 0);
|
||||
MultiPixelPackedSampleModel sm = (MultiPixelPackedSampleModel)bi.getSampleModel();
|
||||
this.input.readFully(((DataBufferByte)tile.getDataBuffer()).getData(), 0, height * sm.getScanlineStride());
|
||||
return bi;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
package com.sun.media.jai.codecimpl;
|
||||
|
||||
import com.sun.media.jai.codec.ImageEncodeParam;
|
||||
import com.sun.media.jai.codec.ImageEncoderImpl;
|
||||
import java.awt.Point;
|
||||
import java.awt.image.DataBufferByte;
|
||||
import java.awt.image.IndexColorModel;
|
||||
import java.awt.image.MultiPixelPackedSampleModel;
|
||||
import java.awt.image.Raster;
|
||||
import java.awt.image.RenderedImage;
|
||||
import java.awt.image.SampleModel;
|
||||
import java.awt.image.WritableRaster;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
final class WBMPImageEncoder extends ImageEncoderImpl {
|
||||
private static int getNumBits(int intValue) {
|
||||
int numBits = 32;
|
||||
int mask = Integer.MIN_VALUE;
|
||||
while (mask != 0 && (intValue & mask) == 0) {
|
||||
numBits--;
|
||||
mask >>>= 1;
|
||||
}
|
||||
return numBits;
|
||||
}
|
||||
|
||||
private static byte[] intToMultiByte(int intValue) {
|
||||
int numBitsLeft = getNumBits(intValue);
|
||||
byte[] multiBytes = new byte[(numBitsLeft + 6) / 7];
|
||||
int maxIndex = multiBytes.length - 1;
|
||||
for (int b = 0; b <= maxIndex; b++) {
|
||||
multiBytes[b] = (byte)(intValue >>> (maxIndex - b) * 7 & 0x7F);
|
||||
if (b != maxIndex)
|
||||
multiBytes[b] = (byte)(multiBytes[b] | Byte.MIN_VALUE);
|
||||
}
|
||||
return multiBytes;
|
||||
}
|
||||
|
||||
public WBMPImageEncoder(OutputStream output, ImageEncodeParam param) {
|
||||
super(output, param);
|
||||
}
|
||||
|
||||
public void encode(RenderedImage im) throws IOException {
|
||||
SampleModel sm = im.getSampleModel();
|
||||
int dataType = sm.getTransferType();
|
||||
if (dataType == 4 || dataType == 5)
|
||||
throw new IllegalArgumentException(JaiI18N.getString("WBMPImageEncoder0"));
|
||||
if (sm.getNumBands() != 1)
|
||||
throw new IllegalArgumentException(JaiI18N.getString("WBMPImageEncoder1"));
|
||||
if (sm.getSampleSize(0) != 1)
|
||||
throw new IllegalArgumentException(JaiI18N.getString("WBMPImageEncoder2"));
|
||||
int width = im.getWidth();
|
||||
int height = im.getHeight();
|
||||
this.output.write(0);
|
||||
this.output.write(0);
|
||||
this.output.write(intToMultiByte(width));
|
||||
this.output.write(intToMultiByte(height));
|
||||
Raster tile = null;
|
||||
if (sm.getDataType() != 0 || !(sm instanceof MultiPixelPackedSampleModel) || ((MultiPixelPackedSampleModel)sm).getDataBitOffset() != 0) {
|
||||
MultiPixelPackedSampleModel mppsm = new MultiPixelPackedSampleModel(0, width, height, 1, (width + 7) / 8, 0);
|
||||
WritableRaster raster = Raster.createWritableRaster(mppsm, new Point(im.getMinX(), im.getMinY()));
|
||||
raster.setRect(im.getData());
|
||||
tile = raster;
|
||||
} else if (im.getNumXTiles() == 1 && im.getNumYTiles() == 1) {
|
||||
tile = im.getTile(im.getMinTileX(), im.getMinTileY());
|
||||
} else {
|
||||
tile = im.getData();
|
||||
}
|
||||
boolean isWhiteZero = false;
|
||||
if (im.getColorModel() instanceof IndexColorModel) {
|
||||
IndexColorModel icm = (IndexColorModel)im.getColorModel();
|
||||
isWhiteZero = (icm.getRed(0) + icm.getGreen(0) + icm.getBlue(0) > icm.getRed(1) + icm.getGreen(1) + icm.getBlue(1));
|
||||
}
|
||||
int lineStride = ((MultiPixelPackedSampleModel)sm).getScanlineStride();
|
||||
int bytesPerRow = (width + 7) / 8;
|
||||
byte[] bdata = ((DataBufferByte)tile.getDataBuffer()).getData();
|
||||
if (!isWhiteZero && lineStride == bytesPerRow) {
|
||||
this.output.write(bdata, 0, height * bytesPerRow);
|
||||
} else {
|
||||
int offset = 0;
|
||||
if (!isWhiteZero) {
|
||||
for (int row = 0; row < height; row++) {
|
||||
this.output.write(bdata, offset, bytesPerRow);
|
||||
offset += lineStride;
|
||||
}
|
||||
} else {
|
||||
byte[] inverted = new byte[bytesPerRow];
|
||||
for (int row = 0; row < height; row++) {
|
||||
for (int col = 0; col < bytesPerRow; col++)
|
||||
inverted[col] = (byte)(bdata[col + offset] ^ 0xFFFFFFFF);
|
||||
this.output.write(inverted, 0, bytesPerRow);
|
||||
offset += lineStride;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,538 @@
|
|||
package com.sun.media.jai.codecimpl.fpx;
|
||||
|
||||
import com.sun.image.codec.jpeg.JPEGCodec;
|
||||
import com.sun.image.codec.jpeg.JPEGDecodeParam;
|
||||
import com.sun.image.codec.jpeg.JPEGImageDecoder;
|
||||
import com.sun.media.jai.codec.FPXDecodeParam;
|
||||
import com.sun.media.jai.codec.ImageCodec;
|
||||
import com.sun.media.jai.codec.SeekableStream;
|
||||
import com.sun.media.jai.codecimpl.ImagingListenerProxy;
|
||||
import com.sun.media.jai.codecimpl.SimpleRenderedImage;
|
||||
import com.sun.media.jai.codecimpl.util.RasterFactory;
|
||||
import java.awt.Point;
|
||||
import java.awt.color.ColorSpace;
|
||||
import java.awt.image.ComponentColorModel;
|
||||
import java.awt.image.DataBufferByte;
|
||||
import java.awt.image.Raster;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Hashtable;
|
||||
|
||||
public class FPXImage extends SimpleRenderedImage {
|
||||
private static final int SUBIMAGE_COLOR_SPACE_COLORLESS = 0;
|
||||
|
||||
private static final int SUBIMAGE_COLOR_SPACE_MONOCHROME = 0;
|
||||
|
||||
private static final int SUBIMAGE_COLOR_SPACE_PHOTOYCC = 0;
|
||||
|
||||
private static final int SUBIMAGE_COLOR_SPACE_NIFRGB = 0;
|
||||
|
||||
private static final String[] COLORSPACE_NAME = new String[] { "Colorless", "Monochrome", "PhotoYCC", "NIF RGB" };
|
||||
|
||||
StructuredStorage storage;
|
||||
|
||||
int numResolutions;
|
||||
|
||||
int highestResWidth;
|
||||
|
||||
int highestResHeight;
|
||||
|
||||
float defaultDisplayHeight;
|
||||
|
||||
float defaultDisplayWidth;
|
||||
|
||||
int displayHeightWidthUnits;
|
||||
|
||||
boolean[] subimageValid;
|
||||
|
||||
int[] subimageWidth;
|
||||
|
||||
int[] subimageHeight;
|
||||
|
||||
int[][] subimageColor;
|
||||
|
||||
int[] decimationMethod;
|
||||
|
||||
float[] decimationPrefilterWidth;
|
||||
|
||||
int highestResolution = -1;
|
||||
|
||||
int maxJPEGTableIndex;
|
||||
|
||||
byte[][] JPEGTable;
|
||||
|
||||
int numChannels;
|
||||
|
||||
int tileHeaderTableOffset;
|
||||
|
||||
int tileHeaderEntryLength;
|
||||
|
||||
SeekableStream subimageHeaderStream;
|
||||
|
||||
SeekableStream subimageDataStream;
|
||||
|
||||
int resolution;
|
||||
|
||||
int tilesAcross;
|
||||
|
||||
int[] bandOffsets = new int[] { 0, 1, 2 };
|
||||
|
||||
private static final int[] RGBBits8 = new int[] { 8, 8, 8 };
|
||||
|
||||
private static final ComponentColorModel colorModelRGB8 = new ComponentColorModel(ColorSpace.getInstance(1004), RGBBits8, false, false, 1, 0);
|
||||
|
||||
public FPXImage(SeekableStream stream, FPXDecodeParam param) throws IOException {
|
||||
this.storage = new StructuredStorage(stream);
|
||||
readImageContents();
|
||||
if (param == null)
|
||||
param = new FPXDecodeParam();
|
||||
this.resolution = param.getResolution();
|
||||
readResolution();
|
||||
this.bandOffsets = new int[this.numChannels];
|
||||
for (int i = 0; i < this.numChannels; i++)
|
||||
this.bandOffsets[i] = i;
|
||||
this.minX = 0;
|
||||
this.minY = 0;
|
||||
this.sampleModel = RasterFactory.createPixelInterleavedSampleModel(0, this.tileWidth, this.tileHeight, this.numChannels, this.numChannels * this.tileWidth, this.bandOffsets);
|
||||
this.colorModel = ImageCodec.createComponentColorModel(this.sampleModel);
|
||||
}
|
||||
|
||||
private void readImageContents() throws IOException {
|
||||
this.storage.changeDirectoryToRoot();
|
||||
this.storage.changeDirectory("Data Object Store 000001");
|
||||
SeekableStream imageContents = this.storage.getStream("\005Image Contents");
|
||||
PropertySet icps = new PropertySet(imageContents);
|
||||
this.numResolutions = (int)icps.getUI4(16777216);
|
||||
this.highestResWidth = (int)icps.getUI4(16777218);
|
||||
this.highestResHeight = (int)icps.getUI4(16777219);
|
||||
this.displayHeightWidthUnits = (int)icps.getUI4(16777222, 0L);
|
||||
this.subimageValid = new boolean[this.numResolutions];
|
||||
this.subimageWidth = new int[this.numResolutions];
|
||||
this.subimageHeight = new int[this.numResolutions];
|
||||
this.subimageColor = new int[this.numResolutions][];
|
||||
this.decimationMethod = new int[this.numResolutions];
|
||||
this.decimationPrefilterWidth = new float[this.numResolutions];
|
||||
for (int j = 0; j < this.numResolutions; j++) {
|
||||
int index = j << 16;
|
||||
if (!icps.hasProperty(0x2000000 | index))
|
||||
break;
|
||||
this.highestResolution = j;
|
||||
this.subimageValid[j] = true;
|
||||
this.subimageWidth[j] = (int)icps.getUI4(0x2000000 | index);
|
||||
this.subimageHeight[j] = (int)icps.getUI4(0x2000001 | index);
|
||||
byte[] subimageColorBlob = icps.getBlob(0x2000002 | index);
|
||||
this.decimationMethod[j] = icps.getI4(0x2000004 | index);
|
||||
int numSubImages = FPXUtils.getIntLE(subimageColorBlob, 0);
|
||||
int numChannels = FPXUtils.getIntLE(subimageColorBlob, 4);
|
||||
this.subimageColor[j] = new int[numChannels];
|
||||
for (int c = 0; c < numChannels; c++) {
|
||||
int color = FPXUtils.getIntLE(subimageColorBlob, 8 + 4 * c);
|
||||
this.subimageColor[j][c] = color & Integer.MAX_VALUE;
|
||||
}
|
||||
}
|
||||
this.maxJPEGTableIndex = (int)icps.getUI4(50331650, -1L);
|
||||
this.JPEGTable = new byte[this.maxJPEGTableIndex + 1][];
|
||||
for (int i = 0; i <= this.maxJPEGTableIndex; i++) {
|
||||
int index = i << 16;
|
||||
if (icps.hasProperty(0x3000001 | index)) {
|
||||
this.JPEGTable[i] = icps.getBlob(0x3000001 | index);
|
||||
} else {
|
||||
this.JPEGTable[i] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void readResolution() throws IOException {
|
||||
if (this.resolution == -1)
|
||||
this.resolution = this.highestResolution;
|
||||
this.storage.changeDirectoryToRoot();
|
||||
this.storage.changeDirectory("Data Object Store 000001");
|
||||
this.storage.changeDirectory("Resolution 000" + this.resolution);
|
||||
this.subimageHeaderStream = this.storage.getStream("Subimage 0000 Header");
|
||||
this.subimageHeaderStream.skip(28L);
|
||||
int headerLength = this.subimageHeaderStream.readIntLE();
|
||||
this.width = this.subimageHeaderStream.readIntLE();
|
||||
this.height = this.subimageHeaderStream.readIntLE();
|
||||
int numTiles = this.subimageHeaderStream.readIntLE();
|
||||
this.tileWidth = this.subimageHeaderStream.readIntLE();
|
||||
this.tileHeight = this.subimageHeaderStream.readIntLE();
|
||||
this.numChannels = this.subimageHeaderStream.readIntLE();
|
||||
this.tileHeaderTableOffset = this.subimageHeaderStream.readIntLE() + 28;
|
||||
this.tileHeaderEntryLength = this.subimageHeaderStream.readIntLE();
|
||||
this.subimageDataStream = this.storage.getStream("Subimage 0000 Data");
|
||||
this.tilesAcross = (this.width + this.tileWidth - 1) / this.tileWidth;
|
||||
}
|
||||
|
||||
private int getTileOffset(int tileIndex) throws IOException {
|
||||
this.subimageHeaderStream.seek((long)(this.tileHeaderTableOffset + 16 * tileIndex));
|
||||
return this.subimageHeaderStream.readIntLE() + 28;
|
||||
}
|
||||
|
||||
private int getTileSize(int tileIndex) throws IOException {
|
||||
this.subimageHeaderStream.seek((long)(this.tileHeaderTableOffset + 16 * tileIndex + 4));
|
||||
return this.subimageHeaderStream.readIntLE();
|
||||
}
|
||||
|
||||
private int getCompressionType(int tileIndex) throws IOException {
|
||||
this.subimageHeaderStream.seek((long)(this.tileHeaderTableOffset + 16 * tileIndex + 8));
|
||||
return this.subimageHeaderStream.readIntLE();
|
||||
}
|
||||
|
||||
private int getCompressionSubtype(int tileIndex) throws IOException {
|
||||
this.subimageHeaderStream.seek((long)(this.tileHeaderTableOffset + 16 * tileIndex + 12));
|
||||
return this.subimageHeaderStream.readIntLE();
|
||||
}
|
||||
|
||||
private static final byte[] PhotoYCCToRGBLUT = new byte[] {
|
||||
0, 1, 1, 2, 2, 3, 4, 5, 6, 7,
|
||||
8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
|
||||
18, 19, 20, 22, 23, 24, 25, 26, 28, 29,
|
||||
30, 31, 33, 34, 35, 36, 38, 39, 40, 41,
|
||||
43, 44, 45, 47, 48, 49, 51, 52, 53, 55,
|
||||
56, 57, 59, 60, 61, 63, 64, 65, 67, 68,
|
||||
70, 71, 72, 74, 75, 76, 78, 79, 81, 82,
|
||||
83, 85, 86, 88, 89, 91, 92, 93, 95, 96,
|
||||
98, 99, 101, 102, 103, 105, 106, 108, 109, 111,
|
||||
112, 113, 115, 116, 118, 119, 121, 122, 123, 125,
|
||||
126, Byte.MIN_VALUE, -127, -126, -124, -123, -122, -120, -119, -118,
|
||||
-116, -115, -114, -112, -111, -110, -108, -107, -106, -104,
|
||||
-103, -102, -101, -99, -98, -97, -96, -94, -93, -92,
|
||||
-91, -90, -88, -87, -86, -85, -84, -82, -81, -80,
|
||||
-79, -78, -77, -76, -74, -73, -72, -71, -70, -69,
|
||||
-68, -67, -66, -65, -64, -62, -61, -60, -59, -58,
|
||||
-57, -56, -55, -54, -53, -52, -52, -51, -50, -49,
|
||||
-48, -47, -46, -45, -44, -43, -43, -42, -41, -40,
|
||||
-39, -39, -38, -37, -36, -35, -35, -34, -33, -33,
|
||||
-32, -31, -31, -30, -29, -29, -28, -27, -27, -26,
|
||||
-26, -25, -25, -24, -23, -23, -22, -22, -21, -21,
|
||||
-20, -20, -20, -19, -19, -18, -18, -18, -17, -17,
|
||||
-16, -16, -16, -15, -15, -15, -14, -14, -14, -14,
|
||||
-13, -13, -13, -12, -12, -12, -12, -11, -11, -11,
|
||||
-11, -11, -10, -10, -10, -10, -10, -9, -9, -9,
|
||||
-9, -9, -9, -8, -8, -8, -8, -8, -8, -7,
|
||||
-7, -7, -7, -7, -7, -7, -7, -7, -6, -6,
|
||||
-6, -6, -6, -6, -6, -6, -6, -6, -5, -5,
|
||||
-5, -5, -5, -5, -5, -5, -5, -5, -5, -5,
|
||||
-5, -5, -4, -4, -4, -4, -4, -4, -4, -4,
|
||||
-4, -4, -4, -4, -4, -4, -4, -4, -4, -3,
|
||||
-3, -3, -3, -3, -3, -3, -3, -3, -3, -3,
|
||||
-3, -3, -3, -3, -3, -3, -3, -2, -2, -2,
|
||||
-2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
|
||||
-2, -2, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1 };
|
||||
|
||||
private final byte PhotoYCCToNIFRed(float scaledY, float Cb, float Cr) {
|
||||
float red = scaledY + 1.8215F * Cr - 249.55F;
|
||||
if (red < 0.0F)
|
||||
return 0;
|
||||
if (red > 360.0F)
|
||||
return -1;
|
||||
byte r = PhotoYCCToRGBLUT[(int)red];
|
||||
return r;
|
||||
}
|
||||
|
||||
private final byte PhotoYCCToNIFGreen(float scaledY, float Cb, float Cr) {
|
||||
float green = scaledY - 0.43031F * Cb - 0.9271F * Cr + 194.14F;
|
||||
if (green < 0.0F)
|
||||
return 0;
|
||||
if (green > 360.0F)
|
||||
return -1;
|
||||
byte g = PhotoYCCToRGBLUT[(int)green];
|
||||
return g;
|
||||
}
|
||||
|
||||
private final byte PhotoYCCToNIFBlue(float scaledY, float Cb, float Cr) {
|
||||
float blue = scaledY + 2.2179F * Cb - 345.99F;
|
||||
if (blue < 0.0F)
|
||||
return 0;
|
||||
if (blue > 360.0F)
|
||||
return -1;
|
||||
byte b = PhotoYCCToRGBLUT[(int)blue];
|
||||
return b;
|
||||
}
|
||||
|
||||
private final byte YCCToNIFRed(float Y, float Cb, float Cr) {
|
||||
float red = Y + 1.402F * Cr - 178.75499F;
|
||||
if (red < 0.0F)
|
||||
return 0;
|
||||
if (red > 255.0F)
|
||||
return -1;
|
||||
return (byte)(int)red;
|
||||
}
|
||||
|
||||
private final byte YCCToNIFGreen(float Y, float Cb, float Cr) {
|
||||
float green = Y - 0.34414F * Cb - 0.71414F * Cr + 134.9307F;
|
||||
if (green < 0.0F)
|
||||
return 0;
|
||||
if (green > 255.0F)
|
||||
return -1;
|
||||
return (byte)(int)green;
|
||||
}
|
||||
|
||||
private final byte YCCToNIFBlue(float Y, float Cb, float Cr) {
|
||||
float blue = Y + 1.772F * Cb - 225.93F;
|
||||
if (blue < 0.0F)
|
||||
return 0;
|
||||
if (blue > 255.0F)
|
||||
return -1;
|
||||
return (byte)(int)blue;
|
||||
}
|
||||
|
||||
private Raster getUncompressedTile(int tileX, int tileY) throws IOException {
|
||||
int tx = tileXToX(tileX);
|
||||
int ty = tileYToY(tileY);
|
||||
Raster ras = RasterFactory.createInterleavedRaster(0, this.tileWidth, this.tileHeight, this.numChannels * this.tileWidth, this.numChannels, this.bandOffsets, new Point(tx, ty));
|
||||
DataBufferByte dataBuffer = (DataBufferByte)ras.getDataBuffer();
|
||||
byte[] data = dataBuffer.getData();
|
||||
int tileIndex = tileY * this.tilesAcross + tileX;
|
||||
this.subimageDataStream.seek((long)getTileOffset(tileIndex));
|
||||
this.subimageDataStream.readFully(data, 0, this.numChannels * this.tileWidth * this.tileHeight);
|
||||
if (this.subimageColor[this.resolution][0] >> 16 == 2) {
|
||||
int size = this.tileWidth * this.tileHeight;
|
||||
for (int i = 0; i < size; i++) {
|
||||
float Y = (float)(data[3 * i] & 0xFF);
|
||||
float Cb = (float)(data[3 * i + 1] & 0xFF);
|
||||
float Cr = (float)(data[3 * i + 2] & 0xFF);
|
||||
float scaledY = Y * 1.3584F;
|
||||
byte red = PhotoYCCToNIFRed(scaledY, Cb, Cr);
|
||||
byte green = PhotoYCCToNIFGreen(scaledY, Cb, Cr);
|
||||
byte blue = PhotoYCCToNIFBlue(scaledY, Cb, Cr);
|
||||
data[3 * i] = red;
|
||||
data[3 * i + 1] = green;
|
||||
data[3 * i + 2] = blue;
|
||||
}
|
||||
}
|
||||
return ras;
|
||||
}
|
||||
|
||||
private Raster getSingleColorCompressedTile(int tileX, int tileY) throws IOException {
|
||||
byte red, green, blue;
|
||||
int tx = tileXToX(tileX);
|
||||
int ty = tileYToY(tileY);
|
||||
Raster ras = RasterFactory.createInterleavedRaster(0, this.tileWidth, this.tileHeight, this.numChannels * this.tileWidth, this.numChannels, this.bandOffsets, new Point(tx, ty));
|
||||
int subimageColorType = this.subimageColor[this.resolution][0] >> 16;
|
||||
DataBufferByte dataBuffer = (DataBufferByte)ras.getDataBuffer();
|
||||
byte[] data = dataBuffer.getData();
|
||||
int tileIndex = tileY * this.tilesAcross + tileX;
|
||||
int color = getCompressionSubtype(tileIndex);
|
||||
byte c0 = (byte)(color >> 0 & 0xFF);
|
||||
byte c1 = (byte)(color >> 8 & 0xFF);
|
||||
byte c2 = (byte)(color >> 16 & 0xFF);
|
||||
byte alpha = (byte)(color >> 24 & 0xFF);
|
||||
if (this.subimageColor[this.resolution][0] >> 16 == 2) {
|
||||
float Y = (float)(c0 & 0xFF);
|
||||
float Cb = (float)(c1 & 0xFF);
|
||||
float Cr = (float)(c2 & 0xFF);
|
||||
float scaledY = Y * 1.3584F;
|
||||
red = PhotoYCCToNIFRed(scaledY, Cb, Cr);
|
||||
green = PhotoYCCToNIFGreen(scaledY, Cb, Cr);
|
||||
blue = PhotoYCCToNIFBlue(scaledY, Cb, Cr);
|
||||
} else {
|
||||
red = c0;
|
||||
green = c1;
|
||||
blue = c2;
|
||||
}
|
||||
int index = 0;
|
||||
int pixels = this.tileWidth * this.tileHeight;
|
||||
if (this.numChannels != 1 &&
|
||||
this.numChannels != 2)
|
||||
if (this.numChannels == 3) {
|
||||
for (int i = 0; i < pixels; i++) {
|
||||
data[index + 0] = red;
|
||||
data[index + 1] = green;
|
||||
data[index + 2] = blue;
|
||||
index += 3;
|
||||
}
|
||||
} else if (this.numChannels == 4) {
|
||||
for (int i = 0; i < pixels; i++) {
|
||||
data[index + 0] = red;
|
||||
data[index + 1] = green;
|
||||
data[index + 2] = blue;
|
||||
data[index + 3] = alpha;
|
||||
index += 4;
|
||||
}
|
||||
}
|
||||
return ras;
|
||||
}
|
||||
|
||||
private Raster getJPEGCompressedTile(int tileX, int tileY) throws IOException {
|
||||
JPEGImageDecoder dec;
|
||||
int tileIndex = tileY * this.tilesAcross + tileX;
|
||||
int tx = tileXToX(tileX);
|
||||
int ty = tileYToY(tileY);
|
||||
int subtype = getCompressionSubtype(tileIndex);
|
||||
int interleave = subtype >> 0 & 0xFF;
|
||||
int chroma = subtype >> 8 & 0xFF;
|
||||
int conversion = subtype >> 16 & 0xFF;
|
||||
int table = subtype >> 24 & 0xFF;
|
||||
JPEGDecodeParam param = null;
|
||||
if (table != 0) {
|
||||
InputStream tableStream = new ByteArrayInputStream(this.JPEGTable[table]);
|
||||
dec = JPEGCodec.createJPEGDecoder(tableStream);
|
||||
Raster junk = dec.decodeAsRaster();
|
||||
param = dec.getJPEGDecodeParam();
|
||||
}
|
||||
this.subimageDataStream.seek((long)getTileOffset(tileIndex));
|
||||
if (param != null) {
|
||||
dec = JPEGCodec.createJPEGDecoder(this.subimageDataStream, param);
|
||||
} else {
|
||||
dec = JPEGCodec.createJPEGDecoder(this.subimageDataStream);
|
||||
}
|
||||
Raster ras = dec.decodeAsRaster().createTranslatedChild(tx, ty);
|
||||
DataBufferByte dataBuffer = (DataBufferByte)ras.getDataBuffer();
|
||||
byte[] data = dataBuffer.getData();
|
||||
int subimageColorType = this.subimageColor[this.resolution][0] >> 16;
|
||||
int size = this.tileWidth * this.tileHeight;
|
||||
if (conversion == 0 && subimageColorType == 2) {
|
||||
int offset = 0;
|
||||
for (int i = 0; i < size; i++) {
|
||||
float Y = (float)(data[offset] & 0xFF);
|
||||
float Cb = (float)(data[offset + 1] & 0xFF);
|
||||
float Cr = (float)(data[offset + 2] & 0xFF);
|
||||
float scaledY = Y * 1.3584F;
|
||||
byte red = PhotoYCCToNIFRed(scaledY, Cb, Cr);
|
||||
byte green = PhotoYCCToNIFGreen(scaledY, Cb, Cr);
|
||||
byte blue = PhotoYCCToNIFBlue(scaledY, Cb, Cr);
|
||||
data[offset] = red;
|
||||
data[offset + 1] = green;
|
||||
data[offset + 2] = blue;
|
||||
offset += this.numChannels;
|
||||
}
|
||||
} else if (conversion == 1 && subimageColorType == 3) {
|
||||
int offset = 0;
|
||||
for (int i = 0; i < size; i++) {
|
||||
float Y = (float)(data[offset] & 0xFF);
|
||||
float Cb = (float)(data[offset + 1] & 0xFF);
|
||||
float Cr = (float)(data[offset + 2] & 0xFF);
|
||||
byte red = YCCToNIFRed(Y, Cb, Cr);
|
||||
byte green = YCCToNIFGreen(Y, Cb, Cr);
|
||||
byte blue = YCCToNIFBlue(Y, Cb, Cr);
|
||||
data[offset] = red;
|
||||
data[offset + 1] = green;
|
||||
data[offset + 2] = blue;
|
||||
offset += this.numChannels;
|
||||
}
|
||||
}
|
||||
if (conversion == 1 && subimageColorType == 3 && this.numChannels == 4) {
|
||||
int offset = 0;
|
||||
for (int i = 0; i < size; i++) {
|
||||
data[offset + 0] = (byte)(255 - data[offset + 0]);
|
||||
data[offset + 1] = (byte)(255 - data[offset + 1]);
|
||||
data[offset + 2] = (byte)(255 - data[offset + 2]);
|
||||
offset += 4;
|
||||
}
|
||||
}
|
||||
return ras;
|
||||
}
|
||||
|
||||
public synchronized Raster getTile(int tileX, int tileY) {
|
||||
int tileIndex = tileY * this.tilesAcross + tileX;
|
||||
try {
|
||||
int ctype = getCompressionType(tileIndex);
|
||||
if (ctype == 0)
|
||||
return getUncompressedTile(tileX, tileY);
|
||||
if (ctype == 1)
|
||||
return getSingleColorCompressedTile(tileX, tileY);
|
||||
if (ctype == 2)
|
||||
return getJPEGCompressedTile(tileX, tileY);
|
||||
return null;
|
||||
} catch (IOException e) {
|
||||
ImagingListenerProxy.errorOccurred(JaiI18N.getString("FPXImage0"), e, ImageCodec.class, false);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Hashtable properties = null;
|
||||
|
||||
private void addLPSTRProperty(String name, PropertySet ps, int id) {
|
||||
String s = ps.getLPSTR(id);
|
||||
if (s != null)
|
||||
this.properties.put(name.toLowerCase(), s);
|
||||
}
|
||||
|
||||
private void addLPWSTRProperty(String name, PropertySet ps, int id) {
|
||||
String s = ps.getLPWSTR(id);
|
||||
if (s != null)
|
||||
this.properties.put(name.toLowerCase(), s);
|
||||
}
|
||||
|
||||
private void addUI4Property(String name, PropertySet ps, int id) {
|
||||
if (ps.hasProperty(id)) {
|
||||
long i = ps.getUI4(id);
|
||||
this.properties.put(name.toLowerCase(), new Integer((int)i));
|
||||
}
|
||||
}
|
||||
|
||||
private void getSummaryInformation() {
|
||||
SeekableStream summaryInformation = null;
|
||||
PropertySet sips = null;
|
||||
try {
|
||||
this.storage.changeDirectoryToRoot();
|
||||
summaryInformation = this.storage.getStream("\005SummaryInformation");
|
||||
sips = new PropertySet(summaryInformation);
|
||||
} catch (IOException e) {
|
||||
ImagingListenerProxy.errorOccurred(JaiI18N.getString("FPXImage1"), e, ImageCodec.class, false);
|
||||
return;
|
||||
}
|
||||
addLPSTRProperty("title", sips, 2);
|
||||
addLPSTRProperty("subject", sips, 3);
|
||||
addLPSTRProperty("author", sips, 4);
|
||||
addLPSTRProperty("keywords", sips, 5);
|
||||
addLPSTRProperty("comments", sips, 6);
|
||||
addLPSTRProperty("template", sips, 7);
|
||||
addLPSTRProperty("last saved by", sips, 8);
|
||||
addLPSTRProperty("revision number", sips, 9);
|
||||
}
|
||||
|
||||
private void getImageInfo() {
|
||||
SeekableStream imageInfo = null;
|
||||
PropertySet iips = null;
|
||||
try {
|
||||
this.storage.changeDirectoryToRoot();
|
||||
imageInfo = this.storage.getStream("\005Image Info");
|
||||
if (imageInfo == null)
|
||||
return;
|
||||
iips = new PropertySet(imageInfo);
|
||||
} catch (IOException e) {
|
||||
ImagingListenerProxy.errorOccurred(JaiI18N.getString("FPXImage2"), e, ImageCodec.class, false);
|
||||
return;
|
||||
}
|
||||
addUI4Property("file source", iips, 553648128);
|
||||
addUI4Property("scene type", iips, 553648129);
|
||||
addLPWSTRProperty("software name/manufacturer/release", iips, 553648131);
|
||||
addLPWSTRProperty("user defined id", iips, 553648132);
|
||||
addLPWSTRProperty("copyright message", iips, 570425344);
|
||||
addLPWSTRProperty("legal broker for the original image", iips, 570425345);
|
||||
addLPWSTRProperty("legal broker for the digital image", iips, 570425346);
|
||||
addLPWSTRProperty("authorship", iips, 570425347);
|
||||
addLPWSTRProperty("intellectual property notes", iips, 570425348);
|
||||
}
|
||||
|
||||
private synchronized void getProperties() {
|
||||
if (this.properties != null)
|
||||
return;
|
||||
this.properties = new Hashtable();
|
||||
getSummaryInformation();
|
||||
getImageInfo();
|
||||
this.properties.put("max_resolution", new Integer(this.highestResolution));
|
||||
}
|
||||
|
||||
public String[] getPropertyNames() {
|
||||
getProperties();
|
||||
int len = this.properties.size();
|
||||
String[] names = new String[len];
|
||||
Enumeration enumeration = this.properties.keys();
|
||||
int count = 0;
|
||||
while (enumeration.hasMoreElements())
|
||||
names[count++] = (String)enumeration.nextElement();
|
||||
return names;
|
||||
}
|
||||
|
||||
public Object getProperty(String name) {
|
||||
getProperties();
|
||||
return this.properties.get(name.toLowerCase());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,103 @@
|
|||
package com.sun.media.jai.codecimpl.fpx;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
public class FPXUtils {
|
||||
public static final short getShortLE(byte[] data, int offset) {
|
||||
int b0 = data[offset] & 0xFF;
|
||||
int b1 = data[offset + 1] & 0xFF;
|
||||
return (short)(b1 << 8 | b0);
|
||||
}
|
||||
|
||||
public static final int getUnsignedShortLE(byte[] data, int offset) {
|
||||
int b0 = data[offset] & 0xFF;
|
||||
int b1 = data[offset + 1] & 0xFF;
|
||||
return b1 << 8 | b0;
|
||||
}
|
||||
|
||||
public static final int getIntLE(byte[] data, int offset) {
|
||||
int b0 = data[offset] & 0xFF;
|
||||
int b1 = data[offset + 1] & 0xFF;
|
||||
int b2 = data[offset + 2] & 0xFF;
|
||||
int b3 = data[offset + 3] & 0xFF;
|
||||
return b3 << 24 | b2 << 16 | b1 << 8 | b0;
|
||||
}
|
||||
|
||||
public static final long getUnsignedIntLE(byte[] data, int offset) {
|
||||
long b0 = (long)(data[offset] & 0xFF);
|
||||
long b1 = (long)(data[offset + 1] & 0xFF);
|
||||
long b2 = (long)(data[offset + 2] & 0xFF);
|
||||
long b3 = (long)(data[offset + 3] & 0xFF);
|
||||
return b3 << 24L | b2 << 16L | b1 << 8L | b0;
|
||||
}
|
||||
|
||||
public static final String getString(byte[] data, int offset, int length) {
|
||||
if (length == 0)
|
||||
return "<none>";
|
||||
length = length / 2 - 1;
|
||||
StringBuffer b = new StringBuffer(length);
|
||||
for (int i = 0; i < length; i++) {
|
||||
int c = getUnsignedShortLE(data, offset);
|
||||
b.append((char)c);
|
||||
offset += 2;
|
||||
}
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
private static void printDecimal(int i) {
|
||||
DecimalFormat d = new DecimalFormat("00000");
|
||||
System.out.print(d.format((long)i));
|
||||
}
|
||||
|
||||
private static void printHex(byte b) {
|
||||
int i = b & 0xFF;
|
||||
int hi = i / 16;
|
||||
int lo = i % 16;
|
||||
if (hi < 10) {
|
||||
System.out.print((char)(48 + hi));
|
||||
} else {
|
||||
System.out.print((char)(97 + hi - 10));
|
||||
}
|
||||
if (lo < 10) {
|
||||
System.out.print((char)(48 + lo));
|
||||
} else {
|
||||
System.out.print((char)(97 + lo - 10));
|
||||
}
|
||||
}
|
||||
|
||||
private static void printChar(byte b) {
|
||||
char c = (char)(b & 0xFF);
|
||||
if (c >= '!' && c <= '~') {
|
||||
System.out.print(' ');
|
||||
System.out.print(c);
|
||||
} else if (c == '\000') {
|
||||
System.out.print("^@");
|
||||
} else if (c < ' ') {
|
||||
System.out.print('^');
|
||||
System.out.print((char)(65 + c - 1));
|
||||
} else if (c == ' ') {
|
||||
System.out.print("__");
|
||||
} else {
|
||||
System.out.print("??");
|
||||
}
|
||||
}
|
||||
|
||||
public static void dumpBuffer(byte[] buf, int offset, int length, int printOffset) {
|
||||
int lines = length / 8;
|
||||
for (int j = 0; j < lines; j++) {
|
||||
printDecimal(printOffset);
|
||||
System.out.print(": ");
|
||||
for (int k = 0; k < 8; k++) {
|
||||
printHex(buf[offset + k]);
|
||||
System.out.print(" ");
|
||||
}
|
||||
for (int i = 0; i < 8; i++) {
|
||||
printChar(buf[offset + i]);
|
||||
System.out.print(" ");
|
||||
}
|
||||
offset += 8;
|
||||
printOffset += 8;
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
package com.sun.media.jai.codecimpl.fpx;
|
||||
|
||||
import com.sun.media.jai.codecimpl.util.PropertyUtil;
|
||||
|
||||
class JaiI18N {
|
||||
static String packageName = "com.sun.media.jai.codecimpl.fpx";
|
||||
|
||||
public static String getString(String key) {
|
||||
return PropertyUtil.getString(packageName, key);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
package com.sun.media.jai.codecimpl.fpx;
|
||||
|
||||
class Property {
|
||||
private int type;
|
||||
|
||||
private int offset;
|
||||
|
||||
public Property(int type, int offset) {
|
||||
this.type = type;
|
||||
this.offset = offset;
|
||||
}
|
||||
|
||||
public int getType() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
public int getOffset() {
|
||||
return this.offset;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,246 @@
|
|||
package com.sun.media.jai.codecimpl.fpx;
|
||||
|
||||
import com.sun.media.jai.codec.SeekableStream;
|
||||
import com.sun.media.jai.codecimpl.ImagingListenerProxy;
|
||||
import java.io.IOException;
|
||||
import java.util.Date;
|
||||
import java.util.Hashtable;
|
||||
|
||||
class PropertySet {
|
||||
private static final int TYPE_VT_EMPTY = -1;
|
||||
|
||||
private static final int TYPE_VT_NULL = -1;
|
||||
|
||||
private static final int TYPE_VT_I2 = 2;
|
||||
|
||||
private static final int TYPE_VT_I4 = 3;
|
||||
|
||||
private static final int TYPE_VT_R4 = -1;
|
||||
|
||||
private static final int TYPE_VT_R8 = -1;
|
||||
|
||||
private static final int TYPE_VT_CY = -1;
|
||||
|
||||
private static final int TYPE_VT_DATE = -1;
|
||||
|
||||
private static final int TYPE_VT_BSTR = -1;
|
||||
|
||||
private static final int TYPE_VT_ERROR = -1;
|
||||
|
||||
private static final int TYPE_VT_BOOL = -1;
|
||||
|
||||
private static final int TYPE_VT_VARIANT = -1;
|
||||
|
||||
private static final int TYPE_VT_UI1 = -1;
|
||||
|
||||
private static final int TYPE_VT_UI2 = -1;
|
||||
|
||||
private static final int TYPE_VT_UI4 = 19;
|
||||
|
||||
private static final int TYPE_VT_I8 = -1;
|
||||
|
||||
private static final int TYPE_VT_UI8 = -1;
|
||||
|
||||
private static final int TYPE_VT_LPSTR = 30;
|
||||
|
||||
private static final int TYPE_VT_LPWSTR = 31;
|
||||
|
||||
private static final int TYPE_VT_FILETIME = 64;
|
||||
|
||||
private static final int TYPE_VT_BLOB = 65;
|
||||
|
||||
private static final int TYPE_VT_STREAM = -1;
|
||||
|
||||
private static final int TYPE_VT_STORAGE = -1;
|
||||
|
||||
private static final int TYPE_VT_STREAMED_OBJECT = -1;
|
||||
|
||||
private static final int TYPE_VT_STORED_OBJECT = -1;
|
||||
|
||||
private static final int TYPE_VT_BLOB_OBJECT = -1;
|
||||
|
||||
private static final int TYPE_VT_CF = 71;
|
||||
|
||||
private static final int TYPE_VT_CLSID = 72;
|
||||
|
||||
private static final int TYPE_VT_VECTOR = 4096;
|
||||
|
||||
SeekableStream stream;
|
||||
|
||||
Hashtable properties = new Hashtable();
|
||||
|
||||
public PropertySet(SeekableStream stream) throws IOException {
|
||||
this.stream = stream;
|
||||
stream.seek(44L);
|
||||
int sectionOffset = stream.readIntLE();
|
||||
stream.seek((long)sectionOffset);
|
||||
int sectionSize = stream.readIntLE();
|
||||
int sectionCount = stream.readIntLE();
|
||||
for (int i = 0; i < sectionCount; i++) {
|
||||
stream.seek((long)(sectionOffset + 8 * i + 8));
|
||||
int pid = stream.readIntLE();
|
||||
int offset = stream.readIntLE();
|
||||
stream.seek((long)(sectionOffset + offset));
|
||||
int type = stream.readIntLE();
|
||||
Property p = new Property(type, sectionOffset + offset + 4);
|
||||
this.properties.put(new Integer(pid), p);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasProperty(int id) {
|
||||
Property p = (Property)this.properties.get(new Integer(id));
|
||||
return (p != null);
|
||||
}
|
||||
|
||||
public int getI4(int id) {
|
||||
Property p = (Property)this.properties.get(new Integer(id));
|
||||
try {
|
||||
int offset = p.getOffset();
|
||||
this.stream.seek((long)offset);
|
||||
return this.stream.readIntLE();
|
||||
} catch (IOException e) {
|
||||
ImagingListenerProxy.errorOccurred(JaiI18N.getString("PropertySet1"), e, this, false);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
public int getUI1(int id) {
|
||||
Property p = (Property)this.properties.get(new Integer(id));
|
||||
try {
|
||||
int offset = p.getOffset();
|
||||
this.stream.seek((long)offset);
|
||||
return this.stream.readUnsignedByte();
|
||||
} catch (IOException e) {
|
||||
ImagingListenerProxy.errorOccurred(JaiI18N.getString("PropertySet1"), e, this, false);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
public int getUI2(int id) {
|
||||
Property p = (Property)this.properties.get(new Integer(id));
|
||||
try {
|
||||
int offset = p.getOffset();
|
||||
this.stream.seek((long)offset);
|
||||
return this.stream.readUnsignedShortLE();
|
||||
} catch (IOException e) {
|
||||
ImagingListenerProxy.errorOccurred(JaiI18N.getString("PropertySet2"), e, this, false);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
public long getUI4(int id) {
|
||||
Property p = (Property)this.properties.get(new Integer(id));
|
||||
try {
|
||||
int offset = p.getOffset();
|
||||
this.stream.seek((long)offset);
|
||||
return this.stream.readUnsignedIntLE();
|
||||
} catch (IOException e) {
|
||||
ImagingListenerProxy.errorOccurred(JaiI18N.getString("PropertySet4"), e, this, false);
|
||||
return -1L;
|
||||
}
|
||||
}
|
||||
|
||||
public long getUI4(int id, long defaultValue) {
|
||||
Property p = (Property)this.properties.get(new Integer(id));
|
||||
if (p == null)
|
||||
return defaultValue;
|
||||
try {
|
||||
int offset = p.getOffset();
|
||||
this.stream.seek((long)offset);
|
||||
return this.stream.readUnsignedIntLE();
|
||||
} catch (IOException e) {
|
||||
ImagingListenerProxy.errorOccurred(JaiI18N.getString("PropertySet4"), e, this, false);
|
||||
return -1L;
|
||||
}
|
||||
}
|
||||
|
||||
public String getLPSTR(int id) {
|
||||
Property p = (Property)this.properties.get(new Integer(id));
|
||||
if (p == null)
|
||||
return null;
|
||||
try {
|
||||
int offset = p.getOffset();
|
||||
this.stream.seek((long)offset);
|
||||
int length = this.stream.readIntLE();
|
||||
StringBuffer sb = new StringBuffer(length);
|
||||
for (int i = 0; i < length; i++)
|
||||
sb.append((char)this.stream.read());
|
||||
return sb.toString();
|
||||
} catch (IOException e) {
|
||||
ImagingListenerProxy.errorOccurred(JaiI18N.getString("PropertySet5"), e, this, false);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public String getLPWSTR(int id) {
|
||||
Property p = (Property)this.properties.get(new Integer(id));
|
||||
try {
|
||||
int offset = p.getOffset();
|
||||
this.stream.seek((long)offset);
|
||||
int length = this.stream.readIntLE();
|
||||
StringBuffer sb = new StringBuffer(length);
|
||||
for (int i = 0; i < length; i++)
|
||||
sb.append(this.stream.readCharLE());
|
||||
return sb.toString();
|
||||
} catch (IOException e) {
|
||||
ImagingListenerProxy.errorOccurred(JaiI18N.getString("PropertySet5"), e, this, false);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public float getR4(int id) {
|
||||
Property p = (Property)this.properties.get(new Integer(id));
|
||||
try {
|
||||
int offset = p.getOffset();
|
||||
this.stream.seek((long)offset);
|
||||
return this.stream.readFloatLE();
|
||||
} catch (IOException e) {
|
||||
ImagingListenerProxy.errorOccurred(JaiI18N.getString("PropertySet6"), e, this, false);
|
||||
return -1.0F;
|
||||
}
|
||||
}
|
||||
|
||||
public Date getDate(int id) {
|
||||
throw new RuntimeException(JaiI18N.getString("PropertySet0"));
|
||||
}
|
||||
|
||||
public Date getFiletime(int id) {
|
||||
throw new RuntimeException(JaiI18N.getString("PropertySet0"));
|
||||
}
|
||||
|
||||
public byte[] getBlob(int id) {
|
||||
Property p = (Property)this.properties.get(new Integer(id));
|
||||
try {
|
||||
int offset = p.getOffset();
|
||||
this.stream.seek((long)offset);
|
||||
int length = this.stream.readIntLE();
|
||||
byte[] buf = new byte[length];
|
||||
this.stream.seek((long)(offset + 4));
|
||||
this.stream.readFully(buf);
|
||||
return buf;
|
||||
} catch (IOException e) {
|
||||
ImagingListenerProxy.errorOccurred(JaiI18N.getString("PropertySet7"), e, this, false);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public int[] getUI1Vector(int id) {
|
||||
throw new RuntimeException(JaiI18N.getString("PropertySet0"));
|
||||
}
|
||||
|
||||
public int[] getUI2Vector(int id) {
|
||||
throw new RuntimeException(JaiI18N.getString("PropertySet0"));
|
||||
}
|
||||
|
||||
public long[] getUI4Vector(int id) {
|
||||
throw new RuntimeException(JaiI18N.getString("PropertySet0"));
|
||||
}
|
||||
|
||||
public float[] getR4Vector(int id) {
|
||||
throw new RuntimeException(JaiI18N.getString("PropertySet0"));
|
||||
}
|
||||
|
||||
public String[] getLPWSTRVector(int id) {
|
||||
throw new RuntimeException(JaiI18N.getString("PropertySet0"));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
package com.sun.media.jai.codecimpl.fpx;
|
||||
|
||||
class SSDirectoryEntry {
|
||||
int index;
|
||||
|
||||
String name;
|
||||
|
||||
long size;
|
||||
|
||||
long startSector;
|
||||
|
||||
long SIDLeftSibling;
|
||||
|
||||
long SIDRightSibling;
|
||||
|
||||
long SIDChild;
|
||||
|
||||
public SSDirectoryEntry(int index, String name, long size, long startSector, long SIDLeftSibling, long SIDRightSibling, long SIDChild) {
|
||||
this.name = name;
|
||||
this.index = index;
|
||||
this.size = size;
|
||||
this.startSector = startSector;
|
||||
this.SIDLeftSibling = SIDLeftSibling;
|
||||
this.SIDRightSibling = SIDRightSibling;
|
||||
this.SIDChild = SIDChild;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public long getSize() {
|
||||
return this.size;
|
||||
}
|
||||
|
||||
public long getStartSector() {
|
||||
return this.startSector;
|
||||
}
|
||||
|
||||
public long getSIDLeftSibling() {
|
||||
return this.SIDLeftSibling;
|
||||
}
|
||||
|
||||
public long getSIDRightSibling() {
|
||||
return this.SIDRightSibling;
|
||||
}
|
||||
|
||||
public long getSIDChild() {
|
||||
return this.SIDChild;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,375 @@
|
|||
package com.sun.media.jai.codecimpl.fpx;
|
||||
|
||||
import com.sun.media.jai.codec.ByteArraySeekableStream;
|
||||
import com.sun.media.jai.codec.FileSeekableStream;
|
||||
import com.sun.media.jai.codec.SeekableStream;
|
||||
import com.sun.media.jai.codec.SegmentedSeekableStream;
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
public class StructuredStorage {
|
||||
private static final long FAT_ENDOFCHAIN = 4294967294L;
|
||||
|
||||
private static final long FAT_FREESECT = 4294967295L;
|
||||
|
||||
SeekableStream file;
|
||||
|
||||
private int sectorShift;
|
||||
|
||||
private int miniSectorShift;
|
||||
|
||||
private long csectFat;
|
||||
|
||||
private long sectDirStart;
|
||||
|
||||
private long miniSectorCutoff;
|
||||
|
||||
private long sectMiniFatStart;
|
||||
|
||||
private long csectMiniFat;
|
||||
|
||||
private long sectDifStart;
|
||||
|
||||
private long csectDif;
|
||||
|
||||
private long[] sectFat;
|
||||
|
||||
private long[] MINIFAT;
|
||||
|
||||
private SSDirectoryEntry[] DIR;
|
||||
|
||||
private SeekableStream miniStream;
|
||||
|
||||
private SeekableStream FATStream;
|
||||
|
||||
long cwdIndex = -1L;
|
||||
|
||||
public StructuredStorage(SeekableStream file) throws IOException {
|
||||
this.file = file;
|
||||
getHeader();
|
||||
getFat();
|
||||
getMiniFat();
|
||||
getDirectory();
|
||||
getMiniStream();
|
||||
}
|
||||
|
||||
private void getHeader() throws IOException {
|
||||
this.file.seek(30L);
|
||||
this.sectorShift = this.file.readUnsignedShortLE();
|
||||
this.file.seek(32L);
|
||||
this.miniSectorShift = this.file.readUnsignedShortLE();
|
||||
this.file.seek(44L);
|
||||
this.csectFat = this.file.readUnsignedIntLE();
|
||||
this.file.seek(48L);
|
||||
this.sectDirStart = this.file.readUnsignedIntLE();
|
||||
this.file.seek(56L);
|
||||
this.miniSectorCutoff = this.file.readUnsignedIntLE();
|
||||
this.file.seek(60L);
|
||||
this.sectMiniFatStart = this.file.readUnsignedIntLE();
|
||||
this.file.seek(64L);
|
||||
this.csectMiniFat = this.file.readUnsignedIntLE();
|
||||
this.file.seek(68L);
|
||||
this.sectDifStart = this.file.readUnsignedIntLE();
|
||||
this.file.seek(72L);
|
||||
this.csectDif = this.file.readUnsignedIntLE();
|
||||
this.sectFat = new long[109];
|
||||
this.file.seek(76L);
|
||||
for (int i = 0; i < 109; i++)
|
||||
this.sectFat[i] = this.file.readUnsignedIntLE();
|
||||
}
|
||||
|
||||
private void getFat() throws IOException {
|
||||
int size = getSectorSize();
|
||||
int sectsPerFat = size / 4;
|
||||
int fatsPerDif = size / 4 - 1;
|
||||
int numFATSectors = (int)(this.csectFat + this.csectDif * (long)fatsPerDif);
|
||||
long[] FATSectors = new long[numFATSectors];
|
||||
int count = 0;
|
||||
for (int i = 0; i < 109; i++) {
|
||||
long sector = this.sectFat[i];
|
||||
if (sector == 4294967295L)
|
||||
break;
|
||||
FATSectors[count++] = getOffsetOfSector(this.sectFat[i]);
|
||||
}
|
||||
if (this.csectDif > 0L) {
|
||||
long dif = this.sectDifStart;
|
||||
byte[] difBuf = new byte[size];
|
||||
for (int j = 0; (long)j < this.csectDif; j++) {
|
||||
readSector(dif, difBuf, 0);
|
||||
for (int k = 0; k < fatsPerDif; k++) {
|
||||
int sec = FPXUtils.getIntLE(difBuf, 4 * k);
|
||||
FATSectors[count++] = getOffsetOfSector((long)sec);
|
||||
}
|
||||
dif = (long)FPXUtils.getIntLE(difBuf, size - 4);
|
||||
}
|
||||
}
|
||||
this.FATStream = new SegmentedSeekableStream(this.file, FATSectors, size, numFATSectors * size, true);
|
||||
}
|
||||
|
||||
private void getMiniFat() throws IOException {
|
||||
int size = getSectorSize();
|
||||
int sectsPerFat = size / 4;
|
||||
int index = 0;
|
||||
this.MINIFAT = new long[(int)(this.csectMiniFat * (long)sectsPerFat)];
|
||||
long sector = this.sectMiniFatStart;
|
||||
byte[] buf = new byte[size];
|
||||
while (sector != 4294967294L) {
|
||||
readSector(sector, buf, 0);
|
||||
for (int j = 0; j < sectsPerFat; j++)
|
||||
this.MINIFAT[index++] = (long)FPXUtils.getIntLE(buf, 4 * j);
|
||||
sector = getFATSector(sector);
|
||||
}
|
||||
}
|
||||
|
||||
private void getDirectory() throws IOException {
|
||||
int size = getSectorSize();
|
||||
long sector = this.sectDirStart;
|
||||
int numDirectorySectors = 0;
|
||||
while (sector != 4294967294L) {
|
||||
sector = getFATSector(sector);
|
||||
numDirectorySectors++;
|
||||
}
|
||||
int directoryEntries = 4 * numDirectorySectors;
|
||||
this.DIR = new SSDirectoryEntry[directoryEntries];
|
||||
sector = this.sectDirStart;
|
||||
byte[] buf = new byte[size];
|
||||
int index = 0;
|
||||
while (sector != 4294967294L) {
|
||||
readSector(sector, buf, 0);
|
||||
int offset = 0;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
int length = FPXUtils.getShortLE(buf, offset + 64);
|
||||
String name = FPXUtils.getString(buf, offset + 0, length);
|
||||
long SIDLeftSibling = FPXUtils.getUnsignedIntLE(buf, offset + 68);
|
||||
long SIDRightSibling = FPXUtils.getUnsignedIntLE(buf, offset + 72);
|
||||
long SIDChild = FPXUtils.getUnsignedIntLE(buf, offset + 76);
|
||||
long startSector = FPXUtils.getUnsignedIntLE(buf, offset + 116);
|
||||
long streamSize = FPXUtils.getUnsignedIntLE(buf, offset + 120);
|
||||
this.DIR[index] = new SSDirectoryEntry(index, name, streamSize, startSector, SIDLeftSibling, SIDRightSibling, SIDChild);
|
||||
index++;
|
||||
offset += 128;
|
||||
}
|
||||
sector = getFATSector(sector);
|
||||
}
|
||||
}
|
||||
|
||||
private void getMiniStream() throws IOException {
|
||||
int length = getLength(0L);
|
||||
int sectorSize = getSectorSize();
|
||||
int sectors = (length + sectorSize - 1) / sectorSize;
|
||||
long[] segmentPositions = new long[sectors];
|
||||
long sector = getStartSector(0L);
|
||||
for (int i = 0; i < sectors - 1; i++) {
|
||||
segmentPositions[i] = getOffsetOfSector(sector);
|
||||
sector = getFATSector(sector);
|
||||
if (sector == 4294967294L)
|
||||
break;
|
||||
}
|
||||
segmentPositions[sectors - 1] = getOffsetOfSector(sector);
|
||||
this.miniStream = new SegmentedSeekableStream(this.file, segmentPositions, sectorSize, length, true);
|
||||
}
|
||||
|
||||
private int getSectorSize() {
|
||||
return 1 << this.sectorShift;
|
||||
}
|
||||
|
||||
private long getOffsetOfSector(long sector) {
|
||||
return sector * (long)getSectorSize() + 512L;
|
||||
}
|
||||
|
||||
private int getMiniSectorSize() {
|
||||
return 1 << this.miniSectorShift;
|
||||
}
|
||||
|
||||
private long getOffsetOfMiniSector(long sector) {
|
||||
return sector * (long)getMiniSectorSize();
|
||||
}
|
||||
|
||||
private void readMiniSector(long sector, byte[] buf, int offset, int length) throws IOException {
|
||||
this.miniStream.seek(getOffsetOfMiniSector(sector));
|
||||
this.miniStream.read(buf, offset, length);
|
||||
}
|
||||
|
||||
private void readMiniSector(long sector, byte[] buf, int offset) throws IOException {
|
||||
readMiniSector(sector, buf, offset, getMiniSectorSize());
|
||||
}
|
||||
|
||||
private void readSector(long sector, byte[] buf, int offset, int length) throws IOException {
|
||||
this.file.seek(getOffsetOfSector(sector));
|
||||
this.file.read(buf, offset, length);
|
||||
}
|
||||
|
||||
private void readSector(long sector, byte[] buf, int offset) throws IOException {
|
||||
readSector(sector, buf, offset, getSectorSize());
|
||||
}
|
||||
|
||||
private SSDirectoryEntry getDirectoryEntry(long index) {
|
||||
return this.DIR[(int)index];
|
||||
}
|
||||
|
||||
private long getStartSector(long index) {
|
||||
return this.DIR[(int)index].getStartSector();
|
||||
}
|
||||
|
||||
private int getLength(long index) {
|
||||
return (int)this.DIR[(int)index].getSize();
|
||||
}
|
||||
|
||||
private long getFATSector(long sector) throws IOException {
|
||||
this.FATStream.seek(4L * sector);
|
||||
return this.FATStream.readUnsignedIntLE();
|
||||
}
|
||||
|
||||
private long getMiniFATSector(long sector) {
|
||||
return this.MINIFAT[(int)sector];
|
||||
}
|
||||
|
||||
private int getCurrentIndex() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
private int getIndex(String name, int index) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
private long searchDirectory(String name, long index) {
|
||||
if (index == 4294967295L)
|
||||
return -1L;
|
||||
SSDirectoryEntry dirent = getDirectoryEntry(index);
|
||||
if (name.equals(dirent.getName()))
|
||||
return index;
|
||||
long lindex = searchDirectory(name, dirent.getSIDLeftSibling());
|
||||
if (lindex != -1L)
|
||||
return lindex;
|
||||
long rindex = searchDirectory(name, dirent.getSIDRightSibling());
|
||||
if (rindex != -1L)
|
||||
return rindex;
|
||||
return -1L;
|
||||
}
|
||||
|
||||
public void changeDirectoryToRoot() {
|
||||
this.cwdIndex = getDirectoryEntry(0L).getSIDChild();
|
||||
}
|
||||
|
||||
public boolean changeDirectory(String name) {
|
||||
long index = searchDirectory(name, this.cwdIndex);
|
||||
if (index != -1L) {
|
||||
this.cwdIndex = getDirectoryEntry(index).getSIDChild();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private long getStreamIndex(String name) {
|
||||
long index = this.cwdIndex;
|
||||
StringTokenizer st = new StringTokenizer(name, "/");
|
||||
boolean firstTime = true;
|
||||
while (st.hasMoreTokens()) {
|
||||
String tok = st.nextToken();
|
||||
if (!firstTime) {
|
||||
index = getDirectoryEntry(index).getSIDChild();
|
||||
} else {
|
||||
firstTime = false;
|
||||
}
|
||||
index = searchDirectory(tok, index);
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
public byte[] getStreamAsBytes(String name) throws IOException {
|
||||
long index = getStreamIndex(name);
|
||||
if (index == -1L)
|
||||
return null;
|
||||
int length = getLength(index);
|
||||
byte[] buf = new byte[length];
|
||||
if ((long)length > this.miniSectorCutoff) {
|
||||
int sectorSize = getSectorSize();
|
||||
int sectors = (length + sectorSize - 1) / sectorSize;
|
||||
long sector = getStartSector(index);
|
||||
int offset = 0;
|
||||
for (int i = 0; i < sectors - 1; i++) {
|
||||
readSector(sector, buf, offset, sectorSize);
|
||||
offset += sectorSize;
|
||||
sector = getFATSector(sector);
|
||||
if (sector == 4294967294L)
|
||||
break;
|
||||
}
|
||||
readSector(sector, buf, offset, length - offset);
|
||||
} else {
|
||||
int sectorSize = getMiniSectorSize();
|
||||
int sectors = (length + sectorSize - 1) / sectorSize;
|
||||
long sector = getStartSector(index);
|
||||
int offset = 0;
|
||||
for (int i = 0; i < sectors - 1; i++) {
|
||||
long miniSectorOffset = getOffsetOfMiniSector(sector);
|
||||
readMiniSector(sector, buf, offset, sectorSize);
|
||||
offset += sectorSize;
|
||||
sector = getMiniFATSector(sector);
|
||||
}
|
||||
readMiniSector(sector, buf, offset, length - offset);
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
public SeekableStream getStream(String name) throws IOException {
|
||||
long index = getStreamIndex(name);
|
||||
if (index == -1L)
|
||||
return null;
|
||||
int length = getLength(index);
|
||||
if ((long)length > this.miniSectorCutoff) {
|
||||
int j = getSectorSize();
|
||||
int k = (length + j - 1) / j;
|
||||
long[] arrayOfLong = new long[k];
|
||||
long l = getStartSector(index);
|
||||
for (int m = 0; m < k - 1; m++) {
|
||||
arrayOfLong[m] = getOffsetOfSector(l);
|
||||
l = getFATSector(l);
|
||||
if (l == 4294967294L)
|
||||
break;
|
||||
}
|
||||
arrayOfLong[k - 1] = getOffsetOfSector(l);
|
||||
return new SegmentedSeekableStream(this.file, arrayOfLong, j, length, true);
|
||||
}
|
||||
int sectorSize = getMiniSectorSize();
|
||||
int sectors = (length + sectorSize - 1) / sectorSize;
|
||||
long[] segmentPositions = new long[sectors];
|
||||
long sector = getStartSector(index);
|
||||
for (int i = 0; i < sectors - 1; i++) {
|
||||
segmentPositions[i] = getOffsetOfMiniSector(sector);
|
||||
sector = getMiniFATSector(sector);
|
||||
}
|
||||
segmentPositions[sectors - 1] = getOffsetOfMiniSector(sector);
|
||||
return new SegmentedSeekableStream(this.miniStream, segmentPositions, sectorSize, length, true);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
RandomAccessFile f = new RandomAccessFile(args[0], "r");
|
||||
SeekableStream sis = new FileSeekableStream(f);
|
||||
StructuredStorage ss = new StructuredStorage(sis);
|
||||
ss.changeDirectoryToRoot();
|
||||
byte[] s = ss.getStreamAsBytes("\005SummaryInformation");
|
||||
PropertySet ps = new PropertySet(new ByteArraySeekableStream(s));
|
||||
byte[] thumb = ps.getBlob(17);
|
||||
System.out.print("BM");
|
||||
int fs = thumb.length - 8 + 14 + 40;
|
||||
System.out.print((char)(fs & 0xFF));
|
||||
System.out.print((char)(fs >> 8 & 0xFF));
|
||||
System.out.print((char)(fs >> 16 & 0xFF));
|
||||
System.out.print((char)(fs >> 24 & 0xFF));
|
||||
System.out.print('\000');
|
||||
System.out.print('\000');
|
||||
System.out.print('\000');
|
||||
System.out.print('\000');
|
||||
System.out.print('6');
|
||||
System.out.print('\000');
|
||||
System.out.print('\000');
|
||||
System.out.print('\000');
|
||||
for (int i = 8; i < thumb.length; i++)
|
||||
System.out.print((char)(thumb[i] & 0xFF));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,527 @@
|
|||
package com.sun.media.jai.codecimpl.util;
|
||||
|
||||
import java.awt.image.ComponentSampleModel;
|
||||
import java.awt.image.DataBuffer;
|
||||
import java.awt.image.DataBufferByte;
|
||||
import java.awt.image.DataBufferInt;
|
||||
import java.awt.image.DataBufferShort;
|
||||
import java.awt.image.DataBufferUShort;
|
||||
import java.awt.image.SampleModel;
|
||||
|
||||
public class ComponentSampleModelJAI extends ComponentSampleModel {
|
||||
public ComponentSampleModelJAI(int dataType, int w, int h, int pixelStride, int scanlineStride, int[] bandOffsets) {
|
||||
super(dataType, w, h, pixelStride, scanlineStride, bandOffsets);
|
||||
}
|
||||
|
||||
public ComponentSampleModelJAI(int dataType, int w, int h, int pixelStride, int scanlineStride, int[] bankIndices, int[] bandOffsets) {
|
||||
super(dataType, w, h, pixelStride, scanlineStride, bankIndices, bandOffsets);
|
||||
}
|
||||
|
||||
private long getBufferSize() {
|
||||
int maxBandOff = this.bandOffsets[0];
|
||||
for (int i = 1; i < this.bandOffsets.length; i++)
|
||||
maxBandOff = Math.max(maxBandOff, this.bandOffsets[i]);
|
||||
long size = 0L;
|
||||
if (maxBandOff >= 0)
|
||||
size += (long)(maxBandOff + 1);
|
||||
if (this.pixelStride > 0)
|
||||
size += (long)(this.pixelStride * (this.width - 1));
|
||||
if (this.scanlineStride > 0)
|
||||
size += (long)(this.scanlineStride * (this.height - 1));
|
||||
return size;
|
||||
}
|
||||
|
||||
private int[] JAIorderBands(int[] orig, int step) {
|
||||
int[] map = new int[orig.length];
|
||||
int[] ret = new int[orig.length];
|
||||
for (int j = 0; j < map.length; ) {
|
||||
map[j] = j;
|
||||
j++;
|
||||
}
|
||||
for (int i = 0; i < ret.length; i++) {
|
||||
int index = i;
|
||||
for (int k = i + 1; k < ret.length; k++) {
|
||||
if (orig[map[index]] > orig[map[k]])
|
||||
index = k;
|
||||
}
|
||||
ret[map[index]] = i * step;
|
||||
map[index] = map[i];
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public SampleModel createCompatibleSampleModel(int w, int h) {
|
||||
int[] bandOff;
|
||||
SampleModel ret = null;
|
||||
int minBandOff = this.bandOffsets[0];
|
||||
int maxBandOff = this.bandOffsets[0];
|
||||
for (int i = 1; i < this.bandOffsets.length; i++) {
|
||||
minBandOff = Math.min(minBandOff, this.bandOffsets[i]);
|
||||
maxBandOff = Math.max(maxBandOff, this.bandOffsets[i]);
|
||||
}
|
||||
maxBandOff -= minBandOff;
|
||||
int bands = this.bandOffsets.length;
|
||||
int pStride = Math.abs(this.pixelStride);
|
||||
int lStride = Math.abs(this.scanlineStride);
|
||||
int bStride = Math.abs(maxBandOff);
|
||||
if (pStride > lStride) {
|
||||
if (pStride > bStride) {
|
||||
if (lStride > bStride) {
|
||||
bandOff = new int[this.bandOffsets.length];
|
||||
for (int k = 0; k < bands; k++)
|
||||
bandOff[k] = this.bandOffsets[k] - minBandOff;
|
||||
lStride = bStride + 1;
|
||||
pStride = lStride * h;
|
||||
} else {
|
||||
bandOff = JAIorderBands(this.bandOffsets, lStride * h);
|
||||
pStride = bands * lStride * h;
|
||||
}
|
||||
} else {
|
||||
pStride = lStride * h;
|
||||
bandOff = JAIorderBands(this.bandOffsets, pStride * w);
|
||||
}
|
||||
} else if (pStride > bStride) {
|
||||
bandOff = new int[this.bandOffsets.length];
|
||||
for (int k = 0; k < bands; k++)
|
||||
bandOff[k] = this.bandOffsets[k] - minBandOff;
|
||||
pStride = bStride + 1;
|
||||
lStride = pStride * w;
|
||||
} else if (lStride > bStride) {
|
||||
bandOff = JAIorderBands(this.bandOffsets, pStride * w);
|
||||
lStride = bands * pStride * w;
|
||||
} else {
|
||||
lStride = pStride * w;
|
||||
bandOff = JAIorderBands(this.bandOffsets, lStride * h);
|
||||
}
|
||||
int base = 0;
|
||||
if (this.scanlineStride < 0) {
|
||||
base += lStride * h;
|
||||
lStride *= -1;
|
||||
}
|
||||
if (this.pixelStride < 0) {
|
||||
base += pStride * w;
|
||||
pStride *= -1;
|
||||
}
|
||||
for (int j = 0; j < bands; j++)
|
||||
bandOff[j] = bandOff[j] + base;
|
||||
return new ComponentSampleModelJAI(this.dataType, w, h, pStride, lStride, this.bankIndices, bandOff);
|
||||
}
|
||||
|
||||
public SampleModel createSubsetSampleModel(int[] bands) {
|
||||
int[] newBankIndices = new int[bands.length];
|
||||
int[] newBandOffsets = new int[bands.length];
|
||||
for (int i = 0; i < bands.length; i++) {
|
||||
int b = bands[i];
|
||||
newBankIndices[i] = this.bankIndices[b];
|
||||
newBandOffsets[i] = this.bandOffsets[b];
|
||||
}
|
||||
return new ComponentSampleModelJAI(this.dataType, this.width, this.height, this.pixelStride, this.scanlineStride, newBankIndices, newBandOffsets);
|
||||
}
|
||||
|
||||
public DataBuffer createDataBuffer() {
|
||||
DataBuffer dataBuffer = null;
|
||||
int size = (int)getBufferSize();
|
||||
switch (this.dataType) {
|
||||
case 0:
|
||||
dataBuffer = new DataBufferByte(size, this.numBanks);
|
||||
break;
|
||||
case 1:
|
||||
dataBuffer = new DataBufferUShort(size, this.numBanks);
|
||||
break;
|
||||
case 3:
|
||||
dataBuffer = new DataBufferInt(size, this.numBanks);
|
||||
break;
|
||||
case 2:
|
||||
dataBuffer = new DataBufferShort(size, this.numBanks);
|
||||
break;
|
||||
case 4:
|
||||
dataBuffer = DataBufferUtils.createDataBufferFloat(size, this.numBanks);
|
||||
break;
|
||||
case 5:
|
||||
dataBuffer = DataBufferUtils.createDataBufferDouble(size, this.numBanks);
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException(JaiI18N.getString("RasterFactory3"));
|
||||
}
|
||||
return dataBuffer;
|
||||
}
|
||||
|
||||
public Object getDataElements(int x, int y, Object obj, DataBuffer data) {
|
||||
byte[] bdata;
|
||||
int i;
|
||||
short[] usdata;
|
||||
int j, idata[], k;
|
||||
short[] sdata;
|
||||
int m;
|
||||
float[] fdata;
|
||||
int n;
|
||||
double[] ddata;
|
||||
int i1;
|
||||
int type = getTransferType();
|
||||
int numDataElems = getNumDataElements();
|
||||
int pixelOffset = y * this.scanlineStride + x * this.pixelStride;
|
||||
switch (type) {
|
||||
case 0:
|
||||
if (obj == null) {
|
||||
bdata = new byte[numDataElems];
|
||||
} else {
|
||||
bdata = (byte[])obj;
|
||||
}
|
||||
for (i = 0; i < numDataElems; i++)
|
||||
bdata[i] = (byte)data.getElem(this.bankIndices[i], pixelOffset + this.bandOffsets[i]);
|
||||
obj = bdata;
|
||||
break;
|
||||
case 1:
|
||||
if (obj == null) {
|
||||
usdata = new short[numDataElems];
|
||||
} else {
|
||||
usdata = (short[])obj;
|
||||
}
|
||||
for (j = 0; j < numDataElems; j++)
|
||||
usdata[j] = (short)data.getElem(this.bankIndices[j], pixelOffset + this.bandOffsets[j]);
|
||||
obj = usdata;
|
||||
break;
|
||||
case 3:
|
||||
if (obj == null) {
|
||||
idata = new int[numDataElems];
|
||||
} else {
|
||||
idata = (int[])obj;
|
||||
}
|
||||
for (k = 0; k < numDataElems; k++)
|
||||
idata[k] = data.getElem(this.bankIndices[k], pixelOffset + this.bandOffsets[k]);
|
||||
obj = idata;
|
||||
break;
|
||||
case 2:
|
||||
if (obj == null) {
|
||||
sdata = new short[numDataElems];
|
||||
} else {
|
||||
sdata = (short[])obj;
|
||||
}
|
||||
for (m = 0; m < numDataElems; m++)
|
||||
sdata[m] = (short)data.getElem(this.bankIndices[m], pixelOffset + this.bandOffsets[m]);
|
||||
obj = sdata;
|
||||
break;
|
||||
case 4:
|
||||
if (obj == null) {
|
||||
fdata = new float[numDataElems];
|
||||
} else {
|
||||
fdata = (float[])obj;
|
||||
}
|
||||
for (n = 0; n < numDataElems; n++)
|
||||
fdata[n] = data.getElemFloat(this.bankIndices[n], pixelOffset + this.bandOffsets[n]);
|
||||
obj = fdata;
|
||||
break;
|
||||
case 5:
|
||||
if (obj == null) {
|
||||
ddata = new double[numDataElems];
|
||||
} else {
|
||||
ddata = (double[])obj;
|
||||
}
|
||||
for (i1 = 0; i1 < numDataElems; i1++)
|
||||
ddata[i1] = data.getElemDouble(this.bankIndices[i1], pixelOffset + this.bandOffsets[i1]);
|
||||
obj = ddata;
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException(JaiI18N.getString("RasterFactory3"));
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
public Object getDataElements(int x, int y, int w, int h, Object obj, DataBuffer data) {
|
||||
short[] usdata;
|
||||
int[] idata;
|
||||
short[] sdata;
|
||||
float[] fdata;
|
||||
double[] ddata;
|
||||
byte[] bdata;
|
||||
int i;
|
||||
int type = getTransferType();
|
||||
int numDataElems = getNumDataElements();
|
||||
int cnt = 0;
|
||||
Object o = null;
|
||||
switch (type) {
|
||||
case 0:
|
||||
if (obj == null) {
|
||||
bdata = new byte[numDataElems * w * h];
|
||||
} else {
|
||||
bdata = (byte[])obj;
|
||||
}
|
||||
for (i = y; i < y + h; i++) {
|
||||
for (int j = x; j < x + w; j++) {
|
||||
o = getDataElements(j, i, o, data);
|
||||
byte[] btemp = (byte[])o;
|
||||
for (int k = 0; k < numDataElems; k++)
|
||||
bdata[cnt++] = btemp[k];
|
||||
}
|
||||
}
|
||||
obj = bdata;
|
||||
break;
|
||||
case 1:
|
||||
if (obj == null) {
|
||||
usdata = new short[numDataElems * w * h];
|
||||
} else {
|
||||
usdata = (short[])obj;
|
||||
}
|
||||
for (i = y; i < y + h; i++) {
|
||||
for (int j = x; j < x + w; j++) {
|
||||
o = getDataElements(j, i, o, data);
|
||||
short[] ustemp = (short[])o;
|
||||
for (int k = 0; k < numDataElems; k++)
|
||||
usdata[cnt++] = ustemp[k];
|
||||
}
|
||||
}
|
||||
obj = usdata;
|
||||
break;
|
||||
case 3:
|
||||
if (obj == null) {
|
||||
idata = new int[numDataElems * w * h];
|
||||
} else {
|
||||
idata = (int[])obj;
|
||||
}
|
||||
for (i = y; i < y + h; i++) {
|
||||
for (int j = x; j < x + w; j++) {
|
||||
o = getDataElements(j, i, o, data);
|
||||
int[] itemp = (int[])o;
|
||||
for (int k = 0; k < numDataElems; k++)
|
||||
idata[cnt++] = itemp[k];
|
||||
}
|
||||
}
|
||||
obj = idata;
|
||||
break;
|
||||
case 2:
|
||||
if (obj == null) {
|
||||
sdata = new short[numDataElems * w * h];
|
||||
} else {
|
||||
sdata = (short[])obj;
|
||||
}
|
||||
for (i = y; i < y + h; i++) {
|
||||
for (int j = x; j < x + w; j++) {
|
||||
o = getDataElements(j, i, o, data);
|
||||
short[] stemp = (short[])o;
|
||||
for (int k = 0; k < numDataElems; k++)
|
||||
sdata[cnt++] = stemp[k];
|
||||
}
|
||||
}
|
||||
obj = sdata;
|
||||
break;
|
||||
case 4:
|
||||
if (obj == null) {
|
||||
fdata = new float[numDataElems * w * h];
|
||||
} else {
|
||||
fdata = (float[])obj;
|
||||
}
|
||||
for (i = y; i < y + h; i++) {
|
||||
for (int j = x; j < x + w; j++) {
|
||||
o = getDataElements(j, i, o, data);
|
||||
float[] ftemp = (float[])o;
|
||||
for (int k = 0; k < numDataElems; k++)
|
||||
fdata[cnt++] = ftemp[k];
|
||||
}
|
||||
}
|
||||
obj = fdata;
|
||||
break;
|
||||
case 5:
|
||||
if (obj == null) {
|
||||
ddata = new double[numDataElems * w * h];
|
||||
} else {
|
||||
ddata = (double[])obj;
|
||||
}
|
||||
for (i = y; i < y + h; i++) {
|
||||
for (int j = x; j < x + w; j++) {
|
||||
o = getDataElements(j, i, o, data);
|
||||
double[] dtemp = (double[])o;
|
||||
for (int k = 0; k < numDataElems; k++)
|
||||
ddata[cnt++] = dtemp[k];
|
||||
}
|
||||
}
|
||||
obj = ddata;
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException(JaiI18N.getString("RasterFactory3"));
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
public void setDataElements(int x, int y, Object obj, DataBuffer data) {
|
||||
byte[] barray;
|
||||
int i;
|
||||
short[] usarray;
|
||||
int j, iarray[], k;
|
||||
short[] sarray;
|
||||
int m;
|
||||
float[] farray;
|
||||
int n;
|
||||
double[] darray;
|
||||
int i1;
|
||||
int type = getTransferType();
|
||||
int numDataElems = getNumDataElements();
|
||||
int pixelOffset = y * this.scanlineStride + x * this.pixelStride;
|
||||
switch (type) {
|
||||
case 0:
|
||||
barray = (byte[])obj;
|
||||
for (i = 0; i < numDataElems; i++)
|
||||
data.setElem(this.bankIndices[i], pixelOffset + this.bandOffsets[i], barray[i] & 0xFF);
|
||||
break;
|
||||
case 1:
|
||||
usarray = (short[])obj;
|
||||
for (j = 0; j < numDataElems; j++)
|
||||
data.setElem(this.bankIndices[j], pixelOffset + this.bandOffsets[j], usarray[j] & 0xFFFF);
|
||||
break;
|
||||
case 3:
|
||||
iarray = (int[])obj;
|
||||
for (k = 0; k < numDataElems; k++)
|
||||
data.setElem(this.bankIndices[k], pixelOffset + this.bandOffsets[k], iarray[k]);
|
||||
break;
|
||||
case 2:
|
||||
sarray = (short[])obj;
|
||||
for (m = 0; m < numDataElems; m++)
|
||||
data.setElem(this.bankIndices[m], pixelOffset + this.bandOffsets[m], sarray[m]);
|
||||
break;
|
||||
case 4:
|
||||
farray = (float[])obj;
|
||||
for (n = 0; n < numDataElems; n++)
|
||||
data.setElemFloat(this.bankIndices[n], pixelOffset + this.bandOffsets[n], farray[n]);
|
||||
break;
|
||||
case 5:
|
||||
darray = (double[])obj;
|
||||
for (i1 = 0; i1 < numDataElems; i1++)
|
||||
data.setElemDouble(this.bankIndices[i1], pixelOffset + this.bandOffsets[i1], darray[i1]);
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException(JaiI18N.getString("RasterFactory3"));
|
||||
}
|
||||
}
|
||||
|
||||
public void setDataElements(int x, int y, int w, int h, Object obj, DataBuffer data) {
|
||||
byte[] barray;
|
||||
short[] usarray;
|
||||
int[] iArray;
|
||||
short[] sArray;
|
||||
float[] fArray;
|
||||
double[] dArray;
|
||||
byte[] btemp;
|
||||
short[] ustemp;
|
||||
int[] itemp;
|
||||
short[] stemp;
|
||||
float[] ftemp;
|
||||
double[] dtemp;
|
||||
int i;
|
||||
int cnt = 0;
|
||||
Object o = null;
|
||||
int type = getTransferType();
|
||||
int numDataElems = getNumDataElements();
|
||||
switch (type) {
|
||||
case 0:
|
||||
barray = (byte[])obj;
|
||||
btemp = new byte[numDataElems];
|
||||
for (i = y; i < y + h; i++) {
|
||||
for (int j = x; j < x + w; j++) {
|
||||
for (int k = 0; k < numDataElems; k++)
|
||||
btemp[k] = barray[cnt++];
|
||||
setDataElements(j, i, btemp, data);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
usarray = (short[])obj;
|
||||
ustemp = new short[numDataElems];
|
||||
for (i = y; i < y + h; i++) {
|
||||
for (int j = x; j < x + w; j++) {
|
||||
for (int k = 0; k < numDataElems; k++)
|
||||
ustemp[k] = usarray[cnt++];
|
||||
setDataElements(j, i, ustemp, data);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
iArray = (int[])obj;
|
||||
itemp = new int[numDataElems];
|
||||
for (i = y; i < y + h; i++) {
|
||||
for (int j = x; j < x + w; j++) {
|
||||
for (int k = 0; k < numDataElems; k++)
|
||||
itemp[k] = iArray[cnt++];
|
||||
setDataElements(j, i, itemp, data);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
sArray = (short[])obj;
|
||||
stemp = new short[numDataElems];
|
||||
for (i = y; i < y + h; i++) {
|
||||
for (int j = x; j < x + w; j++) {
|
||||
for (int k = 0; k < numDataElems; k++)
|
||||
stemp[k] = sArray[cnt++];
|
||||
setDataElements(j, i, stemp, data);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
fArray = (float[])obj;
|
||||
ftemp = new float[numDataElems];
|
||||
for (i = y; i < y + h; i++) {
|
||||
for (int j = x; j < x + w; j++) {
|
||||
for (int k = 0; k < numDataElems; k++)
|
||||
ftemp[k] = fArray[cnt++];
|
||||
setDataElements(j, i, ftemp, data);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
dArray = (double[])obj;
|
||||
dtemp = new double[numDataElems];
|
||||
for (i = y; i < y + h; i++) {
|
||||
for (int j = x; j < x + w; j++) {
|
||||
for (int k = 0; k < numDataElems; k++)
|
||||
dtemp[k] = dArray[cnt++];
|
||||
setDataElements(j, i, dtemp, data);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException(JaiI18N.getString("RasterFactory3"));
|
||||
}
|
||||
}
|
||||
|
||||
public void setSample(int x, int y, int b, float s, DataBuffer data) {
|
||||
data.setElemFloat(this.bankIndices[b], y * this.scanlineStride + x * this.pixelStride + this.bandOffsets[b], s);
|
||||
}
|
||||
|
||||
public float getSampleFloat(int x, int y, int b, DataBuffer data) {
|
||||
float sample = data.getElemFloat(this.bankIndices[b], y * this.scanlineStride + x * this.pixelStride + this.bandOffsets[b]);
|
||||
return sample;
|
||||
}
|
||||
|
||||
public void setSample(int x, int y, int b, double s, DataBuffer data) {
|
||||
data.setElemDouble(this.bankIndices[b], y * this.scanlineStride + x * this.pixelStride + this.bandOffsets[b], s);
|
||||
}
|
||||
|
||||
public double getSampleDouble(int x, int y, int b, DataBuffer data) {
|
||||
double sample = data.getElemDouble(this.bankIndices[b], y * this.scanlineStride + x * this.pixelStride + this.bandOffsets[b]);
|
||||
return sample;
|
||||
}
|
||||
|
||||
public double[] getPixels(int x, int y, int w, int h, double[] dArray, DataBuffer data) {
|
||||
double[] pixels;
|
||||
int Offset = 0;
|
||||
if (dArray != null) {
|
||||
pixels = dArray;
|
||||
} else {
|
||||
pixels = new double[this.numBands * w * h];
|
||||
}
|
||||
for (int i = y; i < h + y; i++) {
|
||||
for (int j = x; j < w + x; j++) {
|
||||
for (int k = 0; k < this.numBands; k++)
|
||||
pixels[Offset++] = getSampleDouble(j, i, k, data);
|
||||
}
|
||||
}
|
||||
return pixels;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
String ret = "ComponentSampleModelJAI: dataType=" + getDataType() + " numBands=" + getNumBands() + " width=" + getWidth() + " height=" + getHeight() + " bandOffsets=[ ";
|
||||
for (int i = 0; i < this.numBands; i++)
|
||||
ret = ret + getBandOffsets()[i] + " ";
|
||||
ret = ret + "]";
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,114 @@
|
|||
package com.sun.media.jai.codecimpl.util;
|
||||
|
||||
import java.awt.image.DataBuffer;
|
||||
|
||||
public class DataBufferDouble extends DataBuffer {
|
||||
protected double[][] bankdata;
|
||||
|
||||
protected double[] data;
|
||||
|
||||
public DataBufferDouble(int size) {
|
||||
super(5, size);
|
||||
this.data = new double[size];
|
||||
this.bankdata = new double[1][];
|
||||
this.bankdata[0] = this.data;
|
||||
}
|
||||
|
||||
public DataBufferDouble(int size, int numBanks) {
|
||||
super(5, size, numBanks);
|
||||
this.bankdata = new double[numBanks][];
|
||||
for (int i = 0; i < numBanks; i++)
|
||||
this.bankdata[i] = new double[size];
|
||||
this.data = this.bankdata[0];
|
||||
}
|
||||
|
||||
public DataBufferDouble(double[] dataArray, int size) {
|
||||
super(5, size);
|
||||
if (dataArray.length < size)
|
||||
throw new RuntimeException(JaiI18N.getString("DataBuffer0"));
|
||||
this.data = dataArray;
|
||||
this.bankdata = new double[1][];
|
||||
this.bankdata[0] = this.data;
|
||||
}
|
||||
|
||||
public DataBufferDouble(double[] dataArray, int size, int offset) {
|
||||
super(5, size, 1, offset);
|
||||
if (dataArray.length < size)
|
||||
throw new RuntimeException(JaiI18N.getString("DataBuffer1"));
|
||||
this.data = dataArray;
|
||||
this.bankdata = new double[1][];
|
||||
this.bankdata[0] = this.data;
|
||||
}
|
||||
|
||||
public DataBufferDouble(double[][] dataArray, int size) {
|
||||
super(5, size, dataArray.length);
|
||||
this.bankdata = dataArray;
|
||||
this.data = this.bankdata[0];
|
||||
}
|
||||
|
||||
public DataBufferDouble(double[][] dataArray, int size, int[] offsets) {
|
||||
super(5, size, dataArray.length, offsets);
|
||||
this.bankdata = dataArray;
|
||||
this.data = this.bankdata[0];
|
||||
}
|
||||
|
||||
public double[] getData() {
|
||||
return this.data;
|
||||
}
|
||||
|
||||
public double[] getData(int bank) {
|
||||
return this.bankdata[bank];
|
||||
}
|
||||
|
||||
public double[][] getBankData() {
|
||||
return this.bankdata;
|
||||
}
|
||||
|
||||
public int getElem(int i) {
|
||||
return (int)this.data[i + this.offset];
|
||||
}
|
||||
|
||||
public int getElem(int bank, int i) {
|
||||
return (int)this.bankdata[bank][i + this.offsets[bank]];
|
||||
}
|
||||
|
||||
public void setElem(int i, int val) {
|
||||
this.data[i + this.offset] = (double)val;
|
||||
}
|
||||
|
||||
public void setElem(int bank, int i, int val) {
|
||||
this.bankdata[bank][i + this.offsets[bank]] = (double)val;
|
||||
}
|
||||
|
||||
public float getElemFloat(int i) {
|
||||
return (float)this.data[i + this.offset];
|
||||
}
|
||||
|
||||
public float getElemFloat(int bank, int i) {
|
||||
return (float)this.bankdata[bank][i + this.offsets[bank]];
|
||||
}
|
||||
|
||||
public void setElemFloat(int i, float val) {
|
||||
this.data[i + this.offset] = (double)val;
|
||||
}
|
||||
|
||||
public void setElemFloat(int bank, int i, float val) {
|
||||
this.bankdata[bank][i + this.offsets[bank]] = (double)val;
|
||||
}
|
||||
|
||||
public double getElemDouble(int i) {
|
||||
return this.data[i + this.offset];
|
||||
}
|
||||
|
||||
public double getElemDouble(int bank, int i) {
|
||||
return this.bankdata[bank][i + this.offsets[bank]];
|
||||
}
|
||||
|
||||
public void setElemDouble(int i, double val) {
|
||||
this.data[i + this.offset] = val;
|
||||
}
|
||||
|
||||
public void setElemDouble(int bank, int i, double val) {
|
||||
this.bankdata[bank][i + this.offsets[bank]] = val;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,114 @@
|
|||
package com.sun.media.jai.codecimpl.util;
|
||||
|
||||
import java.awt.image.DataBuffer;
|
||||
|
||||
public class DataBufferFloat extends DataBuffer {
|
||||
protected float[][] bankdata;
|
||||
|
||||
protected float[] data;
|
||||
|
||||
public DataBufferFloat(int size) {
|
||||
super(4, size);
|
||||
this.data = new float[size];
|
||||
this.bankdata = new float[1][];
|
||||
this.bankdata[0] = this.data;
|
||||
}
|
||||
|
||||
public DataBufferFloat(int size, int numBanks) {
|
||||
super(4, size, numBanks);
|
||||
this.bankdata = new float[numBanks][];
|
||||
for (int i = 0; i < numBanks; i++)
|
||||
this.bankdata[i] = new float[size];
|
||||
this.data = this.bankdata[0];
|
||||
}
|
||||
|
||||
public DataBufferFloat(float[] dataArray, int size) {
|
||||
super(4, size);
|
||||
if (dataArray.length < size)
|
||||
throw new RuntimeException(JaiI18N.getString("DataBuffer0"));
|
||||
this.data = dataArray;
|
||||
this.bankdata = new float[1][];
|
||||
this.bankdata[0] = this.data;
|
||||
}
|
||||
|
||||
public DataBufferFloat(float[] dataArray, int size, int offset) {
|
||||
super(4, size, 1, offset);
|
||||
if (dataArray.length < size)
|
||||
throw new RuntimeException(JaiI18N.getString("DataBuffer1"));
|
||||
this.data = dataArray;
|
||||
this.bankdata = new float[1][];
|
||||
this.bankdata[0] = this.data;
|
||||
}
|
||||
|
||||
public DataBufferFloat(float[][] dataArray, int size) {
|
||||
super(4, size, dataArray.length);
|
||||
this.bankdata = dataArray;
|
||||
this.data = this.bankdata[0];
|
||||
}
|
||||
|
||||
public DataBufferFloat(float[][] dataArray, int size, int[] offsets) {
|
||||
super(4, size, dataArray.length, offsets);
|
||||
this.bankdata = dataArray;
|
||||
this.data = this.bankdata[0];
|
||||
}
|
||||
|
||||
public float[] getData() {
|
||||
return this.data;
|
||||
}
|
||||
|
||||
public float[] getData(int bank) {
|
||||
return this.bankdata[bank];
|
||||
}
|
||||
|
||||
public float[][] getBankData() {
|
||||
return this.bankdata;
|
||||
}
|
||||
|
||||
public int getElem(int i) {
|
||||
return Math.round(this.data[i + this.offset]);
|
||||
}
|
||||
|
||||
public int getElem(int bank, int i) {
|
||||
return Math.round(this.bankdata[bank][i + this.offsets[bank]]);
|
||||
}
|
||||
|
||||
public void setElem(int i, int val) {
|
||||
this.data[i + this.offset] = (float)val;
|
||||
}
|
||||
|
||||
public void setElem(int bank, int i, int val) {
|
||||
this.bankdata[bank][i + this.offsets[bank]] = (float)val;
|
||||
}
|
||||
|
||||
public float getElemFloat(int i) {
|
||||
return this.data[i + this.offset];
|
||||
}
|
||||
|
||||
public float getElemFloat(int bank, int i) {
|
||||
return this.bankdata[bank][i + this.offsets[bank]];
|
||||
}
|
||||
|
||||
public void setElemFloat(int i, float val) {
|
||||
this.data[i + this.offset] = val;
|
||||
}
|
||||
|
||||
public void setElemFloat(int bank, int i, float val) {
|
||||
this.bankdata[bank][i + this.offsets[bank]] = val;
|
||||
}
|
||||
|
||||
public double getElemDouble(int i) {
|
||||
return (double)this.data[i + this.offset];
|
||||
}
|
||||
|
||||
public double getElemDouble(int bank, int i) {
|
||||
return (double)this.bankdata[bank][i + this.offsets[bank]];
|
||||
}
|
||||
|
||||
public void setElemDouble(int i, double val) {
|
||||
this.data[i + this.offset] = (float)val;
|
||||
}
|
||||
|
||||
public void setElemDouble(int bank, int i, double val) {
|
||||
this.bankdata[bank][i + this.offsets[bank]] = (float)val;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,171 @@
|
|||
package com.sun.media.jai.codecimpl.util;
|
||||
|
||||
import java.awt.image.DataBuffer;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public final class DataBufferUtils {
|
||||
private static final String[] FLOAT_CLASS_NAMES = new String[] { "java.awt.image.DataBufferFloat", "javax.media.jai.DataBufferFloat", "com.sun.media.jai.codecimpl.util.DataBufferFloat" };
|
||||
|
||||
private static final String[] DOUBLE_CLASS_NAMES = new String[] { "java.awt.image.DataBufferDouble", "javax.media.jai.DataBufferDouble", "com.sun.media.jai.codecimpl.util.DataBufferDouble" };
|
||||
|
||||
private static Class floatClass = null;
|
||||
|
||||
private static Class doubleClass = null;
|
||||
|
||||
static Class array$$F;
|
||||
|
||||
static Class array$I;
|
||||
|
||||
static Class array$F;
|
||||
|
||||
static Class array$$D;
|
||||
|
||||
static Class array$D;
|
||||
|
||||
static {
|
||||
floatClass = getDataBufferClass(4);
|
||||
doubleClass = getDataBufferClass(5);
|
||||
}
|
||||
|
||||
private static final Class getDataBufferClass(int dataType) {
|
||||
String[] classNames = null;
|
||||
switch (dataType) {
|
||||
case 4:
|
||||
classNames = FLOAT_CLASS_NAMES;
|
||||
break;
|
||||
case 5:
|
||||
classNames = DOUBLE_CLASS_NAMES;
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("dataType == " + dataType + "!");
|
||||
}
|
||||
Class dataBufferClass = null;
|
||||
for (int i = 0; i < classNames.length; i++) {
|
||||
try {
|
||||
dataBufferClass = Class.forName(classNames[i]);
|
||||
if (dataBufferClass != null)
|
||||
break;
|
||||
} catch (ClassNotFoundException e) {}
|
||||
}
|
||||
if (dataBufferClass == null)
|
||||
throw new RuntimeException(JaiI18N.getString("DataBufferUtils0") + " " + ((dataType == 4) ? "DataBufferFloat" : "DataBufferDouble"));
|
||||
return dataBufferClass;
|
||||
}
|
||||
|
||||
private static final DataBuffer constructDataBuffer(int dataType, Class[] paramTypes, Object[] paramValues) {
|
||||
Class dbClass = null;
|
||||
switch (dataType) {
|
||||
case 4:
|
||||
dbClass = floatClass;
|
||||
break;
|
||||
case 5:
|
||||
dbClass = doubleClass;
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("dataType == " + dataType + "!");
|
||||
}
|
||||
DataBuffer dataBuffer = null;
|
||||
try {
|
||||
Constructor constructor = dbClass.getConstructor(paramTypes);
|
||||
dataBuffer = (DataBuffer)constructor.newInstance(paramValues);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(JaiI18N.getString("DataBufferUtils1"));
|
||||
}
|
||||
return dataBuffer;
|
||||
}
|
||||
|
||||
private static final Object invokeDataBufferMethod(DataBuffer dataBuffer, String methodName, Class[] paramTypes, Object[] paramValues) {
|
||||
if (dataBuffer == null)
|
||||
throw new IllegalArgumentException("dataBuffer == null!");
|
||||
Class dbClass = dataBuffer.getClass();
|
||||
Object returnValue = null;
|
||||
try {
|
||||
Method method = dbClass.getMethod(methodName, paramTypes);
|
||||
returnValue = method.invoke(dataBuffer, paramValues);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(JaiI18N.getString("DataBufferUtils2") + " \"" + methodName + "\".");
|
||||
}
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
public static final DataBuffer createDataBufferFloat(float[][] dataArray, int size) {
|
||||
return constructDataBuffer(4, new Class[] { (array$$F == null) ? (array$$F = class$("[[F")) : array$$F, int.class }, new Object[] { dataArray, new Integer(size) });
|
||||
}
|
||||
|
||||
static Class class$(String x0) {
|
||||
try {
|
||||
return Class.forName(x0);
|
||||
} catch (ClassNotFoundException x1) {
|
||||
throw new NoClassDefFoundError(x1.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public static final DataBuffer createDataBufferFloat(float[][] dataArray, int size, int[] offsets) {
|
||||
return constructDataBuffer(4, new Class[] { (array$$F == null) ? (array$$F = class$("[[F")) : array$$F, int.class, (array$I == null) ? (array$I = class$("[I")) : array$I }, new Object[] { dataArray, new Integer(size), offsets });
|
||||
}
|
||||
|
||||
public static final DataBuffer createDataBufferFloat(float[] dataArray, int size) {
|
||||
return constructDataBuffer(4, new Class[] { (array$F == null) ? (array$F = class$("[F")) : array$F, int.class }, new Object[] { dataArray, new Integer(size) });
|
||||
}
|
||||
|
||||
public static final DataBuffer createDataBufferFloat(float[] dataArray, int size, int offset) {
|
||||
return constructDataBuffer(4, new Class[] { (array$F == null) ? (array$F = class$("[F")) : array$F, int.class, int.class }, new Object[] { dataArray, new Integer(size), new Integer(offset) });
|
||||
}
|
||||
|
||||
public static final DataBuffer createDataBufferFloat(int size) {
|
||||
return constructDataBuffer(4, new Class[] { int.class }, new Object[] { new Integer(size) });
|
||||
}
|
||||
|
||||
public static final DataBuffer createDataBufferFloat(int size, int numBanks) {
|
||||
return constructDataBuffer(4, new Class[] { int.class, int.class }, new Object[] { new Integer(size), new Integer(numBanks) });
|
||||
}
|
||||
|
||||
public static final float[][] getBankDataFloat(DataBuffer dataBuffer) {
|
||||
return (float[][])invokeDataBufferMethod(dataBuffer, "getBankData", null, null);
|
||||
}
|
||||
|
||||
public static final float[] getDataFloat(DataBuffer dataBuffer) {
|
||||
return (float[])invokeDataBufferMethod(dataBuffer, "getData", null, null);
|
||||
}
|
||||
|
||||
public static final float[] getDataFloat(DataBuffer dataBuffer, int bank) {
|
||||
return (float[])invokeDataBufferMethod(dataBuffer, "getData", new Class[] { int.class }, new Object[] { new Integer(bank) });
|
||||
}
|
||||
|
||||
public static final DataBuffer createDataBufferDouble(double[][] dataArray, int size) {
|
||||
return constructDataBuffer(5, new Class[] { (array$$D == null) ? (array$$D = class$("[[D")) : array$$D, int.class }, new Object[] { dataArray, new Integer(size) });
|
||||
}
|
||||
|
||||
public static final DataBuffer createDataBufferDouble(double[][] dataArray, int size, int[] offsets) {
|
||||
return constructDataBuffer(5, new Class[] { (array$$D == null) ? (array$$D = class$("[[D")) : array$$D, int.class, (array$I == null) ? (array$I = class$("[I")) : array$I }, new Object[] { dataArray, new Integer(size), offsets });
|
||||
}
|
||||
|
||||
public static final DataBuffer createDataBufferDouble(double[] dataArray, int size) {
|
||||
return constructDataBuffer(5, new Class[] { (array$D == null) ? (array$D = class$("[D")) : array$D, int.class }, new Object[] { dataArray, new Integer(size) });
|
||||
}
|
||||
|
||||
public static final DataBuffer createDataBufferDouble(double[] dataArray, int size, int offset) {
|
||||
return constructDataBuffer(5, new Class[] { (array$D == null) ? (array$D = class$("[D")) : array$D, int.class, int.class }, new Object[] { dataArray, new Integer(size), new Integer(offset) });
|
||||
}
|
||||
|
||||
public static final DataBuffer createDataBufferDouble(int size) {
|
||||
return constructDataBuffer(5, new Class[] { int.class }, new Object[] { new Integer(size) });
|
||||
}
|
||||
|
||||
public static final DataBuffer createDataBufferDouble(int size, int numBanks) {
|
||||
return constructDataBuffer(5, new Class[] { int.class, int.class }, new Object[] { new Integer(size), new Integer(numBanks) });
|
||||
}
|
||||
|
||||
public static final double[][] getBankDataDouble(DataBuffer dataBuffer) {
|
||||
return (double[][])invokeDataBufferMethod(dataBuffer, "getBankData", null, null);
|
||||
}
|
||||
|
||||
public static final double[] getDataDouble(DataBuffer dataBuffer) {
|
||||
return (double[])invokeDataBufferMethod(dataBuffer, "getData", null, null);
|
||||
}
|
||||
|
||||
public static final double[] getDataDouble(DataBuffer dataBuffer, int bank) {
|
||||
return (double[])invokeDataBufferMethod(dataBuffer, "getData", new Class[] { int.class }, new Object[] { new Integer(bank) });
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,514 @@
|
|||
package com.sun.media.jai.codecimpl.util;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.awt.color.ColorSpace;
|
||||
import java.awt.image.ColorModel;
|
||||
import java.awt.image.ComponentColorModel;
|
||||
import java.awt.image.Raster;
|
||||
import java.awt.image.SampleModel;
|
||||
import java.awt.image.WritableRaster;
|
||||
|
||||
public class FloatDoubleColorModel extends ComponentColorModel {
|
||||
protected ColorSpace colorSpace;
|
||||
|
||||
protected int colorSpaceType;
|
||||
|
||||
protected int numColorComponents;
|
||||
|
||||
protected int numComponents;
|
||||
|
||||
protected int transparency;
|
||||
|
||||
protected boolean hasAlpha;
|
||||
|
||||
protected boolean isAlphaPremultiplied;
|
||||
|
||||
private static int[] bitsHelper(int transferType, ColorSpace colorSpace, boolean hasAlpha) {
|
||||
int numBits = (transferType == 4) ? 32 : 64;
|
||||
int numComponents = colorSpace.getNumComponents();
|
||||
if (hasAlpha)
|
||||
numComponents++;
|
||||
int[] bits = new int[numComponents];
|
||||
for (int i = 0; i < numComponents; i++)
|
||||
bits[i] = numBits;
|
||||
return bits;
|
||||
}
|
||||
|
||||
public FloatDoubleColorModel(ColorSpace colorSpace, boolean hasAlpha, boolean isAlphaPremultiplied, int transparency, int transferType) {
|
||||
super(colorSpace, bitsHelper(transferType, colorSpace, hasAlpha), hasAlpha, isAlphaPremultiplied, transparency, transferType);
|
||||
if (transferType != 4 && transferType != 5)
|
||||
throw new IllegalArgumentException(JaiI18N.getString("FloatDoubleColorModel0"));
|
||||
this.colorSpace = colorSpace;
|
||||
this.colorSpaceType = colorSpace.getType();
|
||||
this.numComponents = this.numColorComponents = colorSpace.getNumComponents();
|
||||
if (hasAlpha)
|
||||
this.numComponents++;
|
||||
this.transparency = transparency;
|
||||
this.hasAlpha = hasAlpha;
|
||||
this.isAlphaPremultiplied = isAlphaPremultiplied;
|
||||
}
|
||||
|
||||
public int getRed(int pixel) {
|
||||
throw new IllegalArgumentException(JaiI18N.getString("FloatDoubleColorModel1"));
|
||||
}
|
||||
|
||||
public int getGreen(int pixel) {
|
||||
throw new IllegalArgumentException(JaiI18N.getString("FloatDoubleColorModel2"));
|
||||
}
|
||||
|
||||
public int getBlue(int pixel) {
|
||||
throw new IllegalArgumentException(JaiI18N.getString("FloatDoubleColorModel3"));
|
||||
}
|
||||
|
||||
public int getAlpha(int pixel) {
|
||||
throw new IllegalArgumentException(JaiI18N.getString("FloatDoubleColorModel4"));
|
||||
}
|
||||
|
||||
public int getRGB(int pixel) {
|
||||
throw new IllegalArgumentException(JaiI18N.getString("FloatDoubleColorModel5"));
|
||||
}
|
||||
|
||||
private final int clamp(float value) {
|
||||
return (value >= 0.0F) ? ((value > 255.0F) ? 255 : (int)value) : 0;
|
||||
}
|
||||
|
||||
private final int clamp(double value) {
|
||||
return (value >= 0.0D) ? ((value > 255.0D) ? 255 : (int)value) : 0;
|
||||
}
|
||||
|
||||
private int getSample(Object inData, int sample) {
|
||||
float[] rgb;
|
||||
boolean needAlpha = (this.hasAlpha && this.isAlphaPremultiplied);
|
||||
int type = this.colorSpaceType;
|
||||
boolean is_sRGB = this.colorSpace.isCS_sRGB();
|
||||
if (type == 6) {
|
||||
sample = 0;
|
||||
is_sRGB = true;
|
||||
}
|
||||
if (is_sRGB) {
|
||||
if (this.transferType == 4) {
|
||||
float[] fdata = (float[])inData;
|
||||
float fsample = fdata[sample] * 255.0F;
|
||||
if (needAlpha) {
|
||||
float falp = fdata[this.numColorComponents];
|
||||
if ((double)falp == 0.0D)
|
||||
return 0;
|
||||
return clamp(fsample / falp);
|
||||
}
|
||||
return clamp(fsample);
|
||||
}
|
||||
double[] arrayOfDouble = (double[])inData;
|
||||
double dsample = arrayOfDouble[sample] * 255.0D;
|
||||
if (needAlpha) {
|
||||
double dalp = arrayOfDouble[this.numColorComponents];
|
||||
if (dalp == 0.0D)
|
||||
return 0;
|
||||
return clamp(dsample / dalp);
|
||||
}
|
||||
return clamp(dsample);
|
||||
}
|
||||
if (this.transferType == 4) {
|
||||
float[] fdata = (float[])inData;
|
||||
if (needAlpha) {
|
||||
float falp = fdata[this.numColorComponents];
|
||||
if ((double)falp == 0.0D)
|
||||
return 0;
|
||||
float[] arrayOfFloat = new float[this.numColorComponents];
|
||||
for (int i = 0; i < this.numColorComponents; i++)
|
||||
arrayOfFloat[i] = fdata[i] / falp;
|
||||
rgb = this.colorSpace.toRGB(arrayOfFloat);
|
||||
} else {
|
||||
rgb = this.colorSpace.toRGB(fdata);
|
||||
}
|
||||
return (int)(rgb[sample] * 255.0F + 0.5F);
|
||||
}
|
||||
double[] ddata = (double[])inData;
|
||||
float[] norm = new float[this.numColorComponents];
|
||||
if (needAlpha) {
|
||||
double dalp = ddata[this.numColorComponents];
|
||||
if (dalp == 0.0D)
|
||||
return 0;
|
||||
for (int i = 0; i < this.numColorComponents; i++)
|
||||
norm[i] = (float)(ddata[i] / dalp);
|
||||
rgb = this.colorSpace.toRGB(norm);
|
||||
} else {
|
||||
for (int i = 0; i < this.numColorComponents; i++)
|
||||
norm[i] = (float)ddata[i];
|
||||
rgb = this.colorSpace.toRGB(norm);
|
||||
}
|
||||
return (int)((double)(rgb[sample] * 255.0F) + 0.5D);
|
||||
}
|
||||
|
||||
public int getRed(Object inData) {
|
||||
return getSample(inData, 0);
|
||||
}
|
||||
|
||||
public int getGreen(Object inData) {
|
||||
return getSample(inData, 1);
|
||||
}
|
||||
|
||||
public int getBlue(Object inData) {
|
||||
return getSample(inData, 2);
|
||||
}
|
||||
|
||||
public int getAlpha(Object inData) {
|
||||
if (inData == null)
|
||||
throw new IllegalArgumentException(JaiI18N.getString("Generic0"));
|
||||
if (!this.hasAlpha)
|
||||
return 255;
|
||||
if (this.transferType == 4) {
|
||||
float[] fdata = (float[])inData;
|
||||
return (int)(fdata[this.numColorComponents] * 255.0F + 0.5F);
|
||||
}
|
||||
double[] ddata = (double[])inData;
|
||||
return (int)(ddata[this.numColorComponents] * 255.0D + 0.5D);
|
||||
}
|
||||
|
||||
public int getRGB(Object inData) {
|
||||
int red, green, blue;
|
||||
boolean needAlpha = (this.hasAlpha && this.isAlphaPremultiplied);
|
||||
int alpha = 255;
|
||||
if (this.colorSpace.isCS_sRGB()) {
|
||||
if (this.transferType == 4) {
|
||||
float[] fdata = (float[])inData;
|
||||
float fred = fdata[0];
|
||||
float fgreen = fdata[1];
|
||||
float fblue = fdata[2];
|
||||
float fscale = 255.0F;
|
||||
if (needAlpha) {
|
||||
float falpha = fdata[3];
|
||||
fscale /= falpha;
|
||||
alpha = clamp(255.0F * falpha);
|
||||
}
|
||||
red = clamp(fred * fscale);
|
||||
green = clamp(fgreen * fscale);
|
||||
blue = clamp(fblue * fscale);
|
||||
} else {
|
||||
double[] ddata = (double[])inData;
|
||||
double dred = ddata[0];
|
||||
double dgreen = ddata[1];
|
||||
double dblue = ddata[2];
|
||||
double dscale = 255.0D;
|
||||
if (needAlpha) {
|
||||
double dalpha = ddata[3];
|
||||
dscale /= dalpha;
|
||||
alpha = clamp(255.0D * dalpha);
|
||||
}
|
||||
red = clamp(dred * dscale);
|
||||
green = clamp(dgreen * dscale);
|
||||
blue = clamp(dblue * dscale);
|
||||
}
|
||||
} else if (this.colorSpaceType == 6) {
|
||||
if (this.transferType == 4) {
|
||||
float[] fdata = (float[])inData;
|
||||
float fgray = fdata[0];
|
||||
if (needAlpha) {
|
||||
float falp = fdata[1];
|
||||
red = green = blue = clamp(fgray * 255.0F / falp);
|
||||
alpha = clamp(255.0F * falp);
|
||||
} else {
|
||||
red = green = blue = clamp(fgray * 255.0F);
|
||||
}
|
||||
} else {
|
||||
double[] ddata = (double[])inData;
|
||||
double dgray = ddata[0];
|
||||
if (needAlpha) {
|
||||
double dalp = ddata[1];
|
||||
red = green = blue = clamp(dgray * 255.0D / dalp);
|
||||
alpha = clamp(255.0D * dalp);
|
||||
} else {
|
||||
red = green = blue = clamp(dgray * 255.0D);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
float[] norm;
|
||||
if (this.transferType == 4) {
|
||||
float[] fdata = (float[])inData;
|
||||
if (needAlpha) {
|
||||
float falp = fdata[this.numColorComponents];
|
||||
float invfalp = 1.0F / falp;
|
||||
norm = new float[this.numColorComponents];
|
||||
for (int i = 0; i < this.numColorComponents; i++)
|
||||
norm[i] = fdata[i] * invfalp;
|
||||
alpha = clamp(255.0F * falp);
|
||||
} else {
|
||||
norm = fdata;
|
||||
}
|
||||
} else {
|
||||
double[] ddata = (double[])inData;
|
||||
norm = new float[this.numColorComponents];
|
||||
if (needAlpha) {
|
||||
double dalp = ddata[this.numColorComponents];
|
||||
double invdalp = 1.0D / dalp;
|
||||
for (int i = 0; i < this.numColorComponents; i++)
|
||||
norm[i] = (float)(ddata[i] * invdalp);
|
||||
alpha = clamp(255.0D * dalp);
|
||||
} else {
|
||||
for (int i = 0; i < this.numColorComponents; i++)
|
||||
norm[i] = (float)ddata[i];
|
||||
}
|
||||
}
|
||||
float[] rgb = this.colorSpace.toRGB(norm);
|
||||
red = clamp(rgb[0] * 255.0F);
|
||||
green = clamp(rgb[1] * 255.0F);
|
||||
blue = clamp(rgb[2] * 255.0F);
|
||||
}
|
||||
return alpha << 24 | red << 16 | green << 8 | blue;
|
||||
}
|
||||
|
||||
public Object getDataElements(int rgb, Object pixel) {
|
||||
double[] doublePixel;
|
||||
if (this.transferType == 4) {
|
||||
float[] floatPixel;
|
||||
if (pixel == null) {
|
||||
floatPixel = new float[this.numComponents];
|
||||
} else {
|
||||
if (!(pixel instanceof float[]))
|
||||
throw new ClassCastException(JaiI18N.getString("FloatDoubleColorModel7"));
|
||||
floatPixel = (float[])pixel;
|
||||
if (floatPixel.length < this.numComponents)
|
||||
throw new ArrayIndexOutOfBoundsException(JaiI18N.getString("FloatDoubleColorModel8"));
|
||||
}
|
||||
float f = 0.003921569F;
|
||||
if (this.colorSpace.isCS_sRGB()) {
|
||||
int alp = rgb >> 24 & 0xFF;
|
||||
int red = rgb >> 16 & 0xFF;
|
||||
int grn = rgb >> 8 & 0xFF;
|
||||
int blu = rgb & 0xFF;
|
||||
float norm = f;
|
||||
if (this.isAlphaPremultiplied)
|
||||
norm *= (float)alp;
|
||||
floatPixel[0] = (float)red * norm;
|
||||
floatPixel[1] = (float)grn * norm;
|
||||
floatPixel[2] = (float)blu * norm;
|
||||
if (this.hasAlpha)
|
||||
floatPixel[3] = (float)alp * f;
|
||||
} else if (this.colorSpaceType == 6) {
|
||||
float gray = (float)(rgb >> 16 & 0xFF) * 0.299F * f + (float)(rgb >> 8 & 0xFF) * 0.587F * f + (float)(rgb & 0xFF) * 0.114F * f;
|
||||
floatPixel[0] = gray;
|
||||
if (this.hasAlpha) {
|
||||
int alpha = rgb >> 24 & 0xFF;
|
||||
floatPixel[1] = (float)alpha * f;
|
||||
}
|
||||
} else {
|
||||
float[] norm = new float[3];
|
||||
norm[0] = (float)(rgb >> 16 & 0xFF) * f;
|
||||
norm[1] = (float)(rgb >> 8 & 0xFF) * f;
|
||||
norm[2] = (float)(rgb & 0xFF) * f;
|
||||
norm = this.colorSpace.fromRGB(norm);
|
||||
for (int i = 0; i < this.numColorComponents; i++)
|
||||
floatPixel[i] = norm[i];
|
||||
if (this.hasAlpha) {
|
||||
int alpha = rgb >> 24 & 0xFF;
|
||||
floatPixel[this.numColorComponents] = (float)alpha * f;
|
||||
}
|
||||
}
|
||||
return floatPixel;
|
||||
}
|
||||
if (pixel == null) {
|
||||
doublePixel = new double[this.numComponents];
|
||||
} else {
|
||||
if (!(pixel instanceof double[]))
|
||||
throw new ClassCastException(JaiI18N.getString("FloatDoubleColorModel7"));
|
||||
doublePixel = (double[])pixel;
|
||||
if (doublePixel.length < this.numComponents)
|
||||
throw new ArrayIndexOutOfBoundsException(JaiI18N.getString("FloatDoubleColorModel8"));
|
||||
}
|
||||
double inv255 = 0.00392156862745098D;
|
||||
if (this.colorSpace.isCS_sRGB()) {
|
||||
int alp = rgb >> 24 & 0xFF;
|
||||
int red = rgb >> 16 & 0xFF;
|
||||
int grn = rgb >> 8 & 0xFF;
|
||||
int blu = rgb & 0xFF;
|
||||
double norm = inv255;
|
||||
if (this.isAlphaPremultiplied)
|
||||
norm *= (double)alp;
|
||||
doublePixel[0] = (double)red * norm;
|
||||
doublePixel[1] = (double)grn * norm;
|
||||
doublePixel[2] = (double)blu * norm;
|
||||
if (this.hasAlpha)
|
||||
doublePixel[3] = (double)alp * inv255;
|
||||
} else if (this.colorSpaceType == 6) {
|
||||
double gray = (double)(rgb >> 16 & 0xFF) * 0.299D * inv255 + (double)(rgb >> 8 & 0xFF) * 0.587D * inv255 + (double)(rgb & 0xFF) * 0.114D * inv255;
|
||||
doublePixel[0] = gray;
|
||||
if (this.hasAlpha) {
|
||||
int alpha = rgb >> 24 & 0xFF;
|
||||
doublePixel[1] = (double)alpha * inv255;
|
||||
}
|
||||
} else {
|
||||
float inv255F = 0.003921569F;
|
||||
float[] norm = new float[3];
|
||||
norm[0] = (float)(rgb >> 16 & 0xFF) * inv255F;
|
||||
norm[1] = (float)(rgb >> 8 & 0xFF) * inv255F;
|
||||
norm[2] = (float)(rgb & 0xFF) * inv255F;
|
||||
norm = this.colorSpace.fromRGB(norm);
|
||||
for (int i = 0; i < this.numColorComponents; i++)
|
||||
doublePixel[i] = (double)norm[i];
|
||||
if (this.hasAlpha) {
|
||||
int alpha = rgb >> 24 & 0xFF;
|
||||
doublePixel[this.numColorComponents] = (double)alpha * inv255;
|
||||
}
|
||||
}
|
||||
return doublePixel;
|
||||
}
|
||||
|
||||
public int[] getComponents(int pixel, int[] components, int offset) {
|
||||
throw new IllegalArgumentException(JaiI18N.getString("FloatDoubleColorModel9"));
|
||||
}
|
||||
|
||||
public int[] getComponents(Object pixel, int[] components, int offset) {
|
||||
throw new IllegalArgumentException(JaiI18N.getString("FloatDoubleColorModel9"));
|
||||
}
|
||||
|
||||
public int getDataElement(int[] components, int offset) {
|
||||
throw new IllegalArgumentException(JaiI18N.getString("FloatDoubleColorModel9"));
|
||||
}
|
||||
|
||||
public Object getDataElements(int[] components, int offset, Object obj) {
|
||||
double[] pixel;
|
||||
if (components.length - offset < this.numComponents)
|
||||
throw new IllegalArgumentException(this.numComponents + " " + JaiI18N.getString("FloatDoubleColorModel10"));
|
||||
if (this.transferType == 4) {
|
||||
float[] arrayOfFloat;
|
||||
if (obj == null) {
|
||||
arrayOfFloat = new float[components.length];
|
||||
} else {
|
||||
arrayOfFloat = (float[])obj;
|
||||
}
|
||||
for (int j = 0; j < this.numComponents; j++)
|
||||
arrayOfFloat[j] = (float)components[offset + j];
|
||||
return arrayOfFloat;
|
||||
}
|
||||
if (obj == null) {
|
||||
pixel = new double[components.length];
|
||||
} else {
|
||||
pixel = (double[])obj;
|
||||
}
|
||||
for (int i = 0; i < this.numComponents; i++)
|
||||
pixel[i] = (double)components[offset + i];
|
||||
return pixel;
|
||||
}
|
||||
|
||||
public ColorModel coerceData(WritableRaster raster, boolean isAlphaPremultiplied) {
|
||||
if (!this.hasAlpha || this.isAlphaPremultiplied == isAlphaPremultiplied)
|
||||
return this;
|
||||
int w = raster.getWidth();
|
||||
int h = raster.getHeight();
|
||||
int aIdx = raster.getNumBands() - 1;
|
||||
int rminX = raster.getMinX();
|
||||
int rY = raster.getMinY();
|
||||
if (raster.getTransferType() != this.transferType)
|
||||
throw new IllegalArgumentException(JaiI18N.getString("FloatDoubleColorModel6"));
|
||||
if (isAlphaPremultiplied) {
|
||||
float[] arrayOfFloat;
|
||||
double[] pixel;
|
||||
int y;
|
||||
switch (this.transferType) {
|
||||
case 4:
|
||||
arrayOfFloat = null;
|
||||
for (y = 0; y < h; y++, rY++) {
|
||||
int rX = rminX;
|
||||
for (int x = 0; x < w; x++, rX++) {
|
||||
arrayOfFloat = (float[])raster.getDataElements(rX, rY, arrayOfFloat);
|
||||
float fAlpha = arrayOfFloat[aIdx];
|
||||
if (fAlpha != 0.0F) {
|
||||
for (int c = 0; c < aIdx; c++)
|
||||
arrayOfFloat[c] = arrayOfFloat[c] * fAlpha;
|
||||
raster.setDataElements(rX, rY, arrayOfFloat);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
pixel = null;
|
||||
for (y = 0; y < h; y++, rY++) {
|
||||
int rX = rminX;
|
||||
for (int x = 0; x < w; x++, rX++) {
|
||||
pixel = (double[])raster.getDataElements(rX, rY, pixel);
|
||||
double dAlpha = pixel[aIdx];
|
||||
if (dAlpha != 0.0D) {
|
||||
for (int c = 0; c < aIdx; c++)
|
||||
pixel[c] = pixel[c] * dAlpha;
|
||||
raster.setDataElements(rX, rY, pixel);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException(JaiI18N.getString("FloatDoubleColorModel0"));
|
||||
}
|
||||
if (isAlphaPremultiplied);
|
||||
} else {
|
||||
int y;
|
||||
switch (this.transferType) {
|
||||
case 4:
|
||||
for (y = 0; y < h; y++, rY++) {
|
||||
int rX = rminX;
|
||||
for (int x = 0; x < w; x++, rX++) {
|
||||
float[] pixel = null;
|
||||
pixel = (float[])raster.getDataElements(rX, rY, pixel);
|
||||
float fAlpha = pixel[aIdx];
|
||||
if (fAlpha != 0.0F) {
|
||||
float invFAlpha = 1.0F / fAlpha;
|
||||
for (int c = 0; c < aIdx; c++)
|
||||
pixel[c] = pixel[c] * invFAlpha;
|
||||
}
|
||||
raster.setDataElements(rX, rY, pixel);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
for (y = 0; y < h; y++, rY++) {
|
||||
int rX = rminX;
|
||||
for (int x = 0; x < w; x++, rX++) {
|
||||
double[] pixel = null;
|
||||
pixel = (double[])raster.getDataElements(rX, rY, pixel);
|
||||
double dAlpha = pixel[aIdx];
|
||||
if (dAlpha != 0.0D) {
|
||||
double invDAlpha = 1.0D / dAlpha;
|
||||
for (int c = 0; c < aIdx; c++)
|
||||
pixel[c] = pixel[c] * invDAlpha;
|
||||
}
|
||||
raster.setDataElements(rX, rY, pixel);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException(JaiI18N.getString("FloatDoubleColorModel0"));
|
||||
}
|
||||
}
|
||||
return new FloatDoubleColorModel(this.colorSpace, this.hasAlpha, isAlphaPremultiplied, this.transparency, this.transferType);
|
||||
}
|
||||
|
||||
public boolean isCompatibleRaster(Raster raster) {
|
||||
SampleModel sm = raster.getSampleModel();
|
||||
return isCompatibleSampleModel(sm);
|
||||
}
|
||||
|
||||
public WritableRaster createCompatibleWritableRaster(int w, int h) {
|
||||
SampleModel sm = createCompatibleSampleModel(w, h);
|
||||
return RasterFactory.createWritableRaster(sm, new Point(0, 0));
|
||||
}
|
||||
|
||||
public SampleModel createCompatibleSampleModel(int w, int h) {
|
||||
int[] bandOffsets = new int[this.numComponents];
|
||||
for (int i = 0; i < this.numComponents; i++)
|
||||
bandOffsets[i] = i;
|
||||
return new ComponentSampleModelJAI(this.transferType, w, h, this.numComponents, w * this.numComponents, bandOffsets);
|
||||
}
|
||||
|
||||
public boolean isCompatibleSampleModel(SampleModel sm) {
|
||||
if (sm instanceof java.awt.image.ComponentSampleModel) {
|
||||
if (sm.getNumBands() != getNumComponents())
|
||||
return false;
|
||||
if (sm.getDataType() != this.transferType)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "FloatDoubleColorModel: " + super.toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
package com.sun.media.jai.codecimpl.util;
|
||||
|
||||
import java.io.PrintStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.security.PrivilegedActionException;
|
||||
|
||||
public class ImagingException extends RuntimeException {
|
||||
private Throwable cause = null;
|
||||
|
||||
public ImagingException() {}
|
||||
|
||||
public ImagingException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public ImagingException(Throwable cause) {
|
||||
this.cause = cause;
|
||||
}
|
||||
|
||||
public ImagingException(String message, Throwable cause) {
|
||||
super(message);
|
||||
this.cause = cause;
|
||||
}
|
||||
|
||||
public Throwable getCause() {
|
||||
return this.cause;
|
||||
}
|
||||
|
||||
public Throwable getRootCause() {
|
||||
Throwable rootCause = this.cause;
|
||||
Throwable atop = this;
|
||||
while (rootCause != atop && rootCause != null) {
|
||||
try {
|
||||
atop = rootCause;
|
||||
Method getCause = rootCause.getClass().getMethod("getCause", null);
|
||||
rootCause = (Throwable)getCause.invoke(rootCause, null);
|
||||
} catch (Exception e) {
|
||||
if (rootCause instanceof InvocationTargetException) {
|
||||
rootCause = ((InvocationTargetException)rootCause).getTargetException();
|
||||
} else if (rootCause instanceof PrivilegedActionException) {
|
||||
rootCause = ((PrivilegedActionException)rootCause).getException();
|
||||
} else {
|
||||
rootCause = atop;
|
||||
}
|
||||
} finally {
|
||||
if (rootCause == null)
|
||||
rootCause = atop;
|
||||
}
|
||||
}
|
||||
return rootCause;
|
||||
}
|
||||
|
||||
public void printStackTrace() {
|
||||
printStackTrace(System.err);
|
||||
}
|
||||
|
||||
public void printStackTrace(PrintStream s) {
|
||||
synchronized (s) {
|
||||
super.printStackTrace(s);
|
||||
boolean is14 = false;
|
||||
try {
|
||||
String version = System.getProperty("java.version");
|
||||
is14 = (version.indexOf("1.4") >= 0);
|
||||
} catch (Exception e) {}
|
||||
if (!is14 && this.cause != null) {
|
||||
s.println("Caused by:");
|
||||
this.cause.printStackTrace(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void printStackTrace(PrintWriter s) {
|
||||
synchronized (s) {
|
||||
super.printStackTrace(s);
|
||||
boolean is14 = false;
|
||||
try {
|
||||
String version = System.getProperty("java.version");
|
||||
is14 = (version.indexOf("1.4") >= 0);
|
||||
} catch (Exception e) {}
|
||||
if (!is14 && this.cause != null) {
|
||||
s.println("Caused by:");
|
||||
this.cause.printStackTrace(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
package com.sun.media.jai.codecimpl.util;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import java.util.Locale;
|
||||
|
||||
class JaiI18N {
|
||||
static String packageName = "com.sun.media.jai.codecimpl.util";
|
||||
|
||||
public static String getString(String key) {
|
||||
return PropertyUtil.getString(packageName, key);
|
||||
}
|
||||
|
||||
public static String formatMsg(String key, Object[] args) {
|
||||
MessageFormat mf = new MessageFormat(getString(key));
|
||||
mf.setLocale(Locale.getDefault());
|
||||
return mf.format(args);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,142 @@
|
|||
package com.sun.media.jai.codecimpl.util;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.security.AccessControlException;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Iterator;
|
||||
import java.util.PropertyResourceBundle;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.Vector;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarFile;
|
||||
|
||||
public class PropertyUtil {
|
||||
private static Hashtable bundles = new Hashtable();
|
||||
|
||||
private static String propertiesDir = "com/sun/media/jai/codec";
|
||||
|
||||
public static InputStream getFileFromClasspath(String path) throws IOException, FileNotFoundException {
|
||||
String pathFinal = path;
|
||||
String sep = File.separator;
|
||||
String tmpHome = null;
|
||||
try {
|
||||
tmpHome = System.getProperty("java.home");
|
||||
} catch (Exception e) {
|
||||
tmpHome = null;
|
||||
}
|
||||
String home = tmpHome;
|
||||
String urlHeader = (tmpHome == null) ? null : (home + sep + "lib" + sep);
|
||||
if (home != null) {
|
||||
String libExtPath = urlHeader + "ext" + sep + path;
|
||||
File libExtFile = new File(libExtPath);
|
||||
try {
|
||||
if (libExtFile.exists()) {
|
||||
InputStream inputStream = new FileInputStream(libExtFile);
|
||||
if (inputStream != null)
|
||||
return inputStream;
|
||||
}
|
||||
} catch (AccessControlException e) {}
|
||||
}
|
||||
InputStream is = PropertyUtil.class.getResourceAsStream("/" + path);
|
||||
if (is != null)
|
||||
return is;
|
||||
PrivilegedAction p = new PrivilegedAction(home, urlHeader, sep, pathFinal) {
|
||||
private final String val$home;
|
||||
|
||||
private final String val$urlHeader;
|
||||
|
||||
private final String val$sep;
|
||||
|
||||
private final String val$pathFinal;
|
||||
|
||||
{
|
||||
this.val$home = val$home;
|
||||
this.val$urlHeader = val$urlHeader;
|
||||
this.val$sep = val$sep;
|
||||
this.val$pathFinal = val$pathFinal;
|
||||
}
|
||||
|
||||
public Object run() {
|
||||
String localHome = null;
|
||||
String localUrlHeader = null;
|
||||
if (this.val$home != null) {
|
||||
localHome = this.val$home;
|
||||
localUrlHeader = this.val$urlHeader;
|
||||
} else {
|
||||
localHome = System.getProperty("java.home");
|
||||
localUrlHeader = localHome + this.val$sep + "lib" + this.val$sep;
|
||||
}
|
||||
String[] filenames = { localUrlHeader + "ext" + this.val$sep + "jai_core.jar", localUrlHeader + "ext" + this.val$sep + "jai_codec.jar", localUrlHeader + "jai_core.jar", localUrlHeader + "jai_codec.jar" };
|
||||
for (int i = 0; i < filenames.length; i++) {
|
||||
try {
|
||||
InputStream tmpIS = PropertyUtil.getFileFromJar(filenames[i], this.val$pathFinal);
|
||||
if (tmpIS != null)
|
||||
return tmpIS;
|
||||
} catch (Exception e) {}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
return (InputStream)AccessController.doPrivileged(p);
|
||||
}
|
||||
|
||||
private static InputStream getFileFromJar(String jarFilename, String path) throws Exception {
|
||||
JarFile f = null;
|
||||
try {
|
||||
f = new JarFile(jarFilename);
|
||||
} catch (Exception e) {}
|
||||
JarEntry ent = f.getJarEntry(path);
|
||||
if (ent != null)
|
||||
return f.getInputStream(ent);
|
||||
return null;
|
||||
}
|
||||
|
||||
private static ResourceBundle getBundle(String packageName) {
|
||||
ResourceBundle bundle = null;
|
||||
InputStream in = null;
|
||||
try {
|
||||
in = getFileFromClasspath(propertiesDir + "/" + packageName + ".properties");
|
||||
if (in != null) {
|
||||
bundle = new PropertyResourceBundle(in);
|
||||
bundles.put(packageName, bundle);
|
||||
return bundle;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String getString(String packageName, String key) {
|
||||
ResourceBundle b = (ResourceBundle)bundles.get(packageName);
|
||||
if (b == null)
|
||||
b = getBundle(packageName);
|
||||
return b.getString(key);
|
||||
}
|
||||
|
||||
public static String[] getPropertyNames(String[] propertyNames, String prefix) {
|
||||
if (propertyNames == null)
|
||||
return null;
|
||||
if (prefix == null)
|
||||
throw new IllegalArgumentException(JaiI18N.getString("PropertyUtil0"));
|
||||
prefix = prefix.toLowerCase();
|
||||
Vector names = new Vector();
|
||||
for (int i = 0; i < propertyNames.length; i++) {
|
||||
if (propertyNames[i].toLowerCase().startsWith(prefix))
|
||||
names.addElement(propertyNames[i]);
|
||||
}
|
||||
if (names.size() == 0)
|
||||
return null;
|
||||
String[] arrayOfString = new String[names.size()];
|
||||
int count = 0;
|
||||
for (Iterator it = names.iterator(); it.hasNext();)
|
||||
arrayOfString[count++] = (String)it.next();
|
||||
return arrayOfString;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,319 @@
|
|||
package com.sun.media.jai.codecimpl.util;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.awt.color.ColorSpace;
|
||||
import java.awt.image.ComponentColorModel;
|
||||
import java.awt.image.DataBuffer;
|
||||
import java.awt.image.DataBufferByte;
|
||||
import java.awt.image.DataBufferInt;
|
||||
import java.awt.image.DataBufferShort;
|
||||
import java.awt.image.DataBufferUShort;
|
||||
import java.awt.image.PixelInterleavedSampleModel;
|
||||
import java.awt.image.Raster;
|
||||
import java.awt.image.SampleModel;
|
||||
import java.awt.image.WritableRaster;
|
||||
|
||||
public class RasterFactory {
|
||||
public static WritableRaster createInterleavedRaster(int dataType, int width, int height, int numBands, Point location) {
|
||||
if (numBands < 1)
|
||||
throw new IllegalArgumentException(JaiI18N.getString("RasterFactory0"));
|
||||
int[] bandOffsets = new int[numBands];
|
||||
for (int i = 0; i < numBands; i++)
|
||||
bandOffsets[i] = numBands - 1 - i;
|
||||
return createInterleavedRaster(dataType, width, height, width * numBands, numBands, bandOffsets, location);
|
||||
}
|
||||
|
||||
public static WritableRaster createInterleavedRaster(int dataType, int width, int height, int scanlineStride, int pixelStride, int[] bandOffsets, Point location) {
|
||||
DataBuffer d;
|
||||
if (bandOffsets == null)
|
||||
throw new IllegalArgumentException(JaiI18N.getString("RasterFactory4"));
|
||||
int bands = bandOffsets.length;
|
||||
int maxBandOff = bandOffsets[0];
|
||||
for (int i = 1; i < bands; i++) {
|
||||
if (bandOffsets[i] > maxBandOff)
|
||||
maxBandOff = bandOffsets[i];
|
||||
}
|
||||
long lsize = (long)maxBandOff + (long)scanlineStride * (long)(height - 1) + (long)pixelStride * (long)(width - 1) + 1L;
|
||||
if (lsize > Integer.MAX_VALUE)
|
||||
throw new IllegalArgumentException(JaiI18N.getString("RasterFactory16"));
|
||||
int size = (int)lsize;
|
||||
switch (dataType) {
|
||||
case 0:
|
||||
d = new DataBufferByte(size);
|
||||
break;
|
||||
case 1:
|
||||
d = new DataBufferUShort(size);
|
||||
break;
|
||||
case 2:
|
||||
d = new DataBufferShort(size);
|
||||
break;
|
||||
case 3:
|
||||
d = new DataBufferInt(size);
|
||||
break;
|
||||
case 4:
|
||||
d = DataBufferUtils.createDataBufferFloat(size);
|
||||
break;
|
||||
case 5:
|
||||
d = DataBufferUtils.createDataBufferDouble(size);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException(JaiI18N.getString("RasterFactory3"));
|
||||
}
|
||||
return createInterleavedRaster(d, width, height, scanlineStride, pixelStride, bandOffsets, location);
|
||||
}
|
||||
|
||||
public static WritableRaster createBandedRaster(int dataType, int width, int height, int bands, Point location) {
|
||||
if (bands < 1)
|
||||
throw new IllegalArgumentException(JaiI18N.getString("RasterFactory0"));
|
||||
int[] bankIndices = new int[bands];
|
||||
int[] bandOffsets = new int[bands];
|
||||
for (int i = 0; i < bands; i++) {
|
||||
bankIndices[i] = i;
|
||||
bandOffsets[i] = 0;
|
||||
}
|
||||
return createBandedRaster(dataType, width, height, width, bankIndices, bandOffsets, location);
|
||||
}
|
||||
|
||||
public static WritableRaster createBandedRaster(int dataType, int width, int height, int scanlineStride, int[] bankIndices, int[] bandOffsets, Point location) {
|
||||
DataBuffer d;
|
||||
int bands = bandOffsets.length;
|
||||
if (bankIndices == null)
|
||||
throw new IllegalArgumentException(JaiI18N.getString("RasterFactory1"));
|
||||
if (bandOffsets == null)
|
||||
throw new IllegalArgumentException(JaiI18N.getString("RasterFactory4"));
|
||||
if (bandOffsets.length != bankIndices.length)
|
||||
throw new IllegalArgumentException(JaiI18N.getString("RasterFactory2"));
|
||||
int maxBank = bankIndices[0];
|
||||
int maxBandOff = bandOffsets[0];
|
||||
for (int i = 1; i < bands; i++) {
|
||||
if (bankIndices[i] > maxBank)
|
||||
maxBank = bankIndices[i];
|
||||
if (bandOffsets[i] > maxBandOff)
|
||||
maxBandOff = bandOffsets[i];
|
||||
}
|
||||
int banks = maxBank + 1;
|
||||
long lsize = (long)maxBandOff + (long)scanlineStride * (long)(height - 1) + (long)(width - 1) + 1L;
|
||||
if (lsize > Integer.MAX_VALUE)
|
||||
throw new IllegalArgumentException(JaiI18N.getString("RasterFactory16"));
|
||||
int size = (int)lsize;
|
||||
switch (dataType) {
|
||||
case 0:
|
||||
d = new DataBufferByte(size, banks);
|
||||
break;
|
||||
case 1:
|
||||
d = new DataBufferUShort(size, banks);
|
||||
break;
|
||||
case 2:
|
||||
d = new DataBufferShort(size, banks);
|
||||
break;
|
||||
case 3:
|
||||
d = new DataBufferInt(size, banks);
|
||||
break;
|
||||
case 4:
|
||||
d = DataBufferUtils.createDataBufferFloat(size, banks);
|
||||
break;
|
||||
case 5:
|
||||
d = DataBufferUtils.createDataBufferDouble(size, banks);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException(JaiI18N.getString("RasterFactory3"));
|
||||
}
|
||||
return createBandedRaster(d, width, height, scanlineStride, bankIndices, bandOffsets, location);
|
||||
}
|
||||
|
||||
public static WritableRaster createPackedRaster(int dataType, int width, int height, int[] bandMasks, Point location) {
|
||||
return Raster.createPackedRaster(dataType, width, height, bandMasks, location);
|
||||
}
|
||||
|
||||
public static WritableRaster createPackedRaster(int dataType, int width, int height, int numBands, int bitsPerBand, Point location) {
|
||||
if (bitsPerBand <= 0)
|
||||
throw new IllegalArgumentException(JaiI18N.getString("RasterFactory15"));
|
||||
return Raster.createPackedRaster(dataType, width, height, numBands, bitsPerBand, location);
|
||||
}
|
||||
|
||||
public static WritableRaster createInterleavedRaster(DataBuffer dataBuffer, int width, int height, int scanlineStride, int pixelStride, int[] bandOffsets, Point location) {
|
||||
PixelInterleavedSampleModel csm;
|
||||
int minBandOff, maxBandOff, i;
|
||||
ComponentSampleModelJAI componentSampleModelJAI;
|
||||
if (bandOffsets == null)
|
||||
throw new IllegalArgumentException(JaiI18N.getString("RasterFactory4"));
|
||||
if (location == null)
|
||||
location = new Point(0, 0);
|
||||
int dataType = dataBuffer.getDataType();
|
||||
switch (dataType) {
|
||||
case 0:
|
||||
case 1:
|
||||
csm = new PixelInterleavedSampleModel(dataType, width, height, pixelStride, scanlineStride, bandOffsets);
|
||||
return Raster.createWritableRaster(csm, dataBuffer, location);
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
minBandOff = bandOffsets[0];
|
||||
maxBandOff = bandOffsets[0];
|
||||
for (i = 1; i < bandOffsets.length; i++) {
|
||||
minBandOff = Math.min(minBandOff, bandOffsets[i]);
|
||||
maxBandOff = Math.max(maxBandOff, bandOffsets[i]);
|
||||
}
|
||||
maxBandOff -= minBandOff;
|
||||
if (maxBandOff > scanlineStride)
|
||||
throw new IllegalArgumentException(JaiI18N.getString("RasterFactory5"));
|
||||
if (pixelStride * width > scanlineStride)
|
||||
throw new IllegalArgumentException(JaiI18N.getString("RasterFactory6"));
|
||||
if (pixelStride < maxBandOff)
|
||||
throw new IllegalArgumentException(JaiI18N.getString("RasterFactory7"));
|
||||
componentSampleModelJAI = new ComponentSampleModelJAI(dataType, width, height, pixelStride, scanlineStride, bandOffsets);
|
||||
return Raster.createWritableRaster(componentSampleModelJAI, dataBuffer, location);
|
||||
}
|
||||
throw new IllegalArgumentException(JaiI18N.getString("RasterFactory3"));
|
||||
}
|
||||
|
||||
public static WritableRaster createBandedRaster(DataBuffer dataBuffer, int width, int height, int scanlineStride, int[] bankIndices, int[] bandOffsets, Point location) {
|
||||
if (location == null)
|
||||
location = new Point(0, 0);
|
||||
int dataType = dataBuffer.getDataType();
|
||||
if (bankIndices == null)
|
||||
throw new IllegalArgumentException(JaiI18N.getString("RasterFactory1"));
|
||||
if (bandOffsets == null)
|
||||
throw new IllegalArgumentException(JaiI18N.getString("RasterFactory4"));
|
||||
int bands = bankIndices.length;
|
||||
if (bandOffsets.length != bands)
|
||||
throw new IllegalArgumentException(JaiI18N.getString("RasterFactory2"));
|
||||
SampleModel bsm = new ComponentSampleModelJAI(dataType, width, height, 1, scanlineStride, bankIndices, bandOffsets);
|
||||
switch (dataType) {
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
return Raster.createWritableRaster(bsm, dataBuffer, location);
|
||||
}
|
||||
throw new IllegalArgumentException(JaiI18N.getString("RasterFactory3"));
|
||||
}
|
||||
|
||||
public static WritableRaster createPackedRaster(DataBuffer dataBuffer, int width, int height, int scanlineStride, int[] bandMasks, Point location) {
|
||||
return Raster.createPackedRaster(dataBuffer, width, height, scanlineStride, bandMasks, location);
|
||||
}
|
||||
|
||||
public static WritableRaster createPackedRaster(DataBuffer dataBuffer, int width, int height, int bitsPerPixel, Point location) {
|
||||
return Raster.createPackedRaster(dataBuffer, width, height, bitsPerPixel, location);
|
||||
}
|
||||
|
||||
public static Raster createRaster(SampleModel sampleModel, DataBuffer dataBuffer, Point location) {
|
||||
return Raster.createRaster(sampleModel, dataBuffer, location);
|
||||
}
|
||||
|
||||
public static WritableRaster createWritableRaster(SampleModel sampleModel, Point location) {
|
||||
if (location == null)
|
||||
location = new Point(0, 0);
|
||||
return createWritableRaster(sampleModel, sampleModel.createDataBuffer(), location);
|
||||
}
|
||||
|
||||
public static WritableRaster createWritableRaster(SampleModel sampleModel, DataBuffer dataBuffer, Point location) {
|
||||
return Raster.createWritableRaster(sampleModel, dataBuffer, location);
|
||||
}
|
||||
|
||||
public static WritableRaster createWritableChild(WritableRaster raster, int parentX, int parentY, int width, int height, int childMinX, int childMinY, int[] bandList) {
|
||||
return raster.createWritableChild(parentX, parentY, width, height, childMinX, childMinY, bandList);
|
||||
}
|
||||
|
||||
public static SampleModel createBandedSampleModel(int dataType, int width, int height, int numBands, int[] bankIndices, int[] bandOffsets) {
|
||||
if (numBands < 1)
|
||||
throw new IllegalArgumentException(JaiI18N.getString("RasterFactory0"));
|
||||
if (bankIndices == null) {
|
||||
bankIndices = new int[numBands];
|
||||
for (int i = 0; i < numBands; i++)
|
||||
bankIndices[i] = i;
|
||||
}
|
||||
if (bandOffsets == null) {
|
||||
bandOffsets = new int[numBands];
|
||||
for (int i = 0; i < numBands; i++)
|
||||
bandOffsets[i] = 0;
|
||||
}
|
||||
if (bandOffsets.length != bankIndices.length)
|
||||
throw new IllegalArgumentException(JaiI18N.getString("RasterFactory2"));
|
||||
return new ComponentSampleModelJAI(dataType, width, height, 1, width, bankIndices, bandOffsets);
|
||||
}
|
||||
|
||||
public static SampleModel createBandedSampleModel(int dataType, int width, int height, int numBands) {
|
||||
return createBandedSampleModel(dataType, width, height, numBands, null, null);
|
||||
}
|
||||
|
||||
public static SampleModel createPixelInterleavedSampleModel(int dataType, int width, int height, int pixelStride, int scanlineStride, int[] bandOffsets) {
|
||||
if (bandOffsets == null)
|
||||
throw new IllegalArgumentException(JaiI18N.getString("RasterFactory4"));
|
||||
int minBandOff = bandOffsets[0];
|
||||
int maxBandOff = bandOffsets[0];
|
||||
for (int i = 1; i < bandOffsets.length; i++) {
|
||||
minBandOff = Math.min(minBandOff, bandOffsets[i]);
|
||||
maxBandOff = Math.max(maxBandOff, bandOffsets[i]);
|
||||
}
|
||||
maxBandOff -= minBandOff;
|
||||
if (maxBandOff > scanlineStride)
|
||||
throw new IllegalArgumentException(JaiI18N.getString("RasterFactory5"));
|
||||
if (pixelStride * width > scanlineStride)
|
||||
throw new IllegalArgumentException(JaiI18N.getString("RasterFactory6"));
|
||||
if (pixelStride < maxBandOff)
|
||||
throw new IllegalArgumentException(JaiI18N.getString("RasterFactory7"));
|
||||
switch (dataType) {
|
||||
case 0:
|
||||
case 1:
|
||||
return new PixelInterleavedSampleModel(dataType, width, height, pixelStride, scanlineStride, bandOffsets);
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
return new ComponentSampleModelJAI(dataType, width, height, pixelStride, scanlineStride, bandOffsets);
|
||||
}
|
||||
throw new IllegalArgumentException(JaiI18N.getString("RasterFactory3"));
|
||||
}
|
||||
|
||||
public static SampleModel createPixelInterleavedSampleModel(int dataType, int width, int height, int numBands) {
|
||||
if (numBands < 1)
|
||||
throw new IllegalArgumentException(JaiI18N.getString("RasterFactory0"));
|
||||
int[] bandOffsets = new int[numBands];
|
||||
for (int i = 0; i < numBands; i++)
|
||||
bandOffsets[i] = numBands - 1 - i;
|
||||
return createPixelInterleavedSampleModel(dataType, width, height, numBands, numBands * width, bandOffsets);
|
||||
}
|
||||
|
||||
public static SampleModel createComponentSampleModel(SampleModel sm, int dataType, int width, int height, int numBands) {
|
||||
if (sm instanceof java.awt.image.BandedSampleModel)
|
||||
return createBandedSampleModel(dataType, width, height, numBands);
|
||||
return createPixelInterleavedSampleModel(dataType, width, height, numBands);
|
||||
}
|
||||
|
||||
public static ComponentColorModel createComponentColorModel(int dataType, ColorSpace colorSpace, boolean useAlpha, boolean premultiplied, int transparency) {
|
||||
if (colorSpace == null)
|
||||
throw new IllegalArgumentException(JaiI18N.getString("Generic0"));
|
||||
if (transparency != 1 && transparency != 2 && transparency != 3)
|
||||
throw new IllegalArgumentException(JaiI18N.getString("RasterFactory13"));
|
||||
if (useAlpha && transparency == 1)
|
||||
throw new IllegalArgumentException(JaiI18N.getString("RasterFactory14"));
|
||||
if (!useAlpha) {
|
||||
premultiplied = false;
|
||||
transparency = 1;
|
||||
}
|
||||
int bands = colorSpace.getNumComponents();
|
||||
if (useAlpha)
|
||||
bands++;
|
||||
int dataTypeSize = DataBuffer.getDataTypeSize(dataType);
|
||||
int[] bits = new int[bands];
|
||||
for (int i = 0; i < bands; i++)
|
||||
bits[i] = dataTypeSize;
|
||||
switch (dataType) {
|
||||
case 0:
|
||||
return new ComponentColorModel(colorSpace, bits, useAlpha, premultiplied, transparency, dataType);
|
||||
case 1:
|
||||
return new ComponentColorModel(colorSpace, bits, useAlpha, premultiplied, transparency, dataType);
|
||||
case 3:
|
||||
return new ComponentColorModel(colorSpace, bits, useAlpha, premultiplied, transparency, dataType);
|
||||
case 4:
|
||||
return new FloatDoubleColorModel(colorSpace, useAlpha, premultiplied, transparency, dataType);
|
||||
case 5:
|
||||
return new FloatDoubleColorModel(colorSpace, useAlpha, premultiplied, transparency, dataType);
|
||||
}
|
||||
throw new IllegalArgumentException(JaiI18N.getString("RasterFactory8"));
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue