All Downloads are FREE. Search and download functionalities are using the official Maven repository.

eu.joaocosta.minart.graphics.image.pdi.PdiImageWriter.scala Maven / Gradle / Ivy

package eu.joaocosta.minart.graphics.image.pdi

import java.io.OutputStream

import eu.joaocosta.minart.graphics.*
import eu.joaocosta.minart.graphics.image.*
import eu.joaocosta.minart.internal.*

/** Image writer for Pdi files.
  *
  * Stores data as uncompressed PlayDate PDIs.
  */
trait PdiImageWriter extends ImageWriter {
  import ByteWriter.*

  private def colorsToByte(acc: Byte, colors: List[Color], f: Color => Boolean): Byte = colors match {
    case Nil => acc
    case color :: rem =>
      if (f(color)) colorsToByte(((acc << 1) | 0x01).toByte, rem, f)
      else colorsToByte((acc << 1).toByte, rem, f)
  }

  private def lineToBytes(colors: Array[Color], f: Color => Boolean): Array[Byte] =
    colors.sliding(8, 8).map(cs => colorsToByte(0.toByte, cs.toList.padTo(8, Color(0, 0, 0, 0)), f)).toArray

  private val storeHeader: ByteStreamState[String] = {
    (for {
      _ <- writeString("Playdate IMG")
      _ <- writeLENumber(0, 4) // Disable compression
    } yield ())
  }

  private def storeCellHeader(surface: Surface): ByteStreamState[String] = {
    (for {
      _ <- writeLENumber(surface.width, 2)
      _ <- writeLENumber(surface.height, 2)
      _ <- writeLENumber(math.ceil(surface.width / 8.0).toInt, 2)
      _ <- writeLENumber(0, 2)    // No padding
      _ <- writeLENumber(0, 2)    // No padding
      _ <- writeLENumber(0, 2)    // No padding
      _ <- writeLENumber(0, 2)    // No padding
      _ <- writeLENumber(0x03, 2) // Always enable transparency
    } yield ())
  }

  final def storeImage(surface: Surface, os: OutputStream): Either[String, Unit] = {
    val state = for {
      _ <- storeHeader
      _ <- storeCellHeader(surface)
      pixels = surface.getPixels()
      _ <- append(
        pixels.iterator.map(line => lineToBytes(line, color => math.max(math.max(color.r, color.g), color.b) >= 127))
      )
      _ <- append(pixels.iterator.map(line => lineToBytes(line, color => color.a > 0)))
    } yield ()
    toOutputStream(state, os)
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy