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.tiff.taginfos;
018
019import java.nio.ByteOrder;
020import java.nio.charset.StandardCharsets;
021
022import org.apache.commons.imaging.ImagingException;
023import org.apache.commons.imaging.common.Allocator;
024import org.apache.commons.imaging.formats.tiff.constants.TiffDirectoryType;
025import org.apache.commons.imaging.formats.tiff.fieldtypes.AbstractFieldType;
026
027public class TagInfoAscii extends TagInfo {
028    public TagInfoAscii(final String name, final int tag, final int length, final TiffDirectoryType directoryType) {
029        super(name, tag, AbstractFieldType.ASCII, length, directoryType);
030    }
031
032    public byte[] encodeValue(final ByteOrder byteOrder, final String... values) throws ImagingException {
033        return AbstractFieldType.ASCII.writeData(values, byteOrder);
034    }
035
036    public String[] getValue(final ByteOrder byteOrder, final byte[] bytes) {
037        int nullCount = 0;
038        for (int i = 0; i < bytes.length - 1; i++) {
039            if (bytes[i] == 0) {
040                nullCount++;
041            }
042        }
043        final String[] strings = Allocator.array(nullCount + 1, String[]::new, 24);
044        int stringsAdded = 0;
045        strings[0] = ""; // if we have a 0 length string
046        int nextStringPos = 0;
047        // According to the Exiftool FAQ, [BROKEN URL] http://www.metadataworkinggroup.org
048        // specifies that the TIFF ASCII fields are actually UTF-8.
049        // Exiftool however allows you to configure the charset used.
050        for (int i = 0; i < bytes.length; i++) {
051            if (bytes[i] == 0) {
052                final String string = new String(bytes, nextStringPos, i - nextStringPos, StandardCharsets.UTF_8);
053                strings[stringsAdded++] = string;
054                nextStringPos = i + 1;
055            }
056        }
057        if (nextStringPos < bytes.length) {
058            // Buggy file, string wasn't null terminated
059            final String string = new String(bytes, nextStringPos, bytes.length - nextStringPos, StandardCharsets.UTF_8);
060            strings[stringsAdded++] = string;
061        }
062        return strings;
063    }
064}