    001/*
    002 * Licensed to the Apache Software Foundation (ASF) under one or more
    003 * contributor license agreements.  See the NOTICE file distributed with
    004 * this work for additional information regarding copyright ownership.
    005 * The ASF licenses this file to You under the Apache License, Version 2.0
    006 * (the "License"); you may not use this file except in compliance with
    007 * the License.  You may obtain a copy of the License at
    008 *
    009 *      http://www.apache.org/licenses/LICENSE-2.0
    010 *
    011 * Unless required by applicable law or agreed to in writing, software
    012 * distributed under the License is distributed on an "AS IS" BASIS,
    013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    014 * See the License for the specific language governing permissions and
    015 * limitations under the License.
    016 */
    017package org.apache.commons.imaging.formats.png.chunks;
    018
    019import java.io.ByteArrayInputStream;
    020import java.io.IOException;
    021import java.nio.charset.StandardCharsets;
    022import java.util.zip.InflaterInputStream;
    023
    024import org.apache.commons.imaging.ImagingException;
    025import org.apache.commons.imaging.common.Allocator;
    026import org.apache.commons.imaging.common.BinaryFunctions;
    027import org.apache.commons.imaging.formats.png.AbstractPngText;
    028import org.apache.commons.imaging.formats.png.PngConstants;
    029import org.apache.commons.io.IOUtils;
    030
    031public final class PngChunkZtxt extends AbstractPngTextChunk {
    032
    033    private final String keyword;
    034    private final String text;
    035
    036    public PngChunkZtxt(final int length, final int chunkType, final int crc, final byte[] bytes) throws ImagingException, IOException {
    037        super(length, chunkType, crc, bytes);
    038
    039        int index = BinaryFunctions.indexOf0(bytes, "PNG zTXt chunk keyword is unterminated.");
    040        keyword = new String(bytes, 0, index, StandardCharsets.ISO_8859_1);
    041        index++;
    042
    043        final int compressionMethod = bytes[index++];
    044        if (compressionMethod != PngConstants.COMPRESSION_DEFLATE_INFLATE) {
    045            throw new ImagingException("PNG zTXt chunk has unexpected compression method: " + compressionMethod);
    046        }
    047
    048        final int compressedTextLength = bytes.length - index;
    049        final byte[] compressedText = Allocator.byteArray(compressedTextLength);
    050        System.arraycopy(bytes, index, compressedText, 0, compressedTextLength);
    051
    052        text = new String(IOUtils.toByteArray(new InflaterInputStream(new ByteArrayInputStream(compressedText))), StandardCharsets.ISO_8859_1);
    053    }
    054
    055    @Override
    056    public AbstractPngText getContents() {
    057        return new AbstractPngText.Ztxt(keyword, text);
    058    }
    059
    060    /**
    061     * Gets the keyword.
    062     *
    063     * @return the keyword.
    064     */
    065    @Override
    066    public String getKeyword() {
    067        return keyword;
    068    }
    069
    070    /**
    071     * Gets the text.
    072     *
    073     * @return the text.
    074     */
    075    @Override
    076    public String getText() {
    077        return text;
    078    }
    079
    080}