| /* Copyright (C) 2000 Free Software Foundation |
| |
| This file is part of libgcj. |
| |
| This software is copyrighted work licensed under the terms of the |
| Libgcj License. Please consult the file "LIBGCJ_LICENSE" for |
| details. */ |
| |
| package java.awt.image; |
| |
| import gnu.gcj.awt.BitMaskExtent; |
| import gnu.gcj.awt.Buffers; |
| |
| /** |
| * @author Rolf W. Rasmussen <rolfwr@ii.uib.no> |
| */ |
| public class SinglePixelPackedSampleModel extends SampleModel |
| { |
| private int scanlineStride; |
| private int[] bitMasks; |
| private int[] bitOffsets; |
| private int[] sampleSize;; |
| |
| public SinglePixelPackedSampleModel(int dataType, int w, int h, |
| int[] bitMasks) |
| { |
| this(dataType, w, h, w, bitMasks); |
| } |
| |
| public SinglePixelPackedSampleModel(int dataType, int w, int h, |
| int scanlineStride, int[] bitMasks) |
| { |
| super(dataType, w, h, bitMasks.length); |
| |
| this.scanlineStride = scanlineStride; |
| this.bitMasks = bitMasks; |
| |
| bitOffsets = new int[numBands]; |
| sampleSize = new int[numBands]; |
| |
| BitMaskExtent extent = new BitMaskExtent(); |
| for (int b=0; b<numBands; b++) |
| { |
| extent.setMask(bitMasks[b]); |
| sampleSize[b] = extent.bitWidth; |
| bitOffsets[b] = extent.leastSignificantBit; |
| } |
| } |
| |
| public int getNumDataElements() |
| { |
| return 1; |
| } |
| |
| public SampleModel createCompatibleSampleModel(int w, int h) |
| { |
| /* FIXME: We can avoid recalculation of bit offsets and sample |
| sizes here by passing these from the current instance to a |
| special private constructor. */ |
| return new SinglePixelPackedSampleModel(dataType, w, h, bitMasks); |
| } |
| |
| public DataBuffer createDataBuffer() |
| { |
| // Important: use scanlineStride here, not width! |
| int size = scanlineStride*height; |
| return Buffers.createBuffer(getDataType(), size); |
| } |
| |
| public int[] getSampleSize() |
| { |
| return sampleSize; |
| } |
| |
| public int getSampleSize(int band) |
| { |
| return sampleSize[band]; |
| } |
| |
| public int getOffset(int x, int y) |
| { |
| return scanlineStride*y + x; |
| } |
| |
| public int[] getBitOffsets() |
| { |
| return bitOffsets; |
| } |
| |
| public int[] getBitMasks() |
| { |
| return bitMasks; |
| } |
| |
| public int getScanlineStride() |
| { |
| return scanlineStride; |
| } |
| |
| public SampleModel createSubsetSampleModel(int[] bands) |
| { |
| // FIXME: Is this the right way to interpret bands? |
| |
| int numBands = bands.length; |
| |
| int[] bitMasks = new int[numBands]; |
| |
| for (int b=0; b<numBands; b++) |
| bitMasks[b] = this.bitMasks[bands[b]]; |
| |
| return new SinglePixelPackedSampleModel(dataType, width, height, |
| scanlineStride, bitMasks); |
| } |
| |
| public Object getDataElements(int x, int y, Object obj, |
| DataBuffer data) |
| { |
| int offset = scanlineStride*y + x + data.getOffset(); |
| |
| return Buffers.getData(data, offset, obj, |
| 0, // destination offset, |
| 1 // length |
| ); |
| } |
| |
| public int[] getPixel(int x, int y, int[] iArray, DataBuffer data) |
| { |
| int offset = scanlineStride*y + x; |
| if (iArray == null) iArray = new int[numBands]; |
| int samples = data.getElem(offset); |
| |
| for (int b=0; b<numBands; b++) |
| iArray[b] = (samples & bitMasks[b]) >>> bitOffsets[b]; |
| |
| return iArray; |
| } |
| |
| public int[] getPixels(int x, int y, int w, int h, int[] iArray, |
| DataBuffer data) |
| { |
| int offset = scanlineStride*y + x; |
| if (iArray == null) iArray = new int[numBands*w*h]; |
| int outOffset = 0; |
| for (y=0; y<h; y++) |
| { |
| int lineOffset = offset; |
| for (x=0; x<w; x++) |
| { |
| int samples = data.getElem(lineOffset++); |
| for (int b=0; b<numBands; b++) |
| iArray[outOffset++] = (samples & bitMasks[b]) >>> bitOffsets[b]; |
| } |
| offset += scanlineStride; |
| } |
| return iArray; |
| } |
| |
| public int getSample(int x, int y, int b, DataBuffer data) |
| { |
| int offset = scanlineStride*y + x; |
| int samples = data.getElem(offset); |
| return (samples & bitMasks[b]) >>> bitOffsets[b]; |
| } |
| |
| public void setDataElements(int x, int y, Object obj, DataBuffer data) |
| { |
| int offset = scanlineStride*y + x + data.getOffset(); |
| |
| int transferType = getTransferType(); |
| if (getTransferType() != data.getDataType()) |
| { |
| throw new IllegalArgumentException("transfer type ("+ |
| getTransferType()+"), "+ |
| "does not match data "+ |
| "buffer type (" + |
| data.getDataType() + |
| ")."); |
| } |
| |
| try |
| { |
| switch (transferType) |
| { |
| case DataBuffer.TYPE_BYTE: |
| { |
| DataBufferByte out = (DataBufferByte) data; |
| byte[] in = (byte[]) obj; |
| out.getData()[offset] = in[0]; |
| return; |
| } |
| case DataBuffer.TYPE_USHORT: |
| { |
| DataBufferUShort out = (DataBufferUShort) data; |
| short[] in = (short[]) obj; |
| out.getData()[offset] = in[0]; |
| return; |
| } |
| case DataBuffer.TYPE_INT: |
| { |
| DataBufferInt out = (DataBufferInt) data; |
| int[] in = (int[]) obj; |
| out.getData()[offset] = in[0]; |
| return; |
| } |
| // FIXME: Fill in the other possible types. |
| default: |
| throw new InternalError(); |
| } |
| } |
| catch (ArrayIndexOutOfBoundsException aioobe) |
| { |
| String msg = "While writing data elements" + |
| ", x="+x+", y="+y+ |
| ", width="+width+", height="+height+ |
| ", scanlineStride="+scanlineStride+ |
| ", offset="+offset+ |
| ", data.getSize()="+data.getSize()+ |
| ", data.getOffset()="+data.getOffset()+ |
| ": " + |
| aioobe; |
| throw new ArrayIndexOutOfBoundsException(msg); |
| } |
| } |
| |
| public void setPixel(int x, int y, int[] iArray, DataBuffer data) |
| { |
| int offset = scanlineStride*y + x; |
| |
| int samples = 0; |
| for (int b=0; b<numBands; b++) |
| samples |= (iArray[b] << bitOffsets[b]) & bitMasks[b]; |
| |
| data.setElem(offset, samples); |
| } |
| |
| public void setSample(int x, int y, int b, int s, DataBuffer data) |
| { |
| int offset = scanlineStride*y + x; |
| int samples = data.getElem(offset); |
| int bitMask = bitMasks[b]; |
| samples &= ~bitMask; |
| samples |= (s << bitOffsets[b]) & bitMask; |
| data.setElem(offset, samples); |
| } |
| } |