Esempio n. 1
0
  // TODO: Candidate util method
  private static long skipToEOF(final ImageInputStream stream) throws IOException {
    long length = stream.length();

    if (length > 0) {
      // Known length, skip there and we're done.
      stream.seek(length);
    } else {
      // Otherwise, seek to EOF the hard way.
      // First, store stream position...
      long pos = stream.getStreamPosition();

      // ...skip 1k blocks until we're passed EOF...
      while (stream.skipBytes(1024l) > 0) {
        if (stream.read() == -1) {
          break;
        }

        pos = stream.getStreamPosition();
      }

      // ...go back to last known pos...
      stream.seek(pos);

      // ...finally seek until EOF one byte at a time. Done.
      while (stream.read() != -1) {}
    }

    return stream.getStreamPosition();
  }
Esempio n. 2
0
  private int locateImage(int imageIndex) throws IIOException {
    readHeader();

    try {
      // Find closest known index
      int index = Math.min(imageIndex, imageStartPosition.size() - 1);

      // Seek to that position
      Long l = (Long) imageStartPosition.get(index);
      stream.seek(l.longValue());

      // Skip IFDs until at desired index or last image found
      while (index < imageIndex) {
        int count = stream.readUnsignedShort();
        stream.skipBytes(12 * count);

        long offset = stream.readUnsignedInt();
        if (offset == 0) {
          return index;
        }

        imageStartPosition.add(new Long(offset));
        stream.seek(offset);
        ++index;
      }
    } catch (IOException e) {
      throw new IIOException("Couldn't seek!", e);
    }

    if (currIndex != imageIndex) {
      imageMetadata = null;
    }
    currIndex = imageIndex;
    return imageIndex;
  }
Esempio n. 3
0
  private void parseProperties() throws IOException {
    String line;
    stream.seek(0);
    propertiesByteSize = 0;
    long posInStream = 0l;
    while ((line = stream.readLine()) != null) {
      if (!line.startsWith("#")) {
        stream.seek(posInStream);
        break;
      }
      propertiesByteSize += (stream.getStreamPosition() - posInStream);
      posInStream = stream.getStreamPosition();

      line = line.substring(1);
      int pos = line.indexOf('=');
      if (pos == -1) {
        throw new IOException("Missing '=' in '" + line + "'");
      }
      String name = line.substring(0, pos).trim();
      if (name.isEmpty()) {
        throw new IOException("Empty property name in '" + line + "'");
      }
      String value = line.substring(pos + 1).trim();
      try {
        if (contains(Constants.CRS_IDENTIFIERS, name) && crs != null) {
          crs = CRS.parseWKT(value);
        }
      } catch (FactoryException e) {
        throw new IOException(e);
      }
      properties.put(name, value);
    }
    propertiesParsed = true;
  }
Esempio n. 4
0
 private void skipToLine(long lineOffset) throws IOException {
   if (bytePositionForOffset.containsKey(lineOffset)) {
     stream.seek(bytePositionForOffset.get(lineOffset));
     return;
   }
   Map.Entry<Long, Long> entry = getBestOffset(lineOffset);
   stream.seek(entry.getValue());
   long linesToSkip = lineOffset - entry.getKey();
   for (int i = 0; i < linesToSkip; i++) {
     stream.readLine();
   }
   bytePositionForOffset.put(lineOffset, stream.getStreamPosition());
 }
Esempio n. 5
0
    PSDResource(final short resourceId, final ImageInputStream input) throws IOException {
      id = resourceId;

      name = readPascalString(input);

      // Skip pad
      int nameSize = name.length() + 1;
      if (nameSize % 2 != 0) {
        input.readByte();
      }

      size = input.readUnsignedInt();
      long startPos = input.getStreamPosition();

      readData(new SubImageInputStream(input, size));

      // NOTE: This should never happen, however it's safer to keep it here for future compatibility
      if (input.getStreamPosition() != startPos + size) {
        input.seek(startPos + size);
      }

      // Data is even-padded (word aligned)
      if (size % 2 != 0) {
        input.read();
      }
    }
Esempio n. 6
0
  @Override
  public Raster readRaster(int frameIndex, ImageReadParam param) throws IOException {
    readMetadata();
    checkIndex(frameIndex);

    if (decompressor != null) {
      decompressor.setInput(iisOfFrame(frameIndex));

      if (LOG.isDebugEnabled()) LOG.debug("Start decompressing frame #" + (frameIndex + 1));
      Raster wr =
          pmi.decompress() == pmi && decompressor.canReadRaster()
              ? decompressor.readRaster(0, decompressParam(param))
              : decompressor.read(0, decompressParam(param)).getRaster();
      if (LOG.isDebugEnabled()) LOG.debug("Finished decompressing frame #" + (frameIndex + 1));
      return wr;
    }
    iis.seek(pixeldata.offset + frameIndex * frameLength);
    WritableRaster wr = Raster.createWritableRaster(createSampleModel(dataType, banded), null);
    DataBuffer buf = wr.getDataBuffer();
    if (buf instanceof DataBufferByte) {
      byte[][] data = ((DataBufferByte) buf).getBankData();
      for (byte[] bs : data) iis.readFully(bs);
      if (pixeldata.bigEndian && pixeldataVR.vr == VR.OW) ByteUtils.swapShorts(data);
    } else {
      short[] data = ((DataBufferUShort) buf).getData();
      iis.readFully(data, 0, data.length);
    }
    return wr;
  }
Esempio n. 7
0
 @Override
 public int getRecordCount() throws IOException {
   int count = 1;
   byte[] buffer = new byte[100 * 1024];
   int readChars;
   long currentPosInStream = stream.getStreamPosition();
   stream.seek(0);
   while ((readChars = stream.read(buffer)) != -1) {
     for (int i = 0; i < readChars - 1; ++i) {
       if (buffer[i] == '\n') {
         ++count;
       }
     }
   }
   count -= properties.size();
   final int headerLineCount = 1;
   count -= headerLineCount;
   stream.seek(currentPosInStream);
   return count;
 }
Esempio n. 8
0
 BufferedImage getThumbnail(ImageInputStream iis, JPEGImageReader reader) throws IOException {
   iis.mark();
   iis.seek(streamPos);
   JPEGImageReader thumbReader = new JPEGImageReader(null);
   thumbReader.setInput(iis);
   thumbReader.addIIOReadProgressListener(new ThumbnailReadListener(reader));
   BufferedImage ret = thumbReader.read(0, null);
   thumbReader.dispose();
   iis.reset();
   return ret;
 }
Esempio n. 9
0
  private void initBoolDecoder() throws IOException {

    value = 0; /* value = first 16 input bits */

    data.seek(offset);
    value = data.readUnsignedByte() << 8;
    // value = (data[offset]) << 8;
    offset++;

    range = 255; /* initial range is full */
    bit_count = 0; /* have not yet shifted out any bits */
  }
Esempio n. 10
0
    BufferedImage getThumbnail(ImageInputStream iis, JPEGImageReader reader) throws IOException {
      iis.mark();
      iis.seek(streamPos);
      DataBufferByte buffer = new DataBufferByte(getLength());
      readByteBuffer(iis, buffer.getData(), reader, 1.0F, 0.0F);
      iis.reset();

      WritableRaster raster =
          Raster.createInterleavedRaster(
              buffer, thumbWidth, thumbHeight, thumbWidth * 3, 3, new int[] {0, 1, 2}, null);
      ColorModel cm =
          new ComponentColorModel(
              JPEG.JCS.sRGB, false, false, ColorModel.OPAQUE, DataBuffer.TYPE_BYTE);
      return new BufferedImage(cm, raster, false, null);
    }
Esempio n. 11
0
    BufferedImage getThumbnail(ImageInputStream iis, JPEGImageReader reader) throws IOException {
      iis.mark();
      iis.seek(streamPos);
      // read the palette
      byte[] palette = new byte[PALETTE_SIZE];
      float palettePart = ((float) PALETTE_SIZE) / getLength();
      readByteBuffer(iis, palette, reader, palettePart, 0.0F);
      DataBufferByte buffer = new DataBufferByte(thumbWidth * thumbHeight);
      readByteBuffer(iis, buffer.getData(), reader, 1.0F - palettePart, palettePart);
      iis.read();
      iis.reset();

      IndexColorModel cm = new IndexColorModel(8, 256, palette, 0, false);
      SampleModel sm = cm.createCompatibleSampleModel(thumbWidth, thumbHeight);
      WritableRaster raster = Raster.createWritableRaster(sm, buffer, null);
      return new BufferedImage(cm, raster, false, null);
    }
Esempio n. 12
0
  public MarkerSegment readSegment() throws IOException {
    if (!init) {
      init = true;
      stream.seek(position);
    }

    final int code = stream.readShort() & 0x0000ffff;

    // stream.seek(position + length - 2);

    final MarkerType markerType = MarkerType.get(code);
    if (markerType != null) {
      final MarkerSegment segment = markerType.createSegment();
      segment.readFrom(stream);
      return segment;
    } else {
      final MarkerSegment segment = new IgnoredSegment(code);
      segment.readFrom(stream);
      return segment;
    }
  }
Esempio n. 13
0
  // 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;
  }
Esempio n. 14
0
 private void parseHeader() throws IOException {
   if (!propertiesParsed) {
     throw new IllegalStateException("Properties need to be parsed before header.");
   }
   stream.seek(propertiesByteSize);
   String line;
   long posInStream = stream.getStreamPosition();
   while ((line = stream.readLine()) != null) {
     if (line.startsWith("#")) {
       propertiesByteSize += (stream.getStreamPosition() - posInStream);
       posInStream = stream.getStreamPosition();
       continue;
     }
     headerByteSize += (stream.getStreamPosition() - posInStream);
     final String separator =
         properties.get("separator") != null
             ? properties.get("separator")
             : Constants.DEFAULT_SEPARATOR;
     createFeatureType(line.split(separator));
     break;
   }
 }
Esempio n. 15
0
  private void readHeader() throws IOException {
    if (gotHeader) {
      iis.seek(128);
      return;
    }

    metadata = new PCXMetadata();

    manufacturer = iis.readByte(); // manufacturer
    if (manufacturer != MANUFACTURER) throw new IllegalStateException("image is not a PCX file");
    metadata.version = iis.readByte(); // version
    encoding = iis.readByte(); // encoding
    if (encoding != ENCODING)
      throw new IllegalStateException("image is not a PCX file, invalid encoding " + encoding);

    metadata.bitsPerPixel = iis.readByte();

    metadata.xmin = iis.readShort();
    metadata.ymin = iis.readShort();
    xmax = iis.readShort();
    ymax = iis.readShort();

    metadata.hdpi = iis.readShort();
    metadata.vdpi = iis.readShort();

    iis.readFully(smallPalette);

    iis.readByte(); // reserved

    colorPlanes = iis.readByte();
    bytesPerLine = iis.readShort();
    paletteType = iis.readShort();

    metadata.hsize = iis.readShort();
    metadata.vsize = iis.readShort();

    iis.skipBytes(54); // skip filler

    width = xmax - metadata.xmin + 1;
    height = ymax - metadata.ymin + 1;

    if (colorPlanes == 1) {
      if (paletteType == PALETTE_GRAYSCALE) {
        ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_GRAY);
        int[] nBits = {8};
        colorModel =
            new ComponentColorModel(
                cs, nBits, false, false, Transparency.OPAQUE, DataBuffer.TYPE_BYTE);
        sampleModel =
            new ComponentSampleModel(DataBuffer.TYPE_BYTE, width, height, 1, width, new int[] {0});
      } else {
        if (metadata.bitsPerPixel == 8) {
          // read palette from end of file, then reset back to image data
          iis.mark();

          if (iis.length() == -1) {
            // read until eof, and work backwards
            while (iis.read() != -1) ;
            iis.seek(iis.getStreamPosition() - 256 * 3 - 1);
          } else {
            iis.seek(iis.length() - 256 * 3 - 1);
          }

          int palletteMagic = iis.read();
          if (palletteMagic != 12)
            processWarningOccurred(
                "Expected palette magic number 12; instead read "
                    + palletteMagic
                    + " from this image.");

          iis.readFully(largePalette);
          iis.reset();

          colorModel = new IndexColorModel(metadata.bitsPerPixel, 256, largePalette, 0, false);
          sampleModel = colorModel.createCompatibleSampleModel(width, height);
        } else {
          int msize = metadata.bitsPerPixel == 1 ? 2 : 16;
          colorModel = new IndexColorModel(metadata.bitsPerPixel, msize, smallPalette, 0, false);
          sampleModel = colorModel.createCompatibleSampleModel(width, height);
        }
      }
    } else {
      ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
      int[] nBits = {8, 8, 8};
      colorModel =
          new ComponentColorModel(
              cs, nBits, false, false, Transparency.OPAQUE, DataBuffer.TYPE_BYTE);
      sampleModel =
          new ComponentSampleModel(
              DataBuffer.TYPE_BYTE,
              width,
              height,
              1,
              width * colorPlanes,
              new int[] {0, width, width * 2});
    }

    originalSampleModel = sampleModel;
    originalColorModel = colorModel;

    gotHeader = true;
  }
Esempio n. 16
0
 public void seek() throws IOException {
   data.seek(offset);
 }
Esempio n. 17
0
  public void initialize(
      ImageInputStream stream, boolean ignoreUnknownFields, final boolean isBTIFF)
      throws IOException {
    removeTIFFFields();

    List tagSetList = getTagSetList();

    final long numEntries;
    if (isBTIFF) numEntries = stream.readLong();
    else numEntries = stream.readUnsignedShort();

    for (int i = 0; i < numEntries; i++) {
      // Read tag number, value type, and value count.
      int tag = stream.readUnsignedShort();
      int type = stream.readUnsignedShort();
      int count;
      if (isBTIFF) {
        long count_ = stream.readLong();
        count = (int) count_;
        if (count != count_)
          throw new IllegalArgumentException("unable to use long number of values");
      } else count = (int) stream.readUnsignedInt();

      // Get the associated TIFFTag.
      TIFFTag tiffTag = getTag(tag, tagSetList);

      // Ignore unknown fields.
      if (ignoreUnknownFields && tiffTag == null) {
        // Skip the value/offset so as to leave the stream
        // position at the start of the next IFD entry.

        if (isBTIFF) stream.skipBytes(8);
        else stream.skipBytes(4);

        // XXX Warning message ...

        // Continue with the next IFD entry.
        continue;
      }

      long nextTagOffset;

      if (isBTIFF) {
        nextTagOffset = stream.getStreamPosition() + 8;
        int sizeOfType = TIFFTag.getSizeOfType(type);
        if (count * sizeOfType > 8) {
          long value = stream.readLong();
          stream.seek(value);
        }
      } else {
        nextTagOffset = stream.getStreamPosition() + 4;
        int sizeOfType = TIFFTag.getSizeOfType(type);
        if (count * sizeOfType > 4) {
          long value = stream.readUnsignedInt();
          stream.seek(value);
        }
      }

      if (tag == BaselineTIFFTagSet.TAG_STRIP_BYTE_COUNTS
          || tag == BaselineTIFFTagSet.TAG_TILE_BYTE_COUNTS
          || tag == BaselineTIFFTagSet.TAG_JPEG_INTERCHANGE_FORMAT_LENGTH) {
        this.stripOrTileByteCountsPosition = stream.getStreamPosition();
        if (LAZY_LOADING) {
          type = type == TIFFTag.TIFF_LONG ? TIFFTag.TIFF_LAZY_LONG : TIFFTag.TIFF_LAZY_LONG8;
        }
      } else if (tag == BaselineTIFFTagSet.TAG_STRIP_OFFSETS
          || tag == BaselineTIFFTagSet.TAG_TILE_OFFSETS
          || tag == BaselineTIFFTagSet.TAG_JPEG_INTERCHANGE_FORMAT) {
        this.stripOrTileOffsetsPosition = stream.getStreamPosition();
        if (LAZY_LOADING) {
          type = type == TIFFTag.TIFF_LONG ? TIFFTag.TIFF_LAZY_LONG : TIFFTag.TIFF_LAZY_LONG8;
        }
      }

      Object obj = null;

      try {
        switch (type) {
          case TIFFTag.TIFF_BYTE:
          case TIFFTag.TIFF_SBYTE:
          case TIFFTag.TIFF_UNDEFINED:
          case TIFFTag.TIFF_ASCII:
            byte[] bvalues = new byte[count];
            stream.readFully(bvalues, 0, count);

            if (type == TIFFTag.TIFF_ASCII) {
              // Can be multiple strings
              final List<String> v = new ArrayList<String>();
              boolean inString = false;
              int prevIndex = 0;
              for (int index = 0; index <= count; index++) {
                if (index < count && bvalues[index] != 0) {
                  if (!inString) {
                    // start of string
                    prevIndex = index;
                    inString = true;
                  }
                } else { // null or special case at end of string
                  if (inString) {
                    // end of string
                    final String s = new String(bvalues, prevIndex, index - prevIndex);
                    v.add(s);
                    inString = false;
                  }
                }
              }

              count = v.size();
              String[] strings;
              if (count != 0) {
                strings = new String[count];
                for (int c = 0; c < count; c++) {
                  strings[c] = v.get(c);
                }
              } else {
                // This case has been observed when the value of
                // 'count' recorded in the field is non-zero but
                // the value portion contains all nulls.
                count = 1;
                strings = new String[] {""};
              }

              obj = strings;
            } else {
              obj = bvalues;
            }
            break;

          case TIFFTag.TIFF_SHORT:
            char[] cvalues = new char[count];
            for (int j = 0; j < count; j++) {
              cvalues[j] = (char) (stream.readUnsignedShort());
            }
            obj = cvalues;
            break;

          case TIFFTag.TIFF_LONG:
          case TIFFTag.TIFF_IFD_POINTER:
            long[] lvalues = new long[count];
            for (int j = 0; j < count; j++) {
              lvalues[j] = stream.readUnsignedInt();
            }
            obj = lvalues;
            break;

          case TIFFTag.TIFF_RATIONAL:
            long[][] llvalues = new long[count][2];
            for (int j = 0; j < count; j++) {
              llvalues[j][0] = stream.readUnsignedInt();
              llvalues[j][1] = stream.readUnsignedInt();
            }
            obj = llvalues;
            break;

          case TIFFTag.TIFF_SSHORT:
            short[] svalues = new short[count];
            for (int j = 0; j < count; j++) {
              svalues[j] = stream.readShort();
            }
            obj = svalues;
            break;

          case TIFFTag.TIFF_SLONG:
            int[] ivalues = new int[count];
            for (int j = 0; j < count; j++) {
              ivalues[j] = stream.readInt();
            }
            obj = ivalues;
            break;

          case TIFFTag.TIFF_SRATIONAL:
            int[][] iivalues = new int[count][2];
            for (int j = 0; j < count; j++) {
              iivalues[j][0] = stream.readInt();
              iivalues[j][1] = stream.readInt();
            }
            obj = iivalues;
            break;

          case TIFFTag.TIFF_FLOAT:
            float[] fvalues = new float[count];
            for (int j = 0; j < count; j++) {
              fvalues[j] = stream.readFloat();
            }
            obj = fvalues;
            break;

          case TIFFTag.TIFF_DOUBLE:
            double[] dvalues = new double[count];
            for (int j = 0; j < count; j++) {
              dvalues[j] = stream.readDouble();
            }
            obj = dvalues;
            break;

          case TIFFTag.TIFF_LONG8:
          case TIFFTag.TIFF_SLONG8:
          case TIFFTag.TIFF_IFD8:
            long[] lBvalues = new long[count];
            for (int j = 0; j < count; j++) {
              lBvalues[j] = stream.readLong();
            }
            obj = lBvalues;
            break;

          case TIFFTag.TIFF_LAZY_LONG8:
          case TIFFTag.TIFF_LAZY_LONG:
            obj = new TIFFLazyData(stream, type, count);
            break;
          default:
            // XXX Warning
            break;
        }
      } catch (EOFException eofe) {
        // The TIFF 6.0 fields have tag numbers less than or equal
        // to 532 (ReferenceBlackWhite) or equal to 33432 (Copyright).
        // If there is an error reading a baseline tag, then re-throw
        // the exception and fail; otherwise continue with the next
        // field.
        if (BaselineTIFFTagSet.getInstance().getTag(tag) == null) {
          throw eofe;
        }
      }

      if (tiffTag == null) {
        // XXX Warning: unknown tag
      } else if (!tiffTag.isDataTypeOK(type)) {
        // XXX Warning: bad data type
      } else if (tiffTag.isIFDPointer() && obj != null) {
        stream.mark();
        stream.seek(((long[]) obj)[0]);

        List tagSets = new ArrayList(1);
        tagSets.add(tiffTag.getTagSet());
        TIFFIFD subIFD = new TIFFIFD(tagSets);

        // XXX Use same ignore policy for sub-IFD fields?
        subIFD.initialize(stream, ignoreUnknownFields);
        obj = subIFD;
        stream.reset();
      }

      if (tiffTag == null) {
        tiffTag = new TIFFTag(null, tag, 1 << type, null);
      }

      // Add the field if its contents have been initialized which
      // will not be the case if an EOF was ignored above.
      if (obj != null) {
        TIFFField f = new TIFFField(tiffTag, type, count, obj);
        addTIFFField(f);
      }

      stream.seek(nextTagOffset);
    }

    this.lastPosition = stream.getStreamPosition();
  }
  /** Reads the header. Does nothing if the header has already been loaded. */
  private void readHeader() throws IOException {
    if (numImages == -1) {
      ImageInputStream in = (ImageInputStream) getInput();
      in.seek(0);
      er = new EXIFReader(in);
      er.setFirstImageOnly(false);
      er.read();

      // Get some information that is easy to obtain through a map
      {
        HashMap<TIFFTag, TIFFField> m = er.getMetaDataMap();
        TIFFField mde;
        if ((mde = m.get(MPFTagSet.get(MPFTagSet.TAG_NumberOfImages))) != null) {
          numImages = ((Number) mde.getData()).intValue();
        } else {
          numImages = 1;
        }
        if ((mde = m.get(EXIFTagSet.PixelXDimension)) != null) {
          width = ((Number) mde.getData()).intValue();
        }
        if ((mde = m.get(EXIFTagSet.PixelYDimension)) != null) {
          height = ((Number) mde.getData()).intValue();
        }
      }
      imageOffsets = new long[numImages];
      imageLengths = new long[numImages];
      if (numImages == 1) {
        imageOffsets[0] = 0;
        imageLengths[0] = in.length();
      }

      // Get now at the tough part
      int index = 0;
      for (Iterator<TIFFNode> e = er.getMetaDataTree().preorderIterator(); e.hasNext(); ) {
        TIFFNode n = e.next();
        if (n instanceof TIFFDirectory) {
          TIFFDirectory dir = (TIFFDirectory) n;
          // System.out.println("dir:" + dir.getName());
          if (dir.getName() != null && dir.getName().equals("MPEntry")) {
            long dirOffset = dir.getFileSegments().get(0).getOffset();
            TIFFField offsetField = dir.getField(MPEntryTagSet.IndividualImageDataOffset);
            TIFFField lengthField = dir.getField(MPEntryTagSet.IndividualImageSize);
            if (offsetField != null && lengthField != null) {
              long dataOffset = (Long) offsetField.getData();
              imageOffsets[index] = dataOffset == 0 ? 0 : dirOffset + dataOffset;
              imageLengths[index] = (Long) lengthField.getData();
              index++;
            }
          }
        }
      }

      // Store metadata for later access
      String formatName = "com_sun_media_imageio_plugins_tiff_image_1.0";
      imageMetadata = new IIOMetadata[numImages];
      for (int i = 0; i < numImages; i++) {
        imageMetadata[i] = new DefaultIIOMetadata(formatName, er.getIIOMetadataTree(formatName, i));
      }

      in.seek(0);
    }
  }
Esempio n. 19
0
  /**
   * Initializes these instance variables from the image metadata:
   *
   * <pre>
   * compression
   * width
   * height
   * samplesPerPixel
   * numBands
   * colorMap
   * photometricInterpretation
   * sampleFormat
   * bitsPerSample
   * extraSamples
   * tileOrStripWidth
   * tileOrStripHeight
   * </pre>
   */
  private void initializeFromMetadata() {
    TIFFField f;

    // Compression
    f = imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_COMPRESSION);
    if (f == null) {
      processWarningOccurred("Compression field is missing; assuming no compression");
      compression = BaselineTIFFTagSet.COMPRESSION_NONE;
    } else {
      compression = f.getAsInt(0);
    }

    // Whether key dimensional information is absent.
    boolean isMissingDimension = false;

    // ImageWidth -> width
    f = imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_IMAGE_WIDTH);
    if (f != null) {
      this.width = f.getAsInt(0);
    } else {
      processWarningOccurred("ImageWidth field is missing.");
      isMissingDimension = true;
    }

    // ImageLength -> height
    f = imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_IMAGE_LENGTH);
    if (f != null) {
      this.height = f.getAsInt(0);
    } else {
      processWarningOccurred("ImageLength field is missing.");
      isMissingDimension = true;
    }

    // SamplesPerPixel
    f = imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_SAMPLES_PER_PIXEL);
    if (f != null) {
      samplesPerPixel = f.getAsInt(0);
    } else {
      samplesPerPixel = 1;
      isMissingDimension = true;
    }

    // If any dimension is missing and there is a JPEG stream available
    // get the information from it.
    int defaultBitDepth = 1;
    if (isMissingDimension
        && (f = imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_JPEG_INTERCHANGE_FORMAT))
            != null) {
      Iterator iter = ImageIO.getImageReadersByFormatName("JPEG");
      if (iter != null && iter.hasNext()) {
        ImageReader jreader = (ImageReader) iter.next();
        try {
          stream.mark();
          stream.seek(f.getAsLong(0));
          jreader.setInput(stream);
          if (imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_IMAGE_WIDTH) == null) {
            this.width = jreader.getWidth(0);
          }
          if (imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_IMAGE_LENGTH) == null) {
            this.height = jreader.getHeight(0);
          }
          ImageTypeSpecifier imageType = jreader.getRawImageType(0);
          if (imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_SAMPLES_PER_PIXEL) == null) {
            this.samplesPerPixel = imageType.getSampleModel().getNumBands();
          }
          stream.reset();
          defaultBitDepth = imageType.getColorModel().getComponentSize(0);
        } catch (IOException e) {
          // Ignore it and proceed: an error will occur later.
        }
        jreader.dispose();
      }
    }

    if (samplesPerPixel < 1) {
      processWarningOccurred("Samples per pixel < 1!");
    }

    // SamplesPerPixel -> numBands
    numBands = samplesPerPixel;

    // ColorMap
    this.colorMap = null;
    f = imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_COLOR_MAP);
    if (f != null) {
      // Grab color map
      colorMap = f.getAsChars();
    }

    // PhotometricInterpretation
    f = imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_PHOTOMETRIC_INTERPRETATION);
    if (f == null) {
      if (compression == BaselineTIFFTagSet.COMPRESSION_CCITT_RLE
          || compression == BaselineTIFFTagSet.COMPRESSION_CCITT_T_4
          || compression == BaselineTIFFTagSet.COMPRESSION_CCITT_T_6) {
        processWarningOccurred(
            "PhotometricInterpretation field is missing; " + "assuming WhiteIsZero");
        photometricInterpretation = BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_WHITE_IS_ZERO;
      } else if (this.colorMap != null) {
        photometricInterpretation = BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_PALETTE_COLOR;
      } else if (samplesPerPixel == 3 || samplesPerPixel == 4) {
        photometricInterpretation = BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_RGB;
      } else {
        processWarningOccurred(
            "PhotometricInterpretation field is missing; " + "assuming BlackIsZero");
        photometricInterpretation = BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_BLACK_IS_ZERO;
      }
    } else {
      photometricInterpretation = f.getAsInt(0);
    }

    // SampleFormat
    boolean replicateFirst = false;
    int first = -1;

    f = imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_SAMPLE_FORMAT);
    sampleFormat = new int[samplesPerPixel];
    replicateFirst = false;
    if (f == null) {
      replicateFirst = true;
      first = BaselineTIFFTagSet.SAMPLE_FORMAT_UNDEFINED;
    } else if (f.getCount() != samplesPerPixel) {
      replicateFirst = true;
      first = f.getAsInt(0);
    }

    for (int i = 0; i < samplesPerPixel; i++) {
      sampleFormat[i] = replicateFirst ? first : f.getAsInt(i);
      if (sampleFormat[i] != BaselineTIFFTagSet.SAMPLE_FORMAT_UNSIGNED_INTEGER
          && sampleFormat[i] != BaselineTIFFTagSet.SAMPLE_FORMAT_SIGNED_INTEGER
          && sampleFormat[i] != BaselineTIFFTagSet.SAMPLE_FORMAT_FLOATING_POINT
          && sampleFormat[i] != BaselineTIFFTagSet.SAMPLE_FORMAT_UNDEFINED) {
        processWarningOccurred("Illegal value for SAMPLE_FORMAT, assuming SAMPLE_FORMAT_UNDEFINED");
        sampleFormat[i] = BaselineTIFFTagSet.SAMPLE_FORMAT_UNDEFINED;
      }
    }

    // BitsPerSample
    f = imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_BITS_PER_SAMPLE);
    this.bitsPerSample = new int[samplesPerPixel];
    replicateFirst = false;
    if (f == null) {
      replicateFirst = true;
      first = defaultBitDepth;
    } else if (f.getCount() != samplesPerPixel) {
      replicateFirst = true;
      first = f.getAsInt(0);
    }

    for (int i = 0; i < samplesPerPixel; i++) {
      // Replicate initial value if not enough values provided
      bitsPerSample[i] = replicateFirst ? first : f.getAsInt(i);

      if (DEBUG) {
        System.out.println("bitsPerSample[" + i + "] = " + bitsPerSample[i]);
      }
    }

    // ExtraSamples
    this.extraSamples = null;
    f = imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_EXTRA_SAMPLES);
    if (f != null) {
      extraSamples = f.getAsInts();
    }

    //         System.out.println("colorMap = " + colorMap);
    //         if (colorMap != null) {
    //             for (int i = 0; i < colorMap.length; i++) {
    //              System.out.println("colorMap[" + i + "] = " + (int)(colorMap[i]));
    //             }
    //         }

  }
    private void readTileData(
        File outputFile,
        int tileX,
        int tileY,
        int tileWidth,
        int tileHeight,
        int jp2TileX,
        int jp2TileY,
        int jp2TileWidth,
        int jp2TileHeight,
        short[] tileData,
        Rectangle destRect)
        throws IOException {

      synchronized (this) {
        if (!locks.containsKey(outputFile)) {
          locks.put(outputFile, new Object());
        }
      }
      final Object lock = locks.get(outputFile);

      synchronized (lock) {
        Jp2File jp2File = getOpenJ2pFile(outputFile);

        int jp2Width = jp2File.width;
        int jp2Height = jp2File.height;
        if (jp2Width > jp2TileWidth || jp2Height > jp2TileHeight) {
          throw new IllegalStateException(
              String.format(
                  "width (=%d) > tileWidth (=%d) || height (=%d) > tileHeight (=%d)",
                  jp2Width, jp2TileWidth, jp2Height, jp2TileHeight));
        }

        int jp2X = destRect.x - jp2TileX * jp2TileWidth;
        int jp2Y = destRect.y - jp2TileY * jp2TileHeight;
        if (jp2X < 0 || jp2Y < 0) {
          throw new IllegalStateException(
              String.format("jp2X (=%d) < 0 || jp2Y (=%d) < 0", jp2X, jp2Y));
        }

        final ImageInputStream stream = jp2File.stream;

        if (jp2X == 0
            && jp2Width == tileWidth
            && jp2Y == 0
            && jp2Height == tileHeight
            && tileWidth * tileHeight == tileData.length) {
          stream.seek(jp2File.dataPos);
          stream.readFully(tileData, 0, tileData.length);
        } else {
          final Rectangle jp2FileRect = new Rectangle(0, 0, jp2Width, jp2Height);
          final Rectangle tileRect = new Rectangle(jp2X, jp2Y, tileWidth, tileHeight);
          final Rectangle intersection = jp2FileRect.intersection(tileRect);
          System.out.printf(
              "%s: tile=(%d,%d): jp2FileRect=%s, tileRect=%s, intersection=%s\n",
              jp2File.file, tileX, tileY, jp2FileRect, tileRect, intersection);
          if (!intersection.isEmpty()) {
            long seekPos =
                jp2File.dataPos + NUM_SHORT_BYTES * (intersection.y * jp2Width + intersection.x);
            int tilePos = 0;
            for (int y = 0; y < intersection.height; y++) {
              stream.seek(seekPos);
              stream.readFully(tileData, tilePos, intersection.width);
              seekPos += NUM_SHORT_BYTES * jp2Width;
              tilePos += tileWidth;
              for (int x = intersection.width; x < tileWidth; x++) {
                tileData[y * tileWidth + x] = (short) 0;
              }
            }
            for (int y = intersection.height; y < tileWidth; y++) {
              for (int x = 0; x < tileWidth; x++) {
                tileData[y * tileWidth + x] = (short) 0;
              }
            }
          } else {
            Arrays.fill(tileData, (short) 0);
          }
        }
      }
    }
 @Override
 public void seek(final long pos) throws IOException {
   iis.seek(pos);
 }