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); }
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); }