/** * 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(); }
/** * 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); }