// Do not seek to the beginning of the stream so as to allow users to
  // point us at an IFD within some other file format
  private void readHeader() throws IIOException {
    if (gotHeader) {
      return;
    }
    if (stream == null) {
      throw new IllegalStateException("Input not set!");
    }

    // Create an object to store the stream metadata
    this.streamMetadata = new TIFFStreamMetadata();

    try {
      int byteOrder = stream.readUnsignedShort();
      if (byteOrder == 0x4d4d) {
        streamMetadata.byteOrder = ByteOrder.BIG_ENDIAN;
        stream.setByteOrder(ByteOrder.BIG_ENDIAN);
      } else if (byteOrder == 0x4949) {
        streamMetadata.byteOrder = ByteOrder.LITTLE_ENDIAN;
        stream.setByteOrder(ByteOrder.LITTLE_ENDIAN);
      } else {
        processWarningOccurred("Bad byte order in header, assuming little-endian");
        streamMetadata.byteOrder = ByteOrder.LITTLE_ENDIAN;
        stream.setByteOrder(ByteOrder.LITTLE_ENDIAN);
      }

      int magic = stream.readUnsignedShort();
      if (magic != 42) {
        processWarningOccurred("Bad magic number in header, continuing");
      }

      // Seek to start of first IFD
      long offset = stream.readUnsignedInt();
      imageStartPosition.add(new Long(offset));
      stream.seek(offset);
    } catch (IOException e) {
      throw new IIOException("I/O error reading header!", e);
    }

    gotHeader = true;
  }
  private void readMetadata() throws IOException {
    if (metadata != null) return;

    if (iis == null) throw new IllegalStateException("Input not set");

    dis = new DicomInputStream(new ImageInputStreamAdapter(iis));
    dis.setIncludeBulkData(IncludeBulkData.URI);
    dis.setBulkDataDescriptor(BulkDataDescriptor.PIXELDATA);
    dis.setURI("java:iis"); // avoid copy of pixeldata to temporary file
    Attributes fmi = dis.readFileMetaInformation();
    Attributes ds = dis.readDataset(-1, -1);
    metadata = new DicomMetaData(fmi, ds);
    Object pixeldata = ds.getValue(Tag.PixelData, pixeldataVR);
    if (pixeldata != null) {
      frames = ds.getInt(Tag.NumberOfFrames, 1);
      width = ds.getInt(Tag.Columns, 0);
      height = ds.getInt(Tag.Rows, 0);
      samples = ds.getInt(Tag.SamplesPerPixel, 1);
      banded = samples > 1 && ds.getInt(Tag.PlanarConfiguration, 0) != 0;
      bitsAllocated = ds.getInt(Tag.BitsAllocated, 8);
      bitsStored = ds.getInt(Tag.BitsStored, bitsAllocated);
      dataType = bitsAllocated <= 8 ? DataBuffer.TYPE_BYTE : DataBuffer.TYPE_USHORT;
      pmi =
          PhotometricInterpretation.fromString(
              ds.getString(Tag.PhotometricInterpretation, "MONOCHROME2"));
      if (pixeldata instanceof BulkData) {
        iis.setByteOrder(ds.bigEndian() ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN);
        this.frameLength = pmi.frameLength(width, height, samples, bitsAllocated);
        this.pixeldata = (BulkData) pixeldata;
      } else {
        String tsuid = dis.getTransferSyntax();
        ImageReaderParam param = ImageReaderFactory.getImageReaderParam(tsuid);
        if (param == null) throw new IOException("Unsupported Transfer Syntax: " + tsuid);
        this.decompressor = ImageReaderFactory.getImageReader(param);
        this.patchJpegLS = param.patchJPEGLS;
        this.pixeldataFragments = (Fragments) pixeldata;
      }
    }
  }
 public void setInput(Object input, boolean seekForwardOnly, boolean ignoreMetadata) {
   super.setInput(input, seekForwardOnly, ignoreMetadata);
   iis = (ImageInputStream) input; // Always works
   if (iis != null) iis.setByteOrder(ByteOrder.LITTLE_ENDIAN);
   gotHeader = false;
 }