/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.commons.sanselan.formats.png;

// should just use ints, not longs
public class PngCrc
{
    /* Table of CRCs of all 8-bit messages. */
    private final long crc_table[] = new long[256];

    /* Flag: has the table been computed? Initially false. */
    private boolean crc_table_computed = false;

    /* Make the table for a fast CRC. */
    private void make_crc_table()
    {
        long c;
        int n, k;

        for (n = 0; n < 256; n++)
        {
            c = n;
            for (k = 0; k < 8; k++)
            {
                if ((c & 1) != 0)

                    c = 0xedb88320L ^ (c >> 1);
                else
                    c = c >> 1;
            }
            crc_table[n] = c;
        }
        crc_table_computed = true;
    }

    /* Update a running CRC with the bytes buf[0..len-1]--the CRC
     should be initialized to all 1's, and the transmitted value
     is the 1's complement of the final running CRC (see the
     crc() routine below)). */

    private final long update_crc(long crc, byte buf[])
    {
        long c = crc;
        int n;

        if (!crc_table_computed)
            make_crc_table();
        for (n = 0; n < buf.length; n++)
        {
            //            Debug.debug("crc[" + n + "]", c + " (" + Long.toHexString(c) + ")");

            c = crc_table[(int) ((c ^ buf[n]) & 0xff)] ^ (c >> 8);
        }
        return c;
    }

    /* Return the CRC of the bytes buf[0..len-1]. */
    public final int crc(byte buf[], int len)
    {
        return (int) (update_crc(0xffffffffL, buf) ^ 0xffffffffL);
    }

    public final long start_partial_crc(byte buf[], int len)
    {
        return update_crc(0xffffffffL, buf);
    }

    public final long continue_partial_crc(long old_crc, byte buf[], int len)
    {
        return update_crc(old_crc, buf);
    }

    public final long finish_partial_crc(long old_crc)
    {
        return (old_crc ^ 0xffffffffL);
    }
}