1:
36:
37: package ;
38:
39: import ;
40:
41:
42:
43:
61: public class ComponentSampleModel extends SampleModel
62: {
63: protected int[] bandOffsets;
64: protected int[] bankIndices;
65:
66:
70: protected int numBands;
71:
72:
73: protected int numBanks;
74:
75: protected int scanlineStride;
76:
77: protected int pixelStride;
78:
79: private boolean tightPixelPacking = false;
80:
81: public ComponentSampleModel(int dataType,
82: int w, int h,
83: int pixelStride,
84: int scanlineStride,
85: int[] bandOffsets)
86: {
87: this(dataType, w, h, pixelStride, scanlineStride,
88: new int[bandOffsets.length], bandOffsets);
89: }
90:
91: public ComponentSampleModel(int dataType,
92: int w, int h,
93: int pixelStride,
94: int scanlineStride,
95: int[] bankIndices,
96: int[] bandOffsets)
97: {
98: super(dataType, w, h, bandOffsets.length);
99: if ((pixelStride<0) || (scanlineStride<0) ||
100: (bandOffsets.length<1) ||
101: (bandOffsets.length != bankIndices.length))
102: throw new IllegalArgumentException();
103:
104: this.bandOffsets = bandOffsets;
105: this.bankIndices = bankIndices;
106: this.numBands = bandOffsets.length;
107:
108: this.numBanks = 0;
109: for (int b=0; b<bankIndices.length; b++)
110: this.numBanks = Math.max(this.numBanks, bankIndices[b]+1);
111:
112: this.scanlineStride = scanlineStride;
113: this.pixelStride = pixelStride;
114:
115:
116:
117:
119:
120: if (pixelStride == numBands)
121: {
122: tightPixelPacking = true;
123: for (int b=0; b<numBands; b++) {
124: if ((bandOffsets[b] != b) || (bankIndices[b] !=0))
125: {
126: tightPixelPacking = false;
127: break;
128: }
129: }
130: }
131: }
132:
133: public SampleModel createCompatibleSampleModel(int w, int h)
134: {
135: return new ComponentSampleModel(dataType, w, h, pixelStride,
136: scanlineStride, bankIndices,
137: bandOffsets);
138: }
139:
140: public SampleModel createSubsetSampleModel(int[] bands)
141: {
142: int numBands = bands.length;
143:
144: int[] bankIndices = new int[numBands];
145: int[] bandOffsets = new int[numBands];
146: for (int b=0; b<numBands; b++)
147: {
148: bankIndices[b] = this.bankIndices[bands[b]];
149: bandOffsets[b] = this.bandOffsets[bands[b]];
150: }
151:
152: return new ComponentSampleModel(dataType, width, height, pixelStride,
153: scanlineStride, bankIndices,
154: bandOffsets);
155: }
156:
157: public DataBuffer createDataBuffer()
158: {
159:
160: int highestOffset = 0;
161: for (int b=0; b<numBands; b++)
162: {
163: highestOffset = Math.max(highestOffset, bandOffsets[b]);
164: }
165: int size = pixelStride*(width-1) + scanlineStride*(height-1) +
166: highestOffset + 1;
167:
168: return Buffers.createBuffer(getDataType(), size, numBanks);
169: }
170:
171: public int getOffset(int x, int y)
172: {
173: return getOffset(x, y, 0);
174: }
175:
176: public int getOffset(int x, int y, int b)
177: {
178: return bandOffsets[b] + pixelStride*x + scanlineStride*y;
179: }
180:
181: public final int[] getSampleSize()
182: {
183: int size = DataBuffer.getDataTypeSize(getDataType());
184: int[] sizes = new int[numBands];
185:
186: java.util.Arrays.fill(sizes, size);
187: return sizes;
188: }
189:
190: public final int getSampleSize(int band)
191: {
192: return DataBuffer.getDataTypeSize(getDataType());
193: }
194:
195: public final int[] getBankIndices()
196: {
197: return bankIndices;
198: }
199:
200: public final int[] getBandOffsets()
201: {
202: return bandOffsets;
203: }
204:
205: public final int getScanlineStride()
206: {
207: return scanlineStride;
208: }
209:
210: public final int getPixelStride()
211: {
212: return pixelStride;
213: }
214:
215: public final int getNumDataElements()
216: {
217: return numBands;
218: }
219:
220: public Object getDataElements(int x, int y, Object obj, DataBuffer data)
221: {
222: int xyOffset = pixelStride*x + scanlineStride*y;
223:
224: int[] totalBandDataOffsets = new int[numBands];
225:
226:
229:
230:
235:
236: int[] bankOffsets = data.getOffsets();
237:
238: for (int b=0; b<numBands; b++)
239: {
240: totalBandDataOffsets[b] =
241: bandOffsets[b]+bankOffsets[bankIndices[b]] + xyOffset;
242: }
243:
244: try
245: {
246: switch (getTransferType())
247: {
248: case DataBuffer.TYPE_BYTE:
249: DataBufferByte inByte = (DataBufferByte) data;
250: byte[] outByte = (byte[]) obj;
251: if (outByte == null) outByte = new byte[numBands];
252:
253: for (int b=0; b<numBands; b++)
254: {
255: int dOffset = totalBandDataOffsets[b];
256: outByte[b] = inByte.getData(bankIndices[b])[dOffset];
257: }
258: return outByte;
259:
260: case DataBuffer.TYPE_USHORT:
261: DataBufferUShort inUShort = (DataBufferUShort) data;
262: short[] outUShort = (short[]) obj;
263: if (outUShort == null) outUShort = new short[numBands];
264:
265: for (int b=0; b<numBands; b++)
266: {
267: int dOffset = totalBandDataOffsets[b];
268: outUShort[b] = inUShort.getData(bankIndices[b])[dOffset];
269: }
270: return outUShort;
271:
272: case DataBuffer.TYPE_SHORT:
273: DataBufferShort inShort = (DataBufferShort) data;
274: short[] outShort = (short[]) obj;
275: if (outShort == null) outShort = new short[numBands];
276:
277: for (int b=0; b<numBands; b++)
278: {
279: int dOffset = totalBandDataOffsets[b];
280: outShort[b] = inShort.getData(bankIndices[b])[dOffset];
281: }
282: return outShort;
283:
284: case DataBuffer.TYPE_INT:
285: DataBufferInt inInt = (DataBufferInt) data;
286: int[] outInt = (int[]) obj;
287: if (outInt == null) outInt = new int[numBands];
288:
289: for (int b=0; b<numBands; b++)
290: {
291: int dOffset = totalBandDataOffsets[b];
292: outInt[b] = inInt.getData(bankIndices[b])[dOffset];
293: }
294: return outInt;
295:
296: case DataBuffer.TYPE_FLOAT:
297: DataBufferFloat inFloat = (DataBufferFloat) data;
298: float[] outFloat = (float[]) obj;
299: if (outFloat == null) outFloat = new float[numBands];
300:
301: for (int b=0; b<numBands; b++)
302: {
303: int dOffset = totalBandDataOffsets[b];
304: outFloat[b] = inFloat.getData(bankIndices[b])[dOffset];
305: }
306: return outFloat;
307:
308: case DataBuffer.TYPE_DOUBLE:
309: DataBufferDouble inDouble = (DataBufferDouble) data;
310: double[] outDouble = (double[]) obj;
311: if (outDouble == null) outDouble = new double[numBands];
312:
313: for (int b=0; b<numBands; b++)
314: {
315: int dOffset = totalBandDataOffsets[b];
316: outDouble[b] = inDouble.getData(bankIndices[b])[dOffset];
317: }
318: return outDouble;
319:
320: default:
321: throw new IllegalStateException("unknown transfer type " +
322: getTransferType());
323: }
324: }
325: catch (ArrayIndexOutOfBoundsException aioobe)
326: {
327: String msg = "While reading data elements, " +
328: "x=" + x + ", y=" + y +", " + ", xyOffset=" + xyOffset +
329: ", data.getSize()=" + data.getSize() + ": " + aioobe;
330: throw new ArrayIndexOutOfBoundsException(msg);
331: }
332: }
333:
334: public Object getDataElements(int x, int y, int w, int h, Object obj,
335: DataBuffer data)
336: {
337: if (!tightPixelPacking)
338: {
339: return super.getDataElements(x, y, w, h, obj, data);
340: }
341:
342:
343:
344:
345: int rowSize = w*numBands;
346: int dataSize = rowSize*h;
347:
348: DataBuffer transferBuffer =
349: Buffers.createBuffer(getTransferType(), obj, dataSize);
350: obj = Buffers.getData(transferBuffer);
351:
352: int inOffset =
353: pixelStride*x +
354: scanlineStride*y +
355: data.getOffset();
356:
357:
359:
360:
361: if (scanlineStride == rowSize)
362: {
363:
364: rowSize *= h;
365:
366: h = 1;
367: }
368:
369: int outOffset = 0;
370: Object inArray = Buffers.getData(data);
371: for (int yd = 0; yd<h; yd++)
372: {
373: System.arraycopy(inArray, inOffset, obj, outOffset, rowSize);
374: inOffset += scanlineStride;
375: outOffset += rowSize;
376: }
377: return obj;
378: }
379:
380: public void setDataElements(int x, int y, int w, int h,
381: Object obj, DataBuffer data)
382: {
383: if (!tightPixelPacking)
384: {
385: super.setDataElements(x, y, w, h, obj, data);
386: return;
387: }
388:
389:
390: int rowSize = w*numBands;
391: int dataSize = rowSize*h;
392:
393: DataBuffer transferBuffer =
394: Buffers.createBufferFromData(getTransferType(), obj, dataSize);
395:
396: int[] bankOffsets = data.getOffsets();
397:
398: int outOffset =
399: pixelStride*x +
400: scanlineStride*y +
401: bankOffsets[0];
402:
403:
404: if (scanlineStride == rowSize)
405: {
406:
407: rowSize *= h;
408: h = 1;
409: }
410:
411: int inOffset = 0;
412: Object outArray = Buffers.getData(data);
413: for (int yd = 0; yd<h; yd++)
414: {
415: System.arraycopy(obj, inOffset, outArray, outOffset, rowSize);
416: outOffset += scanlineStride;
417: inOffset += rowSize;
418: }
419: }
420:
421: public int[] getPixel(int x, int y, int[] iArray, DataBuffer data)
422: {
423: int offset = pixelStride*x + scanlineStride*y;
424: if (iArray == null) iArray = new int[numBands];
425: for (int b=0; b<numBands; b++)
426: {
427: iArray[b] = data.getElem(bankIndices[b], offset+bandOffsets[b]);
428: }
429: return iArray;
430: }
431:
432: public int[] getPixels(int x, int y, int w, int h, int[] iArray,
433: DataBuffer data)
434: {
435: int offset = pixelStride*x + scanlineStride*y;
436: if (iArray == null) iArray = new int[numBands*w*h];
437: int outOffset = 0;
438: for (y=0; y<h; y++)
439: {
440: int lineOffset = offset;
441: for (x=0; x<w; x++)
442: {
443: for (int b=0; b<numBands; b++)
444: {
445: iArray[outOffset++] =
446: data.getElem(bankIndices[b], lineOffset+bandOffsets[b]);
447: }
448: lineOffset += pixelStride;
449: }
450: offset += scanlineStride;
451: }
452: return iArray;
453: }
454:
455: public int getSample(int x, int y, int b, DataBuffer data)
456: {
457: return data.getElem(bankIndices[b], getOffset(x, y, b));
458: }
459:
460: public void setDataElements(int x, int y, Object obj, DataBuffer data)
461: {
462: int offset = pixelStride*x + scanlineStride*y;
463: int[] totalBandDataOffsets = new int[numBands];
464: int[] bankOffsets = data.getOffsets();
465: for (int b=0; b<numBands; b++)
466: totalBandDataOffsets[b] =
467: bandOffsets[b]+bankOffsets[bankIndices[b]] + offset;
468:
469: switch (getTransferType())
470: {
471: case DataBuffer.TYPE_BYTE:
472: {
473: DataBufferByte out = (DataBufferByte) data;
474: byte[] in = (byte[]) obj;
475:
476: for (int b=0; b<numBands; b++)
477: out.getData(bankIndices[b])[totalBandDataOffsets[b]] = in[b];
478:
479: return;
480: }
481: case DataBuffer.TYPE_USHORT:
482: {
483: DataBufferUShort out = (DataBufferUShort) data;
484: short[] in = (short[]) obj;
485:
486: for (int b=0; b<numBands; b++)
487: out.getData(bankIndices[b])[totalBandDataOffsets[b]] = in[b];
488:
489: return;
490: }
491: case DataBuffer.TYPE_SHORT:
492: {
493: DataBufferShort out = (DataBufferShort) data;
494: short[] in = (short[]) obj;
495:
496: for (int b=0; b<numBands; b++)
497: out.getData(bankIndices[b])[totalBandDataOffsets[b]] = in[b];
498:
499: return;
500: }
501: case DataBuffer.TYPE_INT:
502: {
503: DataBufferInt out = (DataBufferInt) data;
504: int[] in = (int[]) obj;
505:
506: for (int b=0; b<numBands; b++)
507: out.getData(bankIndices[b])[totalBandDataOffsets[b]] = in[b];
508:
509: return;
510: }
511: case DataBuffer.TYPE_FLOAT:
512: {
513: DataBufferFloat out = (DataBufferFloat) data;
514: float[] in = (float[]) obj;
515:
516: for (int b=0; b<numBands; b++)
517: out.getData(bankIndices[b])[totalBandDataOffsets[b]] = in[b];
518:
519: return;
520: }
521: case DataBuffer.TYPE_DOUBLE:
522: {
523: DataBufferDouble out = (DataBufferDouble) data;
524: double[] in = (double[]) obj;
525:
526: for (int b=0; b<numBands; b++)
527: out.getData(bankIndices[b])[totalBandDataOffsets[b]] = in[b];
528:
529: return;
530: }
531: default:
532: throw new UnsupportedOperationException("transfer type not " +
533: "implemented");
534: }
535: }
536:
537: public void setPixel(int x, int y, int[] iArray, DataBuffer data)
538: {
539: int offset = pixelStride*x + scanlineStride*y;
540: for (int b=0; b<numBands; b++)
541: data.setElem(bankIndices[b], offset+bandOffsets[b], iArray[b]);
542: }
543:
544: public void setSample(int x, int y, int b, int s, DataBuffer data)
545: {
546: data.setElem(bankIndices[b], getOffset(x, y, b), s);
547: }
548: }