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