/**
   * Construct an OpImage given a String representation of a URL, a resolution, and a sub-image
   * index.
   *
   * @param URLSpec The URL of the IIP image including the FIF cimmand if needed and possibly an SDS
   *     command.
   * @param level The resolution level with 0 as the lowest resolution.
   * @param subImage The subimage number.
   * @param layout The layout hint; may be null.
   */
  public IIPResolutionOpImage(Map config, String URLSpec, int level, int subImage) {
    super(
        (Vector) null, // the image is sourceless
        layoutHelper(URLSpec, level, subImage),
        config,
        false);

    this.renderHints = (RenderingHints) config;

    // Cache the constructor parameters.
    URLString = URLSpec;
    this.subImage = subImage;

    // Retrieve required parameters from server.
    String[] cmd = new String[] {"OBJ=Resolution-number"};
    InputStream stream = postCommands(cmd);
    String label = null;
    while ((label = getLabel(stream)) != null) {
      if (label.equals("resolution-number")) {
        String data = getDataAsString(stream, false);
        int numRes = Integer.valueOf(data).intValue();
        if (level < 0) {
          resolution = 0;
        } else if (level >= numRes) {
          resolution = numRes - 1;
        } else {
          resolution = level;
        }
      } else {
        checkError(label, stream, true);
      }
    }
    endResponse(stream);

    // Cache some values which will be used repetitively.
    ColorSpace cs = colorModel.getColorSpace();
    if (cs.isCS_sRGB()) {
      colorSpaceType = CS_NIFRGB;
    } else if (cs.equals(ColorSpace.getInstance(ColorSpace.CS_GRAY))) {
      colorSpaceType = CS_MONOCHROME;
    } else {
      colorSpaceType = CS_PHOTOYCC;
    }
    hasAlpha = colorModel.hasAlpha();
    isAlphaPremultilpied = colorModel.isAlphaPremultiplied();
    minTileX = getMinTileX();
    minTileY = getMinTileY();
    numXTiles = getNumXTiles();
  }
Esempio n. 2
0
  /**
   * Parse the image stream into a buffered image. Note that this is guaranteed to be called after
   * all the other setXXX methods have been called.
   *
   * <p>NOTE: the color convolving is extremely slow on large images. It would be good to see if it
   * could be moved out into the rendering phases, where we might be able to scale the image down
   * first.</p
   */
  protected BufferedImage parseData(byte[] data) {
    // create the data buffer
    DataBuffer db = new DataBufferByte(data, data.length);

    // pick a color model, based on the number of components and
    // bits per component
    ColorModel cm = getColorModel();

    // create a compatible raster
    SampleModel sm = cm.createCompatibleSampleModel(getWidth(), getHeight());
    WritableRaster raster;
    try {
      raster = Raster.createWritableRaster(sm, db, new Point(0, 0));
    } catch (RasterFormatException e) {
      int tempExpectedSize =
          getWidth()
              * getHeight()
              * getColorSpace().getNumComponents()
              * Math.max(8, getBitsPerComponent())
              / 8;

      if (tempExpectedSize < 3) {
        tempExpectedSize = 3;
      }
      if (tempExpectedSize > data.length) {
        byte[] tempLargerData = new byte[tempExpectedSize];
        System.arraycopy(data, 0, tempLargerData, 0, data.length);
        db = new DataBufferByte(tempLargerData, tempExpectedSize);
        raster = Raster.createWritableRaster(sm, db, new Point(0, 0));
      } else {
        throw e;
      }
    }

    /*
     * Workaround for a bug on the Mac -- a class cast exception in
     * drawImage() due to the wrong data buffer type (?)
     */
    BufferedImage bi = null;
    if (cm instanceof IndexColorModel) {
      IndexColorModel icm = (IndexColorModel) cm;

      // choose the image type based on the size
      int type = BufferedImage.TYPE_BYTE_BINARY;
      if (getBitsPerComponent() == 8) {
        type = BufferedImage.TYPE_BYTE_INDEXED;
      }

      // create the image with an explicit indexed color model.
      bi = new BufferedImage(getWidth(), getHeight(), type, icm);

      // set the data explicitly as well
      bi.setData(raster);
    } else {
      // Raster is already in a format which is supported by Java2D,
      // such as RGB or Gray.
      bi = new BufferedImage(cm, raster, true, null);
    }

    // hack to avoid *very* slow conversion
    ColorSpace cs = cm.getColorSpace();
    ColorSpace rgbCS = ColorSpace.getInstance(ColorSpace.CS_sRGB);
    if (!isImageMask() && cs instanceof ICC_ColorSpace && !cs.equals(rgbCS)) {
      ColorConvertOp op = new ColorConvertOp(cs, rgbCS, null);

      BufferedImage converted =
          new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB);

      bi = op.filter(bi, converted);
    }

    // add in the alpha data supplied by the SMask, if any
    PDFImage sMaskImage = getSMask();
    if (sMaskImage != null) {
      BufferedImage si = sMaskImage.getImage();
      BufferedImage outImage =
          new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB);

      int[] srcArray = new int[this.width];
      int[] maskArray = new int[this.width];

      for (int i = 0; i < this.height; i++) {
        bi.getRGB(0, i, this.width, 1, srcArray, 0, this.width);
        si.getRGB(0, i, this.width, 1, maskArray, 0, this.width);

        for (int j = 0; j < this.width; j++) {
          int ac = 0xff000000;

          maskArray[j] = ((maskArray[j] & 0xff) << 24) | (srcArray[j] & ~ac);
        }

        outImage.setRGB(0, i, this.width, 1, maskArray, 0, this.width);
      }

      bi = outImage;
    }

    return (bi);
  }