1:
36:
37: package ;
38:
39:
46: public final class BandedSampleModel extends ComponentSampleModel
47: {
48: private int[] bitMasks;
49: private int[] bitOffsets;
50: private int[] sampleSize;
51: private int dataBitOffset;
52: private int elemBits;
53: private int numberOfBits;
54: private int numElems;
55:
56: private static int[] createBankArray(int size)
57: {
58: int[] result = new int[size];
59: for (int i = 0; i < size; i++)
60: result[i] = i;
61: return result;
62: }
63:
64: public BandedSampleModel(int dataType, int w, int h, int numBands)
65: {
66: this(dataType, w, h, w, createBankArray(numBands), new int[numBands]);
67: }
68:
69: public BandedSampleModel(int dataType, int w, int h, int scanlineStride,
70: int[] bankIndices, int[] bandOffsets)
71: {
72: super(dataType, w, h, 1, scanlineStride, bankIndices, bandOffsets);
73: }
74:
75: public SampleModel createCompatibleSampleModel(int w, int h)
76: {
77:
78:
79:
80:
81: int[] newoffsets = new int[bandOffsets.length];
82: int[] order = new int[bandOffsets.length];
83: for (int i=0; i < bandOffsets.length; i++)
84: order[i] = i;
85:
86:
87: for (int i=0; i < bandOffsets.length; i++)
88: for (int j=i+1; j < bandOffsets.length; i++)
89: if (bankIndices[order[i]] > bankIndices[order[j]]
90: || (bankIndices[order[i]] == bankIndices[order[j]]
91: && bandOffsets[order[i]] > bandOffsets[order[j]]))
92: {
93: int t = order[i]; order[i] = order[j]; order[j] = t;
94: }
95: int bank = 0;
96: int offset = 0;
97: for (int i=0; i < bandOffsets.length; i++)
98: {
99: if (bankIndices[order[i]] != bank)
100: {
101: bank = bankIndices[order[i]];
102: offset = 0;
103: }
104: newoffsets[order[i]] = offset;
105: offset += w * scanlineStride;
106: }
107:
108: return new BandedSampleModel(dataType, w, h, scanlineStride, bankIndices, newoffsets);
109: }
110:
111:
112: public SampleModel createSubsetSampleModel(int[] bands)
113: {
114: if (bands.length > bankIndices.length)
115: throw new
116: RasterFormatException("BandedSampleModel createSubsetSampleModel too"
117: +" many bands");
118: int[] newoff = new int[bands.length];
119: int[] newbanks = new int[bands.length];
120: for (int i=0; i < bands.length; i++)
121: {
122: int b = bands[i];
123: newoff[i] = bandOffsets[b];
124: newbanks[i] = bankIndices[b];
125: }
126:
127: return new BandedSampleModel(dataType, width, height, scanlineStride,
128: newbanks, newoff);
129: }
130:
131:
144: public Object getDataElements(int x, int y, Object obj,
145: DataBuffer data)
146: {
147: int pixel = getSample(x, y, 0, data);
148: switch (getTransferType())
149: {
150: case DataBuffer.TYPE_BYTE:
151: {
152: byte[] b = (byte[])obj;
153: if (b == null) b = new byte[numBands];
154: for (int i=0; i < numBands; i++)
155: b[i] = (byte)getSample(x, y, i, data);
156: return b;
157: }
158: case DataBuffer.TYPE_SHORT:
159: case DataBuffer.TYPE_USHORT:
160: {
161: short[] b = (short[])obj;
162: if (b == null) b = new short[numBands];
163: for (int i=0; i < numBands; i++)
164: b[i] = (short)getSample(x, y, i, data);
165: return b;
166: }
167: case DataBuffer.TYPE_INT:
168: {
169: int[] b = (int[])obj;
170: if (b == null) b = new int[numBands];
171: for (int i=0; i < numBands; i++)
172: b[i] = getSample(x, y, i, data);
173: return b;
174: }
175: case DataBuffer.TYPE_FLOAT:
176: {
177: float[] b = (float[])obj;
178: if (b == null) b = new float[numBands];
179: for (int i=0; i < numBands; i++)
180: b[i] = getSampleFloat(x, y, i, data);
181: return b;
182: }
183: case DataBuffer.TYPE_DOUBLE:
184: {
185: double[] b = (double[])obj;
186: if (b == null) b = new double[numBands];
187: for (int i=0; i < numBands; i++)
188: b[i] = getSample(x, y, i, data);
189: return b;
190: }
191:
192: default:
193:
194: throw new ClassCastException();
195: }
196: }
197:
198: public int[] getPixel(int x, int y, int[] iArray, DataBuffer data)
199: {
200: if (iArray == null) iArray = new int[numBands];
201: for (int i=0; i < numBands; i++)
202: iArray[i] = getSample(x, y, i, data);
203:
204: return iArray;
205: }
206:
207:
228: public int[] getPixels(int x, int y, int w, int h, int[] iArray,
229: DataBuffer data)
230: {
231: if (iArray == null) iArray = new int[w*h*numBands];
232: int outOffset = 0;
233: int maxX = x + w;
234: int maxY = y + h;
235: for (int yy = x; yy < maxY; yy++)
236: {
237: for (int xx = x; xx < maxX; xx++)
238: {
239: for (int b = 0; b < numBands; b++)
240: {
241: int offset = bandOffsets[b] + yy * scanlineStride + xx;
242: iArray[outOffset++] =
243: data.getElem(bankIndices[b], offset);
244: }
245: }
246: }
247: return iArray;
248: }
249:
250: public int getSample(int x, int y, int b, DataBuffer data)
251: {
252: int offset = bandOffsets[b] + y * scanlineStride + x;
253: return data.getElem(bankIndices[b], offset);
254: }
255:
256: public float getSampleFloat(int x, int y, int b, DataBuffer data)
257: {
258: int offset = bandOffsets[b] + y * scanlineStride + x;
259: return data.getElemFloat(bankIndices[b], offset);
260: }
261:
262: public double getSampleDouble(int x, int y, int b, DataBuffer data)
263: {
264: int offset = bandOffsets[b] + y * scanlineStride + x;
265: return data.getElemDouble(bankIndices[b], offset);
266: }
267:
268:
288: public int[] getSamples(int x, int y, int w, int h, int b, int[] iArray,
289: DataBuffer data)
290: {
291: if (iArray == null) iArray = new int[w*h];
292: int outOffset = 0;
293: int maxX = x + w;
294: int maxY = y + h;
295: for (int yy = y; yy < maxY; yy++)
296: {
297: for (int xx = x; xx < maxX; xx++)
298: {
299: int offset = bandOffsets[b] + yy * scanlineStride + xx;
300: iArray[outOffset++] =
301: data.getElem(bankIndices[b], offset);
302: }
303: }
304: return iArray;
305: }
306:
307:
308:
318: public void setDataElements(int x, int y, Object obj, DataBuffer data)
319: {
320: int transferType = getTransferType();
321: if (getTransferType() != data.getDataType())
322: {
323: throw new IllegalArgumentException("transfer type ("+
324: getTransferType()+"), "+
325: "does not match data "+
326: "buffer type (" +
327: data.getDataType() +
328: ").");
329: }
330:
331: int offset = y * scanlineStride + x;
332:
333: try
334: {
335: switch (transferType)
336: {
337: case DataBuffer.TYPE_BYTE:
338: {
339: DataBufferByte out = (DataBufferByte) data;
340: byte[] in = (byte[]) obj;
341: for (int i=0; i < numBands; i++)
342: out.getData(bankIndices[i])[offset + bandOffsets[i]] = in[i];
343: return;
344: }
345: case DataBuffer.TYPE_SHORT:
346: {
347: DataBufferShort out = (DataBufferShort) data;
348: short[] in = (short[]) obj;
349: for (int i=0; i < numBands; i++)
350: out.getData(bankIndices[i])[offset + bandOffsets[i]] = in[i];
351: return;
352: }
353: case DataBuffer.TYPE_USHORT:
354: {
355: DataBufferUShort out = (DataBufferUShort) data;
356: short[] in = (short[]) obj;
357: for (int i=0; i < numBands; i++)
358: out.getData(bankIndices[i])[offset + bandOffsets[i]] = in[i];
359: return;
360: }
361: case DataBuffer.TYPE_INT:
362: {
363: DataBufferInt out = (DataBufferInt) data;
364: int[] in = (int[]) obj;
365: for (int i=0; i < numBands; i++)
366: out.getData(bankIndices[i])[offset + bandOffsets[i]] = in[i];
367: return;
368: }
369: case DataBuffer.TYPE_FLOAT:
370: {
371: DataBufferFloat out = (DataBufferFloat) data;
372: float[] in = (float[]) obj;
373: for (int i=0; i < numBands; i++)
374: out.getData(bankIndices[i])[offset + bandOffsets[i]] = in[i];
375: return;
376: }
377: case DataBuffer.TYPE_DOUBLE:
378: {
379: DataBufferDouble out = (DataBufferDouble) data;
380: double[] in = (double[]) obj;
381: for (int i=0; i < numBands; i++)
382: out.getData(bankIndices[i])[offset + bandOffsets[i]] = in[i];
383: return;
384: }
385: default:
386: throw new ClassCastException("Unsupported data type");
387: }
388: }
389: catch (ArrayIndexOutOfBoundsException aioobe)
390: {
391: String msg = "While writing data elements" +
392: ", x="+x+", y="+y+
393: ", width="+width+", height="+height+
394: ", scanlineStride="+scanlineStride+
395: ", offset="+offset+
396: ", data.getSize()="+data.getSize()+
397: ", data.getOffset()="+data.getOffset()+
398: ": " +
399: aioobe;
400: throw new ArrayIndexOutOfBoundsException(msg);
401: }
402: }
403:
404: public void setPixel(int x, int y, int[] iArray, DataBuffer data)
405: {
406: for (int b=0; b < numBands; b++)
407: data.setElem(bankIndices[b], bandOffsets[b] + y * scanlineStride + x,
408: iArray[b]);
409: }
410:
411: public void setPixels(int x, int y, int w, int h, int[] iArray,
412: DataBuffer data)
413: {
414: int inOffset = 0;
415: for (int hh = 0; hh < h; hh++)
416: {
417: for (int ww = 0; ww < w; ww++)
418: {
419: int offset = y * scanlineStride + (x + ww);
420: for (int b=0; b < numBands; b++)
421: data.setElem(bankIndices[b], bandOffsets[b] + offset,
422: iArray[inOffset++]);
423: }
424: y++;
425: }
426: }
427:
428: public void setSample(int x, int y, int b, int s, DataBuffer data)
429: {
430: data.setElem(bankIndices[b], bandOffsets[b] + y * scanlineStride + x, s);
431: }
432:
433: public void setSample(int x, int y, int b, float s, DataBuffer data)
434: {
435: data.setElemFloat(bankIndices[b], bandOffsets[b] + y * scanlineStride + x, s);
436: }
437:
438: public void setSample(int x, int y, int b, double s, DataBuffer data)
439: {
440: data.setElemDouble(bankIndices[b], bandOffsets[b] + y * scanlineStride + x, s);
441: }
442:
443: public void setSamples(int x, int y, int w, int h, int b, int[] iArray,
444: DataBuffer data)
445: {
446: int inOffset = 0;
447:
448: switch (getTransferType())
449: {
450: case DataBuffer.TYPE_BYTE:
451: {
452: DataBufferByte out = (DataBufferByte) data;
453: byte[] bank = out.getData(bankIndices[b]);
454: for (int hh = 0; hh < h; hh++)
455: {
456: for (int ww = 0; ww < w; ww++)
457: {
458: int offset = bandOffsets[b] + y * scanlineStride + (x + ww);
459: bank[offset] = (byte)iArray[inOffset++];
460: }
461: y++;
462: }
463: return;
464: }
465: case DataBuffer.TYPE_SHORT:
466: {
467: DataBufferShort out = (DataBufferShort) data;
468: short[] bank = out.getData(bankIndices[b]);
469: for (int hh = 0; hh < h; hh++)
470: {
471: for (int ww = 0; ww < w; ww++)
472: {
473: int offset = bandOffsets[b] + y * scanlineStride + (x + ww);
474: bank[offset] = (short)iArray[inOffset++];
475: }
476: y++;
477: }
478: return;
479: }
480: case DataBuffer.TYPE_USHORT:
481: {
482: DataBufferShort out = (DataBufferShort) data;
483: short[] bank = out.getData(bankIndices[b]);
484: for (int hh = 0; hh < h; hh++)
485: {
486: for (int ww = 0; ww < w; ww++)
487: {
488: int offset = bandOffsets[b] + y * scanlineStride + (x + ww);
489: bank[offset] = (short)iArray[inOffset++];
490: }
491: y++;
492: }
493: return;
494: }
495: case DataBuffer.TYPE_INT:
496: {
497: DataBufferInt out = (DataBufferInt) data;
498: int[] bank = out.getData(bankIndices[b]);
499: for (int hh = 0; hh < h; hh++)
500: {
501: for (int ww = 0; ww < w; ww++)
502: {
503: int offset = bandOffsets[b] + y * scanlineStride + (x + ww);
504: bank[offset] = iArray[inOffset++];
505: }
506: y++;
507: }
508: return;
509: }
510: case DataBuffer.TYPE_FLOAT:
511: case DataBuffer.TYPE_DOUBLE:
512: break;
513: default:
514: throw new ClassCastException("Unsupported data type");
515: }
516:
517:
518: for (int hh = 0; hh < h; hh++)
519: {
520: for (int ww = 0; ww < w; ww++)
521: {
522: int offset = bandOffsets[b] + y * scanlineStride + (x + ww);
523: data.setElem(bankIndices[b], offset, iArray[inOffset++]);
524: }
525: y++;
526: }
527: }
528:
529:
534: public String toString()
535: {
536: StringBuffer result = new StringBuffer();
537: result.append(getClass().getName());
538: result.append("[");
539: result.append("scanlineStride=").append(scanlineStride);
540: for(int i=0; i < bitMasks.length; i+=1)
541: {
542: result.append(", mask[").append(i).append("]=0x").append(Integer.toHexString(bitMasks[i]));
543: }
544:
545: result.append("]");
546: return result.toString();
547: }
548: }