List of usage examples for java.nio ByteBuffer getShort
public abstract short getShort(int index);
From source file:com.healthmarketscience.jackcess.impl.DatabaseImpl.java
/** * Reads various config info from the db page 0. *//* w ww. j a v a2s. c om*/ private void initRootPageInfo() throws IOException { ByteBuffer buffer = takeSharedBuffer(); try { _pageChannel.readPage(buffer, 0); _defaultSortOrder = ColumnImpl.readSortOrder(buffer, _format.OFFSET_SORT_ORDER, _format); _defaultCodePage = buffer.getShort(_format.OFFSET_CODE_PAGE); } finally { releaseSharedBuffer(buffer); } }
From source file:com.codestation.henkakuserver.HenkakuServer.java
private Pair<ArrayList<Integer>, List<Byte>> preprocessRop(byte[] urop) throws Exception { byte[] loader = new byte[urop.length + ((-urop.length) & 3)]; System.arraycopy(urop, 0, loader, 0, urop.length); ByteBuffer buf = ByteBuffer.wrap(loader).order(ByteOrder.LITTLE_ENDIAN); int header_size = 0x40; int dsize = buf.getInt(0x10); int csize = buf.getInt(0x20); int reloc_size = buf.getInt(0x30); int symtab_size = buf.getInt(0x38); if (csize % 4 != 0) { throw new Exception("csize % 4 != 0???"); }/*from ww w. j a v a2s . c o m*/ int reloc_offset = header_size + dsize + csize; int symtab = reloc_offset + reloc_size; int symtab_n = symtab_size / 8; Map<Integer, String> reloc_map = new HashMap<>(); for (int x = 0; x < symtab_n; ++x) { int sym_id = buf.getInt(symtab + 8 * x); int str_offset = buf.getInt(symtab + 8 * x + 4); int end = str_offset; while (loader[end] != 0) { end += 1; } String name = new String(Arrays.copyOfRange(loader, str_offset, end)); reloc_map.put(sym_id, name); } Map<Pair<String, Integer>, Integer> reloc_type_map = new HashMap<>(); reloc_type_map.put(new Pair<>("rop.data", 0), 1); reloc_type_map.put(new Pair<>("SceWebKit", 0), 2); reloc_type_map.put(new Pair<>("SceLibKernel", 0), 3); reloc_type_map.put(new Pair<>("SceLibc", 0), 4); reloc_type_map.put(new Pair<>("SceLibHttp", 0), 5); reloc_type_map.put(new Pair<>("SceNet", 0), 6); reloc_type_map.put(new Pair<>("SceAppMgr", 0), 7); int want_len = 0x40 + dsize + csize; ArrayList<Integer> urop_js = new ArrayList<>(); byte[] relocs = new byte[want_len / 4]; int reloc_n = reloc_size / 8; for (int x = 0; x < reloc_n; ++x) { int reloc_type = buf.getShort(reloc_offset + 8 * x); int sym_id = buf.getShort(reloc_offset + 8 * x + 2); int offset = buf.getInt(reloc_offset + 8 * x + 4); if (offset % 4 != 0) { throw new Exception("offset % 4 != 0???"); } if (relocs[offset / 4] != 0) { throw new Exception("symbol relocated twice, not supported"); } Integer wk_reloc_type = reloc_type_map.get(new Pair<>(reloc_map.get(sym_id), reloc_type)); if (wk_reloc_type == null) { throw new Exception("unsupported relocation type"); } relocs[offset / 4] = wk_reloc_type.byteValue(); } for (int x = 0; x < want_len; x += 4) { urop_js.add(buf.getInt(x)); } List<Byte> relocsArray = Arrays.asList(ArrayUtils.toObject(relocs)); return new Pair<>(urop_js, relocsArray); }
From source file:com.healthmarketscience.jackcess.Database.java
/** * Reads various config info from the db page 0. *//*from w w w . j av a 2s . com*/ private void initRootPageInfo() throws IOException { ByteBuffer buffer = takeSharedBuffer(); try { _pageChannel.readPage(buffer, 0); _defaultSortOrder = Column.readSortOrder(buffer, _format.OFFSET_SORT_ORDER, _format); _defaultCodePage = buffer.getShort(_format.OFFSET_CODE_PAGE); } finally { releaseSharedBuffer(buffer); } }
From source file:com.healthmarketscience.jackcess.Column.java
/** * Read a column definition in from a buffer * @param table owning table//from www .ja va2s . co m * @param buffer Buffer containing column definition * @param offset Offset in the buffer at which the column definition starts * @usage _advanced_method_ */ public Column(Table table, ByteBuffer buffer, int offset, int displayIndex) throws IOException { _table = table; _displayIndex = displayIndex; if (LOG.isDebugEnabled()) { LOG.debug("Column def block:\n" + ByteUtil.toHexString(buffer, offset, 25)); } byte colType = buffer.get(offset + getFormat().OFFSET_COLUMN_TYPE); _columnNumber = buffer.getShort(offset + getFormat().OFFSET_COLUMN_NUMBER); _columnLength = buffer.getShort(offset + getFormat().OFFSET_COLUMN_LENGTH); byte flags = buffer.get(offset + getFormat().OFFSET_COLUMN_FLAGS); _variableLength = ((flags & FIXED_LEN_FLAG_MASK) == 0); _autoNumber = ((flags & (AUTO_NUMBER_FLAG_MASK | AUTO_NUMBER_GUID_FLAG_MASK)) != 0); try { _type = DataType.fromByte(colType); } catch (IOException e) { LOG.warn("Unsupported column type " + colType); _type = (_variableLength ? DataType.UNSUPPORTED_VARLEN : DataType.UNSUPPORTED_FIXEDLEN); setUnknownDataType(colType); } if (_type.getHasScalePrecision()) { modifyNumericInfo(); _numericInfo._precision = buffer.get(offset + getFormat().OFFSET_COLUMN_PRECISION); _numericInfo._scale = buffer.get(offset + getFormat().OFFSET_COLUMN_SCALE); } else if (_type.isTextual()) { modifyTextInfo(); // co-located w/ precision/scale _textInfo._sortOrder = readSortOrder(buffer, offset + getFormat().OFFSET_COLUMN_SORT_ORDER, getFormat()); int cpOffset = getFormat().OFFSET_COLUMN_CODE_PAGE; if (cpOffset >= 0) { _textInfo._codePage = buffer.getShort(offset + cpOffset); } _textInfo._compressedUnicode = ((buffer.get(offset + getFormat().OFFSET_COLUMN_COMPRESSED_UNICODE) & 1) == 1); } setAutoNumberGenerator(); if (_variableLength) { _varLenTableIndex = buffer.getShort(offset + getFormat().OFFSET_COLUMN_VARIABLE_TABLE_INDEX); } else { _fixedDataOffset = buffer.getShort(offset + getFormat().OFFSET_COLUMN_FIXED_DATA_OFFSET); } // load complex info if (_type == DataType.COMPLEX_TYPE) { _complexInfo = ComplexColumnInfo.create(this, buffer, offset); } }
From source file:com.healthmarketscience.jackcess.Table.java
/** * Delete the row on which the given rowState is currently positioned. * <p>//from w w w . j ava 2 s . co m * Note, this method is not generally meant to be used directly. You should * use the {@link #deleteCurrentRow} method or use the Cursor class, which * allows for more complex table interactions. * @usage _advanced_method_ */ public void deleteRow(RowState rowState, RowId rowId) throws IOException { requireValidRowId(rowId); // ensure that the relevant row state is up-to-date ByteBuffer rowBuffer = positionAtRowHeader(rowState, rowId); requireNonDeletedRow(rowState, rowId); // delete flag always gets set in the "header" row (even if data is on // overflow row) int pageNumber = rowState.getHeaderRowId().getPageNumber(); int rowNumber = rowState.getHeaderRowId().getRowNumber(); // use any read rowValues to help update the indexes Object[] rowValues = (!_indexDatas.isEmpty() ? rowState.getRowValues() : null); int rowIndex = getRowStartOffset(rowNumber, getFormat()); rowBuffer.putShort(rowIndex, (short) (rowBuffer.getShort(rowIndex) | DELETED_ROW_MASK | OVERFLOW_ROW_MASK)); writeDataPage(rowBuffer, pageNumber); // update the indexes for (IndexData indexData : _indexDatas) { indexData.deleteRow(rowValues, rowId); } // make sure table def gets updated updateTableDefinition(-1); }
From source file:nitf.imageio.NITFReader.java
/** * Reads image data as bytes for the given region, and writes it to the * given writable raster/*from w ww . j a va 2 s. com*/ * * @param sourceRegion * @param sourceXSubsampling * @param sourceYSubsampling * @param bandOffsets * @param destinationOffset * @param imRas * @return Raster * @throws IOException */ protected void readRaster(int imageIndex, Rectangle sourceRegion, Rectangle destRegion, int sourceXSubsampling, int sourceYSubsampling, int[] bandOffsets, int pixelSize, Point destinationOffset, WritableRaster imRas) throws IOException { checkIndex(imageIndex); try { ImageSubheader subheader = record.getImages()[imageIndex].getSubheader(); int numCols = subheader.getNumCols().getIntData(); int numRows = subheader.getNumRows().getIntData(); // try to optimize the read call by reading in the entire // image at once if ((destRegion.height * sourceYSubsampling) == numRows && (destRegion.width * sourceXSubsampling) == numCols) { readFullImage(imageIndex, destRegion, sourceXSubsampling, sourceYSubsampling, bandOffsets, pixelSize, imRas); return; } // the general purpose case else { int colBytes = destRegion.width * pixelSize; int dstMinX = imRas.getMinX(); int dstMaxX = dstMinX + imRas.getWidth() - 1; int dstMinY = imRas.getMinY(); int dstMaxY = dstMinY + imRas.getHeight() - 1; // int swap = 0; int nBands = subheader.getBandCount(); /* * NOTE: This is a "fix" that will be removed once the * underlying NITRO library gets patched. Currently, if you make * a request of a single band, it doesn't matter which band you * request - the data from the first band will be returned * regardless. This is obviously wrong. To thwart this, we will * read all bands, then scale down what we return to the user * based on their actual request. */ int[] requestBands = new int[nBands]; for (int i = 0; i < nBands; ++i) requestBands[i] = i; byte[][] rowBuf = new byte[requestBands.length][colBytes]; // make a SubWindow from the params // TODO may want to read by blocks or rows to make faster and // more // memory efficient SubWindow window; window = new SubWindow(); window.setNumBands(requestBands.length); window.setBandList(requestBands); window.setNumCols(destRegion.width); window.setNumRows(1); window.setStartCol(sourceRegion.x); window.setStartRow(sourceRegion.y); // the NITRO library can do the subsampling for us if (sourceYSubsampling != 1 || sourceXSubsampling != 1) { DownSampler downSampler = new PixelSkipDownSampler(sourceYSubsampling, sourceXSubsampling); window.setDownSampler(downSampler); } // String pixelJustification = record.getImages()[imageIndex] // .getSubheader().getPixelJustification().getStringData() // .trim(); // swap = pixelJustification.equals("R") ? 1 : 0; List<ByteBuffer> bandBufs = new ArrayList<ByteBuffer>(); for (int i = 0; i < requestBands.length; ++i) { ByteBuffer bandBuf = null; bandBuf = ByteBuffer.wrap(rowBuf[i]); // bandBuf.order(ByteOrder.nativeOrder()); // bandBuf.order(swap == 0 ? ByteOrder.BIG_ENDIAN // : ByteOrder.LITTLE_ENDIAN); bandBufs.add(bandBuf); } nitf.ImageReader imageReader = getImageReader(imageIndex); for (int srcY = 0; srcY < sourceRegion.height; srcY++) { if (sourceYSubsampling != 1 && (srcY % sourceYSubsampling) != 0) continue; window.setStartRow(sourceRegion.y + srcY); // Read the row try { imageReader.read(window, rowBuf); } catch (NITFException e) { throw new IIOException("Error reading line " + srcY, e); } // Determine where the row will go in the destination int dstY = destinationOffset.y + srcY / sourceYSubsampling; if (dstY < dstMinY) { continue; // The row is above imRas } if (dstY > dstMaxY) { break; // We're done with the image } // Copy each (subsampled) source pixel into imRas for (int srcX = 0, dstX = destinationOffset.x; srcX < colBytes; srcX += pixelSize, dstX++) { if (dstX < dstMinX) { continue; } if (dstX > dstMaxX) { break; } for (int i = 0; i < bandOffsets.length; ++i) { ByteBuffer bandBuf = bandBufs.get(bandOffsets[i]); switch (pixelSize) { case 1: imRas.setSample(dstX, dstY, i, bandBuf.get(srcX)); break; case 2: imRas.setSample(dstX, dstY, i, bandBuf.getShort(srcX)); break; case 4: imRas.setSample(dstX, dstY, i, bandBuf.getFloat(srcX)); break; case 8: imRas.setSample(dstX, dstY, i, bandBuf.getDouble(srcX)); break; } } } } } } catch (NITFException e1) { throw new IOException(ExceptionUtils.getStackTrace(e1)); } }
From source file:com.healthmarketscience.jackcess.Table.java
/** * Read the table definition//from w w w . ja va 2 s . co m */ private void readTableDefinition(ByteBuffer tableBuffer) throws IOException { if (LOG.isDebugEnabled()) { tableBuffer.rewind(); LOG.debug("Table def block:\n" + ByteUtil.toHexString(tableBuffer, getFormat().SIZE_TDEF_HEADER)); } _rowCount = tableBuffer.getInt(getFormat().OFFSET_NUM_ROWS); _lastLongAutoNumber = tableBuffer.getInt(getFormat().OFFSET_NEXT_AUTO_NUMBER); if (getFormat().OFFSET_NEXT_COMPLEX_AUTO_NUMBER >= 0) { _lastComplexTypeAutoNumber = tableBuffer.getInt(getFormat().OFFSET_NEXT_COMPLEX_AUTO_NUMBER); } _tableType = tableBuffer.get(getFormat().OFFSET_TABLE_TYPE); _maxColumnCount = tableBuffer.getShort(getFormat().OFFSET_MAX_COLS); _maxVarColumnCount = tableBuffer.getShort(getFormat().OFFSET_NUM_VAR_COLS); short columnCount = tableBuffer.getShort(getFormat().OFFSET_NUM_COLS); _logicalIndexCount = tableBuffer.getInt(getFormat().OFFSET_NUM_INDEX_SLOTS); _indexCount = tableBuffer.getInt(getFormat().OFFSET_NUM_INDEXES); int rowNum = ByteUtil.getUnsignedByte(tableBuffer, getFormat().OFFSET_OWNED_PAGES); int pageNum = ByteUtil.get3ByteInt(tableBuffer, getFormat().OFFSET_OWNED_PAGES + 1); _ownedPages = UsageMap.read(getDatabase(), pageNum, rowNum, false); rowNum = ByteUtil.getUnsignedByte(tableBuffer, getFormat().OFFSET_FREE_SPACE_PAGES); pageNum = ByteUtil.get3ByteInt(tableBuffer, getFormat().OFFSET_FREE_SPACE_PAGES + 1); _freeSpacePages = UsageMap.read(getDatabase(), pageNum, rowNum, false); for (int i = 0; i < _indexCount; i++) { _indexDatas.add(IndexData.create(this, tableBuffer, i, getFormat())); } int colOffset = getFormat().OFFSET_INDEX_DEF_BLOCK + _indexCount * getFormat().SIZE_INDEX_DEFINITION; int dispIndex = 0; for (int i = 0; i < columnCount; i++) { Column column = new Column(this, tableBuffer, colOffset + (i * getFormat().SIZE_COLUMN_HEADER), dispIndex++); _columns.add(column); if (column.isVariableLength()) { // also shove it in the variable columns list, which is ordered // differently from the _columns list _varColumns.add(column); } } tableBuffer.position(colOffset + (columnCount * getFormat().SIZE_COLUMN_HEADER)); for (int i = 0; i < columnCount; i++) { Column column = _columns.get(i); column.setName(readName(tableBuffer)); } Collections.sort(_columns); _autoNumColumns = getAutoNumberColumns(_columns); // setup the data index for the columns int colIdx = 0; for (Column col : _columns) { col.setColumnIndex(colIdx++); } // sort variable length columns based on their index into the variable // length offset table, because we will write the columns in this order Collections.sort(_varColumns, VAR_LEN_COLUMN_COMPARATOR); // read index column information for (int i = 0; i < _indexCount; i++) { _indexDatas.get(i).read(tableBuffer, _columns); } // read logical index info (may be more logical indexes than index datas) for (int i = 0; i < _logicalIndexCount; i++) { _indexes.add(new Index(tableBuffer, _indexDatas, getFormat())); } // read logical index names for (int i = 0; i < _logicalIndexCount; i++) { _indexes.get(i).setName(readName(tableBuffer)); } Collections.sort(_indexes); // re-sort columns if necessary if (getDatabase().getColumnOrder() != ColumnOrder.DATA) { Collections.sort(_columns, DISPLAY_ORDER_COMPARATOR); } for (Column col : _columns) { // some columns need to do extra work after the table is completely // loaded col.postTableLoadInit(); } }
From source file:com.healthmarketscience.jackcess.Table.java
/** * Reads the column data from the given row buffer. Leaves limit unchanged. * Caches the returned value in the rowState. *//*from w w w . j a va 2 s . c o m*/ private static Object getRowColumn(JetFormat format, ByteBuffer rowBuffer, Column column, RowState rowState, Map<Column, byte[]> rawVarValues) throws IOException { byte[] columnData = null; try { NullMask nullMask = rowState.getNullMask(rowBuffer); boolean isNull = nullMask.isNull(column); if (column.getType() == DataType.BOOLEAN) { // Boolean values are stored in the null mask. see note about // caching below return rowState.setRowValue(column.getColumnIndex(), Boolean.valueOf(!isNull)); } else if (isNull) { // well, that's easy! (no need to update cache w/ null) return null; } // reset position to row start rowBuffer.reset(); // locate the column data bytes int rowStart = rowBuffer.position(); int colDataPos = 0; int colDataLen = 0; if (!column.isVariableLength()) { // read fixed length value (non-boolean at this point) int dataStart = rowStart + format.OFFSET_COLUMN_FIXED_DATA_ROW_OFFSET; colDataPos = dataStart + column.getFixedDataOffset(); colDataLen = column.getType().getFixedSize(column.getLength()); } else { int varDataStart; int varDataEnd; if (format.SIZE_ROW_VAR_COL_OFFSET == 2) { // read simple var length value int varColumnOffsetPos = (rowBuffer.limit() - nullMask.byteSize() - 4) - (column.getVarLenTableIndex() * 2); varDataStart = rowBuffer.getShort(varColumnOffsetPos); varDataEnd = rowBuffer.getShort(varColumnOffsetPos - 2); } else { // read jump-table based var length values short[] varColumnOffsets = readJumpTableVarColOffsets(rowState, rowBuffer, rowStart, nullMask); varDataStart = varColumnOffsets[column.getVarLenTableIndex()]; varDataEnd = varColumnOffsets[column.getVarLenTableIndex() + 1]; } colDataPos = rowStart + varDataStart; colDataLen = varDataEnd - varDataStart; } // grab the column data columnData = new byte[colDataLen]; rowBuffer.position(colDataPos); rowBuffer.get(columnData); if ((rawVarValues != null) && column.isVariableLength()) { // caller wants raw value as well rawVarValues.put(column, columnData); } // parse the column data. we cache the row values in order to be able // to update the index on row deletion. note, most of the returned // values are immutable, except for binary data (returned as byte[]), // but binary data shouldn't be indexed anyway. return rowState.setRowValue(column.getColumnIndex(), column.read(columnData)); } catch (Exception e) { // cache "raw" row value. see note about caching above rowState.setRowValue(column.getColumnIndex(), Column.rawDataWrapper(columnData)); return rowState.handleRowError(column, columnData, e); } }
From source file:com.healthmarketscience.jackcess.impl.TableImpl.java
/** * @param database database which owns this table * @param tableBuffer Buffer to read the table with * @param pageNumber Page number of the table definition * @param name Table name/*from w w w. ja va 2 s.c o m*/ */ protected TableImpl(DatabaseImpl database, ByteBuffer tableBuffer, int pageNumber, String name, int flags) throws IOException { _database = database; _tableDefPageNumber = pageNumber; _name = name; _flags = flags; // read table definition tableBuffer = loadCompleteTableDefinitionBuffer(tableBuffer); _rowCount = tableBuffer.getInt(getFormat().OFFSET_NUM_ROWS); _lastLongAutoNumber = tableBuffer.getInt(getFormat().OFFSET_NEXT_AUTO_NUMBER); if (getFormat().OFFSET_NEXT_COMPLEX_AUTO_NUMBER >= 0) { _lastComplexTypeAutoNumber = tableBuffer.getInt(getFormat().OFFSET_NEXT_COMPLEX_AUTO_NUMBER); } _tableType = tableBuffer.get(getFormat().OFFSET_TABLE_TYPE); _maxColumnCount = tableBuffer.getShort(getFormat().OFFSET_MAX_COLS); _maxVarColumnCount = tableBuffer.getShort(getFormat().OFFSET_NUM_VAR_COLS); short columnCount = tableBuffer.getShort(getFormat().OFFSET_NUM_COLS); _logicalIndexCount = tableBuffer.getInt(getFormat().OFFSET_NUM_INDEX_SLOTS); _indexCount = tableBuffer.getInt(getFormat().OFFSET_NUM_INDEXES); tableBuffer.position(getFormat().OFFSET_OWNED_PAGES); _ownedPages = UsageMap.read(getDatabase(), tableBuffer, false); tableBuffer.position(getFormat().OFFSET_FREE_SPACE_PAGES); _freeSpacePages = UsageMap.read(getDatabase(), tableBuffer, false); for (int i = 0; i < _indexCount; i++) { _indexDatas.add(IndexData.create(this, tableBuffer, i, getFormat())); } readColumnDefinitions(tableBuffer, columnCount); readIndexDefinitions(tableBuffer); // read column usage map info while (tableBuffer.remaining() >= 2) { short umapColNum = tableBuffer.getShort(); if (umapColNum == IndexData.COLUMN_UNUSED) { break; } int pos = tableBuffer.position(); UsageMap colOwnedPages = null; UsageMap colFreeSpacePages = null; try { colOwnedPages = UsageMap.read(getDatabase(), tableBuffer, false); colFreeSpacePages = UsageMap.read(getDatabase(), tableBuffer, false); } catch (IllegalStateException e) { // ignore invalid usage map info colOwnedPages = null; colFreeSpacePages = null; tableBuffer.position(pos + 8); LOG.warn("Table " + _name + " invalid column " + umapColNum + " usage map definition: " + e); } for (ColumnImpl col : _columns) { if (col.getColumnNumber() == umapColNum) { col.setUsageMaps(colOwnedPages, colFreeSpacePages); break; } } } // re-sort columns if necessary if (getDatabase().getColumnOrder() != ColumnOrder.DATA) { Collections.sort(_columns, DISPLAY_ORDER_COMPARATOR); } for (ColumnImpl col : _columns) { // some columns need to do extra work after the table is completely // loaded col.postTableLoadInit(); } _fkEnforcer = new FKEnforcer(this); if (!isSystem()) { // after fully constructed, allow column validator to be configured (but // only for user tables) for (ColumnImpl col : _columns) { col.setColumnValidator(null); } } }
From source file:nitf.imageio.NITFReader.java
/** * Optimization to read the entire image in one fell swoop... This is most * likely the common use case for this codec, so we hope this optimization * will be helpful./*from ww w .j a v a 2s . co m*/ * * @param imageIndex * @param sourceXSubsampling * @param sourceYSubsampling * @param bandOffsets * @param pixelSize * @param imRas * @throws IOException */ protected void readFullImage(int imageIndex, Rectangle destRegion, int sourceXSubsampling, int sourceYSubsampling, int[] bandOffsets, int pixelSize, WritableRaster imRas) throws IOException { try { ImageSubheader subheader = record.getImages()[imageIndex].getSubheader(); int numCols = destRegion.width; int numRows = destRegion.height; int nBands = subheader.getBandCount(); /* * NOTE: This is a "fix" that will be removed once the underlying * NITRO library gets patched. Currently, if you make a request of a * single band, it doesn't matter which band you request - the data * from the first band will be returned regardless. This is * obviously wrong. To thwart this, we will read all bands, then * scale down what we return to the user based on their actual * request. */ int[] requestBands = bandOffsets; /* * if (nBands != bandOffsets.length && bandOffsets.length == 1 * && bandOffsets[0] != 0) * { * requestBands = new int[nBands]; * for (int i = 0; i < nBands; ++i) * requestBands[i] = i; * } */ int bufSize = numCols * numRows * pixelSize; byte[][] imageBuf = new byte[requestBands.length][bufSize]; // make a SubWindow from the params // TODO may want to read by blocks or rows to make faster and more // memory efficient SubWindow window; window = new SubWindow(); window.setNumBands(requestBands.length); window.setBandList(requestBands); window.setNumCols(numCols); window.setNumRows(numRows); window.setStartCol(0); window.setStartRow(0); // the NITRO library can do the subsampling for us if (sourceYSubsampling != 1 || sourceXSubsampling != 1) { DownSampler downSampler = new PixelSkipDownSampler(sourceYSubsampling, sourceXSubsampling); window.setDownSampler(downSampler); } // String pixelJustification = subheader.getPixelJustification() // .getStringData().trim(); // boolean shouldSwap = pixelJustification.equals("R"); // since this is Java, we need the data in big-endian format // boolean shouldSwap = ByteOrder.nativeOrder() != // ByteOrder.BIG_ENDIAN; nitf.ImageReader imageReader = getImageReader(imageIndex); imageReader.read(window, imageBuf); List<ByteBuffer> bandBufs = new ArrayList<ByteBuffer>(); for (int i = 0; i < bandOffsets.length; ++i) { ByteBuffer bandBuf = null; // the special "fix" we added needs to do this if (bandOffsets.length != requestBands.length) { bandBuf = ByteBuffer.wrap(imageBuf[bandOffsets[i]]); } else { bandBuf = ByteBuffer.wrap(imageBuf[i]); } // ban dBuf.order(ByteOrder.nativeOrder()); // shouldSwap ? ByteOrder.LITTLE_ENDIAN // : ByteOrder.BIG_ENDIAN); bandBufs.add(bandBuf); } // optimization for 1 band case... just dump the whole thing if (bandOffsets.length == 1) { ByteBuffer bandBuf = bandBufs.get(0); switch (pixelSize) { case 1: ByteBuffer rasterByteBuf = ByteBuffer.wrap(((DataBufferByte) imRas.getDataBuffer()).getData()); rasterByteBuf.put(bandBuf); break; case 2: ShortBuffer rasterShortBuf = ShortBuffer .wrap(((DataBufferUShort) imRas.getDataBuffer()).getData()); rasterShortBuf.put(bandBuf.asShortBuffer()); break; case 4: FloatBuffer rasterFloatBuf = FloatBuffer .wrap(((DataBufferFloat) imRas.getDataBuffer()).getData()); rasterFloatBuf.put(bandBuf.asFloatBuffer()); break; case 8: DoubleBuffer rasterDoubleBuf = DoubleBuffer .wrap(((DataBufferDouble) imRas.getDataBuffer()).getData()); rasterDoubleBuf.put(bandBuf.asDoubleBuffer()); break; } } else { // for multi-band case, we need to iterate over each pixel... // TODO -- optimize this!... somehow for (int srcY = 0, srcX = 0; srcY < numRows; srcY++) { // Copy each (subsampled) source pixel into imRas for (int dstX = 0; dstX < numCols; srcX += pixelSize, dstX++) { for (int i = 0; i < bandOffsets.length; ++i) { ByteBuffer bandBuf = bandBufs.get(i); switch (pixelSize) { case 1: imRas.setSample(dstX, srcY, i, bandBuf.get(srcX)); break; case 2: imRas.setSample(dstX, srcY, i, bandBuf.getShort(srcX)); break; case 4: imRas.setSample(dstX, srcY, i, bandBuf.getFloat(srcX)); break; case 8: imRas.setSample(dstX, srcY, i, bandBuf.getDouble(srcX)); break; } } } } } } catch (NITFException e1) { throw new IOException(ExceptionUtils.getStackTrace(e1)); } }