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