//private void AlignColors(int total)
        //{
        //    for (int i = _boxCount; i < total; i++)
        //    {
        //        _boxes[i]._color = new ARGBPixel(255, 0, 0, 0);
        //        _boxes[i]._rootEntry = null;
        //    }

        //    _boxCount = total;
        //}

        private Bitmap Quantize(int targetColors, IProgressTracker progress)
        {
            //Clear group table
            Memory.Fill(_groupTable, (uint)(65536 * sizeof(void *)), 0);

            if (!SelectColors(targetColors))
            {
                SpreadColors(targetColors);
            }

            SortBoxes();

            //Write bitmap
            Bitmap       bmp = new Bitmap(_width, _height, _outFormat);
            ColorPalette pal = ColorPaletteExtension.CreatePalette(ColorPaletteFlags.None, targetColors);

            WritePalette(pal);
            bmp.Palette = pal;

            BitmapData data = bmp.LockBits(new Rectangle(0, 0, _width, _height), ImageLockMode.ReadWrite, _outFormat);

            WriteIndices(data);

            bmp.UnlockBits(data);

            ClearBoxes();

            return(bmp);
        }
Example #2
0
        public static ColorPalette DecodePalette(PLT0v1 *palette)
        {
            int          count = palette->_numEntries;
            ColorPalette pal   = ColorPaletteExtension.CreatePalette(ColorPaletteFlags.HasAlpha, count);

            switch (palette->PaletteFormat)
            {
            case WiiPaletteFormat.IA8:
            {
                IA8Pixel *sPtr = (IA8Pixel *)palette->PaletteData;
                for (int i = 0; i < count; i++)
                {
                    pal.Entries[i] = (Color)sPtr[i];
                }

                break;
            }

            case WiiPaletteFormat.RGB565:
            {
                wRGB565Pixel *sPtr = (wRGB565Pixel *)palette->PaletteData;
                for (int i = 0; i < count; i++)
                {
                    pal.Entries[i] = (Color)sPtr[i];
                }

                break;
            }

            case WiiPaletteFormat.RGB5A3:
            {
                wRGB5A3Pixel *sPtr = (wRGB5A3Pixel *)palette->PaletteData;
                for (int i = 0; i < count; i++)
                {
                    pal.Entries[i] = (Color)(ARGBPixel)sPtr[i];
                }

                break;
            }
            }

            return(pal);
        }
Example #3
0
        public static ColorPalette DecodePalette(VoidPtr address, int count, WiiPaletteFormat format)
        {
            ColorPalette pal = ColorPaletteExtension.CreatePalette(ColorPaletteFlags.HasAlpha, count);

            switch (format)
            {
            case WiiPaletteFormat.IA8:
            {
                IA8Pixel *sPtr = (IA8Pixel *)address;
                for (int i = 0; i < count; i++)
                {
                    pal.Entries[i] = (Color)sPtr[i];
                }

                break;
            }

            case WiiPaletteFormat.RGB565:
            {
                wRGB565Pixel *sPtr = (wRGB565Pixel *)address;
                for (int i = 0; i < count; i++)
                {
                    pal.Entries[i] = (Color)sPtr[i];
                }

                break;
            }

            case WiiPaletteFormat.RGB5A3:
            {
                wRGB5A3Pixel *sPtr = (wRGB5A3Pixel *)address;
                for (int i = 0; i < count; i++)
                {
                    pal.Entries[i] = (Color)(ARGBPixel)sPtr[i];
                }

                break;
            }
            }

            return(pal);
        }
        public static unsafe Bitmap FromFile(string path)
        {
            using (FileMap view = FileMap.FromFile(path, FileMapProtect.Read))// FileStream stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read))
            {
                TGAHeader *header = (TGAHeader *)view.Address;

                int w = header->imageSpecification.width, h = header->imageSpecification.height;
                int entryBpp  = header->imageSpecification.pixelDepth;
                int alphaBits = header->imageSpecification.AlphaBits;

                ColorPalette palette = null;
                PixelFormat  format;
                ColorParser  cParser;
                switch (header->imageType & (TGAImageType)0x3)
                {
                case TGAImageType.UncompressedColorMapped:
                {
                    int mapBpp = header->colorMapSpecification.entrySize;
                    if (entryBpp == 4)
                    {
                        format  = PixelFormat.Format4bppIndexed;
                        cParser = delegate(VoidPtr sPtr, int sIndex, VoidPtr dPtr, int dIndex)
                        {
                            byte val = ((byte *)sPtr)[sIndex >> 1], val2 = ((byte *)dPtr)[dIndex >> 1];
                            val = ((sIndex & 1) == 0) ? (byte)(val >> 4) : (byte)(val & 0xF);
                            ((byte *)dPtr)[dIndex >> 1] = ((dIndex & 1) == 0) ? (byte)((val2 & 0xF) | (val << 4)) : (byte)((val2 & 0xF0) | val);
                        };
                    }
                    else if (entryBpp == 8)
                    {
                        format  = PixelFormat.Format8bppIndexed;
                        cParser = delegate(VoidPtr sPtr, int sIndex, VoidPtr dPtr, int dIndex)
                        { ((byte *)dPtr)[dIndex] = ((byte *)sPtr)[sIndex]; };
                    }
                    else
                    {
                        throw new InvalidDataException("Invalid TGA color map format.");
                    }

                    int firstIndex = header->colorMapSpecification.firstEntryIndex;
                    int palSize    = firstIndex + header->colorMapSpecification.length;
                    palette = ColorPaletteExtension.CreatePalette(ColorPaletteFlags.None, palSize);

                    PaletteParser pParser;
                    if (mapBpp == 32)
                    {
                        pParser = (ref VoidPtr x) => { Color c = (Color)(*(ARGBPixel *)x); x += 4; return(c); }
                    }
                    ;
                    else if (mapBpp == 24)
                    {
                        pParser = (ref VoidPtr x) => { Color c = (Color)(*(RGBPixel *)x); x += 3; return(c); }
                    }
                    ;
                    else
                    {
                        throw new InvalidDataException("Invalid TGA color map format.");
                    }

                    VoidPtr palData = header->ColorMapData;
                    for (int i = firstIndex; i < palSize; i++)
                    {
                        palette.Entries[i] = pParser(ref palData);
                    }

                    break;
                }

                case TGAImageType.UncompressedTrueColor:
                {
                    if ((entryBpp == 15) || ((entryBpp == 16) && (alphaBits == 0)))
                    {
                        format  = PixelFormat.Format16bppRgb555;
                        cParser = delegate(VoidPtr sPtr, int sIndex, VoidPtr dPtr, int dIndex)
                        { ((RGB555Pixel *)dPtr)[dIndex] = ((RGB555Pixel *)sPtr)[sIndex]; };
                    }
                    else if (entryBpp == 16)
                    {
                        format  = PixelFormat.Format16bppArgb1555;
                        cParser = delegate(VoidPtr sPtr, int sIndex, VoidPtr dPtr, int dIndex)
                        { ((RGB555Pixel *)dPtr)[dIndex] = ((RGB555Pixel *)sPtr)[sIndex]; };
                    }
                    else if (entryBpp == 24)
                    {
                        format  = PixelFormat.Format24bppRgb;
                        cParser = delegate(VoidPtr sPtr, int sIndex, VoidPtr dPtr, int dIndex)
                        { ((RGBPixel *)dPtr)[dIndex] = ((RGBPixel *)sPtr)[sIndex]; };
                    }
                    else if (entryBpp == 32)
                    {
                        format  = (alphaBits == 8) ? PixelFormat.Format32bppArgb : PixelFormat.Format32bppRgb;
                        cParser = delegate(VoidPtr sPtr, int sIndex, VoidPtr dPtr, int dIndex)
                        { ((ARGBPixel *)dPtr)[dIndex] = ((ARGBPixel *)sPtr)[sIndex]; };
                    }
                    else
                    {
                        throw new InvalidDataException("Unknown TGA file format.");
                    }

                    break;
                }

                case TGAImageType.UncompressedGreyscale:
                {
                    if (entryBpp == 8)
                    {
                        format  = PixelFormat.Format24bppRgb;
                        cParser = delegate(VoidPtr sPtr, int sIndex, VoidPtr dPtr, int dIndex)
                        { ((RGBPixel *)dPtr)[dIndex] = RGBPixel.FromIntensity(((byte *)sPtr)[sIndex]); };
                    }
                    else
                    {
                        throw new InvalidDataException("Unknown TGA file format.");
                    }
                    break;
                }

                default: throw new InvalidDataException("Unknown TGA file format.");
                }

                Bitmap bmp = new Bitmap(w, h, format);
                if (palette != null)
                {
                    bmp.Palette = palette;
                }
                BitmapData data = bmp.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadWrite, format);

                bool rle          = ((int)header->imageType & 0x8) != 0;
                int  srcStride    = (entryBpp * w).Align(8) / 8;
                int  rleBufferLen = (rle) ? srcStride : 0;

                byte *buffer = stackalloc byte[rleBufferLen];

                int   origin = (int)header->imageSpecification.ImageOrigin;
                int   xStep  = ((origin & 1) == 0) ? 1 : -1;
                int   yStep  = ((origin & 2) != 0) ? 1 : -1;
                byte *imgSrc = header->ImageData;
                for (int dY = (yStep == 1) ? 0 : h - 1, sY = 0; sY < h; dY += yStep, sY++)
                {
                    VoidPtr imgDst = (VoidPtr)data.Scan0 + (data.Stride * dY);

                    if (rle)
                    {
                        imgSrc += DecodeRLE(imgSrc, buffer, srcStride, entryBpp);
                    }

                    for (int dX = (xStep == 1) ? 0 : w - 1, sX = 0; sX < w; dX += xStep, sX++)
                    {
                        cParser((rle) ? buffer : imgSrc, sX, imgDst, dX);
                    }

                    if (!rle)
                    {
                        imgSrc += srcStride;
                    }
                }

                bmp.UnlockBits(data);
                return(bmp);
            }
        }