long blockPos = blockPtrPos + 8 * numBlocks;
int maximumBlockSize = computeMaximumTileSize(new V2i(dw.getXSize(),
Math.min(dw.getYSize(), cm.getScanLinesPerBlock())));
byte[] blockData = new byte[maximumBlockSize];
IIOByteBuffer buf = new IIOByteBuffer(null, 0, 0);
ByteBuffer bytes = ByteBuffer.wrap(blockData).order(ByteOrder.LITTLE_ENDIAN);
int firstBlock;
int lastBlock;
int blockIncr;
switch (getLineOrder()) {
case INCREASING_Y:
case RANDOM_Y:
firstBlock = 0;
lastBlock = numBlocks;
blockIncr = 1;
break;
case DECREASING_Y:
firstBlock = numBlocks - 1;
lastBlock = -1;
blockIncr = -1;
break;
default:
throw new UnexpectedException("Invalid line order");
}
for (int i = firstBlock; i != lastBlock; i += blockIncr) {
out.seek(blockPtrPos + 8 * i);
out.writeLong(blockPos - start);
out.seek(blockPos);
bytes.rewind();
// TODO write the next block here
int x0 = dw.getXMin();
int x1 = dw.getXMax();
int y0 = dw.getYMin() + i * cm.getScanLinesPerBlock();
int y1 = Math.min(y0 + cm.getScanLinesPerBlock() - 1, dw.getYMax());
Box2i block = new Box2i(x0, y0, x1, y1);
int blockSize = computeTileSize(block);
for (int y = y0; y <= y1; y++) {
for (Channel channel : chlist.channels()) {
String name = channel.getName();
int sx = channel.getxSampling();
int sy = channel.getySampling();
if (y % sy == 0) {
int nx = 1 + (x1 - x0 - (x1 % sx)) / sx;
int offset = ((y - ymin) / sy) * nx;
Buffer chBuf = getChannelBuffer(name);
PixelType pt = channel.getPixelType();
switch (pt) {
case UINT:
bytes.asIntBuffer().put((IntBuffer)
((IntBuffer) chBuf).duplicate().position(offset).limit(offset + nx));
break;
case HALF:
bytes.asShortBuffer().put((ShortBuffer)
((ShortBuffer) chBuf).duplicate().position(offset).limit(offset + nx));
break;
case FLOAT:
bytes.asFloatBuffer().put((FloatBuffer)
((FloatBuffer) chBuf).duplicate().position(offset).limit(offset + nx));
break;
default:
throw new UnexpectedException("Invalid pixel type");
}
bytes.position(bytes.position() + nx * pt.getSampleSize());
}
}
}
buf.setData(blockData);
buf.setOffset(0);
buf.setLength(blockSize);
cm.compress(buf, block);
out.writeInt(y0);
if (buf.getLength() < blockSize) {
out.writeInt(buf.getLength());
out.write(buf.getData(), buf.getOffset(), buf.getLength());
} else {
out.writeInt(blockSize);
out.write(blockData);
}