private bool SelectColors(int targetColors)
        {
            int          splitAxis;
            ColorBox *   splitBox, boxPtr = _boxes;
            ARGBPixel *  sPtr = _srcPixels;
            ColorEntry **gPtr = _groupTable;
            ColorEntry * entry;
            ushort       id;

            //Create initial box
            boxPtr->Initialize();
            _boxCount = 1;

            //Iterate through colors using ID generator
            for (int i = 0; i < _size; i++)
            {
                _idFunc(*sPtr++, &id);
                gPtr = _groupTable + id;
                if ((entry = *gPtr) == null)
                {
                    *gPtr = entry = ColorEntry.Create();
                    _idConv(&id, out entry->_color);
                    entry->_weight = 1;
                    boxPtr->_rootEntry->InsertPrev(entry);
                }
                else
                {
                    entry->_weight++;
                }
            }

            //If no quantization is necessary, then leave.
            if (boxPtr->_colors <= targetColors)
            {
                return(false);
            }

            //Update initial box
            boxPtr->Update(targetColors - 1);

            //Split until we reach desired colors
            while (_boxCount < targetColors)
            {
                //Find split candidate
                splitBox = ColorBox.FindSplit(_boxes, _boxCount, targetColors, out splitAxis);

                //Create new box
                (++boxPtr)->Initialize();

                //Move colors from one box to another using split axis
                splitBox->Split(boxPtr, splitAxis);

                //Update boxes
                _boxCount++;
                splitBox->Update(targetColors - _boxCount);
                boxPtr->Update(targetColors - _boxCount);
            }
            return(true);
        }
Example #2
0
        private MedianCut(Bitmap bmp, WiiPixelFormat texFormat, WiiPaletteFormat palFormat)
        {
            //Set output format
            if (texFormat == WiiPixelFormat.CI4)
            {
                _outFormat = PixelFormat.Format4bppIndexed;
            }
            else if (texFormat == WiiPixelFormat.CI8)
            {
                _outFormat = PixelFormat.Format8bppIndexed;
            }
            else
            {
                throw new ArgumentException("Invalid pixel format.");
            }

            //Set conversion functions
            if (palFormat == WiiPaletteFormat.IA8)
            {
                _idFunc = IA8Handler;
                _idConv = IA8Converter;
            }
            else if (palFormat == WiiPaletteFormat.RGB565)
            {
                _idFunc = RGB565Handler;
                _idConv = RGB565Converter;
            }
            else
            {
                _idFunc = RGB5A3Handler;
                _idConv = RGB5A3Converter;
            }

            //Lock/set source data
            _srcBmp  = bmp;
            _width   = bmp.Width;
            _height  = bmp.Height;
            _size    = _width * _height;
            _srcData = bmp.LockBits(new Rectangle(0, 0, _width, _height), ImageLockMode.ReadOnly,
                                    PixelFormat.Format32bppArgb);
            _srcPixels = (ARGBPixel *)_srcData.Scan0;

            //Create buffers
            _boxes      = (ColorBox *)Marshal.AllocHGlobal(256 * sizeof(ColorBox));
            _groupTable = (ColorEntry **)Marshal.AllocHGlobal(65536 * sizeof(void *));
        }
 public void Dispose()
 {
     if (_boxes != null)
     {
         Marshal.FreeHGlobal((IntPtr)_boxes);
         _boxes = null;
     }
     if (_groupTable != null)
     {
         Marshal.FreeHGlobal((IntPtr)_groupTable);
         _groupTable = null;
     }
     if (_srcBmp != null)
     {
         _srcBmp.UnlockBits(_srcData);
         _srcBmp    = null;
         _srcData   = null;
         _srcPixels = null;
     }
     GC.SuppressFinalize(this);
 }
        private MedianCut(Bitmap bmp, WiiPixelFormat texFormat, WiiPaletteFormat palFormat)
        {
            //Set output format
            if (texFormat == WiiPixelFormat.CI4)
                _outFormat = PixelFormat.Format4bppIndexed;
            else if (texFormat == WiiPixelFormat.CI8)
                _outFormat = PixelFormat.Format8bppIndexed;
            else
                throw new ArgumentException("Invalid pixel format.");

            //Set conversion functions
            if (palFormat == WiiPaletteFormat.IA8)
            {
                _idFunc = IA8Handler;
                _idConv = IA8Converter;
            }
            else if (palFormat == WiiPaletteFormat.RGB565)
            {
                _idFunc = RGB565Handler;
                _idConv = RGB565Converter;
            }
            else
            {
                _idFunc = RGB5A3Handler;
                _idConv = RGB5A3Converter;
            }

            //Lock/set source data
            _srcBmp = bmp;
            _width = bmp.Width;
            _height = bmp.Height;
            _size = _width * _height;
            _srcData = bmp.LockBits(new Rectangle(0, 0, _width, _height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
            _srcPixels = (ARGBPixel*)_srcData.Scan0;

            //Create buffers
            _boxes = (ColorBox*)Marshal.AllocHGlobal(256 * sizeof(ColorBox));
            _groupTable = (ColorEntry**)Marshal.AllocHGlobal(65536 * 4);
        }
 public void Dispose()
 {
     if (_boxes != null)
     {
         Marshal.FreeHGlobal((IntPtr)_boxes);
         _boxes = null;
     }
     if (_groupTable != null)
     {
         Marshal.FreeHGlobal((IntPtr)_groupTable);
         _groupTable = null;
     }
     if (_srcBmp != null)
     {
         _srcBmp.UnlockBits(_srcData);
         _srcBmp = null;
         _srcData = null;
         _srcPixels = null;
     }
     GC.SuppressFinalize(this);
 }