import albedo/openai_api/types
import gleam/result
import gleam/string
/// Decode canonical base64 and derive MIME and dimensions from bounded headers.
/// This verifies transport metadata, not the complete compressed image stream.
pub fn validate(
mime_type: String,
data: String,
width: Int,
height: Int,
bytes: Int,
) -> Result(types.Image, String) {
use image <- result.try(
types.image(mime_type, data, width, height, bytes)
|> result.map_error(string.inspect),
)
use inspected <- result.try(
inspect(data)
|> result.replace_error("invalid image payload or header"),
)
case inspected == #(mime_type, width, height, bytes) {
True -> Ok(image)
False -> Error("image metadata does not match its payload")
}
}
/// An image whose MIME type and dimensions are read from its own header.
pub fn from_base64(data: String) -> Result(types.Image, String) {
use #(mime_type, width, height, bytes) <- result.try(
inspect(data)
|> result.replace_error("not a PNG, JPEG, or WebP albedo can read"),
)
types.image(mime_type, data, width, height, bytes)
|> result.map_error(fn(error) {
case error {
types.InvalidRequest(message) -> message
other -> string.inspect(other)
}
})
}
@external(erlang, "albedo_image", "inspect")
fn inspect(data: String) -> Result(#(String, Int, Int, Int), Nil)