001: /*
002: * Geotools2 - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2002, Geotools Project Managment Committee (PMC)
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation;
009: * version 2.1 of the License.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: */
017: package org.geotools.arcsde.gce.band;
018:
019: import java.awt.image.DataBuffer;
020: import java.awt.image.SampleModel;
021: import java.awt.image.WritableRaster;
022: import java.util.logging.Level;
023: import java.util.logging.Logger;
024:
025: import org.geotools.data.DataSourceException;
026:
027: import com.esri.sde.sdk.client.SeException;
028: import com.esri.sde.sdk.client.SeRasterTile;
029:
030: public class UnsignedByteBandCopier extends ArcSDERasterBandCopier {
031:
032: UnsignedByteBandCopier() {
033: }
034:
035: Logger LOGGER = org.geotools.util.logging.Logging.getLogger(this
036: .getClass().toString());
037:
038: public void copyPixelData(SeRasterTile tile, WritableRaster raster,
039: int copyOffX, int copyOffY, int targetBand)
040: throws DataSourceException {
041: if (LOGGER.isLoggable(Level.FINER))
042: LOGGER.finer("copying raster data band "
043: + tile.getBandId().longValue()
044: + " into image band " + targetBand);
045:
046: final int numPixels = tile.getNumPixels();
047: if (numPixels == 0) {
048: //no pixels to copy, skip this one.
049: if (LOGGER.isLoggable(Level.FINE))
050: LOGGER.fine("no pixels to copy in raster tile "
051: + tile.getColumnIndex() + ","
052: + tile.getRowIndex());
053: return;
054: }
055: byte[] pixelData = new byte[numPixels];
056: byte[] bitmaskData;
057: try {
058: pixelData = tile.getPixels(pixelData);
059: // This is a virtually undocumented function. I figured out what it was supposed to be
060: // by looking here: http://edndoc.esri.com/arcsde/9.2/api/japi/docs/com/esri/sde/sdk/client/SeRasterData.html#setScanLine(int,%20byte[],%20int,%20byte[],%20int)
061: // Basically, it's an array of 1-bit values, fully packed (8 1-bit indicators for 8 pixels packed into each byte).
062: // If there's a '0' at the nth position, it means that the n'th pixel is a no-data pixel.
063: bitmaskData = tile.getBitMaskData();
064: } catch (Exception e) {
065: throw new DataSourceException(e);
066: }
067: int x, y;
068: final int imgWidth = raster.getWidth() + copyOffX > tileWidth ? tileWidth
069: - copyOffX
070: : raster.getWidth();
071: final int imgHeight = raster.getHeight() + copyOffY > tileHeight ? tileHeight
072: - copyOffY
073: : raster.getHeight();
074: for (x = 0; x < imgWidth; x++) {
075: for (y = 0; y < imgHeight; y++) {
076: final int pixArrayOffset = (y + copyOffY) * tileWidth
077: + (x + copyOffX);
078: if (bitmaskData.length > 0) {
079: if (((bitmaskData[pixArrayOffset / 8] >> (7 - (pixArrayOffset % 8))) & 0x01) == 0x00) {
080: // it's a no-data pixel. Make it transparent if there's a 4th band,
081: // and also make it white.
082: if (raster.getNumBands() == 4)
083: raster.setSample(x, y, 3, 0);
084:
085: raster.setSample(x, y, targetBand, 255);
086: continue;
087: }
088: }
089: try {
090: //verify that we have an opaque pixel
091: if (raster.getNumBands() == 4)
092: raster.setSample(x, y, 3, 255);
093: final int transferType = raster.getTransferType();
094: if (transferType == DataBuffer.TYPE_BYTE
095: || transferType == DataBuffer.TYPE_INT) {
096: final byte sdePixelData = pixelData[pixArrayOffset];
097: //final int bandSample = (raster.getSample(x, y, targetBand) | sdePixelData) & 0x000000ff;
098: final int bandSample = sdePixelData & 0x000000ff;
099: /*if (bandSample != 0 && Math.random() > .99995) {
100: LOGGER.info("pixel " + x + "," + y + ", band:" + targetBand + " has value " + bandSample);
101: }*/
102: raster.setSample(x, y, targetBand, bandSample);
103: } else {
104: //this can't happen, it'd have been caught earlier when we created the transfer object.
105: throw new IllegalArgumentException(
106: "Can't copy ArcSDE Raster data from an SE_PIXEL_TYPE_8BIT_U raster to a java.awt.Raster with a transferType of "
107: + transferType);
108: }
109: } catch (RuntimeException e) {
110: LOGGER.severe("at data " + (x + copyOffX) + ","
111: + (y + copyOffY) + "(img pixel " + x + ","
112: + y + ")");
113: LOGGER
114: .severe("number of pixels reported in tile was "
115: + numPixels);
116: e.printStackTrace();
117: throw e;
118: }
119: }
120: }
121:
122: }
123:
124: }
|