1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
|
/* Copyright (c) 2015, David A. Clunie DBA Pixelmed Publishing. All rights reserved. */
package com.pixelmed.codec.jpeg;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.ByteOrder;
/**
* <p>A class that allows writing to either an {@link java.io.OutputStream OutputStream}
* or a byte[] or short[] of preallocated size.</p>
*
* <p>An unallocated instance may be constructed but any attempt to write to it will
* fail until either an OutputStream is assigned or an array of the appropriate type
* is allocated. This allows, for example, the instance to be created and later
* allocated based on size information, e.g., as header information is encountered
* while decompressing before decompressed pixel values need to be written.</p>
*
* @author dclunie
*/
public class OutputArrayOrStream {
private static final String identString = "@(#) $Header: /userland/cvs/codec/com/pixelmed/codec/jpeg/OutputArrayOrStream.java,v 1.5 2016/01/16 13:30:09 dclunie Exp $";
protected OutputStream out = null;
protected ByteOrder order = null;
protected byte[] byteValues = null;
protected short[] shortValues = null;
protected int byteOffset = 0;
protected int shortOffset = 0;
public OutputArrayOrStream() {
// lazy allocation
}
public OutputArrayOrStream(OutputStream out,ByteOrder order) {
this.out = out;
this.order = order;
}
public OutputArrayOrStream(byte[] byteValues) {
this.byteValues = byteValues;
byteOffset = 0;
}
public OutputArrayOrStream(short[] shortValues) {
this.shortValues = shortValues;
shortOffset = 0;
}
public void setOutputStream(OutputStream out,ByteOrder order) throws IOException {
if (this.out != null || this.byteValues != null || this.shortValues != null) {
throw new IOException("Destination already allocated");
}
this.out = out;
this.order = order;
}
/**
* <p>Retrieves the OutputStream's byte order used when writing short values.</p>
*
* @return The OutputStream's byte order, or null if no OutputStream
*/
public ByteOrder order() {
return out == null ? null : order;
}
/**
* <p>Modifes the OutputStream's byte order used when writing short values.</p>
*
* @param order the new byte order, either BIG_ENDIAN or LITTLE_ENDIAN
* @throws IOException if no OutputStream assigned
*/
public void order(ByteOrder order) throws IOException {
if (out == null) {
throw new IOException("Cannot assign byte order if no OutputStream");
}
this.order = order;
}
public void allocateByteArray(int length) throws IOException {
if (this.out != null || this.byteValues != null || this.shortValues != null) {
throw new IOException("Destination already allocated");
}
this.byteValues = new byte[length];
byteOffset = 0;
}
public void allocateShortArray(int length) throws IOException {
if (this.out != null || this.byteValues != null || this.shortValues != null) {
throw new IOException("Destination already allocated");
}
this.shortValues = new short[length];
shortOffset = 0;
}
public OutputStream getOutputStream() {
return out;
}
public byte[] getByteArray() {
return byteValues;
}
public short[] getShortArray() {
return shortValues;
}
/**
* Writes the specified <code>byte</code> to this output.
*
* @param b the <code>byte</code>.
* @throws IOException if an I/O error occurs.
*/
public void writeByte(int b) throws IOException {
if (out != null) {
out.write(b);
}
else if (byteValues != null) {
byteValues[byteOffset++] = (byte)b;
}
else if (shortValues != null) {
throw new IOException("Cannot write byte value to short array");
}
else {
throw new IOException("Byte array not allocated yet");
}
}
/**
* Writes the specified <code>short</code> to this output.
*
* @param s the <code>short</code>.
* @throws IOException if an I/O error occurs.
*/
public void writeShort(int s) throws IOException {
if (out != null) {
if (order == ByteOrder.LITTLE_ENDIAN) {
out.write(s);
out.write(s>>8);
}
else {
out.write(s>>8);
out.write(s);
}
}
else if (shortValues != null) {
shortValues[shortOffset++] = (short)s;
}
else if (byteValues != null) {
throw new IOException("Cannot write short value to byte array");
}
else {
throw new IOException("Short array not allocated yet");
}
}
/**
* <p>Closes any assigned OutputStream.</p>
*
* <p>Does nothing if arrays allocated instead of an OutputStream (i.e., does NOT release them).</p>
*
* @throws IOException if an I/O error occurs.
*/
public void close() throws IOException {
if (out != null) {
out.close();
}
}
}
|