6 static final int IMAGE_START = 768;
7 static final int HDR_SIZE = 8;
8 static final int MAP_SIZE = 768;
9 static final int BPS_DATA_SIZE = 6;
10 static final int SCALE_DATA_SIZE = 16;
14 private int bitsPerSample;
15 private int photoInterp;
16 private int samplesPerPixel;
19 private int imageOffset = IMAGE_START;
20 private int imageSize;
21 private int stackSize;
22 private byte[] description;
26 fi.intelByteOrder =
false;
30 int bytesPerPixel = 1;
31 switch (fi.fileType) {
33 photoInterp = fi.whiteIsZero?0:1;
38 photoInterp = fi.whiteIsZero?0:1;
43 photoInterp = fi.whiteIsZero?0:1;
58 if (fi.unit!=null && fi.pixelWidth!=0 && fi.pixelHeight!=0)
62 makeDescriptionString();
63 if (description!=null)
65 ifdSize = 2 + nEntries*12 + 4;
66 imageSize = fi.width*fi.height*bytesPerPixel;
67 stackSize = imageSize*fi.nImages;
73 public void write(DataOutputStream out)
throws IOException {
77 nextIFD = IMAGE_START+stackSize;
80 writeIFD(out, imageOffset, nextIFD);
81 int bpsSize=0, scaleSize=0, descriptionSize=0;
83 bpsSize = writeBitsPerPixel(out);
84 if (description!=null)
85 descriptionSize = writeDescription(out);
86 if (fi.unit!=null && fi.pixelWidth!=0 && fi.pixelHeight!=0)
87 scaleSize = writeScale(out);
88 byte[] filler =
new byte[IMAGE_START - (HDR_SIZE+ifdSize+bpsSize+descriptionSize+scaleSize)];
94 for (
int i=2; i<=fi.nImages; i++) {
99 imageOffset += imageSize;
100 writeIFD(out, imageOffset, nextIFD);
105 void writeHeader(DataOutputStream out)
throws IOException {
106 byte[] hdr =
new byte[8];
119 void writeEntry(DataOutputStream out,
int tag,
int fieldType,
int count,
int value)
throws IOException {
121 out.writeShort(fieldType);
123 if (count==1 && fieldType==TiffDecoder.SHORT)
129 void writeIFD(DataOutputStream out,
int imageOffset,
int nextIFD)
throws IOException {
130 int tagDataOffset = HDR_SIZE + ifdSize;
131 out.writeShort(nEntries);
132 writeEntry(out, TiffDecoder.NEW_SUBFILE_TYPE, 4, 1, 0);
133 writeEntry(out, TiffDecoder.IMAGE_WIDTH, 3, 1, fi.width);
134 writeEntry(out, TiffDecoder.IMAGE_LENGTH, 3, 1, fi.height);
135 if (fi.fileType==FileInfo.RGB) {
136 writeEntry(out, TiffDecoder.BITS_PER_SAMPLE, 3, 3, tagDataOffset);
137 tagDataOffset += BPS_DATA_SIZE;
139 writeEntry(out, TiffDecoder.BITS_PER_SAMPLE, 3, 1, bitsPerSample);
140 writeEntry(out, TiffDecoder.PHOTO_INTERP, 3, 1, photoInterp);
141 if (description!=null) {
142 writeEntry(out, TiffDecoder.IMAGE_DESCRIPTION, 2, description.length, tagDataOffset);
143 tagDataOffset += description.length;
145 writeEntry(out, TiffDecoder.STRIP_OFFSETS, 4, 1, imageOffset);
146 writeEntry(out, TiffDecoder.SAMPLES_PER_PIXEL,3, 1, samplesPerPixel);
147 writeEntry(out, TiffDecoder.ROWS_PER_STRIP, 3, 1, fi.height);
148 writeEntry(out, TiffDecoder.STRIP_BYTE_COUNT, 4, 1, imageSize);
149 if (fi.unit!=null && fi.pixelWidth!=0 && fi.pixelHeight!=0) {
150 writeEntry(out, TiffDecoder.X_RESOLUTION, 5, 1, tagDataOffset);
151 writeEntry(out, TiffDecoder.Y_RESOLUTION, 5, 1, tagDataOffset+8);
152 tagDataOffset += SCALE_DATA_SIZE;
154 if (fi.unit.equals(
"inch"))
156 else if (fi.unit.equals(
"cm"))
158 writeEntry(out, TiffDecoder.RESOLUTION_UNIT, 3, 1, unit);
161 int format = TiffDecoder.FLOATING_POINT;
162 writeEntry(out, TiffDecoder.SAMPLE_FORMAT, 3, 1, format);
164 if (fi.fileType==FileInfo.COLOR8)
165 writeEntry(out, TiffDecoder.COLOR_MAP, 3, MAP_SIZE, IMAGE_START+stackSize);
166 out.writeInt(nextIFD);
170 int writeBitsPerPixel(DataOutputStream out)
throws IOException {
174 return BPS_DATA_SIZE;
178 int writeScale(DataOutputStream out)
throws IOException {
179 double xscale = 1.0/fi.pixelWidth;
180 double yscale = 1.0/fi.pixelHeight;
181 double scale = 1000000.0;
182 if (xscale>1000.0) scale = 1000.0;
183 out.writeInt((
int)(xscale*scale));
184 out.writeInt((
int)scale);
185 out.writeInt((
int)(yscale*scale));
186 out.writeInt((
int)scale);
187 return SCALE_DATA_SIZE;
191 int writeDescription(DataOutputStream out)
throws IOException {
192 out.write(description,0,description.length);
193 return description.length;
197 void writeColorMap(DataOutputStream out)
throws IOException {
198 byte[] colorTable16 =
new byte[MAP_SIZE*2];
200 for (
int i=0; i<fi.lutSize; i++) {
201 colorTable16[j] = fi.reds[i];
202 colorTable16[512+j] = fi.greens[i];
203 colorTable16[1024+j] = fi.blues[i];
206 out.write(colorTable16);
212 void makeDescriptionString() {
213 if (fi.description!=null) {
214 if (fi.description.charAt(fi.description.length()-1)!=(
char)0)
215 fi.description +=
" ";
216 description = fi.description.getBytes();
217 description[description.length-1] = (byte)0;