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.nio.charset.StandardCharsets;
020
021import org.apache.commons.imaging.ImagingException;
022import org.apache.commons.imaging.common.BinaryFunctions;
023
024public final class PngChunkScal extends PngChunk {
025
026    private final double unitsPerPixelXAxis;
027    private final double unitsPerPixelYAxis;
028    private final int unitSpecifier;
029
030    public PngChunkScal(final int length, final int chunkType, final int crc, final byte[] bytes) throws ImagingException {
031        super(length, chunkType, crc, bytes);
032
033        unitSpecifier = bytes[0];
034        if (getUnitSpecifier() != 1 && getUnitSpecifier() != 2) {
035            throw new ImagingException("PNG sCAL invalid unit specifier: " + getUnitSpecifier());
036        }
037
038        final int separator = BinaryFunctions.indexOf0(bytes, "PNG sCAL x and y axis value separator not found.");
039        final int xIndex = 1;
040        final String xStr = new String(bytes, xIndex, separator - 1, StandardCharsets.ISO_8859_1);
041        unitsPerPixelXAxis = toDouble(xStr);
042
043        final int yIndex = separator + 1;
044        if (yIndex >= length) {
045            throw new ImagingException("PNG sCAL chunk missing the y axis value.");
046        }
047
048        final String yStr = new String(bytes, yIndex, length - yIndex, StandardCharsets.ISO_8859_1);
049        unitsPerPixelYAxis = toDouble(yStr);
050    }
051
052    public int getUnitSpecifier() {
053        return unitSpecifier;
054    }
055
056    public double getUnitsPerPixelXAxis() {
057        return unitsPerPixelXAxis;
058    }
059
060    public double getUnitsPerPixelYAxis() {
061        return unitsPerPixelYAxis;
062    }
063
064    private double toDouble(final String str) throws ImagingException {
065        try {
066            return Double.parseDouble(str);
067        } catch (final NumberFormatException e) {
068            throw new ImagingException("PNG sCAL error reading axis value - " + str);
069        }
070    }
071}