<commit_before>package sgdk.rescomp.type;

import java.util.Arrays;

import sgdk.rescomp.type.Basics.TileEquality;
import sgdk.tool.ArrayUtil;
import sgdk.tool.ImageUtil;
import sgdk.tool.TypeUtil;

public class Tile implements Comparable<Tile>
{
    /**
     * @param x
     *        X position in pixel
     * @param y
     *        Y position in pixel
     */
    public static Tile getTile(byte[] image8bpp, int imgW, int imgH, int x, int y)
    {
        final byte[] data = new byte[64];

        int pal = -1;
        int prio = -1;
        int srcOff = (y * imgW) + x;
        int dstOff = 0;
        for (int j = y; j < (y + 8); j++)
        {
            for (int i = x; i < (x + 8); i++)
            {
                final int pixel;

                // inside image ?
                if ((i >= 0) && (i < imgW) && (j >= 0) && (j < imgH))
                    pixel = TypeUtil.unsign(image8bpp[srcOff]);
                else
                    pixel = 0;
                srcOff++;

                final int color = pixel & 0xF;

                // not a transparent pixel ?
                if (color != 0)
                {
                    final int curPal = (pixel >> 4) & 3;
                    final int curPrio = (pixel >> 7) & 1;

                    // set palette
                    if (pal == -1)
                        pal = curPal;
                    else if (pal != curPal)
                        throw new IllegalArgumentException("Error: pixel at [" + i + "," + j
                                + "] reference a different palette (" + curPal + " != " + pal + ").");

                    // set prio
                    if (prio == -1)
                        prio = curPrio;
                    else if (prio != curPrio)
                        throw new IllegalArgumentException("Error: pixel at [" + i + "," + j
                                + "] reference a different priority (" + curPrio + " != " + prio + ").");
                }

                data[dstOff++] = (byte) color;
            }

            srcOff += imgW - 8;
        }

        // default palette and priority
        if (pal == -1)
            pal = 0;
        if (prio == -1)
            prio = 0;

        return new Tile(data, pal, prio != 0);
    }

    public final int[] data;
    public final int pal;
    public final boolean prio;
    public final boolean empty;

    final int hc;

    public Tile(int[] data, int pal, boolean prio)
    {
        super();

        if (data.length != 8)
            throw new IllegalArgumentException("new Tile(int[]) error: array lenght is != 8");

        // 8 lines of 8 pixels (4bpp)
        this.data = data;

        this.pal = pal & 3;
        this.prio = prio;

        // compute hash code and empty
        int c = 0;
        boolean emp = true;
        for (int i = 0; i < data.length; i++)
        {
            final int d = data[i];
            c ^= d;
            if (d != 0)
                emp = false;
        }

        hc = c;
        empty = emp;
    }

    public Tile(int[] data)
    {
        this(data, 0, false);
    }

    public Tile(byte[] pixel8bpp, int pal, boolean prio)
    {
        this(ArrayUtil.byteToInt(ImageUtil.convertTo4bpp(pixel8bpp, 8)), pal, prio);
    }

    public Tile(byte[] pixel8bpp)
    {
        this(ArrayUtil.byteToInt(ImageUtil.convertTo4bpp(pixel8bpp, 8)));
    }

    public boolean isPlain()
    {
        return getPlainValue() != -1;
    }

    /**
     * Return plain pixel value for plain tile (-1 otherwise)
     */
    public int getPlainValue()
    {
        final int result = data[0] & 0xF;

        for (int d : data)
        {
            for (int i = 0; i < 8; i++)
            {
                if ((d & 0xF) != result)
                    return -1;

                d >>= 4;
            }
        }

        return result;
    }

    public Tile getFlipped(boolean hflip, boolean vflip)
    {
        final int[] result = new int[8];

        for (int i = 0; i < 8; i++)
        {
            int line;

            if (vflip)
                line = 7 - i;
            else
                line = i;

            if (hflip)
                result[i] = TypeUtil.swapNibble32(data[line]);
            else
                result[i] = data[line];
        }

        return new Tile(result);
    }

    public TileEquality getEquality(Tile tile)
    {
        // perfect equality
        if (tile.equals(this))
            return TileEquality.EQUAL;

        // hflip
        if (Arrays.equals(data, tile.getFlipped(true, false).data))
            return TileEquality.HFLIP;
        // vflip
        if (Arrays.equals(data, tile.getFlipped(false, true).data))
            return TileEquality.VFLIP;
        // hvflip
        if (Arrays.equals(data, tile.getFlipped(true, true).data))
            return TileEquality.HVFLIP;

        return TileEquality.NONE;
    }

    @Override
    public int hashCode()
    {
        return hc;
    }

    @Override
    public boolean equals(Object obj)
    {
        if (obj instanceof Tile)
        {
            final Tile t = (Tile) obj;

            return (hc == t.hc) && Arrays.equals(data, t.data);
        }

        return super.equals(obj);
    }

    @Override
    public int compareTo(Tile tile)
    {
        return Integer.compare(hc, tile.hc);
    }
}<commit_msg>Moved declaration / methods from Tilemap to Tile<commit_after>package sgdk.rescomp.type;

import java.util.Arrays;

import sgdk.rescomp.type.Basics.TileEquality;
import sgdk.tool.ArrayUtil;
import sgdk.tool.ImageUtil;
import sgdk.tool.TypeUtil;

public class Tile implements Comparable<Tile>
{
    public static final int TILE_MAX_NUM = 1 << 11;
    public static final int TILE_INDEX_MASK = TILE_MAX_NUM - 1;

    public static final int TILE_HFLIP_SFT = 11;
    public static final int TILE_VFLIP_SFT = 12;
    public static final int TILE_PALETTE_SFT = 13;
    public static final int TILE_PRIORITY_SFT = 15;

    public static final int TILE_HFLIP_FLAG = 1 << TILE_HFLIP_SFT;
    public static final int TILE_VFLIP_FLAG = 1 << TILE_VFLIP_SFT;
    public static final int TILE_PRIORITY_FLAG = 1 << TILE_PRIORITY_SFT;

    public static final int TILE_HFLIP_MASK = TILE_HFLIP_FLAG;
    public static final int TILE_VFLIP_MASK = TILE_VFLIP_FLAG;
    public static final int TILE_PALETTE_MASK = 3 << TILE_PALETTE_SFT;
    public static final int TILE_PRIORITY_MASK = TILE_PRIORITY_FLAG;

    public static final int TILE_ATTR_MASK = TILE_PRIORITY_MASK | TILE_PALETTE_MASK | TILE_VFLIP_MASK | TILE_HFLIP_MASK;

    public static int TILE_ATTR(int pal, int prio, int flipV, int flipH)
    {
        return (flipH << TILE_HFLIP_SFT) + (flipV << TILE_VFLIP_SFT) + (pal << TILE_PALETTE_SFT)
                + (prio << TILE_PRIORITY_SFT);
    }

    public static int TILE_ATTR_FULL(int pal, int prio, int flipV, int flipH, int index)
    {
        return (flipH << TILE_HFLIP_SFT) + (flipV << TILE_VFLIP_SFT) + (pal << TILE_PALETTE_SFT)
                + (prio << TILE_PRIORITY_SFT) + index;
    }

    public static int TILE_ATTR(int pal, boolean prio, boolean flipV, boolean flipH)
    {
        return TILE_ATTR(pal, prio ? 1 : 0, flipV ? 1 : 0, flipH ? 1 : 0);
    }

    public static int TILE_ATTR_FULL(int pal, boolean prio, boolean flipV, boolean flipH, int index)
    {
        return TILE_ATTR_FULL(pal, prio ? 1 : 0, flipV ? 1 : 0, flipH ? 1 : 0, index);
    }

    /**
     * @param x
     *        X position in pixel
     * @param y
     *        Y position in pixel
     */
    public static Tile getTile(byte[] image8bpp, int imgW, int imgH, int x, int y)
    {
        final byte[] data = new byte[64];

        int plainCol = -1;
        boolean plain = true;

        int pal = -1;
        int prio = -1;
        int srcOff = (y * imgW) + x;
        int dstOff = 0;
        for (int j = y; j < (y + 8); j++)
        {
            for (int i = x; i < (x + 8); i++)
            {
                final int pixel;

                // inside image ?
                if ((i >= 0) && (i < imgW) && (j >= 0) && (j < imgH))
                    pixel = TypeUtil.unsign(image8bpp[srcOff]);
                else
                    pixel = 0;
                srcOff++;

                final int color = pixel & 0xF;

                // first pixel --> affect color
                if (plainCol == -1)
                    plainCol = color;
                // not the same color --> not a plain tile
                else if (plainCol != color)
                    plain = false;

                // not a transparent pixel ?
                if (color != 0)
                {
                    final int curPal = (pixel >> 4) & 3;
                    final int curPrio = (pixel >> 7) & 1;

                    // set palette
                    if (pal == -1)
                        pal = curPal;
                    else if (pal != curPal)
                        throw new IllegalArgumentException("Error: pixel at [" + i + "," + j
                                + "] reference a different palette (" + curPal + " != " + pal + ").");

                    // set prio
                    if (prio == -1)
                        prio = curPrio;
                    else if (prio != curPrio)
                        throw new IllegalArgumentException("Error: pixel at [" + i + "," + j
                                + "] reference a different priority (" + curPrio + " != " + prio + ").");
                }

                data[dstOff++] = (byte) color;
            }

            srcOff += imgW - 8;
        }

        // default palette and priority
        if (pal == -1)
            pal = 0;
        if (prio == -1)
            prio = 0;

        return new Tile(data, pal, prio != 0, plain ? plainCol : -1);
    }

    public final int[] data;
    public final int pal;
    public final int plain;
    public final boolean prio;
    public final boolean empty;

    final int hc;

    public Tile(int[] data, int pal, boolean prio, int plain)
    {
        super();

        if (data.length != 8)
            throw new IllegalArgumentException("new Tile(int[]) error: array lenght is != 8");

        // 8 lines of 8 pixels (4bpp)
        this.data = data;

        this.pal = pal & 3;
        this.prio = prio;
        this.plain = plain;

        // compute hash code and empty
        int c = 0;
        boolean emp = true;
        for (int i = 0; i < data.length; i++)
        {
            final int d = data[i];
            c ^= d;
            if (d != 0)
                emp = false;
        }

        hc = c;
        empty = emp;
    }

    public Tile(byte[] pixel8bpp, int pal, boolean prio, int plain)
    {
        this(ArrayUtil.byteToInt(ImageUtil.convertTo4bpp(pixel8bpp, 8)), pal, prio, plain);
    }

    public boolean isPlain()
    {
        return getPlainValue() != -1;
    }

    /**
     * Return plain pixel value for plain tile (-1 otherwise)
     */
    public int getPlainValue()
    {
        return plain;
    }

    public Tile getFlipped(boolean hflip, boolean vflip)
    {
        final int[] result = new int[8];

        for (int i = 0; i < 8; i++)
        {
            int line;

            if (vflip)
                line = 7 - i;
            else
                line = i;

            if (hflip)
                result[i] = TypeUtil.swapNibble32(data[line]);
            else
                result[i] = data[line];
        }

        return new Tile(result, pal, prio, plain);
    }

    public TileEquality getEquality(Tile tile)
    {
        // perfect equality
        if (tile.equals(this))
            return TileEquality.EQUAL;

        // hflip
        if (Arrays.equals(data, tile.getFlipped(true, false).data))
            return TileEquality.HFLIP;
        // vflip
        if (Arrays.equals(data, tile.getFlipped(false, true).data))
            return TileEquality.VFLIP;
        // hvflip
        if (Arrays.equals(data, tile.getFlipped(true, true).data))
            return TileEquality.HVFLIP;

        return TileEquality.NONE;
    }

    @Override
    public int hashCode()
    {
        return hc;
    }

    @Override
    public boolean equals(Object obj)
    {
        if (obj instanceof Tile)
        {
            final Tile t = (Tile) obj;

            return (hc == t.hc) && Arrays.equals(data, t.data);
        }

        return super.equals(obj);
    }

    @Override
    public int compareTo(Tile tile)
    {
        return Integer.compare(hc, tile.hc);
    }
}
{'fraction_non_alphanumeric': 0.109375, 'fraction_numerical': 0.010977564102564102, 'mean_word_length': 1.4085295252798147, 'pattern_counts': {'":': 0, '<': 44, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4255217', 'n_tokens_mistral': 4071, 'n_tokens_neox': 3785, 'n_words': 1104}