コード例 #1
0
ファイル: TIFFIFD.java プロジェクト: bradh/imageio-ext
  public void writeToStream(ImageOutputStream stream, final boolean isBTIFF) throws IOException {

    long nextSpace;

    if (!isBTIFF) {
      int numFields = getNumTIFFFields();
      stream.writeShort(numFields);

      nextSpace = stream.getStreamPosition() + 12 * numFields + 4;

    } else {
      long numFields = getNumTIFFFields();
      stream.writeLong(numFields);

      nextSpace = stream.getStreamPosition() + 20 * numFields + 8;
    }

    Iterator iter = iterator();

    while (iter.hasNext()) {
      TIFFField f = (TIFFField) iter.next();

      TIFFTag tag = f.getTag();

      int type = f.getType();
      int count = f.getCount();

      // Hack to deal with unknown tags
      if (type == 0) {
        type = TIFFTag.TIFF_UNDEFINED;
      }
      int size = count * TIFFTag.getSizeOfType(type);

      if (type == TIFFTag.TIFF_ASCII) {
        int chars = 0;
        for (int i = 0; i < count; i++) {
          chars += f.getAsString(i).length() + 1;
        }
        count = chars;
        size = count;
      }

      int tagNumber = f.getTagNumber();
      stream.writeShort(tagNumber);
      stream.writeShort(type);

      if (isBTIFF) {
        stream.writeLong(count);
        stream.writeLong(0);
        stream.mark(); // Mark beginning of next field
        stream.skipBytes(-8);
      } else {
        stream.writeInt(count);
        stream.writeInt(0);
        stream.mark(); // Mark beginning of next field
        stream.skipBytes(-4);
      }

      long pos;

      if (!isBTIFF) {
        if (size > 4 || tag.isIFDPointer()) {
          // Ensure IFD or value is written on a word boundary
          nextSpace = (nextSpace + 3) & ~0x3;

          stream.writeInt((int) nextSpace);
          stream.seek(nextSpace);
          pos = nextSpace;

          if (tag.isIFDPointer()) {
            TIFFIFD subIFD = (TIFFIFD) f.getData();
            subIFD.writeToStream(stream, isBTIFF);
            nextSpace = subIFD.lastPosition;
          } else {
            writeTIFFFieldToStream(f, stream);
            nextSpace = stream.getStreamPosition();
          }
        } else {
          pos = stream.getStreamPosition();
          writeTIFFFieldToStream(f, stream);
        }
      } else {
        if (size > 8 || tag.isIFDPointer()) {
          // Ensure IFD or value is written on a Long boundary
          nextSpace = (nextSpace + 7) & ~0x7;

          stream.writeLong(nextSpace);
          stream.seek(nextSpace);
          pos = nextSpace;

          if (tag.isIFDPointer()) {
            TIFFIFD subIFD = (TIFFIFD) f.getData();
            subIFD.writeToStream(stream, isBTIFF);
            nextSpace = subIFD.lastPosition;
          } else {
            writeTIFFFieldToStream(f, stream);
            nextSpace = stream.getStreamPosition();
          }
        } else {
          pos = stream.getStreamPosition();
          writeTIFFFieldToStream(f, stream);
        }
      }
      // If we are writing the data for the
      // StripByteCounts, TileByteCounts, StripOffsets,
      // TileOffsets, JPEGInterchangeFormat, or
      // JPEGInterchangeFormatLength fields, record the current stream
      // position for backpatching
      if (tagNumber == BaselineTIFFTagSet.TAG_STRIP_BYTE_COUNTS
          || tagNumber == BaselineTIFFTagSet.TAG_TILE_BYTE_COUNTS
          || tagNumber == BaselineTIFFTagSet.TAG_JPEG_INTERCHANGE_FORMAT_LENGTH) {
        this.stripOrTileByteCountsPosition = pos;
      } else if (tagNumber == BaselineTIFFTagSet.TAG_STRIP_OFFSETS
          || tagNumber == BaselineTIFFTagSet.TAG_TILE_OFFSETS
          || tagNumber == BaselineTIFFTagSet.TAG_JPEG_INTERCHANGE_FORMAT) {
        this.stripOrTileOffsetsPosition = pos;
      }

      stream.reset(); // Go to marked position of next field
    }

    this.lastPosition = nextSpace;
  }
コード例 #2
0
ファイル: TIFFIFD.java プロジェクト: bradh/imageio-ext
  /**
   * Returns a <code>TIFFIFD</code> wherein all fields from the <code>BaselineTIFFTagSet</code> are
   * copied by value and all other fields copied by reference.
   */
  public TIFFIFD getShallowClone() {
    // Get the baseline TagSet.
    TIFFTagSet baselineTagSet = BaselineTIFFTagSet.getInstance();

    // If the baseline TagSet is not included just return.
    List tagSetList = getTagSetList();
    if (!tagSetList.contains(baselineTagSet)) {
      return this;
    }

    // Create a new object.
    TIFFIFD shallowClone = new TIFFIFD(tagSetList, getParentTag());

    // Get the tag numbers in the baseline set.
    Set baselineTagNumbers = baselineTagSet.getTagNumbers();

    // Iterate over the fields in this IFD.
    Iterator fields = iterator();
    while (fields.hasNext()) {
      // Get the next field.
      TIFFField field = (TIFFField) fields.next();

      // Get its tag number.
      Integer tagNumber = new Integer(field.getTagNumber());

      // Branch based on membership in baseline set.
      TIFFField fieldClone;
      if (baselineTagNumbers.contains(tagNumber)) {
        // Copy by value.
        Object fieldData = field.getData();

        int fieldType = field.getType();

        try {
          switch (fieldType) {
            case TIFFTag.TIFF_BYTE:
            case TIFFTag.TIFF_SBYTE:
            case TIFFTag.TIFF_UNDEFINED:
              fieldData = ((byte[]) fieldData).clone();
              break;
            case TIFFTag.TIFF_ASCII:
              fieldData = ((String[]) fieldData).clone();
              break;
            case TIFFTag.TIFF_SHORT:
              fieldData = ((char[]) fieldData).clone();
              break;
            case TIFFTag.TIFF_LONG:
            case TIFFTag.TIFF_IFD_POINTER:
              fieldData = ((long[]) fieldData).clone();
              break;
            case TIFFTag.TIFF_RATIONAL:
              fieldData = ((long[][]) fieldData).clone();
              break;
            case TIFFTag.TIFF_SSHORT:
              fieldData = ((short[]) fieldData).clone();
              break;
            case TIFFTag.TIFF_SLONG:
              fieldData = ((int[]) fieldData).clone();
              break;
            case TIFFTag.TIFF_SRATIONAL:
              fieldData = ((int[][]) fieldData).clone();
              break;
            case TIFFTag.TIFF_FLOAT:
              fieldData = ((float[]) fieldData).clone();
              break;
            case TIFFTag.TIFF_DOUBLE:
              fieldData = ((double[]) fieldData).clone();
              break;
            default:
              // Shouldn't happen but do nothing ...
          }
        } catch (Exception e) {
          // Ignore it and copy by reference ...
        }

        fieldClone =
            new TIFFField(
                field.getTag(), fieldType,
                field.getCount(), fieldData);
      } else {
        // Copy by reference.
        fieldClone = field;
      }

      // Add the field to the clone.
      shallowClone.addTIFFField(fieldClone);
    }

    // Set positions.
    shallowClone.setPositions(
        stripOrTileOffsetsPosition, stripOrTileByteCountsPosition, lastPosition);

    return shallowClone;
  }
コード例 #3
0
ファイル: TIFFIFD.java プロジェクト: bradh/imageio-ext
  private static void writeTIFFFieldToStream(TIFFField field, ImageOutputStream stream)
      throws IOException {
    int count = field.getCount();
    Object data = field.getData();

    switch (field.getType()) {
      case TIFFTag.TIFF_ASCII:
        for (int i = 0; i < count; i++) {
          String s = ((String[]) data)[i];
          int length = s.length();
          for (int j = 0; j < length; j++) {
            stream.writeByte(s.charAt(j) & 0xff);
          }
          stream.writeByte(0);
        }
        break;
      case TIFFTag.TIFF_UNDEFINED:
      case TIFFTag.TIFF_BYTE:
      case TIFFTag.TIFF_SBYTE:
        stream.write((byte[]) data);
        break;
      case TIFFTag.TIFF_SHORT:
        stream.writeChars((char[]) data, 0, ((char[]) data).length);
        break;
      case TIFFTag.TIFF_SSHORT:
        stream.writeShorts((short[]) data, 0, ((short[]) data).length);
        break;
      case TIFFTag.TIFF_SLONG:
        stream.writeInts((int[]) data, 0, ((int[]) data).length);
        break;
      case TIFFTag.TIFF_LONG:
        for (int i = 0; i < count; i++) {
          stream.writeInt((int) (((long[]) data)[i]));
        }
        break;
      case TIFFTag.TIFF_LONG8:
        stream.writeLongs((long[]) data, 0, ((long[]) data).length);
        break;
      case TIFFTag.TIFF_IFD_POINTER:
        stream.writeInt(0); // will need to be backpatched
        break;
      case TIFFTag.TIFF_FLOAT:
        stream.writeFloats((float[]) data, 0, ((float[]) data).length);
        break;
      case TIFFTag.TIFF_DOUBLE:
        stream.writeDoubles((double[]) data, 0, ((double[]) data).length);
        break;
      case TIFFTag.TIFF_SRATIONAL:
        for (int i = 0; i < count; i++) {
          stream.writeInt(((int[][]) data)[i][0]);
          stream.writeInt(((int[][]) data)[i][1]);
        }
        break;
      case TIFFTag.TIFF_RATIONAL:
        for (int i = 0; i < count; i++) {
          long num = ((long[][]) data)[i][0];
          long den = ((long[][]) data)[i][1];
          stream.writeInt((int) num);
          stream.writeInt((int) den);
        }
        break;
      default:
        // error
    }
  }