예제 #1
0
        public LRLE(Bitmap image)
        {
            magic   = 0x454C524C;
            version = 0x32303056;
            int imageWidth  = image.Width;
            int imageHeight = image.Height;

            width  = (ushort)imageWidth;
            height = (ushort)imageHeight;

            List <Command>[] commandLists = new List <Command> [9];
            EncodingState    currentState = EncodingState.StartNew;
            uint             runLength    = 0;
            List <byte[]>    colorArray   = new List <byte[]>();

            byte[]        lastPixel = new byte[4];
            ColorTable    colors    = new ColorTable();
            List <byte[]> runColors = new List <byte[]>();

            for (int m = 0; m < 9; m++)
            {
                byte[] mipPixels = GetMipBytes(image);
                commandLists[m] = new List <Command>();
                Array.Copy(mipPixels, 0, lastPixel, 0, 4);
                currentState = EncodingState.StartNew;
                int x = 0, y = 0;
                int w1 = image.Width * 4;
                for (int i = 0; i < mipPixels.Length; i += 64)
                {
                    for (int j = 0; j < 4; j++)
                    {
                        for (int k = 0; k < 16; k += 4)
                        {
                            byte[] tmp = new byte[4];
                            Array.Copy(mipPixels, (y * w1) + x + k, tmp, 0, 4);
                            switch (currentState)
                            {
                            case EncodingState.StartNew:
                                currentState = EncodingState.Unknown;
                                runLength    = 1;
                                colorArray   = new List <byte[]>();
                                colorArray.Add(tmp);
                                break;

                            case EncodingState.Unknown:
                                if (tmp.SequenceEqual(lastPixel))
                                {
                                    currentState = EncodingState.RepeatRun;
                                }
                                else
                                {
                                    currentState = EncodingState.ColorRun;
                                }
                                colorArray.Add(tmp);
                                Array.Copy(tmp, 0, lastPixel, 0, 4);
                                runLength++;
                                break;

                            case EncodingState.ColorRun:
                                if (!tmp.SequenceEqual(lastPixel))
                                {
                                    runLength++;
                                }
                                else
                                {
                                    colorArray.RemoveAt(colorArray.Count - 1);
                                    runLength--;
                                    commandLists[m].Add(new Command(currentState, runLength, colorArray));
                                    foreach (var item in colorArray)
                                    {
                                        colors.AddColor(item);
                                    }
                                    runLength    = 2;
                                    colorArray   = new List <byte[]>();
                                    currentState = EncodingState.RepeatRun;
                                }
                                Array.Copy(tmp, 0, lastPixel, 0, 4);
                                colorArray.Add(tmp);

                                break;

                            case EncodingState.RepeatRun:
                                if (tmp.SequenceEqual(lastPixel))
                                {
                                    runLength++;
                                    Array.Copy(tmp, 0, lastPixel, 0, 4);
                                }
                                else
                                {
                                    commandLists[m].Add(new Command(currentState, runLength, colorArray));
                                    foreach (var item in colorArray)
                                    {
                                        runColors.Add(item);
                                    }
                                    Array.Copy(tmp, 0, lastPixel, 0, 4);
                                    runLength  = 1;
                                    colorArray = new List <byte[]>();
                                    colorArray.Add(tmp);
                                    currentState = EncodingState.Unknown;
                                }
                                break;

                            default:
                                break;
                            }
                        }
                        y++;
                    }
                    x += 16;
                    if (x >= w1)
                    {
                        x = 0;
                    }
                    else
                    {
                        y -= 4;
                    }
                }
                commandLists[m].Add(new Command(currentState, runLength, colorArray));
                foreach (var item in colorArray)
                {
                    colors.AddColor(item);
                }
                mipPixels = null;

                imageWidth  /= 2;
                imageHeight /= 2;

                if (m < 1)
                {
                    Bitmap mip = new Bitmap(imageWidth, imageHeight);
                    using (Graphics g = Graphics.FromImage(mip))
                    {
                        g.SmoothingMode      = SmoothingMode.Default;
                        g.InterpolationMode  = InterpolationMode.High;
                        g.PixelOffsetMode    = PixelOffsetMode.HighQuality;
                        g.CompositingQuality = CompositingQuality.HighQuality;
                        g.DrawImage(image, new Rectangle(0, 0, imageWidth, imageHeight));
                    }
                    image = mip;
                }
                else if (m < 3)
                {
                    image = new Bitmap(image, imageWidth, imageHeight);
                }
                else
                {
                    Bitmap mip = new Bitmap(imageWidth, imageHeight);
                    using (Graphics g = Graphics.FromImage(mip))
                    {
                        g.SmoothingMode      = SmoothingMode.Default;
                        g.InterpolationMode  = InterpolationMode.NearestNeighbor;
                        g.PixelOffsetMode    = PixelOffsetMode.HighSpeed;
                        g.CompositingQuality = CompositingQuality.HighSpeed;
                        g.DrawImage(image, new Rectangle(0, 0, imageWidth, imageHeight));
                    }
                    image = mip;
                }
            }
            colors.SortColors();
            foreach (var item in runColors)
            {
                if (!colors.HasColor(item))
                {
                    colors.AddColor(item);
                }
            }

            List <byte[]> tmpPixels = new List <byte[]>();

            foreach (var item in colors.colors.OrderBy(x => x.Value.Index).Where(x => x.Value.Index < 0x10000).Select(x => x.Key))
            {
                tmpPixels.Add(item.color);
            }
            pixelArray = tmpPixels.ToArray();

            mips = new byte[9][];
            for (int i = 0; i < 9; i++)
            {
                List <byte> tmpCommands = new List <byte>();
                foreach (var item in commandLists[i])
                {
                    tmpCommands.AddRange(item.ToOps(colors).ToArray());
                }
                mips[i] = tmpCommands.ToArray();
            }
        }