first commit

This commit is contained in:
MaddoScientisto 2026-03-14 20:04:39 +01:00
commit 4d332ef662
27586 changed files with 3281783 additions and 0 deletions

View 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

View file

@ -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"));
}
}

View file

@ -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() {}
}

View file

@ -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;
}
}

View file

@ -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);
}
}

View file

@ -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;
}
}

View file

@ -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);
}
}

View file

@ -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);
}

View file

@ -0,0 +1,5 @@
package com.sun.media.jai.codec;
import java.io.Serializable;
public interface ImageDecodeParam extends Cloneable, Serializable {}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -0,0 +1,5 @@
package com.sun.media.jai.codec;
import java.io.Serializable;
public interface ImageEncodeParam extends ImageDecodeParam, Cloneable, Serializable {}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}
}

View file

@ -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();
}
}
}

View file

@ -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);
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}

View file

@ -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;
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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();
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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);
}

View file

@ -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);
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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);
}
}

View file

@ -0,0 +1 @@
2006-09-11 17:23:56.159-0700

View file

@ -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.

View file

@ -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.

View file

@ -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.

View file

@ -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

View file

@ -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);
}
}

View file

@ -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;
}
}

View file

@ -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);
}
}
}

View file

@ -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);
}
}

View file

@ -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;
}
}

View file

@ -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);
}
}

View file

@ -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;
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}
}

View file

@ -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);
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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();
}
}

View file

@ -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;
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}
}

View file

@ -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);
}
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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 {}
}

View file

@ -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);
}
}

View file

@ -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

View file

@ -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);
}
}
}

View file

@ -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();
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}
}

View file

@ -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);
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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

View file

@ -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

View file

@ -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;
}
}
}

View file

@ -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));
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}
}
}
}

View file

@ -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());
}
}

View file

@ -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();
}
}
}

View file

@ -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);
}
}

View file

@ -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;
}
}

View file

@ -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"));
}
}

View file

@ -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;
}
}

View file

@ -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();
}
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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) });
}
}

View file

@ -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();
}
}

View file

@ -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);
}
}
}
}

View file

@ -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);
}
}

View file

@ -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;
}
}

View file

@ -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"));
}
}