QrLuminance.kt
/*
* This file is part of GNU Taler
* (C) 2026 Taler Systems S.A.
*
* GNU Taler is free software; you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation; either version 3, or (at your option) any later version.
*
* GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/
package net.taler.merchantpos.config
import com.google.zxing.PlanarYUVLuminanceSource
import java.nio.ByteBuffer
/** Camera planes may contain padding between rows and between individual pixels. */
internal fun qrLuminance(
buffer: ByteBuffer,
width: Int,
height: Int,
rowStride: Int,
pixelStride: Int,
rotation: Int,
): PlanarYUVLuminanceSource
{
require(width > 0 && height > 0 && pixelStride > 0)
require(rowStride.toLong() >= (width - 1L) * pixelStride + 1)
require(rotation in setOf(0, 90, 180, 270))
require((height - 1L) * rowStride + (width - 1L) * pixelStride < buffer.remaining())
val swapped = rotation == 90 || rotation == 270
val outputWidth = if (swapped) height else width
val outputHeight = if (swapped) width else height
val pixels = ByteArray(Math.multiplyExact(width, height))
val offset = buffer.position()
for (y in 0 until height)
{
for (x in 0 until width)
{
val destination =
when (rotation)
{
90 -> x * outputWidth + height - 1 - y
180 -> (height - 1 - y) * outputWidth + width - 1 - x
270 -> (width - 1 - x) * outputWidth + y
else -> y * outputWidth + x
}
pixels[destination] = buffer.get(offset + y * rowStride + x * pixelStride)
}
}
return PlanarYUVLuminanceSource(
pixels,
outputWidth,
outputHeight,
0,
0,
outputWidth,
outputHeight,
false,
)
}