Ejemplo n.º 1
0
        public static byte[] GetPixelData(Bitmap img, int format, bool rectangle = true)
        {
            int w = img.Width;
            int h = img.Height;

            bool perfect = w == h && w != 0 && (w & (w - 1)) == 0;

            if (!perfect) // Check if square power of two, else resize
            {
                // Square Format Checks
                if (rectangle && Math.Min(img.Width, img.Height) < 32)
                {
                    w = XLIMUtil.NextLargestPow2(img.Width);
                    h = XLIMUtil.NextLargestPow2(img.Height);
                }
                else
                {
                    w = h = Math.Max(XLIMUtil.NextLargestPow2(w), XLIMUtil.NextLargestPow2(h)); // else resize
                }
            }

            using MemoryStream mz = new MemoryStream();
            using BinaryWriter bz = new BinaryWriter(mz);
            int p = XLIMUtil.GreatestCommonMultiple(w, 8) / 8;

            if (p == 0)
            {
                p = 1;
            }
            for (uint i = 0; i < w * h; i++)
            {
                XLIMOrienter.DecimalToCartesian(i % 64, out uint x, out uint y);

                // Get Shift Tile
                uint tile = i / 64;

                // Shift Tile Coordinate into Tilemap
                x += (uint)(tile % p) * 8;
                y += (uint)(tile / p) * 8;

                // Don't write data
                Color c;
                if (x >= img.Width || y >= img.Height)
                {
                    c = Color.FromArgb(0, 0, 0, 0);
                }
                else
                {
                    c = img.GetPixel((int)x, (int)y); if (c.A == 0)
                    {
                        c = Color.FromArgb(0, 86, 86, 86);
                    }
                }

                switch (format)
                {
                case 0: bz.Write(GetL8(c)); break;                  // L8

                case 1: bz.Write(GetA8(c)); break;                  // A8

                case 2: bz.Write(GetLA4(c)); break;                 // LA4(4)

                case 3: bz.Write(GetLA8(c)); break;                 // LA8(8)

                case 4: bz.Write(GetHILO8(c)); break;               // HILO8

                case 5: bz.Write(GetRGB565(c)); break;              // RGB565

                case 6:
                {
                    bz.Write(c.B);
                    bz.Write(c.G);
                    bz.Write(c.R); break;
                }

                case 7: bz.Write(GetRGBA5551(c)); break;            // RGBA5551

                case 8: bz.Write(GetRGBA4444(c)); break;            // RGBA4444

                case 9: bz.Write(GetRGBA8888(c)); break;            // RGBA8

                case 10: throw new Exception("ETC1 not supported.");

                case 11: throw new Exception("ETC1A4 not supported.");

                case 12:
                {
                    byte val = (byte)(GetL8(c) / 0x11);     // First Pix    // L4
                    { c = img.GetPixel((int)x, (int)y); if (c.A == 0)
                      {
                          c = Color.FromArgb(0, 0, 0, 0);
                      }
                    }
                    val |= (byte)((GetL8(c) / 0x11) << 4); i++;
                    bz.Write(val); break;
                }

                case 13:
                {
                    byte val = (byte)(GetA8(c) / 0x11);     // First Pix    // L4
                    { c = img.GetPixel((int)x, (int)y); }
                    val |= (byte)((GetA8(c) / 0x11) << 4); i++;
                    bz.Write(val); break;
                }
                }
            }
            if (!perfect)
            {
                while (mz.Length < XLIMUtil.NextLargestPow2((int)mz.Length)) // pad
                {
                    bz.Write((byte)0);
                }
            }

            return(mz.ToArray());
        }
Ejemplo n.º 2
0
        // BCLIM Data Writing
        public static int Write16BitColorPalette(Bitmap img, MemoryStream ms)
        {
            using Stream pixelcolors = new MemoryStream();
            using BinaryWriter bz    = new BinaryWriter(pixelcolors);
            // Set up our basis.
            bool under16colors = false;
            int  colors        = GetColorCount(img);

            Color[] pcs = new Color[colors];
            if (colors < 16)
            {
                under16colors = true;
            }
            uint div = 1;

            if (under16colors)
            {
                div = 2;
            }

            if (colors > 70)
            {
                throw new Exception("Too many colors");
            }

            // Set up a new reverse image to build into.
            int w = XLIMUtil.GreatestCommonMultiple(img.Width, 8);
            int h = XLIMUtil.GreatestCommonMultiple(img.Height, 8);

            w = Math.Max(XLIMUtil.NextLargestPow2(w), XLIMUtil.NextLargestPow2(h));
            h = w;
            byte[] pixelarray = new byte[w * h];

            const int colorformat = 2;
            int       ctr         = 1;

            pcs[0] = Color.FromArgb(0, 0xFF, 0xFF, 0xFF);

            int p = XLIMUtil.GreatestCommonMultiple(w, 8) / 8;

            if (p == 0)
            {
                p = 1;
            }
            int d = 0;

            for (uint i = 0; i < pixelarray.Length; i++)
            {
                d = (int)(i / div);
                // Get Tile Coordinate
                XLIMOrienter.DecimalToCartesian(i % 64, out var x, out var y);

                // Get Shift Tile
                uint tile = i / 64;

                // Shift Tile Coordinate into Tilemap
                x += (uint)(tile % p) * 8;
                y += (uint)(tile / p) * 8;
                if (x >= img.Width || y >= img.Height) // Don't try to access any pixel data outside of our bounds.
                {
                    i++; continue;
                }                  // Goto next tile.

                // Get Color of Pixel
                Color c = img.GetPixel((int)x, (int)y);

                // Color Table Building Logic
                int index = Array.IndexOf(pcs, c);
                if (c.A == 0)
                {
                    index = 0;
                }
                if (index < 0)                          // If new color
                {
                    pcs[ctr] = c; index = ctr; ctr++;
                }                                       // Add it to color list

                // Add pixel to pixeldata
                if (under16colors)
                {
                    index <<= 4;
                }
                pixelarray[i / div] = (byte)index;
                if (!under16colors)
                {
                    continue;
                }

                c     = img.GetPixel((int)x + 1, (int)y);
                index = Array.IndexOf(pcs, c);
                if (c.A == 0)
                {
                    index = 0;
                }
                if (index < 0)  // If new color
                {
                    pcs[ctr] = c; index = ctr; ctr++;
                }
                pixelarray[i / div] |= (byte)index;
                i++;
            }

            // Write Intro
            bz.Write((ushort)colorformat); bz.Write((ushort)ctr);
            // Write Colors
            for (int i = 0; i < ctr; i++)
            {
                bz.Write(GetRGBA5551(pcs[i]));      // Write byte array.
            }
            // Write Pixel Data
            for (uint i = 0; i < d; i++)
            {
                bz.Write(pixelarray[i]);
            }
            // Write Padding
            while (pixelcolors.Length < XLIMUtil.NextLargestPow2((int)pixelcolors.Length))
            {
                bz.Write((byte)0);
            }
            // Copy to main CLIM.
            pixelcolors.Position = 0; pixelcolors.CopyTo(ms);
            return(7);
        }