/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.sanselan.formats.tiff.write; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import org.apache.sanselan.ImageWriteException; import org.apache.sanselan.common.BinaryOutputStream; import org.apache.sanselan.formats.tiff.JpegImageData; import org.apache.sanselan.formats.tiff.TiffDirectory; import org.apache.sanselan.formats.tiff.TiffElement; //import org.apache.sanselan.formats.tiff.TiffImageData; import org.apache.sanselan.formats.tiff.constants.TagConstantsUtils; import org.apache.sanselan.formats.tiff.constants.TagInfo; import org.apache.sanselan.formats.tiff.constants.TiffConstants; import org.apache.sanselan.formats.tiff.fieldtypes.FieldType; public final class TiffOutputDirectory extends TiffOutputItem implements TiffConstants { public final int type; private final ArrayList fields = new ArrayList(); private TiffOutputDirectory nextDirectory = null; public void setNextDirectory(TiffOutputDirectory nextDirectory) { this.nextDirectory = nextDirectory; } public TiffOutputDirectory(final int type) { this.type = type; } public void add(TiffOutputField field) { fields.add(field); } public ArrayList getFields() { return new ArrayList(fields); } public void removeField(TagInfo tagInfo) { removeField(tagInfo.tag); } public void removeField(int tag) { ArrayList matches = new ArrayList(); for (int i = 0; i < fields.size(); i++) { TiffOutputField field = (TiffOutputField) fields.get(i); if (field.tag == tag) matches.add(field); } fields.removeAll(matches); } public TiffOutputField findField(TagInfo tagInfo) { return findField(tagInfo.tag); } public TiffOutputField findField(int tag) { for (int i = 0; i < fields.size(); i++) { TiffOutputField field = (TiffOutputField) fields.get(i); if (field.tag == tag) return field; } return null; } public void sortFields() { Comparator comparator = new Comparator() { public int compare(Object o1, Object o2) { TiffOutputField e1 = (TiffOutputField) o1; TiffOutputField e2 = (TiffOutputField) o2; if (e1.tag != e2.tag) return e1.tag - e2.tag; return e1.getSortHint() - e2.getSortHint(); } }; Collections.sort(fields, comparator); } public String description() { return TiffDirectory.description(type); } public void writeItem(BinaryOutputStream bos) throws IOException, ImageWriteException { // Write Directory Field Count bos.write2Bytes(fields.size()); // DirectoryFieldCount // Write Fields for (int i = 0; i < fields.size(); i++) { TiffOutputField field = (TiffOutputField) fields.get(i); field.writeField(bos); // Debug.debug("\t" + "writing field (" + field.tag + ", 0x" + // Integer.toHexString(field.tag) + ")", field.tagInfo); // if(field.tagInfo.isOffset()) // Debug.debug("\t\tOFFSET!", field.bytes); } int nextDirectoryOffset = 0; if (nextDirectory != null) nextDirectoryOffset = nextDirectory.getOffset(); // Write nextDirectoryOffset if (nextDirectoryOffset == UNDEFINED_VALUE) bos.write4Bytes(0); else bos.write4Bytes(nextDirectoryOffset); } private JpegImageData jpegImageData = null; public void setJpegImageData(JpegImageData rawJpegImageData) { this.jpegImageData = rawJpegImageData; } public JpegImageData getRawJpegImageData() { return jpegImageData; } // private TiffImageData tiffImageData = null; // // public void setTiffImageData(TiffImageData rawTiffImageData) // { // this.tiffImageData = rawTiffImageData; // } // // public TiffImageData getRawTiffImageData() // { // return tiffImageData; // } public int getItemLength() { return TIFF_ENTRY_LENGTH * fields.size() + TIFF_DIRECTORY_HEADER_LENGTH + TIFF_DIRECTORY_FOOTER_LENGTH; } public String getItemDescription() { ExifDirectoryType dirType = TagConstantsUtils .getExifDirectoryType(type); return "Directory: " + dirType.name + " (" + type + ")"; } private void removeFieldIfPresent(TagInfo tagInfo) { TiffOutputField field = findField(tagInfo); if (null != field) fields.remove(field); } protected List getOutputItems(TiffOutputSummary outputSummary) throws ImageWriteException { // first validate directory fields. removeFieldIfPresent(TIFF_TAG_JPEG_INTERCHANGE_FORMAT); removeFieldIfPresent(TIFF_TAG_JPEG_INTERCHANGE_FORMAT_LENGTH); TiffOutputField jpegOffsetField = null; if (null != jpegImageData) { jpegOffsetField = new TiffOutputField( TIFF_TAG_JPEG_INTERCHANGE_FORMAT, FIELD_TYPE_LONG, 1, FieldType.getStubLocalValue()); add(jpegOffsetField); byte lengthValue[] = FIELD_TYPE_LONG.writeData( new int[] { jpegImageData.length, }, outputSummary.byteOrder); TiffOutputField jpegLengthField = new TiffOutputField( TIFF_TAG_JPEG_INTERCHANGE_FORMAT_LENGTH, FIELD_TYPE_LONG, 1, lengthValue); add(jpegLengthField); } // -------------------------------------------------------------- removeFieldIfPresent(TIFF_TAG_STRIP_OFFSETS); removeFieldIfPresent(TIFF_TAG_STRIP_BYTE_COUNTS); removeFieldIfPresent(TIFF_TAG_TILE_OFFSETS); removeFieldIfPresent(TIFF_TAG_TILE_BYTE_COUNTS); TiffOutputField imageDataOffsetField; ImageDataOffsets imageDataInfo = null; // if (null != tiffImageData) // { // boolean stripsNotTiles = tiffImageData.stripsNotTiles(); // // TagInfo offsetTag; // TagInfo byteCountsTag; // if (stripsNotTiles) // { // offsetTag = TIFF_TAG_STRIP_OFFSETS; // byteCountsTag = TIFF_TAG_STRIP_BYTE_COUNTS; // } else // { // offsetTag = TIFF_TAG_TILE_OFFSETS; // byteCountsTag = TIFF_TAG_TILE_BYTE_COUNTS; // } // // // -------- // // TiffElement.DataElement imageData[] = tiffImageData.getImageData(); // // int imageDataOffsets[] = null; // int imageDataByteCounts[] = null; // // TiffOutputField imageDataOffsetsField = null; // // imageDataOffsets = new int[imageData.length]; // imageDataByteCounts = new int[imageData.length]; // for (int i = 0; i < imageData.length; i++) // { // imageDataByteCounts[i] = imageData[i].length; // } // // // -------- // // // Append imageData-related fields to first directory // imageDataOffsetField = new TiffOutputField(offsetTag, // FIELD_TYPE_LONG, imageDataOffsets.length, FIELD_TYPE_LONG // .writeData(imageDataOffsets, // outputSummary.byteOrder)); // add(imageDataOffsetField); // // // -------- // // byte data[] = FIELD_TYPE_LONG.writeData(imageDataByteCounts, // outputSummary.byteOrder); // TiffOutputField byteCountsField = new TiffOutputField( // byteCountsTag, FIELD_TYPE_LONG, imageDataByteCounts.length, // data); // add(byteCountsField); // // // -------- // // imageDataInfo = new ImageDataOffsets(imageData, imageDataOffsets, // imageDataOffsetField); // } // -------------------------------------------------------------- List result = new ArrayList(); result.add(this); sortFields(); for (int i = 0; i < fields.size(); i++) { TiffOutputField field = (TiffOutputField) fields.get(i); if (field.isLocalValue()) continue; TiffOutputItem item = field.getSeperateValue(); result.add(item); // outputSummary.add(item, field); } if (null != imageDataInfo) { for (int i = 0; i < imageDataInfo.outputItems.length; i++) result.add(imageDataInfo.outputItems[i]); outputSummary.addTiffImageData(imageDataInfo); } if (null != jpegImageData) { TiffOutputItem item = new TiffOutputItem.Value("JPEG image data", jpegImageData.data); result.add(item); outputSummary.add(item, jpegOffsetField); } return result; } }