/* * Geotools2 - OpenSource mapping toolkit * http://geotools.org * (C) 2002, Geotools Project Managment Committee (PMC) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * */ package org.geotools.arcsde.gce.producer; import java.awt.image.BufferedImage; import java.awt.image.DataBufferByte; import com.esri.sde.sdk.client.SeRasterAttr; import com.esri.sde.sdk.client.SeRasterConsumer; import com.esri.sde.sdk.client.SeRasterRenderedImage; import com.esri.sde.sdk.client.SeRasterScanLineGenerator; import com.esri.sde.sdk.client.SeRasterScanLineProducer; public class ArcSDERasterOneBitPerBandProducerImpl extends ArcSDERasterProducer { /** * Use this constructor if you need to pass a particular implementation to code which will later * inject the SeRasterAttr, maskType and source BufferedImage later. */ public ArcSDERasterOneBitPerBandProducerImpl() { super(null, null, SeRasterScanLineGenerator.MASK_ALL_ON); } public ArcSDERasterOneBitPerBandProducerImpl(SeRasterAttr attr, BufferedImage sourceImage, int maskType) { super(attr, sourceImage, maskType); } /** * @see org.geotools.arcsde.gce.producer.ArcSDERasterProducer#setSourceImage(java.awt.image.BufferedImage) */ @Override public void setSourceImage(BufferedImage sourceImage) { for (int i = 0; i < sourceImage.getSampleModel().getSampleSize().length; i++) { if (sourceImage.getSampleModel().getSampleSize(i) != 1) { throw new IllegalArgumentException( "Source image must be one bit per sample on all bands. Band " + i + " has " + sourceImage.getSampleModel().getSampleSize(i) + " bits per sample."); } } if (!(sourceImage.getData().getDataBuffer() instanceof DataBufferByte)) { throw new IllegalArgumentException("Currently one-bit-per-band raster loading is " + "only supported from images backed with a DataBufferByte"); } this.sourceImage = sourceImage; } /** * @see com.esri.sde.sdk.client.SeRasterProducer#startProduction(com.esri.sde.sdk.client.SeRasterConsumer) * Also take a look at {@link SeRasterScanLineProducer} for an (opaque) ESRI supplied * implementation of this functionality that only works with some sort of 8-bit images. * Note that due to some synchronization problems inherent in the SDE api code, the * startProduction() method MUST return before consumer.setScanLines() or * consumer.setRasterTiles() is called. Hence the thread implementation. */ public void startProduction(final SeRasterConsumer consumer) { Thread runme; if (consumer instanceof SeRasterRenderedImage) { runme = new Thread() { @Override public void run() { try { final int imageHeight = sourceImage.getHeight(); // for each band... for (int i = 0; i < sourceImage.getData().getNumBands(); i++) { // luckily the byte-packed data format in MultiPixelPackedSampleModel is // identical // to the one-bit-per-pixel format expected by ArcSDE. final byte[] imgBandData = ((DataBufferByte) sourceImage.getData() .getDataBuffer()).getData(i); consumer.setScanLines(imageHeight, imgBandData, null); consumer.rasterComplete(SeRasterConsumer.SINGLEFRAMEDONE); } consumer.rasterComplete(SeRasterConsumer.STATICIMAGEDONE); } catch (Exception se) { se.printStackTrace(); consumer.rasterComplete(SeRasterConsumer.IMAGEERROR); } } }; } else { throw new IllegalArgumentException("You must set SeRasterAttr.setImportMode(false) to " + "load data using this SeProducer implementation."); } runme.start(); } }