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

commonMain.org.jetbrains.letsPlot.util.pngj.chunks.PngChunkITXT.kt Maven / Gradle / Ivy

/*
 * Copyright (c) 2023 JetBrains s.r.o.
 * Use of this source code is governed by the MIT license that can be found in the LICENSE file.
 *
 * This file has been modified by JetBrains : Java code has been converted to Kotlin code.
 *
 * THE FOLLOWING IS THE COPYRIGHT OF THE ORIGINAL DOCUMENT:
 *
 * Copyright (c) 2009-2012, Hernán J. González.
 * Licensed under the Apache License, Version 2.0.
 *
 * The original PNGJ library is written in Java and can be found here: [PNGJ](https://github.com/leonbloy/pngj).
 */

package org.jetbrains.letsPlot.util.pngj.chunks

import org.jetbrains.letsPlot.util.pngj.ImageInfo
import org.jetbrains.letsPlot.util.pngj.OutputPngStream
import org.jetbrains.letsPlot.util.pngj.PngjException

/**
 * iTXt chunk.
 *
 *
 * see http://www.w3.org/TR/PNG/#11iTXt
 */
internal class PngChunkITXT  // http://www.w3.org/TR/PNG/#11iTXt
    (info: ImageInfo?) : PngChunkTextVar(ID, info) {
    private var isCompressed = false
    private var langtag = ""
    private var translatedTag = ""
    override fun createRawChunk(): ChunkRaw {
        if (key == null || key!!.trim { it <= ' ' }.isEmpty()) throw PngjException("Text chunk key must be non empty")

        val ba = OutputPngStream()
        ba.write(ChunkHelper.toBytesLatin1(key!!))
        ba.write(0) // separator
        ba.write(if (isCompressed) 1 else 0)
        ba.write(0) // compression method (always 0)
        ba.write(ChunkHelper.toBytesLatin1(langtag))
        ba.write(0) // separator
        ba.write(ChunkHelper.toBytesUTF8(translatedTag))
        ba.write(0) // separator
        var textbytes: ByteArray = ChunkHelper.toBytesUTF8(value!!)
        if (isCompressed) {
            textbytes = ChunkHelper.compressBytes(textbytes, true)
        }
        ba.write(textbytes)
        val b: ByteArray = ba.byteArray
        val chunk: ChunkRaw = createEmptyChunk(b.size, false)
        chunk.data = b
        return chunk
    }

    override fun parseFromRaw(chunk: ChunkRaw) {
        var nullsFound = 0
        val nullsIdx = IntArray(3)
        run {
            var i = 0
            while (i < chunk.data!!.size) {
                if (chunk.data!![i].toInt() != 0) {
                    i++
                    continue
                }
                nullsIdx[nullsFound] = i
                nullsFound++
                if (nullsFound == 1) i += 2
                if (nullsFound == 3) break
                i++
            }
        }
        if (nullsFound != 3) throw PngjException("Bad formed PngChunkITXT chunk")
        key = ChunkHelper.toStringLatin1(chunk.data!!, 0, nullsIdx[0])
        var i = nullsIdx[0] + 1
        isCompressed = chunk.data!![i] != 0.toByte()
        i++
        if (isCompressed && chunk.data!![i]
                .toInt() != 0
        ) throw PngjException("Bad formed PngChunkITXT chunk - bad compression method ")
        langtag = ChunkHelper.toStringLatin1(chunk.data!!, i, nullsIdx[1] - i)
        translatedTag = ChunkHelper.toStringUTF8(chunk.data!!, nullsIdx[1] + 1, nullsIdx[2] - nullsIdx[1] - 1)
        i = nullsIdx[2] + 1
        value = if (isCompressed) {
            val bytes: ByteArray = ChunkHelper.compressBytes(chunk.data!!, i, chunk.data!!.size - i, false)
            ChunkHelper.toStringUTF8(bytes)
        } else {
            ChunkHelper.toStringUTF8(chunk.data!!, i, chunk.data!!.size - i)
        }
    }

    companion object {
        const val ID = ChunkHelper.iTXt
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy