1:
36:
37: package ;
38:
39: import ;
40:
41:
48: public class MultiPixelPackedSampleModel extends SampleModel
49: {
50: private int scanlineStride;
51: private int[] bitMasks;
52: private int[] bitOffsets;
53: private int[] sampleSize;
54: private int dataBitOffset;
55: private int elemBits;
56: private int numberOfBits;
57: private int numElems;
58:
59: public MultiPixelPackedSampleModel(int dataType, int w, int h,
60: int numberOfBits)
61: {
62: this(dataType, w, h, numberOfBits, 0, 0);
63: }
64:
65: public MultiPixelPackedSampleModel(int dataType, int w, int h,
66: int numberOfBits, int scanlineStride,
67: int dataBitOffset)
68: {
69: super(dataType, w, h, 1);
70:
71: switch (dataType)
72: {
73: case DataBuffer.TYPE_BYTE:
74: elemBits = 8;
75: break;
76: case DataBuffer.TYPE_USHORT:
77: elemBits = 16;
78: break;
79: case DataBuffer.TYPE_INT:
80: elemBits = 32;
81: break;
82: default:
83: throw new IllegalArgumentException("MultiPixelPackedSampleModel"
84: + " unsupported dataType");
85: }
86:
87: this.dataBitOffset = dataBitOffset;
88:
89: this.numberOfBits = numberOfBits;
90: if (numberOfBits > elemBits)
91: throw new RasterFormatException("MultiPixelPackedSampleModel pixel size"
92: + " larger than dataType");
93: switch (numberOfBits)
94: {
95: case 1: case 2: case 4: case 8: case 16: case 32: break;
96: default:
97: throw new RasterFormatException("MultiPixelPackedSampleModel pixel"
98: + " size not 2^n bits");
99: }
100: numElems = elemBits / numberOfBits;
101:
102:
103: if (scanlineStride == 0)
104: scanlineStride = ((dataBitOffset + w * numberOfBits) / elemBits);
105: this.scanlineStride = scanlineStride;
106:
107:
108: sampleSize = new int[1];
109: sampleSize[0] = numberOfBits;
110:
111: bitMasks = new int[numElems];
112: bitOffsets = new int[numElems];
113: for (int i=0; i < numElems; i++)
114: {
115: bitOffsets[numElems - i- 1] = numberOfBits * i;
116: bitMasks[numElems - i - 1] = ((1 << numberOfBits) - 1) <<
117: bitOffsets[numElems - i - 1];
118: }
119: }
120:
121: public SampleModel createCompatibleSampleModel(int w, int h)
122: {
123:
126: return new MultiPixelPackedSampleModel(dataType, w, h, numberOfBits);
127: }
128:
129:
130:
135: public DataBuffer createDataBuffer()
136: {
137: int size;
138:
139:
140:
141:
142:
143:
144: size = scanlineStride * height;
145:
146: return Buffers.createBuffer(getDataType(), size);
147: }
148:
149:
150: public int getNumDataElements()
151: {
152: return 1;
153: }
154:
155: public int[] getSampleSize()
156: {
157: return sampleSize;
158: }
159:
160: public int getSampleSize(int band)
161: {
162: return sampleSize[0];
163: }
164:
165: public int getOffset(int x, int y)
166: {
167: return scanlineStride * y + ((dataBitOffset + x*numberOfBits) / elemBits);
168: }
169:
170: public int getBitOffset(int x)
171: {
172: return (dataBitOffset + x*numberOfBits) % elemBits;
173: }
174:
175: public int getDataBitOffset()
176: {
177: return dataBitOffset;
178: }
179:
180: public int getScanlineStride()
181: {
182: return scanlineStride;
183: }
184:
185: public int getPixelBitStride()
186: {
187: return numberOfBits;
188: }
189:
190:
191: public SampleModel createSubsetSampleModel(int[] bands)
192: {
193: int numBands = bands.length;
194: if (numBands != 1)
195: throw new RasterFormatException("MultiPixelPackedSampleModel only"
196: + " supports one band");
197:
198: return new MultiPixelPackedSampleModel(dataType, width, height,
199: numberOfBits, scanlineStride,
200: dataBitOffset);
201: }
202:
203:
217: public Object getDataElements(int x, int y, Object obj,
218: DataBuffer data)
219: {
220: int pixel = getSample(x, y, 0, data);
221: switch (getTransferType())
222: {
223: case DataBuffer.TYPE_BYTE:
224: if (obj == null) obj = new byte[1];
225: ((byte[])obj)[0] = (byte)pixel;
226: return obj;
227: case DataBuffer.TYPE_USHORT:
228: if (obj == null) obj = new short[1];
229: ((short[])obj)[0] = (short)pixel;
230: return obj;
231: case DataBuffer.TYPE_INT:
232: if (obj == null) obj = new int[1];
233: ((int[])obj)[0] = pixel;
234: return obj;
235: default:
236:
237: throw new ClassCastException();
238: }
239: }
240:
241: public int[] getPixel(int x, int y, int[] iArray, DataBuffer data)
242: {
243: if (iArray == null) iArray = new int[1];
244: iArray[0] = getSample(x, y, 0, data);
245:
246: return iArray;
247: }
248:
249: public int[] getPixels(int x, int y, int w, int h, int[] iArray,
250: DataBuffer data)
251: {
252: int offset = getOffset(x, y);
253: if (iArray == null) iArray = new int[w*h];
254: int outOffset = 0;
255: for (y=0; y<h; y++)
256: {
257: int lineOffset = offset;
258: for (x=0; x<w;)
259: {
260: int samples = data.getElem(lineOffset++);
261: for (int b=0; b<numElems && x<w; b++)
262: {
263: iArray[outOffset++] = (samples & bitMasks[b]) >>> bitOffsets[b];
264: x++;
265: }
266: }
267: offset += scanlineStride;
268: }
269: return iArray;
270: }
271:
272: public int getSample(int x, int y, int b, DataBuffer data)
273: {
274: int pos =
275: ((dataBitOffset + x * numberOfBits) % elemBits) / numberOfBits;
276: int offset = getOffset(x, y);
277: int samples = data.getElem(offset);
278: return (samples & bitMasks[pos]) >>> bitOffsets[pos];
279: }
280:
281:
291: public void setDataElements(int x, int y, Object obj, DataBuffer data)
292: {
293: int transferType = getTransferType();
294: if (getTransferType() != data.getDataType())
295: {
296: throw new IllegalArgumentException("transfer type ("+
297: getTransferType()+"), "+
298: "does not match data "+
299: "buffer type (" +
300: data.getDataType() +
301: ").");
302: }
303:
304: int offset = getOffset(x, y);
305:
306: try
307: {
308: switch (transferType)
309: {
310: case DataBuffer.TYPE_BYTE:
311: {
312: DataBufferByte out = (DataBufferByte) data;
313: byte[] in = (byte[]) obj;
314: out.getData()[offset] = in[0];
315: return;
316: }
317: case DataBuffer.TYPE_USHORT:
318: {
319: DataBufferUShort out = (DataBufferUShort) data;
320: short[] in = (short[]) obj;
321: out.getData()[offset] = in[0];
322: return;
323: }
324: case DataBuffer.TYPE_INT:
325: {
326: DataBufferInt out = (DataBufferInt) data;
327: int[] in = (int[]) obj;
328: out.getData()[offset] = in[0];
329: return;
330: }
331: default:
332: throw new ClassCastException("Unsupported data type");
333: }
334: }
335: catch (ArrayIndexOutOfBoundsException aioobe)
336: {
337: String msg = "While writing data elements" +
338: ", x="+x+", y="+y+
339: ", width="+width+", height="+height+
340: ", scanlineStride="+scanlineStride+
341: ", offset="+offset+
342: ", data.getSize()="+data.getSize()+
343: ", data.getOffset()="+data.getOffset()+
344: ": " +
345: aioobe;
346: throw new ArrayIndexOutOfBoundsException(msg);
347: }
348: }
349:
350: public void setPixel(int x, int y, int[] iArray, DataBuffer data)
351: {
352: setSample(x, y, 0, iArray[0], data);
353: }
354:
355: public void setSample(int x, int y, int b, int s, DataBuffer data)
356: {
357: int bitpos =
358: ((dataBitOffset + x * numberOfBits) % elemBits) / numberOfBits;
359: int offset = getOffset(x, y);
360:
361: s = s << bitOffsets[bitpos];
362: s = s & bitMasks[bitpos];
363:
364: int sample = data.getElem(offset);
365: sample |= s;
366: data.setElem(offset, sample);
367: }
368:
369:
374: public String toString()
375: {
376: StringBuffer result = new StringBuffer();
377: result.append(getClass().getName());
378: result.append("[");
379: result.append("scanlineStride=").append(scanlineStride);
380: for(int i=0; i < bitMasks.length; i+=1)
381: {
382: result.append(", mask[").append(i).append("]=0x").append(Integer.toHexString(bitMasks[i]));
383: }
384:
385: result.append("]");
386: return result.toString();
387: }
388: }