ProductImage.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.history
import android.graphics.BitmapFactory
import android.util.Base64
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.asImageBitmap
/** Product contract images use data URLs, as in the existing inventory screen. */
internal fun decodeProductImage(data: String?): ImageBitmap?
{
if (data == null ||
!data.startsWith("data:image/") ||
data.length > 12_000_000)
{
return null
}
val separator = data.indexOf(";base64,")
if (separator < 0) return null
return try
{
val bytes = Base64.decode(data.substring(separator + 8), Base64.DEFAULT)
val options = BitmapFactory.Options().apply { inJustDecodeBounds = true }
BitmapFactory.decodeByteArray(bytes, 0, bytes.size, options)
if (options.outWidth <= 0 ||
options.outHeight <= 0)
{
return null
}
options.inSampleSize = 1
while (maxOf(options.outWidth, options.outHeight) / options.inSampleSize > 1600) options.inSampleSize *= 2
options.inJustDecodeBounds = false
BitmapFactory.decodeByteArray(bytes, 0, bytes.size, options)?.asImageBitmap()
}
catch (_: IllegalArgumentException)
{
null
}
}