Exemplo n.º 1
0
 public Palette Combine(Palette secondPalette)
 {
     List<byte> bytes = new List<byte>();
     bytes.AddRange(RawData);
     bytes.AddRange(secondPalette.RawData);
     return new Palette(-1, bytes.ToArray());
 }
Exemplo n.º 2
0
        private static Texture ReadTextureFromTMem(TileDescriptor tile, Palette palette = null)
        {
            Texture newTexture;

            if (!TMEM.LoadedData.ContainsKey(tile.TMem))
                return null;

            //if (!tile.On)   //Not sure if used??
            //    return null;

            int offset = TMEM.LoadedData[tile.TMem].FileOffset;
            int sizeOfData = TMEM.LoadedData[tile.TMem].Size;

            int widthInBytes = 8 * tile.Line;

            double texelSize = 1;
            switch (tile.PixelSize)
            {
                case Texture.PixelInfo.Size_4b:
                    texelSize = 0.5;
                    break;
                case Texture.PixelInfo.Size_16b:
                    texelSize = 2;
                    break;
                case Texture.PixelInfo.Size_32b:
                    texelSize = 4;
                    break;
            }

            int widthInTexels = (int)Math.Round(widthInBytes / texelSize);
            int heightInTexels = sizeOfData / widthInBytes;

            byte[] data = new byte[sizeOfData];
            Array.Copy(TMEM.Data, tile.TMemInBytes, data, 0, sizeOfData);
            
            if(tile.ImageFormat == Texture.ImageFormat.CI)
                newTexture = new Texture(offset, data, tile.ImageFormat, tile.PixelSize,
                    widthInTexels, heightInTexels, palette, tile.Palette);
            else
                newTexture = new Texture(offset, data, tile.ImageFormat, tile.PixelSize,
                    widthInTexels, heightInTexels, null);
            
            tile.SettingsChanged = false;

            return newTexture;
        }
Exemplo n.º 3
0
        private const int PALETTE_TMEM_OFFSET_IN_BYTES = 0x800; //offset * 8

        private static Palette ReadPaletteFromTMem()
        {
            Palette newPalette;

            if (!TMEM.LoadedData.ContainsKey(PALETTE_TMEM_OFFSET))
                return null;

            int offset = TMEM.LoadedData[PALETTE_TMEM_OFFSET].FileOffset;
            int sizeOfData = TMEM.LoadedData[PALETTE_TMEM_OFFSET].Size;

            byte[] data = new byte[sizeOfData];
            Array.Copy(TMEM.Data, PALETTE_TMEM_OFFSET_IN_BYTES, data, 0, sizeOfData);

            newPalette = new Palette(offset, data);

            return newPalette;
        }
Exemplo n.º 4
0
        private static bool TryLoadExistingPalette(out Palette palette)
        {
            palette = null;

            if (TMEM.LoadedElements.ContainsKey(PALETTE_TMEM_OFFSET))
            {
                palette = (TMEM.LoadedElements[PALETTE_TMEM_OFFSET] as Palette);
                return true;
            }

            if (!TMEM.LoadedData.ContainsKey(PALETTE_TMEM_OFFSET))
                return false;

            LoadedTMemData tmemInfo = TMEM.LoadedData[PALETTE_TMEM_OFFSET];

            if (tmemInfo.SourceFile == null || !_foundPalettes.ContainsKey(tmemInfo.SourceFile))
                return false;

            for (int i = 0; i < _foundPalettes[tmemInfo.SourceFile].Count; i++)
            {
                if (_foundPalettes[tmemInfo.SourceFile][i].FileOffset == tmemInfo.FileOffset)
                {
                    palette = _foundPalettes[tmemInfo.SourceFile][i];
                    return true;
                }
            }

            return false;
        }
Exemplo n.º 5
0
        private static void GenerateNewPalette(Palette palette, Bitmap image, int colorCount)
        {
            //This can take a long time (not optimized), so be careful
            List<Color> colors = new List<Color>();

            for (int j = 0; j < image.Height; j++)
            {
                for (int i = 0; i < image.Width; i++)
                {
                    if (!colors.Contains(image.GetPixel(i, j)))
                        colors.Add(image.GetPixel(i, j));
                }
            }

            //Now that we have a huge list of colors, let's start going through them rapidly
            //List<double> minDist = new List<double>();
            //foreach (Color color in colors)
            //    minDist.Add(double.MaxValue);

            //while (colors.Count > colorCount)
            //{
            //    for (int i = 0; i < colors.Count; i++)
            //    {
            //        for (int j = i + 1; j < colors.Count; j++)
            //        {
            //            double dist = colors[i].ColorDistanceFrom(colors[j]);
            //            if (dist < minDist[i])
            //                minDist[i] = dist;
            //        }
            //    }

            //    //Find smallest one, clear it out
            //    double minvalue = minDist.Min();
            //    int removeIndex = minDist.IndexOf(minvalue);
            //    colors.RemoveAt(removeIndex);
            //    minDist.RemoveAt(removeIndex);

            //    //start over
            //    for (int i = 0; i < minDist.Count; i++)
            //        minDist[i] = double.MaxValue;
            //}

            PaletteMedianCutAnalyzer analyzer = new PaletteMedianCutAnalyzer();
            foreach (Color color in colors)
                analyzer.AddColor(color);

            //Now make the new palette
            byte[] newData = PaletteToBinary(analyzer.GetPalette(16));

            palette.RawData = newData;
        }
Exemplo n.º 6
0
        public static byte[] CI8ToBinary(Bitmap bmp, Palette palette)
        {
            //Pixel size is 1 byte

            if (bmp == null)
                return null;

            if (palette == null || palette.Colors.Length < 1)
                return null;

            byte[] imgData = new byte[bmp.Width * bmp.Height];

            int[] paletteIDs = new int[palette.Colors.Length];
            for (int k = 0; k < palette.Colors.Length; k++)
            {
                paletteIDs[k] = palette.Colors[k].ToArgb();
            }

            for (int i = 0; i < bmp.Width; i++)
            {
                for (int j = 0; j < bmp.Height; j++)
                {
                    int index = i + j * bmp.Width;

                    Color pixel = bmp.GetPixel(i, j);
                    int pixelID = pixel.ToArgb();

                    byte palIndex = 0x00;
                    bool foundExactMatch = false;

                    double closestDist = double.MaxValue;
                    byte closestIndex = 0;

                    for (byte p = 0; p < paletteIDs.Length; p++)
                    {
                        if (paletteIDs[p] == pixelID)
                        {
                            palIndex = p;
                            foundExactMatch = true;
                            break;
                        }
                        else
                        {
                            //Get the dist to the color, and keep track of which is the best representation
                            double dist = pixel.ColorDistanceFrom(palette.Colors[p]);

                            if (dist < closestDist)
                            {
                                closestDist = dist;
                                closestIndex = p;
                            }
                        }
                    }

                    if(foundExactMatch)
                        ByteHelper.WriteByte(palIndex, imgData, index);
                    else
                        ByteHelper.WriteByte(closestIndex, imgData, index);
                }
            }

            return imgData;
        }
Exemplo n.º 7
0
        public static Bitmap BinaryToCI8(byte[] imgData, Palette palette, int width, int height)
        {
            //Pixel size is 1 byte
            if (width * height != imgData.Length)
                return null;

            if (palette == null || palette.Colors.Length < 1)
                return null;

            Bitmap bmp = new Bitmap(width, height);
            
            //NOTE: Here's some optimization code that will make it much faster, just adapt it to the BinaryToCI8 method

            //BitmapData data = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
            //int stride = data.Stride;
            //unsafe
            //{
            //    byte* ptr = (byte*)data.Scan0;
            //    // Check this is not a null area
            //    if (!areaToPaint.IsEmpty)
            //    {
            //        // Go through the draw area and set the pixels as they should be
            //        for (int y = areaToPaint.Top; y < areaToPaint.Bottom; y++)
            //        {
            //            for (int x = areaToPaint.Left; x < areaToPaint.Right; x++)
            //            {
            //                // layer.GetBitmap().SetPixel(x, y, m_colour);
            //                ptr[(x * 3) + y * stride] = m_colour.B;
            //                ptr[(x * 3) + y * stride + 1] = m_colour.G;
            //                ptr[(x * 3) + y * stride + 2] = m_colour.R;
            //            }
            //        }
            //    }
            //}
            //bmp.UnlockBits(data);

            for (int i = 0; i < width; i++)
            {
                for (int j = 0; j < height; j++)
                {
                    int index = (i + j * width);

                    byte CI = ByteHelper.ReadByte(imgData, index);

                    if (CI > palette.Colors.Length)
                        CI = 0;

                    bmp.SetPixel(i, j, palette.Colors[CI]);
                }
            }

            return bmp;
        }
Exemplo n.º 8
0
        public static byte[] CI4ToBinary(Bitmap bmp, Palette palette, int paletteIndex, bool generateNewPalette = false)
        {
            //Pixel size is 1/2 bytes
            if (bmp == null)
                return null;

            if (palette == null || palette.Colors.Length < 1)
                return null;

            if (generateNewPalette)
            {
                GenerateNewPalette(palette, bmp, 16);
                paletteIndex = 0;
            }

            byte[] imgData = new byte[bmp.Width * bmp.Height / 2];

            int[] paletteIDs = new int[palette.Colors.Length];
            for (int k = 0; k < palette.Colors.Length; k++)
            {
                int colorIndex = k + 16 * paletteIndex;
                if (colorIndex > palette.Colors.Length)
                    colorIndex = 0;

                paletteIDs[k] = palette.Colors[colorIndex].ToArgb();
            }

            for (int i = 0; i < bmp.Width; i+=2)
            {
                for (int j = 0; j < bmp.Height; j++)
                {
                    int index = (i + j * bmp.Width) / 2;

                    Color pixel = bmp.GetPixel(i, j);
                    int pixelID = pixel.ToArgb();

                    int index1 = -1;
                    byte closestIndex = 0;
                    double closestDist = double.MaxValue;
                    for (byte p = 0; p < paletteIDs.Length; p++)
                    {
                        if (paletteIDs[p] == pixelID)
                        {
                            index1 = p;
                            break;
                        }
                        else
                        {
                            //Get the dist to the color, and keep track of which is the best representation
                            double dist = pixel.ColorDistanceFrom(palette.Colors[p + 16 * paletteIndex]);

                            if (dist < closestDist)
                            {
                                closestDist = dist;
                                closestIndex = p;
                            }
                        }
                    }
                    if (index1 == -1)
                        index1 = closestIndex;

                    pixel = bmp.GetPixel(i + 1, j);
                    pixelID = pixel.ToArgb();

                    int index2 = -1;
                    closestIndex = 0;
                    closestDist = double.MaxValue;
                    for (byte p = 0; p < paletteIDs.Length; p++)
                    {
                        
                        if (paletteIDs[p] == pixelID)
                        {
                            index2 = p;
                            break;
                        }
                        else
                        {
                            //Get the dist to the color, and keep track of which is the best representation
                            double dist = pixel.ColorDistanceFrom(palette.Colors[p + 16 * paletteIndex]);

                            if (dist < closestDist)
                            {
                                closestDist = dist;
                                closestIndex = p;
                            }
                        }
                    }
                    if (index2 == -1)
                        index2 = closestIndex;

                    ByteHelper.WriteByte((byte)((index1 << 4) | index2), imgData, index);
                }
            }

            return imgData;
        }
Exemplo n.º 9
0
        //16b

        #endregion

        #region CI

        //4b, 8b
        public static Bitmap BinaryToCI4(byte[] imgData, Palette palette, int paletteIndex, int width, int height)
        {
            //Pixel size is 1/2 byte
            if (width / 2 * height != imgData.Length)
                return null;

            if (palette == null || palette.Colors.Length < 1)
                return null;
            
            Bitmap bmp = new Bitmap(width, height);

            for (int i = 0; i < width; i += 2)
            {
                for (int j = 0; j < height; j++)
                {
                    int index = (i + j * width) / 2;

                    byte CI = ByteHelper.ReadByte(imgData, index);
                    byte CI1 = (byte)(CI >> 4);
                    byte CI2 = (byte)(CI & 0x0F);

                    int color1Index = CI1 + 16 * paletteIndex;
                    if (color1Index >= palette.Colors.Length)
                        color1Index = 0;

                    int color2Index = CI2 + 16 * paletteIndex;
                    if (color2Index >= palette.Colors.Length)
                        color2Index = 0;

                    bmp.SetPixel(i, j, palette.Colors[color1Index]);
                    bmp.SetPixel(i + 1, j, palette.Colors[color2Index]);

                }
            }

            return bmp;
        }
Exemplo n.º 10
0
        public Texture(int index, byte[] bytes, ImageFormat format = ImageFormat.RGBA,
            PixelInfo pixel = PixelInfo.Size_32b, int width = 0, int height = 0, Palette palette = null,
            int paletteIndex = 0)
            : base(index, bytes)
        {
            Format = format;
            PixelSize = pixel;
            Width = width;
            Height = height;

            ImagePalette = palette;
            PaletteIndex = paletteIndex;
            
            //generate image
            _initializing = false;
            RawData = bytes;
        }