/******************************************************************************* * Copyright (c) 2016 Weasis Team and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Nicolas Roduit - initial API and implementation *******************************************************************************/ package org.weasis.image.jni; import java.awt.Point; import java.awt.Rectangle; import java.awt.image.DataBuffer; import java.awt.image.Raster; import java.awt.image.WritableRaster; import java.io.IOException; import javax.imageio.ImageReadParam; import javax.imageio.ImageTypeSpecifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.sun.media.imageioimpl.common.SimpleRenderedImage; public class NativeRenderedImage extends SimpleRenderedImage { private static final Logger LOGGER = LoggerFactory.getLogger(NativeRenderedImage.class); private Raster currentTile; private Point currentTileGrid; private NativeImageReader reader; private ImageReadParam param = null; private int imageIndex; public NativeRenderedImage(NativeImageReader reader, ImageReadParam param, int imageIndex) throws IOException { this.reader = reader; this.param = param; this.imageIndex = imageIndex; ImageParameters params = reader.getInfoImage(imageIndex, param); this.tileWidth = params.getTileWidth(); this.tileHeight = params.getTileHeight(); this.tileGridXOffset = params.getTileGridXOffset(); this.tileGridYOffset = params.getTileGridYOffset(); this.width = params.getWidth(); this.height = params.getHeight(); this.minX = 0; this.minY = 0; if (tileWidth < 64 || tileHeight < 64) { this.tileWidth = this.width; this.tileHeight = this.height; } ImageTypeSpecifier type = NativeImageReader.createImageType(params, null, null, null, null, null); colorModel = type.getColorModel(); sampleModel = type.getSampleModel().createCompatibleSampleModel(tileWidth, tileHeight); } @Override public synchronized Raster getTile(int tileX, int tileY) { if (currentTile != null && currentTileGrid.x == tileX && currentTileGrid.y == tileY) { return currentTile; } try { long start = System.currentTimeMillis(); boolean tiled = width != tileWidth || height != tileHeight; int x = tileXToX(tileX); int y = tileYToY(tileY); if (tiled) { param.setSourceRegion(new Rectangle(x, y, tileWidth, tileHeight)); } // param.setDestinationType(new ImageTypeSpecifier(colorModel, sampleModel)); NativeImage img = reader.getImage(imageIndex, param); if (img == null) { return null; } DataBuffer db = NativeImageReader.createDataBuffer(img); if (db == null) { return null; } currentTile = Raster.createWritableRaster(sampleModel, db, new Point(x, y)); long stop = System.currentTimeMillis(); LOGGER.debug("Building BufferedImage time: {} ms", (stop - start)); //$NON-NLS-1$ } catch (IOException e) { LOGGER.error("Cannot retrieve tile: {}", e.getMessage()); } int originalNumXTiles = getNumXTiles(); int originalNumYTiles = getNumYTiles(); if (tileX >= originalNumXTiles || tileY >= originalNumYTiles) { throw new IllegalArgumentException(); } if (currentTileGrid == null) { currentTileGrid = new Point(tileX, tileY); } else { currentTileGrid.x = tileX; currentTileGrid.y = tileY; } return currentTile; } public void readAsRaster(WritableRaster raster) throws java.io.IOException { readSubsampledRaster(raster); } private Raster readSubsampledRaster(WritableRaster raster) throws java.io.IOException { throw new IOException("Subsampled not supported"); } }