Не выполнять ручное копирование.
Вы можете использовать, например,
IntBuffer src = IntBuffer.wrap(sourceArray, sourceOffset, sourceArray.length-sourceOffset);
IntBuffer dst = ByteBuffer.wrap(destArray, destOffset, destArray.length - destOffset)
.order(ByteOrder.LITTLE_ENDIAN).asIntBuffer();
for(int i = 0; i < height; i++) {
dst.put(src.limit(src.position()+width));
src.limit(src.capacity()).position(src.position() + sourceIncrement);
dst.position(dst.position() + (destIncrement >> 2));
}
Это предполагает, что destIncrement
описывает пиксельные единицы, то есть кратно четырем. Кроме того, предполагается, что массивы достаточно длинные, что составляет sourceIncrement
соответственно. destIncrement
место для последней строки, которая не записана, но буфер не позволяет установить позицию после последней строки в противном случае.
Если у массивов нет этой комнаты, вы бы необходимо выйти из l oop в последнем ряду, прежде чем увеличивать позиции:
if(height > 0) {
IntBuffer src = IntBuffer.wrap(sourceArray, sourceOffset,
sourceArray.length - sourceOffset);
IntBuffer dst = ByteBuffer.wrap(destArray, destOffset, destArray.length - destOffset)
.order(ByteOrder.LITTLE_ENDIAN).asIntBuffer();
for(int i = 0; ;) {
dst.put(src.limit(src.position()+width));
if(++i == height) break;
src.limit(src.capacity()).position(src.position() + sourceIncrement);
dst.position(dst.position() + (destIncrement >> 2));
}
}
Не ясно, выиграет ли это от параллельной обработки вообще, но для завершения, вот параллельный вариант:
IntBuffer src = IntBuffer.wrap(sourceArray, sourceOffset, (width+sourceIncrement)*height);
IntBuffer dst = ByteBuffer.wrap(destArray, destOffset, (width*4+destIncrement)*height)
.order(ByteOrder.LITTLE_ENDIAN).asIntBuffer();
int srcRow = width + sourceIncrement, dstRow = width + (destIncrement>>2);
IntStream.range(0, height).parallel()
.forEach(y -> dst.slice().position(y * dstRow)
.put(src.slice().position(y * srcRow).limit(y * srcRow + width))
);
Поскольку положение и лимит буфера не являются потокобезопасными, мы должны создать локальный буфер. Это решение использует slice()
, который инкапсулирует начальные значения sourceOffset
соотв. destOffset
, упрощающий расчет позиции и лимита для операции перевода. Вычисление их до перевода также гарантирует, что позиция никогда не будет продвигаться дальше, чем width
последнего ряда.