/*
 * 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.imaging.common;

import java.io.ByteArrayOutputStream;
import java.io.IOException;

import org.apache.commons.imaging.ImageReadException;

public class PackBits
{

    public byte[] decompress(byte bytes[], int expected)
            throws ImageReadException
    {
        int total = 0;

        ByteArrayOutputStream baos = new ByteArrayOutputStream();

        //    Loop until you get the number of unpacked bytes you are expecting:
        int i = 0;
        while (total < expected)

        {
            //        Read the next source byte into n.
            if (i >= bytes.length)
                throw new ImageReadException(
                        "Tiff: Unpack bits source exhausted: " + i
                                + ", done + " + total + ", expected + "
                                + expected);

            int n = bytes[i++];
            //                If n is between 0 and 127 inclusive, copy the next n+1 bytes literally.
            if ((n >= 0) && (n <= 127))
            {

                int count = n + 1;

                total += count;
                for (int j = 0; j < count; j++)
                    baos.write(bytes[i++]);
            }
            //                Else if n is between -127 and -1 inclusive, copy the next byte -n+1
            //                times.
            else if ((n >= -127) && (n <= -1))
            {
                int b = bytes[i++];
                int count = -n + 1;

                total += count;
                for (int j = 0; j < count; j++)
                    baos.write(b);
            }
            else if (n == -128)
                throw new ImageReadException("Packbits: " + n);
            //                Else if n is between -127 and -1 inclusive, copy the next byte -n+1
            //                times.
            //        else
            //                Else if n is -128, noop.
        }
        byte result[] = baos.toByteArray();

        return result;

    }

    private int findNextDuplicate(byte bytes[], int start)
    {
        //        int last = -1;
        if (start >= bytes.length)
            return -1;

        byte prev = bytes[start];

        for (int i = start + 1; i < bytes.length; i++)
        {
            byte b = bytes[i];

            if (b == prev)
                return i - 1;

            prev = b;
        }

        return -1;
    }

    private int findRunLength(byte bytes[], int start)
    {
        byte b = bytes[start];

        int i;

        for (i = start + 1; (i < bytes.length) && (bytes[i] == b); i++)
        { /* do nothing */ }

        return i - start;
    }

    public byte[] compress(byte bytes[]) throws IOException
    {
        MyByteArrayOutputStream baos = new MyByteArrayOutputStream(
                bytes.length * 2); // max length 1 extra byte for every 128

        int ptr = 0;
        int count = 0;
        while (ptr < bytes.length)
        {
            count++;
            int dup = findNextDuplicate(bytes, ptr);

            if (dup == ptr) // write run length
            {
                int len = findRunLength(bytes, dup);
                int actual_len = Math.min(len, 128);
                baos.write(-(actual_len - 1));
                baos.write(bytes[ptr]);
                ptr += actual_len;
            }
            else
            { // write literals
                int len = dup - ptr;

                if (dup > 0)
                {
                    int runlen = findRunLength(bytes, dup);
                    if (runlen < 3) // may want to discard next run.
                    {
                        int nextptr = ptr + len + runlen;
                        int nextdup = findNextDuplicate(bytes, nextptr);
                        if (nextdup != nextptr) // discard 2-byte run
                        {
                            dup = nextdup;
                            len = dup - ptr;
                        }
                    }
                }

                if (dup < 0)
                    len = bytes.length - ptr;
                int actual_len = Math.min(len, 128);

                baos.write(actual_len - 1);
                for (int i = 0; i < actual_len; i++)
                {
                    baos.write(bytes[ptr]);
                    ptr++;
                }
            }
        }
        byte result[] = baos.toByteArray();

        return result;

    }
}