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

darwin.jopenctm.io.CtmFileReader Maven / Gradle / Ivy

/*
 * Copyright (C) 2012 Daniel Heinrich
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * (version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this library.  If not, see  
 * or write to the Free Software Foundation, Inc., 51 Franklin Street,
 * Fifth Floor, Boston, MA 02110-1301  USA.
 */
package darwin.jopenctm.io;

import java.io.IOException;
import java.io.InputStream;
import java.util.ServiceLoader;

import darwin.jopenctm.compression.MeshDecoder;
import darwin.jopenctm.data.Mesh;
import darwin.jopenctm.errorhandling.BadFormatException;
import darwin.jopenctm.errorhandling.InvalidDataException;

/**
 *
 * @author daniel
 */
public class CtmFileReader
{

    public static final int OCTM = getTagInt("OCTM");
    private Mesh mesh;
    private String comment;
    private final CtmInputStream in;
    private boolean decoded;

    public CtmFileReader(InputStream source)
    {
        in = new CtmInputStream(source);
    }

    public Mesh decode() throws IOException, BadFormatException, InvalidDataException
    {
        if (decoded) {
            throw new RuntimeException("Ctm File got already decoded");
        }
        decoded = true;

        if (in.readLittleInt() != OCTM) {
            throw new BadFormatException("The CTM file doesn't start with the OCTM tag!");
        }

        final int formatVersion = in.readLittleInt();
        final int methodTag = in.readLittleInt();

        final MeshInfo mi = new MeshInfo(in.readLittleInt(),//vertex count
                in.readLittleInt(), //triangle count
                in.readLittleInt(), //uvmap count
                in.readLittleInt(), //attribute count
                in.readLittleInt());                  //flags

        comment = in.readString();

        // Uncompress from stream
        Mesh m = null;
        ServiceLoader services = ServiceLoader.load(MeshDecoder.class);
        for (MeshDecoder md : services) {
            if (md.isFormatSupported(methodTag, formatVersion)) {
                m = md.decode(mi, in);
                break;
            }
        }

        if (m == null) {
            throw new IOException("No sutible decoder found for Mesh of compression type: " + unpack(methodTag) + ", version " + formatVersion);
        }

        // Check mesh integrity
        m.checkIntegrity();

        return m;
    }

    public static String unpack(int tag)
    {
        byte[] chars = new byte[4];
        chars[0] = (byte) (tag & 0xff);
        chars[1] = (byte) ((tag >> 8) & 0xff);
        chars[2] = (byte) ((tag >> 16) & 0xff);
        chars[3] = (byte) ((tag >> 24) & 0xff);
        return new String(chars);
    }

    /**
     * before calling this method the first time, the decode method has to be
     * called.
     * 

* @throws RuntimeExceptio- if the file wasn't decoded before. */ public String getFileComment() { if (!decoded) { throw new RuntimeException("The CTM file is not decoded yet."); } return comment; } public static int getTagInt(String tag) { char[] chars = tag.toCharArray(); assert chars.length == 4 : "A tag has to be constructed out of 4 characters!"; return chars[0] | (chars[1] << 8) | (chars[2] << 16) | (chars[3] << 24); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy